Files
jx-callback/business/jxstore/cms/user2.go
邹宗楠 175dc47c60 1
2026-01-26 13:33:32 +08:00

1470 lines
45 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package cms
import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"sort"
"strings"
"sync"
"time"
"git.rosy.net.cn/baseapi/platformapi/alipayapi"
"git.rosy.net.cn/baseapi/platformapi/qywxapi"
"git.rosy.net.cn/jx-callback/business/auth2/authprovider/alipay"
"git.rosy.net.cn/jx-callback/business/jxutils/ddmsg"
"git.rosy.net.cn/jx-callback/business/partner"
beego "github.com/astaxie/beego/server/web"
"git.rosy.net.cn/jx-callback/business/jxstore/permission"
"git.rosy.net.cn/jx-callback/business/partner/purchase/jd"
"git.rosy.net.cn/jx-callback/globals/api/apimanager"
"git.rosy.net.cn/baseapi"
"git.rosy.net.cn/baseapi/platformapi/jdapi"
"git.rosy.net.cn/jx-callback/business/jxutils/excel"
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
"git.rosy.net.cn/baseapi/utils/errlist"
"git.rosy.net.cn/baseapi/platformapi/dingdingapi"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/auth2"
"git.rosy.net.cn/jx-callback/business/auth2/authprovider/dingding"
"git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin"
"git.rosy.net.cn/jx-callback/business/authz"
"git.rosy.net.cn/jx-callback/business/authz/autils"
"git.rosy.net.cn/jx-callback/business/jxutils"
"git.rosy.net.cn/jx-callback/business/jxutils/jsonerr"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/globals/api"
"git.rosy.net.cn/jx-callback/globals/api2"
)
var (
ErrUserIDAndNameMustGiven = errors.New("用户ID2和用户名必须不为空")
)
var (
userProvider = &UserProvider{}
authTypeFieldMap = map[string]string{
auth2.UserIDID: "user_id",
auth2.UserIDID2: "user_id2",
auth2.UserIDMobile: "mobile",
auth2.UserIDEmail: "email",
}
jdUsersStruct GetJdUsersStruct
titleListJdUser = []string{
"用户名",
"关联门店",
"所属角色",
"状态",
}
)
type GetJdUsersStruct struct {
locker sync.RWMutex
userMap []JdUserStruct
}
type JdUserStruct struct {
UserName string `json:"用户名"`
StoreIDs string `json:"关联门店"`
RoleName string `json:"所属角色"`
Status string `json:"状态"`
}
type UserProvider struct {
}
func (*UserProvider) GetUser(authID, authIDType string) (user auth2.IUser) {
fieldName := authTypeFieldMap[authIDType]
if fieldName != "" {
user2, err := dao.GetUserByID(dao.GetDB(), fieldName, authID)
if err == nil {
user = user2 // 这样写的原因是golang nil的比较问题
}
}
return user
}
func (*UserProvider) UpdateUserMobile(userID string, mobile string) (err error) {
_, err = dao.UpdateEntityLogically(dao.GetDB(), &model.User{}, map[string]interface{}{
"Mobile": mobile,
}, userID, map[string]interface{}{
"UserID": userID,
})
return err
}
func (*UserProvider) UpdateUserEmail(userID string, email string) (err error) {
_, err = dao.UpdateEntityLogically(dao.GetDB(), &model.User{}, map[string]interface{}{
"Email": email,
}, userID, map[string]interface{}{
"UserID": userID,
})
return err
}
func (*UserProvider) UpdateUserType(userID string, userTypeMask int8, updateType int) (err error) {
db := dao.GetDB()
user := &model.User{
UserID: userID,
}
if err = dao.GetEntity(db, user, "UserID"); err == nil {
if updateType == auth2.UpdateUserTypeAdd {
user.Type |= userTypeMask
} else if updateType == auth2.UpdateUserTypeDelete {
user.Type &= ^userTypeMask
} else {
user.Type = userTypeMask
}
dao.WrapUpdateULEntity(user, userID)
_, err = dao.UpdateEntity(db, user, "Type", model.FieldUpdatedAt, model.FieldLastOperator)
}
return err
}
func (*UserProvider) UpdateLastLogin(userID string, lastLoginType, fromIP string) (err error) {
_, err = dao.UpdateEntityLogically(dao.GetDB(), &model.User{}, map[string]interface{}{
"LastLoginAt": utils.Time2Pointer(time.Now()),
"LastLoginType": lastLoginType,
"LastLoginIP": fromIP,
}, userID, map[string]interface{}{
"UserID": userID,
})
return err
}
// func (*UserProvider) CreateUser(userID2, mobile, email, name string) (user auth2.IUser, err error) {
// realUser := &model.User{
// UserID2: userID2,
// Mobile: mobile,
// Email: email,
// Name: name,
// }
// return realUser, CreateUser(realUser)
// }
func init() {
auth2.Init(userProvider)
}
func RegisterUserWithMobile(ctx *jxcontext.Context, user *model.User, mobileVerifyCode string, inAuthInfo, manTokenInfo *auth2.AuthInfo) (outAuthInfo *auth2.AuthInfo, err error) {
var mobileAuth *auth2.AuthInfo
fakeMobile := false
user.Type = model.UserTypeConsumer | model.UserTypeStoreBoss // 先不区分商户与消息者
//user.Type = model.UserTypeConsumer // 先不区分商户与消息者
createName := ctx.GetRealRemoteIP()
authType := auth2.AuthTypeMobile
if manTokenInfo != nil && mobileVerifyCode == "" {
manUser, err2 := dao.GetUserByID(dao.GetDB(), "user_id", manTokenInfo.GetID())
if err = err2; err != nil {
return nil, err
}
if manUser.Type&(model.UserTypeOperator|model.UserTypeBoss) == 0 {
return nil, fmt.Errorf("管理员才能添加商户")
}
if utils.Pointer2String(user.Mobile) == "" {
return nil, fmt.Errorf("管理员添加必须指定用户手机号")
}
mobileVerifyCode = auth2.InternalAuthSecret
fakeMobile = true
user.Type |= model.UserTypeStoreBoss
createName = manTokenInfo.GetName()
}
if mobileVerifyCode != "" {
if fakeMobile {
mobileAuth, err = auth2.LoginInternal(ctx.Context, auth2.AuthTypeMobile, user.GetMobile(), auth2.UserIDMobile, mobileVerifyCode)
} else {
mobileAuth, err = auth2.Login(ctx.Context, auth2.AuthTypeMobile, user.GetMobile(), auth2.UserIDMobile, mobileVerifyCode)
}
if err != nil {
return nil, err
}
if mobileAuth != nil && !mobileAuth.IsUserEmpty() {
return mobileAuth, jsonerr.New(mobileAuth, model.ErrCodeJsonUserAlreadyExist)
// auth2.RemoveUserInfo(mobileAuth.Token)
// if newAuthInfo, err := auth2.BindUser(mobileAuth, user); err == nil {
// return nil, jsonerr.New(newAuthInfo, model.ErrCodeJsonUserAlreadyExist)
// } else {
// return nil, err
// }
}
} else if inAuthInfo != nil {
// user.Mobile = nil
} else {
return nil, fmt.Errorf("短信验证码与其它认证方式至少要指定一种")
}
if inAuthInfo != nil {
if inAuthInfo.AuthBindInfo.Type == dingding.AuthTypeStaff {
user.Type |= model.UserTypeOperator
user.Type |= model.UserTypeRole
} else if user.Mobile != nil {
//user.Type |= model.UserTypeStoreBoss
}
createName += "," + inAuthInfo.GetAuthID()
authType = inAuthInfo.GetAuthType()
if user.Avatar == "" {
user.Avatar = inAuthInfo.GetAvatar()
}
}
if err = CreateUser(user, utils.LimitUTF8StringLen(createName, 32)); err == nil {
userProvider.UpdateLastLogin(user.GetID(), authType, ctx.GetRealRemoteIP())
TryAddStoreBossRole4User(ctx, user)
if mobileAuth != nil {
if outAuthInfo, err = auth2.BindUser(mobileAuth, user); err == nil && inAuthInfo != nil {
err = auth2.AddAuthBind(&outAuthInfo.UserBasic, inAuthInfo)
}
} else {
outAuthInfo, err = auth2.BindUser(inAuthInfo, user)
}
} else if dao.IsDuplicateError(err) {
if user.LastLoginType == alipay.AuthType {
if user2, _ := dao.GetUserByID(dao.GetDB(), "mobile", user.GetMobile()); user2 != nil {
user.UserID = user2.GetID()
outAuthInfo, err = auth2.BindUser(inAuthInfo, user)
err = nil
} else {
err = auth2.ErrUserID2AlreadyExist
}
} else {
err = auth2.ErrUserID2AlreadyExist
}
}
return outAuthInfo, err
}
func TryAddStoreBossRole4User(ctx *jxcontext.Context, user *model.User) (err error) {
if user.Type&model.UserTypeStoreBoss != 0 {
userMobile := user.GetMobile()
if userMobile != "" {
if storeList, err := dao.GetStoreList(dao.GetDB(), nil, nil, nil, nil, []string{userMobile}, ""); err == nil && len(storeList) > 0 {
roleList := make([]*authz.RoleInfo, len(storeList))
for k, v := range storeList {
roleList[k] = autils.NewStoreBossRole(v.ID)
}
err = AddRoles4User(ctx, user.GetID(), roleList)
}
}
}
return err
}
func TryAddStoreBossRole4StoreByMobile(ctx *jxcontext.Context, storeID int, mobileList []string) (err error) {
if storeID > 0 {
var userIDs []string
for _, v := range mobileList {
if v != "" {
if userList, _, err := dao.GetUsers(dao.GetDB(), model.UserTypeStoreBoss, "", nil, nil, []string{v}, 0, -1); err == nil && len(userList) > 0 {
userIDs = append(userIDs, userList[0].GetID())
} else {
if manTokenInfo, err := auth2.GetTokenInfo(ctx.GetToken()); err == nil {
RegisterUserWithMobile(ctx, &model.User{
Name: v,
Mobile: &v,
UserID2: v,
}, "", nil, manTokenInfo)
}
}
}
}
if len(userIDs) > 0 {
role := autils.NewStoreBossRole(storeID)
err = AddUsers4Role(ctx, role, userIDs)
}
}
return err
}
func HandleOrder4Consignee(order *model.GoodsOrder) (err error) {
var user *model.User
mobileNumber := jxutils.GetRealMobile4Order(order)
if mobileNumber == "" && order.VendorUserID == "" {
return fmt.Errorf("订单:%s手机号与平台用户标识都是空", order.VendorOrderID)
}
authType := dao.GetAuthType4Vendor(order.VendorID)
if authType == "" {
msg := fmt.Sprintf("平台ID:%d当前不被支持请联系开发", order.VendorID)
return fmt.Errorf(msg)
}
oeratorName := order.VendorOrderID
db := dao.GetDB()
if mobileNumber != "" {
userList, _, err2 := dao.GetUsers(db, 0, "", nil, nil, []string{mobileNumber}, 0, 0)
if err = err2; err != nil {
return err
}
if len(userList) > 0 {
user = userList[0]
}
}
vendorUserID := order.VendorUserID
if vendorUserID != "" {
authInfo, err2 := dao.GetAuthBind(db, model.AuthBindTypeID, authType, vendorUserID)
if err = err2; err != nil && !dao.IsNoRowsError(err) {
return err
}
if err == nil {
vendorUserID = ""
if user == nil {
if user, err = dao.GetUserByID(db, "user_id", authInfo.UserID); err != nil {
return err
}
}
} else {
err = nil
}
}
const Remark = "fromOrder"
if user == nil {
user = &model.User{
UserID2: mobileNumber,
Name: order.ConsigneeName,
Mobile: &mobileNumber,
Type: model.UserTypeConsumer,
Address: order.ConsigneeAddress,
Remark: Remark,
}
setUserAddress(db, user, order)
if user.GetID2() == "" {
user.UserID2 = order.VendorUserID
}
if user.GetID2() == "" {
user.UserID2 = order.VendorOrderID
}
user.Type = model.UserTypeConsumer
err = CreateUser(user, oeratorName)
} else {
if user.GetMobile() == "" && mobileNumber != "" {
user.Mobile = &mobileNumber
dao.UpdateEntity(db, user, "Mobile")
}
}
if err == nil {
order.UserID = user.GetID()
if vendorUserID != "" {
authBind := &model.AuthBind{
UserID: user.GetID(),
BindType: model.AuthBindTypeID,
AuthID: vendorUserID,
Type: authType,
Remark: Remark,
}
dao.WrapAddIDCULDEntity(authBind, oeratorName)
authBind.Status = model.AuthBindStatusNormal
err = dao.CreateEntity(nil, authBind)
}
}
return err
}
func setUserAddress(db *dao.DaoDB, user *model.User, order *model.GoodsOrder) {
user.Address = order.ConsigneeAddress
store := &model.Store{}
store.ID = jxutils.GetSaleStoreIDFromOrder(order)
if err := dao.GetEntity(db, store); err == nil {
user.CityCode = store.CityCode
user.DistrictCode = store.DistrictCode
} else if dao.IsNoRowsError(err) {
if order.ConsigneeLng != 0 && order.ConsigneeLat != 0 {
if user.DistrictCode = api.TencentMapAPI.GetCoordinateDistrictCode(jxutils.IntCoordinate2Standard(order.ConsigneeLng), jxutils.IntCoordinate2Standard(order.ConsigneeLat)); user.DistrictCode > 0 {
if placeInfo, err := dao.GetPlaceByCode(db, user.DistrictCode); err == nil {
user.CityCode = placeInfo.ParentCode
}
}
}
}
}
func GetUserBindAuthInfo(ctx *jxcontext.Context) (authList []*model.AuthBind, err error) {
authInfo, err := ctx.GetV2AuthInfo()
if err == nil {
return auth2.GetUserBindAuthInfo(authInfo.GetID())
}
return nil, err
}
func CreateUser(user *model.User, creatorName string) (err error) {
if user == nil || user.UserID2 == "" || user.Name == "" {
return ErrUserIDAndNameMustGiven
}
if user.GetMobile() == "" {
user.Mobile = nil
}
if user.GetEmail() == "" {
user.Email = nil
}
//支付宝注册电话需要解密
if user.GetMobile() != "" && user.GetName() != "" && user.GetID2() != "" {
if user.LastLoginType == alipay.AuthType {
mobile := &alipayapi.KeyMobile{}
data, _ := base64.StdEncoding.DecodeString(user.GetMobile())
key, _ := base64.StdEncoding.DecodeString(alipay.AuthKey)
iv := []byte{}
iv = append(iv, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
if result, err := utils.AESCBCDecpryt(data, key, iv); err == nil && result != nil {
json.Unmarshal(result, &mobile)
}
if mobile.Mobile == "" {
return fmt.Errorf("支付宝注册解密失败!")
}
user.Mobile = &mobile.Mobile
user.UserID2 = mobile.Mobile
user.Name = mobile.Mobile
}
}
dao.WrapAddIDCULDEntity(user, creatorName)
user.UserID = utils.GetUUID()
user.Status = model.UserStatusNormal
user.DividePercentage = 1
return dao.CreateEntity(nil, user)
}
func DisableUser(ctx *jxcontext.Context, userID string) (err error) {
userName := ctx.GetUserName()
if _, err = dao.UpdateEntityLogically(dao.GetDB(), &model.User{}, map[string]interface{}{
"Status": model.UserStatusDisabled,
}, userName, map[string]interface{}{
"UserID": userID,
}); err == nil {
auth2.DisableUser(userID, userName)
}
return err
}
func OnDingDingMsg(msg map[string]interface{}) (callbackResponse *dingdingapi.CallbackResponse) {
eventType := utils.Interface2String(msg[dingdingapi.KeyEventType])
if eventType == dingdingapi.CBTagUserLeaveOrg {
var (
authBind *model.AuthBind
err error
)
db := dao.GetDB()
for _, userID := range msg[dingdingapi.KeyUserID].([]interface{}) {
userIDStr := utils.Interface2String(userID)
if authBind, err = dao.GetAuthBind(db, model.AuthBindTypeAuth, dingding.AuthTypeStaff, userIDStr); err == nil { // 直接找到了
if err = DeleteUserInfo(jxcontext.AdminCtx, authBind.UserID); err != nil {
globals.SugarLogger.Errorf("OnDingDingMsg failed with error:%v", err)
}
}
}
} else if eventType == dingdingapi.CBTagCheckURL {
return api.DingDingAPI.PackCallbackResult("success")
}
return api.DingDingAPI.Err2CallbackResponse(nil)
}
func GetUsers(ctx *jxcontext.Context, userType int, keyword string, userIDs []string, userID2, mobile string, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) {
userList, totalCount, err := dao.GetUsers(dao.GetDB(), userType, keyword, userIDs, jxutils.BatchString2Slice(userID2), jxutils.BatchString2Slice(mobile), offset, pageSize)
if err == nil {
pagedInfo = &model.PagedInfo{
TotalCount: totalCount,
Data: userList,
}
}
return pagedInfo, err
}
func GetStoreList4User(ctx *jxcontext.Context, mobileNum, userID string) (storeList []*dao.StoreWithCityName, err error) {
roleList, err := api2.RoleMan.GetUserRoleList(userID)
if err != nil {
return nil, err
}
var (
storeIDs []int
shortRoleNameList []string
)
for _, v := range roleList {
if v.StoreID == 0 {
shortRoleNameList = append(shortRoleNameList, v.Name)
} else {
storeIDs = append(storeIDs, v.StoreID)
}
}
storeList, err = dao.GetStoreListByMobileOrStoreIDs(dao.GetDB(), mobileNum, shortRoleNameList, storeIDs)
storeMap, _ := dao.GetStoresMapList(dao.GetDB(), nil, storeIDs, nil, -9, -1, "", "", "")
mapList := make(map[int][]dao.StoreMapList, len(storeMap))
if len(storeMap) != 0 {
for i := 0; i < len(storeMap); i++ {
mapList[storeMap[i].StoreID] = append(mapList[storeMap[i].StoreID], dao.StoreMapList{
JxStoreId: storeMap[i].StoreID,
VendorStoreId: storeMap[i].VendorStoreID,
VendorId: storeMap[i].VendorID,
VendorOrgCode: storeMap[i].VendorOrgCode,
})
}
}
for _, v := range storeList {
v.VendorStore = mapList[v.ID]
}
return storeList, err
}
func GetMyStoreListNew(ctx *jxcontext.Context, version string) (storesInfo interface{}, errCode string, err error) {
if !auth2.IsV2Token(ctx.GetToken()) {
return nil, model.ErrCodeTokenIsInvalid, model.ErrTokenIsInvalid
}
if ctx.GetLoginType() == weixin.AuthTypeWxApp || ctx.GetLoginType() == weixin.AuthTypeWxAppCaishi {
if configs, _ := dao.QueryConfigs(dao.GetDB(), "checkversion", model.ConfigTypeSys, ""); len(configs) > 0 {
if version == "" || configs[0].Value != version {
return nil, "", fmt.Errorf("当前APP版本过旧数据显示有错误请到'京西菜市'公众号下载最新版本APP")
}
}
}
mobile, userID := ctx.GetMobileAndUserID()
if mobile == "" || userID == "" || userID == "null" || userID == "NULL" {
return nil, "", fmt.Errorf("不能得到用户手机号,%s,%s", userID, mobile)
}
var storeList []*dao.StoreWithCityName
if storeList, err = GetStoreList4User(ctx, mobile, userID); err == nil && len(storeList) > 0 {
// todo应该用通用方法
mapDataList := make([]map[string]interface{}, len(storeList))
for k, v := range storeList {
mapDataList[k] = map[string]interface{}{
"id": v.ID,
"address": v.Address,
"cityName": v.CityName,
"name": v.Name,
"tel1": v.Tel1,
"tel2": v.Tel2,
"payeeName": v.PayeeName,
"status": v.Status,
"vendorStoreList": v.VendorStore,
}
}
storesInfo = mapDataList
}
return storesInfo, "", err
}
func SolveNullMobileUser(ctx *jxcontext.Context) (err error) {
return err
}
func GetStoreRoleList(ctx *jxcontext.Context) (roleList []*authz.RoleInfo, err error) {
return authz.StoreRoleList, nil
}
func GetUserRoleList(ctx *jxcontext.Context, userID string) (roleList []*authz.RoleInfo, err error) {
return api2.RoleMan.GetUserRoleList(userID)
}
func GetRoleUserList(ctx *jxcontext.Context, r *authz.RoleInfo) (userIDList []string, err error) {
return api2.RoleMan.GetRoleUserList(r)
}
func GetRolesUserList(ctx *jxcontext.Context, rList []*authz.RoleInfo) (userIDMap map[string][]string, err error) {
userIDMap = make(map[string][]string)
for _, r := range rList {
userIDList, err2 := api2.RoleMan.GetRoleUserList(r)
if err = err2; err == nil {
userIDMap[r.GetFullName()] = userIDList
} else {
break
}
}
return userIDMap, err
}
func checkUserType(userID string, userType int8) (err error) {
userList, _, err := dao.GetUsers(dao.GetDB(), 0, "", []string{userID}, nil, nil, 0, 0)
if err != nil {
return err
}
if len(userList) == 0 {
return fmt.Errorf("找不到用户:%s", userID)
}
if userList[0].Type&userType == 0 {
return fmt.Errorf("用户:%s不能用于当前操作", userID)
}
return nil
}
func AddRoles4User(ctx *jxcontext.Context, userID string, rList []*authz.RoleInfo) (err error) {
errList := errlist.New()
if err = checkUserType(userID, model.UserTypeNonConsumer); err != nil {
return err
}
for _, v := range rList {
if err = autils.ValidateRole(v.Name, v.StoreID); err == nil {
if err = api2.RoleMan.AddRole4User(userID, v); err != nil {
errList.AddErr(err)
} else if v.StoreID > 0 {
HandleUserWXRemark(dao.GetDB(), userID, true)
}
} else {
errList.AddErr(err)
}
}
return errList.GetErrListAsOne()
}
func DeleteRoles4User(ctx *jxcontext.Context, userID string, rList []*authz.RoleInfo) (err error) {
errList := errlist.New()
for _, v := range rList {
if err = api2.RoleMan.DeleteRole4User(userID, v); err != nil {
errList.AddErr(err)
} else if v.StoreID > 0 {
HandleUserWXRemark(dao.GetDB(), userID, true)
}
}
return errList.GetErrListAsOne()
}
func AddUsers4Role(ctx *jxcontext.Context, r *authz.RoleInfo, userIDList []string) (err error) {
if err = autils.ValidateRole(r.Name, r.StoreID); err != nil {
return err
}
errList := errlist.New()
for _, v := range userIDList {
// if permission.IsRoledByUserID(v) {
// if storeIDsMap, err := permission.GetUserStoresResultMap(v); err == nil {
// if storeIDsMap[r.StoreID] == 0 {
// return fmt.Errorf("此用户没有该门店[%v]的权限,无法添加到分组", r.StoreID)
// }
// }
// }
if err = checkUserType(v, model.UserTypeNonConsumer); err != nil {
return err
}
if err = api2.RoleMan.AddRole4User(v, r); err != nil {
errList.AddErr(err)
} else if r.StoreID > 0 {
HandleUserWXRemark(dao.GetDB(), v, true)
}
}
return errList.GetErrListAsOne()
}
func DeleteUsers4Role(ctx *jxcontext.Context, r *authz.RoleInfo, userIDList []string) (err error) {
errList := errlist.New()
for _, v := range userIDList {
if err = api2.RoleMan.DeleteRole4User(v, r); err != nil {
errList.AddErr(err)
} else if r.StoreID > 0 {
HandleUserWXRemark(dao.GetDB(), v, true)
}
}
return errList.GetErrListAsOne()
}
func getAddressInfoFromCoord(db *dao.DaoDB, lng, lat float64, districtCodeParam int) (formattedAddress string, districtCode, cityCode int, err error) {
place, err := dao.GetPlacesByDistrictCode(districtCodeParam)
if err != nil {
return "", 0, 0, err
}
formattedAddress = place.ProvinceName + place.CityName + place.CountyName
districtCode = place.CountyCode
cityCode = place.CityCode
//regeoInfo, err := api.TencentMapAPI.GeoCodeRegeoSingle(lng, lat, 0, false, nil, 0, 0)
//if err == nil {
// formattedAddress = regeoInfo.Result.Address
// districtCode = int(utils.Str2Int64WithDefault(regeoInfo.Result.AdInfo.Adcode, 0))
// if districtCode == 0 {
// err = fmt.Errorf("坐标lng:%f,lat:%f找不到位置信息", lng, lat)
// } else if districtInfo, err2 := dao.GetPlaceByCode(db, districtCode); err2 == nil {
// cityCode = districtInfo.ParentCode
// }
//}
// 地址 // 行政区划code
return formattedAddress, districtCode, cityCode, err
}
func AddUserDeliveryAddress(ctx *jxcontext.Context, address *model.UserDeliveryAddress) (outAddress *model.UserDeliveryAddress, err error) {
if address.UserID == "" {
return nil, fmt.Errorf("操作用户配送地址时必须指定UserID")
}
db := dao.GetDB()
lng := address.Lng
lat := address.Lat
address.AutoAddress, address.DistrictCode, address.CityCode, err = getAddressInfoFromCoord(db, lng, lat, address.DistrictCode)
address.AutoAddress = address.AutoAddress + address.Address
if err == nil {
txDB, _ := dao.Begin(db)
defer func() {
if r := recover(); r != nil {
dao.Rollback(db, txDB)
panic(r)
}
}()
dao.WrapAddIDCULDEntity(address, ctx.GetUserName())
if address.IsDefault == 1 {
if err = dao.ClearUserDeliveryAddressDefault(db, address.UserID, 0); err != nil {
dao.Rollback(db, txDB)
return nil, err
}
}
if err = dao.CreateEntity(db, address); err == nil {
dao.Commit(db, txDB)
outAddress = address
} else {
dao.Rollback(db, txDB)
}
}
return outAddress, err
}
func AddMyDeliveryAddress(ctx *jxcontext.Context, address *model.UserDeliveryAddress) (outAddress *model.UserDeliveryAddress, err error) {
_, address.UserID = ctx.GetMobileAndUserID()
outAddress, err = AddUserDeliveryAddress(ctx, address)
return outAddress, err
}
func DeleteUserDeliveryAddress(ctx *jxcontext.Context, userID string, addressID int) (err error) {
num, err := dao.DeleteEntityLogically(dao.GetDB(), &model.UserDeliveryAddress{}, nil, ctx.GetUserName(), map[string]interface{}{
model.FieldID: addressID,
"UserID": userID,
})
if err == nil {
if num == 0 {
err = fmt.Errorf("地址ID:%d不存在", addressID)
}
}
return err
}
func DeleteMyDeliveryAddress(ctx *jxcontext.Context, addressID int) (err error) {
_, userID := ctx.GetMobileAndUserID()
return DeleteUserDeliveryAddress(ctx, userID, addressID)
}
func UpdateUserDeliveryAddress(ctx *jxcontext.Context, userID string, addressID int, payload map[string]interface{}) (err error) {
if userID == "" {
return fmt.Errorf("操作用户配送地址时必须指定UserID")
}
address := &model.UserDeliveryAddress{
UserID: userID,
}
address.ID = addressID
db := dao.GetDB()
if err = dao.GetEntity(db, address, model.FieldID, "UserID"); err == nil {
var outAddress *model.UserDeliveryAddress
valid := dao.StrictMakeMapByStructObject2(payload, address, &outAddress, ctx.GetUserName())
delete(valid, "autoAddress")
//delete(valid, "districtCode")
delete(valid, "cityCode")
if len(valid) > 0 {
if valid["lng"] != nil || valid["lat"] != nil {
valid["autoAddress"], valid["districtCode"], valid["cityCode"], err = getAddressInfoFromCoord(db, outAddress.Lng, outAddress.Lat, valid["districtCode"].(int))
if err != nil {
return err
}
}
txDB, _ := dao.Begin(db)
defer func() {
if r := recover(); r != nil {
dao.Rollback(db, txDB)
panic(r)
}
}()
if utils.ForceInterface2Int64(valid["isDefault"]) == 1 {
if err = dao.ClearUserDeliveryAddressDefault(db, userID, 0); err != nil {
dao.Rollback(db, txDB)
return err
}
}
if _, err = dao.UpdateEntityLogically(db, address, valid, ctx.GetUserName(), nil); err == nil {
dao.Commit(db, txDB)
} else {
dao.Rollback(db, txDB)
}
}
}
return err
}
func UpdateMyDeliveryAddress(ctx *jxcontext.Context, addressID int, payload map[string]interface{}) (err error) {
_, userID := ctx.GetMobileAndUserID()
return UpdateUserDeliveryAddress(ctx, userID, addressID, payload)
}
func QueryUserDeliveryAddress(ctx *jxcontext.Context, userIDs []string, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) {
addressList, totalCount, err := dao.QueryUserDeliveryAddress(dao.GetDB(), 0, userIDs, offset, pageSize)
if err == nil {
pagedInfo = &model.PagedInfo{
TotalCount: totalCount,
Data: addressList,
}
}
return pagedInfo, err
}
func QueryMyDeliveryAddress(ctx *jxcontext.Context) (addressList []*dao.UserDeliveryAddressEx, err error) {
_, userID := ctx.GetMobileAndUserID()
addressList, _, err = dao.QueryUserDeliveryAddress(dao.GetDB(), 0, []string{userID}, 0, model.UnlimitedPageSize)
return addressList, err
}
func SaveUserCart(ctx *jxcontext.Context, userID string, storeID int, cartItems []*model.UserCartItem) (err error) {
if userID == "" || storeID == 0 {
return fmt.Errorf("用户与门店必须要指定")
}
for _, v := range cartItems {
v.UserID = userID
v.StoreID = storeID
dao.WrapAddIDCULEntity(v, userID)
}
db := dao.GetDB()
txDB, _ := dao.Begin(db)
defer func() {
if r := recover(); r != nil || err != nil {
dao.Rollback(db, txDB)
if r != nil {
panic(r)
}
}
}()
_, err = dao.ExecuteSQL(db, `
DELETE t1
FROM user_cart_item t1
WHERE t1.user_id = ? AND t1.store_id = ?
`, userID, storeID)
if err != nil {
return err
}
if len(cartItems) > 0 {
err = dao.CreateMultiEntities(db, cartItems)
}
if err == nil {
dao.Commit(db, txDB)
}
return err
}
func LoadUserCart(ctx *jxcontext.Context, userID string, storeIDs []int) (cartItems []*model.UserCartItem, err error) {
if userID == "" || len(storeIDs) == 0 {
return nil, fmt.Errorf("用户与门店必须要指定")
}
sql := `
SELECT t1.*
FROM user_cart_item t1
WHERE t1.user_id = ? AND t1.store_id IN (` + dao.GenQuestionMarks(len(storeIDs)) + `)
ORDER BY t1.sku_id
`
err = dao.GetRows(dao.GetDB(), &cartItems, sql, userID, storeIDs)
return cartItems, err
}
func GetSelfInfo(ctx *jxcontext.Context) (getSelfInfoResult *dao.GetSelfInfoResult, err error) {
tokenInfo, err := auth2.GetTokenInfo(ctx.GetToken())
if err == nil {
if getSelfInfoResult, err = dao.GetUserByIDWithMembers(dao.GetDB(), "user_id", tokenInfo.GetID()); err == nil {
if userMembers, err3 := dao.GetUserMember(dao.GetDB(), getSelfInfoResult.UserID, "", "", model.VendorIDJX, 0, model.YES); err3 == nil {
getSelfInfoResult.UserMembers = userMembers
} else {
err = err3
}
}
}
return getSelfInfoResult, err
}
func HandleUserWXRemark(db *dao.DaoDB, mobile string, mobileIsUerID bool) (err error) {
if db == nil {
db = dao.GetDB()
}
openIDs := []string{}
storeID := 0
remark := ""
// if !globals.DisableWXAuth1 {
// wxinfo, err := dao.GetUserStoreInfo(db, "tel", mobile)
// if err == nil {
// openIDs = []string{wxinfo.OpenID}
// storeID = wxinfo.JxStoreID
// }
// }
if globals.EnableWXAuth2 {
userID := ""
if mobileIsUerID {
userID = mobile
} else {
userList, _, err2 := dao.GetUsers(db, model.UserTypeStoreBoss, "", nil, nil, []string{mobile}, 0, -1)
if err = err2; len(userList) > 0 {
userID = userList[0].GetID()
}
}
if userID != "" {
authBindList, err2 := dao.GetUserBindAuthInfo(db, userID, model.AuthBindTypeAuth, []string{weixin.AuthTypeMP}, "", "", nil)
if err = err2; err == nil {
for _, v := range authBindList {
openIDs = append(openIDs, v.AuthID)
}
}
roleList, err2 := api2.RoleMan.GetUserRoleList(userID)
if err = err2; err == nil && len(roleList) > 0 {
storeID = roleList[0].StoreID
}
}
}
if len(openIDs) > 0 {
if storeID > 0 {
store := &model.Store{}
store.ID = storeID
if err = dao.GetEntity(db, store); err == nil {
city := &model.Place{
Code: store.CityCode,
}
if err = dao.GetEntity(db, city, "Code"); err == nil {
remark = city.Name + "-" + store.Name
}
}
}
if err == nil {
if globals.EnableStoreWrite {
for _, openID := range openIDs {
err = api.WeixinAPI.CBUpdateRemark(openID, remark)
}
}
}
}
return err
}
func GetJdUsers(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint string, err error) {
var (
jxVendorIDsMap = make(map[string]string)
pageNoList []int
storeUserList []interface{}
disabledIdList []interface{}
)
db := dao.GetDB()
jdUsersStruct.userMap = jdUsersStruct.userMap[0:0]
taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
switch step {
case 0:
//获取京东商城所有用户
apiList := apimanager.CurAPIManager.GetAppOrgCodeList(model.VendorIDJD)
for _, v := range apiList {
_, _, toatlPage, _ := jd.GetAPI(v).PrivilegeSearchUser(1)
for i := 1; i <= toatlPage; i++ {
pageNoList = append(pageNoList, i)
}
storeMapList, _ := dao.GetStoreMapsListWithoutDisabled(db, []int{model.VendorIDJD}, model.StoreStatusDisabled)
for _, v := range storeMapList {
jxVendorIDsMap[v.VendorStoreID] = utils.Int64ToStr(int64(v.StoreID))
}
taskFunc1 := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
pageNo := batchItemList[0].(int)
storeUserLists, _, _, err := jd.GetAPI(v).PrivilegeSearchUser(pageNo)
retVal = storeUserLists
return retVal, err
}
taskParallel1 := tasksch.NewParallelTask("获取京东商城所有用户列表", tasksch.NewParallelConfig(), ctx, taskFunc1, pageNoList)
tasksch.HandleTask(taskParallel1, task, true).Run()
storeUserList, err = taskParallel1.GetResult(0)
taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
vv := batchItemList[0].(*jdapi.StoreUserInfo)
vendorStoreIDs, err := jd.GetAPI(v).GetJdUserBindStoreIDs(vv.ID)
var vendorStoreIDsMap = make(map[string]string, len(vendorStoreIDs))
var vendorStoreIDsResult []string
var roleNameStr string
for _, v := range vendorStoreIDs {
if jxVendorIDsMap[v] == "" {
continue
}
vendorStoreIDsMap[v] = jxVendorIDsMap[v]
}
if vv.RoleNameStr != "" {
roleNameStr = strings.ReplaceAll(vv.RoleNameStr, " ", "")
if roleNameStr != jdapi.JdUserRoleJHYName && roleNameStr != jdapi.JdUserRolesName && roleNameStr != jdapi.JdUserNoRole {
jd.GetAPI(v).UpdateJdUserRoles(int64(vv.ID), []string{jdapi.JdUserRoleJHYId})
}
}
if len(vendorStoreIDsMap) == 0 {
isManager, _ := jd.GetAPI(v).IsJdManagerUser(int64(vv.ID))
if isManager {
jdStruct := JdUserStruct{vv.LoginName, "商家管理员", vv.RoleNameStr, vv.LockStatus}
jdUsersStruct.AppendData(jdStruct)
} else {
retVal = []int64{int64(vv.ID)}
}
} else {
for _, m := range vendorStoreIDsMap {
vendorStoreIDsResult = append(vendorStoreIDsResult, m)
}
sort.Strings(vendorStoreIDsResult[:])
jdStruct := JdUserStruct{vv.LoginName, strings.Join(vendorStoreIDsResult, ","), vv.RoleNameStr, vv.LockStatus}
jdUsersStruct.AppendData(jdStruct)
}
return retVal, err
}
taskParallel := tasksch.NewParallelTask("获取京东商城用户关联门店列表", tasksch.NewParallelConfig(), ctx, taskFunc, storeUserList)
tasksch.HandleTask(taskParallel, task, true).Run()
disabledIdList, err = taskParallel.GetResult(0)
taskFunc2 := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
id := batchItemList[0].(int64)
jd.GetAPI(v).PrivilegeUpdateJdUserStatus(id, jdapi.JdUserStatusDisable)
return retVal, err
}
taskParallel2 := tasksch.NewParallelTask("禁用未关联活跃门店用户", tasksch.NewParallelConfig(), ctx, taskFunc2, disabledIdList)
tasksch.HandleTask(taskParallel2, task, true).Run()
_, err = taskParallel2.GetResult(0)
}
case 1:
WriteToExcelJd(task, jdUsersStruct.userMap)
}
return result, err
}
taskSeq := tasksch.NewSeqTask2("获取京东商城用户关联门店列表-序列任务", ctx, isContinueWhenError, taskSeqFunc, 2)
tasksch.HandleTask(taskSeq, nil, true).Run()
if !isAsync {
_, err = taskSeq.GetResult(0)
hint = "1"
} else {
hint = taskSeq.GetID()
}
return hint, err
}
func (d *GetJdUsersStruct) AppendData(jd JdUserStruct) {
d.locker.RLock()
defer d.locker.RUnlock()
d.userMap = append(d.userMap, jd)
}
func WriteToExcelJd(task *tasksch.SeqTask, jd []JdUserStruct) (err error) {
var sheetList []*excel.Obj2ExcelSheetConfig
var downloadURL, fileName string
excelConf := &excel.Obj2ExcelSheetConfig{
Title: "京东用户列表",
Data: jd,
CaptionList: titleListJdUser,
}
sheetList = append(sheetList, excelConf)
if excelConf != nil {
downloadURL, fileName, err = jxutils.UploadExeclAndPushMsg(sheetList, "京东用户列表")
} else {
baseapi.SugarLogger.Debug("WriteToExcel: JdUserStruct is nil!")
}
if err != nil {
baseapi.SugarLogger.Errorf("WriteToExcel:upload %s,failed error:%v", fileName, err)
} else {
noticeMsg := fmt.Sprintf("[详情点我]path=%s, \n", downloadURL)
task.SetNoticeMsg(noticeMsg)
baseapi.SugarLogger.Debugf("WriteToExcel:upload %s, success, downloadURL:%s", fileName, downloadURL)
}
return err
}
func UpdateUserWxNoAndPercent(user *model.User, isReceiver bool) (num int64, err error) {
db := dao.GetDB()
user2, err := dao.GetUserByID(db, "user_id", user.UserID)
auth, err := dao.GetUserBindAuthInfo(db, user.UserID, model.AuthBindTypeAuth, []string{"weixinmini"}, "", "", []string{"wx4b5930c13f8b1170"})
if len(auth) == 0 {
return 0, fmt.Errorf("未找到此用户的微信验证方式用户ID[%v]\n", user.UserID)
}
txDB, _ := dao.Begin(db)
defer func() {
if r := recover(); r != nil || err != nil {
dao.Rollback(db, txDB)
if r != nil {
panic(r)
}
}
}()
user2.DividePercentage = user.DividePercentage
num2, err := dao.UpdateEntity(db, user2, "DividePercentage")
num += num2
if err != nil {
dao.Rollback(db, txDB)
}
if isReceiver {
}
dao.Commit(db, txDB)
return num, err
}
func DeleteUserInfo(ctx *jxcontext.Context, userID string) (err error) {
db := dao.GetDB()
sql := `
UPDATE user
SET status = ?
WHERE user_id = ?
`
sqlParams := []interface{}{
model.NO,
userID,
}
_, err = dao.ExecuteSQL(db, sql, sqlParams)
/* 删除离职人员门店市场人员 */
sql2 := `
UPDATE store t1
LEFT JOIN user t2 ON t2.mobile = t1.market_man_phone AND t2.status <> 0
SET t1.market_man_phone = ''
WHERE t2.id IS NULL
`
_, err = dao.ExecuteSQL(db, sql2)
/* 删除离职人员门店运营人员 */
sql3 := `
UPDATE store t1
LEFT JOIN user t2 ON t2.mobile = t1.operator_phone AND t2.status <> 0
SET t1.operator_phone = ''
WHERE t2.id IS NULL
`
_, err = dao.ExecuteSQL(db, sql3)
/* 删除离职人员门店运营人员 */
sql4 := `
UPDATE store t1
LEFT JOIN user t2 ON t2.mobile = t1.operator_phone2 AND t2.status <> 0
SET t1.operator_phone2 = ''
WHERE t2.id IS NULL
`
_, err = dao.ExecuteSQL(db, sql4)
/*删除离职人员的角色信息*/
sql5 := `
DELETE t1
FROM casbin_rule t1
LEFT JOIN user t2 ON t2.user_id = t1.v0 AND t2.status <> 0
WHERE t2.id IS NULL
`
_, err = dao.ExecuteSQL(db, sql5)
//删除token
tokens, err := api.Cacher.Keys("TOKEN.V2." + userID + "*")
for _, v := range tokens {
err = api.Cacher.Del(v)
}
return err
}
func GetMyJxStoreList(ctx *jxcontext.Context, mobile string) (storesInfo interface{}, err error) {
db := dao.GetDB()
user, err := dao.GetUserByID(db, "mobile", mobile)
if err != nil {
return nil, err
}
userID := user.UserID
var storeList []*dao.StoreWithCityName
if storeList, err = GetStoreList4User(ctx, mobile, userID); err == nil && len(storeList) > 0 {
// todo应该用通用方法
mapDataList := make([]map[string]interface{}, len(storeList))
for k, v := range storeList {
mapDataList[k] = map[string]interface{}{
"id": v.ID,
"address": v.Address,
"cityName": v.CityName,
"name": v.Name,
"tel1": v.Tel1,
"tel2": v.Tel2,
"payeeName": v.PayeeName,
"status": v.Status,
}
}
storesInfo = mapDataList
}
return storesInfo, err
}
func CreateUserAgreement(ctx *jxcontext.Context, userAgrs []*model.UserAgreement) (err error) {
var (
db = dao.GetDB()
)
for _, v := range userAgrs {
dao.WrapAddIDCULDEntity(v, ctx.GetUserName())
}
err = dao.CreateMultiEntities(db, userAgrs)
return err
}
func GetUserAgreement(ctx *jxcontext.Context, name, idNumber, bankNumber, mobile string) (userAgrs []*model.UserAgreement, err error) {
var (
db = dao.GetDB()
)
userAgrs, err = dao.GetUserAgreement(db, name, idNumber, bankNumber, mobile)
return userAgrs, err
}
func CleanUserOrderSMSMark(ctx *jxcontext.Context) (err error) {
var (
db = dao.GetDB()
)
if time.Now().Day() == 1 {
sql := `
UPDATE user_order_sms
SET sms_mark = ?
`
sqlParams := []interface{}{model.NO}
_, err = dao.ExecuteSQL(db, sql, sqlParams)
}
return err
}
func RefreshUserMemberStatus(ctx *jxcontext.Context) (err error) {
var (
db = dao.GetDB()
)
userMembers, err := dao.GetUserMember(db, "", "", "", -1, model.MemberTypeDiscountCard, -1)
for _, userMember := range userMembers {
if time.Now().Sub(userMember.EndAt) > 0 {
userMember.DeletedAt = time.Now()
dao.UpdateEntity(db, userMember, "DeletedAt")
}
}
return err
}
func UpdateUserLastInfo(ctx *jxcontext.Context, storeID, brandID int) (err error) {
var (
db = dao.GetDB()
)
if user, err := dao.GetUserByID(db, "user_id", ctx.GetUserID()); err == nil {
//本次与上次不同时再更新
if storeID != user.LastStoreID {
user.LastStoreID = storeID
_, err = dao.UpdateEntity(db, user, "LastStoreID")
}
// 不应该出现这种情况0表示未找到1表示找到其他值为门店ID表示锁定店铺。
if user.LastBrandID > 1 && user.LastBrandID != storeID {
brandID = 0
}
if brandID != user.LastBrandID {
user.LastBrandID = brandID
_, err = dao.UpdateEntity(db, user, "LastBrandID")
}
}
return err
}
func SetUserCId(userId string, cid string) error {
var db = dao.GetDB()
userObj, err := dao.GetUserByID(db, "user_id", userId)
if err != nil {
return err
}
if userObj.CID == "" || userObj.CID != cid {
userObj.CID = cid
_, err := dao.UpdateEntity(db, userObj, "CID")
return err
}
return nil
}
func GetUserStoreAuth(ctx *jxcontext.Context, storeID int) (outStoreID int, err error) {
if permission.IsRoled(ctx) {
configs, _ := dao.QueryConfigs(dao.GetDB(), "checkversion", model.ConfigTypeSys, "")
storeMaps, _, err := GetMyStoreListNew(ctx, configs[0].Value)
if err != nil {
return 0, err
}
for _, v := range storeMaps.([]map[string]interface{}) {
if v["id"].(int) != storeID {
continue
}
return storeID, nil
}
//storeMap, _ := permission.GetUserStoresResultMap(ctx.GetUserID())
//if storeMap[storeID] != 0 {
// return storeID, err
//} else {
// return 0, err
//}
}
return storeID, err
}
func SendQywxPeopleCount(ctx *jxcontext.Context) (err error) {
var (
db = dao.GetDB()
groupIDMap = make(map[string][]interface{})
)
if beego.BConfig.RunMode == model.ServerTypeFruits {
groupIDMap[qywxapi.GyGroupID] = []interface{}{1, "京西果园"}
} else {
groupIDMap[qywxapi.BldGroupID] = []interface{}{7, "京西超市"}
groupIDMap[qywxapi.CsGroupID] = []interface{}{1, "京西菜市"}
}
//先找出群组中所有的unionID
for groupID, list := range groupIDMap {
var (
unionIDMap = make(map[string]string)
mobileMap = make(map[string]string)
mobileExistMap = make(map[string]string)
mobiles []string
)
stores, _ := dao.GetStoreList(db, nil, nil, []int{model.StoreStatusOpened}, []int{int(utils.Interface2Int64WithDefault(list[0], 0))}, nil, "")
for _, store := range stores {
if store.Tel1 != "" {
mobileMap[store.Tel1] = store.Tel1
}
if store.Tel2 != "" {
mobileMap[store.Tel2] = store.Tel2
}
}
group, _ := api.QywxAPI.Groupchat(groupID)
for _, member := range group.GroupChat.MemberList {
if member.UnionID != "" {
unionIDMap[member.UnionID] = member.UnionID
}
}
//再找出群组中所有unionID对应的电话
for _, v := range unionIDMap {
binds, _ := dao.GetUserBindAuthInfo(db, "", model.AuthBindTypeAuth, nil, "", v, nil)
if len(binds) > 0 {
user, _ := dao.GetUserByID(db, "user_id", binds[0].UserID)
if user != nil && user.Mobile != nil {
mobileExistMap[*user.Mobile] = *user.Mobile
}
}
}
for _, v := range mobileMap {
if mobileExistMap[v] == "" {
mobiles = append(mobiles, v)
}
}
//最后找出已有门店电话不在已有群组里的发消息
userMobileMap := make(map[string][]*model.Store)
for _, v := range mobiles {
store := &model.Store{}
sql := `
SELECT * FROM store WHERE (tel1 = ? OR tel2 = ?) AND deleted_at = ?
`
sqlParams := []interface{}{v, v, utils.DefaultTimeValue}
dao.GetRow(db, &store, sql, sqlParams)
if store != nil {
if mobileExistMap[store.Tel1] != "" || mobileExistMap[store.Tel2] != "" {
continue
}
//发消息
var (
userIDMap = make(map[string]string)
)
operatorRoleList := []string{store.OperatorRole, store.OperatorRole2, store.OperatorRole3}
for _, vv := range operatorRoleList {
var (
roleList []*authz.RoleInfo
)
if vv != "" {
roleList = append(roleList, autils.NewRole(vv, 0))
if userIDMap2, err := GetRolesUserList(jxcontext.AdminCtx, roleList); err == nil {
for _, w := range userIDMap2 {
for _, ww := range w {
userIDMap[ww] = ww
}
}
}
}
//noticeMsg := fmt.Sprintf("您有负责的商家还未加入相应的[%s]沟通群门店ID :[%d],门店名:[%s],商家电话:[%s,%s]", list[1].(string), store.ID, store.Name, store.Tel1, store.Tel2)
user2, err := dao.GetUserByID(db, "mobile", store.MarketManPhone)
if err == nil {
userIDMap[user2.UserID] = user2.UserID
for _, v := range userIDMap {
userMobileMap[v] = append(userMobileMap[v], store)
//if api.DingDingAPI.GetToken() != "" {
//ddmsg.SendUserMessage(dingdingapi.MsgTyeText, v, "您有商家还未加入企业微信群", noticeMsg)
//}
}
}
}
}
}
//一次发太多了,尝试分组发
groupList := []string{}
groupListAll := [][]string{}
for k, v := range userMobileMap {
msg := fmt.Sprintf("您有负责的商家还未加入相应的[%s]沟通群,门店信息 :", list[1].(string))
for i := 0; i < len(v); i++ {
if (i+1)%25 != 0 {
msg += utils.Int2Str(v[i].ID) + "" + v[i].Name + ",商家电话:" + v[i].Tel1 + "" + v[i].Tel2 + ",平台负责人:" + v[i].MarketManPhone + ""
} else {
groupList = append(groupList, k, msg)
groupListAll = append(groupListAll, groupList)
groupList = []string{}
msg = fmt.Sprintf("您有负责的商家还未加入相应的[%s]沟通群,门店信息 :", list[1].(string))
msg += utils.Int2Str(v[i].ID) + "" + v[i].Name + ",商家电话:" + v[i].Tel1 + "" + v[i].Tel2 + ",平台负责人:" + v[i].MarketManPhone + ""
}
if i == len(v)-1 {
groupList = append(groupList, k, msg)
groupListAll = append(groupListAll, groupList)
}
}
}
for _, v := range groupListAll {
if api.DingDingAPI.GetToken() != "" {
ddmsg.SendUserMessage(dingdingapi.MsgTyeText, v[0], "您有商家还未加入企业微信群", v[1])
}
}
}
return err
}
type UserInfo struct {
model.User
WxInfo string `json:"wxInfo"`
BrandMaps []*BrandMap `json:"brandMaps"`
}
type BrandMap struct {
BrandID int `orm:"column(brand_id)" json:"brandID"`
Name string `json:"name"`
ManageCount int `json:"managerCount"`
Balance int `json:"balance"`
}
func GetUserInfo(ctx *jxcontext.Context) (userInfo *UserInfo, err error) {
var (
db = dao.GetDB()
)
sql := `
SELECT a.*, b.detail_data wx_info
FROM user a
LEFT JOIN auth_bind b ON a.user_id = b.user_id AND b.type_id = ? AND b.type = ?
WHERE a.user_id = ?
`
sqlParams := []interface{}{"wx2bb99eb5d2c9b82c", "weixinsns", ctx.GetUserID()}
if err = dao.GetRow(db, &userInfo, sql, sqlParams); err == nil && userInfo != nil {
if brandUsers, _ := dao.GetBrandUser(db, 0, ctx.GetUserID()); len(brandUsers) > 0 {
for _, v := range brandUsers {
brands, _ := dao.GetBrands(db, "", v.BrandID, "", false, "")
balance, _ := partner.CurStoreAcctManager.GetBrandBalance(v.BrandID)
brandMap := &BrandMap{
BrandID: v.BrandID,
Name: brands[0].Name,
Balance: balance,
}
stores, _ := dao.GetStoreList(db, nil, nil, nil, []int{v.BrandID}, nil, "")
brandMap.ManageCount = len(stores)
userInfo.BrandMaps = append(userInfo.BrandMaps, brandMap)
}
}
}
return userInfo, err
}