1
0
forked from erp-dev/erp
Files
erpnew/stateflow/CHANGELOG.md
2025-11-11 18:05:10 +08:00

202 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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"章节。