|
@@ -59,13 +59,19 @@
|
|
|
<div class="success-content">
|
|
<div class="success-content">
|
|
|
<el-icon class="success-icon"><CircleCheck /></el-icon>
|
|
<el-icon class="success-icon"><CircleCheck /></el-icon>
|
|
|
<h3>登录成功!</h3>
|
|
<h3>登录成功!</h3>
|
|
|
- <div v-if="accountInfo" class="account-preview">
|
|
|
|
|
- <el-avatar :size="56" :src="accountInfo.avatarUrl || undefined">
|
|
|
|
|
- {{ accountInfo.accountName?.[0] }}
|
|
|
|
|
|
|
+ <!-- 正在获取账号信息 -->
|
|
|
|
|
+ <div v-if="fetchingAccountInfo" class="account-fetching">
|
|
|
|
|
+ <el-icon class="fetching-icon"><Loading /></el-icon>
|
|
|
|
|
+ <span>正在获取账号信息...</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <!-- 已获取到账号信息 -->
|
|
|
|
|
+ <div v-else-if="hasValidAccountInfo" class="account-preview">
|
|
|
|
|
+ <el-avatar :size="56" :src="accountInfo?.avatarUrl || undefined">
|
|
|
|
|
+ {{ accountInfo?.accountName?.[0] }}
|
|
|
</el-avatar>
|
|
</el-avatar>
|
|
|
<div class="account-preview-info">
|
|
<div class="account-preview-info">
|
|
|
- <div class="account-preview-name">{{ accountInfo.accountName }}</div>
|
|
|
|
|
- <div class="account-preview-id">{{ accountInfo.accountId }}</div>
|
|
|
|
|
|
|
+ <div class="account-preview-name">{{ accountInfo?.accountName }}</div>
|
|
|
|
|
+ <div class="account-preview-id">{{ accountInfo?.accountId }}</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
<p>点击"保存账号"完成添加</p>
|
|
<p>点击"保存账号"完成添加</p>
|
|
@@ -117,6 +123,7 @@ const accountInfo = ref<{
|
|
|
worksCount: number;
|
|
worksCount: number;
|
|
|
} | null>(null);
|
|
} | null>(null);
|
|
|
const cookieData = ref('');
|
|
const cookieData = ref('');
|
|
|
|
|
+const fetchingAccountInfo = ref(false); // 是否正在获取账号信息
|
|
|
|
|
|
|
|
// 计时器和标志位
|
|
// 计时器和标志位
|
|
|
let checkTimer: ReturnType<typeof setInterval> | null = null;
|
|
let checkTimer: ReturnType<typeof setInterval> | null = null;
|
|
@@ -129,6 +136,16 @@ const platform = computed(() => props.tab.browserData?.platform as PlatformType)
|
|
|
// 是否是管理后台模式(从后台按钮打开,不需要登录检测和保存账号)
|
|
// 是否是管理后台模式(从后台按钮打开,不需要登录检测和保存账号)
|
|
|
const isAdminMode = computed(() => !!props.tab.browserData?.isAdminMode);
|
|
const isAdminMode = computed(() => !!props.tab.browserData?.isAdminMode);
|
|
|
|
|
|
|
|
|
|
+// 是否已获取到有效的账号信息(排除默认值)
|
|
|
|
|
+const hasValidAccountInfo = computed(() => {
|
|
|
|
|
+ if (!accountInfo.value) return false;
|
|
|
|
|
+ const defaultNames = [
|
|
|
|
|
+ '抖音账号', '小红书账号', '快手账号', '视频号账号', 'B站账号',
|
|
|
|
|
+ '头条账号', '百家号账号', '企鹅号账号', '大鱼号账号'
|
|
|
|
|
+ ];
|
|
|
|
|
+ return accountInfo.value.accountName && !defaultNames.includes(accountInfo.value.accountName);
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
const initialUrl = computed(() => {
|
|
const initialUrl = computed(() => {
|
|
|
// 优先使用 browserData 中指定的 URL
|
|
// 优先使用 browserData 中指定的 URL
|
|
|
if (props.tab.browserData?.url) {
|
|
if (props.tab.browserData?.url) {
|
|
@@ -191,20 +208,6 @@ function handleNavigate(event: Electron.DidNavigateEvent) {
|
|
|
if (!isAdminMode.value && loginStatus.value !== 'success') {
|
|
if (!isAdminMode.value && loginStatus.value !== 'success') {
|
|
|
setTimeout(() => checkLoginSilently(), 500);
|
|
setTimeout(() => checkLoginSilently(), 500);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- // 百家号特殊处理:如果已经登录成功但账号信息是默认值,尝试重新获取
|
|
|
|
|
- if (platform.value === 'baijiahao' &&
|
|
|
|
|
- loginStatus.value === 'success' &&
|
|
|
|
|
- accountInfo.value?.accountName === '百家号账号' &&
|
|
|
|
|
- event.url.includes('baijiahao.baidu.com/builder')) {
|
|
|
|
|
- console.log('[BrowserTab] 百家号跳转到后台页面,尝试重新获取账号信息');
|
|
|
|
|
- setTimeout(async () => {
|
|
|
|
|
- const info = await fetchBaijiahaoAccountInfo();
|
|
|
|
|
- if (info && info.accountName !== '百家号账号') {
|
|
|
|
|
- accountInfo.value = info;
|
|
|
|
|
- }
|
|
|
|
|
- }, 1500);
|
|
|
|
|
- }
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function handleNavigateInPage(event: Electron.DidNavigateInPageEvent) {
|
|
function handleNavigateInPage(event: Electron.DidNavigateInPageEvent) {
|
|
@@ -277,7 +280,7 @@ function isLoggedInByUrl(): boolean {
|
|
|
xiaohongshu: [/passport/, /login/i],
|
|
xiaohongshu: [/passport/, /login/i],
|
|
|
bilibili: [/passport/, /login/i],
|
|
bilibili: [/passport/, /login/i],
|
|
|
toutiao: [/passport/, /login/i],
|
|
toutiao: [/passport/, /login/i],
|
|
|
- baijiahao: [/passport/, /login/i],
|
|
|
|
|
|
|
+ baijiahao: [/passport/, /login/i, /bjh\/login/], // 包含 /builder/theme/bjh/login
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
// 如果在登录页面,返回 false
|
|
// 如果在登录页面,返回 false
|
|
@@ -311,7 +314,10 @@ function isLoggedInByUrl(): boolean {
|
|
|
/mp\.toutiao\.com\/profile/,
|
|
/mp\.toutiao\.com\/profile/,
|
|
|
],
|
|
],
|
|
|
baijiahao: [
|
|
baijiahao: [
|
|
|
- /baijiahao\.baidu\.com\/builder/, // 任何后台页面(builder 目录下)
|
|
|
|
|
|
|
+ /baijiahao\.baidu\.com\/builder\/rc/, // 创作中心首页
|
|
|
|
|
+ /baijiahao\.baidu\.com\/builder\/app/, // 应用页面
|
|
|
|
|
+ /baijiahao\.baidu\.com\/builder\/content/, // 内容管理
|
|
|
|
|
+ // 注意:排除 /builder/theme/bjh/login 登录页面
|
|
|
],
|
|
],
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -332,158 +338,184 @@ async function checkLoginSilently() {
|
|
|
// 简单判断是否有登录相关的 cookie
|
|
// 简单判断是否有登录相关的 cookie
|
|
|
const hasLoginCookie = checkHasLoginCookie(cookies);
|
|
const hasLoginCookie = checkHasLoginCookie(cookies);
|
|
|
|
|
|
|
|
- // 调试日志
|
|
|
|
|
- if (platform.value === 'baijiahao') {
|
|
|
|
|
- console.log('[BrowserTab] 百家号检测 - URL:', currentUrl.value);
|
|
|
|
|
- console.log('[BrowserTab] 百家号检测 - hasLoginCookie:', hasLoginCookie);
|
|
|
|
|
- console.log('[BrowserTab] 百家号检测 - cookies 数量:', cookies.length);
|
|
|
|
|
- const bduss = cookies.find(c => c.name === 'BDUSS');
|
|
|
|
|
- console.log('[BrowserTab] 百家号检测 - BDUSS:', bduss ? '存在' : '不存在');
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
if (hasLoginCookie && loginStatus.value !== 'success') {
|
|
if (hasLoginCookie && loginStatus.value !== 'success') {
|
|
|
// 检查 URL 是否已经在登录后的页面
|
|
// 检查 URL 是否已经在登录后的页面
|
|
|
const urlIndicatesLoggedIn = isLoggedInByUrl();
|
|
const urlIndicatesLoggedIn = isLoggedInByUrl();
|
|
|
|
|
|
|
|
- if (platform.value === 'baijiahao') {
|
|
|
|
|
- console.log('[BrowserTab] 百家号检测 - urlIndicatesLoggedIn:', urlIndicatesLoggedIn);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
if (urlIndicatesLoggedIn) {
|
|
if (urlIndicatesLoggedIn) {
|
|
|
// URL 表明已登录,快速响应:先显示成功,再异步获取详情
|
|
// URL 表明已登录,快速响应:先显示成功,再异步获取详情
|
|
|
- console.log('[BrowserTab] URL 表明已登录,调用 quickLoginSuccess');
|
|
|
|
|
await quickLoginSuccess(cookies);
|
|
await quickLoginSuccess(cookies);
|
|
|
} else {
|
|
} else {
|
|
|
// 还在登录页面,通过服务器验证
|
|
// 还在登录页面,通过服务器验证
|
|
|
- console.log('[BrowserTab] 通过服务器验证登录');
|
|
|
|
|
await verifyLoginWithServer(cookies, true);
|
|
await verifyLoginWithServer(cookies, true);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
// 静默失败,不处理
|
|
// 静默失败,不处理
|
|
|
- console.error('[BrowserTab] checkLoginSilently 异常:', error);
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 通过 webview 执行脚本获取百家号账号信息
|
|
|
|
|
-async function fetchBaijiahaoAccountInfo(retryCount = 0): Promise<{
|
|
|
|
|
|
|
+// 从页面直接提取账号信息
|
|
|
|
|
+async function extractAccountInfoFromPage(): Promise<{
|
|
|
accountId: string;
|
|
accountId: string;
|
|
|
accountName: string;
|
|
accountName: string;
|
|
|
avatarUrl: string;
|
|
avatarUrl: string;
|
|
|
fansCount: number;
|
|
fansCount: number;
|
|
|
worksCount: number;
|
|
worksCount: number;
|
|
|
} | null> {
|
|
} | null> {
|
|
|
- console.log('[BrowserTab] fetchBaijiahaoAccountInfo 开始, retryCount:', retryCount);
|
|
|
|
|
-
|
|
|
|
|
- if (!webviewRef.value) {
|
|
|
|
|
- console.log('[BrowserTab] webviewRef 不存在');
|
|
|
|
|
- return null;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 等待页面加载完成
|
|
|
|
|
- console.log('[BrowserTab] 等待1秒让页面加载...');
|
|
|
|
|
- await new Promise(resolve => setTimeout(resolve, 1000));
|
|
|
|
|
-
|
|
|
|
|
|
|
+ const webview = document.querySelector(`webview[partition="${webviewPartition.value}"]`) as Electron.WebviewTag | null;
|
|
|
|
|
+ if (!webview) return null;
|
|
|
|
|
+
|
|
|
try {
|
|
try {
|
|
|
- // 先获取当前页面的 URL
|
|
|
|
|
- const currentPageUrl = await webviewRef.value.executeJavaScript('window.location.href');
|
|
|
|
|
- console.log('[BrowserTab] 当前页面 URL:', currentPageUrl);
|
|
|
|
|
-
|
|
|
|
|
- // 检查是否在百家号域名下
|
|
|
|
|
- if (!currentPageUrl.includes('baijiahao.baidu.com')) {
|
|
|
|
|
- console.log('[BrowserTab] 当前页面不在百家号域名下,跳过获取');
|
|
|
|
|
- return null;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- console.log('[BrowserTab] 正在获取百家号账号信息...');
|
|
|
|
|
- const script = `
|
|
|
|
|
- (async () => {
|
|
|
|
|
- try {
|
|
|
|
|
- console.log('[Baijiahao] 当前 URL:', window.location.href);
|
|
|
|
|
- console.log('[Baijiahao] 当前 Cookie:', document.cookie.substring(0, 100));
|
|
|
|
|
- console.log('[Baijiahao] Fetching settingInfo...');
|
|
|
|
|
|
|
+ // 根据不同平台使用不同的提取脚本
|
|
|
|
|
+ const extractScripts: Record<string, string> = {
|
|
|
|
|
+ douyin: `
|
|
|
|
|
+ (function() {
|
|
|
|
|
+ const result = { accountId: '', accountName: '', avatarUrl: '', fansCount: 0, worksCount: 0 };
|
|
|
|
|
|
|
|
- const response = await fetch('https://baijiahao.baidu.com/user-ui/cms/settingInfo', {
|
|
|
|
|
- method: 'GET',
|
|
|
|
|
- credentials: 'include',
|
|
|
|
|
- headers: {
|
|
|
|
|
- 'Accept': 'application/json, text/plain, */*',
|
|
|
|
|
- 'Referer': 'https://baijiahao.baidu.com/'
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ // 从页面元素提取
|
|
|
|
|
+ // 头像
|
|
|
|
|
+ const avatarEl = document.querySelector('img[class*="avatar"], .user-avatar img, [class*="userAvatar"] img');
|
|
|
|
|
+ if (avatarEl) result.avatarUrl = avatarEl.src || '';
|
|
|
|
|
|
|
|
- console.log('[Baijiahao] Response status:', response.status);
|
|
|
|
|
|
|
+ // 昵称 - 多种选择器
|
|
|
|
|
+ const nameSelectors = [
|
|
|
|
|
+ '.user-name', '.userName', '[class*="userName"]', '[class*="nickname"]',
|
|
|
|
|
+ '.user-info .name', '.user-info h3', '.user-info h4',
|
|
|
|
|
+ '[class*="userInfo"] [class*="name"]', '.creator-name'
|
|
|
|
|
+ ];
|
|
|
|
|
+ for (const sel of nameSelectors) {
|
|
|
|
|
+ const el = document.querySelector(sel);
|
|
|
|
|
+ if (el && el.textContent?.trim()) {
|
|
|
|
|
+ result.accountName = el.textContent.trim();
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if (!response.ok) {
|
|
|
|
|
- return { success: false, error: 'HTTP ' + response.status };
|
|
|
|
|
|
|
+ // 从 URL 或 Cookie 提取 UID
|
|
|
|
|
+ const uidMatch = document.cookie.match(/passport_uid=([^;]+)/) ||
|
|
|
|
|
+ document.cookie.match(/uid=([^;]+)/) ||
|
|
|
|
|
+ document.cookie.match(/x-uuid=([^;]+)/);
|
|
|
|
|
+ if (uidMatch) {
|
|
|
|
|
+ result.accountId = 'douyin_' + uidMatch[1];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- const text = await response.text();
|
|
|
|
|
- console.log('[Baijiahao] Response text (first 300):', text.substring(0, 300));
|
|
|
|
|
|
|
+ // 尝试从 window 对象获取
|
|
|
|
|
+ if (window.__INITIAL_STATE__) {
|
|
|
|
|
+ const state = window.__INITIAL_STATE__;
|
|
|
|
|
+ if (state.user) {
|
|
|
|
|
+ result.accountName = result.accountName || state.user.nickname || state.user.name || '';
|
|
|
|
|
+ result.avatarUrl = result.avatarUrl || state.user.avatar || state.user.avatarUrl || '';
|
|
|
|
|
+ result.accountId = result.accountId || ('douyin_' + (state.user.uid || state.user.userId || ''));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- let data;
|
|
|
|
|
- try {
|
|
|
|
|
- data = JSON.parse(text);
|
|
|
|
|
- } catch (e) {
|
|
|
|
|
- return { success: false, error: 'JSON parse error: ' + e.message };
|
|
|
|
|
|
|
+ // 尝试从 SSR 数据获取
|
|
|
|
|
+ const ssrScript = document.querySelector('script[id*="RENDER_DATA"], script[type="application/json"]');
|
|
|
|
|
+ if (ssrScript) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const data = JSON.parse(decodeURIComponent(ssrScript.textContent || ''));
|
|
|
|
|
+ const user = data.user || data.userInfo || data.creator || {};
|
|
|
|
|
+ result.accountName = result.accountName || user.nickname || user.name || '';
|
|
|
|
|
+ result.avatarUrl = result.avatarUrl || user.avatar || user.avatarUrl || '';
|
|
|
|
|
+ result.accountId = result.accountId || ('douyin_' + (user.uid || user.userId || ''));
|
|
|
|
|
+ } catch {}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- console.log('[Baijiahao] settingInfo response:', JSON.stringify(data).substring(0, 300));
|
|
|
|
|
|
|
+ return result;
|
|
|
|
|
+ })()
|
|
|
|
|
+ `,
|
|
|
|
|
+ xiaohongshu: `
|
|
|
|
|
+ (function() {
|
|
|
|
|
+ const result = { accountId: '', accountName: '', avatarUrl: '', fansCount: 0, worksCount: 0 };
|
|
|
|
|
|
|
|
- if (data.errno === 0 && data.data) {
|
|
|
|
|
- const accountId = data.data.new_uc_id ? String(data.data.new_uc_id) : 'baijiahao_' + Date.now();
|
|
|
|
|
- const accountName = data.data.name || '百家号账号';
|
|
|
|
|
- const avatarUrl = data.data.avatar || '';
|
|
|
|
|
- console.log('[Baijiahao] 获取成功: id=' + accountId + ', name=' + accountName);
|
|
|
|
|
- return {
|
|
|
|
|
- success: true,
|
|
|
|
|
- accountId: accountId,
|
|
|
|
|
- accountName: accountName,
|
|
|
|
|
- avatarUrl: avatarUrl,
|
|
|
|
|
- };
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ const avatarEl = document.querySelector('.user-avatar img, [class*="avatar"] img');
|
|
|
|
|
+ if (avatarEl) result.avatarUrl = avatarEl.src || '';
|
|
|
|
|
|
|
|
- return { success: false, errno: data.errno, errmsg: data.errmsg || 'Unknown error' };
|
|
|
|
|
- } catch (e) {
|
|
|
|
|
- console.error('[Baijiahao] Error:', e);
|
|
|
|
|
- return { success: false, error: e.message || String(e) };
|
|
|
|
|
- }
|
|
|
|
|
- })()
|
|
|
|
|
- `;
|
|
|
|
|
-
|
|
|
|
|
- console.log('[BrowserTab] 执行 JavaScript 脚本...');
|
|
|
|
|
- const result = await webviewRef.value.executeJavaScript(script);
|
|
|
|
|
- console.log('[BrowserTab] 百家号账号信息结果:', JSON.stringify(result));
|
|
|
|
|
|
|
+ const nameEl = document.querySelector('.user-name, [class*="userName"], [class*="nickname"]');
|
|
|
|
|
+ if (nameEl) result.accountName = nameEl.textContent?.trim() || '';
|
|
|
|
|
+
|
|
|
|
|
+ const uidMatch = document.cookie.match(/customerClientId=([^;]+)/) ||
|
|
|
|
|
+ document.cookie.match(/web_session=([^;]+)/);
|
|
|
|
|
+ if (uidMatch) result.accountId = 'xiaohongshu_' + uidMatch[1].slice(0, 16);
|
|
|
|
|
+
|
|
|
|
|
+ return result;
|
|
|
|
|
+ })()
|
|
|
|
|
+ `,
|
|
|
|
|
+ kuaishou: `
|
|
|
|
|
+ (function() {
|
|
|
|
|
+ const result = { accountId: '', accountName: '', avatarUrl: '', fansCount: 0, worksCount: 0 };
|
|
|
|
|
+
|
|
|
|
|
+ const avatarEl = document.querySelector('.user-avatar img, [class*="avatar"] img');
|
|
|
|
|
+ if (avatarEl) result.avatarUrl = avatarEl.src || '';
|
|
|
|
|
+
|
|
|
|
|
+ const nameEl = document.querySelector('.user-name, [class*="userName"], [class*="nickname"]');
|
|
|
|
|
+ if (nameEl) result.accountName = nameEl.textContent?.trim() || '';
|
|
|
|
|
+
|
|
|
|
|
+ const uidMatch = document.cookie.match(/userId=([^;]+)/);
|
|
|
|
|
+ if (uidMatch) result.accountId = 'kuaishou_' + uidMatch[1];
|
|
|
|
|
+
|
|
|
|
|
+ return result;
|
|
|
|
|
+ })()
|
|
|
|
|
+ `,
|
|
|
|
|
+ baijiahao: `
|
|
|
|
|
+ (function() {
|
|
|
|
|
+ const result = { accountId: '', accountName: '', avatarUrl: '', fansCount: 0, worksCount: 0 };
|
|
|
|
|
+
|
|
|
|
|
+ const avatarEl = document.querySelector('.user-avatar img, [class*="avatar"] img, .header-avatar img');
|
|
|
|
|
+ if (avatarEl) result.avatarUrl = avatarEl.src || '';
|
|
|
|
|
+
|
|
|
|
|
+ const nameEl = document.querySelector('.user-name, [class*="userName"], [class*="nickname"], .header-name');
|
|
|
|
|
+ if (nameEl) result.accountName = nameEl.textContent?.trim() || '';
|
|
|
|
|
+
|
|
|
|
|
+ // 从 cookie 获取
|
|
|
|
|
+ const uidMatch = document.cookie.match(/BAIDUID=([^:;]+)/);
|
|
|
|
|
+ if (uidMatch) result.accountId = 'baijiahao_' + uidMatch[1];
|
|
|
|
|
+
|
|
|
|
|
+ return result;
|
|
|
|
|
+ })()
|
|
|
|
|
+ `,
|
|
|
|
|
+ bilibili: `
|
|
|
|
|
+ (function() {
|
|
|
|
|
+ const result = { accountId: '', accountName: '', avatarUrl: '', fansCount: 0, worksCount: 0 };
|
|
|
|
|
+
|
|
|
|
|
+ const avatarEl = document.querySelector('.user-avatar img, [class*="avatar"] img');
|
|
|
|
|
+ if (avatarEl) result.avatarUrl = avatarEl.src || '';
|
|
|
|
|
+
|
|
|
|
|
+ const nameEl = document.querySelector('.user-name, [class*="userName"], [class*="nickname"]');
|
|
|
|
|
+ if (nameEl) result.accountName = nameEl.textContent?.trim() || '';
|
|
|
|
|
+
|
|
|
|
|
+ const uidMatch = document.cookie.match(/DedeUserID=([^;]+)/);
|
|
|
|
|
+ if (uidMatch) result.accountId = 'bilibili_' + uidMatch[1];
|
|
|
|
|
+
|
|
|
|
|
+ return result;
|
|
|
|
|
+ })()
|
|
|
|
|
+ `,
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const script = extractScripts[platform.value];
|
|
|
|
|
+ if (!script) return null;
|
|
|
|
|
+
|
|
|
|
|
+ const info = await webview.executeJavaScript(script);
|
|
|
|
|
+ console.log(`[${platform.value}] Extracted account info from page:`, info);
|
|
|
|
|
|
|
|
- if (result?.success) {
|
|
|
|
|
- console.log('[BrowserTab] 获取百家号账号信息成功:', result.accountName);
|
|
|
|
|
|
|
+ // 验证提取结果
|
|
|
|
|
+ if (info && (info.accountName || info.accountId)) {
|
|
|
return {
|
|
return {
|
|
|
- accountId: result.accountId,
|
|
|
|
|
- accountName: result.accountName,
|
|
|
|
|
- avatarUrl: result.avatarUrl,
|
|
|
|
|
- fansCount: 0,
|
|
|
|
|
- worksCount: 0,
|
|
|
|
|
|
|
+ accountId: info.accountId || `${platform.value}_${Date.now()}`,
|
|
|
|
|
+ accountName: info.accountName || `${PLATFORMS[platform.value]?.name || platform.value}账号`,
|
|
|
|
|
+ avatarUrl: info.avatarUrl || '',
|
|
|
|
|
+ fansCount: info.fansCount || 0,
|
|
|
|
|
+ worksCount: info.worksCount || 0,
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- console.log('[BrowserTab] 获取百家号账号信息失败:', result?.error || result?.errmsg);
|
|
|
|
|
-
|
|
|
|
|
- // 如果失败且重试次数少于3次,等待后重试
|
|
|
|
|
- if (retryCount < 3) {
|
|
|
|
|
- console.log(`[BrowserTab] 获取百家号账号信息失败,${retryCount + 1}/3 次重试...`);
|
|
|
|
|
- await new Promise(resolve => setTimeout(resolve, 2000));
|
|
|
|
|
- return fetchBaijiahaoAccountInfo(retryCount + 1);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ return null;
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
- console.error('[BrowserTab] 获取百家号账号信息异常:', error);
|
|
|
|
|
- // 失败时重试
|
|
|
|
|
- if (retryCount < 3) {
|
|
|
|
|
- await new Promise(resolve => setTimeout(resolve, 2000));
|
|
|
|
|
- return fetchBaijiahaoAccountInfo(retryCount + 1);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ console.error('Failed to extract account info from page:', error);
|
|
|
|
|
+ return null;
|
|
|
}
|
|
}
|
|
|
- return null;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 快速登录成功(URL 已表明登录成功时使用)
|
|
// 快速登录成功(URL 已表明登录成功时使用)
|
|
@@ -505,44 +537,50 @@ async function quickLoginSuccess(cookies: Electron.Cookie[]) {
|
|
|
ElMessage.success('检测到登录成功!');
|
|
ElMessage.success('检测到登录成功!');
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 异步获取账号详细信息
|
|
|
|
|
|
|
+ // 设置正在获取账号信息状态
|
|
|
|
|
+ fetchingAccountInfo.value = true;
|
|
|
|
|
+ accountInfo.value = null;
|
|
|
|
|
+
|
|
|
|
|
+ // 第一步:尝试从当前页面直接提取账号信息(快速)
|
|
|
try {
|
|
try {
|
|
|
- // 百家号使用特殊方式获取账号信息(通过 webview 执行脚本)
|
|
|
|
|
- if (platform.value === 'baijiahao') {
|
|
|
|
|
- const baijiahaoInfo = await fetchBaijiahaoAccountInfo();
|
|
|
|
|
- if (baijiahaoInfo) {
|
|
|
|
|
- accountInfo.value = baijiahaoInfo;
|
|
|
|
|
- isVerifying = false;
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 其他平台通过服务器 API 验证
|
|
|
|
|
- const result = await accountsApi.verifyLoginCookie(platform.value, cookieString);
|
|
|
|
|
- if (result.success && result.accountInfo) {
|
|
|
|
|
- accountInfo.value = result.accountInfo;
|
|
|
|
|
- } else {
|
|
|
|
|
- // 即使获取详情失败,也保持登录成功状态
|
|
|
|
|
- accountInfo.value = {
|
|
|
|
|
- accountId: `${platform.value}_${Date.now()}`,
|
|
|
|
|
- accountName: `${PLATFORMS[platform.value]?.name || platform.value}账号`,
|
|
|
|
|
- avatarUrl: '',
|
|
|
|
|
- fansCount: 0,
|
|
|
|
|
- worksCount: 0,
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ const pageInfo = await extractAccountInfoFromPage();
|
|
|
|
|
+ if (pageInfo && pageInfo.accountName && pageInfo.accountName !== `${PLATFORMS[platform.value]?.name || platform.value}账号`) {
|
|
|
|
|
+ console.log('[quickLoginSuccess] Got account info from page:', pageInfo);
|
|
|
|
|
+ accountInfo.value = pageInfo;
|
|
|
|
|
+ fetchingAccountInfo.value = false;
|
|
|
|
|
+ isVerifying = false;
|
|
|
|
|
+ return; // 成功从页面提取,无需调用后端 API
|
|
|
}
|
|
}
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
- // 获取详情失败,使用默认值
|
|
|
|
|
- accountInfo.value = {
|
|
|
|
|
- accountId: `${platform.value}_${Date.now()}`,
|
|
|
|
|
- accountName: `${PLATFORMS[platform.value]?.name || platform.value}账号`,
|
|
|
|
|
- avatarUrl: '',
|
|
|
|
|
- fansCount: 0,
|
|
|
|
|
- worksCount: 0,
|
|
|
|
|
- };
|
|
|
|
|
- } finally {
|
|
|
|
|
- isVerifying = false;
|
|
|
|
|
|
|
+ console.warn('[quickLoginSuccess] Failed to extract from page:', error);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ // 第二步:如果页面提取失败,后台异步获取
|
|
|
|
|
+ accountsApi.verifyLoginCookie(platform.value, cookieString)
|
|
|
|
|
+ .then(result => {
|
|
|
|
|
+ if (result.success && result.accountInfo) {
|
|
|
|
|
+ // 只有在用户还没保存时才更新
|
|
|
|
|
+ if (loginStatus.value === 'success') {
|
|
|
|
|
+ accountInfo.value = result.accountInfo;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch(() => {
|
|
|
|
|
+ // 静默失败,使用默认值
|
|
|
|
|
+ if (loginStatus.value === 'success' && !accountInfo.value) {
|
|
|
|
|
+ accountInfo.value = {
|
|
|
|
|
+ accountId: `${platform.value}_${Date.now()}`,
|
|
|
|
|
+ accountName: `${PLATFORMS[platform.value]?.name || platform.value}账号`,
|
|
|
|
|
+ avatarUrl: '',
|
|
|
|
|
+ fansCount: 0,
|
|
|
|
|
+ worksCount: 0,
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ .finally(() => {
|
|
|
|
|
+ fetchingAccountInfo.value = false;
|
|
|
|
|
+ isVerifying = false;
|
|
|
|
|
+ });
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 检查是否有登录 cookie
|
|
// 检查是否有登录 cookie
|
|
@@ -619,26 +657,7 @@ async function verifyLoginWithServer(cookies: Electron.Cookie[], silent = false)
|
|
|
cookieData.value = cookieString;
|
|
cookieData.value = cookieString;
|
|
|
|
|
|
|
|
try {
|
|
try {
|
|
|
- // 百家号使用特殊方式获取账号信息(通过 webview 执行脚本)
|
|
|
|
|
- if (platform.value === 'baijiahao') {
|
|
|
|
|
- const baijiahaoInfo = await fetchBaijiahaoAccountInfo();
|
|
|
|
|
- if (baijiahaoInfo) {
|
|
|
|
|
- if (loginStatus.value !== 'success') {
|
|
|
|
|
- loginStatus.value = 'success';
|
|
|
|
|
- accountInfo.value = baijiahaoInfo;
|
|
|
|
|
- stopAutoCheck();
|
|
|
|
|
-
|
|
|
|
|
- if (!hasShownSuccessMessage) {
|
|
|
|
|
- hasShownSuccessMessage = true;
|
|
|
|
|
- ElMessage.success('检测到登录成功!');
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- isVerifying = false;
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 其他平台调用服务器 API 验证并获取账号信息
|
|
|
|
|
|
|
+ // 所有平台统一调用服务器 API 验证并获取账号信息
|
|
|
const result = await accountsApi.verifyLoginCookie(platform.value, cookieString);
|
|
const result = await accountsApi.verifyLoginCookie(platform.value, cookieString);
|
|
|
|
|
|
|
|
if (result.success && result.accountInfo) {
|
|
if (result.success && result.accountInfo) {
|
|
@@ -646,6 +665,7 @@ async function verifyLoginWithServer(cookies: Electron.Cookie[], silent = false)
|
|
|
if (loginStatus.value !== 'success') {
|
|
if (loginStatus.value !== 'success') {
|
|
|
loginStatus.value = 'success';
|
|
loginStatus.value = 'success';
|
|
|
accountInfo.value = result.accountInfo;
|
|
accountInfo.value = result.accountInfo;
|
|
|
|
|
+ fetchingAccountInfo.value = false;
|
|
|
stopAutoCheck();
|
|
stopAutoCheck();
|
|
|
|
|
|
|
|
// 只显示一次成功消息
|
|
// 只显示一次成功消息
|
|
@@ -1042,6 +1062,26 @@ watch(() => props.tab.id, () => {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+.account-fetching {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ gap: 10px;
|
|
|
|
|
+ padding: 16px 24px;
|
|
|
|
|
+ background: $primary-color-light;
|
|
|
|
|
+ border-radius: $radius-lg;
|
|
|
|
|
+ margin: 24px 0;
|
|
|
|
|
+ border: 1px solid $border-light;
|
|
|
|
|
+ color: $text-secondary;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+
|
|
|
|
|
+ .fetching-icon {
|
|
|
|
|
+ font-size: 18px;
|
|
|
|
|
+ color: $primary-color;
|
|
|
|
|
+ animation: spin 1s linear infinite;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
.account-preview {
|
|
.account-preview {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
align-items: center;
|
|
align-items: center;
|