完善气站客服工单详情展示
This commit is contained in:
@@ -17,6 +17,10 @@ const fieldFormSource = readFileSync(
|
||||
resolve(root, 'src/views/resource/ResourceFieldForm.vue'),
|
||||
'utf8',
|
||||
);
|
||||
const relationLoaderSource = readFileSync(
|
||||
resolve(root, 'src/views/resource/load-resource-record-relations.ts'),
|
||||
'utf8',
|
||||
);
|
||||
const contract = JSON.parse(
|
||||
readFileSync(resolve(root, 'src/contracts/gas-resources.json'), 'utf8'),
|
||||
);
|
||||
@@ -89,6 +93,25 @@ for (const option of [
|
||||
]) {
|
||||
if (!source.includes(option)) throw new Error(`客服工单枚举缺失:${option}`);
|
||||
}
|
||||
for (const display of [
|
||||
"label: '配送点'",
|
||||
"emptyText: '尚未分配配送点'",
|
||||
"label: '处理人员'",
|
||||
"emptyText: '尚未分配处理人员'",
|
||||
"label: '服务气站'",
|
||||
"emptyText: '尚未关联服务气站'",
|
||||
"label: '问题描述'",
|
||||
"emptyText: '未填写问题描述'",
|
||||
"label: '预约时间'",
|
||||
"emptyText: '未预约'",
|
||||
"label: '处理结果'",
|
||||
"emptyText: '尚未提交处理结果'",
|
||||
]) {
|
||||
if (!source.includes(display))
|
||||
throw new Error(`客服工单详情展示契约缺失:${display}`);
|
||||
}
|
||||
if (!relationLoaderSource.includes('relationDisplayName(field, options.record)'))
|
||||
throw new Error('详情关系已有可读名称时不得重复请求关联资源');
|
||||
|
||||
const forbidden = [
|
||||
'/platform/platform_', '/gas/gas_', '/delivery/delivery_', '/staff/',
|
||||
|
||||
@@ -85,6 +85,7 @@ const collectionFieldAliases: Record<string, Record<string, string>> = {
|
||||
attempt_no: '配送尝试次数',
|
||||
staff_account_display_name: '配送人员',
|
||||
staff_account_identity: '配送人员唯一标识',
|
||||
appointment_at: '预约时间',
|
||||
started_at: '开始时间',
|
||||
completed_at: '完成时间',
|
||||
},
|
||||
|
||||
@@ -162,6 +162,7 @@ const fieldLabels: Record<string, string> = {
|
||||
reconciliation_status: '对账状态',
|
||||
repair_no: '检修单号',
|
||||
repair_type: '检修类型',
|
||||
appointment_at: '预约时间',
|
||||
started_at: '开始时间',
|
||||
completed_at: '完成时间',
|
||||
result: '检修结果',
|
||||
@@ -309,7 +310,7 @@ const money = new Set([
|
||||
const booleans = new Set(['is_default', 'is_cover', 'selected', 'withdrawable']);
|
||||
const dates = new Set(['bill_date']);
|
||||
const datetimes = new Set([
|
||||
'expired_at', 'produced_at', 'enabled_at', 'started_at', 'completed_at',
|
||||
'expired_at', 'produced_at', 'enabled_at', 'appointment_at', 'started_at', 'completed_at',
|
||||
'occurred_at', 'reviewed_at', 'signed_at', 'effective_at', 'unbound_at',
|
||||
'assigned_at', 'confirmed_at', 'paid_at', 'period_start', 'period_end',
|
||||
]);
|
||||
@@ -429,6 +430,91 @@ const ticketPriorityField = f('priority', {
|
||||
],
|
||||
});
|
||||
|
||||
/** 客服工单详情字段完整沿用平台口径,辅助处理字段只在详情页展示。 */
|
||||
const ticketFields = [
|
||||
relation('user_account_identity', '/user_account', true, {
|
||||
label: '用户',
|
||||
listLabel: '用户',
|
||||
listRelationNameOnly: true,
|
||||
listDisplayIdentityCopy: true,
|
||||
displayRelationLabel: true,
|
||||
showIdentityCopy: true,
|
||||
}),
|
||||
f('ticket_no', { required: true }),
|
||||
ticketCategoryField,
|
||||
ticketPriorityField,
|
||||
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: '尚未提交处理结果',
|
||||
}),
|
||||
];
|
||||
|
||||
/** 提现渠道保留未来选项,但当前仅开放银行卡提现。 */
|
||||
const withdrawalChannelField = f('channel', {
|
||||
required: true,
|
||||
@@ -538,7 +624,7 @@ const platformResources: ResourceUiDefinition[] = [
|
||||
define('fin_settlement', '财务结算', 'writable', [f('settlement_no', { required: true }), f('subject_type', { required: true }), f('subject_identity', { required: true }), f('period_start', { required: true }), f('period_end', { required: true })]),
|
||||
define('fin_reconciliation', '财务对账', 'readonly', []),
|
||||
define('cms_content', '内容', 'writable', [f('content_type', { required: true }), f('title', { required: true }), f('body', { required: true }), f('version_no'), f('publish_status')]),
|
||||
define('cs_ticket', '客服工单', 'writable', [relation('user_account_identity', '/user_account', true), f('ticket_no', { required: true }), ticketCategoryField, ticketPriorityField]),
|
||||
define('cs_ticket', '客服工单', 'writable', ticketFields),
|
||||
define('platform_account', '平台账户', 'writable', [f('username', { required: true }), f('password', { required: true }), f('display_name'), f('avatar'), f('platform_role_code', { required: true }), f('phone')]),
|
||||
define('platform_role', '平台角色', 'writable', [f('role_code', { required: true }), f('name', { required: true }), f('location_scope', { required: true, type: 'select', options: [{ label: '脱敏坐标', value: 'standard' }, { label: '精确坐标', value: 'precise' }] })], 'list', [
|
||||
{ name: '分配菜单', resource: '/platform_role/:identity/menu', method: 'PUT', fields: [f('menu_identities', { type: 'identity-list', relation: '/platform_menu' })] },
|
||||
@@ -585,7 +671,7 @@ const gasOverrides: ResourceUiDefinition[] = [
|
||||
define('wallet_apply_cash', '提现申请', 'append_only', [relation('wallet_bank_identity', '/wallet_bank'), f('request_no', { required: true }), f('amount', { required: true }), withdrawalChannelField, f('remark')]),
|
||||
define('fin_settlement', '财务结算', 'readonly', []),
|
||||
define('fin_reconciliation', '财务对账', 'readonly', []),
|
||||
define('cs_ticket', '客服工单', 'writable', [relation('user_account_identity', '/user_account', true), f('ticket_no', { required: true }), ticketCategoryField, ticketPriorityField]),
|
||||
define('cs_ticket', '客服工单', 'writable', ticketFields),
|
||||
];
|
||||
|
||||
const gasResourceNames = new Set(gasOverrides.map((item) => item.name));
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
*/
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import type { Ref } from 'vue';
|
||||
import { platformApi, type PlatformRole } from '@/api/platform';
|
||||
import type { ResourceField, ResourceUiDefinition } from '@/api/resources';
|
||||
import { type PlatformRole, platformApi } from '@/api/platform';
|
||||
import type { ResourceRow } from '@/api/resource-page-rules';
|
||||
import type { ResourceField, ResourceUiDefinition } from '@/api/resources';
|
||||
import { relationDisplayName } from '../shared/resource-list-field-display';
|
||||
import type { ResourceRelations } from './use-resource-relations';
|
||||
|
||||
type LoaderOptions = {
|
||||
@@ -26,7 +27,15 @@ type LoaderOptions = {
|
||||
/** 加载当前页面实际使用的关系和动态平台角色。 */
|
||||
export async function loadResourceRecordRelations(options: LoaderOptions) {
|
||||
if (options.detailMode) {
|
||||
await options.relations.preload(options.definition.fields);
|
||||
// 详情只加载实际存在且服务端未提供可读名称的关系,避免为空字段发起无意义请求。
|
||||
const unresolvedFields = options.definition.fields.filter((field) => {
|
||||
const value = options.record[field.key];
|
||||
const hasValue = Array.isArray(value)
|
||||
? value.some(Boolean)
|
||||
: String(value ?? '').trim() !== '';
|
||||
return hasValue && !relationDisplayName(field, options.record);
|
||||
});
|
||||
await options.relations.preload(unresolvedFields);
|
||||
await options.relations.ensureValues(
|
||||
options.definition.fields,
|
||||
options.record,
|
||||
|
||||
Reference in New Issue
Block a user