优化
This commit is contained in:
@@ -38,6 +38,10 @@ type EditableMeasurementItem = Omit<SaveInboundMeasurementItemRequest, 'coeffici
|
||||
serverValues: Pick<InboundMeasurementItem, 'girthCm' | 'unitVolumeCbm' | 'totalWeightKg' | 'totalVolumeCbm' | 'volumeWeightKg'>
|
||||
chargeRuleId: string | null
|
||||
coefficientMode: 'ACTUAL' | 'ADD' | 'MULTIPLY'
|
||||
calculatedOuterLengthCm: number | null
|
||||
calculatedOuterWidthCm: number | null
|
||||
calculatedOuterHeightCm: number | null
|
||||
calculationRuleVersion: string | null
|
||||
}
|
||||
|
||||
interface MeasurementFormModel {
|
||||
@@ -77,6 +81,7 @@ const imagePreviewUrl = ref('')
|
||||
const imagePreviewError = ref<ApiErrorDetails | null>(null)
|
||||
const validationErrors = ref<Record<string, string[]>>({})
|
||||
const baseline = ref('')
|
||||
const confirmedWeightAvailable = ref(false)
|
||||
let requestSequence = 0
|
||||
let itemSequence = 0
|
||||
|
||||
@@ -114,10 +119,18 @@ const confirmedPackageCount = computed(() => form.items.reduce((sum, item) => su
|
||||
const expectedPackageCount = computed(() => detail.value?.originalPackageCount ?? null)
|
||||
const packageCountDifference = computed(() => expectedPackageCount.value == null ? null : confirmedPackageCount.value - expectedPackageCount.value)
|
||||
const packageCountMatched = computed(() => packageCountDifference.value === null || packageCountDifference.value === 0)
|
||||
const hasConfirmedWeightResult = computed(() => detail.value?.weightResults.some((item) => item.recognitionStatus === 'CONFIRMED') === true)
|
||||
const hasConfirmedWeightResult = computed(() => confirmedWeightAvailable.value)
|
||||
const isDropship = computed(() => detail.value?.fulfillmentType === 'ONE_CLICK_DROPSHIP')
|
||||
const expectedPalletCountValid = computed(() => !isDropship.value || (Number.isInteger(form.expectedPalletCount) && Number(form.expectedPalletCount) >= 1))
|
||||
const maySubmit = computed(() => canSubmit.value && submitEditableProcess.value && Boolean(form.measurementId) && packageCountMatched.value && hasConfirmedWeightResult.value && expectedPalletCountValid.value && !loading.value && !saving.value)
|
||||
const submissionBlockReason = computed(() => {
|
||||
if (!canSubmit.value || !submitEditableProcess.value || !form.measurementId) return ''
|
||||
if (!hasConfirmedWeightResult.value) return '即使只有一箱,也必须上传并确认至少一张称重图片后才能提交审核'
|
||||
if (!packageCountMatched.value) return '确认箱数合计必须与订单总箱数一致后才能提交审核'
|
||||
if (!expectedPalletCountValid.value) return '请先填写并保存有效的预计托数后再提交审核'
|
||||
if (isDirty.value) return '请先保存当前修改,再提交审核'
|
||||
return ''
|
||||
})
|
||||
const snapshot = computed(() => JSON.stringify(form))
|
||||
const isDirty = computed(() => Boolean(detail.value) && snapshot.value !== baseline.value)
|
||||
const registrationOpen = computed(() => hasContext.value && canView.value && Boolean(detail.value))
|
||||
@@ -302,10 +315,15 @@ function editableItem(item: InboundMeasurementItem): EditableMeasurementItem {
|
||||
},
|
||||
chargeRuleId: item.chargeRuleId == null ? null : String(item.chargeRuleId),
|
||||
coefficientMode: item.coefficientMode === 'MULTIPLY' ? 'MULTIPLY' : item.coefficientMode === 'ADD' ? 'ADD' : 'ACTUAL',
|
||||
calculatedOuterLengthCm: item.calculatedOuterLengthCm ?? null,
|
||||
calculatedOuterWidthCm: item.calculatedOuterWidthCm ?? null,
|
||||
calculatedOuterHeightCm: item.calculatedOuterHeightCm ?? null,
|
||||
calculationRuleVersion: item.calculationRuleVersion ?? null,
|
||||
}
|
||||
}
|
||||
|
||||
function clearForm() {
|
||||
confirmedWeightAvailable.value = false
|
||||
form.measurementId = null
|
||||
form.version = 0
|
||||
form.actualGoodsName = ''
|
||||
@@ -317,6 +335,7 @@ function clearForm() {
|
||||
|
||||
function applyDetail(resource: InboundMeasurementDetail) {
|
||||
detail.value = resource
|
||||
confirmedWeightAvailable.value = resource.weightResults.some((item) => item.recognitionStatus === 'CONFIRMED')
|
||||
form.measurementId = resource.measurementId == null ? null : String(resource.measurementId)
|
||||
form.version = resource.version ?? 0
|
||||
form.actualGoodsName = resource.actualGoodsName || ''
|
||||
@@ -486,6 +505,10 @@ async function saveDraft() {
|
||||
}
|
||||
|
||||
async function submitForReview() {
|
||||
if (!hasConfirmedWeightResult.value) {
|
||||
ElMessage.warning('即使只有一箱,也必须上传并确认至少一张称重图片后才能提交审核')
|
||||
return
|
||||
}
|
||||
if (!maySubmit.value || !form.measurementId) return
|
||||
if (!validateDraft()) return
|
||||
if (isDirty.value) {
|
||||
@@ -567,9 +590,18 @@ function processStatusLabel(status: string | undefined) {
|
||||
return inboundStatusLabel(status, inboundProcessStatusLabels)
|
||||
}
|
||||
|
||||
function updateActualWeights(actualGrossWeightKg: number | null, actualNetWeightKg: number | null) {
|
||||
function updateWeightEvidence(
|
||||
actualGrossWeightKg: number | null,
|
||||
actualNetWeightKg: number | null,
|
||||
hasConfirmedWeight: boolean,
|
||||
) {
|
||||
if (!detail.value) return
|
||||
detail.value = { ...detail.value, actualGrossWeightKg, actualNetWeightKg }
|
||||
confirmedWeightAvailable.value = hasConfirmedWeight
|
||||
}
|
||||
|
||||
function calculationModeLabel(value: EditableMeasurementItem['coefficientMode']) {
|
||||
return value === 'ADD' ? '箱规尺寸' : value === 'MULTIPLY' ? '箱规系数' : '实测原尺寸'
|
||||
}
|
||||
|
||||
function measurementRowClassName({ row }: { row: EditableMeasurementItem }) {
|
||||
@@ -581,6 +613,7 @@ watch(
|
||||
() => {
|
||||
requestSequence += 1
|
||||
detail.value = null
|
||||
confirmedWeightAvailable.value = false
|
||||
loadError.value = null
|
||||
operationError.value = null
|
||||
conflictDetected.value = false
|
||||
@@ -593,7 +626,7 @@ watch(
|
||||
|
||||
onBeforeUnmount(releaseImagePreview)
|
||||
|
||||
defineExpose({ saveDraft, submitForReview, updateActualWeights, mayMaintain, maySubmit, saving, submitting, canEdit, canSubmit, isDirty })
|
||||
defineExpose({ saveDraft, submitForReview, updateWeightEvidence, submissionBlockReason, mayMaintain, maySubmit, saving, submitting, canEdit, canSubmit, isDirty })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -639,6 +672,15 @@ defineExpose({ saveDraft, submitForReview, updateActualWeights, mayMaintain, may
|
||||
|
||||
<el-alert v-else-if="!canEdit" type="info" :closable="false" show-icon title="当前账号仅可查看测量数据" />
|
||||
|
||||
<el-alert
|
||||
v-if="submissionBlockReason && !hasConfirmedWeightResult"
|
||||
type="warning"
|
||||
:closable="false"
|
||||
show-icon
|
||||
class="measurement-alert"
|
||||
:title="submissionBlockReason"
|
||||
/>
|
||||
|
||||
<el-alert v-if="conflictDetected" type="warning" :closable="false" show-icon class="measurement-alert">
|
||||
<template #title>数据版本已变化,当前修改尚未丢失</template>
|
||||
<p>{{ operationError?.message }}</p>
|
||||
@@ -699,6 +741,22 @@ defineExpose({ saveDraft, submitForReview, updateActualWeights, mayMaintain, may
|
||||
<div v-else-if="isDropship" class="measurement-readonly-field"><span>预计托数</span><strong>{{ detail.expectedPalletCount ?? '—' }}</strong></div>
|
||||
<div class="measurement-readonly-field"><span>原单据号码</span><strong>{{ detail.originalDocumentNo || '—' }}</strong></div>
|
||||
</div>
|
||||
<el-table
|
||||
v-if="detail.latestDeclaration?.items.length"
|
||||
:data="detail.latestDeclaration.items"
|
||||
border
|
||||
stripe
|
||||
size="small"
|
||||
class="measurement-declaration-table"
|
||||
aria-label="客户申报箱规明细"
|
||||
>
|
||||
<el-table-column prop="itemNo" label="#" width="70" />
|
||||
<el-table-column prop="cargoName" label="货物品名" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column prop="packageCount" label="申报箱数" width="100" />
|
||||
<el-table-column label="申报尺寸 长×宽×高(cm)" min-width="190">
|
||||
<template #default="{ row }">{{ formatNumber(row.lengthCm) }} × {{ formatNumber(row.widthCm) }} × {{ formatNumber(row.heightCm) }}</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
@@ -722,11 +780,16 @@ defineExpose({ saveDraft, submitForReview, updateActualWeights, mayMaintain, may
|
||||
<el-table-column type="expand" width="42">
|
||||
<template #default="{ row }">
|
||||
<dl class="measurement-row-details">
|
||||
<div><dt>箱规</dt><dd>{{ row.boxSpecification || '—' }}</dd></div>
|
||||
<div><dt>机器编号</dt><dd>{{ row.machineNo || '人工录入' }}</dd></div>
|
||||
<div><dt>测量时间</dt><dd>{{ row.measuredAt ? row.measuredAt.replace('T', ' ') : '—' }}</dd></div>
|
||||
<div><dt>计算方式</dt><dd>{{ calculationModeLabel(row.coefficientMode) }}</dd></div>
|
||||
<div><dt>计算后外箱</dt><dd>{{ formatNumber(row.calculatedOuterLengthCm) }} × {{ formatNumber(row.calculatedOuterWidthCm) }} × {{ formatNumber(row.calculatedOuterHeightCm) }} cm</dd></div>
|
||||
<div><dt>单箱体积</dt><dd>{{ formatNumber(row.serverValues.unitVolumeCbm, 4) }} m³</dd></div>
|
||||
<div><dt>箱规周长</dt><dd>{{ formatNumber(row.serverValues.girthCm) }} cm</dd></div>
|
||||
<div><dt>总材积重</dt><dd>{{ formatNumber(row.serverValues.volumeWeightKg) }} kg</dd></div>
|
||||
<div><dt>计算规则版本</dt><dd>{{ row.calculationRuleVersion || '—' }}</dd></div>
|
||||
<div><dt>超限提醒</dt><dd>{{ row.overLimitWarning || '—' }}</dd></div>
|
||||
<div><dt>备注</dt><dd>{{ row.remark || '—' }}</dd></div>
|
||||
</dl>
|
||||
</template>
|
||||
@@ -848,6 +911,7 @@ defineExpose({ saveDraft, submitForReview, updateActualWeights, mayMaintain, may
|
||||
.measurement-panel h3 { font-size: 14px; }
|
||||
.measurement-panel__heading p, .measurement-section__heading p { margin: 4px 0 0; color: var(--cc-muted); font-size: 12px; line-height: 1.55; }
|
||||
.measurement-panel__actions, .measurement-panel__footer > div { display: flex; flex: 0 0 auto; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }
|
||||
.measurement-declaration-table { margin-top: 12px; }
|
||||
.measurement-panel__actions :deep(.el-button), .measurement-panel__footer :deep(.el-button) { margin-left: 0; }
|
||||
.measurement-skeleton { padding: 24px; }
|
||||
.measurement-panel > :deep(.el-alert), .measurement-alert { margin: 16px 20px 0; width: auto; }
|
||||
|
||||
Reference in New Issue
Block a user