TicketController.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Controllers\User;
  4. use App\Controllers\BaseController;
  5. use App\Models\Setting;
  6. use App\Models\Ticket;
  7. use App\Models\User;
  8. use App\Utils\Tools;
  9. use Exception;
  10. use Psr\Http\Message\ResponseInterface;
  11. use Slim\Http\Response;
  12. use Slim\Http\ServerRequest;
  13. use voku\helper\AntiXSS;
  14. use function array_merge;
  15. use function count;
  16. use function json_decode;
  17. use function json_encode;
  18. use function time;
  19. /**
  20. * TicketController
  21. */
  22. final class TicketController extends BaseController
  23. {
  24. /**
  25. * @throws Exception
  26. */
  27. public function ticket(ServerRequest $request, Response $response, array $args): ?ResponseInterface
  28. {
  29. if (! Setting::obtain('enable_ticket')) {
  30. return $response->withRedirect('/user');
  31. }
  32. $tickets = Ticket::where('userid', $this->user->id)->orderBy('datetime', 'desc')->get();
  33. foreach ($tickets as $ticket) {
  34. $ticket->status = $ticket->status();
  35. $ticket->type = $ticket->type();
  36. $ticket->datetime = Tools::toDateTime((int) $ticket->datetime);
  37. }
  38. return $response->write(
  39. $this->view()
  40. ->assign('tickets', $tickets)
  41. ->fetch('user/ticket/index.tpl')
  42. );
  43. }
  44. public function ticketAdd(ServerRequest $request, Response $response, array $args): ResponseInterface
  45. {
  46. if (! Setting::obtain('enable_ticket')) {
  47. return $response->withJson([
  48. 'ret' => 0,
  49. 'msg' => '暂时无法开启工单,请稍后再试',
  50. ]);
  51. }
  52. $title = $request->getParam('title') ?? '';
  53. $comment = $request->getParam('comment') ?? '';
  54. $type = $request->getParam('type') ?? '';
  55. if ($this->user->is_shadow_banned) {
  56. return $response->withJson([
  57. 'ret' => 0,
  58. 'msg' => '暂时无法开启工单,请稍后再试',
  59. ]);
  60. }
  61. if ($title === '' || $comment === '' || $type === '') {
  62. return $response->withJson([
  63. 'ret' => 0,
  64. 'msg' => '工单内容不能为空',
  65. ]);
  66. }
  67. $antiXss = new AntiXSS();
  68. $content = [
  69. [
  70. 'comment_id' => 0,
  71. 'commenter_name' => $this->user->user_name,
  72. 'comment' => $antiXss->xss_clean($comment),
  73. 'datetime' => time(),
  74. ],
  75. ];
  76. $ticket = new Ticket();
  77. $ticket->title = $antiXss->xss_clean($title);
  78. $ticket->content = json_encode($content);
  79. $ticket->userid = $this->user->id;
  80. $ticket->datetime = time();
  81. $ticket->status = 'open_wait_admin';
  82. $ticket->type = $antiXss->xss_clean($type);
  83. $ticket->save();
  84. if (Setting::obtain('mail_ticket')) {
  85. $adminUser = User::where('is_admin', 1)->get();
  86. foreach ($adminUser as $user) {
  87. $user->sendMail(
  88. $_ENV['appName'] . '-新工单被开启',
  89. 'warn.tpl',
  90. [
  91. 'text' => '管理员,有人开启了新的工单,请你及时处理。',
  92. ],
  93. []
  94. );
  95. }
  96. }
  97. return $response->withJson([
  98. 'ret' => 1,
  99. 'msg' => '提交成功',
  100. ]);
  101. }
  102. public function ticketUpdate(ServerRequest $request, Response $response, array $args): ResponseInterface
  103. {
  104. if (! Setting::obtain('enable_ticket')) {
  105. return $response->withJson([
  106. 'ret' => 0,
  107. 'msg' => '暂时无法回复工单,请稍后再试',
  108. ]);
  109. }
  110. $id = $args['id'];
  111. $comment = $request->getParam('comment') ?? '';
  112. if ($this->user->is_shadow_banned) {
  113. return $response->withJson([
  114. 'ret' => 0,
  115. 'msg' => '暂时无法回复工单,请稍后再试',
  116. ]);
  117. }
  118. if ($comment === '') {
  119. return $response->withJson([
  120. 'ret' => 0,
  121. 'msg' => '工单回复不能为空',
  122. ]);
  123. }
  124. $ticket = Ticket::where('id', $id)->where('userid', $this->user->id)->first();
  125. if ($ticket === null) {
  126. return $response->withJson([
  127. 'ret' => 0,
  128. 'msg' => '工单不存在',
  129. ]);
  130. }
  131. $antiXss = new AntiXSS();
  132. $content_old = json_decode($ticket->content, true);
  133. $content_new = [
  134. [
  135. 'comment_id' => $content_old[count($content_old) - 1]['comment_id'] + 1,
  136. 'commenter_name' => $this->user->user_name,
  137. 'comment' => $antiXss->xss_clean($comment),
  138. 'datetime' => time(),
  139. ],
  140. ];
  141. $ticket->content = json_encode(array_merge($content_old, $content_new));
  142. $ticket->status = 'open_wait_admin';
  143. $ticket->save();
  144. if (Setting::obtain('mail_ticket')) {
  145. $adminUser = User::where('is_admin', 1)->get();
  146. foreach ($adminUser as $user) {
  147. $user->sendMail(
  148. $_ENV['appName'] . '-工单被回复',
  149. 'warn.tpl',
  150. [
  151. 'text' => '管理员,有人回复了 <a href="' .
  152. $_ENV['baseUrl'] . '/admin/ticket/' . $ticket->id . '/view">#' . $ticket->id .
  153. '</a> 工单,请你及时处理。',
  154. ],
  155. []
  156. );
  157. }
  158. }
  159. return $response->withJson([
  160. 'ret' => 1,
  161. 'msg' => '提交成功',
  162. ]);
  163. }
  164. /**
  165. * @throws Exception
  166. */
  167. public function ticketView(ServerRequest $request, Response $response, array $args): ResponseInterface
  168. {
  169. if (! Setting::obtain('enable_ticket')) {
  170. return $response->withRedirect('/user');
  171. }
  172. $id = $args['id'];
  173. $ticket = Ticket::where('id', '=', $id)->where('userid', $this->user->id)->first();
  174. if ($ticket === null) {
  175. return $response->withRedirect('/user/ticket');
  176. }
  177. $comments = json_decode($ticket->content);
  178. foreach ($comments as $comment) {
  179. $comment->datetime = Tools::toDateTime((int) $comment->datetime);
  180. }
  181. $ticket->status = $ticket->status();
  182. $ticket->type = $ticket->type();
  183. $ticket->datetime = Tools::toDateTime((int) $ticket->datetime);
  184. return $response->write(
  185. $this->view()
  186. ->assign('ticket', $ticket)
  187. ->assign('comments', $comments)
  188. ->fetch('user/ticket/view.tpl')
  189. );
  190. }
  191. }