优化删除部门接口
This commit is contained in:
@@ -26,7 +26,7 @@ class Bid(models.Model):
|
||||
BiddingUnit = models.TextField() # 招标单位 名称、统一社会信用代码/身份证号码
|
||||
ProjectName = models.CharField(max_length=100) # 项目名称
|
||||
times = models.CharField(max_length=100) # 申请日期
|
||||
BiddingAnnouncement = models.CharField(max_length=100) # 上传招标公告
|
||||
BiddingAnnouncement = models.TextField() # 上传招标公告
|
||||
state = models.CharField(max_length=100) # 状态
|
||||
|
||||
|
||||
|
||||
@@ -317,16 +317,50 @@ class EditProject(APIView):
|
||||
:return:
|
||||
"""
|
||||
id = request.data.get('id')
|
||||
type = request.data.get('type')
|
||||
ContractNo = request.data.get('ContractNo')
|
||||
|
||||
if not id:
|
||||
return Response({'status': 'error', 'message': '缺少参数id', 'code': 1}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 检查不可修改的参数(前端不会传入,但作为安全措施进行检查)
|
||||
forbidden_params = []
|
||||
if 'type' in request.data:
|
||||
forbidden_params.append('type')
|
||||
if 'ContractNo' in request.data:
|
||||
forbidden_params.append('ContractNo')
|
||||
if 'personincharge' in request.data:
|
||||
forbidden_params.append('personincharge')
|
||||
if 'user_id' in request.data:
|
||||
forbidden_params.append('user_id')
|
||||
|
||||
if forbidden_params:
|
||||
return Response({
|
||||
'status': 'error',
|
||||
'message': f'以下参数不允许修改: {", ".join(forbidden_params)}',
|
||||
'code': 1
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 获取可修改的参数(前端只传入这些参数)
|
||||
times = request.data.get('times')
|
||||
responsiblefor = request.data.get('responsiblefor')
|
||||
charge = request.data.get('charge')
|
||||
contract = request.FILES.getlist('contract')
|
||||
personincharge = request.data.get('personincharge')
|
||||
|
||||
pro = ProjectRegistration.objects.get(id=id)
|
||||
|
||||
try:
|
||||
pro = ProjectRegistration.objects.get(id=id)
|
||||
except ProjectRegistration.DoesNotExist:
|
||||
return Response({'status': 'error', 'message': '立案登记不存在', 'code': 1}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
import datetime
|
||||
|
||||
# 保存原始值用于日志记录
|
||||
original_type = pro.type
|
||||
original_ContractNo = pro.ContractNo
|
||||
original_responsiblefor = pro.responsiblefor
|
||||
original_times = pro.times
|
||||
original_charge = pro.charge
|
||||
|
||||
update_fields_list = []
|
||||
|
||||
if contract:
|
||||
contract = flies(contract)
|
||||
# 将文件URL列表转换为字符串存储(如果有多个URL,用逗号分隔)
|
||||
@@ -335,23 +369,33 @@ class EditProject(APIView):
|
||||
else:
|
||||
contract_str = ""
|
||||
pro.contract = contract_str
|
||||
pro.save(update_fields=['contract'])
|
||||
pro.times = times
|
||||
pro.type = type
|
||||
|
||||
pro.responsiblefor = responsiblefor
|
||||
pro.charge = charge
|
||||
update_fields_list.append('contract')
|
||||
|
||||
if times:
|
||||
pro.times = times
|
||||
update_fields_list.append('times')
|
||||
|
||||
if responsiblefor:
|
||||
pro.responsiblefor = responsiblefor
|
||||
update_fields_list.append('responsiblefor')
|
||||
|
||||
if charge:
|
||||
pro.charge = charge
|
||||
update_fields_list.append('charge')
|
||||
|
||||
pro.state = "审核中"
|
||||
pro.save(update_fields=['ContractNo', 'times', 'type', 'responsiblefor', 'charge', 'state', "type2"])
|
||||
update_fields_list.append('state')
|
||||
|
||||
if update_fields_list:
|
||||
pro.save(update_fields=update_fields_list)
|
||||
|
||||
today = datetime.datetime.now()
|
||||
formatted_date = today.strftime("%Y-%m-%d")
|
||||
Approval.objects.create(
|
||||
title=responsiblefor + "立项登记重新编辑",
|
||||
content=responsiblefor + "在" + times + "办理立项登记,项目类型:" + type + ",合同编号:" + ContractNo + "描述:" + ",负责人:" + responsiblefor + ",收费情况:" + charge,
|
||||
title=(responsiblefor or original_responsiblefor) + "立项登记重新编辑",
|
||||
content=(responsiblefor or original_responsiblefor) + "在" + (times or original_times) + "办理立项登记,项目类型:" + original_type + ",合同编号:" + original_ContractNo + "描述:" + ",负责人:" + (responsiblefor or original_responsiblefor) + ",收费情况:" + (charge or original_charge),
|
||||
times=formatted_date,
|
||||
personincharge=personincharge,
|
||||
personincharge="", # personincharge不再从请求中获取
|
||||
state='审核中',
|
||||
type="立项登记",
|
||||
user_id=pro.id
|
||||
@@ -432,6 +476,13 @@ class BidRegistration(APIView):
|
||||
|
||||
class BidDetail(APIView):
|
||||
def post(self, request, *args, **kwargs):
|
||||
"""
|
||||
投标登记展示
|
||||
:param request:
|
||||
:param args:
|
||||
:param kwargs:
|
||||
:return:
|
||||
"""
|
||||
page = request.data.get('page')
|
||||
per_page = request.data.get('per_page')
|
||||
times = request.data.get('times')
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
from django.http import HttpResponse, JsonResponse
|
||||
from django.utils.deprecation import MiddlewareMixin
|
||||
from django.urls import resolve, Resolver404
|
||||
import logging
|
||||
from datetime import datetime
|
||||
|
||||
from rest_framework import status
|
||||
from User.models import User
|
||||
|
||||
logger = logging.getLogger('django.server')
|
||||
|
||||
cnt = 0
|
||||
class JWTAuthenticationMiddleware(MiddlewareMixin):
|
||||
def process_request(self, request):
|
||||
@@ -32,3 +38,74 @@ class JWTAuthenticationMiddleware(MiddlewareMixin):
|
||||
headers={'Access-Control-Allow-Origin': '*'}
|
||||
)
|
||||
return None
|
||||
|
||||
|
||||
class ApiLoggingMiddleware(MiddlewareMixin):
|
||||
"""
|
||||
接口日志中间件,记录接口调用信息并显示接口功能描述
|
||||
"""
|
||||
def extract_description(self, docstring):
|
||||
"""从docstring中提取第一行描述"""
|
||||
if not docstring:
|
||||
return None
|
||||
lines = docstring.strip().split('\n')
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
# 跳过空行和参数说明
|
||||
if line and not line.startswith(':') and not line.startswith('param') and not line.startswith('return') and not line.startswith('@'):
|
||||
return line
|
||||
return None
|
||||
|
||||
def process_response(self, request, response):
|
||||
# 跳过OPTIONS请求
|
||||
if request.method == 'OPTIONS':
|
||||
return response
|
||||
|
||||
# 跳过静态文件请求
|
||||
if request.path.startswith('/static/') or request.path.startswith('/media/'):
|
||||
return response
|
||||
|
||||
try:
|
||||
# 解析URL获取view函数
|
||||
resolver_match = resolve(request.path)
|
||||
view_func = resolver_match.func
|
||||
view_class = getattr(view_func, 'view_class', None)
|
||||
|
||||
# 获取接口描述
|
||||
description = None
|
||||
|
||||
if view_class:
|
||||
# 优先从对应方法的docstring获取(针对APIView)
|
||||
method = request.method.lower()
|
||||
if hasattr(view_class, method):
|
||||
method_func = getattr(view_class, method)
|
||||
description = self.extract_description(getattr(method_func, '__doc__', None))
|
||||
|
||||
# 如果方法没有docstring,尝试从类的docstring获取
|
||||
if not description:
|
||||
description = self.extract_description(getattr(view_class, '__doc__', None))
|
||||
else:
|
||||
# 函数视图,直接从函数docstring获取
|
||||
description = self.extract_description(getattr(view_func, '__doc__', None))
|
||||
|
||||
# 如果还是没有找到描述,使用默认值
|
||||
if not description:
|
||||
description = '未知接口'
|
||||
|
||||
# 记录日志,格式与Django默认格式保持一致,并在最后添加接口描述
|
||||
timestamp = datetime.now().strftime('[%d/%b/%Y %H:%M:%S]')
|
||||
log_message = f'{timestamp} "{request.method} {request.path} HTTP/1.1" {response.status_code} {description}'
|
||||
|
||||
# 使用print输出到控制台(与Django开发服务器日志格式保持一致)
|
||||
print(log_message)
|
||||
|
||||
except Resolver404:
|
||||
# URL无法解析,使用默认日志格式
|
||||
timestamp = datetime.now().strftime('[%d/%b/%Y %H:%M:%S]')
|
||||
print(f'{timestamp} "{request.method} {request.path} HTTP/1.1" {response.status_code} 未知接口')
|
||||
except Exception:
|
||||
# 发生异常时不影响请求处理,使用默认格式
|
||||
timestamp = datetime.now().strftime('[%d/%b/%Y %H:%M:%S]')
|
||||
print(f'{timestamp} "{request.method} {request.path} HTTP/1.1" {response.status_code} 未知接口')
|
||||
|
||||
return response
|
||||
|
||||
@@ -51,6 +51,7 @@ MIDDLEWARE = [
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
"jyls_django.middleware.ApiLoggingMiddleware",
|
||||
]
|
||||
|
||||
ROOT_URLCONF = 'jyls_django.urls'
|
||||
|
||||
Reference in New Issue
Block a user