调整部分前端布局和后端增删改逻辑
This commit is contained in:
@@ -159,21 +159,95 @@ test("PDA 路由和工作台入口覆盖五类现场业务", async () => {
|
||||
assert.equal(pagePaths.has(pagePath), true, `${pagePath} 路由缺失`);
|
||||
}
|
||||
|
||||
const workSource = await readFile(
|
||||
path.join(appRoot, "src/pages/work/index.vue"),
|
||||
"utf8",
|
||||
const [workSource, menuSource] = await Promise.all([
|
||||
readFile(path.join(appRoot, "src/pages/work/index.vue"), "utf8"),
|
||||
readFile(path.join(appRoot, "src/config/businessMenu.js"), "utf8"),
|
||||
]);
|
||||
assert.match(workSource, /hasPermi\(entry\.permission\)/);
|
||||
assert.match(menuSource, /business:inbound:list/);
|
||||
assert.match(menuSource, /business:filling:list/);
|
||||
assert.match(menuSource, /business:shipment:list/);
|
||||
assert.match(menuSource, /business:usage:list/);
|
||||
assert.match(menuSource, /business:return:list/);
|
||||
assert.match(menuSource, /pages\/business\/inbound\/index/);
|
||||
assert.match(menuSource, /pages\/business\/filling\/index/);
|
||||
assert.match(menuSource, /pages\/business\/shipment\/index/);
|
||||
assert.match(menuSource, /pages\/business\/usage\/index/);
|
||||
assert.match(menuSource, /pages\/business\/return\/index/);
|
||||
});
|
||||
|
||||
test("首页展示真实运营驾驶舱,不保留模板入口和虚假统计", async () => {
|
||||
const source = await readFile(path.join(appRoot, "src/pages/index.vue"), "utf8");
|
||||
assert.match(source, /listScanExceptions/);
|
||||
assert.match(source, /最近扫码异常/);
|
||||
assert.match(source, /TestBatchBanner/);
|
||||
assert.doesNotMatch(
|
||||
source,
|
||||
/快捷入口|新闻|计划|请假申请|周报|工作效率|新通知|待办任务|85%/,
|
||||
);
|
||||
assert.match(workSource, /hasPermiOr/);
|
||||
assert.match(workSource, /business:inbound/);
|
||||
assert.match(workSource, /business:filling/);
|
||||
assert.match(workSource, /business:shipment/);
|
||||
assert.match(workSource, /business:usage/);
|
||||
assert.match(workSource, /business:return/);
|
||||
assert.match(workSource, /pages\/business\/inbound\/index/);
|
||||
assert.match(workSource, /pages\/business\/filling\/index/);
|
||||
assert.match(workSource, /pages\/business\/shipment\/index/);
|
||||
assert.match(workSource, /pages\/business\/usage\/index/);
|
||||
assert.match(workSource, /pages\/business\/return\/index/);
|
||||
});
|
||||
|
||||
test("工作台只展示真实业务入口并使用后端列表权限", async () => {
|
||||
const [workSource, menuModule] = await Promise.all([
|
||||
readFile(path.join(appRoot, "src/pages/work/index.vue"), "utf8"),
|
||||
importSource("src/config/businessMenu.js"),
|
||||
]);
|
||||
|
||||
assert.deepEqual(
|
||||
menuModule.businessMenuEntries.map(({ title, permission, path: entryPath }) => ({
|
||||
title,
|
||||
permission,
|
||||
path: entryPath,
|
||||
})),
|
||||
[
|
||||
{
|
||||
title: "仓库入库",
|
||||
permission: "business:inbound:list",
|
||||
path: "/pages/business/inbound/index",
|
||||
},
|
||||
{
|
||||
title: "工厂装填",
|
||||
permission: "business:filling:list",
|
||||
path: "/pages/business/filling/index",
|
||||
},
|
||||
{
|
||||
title: "发货出库",
|
||||
permission: "business:shipment:list",
|
||||
path: "/pages/business/shipment/index",
|
||||
},
|
||||
{
|
||||
title: "客户现场使用",
|
||||
permission: "business:usage:list",
|
||||
path: "/pages/business/usage/index",
|
||||
},
|
||||
{
|
||||
title: "退回仓库",
|
||||
permission: "business:return:list",
|
||||
path: "/pages/business/return/index",
|
||||
},
|
||||
],
|
||||
);
|
||||
assert.match(workSource, /businessMenuEntries/);
|
||||
assert.match(workSource, /hasPermi\(entry\.permission\)/);
|
||||
assert.match(workSource, /navigateTo\(entry\.path\)/);
|
||||
assert.doesNotMatch(workSource, /AI 生产力|智能对话|图像生成|系统管理|handleBuilding|模块建设中/);
|
||||
});
|
||||
|
||||
test("运营驾驶舱 API 对接现有扫码异常接口", async () => {
|
||||
const source = await readFile(path.join(appRoot, "src/api/business/dashboard.js"), "utf8");
|
||||
assert.match(source, /export function listScanExceptions\(/);
|
||||
assert.match(source, /url:\s*["']\/business\/dashboard\/scan-exceptions["']/);
|
||||
assert.match(source, /method:\s*["']get["']/);
|
||||
});
|
||||
|
||||
test("APP 页面标题与后端业务菜单名称一致", async () => {
|
||||
const [pages, fillingSource] = await Promise.all([
|
||||
JSON.parse(await readFile(path.join(appRoot, "src/pages.json"), "utf8")),
|
||||
readFile(path.join(appRoot, "src/pages/business/filling/index.vue"), "utf8"),
|
||||
]);
|
||||
const fillingPage = pages.pages.find((page) => page.path === "pages/business/filling/index");
|
||||
assert.equal(fillingPage?.style?.navigationBarTitleText, "工厂装填");
|
||||
assert.match(fillingSource, />工厂装填</);
|
||||
});
|
||||
|
||||
test("PDA 测试模式附加批次请求头并在五个业务页持续提示", async () => {
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { dirname, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import test from "node:test";
|
||||
|
||||
const appRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const readSource = (relativePath) =>
|
||||
readFileSync(resolve(appRoot, relativePath), "utf8");
|
||||
|
||||
test("APP 首页展示 PC 端核心运营统计并保护移动端横向空间", () => {
|
||||
const source = readSource("src/pages/index.vue");
|
||||
|
||||
for (const className of [
|
||||
"dashboard-overview",
|
||||
"dashboard-kpi-grid",
|
||||
"dashboard-trend-card",
|
||||
"dashboard-distribution-card",
|
||||
"dashboard-trend-range",
|
||||
"dashboard-status-list",
|
||||
]) {
|
||||
assert.match(source, new RegExp(`class=\\"[^\\"]*${className}[^\\"]*\\"`));
|
||||
}
|
||||
|
||||
for (const label of [
|
||||
"当前库存托盘",
|
||||
"剩余包数",
|
||||
"今日入库单",
|
||||
"今日出库单",
|
||||
"待确认单据",
|
||||
"入库 / 出库趋势",
|
||||
"托盘流转状态分布",
|
||||
]) {
|
||||
assert.match(source, new RegExp(label));
|
||||
}
|
||||
|
||||
assert.match(source, /listPalletInventory/);
|
||||
assert.match(source, /listShipmentReport/);
|
||||
assert.match(source, /listInbound/);
|
||||
assert.match(source, /listShipment/);
|
||||
assert.match(source, /listReturn/);
|
||||
assert.match(source, /TREND_RANGE_OPTIONS/);
|
||||
assert.match(source, /overflow-x:\s*hidden/);
|
||||
assert.match(source, /min-width:\s*0/);
|
||||
});
|
||||
|
||||
test("APP 首页统计保留加载、空数据和部分失败状态", () => {
|
||||
const source = readSource("src/pages/index.vue");
|
||||
|
||||
assert.match(source, /statsLoading/);
|
||||
assert.match(source, /statsError/);
|
||||
assert.match(source, /dashboard-stat-empty/);
|
||||
assert.match(source, /dashboard-stat-error/);
|
||||
assert.match(source, /formatMetric/);
|
||||
assert.match(source, /--/);
|
||||
});
|
||||
|
||||
test("APP 首页扫码异常支持默认收起并通过标题展开", () => {
|
||||
const source = readSource("src/pages/index.vue");
|
||||
|
||||
assert.match(source, /const exceptionsExpanded = ref\(false\)/);
|
||||
assert.match(source, /function toggleExceptionList\(\)/);
|
||||
assert.match(source, /class="[^"]*exception-header[^"]*"/);
|
||||
assert.match(source, /@click="toggleExceptionList"/);
|
||||
assert.match(source, /exception-toggle-icon/);
|
||||
assert.match(source, /v-else-if="exceptionsExpanded" class="exception-list"/);
|
||||
});
|
||||
|
||||
test("APP 首页报表 API 复用现有只读报表路径", () => {
|
||||
const inventorySource = readSource("src/api/report/palletInventory.js");
|
||||
const shipmentSource = readSource("src/api/report/shipment.js");
|
||||
|
||||
assert.match(inventorySource, /export function listPalletInventory\(/);
|
||||
assert.match(inventorySource, /url:\s*["']\/report\/pallet-inventory\/list["']/);
|
||||
assert.match(inventorySource, /method:\s*["']get["']/);
|
||||
assert.match(shipmentSource, /export function listShipmentReport\(/);
|
||||
assert.match(shipmentSource, /url:\s*["']\/report\/shipment\/list["']/);
|
||||
assert.match(shipmentSource, /method:\s*["']get["']/);
|
||||
});
|
||||
@@ -0,0 +1,38 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { existsSync, readFileSync } from "node:fs";
|
||||
import { dirname, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import test from "node:test";
|
||||
|
||||
const appRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const loginPagePath = resolve(appRoot, "src/pages/login.vue");
|
||||
const loginPageSource = readFileSync(loginPagePath, "utf8");
|
||||
|
||||
test("APP 登录页沿用 PC 端的品牌背景与登录卡片结构", () => {
|
||||
assert.match(loginPageSource, /class="login-page"/);
|
||||
assert.match(loginPageSource, /\/static\/login-background\.jpg/);
|
||||
assert.match(loginPageSource, /class="login-card"/);
|
||||
assert.match(loginPageSource, /globalConfig\.appInfo\.name/);
|
||||
assert.doesNotMatch(
|
||||
loginPageSource,
|
||||
/bg-gradient-to-br from-blue-50 to-indigo-100/,
|
||||
);
|
||||
assert.ok(
|
||||
existsSync(resolve(appRoot, "src/static/login-background.jpg")),
|
||||
"APP 登录页需要包含与 PC 端一致的背景资源",
|
||||
);
|
||||
});
|
||||
|
||||
test("APP 登录页保留验证码刷新与回车登录交互", () => {
|
||||
assert.match(loginPageSource, /@click="getCode"/);
|
||||
assert.match(loginPageSource, /@confirm="handleLogin"/);
|
||||
assert.match(loginPageSource, /captchaEnabled/);
|
||||
});
|
||||
|
||||
test("APP 登录页为白色 Sylvan 字标提供深色承载层", () => {
|
||||
assert.match(loginPageSource, /class="brand-logo-frame"/);
|
||||
assert.match(
|
||||
loginPageSource,
|
||||
/\.brand-logo-frame\s*\{[\s\S]*background:\s*#28225c/,
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,47 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { dirname, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import test from "node:test";
|
||||
|
||||
const appRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const readSource = (relativePath) =>
|
||||
readFileSync(resolve(appRoot, relativePath), "utf8");
|
||||
|
||||
const homeSource = readSource("src/pages/index.vue");
|
||||
const workSource = readSource("src/pages/work/index.vue");
|
||||
const bannerSource = readSource("src/components/business/TestBatchBanner.vue");
|
||||
const modeSwitchSource = readSource(
|
||||
"src/components/business/TestBatchModeSwitch.vue",
|
||||
);
|
||||
|
||||
test("首页使用受约束的运营布局并保护横向空间", () => {
|
||||
assert.match(homeSource, /class="dashboard-page"/);
|
||||
assert.match(homeSource, /class="dashboard-scroll"/);
|
||||
assert.match(homeSource, /class="dashboard-content"/);
|
||||
assert.match(homeSource, /class="dashboard-hero"/);
|
||||
assert.match(homeSource, /class="dashboard-metric-grid"/);
|
||||
assert.match(homeSource, /class="exception-list"/);
|
||||
assert.match(homeSource, /class="exception-item"/);
|
||||
assert.match(homeSource, /overflow-x:\s*hidden/);
|
||||
assert.match(homeSource, /overflow-wrap:\s*anywhere/);
|
||||
});
|
||||
|
||||
test("工作台入口在窄屏下保持单列和可换行", () => {
|
||||
assert.match(workSource, /class="work-page"/);
|
||||
assert.match(workSource, /class="work-scroll"/);
|
||||
assert.match(workSource, /class="work-content"/);
|
||||
assert.match(workSource, /class="work-entry-list"/);
|
||||
assert.match(workSource, /class="work-entry"/);
|
||||
assert.match(workSource, /class="work-entry-copy"/);
|
||||
assert.match(workSource, /overflow-x:\s*hidden/);
|
||||
assert.match(workSource, /overflow-wrap:\s*anywhere/);
|
||||
});
|
||||
|
||||
test("测试批次提示和切换区不会撑开页面", () => {
|
||||
assert.match(bannerSource, /class="test-batch-banner"/);
|
||||
assert.match(bannerSource, /overflow-wrap:\s*anywhere/);
|
||||
assert.match(modeSwitchSource, /class="test-batch-switch"/);
|
||||
assert.match(modeSwitchSource, /class="test-batch-picker"/);
|
||||
assert.match(modeSwitchSource, /overflow-wrap:\s*anywhere/);
|
||||
});
|
||||
Reference in New Issue
Block a user