Compare commits
104 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4506219fb2 | ||
![]() |
91a1d253c5 | ||
![]() |
3d58942844 | ||
![]() |
e0b2aafd2c | ||
![]() |
7278be4e49 | ||
![]() |
a62020650c | ||
![]() |
9baadccfbb | ||
![]() |
538006c3c6 | ||
![]() |
e2399b6aa6 | ||
![]() |
c5aee52667 | ||
![]() |
8991315888 | ||
![]() |
9754a23360 | ||
![]() |
753f6b9dcf | ||
![]() |
bcb96cd3c4 | ||
![]() |
3908c26e2c | ||
![]() |
f17570deef | ||
![]() |
390fc8ccd5 | ||
![]() |
4d9f57a8c7 | ||
![]() |
b8e08eac96 | ||
![]() |
bece4dac86 | ||
![]() |
4b8d5aa507 | ||
![]() |
5ec24ae9c9 | ||
![]() |
25c5faf440 | ||
![]() |
097b0e1ee5 | ||
![]() |
09b20c255b | ||
![]() |
a3db671328 | ||
![]() |
33177f26cb | ||
![]() |
45712076d2 | ||
![]() |
5979088144 | ||
![]() |
42e6cd36aa | ||
![]() |
08b3e472a9 | ||
![]() |
42b99dd64c | ||
![]() |
e412fd3b60 | ||
![]() |
4f0c37d281 | ||
![]() |
bae186d82a | ||
![]() |
5223997031 | ||
![]() |
5fa20a4f28 | ||
![]() |
0cd799dce3 | ||
![]() |
72a878ed30 | ||
![]() |
5f65e3d25f | ||
![]() |
66ec4f174d | ||
![]() |
64ab5439a6 | ||
![]() |
0558764093 | ||
![]() |
4216a48907 | ||
![]() |
8b65690450 | ||
![]() |
4f461bb673 | ||
![]() |
e30de13d35 | ||
![]() |
c72943da58 | ||
![]() |
a98fbdc7a1 | ||
![]() |
42ffcb75c7 | ||
![]() |
c74c3c23d4 | ||
![]() |
5211d29c5e | ||
![]() |
82dc1ebd05 | ||
![]() |
e35532850d | ||
![]() |
0da4627217 | ||
![]() |
5fd218d26a | ||
![]() |
ee624300b6 | ||
![]() |
dc4855f5c1 | ||
![]() |
9e13a9c937 | ||
![]() |
90990f8782 | ||
![]() |
40276babfb | ||
![]() |
818ffb2ce6 | ||
![]() |
763a05fa80 | ||
![]() |
8c153cce60 | ||
![]() |
93b6f1e2f1 | ||
![]() |
61b9a07d99 | ||
![]() |
d75c455bdc | ||
![]() |
04e2b1ffe5 | ||
![]() |
14b5b3ce3a | ||
![]() |
a4e84ffa75 | ||
![]() |
bd7f62b9ed | ||
![]() |
3a2689db18 | ||
![]() |
3fb55deaaf | ||
![]() |
b07defb0e9 | ||
![]() |
377b72ae19 | ||
![]() |
dd023caf36 | ||
![]() |
163d1c4bee | ||
![]() |
2c2b7f8723 | ||
![]() |
d533aeaa9e | ||
![]() |
a6cebc3750 | ||
![]() |
214ca68b44 | ||
![]() |
e712f824f5 | ||
![]() |
f301f149fb | ||
![]() |
96751d6974 | ||
![]() |
da9aa45036 | ||
![]() |
9ec1285cb9 | ||
![]() |
3947ba7386 | ||
![]() |
d0a9a41c68 | ||
![]() |
7fbee46c73 | ||
![]() |
c8a7d0291c | ||
![]() |
d0044ee019 | ||
![]() |
3466c8ec1f | ||
![]() |
b3be31750a | ||
![]() |
ca7a3df823 | ||
![]() |
9a5e7010b1 | ||
![]() |
2e67214032 | ||
![]() |
c5fb6f9409 | ||
![]() |
8f73948223 | ||
![]() |
2941eeac1e | ||
![]() |
e0007d4150 | ||
![]() |
0e3656c7cc | ||
![]() |
44ed0b9788 | ||
![]() |
1d660ba648 | ||
![]() |
202f7f1dea |
77
README.md
77
README.md
@@ -4,7 +4,10 @@
|
||||
|
||||
|
||||
<p align="center"><code>CatchAdmin</code>是一款基于<a href="http://www.thinkphp.cn/" target="_blank">thinkphp framework</a>和
|
||||
<a href="https://pro.loacg.com/docs/getting-started">ant degisn pro vue</a>二次开发而成的后台管理系统,采用了目前趋势的前后端分离开发模式,后端仅需要提供简洁的 API 数据结构,前端负责呈现数据。目前前端采用数据驱动,大大提高了开发效率。这不仅仅是一个项目,更是后端更新技术栈的一次实践</p>
|
||||
<a href="https://github.com/PanJiaChen/vue-element-admin/">element admin</a>二次开发而成后台管理系统。因为 thinkphp 的简单高效,文档齐全。在看了很多 thinkphp 生态中的后台管理系统,发现没有一款合适的前后端分离系统。遂开发了 CatchAdmin。
|
||||
完全利用了 thinkphp6 的新版本特性 ServiceProvider,将管理系统模块之间的耦合降到了最低限度。每个模块之间都有独立的 controller,路由,模型,数据表`。在开发上尽可能将模块之间的影响降到最低,降低了开发上的难度。基于 CatchAdmin 可以开发 cms,CRM,OA 等
|
||||
等系统。也封装了很多实用的工具,提升开发体验。
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="http://doc.catchadmin.com/">文档</a> |
|
||||
@@ -28,18 +31,62 @@
|
||||
<img src="https://svg.hamm.cn/badge.svg?key=License&value=Apache-2.0"/>
|
||||
</p >
|
||||
|
||||
## AntDV 版本
|
||||
- 请使用 `v1`分支
|
||||
|
||||
## 功能
|
||||
- [x] `用户管理` 后台用户管理
|
||||
- [x] `部门管理` 配置公司的部门结构,支持树形结构
|
||||
- [x] `岗位管理` 配置后台用户的职务
|
||||
- [x] `菜单管理` 配置系统菜单,按钮等等
|
||||
- [x] `角色管理` 配置用户担当的角色,分配权限
|
||||
- [x] `数据字典` 管理后台表结构
|
||||
- [x] `操作日志` 后台用户操作记录
|
||||
- [x] `登录日志` 后台系统用户的登录记录
|
||||
- [x] `代码生成` 生成 API 端的 CURD 操作
|
||||
- [x] `敏感词` 支持敏感词配置
|
||||
- [x] `附件管理` 可管理上传的文件
|
||||
- [x] `定时任务` 可管理定时任务,而不依赖于 Crontab
|
||||
- [x] `短信平台` 短信云管理,支持 阿里大于,腾讯云,Ucloud,Submail
|
||||
- [x] `云上传` 支持云上传,七牛,OSS,腾讯
|
||||
- [ ] `微信管理`
|
||||
|
||||
## 项目地址
|
||||
- [github 地址](https://github.com/yanwenwu/catch-admin)
|
||||
- [gitee 地址](https://gitee.com/jaguarjack/catchAdmin)
|
||||
- [前端 Vue 项目地址](https://github.com/yanwenwu/catch-admin-vue)
|
||||
- [文档地址](https://github.com/catch-admin/document)[个人精力实在有限,希望可以小伙伴们可以一起维护文档]
|
||||
## 预览
|
||||
<p align="center">
|
||||
<img src="https://cdn.learnku.com/uploads/images/202005/17/18206/0ECPy72zUZ.png!large">
|
||||
</p>
|
||||
<p align="center">
|
||||
<img src="https://cdn.learnku.com/uploads/images/202005/17/18206/ngzSU0A9SI.png!large">
|
||||
</p>
|
||||
<table>
|
||||
<tr>
|
||||
<td><img src="https://s1.ax1x.com/2020/09/07/wucNXq.md.png"></td>
|
||||
<td><img src="https://s1.ax1x.com/2020/09/07/wucm6I.md.png"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://s1.ax1x.com/2020/09/07/wucZpd.md.png"></td>
|
||||
<td><img src="https://s1.ax1x.com/2020/09/07/wuce1A.md.png"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://s1.ax1x.com/2020/09/07/wucnXt.md.png"></td>
|
||||
<td><img src="https://s1.ax1x.com/2020/09/07/wucKnP.md.png"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://s1.ax1x.com/2020/09/07/wuc3tg.md.png"></td>
|
||||
<td><img src="https://s1.ax1x.com/2020/09/07/wucM0f.md.png"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://s1.ax1x.com/2020/09/07/wucQ78.md.png"></td>
|
||||
<td><img src="https://s1.ax1x.com/2020/09/07/wuc1AS.md.png"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://s1.ax1x.com/2020/09/07/wuc8hQ.md.png"></td>
|
||||
<td><img src="https://s1.ax1x.com/2020/09/07/wucY1s.md.png"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://s1.ax1x.com/2020/09/07/wucJpj.md.png"></td>
|
||||
<td><img src="https://s1.ax1x.com/2020/09/07/wuctcn.md.png"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## 环境要求
|
||||
- php7.1+ (需以下扩展)
|
||||
@@ -63,8 +110,7 @@ curl -sS https://install.phpcomposer.com/installer | php
|
||||
|
||||
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
|
||||
|
||||
composer install
|
||||
|
||||
composer install --ignore-platform-reqs
|
||||
```
|
||||
- composer 安装
|
||||
```shell
|
||||
@@ -80,8 +126,8 @@ composer create-project jaguarjack/catchadmin:dev-master
|
||||
## 体验地址
|
||||
|
||||
[体验地址](http://vue.catchadmin.com)
|
||||
- 账号: admin@gmail.com
|
||||
- 密码: admin
|
||||
- 账号: catch@admin.com
|
||||
- 密码: catchadmin
|
||||
|
||||
[catchadmin 文档地址](http://doc.catchadmin.com)
|
||||
|
||||
@@ -100,19 +146,14 @@ composer create-project jaguarjack/catchadmin:dev-master
|
||||
### Talking
|
||||
- [论坛讨论](http://bbs.catchadmin.com)
|
||||
- 可以提 `ISSUE`,请按照 `issue` 模板提问
|
||||
- 加入 Q 群 `302266230` 讨论以及反馈一些问题。
|
||||
- 加群需要付费,所以请使用能支持群费的客户端。(不喜勿喷,过滤一部分不看文档和 TP 框架文档并且衣来伸手饭来张口的用户)
|
||||
- 不建议你付费入群,认真阅读文档可以解决所有问题
|
||||
- 更愿意以 `ISSUE` 的方式提问
|
||||
- 付费入群,群里的各位也是没有义务回答各种各样的基础问题。请 GOOGLE。
|
||||
- 加入 Q 群 `302266230` 暗号 `catchadmin`。
|
||||
|
||||
### Thanks
|
||||
> 排名部分先后
|
||||
|
||||
- [top-think/think](https://github.com/top-think/think)
|
||||
- [ant-design-pro-vue](https://github.com/sendya/ant-design-pro-vue)
|
||||
- [element-admin](https://panjiachen.gitee.io/vue-element-admin-site/zh/)
|
||||
- [thans/tp-jwt-auth](https://packagist.org/packages/thans/tp-jwt-auth)
|
||||
- [workerman/workerman](https://github.com/walkor/Workerman)
|
||||
- [jaguarjack/think-filesystem-cloud](https://github.com/yanwenwu/think-filesystem-cloud)
|
||||
- [overtrue/wechat](https://github.com/overtrue/wechat)
|
||||
- [jaguarjack/migration-generator](https://github.com/yanwenwu/migration-generator)
|
||||
|
@@ -33,7 +33,7 @@ class Request extends \think\Request
|
||||
$user = $this->auth->guard($guard ? : config('catch.auth.default.guard'))->user();
|
||||
|
||||
if ($user->status == Users::DISABLE) {
|
||||
throw new LoginFailedException('该用户已被禁用');
|
||||
throw new LoginFailedException('该用户已被禁用', Code::USER_FORBIDDEN);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
if ($e instanceof TokenExpiredException) {
|
||||
@@ -45,7 +45,7 @@ class Request extends \think\Request
|
||||
if ($e instanceof TokenInvalidException) {
|
||||
throw new FailedException('token 不合法', Code::LOST_LOGIN);
|
||||
}
|
||||
throw new FailedException('认证失败: '. $e->getMessage(), Code::LOST_LOGIN);
|
||||
throw new FailedException('认证失败: '. $e->getMessage(), $e->getCode());
|
||||
}
|
||||
|
||||
return $user;
|
||||
|
BIN
catch/.DS_Store
vendored
Normal file
BIN
catch/.DS_Store
vendored
Normal file
Binary file not shown.
53
catch/domain/DomainService.php
Normal file
53
catch/domain/DomainService.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~{$year} http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace catchAdmin\domain;
|
||||
|
||||
use catchAdmin\domain\support\contract\DomainActionInterface;
|
||||
use catchAdmin\domain\support\contract\DomainRecordInterface;
|
||||
use catchAdmin\domain\support\driver\aliyun\Domain;
|
||||
use catchAdmin\domain\support\driver\aliyun\DomainRecord;
|
||||
use catcher\ModuleService;
|
||||
|
||||
class DomainService extends ModuleService
|
||||
{
|
||||
public function register()
|
||||
{
|
||||
parent::register(); // TODO: Change the autogenerated stub
|
||||
|
||||
$this->registerInstance();
|
||||
}
|
||||
|
||||
public function loadConfig()
|
||||
{
|
||||
return require __DIR__ . DIRECTORY_SEPARATOR . 'config.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function loadRouteFrom()
|
||||
{
|
||||
// TODO: Implement loadRouteFrom() method.
|
||||
return __DIR__ . DIRECTORY_SEPARATOR . 'route.php';
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function registerInstance()
|
||||
{
|
||||
$default = config('catch.domains.default');
|
||||
|
||||
$this->app->instance(DomainActionInterface::class, $this->app->make(__NAMESPACE__ . '\\support\\driver\\' . $default . '\Domain'));
|
||||
$this->app->instance(DomainRecordInterface::class, $this->app->make(__NAMESPACE__ . '\\support\\driver\\' . $default . '\DomainRecord'));
|
||||
}
|
||||
}
|
46
catch/domain/README.md
Normal file
46
catch/domain/README.md
Normal file
@@ -0,0 +1,46 @@
|
||||
## 域名管理
|
||||
- 阿里云(主支持)
|
||||
- 腾讯云(需要做适配)
|
||||
|
||||
#### 配置
|
||||
首先在 .env 文件设置
|
||||
```
|
||||
[ALIYUN]
|
||||
ACCESS_KEY=
|
||||
ACCESS_SECRET=
|
||||
|
||||
[QCLOUD]
|
||||
ACCESS_KEY=
|
||||
ACCESS_SECRET=
|
||||
```
|
||||
也可以在 config.php 文件配置
|
||||
```
|
||||
'domains' => [
|
||||
// 默认阿里云
|
||||
'default' => 'aliyun',
|
||||
|
||||
/**
|
||||
* 阿里云配置
|
||||
*
|
||||
*/
|
||||
'aliyun' => [
|
||||
'api_domain' => 'http://alidns.aliyuncs.com',
|
||||
|
||||
'access_key' => Env::get('aliyun.access_key', ''),
|
||||
|
||||
'access_secret' => Env::get('aliyun.access_secret', ''),
|
||||
],
|
||||
|
||||
/**
|
||||
* 腾讯云配置
|
||||
*
|
||||
*/
|
||||
'qcloud' => [
|
||||
'api_domain' => 'cns.api.qcloud.com',
|
||||
|
||||
'access_key' => Env::get('qcloud.access_key', ''),
|
||||
|
||||
'access_secret' => Env::get('qcloud.access_secret', ''),
|
||||
]
|
||||
]
|
||||
```
|
43
catch/domain/config.php
Normal file
43
catch/domain/config.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
use think\facade\Env;
|
||||
|
||||
return [
|
||||
'domains' => [
|
||||
// 默认阿里云
|
||||
'default' => 'aliyun',
|
||||
|
||||
/**
|
||||
* 阿里云配置
|
||||
*
|
||||
*/
|
||||
'aliyun' => [
|
||||
'api_domain' => 'http://alidns.aliyuncs.com',
|
||||
|
||||
'access_key' => Env::get('aliyun.access_key', ''),
|
||||
|
||||
'access_secret' => Env::get('aliyun.access_secret', ''),
|
||||
],
|
||||
|
||||
/**
|
||||
* 腾讯云配置
|
||||
*
|
||||
*/
|
||||
'qcloud' => [
|
||||
'api_domain' => 'cns.api.qcloud.com',
|
||||
|
||||
'access_key' => Env::get('qcloud.access_key', ''),
|
||||
|
||||
'access_secret' => Env::get('qcloud.access_secret', ''),
|
||||
]
|
||||
]
|
||||
];
|
50
catch/domain/controller/Domain.php
Normal file
50
catch/domain/controller/Domain.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
namespace catchAdmin\domain\controller;
|
||||
|
||||
use catchAdmin\domain\support\contract\DomainActionInterface;
|
||||
use catcher\base\CatchRequest as Request;
|
||||
use catcher\CatchResponse;
|
||||
use catcher\base\CatchController;
|
||||
|
||||
class Domain extends CatchController
|
||||
{
|
||||
protected $domain;
|
||||
|
||||
public function __construct(DomainActionInterface $domain)
|
||||
{
|
||||
$this->domain = $domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*
|
||||
* @time 2020/09/11 18:14
|
||||
* @param Request $request
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function index(Request $request): \think\Response
|
||||
{
|
||||
return CatchResponse::paginate($this->domain->getList($request->param()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取
|
||||
*
|
||||
* @time 2020/09/11 18:14
|
||||
* @param $name
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function read($name)
|
||||
{
|
||||
return CatchResponse::success($this->domain->read(str_replace('-', '.', $name)));
|
||||
}
|
||||
}
|
99
catch/domain/controller/DomainRecord.php
Normal file
99
catch/domain/controller/DomainRecord.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
namespace catchAdmin\domain\controller;
|
||||
|
||||
use catchAdmin\domain\support\contract\DomainRecordInterface;
|
||||
use catcher\base\CatchRequest as Request;
|
||||
use catcher\CatchResponse;
|
||||
use catcher\base\CatchController;
|
||||
|
||||
class DomainRecord extends CatchController
|
||||
{
|
||||
protected $domainRecord;
|
||||
|
||||
public function __construct(DomainRecordInterface $record)
|
||||
{
|
||||
$this->domainRecord = $record;
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*
|
||||
* @time 2020/09/11 18:14
|
||||
* @param Request $request
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function index(Request $request): \think\Response
|
||||
{
|
||||
return CatchResponse::paginate($this->domainRecord->getList($request->param()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*
|
||||
* @time 2020/09/11 18:14
|
||||
* @param Request Request
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function save(Request $request): \think\Response
|
||||
{
|
||||
return CatchResponse::success($this->domainRecord->store($request->post()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取
|
||||
*
|
||||
* @time 2020/09/11 18:14
|
||||
* @param $name
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function read($name): \think\Response
|
||||
{
|
||||
return CatchResponse::success($this->domainRecord->read($name));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新
|
||||
*
|
||||
* @time 2020/09/11 18:14
|
||||
* @param Request $request
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function update($id, Request $request): \think\Response
|
||||
{
|
||||
return CatchResponse::success($this->domainRecord->update($id, $request->post()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @time 2020/09/11 18:14
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function delete($id): \think\Response
|
||||
{
|
||||
return CatchResponse::success($this->domainRecord->delete($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置状态
|
||||
*
|
||||
* @param $id
|
||||
* @param $status
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function enable($id, $status)
|
||||
{
|
||||
return CatchResponse::success($this->domainRecord->enable($id, $status));
|
||||
}
|
||||
}
|
97
catch/domain/database/seeds/DomainMenusSeed.php
Normal file
97
catch/domain/database/seeds/DomainMenusSeed.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~{$year} http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
use think\migration\Seeder;
|
||||
|
||||
class DomainMenusSeed extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run Method.
|
||||
*
|
||||
* Write your database seeder using this method.
|
||||
*
|
||||
* More information on writing seeders is available here:
|
||||
* http://docs.phinx.org/en/latest/seeding.html
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
\catcher\Utils::importTreeData($this->getPermissions(), 'permissions', 'parent_id');
|
||||
}
|
||||
|
||||
protected function getPermissions()
|
||||
{
|
||||
return array (
|
||||
0 =>
|
||||
array (
|
||||
'id' => 72,
|
||||
'permission_name' => '域名管理',
|
||||
'parent_id' => 0,
|
||||
'level' => '',
|
||||
'route' => '/domain',
|
||||
'icon' => 'el-icon-stopwatch',
|
||||
'module' => 'domain',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'domain',
|
||||
'component' => 'layout',
|
||||
'redirect' => '/domain/index',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1601105834,
|
||||
'updated_at' => 1601105834,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
'id' => 73,
|
||||
'permission_name' => '域名设置',
|
||||
'parent_id' => 72,
|
||||
'level' => '72',
|
||||
'route' => '/domain/index',
|
||||
'icon' => 'el-icon-setting',
|
||||
'module' => 'domain',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'domain',
|
||||
'component' => 'domain',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 8,
|
||||
'created_at' => 1601105879,
|
||||
'updated_at' => 1601112604,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
'id' => 84,
|
||||
'permission_name' => '域名记录',
|
||||
'parent_id' => 72,
|
||||
'level' => '72',
|
||||
'route' => '/domain/record/:domain',
|
||||
'icon' => 'el-icon-document',
|
||||
'module' => 'domain',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'domainRecord',
|
||||
'component' => 'domainRecord',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 2,
|
||||
'sort' => 1,
|
||||
'created_at' => 1601112569,
|
||||
'updated_at' => 1601112606,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
15
catch/domain/module.json
Normal file
15
catch/domain/module.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "域名管理",
|
||||
"alias": "domain",
|
||||
"description": "域名,阿里云,腾讯云",
|
||||
"version": "1.0.0",
|
||||
"keywords": [],
|
||||
"order": 0,
|
||||
"services": [
|
||||
"\\catchAdmin\\domain\\DomainService"
|
||||
],
|
||||
"aliases": {},
|
||||
"files": [],
|
||||
"requires": [],
|
||||
"enable": false
|
||||
}
|
23
catch/domain/route.php
Normal file
23
catch/domain/route.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~{$year} http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
// you should use `$router`
|
||||
use catchAdmin\domain\controller\DomainRecord;
|
||||
|
||||
$router->group(function () use ($router){
|
||||
// 域名管理
|
||||
$router->get('domain', '\catchAdmin\domain\controller\Domain@index');
|
||||
$router->get('domain/<name>', '\catchAdmin\domain\controller\Domain@read');
|
||||
// 域名解析管理
|
||||
$router->resource('record/domain', DomainRecord::class);
|
||||
$router->put('record/domain/<id>/<status>', '\catchAdmin\domain\controller\DomainRecord@enable');
|
||||
})->middleware('auth');
|
||||
|
70
catch/domain/support/CommonParams.php
Normal file
70
catch/domain/support/CommonParams.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
namespace catchAdmin\domain\support;
|
||||
|
||||
use catchAdmin\domain\support\signature\Aliyun;
|
||||
use catchAdmin\domain\support\signature\Qcloud;
|
||||
|
||||
/**
|
||||
* 公共参数
|
||||
*
|
||||
* Class CommonParams
|
||||
* @package catchAdmin\domain\support
|
||||
*/
|
||||
class CommonParams
|
||||
{
|
||||
/**
|
||||
* 阿里云公共参数
|
||||
*
|
||||
* @param array $params
|
||||
* @param string $method
|
||||
* @return array
|
||||
*/
|
||||
public static function aliyun(array $params, $method = 'GET')
|
||||
{
|
||||
date_default_timezone_set('UTC');
|
||||
|
||||
$params = array_merge($params, [
|
||||
'Format' => 'json',
|
||||
'Version' => '2015-01-09',
|
||||
'AccessKeyId' => config('catch.domains.aliyun.access_key'),
|
||||
'SignatureMethod' => 'HMAC-SHA1',
|
||||
'Timestamp' => date('Y-m-d\TH:i:s\Z'),
|
||||
'SignatureVersion' => '1.0',
|
||||
'SignatureNonce' => uniqid()
|
||||
]);
|
||||
|
||||
$params['Signature'] = (new Aliyun($params))->signature($method);
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* 腾讯云公共参数
|
||||
*
|
||||
* @param array $params
|
||||
* @param string $method
|
||||
* @return array
|
||||
*/
|
||||
public static function qcloud(array $params, $method = 'GET')
|
||||
{
|
||||
$params = array_merge($params, [
|
||||
'SecretId' => config('catch.domains.qcloud.access_key'),
|
||||
'SignatureMethod' => 'HmacSHA1',
|
||||
'Timestamp' => time(),
|
||||
'Nonce' => uniqid()
|
||||
]);
|
||||
|
||||
$params['Signature'] = (new Qcloud($params))->signature($method);
|
||||
|
||||
return $params;
|
||||
}
|
||||
}
|
112
catch/domain/support/Transformer.php
Normal file
112
catch/domain/support/Transformer.php
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
namespace catchAdmin\domain\support;
|
||||
|
||||
use think\Paginator;
|
||||
|
||||
class Transformer
|
||||
{
|
||||
/**
|
||||
* 分页展示
|
||||
*
|
||||
* @param array $data
|
||||
* @return mixed
|
||||
*/
|
||||
public static function aliyunDomainPaginate(array $data)
|
||||
{
|
||||
$list = [];
|
||||
|
||||
foreach ($data['Domains']['Domain'] as $item) {
|
||||
$list[] = [
|
||||
'name' => $item['DomainName'],
|
||||
'created_at' => date('Y-m-d', $item['CreateTimestamp']/1000),
|
||||
'dns_server' => $item['DnsServers']['DnsServer'],
|
||||
'from' => $item['VersionName'],
|
||||
'free' => $item['VersionCode'] === 'mianfei',
|
||||
'record_count' => $item['RecordCount'],
|
||||
'tags' => $item['Tags']['Tag'],
|
||||
'id' => $item['DomainId']
|
||||
];
|
||||
}
|
||||
|
||||
return Paginator::make($list, $data['PageSize'], $data['PageNumber'], $data['TotalCount']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 腾讯云域名列表
|
||||
*
|
||||
* @param array $data
|
||||
* @param $page
|
||||
* @param $limit
|
||||
* @return Paginator|\think\paginator\driver\Bootstrap
|
||||
*/
|
||||
public static function qcloudDomainPaginate(array $data, $page, $limit)
|
||||
{
|
||||
$info = $data['data']['info'];
|
||||
$domains = $data['data']['domains'];
|
||||
|
||||
$list = [];
|
||||
|
||||
foreach ($domains as $item) {
|
||||
$list[] = [
|
||||
'name' => $item['name'],
|
||||
'created_at' => $item['created_on'],
|
||||
'dns_server' => [],
|
||||
'from' => 'qcloud',
|
||||
'free' => $item['grade'] === 'DP_Free',
|
||||
'record_count' => $item['records'],
|
||||
'tags' => [],
|
||||
'id' => $item['id']
|
||||
];
|
||||
}
|
||||
|
||||
return Paginator::make($list, $limit, $page + 1,$info['domain_total']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 阿里云域名解析
|
||||
*
|
||||
* @param array $data
|
||||
* @return mixed
|
||||
*/
|
||||
public static function aliyunDomainRecordPaginate(array $data)
|
||||
{
|
||||
$list = [];
|
||||
|
||||
foreach ($data['DomainRecords']['Record'] as &$item) {
|
||||
$list[] = array_change_key_case($item);
|
||||
}
|
||||
|
||||
return Paginator::make($list, $data['PageSize'], $data['PageNumber'], $data['TotalCount']);
|
||||
}
|
||||
|
||||
/**
|
||||
* DNS 记录
|
||||
*
|
||||
* @param array $data
|
||||
* @param $page
|
||||
* @param $limit
|
||||
* @return Paginator|\think\paginator\driver\Bootstrap
|
||||
*/
|
||||
public static function qcloudDomainRecordPaginate(array $data, $page, $limit)
|
||||
{
|
||||
$list = [];
|
||||
|
||||
foreach ($data['data']['records'] as &$item) {
|
||||
$item['status'] = $item['status'] === 'enabled' ? 'ENABLE' : 'DISABLE';
|
||||
$item['rr'] = $item['name'];
|
||||
$item['recordid'] = $item['id'];
|
||||
$list[] = array_change_key_case($item);
|
||||
}
|
||||
|
||||
return Paginator::make($list, $limit, $page + 1, $data['data']['info']['record_total']);
|
||||
}
|
||||
}
|
22
catch/domain/support/contract/DomainActionInterface.php
Normal file
22
catch/domain/support/contract/DomainActionInterface.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
namespace catchAdmin\domain\support\contract;
|
||||
|
||||
interface DomainActionInterface
|
||||
{
|
||||
public function getList(array $params);
|
||||
|
||||
public function store(array $params);
|
||||
|
||||
public function delete(array $params);
|
||||
|
||||
public function read($name);
|
||||
}
|
27
catch/domain/support/contract/DomainRecordInterface.php
Normal file
27
catch/domain/support/contract/DomainRecordInterface.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
namespace catchAdmin\domain\support\contract;
|
||||
|
||||
interface DomainRecordInterface
|
||||
{
|
||||
public function getList(array $params);
|
||||
|
||||
public function store(array $params);
|
||||
|
||||
public function delete($recordId);
|
||||
|
||||
public function read(array $params);
|
||||
|
||||
public function update($recordId, array $params);
|
||||
|
||||
public function enable($recordId, $status);
|
||||
|
||||
}
|
32
catch/domain/support/driver/ApiTrait.php
Normal file
32
catch/domain/support/driver/ApiTrait.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
namespace catchAdmin\domain\support\driver;
|
||||
|
||||
use catcher\facade\Http;
|
||||
use catchAdmin\domain\support\CommonParams;
|
||||
|
||||
trait ApiTrait
|
||||
{
|
||||
public function get(array $params)
|
||||
{
|
||||
$name = config('catch.domains.default');
|
||||
|
||||
$apiDomain = config('catch.domains.' . $name . '.api_domain');
|
||||
|
||||
if (strpos($apiDomain, 'https') === false &&
|
||||
strpos($apiDomain, 'http') === false) {
|
||||
$apiDomain = 'https://' . $apiDomain . '/v2/index.php';
|
||||
}
|
||||
|
||||
return Http::ignoreSsl()->query(CommonParams::{$name}($params))
|
||||
->get($apiDomain)->json();
|
||||
}
|
||||
}
|
55
catch/domain/support/driver/aliyun/Domain.php
Normal file
55
catch/domain/support/driver/aliyun/Domain.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
namespace catchAdmin\domain\support\driver\aliyun;
|
||||
|
||||
use catchAdmin\domain\support\contract\DomainActionInterface;
|
||||
use catchAdmin\domain\support\driver\ApiTrait;
|
||||
use catchAdmin\domain\support\Transformer;
|
||||
|
||||
class Domain implements DomainActionInterface
|
||||
{
|
||||
use ApiTrait;
|
||||
|
||||
public function getList(array $params)
|
||||
{
|
||||
// TODO: Implement getList() method.
|
||||
return Transformer::aliyunDomainPaginate($this->get([
|
||||
'Action' => 'DescribeDomains',
|
||||
'StarMark' => true,
|
||||
'SearchModel' => 'LIKE',
|
||||
'PageNumber' => $params['page'] ?? 1,
|
||||
'PageSize' => $params['limit'] ?? 20,
|
||||
]));
|
||||
}
|
||||
|
||||
public function store(array $params)
|
||||
{
|
||||
// TODO: Implement add() method.
|
||||
}
|
||||
|
||||
public function delete(array $params)
|
||||
{
|
||||
// TODO: Implement delete() method.
|
||||
return $this->get([
|
||||
'Action' => 'DeleteDomain',
|
||||
'DomainName' => $params['name'],
|
||||
]);
|
||||
}
|
||||
|
||||
public function read($name)
|
||||
{
|
||||
// TODO: Implement info() method.
|
||||
return $this->get([
|
||||
'Action' => 'DescribeDomainInfo',
|
||||
'DomainName' => $name
|
||||
]);
|
||||
}
|
||||
}
|
147
catch/domain/support/driver/aliyun/DomainRecord.php
Normal file
147
catch/domain/support/driver/aliyun/DomainRecord.php
Normal file
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
namespace catchAdmin\domain\support\driver\aliyun;
|
||||
|
||||
use catchAdmin\domain\support\contract\DomainRecordInterface;
|
||||
use catchAdmin\domain\support\driver\ApiTrait;
|
||||
use catchAdmin\domain\support\Transformer;
|
||||
|
||||
class DomainRecord implements DomainRecordInterface
|
||||
{
|
||||
use ApiTrait;
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*
|
||||
* @param array $params
|
||||
* @return mixed
|
||||
*/
|
||||
public function getList(array $params)
|
||||
{
|
||||
$data = [
|
||||
'Action' => 'DescribeDomainRecords',
|
||||
'DomainName' => $params['name'],
|
||||
'PageNumber' => $params['page'] ?? 1,
|
||||
'PageSize' => $params['limit'] ?? 20,
|
||||
];
|
||||
|
||||
if ($params['rr']) {
|
||||
$data['RRKeyWord'] = $params['rr'];
|
||||
}
|
||||
|
||||
if ($params['type']) {
|
||||
$data['TypeKeyWord'] = $params['type'];
|
||||
}
|
||||
|
||||
if ($params['value']) {
|
||||
$data['ValueKeyWord'] = $params['value'];
|
||||
}
|
||||
|
||||
if ($params['line']) {
|
||||
$data['Line'] = $params['line'];
|
||||
}
|
||||
|
||||
if ($params['status']) {
|
||||
$data['Status'] = $params['status'];
|
||||
}
|
||||
|
||||
// TODO: Implement getList() method.
|
||||
return Transformer::aliyunDomainRecordPaginate($this->get($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增解析
|
||||
*
|
||||
* @param array $params
|
||||
* @return array
|
||||
*
|
||||
*/
|
||||
public function store(array $params)
|
||||
{
|
||||
// TODO: Implement add() method.
|
||||
return $this->get([
|
||||
'Action' => 'AddDomainRecord',
|
||||
'DomainName' => $params['name'],
|
||||
'RR' => $params['rr'],
|
||||
'Type' => $params['type'],
|
||||
'Value' => $params['value'],
|
||||
'Line' => $params['line'],
|
||||
'TTL' => $params['ttl'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除解析
|
||||
*
|
||||
* @param $recordId
|
||||
* @return array
|
||||
*/
|
||||
public function delete($recordId)
|
||||
{
|
||||
// TODO: Implement delete() method.
|
||||
return $this->get([
|
||||
'Action' => 'DeleteDomainRecord',
|
||||
'RecordId' => $recordId
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取解析记录
|
||||
*
|
||||
* @param array $params
|
||||
* @return array
|
||||
*/
|
||||
public function read(array $params)
|
||||
{
|
||||
// TODO: Implement info() method.
|
||||
return $this->get([
|
||||
'Action' => 'DescribeDomainRecord',
|
||||
'RecordId' => $params['record_id'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新解析
|
||||
*
|
||||
* @param array $params
|
||||
* @param $recordId
|
||||
* @return array
|
||||
*/
|
||||
public function update($recordId, array $params)
|
||||
{
|
||||
// TODO: Implement update() method.
|
||||
return $this->get([
|
||||
'Action' => 'UpdateDomainRecord',
|
||||
'RecordId' => $recordId,
|
||||
'RR' => $params['rr'],
|
||||
'Type' => $params['type'],
|
||||
'Value' => $params['value'],
|
||||
'Line' => $params['line'],
|
||||
'TTL' => $params['ttl'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置状态
|
||||
*
|
||||
* @param $recordId
|
||||
* @param $status
|
||||
* @return array
|
||||
*/
|
||||
public function enable($recordId, $status)
|
||||
{
|
||||
return $this->get([
|
||||
'Action' => 'SetDomainRecordStatus',
|
||||
'RecordId' => $recordId,
|
||||
'Status' => ucfirst(strtolower($status))
|
||||
]);
|
||||
}
|
||||
}
|
56
catch/domain/support/driver/qcloud/Domain.php
Normal file
56
catch/domain/support/driver/qcloud/Domain.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
namespace catchAdmin\domain\support\driver\qcloud;
|
||||
|
||||
use catchAdmin\domain\support\contract\DomainActionInterface;
|
||||
use catchAdmin\domain\support\driver\ApiTrait;
|
||||
use catchAdmin\domain\support\Transformer;
|
||||
|
||||
class Domain implements DomainActionInterface
|
||||
{
|
||||
use ApiTrait;
|
||||
|
||||
public function getList(array $params)
|
||||
{
|
||||
$offset = ($params['page'] ?? 1) - 1;
|
||||
$length = $params['limit'] ?? 10;
|
||||
|
||||
// TODO: Implement getList() method.
|
||||
return Transformer::qcloudDomainPaginate($this->get([
|
||||
'Action' => 'DomainList',
|
||||
'offset' => $offset,
|
||||
'length' => $length
|
||||
]), $offset, $length);
|
||||
}
|
||||
|
||||
public function store(array $params)
|
||||
{
|
||||
// TODO: Implement add() method.
|
||||
}
|
||||
|
||||
public function delete(array $params)
|
||||
{
|
||||
// TODO: Implement delete() method.
|
||||
return $this->get([
|
||||
'Action' => 'DeleteDomain',
|
||||
'DomainName' => $params['name'],
|
||||
]);
|
||||
}
|
||||
|
||||
public function read($name)
|
||||
{
|
||||
// TODO: Implement info() method.
|
||||
return $this->get([
|
||||
'Action' => 'DescribeDomainInfo',
|
||||
'DomainName' => $name
|
||||
]);
|
||||
}
|
||||
}
|
125
catch/domain/support/driver/qcloud/DomainRecord.php
Normal file
125
catch/domain/support/driver/qcloud/DomainRecord.php
Normal file
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
namespace catchAdmin\domain\support\driver\qcloud;
|
||||
|
||||
use catchAdmin\domain\support\contract\DomainRecordInterface;
|
||||
use catchAdmin\domain\support\driver\ApiTrait;
|
||||
use catchAdmin\domain\support\Transformer;
|
||||
|
||||
class DomainRecord implements DomainRecordInterface
|
||||
{
|
||||
use ApiTrait;
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*
|
||||
* @param array $params
|
||||
* @return mixed
|
||||
*/
|
||||
public function getList(array $params)
|
||||
{
|
||||
$data = [
|
||||
'Action' => 'RecordList',
|
||||
'domain' => $params['name'],
|
||||
'offset' => ($params['page'] ?? 1) - 1,
|
||||
'length' => $params['limit'] ?? 10,
|
||||
];
|
||||
|
||||
if ($params['rr']) {
|
||||
$data['subDomain'] = $params['rr'];
|
||||
}
|
||||
|
||||
if ($params['type']) {
|
||||
$data['recordType'] = $params['type'];
|
||||
}
|
||||
|
||||
// TODO: Implement getList() method.
|
||||
return Transformer::qcloudDomainRecordPaginate($this->get($data), $data['offset'], $data['length']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增解析
|
||||
*
|
||||
* @param array $params
|
||||
* @return array
|
||||
*
|
||||
*/
|
||||
public function store(array $params)
|
||||
{
|
||||
// TODO: Implement add() method.
|
||||
return $this->get([
|
||||
'Action' => 'RecordCreate',
|
||||
'domain' => $params['name'],
|
||||
'subDomain' => $params['rr'],
|
||||
'recordType' => $params['type'],
|
||||
'value' => $params['value'],
|
||||
'recordLine' => $params['line'],
|
||||
'ttl' => $params['ttl'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除解析
|
||||
*
|
||||
* @param $recordId
|
||||
* @return array
|
||||
*/
|
||||
public function delete($recordId)
|
||||
{
|
||||
// TODO: Implement delete() method.
|
||||
return $this->get([
|
||||
'Action' => 'RecordDelete',
|
||||
'recordId' => $recordId
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新解析
|
||||
*
|
||||
* @param array $params
|
||||
* @param $recordId
|
||||
* @return array
|
||||
*/
|
||||
public function update($recordId, array $params)
|
||||
{
|
||||
// TODO: Implement update() method.
|
||||
return $this->get([
|
||||
'Action' => 'RecordModify',
|
||||
'recordId' => $recordId,
|
||||
'subDomain' => $params['rr'],
|
||||
'recordType' => $params['type'],
|
||||
'value' => $params['value'],
|
||||
'recordLine' => $params['line'],
|
||||
'ttl' => $params['ttl'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置状态
|
||||
*
|
||||
* @param $recordId
|
||||
* @param $status
|
||||
* @return array
|
||||
*/
|
||||
public function enable($recordId, $status)
|
||||
{
|
||||
return $this->get([
|
||||
'Action' => 'RecordStatus',
|
||||
'recordId' => $recordId,
|
||||
'Status' => strtolower($status)
|
||||
]);
|
||||
}
|
||||
|
||||
public function read(array $params)
|
||||
{
|
||||
// TODO: Implement read() method.
|
||||
}
|
||||
}
|
64
catch/domain/support/signature/Aliyun.php
Normal file
64
catch/domain/support/signature/Aliyun.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
namespace catchAdmin\domain\support\signature;
|
||||
|
||||
class Aliyun
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $params;
|
||||
|
||||
/**
|
||||
* Aliyun constructor.
|
||||
* @param $params
|
||||
*/
|
||||
public function __construct(array $params)
|
||||
{
|
||||
$this->params = $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* encode
|
||||
*
|
||||
* @time 2020年09月25日
|
||||
* @param $str
|
||||
* @return string|string[]|null
|
||||
*/
|
||||
protected function percentEncode(string $str)
|
||||
{
|
||||
return preg_replace(['/\+/', '/\*/', '/%7E/'], ['%20', '%2A', '~'], urlencode($str));
|
||||
}
|
||||
|
||||
/**
|
||||
* 签名
|
||||
*
|
||||
* @time 2020年09月25日
|
||||
* @param $method
|
||||
* @return string
|
||||
*/
|
||||
public function signature(string $method)
|
||||
{
|
||||
ksort($this->params);
|
||||
|
||||
$queryString = '';
|
||||
|
||||
foreach ($this->params as $key => $param) {
|
||||
$queryString .= '&' . $this->percentEncode($key) . '=' . $this->percentEncode($param);
|
||||
}
|
||||
|
||||
$signString = $method . '&' .
|
||||
$this->percentEncode('/') . '&' .
|
||||
$this->percentEncode(substr($queryString, 1));
|
||||
|
||||
return base64_encode(hash_hmac('sha1', $signString, config('catch.domains.aliyun.access_secret'). '&', true));
|
||||
}
|
||||
}
|
63
catch/domain/support/signature/Qcloud.php
Normal file
63
catch/domain/support/signature/Qcloud.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~{$year} http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
namespace catchAdmin\domain\support\signature;
|
||||
|
||||
class Qcloud
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $params;
|
||||
|
||||
/**
|
||||
* Qcloud constructor.
|
||||
* @param $params
|
||||
*/
|
||||
public function __construct(array $params)
|
||||
{
|
||||
$this->params = $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* key 替换
|
||||
*
|
||||
* @param $key
|
||||
* @return mixed|string|string[]
|
||||
*/
|
||||
protected function replaceKey($key)
|
||||
{
|
||||
return strpos($key, '_') === false ?
|
||||
$key : str_replace('_', '.', $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 签名
|
||||
*
|
||||
* @time 2020年09月25日
|
||||
* @param $method
|
||||
* @return string
|
||||
*/
|
||||
public function signature(string $method)
|
||||
{
|
||||
ksort($this->params);
|
||||
|
||||
$queryString = '';
|
||||
|
||||
foreach ($this->params as $key => $param) {
|
||||
$queryString .= '&' . $this->replaceKey($key) . '=' . $param;
|
||||
}
|
||||
|
||||
$signString = $method . config('catch.domains.qcloud.api_domain') . '/v2/index.php?'
|
||||
. substr($queryString, 1);
|
||||
|
||||
return base64_encode(hash_hmac('sha1', $signString, config('catch.domains.qcloud.access_secret'), true));
|
||||
}
|
||||
}
|
@@ -11,15 +11,13 @@ class LoginLogEvent
|
||||
{
|
||||
$agent = request()->header('user-agent');
|
||||
|
||||
$username = Users::where('email', $params['email'])->value('username');
|
||||
|
||||
app(LoginLog::class)->storeBy([
|
||||
'login_name' => $username ? : $params['email'],
|
||||
'login_name' => $params['login_name'],
|
||||
'login_ip' => request()->ip(),
|
||||
'browser' => $this->getBrowser($agent),
|
||||
'os' => $this->getOs($agent),
|
||||
'login_at' => time(),
|
||||
'status' => $params['success'] ? 1 : 2,
|
||||
'status' => $params['success'],
|
||||
]);
|
||||
}
|
||||
|
||||
|
@@ -6,6 +6,7 @@ use catchAdmin\permissions\model\Users;
|
||||
use catcher\base\CatchController;
|
||||
use catcher\CatchAuth;
|
||||
use catcher\CatchResponse;
|
||||
use catcher\Code;
|
||||
use catcher\exceptions\LoginFailedException;
|
||||
use thans\jwt\facade\JWTAuth;
|
||||
|
||||
@@ -21,31 +22,79 @@ class Index extends CatchController
|
||||
*/
|
||||
public function login(LoginRequest $request, CatchAuth $auth)
|
||||
{
|
||||
$params = $request->param();
|
||||
$condition = $request->param();
|
||||
|
||||
$token = $auth->attempt($params);
|
||||
try {
|
||||
$token = $auth->attempt($condition);
|
||||
|
||||
$user = $auth->user();
|
||||
|
||||
if ($user->status == Users::DISABLE) {
|
||||
throw new LoginFailedException('该用户已被禁用');
|
||||
$this->afterLoginSuccess($user);
|
||||
// 登录事件
|
||||
$this->loginEvent($user->username);
|
||||
|
||||
return CatchResponse::success([
|
||||
'token' => $token,
|
||||
], '登录成功');
|
||||
} catch (\Exception $exception) {
|
||||
$this->detailWithLoginFailed($exception, $condition);
|
||||
$code = $exception->getCode();
|
||||
return CatchResponse::fail($code == Code::USER_FORBIDDEN ?
|
||||
'该账户已被禁用,请联系管理员' : '登录失败,请检查邮箱和密码', Code::LOGIN_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
// 记录用户登录
|
||||
/**
|
||||
* 处理登录失败
|
||||
*
|
||||
* @time 2020年10月26日
|
||||
* @param $exception
|
||||
* @param $condition
|
||||
* @return void
|
||||
*/
|
||||
protected function detailWithLoginFailed($exception, $condition)
|
||||
{
|
||||
$message = $exception->getMessage();
|
||||
|
||||
if (strpos($message, '|') !== false) {
|
||||
$username = explode('|', $message)[1];
|
||||
} else {
|
||||
$username = $condition['email'];
|
||||
}
|
||||
|
||||
$this->loginEvent($username, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户登录成功后
|
||||
*
|
||||
* @time 2020年09月09日
|
||||
* @param $user
|
||||
* @return void
|
||||
*/
|
||||
protected function afterLoginSuccess($user)
|
||||
{
|
||||
$user->last_login_ip = request()->ip();
|
||||
$user->last_login_time = time();
|
||||
$user->save();
|
||||
|
||||
// 登录事件
|
||||
$params['success'] = $token;
|
||||
|
||||
event('loginLog', $params);
|
||||
|
||||
return $token ? CatchResponse::success([
|
||||
'token' => $token,
|
||||
], '登录成功') : CatchResponse::success('', '登录失败');
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录事件
|
||||
*
|
||||
* @time 2020年09月09日
|
||||
* @param $name
|
||||
* @param bool $success
|
||||
* @return void
|
||||
*/
|
||||
protected function loginEvent($name, $success = true)
|
||||
{
|
||||
$params['login_name'] = $name;
|
||||
$params['success'] = $success ? 1 : 2;
|
||||
event('loginLog', $params);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 登出
|
||||
*
|
||||
|
@@ -4,7 +4,7 @@
|
||||
"description": "login 模块",
|
||||
"version": "1.0.0",
|
||||
"keywords": [],
|
||||
"order": 1,
|
||||
"order": 100,
|
||||
"services": [
|
||||
"\\catchAdmin\\login\\LoginService"
|
||||
],
|
||||
|
34
catch/monitor/MonitorService.php
Normal file
34
catch/monitor/MonitorService.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~{$year} http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace catchAdmin\monitor;
|
||||
|
||||
use catcher\ModuleService;
|
||||
|
||||
class MonitorService extends ModuleService
|
||||
{
|
||||
protected function loadConfig()
|
||||
{
|
||||
return require __DIR__ . DIRECTORY_SEPARATOR . 'config.php';
|
||||
}
|
||||
|
||||
public function loadRouteFrom()
|
||||
{
|
||||
// TODO: Implement loadRouteFrom() method.
|
||||
return __DIR__ . DIRECTORY_SEPARATOR . 'route.php';
|
||||
}
|
||||
|
||||
public function loadCommands()
|
||||
{
|
||||
return [__NAMESPACE__, __DIR__ . DIRECTORY_SEPARATOR . 'command'];
|
||||
}
|
||||
|
||||
}
|
175
catch/monitor/command/CatchCrontabCommand.php
Normal file
175
catch/monitor/command/CatchCrontabCommand.php
Normal file
@@ -0,0 +1,175 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~{$year} http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace catchAdmin\monitor\command;
|
||||
|
||||
use catchAdmin\monitor\command\process\Master;
|
||||
use catchAdmin\monitor\command\process\Process;
|
||||
use catcher\facade\FileSystem;
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\input\Argument;
|
||||
use think\console\input\Option;
|
||||
use think\console\Output;
|
||||
use think\console\Table;
|
||||
|
||||
class CatchCrontabCommand extends Command
|
||||
{
|
||||
protected $pid;
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
// 指令配置
|
||||
$this->setName('catch:crontab')
|
||||
->addArgument('action', Argument::OPTIONAL, '[start|reload|stop|restart]', 'start')
|
||||
->addOption('daemon', '-d', Option::VALUE_NONE, 'daemon mode')
|
||||
->addOption('pid', '-p', Option::VALUE_REQUIRED, 'you can send signal to the process of pid')
|
||||
->addOption('static', '-s', Option::VALUE_REQUIRED, 'default static process number', 1)
|
||||
->addOption('dynamic', '-dy', Option::VALUE_REQUIRED, 'default dynamic process number', 10)
|
||||
->addOption('interval', '-i', Option::VALUE_REQUIRED, 'interval/seconds', 60)
|
||||
->setDescription('start catch crontab schedule');
|
||||
}
|
||||
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
if (!$input->hasOption('pid')) {
|
||||
$this->pid = Master::getMasterPid();
|
||||
} else {
|
||||
$this->pid = $input->getOption('pid');
|
||||
}
|
||||
|
||||
if (!extension_loaded('pcntl') || !extension_loaded('posix')) {
|
||||
$output->error('you should install extension [pcntl && posix]');
|
||||
} else {
|
||||
$this->{$input->getArgument('action')}();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 进程启动
|
||||
*
|
||||
* @time 2020年09月14日
|
||||
* @return void
|
||||
*/
|
||||
protected function start()
|
||||
{
|
||||
$worker = new Master();
|
||||
|
||||
$worker->staticNumber($this->input->getOption('static'))
|
||||
->dynamic($this->input->getOption('dynamic'))
|
||||
->interval($this->input->getOption('interval'))
|
||||
->asDaemon($this->input->hasOption('daemon'))
|
||||
->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止任务
|
||||
*
|
||||
* @time 2020年07月07日
|
||||
* @return void
|
||||
*/
|
||||
protected function stop()
|
||||
{
|
||||
$retryTimes = 0;
|
||||
|
||||
if (Process::isAlive($this->pid)) {
|
||||
$this->output->info('🔨 catch crontab is running.');
|
||||
Process::kill($this->pid, SIGTERM);
|
||||
// 睡眠 1 秒
|
||||
$this->output->info('⌛️ killing catch crontab service, please waiting...');
|
||||
sleep(1);
|
||||
if (!Process::isAlive($this->pid)) {
|
||||
$this->output->info('🎉 catch crontab stopped!');
|
||||
} else {
|
||||
while (true) {
|
||||
Process::kill($this->pid, SIGKILL);
|
||||
if (Process::isAlive($this->pid)) {
|
||||
$retryTimes++;
|
||||
$this->output->info('🔥 retry $retryTimes times');
|
||||
usleep(500 * 1000);
|
||||
if ($retryTimes >= 3) {
|
||||
$this->output->info('💔 catch crontab is running, stop failed, please use [kill -9 {$this->pid}] to Stop it');
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$this->output->info('🎉 catch crontab stopped!');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Master::exitMasterDo();
|
||||
} else {
|
||||
$this->output->error('🤔️ catch crontab is not running, Please Check it!');
|
||||
}
|
||||
|
||||
$this->output->info('🎉 stop catch crontab successfully');
|
||||
}
|
||||
|
||||
/**
|
||||
* 重启任务
|
||||
*
|
||||
* @time 2020年07月07日
|
||||
* @return void
|
||||
*/
|
||||
protected function reload()
|
||||
{
|
||||
Process::kill($this->pid, SIGUSR1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重启
|
||||
*
|
||||
* @time 2020年07月07日
|
||||
* @return void
|
||||
*/
|
||||
protected function restart()
|
||||
{
|
||||
$this->stop();
|
||||
|
||||
$this->output->info('catch crontab restarting...');
|
||||
|
||||
usleep(500 * 1000);
|
||||
|
||||
$this->start();
|
||||
}
|
||||
|
||||
/**
|
||||
* status
|
||||
*
|
||||
* @time 2020年07月22日
|
||||
* @return void
|
||||
*/
|
||||
protected function status()
|
||||
{
|
||||
if ($this->pid) {
|
||||
if (Process::isAlive($this->pid)) {
|
||||
Process::kill($this->pid, SIGUSR2);
|
||||
|
||||
usleep(100000);
|
||||
|
||||
$worker = new Master;
|
||||
$table = new Table;
|
||||
|
||||
$table->setHeader(['PID', '名称', '内存', '处理任务', '开始时间', '运行时间', '状态'], Table::ALIGN_CENTER);
|
||||
|
||||
$table->setRows($worker->getWorkerStatus(), Table::ALIGN_CENTER);
|
||||
|
||||
$this->output->info($table->render());
|
||||
} else {
|
||||
$this->output->error('🤔️ catch crontab is not running, Please Check it!');
|
||||
}
|
||||
} else {
|
||||
$this->output->error('🤔️ catch crontab is not running, Please Check it!');
|
||||
}
|
||||
}
|
||||
}
|
145
catch/monitor/command/process/Attributes.php
Normal file
145
catch/monitor/command/process/Attributes.php
Normal file
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~{$year} http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace catchAdmin\monitor\command\process;
|
||||
|
||||
use catcher\base\CatchCronTask;
|
||||
|
||||
trait Attributes
|
||||
{
|
||||
/**
|
||||
* 是否以守护进程方式运行
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $daemon = false;
|
||||
|
||||
/**
|
||||
* 静态进程数量
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $static;
|
||||
|
||||
/**
|
||||
* 动态进程数量
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $dynamic;
|
||||
|
||||
/**
|
||||
* 定时器触发时间
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $interval;
|
||||
|
||||
/**
|
||||
* set name
|
||||
*
|
||||
* @var
|
||||
*/
|
||||
protected $name = 'catch-crontab';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $crontabQueueName = 'catch-crontab-task';
|
||||
|
||||
/**
|
||||
* 安全退出
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $exitSafely = false;
|
||||
|
||||
/**
|
||||
* 设置守护进程
|
||||
*
|
||||
* @time 2020年07月21日
|
||||
* @param bool $daemon
|
||||
* @return $this
|
||||
*/
|
||||
public function asDaemon($daemon = false)
|
||||
{
|
||||
$this->daemon = $daemon;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function staticNumber($n)
|
||||
{
|
||||
$this->static = $n;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 可扩容
|
||||
*
|
||||
* @time 2020年07月21日
|
||||
* @param $n
|
||||
* @return $this
|
||||
*/
|
||||
public function dynamic($n)
|
||||
{
|
||||
$this->dynamic = $n;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 定时
|
||||
*
|
||||
* @time 2020年07月21日
|
||||
* @param $n
|
||||
* @return $this
|
||||
*/
|
||||
public function interval($n)
|
||||
{
|
||||
$this->interval = $n;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置 name
|
||||
*
|
||||
* @time 2020年07月23日
|
||||
* @param $name
|
||||
* @return $this
|
||||
*/
|
||||
public function name($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置报告错误
|
||||
*
|
||||
* @time 2020年07月24日
|
||||
* @return void
|
||||
*/
|
||||
public function displayErrors()
|
||||
{
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
error_reporting(E_ALL & ~E_WARNING);
|
||||
|
||||
ini_set('display_startup_errors', 1);
|
||||
|
||||
ini_set('ignore_repeated_errors', 1);
|
||||
}
|
||||
}
|
361
catch/monitor/command/process/Master.php
Normal file
361
catch/monitor/command/process/Master.php
Normal file
@@ -0,0 +1,361 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~{$year} http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace catchAdmin\monitor\command\process;
|
||||
|
||||
use Exception;
|
||||
use catcher\facade\Filesystem;
|
||||
use think\cache\driver\Redis;
|
||||
use think\facade\Cache;
|
||||
|
||||
/**
|
||||
*
|
||||
* - 以后台形式工作 daemon
|
||||
* - 分静态进程和动态扩容进程
|
||||
* - 信号处理机制
|
||||
* - 重启工作进程
|
||||
* - 重启服务
|
||||
* - 定时器 扩容工作进程
|
||||
* - 关闭进程
|
||||
* - 统计信息
|
||||
* - 是否拉起进程,工作进程销毁后是否继续主进程保留
|
||||
* - Fatal Error 处理
|
||||
* - Exception 处理
|
||||
* - 发生内存泄漏如何处理
|
||||
* - 错误输出到哪里
|
||||
* - 提供基础面板查看
|
||||
* - Log 文件的记录
|
||||
*
|
||||
* @time 2020年07月29日
|
||||
*/
|
||||
class Master
|
||||
{
|
||||
use RegisterSignal, Attributes, Store, ParseTask;
|
||||
|
||||
/**
|
||||
* 保存子进程 PID
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $workerIds = [];
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
*
|
||||
* @var
|
||||
*/
|
||||
public $start_at;
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
public $worker_start_at;
|
||||
|
||||
/**
|
||||
* 保存当前工作进程的数量
|
||||
*
|
||||
* @var
|
||||
*/
|
||||
protected $allWorkersCount;
|
||||
|
||||
/**
|
||||
* 保存当前重定向输出文件
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $stdout;
|
||||
|
||||
/**
|
||||
* 任务对象
|
||||
*
|
||||
* @var
|
||||
*/
|
||||
protected $taskService;
|
||||
|
||||
/**
|
||||
* 处理的任务数量
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $dealNum = 0;
|
||||
|
||||
/**
|
||||
* busy waiting
|
||||
*
|
||||
* @var
|
||||
*/
|
||||
protected $status = 'waiting';
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
protected $redis;
|
||||
|
||||
/**
|
||||
* 启动
|
||||
*
|
||||
* @time 2020年07月21日
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
try {
|
||||
if ($this->daemon) {
|
||||
Process::daemon();
|
||||
}
|
||||
|
||||
if ($this->interval) {
|
||||
Process::alarm($this->interval);
|
||||
}
|
||||
$this->init();
|
||||
// 初始化进程池
|
||||
$this->initWorkers();
|
||||
// 设置进程名称
|
||||
Process::setWorkerName($this->name . ' master');
|
||||
// 注册信号
|
||||
$this->registerSignal();
|
||||
// 写入进程状态
|
||||
$this->setWorkerStatus($this->name . ' master');
|
||||
// 信号发送
|
||||
while (true) {
|
||||
Process::dispatch();
|
||||
$pid = pcntl_waitpid(-1, $status, WNOHANG);
|
||||
Process::dispatch();
|
||||
if ($pid > 0) {
|
||||
if (isset($this->workerIds[$pid])) {
|
||||
unset($this->workerIds[$pid]);
|
||||
$this->deleteWorkerStatusFile($pid);
|
||||
$this->worker_start_at = time();
|
||||
// 如果进程挂掉,正常退出码都是 0,当然这里可以自己定义,看 exit($status) 设置什么
|
||||
// 真实的 exit code pcntl_wexitstatus 函数获取
|
||||
// exit code > 0 都是由于异常导致的
|
||||
$exitCode = pcntl_wexitstatus($status);
|
||||
if (!in_array($exitCode, [255, 250])) {
|
||||
$this->forkStatic();
|
||||
}
|
||||
}
|
||||
// 如果静态工作进程全部退出,会发生 CPU 空转,所以这里需要 sleep 1
|
||||
if (!count($this->workerIds)) {
|
||||
// sleep(1);
|
||||
self::exitMasterDo();
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
usleep(500 * 1000);
|
||||
}
|
||||
} catch (\Throwable $exception) {
|
||||
// todo
|
||||
echo sprintf('[%s]: ', date('Y-m-d H:i:s')) . $exception->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function init()
|
||||
{
|
||||
$this->displayErrors();
|
||||
$this->start_at = $this->worker_start_at = time();
|
||||
// 记录 masterID
|
||||
FileSystem::put(self::masterPidStorePath(), posix_getpid());
|
||||
// 保存信息
|
||||
$this->saveTaskInfo();
|
||||
// 初始化进程数量
|
||||
$this->allWorkersCount = $this->static;
|
||||
// 显示UI
|
||||
$this->display();
|
||||
// 重定向
|
||||
$this->dup();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化进程池
|
||||
*
|
||||
* @time 2020年07月21日
|
||||
* @return void
|
||||
*/
|
||||
protected function initWorkers()
|
||||
{
|
||||
$this->redis = $this->getRedisHandle();
|
||||
|
||||
for ($i = 0; $i < $this->static; $i++) {
|
||||
$this->forkStatic();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fork 进程
|
||||
*
|
||||
* @time 2020年07月21日
|
||||
* @return void
|
||||
*/
|
||||
protected function forkDynamic()
|
||||
{
|
||||
$process = new Process(function (Process $process) {
|
||||
$redis = $this->getRedisHandle();
|
||||
while($crontab = $redis->rpop($this->crontabQueueName)) {
|
||||
$task = $this->getTaskObject(\json_decode($crontab, true));
|
||||
$task->run();
|
||||
}
|
||||
|
||||
$process->exit();
|
||||
});
|
||||
|
||||
$process->start();
|
||||
|
||||
$this->workerIds[$process->pid] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 静态进程
|
||||
*
|
||||
* @time 2020年07月21日
|
||||
* @return void
|
||||
*/
|
||||
protected function forkStatic()
|
||||
{
|
||||
$process = new Process(function (Process $process) {
|
||||
$process->initMemory();
|
||||
|
||||
$name = $this->name . ' worker';
|
||||
$this->setWorkerStatus($name, $this->dealNum, $this->status);
|
||||
|
||||
Process::setWorkerName($name);
|
||||
|
||||
Process::signal(SIGUSR2, function ($signal) use ($name) {
|
||||
$this->setWorkerStatus($name, $this->dealNum, $this->status);
|
||||
});
|
||||
|
||||
// 该信号保证进程完成任务后安全退出
|
||||
Process::signal(SIGTERM, function ($signal) {
|
||||
$this->exitSafely = true;
|
||||
});
|
||||
|
||||
while (true) {
|
||||
/************** 任务 *********************/
|
||||
$this->status = 'busying';
|
||||
$this->setWorkerStatus($name, $this->dealNum, 'busying');
|
||||
|
||||
// 处理定时任务
|
||||
while ($crontab = $this->redis->rpop($this->crontabQueueName)) {
|
||||
$task = $this->getTaskObject(\json_decode($crontab, true));
|
||||
$task->run();
|
||||
if ($task->shouldExit()) {
|
||||
$process->exit(250);
|
||||
}
|
||||
$this->dealNum += 1;
|
||||
}
|
||||
|
||||
$this->status = 'waiting';
|
||||
$this->setWorkerStatus($name, $this->dealNum, 'waiting');
|
||||
/****************处理*********************/
|
||||
// 暂停一秒 让出CPU调度
|
||||
sleep(1);
|
||||
// 信号调度
|
||||
Process::dispatch();
|
||||
// 是否需要安全退出 || 查看内存是否溢出
|
||||
if ($this->exitSafely || $process->isMemoryOverflow()) {
|
||||
$process->exit();
|
||||
//exit(0);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$process->start();
|
||||
|
||||
$this->workerIds[$process->pid] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 重定向文件流
|
||||
*
|
||||
* @time 2020年07月22日
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function dup()
|
||||
{
|
||||
if (!$this->daemon) {
|
||||
return;
|
||||
}
|
||||
|
||||
global $stdout, $stderr;
|
||||
|
||||
// 关闭标准输入输出
|
||||
fclose(STDOUT);
|
||||
fclose(STDIN);
|
||||
fclose(STDERR);
|
||||
|
||||
// 重定向输出&错误
|
||||
$stdoutPath = self::$stdout ?: self::stdoutPath();
|
||||
|
||||
!file_exists($stdoutPath) && touch($stdoutPath);
|
||||
// 等待 100 毫秒
|
||||
usleep(100 * 1000);
|
||||
|
||||
$stdout = fopen($stdoutPath, 'a');
|
||||
|
||||
$stderr = fopen($stdoutPath, 'a');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出
|
||||
*
|
||||
* @time 2020年07月21日
|
||||
* @return string
|
||||
*/
|
||||
public function output()
|
||||
{
|
||||
$isShowCtrlC = $this->daemon ? '' : 'Ctrl+c to stop' . "\r\n";
|
||||
|
||||
$info = <<<EOT
|
||||
---------------------------------------------------------------- 🚀
|
||||
| _ _ _ _ |
|
||||
| | | | | | | | | |
|
||||
| ___ __ _| |_ ___| |__ ___ _ __ ___ _ __ | |_ __ _| |__ |
|
||||
| / __/ _` | __/ __| '_ \ / __| '__/ _ \| '_ \| __/ _` | '_ \ |
|
||||
| | (_| (_| | || (__| | | | | (__| | | (_) | | | | || (_| | |_) ||
|
||||
| \___\__,_|\__\___|_| |_| \___|_| \___/|_| |_|\__\__,_|_.__/ |
|
||||
| | |
|
||||
|----------------------------------------------------------------|
|
||||
$isShowCtrlC
|
||||
EOT;
|
||||
return file_put_contents(self::statusPath(), $info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示
|
||||
*
|
||||
* @time 2020年07月22日
|
||||
* @return false|int
|
||||
*/
|
||||
protected function display()
|
||||
{
|
||||
$this->output();
|
||||
|
||||
return fwrite(STDOUT, $this->renderStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 redis 句柄
|
||||
*
|
||||
* @time 2020年09月15日
|
||||
* @return object|null
|
||||
*/
|
||||
protected function getRedisHandle()
|
||||
{
|
||||
return Cache::store('redis')->handler();
|
||||
}
|
||||
}
|
47
catch/monitor/command/process/ParseTask.php
Normal file
47
catch/monitor/command/process/ParseTask.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
namespace catchAdmin\monitor\command\process;
|
||||
|
||||
use catcher\facade\FileSystem;
|
||||
use think\exception\ClassNotFoundException;
|
||||
use think\helper\Str;
|
||||
|
||||
trait ParseTask
|
||||
{
|
||||
/**
|
||||
* 获取任务
|
||||
*
|
||||
* @time 2020年09月15日
|
||||
* @param $crontab
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getTaskObject($crontab)
|
||||
{
|
||||
$class = $this->getTaskNamespace() . ucfirst(Str::camel($crontab['task']));
|
||||
|
||||
if (class_exists($class)) {
|
||||
return app()->make($class)->setCrontab($crontab);
|
||||
}
|
||||
|
||||
throw new ClassNotFoundException('Task '. $crontab['task'] . ' not found');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取任务命名空间
|
||||
*
|
||||
* @time 2020年09月15日
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getTaskNamespace()
|
||||
{
|
||||
return config('catch.crontab.task_namespace');
|
||||
}
|
||||
}
|
213
catch/monitor/command/process/Process.php
Normal file
213
catch/monitor/command/process/Process.php
Normal file
@@ -0,0 +1,213 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~{$year} http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace catchAdmin\monitor\command\process;
|
||||
|
||||
use catcher\exceptions\FailedException;
|
||||
|
||||
class Process
|
||||
{
|
||||
/**
|
||||
* 保存工作进程 PID
|
||||
*
|
||||
* @var
|
||||
*/
|
||||
public $pid;
|
||||
|
||||
/**
|
||||
* 用户自定义方法
|
||||
*
|
||||
* @var callable
|
||||
*/
|
||||
protected $callable;
|
||||
|
||||
/**
|
||||
* 申请最大内存 给出缓冲期
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $initMemory = '256M';
|
||||
|
||||
/**
|
||||
* 超过最大内存报警
|
||||
*
|
||||
* @var float|int
|
||||
*/
|
||||
protected $allowMaxMemory = 128 * 1024 * 1024;
|
||||
|
||||
public function __construct(callable $callable)
|
||||
{
|
||||
$this->callable = $callable;
|
||||
}
|
||||
|
||||
/**
|
||||
* 守护进程
|
||||
*
|
||||
* @time 2020年07月21日
|
||||
* @return void
|
||||
* @throws FailedException
|
||||
*/
|
||||
public static function daemon()
|
||||
{
|
||||
$pid = pcntl_fork();
|
||||
|
||||
if ($pid < 0) {
|
||||
throw new FailedException('fork process failed');
|
||||
}
|
||||
// 退出父进程
|
||||
if ($pid > 0) {
|
||||
exit(0);
|
||||
}
|
||||
// 设置新的会话组
|
||||
if (posix_setsid() < 0) {
|
||||
exit(0);
|
||||
}
|
||||
chdir('/');
|
||||
// 重置掩码 权限问题
|
||||
umask(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动进程
|
||||
*
|
||||
* @time 2020年07月21日
|
||||
* @return void
|
||||
*/
|
||||
public function start()
|
||||
{
|
||||
$pid = pcntl_fork();
|
||||
|
||||
if ($this->pid < 0) {
|
||||
exit('fork failed');
|
||||
}
|
||||
|
||||
if ($pid > 0) {
|
||||
$this->pid = $pid;
|
||||
} else {
|
||||
call_user_func_array($this->callable, [$this]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 信号
|
||||
*
|
||||
* @time 2020年07月21日
|
||||
* @param $signal
|
||||
* @param $callable
|
||||
* @param $restartSysCalls
|
||||
* @return void
|
||||
*/
|
||||
public static function signal($signal, $callable, $restartSysCalls = false)
|
||||
{
|
||||
pcntl_signal($signal, $callable, $restartSysCalls);
|
||||
}
|
||||
|
||||
/**
|
||||
* default 1 second
|
||||
*
|
||||
* @param $interval
|
||||
* @return mixed
|
||||
*/
|
||||
public static function alarm($interval = 1)
|
||||
{
|
||||
return pcntl_alarm($interval);
|
||||
}
|
||||
|
||||
/**
|
||||
* linux 进程下设置进程名称
|
||||
*
|
||||
* @time 2020年07月21日
|
||||
* @param $title
|
||||
* @return void
|
||||
*/
|
||||
public static function setWorkerName($title)
|
||||
{
|
||||
if (strtolower(PHP_OS) === 'linux') {
|
||||
cli_set_process_title($title);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 安全退出
|
||||
*
|
||||
* @time 2020年07月21日
|
||||
* @param int $status
|
||||
* @return void
|
||||
*/
|
||||
public function exit($status = 0)
|
||||
{
|
||||
exit($status);
|
||||
}
|
||||
|
||||
/**
|
||||
* kill
|
||||
*
|
||||
* @time 2020年07月22日
|
||||
* @param $pid
|
||||
* @param $signal
|
||||
* @return bool
|
||||
*/
|
||||
public static function kill($pid, $signal)
|
||||
{
|
||||
return posix_kill($pid, $signal);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @time 2020年07月22日
|
||||
* @return void
|
||||
*/
|
||||
public static function dispatch()
|
||||
{
|
||||
pcntl_signal_dispatch();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 是否存活
|
||||
*
|
||||
* @time 2020年07月22日
|
||||
* @param $pid
|
||||
* @return bool
|
||||
*/
|
||||
public static function isAlive($pid)
|
||||
{
|
||||
return posix_kill($pid, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化进程内存
|
||||
*
|
||||
* @time 2020年07月22日
|
||||
* @param int $memory
|
||||
* @return void
|
||||
*/
|
||||
public function initMemory($memory = 0)
|
||||
{
|
||||
if (ini_get('memory_limit') != $this->initMemory) {
|
||||
// 这里申请一块稍微大的内存
|
||||
ini_set('memory_limit', $memory ?: $this->initMemory);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否超过最大内存
|
||||
*
|
||||
* @time 2020年07月22日
|
||||
* @return mixed
|
||||
*/
|
||||
public function isMemoryOverflow()
|
||||
{
|
||||
// 一旦超过了允许的内存 直接退出进程
|
||||
return memory_get_usage() > $this->allowMaxMemory;
|
||||
}
|
||||
}
|
158
catch/monitor/command/process/RegisterSignal.php
Normal file
158
catch/monitor/command/process/RegisterSignal.php
Normal file
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~{$year} http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace catchAdmin\monitor\command\process;
|
||||
|
||||
use catchAdmin\monitor\model\Crontab;
|
||||
use catcher\facade\FileSystem;
|
||||
use Cron\CronExpression;
|
||||
use EasyWeChat\Kernel\Messages\News;
|
||||
use think\cache\driver\Redis;
|
||||
|
||||
trait RegisterSignal
|
||||
{
|
||||
public function registerSignal()
|
||||
{
|
||||
// 退出信号
|
||||
$this->exit();
|
||||
// 等待子进程退出
|
||||
$this->waitWorkersExit();
|
||||
// 动态扩容
|
||||
$this->workerChecked();
|
||||
// 重启进程
|
||||
$this->reload();
|
||||
// 统计信息
|
||||
$this->showStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* 进程退出
|
||||
*
|
||||
* @time 2020年07月21日
|
||||
* @return void
|
||||
*/
|
||||
protected function exit()
|
||||
{
|
||||
Process::signal(SIGTERM, function ($signal) {
|
||||
foreach ($this->workerIds as $pid => $v) {
|
||||
if (isset($this->workerIds[$pid])) {
|
||||
unset($this->workerIds[$pid]);
|
||||
}
|
||||
Process::kill($pid, SIGTERM);
|
||||
}
|
||||
Process::kill(self::getMasterPid(), SIGKILL);
|
||||
});
|
||||
|
||||
Process::signal(SIGINT, function ($signal) {
|
||||
foreach ($this->workerIds as $pid => $v) {
|
||||
if (isset($this->workerIds[$pid])) {
|
||||
unset($this->workerIds[$pid]);
|
||||
}
|
||||
Process::kill($pid, SIGKILL);
|
||||
}
|
||||
Process::kill(self::getMasterPid(), SIGKILL);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 子进程退出
|
||||
*
|
||||
* @time 2020年07月21日
|
||||
* @return void
|
||||
*/
|
||||
protected function waitWorkersExit()
|
||||
{
|
||||
Process::signal(SIGCHLD, function ($signal) {
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 进程检测
|
||||
*
|
||||
* @time 2020年07月21日
|
||||
* @return void
|
||||
*/
|
||||
protected function workerChecked()
|
||||
{
|
||||
Process::signal(SIGALRM, function ($signal) {
|
||||
$process = new Process(function (Process $process) {
|
||||
$crontabs = Crontab::where('status', Crontab::ENABLE)
|
||||
->where('tactics', '<>', Crontab::EXECUTE_FORBIDDEN)
|
||||
->select()->toArray();
|
||||
|
||||
// 任务
|
||||
foreach ($crontabs as $crontab) {
|
||||
$can = date('Y-m-d H:i', CronExpression::factory(trim($crontab['cron']))
|
||||
->getNextRunDate(date('Y-m-d H:i:s'), 0 , true)
|
||||
->getTimestamp()) == date('Y-m-d H:i', time());
|
||||
|
||||
if ($can) {
|
||||
// 如果任务只执行一次 之后禁用该任务
|
||||
if ($crontab['tactics'] === Crontab::EXECUTE_ONCE) {
|
||||
Crontab::where('id', $crontab['id'])->update([
|
||||
'status' => Crontab::DISABLE,
|
||||
]);
|
||||
}
|
||||
|
||||
$redis = $this->getRedisHandle();
|
||||
|
||||
$redis->lpush($this->crontabQueueName, json_encode([
|
||||
'id' => $crontab['id'],
|
||||
'task' => $crontab['task'],
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
$process->exit();
|
||||
});
|
||||
|
||||
$process->start();
|
||||
|
||||
Process::alarm($this->interval);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 重启
|
||||
*
|
||||
* @time 2020年07月21日
|
||||
* @return void
|
||||
*/
|
||||
protected function reload()
|
||||
{
|
||||
Process::signal(SIGUSR1, function ($signal) {
|
||||
$this->worker_start_at = 0;
|
||||
foreach ($this->workerIds as $pid => $v) {
|
||||
Process::kill($pid, SIGTERM);
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 预留信号
|
||||
*
|
||||
* @time 2020年07月21日
|
||||
* @return void
|
||||
*/
|
||||
protected function showStatus()
|
||||
{
|
||||
Process::signal(SIGUSR2, function ($signal) {
|
||||
$this->setWorkerStatus($this->name . ' master');
|
||||
foreach ($this->workerIds as $pid => $v) {
|
||||
Process::kill($pid, SIGUSR2);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
243
catch/monitor/command/process/Store.php
Normal file
243
catch/monitor/command/process/Store.php
Normal file
@@ -0,0 +1,243 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~{$year} http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace catchAdmin\monitor\command\process;
|
||||
|
||||
use catcher\facade\FileSystem;
|
||||
|
||||
trait Store
|
||||
{
|
||||
/**
|
||||
* worker 根目录
|
||||
*
|
||||
* @time 2020年07月23日
|
||||
* @return string
|
||||
*/
|
||||
public static function storeTaskPath()
|
||||
{
|
||||
$path = config('catch.crontab.store_path');
|
||||
|
||||
if (!Filesystem::exists($path)) {
|
||||
FileSystem::makeDirectory($path, 0777, true);
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存信息备用
|
||||
*
|
||||
* @time 2020年07月29日
|
||||
* @return void
|
||||
*/
|
||||
protected function saveTaskInfo()
|
||||
{
|
||||
FileSystem::put(self::storeTaskPath() . 'information.json', \json_encode([
|
||||
'name' => $this->name,
|
||||
'static' => $this->static,
|
||||
'dynamic' => $this->dynamic,
|
||||
'interval' => $this->interval,
|
||||
], JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
|
||||
/**
|
||||
* worker master pid
|
||||
*
|
||||
* @time 2020年07月23日
|
||||
* @return string
|
||||
*/
|
||||
public static function masterPidStorePath()
|
||||
{
|
||||
return self::storeTaskPath() . 'master.pid';
|
||||
}
|
||||
|
||||
/**
|
||||
* worker master status
|
||||
*
|
||||
* @time 2020年07月23日
|
||||
* @return string
|
||||
*/
|
||||
public static function statusPath()
|
||||
{
|
||||
return self::storeTaskPath() . 'master.status';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* worker status
|
||||
*
|
||||
* @time 2020年07月23日
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
public static function workerStatusPath($name)
|
||||
{
|
||||
$path = self::storeTaskPath() . 'status/';
|
||||
|
||||
if (!FileSystem::exists($path)) {
|
||||
FileSystem::makeDirectory($path, 0777, true);
|
||||
}
|
||||
|
||||
return $path . $name . '.status';
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @time 2020年07月23日
|
||||
* @return string
|
||||
*/
|
||||
public static function getWorkerStatusPath()
|
||||
{
|
||||
return self::storeTaskPath() . 'status/';
|
||||
}
|
||||
|
||||
/**
|
||||
* worker log
|
||||
*
|
||||
* @time 2020年07月23日
|
||||
* @return string
|
||||
*/
|
||||
public static function stdoutPath()
|
||||
{
|
||||
return self::storeTaskPath() . 'errors.log';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取 master pid
|
||||
*
|
||||
* @time 2020年07月21日
|
||||
* @return false|string
|
||||
*/
|
||||
public static function getMasterPid()
|
||||
{
|
||||
$pidFile = config('catch.crontab.master_pid_file');
|
||||
|
||||
if (!file_exists($pidFile)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return FileSystem::sharedGet($pidFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* status
|
||||
*
|
||||
* @time 2020年07月21日
|
||||
* @return false|string
|
||||
*/
|
||||
public function renderStatus()
|
||||
{
|
||||
return file_get_contents(self::statusPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* 运行时间
|
||||
*
|
||||
* @time 2020年07月23日
|
||||
* @param $runtime
|
||||
* @return string
|
||||
*/
|
||||
protected function getRunningTime($runtime)
|
||||
{
|
||||
$day = 3600 * 24;
|
||||
if ($runtime > $day) {
|
||||
$days = floor($runtime / $day);
|
||||
return $days . '天:' . gmstrftime('%H:%M:%S', $runtime % $day);
|
||||
} else {
|
||||
return gmstrftime('%H:%M:%S', $runtime);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取工作进程
|
||||
*
|
||||
* @time 2020年07月23日
|
||||
* @return mixed
|
||||
*/
|
||||
public function getWorkerStatus()
|
||||
{
|
||||
usleep(500 * 1000);
|
||||
|
||||
$files = FileSystem::glob(self::storeTaskPath() . 'status/*.status');
|
||||
|
||||
$workerStatus = [];
|
||||
|
||||
foreach ($files as $file) {
|
||||
$workerStatus[] = explode("\t", FileSystem::sharedGet($file));
|
||||
}
|
||||
|
||||
return $workerStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置进程状态
|
||||
*
|
||||
* @time 2020年07月23日
|
||||
* @param $name
|
||||
* @param int $dealNum
|
||||
* @param string $status
|
||||
* @return void
|
||||
*/
|
||||
protected function setWorkerStatus($name, $dealNum = 0, $status = 'running')
|
||||
{
|
||||
$startAt = strpos($name, 'worker') ? $this->worker_start_at : $this->start_at;
|
||||
|
||||
if ($this->daemon) {
|
||||
FileSystem::put($this->workerStatusPath($this->workerStatusFileName($name)), implode("\t", [
|
||||
posix_getpid(),
|
||||
$name,
|
||||
floor(memory_get_usage() / 1024 / 1024) . 'M',
|
||||
$dealNum,
|
||||
date('Y-m-d H:i:s', $startAt),
|
||||
$this->getRunningTime(time() - $startAt),
|
||||
$status
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 进程名称
|
||||
*
|
||||
* @time 2020年09月15日
|
||||
* @param $name
|
||||
* @return string
|
||||
*/
|
||||
protected function workerStatusFileName($name)
|
||||
{
|
||||
return $name . '_' . posix_getpid();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除进程状态文件
|
||||
*
|
||||
* @time 2020年09月15日
|
||||
* @param $pid
|
||||
* @return void
|
||||
*/
|
||||
protected function deleteWorkerStatusFile($pid)
|
||||
{
|
||||
@unlink(self::workerStatusPath($this->name . ' worker_' . $pid));
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出
|
||||
*
|
||||
* @time 2020年09月15日
|
||||
* @return void
|
||||
*/
|
||||
public static function exitMasterDo()
|
||||
{
|
||||
@unlink(self::masterPidStorePath());
|
||||
@unlink(self::statusPath());
|
||||
Filesystem::deleteDirectory(self::getWorkerStatusPath());
|
||||
}
|
||||
}
|
59
catch/monitor/config.php
Normal file
59
catch/monitor/config.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
return [
|
||||
/**
|
||||
*
|
||||
* 定时任务配置
|
||||
*
|
||||
*/
|
||||
'crontab' => [
|
||||
/**
|
||||
* 存储目录
|
||||
*/
|
||||
'store_path' => runtime_path('catch/crontab'),
|
||||
|
||||
/**
|
||||
* 主进程 pid 存储
|
||||
*/
|
||||
'master_pid_file' => runtime_path('catch/crontab') . 'master.pid',
|
||||
|
||||
/**
|
||||
* 日志配置
|
||||
*/
|
||||
'log' => [
|
||||
// 日志记录方式
|
||||
'type' => 'File',
|
||||
// 日志保存目录
|
||||
'path' => runtime_path('catch/schedule'),
|
||||
// 单文件日志写入
|
||||
'single' => false,
|
||||
// 独立日志级别
|
||||
'apart_level' => [],
|
||||
// 最大日志文件数量
|
||||
'max_files' => 0,
|
||||
// 使用JSON格式记录
|
||||
'json' => false,
|
||||
// 日志处理
|
||||
'processor' => null,
|
||||
// 关闭通道日志写入
|
||||
'close' => false,
|
||||
// 日志输出格式化
|
||||
'format' => '[%s][%s] %s',
|
||||
// 是否实时写入
|
||||
'realtime_write' => false,
|
||||
],
|
||||
|
||||
/**
|
||||
* crontab 任务命名空间
|
||||
*/
|
||||
'task_namespace' => '\\app\\task\\',
|
||||
],
|
||||
];
|
105
catch/monitor/controller/Crontab.php
Normal file
105
catch/monitor/controller/Crontab.php
Normal file
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace catchAdmin\monitor\controller;
|
||||
|
||||
use catcher\base\CatchRequest as Request;
|
||||
use catcher\CatchResponse;
|
||||
use catcher\base\CatchController;
|
||||
use catchAdmin\monitor\model\Crontab as CrontabModel;
|
||||
use Cron\CronExpression;
|
||||
|
||||
class Crontab extends CatchController
|
||||
{
|
||||
protected $model;
|
||||
|
||||
public function __construct(CrontabModel $model)
|
||||
{
|
||||
$this->model = $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*
|
||||
* @time 2020/09/14 20:35
|
||||
*
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return CatchResponse::paginate($this->model->getList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*
|
||||
* @time 2020/09/14 20:35
|
||||
* @param Request Request
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function save(Request $request)
|
||||
{
|
||||
CronExpression::factory($request->post('cron'));
|
||||
|
||||
return CatchResponse::success($this->model->storeBy($request->post()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取
|
||||
*
|
||||
* @time 2020/09/14 20:35
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function read($id)
|
||||
{
|
||||
return CatchResponse::success($this->model->findBy($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新
|
||||
*
|
||||
* @time 2020/09/14 20:35
|
||||
* @param Request $request
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
CronExpression::factory($request->post('cron'));
|
||||
|
||||
return CatchResponse::success($this->model->updateBy($id, $request->post()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @time 2020/09/14 20:35
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
return CatchResponse::success($this->model->deleteBy($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用启用
|
||||
*
|
||||
* @time 2020年09月15日
|
||||
* @param $id
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function disOrEnable($id)
|
||||
{
|
||||
return CatchResponse::success($this->model->disOrEnable($id));
|
||||
}
|
||||
|
||||
}
|
50
catch/monitor/controller/CrontabLog.php
Normal file
50
catch/monitor/controller/CrontabLog.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
namespace catchAdmin\monitor\controller;
|
||||
|
||||
use catchAdmin\monitor\model\CrontabLog as LogModel;
|
||||
use catcher\base\CatchController;
|
||||
use catcher\CatchResponse;
|
||||
use think\Request;
|
||||
|
||||
class CrontabLog extends CatchController
|
||||
{
|
||||
protected $model;
|
||||
|
||||
public function __construct(LogModel $model)
|
||||
{
|
||||
$this->model = $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* 日志列表
|
||||
*
|
||||
* @time 2020年09月15日
|
||||
* @throws \think\db\exception\DbException
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return CatchResponse::paginate($this->model->getList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除日志
|
||||
*
|
||||
* @time 2020年09月15日
|
||||
* @param $id
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
return CatchResponse::success($this->model->deleteBy($id));
|
||||
}
|
||||
}
|
46
catch/monitor/database/migrations/20200914203553_crontab.php
Normal file
46
catch/monitor/database/migrations/20200914203553_crontab.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
use think\migration\Migrator;
|
||||
use think\migration\db\Column;
|
||||
use Phinx\Db\Adapter\MysqlAdapter;
|
||||
|
||||
class Crontab extends Migrator
|
||||
{
|
||||
/**
|
||||
* Change Method.
|
||||
*
|
||||
* Write your reversible migrations using this method.
|
||||
*
|
||||
* More information on writing migrations is available here:
|
||||
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
|
||||
*
|
||||
* The following commands can be used in this method and Phinx will
|
||||
* automatically reverse them when rolling back:
|
||||
*
|
||||
* createTable
|
||||
* renameTable
|
||||
* addColumn
|
||||
* renameColumn
|
||||
* addIndex
|
||||
* addForeignKey
|
||||
*
|
||||
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||
* with the Table class.
|
||||
*/
|
||||
public function change()
|
||||
{
|
||||
$table = $this->table('crontab', ['engine' => 'InnoDB', 'collation' => 'utf8mb4_general_ci', 'comment' => '定时任务' ,'id' => 'id','signed' => true ,'primary_key' => ['id']]);
|
||||
$table->addColumn('name', 'string', ['limit' => 255,'null' => false,'default' => '','signed' => false,'comment' => '任务名称',])
|
||||
->addColumn('group', 'boolean', ['null' => false,'default' => 1,'signed' => false,'comment' => '1 默认 2 系统',])
|
||||
->addColumn('task', 'string', ['limit' => 255,'null' => false,'default' => '','signed' => false,'comment' => '任务名称',])
|
||||
->addColumn('cron', 'string', ['limit' => 50,'null' => false,'default' => '','signed' => false,'comment' => 'cron 表达式',])
|
||||
->addColumn('tactics', 'boolean', ['null' => false,'default' => 1,'signed' => false,'comment' => '1 立即执行 2 执行一次 3 放弃执行',])
|
||||
->addColumn('status', 'boolean', ['null' => false,'default' => 1,'signed' => false,'comment' => '1 正常 2 禁用',])
|
||||
->addColumn('remark', 'string', ['limit' => 1000,'null' => false,'default' => '','signed' => false,'comment' => '备注',])
|
||||
->addColumn('creator_id', 'integer', ['limit' => MysqlAdapter::INT_REGULAR,'null' => false,'default' => 0,'signed' => true,'comment' => '创建人ID',])
|
||||
->addColumn('created_at', 'integer', ['limit' => MysqlAdapter::INT_REGULAR,'null' => false,'default' => 0,'signed' => true,'comment' => '创建时间',])
|
||||
->addColumn('updated_at', 'integer', ['limit' => MysqlAdapter::INT_REGULAR,'null' => false,'default' => 0,'signed' => true,'comment' => '更新时间',])
|
||||
->addColumn('deleted_at', 'integer', ['limit' => MysqlAdapter::INT_REGULAR,'null' => false,'default' => 0,'signed' => true,'comment' => '软删除',])
|
||||
->create();
|
||||
}
|
||||
}
|
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~{$year} http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
use think\migration\Migrator;
|
||||
use think\migration\db\Column;
|
||||
use Phinx\Db\Adapter\MysqlAdapter;
|
||||
|
||||
class CrontabLog extends Migrator
|
||||
{
|
||||
/**
|
||||
* Change Method.
|
||||
*
|
||||
* Write your reversible migrations using this method.
|
||||
*
|
||||
* More information on writing migrations is available here:
|
||||
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
|
||||
*
|
||||
* The following commands can be used in this method and Phinx will
|
||||
* automatically reverse them when rolling back:
|
||||
*
|
||||
* createTable
|
||||
* renameTable
|
||||
* addColumn
|
||||
* renameColumn
|
||||
* addIndex
|
||||
* addForeignKey
|
||||
*
|
||||
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||
* with the Table class.
|
||||
*/
|
||||
public function change()
|
||||
{
|
||||
$table = $this->table('crontab_log', ['engine' => 'Myisam', 'collation' => 'utf8mb4_general_ci', 'comment' => '定时任务日志' ,'id' => 'id','signed' => true ,'primary_key' => ['id']]);
|
||||
$table->addColumn('crontab_id', 'integer', ['limit' => MysqlAdapter::INT_REGULAR,'null' => false,'default' => 0,'signed' => true,'comment' => 'crontab 任务ID',])
|
||||
->addColumn('used_time', 'integer', ['limit' => MysqlAdapter::INT_REGULAR,'null' => false,'default' => 0,'signed' => true,'comment' => '任务消耗时间',])
|
||||
->addColumn('status', 'boolean', ['null' => false,'default' => 1,'signed' => false,'comment' => '1 成功 2 失败',])
|
||||
->addColumn('error_message', 'string', ['limit' => 1000,'null' => false,'default' => '','signed' => false,'comment' => '错误信息',])
|
||||
->addColumn('created_at', 'integer', ['limit' => MysqlAdapter::INT_REGULAR,'null' => false,'default' => 0,'signed' => true,'comment' => '创建时间',])
|
||||
->addColumn('updated_at', 'integer', ['limit' => MysqlAdapter::INT_REGULAR,'null' => false,'default' => 0,'signed' => true,'comment' => '更新时间',])
|
||||
->addColumn('deleted_at', 'integer', ['limit' => MysqlAdapter::INT_REGULAR,'null' => false,'default' => 0,'signed' => true,'comment' => '软删除',])
|
||||
->create();
|
||||
}
|
||||
}
|
253
catch/monitor/database/seeds/MonitorMenusSeed.php
Normal file
253
catch/monitor/database/seeds/MonitorMenusSeed.php
Normal file
@@ -0,0 +1,253 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~{$year} http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
use think\migration\Seeder;
|
||||
|
||||
class MonitorMenusSeed extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run Method.
|
||||
*
|
||||
* Write your database seeder using this method.
|
||||
*
|
||||
* More information on writing seeders is available here:
|
||||
* http://docs.phinx.org/en/latest/seeding.html
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
\catcher\Utils::importTreeData($this->getPermissions(), 'permissions', 'parent_id');
|
||||
}
|
||||
|
||||
protected function getPermissions()
|
||||
{
|
||||
return array (
|
||||
0 =>
|
||||
array (
|
||||
'id' => 103,
|
||||
'permission_name' => '系统监控',
|
||||
'parent_id' => 0,
|
||||
'level' => '',
|
||||
'route' => '/monitor',
|
||||
'icon' => 'el-icon-view',
|
||||
'module' => 'monitor',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'monitor',
|
||||
'component' => 'layout',
|
||||
'redirect' => '/monitor/crontab',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1600126383,
|
||||
'updated_at' => 1600136975,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
'id' => 104,
|
||||
'permission_name' => '定时任务',
|
||||
'parent_id' => 103,
|
||||
'level' => '103',
|
||||
'route' => '/monitor/crontab',
|
||||
'icon' => 'el-icon-time',
|
||||
'module' => 'monitor',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'crontab',
|
||||
'component' => 'crontab',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1600126931,
|
||||
'updated_at' => 1600136975,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
'id' => 105,
|
||||
'permission_name' => '列表',
|
||||
'parent_id' => 104,
|
||||
'level' => '103-104',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'monitor',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'crontab@index',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1600127069,
|
||||
'updated_at' => 1600136975,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
'id' => 106,
|
||||
'permission_name' => '保存',
|
||||
'parent_id' => 104,
|
||||
'level' => '103-104',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'monitor',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'crontab@save',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1600127078,
|
||||
'updated_at' => 1600136975,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
'id' => 107,
|
||||
'permission_name' => '更新',
|
||||
'parent_id' => 104,
|
||||
'level' => '103-104',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'monitor',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'crontab@update',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1600127085,
|
||||
'updated_at' => 1600136975,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
'id' => 108,
|
||||
'permission_name' => '删除',
|
||||
'parent_id' => 104,
|
||||
'level' => '103-104',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'monitor',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'crontab@delete',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1600127091,
|
||||
'updated_at' => 1600136975,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
'id' => 109,
|
||||
'permission_name' => '禁用/启用',
|
||||
'parent_id' => 104,
|
||||
'level' => '103-104',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'monitor',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'crontab@disOrEnable',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1600129279,
|
||||
'updated_at' => 1600136975,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
'id' => 110,
|
||||
'permission_name' => '任务日志',
|
||||
'parent_id' => 103,
|
||||
'level' => '103-104',
|
||||
'route' => '/monitor/crontab/log/:crontab_id?',
|
||||
'icon' => 'el-icon-guide',
|
||||
'module' => 'monitor',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'CrontabLog',
|
||||
'component' => 'crontabLog',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 2,
|
||||
'sort' => 1,
|
||||
'created_at' => 1600167562,
|
||||
'updated_at' => 1600188651,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
'id' => 111,
|
||||
'permission_name' => '列表',
|
||||
'parent_id' => 110,
|
||||
'level' => '103-104-110',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'monitor',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'CrontabLog@index',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1600167574,
|
||||
'updated_at' => 1600168082,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
'id' => 112,
|
||||
'permission_name' => '删除',
|
||||
'parent_id' => 110,
|
||||
'level' => '103-104-110',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'monitor',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'CrontabLog@delete',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1600167581,
|
||||
'updated_at' => 1600168082,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
43
catch/monitor/model/Crontab.php
Normal file
43
catch/monitor/model/Crontab.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace catchAdmin\monitor\model;
|
||||
|
||||
use catchAdmin\monitor\model\search\CrontabSearch;
|
||||
use catcher\base\CatchModel as Model;
|
||||
|
||||
class Crontab extends Model
|
||||
{
|
||||
use CrontabSearch;
|
||||
|
||||
protected $name = 'crontab';
|
||||
|
||||
protected $field = [
|
||||
'id', //
|
||||
'name', // 任务名称
|
||||
'group', // 1 默认 2 系统
|
||||
'task', // 任务名称
|
||||
'cron', // cron 表达式
|
||||
'tactics', // 1 立即执行 2 执行一次 3 放弃执行
|
||||
'status', // 1 正常 2 禁用
|
||||
'remark', // 备注
|
||||
'creator_id', // 创建人ID
|
||||
'created_at', // 创建时间
|
||||
'updated_at', // 更新时间
|
||||
'deleted_at', // 软删除
|
||||
];
|
||||
|
||||
|
||||
const EXECUTE_IMMEDIATELY = 1; // 立即执行
|
||||
const EXECUTE_ONCE = 2; // 执行一次
|
||||
const EXECUTE_FORBIDDEN = 3; // 停止执行
|
||||
|
||||
}
|
53
catch/monitor/model/CrontabLog.php
Normal file
53
catch/monitor/model/CrontabLog.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace catchAdmin\monitor\model;
|
||||
|
||||
use catchAdmin\monitor\model\search\CrontabLogSearch;
|
||||
use catcher\base\CatchModel;
|
||||
|
||||
class CrontabLog extends CatchModel
|
||||
{
|
||||
use CrontabLogSearch;
|
||||
|
||||
protected $name = 'crontab_log';
|
||||
|
||||
protected $field = [
|
||||
'id', //
|
||||
'crontab_id', // crontab 任务ID
|
||||
'used_time', // 任务消耗时间
|
||||
'status', // 1 成功 2 失败
|
||||
'error_message', // 错误信息
|
||||
'created_at', // 创建时间
|
||||
'updated_at', // 更新时间
|
||||
'deleted_at', // 软删除
|
||||
];
|
||||
|
||||
|
||||
const SUCCESS = 1;
|
||||
const FAILED = 2;
|
||||
|
||||
/**
|
||||
* 获取日志列表
|
||||
*
|
||||
* @time 2020年09月15日
|
||||
* @throws \think\db\exception\DbException
|
||||
* @return mixed|\think\Paginator
|
||||
*/
|
||||
public function getList()
|
||||
{
|
||||
return $this->catchLeftJoin(Crontab::class, 'id', 'crontab_id', ['name', 'group', 'task'])
|
||||
->catchSearch()
|
||||
->catchOrder()
|
||||
->field(['used_time', 'error_message', 'crontab_log.status', 'crontab_log.id', 'crontab_log.created_at'])
|
||||
->paginate();
|
||||
}
|
||||
}
|
39
catch/monitor/model/search/CrontabLogSearch.php
Normal file
39
catch/monitor/model/search/CrontabLogSearch.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
namespace catchAdmin\monitor\model\search;
|
||||
|
||||
trait CrontabLogSearch
|
||||
{
|
||||
public function searchCrontabIdAttr($query, $value, $data)
|
||||
{
|
||||
return $query->where('crontab_id', $value);
|
||||
}
|
||||
|
||||
public function searchNameAttr($query, $value, $data)
|
||||
{
|
||||
return $query->whereLike('crontab.name', $value);
|
||||
}
|
||||
|
||||
public function searchStatusAttr($query, $value, $data)
|
||||
{
|
||||
return $query->where('crontab_log.status', $value);
|
||||
}
|
||||
|
||||
public function searchStartAtAttr($query, $value, $data)
|
||||
{
|
||||
return $query->where($this->aliasField('created_at'), '>=', strtotime($value));
|
||||
}
|
||||
|
||||
public function searchEndAtAttr($query, $value, $data)
|
||||
{
|
||||
return $query->where($this->aliasField('created_at'), '<=', strtotime($value));
|
||||
}
|
||||
}
|
24
catch/monitor/model/search/CrontabSearch.php
Normal file
24
catch/monitor/model/search/CrontabSearch.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
namespace catchAdmin\monitor\model\search;
|
||||
|
||||
trait CrontabSearch
|
||||
{
|
||||
public function searchNameAttr($query, $value, $data)
|
||||
{
|
||||
return $query->whereLike('name', $value);
|
||||
}
|
||||
|
||||
public function searchStatusAttr($query, $value, $data)
|
||||
{
|
||||
return $query->whereLike('status', $value);
|
||||
}
|
||||
}
|
15
catch/monitor/module.json
Normal file
15
catch/monitor/module.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "系统监控",
|
||||
"alias": "monitor",
|
||||
"description": "系统监控模块",
|
||||
"version": "1.0.0",
|
||||
"keywords": [],
|
||||
"order": 0,
|
||||
"services": [
|
||||
"\\catchAdmin\\monitor\\MonitorService"
|
||||
],
|
||||
"aliases": [],
|
||||
"files": [],
|
||||
"requires": [],
|
||||
"enable": true
|
||||
}
|
22
catch/monitor/route.php
Normal file
22
catch/monitor/route.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~{$year} http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
// you should use `$router`
|
||||
$router->group('monitor', function () use ($router){
|
||||
// crontab路由
|
||||
$router->resource('crontab', '\catchAdmin\monitor\controller\Crontab');
|
||||
$router->put('crontab/enable/<id>', '\catchAdmin\monitor\controller\Crontab@disOrEnable');
|
||||
|
||||
// crontab 日志
|
||||
$router->get('crontab/log', '\catchAdmin\monitor\controller\CrontabLog@index');
|
||||
$router->delete('crontab/log/<id>', '\catchAdmin\monitor\controller\CrontabLog@delete');
|
||||
|
||||
})->middleware('auth');
|
@@ -5,6 +5,7 @@ use catcher\base\CatchController;
|
||||
use catchAdmin\permissions\model\Department as DepartmentModel;
|
||||
use catcher\base\CatchRequest;
|
||||
use catcher\CatchResponse;
|
||||
use catcher\exceptions\FailedException;
|
||||
use catcher\Tree;
|
||||
|
||||
class Department extends CatchController
|
||||
@@ -26,7 +27,7 @@ class Department extends CatchController
|
||||
*/
|
||||
public function index(): \think\response\Json
|
||||
{
|
||||
return CatchResponse::success(Tree::done($this->department->getList()));
|
||||
return CatchResponse::success($this->department->getList());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,6 +64,10 @@ class Department extends CatchController
|
||||
*/
|
||||
public function delete($id): \think\response\Json
|
||||
{
|
||||
if ($this->department->where('parent_id', $id)->find()) {
|
||||
throw new FailedException('存在子部门,无法删除');
|
||||
}
|
||||
|
||||
return CatchResponse::success($this->department->deleteBy($id));
|
||||
}
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@ use catcher\exceptions\FailedException;
|
||||
use catcher\library\ParseClass;
|
||||
use catcher\Tree;
|
||||
use catchAdmin\permissions\model\Permissions;
|
||||
use think\helper\Str;
|
||||
use think\response\Json;
|
||||
|
||||
class Permission extends CatchController
|
||||
@@ -46,9 +47,9 @@ class Permission extends CatchController
|
||||
// 子节点的 key
|
||||
$children = $request->param('actionList') ?? 'children';
|
||||
// 返回树结构
|
||||
return CatchResponse::success(Tree::done($menuList->each(function (&$item) use ($buttonList, $children){
|
||||
return CatchResponse::success($menuList->each(function (&$item) use ($buttonList, $children){
|
||||
$item[$children] = $buttonList[$item['id']] ?? [];
|
||||
})->toArray()));
|
||||
})->toTree());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,9 +67,22 @@ class Permission extends CatchController
|
||||
|
||||
// 如果是子分类 自动写入父类模块
|
||||
$parentId = $params['parent_id'] ?? 0;
|
||||
if ($parentId) {
|
||||
$parent = $this->permissions->findBy($parentId);
|
||||
$params['module'] = $parent->module;
|
||||
// 按钮类型寻找上级
|
||||
if ($params['type'] == Permissions::BTN_TYPE && $parentId) {
|
||||
$permissionMark = $params['permission_mark'];
|
||||
// 查找父级
|
||||
$parentPermission = $this->permissions->findBy($parentId);
|
||||
// 如果父级是顶级 parent_id = 0
|
||||
if ($parentPermission->parent_id) {
|
||||
if (Str::contains($parentPermission->permission_mark, '@')) {
|
||||
list($controller, $action) = explode('@', $parentPermission->permission_mark);
|
||||
$permissionMark = $controller . '@' . $permissionMark;
|
||||
} else {
|
||||
$permissionMark = $parentPermission->permission_mark .'@'. $permissionMark;
|
||||
}
|
||||
}
|
||||
$params['permission_mark'] = $permissionMark;
|
||||
$params['module'] = $parentPermission->module;
|
||||
}
|
||||
|
||||
return CatchResponse::success($this->permissions->storeBy($params));
|
||||
@@ -85,6 +99,33 @@ class Permission extends CatchController
|
||||
{
|
||||
$permission = $this->permissions->findBy($id);
|
||||
|
||||
$params = $request->param();
|
||||
// 按钮类型
|
||||
if ($params['type'] == Permissions::BTN_TYPE && $permission->parent_id) {
|
||||
$parentPermission = $this->permissions->findBy($permission->parent_id);
|
||||
|
||||
$permissionMark = $params['permission_mark'];
|
||||
if ($parentPermission->parent_id) {
|
||||
if (Str::contains($parentPermission->permission_mark, '@')) {
|
||||
list($controller, $action) = explode('@', $parentPermission->permission_mark);
|
||||
$permissionMark = $controller . '@' . $permissionMark;
|
||||
} else {
|
||||
$permissionMark = $parentPermission->permission_mark .'@'. $permissionMark;
|
||||
}
|
||||
}
|
||||
|
||||
$params['permission_mark'] = $permissionMark;
|
||||
|
||||
|
||||
$this->permissions->where('id',$id)->update(array_merge($params, [
|
||||
'parent_id' => $permission->parent_id,
|
||||
'level' => $permission->level,
|
||||
'updated_at' => time()
|
||||
]));
|
||||
|
||||
return CatchResponse::success();
|
||||
}
|
||||
|
||||
$params = array_merge($request->param(), [
|
||||
'parent_id' => $permission->parent_id,
|
||||
'level' => $permission->level
|
||||
@@ -134,17 +175,9 @@ class Permission extends CatchController
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
$permission = $this->permissions->findBy($id);
|
||||
$this->permissions->show($id);
|
||||
|
||||
$permission->status = $permission->status == Permissions::ENABLE ? Permissions::DISABLE : Permissions::ENABLE;
|
||||
|
||||
if ($permission->save()) {
|
||||
$this->permissions->where('parent_id', $id)->update([
|
||||
'status' => $permission->status,
|
||||
]);
|
||||
}
|
||||
|
||||
return CatchResponse::success($permission->save());
|
||||
return CatchResponse::success();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -160,14 +193,15 @@ class Permission extends CatchController
|
||||
public function getMethods($id, ParseClass $parseClass)
|
||||
{
|
||||
$permission = Permissions::where('id', $id)->find();
|
||||
|
||||
$module = $permission->module;
|
||||
|
||||
$controller = explode('@', $permission->permission_mark)[0];
|
||||
|
||||
try {
|
||||
$methods = $parseClass->setModule('catch')->setRule($module, $controller)->onlySelfMethods();
|
||||
|
||||
return CatchResponse::success($methods);
|
||||
}catch (\Exception $e) {
|
||||
return CatchResponse::success([]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -2,6 +2,7 @@
|
||||
namespace catchAdmin\permissions\controller;
|
||||
|
||||
use catchAdmin\permissions\model\Permissions;
|
||||
use catchAdmin\permissions\model\Roles;
|
||||
use catcher\base\CatchRequest as Request;
|
||||
use catcher\base\CatchController;
|
||||
use catcher\CatchResponse;
|
||||
@@ -26,7 +27,7 @@ class Role extends CatchController
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return CatchResponse::success(Tree::done($this->role->getList()));
|
||||
return CatchResponse::success($this->role->getList());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,14 +39,19 @@ class Role extends CatchController
|
||||
*/
|
||||
public function save(Request $request)
|
||||
{
|
||||
$this->role->storeBy($request->param());
|
||||
$params = $request->param();
|
||||
|
||||
$permissions = $request->param('permissions');
|
||||
if (Roles::where('identify', $params['identify'])->find()) {
|
||||
throw new FailedException('角色标识 [' . $params['identify'] . ']已存在');
|
||||
}
|
||||
|
||||
$this->role->storeBy($params);
|
||||
$permissions = $params['permissions'];
|
||||
if (!empty($permissions)) {
|
||||
$this->role->attachPermissions(array_unique($permissions));
|
||||
}
|
||||
if (!empty($request->param('departments'))) {
|
||||
$this->role->attachDepartments($request->param('departments'));
|
||||
if (!empty($params['permissions'])) {
|
||||
$this->role->attachDepartments($params['permissions']);
|
||||
}
|
||||
// 添加角色
|
||||
return CatchResponse::success();
|
||||
@@ -69,6 +75,10 @@ class Role extends CatchController
|
||||
*/
|
||||
public function update($id, Request $request): Json
|
||||
{
|
||||
if (Roles::where('identify', $request->param('identify'))->where('id', '<>', $id)->find()) {
|
||||
throw new FailedException('角色标识 [' . $request->param('identify') . ']已存在');
|
||||
}
|
||||
|
||||
$this->role->updateBy($id, $request->param());
|
||||
$role = $this->role->findBy($id);
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
namespace catchAdmin\permissions\controller;
|
||||
|
||||
use catchAdmin\permissions\excel\UserExport;
|
||||
use catcher\base\CatchRequest as Request;
|
||||
use catchAdmin\permissions\model\Permissions;
|
||||
use catchAdmin\permissions\model\Roles;
|
||||
@@ -11,6 +12,7 @@ use catcher\base\CatchController;
|
||||
use catcher\CatchAuth;
|
||||
use catcher\CatchCacheKeys;
|
||||
use catcher\CatchResponse;
|
||||
use catcher\library\excel\Excel;
|
||||
use catcher\Tree;
|
||||
use catcher\Utils;
|
||||
use think\facade\Cache;
|
||||
@@ -49,7 +51,7 @@ class User extends CatchController
|
||||
{
|
||||
$user = $auth->user();
|
||||
|
||||
$roles = $user->getRoles();
|
||||
$roles = $user->getRoles()->column('identify');
|
||||
|
||||
$permissionIds = $user->getPermissionsBy($user->id);
|
||||
// 缓存用户权限
|
||||
@@ -86,7 +88,9 @@ class User extends CatchController
|
||||
|
||||
$this->user->attachRoles($request->param('roles'));
|
||||
|
||||
if ($request->param('jobs')) {
|
||||
$this->user->attachJobs($request->param('jobs'));
|
||||
}
|
||||
|
||||
return CatchResponse::success('', '添加成功');
|
||||
}
|
||||
@@ -225,4 +229,30 @@ class User extends CatchController
|
||||
'hasRoles' => $roleIds,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出
|
||||
*
|
||||
* @time 2020年09月08日
|
||||
* @param Excel $excel
|
||||
* @param UserExport $userExport
|
||||
* @throws \PhpOffice\PhpSpreadsheet\Exception
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function export(Excel $excel, UserExport $userExport)
|
||||
{
|
||||
return CatchResponse::success($excel->save($userExport, Utils::publicPath('export/users')));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新个人信息
|
||||
*
|
||||
* @time 2020年09月20日
|
||||
* @param Request $request
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function profile(Request $request)
|
||||
{
|
||||
return CatchResponse::success($this->user->updateBy($request->user()->id, $request->param()));
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
use think\migration\Migrator;
|
||||
use think\migration\db\Column;
|
||||
|
||||
class UpdateRoles extends Migrator
|
||||
{
|
||||
/**
|
||||
* Change Method.
|
||||
*
|
||||
* Write your reversible migrations using this method.
|
||||
*
|
||||
* More information on writing migrations is available here:
|
||||
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
|
||||
*
|
||||
* The following commands can be used in this method and Phinx will
|
||||
* automatically reverse them when rolling back:
|
||||
*
|
||||
* createTable
|
||||
* renameTable
|
||||
* addColumn
|
||||
* renameColumn
|
||||
* addIndex
|
||||
* addForeignKey
|
||||
*
|
||||
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||
* with the Table class.
|
||||
*/
|
||||
public function change()
|
||||
{
|
||||
if ($this->hasTable('roles')) {
|
||||
$table = $this->table('roles');
|
||||
|
||||
$table->addColumn('identify', 'string', [
|
||||
'limit' => 20,
|
||||
'default' => 1,
|
||||
'comment' => '角色的标识,用英文表示,用于后台路由权限',
|
||||
'after' => 'role_name'])
|
||||
->update();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
use think\migration\Migrator;
|
||||
use think\migration\db\Column;
|
||||
|
||||
class UpdatePermissions extends Migrator
|
||||
{
|
||||
/**
|
||||
* Change Method.
|
||||
*
|
||||
* Write your reversible migrations using this method.
|
||||
*
|
||||
* More information on writing migrations is available here:
|
||||
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
|
||||
*
|
||||
* The following commands can be used in this method and Phinx will
|
||||
* automatically reverse them when rolling back:
|
||||
*
|
||||
* createTable
|
||||
* renameTable
|
||||
* addColumn
|
||||
* renameColumn
|
||||
* addIndex
|
||||
* addForeignKey
|
||||
*
|
||||
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||
* with the Table class.
|
||||
*/
|
||||
public function change()
|
||||
{
|
||||
if ($this->hasTable('permissions')) {
|
||||
$table = $this->table('permissions');
|
||||
|
||||
$table->removeColumn('method')
|
||||
->removeColumn('hide_children_in_menu')
|
||||
->renameColumn('status', 'hidden')
|
||||
->update();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~{$year} http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
use think\migration\Migrator;
|
||||
use think\migration\db\Column;
|
||||
|
||||
class AddUserAvatar extends Migrator
|
||||
{
|
||||
/**
|
||||
* Change Method.
|
||||
*
|
||||
* Write your reversible migrations using this method.
|
||||
*
|
||||
* More information on writing migrations is available here:
|
||||
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
|
||||
*
|
||||
* The following commands can be used in this method and Phinx will
|
||||
* automatically reverse them when rolling back:
|
||||
*
|
||||
* createTable
|
||||
* renameTable
|
||||
* addColumn
|
||||
* renameColumn
|
||||
* addIndex
|
||||
* addForeignKey
|
||||
*
|
||||
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||
* with the Table class.
|
||||
*/
|
||||
public function change()
|
||||
{
|
||||
if ($this->hasTable('users')) {
|
||||
$table = $this->table('users');
|
||||
|
||||
$table->addColumn('avatar', 'string', [
|
||||
'limit' => 255,
|
||||
'default' => '',
|
||||
'comment' => '用户头像',
|
||||
'after' => 'email'])
|
||||
->update();
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,7 +2,7 @@
|
||||
|
||||
use think\migration\Seeder;
|
||||
|
||||
class PermissionSeed extends Seeder
|
||||
class PermissionsMenusSeed extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run Method.
|
||||
@@ -27,20 +27,18 @@ class PermissionSeed extends Seeder
|
||||
'parent_id' => 0,
|
||||
'level' => '',
|
||||
'route' => '/permissions',
|
||||
'icon' => 'appstore',
|
||||
'icon' => 'el-icon-cpu',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'permission@index',
|
||||
'component' => 'pageView',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 2,
|
||||
'permission_mark' => 'permission',
|
||||
'component' => 'layout',
|
||||
'redirect' => '/permissions/users',
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'status' => 1,
|
||||
'sort' => 100,
|
||||
'created_at' => 1587461455,
|
||||
'updated_at' => 1593044101,
|
||||
'updated_at' => 1599362429,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array (
|
||||
@@ -51,20 +49,18 @@ class PermissionSeed extends Seeder
|
||||
'parent_id' => 1,
|
||||
'level' => '1',
|
||||
'route' => '/permissions/users',
|
||||
'icon' => 'user',
|
||||
'icon' => 'el-icon-user',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'user@index',
|
||||
'permission_mark' => 'user',
|
||||
'component' => 'users',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 2,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'status' => 1,
|
||||
'sort' => 10,
|
||||
'created_at' => 1587461597,
|
||||
'updated_at' => 1592371975,
|
||||
'updated_at' => 1599362429,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array (
|
||||
@@ -78,17 +74,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'user@index',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587461647,
|
||||
'updated_at' => 1591316160,
|
||||
'updated_at' => 1599030266,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
1 =>
|
||||
@@ -101,17 +95,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'user@create',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587461696,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1599030266,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
2 =>
|
||||
@@ -124,17 +116,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'user@save',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587461721,
|
||||
'updated_at' => 1591345475,
|
||||
'updated_at' => 1599030266,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
3 =>
|
||||
@@ -147,17 +137,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'user@edit',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587461742,
|
||||
'updated_at' => 1591345504,
|
||||
'updated_at' => 1599030266,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
4 =>
|
||||
@@ -170,17 +158,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'user@update',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587461762,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1599030266,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
5 =>
|
||||
@@ -193,17 +179,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'user@delete',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587461841,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1599030266,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
6 =>
|
||||
@@ -216,17 +200,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'user@switchStatus',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587461876,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1599030266,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
7 =>
|
||||
@@ -239,17 +221,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'user@recover',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587461901,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1599030266,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
||||
@@ -261,20 +241,18 @@ class PermissionSeed extends Seeder
|
||||
'parent_id' => 1,
|
||||
'level' => '1',
|
||||
'route' => '/permissions/roles',
|
||||
'icon' => 'usergroup-add',
|
||||
'icon' => 'el-icon-s-custom',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'role@index',
|
||||
'permission_mark' => 'role',
|
||||
'component' => 'roles',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 2,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'status' => 1,
|
||||
'sort' => 9,
|
||||
'created_at' => 1587461939,
|
||||
'updated_at' => 1592371974,
|
||||
'updated_at' => 1599362438,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array (
|
||||
@@ -288,17 +266,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'role@index',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587461984,
|
||||
'updated_at' => 1591341461,
|
||||
'updated_at' => 1599362438,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
1 =>
|
||||
@@ -311,17 +287,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'role@create',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587462007,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1599362438,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
2 =>
|
||||
@@ -334,17 +308,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'role@save',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587462021,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1599362438,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
3 =>
|
||||
@@ -357,17 +329,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'role@edit',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587462040,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1599362438,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
4 =>
|
||||
@@ -380,17 +350,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'role@update',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587462058,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1599362438,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
5 =>
|
||||
@@ -403,17 +371,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'role@delete',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587462070,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1599362438,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
6 =>
|
||||
@@ -426,17 +392,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'role@getPermissions',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587462094,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1599362438,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
||||
@@ -448,20 +412,18 @@ class PermissionSeed extends Seeder
|
||||
'parent_id' => 1,
|
||||
'level' => '1',
|
||||
'route' => '/permissions/rules',
|
||||
'icon' => 'build',
|
||||
'icon' => 'el-icon-collection-tag',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'permission@index',
|
||||
'permission_mark' => 'permission',
|
||||
'component' => 'rules',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 2,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'status' => 1,
|
||||
'sort' => 8,
|
||||
'created_at' => 1587462147,
|
||||
'updated_at' => 1592371979,
|
||||
'updated_at' => 1599362475,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array (
|
||||
@@ -475,17 +437,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'permission@index',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587462205,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1599362475,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
1 =>
|
||||
@@ -498,17 +458,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'permission@create',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587462232,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1599362475,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
2 =>
|
||||
@@ -521,40 +479,36 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'permission@save',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587462250,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1599362475,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
'id' => 23,
|
||||
'permission_name' => '查看',
|
||||
'permission_name' => '禁用/启用',
|
||||
'parent_id' => 19,
|
||||
'level' => '1-19',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'permission@edit',
|
||||
'permission_mark' => 'permission@show',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587462273,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1599362475,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
4 =>
|
||||
@@ -567,17 +521,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'permission@update',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587462284,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1599362475,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
5 =>
|
||||
@@ -590,17 +542,36 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'permission@delete',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587462296,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1599362475,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
'id' => 106,
|
||||
'permission_name' => '权限方法',
|
||||
'parent_id' => 19,
|
||||
'level' => '1-19',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'permission@getMethods',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'sort' => 1,
|
||||
'created_at' => 1599221913,
|
||||
'updated_at' => 1599362475,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
||||
@@ -612,20 +583,18 @@ class PermissionSeed extends Seeder
|
||||
'parent_id' => 1,
|
||||
'level' => '1',
|
||||
'route' => '/permissions/departments',
|
||||
'icon' => 'desktop',
|
||||
'icon' => 'el-icon-monitor',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'departments',
|
||||
'component' => 'departments',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 2,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'status' => 1,
|
||||
'sort' => 7,
|
||||
'created_at' => 1587462488,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1599362429,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array (
|
||||
@@ -639,17 +608,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'department@index',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587462529,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1599030565,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
1 =>
|
||||
@@ -662,17 +629,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'department@save',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587462548,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1599030565,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
2 =>
|
||||
@@ -685,17 +650,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'department@update',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587462579,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1599030565,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
3 =>
|
||||
@@ -708,17 +671,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'department@delete',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587462592,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1599030565,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
||||
@@ -730,20 +691,18 @@ class PermissionSeed extends Seeder
|
||||
'parent_id' => 1,
|
||||
'level' => '1',
|
||||
'route' => '/permissions/jobs',
|
||||
'icon' => 'skin',
|
||||
'icon' => 'el-icon-setting',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'job',
|
||||
'component' => 'jobs',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 2,
|
||||
'hidden' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587462707,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1599362429,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array (
|
||||
@@ -757,17 +716,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'job@index',
|
||||
'permission_mark' => 'job@indexs',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 2,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587462757,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1598959522,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
1 =>
|
||||
@@ -780,17 +737,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'job@save',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 2,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587462774,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1598959522,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
2 =>
|
||||
@@ -803,17 +758,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'job@update',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 2,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587462785,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1598959522,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
3 =>
|
||||
@@ -826,17 +779,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'job@delete',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 2,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587462794,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1598959522,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
4 =>
|
||||
@@ -849,17 +800,15 @@ class PermissionSeed extends Seeder
|
||||
'icon' => '',
|
||||
'module' => 'permissions',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'job@getAll',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'hidden' => 2,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587462818,
|
||||
'updated_at' => 1587547118,
|
||||
'updated_at' => 1598959522,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
@@ -24,7 +24,9 @@ class RolesSeed extends Seeder
|
||||
{
|
||||
\catchAdmin\permissions\model\Roles::create([
|
||||
'role_name' => '超级管理员',
|
||||
'identify' => 'admin',
|
||||
'description' => 'super user',
|
||||
'data_range' => 1,
|
||||
'creator_id' => 1,
|
||||
]);
|
||||
|
||||
|
@@ -16,8 +16,8 @@ class UsersSeed extends Seeder
|
||||
{
|
||||
return \catchAdmin\permissions\model\Users::create([
|
||||
'username' => 'admin',
|
||||
'password' => 'admin',
|
||||
'email' => 'admin@gmail.com',
|
||||
'password' => 'catchadmin',
|
||||
'email' => 'catch@admin.com',
|
||||
'creator_id' => 1,
|
||||
]);
|
||||
}
|
||||
|
78
catch/permissions/excel/UserExport.php
Normal file
78
catch/permissions/excel/UserExport.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
namespace catchAdmin\permissions\excel;
|
||||
|
||||
use catchAdmin\permissions\model\Users;
|
||||
use catcher\library\excel\ExcelContract;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||||
|
||||
class UserExport implements ExcelContract
|
||||
{
|
||||
|
||||
/**
|
||||
* 设置头部
|
||||
*
|
||||
* @time 2020年09月08日
|
||||
* @return string[]
|
||||
*/
|
||||
public function headers(): array
|
||||
{
|
||||
// TODO: Implement headers() method.
|
||||
return [
|
||||
'id', '用户名', '邮箱', '状态', '创建日期'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理数据
|
||||
*
|
||||
* @time 2020年09月08日
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @return \think\Collection
|
||||
*/
|
||||
public function sheets()
|
||||
{
|
||||
// TODO: Implement sheets() method.
|
||||
$users = Users::field(['id', 'username', 'email', 'status', 'created_at'])->select();
|
||||
|
||||
foreach ($users as &$user) {
|
||||
$user->status = $user->status == Users::ENABLE ? '启用' : '停用';
|
||||
}
|
||||
|
||||
return $users;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置开始行
|
||||
*
|
||||
* @time 2020年09月08日
|
||||
* @return int
|
||||
*/
|
||||
public function setRow()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置标题
|
||||
*
|
||||
* @time 2020年09月08日
|
||||
* @return array
|
||||
*/
|
||||
public function setTitle()
|
||||
{
|
||||
return [
|
||||
'A1:G1', '导出用户', Alignment::HORIZONTAL_CENTER
|
||||
];
|
||||
}
|
||||
}
|
@@ -32,6 +32,7 @@ class PermissionsMiddleware
|
||||
|
||||
// 模块忽略
|
||||
[$module, $controller, $action] = Utils::parseRule($rule);
|
||||
|
||||
// toad
|
||||
if (in_array($module, $this->ignoreModule())) {
|
||||
return $next($request);
|
||||
@@ -42,11 +43,11 @@ class PermissionsMiddleware
|
||||
throw new PermissionForbiddenException('Login is invalid', Code::LOST_LOGIN);
|
||||
}
|
||||
// 超级管理员
|
||||
if ($request->user()->id === config('catch.permissions.super_admin_id')) {
|
||||
if (Utils::isSuperAdmin()) {
|
||||
return $next($request);
|
||||
}
|
||||
// Get 请求
|
||||
if ($request->isGet() && config('catch.permissions.is_allow_get')) {
|
||||
if ($this->allowGet($request)) {
|
||||
return $next($request);
|
||||
}
|
||||
// 判断权限
|
||||
@@ -106,4 +107,21 @@ class PermissionsMiddleware
|
||||
'permission' => $permission,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* get allow
|
||||
*
|
||||
* @time 2020年10月12日
|
||||
* @param $request
|
||||
* @return bool
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
protected function allowGet($request)
|
||||
{
|
||||
if (Utils::isMethodNeedAuth($request->rule()->getName())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $request->isGet() && config('catch.permissions.is_allow_get');
|
||||
}
|
||||
}
|
||||
|
@@ -13,7 +13,7 @@ trait DataRangScopeTrait
|
||||
* @author JaguarJack <njphper@gmail.com>
|
||||
* @date 2020/6/6
|
||||
*/
|
||||
protected function dataRange($roles)
|
||||
public function dataRange($roles = [])
|
||||
{
|
||||
if (Utils::isSuperAdmin()) {
|
||||
return $this;
|
||||
@@ -44,6 +44,10 @@ trait DataRangScopeTrait
|
||||
|
||||
$user = request()->user();
|
||||
|
||||
if (empty($roles)) {
|
||||
$roles = $user->getRoles();
|
||||
}
|
||||
|
||||
foreach ($roles as $role) {
|
||||
switch ($role->data_range) {
|
||||
case Roles::ALL_DATA:
|
||||
@@ -57,6 +61,11 @@ trait DataRangScopeTrait
|
||||
$userIds[] = $user->id;
|
||||
break;
|
||||
case Roles::DEPARTMENT_DOWN_DATA:
|
||||
// 查一下下级部门
|
||||
$departmentIds = Department::where('parent_id', $user->department_id)->column('id');
|
||||
$departmentIds[] = $user->department_id;
|
||||
$userIds = array_merge([$user->id], $this->getUserIdsByDepartmentId($departmentIds));
|
||||
break;
|
||||
case Roles::DEPARTMENT_DATA:
|
||||
$userIds = array_merge($userIds, $this->getUserIdsByDepartmentId([$user->department_id]));
|
||||
break;
|
||||
|
@@ -3,6 +3,7 @@ namespace catchAdmin\permissions\model;
|
||||
|
||||
use catchAdmin\permissions\model\search\DepartmentSearch;
|
||||
use catcher\base\CatchModel;
|
||||
use think\db\exception\DbException;
|
||||
|
||||
class Department extends CatchModel
|
||||
{
|
||||
@@ -29,16 +30,13 @@ class Department extends CatchModel
|
||||
* 列表数据
|
||||
*
|
||||
* @time 2020年01月09日
|
||||
* @param $params
|
||||
* @return array
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws DbException
|
||||
*/
|
||||
public function getList(): array
|
||||
{
|
||||
return $this->withoutField(['department_name'])
|
||||
->addFields(['department_name as title'])
|
||||
->catchSearch()
|
||||
return $this->catchSearch()
|
||||
->catchOrder()
|
||||
->select()->toArray();
|
||||
->select()->toTree();
|
||||
}
|
||||
}
|
||||
|
@@ -19,12 +19,10 @@ class Permissions extends CatchModel
|
||||
'component', // 组件
|
||||
'redirect',
|
||||
'keepalive',
|
||||
'hide_children_in_menu',
|
||||
'creator_id',
|
||||
'status',
|
||||
'hidden',
|
||||
'module', // 模块
|
||||
'route', // 路由
|
||||
'method', // 请求方法
|
||||
'permission_mark', // 权限标识
|
||||
'type', // 1 菜单 2 按钮
|
||||
'sort', // 排序字段
|
||||
@@ -71,7 +69,7 @@ class Permissions extends CatchModel
|
||||
return parent::whereIn('id', $permissionIds)
|
||||
->field(['permission_name as title', 'id', 'parent_id',
|
||||
'route', 'icon', 'component', 'redirect', 'module',
|
||||
'keepalive as keepAlive', 'hide_children_in_menu', 'type', 'permission_mark', 'status'
|
||||
'keepalive as keepAlive', 'type', 'permission_mark', 'hidden'
|
||||
])
|
||||
->catchOrder()
|
||||
->select();
|
||||
@@ -101,4 +99,44 @@ class Permissions extends CatchModel
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public function show($id)
|
||||
{
|
||||
$permission = $this->findBy($id);
|
||||
|
||||
// 不能使用改属性判断,模型有该属性,使用数组方式
|
||||
// $permission->hidden
|
||||
$hidden = $permission['hidden'] == Permissions::ENABLE ? Permissions::DISABLE : Permissions::ENABLE;
|
||||
|
||||
$nextLevelIds = $this->getNextLevel([$id]);
|
||||
|
||||
$nextLevelIds[] = $id;
|
||||
|
||||
return $this->whereIn('id', $nextLevelIds)->update([
|
||||
'hidden' => $hidden,
|
||||
'updated_at' => time(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 level ids
|
||||
*
|
||||
* @time 2020年09月06日
|
||||
* @param array $id
|
||||
* @param array $ids
|
||||
* @return array
|
||||
*/
|
||||
protected function getNextLevel(array $id, &$ids = [])
|
||||
{
|
||||
$_ids = $this->whereIn('parent_id', $id)
|
||||
->where('type', self::MENU_TYPE)
|
||||
->column('id');
|
||||
|
||||
if (count($_ids)) {
|
||||
$ids = array_merge($_ids, $this->getNextLevel($_ids, $ids));
|
||||
}
|
||||
|
||||
return $ids;
|
||||
}
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@ class Roles extends CatchModel
|
||||
protected $field = [
|
||||
'id', //
|
||||
'role_name', // 角色名
|
||||
'identify', // 身份标识
|
||||
'parent_id', // 父级ID
|
||||
'creator_id', // 创建者
|
||||
'data_range', // 数据范围
|
||||
@@ -36,7 +37,7 @@ class Roles extends CatchModel
|
||||
return $this->catchSearch()
|
||||
->order('id', 'desc')
|
||||
->select()
|
||||
->toArray();
|
||||
->toTree();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -19,6 +19,7 @@ class Users extends CatchModel
|
||||
'username', // 用户名
|
||||
'password', // 用户密码
|
||||
'email', // 邮箱 登录
|
||||
'avatar', // 头像
|
||||
'creator_id', // 创建者ID
|
||||
'department_id', // 部门ID
|
||||
'status', // 用户状态 1 正常 2 禁用
|
||||
|
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
namespace catchAdmin\permissions\model\search;
|
||||
|
||||
use catchAdmin\permissions\model\Department;
|
||||
|
||||
trait UserSearch
|
||||
{
|
||||
public function searchUsernameAttr($query, $value, $data)
|
||||
@@ -20,6 +22,8 @@ trait UserSearch
|
||||
|
||||
public function searchDepartmentIdAttr($query, $value, $data)
|
||||
{
|
||||
return $query->where($this->aliasField('department_id'), $value);
|
||||
$departmentIds = Department::where('parent_id', $value)->column('id');
|
||||
$departmentIds[] = $value;
|
||||
return $query->whereIn($this->aliasField('department_id'), $departmentIds);
|
||||
}
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@
|
||||
"description": "权限管理模块",
|
||||
"version": "1.0.0",
|
||||
"keywords": [],
|
||||
"order": 2,
|
||||
"order": 100,
|
||||
"services": [
|
||||
"\\catchAdmin\\permissions\\PermissionService"
|
||||
],
|
||||
|
@@ -17,7 +17,7 @@ class CreateRequest extends CatchRequest
|
||||
];
|
||||
}
|
||||
|
||||
protected function message(): array
|
||||
protected function message()
|
||||
{
|
||||
// TODO: Implement message() method.
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@ class UpdateRequest extends CatchRequest
|
||||
];
|
||||
}
|
||||
|
||||
protected function message(): array
|
||||
protected function message()
|
||||
{
|
||||
// TODO: Implement message() method.
|
||||
}
|
||||
|
@@ -21,6 +21,8 @@ $router->group(function () use ($router){
|
||||
// 切换状态
|
||||
$router->put('users/switch/status/<id>', '\catchAdmin\permissions\controller\User@switchStatus');
|
||||
$router->put('users/recover/<id>', '\catchAdmin\permissions\controller\User@recover');
|
||||
$router->put('user/profile', '\catchAdmin\permissions\controller\User@profile');
|
||||
$router->get('users/get/roles', '\catchAdmin\permissions\controller\User@getRoles');
|
||||
$router->get('user/info', '\catchAdmin\permissions\controller\User@info');
|
||||
$router->get('user/export', '\catchAdmin\permissions\controller\User@export');
|
||||
})->middleware('auth');
|
226
catch/sms/Sms.php
Normal file
226
catch/sms/Sms.php
Normal file
@@ -0,0 +1,226 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
namespace catchAdmin\sms;
|
||||
|
||||
use catchAdmin\sms\model\SmsConfig;
|
||||
use catcher\exceptions\FailedException;
|
||||
use Overtrue\EasySms\EasySms;
|
||||
use think\helper\Str;
|
||||
|
||||
class Sms
|
||||
{
|
||||
/**
|
||||
* timeout http 请求时间
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $timeout = 5;
|
||||
|
||||
/**
|
||||
* 错误日志
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $errorLog;
|
||||
|
||||
/**
|
||||
* 网关
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $gateways = [];
|
||||
|
||||
/**
|
||||
* 配置
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $config = [];
|
||||
|
||||
/**
|
||||
* 发送数据
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $sendData = [];
|
||||
|
||||
/**
|
||||
* Sms constructor.
|
||||
* @param $config
|
||||
*/
|
||||
public function __construct(array $config)
|
||||
{
|
||||
$config['timeout'] = $this->timeout;
|
||||
|
||||
$config['gateways']['errorlog'] = runtime_path('log') . 'sms.log';
|
||||
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送
|
||||
*
|
||||
* @time 2020年09月17日
|
||||
* @param string $phone
|
||||
* @param array $data
|
||||
* @return mixed
|
||||
* @throws \Overtrue\EasySms\Exceptions\NoGatewayAvailableException
|
||||
* @throws \Overtrue\EasySms\Exceptions\InvalidArgumentException
|
||||
*/
|
||||
public function send(string $phone, array $data)
|
||||
{
|
||||
try {
|
||||
$this->sendData['data'] = $data;
|
||||
|
||||
return $this->easySms()
|
||||
->send($phone, $this->sendData);
|
||||
} catch (\Exception $exception) {
|
||||
throw new FailedException($exception->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* easy sms
|
||||
*
|
||||
* @time 2020年09月17日
|
||||
* @return EasySms
|
||||
*/
|
||||
public function easySms()
|
||||
{
|
||||
return new EasySms($this->config);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 内容
|
||||
*
|
||||
* @time 2020年09月17日
|
||||
* @param $content
|
||||
* @param string $key
|
||||
* @return $this
|
||||
*/
|
||||
public function content($content, $key = 'content')
|
||||
{
|
||||
$this->sendData[$key] = $content;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 模版
|
||||
*
|
||||
* @time 2020年09月17日
|
||||
* @param $template
|
||||
* @param string $key
|
||||
* @return $this
|
||||
*/
|
||||
public function template($template, $key = 'template')
|
||||
{
|
||||
$this->sendData[$key] = $template;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 超时间时间 s
|
||||
*
|
||||
* @time 2020年09月17日
|
||||
* @param int $timeout
|
||||
* @return $this
|
||||
*/
|
||||
public function timeout(int $timeout)
|
||||
{
|
||||
$this->config['timeout'] = $timeout;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 记录记录地址
|
||||
*
|
||||
* @time 2020年09月17日
|
||||
* @param string $log
|
||||
* @return $this
|
||||
*/
|
||||
public function errorLog(string $log)
|
||||
{
|
||||
$this->config['gateways']['errorlog'] = $log;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* gateways config
|
||||
*
|
||||
* @time 2020年09月17日
|
||||
* @param $gateways
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @return array
|
||||
*/
|
||||
protected static function getGatewaysConfig($gateways)
|
||||
{
|
||||
$gatewaysConfig = [];
|
||||
|
||||
$smsConfig = new SmsConfig();
|
||||
|
||||
foreach ($gateways as $gate) {
|
||||
$c = $smsConfig->findByName($gate);
|
||||
|
||||
if ($c) {
|
||||
$c->hasConfig()
|
||||
->select()
|
||||
->each(function ($item) use (&$gatewaysConfig, $gate){
|
||||
$gatewaysConfig[$gate][$item['key']] = $item['value'];
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $gatewaysConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* sms
|
||||
*
|
||||
* @time 2020年09月17日
|
||||
* @param $method
|
||||
* @param $arg
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @return Sms
|
||||
*/
|
||||
public static function __callStatic($method, $arg)
|
||||
{
|
||||
$gateways = Str::snake($method);
|
||||
|
||||
if (Str::contains($gateways, '_')) {
|
||||
$gateways = explode('_', $gateways);
|
||||
} else {
|
||||
$gateways = [$gateways];
|
||||
}
|
||||
|
||||
$config = [
|
||||
'default' => [
|
||||
'gateways' => $gateways,
|
||||
],
|
||||
|
||||
'gateways' => static::getGatewaysConfig($gateways)
|
||||
];
|
||||
|
||||
|
||||
return new self($config);
|
||||
}
|
||||
}
|
23
catch/sms/SmsService.php
Normal file
23
catch/sms/SmsService.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~{$year} http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace catchAdmin\sms;
|
||||
|
||||
use catcher\ModuleService;
|
||||
|
||||
class SmsService extends ModuleService
|
||||
{
|
||||
public function loadRouteFrom()
|
||||
{
|
||||
// TODO: Implement loadRouteFrom() method.
|
||||
return __DIR__ . DIRECTORY_SEPARATOR . 'route.php';
|
||||
}
|
||||
}
|
89
catch/sms/controller/Config.php
Normal file
89
catch/sms/controller/Config.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace catchAdmin\sms\controller;
|
||||
|
||||
use catcher\base\CatchRequest as Request;
|
||||
use catcher\CatchResponse;
|
||||
use catcher\base\CatchController;
|
||||
use catchAdmin\sms\model\SmsConfig as SmsConfigModel;
|
||||
|
||||
class Config extends CatchController
|
||||
{
|
||||
protected $model;
|
||||
|
||||
public function __construct(SmsConfigModel $model)
|
||||
{
|
||||
$this->model = $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*
|
||||
* @time 2020/09/16 17:28
|
||||
*
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return CatchResponse::paginate($this->model->getList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*
|
||||
* @time 2020/09/16 17:28
|
||||
* @param Request Request
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function save(Request $request)
|
||||
{
|
||||
return CatchResponse::success($this->model->storeBy($request->param()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取
|
||||
*
|
||||
* @time 2020/09/16 17:28
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function read($id)
|
||||
{
|
||||
return CatchResponse::success($this->model->findBy($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新
|
||||
*
|
||||
* @time 2020/09/16 17:28
|
||||
* @param Request $request
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
return CatchResponse::success($this->model->updateBy($id, $request->post()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @time 2020/09/16 17:28
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
return CatchResponse::success($this->model->deleteBy($id));
|
||||
}
|
||||
|
||||
|
||||
}
|
86
catch/sms/controller/Template.php
Normal file
86
catch/sms/controller/Template.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
namespace catchAdmin\sms\controller;
|
||||
|
||||
use catcher\base\CatchRequest as Request;
|
||||
use catcher\CatchResponse;
|
||||
use catcher\base\CatchController;
|
||||
use catchAdmin\sms\model\SmsTemplate as SmsTemplateModel;
|
||||
|
||||
class Template extends CatchController
|
||||
{
|
||||
protected $model;
|
||||
|
||||
public function __construct(SmsTemplateModel $model)
|
||||
{
|
||||
$this->model = $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*
|
||||
* @time 2020/09/16 17:28
|
||||
*
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return CatchResponse::success($this->model->getList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*
|
||||
* @time 2020/09/16 17:28
|
||||
* @param Request Request
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function save(Request $request)
|
||||
{
|
||||
return CatchResponse::success($this->model->storeBy($request->param()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取
|
||||
*
|
||||
* @time 2020/09/16 17:28
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function read($id)
|
||||
{
|
||||
return CatchResponse::success($this->model->findBy($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新
|
||||
*
|
||||
* @time 2020/09/16 17:28
|
||||
* @param Request $request
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
return CatchResponse::success($this->model->updateBy($id, $request->post()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @time 2020/09/16 17:28
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
return CatchResponse::success($this->model->deleteBy($id));
|
||||
}
|
||||
}
|
43
catch/sms/database/migrations/20200916172849_sms_config.php
Normal file
43
catch/sms/database/migrations/20200916172849_sms_config.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
use think\migration\Migrator;
|
||||
use think\migration\db\Column;
|
||||
use Phinx\Db\Adapter\MysqlAdapter;
|
||||
|
||||
class SmsConfig extends Migrator
|
||||
{
|
||||
/**
|
||||
* Change Method.
|
||||
*
|
||||
* Write your reversible migrations using this method.
|
||||
*
|
||||
* More information on writing migrations is available here:
|
||||
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
|
||||
*
|
||||
* The following commands can be used in this method and Phinx will
|
||||
* automatically reverse them when rolling back:
|
||||
*
|
||||
* createTable
|
||||
* renameTable
|
||||
* addColumn
|
||||
* renameColumn
|
||||
* addIndex
|
||||
* addForeignKey
|
||||
*
|
||||
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||
* with the Table class.
|
||||
*/
|
||||
public function change()
|
||||
{
|
||||
$table = $this->table('sms_config', ['engine' => 'InnoDB', 'collation' => 'utf8mb4_general_ci', 'comment' => 'sms 配置' ,'id' => 'id','signed' => true ,'primary_key' => ['id']]);
|
||||
$table->addColumn('name', 'string', ['limit' => 50,'null' => true,'signed' => false,'comment' => '运营商名称',])
|
||||
->addColumn('pid', 'integer', ['limit' => MysqlAdapter::INT_SMALL,'null' => false,'default' => 0,'signed' => false,'comment' => '父级ID',])
|
||||
->addColumn('key', 'string', ['limit' => 100,'null' => false,'default' => '','signed' => false,'comment' => 'key',])
|
||||
->addColumn('value', 'string', ['limit' => 255,'null' => false,'default' => '','signed' => false,'comment' => 'value',])
|
||||
->addColumn('creator_id', 'integer', ['limit' => MysqlAdapter::INT_REGULAR,'null' => false,'default' => 0,'signed' => true,'comment' => '创建人ID',])
|
||||
->addColumn('created_at', 'integer', ['limit' => MysqlAdapter::INT_REGULAR,'null' => false,'default' => 0,'signed' => true,'comment' => '创建时间',])
|
||||
->addColumn('updated_at', 'integer', ['limit' => MysqlAdapter::INT_REGULAR,'null' => false,'default' => 0,'signed' => true,'comment' => '更新时间',])
|
||||
->addColumn('deleted_at', 'integer', ['limit' => MysqlAdapter::INT_REGULAR,'null' => false,'default' => 0,'signed' => true,'comment' => '软删除',])
|
||||
->create();
|
||||
}
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
use think\migration\Migrator;
|
||||
use think\migration\db\Column;
|
||||
use Phinx\Db\Adapter\MysqlAdapter;
|
||||
|
||||
class SmsTemplate extends Migrator
|
||||
{
|
||||
/**
|
||||
* Change Method.
|
||||
*
|
||||
* Write your reversible migrations using this method.
|
||||
*
|
||||
* More information on writing migrations is available here:
|
||||
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
|
||||
*
|
||||
* The following commands can be used in this method and Phinx will
|
||||
* automatically reverse them when rolling back:
|
||||
*
|
||||
* createTable
|
||||
* renameTable
|
||||
* addColumn
|
||||
* renameColumn
|
||||
* addIndex
|
||||
* addForeignKey
|
||||
*
|
||||
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||
* with the Table class.
|
||||
*/
|
||||
public function change()
|
||||
{
|
||||
$table = $this->table('sms_template', ['engine' => 'InnoDB', 'collation' => 'utf8mb4_general_ci', 'comment' => '短信模版' ,'id' => 'id','signed' => true ,'primary_key' => ['id']]);
|
||||
$table->addColumn('operator', 'string', ['limit' => 50,'null' => false,'default' => '','signed' => false,'comment' => '运营商',])
|
||||
->addColumn('name', 'string', ['limit' => 50,'null' => false,'default' => '','signed' => false,'comment' => '模版名称',])
|
||||
->addColumn('identify', 'string', ['limit' => 50,'null' => false,'default' => '','signed' => false,'comment' => '模版标识',])
|
||||
->addColumn('code', 'string', ['limit' => 100,'null' => false,'default' => '','signed' => false,'comment' => '模版CODE',])
|
||||
->addColumn('creator_id', 'integer', ['limit' => MysqlAdapter::INT_REGULAR,'null' => false,'default' => 0,'signed' => true,'comment' => '创建人ID',])
|
||||
->addColumn('created_at', 'integer', ['limit' => MysqlAdapter::INT_REGULAR,'null' => false,'default' => 0,'signed' => true,'comment' => '创建时间',])
|
||||
->addColumn('updated_at', 'integer', ['limit' => MysqlAdapter::INT_REGULAR,'null' => false,'default' => 0,'signed' => true,'comment' => '更新时间',])
|
||||
->addColumn('deleted_at', 'integer', ['limit' => MysqlAdapter::INT_REGULAR,'null' => false,'default' => 0,'signed' => true,'comment' => '软删除',])
|
||||
->create();
|
||||
}
|
||||
}
|
79
catch/sms/database/seeds/SmsMenusSeed.php
Normal file
79
catch/sms/database/seeds/SmsMenusSeed.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~{$year} http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
use think\migration\Seeder;
|
||||
|
||||
class SmsMenusSeed extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run Method.
|
||||
*
|
||||
* Write your database seeder using this method.
|
||||
*
|
||||
* More information on writing seeders is available here:
|
||||
* http://docs.phinx.org/en/latest/seeding.html
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
\catcher\Utils::importTreeData($this->getPermissions(), 'permissions', 'parent_id');
|
||||
}
|
||||
|
||||
protected function getPermissions()
|
||||
{
|
||||
return array (
|
||||
0 =>
|
||||
array (
|
||||
'id' => 113,
|
||||
'permission_name' => '短信管理',
|
||||
'parent_id' => 0,
|
||||
'level' => '',
|
||||
'route' => '/sms',
|
||||
'icon' => 'el-icon-s-promotion',
|
||||
'module' => 'sms',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'sms',
|
||||
'component' => 'layout',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1600229598,
|
||||
'updated_at' => 1600229598,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
'id' => 114,
|
||||
'permission_name' => '短信配置',
|
||||
'parent_id' => 113,
|
||||
'level' => '113',
|
||||
'route' => '/sms/config',
|
||||
'icon' => 'el-icon-copy-document',
|
||||
'module' => 'sms',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'sms',
|
||||
'component' => 'sms',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1600229654,
|
||||
'updated_at' => 1600229778,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
141
catch/sms/model/SmsConfig.php
Normal file
141
catch/sms/model/SmsConfig.php
Normal file
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace catchAdmin\sms\model;
|
||||
|
||||
use catcher\base\CatchModel as Model;
|
||||
|
||||
class SmsConfig extends Model
|
||||
{
|
||||
protected $name = 'sms_config';
|
||||
|
||||
protected $field = [
|
||||
'id', //
|
||||
'name', // 运营商名称
|
||||
'pid', // 父级ID
|
||||
'key', // key
|
||||
'value', // value
|
||||
'creator_id', // 创建人ID
|
||||
'created_at', // 创建时间
|
||||
'updated_at', // 更新时间
|
||||
'deleted_at', // 软删除
|
||||
];
|
||||
|
||||
public function hasConfig()
|
||||
{
|
||||
return $this->hasMany(SmsConfig::class, 'pid', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*
|
||||
* @time 2020年09月16日
|
||||
* @param array $data
|
||||
* @return bool|int
|
||||
*/
|
||||
public function storeBy(array $data)
|
||||
{
|
||||
$config = $this->findByName($data['name']);
|
||||
|
||||
if ($config) {
|
||||
unset($data['name']);
|
||||
$hasConfig = $config->hasConfig()->select();
|
||||
if (empty($hasConfig)) {
|
||||
return $this->insertConfig($config->id, $data);
|
||||
}
|
||||
$this->deleteBy(array_column($hasConfig->toArray(), 'id'), true);
|
||||
$this->insertConfig($config->id, $data);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (parent::storeBy([
|
||||
'name' => $data['name']
|
||||
])) {
|
||||
unset($data['name']);
|
||||
$this->insertConfig($this->id, $data);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增配置
|
||||
*
|
||||
* @time 2020年09月16日
|
||||
* @param $pid
|
||||
* @param $data
|
||||
* @return int
|
||||
*/
|
||||
protected function insertConfig($pid, $data)
|
||||
{
|
||||
$config = [];
|
||||
|
||||
$creatorId = $data['creator_id'];
|
||||
unset($data['creator_id']);
|
||||
|
||||
foreach ($data as $k => $v) {
|
||||
$config[] = [
|
||||
'key' => $k,
|
||||
'value' => $v,
|
||||
'pid' => $pid,
|
||||
'creator_id' => $creatorId,
|
||||
'created_at' => time(),
|
||||
'updated_at' => time(),
|
||||
];
|
||||
}
|
||||
|
||||
return $this->insertAll($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 name 查找
|
||||
*
|
||||
* @time 2020年09月16日
|
||||
* @param $name
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @return array|\think\Model|null
|
||||
*/
|
||||
public function findByName($name)
|
||||
{
|
||||
return $this->where('name', $name)->find();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找配置
|
||||
*
|
||||
* @time 2020年09月16日
|
||||
* @param $id
|
||||
* @param array|string[] $field
|
||||
* @param false $trash
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function findBy($id, array $field = ['*'], $trash = false)
|
||||
{
|
||||
$config = [];
|
||||
|
||||
if (!$this->findByName($id)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$this->findByName($id)
|
||||
->hasConfig()
|
||||
->select()
|
||||
->each(function ($item) use (&$config){
|
||||
$config[$item['key']] = $item['value'];
|
||||
});
|
||||
|
||||
return $config;
|
||||
}
|
||||
}
|
37
catch/sms/model/SmsTemplate.php
Normal file
37
catch/sms/model/SmsTemplate.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace catchAdmin\sms\model;
|
||||
|
||||
use catchAdmin\sms\model\search\SmsTemplateSearch;
|
||||
use catcher\base\CatchModel as Model;
|
||||
|
||||
class SmsTemplate extends Model
|
||||
{
|
||||
use SmsTemplateSearch;
|
||||
|
||||
protected $name = 'sms_template';
|
||||
|
||||
protected $field = [
|
||||
'id', //
|
||||
'operator', // 运营商
|
||||
'name', // 模版名称
|
||||
'identify', // 模版标识
|
||||
'code', // 模版CODE
|
||||
'creator_id', // 创建人ID
|
||||
'created_at', // 创建时间
|
||||
'updated_at', // 更新时间
|
||||
'deleted_at', // 软删除
|
||||
];
|
||||
|
||||
protected $paginate = false;
|
||||
|
||||
}
|
19
catch/sms/model/search/SmsTemplateSearch.php
Normal file
19
catch/sms/model/search/SmsTemplateSearch.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
namespace catchAdmin\sms\model\search;
|
||||
|
||||
trait SmsTemplateSearch
|
||||
{
|
||||
public function searchOperatorAttr($query, $value, $data)
|
||||
{
|
||||
return $query->where('operator', $value);
|
||||
}
|
||||
}
|
15
catch/sms/module.json
Normal file
15
catch/sms/module.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "短信模块",
|
||||
"alias": "sms",
|
||||
"description": "短信,sms,阿里大于",
|
||||
"version": "1.0.0",
|
||||
"keywords": [],
|
||||
"order": 0,
|
||||
"services": [
|
||||
"\\catchAdmin\\sms\\SmsService"
|
||||
],
|
||||
"aliases": {},
|
||||
"files": [],
|
||||
"requires": [],
|
||||
"enable": false
|
||||
}
|
18
catch/sms/route.php
Normal file
18
catch/sms/route.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~{$year} http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
// you should use `$router`
|
||||
$router->group('sms', function () use ($router){
|
||||
// config路由
|
||||
$router->resource('config', '\catchAdmin\sms\controller\Config');
|
||||
// template 路由
|
||||
$router->resource('template', '\catchAdmin\sms\controller\Template');
|
||||
})->middleware('auth');
|
@@ -11,6 +11,8 @@
|
||||
namespace catchAdmin\system;
|
||||
|
||||
use catchAdmin\system\events\AttachmentEvent;
|
||||
use catcher\command\MigrateRunCommand;
|
||||
use catcher\command\SeedRunCommand;
|
||||
use catcher\ModuleService;
|
||||
|
||||
class SystemService extends ModuleService
|
||||
@@ -28,4 +30,12 @@ class SystemService extends ModuleService
|
||||
'attachment' => [ AttachmentEvent::class ],
|
||||
];
|
||||
}
|
||||
|
||||
protected function registerCommands()
|
||||
{
|
||||
$this->commands([
|
||||
MigrateRunCommand::class,
|
||||
SeedRunCommand::class,
|
||||
]);
|
||||
}
|
||||
}
|
@@ -5,7 +5,7 @@ use catcher\base\CatchController;
|
||||
use catcher\CatchResponse;
|
||||
use catchAdmin\system\model\Attachments as AttachmentsModel;
|
||||
use catcher\Utils;
|
||||
use think\facade\Filesystem;
|
||||
use catcher\facade\FileSystem;
|
||||
|
||||
class Attachments extends CatchController
|
||||
{
|
||||
@@ -39,9 +39,17 @@ class Attachments extends CatchController
|
||||
|
||||
if ($model->deleteBy($id)) {
|
||||
foreach ($attachments as $attachment) {
|
||||
if ($attachment->driver == 'local') {
|
||||
$localPath = config('filesystem.disks.local.root') . DIRECTORY_SEPARATOR;
|
||||
$path = $localPath . str_replace('\\','\/', $attachment->path);
|
||||
if (FileSystem::exists($path)) {
|
||||
Filesystem::delete($path);
|
||||
}
|
||||
} else {
|
||||
Filesystem::delete($attachment->path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CatchResponse::success();
|
||||
}
|
||||
|
@@ -7,7 +7,6 @@ use catcher\CatchResponse;
|
||||
use catcher\exceptions\FailedException;
|
||||
use catcher\library\BackUpDatabase;
|
||||
use think\Collection;
|
||||
use think\facade\Console;
|
||||
use think\facade\Db;
|
||||
use think\Paginator;
|
||||
|
||||
@@ -24,7 +23,7 @@ class DataDictionary extends CatchController
|
||||
$tables = Db::query('show table status');
|
||||
|
||||
// 重组数据
|
||||
foreach ($tables as $key => &$table) {
|
||||
foreach ($tables as &$table) {
|
||||
$table = array_change_key_case($table);
|
||||
$table['index_length'] = $table['index_length'] > 1024 ? intval($table['index_length']/1024) .'MB' : $table['index_length'].'KB';
|
||||
$table['data_length'] = $table['data_length'] > 1024 ? intval($table['data_length']/1024) .'MB' : $table['data_length'].'KB';
|
||||
@@ -41,8 +40,10 @@ class DataDictionary extends CatchController
|
||||
if ($engine = $request->get('engine', null)) {
|
||||
$tables = $tables->where('engine', $engine)->values();
|
||||
}
|
||||
$page = $request->get('page', 1) ? : 1;
|
||||
$limit = $request->get('limit', 10);
|
||||
|
||||
return CatchResponse::paginate(Paginator::make($tables->toArray(), $request->get('limit') ?? 10, $request->get('page') ?? 1, $tables->count(), false, []));
|
||||
return CatchResponse::paginate(Paginator::make(array_slice($tables->toArray(), ($page - 1) * $limit, $limit), $limit, $page, $tables->count(), false, []));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -4,7 +4,6 @@ namespace catchAdmin\system\controller;
|
||||
|
||||
use catcher\base\CatchController;
|
||||
use catcher\CatchResponse;
|
||||
use think\facade\Db;
|
||||
use catchAdmin\system\model\LoginLog as Log;
|
||||
|
||||
class LoginLog extends CatchController
|
||||
@@ -26,11 +25,12 @@ class LoginLog extends CatchController
|
||||
*
|
||||
* @time 2020年04月28日
|
||||
* @param Log $log
|
||||
* @param $id
|
||||
* @throws \Exception
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function empty(Log $log)
|
||||
public function empty($id, Log $log)
|
||||
{
|
||||
return CatchResponse::success($log->where('id', '>', 0)->delete(), '清空成功');
|
||||
return CatchResponse::success($log->deleteBy($id), '删除成功');
|
||||
}
|
||||
}
|
||||
|
91
catch/system/controller/Module.php
Normal file
91
catch/system/controller/Module.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
namespace catchAdmin\system\controller;
|
||||
|
||||
use catchAdmin\permissions\model\Permissions;
|
||||
use catcher\base\CatchController;
|
||||
use catcher\CatchResponse;
|
||||
use catcher\CatchAdmin;
|
||||
use catcher\library\InstallCatchModule;
|
||||
use catcher\library\InstallLocalModule;
|
||||
use catcher\Utils;
|
||||
use think\response\Json;
|
||||
|
||||
class Module extends CatchController
|
||||
{
|
||||
/**
|
||||
* 模块列表
|
||||
*
|
||||
* @return Json
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$modules = [];
|
||||
|
||||
foreach(CatchAdmin::getModulesDirectory() as $d) {
|
||||
$modules[] = json_decode(file_get_contents($d . 'module.json'), true);
|
||||
}
|
||||
|
||||
$hasModules = array_unique(Permissions::whereIn('id', request()->user()->getPermissionsBy())->column('module'));
|
||||
|
||||
$orders = array_column($modules, 'order');
|
||||
|
||||
array_multisort($orders, SORT_DESC, $modules);
|
||||
|
||||
if (!Utils::isSuperAdmin()) {
|
||||
foreach ($modules as $k => $module) {
|
||||
if (!in_array($module['alias'], $hasModules)) {
|
||||
unset($modules[$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CatchResponse::success(array_values($modules));
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用/启用模块
|
||||
*
|
||||
* @param string $module
|
||||
* @return Json
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
*/
|
||||
public function disOrEnable(string $module)
|
||||
{
|
||||
$moduleInfo = CatchAdmin::getModuleInfo(CatchAdmin::directory() . $module);
|
||||
|
||||
$install = new InstallLocalModule($module);
|
||||
if (!$moduleInfo['enable']) {
|
||||
$install->findModuleInPermissions() ? $install->enableModule() : $install->done();
|
||||
} else {
|
||||
$install->disableModule();
|
||||
}
|
||||
|
||||
return CatchResponse::success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存
|
||||
*
|
||||
* @time 2020年09月21日
|
||||
* @return Json
|
||||
*/
|
||||
public function cache()
|
||||
{
|
||||
return CatchResponse::success(CatchAdmin::cacheServices());
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理缓存
|
||||
*
|
||||
* @time 2020年09月21日
|
||||
* @return Json
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
return !file_exists(CatchAdmin::getCacheServicesFile()) ?
|
||||
CatchResponse::fail('模块没有缓存') :
|
||||
CatchResponse::success(unlink(CatchAdmin::getCacheServicesFile()));
|
||||
}
|
||||
}
|
@@ -35,7 +35,7 @@ class Developers extends Migrator
|
||||
->addColumn('mobile', 'string', ['limit' => 30,'null' => false,'default' => '','signed' => false,'comment' => '手机号',])
|
||||
->addColumn('id_card', 'string', ['limit' => 50,'null' => false,'default' => '','signed' => false,'comment' => '身份证',])
|
||||
->addColumn('alipay_account', 'string', ['limit' => 100,'null' => false,'default' => '','signed' => false,'comment' => '支付宝账户',])
|
||||
->addColumn('status', 'boolean', ['null' => false,'default' => 1,'signed' => false,'comment' => '1 待认证 1 已认证',])
|
||||
->addColumn('status', 'boolean', ['null' => false,'default' => 1,'signed' => false,'comment' => '1 待认证 2 已认证',])
|
||||
->addColumn('created_at', 'integer', ['limit' => MysqlAdapter::INT_REGULAR,'null' => false,'default' => 0,'signed' => true,'comment' => '创建时间',])
|
||||
->addColumn('updated_at', 'integer', ['limit' => MysqlAdapter::INT_REGULAR,'null' => false,'default' => 0,'signed' => true,'comment' => '更新时间',])
|
||||
->addColumn('deleted_at', 'integer', ['limit' => MysqlAdapter::INT_REGULAR,'null' => false,'default' => 0,'signed' => true,'comment' => '软删除',])
|
||||
|
@@ -18,8 +18,8 @@ class ConfigSeed extends Seeder
|
||||
[
|
||||
'name' => '基础配置',
|
||||
'pid' => 0,
|
||||
'component' => 'basis',
|
||||
'key' => 'basis',
|
||||
'component' => 'basic',
|
||||
'key' => 'basic',
|
||||
],
|
||||
[
|
||||
'name' => '上传配置',
|
||||
|
775
catch/system/database/seeds/SystemMenusSeed.php
Normal file
775
catch/system/database/seeds/SystemMenusSeed.php
Normal file
@@ -0,0 +1,775 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~{$year} http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
use think\migration\Seeder;
|
||||
|
||||
class SystemMenusSeed extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run Method.
|
||||
*
|
||||
* Write your database seeder using this method.
|
||||
*
|
||||
* More information on writing seeders is available here:
|
||||
* http://docs.phinx.org/en/latest/seeding.html
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
\catcher\Utils::importTreeData($this->getPermissions(), 'permissions', 'parent_id');
|
||||
}
|
||||
|
||||
protected function getPermissions()
|
||||
{
|
||||
return array (
|
||||
0 =>
|
||||
array (
|
||||
'id' => 38,
|
||||
'permission_name' => '系统管理',
|
||||
'parent_id' => 0,
|
||||
'level' => '',
|
||||
'route' => '/system',
|
||||
'icon' => 'el-icon-s-tools',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'system',
|
||||
'component' => 'layout',
|
||||
'redirect' => 'attactments',
|
||||
'keepalive' => 2,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587462349,
|
||||
'updated_at' => 1599288737,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
'id' => 39,
|
||||
'permission_name' => '数据字典',
|
||||
'parent_id' => 38,
|
||||
'level' => '38',
|
||||
'route' => '/system/database',
|
||||
'icon' => 'el-icon-copy-document',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'dataDictionary',
|
||||
'component' => 'database',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 8,
|
||||
'created_at' => 1587463087,
|
||||
'updated_at' => 1599362678,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
'id' => 40,
|
||||
'permission_name' => '查看',
|
||||
'parent_id' => 39,
|
||||
'level' => '38-39',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'dataDictionary@view',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587463113,
|
||||
'updated_at' => 1599362691,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
'id' => 41,
|
||||
'permission_name' => '列表',
|
||||
'parent_id' => 39,
|
||||
'level' => '38-39',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'dataDictionary@tables',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 10,
|
||||
'created_at' => 1587463173,
|
||||
'updated_at' => 1599362678,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
'id' => 42,
|
||||
'permission_name' => '优化',
|
||||
'parent_id' => 39,
|
||||
'level' => '38-39',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'dataDictionary@optimize',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587463201,
|
||||
'updated_at' => 1599362678,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
'id' => 43,
|
||||
'permission_name' => '备份',
|
||||
'parent_id' => 39,
|
||||
'level' => '38-39',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'optimize@backup',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587463217,
|
||||
'updated_at' => 1599362678,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
'id' => 44,
|
||||
'permission_name' => '附件管理',
|
||||
'parent_id' => 38,
|
||||
'level' => '38',
|
||||
'route' => '/system/attactments',
|
||||
'icon' => 'el-icon-folder-opened',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'attactments',
|
||||
'component' => 'attachment',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 10,
|
||||
'created_at' => 1587463302,
|
||||
'updated_at' => 1599288737,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
'id' => 45,
|
||||
'permission_name' => '列表',
|
||||
'parent_id' => 44,
|
||||
'level' => '38-44',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'attachments@index',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587463335,
|
||||
'updated_at' => 1599217559,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
'id' => 46,
|
||||
'permission_name' => '删除',
|
||||
'parent_id' => 44,
|
||||
'level' => '38-44',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'attachments@delete',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587463355,
|
||||
'updated_at' => 1599217559,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
'id' => 47,
|
||||
'permission_name' => '上传图片',
|
||||
'parent_id' => 44,
|
||||
'level' => '38-44',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'upload@image',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587466919,
|
||||
'updated_at' => 1599217559,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
'id' => 48,
|
||||
'permission_name' => '上传文件',
|
||||
'parent_id' => 44,
|
||||
'level' => '38-44',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'upload@file',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587466939,
|
||||
'updated_at' => 1599217559,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
'id' => 49,
|
||||
'permission_name' => '配置管理',
|
||||
'parent_id' => 38,
|
||||
'level' => '38',
|
||||
'route' => '/system/config',
|
||||
'icon' => 'el-icon-setting',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'config',
|
||||
'component' => 'config',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 9,
|
||||
'created_at' => 1587466991,
|
||||
'updated_at' => 1599288737,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
'id' => 50,
|
||||
'permission_name' => '父级配置',
|
||||
'parent_id' => 49,
|
||||
'level' => '38-49',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'config@parent',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587467036,
|
||||
'updated_at' => 1591345651,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
'id' => 51,
|
||||
'permission_name' => '存储',
|
||||
'parent_id' => 49,
|
||||
'level' => '38-49',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'config@save',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587467052,
|
||||
'updated_at' => 1587547118,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
'id' => 52,
|
||||
'permission_name' => '获取',
|
||||
'parent_id' => 49,
|
||||
'level' => '38-49',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'config@read',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587467062,
|
||||
'updated_at' => 1587547118,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
'id' => 53,
|
||||
'permission_name' => '登陆日志',
|
||||
'parent_id' => 38,
|
||||
'level' => '38',
|
||||
'route' => '/system/log/login',
|
||||
'icon' => 'el-icon-coin',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'loginLog',
|
||||
'component' => 'loginLog',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 5,
|
||||
'created_at' => 1587467150,
|
||||
'updated_at' => 1599288737,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
'id' => 54,
|
||||
'permission_name' => '列表',
|
||||
'parent_id' => 53,
|
||||
'level' => '38-53',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'loginlog@list',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587467206,
|
||||
'updated_at' => 1587547118,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
'id' => 55,
|
||||
'permission_name' => '清空',
|
||||
'parent_id' => 53,
|
||||
'level' => '38-53',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'loginlog@empty',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587467221,
|
||||
'updated_at' => 1587547118,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
'id' => 56,
|
||||
'permission_name' => '操作日志',
|
||||
'parent_id' => 38,
|
||||
'level' => '38',
|
||||
'route' => '/system/log/operate',
|
||||
'icon' => 'el-icon-house',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'operateLog',
|
||||
'component' => 'operateLog',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587467180,
|
||||
'updated_at' => 1599288737,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
'id' => 57,
|
||||
'permission_name' => '列表',
|
||||
'parent_id' => 56,
|
||||
'level' => '38-56',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'operatelog@list',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587467246,
|
||||
'updated_at' => 1587547118,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
'id' => 58,
|
||||
'permission_name' => '清空',
|
||||
'parent_id' => 56,
|
||||
'level' => '38-56',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'operatelog@empty',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587467266,
|
||||
'updated_at' => 1587547118,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
'id' => 59,
|
||||
'permission_name' => '代码生成',
|
||||
'parent_id' => 38,
|
||||
'level' => '38',
|
||||
'route' => '/system/generate',
|
||||
'icon' => 'el-icon-scissors',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'generate',
|
||||
'component' => 'generate',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587717452,
|
||||
'updated_at' => 1599288737,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
'id' => 60,
|
||||
'permission_name' => '生成',
|
||||
'parent_id' => 59,
|
||||
'level' => '38-59',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'generate@save',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1588110923,
|
||||
'updated_at' => 1599217574,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
'id' => 61,
|
||||
'permission_name' => '预览',
|
||||
'parent_id' => 59,
|
||||
'level' => '38-59',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'generate@preview',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1588110962,
|
||||
'updated_at' => 1599217574,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
'id' => 62,
|
||||
'permission_name' => '敏感词库',
|
||||
'parent_id' => 38,
|
||||
'level' => '38',
|
||||
'route' => '/sensitive/word',
|
||||
'icon' => 'el-icon-folder-delete',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'sensitiveWord',
|
||||
'component' => 'sensitiveWord',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1592375865,
|
||||
'updated_at' => 1599288737,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
'id' => 63,
|
||||
'permission_name' => '列表',
|
||||
'parent_id' => 62,
|
||||
'level' => '38-62',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'sensitiveWord@index',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1592382167,
|
||||
'updated_at' => 1593589434,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
'id' => 64,
|
||||
'permission_name' => '新增',
|
||||
'parent_id' => 62,
|
||||
'level' => '38-62',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'sensitiveWord@save',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1592382179,
|
||||
'updated_at' => 1593589434,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
'id' => 65,
|
||||
'permission_name' => '更新',
|
||||
'parent_id' => 62,
|
||||
'level' => '38-62',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'sensitiveWord@update',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1592382192,
|
||||
'updated_at' => 1593589434,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
'id' => 66,
|
||||
'permission_name' => '删除',
|
||||
'parent_id' => 62,
|
||||
'level' => '38-62',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'sensitiveWord@delete',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1592382202,
|
||||
'updated_at' => 1593589434,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
'id' => 67,
|
||||
'permission_name' => '开发者',
|
||||
'parent_id' => 38,
|
||||
'level' => '38',
|
||||
'route' => '/system/develop',
|
||||
'icon' => 'el-icon-rank',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'develop',
|
||||
'component' => 'develop',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1594626307,
|
||||
'updated_at' => 1599288737,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
'id' => 68,
|
||||
'permission_name' => '模块管理',
|
||||
'parent_id' => 38,
|
||||
'level' => '38',
|
||||
'route' => '/system/module',
|
||||
'icon' => 'el-icon-postcard',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'module',
|
||||
'component' => 'module',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1599904306,
|
||||
'updated_at' => 1599904306,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
'id' => 69,
|
||||
'permission_name' => '列表',
|
||||
'parent_id' => 68,
|
||||
'level' => '38-68',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'module@index',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1599904319,
|
||||
'updated_at' => 1599904319,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
'id' => 70,
|
||||
'permission_name' => '禁用/启用',
|
||||
'parent_id' => 68,
|
||||
'level' => '38-68',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'module@disOrEnable',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1599904331,
|
||||
'updated_at' => 1599904331,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
9 =>
|
||||
array (
|
||||
'id' => 116,
|
||||
'permission_name' => '表单构建',
|
||||
'parent_id' => 38,
|
||||
'level' => '38',
|
||||
'route' => '/system/form',
|
||||
'icon' => 'el-icon-knife-fork',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'form',
|
||||
'component' => 'form',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1600648935,
|
||||
'updated_at' => 1600648935,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,621 +0,0 @@
|
||||
<?php
|
||||
|
||||
use think\migration\Seeder;
|
||||
|
||||
class SystemPermissionSeed extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run Method.
|
||||
*
|
||||
* Write your database seeder using this method.
|
||||
*
|
||||
* More information on writing seeders is available here:
|
||||
* http://docs.phinx.org/en/latest/seeding.html
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
\catcher\Utils::importTreeData($this->getPermissions(), 'permissions', 'parent_id');
|
||||
}
|
||||
|
||||
protected function getPermissions()
|
||||
{
|
||||
return array(
|
||||
0 =>
|
||||
array(
|
||||
'id' => 37,
|
||||
'permission_name' => '系统管理',
|
||||
'parent_id' => 0,
|
||||
'level' => '',
|
||||
'route' => '/system',
|
||||
'icon' => 'bar-chart',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'system',
|
||||
'component' => 'pageView',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 2,
|
||||
'keepalive' => 2,
|
||||
'type' => 1,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587462349,
|
||||
'updated_at' => 1593044431,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array(
|
||||
0 =>
|
||||
array(
|
||||
'id' => 38,
|
||||
'permission_name' => '数据字典',
|
||||
'parent_id' => 37,
|
||||
'level' => '37',
|
||||
'route' => '/system/database',
|
||||
'icon' => 'hdd',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'dataDictionary@index',
|
||||
'component' => 'database',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 2,
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'status' => 1,
|
||||
'sort' => 8,
|
||||
'created_at' => 1587463087,
|
||||
'updated_at' => 1593044431,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array(
|
||||
0 =>
|
||||
array(
|
||||
'id' => 39,
|
||||
'permission_name' => '查看',
|
||||
'parent_id' => 38,
|
||||
'level' => '37-38',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'dataDictionary@view',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587463113,
|
||||
'updated_at' => 1591343449,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
1 =>
|
||||
array(
|
||||
'id' => 40,
|
||||
'permission_name' => '列表',
|
||||
'parent_id' => 38,
|
||||
'level' => '37-38',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'dataDictionary@tables',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 10,
|
||||
'created_at' => 1587463173,
|
||||
'updated_at' => 1587547118,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
2 =>
|
||||
array(
|
||||
'id' => 41,
|
||||
'permission_name' => '优化',
|
||||
'parent_id' => 38,
|
||||
'level' => '37-38',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'dataDictionary@optimize',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587463201,
|
||||
'updated_at' => 1587547118,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
3 =>
|
||||
array(
|
||||
'id' => 42,
|
||||
'permission_name' => '备份',
|
||||
'parent_id' => 38,
|
||||
'level' => '37-38',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'optimize@backup',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587463217,
|
||||
'updated_at' => 1587547118,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
1 =>
|
||||
array(
|
||||
'id' => 43,
|
||||
'permission_name' => '附件管理',
|
||||
'parent_id' => 37,
|
||||
'level' => '37',
|
||||
'route' => '/attactments',
|
||||
'icon' => 'folder-open',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'attactments',
|
||||
'component' => 'attachment',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 2,
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'status' => 1,
|
||||
'sort' => 10,
|
||||
'created_at' => 1587463302,
|
||||
'updated_at' => 1593044431,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array(
|
||||
0 =>
|
||||
array(
|
||||
'id' => 44,
|
||||
'permission_name' => '列表',
|
||||
'parent_id' => 43,
|
||||
'level' => '37-43',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'attachments@index',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587463335,
|
||||
'updated_at' => 1587547118,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
1 =>
|
||||
array(
|
||||
'id' => 45,
|
||||
'permission_name' => '删除',
|
||||
'parent_id' => 43,
|
||||
'level' => '37-43',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'attachments@delete',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587463355,
|
||||
'updated_at' => 1587547118,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
2 =>
|
||||
array(
|
||||
'id' => 46,
|
||||
'permission_name' => '上传图片',
|
||||
'parent_id' => 43,
|
||||
'level' => '37-43',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'upload@image',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587466919,
|
||||
'updated_at' => 1587547118,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
3 =>
|
||||
array(
|
||||
'id' => 47,
|
||||
'permission_name' => '上传文件',
|
||||
'parent_id' => 43,
|
||||
'level' => '37-43',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'upload@file',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587466939,
|
||||
'updated_at' => 1587547118,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
2 =>
|
||||
array(
|
||||
'id' => 48,
|
||||
'permission_name' => '配置管理',
|
||||
'parent_id' => 37,
|
||||
'level' => '37',
|
||||
'route' => '/system/config',
|
||||
'icon' => 'setting',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'config',
|
||||
'component' => 'config',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 2,
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'status' => 1,
|
||||
'sort' => 9,
|
||||
'created_at' => 1587466991,
|
||||
'updated_at' => 1593044431,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array(
|
||||
0 =>
|
||||
array(
|
||||
'id' => 49,
|
||||
'permission_name' => '父级配置',
|
||||
'parent_id' => 48,
|
||||
'level' => '37-48',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'config@parent',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587467036,
|
||||
'updated_at' => 1591345651,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
1 =>
|
||||
array(
|
||||
'id' => 50,
|
||||
'permission_name' => '存储',
|
||||
'parent_id' => 48,
|
||||
'level' => '37-48',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'config@save',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587467052,
|
||||
'updated_at' => 1587547118,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
2 =>
|
||||
array(
|
||||
'id' => 51,
|
||||
'permission_name' => '获取',
|
||||
'parent_id' => 48,
|
||||
'level' => '37-48',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'config@read',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587467062,
|
||||
'updated_at' => 1587547118,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
3 =>
|
||||
array(
|
||||
'id' => 52,
|
||||
'permission_name' => '登陆日志',
|
||||
'parent_id' => 37,
|
||||
'level' => '37',
|
||||
'route' => '/system/log/login',
|
||||
'icon' => 'export',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'loginLog',
|
||||
'component' => 'loginLog',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 2,
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'status' => 1,
|
||||
'sort' => 5,
|
||||
'created_at' => 1587467150,
|
||||
'updated_at' => 1593044431,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array(
|
||||
0 =>
|
||||
array(
|
||||
'id' => 53,
|
||||
'permission_name' => '列表',
|
||||
'parent_id' => 52,
|
||||
'level' => '37-52',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'loginlog@list',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587467206,
|
||||
'updated_at' => 1587547118,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
1 =>
|
||||
array(
|
||||
'id' => 54,
|
||||
'permission_name' => '清空',
|
||||
'parent_id' => 52,
|
||||
'level' => '37-52',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'loginlog@empty',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587467221,
|
||||
'updated_at' => 1587547118,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
4 =>
|
||||
array(
|
||||
'id' => 55,
|
||||
'permission_name' => '操作日志',
|
||||
'parent_id' => 37,
|
||||
'level' => '37',
|
||||
'route' => '/system/log/operate',
|
||||
'icon' => 'profile',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'operateLog',
|
||||
'component' => 'operateLog',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 2,
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587467180,
|
||||
'updated_at' => 1593044431,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array(
|
||||
0 =>
|
||||
array(
|
||||
'id' => 56,
|
||||
'permission_name' => '列表',
|
||||
'parent_id' => 55,
|
||||
'level' => '37-55',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'operatelog@list',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587467246,
|
||||
'updated_at' => 1587547118,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
1 =>
|
||||
array(
|
||||
'id' => 57,
|
||||
'permission_name' => '清空',
|
||||
'parent_id' => 55,
|
||||
'level' => '37-55',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'operatelog@empty',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587467266,
|
||||
'updated_at' => 1587547118,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
5 =>
|
||||
array(
|
||||
'id' => 58,
|
||||
'permission_name' => '代码生成',
|
||||
'parent_id' => 37,
|
||||
'level' => '37',
|
||||
'route' => '/generate',
|
||||
'icon' => 'scissor',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'generate',
|
||||
'component' => 'generate',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 2,
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1587717452,
|
||||
'updated_at' => 1593044431,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array(
|
||||
0 =>
|
||||
array(
|
||||
'id' => 59,
|
||||
'permission_name' => '生成',
|
||||
'parent_id' => 58,
|
||||
'level' => '37-58',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'generate@save',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1588110923,
|
||||
'updated_at' => 1588110923,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
1 =>
|
||||
array(
|
||||
'id' => 60,
|
||||
'permission_name' => '预览',
|
||||
'parent_id' => 58,
|
||||
'level' => '37-58',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'generate@preview',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 1,
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1588110962,
|
||||
'updated_at' => 1588110962,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
6 =>
|
||||
array(
|
||||
'id' => 68,
|
||||
'permission_name' => '敏感词库',
|
||||
'parent_id' => 37,
|
||||
'level' => '37',
|
||||
'route' => '/sensitive/word',
|
||||
'icon' => 'sliders',
|
||||
'module' => 'system',
|
||||
'creator_id' => 1,
|
||||
'method' => 'get',
|
||||
'permission_mark' => 'sensitiveWord',
|
||||
'component' => 'sensitiveWord',
|
||||
'redirect' => '',
|
||||
'hide_children_in_menu' => 2,
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'status' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1592375865,
|
||||
'updated_at' => 1593044431,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,12 +1,15 @@
|
||||
<?php
|
||||
namespace catchAdmin\system\model;
|
||||
|
||||
use catchAdmin\system\model\search\AttachmentsSearch;
|
||||
use catcher\base\CatchModel;
|
||||
use think\file\UploadedFile;
|
||||
use think\Model;
|
||||
|
||||
class Attachments extends CatchModel
|
||||
{
|
||||
use AttachmentsSearch;
|
||||
|
||||
protected $name = 'attachments';
|
||||
|
||||
protected $field = [
|
||||
@@ -27,24 +30,10 @@ class Attachments extends CatchModel
|
||||
{
|
||||
return $this->order('id', 'desc')
|
||||
->catchSearch()
|
||||
->catchOrder()
|
||||
->paginate();
|
||||
}
|
||||
|
||||
public function searchFileExtAttr($query, $value, $data)
|
||||
{
|
||||
return $query->where('file_ext', $value);
|
||||
}
|
||||
|
||||
public function searchMimeTypesAttr($query, $value, $data)
|
||||
{
|
||||
return $query->where('mime_type', $value);
|
||||
}
|
||||
|
||||
public function searchDriver($query, $value, $data)
|
||||
{
|
||||
return $query->where('driver', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
|
@@ -2,6 +2,7 @@
|
||||
namespace catchAdmin\system\model;
|
||||
|
||||
use catcher\base\CatchModel;
|
||||
use catcher\exceptions\FailedException;
|
||||
use thans\jwt\exception\UserNotDefinedException;
|
||||
use think\Model;
|
||||
|
||||
@@ -55,94 +56,47 @@ class Config extends CatchModel
|
||||
return true;
|
||||
}
|
||||
|
||||
// 子配置
|
||||
if ($data['pid'] ?? false) {
|
||||
$config = \json_decode($data['config'], true);
|
||||
$pid = $data['pid'];
|
||||
unset($data['pid']);
|
||||
/**[
|
||||
'key' => [
|
||||
'k' => 'v'
|
||||
],
|
||||
$parent = $data['parent'] ?? false;
|
||||
if (!$parent) {
|
||||
throw new FailedException('父配置丢失');
|
||||
}
|
||||
unset($data['parent']);
|
||||
|
||||
'k' => 'v'
|
||||
]*/
|
||||
foreach ($config as $key => $value) {
|
||||
if (empty($value)) {
|
||||
continue;
|
||||
$parentConfig = $this->where('key', $parent)->find();
|
||||
$config = [];
|
||||
foreach ($data as $key => $item) {
|
||||
foreach ($item as $k => $value) {
|
||||
if ($value) {
|
||||
$config[$key . '.' .$k] = [
|
||||
'pid' => $parentConfig['id'],
|
||||
'key' => $key . '.' . $k,
|
||||
'value' => $value,
|
||||
'created_at' => time(),
|
||||
'updated_at' => time(),
|
||||
];
|
||||
}
|
||||
// 如果二级配置存在
|
||||
$secondLevel = $this->isExistConfig($key, $pid);
|
||||
if ($secondLevel) {
|
||||
// value 是字符串
|
||||
if (!is_array($value)) {
|
||||
if ($value != $secondLevel->value) {
|
||||
$secondLevel->value = $value;
|
||||
$secondLevel->save();
|
||||
}
|
||||
} else {
|
||||
// 数组
|
||||
$thirdLevel = [];
|
||||
$this->subConfig($secondLevel->id, ['id', 'key', 'value'])
|
||||
->each(function ($item, $key) use (&$thirdLevel){
|
||||
$thirdLevel[$item['key']] = $item;
|
||||
}
|
||||
|
||||
$this->where('pid', $parentConfig->id)
|
||||
->select()
|
||||
->each(function ($item) use (&$config){
|
||||
if (isset($config[$item['key']])) {
|
||||
if ($config[$item['key']]['value'] != $item->value) {
|
||||
$item['value'] = $config[$item['key']]['value'];
|
||||
$item->save();
|
||||
}
|
||||
unset($config[$item['key']]);
|
||||
}
|
||||
});
|
||||
|
||||
if (!empty($value)) {
|
||||
$new = [];
|
||||
foreach ($value as $k => $v) {
|
||||
if (isset($thirdLevel[$k])) {
|
||||
if ($v != $thirdLevel[$k]->value) {
|
||||
$thirdLevel[$k]->value = $v;
|
||||
$thirdLevel[$k]->save();
|
||||
}
|
||||
} else {
|
||||
$new[] = [
|
||||
'pid' => $secondLevel->id,
|
||||
'key' => $k,
|
||||
'value' => $v,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($new)) {
|
||||
parent::insertAllBy($new);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!is_array($value)) {
|
||||
parent::createBy([
|
||||
'pid' => $pid,
|
||||
'key' => $key,
|
||||
'value' => $value,
|
||||
]);
|
||||
} else {
|
||||
$id = parent::createBy([
|
||||
'pid' => $pid,
|
||||
'key' => $key,
|
||||
]);
|
||||
if (!empty($value)) {
|
||||
$newConfig = [];
|
||||
foreach ($value as $k => $v) {
|
||||
$newConfig[] = [
|
||||
'key' => $k,
|
||||
'value' => $v,
|
||||
'pid' => $id,
|
||||
];
|
||||
}
|
||||
parent::insertAllBy($newConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count($config)) {
|
||||
return $this->insertAll($config);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return parent::storeBy($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置是否存在
|
||||
*
|
||||
@@ -183,28 +137,26 @@ class Config extends CatchModel
|
||||
* 获取配置
|
||||
*
|
||||
* @time 2020年04月20日
|
||||
* @param int $pid
|
||||
* @param string $component
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function getConfig($pid = 0)
|
||||
public function getConfig(string $component)
|
||||
{
|
||||
$data = [];
|
||||
|
||||
$configs = $this->where('pid', $pid)
|
||||
$configs = $this->where('pid', $this->where('component', $component)->value('id'))
|
||||
->field('id,`key` as k,value,pid')
|
||||
->select();
|
||||
|
||||
foreach ($configs as $config) {
|
||||
if ($config->value !== '') {
|
||||
$data[$config->k] = $config->value;
|
||||
} else {
|
||||
$data[$config->k] = $this->getConfig($config->id);
|
||||
if (strpos($config['k'], '.') !== false) {
|
||||
list($object, $key) = explode('.', $config['k']);
|
||||
$data[$object][$key] = $config['value'];
|
||||
}
|
||||
}
|
||||
|
||||
return empty($data) ? '' : $data;
|
||||
return $data;
|
||||
}
|
||||
}
|
@@ -11,10 +11,13 @@
|
||||
|
||||
namespace catchAdmin\system\model;
|
||||
|
||||
use catchAdmin\system\model\search\DeveloperSearch;
|
||||
use catcher\base\CatchModel as Model;
|
||||
|
||||
class Developers extends Model
|
||||
{
|
||||
use DeveloperSearch;
|
||||
|
||||
protected $name = 'developers';
|
||||
|
||||
protected $field = [
|
||||
|
@@ -8,31 +8,22 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
namespace catcher\library;
|
||||
namespace catchAdmin\system\model\search;
|
||||
|
||||
use catcher\library\crontab\Schedule;
|
||||
|
||||
class ScheduleKernel
|
||||
trait AttachmentsSearch
|
||||
{
|
||||
protected $schedule;
|
||||
|
||||
public function __construct()
|
||||
public function searchFileExtAttr($query, $value, $data)
|
||||
{
|
||||
$this->schedule = new Schedule();
|
||||
return $query->where('file_ext', $value);
|
||||
}
|
||||
|
||||
protected function run()
|
||||
public function searchMimeTypesAttr($query, $value, $data)
|
||||
{
|
||||
$this->schedule->command('catch:cache')->everyThirtySeconds();
|
||||
$this->schedule->command('test')->everyTenSeconds();
|
||||
|
||||
return $query->where('mime_type', $value);
|
||||
}
|
||||
|
||||
|
||||
public function tasks()
|
||||
public function searchDriverAttr($query, $value, $data)
|
||||
{
|
||||
$this->run();
|
||||
|
||||
return $this->schedule->getCronTask();
|
||||
return $query->where('driver', $value);
|
||||
}
|
||||
}
|
29
catch/system/model/search/DeveloperSearch.php
Normal file
29
catch/system/model/search/DeveloperSearch.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CatchAdmin [Just Like ~ ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||
// +----------------------------------------------------------------------
|
||||
namespace catchAdmin\system\model\search;
|
||||
|
||||
trait DeveloperSearch
|
||||
{
|
||||
public function searchUsernameAttr($query, $value, $data)
|
||||
{
|
||||
return $query->whereLike('username', $value);
|
||||
}
|
||||
|
||||
public function searchMobileAttr($query, $value, $data)
|
||||
{
|
||||
return $query->whereLike('mobile', $value);
|
||||
}
|
||||
|
||||
public function searchStatusAttr($query, $value, $data)
|
||||
{
|
||||
return $query->where('driver', $value);
|
||||
}
|
||||
}
|
@@ -4,18 +4,13 @@ namespace catchAdmin\system\model\search;
|
||||
|
||||
trait LoginLogSearch
|
||||
{
|
||||
public function searchLoginNameAttr($query, $value, $data)
|
||||
public function searchStartAtAttr($query, $value, $data)
|
||||
{
|
||||
return $query->whereLike('login_name', $value);
|
||||
return $query->whereTime('login_at', '>=', strtotime($value));
|
||||
}
|
||||
|
||||
public function searchLoginIpAttr($query, $value, $data)
|
||||
public function searchEndAtAttr($query, $value, $data)
|
||||
{
|
||||
return $query->whereLike('login_ip', $value);
|
||||
}
|
||||
|
||||
public function searchLoginAtAttr($query, $value, $data)
|
||||
{
|
||||
return $query->whereTime('login_at', 'between', $value);
|
||||
return $query->whereTime('login_at', '<=', strtotime($value));
|
||||
}
|
||||
}
|
||||
|
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace catchAdmin\system\model\search;
|
||||
|
||||
use catchAdmin\permissions\model\Users;
|
||||
|
||||
trait OperateLogSearch
|
||||
{
|
||||
public function searchModuleAttr($query, $value, $data)
|
||||
@@ -16,7 +18,7 @@ trait OperateLogSearch
|
||||
|
||||
public function searchCreatorAttr($query, $value, $data)
|
||||
{
|
||||
return $query->where('username', $value);
|
||||
return $query->whereLike(app(Users::class)->getTable() . '.username', $value);
|
||||
}
|
||||
|
||||
public function searchCreateAtAttr($query, $value, $data)
|
||||
|
@@ -4,7 +4,7 @@
|
||||
"description": "系统管理模块",
|
||||
"version": "1.0.0",
|
||||
"keywords": [],
|
||||
"order": 2,
|
||||
"order": 100,
|
||||
"services": [
|
||||
"\\catchAdmin\\system\\SystemService"
|
||||
],
|
||||
|
@@ -10,7 +10,7 @@ class CreateRequest extends CatchRequest
|
||||
{
|
||||
// TODO: Implement rules() method.
|
||||
return [
|
||||
'word|词汇' => 'sensitive_word|unique:'.SensitiveWord::class.',word',
|
||||
'word|词汇' => 'unique:'.SensitiveWord::class.',word',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -2,11 +2,11 @@
|
||||
$router->group(function () use ($router) {
|
||||
// 登录日志
|
||||
$router->get('log/login', '\catchAdmin\system\controller\LoginLog@list');
|
||||
$router->delete('loginLog/empty', '\catchAdmin\system\controller\LoginLog@empty');
|
||||
$router->delete('log/login/<id>', '\catchAdmin\system\controller\LoginLog@empty');
|
||||
// 操作日志
|
||||
$router->get('log/operate', '\catchAdmin\system\controller\OperateLog@list');
|
||||
$router->delete('operateLog/empty', '\catchAdmin\system\controller\OperateLog@empty');
|
||||
$router->delete('operateLog/delete', '\catchAdmin\system\controller\OperateLog@delete');
|
||||
// $router->delete('empty/log/operate', '\catchAdmin\system\controller\OperateLog@empty');
|
||||
$router->delete('log/operate/<id>', '\catchAdmin\system\controller\OperateLog@delete');
|
||||
|
||||
// 数据字典
|
||||
$router->get('tables', '\catchAdmin\system\controller\DataDictionary@tables');
|
||||
@@ -31,9 +31,18 @@ $router->group(function () use ($router) {
|
||||
|
||||
// 敏感词
|
||||
$router->resource('sensitive/word', '\catchAdmin\system\controller\SensitiveWord');
|
||||
})->middleware('auth');
|
||||
|
||||
//developer路由
|
||||
$router->resource('developer', '\catchAdmin\system\controller\Developer')->middleware('auth');
|
||||
// 开发者认证
|
||||
$router->post('developer/authenticate', '\catchAdmin\system\controller\Developer@authenticate');
|
||||
|
||||
// 模块管理
|
||||
$router->get('modules', '\catchAdmin\system\controller\Module@index');
|
||||
$router->put('modules/<module>', '\catchAdmin\system\controller\Module@disOrEnable');
|
||||
$router->put('cache/modules', '\catchAdmin\system\controller\Module@cache');
|
||||
$router->delete('clear/modules', '\catchAdmin\system\controller\Module@clear');
|
||||
|
||||
})->middleware('auth');
|
||||
|
||||
|
||||
|
@@ -36,6 +36,18 @@ class Reply extends CatchController
|
||||
return CatchResponse::paginate($this->reply->getList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取
|
||||
*
|
||||
* @time 2020年09月13日
|
||||
* @param $id
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function read($id)
|
||||
{
|
||||
return CatchResponse::success($this->reply->findBy($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*
|
||||
@@ -48,6 +60,18 @@ class Reply extends CatchController
|
||||
return CatchResponse::success($this->reply->storeBy($request->param()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新
|
||||
*
|
||||
* @time 2020年09月13日
|
||||
* @param $id
|
||||
* @param CatchRequest $request
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function update($id, CatchRequest $request)
|
||||
{
|
||||
return CatchResponse::success($this->reply->updateBy($id, $request->param()));
|
||||
}
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user