'use strict'; const { CrudService } = require('naf-framework-mongoose-free/lib/service'); const { BusinessError, ErrorCode } = require('naf-core').Error; const _ = require('lodash'); const assert = require('assert'); const { ObjectId } = require('mongoose').Types; // class MenusService extends CrudService { constructor(ctx) { super(ctx, 'menus'); this.model = this.ctx.model.Dev.Menus; } async query(query = {}) { let list = await this.model.find(query).sort({ order_num: 1 }); if (list.length > 0) list = JSON.parse(JSON.stringify(list)); let treeMenu = list.filter(f => !f.parent_id); treeMenu = this.treeMenu(list, treeMenu); return treeMenu; } treeMenu(allMenus, nowMenu) { for (const nm of nowMenu) { const { _id, parent_id } = nm; // 查下下级其是否有目录 let children = allMenus.filter(f => ObjectId(f.parent_id).equals(_id)); children = this.treeMenu(allMenus, children); if (children.length > 0) nm.children = children; // 换父级组件的名称 if (parent_id) { const r = allMenus.find(f => ObjectId(f._id).equals(parent_id)); if (r) nm.parent_name = r.name; } } nowMenu = _.orderBy(nowMenu, [ 'order_num', [ 'asc' ]]); return nowMenu; } async getUserMenu() { const userInfo = this.ctx.admin; if (!userInfo) return []; const userInfoMenu = _.get(userInfo, 'role.menu'); const userInfoMenuMode = _.get(userInfo, 'role.menu.mode'); // 全部权限,直接返回 if (userInfoMenuMode === 'all') return await this.query(); const userInfoMenuIds = Object.keys(userInfoMenu).filter(f => f !== 'mode'); let menus = await this.model.find(); menus = JSON.parse(JSON.stringify(menus)); const res = this.getParent(menus, userInfoMenuIds); return res; } /** * 查找选中的菜单 * @param {Array} allMenu 树形菜单 * @param {Array} nowMenu 选中的菜单id */ getParent(allMenu, nowMenu) { let arr = []; // 递归查找上级 const checkParent = (menus, tid) => { const cparr = []; const parent = menus.find(f => ObjectId(f._id).equals(tid)); if (!parent) return; const { parent_id } = parent; cparr.push(parent); if (!parent_id) return cparr; const pp = checkParent(menus, parent_id); cparr.push(...pp); return cparr; }; nowMenu = allMenu.filter(f => nowMenu.find(nf => f.path === nf)); for (const nm of nowMenu) { arr.push(nm); const { parent_id } = nm; if (!parent_id) continue; const parent = checkParent(allMenu, parent_id); arr.push(...parent); } arr = _.uniqBy(arr, '_id'); const headLevel = arr.filter(f => !f.parent_id); // 变成树形结构 const toTree = (allMenu, menus) => { for (const m of menus) { const children = allMenu.filter(f => ObjectId(f.parent_id).equals(m._id)); toTree(allMenu, children); m.children = children; } return menus; }; arr = toTree(arr, headLevel); return arr; } } module.exports = MenusService;