2026-10-12 20:33:39 +08:00
< script setup lang = "ts" >
import { computed } from 'vue'
import type { DailyResponse } from '../types'
2026-10-12 21:36:24 +08:00
import { label , quantityText , shownQuantity , trendSegments , reasonsText } from '../state'
2026-10-12 20:33:39 +08:00
const props = defineProps < { data : DailyResponse } > ()
const segments = computed (() => trendSegments ( props . data . points ))
const maximum = computed (() => Math . max ( 1 , ... props . data . points . map ( point => Number ( shownQuantity ( point ) ?? 0 ))))
function x ( index : number ) { return props . data . points . length === 1 ? 400 : 30 + index / ( props . data . points . length - 1 ) * 740 }
function y ( value : string | number | null ) { return 175 - Number ( value ?? 0 ) / maximum . value * 145 }
</ script >
< template >
< section aria -label =" SKU每日出库趋势 " >
2026-10-12 21:36:24 +08:00
< h3 >{{ data . summary . sku }} · 每日出库趋势 </ h3 >
< p > 所属货主 : {{ data . summary . customerCode || '—' }} · {{ data . summary . productName || '—' }}</ p >
< p >{{ data . summary . dataStatus === 'COMPLETE' ? '完整出库量' : '已采集出库量' }} : {{ quantityText ( shownQuantity ( data . summary )) }} {{ data . summary . quantityUnit === 'PCS' ? '件' : '单位未知' }} ; {{ label ( data . summary . dataStatus ) }} 。 今日为已采集累计 。 </ p >
2026-10-12 20:33:39 +08:00
< p v-if = "!segments.length" > 所选范围尚无可靠数据 , 未知日期不作为零销量 。 </ p >
< svg v-else viewBox = "0 0 800 220" role = "img" aria -label =" 每日出库件数 ; 虚线点表示未完整 , 缺失日期断线 " class = "sku-trend" >
< line x1 = "30" y1 = "175" x2 = "770" y2 = "175" stroke = "currentColor" />
2026-10-12 21:36:24 +08:00
< text x = "30" y = "20" >{{ maximum }} 件 </ text >
2026-10-12 20:33:39 +08:00
< path v-for = "(segment, index) in segments" :key="index" :d="segment.path" fill="none" stroke="var(--el-color-primary)" stroke-width="2" :stroke-dasharray="segment.partial ? '5 4' : undefined" />
< g v-for = "(point, index) in data.points" :key="point.businessDate" >
< circle v-if = "shownQuantity(point) != null && point.dataStatus !== 'UNKNOWN'" :cx="x(index)" :cy="y(shownQuantity(point))" r="4" :fill="point.dataStatus === 'COMPLETE' ? 'var(--el-color-primary)' : 'white'" stroke="var(--el-color-primary)" >
2026-10-12 21:36:24 +08:00
< title >{{ point . businessDate }} : {{ quantityText ( shownQuantity ( point )) }} {{ point . quantityUnit === 'PCS' ? '件' : '单位未知' }} , {{ label ( point . dataStatus ) }} ; 覆盖截止 {{ point . coveredUntil ?? '未知' }}</ title >
2026-10-12 20:33:39 +08:00
</ circle >
< text v-if = "data.points.length <= 15 || index === 0 || index === data.points.length - 1" :x="x(index)" y="205" text-anchor="middle" >{{ point.businessDate.slice ( 5 ) }}</ text >
</ g >
</ svg >
< details >
< summary > 每日数量 、 完整性及覆盖证据 </ summary >
< table class = "density-table" >< thead >< tr >< th > 北京时间日期 </ th >< th > 完整出库量 </ th >< th > 已采集量 </ th >< th > 状态 </ th >< th > 覆盖截止 </ th >< th > 缺口原因 </ th ></ tr ></ thead >< tbody >
2026-10-12 21:36:24 +08:00
< tr v-for = "point in data.points" :key="point.businessDate" >< td >{{ point . businessDate }}</ td >< td >{{ quantityText ( point . outboundQuantity ) }}</ td >< td >{{ quantityText ( point . observedQuantity ) }}</ td >< td >{{ label ( point . dataStatus ) }}</ td >< td >{{ point . coveredUntil ?? '—' }}</ td >< td >{{ reasonsText ( point . reasonCodes ) }}</ td ></ tr >
2026-10-12 20:33:39 +08:00
</ tbody ></ table >
</ details >
</ section >
</ template >
< style scoped >
. sku - trend { width : 100 % ; max - height : 280 px ; }
text { font - size : var ( -- admin - font - caption ); }
</ style >