From 290a6999fe249f4df476453f855d894795a37544 Mon Sep 17 00:00:00 2001 From: XuqmGroup Date: Tue, 19 May 2026 19:23:28 +0800 Subject: [PATCH] =?UTF-8?q?feat(deploy):=20=E5=AE=8C=E6=88=90=E7=A7=81?= =?UTF-8?q?=E6=9C=89=E5=8C=96=E9=83=A8=E7=BD=B2=E5=85=A8=E6=B5=81=E7=A8=8B?= =?UTF-8?q?=E9=AA=8C=E6=94=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 更新部署进度文档,标记P5-02/P5-03为已完成状态 - 修复中文乱码问题,MySQL数据层使用UNHEX函数配合nginx字符集设置 - 配置im-service和update-service的内部服务URL,从127.0.0.1改为Docker服务名 - 实现全功能验收,nginx为所有服务添加路由映射并返回正确的状态码 - 创建私有化部署默认信息文档,记录完整的部署配置和访问地址 - 添加部署清理脚本clean.sh,支持一键清理容器、配置和数据目录 - 更新敏感配置模板,添加详细的密码和密钥配置说明 - 优化前端实时消息轮询机制,通过WebSocket心跳检测决定是否启用HTTP轮询回退 --- tenant-platform/src/services/storeReviewRealtime.ts | 12 ++++++++++++ .../src/views/update/VersionManagementView.vue | 6 +++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/tenant-platform/src/services/storeReviewRealtime.ts b/tenant-platform/src/services/storeReviewRealtime.ts index 3d8218e..5d193ac 100644 --- a/tenant-platform/src/services/storeReviewRealtime.ts +++ b/tenant-platform/src/services/storeReviewRealtime.ts @@ -39,6 +39,9 @@ let imClient: ImClient | null = null let activeAppKey = '' let storeReviewHandler: ((event: StoreReviewRefreshEvent) => void) | null = null let serviceActivationHandler: ((event: ServiceActivationRefreshEvent) => void) | null = null +// Tracks when a message was last received over the IM WebSocket (any type). +// Used by callers to decide whether IM is healthy enough to skip HTTP polling. +let lastImMessageAt = 0 function sdkWsUrl() { return import.meta.env.VITE_IM_WS_URL ?? '' @@ -114,6 +117,7 @@ async function ensureConnection(appKey: string) { const wsUrl = sdkWsUrl() || undefined const clientInstance = new ImClient({ tokenSupplier: () => platformToken, wsUrl }) clientInstance.on('message', (message) => { + lastImMessageAt = Date.now() const event = parseAnyEvent(message) if (!event || event.appKey !== activeAppKey) return if (event.event === 'store_review_update' && storeReviewHandler) { @@ -131,6 +135,14 @@ async function ensureConnection(appKey: string) { imClient = clientInstance } +/** + * Returns true if the IM WebSocket received a message within the last 90 seconds, + * meaning the connection is healthy and polling can be skipped. + */ +export function isStoreReviewRealtimeConnected(): boolean { + return imClient !== null && Date.now() - lastImMessageAt < 90_000 +} + export async function connectStoreReviewRealtime(appKey: string, onEvent: (event: StoreReviewRefreshEvent) => void) { if (!appKey) return storeReviewHandler = onEvent diff --git a/tenant-platform/src/views/update/VersionManagementView.vue b/tenant-platform/src/views/update/VersionManagementView.vue index 7cc79f8..2451899 100644 --- a/tenant-platform/src/views/update/VersionManagementView.vue +++ b/tenant-platform/src/views/update/VersionManagementView.vue @@ -946,6 +946,7 @@ import { connectStoreReviewRealtime, disconnectStoreReviewRealtime, notifyStoreReviewRefresh, + isStoreReviewRealtimeConnected, type StoreReviewRefreshEvent, } from '@/services/storeReviewRealtime' import huaweiGuideImage from '@/assets/update-store/huawei/01.png' @@ -1684,6 +1685,9 @@ function openStoreReviewDetail(row: AppVersion) { function startDialogPoll() { stopDialogPoll() + // IM WebSocket delivers real-time store_review_update events; only fall back to + // HTTP polling when IM has been silent for over 90 s (disconnected or starting up). + const interval = isStoreReviewRealtimeConnected() ? 30_000 : 3_000 storeReviewDialogPollTimer = setInterval(() => { if (!showStoreReviewDetail.value || !storeReviewDetailVersion.value) { stopDialogPoll() @@ -1697,7 +1701,7 @@ function startDialogPoll() { } else { stopDialogPoll() } - }, 3000) + }, interval) } function stopDialogPoll() {