This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: ExchangeOrder 换货单模型定义
|
||||
|
||||
系统 SHALL 定义 `ExchangeOrder` 模型并映射到 `tb_exchange_order`,用于承载客户端换货完整生命周期。
|
||||
|
||||
模型字段 MUST 至少包含:
|
||||
- 基础:`id`、`created_at`、`updated_at`、`deleted_at`、`creator`、`updater`
|
||||
- 单号:`exchange_no`
|
||||
- 流程:`flow_type`
|
||||
- 旧资产:`old_asset_type`、`old_asset_id`、`old_asset_identifier`
|
||||
- 新资产:`new_asset_type`、`new_asset_id`、`new_asset_identifier`
|
||||
- 收货:`recipient_name`、`recipient_phone`、`recipient_address`
|
||||
- 物流:`express_company`、`express_no`
|
||||
- 迁移:`migrate_data`、`migration_completed`、`migration_balance`
|
||||
- 时间:`shipped_at`、`completed_at`
|
||||
- 业务:`exchange_reason`、`remark`、`status`
|
||||
- 多租户:`shop_id`
|
||||
|
||||
`flow_type` MUST 使用字符串枚举,至少支持:
|
||||
- `shipping`:需要客户填写收货地址、后台发货、后台确认完成
|
||||
- `direct`:创建时直接完成,不经过客户填写地址和后台发货
|
||||
|
||||
`flow_type` MUST 在数据库层设置默认值 `shipping`,用于兼容历史记录与旧创建请求。
|
||||
|
||||
`ExchangeOrder` SHALL 嵌入 `BaseModel` 并实现 `TableName() string`,返回 `tb_exchange_order`。
|
||||
|
||||
#### Scenario: 创建 shipping 换货单模型实例
|
||||
- **WHEN** 系统创建新的 `shipping` 换货单记录
|
||||
- **THEN** 记录 MUST 包含旧资产快照、流程类型 `flow_type=shipping`、收货信息占位、迁移状态字段和多租户字段
|
||||
|
||||
#### Scenario: 创建 direct 换货单模型实例
|
||||
- **WHEN** 系统创建新的 `direct` 换货单记录
|
||||
- **THEN** 记录 MUST 包含旧资产快照、新资产快照、流程类型 `flow_type=direct`
|
||||
- **AND** 记录在创建成功时即可具备 `completed_at`
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 换货状态常量定义
|
||||
|
||||
系统 MUST 使用 int 常量定义换货状态:
|
||||
- `1` 待填写信息
|
||||
- `2` 待发货
|
||||
- `3` 已发货待确认
|
||||
- `4` 已完成
|
||||
- `5` 已取消
|
||||
|
||||
系统 MUST 使用独立的字符串常量定义换货流程类型:
|
||||
- `shipping`
|
||||
- `direct`
|
||||
|
||||
#### Scenario: 状态与流程常量一致性
|
||||
- **WHEN** Service、Store、Handler 读取或更新换货状态与流程类型
|
||||
- **THEN** 各层 MUST 使用统一常量值,禁止硬编码散落魔法数字和字符串
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 换货状态机流转规则
|
||||
|
||||
系统 SHALL 执行以下状态机:
|
||||
|
||||
- `shipping`:
|
||||
- 创建换货单后:`status=1`
|
||||
- 客户填写收货信息后:`1 -> 2`
|
||||
- 后台发货后:`2 -> 3`
|
||||
- 后台确认完成后:`3 -> 4`
|
||||
- 取消:仅允许 `1/2 -> 5`
|
||||
|
||||
- `direct`:
|
||||
- 创建换货单并完成后:`status=4`
|
||||
- 不经过 `1/2/3`
|
||||
- 不走客户端填写收货地址
|
||||
- 不走后台发货
|
||||
- 不进入取消状态机
|
||||
- 任一步失败时不保留半成品 `direct` 单据
|
||||
|
||||
系统 MUST 禁止非法流转(如 `3 -> 5`、`4 -> 2`、`direct 进入 2`)。
|
||||
|
||||
#### Scenario: shipping 已发货不可取消
|
||||
- **WHEN** `shipping` 换货单状态为 `3` 且请求取消
|
||||
- **THEN** 系统 MUST 拒绝并返回状态流转非法错误
|
||||
|
||||
#### Scenario: direct 创建即完成
|
||||
- **WHEN** 后台以 `flow_type=direct` 创建换货单且所有校验通过
|
||||
- **THEN** 系统 MUST 直接创建 `status=4` 的换货单
|
||||
- **AND** MUST 写入 `completed_at`
|
||||
|
||||
#### Scenario: direct 失败不落半成品状态
|
||||
- **WHEN** 后台以 `flow_type=direct` 创建换货单但完成事务失败
|
||||
- **THEN** 系统 MUST 回滚创建
|
||||
- **AND** MUST NOT 产生 `flow_type=direct AND status IN (1,2,3)` 的换货单
|
||||
|
||||
#### Scenario: direct 不允许进入发货阶段
|
||||
- **WHEN** `direct` 换货单请求执行发货或填写收货地址
|
||||
- **THEN** 系统 MUST 拒绝并返回流程类型不支持该操作的错误
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 换货单号生成规则
|
||||
|
||||
系统 MUST 为每个换货单生成全局可追踪单号,格式为:`EXC + 时间戳片段 + 随机数片段`。
|
||||
|
||||
生成规则 SHALL 满足:
|
||||
- 前缀固定为 `EXC`
|
||||
- 包含日期/时间信息用于人工排查
|
||||
- 包含随机片段降低并发冲突概率
|
||||
|
||||
#### Scenario: 生成换货单号
|
||||
- **WHEN** 后台发起换货并创建新单
|
||||
- **THEN** 系统 MUST 生成形如 `EXC20260319XXXXXX` 的单号并写入 `exchange_no`
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 换货关键业务时间字段语义
|
||||
|
||||
系统 SHALL 使用独立的业务时间字段表达发货完成和换货完成,而不是复用 `updated_at`。
|
||||
|
||||
字段语义 MUST 满足:
|
||||
- `shipped_at`:仅在 `shipping` 流程发货成功后写入
|
||||
- `completed_at`:仅在换货完成成功后写入,`shipping` 与 `direct` 共用
|
||||
- `direct` 流程 MUST 保持 `shipped_at` 为空
|
||||
- 历史已完成单据若 `completed_at` 为空,查询与追溯层 MUST 回退使用 `updated_at`
|
||||
|
||||
#### Scenario: shipping 写入发货时间
|
||||
- **WHEN** `shipping` 换货单执行后台发货成功
|
||||
- **THEN** 系统 MUST 记录 `shipped_at=当前时间`
|
||||
|
||||
#### Scenario: direct 不写发货时间
|
||||
- **WHEN** `direct` 换货单创建并完成成功
|
||||
- **THEN** 系统 MUST 保持 `shipped_at` 为空
|
||||
- **AND** MUST 写入 `completed_at=当前时间`
|
||||
|
||||
#### Scenario: 历史单据完成时间兼容
|
||||
- **WHEN** 查询历史已完成换货单且 `completed_at` 为空
|
||||
- **THEN** 系统 MUST 在追溯展示中回退使用 `updated_at` 作为兼容完成时间
|
||||
Reference in New Issue
Block a user