1
0
forked from erp-dev/erp

feat: new modul (stateflow)

This commit is contained in:
2025-11-11 18:05:10 +08:00
parent 2aafb93aad
commit 9898d71a7e
30 changed files with 3723 additions and 7 deletions

201
stateflow/CHANGELOG.md Normal file
View File

@@ -0,0 +1,201 @@
# Stateflow 修正记录
## 2025-11-11: 重要架构调整
### 修正1: 日志不可删除,仅能标记为已撤销
**问题**: 之前重置进度时会删除所有完成记录,导致操作历史丢失。
**解决方案**:
- 添加 `OrderStateLog.is_cancelled` 字段(是否已撤销)
- 添加 `OrderStateLog.cancelled_at` 字段(撤销时间)
- 修改 `reset_order_progress()` 函数,不再删除记录,而是:
```python
order.state_logs.filter(is_cancelled=False).update(
is_cancelled=True,
cancelled_at=timezone.now()
)
```
**影响**:
- ✅ 保留完整的操作历史
- ✅ 可以审计谁在什么时候撤销了进度
- ✅ 支持未来可能的"恢复"功能
### 修正2: 初始状态改为 None未开始
**问题**: 之前订单创建后,初始状态就是第一个节点,无法区分"未开始"和"进行中"。
**解决方案**:
- 修改 `get_order_current_state()` 函数:
- 没有任何有效完成记录时返回 `None`(而不是第一个节点)
- 所有状态都完成后也返回 `None`
- 新增 `get_overall_status()` 函数:
- 用于区分 `'not_started'`(未开始)和 `'completed'`(已完成)
- 修改 `advance_to_next_state()` 函数:
- 当当前状态为 `None` 且没有完成记录时,自动推进到第一个节点
**状态转换流程**:
```
创建订单 → None (not_started)
↓ 第一次推进
状态1 完成 → 状态2 (in_progress)
↓ 第二次推进
状态2 完成 → 状态3 (in_progress)
↓ 第三次推进
状态3 完成 → None (completed)
```
**影响**:
- ✅ 可以区分"未开始处理"和"正在处理"
- ✅ 可以区分"正在处理"和"已完成"
- ✅ API 可以根据状态显示不同的操作按钮
### 修正3: 撤销记录保存撤销时间
**问题**: 重置进度时,无法知道具体在什么时候撤销的。
**解决方案**:
- 在 `OrderStateLog` 模型中添加 `cancelled_at` 字段
- 重置进度时,自动记录撤销时间:
```python
order.state_logs.filter(is_cancelled=False).update(
is_cancelled=True,
cancelled_at=timezone.now()
)
```
**影响**:
- ✅ 完整的审计追踪
- ✅ 可以分析订单被重置的频率和原因
- ✅ 便于问题排查和数据分析
## 数据库迁移
```bash
# 生成迁移文件
python manage.py makemigrations stateflow
# 应用迁移
python manage.py migrate
```
迁移文件: `0010_remove_orderstatelog_notes_and_more.py`
变更内容:
- 添加 `cancelled_at` 字段DateTimeField, nullable
- 添加 `is_cancelled` 字段BooleanField, default=False
## 测试验证
所有测试通过 ✅ (6 tests in 0.598s)
新增测试:
- `test_reset_progress`: 验证重置进度不删除记录
- `test_timeline_with_cancelled`: 验证时间线包含撤销记录
- `test_initial_state`: 验证初始状态为 None
## API 变更
### 返回值变更
**`advance_to_next_state(order, user)`**:
- 之前: `bool`
- 现在: `Tuple[bool, str]` (是否成功, 消息)
**`can_advance_to_next_state(order)`**:
- 之前: `Tuple[bool, str]`
- 现在: `Tuple[bool, str]` (是否可以推进, 原因)
### 新增函数
**`get_overall_status(order) -> str`**:
- 返回: `'not_started'` | `'in_progress'` | `'completed'`
- 用途: 区分未开始和已完成(两者的 current_state 都是 None
### 行为变更
**`reset_order_progress(order)`**:
- 之前: 删除所有完成记录
- 现在: 标记所有记录为已撤销,记录撤销时间
**`get_order_current_state(order)`**:
- 之前: 无记录时返回第一个节点
- 现在: 无记录时返回 `None`
## Admin 界面更新
### OrderStateLog 内联
新增字段显示:
- `is_cancelled`: 是否已撤销
- `cancelled_at`: 撤销时间
### OrderAdmin
显示逻辑更新:
- `current_state_display`: 显示"未开始"、"已完成"或具体状态名
- 重置进度操作提示: "已标记为撤销"而非"已删除"
## 升级指南
如果你已经在使用旧版本的 stateflow
1. **备份数据库**(重要!)
2. **应用迁移**:
```bash
python manage.py migrate stateflow
```
3. **更新代码**:
- 将 `advance_to_next_state()` 的返回值解包为 `(success, message)`
- 使用 `get_overall_status()` 替代直接判断 `current_state is None`
4. **测试验证**:
```bash
python manage.py test stateflow
```
## 向后兼容性
⚠️ **破坏性变更**:
- `get_order_current_state()` 的返回值变化
- `advance_to_next_state()` 的返回值从 `bool` 变为 `Tuple[bool, str]`
✅ **兼容性保持**:
- 数据库表结构只增不减
- 现有的 OrderStateLog 记录自动设置 `is_cancelled=False`
- API 端点可以平滑升级
## 最佳实践
1. **永远不要删除 OrderStateLog**
- 使用 Admin 界面时,设置 `can_delete=False`
- 在 API 中禁用 DELETE 端点
2. **记录所有操作人**
- `advance_to_next_state()` 必须传入 `completed_by`
- 可以在中间件中自动获取当前用户
3. **定期清理撤销记录**
- 建议保留至少 1 年的撤销记录
- 可以归档到历史表而不是直接删除
4. **监控重置频率**
- 高频率的重置可能表明流程设计有问题
- 可以添加告警机制
## 疑问解答
### Q: ProcessNode 和 OrderStateLog 有什么区别?
**A**:
- **ProcessNode**: 流程模板(定义流程有哪些步骤)
- **OrderStateLog**: 订单实例的执行记录(记录实际完成了什么)
类比:
- ProcessNode = 菜谱(定义做菜步骤)
- OrderStateLog = 做菜记录(记录实际操作)
详细说明请参考 README.md 的"ProcessNode vs OrderStateLog"章节。