投标待办加入提交人

This commit is contained in:
ddrwode
2026-01-30 16:04:40 +08:00
parent 00355e8f8b
commit 8442163a24
3 changed files with 112 additions and 60 deletions

View File

@@ -594,9 +594,11 @@ def get_approvers_from_record(business_record, approval=None):
flow_part = flow_part.split("(按顺序审批)")[0]
# 分割审核人(使用 → 分隔)
approvers_list = [a.strip() for a in flow_part.split("") if a.strip()]
# 移除最后的"财务"或"财务部"(兼容两种格式)
if approvers_list and approvers_list[-1].strip() in ("财务", "财务部"):
approvers_list = approvers_list[:-1]
# 移除最后的"财务"或"财务部"(兼容两种格式),以及"申请人(待查看)"(投标/立项最后一步)
if approvers_list:
last = approvers_list[-1].strip()
if last in ("财务", "财务部") or last == "申请人(待查看)":
approvers_list = approvers_list[:-1]
if approvers_list:
logger.info(f"get_approvers_from_record: 从 Approval.content 解析审核人列表: {approvers_list}")
return approvers_list
@@ -651,6 +653,29 @@ def process_approval_flow(approval, business_record, current_approver, state,
return True, None
# 申请人待查看阶段:当前步骤是申请人待查看,申请人查看后完成(投标/立项不再给财务部)
applicant = getattr(approval, 'applicant', None)
if approval.state == "待查看" and applicant and approval.personincharge == applicant:
if state == "已通过" or not state:
approval.state = "已通过"
if "已通过" not in approval.content:
approval.content = (approval.content or "") + ",申请人已查看"
approval.save(update_fields=['state', 'content'])
if business_record and hasattr(business_record, 'state'):
business_record.state = final_state_map.get("已通过", "已通过")
business_record.save(update_fields=['state'])
return True, None
if state == "未通过":
approval.state = "未通过"
if rejection_reason:
approval.rejection_reason = rejection_reason
approval.save(update_fields=['state', 'rejection_reason'])
if business_record and hasattr(business_record, 'state'):
business_record.state = final_state_map.get("未通过", "未通过")
business_record.save(update_fields=['state'])
return True, None
return False, None
# 检查当前是否已经是财务审核部门ID或“财务”字符串均视为财务阶段
if is_finance_personincharge(approval.personincharge) and approval.state == "已抄送财务":
# 财务部只需要查看,不需要审批,查看后直接完成
@@ -729,18 +754,27 @@ def process_approval_flow(approval, business_record, current_approver, state,
logger.info(f"process_approval_flow: 已更新审批记录personincharge={next_approver}, state=审核中")
return False, None
else:
# 最后一个审核人抄送财务
# 最后一个审核人已通过:投标/立项转申请人待查看,其他类型抄送财务
applicant = getattr(approval, 'applicant', None)
if approval_type in ("投标登记", "立项登记") and applicant:
logger.info(f"process_approval_flow: 最后一个审核人已审核,流转到申请人待查看: {applicant}")
approval.personincharge = applicant
approval.state = "待查看"
if "待申请人查看" not in (approval.content or ""):
approval.content = (approval.content or "") + ",待申请人查看"
approval.save(update_fields=['state', 'personincharge', 'content'])
# 不更新业务记录状态,等申请人查看后再设为已通过
return False, None
# 其他类型:抄送财务
logger.info(f"process_approval_flow: 最后一个审核人已审核,流转到财务部")
finance_personincharge = get_finance_personincharge_value()
approval.personincharge = finance_personincharge
approval.state = "已抄送财务"
if "已抄送财务" not in approval.content and "已抄送财务部" not in approval.content:
approval.content = approval.content + ",已抄送财务部"
if "已抄送财务" not in (approval.content or "") and "已抄送财务部" not in (approval.content or ""):
approval.content = (approval.content or "") + ",已抄送财务部"
approval.save(update_fields=['state', 'personincharge', 'content'])
if business_record and hasattr(business_record, 'state'):
# 抄送财务时就已经审核通过,财务只是查看
# 使用 final_state_map 确保状态映射正确(如待办类型:已通过 -> 已完成)
final_state = final_state_map.get("已通过", "已通过")
business_record.state = final_state
business_record.save(update_fields=['state'])
@@ -750,13 +784,14 @@ def process_approval_flow(approval, business_record, current_approver, state,
def create_approval_with_team_logic(team_name, approvers, title, content, approval_type, user_id,
business_record=None, today=None):
business_record=None, today=None, applicant=None):
"""
根据团队类型创建审批记录(统一逻辑)
规则:
- 个人团队personal直接抄送财务personincharge=财务部IDstate="已抄送财务"
- 团队team需要审核人按顺序审核最后抄送财务
- 投标登记/立项登记:最后一步给申请人,生成「待查看」待办,申请人查看后完成(不再给财务部)
- 其他类型团队team需要审核人按顺序审核最后抄送财务
- 无团队:直接抄送财务
注意personincharge字段统一使用财务部ID优先或回退到"财务"字符串
@@ -764,15 +799,13 @@ def create_approval_with_team_logic(team_name, approvers, title, content, approv
Args:
team_name: 团队名称
approvers: 审核人列表(可以是数组或字符串,多人团队时需要)
- 推荐格式用户ID列表如 [1, 2, 3] 或 ["1", "2", "3"]
- 兼容格式:用户名列表,如 ["张三", "李四", "王五"]
- 字符串格式逗号分隔的ID或用户名"1,2,3""张三,李四,王五"
title: 审批标题
content: 审批内容
approval_type: 审批类型(如"立项登记""付款申请"等)
approval_type: 审批类型(如"立项登记""投标登记""付款申请"等)
user_id: 关联的业务ID字符串
business_record: 业务记录对象(可选用于更新状态和存储approvers_order
business_record: 业务记录对象(可选)
today: 日期字符串可选格式YYYY-MM-DD
applicant: 申请人用户名(可选,投标/立项时填,最后一步生成待查看待办给申请人)
Returns:
tuple: (approval对象, approvers_order_json, 是否需要审核)
@@ -825,7 +858,12 @@ def create_approval_with_team_logic(team_name, approvers, title, content, approv
# 创建审批记录,第一个审核人
first_approver = approvers_list[0]
approvers_str = ''.join(approvers_list) # 使用箭头表示顺序
content_with_flow = f"{content},审批流程:{approvers_str} → 财务部(按顺序审批),当前审批人:{first_approver}"
# 投标登记/立项登记:最后一步给申请人(待查看),不再给财务部
if approval_type in ("投标登记", "立项登记") and applicant:
flow_suffix = " → 申请人(待查看)"
else:
flow_suffix = " → 财务部(按顺序审批)"
content_with_flow = f"{content},审批流程:{approvers_str}{flow_suffix},当前审批人:{first_approver}"
import logging
logger = logging.getLogger(__name__)
@@ -838,7 +876,8 @@ def create_approval_with_team_logic(team_name, approvers, title, content, approv
personincharge=first_approver,
state="审核中",
type=approval_type,
user_id=str(user_id)
user_id=str(user_id),
applicant=applicant
)
logger.info(f"create_approval_with_team_logic: 审批记录已创建 - ID={approval.id}, personincharge={approval.personincharge}, state={approval.state}")
@@ -848,7 +887,22 @@ def create_approval_with_team_logic(team_name, approvers, title, content, approv
# 如果没有传入审核人,则根据团队类型判断
# 判断团队类型
if not team_name or not team or (team and team.team_type == 'personal'):
# 个人团队或无团队:直接到财务团队审核
# 投标登记/立项登记且传入了申请人:最后一步给申请人,生成待查看待办(不再给财务部)
if approval_type in ("投标登记", "立项登记") and applicant:
content_to_save = content + ",待申请人查看"
approval = Approval.objects.create(
title=title,
content=content_to_save,
times=today,
personincharge=applicant,
state="待查看",
type=approval_type,
user_id=str(user_id),
applicant=applicant
)
# 不更新业务记录状态,等申请人查看后再设为已通过
return approval, None, False
# 其他类型:个人团队或无团队,直接到财务团队审核
finance_personincharge = get_finance_personincharge_value()
content_to_save = content
if "已抄送财务" not in content and "已抄送财务部" not in content:
@@ -861,11 +915,11 @@ def create_approval_with_team_logic(team_name, approvers, title, content, approv
personincharge=finance_personincharge,
state="已抄送财务",
type=approval_type,
user_id=str(user_id)
user_id=str(user_id),
applicant=applicant
)
# 更新业务记录状态:抄送财务时就已经审核通过,财务只是查看
# 对于待办和结案申请类型,状态应该是"已完成",其他类型是"已通过"
if business_record:
if approval_type in ["待办", "结案申请"]:
business_record.state = "已完成"
@@ -911,8 +965,12 @@ def create_approval_with_team_logic(team_name, approvers, title, content, approv
# 创建审批记录,第一个审核人
first_approver = approvers_list[0]
approvers_str = ''.join(approvers_list) # 使用箭头表示顺序
content_with_flow = f"{content},审批流程:{approvers_str} → 财务部(按顺序审批),当前审批人:{first_approver}"
approvers_str = ''.join(approvers_list)
if approval_type in ("投标登记", "立项登记") and applicant:
flow_suffix = " → 申请人(待查看)"
else:
flow_suffix = " → 财务部(按顺序审批)"
content_with_flow = f"{content},审批流程:{approvers_str}{flow_suffix},当前审批人:{first_approver}"
import logging
logger = logging.getLogger(__name__)
@@ -925,7 +983,8 @@ def create_approval_with_team_logic(team_name, approvers, title, content, approv
personincharge=first_approver,
state="审核中",
type=approval_type,
user_id=str(user_id)
user_id=str(user_id),
applicant=applicant
)
logger.info(f"create_approval_with_team_logic: 审批记录已创建 - ID={approval.id}, personincharge={approval.personincharge}, state={approval.state}")
@@ -946,11 +1005,11 @@ def create_approval_with_team_logic(team_name, approvers, title, content, approv
personincharge=finance_personincharge,
state="已抄送财务",
type=approval_type,
user_id=str(user_id)
user_id=str(user_id),
applicant=applicant
)
# 更新业务记录状态:抄送财务时就已经审核通过,财务只是查看
# 对于待办和结案申请类型,状态应该是"已完成",其他类型是"已通过"
if business_record:
if approval_type in ["待办", "结案申请"]:
business_record.state = "已完成"

View File

@@ -802,8 +802,8 @@ class roxyExhibition(APIView):
# 单个值
query = Q(state=filter_state)
else:
# 默认状态筛选:审核中、已抄送财务;非财务也包含"已通过"以便按申请人/审批人过滤后展示(待办、投标登记等)
query = Q(state__in=["审核中", "已抄送财务", "已通过"])
# 默认状态筛选:审核中、已抄送财务、待查看(投标/立项最后一步给申请人)、已通过
query = Q(state__in=["审核中", "已抄送财务", "待查看", "已通过"])
# 添加筛选条件
if filter_type:
@@ -1082,23 +1082,21 @@ class roxyExhibition(APIView):
# 计算 approval_status与返回数据时的逻辑保持一致
approval_status = "审批中" # 默认状态
# 待办类型的状态显示逻辑:审核中->审核中,已抄送财务->待查看,已通过->已完成
# 待办类型的状态显示逻辑:审核中->审核中,已抄送财务/待查看->待查看,已通过->已完成
if info.type == "待办":
if info.state == "审核中":
approval_status = "审核中"
elif info.state == "已抄送财务":
elif info.state in ("已抄送财务", "待查看"):
approval_status = "待查看"
elif info.state == "已通过":
approval_status = "已完成"
elif info.state == "未通过":
approval_status = "审核中" # 未通过也可以继续审批流程
else:
# 其他类型的状态显示逻辑:审核中->审批中,已抄送财务->待查看,已通过->已完成
if info.state == "已抄送财务":
# 已抄送财务时,显示"待查看"(财务部需要查看)
# 其他类型:审核中->审批中,已抄送财务/待查看->待查看,已通过->已完成
if info.state in ("已抄送财务", "待查看"):
approval_status = "待查看"
elif info.state == "已通过":
# 审批记录状态为"已通过"(通常是财务查看后),显示"已完成"
approval_status = "已完成"
elif info.state == "审核中":
approval_status = "审批中"
@@ -1326,23 +1324,21 @@ class roxyExhibition(APIView):
# - "已通过" -> "已完成"(财务查看了之后)
approval_status = "审批中" # 默认状态
# 待办类型的状态显示逻辑:审核中->审核中,已抄送财务->待查看,已通过->已完成
# 待办类型的状态显示逻辑:审核中->审核中,已抄送财务/待查看->待查看,已通过->已完成
if info.type == "待办":
if info.state == "审核中":
approval_status = "审核中"
elif info.state == "已抄送财务":
elif info.state in ("已抄送财务", "待查看"):
approval_status = "待查看"
elif info.state == "已通过":
approval_status = "已完成"
elif info.state == "未通过":
approval_status = "审核中" # 未通过也可以继续审批流程
else:
# 其他类型的状态显示逻辑:审核中->审批中,已抄送财务->待查看,已通过->已完成
if info.state == "已抄送财务":
# 已抄送财务时,显示"待查看"(财务部需要查看)
# 其他类型:审核中->审批中,已抄送财务/待查看->待查看(投标/立项最后一步给申请人),已通过->已完成
if info.state in ("已抄送财务", "待查看"):
approval_status = "待查看"
elif info.state == "已通过":
# 审批记录状态为"已通过"(通常是财务查看后),显示"已完成"
approval_status = "已完成"
elif info.state == "审核中":
approval_status = "审批中"
@@ -1989,6 +1985,10 @@ class approvalProcessing(APIView):
except ProjectRegistration.DoesNotExist:
return Response({'status': 'error', 'message': '立项登记记录不存在或已被删除', 'code': 1}, status=status.HTTP_404_NOT_FOUND)
# 申请人待查看阶段:只传 type 和 id 不传 state 时,视为申请人查看完成(默认已通过)
if approval.state == "待查看" and getattr(approval, 'applicant', None) and approval.personincharge == approval.applicant and not state:
state = "已通过"
# 使用统一的审核流程处理函数
from User.utils import process_approval_flow
current_approver = approval.personincharge
@@ -2013,6 +2013,10 @@ class approvalProcessing(APIView):
except Bid.DoesNotExist:
return Response({'status': 'error', 'message': '投标登记记录不存在或已被删除', 'code': 1}, status=status.HTTP_404_NOT_FOUND)
# 申请人待查看阶段:只传 type 和 id 不传 state 时,视为申请人查看完成(默认已通过)
if approval.state == "待查看" and getattr(approval, 'applicant', None) and approval.personincharge == approval.applicant and not state:
state = "已通过"
# 使用统一的审核流程处理函数
from User.utils import process_approval_flow
current_approver = approval.personincharge