Compare commits
144 Commits
old-202405
...
v8.1.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e0cc85966 | ||
|
|
5814fed0da | ||
|
|
40f7ee82cd | ||
|
|
936cb56c7f | ||
|
|
2d1940522c | ||
|
|
264cf56ae4 | ||
|
|
57ea9a3f47 | ||
|
|
31c06cff69 | ||
|
|
4c8d21fccf | ||
|
|
817582bed5 | ||
|
|
3a0c0c1624 | ||
|
|
30c7615e53 | ||
|
|
9d58da3cc3 | ||
|
|
1f5ca39226 | ||
|
|
82f17301a7 | ||
|
|
4ef7879ae3 | ||
|
|
0c9b369e2e | ||
|
|
e981852422 | ||
|
|
1d258621c8 | ||
|
|
9534f2c2fe | ||
|
|
9fb8dd022a | ||
|
|
fc264630ec | ||
|
|
3d19c8d337 | ||
|
|
4baa4e185d | ||
|
|
88bc6441e5 | ||
|
|
0efb70b3b7 | ||
|
|
c22be8ac76 | ||
|
|
ebce7f3b0e | ||
|
|
f8b6d847d5 | ||
|
|
55a9b13e69 | ||
|
|
5d58248cf4 | ||
|
|
bbd0320a35 | ||
|
|
d62a67aafe | ||
|
|
c6cc9d4164 | ||
|
|
add8c5144c | ||
|
|
62f591045e | ||
|
|
7470790657 | ||
|
|
11fa69afaf | ||
|
|
8983705ce4 | ||
|
|
95ccd4071b | ||
|
|
09f3ea7e54 | ||
|
|
9cadb27c9e | ||
|
|
2772034a93 | ||
|
|
08ea79033c | ||
|
|
e7f09d9c68 | ||
|
|
e2effb762c | ||
|
|
0e18825808 | ||
|
|
c031b09422 | ||
|
|
231fd48e2f | ||
|
|
53772badd4 | ||
|
|
3e329a4ea3 | ||
|
|
f015a90b89 | ||
|
|
75c668b966 | ||
|
|
f3e5a041d1 | ||
|
|
34354837d5 | ||
|
|
3b219cfe7f | ||
|
|
ed99fe79fd | ||
|
|
846b8ffafc | ||
|
|
47ef5d9f10 | ||
|
|
70ec12f406 | ||
|
|
e15b56ecc9 | ||
|
|
af275e1c6a | ||
|
|
20d4038159 | ||
|
|
475a1ef84d | ||
|
|
9307e724a9 | ||
|
|
6616e96724 | ||
|
|
963febc15c | ||
|
|
f78edd2fd5 | ||
|
|
83aa399f95 | ||
|
|
3096aa8985 | ||
|
|
c7f7ca9af7 | ||
|
|
352484c69e | ||
|
|
dfe15f7e88 | ||
|
|
4d7365921e | ||
|
|
d613f3c26f | ||
|
|
74c21d2397 | ||
|
|
f1d049fc0a | ||
|
|
a6ec0f143a | ||
|
|
a1d4aa97d5 | ||
|
|
4b8e163454 | ||
|
|
c2762fa2ad | ||
|
|
de92299a4f | ||
|
|
a4782ad38e | ||
|
|
36038516e0 | ||
|
|
aeb3b28184 | ||
|
|
cb34bf1758 | ||
|
|
84f0bdcc77 | ||
|
|
ef40aa27b7 | ||
|
|
e69fddd2f7 | ||
|
|
229c74fbea | ||
|
|
336ca82729 | ||
|
|
5b444f7fc1 | ||
|
|
7375b7cbf0 | ||
|
|
62a3d80fa3 | ||
|
|
ea733d0acb | ||
|
|
857533704e | ||
|
|
af419ff25b | ||
|
|
dcbb944fbf | ||
|
|
5081a21a0b | ||
|
|
92c75e52ba | ||
|
|
2b7f57cc9f | ||
|
|
0708435d91 | ||
|
|
c3a6118387 | ||
|
|
d7dcfb95b6 | ||
|
|
55c4743417 | ||
|
|
f56e3630b6 | ||
|
|
6dfdffeab9 | ||
|
|
ed0e14cb32 | ||
|
|
772ffc6328 | ||
|
|
c9f65c838e | ||
|
|
7f3a3a85f3 | ||
|
|
c5a091c732 | ||
|
|
4f184abb08 | ||
|
|
1365fd08a0 | ||
|
|
71aee61345 | ||
|
|
efbf557cc0 | ||
|
|
96d162d11f | ||
|
|
27b718da3c | ||
|
|
e49b747f43 | ||
|
|
a2942e5589 | ||
|
|
f121d3c8b3 | ||
|
|
a069704803 | ||
|
|
58db4f4277 | ||
|
|
332ededb3a | ||
|
|
214b3e9f19 | ||
|
|
6b97ca12de | ||
|
|
11aa723d75 | ||
|
|
df69c2aea4 | ||
|
|
5855a97255 | ||
|
|
88035326a4 | ||
|
|
df3571534c | ||
|
|
417a834593 | ||
|
|
070d9494e7 | ||
|
|
6dcd0c8d1f | ||
|
|
09beccc30b | ||
|
|
41a444a49d | ||
|
|
1071c7e1d2 | ||
|
|
8b1e9e3744 | ||
|
|
40256d3d4b | ||
|
|
4974ba7c79 | ||
|
|
9d61503ea6 | ||
|
|
2ec046de07 | ||
|
|
0c68f2c1ad | ||
|
|
a6fd81b0ed |
26
.example.env
26
.example.env
@@ -1,24 +1,22 @@
|
||||
APP_DEBUG=true
|
||||
|
||||
[APP]
|
||||
# 后台系统日志开关
|
||||
APP_ADMIN_SYSTEM_LOG=true
|
||||
|
||||
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
27
.gitignore
vendored
@@ -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
66
CURD.md
@@ -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 | 关联模型文件名 |
|
||||
2
LICENSE
2
LICENSE
@@ -18,4 +18,4 @@ 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.
|
||||
SOFTWARE.
|
||||
@@ -1 +0,0 @@
|
||||
# EasyAdmin8
|
||||
53
README.md
53
README.md
@@ -1,16 +1,31 @@
|
||||
<div align="center" dir="auto">
|
||||
<img alt="log" src="/public/static/common/images/logo-8.png" />
|
||||
|
||||
<p>
|
||||
<img src="https://img.shields.io/badge/php-%3E=8.1.0-brightgreen.svg?style=for-the-badge&logo=php&colorB=ff69b4" alt="php">
|
||||
<img src="https://img.shields.io/badge/mysql-%3E=5.7-brightgreen.svg?style=for-the-badge&logo=mysql&colorB=blue" alt="MySQL">
|
||||
<img src="https://img.shields.io/badge/thinkphp-%3E=8.0.0-brightgreen.svg?style=for-the-badge&logo=thinkphp" alt="ThinkPHP">
|
||||
<img src="https://img.shields.io/badge/layui-%3E=2.9.0-brightgreen.svg?style=for-the-badge&logo=layui&colorB=orange" alt="layui">
|
||||
<img src="https://img.shields.io/badge/license-MIT-green?style=for-the-badge&logo=license&colorB=purple" alt="License">
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
## `EasyAdmin8`所有版本 (当前项目为`ThinkPHP`版本)
|
||||
|
||||
| | Github | Gitee |
|
||||
|----------|:--------------------------------------------------------------------:|:-----------------------------------------------------------------:|
|
||||
| ThinkPHP | [EasyAdmin8](https://github.com/wolf-leo/EasyAdmin8) | [EasyAdmin8](https://gitee.com/wolf18/EasyAdmin8) |
|
||||
| Laravel | [EasyAdmin8-Laravel](https://github.com/wolf-leo/EasyAdmin8-Laravel) | [EasyAdmin8-Laravel](https://gitee.com/wolf18/EasyAdmin8-Laravel) |
|
||||
| webman | [EasyAdmin8-webman](https://github.com/wolf-leo/EasyAdmin8-webman) | [EasyAdmin8-webman](https://gitee.com/wolf18/EasyAdmin8-webman) |
|
||||
| | Github | Gitee |
|
||||
|----------|:----------------------------------------------------------------------:|:---------------------------------------------------------------------:|
|
||||
| ThinkPHP | [EasyAdmin8](https://github.com/EasyAdmin8/EasyAdmin8) | [EasyAdmin8](https://gitee.com/EasyAdmin8/EasyAdmin8) |
|
||||
| Laravel | [EasyAdmin8-Laravel](https://github.com/EasyAdmin8/EasyAdmin8-Laravel) | [EasyAdmin8-Laravel](https://gitee.com/EasyAdmin8/EasyAdmin8-Laravel) |
|
||||
| webman | [EasyAdmin8-webman](https://github.com/EasyAdmin8/EasyAdmin8-webman) | [EasyAdmin8-webman](https://gitee.com/EasyAdmin8/EasyAdmin8-webman) |
|
||||
|
||||
## 项目介绍
|
||||
|
||||
> `EasyAdmin8` 在 [`EasyAdmin`](https://gitee.com/zhongshaofa/easyadmin) 的基础上更新 ThinkPHP 框架到 8.0 ,PHP 最低版本要求不低于 8.0
|
||||
> `EasyAdmin8` 在 [`EasyAdmin`](https://gitee.com/zhongshaofa/easyadmin) 的基础上更新 ThinkPHP 框架到 8.0+ ,PHP 最低版本要求不低于 8.1
|
||||
>
|
||||
> 2025年起 `PHP` 版本要求提升到 `8.1+`, 如果需要 `8.0` 到分支 `v8.0` 中下载
|
||||
>
|
||||
> ThinkPHP v8.0 和 Layui v2.9.x 的快速开发的后台管理系统。
|
||||
> ThinkPHP v8.0+ 和 Layui v2.9.x 的快速开发的后台管理系统。
|
||||
>
|
||||
> 项目地址:[http://easyadmin8.top](http://easyadmin8.top)
|
||||
>
|
||||
@@ -20,22 +35,32 @@
|
||||
>
|
||||
>【如果不能访问,可以自行本地搭建预览或参考下方界面预览图】
|
||||
|
||||
## 大版本更新记录:
|
||||
|
||||
[更新记录](log.md)
|
||||
|
||||
## 安装教程
|
||||
|
||||
> EasyAdmin8 使用 Composer 来管理项目依赖。因此,在使用 EasyAdmin8 之前,请确保你的机器已经安装了 Composer。
|
||||
|
||||
### 通过git下载安装包,composer安装依赖包
|
||||
### 通过一键安装命令
|
||||
|
||||
```
|
||||
if [ -f /usr/bin/curl ];then curl -sSO https://easyadmin8.top/auto-install-EasyAdmin8.sh;else wget -O auto-install-EasyAdmin8.sh https://easyadmin8.top/auto-install-EasyAdmin8.sh;fi;bash auto-install-EasyAdmin8.sh
|
||||
```
|
||||
|
||||
### 通过`git`下载安装包,`composer`安装依赖包
|
||||
|
||||
```
|
||||
1.下载安装包
|
||||
|
||||
git clone https://github.com/wolf-leo/EasyAdmin8
|
||||
git clone https://github.com/EasyAdmin8/EasyAdmin8
|
||||
|
||||
或者
|
||||
|
||||
git clone https://gitee.com/wolf18/EasyAdmin8
|
||||
git clone https://gitee.com/EasyAdmin8/EasyAdmin8
|
||||
|
||||
2.安装依赖包(确保 PHP 版本 >= 8.0)
|
||||
2.安装依赖包(确保 PHP 版本 >= 8.1)
|
||||
|
||||
在根目录下 composer install ,如果有报错信息可以使用命令 composer install --ignore-platform-reqs
|
||||
|
||||
@@ -54,7 +79,7 @@
|
||||
|
||||
## CURD命令大全
|
||||
|
||||
> 参考 [CURD命令大全](CURD.md)
|
||||
> 参考 [CURD命令大全](https://edocs.easyadmin8.top/curd/command.html)
|
||||
|
||||
## 常见问题
|
||||
|
||||
@@ -76,11 +101,11 @@
|
||||
|
||||
## 相关文档
|
||||
|
||||
* [ThinkPHP 8.0](https://doc.thinkphp.cn/v8_0)
|
||||
* [ThinkPHP 8.1](https://doc.thinkphp.cn)
|
||||
|
||||
* [EasyAdmin](http://easyadmin.99php.cn/docs)
|
||||
|
||||
* [Layui 2.8.x](https://layui.dev/docs/2.8/)
|
||||
* [Layui 2.9.x](https://layui.dev/docs)
|
||||
|
||||
* [Layuimini](https://github.com/zhongshaofa/layuimini)
|
||||
|
||||
|
||||
22
app/AppService.php
Normal file
22
app/AppService.php
Normal 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()
|
||||
{
|
||||
// 服务启动
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace app;
|
||||
|
||||
// 应用请求对象类
|
||||
class Request extends \think\Request
|
||||
{
|
||||
|
||||
protected $filter = ['htmlspecialchars'];
|
||||
|
||||
}
|
||||
|
||||
@@ -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,11 @@ return [
|
||||
],
|
||||
|
||||
// 默认编辑器
|
||||
'editor_types' => [
|
||||
'ueditor' => '百度编辑器',
|
||||
'editor_types' => [
|
||||
'ueditor' => '百度编辑器(不建议使用)',
|
||||
'ckeditor' => 'CK编辑器',
|
||||
'wangEditor' => 'wangEditor',
|
||||
'wangEditor' => 'wangEditor(推荐使用)',
|
||||
'EasyMDE' => 'EasyMDE(markdown)',
|
||||
],
|
||||
|
||||
];
|
||||
@@ -1,10 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 应用设置
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
use think\facade\Env;
|
||||
|
||||
return [
|
||||
|
||||
];
|
||||
@@ -1,10 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 控制台配置
|
||||
// +----------------------------------------------------------------------
|
||||
return [
|
||||
// 指令定义
|
||||
'commands' => [
|
||||
'alioss' => 'addons\alioss\command\Alioss',
|
||||
],
|
||||
];
|
||||
@@ -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,
|
||||
// 操作日志
|
||||
SystemLog::class,
|
||||
// 验证节点权限
|
||||
CheckAuth::class,
|
||||
],
|
||||
];
|
||||
];
|
||||
@@ -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 Json|null
|
||||
*/
|
||||
public function upload()
|
||||
public function upload(Request $request): Json|null
|
||||
{
|
||||
$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']}",
|
||||
@@ -81,30 +84,35 @@ class Ajax extends AdminController
|
||||
if ($code == 0) {
|
||||
$this->error($upload['data'] ?? '');
|
||||
}else {
|
||||
$type == 'editor' ? json(
|
||||
[
|
||||
'error' => ['message' => '上传成功', 'number' => 201,],
|
||||
'fileName' => '',
|
||||
'uploaded' => 1,
|
||||
'url' => $upload['data']['url'] ?? '',
|
||||
]
|
||||
) : $this->success('上传成功', $upload['data'] ?? '');
|
||||
if ($type == 'editor') {
|
||||
return json(
|
||||
[
|
||||
'error' => ['message' => '上传成功', 'number' => 201,],
|
||||
'fileName' => '',
|
||||
'uploaded' => 1,
|
||||
'url' => $upload['data']['url'] ?? '',
|
||||
]
|
||||
);
|
||||
}else {
|
||||
$this->success('上传成功', $upload['data'] ?? '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取上传文件列表
|
||||
* @param Request $request
|
||||
* @return Json
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public function getUploadFiles(): 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 +125,7 @@ class Ajax extends AdminController
|
||||
})
|
||||
->page($page, $limit)
|
||||
->order($this->sort)
|
||||
->select();
|
||||
->select()->toArray();
|
||||
$data = [
|
||||
'code' => 0,
|
||||
'msg' => '',
|
||||
@@ -129,14 +137,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 +180,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':
|
||||
|
||||
@@ -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,]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,65 +36,67 @@ class Index extends AdminController
|
||||
$mysqlVersion = Db::query("select version() as version")[0]['version'] ?? '未知';
|
||||
$phpVersion = phpversion();
|
||||
$versions = compact('tpVersion', 'mysqlVersion', 'phpVersion');
|
||||
$quicks = SystemQuick::field('id,title,icon,href')
|
||||
->where(['status' => 1])
|
||||
->order('sort', 'desc')
|
||||
->limit(8)
|
||||
->select();
|
||||
$quick_list = SystemQuick::field('id,title,icon,href')
|
||||
->where(['status' => 1])->order('sort', 'desc')->limit(50)->select()->toArray();
|
||||
$quicks = array_chunk($quick_list, 8);
|
||||
$this->assign(compact('quicks', 'versions'));
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改管理员信息
|
||||
* @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);
|
||||
try {
|
||||
$save = $row
|
||||
->allowField(['head_img', 'phone', 'remark', 'update_time'])
|
||||
->save($post);
|
||||
} catch (Exception $e) {
|
||||
$login_type = $post['login_type'] ?? 1;
|
||||
if ($login_type == 2) {
|
||||
$ga_secret = (new SystemAdmin())->where('id', $id)->value('ga_secret');
|
||||
if (empty($ga_secret)) $this->error('请先绑定谷歌验证器');
|
||||
}
|
||||
$save = $row->allowField(['head_img', 'phone', 'remark', 'update_time', 'login_type'])->save($post);
|
||||
}catch (\PDOException $e) {
|
||||
$this->error('保存失败');
|
||||
}
|
||||
$save ? $this->success('保存成功') : $this->error('保存失败');
|
||||
}
|
||||
$this->assign('row', $row);
|
||||
$notes = (new SystemAdmin())->notes;
|
||||
$this->assign('notes', $notes);
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改密码
|
||||
* @param Request $request
|
||||
* @return string
|
||||
* @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('保存失败');
|
||||
}
|
||||
}
|
||||
@@ -125,4 +124,37 @@ class Index extends AdminController
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置谷歌验证码
|
||||
* @param Request $request
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function set2fa(Request $request): string
|
||||
{
|
||||
$id = $this->adminUid;
|
||||
$row = (new SystemAdmin())->withoutField('password')->find($id);
|
||||
if (!$row) $this->error('用户信息不存在');
|
||||
// You can see: https://gitee.com/wolf-code/authenticator
|
||||
$ga = new \Wolfcode\Authenticator\google\PHPGangstaGoogleAuthenticator();
|
||||
if (!$request->isAjax()) {
|
||||
$old_secret = $row->ga_secret;
|
||||
$secret = $ga->createSecret(32);
|
||||
$ga_title = $this->isDemo ? 'EasyAdmin8演示环境' : '可自定义修改显示标题';
|
||||
$dataUri = $ga->getQRCode($ga_title, $secret);
|
||||
$this->assign(compact('row', 'dataUri', 'old_secret', 'secret'));
|
||||
return $this->fetch();
|
||||
}
|
||||
$this->isDemo && $this->error('演示环境下不允许修改');
|
||||
$post = $request->post();
|
||||
$ga_secret = $post['ga_secret'] ?? '';
|
||||
$ga_code = $post['ga_code'] ?? '';
|
||||
if (empty($ga_code)) $this->error('请输入验证码');
|
||||
if (!$ga->verifyCode($ga_secret, $ga_code)) $this->error('验证码错误');
|
||||
$row->ga_secret = $ga_secret;
|
||||
$row->login_type = 2;
|
||||
$row->save();
|
||||
$this->success('操作成功');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,73 +5,75 @@ 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('账号已被禁用');
|
||||
}
|
||||
if ($admin->login_type == 2) {
|
||||
if (empty($post['ga_code'])) $this->error('请输入谷歌验证码', ['is_ga_code' => true]);
|
||||
$ga = new \Wolfcode\Authenticator\google\PHPGangstaGoogleAuthenticator();
|
||||
if (!$ga->verifyCode($admin->ga_secret, $post['ga_code'])) $this->error('谷歌验证码错误');;
|
||||
}
|
||||
$admin->login_num += 1;
|
||||
$admin->save();
|
||||
$admin = $admin->toArray();
|
||||
unset($admin['password']);
|
||||
$admin['expire_time'] = $post['keep_login'] == 1 ? true : time() + 7200;
|
||||
session('admin', $admin);
|
||||
$this->success('登录成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户退出
|
||||
*/
|
||||
public function out()
|
||||
public function out(): void
|
||||
{
|
||||
session('admin', null);
|
||||
$this->success('退出登录成功');
|
||||
@@ -83,6 +85,6 @@ class Login extends AdminController
|
||||
*/
|
||||
public function captcha(): Response
|
||||
{
|
||||
return Captcha::create();
|
||||
return Captcha::instance()->create();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,22 +3,15 @@
|
||||
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;
|
||||
use think\App;
|
||||
|
||||
/**
|
||||
* Class Admin
|
||||
* @package app\admin\controller\system
|
||||
* @ControllerAnnotation(title="商品分类管理")
|
||||
*/
|
||||
#[ControllerAnnotation(title: '商品分类管理')]
|
||||
class Cate extends AdminController
|
||||
{
|
||||
|
||||
use Curd;
|
||||
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
|
||||
@@ -2,51 +2,37 @@
|
||||
|
||||
namespace app\admin\controller\mall;
|
||||
|
||||
use app\admin\model\MallCate;
|
||||
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\response\Json;
|
||||
|
||||
/**
|
||||
* Class Goods
|
||||
* @package app\admin\controller\mall
|
||||
* @ControllerAnnotation(title="商城商品管理")
|
||||
*/
|
||||
#[ControllerAnnotation(title: '商城商品管理')]
|
||||
class Goods extends AdminController
|
||||
{
|
||||
|
||||
use Curd;
|
||||
|
||||
protected bool $relationSearch = true;
|
||||
#[NodeAnnotation(ignore: ['export'])] // 过滤不需要生成的权限节点 默认 CURD 中会自动生成部分节点 可以在此处过滤
|
||||
protected array $ignoreNode;
|
||||
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->model = new MallGoods();
|
||||
$this->assign('cate', (new MallCate())->column('title', 'id'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="列表")
|
||||
*/
|
||||
public function index()
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
public function index(Request $request): Json|string
|
||||
{
|
||||
if ($this->request->isAjax()) {
|
||||
if (input('selectFields')) {
|
||||
return $this->selectList();
|
||||
}
|
||||
if ($request->isAjax()) {
|
||||
if (input('selectFields')) return $this->selectList();
|
||||
list($page, $limit, $where) = $this->buildTableParams();
|
||||
$count = $this->model
|
||||
->withJoin('cate', 'LEFT')
|
||||
->where($where)
|
||||
->count();
|
||||
$list = $this->model
|
||||
->withJoin('cate', 'LEFT')
|
||||
->where($where)
|
||||
->page($page, $limit)
|
||||
->order($this->sort)
|
||||
->select();
|
||||
$count = $this->model->where($where)->count();
|
||||
$list = $this->model->with(['cate'])->where($where)->page($page, $limit)->order($this->sort)->select()->toArray();
|
||||
$data = [
|
||||
'code' => 0,
|
||||
'msg' => '',
|
||||
@@ -58,22 +44,20 @@ class Goods extends AdminController
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="入库")
|
||||
*/
|
||||
public function stock($id)
|
||||
#[NodeAnnotation(title: '入库', auth: true)]
|
||||
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('保存失败');
|
||||
|
||||
@@ -8,18 +8,14 @@ use app\common\constants\AdminConstant;
|
||||
use app\common\controller\AdminController;
|
||||
use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\Request;
|
||||
use think\App;
|
||||
use think\response\Json;
|
||||
|
||||
/**
|
||||
* Class Admin
|
||||
* @package app\admin\controller\system
|
||||
* @ControllerAnnotation(title="管理员管理")
|
||||
*/
|
||||
#[ControllerAnnotation(title: '管理员管理')]
|
||||
class Admin extends AdminController
|
||||
{
|
||||
|
||||
use \app\admin\traits\Curd;
|
||||
|
||||
protected array $sort = [
|
||||
'sort' => 'desc',
|
||||
'id' => 'desc',
|
||||
@@ -32,12 +28,10 @@ class Admin extends AdminController
|
||||
$this->assign('auth_list', $this->model->getAuthList());
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="列表")
|
||||
*/
|
||||
public function index()
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
public function index(Request $request): Json|string
|
||||
{
|
||||
if ($this->request->isAjax()) {
|
||||
if ($request->isAjax()) {
|
||||
if (input('selectFields')) {
|
||||
return $this->selectList();
|
||||
}
|
||||
@@ -50,7 +44,7 @@ class Admin extends AdminController
|
||||
->where($where)
|
||||
->page($page, $limit)
|
||||
->order($this->sort)
|
||||
->select();
|
||||
->select()->toArray();
|
||||
$data = [
|
||||
'code' => 0,
|
||||
'msg' => '',
|
||||
@@ -62,14 +56,12 @@ class Admin extends AdminController
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="添加")
|
||||
*/
|
||||
public function add()
|
||||
#[NodeAnnotation(title: '添加', auth: true)]
|
||||
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 +69,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('保存失败');
|
||||
@@ -85,16 +77,14 @@ class Admin extends AdminController
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="编辑")
|
||||
*/
|
||||
public function edit($id)
|
||||
#[NodeAnnotation(title: '编辑', auth: true)]
|
||||
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 +94,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('保存失败');
|
||||
@@ -114,15 +104,13 @@ class Admin extends AdminController
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="编辑")
|
||||
*/
|
||||
public function password($id)
|
||||
#[NodeAnnotation(title: '设置密码', auth: true)]
|
||||
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 +121,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('保存失败');
|
||||
@@ -145,12 +133,11 @@ class Admin extends AdminController
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="删除")
|
||||
*/
|
||||
public function delete($id)
|
||||
#[NodeAnnotation(title: '删除', auth: true)]
|
||||
public function delete(Request $request): void
|
||||
{
|
||||
$this->checkPostRequest();
|
||||
$id = $request->param('id');
|
||||
$row = $this->model->whereIn('id', $id)->select();
|
||||
$row->isEmpty() && $this->error('数据不存在');
|
||||
$id == AdminConstant::SUPER_ADMIN_ID && $this->error('超级管理员不允许修改');
|
||||
@@ -161,23 +148,21 @@ class Admin extends AdminController
|
||||
}
|
||||
try {
|
||||
$save = $row->delete();
|
||||
} catch (\Exception $e) {
|
||||
}catch (\Exception $e) {
|
||||
$this->error('删除失败');
|
||||
}
|
||||
$save ? $this->success('删除成功') : $this->error('删除失败');
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="属性修改")
|
||||
*/
|
||||
public function modify()
|
||||
#[NodeAnnotation(title: '属性修改', auth: true)]
|
||||
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 +175,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('保存成功');
|
||||
|
||||
@@ -8,18 +8,13 @@ use app\admin\service\TriggerService;
|
||||
use app\common\controller\AdminController;
|
||||
use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\Request;
|
||||
use think\App;
|
||||
|
||||
/**
|
||||
* @ControllerAnnotation(title="角色权限管理")
|
||||
* Class Auth
|
||||
* @package app\admin\controller\system
|
||||
*/
|
||||
#[ControllerAnnotation(title: '角色权限管理', auth: true)]
|
||||
class Auth extends AdminController
|
||||
{
|
||||
|
||||
use \app\admin\traits\Curd;
|
||||
|
||||
protected array $sort = [
|
||||
'sort' => 'desc',
|
||||
'id' => 'desc',
|
||||
@@ -31,14 +26,12 @@ class Auth extends AdminController
|
||||
$this->model = new SystemAuth();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="授权")
|
||||
*/
|
||||
public function authorize($id)
|
||||
#[NodeAnnotation(title: '授权', auth: true)]
|
||||
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);
|
||||
}
|
||||
@@ -46,14 +39,12 @@ class Auth extends AdminController
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="授权保存")
|
||||
*/
|
||||
public function saveAuthorize()
|
||||
#[NodeAnnotation(title: '授权保存', auth: true)]
|
||||
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 +62,7 @@ class Auth extends AdminController
|
||||
$authNode->saveAll($saveAll);
|
||||
}
|
||||
TriggerService::updateMenu();
|
||||
} catch (\Exception $e) {
|
||||
}catch (\Exception $e) {
|
||||
$this->error('保存失败');
|
||||
}
|
||||
$this->success('保存成功');
|
||||
|
||||
@@ -7,13 +7,11 @@ 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
|
||||
* @package app\admin\controller\system
|
||||
* @ControllerAnnotation(title="系统配置管理")
|
||||
*/
|
||||
#[ControllerAnnotation(title: '系统配置管理')]
|
||||
class Config extends AdminController
|
||||
{
|
||||
|
||||
@@ -25,21 +23,17 @@ class Config extends AdminController
|
||||
$this->assign('editor_types', config('admin.editor_types'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="列表")
|
||||
*/
|
||||
public function index()
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
public function index(Request $request): Json|string
|
||||
{
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="保存")
|
||||
*/
|
||||
public function save()
|
||||
#[NodeAnnotation(title: '保存', auth: true)]
|
||||
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 +47,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 +57,8 @@ class Config extends AdminController
|
||||
}
|
||||
}
|
||||
TriggerService::updateMenu();
|
||||
TriggerService::updateSysconfig();
|
||||
} catch (\Exception $e) {
|
||||
TriggerService::updateSysConfig();
|
||||
}catch (\Exception $e) {
|
||||
$this->error('保存失败');
|
||||
}
|
||||
$this->success('保存成功');
|
||||
|
||||
@@ -3,43 +3,36 @@
|
||||
namespace app\admin\controller\system;
|
||||
|
||||
use app\admin\service\curd\BuildCurd;
|
||||
use app\admin\service\curd\exceptions\TableException;
|
||||
use app\common\controller\AdminController;
|
||||
use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\Request;
|
||||
use think\db\exception\PDOException;
|
||||
use think\exception\FileException;
|
||||
use think\facade\Console;
|
||||
use think\facade\Db;
|
||||
use think\helper\Str;
|
||||
use think\response\Json;
|
||||
|
||||
/**
|
||||
* @ControllerAnnotation(title="CURD可视化管理")
|
||||
* @package app\admin\controller\system
|
||||
*/
|
||||
#[ControllerAnnotation(title: 'CURD可视化管理')]
|
||||
class CurdGenerate extends AdminController
|
||||
{
|
||||
/**
|
||||
* @NodeAnnotation(title="列表")
|
||||
*/
|
||||
public function index()
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
public function index(Request $request): Json|string
|
||||
{
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="操作")
|
||||
* @throws TableException
|
||||
*/
|
||||
#[NodeAnnotation(title: '操作', auth: true)]
|
||||
public function save(Request $request, string $type = ''): ?Json
|
||||
{
|
||||
if (!$request->isAjax()) $this->error();
|
||||
$tb_prefix = $request->param('tb_prefix/s', '');
|
||||
$tb_name = $request->param('tb_name/s', '');
|
||||
if (empty($tb_name)) $this->error('参数错误');
|
||||
switch ($type) {
|
||||
case "search":
|
||||
$tb_prefix = $request->param('tb_prefix/s', '');
|
||||
$tb_name = $request->param('tb_name/s', '');
|
||||
if (empty($tb_name)) $this->error('参数错误');
|
||||
|
||||
try {
|
||||
$list = Db::query("SHOW FULL COLUMNS FROM {$tb_prefix}{$tb_name}");
|
||||
$data = [];
|
||||
@@ -59,10 +52,53 @@ class CurdGenerate extends AdminController
|
||||
}
|
||||
break;
|
||||
case "add":
|
||||
$force = $request->post('force/d', 0);
|
||||
$tb_prefix = $request->param('tb_prefix/s', '');
|
||||
$tb_name = $request->param('tb_name/s', '');
|
||||
if (empty($tb_name)) $this->error('参数错误');
|
||||
|
||||
$tb_fields = $request->param('tb_fields');
|
||||
$force = $request->post('force/d', 0);
|
||||
try {
|
||||
$build = (new BuildCurd())->setTablePrefix($tb_prefix)->setTable($tb_name);
|
||||
$build->setForce($force); // 强制覆盖
|
||||
// 新增字段类型
|
||||
if ($tb_fields) {
|
||||
foreach ($tb_fields as $tk => $tf) {
|
||||
if (empty($tf)) continue;
|
||||
$tf = array_values($tf);
|
||||
switch ($tk) {
|
||||
case 'ignore':
|
||||
$build->setIgnoreFields($tf, true);
|
||||
break;
|
||||
case 'select':
|
||||
$build->setSelectFields($tf, true);
|
||||
break;
|
||||
case 'radio':
|
||||
$build->setRadioFieldSuffix($tf, true);
|
||||
break;
|
||||
case 'checkbox':
|
||||
$build->setCheckboxFieldSuffix($tf, true);
|
||||
break;
|
||||
case 'image':
|
||||
$build->setImageFieldSuffix($tf, true);
|
||||
break;
|
||||
case 'images':
|
||||
$build->setImagesFieldSuffix($tf, true);
|
||||
break;
|
||||
case 'date':
|
||||
$build->setDateFieldSuffix($tf, true);
|
||||
break;
|
||||
case 'datetime':
|
||||
$build->setDatetimeFieldSuffix($tf, true);
|
||||
break;
|
||||
case 'editor':
|
||||
$build->setEditorFields($tf, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$build = $build->render();
|
||||
$fileList = $build->getFileList();
|
||||
if (empty($fileList)) $this->error('这里什么都没有');
|
||||
@@ -74,7 +110,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) {
|
||||
@@ -82,6 +118,10 @@ class CurdGenerate extends AdminController
|
||||
}
|
||||
break;
|
||||
case "delete":
|
||||
$tb_prefix = $request->param('tb_prefix/s', '');
|
||||
$tb_name = $request->param('tb_name/s', '');
|
||||
if (empty($tb_name)) $this->error('参数错误');
|
||||
|
||||
try {
|
||||
$build = (new BuildCurd())->setTablePrefix($tb_prefix)->setTable($tb_name);
|
||||
$build = $build->render();
|
||||
@@ -93,6 +133,19 @@ class CurdGenerate extends AdminController
|
||||
return json(['code' => -1, 'msg' => $exception->getMessage()]);
|
||||
}
|
||||
break;
|
||||
case 'console':
|
||||
$command = $request->post('command', '');
|
||||
if (empty($command)) $this->error('请输入命令');
|
||||
$commandExp = explode(' ', $command);
|
||||
try {
|
||||
|
||||
$output = Console::call('curd', [...$commandExp]);
|
||||
}catch (\Throwable $exception) {
|
||||
$this->error($exception->getMessage() . $exception->getLine());
|
||||
}
|
||||
if (empty($output)) $this->error('设置错误');
|
||||
$this->success($output->fetch());
|
||||
break;
|
||||
default:
|
||||
$this->error('参数错误');
|
||||
break;
|
||||
|
||||
@@ -3,38 +3,32 @@
|
||||
namespace app\admin\controller\system;
|
||||
|
||||
use app\admin\model\SystemLog;
|
||||
use app\admin\service\annotation\MiddlewareAnnotation;
|
||||
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="操作日志管理")
|
||||
* Class Auth
|
||||
* @package app\admin\controller\system
|
||||
*/
|
||||
#[ControllerAnnotation(title: '操作日志管理')]
|
||||
class Log extends AdminController
|
||||
{
|
||||
use Curd;
|
||||
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->model = new SystemLog();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="列表")
|
||||
*/
|
||||
public function index()
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
public function index(Request $request): Json|string
|
||||
{
|
||||
if ($this->request->isAjax()) {
|
||||
if ($request->isAjax()) {
|
||||
if (input('selectFields')) {
|
||||
return $this->selectList();
|
||||
}
|
||||
@@ -44,7 +38,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 = [];
|
||||
}
|
||||
@@ -59,10 +53,8 @@ class Log extends AdminController
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="导出")
|
||||
*/
|
||||
public function export()
|
||||
#[NodeAnnotation(title: '导出', auth: true)]
|
||||
public function export(): bool
|
||||
{
|
||||
if (env('EASYADMIN.IS_DEMO', false)) {
|
||||
$this->error('演示环境下不允许操作');
|
||||
@@ -88,11 +80,18 @@ class Log extends AdminController
|
||||
->order('id', 'desc')
|
||||
->select()
|
||||
->toArray();
|
||||
} catch (PDOException|DbException $exception) {
|
||||
}catch (PDOException|DbException $exception) {
|
||||
$this->error($exception->getMessage());
|
||||
}
|
||||
$fileName = time();
|
||||
return Excel::exportData($list, $header, $fileName, 'xlsx');
|
||||
}
|
||||
|
||||
#[MiddlewareAnnotation(ignore: MiddlewareAnnotation::IGNORE_LOG)]
|
||||
#[NodeAnnotation(title: '框架日志', auth: true, ignore: NodeAnnotation::IGNORE_NODE)]
|
||||
public function record(): Json|string
|
||||
{
|
||||
return (new \Wolfcode\PhpLogviewer\thinkphp\LogViewer())->fetch();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,23 +5,18 @@ 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\response\Json;
|
||||
|
||||
/**
|
||||
* Class Menu
|
||||
* @package app\admin\controller\system
|
||||
* @ControllerAnnotation(title="菜单管理",auth=true)
|
||||
*/
|
||||
#[ControllerAnnotation(title: '菜单管理')]
|
||||
class Menu extends AdminController
|
||||
{
|
||||
|
||||
use Curd;
|
||||
|
||||
protected array $sort = [
|
||||
'sort' => 'desc',
|
||||
'id' => 'asc',
|
||||
@@ -33,17 +28,15 @@ class Menu extends AdminController
|
||||
$this->model = new SystemMenu();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="列表")
|
||||
*/
|
||||
public function index()
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
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' => '',
|
||||
@@ -55,17 +48,16 @@ class Menu extends AdminController
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="添加")
|
||||
*/
|
||||
public function add($id = null)
|
||||
#[NodeAnnotation(title: '添加', auth: true)]
|
||||
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 +66,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('保存失败');
|
||||
}
|
||||
}
|
||||
@@ -90,15 +82,13 @@ class Menu extends AdminController
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="编辑")
|
||||
*/
|
||||
public function edit($id)
|
||||
#[NodeAnnotation(title: '编辑', auth: true)]
|
||||
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,57 +98,54 @@ 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)
|
||||
#[NodeAnnotation(title: '删除', auth: true)]
|
||||
public function delete(Request $request): void
|
||||
{
|
||||
$this->checkPostRequest();
|
||||
$id = $request->param('id');
|
||||
$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('删除失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="属性修改")
|
||||
*/
|
||||
public function modify()
|
||||
#[NodeAnnotation(title: '属性修改', auth: true)]
|
||||
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,38 +157,36 @@ 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();
|
||||
$this->success('保存成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="添加菜单提示")
|
||||
*/
|
||||
public function getMenuTips()
|
||||
#[NodeAnnotation(title: '添加菜单提示', auth: true)]
|
||||
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',
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,30 +8,24 @@ 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\response\Json;
|
||||
|
||||
/**
|
||||
* @ControllerAnnotation(title="系统节点管理")
|
||||
* Class Node
|
||||
* @package app\admin\controller\system
|
||||
*/
|
||||
#[ControllerAnnotation(title: '系统节点管理')]
|
||||
class Node extends AdminController
|
||||
{
|
||||
|
||||
use \app\admin\traits\Curd;
|
||||
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->model = new SystemNode();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="列表")
|
||||
*/
|
||||
public function index()
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
public function index(Request $request): Json|string
|
||||
{
|
||||
if ($this->request->isAjax()) {
|
||||
if ($request->isAjax()) {
|
||||
if (input('selectFields')) {
|
||||
return $this->selectList();
|
||||
}
|
||||
@@ -50,9 +44,7 @@ class Node extends AdminController
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="系统节点更新")
|
||||
*/
|
||||
#[NodeAnnotation(title: '系统节点更新', auth: true)]
|
||||
public function refreshNode($force = 0): void
|
||||
{
|
||||
|
||||
@@ -86,15 +78,13 @@ class Node extends AdminController
|
||||
}
|
||||
$model->saveAll($nodeList);
|
||||
TriggerService::updateNode();
|
||||
} catch (\Exception $e) {
|
||||
}catch (\Exception $e) {
|
||||
$this->error('节点更新失败');
|
||||
}
|
||||
$this->success('节点更新成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="清除失效节点")
|
||||
*/
|
||||
#[NodeAnnotation(title: '清除失效节点', auth: true)]
|
||||
public function clearNode(): void
|
||||
{
|
||||
$this->checkPostRequest();
|
||||
@@ -107,7 +97,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('节点更新成功');
|
||||
|
||||
@@ -9,16 +9,10 @@ use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use think\App;
|
||||
|
||||
/**
|
||||
* @ControllerAnnotation(title="快捷入口管理")
|
||||
* Class Quick
|
||||
* @package app\admin\controller\system
|
||||
*/
|
||||
#[ControllerAnnotation(title: '快捷入口管理')]
|
||||
class Quick extends AdminController
|
||||
{
|
||||
|
||||
use \app\admin\traits\Curd;
|
||||
|
||||
protected array $sort = [
|
||||
'sort' => 'desc',
|
||||
'id' => 'desc',
|
||||
|
||||
@@ -8,16 +8,10 @@ use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use think\App;
|
||||
|
||||
/**
|
||||
* @ControllerAnnotation(title="上传文件管理")
|
||||
* Class Uploadfile
|
||||
* @package app\admin\controller\system
|
||||
*/
|
||||
#[ControllerAnnotation(title: '上传文件管理')]
|
||||
class Uploadfile extends AdminController
|
||||
{
|
||||
|
||||
use \app\admin\traits\Curd;
|
||||
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
<?php
|
||||
// 事件定义文件
|
||||
return [
|
||||
'bind' => [
|
||||
],
|
||||
|
||||
'listen' => [
|
||||
'AppInit' => [
|
||||
\app\admin\listener\ViewInitListener::class,
|
||||
],
|
||||
'HttpRun' => [
|
||||
\app\admin\listener\ViewInitListener::class,
|
||||
],
|
||||
'HttpEnd' => [],
|
||||
'LogLevel' => [],
|
||||
'LogWrite' => [],
|
||||
],
|
||||
|
||||
'subscribe' => [
|
||||
],
|
||||
];
|
||||
@@ -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,
|
||||
|
||||
// ...
|
||||
];
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
43
app/admin/middleware/CheckAuth.php
Normal file
43
app/admin/middleware/CheckAuth.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\middleware;
|
||||
|
||||
use app\common\service\AuthService;
|
||||
use app\common\traits\JumpTrait;
|
||||
use app\Request;
|
||||
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 $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()) {
|
||||
if (!in_array($currentNode, ['system.log/record', ''])) $this->error('演示环境下不允许修改');
|
||||
}
|
||||
}
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
@@ -2,18 +2,18 @@
|
||||
|
||||
namespace app\admin\middleware;
|
||||
|
||||
use app\common\traits\JumpTrait;
|
||||
use app\Request;
|
||||
use Closure;
|
||||
|
||||
/**
|
||||
* 检测是否安装成功
|
||||
* 系统安装后可以在 config/route 中删除该中间件判定
|
||||
*/
|
||||
class CheckInstall
|
||||
{
|
||||
public function handle(Request $request, \Closure $next)
|
||||
use JumpTrait;
|
||||
|
||||
public function handle(Request $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);
|
||||
|
||||
47
app/admin/middleware/CheckLogin.php
Normal file
47
app/admin/middleware/CheckLogin.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\middleware;
|
||||
|
||||
use app\common\traits\JumpTrait;
|
||||
use app\Request;
|
||||
use Closure;
|
||||
use ReflectionClass;
|
||||
use ReflectionException;
|
||||
|
||||
class CheckLogin
|
||||
{
|
||||
use JumpTrait;
|
||||
|
||||
/**
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function handle(Request $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(env('EASYADMIN.ADMIN') . '/login/index'));
|
||||
}
|
||||
}
|
||||
$request->adminUserInfo = $adminUserInfo ?: [];
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -3,38 +3,38 @@
|
||||
namespace app\admin\middleware;
|
||||
|
||||
use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\MiddlewareAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\admin\service\SystemLogService;
|
||||
use app\common\traits\JumpTrait;
|
||||
use app\Request;
|
||||
use app\admin\service\tool\CommonTool;
|
||||
use Doctrine\Common\Annotations\AnnotationReader;
|
||||
use Doctrine\Common\Annotations\DocParser;
|
||||
use Closure;
|
||||
use ReflectionException;
|
||||
|
||||
/**
|
||||
* 系统操作日志中间件
|
||||
* 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)
|
||||
/**
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
$response = $next($request);
|
||||
if (!env('APP_ADMIN_SYSTEM_LOG', true)) return $response;
|
||||
$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,9 +44,9 @@ class SystemLog
|
||||
if (env('APP_DEBUG')) {
|
||||
trace(['url' => $url, 'method' => $method, 'params' => $params,], 'requestDebugInfo');
|
||||
}
|
||||
|
||||
if ($request->isAjax()) {
|
||||
if (in_array($method, ['post', 'put', 'delete'])) {
|
||||
|
||||
$title = '';
|
||||
try {
|
||||
$pathInfo = $request->pathinfo();
|
||||
@@ -55,20 +55,36 @@ class SystemLog
|
||||
$pathInfoExp = explode('.', $pathInfoExp[0] ?? '');
|
||||
$_name = $pathInfoExp[0] ?? '';
|
||||
$_controller = ucfirst($pathInfoExp[1] ?? '');
|
||||
if ($_name && $_controller && $_action) {
|
||||
$className = "app\admin\controller\\{$_name}\\{$_controller}";
|
||||
$reflectionClass = new \ReflectionClass($className);
|
||||
$parser = new DocParser();
|
||||
$parser->setIgnoreNotImportedAnnotations(true);
|
||||
$reader = new AnnotationReader($parser);
|
||||
$controllerAnnotation = $reader->getClassAnnotation($reflectionClass, ControllerAnnotation::class);
|
||||
$reflectionAction = $reflectionClass->getMethod($_action);
|
||||
$nodeAnnotation = $reader->getMethodAnnotation($reflectionAction, NodeAnnotation::class);
|
||||
$title = $controllerAnnotation->title . ' - ' . $nodeAnnotation->title;
|
||||
$className = $_controller ? "app\admin\controller\\{$_name}\\{$_controller}" : "app\admin\controller\\{$_name}";
|
||||
if ($_name && $_action) {
|
||||
$reflectionMethod = new \ReflectionMethod($className, $_action);
|
||||
$attributes = $reflectionMethod->getAttributes(MiddlewareAnnotation::class);
|
||||
foreach ($attributes as $attribute) {
|
||||
$annotation = $attribute->newInstance();
|
||||
$_ignore = (array)$annotation->ignore;
|
||||
if (in_array('log', array_map('strtolower', $_ignore))) return $response;
|
||||
}
|
||||
$controllerTitle = $nodeTitle = '';
|
||||
$controllerAttributes = (new \ReflectionClass($className))->getAttributes(ControllerAnnotation::class);
|
||||
$actionAttributes = $reflectionMethod->getAttributes(NodeAnnotation::class);
|
||||
foreach ($controllerAttributes as $controllerAttribute) {
|
||||
$controllerAnnotation = $controllerAttribute->newInstance();
|
||||
$controllerTitle = $controllerAnnotation->title ?? '';
|
||||
}
|
||||
foreach ($actionAttributes as $actionAttribute) {
|
||||
$actionAnnotation = $actionAttribute->newInstance();
|
||||
$nodeTitle = $actionAnnotation->title ?? '';
|
||||
}
|
||||
$title = $controllerTitle . ' - ' . $nodeTitle;
|
||||
}
|
||||
} catch (\Throwable $exception) {
|
||||
}catch (\Throwable $exception) {
|
||||
}
|
||||
$ip = CommonTool::getRealIp();
|
||||
|
||||
$ip = $request->ip();
|
||||
// 限制记录的响应内容,避免过大
|
||||
$_response = json_encode($response->getData(), JSON_UNESCAPED_UNICODE);
|
||||
$_response = mb_substr($_response, 0, 3000, 'utf-8');
|
||||
|
||||
$data = [
|
||||
'admin_id' => session('admin.id'),
|
||||
'title' => $title,
|
||||
@@ -76,13 +92,13 @@ class SystemLog
|
||||
'method' => $method,
|
||||
'ip' => $ip,
|
||||
'content' => json_encode($params, JSON_UNESCAPED_UNICODE),
|
||||
'useragent' => $_SERVER['HTTP_USER_AGENT'],
|
||||
'response' => $_response,
|
||||
'useragent' => $request->server('HTTP_USER_AGENT'),
|
||||
'create_time' => time(),
|
||||
];
|
||||
SystemLogService::instance()->save($data);
|
||||
}
|
||||
}
|
||||
return $next($request);
|
||||
return $response;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
|
||||
use app\common\model\TimeModel;
|
||||
use think\model\relation\BelongsTo;
|
||||
use think\model\relation\HasOne;
|
||||
|
||||
class MallGoods extends TimeModel
|
||||
{
|
||||
@@ -12,9 +13,18 @@ class MallGoods extends TimeModel
|
||||
|
||||
protected $deleteTime = 'delete_time';
|
||||
|
||||
public function cate()
|
||||
// * +++++++++++++++++++++++++++
|
||||
// | 以下两种写法适用于 with 关联
|
||||
// * +++++++++++++++++++++++++
|
||||
|
||||
// public function cate(): BelongsTo
|
||||
// {
|
||||
// return $this->belongsTo('app\admin\model\MallCate', 'cate_id', 'id');
|
||||
// }
|
||||
|
||||
public function cate(): HasOne
|
||||
{
|
||||
return $this->belongsTo('app\admin\model\MallCate', 'cate_id', 'id');
|
||||
return $this->hasOne(MallCate::class, 'id', 'cate_id');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,6 +10,13 @@ class SystemAdmin extends TimeModel
|
||||
|
||||
protected $deleteTime = 'delete_time';
|
||||
|
||||
public array $notes = [
|
||||
'login_type' => [
|
||||
1 => '密码登录',
|
||||
2 => '密码 + 谷歌验证码登录'
|
||||
],
|
||||
];
|
||||
|
||||
public function getAuthList()
|
||||
{
|
||||
$list = (new SystemAuth())
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
@@ -48,14 +44,13 @@ class SystemLogService
|
||||
$this->tablePrefix = Config::get('database.connections.mysql.prefix');
|
||||
$this->tableSuffix = date('Ym', time());
|
||||
$this->tableName = "{$this->tablePrefix}system_log_{$this->tableSuffix}";
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实例对象
|
||||
* @return SystemLogService|object
|
||||
* @return SystemLogService
|
||||
*/
|
||||
public static function instance()
|
||||
public static function instance(): SystemLogService
|
||||
{
|
||||
if (is_null(self::$instance)) {
|
||||
self::$instance = new static();
|
||||
@@ -69,14 +64,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();
|
||||
}
|
||||
@@ -89,15 +84,16 @@ class SystemLogService
|
||||
*/
|
||||
public function detectTable(): bool
|
||||
{
|
||||
$_key = "system_log_{$this->tableName}_table";
|
||||
// 手动删除日志表时候 记得清除缓存
|
||||
$isset = Cache::get("systemLog{$this->tableName}Table");
|
||||
$isset = Cache::get($_key);
|
||||
if ($isset) return true;
|
||||
$check = Db::query("show tables like '{$this->tableName}'");
|
||||
if (empty($check)) {
|
||||
$sql = $this->getCreateSql();
|
||||
Db::execute($sql);
|
||||
}
|
||||
Cache::set("system_log_{$this->tableName}_table", !empty($check));
|
||||
Cache::set($_key, !empty($check));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -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 '操作时间',
|
||||
|
||||
@@ -41,9 +41,9 @@ class TriggerService
|
||||
* 更新系统设置缓存
|
||||
* @return bool
|
||||
*/
|
||||
public static function updateSysconfig()
|
||||
public static function updateSysConfig(): bool
|
||||
{
|
||||
Cache::tag('sysconfig')->clear();
|
||||
Cache::tag('sysConfig')->clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace app\admin\service;
|
||||
|
||||
use app\admin\model\SystemUploadfile;
|
||||
use OSS\Core\OssException;
|
||||
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
|
||||
use OSS\OssClient;
|
||||
use think\facade\Env;
|
||||
use think\file\UploadedFile;
|
||||
@@ -112,10 +113,21 @@ class UploadService
|
||||
$accessKeySecret = $config['oss_access_key_secret'];
|
||||
$endpoint = $config['oss_endpoint'];
|
||||
$bucket = $config['oss_bucket'];
|
||||
// 升级 aliyuncs/oss-sdk-php 到 v2.7.2 以上, 使用签名 v4 版本
|
||||
putenv('OSS_ACCESS_KEY_ID=' . $accessKeyId);
|
||||
putenv('OSS_ACCESS_KEY_SECRET=' . $accessKeySecret);
|
||||
$region = str_replace(['http://oss-', 'https://oss-', 'oss-'], '', explode('.aliyuncs.com', $endpoint)[0] ?? '');
|
||||
$provider = new EnvironmentVariableCredentialsProvider();
|
||||
$args = [
|
||||
"provider" => $provider,
|
||||
"endpoint" => $endpoint,
|
||||
"signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
|
||||
"region" => $region
|
||||
];
|
||||
if ($file->isValid()) {
|
||||
$object = $this->setFilePath($file, Env::get('EASYADMIN.OSS_STATIC_PREFIX', 'easyadmin8') . '/');
|
||||
try {
|
||||
$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
|
||||
$ossClient = new OssClient($args);
|
||||
$_rs = $ossClient->putObject($bucket, $object, file_get_contents($file->getRealPath()));
|
||||
$oss_request_url = $_rs['oss-request-url'] ?? '';
|
||||
if (empty($oss_request_url)) return ['code' => 0, 'data' => '上传至OSS失败'];
|
||||
@@ -164,7 +176,7 @@ class UploadService
|
||||
if (empty($location)) return ['code' => 0, 'data' => '上传至COS失败'];
|
||||
$location = 'https://' . $location;
|
||||
$this->setSaveData($file);
|
||||
} catch (Exception $e) {
|
||||
}catch (Exception $e) {
|
||||
return ['code' => 0, 'data' => $e->getMessage()];
|
||||
}
|
||||
$data = ['url' => $location];
|
||||
|
||||
@@ -2,38 +2,20 @@
|
||||
|
||||
namespace app\admin\service\annotation;
|
||||
|
||||
use Doctrine\Common\Annotations\Annotation\Attributes;
|
||||
use Doctrine\Common\Annotations\Annotation\Required;
|
||||
use Doctrine\Common\Annotations\Annotation\Target;
|
||||
use Attribute;
|
||||
|
||||
/**
|
||||
* Class ControllerAnnotation
|
||||
*
|
||||
* @Annotation
|
||||
* @Target("CLASS")
|
||||
* @Attributes({
|
||||
* @Attribute("title", type="string"),
|
||||
* })
|
||||
*
|
||||
* @since 2.0
|
||||
* controller 节点注解类
|
||||
*/
|
||||
#[Attribute]
|
||||
final class ControllerAnnotation
|
||||
{
|
||||
|
||||
/**
|
||||
* Route group prefix for the controller
|
||||
*
|
||||
* @Required()
|
||||
*
|
||||
* @var string
|
||||
* @param string $title
|
||||
* @param bool $auth 是否需要权限
|
||||
* @param string|array $ignore
|
||||
*/
|
||||
public $title = '';
|
||||
|
||||
/**
|
||||
* 是否开启权限控制
|
||||
* @Enum({true,false})
|
||||
* @var bool
|
||||
*/
|
||||
public $auth = true;
|
||||
|
||||
public function __construct(public string $title = '', public bool $auth = true, public string|array $ignore = '')
|
||||
{
|
||||
}
|
||||
}
|
||||
16
app/admin/service/annotation/MiddlewareAnnotation.php
Normal file
16
app/admin/service/annotation/MiddlewareAnnotation.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\service\annotation;
|
||||
|
||||
use Attribute;
|
||||
|
||||
#[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_METHOD)]
|
||||
final class MiddlewareAnnotation
|
||||
{
|
||||
/** 过滤日志 */
|
||||
const IGNORE_LOG = 'LOG';
|
||||
|
||||
public function __construct(public string $type = '', public string|array $ignore = '')
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -2,32 +2,24 @@
|
||||
|
||||
namespace app\admin\service\annotation;
|
||||
|
||||
use Doctrine\Common\Annotations\Annotation\Attributes;
|
||||
use Attribute;
|
||||
|
||||
/**
|
||||
* 创建节点注解类
|
||||
*
|
||||
* @Annotation
|
||||
* @Target({"METHOD","CLASS"})
|
||||
* @Attributes({
|
||||
* @Attribute("time", type = "int")
|
||||
* })
|
||||
* action 节点注解类
|
||||
*/
|
||||
#[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_METHOD| Attribute::TARGET_PROPERTY)]
|
||||
final class NodeAnnotation
|
||||
{
|
||||
/** 过滤节点 */
|
||||
const IGNORE_NODE = 'NODE';
|
||||
|
||||
/**
|
||||
* 节点名称
|
||||
* @Required()
|
||||
* @var string
|
||||
* @param string $title
|
||||
* @param bool $auth 是否需要权限
|
||||
* @param string|array $ignore
|
||||
*/
|
||||
public string $title;
|
||||
|
||||
/**
|
||||
* 是否开启权限控制
|
||||
* @Enum({true,false})
|
||||
* @var bool
|
||||
*/
|
||||
public bool $auth = true;
|
||||
public function __construct(public string $title = '', public bool $auth = true, public string|array $ignore = '')
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
@@ -65,15 +67,23 @@ 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;
|
||||
|
||||
// 忽略掉不需要的节点
|
||||
$property = $reflectionClass->getProperty('ignoreNode');
|
||||
$propertyAttributes = $property->getAttributes(NodeAnnotation::class);
|
||||
if (!empty($propertyAttributes[0])) {
|
||||
$propertyAttribute = $propertyAttributes[0]->newInstance();
|
||||
if (in_array($method->name, $propertyAttribute->ignore)) continue;
|
||||
}
|
||||
|
||||
$attributes = $reflectionClass->getMethod($method->name)->getAttributes(NodeAnnotation::class);
|
||||
foreach ($attributes as $attribute) {
|
||||
$annotation = $attribute->newInstance();
|
||||
if (!empty($annotation->ignore)) if (strtolower($annotation->ignore) == 'node') continue;
|
||||
$actionList[] = [
|
||||
'node' => $controllerFormat . '/' . $method->name,
|
||||
'title' => $actionTitle,
|
||||
'is_auth' => $actionAuth,
|
||||
'title' => $annotation->title ?? null,
|
||||
'is_auth' => $annotation->auth ?? false,
|
||||
'type' => 2,
|
||||
];
|
||||
}
|
||||
@@ -81,16 +91,17 @@ 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;
|
||||
$nodeList[] = [
|
||||
'node' => $controllerFormat,
|
||||
'title' => $controllerTitle,
|
||||
'is_auth' => $controllerAuth,
|
||||
'type' => 1,
|
||||
];
|
||||
$nodeList = array_merge($nodeList, $actionList);
|
||||
$attributes = $reflectionClass->getAttributes(ControllerAnnotation::class);
|
||||
foreach ($attributes as $attribute) {
|
||||
$controllerAnnotation = $attribute->newInstance();
|
||||
$nodeList[] = [
|
||||
'node' => $controllerFormat,
|
||||
'title' => $controllerAnnotation->title ?? null,
|
||||
'is_auth' => $controllerAnnotation->auth ?? false,
|
||||
'type' => 1,
|
||||
];
|
||||
}
|
||||
$nodeList = array_merge($nodeList, $actionList);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -102,7 +113,7 @@ class Node
|
||||
* 获取所有控制器
|
||||
* @return array
|
||||
*/
|
||||
public function getControllerList()
|
||||
public function getControllerList(): array
|
||||
{
|
||||
return $this->readControllerFiles($this->basePath);
|
||||
}
|
||||
@@ -112,10 +123,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 +137,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') {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace EasyAdmin\curd\exceptions;
|
||||
namespace app\admin\service\curd\exceptions;
|
||||
|
||||
class CurdException extends \Exception
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace EasyAdmin\curd\exceptions;
|
||||
namespace app\admin\service\curd\exceptions;
|
||||
|
||||
class FileException extends \Exception
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace app\admin\service\curd\exceptions;
|
||||
|
||||
class TableException extends \Exception
|
||||
{
|
||||
|
||||
}
|
||||
@@ -7,21 +7,21 @@ use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use think\App;
|
||||
|
||||
/**
|
||||
* @ControllerAnnotation(title="{{controllerAnnotation}}")
|
||||
*/
|
||||
#[ControllerAnnotation(title: '{{controllerAnnotation}}')]
|
||||
class {{controllerName}} extends AdminController
|
||||
{
|
||||
|
||||
use \app\admin\traits\Curd;
|
||||
private array $notes;
|
||||
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
|
||||
$this->model = new {{modelFilename}}();
|
||||
{{selectList}}
|
||||
$this->notes = $notes = $this->model->notes;
|
||||
{{constructRelation}}
|
||||
$this->assign(compact('notes'));
|
||||
}
|
||||
|
||||
{{indexMethod}}
|
||||
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="列表")
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
if ($this->request->isAjax()) {
|
||||
if (input('selectFields')) {
|
||||
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();
|
||||
$data = [
|
||||
'code' => 0,
|
||||
'msg' => '',
|
||||
'count' => $count,
|
||||
'data' => $list,
|
||||
];
|
||||
return json($data);
|
||||
}
|
||||
return $this->fetch();
|
||||
}
|
||||
@@ -13,7 +13,6 @@ class {{modelName}} extends TimeModel
|
||||
|
||||
protected $deleteTime = {{deleteTime}};
|
||||
|
||||
{{relationList}}
|
||||
{{selectList}}
|
||||
public array $notes = {{selectArrays}};
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
});
|
||||
@@ -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>
|
||||
@@ -5,6 +5,11 @@
|
||||
data-auth-edit="{:auth('{{controllerUrl}}/edit')}"
|
||||
data-auth-delete="{:auth('{{controllerUrl}}/delete')}"
|
||||
lay-filter="currentTable">
|
||||
<!-- searchTableShow="false" 隐藏搜索框 -->
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
{{notesScript}}
|
||||
</script>
|
||||
7
app/admin/service/curd/templates/view/module/sort.code
Normal file
7
app/admin/service/curd/templates/view/module/sort.code
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{{comment}}</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="{{field}}" class="layui-input" lay-affix="number" {{required}} placeholder="请输入{{comment}}" value="{{value}}">
|
||||
</div>
|
||||
</div>
|
||||
@@ -14,7 +14,7 @@ class CommonTool
|
||||
{
|
||||
$str = preg_replace_callback('/([-_]+([a-z]{1}))/i', function ($matches) {
|
||||
return strtoupper($matches[2]);
|
||||
}, $str);
|
||||
}, $str);
|
||||
return $str;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ class CommonTool
|
||||
{
|
||||
$str = preg_replace_callback('/([A-Z]{1})/', function ($matches) {
|
||||
return '_' . strtolower($matches[0]);
|
||||
}, $str);
|
||||
}, $str);
|
||||
return $str;
|
||||
}
|
||||
|
||||
@@ -45,11 +45,11 @@ class CommonTool
|
||||
break;
|
||||
}
|
||||
}
|
||||
} elseif (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) {
|
||||
}elseif (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) {
|
||||
$ip = $_SERVER['HTTP_CLIENT_IP'];
|
||||
} elseif (isset($_SERVER['HTTP_CF_CONNECTING_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CF_CONNECTING_IP'])) {
|
||||
}elseif (isset($_SERVER['HTTP_CF_CONNECTING_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CF_CONNECTING_IP'])) {
|
||||
$ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
|
||||
} elseif (isset($_SERVER['HTTP_X_REAL_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_X_REAL_IP'])) {
|
||||
}elseif (isset($_SERVER['HTTP_X_REAL_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_X_REAL_IP'])) {
|
||||
$ip = $_SERVER['HTTP_X_REAL_IP'];
|
||||
}
|
||||
return $ip;
|
||||
@@ -70,7 +70,7 @@ class CommonTool
|
||||
if (is_dir($path . DIRECTORY_SEPARATOR . $file)) {
|
||||
$childFiles = self::readDirAllFiles($path . DIRECTORY_SEPARATOR . $file, $basePath);
|
||||
$list = array_merge($childFiles, $list);
|
||||
} else {
|
||||
}else {
|
||||
$filePath = $path . DIRECTORY_SEPARATOR . $file;
|
||||
$fileName = str_replace($basePath . DIRECTORY_SEPARATOR, '', $filePath);
|
||||
$list[$fileName] = $filePath;
|
||||
@@ -95,4 +95,11 @@ class CommonTool
|
||||
return $string;
|
||||
}
|
||||
|
||||
|
||||
public static function replaceArrayString(?string $arrayString): string
|
||||
{
|
||||
$arrayString = str_replace('array (', '[', $arrayString);
|
||||
$arrayString = str_replace(')', ']', $arrayString);
|
||||
return $arrayString;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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,
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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'],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -1,12 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
|
||||
namespace app\admin\service\upload\interfaces;
|
||||
|
||||
interface OssDriver
|
||||
{
|
||||
|
||||
public function save($objectName,$filePath);
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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复用
|
||||
@@ -15,24 +17,16 @@ use think\facade\Db;
|
||||
trait Curd
|
||||
{
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="列表")
|
||||
*/
|
||||
public function index()
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
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' => '',
|
||||
@@ -44,39 +38,39 @@ trait Curd
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="添加")
|
||||
*/
|
||||
public function add()
|
||||
#[NodeAnnotation(title: '添加', auth: true)]
|
||||
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->save($post);
|
||||
});
|
||||
}catch (\Exception $e) {
|
||||
$this->error('新增失败:' . $e->getMessage());
|
||||
}
|
||||
$save ? $this->success('保存成功') : $this->error('保存失败');
|
||||
$save ? $this->success('新增成功') : $this->error('新增失败');
|
||||
}
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="编辑")
|
||||
*/
|
||||
public function edit($id)
|
||||
#[NodeAnnotation(title: '编辑', auth: true)]
|
||||
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('保存失败');
|
||||
@@ -85,25 +79,23 @@ trait Curd
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="删除")
|
||||
*/
|
||||
public function delete($id)
|
||||
#[NodeAnnotation(title: '删除', auth: true)]
|
||||
public function delete(Request $request): void
|
||||
{
|
||||
// 如果不是id作为主键 请在对应的控制器中覆盖重写
|
||||
$id = $request->param('id', []);
|
||||
$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('删除失败');
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="导出")
|
||||
*/
|
||||
#[NodeAnnotation(title: '导出', auth: true)]
|
||||
public function export()
|
||||
{
|
||||
if (env('EASYADMIN.IS_DEMO', false)) {
|
||||
@@ -131,13 +123,11 @@ trait Curd
|
||||
return Excel::exportData($list, $header, $fileName, 'xlsx');
|
||||
}
|
||||
|
||||
/**
|
||||
* @NodeAnnotation(title="属性修改")
|
||||
*/
|
||||
public function modify()
|
||||
#[NodeAnnotation(title: '属性修改', auth: true)]
|
||||
public function modify(Request $request): void
|
||||
{
|
||||
$this->checkPostRequest();
|
||||
$post = $this->request->post();
|
||||
$post = $request->post();
|
||||
$rule = [
|
||||
'id|ID' => 'require',
|
||||
'field|字段' => 'require',
|
||||
@@ -152,10 +142,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('保存成功');
|
||||
|
||||
@@ -30,6 +30,15 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">登录方式</label>
|
||||
<div class="layui-input-block">
|
||||
{foreach notes.login_type as $key=>$val}
|
||||
<input type="radio" name="login_type" lay-skin="primary" title="{$val}" value="{$key}" lay-filter="loginType-filter" {if $key==$row.login_type}checked=""{/if}>
|
||||
{/foreach}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">备注信息</label>
|
||||
<div class="layui-input-block">
|
||||
|
||||
@@ -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">
|
||||
@@ -26,15 +26,6 @@
|
||||
</ul>
|
||||
|
||||
<ul class="layui-nav layui-layout-right">
|
||||
<!-- <li class="layui-nav-item" lay-unselect>-->
|
||||
<!-- <div class="layui-form ws-header-theme" lay-filter="header-theme">-->
|
||||
<!-- <input type="checkbox" name="theme-mode" id="ID-header-theme-mode" lay-filter="header-theme-mode" lay-skin="switch">-->
|
||||
<!-- <div lay-checkbox>-->
|
||||
<!-- <i class="layui-icon layui-icon-moon"></i> |-->
|
||||
<!-- <i class="layui-icon layui-icon-light"></i>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </li>-->
|
||||
<li class="layui-nav-item" lay-unselect>
|
||||
<a href="http://easyadmin8.top" target="_blank"><i class="fa fa-home"></i></a>
|
||||
</li>
|
||||
@@ -47,6 +38,15 @@
|
||||
<li class="layui-nav-item mobile layui-hide-xs" lay-unselect>
|
||||
<a href="javascript:;" data-check-screen="full"><i class="fa fa-arrows-alt"></i></a>
|
||||
</li>
|
||||
<li class="layui-nav-item" lay-unselect>
|
||||
<div class="layui-form ws-header-theme" lay-filter="header-theme">
|
||||
<input type="checkbox" name="theme-mode" lay-filter="header-theme-mode" lay-skin="switch">
|
||||
<div lay-checkbox>
|
||||
<i class="layui-icon layui-icon-moon"></i> |
|
||||
<i class="layui-icon layui-icon-light"></i>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="layui-nav-item layuimini-setting">
|
||||
<a href="javascript:;">
|
||||
<img src="{:session('admin.head_img')}" class="layui-nav-img" width="50" height="50">
|
||||
|
||||
45
app/admin/view/index/set2fa.html
Normal file
45
app/admin/view/index/set2fa.html
Normal file
@@ -0,0 +1,45 @@
|
||||
<div class="layuimini-container">
|
||||
<form id="app-form" class="layui-form layuimini-form" autocomplete="off">
|
||||
{if $old_secret}
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">提示</div>
|
||||
<div class="layui-card-body">
|
||||
当前账号已经绑定过了 谷歌验证码 ,如果重新保存将替换
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">验证秘钥</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="ga_secret" class="layui-input" value="{$secret}" readonly disabled>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">二维码</label>
|
||||
<div class="layui-input-block">
|
||||
<img src="{$dataUri}" alt="二维码" style="width: 200px;height: 200px">
|
||||
<div class="layui-text layui-font-cyan layui-font-12">
|
||||
使用
|
||||
<a href="https://2fas.com" target="_blank"><span class="layui-text layui-font-blue">2FAS</span></a>
|
||||
或者
|
||||
<a href="https://cn.bing.com/search?q=Google+Authenticator" target="_blank"><span class="layui-text layui-font-blue">Google Authenticator</span></a>
|
||||
APP 扫描二维码 后 输入验证码 进行绑定
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">谷歌验证码</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="ga_code" class="layui-input" maxlength="6" lay-verify="required" placeholder="扫描二维码,输入验证码" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class=" hr-line">
|
||||
</div>
|
||||
<div class="layui-form-item text-center">
|
||||
<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>
|
||||
@@ -1,67 +1,59 @@
|
||||
<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">
|
||||
<div class="layui-col-md8">
|
||||
<div class="layui-row layui-col-space15">
|
||||
<div class="layui-col-md6">
|
||||
<link rel="stylesheet" href="/static/admin/css/welcome.css?v={$version}" media="all">
|
||||
<div class="layui-layout layui-padding-2">
|
||||
<div class="layui-layout-admin">
|
||||
<div class="layui-row layui-col-space10">
|
||||
<div class="layui-col-md8 ">
|
||||
<div class="layui-row layui-col-space10">
|
||||
<div class="layui-col-md6 ">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header"><i class="fa fa-warning icon"></i>数据统计</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="welcome-module">
|
||||
<div class="layui-row layui-col-space10">
|
||||
<div class="layui-col-xs6">
|
||||
<div class="panel layui-bg-number">
|
||||
<div class="panel-body">
|
||||
<div class="panel-title">
|
||||
<span class="label pull-right layui-bg-blue">实时</span>
|
||||
<div class="layui-panel">
|
||||
<div class="layui-card-body">
|
||||
<span class="layui-badge layui-bg-cyan pull-right ">实时</span>
|
||||
<div class="panel-content">
|
||||
<h5>用户统计</h5>
|
||||
</div>
|
||||
<div class="panel-content">
|
||||
<h1 class="no-margins">1234</h1>
|
||||
<small>当前分类总记录数</small>
|
||||
<h1>1234</h1>
|
||||
<h6>当前分类总记录数</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-xs6">
|
||||
<div class="panel layui-bg-number">
|
||||
<div class="panel-body">
|
||||
<div class="panel-title">
|
||||
<span class="label pull-right layui-bg-cyan">实时</span>
|
||||
<div class="layui-panel">
|
||||
<div class="layui-card-body">
|
||||
<span class="layui-badge layui-bg-purple pull-right ">实时</span>
|
||||
<div class="panel-content">
|
||||
<h5>商品统计</h5>
|
||||
</div>
|
||||
<div class="panel-content">
|
||||
<h1 class="no-margins">1234</h1>
|
||||
<small>当前分类总记录数</small>
|
||||
<h1>1234</h1>
|
||||
<h6>当前分类总记录数</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-xs6">
|
||||
<div class="panel layui-bg-number">
|
||||
<div class="panel-body">
|
||||
<div class="panel-title">
|
||||
<span class="label pull-right layui-bg-orange">实时</span>
|
||||
<div class="layui-panel">
|
||||
<div class="layui-card-body ">
|
||||
<span class="layui-badge layui-bg-orange pull-right ">实时</span>
|
||||
<div class="panel-content">
|
||||
<h5>浏览统计</h5>
|
||||
</div>
|
||||
<div class="panel-content">
|
||||
<h1 class="no-margins">1234</h1>
|
||||
<small>当前分类总记录数</small>
|
||||
<h1>1234</h1>
|
||||
<h6>当前分类总记录数</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-xs6">
|
||||
<div class="panel layui-bg-number">
|
||||
<div class="panel-body">
|
||||
<div class="panel-title">
|
||||
<span class="label pull-right layui-bg-green">实时</span>
|
||||
<h5>订单统计</h5>
|
||||
</div>
|
||||
<div class="layui-panel">
|
||||
<div class="layui-card-body ">
|
||||
<span class="layui-badge layui-bg-red pull-right ">实时</span>
|
||||
<div class="panel-content">
|
||||
<h1 class="no-margins">1234</h1>
|
||||
<small>当前分类总记录数</small>
|
||||
<h5>订单统计</h5>
|
||||
<h1>1234</h1>
|
||||
<h6>当前分类总记录数</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -71,29 +63,40 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md6">
|
||||
<div class="layui-col-md6 ">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header"><i class="fa fa-credit-card icon icon-blue"></i>快捷入口</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="welcome-module">
|
||||
<div class="layui-row layui-col-space10 layuimini-qiuck">
|
||||
<div class="layui-row layui-col-space10">
|
||||
<div class="swiper mySwiper">
|
||||
<div class="swiper-wrapper">
|
||||
{foreach $quicks as $value}
|
||||
|
||||
{foreach $quicks as $vo}
|
||||
<div class="layui-col-xs3 layuimini-qiuck-module">
|
||||
<a layuimini-content-href="{:url($vo['href'])}" data-title="{$vo['title']}">
|
||||
<i class="{$vo['icon']|raw}"></i>
|
||||
<cite>{$vo['title']}</cite>
|
||||
</a>
|
||||
<div class="swiper-slide">
|
||||
{foreach $value as $vo}
|
||||
|
||||
<div class="layui-col-xs3 layuimini-qiuck-module">
|
||||
<a layuimini-content-href="{:url($vo['href'])}" data-title="{$vo['title']}">
|
||||
<i class="{$vo['icon']|raw}"></i>
|
||||
<cite>{$vo['title']}</cite>
|
||||
</a>
|
||||
</div>
|
||||
{/foreach}
|
||||
|
||||
</div>
|
||||
{/foreach}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{/foreach}
|
||||
|
||||
<div class="swiper-pagination"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="layui-col-md12">
|
||||
<div class="layui-col-md12 ">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header"><i class="fa fa-line-chart icon"></i>报表统计</div>
|
||||
<div class="layui-card-body">
|
||||
@@ -104,7 +107,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-col-md4">
|
||||
<div class="layui-col-md4 ">
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header"><i class="fa fa-fire icon"></i>版本信息</div>
|
||||
@@ -145,6 +148,15 @@
|
||||
<button type="button" class="layui-btn layui-btn-xs layui-btn-primary" id="layui-version">-</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>DEBUG模式</td>
|
||||
<td>
|
||||
<button type="button" class="layui-btn layui-btn-xs {:env('APP_DEBUG')?'layui-btn-warm':'layui-bg-gray'}">
|
||||
{:env('APP_DEBUG')?'开启中':'已关闭'}
|
||||
</button>
|
||||
<span class="layui-badge layui-bg-gray">建议线上环境关闭 APP_DEBUG</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>主要特色</td>
|
||||
<td>
|
||||
@@ -167,8 +179,8 @@
|
||||
<tr>
|
||||
<td>Github</td>
|
||||
<td>
|
||||
<a href="https://github.com/wolf-leo/easyAdmin8" target="_blank" style="text-decoration: none;">
|
||||
<i class="layui-icon layui-icon-github" style="font-size: 25px; color: #333333;"></i>
|
||||
<a href="https://github.com/wolf-leo/easyAdmin8" target="_blank">
|
||||
<i class="layui-icon layui-icon-github layui-font-20 layui-font-gray layui-text"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -179,16 +191,18 @@
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header"><i class="fa fa-paper-plane-o icon"></i>作者心语</div>
|
||||
<div class="layui-card-body layui-text layadmin-text">
|
||||
<p>本模板基于layui2.8.x以及font-awesome-4.7.0进行实现。layui开发文档地址:<a class="layui-btn layui-btn-xs layui-btn-danger" target="_blank" href="http://layui.dev/docs">layui文档</a></p>
|
||||
<p class="layui-red">备注:此后台框架永久开源,但请勿进行出售或者上传到任何素材网站,否则将追究相应的责任。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header"><i class="fa fa-qq icon"></i>QQ交流群</div>
|
||||
<div class="layui-card-body layui-text layadmin-text">
|
||||
<img src="/static/common/images/EasyAdmin8-ThinkPHP.png">
|
||||
<div class="layui-card-body layui-text">
|
||||
<p>
|
||||
本模板基于layui2.9.x以及font-awesome-4.7.0进行实现。
|
||||
<a class="layui-btn layui-btn-xs layui-btn-danger" style="vertical-align: baseline;" target="_blank" href="http://layui.dev/docs">layui文档</a>
|
||||
</p>
|
||||
<hr>
|
||||
<p class="layui-font-red">备注:此后台框架永久开源,但请勿进行出售或者上传到任何素材网站,否则将追究相应的责任。</p>
|
||||
<hr>
|
||||
<div class="layui-card-header"><i class="fa fa-qq icon"></i>QQ交流群</div>
|
||||
<div class="layui-card-body">
|
||||
<img src="/static/common/images/EasyAdmin8-ThinkPHP.png" width="145">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -2,15 +2,16 @@
|
||||
<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">
|
||||
<link rel="icon" href="{:sysConfig('site', 'site_ico')}" type="image/x-icon">
|
||||
<!--[if lt IE 9]>
|
||||
<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 = {
|
||||
@@ -21,14 +22,15 @@
|
||||
IS_SUPER_ADMIN: "{$isSuperAdmin|default='false'}",
|
||||
VERSION: "{$version|default='1.0.0'}",
|
||||
CSRF_TOKEN: "{:token()}",
|
||||
ADMIN_UPLOAD_URL: "{$adminUploadUrl|DEFAULT=''}",
|
||||
EDITOR_TYPE: "{$adminEditor|default='ueditor'}",
|
||||
ADMIN_UPLOAD_URL: "{$adminUploadUrl|default=''}",
|
||||
IFRAME_OPEN_TOP: "{$iframeOpenTop|default=0}",
|
||||
EDITOR_TYPE: "{$adminEditor|default='wangEditor'}",
|
||||
};
|
||||
</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" charset="utf-8"></script>
|
||||
<script src="/static/plugs/require-2.3.6/require.js" 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>
|
||||
|
||||
@@ -1,20 +1,27 @@
|
||||
{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}
|
||||
|
||||
|
||||
{case EasyMDE}
|
||||
|
||||
<link rel="stylesheet" href="/static/plugs/easymde/easymde.min.css?v={$version}">
|
||||
<script src="/static/plugs/easymde/easymde.min.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}
|
||||
|
||||
@@ -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">
|
||||
@@ -22,6 +22,11 @@
|
||||
<span class="bind-password icon icon-4"></span>
|
||||
</div>
|
||||
|
||||
<div class="item layui-hide" id="gaCode">
|
||||
<span class="icon icon-3"></span>
|
||||
<input type="text" name="ga_code" placeholder="谷歌验证码" maxlength="6">
|
||||
</div>
|
||||
|
||||
{if $captcha == 1}
|
||||
<div id="validatePanel" class="item" style="width: 137px;">
|
||||
<input type="text" name="captcha" placeholder="请输入验证码" maxlength="4">
|
||||
@@ -36,15 +41,15 @@
|
||||
<a href="javascript:" class="forget-password">忘记密码?</a>
|
||||
</div>
|
||||
<div class="layui-form-item" style="text-align:center; width:100%;height:100%;margin:0px;">
|
||||
<button class="login-btn" lay-submit>立即登录</button>
|
||||
<button type="button" class="login-btn" lay-submit>立即登录</button>
|
||||
</div>
|
||||
</form>
|
||||
</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>
|
||||
@@ -22,7 +22,7 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">分类排序</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="sort" class="layui-input" placeholder="请输入分类排序" value="0">
|
||||
<input type="number" name="sort" class="layui-input" lay-affix="number" placeholder="请输入分类排序" value="0">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">分类排序</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="sort" class="layui-input" placeholder="请输入分类排序" value="{$row.sort|default=''}">
|
||||
<input type="number" name="sort" class="layui-input" lay-affix="number" placeholder="请输入分类排序" value="{$row.sort|default=''}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,84 +1,104 @@
|
||||
<div class="layuimini-container">
|
||||
<form id="app-form" class="layui-form layuimini-form">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">商品分类</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="cate_id" lay-verify="required" data-select="{:url('mall.cate/index')}" data-fields="id,title">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<form id="app-form" class="layui-form layuimini-form layui-form-pane">
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">商品标题</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="title" class="layui-input" lay-verify="required" placeholder="请输入商品标题" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-row">
|
||||
<div class="layui-col-xl5 layui-col-lg5 layui-col-md12 layui-col-sm12 layui-col-xs12">
|
||||
<!-- 可以使用该方式 推荐写法-->
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">商品分类</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="cate_id" lay-verify="required" data-select="{:url('mall.cate/index')}" data-fields="id,title">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">商品LOGO</label>
|
||||
<div class="layui-input-block layuimini-upload">
|
||||
<input name="logo" class="layui-input layui-col-xs6" lay-verify="required" placeholder="请上传分类图片" value="">
|
||||
<div class="layuimini-upload-btn">
|
||||
<span><a class="layui-btn" data-upload="logo" data-upload-number="one" data-upload-exts="png|jpg|ico|jpeg" data-upload-icon="image"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_logo" data-upload-select="logo" data-upload-number="one" data-upload-mimetype="image/*"><i class="fa fa-list"></i> 选择</a></span>
|
||||
<!--也可以使用该方式-->
|
||||
<!-- <div class="layui-form-item">-->
|
||||
<!-- <label class="layui-form-label">商品分类</label>-->
|
||||
<!-- <div class="layui-input-block">-->
|
||||
<!-- <select name="cate_id" lay-verify="required">-->
|
||||
<!-- <option value="">请选择</option>-->
|
||||
<!-- {volist name='cate' id='vo'}-->
|
||||
<!-- <option value="{$key}">{$vo}</option>-->
|
||||
<!-- {/volist}-->
|
||||
<!-- </select>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">商品标题</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="title" class="layui-input" lay-verify="required" placeholder="请输入商品标题" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">商品LOGO</label>
|
||||
<div class="layui-input-block layuimini-upload">
|
||||
<input name="logo" class="layui-input layui-col-xs6" lay-verify="required" placeholder="请上传分类图片" value="">
|
||||
<div class="layuimini-upload-btn">
|
||||
<span><a class="layui-btn" data-upload="logo" data-upload-number="one" data-upload-exts="png|jpg|ico|jpeg" data-upload-icon="image"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_logo" data-upload-select="logo" data-upload-number="one" data-upload-mimetype="image/*"><i class="fa fa-list"></i> 选择</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">商品图片</label>
|
||||
<div class="layui-input-block layuimini-upload">
|
||||
<input name="images" class="layui-input layui-col-xs6" lay-verify="required" placeholder="请上传商品图片" value="">
|
||||
<div class="layuimini-upload-btn">
|
||||
<span><a class="layui-btn" data-upload="images" data-upload-number="more" data-upload-exts="png|jpg|ico|jpeg" data-upload-icon="image"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_images" data-upload-select="images" data-upload-number="more" data-upload-mimetype="image/*"><i class="fa fa-list"></i> 选择</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">市场价格</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="market_price" class="layui-input" lay-verify="required" placeholder="请输入市场价格" value="0">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">折扣价格</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="discount_price" class="layui-input" lay-verify="required" placeholder="请输入折扣价格" value="0">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">虚拟销量</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="virtual_sales" class="layui-input" lay-verify="required" placeholder="请输入虚拟销量" value="0">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">分类排序</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="sort" class="layui-input" lay-affix="number" placeholder="请输入分类排序" value="0">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">备注信息</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="remark" class="layui-textarea" placeholder="请输入备注信息"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">商品图片</label>
|
||||
<div class="layui-input-block layuimini-upload">
|
||||
<input name="images" class="layui-input layui-col-xs6" lay-verify="required" placeholder="请上传商品图片" value="">
|
||||
<div class="layuimini-upload-btn">
|
||||
<span><a class="layui-btn" data-upload="images" data-upload-number="more" data-upload-exts="png|jpg|ico|jpeg" data-upload-icon="image"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_images" data-upload-select="images" data-upload-number="more" data-upload-mimetype="image/*"><i class="fa fa-list"></i> 选择</a></span>
|
||||
<div class="layui-col-xl7 layui-col-lg7 layui-col-md12 layui-col-sm12 layui-col-xs12">
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">商品描述</label>
|
||||
<div class="layui-input-block">
|
||||
{:editor_textarea('','describe')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">市场价格</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="market_price" class="layui-input" lay-verify="required" placeholder="请输入市场价格" value="0">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">折扣价格</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="discount_price" class="layui-input" lay-verify="required" placeholder="请输入折扣价格" value="0">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">虚拟销量</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="virtual_sales" class="layui-input" lay-verify="required" placeholder="请输入虚拟销量" value="0">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">商品描述</label>
|
||||
<div class="layui-input-block">
|
||||
{:editor_textarea('','describe')}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">分类排序</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="sort" class="layui-input" placeholder="请输入分类排序" value="0">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">备注信息</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="remark" class="layui-textarea" placeholder="请输入备注信息"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hr-line"></div>
|
||||
<div class="layui-form-item text-center">
|
||||
<button type="submit" class="layui-btn layui-btn-normal layui-btn-sm" lay-submit>确认</button>
|
||||
|
||||
@@ -1,85 +1,104 @@
|
||||
<div class="layuimini-container">
|
||||
<form id="app-form" class="layui-form layuimini-form">
|
||||
<form id="app-form" class="layui-form layuimini-form layui-form-pane">
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">商品分类</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="cate_id" lay-verify="required" data-select="{:url('mall.cate/index')}" data-fields="id,title" data-value="{$row.cate_id|default=''}">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-row">
|
||||
<div class="layui-col-xl5 layui-col-lg5 layui-col-md12 layui-col-sm12 layui-col-xs12">
|
||||
<!-- 可以使用该方式 推荐写法-->
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">商品分类</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="cate_id" lay-verify="required" data-select="{:url('mall.cate/index')}" data-fields="id,title" data-value="{$row.cate_id|default=''}">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">商品标题</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="title" class="layui-input" lay-verify="required" placeholder="请输入商品标题" value="{$row.title|default=''}">
|
||||
</div>
|
||||
</div>
|
||||
<!--也可以使用该方式-->
|
||||
<!-- <div class="layui-form-item">-->
|
||||
<!-- <label class="layui-form-label">商品分类</label>-->
|
||||
<!-- <div class="layui-input-block">-->
|
||||
<!-- <select name="cate_id" lay-verify="required">-->
|
||||
<!-- <option value="">请选择</option>-->
|
||||
<!-- {volist name='cate' id='vo'}-->
|
||||
<!-- <option value="{$key}" {if $key==$row.cate_id}selected{/if}>{$vo}</option>-->
|
||||
<!-- {/volist}-->
|
||||
<!-- </select>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">商品LOGO</label>
|
||||
<div class="layui-input-block layuimini-upload">
|
||||
<input name="logo" class="layui-input layui-col-xs6" lay-verify="required" placeholder="请上传分类图片" value="{$row.logo|default=''}">
|
||||
<div class="layuimini-upload-btn">
|
||||
<span><a class="layui-btn" data-upload="logo" data-upload-number="one" data-upload-exts="png|jpg|ico|jpeg" data-upload-icon="image"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_logo" data-upload-select="logo" data-upload-number="one" data-upload-mimetype="image/*"><i class="fa fa-list"></i> 选择</a></span>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">商品标题</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="title" class="layui-input" lay-verify="required" placeholder="请输入商品标题" value="{$row.title|default=''}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">商品LOGO</label>
|
||||
<div class="layui-input-block layuimini-upload">
|
||||
<input name="logo" class="layui-input layui-col-xs6" lay-verify="required" placeholder="请上传分类图片" value="{$row.logo|default=''}">
|
||||
<div class="layuimini-upload-btn">
|
||||
<span><a class="layui-btn" data-upload="logo" data-upload-number="one" data-upload-exts="png|jpg|ico|jpeg" data-upload-icon="image"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_logo" data-upload-select="logo" data-upload-number="one" data-upload-mimetype="image/*"><i class="fa fa-list"></i> 选择</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">商品图片</label>
|
||||
<div class="layui-input-block layuimini-upload">
|
||||
<input name="images" class="layui-input layui-col-xs6" lay-verify="required" placeholder="请上传商品图片" value="{$row.images|default=''}">
|
||||
<div class="layuimini-upload-btn">
|
||||
<span><a class="layui-btn" data-upload="images" data-upload-number="more" data-upload-exts="png|jpg|ico|jpeg" data-upload-icon="image"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_images" data-upload-select="images" data-upload-number="more" data-upload-mimetype="image/*"><i class="fa fa-list"></i> 选择</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">市场价格</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="market_price" class="layui-input" lay-verify="required" placeholder="请输入市场价格" value="{$row.market_price|default=''}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">折扣价格</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="discount_price" class="layui-input" lay-verify="required" placeholder="请输入折扣价格" value="{$row.discount_price|default=''}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">虚拟销量</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="virtual_sales" class="layui-input" lay-verify="required" placeholder="请输入虚拟销量" value="{$row.virtual_sales|default=''}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">分类排序</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="sort" class="layui-input" lay-affix="number" placeholder="请输入分类排序" value="{$row.sort|default=''}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">备注信息</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="remark" class="layui-textarea" placeholder="请输入备注信息">{$row.remark|default=''}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">商品图片</label>
|
||||
<div class="layui-input-block layuimini-upload">
|
||||
<input name="images" class="layui-input layui-col-xs6" lay-verify="required" placeholder="请上传商品图片" value="{$row.images|default=''}">
|
||||
<div class="layuimini-upload-btn">
|
||||
<span><a class="layui-btn" data-upload="images" data-upload-number="more" data-upload-exts="png|jpg|ico|jpeg" data-upload-icon="image"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_images" data-upload-select="images" data-upload-number="more" data-upload-mimetype="image/*"><i class="fa fa-list"></i> 选择</a></span>
|
||||
<div class="layui-col-xl7 layui-col-lg7 layui-col-md12 layui-col-sm12 layui-col-xs12">
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">商品描述</label>
|
||||
<div class="layui-input-block">
|
||||
{:editor_textarea($row["describe"],'describe')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">市场价格</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="market_price" class="layui-input" lay-verify="required" placeholder="请输入市场价格" value="{$row.market_price|default=''}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">折扣价格</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="discount_price" class="layui-input" lay-verify="required" placeholder="请输入折扣价格" value="{$row.discount_price|default=''}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">虚拟销量</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="virtual_sales" class="layui-input" lay-verify="required" placeholder="请输入虚拟销量" value="{$row.virtual_sales|default=''}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">商品描述</label>
|
||||
<div class="layui-input-block">
|
||||
{:editor_textarea($row["describe"],'describe')}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">分类排序</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="sort" class="layui-input" placeholder="请输入分类排序" value="{$row.sort|default=''}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">备注信息</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="remark" class="layui-textarea" placeholder="请输入备注信息">{$row.remark|default=''}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hr-line"></div>
|
||||
<div class="layui-form-item text-center">
|
||||
<button type="submit" class="layui-btn layui-btn-normal layui-btn-sm" lay-submit>确认</button>
|
||||
|
||||
@@ -8,4 +8,7 @@
|
||||
lay-filter="currentTable">
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
let cateSelects=JSON.parse('{$cate|json_encode=256|raw}')
|
||||
</script>
|
||||
@@ -25,7 +25,7 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">入库数量</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="stock" class="layui-input" lay-verify="required" placeholder="请输入入库数量" value="0">
|
||||
<input type="number" name="stock" class="layui-input" lay-affix="number" lay-verify="required" placeholder="请输入入库数量" value="0">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
<link rel="stylesheet" href="/static/plugs/zTree/fontawesome.css">
|
||||
<link rel="stylesheet" href="/static/plugs/zTree/zTreeStyle.css?v={$version}">
|
||||
<script src='/static/plugs/jquery-3.4.1/jquery-3.4.1.min.js'></script>
|
||||
<script src='/static/plugs/zTree/jquery.ztree.core.js'></script>
|
||||
<script src='/static/plugs/zTree/jquery.ztree.excheck.js'></script>
|
||||
|
||||
<div class="layuimini-container">
|
||||
|
||||
<form id="app-form" class="layui-form layuimini-form">
|
||||
|
||||
<div class="layui-form-item">
|
||||
@@ -10,8 +17,8 @@
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label required">分配节点</label>
|
||||
<div class="layui-input-block">
|
||||
<div id="node_ids" class="demo-tree-more"></div>
|
||||
<div class="layui-input-block" id="zTree">
|
||||
<ul id="tree" class="ztree"></ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -24,4 +31,4 @@
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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,9 +22,9 @@
|
||||
<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" data-upload="admin_background" 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>
|
||||
</div>
|
||||
</div>
|
||||
@@ -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,20 +49,29 @@
|
||||
<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>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">新标签页窗口</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="iframe_open_top" value="0" title="不允许" {if 1!=sysConfig('site','iframe_open_top')}checked{/if}>
|
||||
<input type="radio" name="iframe_open_top" value="1" title="允许" {if 1==sysConfig('site','iframe_open_top')}checked{/if}>
|
||||
<br>
|
||||
<tip>是否允许弹框在新标签页打开。</tip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<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>
|
||||
<tip>默认推荐编辑器。</tip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -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,111 +19,111 @@
|
||||
<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>
|
||||
|
||||
<div class="layui-form-item" v-if="upload_type == 'oss'" v-cloak>
|
||||
<div class="layui-form-item oss layui-hide upload_type">
|
||||
<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>
|
||||
|
||||
<div class="layui-form-item" v-if="upload_type == 'oss'" v-cloak>
|
||||
<div class="layui-form-item oss layui-hide upload_type">
|
||||
<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>
|
||||
|
||||
<div class="layui-form-item" v-if="upload_type == 'oss'" v-cloak>
|
||||
<div class="layui-form-item oss layui-hide upload_type">
|
||||
<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>
|
||||
|
||||
<div class="layui-form-item" v-if="upload_type == 'oss'" v-cloak>
|
||||
<div class="layui-form-item oss layui-hide upload_type">
|
||||
<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>
|
||||
|
||||
<div class="layui-form-item" v-if="upload_type == 'oss'" v-cloak>
|
||||
<div class="layui-form-item oss layui-hide upload_type">
|
||||
<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>
|
||||
|
||||
<div class="layui-form-item" v-if="upload_type == 'cos'" v-cloak>
|
||||
<div class="layui-form-item cos layui-hide upload_type">
|
||||
<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>
|
||||
|
||||
<div class="layui-form-item" v-if="upload_type == 'cos'" v-cloak>
|
||||
<div class="layui-form-item cos layui-hide upload_type">
|
||||
<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>
|
||||
|
||||
<div class="layui-form-item" v-if="upload_type == 'cos'" v-cloak>
|
||||
<div class="layui-form-item cos layui-hide upload_type">
|
||||
<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>
|
||||
|
||||
<div class="layui-form-item" v-if="upload_type == 'cos'" v-cloak>
|
||||
<div class="layui-form-item cos layui-hide upload_type">
|
||||
<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>
|
||||
|
||||
<div class="layui-form-item" v-if="upload_type == 'qnoss'" v-cloak>
|
||||
<div class="layui-form-item qnoss layui-hide upload_type">
|
||||
<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>
|
||||
|
||||
<div class="layui-form-item" v-if="upload_type == 'qnoss'" v-cloak>
|
||||
<div class="layui-form-item qnoss layui-hide upload_type">
|
||||
<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>
|
||||
|
||||
<div class="layui-form-item" v-if="upload_type == 'qnoss'" v-cloak>
|
||||
<div class="layui-form-item qnoss layui-hide upload_type">
|
||||
<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>
|
||||
|
||||
<div class="layui-form-item" v-if="upload_type == 'qnoss'" v-cloak>
|
||||
<div class="layui-form-item qnoss layui-hide upload_type">
|
||||
<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>
|
||||
@@ -1,46 +1,119 @@
|
||||
<style>
|
||||
.table_fields .input_tag {
|
||||
margin-bottom: 5px;
|
||||
display: inline-flex;
|
||||
}
|
||||
</style>
|
||||
<div class="layuimini-container">
|
||||
<div class="layuimini-main" id="app">
|
||||
<div class="layuimini-main">
|
||||
|
||||
<div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
|
||||
<div class="layui-tab" lay-filter="curd-hash">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this" lay-id="1">视图生成</li>
|
||||
<li lay-id="2">命令生成</li>
|
||||
</ul>
|
||||
<div class="layui-tab-content">
|
||||
<div class="layui-tab-item layui-show">
|
||||
<div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
|
||||
|
||||
<form id="app-form" class="layui-form layuimini-form">
|
||||
<form id="app-form" class="layui-form layuimini-form">
|
||||
|
||||
<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','')}">
|
||||
<tip>可为空,为空则不带前缀</tip>
|
||||
<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('DB_PREFIX','')}">
|
||||
<tip>可为空,为空则不带前缀</tip>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">数据库表名字</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="tb_name" class="layui-input" lay-verify="required" placeholder="请输入:例如 test_goods" value="">
|
||||
<tip>数据库表名字 不包含数据库表前缀。</tip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hr-line"></div>
|
||||
<div class="layui-form-item text-center">
|
||||
<button type="button" class="layui-btn layui-btn-normal layui-btn-sm" lay-filter="search" lay-submit="system.CurdGenerate/save?type=search" data-refresh="false">查询</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tableShow layui-hide">
|
||||
<blockquote class="layui-elem-quote layui-quote-nm">
|
||||
数据表:<span class="table-text"></span>
|
||||
</blockquote>
|
||||
<div class="layui-card-body">
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置忽略字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="ignore"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置下拉字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="select"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置单选字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="radio"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置多选字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="checkbox"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置单选图片字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="image"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置多选图片字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="images"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置日期(Y-m-d)字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="date"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置日期时间(Y-m-d H:i:s)字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="datetime"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置编辑器字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="editor"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="layui-btn-container">
|
||||
<form class="layui-form layuimini-form">
|
||||
<button type="button" class="layui-btn layui-bg-cyan" lay-filter="add" lay-submit="system.CurdGenerate/save?type=add">自动生成CURD</button>
|
||||
<button type="button" class="layui-btn layui-bg-red" lay-filter="delete" lay-submit="system.CurdGenerate/save?type=delete">删除CURD对应的文件</button>
|
||||
</form>
|
||||
<div class="file-list layui-elem-quote">还未生成任何文件</div>
|
||||
</div>
|
||||
<table id="currentTable" class="layui-table" lay-filter="currentTable"></table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">数据库表名字</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="tb_name" class="layui-input" lay-verify="required" placeholder="请输入:例如 test_goods" value="">
|
||||
<tip>数据库表名字 不包含数据库表前缀。</tip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hr-line"></div>
|
||||
<div class="layui-form-item text-center">
|
||||
<button type="button" class="layui-btn layui-btn-normal layui-btn-sm" lay-filter="search" lay-submit="system.CurdGenerate/save?type=search" data-refresh="false">查询</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tableShow layui-hide">
|
||||
<blockquote class="layui-elem-quote layui-quote-nm">
|
||||
数据表:<span class="table-text"></span>
|
||||
</blockquote>
|
||||
<div class="layui-btn-container">
|
||||
<form class="layui-form layuimini-form">
|
||||
<button type="button" class="layui-btn layui-bg-cyan" lay-filter="add" lay-submit="system.CurdGenerate/save?type=add">自动生成CURD</button>
|
||||
<button type="button" class="layui-btn layui-bg-red" lay-filter="delete" lay-submit="system.CurdGenerate/save?type=delete">删除CURD对应的文件</button>
|
||||
</form>
|
||||
<div class="file-list layui-elem-quote">还未生成任何文件</div>
|
||||
<div class="layui-tab-item"></div>
|
||||
</div>
|
||||
<table id="currentTable" class="layui-table" lay-filter="currentTable"></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,6 +1,7 @@
|
||||
<div class="layuimini-container">
|
||||
<div class="layuimini-main">
|
||||
<table id="currentTable" class="layui-table layui-hide"
|
||||
data-auth-record="{:auth('system.log/record')}"
|
||||
lay-filter="currentTable">
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">菜单排序</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="sort" lay-reqtext="菜单排序不能为空" placeholder="请输入菜单排序" value="0" class="layui-input">
|
||||
<input type="number" name="sort" lay-reqtext="菜单排序不能为空" placeholder="请输入菜单排序" value="0" class="layui-input" lay-affix="number">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">菜单排序</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="sort" lay-reqtext="菜单排序不能为空" placeholder="请输入菜单排序" value="{$row.sort|default=''}" class="layui-input">
|
||||
<input type="number" name="sort" lay-reqtext="菜单排序不能为空" placeholder="请输入菜单排序" value="{$row.sort|default=''}" class="layui-input" lay-affix="number">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">菜单排序</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="sort" lay-reqtext="菜单排序不能为空" placeholder="请输入菜单排序" value="0" class="layui-input">
|
||||
<input type="number" name="sort" lay-reqtext="菜单排序不能为空" placeholder="请输入菜单排序" value="0" class="layui-input" lay-affix="number">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">菜单排序</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="sort" lay-reqtext="菜单排序不能为空" placeholder="请输入菜单排序" value="{$row.sort|default=''}" class="layui-input">
|
||||
<input type="number" name="sort" lay-reqtext="菜单排序不能为空" placeholder="请输入菜单排序" value="{$row.sort|default=''}" class="layui-input" lay-affix="number">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -9,6 +9,5 @@
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
let upload_types = '{$upload_types|json_encode|raw}'
|
||||
upload_types = JSON.parse(upload_types)
|
||||
let upload_types = JSON.parse('{$upload_types|json_encode=256|raw}')
|
||||
</script>
|
||||
@@ -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,8 +17,9 @@ 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
|
||||
{
|
||||
if (filter_var($url, FILTER_VALIDATE_URL)) return $url;
|
||||
return url($url, $vars, $suffix, $domain)->build();
|
||||
}
|
||||
}
|
||||
@@ -24,11 +28,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 +39,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 +74,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,30 +91,30 @@ 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $detail
|
||||
* @param string|null $detail
|
||||
* @param string $name
|
||||
* @param string $placeholder
|
||||
* @return string
|
||||
*/
|
||||
function editor_textarea(string $detail, string $name = 'desc', string $placeholder = '请输入'): string
|
||||
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>",
|
||||
'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>",
|
||||
'ueditor' => "<script type='text/plain' id='{$name}' name='{$name}' class='editor' data-content='{$detail}'></script>",
|
||||
'EasyMDE' => "<textarea id='{$name}' class='editor' name='{$name}'>{$detail}</textarea>",
|
||||
default => "<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>",
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ class Curd extends Command
|
||||
->addOption('filesFieldSuffix', null, Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY, '多文件字段后缀', null)
|
||||
->addOption('dateFieldSuffix', null, Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY, '时间字段后缀', null)
|
||||
->addOption('switchFields', null, Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY, '开关的字段', null)
|
||||
->addOption('selectFileds', null, Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY, '下拉的字段', null)
|
||||
->addOption('selectFields', null, Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY, '下拉的字段', null)
|
||||
->addOption('editorFields', null, Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY, '富文本的字段', null)
|
||||
->addOption('sortFields', null, Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY, '排序的字段', null)
|
||||
->addOption('ignoreFields', null, Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY, '忽略的字段', null)
|
||||
@@ -36,7 +36,7 @@ class Curd extends Command
|
||||
->addOption('foreignKey', null, Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY, '关联外键', null)
|
||||
->addOption('primaryKey', null, Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY, '关联主键', null)
|
||||
->addOption('relationModelFilename', null, Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY, '关联模型文件名', null)
|
||||
->addOption('relationOnlyFileds', null, Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY, '关联模型中只显示的字段', null)
|
||||
->addOption('relationOnlyFields', null, Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY, '关联模型中只显示的字段', null)
|
||||
->addOption('relationBindSelect', null, Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY, '关联模型中的字段用于主表外键的表单下拉选择', null)
|
||||
#
|
||||
->addOption('force', 'f', Option::VALUE_REQUIRED, '强制覆盖模式', 0)
|
||||
@@ -59,7 +59,7 @@ class Curd extends Command
|
||||
$filesFieldSuffix = $input->getOption('filesFieldSuffix');
|
||||
$dateFieldSuffix = $input->getOption('dateFieldSuffix');
|
||||
$switchFields = $input->getOption('switchFields');
|
||||
$selectFileds = $input->getOption('selectFileds');
|
||||
$selectFields = $input->getOption('selectFields');
|
||||
$sortFields = $input->getOption('sortFields');
|
||||
$ignoreFields = $input->getOption('ignoreFields');
|
||||
|
||||
@@ -67,7 +67,7 @@ class Curd extends Command
|
||||
$foreignKey = $input->getOption('foreignKey');
|
||||
$primaryKey = $input->getOption('primaryKey');
|
||||
$relationModelFilename = $input->getOption('relationModelFilename');
|
||||
$relationOnlyFileds = $input->getOption('relationOnlyFileds');
|
||||
$relationOnlyFields = $input->getOption('relationOnlyFields');
|
||||
$relationBindSelect = $input->getOption('relationBindSelect');
|
||||
|
||||
$force = $input->getOption('force');
|
||||
@@ -80,13 +80,16 @@ class Curd extends Command
|
||||
'foreignKey' => $foreignKey[$key] ?? null,
|
||||
'primaryKey' => $primaryKey[$key] ?? null,
|
||||
'modelFilename' => $relationModelFilename[$key] ?? null,
|
||||
'onlyFileds' => isset($relationOnlyFileds[$key]) ? explode(",", $relationOnlyFileds[$key]) : [],
|
||||
'onlyField' => isset($relationOnlyFields[$key]) ? explode(",", $relationOnlyFields[$key]) : [],
|
||||
'relationBindSelect' => $relationBindSelect[$key] ?? null,
|
||||
];
|
||||
}
|
||||
|
||||
if (empty($table)) {
|
||||
CliEcho::error('请设置主表');
|
||||
if (PHP_SAPI == 'cli')
|
||||
CliEcho::error('请设置主表');
|
||||
else
|
||||
$output->writeln('请设置主表');
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -106,12 +109,12 @@ class Curd extends Command
|
||||
!empty($filesFieldSuffix) && $build = $build->setFilesFieldSuffix($filesFieldSuffix);
|
||||
!empty($dateFieldSuffix) && $build = $build->setDateFieldSuffix($dateFieldSuffix);
|
||||
!empty($switchFields) && $build = $build->setSwitchFields($switchFields);
|
||||
!empty($selectFileds) && $build = $build->setSelectFileds($selectFileds);
|
||||
!empty($selectFields) && $build = $build->setselectFields($selectFields);
|
||||
!empty($sortFields) && $build = $build->setSortFields($sortFields);
|
||||
!empty($ignoreFields) && $build = $build->setIgnoreFields($ignoreFields);
|
||||
|
||||
foreach ($relations as $relation) {
|
||||
$build = $build->setRelation($relation['table'], $relation['foreignKey'], $relation['primaryKey'], $relation['modelFilename'], $relation['onlyFileds'], $relation['relationBindSelect']);
|
||||
$build = $build->setRelation($relation['table'], $relation['foreignKey'], $relation['primaryKey'], $relation['modelFilename'], $relation['onlyField'], $relation['relationBindSelect']);
|
||||
}
|
||||
|
||||
$build = $build->render();
|
||||
@@ -120,41 +123,64 @@ class Curd extends Command
|
||||
if (!$delete) {
|
||||
$result = $build->create();
|
||||
if ($force) {
|
||||
if (PHP_SAPI == 'cli') {
|
||||
$output->info(">>>>>>>>>>>>>>>");
|
||||
foreach ($fileList as $key => $val) {
|
||||
$output->info($key);
|
||||
}
|
||||
$output->info(">>>>>>>>>>>>>>>");
|
||||
$output->info("确定强制生成上方所有文件? 如果文件存在会直接覆盖。 请输入 'yes' 按回车键继续操作: ");
|
||||
$line = fgets(defined('STDIN') ? STDIN : fopen('php://stdin', 'r'));
|
||||
if (trim($line) != 'yes') {
|
||||
throw new Exception("取消文件CURD生成操作");
|
||||
}
|
||||
CliEcho::success('自动生成CURD成功');
|
||||
}else {
|
||||
$output->writeln('自动生成CURD成功');
|
||||
}
|
||||
}
|
||||
}else {
|
||||
if (PHP_SAPI == 'cli') {
|
||||
$output->info(">>>>>>>>>>>>>>>");
|
||||
foreach ($fileList as $key => $val) {
|
||||
$output->info($key);
|
||||
}
|
||||
$output->info(">>>>>>>>>>>>>>>");
|
||||
$output->info("确定强制生成上方所有文件? 如果文件存在会直接覆盖。 请输入 'yes' 按回车键继续操作: ");
|
||||
$output->info("确定删除上方所有文件? 请输入 'yes' 按回车键继续操作: ");
|
||||
$line = fgets(defined('STDIN') ? STDIN : fopen('php://stdin', 'r'));
|
||||
if (trim($line) != 'yes') {
|
||||
throw new Exception("取消文件CURD生成操作");
|
||||
throw new Exception("取消删除文件操作");
|
||||
}
|
||||
$result = $build->delete();
|
||||
CliEcho::success('>>>>>>>>>>>>>>>');
|
||||
CliEcho::success('删除自动生成CURD文件成功');
|
||||
CliEcho::success('>>>>>>>>>>>>>>>');
|
||||
foreach ($result as $vo) {
|
||||
CliEcho::success($vo);
|
||||
}
|
||||
}else {
|
||||
$result = $build->delete();
|
||||
$output->writeln('>>>>>>>>>>>>>>>');
|
||||
$output->writeln('删除自动生成CURD文件成功');
|
||||
$output->writeln('>>>>>>>>>>>>>>>');
|
||||
foreach ($result as $vo) {
|
||||
$output->writeln($vo);
|
||||
}
|
||||
}
|
||||
CliEcho::success('自动生成CURD成功');
|
||||
} else {
|
||||
$output->info(">>>>>>>>>>>>>>>");
|
||||
foreach ($fileList as $key => $val) {
|
||||
$output->info($key);
|
||||
}
|
||||
$output->info(">>>>>>>>>>>>>>>");
|
||||
$output->info("确定删除上方所有文件? 请输入 'yes' 按回车键继续操作: ");
|
||||
$line = fgets(defined('STDIN') ? STDIN : fopen('php://stdin', 'r'));
|
||||
if (trim($line) != 'yes') {
|
||||
throw new Exception("取消删除文件操作");
|
||||
}
|
||||
$result = $build->delete();
|
||||
CliEcho::success('>>>>>>>>>>>>>>>');
|
||||
CliEcho::success('删除自动生成CURD文件成功');
|
||||
}
|
||||
CliEcho::success('>>>>>>>>>>>>>>>');
|
||||
foreach ($result as $vo) {
|
||||
CliEcho::success($vo);
|
||||
if (PHP_SAPI == 'cli') {
|
||||
$output->info(">>>>>>>>>>>>>>>");
|
||||
$output->info('执行成功');
|
||||
}else {
|
||||
$output->writeln('执行成功');
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
CliEcho::error($e->getMessage());
|
||||
return false;
|
||||
}catch (\Exception $e) {
|
||||
if (PHP_SAPI == 'cli')
|
||||
CliEcho::error($e->getMessage());
|
||||
else
|
||||
$output->writeln($e->getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\command;
|
||||
|
||||
use EasyAdmin\console\CliEcho;
|
||||
use EasyAdmin\tool\CommonTool;
|
||||
use EasyAdmin\upload\driver\alioss\Oss;
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\input\Option;
|
||||
use think\console\Output;
|
||||
|
||||
class OssStatic extends Command
|
||||
{
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('OssStatic')
|
||||
->setDescription('将静态资源上传到oss上');
|
||||
}
|
||||
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
$output->writeln("========正在上传静态资源到OSS上:========" . date('Y-m-d H:i:s'));
|
||||
$dir = root_path() . 'public' . DIRECTORY_SEPARATOR . 'static';
|
||||
$list = CommonTool::readDirAllFiles($dir);
|
||||
$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];
|
||||
try {
|
||||
$upload = Oss::instance($uploadConfig)
|
||||
->save($objectName, $filePath);
|
||||
} catch (\Exception $e) {
|
||||
CliEcho::error('文件上传失败:' . $filePath . '。错误信息:' . $e->getMessage());
|
||||
continue;
|
||||
}
|
||||
if ($upload['save'] == true) {
|
||||
CliEcho::success('文件上传成功:' . $filePath . '。上传地址:' . $upload['url']);
|
||||
} else {
|
||||
CliEcho::error('文件上传失败:' . $filePath . '。错误信息:' . $upload['msg']);
|
||||
}
|
||||
}
|
||||
$output->writeln("========已完成静态资源上传到OSS上:========" . date('Y-m-d H:i:s'));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* 当前模型
|
||||
@@ -51,6 +44,12 @@ class AdminController extends BaseController
|
||||
'title',
|
||||
];
|
||||
|
||||
/**
|
||||
* 过滤节点更新
|
||||
* @var array
|
||||
*/
|
||||
protected array $ignoreNode = [];
|
||||
|
||||
/**
|
||||
* 不导出的字段信息
|
||||
* @var array
|
||||
@@ -81,39 +80,63 @@ 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->setOrder();
|
||||
$this->viewInit();
|
||||
$this->checkAuth();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化排序
|
||||
* @return $this
|
||||
*/
|
||||
public function setOrder(): static
|
||||
{
|
||||
$tableOrder = $this->request->param('tableOrder/s', '');
|
||||
if (!empty($tableOrder)) {
|
||||
[$orderField, $orderType] = explode(' ', $tableOrder);
|
||||
$this->sort = [$orderField => $orderType];
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 模板变量赋值
|
||||
* @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);
|
||||
if (empty($template)) {
|
||||
$template = strtolower(str_replace('.', '/', $this->request->pathinfo()));
|
||||
}
|
||||
return View::fetch($template);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -158,7 +181,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}";
|
||||
}
|
||||
@@ -176,6 +199,9 @@ class AdminController extends BaseController
|
||||
case '%*':
|
||||
$where[] = [$key, 'LIKE', "%{$val}"];
|
||||
break;
|
||||
case 'in':
|
||||
$where[] = [$key, 'IN', $val];
|
||||
break;
|
||||
case 'range':
|
||||
[$beginTime, $endTime] = explode(' - ', $val);
|
||||
$where[] = [$key, '>=', strtotime($beginTime)];
|
||||
@@ -185,7 +211,7 @@ class AdminController extends BaseController
|
||||
$where[] = [$key, $op, "%{$val}"];
|
||||
}
|
||||
}
|
||||
return [$page, $limit, $where, $excludes];
|
||||
return [(int)$page, (int)$limit, $where, $excludes];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -195,17 +221,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 +238,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 +251,17 @@ 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') ?: 'wangEditor',
|
||||
'iframeOpenTop' => sysConfig('site', 'iframe_open_top') ?: 0,
|
||||
];
|
||||
|
||||
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("当前请求不合法!");
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user