You've already forked think-plugs-recorder
recorder
This commit is contained in:
507
DESIGN.md
Normal file
507
DESIGN.md
Normal file
@@ -0,0 +1,507 @@
|
||||
# think-plugs-recorder 插件设计文档
|
||||
|
||||
## 1. 功能需求分析
|
||||
|
||||
### 1.1 项目概述
|
||||
think-plugs-recorder 是一个基于 ThinkAdmin v6.1 的操作记录插件,用于记录用户在系统中的各种操作行为,提供完整的操作日志追踪功能。
|
||||
|
||||
### 1.2 核心功能需求
|
||||
|
||||
#### 1.2.1 操作记录功能
|
||||
- 记录用户的读取操作
|
||||
- 记录用户的自定义操作
|
||||
- 支持记录操作数据的类型和ID
|
||||
- 支持记录关联数据的类型和ID
|
||||
|
||||
#### 1.2.2 记录字段要求
|
||||
1. **操作类型** (operation_type): 如 create, read, update, delete, custom 等
|
||||
2. **操作说明** (operation_desc): 具体的操作描述
|
||||
3. **用户ID** (user_id): 操作用户的唯一标识
|
||||
4. **用户昵称** (user_nickname): 操作用户的显示名称
|
||||
5. **操作时间** (operation_time): 操作发生的时间戳
|
||||
6. **当前操作数据类型** (data_type): 如 user, order, product 等
|
||||
7. **当前操作数据ID** (data_id): 具体数据记录的ID
|
||||
8. **关联数据类型** (related_type): 关联数据的类型(可选)
|
||||
9. **关联数据ID** (related_id): 关联数据的ID(可选)
|
||||
|
||||
#### 1.2.3 功能扩展需求
|
||||
- 支持批量记录操作
|
||||
- 支持按多种条件查询操作记录
|
||||
- 支持操作记录的导出功能
|
||||
- 支持自定义操作类型配置
|
||||
- 支持敏感操作的特殊标记
|
||||
|
||||
### 1.3 非功能性需求
|
||||
- **性能要求**: 记录操作不应影响主业务性能
|
||||
- **存储要求**: 支持大量历史记录存储
|
||||
- **安全要求**: 操作记录不可被随意修改或删除
|
||||
- **可维护性**: 提供清晰的接口和配置选项
|
||||
|
||||
## 2. 数据库设计
|
||||
|
||||
### 2.1 主要数据表设计
|
||||
|
||||
#### 2.1.1 操作记录表 (jl_recorder_log)
|
||||
|
||||
```sql
|
||||
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
|
||||
<?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
|
||||
<?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
|
||||
<?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 记录接口
|
||||
```php
|
||||
// 基础记录接口
|
||||
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 查询接口
|
||||
```php
|
||||
// 查询用户操作记录
|
||||
$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 视图调用接口
|
||||
```php
|
||||
// 在模板中获取操作记录
|
||||
{: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 手动记录
|
||||
在业务代码中手动调用记录方法:
|
||||
```php
|
||||
use jerryyan\recorder\service\RecorderService;
|
||||
|
||||
// 在控制器或服务中记录操作
|
||||
RecorderService::record([
|
||||
'operation_type' => '读取',
|
||||
'operation_desc' => '查看用户详情',
|
||||
'data_type' => 'user',
|
||||
'data_id' => $userId
|
||||
]);
|
||||
```
|
||||
|
||||
### 4.2 中间件自动记录
|
||||
通过中间件自动记录请求操作:
|
||||
```php
|
||||
// 在应用配置中启用中间件
|
||||
'middleware' => [
|
||||
'jerryyan\recorder\middleware\RecorderMiddleware'
|
||||
]
|
||||
```
|
||||
|
||||
### 4.3 模型事件记录
|
||||
在模型事件中自动记录CRUD操作:
|
||||
```php
|
||||
// 在模型中添加事件监听
|
||||
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 获取记录数据
|
||||
```html
|
||||
<!-- 获取用户操作记录 -->
|
||||
{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组件
|
||||
```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异步加载
|
||||
```html
|
||||
<!-- 异步加载更多记录 -->
|
||||
<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 可配置的显示选项
|
||||
```html
|
||||
<!-- 带配置选项的记录列表 -->
|
||||
{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 插件配置
|
||||
```php
|
||||
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 注册的模板函数
|
||||
插件将自动注册以下模板函数供视图调用:
|
||||
|
||||
```php
|
||||
// 获取操作记录数据
|
||||
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 可用的显示选项
|
||||
```php
|
||||
$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**: 紧凑式布局
|
||||
|
||||
---
|
||||
|
||||
**注意**: 此设计文档需要在开始编码前经过确认,确保需求理解准确无误。
|
Reference in New Issue
Block a user