Просмотр исходного кода

fix(login): 修复视频号登录状态检测逻辑

- 在 BaseLoginService 中提取登录成功 URL 检测逻辑到独立方法
- 为 WeixinVideoLoginService 重写 isUrlLoginSuccess 方法,增加额外验证:
  - 排除 `/platform/login` 路径(iframe 登录页)
  - 检查 authData.uniqId 或页面元素 `#finder-uid-copy`
- 更新客户端路由检测规则,修正视频号登录页和已登录页的正则表达式
- 移除未使用的 ElImage 组件类型声明
Ethanfly 19 часов назад
Родитель
Сommit
387ef7f8b3

+ 0 - 1
client/src/components.d.ts

@@ -32,7 +32,6 @@ declare module 'vue' {
     ElForm: typeof import('element-plus/es')['ElForm']
     ElFormItem: typeof import('element-plus/es')['ElFormItem']
     ElIcon: typeof import('element-plus/es')['ElIcon']
-    ElImage: typeof import('element-plus/es')['ElImage']
     ElInput: typeof import('element-plus/es')['ElInput']
     ElMain: typeof import('element-plus/es')['ElMain']
     ElMenu: typeof import('element-plus/es')['ElMenu']

+ 6 - 4
client/src/components/BrowserTab.vue

@@ -1790,7 +1790,8 @@ function isLoggedInByUrl(): boolean {
     ],
     weixin_video: [
       /channels\.weixin\.qq\.com\/?$/,      // 视频号根路径
-      /channels\.weixin\.qq\.com\/login/,   // 登录页
+      /channels\.weixin\.qq\.com\/login\.html/,   // 登录页
+      /channels\.weixin\.qq\.com\/platform\/login/, // iframe 登录页
     ],
     bilibili: [
       /passport\.bilibili/,
@@ -1826,7 +1827,7 @@ function isLoggedInByUrl(): boolean {
       /creator\.xiaohongshu\.com\/new\//,           // /new/ 下的其他页面也算
     ],
     weixin_video: [
-      /channels\.weixin\.qq\.com\/platform/,        // 主要判断条件
+      /channels\.weixin\.qq\.com\/platform(?!\/login)/,        // 主要判断条件(排除 login-for-iframe 等未登录态)
     ],
     bilibili: [
       /member\.bilibili\.com\/platform/,
@@ -1858,7 +1859,7 @@ function isLoggedInByUrl(): boolean {
       /xiaohongshu\.com/,
       /xhslink\.com/,
     ],
-    weixin_video: [/weixin\.qq\.com/, /qq\.com/],
+    weixin_video: [],
     bilibili: [/bilibili\.com/],
     toutiao: [/toutiao\.com/],
     baijiahao: [/baidu\.com/, /baijiahao\.baidu\.com/],
@@ -1987,7 +1988,8 @@ function isOnLoginPage(): boolean {
     ],
     weixin_video: [
       /channels\.weixin\.qq\.com\/?$/,      // 视频号根路径
-      /channels\.weixin\.qq\.com\/login/,   // 视频号登录页
+      /channels\.weixin\.qq\.com\/login\.html/,   // 视频号登录页
+      /channels\.weixin\.qq\.com\/platform\/login/, // 视频号 iframe 登录页
     ],
     bilibili: [
       /passport\.bilibili/,

+ 6 - 3
server/src/services/login/BaseLoginService.ts

@@ -203,9 +203,7 @@ export abstract class BaseLoginService extends EventEmitter {
         const currentUrl = session.page.url();
 
         // 检测是否跳转到成功页面
-        const isSuccess = this.config.successIndicators.some(indicator =>
-          currentUrl.includes(indicator)
-        );
+        const isSuccess = await this.isUrlLoginSuccess(session, currentUrl);
 
         if (isSuccess) {
           logger.info(`[${this.displayName}] URL 检测到登录成功: ${currentUrl}`);
@@ -220,6 +218,11 @@ export abstract class BaseLoginService extends EventEmitter {
     }, this.CHECK_INTERVAL);
   }
 
+  protected async isUrlLoginSuccess(session: LoginSession, currentUrl: string): Promise<boolean> {
+    void session;
+    return this.config.successIndicators.some((indicator) => currentUrl.includes(indicator));
+  }
+
   /**
    * AI 静默监控 - 只用于检测登录状态,不发送分析结果给前端
    */

+ 20 - 1
server/src/services/login/WeixinVideoLoginService.ts

@@ -24,12 +24,31 @@ export class WeixinVideoLoginService extends BaseLoginService {
       platform: 'weixin_video',
       displayName: '视频号',
       loginUrl: 'https://channels.weixin.qq.com/login.html',
-      successIndicators: ['/platform', 'channels.weixin.qq.com/platform'],
+      successIndicators: ['channels.weixin.qq.com/platform'],
       cookieDomain: '.weixin.qq.com',
       accountIdPrefix: 'sph_',
     });
   }
 
+  protected override async isUrlLoginSuccess(session: LoginSession, currentUrl: string): Promise<boolean> {
+    const urlMatched = this.config.successIndicators.some((indicator) => currentUrl.includes(indicator));
+    if (!urlMatched) return false;
+
+    if (currentUrl.includes('/platform/login')) {
+      return false;
+    }
+
+    const authData: any = session.apiData?.authData;
+    if (authData?.uniqId) return true;
+
+    try {
+      const el = await session.page.$('#finder-uid-copy');
+      return Boolean(el);
+    } catch {
+      return false;
+    }
+  }
+
   /**
    * API 拦截配置 - 视频号所有信息都在 auth_data 接口
    */