控制台应用,yzncms本身基于tp5.1框架,里面的队列用不了,bug,坑

Cms.php 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | Yzncms [ 御宅男工作室 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2018 http://yzncms.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: 御宅男 <530765310@qq.com>
  10. // +----------------------------------------------------------------------
  11. // +----------------------------------------------------------------------
  12. // | cms管理
  13. // +----------------------------------------------------------------------
  14. namespace app\admin\controller\cms;
  15. use addons\cms\library\Service;
  16. use app\admin\model\cms\Cms as CmsModel;
  17. use app\admin\model\cms\Page as PageModel;
  18. use app\common\controller\Adminbase;
  19. use think\Db;
  20. class Cms extends Adminbase
  21. {
  22. protected $searchFields = 'id,title';
  23. protected $noNeedRight = ['check_title', 'panl', 'classlist'];
  24. protected function initialize()
  25. {
  26. parent::initialize();
  27. $this->CmsModel = new CmsModel;
  28. $this->cmsConfig = get_addon_config("cms");
  29. $this->assign("cmsConfig", $this->cmsConfig);
  30. }
  31. public function index()
  32. {
  33. $isAdministrator = $this->auth->isAdministrator();
  34. $json = $priv_catids = [];
  35. if (0 !== (int) $this->cmsConfig['site_category_auth']) {
  36. //栏目权限 超级管理员例外
  37. if ($isAdministrator !== true) {
  38. $role_id = $this->auth->roleid;
  39. $priv_result = Db::name('CategoryPriv')->where(['roleid' => $role_id, 'action' => 'init'])->select();
  40. foreach ($priv_result as $_v) {
  41. $priv_catids[] = $_v['catid'];
  42. }
  43. }
  44. }
  45. $categorys = Db::name('Category')->order('listorder DESC, id DESC')->select();
  46. foreach ($categorys as $rs) {
  47. //剔除无子栏目外部链接
  48. if ($rs['type'] == 3 && $rs['child'] == 0) {
  49. continue;
  50. }
  51. if (0 !== (int) $this->cmsConfig['site_category_auth']) {
  52. //只显示有init权限的,超级管理员除外
  53. if ($isAdministrator !== true && !in_array($rs['id'], $priv_catids)) {
  54. $arrchildid = explode(',', $rs['arrchildid']);
  55. $array_intersect = array_intersect($priv_catids, $arrchildid);
  56. if (empty($array_intersect)) {
  57. continue;
  58. }
  59. }
  60. }
  61. $data = [
  62. 'id' => $rs['id'],
  63. 'parentid' => $rs['parentid'],
  64. 'catname' => $rs['catname'],
  65. 'type' => $rs['type'],
  66. ];
  67. //终极栏目
  68. if ($rs['child'] !== 0) {
  69. $data['isParent'] = true;
  70. }
  71. $data['target'] = 'right';
  72. if ($rs['type'] == 2) {
  73. $data['url'] = url('classlist', ['catid' => $rs['id']]);
  74. }
  75. //单页
  76. if ($rs['type'] == 1) {
  77. $data['target'] = 'right';
  78. $data['url'] = url('add', ['catid' => $rs['id']]);
  79. }
  80. $json[] = $data;
  81. }
  82. $this->assign('json', json_encode($json));
  83. return $this->fetch();
  84. }
  85. //栏目信息列表
  86. public function classlist()
  87. {
  88. $catid = $this->request->param('catid/d', 0);
  89. //当前栏目信息
  90. $catInfo = getCategory($catid);
  91. if (empty($catInfo)) {
  92. $this->error('该栏目不存在!');
  93. }
  94. //栏目所属模型
  95. $modelid = $catInfo['modelid'];
  96. if ($this->request->isAjax()) {
  97. //检查模型是否被禁用
  98. if (!getModel($modelid, 'status')) {
  99. $this->error('模型被禁用!');
  100. }
  101. $modelCache = cache("Model");
  102. $tableName = $modelCache[$modelid]['tablename'];
  103. $this->modelClass = Db::name($tableName);
  104. //如果发送的来源是Selectpage,则转发到Selectpage
  105. if ($this->request->request('keyField')) {
  106. return $this->selectpage();
  107. }
  108. list($page, $limit, $where) = $this->buildTableParames();
  109. $conditions = [
  110. ['catid', '=', $catid],
  111. ['status', 'in', [0, 1]],
  112. ];
  113. $total = Db::name($tableName)->where($where)->where($conditions)->count();
  114. $list = Db::name($tableName)->page($page, $limit)->where($where)->where($conditions)->order('listorder DESC, id DESC')->select();
  115. $_list = [];
  116. foreach ($list as $k => $v) {
  117. $v['update_time'] = date('Y-m-d H:i:s', $v['update_time']);
  118. $v['url'] = buildContentUrl($v['catid'], $v['id'], $v['url']);
  119. $_list[] = $v;
  120. }
  121. $result = ["code" => 0, "count" => $total, "data" => $_list];
  122. return json($result);
  123. }
  124. /*移动栏目 复制栏目*/
  125. $tree = new \util\Tree();
  126. $tree->icon = ['&nbsp;&nbsp;&nbsp;│ ', '&nbsp;&nbsp;&nbsp;├─ ', '&nbsp;&nbsp;&nbsp;└─ '];
  127. $tree->nbsp = '&nbsp;&nbsp;&nbsp;';
  128. $categorys = [];
  129. $result = Db::name('category')->order('listorder DESC, id DESC')->select();
  130. foreach ($result as $k => $v) {
  131. if ($v['type'] != 2) {
  132. $v['disabled'] = 'disabled';
  133. }
  134. if ($modelid && $modelid != $v['modelid']) {
  135. $v['disabled'] = 'disabled';
  136. }
  137. //$v['disabled'] = $v['child'] ? 'disabled' : '';
  138. $v['selected'] = $v['id'] == $catid ? 'selected' : '';
  139. $categorys[$k] = $v;
  140. }
  141. $str = "<option value=@id @selected @disabled>@spacer @catname</option>";
  142. $tree->init($categorys);
  143. $string = $tree->getTree(0, $str, $catid);
  144. $this->assign('string', $string);
  145. $this->assign('catid', $catid);
  146. return $this->fetch();
  147. }
  148. //移动文章
  149. public function remove()
  150. {
  151. $this->check_priv('remove');
  152. if ($this->request->isPost()) {
  153. $catid = $this->request->param('catid/d', 0);
  154. if (!$catid) {
  155. $this->error("请指定栏目!");
  156. }
  157. //需要移动的信息ID集合
  158. $ids = $this->request->param('ids/s');
  159. //目标栏目
  160. $tocatid = $this->request->param('tocatid/d', 0);
  161. if ($ids) {
  162. if ($tocatid == $catid) {
  163. $this->error('目标栏目和当前栏目是同一个栏目!');
  164. }
  165. $modelid = getCategory($tocatid, 'modelid');
  166. if (!$modelid) {
  167. $this->error('该模型不存在!');
  168. }
  169. $ids = array_filter(explode('|', $ids), 'intval');
  170. $tableName = Db::name('model')->where('id', $modelid)->where('status', 1)->value('tablename');
  171. if (!$tableName) {
  172. $this->error('模型被冻结不可操作~');
  173. }
  174. if (Db::name(ucwords($tableName))->where('id', 'in', $ids)->update(['catid' => $tocatid])) {
  175. Db::name('Category')->where('id', $catid)->setDec('items', count($ids));
  176. Db::name('Category')->where('id', $tocatid)->setInc('items', count($ids));
  177. $this->success('移动成功~');
  178. } else {
  179. $this->error('移动失败~');
  180. }
  181. } else {
  182. $this->error('请选择需要移动的信息!');
  183. }
  184. }
  185. }
  186. //添加信息
  187. public function add()
  188. {
  189. $this->check_priv('add');
  190. if ($this->request->isPost()) {
  191. $data = $this->request->post();
  192. $catid = intval($data['modelField']['catid']);
  193. if (empty($catid)) {
  194. $this->error("请指定栏目ID!");
  195. }
  196. $category = getCategory($catid);
  197. //dump($data['modelField']);die;
  198. if (empty($category)) {
  199. $this->error('该栏目不存在!');
  200. }
  201. if ($category['type'] == 2) {
  202. //模型类型
  203. if((int)$catid === 17){
  204. //关键词栏目
  205. //进行判断标题是否存在
  206. //不用考虑状态还有指令类型
  207. $one = Db::name('cms_zl')->where([
  208. 'gzxh' => $data['modelField']['gzxh'],
  209. 'title' => $data['modelField']['title'],
  210. ])->find();
  211. if(!empty($one)){
  212. $this->error("该规则下此标题已存在!");
  213. }
  214. if((int)$data['modelField']['is_qj'] == 1){
  215. //是全局
  216. $t_data = [
  217. '全局-非主非副','全局-主词类型','全局-副词类型'
  218. ];
  219. if(!in_array($data['modelField']['title'],$t_data)){
  220. $this->error("标题必须是'全局-非主非副','全局-主词类型','全局-副词类型'其中一个!");
  221. }
  222. }
  223. }
  224. $data['modelFieldExt'] = $data['modelFieldExt'] ?? [];
  225. try {
  226. $this->CmsModel->addModelData($data['modelField'], $data['modelFieldExt']);
  227. } catch (\Exception $ex) {
  228. $this->error($ex->getMessage());
  229. }
  230. } elseif ($category['type'] == 1) {
  231. $PageModel = new PageModel;
  232. if (!$PageModel->savePage($data['modelField'])) {
  233. $error = $PageModel->getError();
  234. $this->error($error ? $error : '操作失败!');
  235. }
  236. }
  237. $this->success('操作成功!');
  238. } else {
  239. $catid = $this->request->param('catid/d', 0);
  240. $category = getCategory($catid);
  241. if (empty($category)) {
  242. $this->error('该栏目不存在!');
  243. }
  244. if ($category['type'] == 2) {
  245. $modelid = $category['modelid'];
  246. $fieldList = Service::getFieldList($modelid);
  247. $this->assign([
  248. 'catid' => $catid,
  249. 'fieldList' => $fieldList,
  250. ]);
  251. return $this->fetch();
  252. } elseif ($category['type'] == 1) {
  253. $PageModel = new PageModel;
  254. $info = $PageModel->getPage($catid);
  255. $this->assign([
  256. 'info' => $info,
  257. 'catid' => $catid,
  258. ]);
  259. return $this->fetch('singlepage');
  260. }
  261. }
  262. }
  263. //编辑信息
  264. public function edit()
  265. {
  266. $this->check_priv('edit');
  267. if ($this->request->isPost()) {
  268. $data = $this->request->post();
  269. $data['modelFieldExt'] = $data['modelFieldExt'] ?? [];
  270. //模型类型
  271. if((int)$data['modelField']['catid'] === 17){
  272. if((int)$data['modelField']['is_qj'] == 1){
  273. //是全局
  274. $t_data = [
  275. '全局-非主非副','全局-主词类型','全局-副词类型'
  276. ];
  277. if(!in_array($data['modelField']['title'],$t_data)){
  278. $this->error("标题必须是'全局-非主非副','全局-主词类型','全局-副词类型'其中一个!");
  279. }
  280. }
  281. }
  282. try {
  283. $this->CmsModel->editModelData($data['modelField'], $data['modelFieldExt']);
  284. } catch (\Exception $ex) {
  285. $this->error($ex->getMessage());
  286. }
  287. $this->success('编辑成功!');
  288. } else {
  289. $catid = $this->request->param('catid/d', 0);
  290. $id = $this->request->param('id/d', 0);
  291. $category = getCategory($catid);
  292. if (empty($category)) {
  293. $this->error('该栏目不存在!');
  294. }
  295. if ($category['type'] == 2) {
  296. $modelid = $category['modelid'];
  297. $fieldList = Service::getFieldList($modelid, $id);
  298. $this->assign([
  299. 'catid' => $catid,
  300. 'id' => $id,
  301. 'fieldList' => $fieldList,
  302. ]);
  303. return $this->fetch();
  304. } else {
  305. return $this->fetch('singlepage');
  306. }
  307. }
  308. }
  309. //删除
  310. public function del()
  311. {
  312. $this->check_priv('delete');
  313. $catid = $this->request->param('catid/d', 0);
  314. $ids = $this->request->param('id/a', null);
  315. if (empty($ids) || !$catid) {
  316. $this->error('参数错误!');
  317. }
  318. if (!is_array($ids)) {
  319. $ids = [0 => $ids];
  320. }
  321. $modelid = getCategory($catid, 'modelid');
  322. try {
  323. foreach ($ids as $id) {
  324. $this->CmsModel->deleteModelData($modelid, $id, $this->cmsConfig['web_site_recycle']);
  325. }
  326. } catch (\Exception $ex) {
  327. $this->error($ex->getMessage());
  328. }
  329. $this->success('删除成功!');
  330. }
  331. //清空回收站
  332. public function destroy()
  333. {
  334. $catid = $this->request->param('catid/d', 0);
  335. $ids = $this->request->param('id/a', null);
  336. if (empty($ids) || !$catid) {
  337. $this->error('参数错误!');
  338. }
  339. if (!is_array($ids)) {
  340. $ids = [0 => $ids];
  341. }
  342. $modelid = getCategory($catid, 'modelid');
  343. try {
  344. foreach ($ids as $id) {
  345. $this->CmsModel->deleteModelData($modelid, $id);
  346. }
  347. } catch (\Exception $ex) {
  348. $this->error($ex->getMessage());
  349. }
  350. $this->success('销毁成功!');
  351. }
  352. //面板
  353. public function panl()
  354. {
  355. if ($this->request->isPost()) {
  356. $date = $this->request->post('date');
  357. list($xAxisData, $seriesData) = $this->getAdminPostData($date);
  358. $this->success('', '', ['xAxisData' => $xAxisData, 'seriesData' => $seriesData]);
  359. } else {
  360. $info['category'] = Db::name('Category')->count();
  361. $info['model'] = Db::name('Model')->where(['module' => 'cms'])->count();
  362. $info['tags'] = Db::name('Tags')->count();
  363. $info['doc'] = Db::name('Category')->where('type', 2)->sum('items');
  364. list($xAxisData, $seriesData) = $this->getAdminPostData();
  365. $this->assign('xAxisData', $xAxisData);
  366. $this->assign('seriesData', $seriesData);
  367. $this->assign('info', $info);
  368. return $this->fetch();
  369. }
  370. }
  371. protected function getAdminPostData($date = '')
  372. {
  373. if ($date) {
  374. list($start, $end) = explode(' - ', $date);
  375. $start_time = strtotime($start);
  376. $end_time = strtotime($end);
  377. } else {
  378. $start_time = \util\Date::unixtime('day', 0, 'begin');
  379. $end_time = \util\Date::unixtime('day', 0, 'end');
  380. }
  381. $diff_time = $end_time - $start_time;
  382. $format = '%Y-%m-%d';
  383. if ($diff_time > 86400 * 30 * 2) {
  384. $format = '%Y-%m';
  385. } else {
  386. if ($diff_time > 86400) {
  387. $format = '%Y-%m-%d';
  388. } else {
  389. $format = '%H:00';
  390. }
  391. }
  392. //获取所有表名
  393. $models = Db::name('model')->where(['module' => 'cms', 'status' => 1])->select();
  394. $list = $xAxisData = $seriesData = [];
  395. if (count($models) > 0) {
  396. $table1 = $models[0]['tablename'];
  397. unset($models[0]);
  398. $field = 'a.username,uid,FROM_UNIXTIME(b.create_time, "' . $format . '") as create_times,COUNT(*) AS num';
  399. $dbObj = Db::name($table1)->alias('b')->field($field)->where('b.create_time', 'between time', [$start_time, $end_time])->join('admin a', 'a.id = b.uid');
  400. foreach ($models as $k => $v) {
  401. $dbObj->union(function ($query) use ($field, $start_time, $end_time, $v) {
  402. $query->name($v['tablename'])->alias('b')->field($field)->where('b.create_time', 'between time', [$start_time, $end_time])->join('admin a', 'a.id = b.uid')->group('uid,create_times');
  403. });
  404. };
  405. $res = $dbObj->group('uid,create_times')->select();
  406. if ($diff_time > 84600 * 30 * 2) {
  407. $start_time = strtotime('last month', $start_time);
  408. while (($start_time = strtotime('next month', $start_time)) <= $end_time) {
  409. $column[] = date('Y-m', $start_time);
  410. }
  411. } else {
  412. if ($diff_time > 86400) {
  413. for ($time = $start_time; $time <= $end_time;) {
  414. $column[] = date("Y-m-d", $time);
  415. $time += 86400;
  416. }
  417. } else {
  418. for ($time = $start_time; $time <= $end_time;) {
  419. $column[] = date("H:00", $time);
  420. $time += 3600;
  421. }
  422. }
  423. }
  424. $xAxisData = array_fill_keys($column, 0);
  425. foreach ($res as $k => $v) {
  426. if (!isset($list[$v['username']])) {
  427. $list[$v['username']] = $xAxisData;
  428. }
  429. $list[$v['username']][$v['create_times']] = $v['num'];
  430. }
  431. foreach ($list as $index => $item) {
  432. $seriesData[] = [
  433. 'name' => $index,
  434. 'type' => 'line',
  435. 'smooth' => true,
  436. 'areaStyle' => [],
  437. 'data' => array_values($item),
  438. ];
  439. }
  440. }
  441. return [array_keys($xAxisData), $seriesData];
  442. }
  443. /**
  444. * 排序
  445. */
  446. public function listorder()
  447. {
  448. $this->check_priv('listorder');
  449. $catid = $this->request->param('catid/d', 0);
  450. $id = $this->request->param('id/d', 0);
  451. $listorder = $this->request->param('value/d', 0);
  452. $modelid = getCategory($catid, 'modelid');
  453. $modelCache = cache("Model");
  454. if (empty($modelCache[$modelid])) {
  455. return false;
  456. };
  457. $tableName = $modelCache[$modelid]['tablename'];
  458. if (Db::name($tableName)->where('id', $id)->update(['listorder' => $listorder])) {
  459. $this->success("排序成功!");
  460. } else {
  461. $this->error("排序失败!");
  462. }
  463. }
  464. //回收站
  465. public function recycle()
  466. {
  467. $catid = $this->request->param('catid/d', 0);
  468. //当前栏目信息
  469. $catInfo = getCategory($catid);
  470. if (empty($catInfo)) {
  471. $this->error('该栏目不存在!');
  472. }
  473. //栏目所属模型
  474. $modelid = $catInfo['modelid'];
  475. if ($this->request->isAjax()) {
  476. $modelCache = cache("Model");
  477. $tableName = $modelCache[$modelid]['tablename'];
  478. $this->modelClass = Db::name($tableName);
  479. list($page, $limit, $where) = $this->buildTableParames();
  480. $conditions = [
  481. ['catid', '=', $catid],
  482. ['status', '=', -1],
  483. ];
  484. $total = Db::name($tableName)->where($where)->where($conditions)->count();
  485. $_list = Db::name($tableName)->where($where)->page($page, $limit)->where($conditions)->order('listorder DESC, id DESC')->select();
  486. $result = ["code" => 0, "count" => $total, "data" => $_list];
  487. return json($result);
  488. }
  489. $this->assign('catid', $catid);
  490. return $this->fetch();
  491. }
  492. //还原回收站
  493. public function restore()
  494. {
  495. $catid = $this->request->param('catid/d', 0);
  496. //当前栏目信息
  497. $catInfo = getCategory($catid);
  498. if (empty($catInfo)) {
  499. $this->error('该栏目不存在!');
  500. }
  501. //栏目所属模型
  502. $modelid = $catInfo['modelid'];
  503. $ids = $this->request->param('id/a');
  504. $modelInfo = cache('Model');
  505. $modelInfo = $modelInfo[$modelid];
  506. if ($ids) {
  507. if (!is_array($ids)) {
  508. $ids = [0 => $ids];
  509. }
  510. Db::name($modelInfo['tablename'])->where('id', 'in', $ids)->setField('status', 1);
  511. }
  512. $this->success('还原成功!');
  513. }
  514. //状态
  515. public function setstate()
  516. {
  517. $this->check_priv('status');
  518. $catid = $this->request->param('catid/d', 0);
  519. $id = $this->request->param('id/d', 0);
  520. $status = $this->request->param('value/d');
  521. $modelid = getCategory($catid, 'modelid');
  522. $modelCache = cache("Model");
  523. if (empty($modelCache[$modelid])) {
  524. return false;
  525. };
  526. $tableName = ucwords($modelCache[$modelid]['tablename']);
  527. if (Db::name($tableName)->where('id', $id)->update(['status' => $status])) {
  528. //更新栏目缓存
  529. cache('Category', null);
  530. getCategory($id, '', true);
  531. $data = Db::name($tableName)->where('id', $id)->find();
  532. //标签
  533. hook('content_edit_end', $data);
  534. $this->success('操作成功!');
  535. } else {
  536. $this->error('操作失败!');
  537. }
  538. }
  539. public function check_title()
  540. {
  541. $title = $this->request->param('data/s', '');
  542. $catid = $this->request->param('catid/d', 0);
  543. $id = $this->request->param('id/d', 0);
  544. if (empty($title)) {
  545. $this->success('标题没有重复!');
  546. return false;
  547. }
  548. $modelid = getCategory($catid, 'modelid');
  549. $modelCache = cache("Model");
  550. if (empty($modelCache[$modelid])) {
  551. $this->error('模型不存在!');
  552. return false;
  553. };
  554. $tableName = ucwords($modelCache[$modelid]['tablename']);
  555. $repeat = Db::name($tableName)->where('title', $title);
  556. empty($id) ?: $repeat->where('id', '<>', $id);
  557. if ($repeat->find()) {
  558. $this->error('标题有重复!');
  559. } else {
  560. $this->success('标题没有重复!');
  561. }
  562. }
  563. //批量更新
  564. public function multi()
  565. {
  566. // 管理员禁止批量操作
  567. $this->error();
  568. }
  569. protected function check_priv($action)
  570. {
  571. if ($this->auth->isAdministrator() !== true) {
  572. if (0 !== (int) $this->cmsConfig['site_category_auth']) {
  573. $catid = $this->request->param('catid/d', 0);
  574. $action = getCategory($catid, 'type') == 1 ? 'init' : $action;
  575. $priv_datas = Db::name('CategoryPriv')->where(['catid' => $catid, 'is_admin' => 1, 'roleid' => $this->auth->roleid, 'action' => $action])->find();
  576. if (empty($priv_datas)) {
  577. $this->error('您没有操作该项的权限!');
  578. }
  579. }
  580. }
  581. }
  582. }