This commit is contained in:
2026-08-11 19:35:28 +08:00
parent 886c7d3529
commit c690a30422
48 changed files with 935 additions and 171 deletions
@@ -46,6 +46,8 @@ describe('MeasurementReviewPanel', () => {
expect(wrapper.text()).toContain('原单申报')
expect(wrapper.text()).toContain('设备实测')
expect(wrapper.text()).toContain('设备采集')
expect(wrapper.text()).not.toContain('DEVICE')
expect(wrapper.text()).toContain('称重 OCR')
expect(wrapper.text()).toContain('实测长 × 宽 × 高(cm)')
expect(wrapper.text()).toContain('周长超过渠道限制')
@@ -7,6 +7,7 @@ import { getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http'
import ApiErrorMeta from '@/shared/components/ApiErrorMeta.vue'
import DataTable, { type DataTableColumn } from '@/shared/components/DataTable.vue'
import StatusBadge from '@/shared/components/StatusBadge.vue'
import { inboundReviewStatusLabels, inboundStatusLabel, weightRecognitionStatusLabels } from '../status'
import {
approveMeasurement,
getMeasurementReviewDetail,
@@ -49,12 +50,7 @@ const customerId = computed(() => props.customerId || props.tenantId || '')
const isPending = computed(() => detail.value?.measureReviewStatus === 'PENDING' && detail.value?.processStatus === 'MEASURE_PENDING')
const isRejected = computed(() => detail.value?.measureReviewStatus === 'REJECTED' && detail.value?.processStatus === 'MEASURE_REJECTED')
const confirmedWeights = computed(() => detail.value?.weightResults.filter((item) => item.confirmedAt && item.finalWeightKg !== null).length ?? 0)
const reviewStatusLabel = computed(() => {
if (isPending.value) return '待审核'
if (isRejected.value) return '已驳回'
if (detail.value?.measureReviewStatus === 'APPROVED') return '已通过'
return detail.value?.measureReviewStatus || '未提交'
})
const reviewStatusLabel = computed(() => inboundStatusLabel(detail.value?.measureReviewStatus, inboundReviewStatusLabels, '未提交'))
const measurementColumns: DataTableColumn[] = [
{ key: 'boxCode', label: '扫描箱号', minWidth: 190, slotName: 'boxCode' },
@@ -83,7 +79,16 @@ function formatDate(value: string | null | undefined) {
function resultLabel(value: string | null | undefined) {
if (value === 'APPROVED') return '审核通过'
if (value === 'REJECTED') return '审核驳回'
return value || '未知结果'
return '未知结果'
}
function recognitionStatusLabel(value: string | null | undefined) {
return inboundStatusLabel(value, weightRecognitionStatusLabels, '待确认')
}
function measurementSourceLabel(value: string | null | undefined) {
if (!value) return '-'
return ({ DEVICE: '设备采集', THIRD_PARTY: '第三方设备', MANUAL: '人工录入' } as Record<string, string>)[value] || '其他来源'
}
function isConflict(error: unknown) {
@@ -247,7 +252,7 @@ onMounted(() => {
<strong>{{ formatNumber(detail.actualGrossWeightKg, ' kg') }}</strong>
<dl>
<div><dt>已确认图片</dt><dd>{{ confirmedWeights }} / {{ detail.weightResults.length }}</dd></div>
<div><dt>测量来源</dt><dd>{{ detail.sourceType || '-' }}</dd></div>
<div><dt>测量来源</dt><dd>{{ measurementSourceLabel(detail.sourceType) }}</dd></div>
</dl>
</article>
</div>
@@ -281,7 +286,7 @@ onMounted(() => {
<div class="section-heading"><div><h3>称重图片识别结果</h3><p>原始 OCR 值不可覆盖,只有已确认且有效的结果会计入实际重量。</p></div><span class="section-count">{{ detail.weightResults.length }} 张</span></div>
<div class="weight-list">
<div v-for="item in detail.weightResults" :key="item.id" class="weight-row">
<div><strong>{{ item.fileId || '未关联文件' }}</strong><span>{{ item.ocrProvider || 'OCR' }} · {{ item.recognitionStatus || '待确认' }}</span><p v-if="item.ocrRawText">OCR 原文:{{ item.ocrRawText }}</p><p v-if="item.adjustmentReason">调整原因:{{ item.adjustmentReason }}</p></div>
<div><strong>{{ item.fileId || '未关联文件' }}</strong><span>{{ item.ocrProvider || 'OCR' }} · {{ recognitionStatusLabel(item.recognitionStatus) }}</span><p v-if="item.ocrRawText">OCR 原文:{{ item.ocrRawText }}</p><p v-if="item.adjustmentReason">调整原因:{{ item.adjustmentReason }}</p></div>
<div><span>原始</span><strong>{{ formatNumber(item.ocrWeightValue, ` ${item.ocrWeightUnit || ''}`) }}</strong></div>
<div><span>调整后</span><strong>{{ formatNumber(item.adjustedWeightValue, ` ${item.adjustedWeightUnit || ''}`) }}</strong></div>
<div><span>最终</span><strong>{{ formatNumber(item.finalWeightKg, ' kg') }}</strong></div>