515 lines
24 KiB
Markdown
515 lines
24 KiB
Markdown
# 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 ERP,2 人工',
|
||
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} <= 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` 或其他无关改动。
|