<?php
declare(strict_types=1);
* +----------------------------------------------------------------------
* | ThinkAdmin Plugin for ThinkAdmin
* +----------------------------------------------------------------------
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
* +----------------------------------------------------------------------
* | 官方网站: https://thinkadmin.top
* +----------------------------------------------------------------------
* | 开源协议 ( https://mit-license.org )
* | 免责声明 ( https://thinkadmin.top/disclaimer )
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
* +----------------------------------------------------------------------
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
* +----------------------------------------------------------------------
*/
namespace think\admin;
use think\admin\extend\JwtExtend;
use think\admin\helper\DeleteHelper;
use think\admin\helper\FormHelper;
use think\admin\helper\PageHelper;
use think\admin\helper\QueryHelper;
use think\admin\helper\SaveHelper;
use think\admin\helper\TokenHelper;
use think\admin\helper\ValidateHelper;
use think\admin\service\NodeService;
use think\admin\service\QueueService;
use think\App;
use think\db\BaseQuery;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\exception\HttpResponseException;
use think\Model;
use think\Request;
* 标准控制器基类.
* @class Controller
*/
class Controller extends \stdClass
{
* 应用容器.
* @var App
*/
public $app;
* 请求GET参数.
* @var array
*/
public $get = [];
* 当前功能节点.
* @var string
*/
public $node;
* 请求参数对象
* @var Request
*/
public $request;
* 表单CSRF验证状态
* @var bool
*/
public $csrf_state = false;
* 表单CSRF验证消息.
* @var string
*/
public $csrf_message;
* Constructor.
*/
public function __construct(App $app)
{
if (in_array($app->request->action(), get_class_methods(__CLASS__))) {
$this->error('禁止访问内置方法!');
}
$this->get = $app->request->get();
$this->app = $app->bind('think\admin\Controller', $this);
$this->node = NodeService::getCurrent();
$this->request = $this->app->request;
$this->initialize();
}
* 返回失败的内容.
* @param mixed $info 消息内容
* @param mixed $data 返回数据
* @param mixed $code 返回代码
*/
public function error($info, $data = '{-null-}', $code = 0): void
{
$this->success($info, $data, $code);
}
* 返回成功的内容.
* @param mixed $info 消息内容
* @param mixed $data 返回数据
* @param mixed $code 返回代码
*/
public function success($info, $data = '{-null-}', $code = 1): void
{
if ($data === '{-null-}') {
$data = new \stdClass();
}
$result = ['code' => $code, 'info' => is_string($info) ? lang($info) : $info, 'data' => $data];
if (JwtExtend::isRejwt()) {
$result['token'] = JwtExtend::token();
}
throw new HttpResponseException(json($result));
}
* URL重定向.
* @param string $url 跳转链接
* @param int $code 跳转代码
*/
public function redirect(string $url, int $code = 302): void
{
throw new HttpResponseException(redirect($url, $code));
}
* 返回视图内容.
* @param string $tpl 模板名称
* @param array $vars 模板变量
* @param null|string $node 授权节点
*/
public function fetch(string $tpl = '', array $vars = [], ?string $node = null): void
{
if (JwtExtend::$sessionId) {
JwtExtend::fetch($this, $vars);
} else {
foreach ($this as $name => $value) {
$vars[$name] = $value;
}
if ($this->csrf_state) {
TokenHelper::fetch($tpl, $vars, $node);
} else {
throw new HttpResponseException(view($tpl, $vars));
}
}
}
* 模板变量赋值
* @param mixed $name 要显示的模板变量
* @param mixed $value 变量的值
* @return $this
*/
public function assign($name, $value = ''): Controller
{
if (is_string($name)) {
$this->{$name} = $value;
} elseif (is_array($name)) {
foreach ($name as $k => $v) {
if (is_string($k)) {
$this->{$k} = $v;
}
}
}
return $this;
}
* 数据回调处理机制.
* @param string $name 回调方法名称
* @param mixed $one 回调引用参数1
* @param mixed $two 回调引用参数2
* @param mixed $thr 回调引用参数3
*/
public function callback(string $name, &$one = [], &$two = [], &$thr = []): bool
{
if (is_callable($name)) {
return call_user_func($name, $this, $one, $two, $thr);
}
foreach (["_{$this->app->request->action()}{$name}", $name] as $method) {
if (method_exists($this, $method) && $this->{$method}($one, $two, $thr) === false) {
return false;
}
}
return true;
}
* 控制器初始化.
*/
protected function initialize() {}
* 快捷查询逻辑器.
* @param BaseQuery|Model|string $dbQuery
* @param null|array|string $input
* @throws DbException
*/
protected function _query($dbQuery, $input = null): QueryHelper
{
return QueryHelper::instance()->init($dbQuery, $input);
}
* 快捷分页逻辑器.
* @param BaseQuery|Model|string $dbQuery
* @param bool|int $page 是否分页或指定分页
* @param bool $display 是否渲染模板
* @param bool|int $total 集合分页记录数
* @param int $limit 集合每页记录数
* @param string $template 模板文件名称
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
protected function _page($dbQuery, $page = true, bool $display = true, $total = false, int $limit = 0, string $template = ''): array
{
return PageHelper::instance()->init($dbQuery, $page, $display, $total, $limit, $template);
}
* 快捷表单逻辑器.
* @param BaseQuery|Model|string $dbQuery
* @param string $template 模板名称
* @param string $field 指定数据主键
* @param mixed $where 额外更新条件
* @param array $data 表单扩展数据
* @return array|bool
* @throws Exception
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
protected function _form($dbQuery, string $template = '', string $field = '', $where = [], array $data = [])
{
return FormHelper::instance()->init($dbQuery, $template, $field, $where, $data);
}
* 快捷输入并验证( 支持 规则 # 别名 ).
* @param array $rules 验证规则( 验证信息数组 )
* @param array|string $type 输入方式 ( post. 或 get. )
* @param null|callable $callable 异常处理操作
*/
protected function _vali(array $rules, $type = '', ?callable $callable = null): array
{
return ValidateHelper::instance()->init($rules, $type, $callable);
}
* 快捷更新逻辑器.
* @param BaseQuery|Model|string $dbQuery
* @param array $data 表单扩展数据
* @param string $field 数据对象主键
* @param mixed $where 额外更新条件
* @throws DbException
*/
protected function _save($dbQuery, array $data = [], string $field = '', $where = []): bool
{
return SaveHelper::instance()->init($dbQuery, $data, $field, $where);
}
* 快捷删除逻辑器.
* @param BaseQuery|Model|string $dbQuery
* @param string $field 数据对象主键
* @param mixed $where 额外更新条件
* @throws DbException
*/
protected function _delete($dbQuery, string $field = '', $where = []): bool
{
return DeleteHelper::instance()->init($dbQuery, $field, $where);
}
* 检查表单令牌验证
* @param bool $return 是否返回结果
*/
protected function _applyFormToken(bool $return = false): bool
{
return TokenHelper::instance()->init($return);
}
* 创建异步任务并返回任务编号.
* @param string $title 任务名称
* @param string $command 执行内容
* @param int $later 延时执行时间
* @param array $data 任务附加数据
* @param int $rscript 任务类型(0单例,1多例)
* @param int $loops 循环等待时间
*/
protected function _queue(string $title, string $command, int $later = 0, array $data = [], int $rscript = 0, int $loops = 0)
{
try {
$queue = QueueService::register($title, $command, $later, $data, $rscript, $loops);
$this->success('创建任务成功!', $queue->code);
} catch (Exception $exception) {
$code = $exception->getData();
if (is_string($code) && stripos($code, 'Q') === 0) {
$this->success('任务已经存在,无需再次创建!', $code);
} else {
$this->error($exception->getMessage());
}
} catch (HttpResponseException $exception) {
throw $exception;
} catch (\Exception $exception) {
trace_file($exception);
$this->error(lang('创建任务失败,%s', [$exception->getMessage()]));
}
}
}