8 天以前 fdd158306bf6dc3584f5110a385323f4a8dfb463
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<script lang="ts" setup>
import { computed } from 'vue';
import type { MesTraceBatchApi } from '#/api/mes/trace/batch';
 
const props = defineProps<{ detail: MesTraceBatchApi.Detail }>();
 
const formatTime = (value?: string) => value ? new Date(value).toLocaleString() : '未记录';
 
const timeline = computed(() => {
  if (props.detail.timeline?.length) return props.detail.timeline;
  return [
    ...(props.detail.purchaseSources?.length ? [{ stage: '来源', eventName: '采购来源', status: `${props.detail.purchaseSources.length} 条记录` }] : []),
    { stage: '生产', eventType: 'BATCH_CREATED', eventName: '生产批次建立', eventTime: props.detail.produceDate, status: props.detail.batchStatusName },
    { stage: '包装', eventName: '包装赋码', quantity: props.detail.bagTotal },
    ...(props.detail.inbound ? [{ stage: '仓储', eventType: 'INBOUND', eventName: '仓储入库', eventTime: props.detail.inbound.eventTime, quantity: props.detail.inbound.quantity, status: props.detail.inbound.status }] : []),
    ...(props.detail.salesTargets ?? []).map((item) => ({ stage: '销售', eventType: 'OUTBOUND', eventName: `销售去向 · ${item.clientName || '未记录客户'}`, eventTime: item.salesDate, quantity: item.quantity, status: item.qualityStatus == null ? undefined : String(item.qualityStatus) })),
    ...(props.detail.antiFake?.scanCount ? [{ stage: '消费', eventType: 'CONSUMER_SCANNED', eventName: '消费者验证', eventTime: props.detail.antiFake.lastScanTime, quantity: props.detail.antiFake.scanCount, status: `累计扫码 ${props.detail.antiFake.scanCount} 次` }] : []),
  ];
});
 
const colorMap: Record<string, string> = { 来源: 'blue', 生产: 'blue', 包装: 'purple', 仓储: 'green', 销售: 'orange', 消费: 'purple', 风险: 'red' };
</script>
 
<template>
  <div class="p-4">
    <a-timeline>
      <a-timeline-item v-for="(item, index) in timeline" :key="`${item.eventType || item.stage}-${index}`" :color="colorMap[item.stage || '生产'] || 'blue'">
        <div class="font-medium">{{ item.eventName || '追溯事件' }}</div>
        <div class="text-muted-foreground text-sm">
          {{ item.stage || '未分类' }} · 数量:{{ item.quantity ?? '—' }} · {{ formatTime(item.eventTime) }}
          <span v-if="item.status"> · {{ item.status }}</span>
        </div>
      </a-timeline-item>
      <a-empty v-if="!timeline.length" description="暂无追溯事件" />
    </a-timeline>
  </div>
</template>