From 664d4844c3f6a4f4986c1aeeed51456562107f97 Mon Sep 17 00:00:00 2001 From: liuyihe <2513762445@qq.com> Date: Thu, 3 Sep 2026 15:05:30 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CustomerBillingRulesPanel.test.ts | 10 ++--- .../components/CustomerBillingRulesPanel.vue | 10 ++--- .../pages/UnifiedOrdersView.test.ts | 4 ++ .../pages/UnifiedOrdersView.vue | 42 ++++++++++++------- 4 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/modules/customers/components/CustomerBillingRulesPanel.test.ts b/src/modules/customers/components/CustomerBillingRulesPanel.test.ts index df4b73dd..202edf9c 100644 --- a/src/modules/customers/components/CustomerBillingRulesPanel.test.ts +++ b/src/modules/customers/components/CustomerBillingRulesPanel.test.ts @@ -34,8 +34,8 @@ const config: CustomerDimensionConfig = { rules: boxes.map(([boxType, boxTypeName, innerLengthCm, innerWidthCm, innerHeightCm, remark], index) => ({ id: String(100 + index), boxType, boxTypeName, innerLengthCm, innerWidthCm, innerHeightCm, edgeAdditionCm: 2, - outerLengthCm: innerLengthCm + 4, outerWidthCm: innerWidthCm + 4, outerHeightCm: innerHeightCm + 4, - volumeCbm: Number(((innerLengthCm + 4) * (innerWidthCm + 4) * (innerHeightCm + 4) / 1_000_000).toFixed(3)), + outerLengthCm: innerLengthCm + 2, outerWidthCm: innerWidthCm + 2, outerHeightCm: innerHeightCm + 2, + volumeCbm: Number(((innerLengthCm + 2) * (innerWidthCm + 2) * (innerHeightCm + 2) / 1_000_000).toFixed(3)), remark, version: 3, createdAt: '2026-08-07T10:00:00', updatedAt: '2026-08-07T10:20:00', })), } @@ -71,11 +71,11 @@ describe('CustomerBillingRulesPanel', () => { await flushPromises() expect(getCustomerDimensionConfig).toHaveBeenCalledWith('8') expect(document.body.textContent).toContain('按箱规尺寸计算') - expect(document.body.textContent).toContain('内径尺寸 + 外边加宽 × 2 = 外径尺寸') + expect(document.body.textContent).toContain('长加 X、宽加 X、高加 X = 外径尺寸') expect(document.body.textContent).toContain('小箱') expect(document.body.textContent).toContain('特大箱') - expect(document.body.textContent).toContain('34 × 24 × 24') - expect(document.body.textContent).toContain('0.020') + expect(document.body.textContent).toContain('32 × 22 × 22') + expect(document.body.textContent).toContain('0.015') expect(document.body.textContent).toContain('标准中箱') }) diff --git a/src/modules/customers/components/CustomerBillingRulesPanel.vue b/src/modules/customers/components/CustomerBillingRulesPanel.vue index bff779d8..3dd4e0e6 100644 --- a/src/modules/customers/components/CustomerBillingRulesPanel.vue +++ b/src/modules/customers/components/CustomerBillingRulesPanel.vue @@ -71,7 +71,7 @@ const BOX_NAMES: Record = { const columns: DataTableColumn[] = [ { key: 'boxTypeName', label: '箱规类型', minWidth: 110, slotName: 'boxTypeName' }, { key: 'inner', label: '内径尺寸(长×宽×高 cm)', minWidth: 210, slotName: 'inner' }, - { key: 'edgeAdditionCm', label: '外边加宽(cm)', width: 150, slotName: 'edgeAdditionCm' }, + { key: 'edgeAdditionCm', label: '尺寸增加值(cm)', width: 150, slotName: 'edgeAdditionCm' }, { key: 'outer', label: '外径尺寸(长×宽×高 cm)', minWidth: 210, slotName: 'outer' }, { key: 'volumeCbm', label: '体积(CBM)', width: 130, slotName: 'volumeCbm' }, { key: 'remark', label: '备注', minWidth: 140, prop: 'remark' }, @@ -168,7 +168,7 @@ function validateRules() { return false } if (form.rules.some((rule) => !Number.isFinite(rule.edgeAdditionCm) || rule.edgeAdditionCm < 0.001 || rule.edgeAdditionCm > 100)) { - ElMessage.error('外边加宽必须在 0.001 至 100cm 之间') + ElMessage.error('尺寸增加值必须在 0.001 至 100cm 之间') return false } if (form.rules.some((rule) => (rule.remark || '').length > 500)) { @@ -300,7 +300,7 @@ onMounted(() => { void loadConfig(); void loadChargeRules() }) 编辑规则 -
计算方式:内径尺寸 + 外边加宽 × 2 = 外径尺寸(按实测尺寸匹配最小可容纳箱规)体积公式:外径长 × 外径宽 × 外径高 ÷ 1,000,000 = CBM超出当前箱规时自动匹配下一档箱规
+
计算方式:长加 X、宽加 X、高加 X = 外径尺寸(X 为尺寸增加值,按实测尺寸匹配最小可容纳箱规)体积公式:外径长 × 外径宽 × 外径高 ÷ 1,000,000 = CBM超出当前箱规时自动匹配下一档箱规
@@ -328,10 +328,10 @@ onMounted(() => { void loadConfig(); void loadChargeRules() })
-

计算公式:按长、宽、高匹配最小可容纳箱规;外径 = 该箱规内径 + 加宽 × 2(每侧加宽),体积(CBM) = 外径长 × 外径宽 × 外径高 ÷ 1,000,000

+

计算公式:按长、宽、高匹配最小可容纳箱规;长加 X、宽加 X、高加 X(X 为尺寸增加值),体积(CBM) = 外径长 × 外径宽 × 外径高 ÷ 1,000,000

- +
箱规类型内径长(cm)内径宽(cm)内径高(cm)外边加宽(cm)备注
箱规类型内径长(cm)内径宽(cm)内径高(cm)尺寸增加值(cm)备注
{{ row.boxTypeName }}
diff --git a/src/modules/unified-orders/pages/UnifiedOrdersView.test.ts b/src/modules/unified-orders/pages/UnifiedOrdersView.test.ts index fbc766b8..d9fc1df2 100644 --- a/src/modules/unified-orders/pages/UnifiedOrdersView.test.ts +++ b/src/modules/unified-orders/pages/UnifiedOrdersView.test.ts @@ -336,6 +336,7 @@ describe('UnifiedOrdersView contract', () => { it('shows the matched dimension addition and enabled multiplier in calculation choices', () => { expect(source).toContain('getCustomerDimensionConfig') expect(source).toContain('matchingDimensionRule') + expect(source).toContain('|| rules[rules.length - 1]') expect(source).toContain('`原尺寸 + ${values[0]}cm`') expect(source).toContain('`原尺寸 × ${rule.lengthFactor}`') expect(source).toContain('label="箱规尺寸" value="ADD"') @@ -353,10 +354,13 @@ describe('UnifiedOrdersView contract', () => { expect(source).toContain('calculatedMeasurementRow(row, measurementSectionModes.customer, true)') expect(source).toContain('calculatedMeasurementRow(source, measurementSectionModes.outer)') expect(source).toContain('calculatedMeasurementRow(row as unknown as Record, measurementSectionModes.actual)') + expect(source).toContain("return Number(hasOuterOverride && override != null && override !== '' ? override : value)") expect(source).toContain('rawDimensions.map((value) => value + rule.edgeAdditionCm)') expect(source).toContain('matchedSpecificationCoefficient(chargeRule, calculationSource)') expect(source).toContain('listCustomerChargeRules(customerId, tenantId)') expect(source).toContain('matchedDimensions.map((value) => roundedUp(value * specificationCoefficient, 3))') + expect(source).toContain("const selectedMode: 'ADD' | 'MULTIPLY' = measurementSectionModes.outer === 'MULTIPLY'") + expect(source).toContain('? selectedMode') expect(source).not.toContain('[chargeRule.lengthFactor, chargeRule.widthFactor, chargeRule.heightFactor]') expect(source).not.toContain('column.key === \'coefficientMode\'') expect(source).not.toContain('@change="updateMeasurementCalculationMode(null, $event)"') diff --git a/src/modules/unified-orders/pages/UnifiedOrdersView.vue b/src/modules/unified-orders/pages/UnifiedOrdersView.vue index 15a070c4..81523c18 100644 --- a/src/modules/unified-orders/pages/UnifiedOrdersView.vue +++ b/src/modules/unified-orders/pages/UnifiedOrdersView.vue @@ -277,15 +277,16 @@ function sortedDimensions(row: Record) { function matchingDimensionRule(row: Record): CustomerDimensionRule | null { const measured = sortedDimensions(row) if (!measured) return null - return [...(measurementDimensionConfig.value?.rules || [])] + const rules = [...(measurementDimensionConfig.value?.rules || [])] .sort((left, right) => ( left.innerLengthCm * left.innerWidthCm * left.innerHeightCm - right.innerLengthCm * right.innerWidthCm * right.innerHeightCm )) - .find((rule) => { + if (!rules.length) return null + return rules.find((rule) => { const inner = [rule.innerLengthCm, rule.innerWidthCm, rule.innerHeightCm].sort((left, right) => right - left) return measured.every((value, index) => value <= inner[index]) - }) || null + }) || rules[rules.length - 1] } function addCoefficientLabel(row?: Record) { @@ -333,9 +334,20 @@ function calculatedMeasurementRow( mode: MeasurementCalculationMode, customerSource = false, ) { - const calculationSource = source + const outerOverrides = [source.outerLengthCm, source.outerWidthCm, source.outerHeightCm] + const hasOuterOverride = !customerSource && mode !== 'ACTUAL' + && outerOverrides.some((value) => value != null && value !== '') + const rawDimensions = [source.lengthCm, source.widthCm, source.heightCm].map((value, index) => { + const override = outerOverrides[index] + return Number(hasOuterOverride && override != null && override !== '' ? override : value) + }) + const calculationSource = { + ...source, + lengthCm: rawDimensions[0], + widthCm: rawDimensions[1], + heightCm: rawDimensions[2], + } const rule = matchingDimensionRule(calculationSource) - const rawDimensions = [Number(calculationSource.lengthCm), Number(calculationSource.widthCm), Number(calculationSource.heightCm)] if (!rawDimensions.every((value) => Number.isFinite(value) && value > 0)) return { ...source } const matchedDimensions = mode === 'ADD' && rule @@ -346,13 +358,7 @@ function calculatedMeasurementRow( ? matchedSpecificationCoefficient(chargeRule, calculationSource) : 1 const strategyDimensions = matchedDimensions.map((value) => roundedUp(value * specificationCoefficient, 3)) - const outerOverrides = [source.outerLengthCm, source.outerWidthCm, source.outerHeightCm] - const hasOuterOverride = !customerSource && mode !== 'ACTUAL' - && outerOverrides.some((value) => value != null && value !== '') - const [lengthCm, widthCm, heightCm] = strategyDimensions.map((value, index) => { - const override = outerOverrides[index] - return hasOuterOverride && override != null && override !== '' ? Number(override) : value - }) + const [lengthCm, widthCm, heightCm] = strategyDimensions const packageCount = Number(source.packageCount) const unitVolumeCbm = mode === 'ADD' && rule && !hasOuterOverride ? Math.round((lengthCm * widthCm * heightCm / 1_000_000) * 1000) / 1000 @@ -886,6 +892,12 @@ async function saveWarehouseOuterDimensions(row: Record) { ElMessage.warning('仓库修改外箱尺寸必须大于 0') return } + const selectedMode: 'ADD' | 'MULTIPLY' = measurementSectionModes.outer === 'MULTIPLY' + ? 'MULTIPLY' + : 'ADD' + const selectedChargeRuleId = selectedMode === 'MULTIPLY' + ? activeMeasurementChargeRule.value?.id || null + : null measurementOuterSavingId.value = String(row.id) try { await saveInboundMeasurementDraft(String(summary.tenantId), String(summary.inboundId), { @@ -909,8 +921,10 @@ async function saveWarehouseOuterDimensions(row: Record) { outerLengthCm: String(item.id) === String(row.id) ? dimensions[0] : item.outerLengthCm, outerWidthCm: String(item.id) === String(row.id) ? dimensions[1] : item.outerWidthCm, outerHeightCm: String(item.id) === String(row.id) ? dimensions[2] : item.outerHeightCm, - chargeRuleId: item.chargeRuleId, - coefficientMode: item.coefficientMode || 'ADD', + chargeRuleId: String(item.id) === String(row.id) ? selectedChargeRuleId : item.chargeRuleId, + coefficientMode: String(item.id) === String(row.id) + ? selectedMode + : item.coefficientMode || 'ADD', remark: item.remark, })), })