优化
This commit is contained in:
@@ -10,7 +10,6 @@ import LoadErrorState from '@/shared/components/LoadErrorState.vue'
|
||||
import { getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http'
|
||||
import { inboundProcessStatusLabels, inboundStatusLabel } from '../status'
|
||||
import { createManualCartonScan, downloadInboundMeasurementImage, getInboundMeasurement, saveInboundMeasurementDraft, submitInboundMeasurement, updateConfirmedPackageCount } from './api'
|
||||
import { listCustomerChargeRules, type CustomerChargeRule } from '@/modules/fba-pricing'
|
||||
import type {
|
||||
InboundMeasurementDetail,
|
||||
InboundMeasurementItem,
|
||||
@@ -21,7 +20,6 @@ const props = defineProps<{
|
||||
customerId?: string
|
||||
tenantId?: string
|
||||
inboundId: string
|
||||
openWarehouseSuggestion?: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -62,15 +60,10 @@ const loading = ref(false)
|
||||
const saving = ref(false)
|
||||
const submitting = ref(false)
|
||||
const manualEntryOpen = ref(false)
|
||||
const warehouseSuggestionOpen = ref(false)
|
||||
const warehouseSuggestionAutoOpened = ref(false)
|
||||
const warehouseSuggestion = reactive({ itemId: '', packageCount: 1, remark: '', coefficientMode: 'ADD' as 'ADD' | 'MULTIPLY' })
|
||||
const manualEntrySubmitting = ref(false)
|
||||
const manualEntryImage = ref<File | null>(null)
|
||||
const manualEntryErrors = ref<string[]>([])
|
||||
const detail = ref<InboundMeasurementDetail | null>(null)
|
||||
const chargeRules = ref<CustomerChargeRule[]>([])
|
||||
const chargeRulesLoading = ref(false)
|
||||
const loadError = ref<ApiErrorDetails | null>(null)
|
||||
const operationError = ref<ApiErrorDetails | null>(null)
|
||||
const conflictDetected = ref(false)
|
||||
@@ -105,7 +98,6 @@ const canView = computed(() => access.can('platform:firstleg:inbound:measure:vie
|
||||
const canEdit = computed(() => access.can('platform:firstleg:inbound:measure:edit'))
|
||||
const canManualEntry = computed(() => access.can('platform:firstleg:inbound:measure:manual-entry'))
|
||||
const canSubmit = computed(() => access.can('platform:firstleg:inbound:measure:submit'))
|
||||
const canWarehouseSuggestion = computed(() => access.can('platform:firstleg:inbound:warehouse-suggestion:edit'))
|
||||
const customerId = computed(() => props.customerId || props.tenantId || '')
|
||||
const hasContext = computed(() => Boolean(customerId.value && props.inboundId))
|
||||
const countEditableProcess = computed(() => ['WAIT_MEASURE', 'MEASURING', 'MEASURE_PENDING', 'MEASURE_REJECTED'].includes(detail.value?.processStatus || ''))
|
||||
@@ -123,9 +115,6 @@ const isDirty = computed(() => Boolean(detail.value) && snapshot.value !== basel
|
||||
const registrationOpen = computed(() => hasContext.value && canView.value && Boolean(detail.value))
|
||||
const requiredPermission = computed(() => canEdit.value ? 'platform:firstleg:inbound:measure:edit' : null)
|
||||
const sourceLabel = computed(() => ({ THIRD_PARTY: '第三方设备', MANUAL: '平台人工', OPENAPI: '第三方设备' }[detail.value?.sourceType || ''] || (detail.value?.sourceType ? '未知来源' : '尚未测量')))
|
||||
const suggestionItem = computed(() => form.items.find((item) => item.itemId === warehouseSuggestion.itemId) || null)
|
||||
const suggestionTotalVolume = computed(() => Number(suggestionItem.value?.serverValues.unitVolumeCbm || 0) * warehouseSuggestion.packageCount)
|
||||
const suggestionGirth = computed(() => suggestionItem.value ? suggestionItem.value.lengthCm + 2 * (suggestionItem.value.widthCm + suggestionItem.value.heightCm) : 0)
|
||||
|
||||
interface MeasurementDeviationWarning {
|
||||
key: string
|
||||
@@ -305,36 +294,6 @@ function editableItem(item: InboundMeasurementItem): EditableMeasurementItem {
|
||||
}
|
||||
}
|
||||
|
||||
function openWarehouseSuggestion() {
|
||||
if (!canWarehouseSuggestion.value && !canEdit.value) return
|
||||
const first = form.items[0]
|
||||
warehouseSuggestion.itemId = first?.itemId || ''
|
||||
warehouseSuggestion.packageCount = first?.packageCount || 1
|
||||
warehouseSuggestion.remark = first?.remark || ''
|
||||
warehouseSuggestion.coefficientMode = first?.coefficientMode === 'MULTIPLY' ? 'MULTIPLY' : 'ADD'
|
||||
warehouseSuggestionOpen.value = true
|
||||
}
|
||||
|
||||
function applyWarehouseSuggestion() {
|
||||
const item = suggestionItem.value
|
||||
if (!item) { ElMessage.warning('请选择当前实测 SKU'); return }
|
||||
if (!Number.isInteger(warehouseSuggestion.packageCount) || warehouseSuggestion.packageCount < 1) { ElMessage.warning('箱数必须是大于 0 的整数'); return }
|
||||
item.packageCount = warehouseSuggestion.packageCount
|
||||
item.remark = warehouseSuggestion.remark.trim() || null
|
||||
item.coefficientMode = warehouseSuggestion.coefficientMode
|
||||
warehouseSuggestionOpen.value = false
|
||||
ElMessage.success('仓库建议数据已加入,请保存测量数据')
|
||||
}
|
||||
|
||||
async function loadChargeRules() {
|
||||
if (!customerId.value || !access.can('firstleg:fba-pricing:rule:view')) return
|
||||
chargeRulesLoading.value = true
|
||||
try {
|
||||
chargeRules.value = await listCustomerChargeRules(customerId.value)
|
||||
} catch { chargeRules.value = [] }
|
||||
finally { chargeRulesLoading.value = false }
|
||||
}
|
||||
|
||||
function clearForm() {
|
||||
form.measurementId = null
|
||||
form.version = 0
|
||||
@@ -366,11 +325,6 @@ async function loadMeasurement() {
|
||||
const resource = await getInboundMeasurement(customerId.value, props.inboundId)
|
||||
if (sequence !== requestSequence) return
|
||||
applyDetail(resource)
|
||||
void loadChargeRules()
|
||||
if (props.openWarehouseSuggestion && !warehouseSuggestionAutoOpened.value && form.items.length) {
|
||||
warehouseSuggestionAutoOpened.value = true
|
||||
openWarehouseSuggestion()
|
||||
}
|
||||
} catch (error) {
|
||||
if (sequence !== requestSequence) return
|
||||
detail.value = null
|
||||
@@ -603,17 +557,6 @@ function measurementRowClassName({ row }: { row: EditableMeasurementItem }) {
|
||||
return validationErrors.value[row.clientKey]?.length ? 'measurement-table__row--error' : ''
|
||||
}
|
||||
|
||||
function chargeRuleName(ruleId: string | null | undefined) {
|
||||
if (!ruleId) return '默认规则'
|
||||
const rule = chargeRules.value.find((item) => item.id === ruleId)
|
||||
return rule ? chargeRuleLabel(rule) : ruleId
|
||||
}
|
||||
|
||||
function chargeRuleLabel(rule: CustomerChargeRule) {
|
||||
const remark = rule.remark?.trim()
|
||||
return `系数 ${rule.lengthFactor}${remark ? ` · ${remark}` : ''}${rule.defaultRule ? '(默认)' : ''}`
|
||||
}
|
||||
|
||||
watch(
|
||||
() => [customerId.value, props.inboundId, canView.value] as const,
|
||||
() => {
|
||||
@@ -623,7 +566,6 @@ watch(
|
||||
operationError.value = null
|
||||
conflictDetected.value = false
|
||||
validationErrors.value = {}
|
||||
warehouseSuggestionAutoOpened.value = false
|
||||
clearForm()
|
||||
if (hasContext.value && canView.value) void loadMeasurement()
|
||||
},
|
||||
@@ -733,7 +675,6 @@ defineExpose({ saveDraft, submitForReview, updateActualWeights, mayMaintain, may
|
||||
<div class="measurement-section__heading">
|
||||
<div><h3>箱规明细</h3></div>
|
||||
<div class="measurement-section-actions">
|
||||
<el-button v-if="canWarehouseSuggestion" type="primary" plain :disabled="!mayMaintain || !form.items.length" @click="openWarehouseSuggestion"><Plus :size="15" />添加仓库建议数据</el-button>
|
||||
<el-button v-if="canManualEntry" type="primary" plain :disabled="!mayCreateManualEntry" @click="openManualEntry"><Plus :size="15" />手动录入箱规</el-button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -789,15 +730,6 @@ defineExpose({ saveDraft, submitForReview, updateActualWeights, mayMaintain, may
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="计算方式" min-width="150">
|
||||
<template #default="{ row }">
|
||||
<el-select v-model="row.coefficientMode" placeholder="选择计算方式">
|
||||
<el-option label="实测原尺寸(不调整)" value="ACTUAL" />
|
||||
<el-option label="按箱规尺寸策略" value="ADD" />
|
||||
<el-option label="按箱规尺寸系数" value="MULTIPLY" :disabled="!chargeRules.some((rule) => rule.defaultRule && rule.status === 'ACTIVE')" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="总体积(m³)" width="108" align="right">
|
||||
<template #default="{ row }">{{ formatNumber(row.serverValues.totalVolumeCbm, 4) }}</template>
|
||||
</el-table-column>
|
||||
@@ -812,18 +744,6 @@ defineExpose({ saveDraft, submitForReview, updateActualWeights, mayMaintain, may
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-empty v-else description="暂无扫描箱测量数据" />
|
||||
<div v-if="form.items.length" class="warehouse-suggestion-table">
|
||||
<h3>仓库建议数据</h3>
|
||||
<el-table :data="form.items" border stripe empty-text="暂无仓库建议数据">
|
||||
<el-table-column prop="itemNo" label="当前实测 SKU" min-width="150" />
|
||||
<el-table-column label="外箱规 长×宽×高(cm)" min-width="190"><template #default="{ row }">{{ formatNumber(row.outerLengthCm) }} × {{ formatNumber(row.outerWidthCm) }} × {{ formatNumber(row.outerHeightCm) }}</template></el-table-column>
|
||||
<el-table-column prop="packageCount" label="箱数" width="90" />
|
||||
<el-table-column label="周长(cm)" width="110"><template #default="{ row }">{{ formatNumber(row.serverValues.girthCm) }}</template></el-table-column>
|
||||
<el-table-column label="总体积(m³)" width="120"><template #default="{ row }">{{ formatNumber(row.serverValues.unitVolumeCbm == null ? null : row.serverValues.unitVolumeCbm * row.packageCount, 6) }}</template></el-table-column>
|
||||
<el-table-column label="计算策略" min-width="190"><template #default="{ row }">{{ row.coefficientMode === 'MULTIPLY' ? '按箱规尺寸系数' : '按箱规尺寸策略' }}<span v-if="row.coefficientMode === 'MULTIPLY'">({{ chargeRuleName(row.chargeRuleId) }})</span></template></el-table-column>
|
||||
<el-table-column prop="remark" label="备注" min-width="160" show-overflow-tooltip />
|
||||
</el-table>
|
||||
</div>
|
||||
</section>
|
||||
</fieldset>
|
||||
</form>
|
||||
@@ -837,21 +757,6 @@ defineExpose({ saveDraft, submitForReview, updateActualWeights, mayMaintain, may
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<AppDialog v-model="warehouseSuggestionOpen" title="添加仓库建议数据" width="min(680px, calc(100vw - 28px))" confirm-text="加入建议" @confirm="applyWarehouseSuggestion">
|
||||
<el-form label-position="top" class="warehouse-suggestion-form">
|
||||
<el-form-item label="当前实测 SKU" required><el-select v-model="warehouseSuggestion.itemId" filterable><el-option v-for="item in form.items" :key="item.itemId" :label="`${item.itemNo} · ${item.boxSpecification || item.boxCode || '实测SKU'}`" :value="item.itemId" /></el-select></el-form-item>
|
||||
<el-form-item label="箱数" required><el-input-number v-model="warehouseSuggestion.packageCount" :min="1" :max="1000000" step-strictly /></el-form-item>
|
||||
<el-form-item label="计算方式"><el-select v-model="warehouseSuggestion.coefficientMode"><el-option label="按箱规尺寸策略" value="ADD" /><el-option label="按箱规尺寸系数" value="MULTIPLY" /></el-select></el-form-item>
|
||||
<el-form-item label="备注"><el-input v-model="warehouseSuggestion.remark" type="textarea" :rows="3" maxlength="500" show-word-limit /></el-form-item>
|
||||
</el-form>
|
||||
<dl v-if="suggestionItem" class="suggestion-preview">
|
||||
<div><dt>长 × 宽 × 高</dt><dd>{{ formatNumber(suggestionItem.lengthCm) }} × {{ formatNumber(suggestionItem.widthCm) }} × {{ formatNumber(suggestionItem.heightCm) }} cm</dd></div>
|
||||
<div><dt>箱规周长</dt><dd>{{ formatNumber(suggestionGirth) }} cm</dd></div>
|
||||
<div><dt>单箱体积</dt><dd>{{ formatNumber(suggestionItem.serverValues.unitVolumeCbm, 6) }} m³</dd></div>
|
||||
<div><dt>总体积</dt><dd>{{ formatNumber(suggestionTotalVolume, 6) }} m³</dd></div>
|
||||
</dl>
|
||||
</AppDialog>
|
||||
|
||||
<el-dialog v-model="imagePreviewOpen" title="当前有效测量图片" width="min(720px, 92vw)" destroy-on-close @closed="releaseImagePreview">
|
||||
<div class="measurement-image-preview">
|
||||
<el-skeleton v-if="imagePreviewLoading" :rows="5" animated />
|
||||
|
||||
Reference in New Issue
Block a user