zoukankan      html  css  js  c++  java
  • 浅谈管理系统操作日志设计(附操作日志类)(转)

    管理系统的操作日志如何做成通用的模块一直是个让我头疼的问题,不过看了博客园里的某篇文章后,现在基本解决了。

      相关文章链接:《系统操作日志设计

      在开始做之前,必须把两个日志分清楚,那就是普通操作日志和业务操作日志,这两者有何区别?

      在我理解,普通操作日志就是单表的操作记录,而业务操作日志则就是一系列的普通操作日志的集合。

      打个比方,用户需要购买一样宝贝,已经到了下单那步,下单就是个业务,这个业务背后就是一系列的业务,如:

      生成订单 → 生成商品快照 → 发送一条站内信 → 删除购物车里对应宝贝

      这样一个下单操作就包含了4部分,可以把这4部分看成是4张表,分别对这4张表进行对应的操作,就实现了业务。

      但今天我要讲的不是业务操作日志,因为不同项目的业务不尽相同,所以它无法做成通用模块,而我要讲的,就是普通操作日志。

      上面解释了一大段,下面干货就要亮相了,先洗把脸清醒下。

      ……

      首先,哪些地方需要记录操作日志?执行insert、update、delete这3个操作的时候,就需要进行日志,而日志执行的先后顺序如下

    insert 在insert后执行
    update 在update前后都要执行,操作前获取操作前数据,操作后获取操作后数据
    delete 在delete前执行

      顺序清楚后,就来看下我写的一份日志操作类吧,第一版随便写写的,重复代码有点多,还未来得及优化。

     

    class LOG{
        protected $primaryid;
        protected $tbid;
        protected $tbname;
        protected $keys;
        protected $values;
        /**
         * 参数说明
         * int              $tbid       查询指定表的id
         * string           $tbname     数据库表名
         */
        public function insert($tbid, $tbname){
            global $db;
            //查询表注释
            $db->query('show table status where name = "'.$tbname.'"');
            $tb = $db->fetch();
            //插入日志主表
            $returnid = $db->insert(0, 2, 'tb_log', array(
                'adminid = '.$_SESSION['admin']['id'],
                'type = 1',
                'tableid = '.$tbid,
                'tablename = "'.$tbname.'"',
                'comment = "'.$tb['Comment'].'"',
                'dt = now()'
            ));
            //查询字段注释
            $db->query('show full columns from '.$tbname);
            $tb = $db->fetchAll();
            foreach($tb as $v){
                $commentArray[$v['Field']] = $v['Comment'];
            }
            //查询所有字段信息,插入日志从表
            $rs = $db->select(0, 1, $tbname, '*', 'and tbid = '.$tbid);
            $keys = array_keys($rs);
            $values = array_values($rs);
            for($i = 0; $i < count($keys); $i++){
                $db->insert(0, 0, 'tb_log_content', array(
                    'logid = '.$returnid,
                    'tbkey = "'.$keys[$i].'"',
                    'tbvalue = "'.$values[$i].'"',
                    'comment = "'.$commentArray[$keys[$i]].'"'
                ));
            }
        }
        public function updateStart($tbid, $tbname){
            global $db;
            //查询表注释
            $db->query('show table status where name = "'.$tbname.'"');
            $tb = $db->fetch();
            //插入日志主表
            $returnid = $db->insert(0, 2, 'tb_log', array(
                'adminid = '.$_SESSION['admin']['id'],
                'type = 2',
                'tableid = '.$tbid,
                'tablename = "'.$tbname.'"',
                'comment = "'.$tb['Comment'].'"',
                'dt = now()'
            ));
            //查询修改前数据信息
            $rs = $db->select(0, 1, $tbname, '*', 'and tbid = '.$tbid);
            $keys = array_keys($rs);
            $values = array_values($rs);
            $this->primaryid = $returnid;
            $this->tbid = $tbid;
            $this->tbname = $tbname;
            $this->keys = $keys;
            $this->values = $values;
        }
        public function updateEnd(){
            global $db;
            //查询字段注释
            $db->query('show full columns from '.$this->tbname);
            $tb = $db->fetchAll();
            foreach($tb as $v){
                $commentArray[$v['Field']] = $v['Comment'];
            }
            //查询修改后数据信息
            $rs = $db->select(0, 1, $this->tbname, '*', 'and tbid = '.$this->tbid);
            $currentvalues = array_values($rs);
            //前后信息进行比较
            for($i = 0; $i < count($currentvalues); $i++){
                if($this->values[$i] !== $currentvalues[$i]){
                    $db->insert(0, 0, 'tb_log_content', array(
                        'logid = '.$this->primaryid,
                        'tbkey = "'.$this->keys[$i].'"',
                        'tbvalue = "'.$this->values[$i].'"',
                        'currenttbvalue = "'.$currentvalues[$i].'"',
                        'comment = "'.$commentArray[$this->keys[$i]].'"'
                    ));
                }
            }
        }
        public function delete($tbid, $tbname){
            global $db;
            //查询表注释
            $db->query('show table status where name = "'.$tbname.'"');
            $tb = $db->fetch();
            //插入日志主表
            $returnid = $db->insert(0, 2, 'tb_log', array(
                'adminid = '.$_SESSION['admin']['id'],
                'type = 3',
                'tableid = '.$tbid,
                'tablename = "'.$tbname.'"',
                'comment = "'.$tb['Comment'].'"',
                'dt = now()'
            ));
            //查询字段注释
            $db->query('show full columns from '.$tbname);
            $tb = $db->fetchAll();
            foreach($tb as $v){
                $commentArray[$v['Field']] = $v['Comment'];
            }
            //查询所有字段信息,插入日志从表
            $rs = $db->select(0, 1, $tbname, '*', 'and tbid = '.$tbid);
            $keys = array_keys($rs);
            $values = array_values($rs);
            for($i = 0; $i < count($keys); $i++){
                $db->insert(0, 0, 'tb_log_content', array(
                    'logid = '.$returnid,
                    'tbkey = "'.$keys[$i].'"',
                    'tbvalue = "'.$values[$i].'"',
                    'comment = "'.$commentArray[$keys[$i]].'"'
                ));
            }
        }
    }
    

      

    使用前,需要引入数据库操作类,这是我之前写的一份,可参考《全新的PDO数据库操作类(仅适用Mysql)》。

      引入之后,就可以开始使用了。

      select

    1
    $log->insert(82, 'tb_member');

      update

    1
    2
    3
    $log->updateStart(82, 'tb_member');
    //中间放更新操作代码
    $log->updateEnd();

      delete

    1
    $log->delete(82, 'tb_member');

      可以看到,一共只需要两个参数即可,分别是表ID(主键)和表名称。

      另外需要强调一点,表注释和字段注释一定要完整,因为记录的信息包含注释,目的就是为了查阅的时候能清楚哪个字段是干什么用的。

      下面就看下成品吧

      最后把表结构分享下,一共2张表,一张主表一张从表,主表记录操作表及操作人等信息,从表记录操作的表字段信息。

    -- ----------------------------
    -- Table structure for `tb_log`
    -- ----------------------------
    CREATE TABLE `tb_log` (
      `tbid` bigint(20) NOT NULL AUTO_INCREMENT,
      `adminid` bigint(20) DEFAULT NULL COMMENT '管理员id',
      `type` tinyint(4) DEFAULT '1' COMMENT '操作类型:1新增2修改3删除',
      `tableid` bigint(20) DEFAULT NULL,
      `tablename` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '表名',
      `comment` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
      `dt` datetime DEFAULT NULL,
      PRIMARY KEY (`tbid`)
    ) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
     
    -- ----------------------------
    -- Table structure for `tb_log_content`
    -- ----------------------------
    CREATE TABLE `tb_log_content` (
      `tbid` bigint(20) NOT NULL AUTO_INCREMENT,
      `logid` bigint(20) DEFAULT NULL,
      `tbkey` longtext COLLATE utf8_unicode_ci,
      `tbvalue` longtext COLLATE utf8_unicode_ci,
      `currenttbvalue` longtext COLLATE utf8_unicode_ci,
      `comment` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
      PRIMARY KEY (`tbid`)
    ) ENGINE=InnoDB AUTO_INCREMENT=109 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
    

      

  • 相关阅读:
    virtualbox结合nat和host-only设置固定ip的环境
    [zebra源码]流控设计
    [zebra源码]JdbcFilter过滤器和SPI扩展
    [zebra源码]如果数据库连接建立失败会怎样
    [zebra源码]insert后获取自增值的处理
    [zebra源码]GroupDataSource读库的负载均衡
    [zebra源码]不带分片键的sql会怎么执行?
    [zebra源码]如果定位到多个分库或分表怎么执行的?
    自定义类型hash
    spark on dataworks
  • 原文地址:https://www.cnblogs.com/freespider/p/9183320.html
Copyright © 2011-2022 走看看