From ab43fe863277bdb702dbcd18b4d8820afa77c9e4 Mon Sep 17 00:00:00 2001 From: sunlei Date: Fri, 12 Jun 2026 21:40:43 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=8B=86=E5=88=86QQBot=E8=B4=A6?= =?UTF-8?q?=E5=8F=B7=E7=8A=B6=E6=80=81=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + apps/web-antdv-next/src/api/qqbot/index.ts | 10 +++ .../src/views/qqbot/account/list.tsx | 88 ++++++++++++++++--- 3 files changed, 89 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 89f9707..6089f30 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ pnpm run build:antdv-next ## 业务页面 - 系统管理 / 站内信是日志级通知列表,只展示 API 错误、QQBot 下线、NapCat 离线等后端自动捕获事件;页面提供筛选、处理/重新打开、置顶和删除,不提供人工新增或编辑。 +- QQBot / 账号连接页拆分 OneBot 连接、QQ 登录、NapCat 运行和运行说明列;更新登录通过 SSE 展示 quick / password / qrcode 每步进度。 ## 部署说明 diff --git a/apps/web-antdv-next/src/api/qqbot/index.ts b/apps/web-antdv-next/src/api/qqbot/index.ts index 9fc2f9d..9096423 100644 --- a/apps/web-antdv-next/src/api/qqbot/index.ts +++ b/apps/web-antdv-next/src/api/qqbot/index.ts @@ -53,11 +53,21 @@ export namespace QqbotApi { bindStatus?: 'bound' | 'disabled' | 'pending'; containerId?: string; containerName?: string; + containerOnline?: boolean; containerStatus?: 'creating' | 'error' | 'running' | 'stopped'; lastCheckedAt?: string; lastError?: string; lastLoginAt?: string; lastStartedAt?: string; + oneBotOnline?: boolean; + qqLoginMessage?: null | string; + qqLoginStatus?: + | 'offline' + | 'online' + | 'qrcode_expired' + | 'qrcode_pending' + | 'unknown'; + webuiOnline?: boolean | null; webuiPort?: null | number; } diff --git a/apps/web-antdv-next/src/views/qqbot/account/list.tsx b/apps/web-antdv-next/src/views/qqbot/account/list.tsx index c206647..63e0303 100644 --- a/apps/web-antdv-next/src/views/qqbot/account/list.tsx +++ b/apps/web-antdv-next/src/views/qqbot/account/list.tsx @@ -184,14 +184,20 @@ export default defineComponent({ { dataIndex: 'connectStatus', key: 'accountOnlineStatus', - title: '账号在线', - width: 130, + title: 'OneBot 连接', + width: 140, + }, + { + dataIndex: 'napcat', + key: 'qqLoginStatus', + title: 'QQ 登录', + width: 150, }, { dataIndex: 'napcat', key: 'napcatRuntime', - title: 'NapCat 容器', - width: 220, + title: 'NapCat 运行', + width: 240, }, { dataIndex: 'lastHeartbeatAt', @@ -302,7 +308,7 @@ export default defineComponent({ ], }, fieldName: 'connectStatus', - label: '账号在线', + label: 'OneBot', }, ], }, @@ -626,19 +632,38 @@ export default defineComponent({ if (!row.enabled) { return 已停用; } + const online = row.napcat?.oneBotOnline ?? row.connectStatus === 'online'; return ( - - {row.connectStatus === 'online' ? 'OneBot 在线' : 'OneBot 离线'} + + {online ? 'OneBot 在线' : 'OneBot 离线'} ); }; + const renderQqLoginStatus = (row: QqbotApi.Account) => { + const meta = getQqLoginStatusMeta(row.napcat); + return ( + + {meta.label} + {row.napcat?.qqLoginMessage ? ( + + {row.napcat.qqLoginMessage} + + ) : null} + + ); + }; + const renderNapcatRuntime = (row: QqbotApi.Account) => { const napcat = row.napcat; const meta = getNapcatStatusMeta(napcat); + const webuiMeta = getNapcatWebuiMeta(napcat); return ( - {meta.label} + + {meta.label} + {webuiMeta.label} + {napcat?.containerName ? ( {napcat.containerName} @@ -694,6 +719,34 @@ export default defineComponent({ return statusMap[napcat.containerStatus]; } + function getNapcatWebuiMeta(napcat?: null | QqbotApi.AccountNapcatRuntime) { + if (!napcat) return { color: 'default', label: 'WebUI 未绑定' }; + if (napcat.webuiOnline === true) { + return { color: 'success', label: 'WebUI 可用' }; + } + if (napcat.webuiOnline === false) { + return { color: 'error', label: 'WebUI 不可用' }; + } + return { color: 'default', label: 'WebUI 未检查' }; + } + + function getQqLoginStatusMeta( + napcat?: null | QqbotApi.AccountNapcatRuntime, + ) { + if (!napcat) return { color: 'default', label: '未绑定容器' }; + const statusMap: Record< + NonNullable, + { color: string; label: string } + > = { + offline: { color: 'error', label: 'QQ 离线' }, + online: { color: 'success', label: 'QQ 在线' }, + qrcode_expired: { color: 'warning', label: '二维码过期' }, + qrcode_pending: { color: 'processing', label: '等待扫码' }, + unknown: { color: 'default', label: '状态未知' }, + }; + return statusMap[napcat.qqLoginStatus || 'unknown']; + } + function getRecentActivity(row: QqbotApi.Account) { const candidates = [ { label: '最近心跳', value: row.lastHeartbeatAt }, @@ -719,14 +772,26 @@ export default defineComponent({ if (row.lastError) { return { level: 'warning', text: `账号异常:${row.lastError}` }; } + if (row.napcat?.qqLoginMessage) { + return { + level: 'warning', + text: `QQ 登录:${row.napcat.qqLoginMessage}`, + }; + } if (row.napcat?.lastError) { - return { level: 'warning', text: `容器异常:${row.napcat.lastError}` }; + return { level: 'warning', text: `NapCat:${row.napcat.lastError}` }; + } + if (row.napcat?.qqLoginStatus === 'qrcode_expired') { + return { level: 'warning', text: '二维码已过期,点击更新登录' }; } if (row.connectStatus === 'online') { return { level: 'normal', text: '消息链路可用' }; } + if (row.napcat?.qqLoginStatus === 'online') { + return { level: 'warning', text: 'QQ 在线,等待 OneBot 连接' }; + } if (row.napcat?.containerStatus === 'running') { - return { level: 'warning', text: '等待反向 WS' }; + return { level: 'warning', text: 'NapCat 运行中,等待 OneBot 连接' }; } if (row.napcat?.containerStatus === 'creating') { return { level: 'warning', text: '容器创建中' }; @@ -840,6 +905,9 @@ export default defineComponent({ if (column.key === 'accountOnlineStatus') { return renderAccountOnlineStatus(row); } + if (column.key === 'qqLoginStatus') { + return renderQqLoginStatus(row); + } if (column.key === 'napcatRuntime') { return renderNapcatRuntime(row); }