[ 'op' => '操作', 'id' => '工单ID', 'title' => '主题', 'status' => '工单状态', 'type' => '工单类型', 'userid' => '提交用户', 'datetime' => '创建时间', ], ]; /** * 后台工单页面 * * @throws Exception */ public function index(ServerRequest $request, Response $response, array $args): Response|ResponseInterface { return $response->write( $this->view() ->assign('details', self::$details) ->fetch('admin/ticket/index.tpl') ); } /** * 后台更新工单内容 */ public function update(ServerRequest $request, Response $response, array $args): Response|ResponseInterface { $id = $args['id']; $comment = $request->getParam('comment') ?? ''; if ($comment === '') { return $response->withJson([ 'ret' => 0, 'msg' => '工单回复不能为空', ]); } $ticket = Ticket::where('id', $id)->first(); if ($ticket === null) { return $response->withJson([ 'ret' => 0, 'msg' => '工单不存在', ]); } $content_old = json_decode($ticket->content, true); $content_new = [ [ 'comment_id' => $content_old[count($content_old) - 1]['comment_id'] + 1, 'commenter_name' => 'Admin', 'comment' => $comment, 'datetime' => time(), ], ]; $user = User::find($ticket->userid); $user->sendMail( $_ENV['appName'] . '-工单被回复', 'warn.tpl', [ 'text' => '你好,有人回复了工单,请你查看。', ], [] ); $ticket->content = json_encode(array_merge($content_old, $content_new)); $ticket->status = 'open_wait_user'; $ticket->save(); return $response->withJson([ 'ret' => 1, 'msg' => '提交成功', ]); } /** * 喊 LLM 帮忙回复工单 */ public function updateAI(ServerRequest $request, Response $response, array $args): Response|ResponseInterface { $id = $args['id']; $ticket = Ticket::where('id', $id)->first(); if ($ticket === null) { return $response->withJson([ 'ret' => 0, 'msg' => '工单不存在', ]); } $content_old = json_decode($ticket->content, true); // 获取用户的第一个问题,作为 LLM 的输入 $ai_reply = LLM::genTextResponse($content_old[0]['comment']); $content_new = [ [ 'comment_id' => $content_old[count($content_old) - 1]['comment_id'] + 1, 'commenter_name' => 'AI Admin', 'comment' => $ai_reply, 'datetime' => time(), ], ]; $user = User::find($ticket->userid); $user->sendMail( $_ENV['appName'] . '-工单被回复', 'warn.tpl', [ 'text' => '你好,AI 回复了工单,请你查看。', ], [] ); $ticket->content = json_encode(array_merge($content_old, $content_new)); $ticket->status = 'open_wait_user'; $ticket->save(); return $response->withJson([ 'ret' => 1, 'msg' => '提交成功', ]); } /** * 后台查看指定工单 * * @throws Exception */ public function ticketView(ServerRequest $request, Response $response, array $args): Response|ResponseInterface { $id = $args['id']; $ticket = Ticket::where('id', '=', $id)->first(); if ($ticket === null) { return $response->withRedirect('/admin/ticket'); } $comments = json_decode($ticket->content); foreach ($comments as $comment) { $comment->datetime = Tools::toDateTime((int) $comment->datetime); } return $response->write( $this->view() ->assign('ticket', $ticket) ->assign('comments', $comments) ->fetch('admin/ticket/view.tpl') ); } /** * 后台关闭工单 */ public function close(ServerRequest $request, Response $response, array $args): Response|ResponseInterface { $id = $args['id']; $ticket = Ticket::where('id', '=', $id)->first(); if ($ticket === null) { return $response->withJson([ 'ret' => 0, 'msg' => '工单不存在', ]); } if ($ticket->status === 'closed') { return $response->withJson([ 'ret' => 0, 'msg' => '操作失败,工单已关闭', ]); } $ticket->status = 'closed'; $ticket->save(); return $response->withJson([ 'ret' => 1, 'msg' => '关闭成功', ]); } /** * 后台删除工单 */ public function delete(ServerRequest $request, Response $response, array $args): Response|ResponseInterface { $id = $args['id']; Ticket::where('id', '=', $id)->delete(); return $response->withJson([ 'ret' => 1, 'msg' => '删除成功', ]); } /** * 后台工单页面 Ajax */ public function ajax(ServerRequest $request, Response $response, array $args): Response|ResponseInterface { $tickets = Ticket::orderBy('id', 'desc')->get(); foreach ($tickets as $ticket) { $ticket->op = ''; if ($ticket->status !== 'closed') { $ticket->op .= ' '; } $ticket->op .= ' 查看'; $ticket->status = $ticket->status(); $ticket->type = $ticket->type(); $ticket->datetime = Tools::toDateTime((int) $ticket->datetime); } return $response->withJson([ 'tickets' => $tickets, ]); } }