role.go 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. package service
  2. import (
  3. "dy-admin/internal/pcmserver/common"
  4. "dy-admin/internal/pcmserver/global"
  5. "dy-admin/internal/pcmserver/pkg/code"
  6. "dy-admin/internal/pcmserver/sys/model"
  7. "dy-admin/pkg/rescode"
  8. "fmt"
  9. "github.com/pkg/errors"
  10. "gorm.io/gorm"
  11. "strconv"
  12. )
  13. type RoleService struct {
  14. }
  15. func (rs *RoleService) CreateRole(role model.Role) (err error) {
  16. var menus []model.Menu
  17. err = global.DB.Where("role_name = ?", role.RoleName).First(&model.Role{}).Error
  18. if !errors.Is(err, gorm.ErrRecordNotFound) {
  19. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrRoleAlreadyExistCode])
  20. }
  21. err = global.DB.Preload("SysApi").Where("menu_id in ?", role.MenuIds).Find(&menus).Error
  22. if err != nil {
  23. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  24. }
  25. role.SysMenu = menus
  26. // 默认角色数据权限。 只能查看本部门数据
  27. if role.DataScope == "" {
  28. role.DataScope = "4"
  29. }
  30. tx := global.DB.Begin()
  31. defer func() {
  32. if err != nil {
  33. tx.Rollback()
  34. } else {
  35. tx.Commit()
  36. }
  37. }()
  38. err = tx.Create(&role).Error
  39. if err != nil {
  40. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  41. }
  42. //排重map
  43. repetitionMap := make(map[string]struct{})
  44. polices := make([][]string, 0)
  45. for _, menu := range menus {
  46. for _, api := range menu.SysApi {
  47. key := role.RoleName + "-" + api.Path + "-" + api.Action
  48. if _, ok := repetitionMap[key]; !ok {
  49. repetitionMap[key] = struct{}{}
  50. polices = append(polices, []string{strconv.Itoa(role.RoleID), api.Path, api.Action})
  51. }
  52. }
  53. }
  54. // 每个角色的默认权限
  55. for _, defaultApi := range model.DefaultAPIs() {
  56. polices = append(polices, []string{strconv.Itoa(role.RoleID), defaultApi.Path, defaultApi.Action})
  57. }
  58. if len(polices) == 0 {
  59. return
  60. }
  61. _, err = CasbinServiceInstance.Casbin().AddPolicies(polices)
  62. if err != nil {
  63. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrCasbinInternalCode])
  64. }
  65. err = CasbinServiceInstance.Casbin().InvalidateCache()
  66. if err != nil {
  67. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrCasbinInternalCode])
  68. }
  69. return
  70. }
  71. func (rs *RoleService) UpdateRole(role model.Role) (err error) {
  72. var oldRole model.Role
  73. tx := global.DB.Begin()
  74. defer func() {
  75. if err != nil {
  76. tx.Rollback()
  77. } else {
  78. tx.Commit()
  79. }
  80. }()
  81. // 关联查到角色对应的菜单
  82. tx.Preload("SysMenu").First(&oldRole, role.RoleID)
  83. var newMenuList []model.Menu
  84. // 查询新的的菜单数据,关联查询api
  85. tx.Preload("SysApi").Where("menu_id in ?", role.MenuIds).Find(&newMenuList)
  86. // 删除角色绑定的旧菜单
  87. err = tx.Model(&oldRole).Association("SysMenu").Delete(oldRole.SysMenu)
  88. if err != nil {
  89. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  90. }
  91. role.SysMenu = newMenuList
  92. err = tx.Session(&gorm.Session{FullSaveAssociations: true}).Debug().Updates(&role).Error
  93. if err != nil {
  94. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  95. }
  96. // 删除casbin规则
  97. _, err = CasbinServiceInstance.ClearCasbin(0, strconv.Itoa(role.RoleID))
  98. if err != nil {
  99. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrCasbinInternalCode])
  100. }
  101. repetitionMap := make(map[string]struct{})
  102. polices := make([][]string, 0)
  103. for _, menu := range newMenuList {
  104. for _, api := range menu.SysApi {
  105. key := role.RoleName + "-" + api.Path + "-" + api.Action
  106. if _, ok := repetitionMap[key]; !ok {
  107. repetitionMap[key] = struct{}{}
  108. polices = append(polices, []string{strconv.Itoa(role.RoleID), api.Path, api.Action})
  109. }
  110. }
  111. }
  112. // 每个角色的默认权限
  113. for _, defaultApi := range model.DefaultAPIs() {
  114. polices = append(polices, []string{strconv.Itoa(role.RoleID), defaultApi.Path, defaultApi.Action})
  115. }
  116. if len(polices) == 0 {
  117. return
  118. }
  119. _, err = CasbinServiceInstance.Casbin().AddPolicies(polices)
  120. if err != nil {
  121. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrCasbinInternalCode])
  122. }
  123. err = CasbinServiceInstance.Casbin().InvalidateCache()
  124. if err != nil {
  125. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrCasbinInternalCode])
  126. }
  127. return
  128. }
  129. func (rs *RoleService) DeleteRole(roleId int) (err error) {
  130. tx := global.DB.Begin()
  131. defer func() {
  132. if err != nil {
  133. tx.Rollback()
  134. } else {
  135. tx.Commit()
  136. }
  137. }()
  138. // 角色是否存在
  139. var role model.Role
  140. err = tx.Preload("SysMenu").Preload("SysDept").Preload("SysUser").Where("role_id = ?", roleId).First(&role).Error
  141. if err != nil {
  142. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  143. }
  144. // 角色下如果存在用户,不允许删除
  145. if len(role.SysUser) != 0 {
  146. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrRoleHasUserCode])
  147. }
  148. // 删除角色关联菜单
  149. err = tx.Model(&role).Association("SysMenu").Delete(role.SysMenu)
  150. if err != nil {
  151. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  152. }
  153. err = tx.Model(&role).Association("SysDept").Delete(role.SysDept)
  154. if err != nil {
  155. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  156. }
  157. // 删除角色
  158. err = tx.Delete(&role, role.RoleID).Error
  159. if err != nil {
  160. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  161. }
  162. // casbin清除角色权限
  163. _, err = CasbinServiceInstance.ClearCasbin(0, strconv.Itoa(role.RoleID))
  164. if err != nil {
  165. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrCasbinInternalCode])
  166. }
  167. return
  168. }
  169. // GetRoleList 分页获取角色数据
  170. func (rs *RoleService) GetRoleList(role model.Role, info common.PageInfo, order string, desc bool) (list []model.Role, total int64, err error) {
  171. var limit, offset int
  172. if info.Page == 0 || info.PageSize == 0 {
  173. limit = -1
  174. offset = -1
  175. } else {
  176. limit = info.PageSize
  177. offset = info.PageSize * (info.Page - 1)
  178. }
  179. db := global.DB.Model(&model.Role{}).Preload("SysMenu").Preload("SysDept").Where("role_id !=?", 2)
  180. if role.RoleName != "" {
  181. db.Where("role_name LIKE ?", "%"+role.RoleName+"%")
  182. }
  183. if role.Status != "" {
  184. db.Where("status = ?", role.Status)
  185. }
  186. err = db.Count(&total).Error
  187. if err != nil {
  188. return list, total, rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  189. }
  190. db.Limit(limit).Offset(offset)
  191. if order == "" {
  192. err = db.Order("role_sort asc").Find(&list).Error
  193. if err != nil {
  194. return list, total, rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  195. }
  196. return
  197. }
  198. var OrderStr string
  199. allowOrderField := role.AllowOrderField()
  200. if _, ok := allowOrderField[order]; !ok {
  201. msg := fmt.Sprintf("params=>order:%s", order)
  202. return list, total,
  203. rescode.RegisterErrorWithMessage(errors.New("非法排序字段"), msg, code.ErrCodeMap[code.ErrIllegalOrderFieldCode])
  204. }
  205. if desc {
  206. OrderStr = order + " desc"
  207. } else {
  208. OrderStr = order
  209. }
  210. err = db.Order(OrderStr).Find(&list).Error
  211. return
  212. }
  213. func (rs *RoleService) GetRoleById(roleId int) (role model.Role, err error) {
  214. if err = global.DB.Where("role_id = ?", roleId).Preload("SysMenu").Preload("SysDept").First(&role).Error; err != nil {
  215. if errors.Is(err, gorm.ErrRecordNotFound) {
  216. return role, rescode.RegisterErrorWithCause(nil, code.ErrCodeMap[code.ErrRoleNotFoundCode])
  217. }
  218. }
  219. role.MenuIds, err = rs.GetRoleMenuIDs(roleId)
  220. role.DeptIds, err = rs.GetRoleDeptIDs(roleId)
  221. return
  222. }
  223. func (rs *RoleService) GetRoleMenuIDs(roleId int) (menuIds []int, err error) {
  224. var role model.Role
  225. if err := global.DB.Preload("SysMenu").Where("role_id = ?", roleId).First(&role).Error; err != nil {
  226. return menuIds, rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  227. }
  228. for _, menu := range role.SysMenu {
  229. menuIds = append(menuIds, menu.MenuID)
  230. }
  231. return menuIds, nil
  232. }
  233. func (rs *RoleService) GetRoleDeptIDs(roleId int) (deptIds []int, err error) {
  234. var role model.Role
  235. if err := global.DB.Preload("SysDept").Where("role_id = ?", roleId).First(&role).Error; err != nil {
  236. return deptIds, rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  237. }
  238. for _, dept := range role.SysDept {
  239. deptIds = append(deptIds, dept.DeptID)
  240. }
  241. return deptIds, nil
  242. }
  243. func (rs *RoleService) UpdateDataScope(roleId int, dataScope string, deptIds []int) (err error) {
  244. tx := global.DB.Begin()
  245. defer func() {
  246. if err != nil {
  247. tx.Rollback()
  248. } else {
  249. tx.Commit()
  250. }
  251. }()
  252. var role model.Role
  253. tx.Preload("SysDept").First(&role, roleId)
  254. var deptList []model.Dept
  255. tx.Where("dept_id in ?", deptIds).Find(&deptList)
  256. // 删除旧的
  257. err = tx.Model(&role).Association("SysDept").Delete(role.SysDept)
  258. if err != nil {
  259. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  260. }
  261. role.SysDept = deptList
  262. role.DataScope = dataScope
  263. err = tx.Model(&role).Session(&gorm.Session{FullSaveAssociations: true}).Debug().Updates(&role).Error
  264. if err != nil {
  265. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  266. }
  267. return
  268. }