1
0
forked from erp-dev/erp

fix: current_state has been changed to a computed property

This commit is contained in:
2025-11-19 10:23:17 +08:00
parent 7f822b0064
commit 400c0db6db
14 changed files with 964 additions and 87 deletions

View File

@@ -9,27 +9,69 @@ from . import models
User = get_user_model()
def get_last_completed_state(business_object: 'models.BusinessObject') -> Optional['models.State']:
"""
获取最后完成的状态
返回:最后一个已完成的状态节点,如果没有则返回 None
应用场景:
- 显示"刚完成了什么"
- 查询最后完成状态的参数
- 审计日志
"""
last_log = business_object.state_logs.filter(
is_cancelled=False
).order_by('-completed_at', '-id').first()
return last_log.state if last_log else None
def get_next_pending_state_simple(business_object: 'models.BusinessObject') -> Optional['models.State']:
"""
获取下一个待执行的状态简化版只返回State对象
返回:下一个待执行的状态节点,如果没有则返回 None
应用场景:
- 显示"接下来要做什么"
- 获取下一步需要的参数
- 流程推进前的检查
"""
next_pending = get_next_pending_state(business_object, include_parameters=False)
return next_pending['state'] if next_pending else None
def get_business_object_current_state(business_object: 'models.BusinessObject') -> Optional['models.State']:
"""
获取业务对象的当前状态(下一个待执行的节点
获取业务对象的当前状态(可配置模式
规则
根据 settings.STATEFLOW_CURRENT_STATE_MODE 决定返回
- 'NEXT' (默认): 下一个待执行的节点
- 'LAST': 最后完成的节点
注意:此函数保持原有接口不变,但行为可配置
推荐:在新代码中直接使用 get_last_completed_state() 或 get_next_pending_state_simple() 以明确语义
NEXT模式的规则
- 返回下一个待执行的节点(第一个未完成的节点)
- 如果所有节点都已完成,返回 None
- 配合进度可以判断具体状态:
- 进度 0% + current_state 非空 → 显示"未开始"
- 进度 > 0% + current_state 非空 → 显示 current_state.name正在进行
- current_state = None → 显示"已完成"
注意current_state 始终返回"下一个待执行的节点",配合进度可以判断具体状态
- 进度 0% + current_state 非空 → 显示"未开始"(还没开始执行,但知道第一个节点是什么)
- 进度 > 0% + current_state 非空 → 显示 current_state.name正在进行
- current_state = None → 显示"已完成"(没有待执行的节点了)
LAST模式的规则
- 返回最后一个已完成的节点
- 如果没有完成任何节点,返回 None
"""
# 使用 get_next_pending_state 获取下一个待执行的节点
next_pending = get_next_pending_state(business_object, include_parameters=False)
from django.conf import settings
mode = getattr(settings, 'STATEFLOW_CURRENT_STATE_MODE', 'NEXT')
if next_pending:
return next_pending['state']
# 所有节点都已完成,返回 None
return None
if mode == 'LAST':
return get_last_completed_state(business_object)
else: # 默认 'NEXT'
return get_next_pending_state_simple(business_object)
def get_business_object_state_status(business_object: 'models.BusinessObject', state: 'models.State') -> str:
@@ -187,21 +229,42 @@ def get_current_state_parameters(business_object: 'models.BusinessObject') -> Li
return []
def get_display_status(business_object: 'models.BusinessObject') -> str:
"""
获取用于显示的状态文本
规则:
- 如果没有 business_object返回第一个节点名称如果有流程否则返回空字符串
- 如果 current_state 为 None返回"已完成"
- 否则:返回 current_state 的名称
注意:此函数废除了"未开始"的概念,直接显示节点名称
返回值: 状态显示文本(字符串)
"""
if not business_object:
return ''
current_state = get_business_object_current_state(business_object)
if current_state is None:
# 没有待执行的节点,已完成
return '已完成'
# 直接返回当前状态名称,不管进度如何
return current_state.name
def get_overall_status(business_object: 'models.BusinessObject') -> str:
"""
获取业务对象的整体状态
返回值:
- 'not_started': 未开始(没有任何有效的完成记录)
- 'in_progress': 进行中(有部分状态已完成,但未完成所有)
- 'completed': 已完成(所有状态都已完成)
注意:废除了 'not_started' 状态进度为0时也返回 'in_progress'
"""
# 检查是否有任何有效的完成记录
has_completed = business_object.state_logs.filter(is_cancelled=False).exists()
if not has_completed:
return 'not_started'
# 检查是否有下一个待执行节点
next_pending = get_next_pending_state(business_object, include_parameters=False)