menus.js 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. 'use strict';
  2. const { CrudService } = require('naf-framework-mongoose-free/lib/service');
  3. const { BusinessError, ErrorCode } = require('naf-core').Error;
  4. const _ = require('lodash');
  5. const assert = require('assert');
  6. const { ObjectId } = require('mongoose').Types;
  7. //
  8. class MenusService extends CrudService {
  9. constructor(ctx) {
  10. super(ctx, 'menus');
  11. this.model = this.ctx.model.Dev.Menus;
  12. }
  13. async query(query = {}) {
  14. let list = await this.model.find(query).sort({ order_num: 1 });
  15. if (list.length > 0) list = JSON.parse(JSON.stringify(list));
  16. let treeMenu = list.filter(f => !f.parent_id);
  17. treeMenu = this.treeMenu(list, treeMenu);
  18. return treeMenu;
  19. }
  20. treeMenu(allMenus, nowMenu) {
  21. for (const nm of nowMenu) {
  22. const { _id, parent_id } = nm;
  23. // 查下下级其是否有目录
  24. let children = allMenus.filter(f => ObjectId(f.parent_id).equals(_id));
  25. children = this.treeMenu(allMenus, children);
  26. if (children.length > 0) nm.children = children;
  27. // 换父级组件的名称
  28. if (parent_id) {
  29. const r = allMenus.find(f => ObjectId(f._id).equals(parent_id));
  30. if (r) nm.parent_name = r.name;
  31. }
  32. }
  33. nowMenu = _.orderBy(nowMenu, [ 'order_num', [ 'asc' ]]);
  34. return nowMenu;
  35. }
  36. async getUserMenu() {
  37. const userInfo = this.ctx.admin;
  38. if (!userInfo) return [];
  39. const userInfoMenu = _.get(userInfo, 'role.menu');
  40. const userInfoMenuMode = _.get(userInfo, 'role.menu.mode');
  41. // 全部权限,直接返回
  42. if (userInfoMenuMode === 'all') return await this.query();
  43. const userInfoMenuIds = Object.keys(userInfoMenu).filter(f => f !== 'mode');
  44. let menus = await this.model.find();
  45. menus = JSON.parse(JSON.stringify(menus));
  46. const res = this.getParent(menus, userInfoMenuIds);
  47. return res;
  48. }
  49. /**
  50. * 查找选中的菜单
  51. * @param {Array} allMenu 树形菜单
  52. * @param {Array} nowMenu 选中的菜单id
  53. */
  54. getParent(allMenu, nowMenu) {
  55. let arr = [];
  56. // 递归查找上级
  57. const checkParent = (menus, tid) => {
  58. const cparr = [];
  59. const parent = menus.find(f => ObjectId(f._id).equals(tid));
  60. if (!parent) return;
  61. const { parent_id } = parent;
  62. cparr.push(parent);
  63. if (!parent_id) return cparr;
  64. const pp = checkParent(menus, parent_id);
  65. cparr.push(...pp);
  66. return cparr;
  67. };
  68. nowMenu = allMenu.filter(f => nowMenu.find(nf => f.path === nf));
  69. for (const nm of nowMenu) {
  70. arr.push(nm);
  71. const { parent_id } = nm;
  72. if (!parent_id) continue;
  73. const parent = checkParent(allMenu, parent_id);
  74. arr.push(...parent);
  75. }
  76. arr = _.uniqBy(arr, '_id');
  77. const headLevel = arr.filter(f => !f.parent_id);
  78. // 变成树形结构
  79. const toTree = (allMenu, menus) => {
  80. for (const m of menus) {
  81. const children = allMenu.filter(f => ObjectId(f.parent_id).equals(m._id));
  82. toTree(allMenu, children);
  83. m.children = children;
  84. }
  85. return menus;
  86. };
  87. arr = toTree(arr, headLevel);
  88. return arr;
  89. }
  90. }
  91. module.exports = MenusService;