This commit is contained in:
ddrwode
2026-01-12 23:17:39 +08:00
parent eb23734f0d
commit 78e9987123
4 changed files with 68 additions and 37 deletions

View File

@@ -258,27 +258,58 @@ def get_team_approval_info(team_name):
def parse_approvers(approvers):
"""
解析审核人列表,统一处理数组和字符串格式
支持用户ID列表推荐和用户名列表兼容旧接口
Args:
approvers: 审核人列表,可以是:
- 数组格式["张三", "李四", "王五"]
- 字符串格式(逗号分隔"张三,李四,王五"
- 数组格式ID列表推荐[1, 2, 3] 或 ["1", "2", "3"]
- 数组格式(用户名列表,兼容["张三", "李四", "王五"]
- 字符串格式逗号分隔的ID"1,2,3"
- 字符串格式(逗号分隔的用户名,兼容):"张三,李四,王五"
- None: 返回空列表
Returns:
list: 审核人列表,如 ["张三", "李四", "王五"]
list: 审核人用户名列表,如 ["张三", "李四", "王五"]
"""
if not approvers:
return []
approvers_list = []
if isinstance(approvers, str):
# 字符串格式:逗号分隔
return [a.strip() for a in approvers.split(',') if a.strip()]
approvers_list = [a.strip() for a in approvers.split(',') if a.strip()]
elif isinstance(approvers, list):
# 数组格式(推荐)
return [str(a).strip() for a in approvers if a]
approvers_list = [str(a).strip() for a in approvers if a]
else:
return []
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
def get_approvers_from_record(business_record):
@@ -433,6 +464,9 @@ 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: 审批类型(如"立项登记""付款申请"等)

View File

@@ -197,7 +197,7 @@ class Project(APIView):
responsiblefor = request.data.get('responsiblefor')
charge = request.data.get('charge')
contract = request.FILES.getlist('contract')
approvers = request.data.get('approvers') # 审核人列表(可选,多人团队时需要)
approvers = request.data.get('approvers') # 审核人列表(可选,多人团队时需要推荐用户ID数组如[1,2,3],兼容:用户名数组
# 兼容旧接口:如果传了 personincharge转换为 approvers
personincharge = request.data.get('personincharge')
if personincharge and not approvers:
@@ -606,7 +606,7 @@ class BidRegistration(APIView):
ProjectName = request.data.get('ProjectName')
times = request.data.get('times')
BiddingAnnouncement = request.FILES.getlist('BiddingAnnouncement')
approvers = request.data.get('approvers') # 审核人列表(可选,多人团队时需要)
approvers = request.data.get('approvers') # 审核人列表(可选,多人团队时需要推荐用户ID数组如[1,2,3],兼容:用户名数组
# 兼容旧接口:如果传了 personincharge转换为 approvers
personincharge = request.data.get('personincharge')
if personincharge and not approvers:
@@ -2006,8 +2006,9 @@ class CreateSchedule(APIView):
前端传参说明:
- approvers: 审核人列表(团队类型时需要)
* 可以是数组格式:["张三", "李四", "王五"](推荐,数组顺序即为审核顺序)
* 可以是逗号分隔的字符串:"张三,李四,王五"(字符串顺序即为审核顺序)
* 推荐格式用户ID数组如 [1, 2, 3]数组顺序即为审核顺序)
* 兼容格式:用户名数组,如 ["张三", "李四", "王五"](数组顺序即为审核顺序)
* 字符串格式逗号分隔的ID或用户名"1,2,3""张三,李四,王五"
* 如果不传,则使用团队配置的审核人(按团队审核人顺序)
:param request:
:param args:
@@ -2018,7 +2019,7 @@ class CreateSchedule(APIView):
tiems = request.data.get('tiems')
end_time = request.data.get('end_time')
remark = request.data.get('remark')
approvers = request.data.get('approvers') # 审核人列表(团队类型时需要)
approvers = request.data.get('approvers') # 审核人列表(团队类型时需要推荐用户ID数组如[1,2,3],兼容:用户名数组
if not all([title, tiems, end_time]):
return Response({'status': 'error', 'message': '缺少参数', 'code': 1}, status=status.HTTP_400_BAD_REQUEST)
@@ -2057,16 +2058,11 @@ class CreateSchedule(APIView):
elif team.team_type == 'team':
# 情况3团队类型需要审核人审核按顺序
# 优先使用前端传入的审核人列表,如果没有则使用团队的审核人
from User.utils import parse_approvers
if approvers:
# 解析审核人列表
if isinstance(approvers, str):
# 字符串格式:逗号分隔
approvers_list = [a.strip() for a in approvers.split(',') if a.strip()]
elif isinstance(approvers, list):
# 数组格式(推荐)
approvers_list = [str(a).strip() for a in approvers if a]
else:
approvers_list = []
# 使用统一的解析函数支持ID和用户名
approvers_list = parse_approvers(approvers)
else:
# 使用团队的审核人(按团队配置的顺序)
approvers_list = [approver.username for approver in team.approvers.filter(is_deleted=False).order_by('id')]
@@ -2074,7 +2070,7 @@ class CreateSchedule(APIView):
if not approvers_list:
return Response({'status': 'error', 'message': '团队类型需要指定审核人请在前端传递approvers参数或配置团队审核人', 'code': 1}, status=status.HTTP_400_BAD_REQUEST)
# 验证审核人是否存在
# 验证审核人是否存在parse_approvers已经验证这里再次确认
for approver_name in approvers_list:
if not User.objects.filter(username=approver_name, is_deleted=False).exists():
return Response({'status': 'error', 'message': f'审核人"{approver_name}"不存在', 'code': 1}, status=status.HTTP_400_BAD_REQUEST)

View File

@@ -30,7 +30,7 @@ class UserRegister(APIView):
# 以下字段改为可选,如果未提供则从人事管理同步
card = request.data.get('card') # 身份证(可选)
position = request.data.get('position') # 岗位(可选)
approvers = request.data.get('approvers') # 审核人列表(可选,多人团队时需要)
approvers = request.data.get('approvers') # 审核人列表(可选,多人团队时需要推荐用户ID数组如[1,2,3],兼容:用户名数组
# 兼容旧接口:如果传了 personincharge转换为 approvers
personincharge = request.data.get('personincharge')
if personincharge and not approvers:
@@ -786,7 +786,7 @@ class confirm(APIView):
amount = request.data.get('amount')
allocate = request.data.get('allocate') # 改为可选,由审批人指定
token = request.META.get('token')
approvers = request.data.get('approvers') # 审核人列表(可选,多人团队时需要)
approvers = request.data.get('approvers') # 审核人列表(可选,多人团队时需要推荐用户ID数组如[1,2,3],兼容:用户名数组
# 兼容旧接口:如果传了 personincharge转换为 approvers
personincharge = request.data.get('personincharge')
if personincharge and not approvers:
@@ -1331,7 +1331,7 @@ class PaymentRequest(APIView):
bankcard = request.data.get('bankcard')
BankName = request.data.get('BankName')
applicant= request.data.get('applicant')
approvers = request.data.get('approvers') # 审核人列表(可选,多人团队时需要)
approvers = request.data.get('approvers') # 审核人列表(可选,多人团队时需要推荐用户ID数组如[1,2,3],兼容:用户名数组
# 兼容旧接口:如果传了 personincharge转换为 approvers
personincharge = request.data.get('personincharge')
if personincharge and not approvers:
@@ -1529,7 +1529,7 @@ class reimbursement(APIView):
reason = request.data.get('reason')
amount = request.data.get('amount')
FeeDescription = request.data.get('FeeDescription')
approvers = request.data.get('approvers') # 审批人列表(数组,仅团队类型需要)
approvers = request.data.get('approvers') # 审批人列表(数组,仅团队类型需要推荐用户ID数组如[1,2,3],兼容:用户名数组
token = request.META.get('token')
if not all([person, times, reason, amount, FeeDescription]):
@@ -1762,7 +1762,7 @@ class Change(APIView):
username = request.data.get('username')
type = request.data.get('type')
Instructions = request.data.get('Instructions')
approvers = request.data.get('approvers') # 审核人列表(可选,多人团队时需要)
approvers = request.data.get('approvers') # 审核人列表(可选,多人团队时需要推荐用户ID数组如[1,2,3],兼容:用户名数组
# 兼容旧接口:如果传了 personincharge转换为 approvers
personincharge = request.data.get('personincharge')
if personincharge and not approvers:
@@ -1961,7 +1961,7 @@ class UserDeparture(APIView):
"""
username = request.data.get('username')
Dateofdeparture = request.data.get('Dateofdeparture') # 离职时间
approvers = request.data.get('approvers') # 审核人列表(可选,多人团队时需要)
approvers = request.data.get('approvers') # 审核人列表(可选,多人团队时需要推荐用户ID数组如[1,2,3],兼容:用户名数组
# 兼容旧接口:如果传了 personincharge转换为 approvers
personincharge = request.data.get('personincharge')
if personincharge and not approvers:

View File

@@ -13,8 +13,9 @@
### 审核人参数说明
- `approvers`:审核人列表(可选,多人团队时需要)
- 可以是数组格式:`["张三", "李四", "王五"]`推荐,数组顺序即为审核顺序)
- 可以是逗号分隔的字符串:`"张三,李四,王五"`字符串顺序即为审核顺序)
- **推荐格式**用户ID数组`[1, 2, 3]``["1", "2", "3"]`(数组顺序即为审核顺序)
- **兼容格式**:用户名数组,如 `["张三", "李四", "王五"]`数组顺序即为审核顺序)
- **字符串格式**逗号分隔的ID或用户名`"1,2,3"``"张三,李四,王五"`(字符串顺序即为审核顺序)
- 如果不传,则使用团队配置的审核人(按团队审核人顺序)
- `personincharge`:兼容旧接口,单个审核人(已废弃,建议使用`approvers`
@@ -38,7 +39,7 @@
"responsiblefor": "负责人(必填)",
"charge": "收费情况(必填)",
"contract": "合同文件(可选,文件列表)",
"approvers": ["审核人1", "审核人2"] // 可选,团队类型时需要
"approvers": [1, 2] // 可选团队类型时需要推荐用户ID数组如 [1, 2];兼容:用户名数组,如 ["张三", "李四"]
}
```
@@ -76,7 +77,7 @@
"ProjectName": "项目名称(必填)",
"times": "日期(必填)",
"BiddingAnnouncement": "招标公告文件(可选,文件列表)",
"approvers": ["审核人1", "审核人2"] // 可选,团队类型时需要
"approvers": [1, 2] // 可选团队类型时需要推荐用户ID数组如 [1, 2];兼容:用户名数组,如 ["张三", "李四"]
}
```
@@ -150,7 +151,7 @@
"tiems": "开始时间(必填)",
"end_time": "结束时间(必填)",
"remark": "备注(可选)",
"approvers": ["审核人1", "审核人2"] // 可选,团队类型时需要
"approvers": [1, 2] // 可选团队类型时需要推荐用户ID数组如 [1, 2];兼容:用户名数组,如 ["张三", "李四"]
}
```
@@ -194,7 +195,7 @@
"salary": "工资(必填)",
"card": "身份证(可选,未提供则从人事管理同步)",
"position": "岗位(可选,未提供则从人事管理同步)",
"approvers": ["审核人1", "审核人2"] // 可选,团队类型时需要
"approvers": [1, 2] // 可选团队类型时需要推荐用户ID数组如 [1, 2];兼容:用户名数组,如 ["张三", "李四"]
}
```
@@ -244,7 +245,7 @@
"amount": "收款金额(必填)",
"allocate": "收入分配(可选,未提供则设为'待审批人指定'",
"case_id": "案件ID可选用于关联案件",
"approvers": ["审核人1", "审核人2"] // 可选,团队类型时需要
"approvers": [1, 2] // 可选团队类型时需要推荐用户ID数组如 [1, 2];兼容:用户名数组,如 ["张三", "李四"]
}
```
@@ -292,7 +293,7 @@
"bankcard": "银行卡号(必填)",
"BankName": "开户行(必填)",
"applicant": "申请人(必填)",
"approvers": ["审核人1", "审核人2"] // 可选,团队类型时需要
"approvers": [1, 2] // 可选团队类型时需要推荐用户ID数组如 [1, 2];兼容:用户名数组,如 ["张三", "李四"]
}
```
@@ -330,7 +331,7 @@
"reason": "报销理由(必填)",
"amount": "报销金额(必填)",
"FeeDescription": "费用说明(必填)",
"approvers": ["审核人1", "审核人2"] // 可选,团队类型时需要
"approvers": [1, 2] // 可选团队类型时需要推荐用户ID数组如 [1, 2];兼容:用户名数组,如 ["张三", "李四"]
}
```
@@ -372,7 +373,7 @@
"username": "用户名(必填)",
"type": "变更类型(必填)",
"Instructions": "调整说明(必填)",
"approvers": ["审核人1", "审核人2"] // 可选,团队类型时需要
"approvers": [1, 2] // 可选团队类型时需要推荐用户ID数组如 [1, 2];兼容:用户名数组,如 ["张三", "李四"]
}
```
@@ -412,7 +413,7 @@
"username": "用户名(必填)",
"Dateofdeparture": "离职时间必填格式YYYY-MM-DD",
"settlement_salary": "结算工资(可选,审批人可以后续填写)",
"approvers": ["审核人1", "审核人2"] // 可选,团队类型时需要
"approvers": [1, 2] // 可选团队类型时需要推荐用户ID数组如 [1, 2];兼容:用户名数组,如 ["张三", "李四"]
}
```