forked from erp-dev/erp
fix: current_state has been changed to a computed property
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user