优化运行轨迹关联名称展示
This commit is contained in:
@@ -53,6 +53,30 @@ if (missingLabels.length) {
|
||||
throw new Error(`资源字段缺少中文名称:${missingLabels.join('、')}`);
|
||||
}
|
||||
|
||||
// 运行轨迹必须复用统一关联名称组件,避免再次把截断唯一标识当成业务名称。
|
||||
const trackDefinition = resources.match(
|
||||
/define\('gasorder_track',[\s\S]*?\n\s*\]\),/,
|
||||
)?.[0];
|
||||
if (!trackDefinition) throw new Error('无法读取运行轨迹资源定义');
|
||||
for (const [key, label] of [
|
||||
['gasorder_basic_identity', '配送订单'],
|
||||
['staff_account_identity', '配送人员'],
|
||||
]) {
|
||||
const field = trackDefinition.match(
|
||||
new RegExp(`relation\\('${key}'[\\s\\S]*?\\}\\)`),
|
||||
)?.[0];
|
||||
if (
|
||||
!field ||
|
||||
!field.includes(`listLabel: '${label}'`) ||
|
||||
!field.includes('listRelationNameOnly: true') ||
|
||||
!field.includes('showIdentityCopy: true') ||
|
||||
(key === 'staff_account_identity' &&
|
||||
!field.includes("staffRelation: { roles: ['delivery'] }"))
|
||||
) {
|
||||
throw new Error(`运行轨迹的${label}必须以业务名称展示并保留唯一标识复制入口`);
|
||||
}
|
||||
}
|
||||
|
||||
if (/title="ID"|data-index="id"/.test(listPage)) {
|
||||
throw new Error('标准资源列表不得把数据库ID作为业务列展示');
|
||||
}
|
||||
@@ -79,7 +103,7 @@ assertIncludes(
|
||||
);
|
||||
for (const collection of [
|
||||
'products', 'revisions', 'items', 'assignments', 'statuses',
|
||||
'tracks', 'confirmations', 'payments',
|
||||
'tracks', 'confirmations', 'payments', 'points',
|
||||
]) {
|
||||
assertIncludes(
|
||||
detailContract,
|
||||
@@ -87,5 +111,10 @@ for (const collection of [
|
||||
`缺少关联记录固定列契约:${collection}`,
|
||||
);
|
||||
}
|
||||
assertIncludes(
|
||||
display,
|
||||
"if (detail.track && typeof detail.track === 'object')",
|
||||
'运行轨迹详情必须解包 track 聚合主记录',
|
||||
);
|
||||
|
||||
process.stdout.write('平台48类资源中文展示契约检查通过\n');
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* 功能:验证工作人员关联字段过滤、资质来源校验和路由上下文传递契约。
|
||||
* 版本:v1.2.0
|
||||
* 版本:v1.3.0
|
||||
*/
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
@@ -105,8 +105,17 @@ const resourcesSource = await readFile(
|
||||
assert.match(resourcesSource, /organizationScoped: true/);
|
||||
assert.equal(
|
||||
(resourcesSource.match(/staffRelation:/g) ?? []).length,
|
||||
3,
|
||||
'三个工作人员关联场景都必须显式声明策略',
|
||||
4,
|
||||
'四个工作人员关联场景都必须显式声明策略',
|
||||
);
|
||||
const trackPolicy = resourcesSource.match(
|
||||
/define\('gasorder_track',[\s\S]*?staffRelation: \{ roles: \['delivery'\] \}[\s\S]*?\n\s*\]\),/,
|
||||
)?.[0];
|
||||
assert.ok(trackPolicy, '运行轨迹必须显式限定配送人员岗位');
|
||||
assert.doesNotMatch(
|
||||
trackPolicy,
|
||||
/enabledOnly|workStatus|validCredentialOnly/,
|
||||
'历史运行轨迹不得按人员当前启用、在岗或资质状态过滤',
|
||||
);
|
||||
|
||||
const relationsSource = await readFile(
|
||||
|
||||
@@ -100,6 +100,24 @@ const contracts: Record<string, ResourceDetailContract> = {
|
||||
},
|
||||
},
|
||||
},
|
||||
gasorder_track: {
|
||||
leadingKeys: [
|
||||
'gasorder_basic_identity', 'staff_account_identity', 'attempt_no',
|
||||
'started_at', 'completed_at', 'identity', 'status',
|
||||
],
|
||||
relationResources: {
|
||||
gasorder_basic_identity: '/gasorder_basic',
|
||||
staff_account_identity: '/staff_account',
|
||||
},
|
||||
collections: {
|
||||
points: {
|
||||
columns: [
|
||||
'occurred_at', 'received_at', 'longitude', 'latitude', 'accuracy',
|
||||
'speed', 'direction', 'source', 'request_no',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
payment_order: {
|
||||
leadingKeys: [
|
||||
'payment_no', 'payment_status', 'request_no', 'business_type',
|
||||
|
||||
@@ -39,6 +39,7 @@ const aliases: Record<string, string> = {
|
||||
creator_display_name: '创建方',
|
||||
contract_display_name: '配送合同',
|
||||
assigner_name: '分配人',
|
||||
points: '轨迹点',
|
||||
};
|
||||
|
||||
/** 聚合子表字段可能与全局同名字段具有不同业务语义,按父资源和集合名称覆盖。 */
|
||||
@@ -85,6 +86,17 @@ const collectionFieldAliases: Record<string, Record<string, string>> = {
|
||||
started_at: '开始时间',
|
||||
completed_at: '完成时间',
|
||||
},
|
||||
'gasorder_track.points': {
|
||||
request_no: '上报流水号',
|
||||
longitude: '经度',
|
||||
latitude: '纬度',
|
||||
occurred_at: '定位时间',
|
||||
received_at: '接收时间',
|
||||
source: '定位来源',
|
||||
accuracy: '定位精度',
|
||||
speed: '行进速度',
|
||||
direction: '行进方向',
|
||||
},
|
||||
'gasorder_basic.confirmations': {
|
||||
confirmed_at: '确认时间',
|
||||
confirm_type: '确认方式',
|
||||
@@ -160,6 +172,8 @@ export function primaryRecord(detail: ResourceRow): ResourceRow {
|
||||
return detail.order as ResourceRow;
|
||||
if (detail.contract && typeof detail.contract === 'object')
|
||||
return detail.contract as ResourceRow;
|
||||
if (detail.track && typeof detail.track === 'object')
|
||||
return detail.track as ResourceRow;
|
||||
return detail;
|
||||
}
|
||||
|
||||
|
||||
@@ -656,8 +656,22 @@ export const resources: ResourceUiDefinition[] = [
|
||||
f('from_status'), f('to_status'), f('operator_name'), f('operator_identity'), f('occurred_at'), f('reason'),
|
||||
]),
|
||||
define('gasorder_track', '运行轨迹', 'readonly', [
|
||||
relation('gasorder_basic_identity', '/gasorder_basic'),
|
||||
relation('staff_account_identity', '/staff_account'),
|
||||
relation('gasorder_basic_identity', '/gasorder_basic', false, {
|
||||
label: '配送订单',
|
||||
listLabel: '配送订单',
|
||||
listRelationNameOnly: true,
|
||||
displayRelationLabel: true,
|
||||
showIdentityCopy: true,
|
||||
}),
|
||||
relation('staff_account_identity', '/staff_account', false, {
|
||||
label: '配送人员',
|
||||
listLabel: '配送人员',
|
||||
listRelationNameOnly: true,
|
||||
displayRelationLabel: true,
|
||||
showIdentityCopy: true,
|
||||
// 历史轨迹只限定岗位,不按当前启用、在岗或资质状态过滤。
|
||||
staffRelation: { roles: ['delivery'] },
|
||||
}),
|
||||
f('attempt_no'), f('started_at'), f('completed_at'),
|
||||
]),
|
||||
define('gasorder_track_point', '轨迹点', 'readonly', [
|
||||
|
||||
Reference in New Issue
Block a user