diff --git a/web-admin/scripts/pl-freight-calc-reset.test.ts b/web-admin/scripts/pl-freight-calc-reset.test.ts new file mode 100644 index 000000000..8300b8f03 --- /dev/null +++ b/web-admin/scripts/pl-freight-calc-reset.test.ts @@ -0,0 +1,91 @@ +import assert from 'node:assert/strict' +import { existsSync, readFileSync } from 'node:fs' +import test from 'node:test' +import ts from 'typescript' +import * as vue from 'vue' + +function loadFreightCalc() { + const path = new URL('../src/composables/usePlFreightCalc.ts', import.meta.url) + assert.ok(existsSync(path), 'usePlFreightCalc must exist') + const source = readFileSync(path, 'utf8') + const ast = ts.createSourceFile('usePlFreightCalc.ts', source, ts.ScriptTarget.Latest, true) + const code = ast.statements + .filter((node) => !ts.isImportDeclaration(node)) + .map((node) => node.getText(ast)) + .join('\n') + const compiled = ts.transpileModule(code, { + compilerOptions: { target: ts.ScriptTarget.ES2022, module: ts.ModuleKind.CommonJS } + }).outputText + const module = { exports: {} as Record } + const requireStub = () => { + throw new Error('unexpected require in freight calc test harness') + } + // eslint-disable-next-line no-new-func + const factory = new Function( + 'exports', + 'require', + 'module', + '__filename', + '__dirname', + 'computed', + 'ref', + 'watch', + compiled + '\nmodule.exports = { usePlFreightCalc, sumProductActualQuantities };' + ) + factory( + module.exports, + requireStub, + module, + 'usePlFreightCalc.ts', + '.', + vue.computed, + vue.ref, + vue.watch + ) + return module.exports as { + usePlFreightCalc: typeof import('../src/composables/usePlFreightCalc').usePlFreightCalc + } +} + +test('resetFreightCalc re-sums transport qty from existing product actuals', async () => { + const { usePlFreightCalc } = loadFreightCalc() + const products = vue.ref([{ actualQty: 0.04, unit: '吨' }, { actualQty: 0.04, unit: '吨' }]) + const hasFreight = vue.ref(1) + const freightType = vue.ref('by_weight') + + const scope = vue.effectScope() + const calc = scope.run(() => usePlFreightCalc({ products, hasFreight, freightType })) + assert.ok(calc) + await vue.nextTick() + assert.equal(calc!.transportQty.value, 0.08) + + calc!.resetFreightCalc() + await vue.nextTick() + assert.equal(calc!.transportQtyTouched.value, false) + assert.equal( + calc!.transportQty.value, + 0.08, + 'reset after products already loaded must not leave transport qty empty' + ) + scope.stop() +}) + +test('resetFreightCalc restores product sum after manual transport qty edit', async () => { + const { usePlFreightCalc } = loadFreightCalc() + const products = vue.ref([{ actualQty: 0.04, unit: '吨' }]) + const hasFreight = vue.ref(1) + const freightType = vue.ref('by_weight') + + const scope = vue.effectScope() + const calc = scope.run(() => usePlFreightCalc({ products, hasFreight, freightType })) + assert.ok(calc) + await vue.nextTick() + + calc!.transportQty.value = 9.9 + calc!.markTransportQtyTouched() + calc!.resetFreightCalc() + await vue.nextTick() + assert.equal(calc!.transportQtyTouched.value, false) + assert.equal(calc!.transportQty.value, 0.04) + scope.stop() +}) diff --git a/web-admin/src/composables/usePlFreightCalc.ts b/web-admin/src/composables/usePlFreightCalc.ts index b30c9d724..91be7f256 100644 --- a/web-admin/src/composables/usePlFreightCalc.ts +++ b/web-admin/src/composables/usePlFreightCalc.ts @@ -86,11 +86,13 @@ export function usePlFreightCalc(options: { ) function resetFreightCalc() { - transportQty.value = null transportQtyTouched.value = false freightAmount.value = null freightAmountTouched.value = false freightPrice.value = null + // 产品已加载时 watch 不会因 reset 重跑;须立即按当前实际数量回填, + // 否则归档弹窗再次打开会误报「运输量须大于0」。 + transportQty.value = defaultTransportQty.value || null } function markTransportQtyTouched() {