You've already forked think-plugs-recorder
15 KiB
15 KiB
think-plugs-recorder 插件设计文档
1. 功能需求分析
1.1 项目概述
think-plugs-recorder 是一个基于 ThinkAdmin v6.1 的操作记录插件,用于记录用户在系统中的各种操作行为,提供完整的操作日志追踪功能。
1.2 核心功能需求
1.2.1 操作记录功能
- 记录用户的读取操作
- 记录用户的自定义操作
- 支持记录操作数据的类型和ID
- 支持记录关联数据的类型和ID
1.2.2 记录字段要求
- 操作类型 (operation_type): 如 create, read, update, delete, custom 等
- 操作说明 (operation_desc): 具体的操作描述
- 用户ID (user_id): 操作用户的唯一标识
- 用户昵称 (user_nickname): 操作用户的显示名称
- 操作时间 (operation_time): 操作发生的时间戳
- 当前操作数据类型 (data_type): 如 user, order, product 等
- 当前操作数据ID (data_id): 具体数据记录的ID
- 关联数据类型 (related_type): 关联数据的类型(可选)
- 关联数据ID (related_id): 关联数据的ID(可选)
1.2.3 功能扩展需求
- 支持批量记录操作
- 支持按多种条件查询操作记录
- 支持操作记录的导出功能
- 支持自定义操作类型配置
- 支持敏感操作的特殊标记
1.3 非功能性需求
- 性能要求: 记录操作不应影响主业务性能
- 存储要求: 支持大量历史记录存储
- 安全要求: 操作记录不可被随意修改或删除
- 可维护性: 提供清晰的接口和配置选项
2. 数据库设计
2.1 主要数据表设计
2.1.1 操作记录表 (jl_recorder_log)
CREATE TABLE `jl_recorder_log` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '记录ID',
`operation_type` varchar(50) NOT NULL DEFAULT '' COMMENT '操作类型',
`operation_desc` varchar(500) NOT NULL DEFAULT '' COMMENT '操作说明',
`user_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '操作用户ID',
`user_nickname` varchar(100) NOT NULL DEFAULT '' COMMENT '操作用户昵称',
`data_type` varchar(100) NOT NULL DEFAULT '' COMMENT '操作数据类型',
`data_id` varchar(100) NOT NULL DEFAULT '' COMMENT '操作数据ID',
`related_type` varchar(100) NOT NULL DEFAULT '' COMMENT '关联数据类型',
`related_id` varchar(100) NOT NULL DEFAULT '' COMMENT '关联数据ID',
`request_method` varchar(10) NOT NULL DEFAULT '' COMMENT '请求方法',
`request_url` varchar(500) NOT NULL DEFAULT '' COMMENT '请求URL',
`request_ip` varchar(50) NOT NULL DEFAULT '' COMMENT '请求IP',
`user_agent` varchar(500) NOT NULL DEFAULT '' COMMENT '用户代理',
`extra_data` text COMMENT '额外数据(JSON格式)',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_operation_type` (`operation_type`),
KEY `idx_data_type_id` (`data_type`, `data_id`),
KEY `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='操作记录表';
2.1.2 预置操作类型说明
操作类型直接使用中文字符串,常用的操作类型包括:
- 创建: 新增数据记录
- 读取: 查看数据详情
- 更新: 修改数据记录
- 删除: 删除数据记录
- 导出: 导出数据
- 登录: 用户登录
- 登出: 用户登出
- 审核: 审核操作
- 发布: 发布操作
2.2 索引设计说明
idx_user_id
: 按用户查询操作记录idx_operation_type
: 按操作类型查询idx_data_type_id
: 按数据类型和ID查询特定数据的操作记录idx_created_at
: 按时间范围查询操作记录
3. 架构设计
3.1 插件架构
think-plugs-recorder/
├── composer.json # Composer配置
├── DESIGN.md # 设计文档
├── README.md # 使用说明
├── src/ # 源码目录
│ ├── Service.php # 插件服务类
│ ├── model/ # 模型目录
│ │ └── RecorderLog.php # 操作记录模型
│ ├── service/ # 服务目录
│ │ └── RecorderService.php # 核心服务类
│ ├── controller/ # 控制器目录 (可选)
│ │ └── RecorderController.php # 记录管理控制器
│ ├── middleware/ # 中间件目录
│ │ └── RecorderMiddleware.php # 操作记录中间件
│ └── helper/ # 辅助工具目录
│ └── ViewHelper.php # 视图辅助类
├── stc/ # 静态资源
│ └── database/ # 数据库迁移脚本
│ └── 20241201000001_create_recorder_logs_table.php
└── view/ # 视图文件
└── recorder/
├── components/ # 视图组件
│ ├── record_list.html # 记录列表组件
│ ├── record_item.html # 记录项组件
│ └── record_timeline.html # 时间线组件
├── index.html # 管理页面
└── detail.html # 详情页面
3.2 核心类设计
3.2.1 RecorderService 核心服务类
<?php
namespace jerryyan\recorder\service;
class RecorderService
{
// 记录操作
public function record(array $data): bool;
// 批量记录操作
public function batchRecord(array $records): bool;
// 查询操作记录
public function query(array $conditions = []): array;
// 获取用户操作记录
public function getUserRecords(int $userId, array $conditions = []): array;
// 获取数据操作记录
public function getDataRecords(string $dataType, string $dataId): array;
// 导出操作记录
public function export(array $conditions = []): string;
// 清理过期记录
public function cleanup(int $days = 90): int;
}
3.2.2 RecorderLog 数据模型
<?php
namespace jerryyan\recorder\model;
class RecorderLog extends \think\admin\Model
{
// 自动时间戳
protected $autoWriteTimestamp = true;
// 字段类型转换
protected $type = [
'id' => 'integer',
'user_id' => 'integer',
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
// 字段验证规则
protected function getRules(): array;
// 获取额外数据
public function getExtraDataAttr($value): array;
// 设置额外数据
public function setExtraDataAttr($value): string;
}
3.2.3 ViewHelper 视图辅助类
<?php
namespace jerryyan\recorder\helper;
class ViewHelper
{
// 获取操作记录数据
public static function getRecords(array $conditions = []): array;
// 渲染记录列表HTML
public static function renderList(array $conditions = [], array $options = []): string;
// 渲染记录时间线HTML
public static function renderTimeline(array $conditions = [], array $options = []): string;
// 渲染单条记录HTML
public static function renderItem(array $record, array $options = []): string;
// 注册模板函数
public static function registerTemplateFunctions(): void;
}
3.3 接口设计
3.3.1 记录接口
// 基础记录接口
RecorderService::record([
'operation_type' => '读取',
'operation_desc' => '查看用户信息',
'data_type' => 'user',
'data_id' => '123',
'related_type' => 'department',
'related_id' => '456'
]);
// 自动记录当前用户信息
RecorderService::autoRecord([
'operation_type' => '创建',
'operation_desc' => '创建新订单',
'data_type' => 'order',
'data_id' => '789'
]);
3.3.2 查询接口
// 查询用户操作记录
$records = RecorderService::getUserRecords(123, [
'operation_type' => '读取',
'start_time' => '2024-01-01',
'end_time' => '2024-12-31'
]);
// 查询数据操作记录
$records = RecorderService::getDataRecords('user', '123');
// 复杂条件查询
$records = RecorderService::query([
'user_id' => 123,
'operation_type' => ['读取', '更新'],
'data_type' => 'user',
'date_range' => ['2024-01-01', '2024-12-31']
]);
3.3.3 视图调用接口
// 在模板中获取操作记录
{:recorder_get_records(['data_type' => 'user', 'data_id' => $user_id])}
// 渲染记录列表
{:recorder_render_list(['user_id' => $user_id], ['limit' => 10])}
// 渲染时间线
{:recorder_render_timeline(['data_type' => 'order', 'data_id' => $order_id])}
// 渲染单条记录
{:recorder_render_item($record)}
4. 使用方式设计
4.1 手动记录
在业务代码中手动调用记录方法:
use jerryyan\recorder\service\RecorderService;
// 在控制器或服务中记录操作
RecorderService::record([
'operation_type' => '读取',
'operation_desc' => '查看用户详情',
'data_type' => 'user',
'data_id' => $userId
]);
4.2 中间件自动记录
通过中间件自动记录请求操作:
// 在应用配置中启用中间件
'middleware' => [
'jerryyan\recorder\middleware\RecorderMiddleware'
]
4.3 模型事件记录
在模型事件中自动记录CRUD操作:
// 在模型中添加事件监听
protected static function onAfterInsert($model) {
RecorderService::autoRecord([
'operation_type' => '创建',
'operation_desc' => '创建' . $model->getTable() . '记录',
'data_type' => $model->getTable(),
'data_id' => $model->getPk()
]);
}
4.4 视图模板调用
在ThinkPHP模板中直接调用操作记录功能:
4.4.1 获取记录数据
<!-- 获取用户操作记录 -->
{assign name="user_records" value=":recorder_get_records(['user_id' => $user_id, 'limit' => 5])" /}
<!-- 获取特定数据的操作记录 -->
{assign name="data_records" value=":recorder_get_records(['data_type' => 'order', 'data_id' => $order_id])" /}
<!-- 遍历显示记录 -->
{volist name="user_records" id="record"}
<div class="record-item">
<span class="operation">{$record.operation_type}</span>
<span class="desc">{$record.operation_desc}</span>
<span class="time">{$record.created_at}</span>
</div>
{/volist}
4.4.2 渲染HTML组件
<!-- 渲染操作记录列表 -->
<div class="record-section">
<h4>操作记录</h4>
{:recorder_render_list(['user_id' => $user_id], ['limit' => 10, 'show_user' => false])}
</div>
<!-- 渲染时间线样式 -->
<div class="timeline-section">
<h4>操作时间线</h4>
{:recorder_render_timeline(['data_type' => 'order', 'data_id' => $order_id], ['theme' => 'vertical'])}
</div>
<!-- 在用户详情页显示最近操作 -->
<div class="recent-actions">
<h5>最近操作</h5>
{:recorder_render_list(['user_id' => $user_id], ['limit' => 3, 'compact' => true])}
</div>
4.4.3 AJAX异步加载
<!-- 异步加载更多记录 -->
<div id="record-container">
<div class="record-list">
{:recorder_render_list(['data_type' => 'user', 'data_id' => $user_id], ['limit' => 10])}
</div>
<button onclick="loadMoreRecords()" class="load-more">加载更多</button>
</div>
<script>
function loadMoreRecords() {
$.post('/recorder/load_more', {
data_type: 'user',
data_id: {$user_id},
offset: $('.record-item').length
}, function(html) {
$('.record-list').append(html);
});
}
</script>
4.4.4 可配置的显示选项
<!-- 带配置选项的记录列表 -->
{assign name="list_options" value="[
'limit' => 20,
'show_user' => true,
'show_ip' => false,
'date_format' => 'Y-m-d H:i:s',
'theme' => 'card',
'show_extra' => false
]" /}
{:recorder_render_list(['user_id' => $user_id], $list_options)}
<!-- 简洁模式的时间线 -->
{:recorder_render_timeline(['data_type' => 'project', 'data_id' => $project_id], ['compact' => true, 'limit' => 5])}
5. 配置设计
5.1 插件配置
return [
'recorder' => [
// 是否启用操作记录
'enabled' => true,
// 自动记录模式
'auto_record' => [
'enabled' => true,
'exclude_operations' => ['读取'], // 排除的操作类型
'exclude_controllers' => [], // 排除的控制器
],
// 记录保留天数
'retention_days' => 90,
// 敏感操作标记
'sensitive_operations' => ['删除', '导出'],
// 视图组件配置
'view' => [
'default_limit' => 10,
'date_format' => 'Y-m-d H:i:s',
'theme' => 'default', // default, card, timeline
'show_user' => true,
'show_ip' => false,
'compact_mode' => false,
]
]
];
6. 安全考虑
6.1 数据安全
- 记录表只允许插入和查询,不允许更新和删除
- 敏感操作需要特殊权限才能查看
- 支持数据脱敏显示
6.2 性能考虑
- 异步记录操作日志,不影响主业务
- 定期清理过期日志
- 合理的索引设计
6.3 权限控制
- 基于 ThinkAdmin 的权限系统
- 不同用户只能查看自己的操作记录
- 管理员可以查看所有用户的操作记录
7. 扩展计划
7.1 功能扩展
- 支持操作记录的统计分析
- 支持异常操作的告警机制
- 支持操作记录的可视化展示
7.2 集成扩展
- 支持与其他日志系统集成
- 支持导出到第三方审计系统
- 支持API接口调用记录
7.3 视图功能扩展
- 支持更多主题样式和布局
- 支持自定义模板和组件
- 支持实时刷新和WebSocket推送
- 支持操作记录的图表统计
8. 视图模板函数设计
8.1 注册的模板函数
插件将自动注册以下模板函数供视图调用:
// 获取操作记录数据
function recorder_get_records(array $conditions = []): array
// 渲染记录列表
function recorder_render_list(array $conditions = [], array $options = []): string
// 渲染时间线
function recorder_render_timeline(array $conditions = [], array $options = []): string
// 渲染单条记录
function recorder_render_item(array $record, array $options = []): string
// 获取记录统计
function recorder_get_stats(array $conditions = []): array
8.2 可用的显示选项
$options = [
'limit' => 10, // 显示数量限制
'show_user' => true, // 是否显示用户信息
'show_ip' => false, // 是否显示IP地址
'show_extra' => false, // 是否显示额外数据
'date_format' => 'Y-m-d H:i:s', // 日期格式
'theme' => 'default', // 主题样式 (default, card, timeline, compact)
'compact' => false, // 是否紧凑模式
'css_class' => '', // 自定义CSS类
'template' => '', // 自定义模板文件
];
8.3 视图组件样式
插件提供多种预置样式主题:
- default: 默认列表样式
- card: 卡片式布局
- timeline: 时间线布局
- compact: 紧凑式布局
注意: 此设计文档需要在开始编码前经过确认,确保需求理解准确无误。