欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 产业 > 二十六、【健壮性与审计篇】操作日志:前端日志管理界面的设计与实现

二十六、【健壮性与审计篇】操作日志:前端日志管理界面的设计与实现

2025/6/19 14:38:27 来源:https://blog.csdn.net/weixin_48321392/article/details/148739445  浏览:    关键词:二十六、【健壮性与审计篇】操作日志:前端日志管理界面的设计与实现

【健壮性与审计篇】操作日志:前端日志管理界面的设计与实现

    • 前言
    • 第一部分:后端实现 - 操作日志模型与API
      • 1. 创建 OperationLog 模型
      • 2. 生成并应用数据库迁移
      • 3. 创建记录操作日志的工具/装饰器
      • 4. 在关键视图操作中调用日志记录函数
      • 5. 创建 OperationLogSerializer 和 OperationLogViewSet
      • 6. 注册 OperationLogViewSet 路由
      • 7. 测试后端日志记录
    • 第二部分:前端实现 - 操作日志查看界面
      • 1. 创建 API 服务 (`src/api/log.ts`)
      • 2. 添加路由和菜单入口
      • 3. 创建操作日志列表页面 (`src/views/system/OperationLogListView.vue`)
      • 第四部分:全面测试
    • 总结

前言

在上一篇关于健壮性的文章中,我们重点配置了后端的错误日志和前端的错误捕获。现在,我们将更进一步,实现一个专门的操作日志系统,用于记录用户在平台上的关键操作,并提供一个前端界面供管理员查看这些日志,以达到审计和问题追踪的目的。

这篇文章将分为后端和前端两大部分:

  • 后端:
    1. 创建 OperationLog 模型来结构化地存储操作日志。
    2. 实现一个工具函数或装饰器,方便在关键的视图操作中记录日志。
    3. 创建 OperationLogSerializerOperationLogViewSet 提供 API。
  • 前端:
    1. 创建 API 服务调用后端日志接口。
    2. 实现操作日志列表页面,支持筛选和分页。

第一部分:后端实现 - 操作日志模型与API

1. 创建 OperationLog 模型

打开 test-platform/backend/api/models.py,添加 OperationLog 模型:
在这里插入图片描述

# test-platform/api/models.py
import uuid
from django.db import models
from django.conf import settings # 导入 settings
from django.contrib.auth.models import User# ... (其他模型保持不变) ...class OperationLog(models.Model):"""操作日志模型"""user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, # 用户删除后,日志中的用户字段设为NULLnull=True, blank=True, verbose_name="操作用户")action_time = models.DateTimeField(auto_now_add=True, verbose_name="操作时间")action_type_choices = [('CREATE', '创建'), ('UPDATE', '更新'), ('DELETE', '删除'),('LOGIN', '登录'), ('LOGOUT', '登出'), ('EXECUTE', '执行'),('VIEW', '查看'), ('OTHER', '其他')]action_type = models.CharField(max_length=10, choices=action_type_choices, verbose_name="操作类型")# 例如:Project, Module, TestCase, User, Role 等target_resource = models.CharField(max_length=100, verbose_name="操作对象类型")target_id = models.CharField(max_length=100, null=True, blank=True, verbose_name="操作对象ID") # 有些操作可能没有具体IDdescription = models.TextField(verbose_name="操作描述") # 例如 "创建了项目 '项目A'"# 存储更详细的上下文信息,例如请求参数、修改前后的数据差异等 (可选)details = models.JSONField(null=True, blank=True, verbose_name="详细信息 (JSON)")# 记录操作时的 IP 地址ip_address = models.GenericIPAddressField(null=True, blank=True, verbose_name="IP地址")class Meta:verbose_name = "操作日志"verbose_name_plural = "操作日志列表"ordering = ['-action_time'] # 按操作时间降序def __str__(self):user_str = self.user.username if self.user else "系统操作"return f"{self.action_time.strftime('%Y-%m-%d %H:%M:%S')} - {user_str} {self.get_action_type_display()} {self.target_resource}: {self.description[:50]}"

模型字段解释:

  • user: 关联到执行操作的用户。
  • action_time: 操作发生的时间。
  • action_type: 操作的类型(创建、更新、删除、登录、执行等)。
  • target_resource: 操作影响的资源类型(如"项目"、“用户”)。
  • target_id: 操作影响的具体资源ID。
  • description: 对操作的简短描述。
  • details: (可选) JSON格式,存储更详细的上下文或数据快照。
  • ip_address: 操作者IP地址。

2. 生成并应用数据库迁移

python manage.py makemigrations api
python manage.py migrate api

在这里插入图片描述

3. 创建记录操作日志的工具/装饰器

为了方便在各个视图中记录操作日志,我们可以创建一个工具函数。

a. 创建 api/utils/log_utils.py
在这里插入图片描述
在这里插入图片描述

# test-platform/api/utils/log_utils.py
from ..models import OperationLog # 从父级 models 导入
from django.contrib.auth.models import User
from typing import Optional, Dict, Anydef get_client_ip(request) -> Optional[str]:"""获取客户端IP地址"""x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')if x_forwarded_for:ip = x_forwarded_for.split(',')[0]else:ip = request.META.get('REMOTE_ADDR')return ipdef record_operation_log(user: Optional[User],action_type: str,target_resource: str,description: str,target_id: Optional[Any] = None,details: Optional[Dict[str, Any]] = None,request = None # 可选,用于获取 IP
):"""记录一条操作日志。"""ip_addr = Noneif request:ip_addr = get_client_ip(request)try:OperationLog.objects.create(user=user if user and user.is_authenticated else None,action_type=action_type,target_resource=target_resource,target_id=str(target_id) if target_id is not None else None,description=description,details=details,ip_address=ip_addr)except Exception as e:# 记录日志失败不应影响主业务流程,但应记录错误import logginglogger = logging.getLogger(__name__) # 或者使用 app 级别的 loggerlogger.error(f"记录操作日志失败: {e}", exc_info=True)

4. 在关键视图操作中调用日志记录函数

现在,我们需要在一些关键的 ModelViewSet 操作 (如 create, update, destroy) 或自定义 action 中调用 record_operation_log

修改 ProjectViewSet (api/views.py):
在这里插入图片描述

# test-platform/api/views.py
from .utils.log_utils import record_operation_log # 导入日志记录函数
# ... 其他导入 ...class ProjectViewSet(viewsets.ModelViewSet):queryset = Project.objects.all().order_by('-create_time')serializer_class = ProjectSerializerpermission_classes = [permissions.IsAuthenticated]def perform_create(self, serializer):instance = serializer.save()record_operation_log(user=self.request.user,action_type='CREATE',target_resource='项目',target_id=instance.id,description=f"创建了项目: '{instance.name}' (ID: {instance.id})",request=self.request # 传递 request 对象以获取 IP)def perform_update(self, serializer):instance = serializer.save()# 可以在 details 中记录修改前后的差异 (更复杂)record_operation_log(user=self.request.user,action_type='UPDATE',target_resource='项目',target_id=instance.id,description=f"更新了项目: '{instance.name}' (ID: {instance.id})",request=self.request)def perform_destroy(self, instance):project_name = instance.nameproject_id = instance.idinstance.delete()record_operation_log(user=self.request.user,action_type='DELETE',target_resource='项目',target_id=project_id, # instance 在 delete() 后可能没有 iddescription=f"删除了项目: '{project_name}' (ID: {project_id})",request=self.request)

修改 ModuleViewSet (api/views.py):

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词