feat: 管理端公账支付与确认、锁店遮罩及表单提交修复

新增公账账单/到账确认页与全局锁店组件;系统配置补公账参数面板;
统一弹窗 onConfirm 校验提交,并完善订单详情与门店相关交互。
This commit is contained in:
李琦
2026-08-21 12:51:42 +08:00
parent 66e666754a
commit 879efb8f29
145 changed files with 7326 additions and 884 deletions

View File

@@ -238,3 +238,76 @@ describe('generateAccessible - redirect normalization', () => {
expect(findByName(result, 'Custom')?.redirect).toBe('/custom/keep');
});
});
describe('generateAccessible - Root path=/ flatten', () => {
/**
* 模拟框架 Rootpath=/、name=Root用于断言后端 Dashboard(path=/) 被扁平合并
*/
function createRootRouterStub() {
const root: RouteRecordRaw = {
name: 'Root',
path: '/',
redirect: '/home',
children: [],
meta: { title: 'Root' },
};
const routes = [root];
return {
addRoute: (route: RouteRecordRaw) => {
const idx = routes.findIndex((r) => r.name === route.name);
if (idx === -1) {
routes.push(route);
} else {
routes[idx] = route;
}
},
getRoutes: () => routes,
removeRoute: (name: string | symbol) => {
const idx = routes.findIndex((r) => r.name === name);
if (idx !== -1) {
routes.splice(idx, 1);
}
},
_root: root,
} as any;
}
it('后端 Dashboard path=/ 不嵌套进 Root子路由扁平挂到 Root.children', async () => {
const router = createRootRouterStub();
const { accessibleRoutes } = await generateAccessible('frontend', {
router,
routes: [
{
name: 'Dashboard',
path: '/',
redirect: '/workspace',
children: [
{
name: 'Workspace',
path: '/workspace',
meta: { title: 'workspace' },
},
],
meta: { title: 'dashboard' },
},
{
name: 'System',
path: '/system',
meta: { title: 'system' },
},
] as unknown as RouteRecordRaw[],
});
const root = router._root as RouteRecordRaw;
const childNames = (root.children ?? []).map((c) => c.name);
// 不应再挂一层同名 Dashboard
expect(childNames).not.toContain('Dashboard');
expect(childNames).toContain('Workspace');
expect(childNames).toContain('System');
expect(root.redirect).toBe('/workspace');
// 菜单树仍保留原始 Dashboard侧栏结构不变
expect(findByName(accessibleRoutes, 'Dashboard')?.path).toBe('/');
});
});

View File

@@ -29,10 +29,33 @@ async function generateAccessible(
// 生成路由
const accessibleRoutes = await generateRoutes(mode, options);
const root = router.getRoutes().find((item) => item.path === '/');
// 优先按 name=Root 定位布局根,避免误抓到后端 path=/ 的 Dashboard
const root =
router.getRoutes().find((item) => item.name === 'Root') ??
router.getRoutes().find((item) => item.path === '/');
// 获取已有的路由名称列表
const names = root?.children?.map((item) => item.name) ?? [];
// 获取已有的路由名称列表(合并过程中同步维护,保证同批去重)
const names: (string | symbol | undefined)[] =
root?.children?.map((item) => item.name) ?? [];
/**
* 将一条路由挂到 Root.children同名则替换否则追加
* 为什么:切换用户时一级目录要更新,且 path=/ 扁平合并时也要复用同一套去重
*/
const upsertRootChild = (child: RouteRecordRaw) => {
if (!root?.children) {
return;
}
if (names.includes(child.name)) {
const index = root.children.findIndex((item) => item.name === child.name);
if (index !== -1) {
root.children[index] = child;
}
return;
}
root.children.push(child);
names.push(child.name);
};
// 动态添加到router实例内
accessibleRoutes.forEach((route) => {
@@ -42,18 +65,19 @@ async function generateAccessible(
if (route.children && route.children.length > 0) {
delete route.component;
}
// 根据router name判断如果路由已经存在则不再添加
if (names?.includes(route.name)) {
// 找到已存在的路由索引并更新不更新会造成切换用户时一级目录未更新homePath 在二级目录导致的404问题
const index = root.children?.findIndex(
(item) => item.name === route.name,
);
if (index !== undefined && index !== -1 && root.children) {
root.children[index] = route;
// 后端「概览」等与 Root 同 path=/:扁平合并子路由,禁止再嵌套一层同名 Dashboard
if (route.path === '/' || route.path === root.path) {
if (route.redirect) {
root.redirect = route.redirect;
}
} else {
root.children?.push(route);
for (const child of route.children ?? []) {
upsertRootChild(child);
}
return;
}
upsertRootChild(route);
} else {
router.addRoute(route);
}
@@ -66,7 +90,7 @@ async function generateAccessible(
router.addRoute(root);
}
// 生成菜单
// 生成菜单(仍用原始树,侧栏「概览」结构不变;仅 router 挂载做了扁平)
const accessibleMenus = generateMenus(accessibleRoutes, options.router);
return { accessibleMenus, accessibleRoutes };