diff --git a/applications/common/admin.py b/applications/common/admin.py index 4550d7d..2c1b62d 100644 --- a/applications/common/admin.py +++ b/applications/common/admin.py @@ -1,18 +1,96 @@ from io import BytesIO +from flask import make_response +from flask_login import current_user -from flask import session, make_response - +from applications.common.utils.validate import str_escape from applications.common.utils.captcha import vieCode +from applications.extensions import db +from applications.models import AdminLog -# 生成验证码 def get_captcha(): + """ + 生成验证码图片及其对应的验证码字符串。 + + :return: 返回验证码图片的响应对象和验证码字符串。 + """ image, code = vieCode().GetCodeImage() code = ''.join(code).lower() out = BytesIO() - # session["code"] = code image.save(out, 'png') out.seek(0) resp = make_response(out.read()) resp.content_type = 'image/png' - return resp, code \ No newline at end of file + return resp, code + + +def normal_log(method, url, ip, user_agent, desc, uid, is_access): + """ + 记录通用日志信息到数据库。 + + :param method: 请求方法(如 GET、POST)。 + :param url: 请求的 URL。 + :param ip: 客户端的 IP 地址。 + :param user_agent: 客户端的 User-Agent 信息。 + :param desc: 日志描述信息。 + :param uid: 用户 ID。 + :param is_access: 是否成功访问(True 或 False)。 + :return: 返回日志记录的 ID。 + """ + info = { + 'method': method, + 'url': url, + 'ip': ip, + 'user_agent': user_agent, + 'desc': desc, + 'uid': uid, + 'success': int(is_access) + } + log = AdminLog( + url=info.get('url'), + ip=info.get('ip'), + user_agent=info.get('user_agent'), + desc=info.get('desc'), + uid=info.get('uid'), + method=info.get('method'), + success=info.get('success') + ) + db.session.add(log) + db.session.commit() + return log.id + + +def login_log(request, uid, is_access): + """ + 记录用户登录日志。 + + :param request: Flask 请求对象。 + :param uid: 用户 ID。 + :param is_access: 是否成功登录(True 或 False)。 + :return: 返回日志记录的 ID。 + """ + method = request.method + url = request.path + ip = request.remote_addr + user_agent = str_escape(request.headers.get('User-Agent')) + desc = str_escape(request.form.get('username')) + return normal_log(method, url, ip, user_agent, desc, uid, is_access) + + +def admin_log(request, is_access, desc=None): + """ + 记录管理员操作日志。 + + :param request: Flask 请求对象。 + :param is_access: 是否成功操作(True 或 False)。 + :param desc: 日志描述信息(可选)。如果未提供,则从请求数据中提取。 + :return: 返回日志记录的 ID。 + """ + method = request.method + url = request.path + ip = request.remote_addr + user_agent = str_escape(request.headers.get('User-Agent')) + request_data = request.json if request.headers.get('Content-Type') == 'application/json' else request.values + if desc is None: + desc = str_escape(str(dict(request_data))) + return normal_log(method, url, ip, user_agent, desc, current_user.id, is_access) diff --git a/applications/common/admin_log.py b/applications/common/admin_log.py deleted file mode 100644 index ea1298f..0000000 --- a/applications/common/admin_log.py +++ /dev/null @@ -1,49 +0,0 @@ -from flask_login import current_user - -from applications.common.utils.validate import str_escape -from applications.extensions import db -from applications.models import AdminLog - - -def normal_log(method, url, ip, user_agent, desc, uid, is_access): - info = { - 'method': method, - 'url': url, - 'ip': ip, - 'user_agent': user_agent, - 'desc': desc, - 'uid': uid, - 'success': int(is_access) - } - log = AdminLog( - url=info.get('url'), - ip=info.get('ip'), - user_agent=info.get('user_agent'), - desc=info.get('desc'), - uid=info.get('uid'), - method=info.get('method'), - success=info.get('success') - ) - db.session.add(log) - db.session.commit() - return log.id - - -def login_log(request, uid, is_access): - method = request.method - url = request.path - ip = request.remote_addr - user_agent = str_escape(request.headers.get('User-Agent')) - desc = str_escape(request.form.get('username')) - return normal_log(method, url, ip, user_agent, desc, uid, is_access) - - -def admin_log(request, is_access, desc=None): - method = request.method - url = request.path - ip = request.remote_addr - user_agent = str_escape(request.headers.get('User-Agent')) - request_data = request.json if request.headers.get('Content-Type') == 'application/json' else request.values - if desc is None: - desc = str_escape(str(dict(request_data))) - return normal_log(method, url, ip, user_agent, desc, current_user.id, is_access) diff --git a/applications/common/utils/rights.py b/applications/common/utils/rights.py index c498c2f..bb48725 100644 --- a/applications/common/utils/rights.py +++ b/applications/common/utils/rights.py @@ -1,7 +1,7 @@ from functools import wraps from flask import abort, request, jsonify, session, current_app from flask_login import login_required, current_user -from applications.common.admin_log import admin_log +from applications.common.admin import admin_log def authorize(power: str, log: bool = False): diff --git a/applications/view/system/mail.py b/applications/view/system/mail.py index 51f3f16..17e4fc1 100644 --- a/applications/view/system/mail.py +++ b/applications/view/system/mail.py @@ -10,7 +10,7 @@ from applications.extensions import db from applications.models import Mail from applications.schemas import MailOutSchema from applications.common.utils import mail -from applications.common.admin_log import admin_log +from applications.common.admin import admin_log bp = Blueprint('adminMail', __name__, url_prefix='/mail') diff --git a/applications/view/system/passport.py b/applications/view/system/passport.py index 6004981..3b53d55 100644 --- a/applications/view/system/passport.py +++ b/applications/view/system/passport.py @@ -1,8 +1,7 @@ from flask import Blueprint, session, redirect, url_for, render_template, request from flask_login import current_user, login_user, login_required, logout_user -from applications.common import admin as index_curd -from applications.common.admin_log import login_log +from applications.common.admin import get_captcha, login_log from applications.common.utils.http import fail_api, success_api from applications.models import User @@ -11,8 +10,8 @@ bp = Blueprint('passport', __name__, url_prefix='/passport') # 获取验证码 @bp.get('/getCaptcha') -def get_captcha(): - resp, code = index_curd.get_captcha() +def captcha(): + resp, code = get_captcha() session["code"] = code return resp diff --git a/docs/source/function/admin.rst b/docs/source/function/admin.rst new file mode 100644 index 0000000..b23d1a9 --- /dev/null +++ b/docs/source/function/admin.rst @@ -0,0 +1,49 @@ +:mod:`admin` -- 后台函数模块 +======================================= + +:mod:`admin` 模块源代码在文件夹 `applications/common/admin.py` 下,主要集结了一些常用的后台需要频繁调用的函数。 + +.. module:: admin + +函数 +------------- + +.. function:: get_captcha() + + 生成验证码图片及其对应的验证码字符串。 + + :return: 返回验证码图片的响应对象和验证码字符串。 + + +.. function:: normal_log(method, url, ip, user_agent, desc, uid, is_access) + + 记录通用日志信息到数据库。 + + :param method: 请求方法(如 GET、POST)。 + :param url: 请求的 URL。 + :param ip: 客户端的 IP 地址。 + :param user_agent: 客户端的 User-Agent 信息。 + :param desc: 日志描述信息。 + :param uid: 用户 ID。 + :param is_access: 是否成功访问(True 或 False)。 + :return: 返回日志记录的 ID。 + + +.. function:: login_log(request, uid, is_access) + + 记录用户登录日志。 + + :param request: Flask 请求对象。 + :param uid: 用户 ID。 + :param is_access: 是否成功登录(True 或 False)。 + :return: 返回日志记录的 ID。 + + +.. function:: admin_log(request, is_access, desc=None) + + 记录管理员操作日志。 + + :param request: Flask 请求对象。 + :param is_access: 是否成功操作(True 或 False)。 + :param desc: 日志描述信息(可选)。如果未提供,则从请求数据中提取。 + :return: 返回日志记录的 ID。 \ No newline at end of file diff --git a/docs/source/function/index.rst b/docs/source/function/index.rst index 2031ba7..b567811 100644 --- a/docs/source/function/index.rst +++ b/docs/source/function/index.rst @@ -2,6 +2,17 @@ 目录索引 +公共函数 +------------ + +.. toctree:: + :maxdepth: 1 + + admin + +辅助函数 +------------ + .. toctree:: :maxdepth: 1 diff --git a/docs/source/function/utils/index.rst b/docs/source/function/utils/index.rst index b85744f..17cbaf5 100644 --- a/docs/source/function/utils/index.rst +++ b/docs/source/function/utils/index.rst @@ -1,5 +1,3 @@ -.. module:: applications.common.utils - .. title:: 辅助函数 目录索引 diff --git a/docs/source/function/utils/validate.rst b/docs/source/function/utils/validate.rst index 6bb62cd..b6048bd 100644 --- a/docs/source/function/utils/validate.rst +++ b/docs/source/function/utils/validate.rst @@ -1,7 +1,7 @@ :mod:`validate` -- 效验模块 ================================== -:mod:`validate` 模块源代码在文件夹 `applications/common/utils/rights.py` 下,主要用于数据效验与过滤。 +:mod:`validate` 模块源代码在文件夹 `applications/common/utils/validate.py` 下,主要用于数据效验与过滤。 .. module:: validate diff --git a/docs/source/welcome/migration.rst b/docs/source/welcome/migration.rst index 0d9f0c2..2481b9d 100644 --- a/docs/source/welcome/migration.rst +++ b/docs/source/welcome/migration.rst @@ -94,5 +94,20 @@ 你会注意到修改之后的 layui-btn-primary 属性添加在了 “重置” 按钮上,而不是 “查询” 按钮上, 这是因为 layui-btn-primary 是默认白色的,而不加 layui-btn-primary 属性是跟随主题色的。这里需要特别注意一下。 +合并日志模块 +~~~~~~~~~~~~~~~~~~~~ + +为了减少冗余,将 applications/common/admin_log.py 与 applications/common/admin.py 合并,仅留下 applications/common/admin.py 。 +例如: + +.. code-block:: python + + from applications.common.admin_log import admin_log + +改为: + +.. code-block:: python + + from applications.common.admin import admin_log \ No newline at end of file diff --git a/docs/source/welcome/update.rst b/docs/source/welcome/update.rst index 7ab5799..039c1ee 100644 --- a/docs/source/welcome/update.rst +++ b/docs/source/welcome/update.rst @@ -38,6 +38,8 @@ * 增加后台消息接口 * 系统监控中对硬盘的获取,如果是在 docker 中就获取根目录的数据 * 更正登录之后重定向由于路由更改从而设置错误的问题 +* 将 applications/common/admin_log.py 与 applications/common/admin.py 合并,仅留下 applications/common/admin.py +* 优化代码结构,新增函数 `normal_log` 减少代码复用 已知问题以及解决方式 ~~~~~~~~~~~~~~~~~~~~~~~