Files
huachuang/docs/superpowers/plans/2026-08-14-lms-daily-plan.md

515 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# LMS 日计划管理实现计划
> **面向 AI 代理的工作者:** 必需子技能:使用 superpowers:subagent-driven-development推荐或 superpowers:executing-plans 逐任务实现此计划。步骤使用复选框(`- [ ]`)语法来跟踪进度。
**目标:** 在 LMS 中实现 ERP/人工日计划、独立的查询维护与作业页面、订单/备货/套管状态机、顺序与权重策略,以及供后续定时器调用的调度查询和进度更新能力。
**架构:** 后端按 `dailyplan` 业务包组织,日计划、策略、操作日志分别映射独立表并使用 Mapper XML。管理端接口、ERP 推送接口和内部调度能力共用 `DailyPlanService` 状态机,所有状态及数量变更使用事务和版本号。前端使用两个同级动态菜单页面,共用同一 API 类型和详情组件。
**技术栈:** Java 17、Spring Boot、Spring Security、MyBatis/MyBatis-Plus 分页、MySQL、EasyTrans、Vue 3、TypeScript、Vben Admin、Ant Design Vue Next、VXE Table。
---
## 文件结构
### 数据库与公共常量
- 创建 `sql/mysql/lms_daily_plan.sql`:三张业务表、编码规则、字典和初始策略。
- 创建 `sql/mysql/lms_daily_plan_menu.sql`:两个菜单及按钮权限。
- 创建 `nl-module-lms/nl-module-lms-api/src/main/java/cn/code/nl/module/lms/enums/DailyPlanSourceTypeEnum.java`:来源枚举。
- 创建 `nl-module-lms/nl-module-lms-api/src/main/java/cn/code/nl/module/lms/enums/DailyPlanOrderStatusEnum.java`:订单状态枚举。
- 创建 `nl-module-lms/nl-module-lms-api/src/main/java/cn/code/nl/module/lms/enums/DailyPlanWorkStatusEnum.java`:备货/套管状态枚举。
- 创建 `nl-module-lms/nl-module-lms-api/src/main/java/cn/code/nl/module/lms/enums/DailyPlanStrategyModeEnum.java`:策略模式枚举。
- 创建 `nl-module-lms/nl-module-lms-api/src/main/java/cn/code/nl/module/lms/enums/DailyPlanStrategyTypeEnum.java`:策略业务类型枚举。
- 修改 `nl-module-lms/nl-module-lms-api/src/main/java/cn/code/nl/module/lms/enums/ErrorCodeConstants.java`:日计划业务错误码。
### 后端
- 创建 `nl-module-lms/nl-module-lms-server/src/main/java/cn/code/nl/module/lms/dal/dataobject/dailyplan/DailyPlanDO.java`:主表映射。
- 创建 `.../dailyplan/DailyPlanStrategyDO.java`:策略表映射。
- 创建 `.../dailyplan/DailyPlanOperationLogDO.java`:操作日志表映射。
- 创建 `.../dal/mysql/dailyplan/DailyPlanMapper.java``src/main/resources/mapper/dailyplan/DailyPlanMapper.xml`:主表查询和原子更新。
- 创建 `.../dal/mysql/dailyplan/DailyPlanStrategyMapper.java` 和对应 XML策略查询、切换及游标更新。
- 创建 `.../dal/mysql/dailyplan/DailyPlanOperationLogMapper.java` 和对应 XML日志追加与分页查询。
- 创建 `.../controller/admin/dailyplan/vo/*.java`:管理、作业和操作请求/响应 VO。
- 创建 `.../controller/erp/dailyplan/vo/ErpDailyPlanPushReqVO.java`ERP 推送请求。
- 创建 `.../service/dailyplan/DailyPlanService.java``DailyPlanServiceImpl.java`:状态机和事务。
- 创建 `.../service/dailyplan/DailyPlanScheduleService.java``DailyPlanScheduleServiceImpl.java`:定时器候选和进度更新。
- 创建 `.../controller/admin/dailyplan/DailyPlanController.java`:管理与作业接口。
- 创建 `.../controller/erp/dailyplan/ErpDailyPlanController.java`ERP 推送接口。
- 修改 `.../framwork/security/config/SecurityConfiguration.java`:放行 ERP 路径,由控制器校验独立令牌。
- 修改 `.../framwork/rpc/config/RpcConfiguration.java`:注册 `CodeGenApi`
- 修改 `nl-module-lms/nl-module-lms-server/src/main/resources/application-*.yaml`:仅增加配置键引用;实际令牌由 Nacos 环境配置。
### 前端
- 创建 `nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/api/lms/dailyplan/index.ts`API 类型和请求。
- 创建 `.../src/views/lms/dailyplan/index.vue``data.ts`:日计划管理页。
- 创建 `.../src/views/lms/dailyplan/modules/form.vue`:人工新增/编辑抽屉。
- 创建 `.../src/views/lms/dailyplan/modules/start-order.vue`:开始订单弹窗。
- 创建 `.../src/views/lms/dailyplan/modules/detail.vue`:共享详情与操作日志抽屉。
- 创建 `.../src/views/lms/dailyplanwork/index.vue``data.ts`:日计划作业页。
- 创建 `.../src/views/lms/dailyplanwork/modules/operation.vue`:追加、取消、恢复等操作弹窗。
- 创建 `.../src/views/lms/dailyplanwork/modules/strategy.vue`:策略切换弹窗。
- 创建 `.../src/views/lms/dailyplanwork/modules/sort.vue`:批量顺序调整弹窗。
- 修改 `nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/packages/constants/src/dict-enum.ts`:字典编码。
## 任务 1建立数据库、字典、编码规则和菜单
- [ ] **步骤 1创建业务表脚本**
`sql/mysql/lms_daily_plan.sql` 创建:
```sql
CREATE TABLE lms_daily_plan (
daily_plan_id BIGINT NOT NULL COMMENT '日计划标识',
plan_code VARCHAR(32) NOT NULL COMMENT '日计划编号',
source_type TINYINT NOT NULL COMMENT '来源类型1 ERP2 人工',
erp_order_code VARCHAR(64) NULL COMMENT 'ERP订单号',
manual_order_code VARCHAR(64) NULL COMMENT '人工订单号',
plan_date DATE NOT NULL COMMENT '计划日期',
material_id BIGINT NOT NULL COMMENT '管芯物料标识',
material_code VARCHAR(64) NOT NULL COMMENT '管芯物料编码',
material_name VARCHAR(128) NOT NULL COMMENT '管芯物料名称',
material_spec VARCHAR(128) NULL COMMENT '管芯规格',
plan_qty INT NOT NULL COMMENT '计划数量',
append_qty INT NOT NULL DEFAULT 0 COMMENT '追加数量',
stocked_qty INT NOT NULL DEFAULT 0 COMMENT '已备货数量',
sleeved_qty INT NOT NULL DEFAULT 0 COMMENT '已套管数量',
packing_info TEXT NULL COMMENT '装箱信息',
sort_seq INT NOT NULL COMMENT '顺序号',
weight INT NOT NULL DEFAULT 1 COMMENT '权重',
order_status TINYINT NOT NULL DEFAULT 0 COMMENT '订单状态',
stocking_status TINYINT NOT NULL DEFAULT 0 COMMENT '备货状态',
sleeving_status TINYINT NOT NULL DEFAULT 0 COMMENT '套管状态',
previous_order_status TINYINT NULL COMMENT '取消前订单状态',
previous_stocking_status TINYINT NULL COMMENT '取消前备货状态',
previous_sleeving_status TINYINT NULL COMMENT '取消前套管状态',
order_start_time DATETIME NULL,
order_end_time DATETIME NULL,
stocking_start_time DATETIME NULL,
stocking_complete_time DATETIME NULL,
sleeving_start_time DATETIME NULL,
sleeving_complete_time DATETIME NULL,
version INT NOT NULL DEFAULT 0 COMMENT '版本号',
creator VARCHAR(64) NULL,
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updater VARCHAR(64) NULL,
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted BIT(1) NOT NULL DEFAULT b'0',
tenant_id BIGINT NOT NULL DEFAULT 0,
PRIMARY KEY (daily_plan_id),
UNIQUE KEY uk_lms_daily_plan_code (plan_code, tenant_id),
UNIQUE KEY uk_lms_daily_plan_erp_order (erp_order_code, tenant_id)
) COMMENT='LMS日计划';
```
同一脚本创建 `lms_daily_plan_strategy``lms_daily_plan_operation_log`。策略表以 `(strategy_type, tenant_id)` 唯一,包含 `strategy_mode``cursor_daily_plan_id``version` 和审计字段;日志表包含操作对象、操作类型、前值、后值、数量变化、原因和审计字段。
- [ ] **步骤 2初始化编码规则和字典**
幂等写入编码规则 `LMS_DAILY_PLAN_CODE`,段配置生成 `DPyyyyMMdd0001`。幂等写入以下字典:
```text
lms_daily_plan_source_type: 1 ERP, 2 人工
lms_daily_plan_order_status: 0 未开始, 1 进行中, 2 已结束, 3 已取消
lms_daily_plan_work_status: 0 未开始, 1 进行中, 2 已完成, 3 已取消
lms_daily_plan_strategy_mode: 1 顺序模式, 2 权重轮转
```
为每个现有租户幂等初始化备货、套管两条顺序模式策略。
- [ ] **步骤 3创建菜单权限脚本**
`sql/mysql/lms_daily_plan_menu.sql` 下将两个 type=2 菜单挂到 `tube-library`
```text
日计划管理 -> lms/dailyplan/index
日计划作业 -> lms/dailyplanwork/index
```
创建权限:
```text
lms:daily-plan:query
lms:daily-plan:create
lms:daily-plan:update
lms:daily-plan:start
lms:daily-plan:operate
lms:daily-plan:schedule
lms:daily-plan:strategy
```
脚本按路径、组件和权限编码幂等,并为已授权子菜单的角色补齐“管芯库管理”父目录权限。
- [ ] **步骤 4验证 SQL**
运行:
```bash
MYSQL_PWD=root /usr/local/mysql/bin/mysql --protocol=TCP -h 127.0.0.1 -P 3306 -u root -D huachuang_lms_dev -e "SOURCE sql/mysql/lms_daily_plan.sql; SOURCE sql/mysql/lms_daily_plan_menu.sql;"
```
连续执行两次,预期无重复键错误;查询三张表、字典、编码规则和菜单,预期每项只有一份有效数据。
- [ ] **步骤 5提交数据库基线**
```bash
git add sql/mysql/lms_daily_plan.sql sql/mysql/lms_daily_plan_menu.sql
git commit -m "feat: 初始化LMS日计划数据结构"
```
## 任务 2建立枚举、数据对象和错误码
- [ ] **步骤 1创建五个业务枚举**
枚举使用 `Integer code``getByCode`。状态码严格使用任务 1 的字典值。例如:
```java
public enum DailyPlanOrderStatusEnum {
NOT_STARTED(0), IN_PROGRESS(1), FINISHED(2), CANCELED(3);
private final Integer code;
public static DailyPlanOrderStatusEnum getByCode(Integer code) {
for (DailyPlanOrderStatusEnum value : values()) {
if (value.code.equals(code)) {
return value;
}
}
return null;
}
}
```
- [ ] **步骤 2创建三个 DO**
`DailyPlanDO` 继承 `TenantBaseDO`(若 LMS 当前公共基类只支持 `BaseDO`,则显式增加 `tenantId`),字段与 DDL 一一对应;主键使用 `@TableId`。策略和日志 DO 同样只表达表结构,不加入业务方法。
- [ ] **步骤 3增加错误码**
`ErrorCodeConstants` 增加日计划不存在、ERP 订单重复/终态不可更新、ERP 数量减少、非法状态流转、数量超限、版本冲突、策略不存在、顺序或权重非法、取消/恢复原因缺失、ERP 令牌错误。
- [ ] **步骤 4编译 API 和 Server**
```bash
./mvnw -pl nl-module-lms/nl-module-lms-server -am -DskipTests compile
```
预期 `BUILD SUCCESS`
- [ ] **步骤 5提交基础模型**
```bash
git add nl-module-lms/nl-module-lms-api/src/main/java/cn/code/nl/module/lms/enums \
nl-module-lms/nl-module-lms-server/src/main/java/cn/code/nl/module/lms/dal/dataobject/dailyplan
git commit -m "feat: 增加LMS日计划领域模型"
```
## 任务 3实现 Mapper XML 与并发更新
- [ ] **步骤 1实现日计划查询**
`DailyPlanMapper` 提供:
```java
PageResult<DailyPlanDO> selectManagementPage(DailyPlanPageReqVO reqVO);
PageResult<DailyPlanDO> selectWorkPage(DailyPlanWorkPageReqVO reqVO);
DailyPlanDO selectById(Long dailyPlanId);
DailyPlanDO selectByErpOrderCode(String erpOrderCode);
List<DailyPlanDO> selectStockingCandidates();
List<DailyPlanDO> selectSleevingCandidates();
```
所有查询写入 `DailyPlanMapper.xml`。管理分页默认 `plan_date DESC, sort_seq ASC, daily_plan_id DESC`;作业分页限定进行中或指定的已取消页签,不限制日期,按 `sort_seq ASC, daily_plan_id ASC`
- [ ] **步骤 2实现受控写入**
XML 提供 `insertDailyPlan``updateNotStartedPlan``updateStateWithVersion``updateSortWithVersion``updateWeightWithVersion` 和两个基于 Claim 的原子进度方法。页面写操作使用日计划版本;调度进度以 Claim 令牌及领取时对应作业进度作为并发边界:
```sql
UPDATE lms_daily_plan
SET stocked_qty = stocked_qty + #{incrementQty},
stocking_status = CASE
WHEN stocking_status = 1 AND stocked_qty + #{incrementQty} = plan_qty + append_qty THEN 2
ELSE stocking_status
END,
version = version + 1,
updater = #{updater}
WHERE daily_plan_id = #{dailyPlanId}
AND stocked_qty = #{claimProgressQty}
AND stocked_qty + #{incrementQty} &lt;= plan_qty + append_qty
```
套管方法使用独立的 `sleeved_qty` 快照约束。排序、权重、ERP 追加和另一作业进度引起的日计划版本变化不影响确认。取消或结束只阻止新领取,已有有效 Claim 仍允许累计数量,且 SQL 不覆盖用户选择的取消或结束状态。受影响行数不是 1 时由 Service 区分进度冲突或数量超限。
- [ ] **步骤 3实现策略与日志 Mapper**
策略 XML 提供按业务类型查询、版本切换模式、版本更新游标。日志 XML 提供插入和按日计划 ID、操作时间倒序查询。
- [ ] **步骤 4编译检查 Mapper 签名**
运行 Maven compile预期 Mapper XML 可解析且无 `Invalid bound statement` 的构建期问题。
- [ ] **步骤 5提交持久层**
```bash
git add nl-module-lms/nl-module-lms-server/src/main/java/cn/code/nl/module/lms/dal/mysql/dailyplan \
nl-module-lms/nl-module-lms-server/src/main/resources/mapper/dailyplan
git commit -m "feat: 实现LMS日计划持久层"
```
## 任务 4实现请求响应模型和日计划状态机
- [ ] **步骤 1创建查询和响应 VO**
创建管理分页、作业分页、详情、操作日志和策略响应。`DailyPlanRespVO` 实现 EasyTrans `VO``dailyPlanId` 标注 `@TableId`,修改人按现有备货区域模式翻译为 `updaterName`
- [ ] **步骤 2创建写入请求 VO**
创建人工新增、更新、开始订单、追加数量、原因操作、批量顺序、权重、策略切换请求。使用 `@NotNull``@NotBlank``@Positive``@Size` 完成参数校验;所有修改请求携带 `version`
- [ ] **步骤 3实现人工创建与编辑**
`DailyPlanServiceImpl#createManualPlan` 调用 `CodeGenApi.generate` 生成 `LMS_DAILY_PLAN_CODE`。RPC 返回失败必须抛业务异常。初始三个状态为未开始,数量进度为零,权重默认 1。
编辑方法只接受人工来源且订单未开始的计划,并通过版本更新防止覆盖。
- [ ] **步骤 4实现三条状态机**
为每个业务动作实现公开 Service 方法,不暴露通用状态修改:
```java
void startOrder(DailyPlanStartReqVO reqVO);
void appendQuantity(DailyPlanAppendReqVO reqVO);
void startStocking(DailyPlanVersionReqVO reqVO);
void cancelStocking(DailyPlanReasonReqVO reqVO);
void restoreStocking(DailyPlanReasonReqVO reqVO);
void startSleeving(DailyPlanVersionReqVO reqVO);
void cancelSleeving(DailyPlanReasonReqVO reqVO);
void restoreSleeving(DailyPlanReasonReqVO reqVO);
void cancelOrder(DailyPlanReasonReqVO reqVO);
void restoreOrder(DailyPlanReasonReqVO reqVO);
void finishOrder(DailyPlanVersionReqVO reqVO);
```
每个方法先校验当前状态,再构造新的更新对象;禁止直接修改查询得到的 DO。状态更新和操作日志使用同一 `@Transactional` 事务。
- [ ] **步骤 5实现排序、权重和策略切换**
批量排序校验所有顺序为正整数且计划处于未结束状态,在一个事务内逐条版本更新;任一失败整体回滚。权重只允许正整数。策略切换分别更新备货或套管配置并清空轮转游标,立即影响下一轮调度。
- [ ] **步骤 6编译并提交状态机**
运行 Maven compile预期成功。提交 VO、Service 和 RPC 配置:
```bash
git commit -m "feat: 实现LMS日计划状态流转"
```
## 任务 5实现 ERP 幂等推送与独立鉴权
- [ ] **步骤 1定义 ERP 请求**
`ErpDailyPlanPushReqVO` 包含 ERP 订单号、计划日期、物料 ID/编码/名称/规格、计划数量和装箱信息,数量使用 `@Positive`
- [ ] **步骤 2实现幂等推送**
`pushErpDailyPlan` 使用 ERP 订单号查询:
```text
不存在 -> 新建
未开始 -> 覆盖 ERP 可维护字段
进行中且数量增加 -> 差额累计 append_qty
进行中且数量相同 -> 返回现有日计划编号
进行中且数量减少 -> 抛业务异常
已结束或已取消 -> 抛业务异常
```
创建、更新和日志在同一事务;唯一键冲突按幂等查询重新判定,不返回数据库异常文本。
- [ ] **步骤 3实现令牌鉴权**
控制器接收 `X-ERP-Token`,使用:
```java
@Value("${erp.daily-plan.token}")
private String erpDailyPlanToken;
```
令牌不匹配时抛出 ERP 令牌错误。`SecurityConfiguration` 只对 `/lms/daily-plan/erpPush` 放行登录鉴权,业务令牌仍为必填。配置文件不写真实令牌,只声明由 Nacos 提供的配置键。
- [ ] **步骤 4实现 ERP Controller**
接口路径使用驼峰:
```text
POST /lms/daily-plan/erpPush
```
返回 LMS 日计划编号,重复推送返回相同编号。
- [ ] **步骤 5编译并提交 ERP 接口**
运行 Maven compile预期成功提交请求、Controller、Service 与安全配置。
## 任务 6实现后续定时器使用的调度服务
- [ ] **步骤 1定义调度返回对象**
创建 `DailyPlanScheduleCandidate`,包含日计划 ID、计划编号、物料信息、建议处理数量、版本号、策略模式、排他 Claim 令牌和租约过期时间。版本号仅供展示审计,不作为进度确认并发边界。
- [ ] **步骤 2实现顺序模式选择**
备货或套管候选先按 `sort_seq ASC, daily_plan_id ASC` 查询。顺序模式只返回第一张可执行计划,建议数量为全部剩余数量。
- [ ] **步骤 3实现权重轮转选择**
根据策略游标从有序候选列表定位下一张;建议数量为 `min(weight, remainingQty)`。先原子创建 Claim成功后再以策略版本号更新游标到下一张计划两者同事务提交。游标无效时从顺序第一张开始。
- [ ] **步骤 4实现原子进度更新**
提供:
```java
void increaseStockedQuantity(String claimToken, Long dailyPlanId, Integer quantity, String operator);
void increaseSleevedQuantity(String claimToken, Long dailyPlanId, Integer quantity, String operator);
```
确认先锁定并原子消费 Claim再按 Claim 保存的对应作业进度快照更新数量并追加日志。备货、套管可独立并发;同一 Claim 重复确认幂等成功。更新到需求总量时,仅当该作业仍在进行中才同步写完成状态和完成时间;若用户已取消或结束则保留终态。另提供 Claim 续租、主动释放和过期回收能力。
- [ ] **步骤 5编译并提交调度能力**
运行 Maven compile提交 Schedule Service 和相关 DTO。
## 任务 7实现管理端 Controller 与前端 API
- [ ] **步骤 1实现管理端接口**
`DailyPlanController` 使用 `/lms/daily-plan`,提供 `managementPage``workPage``get``operationLogList``create``update``startOrder``appendQuantity`、三组备货/套管/订单操作、`updateSort``updateWeight``getStrategies``updateStrategy`。查询响应增加 `@TransMethodResult`
- [ ] **步骤 2绑定权限**
按照菜单脚本权限编码给每个接口增加 `@PreAuthorize`,禁止仅靠前端隐藏按钮控制权限。
- [ ] **步骤 3创建前端 API**
`src/api/lms/dailyplan/index.ts` 定义 `DailyPlan``OperationLog``Strategy` 和所有请求类型;接口路径与 Controller 驼峰方法一致。
- [ ] **步骤 4编译和类型检查**
运行 Maven compile前端运行
```bash
pnpm --filter @vben/web-antdv-next typecheck
```
- [ ] **步骤 5提交接口层**
```bash
git commit -m "feat: 增加LMS日计划管理接口"
```
## 任务 8实现“日计划管理”页面
- [ ] **步骤 1注册字典常量**
`dict-enum.ts` 增加四个 `LMS_DAILY_PLAN_*` 编码,页面统一使用 `getDictOptions``CellDict`
- [ ] **步骤 2实现查询与列表**
`dailyplan/data.ts` 查询项包括计划/订单号、日期范围、管芯、来源和订单状态。列表展示计划、ERP/人工订单、日期、管芯、需求总量、两个完成进度、三个状态、来源、修改人和修改时间。
- [ ] **步骤 3实现新增/编辑抽屉**
表单字段为计划日期、人工订单号、管芯、计划数量、装箱信息、顺序和权重。ERP 来源以及已开始计划不显示编辑入口。
- [ ] **步骤 4实现开始订单和详情**
开始订单弹窗展示原计划量、确认计划量、已有追加、本次追加和开始后总量确认计划量为必填正整数ERP 与人工来源都可在开始时确认。服务端在同一事务内原子更新计划量、累计追加量和订单状态,并分别记录数量调整、追加和开始日志。管理页为未开始订单提供填写原因的取消入口。详情抽屉展示三类状态时间和按时间倒序的操作记录。
- [ ] **步骤 5运行局部 ESLint**
```bash
node node_modules/eslint/bin/eslint.js \
apps/web-antdv-next/src/api/lms/dailyplan/index.ts \
apps/web-antdv-next/src/views/lms/dailyplan
```
- [ ] **步骤 6提交管理页面**
```bash
git commit -m "feat: 增加LMS日计划管理页面"
```
## 任务 9实现“日计划作业”页面
- [ ] **步骤 1实现进行中与已取消页签**
默认页签请求所有日期的进行中订单;已取消页签请求可恢复订单。列表始终显示顺序,展示管芯、需求总量、备货进度、套管进度和状态。
- [ ] **步骤 2实现策略联动列**
页面加载备货和套管两条策略。考虑两类策略可能不同,列表提供“备货作业”和“套管作业”视图切换;当前视图为权重模式时显示权重列,否则隐藏权重列,但顺序列始终显示。
- [ ] **步骤 3实现状态操作**
根据状态动态提供追加、开始/取消/恢复备货、开始/取消/恢复套管、取消/恢复/结束订单。取消和恢复要求原因,所有操作携带版本号,成功后刷新表格和策略。
- [ ] **步骤 4实现批量顺序和权重维护**
顺序弹窗列出当前可作业计划并允许输入正整数;权重模式下允许内联修改权重。提交冲突时展示后端提示并重新加载。
- [ ] **步骤 5实现策略切换**
备货、套管各自展示当前模式和修改时间。切换二次确认,说明“下一轮调度立即生效,已下发任务不撤销”。
- [ ] **步骤 6运行类型检查和 ESLint**
对 API、两个页面及模块运行类型检查和局部 ESLint预期无错误。
- [ ] **步骤 7提交作业页面**
```bash
git commit -m "feat: 增加LMS日计划作业页面"
```
## 任务 10执行端到端验证和收尾
- [ ] **步骤 1完整后端编译**
```bash
./mvnw -pl nl-module-lms/nl-module-lms-server -am -DskipTests compile
```
预期 `BUILD SUCCESS`
- [ ] **步骤 2完整前端检查**
运行目标应用 typecheck并对所有日计划相关 TS/Vue 文件执行 ESLint预期退出码 0。
- [ ] **步骤 3执行 SQL 幂等验证**
在本地开发库连续执行两次初始化和菜单脚本,查询确认三张表、两条策略、四组字典、两个菜单及按钮权限无重复。
- [ ] **步骤 4联调关键业务路径**
按顺序验证ERP 首推 → 重推不变 → 未开始覆盖 → 开始订单 → ERP 增量追加 → 开始备货/套管 → 调度候选查询 → 原子更新进度 → 取消/恢复 → 结束订单。另验证 ERP 减量、终态推送、数量超限和旧版本更新均返回预期业务错误。
- [ ] **步骤 5核对双页面边界**
确认管理页面可查全量但不提供现场作业按钮;作业页面不限制日期、默认只展示进行中,并通过已取消页签恢复订单;已结束订单不出现在作业页面。
- [ ] **步骤 6核对策略行为**
使用 A顺序 1、权重 2、B顺序 2、权重 3、C顺序 3、权重 1验证权重候选为 A×2 → B×3 → C×1 循环;切到顺序模式后只返回顺序第一张未完成计划。
- [ ] **步骤 7检查工作区并提交收尾**
```bash
git diff --check
git status --short
```
只提交日计划相关文件,不包含用户已有的 `nl-module-wms/img.png` 或其他无关改动。