tp/docs/operation_log_usage.md
2026-01-26 09:29:36 +08:00

9.4 KiB
Raw Blame History

操作日志使用说明

1. 数据库表创建

执行以下 SQL 创建操作日志表:

-- 操作日志表
CREATE TABLE IF NOT EXISTS `mete_operation_log` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `user_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '用户ID',
  `user_account` varchar(50) NOT NULL DEFAULT '' COMMENT '用户账号',
  `user_name` varchar(50) NOT NULL DEFAULT '' COMMENT '用户姓名',
  `module` varchar(50) NOT NULL DEFAULT '' COMMENT '操作模块(如:用户管理、文件管理等)',
  `action` varchar(50) NOT NULL DEFAULT '' COMMENT '操作动作(如:添加、编辑、删除、查询等)',
  `method` varchar(10) NOT NULL DEFAULT '' COMMENT '请求方法GET、POST、PUT、DELETE等',
  `url` varchar(255) NOT NULL DEFAULT '' COMMENT '请求URL',
  `ip` varchar(50) NOT NULL DEFAULT '' COMMENT '操作IP地址',
  `user_agent` varchar(500) NOT NULL DEFAULT '' COMMENT '用户代理(浏览器信息)',
  `request_data` text COMMENT '请求参数JSON格式',
  `response_data` text COMMENT '响应数据JSON格式',
  `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '操作状态1-成功0-失败',
  `error_message` text COMMENT '错误信息(失败时记录)',
  `execution_time` decimal(10,3) NOT NULL DEFAULT '0.000' COMMENT '执行时间(秒)',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `delete_time` datetime DEFAULT NULL COMMENT '删除时间(软删除)',
  PRIMARY KEY (`id`),
  KEY `idx_user_id` (`user_id`),
  KEY `idx_module` (`module`),
  KEY `idx_action` (`action`),
  KEY `idx_create_time` (`create_time`),
  KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='操作日志表';

2. 在控制器中记录操作日志

方法1使用 BaseController 的便捷方法(推荐)

所有继承 BaseController 的控制器都可以使用 $this->logOperation() 方法:

class YourController extends BaseController
{
    public function yourAction()
    {
        $startTime = microtime(true);
        
        try {
            // 你的业务逻辑
            $result = $this->doSomething();
            
            $executionTime = microtime(true) - $startTime;
            
            // 记录成功日志
            $this->logOperation(
                '模块名称',           // 如:用户管理、文件管理等
                '操作动作',           // 如:添加、编辑、删除、查询等
                Request::param(),     // 请求参数(可选,默认自动获取)
                ['id' => $result],   // 响应数据
                1,                    // 状态1-成功
                '',                   // 错误信息(成功时为空)
                $executionTime        // 执行时间(可选)
            );
            
            return json(['code' => 200, 'msg' => '操作成功']);
        } catch (\Exception $e) {
            $executionTime = microtime(true) - $startTime;
            
            // 记录失败日志
            $this->logOperation(
                '模块名称',
                '操作动作',
                Request::param(),
                [],
                0,                    // 状态0-失败
                $e->getMessage(),     // 错误信息
                $executionTime
            );
            
            return json(['code' => 500, 'msg' => $e->getMessage()]);
        }
    }
}

方法2直接使用 OperationLogHelper

use app\admin\common\OperationLogHelper;
use think\facade\Request;

class YourController extends BaseController
{
    public function yourAction()
    {
        $startTime = microtime(true);
        
        try {
            // 你的业务逻辑
            $result = $this->doSomething();
            
            $executionTime = microtime(true) - $startTime;
            
            // 记录成功日志
            OperationLogHelper::log(
                '模块名称',
                '操作动作',
                Request::param(),
                ['result' => 'success'],
                1,
                '',
                $executionTime
            );
            
            return json(['code' => 200, 'msg' => '操作成功']);
        } catch (\Exception $e) {
            $executionTime = microtime(true) - $startTime;
            
            OperationLogHelper::log(
                '模块名称',
                '操作动作',
                Request::param(),
                [],
                0,
                $e->getMessage(),
                $executionTime
            );
            
            return json(['code' => 500, 'msg' => $e->getMessage()]);
        }
    }
}

3. 使用示例

示例1用户管理 - 添加用户

public function addUser()
{
    $startTime = microtime(true);
    
    try {
        $data = Request::param();
        // ... 添加用户的业务逻辑
        $userId = AdminUser::insertGetId($data);
        
        $executionTime = microtime(true) - $startTime;
        
        // 记录日志
        $this->logOperation(
            '用户管理',
            '添加用户',
            $data,
            ['id' => $userId],
            1,
            '',
            $executionTime
        );
        
        return json(['code' => 200, 'msg' => '添加成功']);
    } catch (\Exception $e) {
        $executionTime = microtime(true) - $startTime;
        
        $this->logOperation(
            '用户管理',
            '添加用户',
            Request::param(),
            [],
            0,
            $e->getMessage(),
            $executionTime
        );
        
        return json(['code' => 500, 'msg' => $e->getMessage()]);
    }
}

示例2文件管理 - 创建文件分组

public function createFileCate()
{
    $startTime = microtime(true);
    
    try {
        $data = Request::param();
        $data['create_time'] = date('Y-m-d H:i:s');
        $id = FilesCategory::insertGetId($data);
        
        $executionTime = microtime(true) - $startTime;
        
        // 记录日志
        $this->logOperation(
            '文件管理',
            '创建文件分组',
            $data,
            ['id' => $id],
            1,
            '',
            $executionTime
        );
        
        return json([
            'code' => 200,
            'msg' => '新建文件分组成功',
            'data' => ['id' => $id]
        ]);
    } catch (\Exception $e) {
        $executionTime = microtime(true) - $startTime;
        
        $this->logOperation(
            '文件管理',
            '创建文件分组',
            Request::param(),
            [],
            0,
            $e->getMessage(),
            $executionTime
        );
        
        return json([
            'code' => 500,
            'msg' => '新建文件分组失败: ' . $e->getMessage()
        ]);
    }
}

示例3文件管理 - 删除文件

public function deleteFile($id)
{
    $startTime = microtime(true);
    
    try {
        // ... 删除文件的业务逻辑
        Files::where('id', $id)->delete();
        
        $executionTime = microtime(true) - $startTime;
        
        $this->logOperation(
            '文件管理',
            '删除文件',
            ['id' => $id],
            ['result' => 'success'],
            1,
            '',
            $executionTime
        );
        
        return json(['code' => 200, 'msg' => '删除成功']);
    } catch (\Exception $e) {
        $executionTime = microtime(true) - $startTime;
        
        $this->logOperation(
            '文件管理',
            '删除文件',
            ['id' => $id],
            [],
            0,
            $e->getMessage(),
            $executionTime
        );
        
        return json(['code' => 500, 'msg' => $e->getMessage()]);
    }
}

4. 模块和操作命名规范

模块名称建议:

  • 用户管理
  • 角色管理
  • 文件管理
  • 文章管理
  • 菜单管理
  • 系统设置
  • Banner管理
  • 单页管理
  • 等等...

操作动作建议:

  • 添加 / 创建
  • 编辑 / 更新
  • 删除
  • 查询 / 查看
  • 登录
  • 登出
  • 上传
  • 下载
  • 导出
  • 导入
  • 重命名
  • 移动
  • 修改密码
  • 等等...

5. 注意事项

  1. 敏感信息过滤工具类会自动过滤密码、token 等敏感信息
  2. 性能影响:操作日志记录是异步的,不会影响主业务流程
  3. 错误处理:即使日志记录失败,也不会影响业务逻辑的执行
  4. 执行时间:建议使用 microtime(true) 来精确计算执行时间
  5. 按需记录:只在需要记录的操作中添加日志代码,避免过度记录

6. 前端查看

操作日志可以在后台管理系统的"系统管理 -> 操作日志"页面查看,支持:

  • 关键词搜索
  • 模块筛选
  • 操作动作筛选
  • 状态筛选
  • 时间范围筛选
  • 查看详情
  • 删除和批量删除

7. 总结

使用方式

  • 推荐使用 $this->logOperation() 方法BaseController 提供)
  • 或者使用 OperationLogHelper::log() 静态方法

使用场景

  • 重要的增删改操作
  • 需要审计的操作
  • 需要追踪问题的操作

不需要记录

  • 简单的查询操作
  • 频繁的操作(如心跳检测)
  • 不重要的操作