🚀 202405重置版

This commit is contained in:
wolfcode
2024-05-13 11:16:20 +08:00
parent 504ab4c4cf
commit a6fd81b0ed
242 changed files with 1169 additions and 2698 deletions

View File

@@ -1,24 +1,19 @@
APP_DEBUG=true
[APP]
DEFAULT_TIMEZONE=Asia/Shanghai
[DATABASE]
TYPE=mysql
HOSTNAME=127.0.0.1
DATABASE=easyadmin8
USERNAME=root
PASSWORD=root
HOSTPORT=3306
CHARSET=utf8mb4
DEBUG=true
PREFIX=ea8_
[LANG]
default_lang=zh-cn
DB_TYPE=mysql
DB_HOST=127.0.0.1
DB_NAME=easyadmin8
DB_USER=root
DB_PASS=root
DB_PORT=3306
DB_CHARSET=utf8mb4
DB_PREFIX=ea8_
# 后台配置项组
[EASYADMIN]
# 后台地址后缀名称
ADMIN=admin

27
.gitignore vendored
View File

@@ -1,21 +1,12 @@
/.idea
/.vscode
*.log
.env
config/install/lock/install.lock
/public/upload
/public/storage
/public/docs
runtime/admin
runtime/index
runtime/log
runtime/session
runtime/temp
runtime/cache
public/conf
public/WowOss.exe
app/index/controller/Test.php
composer.phar
app/test/
vendor
composer.lock
composer.lock
.DS_Store
Thumbs.db
/.idea
/.vscode
/vendor
/.settings
/.buildpath
/.project

66
CURD.md
View File

@@ -1,66 +0,0 @@
# CURD命令大全
`EasyAdmin8`框架以内置快速生成CURD的命令, 包括控制器、视图、模型、JS文件。能够使开发者效率得到进一步提升。
# 常用命令
```shell
# 生成ea8_test_goods表的CURD
php think curd -t test_goods
# 生成ea8_test_goods表的CURD, 文件冲突时强制覆盖
php think curd -t test_goods -f 1
# 删除ea8_test_goods表的CURD
php think curd -t test_goods -d 1
# 生成ea8_test_goods表的CURD, 控制器在目录demo下的Goods.php文件
php think curd -t test_goods -c demo/Goods
# 生成ea8_test_goods表的CURD, 模型在目录demo下的Goods.php文件
php think curd -t test_goods -m demo/Goods
# 生成ea8_test_goods表的CURD, 并关联ea8_test_cate表, 并设置外键为cate_id
php think curd -t test_goods -r test_cate --foreignKey=cate_id --primaryKey=id
# 生成ea8_test_goods表的CURD, 并关联ea8_test_cate表, 并设置只显示title,image两个字段
php think curd -t test_goods -r test_cate --foreignKey=cate_id --relationOnlyFileds=title,image
# 生成ea8_test_goods表的CURD, 并关联ea8_test_cate表, 并设置主表外键cate_id在表单的下拉选择显示的关联表的title字段
php think curd -t test_goods -r test_cate --foreignKey=cate_id --relationBindSelect=title
# 生成ea8_test_goods表的CURD, 并设置logo字段后缀为单图片
php think curd -t test_goods --imageFieldSuffix=logo
# 生成ea8_test_goods表的CURD, 并设置忽略remark, stock字段
php think curd -t test_goods --ignoreFields=remark --ignoreFields=stock
```
# 参数介绍
| 短参 | 长参 | 说明 |
| --- | --- |--- |
| -t | --table=VALUE | 主表名 |
| -c | --controllerFilename=VALUE | 控制器文件名 |
| -m | --modelFilename=VALUE | 主表模型文件名 |
| -f | --force=VALUE | 强制覆盖模式 |
| -d | --delete=VALUE | 删除模式 |
| | --checkboxFieldSuffix=VALUE | 复选框字段后缀 |
| | --radioFieldSuffix=VALUE | 单选框字段后缀 |
| | --imageFieldSuffix=VALUE | 单图片字段后缀 |
| | --imagesFieldSuffix=VALUE | 多图片字段后缀 |
| | --fileFieldSuffix=VALUE | 单文件字段后缀 |
| | --filesFieldSuffix=VALUE | 多文件字段后缀 |
| | --dateFieldSuffix=VALUE | 时间字段后缀 |
| | --switchFields=VALUE | 开关的字段 |
| | --selectFileds=VALUE | 下拉的字段 |
| | --editorFields=VALUE | 富文本的字段 |
| | --sortFields=VALUE | 排序的字段 |
| | --ignoreFields=VALUE | 忽略的字段 |
| -r | --relationTable=VALUE | 关联表名 |
| | --foreignKey=VALUE | 关联外键 |
| | --primaryKey=VALUE | 关联主键 |
| | --relationOnlyFileds=VALUE | 关联模型中只显示的字段 |
| | --relationBindSelect=VALUE | 关联模型中的字段用于主表外键的表单下拉选择 |
| | --relationModelFilename=VALUE | 关联模型文件名 |

21
LICENSE
View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2020 EasyAdmin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

32
LICENSE.txt Normal file
View File

@@ -0,0 +1,32 @@
ThinkPHP遵循Apache2开源协议发布并提供免费使用。
版权所有Copyright © 2006-2023 by ThinkPHP (http://thinkphp.cn)
All rights reserved。
ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。
Apache Licence是著名的非盈利开源组织Apache采用的协议。
该协议和BSD类似鼓励代码共享和尊重原作者的著作权
允许代码修改,再作为开源或商业软件发布。需要满足
的条件:
1 需要给代码的用户一份Apache Licence
2 如果你修改了代码,需要在被修改的文件中说明;
3 在延伸的代码中(修改和有源代码衍生的代码中)需要
带有原来代码中的协议,商标,专利声明和其他原来作者规
定需要包含的说明;
4 如果再发布的产品中包含一个Notice文件则在Notice文
件中需要带有本协议内容。你可以在Notice中增加自己的
许可但不可以表现为对Apache Licence构成更改。
具体的协议参考http://www.apache.org/licenses/LICENSE-2.0
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1 +0,0 @@
# EasyAdmin8

View File

@@ -20,6 +20,10 @@
>
>【如果不能访问,可以自行本地搭建预览或参考下方界面预览图】
## 大版本更新记录:
[更新记录](log.md)
## 安装教程
> EasyAdmin8 使用 Composer 来管理项目依赖。因此,在使用 EasyAdmin8 之前,请确保你的机器已经安装了 Composer。

22
app/AppService.php Normal file
View File

@@ -0,0 +1,22 @@
<?php
declare (strict_types = 1);
namespace app;
use think\Service;
/**
* 应用服务类
*/
class AppService extends Service
{
public function register()
{
// 服务注册
}
public function boot()
{
// 服务启动
}
}

View File

@@ -64,7 +64,7 @@ abstract class BaseController
* @return array|string|true
* @throws ValidateException
*/
protected function validate(array $data, $validate, array $message = [], bool $batch = false)
protected function validate(array $data, string|array $validate, array $message = [], bool $batch = false)
{
if (is_array($validate)) {
$v = new Validate();
@@ -72,7 +72,7 @@ abstract class BaseController
} else {
if (strpos($validate, '.')) {
// 支持场景
list($validate, $scene) = explode('.', $validate);
[$validate, $scene] = explode('.', $validate);
}
$class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
$v = new $class();

View File

@@ -1,11 +1,8 @@
<?php
namespace app;
// 应用请求对象类
class Request extends \think\Request
{
protected $filter = ['htmlspecialchars'];
}

View File

@@ -1,33 +1,24 @@
<?php
return [
// 不需要验证登录的控制器
'no_login_controller' => [
'login',
],
// 不需要验证登录的节点
'no_login_node' => [
'login/index',
'login/out',
],
// 后台路径地址 默认 admin
'alias_name' => env('EASYADMIN.ADMIN'),
// 不需要验证权限的控制器
'no_auth_controller' => [
'no_auth_controller' => [
'ajax',
'login',
'index',
],
// 不需要验证权限的节点
'no_auth_node' => [
'no_auth_node' => [
'login/index',
'login/out',
],
//上传类型
'upload_types' => [
'upload_types' => [
'local' => '本地存储',
'oss' => '阿里云oss',
'cos' => '腾讯云cos',
@@ -35,9 +26,10 @@ return [
],
// 默认编辑器
'editor_types' => [
'editor_types' => [
'ueditor' => '百度编辑器',
'ckeditor' => 'CK编辑器',
'wangEditor' => 'wangEditor',
],
];

View File

@@ -1,10 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | 应用设置
// +----------------------------------------------------------------------
use think\facade\Env;
return [
];

View File

@@ -1,10 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | 控制台配置
// +----------------------------------------------------------------------
return [
// 指令定义
'commands' => [
'alioss' => 'addons\alioss\command\Alioss',
],
];

View File

@@ -1,19 +1,28 @@
<?php
use app\admin\middleware\CheckInstall;
use app\admin\middleware\CheckLogin;
use app\admin\middleware\CheckAuth;
use app\admin\middleware\SystemLog;
// 你可以在这里继续写你需要的路由
// +----------------------------------------------------------------------
// | 路由设置
// | 这里只是路由的中间件
// | 至于为什么要把中间件配置写在这里呢??? Why???
// | 因为 ThinkPHP官方最新版本 已经不支持在中间件获取 controller 和 action 了
// +----------------------------------------------------------------------
return [
// 路由中间件
'middleware' => [
// // 后台视图初始化
// \app\admin\middleware\ViewInit::class,
// 检测用户是否登录
// \app\admin\middleware\CheckAdmin::class,
// 判断是否已经安装后台系统
CheckInstall::class,
// 检测是否登录
CheckLogin::class,
// 验证节点权限
CheckAuth::class,
// 操作日志
SystemLog::class,
],
];
];

View File

@@ -6,6 +6,7 @@ use app\admin\model\SystemUploadfile;
use app\admin\service\UploadService;
use app\common\controller\AdminController;
use app\common\service\MenuService;
use app\Request;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
@@ -25,28 +26,28 @@ class Ajax extends AdminController
*/
public function initAdmin(): Json
{
$cacheData = Cache::get('initAdmin_' . session('admin.id'));
$cacheData = Cache::get('initAdmin_' . $this->adminUid);
if (!empty($cacheData)) {
return json($cacheData);
}
$menuService = new MenuService(session('admin.id'));
$menuService = new MenuService($this->adminUid);
$data = [
'logoInfo' => [
'title' => sysconfig('site', 'logo_title'),
'image' => sysconfig('site', 'logo_image'),
'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_' . session('admin.id'), $data);
Cache::tag('initAdmin')->set('initAdmin_' . $this->adminUid, $data);
return json($data);
}
/**
* 清理缓存接口
*/
public function clearCache()
public function clearCache(): void
{
Cache::clear();
$this->success('清理缓存成功');
@@ -54,17 +55,19 @@ class Ajax extends AdminController
/**
* 上传文件
* @param Request $request
* @return void
*/
public function upload()
public function upload(Request $request): void
{
$this->isDemo && $this->error('演示环境下不允许修改');
$this->checkPostRequest();
$type = $this->request->param('type', '');
$type = $request->param('type', '');
$data = [
'upload_type' => $this->request->post('upload_type'),
'file' => $this->request->file($type == 'editor' ? 'upload' : 'file'),
'upload_type' => $request->post('upload_type'),
'file' => $request->file($type == 'editor' ? 'upload' : 'file'),
];
$uploadConfig = sysconfig('upload');
$uploadConfig = sysConfig('upload');
empty($data['upload_type']) && $data['upload_type'] = $uploadConfig['upload_type'];
$rule = [
'upload_type|指定上传类型有误' => "in:{$uploadConfig['upload_allow_type']}",
@@ -94,17 +97,18 @@ class Ajax extends AdminController
/**
* 获取上传文件列表
* @param Request $request
* @return Json
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function getUploadFiles(): Json
public function getUploadFiles(Request $request): Json
{
$get = $this->request->get();
$page = isset($get['page']) && !empty($get['page']) ? $get['page'] : 1;
$limit = isset($get['limit']) && !empty($get['limit']) ? $get['limit'] : 10;
$title = isset($get['title']) && !empty($get['title']) ? $get['title'] : null;
$get = $request->get();
$page = !empty($get['page']) ? $get['page'] : 1;
$limit = !empty($get['limit']) ? $get['limit'] : 10;
$title = !empty($get['title']) ? $get['title'] : null;
$this->model = new SystemUploadfile();
$count = $this->model
->where(function (Query $query) use ($title) {
@@ -117,7 +121,7 @@ class Ajax extends AdminController
})
->page($page, $limit)
->order($this->sort)
->select();
->select()->toArray();
$data = [
'code' => 0,
'msg' => '',
@@ -129,14 +133,15 @@ class Ajax extends AdminController
/**
* 百度编辑器上传
* @param Request $request
* @return Json
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function uploadUEditor(): Json
public function uploadUEditor(Request $request): Json
{
$uploadConfig = sysconfig('upload');
$uploadConfig = sysConfig('upload');
$upload_allow_size = $uploadConfig['upload_allow_size'];
$_upload_allow_ext = explode(',', $uploadConfig['upload_allow_ext']);
$upload_allow_ext = [];
@@ -171,8 +176,8 @@ class Ajax extends AdminController
"fileMaxSize" => $upload_allow_size,
"fileAllowFiles" => $upload_allow_ext,
];
$action = $this->request->param('action/s', '');
$file = $this->request->file('file');
$action = $request->param('action/s', '');
$file = $request->file('file');
$upload_type = $uploadConfig['upload_type'];
switch ($action) {
case 'image':

View File

@@ -5,27 +5,24 @@ namespace app\admin\controller;
use app\admin\model\SystemAdmin;
use app\admin\model\SystemQuick;
use app\common\controller\AdminController;
use app\Request;
use Exception;
use think\App;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;
use think\facade\Env;
class Index extends AdminController
{
/**
* 后台主页
* @param Request $request
* @return string
* @throws Exception
*/
public function index(): string
public function index(Request $request): string
{
return $this->fetch('', [
'admin' => session('admin'),
]);
return $this->fetch('', ['admin' => $request->adminUserInfo,]);
}
/**
@@ -50,20 +47,21 @@ class Index extends AdminController
/**
* 修改管理员信息
* @param Request $request
* @return string
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function editAdmin(): string
public function editAdmin(Request $request): string
{
$id = session('admin.id');
$id = $this->adminUid;
$row = (new SystemAdmin())
->withoutField('password')
->find($id);
empty($row) && $this->error('用户信息不存在');
if ($this->request->isPost()) {
$post = $this->request->post();
if ($request->isPost()) {
$post = $request->post();
$this->isDemo && $this->error('演示环境下不允许修改');
$rule = [];
$this->validate($post, $rule);
@@ -71,7 +69,7 @@ class Index extends AdminController
$save = $row
->allowField(['head_img', 'phone', 'remark', 'update_time'])
->save($post);
} catch (Exception $e) {
}catch (Exception $e) {
$this->error('保存失败');
}
$save ? $this->success('保存成功') : $this->error('保存失败');
@@ -82,22 +80,23 @@ class Index extends AdminController
/**
* 修改密码
* @param Request $request
* @return string
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function editPassword(): string
public function editPassword(Request $request): string
{
$id = session('admin.id');
$id = $this->adminUid;
$row = (new SystemAdmin())
->withoutField('password')
->find($id);
if (!$row) {
$this->error('用户信息不存在');
}
if ($this->request->isPost()) {
$post = $this->request->post();
if ($request->isPost()) {
$post = $request->post();
$this->isDemo && $this->error('演示环境下不允许修改');
$rule = [
'password|登录密码' => 'require',
@@ -110,14 +109,14 @@ class Index extends AdminController
try {
$save = $row->save([
'password' => password($post['password']),
]);
} catch (Exception $e) {
'password' => password($post['password']),
]);
}catch (Exception $e) {
$this->error('保存失败');
}
if ($save) {
$this->success('保存成功');
} else {
}else {
$this->error('保存失败');
}
}

View File

@@ -5,73 +5,70 @@ namespace app\admin\controller;
use app\admin\model\SystemAdmin;
use app\common\controller\AdminController;
use think\captcha\facade\Captcha;
use think\facade\Env;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use app\Request;
use think\Response;
/**
* Class Login
* @package app\admin\controller
*/
class Login extends AdminController
{
/**
* 初始化方法
*/
public function initialize()
protected bool $ignoreAuth = true;
public function initialize(): void
{
parent::initialize();
$action = $this->request->action();
if (!empty(session('admin')) && !in_array($action, ['out'])) {
$adminModuleName = config('app.admin_alias_name');
if (!empty($this->adminUid) && !in_array($action, ['out'])) {
$adminModuleName = config('admin.alias_name');
$this->success('已登录,无需再次登录', [], __url("@{$adminModuleName}"));
}
}
/**
* 用户登录
* @param Request $request
* @return string
* @throws \Exception
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function index(): string
public function index(Request $request): string
{
$captcha = Env::get('EASYADMIN.CAPTCHA', 1);
if ($this->request->isPost()) {
$post = $this->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($post['password']) != $admin->password) {
$this->error('密码输入有误');
}
if ($admin->status == 0) {
$this->error('账号已被禁用');
}
$admin->login_num += 1;
$admin->save();
$admin = $admin->toArray();
unset($admin['password']);
$admin['expire_time'] = $post['keep_login'] == 1 ? true : time() + 7200;
session('admin', $admin);
$this->success('登录成功');
$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('用户不存在');
}
$this->assign('captcha', $captcha);
$this->assign('demo', $this->isDemo);
return $this->fetch();
if (password($post['password']) != $admin->password) {
$this->error('密码输入有误');
}
if ($admin->status == 0) {
$this->error('账号已被禁用');
}
$admin->login_num += 1;
$admin->save();
$admin = $admin->toArray();
unset($admin['password']);
$admin['expire_time'] = $post['keep_login'] == 1 ? true : time() + 7200;
session('admin', $admin);
$this->success('登录成功');
}
/**
* 用户退出
*/
public function out()
public function out(): void
{
session('admin', null);
$this->success('退出登录成功');
@@ -83,6 +80,6 @@ class Login extends AdminController
*/
public function captcha(): Response
{
return Captcha::create();
return Captcha::instance()->create();
}
}

View File

@@ -3,7 +3,6 @@
namespace app\admin\controller\mall;
use app\admin\model\MallCate;
use app\admin\traits\Curd;
use app\common\controller\AdminController;
use app\admin\service\annotation\ControllerAnnotation;
use app\admin\service\annotation\NodeAnnotation;
@@ -17,8 +16,6 @@ use think\App;
class Cate extends AdminController
{
use Curd;
public function __construct(App $app)
{
parent::__construct($app);

View File

@@ -3,11 +3,13 @@
namespace app\admin\controller\mall;
use app\admin\model\MallGoods;
use app\admin\traits\Curd;
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\db\exception\DbException;
use think\response\Json;
/**
* Class Goods
@@ -17,8 +19,6 @@ use think\App;
class Goods extends AdminController
{
use Curd;
protected bool $relationSearch = true;
public function __construct(App $app)
@@ -29,10 +29,11 @@ class Goods extends AdminController
/**
* @NodeAnnotation(title="列表")
* @throws DbException
*/
public function index()
public function index(Request $request): Json|string
{
if ($this->request->isAjax()) {
if ($request->isAjax()) {
if (input('selectFields')) {
return $this->selectList();
}
@@ -46,7 +47,7 @@ class Goods extends AdminController
->where($where)
->page($page, $limit)
->order($this->sort)
->select();
->select()->toArray();
$data = [
'code' => 0,
'msg' => '',
@@ -61,19 +62,19 @@ class Goods extends AdminController
/**
* @NodeAnnotation(title="入库")
*/
public function stock($id)
public function stock(Request $request, $id): string
{
$row = $this->model->find($id);
empty($row) && $this->error('数据不存在');
if ($this->request->isPost()) {
$post = $this->request->post();
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) {
}catch (\Exception $e) {
$this->error('保存失败');
}
$save ? $this->success('保存成功') : $this->error('保存失败');

View File

@@ -8,7 +8,10 @@ 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\db\exception\DbException;
use think\response\Json;
/**
* Class Admin
@@ -18,8 +21,6 @@ use think\App;
class Admin extends AdminController
{
use \app\admin\traits\Curd;
protected array $sort = [
'sort' => 'desc',
'id' => 'desc',
@@ -34,10 +35,11 @@ class Admin extends AdminController
/**
* @NodeAnnotation(title="列表")
* @throws DbException
*/
public function index()
public function index(Request $request): Json|string
{
if ($this->request->isAjax()) {
if ($request->isAjax()) {
if (input('selectFields')) {
return $this->selectList();
}
@@ -50,7 +52,7 @@ class Admin extends AdminController
->where($where)
->page($page, $limit)
->order($this->sort)
->select();
->select()->toArray();
$data = [
'code' => 0,
'msg' => '',
@@ -65,11 +67,11 @@ class Admin extends AdminController
/**
* @NodeAnnotation(title="添加")
*/
public function add()
public function add(Request $request): string
{
if ($this->request->isPost()) {
$post = $this->request->post();
$authIds = $this->request->post('auth_ids', []);
if ($request->isPost()) {
$post = $request->post();
$authIds = $request->post('auth_ids', []);
$post['auth_ids'] = implode(',', array_keys($authIds));
$rule = [];
$this->validate($post, $rule);
@@ -77,7 +79,7 @@ class Admin extends AdminController
$post['password'] = password($post['password']);
try {
$save = $this->model->save($post);
} catch (\Exception $e) {
}catch (\Exception $e) {
$this->error('保存失败');
}
$save ? $this->success('保存成功') : $this->error('保存失败');
@@ -88,13 +90,13 @@ class Admin extends AdminController
/**
* @NodeAnnotation(title="编辑")
*/
public function edit($id)
public function edit(Request $request, $id = 0): string
{
$row = $this->model->find($id);
empty($row) && $this->error('数据不存在');
if ($this->request->isPost()) {
$post = $this->request->post();
$authIds = $this->request->post('auth_ids', []);
if ($request->isPost()) {
$post = $request->post();
$authIds = $request->post('auth_ids', []);
$post['auth_ids'] = implode(',', array_keys($authIds));
$rule = [];
$this->validate($post, $rule);
@@ -104,7 +106,7 @@ class Admin extends AdminController
try {
$save = $row->save($post);
TriggerService::updateMenu($id);
} catch (\Exception $e) {
}catch (\Exception $e) {
$this->error('保存失败');
}
$save ? $this->success('保存成功') : $this->error('保存失败');
@@ -117,12 +119,12 @@ class Admin extends AdminController
/**
* @NodeAnnotation(title="编辑")
*/
public function password($id)
public function password(Request $request, $id): string
{
$row = $this->model->find($id);
empty($row) && $this->error('数据不存在');
if ($this->request->isAjax()) {
$post = $this->request->post();
if ($request->isAjax()) {
$post = $request->post();
$rule = [
'password|登录密码' => 'require',
'password_again|确认密码' => 'require',
@@ -133,9 +135,9 @@ class Admin extends AdminController
}
try {
$save = $row->save([
'password' => password($post['password']),
]);
} catch (\Exception $e) {
'password' => password($post['password']),
]);
}catch (\Exception $e) {
$this->error('保存失败');
}
$save ? $this->success('保存成功') : $this->error('保存失败');
@@ -148,7 +150,7 @@ class Admin extends AdminController
/**
* @NodeAnnotation(title="删除")
*/
public function delete($id)
public function delete($id): void
{
$this->checkPostRequest();
$row = $this->model->whereIn('id', $id)->select();
@@ -161,7 +163,7 @@ class Admin extends AdminController
}
try {
$save = $row->delete();
} catch (\Exception $e) {
}catch (\Exception $e) {
$this->error('删除失败');
}
$save ? $this->success('删除成功') : $this->error('删除失败');
@@ -170,14 +172,14 @@ class Admin extends AdminController
/**
* @NodeAnnotation(title="属性修改")
*/
public function modify()
public function modify(Request $request): void
{
$this->checkPostRequest();
$post = $this->request->post();
$post = $request->post();
$rule = [
'id|ID' => 'require',
'id|ID' => 'require',
'field|字段' => 'require',
'value|值' => 'require',
'value|值' => 'require',
];
$this->validate($post, $rule);
if (!in_array($post['field'], $this->allowModifyFields)) {
@@ -190,9 +192,9 @@ class Admin extends AdminController
empty($row) && $this->error('数据不存在');
try {
$row->save([
$post['field'] => $post['value'],
]);
} catch (\Exception $e) {
$post['field'] => $post['value'],
]);
}catch (\Exception $e) {
$this->error($e->getMessage());
}
$this->success('保存成功');

View File

@@ -8,6 +8,7 @@ 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;
/**
@@ -18,8 +19,6 @@ use think\App;
class Auth extends AdminController
{
use \app\admin\traits\Curd;
protected array $sort = [
'sort' => 'desc',
'id' => 'desc',
@@ -34,11 +33,11 @@ class Auth extends AdminController
/**
* @NodeAnnotation(title="授权")
*/
public function authorize($id)
public function authorize(Request $request, $id): string
{
$row = $this->model->find($id);
empty($row) && $this->error('数据不存在');
if ($this->request->isAjax()) {
if ($request->isAjax()) {
$list = $this->model->getAuthorizeNodeListByAdminId($id);
$this->success('获取成功', $list);
}
@@ -49,11 +48,11 @@ class Auth extends AdminController
/**
* @NodeAnnotation(title="授权保存")
*/
public function saveAuthorize()
public function saveAuthorize(Request $request): void
{
$this->checkPostRequest();
$id = $this->request->post('id');
$node = $this->request->post('node', "[]");
$id = $request->post('id');
$node = $request->post('node', "[]");
$node = json_decode($node, true);
$row = $this->model->find($id);
empty($row) && $this->error('数据不存在');
@@ -71,7 +70,7 @@ class Auth extends AdminController
$authNode->saveAll($saveAll);
}
TriggerService::updateMenu();
} catch (\Exception $e) {
}catch (\Exception $e) {
$this->error('保存失败');
}
$this->success('保存成功');

View File

@@ -7,7 +7,9 @@ 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\response\Json;
/**
* Class Config
@@ -28,7 +30,7 @@ class Config extends AdminController
/**
* @NodeAnnotation(title="列表")
*/
public function index()
public function index(Request $request): Json|string
{
return $this->fetch();
}
@@ -36,10 +38,10 @@ class Config extends AdminController
/**
* @NodeAnnotation(title="保存")
*/
public function save()
public function save(Request $request): void
{
$this->checkPostRequest();
$post = $this->request->post();
$post = $request->post();
$notAddFields = ['_token', 'file', 'group'];
try {
$group = $post['group'] ?? '';
@@ -53,7 +55,7 @@ class Config extends AdminController
if (in_array($key, $notAddFields)) continue;
if ($this->model->where('name', $key)->count()) {
$this->model->where('name', $key)->update(['value' => $val,]);
} else {
}else {
$this->model->create(
[
'name' => $key,
@@ -63,8 +65,8 @@ class Config extends AdminController
}
}
TriggerService::updateMenu();
TriggerService::updateSysconfig();
} catch (\Exception $e) {
TriggerService::updatesysConfig();
}catch (\Exception $e) {
$this->error('保存失败');
}
$this->success('保存成功');

View File

@@ -23,7 +23,7 @@ class CurdGenerate extends AdminController
/**
* @NodeAnnotation(title="列表")
*/
public function index()
public function index(Request $request): Json|string
{
return $this->fetch();
}
@@ -74,7 +74,7 @@ class CurdGenerate extends AdminController
$_fileExp_last = array_slice($_fileExp, -2);
$_fileExp_last_0 = $_fileExp_last[0] . '.';
if ($_fileExp_last[0] == 'controller') $_fileExp_last_0 = '';
$link = '/' . env('EASYADMIN.ADMIN', 'admin') . '/' . $_fileExp_last_0 . Str::snake(explode('.php', end($_fileExp_last))[0] ?? '') . '/index';
$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) {

View File

@@ -4,15 +4,16 @@ namespace app\admin\controller\system;
use app\admin\model\SystemLog;
use app\admin\service\tool\CommonTool;
use app\admin\traits\Curd;
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="操作日志管理")
@@ -21,7 +22,6 @@ use think\facade\Db;
*/
class Log extends AdminController
{
use Curd;
public function __construct(App $app)
{
@@ -32,9 +32,9 @@ class Log extends AdminController
/**
* @NodeAnnotation(title="列表")
*/
public function index()
public function index(Request $request): Json|string
{
if ($this->request->isAjax()) {
if ($request->isAjax()) {
if (input('selectFields')) {
return $this->selectList();
}
@@ -44,7 +44,7 @@ class Log extends AdminController
try {
$count = $model->count();
$list = $model->page($page, $limit)->order($this->sort)->select();
} catch (PDOException|DbException $exception) {
}catch (PDOException|DbException $exception) {
$count = 0;
$list = [];
}
@@ -62,7 +62,7 @@ class Log extends AdminController
/**
* @NodeAnnotation(title="导出")
*/
public function export()
public function export(): bool
{
if (env('EASYADMIN.IS_DEMO', false)) {
$this->error('演示环境下不允许操作');
@@ -88,7 +88,7 @@ class Log extends AdminController
->order('id', 'desc')
->select()
->toArray();
} catch (PDOException|DbException $exception) {
}catch (PDOException|DbException $exception) {
$this->error($exception->getMessage());
}
$fileName = time();

View File

@@ -5,12 +5,14 @@ namespace app\admin\controller\system;
use app\admin\model\SystemMenu;
use app\admin\model\SystemNode;
use app\admin\service\TriggerService;
use app\admin\traits\Curd;
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\db\exception\DbException;
use think\response\Json;
/**
* Class Menu
@@ -20,8 +22,6 @@ use think\App;
class Menu extends AdminController
{
use Curd;
protected array $sort = [
'sort' => 'desc',
'id' => 'asc',
@@ -35,15 +35,16 @@ class Menu extends AdminController
/**
* @NodeAnnotation(title="列表")
* @throws DbException
*/
public function index()
public function index(Request $request): Json|string
{
if ($this->request->isAjax()) {
if ($request->isAjax()) {
if (input('selectFields')) {
return $this->selectList();
}
$count = $this->model->count();
$list = $this->model->order($this->sort)->select();
$list = $this->model->order($this->sort)->select()->toArray();
$data = [
'code' => 0,
'msg' => '',
@@ -58,14 +59,15 @@ class Menu extends AdminController
/**
* @NodeAnnotation(title="添加")
*/
public function add($id = null)
public function add(Request $request): string
{
$id = $request->param('id');
$homeId = $this->model->where(['pid' => MenuConstant::HOME_PID,])->value('id');
if ($id == $homeId) {
$this->error('首页不能添加子菜单');
}
if ($this->request->isPost()) {
$post = $this->request->post();
if ($request->isPost()) {
$post = $request->post();
$rule = [
'pid|上级菜单' => 'require',
'title|菜单名称' => 'require',
@@ -74,13 +76,13 @@ class Menu extends AdminController
$this->validate($post, $rule);
try {
$save = $this->model->save($post);
} catch (\Exception $e) {
}catch (\Exception $e) {
$this->error('保存失败');
}
if ($save) {
TriggerService::updateMenu();
$this->success('保存成功');
} else {
}else {
$this->error('保存失败');
}
}
@@ -93,12 +95,12 @@ class Menu extends AdminController
/**
* @NodeAnnotation(title="编辑")
*/
public function edit($id)
public function edit(Request $request, $id = 0): string
{
$row = $this->model->find($id);
empty($row) && $this->error('数据不存在');
if ($this->request->isPost()) {
$post = $this->request->post();
if ($request->isPost()) {
$post = $request->post();
$rule = [
'pid|上级菜单' => 'require',
'title|菜单名称' => 'require',
@@ -108,42 +110,42 @@ class Menu extends AdminController
if ($row->pid == MenuConstant::HOME_PID) $post['pid'] = MenuConstant::HOME_PID;
try {
$save = $row->save($post);
} catch (\Exception $e) {
}catch (\Exception $e) {
$this->error('保存失败');
}
if (!empty($save)) {
TriggerService::updateMenu();
$this->success('保存成功');
} else {
}else {
$this->error('保存失败');
}
}
$pidMenuList = $this->model->getPidMenuList();
$this->assign([
'id' => $id,
'pidMenuList' => $pidMenuList,
'row' => $row,
]);
'id' => $id,
'pidMenuList' => $pidMenuList,
'row' => $row,
]);
return $this->fetch();
}
/**
* @NodeAnnotation(title="删除")
*/
public function delete($id)
public function delete($id): void
{
$this->checkPostRequest();
$row = $this->model->whereIn('id', $id)->select();
empty($row) && $this->error('数据不存在');
try {
$save = $row->delete();
} catch (\Exception $e) {
}catch (\Exception $e) {
$this->error('删除失败');
}
if ($save) {
TriggerService::updateMenu();
$this->success('删除成功');
} else {
}else {
$this->error('删除失败');
}
}
@@ -151,14 +153,14 @@ class Menu extends AdminController
/**
* @NodeAnnotation(title="属性修改")
*/
public function modify()
public function modify(Request $request): void
{
$this->checkPostRequest();
$post = $this->request->post();
$post = $request->post();
$rule = [
'id|ID' => 'require',
'id|ID' => 'require',
'field|字段' => 'require',
'value|值' => 'require',
'value|值' => 'require',
];
$this->validate($post, $rule);
$row = $this->model->find($post['id']);
@@ -170,17 +172,17 @@ class Menu extends AdminController
}
$homeId = $this->model
->where([
'pid' => MenuConstant::HOME_PID,
])
'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) {
$post['field'] => $post['value'],
]);
}catch (\Exception $e) {
$this->error($e->getMessage());
}
TriggerService::updateMenu();
@@ -190,18 +192,18 @@ class Menu extends AdminController
/**
* @NodeAnnotation(title="添加菜单提示")
*/
public function getMenuTips()
public function getMenuTips(): Json
{
$node = input('get.keywords');
$list = SystemNode::whereLike('node', "%{$node}%")
->field('node,title')
->limit(10)
->select();
->select()->toArray();
return json([
'code' => 0,
'content' => $list,
'type' => 'success',
]);
'code' => 0,
'content' => $list,
'type' => 'success',
]);
}
}

View File

@@ -8,7 +8,10 @@ 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\DbException;
use think\response\Json;
/**
* @ControllerAnnotation(title="系统节点管理")
@@ -18,8 +21,6 @@ use think\App;
class Node extends AdminController
{
use \app\admin\traits\Curd;
public function __construct(App $app)
{
parent::__construct($app);
@@ -28,10 +29,11 @@ class Node extends AdminController
/**
* @NodeAnnotation(title="列表")
* @throws DbException
*/
public function index()
public function index(Request $request): Json|string
{
if ($this->request->isAjax()) {
if ($request->isAjax()) {
if (input('selectFields')) {
return $this->selectList();
}
@@ -86,7 +88,7 @@ class Node extends AdminController
}
$model->saveAll($nodeList);
TriggerService::updateNode();
} catch (\Exception $e) {
}catch (\Exception $e) {
$this->error('节点更新失败');
}
$this->success('节点更新成功');
@@ -107,7 +109,7 @@ class Node extends AdminController
!isset($formatNodeList[$vo['node']]) && $model->where('id', $vo['id'])->delete();
}
TriggerService::updateNode();
} catch (\Exception $e) {
}catch (\Exception $e) {
$this->error('节点更新失败');
}
$this->success('节点更新成功');

View File

@@ -17,8 +17,6 @@ use think\App;
class Quick extends AdminController
{
use \app\admin\traits\Curd;
protected array $sort = [
'sort' => 'desc',
'id' => 'desc',

View File

@@ -10,14 +10,11 @@ use think\App;
/**
* @ControllerAnnotation(title="上传文件管理")
* Class Uploadfile
* @package app\admin\controller\system
*/
class Uploadfile extends AdminController
{
use \app\admin\traits\Curd;
public function __construct(App $app)
{
parent::__construct($app);

View File

@@ -1,21 +0,0 @@
<?php
// 事件定义文件
return [
'bind' => [
],
'listen' => [
'AppInit' => [
\app\admin\listener\ViewInitListener::class,
],
'HttpRun' => [
\app\admin\listener\ViewInitListener::class,
],
'HttpEnd' => [],
'LogLevel' => [],
'LogWrite' => [],
],
'subscribe' => [
],
];

View File

@@ -1,23 +1,5 @@
<?php
// 全局中间件定义文件
return [
// Session初始化
\think\middleware\SessionInit::class,
// 系统操作日志
\app\admin\middleware\SystemLog::class,
// Csrf安全校验
\app\admin\middleware\CsrfMiddleware::class,
// 后台视图初始化
// \app\admin\middleware\ViewInit::class,
// 检测用户是否登录
// \app\admin\middleware\CheckAdmin::class,
// 检测是否已经安装程序
\app\admin\middleware\CheckInstall::class,
// ...
];

View File

@@ -1,57 +0,0 @@
<?php
namespace app\admin\middleware;
use app\common\service\AuthService;
use think\Request;
/**
* @deprecated 废弃新版TP不支持在中间件获取控制器相关信息
* 检测用户登录和节点权限
* Class CheckAdmin
* @package app\admin\middleware
*/
class CheckAdmin
{
use \app\common\traits\JumpTrait;
public function handle(Request $request, \Closure $next)
{
$adminConfig = config('admin');
$adminId = session('admin.id');
$expireTime = session('admin.expire_time');
/** @var AuthService $authService */
$authService = app(AuthService::class, ['adminId' => $adminId]);
$currentNode = $authService->getCurrentNode();
$currentController = parse_name($request->controller());
// 验证登录
if (!in_array($currentController, $adminConfig['no_login_controller']) &&
!in_array($currentNode, $adminConfig['no_login_node'])) {
empty($adminId) && $this->error('请先登录后台', [], __url('admin/login/index'));
// 判断是否登录过期
if ($expireTime !== true && time() > $expireTime) {
session('admin', null);
$this->error('登录已过期,请重新登录', [], __url('admin/login/index'));
}
}
// 验证权限
if (!in_array($currentController, $adminConfig['no_auth_controller']) &&
!in_array($currentNode, $adminConfig['no_auth_node'])) {
$check = $authService->checkNode($currentNode);
!$check && $this->error('无权限访问');
// 判断是否为演示环境
if(env('EASYADMIN.IS_DEMO', false) && $request->isPost()){
$this->error('演示环境下不允许修改');
}
}
return $next($request);
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace app\admin\middleware;
use app\common\service\AuthService;
use app\common\traits\JumpTrait;
use Closure;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
class CheckAuth
{
use JumpTrait;
/**
* @throws ModelNotFoundException
* @throws DbException
* @throws DataNotFoundException
*/
public function handle($request, Closure $next)
{
$adminUserInfo = $request->adminUserInfo;
if (empty($adminUserInfo)) return $next($request);
$adminConfig = config('admin');
$adminId = $adminUserInfo['id'];
$authService = app(AuthService::class, ['adminId' => $adminId]);
$currentNode = $authService->getCurrentNode();
$currentController = parse_name($request->controller());
if (!in_array($currentController, $adminConfig['no_auth_controller']) && !in_array($currentNode, $adminConfig['no_auth_node'])) {
$check = $authService->checkNode($currentNode);
!$check && $this->error('无权限访问');
// 判断是否为演示环境
if (env('EASYADMIN.IS_DEMO', false) && $request->isPost()) {
$this->error('演示环境下不允许修改');
}
}
return $next($request);
}
}

View File

@@ -2,18 +2,17 @@
namespace app\admin\middleware;
use app\Request;
use app\common\traits\JumpTrait;
use Closure;
/**
* 检测是否安装成功
* 系统安装后可以在 config/route 中删除该中间件判定
*/
class CheckInstall
{
public function handle(Request $request, \Closure $next)
use JumpTrait;
public function handle($request, Closure $next)
{
$controller = $request->controller();
if (!is_file(ROOT_PATH . 'config' . DS . 'install' . DS . 'lock' . DS . 'install.lock')) {
if (!is_file(root_path() . 'config' . DIRECTORY_SEPARATOR . 'install' . DIRECTORY_SEPARATOR . 'lock' . DIRECTORY_SEPARATOR . 'install.lock')) {
if ($controller != 'Install') return redirect('/install');
}
return $next($request);

View File

@@ -0,0 +1,46 @@
<?php
namespace app\admin\middleware;
use app\common\traits\JumpTrait;
use Closure;
use ReflectionClass;
use ReflectionException;
class CheckLogin
{
use JumpTrait;
/**
* @throws ReflectionException
*/
public function handle($request, Closure $next)
{
$controller = $request->controller();
if (empty($controller)) return $next($request);
if (str_contains($controller, '.')) $controller = str_replace('.', '\\', $controller);
$action = $request->action();
$controllerClass = 'app\\admin\\controller\\' . $controller;
$classObj = new ReflectionClass($controllerClass);
$properties = $classObj->getDefaultProperties();
$ignoreAuth = $properties['ignoreAuth'] ?? false;
$adminUserInfo = session('admin');
if (!$ignoreAuth) {
$noNeedCheck = $properties['noNeedCheck'] ?? [];
if (in_array($action, $noNeedCheck)) {
return $next($request);
}
if (empty($adminUserInfo)) {
return redirect(__url('login/index'));
}
// 判断是否登录过期
$expireTime = $adminUserInfo['expire_time'];
if ($expireTime !== true && time() > $expireTime) {
session('admin', null);
$this->error('登录已过期,请重新登录', [], __url('admin/login/index'));
}
}
$request->adminUserInfo = $adminUserInfo ?: [];
return $next($request);
}
}

View File

@@ -1,40 +0,0 @@
<?php
namespace app\admin\middleware;
use app\Request;
use CsrfVerify\drive\ThinkphpCache;
use CsrfVerify\entity\CsrfVerifyEntity;
use CsrfVerify\interfaces\CsrfVerifyInterface;
use think\facade\Session;
class CsrfMiddleware
{
use \app\common\traits\JumpTrait;
public function handle(Request $request, \Closure $next)
{
if (env('EASYADMIN.IS_CSRF', true)) {
if (in_array($request->method(), ['POST', 'DELETE'])) {
// 跨域校验
$refererUrl = $request->header('REFERER', null);
$refererInfo = parse_url($refererUrl);
$host = $request->host(true);
if (!isset($refererInfo['host']) || $refererInfo['host'] != $host) {
$this->error('当前请求不合法!');
}
// CSRF校验
// @todo 兼容CK编辑器上传功能
$ckCsrfToken = $request->post('ckCsrfToken');
$data = !empty($ckCsrfToken) ? ['__token__' => $ckCsrfToken] : [];
$check = $request->checkToken('__token__', $data);
if (!$check) {
$this->error('请求验证失败,请重新刷新页面!');
}
}
}
return $next($request);
}
}

View File

@@ -5,36 +5,30 @@ namespace app\admin\middleware;
use app\admin\service\annotation\ControllerAnnotation;
use app\admin\service\annotation\NodeAnnotation;
use app\admin\service\SystemLogService;
use app\Request;
use app\admin\service\tool\CommonTool;
use app\common\traits\JumpTrait;
use Closure;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Annotations\DocParser;
/**
* 系统操作日志中间件
* Class SystemLog
* @package app\admin\middleware
*/
class SystemLog
{
use JumpTrait;
/**
* 敏感信息字段,日志记录时需要加密
* @var array
*/
protected $sensitiveParams = [
protected array $sensitiveParams = [
'password',
'password_again',
'phone',
'mobile',
];
public function handle(Request $request, \Closure $next)
public function handle($request, Closure $next)
{
$params = $request->param();
if (isset($params['s'])) {
unset($params['s']);
}
if (isset($params['s'])) unset($params['s']);
foreach ($params as $key => $val) {
in_array($key, $this->sensitiveParams) && $params[$key] = "***********";
}
@@ -44,7 +38,7 @@ class SystemLog
if (env('APP_DEBUG')) {
trace(['url' => $url, 'method' => $method, 'params' => $params,], 'requestDebugInfo');
}
$response = $next($request);
if ($request->isAjax()) {
if (in_array($method, ['post', 'put', 'delete'])) {
$title = '';
@@ -66,9 +60,9 @@ class SystemLog
$nodeAnnotation = $reader->getMethodAnnotation($reflectionAction, NodeAnnotation::class);
$title = $controllerAnnotation->title . ' - ' . $nodeAnnotation->title;
}
} catch (\Throwable $exception) {
}catch (\Throwable $exception) {
}
$ip = CommonTool::getRealIp();
$ip = $request->server('HTTP_X_FORWARDED_FOR', $request->ip());
$data = [
'admin_id' => session('admin.id'),
'title' => $title,
@@ -76,13 +70,13 @@ class SystemLog
'method' => $method,
'ip' => $ip,
'content' => json_encode($params, JSON_UNESCAPED_UNICODE),
'useragent' => $_SERVER['HTTP_USER_AGENT'],
'response' => json_encode($response->getData(), JSON_UNESCAPED_UNICODE),
'useragent' => $request->server('HTTP_USER_AGENT'),
'create_time' => time(),
];
SystemLogService::instance()->save($data);
}
}
return $next($request);
return $response;
}
}

View File

@@ -1,47 +0,0 @@
<?php
namespace app\admin\middleware;
use app\admin\service\ConfigService;
use app\common\constants\AdminConstant;
use think\App;
use think\facade\Request;
use think\facade\View;
/**
* @deprecated 废弃新版TP不支持在中间件获取控制器相关信息
* Class ViewInit
* @package app\admin\middleware
*/
class ViewInit
{
public function handle(\app\Request $request, \Closure $next)
{
list($thisModule, $thisController, $thisAction) = [app('http')->getName(), Request::controller(), $request->action()];
list($thisControllerArr, $jsPath) = [explode('.', $thisController), null];
foreach ($thisControllerArr as $vo) {
empty($jsPath) ? $jsPath = parse_name($vo) : $jsPath .= '/' . parse_name($vo);
}
$autoloadJs = file_exists(root_path('public')."static/{$thisModule}/js/{$jsPath}.js") ? true : false;
$thisControllerJsPath = "{$thisModule}/js/{$jsPath}.js";
$adminModuleName = config('app.admin_alias_name');
$isSuperAdmin = session('admin.id') == AdminConstant::SUPER_ADMIN_ID ? true : false;
$data = [
'adminModuleName' => $adminModuleName,
'thisController' => parse_name($thisController),
'thisAction' => $thisAction,
'thisRequest' => parse_name("{$thisModule}/{$thisController}/{$thisAction}"),
'thisControllerJsPath' => "{$thisControllerJsPath}",
'autoloadJs' => $autoloadJs,
'isSuperAdmin' => $isSuperAdmin,
'version' => env('APP_DEBUG') ? time() : ConfigService::getVersion(),
];
View::assign($data);
$request->adminModuleName = $adminModuleName;
return $next($request);
}
}

View File

@@ -11,7 +11,7 @@ class ConfigService
{
$version = cache('version');
if (empty($version)) {
$version = sysconfig('site', 'site_version');
$version = sysConfig('site', 'site_version');
cache('site_version', $version);
Cache::set('version', $version, 3600);
}

View File

@@ -15,29 +15,25 @@ use think\facade\Env;
class SystemLogService
{
/**
* 当前实例
* @var object
*/
protected static $instance;
protected static ?SystemLogService $instance = null;
/**
* 表前缀
* @var string
*/
protected $tablePrefix;
protected string $tablePrefix;
/**
* 表后缀
* @var string
*/
protected $tableSuffix;
protected string $tableSuffix;
/**
* 表名
* @var string
*/
protected $tableName;
protected string $tableName;
/**
* 构造方法
@@ -69,14 +65,14 @@ class SystemLogService
* @param $data
* @return bool|string
*/
public function save($data)
public function save($data): bool|string
{
Db::startTrans();
try {
$this->detectTable();
Db::table($this->tableName)->insert($data);
Db::table($this->tableName)->strict(false)->insert($data);
Db::commit();
} catch (\Exception $e) {
}catch (\Exception $e) {
Db::rollback();
return $e->getMessage();
}
@@ -119,7 +115,8 @@ CREATE TABLE `{$this->tableName}` (
`url` varchar(1500) NOT NULL DEFAULT '' COMMENT '操作页面',
`method` varchar(50) NOT NULL COMMENT '请求方法',
`title` varchar(100) DEFAULT '' COMMENT '日志标题',
`content` text NOT NULL COMMENT '内容',
`content` json NOT NULL COMMENT '请求数据',
`response` json DEFAULT NULL COMMENT '回调数据',
`ip` varchar(50) NOT NULL DEFAULT '' COMMENT 'IP',
`useragent` varchar(255) DEFAULT '' COMMENT 'User-Agent',
`create_time` int(10) DEFAULT NULL COMMENT '操作时间',

View File

@@ -41,7 +41,7 @@ class TriggerService
* 更新系统设置缓存
* @return bool
*/
public static function updateSysconfig()
public static function updatesysConfig()
{
Cache::tag('sysconfig')->clear();
return true;

View File

@@ -2,12 +2,14 @@
namespace app\admin\service\auth;
use Doctrine\Common\Annotations\AnnotationException;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Annotations\AnnotationRegistry;
use Doctrine\Common\Annotations\DocParser;
use app\admin\service\annotation\ControllerAnnotation;
use app\admin\service\annotation\NodeAnnotation;
use app\admin\service\tool\CommonTool;
use ReflectionException;
/**
* 节点处理类
@@ -20,12 +22,12 @@ class Node
/**
* @var string 当前文件夹
*/
protected $basePath;
protected string $basePath;
/**
* @var string 命名空间前缀
*/
protected $baseNamespace;
protected string $baseNamespace;
/**
* 构造方法
@@ -33,7 +35,7 @@ class Node
* @param string $basePath 读取的文件夹
* @param string $baseNamespace 读取的命名空间前缀
*/
public function __construct($basePath, $baseNamespace)
public function __construct(string $basePath, string $baseNamespace)
{
$this->basePath = $basePath;
$this->baseNamespace = $baseNamespace;
@@ -43,8 +45,8 @@ class Node
/**
* 获取所有节点
* @return array
* @throws \Doctrine\Common\Annotations\AnnotationException
* @throws \ReflectionException
* @throws AnnotationException
* @throws ReflectionException
*/
public function getNodeList(): array
{
@@ -67,9 +69,9 @@ class Node
foreach ($methods as $method) {
// 读取NodeAnnotation的注解
$nodeAnnotation = $reader->getMethodAnnotation($method, NodeAnnotation::class);
if (!empty($nodeAnnotation) && !empty($nodeAnnotation->title)) {
$actionTitle = !empty($nodeAnnotation) && !empty($nodeAnnotation->title) ? $nodeAnnotation->title : null;
$actionAuth = !empty($nodeAnnotation) && !empty($nodeAnnotation->auth) ? $nodeAnnotation->auth : false;
if (!empty($nodeAnnotation)) {
$actionTitle = !empty($nodeAnnotation->title) ? $nodeAnnotation->title : null;
$actionAuth = !empty($nodeAnnotation->auth) ? $nodeAnnotation->auth : false;
$actionList[] = [
'node' => $controllerFormat . '/' . $method->name,
'title' => $actionTitle,
@@ -82,8 +84,8 @@ class Node
if (!empty($actionList)) {
// 读取Controller的注解
$controllerAnnotation = $reader->getClassAnnotation($reflectionClass, ControllerAnnotation::class);
$controllerTitle = !empty($controllerAnnotation) && !empty($controllerAnnotation->title) ? $controllerAnnotation->title : null;
$controllerAuth = !empty($controllerAnnotation) && !empty($controllerAnnotation->auth) ? $controllerAnnotation->auth : false;
$controllerTitle = !empty($controllerAnnotation->title) ? $controllerAnnotation->title : null;
$controllerAuth = !empty($controllerAnnotation->auth) ? $controllerAnnotation->auth : false;
$nodeList[] = [
'node' => $controllerFormat,
'title' => $controllerTitle,
@@ -102,7 +104,7 @@ class Node
* 获取所有控制器
* @return array
*/
public function getControllerList()
public function getControllerList(): array
{
return $this->readControllerFiles($this->basePath);
}
@@ -112,10 +114,10 @@ class Node
* @param $path
* @return array
*/
protected function readControllerFiles($path)
protected function readControllerFiles($path): array
{
list($list, $temp_list, $dirExplode) = [[], scandir($path), explode($this->basePath, $path)];
$middleDir = isset($dirExplode[1]) && !empty($dirExplode[1]) ? str_replace('/', '\\', substr($dirExplode[1], 1)) . "\\" : '';
$middleDir = !empty($dirExplode[1]) ? str_replace('/', '\\', substr($dirExplode[1], 1)) . "\\" : '';
foreach ($temp_list as $file) {
// 排除根目录和没有开启注解的模块
@@ -126,7 +128,7 @@ class Node
// 子文件夹,进行递归
$childFiles = $this->readControllerFiles($path . DIRECTORY_SEPARATOR . $file);
$list = array_merge($childFiles, $list);
} else {
}else {
// 判断是不是控制器
$fileExplodeArray = explode('.', $file);
if (count($fileExplodeArray) != 2 || end($fileExplodeArray) != 'php') {

View File

@@ -5,11 +5,11 @@ namespace app\admin\service\console;
class CliEcho
{
private $foreground_colors = [];
private array $foreground_colors = [];
private $background_colors = [];
private array $background_colors = [];
private static $foregroundColors = [
private static array $foregroundColors = [
'black' => '0;30',
'dark_gray' => '1;30',
'blue' => '0;34',
@@ -42,57 +42,57 @@ class CliEcho
public function __construct()
{
// Set up shell colors
$this->foreground_colors['black'] = '0;30';
$this->foreground_colors['dark_gray'] = '1;30';
$this->foreground_colors['blue'] = '0;34';
$this->foreground_colors['light_blue'] = '1;34';
$this->foreground_colors['green'] = '0;32';
$this->foreground_colors['light_green'] = '1;32';
$this->foreground_colors['cyan'] = '0;36';
$this->foreground_colors['light_cyan'] = '1;36';
$this->foreground_colors['red'] = '0;31';
$this->foreground_colors['light_red'] = '1;31';
$this->foreground_colors['purple'] = '0;35';
$this->foreground_colors['black'] = '0;30';
$this->foreground_colors['dark_gray'] = '1;30';
$this->foreground_colors['blue'] = '0;34';
$this->foreground_colors['light_blue'] = '1;34';
$this->foreground_colors['green'] = '0;32';
$this->foreground_colors['light_green'] = '1;32';
$this->foreground_colors['cyan'] = '0;36';
$this->foreground_colors['light_cyan'] = '1;36';
$this->foreground_colors['red'] = '0;31';
$this->foreground_colors['light_red'] = '1;31';
$this->foreground_colors['purple'] = '0;35';
$this->foreground_colors['light_purple'] = '1;35';
$this->foreground_colors['brown'] = '0;33';
$this->foreground_colors['yellow'] = '1;33';
$this->foreground_colors['light_gray'] = '0;37';
$this->foreground_colors['white'] = '1;37';
$this->background_colors['black'] = '40';
$this->background_colors['red'] = '41';
$this->background_colors['green'] = '42';
$this->background_colors['yellow'] = '43';
$this->background_colors['blue'] = '44';
$this->background_colors['magenta'] = '45';
$this->background_colors['cyan'] = '46';
$this->background_colors['light_gray'] = '47';
$this->foreground_colors['brown'] = '0;33';
$this->foreground_colors['yellow'] = '1;33';
$this->foreground_colors['light_gray'] = '0;37';
$this->foreground_colors['white'] = '1;37';
$this->background_colors['black'] = '40';
$this->background_colors['red'] = '41';
$this->background_colors['green'] = '42';
$this->background_colors['yellow'] = '43';
$this->background_colors['blue'] = '44';
$this->background_colors['magenta'] = '45';
$this->background_colors['cyan'] = '46';
$this->background_colors['light_gray'] = '47';
}
// Returns colored string
public function getColoredString($string, $foreground_color = null, $background_color = null, $new_line = false)
public function getColoredString($string, $foreground_color = null, $background_color = null, $new_line = false): string
{
$colored_string = '';
// Check if given foreground color found
if (isset($this->foreground_colors[$foreground_color])) {
$colored_string .= "\033[".$this->foreground_colors[$foreground_color].'m';
$colored_string .= "\033[" . $this->foreground_colors[$foreground_color] . 'm';
}
// Check if given background color found
if (isset($this->background_colors[$background_color])) {
$colored_string .= "\033[".$this->background_colors[$background_color].'m';
$colored_string .= "\033[" . $this->background_colors[$background_color] . 'm';
}
// Add string and end coloring
$colored_string .= $string."\033[0m";
return $new_line ? $colored_string.PHP_EOL : $colored_string;
$colored_string .= $string . "\033[0m";
return $new_line ? $colored_string . PHP_EOL : $colored_string;
}
// Returns all foreground color names
public function getForegroundColors()
public function getForegroundColors(): array
{
return array_keys($this->foreground_colors);
}
// Returns all background color names
public function getBackgroundColors()
public function getBackgroundColors(): array
{
return array_keys($this->background_colors);
}
@@ -100,25 +100,26 @@ class CliEcho
/**
* 获取带颜色的文字.
*
* @param string $string black|dark_gray|blue|light_blue|green|light_green|cyan|light_cyan|red|light_red|purple|brown|yellow|light_gray|white
* @param string $string black|dark_gray|blue|light_blue|green|light_green|cyan|light_cyan|red|light_red|purple|brown|yellow|light_gray|white
* @param string|null $foregroundColor 前景颜色 black|red|green|yellow|blue|magenta|cyan|light_gray
* @param string|null $backgroundColor 背景颜色 同$foregroundColor
*
* @return string
*/
public static function initColoredString(
$string,
$foregroundColor = null,
$backgroundColor = null
) {
string $string,
?string $foregroundColor = null,
?string $backgroundColor = null
): string
{
$coloredString = '';
if (isset(static::$foregroundColors[$foregroundColor])) {
$coloredString .= "\033[".static::$foregroundColors[$foregroundColor].'m';
$coloredString .= "\033[" . static::$foregroundColors[$foregroundColor] . 'm';
}
if (isset(static::$backgroundColors[$backgroundColor])) {
$coloredString .= "\033[".static::$backgroundColors[$backgroundColor].'m';
$coloredString .= "\033[" . static::$backgroundColors[$backgroundColor] . 'm';
}
$coloredString .= $string."\033[0m";
$coloredString .= $string . "\033[0m";
return $coloredString;
}
@@ -127,9 +128,9 @@ class CliEcho
*
* @param $msg
*/
public static function notice($msg)
public static function notice($msg): void
{
fwrite(STDOUT, self::initColoredString($msg, 'light_gray').PHP_EOL);
fwrite(STDOUT, self::initColoredString($msg, 'light_gray') . PHP_EOL);
}
/**
@@ -137,9 +138,9 @@ class CliEcho
*
* @param $msg
*/
public static function error($msg)
public static function error($msg): void
{
fwrite(STDERR, self::initColoredString($msg, 'white','red').PHP_EOL);
fwrite(STDERR, self::initColoredString($msg, 'white', 'red') . PHP_EOL);
}
/**
@@ -147,9 +148,9 @@ class CliEcho
*
* @param $msg
*/
public static function warn($msg)
public static function warn($msg): void
{
fwrite(STDOUT, self::initColoredString($msg, 'red','yellow').PHP_EOL);
fwrite(STDOUT, self::initColoredString($msg, 'red', 'yellow') . PHP_EOL);
}
/**
@@ -157,9 +158,9 @@ class CliEcho
*
* @param $msg
*/
public static function success($msg)
public static function success($msg): void
{
fwrite(STDOUT, self::initColoredString($msg, 'light_cyan').PHP_EOL);
fwrite(STDOUT, self::initColoredString($msg, 'light_cyan') . PHP_EOL);
}
}

View File

@@ -4,6 +4,7 @@ namespace app\admin\service\curd;
use app\admin\service\curd\exceptions\TableException;
use app\admin\service\tool\CommonTool;
use Exception;
use think\exception\FileException;
use think\facade\Db;
@@ -19,212 +20,212 @@ class BuildCurd
* 当前目录
* @var string
*/
protected $dir;
protected string $dir;
/**
* 应用目录
* @var string
*/
protected $rootDir;
protected string $rootDir;
/**
* 分隔符
* @var string
*/
protected $DS = DIRECTORY_SEPARATOR;
protected string $DS = DIRECTORY_SEPARATOR;
/**
* 数据库名
* @var string
*/
protected $dbName;
protected mixed $dbName;
/**
* 表前缀
* @var string
*/
protected $tablePrefix = 'ea';
protected mixed $tablePrefix = 'ea';
/**
* 主表
* @var string
*/
protected $table;
protected string $table;
/**
* 表注释名
* @var string
*/
protected $tableComment;
protected string $tableComment;
/**
* 主表列信息
* @var array
*/
protected $tableColumns;
protected array $tableColumns;
/**
* 数据列表可见字段
* @var string
*/
protected $fields;
protected string $fields;
/**
* 是否软删除模式
* @var bool
*/
protected $delete = false;
protected bool $delete = false;
/**
* 是否强制覆盖
* @var bool
*/
protected $force = false;
protected bool $force = false;
/**
* 关联模型
* @var array
*/
protected $relationArray = [];
protected array $relationArray = [];
/**
* 控制器对应的URL
* @var string
*/
protected $controllerUrl;
protected string $controllerUrl;
/**
* 生成的控制器名
* @var string
*/
protected $controllerFilename;
protected string $controllerFilename;
/**
* 控制器命名
* @var string
*/
protected $controllerName;
protected string $controllerName;
/**
* 控制器命名空间
* @var string
*/
protected $controllerNamespace;
protected string $controllerNamespace;
/**
* 视图名
* @var string
*/
protected $viewFilename;
protected string $viewFilename;
/**
* js文件名
* @var string
*/
protected $jsFilename;
protected string $jsFilename;
/**
* 生成的模型文件名
* @var string
*/
protected $modelFilename;
protected string $modelFilename;
/**
* 主表模型命名
* @var string
*/
protected $modelName;
protected string $modelName;
/**
* 复选框字段后缀
* @var array
*/
protected $checkboxFieldSuffix = [];
protected array $checkboxFieldSuffix = [];
/**
* 单选框字段后缀
* @var array
*/
protected $radioFieldSuffix = [];
protected array $radioFieldSuffix = [];
/**
* 单图片字段后缀
* @var array
*/
protected $imageFieldSuffix = ['image', 'logo', 'photo', 'icon'];
protected array $imageFieldSuffix = ['image', 'logo', 'photo', 'icon'];
/**
* 多图片字段后缀
* @var array
*/
protected $imagesFieldSuffix = ['images', 'photos', 'icons'];
protected array $imagesFieldSuffix = ['images', 'photos', 'icons'];
/**
* 单文件字段后缀
* @var array
*/
protected $fileFieldSuffix = ['file'];
protected array $fileFieldSuffix = ['file'];
/**
* 多文件字段后缀
* @var array
*/
protected $filesFieldSuffix = ['files'];
protected array $filesFieldSuffix = ['files'];
/**
* 时间字段后缀
* @var array
*/
protected $dateFieldSuffix = ['time', 'date'];
protected array $dateFieldSuffix = ['time', 'date'];
/**
* 开关组件字段
* @var array
*/
protected $switchFields = ['status'];
protected array $switchFields = ['status'];
/**
* 下拉选择字段
* @var array
*/
protected $selectFileds = [];
protected array $selectFields = [];
/**
* 富文本字段
* @var array
*/
protected $editorFields = [];
protected array $editorFields = [];
/**
* 排序字段
* @var array
*/
protected $sortFields = [];
protected array $sortFields = [];
/**
* 忽略字段
* @var array
*/
protected $ignoreFields = ['update_time', 'delete_time'];
protected array $ignoreFields = ['update_time', 'delete_time'];
/**
* 外键字段
* @var array
*/
protected $foreignKeyFields = [];
protected array $foreignKeyFields = [];
/**
* 相关生成文件
* @var array
*/
protected $fileList = [];
protected array $fileList = [];
/**
* 表单类型
* @var array
*/
protected $formTypeArray = ['text', 'image', 'images', 'file', 'files', 'select', 'switch', 'date', 'editor', 'textarea', 'checkbox', 'radio'];
protected array $formTypeArray = ['text', 'image', 'images', 'file', 'files', 'select', 'switch', 'date', 'editor', 'textarea', 'checkbox', 'radio'];
/**
* 初始化
@@ -251,19 +252,18 @@ class BuildCurd
* @return $this
* @throws TableException
*/
public function setTable($table)
public function setTable($table): static
{
$this->table = $table;
try {
// 获取表列注释
$colums = Db::query("SHOW FULL COLUMNS FROM {$this->tablePrefix}{$this->table}");
foreach ($colums as $vo) {
$columns = Db::query("SHOW FULL COLUMNS FROM {$this->tablePrefix}{$this->table}");
foreach ($columns as $vo) {
$colum = [
'type' => $vo['Type'],
'comment' => !empty($vo['Comment']) ? $vo['Comment'] : $vo['Field'],
'required' => $vo['Null'] == "NO" ? true : false,
'required' => $vo['Null'] == "NO",
'default' => $vo['Default'],
];
@@ -277,7 +277,7 @@ class BuildCurd
}
}
$this->tableComment = $this->table;
} catch (\Exception $e) {
}catch (Exception $e) {
throw new TableException($e->getMessage());
}
@@ -285,11 +285,11 @@ class BuildCurd
$nodeArray = explode('_', $this->table);
if (count($nodeArray) == 1) {
$this->controllerFilename = ucfirst($nodeArray[0]);
} else {
}else {
foreach ($nodeArray as $k => $v) {
if ($k == 0) {
$this->controllerFilename = "{$v}{$this->DS}";
} else {
}else {
$this->controllerFilename .= ucfirst($v);
}
}
@@ -312,12 +312,12 @@ class BuildCurd
* @param $foreignKey
* @param null $primaryKey
* @param null $modelFilename
* @param array $onlyShowFileds
* @param array $onlyShowFields
* @param null $bindSelectField
* @return $this
* @throws TableException
*/
public function setRelation($relationTable, $foreignKey, $primaryKey = null, $modelFilename = null, $onlyShowFileds = [], $bindSelectField = null)
public function setRelation($relationTable, $foreignKey, $primaryKey = null, $modelFilename = null, array $onlyShowFields = [], $bindSelectField = null): static
{
if (!isset($this->tableColumns[$foreignKey])) {
throw new TableException("主表不存在外键字段:{$foreignKey}");
@@ -326,17 +326,17 @@ class BuildCurd
$modelFilename = str_replace('/', $this->DS, $modelFilename);
}
try {
$colums = Db::query("SHOW FULL COLUMNS FROM {$this->tablePrefix}{$relationTable}");
$formatColums = [];
$columns = Db::query("SHOW FULL COLUMNS FROM {$this->tablePrefix}{$relationTable}");
$formatColumns = [];
$delete = false;
if (!empty($bindSelectField) && !in_array($bindSelectField, array_column($colums, 'Field'))) {
if (!empty($bindSelectField) && !in_array($bindSelectField, array_column($columns, 'Field'))) {
throw new TableException("关联表{$relationTable}不存在该字段: {$bindSelectField}");
}
foreach ($colums as $vo) {
foreach ($columns as $vo) {
if (empty($primaryKey) && $vo['Key'] == 'PRI') {
$primaryKey = $vo['Field'];
}
if (!empty($onlyShowFileds) && !in_array($vo['Field'], $onlyShowFileds)) {
if (!empty($onlyShowFields) && !in_array($vo['Field'], $onlyShowFields)) {
continue;
}
$colum = [
@@ -347,7 +347,7 @@ class BuildCurd
$this->buildColum($colum);
$formatColums[$vo['Field']] = $colum;
$formatColumns[$vo['Field']] = $colum;
if ($vo['Field'] == 'delete_time') {
$delete = true;
}
@@ -364,7 +364,7 @@ class BuildCurd
'primaryKey' => $primaryKey,
'bindSelectField' => $bindSelectField,
'delete' => $delete,
'tableColumns' => $formatColums,
'tableColumns' => $formatColumns,
];
if (!empty($bindSelectField)) {
$relationArray = explode('\\', $modelFilename);
@@ -372,8 +372,8 @@ class BuildCurd
$this->tableColumns[$foreignKey]['bindRelation'] = end($relationArray);
}
$this->relationArray[$relationTable] = $relation;
$this->selectFileds[] = $foreignKey;
} catch (\Exception $e) {
$this->selectFields[] = $foreignKey;
}catch (Exception $e) {
throw new TableException($e->getMessage());
}
return $this;
@@ -384,7 +384,7 @@ class BuildCurd
* @param $controllerFilename
* @return $this
*/
public function setControllerFilename($controllerFilename)
public function setControllerFilename($controllerFilename): static
{
$this->controllerFilename = str_replace('/', $this->DS, $controllerFilename);
$this->buildViewJsUrl();
@@ -396,7 +396,7 @@ class BuildCurd
* @param $modelFilename
* @return $this
*/
public function setModelFilename($modelFilename)
public function setModelFilename($modelFilename): static
{
$this->modelFilename = str_replace('/', $this->DS, $modelFilename);
$this->buildViewJsUrl();
@@ -408,7 +408,7 @@ class BuildCurd
* @param $fields
* @return $this
*/
public function setFields($fields)
public function setFields($fields): static
{
$this->fields = $fields;
return $this;
@@ -419,7 +419,7 @@ class BuildCurd
* @param $delete
* @return $this
*/
public function setDelete($delete)
public function setDelete($delete): static
{
$this->delete = $delete;
return $this;
@@ -430,7 +430,7 @@ class BuildCurd
* @param $force
* @return $this
*/
public function setForce($force)
public function setForce($force): static
{
$this->force = $force;
return $this;
@@ -441,7 +441,7 @@ class BuildCurd
* @param $array
* @return $this
*/
public function setCheckboxFieldSuffix($array)
public function setCheckboxFieldSuffix($array): static
{
$this->checkboxFieldSuffix = array_merge($this->checkboxFieldSuffix, $array);
return $this;
@@ -452,7 +452,7 @@ class BuildCurd
* @param $array
* @return $this
*/
public function setRadioFieldSuffix($array)
public function setRadioFieldSuffix($array): static
{
$this->radioFieldSuffix = array_merge($this->radioFieldSuffix, $array);
return $this;
@@ -463,7 +463,7 @@ class BuildCurd
* @param $array
* @return $this
*/
public function setImageFieldSuffix($array)
public function setImageFieldSuffix($array): static
{
$this->imageFieldSuffix = array_merge($this->imageFieldSuffix, $array);
return $this;
@@ -474,7 +474,7 @@ class BuildCurd
* @param $array
* @return $this
*/
public function setImagesFieldSuffix($array)
public function setImagesFieldSuffix($array): static
{
$this->imagesFieldSuffix = array_merge($this->imagesFieldSuffix, $array);
return $this;
@@ -485,7 +485,7 @@ class BuildCurd
* @param $array
* @return $this
*/
public function setFileFieldSuffix($array)
public function setFileFieldSuffix($array): static
{
$this->fileFieldSuffix = array_merge($this->fileFieldSuffix, $array);
return $this;
@@ -496,7 +496,7 @@ class BuildCurd
* @param $array
* @return $this
*/
public function setFilesFieldSuffix($array)
public function setFilesFieldSuffix($array): static
{
$this->filesFieldSuffix = array_merge($this->filesFieldSuffix, $array);
return $this;
@@ -507,7 +507,7 @@ class BuildCurd
* @param $array
* @return $this
*/
public function setDateFieldSuffix($array)
public function setDateFieldSuffix($array): static
{
$this->dateFieldSuffix = array_merge($this->dateFieldSuffix, $array);
return $this;
@@ -518,7 +518,7 @@ class BuildCurd
* @param $array
* @return $this
*/
public function setSwitchFields($array)
public function setSwitchFields($array): static
{
$this->switchFields = array_merge($this->switchFields, $array);
return $this;
@@ -529,9 +529,9 @@ class BuildCurd
* @param $array
* @return $this
*/
public function setSelectFileds($array)
public function setSelectFields($array): static
{
$this->selectFileds = array_merge($this->selectFileds, $array);
$this->selectFields = array_merge($this->selectFields, $array);
return $this;
}
@@ -540,7 +540,7 @@ class BuildCurd
* @param $array
* @return $this
*/
public function setSortFields($array)
public function setSortFields($array): static
{
$this->sortFields = array_merge($this->sortFields, $array);
return $this;
@@ -551,7 +551,7 @@ class BuildCurd
* @param $array
* @return $this
*/
public function setIgnoreFields($array)
public function setIgnoreFields($array): static
{
$this->ignoreFields = array_merge($this->ignoreFields, $array);
return $this;
@@ -561,7 +561,7 @@ class BuildCurd
* 获取相关的文件
* @return array
*/
public function getFileList()
public function getFileList(): array
{
return $this->fileList;
}
@@ -570,7 +570,7 @@ class BuildCurd
* 构建基础视图、JS、URL
* @return $this
*/
protected function buildViewJsUrl()
protected function buildViewJsUrl(): static
{
$nodeArray = explode($this->DS, $this->controllerFilename);
$formatArray = [];
@@ -599,12 +599,12 @@ class BuildCurd
* 构建字段
* @return $this
*/
protected function buildStructure()
protected function buildStructure(): static
{
foreach ($this->tableColumns as $key => $val) {
// 排序
if (in_array($key, ['sort'])) {
if ($key == 'sort') {
$this->sortFields[] = $key;
}
@@ -622,7 +622,7 @@ class BuildCurd
* @param $require
* @return string
*/
protected function buildRequiredHtml($require)
protected function buildRequiredHtml($require): string
{
return $require ? 'lay-verify="required"' : "";
}
@@ -630,9 +630,9 @@ class BuildCurd
/**
* 构建初始化字段信息
* @param $colum
* @return mixed
* @return array
*/
protected function buildColum(&$colum)
protected function buildColum(&$colum): array
{
$string = $colum['comment'];
@@ -663,7 +663,7 @@ class BuildCurd
}
}
!empty($formatDefine) && $colum['define'] = $formatDefine;
} else {
}else {
$colum['define'] = $define;
}
}
@@ -679,7 +679,7 @@ class BuildCurd
* @param $field
* @return mixed
*/
protected function buildSelectController($field)
protected function buildSelectController($field): mixed
{
$field = CommonTool::lineToHump(ucfirst($field));
$name = "get{$field}List";
@@ -697,7 +697,7 @@ class BuildCurd
* @param $array
* @return mixed
*/
protected function buildSelectModel($field, $array)
protected function buildSelectModel($field, $array): mixed
{
$field = CommonTool::lineToHump(ucfirst($field));
$name = "get{$field}List";
@@ -721,7 +721,7 @@ class BuildCurd
* @param $filed
* @return mixed
*/
protected function buildRelationSelectModel($relation, $filed)
protected function buildRelationSelectModel($relation, $filed): mixed
{
$relationArray = explode('\\', $relation);
$name = end($relationArray);
@@ -742,17 +742,16 @@ class BuildCurd
* @param string $select
* @return mixed
*/
protected function buildOptionView($field, $select = '')
protected function buildOptionView($field, string $select = '')
{
$field = CommonTool::lineToHump(ucfirst($field));
$name = "get{$field}List";
$optionCode = CommonTool::replaceTemplate(
return CommonTool::replaceTemplate(
$this->getTemplate("view{$this->DS}module{$this->DS}option"),
[
'name' => $name,
'select' => $select,
]);
return $optionCode;
}
/**
@@ -761,18 +760,17 @@ class BuildCurd
* @param string $select
* @return mixed
*/
protected function buildRadioView($field, $select = '')
protected function buildRadioView($field, string $select = ''): mixed
{
$formatField = CommonTool::lineToHump(ucfirst($field));
$name = "get{$formatField}List";
$optionCode = CommonTool::replaceTemplate(
return CommonTool::replaceTemplate(
$this->getTemplate("view{$this->DS}module{$this->DS}radioInput"),
[
'field' => $field,
'name' => $name,
'select' => $select,
]);
return $optionCode;
}
/**
@@ -781,25 +779,24 @@ class BuildCurd
* @param string $select
* @return mixed
*/
protected function buildCheckboxView($field, $select = '')
protected function buildCheckboxView($field, string $select = ''): mixed
{
$formatField = CommonTool::lineToHump(ucfirst($field));
$name = "get{$formatField}List";
$optionCode = CommonTool::replaceTemplate(
return CommonTool::replaceTemplate(
$this->getTemplate("view{$this->DS}module{$this->DS}checkboxInput"),
[
'field' => $field,
'name' => $name,
'select' => $select,
]);
return $optionCode;
}
/**
* 初始化
* @return $this
*/
public function render()
public function render(): static
{
// 初始化数据
@@ -824,7 +821,7 @@ class BuildCurd
* 初始化数据
* @return $this
*/
protected function renderData()
protected function renderData(): static
{
// 主表
@@ -886,7 +883,7 @@ class BuildCurd
}
// 判断下拉选择
if (in_array($field, $this->selectFileds)) {
if (in_array($field, $this->selectFields)) {
$this->tableColumns[$field]['formType'] = 'select';
continue;
}
@@ -954,7 +951,7 @@ class BuildCurd
}
// 判断下拉选择
if (in_array($field, $this->selectFileds)) {
if (in_array($field, $this->selectFields)) {
$this->relationArray[$table]['tableColumns'][$field]['formType'] = 'select';
continue;
}
@@ -971,12 +968,12 @@ class BuildCurd
* 初始化控制器
* @return $this
*/
protected function renderController()
protected function renderController(): static
{
$controllerFile = "{$this->rootDir}app{$this->DS}admin{$this->DS}controller{$this->DS}{$this->controllerFilename}.php";
if (empty($this->relationArray)) {
$controllerIndexMethod = '';
} else {
}else {
$relationCode = '';
foreach ($this->relationArray as $key => $val) {
$relation = CommonTool::lineToHump($key);
@@ -1021,14 +1018,12 @@ class BuildCurd
* 初始化模型
* @return $this
*/
protected function renderModel()
protected function renderModel(): static
{
// 主表模型
$modelFile = "{$this->rootDir}app{$this->DS}admin{$this->DS}model{$this->DS}{$this->modelFilename}.php";
if (empty($this->relationArray)) {
$relationList = '';
} else {
$relationList = '';
$relationList = '';
if (!empty($this->relationArray)) {
foreach ($this->relationArray as $key => $val) {
$relation = CommonTool::lineToHump($key);
$relationCode = CommonTool::replaceTemplate(
@@ -1113,7 +1108,7 @@ class BuildCurd
* 初始化视图
* @return $this
*/
protected function renderView()
protected function renderView(): static
{
// 列表页面
$viewIndexFile = "{$this->rootDir}app{$this->DS}admin{$this->DS}view{$this->DS}{$this->viewFilename}{$this->DS}index.html";
@@ -1139,45 +1134,45 @@ class BuildCurd
// 根据formType去获取具体模板
if ($val['formType'] == 'image') {
$templateFile = "view{$this->DS}module{$this->DS}image";
} elseif ($val['formType'] == 'images') {
}elseif ($val['formType'] == 'images') {
$templateFile = "view{$this->DS}module{$this->DS}images";
$define = isset($val['define']) ? $val['define'] : '|';
} elseif ($val['formType'] == 'file') {
$define = $val['define'] ?? '|';
}elseif ($val['formType'] == 'file') {
$templateFile = "view{$this->DS}module{$this->DS}file";
} elseif ($val['formType'] == 'files') {
}elseif ($val['formType'] == 'files') {
$templateFile = "view{$this->DS}module{$this->DS}files";
$define = isset($val['define']) ? $val['define'] : '|';
} elseif ($val['formType'] == 'editor') {
$define = $val['define'] ?? '|';
}elseif ($val['formType'] == 'editor') {
$templateFile = "view{$this->DS}module{$this->DS}editor";
$val['default'] = '""';
} elseif ($val['formType'] == 'date') {
}elseif ($val['formType'] == 'date') {
$templateFile = "view{$this->DS}module{$this->DS}date";
if (isset($val['define']) && !empty($val['define'])) {
if (!empty($val['define'])) {
$define = $val['define'];
} else {
}else {
$define = 'datetime';
}
if (!in_array($define, ['year', 'month', 'date', 'time', 'datetime'])) {
$define = 'datetime';
}
} elseif ($val['formType'] == 'radio') {
}elseif ($val['formType'] == 'radio') {
$templateFile = "view{$this->DS}module{$this->DS}radio";
if (isset($val['define']) && !empty($val['define'])) {
if (!empty($val['define'])) {
$define = $this->buildRadioView($field, '{in name="k" value="' . $val['default'] . '"}checked=""{/in}');
}
} elseif ($val['formType'] == 'checkbox') {
}elseif ($val['formType'] == 'checkbox') {
$templateFile = "view{$this->DS}module{$this->DS}checkbox";
if (isset($val['define']) && !empty($val['define'])) {
if (!empty($val['define'])) {
$define = $this->buildCheckboxView($field, '{in name="k" value="' . $val['default'] . '"}checked=""{/in}');
}
} elseif ($val['formType'] == 'select') {
}elseif ($val['formType'] == 'select') {
$templateFile = "view{$this->DS}module{$this->DS}select";
if (isset($val['bindRelation'])) {
$define = $this->buildOptionView($val['bindRelation']);
} elseif (isset($val['define']) && !empty($val['define'])) {
}elseif (!empty($val['define'])) {
$define = $this->buildOptionView($field);
}
} elseif (in_array($field, ['remark']) || $val['formType'] == 'textarea') {
}elseif ($field == 'remark' || $val['formType'] == 'textarea') {
$templateFile = "view{$this->DS}module{$this->DS}textarea";
}
@@ -1216,43 +1211,43 @@ class BuildCurd
// 根据formType去获取具体模板
if ($val['formType'] == 'image') {
$templateFile = "view{$this->DS}module{$this->DS}image";
} elseif ($val['formType'] == 'images') {
}elseif ($val['formType'] == 'images') {
$templateFile = "view{$this->DS}module{$this->DS}images";
} elseif ($val['formType'] == 'file') {
}elseif ($val['formType'] == 'file') {
$templateFile = "view{$this->DS}module{$this->DS}file";
} elseif ($val['formType'] == 'files') {
}elseif ($val['formType'] == 'files') {
$templateFile = "view{$this->DS}module{$this->DS}files";
} elseif ($val['formType'] == 'editor') {
}elseif ($val['formType'] == 'editor') {
$templateFile = "view{$this->DS}module{$this->DS}editor";
$value = '$row["' . $field . '"]';
} elseif ($val['formType'] == 'date') {
}elseif ($val['formType'] == 'date') {
$templateFile = "view{$this->DS}module{$this->DS}date";
if (isset($val['define']) && !empty($val['define'])) {
if (!empty($val['define'])) {
$define = $val['define'];
} else {
}else {
$define = 'datetime';
}
if (!in_array($define, ['year', 'month', 'date', 'time', 'datetime'])) {
$define = 'datetime';
}
} elseif ($val['formType'] == 'radio') {
}elseif ($val['formType'] == 'radio') {
$templateFile = "view{$this->DS}module{$this->DS}radio";
if (isset($val['define']) && !empty($val['define'])) {
if (!empty($val['define'])) {
$define = $this->buildRadioView($field, '{in name="k" value="$row.' . $field . '"}checked=""{/in}');
}
} elseif ($val['formType'] == 'checkbox') {
}elseif ($val['formType'] == 'checkbox') {
$templateFile = "view{$this->DS}module{$this->DS}checkbox";
if (isset($val['define']) && !empty($val['define'])) {
if (!empty($val['define'])) {
$define = $this->buildCheckboxView($field, '{in name="k" value="$row.' . $field . '"}checked=""{/in}');
}
} elseif ($val['formType'] == 'select') {
}elseif ($val['formType'] == 'select') {
$templateFile = "view{$this->DS}module{$this->DS}select";
if (isset($val['bindRelation'])) {
$define = $this->buildOptionView($val['bindRelation'], '{in name="k" value="$row.' . $field . '"}selected=""{/in}');
} elseif (isset($val['define']) && !empty($val['define'])) {
}elseif (!empty($val['define'])) {
$define = $this->buildOptionView($field, '{in name="k" value="$row.' . $field . '"}selected=""{/in}');
}
} elseif (in_array($field, ['remark']) || $val['formType'] == 'textarea') {
}elseif ($field == 'remark' || $val['formType'] == 'textarea') {
$templateFile = "view{$this->DS}module{$this->DS}textarea";
$value = '{$row.' . $field . '|raw|default=\'\'}';
}
@@ -1281,7 +1276,7 @@ class BuildCurd
* 初始化JS
* @return $this
*/
protected function renderJs()
protected function renderJs(): static
{
$jsFile = "{$this->rootDir}public{$this->DS}static{$this->DS}admin{$this->DS}js{$this->DS}{$this->jsFilename}.js";
@@ -1292,33 +1287,33 @@ class BuildCurd
if ($val['formType'] == 'image') {
$templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ea.table.image}";
} elseif ($val['formType'] == 'images') {
}elseif ($val['formType'] == 'images') {
continue;
} elseif ($val['formType'] == 'file') {
}elseif ($val['formType'] == 'file') {
$templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ea.table.url}";
} elseif ($val['formType'] == 'files') {
}elseif ($val['formType'] == 'files') {
continue;
} elseif ($val['formType'] == 'editor') {
}elseif ($val['formType'] == 'editor') {
continue;
} elseif (in_array($field, $this->switchFields)) {
if (isset($val['define']) && !empty($val['define'])) {
}elseif (in_array($field, $this->switchFields)) {
if (!empty($val['define'])) {
$values = json_encode($val['define'], JSON_UNESCAPED_UNICODE);
$templateValue = "{field: '{$field}', search: 'select', selectList: {$values}, title: '{$val['comment']}', templet: ea.table.switch}";
} else {
}else {
$templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ea.table.switch}";
}
} elseif (in_array($val['formType'], ['select', 'checkbox', 'radio', 'switch'])) {
if (isset($val['define']) && !empty($val['define'])) {
}elseif (in_array($val['formType'], ['select', 'checkbox', 'radio', 'switch'])) {
if (!empty($val['define'])) {
$values = json_encode($val['define'], JSON_UNESCAPED_UNICODE);
$templateValue = "{field: '{$field}', search: 'select', selectList: {$values}, title: '{$val['comment']}'}";
} else {
}else {
$templateValue = "{field: '{$field}', title: '{$val['comment']}'}";
}
} elseif (in_array($field, ['remark'])) {
}elseif ($field == 'remark') {
$templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ea.table.text}";
} elseif (in_array($field, $this->sortFields)) {
}elseif (in_array($field, $this->sortFields)) {
$templateValue = "{field: '{$field}', title: '{$val['comment']}', edit: 'text'}";
} else {
}else {
$templateValue = "{field: '{$field}', title: '{$val['comment']}'}";
}
@@ -1331,23 +1326,23 @@ class BuildCurd
foreach ($tableVal['tableColumns'] as $field => $val) {
if ($val['formType'] == 'image') {
$templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}', templet: ea.table.image}";
} elseif ($val['formType'] == 'images') {
}elseif ($val['formType'] == 'images') {
continue;
} elseif ($val['formType'] == 'file') {
}elseif ($val['formType'] == 'file') {
$templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}', templet: ea.table.url}";
} elseif ($val['formType'] == 'files') {
}elseif ($val['formType'] == 'files') {
continue;
} elseif ($val['formType'] == 'editor') {
}elseif ($val['formType'] == 'editor') {
continue;
} elseif ($val['formType'] == 'select') {
}elseif ($val['formType'] == 'select') {
$templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}'}";
} elseif (in_array($field, ['remark'])) {
}elseif ($field == 'remark') {
$templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}', templet: ea.table.text}";
} elseif (in_array($field, $this->switchFields)) {
}elseif (in_array($field, $this->switchFields)) {
$templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}', templet: ea.table.switch}";
} elseif (in_array($field, $this->sortFields)) {
}elseif (in_array($field, $this->sortFields)) {
$templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}', edit: 'text'}";
} else {
}else {
$templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}'}";
}
@@ -1371,7 +1366,7 @@ class BuildCurd
* 检测文件
* @return $this
*/
protected function check()
protected function check(): static
{
// 是否强制性
if ($this->force) {
@@ -1389,7 +1384,7 @@ class BuildCurd
* 开始生成
* @return array
*/
public function create()
public function create(): array
{
$this->check();
foreach ($this->fileList as $key => $val) {
@@ -1412,7 +1407,7 @@ class BuildCurd
* 开始删除
* @return array
*/
public function delete()
public function delete(): array
{
$deleteFile = [];
foreach ($this->fileList as $key => $val) {
@@ -1430,10 +1425,10 @@ class BuildCurd
* @param $array
* @return bool
*/
protected function checkContain($string, $array)
protected function checkContain($string, $array): bool
{
foreach ($array as $vo) {
if (substr($string, 0, strlen($vo)) === $vo) {
if (str_starts_with($string, $vo)) {
return true;
}
}
@@ -1445,7 +1440,7 @@ class BuildCurd
* @param $value
* @return string
*/
protected function formatColsRow($value)
protected function formatColsRow($value): string
{
return " {$value}";
}
@@ -1455,7 +1450,7 @@ class BuildCurd
* @param $name
* @return false|string
*/
protected function getTemplate($name)
protected function getTemplate($name): bool|string
{
return file_get_contents("{$this->dir}{$this->DS}templates{$this->DS}{$name}.code");
}

View File

@@ -13,15 +13,13 @@ use think\App;
class {{controllerName}} extends AdminController
{
use \app\admin\traits\Curd;
public function __construct(App $app)
{
parent::__construct($app);
$this->model = new {{modelFilename}}();
{{selectList}}
}
{{indexMethod}}
}

View File

@@ -9,16 +9,8 @@
return $this->selectList();
}
list($page, $limit, $where) = $this->buildTableParams();
$count = $this->model
{{relationIndexMethod}}
->where($where)
->count();
$list = $this->model
{{relationIndexMethod}}
->where($where)
->page($page, $limit)
->order($this->sort)
->select();
$count = $this->model{{relationIndexMethod}}->where($where)->count();
$list = $this->model{{relationIndexMethod}}->where($where)->page($page, $limit)->order($this->sort)->select()->toArray();
$data = [
'code' => 0,
'msg' => '',

View File

@@ -11,7 +11,7 @@ define(["jquery", "easy-admin"], function ($, ea) {
modify_url: '{{controllerUrl}}/modify',
};
var Controller = {
return {
index: function () {
ea.table.render({
@@ -30,5 +30,4 @@ define(["jquery", "easy-admin"], function ($, ea) {
ea.listen();
},
};
return Controller;
});

View File

@@ -6,6 +6,5 @@
<button type="submit" class="layui-btn layui-btn-normal layui-btn-sm" lay-submit>确认</button>
<button type="reset" class="layui-btn layui-btn-primary layui-btn-sm">重置</button>
</div>
</form>
</div>

View File

@@ -1,122 +0,0 @@
<?php
namespace app\admin\service\upload;
use think\facade\Filesystem;
use think\File;
/**
* 基类
* Class Base
* @package EasyAdmin\upload
*/
class FileBase
{
/**
* 上传配置
* @var array
*/
protected $uploadConfig;
/**
* 上传文件对象
* @var object
*/
protected $file;
/**
* 上传完成的文件路径
* @var string
*/
protected $completeFilePath;
/**
* 上传完成的文件的URL
* @var string
*/
protected $completeFileUrl;
/**
* 保存上传文件的数据表
* @var string
*/
protected $tableName;
/**
* 上传类型
* @var string
*/
protected $uploadType = 'local';
/**
* 设置上传方式
* @param $value
* @return $this
*/
public function setUploadType($value)
{
$this->uploadType = $value;
return $this;
}
/**
* 设置上传配置
* @param $value
* @return $this
*/
public function setUploadConfig($value)
{
$this->uploadConfig = $value;
return $this;
}
/**
* 设置上传配置
* @param $value
* @return $this
*/
public function setFile($value)
{
$this->file = $value;
return $this;
}
/**
* 设置保存文件数据表
* @param $value
* @return $this
*/
public function setTableName($value)
{
$this->tableName = $value;
return $this;
}
/**
* 保存文件
*/
public function save()
{
$this->completeFilePath = Filesystem::disk('public')->putFile('upload', $this->file, 'md5');
$this->completeFileUrl = request()->domain() . '/' . str_replace(DIRECTORY_SEPARATOR, '/', $this->completeFilePath);
}
/**
* 删除保存在本地的文件
* @return bool|string
*/
public function rmLocalSave()
{
try {
$rm = unlink($this->completeFilePath);
} catch (\Exception $e) {
return $e->getMessage();
}
return $rm;
}
}

View File

@@ -1,127 +0,0 @@
<?php
namespace app\admin\service\upload;
use app\admin\service\upload\driver\Alioss;
use app\admin\service\upload\driver\Qnoss;
use app\admin\service\upload\driver\Txcos;
use app\admin\service\upload\driver\Local;
use think\File;
/**
* 上传组件
* Class Uploadfile
* @package EasyAdmin\upload
*/
class Uploadfile
{
/**
* 当前实例对象
* @var object
*/
protected static $instance;
/**
* 上传方式
* @var string
*/
protected $uploadType = 'local';
/**
* 上传配置文件
* @var array
*/
protected $uploadConfig;
/**
* 需要上传的文件对象
* @var File
*/
protected $file;
/**
* 保存上传文件的数据表
* @var string
*/
protected $tableName = 'system_uploadfile';
/**
* 获取对象实例
* @return Uploadfile|object
*/
public static function instance()
{
if (is_null(self::$instance)) {
self::$instance = new static();
}
return self::$instance;
}
/**
* 设置上传对象
* @param $value
* @return $this
*/
public function setFile($value)
{
$this->file = $value;
return $this;
}
/**
* 设置上传文件
* @param $value
* @return $this
*/
public function setUploadConfig($value)
{
$this->uploadConfig = $value;
return $this;
}
/**
* 设置上传方式
* @param $value
* @return $this
*/
public function setUploadType($value)
{
$this->uploadType = $value;
return $this;
}
/**
* 设置保存数据表
* @param $value
* @return $this
*/
public function setTableName($value)
{
$this->tableName = $value;
return $this;
}
/**
* 保存文件
* @return array|void
*/
public function save()
{
$obj = null;
if ($this->uploadType == 'local') {
$obj = new Local();
} elseif ($this->uploadType == 'oss') {
$obj = new Alioss();
} elseif ($this->uploadType == 'cos') {
$obj = new Txcos();
}
$save = $obj->setUploadConfig($this->uploadConfig)
->setUploadType($this->uploadType)
->setTableName($this->tableName)
->setFile($this->file)
->save();
return $save;
}
}

View File

@@ -1,42 +0,0 @@
<?php
namespace app\admin\service\upload\driver;
use app\admin\service\upload\FileBase;
use app\admin\service\upload\trigger\SaveDb;
use app\admin\service\upload\driver\alioss\Oss;
/**
* 阿里云上传
* Class Alioss
* @package EasyAdmin\upload\driver
*/
class Alioss extends FileBase
{
/**
* 重写上传方法
* @return array|void
*/
public function save()
{
parent::save();
$upload = Oss::instance($this->uploadConfig)
->save($this->completeFilePath, $this->completeFilePath);
if ($upload['save'] == true) {
SaveDb::trigger($this->tableName, [
'upload_type' => $this->uploadType,
'original_name' => $this->file->getOriginalName(),
'mime_type' => $this->file->getOriginalMime(),
'file_ext' => strtolower($this->file->getOriginalExtension()),
'url' => $upload['url'],
'create_time' => time(),
]);
}
$this->rmLocalSave();
return $upload;
}
}

View File

@@ -1,45 +0,0 @@
<?php
namespace app\admin\service\upload\driver;
use app\admin\service\upload\FileBase;
use app\admin\service\upload\trigger\SaveDb;
/**
* 本地上传
* Class Local
* @package EasyAdmin\upload\driver
*/
class Local extends FileBase
{
/**
* 重写上传方法
* @return array|void
*/
public function save()
{
if (pathinfo($this->file->getOriginalName(), PATHINFO_EXTENSION) === 'php') {
return [
'save' => false,
'msg' => '上传文件中存在异常文件,请重新选择',
'url' => '',
];
}
parent::save();
SaveDb::trigger($this->tableName, [
'upload_type' => $this->uploadType,
'original_name' => $this->file->getOriginalName(),
'mime_type' => $this->file->getOriginalMime(),
'file_ext' => strtolower($this->file->getOriginalExtension()),
'url' => $this->completeFileUrl,
'create_time' => time(),
]);
return [
'save' => true,
'msg' => '上传成功',
'url' => $this->completeFileUrl,
];
}
}

View File

@@ -1,42 +0,0 @@
<?php
namespace app\admin\service\upload\driver;
use app\admin\service\upload\driver\qnoss\Oss;
use app\admin\service\upload\FileBase;
use app\admin\service\upload\trigger\SaveDb;
/**
* 七牛云上传
* Class Qnoss
* @package EasyAdmin\upload\driver
*/
class Qnoss extends FileBase
{
/**
* 重写上传方法
* @return array|void
*/
public function save()
{
parent::save();
$upload = Oss::instance($this->uploadConfig)
->save($this->completeFilePath, $this->completeFilePath);
if ($upload['save'] == true) {
SaveDb::trigger($this->tableName, [
'upload_type' => $this->uploadType,
'original_name' => $this->file->getOriginalName(),
'mime_type' => $this->file->getOriginalMime(),
'file_ext' => strtolower($this->file->getOriginalExtension()),
'url' => $upload['url'],
'create_time' => time(),
]);
}
$this->rmLocalSave();
return $upload;
}
}

View File

@@ -1,43 +0,0 @@
<?php
namespace app\admin\service\upload\driver;
use app\admin\service\upload\driver\txcos\Cos;
use app\admin\service\upload\FileBase;
use app\admin\service\upload\trigger\SaveDb;
/**
* 腾讯云上传
* Class Txcos
* @package EasyAdmin\upload\driver
*/
class Txcos extends FileBase
{
/**
* 重写上传方法
* @return array|void
*/
public function save()
{
parent::save();
$upload = Cos::instance($this->uploadConfig)
->save($this->completeFilePath, $this->completeFilePath);
if ($upload['save'] == true) {
SaveDb::trigger($this->tableName, [
'upload_type' => $this->uploadType,
'original_name' => $this->file->getOriginalName(),
'mime_type' => $this->file->getOriginalMime(),
'file_ext' => strtolower($this->file->getOriginalExtension()),
'url' => $upload['url'],
'create_time' => time(),
]);
}
$this->rmLocalSave();
return $upload;
}
}

View File

@@ -1,70 +0,0 @@
<?php
namespace app\admin\service\upload\driver\alioss;
use EasyAdmin\upload\interfaces\OssDriver;
use OSS\Core\OssException;
use OSS\OssClient;
class Oss implements OssDriver
{
protected static $instance;
protected $accessKeyId;
protected $accessKeySecret;
protected $endpoint;
protected $bucket;
protected $domain;
protected $ossClient;
protected function __construct($config)
{
$this->accessKeyId = $config['alioss_access_key_id'];
$this->accessKeySecret = $config['alioss_access_key_secret'];
$this->endpoint = $config['alioss_endpoint'];
$this->bucket = $config['alioss_bucket'];
$this->domain = $config['alioss_domain'];
$this->ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint);
return $this;
}
public static function instance($config)
{
if (is_null(self::$instance)) {
self::$instance = new static($config);
}
return self::$instance;
}
public function save($objectName,$filePath)
{
try {
$upload = $this->ossClient->uploadFile($this->bucket, $objectName, $filePath);
} catch (OssException $e) {
return [
'save' => false,
'msg' => $e->getMessage(),
];
}
if (!isset($upload['info']['url'])) {
return [
'save' => false,
'msg' => '保存失败',
];
}
return [
'save' => true,
'msg' => '上传成功',
'url' => $upload['info']['url'],
];
}
}

View File

@@ -1,64 +0,0 @@
<?php
namespace app\admin\service\upload\driver\qnoss;
use app\admin\service\upload\interfaces\OssDriver;
use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
class Oss implements OssDriver
{
protected static $instance;
protected $accessKey;
protected $secretKey;
protected $bucket;
protected $domain;
protected $auth;
public function __construct($config)
{
$this->accessKey = $config['qnoss_access_key'];
$this->secretKey = $config['qnoss_secret_key'];
$this->bucket = $config['qnoss_bucket'];
$this->domain = $config['qnoss_domain'];
$this->auth = new Auth($this->accessKey, $this->secretKey);
return $this;
}
public static function instance($config)
{
if (is_null(self::$instance)) {
self::$instance = new static($config);
}
return self::$instance;
}
public function save($objectName, $filePath)
{
$token = $this->auth->uploadToken($this->bucket);
$uploadMgr = new UploadManager();
list($result, $error) = $uploadMgr->putFile($token, $objectName, $filePath);
if ($error !== null) {
return [
'save' => false,
'msg' => '保存失败',
];
} else {
return [
'save' => true,
'msg' => '上传成功',
'url' => $this->domain . '/' . $result['key'],
];
}
}
}

View File

@@ -1,12 +0,0 @@
<?php
namespace app\admin\service\upload\interfaces;
interface OssDriver
{
public function save($objectName,$filePath);
}

View File

@@ -1,31 +0,0 @@
<?php
namespace app\admin\service\upload\trigger;
use think\facade\Db;
/**
* 保存到数据库
* Class SaveDb
* @package EasyAdmin\upload\trigger
*/
class SaveDb
{
/**
* 保存上传文件
* @param $tableName
* @param $data
*/
public static function trigger($tableName, $data)
{
if (isset($data['original_name'])) {
$data['original_name'] = htmlspecialchars($data['original_name'], ENT_QUOTES);
}
Db::name($tableName)->save($data);
}
}

View File

@@ -4,8 +4,10 @@ namespace app\admin\traits;
use app\admin\service\annotation\NodeAnnotation;
use app\admin\service\tool\CommonTool;
use app\Request;
use jianyan\excel\Excel;
use think\facade\Db;
use think\response\Json;
/**
* 后台CURD复用
@@ -18,21 +20,15 @@ trait Curd
/**
* @NodeAnnotation(title="列表")
*/
public function index()
public function index(Request $request): Json|string
{
if ($this->request->isAjax()) {
if ($request->isAjax()) {
if (input('selectFields')) {
return $this->selectList();
}
list($page, $limit, $where) = $this->buildTableParams();
$count = $this->model
->where($where)
->count();
$list = $this->model
->where($where)
->page($page, $limit)
->order($this->sort)
->select();
$count = $this->model->where($where)->count();
$list = $this->model->where($where)->page($page, $limit)->order($this->sort)->select()->toArray();
$data = [
'code' => 0,
'msg' => '',
@@ -47,18 +43,20 @@ trait Curd
/**
* @NodeAnnotation(title="添加")
*/
public function add()
public function add(Request $request): string
{
if ($this->request->isPost()) {
$post = $this->request->post();
if ($request->isPost()) {
$post = $request->post();
$rule = [];
$this->validate($post, $rule);
try {
$save = $this->model->save($post);
} catch (\Exception $e) {
$this->error('保存失败:' . $e->getMessage());
Db::transaction(function () use ($post, &$save) {
$save = $this->model->strict(false)->save($post);
});
}catch (\Exception $e) {
$this->error('新增失败:' . $e->getMessage());
}
$save ? $this->success('保存成功') : $this->error('保存失败');
$save ? $this->success('新增成功') : $this->error('新增失败');
}
return $this->fetch();
}
@@ -66,17 +64,19 @@ trait Curd
/**
* @NodeAnnotation(title="编辑")
*/
public function edit($id)
public function edit(Request $request, $id = 0): string
{
$row = $this->model->find($id);
empty($row) && $this->error('数据不存在');
if ($this->request->isPost()) {
$post = $this->request->post();
if ($request->isPost()) {
$post = $request->post();
$rule = [];
$this->validate($post, $rule);
try {
$save = $row->save($post);
} catch (\Exception $e) {
Db::transaction(function () use ($post, $row, &$save) {
$save = $row->save($post);
});
}catch (\Exception $e) {
$this->error('保存失败');
}
$save ? $this->success('保存成功') : $this->error('保存失败');
@@ -88,14 +88,14 @@ trait Curd
/**
* @NodeAnnotation(title="删除")
*/
public function delete($id)
public function delete($id): void
{
$this->checkPostRequest();
$row = $this->model->whereIn('id', $id)->select();
$row->isEmpty() && $this->error('数据不存在');
try {
$save = $row->delete();
} catch (\Exception $e) {
}catch (\Exception $e) {
$this->error('删除失败');
}
$save ? $this->success('删除成功') : $this->error('删除失败');
@@ -134,10 +134,10 @@ trait Curd
/**
* @NodeAnnotation(title="属性修改")
*/
public function modify()
public function modify(Request $request): void
{
$this->checkPostRequest();
$post = $this->request->post();
$post = $request->post();
$rule = [
'id|ID' => 'require',
'field|字段' => 'require',
@@ -152,10 +152,12 @@ trait Curd
$this->error('该字段不允许修改:' . $post['field']);
}
try {
$row->save([
$post['field'] => $post['value'],
]);
} catch (\Exception $e) {
Db::transaction(function () use ($post, $row) {
$row->save([
$post['field'] => $post['value'],
]);
});
}catch (\Exception $e) {
$this->error($e->getMessage());
}
$this->success('保存成功');

View File

@@ -1,5 +1,5 @@
<link rel="stylesheet" href="__STATIC__/plugs/lay-module/layuimini/layuimini.css?v={$version}" media="all">
<link rel="stylesheet" href="__STATIC__/plugs/lay-module/layuimini/themes/default.css?v={$version}" media="all">
<link rel="stylesheet" href="/static/plugs/lay-module/layuimini/layuimini.css?v={$version}" media="all">
<link rel="stylesheet" href="/static/plugs/lay-module/layuimini/themes/default.css?v={$version}" media="all">
<style id="layuimini-bg-color"></style>
<div class="layui-layout-body layuimini-all">
<div class="layui-layout layui-layout-admin">

View File

@@ -1,4 +1,4 @@
<link rel="stylesheet" href="__STATIC__/admin/css/welcome.css?v={$version}" media="all">
<link rel="stylesheet" href="/static/admin/css/welcome.css?v={$version}" media="all">
<div class="layuimini-container">
<div class="layuimini-main">
<div class="layui-row layui-col-space15">

View File

@@ -2,7 +2,7 @@
<html>
<head>
<meta charset="utf-8">
<title>{:sysconfig('site','site_name')}</title>
<title>{:sysConfig('site','site_name')}</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
@@ -10,7 +10,7 @@
<script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
<script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<link rel="stylesheet" href="__STATIC__/admin/css/public.css?v={$version}" media="all">
<link rel="stylesheet" href="/static/admin/css/public.css?v={$version}" media="all">
<link rel="stylesheet" href="" id="layuicss-theme-dark" media="all">
<script>
window.CONFIG = {
@@ -25,10 +25,10 @@
EDITOR_TYPE: "{$adminEditor|default='ueditor'}",
};
</script>
<script src="__STATIC__/plugs/layui-v2.8.x/layui.js?v={$version}" charset="utf-8"></script>
<script src="__STATIC__/plugs/require-2.3.6/require.js?v={$version}" charset="utf-8"></script>
<script src="__STATIC__/config-admin.js?v={$version}" charset="utf-8"></script>
<script src="__STATIC__/common/js/admin.js?v={$version}" charset="utf-8"></script>
<script src="/static/plugs/layui-v2.x/layui.js?v={$version}" charset="utf-8"></script>
<script src="/static/plugs/require-2.3.6/require.js?v={$version}" charset="utf-8"></script>
<script src="/static/config-admin.js?v={$version}" charset="utf-8"></script>
<script src="/static/common/js/admin.js?v={$version}" charset="utf-8"></script>
{include file="layout/editor" /}
</head>
<body>

View File

@@ -1,20 +1,20 @@
{switch $adminEditor}
{case ckeditor}
<script src="__STATIC__/plugs/ckeditor4/ckeditor.js?v={$version}" charset="utf-8"></script>
<script src="/static/plugs/ckeditor4/ckeditor.js?v={$version}" charset="utf-8"></script>
{/case}
{case wangEditor}
<link rel="stylesheet" href="__STATIC__/plugs/wangEditor/dist/style.css?v={$version}">
<script src="__STATIC__/plugs/wangEditor/dist/index.js?v={$version}"></script>
<link rel="stylesheet" href="/static/plugs/wangEditor/dist/style.css?v={$version}">
<script src="/static/plugs/wangEditor/dist/index.js?v={$version}"></script>
{/case}
{default /}
<script src="__STATIC__/plugs/ueditor/ueditor.config.js?v={$version}" charset="utf-8"></script>
<script src="__STATIC__/plugs/ueditor/ueditor.all.js?v={$version}" charset="utf-8"></script>
<script src="__STATIC__/plugs/ueditor/lang/zh-cn/zh-cn.js?v={$version}" charset="utf-8"></script>
<script src="__STATIC__/plugs/ueditor/third-party/codemirror/codemirror.js?v={$version}" charset="utf-8"></script>
<script src="__STATIC__/plugs/ueditor/third-party/zeroclipboard/zeroclipboard.js?v={$version}" charset="utf-8"></script>
<script src="/static/plugs/ueditor/ueditor.config.js?v={$version}" charset="utf-8"></script>
<script src="/static/plugs/ueditor/ueditor.all.js?v={$version}" charset="utf-8"></script>
<script src="/static/plugs/ueditor/lang/zh-cn/zh-cn.js?v={$version}" charset="utf-8"></script>
<script src="/static/plugs/ueditor/third-party/codemirror/codemirror.js?v={$version}" charset="utf-8"></script>
<script src="/static/plugs/ueditor/third-party/zeroclipboard/zeroclipboard.js?v={$version}" charset="utf-8"></script>
{/switch}

View File

@@ -1,14 +1,14 @@
<link rel="stylesheet" href="__STATIC__/admin/css/login.css?v={$version}" media="all">
<link rel="stylesheet" href="/static/admin/css/login.css?v={$version}" media="all">
<div class="container">
<div class="main-body">
<div class="login-main">
<div class="login-top">
<span>{:sysconfig('site','site_name')}</span>
<span>{:sysConfig('site','site_name')}</span>
<span class="bg1"></span>
<span class="bg2"></span>
</div>
<form class="layui-form login-bottom">
<div class="demo{if !$demo} layui-hide{/if}">用户名:admin 密码:123456</div>
<div class="demo {if !$isDemo}layui-hide{/if}">用户名:admin 密码:123456</div>
<div class="center">
<div class="item">
@@ -42,9 +42,9 @@
</div>
</div>
<div class="footer">
{:sysconfig('site','site_copyright')}<span class="padding-5">|</span><a target="_blank" href="http://www.miitbeian.gov.cn">{:sysconfig('site','site_beian')}</a>
{:sysConfig('site','site_copyright')}<span class="padding-5">|</span><a target="_blank" href="http://www.miitbeian.gov.cn">{:sysConfig('site','site_beian')}</a>
</div>
</div>
<script>
let backgroundUrl = "{:sysconfig('site','admin_background')}"
let backgroundUrl = "{:sysConfig('site','admin_background')}"
</script>

View File

@@ -3,7 +3,7 @@
<div class="layui-form-item">
<label class="layui-form-label">LOGO标题</label>
<div class="layui-input-block">
<input type="text" name="logo_title" class="layui-input" lay-verify="required" placeholder="请输入LOGO标题" value="{:sysconfig('site','logo_title')}">
<input type="text" name="logo_title" class="layui-input" lay-verify="required" placeholder="请输入LOGO标题" value="{:sysConfig('site','logo_title')}">
<tip>填写站点名称。</tip>
</div>
</div>
@@ -11,7 +11,7 @@
<div class="layui-form-item">
<label class="layui-form-label">LOGO图标</label>
<div class="layui-input-block layuimini-upload">
<input name="logo_image" class="layui-input layui-col-xs6" lay-verify="required" placeholder="请上传LOGO图标" value="{:sysconfig('site','logo_image')}">
<input name="logo_image" class="layui-input layui-col-xs6" lay-verify="required" placeholder="请上传LOGO图标" value="{:sysConfig('site','logo_image')}">
<div class="layuimini-upload-btn">
<span><a class="layui-btn" data-upload="logo_image" data-upload-number="one" data-upload-exts="ico|png|jpg|jpeg"><i class="fa fa-upload"></i> 上传</a></span>
<span><a class="layui-btn layui-btn-normal" id="select_logo_image" data-upload-select="logo_image" data-upload-number="one"><i class="fa fa-list"></i> 选择</a></span>

View File

@@ -3,7 +3,7 @@
<div class="layui-form-item">
<label class="layui-form-label">站点名称</label>
<div class="layui-input-block">
<input type="text" name="site_name" class="layui-input" lay-verify="required" placeholder="请输入站点名称" value="{:sysconfig('site','site_name')}">
<input type="text" name="site_name" class="layui-input" lay-verify="required" placeholder="请输入站点名称" value="{:sysConfig('site','site_name')}">
<tip>填写站点名称。</tip>
</div>
</div>
@@ -11,7 +11,7 @@
<div class="layui-form-item">
<label class="layui-form-label">浏览器图标ico格式</label>
<div class="layui-input-block layuimini-upload">
<input name="site_ico" class="layui-input layui-col-xs6" lay-verify="required" placeholder="请上传浏览器图标,ico类型" value="{:sysconfig('site','site_ico')}">
<input name="site_ico" class="layui-input layui-col-xs6" lay-verify="required" placeholder="请上传浏览器图标,ico类型" value="{:sysConfig('site','site_ico')}">
<div class="layuimini-upload-btn">
<span><a class="layui-btn" data-upload="site_ico" data-upload-number="one" data-upload-exts="ico"><i class="fa fa-upload"></i> 上传</a></span>
<span><a class="layui-btn layui-btn-normal" id="select_site_ico" data-upload-select="site_ico" data-upload-number="one"><i class="fa fa-list"></i> 选择</a></span>
@@ -22,7 +22,7 @@
<div class="layui-form-item">
<label class="layui-form-label">后台背景图</label>
<div class="layui-input-block layuimini-upload">
<input name="admin_background" class="layui-input layui-col-xs6" placeholder="不填默认#333333" value="{:sysconfig('site','admin_background')}">
<input name="admin_background" class="layui-input layui-col-xs6" placeholder="不填默认#333333" value="{:sysConfig('site','admin_background')}">
<div class="layuimini-upload-btn">
<span><a class="layui-btn" data-upload="site_ico" data-upload-number="one" data-upload-exts="png|jpg|jpeg"><i class="fa fa-upload"></i> 上传</a></span>
<span><a class="layui-btn layui-btn-normal" id="select_admin_background" data-upload-select="admin_background" data-upload-number="one"><i class="fa fa-list"></i> 选择</a></span>
@@ -33,7 +33,7 @@
<div class="layui-form-item">
<label class="layui-form-label">版本信息</label>
<div class="layui-input-block">
<input type="text" name="site_version" class="layui-input" lay-verify="required" placeholder="请输入版本信息" value="{:sysconfig('site','site_version')}">
<input type="text" name="site_version" class="layui-input" lay-verify="required" placeholder="请输入版本信息" value="{:sysConfig('site','site_version')}">
<tip>填写版本信息。</tip>
</div>
</div>
@@ -41,7 +41,7 @@
<div class="layui-form-item">
<label class="layui-form-label">备案信息</label>
<div class="layui-input-block">
<input type="text" name="site_beian" class="layui-input" lay-verify="required" placeholder="请输入备案信息" value="{:sysconfig('site','site_beian')}">
<input type="text" name="site_beian" class="layui-input" lay-verify="required" placeholder="请输入备案信息" value="{:sysConfig('site','site_beian')}">
<tip>填写备案信息。</tip>
</div>
</div>
@@ -49,7 +49,7 @@
<div class="layui-form-item">
<label class="layui-form-label">版权信息</label>
<div class="layui-input-block">
<input type="text" name="site_copyright" class="layui-input" lay-verify="required" placeholder="请输入版权信息" value="{:sysconfig('site','site_copyright')}">
<input type="text" name="site_copyright" class="layui-input" lay-verify="required" placeholder="请输入版权信息" value="{:sysConfig('site','site_copyright')}">
<tip>填写版权信息。</tip>
</div>
</div>
@@ -59,7 +59,7 @@
<label class="layui-form-label">默认编辑器</label>
<div class="layui-input-block">
{foreach $editor_types as $key=>$val}
<input type="radio" name="editor_type" lay-filter="editor_type" value="{$key}" title="{$val}" {if $key==sysconfig('site','editor_type')}checked=""{/if}>
<input type="radio" name="editor_type" lay-filter="editor_type" value="{$key}" title="{$val}" {if $key==sysConfig('site','editor_type')}checked=""{/if}>
{/foreach}
<br>
<tip>默认百度编辑器。</tip>

View File

@@ -3,7 +3,7 @@
<label class="layui-form-label required">存储方式</label>
<div class="layui-input-block">
{foreach $upload_types as $key=>$val}
<input type="radio" v-model="upload_type" name="upload_type" lay-filter="upload_type" value="{$key}" title="{$val}" {if $key==sysconfig('upload','upload_type')}checked=""{/if}>
<input type="radio" v-model="upload_type" name="upload_type" lay-filter="upload_type" value="{$key}" title="{$val}" {if $key==sysConfig('upload','upload_type')}checked=""{/if}>
{/foreach}
</div>
</div>
@@ -11,7 +11,7 @@
<div class="layui-form-item">
<label class="layui-form-label required">允许类型</label>
<div class="layui-input-block">
<input type="text" name="upload_allow_ext" class="layui-input" lay-verify="required" lay-reqtext="请输入允许类型" placeholder="请输入允许类型" value="{:sysconfig('upload','upload_allow_ext')}">
<input type="text" name="upload_allow_ext" class="layui-input" lay-verify="required" lay-reqtext="请输入允许类型" placeholder="请输入允许类型" value="{:sysConfig('upload','upload_allow_ext')}">
<tip>英文逗号做分隔符。</tip>
</div>
</div>
@@ -19,7 +19,7 @@
<div class="layui-form-item">
<label class="layui-form-label required">允许大小</label>
<div class="layui-input-block">
<input type="text" name="upload_allow_size" class="layui-input" lay-verify="required" lay-reqtext="请输入允许上传大小" placeholder="请输入允许上传大小" value="{:sysconfig('upload','upload_allow_size')}">
<input type="text" name="upload_allow_size" class="layui-input" lay-verify="required" lay-reqtext="请输入允许上传大小" placeholder="请输入允许上传大小" value="{:sysConfig('upload','upload_allow_size')}">
<tip>设置允许上传大小。</tip>
</div>
</div>
@@ -27,7 +27,7 @@
<div class="layui-form-item" v-if="upload_type == 'oss'" v-cloak>
<label class="layui-form-label required">公钥信息</label>
<div class="layui-input-block">
<input type="text" name="oss_access_key_id" class="layui-input" lay-verify="required" lay-reqtext="请输入公钥信息" placeholder="请输入公钥信息" value="{:sysconfig('upload','oss_access_key_id')}">
<input type="text" name="oss_access_key_id" class="layui-input" lay-verify="required" lay-reqtext="请输入公钥信息" placeholder="请输入公钥信息" value="{:sysConfig('upload','oss_access_key_id')}">
<tip>例子FSGGshu64642THSk</tip>
</div>
</div>
@@ -35,7 +35,7 @@
<div class="layui-form-item" v-if="upload_type == 'oss'" v-cloak>
<label class="layui-form-label required">私钥信息</label>
<div class="layui-input-block">
<input type="text" name="oss_access_key_secret" class="layui-input" lay-verify="required" lay-reqtext="请输入私钥信息" placeholder="请输入私钥信息" value="{:sysconfig('upload','oss_access_key_secret')}">
<input type="text" name="oss_access_key_secret" class="layui-input" lay-verify="required" lay-reqtext="请输入私钥信息" placeholder="请输入私钥信息" value="{:sysConfig('upload','oss_access_key_secret')}">
<tip>例子5fsfPReYKkFSGGshu64642THSkmTInaIm</tip>
</div>
</div>
@@ -43,7 +43,7 @@
<div class="layui-form-item" v-if="upload_type == 'oss'" v-cloak>
<label class="layui-form-label required">数据中心</label>
<div class="layui-input-block">
<input type="text" name="oss_endpoint" class="layui-input" lay-verify="required" lay-reqtext="请输入数据中心" placeholder="请输入数据中心" value="{:sysconfig('upload','oss_endpoint')}">
<input type="text" name="oss_endpoint" class="layui-input" lay-verify="required" lay-reqtext="请输入数据中心" placeholder="请输入数据中心" value="{:sysConfig('upload','oss_endpoint')}">
<tip>例子https://oss-cn-shenzhen.aliyuncs.com</tip>
</div>
</div>
@@ -51,7 +51,7 @@
<div class="layui-form-item" v-if="upload_type == 'oss'" v-cloak>
<label class="layui-form-label required">空间名称</label>
<div class="layui-input-block">
<input type="text" name="oss_bucket" class="layui-input" lay-verify="required" lay-reqtext="请输入空间名称" placeholder="请输入空间名称" value="{:sysconfig('upload','oss_bucket')}">
<input type="text" name="oss_bucket" class="layui-input" lay-verify="required" lay-reqtext="请输入空间名称" placeholder="请输入空间名称" value="{:sysConfig('upload','oss_bucket')}">
<tip>例子easy-admin</tip>
</div>
</div>
@@ -59,7 +59,7 @@
<div class="layui-form-item" v-if="upload_type == 'oss'" v-cloak>
<label class="layui-form-label required">访问域名</label>
<div class="layui-input-block">
<input type="text" name="oss_domain" class="layui-input" lay-verify="required" lay-reqtext="请输入访问域名" placeholder="请输入访问域名" value="{:sysconfig('upload','oss_domain')}">
<input type="text" name="oss_domain" class="layui-input" lay-verify="required" lay-reqtext="请输入访问域名" placeholder="请输入访问域名" value="{:sysConfig('upload','oss_domain')}">
<tip>例子easy-admin.oss-cn-shenzhen.aliyuncs.com</tip>
</div>
</div>
@@ -67,7 +67,7 @@
<div class="layui-form-item" v-if="upload_type == 'cos'" v-cloak>
<label class="layui-form-label required">公钥信息</label>
<div class="layui-input-block">
<input type="text" name="cos_secret_id" class="layui-input" lay-verify="required" lay-reqtext="请输入公钥信息" placeholder="请输入公钥信息" value="{:sysconfig('upload','cos_secret_id')}">
<input type="text" name="cos_secret_id" class="layui-input" lay-verify="required" lay-reqtext="请输入公钥信息" placeholder="请输入公钥信息" value="{:sysConfig('upload','cos_secret_id')}">
<tip>例子AKIDta6OQCbALQGrCI6ngKwQffR3dfsfrwrfs</tip>
</div>
</div>
@@ -75,7 +75,7 @@
<div class="layui-form-item" v-if="upload_type == 'cos'" v-cloak>
<label class="layui-form-label required">私钥信息</label>
<div class="layui-input-block">
<input type="text" name="cos_secret_key" class="layui-input" lay-verify="required" lay-reqtext="请输入私钥信息" placeholder="请输入私钥信息" value="{:sysconfig('upload','cos_secret_key')}">
<input type="text" name="cos_secret_key" class="layui-input" lay-verify="required" lay-reqtext="请输入私钥信息" placeholder="请输入私钥信息" value="{:sysConfig('upload','cos_secret_key')}">
<tip>例子VllEWYKtClAbpqfFdTqysXxGQM6dsfs</tip>
</div>
</div>
@@ -83,7 +83,7 @@
<div class="layui-form-item" v-if="upload_type == 'cos'" v-cloak>
<label class="layui-form-label required">存储桶地域</label>
<div class="layui-input-block">
<input type="text" name="cos_region" class="layui-input" lay-verify="required" lay-reqtext="请输入存储桶地域" placeholder="请输入存储桶地域" value="{:sysconfig('upload','cos_region')}">
<input type="text" name="cos_region" class="layui-input" lay-verify="required" lay-reqtext="请输入存储桶地域" placeholder="请输入存储桶地域" value="{:sysConfig('upload','cos_region')}">
<tip>例子ap-guangzhou</tip>
</div>
</div>
@@ -91,7 +91,7 @@
<div class="layui-form-item" v-if="upload_type == 'cos'" v-cloak>
<label class="layui-form-label required">存储桶名称</label>
<div class="layui-input-block">
<input type="text" name="cos_bucket" class="layui-input" lay-verify="required" lay-reqtext="请输入存储桶名称" placeholder="请输入存储桶名称" value="{:sysconfig('upload','cos_bucket')}">
<input type="text" name="cos_bucket" class="layui-input" lay-verify="required" lay-reqtext="请输入存储桶名称" placeholder="请输入存储桶名称" value="{:sysConfig('upload','cos_bucket')}">
<tip>例子easyadmin-1251997243</tip>
</div>
</div>
@@ -99,7 +99,7 @@
<div class="layui-form-item" v-if="upload_type == 'qnoss'" v-cloak>
<label class="layui-form-label required">公钥信息</label>
<div class="layui-input-block">
<input type="text" name="qnoss_access_key" class="layui-input" lay-verify="required" lay-reqtext="请输入公钥信息" placeholder="请输入公钥信息" value="{:sysconfig('upload','qnoss_access_key')}">
<input type="text" name="qnoss_access_key" class="layui-input" lay-verify="required" lay-reqtext="请输入公钥信息" placeholder="请输入公钥信息" value="{:sysConfig('upload','qnoss_access_key')}">
<tip>例子v-lV3tXev7yyfsfa1jRc6_8rFOhFYGQvvjsAQxdrB</tip>
</div>
</div>
@@ -107,7 +107,7 @@
<div class="layui-form-item" v-if="upload_type == 'qnoss'" v-cloak>
<label class="layui-form-label required">私钥信息</label>
<div class="layui-input-block">
<input type="text" name="qnoss_secret_key" class="layui-input" lay-verify="required" lay-reqtext="请输入私钥信息" placeholder="请输入私钥信息" value="{:sysconfig('upload','qnoss_secret_key')}">
<input type="text" name="qnoss_secret_key" class="layui-input" lay-verify="required" lay-reqtext="请输入私钥信息" placeholder="请输入私钥信息" value="{:sysConfig('upload','qnoss_secret_key')}">
<tip>例子XOhYRR9JNqxsWVEO-mHWB4193vfsfsQADuORaXzr</tip>
</div>
</div>
@@ -115,7 +115,7 @@
<div class="layui-form-item" v-if="upload_type == 'qnoss'" v-cloak>
<label class="layui-form-label required">存储空间</label>
<div class="layui-input-block">
<input type="text" name="qnoss_bucket" class="layui-input" lay-verify="required" lay-reqtext="请输入存储桶地域" placeholder="请输入存储桶地域" value="{:sysconfig('upload','qnoss_bucket')}">
<input type="text" name="qnoss_bucket" class="layui-input" lay-verify="required" lay-reqtext="请输入存储桶地域" placeholder="请输入存储桶地域" value="{:sysConfig('upload','qnoss_bucket')}">
<tip>例子easyadmin</tip>
</div>
</div>
@@ -123,7 +123,7 @@
<div class="layui-form-item" v-if="upload_type == 'qnoss'" v-cloak>
<label class="layui-form-label required">访问域名</label>
<div class="layui-input-block">
<input type="text" name="qnoss_domain" class="layui-input" lay-verify="required" lay-reqtext="请输入访问域名" placeholder="请输入访问域名" value="{:sysconfig('upload','qnoss_domain')}">
<input type="text" name="qnoss_domain" class="layui-input" lay-verify="required" lay-reqtext="请输入访问域名" placeholder="请输入访问域名" value="{:sysConfig('upload','qnoss_domain')}">
<tip>例子http://q0xqzappp.bkt.clouddn.com</tip>
</div>
</div>
@@ -136,5 +136,5 @@
</form>
<script>
var upload_type = "{:sysconfig('upload','upload_type')}";
var upload_type = "{:sysConfig('upload','upload_type')}";
</script>

View File

@@ -8,7 +8,7 @@
<div class="layui-form-item">
<label class="layui-form-label">数据库表前缀</label>
<div class="layui-input-block">
<input type="text" name="tb_prefix" class="layui-input" placeholder="请输入" value="{:env('DATABASE.PREFIX','')}">
<input type="text" name="tb_prefix" class="layui-input" placeholder="请输入" value="{:env('DB_PREFIX','')}">
<tip>可为空,为空则不带前缀</tip>
</div>
</div>

View File

@@ -3,7 +3,7 @@
display: none;
}
</style>
<link rel="stylesheet" href="__STATIC__/plugs/lay-module/autocomplete/autocomplete.css?v={$version}" media="all">
<link rel="stylesheet" href="/static/plugs/lay-module/autocomplete/autocomplete.css?v={$version}" media="all">
<div class="layuimini-container">
<form id="app-form" class="layui-form layuimini-form">

View File

@@ -3,7 +3,7 @@
display: none;
}
</style>
<link rel="stylesheet" href="__STATIC__/plugs/lay-module/autocomplete/autocomplete.css?v={$version}" media="all">
<link rel="stylesheet" href="/static/plugs/lay-module/autocomplete/autocomplete.css?v={$version}" media="all">
<div class="layuimini-container">
<form id="app-form" class="layui-form layuimini-form">

View File

@@ -1,4 +1,4 @@
<link rel="stylesheet" href="__STATIC__/plugs/lay-module/treetable-lay/treetable.css?v={$version}" media="all">
<link rel="stylesheet" href="/static/plugs/lay-module/treetable-lay/treetable.css?v={$version}" media="all">
<style>
.layui-btn:not(.layui-btn-lg ):not(.layui-btn-sm):not(.layui-btn-xs) {
height: 34px;

View File

@@ -3,7 +3,7 @@
display: none;
}
</style>
<link rel="stylesheet" href="__STATIC__/plugs/lay-module/autocomplete/autocomplete.css?v={$version}" media="all">
<link rel="stylesheet" href="/static/plugs/lay-module/autocomplete/autocomplete.css?v={$version}" media="all">
<div class="layuimini-container">
<form id="app-form" class="layui-form layuimini-form">

View File

@@ -3,7 +3,7 @@
display: none;
}
</style>
<link rel="stylesheet" href="__STATIC__/plugs/lay-module/autocomplete/autocomplete.css?v={$version}" media="all">
<link rel="stylesheet" href="/static/plugs/lay-module/autocomplete/autocomplete.css?v={$version}" media="all">
<div class="layuimini-container">
<form id="app-form" class="layui-form layuimini-form">

View File

@@ -2,6 +2,9 @@
// 应用公共文件
use app\common\service\AuthService;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Cache;
if (!function_exists('__url')) {
@@ -14,7 +17,7 @@ if (!function_exists('__url')) {
* @param bool $domain
* @return string
*/
function __url(string $url = '', array $vars = [], $suffix = true, $domain = false)
function __url(string $url = '', array $vars = [], bool $suffix = true, bool $domain = false): string
{
return url($url, $vars, $suffix, $domain)->build();
}
@@ -24,11 +27,10 @@ if (!function_exists('password')) {
/**
* 密码加密算法
* @param $value 需要加密的值
* @param $type 加密类型默认为md5 md5, hash
* @return mixed
* @param $value
* @return string
*/
function password($value)
function password($value): string
{
$value = sha1('blog_') . md5($value) . md5('_encrypt') . sha1($value);
return sha1($value);
@@ -36,49 +38,27 @@ if (!function_exists('password')) {
}
if (!function_exists('xdebug')) {
/**
* debug调试
* @param string|array $data 打印信息
* @param string $type 类型
* @param string $suffix 文件后缀名
* @param bool $force
* @param null $file
* @deprecated 不建议使用建议直接使用框架自带的log组件
*/
function xdebug($data, $type = 'xdebug', $suffix = null, $force = false, $file = null)
{
!is_dir(runtime_path() . 'xdebug/') && mkdir(runtime_path() . 'xdebug/');
if (is_null($file)) {
$file = is_null($suffix) ? runtime_path() . 'xdebug/' . date('Ymd') . '.txt' : runtime_path() . 'xdebug/' . date('Ymd') . "_{$suffix}" . '.txt';
}
file_put_contents($file, "[" . date('Y-m-d H:i:s') . "] " . "========================= {$type} ===========================" . PHP_EOL, FILE_APPEND);
$str = ((is_string($data) ? $data : (is_array($data) || is_object($data))) ? print_r($data, true) : var_export($data, true)) . PHP_EOL;
$force ? file_put_contents($file, $str) : file_put_contents($file, $str, FILE_APPEND);
}
}
if (!function_exists('sysconfig')) {
if (!function_exists('sysConfig')) {
/**
* 获取系统配置信息
* @param $group
* @param null $name
* @return array|mixed
* @param $name
* @return mixed
*/
function sysconfig($group, $name = null)
function sysConfig($group, $name = null): mixed
{
$where = ['group' => $group];
$value = empty($name) ? Cache::get("sysconfig_{$group}") : Cache::get("sysconfig_{$group}_{$name}");
$value = empty($name) ? Cache::get("sysConfig_{$group}") : Cache::get("sysConfig_{$group}_{$name}");
if (empty($value)) {
if (!empty($name)) {
$where['name'] = $name;
$value = \app\admin\model\SystemConfig::where($where)->value('value');
Cache::tag('sysconfig')->set("sysconfig_{$group}_{$name}", $value, 3600);
} else {
Cache::tag('sysConfig')->set("sysConfig_{$group}_{$name}", $value, 3600);
}else {
$value = \app\admin\model\SystemConfig::where($where)->column('value', 'name');
Cache::tag('sysconfig')->set("sysconfig_{$group}", $value, 3600);
Cache::tag('sysConfig')->set("sysConfig_{$group}", $value, 3600);
}
}
return $value;
@@ -93,7 +73,7 @@ if (!function_exists('array_format_key')) {
* @param $key
* @return array
*/
function array_format_key($array, $key)
function array_format_key($array, $key): array
{
$newArray = [];
foreach ($array as $vo) {
@@ -110,15 +90,14 @@ if (!function_exists('auth')) {
* auth权限验证
* @param $node
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
function auth($node = null)
function auth($node = null): bool
{
$authService = new AuthService(session('admin.id'));
$check = $authService->checkNode($node);
return $check;
return $authService->checkNode($node);
}
/**
@@ -129,11 +108,11 @@ if (!function_exists('auth')) {
*/
function editor_textarea(string $detail, string $name = 'desc', string $placeholder = '请输入'): string
{
$editor_type = sysconfig('site', 'editor_type');
$editor_type = sysConfig('site', 'editor_type');
return match ($editor_type) {
'ckeditor' => "<textarea name='{$name}' rows='20' class='layui-textarea editor' placeholder='{$placeholder}'>{$detail}</textarea>",
'ckeditor' => "<textarea name='{$name}' rows='20' class='layui-textarea editor' placeholder='{$placeholder}'>{$detail}</textarea>",
'wangEditor' => "<div class='wangEditor_div'><textarea name='{$name}' rows='20' class='layui-textarea editor layui-hide'>{$detail}</textarea><div id='editor_toolbar_{$name}'></div><div id='editor_{$name}' style='height: 300px'></div></div>",
default => "<script type='text/plain' id='{$name}' name='{$name}' class='editor' data-content='{$detail}'></script>",
default => "<script type='text/plain' id='{$name}' name='{$name}' class='editor' data-content='{$detail}'></script>",
};
}
}

View File

@@ -24,7 +24,7 @@ class OssStatic extends Command
$output->writeln("========正在上传静态资源到OSS上========" . date('Y-m-d H:i:s'));
$dir = root_path() . 'public' . DIRECTORY_SEPARATOR . 'static';
$list = CommonTool::readDirAllFiles($dir);
$uploadConfig = sysconfig('upload');
$uploadConfig = sysConfig('upload');
$uploadPrefix = config('app.oss_static_prefix', 'oss_static_prefix');
foreach ($list as $key => $val) {
list($objectName, $filePath) = [$uploadPrefix . DIRECTORY_SEPARATOR . $key, $val];

View File

@@ -3,25 +3,18 @@
namespace app\common\controller;
use app\admin\service\ConfigService;
use app\admin\traits\Curd;
use app\BaseController;
use app\common\constants\AdminConstant;
use app\common\service\AuthService;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Env;
use app\common\traits\JumpTrait;
use think\facade\View;
use think\helper\Str;
use think\response\Json;
/**
* Class AdminController
* @package app\common\controller
*/
class AdminController extends BaseController
{
use \app\common\traits\JumpTrait;
use Curd;
use JumpTrait;
/**
* 当前模型
@@ -81,39 +74,45 @@ class AdminController extends BaseController
*/
protected bool $isDemo = false;
/**
* @var int|string
*/
protected int|string $adminUid;
/**
* 初始化方法
*/
protected function initialize()
protected function initialize(): void
{
parent::initialize();
$this->layout && $this->app->view->engine()->layout($this->layout);
$this->isDemo = Env::get('EASYADMIN.IS_DEMO', false);
$this->adminUid = request()->adminUserInfo['id'] ?? 0;
$this->isDemo = env('EASYADMIN.IS_DEMO', false);
$this->viewInit();
$this->checkAuth();
}
/**
* 模板变量赋值
* @param string|array $name 模板变量
* @param mixed $value 变量值
* @return mixed
* @param array|string $name 模板变量
* @param mixed|null $value 变量值
*/
public function assign($name, $value = null): mixed
public function assign(array|string $name, mixed $value = null): void
{
return $this->app->view->assign($name, $value);
View::assign($name, $value);
}
/**
* 解析和获取模板内容 用于输出
* @param string $template
* @param array $vars
* @return mixed
* @param bool $layout 是否需要自动布局
* @return string
*/
public function fetch(string $template = '', array $vars = []): mixed
public function fetch(string $template = '', array $vars = [], bool $layout = true): string
{
return $this->app->view->fetch($template, $vars);
if ($layout) View::instance()->engine()->layout('/layout/default');
View::assign($vars);
return View::fetch($template);
}
/**
@@ -158,7 +157,7 @@ class AdminController extends BaseController
$excludes[$key] = $val;
continue;
}
$op = isset($ops[$key]) && !empty($ops[$key]) ? $ops[$key] : '%*%';
$op = !empty($ops[$key]) ? $ops[$key] : '%*%';
if ($this->relationSearch && count(explode('.', $key)) == 1) {
$key = "{$tableName}.{$key}";
}
@@ -195,17 +194,14 @@ class AdminController extends BaseController
public function selectList(): Json
{
$fields = input('selectFields');
$data = $this->model
->where($this->selectWhere)
->field($fields)
->select();
$data = $this->model->where($this->selectWhere)->field($fields)->select()->toArray();
$this->success(null, $data);
}
/**
* 初始化视图参数
*/
private function viewInit()
private function viewInit(): void
{
$request = app()->request;
list($thisModule, $thisController, $thisAction) = [app('http')->getName(), app()->request->controller(), $request->action()];
@@ -215,9 +211,10 @@ class AdminController extends BaseController
}
$autoloadJs = file_exists(root_path('public') . "static/{$thisModule}/js/{$jsPath}.js");
$thisControllerJsPath = "{$thisModule}/js/{$jsPath}.js";
$adminModuleName = config('app.admin_alias_name');
$isSuperAdmin = session('admin.id') == AdminConstant::SUPER_ADMIN_ID;
$adminModuleName = config('admin.alias_name');
$isSuperAdmin = $this->adminUid == AdminConstant::SUPER_ADMIN_ID;
$data = [
'isDemo' => $this->isDemo,
'adminModuleName' => $adminModuleName,
'thisController' => parse_name($thisController),
'thisAction' => $thisAction,
@@ -227,60 +224,16 @@ class AdminController extends BaseController
'isSuperAdmin' => $isSuperAdmin,
'version' => env('APP_DEBUG') ? time() : ConfigService::getVersion(),
'adminUploadUrl' => url('ajax/upload', [], false),
'adminEditor' => sysconfig('site', 'editor_type') ?: 'ueditor',
'adminEditor' => sysConfig('site', 'editor_type') ?: 'ueditor',
];
View::assign($data);
}
/**
* 检测权限
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
private function checkAuth()
{
$adminConfig = config('admin');
$adminId = session('admin.id');
$expireTime = session('admin.expire_time');
/** @var AuthService $authService */
$authService = app(AuthService::class, ['adminId' => $adminId]);
$currentNode = $authService->getCurrentNode();
$currentController = parse_name(app()->request->controller());
// 验证登录
if (
!in_array($currentController, $adminConfig['no_login_controller'])
&& !in_array($currentNode, $adminConfig['no_login_node'])) {
empty($adminId) && $this->error('请先登录后台', [], __url('admin/login/index'));
// 判断是否登录过期
if ($expireTime !== true && time() > $expireTime) {
session('admin', null);
$this->error('登录已过期,请重新登录', [], __url('admin/login/index'));
}
}
// 验证权限
if (
!in_array($currentController, $adminConfig['no_auth_controller'])
&& !in_array($currentNode, $adminConfig['no_auth_node'])) {
$check = $authService->checkNode($currentNode);
!$check && $this->error('无权限访问');
// 判断是否为演示环境
if (env('EASYADMIN.IS_DEMO', false) && app()->request->isPost()) {
$this->error('演示环境下不允许修改');
}
}
}
/**
* 严格校验接口是否为POST请求
*/
protected function checkPostRequest()
protected function checkPostRequest(): void
{
if (!$this->request->isPost()) {
$this->error("当前请求不合法!");

View File

@@ -1,59 +1,161 @@
{__NOLAYOUT__}<!DOCTYPE html>
<html>
<!DOCTYPE html>
<html lang="">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>跳转提示</title>
<style type="text/css">
*{box-sizing:border-box;margin:0;padding:0;font-family:Lantinghei SC,Open Sans,Arial,Hiragino Sans GB,Microsoft YaHei,"微软雅黑",STHeiti,WenQuanYi Micro Hei,SimSun,sans-serif;-webkit-font-smoothing:antialiased}
body{padding:70px 0;background:#edf1f4;font-weight:400;font-size:1pc;-webkit-text-size-adjust:none;color:#333}
a{outline:0;color:#3498db;text-decoration:none;cursor:pointer}
.system-message{margin:20px 5%;padding:40px 20px;background:#fff;box-shadow:1px 1px 1px hsla(0,0%,39%,.1);text-align:center}
.system-message h1{margin:0;margin-bottom:9pt;color:#444;font-weight:400;font-size:40px}
.system-message .jump,.system-message .image{margin:20px 0;padding:0;padding:10px 0;font-weight:400}
.system-message .jump{font-size:14px}
.system-message .jump a{color:#333}
.system-message p{font-size:9pt;line-height:20px}
.system-message .btn{display:inline-block;margin-right:10px;width:138px;height:2pc;border:1px solid #44a0e8;border-radius:30px;color:#44a0e8;text-align:center;font-size:1pc;line-height:2pc;margin-bottom:5px;}
.success .btn{border-color:#69bf4e;color:#69bf4e}
.error .btn{border-color:#ff8992;color:#ff8992}
.info .btn{border-color:#3498db;color:#3498db}
.copyright p{width:100%;color:#919191;text-align:center;font-size:10px}
.system-message .btn-grey{border-color:#bbb;color:#bbb}
.clearfix:after{clear:both;display:block;visibility:hidden;height:0;content:"."}
@media (max-width:768px){body {padding:20px 0;}}
@media (max-width:480px){.system-message h1{font-size:30px;}}
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: Lantinghei SC, Open Sans, Arial, Hiragino Sans GB, Microsoft YaHei, "微软雅黑", STHeiti, WenQuanYi Micro Hei, SimSun, sans-serif;
-webkit-font-smoothing: antialiased
}
body {
padding: 70px 0;
background: #edf1f4;
font-weight: 400;
font-size: 1pc;
-webkit-text-size-adjust: none;
color: #333
}
a {
outline: 0;
color: #3498db;
text-decoration: none;
cursor: pointer
}
.system-message {
margin: 20px 5%;
padding: 40px 20px;
background: #fff;
box-shadow: 1px 1px 1px hsla(0, 0%, 39%, .1);
text-align: center
}
.system-message h1 {
margin: 0;
margin-bottom: 9pt;
color: #444;
font-weight: 400;
font-size: 40px
}
.system-message .jump, .system-message .image {
margin: 20px 0;
padding: 0;
padding: 10px 0;
font-weight: 400
}
.system-message .jump {
font-size: 14px
}
.system-message .jump a {
color: #333
}
.system-message p {
font-size: 9pt;
line-height: 20px
}
.system-message .btn {
display: inline-block;
margin-right: 10px;
width: 138px;
height: 2pc;
border: 1px solid #44a0e8;
border-radius: 30px;
color: #44a0e8;
text-align: center;
font-size: 1pc;
line-height: 2pc;
margin-bottom: 5px;
}
.success .btn {
border-color: #69bf4e;
color: #69bf4e
}
.error .btn {
border-color: #ff8992;
color: #ff8992
}
.info .btn {
border-color: #3498db;
color: #3498db
}
.copyright p {
width: 100%;
color: #919191;
text-align: center;
font-size: 10px
}
.system-message .btn-grey {
border-color: #bbb;
color: #bbb
}
.clearfix:after {
clear: both;
display: block;
visibility: hidden;
height: 0;
content: "."
}
@media (max-width: 768px) {
body {
padding: 20px 0;
}
}
@media (max-width: 480px) {
.system-message h1 {
font-size: 30px;
}
}
</style>
</head>
<body>
<?php
$codeText = $code == 1 ? 'success' : ($code == 0 ? 'error' : 'info');
?>
<div class="system-message {$codeText}">
<div class="image">
<img src="/static/common/images/{$codeText}.svg" alt="" width="150" />
</div>
<h1><?php echo(strip_tags($msg));?></h1>
<p class="jump">
页面将在 <span id="wait"><?php echo($wait);?></span> 秒后自动跳转
</p>
<p class="clearfix">
<a href="#" onClick="javascript :history.back(-1);" class="btn btn-grey">返回上一页</a>
<a id="href" href="{$url}" class="btn btn-primary">立即跳转</a>
</p>
<div class="system-message {$codeText}">
<div class="image">
<img src="/static/common/images/{$codeText}.svg" alt="" width="150"/>
</div>
<script type="text/javascript">
(function(){
var wait = document.getElementById('wait'),
href = document.getElementById('href').href;
var interval = setInterval(function(){
var time = --wait.innerHTML;
if(time <= 0) {
location.href = href;
clearInterval(interval);
};
}, 1000);
})();
</script>
<h1><?php echo(strip_tags($msg));?></h1>
<p class="jump">
页面将在 <span id="wait"><?php echo($wait);?></span> 秒后自动跳转
</p>
<p class="clearfix">
<a href="#" onClick="history.back(-1);" class="btn btn-grey">返回上一页</a>
<a id="href" href="{$url}" class="btn btn-primary">立即跳转</a>
</p>
</div>
<script type="text/javascript">
(function () {
var wait = document.getElementById('wait'),
href = document.getElementById('href').href;
var interval = setInterval(function () {
var time = --wait.innerHTML;
if (time <= 0) {
location.href = href;
clearInterval(interval);
}
}, 1000);
})();
</script>
</body>
</html>

View File

@@ -15,22 +15,20 @@ trait JumpTrait
/**
* 操作成功跳转的快捷方法
* @access protected
* @param mixed $msg 提示信息
* @param mixed $data 返回的数据
* @param string $url 跳转的 URL 地址
* @param int $wait 跳转等待时间
* @param array $header 发送的 Header 信息
* @param string|null $msg 提示信息
* @param mixed|string $data 返回的数据
* @param string|null $url 跳转的 URL 地址
* @param int $wait 跳转等待时间
* @param array $header 发送的 Header 信息
* @return void
* @throws HttpResponseException
*/
protected function success($msg = '', $data = '', $url = null, $wait = 3, array $header = [])
protected function success(?string $msg = null, mixed $data = '', ?string $url = null, int $wait = 3, array $header = []): void
{
if (is_null($url) && isset($_SERVER["HTTP_REFERER"])) {
$url = $_SERVER["HTTP_REFERER"];
} elseif ($url) {
$url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : app('route')->buildUrl($url)->__toString();
if (is_null($url)) {
$url = app()->request->server('HTTP_REFERER');
}elseif ($url) {
$url = (strpos($url, '://') || str_starts_with($url, '/')) ? $url : app('route')->buildUrl($url)->__toString();
}
$result = [
'code' => 1,
'msg' => $msg,
@@ -42,8 +40,8 @@ trait JumpTrait
$type = $this->getResponseType();
if ($type == 'html') {
$response = view(app('config')->get('app.dispatch_success_tmpl'), $result);
} elseif ($type == 'json') {
$response = view(config('app.dispatch_success_tmpl'), $result);
}else {
$response = json($result);
}
throw new HttpResponseException($response);
@@ -52,20 +50,19 @@ trait JumpTrait
/**
* 操作错误跳转的快捷方法
* @access protected
* @param mixed $msg 提示信息
* @param mixed $data 返回的数据
* @param string $url 跳转的 URL 地址
* @param int $wait 跳转等待时间
* @param array $header 发送的 Header 信息
* @param string|null $msg 提示信息
* @param mixed $data 返回的数据
* @param string|null $url 跳转的 URL 地址
* @param int $wait 跳转等待时间
* @param array $header 发送的 Header 信息
* @return void
* @throws HttpResponseException
*/
protected function error($msg = '', $data = '', $url = null, $wait = 3, array $header = [])
protected function error(?string $msg = null, mixed $data = '', ?string $url = null, int $wait = 3, array $header = []): void
{
if (is_null($url)) {
$url = request()->isAjax() ? '' : 'javascript:history.back(-1);';
} elseif ($url) {
$url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : app('route')->buildUrl($url)->__toString();
}elseif ($url) {
$url = (strpos($url, '://') || str_starts_with($url, '/')) ? $url : app('route')->buildUrl($url)->__toString();
}
$type = $this->getResponseType();
@@ -78,8 +75,8 @@ trait JumpTrait
'__token__' => request()->buildToken('__token__'),
];
if ($type == 'html') {
$response = view(app('config')->get('app.dispatch_error_tmpl'), $result);
} elseif ($type == 'json') {
$response = view(config('app.dispatch_error_tmpl'), $result);
}else {
$response = json($result);
}
throw new HttpResponseException($response);
@@ -88,15 +85,14 @@ trait JumpTrait
/**
* 返回封装后的 API 数据到客户端
* @access protected
* @param mixed $data 要返回的数据
* @param int $code 返回的 code
* @param mixed $msg 提示信息
* @param string $type 返回数据格式
* @param array $header 发送的 Header 信息
* @param mixed $data 要返回的数据
* @param int $code 返回的 code
* @param string|null $msg 提示信息
* @param string $type 返回数据格式
* @param array $header 发送的 Header 信息
* @return void
* @throws HttpResponseException
*/
protected function result($data, $code = 0, $msg = '', $type = '', array $header = [])
protected function result(mixed $data, int $code = 0, ?string $msg = '', string $type = '', array $header = []): void
{
$result = [
'code' => $code,
@@ -106,27 +102,19 @@ trait JumpTrait
];
$type = $type ?: $this->getResponseType();
$response = Response::create($result, $type)->header($header);
throw new HttpResponseException($response);
}
/**
* URL 重定向
* @access protected
* @param string $url 跳转的 URL 表达式
* @param array|int $params 其它 URL 参数
* @param int $code http code
* @param array $with 隐式传参
* @param string $url 跳转的 URL 表达式
* @param int $code http code
* @return void
* @throws HttpResponseException
*/
protected function redirect($url = [], $params = [], $code = 302)
protected function redirect(string $url = '', int $code = 302): void
{
if (is_integer($params)) {
$code = $params;
$params = [];
}
$response = Response::create($url, 'redirect', $code);
throw new HttpResponseException($response);
}
@@ -136,7 +124,7 @@ trait JumpTrait
* @access protected
* @return string
*/
protected function getResponseType()
protected function getResponseType(): string
{
return (request()->isJson() || request()->isAjax() || request()->isPost()) ? 'json' : 'html';
}

View File

@@ -18,17 +18,19 @@ class Install extends BaseController
$installPath = config_path() . DIRECTORY_SEPARATOR . 'install' . DIRECTORY_SEPARATOR;
$errorInfo = null;
if (is_file($installPath . 'lock' . DIRECTORY_SEPARATOR . 'install.lock')) {
// 如果你已经成功安装了后台系统 并且不想再次出现安装界面,可以把下面跳转注释取消
// $this->redirect('/');
$isInstall = true;
$errorInfo = '已安装系统,如需重新安装请删除文件:/config/install/lock/install.lock或者删除 /install 路由';
} elseif (version_compare(phpversion(), '8.0.0', '<')) {
}elseif (version_compare(phpversion(), '8.0.0', '<')) {
$errorInfo = 'PHP版本不能小于8.0.0';
} elseif (!extension_loaded("PDO")) {
}elseif (!extension_loaded("PDO")) {
$errorInfo = '当前未开启PDO无法进行安装';
}
if (!$request->isAjax()) {
$currentHost = '://';
$result = compact('errorInfo', 'currentHost', 'isInstall');
return view('', $result);
return view('index/install/index', $result);
}
if ($errorInfo) $this->error($errorInfo);
$charset = 'utf8mb4';
@@ -53,9 +55,9 @@ class Install extends BaseController
}
if (strlen($adminUrl) < 2) {
$validateError = '后台的地址不能小于2位数';
} elseif (strlen($password) < 5) {
}elseif (strlen($password) < 5) {
$validateError = '管理员密码不能小于5位数';
} elseif (strlen($username) < 4) {
}elseif (strlen($username) < 4) {
$validateError = '管理员账号不能小于4位数';
}
if (!empty($validateError)) $this->error($validateError);
@@ -110,7 +112,7 @@ class Install extends BaseController
!is_dir($installPath) && @mkdir($installPath);
!is_dir($installPath . 'lock' . DIRECTORY_SEPARATOR) && @mkdir($installPath . 'lock' . DIRECTORY_SEPARATOR);
@file_put_contents($installPath . 'lock' . DIRECTORY_SEPARATOR . 'install.lock', date('Y-m-d H:i:s'));
} catch (\Exception|\PDOException|\Throwable $e) {
}catch (\Exception|\PDOException|\Throwable $e) {
$this->error("系统安装失败:" . $e->getMessage());
}
return true;
@@ -160,7 +162,7 @@ class Install extends BaseController
$con = mysqli_connect($config['host'] ?? '127.0.0.1', $config['username'] ?? 'root', $config['password'] ?? '', null, $config['port'] ?? '');
mysqli_query($con, "CREATE DATABASE IF NOT EXISTS `{$database}` DEFAULT CHARACTER SET {$config['charset']} COLLATE=utf8mb4_general_ci");
mysqli_close($con);
} catch (\Throwable $e) {
}catch (\Throwable $e) {
return false;
}
return true;
@@ -170,12 +172,12 @@ class Install extends BaseController
{
try {
$check = Db::query("SELECT * FROM information_schema.schemata WHERE schema_name='{$database}'");
} catch (\Throwable $exception) {
}catch (\Throwable $exception) {
$check = false;
}
if (empty($check)) {
return false;
} else {
}else {
return true;
}
}
@@ -191,7 +193,7 @@ class Install extends BaseController
if (version_compare($_version, '5.7.0', '<')) {
$this->error('mysql版本最低要求 5.7.x');
}
} catch (\mysqli_sql_exception $e) {
}catch (\mysqli_sql_exception $e) {
$this->error($e->getMessage());
}
return true;

View File

@@ -6,5 +6,5 @@ return [
// 多语言加载
// \think\middleware\LoadLangPack::class,
// Session初始化
\think\middleware\SessionInit::class
\think\middleware\SessionInit::class
];

View File

@@ -1,7 +1,9 @@
<?php
declare (strict_types=1);
use app\AppService;
// 系统服务定义文件
// 服务在完成全局初始化之后执行
return [
0 => 'think\\captcha\\CaptchaService',
1 => 'think\\app\\Service',
];
AppService::class,
];

View File

@@ -1,58 +1,63 @@
{
"name": "wolfcode/easyadmin8",
"url": "https://github.com/wolf-leo/EasyAdmin8",
"description": "基于ThinkPHP8.0和Layui的快速开发的后台管理系统。",
"type": "project",
"keywords": [
"thinkphp",
"easyadmin",
"admin"
],
"homepage": "https://easyadmin8.top/",
"license": "MIT",
"authors": [
{
"name": "wolfcode"
}
],
"require": {
"php": ">=8.0.0",
"topthink/framework": "8.0.3",
"topthink/think-orm": "^3.0",
"topthink/think-multi-app": "^1.0",
"topthink/think-view": "^2.0",
"topthink/think-captcha": "^3.0",
"topthink/think-filesystem": "^2.0",
"aliyuncs/oss-sdk-php": "^2.6",
"qcloud/cos-sdk-v5": "^2.6",
"alibabacloud/client": "^1.5",
"jianyan74/php-excel": "^1.0.2",
"doctrine/annotations": "^1.13",
"phpoffice/phpspreadsheet": "^1.28",
"myclabs/php-enum": "^1.8",
"ext-json": "*",
"qiniu/php-sdk": "v7.11.0"
},
"require-dev": {
"symfony/var-dumper": "^4.2",
"eaglewu/swoole-ide-helper": "dev-master"
},
"autoload": {
"psr-4": {
"app\\": "app"
"name": "topthink/think",
"description": "the new thinkphp framework",
"type": "project",
"keywords": [
"framework",
"thinkphp",
"ORM"
],
"homepage": "https://www.thinkphp.cn/",
"license": "Apache-2.0",
"authors": [
{
"name": "liu21st",
"email": "liu21st@gmail.com"
},
{
"name": "yunwuxin",
"email": "448901948@qq.com"
}
],
"require": {
"php": ">=8.0.0",
"topthink/framework": "^8.0",
"topthink/think-orm": "^3.0",
"topthink/think-multi-app": "^1.0",
"topthink/think-view": "^2.0",
"topthink/think-captcha": "^3.0",
"topthink/think-filesystem": "^2.0",
"aliyuncs/oss-sdk-php": "^2.6",
"qcloud/cos-sdk-v5": "^2.6",
"alibabacloud/client": "^1.5",
"jianyan74/php-excel": "^1.0.2",
"doctrine/annotations": "^1.13",
"phpoffice/phpspreadsheet": "^1.28",
"myclabs/php-enum": "^1.8",
"ext-json": "*",
"qiniu/php-sdk": "v7.11.0",
"ext-mysqli": "*",
"ext-pdo": "*"
},
"psr-0": {
"": "extend/"
"require-dev": {
"symfony/var-dumper": ">=4.2",
"topthink/think-trace": "^1.0"
},
"autoload": {
"psr-4": {
"app\\": "app"
},
"psr-0": {
"": "extend/"
}
},
"config": {
"preferred-install": "dist"
},
"scripts": {
"post-autoload-dump": [
"@php think service:discover",
"@php think vendor:publish"
]
}
},
"config": {
"preferred-install": "dist",
"secure-http": false
},
"scripts": {
"post-autoload-dump": [
"@php think service:discover",
"@php think vendor:publish"
]
}
}

View File

@@ -1,14 +0,0 @@
<?php
return [
// 自动加载,插件命令行模式下必须
'autoload' => true,
// 默认插件入口路径
'path' => 'addons',
// 默认方法
'default_action' => 'index',
];

View File

@@ -7,35 +7,32 @@ use think\facade\Env;
return [
// 应用地址
'app_host' => Env::get('APP.HOST', ''),
'app_host' => env('APP_HOST', ''),
// 应用的命名空间
'app_namespace' => '',
// 是否启用路由
'with_route' => true,
// 是否启用事件
'with_event' => true,
// 开启应用快速访问
'app_express' => true,
// 默认应用
'default_app' => 'index',
// 默认时区
'default_timezone' => 'Asia/Shanghai',
// 应用映射(自动多应用模式有效)
'app_map' => [
Env::get('EASYADMIN.ADMIN', 'admin') => 'admin',
],
// 后台别名
'admin_alias_name' => Env::get('EASYADMIN.ADMIN', 'admin'),
// 域名绑定(自动多应用模式有效)
'domain_bind' => [],
// 禁止URL访问的应用列表自动多应用模式有效
'deny_app_list' => ['common'],
// 异常页面的模板文件
'exception_tmpl' => Env::get('APP_DEBUG') == 1 ? app()->getThinkPath() . 'tpl/think_exception.tpl' : app()->getBasePath() . 'common' . DIRECTORY_SEPARATOR . 'tpl' . DIRECTORY_SEPARATOR . 'think_exception.tpl',
// 跳转页面的成功模板文件
'dispatch_success_tmpl' => app()->getBasePath() . 'common' . DIRECTORY_SEPARATOR . 'tpl' . DIRECTORY_SEPARATOR . 'dispatch_jump.tpl',
// 跳转页面的失败模板文件
'dispatch_error_tmpl' => app()->getBasePath() . 'common' . DIRECTORY_SEPARATOR . 'tpl' . DIRECTORY_SEPARATOR . 'dispatch_jump.tpl',
// 错误显示信息,非调试模式有效
'error_message' => '页面错误!请稍后再试~',
// 显示错误信息

View File

@@ -1,14 +1,12 @@
<?php
use think\facade\Env;
// +----------------------------------------------------------------------
// | 缓存设置
// +----------------------------------------------------------------------
return [
// 默认缓存驱动
'default' => Env::get('CACHE.DRIVER', 'file'),
'default' => 'file',
// 缓存连接方式配置
'stores' => [

View File

@@ -7,7 +7,7 @@ return [
//验证码位数
'length' => 4,
// 验证码字符集合
'codeSet' => '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY',
'codeSet' => '1234567890',
// 验证码过期时间
'expire' => 1800,
// 是否使用中文验证码
@@ -17,7 +17,7 @@ return [
// 是否使用背景图
'useImgBg' => false,
//验证码字符大小
'fontSize' => 50,
'fontSize' => 25,
// 是否使用混淆曲线
'useCurve' => true,
//是否添加杂点

View File

@@ -5,8 +5,5 @@
return [
// 指令定义
'commands' => [
'curd' => 'app\common\command\Curd',
'node' => 'app\common\command\Node',
'OssStatic' => 'app\common\command\OssStatic',
],
];

View File

@@ -15,4 +15,6 @@ return [
'httponly' => false,
// 是否使用 setcookie
'setcookie' => true,
// samesite 设置,支持 'strict' 'lax'
'samesite' => '',
];

View File

@@ -1,10 +1,8 @@
<?php
use think\facade\Env;
return [
// 默认使用的数据库连接配置
'default' => Env::get('DATABASE.DRIVER', 'mysql'),
'default' => env('DB_DRIVER', 'mysql'),
// 自定义时间查询规则
'time_query_rule' => [],
@@ -17,46 +15,47 @@ return [
// 时间字段取出后的默认时间格式
'datetime_format' => 'Y-m-d H:i:s',
// 时间字段配置 配置格式create_time,update_time
'datetime_field' => '',
// 数据库连接配置信息
'connections' => [
'mysql' => [
// 数据库类型
'type' => Env::get('DATABASE.TYPE', 'mysql'),
'type' => env('DB_TYPE', 'mysql'),
// 服务器地址
'hostname' => Env::get('DATABASE.HOSTNAME', '127.0.0.1'),
'hostname' => env('DB_HOST', '127.0.0.1'),
// 数据库名
'database' => Env::get('DATABASE.DATABASE', 'easyadmin8'),
'database' => env('DB_NAME', ''),
// 用户名
'username' => Env::get('DATABASE.USERNAME', 'root'),
'username' => env('DB_USER', 'root'),
// 密码
'password' => Env::get('DATABASE.PASSWORD', 'root'),
'password' => env('DB_PASS', ''),
// 端口
'hostport' => Env::get('DATABASE.HOSTPORT', '3306'),
'hostport' => env('DB_PORT', '3306'),
// 数据库连接参数
'params' => [],
'params' => [],
// 数据库编码默认采用utf8
'charset' => Env::get('DATABASE.CHARSET', 'utf8'),
'charset' => env('DB_CHARSET', 'utf8'),
// 数据库表前缀
'prefix' => Env::get('DATABASE.PREFIX', 'ea8_'),
'prefix' => env('DB_PREFIX', ''),
// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
'deploy' => 0,
'deploy' => 0,
// 数据库读写是否分离 主从式有效
'rw_separate' => false,
'rw_separate' => false,
// 读写分离后 主服务器数量
'master_num' => 1,
'master_num' => 1,
// 指定从服务器序号
'slave_no' => '',
'slave_no' => '',
// 是否严格检查字段是否存在
'fields_strict' => true,
'fields_strict' => true,
// 是否需要断线重连
'break_reconnect' => false,
'break_reconnect' => false,
// 监听SQL
'trigger_sql' => true,
'trigger_sql' => env('APP_DEBUG', true),
// 开启字段缓存
'fields_cache' => false,
// 字段缓存路径
'schema_cache_path' => app()->getRuntimePath() . 'schema' . DIRECTORY_SEPARATOR,
'fields_cache' => false,
],
// 更多的数据库配置信息

View File

@@ -1,10 +1,8 @@
<?php
use think\facade\Env;
return [
// 默认磁盘
'default' => Env::get('FILESYSTEM.DRIVER', 'local'),
'default' => 'local',
// 磁盘列表
'disks' => [
'local' => [
@@ -15,7 +13,7 @@ return [
// 磁盘类型
'type' => 'local',
// 磁盘路径
'root' => app()->getRootPath() . 'public',
'root' => app()->getRootPath() . 'public/storage',
// 磁盘路径对应的外部URL路径
'url' => '/storage',
// 可见性

2
config/install/lock/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
install.lock
!.gitignore

View File

@@ -3,11 +3,9 @@
// | 多语言设置
// +----------------------------------------------------------------------
use think\facade\Env;
return [
// 默认语言
'default_lang' => Env::get('LANG.DEFAULT_LANG', 'zh-cn'),
'default_lang' => env('DEFAULT_LANG', 'zh-cn'),
// 允许的语言列表
'allow_lang_list' => [],
// 多语言自动侦测变量名
@@ -16,6 +14,8 @@ return [
'use_cookie' => true,
// 多语言cookie变量
'cookie_var' => 'think_lang',
// 多语言header变量
'header_var' => 'think-lang',
// 扩展语言包
'extend_list' => [],
// Accept-Language转义为对应语言包名称

View File

@@ -1,13 +1,11 @@
<?php
use think\facade\Env;
// +----------------------------------------------------------------------
// | 日志设置
// +----------------------------------------------------------------------
return [
// 默认日志记录通道
'default' => Env::get('LOG.CHANNEL', 'file'),
'default' => 'file',
// 日志记录级别
'level' => [],
// 日志类型记录的通道 ['error'=>'email',...]
@@ -21,7 +19,7 @@ return [
'channels' => [
'file' => [
// 日志记录方式
'type' => 'file',
'type' => 'File',
// 日志保存目录
'path' => '',
// 单文件日志写入
@@ -29,15 +27,13 @@ return [
// 独立日志级别
'apart_level' => [],
// 最大日志文件数量
'max_files' => 30,
'max_files' => 0,
// 使用JSON格式记录
'json' => true,
'json' => false,
// 日志处理
'processor' => null,
// 关闭通道日志写入
'close' => false,
// 格式化时间
'time_format' => 'Y-m-d H:i:s',
// 日志输出格式化
'format' => '[%s][%s] %s',
// 是否实时写入

View File

@@ -7,7 +7,7 @@ return [
// pathinfo分隔符
'pathinfo_depr' => '/',
// URL伪静态后缀
'url_html_suffix' => 'html',
'url_html_suffix' => '',
// URL普通方式参数 用于自动生成
'url_common_param' => true,
// 是否开启路由延迟解析
@@ -27,7 +27,7 @@ return [
// 默认的路由变量规则
'default_route_pattern' => '[\w\.]+',
// 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
'request_cache' => false,
'request_cache_key' => false,
// 请求缓存有效期
'request_cache_expire' => null,
// 全局请求缓存排除规则
@@ -42,9 +42,4 @@ return [
'default_jsonp_handler' => 'jsonpReturn',
// 默认JSONP处理方法
'var_jsonp_handler' => 'callback',
// 系统安装后可以删除该中间件判定
'middleware' => [
\app\admin\middleware\CheckInstall::class
]
];

View File

@@ -13,7 +13,7 @@ return [
// 存储连接标识 当type使用cache的时候有效
'store' => null,
// 过期时间
'expire' => 86400,
'expire' => 1440,
// 前缀
'prefix' => '',
];

View File

@@ -3,32 +3,23 @@
// | 模板设置
// +----------------------------------------------------------------------
use think\facade\Env;
return [
// 模板引擎类型使用Think
'type' => 'Think',
'type' => 'Think',
// 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法
'auto_rule' => 1,
'auto_rule' => 1,
// 模板目录名
'view_dir_name' => 'view',
'view_dir_name' => 'view',
// 模板后缀
'view_suffix' => 'html',
'view_suffix' => 'html',
// 模板文件名分隔符
'view_depr' => DIRECTORY_SEPARATOR,
'view_depr' => DIRECTORY_SEPARATOR,
// 模板引擎普通标签开始标记
'tpl_begin' => '{',
'tpl_begin' => '{',
// 模板引擎普通标签结束标记
'tpl_end' => '}',
'tpl_end' => '}',
// 标签库标签开始标记
'taglib_begin' => '{',
'taglib_begin' => '{',
// 标签库标签结束标记
'taglib_end' => '}',
// 模板缓存
'display_cache' => true,
// 字符替换
'tpl_replace_string' => [
'__STATIC__' => Env::get('EASYADMIN.STATIC_PATH', '/static'),
'__JS__' => '/static/javascript',
]
'taglib_end' => '}',
];

2
extend/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*
!.gitignore

2
log.md Normal file
View File

@@ -0,0 +1,2 @@
>
> 2024年05月 更新 `EasyAdmin8` 重置版,多处语法、写法进行变更

View File

@@ -1,7 +1,8 @@
<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L]
</IfModule>
Options +FollowSymlinks -Multiviews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>

Some files were not shown because too many files have changed in this diff Show More