- 新增 ReconciliationCompleteCmd DTO用于对账完成请求 - 在 ReconciliationServiceI 中添加 complete 方法定义 - 在 ReconciliationGateway 中添加 complete 方法定义 - 实现 Gateway 层 complete 方法,包含状态校验逻辑 - 添加 ReconciliationCompleteCmdExe 执行器处理业务逻辑 - 在 ReconciliationServiceImpl 中注入并实现 complete 方法 - 在 Controller 中添加 completeReconciliation 接口 - 添加 B_BIZ_RECONCILIATION_NOT_PENDING 业务异常码 - 修复 ReconciliationGatewayImpl 中的插入顺序问题
314 lines
8.1 KiB
Markdown
314 lines
8.1 KiB
Markdown
---
|
||
name: "add-state-transition"
|
||
description: "为实体添加状态流转接口(如:完成、取消等)。遵循 ERPTurbo 项目的 DDD 分层架构规范。"
|
||
---
|
||
|
||
# Add State Transition
|
||
|
||
为实体添加状态流转接口,遵循 DDD 分层架构规范。
|
||
|
||
## ⚠️ 重要规则
|
||
|
||
**仅操作 `erp-turbo-business` 和 `erp-turbo-admin` 模块,禁止修改 `erp-turbo-svc` 模块!**
|
||
|
||
详见:`.claude/PROJECT_RULES.md`
|
||
|
||
## 功能说明
|
||
|
||
为实体添加状态流转接口,例如:订单完成、对账取消、审核通过等。
|
||
|
||
## 输入格式
|
||
|
||
```
|
||
Entity: {实体名称}
|
||
Action: {操作名称}
|
||
TargetState: {目标状态值}
|
||
Comment: {操作中文描述}
|
||
```
|
||
|
||
**示例:**
|
||
```
|
||
Entity: Reconciliation
|
||
Action: Complete
|
||
TargetState: RECONCILED
|
||
Comment: 对账完成
|
||
```
|
||
|
||
## 工作流程
|
||
|
||
### 1. 创建 Cmd DTO
|
||
|
||
路径:`erp-turbo-common/erp-turbo-api/src/main/java/com/xunhong/erp/turbo/api/biz/dto/cmd/`
|
||
|
||
**文件名:** `{Entity}{Action}Cmd.java`
|
||
|
||
```java
|
||
package com.xunhong.erp.turbo.api.biz.dto.cmd;
|
||
|
||
import com.xunhong.erp.turbo.base.dto.Command;
|
||
import io.swagger.v3.oas.annotations.media.Schema;
|
||
import lombok.Data;
|
||
import lombok.EqualsAndHashCode;
|
||
|
||
/**
|
||
* @author shenyifei
|
||
*/
|
||
@Data
|
||
@Schema(title = "{Comment}")
|
||
@EqualsAndHashCode(callSuper = true)
|
||
public class {Entity}{Action}Cmd extends Command {
|
||
|
||
@Schema(title = "{EntityComment}ID", requiredMode = Schema.RequiredMode.REQUIRED, type = "string")
|
||
private Long {entityFieldName}Id;
|
||
}
|
||
```
|
||
|
||
### 2. 更新 Service 接口
|
||
|
||
路径:`erp-turbo-common/erp-turbo-api/src/main/java/com/xunhong/erp/turbo/api/biz/api/{Entity}ServiceI.java`
|
||
|
||
添加方法签名:
|
||
|
||
```java
|
||
{Entity}VO {action}({Entity}{Action}Cmd {entity}{Action}Cmd);
|
||
```
|
||
|
||
### 3. 更新 Gateway 接口
|
||
|
||
路径:`erp-turbo-business/erp-turbo-biz/src/main/java/com/xunhong/erp/turbo/biz/domain/gateway/{Entity}Gateway.java`
|
||
|
||
添加方法签名:
|
||
|
||
```java
|
||
{Entity} {action}({Entity}{Action}Cmd {entity}{Action}Cmd);
|
||
```
|
||
|
||
### 4. 实现 Gateway
|
||
|
||
路径:`erp-turbo-business/erp-turbo-biz/src/main/java/com/xunhong/erp/turbo/biz/infrastructure/gateway/{Entity}GatewayImpl.java`
|
||
|
||
添加 import:
|
||
|
||
```java
|
||
import com.xunhong.erp.turbo.api.biz.dto.cmd.{Entity}{Action}Cmd;
|
||
import com.xunhong.erp.turbo.api.biz.dto.enums.{Entity}StateEnum;
|
||
```
|
||
|
||
实现方法:
|
||
|
||
```java
|
||
@Override
|
||
public {Entity} {action}({Entity}{Action}Cmd cmd) {
|
||
LambdaQueryWrapper<{Entity}DO> queryWrapper = Wrappers.lambdaQuery({Entity}DO.class);
|
||
queryWrapper.eq({Entity}DO::get{Entity}Id, cmd.get{Entity}Id());
|
||
queryWrapper.select({Entity}DO::get{Entity}Id, {Entity}DO::getState);
|
||
queryWrapper.last("limit 1");
|
||
|
||
{Entity}DO {entity}DO = {entity}Mapper.selectOne(queryWrapper);
|
||
|
||
if (!{entity}DO.getState().equals({Entity}StateEnum.{CURRENT_STATE})) {
|
||
throw new BizException(BizErrorCode.B_BIZ_{ENTITY_UPPER}_NOT_{CURRENT_STATE_UPPER});
|
||
}
|
||
|
||
{entity}DO.setState({Entity}StateEnum.{TARGET_STATE});
|
||
{entity}Mapper.updateById({entity}DO);
|
||
|
||
return {entity}Convert.to{Entity}({entity}DO);
|
||
}
|
||
```
|
||
|
||
### 5. 创建 Executor
|
||
|
||
路径:`erp-turbo-business/erp-turbo-biz/src/main/java/com/xunhong/erp/turbo/biz/app/executor/cmd/{Entity}{Action}CmdExe.java`
|
||
|
||
```java
|
||
package com.xunhong.erp.turbo.biz.app.executor.cmd;
|
||
|
||
import com.xunhong.erp.turbo.api.biz.dto.cmd.{Entity}{Action}Cmd;
|
||
import com.xunhong.erp.turbo.api.biz.dto.vo.{Entity}VO;
|
||
import com.xunhong.erp.turbo.biz.app.assembler.{Entity}Assembler;
|
||
import com.xunhong.erp.turbo.biz.domain.gateway.{Entity}Gateway;
|
||
import com.xunhong.erp.turbo.biz.domain.entity.{Entity};
|
||
import lombok.RequiredArgsConstructor;
|
||
import lombok.extern.slf4j.Slf4j;
|
||
import org.springframework.stereotype.Component;
|
||
|
||
/**
|
||
* @author shenyifei
|
||
*/
|
||
@Slf4j
|
||
@Component
|
||
@RequiredArgsConstructor
|
||
public class {Entity}{Action}CmdExe {
|
||
private final {Entity}Gateway {entity}Gateway;
|
||
private final {Entity}Assembler {entity}Assembler;
|
||
|
||
public {Entity}VO execute({Entity}{Action}Cmd cmd) {
|
||
{Entity} {entity} = {entity}Gateway.{action}(cmd);
|
||
return {entity}Assembler.to{Entity}VO({entity});
|
||
}
|
||
}
|
||
```
|
||
|
||
### 6. 更新 ServiceImpl
|
||
|
||
路径:`erp-turbo-business/erp-turbo-biz/src/main/java/com/xunhong/erp/turbo/biz/app/service/{Entity}ServiceImpl.java`
|
||
|
||
添加字段注入:
|
||
|
||
```java
|
||
private final {Entity}{Action}CmdExe {entity}{Action}CmdExe;
|
||
```
|
||
|
||
添加方法实现:
|
||
|
||
```java
|
||
@Override
|
||
public {Entity}VO {action}({Entity}{Action}Cmd cmd) {
|
||
return {entity}{Action}CmdExe.execute(cmd);
|
||
}
|
||
```
|
||
|
||
### 7. 更新 Controller
|
||
|
||
路径:`erp-turbo-admin/src/main/java/com/xunhong/erp/turbo/admin/controller/{Entity}Controller.java`
|
||
|
||
添加 import:
|
||
|
||
```java
|
||
import com.xunhong.erp.turbo.api.biz.dto.cmd.{Entity}{Action}Cmd;
|
||
```
|
||
|
||
添加接口方法:
|
||
|
||
```java
|
||
@SaCheckLogin
|
||
@PostMapping("{action}{Entity}")
|
||
@Operation(summary = "{Comment}", method = "POST")
|
||
public SingleResponse<{Entity}VO> {action}{Entity}(
|
||
@RequestBody @Validated {Entity}{Action}Cmd cmd) {
|
||
return SingleResponse.of({entity}Service.{action}(cmd));
|
||
}
|
||
```
|
||
|
||
## 命名规范
|
||
|
||
| 类型 | 格式 | 示例 |
|
||
|-----|------|-----|
|
||
| 实体名 | PascalCase | Reconciliation, Order |
|
||
| 操作名 | PascalCase | Complete, Cancel, Approve |
|
||
| 方法名 | camelCase | complete, cancel, approve |
|
||
| 字段名 | camelCase | reconciliationId, orderId |
|
||
| 常量 | UPPER_SNAKE_CASE | RECONCILIATION, ORDER |
|
||
|
||
## 使用示例
|
||
|
||
### 示例 1:对账完成
|
||
```
|
||
Entity: Reconciliation
|
||
Action: Complete
|
||
TargetState: RECONCILED
|
||
Comment: 对账完成
|
||
CurrentState: PENDING
|
||
```
|
||
|
||
生成接口:`POST /operation/completeReconciliation`
|
||
|
||
### 示例 2:订单取消
|
||
```
|
||
Entity: Order
|
||
Action: Cancel
|
||
TargetState: CANCELLED
|
||
Comment: 取消订单
|
||
CurrentState: PENDING
|
||
```
|
||
|
||
生成接口:`POST /operation/cancelOrder`
|
||
|
||
### 示例 3:审核通过
|
||
```
|
||
Entity: PaymentTask
|
||
Action: Approve
|
||
TargetState: APPROVED
|
||
Comment: 审核通过
|
||
CurrentState: PENDING_APPROVAL
|
||
```
|
||
|
||
生成接口:`POST /operation/approvePaymentTask`
|
||
|
||
## 输出示例
|
||
|
||
```
|
||
✅ 已完成状态流转接口添加
|
||
========================================
|
||
创建文件:
|
||
✅ api/.../cmd/{Entity}{Action}Cmd.java (erp-turbo-common)
|
||
✅ biz/.../executor/cmd/{Entity}{Action}CmdExe.java (erp-turbo-business)
|
||
|
||
更新文件:
|
||
✅ api/.../api/{Entity}ServiceI.java (erp-turbo-common)
|
||
✅ biz/.../gateway/{Entity}Gateway.java (erp-turbo-business)
|
||
✅ biz/.../gateway/{Entity}GatewayImpl.java (erp-turbo-business)
|
||
✅ biz/.../service/{Entity}ServiceImpl.java (erp-turbo-business)
|
||
✅ admin/.../controller/{Entity}Controller.java (erp-turbo-admin)
|
||
|
||
接口路径: POST /{basePath}/{action}{Entity}
|
||
请求体: {"{entityFieldName}Id": 123}
|
||
状态流转: {CURRENT_STATE} → {TARGET_STATE}
|
||
```
|
||
|
||
## 注意事项
|
||
|
||
1. **状态验证**:
|
||
- Gateway 实现中应验证当前状态
|
||
- 使用 `BizException` 抛出业务异常
|
||
- 错误码格式:`B_BIZ_{ENTITY}_NOT_{STATE}`
|
||
|
||
2. **查询优化**:
|
||
- 使用 `queryWrapper.select()` 只查询必要字段
|
||
- 减少数据传输和内存占用
|
||
|
||
3. **事务处理**:
|
||
- 根据需要添加 `@Transactional` 注解
|
||
- 涉及多表操作时务必使用事务
|
||
|
||
4. **接口一致性**:
|
||
- 使用 `@PostMapping`
|
||
- 使用 `@RequestBody @Validated` 接收参数
|
||
- 返回类型统一为 `SingleResponse<{Entity}VO>`
|
||
|
||
5. **权限控制**:
|
||
- 所有接口添加 `@SaCheckLogin` 注解
|
||
- 根据需要添加其他权限验证
|
||
|
||
6. **Assemble 方法**:
|
||
- 使用 `to{Entity}VO()` 而非 `toVO()`
|
||
- 保持命名一致性
|
||
|
||
## 文件搜索规则
|
||
|
||
使用 Glob 工具时,**限定在特定模块**:
|
||
|
||
```bash
|
||
# ✅ 正确:限定路径
|
||
erp-turbo-business/**/{Entity}*.java
|
||
erp-turbo-common/**/{Entity}*.java
|
||
erp-turbo-admin/**/{Entity}*.java
|
||
|
||
# ❌ 错误:会匹配到 svc 模块
|
||
**/*{Entity}*.java
|
||
```
|
||
|
||
## 常见状态流转模式
|
||
|
||
| 业务场景 | 当前状态 | 目标状态 | 操作名 |
|
||
|---------|---------|---------|--------|
|
||
| 对账完成 | PENDING | RECONCILED | Complete |
|
||
| 部分开票 | RECONCILED | PARTIAL_INVOICE | PartialInvoice |
|
||
| 完成开票 | PARTIAL_INVOICE | INVOICED | Invoice |
|
||
| 部分回款 | INVOICED | PARTIAL_PAYMENT | PartialPayment |
|
||
| 完成回款 | PARTIAL_PAYMENT | PAID | Payment |
|
||
| 订单取消 | PENDING | CANCELLED | Cancel |
|
||
| 审核通过 | PENDING | APPROVED | Approve |
|
||
| 审核驳回 | PENDING | REJECTED | Reject |
|