liujie
2026-08-21 a7c8a8f6055e1a03414f2227d12ff2e87ec52d41
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
const page = (code, title, path, options = {}) => ({ code, title, path, ...options })
const placeholder = (code, title, path, description, options = {}) => page(code, title, path, {
  component: 'placeholder',
  description,
  endpoint: '待接入',
  ...options,
})
 
export const adminMenu = [
  page('dashboard', '工作台', '/dashboard', { icon: 'Monitor', component: 'dashboard', permission: 'DASHBOARD' }),
  {
    code: 'users', title: '用户管理', icon: 'User', children: [
      page('visitor-list', '游客列表', '/visitors', { component: 'visitors', permission: 'VISITOR_LIST' }),
    ],
  },
  {
    code: 'guides', title: '导游管理', icon: 'Guide', children: [
      page('guide-list', '导游列表', '/guides', { component: 'guides', permission: 'GUIDE_LIST' }),
      page('guide-audit', '导游审核', '/guide-audits', { component: 'guideAudits', permission: 'GUIDE_AUDIT' }),
      page('guide-team', '讲解队管理', '/guide-teams', { component: 'guideTeams', permission: 'GUIDE_TEAM' }),
    ],
  },
  {
    code: 'orders', title: '订单管理', icon: 'Tickets', children: [
      page('order-list', '订单列表', '/orders', { component: 'orders', permission: 'ORDER_LIST' }),
    ],
  },
  {
    code: 'operations', title: '运营管理', icon: 'Operation', children: [
      page('city-list', '城市管理', '/operations/cities', { component: 'cities', permission: 'CITY_LIST' }),
      page('scenic-list', '景区管理', '/operations/scenic-spots', { component: 'scenicSpots', permission: 'SCENIC_LIST' }),
      page('review-list', '评价管理', '/operations/reviews', { component: 'reviews', permission: 'REVIEW_LIST' }),
      page('feedback-list', '反馈管理', '/operations/feedback', { component: 'feedback', permission: 'FEEDBACK_LIST' }),
      page('platform-settings', '平台设置', '/operations/platform-settings', { component: 'platformSettings', permission: 'PLATFORM_SETTINGS' }),
      page('agreement-settings', '协议设置', '/operations/agreements', { component: 'agreements', permission: 'AGREEMENT_SETTINGS' }),
    ],
  },
  {
    code: 'finance', title: '财务管理', icon: 'Wallet', children: [
      page('finance-detail', '财务详情', '/finance/details', { component: 'financeLedger', permission: 'FINANCE_DETAIL' }),
      page('finance-refund', '财务详情-退款', '/finance/refunds', { component: 'financeLedger', permission: 'FINANCE_REFUND' }),
      page('withdrawal-list', '提现管理', '/finance/withdrawals', { component: 'withdrawals', permission: 'WITHDRAWAL_LIST' }),
    ],
  },
  {
    code: 'system', title: '系统设置', icon: 'Setting', children: [
      page('role-list', '角色管理', '/system/roles', { component: 'roles', permission: 'ROLE_LIST' }),
      page('employee-list', '员工管理', '/system/employees', { component: 'employees', permission: 'EMPLOYEE_LIST' }),
    ],
  },
]
 
const componentLoaders = {
  dashboard: () => import('@/views/DashboardView.vue'),
  employees: () => import('@/views/AdminUsersView.vue'),
  visitors: () => import('@/views/MiniUsersView.vue'),
  guides: () => import('@/views/GuideUsersView.vue'),
  guideAudits: () => import('@/views/GuideAuditsView.vue'),
  guideTeams: () => import('@/views/GuideTeamsView.vue'),
  orders: () => import('@/views/OrdersView.vue'),
  reviews: () => import('@/views/ReviewsView.vue'),
  feedback: () => import('@/views/FeedbackView.vue'),
  cities: () => import('@/views/CitiesView.vue'),
  scenicSpots: () => import('@/views/ScenicSpotsView.vue'),
  agreements: () => import('@/views/AgreementsView.vue'),
  platformSettings: () => import('@/views/PlatformSettingsView.vue'),
  roles: () => import('@/views/RolesView.vue'),
  financeLedger: () => import('@/views/FinanceLedgerView.vue'),
  withdrawals: () => import('@/views/WithdrawalsView.vue'),
  placeholder: () => import('@/components/ModulePlaceholder.vue'),
}
 
const toRoute = (item) => ({
  path: item.path.slice(1),
  name: item.code,
  component: componentLoaders[item.component],
  meta: { title: item.title, permission: item.permission },
  props: item.component === 'placeholder'
    ? { title: item.title, description: item.description, endpoint: item.endpoint }
    : undefined,
})
 
export const createAdminRoutes = (items = adminMenu) => items.flatMap((item) => {
  const routes = item.path ? [toRoute(item)] : []
  return item.children ? routes.concat(createAdminRoutes(item.children)) : routes
})
 
export const getExpandedMenuCodes = (items = adminMenu) => items.flatMap((item) => (
  item.children ? [item.code, ...getExpandedMenuCodes(item.children)] : []
))
 
export const hasPermission = (menuCodes, permission) => (
  !permission || new Set(menuCodes || []).has(permission)
)
 
export const filterAdminMenu = (menuCodes, items = adminMenu) => items.flatMap((item) => {
  if (item.children) {
    const children = filterAdminMenu(menuCodes, item.children)
    return children.length ? [{ ...item, children }] : []
  }
  return hasPermission(menuCodes, item.permission) ? [item] : []
})
 
export const firstPermittedPath = (menuCodes) => {
  const firstItem = filterAdminMenu(menuCodes)
    .flatMap((item) => item.children || [item])
    .find((item) => item.path)
  return firstItem?.path || null
}