1348 lines
42 KiB
Go
1348 lines
42 KiB
Go
package cms
|
||
|
||
import (
|
||
"encoding/base64"
|
||
"encoding/json"
|
||
"errors"
|
||
"fmt"
|
||
"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"
|
||
beego "github.com/astaxie/beego/server/web"
|
||
"sort"
|
||
"strings"
|
||
"sync"
|
||
"time"
|
||
|
||
"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) {
|
||
globals.SugarLogger.Debugf("GetUser, authID:%s, authIDType:%s", authID, authIDType)
|
||
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 // 先不区分商户与消息者
|
||
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 {
|
||
// globals.SugarLogger.Debugf("testRegisterUserWithMobile", utils.Format4Output(mobileAuth, false), utils.Format4Output(newAuthInfo, false))
|
||
// 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) {
|
||
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)
|
||
globals.SugarLogger.Warn(msg)
|
||
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.AutonaviAPI.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) {
|
||
globals.SugarLogger.Debugf("CreateUser user:%s, creatorName:%s", utils.Format4Output(user, true), creatorName)
|
||
|
||
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 != "" && 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)
|
||
}
|
||
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)
|
||
globals.SugarLogger.Debugf("OnDingDingMsg dingding user:%s left company", userIDStr)
|
||
if authBind, err = dao.GetAuthBind(db, model.AuthBindTypeAuth, dingding.AuthTypeStaff, userIDStr); err == nil { // 直接找到了
|
||
globals.SugarLogger.Debugf("OnDingDingMsg dingding user:%s, userID:%s left company", userIDStr, authBind.UserID)
|
||
if err = DisableUser(jxcontext.AdminCtx, authBind.UserID); err != nil {
|
||
globals.SugarLogger.Errorf("OnDingDingMsg failed with error:%v", err)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
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)
|
||
return storeList, err
|
||
}
|
||
|
||
func GetMyStoreListNew(ctx *jxcontext.Context) (storesInfo interface{}, errCode string, err error) {
|
||
if !auth2.IsV2Token(ctx.GetToken()) {
|
||
return nil, model.ErrCodeTokenIsInvalid, model.ErrTokenIsInvalid
|
||
}
|
||
mobile, userID := ctx.GetMobileAndUserID()
|
||
if mobile == "" {
|
||
return nil, "", fmt.Errorf("不能得到用户手机号")
|
||
}
|
||
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 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) (formattedAddress string, districtCode, cityCode int, err error) {
|
||
regeoInfo, err := api.AutonaviAPI.GeoCodeRegeoSingle(lng, lat, 0, false, nil, 0, 0)
|
||
if err == nil {
|
||
formattedAddress = regeoInfo.FormattedAddress
|
||
districtCode = int(utils.Str2Int64WithDefault(regeoInfo.AddressComponent.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
|
||
}
|
||
}
|
||
return formattedAddress, districtCode, cityCode, err
|
||
}
|
||
|
||
func AddUserDeliveryAddress(ctx *jxcontext.Context, address *model.UserDeliveryAddress) (outAddress *model.UserDeliveryAddress, err error) {
|
||
globals.SugarLogger.Debugf("AddUserDeliveryAddress1 address:%s", utils.Format4Output(address, true))
|
||
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)
|
||
if err == nil {
|
||
globals.SugarLogger.Debugf("AddUserDeliveryAddress2 address:%s", utils.Format4Output(address, true))
|
||
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)
|
||
}
|
||
}
|
||
globals.SugarLogger.Debugf("AddUserDeliveryAddress3 address:%s", utils.Format4Output(address, true))
|
||
return outAddress, err
|
||
}
|
||
|
||
func AddMyDeliveryAddress(ctx *jxcontext.Context, address *model.UserDeliveryAddress) (outAddress *model.UserDeliveryAddress, err error) {
|
||
globals.SugarLogger.Debugf("AddMyDeliveryAddress address:%s", utils.Format4Output(address, true))
|
||
_, address.UserID = ctx.GetMobileAndUserID()
|
||
outAddress, err = AddUserDeliveryAddress(ctx, address)
|
||
globals.SugarLogger.Debugf("AddMyDeliveryAddress2 address:%s, err:%v", utils.Format4Output(address, true), err)
|
||
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)
|
||
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, nil)
|
||
|
||
/* 删除离职人员门店运营人员 */
|
||
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, nil)
|
||
|
||
/* 删除离职人员门店运营人员 */
|
||
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, nil)
|
||
|
||
/*删除离职人员的角色信息*/
|
||
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, nil)
|
||
|
||
//删除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 != 0 {
|
||
user.LastStoreID = storeID
|
||
_, err = dao.UpdateEntity(db, user, "LastStoreID")
|
||
}
|
||
if brandID != 0 {
|
||
user.LastBrandID = brandID
|
||
_, err = dao.UpdateEntity(db, user, "LastBrandID")
|
||
}
|
||
}
|
||
return err
|
||
}
|
||
|
||
func GetUserStoreAuth(ctx *jxcontext.Context, storeID int) (outStoreID int, err error) {
|
||
if permission.IsRoled(ctx) {
|
||
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 == "jxgy" {
|
||
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 + ","
|
||
} 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 + ","
|
||
}
|
||
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
|
||
}
|