Release/test 合并上生产 #2

Merged
admin merged 736 commits from release/test into main 2026-09-17 11:50:56 +08:00
4 changed files with 17 additions and 4 deletions
Showing only changes of commit e0b1334d2d - Show all commits
@@ -16,7 +16,7 @@ describe('InboundHistoryPanel dropship pallet result', () => {
it('keeps the existing scoped pallet-label action available', () => {
expect(source).toContain('downloadDropshipPalletLabel(props.customerId, props.inboundId, pallet.palletId)')
expect(source).toContain("pallet.status === 'SEALED' && pallet.palletNo")
expect(source).toContain('v-if="pallet.palletNo"')
expect(source).toContain('打印托盘码')
})
})
@@ -55,7 +55,7 @@ async function printPallet(pallet: InboundDropshipPallet) {
<article v-for="pallet in dropshipPallets" :key="pallet.palletId" class="dropship-pallet-card">
<header>
<div><strong>{{ value(pallet.palletNo) }}</strong><el-tag size="small" :type="pallet.status === 'SEALED' ? 'success' : 'warning'" effect="plain">{{ dropshipPalletStatus(pallet.status) }}</el-tag></div>
<el-button v-if="pallet.status === 'SEALED' && pallet.palletNo" link type="primary" @click="printPallet(pallet)">打印托盘码</el-button>
<el-button v-if="pallet.palletNo" link type="primary" @click="printPallet(pallet)">打印托盘码</el-button>
</header>
<dl class="dropship-pallet-summary">
<div><dt>箱数</dt><dd>{{ pallet.cartonCount }}</dd></div>
@@ -44,6 +44,7 @@ interface MeasurementFormModel {
measurementId: string | null
version: number
actualGoodsName: string
expectedPalletCount: number | null
items: EditableMeasurementItem[]
}
@@ -83,6 +84,7 @@ const form = reactive<MeasurementFormModel>({
measurementId: null,
version: 0,
actualGoodsName: '',
expectedPalletCount: null,
items: [],
})
@@ -113,7 +115,9 @@ const expectedPackageCount = computed(() => detail.value?.originalPackageCount ?
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 maySubmit = computed(() => canSubmit.value && submitEditableProcess.value && Boolean(form.measurementId) && packageCountMatched.value && hasConfirmedWeightResult.value && !loading.value && !saving.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 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))
@@ -305,6 +309,7 @@ function clearForm() {
form.measurementId = null
form.version = 0
form.actualGoodsName = ''
form.expectedPalletCount = null
form.items.splice(0)
baseline.value = JSON.stringify(form)
captureBaseline()
@@ -315,6 +320,7 @@ function applyDetail(resource: InboundMeasurementDetail) {
form.measurementId = resource.measurementId == null ? null : String(resource.measurementId)
form.version = resource.version ?? 0
form.actualGoodsName = resource.actualGoodsName || ''
form.expectedPalletCount = resource.expectedPalletCount ?? null
form.items.splice(0, form.items.length, ...resource.items.map(editableItem))
baseline.value = JSON.stringify(form)
captureBaseline()
@@ -361,6 +367,7 @@ function validateDraft() {
const errors: Record<string, string[]> = {}
const general: string[] = []
if (!form.items.length) general.push('请至少保留一条实际扫描箱测量记录')
if (isDropship.value && (!Number.isInteger(form.expectedPalletCount) || Number(form.expectedPalletCount) < 1 || Number(form.expectedPalletCount) > 1000)) general.push('一件代发预计托数必须是 1 至 1,000 的整数')
if (form.items.length > 500) general.push('单个测量批次最多包含 500 条实际扫描箱记录')
form.items.forEach((item, index) => {
const itemErrors: string[] = []
@@ -432,7 +439,7 @@ async function saveDraft() {
outerLengthCm: item.outerLengthCm, outerWidthCm: item.outerWidthCm, outerHeightCm: item.outerHeightCm,
chargeRuleId: item.chargeRuleId || null, coefficientMode: item.coefficientMode || 'ACTUAL', remark: item.remark || null,
})]))
const draftChanged = Boolean(detail.value && ((detail.value.actualGoodsName || '') !== form.actualGoodsName || form.items.some((item) => originalDraftValues.get(item.itemId) !== JSON.stringify({
const draftChanged = Boolean(detail.value && ((detail.value.actualGoodsName || '') !== form.actualGoodsName || (detail.value.expectedPalletCount ?? null) !== form.expectedPalletCount || form.items.some((item) => originalDraftValues.get(item.itemId) !== JSON.stringify({
lengthCm: item.lengthCm, widthCm: item.widthCm, heightCm: item.heightCm,
outerLengthCm: item.outerLengthCm, outerWidthCm: item.outerWidthCm, outerHeightCm: item.outerHeightCm,
chargeRuleId: item.chargeRuleId || null, coefficientMode: item.coefficientMode, remark: item.remark || null,
@@ -444,6 +451,7 @@ async function saveDraft() {
measurementId: form.measurementId,
version,
actualGoodsName: form.actualGoodsName.trim() || null,
expectedPalletCount: isDropship.value ? form.expectedPalletCount : null,
items: form.items.map((item) => ({
inboundDetailId: item.inboundDetailId, itemNo: item.itemNo, boxSpecification: item.boxSpecification,
packageCount: item.packageCount, lengthCm: item.lengthCm, widthCm: item.widthCm, heightCm: item.heightCm,
@@ -686,6 +694,8 @@ defineExpose({ saveDraft, submitForReview, updateActualWeights, mayMaintain, may
<div class="measurement-readonly-field"><span>申报体积(m³)</span><strong>{{ formatNumber(detail.originalVolumeCbm, 4) }}</strong></div>
<label v-if="mayMaintain" class="measurement-goods-name"><span>实际品名</span><el-input v-model="form.actualGoodsName" placeholder="请输入实际品名" maxlength="255" /></label>
<div v-else class="measurement-readonly-field measurement-goods-name"><span>实际品名</span><strong>{{ detail.actualGoodsName || '—' }}</strong></div>
<label v-if="isDropship && mayMaintain"><span>预计托数</span><el-input-number v-model="form.expectedPalletCount" :min="1" :max="1000" :step="1" step-strictly controls-position="right" /></label>
<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>
</section>
@@ -103,6 +103,8 @@ export interface InboundMeasurementDetail {
companyName: string
channelCode: string | null
channelName: string | null
fulfillmentType?: string | null
expectedPalletCount?: number | null
processStatus: InboundMeasurementProcessStatus
measureReviewStatus: string | null
recommendedPalletType: string | null
@@ -154,6 +156,7 @@ export interface SaveInboundMeasurementDraftRequest {
measurementId: MeasurementIdentifier | null
version: number
actualGoodsName: string | null
expectedPalletCount?: number | null
items: SaveInboundMeasurementItemRequest[]
}