1
This commit is contained in:
247
app/admin/controller/Ajax.php
Normal file
247
app/admin/controller/Ajax.php
Normal file
@ -0,0 +1,247 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\admin\model\SystemUploadfile;
|
||||
use app\admin\service\UploadService;
|
||||
use app\common\controller\AdminController;
|
||||
use app\common\service\MenuService;
|
||||
use app\Request;
|
||||
use Kaadon\Helper\GdImageHelper;
|
||||
use think\db\exception\DataNotFoundException;
|
||||
use think\db\exception\DbException;
|
||||
use think\db\exception\ModelNotFoundException;
|
||||
use think\db\Query;
|
||||
use think\facade\Cache;
|
||||
use think\file\UploadedFile;
|
||||
use think\response\Json;
|
||||
|
||||
class Ajax extends AdminController
|
||||
{
|
||||
|
||||
/**
|
||||
* 初始化后台接口地址
|
||||
* @return Json
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public function initAdmin(): Json
|
||||
{
|
||||
$cacheData = Cache::get('initAdmin_' . $this->adminUid);
|
||||
if (!empty($cacheData)) {
|
||||
return json($cacheData);
|
||||
}
|
||||
$menuService = new MenuService($this->adminUid);
|
||||
$data = [
|
||||
'logoInfo' => [
|
||||
'title' => sysConfig('site', 'logo_title'),
|
||||
'image' => sysConfig('site', 'logo_image'),
|
||||
'href' => __url('index/index'),
|
||||
],
|
||||
'homeInfo' => $menuService->getHomeInfo(),
|
||||
'menuInfo' => $menuService->getMenuTree(),
|
||||
];
|
||||
Cache::tag('initAdmin')->set('initAdmin_' . $this->adminUid, $data);
|
||||
return json($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理缓存接口
|
||||
*/
|
||||
public function clearCache(): void
|
||||
{
|
||||
Cache::clear();
|
||||
$this->success('清理缓存成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件
|
||||
* @param Request $request
|
||||
* @return Json|null
|
||||
* @throws \Kaadon\Helper\HelperException
|
||||
*/
|
||||
public function upload(Request $request): Json|null
|
||||
{
|
||||
$this->isDemo && $this->error('演示环境下不允许修改');
|
||||
$this->checkPostRequest();
|
||||
$type = $request->param('type', '');
|
||||
$file = $request->file($type == 'editor' ? 'upload' : 'file');
|
||||
if (config('filesystem.image.to_webp', true) && GdImageHelper::isSupportSuffix($file->extension())) {
|
||||
(new GdImageHelper($file->getRealPath(), $file->extension()))->convertTo($file->getRealPath(),'webp');
|
||||
$file = new UploadedFile($file->getRealPath(), date("YmdHis") . "_" . md5($file->getOriginalName()) . '.webp');
|
||||
$file->setExtension('webp');
|
||||
}
|
||||
$data = [
|
||||
'upload_type' => $request->post('upload_type'),
|
||||
'file' => $file,
|
||||
];
|
||||
$uploadConfig = sysConfig('upload');
|
||||
empty($data['upload_type']) && $data['upload_type'] = $uploadConfig['upload_type'];
|
||||
$rule = [
|
||||
'upload_type|指定上传类型有误' => "in:{$uploadConfig['upload_allow_type']}",
|
||||
'file|文件' => "require|file|fileExt:{$uploadConfig['upload_allow_ext']},webp|fileSize:{$uploadConfig['upload_allow_size']}",
|
||||
];
|
||||
$this->validate($data, $rule);
|
||||
$upload_type = $uploadConfig['upload_type'];
|
||||
try {
|
||||
$upload = UploadService::instance()->setConfig($uploadConfig)->$upload_type($data['file'], $type);
|
||||
}catch (\Exception $e) {
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
$code = $upload['code'] ?? 0;
|
||||
if ($code == 0) {
|
||||
$this->error($upload['data'] ?? '');
|
||||
}else {
|
||||
if ($type == 'editor') {
|
||||
return json(
|
||||
[
|
||||
'error' => ['message' => '上传成功', 'number' => 201,],
|
||||
'fileName' => '',
|
||||
'uploaded' => 1,
|
||||
'url' => $upload['data']['url'] ?? '',
|
||||
]
|
||||
);
|
||||
}else {
|
||||
$this->success('上传成功', $upload['data'] ?? '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取上传文件列表
|
||||
* @param Request $request
|
||||
* @return Json
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public function getUploadFiles(Request $request): Json
|
||||
{
|
||||
$get = $request->get();
|
||||
$page = !empty($get['page']) ? $get['page'] : 1;
|
||||
$limit = !empty($get['limit']) ? $get['limit'] : 10;
|
||||
$title = !empty($get['title']) ? $get['title'] : null;
|
||||
$count = SystemUploadfile::where(function(Query $query) use ($title) {
|
||||
!empty($title) && $query->where('original_name', 'like', "%{$title}%");
|
||||
})
|
||||
->count();
|
||||
$list = SystemUploadfile::where(function(Query $query) use ($title) {
|
||||
!empty($title) && $query->where('original_name', 'like', "%{$title}%");
|
||||
})
|
||||
->page($page, $limit)
|
||||
->order($this->sort)
|
||||
->select()->toArray();
|
||||
$data = [
|
||||
'code' => 0,
|
||||
'msg' => '',
|
||||
'count' => $count,
|
||||
'data' => $list,
|
||||
];
|
||||
return json($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 百度编辑器上传
|
||||
* @param Request $request
|
||||
* @return Json
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
* @throws \Kaadon\Helper\HelperException
|
||||
*/
|
||||
public function uploadUEditor(Request $request): Json
|
||||
{
|
||||
$uploadConfig = sysConfig('upload');
|
||||
$upload_allow_size = $uploadConfig['upload_allow_size'];
|
||||
$_upload_allow_ext = explode(',', $uploadConfig['upload_allow_ext']);
|
||||
$upload_allow_ext = [];
|
||||
array_map(function($value) use (&$upload_allow_ext) {
|
||||
$upload_allow_ext[] = '.' . $value;
|
||||
}, $_upload_allow_ext);
|
||||
$config = [
|
||||
// 上传图片配置项
|
||||
"imageActionName" => "image",
|
||||
"imageFieldName" => "file",
|
||||
"imageMaxSize" => $upload_allow_size,
|
||||
"imageAllowFiles" => $upload_allow_ext,
|
||||
"imageCompressEnable" => true,
|
||||
"imageCompressBorder" => 5000,
|
||||
"imageInsertAlign" => "none",
|
||||
"imageUrlPrefix" => "",
|
||||
// 列出图片
|
||||
"imageManagerActionName" => "listImage",
|
||||
"imageManagerListSize" => 20,
|
||||
"imageManagerUrlPrefix" => "",
|
||||
"imageManagerInsertAlign" => "none",
|
||||
"imageManagerAllowFiles" => $upload_allow_ext,
|
||||
// 上传 video
|
||||
"videoActionName" => "video",
|
||||
"videoFieldName" => "file",
|
||||
"videoUrlPrefix" => "",
|
||||
"videoMaxSize" => $upload_allow_size,
|
||||
"videoAllowFiles" => $upload_allow_ext,
|
||||
// 上传 附件
|
||||
"fileActionName" => "attachment",
|
||||
"fileFieldName" => "file",
|
||||
"fileMaxSize" => $upload_allow_size,
|
||||
"fileAllowFiles" => $upload_allow_ext,
|
||||
];
|
||||
$action = $request->param('action/s', '');
|
||||
$file = $request->file('file');
|
||||
$upload_type = $uploadConfig['upload_type'];
|
||||
switch ($action) {
|
||||
case 'image':
|
||||
if (config('filesystem.image.to_webp', true) && GdImageHelper::isSupportSuffix($file->extension())) {
|
||||
(new GdImageHelper($file->getRealPath(), $file->extension()))->convertTo($file->getRealPath(),'webp');
|
||||
$file = new UploadedFile($file->getRealPath(), date("YmdHis") . "_" . md5($file->getOriginalName()) . '.webp');
|
||||
$file->setExtension('webp');
|
||||
}
|
||||
case 'attachment':
|
||||
case 'video':
|
||||
if ($this->isDemo) return json(['state' => '演示环境下不允许修改']);
|
||||
try {
|
||||
$upload = UploadService::instance()->setConfig($uploadConfig)->$upload_type($file);
|
||||
$code = $upload['code'] ?? 0;
|
||||
if ($code == 0) {
|
||||
return json(['state' => $upload['data'] ?? '上传错误信息']);
|
||||
}else {
|
||||
return json(['state' => 'SUCCESS', 'url' => $upload['data']['url'] ?? '']);
|
||||
}
|
||||
}catch (\Exception $e) {
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
break;
|
||||
case 'listImage':
|
||||
$list = (new SystemUploadfile())->order($this->sort)->limit(100)->field('url')->select()->toArray();
|
||||
$result = [
|
||||
"state" => "SUCCESS",
|
||||
"list" => $list,
|
||||
"total" => 0,
|
||||
"start" => 0,
|
||||
];
|
||||
return json($result);
|
||||
default:
|
||||
return json($config);
|
||||
}
|
||||
}
|
||||
|
||||
public function composerInfo(): Json
|
||||
{
|
||||
$lockFilePath = root_path() . '/composer.lock';
|
||||
$list = [];
|
||||
if (file_exists($lockFilePath)) {
|
||||
$lockFileContent = file_get_contents($lockFilePath);
|
||||
if ($lockFileContent !== false) {
|
||||
$lockData = json_decode($lockFileContent, true);
|
||||
if (!empty($lockData['packages'])) {
|
||||
foreach ($lockData['packages'] as $package) {
|
||||
$list[] = ['name' => $package['name'], 'version' => $package['version']];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->success('success', $list);
|
||||
}
|
||||
|
||||
}
|
||||
198
app/admin/controller/Index.php
Normal file
198
app/admin/controller/Index.php
Normal file
@ -0,0 +1,198 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\admin\model\MallOrder;
|
||||
use app\admin\model\SystemAdmin;
|
||||
use app\admin\model\SystemQuick;
|
||||
use app\common\controller\AdminController;
|
||||
use app\Request;
|
||||
use Exception;
|
||||
use think\db\exception\DataNotFoundException;
|
||||
use think\db\exception\DbException;
|
||||
use think\db\exception\ModelNotFoundException;
|
||||
use think\facade\Db;
|
||||
|
||||
class Index extends AdminController
|
||||
{
|
||||
|
||||
/**
|
||||
* 后台主页
|
||||
* @param Request $request
|
||||
* @return string
|
||||
*/
|
||||
public function index(Request $request): string
|
||||
{
|
||||
return $this->fetch('', ['admin' => $request->adminUserInfo,]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台欢迎页
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function welcome(): string
|
||||
{
|
||||
$tpVersion = \think\facade\App::version();
|
||||
$mysqlVersion = Db::query("select version() as version")[0]['version'] ?? '未知';
|
||||
$phpVersion = phpversion();
|
||||
$versions = compact('tpVersion', 'mysqlVersion', 'phpVersion');
|
||||
$quick_list = SystemQuick::field('id,title,icon,href')
|
||||
->where(['status' => 1])->order('sort', 'desc')->limit(50)->select()->toArray();
|
||||
$quicks = array_chunk($quick_list, 8);
|
||||
$this->assign(compact('quicks', 'versions'));
|
||||
$data = [
|
||||
'all_member'=>[
|
||||
"title"=>"今日订单",
|
||||
"data"=>(new MallOrder())->where([['create_time','>',strtotime(date('Y-m-d')." 06:00:00")]])->count(),
|
||||
],
|
||||
'login_member'=>[
|
||||
"title"=>"今日金额",
|
||||
"data"=> (new MallOrder())->where([['create_time','>',strtotime(date('Y-m-d')." 06:00:00")]])->sum('money'),
|
||||
],
|
||||
'recharge_member'=>[
|
||||
"title"=>"今日已支付",
|
||||
"data"=>(new MallOrder())->where([['create_time','>',strtotime(date('Y-m-d')." 06:00:00")],['status','=',2]])->count(),
|
||||
],
|
||||
|
||||
'all_charge'=>[
|
||||
"title"=>"今日已支付金额",
|
||||
"data"=>(new MallOrder())->where([['create_time','>',strtotime(date('Y-m-d')." 06:00:00")],['status','=',2]])->sum('money'),
|
||||
|
||||
],
|
||||
'day_charge'=>[
|
||||
"title"=>"待处理订单",
|
||||
"data"=>(new MallOrder())->where([['create_time','>',strtotime(date('Y-m-d')." 06:00:00")],['status','=',0]])->count(),
|
||||
|
||||
],
|
||||
'recharge_number'=>[
|
||||
"title"=>"总订单数",
|
||||
"data"=>(new MallOrder())->count(),
|
||||
],
|
||||
];
|
||||
$this->assign('data', $data);
|
||||
return $this->fetch();
|
||||
}
|
||||
public function get_order()
|
||||
{
|
||||
$this->success('操作成功', [
|
||||
'count'=>(new MallOrder())->where([['create_time','>',strtotime(date('Y-m-d')." 06:00:00")],['status','=',0]])->count(),
|
||||
'rid'=>(new MallOrder())->where([['create_time','>',strtotime(date('Y-m-d')." 06:00:00")],['status','=',0]])
|
||||
->order('id desc')->value('id')
|
||||
]);
|
||||
}
|
||||
/**
|
||||
* 修改管理员信息
|
||||
* @param Request $request
|
||||
* @return string
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public function editAdmin(Request $request): string
|
||||
{
|
||||
$id = $this->adminUid;
|
||||
$row = (new SystemAdmin())
|
||||
->withoutField('password')
|
||||
->find($id);
|
||||
empty($row) && $this->error('用户信息不存在');
|
||||
if ($request->isPost()) {
|
||||
$post = $request->post();
|
||||
$this->isDemo && $this->error('演示环境下不允许修改');
|
||||
$rule = [];
|
||||
$this->validate($post, $rule);
|
||||
try {
|
||||
$login_type = $post['login_type'] ?? 1;
|
||||
if ($login_type == 2) {
|
||||
$ga_secret = (new SystemAdmin())->where('id', $id)->value('ga_secret');
|
||||
if (empty($ga_secret)) $this->error('请先绑定谷歌验证器');
|
||||
}
|
||||
$save = $row->allowField(['head_img', 'phone', 'remark', 'update_time', 'login_type'])->save($post);
|
||||
}catch (\PDOException $e) {
|
||||
$this->error('保存失败');
|
||||
}
|
||||
$save ? $this->success('保存成功') : $this->error('保存失败');
|
||||
}
|
||||
$this->assign('row', $row);
|
||||
$notes = (new SystemAdmin())->notes;
|
||||
$this->assign('notes', $notes);
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改密码
|
||||
* @param Request $request
|
||||
* @return string
|
||||
*/
|
||||
public function editPassword(Request $request): string
|
||||
{
|
||||
$id = $this->adminUid;
|
||||
$row = (new SystemAdmin())
|
||||
->withoutField('password')
|
||||
->find($id);
|
||||
if (!$row) {
|
||||
$this->error('用户信息不存在');
|
||||
}
|
||||
if ($request->isPost()) {
|
||||
$post = $request->post();
|
||||
$this->isDemo && $this->error('演示环境下不允许修改');
|
||||
$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('保存失败');
|
||||
}
|
||||
if ($save) {
|
||||
$this->success('保存成功');
|
||||
}else {
|
||||
$this->error('保存失败');
|
||||
}
|
||||
}
|
||||
$this->assign('row', $row);
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置谷歌验证码
|
||||
* @param Request $request
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function set2fa(Request $request): string
|
||||
{
|
||||
$id = $this->adminUid;
|
||||
$row = (new SystemAdmin())->withoutField('password')->find($id);
|
||||
if (!$row) $this->error('用户信息不存在');
|
||||
// You can see: https://gitee.com/wolf-code/authenticator
|
||||
$ga = new \Wolfcode\Authenticator\google\PHPGangstaGoogleAuthenticator();
|
||||
if (!$request->isAjax()) {
|
||||
$old_secret = $row->ga_secret;
|
||||
$secret = $ga->createSecret(32);
|
||||
$ga_title = $this->isDemo ? 'EasyAdmin8演示环境' : '可自定义修改显示标题';
|
||||
$dataUri = $ga->getQRCode($ga_title, $secret);
|
||||
$this->assign(compact('row', 'dataUri', 'old_secret', 'secret'));
|
||||
return $this->fetch();
|
||||
}
|
||||
$this->isDemo && $this->error('演示环境下不允许修改');
|
||||
$post = $request->post();
|
||||
$ga_secret = $post['ga_secret'] ?? '';
|
||||
$ga_code = $post['ga_code'] ?? '';
|
||||
if (empty($ga_code)) $this->error('请输入验证码');
|
||||
if (!$ga->verifyCode($ga_secret, $ga_code)) $this->error('验证码错误');
|
||||
$row->ga_secret = $ga_secret;
|
||||
$row->login_type = 2;
|
||||
$row->save();
|
||||
$this->success('操作成功');
|
||||
}
|
||||
|
||||
}
|
||||
93
app/admin/controller/Login.php
Normal file
93
app/admin/controller/Login.php
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\admin\model\SystemAdmin;
|
||||
use app\common\controller\AdminController;
|
||||
use app\common\utils\Helper;
|
||||
use think\captcha\facade\Captcha;
|
||||
use think\db\exception\DataNotFoundException;
|
||||
use think\db\exception\DbException;
|
||||
use think\db\exception\ModelNotFoundException;
|
||||
use app\Request;
|
||||
use think\Response;
|
||||
use Wolfcode\RateLimiting\Attributes\RateLimitingMiddleware;
|
||||
|
||||
class Login extends AdminController
|
||||
{
|
||||
|
||||
protected bool $ignoreLogin = true;
|
||||
|
||||
public function initialize(): void
|
||||
{
|
||||
parent::initialize();
|
||||
$action = $this->request->action();
|
||||
if (!empty($this->adminUid) && !in_array($action, ['out'])) {
|
||||
$adminModuleName = config('admin.alias_name');
|
||||
$this->success('已登录,无需再次登录', [], __url("@{$adminModuleName}"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户登录
|
||||
* @param Request $request
|
||||
* @return string
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
#[RateLimitingMiddleware(key: [Helper::class, 'getIp'], seconds: 1, limit: 1, message: '请求过于频繁')]
|
||||
public function index(Request $request): string
|
||||
{
|
||||
$captcha = env('EASYADMIN.CAPTCHA', 1);
|
||||
if (!$request->isPost()) return $this->fetch('', compact('captcha'));
|
||||
$post = $request->post();
|
||||
$rule = [
|
||||
'username|用户名' => 'require',
|
||||
'password|密码' => 'require',
|
||||
'keep_login|是否保持登录' => 'require',
|
||||
];
|
||||
$captcha == 1 && $rule['captcha|验证码'] = 'require|captcha';
|
||||
$this->validate($post, $rule);
|
||||
$admin = SystemAdmin::where(['username' => $post['username']])->find();
|
||||
if (empty($admin)) {
|
||||
$this->error('用户不存在');
|
||||
}
|
||||
if (!password_verify($post['password'], $admin->password)) {
|
||||
$this->error('密码输入有误');
|
||||
}
|
||||
if ($admin->status == 0) {
|
||||
$this->error('账号已被禁用');
|
||||
}
|
||||
if ($admin->login_type == 2) {
|
||||
if (empty($post['ga_code'])) $this->error('请输入谷歌验证码', ['is_ga_code' => true]);
|
||||
$ga = new \Wolfcode\Authenticator\google\PHPGangstaGoogleAuthenticator();
|
||||
if (!$ga->verifyCode($admin->ga_secret, $post['ga_code'])) $this->error('谷歌验证码错误');;
|
||||
}
|
||||
$admin->login_num += 1;
|
||||
$admin->save();
|
||||
$admin = $admin->toArray();
|
||||
unset($admin['password']);
|
||||
$admin['expire_time'] = $post['keep_login'] == 1 ? 0 : time() + 7200;
|
||||
session('admin', $admin);
|
||||
$this->success('登录成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户退出
|
||||
*/
|
||||
public function out(): void
|
||||
{
|
||||
session('admin', null);
|
||||
$this->success('退出登录成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证码
|
||||
* @return Response
|
||||
*/
|
||||
public function captcha(): Response
|
||||
{
|
||||
return Captcha::instance()->create();
|
||||
}
|
||||
}
|
||||
21
app/admin/controller/article/Article.php
Normal file
21
app/admin/controller/article/Article.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\article;
|
||||
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\common\controller\AdminController;
|
||||
use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\common\model\Articles;
|
||||
use think\App;
|
||||
|
||||
#[ControllerAnnotation(title: '文章管理')]
|
||||
class Article extends AdminController
|
||||
{
|
||||
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
self::$model = Articles::class;
|
||||
}
|
||||
|
||||
}
|
||||
21
app/admin/controller/article/Cate.php
Normal file
21
app/admin/controller/article/Cate.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\article;
|
||||
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\common\controller\AdminController;
|
||||
use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\common\model\ArticleCates;
|
||||
use think\App;
|
||||
|
||||
#[ControllerAnnotation(title: '文章分类管理')]
|
||||
class Cate extends AdminController
|
||||
{
|
||||
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
self::$model = ArticleCates::class;
|
||||
}
|
||||
|
||||
}
|
||||
51
app/admin/controller/mall/Blackip.php
Normal file
51
app/admin/controller/mall/Blackip.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\mall;
|
||||
|
||||
use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\MiddlewareAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\common\controller\AdminController;
|
||||
use app\Request;
|
||||
use think\App;
|
||||
use think\response\Json;
|
||||
|
||||
#[ControllerAnnotation(title: '商城商品管理')]
|
||||
class Blackip extends AdminController
|
||||
{
|
||||
|
||||
#[NodeAnnotation(ignore: ['export'])] // 过滤不需要生成的权限节点 默认 CURD 中会自动生成部分节点 可以在此处过滤
|
||||
protected array $ignoreNode;
|
||||
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
self::$model = new \app\admin\model\BlackIp();
|
||||
}
|
||||
|
||||
#[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::where($where)->page($page, $limit)->order($this->sort)->select()->toArray();
|
||||
$data = [
|
||||
'code' => 0,
|
||||
'msg' => '',
|
||||
'count' => $count,
|
||||
'data' => $list,
|
||||
];
|
||||
return json($data);
|
||||
}
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
#[MiddlewareAnnotation(ignore: MiddlewareAnnotation::IGNORE_LOGIN)]
|
||||
public function no_check_login(Request $request): string
|
||||
{
|
||||
return '这里演示方法不需要经过登录验证';
|
||||
}
|
||||
|
||||
}
|
||||
21
app/admin/controller/mall/Cate.php
Normal file
21
app/admin/controller/mall/Cate.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\mall;
|
||||
|
||||
use app\admin\model\MallCate;
|
||||
use app\common\controller\AdminController;
|
||||
use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use think\App;
|
||||
|
||||
#[ControllerAnnotation(title: '商品分类管理')]
|
||||
class Cate extends AdminController
|
||||
{
|
||||
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
self::$model = MallCate::class;
|
||||
}
|
||||
|
||||
}
|
||||
135
app/admin/controller/mall/Goods.php
Normal file
135
app/admin/controller/mall/Goods.php
Normal file
@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\mall;
|
||||
|
||||
use app\admin\model\MallCate;
|
||||
use app\admin\model\MallGoods;
|
||||
use app\admin\service\annotation\MiddlewareAnnotation;
|
||||
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;
|
||||
use Wolfcode\Ai\Enum\AiType;
|
||||
use Wolfcode\Ai\Service\AiChatService;
|
||||
|
||||
#[ControllerAnnotation(title: '商城商品管理')]
|
||||
class Goods extends AdminController
|
||||
{
|
||||
|
||||
#[NodeAnnotation(ignore: ['export'])] // 过滤不需要生成的权限节点 默认 CURD 中会自动生成部分节点 可以在此处过滤
|
||||
protected array $ignoreNode;
|
||||
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
self::$model = new MallGoods();
|
||||
$this->assign('cate', MallCate::column('title', 'id'));
|
||||
}
|
||||
|
||||
#[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::with(['cate'])->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 stock(Request $request, $id): string
|
||||
{
|
||||
$row = self::$model::find($id);
|
||||
empty($row) && $this->error('数据不存在');
|
||||
if ($request->isPost()) {
|
||||
$post = $request->post();
|
||||
$rule = [];
|
||||
$this->validate($post, $rule);
|
||||
try {
|
||||
$post['total_stock'] = $row->total_stock + $post['stock'];
|
||||
$post['stock'] = $row->stock + $post['stock'];
|
||||
$save = $row->save($post);
|
||||
}catch (\Exception $e) {
|
||||
$this->error('保存失败');
|
||||
}
|
||||
$save ? $this->success('保存成功') : $this->error('保存失败');
|
||||
}
|
||||
$this->assign('row', $row);
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
#[MiddlewareAnnotation(ignore: MiddlewareAnnotation::IGNORE_LOGIN)]
|
||||
public function no_check_login(Request $request): string
|
||||
{
|
||||
return '这里演示方法不需要经过登录验证';
|
||||
}
|
||||
|
||||
|
||||
#[NodeAnnotation(title: 'AI优化', auth: true)]
|
||||
public function aiOptimization(Request $request): void
|
||||
{
|
||||
$message = $request->post('message');
|
||||
if (empty($message)) $this->error('请输入内容');
|
||||
|
||||
// 演示环境下 默认返回的内容
|
||||
if ($this->isDemo) {
|
||||
$content = <<<EOF
|
||||
演示环境中 默认返回的内容
|
||||
|
||||
我来帮你优化这个标题,让它更有吸引力且更符合电商平台的搜索逻辑:
|
||||
|
||||
"商务男士高端定制马克杯 | 办公室精英必备 | 优质陶瓷防烫手柄"
|
||||
|
||||
这个优化后的标题:
|
||||
1. 突出了目标用户群体(商务男士)
|
||||
2. 强调了产品定位(高端定制)
|
||||
3. 点明了使用场景(办公室)
|
||||
4. 添加了材质和功能特点(优质陶瓷、防烫手柄)
|
||||
5. 使用了吸引人的关键词(精英必备)
|
||||
|
||||
这样的标题不仅更具体,也更容易被搜索引擎识别,同时能精准触达目标客户群。您觉得这个版本如何?
|
||||
EOF;
|
||||
$choices = [['message' => [
|
||||
'role' => 'assistant',
|
||||
'content' => $content,
|
||||
]]];
|
||||
$this->success('success', compact('choices'));
|
||||
}
|
||||
|
||||
try {
|
||||
$result = AiChatService::instance()
|
||||
// 当使用推理模型时,可能存在超时的情况,所以需要设置超时时间为 0
|
||||
// ->setTimeLimit(0)
|
||||
// 请替换为您需要的模型类型
|
||||
->setAiType(AiType::QWEN)
|
||||
// 如果需要指定模型的 API 地址,可自行设置
|
||||
// ->setAiUrl('https://xxx.com')
|
||||
// 请替换为您的模型
|
||||
->setAiModel('qwen-plus')
|
||||
// 请替换为您的 API KEY
|
||||
->setAiKey('sk-1234567890')
|
||||
// 此内容会作为系统提示,会影响到回答的内容 当前仅作为测试使用
|
||||
->setSystemContent('你现在是一位资深的海外电商产品经理')
|
||||
->chat($message);
|
||||
$choices = $result['choices'];
|
||||
}catch (\Throwable $exception) {
|
||||
$choices = [['message' => [
|
||||
'role' => 'assistant',
|
||||
'content' => $exception->getMessage(),
|
||||
]]];
|
||||
}
|
||||
$this->success('success', compact('choices'));
|
||||
}
|
||||
|
||||
}
|
||||
120
app/admin/controller/mall/Order.php
Normal file
120
app/admin/controller/mall/Order.php
Normal file
@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\mall;
|
||||
|
||||
use app\admin\model\MallOrder;
|
||||
use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\MiddlewareAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\common\controller\AdminController;
|
||||
use app\Request;
|
||||
use think\App;
|
||||
use think\facade\Db;
|
||||
use think\response\Json;
|
||||
use Wolfcode\Ai\Enum\AiType;
|
||||
use Wolfcode\Ai\Service\AiChatService;
|
||||
|
||||
#[ControllerAnnotation(title: '商城商品管理')]
|
||||
class Order extends AdminController
|
||||
{
|
||||
|
||||
#[NodeAnnotation(ignore: ['export'])] // 过滤不需要生成的权限节点 默认 CURD 中会自动生成部分节点 可以在此处过滤
|
||||
protected array $ignoreNode;
|
||||
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
self::$model = new MallOrder();
|
||||
}
|
||||
protected array $allowModifyFields = [
|
||||
'status',
|
||||
'sort',
|
||||
'remark',
|
||||
'is_delete',
|
||||
'is_auth',
|
||||
'title',
|
||||
'url',
|
||||
];
|
||||
|
||||
#[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::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 recharge(Request $request, $id): string
|
||||
{
|
||||
$row = self::$model::find($id);
|
||||
empty($row) && $this->error('数据不存在');
|
||||
if ($request->isPost()) {
|
||||
$post = $request->post();
|
||||
try {
|
||||
$post['status'] = 2;
|
||||
$save = $row->save($post);
|
||||
}catch (\Exception $e) {
|
||||
$this->error('保存失败');
|
||||
}
|
||||
$save ? $this->success('确认支付成功') : $this->error('保存失败');
|
||||
}
|
||||
}
|
||||
|
||||
#[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 = [];
|
||||
$this->validate($post, $rule);
|
||||
try {
|
||||
Db::transaction(function() use ($post, $row, &$save) {
|
||||
$post['status'] = 1;
|
||||
$save = $row->save($post);
|
||||
});
|
||||
}catch (\Exception $e) {
|
||||
$this->error('保存失败');
|
||||
}
|
||||
$save ? $this->success('保存成功') : $this->error('保存失败');
|
||||
}
|
||||
$this->assign('row', $row);
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: 'IP拉黑', auth: true)]
|
||||
public function blockip(Request $request, $id): string
|
||||
{
|
||||
$row = self::$model::find($id);
|
||||
empty($row) && $this->error('数据不存在');
|
||||
if ($request->isPost()) {
|
||||
try {
|
||||
$save = (new \app\admin\model\BlackIp())->save([
|
||||
'ip' => $row->ip,
|
||||
]);
|
||||
}catch (\Exception $e) {
|
||||
$this->error('保存失败');
|
||||
}
|
||||
$save ? $this->success('IP拉黑成功') : $this->error('保存失败');
|
||||
}
|
||||
}
|
||||
|
||||
#[MiddlewareAnnotation(ignore: MiddlewareAnnotation::IGNORE_LOGIN)]
|
||||
public function no_check_login(Request $request): string
|
||||
{
|
||||
return '这里演示方法不需要经过登录验证';
|
||||
}
|
||||
|
||||
}
|
||||
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