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

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

      update

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

      delete

    $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;
  • 相关阅读:
    (Java实现) 洛谷 P1603 斯诺登的密码
    (Java实现) 洛谷 P1036 选数
    (Java实现) 洛谷 P1036 选数
    (Java实现) 洛谷 P1012 拼数
    (Java实现) 洛谷 P1012 拼数
    (Java实现) 洛谷 P1028 数的计算
    (Java实现) 洛谷 P1028 数的计算
    (Java实现) 洛谷 P1553 数字反转(升级版)
    8.4 确定两个日期之间的月份数或年数
    (Java实现) 洛谷 P1553 数字反转(升级版)
  • 原文地址:https://www.cnblogs.com/hooray/p/2672133.html
Copyright © 2011-2022 走看看