1
This commit is contained in:
179
app/admin/controller/system/Admin.php
Normal file
179
app/admin/controller/system/Admin.php
Normal file
@ -0,0 +1,179 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\system;
|
||||
|
||||
use app\admin\model\SystemAdmin;
|
||||
use app\admin\service\TriggerService;
|
||||
use app\common\constants\AdminConstant;
|
||||
use app\common\controller\AdminController;
|
||||
use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\Request;
|
||||
use think\App;
|
||||
use think\response\Json;
|
||||
|
||||
#[ControllerAnnotation(title: '管理员管理')]
|
||||
class Admin extends AdminController
|
||||
{
|
||||
|
||||
protected array $sort = [
|
||||
'sort' => 'desc',
|
||||
'id' => 'desc',
|
||||
];
|
||||
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
self::$model = SystemAdmin::class;
|
||||
$this->assign('auth_list', self::$model::getAuthList());
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
public function index(Request $request): Json|string
|
||||
{
|
||||
if ($request->isAjax()) {
|
||||
if (input('selectFields')) {
|
||||
return $this->selectList();
|
||||
}
|
||||
list($page, $limit, $where) = $this->buildTableParams();
|
||||
$count = self::$model::where($where)->count();
|
||||
$list = self::$model::withoutField('password')
|
||||
->where($where)
|
||||
->page($page, $limit)
|
||||
->order($this->sort)
|
||||
->select()->toArray();
|
||||
$data = [
|
||||
'code' => 0,
|
||||
'msg' => '',
|
||||
'count' => $count,
|
||||
'data' => $list,
|
||||
];
|
||||
return json($data);
|
||||
}
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '添加', auth: true)]
|
||||
public function add(Request $request): string
|
||||
{
|
||||
if ($request->isPost()) {
|
||||
$post = $request->post();
|
||||
$authIds = $request->post('auth_ids', []);
|
||||
$post['auth_ids'] = implode(',', array_keys($authIds));
|
||||
$rule = [];
|
||||
$this->validate($post, $rule);
|
||||
if (empty($post['password'])) $post['password'] = '123456';
|
||||
$post['password'] = password_hash($post['password'],PASSWORD_DEFAULT);
|
||||
try {
|
||||
$save = self::$model::create($post);
|
||||
}catch (\Exception $e) {
|
||||
$this->error('保存失败' . $e->getMessage());
|
||||
}
|
||||
$save ? $this->success('保存成功') : $this->error('保存失败');
|
||||
}
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '编辑', auth: true)]
|
||||
public function edit(Request $request, $id = 0): string
|
||||
{
|
||||
$row = self::$model::find($id);
|
||||
empty($row) && $this->error('数据不存在');
|
||||
if ($request->isPost()) {
|
||||
$post = $request->post();
|
||||
$authIds = $request->post('auth_ids', []);
|
||||
$post['auth_ids'] = implode(',', array_keys($authIds));
|
||||
$rule = [];
|
||||
$this->validate($post, $rule);
|
||||
try {
|
||||
$save = $row->save($post);
|
||||
TriggerService::updateMenu($id);
|
||||
}catch (\Exception $e) {
|
||||
$this->error('保存失败' . $e->getMessage());
|
||||
}
|
||||
$save ? $this->success('保存成功') : $this->error('保存失败');
|
||||
}
|
||||
$this->assign('row', $row);
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '设置密码', auth: true)]
|
||||
public function password(Request $request, $id): string
|
||||
{
|
||||
$row = self::$model::find($id);
|
||||
empty($row) && $this->error('数据不存在');
|
||||
if ($request->isAjax()) {
|
||||
$post = $request->post();
|
||||
$rule = [
|
||||
'password|登录密码' => 'require',
|
||||
'password_again|确认密码' => 'require',
|
||||
];
|
||||
$this->validate($post, $rule);
|
||||
if ($post['password'] != $post['password_again']) {
|
||||
$this->error('两次密码输入不一致');
|
||||
}
|
||||
try {
|
||||
$save = $row->save([
|
||||
'password' => password_hash($post['password'],PASSWORD_DEFAULT),
|
||||
]);
|
||||
}catch (\Exception $e) {
|
||||
$this->error('保存失败');
|
||||
}
|
||||
$save ? $this->success('保存成功') : $this->error('保存失败');
|
||||
}
|
||||
$this->assign('row', $row);
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '删除', auth: true)]
|
||||
public function delete(Request $request): void
|
||||
{
|
||||
$this->checkPostRequest();
|
||||
$id = $request->param('id');
|
||||
$row = self::$model::whereIn('id', $id)->select();
|
||||
$row->isEmpty() && $this->error('数据不存在');
|
||||
$id == AdminConstant::SUPER_ADMIN_ID && $this->error('超级管理员不允许修改');
|
||||
if (is_array($id)) {
|
||||
if (in_array(AdminConstant::SUPER_ADMIN_ID, $id)) {
|
||||
$this->error('超级管理员不允许修改');
|
||||
}
|
||||
}
|
||||
try {
|
||||
$save = $row->delete();
|
||||
}catch (\Exception $e) {
|
||||
$this->error('删除失败');
|
||||
}
|
||||
$save ? $this->success('删除成功') : $this->error('删除失败');
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '属性修改', auth: true)]
|
||||
public function modify(Request $request): void
|
||||
{
|
||||
$this->checkPostRequest();
|
||||
$post = $request->post();
|
||||
$rule = [
|
||||
'id|ID' => 'require',
|
||||
'field|字段' => 'require',
|
||||
'value|值' => 'require',
|
||||
];
|
||||
$this->validate($post, $rule);
|
||||
if (!in_array($post['field'], $this->allowModifyFields)) {
|
||||
$this->error('该字段不允许修改:' . $post['field']);
|
||||
}
|
||||
if ($post['id'] == AdminConstant::SUPER_ADMIN_ID && $post['field'] == 'status') {
|
||||
$this->error('超级管理员状态不允许修改');
|
||||
}
|
||||
$row = self::$model::find($post['id']);
|
||||
empty($row) && $this->error('数据不存在');
|
||||
try {
|
||||
$row->save([
|
||||
$post['field'] => $post['value'],
|
||||
]);
|
||||
}catch (\Exception $e) {
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
$this->success('保存成功');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
71
app/admin/controller/system/Auth.php
Normal file
71
app/admin/controller/system/Auth.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\system;
|
||||
|
||||
use app\admin\model\SystemAuth;
|
||||
use app\admin\model\SystemAuthNode;
|
||||
use app\admin\service\TriggerService;
|
||||
use app\common\controller\AdminController;
|
||||
use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\Request;
|
||||
use think\App;
|
||||
|
||||
#[ControllerAnnotation(title: '角色权限管理', auth: true)]
|
||||
class Auth extends AdminController
|
||||
{
|
||||
|
||||
protected array $sort = [
|
||||
'sort' => 'desc',
|
||||
'id' => 'desc',
|
||||
];
|
||||
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
self::$model = SystemAuth::class;
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '授权', auth: true)]
|
||||
public function authorize(Request $request, $id): string
|
||||
{
|
||||
$row = self::$model::find($id);
|
||||
empty($row) && $this->error('数据不存在');
|
||||
if ($request->isAjax()) {
|
||||
$list = self::$model::getAuthorizeNodeListByAdminId($id);
|
||||
$this->success('获取成功', $list);
|
||||
}
|
||||
$this->assign('row', $row);
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '授权保存', auth: true)]
|
||||
public function saveAuthorize(Request $request): void
|
||||
{
|
||||
$this->checkPostRequest();
|
||||
$id = $request->post('id');
|
||||
$node = $request->post('node', "[]");
|
||||
$node = json_decode($node, true);
|
||||
$row = self::$model::find($id);
|
||||
empty($row) && $this->error('数据不存在');
|
||||
try {
|
||||
$authNode = new SystemAuthNode();
|
||||
$authNode->where('auth_id', $id)->delete();
|
||||
if (!empty($node)) {
|
||||
$saveAll = [];
|
||||
foreach ($node as $vo) {
|
||||
$saveAll[] = [
|
||||
'auth_id' => $id,
|
||||
'node_id' => $vo,
|
||||
];
|
||||
}
|
||||
$authNode->saveAll($saveAll);
|
||||
}
|
||||
TriggerService::updateMenu();
|
||||
}catch (\Exception $e) {
|
||||
$this->error('保存失败');
|
||||
}
|
||||
$this->success('保存成功');
|
||||
}
|
||||
|
||||
}
|
||||
70
app/admin/controller/system/Config.php
Normal file
70
app/admin/controller/system/Config.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\system;
|
||||
|
||||
use app\admin\model\SystemConfig;
|
||||
use app\admin\service\TriggerService;
|
||||
use app\common\controller\AdminController;
|
||||
use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\Request;
|
||||
use think\App;
|
||||
use think\facade\Cache;
|
||||
use think\response\Json;
|
||||
|
||||
#[ControllerAnnotation(title: '系统配置管理')]
|
||||
class Config extends AdminController
|
||||
{
|
||||
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
self::$model = SystemConfig::class;
|
||||
$this->assign('upload_types', config('admin.upload_types'));
|
||||
$this->assign('editor_types', config('admin.editor_types'));
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
public function index(Request $request): Json|string
|
||||
{
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '保存', auth: true)]
|
||||
public function save(Request $request): void
|
||||
{
|
||||
$this->checkPostRequest();
|
||||
$post = $request->post();
|
||||
$notAddFields = ['_token', 'file', 'group'];
|
||||
try {
|
||||
$group = $post['group'] ?? '';
|
||||
if (empty($group)) $this->error('保存失败');
|
||||
if ($group == 'upload') {
|
||||
$upload_types = config('admin.upload_types');
|
||||
// 兼容旧版本
|
||||
self::$model::where('name', 'upload_allow_type')->update(['value' => implode(',', array_keys($upload_types))]);
|
||||
}
|
||||
foreach ($post as $key => $val) {
|
||||
if (in_array($key, $notAddFields)) continue;
|
||||
$config_key_data = self::$model::where('name', $key)->find();
|
||||
if (!is_null($config_key_data)) {
|
||||
$config_key_data->save(['value' => $val,]);
|
||||
}else {
|
||||
self::$model::create(
|
||||
[
|
||||
'name' => $key,
|
||||
'value' => $val,
|
||||
'group' => $group,
|
||||
]);
|
||||
}
|
||||
if (Cache::has($key)) Cache::set($key, $val);
|
||||
}
|
||||
TriggerService::updateMenu();
|
||||
TriggerService::updateSysConfig();
|
||||
}catch (\Exception $e) {
|
||||
$this->error('保存失败' . $e->getMessage());
|
||||
}
|
||||
$this->success('保存成功');
|
||||
}
|
||||
|
||||
}
|
||||
155
app/admin/controller/system/CurdGenerate.php
Normal file
155
app/admin/controller/system/CurdGenerate.php
Normal file
@ -0,0 +1,155 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\system;
|
||||
|
||||
use app\admin\service\curd\BuildCurd;
|
||||
use app\common\controller\AdminController;
|
||||
use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\Request;
|
||||
use think\db\exception\PDOException;
|
||||
use think\exception\FileException;
|
||||
use think\facade\Console;
|
||||
use think\facade\Db;
|
||||
use think\helper\Str;
|
||||
use think\response\Json;
|
||||
|
||||
#[ControllerAnnotation(title: 'CURD可视化管理')]
|
||||
class CurdGenerate extends AdminController
|
||||
{
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
public function index(Request $request): Json|string
|
||||
{
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '操作', auth: true)]
|
||||
public function save(Request $request, string $type = ''): ?Json
|
||||
{
|
||||
if (!$request->isAjax()) $this->error();
|
||||
switch ($type) {
|
||||
case "search":
|
||||
$tb_prefix = $request->param('tb_prefix/s', '');
|
||||
$tb_name = $request->param('tb_name/s', '');
|
||||
if (empty($tb_name)) $this->error('参数错误');
|
||||
|
||||
try {
|
||||
$list = Db::query("SHOW FULL COLUMNS FROM {$tb_prefix}{$tb_name}");
|
||||
$data = [];
|
||||
foreach ($list as $value) {
|
||||
$data[] = [
|
||||
'name' => $value['Field'],
|
||||
'type' => $value['Type'],
|
||||
'key' => $value['Key'],
|
||||
'extra' => $value['Extra'],
|
||||
'null' => $value['Null'],
|
||||
'desc' => $value['Comment'],
|
||||
];
|
||||
}
|
||||
$this->success('查询成功', compact('data', 'list'));
|
||||
}catch (PDOException $exception) {
|
||||
$this->error($exception->getMessage());
|
||||
}
|
||||
break;
|
||||
case "add":
|
||||
$tb_prefix = $request->param('tb_prefix/s', '');
|
||||
$tb_name = $request->param('tb_name/s', '');
|
||||
if (empty($tb_name)) $this->error('参数错误');
|
||||
|
||||
$tb_fields = $request->param('tb_fields');
|
||||
$force = $request->post('force/d', 0);
|
||||
try {
|
||||
$build = (new BuildCurd())->setTablePrefix($tb_prefix)->setTable($tb_name);
|
||||
$build->setForce($force); // 强制覆盖
|
||||
// 新增字段类型
|
||||
if ($tb_fields) {
|
||||
foreach ($tb_fields as $tk => $tf) {
|
||||
if (empty($tf)) continue;
|
||||
$tf = array_values($tf);
|
||||
switch ($tk) {
|
||||
case 'ignore':
|
||||
$build->setIgnoreFields($tf, true);
|
||||
break;
|
||||
case 'select':
|
||||
$build->setSelectFields($tf, true);
|
||||
break;
|
||||
case 'radio':
|
||||
$build->setRadioFieldSuffix($tf, true);
|
||||
break;
|
||||
case 'checkbox':
|
||||
$build->setCheckboxFieldSuffix($tf, true);
|
||||
break;
|
||||
case 'image':
|
||||
$build->setImageFieldSuffix($tf, true);
|
||||
break;
|
||||
case 'images':
|
||||
$build->setImagesFieldSuffix($tf, true);
|
||||
break;
|
||||
case 'date':
|
||||
$build->setDateFieldSuffix($tf, true);
|
||||
break;
|
||||
case 'datetime':
|
||||
$build->setDatetimeFieldSuffix($tf, true);
|
||||
break;
|
||||
case 'editor':
|
||||
$build->setEditorFields($tf, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$build = $build->render();
|
||||
$fileList = $build->getFileList();
|
||||
if (empty($fileList)) $this->error('这里什么都没有');
|
||||
$result = $build->create();
|
||||
$_file = $result[0] ?? '';
|
||||
$link = '';
|
||||
if (!empty($_file)) {
|
||||
$_fileExp = explode(DIRECTORY_SEPARATOR, $_file);
|
||||
$_fileExp_last = array_slice($_fileExp, -2);
|
||||
$_fileExp_last_0 = $_fileExp_last[0] . '.';
|
||||
if ($_fileExp_last[0] == 'controller') $_fileExp_last_0 = '';
|
||||
$link = '/' . config('admin.alias_name') . '/' . $_fileExp_last_0 . Str::snake(explode('.php', end($_fileExp_last))[0] ?? '') . '/index';
|
||||
}
|
||||
$this->success('生成成功', compact('result', 'link'));
|
||||
}catch (FileException $exception) {
|
||||
return json(['code' => -1, 'msg' => $exception->getMessage()]);
|
||||
}
|
||||
break;
|
||||
case "delete":
|
||||
$tb_prefix = $request->param('tb_prefix/s', '');
|
||||
$tb_name = $request->param('tb_name/s', '');
|
||||
if (empty($tb_name)) $this->error('参数错误');
|
||||
|
||||
try {
|
||||
$build = (new BuildCurd())->setTablePrefix($tb_prefix)->setTable($tb_name);
|
||||
$build = $build->render();
|
||||
$fileList = $build->getFileList();
|
||||
if (empty($fileList)) $this->error('这里什么都没有');
|
||||
$result = $build->delete();
|
||||
$this->success('删除自动生成CURD文件成功', compact('result'));
|
||||
}catch (FileException $exception) {
|
||||
return json(['code' => -1, 'msg' => $exception->getMessage()]);
|
||||
}
|
||||
break;
|
||||
case 'console':
|
||||
$command = $request->post('command', '');
|
||||
if (empty($command)) $this->error('请输入命令');
|
||||
$commandExp = explode(' ', $command);
|
||||
$commandExp = array_values(array_filter($commandExp));
|
||||
try {
|
||||
|
||||
$output = Console::call('curd', [...$commandExp]);
|
||||
}catch (\Throwable $exception) {
|
||||
$this->error($exception->getMessage() . $exception->getLine());
|
||||
}
|
||||
if (empty($output)) $this->error('设置错误');
|
||||
$this->success($output->fetch());
|
||||
break;
|
||||
default:
|
||||
$this->error('参数错误');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
138
app/admin/controller/system/Log.php
Normal file
138
app/admin/controller/system/Log.php
Normal file
@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\system;
|
||||
|
||||
use app\admin\model\SystemLog;
|
||||
use app\admin\service\annotation\MiddlewareAnnotation;
|
||||
use app\admin\service\tool\CommonTool;
|
||||
use app\common\controller\AdminController;
|
||||
use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\Request;
|
||||
use jianyan\excel\Excel;
|
||||
use think\App;
|
||||
use think\db\exception\DbException;
|
||||
use think\db\exception\PDOException;
|
||||
use think\facade\Db;
|
||||
use think\response\Json;
|
||||
|
||||
#[ControllerAnnotation(title: '操作日志管理')]
|
||||
class Log extends AdminController
|
||||
{
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
self::$model = SystemLog::class;
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
public function index(Request $request): Json|string
|
||||
{
|
||||
if ($request->isAjax()) {
|
||||
if (input('selectFields')) {
|
||||
return $this->selectList();
|
||||
}
|
||||
[$page, $limit, $where, $excludeFields] = $this->buildTableParams(['month']);
|
||||
$month = !empty($excludeFields['month']) ? date('Ym', strtotime($excludeFields['month'])) : date('Ym');
|
||||
$model = (new self::$model)->setSuffix("_$month")->with('admin')->where($where);
|
||||
try {
|
||||
$count = $model->count();
|
||||
$list = $model->page($page, $limit)->order($this->sort)->select();
|
||||
}catch (PDOException|DbException $exception) {
|
||||
$count = 0;
|
||||
$list = [];
|
||||
}
|
||||
$data = [
|
||||
'code' => 0,
|
||||
'msg' => '',
|
||||
'count' => $count,
|
||||
'data' => $list,
|
||||
];
|
||||
return json($data);
|
||||
}
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '导出', auth: true)]
|
||||
public function export()
|
||||
{
|
||||
if (env('EASYADMIN.IS_DEMO', false)) {
|
||||
$this->error('演示环境下不允许操作');
|
||||
}
|
||||
[$page, $limit, $where, $excludeFields] = $this->buildTableParams(['month']);
|
||||
$month = !empty($excludeFields['month']) ? date('Ym', strtotime($excludeFields['month'])) : date('Ym');
|
||||
$tableName = (new self::$model)->setSuffix("_$month")->getName();
|
||||
$tableName = CommonTool::humpToLine(lcfirst($tableName));
|
||||
$prefix = config('database.connections.mysql.prefix');
|
||||
$dbList = Db::query("show full columns from {$prefix}{$tableName}");
|
||||
$header = [];
|
||||
foreach ($dbList as $vo) {
|
||||
$comment = !empty($vo['Comment']) ? $vo['Comment'] : $vo['Field'];
|
||||
if (!in_array($vo['Field'], $this->noExportFields)) {
|
||||
$header[] = [$comment, $vo['Field']];
|
||||
}
|
||||
}
|
||||
$model = (new self::$model)->setSuffix("_$month")->with('admin')->where($where);
|
||||
try {
|
||||
$list = $model
|
||||
->limit(10000)
|
||||
->order('id', 'desc')
|
||||
->select()
|
||||
->toArray();
|
||||
foreach ($list as &$vo) {
|
||||
$vo['content'] = json_encode($vo['content'], JSON_UNESCAPED_UNICODE);
|
||||
$vo['response'] = json_encode($vo['response'], JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
exportExcel($header, $list, '操作日志');
|
||||
}catch (\Throwable $exception) {
|
||||
$this->error($exception->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[NodeAnnotation(title: '删除指定日志', auth: true)]
|
||||
public function deleteMonthLog(Request $request)
|
||||
{
|
||||
if (!$request->isAjax()) {
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
if ($this->isDemo) $this->error('演示环境下不允许操作');
|
||||
|
||||
$monthsAgo = $request->param('month/d', 0);
|
||||
if ($monthsAgo < 1) $this->error('月份错误');
|
||||
|
||||
$currentDate = new \DateTime();
|
||||
$currentDate->modify("-$monthsAgo months");
|
||||
|
||||
$dbPrefix = env('DB_PREFIX');
|
||||
$dbLike = "{$dbPrefix}system_log_";
|
||||
$tables = Db::query("SHOW TABLES LIKE '$dbLike%'");
|
||||
$threshold = date('Ym', strtotime("-$monthsAgo month"));
|
||||
$tableNames = [];
|
||||
try {
|
||||
foreach ($tables as $table) {
|
||||
$tableName = current($table);
|
||||
if (!preg_match("/^$dbLike\d{6}$/", $tableName)) continue;
|
||||
$datePart = substr($tableName, -6);
|
||||
$issetTable = Db::query("SHOW TABLES LIKE '$tableName'");
|
||||
if (!$issetTable) continue;
|
||||
if ($datePart - $threshold <= 0) {
|
||||
Db::execute("DROP TABLE `$tableName`");
|
||||
$tableNames[] = $tableName;
|
||||
}
|
||||
}
|
||||
}catch (PDOException) {
|
||||
}
|
||||
if (empty($tableNames)) $this->error('没有需要删除的表');
|
||||
$this->success('操作成功 - 共删除 ' . count($tableNames) . ' 张表<br/>' . implode('<br>', $tableNames));
|
||||
}
|
||||
|
||||
#[MiddlewareAnnotation(ignore: MiddlewareAnnotation::IGNORE_LOG)]
|
||||
#[NodeAnnotation(title: '框架日志', auth: true, ignore: NodeAnnotation::IGNORE_NODE)]
|
||||
public function record(): Json|string
|
||||
{
|
||||
return (new \Wolfcode\PhpLogviewer\thinkphp\LogViewer())->fetch();
|
||||
}
|
||||
|
||||
}
|
||||
191
app/admin/controller/system/Menu.php
Normal file
191
app/admin/controller/system/Menu.php
Normal file
@ -0,0 +1,191 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\system;
|
||||
|
||||
use app\admin\model\SystemMenu;
|
||||
use app\admin\model\SystemNode;
|
||||
use app\admin\service\TriggerService;
|
||||
use app\common\constants\MenuConstant;
|
||||
use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\common\controller\AdminController;
|
||||
use app\Request;
|
||||
use think\App;
|
||||
use think\response\Json;
|
||||
|
||||
#[ControllerAnnotation(title: '菜单管理')]
|
||||
class Menu extends AdminController
|
||||
{
|
||||
|
||||
protected array $sort = [
|
||||
'sort' => 'desc',
|
||||
'id' => 'asc',
|
||||
];
|
||||
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
self::$model = SystemMenu::class;
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
public function index(Request $request): Json|string
|
||||
{
|
||||
if ($request->isAjax()) {
|
||||
if (input('selectFields')) {
|
||||
return $this->selectList();
|
||||
}
|
||||
$count = self::$model::count();
|
||||
$list = self::$model::order($this->sort)->select()->toArray();
|
||||
$data = [
|
||||
'code' => 0,
|
||||
'msg' => '',
|
||||
'count' => $count,
|
||||
'data' => $list,
|
||||
];
|
||||
return json($data);
|
||||
}
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '添加', auth: true)]
|
||||
public function add(Request $request): string
|
||||
{
|
||||
$id = $request->param('id');
|
||||
$homeId = self::$model::where(['pid' => MenuConstant::HOME_PID,])->value('id');
|
||||
if ($id == $homeId) {
|
||||
$this->error('首页不能添加子菜单');
|
||||
}
|
||||
if ($request->isPost()) {
|
||||
$post = $request->post();
|
||||
$rule = [
|
||||
'pid|上级菜单' => 'require',
|
||||
'title|菜单名称' => 'require',
|
||||
'icon|菜单图标' => 'require',
|
||||
];
|
||||
$this->validate($post, $rule);
|
||||
try {
|
||||
$save = self::$model::create($post);
|
||||
}catch (\Exception $e) {
|
||||
$this->error('保存失败');
|
||||
}
|
||||
if ($save) {
|
||||
TriggerService::updateMenu();
|
||||
$this->success('保存成功');
|
||||
}else {
|
||||
$this->error('保存失败');
|
||||
}
|
||||
}
|
||||
$pidMenuList = self::$model::getPidMenuList();
|
||||
$this->assign('id', $id);
|
||||
$this->assign('pidMenuList', $pidMenuList);
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '编辑', auth: true)]
|
||||
public function edit(Request $request, $id = 0): string
|
||||
{
|
||||
$row = self::$model::find($id);
|
||||
empty($row) && $this->error('数据不存在');
|
||||
if ($request->isPost()) {
|
||||
$post = $request->post();
|
||||
$rule = [
|
||||
'pid|上级菜单' => 'require',
|
||||
'title|菜单名称' => 'require',
|
||||
'icon|菜单图标' => 'require',
|
||||
];
|
||||
$this->validate($post, $rule);
|
||||
if ($row->pid == MenuConstant::HOME_PID) $post['pid'] = MenuConstant::HOME_PID;
|
||||
try {
|
||||
$save = $row->save($post);
|
||||
}catch (\Exception $e) {
|
||||
$this->error('保存失败');
|
||||
}
|
||||
if (!empty($save)) {
|
||||
TriggerService::updateMenu();
|
||||
$this->success('保存成功');
|
||||
}else {
|
||||
$this->error('保存失败');
|
||||
}
|
||||
}
|
||||
$pidMenuList = self::$model::getPidMenuList();
|
||||
$this->assign([
|
||||
'id' => $id,
|
||||
'pidMenuList' => $pidMenuList,
|
||||
'row' => $row,
|
||||
]);
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '删除', auth: true)]
|
||||
public function delete(Request $request): void
|
||||
{
|
||||
$this->checkPostRequest();
|
||||
$id = $request->param('id');
|
||||
$row = self::$model::whereIn('id', $id)->select();
|
||||
empty($row) && $this->error('数据不存在');
|
||||
try {
|
||||
$save = $row->delete();
|
||||
}catch (\Exception $e) {
|
||||
$this->error('删除失败');
|
||||
}
|
||||
if ($save) {
|
||||
TriggerService::updateMenu();
|
||||
$this->success('删除成功');
|
||||
}else {
|
||||
$this->error('删除失败');
|
||||
}
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '属性修改', auth: true)]
|
||||
public function modify(Request $request): void
|
||||
{
|
||||
$this->checkPostRequest();
|
||||
$post = $request->post();
|
||||
$rule = [
|
||||
'id|ID' => 'require',
|
||||
'field|字段' => 'require',
|
||||
'value|值' => 'require',
|
||||
];
|
||||
$this->validate($post, $rule);
|
||||
$row = self::$model::find($post['id']);
|
||||
if (!$row) {
|
||||
$this->error('数据不存在');
|
||||
}
|
||||
if (!in_array($post['field'], $this->allowModifyFields)) {
|
||||
$this->error('该字段不允许修改:' . $post['field']);
|
||||
}
|
||||
$homeId = self::$model::where([
|
||||
'pid' => MenuConstant::HOME_PID,
|
||||
])
|
||||
->value('id');
|
||||
if ($post['id'] == $homeId && $post['field'] == 'status') {
|
||||
$this->error('首页状态不允许关闭');
|
||||
}
|
||||
try {
|
||||
$row->save([
|
||||
$post['field'] => $post['value'],
|
||||
]);
|
||||
}catch (\Exception $e) {
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
TriggerService::updateMenu();
|
||||
$this->success('保存成功');
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '添加菜单提示', auth: true)]
|
||||
public function getMenuTips(): Json
|
||||
{
|
||||
$node = input('get.keywords');
|
||||
$list = SystemNode::whereLike('node', "%{$node}%")
|
||||
->field('node,title')
|
||||
->limit(10)
|
||||
->select()->toArray();
|
||||
return json([
|
||||
'code' => 0,
|
||||
'content' => $list,
|
||||
'type' => 'success',
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
125
app/admin/controller/system/Node.php
Normal file
125
app/admin/controller/system/Node.php
Normal file
@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\system;
|
||||
|
||||
use app\admin\model\SystemMenu;
|
||||
use app\admin\model\SystemNode;
|
||||
use app\admin\service\TriggerService;
|
||||
use app\common\controller\AdminController;
|
||||
use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\admin\service\NodeService;
|
||||
use app\Request;
|
||||
use think\App;
|
||||
use think\db\exception\DataNotFoundException;
|
||||
use think\db\exception\DbException;
|
||||
use think\db\exception\ModelNotFoundException;
|
||||
use think\response\Json;
|
||||
|
||||
#[ControllerAnnotation(title: '系统节点管理')]
|
||||
class Node extends AdminController
|
||||
{
|
||||
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
self::$model = SystemNode::class;
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
public function index(Request $request): Json|string
|
||||
{
|
||||
if ($request->isAjax()) {
|
||||
if (input('selectFields')) {
|
||||
return $this->selectList();
|
||||
}
|
||||
$count = self::$model::count();
|
||||
$list = self::$model::getNodeTreeList();
|
||||
$data = [
|
||||
'code' => 0,
|
||||
'msg' => '',
|
||||
'count' => $count,
|
||||
'data' => $list,
|
||||
];
|
||||
return json($data);
|
||||
}
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '系统节点更新', auth: true)]
|
||||
public function refreshNode($force = 0): void
|
||||
{
|
||||
|
||||
$this->checkPostRequest();
|
||||
$nodeList = (new NodeService())->getNodeList();
|
||||
empty($nodeList) && $this->error('暂无需要更新的系统节点');
|
||||
|
||||
try {
|
||||
if ($force == 1) {
|
||||
$updateNodeList = self::$model::whereIn('node', array_column($nodeList, 'node'))->select();
|
||||
$formatNodeList = array_format_key($nodeList, 'node');
|
||||
foreach ($updateNodeList as $vo) {
|
||||
isset($formatNodeList[$vo['node']])
|
||||
&& self::$model::where('id', $vo['id'])->update(
|
||||
[
|
||||
'title' => $formatNodeList[$vo['node']]['title'],
|
||||
'is_auth' => $formatNodeList[$vo['node']]['is_auth'],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
$existNodeList = self::$model::field('node,title,type,is_auth')->select();
|
||||
foreach ($nodeList as $key => $vo) {
|
||||
foreach ($existNodeList as $v) {
|
||||
if ($vo['node'] == $v->node) {
|
||||
unset($nodeList[$key]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($nodeList)) {
|
||||
(new self::$model)->saveAll($nodeList);
|
||||
TriggerService::updateNode();
|
||||
}
|
||||
}catch (\Exception $e) {
|
||||
$this->error('节点更新失败');
|
||||
}
|
||||
$this->success('节点更新成功');
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '清除失效节点', auth: true)]
|
||||
public function clearNode(): void
|
||||
{
|
||||
$this->checkPostRequest();
|
||||
$nodeList = (new NodeService())->getNodeList();
|
||||
try {
|
||||
$existNodeList = self::$model::field('id,node,title,type,is_auth')->select()->toArray();
|
||||
$formatNodeList = array_format_key($nodeList, 'node');
|
||||
foreach ($existNodeList as $vo) {
|
||||
!isset($formatNodeList[$vo['node']]) && self::$model::where('id', $vo['id'])->delete();
|
||||
}
|
||||
TriggerService::updateNode();
|
||||
}catch (\Exception $e) {
|
||||
$this->error('节点更新失败');
|
||||
}
|
||||
$this->success('节点更新成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \ReflectionException
|
||||
* @throws \Doctrine\Common\Annotations\AnnotationException
|
||||
*/
|
||||
#[NodeAnnotation(title: '刷新菜单', auth: true)]
|
||||
public function refreshMenu(): void
|
||||
{
|
||||
$this->checkPostRequest();
|
||||
$nodeList = (new NodeService())->getNodeList();
|
||||
empty($nodeList) && $this->error('暂无需要更新的系统节点');
|
||||
try {
|
||||
SystemMenu::refreshMenu($nodeList);
|
||||
}catch (\Exception $e) {
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
$this->success('菜单刷新成功');
|
||||
}
|
||||
}
|
||||
27
app/admin/controller/system/Quick.php
Normal file
27
app/admin/controller/system/Quick.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\system;
|
||||
|
||||
|
||||
use app\admin\model\SystemQuick;
|
||||
use app\common\controller\AdminController;
|
||||
use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use think\App;
|
||||
|
||||
#[ControllerAnnotation(title: '快捷入口管理')]
|
||||
class Quick extends AdminController
|
||||
{
|
||||
|
||||
protected array $sort = [
|
||||
'sort' => 'desc',
|
||||
'id' => 'desc',
|
||||
];
|
||||
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
self::$model = SystemQuick::class;
|
||||
}
|
||||
|
||||
}
|
||||
22
app/admin/controller/system/Uploadfile.php
Normal file
22
app/admin/controller/system/Uploadfile.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\system;
|
||||
|
||||
use app\admin\model\SystemUploadfile;
|
||||
use app\common\controller\AdminController;
|
||||
use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use think\App;
|
||||
|
||||
#[ControllerAnnotation(title: '上传文件管理')]
|
||||
class Uploadfile extends AdminController
|
||||
{
|
||||
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
self::$model = SystemUploadfile::class;
|
||||
$this->assign('upload_types', config('admin.upload_types'));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user