TicketController.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Controllers\Admin;
  4. use App\Controllers\BaseController;
  5. use App\Models\Ticket;
  6. use App\Models\User;
  7. use App\Utils\Tools;
  8. use Slim\Http\Request;
  9. use Slim\Http\Response;
  10. use voku\helper\AntiXSS;
  11. final class TicketController extends BaseController
  12. {
  13. public static $details =
  14. [
  15. 'field' => [
  16. 'op' => '操作',
  17. 'id' => '工单ID',
  18. 'title' => '主题',
  19. 'status' => '工单状态',
  20. 'type' => '工单类型',
  21. 'userid' => '提交用户',
  22. 'datetime' => '创建时间',
  23. ],
  24. ];
  25. /**
  26. * 后台工单页面
  27. *
  28. * @param array $args
  29. */
  30. public function index(Request $request, Response $response, array $args)
  31. {
  32. return $response->write(
  33. $this->view()
  34. ->assign('details', self::$details)
  35. ->display('admin/ticket/index.tpl')
  36. );
  37. }
  38. /**
  39. * 后台 更新工单内容
  40. *
  41. * @param array $args
  42. */
  43. public function update(Request $request, Response $response, array $args)
  44. {
  45. $id = $args['id'];
  46. $comment = $request->getParam('comment');
  47. if ($comment === '') {
  48. return $response->withJson([
  49. 'ret' => 0,
  50. 'msg' => '非法输入',
  51. ]);
  52. }
  53. $ticket = Ticket::where('id', $id)->first();
  54. if ($ticket === null) {
  55. return $response->withStatus(302)->withHeader('Location', '/admin/ticket');
  56. }
  57. $antiXss = new AntiXSS();
  58. $content_old = \json_decode($ticket->content, true);
  59. $content_new = [
  60. [
  61. 'comment_id' => $content_old[count($content_old) - 1]['comment_id'] + 1,
  62. 'commenter_name' => 'Admin',
  63. 'comment' => $antiXss->xss_clean($comment),
  64. 'datetime' => \time(),
  65. ],
  66. ];
  67. $user = User::find($ticket->userid);
  68. $user->sendMail(
  69. $_ENV['appName'] . '-工单被回复',
  70. 'news/warn.tpl',
  71. [
  72. 'text' => '您好,有人回复了<a href="' . $_ENV['baseUrl'] . '/user/ticket/' . $ticket->id . '/view">工单</a>,请您查看。',
  73. ],
  74. []
  75. );
  76. $ticket->content = \json_encode(\array_merge($content_old, $content_new));
  77. $ticket->status = 'open_wait_user';
  78. $ticket->save();
  79. return $response->withJson([
  80. 'ret' => 1,
  81. 'msg' => '提交成功',
  82. ]);
  83. }
  84. /**
  85. * 后台 查看指定工单
  86. *
  87. * @param array $args
  88. */
  89. public function ticketView(Request $request, Response $response, array $args)
  90. {
  91. $id = $args['id'];
  92. $ticket = Ticket::where('id', '=', $id)->first();
  93. $comments = \json_decode($ticket->content, true);
  94. if ($ticket === null) {
  95. return $response->withStatus(302)->withHeader('Location', '/user/ticket');
  96. }
  97. return $response->write(
  98. $this->view()
  99. ->assign('ticket', $ticket)
  100. ->assign('comments', $comments)
  101. ->registerClass('Tools', Tools::class)
  102. ->display('admin/ticket/view.tpl')
  103. );
  104. }
  105. /**
  106. * 后台 关闭工单
  107. *
  108. * @param array $args
  109. */
  110. public function close(Request $request, Response $response, array $args)
  111. {
  112. $id = $args['id'];
  113. $ticket = Ticket::where('id', '=', $id)->first();
  114. if ($ticket->status === 'closed') {
  115. return $response->withJson([
  116. 'ret' => 0,
  117. 'msg' => '工单已关闭',
  118. ]);
  119. }
  120. $user = User::find($ticket->userid);
  121. $user->sendMail(
  122. $_ENV['appName'] . '-工单已被关闭',
  123. 'news/warn.tpl',
  124. [
  125. 'text' => '您好,您的工单 #'. $ticket->id .' 已被关闭,如果您还有问题,欢迎提交新的工单。',
  126. ],
  127. []
  128. );
  129. $ticket->status = 'closed';
  130. $ticket->save();
  131. return $response->withJson([
  132. 'ret' => 1,
  133. 'msg' => '关闭成功',
  134. ]);
  135. }
  136. /**
  137. * 后台 删除工单
  138. *
  139. * @param array $args
  140. */
  141. public function delete(Request $request, Response $response, array $args)
  142. {
  143. $id = $args['id'];
  144. Ticket::where('id', '=', $id)->delete();
  145. return $response->withJson([
  146. 'ret' => 1,
  147. 'msg' => '删除成功',
  148. ]);
  149. }
  150. /**
  151. * @param array $args
  152. */
  153. public function ajax(Request $request, Response $response, array $args)
  154. {
  155. $tickets = Ticket::orderBy('id', 'desc')->get();
  156. foreach ($tickets as $ticket) {
  157. $ticket->op = '<button type="button" class="btn btn-red" id="delete-ticket"
  158. onclick="deleteTicket(' . $ticket->id . ')">删除</button>
  159. <button type="button" class="btn btn-orange" id="close-ticket"
  160. onclick="closeTicket(' . $ticket->id . ')">关闭</button>
  161. <a class="btn btn-blue" href="/admin/ticket/' . $ticket->id . '/view">查看</a>';
  162. $ticket->status = Tools::getTicketStatus($ticket);
  163. $ticket->type = Tools::getTicketType($ticket);
  164. $ticket->datetime = Tools::toDateTime((int) $ticket->datetime);
  165. }
  166. return $response->withJson([
  167. 'tickets' => $tickets,
  168. ]);
  169. }
  170. }