|
@ -12,6 +12,7 @@ from typing import Optional |
|
|
from module_admin.service.login_service import LoginService |
|
|
from module_admin.service.login_service import LoginService |
|
|
from module_admin.service.log_service import OperationLogService, LoginLogService |
|
|
from module_admin.service.log_service import OperationLogService, LoginLogService |
|
|
from module_admin.entity.vo.log_vo import OperLogModel, LogininforModel |
|
|
from module_admin.entity.vo.log_vo import OperLogModel, LogininforModel |
|
|
|
|
|
from config.env import AppConfig |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def log_decorator(title: str, business_type: int, log_type: Optional[str] = 'operation'): |
|
|
def log_decorator(title: str, business_type: int, log_type: Optional[str] = 'operation'): |
|
@ -50,126 +51,126 @@ def log_decorator(title: str, business_type: int, log_type: Optional[str] = 'ope |
|
|
# 获取请求的ip及ip归属区域 |
|
|
# 获取请求的ip及ip归属区域 |
|
|
oper_ip = request.headers.get("X-Forwarded-For") |
|
|
oper_ip = request.headers.get("X-Forwarded-For") |
|
|
oper_location = '内网IP' |
|
|
oper_location = '内网IP' |
|
|
try: |
|
|
if AppConfig.app_ip_location_query: |
|
|
if oper_ip != '127.0.0.1' and oper_ip != 'localhost': |
|
|
try: |
|
|
ip_result = requests.get(f'https://qifu-api.baidubce.com/ip/geo/v1/district?ip={oper_ip}') |
|
|
if oper_ip != '127.0.0.1' and oper_ip != 'localhost': |
|
|
if ip_result.status_code == 200: |
|
|
ip_result = requests.get(f'https://qifu-api.baidubce.com/ip/geo/v1/district?ip={oper_ip}') |
|
|
prov = ip_result.json().get('data').get('prov') |
|
|
if ip_result.status_code == 200: |
|
|
city = ip_result.json().get('data').get('city') |
|
|
prov = ip_result.json().get('data').get('prov') |
|
|
if prov or city: |
|
|
city = ip_result.json().get('data').get('city') |
|
|
oper_location = f'{prov}-{city}' |
|
|
if prov or city: |
|
|
|
|
|
oper_location = f'{prov}-{city}' |
|
|
|
|
|
else: |
|
|
|
|
|
oper_location = '未知' |
|
|
else: |
|
|
else: |
|
|
oper_location = '未知' |
|
|
oper_location = '未知' |
|
|
else: |
|
|
except Exception as e: |
|
|
oper_location = '未知' |
|
|
oper_location = '未知' |
|
|
except Exception as e: |
|
|
print(e) |
|
|
oper_location = '未知' |
|
|
# 根据不同的请求类型使用不同的方法获取请求参数 |
|
|
print(e) |
|
|
content_type = request.headers.get("Content-Type") |
|
|
finally: |
|
|
if content_type and ("multipart/form-data" in content_type or 'application/x-www-form-urlencoded' in content_type): |
|
|
# 根据不同的请求类型使用不同的方法获取请求参数 |
|
|
payload = await request.form() |
|
|
content_type = request.headers.get("Content-Type") |
|
|
oper_param = "\n".join([f"{key}: {value}" for key, value in payload.items()]) |
|
|
if content_type and ("multipart/form-data" in content_type or 'application/x-www-form-urlencoded' in content_type): |
|
|
else: |
|
|
payload = await request.form() |
|
|
payload = await request.body() |
|
|
oper_param = "\n".join([f"{key}: {value}" for key, value in payload.items()]) |
|
|
# 通过 request.path_params 直接访问路径参数 |
|
|
else: |
|
|
path_params = request.path_params |
|
|
payload = await request.body() |
|
|
oper_param = {} |
|
|
# 通过 request.path_params 直接访问路径参数 |
|
|
if payload: |
|
|
path_params = request.path_params |
|
|
oper_param.update(json.loads(str(payload, 'utf-8'))) |
|
|
oper_param = {} |
|
|
if path_params: |
|
|
if payload: |
|
|
oper_param.update(path_params) |
|
|
oper_param.update(json.loads(str(payload, 'utf-8'))) |
|
|
oper_param = json.dumps(oper_param, ensure_ascii=False) |
|
|
if path_params: |
|
|
# 日志表请求参数字段长度最大为2000,因此在此处判断长度 |
|
|
oper_param.update(path_params) |
|
|
if len(oper_param) > 2000: |
|
|
oper_param = json.dumps(oper_param, ensure_ascii=False) |
|
|
oper_param = '请求参数过长' |
|
|
# 日志表请求参数字段长度最大为2000,因此在此处判断长度 |
|
|
|
|
|
if len(oper_param) > 2000: |
|
|
|
|
|
oper_param = '请求参数过长' |
|
|
|
|
|
|
|
|
|
|
|
# 获取操作时间 |
|
|
# 获取操作时间 |
|
|
oper_time = datetime.now() |
|
|
oper_time = datetime.now() |
|
|
# 此处在登录之前向原始函数传递一些登录信息,用于监测在线用户的相关信息 |
|
|
# 此处在登录之前向原始函数传递一些登录信息,用于监测在线用户的相关信息 |
|
|
login_log = {} |
|
|
login_log = {} |
|
|
if log_type == 'login': |
|
|
if log_type == 'login': |
|
|
user_agent_info = parse(user_agent) |
|
|
user_agent_info = parse(user_agent) |
|
|
browser = f'{user_agent_info.browser.family}' |
|
|
browser = f'{user_agent_info.browser.family}' |
|
|
system_os = f'{user_agent_info.os.family}' |
|
|
system_os = f'{user_agent_info.os.family}' |
|
|
if user_agent_info.browser.version != (): |
|
|
if user_agent_info.browser.version != (): |
|
|
browser += f' {user_agent_info.browser.version[0]}' |
|
|
browser += f' {user_agent_info.browser.version[0]}' |
|
|
if user_agent_info.os.version != (): |
|
|
if user_agent_info.os.version != (): |
|
|
system_os += f' {user_agent_info.os.version[0]}' |
|
|
system_os += f' {user_agent_info.os.version[0]}' |
|
|
login_log = dict( |
|
|
login_log = dict( |
|
|
ipaddr=oper_ip, |
|
|
ipaddr=oper_ip, |
|
|
loginLocation=oper_location, |
|
|
loginLocation=oper_location, |
|
|
browser=browser, |
|
|
browser=browser, |
|
|
os=system_os, |
|
|
os=system_os, |
|
|
loginTime=oper_time.strftime('%Y-%m-%d %H:%M:%S') |
|
|
loginTime=oper_time.strftime('%Y-%m-%d %H:%M:%S') |
|
|
) |
|
|
) |
|
|
kwargs['form_data'].login_info = login_log |
|
|
kwargs['form_data'].login_info = login_log |
|
|
# 调用原始函数 |
|
|
# 调用原始函数 |
|
|
result = await func(*args, **kwargs) |
|
|
result = await func(*args, **kwargs) |
|
|
# 获取请求耗时 |
|
|
# 获取请求耗时 |
|
|
cost_time = float(time.time() - start_time) * 100 |
|
|
cost_time = float(time.time() - start_time) * 100 |
|
|
# 判断请求是否来自api文档 |
|
|
# 判断请求是否来自api文档 |
|
|
request_from_swagger = request.headers.get('referer').endswith('docs') if request.headers.get('referer') else False |
|
|
request_from_swagger = request.headers.get('referer').endswith('docs') if request.headers.get('referer') else False |
|
|
request_from_redoc = request.headers.get('referer').endswith('redoc') if request.headers.get('referer') else False |
|
|
request_from_redoc = request.headers.get('referer').endswith('redoc') if request.headers.get('referer') else False |
|
|
# 根据响应结果的类型使用不同的方法获取响应结果参数 |
|
|
# 根据响应结果的类型使用不同的方法获取响应结果参数 |
|
|
if isinstance(result, JSONResponse) or isinstance(result, ORJSONResponse) or isinstance(result, UJSONResponse): |
|
|
if isinstance(result, JSONResponse) or isinstance(result, ORJSONResponse) or isinstance(result, UJSONResponse): |
|
|
result_dict = json.loads(str(result.body, 'utf-8')) |
|
|
result_dict = json.loads(str(result.body, 'utf-8')) |
|
|
|
|
|
else: |
|
|
|
|
|
if request_from_swagger or request_from_redoc: |
|
|
|
|
|
result_dict = {} |
|
|
else: |
|
|
else: |
|
|
if request_from_swagger or request_from_redoc: |
|
|
if result.status_code == 200: |
|
|
result_dict = {} |
|
|
result_dict = {'code': result.status_code, 'message': '获取成功'} |
|
|
else: |
|
|
else: |
|
|
if result.status_code == 200: |
|
|
result_dict = {'code': result.status_code, 'message': '获取失败'} |
|
|
result_dict = {'code': result.status_code, 'message': '获取成功'} |
|
|
json_result = json.dumps(result_dict, ensure_ascii=False) |
|
|
else: |
|
|
# 根据响应结果获取响应状态及异常信息 |
|
|
result_dict = {'code': result.status_code, 'message': '获取失败'} |
|
|
status = 1 |
|
|
json_result = json.dumps(result_dict, ensure_ascii=False) |
|
|
error_msg = '' |
|
|
# 根据响应结果获取响应状态及异常信息 |
|
|
if result_dict.get('code') == 200: |
|
|
status = 1 |
|
|
status = 0 |
|
|
error_msg = '' |
|
|
else: |
|
|
if result_dict.get('code') == 200: |
|
|
error_msg = result_dict.get('msg') |
|
|
status = 0 |
|
|
# 根据日志类型向对应的日志表插入数据 |
|
|
|
|
|
if log_type == 'login': |
|
|
|
|
|
# 登录请求来自于api文档时不记录登录日志,其余情况则记录 |
|
|
|
|
|
if request_from_swagger or request_from_redoc: |
|
|
|
|
|
pass |
|
|
else: |
|
|
else: |
|
|
error_msg = result_dict.get('msg') |
|
|
user = kwargs.get('form_data') |
|
|
# 根据日志类型向对应的日志表插入数据 |
|
|
user_name = user.username |
|
|
if log_type == 'login': |
|
|
login_log['loginTime'] = oper_time |
|
|
# 登录请求来自于api文档时不记录登录日志,其余情况则记录 |
|
|
login_log['userName'] = user_name |
|
|
if request_from_swagger or request_from_redoc: |
|
|
login_log['status'] = str(status) |
|
|
pass |
|
|
login_log['msg'] = result_dict.get('msg') |
|
|
else: |
|
|
|
|
|
user = kwargs.get('form_data') |
|
|
|
|
|
user_name = user.username |
|
|
|
|
|
login_log['loginTime'] = oper_time |
|
|
|
|
|
login_log['userName'] = user_name |
|
|
|
|
|
login_log['status'] = str(status) |
|
|
|
|
|
login_log['msg'] = result_dict.get('msg') |
|
|
|
|
|
|
|
|
|
|
|
LoginLogService.add_login_log_services(query_db, LogininforModel(**login_log)) |
|
|
LoginLogService.add_login_log_services(query_db, LogininforModel(**login_log)) |
|
|
else: |
|
|
else: |
|
|
current_user = await LoginService.get_current_user(request, token, query_db) |
|
|
current_user = await LoginService.get_current_user(request, token, query_db) |
|
|
oper_name = current_user.user.user_name |
|
|
oper_name = current_user.user.user_name |
|
|
dept_name = current_user.user.dept.dept_name if current_user.user.dept else None |
|
|
dept_name = current_user.user.dept.dept_name if current_user.user.dept else None |
|
|
operation_log = OperLogModel( |
|
|
operation_log = OperLogModel( |
|
|
title=title, |
|
|
title=title, |
|
|
businessType=business_type, |
|
|
businessType=business_type, |
|
|
method=func_path, |
|
|
method=func_path, |
|
|
requestMethod=request_method, |
|
|
requestMethod=request_method, |
|
|
operatorType=operator_type, |
|
|
operatorType=operator_type, |
|
|
operName=oper_name, |
|
|
operName=oper_name, |
|
|
deptName=dept_name, |
|
|
deptName=dept_name, |
|
|
operUrl=oper_url, |
|
|
operUrl=oper_url, |
|
|
operIp=oper_ip, |
|
|
operIp=oper_ip, |
|
|
operLocation=oper_location, |
|
|
operLocation=oper_location, |
|
|
operParam=oper_param, |
|
|
operParam=oper_param, |
|
|
jsonResult=json_result, |
|
|
jsonResult=json_result, |
|
|
status=status, |
|
|
status=status, |
|
|
errorMsg=error_msg, |
|
|
errorMsg=error_msg, |
|
|
operTime=oper_time, |
|
|
operTime=oper_time, |
|
|
costTime=int(cost_time) |
|
|
costTime=int(cost_time) |
|
|
) |
|
|
) |
|
|
OperationLogService.add_operation_log_services(query_db, operation_log) |
|
|
OperationLogService.add_operation_log_services(query_db, operation_log) |
|
|
|
|
|
|
|
|
return result |
|
|
return result |
|
|
|
|
|
|
|
|
return wrapper |
|
|
return wrapper |
|
|
|
|
|
|
|
|