com_handler_user.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. package services
  2. import (
  3. "app/commons/constant"
  4. "app/commons/core"
  5. "app/commons/model/entity"
  6. "app/commons/utils"
  7. "encoding/json"
  8. "fmt"
  9. "github.com/samber/lo"
  10. "gorm.io/gorm"
  11. "time"
  12. )
  13. // tips:
  14. // 用户信息处理
  15. // 使用地址或用户ID获取用户信息
  16. func (s *CommonService) GetUserByUserUid(uid interface{}) (*entity.User, error) {
  17. return GetOne[entity.User](s.DB().Where("uid", uid))
  18. }
  19. func (s *CommonService) GetUserByUserId(userId interface{}) (*entity.User, error) {
  20. return GetOne[entity.User](s.DB().Where("id", userId))
  21. }
  22. func (s *CommonService) GetUserByCode(code interface{}) (*entity.User, error) {
  23. return GetOne[entity.User](s.DB().Where("code", code))
  24. }
  25. func (s *CommonService) GetUserInfoByOpenId(openId string) (*entity.User, error) {
  26. row, err := GetOne[entity.User](s.DB(), "open_id", openId)
  27. if err != nil {
  28. return nil, fmt.Errorf("user not found")
  29. }
  30. return row, nil
  31. }
  32. // 用户登陆时使用 isLogin = true
  33. func (s *CommonService) CheckUserWithOpenIdAndUid(openId string, uid string, isLogin bool) (*entity.User, error) {
  34. if uid == "" {
  35. return nil, fmt.Errorf("uid is null")
  36. }
  37. if isLogin {
  38. if openId == "" {
  39. return nil, fmt.Errorf("open_id is null")
  40. }
  41. }
  42. user, err := GetOne[entity.User](s.DB(), "uid", uid)
  43. if err == nil {
  44. if openId != "" && user.OpenId != openId {
  45. s.DB().Model(entity.User{}).Where("id", user.Id).Update("open_id", openId)
  46. }
  47. core.Log.Infof("用户授权登录,检查用户openId:%+v,存在老用户", openId)
  48. return user, nil
  49. }
  50. inviteCode, err := s.genInviteCode()
  51. if err != nil {
  52. return nil, err
  53. }
  54. return s.newUser(openId, uid, inviteCode)
  55. }
  56. var userInvites []string
  57. func (s *CommonService) initUserInvites() error {
  58. return s.DB().Model(&entity.User{}).Where("1=1").Select("code").Scan(&userInvites).Error
  59. }
  60. func (s *CommonService) genInviteCode() (string, error) {
  61. if len(userInvites) == 0 {
  62. if err := s.initUserInvites(); err != nil {
  63. return "", err
  64. }
  65. }
  66. i := 0
  67. // 使用预生成邀请码
  68. for {
  69. if i > 10 {
  70. return "", fmt.Errorf("gen invite code faild")
  71. }
  72. newInvite := utils.RandStr(6)
  73. if !lo.Contains(userInvites, newInvite) {
  74. userInvites = append(userInvites, newInvite)
  75. return newInvite, nil
  76. }
  77. i++
  78. }
  79. }
  80. func (s *CommonService) newUser(openId string, uid string, inviteCode string) (*entity.User, error) {
  81. core.Log.Infof("创建新用户,请求参数,uid:%+v,openId:%v", uid, openId)
  82. var err error
  83. // 新用户
  84. txDb := s.DB().Begin()
  85. newUser := &entity.User{
  86. OpenId: openId,
  87. Code: inviteCode,
  88. Uid: uid,
  89. RefCode: "",
  90. ParentId: 0,
  91. ParentIds: []int64{},
  92. Enable: true,
  93. LockWithdraw: true,
  94. }
  95. err = txDb.Create(&newUser).Error
  96. if err != nil {
  97. txDb.Rollback()
  98. core.Log.Errorf("创建新用户失败,更新老用户资产信息失败,uid:%+v,错误:%v", uid, err)
  99. return nil, err
  100. }
  101. quota := entity.NewUserQuota()
  102. quota.UserId = newUser.Id
  103. quota.Uid = uid
  104. err = txDb.Create(&quota).Error
  105. if err != nil {
  106. txDb.Rollback()
  107. core.Log.Errorf("Create quota ,uid:%+v,错误:%v", uid, err)
  108. return nil, err
  109. }
  110. // 获取所有资产 并创建资产账号
  111. _, err = s.GetAndCheckAssets(newUser.Id, newUser.Uid)
  112. if err != nil {
  113. txDb.Rollback()
  114. core.Log.Errorf("GetAndCheckAssets uid:%+v,错误:%v", uid, err)
  115. return nil, err
  116. }
  117. txDb.Commit()
  118. return newUser, nil
  119. }
  120. // 用户失效/生效
  121. func (s *CommonService) ActiveUser(db *gorm.DB, id int64, active bool) error {
  122. return db.Model(&entity.User{}).Where("id", id).Update("is_active", active).Error
  123. }
  124. // 方法适用于前端api设置 以及管理后台修改
  125. // 1 正常设置上级 ("1","2",false)
  126. // 2 重置上级 ("1","",true)
  127. // 3 强制修改上级 ("1","3",true)
  128. func (s *CommonService) SetParentWithUid(uid, parentUid string, opId string, isSystem bool) error {
  129. var err error
  130. var user, parent *entity.User
  131. user, err = s.GetUserByUserUid(uid)
  132. if err != nil {
  133. return fmt.Errorf(constant.ErrorInfo)
  134. }
  135. // 非系统设置
  136. if !isSystem {
  137. if user.ParentId != 0 || user.RefCode != "" {
  138. return fmt.Errorf("一仆不事二主")
  139. }
  140. }
  141. if parentUid != "" {
  142. parent, err = s.GetUserByUserUid(parentUid)
  143. if err != nil {
  144. return fmt.Errorf("上级不存在")
  145. }
  146. if parent.Id == user.Id {
  147. return fmt.Errorf("禁止设置自己为上级")
  148. }
  149. // 设置了死循环
  150. if lo.Contains(parent.ParentIds, user.Id) {
  151. return fmt.Errorf("禁止设置下线为上级")
  152. }
  153. }
  154. dbTx := s.DB().Begin()
  155. user.ParentIds = []int64{}
  156. if parent.Id != 0 {
  157. if err = dbTx.Model(&entity.UserQuota{}).
  158. Where("user_id", parent.Id).
  159. Updates(map[string]interface{}{
  160. "invite_count": gorm.Expr("invite_count + ?", 1),
  161. "team_count": gorm.Expr("team_count + ?", 1),
  162. }).Error; err != nil {
  163. dbTx.Rollback()
  164. return err
  165. }
  166. if err = dbTx.Model(&entity.UserQuota{}).
  167. Where("user_id in (?)", parent.ParentIds).
  168. Updates(map[string]interface{}{
  169. "team_count": gorm.Expr("team_count + ?", 1),
  170. }).Error; err != nil {
  171. dbTx.Rollback()
  172. return err
  173. }
  174. user.ParentIds = append([]int64{parent.Id}, parent.ParentIds...)
  175. }
  176. parentIdsData, err := json.Marshal(user.ParentIds)
  177. if err != nil {
  178. dbTx.Rollback()
  179. return err
  180. }
  181. if err = dbTx.Model(&entity.User{}).
  182. Where("id", user.Id).
  183. Updates(map[string]interface{}{
  184. "parent_id": parent.Id,
  185. "ref_code": parent.Code,
  186. "parent_uid": parent.Uid,
  187. "parent_ids": parentIdsData,
  188. }).Error; err != nil {
  189. dbTx.Rollback()
  190. return err
  191. }
  192. userQuotaUpdateMap := map[string]interface{}{
  193. "parent_id": parent.Id,
  194. "parent_uid": parent.Uid,
  195. "parent_update_time": time.Now().Unix(),
  196. }
  197. if user.ParentId == 0 && parent.Id != 0 {
  198. userQuotaUpdateMap["parent_set_time"] = time.Now().Unix()
  199. }
  200. if err = dbTx.Model(&entity.UserQuota{}).
  201. Where("user_id", user.Id).
  202. Updates(userQuotaUpdateMap).Error; err != nil {
  203. dbTx.Rollback()
  204. return err
  205. }
  206. opsName := fmt.Sprintf("SetParentWithUid ByUser:%s", opId)
  207. if isSystem {
  208. opsName = fmt.Sprintf("SetParentWithUid ByAdmin:%s", opId)
  209. }
  210. // 记录用户修改关系记录
  211. err = s.CreateUserRelationActionLog(dbTx, user, opsName, user.ParentUid, parent.Uid)
  212. if err != nil {
  213. dbTx.Rollback()
  214. return err
  215. }
  216. dbTx.Commit()
  217. return nil
  218. }