From a5460f98dd5d4e09ed31d5f241802ddbf900dfa9 Mon Sep 17 00:00:00 2001 From: 27942 Date: Thu, 15 Jan 2026 12:16:00 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=A1=88=E4=BB=B6=E6=A8=A1?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/views.py | 129 +++++++++++++++++++++++++++----------- finance/views.py | 86 ++++++++++++++++++------- jyls_django/middleware.py | 17 ++++- 3 files changed, 174 insertions(+), 58 deletions(-) diff --git a/business/views.py b/business/views.py index 9aef1f8..a2a53d0 100644 --- a/business/views.py +++ b/business/views.py @@ -1269,28 +1269,27 @@ class EditCase(APIView): case.state = "审核中" update_fields_list.extend(['ChangeRequest', 'state']) - if approvers: - import datetime - today = datetime.datetime.now() - formatted_date = today.strftime("%Y-%m-%d") - from User.utils import create_approval_with_team_logic - team_name = get_team_name_from_responsiblefor(case.project.responsiblefor) if case.project else None - approval, approvers_order_json, needs_approval = create_approval_with_team_logic( - team_name=team_name, - approvers=approvers, - title="案件管理信息提交", - content=(times or case.times) + "提交了一份案件信息,更改了变更申请", - approval_type="案件管理", - user_id=case.id, - business_record=case, - today=formatted_date - ) - if approval is None and needs_approval: - return Response({ - 'status': 'error', - 'message': build_missing_approvers_message(team_name, approvers), - 'code': 1 - }, status=status.HTTP_400_BAD_REQUEST) + import datetime + today = datetime.datetime.now() + formatted_date = today.strftime("%Y-%m-%d") + from User.utils import create_approval_with_team_logic + team_name = get_team_name_from_responsiblefor(case.project.responsiblefor) if case.project else None + approval, approvers_order_json, needs_approval = create_approval_with_team_logic( + team_name=team_name, + approvers=approvers, + title="案件管理信息提交", + content=(times or case.times) + "提交了一份案件信息,更改了变更申请", + approval_type="案件管理", + user_id=case.id, + business_record=case, + today=formatted_date + ) + if approval is None and needs_approval: + return Response({ + 'status': 'error', + 'message': build_missing_approvers_message(team_name, approvers), + 'code': 1 + }, status=status.HTTP_400_BAD_REQUEST) if paymentcollection: case.paymentcollection = paymentcollection @@ -2716,6 +2715,7 @@ class TransferCase(APIView): old_undertaker = request.data.get('old_undertaker') # 原承办人员(离职用户) new_undertaker = request.data.get('new_undertaker') # 新承办人员 case_ids = request.data.get('case_ids') # 要转移的案件ID列表(可选,如果不传则转移所有案件) + project_ids = request.data.get('project_ids') # 要转移的立项ID列表(可选) if not all([old_undertaker, new_undertaker]): return Response({ @@ -2744,17 +2744,44 @@ class TransferCase(APIView): 'code': 1 }, status=status.HTTP_404_NOT_FOUND) - # 查询要转移的案件 + # 查询要转移的预立案 if case_ids and isinstance(case_ids, list): - # 转移指定的案件 - cases = PreFiling.objects.filter(Undertaker=old_undertaker, id__in=case_ids) + prefiling_cases = PreFiling.objects.filter(Undertaker=old_undertaker, id__in=case_ids) else: - # 转移所有案件 - cases = PreFiling.objects.filter(Undertaker=old_undertaker) + prefiling_cases = PreFiling.objects.filter(Undertaker=old_undertaker) - case_count = cases.count() + prefiling_count = prefiling_cases.count() - if case_count == 0: + def _replace_responsible(responsiblefor_value, old_name, new_name): + try: + data = json.loads(responsiblefor_value) if responsiblefor_value else {} + except (json.JSONDecodeError, TypeError): + data = responsiblefor_value if responsiblefor_value else {} + if not isinstance(data, dict): + return None, False + changed = False + for key, value in list(data.items()): + if value == old_name: + data[key] = new_name + changed = True + return data, changed + + # 查询要转移的正式案件 + formal_cases_qs = Case.objects.filter(is_deleted=False, responsiblefor__icontains=old_undertaker) + if case_ids and isinstance(case_ids, list): + formal_cases_qs = formal_cases_qs.filter(id__in=case_ids) + + # 查询要转移的立项登记 + formal_projects_qs = ProjectRegistration.objects.filter(is_deleted=False, responsiblefor__icontains=old_undertaker) + if project_ids and isinstance(project_ids, list): + formal_projects_qs = formal_projects_qs.filter(id__in=project_ids) + + formal_cases = list(formal_cases_qs) + formal_projects = list(formal_projects_qs) + + total_count = prefiling_count + len(formal_cases) + len(formal_projects) + + if total_count == 0: return Response({ 'status': 'error', 'message': '没有找到需要转移的案件', @@ -2762,11 +2789,11 @@ class TransferCase(APIView): }, status=status.HTTP_400_BAD_REQUEST) # 执行转移 - transferred_cases = [] - for case in cases: + transferred_prefilings = [] + for case in prefiling_cases: case.Undertaker = new_undertaker case.save(update_fields=['Undertaker']) - transferred_cases.append({ + transferred_prefilings.append({ 'id': case.id, 'times': case.times, 'client_username': case.client_username, @@ -2774,13 +2801,45 @@ class TransferCase(APIView): 'description': case.description }) + transferred_formal_cases = [] + for case in formal_cases: + updated_data, changed = _replace_responsible(case.responsiblefor, old_undertaker, new_undertaker) + if changed: + case.responsiblefor = json.dumps(updated_data, ensure_ascii=False) + case.save(update_fields=['responsiblefor']) + transferred_formal_cases.append({ + 'id': case.id, + 'project_id': case.project_id, + 'contract_no': case.contract_no, + 'project_type': case.project_type, + 'times': case.times + }) + + transferred_projects = [] + for project in formal_projects: + updated_data, changed = _replace_responsible(project.responsiblefor, old_undertaker, new_undertaker) + if changed: + project.responsiblefor = json.dumps(updated_data, ensure_ascii=False) + project.save(update_fields=['responsiblefor']) + transferred_projects.append({ + 'id': project.id, + 'contract_no': project.ContractNo, + 'type': project.type, + 'times': project.times + }) + return Response({ - 'message': f'案件转移成功,共转移{case_count}个案件', + 'message': f'案件转移成功,共转移{total_count}个案件', 'code': 0, 'data': { 'old_undertaker': old_undertaker, 'new_undertaker': new_undertaker, - 'transferred_count': case_count, - 'transferred_cases': transferred_cases + 'transferred_count': total_count, + 'prefiling_count': prefiling_count, + 'formal_case_count': len(transferred_formal_cases), + 'formal_project_count': len(transferred_projects), + 'prefiling_cases': transferred_prefilings, + 'formal_cases': transferred_formal_cases, + 'formal_projects': transferred_projects } }, status=status.HTTP_200_OK) diff --git a/finance/views.py b/finance/views.py index 7ad87c8..991412f 100644 --- a/finance/views.py +++ b/finance/views.py @@ -11,7 +11,7 @@ from utility.utility import flies from django.contrib.sessions.backends.db import SessionStore from django.db.models import Count, Q from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger -from business.models import PreFiling +from business.models import PreFiling, Case, ProjectRegistration class UserRegister(APIView): @@ -896,16 +896,17 @@ class confirm(APIView): status=status.HTTP_401_UNAUTHORIZED) # 必填字段验证(allocate改为可选) - if not all([times, ContractNo, CustomerID, amount]): - missing_params = [] - if not times: - missing_params.append('times(收款日期)') - if not ContractNo: - missing_params.append('ContractNo(合同号)') - if not CustomerID: - missing_params.append('CustomerID(客户名称)') - if not amount: - missing_params.append('amount(收款金额)') + # ContractNo 允许通过 case_id 同步 + missing_params = [] + if not times: + missing_params.append('times(收款日期)') + if not CustomerID: + missing_params.append('CustomerID(客户名称)') + if not amount: + missing_params.append('amount(收款金额)') + if not ContractNo and not case_id: + missing_params.append('ContractNo(合同号)') + if missing_params: return Response({ 'status': 'error', 'message': f'缺少必填参数: {", ".join(missing_params)}', @@ -2096,15 +2097,56 @@ class UserDeparture(APIView): return Response({'status': 'error', 'message': '用户不存在或已被删除', 'code': 1}, status=status.HTTP_404_NOT_FOUND) - # 检查用户是否有案件(作为承办人员) - cases = PreFiling.objects.filter(Undertaker=username) - case_count = cases.count() + # 检查用户是否有案件(预立案 + 正式案件) + prefiling_cases = PreFiling.objects.filter(Undertaker=username, is_deleted=False) + prefiling_count = prefiling_cases.count() - if case_count > 0: + def _user_in_responsible(responsiblefor_data, target_username): + if isinstance(responsiblefor_data, dict): + return target_username in responsiblefor_data.values() + return False + + formal_case_list = [] + formal_project_list = [] + + # 正式案件:Case 表(责任人信息来自立项同步) + case_qs = Case.objects.filter(is_deleted=False, responsiblefor__icontains=username) + for case in case_qs: + try: + responsible_data = json.loads(case.responsiblefor) if case.responsiblefor else {} + except (json.JSONDecodeError, TypeError): + responsible_data = case.responsiblefor if case.responsiblefor else {} + if _user_in_responsible(responsible_data, username): + formal_case_list.append({ + 'id': case.id, + 'project_id': case.project_id, + 'contract_no': case.contract_no, + 'project_type': case.project_type, + 'times': case.times + }) + + # 立项登记:尚未生成案件但已绑定负责人 + project_qs = ProjectRegistration.objects.filter(is_deleted=False, responsiblefor__icontains=username) + for project in project_qs: + try: + responsible_data = json.loads(project.responsiblefor) if project.responsiblefor else {} + except (json.JSONDecodeError, TypeError): + responsible_data = project.responsiblefor if project.responsiblefor else {} + if _user_in_responsible(responsible_data, username): + formal_project_list.append({ + 'id': project.id, + 'contract_no': project.ContractNo, + 'type': project.type, + 'times': project.times + }) + + total_case_count = prefiling_count + len(formal_case_list) + len(formal_project_list) + + if total_case_count > 0: # 用户有案件,需要先转移案件才能离职 - case_list = [] - for case in cases: - case_list.append({ + prefiling_list = [] + for case in prefiling_cases: + prefiling_list.append({ 'id': case.id, 'times': case.times, 'client_username': case.client_username, @@ -2114,12 +2156,14 @@ class UserDeparture(APIView): return Response({ 'status': 'error', - 'message': f'该用户还有{case_count}个案件未转移,请先转移案件后再进行离职登记', + 'message': f'该用户还有{total_case_count}个案件未转移,请先转移案件后再进行离职登记', 'code': 1, 'data': { 'has_cases': True, - 'case_count': case_count, - 'cases': case_list + 'case_count': total_case_count, + 'prefiling_cases': prefiling_list, + 'formal_cases': formal_case_list, + 'formal_projects': formal_project_list } }, status=status.HTTP_400_BAD_REQUEST) diff --git a/jyls_django/middleware.py b/jyls_django/middleware.py index 2cd244e..443f7b2 100644 --- a/jyls_django/middleware.py +++ b/jyls_django/middleware.py @@ -1,5 +1,6 @@ from django.http import HttpResponse, JsonResponse from django.utils.deprecation import MiddlewareMixin +from django.conf import settings from django.urls import resolve, Resolver404 import logging from datetime import datetime @@ -290,10 +291,22 @@ class ApiLoggingMiddleware(MiddlewareMixin): # 添加 CORS 响应头(确保所有响应都包含 CORS 头) if not hasattr(response, 'headers'): response.headers = {} - response['Access-Control-Allow-Origin'] = '*' + allow_credentials = getattr(settings, 'CORS_ALLOW_CREDENTIALS', False) + origin = request.META.get('HTTP_ORIGIN') + if allow_credentials: + response['Access-Control-Allow-Origin'] = origin if origin else 'null' + existing_vary = response.get('Vary') + if existing_vary: + if 'Origin' not in existing_vary: + response['Vary'] = f"{existing_vary}, Origin" + else: + response['Vary'] = 'Origin' + response['Access-Control-Allow-Credentials'] = 'true' + else: + response['Access-Control-Allow-Origin'] = '*' + response['Access-Control-Allow-Credentials'] = 'false' response['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS, PATCH' response['Access-Control-Allow-Headers'] = 'Content-Type, Authorization, X-Requested-With' - response['Access-Control-Allow-Credentials'] = 'true' # 检查是否为恶意请求 is_malicious = request.META.get('_is_malicious', False)