const fs = require('fs') const path = require('path') const root = path.resolve(__dirname, '..') function read(file) { return fs.readFileSync(path.join(root, file), 'utf8') } function assertMatch(name, content, pattern) { if (!pattern.test(content)) { throw new Error(name) } } function assertOrder(name, content, markers) { let cursor = -1 for (const marker of markers) { const index = content.indexOf(marker) if (index === -1 || index <= cursor) { throw new Error(name) } cursor = index } } const inJob = read('ruoyi-ui/src/views/in/job/index.vue') assertMatch( '入库作业页面必须加载入库任务类型字典', inJob, /dicts:\s*\[[^\]]*['"]in_job_type['"][^\]]*\]/ ) assertMatch( '任务状态列必须使用任务状态字典渲染', inJob, /label="任务状态"[\s\S]*dict\.type\.mydo_job_status[\s\S]*scope\.row\.status/ ) assertMatch( '任务类型列必须使用入库任务类型字典渲染', inJob, /label="任务类型"[\s\S]*dict\.type\.in_job_type[\s\S]*scope\.row\.inOrOut/ ) assertMatch( '手动作废和手动完成按钮必须按选中作业终态统一禁用', inJob, /:disabled="!canOperateSelectedJob"[\s\S]*:disabled="!canOperateSelectedJob"/ ) assertMatch( '终态状态必须包含已完成和已作废', inJob, /return\s+\['4',\s*'5'\]\.includes\(String\(status\)\)/ ) const stationPoint = read('ruoyi-ui/src/views/bas/stationpoint/index.vue') assertMatch( '点位配置弹窗点位类型下拉必须与其他控件等宽', stationPoint, /v-model="form\.pointType"[^>]*style="width:\s*100%"/ ) const bindTray = read('pda/pages/warehouse/inbound/bindTray.vue') assertOrder( 'PDA 入库点位选择必须放在托盘号下面', bindTray, ['仓库', '托盘号', '入库点位'] ) assertMatch( 'PDA 必须在仓库和托盘号不完整时提示先选择仓库并扫描托盘号', bindTray, /请先选择仓库和扫描托盘号/ ) assertMatch( 'PDA 仓库和托盘号完整后必须提示扫描入库点位', bindTray, /请扫描入库点位/ ) assertMatch( 'PDA 绑盘并生成作业成功后必须清空托盘号和已绑定物料', bindTray, /resetBindPayload\(\)[\s\S]*this\.trayCode\s*=\s*''[\s\S]*this\.items\s*=\s*\[\]/ ) const pdaService = read('ruoyi-admin/src/main/java/com/ruoyi/pda/service/impl/PdaServiceImpl.java') assertMatch( '入库作业生成后必须兜底写入初始状态 1 和执行阶段 0', pdaService, /setStatus\("1"\)[\s\S]*setExecutionPhase\("0"\)/ ) assertMatch( '入库 WCS 下发成功后必须写入状态 3 和执行阶段 1', pdaService, /setStatus\("3"\)[\s\S]*setExecutionPhase\("1"\)/ ) assertMatch( '入库作业生成后必须补写仓库名称', pdaService, /selectBasWarehouseByWarehouseId[\s\S]*setWarehouseName/ ) const mydoJobMapper = read('ruoyi-admin/src/main/resources/mapper/in/MydoJobMapper.xml') assertMatch( '作业列表查询必须在 warehouse_name 为空时按 warehouse_id 兜底显示仓库名称', mydoJobMapper, /isnull\(nullif\(warehouse_name,\s*''\),\s*\(select top 1 bw\.warehouse_name/ ) const mydoJobService = read('ruoyi-admin/src/main/java/com/ruoyi/in/job/service/impl/MydoJobServiceImpl.java') assertMatch( '共用 WCS 推送成功后必须写入状态 3 和执行阶段 1', mydoJobService, /pushOutJobToWcs[\s\S]*setStatus\("3"\)[\s\S]*setExecutionPhase\("1"\)/ ) const sql = read('sql/20260624_update_job_dicts.sql') assertMatch('SQL 脚本必须包含正执行状态字典', sql, /正执行/) assertMatch('SQL 脚本必须包含生成作业执行阶段字典', sql, /生成作业/) assertMatch('SQL 脚本必须包含下发到WCS执行阶段字典', sql, /下发到WCS/) console.log('Inbound job fix checks passed')