77 lines
4.4 KiB
JavaScript
77 lines
4.4 KiB
JavaScript
/**
|
||
* 功能描述:校验配送点资源的独立详情、新建、编辑页面与后端契约保持一致。
|
||
* 版本:v1.0.0。
|
||
*/
|
||
import fs from 'node:fs';
|
||
import path from 'node:path';
|
||
import { fileURLToPath } from 'node:url';
|
||
|
||
const projectRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
||
const contract = JSON.parse(fs.readFileSync(
|
||
path.join(projectRoot, 'src/contracts/delivery-resources.json'),
|
||
'utf8',
|
||
));
|
||
const read = (relativePath) => fs.readFileSync(path.join(projectRoot, relativePath), 'utf8');
|
||
const routeKeys = new Set(contract.routes.map((route) => `${route.method} ${route.path}`));
|
||
const listResources = contract.resources.filter(
|
||
(resource) => resource.pageKind === 'list' && resource.name !== 'delivery_profile',
|
||
);
|
||
const creatable = new Set([
|
||
'staff_account', 'staff_credential', 'user_account', 'user_address',
|
||
'gasorder_contract', 'gasorder_contract_product', 'gasorder_basic',
|
||
'wallet_recharge', 'wallet_apply_cash',
|
||
]);
|
||
const editable = new Set([
|
||
'staff_account', 'staff_credential', 'user_account', 'user_address', 'gasorder_contract',
|
||
]);
|
||
|
||
/** 在条件不成立时中止检查,并给出可直接定位的原因。 */
|
||
function assert(condition, message) {
|
||
if (!condition) throw new Error(message);
|
||
}
|
||
|
||
for (const resource of listResources) {
|
||
assert(
|
||
routeKeys.has(`GET ${resource.path}/:identity`),
|
||
`${resource.name} 缺少详情接口`,
|
||
);
|
||
if (creatable.has(resource.name)) {
|
||
assert(routeKeys.has(`POST ${resource.path}`), `${resource.name} 缺少新建接口`);
|
||
}
|
||
if (editable.has(resource.name)) {
|
||
assert(routeKeys.has(`PUT ${resource.path}/:identity`), `${resource.name} 缺少编辑接口`);
|
||
}
|
||
}
|
||
|
||
assert(listResources.length === 17, `详情页面资源应为 17 个,当前为 ${listResources.length}`);
|
||
assert(creatable.size === 9, `新建页面资源应为 9 个,当前为 ${creatable.size}`);
|
||
assert(editable.size === 5, `编辑页面资源应为 5 个,当前为 ${editable.size}`);
|
||
|
||
const builder = read('src/router/routes/modules/resource-route-builder.ts');
|
||
const platform = read('src/router/routes/modules/platform.ts');
|
||
const resourcePage = read('src/views/shared/ResourcePage.vue');
|
||
const definitions = read('src/api/resources.ts');
|
||
assert(builder.includes("recordRoute('detail', ':identity'"), '路由生成器未创建详情页');
|
||
assert(builder.includes("recordRoute('create', 'new'"), '路由生成器未创建新建页');
|
||
assert(builder.includes("recordRoute('edit', ':identity/edit'"), '路由生成器未创建编辑页');
|
||
assert(platform.includes("createChild('add'"), '工作人员正式新建路由必须保留 /staff/add');
|
||
assert(platform.includes("createChild('create'"), '配送订单正式新建路由必须保留 /gasorder/create');
|
||
assert(resourcePage.includes('ResourceListPage'), '标准资源列表尚未切换到独立页面导航');
|
||
assert(!resourcePage.includes('CrudListPage'), '活动列表仍依赖抽屉式 CrudListPage');
|
||
assert(definitions.includes("define('payment_order'"), '支付资源必须使用后端名称 payment_order');
|
||
assert(definitions.includes("define('payment_refund'"), '退款资源必须使用后端名称 payment_refund');
|
||
assert(routeKeys.has('GET /staff_account/:identity/avatar'), '配送人员缺少受保护头像读取接口');
|
||
assert(routeKeys.has('GET /user_account/:identity/avatar'), '用户账户缺少受保护头像读取接口');
|
||
const recordPage = read('src/views/resource/ResourceRecordPage.vue');
|
||
assert(recordPage.includes('ResourceAccountSummary'), '账户资源页尚未接入 5173 头像摘要卡片');
|
||
assert(recordPage.includes("field.key !== 'avatar'"), '头像字段仍可能显示为普通文本框');
|
||
const listPage = read('src/views/shared/ResourceListPage.vue');
|
||
assert(!listPage.includes('title="ID"'), '标准列表仍暴露数据库自增 ID');
|
||
assert(listPage.includes('ProtectedAvatarThumbnail'), '账户列表尚未接入受控头像缩略图');
|
||
assert(listPage.includes('avatarLoader.reset()'), '列表刷新未清理头像缓存和请求');
|
||
const avatarLoader = read('src/views/shared/protected-list-avatar-loader.ts');
|
||
assert(avatarLoader.includes('MAX_CONCURRENT_REQUESTS = 6'), '头像请求并发上限未与 5173 对齐');
|
||
assert(avatarLoader.includes("new Set(['staff_account', 'user_account'])"), '头像列表资源白名单不正确');
|
||
|
||
console.log(`独立资源页面契约通过:详情 ${listResources.length},新建 ${creatable.size},编辑 ${editable.size}`);
|