云
2 天以前 91bfcf61f44f353dfebc54a57b5b774721de3e9a
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/** 仅供 Vite 本地视觉检查;使用演示菜单和空数据,不连接业务接口。 */
import { createApp, defineComponent, h } from 'vue';
import { createMemoryHistory, createRouter } from 'vue-router';
 
import { BasicLayout, UserDropdown } from '@vben/layouts';
import { IconifyIcon } from '@vben/icons';
import { initPreferences, updatePreferences } from '@vben/preferences';
import { initStores, useAccessStore, useDictStore } from '@vben/stores';
 
import '../src/packages/styles/src';
import '../src/packages/styles/src/antd/index.css';
import '../src/portal-theme.css';
 
import { initComponentAdapter } from '../src/adapter/component';
import { initSetupVbenForm } from '../src/adapter/form';
import { requestClient } from '../src/api/request';
import App from '../src/app.vue';
import AuthLayout from '../src/layouts/auth.vue';
import { setupI18n } from '../src/locales';
import { overridesPreferences, portalAppearancePreferences, preferencesExtension } from '../src/preferences';
import Login from '../src/views/_core/authentication/login.vue';
import Analytics from '../src/views/dashboard/analytics/index.vue';
import PortalBrandText from '../src/components/portal/portal-brand-text.vue';
import Profile from '../src/views/_core/profile/index.vue';
import { portalSystemMenus } from '../src/router/portal-system-menus';
 
await initPreferences({ namespace: 'portal-visual-preview', overrides: overridesPreferences, extension: preferencesExtension });
await initComponentAdapter();
await initSetupVbenForm();
 
// 此替身仅存在于独立预览入口,正式入口不加载本文件。
const surface = new URLSearchParams(location.search).get('surface');
const crowded = new URLSearchParams(location.search).get('crowded') === '1';
const populated = new URLSearchParams(location.search).get('populated') === '1';
let failNoticeOnce = surface === 'notice-error';
requestClient.get = async (url: string) => {
  if (url.includes('/system/user/profile/get')) {
    if (surface === 'profile-error') throw new Error('预览资料加载失败');
    return { id: 1, username: 'preview-user', nickname: '预览用户', email: 'preview@example.com', mobile: '', sex: 1, avatar: '', dept: { name: '学术研究部(示例)' }, roles: [{ id: 1, name: '普通用户(示例)' }], posts: [{ name: '研究人员(示例)' }], createTime: '2026-01-01 09:00:00', loginDate: '2026-10-18 09:30:00', loginIp: '127.0.0.1' } as never;
  }
  if (url.includes('/system/social-user/get-bind-list')) return [] as never;
  if (failNoticeOnce && url.includes('/bpm/oa/notice/page')) {
    failNoticeOnce = false;
    throw new Error('演示公告加载失败');
  }
  if (populated && url.includes('/research/application/page')) {
    return { total: 12, list: [
      '供销合作服务体系与乡村产业协同发展研究',
      '农产品流通模式与数字化服务研究',
      '农村现代物流与资源协同机制研究',
      '新形势下供销合作经济发展路径研究',
      '基层服务能力建设与创新实践研究',
      '区域协同与供销合作高质量发展研究',
    ].map((title, index) => ({ id: index + 1, title: `示例|${title}`, applicantName: '预览用户', createTime: `2026-10-${String(18 - index).padStart(2, '0')}`, status: 15 })) } as never;
  }
  if (populated && url.includes('/bpm/oa/notice/page')) {
    return { total: 6, list: [
      '关于开展年度研究课题申报工作的通知',
      '关于课题申报材料提交的相关说明',
      '关于业务协同服务事项的通知',
      '关于加强课题研究成果交流的通知',
      '关于完善平台个人资料的通知',
      '关于近期系统服务安排的通知',
    ].map((title, index) => ({ id: index + 1, title: `示例|${title}`, publishTime: `2026-10-${String(18 - index).padStart(2, '0')}`, createTime: '2026-10-18' })) } as never;
  }
  if (populated && url.includes('/bpm/task/todo')) return { list: [], total: 3 } as never;
  if (populated && url.includes('/finance/reimbursement/page')) return { list: [], total: 8 } as never;
  if (populated && url.includes('/research/guideline/page')) return { list: [], total: 4 } as never;
  return { list: [], total: 0 } as never;
};
 
const emptyPage = defineComponent({ render: () => h('div', { style: 'padding:32px;background:white' }, '业务页面预览') });
const shell = defineComponent({
  setup: () => () => h(BasicLayout, { class: 'supply-portal-shell' }, {
    'logo-text': () => h(PortalBrandText),
    'user-dropdown': () => h(UserDropdown, { showText: true, avatar: '/static/imgs/portal-avatar.svg', text: populated ? '预览数据' : '演示用户', menus: [{ text: '个人中心', icon: 'lucide:user-round', handler: () => router.push('/profile') }, { text: '密码设置', icon: 'lucide:shield-check', handler: () => router.push('/profile?section=resetPwd') }] }),
    'header-right-165': () => h('button', { class: 'portal-personal-entry', 'aria-label': '个人中心', onClick: () => router.push('/profile') }, [h(IconifyIcon, { icon: 'lucide:user-round' }), h('span', '个人中心')]),
  }),
});
const router = createRouter({
  history: createMemoryHistory(),
  routes: [
    { path: '/auth', component: AuthLayout, children: [{ path: 'login', component: Login, name: 'Login', meta: { title: '登录' } }] },
    { path: '/', name: 'PortalPreviewShell', component: shell, children: [
      { path: 'analytics', name: 'Analytics', component: Analytics, meta: { title: '首页', affixTab: true, icon: 'lucide:house' } },
      { path: 'profile', name: 'Profile', component: Profile, meta: { title: '个人中心', fullPathKey: false } },
      { path: 'bpm/task/todo', name: 'BpmTaskTodo', component: emptyPage, meta: { title: '待办任务' } },
      { path: 'bpm/task/done', name: 'BpmTaskDone', component: emptyPage, meta: { title: '已办任务' } },
      { path: 'bpm/create', name: 'BpmProcessInstanceCreate', component: emptyPage, meta: { title: '发起流程' } },
      { path: 'research/application', name: 'ResearchApplication', component: emptyPage, meta: { title: '课题申报' } },
      { path: 'research/guideline', name: 'ResearchGuideline', component: emptyPage, meta: { title: '课题指南' } },
      { path: 'finance/reimbursement', name: 'FinanceReimbursement', component: emptyPage, meta: { title: '财务报销' } },
      { path: 'bpm/oa/notice', name: 'BpmOaNotice', component: emptyPage, meta: { title: '通知公告' } },
    ] },
  ],
});
 
const app = createApp(App);
await initStores(app, { namespace: 'portal-visual-preview' });
useDictStore().setDictCache({ system_user_sex: [{ label: '男', value: '1' }, { label: '女', value: '2' }] });
await setupI18n(app);
const access = useAccessStore();
const previewMenus = [
  { path: '/analytics', name: '首页', icon: 'lucide:house' },
  { path: '/bpm', name: '审批中心', icon: 'lucide:workflow', children: [
    { path: '/bpm/task/todo', name: '待办任务', icon: 'lucide:list-todo' },
    { path: '/bpm/task/done', name: '已办任务', icon: 'lucide:circle-check' },
    { path: '/bpm/create', name: '发起流程', icon: 'lucide:circle-plus' },
    { path: '/bpm/oa/notice', name: '通知公告', icon: 'lucide:megaphone' },
  ] },
  { path: '/research', name: '课题管理', icon: 'lucide:book-open-text', children: [
    { path: '/research/application', name: '课题申报', icon: 'lucide:file-text' },
    { path: '/research/guideline', name: '课题指南', icon: 'lucide:book-open' },
  ] },
  { path: '/finance', name: '财务报销', icon: 'lucide:receipt', children: [
    { path: '/finance/reimbursement', name: '报销管理', icon: 'lucide:receipt' },
  ] },
];
if (surface === 'system') {
  const [system] = portalSystemMenus([
    { id: 1, parentId: 0, path: '/system', name: '系统管理', meta: { title: '系统管理' }, children: [
      { id: 2, parentId: 1, path: 'tenant', name: '租户管理', meta: { title: '租户管理' }, children: [
        { id: 3, parentId: 2, path: 'list', name: '租户列表', component: 'system/tenant/index', meta: { title: '租户列表' } },
      ] },
    ] },
  ], ['system:user:list', 'system:role:query', 'system:dept:query', 'system:post:query', 'system:menu:query', 'system:dict:query'], []);
  if (system) {
    previewMenus.push({ path: '/system', name: system.name, icon: system.icon ?? 'lucide:settings-2', children: system.children?.map((item) => {
      const path = `/system/${item.path}`;
      router.addRoute('PortalPreviewShell', { path, name: item.componentName ?? item.name, component: emptyPage, meta: { title: item.name } });
      return { path, name: item.name, icon: item.icon ?? 'lucide:settings-2' };
    }) ?? [] });
  }
}
if (crowded) {
  for (let index = 1; index <= 16; index++) {
    const path = `/preview-module/${index}`;
    previewMenus.push({ path, name: `演示模块${index}`, icon: 'lucide:layers' });
    router.addRoute('PortalPreviewShell', { path, name: `PreviewModule${index}`, component: emptyPage, meta: { title: `演示模块${index}` } });
  }
}
access.setAccessMenus(previewMenus.map((menu) => ({ ...menu, parents: [], children: menu.children?.map((child) => ({ ...child, parents: [menu.path] })) })));
router.addRoute({ path: '/bpm', redirect: '/bpm/task/todo' });
router.addRoute({ path: '/research', redirect: '/research/application' });
router.addRoute({ path: '/finance', redirect: '/finance/reimbursement' });
updatePreferences({ ...portalAppearancePreferences, copyright: overridesPreferences.copyright, logo: overridesPreferences.logo, app: { ...overridesPreferences.app, ...portalAppearancePreferences.app, enableCheckUpdates: false, enablePreferences: crowded }, widget: { ...portalAppearancePreferences.widget, notification: false, globalSearch: true, fullscreen: crowded, themeToggle: false } });
app.use(router);
await router.push(surface === 'login' ? '/auth/login' : surface?.startsWith('profile') ? { path: '/profile', query: { section: new URLSearchParams(location.search).get('section') ?? 'basicInfo' } } : surface === 'menu' ? '/bpm/task/todo' : surface === 'system' ? '/system/user' : '/analytics');
await router.isReady();
app.mount('#app');
document.getElementById('__app-loading__')?.remove();