补全工单流转记录中文事件映射
- 补齐内部寄售、电子凭证核销、自动发布等 30+ 事件文案 - 新增扫描测试:后端写入的 eventType 必须在前端有中文映射 - 覆盖生产库历史事件类型,避免工单详情露英文 key
This commit is contained in:
@@ -61,6 +61,42 @@ function formatFenAmount(value: number) {
|
||||
return `${(value / 100).toFixed(2)} 元`
|
||||
}
|
||||
|
||||
/**
|
||||
* 电子凭证核销计划事件:发布 / 指派 / 寄卖履约三条链路共用一套 payload。
|
||||
* status=queued 已安排、failed 安排失败、skipped 无需核销或跳过。
|
||||
*/
|
||||
function formatVoucherScheduleEvent(event: WorkOrderEvent, actionLabel: string): EventNodeStyle {
|
||||
const status = readPayload(event, 'status')
|
||||
const errorMessage = readPayload(event, 'errorMessage')
|
||||
const dueAt = readPayload(event, 'dueAt')
|
||||
const voucherCount = readPayloadAmount(event, 'voucherCount')
|
||||
|
||||
if (status === 'queued') {
|
||||
const details = [
|
||||
dueAt ? `计划核销时间:${dayjs(dueAt).format('MM-DD HH:mm')}` : '',
|
||||
voucherCount > 0 ? `待核销 ${voucherCount} 张` : '',
|
||||
].filter(Boolean)
|
||||
return {
|
||||
title: `${actionLabel}时已安排电子凭证自动核销`,
|
||||
description: details.length > 0 ? details.join(';') : undefined,
|
||||
color: 'geekblue',
|
||||
}
|
||||
}
|
||||
if (status === 'failed') {
|
||||
return {
|
||||
title: `${actionLabel}时电子凭证自动核销安排失败`,
|
||||
description: errorMessage || undefined,
|
||||
color: 'orange',
|
||||
}
|
||||
}
|
||||
return {
|
||||
title: `${actionLabel}时电子凭证核销已跳过`,
|
||||
description:
|
||||
voucherCount > 0 ? `未核销 ${voucherCount} 张` : '该订单没有需要自动核销的电子凭证',
|
||||
color: 'default',
|
||||
}
|
||||
}
|
||||
|
||||
/** 事件涉及的打手名(管理端接口会附带打手摘要;打手端退回 #id) */
|
||||
function resolveEventWorkerLabel(event: WorkOrderEvent): string {
|
||||
if (event.worker?.displayName) return event.worker.displayName
|
||||
@@ -203,6 +239,91 @@ export function formatWorkOrderEvent(event: WorkOrderEvent): EventNodeStyle {
|
||||
color: 'orange',
|
||||
}
|
||||
|
||||
// —— 内部寄售 / 寄卖履约节点 ——
|
||||
case 'consignment_waiting_friend_add':
|
||||
return {
|
||||
title: '内部寄售已占库,等待客服加好友',
|
||||
description: '订单停在「待加好友」,客服确认后再开始赠送冷却',
|
||||
color: 'gold',
|
||||
}
|
||||
case 'consignment_gift_countdown_started':
|
||||
case 'consignment_share_gift_countdown_started': {
|
||||
const cooldownHours = readPayloadAmount(event, 'cooldownHours')
|
||||
const cooldownMinutes = readPayloadAmount(event, 'cooldownMinutes')
|
||||
const duration =
|
||||
cooldownMinutes > 0
|
||||
? `${cooldownMinutes} 分钟`
|
||||
: cooldownHours > 0
|
||||
? `${cooldownHours} 小时`
|
||||
: ''
|
||||
return {
|
||||
title:
|
||||
type === 'consignment_share_gift_countdown_started'
|
||||
? '拼单寄售已确认加好友,赠送冷却开始'
|
||||
: '内部寄售已确认加好友,赠送冷却开始',
|
||||
description: duration ? `冷却 ${duration},结束后使用库存账号赠送并验收` : undefined,
|
||||
color: 'gold',
|
||||
}
|
||||
}
|
||||
case 'consignment_manual_matched':
|
||||
case 'consignment_auto_matched': {
|
||||
const inventoryNo = readPayload(event, 'inventoryNo')
|
||||
return {
|
||||
title: `${type === 'consignment_manual_matched' ? '手动' : '自动'}匹配寄卖库存${
|
||||
inventoryNo ? `(${inventoryNo})` : ''
|
||||
}`,
|
||||
description: '按内部现货履约,不在工单上指派接单打手',
|
||||
color: 'green',
|
||||
}
|
||||
}
|
||||
case 'consignment_sharing_matched':
|
||||
case 'consignment_manual_sharing_matched': {
|
||||
const inventoryNo = readPayload(event, 'inventoryNo')
|
||||
return {
|
||||
title: `拼单寄卖库存匹配${inventoryNo ? `(${inventoryNo})` : ''}`,
|
||||
description:
|
||||
type === 'consignment_manual_sharing_matched'
|
||||
? '手动匹配拼单寄卖库存'
|
||||
: '自动匹配拼单寄卖库存',
|
||||
color: 'green',
|
||||
}
|
||||
}
|
||||
case 'consignment_fulfilled': {
|
||||
const inventoryNo = readPayload(event, 'inventoryNo')
|
||||
return {
|
||||
title: '寄卖库存已履约,订单停在待加好友',
|
||||
description: inventoryNo ? `库存号:${inventoryNo}` : undefined,
|
||||
color: 'green',
|
||||
}
|
||||
}
|
||||
case 'consignment_worker_assigned': {
|
||||
const workerLabel = resolveEventWorkerLabel(event) || readPayload(event, 'workerName')
|
||||
const inventoryNo = readPayload(event, 'inventoryNo')
|
||||
return {
|
||||
title: `寄卖库存已指派履约打手${workerLabel ? `(${workerLabel})` : ''}`,
|
||||
description: inventoryNo ? `库存号:${inventoryNo}` : undefined,
|
||||
color: 'green',
|
||||
}
|
||||
}
|
||||
case 'consignment_revoked':
|
||||
return {
|
||||
title: note ? `撤销寄卖履约(${note})` : '撤销寄卖履约',
|
||||
color: 'red',
|
||||
}
|
||||
case 'consignment_internal_matching_entered':
|
||||
case 'consignment_internal_matching_reentered':
|
||||
case 'consignment_internal_matching_expired':
|
||||
case 'consignment_internal_matching_migrated':
|
||||
return {
|
||||
title:
|
||||
type === 'consignment_internal_matching_expired'
|
||||
? '内部匹配等待超时(历史流程)'
|
||||
: type === 'consignment_internal_matching_migrated'
|
||||
? '内部匹配等待记录已迁移(历史流程)'
|
||||
: '进入内部匹配等待(历史流程)',
|
||||
color: type === 'consignment_internal_matching_expired' ? 'orange' : 'default',
|
||||
}
|
||||
|
||||
// —— 验收节点 ——
|
||||
case 'acceptance_submitted': {
|
||||
const imageCount = readPayload(event, 'imageCount')
|
||||
@@ -232,6 +353,14 @@ export function formatWorkOrderEvent(event: WorkOrderEvent): EventNodeStyle {
|
||||
description: readPayload(event, 'evidenceDueAt') ? '可在 24 小时内补充验收图片' : undefined,
|
||||
color: 'purple',
|
||||
}
|
||||
case 'acceptance_reminded':
|
||||
return {
|
||||
title: '打手提醒客服尽快验收',
|
||||
description: readPayload(event, 'reminderCount')
|
||||
? `已提醒 ${readPayload(event, 'reminderCount')} 次`
|
||||
: undefined,
|
||||
color: 'orange',
|
||||
}
|
||||
case 'acceptance_evidence_supplemented': {
|
||||
const addedImageCount = readPayload(event, 'addedImageCount')
|
||||
return {
|
||||
@@ -329,6 +458,25 @@ export function formatWorkOrderEvent(event: WorkOrderEvent): EventNodeStyle {
|
||||
}
|
||||
|
||||
// —— 其他 ——
|
||||
case 'auto_publish_succeeded':
|
||||
return { title: '订单自动发布成功', color: 'geekblue' }
|
||||
case 'admin_note_updated':
|
||||
return {
|
||||
title: note ? `更新了后台备注:${note}` : '更新了后台备注',
|
||||
color: 'default',
|
||||
}
|
||||
case 'customer_refund_cancelled':
|
||||
return {
|
||||
title: '客户退款已取消',
|
||||
description: note || undefined,
|
||||
color: 'default',
|
||||
}
|
||||
case 'status_repaired':
|
||||
return { title: '系统修复了订单状态', color: 'orange' }
|
||||
case 'problem_cancel_restored':
|
||||
return { title: '问题单取消后已恢复', color: 'orange' }
|
||||
case 'cancelled_by_channel_switch':
|
||||
return { title: '因切换履约渠道取消订单', color: 'red' }
|
||||
case 'payment_amount_updated': {
|
||||
const previousAmountFen = readPayloadAmount(event, 'previousAmountFen')
|
||||
const amountFen = readPayloadAmount(event, 'amountFen')
|
||||
@@ -509,6 +657,30 @@ export function formatWorkOrderEvent(event: WorkOrderEvent): EventNodeStyle {
|
||||
return { title: '扣减了待解冻押金', color: 'default' }
|
||||
case 'voucher_backfilled':
|
||||
return { title: '回填了电子凭证信息', color: 'default' }
|
||||
case 'douyin_voucher_backfilled':
|
||||
return { title: '回填了抖音电子凭证信息', color: 'default' }
|
||||
case 'publish_voucher_consumed': {
|
||||
const consumedCount = readPayloadAmount(event, 'consumedCount')
|
||||
const voucherCodes = event.payload?.voucherCodes
|
||||
const count = Array.isArray(voucherCodes) ? voucherCodes.length : consumedCount
|
||||
return {
|
||||
title: '订单发布时已核销电子凭证',
|
||||
description: count > 0 ? `已核销 ${count} 张` : undefined,
|
||||
color: 'green',
|
||||
}
|
||||
}
|
||||
case 'publish_voucher_consume_scheduled':
|
||||
case 'publish_voucher_consume_schedule_skipped':
|
||||
case 'publish_voucher_consume_schedule_failed':
|
||||
return formatVoucherScheduleEvent(event, '订单发布')
|
||||
case 'assign_voucher_consume_scheduled':
|
||||
case 'assign_voucher_consume_schedule_skipped':
|
||||
case 'assign_voucher_consume_schedule_failed':
|
||||
return formatVoucherScheduleEvent(event, '指派')
|
||||
case 'consignment_fulfill_voucher_consume_scheduled':
|
||||
case 'consignment_fulfill_voucher_consume_schedule_skipped':
|
||||
case 'consignment_fulfill_voucher_consume_schedule_failed':
|
||||
return formatVoucherScheduleEvent(event, '寄卖履约')
|
||||
case 'assign_voucher_consume_failed':
|
||||
return { title: '电子凭证核销失败,本次操作未生效', color: 'red' }
|
||||
case 'publish_voucher_consume_failed':
|
||||
|
||||
Reference in New Issue
Block a user