设计文档完善状态机
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
-- ================================
|
||||
-- 出入库单据控制层(新增)
|
||||
-- 出入库单据控制层
|
||||
-- 目标:通过“单据 -> 审核 -> 执行”控制库存变更,避免直接操作出入库流水
|
||||
-- 说明:
|
||||
-- 1) 业务层先创建“出入库单”,再由单据生成实际的 gear_stock_io / gear_stock_io_detail
|
||||
-- 2) 单据状态控制提交、审核、作废与执行结果
|
||||
-- 3) 通过 source_io_id 关联已生成的实际出入库记录,确保单据可追溯
|
||||
-- 1) 业务先创建出入库单据,再由单据驱动实际 gear_stock_io / gear_stock_io_detail
|
||||
-- 2) 单据支持草稿、提交、审核、执行、作废、冲销
|
||||
-- 3) 通过关联字段保留来源单、回退单、执行单之间的链路
|
||||
-- ================================
|
||||
|
||||
DROP TABLE IF EXISTS gear_stock_io_order;
|
||||
@@ -12,13 +13,20 @@ CREATE TABLE gear_stock_io_order (
|
||||
order_code varchar(64) NOT NULL COMMENT '单据编号(唯一)',
|
||||
io_type char(1) NOT NULL COMMENT '出入库类型(I入库 O出库 T调拨)',
|
||||
biz_type varchar(32) NOT NULL COMMENT '业务类型(purchase/sale/return/transfer/other)',
|
||||
source_type varchar(32) DEFAULT '' COMMENT '来源单据类型(采购单/销售单/报工单等)',
|
||||
source_type varchar(32) DEFAULT '' COMMENT '来源单据类型(采购单/销售单/退货单/调拨单等)',
|
||||
source_no varchar(64) DEFAULT '' COMMENT '来源单据编号',
|
||||
source_order_id bigint(20) DEFAULT NULL COMMENT '来源单据ID(业务单ID)',
|
||||
warehouse_id bigint(20) DEFAULT NULL COMMENT '主仓库ID',
|
||||
from_warehouse_id bigint(20) DEFAULT NULL COMMENT '调出仓库ID',
|
||||
to_warehouse_id bigint(20) DEFAULT NULL COMMENT '调入仓库ID',
|
||||
status char(1) NOT NULL DEFAULT '0' COMMENT '单据状态(0草稿 1已提交 2已审核 3已执行 4已作废)',
|
||||
status char(1) NOT NULL DEFAULT '0' COMMENT '单据状态(0草稿 1已提交 2已审核 3已执行 4已作废 5已冲销)',
|
||||
exec_flag char(1) NOT NULL DEFAULT '0' COMMENT '执行标志(0未执行 1已执行)',
|
||||
reversal_flag char(1) NOT NULL DEFAULT '0' COMMENT '是否冲销单(0否 1是)',
|
||||
reversal_order_id bigint(20) DEFAULT NULL COMMENT '对应原单据ID',
|
||||
reversal_reason varchar(500) DEFAULT '' COMMENT '冲销原因',
|
||||
reversal_time datetime COMMENT '冲销时间',
|
||||
cancel_reason varchar(500) DEFAULT '' COMMENT '作废原因',
|
||||
cancel_time datetime COMMENT '作废时间',
|
||||
audit_by varchar(64) DEFAULT '' COMMENT '审核人',
|
||||
audit_time datetime COMMENT '审核时间',
|
||||
execute_by varchar(64) DEFAULT '' COMMENT '执行人',
|
||||
@@ -33,12 +41,15 @@ CREATE TABLE gear_stock_io_order (
|
||||
update_time datetime COMMENT '更新时间',
|
||||
PRIMARY KEY (order_id),
|
||||
UNIQUE KEY uk_order_code (order_code),
|
||||
UNIQUE KEY uk_reversal_order_id (reversal_order_id),
|
||||
KEY idx_status (status),
|
||||
KEY idx_exec_flag (exec_flag),
|
||||
KEY idx_biz_type (biz_type),
|
||||
KEY idx_source_no (source_no),
|
||||
KEY idx_source_order_id (source_order_id),
|
||||
KEY idx_create_time (create_time),
|
||||
KEY idx_source_io_id (source_io_id)
|
||||
KEY idx_source_io_id (source_io_id),
|
||||
KEY idx_reversal_flag (reversal_flag)
|
||||
) ENGINE=InnoDB COMMENT='出入库单据表';
|
||||
|
||||
DROP TABLE IF EXISTS gear_stock_io_order_detail;
|
||||
@@ -58,6 +69,7 @@ CREATE TABLE gear_stock_io_order_detail (
|
||||
unit_price decimal(18,4) NOT NULL DEFAULT 0.0000 COMMENT '单价快照',
|
||||
amount decimal(18,4) NOT NULL DEFAULT 0.0000 COMMENT '金额快照',
|
||||
source_detail_no varchar(64) DEFAULT '' COMMENT '来源明细编号',
|
||||
reversal_detail_id bigint(20) DEFAULT NULL COMMENT '对应冲销明细ID',
|
||||
remark varchar(500) DEFAULT NULL COMMENT '备注',
|
||||
del_flag char(1) NOT NULL DEFAULT '0' COMMENT '删除标志(0存在 2删除)',
|
||||
create_by varchar(64) DEFAULT '' COMMENT '创建者',
|
||||
@@ -69,11 +81,11 @@ CREATE TABLE gear_stock_io_order_detail (
|
||||
KEY idx_order_id (order_id),
|
||||
KEY idx_item_id (item_id),
|
||||
KEY idx_batch_no (batch_no),
|
||||
KEY idx_source_detail_no (source_detail_no)
|
||||
KEY idx_source_detail_no (source_detail_no),
|
||||
KEY idx_reversal_detail_id (reversal_detail_id)
|
||||
) ENGINE=InnoDB COMMENT='出入库单据明细表';
|
||||
|
||||
-- 建议补充的业务索引说明:
|
||||
-- 1) 先保存 gear_stock_io_order/gear_stock_io_order_detail 为草稿
|
||||
-- 2) 提交后进入审核
|
||||
-- 3) 审核通过后生成实际 gear_stock_io / gear_stock_io_detail,并回写 source_io_id
|
||||
-- 4) 如果需要严格防重复执行,可在业务层通过 order_code + status / source_io_id 控制幂等
|
||||
-- 建议:
|
||||
-- 1) 业务层只允许通过单据驱动库存变更,禁止直接改 gear_stock / gear_stock_log
|
||||
-- 2) 审核通过后,统一调用执行入口生成实际 gear_stock_io / gear_stock_io_detail
|
||||
-- 3) 已执行错误时,通过反向单据进行冲销,不直接修改历史流水
|
||||
|
||||
@@ -2,172 +2,299 @@
|
||||
|
||||
## 1. 背景
|
||||
|
||||
当前系统中的出入库逻辑是直接操作 `gear_stock_io` 与 `gear_stock_io_detail`,缺少“单据层”的控制,因此会出现以下问题:
|
||||
当前系统中的出入库是直接操作 `gear_stock_io` 与 `gear_stock_io_detail`,这会带来两个核心问题:
|
||||
|
||||
- 业务流程不完整,无法体现草稿、提交、审核、执行等状态
|
||||
- 直接操作库存,缺少审批与追溯能力
|
||||
- 无法与采购、销售、退货、调拨等来源单据建立统一关联
|
||||
- 事务失败、重复执行、人工误操作时难以定位责任与恢复
|
||||
- 库存变更没有“单据审批链”,无法体现业务流程
|
||||
- 出入库做错后,只能人工修库存,缺少标准回退方案
|
||||
|
||||
因此建议在现有出入库表之上新增一层“出入库单据表”,用于统一控制流程,再由单据驱动实际库存操作。
|
||||
因此建议增加一层“出入库单据”,由单据统一控制库存执行。
|
||||
|
||||
---
|
||||
|
||||
## 2. 设计目标
|
||||
|
||||
1. 先单据,后执行:所有库存变化必须先落单据
|
||||
2. 状态可追踪:支持草稿、已提交、已审核、已执行、已作废
|
||||
3. 数据可追溯:单据可关联来源业务单号与实际出入库记录
|
||||
4. 支持扩展:兼容入库、出库、调拨等场景
|
||||
5. 幂等可控:避免重复执行导致库存被重复增减
|
||||
1. 所有库存变动都先落单据
|
||||
2. 单据必须支持草稿、提交、审核、执行、作废、冲销
|
||||
3. 单据执行后自动生成实际出入库流水
|
||||
4. 做错时通过反向单据回退,不直接改历史流水
|
||||
5. 保留完整审计链路,方便追责和排查
|
||||
|
||||
## 3. 现有表与新增表的关系
|
||||
---
|
||||
|
||||
### 3.1 现有表
|
||||
## 3. 表结构设计
|
||||
|
||||
- `gear_stock_io`:实际出入库主表
|
||||
- `gear_stock_io_detail`:实际出入库明细表
|
||||
- `gear_stock`:库存汇总表
|
||||
- `gear_stock_log`:库存变动日志表
|
||||
### 3.1 单据主表 `gear_stock_io_order`
|
||||
|
||||
### 3.2 新增表
|
||||
用于保存出入库单据头信息与状态控制。
|
||||
|
||||
- `gear_stock_io_order`:出入库单据主表
|
||||
- `gear_stock_io_order_detail`:出入库单据明细表
|
||||
核心字段说明:
|
||||
|
||||
### 3.3 关系说明
|
||||
|
||||
- `gear_stock_io_order` 1 - N `gear_stock_io_order_detail`
|
||||
- `gear_stock_io_order` 可关联一个实际 `gear_stock_io`,字段为 `source_io_id`
|
||||
- 业务层在单据审核通过后,生成实际 `gear_stock_io` 与 `gear_stock_io_detail`
|
||||
- `gear_stock_io_order` 作为流程控制层,`gear_stock_io` 作为库存执行层
|
||||
|
||||
## 4. 表结构设计
|
||||
|
||||
## 4.1 出入库单据主表 `gear_stock_io_order`
|
||||
|
||||
### 核心字段
|
||||
|
||||
- `order_id`:单据主键
|
||||
- `order_code`:单据编号,唯一
|
||||
- `io_type`:出入库类型,建议使用 `I` 入库、`O` 出库、`T` 调拨
|
||||
- `io_type`:I 入库、O 出库、T 调拨
|
||||
- `biz_type`:业务类型,如 `purchase`、`sale`、`return`、`transfer`、`other`
|
||||
- `source_type`:来源单据类型
|
||||
- `source_no`:来源单据编号
|
||||
- `warehouse_id`:主仓库
|
||||
- `from_warehouse_id`:调出仓库
|
||||
- `to_warehouse_id`:调入仓库
|
||||
- `source_type` / `source_no` / `source_order_id`:关联来源业务单
|
||||
- `warehouse_id` / `from_warehouse_id` / `to_warehouse_id`:仓库维度信息
|
||||
- `status`:单据状态
|
||||
- `exec_flag`:执行标志
|
||||
- `source_io_id`:关联的实际出入库单据ID
|
||||
- `total_qty`:总数量
|
||||
- `exec_flag`:是否已执行
|
||||
- `reversal_flag` / `reversal_order_id`:冲销标记与原单关联
|
||||
- `source_io_id`:对应实际执行的出入库单
|
||||
|
||||
### 状态建议
|
||||
状态建议:
|
||||
|
||||
- `0` 草稿
|
||||
- `1` 已提交
|
||||
- `2` 已审核
|
||||
- `3` 已执行
|
||||
- `4` 已作废
|
||||
- `5` 已冲销
|
||||
|
||||
### 说明
|
||||
### 3.2 单据明细表 `gear_stock_io_order_detail`
|
||||
|
||||
- 草稿阶段允许编辑
|
||||
- 已提交后进入审核流程
|
||||
- 已审核后仅允许执行,不建议再修改
|
||||
- 已执行后视为完成,若需变更应走冲销或红字单据
|
||||
- 已作废单据不可再执行
|
||||
用于保存每一行出入库明细。
|
||||
|
||||
## 4.2 出入库单据明细表 `gear_stock_io_order_detail`
|
||||
核心字段说明:
|
||||
|
||||
### 核心字段
|
||||
|
||||
- `detail_id`:明细主键
|
||||
- `order_id`:所属单据ID
|
||||
- `line_no`:行号
|
||||
- `item_type`:物料类型
|
||||
- `item_id`:物料ID
|
||||
- `item_name`:物料名称快照
|
||||
- `spec_name`:规格型号快照
|
||||
- `warehouse_id`:入库仓库
|
||||
- `from_warehouse_id`:出库仓库
|
||||
- `item_type` / `item_id`:物料信息
|
||||
- `item_name` / `spec_name`:快照字段
|
||||
- `warehouse_id` / `from_warehouse_id`:入库/出库仓库
|
||||
- `quantity`:数量
|
||||
- `unit`:单位
|
||||
- `batch_no`:批次号
|
||||
- `unit_price`:单价快照
|
||||
- `amount`:金额快照
|
||||
- `source_detail_no`:来源明细编号
|
||||
- `unit_price` / `amount`:金额快照
|
||||
- `source_detail_no`:来源明细号
|
||||
- `reversal_detail_id`:冲销明细关联
|
||||
|
||||
### 说明
|
||||
---
|
||||
|
||||
- 明细表保留快照字段,避免后续基础资料变更影响历史单据
|
||||
- `line_no` 作为单据内行号,保证同单据明细顺序和唯一性
|
||||
## 4. 错单、超量、回退怎么处理
|
||||
|
||||
## 5. 业务流程建议
|
||||
### 4.1 未执行前发现错误
|
||||
|
||||
### 5.1 入库流程
|
||||
如果单据还没执行,处理方式最简单:
|
||||
|
||||
1. 创建入库单据草稿
|
||||
2. 录入明细并保存
|
||||
3. 提交单据
|
||||
4. 审核单据
|
||||
5. 审核通过后生成实际入库单 `gear_stock_io`
|
||||
6. 生成实际入库明细 `gear_stock_io_detail`
|
||||
7. 更新库存 `gear_stock`
|
||||
8. 写入库存日志 `gear_stock_log`
|
||||
9. 回写 `gear_stock_io_order.source_io_id` 与执行状态
|
||||
1. 撤回到草稿,修改明细
|
||||
2. 或直接作废单据,重新建正确单据
|
||||
|
||||
### 5.2 出库流程
|
||||
这种场景不涉及库存回退,因为库存还没变。
|
||||
|
||||
1. 创建出库单据草稿
|
||||
2. 录入出库明细
|
||||
3. 提交单据
|
||||
4. 审核单据
|
||||
5. 审核通过后生成实际出库单
|
||||
6. 扣减库存并写库存日志
|
||||
7. 标记单据已执行
|
||||
### 4.2 已执行后发现多入/多出/录错
|
||||
|
||||
### 5.3 调拨流程
|
||||
如果单据已经执行,**不要直接改历史明细或库存汇总表**,而是使用冲销单处理。
|
||||
|
||||
1. 创建调拨单据
|
||||
2. 录入调出仓库与调入仓库
|
||||
3. 审核通过后生成实际调拨出入库记录
|
||||
4. 先扣减调出仓库库存,再增加调入仓库库存
|
||||
5. 回写单据执行结果
|
||||
举例:
|
||||
|
||||
## 6. 幂等与异常控制建议
|
||||
- 入库多了 10 件:创建一张出库冲销单,把这 10 件扣回去
|
||||
- 出库多了 10 件:创建一张入库冲销单,把这 10 件补回来
|
||||
- 仓库选错:先冲销原单,再按正确仓库重建新单
|
||||
- 批次录错:按原批次反向扣回,再按正确批次重新入账
|
||||
|
||||
1. 单据编号 `order_code` 必须唯一
|
||||
2. 执行前检查 `exec_flag`,避免重复执行
|
||||
3. 单据执行时采用事务,保证主表、明细、库存、日志一致性
|
||||
4. 建议在业务层增加“审核通过后仅允许一次执行”的判断
|
||||
5. 如果执行失败,单据状态不应直接置为已执行
|
||||
6. 对已执行单据的修改建议通过红字冲销或新单据处理
|
||||
### 4.3 回退的原则
|
||||
|
||||
## 7. 建议的后续开发接口
|
||||
1. 原单据不删除
|
||||
2. 原执行流水不删除
|
||||
3. 通过反向单据把库存恢复到正确状态
|
||||
4. 回退单与原单必须建立关联
|
||||
5. 每次回退都写审计日志
|
||||
|
||||
- 单据新增
|
||||
- 单据编辑
|
||||
- 单据提交
|
||||
- 单据审核
|
||||
- 单据执行
|
||||
- 单据作废
|
||||
- 单据详情查询
|
||||
- 单据列表查询
|
||||
- 按来源单号查询
|
||||
### 4.4 推荐的冲销链路
|
||||
|
||||
## 8. 与现有表的兼容方式
|
||||
- 原单执行成功
|
||||
- 发现错误
|
||||
- 创建冲销单 `reversal_flag=1`
|
||||
- 冲销单引用原单 `reversal_order_id`
|
||||
- 冲销单审核并执行
|
||||
- 冲销单执行后,库存回到正确状态
|
||||
- 原单状态标记为“已冲销”或“已回退完成”
|
||||
|
||||
本次设计不删除现有出入库表,而是在其上增加单据控制层,便于平滑迁移:
|
||||
---
|
||||
|
||||
- 老接口仍可保留直接写 `gear_stock_io`
|
||||
- 新接口优先写 `gear_stock_io_order`
|
||||
- 后端逐步切换为“单据驱动库存”模式
|
||||
- 未来如需更严格的流程控制,可将 `gear_stock_io` 仅作为执行结果表使用
|
||||
## 5. 后端实现步骤
|
||||
|
||||
## 9. 结论
|
||||
下面按后端开发落地来拆解。
|
||||
|
||||
建议采用“单据表 + 执行表”的双层设计:
|
||||
### 5.1 新增数据库实体
|
||||
|
||||
- 单据表负责流程控制、审批、追溯
|
||||
- 执行表负责真实库存变更
|
||||
先新增两个实体:
|
||||
|
||||
这样可以兼顾当前系统兼容性和后续业务扩展能力。
|
||||
- `StockIoOrder`
|
||||
- `StockIoOrderDetail`
|
||||
|
||||
实体字段与 SQL 保持一致,尤其注意:
|
||||
|
||||
- 单据状态字段
|
||||
- 执行标志字段
|
||||
- 冲销字段
|
||||
- 来源单据字段
|
||||
- 审核/执行人字段
|
||||
|
||||
### 5.2 新增单据服务层
|
||||
|
||||
建议新增服务:
|
||||
|
||||
- `StockIoOrderService`
|
||||
- `StockIoOrderDetailService`
|
||||
|
||||
其中主服务负责流程,明细服务负责增删改查。
|
||||
|
||||
推荐核心方法:
|
||||
|
||||
- `createOrder(...)`
|
||||
- `updateOrder(...)`
|
||||
- `submitOrder(orderId)`
|
||||
- `auditOrder(orderId)`
|
||||
- `executeOrder(orderId)`
|
||||
- `cancelOrder(orderId, reason)`
|
||||
- `reverseOrder(orderId, reason)`
|
||||
- `queryOrderDetail(orderId)`
|
||||
|
||||
### 5.3 统一执行入口
|
||||
|
||||
把原来直接操作库存的逻辑改成一个统一入口,例如:
|
||||
|
||||
- `applyStockChangeByOrder(orderId)`
|
||||
|
||||
执行流程建议:
|
||||
|
||||
1. 查询单据主表和明细
|
||||
2. 校验状态必须为“已审核”
|
||||
3. 校验 `exec_flag=0`
|
||||
4. 校验库存是否足够(出库类)
|
||||
5. 组装实际 `gear_stock_io` 主表
|
||||
6. 组装实际 `gear_stock_io_detail` 明细
|
||||
7. 更新 `gear_stock`
|
||||
8. 写入 `gear_stock_log`
|
||||
9. 回写单据 `source_io_id`、`exec_flag`、`status`
|
||||
|
||||
### 5.4 冲销单生成逻辑
|
||||
|
||||
新增反向单据生成方法:
|
||||
|
||||
- `buildReversalOrder(originalOrderId, reason)`
|
||||
|
||||
处理规则:
|
||||
|
||||
1. 读取原单据和明细
|
||||
2. 主单的 `io_type` 取反
|
||||
- 原来是入库 -> 冲销单做出库
|
||||
- 原来是出库 -> 冲销单做入库
|
||||
- 原来是调拨 -> 冲销单按反方向调拨
|
||||
3. 明细数量保留原数量,但执行时按反向逻辑处理
|
||||
4. 记录 `reversal_order_id`
|
||||
5. 记录 `reversal_reason`
|
||||
6. 冲销单提交、审核、执行
|
||||
|
||||
### 5.5 状态机控制
|
||||
|
||||
建议在代码里明确状态流转校验:
|
||||
|
||||
- 草稿 -> 提交
|
||||
- 已提交 -> 审核
|
||||
- 已审核 -> 执行
|
||||
- 已执行 -> 冲销完成 / 已冲销
|
||||
- 草稿/已提交/已审核 -> 作废(未执行时)
|
||||
|
||||
禁止的操作:
|
||||
|
||||
- 已执行后直接修改明细
|
||||
- 已执行后再次执行
|
||||
- 作废单据再执行
|
||||
- 冲销单再次冲销自己
|
||||
|
||||
### 5.6 事务控制
|
||||
|
||||
执行与冲销都必须包事务,至少包括:
|
||||
|
||||
- 单据状态更新
|
||||
- 实际出入库单写入
|
||||
- 库存更新
|
||||
- 库存日志写入
|
||||
|
||||
要求:
|
||||
|
||||
- 任一步失败,整体回滚
|
||||
- 不允许库存更新成功但单据状态失败
|
||||
- 不允许单据状态成功但库存未更新
|
||||
|
||||
### 5.7 幂等控制
|
||||
|
||||
建议增加以下幂等控制:
|
||||
|
||||
- `order_code` 唯一
|
||||
- `exec_flag` 防止重复执行
|
||||
- `reversal_order_id` 唯一,防止同一原单重复冲销
|
||||
- 关键执行方法中加锁或乐观校验,防并发重复提交
|
||||
|
||||
### 5.8 库存回退代码建议
|
||||
|
||||
不要写“直接减库存/加库存”的散落代码,而要统一封装:
|
||||
|
||||
- `increaseStock(...)`
|
||||
- `decreaseStock(...)`
|
||||
- `applyStockChangeByOrder(...)`
|
||||
- `applyReversalByOrder(...)`
|
||||
|
||||
其中冲销逻辑只是在“执行入口”里改变方向,而不是单独写一套完全不同的库存更新代码。
|
||||
|
||||
### 5.9 日志与审计
|
||||
|
||||
每次执行或冲销必须记录:
|
||||
|
||||
- 操作人
|
||||
- 操作时间
|
||||
- 原单号
|
||||
- 冲销单号
|
||||
- 原因
|
||||
- 影响仓库
|
||||
- 影响物料
|
||||
- 影响批次
|
||||
|
||||
---
|
||||
|
||||
## 6. 代码改造建议
|
||||
|
||||
### 6.1 原先直接改库存的代码
|
||||
|
||||
如果项目里有类似:
|
||||
|
||||
- 保存单据后立即改 `gear_stock`
|
||||
- 前端点一次按钮就直接扣库存
|
||||
- 业务代码里到处 `update stock set qty = qty +/- x`
|
||||
|
||||
都建议改成:
|
||||
|
||||
- 先保存单据
|
||||
- 审核通过后统一执行
|
||||
- 出错后走冲销单
|
||||
|
||||
### 6.2 建议改造顺序
|
||||
|
||||
1. 先加单据表和明细表
|
||||
2. 再加实体和 Mapper
|
||||
3. 再加单据 Service
|
||||
4. 再把库存执行逻辑抽到统一方法
|
||||
5. 再把原直接操作入口改成单据入口
|
||||
6. 最后补冲销接口
|
||||
|
||||
### 6.3 推荐接口拆分
|
||||
|
||||
- `POST /stock-io-order`
|
||||
- `PUT /stock-io-order`
|
||||
- `POST /stock-io-order/submit/{id}`
|
||||
- `POST /stock-io-order/audit/{id}`
|
||||
- `POST /stock-io-order/execute/{id}`
|
||||
- `POST /stock-io-order/cancel/{id}`
|
||||
- `POST /stock-io-order/reverse/{id}`
|
||||
|
||||
---
|
||||
|
||||
## 7. 总结
|
||||
|
||||
这套方案的关键点是:
|
||||
|
||||
- 业务上:先单据后执行
|
||||
- 技术上:统一库存执行入口
|
||||
- 出错后:通过反向单据冲销,不直接修历史数据
|
||||
- 落地上:先建表,再加服务,再改原逻辑,再补回退
|
||||
|
||||
如果你愿意,我下一步可以继续直接帮你把“后端实现步骤”再细化成接口清单、Java Service 方法清单和状态流转图说明。
|
||||
Reference in New Issue
Block a user