Feat: 前端改版 Web 端界面与业务作业流程
按设计稿改版登录后的全部页面,登录页与 Logo 资源未改动。 - 全局外壳:浅色侧边栏与分组菜单、左下角用户卡片、Ctrl/⌘K 搜索面板、 测试模式提示条、深色模式配色、窄屏适配 - 共用组件:页头 PageHeader、托盘流程条 FlowStepper、扫码反馈 ScanFeedback、 缩短单号 DocNo、托盘档案链接 PalletCodeLink、图标 SfIcon、上级资料选择 MasterRefSelect,以及编号段解析等工具 - 工作台重做;新增托盘档案页;托盘追溯增加单托盘入口,报表托盘号可跳转档案 - 基础资料维护:各页加指标条、名称代替 ID、详情面板;三步式批量导入预览; 分配用户对话框标注增减;7 个新增/编辑对话框统一布局 - 业务管理:发货出库、仓库入库、工厂装填、客户现场使用、退回仓库改为 列表 + 详情面板 + 全屏作业区;写入流程、幂等键与防串单逻辑保持不变 - 修复入库页扫码反馈条因同名状态变量遮蔽组件而不显示的问题,并新增契约检查 - 新增入库粘贴解析、退回、装填的行为测试与现场使用页新流程测试, 同步更新业务与工作台契约脚本 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import { test } from 'node:test'
|
||||
import { groupCodeRanges, parsePasteTokens, splitPalletCode } from '../src/utils/palletRanges.js'
|
||||
|
||||
test('托盘号拆分为前缀与末尾数字,无数字结尾时返回空', () => {
|
||||
assert.deepEqual(splitPalletCode(' TP-10501 '), { prefix: 'TP-', digits: '10501', number: 10501 })
|
||||
assert.deepEqual(splitPalletCode('PLT-007'), { prefix: 'PLT-', digits: '007', number: 7 })
|
||||
assert.equal(splitPalletCode('TP-A'), null)
|
||||
assert.equal(splitPalletCode(''), null)
|
||||
})
|
||||
|
||||
test('连续编号合并成段,乱序与重复不影响结果', () => {
|
||||
const ranges = groupCodeRanges(['TP-10503', 'TP-10501', 'TP-10502', 'TP-10502', 'TP-10520', 'TP-10521'])
|
||||
assert.deepEqual(
|
||||
ranges.map(({ label, count }) => [label, count]),
|
||||
[['TP-10501 – 10503', 3], ['TP-10520 – 10521', 2]]
|
||||
)
|
||||
})
|
||||
|
||||
test('补零位数保持连续,不同前缀与无数字托盘号单独成段', () => {
|
||||
const ranges = groupCodeRanges(['PLT-0999', 'PLT-1000', 'A-9', 'A-10', 'B-001', 'TP-X'])
|
||||
assert.deepEqual(
|
||||
ranges.map(({ label, count }) => [label, count]),
|
||||
[['A-9 – 10', 2], ['B-001', 1], ['PLT-0999 – 1000', 2], ['TP-X', 1]]
|
||||
)
|
||||
// 位数不同且带补零的编号不是同一段
|
||||
assert.equal(groupCodeRanges(['C-09', 'C-010']).length, 2)
|
||||
})
|
||||
|
||||
test('粘贴内容按换行、空格与中英文标点切分并去重', () => {
|
||||
const result = parsePasteTokens('TP-10501\nTP-10502,TP-10503、TP-10501;TP-10504 TP-10505')
|
||||
assert.deepEqual(result.codes, ['TP-10501', 'TP-10502', 'TP-10503', 'TP-10504', 'TP-10505'])
|
||||
assert.equal(result.duplicates, 1)
|
||||
assert.deepEqual(result.errors, [])
|
||||
})
|
||||
|
||||
test('区间按起始托盘号的前缀与位数展开', () => {
|
||||
assert.deepEqual(parsePasteTokens('TP-10512-10514').codes, ['TP-10512', 'TP-10513', 'TP-10514'])
|
||||
assert.deepEqual(parsePasteTokens('10512-10513').codes, ['10512', '10513'])
|
||||
assert.deepEqual(parsePasteTokens('PLT-008 ~ PLT-010').codes, ['PLT-008', 'PLT-009', 'PLT-010'])
|
||||
assert.deepEqual(parsePasteTokens('PLT-008–010').codes, ['PLT-008', 'PLT-009', 'PLT-010'])
|
||||
})
|
||||
|
||||
test('普通带连字符的托盘号不会被误当作区间', () => {
|
||||
assert.deepEqual(parsePasteTokens('TP-10501').codes, ['TP-10501'])
|
||||
// 右侧不大于左侧时不构成区间
|
||||
assert.deepEqual(parsePasteTokens('A1-0001').codes, ['A1-0001'])
|
||||
})
|
||||
|
||||
test('超长区间与无法识别的波浪号区间给出错误且不展开', () => {
|
||||
const result = parsePasteTokens('TP-1-300 TP-5~TP-3 TP-9', { rangeLimit: 200 })
|
||||
assert.deepEqual(result.codes, ['TP-9'])
|
||||
assert.equal(result.errors.length, 2)
|
||||
assert.match(result.errors[0].message, /最多 200 个/)
|
||||
assert.match(result.errors[1].message, /无法识别/)
|
||||
})
|
||||
|
||||
test('总数超过上限时截断并标记', () => {
|
||||
const result = parsePasteTokens('T-1-10', { totalLimit: 4 })
|
||||
assert.deepEqual(result.codes, ['T-1', 'T-2', 'T-3', 'T-4'])
|
||||
assert.equal(result.truncated, true)
|
||||
})
|
||||
Reference in New Issue
Block a user