# ThinkAdmin 操作记录插件 基于 ThinkAdmin v6.1 的操作记录插件,提供完整的用户操作追踪功能,支持手动记录和自动记录,包含丰富的视图展示功能。 ## 功能特性 ### 核心功能 - ✅ **灵活记录**: 支持手动记录和自动记录两种模式 - ✅ **完整追踪**: 记录操作类型、用户信息、数据信息、时间等 - ✅ **关联数据**: 支持记录操作数据和关联数据 - ✅ **视图集成**: 提供模板函数,可在视图中直接调用 - ✅ **多种样式**: 支持列表、卡片、时间线等多种展示样式 - ✅ **自动清理**: 支持定期清理过期记录 ### 记录内容 - 操作类型:创建、读取、更新、删除、导出、登录、登出等 - 操作说明:具体的操作描述 - 用户信息:用户ID、用户昵称 - 数据信息:操作的数据类型和ID - 关联信息:关联的数据类型和ID(可选) - 请求信息:请求方法、URL、IP地址、用户代理 - 额外数据:JSON格式的扩展信息 ## 安装配置 ### 1. 数据库迁移 ```bash # 运行数据库迁移脚本 php think migrate:run ``` ### 2. 插件发布 ```bash # 发布插件资源 php think xadmin:publish --migrate ``` ### 3. 配置文件 在 `config/` 目录下创建 `recorder.php` 配置文件: ```php 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', 'show_user' => true, 'show_ip' => false, 'compact_mode' => false, ] ]; ``` ### 4. 注册中间件(可选) 在 `app/middleware.php` 中注册中间件实现自动记录: ```php '创建', 'operation_desc' => '创建新用户', 'data_type' => 'user', 'data_id' => '123' ]); // 完整记录 RecorderService::record([ 'operation_type' => '更新', 'operation_desc' => '修改用户信息', 'user_id' => 1, 'user_nickname' => '管理员', 'data_type' => 'user', 'data_id' => '123', 'related_type' => 'department', 'related_id' => '456', 'extra_data' => ['old_name' => '张三', 'new_name' => '李四'] ]); // 自动记录(自动获取当前用户和请求信息) RecorderService::autoRecord([ 'operation_type' => '导出', 'operation_desc' => '导出用户列表', 'data_type' => 'user' ]); ``` ### 2. 查询操作记录 ```php use jerryyan\recorder\service\RecorderService; // 查询用户操作记录 $userRecords = RecorderService::getUserRecords(123, [ 'limit' => 10, 'operation_type' => '创建' ]); // 查询数据操作记录 $dataRecords = RecorderService::getDataRecords('user', '123'); // 复杂查询 $records = RecorderService::query([ 'user_id' => 123, 'operation_type' => ['创建', '更新'], 'data_type' => 'user', 'start_time' => '2024-01-01', 'end_time' => '2024-12-31', 'keyword' => '用户管理' ]); // 获取统计数据 $stats = RecorderService::getStats([ 'start_time' => '2024-01-01', 'end_time' => '2024-12-31' ]); ``` ### 3. 视图中调用 **注意**: 如果提示函数未定义,请参考 [模板函数使用指南](TEMPLATE_FUNCTIONS_GUIDE.md) 解决。 首先确保函数已正确注册: ```bash # 更新Composer自动加载 composer dump-autoload ``` #### 3.1 获取记录数据 ```html {assign name="records" value=":recorder_get_records(['user_id' => $user_id, 'limit' => 5])" /} {volist name="records" id="record"}
{$record.operation_type} - {$record.operation_desc} - {$record.created_at}
{/volist} ``` #### 3.2 渲染HTML组件 ```html

操作记录

{:recorder_render_list(['user_id' => $user_id], ['limit' => 10])}
{:recorder_render_list(['data_type' => 'order'], ['theme' => 'card', 'show_user' => true])} {:recorder_render_timeline(['data_type' => 'project', 'data_id' => $project_id])} {:recorder_render_item($record, ['show_extra' => true])} ``` #### 3.3 配置选项 ```html {assign name="options" value="[ 'limit' => 20, 'show_user' => true, 'show_ip' => false, 'date_format' => 'Y-m-d H:i:s', 'theme' => 'card', 'compact' => false, 'css_class' => 'my-custom-class' ]" /} {:recorder_render_list(['user_id' => $user_id], $options)} ``` #### 3.4 备用方案(如果函数未注册) ```html {assign name="records" value=":jerryyan\recorder\helper\ViewHelper::getRecords(['user_id' => $user_id])" /} {:jerryyan\recorder\helper\ViewHelper::renderList(['user_id' => $user_id], ['limit' => 10])} {:jerryyan\recorder\helper\ViewHelper::renderTimeline(['data_type' => 'order', 'data_id' => $order_id])} ``` ### 4. 模型事件自动记录 ```php use jerryyan\recorder\service\RecorderService; class User extends \think\admin\Model { // 创建后自动记录 protected static function onAfterInsert($user) { RecorderService::autoRecord([ 'operation_type' => '创建', 'operation_desc' => '创建用户:' . $user->username, 'data_type' => 'user', 'data_id' => $user->id ]); } // 更新后自动记录 protected static function onAfterUpdate($user) { RecorderService::autoRecord([ 'operation_type' => '更新', 'operation_desc' => '更新用户:' . $user->username, 'data_type' => 'user', 'data_id' => $user->id ]); } } ``` ### 5. 数据管理 ```php use jerryyan\recorder\service\RecorderService; // 导出记录 $filepath = RecorderService::export([ 'start_time' => '2024-01-01', 'end_time' => '2024-12-31' ]); // 清理过期记录 $deletedCount = RecorderService::cleanup(90); // 清理90天前的记录 ``` ## 视图样式 插件提供多种内置样式: ### 1. 默认列表样式 简洁的列表展示,适合在管理页面中使用。 ### 2. 卡片样式 美观的卡片布局,适合在首页或仪表板中展示。 ### 3. 时间线样式 时间线形式展示,清晰展示操作的时间顺序。 ### 4. 紧凑样式 紧凑的显示模式,适合空间有限的场景。 ## 数据库结构 插件使用单表存储所有操作记录: ```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='操作记录表'; ``` ## 性能优化 1. **索引优化**: 针对常用查询条件建立了合适的数据库索引 2. **异步记录**: 记录操作不会影响主业务的性能 3. **数据限制**: 自动限制存储数据的长度,避免过大数据影响性能 4. **定期清理**: 支持自动清理过期记录,保持表的性能 ## 安全考虑 1. **数据脱敏**: 自动过滤敏感信息如密码、密钥等 2. **权限控制**: 基于ThinkAdmin的权限系统 3. **只读模式**: 操作记录支持只读模式,防止恶意修改 4. **错误隔离**: 记录失败不会影响主业务逻辑 ## 常见问题 ### Q: 插件安装后没有生效怎么办? A: 检查以下几点: 1. 确认数据库迁移是否成功执行 2. 检查配置文件是否正确 3. 确认插件是否已经正确注册 ### Q: 如何自定义操作类型? A: 操作类型由代码直接控制,可以使用任意中文字符串作为操作类型。 ### Q: 如何实现自定义的视图样式? A: 可以通过以下方式: 1. 在配置中指定自定义CSS类 2. 创建自定义模板文件 3. 修改内置的CSS样式 ### Q: 记录过多会影响性能吗? A: 插件已经进行了性能优化: 1. 使用了合适的数据库索引 2. 支持定期清理过期记录 3. 异步记录不影响主业务 ## 更新日志 ### v1.0.0 (2024-12-12) - 🎉 初始版本发布 - ✅ 支持手动和自动操作记录 - ✅ 提供完整的视图展示功能 - ✅ 支持多种展示样式 - ✅ 包含中间件自动记录功能 ## 许可证 WTFPL ## 作者 Jerry Yan (792602257@qq.com) ## 技术支持 如有问题,请提交 Issue 或联系作者。