完善客服工单详情空状态与关联展示

This commit is contained in:
czl231
2026-08-17 19:48:51 +08:00
parent dadf4dfe0f
commit 877b184de1
6 changed files with 104 additions and 1 deletions

View File

@@ -23,6 +23,7 @@ const display = read('src/api/resource-display.ts');
const detailContract = read('src/api/resource-detail-contract.ts');
const detailPage = read('src/views/resource/ResourceDetailContent.vue');
const listPage = read('src/views/shared/CrudListPage.vue');
const listFieldDisplay = read('src/views/shared/resource-list-field-display.ts');
const treePage = read('src/views/shared/TreePage.vue');
const identityText = read('src/components/IdentityText.vue');
@@ -363,6 +364,13 @@ for (const ticketContract of [
"unknownValueLabel: '未知工单分类'",
"{ label: '普通', value: 'normal' }",
"unknownValueLabel: '未知优先级'",
"emptyText: '尚未分配配送点'",
"emptyText: '尚未分配处理人员'",
"staffRelation: { roles: ['installer', 'delivery', 'operations'] }",
"emptyText: '尚未关联服务气站'",
"emptyText: '尚未开始处理'",
"emptyText: '尚未完成'",
"emptyText: '尚未提交处理结果'",
]) {
assertIncludes(
resources,
@@ -370,6 +378,11 @@ for (const ticketContract of [
`客服工单缺少用户关系或中文枚举契约:${ticketContract}`,
);
}
assertIncludes(
listFieldDisplay,
'!field.listHidden',
'仅用于详情的辅助字段不得扩张标准资源列表',
);
assertIncludes(
detailPage,
'!hasResourceFieldLabel(props.definition, actualKey)',

View File

@@ -157,6 +157,19 @@ const pageRules: Record<string, ResourcePageRule> = {
editKeys: ['content_type', 'title', 'body', 'version_no', 'publish_status'],
},
cs_ticket: {
createHiddenKeys: [
'delivery_basic_identity',
'staff_account_identity',
'gas_basic_identity',
'operator_identity',
'description',
'request_no',
'address',
'appointment_at',
'started_at',
'completed_at',
'result',
],
editKeys: ['user_account_identity', 'ticket_no', 'category', 'priority'],
},
platform_account: {

View File

@@ -86,6 +86,8 @@ export type ResourceField = {
listDetailLink?: boolean;
/** 列表以可读展示字段为主文案,同时保留原关系唯一标识复制入口。 */
listDisplayIdentityCopy?: boolean;
/** 仅用于详情或表单的辅助字段,不进入标准资源列表。 */
listHidden?: boolean;
options?: Array<{ label: string; value: string | number }>;
defaultValue?: string | number | boolean;
readonlyOnCreate?: boolean;
@@ -186,6 +188,7 @@ const fieldLabels: Record<string, string> = {
repair_type: '检修类型',
started_at: '开始时间',
completed_at: '完成时间',
appointment_at: '预约时间',
result: '检修结果',
target_product_status: '目标产品状态',
content: '内容',
@@ -922,6 +925,27 @@ export const resources: ResourceUiDefinition[] = [
{ label: '高', value: 'high' },
{ label: '紧急', value: 'urgent' },
], unknownValueLabel: '未知优先级' }),
relation('delivery_basic_identity', '/delivery_basic', false, {
label: '配送点', listHidden: true, displayRelationLabel: true,
showIdentityCopy: true, emptyText: '尚未分配配送点',
}),
relation('staff_account_identity', '/staff_account', false, {
label: '处理人员', listHidden: true, displayRelationLabel: true,
showIdentityCopy: true, emptyText: '尚未分配处理人员',
staffRelation: { roles: ['installer', 'delivery', 'operations'] },
}),
relation('gas_basic_identity', '/gas_basic', false, {
label: '服务气站', listHidden: true, displayRelationLabel: true,
showIdentityCopy: true, emptyText: '尚未关联服务气站',
}),
f('operator_identity', { label: '最近操作人标识', listHidden: true, listCopyable: true, emptyText: '暂无操作记录' }),
f('description', { label: '问题描述', type: 'textarea', listHidden: true, emptyText: '未填写问题描述' }),
f('request_no', { label: '请求流水号', listHidden: true, listCopyable: true, emptyText: '未记录请求流水号' }),
f('address', { label: '上门地址', type: 'textarea', listHidden: true, emptyText: '未填写上门地址' }),
f('appointment_at', { label: '预约时间', type: 'datetime', listHidden: true, emptyText: '未预约' }),
f('started_at', { label: '开始时间', type: 'datetime', listHidden: true, emptyText: '尚未开始处理' }),
f('completed_at', { label: '完成时间', type: 'datetime', listHidden: true, emptyText: '尚未完成' }),
f('result', { label: '处理结果', type: 'textarea', listHidden: true, emptyText: '尚未提交处理结果' }),
]),
define('platform_account', '平台账户', 'writable', [f('username', { required: true }), f('password', { required: true }), f('display_name'), f('avatar'), f('platform_role_code', { required: true, unknownValueLabel: '未知角色' }), f('phone')]),
define('platform_role', '平台角色', 'writable', [f('role_code', { required: true }), f('name', { required: true }), f('location_scope', { required: true, type: 'select', options: resourceSearchEnumOptions('platform_role', 'location_scope') })], 'list', [

View File

@@ -77,7 +77,12 @@ export function resourceListDisplayFields(
...definition.fields.filter((field) => !priority.includes(field.key)),
];
return ordered
.filter((field) => field.key !== 'identity' && field.type !== 'password')
.filter(
(field) =>
field.key !== 'identity' &&
field.type !== 'password' &&
!field.listHidden,
)
.filter(
(field) =>
!(