Files
jyls_django/User/utils.py

738 lines
30 KiB
Python
Raw Normal View History

2025-12-30 15:55:20 +08:00
"""
审批相关的工具函数
"""
2025-12-31 12:28:10 +08:00
import json
from datetime import datetime
2026-01-08 17:24:00 +08:00
from .models import OperationLog, User, Team, Approval
2025-12-30 15:55:20 +08:00
def is_department_id(value):
"""
判断personincharge字段的值是部门ID还是审批员用户名
统一规则
- 如果是纯数字字符串 "1", "2", "123"表示部门ID
- 如果包含非数字字符 "张三", "李四"表示审批员用户名
Args:
value: personincharge字段的值字符串
Returns:
bool: True表示是部门IDFalse表示是审批员用户名
示例:
>>> is_department_id("1")
True
>>> is_department_id("123")
True
>>> is_department_id("张三")
False
>>> is_department_id("dept:1")
False
"""
if not value:
return False
# 判断是否为纯数字字符串(去除首尾空格)
return str(value).strip().isdigit()
def format_personincharge(value, is_department=False):
"""
格式化personincharge字段的值
统一规则
- 如果是部门ID确保是纯数字字符串
- 如果是审批员用户名保持原样
Args:
value: 部门ID整数或字符串或审批员用户名字符串
is_department: 是否为部门ID默认False审批员用户名
Returns:
str: 格式化后的personincharge值
"""
if not value:
return ''
if is_department:
# 部门ID转换为字符串确保是纯数字
try:
return str(int(value))
except (ValueError, TypeError):
raise ValueError(f"部门ID必须是数字当前值: {value}")
else:
# 审批员用户名:保持原样,但确保是字符串
return str(value).strip()
2025-12-31 12:28:10 +08:00
def log_operation(request, operation_type, module, action, target_type, target_id=None,
target_name=None, old_data=None, new_data=None, remark=None):
"""
记录操作日志
Args:
request: Django request对象
operation_type: 操作类型DELETE, CREATE, UPDATE, APPROVE等
module: 模块名称User, Business, Finance等
action: 操作描述"删除用户""创建立项"
target_type: 目标类型如User, ProjectRegistration等
target_id: 目标ID
target_name: 目标名称如用户名项目名等
old_data: 操作前的数据字典会自动转换为JSON
new_data: 操作后的数据字典会自动转换为JSON
remark: 备注信息
Returns:
OperationLog对象
"""
try:
# 获取操作人信息
token = request.META.get('token') or request.META.get('HTTP_AUTHORIZATION', '').replace('Bearer ', '')
operator = '未知用户'
operator_id = None
if token:
try:
user = User.objects.get(token=token, is_deleted=False)
operator = user.username
operator_id = user.id
except User.DoesNotExist:
pass
# 获取IP地址
ip_address = request.META.get('HTTP_X_FORWARDED_FOR', '').split(',')[0].strip()
if not ip_address:
ip_address = request.META.get('REMOTE_ADDR', '')
# 获取用户代理
user_agent = request.META.get('HTTP_USER_AGENT', '')
# 转换数据为JSON字符串
old_data_str = json.dumps(old_data, ensure_ascii=False) if old_data else None
new_data_str = json.dumps(new_data, ensure_ascii=False) if new_data else None
# 创建日志记录
log = OperationLog.objects.create(
operator=operator,
operator_id=operator_id,
operation_type=operation_type,
module=module,
action=action,
target_type=target_type,
target_id=str(target_id) if target_id else None,
target_name=target_name,
old_data=old_data_str,
new_data=new_data_str,
ip_address=ip_address,
user_agent=user_agent,
request_path=request.path,
remark=remark
)
return log
except Exception as e:
# 日志记录失败不应该影响主业务流程
import logging
logger = logging.getLogger(__name__)
logger.error(f"记录操作日志失败: {str(e)}")
return None
2026-01-08 17:24:00 +08:00
def create_team_approval(team_name, title, content, approval_type, user_id, request=None):
"""
根据团队类型创建审批流程
规则
- 个人团队personal不需要审核人直接抄送财务personincharge设为"财务"
- 团队team需要指定审核人可以多个审核通过后才抄送财务
Args:
team_name: 团队名称
title: 审批标题
content: 审批内容
approval_type: 审批类型"立项登记""付款申请"
user_id: 关联的业务ID字符串
request: Django request对象可选用于记录日志
Returns:
Approval对象或None
"""
try:
# 查找团队
team = Team.objects.prefetch_related('approvers').filter(name=team_name, is_deleted=False).first()
if not team:
# 如果找不到团队,使用默认流程(需要审核人)
return None
today = datetime.now().strftime("%Y-%m-%d")
if team.team_type == 'personal':
# 个人团队:直接抄送财务,不需要审核人
approval = Approval.objects.create(
title=title,
content=content,
times=today,
personincharge='财务', # 直接抄送财务
state='已抄送财务', # 直接标记为已抄送财务
type=approval_type,
user_id=str(user_id)
)
return approval
elif team.team_type == 'team':
# 团队:需要审核人审核
approvers = team.approvers.filter(is_deleted=False)
if not approvers.exists():
# 如果没有审核人返回None应该在前端验证
return None
# 将审核人用户名用逗号连接(多个审核人)
approver_names = ','.join([approver.username for approver in approvers])
approval = Approval.objects.create(
title=title,
content=content,
times=today,
personincharge=approver_names, # 多个审核人用逗号分隔
state='审核中',
type=approval_type,
user_id=str(user_id)
)
return approval
return None
except Exception as e:
import logging
logger = logging.getLogger(__name__)
logger.error(f"创建团队审批失败: {str(e)}")
return None
def get_team_approval_info(team_name):
"""
获取团队的审批信息
Args:
team_name: 团队名称
Returns:
dict: {
'team_type': 'personal' 'team',
'needs_approval': True/False, # 是否需要审核
'approvers': [{'id': 1, 'username': '张三'}, ...], # 审核人列表
'direct_to_finance': True/False # 是否直接抄送财务
}
"""
try:
team = Team.objects.prefetch_related('approvers').filter(name=team_name, is_deleted=False).first()
if not team:
return {
'team_type': None,
'needs_approval': True, # 默认需要审核
'approvers': [],
'direct_to_finance': False
}
approvers = list(team.approvers.filter(is_deleted=False).values('id', 'username'))
return {
'team_type': team.team_type,
'needs_approval': team.team_type == 'team',
'approvers': approvers,
'direct_to_finance': team.team_type == 'personal'
}
except Exception as e:
import logging
logger = logging.getLogger(__name__)
logger.error(f"获取团队审批信息失败: {str(e)}")
return {
'team_type': None,
'needs_approval': True,
'approvers': [],
'direct_to_finance': False
}
2026-01-12 22:20:36 +08:00
2026-01-15 11:41:49 +08:00
def normalize_approvers_param(approvers, personincharge):
"""
兼容旧接口如果未传 approvers则使用 personincharge
personincharge 支持单个值逗号分隔字符串或列表格式
"""
if approvers:
return approvers
if personincharge:
return personincharge
return approvers
def build_missing_approvers_message(team_name, approvers):
"""
统一生成缺少审核人的详细错误文案
适用于团队类型需要审批但未能解析到有效审核人的情况
"""
try:
approvers_missing = approvers is None
approvers_empty = approvers == "" or approvers == []
approvers_provided = not approvers_missing and not approvers_empty
team = None
if team_name:
team = Team.objects.prefetch_related('approvers').filter(
name=team_name, is_deleted=False
).first()
if not team_name:
return "当前用户未绑定团队,无法自动获取审核人,请传 approvers 参数或先配置团队。"
if not team:
return f'团队"{team_name}"不存在或已被删除,请检查团队配置或传 approvers 参数。'
if team.team_type != "team":
return f'团队"{team_name}"为个人团队,无需审核人。'
if approvers_empty:
return "已传 approvers 但为空请传入有效的审核人列表推荐ID数组如[1,2,3])。"
if approvers_provided:
approvers_list = parse_approvers(approvers)
if not approvers_list:
return "已传 approvers 但解析失败请按推荐格式传入用户ID数组如 [1,2,3]。"
invalid = [
name for name in approvers_list
if not User.objects.filter(username=name, is_deleted=False).exists()
]
if invalid and len(invalid) == len(approvers_list):
return f'已传 approvers但全部审核人无效/不存在:{", ".join(invalid)}。请更换有效审核人或调整团队配置。'
if invalid:
return f'已传 approvers但部分审核人无效{", ".join(invalid)}。请移除无效人员或补充有效审核人。'
return "审核人参数已传入但审批创建失败,请检查团队配置或权限。"
# 未传 approvers尝试使用团队配置
team_approvers = list(
team.approvers.filter(is_deleted=False).values_list("username", flat=True)
)
if not team_approvers:
return f'未传 approvers且团队"{team_name}"未配置审核人,请先配置团队审核人或传 approvers 参数。'
valid_team_approvers = [
name for name in team_approvers
if User.objects.filter(username=name, is_deleted=False).exists()
]
if not valid_team_approvers:
return f'未传 approvers且团队"{team_name}"配置的审核人无效或已被删除,请重新配置或传 approvers 参数。'
return (
f'未传 approvers。团队"{team_name}"为团队类型,需要审核人。团队当前审核人:'
f'{", ".join(valid_team_approvers)}'
'请传 approvers 参数推荐ID数组如[1,2,3]),或调整团队审核人配置。'
)
except Exception:
return "团队类型需要指定审核人,请提供 approvers 参数并检查团队配置。"
2026-01-12 22:20:36 +08:00
def parse_approvers(approvers):
"""
解析审核人列表统一处理数组和字符串格式
2026-01-12 23:17:39 +08:00
支持用户ID列表推荐和用户名列表兼容旧接口
2026-01-12 22:20:36 +08:00
Args:
approvers: 审核人列表可以是
2026-01-12 23:17:39 +08:00
- 数组格式ID列表推荐[1, 2, 3] ["1", "2", "3"]
- 数组格式用户名列表兼容["张三", "李四", "王五"]
2026-01-15 17:24:43 +08:00
- JSON字符串格式ID列表"[1,2,3]" "[5]" '"[1,2,3]"'
- JSON字符串格式带空格"[ 5 ]" "[1, 2, 3]"
2026-01-13 17:35:09 +08:00
- JSON字符串格式用户名列表兼容'["张三","李四","王五"]'
2026-01-15 17:24:43 +08:00
- 字符串格式逗号分隔的ID"1,2,3" "5"
2026-01-12 23:17:39 +08:00
- 字符串格式逗号分隔的用户名兼容"张三,李四,王五"
2026-01-12 22:20:36 +08:00
- None: 返回空列表
Returns:
2026-01-12 23:17:39 +08:00
list: 审核人用户名列表 ["张三", "李四", "王五"]
2026-01-12 22:20:36 +08:00
"""
2026-01-15 17:24:43 +08:00
import json
2026-01-12 22:20:36 +08:00
if not approvers:
return []
2026-01-12 23:17:39 +08:00
approvers_list = []
2026-01-12 22:20:36 +08:00
if isinstance(approvers, str):
2026-01-15 17:24:43 +08:00
# 去除首尾空格
approvers = approvers.strip()
# 如果字符串为空,返回空列表
if not approvers:
return []
# 尝试解析 JSON 字符串格式(如 "[1,2,3]" 或 "[5]" 或 '"[1,2,3]"'
2026-01-13 17:35:09 +08:00
try:
# 先尝试直接解析 JSON
parsed = json.loads(approvers)
if isinstance(parsed, list):
2026-01-15 17:24:43 +08:00
approvers_list = [str(a).strip() for a in parsed if a is not None and str(a).strip()]
elif isinstance(parsed, str):
# 如果是字符串可能是被双重编码的JSON字符串再解析一次
# 例如:'"[5]"' -> "[5]" -> [5]
try:
parsed2 = json.loads(parsed)
if isinstance(parsed2, list):
approvers_list = [str(a).strip() for a in parsed2 if a is not None and str(a).strip()]
elif isinstance(parsed2, (int, str)):
# 单个值,转换为列表
approvers_list = [str(parsed2).strip()]
except (json.JSONDecodeError, ValueError, TypeError):
# 双重解析失败,可能是普通字符串,按逗号分隔处理
approvers_list = [parsed.strip()] if parsed.strip() else []
elif isinstance(parsed, (int, str)):
# 单个值(数字或字符串),转换为列表
approvers_list = [str(parsed).strip()]
2026-01-13 17:35:09 +08:00
except (json.JSONDecodeError, ValueError, TypeError):
# JSON 解析失败,尝试按逗号分隔处理
2026-01-15 17:24:43 +08:00
# 例如:"1,2,3" 或 "5" 或 "张三,李四"
2026-01-13 17:35:09 +08:00
approvers_list = [a.strip() for a in approvers.split(',') if a.strip()]
2026-01-12 22:20:36 +08:00
elif isinstance(approvers, list):
# 数组格式(推荐)
2026-01-15 17:24:43 +08:00
approvers_list = [str(a).strip() for a in approvers if a is not None and str(a).strip()]
elif isinstance(approvers, (int, float)):
# 单个数字,转换为列表
approvers_list = [str(int(approvers))]
2026-01-12 22:20:36 +08:00
else:
return []
2026-01-12 23:17:39 +08:00
if not approvers_list:
return []
# 判断是ID还是用户名如果第一个元素是纯数字则认为是ID列表
# 否则认为是用户名列表(兼容旧接口)
first_item = approvers_list[0]
is_id_list = str(first_item).strip().isdigit()
if is_id_list:
# ID列表转换为用户名列表
try:
user_ids = [int(uid) for uid in approvers_list]
users = User.objects.filter(id__in=user_ids, is_deleted=False)
# 保持原有顺序
user_dict = {user.id: user.username for user in users}
username_list = [user_dict.get(uid, None) for uid in user_ids]
# 过滤掉不存在的用户
username_list = [name for name in username_list if name is not None]
return username_list
except (ValueError, TypeError):
# 如果转换失败,返回空列表
return []
else:
# 用户名列表(兼容旧接口):直接返回
return approvers_list
2026-01-12 22:20:36 +08:00
2026-01-13 17:47:36 +08:00
def get_approvers_from_record(business_record, approval=None):
2026-01-12 22:20:36 +08:00
"""
从业务记录中获取审核人列表统一方法
优先从 approvers_order 字段读取JSON格式
如果没有则从 Approval.content 字段解析兼容旧数据
Args:
business_record: 业务记录对象 Schedule, Reimbursement, Income
2026-01-13 17:47:36 +08:00
approval: Approval对象可选用于从content字段解析审核人列表
2026-01-12 22:20:36 +08:00
Returns:
list: 审核人列表 ["张三", "李四", "王五"]如果没有则返回空列表
"""
import json
2026-01-13 17:47:36 +08:00
import logging
logger = logging.getLogger(__name__)
2026-01-12 22:20:36 +08:00
# 优先从 approvers_order 字段读取
if hasattr(business_record, 'approvers_order') and business_record.approvers_order:
try:
approvers_list = json.loads(business_record.approvers_order)
if isinstance(approvers_list, list):
2026-01-13 17:47:36 +08:00
logger.info(f"get_approvers_from_record: 从 business_record.approvers_order 获取审核人列表: {approvers_list}")
2026-01-12 22:20:36 +08:00
return approvers_list
2026-01-13 17:47:36 +08:00
except (json.JSONDecodeError, TypeError) as e:
logger.warning(f"get_approvers_from_record: 解析 approvers_order 失败: {e}")
2026-01-12 22:20:36 +08:00
2026-01-13 17:47:36 +08:00
# 如果 business_record 没有 approvers_order 字段,尝试从 Approval.content 字段解析
if approval and approval.content:
try:
# 格式:审批流程:张三 → 李四 → 王五 → 财务(按顺序审批),当前审批人:张三
if "审批流程:" in approval.content:
# 提取审批流程部分
flow_part = approval.content.split("审批流程:")[1].split("(按顺序审批)")[0]
# 分割审核人(使用 → 分隔)
approvers_list = [a.strip() for a in flow_part.split("") if a.strip()]
# 移除最后的"财务"
if approvers_list and approvers_list[-1].strip() == "财务":
approvers_list = approvers_list[:-1]
if approvers_list:
logger.info(f"get_approvers_from_record: 从 Approval.content 解析审核人列表: {approvers_list}")
return approvers_list
except Exception as e:
logger.warning(f"get_approvers_from_record: 从 Approval.content 解析失败: {e}")
logger.info(f"get_approvers_from_record: 未找到审核人列表")
2026-01-12 22:20:36 +08:00
return []
def process_approval_flow(approval, business_record, current_approver, state,
approval_type, final_state_map=None):
"""
统一的审核流程处理函数
规则
- 如果 business_record approvers_order 字段从该字段读取审核人列表
- 如果没有审核人列表个人团队直接抄送财务
- 如果有审核人列表多人团队按顺序流转
- 最后一个审核人通过后抄送财务
- 财务审核通过后完成审批
Args:
approval: Approval对象
business_record: 业务记录对象 Schedule, Reimbursement, Income
current_approver: 当前审核人 approval.personincharge 获取
state: 审核状态"已通过" "未通过"
approval_type: 审批类型"待办""报销申请"
final_state_map: 状态映射字典格式{"已通过": "已完成", "未通过": "未通过"}
Returns:
tuple: (是否完成, 错误信息)
"""
import json
from .models import Approval
if final_state_map is None:
final_state_map = {"已通过": "已完成", "未通过": "未通过"}
# 如果审核不通过,直接结束
if state == "未通过":
approval.state = "未通过"
approval.save(update_fields=['state'])
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 approval.personincharge == "财务" and approval.state == "已抄送财务":
# 财务部审核逻辑:财务部只需要一个人审核完即可完成
if state == "已通过":
approval.state = "已通过"
approval.save(update_fields=['state'])
if business_record and hasattr(business_record, 'state'):
business_record.state = final_state_map.get("已通过", "已完成")
business_record.save(update_fields=['state'])
return True, None
# 获取审核人列表
2026-01-13 17:47:36 +08:00
approvers_list = get_approvers_from_record(business_record, approval=approval)
import logging
logger = logging.getLogger(__name__)
logger.info(f"process_approval_flow: 审批类型={approval_type}, 当前审核人={current_approver}, 审核状态={state}, 审核人列表={approvers_list}")
2026-01-12 22:20:36 +08:00
if not approvers_list:
# 没有审核人列表(个人团队或直接到财务)
# 如果当前不是财务,则抄送财务
if approval.personincharge != "财务":
approval.personincharge = "财务"
approval.state = "已抄送财务"
if "已抄送财务" not in approval.content:
approval.content = approval.content + ",已抄送财务"
approval.save(update_fields=['state', 'personincharge', 'content'])
if business_record and hasattr(business_record, 'state'):
business_record.state = "待财务处理"
business_record.save(update_fields=['state'])
return False, None
# 有审核人列表(多人团队),按顺序流转
try:
current_index = approvers_list.index(current_approver)
2026-01-13 17:47:36 +08:00
logger.info(f"process_approval_flow: 当前审核人在列表中的位置: {current_index}/{len(approvers_list)-1}")
2026-01-12 22:20:36 +08:00
except ValueError:
# 当前审核人不在列表中,可能是旧数据,直接抄送财务
2026-01-13 17:47:36 +08:00
logger.warning(f"process_approval_flow: 当前审核人 {current_approver} 不在审核人列表中 {approvers_list},直接抄送财务")
2026-01-12 22:20:36 +08:00
approval.personincharge = "财务"
approval.state = "已抄送财务"
approval.save(update_fields=['state', 'personincharge'])
return False, None
# 检查是否还有下一个审核人
if current_index < len(approvers_list) - 1:
# 不是最后一个审核人,流转到下一个
next_approver = approvers_list[current_index + 1]
2026-01-13 17:47:36 +08:00
logger.info(f"process_approval_flow: 流转到下一个审核人: {next_approver} (位置: {current_index + 1})")
2026-01-12 22:20:36 +08:00
approval.personincharge = next_approver
approval.state = "审核中"
# 更新审批内容,显示当前审批人
if "当前审批人:" in approval.content:
approval.content = approval.content.replace(
f"当前审批人:{current_approver}",
f"当前审批人:{next_approver}"
)
approval.save(update_fields=['state', 'personincharge', 'content'])
2026-01-13 17:47:36 +08:00
logger.info(f"process_approval_flow: 已更新审批记录personincharge={next_approver}, state=审核中")
2026-01-12 22:20:36 +08:00
return False, None
else:
# 最后一个审核人,抄送财务
2026-01-13 17:47:36 +08:00
logger.info(f"process_approval_flow: 最后一个审核人已审核,流转到财务部")
2026-01-12 22:20:36 +08:00
approval.personincharge = "财务"
approval.state = "已抄送财务"
if "已抄送财务" not in approval.content:
approval.content = approval.content + ",已抄送财务"
approval.save(update_fields=['state', 'personincharge', 'content'])
if business_record and hasattr(business_record, 'state'):
business_record.state = "待财务处理"
business_record.save(update_fields=['state'])
2026-01-13 17:47:36 +08:00
logger.info(f"process_approval_flow: 已抄送财务部personincharge=财务, state=已抄送财务")
2026-01-12 22:20:36 +08:00
return False, None
def create_approval_with_team_logic(team_name, approvers, title, content, approval_type, user_id,
business_record=None, today=None):
"""
根据团队类型创建审批记录统一逻辑
规则
- 个人团队personal直接抄送财务personincharge="财务"state="已抄送财务"
- 团队team需要审核人按顺序审核最后抄送财务
- 无团队直接抄送财务
Args:
team_name: 团队名称
approvers: 审核人列表可以是数组或字符串多人团队时需要
2026-01-12 23:17:39 +08:00
- 推荐格式用户ID列表 [1, 2, 3] ["1", "2", "3"]
- 兼容格式用户名列表 ["张三", "李四", "王五"]
- 字符串格式逗号分隔的ID或用户名 "1,2,3" "张三,李四,王五"
2026-01-12 22:20:36 +08:00
title: 审批标题
content: 审批内容
approval_type: 审批类型"立项登记""付款申请"
user_id: 关联的业务ID字符串
business_record: 业务记录对象可选用于更新状态和存储approvers_order
today: 日期字符串可选格式YYYY-MM-DD
Returns:
tuple: (approval对象, approvers_order_json, 是否需要审核)
"""
import json
from datetime import datetime
from .models import Team, Approval, User
if today is None:
today = datetime.now().strftime("%Y-%m-%d")
# 查找团队
team = None
if team_name:
try:
team = Team.objects.prefetch_related('approvers').filter(name=team_name, is_deleted=False).first()
except:
team = None
# 判断团队类型
if not team_name or not team or (team and team.team_type == 'personal'):
# 个人团队或无团队:直接到财务团队审核
approval = Approval.objects.create(
title=title,
content=content,
times=today,
personincharge="财务",
state="已抄送财务",
type=approval_type,
user_id=str(user_id)
)
# 更新业务记录状态
if business_record:
business_record.state = "待财务处理"
business_record.save(update_fields=['state'])
return approval, None, False
elif team and team.team_type == 'team':
# 团队类型:需要审核人审核(按顺序)
approvers_list = parse_approvers(approvers)
# 如果没有传入审核人,使用团队的审核人
if not approvers_list:
2026-01-13 17:25:35 +08:00
team_approvers = team.approvers.filter(is_deleted=False).order_by('id')
approvers_list = [approver.username for approver in team_approvers]
2026-01-12 22:20:36 +08:00
if not approvers_list:
return None, None, True # 需要审核但没有审核人
2026-01-13 17:25:35 +08:00
# 验证审核人是否存在,过滤掉无效的审核人
valid_approvers_list = []
invalid_approvers_list = []
2026-01-12 22:20:36 +08:00
for approver_name in approvers_list:
2026-01-13 17:25:35 +08:00
if User.objects.filter(username=approver_name, is_deleted=False).exists():
valid_approvers_list.append(approver_name)
else:
invalid_approvers_list.append(approver_name)
# 如果所有审核人都无效,返回 None
if not valid_approvers_list:
return None, None, True # 审核人不存在
# 使用有效的审核人列表
approvers_list = valid_approvers_list
2026-01-12 22:20:36 +08:00
# 将审核人顺序存储为JSON格式
approvers_order_json = json.dumps(approvers_list, ensure_ascii=False)
# 存储到业务记录
if business_record and hasattr(business_record, 'approvers_order'):
business_record.approvers_order = approvers_order_json
business_record.state = "审核中"
business_record.save(update_fields=['approvers_order', 'state'])
# 创建审批记录,第一个审核人
first_approver = approvers_list[0]
approvers_str = ''.join(approvers_list) # 使用箭头表示顺序
content_with_flow = f"{content},审批流程:{approvers_str} → 财务(按顺序审批),当前审批人:{first_approver}"
2026-01-13 17:47:36 +08:00
import logging
logger = logging.getLogger(__name__)
logger.info(f"create_approval_with_team_logic: 创建审批记录 - 审批类型={approval_type}, 审核人列表={approvers_list}, 第一个审核人={first_approver}, approvers_order_json={approvers_order_json}")
2026-01-12 22:20:36 +08:00
approval = Approval.objects.create(
title=title,
content=content_with_flow,
times=today,
personincharge=first_approver,
state="审核中",
type=approval_type,
user_id=str(user_id)
)
2026-01-13 17:47:36 +08:00
logger.info(f"create_approval_with_team_logic: 审批记录已创建 - ID={approval.id}, personincharge={approval.personincharge}, state={approval.state}")
2026-01-12 22:20:36 +08:00
return approval, approvers_order_json, True
else:
# 找不到团队或团队类型未知,直接抄送财务
approval = Approval.objects.create(
title=title,
content=content,
times=today,
personincharge="财务",
state="已抄送财务",
type=approval_type,
user_id=str(user_id)
)
# 更新业务记录状态
if business_record:
business_record.state = "待财务处理"
business_record.save(update_fields=['state'])
return approval, None, False