TP5數據庫數據變動日志記錄設計


根據網友的設計進行了部分調整: 用戶分為管理員admin表和用戶user表

記錄操作表數據 增刪改: insert/delete/update

<?php
/**
 * OperateLog.php
 * description
 */

namespace app\service;

use think\Db;
use think\Log;

/**
 * 操作日志
 * Class OperateLog
 * @package app\service
 */
class OperateLogService
{
    // 日志表主鍵值id
    protected $primaryid;
    // 操作表的id
    protected $tbid;
    // 操作表名
    protected $tbname;
    // 操作表行字段名
    protected $keys;
    // 操作表行字段值
    protected $values;
    // 表前綴
    protected $prefix;
    // 操作用戶類型: 1管理員,admin_id | 2用戶,user_id
    protected $user_type;
    protected $user_id = 0;
    protected $admin_id = 0;
    protected $ip;
    const LOGT1 = 'operatelog';
    const LOGT2 = 'operatelog_content';

    /**
     * OperateLog constructor.
     * @param int $userType 操作用戶類型,1管理員
     * @param int $uid 操作用戶類型不為1時傳入
     */
    public function __construct($userType = 1, $uid = 0)
    {
        if ($userType == 1) {
            $this->admin_id = session('admin_id');
        } else {
            $this->user_id = $uid;
        }
        $this->user_type = $userType;
        $this->ip = ip2long(getIp());
        $this->url = request()->url();
        $this->prefix = config('database.prefix');
    }

    /**
     * 參數說明 插入行為
     * int              $tbid       查詢指定表的id
     * string           $tbname     數據庫表名
     */
    public function insert($tbid, $tbname)
    {
        try {
            //查詢表注釋
            $tb = Db::query('show table status where name = "' . $this->prefix . $tbname . '"');
            $priIdName = $this->getPrimaryKey($tbname);
            $data = [
                'type' => 1,
                'create_time' => time(),
                'tablename' => $tbname,
                'tableid' => $tbid,
                'tableid_name' => $priIdName,
                'admin_id' => $this->admin_id,
                'user_id' => $this->user_id,
                'user_type' => $this->user_type,
                'ip' => $this->ip,
                'comment' => $tb['Comment'],
                'url' => $this->url,
            ];
            //插入日志主表
            $returnid = Db::name(self::LOGT1)->insertGetId($data);
            //查詢字段注釋
            $fields = Db::query('show full columns from ' . $this->prefix . $tbname);
            foreach ($fields as $v) {
                $commentArray[$v['Field']] = $v['Comment'];
            }
            //查詢所有字段信息,插入日志從表
            $rs = Db::name($tbname)->where($priIdName, $tbid)->find();
            $keys = array_keys($rs);
            $values = array_values($rs);
            for ($i = 0; $i < count($keys); $i++) {
                Db::name(self::LOGT2)->insert([
                    'operatelog_id' => $returnid,
                    'tbkey' => $keys[$i],
                    'tbvalue' => $values[$i],
                    'comment' => $commentArray[$keys[$i]]
                ]);
            }
        } catch (\Exception $e) {
            Log::error($e->getMessage());
        }

    }

    /**
     * 更新行為前
     * @param $tbid
     * @param $tbname
     */
    public function updateStart($tbid, $tbname)
    {
        try {
            //查詢表注釋
            $tb = Db::query('show table status where name = "' . $this->prefix . $tbname . '"');
            $priIdName = $this->getPrimaryKey($tbname);
            $data = [
                'type' => 2,
                'create_time' => time(),
                'tablename' => $tbname,
                'tableid' => $tbid,
                'tableid_name' => $priIdName,
                'admin_id' => $this->admin_id,
                'user_id' => $this->user_id,
                'user_type' => $this->user_type,
                'ip' => $this->ip,
                'comment' => $tb['Comment'],
                'url' => $this->url,
            ];
            //插入日志主表
            $returnid = Db::name(self::LOGT1)->insertGetId($data);
            //查詢修改前數據信息
            $rs = Db::name($tbname)->where($priIdName, $tbid)->find();
            $keys = array_keys($rs);
            $values = array_values($rs);
            $this->primaryid = $returnid;
            $this->tbid = $tbid;
            $this->tbname = $tbname;
            $this->keys = $keys;
            $this->values = $values;
        } catch (\Exception $e) {
            Log::error($e->getMessage());
        }

    }

    /**
     * 更新行為后
     */
    public function updateEnd()
    {
        try {
            //查詢表注釋
            $tb = Db::query('show table status where name = "' . $this->prefix . $this->tbname . '"');
            $priIdName = $this->getPrimaryKey($this->tbname);
            foreach ($tb as $v) {
                $commentArray[$v['Field']] = $v['Comment'];
            }
            //查詢修改后數據信息
            $rs = Db::name($this->tbname)->where($priIdName, $this->tbid)->find();
            $currentvalues = array_values($rs);
            //前后信息進行比較
            for ($i = 0; $i < count($currentvalues); $i++) {
                if ($this->values[$i] !== $currentvalues[$i]) {
                    Db::name(self::LOGT2)->insert([
                        'operatelog_id' => $this->primaryid,
                        'tbkey' => $this->keys[$i],
                        'tbvalue' => $this->values[$i],
                        'currenttbvalue' => $currentvalues[$i],
                        'comment' => $commentArray[$this->keys[$i]]
                    ]);
                }
            }
        } catch (\Exception $e) {
            Log::error($e->getMessage());
        }

    }

    /**
     * 刪除行為
     * @param $tbid
     * @param $tbname
     */
    public function delete($tbid, $tbname)
    {
        try {
            //查詢表注釋
            $tb = Db::query('show table status where name = "' . $this->prefix . $this->tbname . '"');
            $priIdName = $this->getPrimaryKey($this->tbname);
            $data = [
                'type' => 3,
                'create_time' => time(),
                'tablename' => $tbname,
                'tableid' => $tbid,
                'tableid_name' => $priIdName,
                'admin_id' => $this->admin_id,
                'user_id' => $this->user_id,
                'user_type' => $this->user_type,
                'ip' => $this->ip,
                'comment' => $tb['Comment'],
                'url' => $this->url,
            ];
            //插入日志主表
            $returnid = Db::name(self::LOGT1)->insertGetId($data);
            //查詢字段注釋
            $fields = Db::query('show full columns from ' . $this->prefix . $tbname);
            foreach ($fields as $v) {
                $commentArray[$v['Field']] = $v['Comment'];
            }
            //查詢修改前數據信息
            $rs = Db::name($tbname)->where($priIdName, $tbid)->find();
            $keys = array_keys($rs);
            $values = array_values($rs);
            for ($i = 0; $i < count($keys); $i++) {
                Db::name(self::LOGT2)->insert([
                    'operatelog_id' => $returnid,
                    'tbkey' => $keys[$i],
                    'tbvalue' => $values[$i],
                    'comment' => $commentArray[$keys[$i]]
                ]);
            }
        } catch (\Exception $e) {
            Log::error($e->getMessage());
        }

    }

    /**
     * 查詢表主鍵id名
     * @param $tbname
     * @return mixed
     */
    protected function getPrimaryKey($tbname)
    {
        $priIdTb = Db::query("SELECT column_name FROM INFORMATION_SCHEMA.`KEY_COLUMN_USAGE` WHERE table_name='" . $this->prefix . $tbname . "' AND constraint_name='PRIMARY'");
        return $priIdTb[0]['column_name'];
    }
}

數據表設計:

CREATE TABLE `yed_operatelog` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(11) unsigned DEFAULT '0' COMMENT 'user表用戶id',
  `admin_id` int(11) unsigned DEFAULT '0' COMMENT 'admin表主鍵:管理員id',
  `user_type` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '操作用戶類型:1管理員,admin_id | 2用戶,user_id',
  `type` tinyint(1) NOT NULL DEFAULT '1' COMMENT '操作類型:1新增2修改3刪除',
  `tableid` int(11) unsigned NOT NULL,
  `tablename` varchar(255) NOT NULL COMMENT '表名',
  `comment` varchar(255) DEFAULT NULL COMMENT '表的comment屬性',
  `create_time` int(11) unsigned NOT NULL COMMENT '創建時間',
  `tableid_name` varchar(50) NOT NULL DEFAULT '' COMMENT '主鍵id名',
  `ip` int(11) DEFAULT NULL COMMENT '操作ip',
  `url` varchar(800) DEFAULT NULL COMMENT '操作url',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COMMENT='操作日志表';
 
CREATE TABLE `yed_operatelog_content` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `operatelog_id` int(11) NOT NULL COMMENT 'operatelog表id',
  `tbkey` longtext NOT NULL COMMENT '字段名',
  `tbvalue` longtext COMMENT '改之前值',
  `currenttbvalue` longtext COMMENT '改之后值',
  `comment` varchar(255) DEFAULT NULL COMMENT '字段注釋',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT='操作日志從表';

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM