diff --git a/User/utils.py b/User/utils.py index 628c9c9..80b459d 100644 --- a/User/utils.py +++ b/User/utils.py @@ -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: 审批类型(如"立项登记"、"付款申请"等) diff --git a/business/views.py b/business/views.py index 9a45a23..29d0a68 100644 --- a/business/views.py +++ b/business/views.py @@ -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) diff --git a/finance/views.py b/finance/views.py index 37f7910..35a3601 100644 --- a/finance/views.py +++ b/finance/views.py @@ -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: diff --git a/创建审核接口文档.md b/创建审核接口文档.md index 938d5aa..87aa98e 100644 --- a/创建审核接口文档.md +++ b/创建审核接口文档.md @@ -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];兼容:用户名数组,如 ["张三", "李四"]) } ```