<script lang="ts" setup>
|
import { computed, onMounted, onUnmounted, ref } from 'vue';
|
import { gsap } from 'gsap';
|
import type { MesTraceBatchApi } from '#/api/mes/trace/batch';
|
|
const props = defineProps<{ detail: MesTraceBatchApi.Detail }>();
|
const qualityRisk = computed(() => props.detail.decision?.qualityRisk ?? props.detail.quality?.result === 2);
|
const riskLevel = computed(() => props.detail.decision?.riskLevel || (qualityRisk.value ? 'HIGH' : 'NORMAL'));
|
const containerRef = ref<HTMLElement>();
|
let animationContext: gsap.Context | undefined;
|
|
onMounted(() => {
|
if (!containerRef.value) return;
|
animationContext = gsap.context(() => {
|
gsap.from('.trace-stage-card', { autoAlpha: 0, y: 12, duration: 0.3, stagger: 0.04, ease: 'power2.out' });
|
}, containerRef.value);
|
});
|
|
onUnmounted(() => animationContext?.revert());
|
</script>
|
|
<template>
|
<div ref="containerRef" class="grid grid-cols-2 gap-3 p-4 lg:grid-cols-4">
|
<div v-for="stage in [
|
{ name: '来源', value: detail.purchaseSources?.length ? '已建立' : '待补充' },
|
{ name: '生产批次', value: detail.batchStatusName || '未知' },
|
{ name: '质量检验', value: detail.quality?.resultName || '待检验' },
|
{ name: '包装赋码', value: `${detail.bagTotal ?? 0} 袋 / ${detail.palletCount ?? 0} 托` },
|
{ name: '仓储入库', value: detail.inbound ? '已入库' : '未入库' },
|
{ name: '销售去向', value: `${detail.salesTargets?.length ?? 0} 条` },
|
{ name: '消费者验证', value: `${detail.antiFake?.scanCount ?? 0} 次扫码` },
|
{ name: '风险状态', value: qualityRisk ? '质量异常' : riskLevel === 'NORMAL' ? '正常' : riskLevel },
|
]" :key="stage.name" class="trace-stage-card rounded border bg-white p-4 shadow-sm">
|
<div class="text-muted-foreground text-sm">{{ stage.name }}</div>
|
<div class="mt-2 text-base font-semibold" :class="stage.name === '风险状态' ? qualityRisk ? 'text-red-600' : riskLevel === 'NORMAL' ? 'text-green-600' : 'text-orange-600' : ''">
|
{{ stage.value }}
|
</div>
|
</div>
|
</div>
|
</template>
|