menus.js 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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 = await this.ctx.service.system.user.getUserInfo();
  38. const userInfoMenu = _.get(userInfo, 'role.menu');
  39. const userInfoMenuMode = _.get(userInfo, 'role.menu.mode');
  40. // 全部权限,直接返回
  41. if (userInfoMenuMode === 'all') return await this.query();
  42. const userInfoMenuIds = Object.keys(userInfoMenu).filter(f => f !== 'mode');
  43. let menus = await this.model.find();
  44. menus = JSON.parse(JSON.stringify(menus));
  45. const res = this.getParent(menus, userInfoMenuIds);
  46. return res;
  47. }
  48. /**
  49. * 查找选中的菜单
  50. * @param {Array} allMenu 树形菜单
  51. * @param {Array} nowMenu 选中的菜单id
  52. */
  53. getParent(allMenu, nowMenu) {
  54. let arr = [];
  55. // 递归查找上级
  56. const checkParent = (menus, tid) => {
  57. const cparr = [];
  58. const parent = menus.find(f => ObjectId(f._id).equals(tid));
  59. if (!parent) return;
  60. const { parent_id } = parent;
  61. cparr.push(parent);
  62. if (!parent_id) return cparr;
  63. const pp = checkParent(menus, parent_id);
  64. cparr.push(...pp);
  65. return cparr;
  66. };
  67. nowMenu = allMenu.filter(f => nowMenu.find(nf => f.path === nf));
  68. for (const nm of nowMenu) {
  69. arr.push(nm);
  70. const { parent_id } = nm;
  71. if (!parent_id) continue;
  72. const parent = checkParent(allMenu, parent_id);
  73. arr.push(...parent);
  74. }
  75. arr = _.uniqBy(arr, '_id');
  76. const headLevel = arr.filter(f => !f.parent_id);
  77. // 变成树形结构
  78. const toTree = (allMenu, menus) => {
  79. for (const m of menus) {
  80. const children = allMenu.filter(f => ObjectId(f.parent_id).equals(m._id));
  81. toTree(allMenu, children);
  82. m.children = children;
  83. }
  84. return menus;
  85. };
  86. arr = toTree(arr, headLevel);
  87. return arr;
  88. }
  89. }
  90. module.exports = MenusService;