Browse Source

初始化版本

master
ahbmz 4 years ago
commit
ae67f07f3a
  1. 1
      .env
  2. 6
      .gitignore
  3. 42
      .travis.yml
  4. 32
      LICENSE.txt
  5. 52
      README.md
  6. 1
      app/.htaccess
  7. 22
      app/AppService.php
  8. 94
      app/BaseController.php
  9. 58
      app/ExceptionHandle.php
  10. 10
      app/Request.php
  11. 11
      app/api/config/app.php
  12. 23
      app/api/config/jwtauth.php
  13. 205
      app/api/controller/Ad.php
  14. 118
      app/api/controller/Block.php
  15. 135
      app/api/controller/Column.php
  16. 117
      app/api/controller/Common.php
  17. 90
      app/api/controller/Config.php
  18. 242
      app/api/controller/Demo.php
  19. 203
      app/api/controller/Dictionary.php
  20. 207
      app/api/controller/DictionaryType.php
  21. 395
      app/api/controller/Group.php
  22. 85
      app/api/controller/ImageStorage.php
  23. 25
      app/api/controller/Index.php
  24. 55
      app/api/controller/Log.php
  25. 169
      app/api/controller/Login.php
  26. 439
      app/api/controller/Manager.php
  27. 256
      app/api/controller/Menu.php
  28. 200
      app/api/controller/Message.php
  29. 23
      app/api/controller/Swagger.php
  30. 71
      app/api/controller/Test.php
  31. 111
      app/api/controller/UploadLog.php
  32. 96
      app/api/controller/v1/Test.php
  33. 6
      app/api/middleware.php
  34. 101
      app/api/model/Ad.php
  35. 78
      app/api/model/AdData.php
  36. 66
      app/api/model/Block.php
  37. 88
      app/api/model/Column.php
  38. 270
      app/api/model/Common.php
  39. 119
      app/api/model/Config.php
  40. 137
      app/api/model/Demo.php
  41. 108
      app/api/model/Dictionary.php
  42. 119
      app/api/model/DictionaryType.php
  43. 46
      app/api/model/ImageStorages.php
  44. 188
      app/api/model/Log.php
  45. 289
      app/api/model/Manager.php
  46. 226
      app/api/model/Menu.php
  47. 248
      app/api/model/Message.php
  48. 79
      app/api/model/MessageContent.php
  49. 31
      app/api/model/Site.php
  50. 72
      app/api/model/Token.php
  51. 164
      app/api/model/UploadLog.php
  52. 24
      app/api/route/app.php
  53. 58
      app/api/validate/Ad.php
  54. 68
      app/api/validate/AdData.php
  55. 59
      app/api/validate/Block.php
  56. 54
      app/api/validate/Config.php
  57. 67
      app/api/validate/Demo.php
  58. 80
      app/api/validate/Dictionary.php
  59. 64
      app/api/validate/DictionaryType.php
  60. 52
      app/api/validate/Group.php
  61. 62
      app/api/validate/Log.php
  62. 92
      app/api/validate/Manager.php
  63. 68
      app/api/validate/Menu.php
  64. 42
      app/api/validate/Message.php
  65. 251
      app/common.php
  66. 17
      app/event.php
  67. 82
      app/exception/ExceptionHandle.php
  68. 42
      app/exception/HttpException.php
  69. 19
      app/facade/Test.php
  70. 87
      app/index/controller/Blog.php
  71. 30
      app/index/controller/Index.php
  72. 89
      app/index/controller/Jwt.php
  73. 14
      app/index/model/User.php
  74. 13
      app/index/route/app.php
  75. 20
      app/middleware.php
  76. 44
      app/middleware/AllowCrossDomain.php
  77. 70
      app/middleware/CheckJwtAuth.php
  78. 11
      app/provider.php
  79. 9
      app/service.php
  80. 55
      composer.json
  81. 2350
      composer.lock
  82. 36
      config/app.php
  83. 20
      config/auth.php
  84. 29
      config/cache.php
  85. 39
      config/captcha.php
  86. 9
      config/console.php
  87. 18
      config/cookie.php
  88. 62
      config/database.php
  89. 53
      config/dict.php
  90. 86
      config/dictionary.php
  91. 24
      config/filesystem.php
  92. 25
      config/lang.php
  93. 45
      config/log.php
  94. 8
      config/middleware.php
  95. 45
      config/route.php
  96. 19
      config/session.php
  97. 10
      config/trace.php
  98. 25
      config/view.php
  99. 108
      database/migrations/20181113071924_create_rules_table.php
  100. 1
      extend/.gitignore

1
.env

@ -0,0 +1 @@
APP_DEBUG = false [APP] DEFAULT_TIMEZONE = Asia/Shanghai [DATABASE] TYPE = mysql HOSTNAME = 122.114.59.173 DATABASE = bmz_base USERNAME = bmz_base PASSWORD = C2dA3FPLZxhDjKnr HOSTPORT = 3306 CHARSET = utf8mb4 DEBUG = true [LANG] default_lang = zh-cn

6
.gitignore

@ -0,0 +1,6 @@
/.idea
/.vscode
*.log
/runtime
/verdor
/vendor/

42
.travis.yml

@ -0,0 +1,42 @@
sudo: false
language: php
branches:
only:
- stable
cache:
directories:
- $HOME/.composer/cache
before_install:
- composer self-update
install:
- composer install --no-dev --no-interaction --ignore-platform-reqs
- zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Core.zip .
- composer require --update-no-dev --no-interaction "topthink/think-image:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-migration:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-captcha:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-mongo:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-worker:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-helper:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-queue:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-angular:^1.0"
- composer require --dev --update-no-dev --no-interaction "topthink/think-testing:^1.0"
- zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Full.zip .
script:
- php think unit
deploy:
provider: releases
api_key:
secure: TSF6bnl2JYN72UQOORAJYL+CqIryP2gHVKt6grfveQ7d9rleAEoxlq6PWxbvTI4jZ5nrPpUcBUpWIJHNgVcs+bzLFtyh5THaLqm39uCgBbrW7M8rI26L8sBh/6nsdtGgdeQrO/cLu31QoTzbwuz1WfAVoCdCkOSZeXyT/CclH99qV6RYyQYqaD2wpRjrhA5O4fSsEkiPVuk0GaOogFlrQHx+C+lHnf6pa1KxEoN1A0UxxVfGX6K4y5g4WQDO5zT4bLeubkWOXK0G51XSvACDOZVIyLdjApaOFTwamPcD3S1tfvuxRWWvsCD5ljFvb2kSmx5BIBNwN80MzuBmrGIC27XLGOxyMerwKxB6DskNUO9PflKHDPI61DRq0FTy1fv70SFMSiAtUv9aJRT41NQh9iJJ0vC8dl+xcxrWIjU1GG6+l/ZcRqVx9V1VuGQsLKndGhja7SQ+X1slHl76fRq223sMOql7MFCd0vvvxVQ2V39CcFKao/LB1aPH3VhODDEyxwx6aXoTznvC/QPepgWsHOWQzKj9ftsgDbsNiyFlXL4cu8DWUty6rQy8zT2b4O8b1xjcwSUCsy+auEjBamzQkMJFNlZAIUrukL/NbUhQU37TAbwsFyz7X0E/u/VMle/nBCNAzgkMwAUjiHM6FqrKKBRWFbPrSIixjfjkCnrMEPw=
file:
- ThinkPHP_Core.zip
- ThinkPHP_Full.zip
skip_cleanup: true
on:
tags: true

32
LICENSE.txt

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

52
README.md

@ -0,0 +1,52 @@
ThinkPHP 6.0
===============
> 运行环境要求PHP7.1+。
## 主要新特性
* 采用`PHP7`强类型(严格模式)
* 支持更多的`PSR`规范
* 原生多应用支持
* 更强大和易用的查询
* 全新的事件系统
* 模型事件和数据库事件统一纳入事件系统
* 模板引擎分离出核心
* 内部功能中间件化
* SESSION/Cookie机制改进
* 对Swoole以及协程支持改进
* 对IDE更加友好
* 统一和精简大量用法
## 安装
~~~
composer create-project topthink/think tp 6.0.*
~~~
如果需要更新框架使用
~~~
composer update topthink/framework
~~~
## 文档
[完全开发手册](https://www.kancloud.cn/manual/thinkphp6_0/content)
## 参与开发
请参阅 [ThinkPHP 核心框架包](https://github.com/top-think/framework)。
## 版权信息
ThinkPHP遵循Apache2开源协议发布,并提供免费使用。
本项目包含的第三方源码和二进制文件之版权信息另行标注。
版权所有Copyright © 2006-2020 by ThinkPHP (http://thinkphp.cn)
All rights reserved。
ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。
更多细节参阅 [LICENSE.txt](LICENSE.txt)

1
app/.htaccess

@ -0,0 +1 @@
deny from all

22
app/AppService.php

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

94
app/BaseController.php

@ -0,0 +1,94 @@
<?php
declare (strict_types = 1);
namespace app;
use think\App;
use think\exception\ValidateException;
use think\Validate;
/**
* 控制器基础类.
*/
abstract class BaseController
{
/**
* Request实例
* @var \think\Request
*/
protected $request;
/**
* 应用实例
* @var \think\App
*/
protected $app;
/**
* 是否批量验证
* @var bool
*/
protected $batchValidate = false;
/**
* 控制器中间件
* @var array
*/
protected $middleware = [];
/**
* 构造方法
* @access public
* @param App $app 应用对象
*/
public function __construct(App $app)
{
$this->app = $app;
$this->request = $this->app->request;
// 控制器初始化
$this->initialize();
}
// 初始化
protected function initialize()
{}
/**
* 验证数据
* @access protected
* @param array $data 数据
* @param string|array $validate 验证器名或者验证规则数组
* @param array $message 提示信息
* @param bool $batch 是否批量验证
* @return array|string|true
* @throws ValidateException
*/
protected function validate(array $data, $validate, array $message = [], bool $batch = false)
{
if (is_array($validate)) {
$v = new Validate();
$v->rule($validate);
} else {
if (strpos($validate, '.')) {
// 支持场景
[$validate, $scene] = explode('.', $validate);
}
$class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
$v = new $class();
if (!empty($scene)) {
$v->scene($scene);
}
}
$v->message($message);
// 是否批量验证
if ($batch || $this->batchValidate) {
$v->batch(true);
}
return $v->failException(true)->check($data);
}
}

58
app/ExceptionHandle.php

@ -0,0 +1,58 @@
<?php
namespace app;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\exception\Handle;
use think\exception\HttpException;
use think\exception\HttpResponseException;
use think\exception\ValidateException;
use think\Response;
use Throwable;
/**
* 应用异常处理类
*/
class ExceptionHandle extends Handle
{
/**
* 不需要记录信息(日志)的异常类列表
* @var array
*/
protected $ignoreReport = [
HttpException::class,
HttpResponseException::class,
ModelNotFoundException::class,
DataNotFoundException::class,
ValidateException::class,
];
/**
* 记录异常信息(包括日志或者其它方式记录)
*
* @access public
* @param Throwable $exception
* @return void
*/
public function report(Throwable $exception): void
{
// 使用内置的方式记录异常日志
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
*
* @access public
* @param \think\Request $request
* @param Throwable $e
* @return Response
*/
public function render($request, Throwable $e): Response
{
// 添加自定义异常处理机制
// 其他错误交给系统处理
return parent::render($request, $e);
}
}

10
app/Request.php

@ -0,0 +1,10 @@
<?php
namespace app;
// 应用请求对象类
class Request extends \think\Request
{
//全局请求过滤
protected $filter = ['htmlspecialchars', 'trim', 'strip_tags'];
}

11
app/api/config/app.php

@ -0,0 +1,11 @@
<?php
// +----------------------------------------------------------------------
// | Api统一配置文件
// +----------------------------------------------------------------------
return [
// 应用地址
'page' => 1,
'limit' => 10,
];

23
app/api/config/jwtauth.php

@ -0,0 +1,23 @@
<?php
// +----------------------------------------------------------------------
// | JWT签名专用配置文件
// +----------------------------------------------------------------------
return [
// JWT-TOKEN验证应用地址
'web' => [
'host' => 'base.ahbmz.com',
'expire_time' => '+1200 minute', //分钟 DateTimeImmutable
'expire_at' => 72000, //秒 //对应expire_time
'token_key' => 'K4Eya8bEbxmjzxcplUo8u3d',
'jti_nonce' => 'lwEinge4Ey8ExjxpU83klKlfeiao8L', //jwt jti
'expire_time_refresh' => 3600 * 24 * 7, //7天过期
],
//不需要jwt的控制器、方法直接返回
'filter_router' => [
'api/login/login',
'api/login/refreshtoken',
'api/login/captcha',
'api/UploadLog/add',
]
];

205
app/api/controller/Ad.php

@ -0,0 +1,205 @@
<?php
declare (strict_types=1);
/**
* Created by 安徽云掌.
* User: 云掌.帮德
* Date: 2020/3/8 22:30
* Desc: 行为日志类
*/
namespace app\api\controller;
use think\App;
class Ad extends Common
{
public $model = null;
public function __construct(App $app)
{
parent::__construct($app);
$this->model = new \app\api\model\Ad();
}
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index()
{
//接受参数
$_get = $this->request->get();
//验证参数
// validate(\app\api\validate\Block::class)->scene('lists')->check($_get);
//数据处理
$_data = $this->model->index();
//返回数据
return send_http_status($_data);
}
/**
* 获取广告位类型
*
* @return \think\Response
*/
public function getAdType(){
//获取栏目类型
$_ad_type = config('dictionary.sqlfields.ad_type');
//返回数据
return send_http_status($_ad_type);
}
/**
* 添加数据
* @return \think\Response
* @Log [sys_name] 在 [sys_time] 创建了广告位:[name]
*/
public function add()
{
//接收参数
$_post = $this->request->post();
//验证参数
validate(\app\api\validate\Ad::class)->check($_post);
//处理并返回参数
$insertId = $this->model->parentAdd($_post);
return send_http_status($insertId, $insertId ? 201 : 202);
}
/**
* 读取单条数据
* @param int $id
* @return \think\Response
*/
public function read($id = '')
{
//验证参数
validate(\app\api\validate\Block::class)->scene('read')->check(['id' => $id]);
//返回数据
return send_http_status($this->model->parentRead($id));
}
/**
* 保存更新的资源
* @param \think\Request $request
* @param int $id
* @return \think\Response
* @Log [sys_name]在[sys_time]修改了广告位[id]的数据
*/
public function edit($id = 0)
{
//接收参数
$_post = $this->request->post();
$_post['id'] = $id; //安全赋值,以免客户端没传id,修改需要id字段
//验证参数
validate(\app\api\validate\Ad::class)->scene('update')->check($_post);
//处理并返回数据
return send_http_status('', $this->model->parentEdit($_post, $id) ? 203 : 204);
}
/**
* 删除指定资源
* @Log [sys_name] 在 [sys_time] 删除了广告位id:[id]
* @param int $id
* @return \think\Response
*/
public function delete()
{
//接收参数
$ids = $this->request->get('id');
//验证参数
validate(['ids|id' => 'require|length:1,10'])->check(['ids' => $ids]);
//处理并返回数据
return send_http_status('', $this->model->parentDel($ids) ? 205 : 206);
}
/**
* 显示广告列表
*
* @return \think\Response
*/
public function data()
{
//接受参数
$_get = $this->request->get();
//验证参数
// validate(\app\api\validate\Block::class)->scene('lists')->check($_get);
//数据处理
$_data = $this->model->AdData();
//返回数据
return send_http_status($_data);
}
public function dataAdd(){
$this->model = new \app\api\model\AdData();
//接收参数
$_post = $this->request->post();
//验证参数
validate(\app\api\validate\AdData::class)->check($_post);
//处理并返回参数
$insertId = $this->model->parentAdd($_post);
return send_http_status($insertId, $insertId ? 201 : 202);
}
public function dataEdit($id = 0){
$this->model = new \app\api\model\AdData();
//接收参数
$_post = $this->request->post();
$_post['id'] = $id; //安全赋值,以免客户端没传id,修改需要id字段
//验证参数
validate(\app\api\validate\AdData::class)->scene('update')->check($_post);
//处理并返回数据
return send_http_status('', $this->model->parentEdit($_post, $id) ? 203 : 204);
}
public function dataRead($id=0){
$this->model = new \app\api\model\AdData();
//验证参数
validate(\app\api\validate\AdData::class)->scene('read')->check(['id' => $id]);
//返回数据
return send_http_status($this->model->parentRead($id));
}
/**
* 删除指定资源
* @Log [sys_name] 在 [sys_time] 删除了广告id:[id]
* @param int $id
* @return \think\Response
*/
public function dataDelete()
{
$this->model = new \app\api\model\AdData();
//接收参数
$ids = $this->request->get('id');
//验证参数
validate(['ids|id' => 'require|length:1,10'])->check(['ids' => $ids]);
//处理并返回数据
return send_http_status('', $this->model->parentDel($ids) ? 205 : 206);
}
}

118
app/api/controller/Block.php

@ -0,0 +1,118 @@
<?php
declare (strict_types=1);
/**
* Created by 安徽云掌.
* User: 云掌.帮德
* Date: 2020/3/8 22:30
* Desc: 行为日志类
*/
namespace app\api\controller;
use think\App;
class Block extends Common
{
public $model = null;
public function __construct(App $app)
{
parent::__construct($app);
$this->model = new \app\api\model\Block();
}
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index()
{
//接受参数
$_get = $this->request->get();
//验证参数
// validate(\app\api\validate\Block::class)->scene('lists')->check($_get);
//数据处理
$_data = $this->model->index();
//返回数据
return send_http_status($_data);
}
/**
* 添加数据
* @return \think\Response
* @Log [sys_name] 在 [sys_time] 创建了管理员:[ident]
*/
public function add()
{
//接收参数
$_post = $this->request->post();
//验证参数
validate(\app\api\validate\Block::class)->check($_post);
//处理并返回参数
$insertId = $this->model->parentAdd($_post);
return send_http_status($insertId, $insertId ? 201 : 202);
}
/**
* 读取单条数据
* @param int $id
* @return \think\Response
*/
public function read($id = '')
{
//验证参数
validate(\app\api\validate\Block::class)->scene('read')->check(['id' => $id]);
//返回数据
return send_http_status($this->model->parentRead($id));
}
/**
* 保存更新的资源
* @param \think\Request $request
* @param int $id
* @return \think\Response
* @Log [sys_name]在[sys_time]修改了碎片标志[ident]的数据
*/
public function edit($id = 0)
{
//接收参数
$_post = $this->request->post();
$_post['id'] = $id; //安全赋值,以免客户端没传id,修改需要id字段
//验证参数
validate(\app\api\validate\Block::class)->scene('update')->check($_post);
//处理并返回数据
return send_http_status('', $this->model->parentEdit($_post, $id) ? 203 : 204);
}
/**
* 删除指定资源
* @Log [sys_name] 在 [sys_time] 删除了碎片id:[id]
* @param int $id
* @return \think\Response
*/
public function delete()
{
//接收参数
$ids = $this->request->post('id');
//验证参数
validate(['ids|id' => 'require|length:1,10'])->check(['ids' => $ids]);
//处理并返回数据
return send_http_status('', $this->model->parentDel($ids) ? 205 : 206);
}
}

135
app/api/controller/Column.php

@ -0,0 +1,135 @@
<?php
declare (strict_types=1);
/**
* Created by 安徽云掌.
* User: 云掌.帮德
* Date: 2020/3/8 22:30
* Desc: 行为日志类
*/
namespace app\api\controller;
use think\App;
class Column extends Common
{
public $model = null;
public function __construct(App $app)
{
parent::__construct($app);
$this->model = new \app\api\model\Column();
}
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index()
{
//接受参数
$_get = $this->request->get();
//数据处理
$_data = $this->model->index();
//返回数据
return send_http_status($_data, 200);
}
/**
* 添加数据
* @return \think\Response
* @Log [sys_name] 在 [sys_time] 创建了栏目:[name]
*/
public function add()
{
//接收参数
$_post = $this->request->post();
//验证参数
validate(\app\api\validate\Manager::class)->check($_post);
//处理并返回参数
$insertId = $this->model->parentAdd($_post);
return send_http_status($insertId, $insertId ? 201 : 202);
}
/**
* 读取单条数据
* @param int $id
* @return \think\Response
*/
public function read($id = '')
{
//验证参数
validate(\app\api\validate\Manager::class)->scene('read')->check(['id' => $id]);
//返回数据
return send_http_status($this->model->parentRead($id));
}
/**
* 保存更新的资源
* @param \think\Request $request
* @param int $id
* @return \think\Response
* @Log [sys_name]在[sys_time]修改了管理员账号[name]的数据
*/
public function edit($id = 0)
{
//接收参数
$_post = $this->request->post();
$_post['id'] = $id; //安全赋值,以免客户端没传id,修改需要id字段
//验证参数
validate(\app\api\validate\Manager::class)->scene('update')->check($_post);
//处理并返回数据
return send_http_status('', $this->model->parentEdit($_post, $id) ? 203 : 204);
}
/**
* 删除指定资源
* @Log [sys_name] 在 [sys_time] 删除了栏目名称:[name]
* @param int $id
* @return \think\Response
*/
public function delete()
{
//接收参数
$ids = $this->request->post('id');
//验证参数
validate(['ids|id' => 'require|length:1,100'])->check(['ids' => $ids]);
//处理并返回数据
return send_http_status('', $this->model->parentDel($ids) ? 205 : 206);
}
/**
* 修改数据状态
* @param int $id
* @return \think\Response
* @Log [sys_name] 在 [sys_time] 设置ID为[id]管理员账号为:[dictionary_status]
*/
public function status()
{
//接收参数
$ids = $this->request->param('id');
$status = $this->request->param('status');
//验证参数
$_rules = [
'ids|id' => 'require|length:1,100',
'status|状态值' => 'require|number|length:1',
];
validate($_rules)->check(['ids' => $ids, 'status' => $status]);
//处理并返回数据
return send_http_status('', $this->model->parentStatus($ids, $status) !== false ? 207 : 208);
}
}

117
app/api/controller/Common.php

@ -0,0 +1,117 @@
<?php
declare (strict_types=1);
namespace app\api\controller;
use app\BaseController;
use auth\PermissAuth;
use think\facade\Request;
use think\facade\Validate;
/**
* @OA\OpenApi(
* @OA\Server(
* url="base.ahbmz.com",
* description="API server"
* ),
* @OA\Info(
* version="1.0.0",
* title="这是我的swagger文档第一个Api",
* description="用户Api接口",
* termsOfService="http://swagger.io/terms/",
* @OA\Contact(
* name="安徽云掌技术支持",
* email="txg@huamill.com",
* url="http://www.ahbmz.com"
* ),
* @OA\License(name="BMZMIT")
* )
* )
*/
class Common extends BaseController
{
protected $action_url = ''; // 请求URL api/manager/index
public function initialize()
{
//获取请求路径
$this->action_url = $this->getBaseActionUrl();
//是否跳过token、权限验证
if (!$this->filterJwtAuth()) {
/**
* JWT Token检测
*/
if ((!defined('UID') || !defined('SITE_ID'))) {
return send_http_status('', 40512);
}
/**
* 定义当前类的实例化[操作日志类使用]
*/
defined('CURR_THIS') ?: define('CURR_THIS', get_called_class());
/**
* 检测用户权限
*/
env('app_debug') ?: $this->checkPermissAuth(); // $this->checkPermissAuth();
}
/**
* 自定义全局验证器
*/
$this->uniqueSite();
}
/**
*
* 自定义全局验证器,检测同站点下数据是否重复
*/
private function uniqueSite()
{
Validate::maker(function ($validate) {
$validate->extend('uniqueSite', 'extra_unique_validate');
});
}
/**
* 检测用户权限
*/
private function checkPermissAuth()
{
$url = str_replace(['//', '\\', '/'], '', $this->request->root());
$url .= '/' . $this->request->controller();
$url .= '/' . $this->request->action();
if (!(PermissAuth::getInstance())->check($url, UID)) {
return send_http_status('', 403);
}
}
/**
* jwt 过滤请求地址,如果返回 true 说明不需要验证
* @return bool
*/
private function filterJwtAuth()
{
$filter_router = config('jwtauth.filter_router');
if (empty($filter_router)) {
return false;
}
if (in_array($this->action_url, array_map('strtolower', $filter_router))) {
return true;
}
return false;
}
/**
* 获取请求路径 模块名/控制器名/方法名
* @return string
*/
private function getBaseActionUrl()
{
$url = str_replace(['//', '\\', '/'], '', $this->request->root());
$url .= '/' . $this->request->controller();
$url .= '/' . $this->request->action();
return strtolower($url);
}
}

90
app/api/controller/Config.php

@ -0,0 +1,90 @@
<?php
declare (strict_types=1);
/**
* Created by 安徽云掌.
* User: 云掌.帮德
* Date: 2020/3/8 22:30
* Desc: 全局配置
*/
namespace app\api\controller;
use think\App;
class Config extends Common
{
public $model = null;
public function __construct(App $app)
{
parent::__construct($app);
$this->model = new \app\api\model\Config();
}
/**
* @OA\Get (
* path="config/index",tags={"系统配置"},summary="获取系统配置",description="获取系统配置",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\Parameter(name="name",in="query",description="配置名称",@OA\Schema (type="string")),
* @OA\Parameter(name="type",in="query",description="配置标识",@OA\Schema (type="string")),
* @OA\Parameter(name="value",in="query",description="配置值",@OA\Schema (type="string")),
* @OA\Response(
* response=200,
* description="返回所有配置信息",
* ),
* )
*/
public function index()
{
//接受参数
$_get = $this->request->param();
//验证参数
validate(\app\api\validate\Config::class)->scene('lists')->check($_get);
//指定搜索参数
$this->model->search_arr = ['name', 'type', 'value'];
//数据处理
$_data = $this->model->index();
//返回数据
return send_http_status($_data);
}
/**
* @OA\Post (path="config/save",tags={"系统配置"},summary="系统配置",description="系统配置",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema (
* @OA\Property(property="name",type="string",description="此那么可自行定义 比如 seo_title"),
* @OA\Property(property="value",type="string",description="此那么可自行定义 比如 合肥网站优化"),
* ),
* ),
* ),
* @OA\Response(
* response=200,
* description="添加成功",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录总数"),
* @OA\Property(property="data", type="integer",format="int32",description="添加成功的的数据ID"),
* ),
* ),
* )
* @Log [sys_name] 在 [sys_time] 更新了配置信息
*/
public function save()
{
//接收参数
$_post = $this->request->post();
//处理并返回参数
$insertId = $this->model->edit($_post);
return send_http_status($insertId, $insertId ? 209 : 210);
}
}

242
app/api/controller/Demo.php

@ -0,0 +1,242 @@
<?php
declare (strict_types=1);
/**
* Created by 安徽云掌.
* User: 云掌.帮德
* Date: 2020/3/8 22:30
* Desc: 统一参考类
*/
namespace app\api\controller;
use think\App;
/**
* Demo类添加、修改等公共请求参数
* @OA\Schema (
* schema = "DemoField",
* required={"id","username","password","sex","phone"},
* @OA\Property(property="username",type="string",minLength=2,maxLength=20,mock={"mock":"@uname"},default="Jessica Smitch",description="管理员名称"),
* @OA\Property(property="truename",type="string",minLength=2,maxLength=20,mock={"mock":"@uname"},default="jack ",description="管理员真实姓名"),
* @OA\Property(property="password",type="string",minLength=6,maxLength=20,mock={"mock":"@string"},default="",description="管理员密码"),
* @OA\Property(property="phone",type="integer",format="int15",minLength=11,maxLength=11,default="",description="手机号"),
* @OA\Property(property="email",type="string",minLength=5,maxLength=50,mock={"mock":"@email"},default="",description="管理员邮箱"),
* @OA\Property(property="birthday",type="string",default="2017-02-02 18:31:45",format="datetime",description="管理员生日"),
* @OA\Property(property="age",type="integer",format="int32",default="1",minimum=1,exclusiveMinimum=true,maximum=150,exclusiveMaximum=true,minLength=1,maxLength=3,description="年龄"),
* ),
*/
class Demo extends Common
{
public $model = null;
public function __construct(App $app)
{
parent::__construct($app);
$this->model = new \app\api\model\Demo();
}
/**
* @OA\Get (
* path="demo/index",tags={"测试案例"},summary="获取DEMO列表",description="根据相关参数获取DEMO列表",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\Parameter(name="username",in="query",description="用户名称",@OA\Schema (type="string")),
* @OA\Parameter (name="sex",in="query",description="用户年龄",@OA\Schema (type="integer",format="int15")),
* @OA\Parameter (name="page",in="query",description="当前页码",@OA\Schema (type="integer",format="int15")),
* @OA\Parameter (name="limit",in="query",description="分页数量",@OA\Schema (type="integer",format="int15")),
* @OA\Response(
* response=200,
* description="返回DEMo用户数据信息",
* @OA\JsonContent(ref="#/components/schemas/DemoMsgExport"),
* ),
* )
*/
public function index()
{
//接受参数
$_get = $this->request->get();
//验证参数
validate(\app\api\validate\Demo::class)->scene('lists')->check($_get);
//指定搜索参数
$this->model->search_arr = ['username', 'phone:OR', 'sex:OR', 'truename'];
//数据处理
$_data = $this->model->index();
//返回数据
return send_http_status($_data);
}
/**
* @OA\Get (
* path="demo/read/{id}",tags={"测试案例"},summary="获取DEMO详情",description="根据ID查询DEMO信息",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\Parameter(name="id",in="path",required=true,description="ID",@OA\Schema (type="integer",format="int32")),
* @OA\Response(
* response=200,
* description="返回DEMO单条用户数据信息",
* @OA\JsonContent(ref="#/components/schemas/DemoMsgExport"),
* ),
* )
*/
public function read(int $id = 0)
{
//验证参数
validate(\app\api\validate\Demo::class)->scene('read')->check(['id' => $id]);
//返回数据
return send_http_status($this->model->parentRead($id));
}
/**
* @OA\Post (path="demo/add",tags={"测试案例"},summary="添加DEMO数据",description="添加后台DEMO管理数据",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema(ref="#/components/schemas/DemoField"),
* ),
* ),
* @OA\Response(
* response=200,
* description="添加成功",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="integer",format="int32",description="添加成功的的数据ID"),
* ),
* ),
* )
* @Log [sys_name] 在 [sys_time] 创建了测试:[username]
*/
public function add()
{
//接收参数
$_post = $this->request->post();
//验证参数
validate(\app\api\validate\Demo::class)->check($_post);
//处理并返回参数
$insertId = $this->model->parentAdd($_post);
return send_http_status($insertId, $insertId ? 201 : 202);
}
/**
* @OA\Post (path="demo/edit/id/{id}",tags={"测试案例"},summary="修改DEMO数据",description="修改后台DEMO管理数据",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema(ref="#/components/schemas/DemoField"),
* ),
* ),
* @OA\Response(
* response=200,
* description="修改数据状态",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="string",description="不返回"),
* ),
* ),
* )
* @Log [sys_name]在[sys_time]修改了测试账号[username]的数据
*/
public function edit(int $id = 0)
{
//接收参数
$_post = $this->request->post();
$_post['id'] = empty($_post['id']) ? $id : 0; //安全赋值,以免客户端没传id,修改需要id字段
//验证参数
validate(\app\api\validate\Demo::class)->scene('update')->check($_post);
//处理并返回数据
return send_http_status('', $this->model->parentEdit($_post, $id) ? 203 : 204);
}
/**
* @OA\Post (
* path="demo/delete",tags={"测试案例"},summary="删除DEMO数据",description="根据ID删除DEMO信息",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema (
* required={"id"},
* @OA\Property(property="id",type="string",description="数据ID或数据ID集合 id=1或 id=1,2,8"),
* ),
* ),
* ),
* @OA\Response(
* response=200,
* description="删除数据状态",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="string",description="不返回"),
* ),
* ),
* )
* @Log [sys_name] 在 [sys_time] 删除了测试账号:[username]
*/
public function delete()
{
//接收参数
$ids = $this->request->post('id');
//验证参数
validate(['ids|id' => 'require|length:1,1000'])->check(['ids' => $ids]);
//处理并返回数据
return send_http_status('', $this->model->parentDel($ids) ? 205 : 206);
}
/**
* @OA\Post (
* path="demo/status",tags={"测试案例"},summary="更新DEMO状态",description="根据ID及status更新DEMO状态",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema (
* required={"id","status"},
* @OA\Property(property="id",type="string",description="数据ID或数据ID集合 id=1或 id=1,2,8"),
* @OA\Property(property="status",type="integer",format="int15",description="数据状态 0禁用 1启用"),
* ),
* ),
* ),
* @OA\Response(
* response=200,
* description="删除数据状态",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="string",description="不返回"),
* ),
* ),
* )
* @Log [sys_name] 在 [sys_time] 设置ID为[id]测试账号为:[dictionary_status]
*/
public function status()
{
//接收参数
$ids = $this->request->param('id');
$status = $this->request->param('status');
//验证参数
$_rules = [
'ids|id' => 'require|length:1,100',
'status|状态值' => 'require|number|length:1',
];
validate($_rules)->check(['ids' => $ids, 'status' => $status]);
//处理并返回数据
return send_http_status('', $this->model->parentStatus($ids, $status) !== false ? 207 : 208);
}
}

203
app/api/controller/Dictionary.php

@ -0,0 +1,203 @@
<?php
declare (strict_types=1);
/**
* Created by 安徽云掌.
* User: 云掌.帮德
* Date: 2020/3/8 22:30
* Desc: 字典类型类
*/
namespace app\api\controller;
use think\App;
class Dictionary extends Common
{
public $model = null;
public function __construct(App $app)
{
parent::__construct($app);
$this->model = new \app\api\model\Dictionary();
}
public function index()
{
//接受参数
$_get = $this->request->get();
//验证参数
// validate(\app\api\validate\Dictionary::class)->scene('lists')->check($_get);
//指定搜索参数
$this->model->search_arr = ['dict_name','dict_value:OR'];
//数据处理
$_data = $this->model->index();
//返回数据
return send_http_status($_data);
}
public function read(int $id = 0)
{
//验证参数
validate(\app\api\validate\Dictionary::class)->scene('read')->check(['id' => $id]);
//返回数据
return send_http_status($this->model->parentRead($id));
}
/**
* @OA\Post (path="demo/add",tags={"测试案例"},summary="添加DEMO数据",description="添加后台DEMO管理数据",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema(ref="#/components/schemas/DemoField"),
* ),
* ),
* @OA\Response(
* response=200,
* description="添加成功",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="integer",format="int32",description="添加成功的的数据ID"),
* ),
* ),
* )
* @Log [sys_name] 在 [sys_time] 创建了字典类型:[dict_symbol]:[dict_name]
*/
public function add()
{
//接收参数
$_post = $this->request->post();
//验证参数
validate(\app\api\validate\Dictionary::class)->check($_post);
//处理并返回参数
$insertId = $this->model->parentAdd($_post);
return send_http_status($insertId, $insertId ? 201 : 202);
}
/**
* @OA\Post (path="demo/edit/id/{id}",tags={"测试案例"},summary="修改DEMO数据",description="修改后台DEMO管理数据",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema(ref="#/components/schemas/DemoField"),
* ),
* ),
* @OA\Response(
* response=200,
* description="修改数据状态",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="string",description="不返回"),
* ),
* ),
* )
* @Log [sys_name]在[sys_time]修改了字典[dict_symbol]的数据
*/
public function edit(int $id = 0)
{
//接收参数
$_post = $this->request->post();
$_post['id'] = empty($_post['id']) ? $id : 0; //安全赋值,以免客户端没传id,修改需要id字段
//验证参数
validate(\app\api\validate\Dictionary::class)->scene('update')->check($_post);
//处理并返回数据
return send_http_status('', $this->model->parentEdit($_post, $id) ? 203 : 204);
}
/**
* @OA\Post (
* path="demo/delete",tags={"测试案例"},summary="删除DEMO数据",description="根据ID删除DEMO信息",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema (
* required={"id"},
* @OA\Property(property="id",type="string",description="数据ID或数据ID集合 id=1或 id=1,2,8"),
* ),
* ),
* ),
* @OA\Response(
* response=200,
* description="删除数据状态",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="string",description="不返回"),
* ),
* ),
* )
* @Log [sys_name] 在 [sys_time] 删除了字典:[dict_symbol]:[dict_name]
*/
public function delete()
{
//接收参数
$ids = $this->request->param('id');
//验证参数
validate(['ids|id' => 'require|length:1,1000'])->check(['ids' => $ids]);
//处理并返回数据
return send_http_status('', $this->model->parentDel($ids) ? 205 : 206);
}
/**
* @OA\Post (
* path="demo/status",tags={"测试案例"},summary="更新DEMO状态",description="根据ID及status更新DEMO状态",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema (
* required={"id","status"},
* @OA\Property(property="id",type="string",description="数据ID或数据ID集合 id=1或 id=1,2,8"),
* @OA\Property(property="status",type="integer",format="int15",description="数据状态 0禁用 1启用"),
* ),
* ),
* ),
* @OA\Response(
* response=200,
* description="删除数据状态",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="string",description="不返回"),
* ),
* ),
* )
* @Log [sys_name] 在 [sys_time] 设置ID为[id]测试账号为:[dictionary_status]
*/
public function status()
{
//接收参数
$ids = $this->request->param('id');
$status = $this->request->param('status');
//验证参数
$_rules = [
'ids|id' => 'require|length:1,100',
'status|状态值' => 'require|number|length:1',
];
validate($_rules)->check(['ids' => $ids, 'status' => $status]);
//处理并返回数据
return send_http_status('', $this->model->parentStatus($ids, $status) !== false ? 207 : 208);
}
}

207
app/api/controller/DictionaryType.php

@ -0,0 +1,207 @@
<?php
declare (strict_types=1);
/**
* Created by 安徽云掌.
* User: 云掌.帮德
* Date: 2020/3/8 22:30
* Desc: 字典类型类
*/
namespace app\api\controller;
use think\App;
class DictionaryType extends Common
{
public $model = null;
public function __construct(App $app)
{
parent::__construct($app);
$this->model = new \app\api\model\DictionaryType();
}
public function index()
{
//接受参数
$_get = $this->request->get();
//验证参数
// validate(\app\api\validate\DictionaryType::class)->scene('lists')->check($_get);
//指定搜索参数
// $this->model->search_arr = ['username', 'phone:OR', 'sex:OR', 'truename'];
//数据处理
$_data = $this->model->index();
$this->model->exportDictToConfig();
//返回数据
return send_http_status($_data);
}
public function test(){
}
public function read(int $id = 0)
{
//验证参数
validate(\app\api\validate\DictionaryType::class)->scene('read')->check(['id' => $id]);
//返回数据
return send_http_status($this->model->parentRead($id));
}
/**
* @OA\Post (path="demo/add",tags={"测试案例"},summary="添加DEMO数据",description="添加后台DEMO管理数据",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema(ref="#/components/schemas/DemoField"),
* ),
* ),
* @OA\Response(
* response=200,
* description="添加成功",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="integer",format="int32",description="添加成功的的数据ID"),
* ),
* ),
* )
* @Log [sys_name] 在 [sys_time] 创建了字典类型:[dict_symbol]:[dict_name]
*/
public function add()
{
//接收参数
$_post = $this->request->post();
//验证参数
validate(\app\api\validate\DictionaryType::class)->check($_post);
//处理并返回参数
$insertId = $this->model->parentAdd($_post);
return send_http_status($insertId, $insertId ? 201 : 202);
}
/**
* @OA\Post (path="demo/edit/id/{id}",tags={"测试案例"},summary="修改DEMO数据",description="修改后台DEMO管理数据",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema(ref="#/components/schemas/DemoField"),
* ),
* ),
* @OA\Response(
* response=200,
* description="修改数据状态",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="string",description="不返回"),
* ),
* ),
* )
* @Log [sys_name]在[sys_time]修改了字典[dict_symbol]的数据
*/
public function edit(int $id = 0)
{
//接收参数
$_post = $this->request->post();
$_post['id'] = empty($_post['id']) ? $id : 0; //安全赋值,以免客户端没传id,修改需要id字段
//验证参数
validate(\app\api\validate\DictionaryType::class)->scene('update')->check($_post);
//处理并返回数据
return send_http_status('', $this->model->parentEdit($_post, $id) ? 203 : 204);
}
/**
* @OA\Post (
* path="demo/delete",tags={"测试案例"},summary="删除DEMO数据",description="根据ID删除DEMO信息",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema (
* required={"id"},
* @OA\Property(property="id",type="string",description="数据ID或数据ID集合 id=1或 id=1,2,8"),
* ),
* ),
* ),
* @OA\Response(
* response=200,
* description="删除数据状态",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="string",description="不返回"),
* ),
* ),
* )
* @Log [sys_name] 在 [sys_time] 删除了字典:[dict_symbol]:[dict_name]
*/
public function delete()
{
//接收参数
$ids = $this->request->param('id');
//验证参数
validate(['ids|id' => 'require|length:1,1000'])->check(['ids' => $ids]);
//处理并返回数据
return send_http_status('', $this->model->parentDel($ids) ? 205 : 206);
}
/**
* @OA\Post (
* path="demo/status",tags={"测试案例"},summary="更新DEMO状态",description="根据ID及status更新DEMO状态",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema (
* required={"id","status"},
* @OA\Property(property="id",type="string",description="数据ID或数据ID集合 id=1或 id=1,2,8"),
* @OA\Property(property="status",type="integer",format="int15",description="数据状态 0禁用 1启用"),
* ),
* ),
* ),
* @OA\Response(
* response=200,
* description="删除数据状态",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="string",description="不返回"),
* ),
* ),
* )
* @Log [sys_name] 在 [sys_time] 设置ID为[id]测试账号为:[dictionary_status]
*/
public function status()
{
//接收参数
$ids = $this->request->param('id');
$status = $this->request->param('status');
//验证参数
$_rules = [
'ids|id' => 'require|length:1,100',
'status|状态值' => 'require|number|length:1',
];
validate($_rules)->check(['ids' => $ids, 'status' => $status]);
//处理并返回数据
return send_http_status('', $this->model->parentStatus($ids, $status) !== false ? 207 : 208);
}
}

395
app/api/controller/Group.php

@ -0,0 +1,395 @@
<?php
declare (strict_types=1);
/**
* Created by 安徽云掌.
* User: 云掌.帮德
* Date: 2020/3/8 22:30
* Desc: 角色权限类
*/
namespace app\api\controller;
use auth\PermissAuth;
use think\App;
/**
* Manager类添加、修改等公共请求参数
* @OA\Schema (
* schema = "GroupField",
* required={"id","username","password","sex","phone"},
* @OA\Property(property="title",type="string",minLength=1,maxLength=100,mock={"mock":"@cname"},default="商务部",description="用户组中文名称"),
* @OA\Property(property="role_code",type="string",minLength=1,maxLength=100,mock={"mock":"@name"},default="bussiness ",description="角色标识"),
* @OA\Property(property="remark",type="string",minLength=1,maxLength=100,mock={"mock":"@string"},default="",description="备注"),
* ),
*/
class Group extends Common
{
public $model = null;
public function __construct(App $app)
{
parent::__construct($app);
}
/**
* @OA\Get (
* path="group/index",tags={"角色管理"},summary="获取角色管理",description="根据相关参数获取角色管理",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\Parameter(name="title",in="query",description="角色名称",@OA\Schema (type="string")),
* @OA\Parameter(name="role_code",in="query",description="角色标识",@OA\Schema (type="string")),
* @OA\Parameter (name="page",in="query",description="当前页码",@OA\Schema (type="integer",format="int15")),
* @OA\Parameter (name="limit",in="query",description="分页数量",@OA\Schema (type="integer",format="int15")),
* @OA\Response(
* response=200,
* description="返回管理员用户数据信息",
* @OA\JsonContent(ref="#/components/schemas/GroupMsgExport"),
* ),
* )
*/
public function index()
{
//接受参数
$_get = $this->request->get();
//验证参数
validate(\app\api\validate\Group::class)->scene('lists')->check($_get);
$_data = (PermissAuth::getInstance())->getGroups();
//返回数据
return send_http_status($_data);
}
/**
* @OA\Get (
* path="group/getGroupRule",tags={"角色管理"},summary="查询角色权限",description="查询角色所有的权限菜单,并进行标记checked",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\Parameter(name="role_id",in="path",required=true,description="角色ID",@OA\Schema (type="integer",format="int32")),
* @OA\Response(
* response=200,
* description="返回管理员用户数据信息",
* @OA\JsonContent(ref="#/components/schemas/MenuMsgExport"),
* ),
* )
*/
public function getGroupRule()
{
//接受参数
$_get = $this->request->param('role_id', 0, 'int');
// //验证参数
// validate(\app\api\validate\Group::class)->scene('lists')->check($_get);
$_data = (PermissAuth::getInstance())->getGroupRule($_get);
//返回数据
return send_http_status($_data);
}
public function getUserGroups()
{
$_data = (PermissAuth::getInstance())->getUserGroups(UID);
//返回数据
return send_http_status($_data);
}
/**
* @OA\Post (path="group/add",tags={"角色管理"},summary="添加角色数据",description="添加后台角色数据",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema(ref="#/components/schemas/GroupField"),
* ),
* ),
* @OA\Response(
* response=200,
* description="添加成功",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录总数"),
* @OA\Property(property="data", type="integer",format="int32",description="添加成功的的数据ID"),
* ),
* ),
* )
* @Log [sys_name] 在 [sys_time] 创建了用户角色:[title]
*/
public function add()
{
//接收参数
$_post = $this->request->post();
//验证参数
validate(\app\api\validate\Group::class)->check($_post);
//处理并返回参数
$insertId = (PermissAuth::getInstance())->addGroup($_post);
return send_http_status($insertId, $insertId ? 201 : 202);
}
/**
* @OA\Post (path="group/addGroupRule/role_id/{role_id}",tags={"角色管理"},summary="添加角色权限",description="添加后台角色权限",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema (
* required={"menu_id"},
* @OA\Property(property="menu_id",type="string",description="数据ID或数据ID集合 id=1或 id=1,2,8"),
* ),
* ),
* ),
* @OA\Response(
* response=200,
* description="添加成功",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录总数"),
* @OA\Property(property="data", type="integer",format="int32",description="添加成功的的数据ID"),
* ),
* ),
* )
* @param int $role_id
* @Log [sys_name] 在 [sys_time] 编辑了用户角色:[title]的权限菜单:
*/
public function addGroupRule($role_id = 0)
{
//接收参数
$menu_id = $this->request->param('menu_id', '', 'string');
$menu_id = implode(',', $menu_id);
//验证参数
$_rules = [
'role_id|用户角色ID' => 'require|length:1,100',
'menu_id|菜单id' => 'require|length:1,10000',
];
validate($_rules)->check(['role_id' => $role_id, 'menu_id' => $menu_id]);
//处理并返回参数
$insertId = (PermissAuth::getInstance())->addGroupRule((int)$role_id, $menu_id);
return send_http_status($insertId, $insertId ? 201 : 202);
}
/**
* @param int $id 角色ID
*/
public function readRule($id = '')
{
//验证参数
validate(\app\api\validate\Demo::class)->scene('read')->check(['id' => $id]);
//处理数据
$_data = (PermissAuth::getInstance())->getGroupRule((int)$id);
if (!empty($_data)) {
$_data = get_tree($_data);
}
//返回数据
return send_http_status($_data);
}
/**
* @OA\Post (path="group/edit/id/{id}",tags={"角色管理"},summary="修改角色数据",description="修改角色数据",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema(ref="#/components/schemas/GroupField"),
* ),
* ),
* @OA\Response(
* response=200,
* description="修改数据状态",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="string",description="不返回"),
* ),
* ),
* )
* @Log [sys_name]在[sys_time]修改了用户角色:[title]
*/
public function edit($id = 0)
{
//接收参数
$_post['title'] = $this->request->post('title', '');
$_post['role_code'] = $this->request->post('role_code', '');
$_post['remark'] = $this->request->post('remark', '');
$_post['id'] = $id; //安全赋值,以免客户端没传id,修改需要id字段
//验证参数
validate(\app\api\validate\Group::class)->check($_post);
//处理并返回数据
return send_http_status('', (PermissAuth::getInstance())->editGroup($_post) ? 203 : 204);
}
/**
* @OA\Post (
* path="group/status",tags={"角色管理"},summary="更新角色状态",description="根据ID及status更新角色状态",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema (
* required={"id","status"},
* @OA\Property(property="id",type="string",description="数据ID或数据ID集合 id=1或 id=1,2,8"),
* @OA\Property(property="status",type="integer",format="int15",description="数据状态 0禁用 1启用"),
* ),
* ),
* ),
* @OA\Response(
* response=200,
* description="删除数据状态",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="string",description="不返回"),
* ),
* ),
* )
* @Log [sys_name] 在 [sys_time] [dictionary_status]了用户角色:[title]
*/
public function status()
{
//接收参数
$ids = $this->request->param('id');
$status = $this->request->param('status', 1, 'int');
//验证参数
$_rules = [
'ids|id' => 'require|length:1,100',
'status|状态值' => 'require|number|length:1',
];
validate($_rules)->check(['ids' => $ids, 'status' => $status]);
//处理并返回数据
return send_http_status('', PermissAuth::getInstance()->statusGroup($ids, $status) !== false ? 207 : 208);
}
/**
* @OA\Post (
* path="group/delete",tags={"角色管理"},summary="删除角色数据",description="根据ID删除角色数据",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema (
* required={"id"},
* @OA\Property(property="id",type="string",description="数据ID或数据ID集合 id=1或 id=1,2,8"),
* ),
* ),
* ),
* @OA\Response(
* response=200,
* description="删除数据状态",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="string",description="不返回"),
* ),
* ),
* )
* @Log [sys_name] 在 [sys_time] 删除了用户角色:[title]
*/
public function delete()
{
//接收参数
$ids = $this->request->post('id');
//验证参数
validate(['ids|id' => 'require|length:1,100'])->check(['ids' => $ids]);
$affected = (PermissAuth::getInstance())->deleteGroup($ids);
//处理并返回数据
return send_http_status('', $affected ? 205 : 206);
}
/**
* swagger response返回数据引用
* @OA\Schema(
* schema="GroupMsgExport",
* required={"code","msg","count","data"},
* @OA\Property(
* property="code",
* type="integer",
* format="int32",
* description="状态码"
* ),
* @OA\Property(
* property="msg",
* type="string",
* description="提示消息"
* ),
* @OA\Property(
* property="count",
* type="integer",
* format="int32",
* description="记录总数",
* ),
* @OA\Property(
* property="data",
* type="array",
* description="请求结果",
* @OA\Items(
* @OA\Property(
* property="id",
* type="integer",
* description="ID"
* ),
* @OA\Property(
* property="site_id",
* type="integer",
* description="站点ID"
* ),
* @OA\Property(
* property="remark",
* type="string",
* description="备注",
* ),
* @OA\Property(
* property="title",
* type="string",
* description="用户组中文名称"
* ),
* @OA\Property(
* property="role_code",
* type="string",
* description="角色标识"
* ),
* @OA\Property(
* property="status",
* type="integer",
* description="状态:为1正常,为0禁用"
* ),
* @OA\Property(
* property="rules",
* type="string",
* description="用户组拥有的规则id, 多个规则","隔开"
* ),
* @OA\Property(
* property="type",
* type="integer",
* description="组的类型 1:共用 2:个人"
* ),
* @OA\Property(
* property="delete_time",
* type="integer",
* description="是否删除 null:未删除"
* ),
* @OA\Property(
* property="update_time",
* type="integer",
* description="更新时间"
* ),
* @OA\Property(
* property="create_time",
* type="integer",
* description="创建时间"
* ),
* )
* ),
*
* ),
*/
}

85
app/api/controller/ImageStorage.php

@ -0,0 +1,85 @@
<?php
declare (strict_types=1);
/**
* Created by 安徽云掌.
* User: 云掌.帮德
* Date: 2020/3/8 22:30
* Desc: 字典类型类
*/
namespace app\api\controller;
use think\App;
class ImageStorage extends Common
{
public $model = null;
public function __construct(App $app)
{
parent::__construct($app);
$this->model = new \app\api\model\ImageStorages();
}
public function index()
{
//接受参数
$_get = $this->request->get();
//指定搜索参数
$this->model->search_arr = ['title'];
//数据处理
$_data = $this->model->index();
//返回数据
return send_http_status($_data);
}
public function read(int $id = 0)
{
//验证参数
validate(\app\api\validate\Message::class)->scene('read')->check(['id' => $id]);
//返回数据
return send_http_status($this->model->parentRead($id));
}
public function add()
{
//接收参数
$_post = $this->request->post();
//处理并返回参数
$insertId = $this->model->parentAdd($_post);
return send_http_status($insertId, $insertId ? 201 : 202);
}
public function edit(int $id = 0)
{
//接收参数
$_post = $this->request->post();
$_post['id'] = empty($_post['id']) ? $id : 0; //安全赋值,以免客户端没传id,修改需要id字段
//处理并返回数据
return send_http_status('', $this->model->parentEdit($_post, $id) ? 203 : 204);
}
public function delete()
{
//接收参数
$ids = $this->request->param('id');
//验证参数
validate(['ids|id' => 'require|length:1,1000'])->check(['ids' => $ids]);
//处理并返回数据
return send_http_status('', $this->model->parentDel($ids) ? 205 : 206);
}
}

25
app/api/controller/Index.php

@ -0,0 +1,25 @@
<?php
declare (strict_types=1);
namespace app\api\controller;
use think\facade\Console;
use think\Request;
use OpenApi\Serializer;
class Index extends Common
{
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index()
{
exit;
}
}

55
app/api/controller/Log.php

@ -0,0 +1,55 @@
<?php
declare (strict_types=1);
namespace app\api\controller;
use think\App;
/**
* 系统日志
* @package app\api\controller
*/
class Log extends Common
{
public $model = null;
public function __construct(App $app)
{
parent::__construct($app);
$this->model = new \app\api\model\Log();
}
/**
* @OA\Get (
* path="log/index",tags={"日志管理"},summary="获取日志列表",description="根据相关参数获取日志列表",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\Parameter(name="username",in="query",description="管理员名称",@OA\Schema (type="string")),
* @OA\Parameter(name="model",in="query",description="操作模块",@OA\Schema (type="string")),
* @OA\Parameter (name="page",in="query",description="当前页码",@OA\Schema (type="integer",format="int15")),
* @OA\Parameter (name="limit",in="query",description="分页数量",@OA\Schema (type="integer",format="int15")),
* @OA\Response(
* response=200,
* description="返回管理员用户数据信息",
* @OA\JsonContent(ref="#/components/schemas/LogMsgExport"),
* ),
* ),
*/
public function index()
{
//接受参数
$_get = $this->request->get();
//验证参数
validate(\app\api\validate\Log::class)->check($_get);
//指定搜索参数
$this->model->search_arr = ['username','model'];
//数据处理
$_data = $this->model->index();
//返回数据
return send_http_status($_data);
}
}

169
app/api/controller/Login.php

@ -0,0 +1,169 @@
<?php
declare (strict_types=1);
namespace app\api\controller;
use app\api\model\Manager;
use app\api\model\Token;
use auth\JwtAuth;
use edward\captcha\facade\CaptchaApi;
use service\ActionLog;
class Login
{
/**
* @OA\Post (
* path="login/login",tags={"公共分类"},summary="用户登录",description="用户登录",
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema (
* required={"username","password","key","code"},
* @OA\Property(property="username",type="string",minLength=2,maxLength=20,description="登录账号"),
* @OA\Property(property="password",type="string",minLength=6,maxLength=20,description="登录密码"),
* @OA\Property(property="key",type="string",minLength=1,maxLength=100,description="验证码安全标识 验证码接口返回"),
* @OA\Property(property="code",type="integer",minLength=1,maxLength=6,format="int15",description="验证码"),
* ),
* ),
* ),
* @OA\Response(
* response=200,
* description="返回管理员用户数据信息,token信息、管理员信息",
* ),
* )
* @Log [sys_name] 在 [sys_time] 登录了后台
*/
public function login(Manager $manager)
{
//获取参数
$_post = \request()->param();
//验证参数
$_rule = [
'username|登录用户名' => 'require|length:4,20',
'password|登录密码' => 'require|length:6,20',
'key|验证码' => 'require|length:6,200',
'code|验证码' => 'require|length:1,6',
];
$_message = [
'username.length' => '请输入4到20位的用户名!!!',
'password.length' => '请输入6到20位的密码!!!',
'code.length' => '请输入1到6位的验证码!!!',
'key.length' => '验证码不正确!!!',
];
env('app_debug') ?: validate($_rule, $_message)->check($_post);
//验证码检测
env('app_debug') ?: $this->checkCaptcha($_post['code'], $_post['key']);
//验证用户信息
$user_data = $manager->checkLogin($_post);
//发送JWT签证密钥
$token_obj = (JwtAuth::getInstance())->setToken($user_data);
//写入登录日志
defined('CURR_THIS') ?: define('CURR_THIS', get_called_class());
$user_data['user_id'] = $user_data['id'];
ActionLog::getInstance()->write($user_data);
//获取未读系统邮件
$message = new \app\api\model\Message();
$message->setUserMessage($user_data['user_id'],$user_data['site_id']);
//返回数据
$data = [
'access_token' => [
'token' => $token_obj->getToken(),
'expire' => config('jwtauth.web.expire_at'),
// 'refresh_token' => $token_obj->createRefreshToken(new Token()),
],
'userinfo' => $user_data,
];
return send_http_status($data);
}
/**
* 通过refresh_token重新生成token
*/
public function refreshToken(Token $token)
{
$refresh_token = request()->param('refresh_token');
$_data = $token->refreshToken($refresh_token);
if (!empty($_data)) {
return send_http_status($_data);
}
return send_http_status('', 40509, 406);
}
/**
* @OA\Get (
* path="login/captcha",tags={"公共分类"},summary="获取验证码",description="获取验证码",
* @OA\Response(
* response=200,
* description="返回验证码信息",
* @OA\JsonContent(
* @OA\Schema(
* required={"code","msg","count","data"},
* @OA\Property(
* property="code",
* type="integer",
* format="int32",
* description="状态码"
* ),
* @OA\Property(
* property="msg",
* type="string",
* description="提示消息"
* ),
* @OA\Property(
* property="count",
* type="integer",
* format="int32",
* description="记录总数",
* ),
* @OA\Property(
* property="data",
* type="array",
* description="请求结果",
* @OA\Items(
* @OA\Property(
* property="base64",
* type="string",
* description="base64图片"
* ),
* @OA\Property(
* property="key",
* type="string",
* description="验证码安全标识"
* ),
* @OA\Property(
* property="md5",
* type="string",
* description="验证码md5值"
* ),
* )
* ),
* ),
* ),
* ),
* )
* 前后端分离验证码生成
*/
public function captcha()
{
$_data = CaptchaApi::create();
return send_http_status($_data);
}
/**
* 前后端分离验证码检测
* @param string $code
* @param string $key
*/
public function checkCaptcha(string $code = '', string $key = '')
{
return CaptchaApi::check($code, $key) ?: send_http_status('', 40506);
}
}

439
app/api/controller/Manager.php

@ -0,0 +1,439 @@
<?php
declare (strict_types=1);
/**
* Created by 安徽云掌.
* User: 云掌.帮德
* Date: 2020/3/8 22:30
* Desc: 管理员类
*/
namespace app\api\controller;
use auth\PermissAuth;
use think\App;
/**
* Manager类添加、修改等公共请求参数
* @OA\Schema (
* schema = "ManagerField",
* required={"username","password","sex","phone"},
* @OA\Property(property="username",type="string",minLength=2,maxLength=20,mock={"mock":"@word"},default="Jessica Smitch",description="管理员名称"),
* @OA\Property(property="truename",type="string",minLength=2,maxLength=20,mock={"mock":"@cname"},default="jack ",description="管理员真实姓名"),
* @OA\Property(property="password",type="string",minLength=6,maxLength=20,mock={"mock":"@string"},default="",description="管理员密码"),
* @OA\Property(property="sex",type="integer",format="int15",minLength=1,maxLength=1,default="0",description="性别"),
* @OA\Property(property="phone",type="integer",format="int15",minLength=11,maxLength=11,default="",description="手机号"),
* @OA\Property(property="email",type="string",minLength=5,maxLength=50,mock={"mock":"@email"},default="",description="管理员邮箱"),
* @OA\Property(property="status",type="integer",format="int15",minLength=1,maxLength=1,default="1",description="状态"),
* @OA\Property(property="introduction",type="string",minLength=1,maxLength=200,mock={"mock":"@cparagraph"},default=" ",description="管理员简介"),
* ),
*/
class Manager extends Common
{
public $model = null;
public function __construct(App $app)
{
parent::__construct($app);
$this->model = new \app\api\model\Manager();
}
/**
* @OA\Get (
* path="manager/index",tags={"用户管理"},summary="获取用户列表",description="根据相关参数获取用户列表",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\Parameter(name="username",in="query",description="管理员名称",@OA\Schema (type="string")),
* @OA\Parameter(name="truename",in="query",description="真实姓名",@OA\Schema (type="string")),
* @OA\Parameter (name="phone",in="query",description="手机号",@OA\Schema (type="integer",format="int15")),
* @OA\Parameter (name="sex",in="query",description="性别",@OA\Schema (type="integer",format="int15")),
* @OA\Parameter (name="page",in="query",description="当前页码",@OA\Schema (type="integer",format="int15")),
* @OA\Parameter (name="limit",in="query",description="分页数量",@OA\Schema (type="integer",format="int15")),
* @OA\Response(
* response=200,
* description="返回管理员用户数据信息",
* @OA\JsonContent(ref="#/components/schemas/ManagerMsgExport"),
* ),
* )
*/
public function index()
{
//接受参数
$_get = $this->request->get();
//验证参数
validate(\app\api\validate\Manager::class)->scene('lists')->check($_get);
//指定搜索参数
$this->model->search_arr = ['username', 'phone', 'sex', 'truename'];
//数据处理
$_data = $this->model->index();
//返回数据
return send_http_status($_data);
}
/**
* @OA\Get (
* path="manager/read/id/{id}",tags={"用户管理"},summary="获取用户详情",description="根据ID查询用户信息",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\Parameter(name="id",in="path",required=true,description="ID",@OA\Schema (type="integer",format="int32")),
* @OA\Response(
* response=200,
* description="返回管理员用户数据信息",
* @OA\JsonContent(ref="#/components/schemas/ManagerMsgExport"),
* ),
* )
*/
public function read(int $id = UID)
{
//验证参数
validate(\app\api\validate\Manager::class)->scene('read')->check(['id' => $id]);
//返回数据
return send_http_status($this->model->parentRead($id));
}
/**
* @OA\Get (
* path="manager/readPersional",tags={"用户管理"},summary="获取个人详情",description="获取当前登录用户的个人资料",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\Response(
* response=200,
* description="返回当前登录用户的数据信息",
* @OA\JsonContent(ref="#/components/schemas/ManagerMsgExport"),
* ),
* )
*/
public function readPersional()
{
//验证参数
validate(\app\api\validate\Manager::class)->scene('read')->check(['id' => UID]);
//返回数据
return send_http_status($this->model->parentRead(UID));
}
/**
* @OA\Get (
* path="manager/permissMenu",tags={"用户管理"},summary="获取用户权限",description="根据当前登录用户UID获取当前用户权限菜单",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\Response(
* response=200,
* description="返回管理员权限菜单数据",
* @OA\JsonContent(ref="#/components/schemas/MenuMsgExport"),
* ),
* )
*/
public function permissMenu()
{
$_data = PermissAuth::getInstance()->getAuthList(UID, 1, true);
//用户权限
$_data = get_tree($_data, 0, 'children');
//返回数据
return send_http_status($_data);
}
/**
* @OA\Post (path="manager/add",tags={"用户管理"},summary="添加管理员数据",description="添加后台管理员数据",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema(ref="#/components/schemas/ManagerField"),
* ),
* ),
* @OA\Response(
* response=200,
* description="添加成功",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录总数"),
* @OA\Property(property="data", type="integer",format="int32",description="添加成功的的数据ID"),
* ),
* ),
* )
* @Log [sys_name] 在 [sys_time] 创建了管理员:[username]
*/
public function add()
{
//接收参数
$_post = $this->request->post();
//验证参数
validate(\app\api\validate\Manager::class)->check($_post);
//处理并返回参数
$insertId = $this->model->parentAdd($_post);
return send_http_status($insertId, $insertId ? 201 : 202);
}
/**
* @OA\Post (path="manager/edit/id/{id}",tags={"用户管理"},summary="修改用户数据",description="修改管理员数据",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema(ref="#/components/schemas/ManagerField"),
* ),
* ),
* @OA\Response(
* response=200,
* description="修改数据状态",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="string",description="不返回"),
* ),
* ),
* )
* @Log [sys_name]在[sys_time] 修改了管理员账号[username]的数据
*/
public function edit($id = 0)
{
//接收参数
$_post = $this->request->param();
//验证参数
validate(\app\api\validate\Manager::class)->scene('update')->check($_post);
//处理并返回数据
return send_http_status('', $this->model->parentEdit($_post, $id) ? 203 : 204);
}
/**
* @OA\Post (path="manager/editPersional",tags={"用户管理"},summary="修改个人数据",description="修改自己的个人资料",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema(ref="#/components/schemas/ManagerField"),
* ),
* ),
* @OA\Response(
* response=200,
* description="修改数据状态",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="string",description="不返回"),
* ),
* ),
* )
* @Log [sys_name]在[sys_time] 修改了管理员账号[username]的数据
*/
public function editPersional()
{
//接收参数
$_post = $this->request->param();
//验证参数
validate(\app\api\validate\Manager::class)->scene('update')->check($_post);
//处理并返回数据
return send_http_status('', $this->model->parentEdit($_post, UID) ? 203 : 204);
}
/**
* @OA\Post (
* path="manager/passwordEdit",tags={"用户管理"},summary="重置用户密码",description="根据ID重置用户密码",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema (
* required={"id","password","old_password","username"},
* @OA\Property(property="id",type="integer",format="int15",description="用户ID"),
* @OA\Property(property="password",type="string",minLength=6,maxLength=20,description="新密码"),
* @OA\Property(property="old_password",type="string",minLength=6,maxLength=20,description="原始密码"),
* @OA\Property(property="username",type="string",minLength=2,maxLength=20,description="管理员账号"),
* ),
* ),
* ),
* @OA\Response(
* response=200,
* description="删除数据状态",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="string",description="不返回"),
* ),
* ),
* )
* @Log [sys_name]在[sys_time] 修改了账号密码
*/
public function passwordEdit()
{
//接收参数
$_post = $this->request->param();
$_post['id'] = UID;
//验证参数
validate(\app\api\validate\Manager::class)->scene('UpdatePassword')->check($_post);
//处理并返回数据
return send_http_status('', $this->model->parentEdit($_post, UID) ? 203 : 204);
}
/**
* @OA\Post (
* path="manager/passwordReset",tags={"用户管理"},summary="重置用户密码",description="根据ID重置用户密码",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema (
* required={"id","password","username"},
* @OA\Property(property="id",type="integer",format="int15",description="用户ID"),
* @OA\Property(property="password",type="string",minLength=6,maxLength=20,description="管理员密码"),
* @OA\Property(property="username",type="string",minLength=2,maxLength=20,description="管理员账号"),
* ),
* ),
* ),
* @OA\Response(
* response=200,
* description="删除数据状态",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="string",description="不返回"),
* ),
* ),
* )
* @Log [sys_name]在[sys_time] 重置了[username]的账号密码为:[password]
*/
public function passwordReset()
{
//接收参数
$_post = $this->request->only(['id', 'password', 'username']);
//验证参数
validate(\app\api\validate\Manager::class)->scene('ResetPassword')->check($_post);
//处理并返回数据
return send_http_status('', $this->model->parentEdit($_post, $_post['id']) ? 203 : 204);
}
/**
* @OA\Post (
* path="manager/delete",tags={"用户管理"},summary="删除用户数据",description="根据ID删除用户数据",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema (
* required={"id"},
* @OA\Property(property="id",type="string",description="数据ID或数据ID集合 id=1或 id=1,2,8"),
* ),
* ),
* ),
* @OA\Response(
* response=200,
* description="删除数据状态",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="string",description="不返回"),
* ),
* ),
* )
* @Log [sys_name] 在 [sys_time] 删除了管理员账号:[username]
*/
public function delete()
{
//接收参数
$ids = $this->request->post('id');
//验证参数
validate(['ids|id' => 'require|length:1,100'])->check(['ids' => $ids]);
//处理并返回数据
return send_http_status('', $this->model->parentDel($ids) ? 205 : 206);
}
/**
* @OA\Post (
* path="manager/status",tags={"用户管理"},summary="更新用户状态",description="根据ID及status更新用户状态",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema (
* required={"id","status"},
* @OA\Property(property="id",type="string",description="数据ID或数据ID集合 id=1或 id=1,2,8"),
* @OA\Property(property="status",type="integer",format="int15",description="数据状态 0禁用 1启用"),
* ),
* ),
* ),
* @OA\Response(
* response=200,
* description="删除数据状态",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="string",description="不返回"),
* ),
* ),
* )
* @Log [sys_name] 在 [sys_time] [dictionary_status]了管理员:[username], 管理员ID为:[id]
*/
public function status()
{
//接收参数
$ids = $this->request->param('id');
$status = $this->request->param('status');
//验证参数
$_rules = [
'ids|id' => 'require|length:1,100',
'status|状态值' => 'require|number|length:1',
];
validate($_rules)->check(['ids' => $ids, 'status' => $status]);
//处理并返回数据
return send_http_status('', $this->model->parentStatus($ids, $status) !== false ? 207 : 208);
}
public function getMessage(){
$type = $this->request->param('type','98');
$model = new \app\api\model\Message();
$_data = $model->getUserMessage($type);
return send_http_status($_data);
}
public function messageStatus()
{
//接收参数
$ids = $this->request->param('id');
$type = $this->request->param('type');
$model = new \app\api\model\Message();
//处理并返回数据
return send_http_status('',$model->setMessageRead($ids,$type) !== false ? 207 : 208);
}
public function messageDelete(){
//接收参数
$ids = $this->request->param('id');
$model = new \app\api\model\Message();
//处理并返回数据
return send_http_status('',$model->setMessageDelete($ids) ? 205 : 206);
}
public function setMessage(){
//获取未读系统邮件
$message = new \app\api\model\Message();
$message->setUserMessage();
return send_http_status('', 200);
}
}

256
app/api/controller/Menu.php

@ -0,0 +1,256 @@
<?php
declare (strict_types=1);
/**
* Created by 安徽云掌.
* User: 云掌.帮德
* Date: 2020/3/8 22:30
* Desc: 获取权限菜单
*/
namespace app\api\controller;
use auth\PermissAuth;
use think\App;
/**
* Menu类添加、修改等公共请求参数
* @OA\Schema (
* schema = "MenuField",
* required={"id","name","model_name"},
* @OA\Property(property="name",type="string",minLength=1,maxLength=30,mock={"mock":"@cname"},default="栏目菜单",description="权限菜单名称"),
* @OA\Property(property="parent_id",type="integer",format="int15",minLength=1,maxLength=100,default="0",description="父级ID"),
* @OA\Property(property="model_name",type="string",minLength=2,maxLength=20,mock={"mock":"@word"},default="/api/menu/index ",description="模块名/控制器/方法"),
* @OA\Property(property="path",type="string",default="/system/menu",description="权限菜单前端路由"),
* @OA\Property(property="component",type="string",default="/system/menu",description="对应前台的模板的路由地址"),
* @OA\Property(property="authority",type="string",default="sys:menu:add",description="按钮权限标识"),
* @OA\Property(property="icon",type="string",default="",description="菜单图标"),
* @OA\Property(property="color",type="string",default="",description="icon颜色"),
* @OA\Property(property="target",type="string",default="",description="是否新窗口 _target"),
* @OA\Property(property="iframe",type="integer",format="int15",default="0",description="是否为 iframe模式 0:不是 1:是"),
* @OA\Property(property="hide",type="integer",format="int15",minLength=1,maxLength=1,default="0",description="是否显示 0:显示 1:隐藏"),
* @OA\Property(property="sort",type="integer",format="int15",minLength=1,maxLength=100,default="0",description="排序"),
* @OA\Property(property="menu_type",type="integer",format="int15",minLength=1,maxLength=1,default="0",description="菜单类型 0:菜单 1:按钮"),
* @OA\Property(property="open_type",type="integer",format="int15",minLength=1,maxLength=1,default="0",description="打开方式 0:组件 1:内链 2:外链"),
* @OA\Property(property="is_dev",type="integer",format="int15",minLength=1,maxLength=1,default="0",description="1:开发者模式(即tp调试模式开启)"),
* @OA\Property(property="status",type="integer",format="int15",minLength=1,maxLength=1,default="1",description="状态:为1正常,为0禁用"),
* @OA\Property(property="condition",type="string",minLength=1,maxLength=100,default=" ",description="规则表达式,为空表示存在就验证,不为空表示按照条件验证"),
* @OA\Property(property="remarks",type="string",minLength=1,maxLength=200,default=" ",description="备注"),
* @OA\Property(property="child_list",type="string",minLength=1,maxLength=200,default=" ",description="100100 子集菜单集合"),
* ),
*/
class Menu extends Common
{
public $model = null;
public function __construct(App $app)
{
parent::__construct($app);
$this->model = new \app\api\model\Menu();
}
/**
* @OA\Get (
* path="menu/index",tags={"权限菜单"},summary="获取菜单列表",description="根据相关参数获取菜单列表",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\Parameter(name="path",in="query",description="前端权限路由",@OA\Schema (type="string")),
* @OA\Parameter(name="name",in="query",description="权限菜单名称",@OA\Schema (type="string")),
* @OA\Parameter (name="page",in="query",description="当前页码",@OA\Schema (type="integer",format="int15")),
* @OA\Parameter (name="limit",in="query",description="分页数量",@OA\Schema (type="integer",format="int15")),
* @OA\Response(
* response=200,
* description="返回权限菜单菜单数据信息",
* @OA\JsonContent(ref="#/components/schemas/MenuMsgExport"),
* ),
* )
*/
public function index()
{
//接受参数
$_get = $this->request->param();
//指定搜索参数
$this->model->search_arr = ['path', 'name'];
//验证参数
validate(\app\api\validate\Menu::class)->scene('lists')->check($_get);
$_data = $this->model->index();
//数据处理 前台处理
// $_data['data'] = get_tree($_data['data'], 0, 'children');
//返回数据
return send_http_status($_data);
}
/**
* @OA\Post (path="menu/add",tags={"权限菜单"},summary="添加权限菜单数据",description="添加后台权限菜单数据",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema(ref="#/components/schemas/MenuField"),
* ),
* ),
* @OA\Response(
* response=200,
* description="添加成功",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录总数"),
* @OA\Property(property="data", type="integer",format="int32",description="添加成功的的数据ID"),
* ),
* ),
* )
* @Log [sys_name] 在 [sys_time] 创建了权限菜单:[name]
*/
public function add()
{
//接收参数
$_post = $this->request->post();
//验证参数
validate(\app\api\validate\Menu::class)->check($_post);
//处理并返回参数
$insertId = $this->model->parentAdd($_post);
return send_http_status($insertId, $insertId ? 201 : 202);
}
/**
* @OA\Get (
* path="menu/read/id/{id}",tags={"权限菜单"},summary="获取菜单详情",description="根据ID查询菜单信息",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\Parameter(name="id",in="path",required=true,description="ID",@OA\Schema (type="integer",format="int32")),
* @OA\Response(
* response=200,
* description="返回权限菜单菜单数据信息",
* @OA\JsonContent(ref="#/components/schemas/MenuMsgExport"),
* ),
* )
*/
public function read($id = '')
{
//验证参数
validate(\app\api\validate\Menu::class)->scene('read')->check(['id' => $id]);
//返回数据
return send_http_status($this->model->parentRead($id));
}
/**
* @OA\Post (path="menu/edit/id/{id}",tags={"权限菜单"},summary="修改菜单数据",description="修改权限菜单数据",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema(ref="#/components/schemas/MenuField"),
* ),
* ),
* @OA\Response(
* response=200,
* description="修改数据状态",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="string",description="不返回"),
* ),
* ),
* )
* @Log [sys_name]在[sys_time] 修改了权限菜单[name]的数据
*/
public function edit($id = 0)
{
//接收参数
$_post = $this->request->post();
$_post['id'] = $id; //安全赋值,以免客户端没传id,修改需要id字段
//验证参数
validate(\app\api\validate\Menu::class)->scene('update')->check($_post);
//处理并返回数据
return send_http_status('', $this->model->parentEdit($_post, $id) ? 203 : 204);
}
/**
* @OA\Post (
* path="menu/delete",tags={"权限菜单"},summary="删除菜单数据",description="根据ID删除菜单数据",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema (
* required={"id"},
* @OA\Property(property="id",type="string",description="数据ID或数据ID集合 id=1或 id=1,2,8"),
* ),
* ),
* ),
* @OA\Response(
* response=200,
* description="删除数据状态",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="string",description="不返回"),
* ),
* ),
* )
* @Log [sys_name] 在 [sys_time] 删除了权限菜单:[name]
*/
public function delete()
{
//接收参数
$ids = $this->request->param('id');
//验证参数
validate(['ids|id' => 'require|length:1,100'])->check(['ids' => $ids]);
//处理并返回数据
return send_http_status('', $this->model->parentDel($ids) ? 205 : 206);
}
/**
* @OA\Post (
* path="menu/status",tags={"权限菜单"},summary="更新菜单状态",description="根据ID及status更新菜单状态",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema (
* required={"id","status"},
* @OA\Property(property="id",type="string",description="数据ID或数据ID集合 id=1或 id=1,2,8"),
* @OA\Property(property="status",type="integer",format="int15",description="数据状态 0禁用 1启用"),
* ),
* ),
* ),
* @OA\Response(
* response=200,
* description="删除数据状态",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="string",description="不返回"),
* ),
* ),
* )
* @Log [sys_name] 在 [sys_time] [dictionary_status]了权限菜单:[name]
*/
public function status()
{
//接收参数
$ids = $this->request->param('id');
$status = $this->request->param('status');
//验证参数
$_rules = [
'ids|id' => 'require|length:1,100',
'status|状态值' => 'require|number|length:1',
];
validate($_rules)->check(['ids' => $ids, 'status' => $status]);
//处理并返回数据
return send_http_status('', $this->model->parentStatus($ids, $status) !== false ? 207 : 208);
}
}

200
app/api/controller/Message.php

@ -0,0 +1,200 @@
<?php
declare (strict_types=1);
/**
* Created by 安徽云掌.
* User: 云掌.帮德
* Date: 2020/3/8 22:30
* Desc: 字典类型类
*/
namespace app\api\controller;
use think\App;
class Message extends Common
{
public $model = null;
public function __construct(App $app)
{
parent::__construct($app);
$this->model = new \app\api\model\Message();
}
public function index()
{
//接受参数
$_get = $this->request->get();
//指定搜索参数
$this->model->search_arr = ['title'];
//数据处理
$_data = $this->model->index();
//返回数据
return send_http_status($_data);
}
public function read(int $id = 0)
{
//验证参数
validate(\app\api\validate\Message::class)->scene('read')->check(['id' => $id]);
//返回数据
return send_http_status($this->model->parentRead($id));
}
/**
* @OA\Post (path="demo/add",tags={"测试案例"},summary="添加DEMO数据",description="添加后台DEMO管理数据",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema(ref="#/components/schemas/DemoField"),
* ),
* ),
* @OA\Response(
* response=200,
* description="添加成功",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="integer",format="int32",description="添加成功的的数据ID"),
* ),
* ),
* )
* @Log [sys_name] 在 [sys_time] 创建了字典类型:[dict_symbol]:[dict_name]
*/
public function add()
{
//接收参数
$_post = $this->request->post();
//验证参数
// validate(\app\api\validate\Dictionary::class)->check($_post);
//处理并返回参数
$insertId = $this->model->parentAdd($_post);
return send_http_status($insertId, $insertId ? 201 : 202);
}
/**
* @OA\Post (path="demo/edit/id/{id}",tags={"测试案例"},summary="修改DEMO数据",description="修改后台DEMO管理数据",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema(ref="#/components/schemas/DemoField"),
* ),
* ),
* @OA\Response(
* response=200,
* description="修改数据状态",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="string",description="不返回"),
* ),
* ),
* )
* @Log [sys_name]在[sys_time]修改了字典[dict_symbol]的数据
*/
public function edit(int $id = 0)
{
//接收参数
$_post = $this->request->post();
$_post['id'] = empty($_post['id']) ? $id : 0; //安全赋值,以免客户端没传id,修改需要id字段
//验证参数
// validate(\app\api\validate\Dictionary::class)->scene('update')->check($_post);
//处理并返回数据
return send_http_status('', $this->model->parentEdit($_post, $id) ? 203 : 204);
}
/**
* @OA\Post (
* path="demo/delete",tags={"测试案例"},summary="删除DEMO数据",description="根据ID删除DEMO信息",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema (
* required={"id"},
* @OA\Property(property="id",type="string",description="数据ID或数据ID集合 id=1或 id=1,2,8"),
* ),
* ),
* ),
* @OA\Response(
* response=200,
* description="删除数据状态",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="string",description="不返回"),
* ),
* ),
* )
* @Log [sys_name] 在 [sys_time] 删除了字典:[dict_symbol]:[dict_name]
*/
public function delete()
{
//接收参数
$ids = $this->request->param('id');
//验证参数
validate(['ids|id' => 'require|length:1,1000'])->check(['ids' => $ids]);
//处理并返回数据
return send_http_status('', $this->model->parentDel($ids) ? 205 : 206);
}
/**
* @OA\Post (
* path="demo/status",tags={"测试案例"},summary="更新DEMO状态",description="根据ID及status更新DEMO状态",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\RequestBody(
* @OA\MediaType(mediaType="application/json",
* @OA\Schema (
* required={"id","status"},
* @OA\Property(property="id",type="string",description="数据ID或数据ID集合 id=1或 id=1,2,8"),
* @OA\Property(property="status",type="integer",format="int15",description="数据状态 0禁用 1启用"),
* ),
* ),
* ),
* @OA\Response(
* response=200,
* description="删除数据状态",
* @OA\JsonContent(type="object",
* @OA\Property(property="code", type="integer",format="int32",description="状态码"),
* @OA\Property(property="msg", type="string",description="提示信息"),
* @OA\Property(property="count", type="integer",format="int32",description="记录数"),
* @OA\Property(property="data", type="string",description="不返回"),
* ),
* ),
* )
* @Log [sys_name] 在 [sys_time] 设置ID为[id]测试账号为:[dictionary_status]
*/
public function status()
{
//接收参数
$ids = $this->request->param('id');
$status = $this->request->param('status');
//验证参数
$_rules = [
'ids|id' => 'require|length:1,100',
'status|状态值' => 'require|number|length:1',
];
validate($_rules)->check(['ids' => $ids, 'status' => $status]);
//处理并返回数据
return send_http_status('', $this->model->parentStatus($ids, $status) !== false ? 207 : 208);
}
}

23
app/api/controller/Swagger.php

@ -0,0 +1,23 @@
<?php
declare (strict_types=1);
namespace app\api\controller;
use function OpenApi\scan;
class Swagger
{
/**
* 生成json/yamf文件
*/
public function createFile()
{
$openapi = @scan(dirname(__DIR__));
$spec = json_encode($openapi, JSON_PRETTY_PRINT);
if (file_put_contents('openapi.json', $spec)) {
echo 'http://' . \request()->server()['HTTP_HOST'] . '/openapi.json';
}
}
}

71
app/api/controller/Test.php

@ -0,0 +1,71 @@
<?php
declare (strict_types=1);
namespace app\api\controller;
use edward\captcha\facade\CaptchaApi;
use service\ActionLog;
class Test extends Common
{
/**
* 邮件发送测试
*
* @return \think\Response
*/
public function sendMail()
{
//配置smtp信息
$transport = new \Swift_SmtpTransport('smtp.exmail.qq.com', 25);
$transport->setUsername('service@huamill.com');
$transport->setPassword('Jiabaiyan1018');
//实例化mailer
$mailer = new \Swift_Mailer($transport);
//邮件内容
$message = new \Swift_Message('测试swiftmailer邮件类');
$message->setContentType('text/html');
$message->setFrom(['service@huamill.com' => 'cloud']);
$message->setTo('243993898@qq.com');
$message->setBody('这是邮件内容,收到请勿回复');
//发送邮件
$result = $mailer->send($message);
halt($result);
}
/**
* 发送短信验证码
* @param int $phone
*/
public function sendSms(string $phone = '')
{
halt(CaptchaApi::createSMS($phone));
}
public function checkSms(string $code = '', string $phone = '')
{
halt(CaptchaApi::checkSMS($code, $phone));
}
/**
* 日志类测试
* @Log [sys_name] 在 [sys_time]新增插件数据
*/
public function writeLog()
{
//手动写入日志数据
ActionLog::getInstance()->write();
}
/**
* composer require jenssegers/agent 获取系统信息,访问终端判断、系统设备等信息
*/
public function systemInfo()
{
echo 'system';
}
}

111
app/api/controller/UploadLog.php

@ -0,0 +1,111 @@
<?php
declare (strict_types=1);
namespace app\api\controller;
use app\api\model\ImageStorages;
use think\App;
/**
* 系统日志
* @package app\api\controller
*/
class UploadLog extends Common
{
public $model = null;
public function __construct(App $app)
{
parent::__construct($app);
$this->model = new \app\api\model\UploadLog();
}
/**
* @OA\Get (
* path="log/index",tags={"上传日志管理"},summary="获取上传日志列表",description="根据相关参数获取日志列表",
* @OA\Parameter(ref="#/components/parameters/token"),
* @OA\Parameter(name="username",in="query",description="管理员名称",@OA\Schema (type="string")),
* @OA\Parameter(name="model",in="query",description="操作模块",@OA\Schema (type="string")),
* @OA\Parameter (name="page",in="query",description="当前页码",@OA\Schema (type="integer",format="int15")),
* @OA\Parameter (name="limit",in="query",description="分页数量",@OA\Schema (type="integer",format="int15")),
* @OA\Response(
* response=200,
* description="返回管理员用户数据信息",
* @OA\JsonContent(ref="#/components/schemas/LogMsgExport"),
* ),
* ),
*/
public function index()
{
//接受参数
$_get = $this->request->get();
//指定搜索参数
// $this->model->search_arr = ['current'];
//数据处理
$_data = $this->model->index();
//返回数据
return send_http_status($_data);
}
public function add()
{
//接收参数
$_post = $this->request->post();
//处理并返回参数
$insertId = $this->model->parentAdd($_post);
return send_http_status($insertId, $insertId ? 201 : 202);
}
/**
* @Log [sys_name]在[sys_time] 删除了文件数据
*/
public function delete()
{
//接收参数
$ids = $this->request->param('id');
//验证参数
validate(['ids|id' => 'require|length:1,1000'])->check(['ids' => $ids]);
//处理并返回数据
return send_http_status('', $this->model->parentDel($ids) ? 205 : 206);
}
public function getSiteLists(){
//数据处理
$_data = $this->model->getLists();
//返回数据
return send_http_status($_data);
}
public function getTagLists(){
$tagLists = config('dict.sqlfields.image_storage_type');
$senddData = [];
foreach ($tagLists as $key => $val){
$item = [];
$item['title'] = $key;
$item['name'] = $val;
$senddData[] = $item;
}
return send_http_status($senddData);
}
public function getStorageImages(){
$model = new ImageStorages();
$model->search_arr = ['title'];
$_data = $model->getStorgaeImagesLists();
//返回数据
return send_http_status($_data);
}
}

96
app/api/controller/v1/Test.php

@ -0,0 +1,96 @@
<?php
declare (strict_types=1);
namespace app\api\controller\v1;
use app\api\controller\Common;
use think\facade\Console;
use think\Request;
class Test extends Common
{
/**
* 清除runtime下的file缓存
*/
public function clear()
{
Console::call('clear');
}
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index()
{
echo '加上v1版本号 一定要定制路由规则 ';
}
/**
* 显示创建资源表单页.
*
* @return \think\Response
*/
public function create()
{
//
}
/**
* 保存新建的资源
*
* @param \think\Request $request
* @return \think\Response
*/
public function save(Request $request)
{
//
}
/**
* 显示指定的资源
*
* @param int $id
* @return \think\Response
*/
public function read($id)
{
//
}
/**
* 显示编辑资源表单页.
*
* @param int $id
* @return \think\Response
*/
public function edit($id)
{
//
}
/**
* 保存更新的资源
*
* @param \think\Request $request
* @param int $id
* @return \think\Response
*/
public function update(Request $request, $id)
{
//
}
/**
* 删除指定资源
*
* @param int $id
* @return \think\Response
*/
public function delete($id)
{
//
}
}

6
app/api/middleware.php

@ -0,0 +1,6 @@
<?php
// 应用中间件定义文件
return [
//检测JwtToken中间件
\app\middleware\CheckJwtAuth::class,
];

101
app/api/model/Ad.php

@ -0,0 +1,101 @@
<?php
declare (strict_types=1);
namespace app\api\model;
use app\Request;
use think\facade\Db;
use think\Model;
/**
* @mixin think\Model
*/
class Ad extends Common
{
protected $table = 'cloud_ad';
protected $_data_table = 'ad_data';
/**
* 管理员列表数据模型
* @return array|\think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
$name = $this->request->param('name', '');
$_op = $this->where('site_id', SITE_ID); //没有默认where查询 这个一定要 否则获取不到下面的getOptions查询条件值
if ($name) {
$_op->whereLike('name', "%{$name}%");
}
$_op->order('create_time DESC');
return parent::parentLists($_op);
}
/**
* 读取后
* @param Model $model
* @return bool|void
*/
public static function onAfterRead(Model $model)
{
}
/**
* 新增前
* @param Model $model
* @return mixed|void
*/
public static function onBeforeInsert(Model $model)
{
//code
}
/**
* 新增或修改前
* @param Model $model
* @return mixed|void
*/
public static function onBeforeWrite(Model $model)
{
}
/**
* 获取广告数据
* @return array|\think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function AdData()
{
$adid = $this->request->param('adid', '');
$_op = Db::name($this->_data_table)->where('site_id', SITE_ID); //没有默认where查询 这个一定要 否则获取不到下面的getOptions查询条件值
if ($adid) {
$_op->whereLike('adid', $adid);
}
$_op->order('create_time DESC');
$data = parent::parentLists($_op);
$result = $data['data'];
//查询广告位限制的图片宽度、高度
$_ad = Db::name('ad')->field('width,height')->where('id',$adid)->find();
array_walk($result, function (&$v) use ($_ad) {
$v['create_time'] = date('Y-m-d H:i:s', $v['create_time']);
$v['start_time'] = date('Y-m-d H:i:s', $v['start_time']);
$v['end_time'] = date('Y-m-d H:i:s', $v['end_time']);
$v['thumb'] = config('dictionary.upload.cdn_img_host') . $v['thumb'];
$v['crop_thumb'] = crop_thumb($v['thumb'], (int)$_ad['width'], (int)$_ad['height']);
});
$data['data'] = $result;
return $data;
}
}

78
app/api/model/AdData.php

@ -0,0 +1,78 @@
<?php
declare (strict_types=1);
namespace app\api\model;
use app\Request;
use think\facade\Db;
use think\Model;
/**
* @mixin think\Model
*/
class AdData extends Common
{
protected $table = 'cloud_ad_data';
protected $_data_table = 'ad_data';
/**
* 管理员列表数据模型
* @return array|\think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
$name = $this->request->param('name', '');
$_op = $this->where('site_id', SITE_ID); //没有默认where查询 这个一定要 否则获取不到下面的getOptions查询条件值
if ($name) {
$_op->whereLike('name', "%{$name}%");
}
$_op->order('create_time DESC');
return parent::parentLists($_op);
}
/**
* 读取后
* @param Model $model
* @return bool|void
*/
public static function onAfterRead(Model $model)
{
if (!in_array(request()->action(), ['read','dataRead'])) {
return;
}
//成时间戳转化时间字符串
$model->setAttr('end_time', date('Y-m-d H:i:s',$model->getAttr('end_time')));
$model->setAttr('start_time', date('Y-m-d H:i:s',$model->getAttr('start_time')));
}
/**
* 新增前
* @param Model $model
* @return mixed|void
*/
public static function onBeforeInsert(Model $model)
{
// //时间字符串转化成时间戳
}
/**
* 新增或修改前
* @param Model $model
* @return mixed|void
*/
public static function onBeforeWrite(Model $model)
{
if (!in_array(request()->action(), ['add', 'edit','dataEdit','dataAdd'])) {
return;
}
//时间字符串转化成时间戳
$model->setAttr('end_time', strtotime($model->getAttr('end_time')));
$model->setAttr('start_time', strtotime($model->getAttr('start_time')));
}
}

66
app/api/model/Block.php

@ -0,0 +1,66 @@
<?php
declare (strict_types=1);
namespace app\api\model;
use app\Request;
use think\Model;
/**
* @mixin think\Model
*/
class Block extends Common
{
protected $table = 'cloud_block';
/**
* 管理员列表数据模型
* @return array|\think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
$name = $this->request->param('name', '');
$_op = $this->where('site_id', SITE_ID); //没有默认where查询 这个一定要 否则获取不到下面的getOptions查询条件值
if ($name) {
$_op->whereLike('name', "%{$name}%");
}
$_op->order('sort DESC,create_time DESC');
return parent::parentLists($_op);
}
/**
* 读取后
* @param Model $model
* @return bool|void
*/
public static function onAfterRead(Model $model)
{
}
/**
* 新增前
* @param Model $model
* @return mixed|void
*/
public static function onBeforeInsert(Model $model)
{
//code
}
/**
* 新增或修改前
* @param Model $model
* @return mixed|void
*/
public static function onBeforeWrite(Model $model)
{
}
}

88
app/api/model/Column.php

@ -0,0 +1,88 @@
<?php
declare (strict_types=1);
namespace app\api\model;
use app\Request;
use think\facade\Db;
use think\Model;
/**
* @mixin think\Model
*/
class Column extends Common
{
/**
* 管理员列表数据模型
* @return array|\think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
$username = $this->request->param('username', '');
$sex = $this->request->param('sex', '', 'intval');
$truename = $this->request->param('truename', '');
$_op = $this->where('site_id', SITE_ID); //没有默认where查询 这个一定要 否则获取不到下面的getOptions查询条件值
if ($username) {
$_op->whereLike('username', "%{$username}%");
}
$data = parent::parentLists($_op);
//获取栏目类型
$_column_type = config('dictionary.sqlfields.column_type');
$_model = Db::name('model')->column('*', 'id');
$data_tmp = $data['data'];
array_walk($data_tmp, function (&$v) use ($_model, $_column_type) {
$v['model_name'] = $_model[$v['model_id']]['name'];
$v['column_type_name'] = $_column_type[$v['type']];
});
$data['data'] = $data_tmp;
// $data = tree($data);
return $data;
}
/**
* 读取后
* @param Model $model
* @return bool|void
*/
public static function onAfterRead(Model $model)
{
$model->setAttr('open', true);
}
/**
* 新增前
* @param Model $model
* @return mixed|void
*/
public static function onBeforeInsert(Model $model)
{
//code
}
/**
* 新增或修改前
* @param Model $model
* @return mixed|void
*/
public static function onBeforeWrite(Model $model)
{
}
public static function onAfterDelete(Model $model)
{
//删除父级栏目下所有子栏目
self::destroy(function ($query) use ($model) {
$query->where('child_list', 'like', $model->getAttr('child_list') . '%');
});
parent::onAfterDelete($model);
}
}

270
app/api/model/Common.php

@ -0,0 +1,270 @@
<?php
declare (strict_types=1);
namespace app\api\model;
use service\ActionLog;
use think\App;
use think\Model;
use think\model\concern\SoftDelete;
/**
* 定义所有接口公共请求参数token【swagger ref使用】
* @OA\Parameter(
* in="header",
* name="token",
* description="用户登录返回的jwt-token值",
* required=true,
* @OA\Schema(
* type="string"
* )
* ),
*
*/
/**
* @mixin think\Model
*/
class Common extends Model
{
use SoftDelete;
protected $deleteTime = 'delete_time';
protected $readonly = ['id', 'site_id'];
public $search_arr = []; //搜索数据
/**
* Request实例
* @var \think\Request
*/
protected $request;
public function __construct(array $_data = [])
{
parent::__construct($_data);
$this->request = request();
}
/**
* 获取单条数据基类模型
* @param string $id
* @param null $_op 模型链式对象
* @return array|Model|null
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function parentRead($id = '', $_op = null)
{
if (!is_object($_op)) {
$_op = $this;
}
return $_op->where('site_id', SITE_ID)->find($id);
}
/**
* 获取数据列表基类模型
* @param null $_op 模型链式对象
* @param int $ispage 是否分页,默认分页
* @return array|\think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
protected function parentLists($_op = null, $ispage = 1,$issite=true)
{
//模型对象为空,设定默认查询对象
if($issite){
if (!is_object($_op) || empty($_op)) {
$_op = $this->where('site_id', SITE_ID); //没有默认where查询 这个一定要 否则获取不到下面的getOptions查询条件值
} else {
$_op->where('site_id', SITE_ID); //强制绑定站点参数
}
}
//公共搜索查询
if (count($this->search_arr) > 0) {
$_param = request()->param(); //搜索参数集合
$_op->where(function ($query) use ($_param) {
foreach ($this->search_arr as $k => $v) {
$search_arr = explode(':', $v);
$search_name = $search_arr[0];
$logic = $search_arr[1] ?? 'AND';
if (array_key_exists($search_name, $_param)) {
if (!empty($_param[$search_name])) {
$query->whereLike($search_name, "%{$_param[$search_name]}%", $logic);
}
}
}
});
}
//执行分页查询
$page = $this->request->param('page', config('page'));
$limit = $this->request->param('limit', config('limit'));
$count = $_op->count();
$this->listsOrder($_op); //统一排序
//无分页判断
$ispage != 1 ?: $_op->page((int)$page, (int)$limit);
$_data = [
'data' => $_op->select()->toArray(),
'page_total' => $count,
];
return $_data;
}
/**
* 数据排序
*/
private function listsOrder(&$_op)
{
if ($_op->getOptions('order')) {
return;
}
$sort = $this->request->get('sort');
$sort = in_array($sort, $this->checkAllowFields()) ? $sort : '';
$order = $this->request->get('order', 'DESC', 'strtoupper') == 'ASC' ? 'ASC' : 'DESC';
$sort_order = $sort . ' ' . $order;
if (empty($sort)) {
$sort_order = in_array('sort', $this->checkAllowFields()) ? 'sort DESC,create_time DESC' : 'create_time DESC';
}
$_op->order($sort_order);
}
/**
* 新增数据基类模型
* @param array $_param
* @return Common|Model
*/
public function parentAdd($_param = [])
{
if (empty($_param)) {
$_param = $this->request->post();
}
$_param['site_id'] = SITE_ID;
$_result = self::create($_param);
return $_result->id;
}
/**
* 修改基类模型
* @param array $_data
* @param null $_op 模型链式对象
* @param $id
* @return bool|\type
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function parentEdit($_data = [], $id = 0, $_op = null)
{
if (empty($_data)) {
$_data = $this->request->param();
}
if (!is_object($_op)) {
$_op = $this;
}
$_op = $_op->where('site_id', SITE_ID)->find($id);
if (empty($_op)) {
return send_http_status('', 101);
}
$_data['site_id'] = SITE_ID; //防止篡改站点
return $_op->save($_data);
}
/**
* 删除
* @param $id
* @param null $_op 模型链式对象
* @param false $true_delete 是否真删除 默认软删除
* @return bool|\type
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function parentDel($id, $_op = null, bool $true_delete = false)
{
if (!is_object($_op)) {
$_op = $this;
}
$ids = explode(',', $id);
$_op = $_op->where('id', 'in', $ids)->where('site_id', SITE_ID)->select();
if ($_op->isEmpty()) {
return send_http_status('', 101);
}
return self::destroy($ids, $true_delete); //TP软删除
}
/**
* 更改数据状态
* @param $id
* @param $status
* @param null $_op
* @return \type
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function parentStatus($id, $status, $_op = null)
{
if (!is_object($_op)) {
$_op = $this;
}
$ids = explode(',', $id);
$_op = $_op->where('id', 'in', $ids)->where('site_id', SITE_ID)->select();
if ($_op->isEmpty()) {
return send_http_status('', 101);
}
$_where = [
['id', 'in', $ids],
['site_id', '=', SITE_ID],
];
// $affected = self::where('id', 'in', $ids)->where('site_id', SITE_ID)->update(['status' => $status]);
$affected = self::update(['status' => $status], $_where);
return $affected;
}
public static function onAfterRead(Model $model)
{
$model->offsetUnset('delete_time');
}
public static function onBeforeWrite(Model $model)
{
//以下参数禁止新增或更改
$model->setAttr('copy_safe_id', (int)$model->getAttr('id')); //设定副本参数
$model->setAttr('copy_safe_site_id', (int)$model->getAttr('site_id')); //设定副本参数
$model->offsetUnset('id');
$model->offsetUnset('site_id');
$model->offsetUnset('delete_time');
$model->offsetUnset('update_time');
$model->offsetUnset('create_time');
}
public static function onAfterWrite(Model $model)
{
//增加创建和修改日志记录
ActionLog::getInstance()->write($model->getData(), $model->getOrigin(), $model->getLastSql());
}
public static function onAfterDelete(Model $model)
{
//增加删除日志记录
ActionLog::getInstance()->write($model->getData(), [], $model->getLastSql());
}
}

119
app/api/model/Config.php

@ -0,0 +1,119 @@
<?php
declare (strict_types=1);
namespace app\api\model;
use think\Model;
/**
* // swagger response返回数据引用
* @OA\Schema(
* schema="ConfigMsgExport",
* required={"code","msg","count","data"},
* @OA\Property(
* property="code",
* type="integer",
* format="int32",
* description="状态码"
* ),
* @OA\Property(
* property="msg",
* type="string",
* description="提示消息"
* ),
* @OA\Property(
* property="count",
* type="integer",
* format="int32",
* description="数量",
* ),
* @OA\Property(
* property="data",
* type="array",
* description="请求结果",
* @OA\Items(
* @OA\Property(
* property="id",
* type="integer",
* description="ID"
* ),
* @OA\Property(
* property="username",
* type="string",
* description="管理员名称",
* ),
* @OA\Property(
* property="truename",
* type="string",
* description="管理员真实姓名",
* ),
* )
* ),
*
* ),
*/
/**
* @mixin think\Model
*/
class Config extends Common
{
/**
* 管理员列表数据模型
* @return array|\think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
$_result = parent::parentLists('', 0);
$_result = array_column($_result['data'], 'value', 'name');
//通用逻辑
return $_result;
}
public function edit(array $_post = [])
{
//业务逻辑
if (empty($_post)) {
return false;
}
$name_arr = array_keys($_post);
$id_arr = $this->where('name', 'in', $name_arr)->where('site_id', SITE_ID)->column('id');
if (!empty($id_arr)) {
$affected = self::destroy($id_arr, true); //TP真删除
if (!$affected) {
return false;
}
}
foreach ($_post as $k => $v) {
$_temp = [
'name' => $k,
'value' => $v,
'site_id' => SITE_ID,
'create_time' => time(),
'update_time' => time(),
];
$_data[] = $_temp;
}
return $this->insertAll($_data);
}
/**
* 读取后
* @param Model $model
* @return bool|void
*/
public static function onAfterRead(Model $model)
{
//读取数据前格式化数据
if (in_array(request()->action(), ['edit', 'delete', 'status'])) {
return true;
}
//业务逻辑
}
}

137
app/api/model/Demo.php

@ -0,0 +1,137 @@
<?php
declare (strict_types=1);
namespace app\api\model;
use think\Model;
/**
* swagger response返回数据引用
* @OA\Schema(
* schema="DemoMsgExport",
* required={"code","msg","count","data"},
* @OA\Property(
* property="code",
* type="integer",
* format="int32",
* description="状态码"
* ),
* @OA\Property(
* property="msg",
* type="string",
* description="提示消息"
* ),
* @OA\Property(
* property="count",
* type="integer",
* format="int32",
* description="记录总数",
* ),
* @OA\Property(
* property="data",
* type="array",
* description="请求结果",
* @OA\Items(
* @OA\Property(
* property="id",
* type="integer",
* description="ID"
* ),
* @OA\Property(
* property="site_id",
* type="integer",
* description="站点ID"
* ),
* @OA\Property(
* property="username",
* type="string",
* description="管理员名称",
* ),
* @OA\Property(
* property="sex",
* type="integer",
* description="性别"
* ),
* @OA\Property(
* property="delete_time",
* type="integer",
* description="是否删除 null:未删除"
* ),
* @OA\Property(
* property="update_time",
* type="integer",
* description="更新时间"
* ),
* @OA\Property(
* property="create_time",
* type="integer",
* description="创建时间"
* ),
* )
* ),
*
* ),
*/
/**
* @mixin think\Model
*/
class Demo extends Common
{
protected $table = 'system_demo'; //如cloud_开头不需要
/**
* 管理员列表数据模型
* @return array|\think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
//自定义处理逻辑
// $username = $this->request->param('username', '');
// $_op = $this->whereLike('username', "{$username}%");
// return parent::parentLists($_op);
//通用逻辑
return parent::parentLists();
}
/**
* 读取后
* @param Model $model
* @return bool|void
*/
public static function onAfterRead(Model $model)
{
//读取数据前格式化数据
if (in_array(request()->action(), ['edit', 'delete', 'status'])) {
return true;
}
//业务逻辑
}
/**
* 新增或修改前
* @param Model $model
* @return mixed|void
*/
public static function onBeforeWrite(Model $model)
{
parent::onBeforeWrite($model);
//写入数据前格式化数据
if (!in_array(request()->action(), ['add', 'edit'])) {
return true;
}
//业务逻辑
// code...
//以下参数禁止新增或者修改
$model->offsetUnset('ip');
}
}

108
app/api/model/Dictionary.php

@ -0,0 +1,108 @@
<?php
declare (strict_types=1);
namespace app\api\model;
use think\Model;
/**
* @mixin think\Model
*/
class Dictionary extends Common
{
protected $table = 'system_dictionary'; //如cloud_开头不需要
/**
* 字典列表数据模型
* @return array|\think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
//自定义处理逻辑
$dict_name = $this->request->param('dict_name', '');
$_op = $this->whereLike('dict_name', "{$dict_name}%");
$dict_value = $this->request->param('dict_value', '');
$_op = $this->whereLike('dict_value', "{dict_value}%");
//自定义处理逻辑
$dict_type_id = $this->request->param('dict_type_id', '');
$_op = $this->where('dict_type_id', $dict_type_id);
//通用逻辑
return parent::parentLists($_op);
}
public function chekName($name)
{
//自定义处理逻辑
$dict_type_id = $this->request->param('dict_type_id', '');
$id = $this->request->param('id', '');
$codition = [
'dict_value' => $name,
'dict_type_id' => $dict_type_id,
];
if($id >0){
$count = $this->where($codition)->where('id','<>',$id)->count();
}else{
$count = $this->where($codition)->count();
}
return $count;
}
/**
* 读取后
* @param Model $model
* @return bool|void
*/
public static function onAfterRead(Model $model)
{
//读取数据前格式化数据
if (in_array(request()->action(), ['edit', 'delete', 'status'])) {
return true;
}
//业务逻辑
}
/**
* 新增或修改前
* @param Model $model
* @return mixed|void
*/
public static function onBeforeWrite(Model $model)
{
parent::onBeforeWrite($model);
//写入数据前格式化数据
if (!in_array(request()->action(), ['add', 'edit'])) {
return true;
}
//业务逻辑
// code...
}
public static function onAfterDelete(Model $model)
{
parent::onAfterDelete($model); // TODO: Change the autogenerated stub
$dic = new DictionaryType();
$dic->exportDictToConfig();
}
public static function onAfterWrite(Model $model)
{
parent::onAfterWrite($model); // TODO: Change the autogenerated stub
$dic = new DictionaryType();
$dic->exportDictToConfig();
}
}

119
app/api/model/DictionaryType.php

@ -0,0 +1,119 @@
<?php
declare (strict_types=1);
namespace app\api\model;
use think\App;
use think\Env;
use think\Model;
use think\route\Rule;
/**
* @mixin think\Model
*/
class DictionaryType extends Common
{
protected $table = 'system_dictionary_type'; //如cloud_开头不需要
/**
* 字典列表数据模型
* @return array|\think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
//自定义处理逻辑
// $username = $this->request->param('username', '');
// $_op = $this->whereLike('username', "{$username}%");
//通用逻辑
return parent::parentLists();
}
/**
* 读取后
* @param Model $model
* @return bool|void
*/
public static function onAfterRead(Model $model)
{
//读取数据前格式化数据
if (in_array(request()->action(), ['edit', 'delete', 'status'])) {
return true;
}
//业务逻辑
}
/**
* 新增或修改前
* @param Model $model
* @return mixed|void
*/
public static function onBeforeWrite(Model $model)
{
parent::onBeforeWrite($model);
//写入数据前格式化数据
if (!in_array(request()->action(), ['add', 'edit'])) {
return true;
}
//业务逻辑
// code...
}
public static function onAfterDelete(Model $model)
{
parent::onAfterDelete($model); // TODO: Change the autogenerated stub
//删除字典类型后 下属的字典值全部删除
$dict_type_id = $model->getAttr('id');
$diction = new Dictionary();
$diction->destroy(['dict_type_id'=>$dict_type_id]);
$model->exportDictToConfig();
}
public static function onAfterWrite(Model $model)
{
parent::onAfterWrite($model); // TODO: Change the autogenerated stub
$model->exportDictToConfig();
}
public function exportDictToConfig(){
$dict_datas = $this->field('a.dict_symbol,b.dict_name,b.dict_value')->alias('a')
->join(['system_dictionary'=>'b'],'a.id=b.dict_type_id','left')
->where('b.delete_time','null')
->select()
;
$datas = [];
foreach ($dict_datas as $item){
$datas[$item['dict_symbol']][$item['dict_value']] = $item['dict_name'];
}
$path = \think\facade\App::getConfigPath().'dict.php';
$ditc_text = "
<?php
/**
* 数据库字典表数据
*/
return [
'sqlfields' =>
".var_export($datas,true)."
,
];
";
if (fopen($path,'w')){
file_put_contents($path,$ditc_text);
}
}
}

46
app/api/model/ImageStorages.php

@ -0,0 +1,46 @@
<?php
declare (strict_types=1);
namespace app\api\model;
use think\Model;
/**
* @mixin think\Model
*/
class ImageStorages extends Common
{
public $table = 'system_image_storages';
public function index(){
$type = $this->request->param('type', 0);
$_op = $this->field('*');
if($type){
$_op = $this->where('type',$type);
}
//执行通用查询
return parent::parentLists($_op);
}
/**
* 读取后
* @param Model $model
* @return bool|void
*/
public static function onAfterRead(Model $model)
{
if (in_array(request()->action(), ['edit', 'delete', 'status'])) {
return true;
}
$typeArr = config('dict.sqlfields.image_storage_type');
$model->setAttr('type_str',$typeArr[$model->getAttr('type')]);
}
}

188
app/api/model/Log.php

@ -0,0 +1,188 @@
<?php
declare (strict_types=1);
namespace app\api\model;
use app\Request;
use auth\PermissAuth;
use think\Model;
/**
* swagger response返回数据引用
* @OA\Schema(
* schema="LogMsgExport",
* required={"code","msg","count","data"},
* @OA\Property(
* property="code",
* type="integer",
* format="int32",
* description="状态码"
* ),
* @OA\Property(
* property="msg",
* type="string",
* description="提示消息"
* ),
* @OA\Property(
* property="count",
* type="integer",
* format="int32",
* description="记录总数",
* ),
* @OA\Property(
* property="data",
* type="array",
* description="请求结果",
* @OA\Items(
* @OA\Property(
* property="id",
* type="integer",
* description="ID"
* ),
* @OA\Property(
* property="site_id",
* type="integer",
* description="站点ID"
* ),
* @OA\Property(
* property="user_id",
* type="integer",
* description="管理员ID",
* ),
* @OA\Property(
* property="username",
* type="string",
* description="管理员用户名",
* ),
* @OA\Property(
* property="action_ip",
* type="string",
* description="执行行为者ip"
* ),
* @OA\Property(
* property="model",
* type="string",
* description="操作模块"
* ),
* @OA\Property(
* property="request_param",
* type="string",
* description="请求参数",
* ),
* @OA\Property(
* property="url",
* type="string",
* description="触发行为完整的url",
* ),
* @OA\Property(
* property="request_method",
* type="string",
* description="请求方式",
* ),
* @OA\Property(
* property="spend_time",
* type="float",
* description="耗时几秒",
* ),
* @OA\Property(
* property="record_id",
* type="integer",
* description="触发行为的数据id",
* ),
* @OA\Property(
* property="remark",
* type="string",
* description="日志备注"
* ),
* @OA\Property(
* property="data",
* type="string",
* description="修改后数据集合"
* ),
* @OA\Property(
* property="origin",
* type="string",
* description="修改前源数据"
* ),
* @OA\Property(
* property="sql",
* type="string",
* description="执行的sql记录"
* ),
* @OA\Property(
* property="status",
* type="integer",
* description="状态 0:禁用 1:启用"
* ),
* @OA\Property(
* property="client_os",
* type="string",
* description="客户端系统类型"
* ),
* @OA\Property(
* property="client_browser",
* type="string",
* description="客户端浏览器类型"
* ),
* @OA\Property(
* property="client_device",
* type="string",
* description="客户端设备型号,如 phone x 由api传过来"
* ),
* @OA\Property(
* property="delete_time",
* type="integer",
* description="是否删除 null:未删除"
* ),
* @OA\Property(
* property="update_time",
* type="integer",
* description="更新时间"
* ),
* @OA\Property(
* property="create_time",
* type="integer",
* description="创建时间"
* ),
* )
* ),
*
* ),
*/
class Log extends Common
{
public $table = 'system_action_log';
/**
* 管理员列表数据模型
* @return array|\think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
$start_time = $this->request->param('create_time_start', '');
$end_time = $this->request->param('create_time_end', '');
if ($start_time && $end_time) {
$_op = $this->whereTime('create_time', '>=', strtotime($start_time));
$_op->whereTime('create_time', '<=', strtotime('+1 day', strtotime($end_time)));
}
return parent::parentLists(!empty($_op) ? $_op : '');
}
/**
* 读取后
* @param Model $model
* @return bool|void
*/
public static function onAfterRead(Model $model)
{
if (in_array(request()->action(), ['edit', 'delete', 'status'])) {
return true;
}
$model->offsetSet('action_ip', long2ip((int)$model->getAttr('action_ip')));
}
}

289
app/api/model/Manager.php

@ -0,0 +1,289 @@
<?php
declare (strict_types=1);
namespace app\api\model;
use auth\PermissAuth;
use think\Model;
/**
* swagger response返回数据引用
* @OA\Schema(
* schema="ManagerMsgExport",
* required={"code","msg","count","data"},
* @OA\Property(
* property="code",
* type="integer",
* format="int32",
* description="状态码"
* ),
* @OA\Property(
* property="msg",
* type="string",
* description="提示消息"
* ),
* @OA\Property(
* property="count",
* type="integer",
* format="int32",
* description="记录总数",
* ),
* @OA\Property(
* property="data",
* type="array",
* description="请求结果",
* @OA\Items(
* @OA\Property(
* property="id",
* type="integer",
* description="ID"
* ),
* @OA\Property(
* property="site_id",
* type="integer",
* description="站点ID"
* ),
* @OA\Property(
* property="username",
* type="string",
* description="管理员名称",
* ),
* @OA\Property(
* property="truename",
* type="string",
* description="管理员真实姓名",
* ),
* @OA\Property(
* property="sex",
* type="integer",
* description="性别"
* ),
* @OA\Property(
* property="phone",
* type="integer",
* description="手机号"
* ),
* @OA\Property(
* property="email",
* type="string",
* description="邮箱",
* ),
* @OA\Property(
* property="status",
* type="integer",
* description="状态",
* ),
* @OA\Property(
* property="ip",
* type="integer",
* description="ip",
* ),
* @OA\Property(
* property="avatar",
* type="string",
* description="头像地址",
* ),
* @OA\Property(
* property="introduction",
* type="string",
* description="用户简介",
* ),
* @OA\Property(
* property="delete_time",
* type="integer",
* description="是否删除 null:未删除"
* ),
* @OA\Property(
* property="login_time",
* type="integer",
* description="最后登录时间"
* ),
* @OA\Property(
* property="update_time",
* type="integer",
* description="更新时间"
* ),
* @OA\Property(
* property="create_time",
* type="integer",
* description="创建时间"
* ),
* )
* ),
*
* ),
*/
/**
* @mixin think\Model
*/
class Manager extends Common
{
protected $table = 'system_user';
/**
* @return array|\think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
//执行通用查询
return parent::parentLists();
}
/**
* 登录验证
* @param array $_post
* @return array|\type
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function checkLogin($_post = [])
{
//站点域名检测
$site_id = (int)(new Site())->checkSite();
$_data = self::where('username', $_post['username'])->where('site_id', $site_id)->find();
if (empty($_data)) {
return send_http_status('', 40502);
}
if ($_data['status'] != 1) {
return send_http_status('', 40503);
}
if (!password_verify($_post['password'], $_data['password'])) {
return send_http_status('', 40504);
}
//登录成功写入登录信息
$this->setLoginIp($_data['id'], $site_id);
return $_data->hidden(['password'])->toArray();
}
/**
* 用户最后登录 IP
*/
private function setLoginIp(int $user_id = 0, int $site_id = 0)
{
$_data = [
'ip' => ip2long(request()->ip()),
'login_time' => time(),
];
$_op = $this->where('site_id', $site_id)->where('id', $user_id);
return $_op->save($_data);
}
/**
* 读取后
* @param Model $model
* @return bool|void
*/
public static function onAfterRead(Model $model)
{
if (in_array(request()->action(), ['edit', 'delete', 'status'])) {
return true;
}
$model->hidden(['password']);
$model->offsetSet('ip', long2ip((int)$model->getAttr('ip')));
$model->offsetSet('sexname', config('dictionary.sqlfields.sex')[$model->getAttr('sex')]);
//用户权限
$model->offsetSet('authorities', PermissAuth::getInstance()->getAuthList($model->getAttr('id'), 1, true));
//用户角色
$_roles = PermissAuth::getInstance()->getUserGroups($model->getAttr('id'));
$model->offsetSet('roles', $_roles);
$model->offsetSet('role_ids', implode(',', array_column($_roles, 'id')));
//省市区代码转换
$model->setAttr('province_city', [$model->getAttr('province'), $model->getAttr('city'), $model->getAttr('area')]);
}
/**
* 新增前
* @param Model $model
* @return mixed|void
*/
public static function onBeforeInsert(Model $model)
{
if (!in_array(request()->action(), ['add'])) {
return true;
}
//密码加密
$salt_password = password_hash($model->getAttr('password'), PASSWORD_DEFAULT);
$model->setAttr('password', $salt_password);
}
/**
* 修改前
* @param Model $model
* @return mixed|void
*/
public static function onBeforeUpdate(Model $model)
{
//禁止修改用户名
$model->offsetUnset('username');
$action = request()->action();
if (!in_array($action, ['edit', 'passwordEdit', 'passwordReset', 'editPersional'])) {
return true;
}
//密码修改验证逻辑
if ($action == 'passwordEdit') {
if (!password_verify($model->getData('old_password'), $model->getOrigin('password'))) {
return send_http_status('', 40504);
}
}
//密码加密
if ($action == 'passwordEdit' || $action == 'passwordReset') {
$salt_password = password_hash($model->getData('password'), PASSWORD_DEFAULT);
$model->setAttr('password', $salt_password);
}
//省市区代码拆分
$city_arr = $model->getAttr('province_city');
if (!empty($city_arr)) {
$model->setAttr('province', $city_arr[0]);
$model->setAttr('city', $city_arr[1]);
$model->setAttr('area', $city_arr[2]);
}
}
/**
* 新增前、修改前 同时
* @param Model $model
* @return mixed|void
*/
public static function onBeforeWrite(Model $model)
{
parent::onBeforeWrite($model);
if (!in_array(request()->action(), ['add', 'edit'])) {
return true;
}
//以下参数禁止新增或更改
$model->offsetUnset('ip');
}
public static function onAfterWrite(Model $model)
{
parent::onAfterWrite($model);
if (!in_array(request()->action(), ['add', 'edit'])) {
return true;
}
//写入用户权限
$id = $model->getAttr('id') ?? $model->getAttr('copy_safe_id');
PermissAuth::getInstance()->addUserGroupAccess((int)$id, $model->getAttr('role_ids'));
}
}

226
app/api/model/Menu.php

@ -0,0 +1,226 @@
<?php
declare (strict_types=1);
namespace app\api\model;
use think\Model;
/**
* @mixin think\Model
*/
class Menu extends Common
{
public $table = 'system_auth_rule';
/**
* 列表数据模型
* @return array|\think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
$_op = config('app.app_debug') ?: $_op = $this->where('is_dev', 0); //开发者模式
return parent::parentLists($_op, 0);
}
/**
* 新增或修改前
* @param Model $model
* @return mixed|void
*/
public static function onBeforeWrite(Model $model)
{
//设定child_list
if (empty($model->getAttr('parent_id'))) {
//parent_id = 0 一级栏目填充
$child_list = self::where('parent_id', 0)->max('child_list');
$child_list = !empty($child_list) ? (int)$child_list + 1 : 100; //如果不存在设置默认值 100起始
$model->setAttr('child_list', $child_list);
} else {
//子栏目填充
$child_list = self::where('parent_id', $model->getAttr('parent_id'))->max('child_list'); //同级最大
$parent_child_list = self::where('id', $model->getAttr('parent_id'))->value('child_list'); //父级初始
$child_list = !empty($child_list) ? (int)$child_list + 1 : $parent_child_list . '100';
$model->setAttr('child_list', $child_list);
}
parent::onBeforeWrite($model);
}
public static function onAfterDelete(Model $model)
{
//删除父级栏目下所有子栏目
if ($model->getAttr('child_list')) {
self::where('child_list', 'like', $model->getAttr('child_list') . '%')->useSoftDelete('delete_time', time())->delete();
}
parent::onAfterDelete($model);
}
/**
* swagger response返回数据引用
* @OA\Schema(
* schema="MenuMsgExport",
* required={"code","msg","count","data"},
* @OA\Property(
* property="code",
* type="integer",
* format="int32",
* description="状态码"
* ),
* @OA\Property(
* property="msg",
* type="string",
* description="提示消息"
* ),
* @OA\Property(
* property="count",
* type="integer",
* format="int32",
* description="记录总数",
* ),
* @OA\Property(
* property="data",
* type="array",
* description="请求结果",
* @OA\Items(
* @OA\Property(
* property="id",
* type="integer",
* description="菜单ID"
* ),
* @OA\Property(
* property="site_id",
* type="integer",
* description="站点ID"
* ),
* @OA\Property(
* property="name",
* type="string",
* description="菜单名称",
* ),
* @OA\Property(
* property="parent_id",
* type="integer",
* description="父级ID",
* ),
* @OA\Property(
* property="model_name",
* type="string",
* description="模块名/控制器/方法"
* ),
* @OA\Property(
* property="path",
* type="string",
* description="对应前台的模板的路由地址"
* ),
* @OA\Property(
* property="component",
* type="string",
* description="前台对应的组件路径",
* ),
* @OA\Property(
* property="authority",
* type="string",
* description="按钮权限标识",
* ),
* @OA\Property(
* property="icon",
* type="string",
* description="菜单图标",
* ),
* @OA\Property(
* property="color",
* type="string",
* description="icon颜色",
* ),
* @OA\Property(
* property="target",
* type="string",
* description="是否新窗口 _target/_self",
* ),
* @OA\Property(
* property="iframe",
* type="integer",
* description="是否为 iframe模式 0:不是 1:是",
* ),
* @OA\Property(
* property="hide",
* type="integer",
* description="是否显示 0:显示 1:隐藏",
* ),
* @OA\Property(
* property="type",
* type="integer",
* description="在think_auth_rule 表中定义一条规则时,如果type为1, condition字段就可以定义规则表达式。 如定义{score}>5 and {score}<100 表示用户的分数在5-100之间时这条规则才会通过",
* ),
* @OA\Property(
* property="sort",
* type="integer",
* description="排序",
* ),
* @OA\Property(
* property="menu_type",
* type="integer",
* description="菜单类型 0:菜单 1:按钮",
* ),
* @OA\Property(
* property="open_type",
* type="integer",
* description="打开方式 0:组件 1:内链 2:外链",
* ),
* @OA\Property(
* property="is_dev",
* type="integer",
* description="1:开发者模式(即tp调试模式开启)",
* ),
* @OA\Property(
* property="status",
* type="integer",
* description="状态:为1正常,为0禁用",
* ),
* @OA\Property(
* property="condition",
* type="string",
* description="规则表达式,为空表示存在就验证,不为空表示按照条件验证",
* ),
* @OA\Property(
* property="remarks",
* type="string",
* description="备注",
* ),
* @OA\Property(
* property="child_list",
* type="string",
* description="100100 子集菜单集合",
* ),
* @OA\Property(
* property="children",
* type="object",
* description="子集菜单对象",
* ),
* @OA\Property(
* property="delete_time",
* type="integer",
* description="是否删除 null:未删除"
* ),
* @OA\Property(
* property="update_time",
* type="integer",
* description="更新时间"
* ),
* @OA\Property(
* property="create_time",
* type="integer",
* description="创建时间"
* ),
* )
* ),
*
* ),
*/
}

248
app/api/model/Message.php

@ -0,0 +1,248 @@
<?php
declare (strict_types=1);
namespace app\api\model;
use app\index\model\User;
use think\Db;
use think\Model;
/**
* @mixin think\Model
*/
class Message extends Common
{
protected $table = 'system_message'; //如cloud_开头不需要
/**
* 字典列表数据模型
* @return array|\think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
//自定义处理逻辑
$title = $this->request->param('title', '');
$_op = $this->where('is_init',1);
//通用逻辑
return parent::parentLists($_op);
}
public function getUserMessage($type){
$_op = $this->where('receve_id',UID);
if($type == 99){
//获取未读系统消息总数
$gg_count = $this->where('receve_id',UID)->where('type',1)->where('read_status',0)->count();
//获取未读私信消息总数
$sx_count = $this->where('receve_id',UID)->where('type',0)->where('read_status',0)->count();
//获取通知类型最新5条消息
$gg_list = $this->where('receve_id',UID)->where('type',1)->where('read_status',0)->order('create_time desc,id desc')->limit(5)->select()->toArray();
//获取
$sx_list = $this->where('receve_id',UID)->where('type',0)->where('read_status',0)->order('create_time desc,id desc')->limit(5)->select()->toArray();
$reData = [];
$reData['gg']['count'] = $gg_count;
$reData['gg']['list'] = $gg_list;
$reData['sx']['count'] = $sx_count;
$reData['sx']['list'] = $sx_list;
return $reData;
}else if($type != 98){
$_op->where('type',$type);
}
$_op->order('read_status asc,create_time desc');
return parent::parentLists($_op);
}
/**
* 读取后
* @param Model $model
* @return bool|void
*/
public static function onAfterRead(Model $model)
{
//读取数据前格式化数据
if (in_array(request()->action(), ['edit', 'delete', 'status'])) {
return true;
}
$content_id = $model->getAttr('content_id');
$receve_id = $model->getAttr('receve_id');
$send_id = $model->getAttr('send_id');
if($content_id){
$c_model = new MessageContent();
$contents = $c_model->find($content_id);
$model->setAttr('title',$contents['title']);
$model->setAttr('content',$contents['content']);
$model->setAttr('pub_time',$contents['create_time']);
}
$u_model = new Manager();
if($receve_id>0){
$receve_user = $u_model->find($receve_id)->toArray();
if($receve_user){
$model->setAttr('receve_user_str',$receve_user['truename']);
}else{
$model->setAttr('receve_user_str','');
}
}else{
$model->setAttr('receve_user_str','所有人');
}
if($send_id>0){
$receve_user = $u_model->find($send_id)->toArray();
if($receve_user){
$model->setAttr('send_user_str',$receve_user['truename']);
$model->setAttr('avatar_str',$receve_user['avatar']);
}else{
$model->setAttr('send_user_str','');
}
}else{
$model->setAttr('send_user_str','');
}
// $model->setAttr('create_time_str',date('Y-m-d H:i:s',$model->getAttr('create_time')));
$model->setAttr('read_status_str',$model->getAttr('create_time')==1?'已读':'未读');
//业务逻辑
}
/**
* 新增或修改前
* @param Model $model
* @return mixed|void
*/
public static function onBeforeWrite(Model $model)
{
parent::onBeforeWrite($model);
//写入数据前格式化数据
if (!in_array(request()->action(), ['add', 'edit'])) {
return true;
}
$title = $model->getAttr('title');
$content = $model->getAttr('content');
$message_content = new MessageContent();
$ms_content['title'] = $title;
$ms_content['content'] = $content;
if(request()->action() == 'add'){
if($title && $content){
$content_id = $message_content->parentAdd($ms_content);
$model->setAttr('content_id',$content_id);
}
}else{
$c_id = $model->getAttr('content_id');
if($title && $content){
$message_content->where('id',$c_id)->save($ms_content);
}
}
$receve_id = $model->getAttr('receve_id');
$type = $receve_id<0?1:0;
$model->setAttr('send_id',UID);
$model->setAttr('type',$type);
$model->hidden(['title','content']);
//业务逻辑
// code...
}
public static function onAfterDelete(Model $model)
{
parent::onAfterDelete($model); // TODO: Change the autogenerated stub
}
public static function onAfterWrite(Model $model)
{
parent::onAfterWrite($model); // TODO: Change the autogenerated stub
}
/*
* 查看用户是否有待插入的公告
* */
public function setUserMessage($uid=0,$site_id=0){
if(!$uid){
$uid = UID;
}
if(!$site_id){
$site_id = SITE_ID;
}
//获取用户最近一份公告的时间
$last_gg = $this->withTrashed()->where('receve_id',$uid)->where('type',1)->order('create_time desc')->find();
if($last_gg){
$last_gg = $last_gg->toArray();
$start_time = strtotime($last_gg['create_time']);
}
//查询所有该用户没有的公告
$no_ggs = $this->where('site_id','in',[1,$site_id])->where('type',1)->where('create_time','>',$start_time)->order('create_time asc')->select()->toArray();
//var_dump($no_ggs);die;
foreach ($no_ggs as $item){
$model = new Message();
$gg_item = [];
$gg_item['send_id'] = $item['send_id'];
$gg_item['site_id'] = $site_id;
$gg_item['receve_id'] = $uid;
$gg_item['content_id'] = $item['content_id'];
$gg_item['is_init'] = 0;
$gg_item['type'] = 1;
$model->save($gg_item);
}
return true;
}
public function setMessageRead($ids,$type){
$_where = [
['site_id', '=', SITE_ID],
['receve_id','=',UID]
];
if($ids == -1){
if($type==0 || $type==1){
$_where[] = ['type','=',$type];
}
}else{
$ids = explode(',', $ids);
$_where[] = ['id', 'in', $ids];
}
$affected = self::update(['read_status' => 1], $_where);
return $affected;
}
public function setMessageDelete($ids){
$ids = explode(',', $ids);
if($ids){
$_op = $this->where('id', 'in', $ids)->where('receve_id',UID)->where('site_id', SITE_ID)->select();
if ($_op->isEmpty()) {
return send_http_status('', 101);
}
return self::destroy($ids); //TP软删除
}else{
return false;
}
}
}

79
app/api/model/MessageContent.php

@ -0,0 +1,79 @@
<?php
declare (strict_types=1);
namespace app\api\model;
use think\Model;
/**
* @mixin think\Model
*/
class MessageContent extends Common
{
protected $table = 'system_message_content'; //如cloud_开头不需要
/**
* 字典列表数据模型
* @return array|\think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
//自定义处理逻辑
$dict_name = $this->request->param('title', '');
$_op = $this->whereLike('title', "{$dict_name}%");
//通用逻辑
return parent::parentLists($_op);
}
/**
* 读取后
* @param Model $model
* @return bool|void
*/
public static function onAfterRead(Model $model)
{
//读取数据前格式化数据
if (in_array(request()->action(), ['edit', 'delete', 'status'])) {
return true;
}
//业务逻辑
}
/**
* 新增或修改前
* @param Model $model
* @return mixed|void
*/
public static function onBeforeWrite(Model $model)
{
parent::onBeforeWrite($model);
//写入数据前格式化数据
if (!in_array(request()->action(), ['add', 'edit'])) {
return true;
}
//业务逻辑
// code...
}
public static function onAfterDelete(Model $model)
{
parent::onAfterDelete($model); // TODO: Change the autogenerated stub
}
public static function onAfterWrite(Model $model)
{
parent::onAfterWrite($model); // TODO: Change the autogenerated stub
}
}

31
app/api/model/Site.php

@ -0,0 +1,31 @@
<?php
declare (strict_types=1);
namespace app\api\model;
/**
* @mixin think\Model
*/
class Site extends Common
{
/**
* 根据域名读取站点信息
* @return array|\think\Model|null
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function checkSite()
{
$_op = $this->whereFindInSet('host', $this->request->host());
$_op->where('start_time', '<=', time());
$_op->where('end_time', '>=', time());
$_data = $_op->find();
if (empty($_data)) {
return send_http_status('', 102);
}
return $_data->id;
}
}

72
app/api/model/Token.php

@ -0,0 +1,72 @@
<?php
declare (strict_types=1);
namespace app\api\model;
use auth\JwtAuth;
use auth\PermissAuth;
/**
* @mixin think\Model
*/
class Token extends Common
{
/**
* 登录
* @param array $data
* @return Common|\think\Model|void
*/
public function add($data = [])
{
$this->token = $data['token'];
$this->refresh_token = $data['refresh_token'];
$this->user_id = $data['user_id'];
$this->start_time = time();
$this->site_id = $data['site_id'];
$this->end_time = time() + config('jwtauth.web.expire_time_refresh');
$this->save();
}
/**
* 返回刷新token
* @param $refresh_token
* @return array|void
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function refreshToken($refresh_token)
{
$time = time();
$_op = self::where('refresh_token', $refresh_token);
$_op->where('start_time', '<', $time)->where('end_time', '>', $time);
$token_data = $_op->field('user_id,site_id')->find();
if (!empty($token_data)) {
/**
* 登录用户ID
*/
defined('UID') ?: define('UID', $token_data->getData('user_id'));
/**
* 站点ID
*/
defined('SITE_ID') ?: define('SITE_ID', $token_data->getData('site_id'));
// //查询用户信息
// $loginUser = (new Manager())->parentRead(UID)->toArray();
//发送JWT签证密钥
$token_data->id = $token_data->user_id;
$token_obj = (JwtAuth::getInstance())->setToken($token_data);
$token = $token_obj->getToken();
$_data = [
'token' => $token,
'refresh_token' => $refresh_token, //返回refresh_token本身不延期
'expire' => config('jwtauth.web.expire_time'),
// 'refresh_token' => $token_obj->createRefreshToken($this),
];
return $_data;
}
return;
}
}

164
app/api/model/UploadLog.php

@ -0,0 +1,164 @@
<?php
declare (strict_types=1);
namespace app\api\model;
use think\Model;
/**
* @mixin think\Model
*/
class UploadLog extends Common
{
public $table = 'system_upload_log';
/**
* 上传日志数据模型
* @return array|\think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
$current = $this->request->param('current', '/');
$direct = $this->request->param('direct', 0);
$dic_arr = [
'host',
'y',
'date',
// 'd',
'url',
];
$current_arr = explode('/',$current);
if($current == '/' || $current == ''){
$current_arr = [
'/'
];
}
$current_arr[0] = '/';
//向下层取数据
$field_name = $dic_arr[count($current_arr)-1];
if($field_name == 'url'){
$field_str = $field_name.',name,type,size ,0 as isDirectory,update_time,id';
}else{
$field_str = $field_name.' as name ,1 as isDirectory';
}
$conition = [];
$current_arr_1 = $current_arr;
if(count($current_arr_1)>1){
unset($current_arr_1[count($current_arr_1)-1]);
$current_arr_1[0] = '';
}
$pre_current = implode('/',$current_arr_1);
$_op = $this->field($field_str);
//获取该id下的所有的域名
$siteModel = new Site();
$hosts_str = $siteModel->where('id',SITE_ID)->find();
$host_arr = [];
if($current == '' || $current == '/'){
if($hosts_str['host']){
$host_arr = explode(',',$hosts_str['host']);
}
if(count($host_arr)==0){
$host_arr[] = $_SERVER['host'];
}
$_op->whereIn('host',$host_arr);
}else{
$conition['host'] = $current_arr[1];
}
//年
if(isset($current_arr[2]) && $current_arr[2]!=''){
$conition['Y'] = $current_arr[2];
}
// //月
// if(isset($current_arr[3]) &&$current_arr[3]!='' ){
// $conition['m'] = $current_arr[3];
// }
// //日
// if(isset($current_arr[4]) && $current_arr[4]!=''){
// $conition['d'] = $current_arr[4];
// }
//日期
if(isset($current_arr[3]) && $current_arr[3]!=''){
$conition['date'] = $current_arr[3];
}
$_op->distinct(true);
$_op->where($conition);
$data = parent::parentLists(!empty($_op) ? $_op : '',1,0);
$count = $this->field($field_name)->where($conition)->group($field_name)->count();
$data['page_total'] = $count;
$returnData = [];
// $data['current'] = $current;
// $data['pre_current'] = $pre_current;
// $returnData['data'] = $data;
// $returnData['page_total'] = $data['page_total'];
return $data;
}
public function getLists(){
//执行通用查询
return parent::parentLists();
}
public function getStorgaeImagesLists(){
$type = $this->request->param('type', 0);
$_op = $this;
if($type){
$_op->where('type',$type);
}
//执行通用查询
return parent::parentLists();
}
/**
* 读取后
* @param Model $model
* @return bool|void
*/
public static function onAfterRead(Model $model)
{
if (in_array(request()->action(), ['edit', 'delete', 'status'])) {
return true;
}
$model->offsetSet('action_ip', long2ip((int)$model->getAttr('action_ip')));
}
/**
* 新增前
* @param Model $model
* @return mixed|void
*/
public static function onBeforeInsert(Model $model)
{
if (!in_array(request()->action(), ['add'])) {
return true;
}
//密码加密
$m = $model->getAttr('m');
$d = $model->getAttr('d');
$model->setAttr('date', $m.$d);
}
}

24
app/api/route/app.php

@ -0,0 +1,24 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
use think\facade\Route;
//Route::rule(':ver/login', 'api/v1.Login/login')->allowCrossDomain();
//Route::rule(':ver/refreshToken', 'api/v1.Login/refreshToken');
//Route::rule(':ver/getManager/:id', 'api/v1.Manager/read');
//Route::rule(':ver/getUser', 'api/v1.Manager/index')->allowCrossDomain(['Access-Control-Allow-Headers'=>'token']);
//Route::rule(':ver/updateManager/[:id]', 'api/:ver.Manager/edit');
//Route::rule(':ver/addManager', 'api/:ver.Manager/create');
//Route::rule(':ver/delManager', 'api/:ver.Manager/delete');
//Route::rule(':ver/index', 'api/v1.Index/index');
//Route::rule('getManager', 'api/Manager/index');
Route::get('manager/int <id>', 'api/Manager/read');
Route::rule(':ver/test', 'api/:ver.Test/index'); //测试多层级api

58
app/api/validate/Ad.php

@ -0,0 +1,58 @@
<?php
declare (strict_types=1);
namespace app\api\validate;
use think\facade\Db;
use think\Validate;
class Ad extends Validate
{
/**
* 定义验证规则
* 格式:'字段名' => ['规则1','规则2'...]
*
* @var array
*/
protected $rule = [
'id' => 'number|length:1,10',
'name|广告名称' => "require|length:1,50",
];
/**
* 定义错误信息
* 格式:'字段名.规则名' => '错误信息'
*
* @var array
*/
protected $message = [
'name.require' => '请输入广告位名称',
'name.length' => '广告位名称必需在1~50位之间',
];
/**
* 验证场景规则
* @var array
*/
protected $scene = [
'read' => ['id'],
];
/**
* 修改场景验证
* @return Manager
*/
public function sceneUpdate()
{
return $this->remove('name', 'require');
}
/**
* 自定义查询场景验证 可灵活设置验证字段
* @return Manager
*/
public function sceneLists()
{
}
}

68
app/api/validate/AdData.php

@ -0,0 +1,68 @@
<?php
declare (strict_types=1);
namespace app\api\validate;
use think\facade\Db;
use think\Validate;
class AdData extends Validate
{
/**
* 定义验证规则
* 格式:'字段名' => ['规则1','规则2'...]
*
* @var array
*/
protected $rule = [
'id' => 'number|length:1,10',
'adid' => "require|number|length:1,50",
'link' => 'url',
'sort' => 'number',
'start_time' => 'require|dateFormat:Y-m-d H:i:s',
'end_time' => 'require|dateFormat:Y-m-d H:i:s|gt:start_time',
];
/**
* 定义错误信息
* 格式:'字段名.规则名' => '错误信息'
*
* @var array
*/
protected $message = [
'adid.require' => '请输入广告位ID',
'adid.number' => '广告位ID必须是数字',
'adid.length' => '广告位ID需在1~50位之间',
'start_time.dateFormat' => '开始时间格式不正确',
'end_time.dateFormat' => '结束时间格式不正确',
'end_time.gt' => '结束时间必须大于开始时间',
'end_time.require' => '结束时间不能为空',
'start_time.require' => '结束时间不能为空',
];
/**
* 验证场景规则
* @var array
*/
protected $scene = [
'read' => ['id'],
];
/**
* 修改场景验证
* @return Manager
*/
public function sceneUpdate()
{
return $this->remove('name', 'require');
}
/**
* 自定义查询场景验证 可灵活设置验证字段
* @return Manager
*/
public function sceneLists()
{
}
}

59
app/api/validate/Block.php

@ -0,0 +1,59 @@
<?php
declare (strict_types=1);
namespace app\api\validate;
use think\facade\Db;
use think\Validate;
class Block extends Validate
{
/**
* 定义验证规则
* 格式:'字段名' => ['规则1','规则2'...]
*
* @var array
*/
protected $rule = [
'id' => 'number|length:1,10',
'ident|碎片标识' => "require|uniqueSite:cloud_block|alphaDash|length:1,50",
];
/**
* 定义错误信息
* 格式:'字段名.规则名' => '错误信息'
*
* @var array
*/
protected $message = [
'ident.require' => '请输入碎片标识',
'ident.length' => '碎片标识必需在1~50位之间',
'ident.alphaDash'=>'碎片标志是能是数字字母和下划线组成'
];
/**
* 验证场景规则
* @var array
*/
protected $scene = [
'read' => ['id'],
];
/**
* 修改场景验证
* @return Manager
*/
public function sceneUpdate()
{
return $this->remove('ident', 'require');
}
/**
* 自定义查询场景验证 可灵活设置验证字段
* @return Manager
*/
public function sceneLists()
{
}
}

54
app/api/validate/Config.php

@ -0,0 +1,54 @@
<?php
declare (strict_types=1);
namespace app\api\validate;
use think\Validate;
class Config extends Validate
{
/**
* 定义验证规则
* 格式:'字段名' => ['规则1','规则2'...]
*
* @var array
*/
protected $rule = [
'id' => 'number|length:1,10',
'name|配置名称' => "require|uniqueSite:bmz_config|length:1,30",
'value|配置内容' => 'require|length:1,200',
'type|配置类型' => 'require|length:1,30',
];
/**
* 定义错误信息
* 格式:'字段名.规则名' => '错误信息'
*
* @var array
*/
protected $message = [
'name.require' => '请输入配置名称',
'name.length' => '配置名称必需在1~30位之间',
];
/**
* 验证场景规则
* @var array
*/
protected $scene = [
'read' => ['id'],
];
/**
* 自定义查询场景验证 可灵活设置验证字段
* @return Manager
*/
public function sceneLists()
{
return $this->only(['name', 'value', 'type'])
->remove('name', 'uniqueSite|require|length')
->remove('value', 'length|require')
->remove('type', 'length|require');
}
}

67
app/api/validate/Demo.php

@ -0,0 +1,67 @@
<?php
declare (strict_types=1);
namespace app\api\validate;
use think\Validate;
class Demo extends Validate
{
/**
* 定义验证规则
* 格式:'字段名' => ['规则1','规则2'...]
*
* @var array
*/
protected $rule = [
'id' => 'number|length:1,10',
'username|测试账号' => "require|uniqueSite:system_demo|length:4,20",
'truename|测试真实姓名' => 'require|length:1,20',
'password|测试密码' => 'require|length:6,20',
'sex|性别' => 'number|between:0,2',
];
/**
* 定义错误信息
* 格式:'字段名.规则名' => '错误信息'
*
* @var array
*/
protected $message = [
'username.require' => '请输入测试账号',
'username.length' => '测试账号名称必需在4~20位之间',
];
/**
* 验证场景规则
* @var array
*/
protected $scene = [
'read' => ['id'],
];
/**
* 修改场景验证
* @return Manager
*/
public function sceneUpdate()
{
return $this->remove('username', 'require')
->remove('truename', 'require')
->remove('phone', 'require');
//需删除以上代码,重新定义
}
/**
* 自定义查询场景验证 可灵活设置验证字段
* @return Manager
*/
public function sceneLists()
{
return $this->only(['username', 'truename', 'sex'])
->remove('username', 'uniqueSite|require|length')
->append('username', 'min:1|max:20')
->remove('truename', 'uniqueSite|require');
//需删除以上代码,重新定义
}
}

80
app/api/validate/Dictionary.php

@ -0,0 +1,80 @@
<?php
declare (strict_types=1);
namespace app\api\validate;
use think\Validate;
class Dictionary extends Validate
{
/**
* 定义验证规则
* 格式:'字段名' => ['规则1','规则2'...]
*
* @var array
*/
protected $rule = [
'id' => 'number|length:1,10',
'dict_type_id|字典类型id' => "require|integer",
'dict_name|字典名称' => 'require|length:1,100',
'dict_value|字典值' => "require|checkValue",
];
// 验证名称是否存在
protected function checkValue($value, $rule, $data=[])
{
$_op = new \app\api\model\Dictionary();
$count = $_op->chekName($value);
return $count == 0 ? true : '该类型下字典值不能重复';
}
/**
* 定义错误信息
* 格式:'字段名.规则名' => '错误信息'
*
* @var array
*/
protected $message = [
'dict_name.require' => '请输入字典标志',
'dict_name.length' => '字典标志长度为1~100',
'dict_value.require' => '请输入字典值',
'dict_value.length' => '字典值为1~100',
'dict_type_id.require' => '字典类型不能为空',
'dict_type_id.integer' => '字典类型为存数字',
];
/**
* 验证场景规则
* @var array
*/
protected $scene = [
'read' => ['id'],
];
/**
* 修改场景验证
* @return Manager
*/
public function sceneUpdate()
{
// return $this->remove('dict_symbol', 'dict_value')->append('');
}
/**
* 自定义查询场景验证 可灵活设置验证字段
* @return Manager
*/
public function sceneLists()
{
//需删除以上代码,重新定义
return $this->only(['dict_type_id','dict_name', 'dict_value'])
->remove('dict_name', 'require')
->remove('dict_value', 'require')
->remove('dict_value', 'checkValue')
// ->remove('dict_type_id', 'require|integer')
;
}
}

64
app/api/validate/DictionaryType.php

@ -0,0 +1,64 @@
<?php
declare (strict_types=1);
namespace app\api\validate;
use think\Validate;
class DictionaryType extends Validate
{
/**
* 定义验证规则
* 格式:'字段名' => ['规则1','规则2'...]
*
* @var array
*/
protected $rule = [
'id' => 'number|length:1,10',
'dict_symbol|字典标志' => "require|checkSymbol|alphaDash|length:2,50",
'dict_name|字典名称' => 'require|length:2,100',
];
// 验证名称是否存在
protected function checkSymbol($value, $rule, $data=[])
{
$_op = new \app\api\model\DictionaryType();
$count = $_op->where('dict_symbol',$value)->count();
return $count == 0 ? true : '字典类型标志不能重复';
}
/**
* 定义错误信息
* 格式:'字段名.规则名' => '错误信息'
*
* @var array
*/
protected $message = [
'dict_symbol.require' => '请输入字典类型标志',
'dict_symbol.length' => '字典类型标志必需在2~50位之间',
'dict_symbol.checkSymbol' => '字典类型标志不能重复',
'dict_symbol.alphaDash' => '字典类型只能是字母,数字和下划线',
'dict_name.require' => '请输入字典类型名称',
'dict_name.length' => '字典类型名称必需在2~100位之间',
];
/**
* 验证场景规则
* @var array
*/
protected $scene = [
'read' => ['id'],
];
/**
* 修改场景验证
* @return Manager
*/
public function sceneUpdate()
{
return $this->remove('dict_symbol', 'checkSymbol');
//需删除以上代码,重新定义
}
}

52
app/api/validate/Group.php

@ -0,0 +1,52 @@
<?php
declare (strict_types=1);
namespace app\api\validate;
use think\Validate;
class Group extends Validate
{
/**
* 定义验证规则
* 格式:'字段名' => ['规则1','规则2'...]
*
* @var array
*/
protected $rule = [
'id' => 'number|length:1,10',
'title|角色名称' => "require|uniqueSite:system_auth_group|length:2,20",
'role_code|角色标识' => "require|uniqueSite:system_auth_group|length:2,20",
'remark|角色备注' => 'length:2,200',
'status|状态' => 'number|length:1',
'page|页码' => 'number|length:1,10',
'pagesize|每页数量' => 'number|length:1,10',
];
/**
* 定义错误信息
* 格式:'字段名.规则名' => '错误信息'
*
* @var array
*/
protected $message = [
'title.require' => '请输入角色名称',
];
/**
* 验证场景规则
* @var array
*/
protected $scene = [
'read' => ['id'],
];
public function sceneLists()
{
return $this->remove('title', 'require|uniqueSite|length')
->append('title', 'min:1|max:20') //删除title length之后 ,再append length就无效了,只能换成min max
->remove('role_code','require|uniqueSite|length')
->append('role_code','min:1|max:20');
}
}

62
app/api/validate/Log.php

@ -0,0 +1,62 @@
<?php
declare (strict_types=1);
namespace app\api\validate;
use think\Validate;
class Log extends Validate
{
/**
* 定义验证规则
* 格式:'字段名' => ['规则1','规则2'...]
*
* @var array
*/
protected $rule = [
'username|管理员账号' => "length:1,20",
];
/**
* 定义错误信息
* 格式:'字段名.规则名' => '错误信息'
*
* @var array
*/
protected $message = [
'username.length' => '管理员账号名称必需在1~20位之间',
];
/**
* 验证场景规则
* @var array
*/
protected $scene = [
'read' => ['id'],
];
/**
* 修改场景验证
* @return Manager
*/
public function sceneUpdate()
{
return $this->remove('username', 'require')
->remove('truename', 'require')
->remove('phone', 'require');
//需删除以上代码,重新定义
}
/**
* 自定义查询场景验证 可灵活设置验证字段
* @return Manager
*/
public function sceneLists()
{
return $this->only(['username', 'truename', 'sex'])
->remove('username', 'uniqueSite|require|length')
->append('username', 'min:1|max:20')
->remove('truename', 'uniqueSite|require');
//需删除以上代码,重新定义
}
}

92
app/api/validate/Manager.php

@ -0,0 +1,92 @@
<?php
declare (strict_types=1);
namespace app\api\validate;
use think\facade\Db;
use think\Validate;
class Manager extends Validate
{
/**
* 定义验证规则
* 格式:'字段名' => ['规则1','规则2'...]
*
* @var array
*/
protected $rule = [
'id' => 'number|length:1,10',
'username|管理员账号' => "require|uniqueSite:system_user|length:4,20",
'truename|管理员真实姓名' => 'require|length:1,20',
'password|管理员密码' => 'require|length:6,20',
'sex|性别' => 'number|length:1,1',
'phone|手机号' => 'require|uniqueSite:system_user|mobile',
'email|邮箱' => 'email|uniqueSite:system_user',
'avatar|头像' => 'length:6,255',
];
/**
* 定义错误信息
* 格式:'字段名.规则名' => '错误信息'
*
* @var array
*/
protected $message = [
'username.require' => '请输入管理员账号',
'username.length' => '管理员账号名称必需在4~20位之间',
'password2.confirm' => '新密码与确认密码不一致',
];
/**
* 验证场景规则
* @var array
*/
protected $scene = [
'read' => ['id'],
];
/**
* 修改场景验证
* @return Manager
*/
public function sceneUpdate()
{
return $this->remove('username', 'require')
->remove('password', 'require');
}
/**
* 修改密码场景验证
* @return Manager
*/
public function sceneUpdatePassword()
{
return $this->remove('username', 'require')
->remove('truename', 'require')
->remove('phone', 'require')
->append('password2|确认密码', 'require|confirm:password');
}
/**
* 重置密码场景验证
* @return Manager
*/
public function sceneResetPassword()
{
return $this->remove('username', 'require')
->remove('truename', 'require')
->remove('phone', 'require');
}
/**
* 自定义查询场景验证 可灵活设置验证字段
* @return Manager
*/
public function sceneLists()
{
return $this->only(['username', 'truename', 'sex'])
->remove('username', 'uniqueSite|require|length')
->append('username', 'min:1|max:20')
->remove('truename', 'require');
}
}

68
app/api/validate/Menu.php

@ -0,0 +1,68 @@
<?php
declare (strict_types=1);
namespace app\api\validate;
use think\facade\Db;
use think\Validate;
class Menu extends Validate
{
/**
* 定义验证规则
* 格式:'字段名' => ['规则1','规则2'...]
*
* @var array
*/
protected $rule = [
'id' => 'number|length:1,10',
'name|菜单名称' => "require|uniqueSite:system_auth_rule|length:1,15",
'path|路由地址' => 'length:1,100',
'model_name|接口地址' => 'require|length:1,100',
'component|组件路径' => 'length:1,100',
'authority|权限标识' => 'uniqueSite:system_auth_rule|length:1,100',
'icon|图标' => 'length:1,100',
'hide|显示隐藏' => 'max:1|min:0',
'sort|排序' => 'between:0,10000',
'menu_type|菜单类型' => 'max:1|min:0',
'remarks|菜单备注' => 'length:1,100',
];
/**
* 定义错误信息
* 格式:'字段名.规则名' => '错误信息'
*
* @var array
*/
protected $message = [
'username.require' => '请输入菜单名称',
'username.length' => '菜单名称必需在1~15位之间',
];
/**
* 验证场景规则
* @var array
*/
protected $scene = [
'read' => ['id'],
];
/**
* 修改场景验证
* @return Manager
*/
public function sceneUpdate()
{
}
/**
* 自定义查询场景验证 可灵活设置验证字段
* @return Manager
*/
public function sceneLists()
{
return $this->remove('name', 'require|uniqueSite')
->remove('model_name', 'require');
}
}

42
app/api/validate/Message.php

@ -0,0 +1,42 @@
<?php
declare (strict_types=1);
namespace app\api\validate;
use think\Validate;
class Message extends Validate
{
/**
* 定义验证规则
* 格式:'字段名' => ['规则1','规则2'...]
*
* @var array
*/
protected $rule = [
'id' => 'number|length:1,10',
];
/**
* 验证场景规则
* @var array
*/
protected $scene = [
'read' => ['id'],
];
/**
* 修改场景验证
* @return Manager
*/
public function sceneUpdate()
{
// return $this->remove('dict_symbol', 'dict_value')->append('');
}
}

251
app/common.php

@ -0,0 +1,251 @@
<?php
// 应用公共文件
/**
* 解析文档注释正则匹配
* @param $str //完整注释
* @param string $tag 获取指定的标签数据
* @return string
*/
if (!function_exists('get_doc_comment')) {
function get_doc_comment($str, $tag = '')
{
if (empty($tag)) {
return $str;
}
$matches = array();
preg_match("/@" . $tag . "(.*)(\\r\\n|\\r|\\n)/U", $str, $matches);
if (isset($matches[1])) {
return trim($matches[1]);
}
return '';
}
}
/**
* 自定义全局验证器 判断同站点是否有重复数据 示例:uniqueSite:表名
* @param $value 验证数据
* @param $rule 验证规则
* @param $data 全部数据(数组)
* @param $name 字段名
* @param $note 字段描述
* @return bool
*/
function extra_unique_validate($value, $rule, $data, $name, $note)
{
$_db = \think\facade\Db::table($rule)->where('site_id', SITE_ID);
//id存在需要判断修改逻辑下排除id本身且不为空的情况下 有没有重复
$id = !empty($data['id']) ? $data['id'] : '';
if ($id) {
$_db->where('id', '<>', $id);
$_db->where($name, '<>', ' ');
}
$_data = $_db->where($name, $value)->find();
if (empty($_data)) {
return true;
}
return $note . '已存在,请重新输入!!!';
}
/**
* json统一返回
* @param type $code 状态编码 0正常
* @param type $data 返回数据
* @param type $msg 错误的提示信息
* @return type
*/
function send_http_status($data = [], $code = 0, $httpStatus = 200, $msg = '')
{
$msg = !empty($msg) ? $msg : config('dictionary')[$code];
//排除成功的状态信息
if (in_array($code, [201, 203, 205, 207, 209])) {
$code = 0;
}
$_data = [
'code' => $code,
'msg' => $msg,
'count' => 0,
'data' => $data,
];
//更改data2级数据为一级 增加列表页count数据
if (isset($data['page_total'])) {
$_data['count'] = $data['page_total'];
$_data['data'] = empty($data['data']) ? [] : $data['data'];
}
if ($code != 0 && $code != 200) {
throw new \app\exception\HttpException($httpStatus, $msg, $code);
}
return json($_data, $httpStatus);
}
/**
* 把格式数组,拆分父栏目,与子栏目
* @param type $arr 一级数组
* @param type $pid 父id
* @param type $child_name 生成子数组的名称
* @param type $primary 表的主键值,上一级id
* @return type
*/
function get_tree(array $arr, $pid = 0, $child_name = 'children', $primary = 'id')
{
if (empty($arr)) {
return $arr;
}
if (is_array($arr)) {
$child = get_child($arr, $pid);
if (empty($child)) {
return null;
}
foreach ($child as $key => $value) {
$current_child = get_tree($arr, $value[$primary]);
if ($current_child != null) {
$child[$key][$child_name] = $current_child;
}
}
}
return $child;
}
//根据pid获取子栏目 返回子栏目数组集合
function get_child($arr, $pid = 0)
{
if (is_array($arr)) {
$child = array();
foreach ($arr as $key => $value) {
if ($value['parent_id'] == $pid) {
$child[$key] = $value;
}
}
return array_values($child);
}
return $arr;
}
/**
* 云掌图片服务器裁剪函数
* @param $src 源地址,不带?号
* @param $w 宽度
* @param $h 高度
* @param $g 裁剪位置 nw西北 north正北 ne东北 west正西 center中间 east正东 sw西南 south正南 se东南
* @param string $type 执行方式 crop:裁剪 resize:缩放
*/
function crop_thumb($src, $w = '', $h = '')
{
//判断图片是不是全路径
$cdn_img_host = strpos($src, 'http') !== 0 ? config('cdn_img_host') : '';
if (empty($src) || !$w || !$h) {
return $cdn_img_host . $src;
}
//限制宽、高大小
if ($w > 2000 || $w < 5 || $h > 2000 || $h < 5) {
return $src;
}
//有逗号分割符取第一张图片
$first_pic = strstr($src, ',', true);
$src = !empty($first_pic) ? $first_pic : $src;
//拆分图片后缀
$last_pos = strripos($src, '.'); //图片格式中点的位置
$base_url = mb_substr($src, 0, $last_pos); //去图片后缀的url
$exp_url = mb_substr($src, $last_pos); //图片后缀
return $cdn_img_host . $base_url . '_' . $w . 'x' . $h . $exp_url;
}
/**
* 判断浏览器名称和版本
*/
function get_client_browser()
{
$agent = !empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : false;
if (!$agent) {
return false;
}
if ((strpos($agent, 'MSIE') == false) && (strpos($agent, 'Trident') !== FALSE)) {
return 'Internet Explorer 11.0';
}
if (strpos($agent, 'MSIE 10.0') != false) {
return 'Internet Explorer 10.0';
}
if (strpos($agent, 'MSIE 9.0') != false) {
return 'Internet Explorer 9.0';
}
if (strpos($agent, 'MSIE 8.0') != false) {
return 'Internet Explorer 8.0';
}
if (strpos($agent, 'MSIE 7.0') != false) {
return 'Internet Explorer 7.0';
}
if (strpos($agent, 'MSIE 6.0') != false) {
return 'Internet Explorer 6.0';
}
if (strpos($agent, 'Edge') != false) {
return 'Edge';
}
if (strpos($agent, '360SE') != false) {
return '360SE';
}
if (strpos($agent, 'QQBrowser') != false) {
return 'QQBrowser';
}
if (strpos($agent, 'Firefox') != false) {
return 'Firefox';
}
if (strpos($agent, 'Chrome') != false) {
return 'Chrome';
}
if (strpos($agent, 'Safari') != false) {
return 'Safari';
}
if (strpos($agent, 'Opera') != false) {
return 'Opera';
}
//微信浏览器
if (strpos($agent, 'MicroMessage') != false) {
return '微信浏览器';
}
}
/**
* 获取系统类型
*/
function get_client_os()
{
$agent = strtolower($_SERVER['HTTP_USER_AGENT']);
if (strpos($agent, 'windows nt')) {
$platform = 'Windows';
} elseif (strpos($agent, 'macintosh')) {
$platform = 'Mac';
} elseif (strpos($agent, 'ipod')) {
$platform = 'iPod';
} elseif (strpos($agent, 'ipad')) {
$platform = 'iPad';
} elseif (strpos($agent, 'iphone')) {
$platform = 'iPhone';
} elseif (strpos($agent, 'android')) {
$platform = 'Android';
} elseif (strpos($agent, 'unix')) {
$platform = 'Unix';
} elseif (strpos($agent, 'linux')) {
$platform = 'Linux';
} else {
$platform = '其他';
}
return $platform;
}
//过滤单双引号
function htmlspecialchars_custom($str)
{
return htmlspecialchars($str, ENT_QUOTES);
}

17
app/event.php

@ -0,0 +1,17 @@
<?php
// 事件定义文件
return [
'bind' => [
],
'listen' => [
'AppInit' => [],
'HttpRun' => [],
'HttpEnd' => [],
'LogLevel' => [],
'LogWrite' => [],
],
'subscribe' => [
],
];

82
app/exception/ExceptionHandle.php

@ -0,0 +1,82 @@
<?php
namespace app\exception;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\Exception;
use think\exception\Handle;
use app\exception\HttpException;
use think\exception\HttpResponseException;
use think\exception\ValidateException;
use think\Response;
use Throwable;
/**
* 应用异常处理类
*/
class ExceptionHandle extends Handle
{
private $httpStatusCode = 200; //http状态码
private $msg = '未知错误'; //自定义错误内容
private $code = 100; //自定义错误码
/**
* 不需要记录信息(日志)的异常类列表
* @var array
*/
protected $ignoreReport = [
HttpException::class,
HttpResponseException::class,
ModelNotFoundException::class,
DataNotFoundException::class,
ValidateException::class,
];
/**
* 记录异常信息(包括日志或者其它方式记录)
*
* @access public
* @param Throwable $exception
* @return void
*/
public function report(Throwable $exception): void
{
// 使用内置的方式记录异常日志
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
* throw new \app\exception\HttpException(309, ''); http使用方法
* throw new Exception('导演',300); 异常类使用访求
* @access public
* @param \think\Request $request
* @param Throwable $e
* @return Response
*/
public function render($request, Throwable $e): Response
{
// 其他错误交给系统处理
if (config('app.app_debug')) {
return parent::render($request, $e);
}
// 添加自定义异常处理机制
$this->msg = $e->getMessage() ?: $this->msg;
//兼容Exception类 这个类没有getStatusCode方法
if ($e instanceof HttpException) {
$this->httpStatusCode = $e->getStatusCode() ?: $this->httpStatusCode;
}
$this->code = $e->getCode() ?: $this->code;
$data = [
'msg' => $this->msg,
'data' => [],
'code' => $this->code,
];
return json($data, $this->httpStatusCode);
}
}

42
app/exception/HttpException.php

@ -0,0 +1,42 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: yunwuxin <448901948@qq.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\exception;
use Exception;
/**
* HTTP异常
*/
class HttpException extends \RuntimeException
{
private $statusCode;
private $headers;
public function __construct(int $statusCode, string $message = '', $code = 0, array $headers = [], Exception $previous = null)
{
$this->statusCode = $statusCode;
$this->headers = $headers;
parent::__construct($message, $code, $previous);
}
public function getStatusCode()
{
return $this->statusCode;
}
public function getHeaders()
{
return $this->headers;
}
}

19
app/facade/Test.php

@ -0,0 +1,19 @@
<?php
/**
* Created by 花密欧团队.
* User: 云掌.帮德
* Date: 2020/3/5 13:34
* Desc:
*/
namespace app\facade;
use think\facade;
class Test extends Facade
{
public static function getFacadeClass()
{
return 'test\Test';
}
}

87
app/index/controller/Blog.php

@ -0,0 +1,87 @@
<?php
declare (strict_types=1);
namespace app\index\controller;
use app\facade\Test;
use auth\JwtAuth;
use think\Request;
class Blog
{
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index()
{
JwtAuth::index();
}
/**
* 显示创建资源表单页.
*
* @return \think\Response
*/
public function create(Request $request)
{
Test::index();
}
/**
* 保存新建的资源
*
* @param \think\Request $request
* @return \think\Response
*/
public function save(Request $request)
{
//
}
/**
* 显示指定的资源
*
* @param int $id
* @return \think\Response
*/
public function read($id)
{
//
}
/**
* 显示编辑资源表单页.
*
* @param int $id
* @return \think\Response
*/
public function edit($id)
{
//
}
/**
* 保存更新的资源
*
* @param \think\Request $request
* @param int $id
* @return \think\Response
*/
public function update(Request $request, $id)
{
//
}
/**
* 删除指定资源
*
* @param int $id
* @return \think\Response
*/
public function delete($id)
{
//
}
}

30
app/index/controller/Index.php

@ -0,0 +1,30 @@
<?php
declare (strict_types=1);
namespace app\index\controller;
use app\index\model\User;
use think\Exception;
class Index
{
public function hello(User $user)
{
exit('a');
echo 'a';
echo 'b';
echo 'c';
echo 'd';
echo 'e';
throw new \app\exception\HttpException(401, '', 19999);
// halt($user->find(7));
}
public function index(){
echo "hello";
}
}

89
app/index/controller/Jwt.php

@ -0,0 +1,89 @@
<?php
declare (strict_types=1);
namespace app\index\controller;
use Lcobucci\Clock\FrozenClock;
use Lcobucci\JWT\Configuration;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\Signer\Key\InMemory;
use Lcobucci\JWT\UnencryptedToken;
use Lcobucci\JWT\Validation\Constraint;
class Jwt
{
private $config;
public function __construct()
{
// $key = InMemory::plainText('my-key');
// $key = InMemory::base64Encoded('bXkgdGVzdCB0b2tlbnMK');
$key = 'bXkgdGVzdCB0b2tlbnMK';
$this->config = Configuration::forSymmetricSigner(
new Sha256(),
InMemory::plainText($key)
);
}
public function createToken()
{
// halt($key,$configuration);
// echo($config instanceof Configuration);
$now = new \DateTimeImmutable();
$token = $this->config->builder()
// jwt签发者
->issuedBy('http://example.com')
// Configures the audience (aud claim)
->permittedFor('http://example.org')
// jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
->identifiedBy('4f1g23a12aa')
// jwt的签发时间
->issuedAt($now)
// Configures the time that the token can be used (nbf claim)
->canOnlyBeUsedAfter($now->modify('+1 minute'))
// Configures the expiration time of the token (exp claim)
->expiresAt($now->modify('+1 minute'))
// Configures a new claim, called "uid"
->withClaim('uid', 10)
// Configures a new header, called "foo"
->withHeader('foo', 'bar')
// Builds a new token
->getToken($this->config->signer(), $this->config->signingKey());
// halt($token->claims()->get('uid'));
halt($token->toString());
}
public function parseToken()
{
$_token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhaGJtei5jb20iLCJhdWQiOiJiYXNlLmFoYm16LmNvbSIsImp0aSI6Imx3RWluZ2U0RXk4RXhqeHBVODNrbEtsZmVpYW84TCIsImlhdCI6IjE2MTUyNjkxNDIuOTQ2NDc3IiwibmJmIjoiMTYxNTI2OTE0Mi45NDY0NzciLCJleHAiOiIxNjE1MzQxMTQyLjk0NjQ3NyIsInVzZXJfaWQiOjEsInNpdGVfaWQiOjF9.9bGtgvWH0iredbmuJrfhA2hY0aatEnpX3g-jKY9bLXs';
$token = $this->config->parser()->parse($_token);
halt($token->headers(), $token->claims());
}
public function checkToken()
{
$config = $this->config;
$_token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImZvbyI6ImJhciJ9.eyJpc3MiOiJodHRwOi8vZXhhbXBsZS5jb20iLCJhdWQiOiJodHRwOi8vZXhhbXBsZS5vcmciLCJqdGkiOiI0ZjFnMjNhMTJhYSIsImlhdCI6IjE2MTQxNzc0NjkuNDM3NDMwIiwibmJmIjoiMTYxNDE3NzUyOS40Mzc0MzAiLCJleHAiOiIxNjE0MTc3NTI5LjQzNzQzMCIsInVpZCI6MTB9.oC37eJvIsGGNu7X6J7axbH7-Rzs-MJQsI5gvqmpDn-Q';
$token = $config->parser()->parse($_token);
// halt($config->parser()->parse($_token));
$constraint = new Constraint\SignedWith($this->config->signer(), $this->config->verificationKey());
$config->setValidationConstraints($constraint);
$constraints = $config->validationConstraints();
if (!$config->validator()->validate($token, ...$constraints)) {
exit('no way!');
}else{
$now = new \DateTimeImmutable();
// $clock = new FrozenClock($now);
// $a = new Constraint\LooseValidAt($clock,new \DateInterval('P2W'));
// halt($a,$token->isExpired($now));
halt($token);
halt($token->isMinimumTimeBefore($now),$token->isPermittedFor('http://example.org'),$token->isExpired($now),$token->hasBeenIssuedBy('http://example.com'));
exit('验证通过');
}
}
}

14
app/index/model/User.php

@ -0,0 +1,14 @@
<?php
declare (strict_types=1);
namespace app\index\model;
use think\Model;
/**
* @mixin think\Model
*/
class User extends Model
{
//
}

13
app/index/route/app.php

@ -0,0 +1,13 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
use think\facade\Route;
Route::get('user/:id','index/Index/hello');

20
app/middleware.php

@ -0,0 +1,20 @@
<?php
// 全局中间件定义文件
return [
// 全局请求缓存
// \think\middleware\CheckRequestCache::class,
// 多语言加载
// \think\middleware\LoadLangPack::class,
// Session初始化
// \think\middleware\SessionInit::class
//自定义跨域中间件
\app\middleware\AllowCrossDomain::class,
// 系统跨域,传入token参数
// \think\middleware\AllowCrossDomain::class,
// [
// \think\middleware\AllowCrossDomain::class,
// [
// ['Access-Control-Allow-Headers' => 'Token,Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-CSRF-TOKEN, X-Requested-With']
// ]
// ],
];

44
app/middleware/AllowCrossDomain.php

@ -0,0 +1,44 @@
<?php
declare (strict_types=1);
namespace app\middleware;
use think\App;
class AllowCrossDomain
{
protected $app;
public function __construct(App $app)
{
$this->app = $app;
}
/**
* 处理请求
*
* @param \think\Request $request
* @param \Closure $next
* @return Response
*/
public function handle($request, \Closure $next)
{
/** @var Response $response */
$response = $next($request);
// 支持跨域请求的host数组['a.cn', 'b.cn']
$corsHost = ['api.base.ahbmz.com', 'api.ahbmz.com', 'cms.ahbmz.com'];
// if (!empty($corsHost) && is_array($corsHost) && in_array($request->host(), $corsHost)) {
$response->header([
'Access-Control-Allow-Origin' => '*',
'Access-Control-Max-Age' => 1800,
'Access-Control-Allow-Methods' => 'GET, POST, PATCH, PUT, DELETE',
'Access-Control-Allow-Headers' => 'Authorization, Token, Content-Type, If-Match,If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With',
]);
// }
return $response;
}
}

70
app/middleware/CheckJwtAuth.php

@ -0,0 +1,70 @@
<?php
declare (strict_types=1);
namespace app\middleware;
use auth\JwtAuth;
class CheckJwtAuth
{
/**
* 处理请求
*
* @param \think\Request $request
* @param \Closure $next
* @return Response
*/
public function handle($request, \Closure $next)
{
//获取当前控制器模型
// $url = str_replace(['//', '\\', '/'], '', $request->root()) . '/' . $request->pathinfo();
// $filter_router = config('jwtauth.filter_router');
// foreach ($filter_router as $v) {
// if (strpos(strtolower($url), strtolower($v)) === 0) {
// return $next($request);
// }
// }
//测试开户app_debug,设置自定用户参数及站点参数
env('app_debug') ? $this->getLocalToken() : $this->getJwtToken();
return $next($request);
}
/**
* 正式环境
* @return \type
*/
private function getJwtToken()
{
$token = JwtAuth::getInstance()->checkToken(request()->header('Token'));
if ($token) {
/**
* 登录用户ID
*/
defined('UID') ?: define('UID', $token['user_id']);
/**
* 站点ID
*/
defined('SITE_ID') ?: define('SITE_ID', $token['site_id']);
}
}
/**
* 本地模拟
*/
private function getLocalToken()
{
/**
* 登录用户ID
*/
defined('UID') ?: define('UID', Request()->param('uid', 1));
/**
* 站点ID
*/
defined('SITE_ID') ?: define('SITE_ID', Request()->param('site_id', 1));
}
}

11
app/provider.php

@ -0,0 +1,11 @@
<?php
use app\ExceptionHandle;
use app\Request;
// 容器Provider定义文件
return [
'think\Request' => Request::class,
// 'think\exception\Handle' => ExceptionHandle::class, //原系统
'think\exception\Handle' => 'app\\exception\\ExceptionHandle', //自定义异常类
];

9
app/service.php

@ -0,0 +1,9 @@
<?php
use app\AppService;
// 系统服务定义文件
// 服务在完成全局初始化之后执行
return [
AppService::class,
];

55
composer.json

@ -0,0 +1,55 @@
{
"name": "topthink/think",
"description": "the new thinkphp framework",
"type": "project",
"keywords": [
"framework",
"thinkphp",
"ORM"
],
"homepage": "http://thinkphp.cn/",
"license": "Apache-2.0",
"authors": [
{
"name": "liu21st",
"email": "liu21st@gmail.com"
},
{
"name": "yunwuxin",
"email": "448901948@qq.com"
}
],
"require": {
"php": ">=7.1.0",
"topthink/framework": "^6.0.0",
"topthink/think-orm": "^2.0",
"topthink/think-multi-app": "^1.0",
"lcobucci/jwt": "^4.0",
"topthink/think-migration": "^3.0",
"doctrine/annotations": "^1.8",
"zircote/swagger-php": "^3.1",
"swiftmailer/swiftmailer": "^6.2",
"edward1108/edward-captcha": "^1.1"
},
"require-dev": {
"symfony/var-dumper": "^4.2",
"topthink/think-trace":"^1.0"
},
"autoload": {
"psr-4": {
"app\\": "app"
},
"psr-0": {
"": "extend/"
}
},
"config": {
"preferred-install": "dist"
},
"scripts": {
"post-autoload-dump": [
"@php think service:discover",
"@php think vendor:publish"
]
}
}

2350
composer.lock

File diff suppressed because it is too large

36
config/app.php

@ -0,0 +1,36 @@
<?php
// +----------------------------------------------------------------------
// | 应用设置
// +----------------------------------------------------------------------
return [
// 应用地址
'app_host' => env('app.host', ''),
//调试开关
'app_debug' => env('app_debug', false),
// 应用的命名空间
'app_namespace' => '',
// 是否启用路由
'with_route' => true,
// 是否启用事件
'with_event' => true,
// 默认应用
'default_app' => 'index',
// 默认时区
'default_timezone' => 'Asia/Shanghai',
// 应用映射(自动多应用模式有效)
'app_map' => [],
// 域名绑定(自动多应用模式有效)
'domain_bind' => [],
// 禁止URL访问的应用列表(自动多应用模式有效)
'deny_app_list' => [],
// 异常页面的模板文件
'exception_tmpl' => app()->getThinkPath() . 'tpl/think_exception.tpl',
// 错误显示信息,非调试模式有效
'error_message' => '页面错误!请稍后再试~',
// 显示错误信息
'show_error_msg' => true,
];

20
config/auth.php

@ -0,0 +1,20 @@
<?php
// +----------------------------------------------------------------------
// | PermissAuth权限系统配置文件
// +----------------------------------------------------------------------
return [
'auth_on' => 1, // 权限开关
'auth_type' => 1, // 认证方式,1为实时认证;2为登录认证。
'auth_group' => 'system_auth_group', // 用户组数据不带前缀表名
'auth_group_access' => 'system_auth_group_access', // 用户-用户组关系不带前缀表名
'auth_rule' => 'system_auth_rule', // 权限规则不带前缀表名
'auth_user' => 'system_user', // 用户信息不带前缀表名
'auth_filter_model' => [
'api/login/login' => '用户登录',
'api/manager/permissMenu' => '用户获取菜单',
'api/manager/read' => '用户个人信息',
'api/manager/passwordReset' => '修改密码',
'api/Dashboard/index' => '仪表盘',
]
];

29
config/cache.php

@ -0,0 +1,29 @@
<?php
// +----------------------------------------------------------------------
// | 缓存设置
// +----------------------------------------------------------------------
return [
// 默认缓存驱动
'default' => env('cache.driver', 'file'),
// 缓存连接方式配置
'stores' => [
'file' => [
// 驱动方式
'type' => 'File',
// 缓存保存目录
'path' => '',
// 缓存前缀
'prefix' => '',
// 缓存有效期 0表示永久缓存
'expire' => 0,
// 缓存标签前缀
'tag_prefix' => 'tag:',
// 序列化机制 例如 ['serialize', 'unserialize']
'serialize' => [],
],
// 更多的缓存连接
],
];

39
config/captcha.php

@ -0,0 +1,39 @@
<?php
// +----------------------------------------------------------------------
// | Captcha配置文件
// +----------------------------------------------------------------------
return [
//验证码位数
'length' => 4,
// 验证码字符集合
'codeSet' => '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY',
// 验证码过期时间
'expire' => 1800,
// 是否使用中文验证码
'useZh' => false,
// 是否使用算术验证码
'math' => true,
// 是否使用背景图
'useImgBg' => false,
//验证码字符大小
'fontSize' => 18,
// 是否使用混淆曲线
'useCurve' => true,
//是否添加杂点
'useNoise' => true,
// 验证码字体 不设置则随机
'fontttf' => '',
//背景颜色
'bg' => [243, 251, 254],
// 验证码图片高度
'imageH' => 48,
// 验证码图片宽度
'imageW' => 130,
// 添加额外的验证码设置
// verify => [
// 'length'=>4,
// ...
//],
];

9
config/console.php

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

18
config/cookie.php

@ -0,0 +1,18 @@
<?php
// +----------------------------------------------------------------------
// | Cookie设置
// +----------------------------------------------------------------------
return [
// cookie 保存时间
'expire' => 0,
// cookie 保存路径
'path' => '/',
// cookie 有效域名
'domain' => '',
// cookie 启用安全传输
'secure' => false,
// httponly设置
'httponly' => false,
// 是否使用 setcookie
'setcookie' => true,
];

62
config/database.php

@ -0,0 +1,62 @@
<?php
return [
// 默认使用的数据库连接配置
'default' => env('database.driver', 'mysql'),
// 自定义时间查询规则
'time_query_rule' => [],
// 自动写入时间戳字段
// true为自动识别类型 false关闭
// 字符串则明确指定时间字段类型 支持 int timestamp datetime date
'auto_timestamp' => true,
// 时间字段取出后的默认时间格式
'datetime_format' => 'Y-m-d H:i:s',
// 数据库连接配置信息
'connections' => [
'mysql' => [
// 数据库类型
'type' => env('database.type', 'mysql'),
// 服务器地址
'hostname' => env('database.hostname', '122.114.59.173'),
// 数据库名
'database' => env('database.database', 'bmz_base'),
// 用户名
'username' => env('database.username', 'bmz_base'),
// 密码
'password' => env('database.password', 'C2dA3FPLZxhDjKnr'),
// 端口
'hostport' => env('database.hostport', '3306'),
// 数据库连接参数
'params' => [],
// 数据库编码默认采用utf8
'charset' => env('database.charset', 'utf8mb4'),
// 数据库表前缀
'prefix' => env('database.prefix', 'bmz_'),
// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
'deploy' => 0,
// 数据库读写是否分离 主从式有效
'rw_separate' => false,
// 读写分离后 主服务器数量
'master_num' => 1,
// 指定从服务器序号
'slave_no' => '',
// 是否严格检查字段是否存在
'fields_strict' => true,
// 是否需要断线重连
'break_reconnect' => false,
// 监听SQL
'trigger_sql' => env('app_debug', true),
// 开启字段缓存
'fields_cache' => false,
// 字段缓存路径
'schema_cache_path' => app()->getRuntimePath() . 'schema' . DIRECTORY_SEPARATOR,
],
// 更多的数据库配置信息
],
];

53
config/dict.php

@ -0,0 +1,53 @@
<?php
/**
* 数据库字典表数据
*/
return [
'sqlfields' =>
array (
'status' =>
array (
0 => '禁用',
1 => '启用',
),
'sex' =>
array (
1 => '女',
2 => '男',
),
'column_type' =>
array (
0 => '列表',
1 => '单页',
2 => '外部链接',
3 => '留言板',
),
'ad_type' =>
array (
0 => '固定广告',
1 => '幻灯广告',
2 => '对联广告',
3 => '漂浮广告',
),
'image_storage_type' =>
array (
0 => '全部',
1 => '商务',
2 => '建筑',
3 => '山水',
4 => '风景',
5 => '办公',
6 => '天空',
7 => '家具',
8 => '汽车',
9 => '服装',
10 => '工厂',
11 => '安全',
12 => '峡谷',
),
)
,
];

86
config/dictionary.php

@ -0,0 +1,86 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// +----------------------------------------------------------------------
// | 数据字典配置
// +----------------------------------------------------------------------
return [
//登录数据字典
'0' => 'ok',
'100' => '未知错误',
'101' => '数据不存在',
'102' => '站点不存在,请联系官方客服授权!!!',
'200' => 'ok',
'201' => '添加成功',
'202' => '添加失败',
'203' => '修改成功',
'204' => '修改失败或者没做任何修改',
'205' => '删除成功',
'206' => '删除失败',
'207' => '状态更改成功',
'208' => '状态更改失败',
'209' => '保存成功',
'210' => '保存失败',
'403' => '很抱歉您没有操作权限,请联系站点管理员!!!',
'500' => 'error',
'40500' => '恭喜,登陆成功!!!',
'40501' => '用户名不正确!!!',
'40502' => '用户名不存在!!!',
'40503' => '该用户名已被禁用!!!',
'40504' => '密码不正确!!!',
'40505' => '未检测到正确的用户名!!!',
'40506' => '验证码不正确!!!',
'40507' => '密码错误次数过多,请半小时后重试或联系管理员!!!',
'40508' => '您的ip已被禁止访问,请联系管理员!!!',
'40509' => 'refresh_token已过期',
'40510' => 'token已过期',
'40511' => '您没有操作权限请联系站点管理员!!!',
'40512' => 'token无效或验证失败!!!',
//短信Api数据字典
'40601' => '请输入正确的手机号!!!',
'40602' => '短信服务商数据不存在或被禁用!!!',
'40603' => '短信模板不存在或被禁用!!!',
'40604' => '请输入4位验证码!!!',
'40605' => '验证码不正确,请重新输入!!!',
//数据库字典
'sqlfields' => [
'status' => [
0 => '禁用',
1 => '启用',
],
'sex' => [
1 => '女',
2 => '男'
],
/*栏目类型*/
'column_type' => [
0 => '列表',
1 => '单页',
2 => '外部链接',
3 => '留言板',
],
/*广告类型*/
'ad_type' => [
0 => '固定广告',
1 => '幻灯广告',
2 => '对联广告',
3 => '漂浮广告',
],
],
'upload'=>[
'cdn_img_host'=>'http://xxxx.com/'
],
];

24
config/filesystem.php

@ -0,0 +1,24 @@
<?php
return [
// 默认磁盘
'default' => env('filesystem.driver', 'local'),
// 磁盘列表
'disks' => [
'local' => [
'type' => 'local',
'root' => app()->getRuntimePath() . 'storage',
],
'public' => [
// 磁盘类型
'type' => 'local',
// 磁盘路径
'root' => app()->getRootPath() . 'public/storage',
// 磁盘路径对应的外部URL路径
'url' => '/storage',
// 可见性
'visibility' => 'public',
],
// 更多的磁盘配置信息
],
];

25
config/lang.php

@ -0,0 +1,25 @@
<?php
// +----------------------------------------------------------------------
// | 多语言设置
// +----------------------------------------------------------------------
return [
// 默认语言
'default_lang' => env('lang.default_lang', 'zh-cn'),
// 允许的语言列表
'allow_lang_list' => [],
// 多语言自动侦测变量名
'detect_var' => 'lang',
// 是否使用Cookie记录
'use_cookie' => true,
// 多语言cookie变量
'cookie_var' => 'think_lang',
// 扩展语言包
'extend_list' => [],
// Accept-Language转义为对应语言包名称
'accept_language' => [
'zh-hans-cn' => 'zh-cn',
],
// 是否支持语言分组
'allow_group' => false,
];

45
config/log.php

@ -0,0 +1,45 @@
<?php
// +----------------------------------------------------------------------
// | 日志设置
// +----------------------------------------------------------------------
return [
// 默认日志记录通道
'default' => env('log.channel', 'file'),
// 日志记录级别
'level' => [],
// 日志类型记录的通道 ['error'=>'email',...]
'type_channel' => [],
// 关闭全局日志写入
'close' => false,
// 全局日志处理 支持闭包
'processor' => null,
// 日志通道列表
'channels' => [
'file' => [
// 日志记录方式
'type' => 'File',
// 日志保存目录
'path' => '',
// 单文件日志写入
'single' => false,
// 独立日志级别
'apart_level' => [],
// 最大日志文件数量
'max_files' => 0,
// 使用JSON格式记录
'json' => false,
// 日志处理
'processor' => null,
// 关闭通道日志写入
'close' => false,
// 日志输出格式化
'format' => '[%s][%s] %s',
// 是否实时写入
'realtime_write' => false,
],
// 其它日志通道配置
],
];

8
config/middleware.php

@ -0,0 +1,8 @@
<?php
// 中间件配置
return [
// 别名或分组
'alias' => [],
// 优先级设置,此数组中的中间件会按照数组中的顺序优先执行
'priority' => [],
];

45
config/route.php

@ -0,0 +1,45 @@
<?php
// +----------------------------------------------------------------------
// | 路由设置
// +----------------------------------------------------------------------
return [
// pathinfo分隔符
'pathinfo_depr' => '/',
// URL伪静态后缀
'url_html_suffix' => 'html',
// URL普通方式参数 用于自动生成
'url_common_param' => true,
// 是否开启路由延迟解析
'url_lazy_route' => false,
// 是否强制使用路由
'url_route_must' => false,
// 合并路由规则
'route_rule_merge' => false,
// 路由是否完全匹配
'route_complete_match' => false,
// 访问控制器层名称
'controller_layer' => 'controller',
// 空控制器名
'empty_controller' => 'Error',
// 是否使用控制器后缀
'controller_suffix' => false,
// 默认的路由变量规则
'default_route_pattern' => '[\w\.]+',
// 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
'request_cache' => false,
// 请求缓存有效期
'request_cache_expire' => null,
// 全局请求缓存排除规则
'request_cache_except' => [],
// 默认控制器名
'default_controller' => 'Index',
// 默认操作名
'default_action' => 'index',
// 操作方法后缀
'action_suffix' => '',
// 默认JSONP格式返回的处理方法
'default_jsonp_handler' => 'jsonpReturn',
// 默认JSONP处理方法
'var_jsonp_handler' => 'callback',
];

19
config/session.php

@ -0,0 +1,19 @@
<?php
// +----------------------------------------------------------------------
// | 会话设置
// +----------------------------------------------------------------------
return [
// session name
'name' => 'PHPSESSID',
// SESSION_ID的提交变量,解决flash上传跨域
'var_session_id' => '',
// 驱动方式 支持file cache
'type' => 'file',
// 存储连接标识 当type使用cache的时候有效
'store' => null,
// 过期时间
'expire' => 1440,
// 前缀
'prefix' => '',
];

10
config/trace.php

@ -0,0 +1,10 @@
<?php
// +----------------------------------------------------------------------
// | Trace设置 开启调试模式后有效
// +----------------------------------------------------------------------
return [
// 内置Html和Console两种方式 支持扩展
'type' => 'Html',
// 读取的日志通道名
'channel' => '',
];

25
config/view.php

@ -0,0 +1,25 @@
<?php
// +----------------------------------------------------------------------
// | 模板设置
// +----------------------------------------------------------------------
return [
// 模板引擎类型使用Think
'type' => 'Think',
// 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法
'auto_rule' => 1,
// 模板目录名
'view_dir_name' => 'view',
// 模板后缀
'view_suffix' => 'html',
// 模板文件名分隔符
'view_depr' => DIRECTORY_SEPARATOR,
// 模板引擎普通标签开始标记
'tpl_begin' => '{',
// 模板引擎普通标签结束标记
'tpl_end' => '}',
// 标签库标签开始标记
'taglib_begin' => '{',
// 标签库标签结束标记
'taglib_end' => '}',
];

108
database/migrations/20181113071924_create_rules_table.php

@ -0,0 +1,108 @@
<?php
use think\migration\Migrator;
use Phinx\Db\Adapter\AdapterFactory;
class CreateRulesTable extends Migrator
{
/**
* Initialize method.
*
* @return void
*/
protected function init()
{
$options = $this->getDbConfig();
$adapter = AdapterFactory::instance()->getAdapter($options['adapter'], $options);
if ($adapter->hasOption('table_prefix') || $adapter->hasOption('table_suffix')) {
$adapter = AdapterFactory::instance()->getWrapper('prefix', $adapter);
}
$this->setAdapter( $adapter);
}
/**
* 获取数据库配置
* @return array
*/
protected function getDbConfig(): array
{
$default = config('tauthz.database.connection') ?: config('database.default');
$config = config("database.connections.{$default}");
if (0 == $config['deploy']) {
$dbConfig = [
'adapter' => $config['type'],
'host' => $config['hostname'],
'name' => $config['database'],
'user' => $config['username'],
'pass' => $config['password'],
'port' => $config['hostport'],
'charset' => $config['charset'],
'table_prefix' => $config['prefix'],
];
} else {
$dbConfig = [
'adapter' => explode(',', $config['type'])[0],
'host' => explode(',', $config['hostname'])[0],
'name' => explode(',', $config['database'])[0],
'user' => explode(',', $config['username'])[0],
'pass' => explode(',', $config['password'])[0],
'port' => explode(',', $config['hostport'])[0],
'charset' => explode(',', $config['charset'])[0],
'table_prefix' => explode(',', $config['prefix'])[0],
];
}
$table = config('database.migration_table', 'migrations');
$dbConfig['default_migration_table'] = $dbConfig['table_prefix'] . $table;
return $dbConfig;
}
/**
* 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 up()
{
$default = config('tauthz.default');
$table = $this->table(config('tauthz.enforcers.'.$default.'.database.rules_name'));
$table->addColumn('ptype', 'string', ['null' => true])
->addColumn('v0', 'string', ['null' => true])
->addColumn('v1', 'string', ['null' => true])
->addColumn('v2', 'string', ['null' => true])
->addColumn('v3', 'string', ['null' => true])
->addColumn('v4', 'string', ['null' => true])
->addColumn('v5', 'string', ['null' => true])
->create();
}
public function down()
{
$default = config('tauthz.default');
$table = $this->table(config('tauthz.enforcers.'.$default.'.database.rules_name'));
$table->drop();
}
}

1
extend/.gitignore

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

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

Loading…
Cancel
Save