加入导出案件日志功能
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
from django.urls import path
|
||||
|
||||
from .models import Schedule
|
||||
from .views import registration,registrationDetail,Project,Projectquerytype,ProjectDetail,EditProject,BidRegistration,BidDetail,registrationList,caseManagement,caseManagementDetail,CaseAttachmentUpload,CaseAttachmentUpdate,Uploadinvoice,InvoiceDetail,Log,LogDetail,accumulate,preFilingLinkedCases,Application,ApplicationDetail,WarehousingRegistration,WarehousingDetail,PlatformRegistration,PlatformDetail,EditPlatformDetail,DeletePlatformDetail,bulletin,BulletinDetail,EditBulletin,deleteBulletin,Lawyersdocuments,LawyersdocumentsDetail,LwaDetail,CreateSchedule,DeleteSchedule,ScheduleDetail,handleSchedule,AddRermission,DisplayRermission,DeleteRermission,EditRermission,addRole,DeleteRole,EditRole,displayRole,modifypermissions,getRolePermissions,DeleteRegistration,EditRegistration,DeleteProject,EditBid,DeleteBid,EditCase,DeleteCase,EditApplication,DeleteApplication,EditWarehousing,DeleteWarehousing,EditLawyerFlie,EditSchedule,TransferCase,CaseChangeRequestCreate,CaseChangeRequestList,CaseChangeRequestDetail,ProjectDropdownList,CaseDropdownList,ConflictSearch,CreateCaseTag,CaseTagList,CaseTagDetail,EditCaseTag,DeleteCaseTag,CaseTagDropdownList,CaseListByTag,SetCaseTags,PropagandaEit,addSystem,SystemList,eitSystem,deleteSystem
|
||||
from .views import registration,registrationDetail,Project,Projectquerytype,ProjectDetail,EditProject,BidRegistration,BidDetail,registrationList,caseManagement,caseManagementDetail,CaseAttachmentUpload,CaseAttachmentUpdate,Uploadinvoice,InvoiceDetail,Log,LogDetail,accumulate,preFilingLinkedCases,Application,ApplicationDetail,WarehousingRegistration,WarehousingDetail,PlatformRegistration,PlatformDetail,EditPlatformDetail,DeletePlatformDetail,bulletin,BulletinDetail,EditBulletin,deleteBulletin,Lawyersdocuments,LawyersdocumentsDetail,LwaDetail,CreateSchedule,DeleteSchedule,ScheduleDetail,handleSchedule,AddRermission,DisplayRermission,DeleteRermission,EditRermission,addRole,DeleteRole,EditRole,displayRole,modifypermissions,getRolePermissions,DeleteRegistration,EditRegistration,DeleteProject,EditBid,DeleteBid,EditCase,DeleteCase,EditApplication,DeleteApplication,EditWarehousing,DeleteWarehousing,EditLawyerFlie,EditSchedule,TransferCase,CaseChangeRequestCreate,CaseChangeRequestList,CaseChangeRequestDetail,ProjectDropdownList,CaseDropdownList,ConflictSearch,CreateCaseTag,CaseTagList,CaseTagDetail,EditCaseTag,DeleteCaseTag,CaseTagDropdownList,CaseListByTag,SetCaseTags,PropagandaEit,addSystem,SystemList,eitSystem,deleteSystem,ExportCaseLogExcel
|
||||
urlpatterns = [
|
||||
|
||||
path('register',registration.as_view(),name='register'),
|
||||
@@ -85,5 +85,7 @@ urlpatterns = [
|
||||
path('addSystem',addSystem.as_view(),name='addSystem'),
|
||||
path('SystemList',SystemList.as_view(),name='SystemList'),
|
||||
path('eitSystem',eitSystem.as_view(),name='eitSystem'),
|
||||
path('deleteSystem',deleteSystem.as_view(),name='deleteSystem')
|
||||
path('deleteSystem',deleteSystem.as_view(),name='deleteSystem'),
|
||||
# 案件日志导出Excel
|
||||
path('export-case-log-excel',ExportCaseLogExcel.as_view(),name='export-case-log-excel'),
|
||||
]
|
||||
@@ -5149,3 +5149,154 @@ class deleteSystem(APIView):
|
||||
except System.DoesNotExist:
|
||||
return Response({'status': 'error', 'message': '系统公告不存在', 'code': 1}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
|
||||
class ExportCaseLogExcel(APIView):
|
||||
def post(self, request, *args, **kwargs):
|
||||
"""
|
||||
导出案件日志到Excel
|
||||
必填参数:case_id(案件ID)
|
||||
可选参数:start_time(开始时间)、end_time(结束时间)
|
||||
返回:Excel文件下载
|
||||
"""
|
||||
import pandas as pd
|
||||
from django.http import HttpResponse
|
||||
from io import BytesIO
|
||||
|
||||
case_id = request.data.get('case_id') # 案件ID(必填)
|
||||
start_time = request.data.get('start_time') # 开始时间(可选)
|
||||
end_time = request.data.get('end_time') # 结束时间(可选)
|
||||
|
||||
if not case_id:
|
||||
return Response({'status': 'error', 'message': '缺少参数case_id(案件ID)', 'code': 1}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 获取案件信息
|
||||
try:
|
||||
case = Case.objects.get(id=case_id, is_deleted=False)
|
||||
except Case.DoesNotExist:
|
||||
return Response({'status': 'error', 'message': '案件不存在', 'code': 1}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
# 构建查询条件
|
||||
Q_obj = Q(is_deleted=False, case_id=case_id)
|
||||
|
||||
# 时间范围筛选(可选)
|
||||
if start_time:
|
||||
Q_obj &= Q(times__gte=start_time)
|
||||
if end_time:
|
||||
Q_obj &= Q(times__lte=end_time)
|
||||
|
||||
# 查询日志数据
|
||||
logs = Caselog.objects.filter(Q_obj).order_by('-times', '-id')
|
||||
|
||||
if not logs.exists():
|
||||
return Response({'status': 'error', 'message': '没有找到案件日志数据', 'code': 1}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
# 解析案件负责人信息
|
||||
responsiblefor_info = ""
|
||||
if case.responsiblefor:
|
||||
try:
|
||||
resp_data = json.loads(case.responsiblefor) if isinstance(case.responsiblefor, str) else case.responsiblefor
|
||||
if isinstance(resp_data, dict):
|
||||
parts = []
|
||||
if resp_data.get('responsible_person'):
|
||||
parts.append(f"承办人:{resp_data.get('responsible_person')}")
|
||||
if resp_data.get('main_lawyer'):
|
||||
parts.append(f"主办律师:{resp_data.get('main_lawyer')}")
|
||||
if resp_data.get('assist_lawyer'):
|
||||
parts.append(f"协办律师:{resp_data.get('assist_lawyer')}")
|
||||
if resp_data.get('trainee_lawyer'):
|
||||
parts.append(f"实习律师:{resp_data.get('trainee_lawyer')}")
|
||||
if resp_data.get('secretary'):
|
||||
parts.append(f"秘书/助理:{resp_data.get('secretary')}")
|
||||
responsiblefor_info = ";".join(parts) if parts else str(case.responsiblefor)
|
||||
else:
|
||||
responsiblefor_info = str(case.responsiblefor)
|
||||
except (json.JSONDecodeError, TypeError):
|
||||
responsiblefor_info = str(case.responsiblefor) if case.responsiblefor else ""
|
||||
|
||||
# 获取案件标签
|
||||
tags_str = ""
|
||||
try:
|
||||
tags = case.tags.filter(is_deleted=False).values_list('name', flat=True)
|
||||
tags_str = "、".join(tags) if tags else ""
|
||||
except:
|
||||
tags_str = ""
|
||||
|
||||
# 构建Excel数据
|
||||
excel_data = []
|
||||
for log in logs:
|
||||
# 解析附件信息
|
||||
file_info = ""
|
||||
if log.file:
|
||||
try:
|
||||
files = json.loads(log.file) if isinstance(log.file, str) else log.file
|
||||
if isinstance(files, list):
|
||||
file_names = []
|
||||
for f in files:
|
||||
if isinstance(f, dict):
|
||||
file_names.append(f.get('name', f.get('url', '未知文件')))
|
||||
elif isinstance(f, str):
|
||||
file_names.append(f)
|
||||
file_info = ";".join(file_names) if file_names else ""
|
||||
else:
|
||||
file_info = str(files)
|
||||
except (json.JSONDecodeError, TypeError):
|
||||
file_info = str(log.file) if log.file else ""
|
||||
|
||||
excel_data.append({
|
||||
'日志ID': log.id,
|
||||
'案件ID': case_id,
|
||||
'合同编号': case.contract_no or '',
|
||||
'项目类型': case.project_type or '',
|
||||
'客户名称': case.client_name or '',
|
||||
'相对方名称': case.party_name or '',
|
||||
'项目简述': case.project_description or '',
|
||||
'负责人信息': responsiblefor_info,
|
||||
'收费情况': case.charge or '',
|
||||
'立案时间': case.times or '',
|
||||
'案件状态': case.state or '',
|
||||
'案件标签': tags_str,
|
||||
'已开票金额': case.invoice_status or '0',
|
||||
'已收款金额': case.paymentcollection or '0',
|
||||
'日志内容': log.content or '',
|
||||
'记录时间': log.times or '',
|
||||
'记录人': log.username or '',
|
||||
'附件信息': file_info,
|
||||
})
|
||||
|
||||
# 创建DataFrame
|
||||
df = pd.DataFrame(excel_data)
|
||||
|
||||
# 导出Excel
|
||||
output = BytesIO()
|
||||
with pd.ExcelWriter(output, engine='openpyxl') as writer:
|
||||
df.to_excel(writer, index=False, sheet_name='案件日志')
|
||||
|
||||
# 调整列宽
|
||||
worksheet = writer.sheets['案件日志']
|
||||
for idx, col in enumerate(df.columns):
|
||||
max_length = max(
|
||||
df[col].astype(str).map(len).max() if len(df) > 0 else 0,
|
||||
len(str(col))
|
||||
)
|
||||
# 限制最大列宽为50
|
||||
adjusted_width = min(max_length + 2, 50)
|
||||
worksheet.column_dimensions[chr(65 + idx) if idx < 26 else 'A' + chr(65 + idx - 26)].width = adjusted_width
|
||||
|
||||
output.seek(0)
|
||||
|
||||
# 生成文件名
|
||||
contract_no = case.contract_no or f'案件{case_id}'
|
||||
filename = f'{contract_no}_案件日志_{datetime.now().strftime("%Y%m%d_%H%M%S")}.xlsx'
|
||||
|
||||
# 返回Excel文件
|
||||
response = HttpResponse(
|
||||
output.read(),
|
||||
content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||
)
|
||||
# 处理中文文件名
|
||||
from urllib.parse import quote
|
||||
response['Content-Disposition'] = f'attachment; filename*=UTF-8\'\'{quote(filename)}'
|
||||
response['Access-Control-Expose-Headers'] = 'Content-Disposition'
|
||||
|
||||
return response
|
||||
|
||||
|
||||
Reference in New Issue
Block a user