const Router = (() => { const routes = {}; const beforeEachHooks = []; const afterEachHooks = []; function register(path, render) { routes[path] = render; } function onBeforeEach(fn) { beforeEachHooks.push(fn); } function onAfterEach(fn) { afterEachHooks.push(fn); } async function navigate(path) { for (const h of beforeEachHooks) await h(path); const view = document.getElementById('view'); view.classList.add('fade-enter'); const render = routes[path] || routes['/404']; const html = await render(); view.innerHTML = html; requestAnimationFrame(() => { view.classList.add('fade-enter-active'); view.classList.remove('fade-enter'); setTimeout(() => view.classList.remove('fade-enter-active'), 220); }); for (const h of afterEachHooks) await h(path); } async function init() { window.addEventListener('hashchange', () => { const path = location.hash.replace('#', '') || '/dashboard'; navigate(path); highlightActive(path); updateBreadcrumb(path); }); const path = location.hash.replace('#', '') || '/dashboard'; navigate(path); highlightActive(path); updateBreadcrumb(path); } function highlightActive(path) { document.querySelectorAll('.nav-item, .nav-child').forEach(el => el.classList.remove('active')); const target = document.querySelector(`[data-route="${routeKey(path)}"]`); if (target) target.classList.add('active'); } function routeKey(path) { return path .replace('/', '') .replaceAll('/', '-') || 'dashboard'; } function updateBreadcrumb(path) { const bc = document.getElementById('breadcrumb'); if (!bc) return; // 元素不存在时直接返回 const parts = path.split('/').filter(Boolean); let acc = '#'; bc.innerHTML = parts.map((p, i) => { acc += '/' + p; const last = i === parts.length - 1; return `${label(p)}`; }).join(' / '); } function label(key) { const map = { dashboard: '仪表盘', login: '登录', upload: '上传', mac: 'MAC与批次', stats: '良/不良统计', defects: '不良明细', repairs: '返修记录', 'repairs-history': '返修历史', shipments: '发货', sop: 'SOP', query: '详细记录查询', summary: '汇总信息查询', devices: '设备状态', environment: '环境参数', personnel: '人员信息', qa: '质检报告', production: '时间记录', 'production-mgmt': '生产管理', 'work-order': '生产工单下发中心', 'plan-mgmt': '计划管理', 'bom': 'BOM物料清单', 'initial-stock': '期初库存', 'purchase-demand': '采购需求清单', 'customer-order': '客户订单', 'reconciliation': '对账单', export: '导出', settings: '设置', finance: '财务管理', 'customer-rec': '客户对账', 'supplier-rec': '供应商对账', invoice: '发票管理', outsoucing: '委外管理', 'outsourcing-mgmt': '委外管理', 'outsourcing-orders': '委外工单', 'material-issue': '委外发料', 'finished-goods-receipt': '成品入库', 'wip-stock': '委外在制库存', collect: '采集', test: '测试', meituan: '美团测试', system: '系统', 'operations-log': '操作日志', 'material-purchase': '物料采购', 'ai-report': 'AI报表', warehouse: '仓库管理', borrow: '借出单', return: '借出还入单' }; return map[key] || key; } return { register, init, onBeforeEach, onAfterEach }; })();