用户反馈:在库待匹配列表点「手动匹配订单」没有反应。 根因:上一批把手动匹配弹窗挂到了「编辑寄售物品」弹窗**内部**,外层弹窗未打开时 该组件根本没被挂载,点击只改状态、界面无变化。 - 弹窗移到面板顶层(与其它弹窗同级),点击即弹 - 新增静态守卫测试:断言手动匹配弹窗前面不能有未闭合的 Modal(即不能嵌在别的弹窗里)、 按钮必须真的 setState、open 由该状态驱动;已验证该守卫能拦下错误写法 - 顺带补入口缺口:订单侧原先只在"检测到系统候选"的提醒弹窗里给入口,订单没有任何候选时 反而进不去手动匹配 —— 工单行内新增常驻「手动匹配现货」(仅待指派/待补资料, 与后端前置校验同口径) - 已暂停匹配的现货点按钮会直接 409,改为按钮禁用并提示先打开「允许匹配」开关 - destroyOnClose → antd 6 的 destroyOnHidden(前者已废弃) 验证:前端 typecheck/lint/format/48 例测试/build 全过。
47 lines
2.0 KiB
TypeScript
47 lines
2.0 KiB
TypeScript
import assert from 'node:assert/strict'
|
|
import { readFileSync } from 'node:fs'
|
|
import test from 'node:test'
|
|
|
|
/**
|
|
* 手动匹配弹窗曾经被插到「编辑寄售物品」弹窗**内部**,导致外层弹窗没打开时它根本没挂载:
|
|
* 用户点「手动匹配订单」什么都不会发生。这类"点了没反应"的问题在浏览器里才看得出来,
|
|
* 这里用静态检查把它钉住:组件必须挂在顶层(前面不能有未闭合的 Modal)。
|
|
*/
|
|
function assertTopLevelMount(filePath: string, componentName: string) {
|
|
const source = readFileSync(filePath, 'utf8')
|
|
const index = source.indexOf(`<${componentName}`)
|
|
assert.ok(index > 0, `${filePath} 里找不到 ${componentName} 的挂载点`)
|
|
|
|
const before = source.slice(0, index)
|
|
const opened = (before.match(/<Modal[\s>]/g) || []).length
|
|
const closed = (before.match(/<\/Modal>/g) || []).length
|
|
assert.equal(
|
|
opened - closed,
|
|
0,
|
|
`${componentName} 必须挂在顶层:不能嵌在别的 Modal 里,否则外层弹窗未打开时它不会渲染`,
|
|
)
|
|
}
|
|
|
|
test('库存面板:手动匹配订单弹窗挂在顶层(按钮点了必须能弹出来)', () => {
|
|
assertTopLevelMount(
|
|
new URL('../src/pages/admin/panels/ConsignmentInventoryPanel.tsx', import.meta.url).pathname,
|
|
'ConsignmentManualMatchModal',
|
|
)
|
|
})
|
|
|
|
test('订单面板:手动指定现货弹窗同样挂在顶层', () => {
|
|
assertTopLevelMount(
|
|
new URL('../src/pages/admin/panels/WorkOrdersPanel.tsx', import.meta.url).pathname,
|
|
'ConsignmentManualMatchModal',
|
|
)
|
|
})
|
|
|
|
test('按钮点击要真的把状态设上,弹窗的 open 由该状态驱动', () => {
|
|
const source = readFileSync(
|
|
new URL('../src/pages/admin/panels/ConsignmentInventoryPanel.tsx', import.meta.url).pathname,
|
|
'utf8',
|
|
)
|
|
assert.ok(source.includes('setManualMatchItem(record)'), '行内按钮必须设置待匹配的现货')
|
|
assert.ok(source.includes('open={Boolean(manualMatchItem)}'), '弹窗 open 必须由该状态驱动')
|
|
})
|