admin.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. package admin
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/duke-git/lancet/v2/convertor"
  6. v1 "github.com/go-nunu/nunu-layout-advanced/api/v1"
  7. "github.com/go-nunu/nunu-layout-advanced/internal/model"
  8. "github.com/go-nunu/nunu-layout-advanced/internal/repository"
  9. "go.uber.org/zap"
  10. "strings"
  11. )
  12. type AdminRepository interface {
  13. GetAdminUsers(ctx context.Context, req *v1.GetAdminUsersRequest) ([]model.AdminUser, int64, error)
  14. GetAdminUser(ctx context.Context, uid uint) (model.AdminUser, error)
  15. GetAdminUserByUsername(ctx context.Context, username string) (model.AdminUser, error)
  16. AdminUserUpdate(ctx context.Context, m *model.AdminUser) error
  17. AdminUserCreate(ctx context.Context, m *model.AdminUser) error
  18. AdminUserDelete(ctx context.Context, id uint) error
  19. GetUserPermissions(ctx context.Context, uid uint) ([][]string, error)
  20. GetUserRoles(ctx context.Context, uid uint) ([]string, error)
  21. GetRolePermissions(ctx context.Context, role string) ([][]string, error)
  22. UpdateRolePermission(ctx context.Context, role string, permissions map[string]struct{}) error
  23. UpdateUserRoles(ctx context.Context, uid uint, roles []string) error
  24. DeleteUserRoles(ctx context.Context, uid uint) error
  25. GetMenuList(ctx context.Context) ([]model.Menu, error)
  26. MenuUpdate(ctx context.Context, m *model.Menu) error
  27. MenuCreate(ctx context.Context, m *model.Menu) error
  28. MenuDelete(ctx context.Context, id uint) error
  29. GetRoles(ctx context.Context, req *v1.GetRoleListRequest) ([]model.Role, int64, error)
  30. RoleUpdate(ctx context.Context, m *model.Role) error
  31. RoleCreate(ctx context.Context, m *model.Role) error
  32. RoleDelete(ctx context.Context, id uint) error
  33. CasbinRoleDelete(ctx context.Context, role string) error
  34. GetRole(ctx context.Context, id uint) (model.Role, error)
  35. GetRoleBySid(ctx context.Context, sid string) (model.Role, error)
  36. GetApis(ctx context.Context, req *v1.GetApisRequest) ([]model.Api, int64, error)
  37. GetApiGroups(ctx context.Context) ([]string, error)
  38. ApiUpdate(ctx context.Context, m *model.Api) error
  39. ApiCreate(ctx context.Context, m *model.Api) error
  40. ApiDelete(ctx context.Context, id uint) error
  41. }
  42. func NewAdminRepository(
  43. repository *repository.Repository,
  44. ) AdminRepository {
  45. return &adminRepository{
  46. Repository: repository,
  47. }
  48. }
  49. type adminRepository struct {
  50. *repository.Repository
  51. }
  52. func (r *adminRepository) CasbinRoleDelete(ctx context.Context, role string) error {
  53. _, err := r.E.DeleteRole(role)
  54. return err
  55. }
  56. func (r *adminRepository) GetRole(ctx context.Context, id uint) (model.Role, error) {
  57. m := model.Role{}
  58. return m, r.DBWithName(ctx,"admin").Where("id = ?", id).First(&m).Error
  59. }
  60. func (r *adminRepository) GetRoleBySid(ctx context.Context, sid string) (model.Role, error) {
  61. m := model.Role{}
  62. return m, r.DBWithName(ctx,"admin").Where("sid = ?", sid).First(&m).Error
  63. }
  64. func (r *adminRepository) DeleteUserRoles(ctx context.Context, uid uint) error {
  65. _, err := r.E.DeleteRolesForUser(convertor.ToString(uid))
  66. return err
  67. }
  68. func (r *adminRepository) UpdateUserRoles(ctx context.Context, uid uint, roles []string) error {
  69. if len(roles) == 0 {
  70. _, err := r.E.DeleteRolesForUser(convertor.ToString(uid))
  71. return err
  72. }
  73. old, err := r.E.GetRolesForUser(convertor.ToString(uid))
  74. if err != nil {
  75. return err
  76. }
  77. oldMap := make(map[string]struct{})
  78. newMap := make(map[string]struct{})
  79. for _, v := range old {
  80. oldMap[v] = struct{}{}
  81. }
  82. for _, v := range roles {
  83. newMap[v] = struct{}{}
  84. }
  85. addRoles := make([]string, 0)
  86. delRoles := make([]string, 0)
  87. for key, _ := range oldMap {
  88. if _, exists := newMap[key]; !exists {
  89. delRoles = append(delRoles, key)
  90. }
  91. }
  92. for key, _ := range newMap {
  93. if _, exists := oldMap[key]; !exists {
  94. addRoles = append(addRoles, key)
  95. }
  96. }
  97. if len(addRoles) == 0 && len(delRoles) == 0 {
  98. return nil
  99. }
  100. for _, role := range delRoles {
  101. if _, err := r.E.DeleteRoleForUser(convertor.ToString(uid), role); err != nil {
  102. r.Logger.WithContext(ctx).Error("DeleteRoleForUser error", zap.Error(err))
  103. return err
  104. }
  105. }
  106. _, err = r.E.AddRolesForUser(convertor.ToString(uid), addRoles)
  107. return err
  108. }
  109. func (r *adminRepository) GetAdminUserByUsername(ctx context.Context, username string) (model.AdminUser, error) {
  110. m := model.AdminUser{}
  111. return m, r.DBWithName(ctx,"admin").Where("username = ?", username).First(&m).Error
  112. }
  113. func (r *adminRepository) GetAdminUsers(ctx context.Context, req *v1.GetAdminUsersRequest) ([]model.AdminUser, int64, error) {
  114. var list []model.AdminUser
  115. var total int64
  116. scope := r.DBWithName(ctx,"admin").Model(&model.AdminUser{})
  117. if req.Username != "" {
  118. scope = scope.Where("username LIKE ?", "%"+req.Username+"%")
  119. }
  120. if req.Nickname != "" {
  121. scope = scope.Where("nickname LIKE ?", "%"+req.Nickname+"%")
  122. }
  123. if req.Email != "" {
  124. scope = scope.Where("email LIKE ?", "%"+req.Email+"%")
  125. }
  126. if req.Phone != "" {
  127. scope = scope.Where("phone LIKE ?", "%"+req.Phone+"%")
  128. }
  129. if err := scope.Count(&total).Error; err != nil {
  130. return nil, total, err
  131. }
  132. if err := scope.Offset((req.Page - 1) * req.PageSize).Limit(req.PageSize).Order("id DESC").Find(&list).Error; err != nil {
  133. return nil, total, err
  134. }
  135. return list, total, nil
  136. }
  137. func (r *adminRepository) GetAdminUser(ctx context.Context, uid uint) (model.AdminUser, error) {
  138. m := model.AdminUser{}
  139. return m, r.DBWithName(ctx,"admin").Where("id = ?", uid).First(&m).Error
  140. }
  141. func (r *adminRepository) AdminUserUpdate(ctx context.Context, m *model.AdminUser) error {
  142. return r.DBWithName(ctx,"admin").Where("id = ?", m.ID).Save(m).Error
  143. }
  144. func (r *adminRepository) AdminUserCreate(ctx context.Context, m *model.AdminUser) error {
  145. return r.DBWithName(ctx,"admin").Create(m).Error
  146. }
  147. func (r *adminRepository) AdminUserDelete(ctx context.Context, id uint) error {
  148. return r.DBWithName(ctx,"admin").Where("id = ?", id).Delete(&model.AdminUser{}).Error
  149. }
  150. func (r *adminRepository) UpdateRolePermission(ctx context.Context, role string, newPermSet map[string]struct{}) error {
  151. if len(newPermSet) == 0 {
  152. return nil
  153. }
  154. // 获取当前角色的所有权限
  155. oldPermissions, err := r.E.GetPermissionsForUser(role)
  156. if err != nil {
  157. return err
  158. }
  159. // 将旧权限转换为 map 方便查找
  160. oldPermSet := make(map[string]struct{})
  161. for _, perm := range oldPermissions {
  162. if len(perm) == 3 {
  163. oldPermSet[strings.Join([]string{perm[1], perm[2]}, model.PermSep)] = struct{}{}
  164. }
  165. }
  166. // 找出需要删除的权限
  167. var removePermissions [][]string
  168. for key, _ := range oldPermSet {
  169. if _, exists := newPermSet[key]; !exists {
  170. removePermissions = append(removePermissions, strings.Split(key, model.PermSep))
  171. }
  172. }
  173. // 找出需要添加的权限
  174. var addPermissions [][]string
  175. for key, _ := range newPermSet {
  176. if _, exists := oldPermSet[key]; !exists {
  177. addPermissions = append(addPermissions, strings.Split(key, model.PermSep))
  178. }
  179. }
  180. // 先移除多余的权限(使用 DeletePermissionForUser 逐条删除)
  181. for _, perm := range removePermissions {
  182. _, err := r.E.DeletePermissionForUser(role, perm...)
  183. if err != nil {
  184. return fmt.Errorf("移除权限失败: %v", err)
  185. }
  186. }
  187. // 再添加新的权限
  188. if len(addPermissions) > 0 {
  189. _, err = r.E.AddPermissionsForUser(role, addPermissions...)
  190. if err != nil {
  191. return fmt.Errorf("添加新权限失败: %v", err)
  192. }
  193. }
  194. return nil
  195. }
  196. func (r *adminRepository) GetApiGroups(ctx context.Context) ([]string, error) {
  197. res := make([]string, 0)
  198. if err := r.DBWithName(ctx,"admin").Model(&model.Api{}).Group("`group`").Pluck("`group`", &res).Error; err != nil {
  199. return nil, err
  200. }
  201. return res, nil
  202. }
  203. func (r *adminRepository) GetApis(ctx context.Context, req *v1.GetApisRequest) ([]model.Api, int64, error) {
  204. var list []model.Api
  205. var total int64
  206. scope := r.DBWithName(ctx,"admin").Model(&model.Api{})
  207. if req.Name != "" {
  208. scope = scope.Where("name LIKE ?", "%"+req.Name+"%")
  209. }
  210. if req.Group != "" {
  211. scope = scope.Where("`group` LIKE ?", "%"+req.Group+"%")
  212. }
  213. if req.Path != "" {
  214. scope = scope.Where("path LIKE ?", "%"+req.Path+"%")
  215. }
  216. if req.Method != "" {
  217. scope = scope.Where("method = ?", req.Method)
  218. }
  219. if err := scope.Count(&total).Error; err != nil {
  220. return nil, total, err
  221. }
  222. if err := scope.Offset((req.Page - 1) * req.PageSize).Limit(req.PageSize).Order("`group` ASC").Find(&list).Error; err != nil {
  223. return nil, total, err
  224. }
  225. return list, total, nil
  226. }
  227. func (r *adminRepository) ApiUpdate(ctx context.Context, m *model.Api) error {
  228. return r.DBWithName(ctx,"admin").Where("id = ?", m.ID).Save(m).Error
  229. }
  230. func (r *adminRepository) ApiCreate(ctx context.Context, m *model.Api) error {
  231. return r.DBWithName(ctx,"admin").Create(m).Error
  232. }
  233. func (r *adminRepository) ApiDelete(ctx context.Context, id uint) error {
  234. return r.DBWithName(ctx,"admin").Where("id = ?", id).Delete(&model.Api{}).Error
  235. }
  236. func (r *adminRepository) GetUserPermissions(ctx context.Context, uid uint) ([][]string, error) {
  237. return r.E.GetImplicitPermissionsForUser(convertor.ToString(uid))
  238. }
  239. func (r *adminRepository) GetRolePermissions(ctx context.Context, role string) ([][]string, error) {
  240. return r.E.GetPermissionsForUser(role)
  241. }
  242. func (r *adminRepository) GetUserRoles(ctx context.Context, uid uint) ([]string, error) {
  243. return r.E.GetRolesForUser(convertor.ToString(uid))
  244. }
  245. func (r *adminRepository) MenuUpdate(ctx context.Context, m *model.Menu) error {
  246. return r.DBWithName(ctx,"admin").Where("id = ?", m.ID).Save(m).Error
  247. }
  248. func (r *adminRepository) MenuCreate(ctx context.Context, m *model.Menu) error {
  249. return r.DBWithName(ctx,"admin").Save(m).Error
  250. }
  251. func (r *adminRepository) MenuDelete(ctx context.Context, id uint) error {
  252. return r.DBWithName(ctx,"admin").Where("id = ?", id).Delete(&model.Menu{}).Error
  253. }
  254. func (r *adminRepository) GetMenuList(ctx context.Context) ([]model.Menu, error) {
  255. var menuList []model.Menu
  256. if err := r.DBWithName(ctx,"admin").Order("weight DESC").Find(&menuList).Error; err != nil {
  257. return nil, err
  258. }
  259. return menuList, nil
  260. }
  261. func (r *adminRepository) RoleUpdate(ctx context.Context, m *model.Role) error {
  262. return r.DBWithName(ctx,"admin").Where("id = ?", m.ID).UpdateColumn("name", m.Name).Error
  263. }
  264. func (r *adminRepository) RoleCreate(ctx context.Context, m *model.Role) error {
  265. return r.DBWithName(ctx,"admin").Create(m).Error
  266. }
  267. func (r *adminRepository) RoleDelete(ctx context.Context, id uint) error {
  268. return r.DBWithName(ctx,"admin").Where("id = ?", id).Delete(&model.Role{}).Error
  269. }
  270. func (r *adminRepository) GetRoles(ctx context.Context, req *v1.GetRoleListRequest) ([]model.Role, int64, error) {
  271. var list []model.Role
  272. var total int64
  273. scope := r.DBWithName(ctx,"admin").Model(&model.Role{})
  274. if req.Name != "" {
  275. scope = scope.Where("name LIKE ?", "%"+req.Name+"%")
  276. }
  277. if req.Sid != "" {
  278. scope = scope.Where("sid = ?", req.Sid)
  279. }
  280. if err := scope.Count(&total).Error; err != nil {
  281. return nil, total, err
  282. }
  283. if err := scope.Offset((req.Page - 1) * req.PageSize).Limit(req.PageSize).Find(&list).Error; err != nil {
  284. return nil, total, err
  285. }
  286. return list, total, nil
  287. }