DocsController.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. <?php
  2. namespace App\Http\Controllers\Api;
  3. use App\Http\Controllers\Controller;
  4. use App\Module\Base;
  5. use App\Module\Docs;
  6. use App\Module\Users;
  7. use App\Tasks\PushTask;
  8. use Cache;
  9. use DB;
  10. use Hhxsv5\LaravelS\Swoole\Task\Task;
  11. use Request;
  12. /**
  13. * @apiDefine docs
  14. *
  15. * 知识库
  16. */
  17. class DocsController extends Controller
  18. {
  19. public function __invoke($method, $action = '')
  20. {
  21. $app = $method ? $method : 'main';
  22. if ($action) {
  23. $app .= "__" . $action;
  24. }
  25. return (method_exists($this, $app)) ? $this->$app() : Base::ajaxError("404 not found (" . str_replace("__", "/", $app) . ").");
  26. }
  27. /**
  28. * 知识库列表
  29. *
  30. * @apiParam {Number} [page] 当前页,默认:1
  31. * @apiParam {Number} [pagesize] 每页显示数量,默认:20,最大:100
  32. */
  33. public function book__lists()
  34. {
  35. $user = Users::authE();
  36. if (Base::isError($user)) {
  37. return $user;
  38. } else {
  39. $user = $user['data'];
  40. }
  41. //
  42. $lists = DB::table('docs_book')
  43. ->where('role_edit', 'reg')
  44. ->orWhere(function ($query) use ($user) {
  45. $query->where('role_edit', 'private')->where('username', $user['username']);
  46. })
  47. ->orWhere(function ($query) use ($user) {
  48. $query->where('role_edit', 'member')->whereIn('id', function ($query2) use ($user) {
  49. $query2->select('bookid')
  50. ->from('docs_users')
  51. ->where('username', $user['username'])
  52. ->whereRaw(env('DB_PREFIX') . 'docs_book.id = bookid');
  53. });
  54. })
  55. ->orderByDesc('id')
  56. ->paginate(Min(Max(Base::nullShow(Request::input('pagesize'), 10), 1), 100));
  57. $lists = Base::getPageList($lists);
  58. if ($lists['total'] == 0) {
  59. return Base::retError('暂无知识库', $lists);
  60. }
  61. return Base::retSuccess('success', $lists);
  62. }
  63. /**
  64. * 添加/修改知识库
  65. *
  66. * @apiParam {Number} id 知识库数据ID
  67. * @apiParam {String} title 知识库名称
  68. */
  69. public function book__add()
  70. {
  71. $user = Users::authE();
  72. if (Base::isError($user)) {
  73. return $user;
  74. } else {
  75. $user = $user['data'];
  76. }
  77. //
  78. $id = intval(Request::input('id'));
  79. $title = trim(Request::input('title'));
  80. $role = Docs::checkRole($id, 'edit');
  81. if (Base::isError($role)) {
  82. return $role;
  83. }
  84. if (mb_strlen($title) < 2 || mb_strlen($title) > 100) {
  85. return Base::retError('标题限制2-100个字!');
  86. }
  87. if ($id > 0) {
  88. // 修改
  89. $row = Base::DBC2A(DB::table('docs_book')->where('id', $id)->first());
  90. if (empty($row)) {
  91. return Base::retError('知识库不存在或已被删除!');
  92. }
  93. $data = [
  94. 'title' => $title,
  95. ];
  96. DB::table('docs_book')->where('id', $id)->update($data);
  97. return Base::retSuccess('修改成功!', $data);
  98. } else {
  99. // 添加
  100. $data = [
  101. 'username' => $user['username'],
  102. 'title' => $title,
  103. 'indate' => Base::time(),
  104. ];
  105. $id = DB::table('docs_book')->insertGetId($data);
  106. if (empty($id)) {
  107. return Base::retError('系统繁忙,请稍后再试!');
  108. }
  109. $data['id'] = $id;
  110. return Base::retSuccess('添加成功!', $data);
  111. }
  112. }
  113. /**
  114. * 设置知识库
  115. *
  116. * @apiParam {Number} id 知识库数据ID
  117. * @apiParam {String} role_edit
  118. * @apiParam {String} role_view
  119. */
  120. public function book__setting()
  121. {
  122. $user = Users::authE();
  123. if (Base::isError($user)) {
  124. return $user;
  125. } else {
  126. $user = $user['data'];
  127. }
  128. //
  129. $id = intval(Request::input('id'));
  130. $role = Docs::checkRole($id, 'edit');
  131. if (Base::isError($role)) {
  132. return $role;
  133. }
  134. $row = Base::DBC2A(DB::table('docs_book')->where('id', $id)->first());
  135. if (empty($row)) {
  136. return Base::retError('知识库不存在或已被删除!');
  137. }
  138. $setting = Base::string2array($row['setting']);
  139. $type = trim(Request::input('type'));
  140. if ($type == 'save') {
  141. foreach (Request::input() AS $key => $value) {
  142. if (in_array($key, ['role_edit', 'role_view'])) {
  143. $setting[$key] = $value;
  144. }
  145. }
  146. DB::table('docs_book')->where('id', $id)->update([
  147. 'role_edit' => $setting['role_edit'],
  148. 'role_view' => $setting['role_view'],
  149. 'setting' => Base::array2string($setting),
  150. ]);
  151. }
  152. return Base::retSuccess($type == 'save' ? '修改成功!' : 'success', $setting ?: json_decode('{}'));
  153. }
  154. /**
  155. * 删除知识库
  156. *
  157. * @apiParam {Number} id 知识库数据ID
  158. */
  159. public function book__delete()
  160. {
  161. $user = Users::authE();
  162. if (Base::isError($user)) {
  163. return $user;
  164. } else {
  165. $user = $user['data'];
  166. }
  167. //
  168. $id = intval(Request::input('id'));
  169. $row = Base::DBC2A(DB::table('docs_book')->where('id', $id)->first());
  170. if (empty($row)) {
  171. return Base::retError('知识库不存在或已被删除!');
  172. }
  173. if ($row['username'] != $user['username']) {
  174. return Base::retError('此操作仅限知识库负责人!');
  175. }
  176. DB::table('docs_book')->where('id', $id)->delete();
  177. DB::table('docs_section')->where('bookid', $id)->delete();
  178. DB::table('docs_content')->where('bookid', $id)->delete();
  179. return Base::retSuccess('删除成功!');
  180. }
  181. /**
  182. * 成员-列表
  183. *
  184. * @apiParam {Number} id 知识库数据ID
  185. * @apiParam {Number} [page] 当前页,默认:1
  186. * @apiParam {Number} [pagesize] 每页显示数量,默认:20,最大:100
  187. */
  188. public function users__lists()
  189. {
  190. $user = Users::authE();
  191. if (Base::isError($user)) {
  192. return $user;
  193. } else {
  194. $user = $user['data'];
  195. }
  196. //
  197. $id = intval(Request::input('id'));
  198. $role = Docs::checkRole($id, 'edit');
  199. if (Base::isError($role)) {
  200. return $role;
  201. }
  202. $row = Base::DBC2A(DB::table('docs_book')->where('id', $id)->first());
  203. if (empty($row)) {
  204. return Base::retError('知识库不存在或已被删除!');
  205. }
  206. //
  207. $lists = DB::table('docs_book')
  208. ->join('docs_users', 'docs_book.id', '=', 'docs_users.bookid')
  209. ->select(['docs_book.title', 'docs_users.*'])
  210. ->where([
  211. ['docs_book.id', $id],
  212. ])
  213. ->orderByDesc('docs_users.id')->paginate(Min(Max(Base::nullShow(Request::input('pagesize'), 10), 1), 100));
  214. $lists = Base::getPageList($lists);
  215. if ($lists['total'] == 0) {
  216. return Base::retError('未找到任何相关的成员');
  217. }
  218. foreach ($lists['lists'] AS $key => $item) {
  219. $userInfo = Users::username2basic($item['username']);
  220. $lists['lists'][$key]['userimg'] = $userInfo['userimg'];
  221. $lists['lists'][$key]['nickname'] = $userInfo['nickname'];
  222. $lists['lists'][$key]['profession'] = $userInfo['profession'];
  223. }
  224. return Base::retSuccess('success', $lists);
  225. }
  226. /**
  227. * 成员-添加、删除
  228. *
  229. * @apiParam {String} act
  230. * - delete: 删除成员
  231. * - else: 添加成员
  232. * @apiParam {Number} id 知识库数据ID
  233. * @apiParam {Array|String} username 用户名(或用户名组)
  234. */
  235. public function users__join()
  236. {
  237. $user = Users::authE();
  238. if (Base::isError($user)) {
  239. return $user;
  240. } else {
  241. $user = $user['data'];
  242. }
  243. //
  244. $id = intval(Request::input('id'));
  245. $role = Docs::checkRole($id, 'edit');
  246. if (Base::isError($role)) {
  247. return $role;
  248. }
  249. $row = Base::DBC2A(DB::table('docs_book')->where('id', $id)->first());
  250. if (empty($row)) {
  251. return Base::retError('知识库不存在或已被删除!');
  252. }
  253. //
  254. $usernames = Request::input('username');
  255. if (empty($usernames)) {
  256. return Base::retError('参数错误!');
  257. }
  258. if (!is_array($usernames)) {
  259. if (Base::strExists($usernames, ',')) {
  260. $usernames = explode(',', $usernames);
  261. } else {
  262. $usernames = [$usernames];
  263. }
  264. }
  265. //
  266. foreach ($usernames AS $username) {
  267. $inRow = Base::DBC2A(DB::table('docs_users')->where(['bookid' => $id, 'username' => $username])->first());
  268. switch (Request::input('act')) {
  269. case 'delete': {
  270. if ($inRow) {
  271. DB::table('docs_users')->where([
  272. 'bookid' => $id,
  273. 'username' => $username
  274. ])->delete();
  275. }
  276. break;
  277. }
  278. default: {
  279. if (!$inRow && $username != $user['username']) {
  280. DB::table('docs_users')->insert([
  281. 'bookid' => $id,
  282. 'username' => $username,
  283. 'indate' => Base::time()
  284. ]);
  285. }
  286. break;
  287. }
  288. }
  289. }
  290. return Base::retSuccess('操作完成!');
  291. }
  292. /**
  293. * 章节列表
  294. *
  295. * @apiParam {String} act 请求方式,用于判断权限
  296. * - edit: 管理页请求
  297. * - view: 阅读页请求
  298. * @apiParam {Number} bookid 知识库数据ID
  299. */
  300. public function section__lists()
  301. {
  302. $bookid = intval(Request::input('bookid'));
  303. $role = Docs::checkRole($bookid, Request::input('act'));
  304. if (Base::isError($role)) {
  305. return $role;
  306. }
  307. $lists = Base::DBC2A(DB::table('docs_section')
  308. ->where('bookid', $bookid)
  309. ->orderByDesc('inorder')
  310. ->orderByDesc('id')
  311. ->take(500)
  312. ->get());
  313. if (empty($lists)) {
  314. return Base::retError('暂无章节');
  315. }
  316. foreach ($lists AS $key => $item) {
  317. $lists[$key]['icon'] = Base::fillUrl('images/files/' . $item['type'] . '.png');
  318. }
  319. $bookDetail = Base::DBC2A(DB::table('docs_book')->select(['title'])->where('id', $bookid)->first());
  320. return Base::retSuccess('success', [
  321. 'book' => $bookDetail ?: json_decode('{}'),
  322. 'tree' => Base::list2Tree($lists, 'id', 'parentid')
  323. ]);
  324. }
  325. /**
  326. * 添加/修改章节
  327. *
  328. * @apiParam {Number} bookid 知识库数据ID
  329. * @apiParam {String} title 章节名称
  330. * @apiParam {String} type 章节类型
  331. */
  332. public function section__add()
  333. {
  334. $user = Users::authE();
  335. if (Base::isError($user)) {
  336. return $user;
  337. } else {
  338. $user = $user['data'];
  339. }
  340. //
  341. $bookid = intval(Request::input('bookid'));
  342. $role = Docs::checkRole($bookid, 'edit');
  343. if (Base::isError($role)) {
  344. return $role;
  345. }
  346. $bookRow = Base::DBC2A(DB::table('docs_book')->where('id', $bookid)->first());
  347. if (empty($bookRow)) {
  348. return Base::retError('知识库不存在或已被删除!');
  349. }
  350. $count = DB::table('docs_section')->where('bookid', $bookid)->count();
  351. if ($count >= 500) {
  352. return Base::retError(['知识库章节已经超过最大限制(%)!', 500]);
  353. }
  354. //
  355. $id = intval(Request::input('id'));
  356. $title = trim(Request::input('title'));
  357. $type = trim(Request::input('type'));
  358. if (mb_strlen($title) < 2 || mb_strlen($title) > 100) {
  359. return Base::retError('标题限制2-100个字!');
  360. }
  361. if ($id > 0) {
  362. // 修改
  363. $row = Base::DBC2A(DB::table('docs_section')->where('id', $id)->first());
  364. if (empty($row)) {
  365. return Base::retError('知识库不存在或已被删除!');
  366. }
  367. $data = [
  368. 'title' => $title,
  369. ];
  370. DB::table('docs_section')->where('id', $id)->update($data);
  371. return Base::retSuccess('修改成功!', $data);
  372. } else {
  373. // 添加
  374. if (!in_array($type, ['document', 'mind', 'sheet', 'flow', 'folder'])) {
  375. return Base::retError('参数错误!');
  376. }
  377. $parentid = 0;
  378. if ($id < 0) {
  379. $count = Base::DBC2A(DB::table('docs_section')->where('id', abs($id))->where('bookid', $bookid)->count());
  380. if ($count > 0) {
  381. $parentid = abs($id);
  382. }
  383. }
  384. $data = [
  385. 'bookid' => $bookid,
  386. 'parentid' => $parentid,
  387. 'username' => $user['username'],
  388. 'title' => $title,
  389. 'type' => $type,
  390. 'inorder' => intval(DB::table('docs_section')->select(['inorder'])->where('bookid', $bookid)->orderByDesc('inorder')->value('inorder')) + 1,
  391. 'indate' => Base::time(),
  392. ];
  393. $id = DB::table('docs_section')->insertGetId($data);
  394. if (empty($id)) {
  395. return Base::retError('系统繁忙,请稍后再试!');
  396. }
  397. $data['id'] = $id;
  398. return Base::retSuccess('添加成功!', $data);
  399. }
  400. }
  401. /**
  402. * 排序章节
  403. *
  404. * @apiParam {Number} bookid 知识库数据ID
  405. * @apiParam {String} oldsort 旧排序数据
  406. * @apiParam {String} newsort 新排序数据
  407. */
  408. public function section__sort()
  409. {
  410. $user = Users::authE();
  411. if (Base::isError($user)) {
  412. return $user;
  413. } else {
  414. $user = $user['data'];
  415. }
  416. //
  417. $bookid = intval(Request::input('bookid'));
  418. $role = Docs::checkRole($bookid, 'edit');
  419. if (Base::isError($role)) {
  420. return $role;
  421. }
  422. $bookRow = Base::DBC2A(DB::table('docs_book')->where('id', $bookid)->first());
  423. if (empty($bookRow)) {
  424. return Base::retError('知识库不存在或已被删除!');
  425. }
  426. //
  427. $newSort = explode(";", Request::input('newsort'));
  428. if (count($newSort) == 0) {
  429. return Base::retError('参数错误!');
  430. }
  431. //
  432. $count = count($newSort);
  433. foreach ($newSort AS $sort => $item) {
  434. list($newId, $newParentid) = explode(':', $item);
  435. DB::table('docs_section')->where([
  436. 'id' => $newId,
  437. 'bookid' => $bookid
  438. ])->update([
  439. 'inorder' => $count - intval($sort),
  440. 'parentid' => $newParentid
  441. ]);
  442. }
  443. return Base::retSuccess('保存成功!');
  444. }
  445. /**
  446. * 删除章节
  447. *
  448. * @apiParam {Number} id 章节数据ID
  449. */
  450. public function section__delete()
  451. {
  452. $user = Users::authE();
  453. if (Base::isError($user)) {
  454. return $user;
  455. } else {
  456. $user = $user['data'];
  457. }
  458. //
  459. $id = intval(Request::input('id'));
  460. $row = Base::DBC2A(DB::table('docs_section')->where('id', $id)->first());
  461. if (empty($row)) {
  462. return Base::retError('文档不存在或已被删除!');
  463. }
  464. $role = Docs::checkRole($row['bookid'], 'edit');
  465. if (Base::isError($role)) {
  466. return $role;
  467. }
  468. DB::table('docs_section')->where('parentid', $id)->update([ 'parentid' => $row['parentid'] ]);
  469. DB::table('docs_section')->where('id', $id)->delete();
  470. DB::table('docs_content')->where('sid', $id)->delete();
  471. return Base::retSuccess('删除成功!');
  472. }
  473. /**
  474. * 获取章节内容
  475. *
  476. * @apiParam {String} act 请求方式,用于判断权限
  477. * - edit: 管理页请求
  478. * - view: 阅读页请求
  479. * @apiParam {Number|String} id 章节数据ID(或:章节数据ID-历史数据ID)
  480. */
  481. public function section__content()
  482. {
  483. $id = Request::input('id');
  484. $hid = 0;
  485. if (Base::strExists($id, '-')) {
  486. list($id, $hid) = explode("-", $id);
  487. }
  488. $id = intval($id);
  489. $hid = intval($hid);
  490. $row = Base::DBC2A(DB::table('docs_section')->where('id', $id)->first());
  491. if (empty($row)) {
  492. return Base::retError('文档不存在或已被删除!');
  493. }
  494. $role = Docs::checkRole($row['bookid'], Request::input('act'));
  495. if (Base::isError($role)) {
  496. return $role;
  497. }
  498. $whereArray = [];
  499. if ($hid > 0) {
  500. $whereArray[] = ['id', '=', $hid];
  501. }
  502. $whereArray[] = ['sid', '=', $id];
  503. $cRow = Base::DBC2A(DB::table('docs_content')->select(['id AS hid', 'content'])->where($whereArray)->orderByDesc('id')->first());
  504. if (empty($cRow)) {
  505. $cRow = [ 'hid' => 0, 'content' => '' ];
  506. }
  507. return Base::retSuccess('success', array_merge($row, $cRow));
  508. }
  509. /**
  510. * 获取章节历史内容
  511. *
  512. * @apiParam {Number} id 章节数据ID
  513. */
  514. public function section__history()
  515. {
  516. $user = Users::authE();
  517. if (Base::isError($user)) {
  518. return $user;
  519. } else {
  520. $user = $user['data'];
  521. }
  522. //
  523. $id = intval(Request::input('id'));
  524. $row = Base::DBC2A(DB::table('docs_section')->where('id', $id)->first());
  525. if (empty($row)) {
  526. return Base::retError('文档不存在或已被删除!');
  527. }
  528. $role = Docs::checkRole($row['bookid'], 'view');
  529. if (Base::isError($role)) {
  530. return $role;
  531. }
  532. //
  533. $lists = Base::DBC2A(DB::table('docs_content')
  534. ->where('sid', $id)
  535. ->orderByDesc('id')
  536. ->take(50)
  537. ->get());
  538. if (count($lists) <= 1) {
  539. return Base::retError('暂无历史数据');
  540. }
  541. return Base::retSuccess('success', $lists);
  542. }
  543. /**
  544. * 保存章节内容
  545. *
  546. * @apiParam {Number} id 章节数据ID
  547. * @apiParam {Object} [D] Request Payload 提交
  548. * - content: 内容
  549. */
  550. public function section__save()
  551. {
  552. $user = Users::authE();
  553. if (Base::isError($user)) {
  554. return $user;
  555. } else {
  556. $user = $user['data'];
  557. }
  558. //
  559. $id = intval(Request::input('id'));
  560. $row = Base::DBC2A(DB::table('docs_section')->where('id', $id)->first());
  561. if (empty($row)) {
  562. return Base::retError('文档不存在或已被删除!');
  563. }
  564. $role = Docs::checkRole($row['bookid'], 'edit');
  565. if (Base::isError($role)) {
  566. return $role;
  567. }
  568. if ($row['lockdate'] + 60 > Base::time() && $row['lockname'] != $user['username']) {
  569. return Base::retError(['已被会员【%】锁定!', Users::nickname($row['lockname'])]);
  570. }
  571. $D = Base::getContentsParse('D');
  572. DB::table('docs_content')->insert([
  573. 'bookid' => $row['bookid'],
  574. 'sid' => $id,
  575. 'content' => $D['content'],
  576. 'username' => $user['username'],
  577. 'indate' => Base::time()
  578. ]);
  579. Docs::notice($id, [ 'type' => 'update' ]);
  580. //
  581. return Base::retSuccess('保存成功!');
  582. }
  583. /**
  584. * 保存章节内容
  585. *
  586. * @apiParam {String} act
  587. * - lock: 锁定
  588. * - unlock: 解锁
  589. * @apiParam {Number} id 章节数据ID
  590. */
  591. public function section__lock()
  592. {
  593. $user = Users::authE();
  594. if (Base::isError($user)) {
  595. return $user;
  596. } else {
  597. $user = $user['data'];
  598. }
  599. //
  600. $id = intval(Request::input('id'));
  601. $act = trim(Request::input('act'));
  602. $row = Base::DBC2A(DB::table('docs_section')->where('id', $id)->first());
  603. if (empty($row)) {
  604. return Base::retError('文档不存在或已被删除!');
  605. }
  606. $role = Docs::checkRole($row['bookid'], 'edit');
  607. if (Base::isError($role)) {
  608. return $role;
  609. }
  610. if ($row['lockdate'] + 60 > Base::time() && $row['lockname'] != $user['username']) {
  611. return Base::retError(['已被会员【%】锁定!', Users::nickname($row['lockname'])]);
  612. }
  613. if ($act == 'lock') {
  614. $upArray = [
  615. 'lockname' => $user['username'],
  616. 'lockdate' => Base::time(),
  617. ];
  618. } else {
  619. $upArray = [
  620. 'lockname' => '',
  621. 'lockdate' => 0,
  622. ];
  623. }
  624. DB::table('docs_section')->where('id', $id)->update($upArray);
  625. $upArray['type'] = $act;
  626. Docs::notice($id, $upArray);
  627. //
  628. return Base::retSuccess($act == 'lock' ? '锁定成功' : '已解除锁定', $upArray);
  629. }
  630. }