feat:数据回收功能实现

This commit is contained in:
妙码生花 2022-04-03 16:27:00 +08:00
parent d78cebf5c3
commit 8dc6e2ef2b
8 changed files with 246 additions and 12 deletions

View File

@ -43,8 +43,9 @@ abstract class BaseController
*/
public function __construct(App $app)
{
$this->app = $app;
$this->request = $this->app->request;
$this->app = $app;
$this->request = $this->app->request;
$this->request->controllerPath = str_replace('.', '/', $this->request->controller(true));
// 控制器初始化
$this->initialize();

View File

@ -4,7 +4,10 @@ namespace app\admin\controller\security;
use app\common\controller\Backend;
use app\admin\model\DataRecycle as DataRecycleModel;
use think\db\exception\PDOException;
use think\exception\ValidateException;
use think\facade\Db;
use Exception;
class DataRecycle extends Backend
{
@ -27,7 +30,44 @@ class DataRecycle extends Backend
public function add()
{
if ($this->request->isPost()) {
parent::add();
$data = $this->request->post();
if (!$data) {
$this->error(__('Parameter %s can not be empty', ['']));
}
$data = $this->excludeFields($data);
$data['controller_as'] = str_ireplace('.php', '', $data['controller'] ?? '');
$data['controller_as'] = strtolower(str_ireplace(['\\', '.'], '/', $data['controller_as']));
$result = false;
Db::startTrans();
try {
// 模型验证
if ($this->modelValidate) {
$validate = str_replace("\\model\\", "\\validate\\", get_class($this->model));
if (class_exists($validate)) {
$validate = new $validate;
if ($this->modelSceneValidate) $validate->scene('add');
$validate->check($data);
}
}
$result = $this->model->save($data);
Db::commit();
} catch (ValidateException $e) {
Db::rollback();
$this->error($e->getMessage());
} catch (PDOException $e) {
Db::rollback();
$this->error($e->getMessage());
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($result !== false) {
$this->success(__('Added successfully'));
} else {
$this->error(__('No rows were added'));
}
}
// 放在add方法内就不需要额外添加权限节点了
@ -37,6 +77,63 @@ class DataRecycle extends Backend
]);
}
/**
* 编辑
* @param null $id
*/
public function edit($id = null)
{
$row = $this->model->find($id);
if (!$row) {
$this->error(__('Record not found'));
}
if ($this->request->isPost()) {
$data = $this->request->post();
if (!$data) {
$this->error(__('Parameter %s can not be empty', ['']));
}
$data = $this->excludeFields($data);
$data['controller_as'] = str_ireplace('.php', '', $data['controller'] ?? '');
$data['controller_as'] = strtolower(str_ireplace(['\\', '.'], '/', $data['controller_as']));
$result = false;
Db::startTrans();
try {
// 模型验证
if ($this->modelValidate) {
$validate = str_replace("\\model\\", "\\validate\\", get_class($this->model));
if (class_exists($validate)) {
$validate = new $validate;
if ($this->modelSceneValidate) $validate->scene('edit');
$validate->check($data);
}
}
$result = $row->save($data);
Db::commit();
} catch (ValidateException $e) {
Db::rollback();
$this->error($e->getMessage());
} catch (PDOException $e) {
Db::rollback();
$this->error($e->getMessage());
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($result !== false) {
$this->success(__('Update successful'));
} else {
$this->error(__('No rows updated'));
}
}
$this->success('', [
'row' => $row
]);
}
protected function getControllerList()
{
$outExcludeController = [

16
app/admin/event.php Normal file
View File

@ -0,0 +1,16 @@
<?php
// 事件定义文件
return [
'bind' => [
],
'listen' => [
'AppInit' => [],
'HttpRun' => [],
'HttpEnd' => [],
'LogLevel' => [],
'LogWrite' => [],
'backendInit' => [app\common\event\Security::class],
],
'subscribe' => [
],
];

View File

@ -0,0 +1,7 @@
<?php
return [
'Name' => '规则名称',
'Controller' => '控制器',
'Data Table' => '对应数据表',
'Primary Key' => '数据表主键',
];

View File

@ -0,0 +1,48 @@
<?php
namespace app\admin\validate;
use think\Validate;
class DataRecycle extends Validate
{
protected $failException = true;
protected $rule = [
'name' => 'require',
'controller' => 'require|unique:security_data_recycle',
'data_table' => 'require',
'primary_key' => 'require',
];
/**
* 验证提示信息
* @var array
*/
protected $message = [];
/**
* 字段描述
*/
protected $field = [
];
/**
* 验证场景
*/
protected $scene = [
'add' => ['name', 'controller', 'data_table', 'primary_key'],
'edit' => ['name', 'controller', 'data_table', 'primary_key'],
];
public function __construct()
{
$this->field = [
'name' => __('Name'),
'controller' => __('Controller'),
'data_table' => __('Data Table'),
'primary_key' => __('Primary Key'),
];
parent::__construct();
}
}

View File

@ -19,11 +19,6 @@ class Api extends BaseController
*/
protected $responseType = 'json';
/**
* 控制器目录路径
*/
protected $controllerPath;
public function __construct(App $app)
{
parent::__construct($app);
@ -38,10 +33,9 @@ class Api extends BaseController
$this->request->filter('trim,strip_tags,htmlspecialchars');
// 加载控制器语言包
$langset = $this->app->lang->getLangSet();
$this->controllerPath = str_replace('.', '/', $this->request->controller(true));
$langset = $this->app->lang->getLangSet();
$this->app->lang->load([
app_path() . 'lang' . DIRECTORY_SEPARATOR . $langset . DIRECTORY_SEPARATOR . (str_replace('/', DIRECTORY_SEPARATOR, $this->controllerPath)) . '.php'
app_path() . 'lang' . DIRECTORY_SEPARATOR . $langset . DIRECTORY_SEPARATOR . (str_replace('/', DIRECTORY_SEPARATOR, $this->app->request->controllerPath)) . '.php'
]);
}

View File

@ -7,6 +7,7 @@ use think\db\exception\PDOException;
use think\facade\Config;
use think\facade\Cookie;
use think\facade\Db;
use think\facade\Event;
class Backend extends Api
{
@ -77,7 +78,7 @@ class Backend extends Api
}
$this->auth = Auth::instance();
$routePath = $this->controllerPath . '/' . $this->request->action(true);
$routePath = $this->app->request->controllerPath . '/' . $this->request->action(true);
$token = $this->request->server('HTTP_BATOKEN', $this->request->request('batoken', Cookie::get('batoken') ?: false));
if (!$this->auth->actionInArr($this->noNeedLogin)) {
$this->auth->init($token);
@ -98,6 +99,9 @@ class Backend extends Api
$this->auth->init($token);
}
}
// 管理员验权和登录标签位
Event::trigger('backendInit');
}
public function queryBuilder()

View File

@ -0,0 +1,67 @@
<?php
namespace app\common\event;
use Exception;
use think\Request;
use think\facade\Db;
use think\facade\Log;
use app\admin\library\Auth;
use think\db\exception\PDOException;
class Security
{
protected $listenAction = ['edit', 'del'];
public function handle(Request $request)
{
$action = $request->action(true);
if (!in_array($action, $this->listenAction) || (!$request->isPost() && !$request->isDelete())) {
return true;
}
if ($action == 'del') {
$dataIds = $request->param('ids');
try {
$recycle = \app\admin\model\DataRecycle::where('status', '1')
->where('controller_as', $request->controllerPath)
->find();
if (!$recycle) {
return true;
}
$recycleData = Db::table($recycle['data_table'])
->whereIn($recycle['primary_key'], $dataIds)
->select()->toArray();
$recycleDataArr = [];
$auth = Auth::instance();
$adminId = $auth->isLogin() ? $auth->id : 123;
foreach ($recycleData as $recycleDatum) {
$recycleDataArr[] = [
'admin_id' => $adminId,
'recycle_id' => $recycle['id'],
'data' => json_encode($recycleDatum),
'ip' => $request->ip(),
'useragent' => substr($request->server('HTTP_USER_AGENT'), 0, 255),
];
}
if (!$recycleDataArr) {
return true;
}
} catch (PDOException $e) {
Log::record('[ DataSecurity ]' . var_export($e, true), 'warning');
} catch (Exception $e) {
Log::record('[ DataSecurity ]' . var_export($e, true), 'warning');
}
// saveAll 方法自带事务
$dataRecycleLogModel = new \app\admin\model\DataRecycleLog;
if ($dataRecycleLogModel->saveAll($recycleDataArr) === false) {
Log::record('[ DataSecurity ] Failed to recycle data:' . var_export($recycleDataArr, true), 'warning');
}
return true;
}
return true;
}
}