From 98b60c333aeb8eb00dbca25726f26b5125f047c2 Mon Sep 17 00:00:00 2001 From: GiveMePast <1248298477@qq.com> Date: Wed, 5 Aug 2026 17:38:29 +0800 Subject: [PATCH] wip --- app/admin/controller/Ticket.php | 13 ++++- app/common/service/TicketNotifier.php | 50 +++++++++++++++++ app/common/service/TicketService.php | 4 ++ composer.json | 3 +- worker/websocket.php | 79 +++++++++++++++++++++++++++ 5 files changed, 145 insertions(+), 4 deletions(-) create mode 100644 app/common/service/TicketNotifier.php create mode 100644 worker/websocket.php diff --git a/app/admin/controller/Ticket.php b/app/admin/controller/Ticket.php index fa3bb2b..d892fbd 100644 --- a/app/admin/controller/Ticket.php +++ b/app/admin/controller/Ticket.php @@ -5,6 +5,7 @@ namespace app\admin\controller; use app\BaseController; use app\common\model\Tickets; +use app\common\service\TicketNotifier; use app\common\service\TicketService; use think\facade\Session; @@ -109,8 +110,14 @@ class Ticket extends BaseController $ticket = Tickets::find($id); if (!$ticket) return $this->error('工单不存在'); - return $ticket->delete() - ? $this->success('删除成功', []) - : $this->error('删除失败', []); + $deleted = $ticket->delete(); + if (!$deleted) { + return $this->error('删除失败', []); + } + + // 通知前端实时刷新(静默,广播服务不可用不影响删除流程) + TicketNotifier::notify($id, 'delete'); + + return $this->success('删除成功', []); } } diff --git a/app/common/service/TicketNotifier.php b/app/common/service/TicketNotifier.php new file mode 100644 index 0000000..9beef31 --- /dev/null +++ b/app/common/service/TicketNotifier.php @@ -0,0 +1,50 @@ + (string)$action, + 'ticket_id' => (int)$ticketId, + ], JSON_UNESCAPED_UNICODE); + + $context = stream_context_create([ + 'http' => [ + 'method' => 'POST', + 'header' => "Content-Type: application/json\r\n", + 'content' => $payload, + 'timeout' => self::TIMEOUT, + 'ignore_errors' => true, + ], + ]); + + try { + $result = @file_get_contents(self::PUSH_URL, false, $context); + return $result !== false; + } catch (\Throwable $e) { + return false; + } + } +} diff --git a/app/common/service/TicketService.php b/app/common/service/TicketService.php index acb1d9d..04a587b 100644 --- a/app/common/service/TicketService.php +++ b/app/common/service/TicketService.php @@ -89,6 +89,10 @@ class TicketService // 当前无相同网站 $ticketResult = Tickets::create($data); + + // 通知前端实时刷新(静默,广播服务不可用不影响主流程) + TicketNotifier::notify($ticketResult->id, 'create'); + return $ticketResult; } catch (\Exception $e) { Cache::delete($lockKey); diff --git a/composer.json b/composer.json index a7fd3c7..2652967 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,8 @@ "topthink/framework": "^8.0", "topthink/think-orm": "^3.0|^4.0", "topthink/think-filesystem": "^2.0|^3.0", - "topthink/think-multi-app": "^1.1" + "topthink/think-multi-app": "^1.1", + "workerman/workerman": "^4.2" }, "require-dev": { "topthink/think-dumper": "^1.0", diff --git a/worker/websocket.php b/worker/websocket.php new file mode 100644 index 0000000..51bbac5 --- /dev/null +++ b/worker/websocket.php @@ -0,0 +1,79 @@ + connection) +$clients = []; + +// ---------- 主 worker:WebSocket 服务(员工前端连接) ---------- +$wsWorker = new Worker('websocket://0.0.0.0:2346'); +$wsWorker->name = 'ticket-broadcast'; + +$wsWorker->onConnect = function ($connection) use (&$clients) { + $connection->cid = spl_object_id($connection); + $clients[$connection->cid] = $connection; + echo '[' . date('Y-m-d H:i:s') . "] client connected, online: " . count($clients) . PHP_EOL; +}; + +$wsWorker->onClose = function ($connection) use (&$clients) { + if (isset($clients[$connection->cid])) { + unset($clients[$connection->cid]); + } + echo '[' . date('Y-m-d H:i:s') . "] client closed, online: " . count($clients) . PHP_EOL; +}; + +// ---------- 进程启动后追加 HTTP 触发端口(仅本机) ---------- +$wsWorker->onWorkerStart = function ($worker) use (&$clients) { + $httpWorker = new Worker('http://127.0.0.1:2347'); + $httpWorker->name = 'ticket-push-trigger'; + + $httpWorker->onMessage = function ($connection, Request $request) use (&$clients) { + if ($request->method() === 'POST' && $request->path() === '/push') { + $data = json_decode($request->rawBody(), true) ?: []; + + $payload = json_encode([ + 'type' => 'ticket_changed', + 'action' => isset($data['action']) ? (string)$data['action'] : 'update', + 'ticket_id' => isset($data['ticket_id']) ? (int)$data['ticket_id'] : null, + ], JSON_UNESCAPED_UNICODE); + + $sent = 0; + foreach ($clients as $client) { + $client->send($payload); + $sent++; + } + + echo '[' . date('Y-m-d H:i:s') . "] push [{$payload}] to {$sent} clients" . PHP_EOL; + $connection->send('ok'); + } else { + $connection->send('bad request'); + } + }; + + // 同一进程内动态监听第二端口(Windows 下多 worker 的限制的官方解法) + $httpWorker->listen(); +}; + +Worker::runAll();