Controller.php 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | Library for ThinkAdmin
  4. // +----------------------------------------------------------------------
  5. // | 版权所有 2014~2021 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
  6. // +----------------------------------------------------------------------
  7. // | 官方网站: https://gitee.com/zoujingli/ThinkLibrary
  8. // +----------------------------------------------------------------------
  9. // | 开源协议 ( https://mit-license.org )
  10. // +----------------------------------------------------------------------
  11. // | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
  12. // | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
  13. // +----------------------------------------------------------------------
  14. declare (strict_types=1);
  15. namespace think\admin;
  16. use stdClass;
  17. use think\admin\helper\DeleteHelper;
  18. use think\admin\helper\FormHelper;
  19. use think\admin\helper\PageHelper;
  20. use think\admin\helper\QueryHelper;
  21. use think\admin\helper\SaveHelper;
  22. use think\admin\helper\TokenHelper;
  23. use think\admin\helper\ValidateHelper;
  24. use think\admin\service\QueueService;
  25. use think\App;
  26. use think\db\BaseQuery;
  27. use think\db\exception\DataNotFoundException;
  28. use think\db\exception\DbException;
  29. use think\db\exception\ModelNotFoundException;
  30. use think\exception\HttpResponseException;
  31. use think\Model;
  32. use think\Request;
  33. /**
  34. * 标准控制器基类
  35. * Class Controller
  36. * @package think\admin
  37. */
  38. abstract class Controller extends stdClass
  39. {
  40. /**
  41. * 应用容器
  42. * @var App
  43. */
  44. public $app;
  45. /**
  46. * 请求对象
  47. * @var Request
  48. */
  49. public $request;
  50. /**
  51. * 表单CSRF验证状态
  52. * @var boolean
  53. */
  54. public $csrf_state = false;
  55. /**
  56. * 表单CSRF验证消息
  57. * @var string
  58. */
  59. public $csrf_message;
  60. /**
  61. * Controller constructor.
  62. * @param App $app
  63. */
  64. public function __construct(App $app)
  65. {
  66. $this->app = $app;
  67. $this->request = $app->request;
  68. $this->app->bind('think\admin\Controller', $this);
  69. // 过滤基础方法访问
  70. if (in_array($this->request->action(), get_class_methods(__CLASS__))) {
  71. $this->error('Access without permission.');
  72. }
  73. $this->initialize();
  74. }
  75. /**
  76. * 控制器初始化
  77. */
  78. protected function initialize()
  79. {
  80. }
  81. /**
  82. * 返回失败的操作
  83. * @param mixed $info 消息内容
  84. * @param mixed $data 返回数据
  85. * @param mixed $code 返回代码
  86. */
  87. public function error($info, $data = '{-null-}', $code = 0): void
  88. {
  89. if ($data === '{-null-}') $data = new stdClass();
  90. throw new HttpResponseException(json([
  91. 'code' => $code, 'info' => $info, 'data' => $data,
  92. ]));
  93. }
  94. /**
  95. * 返回成功的操作
  96. * @param mixed $info 消息内容
  97. * @param mixed $data 返回数据
  98. * @param mixed $code 返回代码
  99. */
  100. public function success($info, $data = '{-null-}', $code = 1): void
  101. {
  102. if ($this->csrf_state) {
  103. TokenHelper::instance()->clear();
  104. }
  105. if ($data === '{-null-}') $data = new stdClass();
  106. throw new HttpResponseException(json([
  107. 'code' => $code, 'info' => $info, 'data' => $data,
  108. ]));
  109. }
  110. /**
  111. * URL重定向
  112. * @param string $url 跳转链接
  113. * @param integer $code 跳转代码
  114. */
  115. public function redirect(string $url, int $code = 301): void
  116. {
  117. throw new HttpResponseException(redirect($url, $code));
  118. }
  119. /**
  120. * 返回视图内容
  121. * @param string $tpl 模板名称
  122. * @param array $vars 模板变量
  123. * @param null|string $node 授权节点
  124. */
  125. public function fetch(string $tpl = '', array $vars = [], ?string $node = null): void
  126. {
  127. foreach ($this as $name => $value) $vars[$name] = $value;
  128. if ($this->csrf_state) {
  129. TokenHelper::instance()->fetchTemplate($tpl, $vars, $node);
  130. } else {
  131. throw new HttpResponseException(view($tpl, $vars));
  132. }
  133. }
  134. /**
  135. * 模板变量赋值
  136. * @param mixed $name 要显示的模板变量
  137. * @param mixed $value 变量的值
  138. * @return $this
  139. */
  140. public function assign($name, $value = ''): Controller
  141. {
  142. if (is_string($name)) {
  143. $this->$name = $value;
  144. } elseif (is_array($name)) {
  145. foreach ($name as $k => $v) {
  146. if (is_string($k)) $this->$k = $v;
  147. }
  148. }
  149. return $this;
  150. }
  151. /**
  152. * 数据回调处理机制
  153. * @param string $name 回调方法名称
  154. * @param mixed $one 回调引用参数1
  155. * @param mixed $two 回调引用参数2
  156. * @param mixed $thr 回调引用参数3
  157. * @return boolean
  158. */
  159. public function callback(string $name, &$one = [], &$two = [], &$thr = []): bool
  160. {
  161. if (is_callable($name)) return call_user_func($name, $this, $one, $two, $thr);
  162. foreach (["_{$this->app->request->action()}{$name}", $name] as $method) {
  163. if (method_exists($this, $method) && false === $this->$method($one, $two, $thr)) {
  164. return false;
  165. }
  166. }
  167. return true;
  168. }
  169. /**
  170. * 快捷查询逻辑器
  171. * @param Model|BaseQuery|string $dbQuery
  172. * @param array|string|null $input
  173. * @return QueryHelper
  174. * @throws DbException
  175. */
  176. protected function _query($dbQuery, $input = null): QueryHelper
  177. {
  178. return QueryHelper::instance()->init($dbQuery, $input);
  179. }
  180. /**
  181. * 快捷分页逻辑器
  182. * @param Model|BaseQuery|string $dbQuery
  183. * @param boolean $page 是否启用分页
  184. * @param boolean $display 是否渲染模板
  185. * @param boolean|integer $total 集合分页记录数
  186. * @param integer $limit 集合每页记录数
  187. * @param string $template 模板文件名称
  188. * @return array
  189. * @throws DataNotFoundException
  190. * @throws DbException
  191. * @throws ModelNotFoundException
  192. */
  193. protected function _page($dbQuery, bool $page = true, bool $display = true, $total = false, int $limit = 0, string $template = ''): array
  194. {
  195. return PageHelper::instance()->init($dbQuery, $page, $display, $total, $limit, $template);
  196. }
  197. /**
  198. * 快捷表单逻辑器
  199. * @param Model|BaseQuery|string $dbQuery
  200. * @param string $template 模板名称
  201. * @param string $field 指定数据对象主键
  202. * @param array $where 额外更新条件
  203. * @param array $data 表单扩展数据
  204. * @return array|boolean
  205. * @throws DataNotFoundException
  206. * @throws DbException
  207. * @throws ModelNotFoundException
  208. */
  209. protected function _form($dbQuery, string $template = '', string $field = '', array $where = [], array $data = [])
  210. {
  211. return FormHelper::instance()->init($dbQuery, $template, $field, $where, $data);
  212. }
  213. /**
  214. * 快捷输入并验证( 支持 规则 # 别名 )
  215. * @param array $rules 验证规则( 验证信息数组 )
  216. * @param string|array $type 输入方式 ( post. 或 get. )
  217. * @return array
  218. */
  219. protected function _vali(array $rules, $type = ''): array
  220. {
  221. return ValidateHelper::instance()->init($rules, $type);
  222. }
  223. /**
  224. * 快捷更新逻辑器
  225. * @param Model|BaseQuery|string $dbQuery
  226. * @param array $data 表单扩展数据
  227. * @param string $field 数据对象主键
  228. * @param array $where 额外更新条件
  229. * @return boolean
  230. * @throws DbException
  231. */
  232. protected function _save($dbQuery, array $data = [], string $field = '', array $where = []): bool
  233. {
  234. return SaveHelper::instance()->init($dbQuery, $data, $field, $where);
  235. }
  236. /**
  237. * 快捷删除逻辑器
  238. * @param Model|BaseQuery|string $dbQuery
  239. * @param string $field 数据对象主键
  240. * @param array $where 额外更新条件
  241. * @return boolean|null
  242. * @throws DbException
  243. */
  244. protected function _delete($dbQuery, string $field = '', array $where = []): ?bool
  245. {
  246. return DeleteHelper::instance()->init($dbQuery, $field, $where);
  247. }
  248. /**
  249. * 检查表单令牌验证
  250. * @param boolean $return 是否返回结果
  251. * @return boolean
  252. */
  253. protected function _applyFormToken(bool $return = false): bool
  254. {
  255. return TokenHelper::instance()->init($return);
  256. }
  257. /**
  258. * 创建异步任务并返回任务编号
  259. * @param string $title 任务名称
  260. * @param string $command 执行内容
  261. * @param integer $later 延时执行时间
  262. * @param array $data 任务附加数据
  263. * @param integer $rscript 任务类型(0单例,1多例)
  264. * @param integer $loops 循环等待时间
  265. */
  266. protected function _queue(string $title, string $command, int $later = 0, array $data = [], int $rscript = 0, int $loops = 0)
  267. {
  268. try {
  269. $queue = QueueService::instance()->register($title, $command, $later, $data, $rscript, $loops);
  270. $this->success('创建任务成功!', $queue->code);
  271. } catch (Exception $exception) {
  272. $code = $exception->getData();
  273. if (is_string($code) && stripos($code, 'Q') === 0) {
  274. $this->success('任务已经存在,无需再次创建!', $code);
  275. } else {
  276. $this->error($exception->getMessage());
  277. }
  278. } catch (HttpResponseException $exception) {
  279. throw $exception;
  280. } catch (\Exception $exception) {
  281. $this->error("创建任务失败,{$exception->getMessage()}");
  282. }
  283. }
  284. }