From 39a2a4028b0162dcec37f59638218ac32693c9dd Mon Sep 17 00:00:00 2001 From: Qiao Date: Thu, 5 Feb 2026 10:54:40 +0800 Subject: [PATCH] =?UTF-8?q?feat(webui):=20=E6=B7=BB=E5=8A=A0QQ=E6=8E=89?= =?UTF-8?q?=E7=BA=BF=E6=97=B6=E9=87=8D=E5=90=AF=E8=BF=9B=E7=A8=8B=E6=8F=90?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 后端 CheckLoginStatus API 新增 isOffline 字段区分掉线与未登录状态 - 后端 GetQQLoginInfo API 新增返回 online 和 avatarUrl 字段 - 前端掉线时弹窗提示用户是否重启进程 - 修正 isLogin 类型从 string 改为 boolean --- packages/napcat-webui-backend/src/api/QQLogin.ts | 15 ++++++++++++++- .../src/controllers/qq_manager.ts | 5 +++-- .../napcat-webui-frontend/src/layouts/default.tsx | 11 ++++++++--- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/packages/napcat-webui-backend/src/api/QQLogin.ts b/packages/napcat-webui-backend/src/api/QQLogin.ts index 4eb1d832..2ce7df04 100644 --- a/packages/napcat-webui-backend/src/api/QQLogin.ts +++ b/packages/napcat-webui-backend/src/api/QQLogin.ts @@ -34,8 +34,11 @@ export const QQCheckLoginStatusHandler: RequestHandler = async (_, res) => { const qqLoginStatus = WebUiDataRuntime.getQQLoginStatus(); // 必须同时满足:已登录且在线(online 必须明确为 true) const isLogin = qqLoginStatus && isOnline === true; + // 检测掉线状态:已登录但不在线 + const isOffline = qqLoginStatus && isOnline === false; const data = { isLogin, + isOffline, qrcodeurl: WebUiDataRuntime.getQQLoginQrcodeURL(), loginError: WebUiDataRuntime.getQQLoginError(), }; @@ -80,7 +83,17 @@ export const QQGetLoginListNewHandler: RequestHandler = async (_, res) => { // 获取登录的QQ的信息 export const getQQLoginInfoHandler: RequestHandler = async (_, res) => { - const data = WebUiDataRuntime.getQQLoginInfo(); + const basicInfo = WebUiDataRuntime.getQQLoginInfo(); + // 从 OneBot 上下文获取实时的 selfInfo.online 状态 + const oneBotContext = WebUiDataRuntime.getOneBotContext(); + const selfInfo = oneBotContext?.core?.selfInfo; + const online = selfInfo?.online ?? undefined; + const avatarUrl = selfInfo?.avatarUrl; + const data = { + ...basicInfo, + online, + avatarUrl, + }; return sendSuccess(res, data); }; diff --git a/packages/napcat-webui-frontend/src/controllers/qq_manager.ts b/packages/napcat-webui-frontend/src/controllers/qq_manager.ts index db3826fc..05dccb44 100644 --- a/packages/napcat-webui-frontend/src/controllers/qq_manager.ts +++ b/packages/napcat-webui-frontend/src/controllers/qq_manager.ts @@ -21,7 +21,8 @@ export default class QQManager { public static async checkQQLoginStatus () { const data = await serverRequest.post< ServerResponse<{ - isLogin: string; + isLogin: boolean; + isOffline?: boolean; qrcodeurl: string; }> >('/QQLogin/CheckLoginStatus'); @@ -31,7 +32,7 @@ export default class QQManager { public static async checkQQLoginStatusWithQrcode () { const data = await serverRequest.post< - ServerResponse<{ qrcodeurl: string; isLogin: string; loginError?: string; }> + ServerResponse<{ qrcodeurl: string; isLogin: boolean; isOffline?: boolean; loginError?: string; }> >('/QQLogin/CheckLoginStatus'); return data.data.data; diff --git a/packages/napcat-webui-frontend/src/layouts/default.tsx b/packages/napcat-webui-frontend/src/layouts/default.tsx index 4f394f04..2b3df6d8 100644 --- a/packages/napcat-webui-frontend/src/layouts/default.tsx +++ b/packages/napcat-webui-frontend/src/layouts/default.tsx @@ -68,8 +68,8 @@ const Layout: React.FC<{ children: React.ReactNode; }> = ({ children }) => { isOnlineRef.current = false; dialog.confirm({ title: '账号已离线', - content: '您的 QQ 账号已下线,请重新登录。', - confirmText: '重新登陆', + content: '您的 QQ 账号已掉线,是否重启进程以重新登录?', + confirmText: '重启进程', cancelText: '退出账户', onConfirm: async () => { setIsRestarting(true); @@ -115,7 +115,12 @@ const Layout: React.FC<{ children: React.ReactNode; }> = ({ children }) => { const checkIsQQLogin = async () => { try { const result = await QQManager.checkQQLoginStatus(); - if (!result.isLogin) { + // 掉线状态由 checkOnlineStatus 定期检测并弹窗处理,这里只处理未登录 + if (result.isOffline) { + // 已登录但掉线,标记状态,等待 checkOnlineStatus 弹窗 + isOnlineRef.current = false; + } else if (!result.isLogin) { + // 未登录状态:跳转到登录页面 if (isAuth) { navigate('/qq_login', { replace: true }); } else {