sysUserModel.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. package user
  2. import (
  3. "context"
  4. "database/sql"
  5. "errors"
  6. "fmt"
  7. "strings"
  8. "time"
  9. "github.com/zeromicro/go-zero/core/stores/cache"
  10. "github.com/zeromicro/go-zero/core/stores/sqlx"
  11. )
  12. var ErrUpdateConflict = errors.New("update conflict: data has been modified by another operation")
  13. var _ SysUserModel = (*customSysUserModel)(nil)
  14. type (
  15. SysUserModel interface {
  16. sysUserModel
  17. FindListByPage(ctx context.Context, page, pageSize int64) ([]*SysUser, int64, error)
  18. FindListByProductMembers(ctx context.Context, productCode string, page, pageSize int64) ([]*SysUser, int64, error)
  19. FindByIds(ctx context.Context, ids []int64) ([]*SysUser, error)
  20. FindIdsByDeptId(ctx context.Context, deptId int64) ([]int64, error)
  21. UpdateProfile(ctx context.Context, id int64, username string, nickname, email, phone, remark string, deptId, newStatus int64, statusChanged bool, expectedUpdateTime int64) error
  22. UpdatePassword(ctx context.Context, id int64, password string, mustChangePassword int64) error
  23. UpdateStatus(ctx context.Context, id int64, status int64) error
  24. IncrementTokenVersion(ctx context.Context, id int64) (int64, error)
  25. }
  26. customSysUserModel struct {
  27. *defaultSysUserModel
  28. }
  29. )
  30. func NewSysUserModel(conn sqlx.SqlConn, c cache.CacheConf, cachePrefix string, opts ...cache.Option) SysUserModel {
  31. return &customSysUserModel{
  32. defaultSysUserModel: newSysUserModel(conn, c, cachePrefix, opts...),
  33. }
  34. }
  35. func (m *customSysUserModel) FindListByPage(ctx context.Context, page, pageSize int64) ([]*SysUser, int64, error) {
  36. var total int64
  37. countQuery := fmt.Sprintf("SELECT COUNT(*) FROM %s", m.table)
  38. if err := m.QueryRowNoCacheCtx(ctx, &total, countQuery); err != nil {
  39. return nil, 0, err
  40. }
  41. var list []*SysUser
  42. query := fmt.Sprintf("SELECT %s FROM %s ORDER BY id DESC LIMIT ?,?", sysUserRows, m.table)
  43. if err := m.QueryRowsNoCacheCtx(ctx, &list, query, (page-1)*pageSize, pageSize); err != nil {
  44. return nil, 0, err
  45. }
  46. return list, total, nil
  47. }
  48. func (m *customSysUserModel) FindListByProductMembers(ctx context.Context, productCode string, page, pageSize int64) ([]*SysUser, int64, error) {
  49. memberTable := "`sys_product_member`"
  50. var total int64
  51. countQuery := fmt.Sprintf("SELECT COUNT(*) FROM %s u INNER JOIN %s pm ON u.`id` = pm.`userId` WHERE pm.`productCode` = ?", m.table, memberTable)
  52. if err := m.QueryRowNoCacheCtx(ctx, &total, countQuery, productCode); err != nil {
  53. return nil, 0, err
  54. }
  55. var list []*SysUser
  56. fields := strings.Join(sysUserFieldNames, ",u.")
  57. query := fmt.Sprintf("SELECT u.%s FROM %s u INNER JOIN %s pm ON u.`id` = pm.`userId` WHERE pm.`productCode` = ? ORDER BY u.`id` DESC LIMIT ?,?", fields, m.table, memberTable)
  58. if err := m.QueryRowsNoCacheCtx(ctx, &list, query, productCode, (page-1)*pageSize, pageSize); err != nil {
  59. return nil, 0, err
  60. }
  61. return list, total, nil
  62. }
  63. func (m *customSysUserModel) FindIdsByDeptId(ctx context.Context, deptId int64) ([]int64, error) {
  64. var ids []int64
  65. query := fmt.Sprintf("SELECT `id` FROM %s WHERE `deptId` = ?", m.table)
  66. if err := m.QueryRowsNoCacheCtx(ctx, &ids, query, deptId); err != nil {
  67. return nil, err
  68. }
  69. return ids, nil
  70. }
  71. func (m *customSysUserModel) UpdateProfile(ctx context.Context, id int64, username string, nickname, email, phone, remark string, deptId, newStatus int64, statusChanged bool, expectedUpdateTime int64) error {
  72. sysUserIdKey := fmt.Sprintf("%s%v", cacheSysUserIdPrefix, id)
  73. sysUserUsernameKey := fmt.Sprintf("%s%v", cacheSysUserUsernamePrefix, username)
  74. now := time.Now().Unix()
  75. res, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (sql.Result, error) {
  76. if statusChanged {
  77. query := fmt.Sprintf("UPDATE %s SET `nickname`=?, `email`=?, `phone`=?, `remark`=?, `deptId`=?, `status`=?, `tokenVersion`=`tokenVersion`+1, `updateTime`=? WHERE `id`=? AND `updateTime`=?", m.table)
  78. return conn.ExecCtx(ctx, query, nickname, email, phone, remark, deptId, newStatus, now, id, expectedUpdateTime)
  79. }
  80. query := fmt.Sprintf("UPDATE %s SET `nickname`=?, `email`=?, `phone`=?, `remark`=?, `deptId`=?, `updateTime`=? WHERE `id`=? AND `updateTime`=?", m.table)
  81. return conn.ExecCtx(ctx, query, nickname, email, phone, remark, deptId, now, id, expectedUpdateTime)
  82. }, sysUserIdKey, sysUserUsernameKey)
  83. if err != nil {
  84. return err
  85. }
  86. affected, _ := res.RowsAffected()
  87. if affected == 0 {
  88. return ErrUpdateConflict
  89. }
  90. return nil
  91. }
  92. func (m *customSysUserModel) UpdatePassword(ctx context.Context, id int64, password string, mustChangePassword int64) error {
  93. data, err := m.FindOne(ctx, id)
  94. if err != nil {
  95. return err
  96. }
  97. sysUserIdKey := fmt.Sprintf("%s%v", cacheSysUserIdPrefix, id)
  98. sysUserUsernameKey := fmt.Sprintf("%s%v", cacheSysUserUsernamePrefix, data.Username)
  99. _, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (sql.Result, error) {
  100. query := fmt.Sprintf("UPDATE %s SET `password` = ?, `mustChangePassword` = ?, `tokenVersion` = `tokenVersion` + 1, `updateTime` = ? WHERE `id` = ?", m.table)
  101. return conn.ExecCtx(ctx, query, password, mustChangePassword, time.Now().Unix(), id)
  102. }, sysUserIdKey, sysUserUsernameKey)
  103. return err
  104. }
  105. func (m *customSysUserModel) UpdateStatus(ctx context.Context, id int64, status int64) error {
  106. data, err := m.FindOne(ctx, id)
  107. if err != nil {
  108. return err
  109. }
  110. sysUserIdKey := fmt.Sprintf("%s%v", cacheSysUserIdPrefix, id)
  111. sysUserUsernameKey := fmt.Sprintf("%s%v", cacheSysUserUsernamePrefix, data.Username)
  112. _, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (sql.Result, error) {
  113. query := fmt.Sprintf("UPDATE %s SET `status` = ?, `tokenVersion` = `tokenVersion` + 1, `updateTime` = ? WHERE `id` = ?", m.table)
  114. return conn.ExecCtx(ctx, query, status, time.Now().Unix(), id)
  115. }, sysUserIdKey, sysUserUsernameKey)
  116. return err
  117. }
  118. func (m *customSysUserModel) IncrementTokenVersion(ctx context.Context, id int64) (int64, error) {
  119. data, err := m.FindOne(ctx, id)
  120. if err != nil {
  121. return 0, err
  122. }
  123. sysUserIdKey := fmt.Sprintf("%s%v", cacheSysUserIdPrefix, id)
  124. sysUserUsernameKey := fmt.Sprintf("%s%v", cacheSysUserUsernamePrefix, data.Username)
  125. _, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (sql.Result, error) {
  126. query := fmt.Sprintf("UPDATE %s SET `tokenVersion` = `tokenVersion` + 1, `updateTime` = ? WHERE `id` = ?", m.table)
  127. return conn.ExecCtx(ctx, query, time.Now().Unix(), id)
  128. }, sysUserIdKey, sysUserUsernameKey)
  129. if err != nil {
  130. return 0, err
  131. }
  132. return data.TokenVersion + 1, nil
  133. }
  134. func (m *customSysUserModel) FindByIds(ctx context.Context, ids []int64) ([]*SysUser, error) {
  135. if len(ids) == 0 {
  136. return nil, nil
  137. }
  138. placeholders := make([]string, len(ids))
  139. args := make([]interface{}, len(ids))
  140. for i, id := range ids {
  141. placeholders[i] = "?"
  142. args[i] = id
  143. }
  144. var list []*SysUser
  145. query := fmt.Sprintf("SELECT %s FROM %s WHERE `id` IN (%s)", sysUserRows, m.table, strings.Join(placeholders, ","))
  146. if err := m.QueryRowsNoCacheCtx(ctx, &list, query, args...); err != nil {
  147. return nil, err
  148. }
  149. return list, nil
  150. }