1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import type { MenuRecordRaw } from '@vben/types';
 
import { computed } from 'vue';
import { useRouter } from 'vue-router';
 
import { useAccessStore } from '@vben/stores';
 
function visibleTree(items: MenuRecordRaw[]): MenuRecordRaw[] {
  return items.flatMap((item) => {
    if (item.show === false || item.disabled || item.path === '/analytics') return [];
    const children = item.children ? visibleTree(item.children) : undefined;
    if (item.children?.length && !children?.length) return [];
    return [{ ...item, children }];
  });
}
 
function flatten(items: MenuRecordRaw[]): MenuRecordRaw[] {
  return items.flatMap((item) => item.children?.length ? flatten(item.children) : [item]);
}
 
export function firstPortalPage(menu: MenuRecordRaw): MenuRecordRaw | undefined {
  if (menu.disabled || menu.show === false) return;
  if (menu.children?.length) {
    for (const child of menu.children) {
      const target = firstPortalPage(child);
      if (target) return target;
    }
    return;
  }
  return menu.path ? menu : undefined;
}
 
export function portalCategory(menu: MenuRecordRaw) {
  const key = `${menu.path} ${menu.name}`;
  if (/research|课题|科研|学术/i.test(key)) return 'research';
  if (/finance|财务|报销/i.test(key)) return 'finance';
  if (/bpm|审批|办公|流程/i.test(key)) return 'office';
  return 'archive';
}
 
export function usePortalMenus() {
  const router = useRouter();
  const access = useAccessStore();
  const menus = computed(() => visibleTree(access.accessMenus));
  const leaves = computed(() => flatten(menus.value));
  const match = (pattern: RegExp) => leaves.value.find((menu) => pattern.test(`${menu.name} ${menu.path}`));
  const features = computed(() => ({
    todo: match(/待办任务|我的待办|\/task\/todo/),
    create: match(/发起流程|\/process-instance\/create/),
    application: match(/课题申报|\/research\/application/),
    guideline: match(/课题指南|\/research\/guideline/),
    reimbursement: match(/财务报销|报销管理|\/finance\/reimbursement/),
    notice: match(/\/bpm\/oa\/notice/) ?? match(/通知公告|\/system\/notice/),
  }));
 
  function goMenu(menu?: MenuRecordRaw) {
    const target = menu && firstPortalPage(menu);
    if (!target) return;
    if (/^https?:\/\//i.test(target.path)) window.open(target.path, '_blank', 'noopener,noreferrer');
    else router.push({ path: target.path, query: target.query });
  }
 
  return { menus, leaves, features, goMenu };
}