package cms import ( "errors" "fmt" "sync" "time" "git.rosy.net.cn/jx-callback/business/jxutils/smsmsg" "git.rosy.net.cn/jx-callback/business/jxstore/event" "git.rosy.net.cn/jx-callback/business/jxstore/financial" "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/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" ) 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 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 createName := ctx.GetRealRemoteIP() authType := auth2.AuthTypeMobile if manTokenInfo != nil && mobileVerifyCode == "" { _, err2 := dao.GetUserByID(dao.GetDB(), "user_id", manTokenInfo.GetID()) if err = err2; err != nil { return nil, err } if utils.Pointer2String(user.Mobile) == "" { return nil, fmt.Errorf("管理员添加必须指定用户手机号") } mobileVerifyCode = auth2.InternalAuthSecret fakeMobile = true 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 nil, 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 { 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) } //给用户添加一条账单记录 err = AddUserBill(user) } else if dao.IsDuplicateError(err) { err = auth2.ErrUserID2AlreadyExist } return outAuthInfo, err } func AddUserBill(user *model.User) (err error) { var ( db = dao.GetDB() ) userBill := &model.UserBill{ BillID: jxutils.GenBillID(), UserID: user.UserID, } dao.WrapAddIDCULDEntity(userBill, jxcontext.AdminCtx.GetUserName()) return dao.CreateEntity(db, userBill) } 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 } dao.WrapAddIDCULDEntity(user, creatorName) user.UserID = utils.GetUUID() user.Status = model.UserStatusNormal //推广码 popCode := "" for { popCode = jxutils.GenRandomString(6) user2, _ := dao.GetUserByID(dao.GetDB(), "pop_code", popCode) if user2 == nil { user.PopCode = popCode break } } 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, keyword string, userID string, pop int, mobile string, fromTime, toTime string, timeType int, cityCodes, consumeTypes []int, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) { return dao.GetUsers2(dao.GetDB(), keyword, userID, pop, mobile, utils.Str2Time(fromTime), utils.Str2Time(toTime), timeType, cityCodes, consumeTypes, offset, pageSize) } func GetUser(ctx *jxcontext.Context, userID string) (user *model.GetUserResult, err error) { return dao.GetUser(dao.GetDB(), userID) } 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 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 AddMyDeliveryAddress(ctx *jxcontext.Context, address *model.UserDeliveryAddress) (outAddress *dao.UserDeliveryAddressEx, err error) { globals.SugarLogger.Debugf("AddMyDeliveryAddress address:%s", utils.Format4Output(address, true)) _, address.UserID = ctx.GetMobileAndUserID() out, err := AddUserDeliveryAddress(ctx, address) list, _, err := dao.QueryUserDeliveryAddress(dao.GetDB(), int64(out.ID), nil, 0, 0, -1) globals.SugarLogger.Debugf("AddMyDeliveryAddress2 address:%s, err:%v", utils.Format4Output(address, true), err) return list[0], 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, 0, offset, pageSize) if err == nil { pagedInfo = &model.PagedInfo{ TotalCount: totalCount, Data: addressList, } } return pagedInfo, err } func QueryMyDeliveryAddress(ctx *jxcontext.Context, addType int) (addressList []*dao.UserDeliveryAddressEx, err error) { _, userID := ctx.GetMobileAndUserID() addressList, _, err = dao.QueryUserDeliveryAddress(dao.GetDB(), 0, []string{userID}, addType, 0, model.UnlimitedPageSize) return addressList, 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 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.User.UserID, 0); err3 == nil { getSelfInfoResult.UserMembers = userMembers } else { err = err3 } if price, err := dao.GetUserAllWaitCashPrice(dao.GetDB(), getSelfInfoResult.User.UserID); err == nil { getSelfInfoResult.WaitCashPrice = price } if price, err := dao.GetUserAllWaitRealCashPrice(dao.GetDB(), getSelfInfoResult.User.UserID); err == nil { getSelfInfoResult.WaitRealCashPrice = price } } } return getSelfInfoResult, err } func RefreshUserMemberStatus(ctx *jxcontext.Context) (err error) { var ( db = dao.GetDB() ) userMembers, err := dao.GetUserMember(db, "", 0) for _, userMember := range userMembers { if time.Now().Sub(userMember.EndAt) > 0 { userMember.DeletedAt = time.Now() dao.UpdateEntity(db, userMember, "DeletedAt") } } return err } func InvestMember(ctx *jxcontext.Context, memberID int, userID string, isFree bool) (errCode string, err error) { var ( db = dao.GetDB() memberCards []*model.MemberCard memberCard *model.MemberCard userIDReal string ) if !isFree { userIDReal = ctx.GetUserID() } else { userIDReal = userID } userMembers, err := dao.GetUserMember(db, userIDReal, model.MemberTypeNormal) configList, err := dao.QueryConfigs(db, model.ConfigTypeName[model.ConfigTypeMemberCard], model.ConfigTypeMemberCard, "") userBill, err := dao.GetUserBill(db, userIDReal, "") if len(configList) <= 0 { return "", fmt.Errorf("未找到会员卡配置!") } config := configList[0] err = jxutils.Strings2Objs(config.Value, &memberCards) if err != nil { return "", err } for _, v := range memberCards { if v.ID == memberID { memberCard = v } } txDB, _ := dao.Begin(db) defer func() { if r := recover(); r != nil { dao.Rollback(db, txDB) panic(r) } }() if !isFree { //验证微信绑定 if err = auth2.CheckWeixinminiAuthBind(userIDReal); err != nil { return "", err } if userBill.AccountBalance < memberCard.ActPrice { //if _, err := financial.WXInvestMember(ctx, userMembers[0].MemberTypeID, userMembers[0].UserID); err != nil { // dao.Rollback(db, txDB) //} return model.ErrCodeAccountBalanceNotEnough, fmt.Errorf("用户余额不足,请充值!") } } //证明已经开了会员了,相当于续费 if len(userMembers) > 0 { userMember := userMembers[0] if memberID == model.MemberCardTypeMonth { userMember.EndAt = userMember.EndAt.AddDate(0, 1, 0) } else { userMember.EndAt = userMember.EndAt.AddDate(1, 0, 0) } if _, err = dao.UpdateEntity(db, userMember, "EndAt"); err != nil { dao.Rollback(db, txDB) return } } else { userMember2 := &model.UserMember{ UserID: userIDReal, MemberType: model.MemberTypeNormal, MemberTypeID: memberID, } if memberID == model.MemberCardTypeMonth { userMember2.EndAt = time.Now().AddDate(0, 1, 0) } else { userMember2.EndAt = time.Now().AddDate(1, 0, 0) } dao.WrapAddIDCULDEntity(userMember2, ctx.GetUserName()) if err = dao.CreateEntity(db, userMember2); err != nil { dao.Rollback(db, txDB) return } } if !isFree { //支出明细 if err = financial.AddExpendUpdateAccount(txDB, userBill, model.BillTypeMember, memberCard.ActPrice, 0); err != nil { dao.Rollback(db, txDB) return } } dao.Commit(db, txDB) return errCode, err } func UpdateUser(ctx *jxcontext.Context, payload map[string]interface{}) (err error) { var ( db = dao.GetDB() userID string ) if payload["userID"] != nil { userID = payload["userID"].(string) } else { userID = ctx.GetUserID() } user := &model.User{ UserID: userID, } dao.GetEntity(db, user, "UserID") if payload["lng"] != nil && payload["lat"] != nil { if address, districtCode, cityCode, err := getAddressInfoFromCoord(db, utils.MustInterface2Float64(payload["lng"]), utils.MustInterface2Float64(payload["lat"])); err == nil { delete(payload, "lng") delete(payload, "lat") payload["address"] = address payload["districtCode"] = districtCode payload["cityCode"] = cityCode } else { return err } } //暂时用这个字段作为更新他的推广人 if payload["popCode"] != nil { if user, err := dao.GetUserByID(db, "pop_code", payload["popCode"].(string)); err == nil { if user != nil { payload["popUser"] = user.UserID delete(payload, "popCode") } else { return fmt.Errorf("未查询到此推广人!%v", payload["popCode"]) } } } valid := dao.StrictMakeMapByStructObject(payload, user, ctx.GetUserName()) if len(valid) > 0 { txDB, _ := dao.Begin(db) defer func() { if r := recover(); r != nil { dao.Rollback(db, txDB) panic(r) } }() if _, err = dao.UpdateEntityByKV(db, user, valid, nil); err != nil { dao.Rollback(db, txDB) return err } dao.Commit(db, txDB) } if payload["popUser"] != nil { // InvestMemberAndUpdate := func(user *model.User) (err error) { // if _, err = InvestMember(ctx, 1, user.UserID, true); err == nil { // } // user.PopFlag = model.YES // _, err = dao.UpdateEntity(db, user, "PopFlag") // return err // } user2, err2 := dao.GetUserByID(db, "user_id", payload["popUser"].(string)) err = err2 do := func(user *model.User, flag bool) (err error) { if user.PopCount%4 == 0 && user.PopFlag == model.NO { if _, err = InvestMember(ctx, 1, user.UserID, true); err == nil { //发短信,公众号消息通知 smsmsg.SendSMSMsg([]string{*user.Mobile}, globals.SMSSignName, globals.SMSPopSuccessTemplate, nil) // weixinmsg.SendMsgToUser(userID, templateID, data) event.SendSysMessageSimple("您好,您已成功邀请4人加入我们,成功免费获得1个月会员!", user.UserID) } user.PopFlag = model.YES dao.UpdateEntity(db, user, "PopFlag") if flag { if users, _, err := dao.GetUsers(db, 0, "", user.UserID, nil, nil, nil, 0, 999); err == nil { for _, v := range users { v.PopedFlag = model.YES dao.UpdateEntity(db, v, "PopedFlag") } } _, err = event.CreateMessageGroup(ctx, user.UserID, "", "", 5, 100) } } return err } if user2 != nil { user2.PopCount++ messageGroupsResult, err3 := dao.GetMessageGroups(db, user2.UserID, 0, model.GroupTypeMulit, false, "") err = err3 //如果他已经有群了,被邀请人直接进群 //如果他没群,在邀请到4个人的时候,自动创一个群,所有被邀请人打上标志 if len(messageGroupsResult) > 0 { err = event.AddMessageGroup(ctx, messageGroupsResult[0].GroupID, user.UserID) //邀请过4人直接开通一个月会员 do(user2, false) } else { //邀请过4人直接开通一个月会员并创建群组 do(user2, true) } dao.UpdateEntity(db, user2, "PopCount") } } return err } func AcceptAddGroup(ctx *jxcontext.Context, flag int) (err error) { var ( db = dao.GetDB() userID = ctx.GetUserID() ) user, err := dao.GetUserByID(db, "user_id", userID) if user == nil { return fmt.Errorf("获取用户信息失败!") } if err != nil { return err } if user.PopedFlag == model.NO { return fmt.Errorf("获取用户邀请信息失败") } //同意加入 if flag == model.YES { //1、找到这个人的邀请人 //2、这个邀请人有群就直接进,没群就加入失败了 messageGroupsResult, err := dao.GetMessageGroups(db, user.PopUser, 0, model.GroupTypeMulit, false, "") if err != nil { return fmt.Errorf("获取邀请人群信息失败! %v", err) } if len(messageGroupsResult) > 0 { err = event.AddMessageGroup(ctx, messageGroupsResult[0].GroupID, user.UserID) } else { return fmt.Errorf("获取邀请人群信息失败!") } } //同步同意都清标志 user.PopedFlag = model.NO dao.UpdateEntity(db, user, "PopedFlag") return err } type GetUserSerachKeywordResult struct { AllSpan []*model.UserSearch `json:"allSpan"` UserSpan []*model.UserSearch `json:"userSpan"` } func GetUserSerachKeyword(ctx *jxcontext.Context) (getUserSerachKeywordResult *GetUserSerachKeywordResult, err error) { var ( db = dao.GetDB() userID = ctx.GetUserID() userSearchAll []*model.UserSearch userSearch []*model.UserSearch ) getUserSerachKeywordResult = &GetUserSerachKeywordResult{} sql := ` SELECT keyword, SUM(count) count FROM user_search WHERE created_at > ? GROUP BY 1 ORDER BY SUM(count) DESC LIMIT 20 ` sqlParams := []interface{}{time.Now().AddDate(0, -1, 0)} err = dao.GetRows(db, &userSearchAll, sql, sqlParams) getUserSerachKeywordResult.AllSpan = userSearchAll sql2 := ` SELECT keyword, SUM(count) count FROM user_search WHERE created_at > ? AND user_id = ? GROUP BY 1 ORDER BY SUM(count) DESC LIMIT 20 ` sqlParams2 := []interface{}{time.Now().AddDate(0, -1, 0), userID} err = dao.GetRows(db, &userSearch, sql2, sqlParams2) getUserSerachKeywordResult.UserSpan = userSearch return getUserSerachKeywordResult, err }