import { Inject, Provide } from '@midwayjs/core'; import { InjectEntityModel } from '@midwayjs/typeorm'; import { In, Repository } from 'typeorm'; import { Role } from '../../entity/system/role.entity'; import { Context } from '@midwayjs/koa'; import { AdminService } from './admin.service'; import { compact, flattenDeep, get, isArray, last, lowerFirst, uniq, upperFirst } from 'lodash'; import { DeptService } from './dept.service'; import { MenusService } from './menus.service'; import { BaseServiceV2 } from '../../frame/BaseServiceV2'; @Provide() export class RoleService extends BaseServiceV2 { @InjectEntityModel(Role) model: Repository; @Inject() deptService: DeptService; @Inject() adminService: AdminService; @Inject() menusService: MenusService; @Inject() ctx: Context; getQueryColumnsOpera(): object { return {}; } //是否是超级管理员 async isSuperAdmin() { const user = this.ctx.user; // if (isArray(user.role) && user.role.includes('Admin')) { if (user.is_super) { const qb = { id: user.id }; const admin = await this.adminService.fetch(qb); if (!admin) return false; if (admin.is_super === '0') return true; } else return false; } /** * 获取用户接口权限编码列表 * @returns {Array} apiCodes 用户接口权限编码列表 */ async getUserApiCodes() { const user = this.ctx.user; const getControllerCode = list => { const result = []; for (const i of list) { const { config = [], children = [] } = i; const l = config.map(i => get(i, 'controller_code')); result.push(...l); if (children && children.length > 0) { const cl = getControllerCode(children); result.push(...cl); } } return result; }; if (await this.isSuperAdmin()) { const smqb = { is_use: '0' }; const menus = await this.menusService.queryMenu(smqb); // 需要整理出所有 config 中 methodCode = ${controllerCode}.${method} ,query 没有二级code let apiCodes = getControllerCode(menus); apiCodes = compact(apiCodes); return apiCodes; } // 其他用户需要把 部门 和 角色的权限叠加在一起 // 部门权限 const deptCodes = await this.getDeptCodes(get(user, 'dept')); // 角色权限 const roleCodes = await this.getRoleCodes(get(user, 'role')); let allCodes = [...deptCodes, ...roleCodes]; allCodes = uniq(allCodes); const qb = { route_name: allCodes }; const operas = { route_name: this.Opera.In }; const { data: menuList } = await this.menusService.query(qb, null, operas); const apiCodes = getControllerCode(menuList); return apiCodes; } async getUserMenus(needCode = false) { const user = this.ctx.user; // 平台的超级管理员有所有权限 if (await this.isSuperAdmin()) { const menus = await this.menusService.queryMenu({ is_use: '0' }); return { menus }; } // 其他用户需要把 部门 和 角色的权限叠加在一起 // 部门权限 const deptCodes = await this.getDeptCodes(get(user, 'dept')); // 角色权限 const roleCodes = await this.getRoleCodes(get(user, 'role')); let allCodes = [...deptCodes, ...roleCodes]; allCodes = uniq(allCodes); // 只获取编码,直接返回 if (needCode) return allCodes; // 根据编码获取目录数据 const menuCodes = this.setMenuCodes(allCodes); const qb = { route_name: menuCodes }; const operas = { route_name: this.Opera.In }; const { data: menuList } = await this.menusService.query(qb, null, operas); let treeMenu = menuList.filter(f => !f.parent_id); treeMenu = this.menusService.treeMenu(menuList, treeMenu); return { menus: treeMenu, role_code: allCodes }; } /** * 整理出角色目录的编码,主要是与route_name编码对应 * @param allCodes 本用户的角色+部门的完整权限编码 * @returns 目录需要的编码 */ setMenuCodes(allCodes: Array) { const result = []; for (const code of allCodes) { const arr = code.split('.'); result.push(last(arr)); } return uniq(result); } /** * 根据部门id获取权限列表 * @param deptId 部门id * @returns 权限列表 */ async getDeptCodes(deptId: number) { if (deptId) { const qb = { id: deptId }; const dept = await this.deptService.fetch(qb); if (!dept) return []; // 处理部门有的权限 const resource = get(dept, 'resource', []); // const result = resource.map(i => { // const arr = i.split('.'); // return last(arr); // }); return resource; } else return []; } /** * 根据角色数组获取角色权限 * @param roleCode 角色数据 * @returns 权限列表 */ async getRoleCodes(roleCode: Array) { if (!roleCode) return []; const roleCodes = []; for (const rc of roleCode) { roleCodes.push(lowerFirst(rc)); roleCodes.push(upperFirst(rc)); } // const role = await this.model.findOne({ where: { code: In(roleCode), is_use: '0' } }); const role = await this.fetch({ code: roleCode }, { code: this.Opera.In }); if (!role) return []; const roleMenu = get(role, 'menu', []); return roleMenu; } /** * 根据角色id数组,整理目录 * @param roleIdList 角色id数组 */ async getMenuByRoles(roleIdList) { let menus = []; // 第一步,整理所有目录至一维数组 for (const r of roleIdList) { menus.push(...flattenDeep(r)); } menus = uniq(menus); const qb = { id: menus, is_use: '0' }; const operas = { id: this.Opera.In }; const { data: allMenu } = await this.menusService.query(qb, { order: { order_num: 'ASC' } }, operas); let treeMenu = allMenu.filter(f => !f.parent_id); treeMenu = this.menusService.treeMenu(allMenu, treeMenu); return treeMenu; } }