Files
ShiErFeng/shierfeng-fastapi-frontend/scripts/filling-dates.test.mjs
T
yujiangandClaude Opus 5.5 167df4adb8 Feat: 前端改版 Web 端界面与业务作业流程
按设计稿改版登录后的全部页面,登录页与 Logo 资源未改动。

- 全局外壳:浅色侧边栏与分组菜单、左下角用户卡片、Ctrl/⌘K 搜索面板、
  测试模式提示条、深色模式配色、窄屏适配
- 共用组件:页头 PageHeader、托盘流程条 FlowStepper、扫码反馈 ScanFeedback、
  缩短单号 DocNo、托盘档案链接 PalletCodeLink、图标 SfIcon、上级资料选择
  MasterRefSelect,以及编号段解析等工具
- 工作台重做;新增托盘档案页;托盘追溯增加单托盘入口,报表托盘号可跳转档案
- 基础资料维护:各页加指标条、名称代替 ID、详情面板;三步式批量导入预览;
  分配用户对话框标注增减;7 个新增/编辑对话框统一布局
- 业务管理:发货出库、仓库入库、工厂装填、客户现场使用、退回仓库改为
  列表 + 详情面板 + 全屏作业区;写入流程、幂等键与防串单逻辑保持不变
- 修复入库页扫码反馈条因同名状态变量遮蔽组件而不显示的问题,并新增契约检查
- 新增入库粘贴解析、退回、装填的行为测试与现场使用页新流程测试,
  同步更新业务与工作台契约脚本

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 05:03:22 -07:00

68 lines
3.2 KiB
JavaScript

import assert from 'node:assert/strict'
import { readFile } from 'node:fs/promises'
import vm from 'node:vm'
import { test } from 'node:test'
import { computed, reactive, ref, toRefs, watch, nextTick } from 'vue'
// 执行真实页面的 setup 与提交方法;只替代网络和运行平台边界。
async function fillingPage(platform) {
const source = await readFile(new URL(platform === 'pc'
? '../src/views/business/filling/index.vue'
: '../../shierfeng-fastapi-app/src/pages/business/filling/index.vue', import.meta.url), 'utf8')
const script = source.match(/<script\b[^>]*>([\s\S]*?)<\/script>/)[1]
.replace(/^import[\s\S]*?from\s+['"][^'"]+['"];?\s*$/gm, '')
const submissions = []
let key = 0
const proxy = {
$auth: { hasPermi: () => true, hasPermiAnd: () => true },
$refs: { fillingRef: { validate: callback => callback(true), clearValidate() {} } },
$modal: { msgSuccess() {} },
resetForm() {},
}
const context = vm.createContext({
computed, reactive, ref, toRefs, watch,
getCurrentInstance: () => ({ proxy }),
useUserStore: () => ({ admin: true }), useTestBatchStore: () => ({ isTestMode: false }),
onShow() {}, createIdempotencyKey: () => `date-command-${++key}`,
listFilling: async () => ({ rows: [], total: 0 }),
listFillingBatches: async () => ({ rows: [], total: 0 }),
getFillingSummary: async () => ({ data: null }),
getFillingBatchDetail: async () => ({ data: null }),
addFilling: async payload => { submissions.push(payload); throw new Error('网络暂不可用') },
})
vm.runInContext(`${script}\nglobalThis.page = {form, scannedPallet, submitFilling, formError};`, context)
const page = context.page
const form = platform === 'pc' ? page.form.value : page.form
Object.assign(form, { qrToken: 'qr-1', warehouseId: 1, strainId: 1, batchNo: 'B-1', packageSpec: '标准包', initialPackages: 100 })
page.scannedPallet.value = { palletId: 1, capacityPackages: 100 }
await nextTick()
return { page, form, submissions }
}
for (const platform of ['pc', 'app']) {
test(`${platform} 装填提交保留来源日期,失败后重试复用幂等键`, async () => {
const { page, form, submissions } = await fillingPage(platform)
Object.assign(form, { productionDate: '2026-10-01', expiryDate: '2027-03-31' })
await nextTick()
page.submitFilling()
await new Promise(resolve => setImmediate(resolve))
assert.equal(submissions.length, 1)
assert.equal(submissions[0].productionDate, '2026-10-01')
assert.equal(submissions[0].expiryDate, '2027-03-31')
page.submitFilling()
await new Promise(resolve => setImmediate(resolve))
assert.equal(submissions[1].idempotencyKey, submissions[0].idempotencyKey)
})
test(`${platform} 装填日期缺失或倒置时不发送请求`, async () => {
const { page, form, submissions } = await fillingPage(platform)
for (const dates of [{ productionDate: '', expiryDate: '' }, { productionDate: '2026-10-02', expiryDate: '2026-10-01' }]) {
Object.assign(form, dates)
page.submitFilling()
await new Promise(resolve => setImmediate(resolve))
assert.equal(submissions.length, 0)
assert.ok(page.formError.value)
}
})
}