工单流转记录始终展示操作人并区分涉及打手补充编辑与撤回明细
This commit is contained in:
@@ -40,6 +40,21 @@ function readPayload(event: WorkOrderEvent, key: string): string {
|
|||||||
return String(value).trim()
|
return String(value).trim()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function readPayloadAmount(event: WorkOrderEvent, key: string): number {
|
||||||
|
return Number(readPayload(event, key) || 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatFenAmount(value: number) {
|
||||||
|
return `${(value / 100).toFixed(2)} 元`
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 事件涉及的打手名(管理端接口会附带打手摘要;打手端退回 #id) */
|
||||||
|
function resolveEventWorkerLabel(event: WorkOrderEvent): string {
|
||||||
|
if (event.worker?.displayName) return event.worker.displayName
|
||||||
|
const workerId = readPayload(event, 'workerId')
|
||||||
|
return workerId ? `打手 #${workerId}` : ''
|
||||||
|
}
|
||||||
|
|
||||||
/** 事件类型 → 节点阶段文案与颜色 */
|
/** 事件类型 → 节点阶段文案与颜色 */
|
||||||
export function formatWorkOrderEvent(event: WorkOrderEvent): EventNodeStyle {
|
export function formatWorkOrderEvent(event: WorkOrderEvent): EventNodeStyle {
|
||||||
const type = event.eventType
|
const type = event.eventType
|
||||||
@@ -79,9 +94,9 @@ export function formatWorkOrderEvent(event: WorkOrderEvent): EventNodeStyle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 'assigned_by_admin': {
|
case 'assigned_by_admin': {
|
||||||
const workerId = readPayload(event, 'workerId')
|
const workerLabel = resolveEventWorkerLabel(event)
|
||||||
return {
|
return {
|
||||||
title: `指派打手接手此单${workerId ? `(打手 #${workerId})` : ''}`,
|
title: workerLabel ? `指派打手接手此单(${workerLabel})` : '指派打手接手此单',
|
||||||
description: `订单状态:${formatStatusLabel(event.fromStatus)} → ${formatStatusLabel(
|
description: `订单状态:${formatStatusLabel(event.fromStatus)} → ${formatStatusLabel(
|
||||||
event.toStatus,
|
event.toStatus,
|
||||||
)}`,
|
)}`,
|
||||||
@@ -90,11 +105,15 @@ export function formatWorkOrderEvent(event: WorkOrderEvent): EventNodeStyle {
|
|||||||
}
|
}
|
||||||
case 'unassigned_by_admin':
|
case 'unassigned_by_admin':
|
||||||
return { title: '取消指派,订单回到未分配状态', color: 'green' }
|
return { title: '取消指派,订单回到未分配状态', color: 'green' }
|
||||||
case 'returned_to_hall_by_admin':
|
case 'returned_to_hall_by_admin': {
|
||||||
|
const releaseAmount = readPayloadAmount(event, 'releaseAmount')
|
||||||
return {
|
return {
|
||||||
title: note ? `撤回订单到抢单大厅(${note})` : '撤回订单到抢单大厅',
|
title: note ? `撤回订单到抢单大厅(${note})` : '撤回订单到抢单大厅',
|
||||||
|
description:
|
||||||
|
releaseAmount > 0 ? `已退回该打手冻结押金 ${formatFenAmount(releaseAmount)}` : undefined,
|
||||||
color: 'green',
|
color: 'green',
|
||||||
}
|
}
|
||||||
|
}
|
||||||
case 'cancelled_by_worker':
|
case 'cancelled_by_worker':
|
||||||
return { title: '打手取消接单', color: 'red' }
|
return { title: '打手取消接单', color: 'red' }
|
||||||
case 'cancel_request_submitted':
|
case 'cancel_request_submitted':
|
||||||
@@ -177,9 +196,9 @@ export function formatWorkOrderEvent(event: WorkOrderEvent): EventNodeStyle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 'sharing_share_accepted': {
|
case 'sharing_share_accepted': {
|
||||||
const workerId = readPayload(event, 'workerId')
|
const workerLabel = resolveEventWorkerLabel(event)
|
||||||
return {
|
return {
|
||||||
title: `拼单份额验收通过并已结算${workerId ? `(打手 #${workerId})` : ''}`,
|
title: `拼单份额验收通过并已结算${workerLabel ? `(${workerLabel})` : ''}`,
|
||||||
color: 'purple',
|
color: 'purple',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -251,8 +270,23 @@ export function formatWorkOrderEvent(event: WorkOrderEvent): EventNodeStyle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// —— 其他 ——
|
// —— 其他 ——
|
||||||
case 'edited':
|
case 'edited': {
|
||||||
return { title: '更改了订单信息', color: 'default' }
|
const productName = readPayload(event, 'productName')
|
||||||
|
const rewardAmount = readPayloadAmount(event, 'rewardAmount')
|
||||||
|
const requiredDepositAmount = readPayloadAmount(event, 'requiredDepositAmount')
|
||||||
|
const timeoutMinutes = readPayloadAmount(event, 'timeoutMinutes')
|
||||||
|
const changes = [
|
||||||
|
productName ? `品名:${productName}` : '',
|
||||||
|
rewardAmount > 0 ? `报酬 ${formatFenAmount(rewardAmount)}` : '',
|
||||||
|
requiredDepositAmount > 0 ? `押金 ${formatFenAmount(requiredDepositAmount)}` : '',
|
||||||
|
timeoutMinutes > 0 ? `时限 ${Math.round(timeoutMinutes)} 分钟` : '',
|
||||||
|
].filter(Boolean)
|
||||||
|
return {
|
||||||
|
title: '更改了订单信息',
|
||||||
|
description: changes.length > 0 ? `改为:${changes.join(' · ')}` : undefined,
|
||||||
|
color: 'default',
|
||||||
|
}
|
||||||
|
}
|
||||||
case 'sharing_config_updated':
|
case 'sharing_config_updated':
|
||||||
return { title: '更新了拼单配置', color: 'default' }
|
return { title: '更新了拼单配置', color: 'default' }
|
||||||
case 'price_synced_from_rule': {
|
case 'price_synced_from_rule': {
|
||||||
@@ -266,10 +300,10 @@ export function formatWorkOrderEvent(event: WorkOrderEvent): EventNodeStyle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 'sharing_share_cancelled_by_admin': {
|
case 'sharing_share_cancelled_by_admin': {
|
||||||
const workerId = readPayload(event, 'workerId')
|
const workerLabel = resolveEventWorkerLabel(event)
|
||||||
const quantity = readPayload(event, 'quantity')
|
const quantity = readPayload(event, 'quantity')
|
||||||
return {
|
return {
|
||||||
title: `撤销拼单参与者${workerId ? `(打手 #${workerId})` : ''}`,
|
title: `撤销拼单参与者${workerLabel ? `(${workerLabel})` : ''}`,
|
||||||
description: `${quantity ? `撤销 ${quantity} 份;` : ''}${note ? `原因:${note}` : '份数已退回接单大厅'}`,
|
description: `${quantity ? `撤销 ${quantity} 份;` : ''}${note ? `原因:${note}` : '份数已退回接单大厅'}`,
|
||||||
color: 'red',
|
color: 'red',
|
||||||
}
|
}
|
||||||
@@ -351,8 +385,37 @@ export default function WorkOrderEventTimeline({
|
|||||||
</Typography.Text>
|
</Typography.Text>
|
||||||
) : null}
|
) : null}
|
||||||
<div className="work-order-event-actor">
|
<div className="work-order-event-actor">
|
||||||
|
{event.worker && event.actorType === 'worker' ? (
|
||||||
|
<Space size={[4, 4]} wrap>
|
||||||
|
<Tag
|
||||||
|
color="blue"
|
||||||
|
className={canNavigateToWorker ? 'work-order-event-worker-link' : undefined}
|
||||||
|
onClick={() => {
|
||||||
|
if (!canNavigateToWorker) return
|
||||||
|
void navigate(
|
||||||
|
`/admin/worker-platform?tab=workers&workerId=${event.worker?.workerId}`,
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
操作人 · {event.worker.displayName} #{event.worker.workerId}
|
||||||
|
{canNavigateToWorker ? <LinkOutlined /> : null}
|
||||||
|
</Tag>
|
||||||
|
<Typography.Text type="secondary" className="work-order-event-worker-meta">
|
||||||
|
{event.worker.username} ·{' '}
|
||||||
|
{event.worker.workerType === 'internal' ? '内部' : '外部'} ·{' '}
|
||||||
|
{event.worker.levelName} · {formatWorkerStatus(event.worker.status)}
|
||||||
|
</Typography.Text>
|
||||||
|
</Space>
|
||||||
|
) : (
|
||||||
|
<Space size={[4, 4]} wrap>
|
||||||
|
<Tag color={resolveActorTagColor(event.actorType)}>
|
||||||
|
操作人 · {event.actorName || event.actorType || '未知'}
|
||||||
|
</Tag>
|
||||||
{event.worker ? (
|
{event.worker ? (
|
||||||
<Space size={[4, 4]} wrap>
|
<Space size={[4, 4]} wrap>
|
||||||
|
<Typography.Text type="secondary" className="work-order-event-worker-meta">
|
||||||
|
涉及打手
|
||||||
|
</Typography.Text>
|
||||||
<Tag
|
<Tag
|
||||||
color="blue"
|
color="blue"
|
||||||
className={canNavigateToWorker ? 'work-order-event-worker-link' : undefined}
|
className={canNavigateToWorker ? 'work-order-event-worker-link' : undefined}
|
||||||
@@ -366,26 +429,9 @@ export default function WorkOrderEventTimeline({
|
|||||||
{event.worker.displayName} #{event.worker.workerId}
|
{event.worker.displayName} #{event.worker.workerId}
|
||||||
{canNavigateToWorker ? <LinkOutlined /> : null}
|
{canNavigateToWorker ? <LinkOutlined /> : null}
|
||||||
</Tag>
|
</Tag>
|
||||||
<Typography.Text type="secondary" className="work-order-event-worker-meta">
|
|
||||||
{event.worker.username} ·{' '}
|
|
||||||
{event.worker.workerType === 'internal' ? '内部' : '外部'} ·{' '}
|
|
||||||
{event.worker.levelName} · {formatWorkerStatus(event.worker.status)}
|
|
||||||
</Typography.Text>
|
|
||||||
</Space>
|
</Space>
|
||||||
) : (
|
) : null}
|
||||||
<Tag
|
</Space>
|
||||||
color={
|
|
||||||
event.actorType === 'system'
|
|
||||||
? 'default'
|
|
||||||
: event.actorType === 'worker'
|
|
||||||
? 'blue'
|
|
||||||
: event.actorType === 'admin'
|
|
||||||
? 'green'
|
|
||||||
: 'default'
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{event.actorName || event.actorType}
|
|
||||||
</Tag>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -405,3 +451,10 @@ function formatWorkerStatus(status: string) {
|
|||||||
}
|
}
|
||||||
return labels[status] || status || '未知状态'
|
return labels[status] || status || '未知状态'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resolveActorTagColor(actorType: string) {
|
||||||
|
if (actorType === 'admin') return 'green'
|
||||||
|
if (actorType === 'worker') return 'blue'
|
||||||
|
if (actorType === 'system') return 'default'
|
||||||
|
return 'default'
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user