sysUserModel.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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. }
  25. customSysUserModel struct {
  26. *defaultSysUserModel
  27. }
  28. )
  29. func NewSysUserModel(conn sqlx.SqlConn, c cache.CacheConf, cachePrefix string, opts ...cache.Option) SysUserModel {
  30. return &customSysUserModel{
  31. defaultSysUserModel: newSysUserModel(conn, c, cachePrefix, opts...),
  32. }
  33. }
  34. func (m *customSysUserModel) FindListByPage(ctx context.Context, page, pageSize int64) ([]*SysUser, int64, error) {
  35. var total int64
  36. countQuery := fmt.Sprintf("SELECT COUNT(*) FROM %s", m.table)
  37. if err := m.QueryRowNoCacheCtx(ctx, &total, countQuery); err != nil {
  38. return nil, 0, err
  39. }
  40. var list []*SysUser
  41. query := fmt.Sprintf("SELECT %s FROM %s ORDER BY id DESC LIMIT ?,?", sysUserRows, m.table)
  42. if err := m.QueryRowsNoCacheCtx(ctx, &list, query, (page-1)*pageSize, pageSize); err != nil {
  43. return nil, 0, err
  44. }
  45. return list, total, nil
  46. }
  47. func (m *customSysUserModel) FindListByProductMembers(ctx context.Context, productCode string, page, pageSize int64) ([]*SysUser, int64, error) {
  48. memberTable := "`sys_product_member`"
  49. var total int64
  50. countQuery := fmt.Sprintf("SELECT COUNT(*) FROM %s u INNER JOIN %s pm ON u.`id` = pm.`userId` WHERE pm.`productCode` = ?", m.table, memberTable)
  51. if err := m.QueryRowNoCacheCtx(ctx, &total, countQuery, productCode); err != nil {
  52. return nil, 0, err
  53. }
  54. var list []*SysUser
  55. fields := strings.Join(sysUserFieldNames, ",u.")
  56. 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)
  57. if err := m.QueryRowsNoCacheCtx(ctx, &list, query, productCode, (page-1)*pageSize, pageSize); err != nil {
  58. return nil, 0, err
  59. }
  60. return list, total, nil
  61. }
  62. func (m *customSysUserModel) FindIdsByDeptId(ctx context.Context, deptId int64) ([]int64, error) {
  63. var ids []int64
  64. query := fmt.Sprintf("SELECT `id` FROM %s WHERE `deptId` = ?", m.table)
  65. if err := m.QueryRowsNoCacheCtx(ctx, &ids, query, deptId); err != nil {
  66. return nil, err
  67. }
  68. return ids, nil
  69. }
  70. func (m *customSysUserModel) UpdateProfile(ctx context.Context, id int64, username string, nickname, email, phone, remark string, deptId, newStatus int64, statusChanged bool, expectedUpdateTime int64) error {
  71. sysUserIdKey := fmt.Sprintf("%s%v", cacheSysUserIdPrefix, id)
  72. sysUserUsernameKey := fmt.Sprintf("%s%v", cacheSysUserUsernamePrefix, username)
  73. now := time.Now().Unix()
  74. res, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (sql.Result, error) {
  75. if statusChanged {
  76. query := fmt.Sprintf("UPDATE %s SET `nickname`=?, `email`=?, `phone`=?, `remark`=?, `deptId`=?, `status`=?, `tokenVersion`=`tokenVersion`+1, `updateTime`=? WHERE `id`=? AND `updateTime`=?", m.table)
  77. return conn.ExecCtx(ctx, query, nickname, email, phone, remark, deptId, newStatus, now, id, expectedUpdateTime)
  78. }
  79. query := fmt.Sprintf("UPDATE %s SET `nickname`=?, `email`=?, `phone`=?, `remark`=?, `deptId`=?, `updateTime`=? WHERE `id`=? AND `updateTime`=?", m.table)
  80. return conn.ExecCtx(ctx, query, nickname, email, phone, remark, deptId, now, id, expectedUpdateTime)
  81. }, sysUserIdKey, sysUserUsernameKey)
  82. if err != nil {
  83. return err
  84. }
  85. affected, _ := res.RowsAffected()
  86. if affected == 0 {
  87. return ErrUpdateConflict
  88. }
  89. return nil
  90. }
  91. func (m *customSysUserModel) UpdatePassword(ctx context.Context, id int64, password string, mustChangePassword int64) error {
  92. data, err := m.FindOne(ctx, id)
  93. if err != nil {
  94. return err
  95. }
  96. sysUserIdKey := fmt.Sprintf("%s%v", cacheSysUserIdPrefix, id)
  97. sysUserUsernameKey := fmt.Sprintf("%s%v", cacheSysUserUsernamePrefix, data.Username)
  98. _, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (sql.Result, error) {
  99. query := fmt.Sprintf("UPDATE %s SET `password` = ?, `mustChangePassword` = ?, `tokenVersion` = `tokenVersion` + 1, `updateTime` = ? WHERE `id` = ?", m.table)
  100. return conn.ExecCtx(ctx, query, password, mustChangePassword, time.Now().Unix(), id)
  101. }, sysUserIdKey, sysUserUsernameKey)
  102. return err
  103. }
  104. func (m *customSysUserModel) UpdateStatus(ctx context.Context, id int64, status int64) error {
  105. data, err := m.FindOne(ctx, id)
  106. if err != nil {
  107. return err
  108. }
  109. sysUserIdKey := fmt.Sprintf("%s%v", cacheSysUserIdPrefix, id)
  110. sysUserUsernameKey := fmt.Sprintf("%s%v", cacheSysUserUsernamePrefix, data.Username)
  111. _, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (sql.Result, error) {
  112. query := fmt.Sprintf("UPDATE %s SET `status` = ?, `tokenVersion` = `tokenVersion` + 1, `updateTime` = ? WHERE `id` = ?", m.table)
  113. return conn.ExecCtx(ctx, query, status, time.Now().Unix(), id)
  114. }, sysUserIdKey, sysUserUsernameKey)
  115. return err
  116. }
  117. func (m *customSysUserModel) FindByIds(ctx context.Context, ids []int64) ([]*SysUser, error) {
  118. if len(ids) == 0 {
  119. return nil, nil
  120. }
  121. placeholders := make([]string, len(ids))
  122. args := make([]interface{}, len(ids))
  123. for i, id := range ids {
  124. placeholders[i] = "?"
  125. args[i] = id
  126. }
  127. var list []*SysUser
  128. query := fmt.Sprintf("SELECT %s FROM %s WHERE `id` IN (%s)", sysUserRows, m.table, strings.Join(placeholders, ","))
  129. if err := m.QueryRowsNoCacheCtx(ctx, &list, query, args...); err != nil {
  130. return nil, err
  131. }
  132. return list, nil
  133. }