package services import ( "app/commons/constant" "app/commons/core" "app/commons/model/entity" "app/commons/utils" "encoding/json" "fmt" "github.com/samber/lo" "gorm.io/gorm" "time" ) // tips: // 用户信息处理 // 使用地址或用户ID获取用户信息 func (s *CommonService) GetUserByUserUid(uid interface{}) (*entity.User, error) { return GetOne[entity.User](s.DB().Where("uid", uid)) } func (s *CommonService) GetUserByUserId(userId interface{}) (*entity.User, error) { return GetOne[entity.User](s.DB().Where("id", userId)) } func (s *CommonService) GetUserByCode(code interface{}) (*entity.User, error) { return GetOne[entity.User](s.DB().Where("code", code)) } func (s *CommonService) GetUserInfoByOpenId(openId string) (*entity.User, error) { row, err := GetOne[entity.User](s.DB(), "open_id", openId) if err != nil { return nil, fmt.Errorf("user not found") } return row, nil } // 用户登陆时使用 isLogin = true func (s *CommonService) CheckUserWithOpenIdAndUid(openId string, uid string, isLogin bool) (*entity.User, error) { if uid == "" { return nil, fmt.Errorf("uid is null") } if isLogin { if openId == "" { return nil, fmt.Errorf("open_id is null") } } user, err := GetOne[entity.User](s.DB(), "uid", uid) if err == nil { if openId != "" && user.OpenId != openId { s.DB().Model(entity.User{}).Where("id", user.Id).Update("open_id", openId) } core.Log.Infof("用户授权登录,检查用户openId:%+v,存在老用户", openId) return user, nil } inviteCode, err := s.genInviteCode() if err != nil { return nil, err } return s.newUser(openId, uid, inviteCode) } var userInvites []string func (s *CommonService) initUserInvites() error { return s.DB().Model(&entity.User{}).Where("1=1").Select("code").Scan(&userInvites).Error } func (s *CommonService) genInviteCode() (string, error) { if len(userInvites) == 0 { if err := s.initUserInvites(); err != nil { return "", err } } i := 0 // 使用预生成邀请码 for { if i > 10 { return "", fmt.Errorf("gen invite code faild") } newInvite := utils.RandStr(6) if !lo.Contains(userInvites, newInvite) { userInvites = append(userInvites, newInvite) return newInvite, nil } i++ } } func (s *CommonService) newUser(openId string, uid string, inviteCode string) (*entity.User, error) { core.Log.Infof("创建新用户,请求参数,uid:%+v,openId:%v", uid, openId) var err error // 新用户 txDb := s.DB().Begin() newUser := &entity.User{ OpenId: openId, Code: inviteCode, Uid: uid, RefCode: "", ParentId: 0, ParentIds: []int64{}, Enable: true, LockWithdraw: true, } err = txDb.Create(&newUser).Error if err != nil { txDb.Rollback() core.Log.Errorf("创建新用户失败,更新老用户资产信息失败,uid:%+v,错误:%v", uid, err) return nil, err } quota := entity.NewUserQuota() quota.UserId = newUser.Id quota.Uid = uid err = txDb.Create("a).Error if err != nil { txDb.Rollback() core.Log.Errorf("Create quota ,uid:%+v,错误:%v", uid, err) return nil, err } // 获取所有资产 并创建资产账号 _, err = s.GetAndCheckAssets(newUser.Id, newUser.Uid) if err != nil { txDb.Rollback() core.Log.Errorf("GetAndCheckAssets uid:%+v,错误:%v", uid, err) return nil, err } txDb.Commit() return newUser, nil } // 用户失效/生效 func (s *CommonService) ActiveUser(db *gorm.DB, id int64, active bool) error { return db.Model(&entity.User{}).Where("id", id).Update("is_active", active).Error } // 方法适用于前端api设置 以及管理后台修改 // 1 正常设置上级 ("1","2",false) // 2 重置上级 ("1","",true) // 3 强制修改上级 ("1","3",true) func (s *CommonService) SetParentWithUid(uid, parentUid string, opId string, isSystem bool) error { var err error var user, parent *entity.User user, err = s.GetUserByUserUid(uid) if err != nil { return fmt.Errorf(constant.ErrorInfo) } // 非系统设置 if !isSystem { if user.ParentId != 0 || user.RefCode != "" { return fmt.Errorf("一仆不事二主") } } if parentUid != "" { parent, err = s.GetUserByUserUid(parentUid) if err != nil { return fmt.Errorf("上级不存在") } if parent.Id == user.Id { return fmt.Errorf("禁止设置自己为上级") } // 设置了死循环 if lo.Contains(parent.ParentIds, user.Id) { return fmt.Errorf("禁止设置下线为上级") } } dbTx := s.DB().Begin() user.ParentIds = []int64{} if parent.Id != 0 { if err = dbTx.Model(&entity.UserQuota{}). Where("user_id", parent.Id). Updates(map[string]interface{}{ "invite_count": gorm.Expr("invite_count + ?", 1), "team_count": gorm.Expr("team_count + ?", 1), }).Error; err != nil { dbTx.Rollback() return err } if err = dbTx.Model(&entity.UserQuota{}). Where("user_id in (?)", parent.ParentIds). Updates(map[string]interface{}{ "team_count": gorm.Expr("team_count + ?", 1), }).Error; err != nil { dbTx.Rollback() return err } user.ParentIds = append([]int64{parent.Id}, parent.ParentIds...) } parentIdsData, err := json.Marshal(user.ParentIds) if err != nil { dbTx.Rollback() return err } if err = dbTx.Model(&entity.User{}). Where("id", user.Id). Updates(map[string]interface{}{ "parent_id": parent.Id, "ref_code": parent.Code, "parent_uid": parent.Uid, "parent_ids": parentIdsData, }).Error; err != nil { dbTx.Rollback() return err } userQuotaUpdateMap := map[string]interface{}{ "parent_id": parent.Id, "parent_uid": parent.Uid, "parent_update_time": time.Now().Unix(), } if user.ParentId == 0 && parent.Id != 0 { userQuotaUpdateMap["parent_set_time"] = time.Now().Unix() } if err = dbTx.Model(&entity.UserQuota{}). Where("user_id", user.Id). Updates(userQuotaUpdateMap).Error; err != nil { dbTx.Rollback() return err } opsName := fmt.Sprintf("SetParentWithUid ByUser:%s", opId) if isSystem { opsName = fmt.Sprintf("SetParentWithUid ByAdmin:%s", opId) } // 记录用户修改关系记录 err = s.CreateUserRelationActionLog(dbTx, user, opsName, user.ParentUid, parent.Uid) if err != nil { dbTx.Rollback() return err } dbTx.Commit() return nil }