role.service.ts 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. import { Inject, Provide } from '@midwayjs/core';
  2. import { InjectEntityModel } from '@midwayjs/typeorm';
  3. import { In, Repository } from 'typeorm';
  4. import { Role } from '../../entity/system/role.entity';
  5. import { Context } from '@midwayjs/koa';
  6. import { AdminService } from './admin.service';
  7. import { compact, flattenDeep, get, isArray, last, lowerFirst, uniq, upperFirst } from 'lodash';
  8. import { DeptService } from './dept.service';
  9. import { MenusService } from './menus.service';
  10. import { BaseServiceV2 } from '../../frame/BaseServiceV2';
  11. @Provide()
  12. export class RoleService extends BaseServiceV2 {
  13. @InjectEntityModel(Role)
  14. model: Repository<Role>;
  15. @Inject()
  16. deptService: DeptService;
  17. @Inject()
  18. adminService: AdminService;
  19. @Inject()
  20. menusService: MenusService;
  21. @Inject()
  22. ctx: Context;
  23. getQueryColumnsOpera(): object {
  24. return {};
  25. }
  26. //是否是超级管理员
  27. async isSuperAdmin() {
  28. const user = this.ctx.user;
  29. // if (isArray(user.role) && user.role.includes('Admin')) {
  30. if (user.is_super) {
  31. const qb = { id: user.id };
  32. const admin = await this.adminService.fetch(qb);
  33. if (!admin) return false;
  34. if (admin.is_super === '0') return true;
  35. } else return false;
  36. }
  37. /**
  38. * 获取用户接口权限编码列表
  39. * @returns {Array<string>} apiCodes 用户接口权限编码列表
  40. */
  41. async getUserApiCodes() {
  42. const user = this.ctx.user;
  43. const getControllerCode = list => {
  44. const result = [];
  45. for (const i of list) {
  46. const { config = [], children = [] } = i;
  47. const l = config.map(i => get(i, 'controller_code'));
  48. result.push(...l);
  49. if (children && children.length > 0) {
  50. const cl = getControllerCode(children);
  51. result.push(...cl);
  52. }
  53. }
  54. return result;
  55. };
  56. if (await this.isSuperAdmin()) {
  57. const smqb = { is_use: '0' };
  58. const menus = await this.menusService.queryMenu(smqb);
  59. // 需要整理出所有 config 中 methodCode = ${controllerCode}.${method} ,query 没有二级code
  60. let apiCodes = getControllerCode(menus);
  61. apiCodes = compact(apiCodes);
  62. return apiCodes;
  63. }
  64. // 其他用户需要把 部门 和 角色的权限叠加在一起
  65. // 部门权限
  66. const deptCodes = await this.getDeptCodes(get(user, 'dept'));
  67. // 角色权限
  68. const roleCodes = await this.getRoleCodes(get(user, 'role'));
  69. let allCodes = [...deptCodes, ...roleCodes];
  70. allCodes = uniq(allCodes);
  71. const qb = { route_name: allCodes };
  72. const operas = { route_name: this.Opera.In };
  73. const { data: menuList } = await this.menusService.query(qb, null, operas);
  74. const apiCodes = getControllerCode(menuList);
  75. return apiCodes;
  76. }
  77. async getUserMenus(needCode = false) {
  78. const user = this.ctx.user;
  79. // 平台的超级管理员有所有权限
  80. if (await this.isSuperAdmin()) {
  81. const menus = await this.menusService.queryMenu({ is_use: '0' });
  82. return { menus };
  83. }
  84. // 其他用户需要把 部门 和 角色的权限叠加在一起
  85. // 部门权限
  86. const deptCodes = await this.getDeptCodes(get(user, 'dept'));
  87. // 角色权限
  88. const roleCodes = await this.getRoleCodes(get(user, 'role'));
  89. let allCodes = [...deptCodes, ...roleCodes];
  90. allCodes = uniq(allCodes);
  91. // 只获取编码,直接返回
  92. if (needCode) return allCodes;
  93. // 根据编码获取目录数据
  94. const menuCodes = this.setMenuCodes(allCodes);
  95. const qb = { route_name: menuCodes };
  96. const operas = { route_name: this.Opera.In };
  97. const { data: menuList } = await this.menusService.query(qb, null, operas);
  98. let treeMenu = menuList.filter(f => !f.parent_id);
  99. treeMenu = this.menusService.treeMenu(menuList, treeMenu);
  100. return { menus: treeMenu, role_code: allCodes };
  101. }
  102. /**
  103. * 整理出角色目录的编码,主要是与route_name编码对应
  104. * @param allCodes 本用户的角色+部门的完整权限编码
  105. * @returns 目录需要的编码
  106. */
  107. setMenuCodes(allCodes: Array<string>) {
  108. const result = [];
  109. for (const code of allCodes) {
  110. const arr = code.split('.');
  111. result.push(last(arr));
  112. }
  113. return uniq(result);
  114. }
  115. /**
  116. * 根据部门id获取权限列表
  117. * @param deptId 部门id
  118. * @returns 权限列表
  119. */
  120. async getDeptCodes(deptId: number) {
  121. if (deptId) {
  122. const qb = { id: deptId };
  123. const dept = await this.deptService.fetch(qb);
  124. if (!dept) return [];
  125. // 处理部门有的权限
  126. const resource = get(dept, 'resource', []);
  127. // const result = resource.map(i => {
  128. // const arr = i.split('.');
  129. // return last(arr);
  130. // });
  131. return resource;
  132. } else return [];
  133. }
  134. /**
  135. * 根据角色数组获取角色权限
  136. * @param roleCode 角色数据
  137. * @returns 权限列表
  138. */
  139. async getRoleCodes(roleCode: Array<string>) {
  140. if (!roleCode) return [];
  141. const roleCodes = [];
  142. for (const rc of roleCode) {
  143. roleCodes.push(lowerFirst(rc));
  144. roleCodes.push(upperFirst(rc));
  145. }
  146. // const role = await this.model.findOne({ where: { code: In(roleCode), is_use: '0' } });
  147. const role = await this.fetch({ code: roleCode }, { code: this.Opera.In });
  148. if (!role) return [];
  149. const roleMenu = get(role, 'menu', []);
  150. return roleMenu;
  151. }
  152. /**
  153. * 根据角色id数组,整理目录
  154. * @param roleIdList 角色id数组
  155. */
  156. async getMenuByRoles(roleIdList) {
  157. let menus = [];
  158. // 第一步,整理所有目录至一维数组
  159. for (const r of roleIdList) {
  160. menus.push(...flattenDeep(r));
  161. }
  162. menus = uniq(menus);
  163. const qb = { id: menus, is_use: '0' };
  164. const operas = { id: this.Opera.In };
  165. const { data: allMenu } = await this.menusService.query(qb, { order: { order_num: 'ASC' } }, operas);
  166. let treeMenu = allMenu.filter(f => !f.parent_id);
  167. treeMenu = this.menusService.treeMenu(allMenu, treeMenu);
  168. return treeMenu;
  169. }
  170. }