sysRoleModel.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package role
  2. import (
  3. "context"
  4. "database/sql"
  5. "errors"
  6. "fmt"
  7. "strings"
  8. "github.com/zeromicro/go-zero/core/stores/cache"
  9. "github.com/zeromicro/go-zero/core/stores/sqlx"
  10. )
  11. var ErrUpdateConflict = errors.New("update conflict: data has been modified by another operation")
  12. var _ SysRoleModel = (*customSysRoleModel)(nil)
  13. type (
  14. SysRoleModel interface {
  15. sysRoleModel
  16. FindListByProductCode(ctx context.Context, productCode string, page, pageSize int64) ([]*SysRole, int64, error)
  17. FindByIds(ctx context.Context, ids []int64) ([]*SysRole, error)
  18. FindMinPermsLevelByUserIdAndProductCode(ctx context.Context, userId int64, productCode string) (int64, error)
  19. UpdateWithOptLock(ctx context.Context, data *SysRole, expectedUpdateTime int64) error
  20. }
  21. customSysRoleModel struct {
  22. *defaultSysRoleModel
  23. }
  24. )
  25. func NewSysRoleModel(conn sqlx.SqlConn, c cache.CacheConf, cachePrefix string, opts ...cache.Option) SysRoleModel {
  26. return &customSysRoleModel{
  27. defaultSysRoleModel: newSysRoleModel(conn, c, cachePrefix, opts...),
  28. }
  29. }
  30. func (m *customSysRoleModel) FindListByProductCode(ctx context.Context, productCode string, page, pageSize int64) ([]*SysRole, int64, error) {
  31. var total int64
  32. countQuery := fmt.Sprintf("SELECT COUNT(*) FROM %s WHERE `productCode` = ?", m.table)
  33. if err := m.QueryRowNoCacheCtx(ctx, &total, countQuery, productCode); err != nil {
  34. return nil, 0, err
  35. }
  36. var list []*SysRole
  37. query := fmt.Sprintf("SELECT %s FROM %s WHERE `productCode` = ? ORDER BY `permsLevel` ASC, id DESC LIMIT ?,?", sysRoleRows, m.table)
  38. if err := m.QueryRowsNoCacheCtx(ctx, &list, query, productCode, (page-1)*pageSize, pageSize); err != nil {
  39. return nil, 0, err
  40. }
  41. return list, total, nil
  42. }
  43. func (m *customSysRoleModel) FindByIds(ctx context.Context, ids []int64) ([]*SysRole, error) {
  44. if len(ids) == 0 {
  45. return nil, nil
  46. }
  47. args := make([]interface{}, len(ids))
  48. marks := make([]string, len(ids))
  49. for i, id := range ids {
  50. args[i] = id
  51. marks[i] = "?"
  52. }
  53. var list []*SysRole
  54. query := fmt.Sprintf("SELECT %s FROM %s WHERE `id` IN (%s)", sysRoleRows, m.table, strings.Join(marks, ","))
  55. if err := m.QueryRowsNoCacheCtx(ctx, &list, query, args...); err != nil {
  56. return nil, err
  57. }
  58. return list, nil
  59. }
  60. func (m *customSysRoleModel) UpdateWithOptLock(ctx context.Context, data *SysRole, expectedUpdateTime int64) error {
  61. sysRoleIdKey := fmt.Sprintf("%s%v", cacheSysRoleIdPrefix, data.Id)
  62. sysRoleProductCodeNameKey := fmt.Sprintf("%s%v:%v", cacheSysRoleProductCodeNamePrefix, data.ProductCode, data.Name)
  63. res, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (sql.Result, error) {
  64. query := fmt.Sprintf("UPDATE %s SET `name`=?, `remark`=?, `status`=?, `permsLevel`=?, `updateTime`=? WHERE `id`=? AND `updateTime`=?", m.table)
  65. return conn.ExecCtx(ctx, query, data.Name, data.Remark, data.Status, data.PermsLevel, data.UpdateTime, data.Id, expectedUpdateTime)
  66. }, sysRoleIdKey, sysRoleProductCodeNameKey)
  67. if err != nil {
  68. return err
  69. }
  70. affected, _ := res.RowsAffected()
  71. if affected == 0 {
  72. return ErrUpdateConflict
  73. }
  74. return nil
  75. }
  76. func (m *customSysRoleModel) FindMinPermsLevelByUserIdAndProductCode(ctx context.Context, userId int64, productCode string) (int64, error) {
  77. var level int64
  78. query := fmt.Sprintf(
  79. "SELECT IFNULL(MIN(r.`permsLevel`), -1) FROM %s r INNER JOIN `sys_user_role` ur ON r.`id` = ur.`roleId` WHERE ur.`userId` = ? AND r.`productCode` = ? AND r.`status` = 1",
  80. m.table,
  81. )
  82. if err := m.QueryRowNoCacheCtx(ctx, &level, query, userId, productCode); err != nil {
  83. return 0, err
  84. }
  85. if level < 0 {
  86. return 0, ErrNotFound
  87. }
  88. return level, nil
  89. }