Compare commits
59 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 |
20
README.md
20
README.md
@@ -31,6 +31,9 @@
|
|||||||
<img src="https://svg.hamm.cn/badge.svg?key=License&value=Apache-2.0"/>
|
<img src="https://svg.hamm.cn/badge.svg?key=License&value=Apache-2.0"/>
|
||||||
</p >
|
</p >
|
||||||
|
|
||||||
|
## AntDV 版本
|
||||||
|
- 请使用 `v1`分支
|
||||||
|
|
||||||
## 功能
|
## 功能
|
||||||
- [x] `用户管理` 后台用户管理
|
- [x] `用户管理` 后台用户管理
|
||||||
- [x] `部门管理` 配置公司的部门结构,支持树形结构
|
- [x] `部门管理` 配置公司的部门结构,支持树形结构
|
||||||
@@ -43,6 +46,9 @@
|
|||||||
- [x] `代码生成` 生成 API 端的 CURD 操作
|
- [x] `代码生成` 生成 API 端的 CURD 操作
|
||||||
- [x] `敏感词` 支持敏感词配置
|
- [x] `敏感词` 支持敏感词配置
|
||||||
- [x] `附件管理` 可管理上传的文件
|
- [x] `附件管理` 可管理上传的文件
|
||||||
|
- [x] `定时任务` 可管理定时任务,而不依赖于 Crontab
|
||||||
|
- [x] `短信平台` 短信云管理,支持 阿里大于,腾讯云,Ucloud,Submail
|
||||||
|
- [x] `云上传` 支持云上传,七牛,OSS,腾讯
|
||||||
- [ ] `微信管理`
|
- [ ] `微信管理`
|
||||||
|
|
||||||
## 项目地址
|
## 项目地址
|
||||||
@@ -104,8 +110,7 @@ curl -sS https://install.phpcomposer.com/installer | php
|
|||||||
|
|
||||||
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
|
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
|
||||||
|
|
||||||
composer install
|
composer install --ignore-platform-reqs
|
||||||
|
|
||||||
```
|
```
|
||||||
- composer 安装
|
- composer 安装
|
||||||
```shell
|
```shell
|
||||||
@@ -121,8 +126,8 @@ composer create-project jaguarjack/catchadmin:dev-master
|
|||||||
## 体验地址
|
## 体验地址
|
||||||
|
|
||||||
[体验地址](http://vue.catchadmin.com)
|
[体验地址](http://vue.catchadmin.com)
|
||||||
- 账号: admin@gmail.com
|
- 账号: catch@admin.com
|
||||||
- 密码: admin
|
- 密码: catchadmin
|
||||||
|
|
||||||
[catchadmin 文档地址](http://doc.catchadmin.com)
|
[catchadmin 文档地址](http://doc.catchadmin.com)
|
||||||
|
|
||||||
@@ -141,11 +146,7 @@ composer create-project jaguarjack/catchadmin:dev-master
|
|||||||
### Talking
|
### Talking
|
||||||
- [论坛讨论](http://bbs.catchadmin.com)
|
- [论坛讨论](http://bbs.catchadmin.com)
|
||||||
- 可以提 `ISSUE`,请按照 `issue` 模板提问
|
- 可以提 `ISSUE`,请按照 `issue` 模板提问
|
||||||
- 加入 Q 群 `302266230` 讨论以及反馈一些问题。
|
- 加入 Q 群 `302266230` 暗号 `catchadmin`。
|
||||||
- 加群需要付费,所以请使用能支持群费的客户端。(不喜勿喷,过滤一部分不看文档和 TP 框架文档并且衣来伸手饭来张口的用户)
|
|
||||||
- 不建议你付费入群,认真阅读文档可以解决所有问题
|
|
||||||
- 更愿意以 `ISSUE` 的方式提问
|
|
||||||
- 付费入群,群里的各位也是没有义务回答各种各样的基础问题。请 GOOGLE。
|
|
||||||
|
|
||||||
### Thanks
|
### Thanks
|
||||||
> 排名部分先后
|
> 排名部分先后
|
||||||
@@ -153,7 +154,6 @@ composer create-project jaguarjack/catchadmin:dev-master
|
|||||||
- [top-think/think](https://github.com/top-think/think)
|
- [top-think/think](https://github.com/top-think/think)
|
||||||
- [element-admin](https://panjiachen.gitee.io/vue-element-admin-site/zh/)
|
- [element-admin](https://panjiachen.gitee.io/vue-element-admin-site/zh/)
|
||||||
- [thans/tp-jwt-auth](https://packagist.org/packages/thans/tp-jwt-auth)
|
- [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)
|
- [jaguarjack/think-filesystem-cloud](https://github.com/yanwenwu/think-filesystem-cloud)
|
||||||
- [overtrue/wechat](https://github.com/overtrue/wechat)
|
- [overtrue/wechat](https://github.com/overtrue/wechat)
|
||||||
- [jaguarjack/migration-generator](https://github.com/yanwenwu/migration-generator)
|
- [jaguarjack/migration-generator](https://github.com/yanwenwu/migration-generator)
|
||||||
|
@@ -1,13 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace catchAdmin\cms;
|
|
||||||
|
|
||||||
use catcher\ModuleService;
|
|
||||||
|
|
||||||
class CmsService extends ModuleService
|
|
||||||
{
|
|
||||||
public function loadRouteFrom()
|
|
||||||
{
|
|
||||||
// TODO: Implement loadRouteFrom() method.
|
|
||||||
return __DIR__ . DIRECTORY_SEPARATOR . 'route.php';
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "内容管理",
|
|
||||||
"alias": "cms",
|
|
||||||
"description": "cms,博客,企业站点,内容管理",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"keywords": [],
|
|
||||||
"order": 0,
|
|
||||||
"services": [
|
|
||||||
"\\catchAdmin\\cms\\CmsService"
|
|
||||||
],
|
|
||||||
"aliases": {},
|
|
||||||
"files": [],
|
|
||||||
"requires": [],
|
|
||||||
"enable": true
|
|
||||||
}
|
|
@@ -1,14 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// you should user `$router`
|
|
||||||
$router->group(function () use ($router){
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//hello路由
|
|
||||||
$router->resource('hello', '\catchAdmin\cms\controller\Hello')->middleware('auth');
|
|
||||||
|
|
||||||
//hello路由
|
|
||||||
$router->resource('hello', '\catchAdmin\cms\controller\Hello')->middleware('auth');
|
|
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));
|
||||||
|
}
|
||||||
|
}
|
@@ -22,17 +22,79 @@ class Index extends CatchController
|
|||||||
*/
|
*/
|
||||||
public function login(LoginRequest $request, CatchAuth $auth)
|
public function login(LoginRequest $request, CatchAuth $auth)
|
||||||
{
|
{
|
||||||
|
$condition = $request->param();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$params = $request->param();
|
$token = $auth->attempt($condition);
|
||||||
$token = $auth->attempt($params);
|
|
||||||
|
$user = $auth->user();
|
||||||
|
|
||||||
|
$this->afterLoginSuccess($user);
|
||||||
|
// 登录事件
|
||||||
|
$this->loginEvent($user->username);
|
||||||
|
|
||||||
return CatchResponse::success([
|
return CatchResponse::success([
|
||||||
'token' => $token,
|
'token' => $token,
|
||||||
], '登录成功');
|
], '登录成功');
|
||||||
} catch (\Exception $exception) {
|
} catch (\Exception $exception) {
|
||||||
return CatchResponse::fail('登录失败', $exception->getCode());
|
$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();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录事件
|
||||||
|
*
|
||||||
|
* @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 模块",
|
"description": "login 模块",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"order": 1,
|
"order": 100,
|
||||||
"services": [
|
"services": [
|
||||||
"\\catchAdmin\\login\\LoginService"
|
"\\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));
|
||||||
|
}
|
||||||
|
}
|
@@ -8,31 +8,17 @@
|
|||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
namespace catcher\library;
|
namespace catchAdmin\monitor\model\search;
|
||||||
|
|
||||||
use catcher\library\crontab\Schedule;
|
trait CrontabSearch
|
||||||
|
|
||||||
class ScheduleKernel
|
|
||||||
{
|
{
|
||||||
protected $schedule;
|
public function searchNameAttr($query, $value, $data)
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
{
|
||||||
$this->schedule = new Schedule();
|
return $query->whereLike('name', $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function run()
|
public function searchStatusAttr($query, $value, $data)
|
||||||
{
|
{
|
||||||
$this->schedule->command('catch:cache')->everyThirtySeconds();
|
return $query->whereLike('status', $value);
|
||||||
$this->schedule->command('test')->everyTenSeconds();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function tasks()
|
|
||||||
{
|
|
||||||
$this->run();
|
|
||||||
|
|
||||||
return $this->schedule->getCronTask();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
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');
|
@@ -27,7 +27,7 @@ class Department extends CatchController
|
|||||||
*/
|
*/
|
||||||
public function index(): \think\response\Json
|
public function index(): \think\response\Json
|
||||||
{
|
{
|
||||||
return CatchResponse::success(Tree::done($this->department->getList()));
|
return CatchResponse::success($this->department->getList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -47,9 +47,9 @@ class Permission extends CatchController
|
|||||||
// 子节点的 key
|
// 子节点的 key
|
||||||
$children = $request->param('actionList') ?? 'children';
|
$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']] ?? [];
|
$item[$children] = $buttonList[$item['id']] ?? [];
|
||||||
})->toArray()));
|
})->toTree());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -27,7 +27,7 @@ class Role extends CatchController
|
|||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
return CatchResponse::success(Tree::done($this->role->getList()));
|
return CatchResponse::success($this->role->getList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -243,4 +243,16 @@ class User extends CatchController
|
|||||||
{
|
{
|
||||||
return CatchResponse::success($excel->save($userExport, Utils::publicPath('export/users')));
|
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,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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -16,8 +16,8 @@ class UsersSeed extends Seeder
|
|||||||
{
|
{
|
||||||
return \catchAdmin\permissions\model\Users::create([
|
return \catchAdmin\permissions\model\Users::create([
|
||||||
'username' => 'admin',
|
'username' => 'admin',
|
||||||
'password' => 'admin',
|
'password' => 'catchadmin',
|
||||||
'email' => 'admin@gmail.com',
|
'email' => 'catch@admin.com',
|
||||||
'creator_id' => 1,
|
'creator_id' => 1,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@@ -32,6 +32,7 @@ class PermissionsMiddleware
|
|||||||
|
|
||||||
// 模块忽略
|
// 模块忽略
|
||||||
[$module, $controller, $action] = Utils::parseRule($rule);
|
[$module, $controller, $action] = Utils::parseRule($rule);
|
||||||
|
|
||||||
// toad
|
// toad
|
||||||
if (in_array($module, $this->ignoreModule())) {
|
if (in_array($module, $this->ignoreModule())) {
|
||||||
return $next($request);
|
return $next($request);
|
||||||
@@ -42,11 +43,11 @@ class PermissionsMiddleware
|
|||||||
throw new PermissionForbiddenException('Login is invalid', Code::LOST_LOGIN);
|
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);
|
return $next($request);
|
||||||
}
|
}
|
||||||
// Get 请求
|
// Get 请求
|
||||||
if ($request->isGet() && config('catch.permissions.is_allow_get')) {
|
if ($this->allowGet($request)) {
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
// 判断权限
|
// 判断权限
|
||||||
@@ -106,4 +107,21 @@ class PermissionsMiddleware
|
|||||||
'permission' => $permission,
|
'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>
|
* @author JaguarJack <njphper@gmail.com>
|
||||||
* @date 2020/6/6
|
* @date 2020/6/6
|
||||||
*/
|
*/
|
||||||
protected function dataRange($roles)
|
public function dataRange($roles = [])
|
||||||
{
|
{
|
||||||
if (Utils::isSuperAdmin()) {
|
if (Utils::isSuperAdmin()) {
|
||||||
return $this;
|
return $this;
|
||||||
@@ -44,6 +44,10 @@ trait DataRangScopeTrait
|
|||||||
|
|
||||||
$user = request()->user();
|
$user = request()->user();
|
||||||
|
|
||||||
|
if (empty($roles)) {
|
||||||
|
$roles = $user->getRoles();
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($roles as $role) {
|
foreach ($roles as $role) {
|
||||||
switch ($role->data_range) {
|
switch ($role->data_range) {
|
||||||
case Roles::ALL_DATA:
|
case Roles::ALL_DATA:
|
||||||
|
@@ -3,6 +3,7 @@ namespace catchAdmin\permissions\model;
|
|||||||
|
|
||||||
use catchAdmin\permissions\model\search\DepartmentSearch;
|
use catchAdmin\permissions\model\search\DepartmentSearch;
|
||||||
use catcher\base\CatchModel;
|
use catcher\base\CatchModel;
|
||||||
|
use think\db\exception\DbException;
|
||||||
|
|
||||||
class Department extends CatchModel
|
class Department extends CatchModel
|
||||||
{
|
{
|
||||||
@@ -29,14 +30,13 @@ class Department extends CatchModel
|
|||||||
* 列表数据
|
* 列表数据
|
||||||
*
|
*
|
||||||
* @time 2020年01月09日
|
* @time 2020年01月09日
|
||||||
* @param $params
|
|
||||||
* @return array
|
* @return array
|
||||||
* @throws \think\db\exception\DbException
|
* @throws DbException
|
||||||
*/
|
*/
|
||||||
public function getList(): array
|
public function getList(): array
|
||||||
{
|
{
|
||||||
return $this->catchSearch()
|
return $this->catchSearch()
|
||||||
->catchOrder()
|
->catchOrder()
|
||||||
->select()->toArray();
|
->select()->toTree();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -37,7 +37,7 @@ class Roles extends CatchModel
|
|||||||
return $this->catchSearch()
|
return $this->catchSearch()
|
||||||
->order('id', 'desc')
|
->order('id', 'desc')
|
||||||
->select()
|
->select()
|
||||||
->toArray();
|
->toTree();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -19,6 +19,7 @@ class Users extends CatchModel
|
|||||||
'username', // 用户名
|
'username', // 用户名
|
||||||
'password', // 用户密码
|
'password', // 用户密码
|
||||||
'email', // 邮箱 登录
|
'email', // 邮箱 登录
|
||||||
|
'avatar', // 头像
|
||||||
'creator_id', // 创建者ID
|
'creator_id', // 创建者ID
|
||||||
'department_id', // 部门ID
|
'department_id', // 部门ID
|
||||||
'status', // 用户状态 1 正常 2 禁用
|
'status', // 用户状态 1 正常 2 禁用
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
"description": "权限管理模块",
|
"description": "权限管理模块",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"order": 2,
|
"order": 100,
|
||||||
"services": [
|
"services": [
|
||||||
"\\catchAdmin\\permissions\\PermissionService"
|
"\\catchAdmin\\permissions\\PermissionService"
|
||||||
],
|
],
|
||||||
|
@@ -17,7 +17,7 @@ class CreateRequest extends CatchRequest
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function message(): array
|
protected function message()
|
||||||
{
|
{
|
||||||
// TODO: Implement message() method.
|
// TODO: Implement message() method.
|
||||||
}
|
}
|
||||||
|
@@ -16,7 +16,7 @@ class UpdateRequest extends CatchRequest
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function message(): array
|
protected function message()
|
||||||
{
|
{
|
||||||
// TODO: Implement message() method.
|
// TODO: Implement message() method.
|
||||||
}
|
}
|
||||||
|
@@ -21,6 +21,7 @@ $router->group(function () use ($router){
|
|||||||
// 切换状态
|
// 切换状态
|
||||||
$router->put('users/switch/status/<id>', '\catchAdmin\permissions\controller\User@switchStatus');
|
$router->put('users/switch/status/<id>', '\catchAdmin\permissions\controller\User@switchStatus');
|
||||||
$router->put('users/recover/<id>', '\catchAdmin\permissions\controller\User@recover');
|
$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('users/get/roles', '\catchAdmin\permissions\controller\User@getRoles');
|
||||||
$router->get('user/info', '\catchAdmin\permissions\controller\User@info');
|
$router->get('user/info', '\catchAdmin\permissions\controller\User@info');
|
||||||
$router->get('user/export', '\catchAdmin\permissions\controller\User@export');
|
$router->get('user/export', '\catchAdmin\permissions\controller\User@export');
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@@ -9,22 +9,29 @@
|
|||||||
// | Author: JaguarJack [ njphper@gmail.com ]
|
// | Author: JaguarJack [ njphper@gmail.com ]
|
||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
namespace catchAdmin\cms\model;
|
namespace catchAdmin\sms\model;
|
||||||
|
|
||||||
|
use catchAdmin\sms\model\search\SmsTemplateSearch;
|
||||||
use catcher\base\CatchModel as Model;
|
use catcher\base\CatchModel as Model;
|
||||||
|
|
||||||
class Hello extends Model
|
class SmsTemplate extends Model
|
||||||
{
|
{
|
||||||
protected $name = 'hello';
|
use SmsTemplateSearch;
|
||||||
|
|
||||||
|
protected $name = 'sms_template';
|
||||||
|
|
||||||
protected $field = [
|
protected $field = [
|
||||||
'id', //
|
'id', //
|
||||||
'good', //
|
'operator', // 运营商
|
||||||
|
'name', // 模版名称
|
||||||
|
'identify', // 模版标识
|
||||||
|
'code', // 模版CODE
|
||||||
'creator_id', // 创建人ID
|
'creator_id', // 创建人ID
|
||||||
'created_at', // 创建时间
|
'created_at', // 创建时间
|
||||||
'updated_at', // 更新时间
|
'updated_at', // 更新时间
|
||||||
'deleted_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;
|
namespace catchAdmin\system;
|
||||||
|
|
||||||
use catchAdmin\system\events\AttachmentEvent;
|
use catchAdmin\system\events\AttachmentEvent;
|
||||||
|
use catcher\command\MigrateRunCommand;
|
||||||
|
use catcher\command\SeedRunCommand;
|
||||||
use catcher\ModuleService;
|
use catcher\ModuleService;
|
||||||
|
|
||||||
class SystemService extends ModuleService
|
class SystemService extends ModuleService
|
||||||
@@ -28,4 +30,12 @@ class SystemService extends ModuleService
|
|||||||
'attachment' => [ AttachmentEvent::class ],
|
'attachment' => [ AttachmentEvent::class ],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function registerCommands()
|
||||||
|
{
|
||||||
|
$this->commands([
|
||||||
|
MigrateRunCommand::class,
|
||||||
|
SeedRunCommand::class,
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
@@ -42,7 +42,7 @@ class Attachments extends CatchController
|
|||||||
if ($attachment->driver == 'local') {
|
if ($attachment->driver == 'local') {
|
||||||
$localPath = config('filesystem.disks.local.root') . DIRECTORY_SEPARATOR;
|
$localPath = config('filesystem.disks.local.root') . DIRECTORY_SEPARATOR;
|
||||||
$path = $localPath . str_replace('\\','\/', $attachment->path);
|
$path = $localPath . str_replace('\\','\/', $attachment->path);
|
||||||
if (!FileSystem::exists($path)) {
|
if (FileSystem::exists($path)) {
|
||||||
Filesystem::delete($path);
|
Filesystem::delete($path);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@@ -7,7 +7,6 @@ use catcher\CatchResponse;
|
|||||||
use catcher\exceptions\FailedException;
|
use catcher\exceptions\FailedException;
|
||||||
use catcher\library\BackUpDatabase;
|
use catcher\library\BackUpDatabase;
|
||||||
use think\Collection;
|
use think\Collection;
|
||||||
use think\facade\Console;
|
|
||||||
use think\facade\Db;
|
use think\facade\Db;
|
||||||
use think\Paginator;
|
use think\Paginator;
|
||||||
|
|
||||||
@@ -24,7 +23,7 @@ class DataDictionary extends CatchController
|
|||||||
$tables = Db::query('show table status');
|
$tables = Db::query('show table status');
|
||||||
|
|
||||||
// 重组数据
|
// 重组数据
|
||||||
foreach ($tables as $key => &$table) {
|
foreach ($tables as &$table) {
|
||||||
$table = array_change_key_case($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['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';
|
$table['data_length'] = $table['data_length'] > 1024 ? intval($table['data_length']/1024) .'MB' : $table['data_length'].'KB';
|
||||||
@@ -41,8 +40,7 @@ class DataDictionary extends CatchController
|
|||||||
if ($engine = $request->get('engine', null)) {
|
if ($engine = $request->get('engine', null)) {
|
||||||
$tables = $tables->where('engine', $engine)->values();
|
$tables = $tables->where('engine', $engine)->values();
|
||||||
}
|
}
|
||||||
|
$page = $request->get('page', 1) ? : 1;
|
||||||
$page = $request->get('page', 1);
|
|
||||||
$limit = $request->get('limit', 10);
|
$limit = $request->get('limit', 10);
|
||||||
|
|
||||||
return CatchResponse::paginate(Paginator::make(array_slice($tables->toArray(), ($page - 1) * $limit, $limit), $limit, $page, $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\base\CatchController;
|
||||||
use catcher\CatchResponse;
|
use catcher\CatchResponse;
|
||||||
use think\facade\Db;
|
|
||||||
use catchAdmin\system\model\LoginLog as Log;
|
use catchAdmin\system\model\LoginLog as Log;
|
||||||
|
|
||||||
class LoginLog extends CatchController
|
class LoginLog extends CatchController
|
||||||
@@ -26,11 +25,12 @@ class LoginLog extends CatchController
|
|||||||
*
|
*
|
||||||
* @time 2020年04月28日
|
* @time 2020年04月28日
|
||||||
* @param Log $log
|
* @param Log $log
|
||||||
|
* @param $id
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
* @return \think\response\Json
|
* @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()));
|
||||||
|
}
|
||||||
|
}
|
@@ -1,4 +1,13 @@
|
|||||||
<?php
|
<?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;
|
use think\migration\Seeder;
|
||||||
|
|
||||||
@@ -22,7 +31,7 @@ class SystemMenusSeed extends Seeder
|
|||||||
return array (
|
return array (
|
||||||
0 =>
|
0 =>
|
||||||
array (
|
array (
|
||||||
'id' => 37,
|
'id' => 38,
|
||||||
'permission_name' => '系统管理',
|
'permission_name' => '系统管理',
|
||||||
'parent_id' => 0,
|
'parent_id' => 0,
|
||||||
'level' => '',
|
'level' => '',
|
||||||
@@ -33,9 +42,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'system',
|
'permission_mark' => 'system',
|
||||||
'component' => 'layout',
|
'component' => 'layout',
|
||||||
'redirect' => 'attactments',
|
'redirect' => 'attactments',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 2,
|
'keepalive' => 2,
|
||||||
'type' => 1,
|
'type' => 1,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1587462349,
|
'created_at' => 1587462349,
|
||||||
'updated_at' => 1599288737,
|
'updated_at' => 1599288737,
|
||||||
@@ -44,10 +53,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
array (
|
array (
|
||||||
0 =>
|
0 =>
|
||||||
array (
|
array (
|
||||||
'id' => 38,
|
'id' => 39,
|
||||||
'permission_name' => '数据字典',
|
'permission_name' => '数据字典',
|
||||||
'parent_id' => 37,
|
'parent_id' => 38,
|
||||||
'level' => '37',
|
'level' => '38',
|
||||||
'route' => '/system/database',
|
'route' => '/system/database',
|
||||||
'icon' => 'el-icon-copy-document',
|
'icon' => 'el-icon-copy-document',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -55,9 +64,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'dataDictionary',
|
'permission_mark' => 'dataDictionary',
|
||||||
'component' => 'database',
|
'component' => 'database',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 1,
|
'type' => 1,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 8,
|
'sort' => 8,
|
||||||
'created_at' => 1587463087,
|
'created_at' => 1587463087,
|
||||||
'updated_at' => 1599362678,
|
'updated_at' => 1599362678,
|
||||||
@@ -66,10 +75,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
array (
|
array (
|
||||||
0 =>
|
0 =>
|
||||||
array (
|
array (
|
||||||
'id' => 39,
|
'id' => 40,
|
||||||
'permission_name' => '查看',
|
'permission_name' => '查看',
|
||||||
'parent_id' => 38,
|
'parent_id' => 39,
|
||||||
'level' => '37-38',
|
'level' => '38-39',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -77,9 +86,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'dataDictionary@view',
|
'permission_mark' => 'dataDictionary@view',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1587463113,
|
'created_at' => 1587463113,
|
||||||
'updated_at' => 1599362691,
|
'updated_at' => 1599362691,
|
||||||
@@ -87,10 +96,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
1 =>
|
1 =>
|
||||||
array (
|
array (
|
||||||
'id' => 40,
|
'id' => 41,
|
||||||
'permission_name' => '列表',
|
'permission_name' => '列表',
|
||||||
'parent_id' => 38,
|
'parent_id' => 39,
|
||||||
'level' => '37-38',
|
'level' => '38-39',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -98,9 +107,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'dataDictionary@tables',
|
'permission_mark' => 'dataDictionary@tables',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 10,
|
'sort' => 10,
|
||||||
'created_at' => 1587463173,
|
'created_at' => 1587463173,
|
||||||
'updated_at' => 1599362678,
|
'updated_at' => 1599362678,
|
||||||
@@ -108,10 +117,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
2 =>
|
2 =>
|
||||||
array (
|
array (
|
||||||
'id' => 41,
|
'id' => 42,
|
||||||
'permission_name' => '优化',
|
'permission_name' => '优化',
|
||||||
'parent_id' => 38,
|
'parent_id' => 39,
|
||||||
'level' => '37-38',
|
'level' => '38-39',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -119,9 +128,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'dataDictionary@optimize',
|
'permission_mark' => 'dataDictionary@optimize',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1587463201,
|
'created_at' => 1587463201,
|
||||||
'updated_at' => 1599362678,
|
'updated_at' => 1599362678,
|
||||||
@@ -129,10 +138,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
3 =>
|
3 =>
|
||||||
array (
|
array (
|
||||||
'id' => 42,
|
'id' => 43,
|
||||||
'permission_name' => '备份',
|
'permission_name' => '备份',
|
||||||
'parent_id' => 38,
|
'parent_id' => 39,
|
||||||
'level' => '37-38',
|
'level' => '38-39',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -140,9 +149,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'optimize@backup',
|
'permission_mark' => 'optimize@backup',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1587463217,
|
'created_at' => 1587463217,
|
||||||
'updated_at' => 1599362678,
|
'updated_at' => 1599362678,
|
||||||
@@ -152,10 +161,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
1 =>
|
1 =>
|
||||||
array (
|
array (
|
||||||
'id' => 43,
|
'id' => 44,
|
||||||
'permission_name' => '附件管理',
|
'permission_name' => '附件管理',
|
||||||
'parent_id' => 37,
|
'parent_id' => 38,
|
||||||
'level' => '37',
|
'level' => '38',
|
||||||
'route' => '/system/attactments',
|
'route' => '/system/attactments',
|
||||||
'icon' => 'el-icon-folder-opened',
|
'icon' => 'el-icon-folder-opened',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -163,9 +172,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'attactments',
|
'permission_mark' => 'attactments',
|
||||||
'component' => 'attachment',
|
'component' => 'attachment',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 1,
|
'type' => 1,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 10,
|
'sort' => 10,
|
||||||
'created_at' => 1587463302,
|
'created_at' => 1587463302,
|
||||||
'updated_at' => 1599288737,
|
'updated_at' => 1599288737,
|
||||||
@@ -174,10 +183,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
array (
|
array (
|
||||||
0 =>
|
0 =>
|
||||||
array (
|
array (
|
||||||
'id' => 44,
|
'id' => 45,
|
||||||
'permission_name' => '列表',
|
'permission_name' => '列表',
|
||||||
'parent_id' => 43,
|
'parent_id' => 44,
|
||||||
'level' => '37-43',
|
'level' => '38-44',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -185,9 +194,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'attachments@index',
|
'permission_mark' => 'attachments@index',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1587463335,
|
'created_at' => 1587463335,
|
||||||
'updated_at' => 1599217559,
|
'updated_at' => 1599217559,
|
||||||
@@ -195,10 +204,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
1 =>
|
1 =>
|
||||||
array (
|
array (
|
||||||
'id' => 45,
|
'id' => 46,
|
||||||
'permission_name' => '删除',
|
'permission_name' => '删除',
|
||||||
'parent_id' => 43,
|
'parent_id' => 44,
|
||||||
'level' => '37-43',
|
'level' => '38-44',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -206,9 +215,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'attachments@delete',
|
'permission_mark' => 'attachments@delete',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1587463355,
|
'created_at' => 1587463355,
|
||||||
'updated_at' => 1599217559,
|
'updated_at' => 1599217559,
|
||||||
@@ -216,10 +225,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
2 =>
|
2 =>
|
||||||
array (
|
array (
|
||||||
'id' => 46,
|
'id' => 47,
|
||||||
'permission_name' => '上传图片',
|
'permission_name' => '上传图片',
|
||||||
'parent_id' => 43,
|
'parent_id' => 44,
|
||||||
'level' => '37-43',
|
'level' => '38-44',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -227,9 +236,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'upload@image',
|
'permission_mark' => 'upload@image',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1587466919,
|
'created_at' => 1587466919,
|
||||||
'updated_at' => 1599217559,
|
'updated_at' => 1599217559,
|
||||||
@@ -237,10 +246,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
3 =>
|
3 =>
|
||||||
array (
|
array (
|
||||||
'id' => 47,
|
'id' => 48,
|
||||||
'permission_name' => '上传文件',
|
'permission_name' => '上传文件',
|
||||||
'parent_id' => 43,
|
'parent_id' => 44,
|
||||||
'level' => '37-43',
|
'level' => '38-44',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -248,9 +257,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'upload@file',
|
'permission_mark' => 'upload@file',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1587466939,
|
'created_at' => 1587466939,
|
||||||
'updated_at' => 1599217559,
|
'updated_at' => 1599217559,
|
||||||
@@ -260,10 +269,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
2 =>
|
2 =>
|
||||||
array (
|
array (
|
||||||
'id' => 48,
|
'id' => 49,
|
||||||
'permission_name' => '配置管理',
|
'permission_name' => '配置管理',
|
||||||
'parent_id' => 37,
|
'parent_id' => 38,
|
||||||
'level' => '37',
|
'level' => '38',
|
||||||
'route' => '/system/config',
|
'route' => '/system/config',
|
||||||
'icon' => 'el-icon-setting',
|
'icon' => 'el-icon-setting',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -271,9 +280,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'config',
|
'permission_mark' => 'config',
|
||||||
'component' => 'config',
|
'component' => 'config',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 1,
|
'type' => 1,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 9,
|
'sort' => 9,
|
||||||
'created_at' => 1587466991,
|
'created_at' => 1587466991,
|
||||||
'updated_at' => 1599288737,
|
'updated_at' => 1599288737,
|
||||||
@@ -282,10 +291,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
array (
|
array (
|
||||||
0 =>
|
0 =>
|
||||||
array (
|
array (
|
||||||
'id' => 49,
|
'id' => 50,
|
||||||
'permission_name' => '父级配置',
|
'permission_name' => '父级配置',
|
||||||
'parent_id' => 48,
|
'parent_id' => 49,
|
||||||
'level' => '37-48',
|
'level' => '38-49',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -293,9 +302,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'config@parent',
|
'permission_mark' => 'config@parent',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1587467036,
|
'created_at' => 1587467036,
|
||||||
'updated_at' => 1591345651,
|
'updated_at' => 1591345651,
|
||||||
@@ -303,10 +312,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
1 =>
|
1 =>
|
||||||
array (
|
array (
|
||||||
'id' => 50,
|
'id' => 51,
|
||||||
'permission_name' => '存储',
|
'permission_name' => '存储',
|
||||||
'parent_id' => 48,
|
'parent_id' => 49,
|
||||||
'level' => '37-48',
|
'level' => '38-49',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -314,9 +323,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'config@save',
|
'permission_mark' => 'config@save',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1587467052,
|
'created_at' => 1587467052,
|
||||||
'updated_at' => 1587547118,
|
'updated_at' => 1587547118,
|
||||||
@@ -324,10 +333,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
2 =>
|
2 =>
|
||||||
array (
|
array (
|
||||||
'id' => 51,
|
'id' => 52,
|
||||||
'permission_name' => '获取',
|
'permission_name' => '获取',
|
||||||
'parent_id' => 48,
|
'parent_id' => 49,
|
||||||
'level' => '37-48',
|
'level' => '38-49',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -335,9 +344,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'config@read',
|
'permission_mark' => 'config@read',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1587467062,
|
'created_at' => 1587467062,
|
||||||
'updated_at' => 1587547118,
|
'updated_at' => 1587547118,
|
||||||
@@ -347,20 +356,20 @@ class SystemMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
3 =>
|
3 =>
|
||||||
array (
|
array (
|
||||||
'id' => 52,
|
'id' => 53,
|
||||||
'permission_name' => '登陆日志',
|
'permission_name' => '登陆日志',
|
||||||
'parent_id' => 37,
|
'parent_id' => 38,
|
||||||
'level' => '37',
|
'level' => '38',
|
||||||
'route' => '/system/log/operate',
|
'route' => '/system/log/login',
|
||||||
'icon' => 'el-icon-coin',
|
'icon' => 'el-icon-coin',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
'creator_id' => 1,
|
'creator_id' => 1,
|
||||||
'permission_mark' => 'loginLog',
|
'permission_mark' => 'loginLog',
|
||||||
'component' => 'loginLog',
|
'component' => 'loginLog',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 1,
|
'type' => 1,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 5,
|
'sort' => 5,
|
||||||
'created_at' => 1587467150,
|
'created_at' => 1587467150,
|
||||||
'updated_at' => 1599288737,
|
'updated_at' => 1599288737,
|
||||||
@@ -369,10 +378,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
array (
|
array (
|
||||||
0 =>
|
0 =>
|
||||||
array (
|
array (
|
||||||
'id' => 53,
|
'id' => 54,
|
||||||
'permission_name' => '列表',
|
'permission_name' => '列表',
|
||||||
'parent_id' => 52,
|
'parent_id' => 53,
|
||||||
'level' => '37-52',
|
'level' => '38-53',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -380,9 +389,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'loginlog@list',
|
'permission_mark' => 'loginlog@list',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1587467206,
|
'created_at' => 1587467206,
|
||||||
'updated_at' => 1587547118,
|
'updated_at' => 1587547118,
|
||||||
@@ -390,10 +399,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
1 =>
|
1 =>
|
||||||
array (
|
array (
|
||||||
'id' => 54,
|
'id' => 55,
|
||||||
'permission_name' => '清空',
|
'permission_name' => '清空',
|
||||||
'parent_id' => 52,
|
'parent_id' => 53,
|
||||||
'level' => '37-52',
|
'level' => '38-53',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -401,9 +410,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'loginlog@empty',
|
'permission_mark' => 'loginlog@empty',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1587467221,
|
'created_at' => 1587467221,
|
||||||
'updated_at' => 1587547118,
|
'updated_at' => 1587547118,
|
||||||
@@ -413,20 +422,20 @@ class SystemMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
4 =>
|
4 =>
|
||||||
array (
|
array (
|
||||||
'id' => 55,
|
'id' => 56,
|
||||||
'permission_name' => '操作日志',
|
'permission_name' => '操作日志',
|
||||||
'parent_id' => 37,
|
'parent_id' => 38,
|
||||||
'level' => '37',
|
'level' => '38',
|
||||||
'route' => '/system/log/login',
|
'route' => '/system/log/operate',
|
||||||
'icon' => 'el-icon-house',
|
'icon' => 'el-icon-house',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
'creator_id' => 1,
|
'creator_id' => 1,
|
||||||
'permission_mark' => 'operateLog',
|
'permission_mark' => 'operateLog',
|
||||||
'component' => 'operateLog',
|
'component' => 'operateLog',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 1,
|
'type' => 1,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1587467180,
|
'created_at' => 1587467180,
|
||||||
'updated_at' => 1599288737,
|
'updated_at' => 1599288737,
|
||||||
@@ -435,10 +444,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
array (
|
array (
|
||||||
0 =>
|
0 =>
|
||||||
array (
|
array (
|
||||||
'id' => 56,
|
'id' => 57,
|
||||||
'permission_name' => '列表',
|
'permission_name' => '列表',
|
||||||
'parent_id' => 55,
|
'parent_id' => 56,
|
||||||
'level' => '37-55',
|
'level' => '38-56',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -446,9 +455,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'operatelog@list',
|
'permission_mark' => 'operatelog@list',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1587467246,
|
'created_at' => 1587467246,
|
||||||
'updated_at' => 1587547118,
|
'updated_at' => 1587547118,
|
||||||
@@ -456,10 +465,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
1 =>
|
1 =>
|
||||||
array (
|
array (
|
||||||
'id' => 57,
|
'id' => 58,
|
||||||
'permission_name' => '清空',
|
'permission_name' => '清空',
|
||||||
'parent_id' => 55,
|
'parent_id' => 56,
|
||||||
'level' => '37-55',
|
'level' => '38-56',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -467,9 +476,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'operatelog@empty',
|
'permission_mark' => 'operatelog@empty',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1587467266,
|
'created_at' => 1587467266,
|
||||||
'updated_at' => 1587547118,
|
'updated_at' => 1587547118,
|
||||||
@@ -479,10 +488,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
5 =>
|
5 =>
|
||||||
array (
|
array (
|
||||||
'id' => 58,
|
'id' => 59,
|
||||||
'permission_name' => '代码生成',
|
'permission_name' => '代码生成',
|
||||||
'parent_id' => 37,
|
'parent_id' => 38,
|
||||||
'level' => '37',
|
'level' => '38',
|
||||||
'route' => '/system/generate',
|
'route' => '/system/generate',
|
||||||
'icon' => 'el-icon-scissors',
|
'icon' => 'el-icon-scissors',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -490,9 +499,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'generate',
|
'permission_mark' => 'generate',
|
||||||
'component' => 'generate',
|
'component' => 'generate',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 1,
|
'type' => 1,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1587717452,
|
'created_at' => 1587717452,
|
||||||
'updated_at' => 1599288737,
|
'updated_at' => 1599288737,
|
||||||
@@ -501,10 +510,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
array (
|
array (
|
||||||
0 =>
|
0 =>
|
||||||
array (
|
array (
|
||||||
'id' => 59,
|
'id' => 60,
|
||||||
'permission_name' => '生成',
|
'permission_name' => '生成',
|
||||||
'parent_id' => 58,
|
'parent_id' => 59,
|
||||||
'level' => '37-58',
|
'level' => '38-59',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -512,9 +521,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'generate@save',
|
'permission_mark' => 'generate@save',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1588110923,
|
'created_at' => 1588110923,
|
||||||
'updated_at' => 1599217574,
|
'updated_at' => 1599217574,
|
||||||
@@ -522,10 +531,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
1 =>
|
1 =>
|
||||||
array (
|
array (
|
||||||
'id' => 60,
|
'id' => 61,
|
||||||
'permission_name' => '预览',
|
'permission_name' => '预览',
|
||||||
'parent_id' => 58,
|
'parent_id' => 59,
|
||||||
'level' => '37-58',
|
'level' => '38-59',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -533,9 +542,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'generate@preview',
|
'permission_mark' => 'generate@preview',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1588110962,
|
'created_at' => 1588110962,
|
||||||
'updated_at' => 1599217574,
|
'updated_at' => 1599217574,
|
||||||
@@ -545,10 +554,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
6 =>
|
6 =>
|
||||||
array (
|
array (
|
||||||
'id' => 68,
|
'id' => 62,
|
||||||
'permission_name' => '敏感词库',
|
'permission_name' => '敏感词库',
|
||||||
'parent_id' => 37,
|
'parent_id' => 38,
|
||||||
'level' => '37',
|
'level' => '38',
|
||||||
'route' => '/sensitive/word',
|
'route' => '/sensitive/word',
|
||||||
'icon' => 'el-icon-folder-delete',
|
'icon' => 'el-icon-folder-delete',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -556,9 +565,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'sensitiveWord',
|
'permission_mark' => 'sensitiveWord',
|
||||||
'component' => 'sensitiveWord',
|
'component' => 'sensitiveWord',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 1,
|
'type' => 1,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1592375865,
|
'created_at' => 1592375865,
|
||||||
'updated_at' => 1599288737,
|
'updated_at' => 1599288737,
|
||||||
@@ -567,10 +576,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
array (
|
array (
|
||||||
0 =>
|
0 =>
|
||||||
array (
|
array (
|
||||||
'id' => 69,
|
'id' => 63,
|
||||||
'permission_name' => '列表',
|
'permission_name' => '列表',
|
||||||
'parent_id' => 68,
|
'parent_id' => 62,
|
||||||
'level' => '37-68',
|
'level' => '38-62',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -578,9 +587,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'sensitiveWord@index',
|
'permission_mark' => 'sensitiveWord@index',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1592382167,
|
'created_at' => 1592382167,
|
||||||
'updated_at' => 1593589434,
|
'updated_at' => 1593589434,
|
||||||
@@ -588,10 +597,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
1 =>
|
1 =>
|
||||||
array (
|
array (
|
||||||
'id' => 70,
|
'id' => 64,
|
||||||
'permission_name' => '新增',
|
'permission_name' => '新增',
|
||||||
'parent_id' => 68,
|
'parent_id' => 62,
|
||||||
'level' => '37-68',
|
'level' => '38-62',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -599,9 +608,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'sensitiveWord@save',
|
'permission_mark' => 'sensitiveWord@save',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1592382179,
|
'created_at' => 1592382179,
|
||||||
'updated_at' => 1593589434,
|
'updated_at' => 1593589434,
|
||||||
@@ -609,10 +618,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
2 =>
|
2 =>
|
||||||
array (
|
array (
|
||||||
'id' => 71,
|
'id' => 65,
|
||||||
'permission_name' => '更新',
|
'permission_name' => '更新',
|
||||||
'parent_id' => 68,
|
'parent_id' => 62,
|
||||||
'level' => '37-68',
|
'level' => '38-62',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -620,9 +629,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'sensitiveWord@update',
|
'permission_mark' => 'sensitiveWord@update',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1592382192,
|
'created_at' => 1592382192,
|
||||||
'updated_at' => 1593589434,
|
'updated_at' => 1593589434,
|
||||||
@@ -630,10 +639,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
3 =>
|
3 =>
|
||||||
array (
|
array (
|
||||||
'id' => 72,
|
'id' => 66,
|
||||||
'permission_name' => '删除',
|
'permission_name' => '删除',
|
||||||
'parent_id' => 68,
|
'parent_id' => 62,
|
||||||
'level' => '37-68',
|
'level' => '38-62',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -641,9 +650,9 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'sensitiveWord@delete',
|
'permission_mark' => 'sensitiveWord@delete',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1592382202,
|
'created_at' => 1592382202,
|
||||||
'updated_at' => 1593589434,
|
'updated_at' => 1593589434,
|
||||||
@@ -653,10 +662,10 @@ class SystemMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
7 =>
|
7 =>
|
||||||
array (
|
array (
|
||||||
'id' => 101,
|
'id' => 67,
|
||||||
'permission_name' => '开发者',
|
'permission_name' => '开发者',
|
||||||
'parent_id' => 37,
|
'parent_id' => 38,
|
||||||
'level' => '37',
|
'level' => '38',
|
||||||
'route' => '/system/develop',
|
'route' => '/system/develop',
|
||||||
'icon' => 'el-icon-rank',
|
'icon' => 'el-icon-rank',
|
||||||
'module' => 'system',
|
'module' => 'system',
|
||||||
@@ -664,14 +673,101 @@ class SystemMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'develop',
|
'permission_mark' => 'develop',
|
||||||
'component' => 'develop',
|
'component' => 'develop',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 1,
|
'type' => 1,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1594626307,
|
'created_at' => 1594626307,
|
||||||
'updated_at' => 1599288737,
|
'updated_at' => 1599288737,
|
||||||
'deleted_at' => 0,
|
'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,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@@ -4,18 +4,13 @@ namespace catchAdmin\system\model\search;
|
|||||||
|
|
||||||
trait LoginLogSearch
|
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);
|
return $query->whereTime('login_at', '<=', strtotime($value));
|
||||||
}
|
|
||||||
|
|
||||||
public function searchLoginAtAttr($query, $value, $data)
|
|
||||||
{
|
|
||||||
return $query->whereTime('login_at', 'between', $value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace catchAdmin\system\model\search;
|
namespace catchAdmin\system\model\search;
|
||||||
|
|
||||||
|
use catchAdmin\permissions\model\Users;
|
||||||
|
|
||||||
trait OperateLogSearch
|
trait OperateLogSearch
|
||||||
{
|
{
|
||||||
public function searchModuleAttr($query, $value, $data)
|
public function searchModuleAttr($query, $value, $data)
|
||||||
@@ -16,7 +18,7 @@ trait OperateLogSearch
|
|||||||
|
|
||||||
public function searchCreatorAttr($query, $value, $data)
|
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)
|
public function searchCreateAtAttr($query, $value, $data)
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
"description": "系统管理模块",
|
"description": "系统管理模块",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"order": 2,
|
"order": 100,
|
||||||
"services": [
|
"services": [
|
||||||
"\\catchAdmin\\system\\SystemService"
|
"\\catchAdmin\\system\\SystemService"
|
||||||
],
|
],
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
$router->group(function () use ($router) {
|
$router->group(function () use ($router) {
|
||||||
// 登录日志
|
// 登录日志
|
||||||
$router->get('log/login', '\catchAdmin\system\controller\LoginLog@list');
|
$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->get('log/operate', '\catchAdmin\system\controller\OperateLog@list');
|
||||||
// $router->delete('empty/log/operate', '\catchAdmin\system\controller\OperateLog@empty');
|
// $router->delete('empty/log/operate', '\catchAdmin\system\controller\OperateLog@empty');
|
||||||
@@ -31,9 +31,18 @@ $router->group(function () use ($router) {
|
|||||||
|
|
||||||
// 敏感词
|
// 敏感词
|
||||||
$router->resource('sensitive/word', '\catchAdmin\system\controller\SensitiveWord');
|
$router->resource('sensitive/word', '\catchAdmin\system\controller\SensitiveWord');
|
||||||
})->middleware('auth');
|
|
||||||
|
|
||||||
//developer路由
|
//developer路由
|
||||||
$router->resource('developer', '\catchAdmin\system\controller\Developer')->middleware('auth');
|
$router->resource('developer', '\catchAdmin\system\controller\Developer')->middleware('auth');
|
||||||
// 开发者认证
|
// 开发者认证
|
||||||
$router->post('developer/authenticate', '\catchAdmin\system\controller\Developer@authenticate');
|
$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());
|
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()));
|
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()));
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 删除
|
* 删除
|
||||||
*
|
*
|
||||||
|
@@ -1,4 +1,13 @@
|
|||||||
<?php
|
<?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;
|
use think\migration\Seeder;
|
||||||
|
|
||||||
@@ -22,7 +31,7 @@ class WechatMenusSeed extends Seeder
|
|||||||
return array (
|
return array (
|
||||||
0 =>
|
0 =>
|
||||||
array (
|
array (
|
||||||
'id' => 66,
|
'id' => 71,
|
||||||
'permission_name' => '微信管理',
|
'permission_name' => '微信管理',
|
||||||
'parent_id' => 0,
|
'parent_id' => 0,
|
||||||
'level' => '',
|
'level' => '',
|
||||||
@@ -33,9 +42,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'wechat',
|
'permission_mark' => 'wechat',
|
||||||
'component' => 'layout',
|
'component' => 'layout',
|
||||||
'redirect' => '/wechat/menus',
|
'redirect' => '/wechat/menus',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 1,
|
'type' => 1,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1591603025,
|
'created_at' => 1591603025,
|
||||||
'updated_at' => 1599371183,
|
'updated_at' => 1599371183,
|
||||||
@@ -44,32 +53,32 @@ class WechatMenusSeed extends Seeder
|
|||||||
array (
|
array (
|
||||||
0 =>
|
0 =>
|
||||||
array (
|
array (
|
||||||
'id' => 67,
|
'id' => 72,
|
||||||
'permission_name' => '微信菜单',
|
'permission_name' => '微信菜单',
|
||||||
'parent_id' => 66,
|
'parent_id' => 71,
|
||||||
'level' => '66',
|
'level' => '71',
|
||||||
'route' => '/wechat/menus',
|
'route' => '/wechat/menus',
|
||||||
'icon' => 'table',
|
'icon' => 'table',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
'creator_id' => 1,
|
'creator_id' => 1,
|
||||||
'permission_mark' => 'menus',
|
'permission_mark' => 'menus',
|
||||||
'component' => 'menus',
|
'component' => 'wechatMenus',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 1,
|
'type' => 1,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 18,
|
'sort' => 18,
|
||||||
'created_at' => 1591603088,
|
'created_at' => 1591603088,
|
||||||
'updated_at' => 1599371183,
|
'updated_at' => 1599963701,
|
||||||
'deleted_at' => 0,
|
'deleted_at' => 0,
|
||||||
'children' =>
|
'children' =>
|
||||||
array (
|
array (
|
||||||
0 =>
|
0 =>
|
||||||
array (
|
array (
|
||||||
'id' => 95,
|
'id' => 73,
|
||||||
'permission_name' => '列表',
|
'permission_name' => '列表',
|
||||||
'parent_id' => 67,
|
'parent_id' => 72,
|
||||||
'level' => '66-67',
|
'level' => '71-72',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -77,20 +86,20 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'menus@index',
|
'permission_mark' => 'menus@index',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1593304908,
|
'created_at' => 1593304908,
|
||||||
'updated_at' => 1599371167,
|
'updated_at' => 1599963701,
|
||||||
'deleted_at' => 0,
|
'deleted_at' => 0,
|
||||||
),
|
),
|
||||||
1 =>
|
1 =>
|
||||||
array (
|
array (
|
||||||
'id' => 96,
|
'id' => 74,
|
||||||
'permission_name' => '保存',
|
'permission_name' => '保存',
|
||||||
'parent_id' => 67,
|
'parent_id' => 72,
|
||||||
'level' => '66-67',
|
'level' => '71-72',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -98,20 +107,20 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'menus@save',
|
'permission_mark' => 'menus@save',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1593304915,
|
'created_at' => 1593304915,
|
||||||
'updated_at' => 1599371167,
|
'updated_at' => 1599963701,
|
||||||
'deleted_at' => 0,
|
'deleted_at' => 0,
|
||||||
),
|
),
|
||||||
2 =>
|
2 =>
|
||||||
array (
|
array (
|
||||||
'id' => 97,
|
'id' => 75,
|
||||||
'permission_name' => '更新',
|
'permission_name' => '更新',
|
||||||
'parent_id' => 67,
|
'parent_id' => 72,
|
||||||
'level' => '66-67',
|
'level' => '71-72',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -119,20 +128,20 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'menus@update',
|
'permission_mark' => 'menus@update',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1593304923,
|
'created_at' => 1593304923,
|
||||||
'updated_at' => 1599371167,
|
'updated_at' => 1599963701,
|
||||||
'deleted_at' => 0,
|
'deleted_at' => 0,
|
||||||
),
|
),
|
||||||
3 =>
|
3 =>
|
||||||
array (
|
array (
|
||||||
'id' => 98,
|
'id' => 76,
|
||||||
'permission_name' => '删除',
|
'permission_name' => '删除',
|
||||||
'parent_id' => 67,
|
'parent_id' => 72,
|
||||||
'level' => '66-67',
|
'level' => '71-72',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -140,20 +149,20 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'menus@delete',
|
'permission_mark' => 'menus@delete',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1593304929,
|
'created_at' => 1593304929,
|
||||||
'updated_at' => 1599371167,
|
'updated_at' => 1599963701,
|
||||||
'deleted_at' => 0,
|
'deleted_at' => 0,
|
||||||
),
|
),
|
||||||
4 =>
|
4 =>
|
||||||
array (
|
array (
|
||||||
'id' => 99,
|
'id' => 77,
|
||||||
'permission_name' => '同步',
|
'permission_name' => '同步',
|
||||||
'parent_id' => 67,
|
'parent_id' => 72,
|
||||||
'level' => '66-67',
|
'level' => '71-72',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -161,22 +170,22 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'menus@sync',
|
'permission_mark' => 'menus@sync',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1593304938,
|
'created_at' => 1593304938,
|
||||||
'updated_at' => 1599371167,
|
'updated_at' => 1599963701,
|
||||||
'deleted_at' => 0,
|
'deleted_at' => 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
1 =>
|
1 =>
|
||||||
array (
|
array (
|
||||||
'id' => 75,
|
'id' => 78,
|
||||||
'permission_name' => '用户管理',
|
'permission_name' => '用户管理',
|
||||||
'parent_id' => 66,
|
'parent_id' => 71,
|
||||||
'level' => '66',
|
'level' => '71',
|
||||||
'route' => '/wechat/users',
|
'route' => '/wechat/users',
|
||||||
'icon' => 'el-icon-s-custom',
|
'icon' => 'el-icon-s-custom',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -184,9 +193,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'users',
|
'permission_mark' => 'users',
|
||||||
'component' => 'routerView',
|
'component' => 'routerView',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 1,
|
'type' => 1,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1592624761,
|
'created_at' => 1592624761,
|
||||||
'updated_at' => 1599371697,
|
'updated_at' => 1599371697,
|
||||||
@@ -195,10 +204,10 @@ class WechatMenusSeed extends Seeder
|
|||||||
array (
|
array (
|
||||||
0 =>
|
0 =>
|
||||||
array (
|
array (
|
||||||
'id' => 76,
|
'id' => 79,
|
||||||
'permission_name' => '微信用户',
|
'permission_name' => '微信用户',
|
||||||
'parent_id' => 75,
|
'parent_id' => 78,
|
||||||
'level' => '66-75',
|
'level' => '71-78',
|
||||||
'route' => '/wechat/users/user',
|
'route' => '/wechat/users/user',
|
||||||
'icon' => 'user',
|
'icon' => 'user',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -206,9 +215,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'users',
|
'permission_mark' => 'users',
|
||||||
'component' => 'wechatUsers',
|
'component' => 'wechatUsers',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 1,
|
'type' => 1,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1592624799,
|
'created_at' => 1592624799,
|
||||||
'updated_at' => 1599376002,
|
'updated_at' => 1599376002,
|
||||||
@@ -217,10 +226,10 @@ class WechatMenusSeed extends Seeder
|
|||||||
array (
|
array (
|
||||||
0 =>
|
0 =>
|
||||||
array (
|
array (
|
||||||
'id' => 90,
|
'id' => 80,
|
||||||
'permission_name' => '列表',
|
'permission_name' => '列表',
|
||||||
'parent_id' => 76,
|
'parent_id' => 79,
|
||||||
'level' => '66-75-76',
|
'level' => '71-78-79',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -228,9 +237,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'users@index',
|
'permission_mark' => 'users@index',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1593304869,
|
'created_at' => 1593304869,
|
||||||
'updated_at' => 1599376002,
|
'updated_at' => 1599376002,
|
||||||
@@ -238,10 +247,10 @@ class WechatMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
1 =>
|
1 =>
|
||||||
array (
|
array (
|
||||||
'id' => 91,
|
'id' => 81,
|
||||||
'permission_name' => '标记',
|
'permission_name' => '标记',
|
||||||
'parent_id' => 76,
|
'parent_id' => 79,
|
||||||
'level' => '66-75-76',
|
'level' => '71-78-79',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -249,9 +258,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'users@remark',
|
'permission_mark' => 'users@remark',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1593304876,
|
'created_at' => 1593304876,
|
||||||
'updated_at' => 1599376002,
|
'updated_at' => 1599376002,
|
||||||
@@ -259,10 +268,10 @@ class WechatMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
2 =>
|
2 =>
|
||||||
array (
|
array (
|
||||||
'id' => 92,
|
'id' => 82,
|
||||||
'permission_name' => '拉黑',
|
'permission_name' => '拉黑',
|
||||||
'parent_id' => 76,
|
'parent_id' => 79,
|
||||||
'level' => '66-75-76',
|
'level' => '71-78-79',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -270,9 +279,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'users@block',
|
'permission_mark' => 'users@block',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1593304884,
|
'created_at' => 1593304884,
|
||||||
'updated_at' => 1599376002,
|
'updated_at' => 1599376002,
|
||||||
@@ -280,10 +289,10 @@ class WechatMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
3 =>
|
3 =>
|
||||||
array (
|
array (
|
||||||
'id' => 93,
|
'id' => 83,
|
||||||
'permission_name' => '打标签',
|
'permission_name' => '打标签',
|
||||||
'parent_id' => 76,
|
'parent_id' => 79,
|
||||||
'level' => '66-75-76',
|
'level' => '71-78-79',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -291,9 +300,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'users@tag',
|
'permission_mark' => 'users@tag',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1593304892,
|
'created_at' => 1593304892,
|
||||||
'updated_at' => 1599376002,
|
'updated_at' => 1599376002,
|
||||||
@@ -301,10 +310,10 @@ class WechatMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
4 =>
|
4 =>
|
||||||
array (
|
array (
|
||||||
'id' => 94,
|
'id' => 84,
|
||||||
'permission_name' => '同步',
|
'permission_name' => '同步',
|
||||||
'parent_id' => 76,
|
'parent_id' => 79,
|
||||||
'level' => '66-75-76',
|
'level' => '71-78-79',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -312,9 +321,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'users@sync',
|
'permission_mark' => 'users@sync',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1593304900,
|
'created_at' => 1593304900,
|
||||||
'updated_at' => 1599376002,
|
'updated_at' => 1599376002,
|
||||||
@@ -324,10 +333,10 @@ class WechatMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
1 =>
|
1 =>
|
||||||
array (
|
array (
|
||||||
'id' => 77,
|
'id' => 85,
|
||||||
'permission_name' => '微信标签',
|
'permission_name' => '微信标签',
|
||||||
'parent_id' => 75,
|
'parent_id' => 78,
|
||||||
'level' => '66-75',
|
'level' => '71-78',
|
||||||
'route' => '/wechat/users/tag',
|
'route' => '/wechat/users/tag',
|
||||||
'icon' => 'el-icon-paperclip',
|
'icon' => 'el-icon-paperclip',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -335,9 +344,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'tags',
|
'permission_mark' => 'tags',
|
||||||
'component' => 'wechatTags',
|
'component' => 'wechatTags',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 1,
|
'type' => 1,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1592722634,
|
'created_at' => 1592722634,
|
||||||
'updated_at' => 1599376011,
|
'updated_at' => 1599376011,
|
||||||
@@ -346,10 +355,10 @@ class WechatMenusSeed extends Seeder
|
|||||||
array (
|
array (
|
||||||
0 =>
|
0 =>
|
||||||
array (
|
array (
|
||||||
'id' => 84,
|
'id' => 86,
|
||||||
'permission_name' => '列表',
|
'permission_name' => '列表',
|
||||||
'parent_id' => 77,
|
'parent_id' => 85,
|
||||||
'level' => '66-75-77',
|
'level' => '71-78-85',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -357,9 +366,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'tags@index',
|
'permission_mark' => 'tags@index',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1593304575,
|
'created_at' => 1593304575,
|
||||||
'updated_at' => 1599376011,
|
'updated_at' => 1599376011,
|
||||||
@@ -367,10 +376,10 @@ class WechatMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
1 =>
|
1 =>
|
||||||
array (
|
array (
|
||||||
'id' => 85,
|
'id' => 87,
|
||||||
'permission_name' => '新增',
|
'permission_name' => '新增',
|
||||||
'parent_id' => 77,
|
'parent_id' => 85,
|
||||||
'level' => '66-75-77',
|
'level' => '71-78-85',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -378,9 +387,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'tags@save',
|
'permission_mark' => 'tags@save',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1593304592,
|
'created_at' => 1593304592,
|
||||||
'updated_at' => 1599376011,
|
'updated_at' => 1599376011,
|
||||||
@@ -388,10 +397,10 @@ class WechatMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
2 =>
|
2 =>
|
||||||
array (
|
array (
|
||||||
'id' => 86,
|
'id' => 88,
|
||||||
'permission_name' => '获取',
|
'permission_name' => '获取',
|
||||||
'parent_id' => 77,
|
'parent_id' => 85,
|
||||||
'level' => '66-75-77',
|
'level' => '71-78-85',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -399,9 +408,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'tags@read',
|
'permission_mark' => 'tags@read',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1593304830,
|
'created_at' => 1593304830,
|
||||||
'updated_at' => 1599376011,
|
'updated_at' => 1599376011,
|
||||||
@@ -409,10 +418,10 @@ class WechatMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
3 =>
|
3 =>
|
||||||
array (
|
array (
|
||||||
'id' => 87,
|
'id' => 89,
|
||||||
'permission_name' => '更新',
|
'permission_name' => '更新',
|
||||||
'parent_id' => 77,
|
'parent_id' => 85,
|
||||||
'level' => '66-75-77',
|
'level' => '71-78-85',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -420,9 +429,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'tags@update',
|
'permission_mark' => 'tags@update',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1593304837,
|
'created_at' => 1593304837,
|
||||||
'updated_at' => 1599376011,
|
'updated_at' => 1599376011,
|
||||||
@@ -430,10 +439,10 @@ class WechatMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
4 =>
|
4 =>
|
||||||
array (
|
array (
|
||||||
'id' => 88,
|
'id' => 90,
|
||||||
'permission_name' => '删除',
|
'permission_name' => '删除',
|
||||||
'parent_id' => 77,
|
'parent_id' => 85,
|
||||||
'level' => '66-75-77',
|
'level' => '71-78-85',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -441,9 +450,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'tags@delete',
|
'permission_mark' => 'tags@delete',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1593304846,
|
'created_at' => 1593304846,
|
||||||
'updated_at' => 1599376011,
|
'updated_at' => 1599376011,
|
||||||
@@ -451,10 +460,10 @@ class WechatMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
5 =>
|
5 =>
|
||||||
array (
|
array (
|
||||||
'id' => 89,
|
'id' => 91,
|
||||||
'permission_name' => '同步',
|
'permission_name' => '同步',
|
||||||
'parent_id' => 77,
|
'parent_id' => 85,
|
||||||
'level' => '66-75-77',
|
'level' => '71-78-85',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -462,9 +471,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'tags@sync',
|
'permission_mark' => 'tags@sync',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1593304859,
|
'created_at' => 1593304859,
|
||||||
'updated_at' => 1599376011,
|
'updated_at' => 1599376011,
|
||||||
@@ -476,10 +485,10 @@ class WechatMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
2 =>
|
2 =>
|
||||||
array (
|
array (
|
||||||
'id' => 78,
|
'id' => 92,
|
||||||
'permission_name' => '图文管理',
|
'permission_name' => '图文管理',
|
||||||
'parent_id' => 66,
|
'parent_id' => 71,
|
||||||
'level' => '66',
|
'level' => '71',
|
||||||
'route' => '/wechat/graphic',
|
'route' => '/wechat/graphic',
|
||||||
'icon' => 'el-icon-document-add',
|
'icon' => 'el-icon-document-add',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -487,9 +496,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'graphic',
|
'permission_mark' => 'graphic',
|
||||||
'component' => 'wechatGraphic',
|
'component' => 'wechatGraphic',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 1,
|
'type' => 1,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1593227704,
|
'created_at' => 1593227704,
|
||||||
'updated_at' => 1599371183,
|
'updated_at' => 1599371183,
|
||||||
@@ -498,10 +507,10 @@ class WechatMenusSeed extends Seeder
|
|||||||
array (
|
array (
|
||||||
0 =>
|
0 =>
|
||||||
array (
|
array (
|
||||||
'id' => 79,
|
'id' => 93,
|
||||||
'permission_name' => '新增',
|
'permission_name' => '新增',
|
||||||
'parent_id' => 78,
|
'parent_id' => 92,
|
||||||
'level' => '66-78',
|
'level' => '71-92',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -509,9 +518,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'graphic@save',
|
'permission_mark' => 'graphic@save',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1593304490,
|
'created_at' => 1593304490,
|
||||||
'updated_at' => 1595978929,
|
'updated_at' => 1595978929,
|
||||||
@@ -519,10 +528,10 @@ class WechatMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
1 =>
|
1 =>
|
||||||
array (
|
array (
|
||||||
'id' => 80,
|
'id' => 94,
|
||||||
'permission_name' => '获取',
|
'permission_name' => '获取',
|
||||||
'parent_id' => 78,
|
'parent_id' => 92,
|
||||||
'level' => '66-78',
|
'level' => '71-92',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -530,9 +539,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'graphic@read',
|
'permission_mark' => 'graphic@read',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1593304510,
|
'created_at' => 1593304510,
|
||||||
'updated_at' => 1595978929,
|
'updated_at' => 1595978929,
|
||||||
@@ -540,10 +549,10 @@ class WechatMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
2 =>
|
2 =>
|
||||||
array (
|
array (
|
||||||
'id' => 81,
|
'id' => 95,
|
||||||
'permission_name' => '列表',
|
'permission_name' => '列表',
|
||||||
'parent_id' => 78,
|
'parent_id' => 92,
|
||||||
'level' => '66-78',
|
'level' => '71-92',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -551,9 +560,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'graphic@index',
|
'permission_mark' => 'graphic@index',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 2,
|
'sort' => 2,
|
||||||
'created_at' => 1593304520,
|
'created_at' => 1593304520,
|
||||||
'updated_at' => 1595978929,
|
'updated_at' => 1595978929,
|
||||||
@@ -561,10 +570,10 @@ class WechatMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
3 =>
|
3 =>
|
||||||
array (
|
array (
|
||||||
'id' => 82,
|
'id' => 96,
|
||||||
'permission_name' => '更新',
|
'permission_name' => '更新',
|
||||||
'parent_id' => 78,
|
'parent_id' => 92,
|
||||||
'level' => '66-78',
|
'level' => '71-92',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -572,9 +581,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'graphic@update',
|
'permission_mark' => 'graphic@update',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1593304530,
|
'created_at' => 1593304530,
|
||||||
'updated_at' => 1595978929,
|
'updated_at' => 1595978929,
|
||||||
@@ -582,10 +591,10 @@ class WechatMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
4 =>
|
4 =>
|
||||||
array (
|
array (
|
||||||
'id' => 83,
|
'id' => 97,
|
||||||
'permission_name' => '删除',
|
'permission_name' => '删除',
|
||||||
'parent_id' => 78,
|
'parent_id' => 92,
|
||||||
'level' => '66-78',
|
'level' => '71-92',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -593,9 +602,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'graphic@delete',
|
'permission_mark' => 'graphic@delete',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1593304537,
|
'created_at' => 1593304537,
|
||||||
'updated_at' => 1595978929,
|
'updated_at' => 1595978929,
|
||||||
@@ -605,10 +614,10 @@ class WechatMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
3 =>
|
3 =>
|
||||||
array (
|
array (
|
||||||
'id' => 100,
|
'id' => 98,
|
||||||
'permission_name' => '微信回复',
|
'permission_name' => '微信回复',
|
||||||
'parent_id' => 66,
|
'parent_id' => 71,
|
||||||
'level' => '66',
|
'level' => '71',
|
||||||
'route' => '/wechat/reply',
|
'route' => '/wechat/reply',
|
||||||
'icon' => 'el-icon-chat-line-round',
|
'icon' => 'el-icon-chat-line-round',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -616,9 +625,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'reply',
|
'permission_mark' => 'reply',
|
||||||
'component' => 'wechatReply',
|
'component' => 'wechatReply',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 1,
|
'type' => 1,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1593323887,
|
'created_at' => 1593323887,
|
||||||
'updated_at' => 1599371183,
|
'updated_at' => 1599371183,
|
||||||
@@ -627,10 +636,10 @@ class WechatMenusSeed extends Seeder
|
|||||||
array (
|
array (
|
||||||
0 =>
|
0 =>
|
||||||
array (
|
array (
|
||||||
'id' => 111,
|
'id' => 99,
|
||||||
'permission_name' => '列表',
|
'permission_name' => '列表',
|
||||||
'parent_id' => 100,
|
'parent_id' => 98,
|
||||||
'level' => '66-100',
|
'level' => '71-98',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -638,9 +647,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'reply@index',
|
'permission_mark' => 'reply@index',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1599292333,
|
'created_at' => 1599292333,
|
||||||
'updated_at' => 1599292373,
|
'updated_at' => 1599292373,
|
||||||
@@ -648,10 +657,10 @@ class WechatMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
1 =>
|
1 =>
|
||||||
array (
|
array (
|
||||||
'id' => 112,
|
'id' => 100,
|
||||||
'permission_name' => '新增',
|
'permission_name' => '新增',
|
||||||
'parent_id' => 100,
|
'parent_id' => 98,
|
||||||
'level' => '66-100',
|
'level' => '71-98',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -659,9 +668,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'reply@save',
|
'permission_mark' => 'reply@save',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1599292344,
|
'created_at' => 1599292344,
|
||||||
'updated_at' => 1599292344,
|
'updated_at' => 1599292344,
|
||||||
@@ -669,10 +678,10 @@ class WechatMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
2 =>
|
2 =>
|
||||||
array (
|
array (
|
||||||
'id' => 113,
|
'id' => 101,
|
||||||
'permission_name' => '删除',
|
'permission_name' => '删除',
|
||||||
'parent_id' => 100,
|
'parent_id' => 98,
|
||||||
'level' => '66-100',
|
'level' => '71-98',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -680,9 +689,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'reply@delete',
|
'permission_mark' => 'reply@delete',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1599292351,
|
'created_at' => 1599292351,
|
||||||
'updated_at' => 1599292351,
|
'updated_at' => 1599292351,
|
||||||
@@ -690,10 +699,10 @@ class WechatMenusSeed extends Seeder
|
|||||||
),
|
),
|
||||||
3 =>
|
3 =>
|
||||||
array (
|
array (
|
||||||
'id' => 114,
|
'id' => 102,
|
||||||
'permission_name' => '禁用/启用',
|
'permission_name' => '禁用/启用',
|
||||||
'parent_id' => 100,
|
'parent_id' => 98,
|
||||||
'level' => '66-100',
|
'level' => '71-98',
|
||||||
'route' => '',
|
'route' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'module' => 'wechat',
|
'module' => 'wechat',
|
||||||
@@ -701,9 +710,9 @@ class WechatMenusSeed extends Seeder
|
|||||||
'permission_mark' => 'reply@disOrEnable',
|
'permission_mark' => 'reply@disOrEnable',
|
||||||
'component' => '',
|
'component' => '',
|
||||||
'redirect' => '',
|
'redirect' => '',
|
||||||
'hidden' => 1,
|
|
||||||
'keepalive' => 1,
|
'keepalive' => 1,
|
||||||
'type' => 2,
|
'type' => 2,
|
||||||
|
'hidden' => 1,
|
||||||
'sort' => 1,
|
'sort' => 1,
|
||||||
'created_at' => 1599292363,
|
'created_at' => 1599292363,
|
||||||
'updated_at' => 1599292363,
|
'updated_at' => 1599292363,
|
||||||
|
@@ -45,6 +45,9 @@ class WechatMenusRepository extends CatchRepository
|
|||||||
* @time 2020年06月26日
|
* @time 2020年06月26日
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @return mixed
|
* @return mixed
|
||||||
|
* @throws \think\db\exception\DbException
|
||||||
|
* @throws \think\db\exception\ModelNotFoundException
|
||||||
|
* @throws \think\db\exception\DataNotFoundException
|
||||||
*/
|
*/
|
||||||
public function storeBy(array $data)
|
public function storeBy(array $data)
|
||||||
{
|
{
|
||||||
@@ -55,6 +58,8 @@ class WechatMenusRepository extends CatchRepository
|
|||||||
$data['parent_id'] = $parentId;
|
$data['parent_id'] = $parentId;
|
||||||
$data['key'] = $data['type'] . '_' . rand(10000, 999999);
|
$data['key'] = $data['type'] . '_' . rand(10000, 999999);
|
||||||
|
|
||||||
|
$data['created_at'] = $data['updated_at'] = time();
|
||||||
|
|
||||||
if (parent::storeBy($data)) {
|
if (parent::storeBy($data)) {
|
||||||
return $this->syncToWechat();
|
return $this->syncToWechat();
|
||||||
}// TODO: Change the autogenerated stub
|
}// TODO: Change the autogenerated stub
|
||||||
@@ -75,6 +80,8 @@ class WechatMenusRepository extends CatchRepository
|
|||||||
*/
|
*/
|
||||||
public function updateBy(int $id, array $data)
|
public function updateBy(int $id, array $data)
|
||||||
{
|
{
|
||||||
|
$data['updated_at'] = time();
|
||||||
|
|
||||||
if (parent::updateBy($id, $data)) {
|
if (parent::updateBy($id, $data)) {
|
||||||
return $this->syncToWechat();
|
return $this->syncToWechat();
|
||||||
}
|
}
|
||||||
|
@@ -28,6 +28,13 @@ class WechatReplyRepository extends CatchRepository
|
|||||||
return $this->reply;
|
return $this->reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 存储
|
||||||
|
*
|
||||||
|
* @time 2020年09月13日
|
||||||
|
* @param array $data
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
public function storeBy(array $data)
|
public function storeBy(array $data)
|
||||||
{
|
{
|
||||||
$material = WeChat::officialAccount()->material;
|
$material = WeChat::officialAccount()->material;
|
||||||
@@ -55,6 +62,41 @@ class WechatReplyRepository extends CatchRepository
|
|||||||
return parent::storeBy($data); // TODO: Change the autogenerated stub
|
return parent::storeBy($data); // TODO: Change the autogenerated stub
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新
|
||||||
|
*
|
||||||
|
* @time 2020年09月13日
|
||||||
|
* @param int $id
|
||||||
|
* @param array $data
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function updateBy(int $id, array $data)
|
||||||
|
{
|
||||||
|
$material = WeChat::officialAccount()->material;
|
||||||
|
|
||||||
|
$mediaUrl = $this->getLocalPath($data['media_url'] ?? '');
|
||||||
|
$imageUrl = $this->getLocalPath($data['image_url'] ?? '');
|
||||||
|
|
||||||
|
if ($imageUrl) {
|
||||||
|
// 音乐
|
||||||
|
if ($data['type'] == WechatReply::MUSIC) {
|
||||||
|
$data['media_id'] = $material->uploadThumb($imageUrl)['media_id'];
|
||||||
|
} else {
|
||||||
|
// $data['media_id'] = $material->uploadImage($imageUrl)['media_id'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 语音
|
||||||
|
if ($data['type'] == WechatReply::VOICE) {
|
||||||
|
$data['media_id'] = $material->uploadVoice($mediaUrl)['media_id'];
|
||||||
|
}
|
||||||
|
// 视频
|
||||||
|
if ($data['type'] == WechatReply::VIDEO) {
|
||||||
|
$data['media_id'] = $material->uploadVideo($mediaUrl, $data['title'], $data['content'])['media_id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::updateBy($id, $data); // TODO: Change the autogenerated stub
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取本地地址
|
* 获取本地地址
|
||||||
*
|
*
|
||||||
|
@@ -34,9 +34,7 @@ $router->group('wechat', function () use ($router){
|
|||||||
});
|
});
|
||||||
// 微信回复管理
|
// 微信回复管理
|
||||||
$router->group('official/reply', function () use ($router){
|
$router->group('official/reply', function () use ($router){
|
||||||
$router->get('', '\catchAdmin\wechat\controller\Reply@index');
|
$router->resource('', '\catchAdmin\wechat\controller\Reply');
|
||||||
$router->post('', '\catchAdmin\wechat\controller\Reply@save');
|
|
||||||
$router->delete('<id>', '\catchAdmin\wechat\controller\Reply@delete');
|
|
||||||
$router->put('enable/<id>', '\catchAdmin\wechat\controller\Reply@disOrEnable');
|
$router->put('enable/<id>', '\catchAdmin\wechat\controller\Reply@disOrEnable');
|
||||||
});
|
});
|
||||||
// 微信上传
|
// 微信上传
|
||||||
|
@@ -18,16 +18,18 @@
|
|||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=7.1.0",
|
"php": ">=7.1.0",
|
||||||
"topthink/framework": "6.0.2",
|
"topthink/framework": "6.0.4",
|
||||||
"topthink/think-orm": "v2.0.31",
|
"topthink/think-orm": "2.0.33",
|
||||||
"topthink/think-migration": "^3.0",
|
"topthink/think-migration": "^3.0",
|
||||||
"thans/tp-jwt-auth": "1.1",
|
"thans/tp-jwt-auth": "1.1",
|
||||||
"jaguarjack/think-filesystem-cloud": "dev-master",
|
"jaguarjack/think-filesystem-cloud": "dev-master",
|
||||||
"overtrue/wechat": "^4.2",
|
"overtrue/wechat": "^4.2",
|
||||||
"jaguarjack/migration-generator": "dev-master",
|
|
||||||
"phpoffice/phpspreadsheet": "^1.12",
|
"phpoffice/phpspreadsheet": "^1.12",
|
||||||
"dragonmantank/cron-expression": "^3.0",
|
"dragonmantank/cron-expression": "^3.0",
|
||||||
"symfony/finder": "^4.4"
|
"symfony/finder": "^4.4",
|
||||||
|
"ext-json": "*",
|
||||||
|
"overtrue/easy-sms": "^1.1",
|
||||||
|
"jaguarjack/migration-generator": "dev-master"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"topthink/think-trace":"^1.0",
|
"topthink/think-trace":"^1.0",
|
||||||
|
@@ -22,6 +22,14 @@ return [
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
'super_admin_id' => 1,
|
'super_admin_id' => 1,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 方法认证标记
|
||||||
|
*
|
||||||
|
* 尽量使用唯以字符
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
'method_auth_mark' => '@CatchAuth'
|
||||||
],
|
],
|
||||||
/**
|
/**
|
||||||
* auth 认证
|
* auth 认证
|
||||||
@@ -76,57 +84,4 @@ return [
|
|||||||
'image' => 'fileSize:' . 1024 * 1024 * 5 . '|fileExt:jpg,png,gif,jpeg',
|
'image' => 'fileSize:' . 1024 * 1024 * 5 . '|fileExt:jpg,png,gif,jpeg',
|
||||||
'file' => 'fileSize:' . 1024 * 1024 * 10 . '|fileExt:txt,pdf,xlsx,xls,html,mp4,mp3,amr'
|
'file' => 'fileSize:' . 1024 * 1024 * 10 . '|fileExt:txt,pdf,xlsx,xls,html,mp4,mp3,amr'
|
||||||
],
|
],
|
||||||
|
|
||||||
/**
|
|
||||||
* 任务调度配置
|
|
||||||
*/
|
|
||||||
'schedule' => [
|
|
||||||
/**
|
|
||||||
* 常驻 worker 数量
|
|
||||||
*/
|
|
||||||
'static_worker_number' => 4,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 动态可扩展 worker 最大数量
|
|
||||||
*/
|
|
||||||
'max_worker_number' => 10,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 存储位置
|
|
||||||
*/
|
|
||||||
'store_path' => runtime_path('catch/schedule'),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 主进程 ID
|
|
||||||
*/
|
|
||||||
'master_pid_file' => runtime_path('catch/schedule') . '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,
|
|
||||||
],
|
|
||||||
|
|
||||||
'schedule_kernel' => \catcher\library\ScheduleKernel::class,
|
|
||||||
],
|
|
||||||
];
|
];
|
||||||
|
@@ -7,7 +7,7 @@ class CatchAdmin
|
|||||||
{
|
{
|
||||||
public static $root = 'catch';
|
public static $root = 'catch';
|
||||||
|
|
||||||
public const VERSION = '1.0.0';
|
public const VERSION = '2.1.0';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -227,6 +227,10 @@ class CatchAdmin
|
|||||||
|
|
||||||
$info['enable'] = true;
|
$info['enable'] = true;
|
||||||
|
|
||||||
|
if (!is_writeable($moduleJson)) {
|
||||||
|
chmod($moduleJson, 666);
|
||||||
|
}
|
||||||
|
|
||||||
file_put_contents($moduleJson, \json_encode($info, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
|
file_put_contents($moduleJson, \json_encode($info, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -251,6 +255,10 @@ class CatchAdmin
|
|||||||
|
|
||||||
$info['enable'] = false;
|
$info['enable'] = false;
|
||||||
|
|
||||||
|
if (!is_writeable($moduleJson)) {
|
||||||
|
chmod($moduleJson, 666);
|
||||||
|
}
|
||||||
|
|
||||||
file_put_contents($moduleJson, \json_encode($info, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));
|
file_put_contents($moduleJson, \json_encode($info, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -377,7 +385,7 @@ class CatchAdmin
|
|||||||
public static function cacheServices()
|
public static function cacheServices()
|
||||||
{
|
{
|
||||||
return file_put_contents(self::getCacheServicesFile(), "<?php\r\n return "
|
return file_put_contents(self::getCacheServicesFile(), "<?php\r\n return "
|
||||||
. var_export(self::getModuleServices(), true) . ';');
|
. var_export(self::getEnabledService(), true) . ';');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -425,7 +433,7 @@ class CatchAdmin
|
|||||||
* @time 2019年11月30日
|
* @time 2019年11月30日
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
protected static function getCacheServicesFile()
|
public static function getCacheServicesFile()
|
||||||
{
|
{
|
||||||
return self::cacheDirectory() . 'services.php';
|
return self::cacheDirectory() . 'services.php';
|
||||||
}
|
}
|
||||||
|
@@ -127,7 +127,9 @@ class CatchAdminService extends Service
|
|||||||
*/
|
*/
|
||||||
protected function registerServices()
|
protected function registerServices()
|
||||||
{
|
{
|
||||||
$services = CatchAdmin::getEnabledService();
|
$services = file_exists(CatchAdmin::getCacheServicesFile()) ?
|
||||||
|
include CatchAdmin::getCacheServicesFile() :
|
||||||
|
CatchAdmin::getEnabledService();
|
||||||
|
|
||||||
foreach ($services as $service) {
|
foreach ($services as $service) {
|
||||||
if (class_exists($service)) {
|
if (class_exists($service)) {
|
||||||
|
@@ -53,7 +53,6 @@ class CatchAuth
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$user = $this->authenticate($condition);
|
$user = $this->authenticate($condition);
|
||||||
|
|
||||||
if (!$user) {
|
if (!$user) {
|
||||||
throw new LoginFailedException();
|
throw new LoginFailedException();
|
||||||
}
|
}
|
||||||
@@ -65,51 +64,13 @@ class CatchAuth
|
|||||||
throw new LoginFailedException('登录失败|' . $user->username);
|
throw new LoginFailedException('登录失败|' . $user->username);
|
||||||
}
|
}
|
||||||
|
|
||||||
$token = $this->{$this->getDriver()}($user);
|
return $this->{$this->getDriver()}($user);
|
||||||
$this->afterLoginSuccess($user);
|
|
||||||
// 登录事件
|
|
||||||
$this->loginEvent($user->username);
|
|
||||||
return $token;
|
|
||||||
} catch (\Exception $exception) {
|
} catch (\Exception $exception) {
|
||||||
$message = $exception->getMessage();
|
//
|
||||||
if (strpos($message, '|') !== false) {
|
|
||||||
$username = explode('|', $message)[1];
|
|
||||||
} else {
|
|
||||||
$username = $condition['email'];
|
|
||||||
}
|
|
||||||
$this->loginEvent($username, false);
|
|
||||||
throw new LoginFailedException('登录失败', $exception->getCode());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户登录成功后
|
|
||||||
*
|
|
||||||
* @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();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 登录事件
|
|
||||||
*
|
|
||||||
* @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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* user
|
* user
|
||||||
|
86
extend/catcher/CatchModelCollection.php
Normal file
86
extend/catcher/CatchModelCollection.php
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
namespace catcher;
|
||||||
|
|
||||||
|
use catcher\library\excel\CatchExcel;
|
||||||
|
use catcher\library\excel\Excel;
|
||||||
|
use catcher\library\excel\ExcelContract;
|
||||||
|
use think\facade\Cache;
|
||||||
|
use think\model\Collection;
|
||||||
|
|
||||||
|
class CatchModelCollection extends Collection
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* tree 结构
|
||||||
|
*
|
||||||
|
* @time 2020年10月21日
|
||||||
|
* @param int $pid
|
||||||
|
* @param string $pidField
|
||||||
|
* @param string $children
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toTree($pid = 0, $pidField = 'parent_id', $children = 'children')
|
||||||
|
{
|
||||||
|
return Tree::done($this->items, $pid, $pidField, $children);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出数据
|
||||||
|
*
|
||||||
|
* @time 2020年10月21日
|
||||||
|
* @param $header
|
||||||
|
* @param string $path
|
||||||
|
* @param string $disk
|
||||||
|
* @throws \PhpOffice\PhpSpreadsheet\Exception
|
||||||
|
* @return mixed|string[]
|
||||||
|
*/
|
||||||
|
public function export($header, $path = '', $disk = 'local')
|
||||||
|
{
|
||||||
|
$excel = new Class($header, $this->items) implements ExcelContract
|
||||||
|
{
|
||||||
|
protected $headers;
|
||||||
|
|
||||||
|
protected $sheets;
|
||||||
|
|
||||||
|
public function __construct($headers, $sheets)
|
||||||
|
{
|
||||||
|
$this->headers = $headers;
|
||||||
|
|
||||||
|
$this->sheets = $sheets;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function headers(): array
|
||||||
|
{
|
||||||
|
// TODO: Implement headers() method.
|
||||||
|
return $this->headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sheets()
|
||||||
|
{
|
||||||
|
// TODO: Implement sheets() method.
|
||||||
|
return $this->sheets;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!$path) {
|
||||||
|
$path = Utils::publicPath('exports');
|
||||||
|
}
|
||||||
|
|
||||||
|
return (new Excel)->save($excel, $path, $disk);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存 collection
|
||||||
|
*
|
||||||
|
* @time 2020年10月21日
|
||||||
|
* @param $key
|
||||||
|
* @param int $ttl
|
||||||
|
* @param string $store
|
||||||
|
* @return bool
|
||||||
|
* @throws \Psr\SimpleCache\InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function cache($key, int $ttl = 0, string $store = 'redis')
|
||||||
|
{
|
||||||
|
return Cache::store($store)->set($key, $this->items, $ttl);
|
||||||
|
}
|
||||||
|
}
|
@@ -159,7 +159,11 @@ class CatchQuery extends Query
|
|||||||
$condition .= '%';
|
$condition .= '%';
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::whereLike($this->getAlias() . '.' . $field, $condition, $logic);
|
if (strpos($field, '.') === false) {
|
||||||
|
$field = $this->getAlias() . '.' . $field;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::whereLike($field, $condition, $logic);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -28,7 +28,9 @@ abstract class ModuleService extends Service
|
|||||||
|
|
||||||
$this->registerEvents();
|
$this->registerEvents();
|
||||||
|
|
||||||
$this->registerCommands();;
|
$this->registerCommands();
|
||||||
|
|
||||||
|
$this->registerConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,6 +46,19 @@ abstract class ModuleService extends Service
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* register config
|
||||||
|
*
|
||||||
|
* @time 2020年09月25日
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function registerConfig()
|
||||||
|
{
|
||||||
|
if (method_exists($this, 'loadConfig')) {
|
||||||
|
$this->app->config->set(array_merge($this->app->config->get('catch'), $this->loadConfig()), 'catch');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注册commands
|
* 注册commands
|
||||||
*
|
*
|
||||||
|
@@ -75,8 +75,18 @@ class Utils
|
|||||||
unset($value['children']);
|
unset($value['children']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$id = Db::name($table)->insertGetId($value);
|
// 首先查询是否存在
|
||||||
|
$menu = Db::name($table)
|
||||||
|
->where('permission_name', $value['permission_name'])
|
||||||
|
->where('module', $value['module'])
|
||||||
|
->where('permission_mark', $value['permission_mark'])
|
||||||
|
->find();
|
||||||
|
|
||||||
|
if (!empty($menu)) {
|
||||||
|
$id = $menu['id'];
|
||||||
|
} else {
|
||||||
|
$id = Db::name($table)->insertGetId($value);
|
||||||
|
}
|
||||||
if ($children) {
|
if ($children) {
|
||||||
foreach ($children as &$v) {
|
foreach ($children as &$v) {
|
||||||
$v[$pid] = $id;
|
$v[$pid] = $id;
|
||||||
@@ -109,6 +119,25 @@ class Utils
|
|||||||
return [$module, $controllerName, $action];
|
return [$module, $controllerName, $action];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get controller & action
|
||||||
|
*
|
||||||
|
* @time 2020年10月12日
|
||||||
|
* @param $rule
|
||||||
|
* @return false|string[]
|
||||||
|
* @throws \ReflectionException
|
||||||
|
*/
|
||||||
|
public static function isMethodNeedAuth($rule)
|
||||||
|
{
|
||||||
|
list($controller, $action) = explode(Str::contains($rule, '@') ? '@' : '/', $rule);
|
||||||
|
|
||||||
|
$docComment = (new \ReflectionClass($controller))->getMethod($action)->getDocComment();
|
||||||
|
|
||||||
|
return strpos($docComment, config('catch.permissions.method_auth_mark')) !== false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表前缀
|
* 表前缀
|
||||||
*
|
*
|
||||||
|
102
extend/catcher/base/CatchCronTask.php
Normal file
102
extend/catcher/base/CatchCronTask.php
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
<?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 catcher\base;
|
||||||
|
|
||||||
|
use catchAdmin\monitor\model\CrontabLog;
|
||||||
|
|
||||||
|
abstract class CatchCronTask
|
||||||
|
{
|
||||||
|
protected $exceptionHappenTimes = 0;
|
||||||
|
|
||||||
|
protected $exitTimes = 1;
|
||||||
|
|
||||||
|
protected $crontab;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @time 2020年07月29日
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public abstract function deal();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @time 2020年07月29日
|
||||||
|
* @param \Throwable $e
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public abstract function dealWithException(\Throwable $e);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行
|
||||||
|
*
|
||||||
|
* @time 2020年07月23日
|
||||||
|
* @return void|bool
|
||||||
|
*/
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$startAt = round(microtime(true) * 1000);
|
||||||
|
try {
|
||||||
|
if ($this->deal() === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$this->recordLog($startAt);
|
||||||
|
return true;
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
$this->dealWithException($e);
|
||||||
|
echo sprintf('[%s]: ', date('Y-m-d H:i:s')) . 'File:' . $e->getFile() . ', Lines: '. $e->getLine() .'行,Exception Message: ' . $e->getMessage() . PHP_EOL;
|
||||||
|
// 输出堆栈信息
|
||||||
|
echo sprintf('[%s]: ', date('Y-m-d H:i:s')) . $e->getTraceAsString() . PHP_EOL;
|
||||||
|
// 日志记录
|
||||||
|
$this->recordLog($startAt, 'File:' . $e->getFile() . ', Lines: '. $e->getLine() .'行,Exception Message: ' . $e->getMessage());
|
||||||
|
$this->exceptionHappenTimes += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退出
|
||||||
|
*
|
||||||
|
* @time 2020年07月29日
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function shouldExit()
|
||||||
|
{
|
||||||
|
// var_dump($this->exceptionHappenTimes);
|
||||||
|
return $this->exceptionHappenTimes > $this->exitTimes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置 crontab
|
||||||
|
*
|
||||||
|
* @time 2020年09月15日
|
||||||
|
* @param array $crontab
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setCrontab(array $crontab)
|
||||||
|
{
|
||||||
|
$this->crontab = $crontab;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function recordLog($startAt, $message = '')
|
||||||
|
{
|
||||||
|
$endAt = round(microtime(true) * 1000);
|
||||||
|
CrontabLog::insert([
|
||||||
|
'crontab_id' => $this->crontab['id'],
|
||||||
|
'used_time' => $endAt - $startAt,
|
||||||
|
'error_message' => $message,
|
||||||
|
'status' => $message ? CrontabLog::FAILED : CrontabLog::SUCCESS,
|
||||||
|
'created_at' => time(),
|
||||||
|
'updated_at' => time(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@@ -4,6 +4,7 @@ namespace catcher\base;
|
|||||||
use app\Request;
|
use app\Request;
|
||||||
use catcher\exceptions\FailedException;
|
use catcher\exceptions\FailedException;
|
||||||
use catcher\exceptions\ValidateFailedException;
|
use catcher\exceptions\ValidateFailedException;
|
||||||
|
use think\App;
|
||||||
|
|
||||||
class CatchRequest extends Request
|
class CatchRequest extends Request
|
||||||
{
|
{
|
||||||
@@ -47,35 +48,12 @@ class CatchRequest extends Request
|
|||||||
$validate->batch($this->batch);
|
$validate->batch($this->batch);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* // 场景设置验证
|
|
||||||
* if (property_exists($this, 'scene') && !empty($this->scene)) {
|
|
||||||
* foreach ($this->scene as $scene => $rules) {
|
|
||||||
* $validate->scene($scene);
|
|
||||||
* // 只限制字段
|
|
||||||
* if (!isset($rules['only'])) {
|
|
||||||
* $validate->only($rules);
|
|
||||||
* } else {
|
|
||||||
* $validate->only($rules['only']);
|
|
||||||
* // 新增规则
|
|
||||||
* if (isset($rules['append'])) {
|
|
||||||
* foreach ($rules['append'] as $field => $rule) {
|
|
||||||
* $validate->append($field, $rule);
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* // 移除规则
|
|
||||||
* if (isset($rules['remove'])) {
|
|
||||||
* foreach ($rules['remove'] as $field => $rule) {
|
|
||||||
* $validate->remove($field, $rule);
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* }
|
|
||||||
* }**/
|
|
||||||
|
|
||||||
// 验证
|
// 验证
|
||||||
if (!$validate->check(request()->param(), $this->rules())) {
|
$message = [];
|
||||||
|
if (method_exists($this, 'message')) {
|
||||||
|
$message = $this->message();
|
||||||
|
}
|
||||||
|
if (!$validate->message(empty($message) ? [] : $message)->check(request()->param(), $this->rules())) {
|
||||||
throw new FailedException($validate->getError());
|
throw new FailedException($validate->getError());
|
||||||
}
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
@@ -86,9 +64,27 @@ class CatchRequest extends Request
|
|||||||
// 设置默认参数
|
// 设置默认参数
|
||||||
if ($this->needCreatorId) {
|
if ($this->needCreatorId) {
|
||||||
$this->param['creator_id'] = $this->user()->id;
|
$this->param['creator_id'] = $this->user()->id;
|
||||||
$this->post['creator_id'] = $this->user()->id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rewrite post
|
||||||
|
*
|
||||||
|
* @time 2020年10月15日
|
||||||
|
* @param string $name
|
||||||
|
* @param null $default
|
||||||
|
* @param string $filter
|
||||||
|
* @return array|mixed|null
|
||||||
|
*/
|
||||||
|
public function post($name = '', $default = null, $filter = '')
|
||||||
|
{
|
||||||
|
if ($this->needCreatorId) {
|
||||||
|
$this->post['creator_id'] = $this->user()->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::post($name, $default, $filter); // TODO: Change the autogenerated stub
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,104 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare (strict_types = 1);
|
|
||||||
|
|
||||||
namespace catcher\command;
|
|
||||||
|
|
||||||
use catcher\library\crontab\Master;
|
|
||||||
use think\console\Command;
|
|
||||||
use think\console\Input;
|
|
||||||
use think\console\input\Argument;
|
|
||||||
use think\console\input\Option;
|
|
||||||
use think\console\Output;
|
|
||||||
|
|
||||||
class CatchScheduleCommand extends Command
|
|
||||||
{
|
|
||||||
protected function configure()
|
|
||||||
{
|
|
||||||
// 指令配置
|
|
||||||
$this->setName('catch:schedule')
|
|
||||||
->addArgument('option', Argument::OPTIONAL, '[start|reload|stop|restart||status]', 'start')
|
|
||||||
->addOption('daemon', '-d', Option::VALUE_NONE, 'daemon mode')
|
|
||||||
->setDescription('start task schedule');
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function execute(Input $input, Output $output)
|
|
||||||
{
|
|
||||||
if (!extension_loaded('swoole')) {
|
|
||||||
$output->error('Swoole Extension Not Installed! You can use [pecl] to install swoole');
|
|
||||||
} else {
|
|
||||||
$master = new Master();
|
|
||||||
if ($this->input->hasOption('daemon')) {
|
|
||||||
$master->daemon();
|
|
||||||
}
|
|
||||||
$this->{$input->getArgument('option')}($master);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进程启动
|
|
||||||
*
|
|
||||||
* @time 2020年07月07日
|
|
||||||
* @param Master $process
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function start(Master $process)
|
|
||||||
{
|
|
||||||
$process->start();
|
|
||||||
$this->output->info($process->renderProcessesStatusToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 状态输出
|
|
||||||
*
|
|
||||||
* @time 2020年07月07日
|
|
||||||
* @param Master $process
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function status(Master $process)
|
|
||||||
{
|
|
||||||
$process->status();
|
|
||||||
|
|
||||||
$this->output->info($process->output());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 停止任务
|
|
||||||
*
|
|
||||||
* @time 2020年07月07日
|
|
||||||
* @param Master $process
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function stop(Master $process)
|
|
||||||
{
|
|
||||||
$process->stop();
|
|
||||||
|
|
||||||
$this->output->info('stop catch schedule successfully');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 重启任务
|
|
||||||
*
|
|
||||||
* @time 2020年07月07日
|
|
||||||
* @param Master $process
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function reload(Master $process)
|
|
||||||
{
|
|
||||||
$process->reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 重启
|
|
||||||
*
|
|
||||||
* @time 2020年07月07日
|
|
||||||
* @param Master $process
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function restart(Master $process)
|
|
||||||
{
|
|
||||||
$process->stop();
|
|
||||||
|
|
||||||
$process->start();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
declare (strict_types = 1);
|
|
||||||
|
|
||||||
namespace catcher\command;
|
|
||||||
|
|
||||||
use catcher\CatchAdmin;
|
|
||||||
use think\console\Command;
|
|
||||||
use think\console\Input;
|
|
||||||
use think\console\input\Argument;
|
|
||||||
use think\console\input\Option;
|
|
||||||
use think\console\Output;
|
|
||||||
|
|
||||||
class ModuleCacheCommand extends Command
|
|
||||||
{
|
|
||||||
protected function configure()
|
|
||||||
{
|
|
||||||
// 指令配置
|
|
||||||
$this->setName('catch:cache')
|
|
||||||
->setDescription('cache routes, views, services of module');
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function execute(Input $input, Output $output)
|
|
||||||
{
|
|
||||||
CatchAdmin::cacheRoutes();
|
|
||||||
CatchAdmin::cacheServices();
|
|
||||||
CatchAdmin::cacheViews();
|
|
||||||
// 指令输出
|
|
||||||
$output->info('succeed!');
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user