优化大版本

This commit is contained in:
27942
2026-01-12 13:43:40 +08:00
parent f71394d562
commit 7daff88977

View File

@@ -235,8 +235,43 @@ class ApiLoggingMiddleware(MiddlewareMixin):
'EditBonusChange': '编辑变更',
'DeleteBonusChange': '删除变更',
'OperationLogView': '操作日志查询',
'LawyersdocumentsDetail': '文件详情', # 确保映射正确
'BulletinDetail': '公告详情', # 确保映射正确
'ScheduleDetail': '日程详情', # 确保映射正确
# 添加路径变体的映射
'Bulletindetail': '公告详情', # bulletindetail 路径
'Scheduledetail': '日程详情', # scheduledetail 路径
'Lawyersdocumentsdetail': '文件详情', # lawdisplay 路径对应的类
}
return name_mapping.get(class_name, None)
# 先尝试直接匹配
result = name_mapping.get(class_name, None)
if result:
return result
# 如果直接匹配失败,尝试不区分大小写匹配
for key, value in name_mapping.items():
if key.lower() == class_name.lower():
return value
return None
def path_to_class_name(self, path):
"""从URL路径推断可能的类名"""
# 移除前导斜杠并分割路径
parts = path.strip('/').split('/')
if not parts or not parts[-1]:
return None
# 获取最后一部分(通常是视图名称)
last_part = parts[-1]
# 将下划线或连字符分隔的名称转换为驼峰命名
# 例如: bulletindetail -> BulletinDetail
words = last_part.replace('-', '_').split('_')
class_name = ''.join(word.capitalize() for word in words)
# 返回转换后的类名(即使不是标准驼峰命名也返回,让调用者尝试匹配)
return class_name if class_name else None
def func_name_to_description(self, func_name):
"""从函数名转换为中文描述"""
@@ -278,6 +313,7 @@ class ApiLoggingMiddleware(MiddlewareMixin):
return response
# 正常请求,记录详细日志
description = None
try:
# 解析URL获取view函数
resolver_match = resolve(request.path)
@@ -285,8 +321,6 @@ class ApiLoggingMiddleware(MiddlewareMixin):
view_class = getattr(view_func, 'view_class', None)
# 获取接口描述
description = None
if view_class:
# 优先从对应方法的docstring获取针对APIView
method = request.method.lower()
@@ -316,29 +350,46 @@ class ApiLoggingMiddleware(MiddlewareMixin):
func_name = view_func.__name__
description = self.func_name_to_description(func_name)
# 如果还是没有找到描述,使用默认值
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无法解析
# 如果是未授权请求,可能是恶意扫描,只记录简要信息
if is_unauthorized:
timestamp = datetime.now().strftime('[%d/%b/%Y %H:%M:%S]')
print(f'{timestamp} [未授权访问] "{request.method} {request.path}" {response.status_code}')
else:
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} 未知接口')
# URL无法解析,尝试从路径推断
possible_class_name = self.path_to_class_name(request.path)
if possible_class_name:
description = self.class_name_to_description(possible_class_name)
# 如果直接匹配失败,尝试匹配常见的变体
if not description and possible_class_name:
# 尝试匹配Bulletindetail -> BulletinDetail
if possible_class_name.lower().endswith('detail'):
# 将 detail 前的部分首字母大写
base = possible_class_name[:-6] # 移除 'detail'
if base:
# 尝试匹配Bulletin + Detail
variant = base.capitalize() + 'Detail'
description = self.class_name_to_description(variant)
except Exception as e:
# 发生异常时,尝试从路径推断
try:
possible_class_name = self.path_to_class_name(request.path)
if possible_class_name:
description = self.class_name_to_description(possible_class_name)
# 如果直接匹配失败,尝试匹配常见的变体
if not description and possible_class_name:
if possible_class_name.lower().endswith('detail'):
base = possible_class_name[:-6]
if base:
variant = base.capitalize() + 'Detail'
description = self.class_name_to_description(variant)
except:
pass
# 如果还是没有找到描述,使用默认值
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)
return response