169 lines
6.0 KiB
JavaScript
169 lines
6.0 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
|
|
const root = path.resolve(__dirname, '..');
|
|
const failures = [];
|
|
let html = '';
|
|
|
|
try {
|
|
html = [
|
|
fs.readFileSync(path.join(root, 'prototype-src', 'modules', '03-overseas-warehouse.html'), 'utf8'),
|
|
fs.readFileSync(path.join(root, 'prototype-src', 'app.js'), 'utf8'),
|
|
].join('\n');
|
|
} catch (error) {
|
|
failures.push(`无法读取原型文件:${error.message}`);
|
|
}
|
|
|
|
const detailPages = [
|
|
{
|
|
pageId: 'fba-inbound-order-detail',
|
|
listPageId: 'fba-inbound-order',
|
|
openFunction: 'openFbaInboundOrderDetail',
|
|
backFunction: 'backToFbaInboundOrders',
|
|
renderer: 'renderFbaInboundOrder',
|
|
entryField: 'inboundNo',
|
|
title: '入库单详情',
|
|
fields: ['入库单号', '入仓码'],
|
|
},
|
|
{
|
|
pageId: 'fba-outbound-order-detail',
|
|
listPageId: 'fba-outbound-order',
|
|
openFunction: 'openFbaOutboundOrderDetail',
|
|
backFunction: 'backToFbaOutboundOrders',
|
|
renderer: 'renderFbaOutboundOrder',
|
|
entryField: 'outboundNo',
|
|
title: '出库单详情',
|
|
fields: ['出库单号', '出库类型'],
|
|
},
|
|
{
|
|
pageId: 'fba-relabel-order-detail',
|
|
listPageId: 'fba-relabel-order',
|
|
openFunction: 'openFbaRelabelOrderDetail',
|
|
backFunction: 'backToFbaRelabelOrders',
|
|
renderer: 'renderFbaRelabelOrder',
|
|
entryField: 'orderNo',
|
|
title: '换标单详情',
|
|
fields: ['换标单号', '商品信息', '预算总价', '贴标要求', '费用明细', '开箱费', '挑货费', '换标费', '换箱唛标费', '换标费总计'],
|
|
},
|
|
{
|
|
pageId: 'fba-pallet-detail',
|
|
listPageId: 'fba-pallet',
|
|
openFunction: 'openFbaPalletDetail',
|
|
backFunction: 'backToFbaPallets',
|
|
renderer: 'renderFbaPallet',
|
|
entryField: 'code',
|
|
title: '托盘详情',
|
|
fields: ['托盘编码', '关联箱数'],
|
|
},
|
|
{
|
|
pageId: 'fba-carton-detail',
|
|
listPageId: 'fba-carton',
|
|
openFunction: 'openFbaCartonDetail',
|
|
backFunction: 'backToFbaCartons',
|
|
renderer: 'renderFbaCarton',
|
|
entryField: 'cartonNo',
|
|
title: '箱号详情',
|
|
fields: ['箱号', '关联托盘'],
|
|
},
|
|
];
|
|
|
|
function escapeRegExp(value) {
|
|
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
}
|
|
|
|
function requireMatch(pattern, label, source = html) {
|
|
if (!pattern.test(source)) failures.push(`missing ${label}`);
|
|
}
|
|
|
|
function getPageSource(pageId) {
|
|
const pagePattern = new RegExp(
|
|
`<div\\b(?=[^>]*\\bclass=["'][^"']*\\bpage\\b)(?=[^>]*\\bid=["']page-${escapeRegExp(pageId)}["'])[^>]*>`,
|
|
'i',
|
|
);
|
|
const match = pagePattern.exec(html);
|
|
if (!match) return '';
|
|
|
|
const start = match.index;
|
|
const remaining = html.slice(start + match[0].length);
|
|
const nextPage = /<div\b(?=[^>]*\bclass=["'][^"']*\bpage\b)(?=[^>]*\bid=["']page-[^"']+["'])[^>]*>/i.exec(remaining);
|
|
const end = nextPage ? start + match[0].length + nextPage.index : html.length;
|
|
return html.slice(start, end);
|
|
}
|
|
|
|
function getFunctionSource(functionName) {
|
|
const declaration = new RegExp(`function\\s+${escapeRegExp(functionName)}\\s*\\(`).exec(html);
|
|
if (!declaration) return '';
|
|
|
|
const remaining = html.slice(declaration.index + declaration[0].length);
|
|
const nextFunction = /\n\s*function\s+[A-Za-z_$][\w$]*\s*\(/.exec(remaining);
|
|
const end = nextFunction
|
|
? declaration.index + declaration[0].length + nextFunction.index
|
|
: html.length;
|
|
return html.slice(declaration.index, end);
|
|
}
|
|
|
|
requireMatch(/function\s+renderFbaReadOnlyDetail\s*\(/, '共享 renderFbaReadOnlyDetail 函数');
|
|
requireMatch(/function\s+showExistingFbaList\s*\(/, '保留筛选结果的列表返回函数');
|
|
requireMatch(/['"]处理中['"]\s*:\s*['"]tag-purple['"]/, '换标单处理中状态沿用列表紫色标签');
|
|
|
|
detailPages.forEach((detail) => {
|
|
const pageSource = getPageSource(detail.pageId);
|
|
if (!pageSource) {
|
|
failures.push(`missing 页面节点 page-${detail.pageId}`);
|
|
}
|
|
requireMatch(new RegExp(escapeRegExp(detail.title)), `${detail.title}页面标题`, pageSource);
|
|
detail.fields.forEach((field) => {
|
|
requireMatch(new RegExp(escapeRegExp(field)), `${detail.title}字段文案“${field}”`);
|
|
});
|
|
|
|
const openSource = getFunctionSource(detail.openFunction);
|
|
if (!openSource) {
|
|
failures.push(`missing ${detail.openFunction} 打开函数`);
|
|
} else {
|
|
requireMatch(
|
|
/if\s*\(\s*!\s*[A-Za-z_$][\w$]*\s*\)\s*\{?[\s\S]{0,240}?showToast\s*\([\s\S]*?,\s*['"]error['"]\s*\)/,
|
|
`${detail.openFunction} 未找到记录时的 error toast`,
|
|
openSource,
|
|
);
|
|
}
|
|
|
|
requireMatch(
|
|
new RegExp(`function\\s+${escapeRegExp(detail.backFunction)}\\s*\\(`),
|
|
`${detail.backFunction} 返回函数`,
|
|
);
|
|
const backSource = getFunctionSource(detail.backFunction);
|
|
requireMatch(
|
|
/showExistingFbaList\s*\(/,
|
|
`${detail.backFunction} 返回时保留筛选结果`,
|
|
backSource,
|
|
);
|
|
|
|
const rendererSource = getFunctionSource(detail.renderer);
|
|
if (detail.pageId === 'fba-relabel-order-detail') {
|
|
requireMatch(/data-fbro-view-order/, `${detail.renderer} 列表查看数据入口`, rendererSource);
|
|
requireMatch(/openFbaRelabelOrderDetail\s*\(\s*view\.dataset\.fbroViewOrder\s*\)/, `${detail.renderer} 委托查看入口传入 ${detail.entryField}`);
|
|
} else if (detail.pageId === 'fba-carton-detail') {
|
|
requireMatch(/cartonArg\s*=\s*lmoEsc\s*\(\s*JSON\.stringify\s*\(\s*item\.cartonNo\s*\)\s*\)/, `${detail.renderer} 安全序列化 ${detail.entryField}`, rendererSource);
|
|
requireMatch(/openFbaCartonDetail\s*\(\$\{cartonArg\}\)/, `${detail.renderer} 查看入口传入 ${detail.entryField}`, rendererSource);
|
|
} else {
|
|
const entryPattern = new RegExp(
|
|
`${escapeRegExp(detail.openFunction)}\\s*\\([^)]*\\b(?:d|item|record)\\.${escapeRegExp(detail.entryField)}\\b[^)]*\\)`,
|
|
);
|
|
requireMatch(
|
|
entryPattern,
|
|
`${detail.renderer} 列表查看入口传入 ${detail.entryField}`,
|
|
rendererSource,
|
|
);
|
|
}
|
|
});
|
|
|
|
if (failures.length) {
|
|
console.error('OVERSEAS_WAREHOUSE_DETAIL_PAGES_CHECK_FAIL');
|
|
failures.forEach((failure) => console.error(`- ${failure}`));
|
|
process.exitCode = 1;
|
|
} else {
|
|
console.log('OVERSEAS_WAREHOUSE_DETAIL_PAGES_CHECK_PASS');
|
|
}
|