Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ba62ec7b36 | ||
|
|
579285a7bf | ||
|
|
f41e47601d |
No files matched your search
@@ -25,6 +25,20 @@ test('incomplete certificate filter is sent as quotaCertWaivedIn=0', () => {
|
||||
assert.deepEqual(params, { quotaCertWaivedIn: '0' })
|
||||
})
|
||||
|
||||
test('fulfill tab selection column is first among table columns', () => {
|
||||
const web = readFileSync(new URL('../src/views/pl/cert-ready/index.vue', import.meta.url), 'utf8')
|
||||
const selectionIdx = web.indexOf('type="selection"')
|
||||
const columnsIdx = web.indexOf('v-for="column in columns"')
|
||||
const actionsIdx = web.indexOf('label="操作"')
|
||||
assert.ok(selectionIdx > 0, 'selection column missing')
|
||||
assert.ok(columnsIdx > selectionIdx, 'selection must precede business columns')
|
||||
assert.ok(actionsIdx > columnsIdx, 'actions must follow business columns')
|
||||
assert.match(
|
||||
web,
|
||||
/v-if="listMode === 'fulfill'"[\s\S]*?type="selection"[\s\S]*?v-for="column in columns"/
|
||||
)
|
||||
})
|
||||
|
||||
test('web funnel and miniprogram status dropdown default to incomplete', () => {
|
||||
const web = readFileSync(new URL('../src/views/pl/cert-ready/index.vue', import.meta.url), 'utf8')
|
||||
const mobile = readFileSync(
|
||||
|
||||
@@ -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<string, unknown> }
|
||||
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()
|
||||
})
|
||||
@@ -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() {
|
||||
|
||||
@@ -50,6 +50,14 @@
|
||||
class="list-table"
|
||||
@selection-change="onSelectionChange"
|
||||
>
|
||||
<el-table-column
|
||||
v-if="listMode === 'fulfill'"
|
||||
type="selection"
|
||||
width="48"
|
||||
align="center"
|
||||
header-align="center"
|
||||
:reserve-selection="false"
|
||||
/>
|
||||
<el-table-column
|
||||
v-for="column in columns"
|
||||
:key="column.prop"
|
||||
@@ -93,12 +101,6 @@
|
||||
<span v-else>{{ row[column.prop] || '—' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
v-if="listMode === 'fulfill'"
|
||||
type="selection"
|
||||
width="48"
|
||||
:reserve-selection="false"
|
||||
/>
|
||||
<el-table-column label="操作" min-width="260" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<template v-if="listMode === 'fulfill'">
|
||||
|
||||
Reference in new issue
Block a user