You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
219 lines
6.6 KiB
219 lines
6.6 KiB
<?php
|
|
/**
|
|
* Created by 花密欧团队.
|
|
* User: 云掌.帮德
|
|
* Date: 2020/3/8 22:30
|
|
* Desc: 行为日志类
|
|
*/
|
|
|
|
namespace service;
|
|
|
|
use think\facade\Db;
|
|
|
|
class ActionLog
|
|
{
|
|
|
|
/**
|
|
* 系统日志表
|
|
* @var string
|
|
*/
|
|
private $table = 'system_action_log';
|
|
|
|
/**
|
|
* 系统用户表
|
|
* @var string
|
|
*/
|
|
private $table_manager = 'system_user';
|
|
|
|
/**
|
|
* 禁止写入日志的控制器名称
|
|
* @var array
|
|
*/
|
|
private $_controller = [];
|
|
|
|
/**
|
|
* 修改后数据
|
|
* @var array
|
|
*/
|
|
private $_data = [];
|
|
|
|
/**
|
|
* 修改前数据
|
|
* @var array
|
|
*/
|
|
private $_origin = [];
|
|
|
|
/**
|
|
* 系统管理员信息
|
|
* @var string
|
|
*/
|
|
private $sys_manager = '';
|
|
|
|
private static $instance = null;
|
|
|
|
private function __construct()
|
|
{
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* 禁止克隆
|
|
*/
|
|
private function __clone()
|
|
{
|
|
// TODO: Implement __clone() method.
|
|
}
|
|
|
|
/**
|
|
* 返回单例对象
|
|
* @return JwtAuth|null
|
|
*/
|
|
public static function getInstance()
|
|
{
|
|
if (!self::$instance instanceof self) {
|
|
self::$instance = new self();
|
|
}
|
|
return self::$instance;
|
|
}
|
|
|
|
/**
|
|
* @param array $_data 创建或者修改的最新数据
|
|
* @param array $_origin 修改或删除前的源数据
|
|
* @param string $_sql 数据sql
|
|
* @return bool
|
|
*/
|
|
public function write(array $_data = [], array $_origin = [], string $_sql = ''): bool
|
|
{
|
|
if (in_array(\request()->controller(), $this->_controller)) {
|
|
return false;
|
|
}
|
|
|
|
$_param = request()->param();
|
|
$this->_data = array_merge($_data, $_param);
|
|
$this->_origin = $_origin;
|
|
$this->sys_manager = $this->getSysManager();
|
|
//增加日志记录
|
|
$data = [
|
|
'site_id' => defined('SITE_ID') ? SITE_ID : $this->_data['site_id'] ?? 0,
|
|
'user_id' => defined('UID') ? UID : $this->_data['user_id'] ?? 0,
|
|
'username' => $this->sys_manager['username'] ?? '',
|
|
'action_ip' => ip2long(request()->ip()),
|
|
'request_method' => request()->method(),
|
|
'request_param' => json_encode($_param),
|
|
'model' => request()->baseUrl(),
|
|
'url' => request()->host() . request()->url(),
|
|
'spend_time' => round(microtime(true) - request()->time(), 4),
|
|
'record_id' => $_data['id'] ?? $_param['id'] ?? 0, //数据表id
|
|
'remark' => $this->replaceLog(), //admin在2018年12月23 17:20:48复制了栏目。权限节点cloud/column/copy,记录编号1。
|
|
'data' => json_encode($_data),
|
|
'origin' => json_encode($_origin),
|
|
'sql' => $_sql,
|
|
'client_browser' => get_client_browser(),
|
|
'client_os' => get_client_os(),
|
|
'client_device' => request()->header('client-device') ?? get_client_os(),
|
|
'update_time' => time(),
|
|
'create_time' => time(),
|
|
];
|
|
return Db::table($this->table)->insert($data);
|
|
}
|
|
|
|
/**
|
|
* 写入日志数据
|
|
* @return string|string[]|void
|
|
* @throws \ReflectionException
|
|
*/
|
|
private function replaceLog()
|
|
{
|
|
//通过注解获取以下信息数据再解析
|
|
// @Log [sys_name]在[sys_time]创建了管理员:[username]
|
|
// @Log [sys_name]在[sys_time]修改了[origin_username]管理员账号为[username]
|
|
|
|
//解析数据
|
|
$annot = $this->getAnnotations();
|
|
if (!$annot) {
|
|
return '未检测到日志信息模型,请检查CURR_THIS反射常量!!!';
|
|
}
|
|
preg_match_all('/\[(\S+?)\]/', $annot, $match);
|
|
list($find, $replace) = $match;
|
|
foreach ($replace as $k => $v) {
|
|
switch ($v) {
|
|
case 'sys_name':
|
|
$replace[$k] = $this->sys_manager['username'] ?? '';
|
|
break;
|
|
case 'sys_time':
|
|
$replace[$k] = date('Y-m-d H:i:s');
|
|
break;
|
|
default:
|
|
if (strpos($v, 'origin_') === 0) {
|
|
//判断是否含有源数据的字段标识 origin_
|
|
$replace[$k] = $this->_origin[str_replace('origin_', '', $v)];
|
|
} elseif (strpos($v, 'dictionary_') === 0) {
|
|
//判断是否含有数据字典的标识 dictionary_
|
|
$filter_name = str_replace('dictionary_', '', $v);
|
|
//如果字典有值就替换 否则保持原数据
|
|
$replace[$k] = $this->getDictionary($filter_name)[$this->_data[$filter_name]] ?? $this->_data[$filter_name];
|
|
} else {
|
|
//默认返回原数据值
|
|
$replace[$k] = $this->_data[$v] ?? '{变量未知}';
|
|
}
|
|
}
|
|
}
|
|
$annot = str_replace($find, $replace, $annot);
|
|
return $annot;
|
|
}
|
|
|
|
/**
|
|
* 通过反射类获取PHP类的注释
|
|
* @return string|void
|
|
* @throws \ReflectionException
|
|
*/
|
|
private function getAnnotations()
|
|
{
|
|
if (!defined('CURR_THIS')) {
|
|
return;
|
|
}
|
|
$class = new \ReflectionClass(CURR_THIS);
|
|
$docComment = $class->getMethod(request()->action())->getDocComment();
|
|
return get_doc_comment($docComment, 'Log');
|
|
// return '[sys_name]在[sys_time]创建了管理员账号:[username]';
|
|
// return '[sys_name]在[sys_time]修改了[origin_username]管理员账号为:[username]'; //指定字段后的修改变化
|
|
// return '[sys_name]在[sys_time]删除了管理员账号:[username]';
|
|
// return '[sys_name]在[sys_time]:更改了管理员状态为:[dictionary_status]';
|
|
}
|
|
|
|
/**
|
|
* 获取系统管理员用户信息
|
|
* @param string $field
|
|
* @return array|\think\Model|null
|
|
* @throws \think\db\exception\DataNotFoundException
|
|
* @throws \think\db\exception\DbException
|
|
* @throws \think\db\exception\ModelNotFoundException
|
|
*/
|
|
private function getSysManager($field = '')
|
|
{
|
|
$_db = Db::table($this->table_manager);
|
|
if ($field) {
|
|
return $_db->value($field);
|
|
}
|
|
$user_id = defined('UID') ? UID : $this->_data['user_id'] ?? 0;
|
|
if (empty($user_id)) {
|
|
return;
|
|
}
|
|
return $_db->find($user_id);
|
|
}
|
|
|
|
/**
|
|
* 获取数据库字典数据
|
|
* @param string $field
|
|
*/
|
|
private function getDictionary($field = '')
|
|
{
|
|
if ($field) {
|
|
return config('dictionary.sqlfields.' . $field);
|
|
}
|
|
return config('dictionary.sqlfields');
|
|
}
|
|
|
|
|
|
}
|