|
|
@@ -59,13 +59,19 @@
|
|
|
<div class="success-content">
|
|
|
<el-icon class="success-icon"><CircleCheck /></el-icon>
|
|
|
<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>
|
|
|
<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>
|
|
|
<p>点击"保存账号"完成添加</p>
|
|
|
@@ -117,6 +123,7 @@ const accountInfo = ref<{
|
|
|
worksCount: number;
|
|
|
} | null>(null);
|
|
|
const cookieData = ref('');
|
|
|
+const fetchingAccountInfo = ref(false); // 是否正在获取账号信息
|
|
|
|
|
|
// 计时器和标志位
|
|
|
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 hasValidAccountInfo = computed(() => {
|
|
|
+ if (!accountInfo.value) return false;
|
|
|
+ const defaultNames = [
|
|
|
+ '抖音账号', '小红书账号', '快手账号', '视频号账号', 'B站账号',
|
|
|
+ '头条账号', '百家号账号', '企鹅号账号', '大鱼号账号'
|
|
|
+ ];
|
|
|
+ return accountInfo.value.accountName && !defaultNames.includes(accountInfo.value.accountName);
|
|
|
+});
|
|
|
+
|
|
|
const initialUrl = computed(() => {
|
|
|
// 优先使用 browserData 中指定的 URL
|
|
|
if (props.tab.browserData?.url) {
|
|
|
@@ -191,20 +208,6 @@ function handleNavigate(event: Electron.DidNavigateEvent) {
|
|
|
if (!isAdminMode.value && loginStatus.value !== 'success') {
|
|
|
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) {
|
|
|
@@ -277,7 +280,7 @@ function isLoggedInByUrl(): boolean {
|
|
|
xiaohongshu: [/passport/, /login/i],
|
|
|
bilibili: [/passport/, /login/i],
|
|
|
toutiao: [/passport/, /login/i],
|
|
|
- baijiahao: [/passport/, /login/i],
|
|
|
+ baijiahao: [/passport/, /login/i, /bjh\/login/], // 包含 /builder/theme/bjh/login
|
|
|
};
|
|
|
|
|
|
// 如果在登录页面,返回 false
|
|
|
@@ -311,7 +314,10 @@ function isLoggedInByUrl(): boolean {
|
|
|
/mp\.toutiao\.com\/profile/,
|
|
|
],
|
|
|
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,229 @@ async function checkLoginSilently() {
|
|
|
// 简单判断是否有登录相关的 cookie
|
|
|
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') {
|
|
|
// 检查 URL 是否已经在登录后的页面
|
|
|
const urlIndicatesLoggedIn = isLoggedInByUrl();
|
|
|
|
|
|
- if (platform.value === 'baijiahao') {
|
|
|
- console.log('[BrowserTab] 百家号检测 - urlIndicatesLoggedIn:', urlIndicatesLoggedIn);
|
|
|
- }
|
|
|
-
|
|
|
if (urlIndicatesLoggedIn) {
|
|
|
// URL 表明已登录,快速响应:先显示成功,再异步获取详情
|
|
|
- console.log('[BrowserTab] URL 表明已登录,调用 quickLoginSuccess');
|
|
|
await quickLoginSuccess(cookies);
|
|
|
} else {
|
|
|
// 还在登录页面,通过服务器验证
|
|
|
- console.log('[BrowserTab] 通过服务器验证登录');
|
|
|
await verifyLoginWithServer(cookies, true);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
} catch (error) {
|
|
|
// 静默失败,不处理
|
|
|
- console.error('[BrowserTab] checkLoginSilently 异常:', error);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// 通过 webview 执行脚本获取百家号账号信息
|
|
|
-async function fetchBaijiahaoAccountInfo(retryCount = 0): Promise<{
|
|
|
+// 从页面直接提取账号信息
|
|
|
+async function extractAccountInfoFromPage(): Promise<{
|
|
|
accountId: string;
|
|
|
accountName: string;
|
|
|
avatarUrl: string;
|
|
|
fansCount: number;
|
|
|
worksCount: number;
|
|
|
} | null> {
|
|
|
- console.log('[BrowserTab] fetchBaijiahaoAccountInfo 开始, retryCount:', retryCount);
|
|
|
-
|
|
|
- if (!webviewRef.value) {
|
|
|
- console.log('[BrowserTab] webviewRef 不存在');
|
|
|
+ const webview = webviewRef.value;
|
|
|
+ if (!webview) {
|
|
|
+ console.warn('[extractAccountInfoFromPage] webviewRef is null');
|
|
|
return null;
|
|
|
}
|
|
|
-
|
|
|
- // 等待页面加载完成
|
|
|
- console.log('[BrowserTab] 等待1秒让页面加载...');
|
|
|
- await new Promise(resolve => setTimeout(resolve, 1000));
|
|
|
-
|
|
|
+
|
|
|
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/'
|
|
|
+ try {
|
|
|
+ // 抖音创作服务平台页面(summon.bytedance.com)
|
|
|
+ // 1. 查找头像 - 通常是较大的圆形图片
|
|
|
+ const imgs = Array.from(document.querySelectorAll('img'));
|
|
|
+ for (const img of imgs) {
|
|
|
+ const src = img.src || '';
|
|
|
+ const style = window.getComputedStyle(img);
|
|
|
+ const isRound = style.borderRadius && (style.borderRadius.includes('50%') || parseInt(style.borderRadius) > 20);
|
|
|
+ const isAvatarSize = img.width >= 40 && img.width <= 150;
|
|
|
+ const isAvatarUrl = src.includes('avatar') || src.includes('aweme') || src.includes('douyinpic') || src.includes('bytedance');
|
|
|
+
|
|
|
+ if ((isRound || isAvatarUrl) && isAvatarSize && src.startsWith('http')) {
|
|
|
+ result.avatarUrl = src;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 查找抖音号 - 格式通常是 "抖音号:xxx"
|
|
|
+ const bodyText = document.body.innerText;
|
|
|
+ const douyinIdMatch = bodyText.match(/抖音号[::]\s*([a-zA-Z0-9_]+)/);
|
|
|
+ if (douyinIdMatch) {
|
|
|
+ result.accountId = 'douyin_' + douyinIdMatch[1];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 查找昵称 - 通常在抖音号附近,或者在用户信息区域
|
|
|
+ // 先找到抖音号所在的元素,然后向上找用户名
|
|
|
+ const allElements = document.querySelectorAll('*');
|
|
|
+ let userInfoContainer = null;
|
|
|
+
|
|
|
+ for (const el of allElements) {
|
|
|
+ const text = el.innerText || '';
|
|
|
+ if (text.includes('抖音号') && text.length < 200) {
|
|
|
+ userInfoContainer = el.parentElement || el;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (userInfoContainer) {
|
|
|
+ // 在用户信息容器中查找昵称(通常是第一个非空的短文本)
|
|
|
+ const children = userInfoContainer.querySelectorAll('span, div, p, a');
|
|
|
+ for (const child of children) {
|
|
|
+ const text = child.innerText?.trim() || '';
|
|
|
+ // 昵称特征:2-20字符,不是纯数字,不包含特殊词
|
|
|
+ if (text.length >= 2 && text.length <= 20 &&
|
|
|
+ !/^[0-9]+$/.test(text) &&
|
|
|
+ !text.includes('抖音号') && !text.includes('粉丝') &&
|
|
|
+ !text.includes('关注') && !text.includes('获赞') &&
|
|
|
+ !text.includes('家人') && !text.includes('@')) {
|
|
|
+ result.accountName = text;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 备选:遍历页面查找看起来像用户名的文本
|
|
|
+ if (!result.accountName) {
|
|
|
+ const candidates = [];
|
|
|
+ document.querySelectorAll('span, div').forEach(el => {
|
|
|
+ const text = el.innerText?.trim() || '';
|
|
|
+ const rect = el.getBoundingClientRect();
|
|
|
+ // 筛选条件:可见、长度适中、包含中文或字母
|
|
|
+ if (rect.width > 0 && text.length >= 2 && text.length <= 25 &&
|
|
|
+ /[\u4e00-\u9fa5a-zA-Z]/.test(text) &&
|
|
|
+ !/粉丝|关注|获赞|作品|发布|数据|登录|注册/.test(text)) {
|
|
|
+ candidates.push({ text, top: rect.top, left: rect.left });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ // 优先选择靠上方、靠左侧的(通常是用户名位置)
|
|
|
+ candidates.sort((a, b) => (a.top + a.left) - (b.top + b.left));
|
|
|
+ if (candidates.length > 0) {
|
|
|
+ result.accountName = candidates[0].text;
|
|
|
+ }
|
|
|
}
|
|
|
- });
|
|
|
+
|
|
|
+ // 5. 从 Cookie 获取 UID 作为备选
|
|
|
+ if (!result.accountId) {
|
|
|
+ const uidMatch = document.cookie.match(/passport_uid=([^;]+)/) ||
|
|
|
+ document.cookie.match(/uid_tt=([^;]+)/) ||
|
|
|
+ document.cookie.match(/ttwid=1%7C([^%|]+)/);
|
|
|
+ if (uidMatch) {
|
|
|
+ result.accountId = 'douyin_' + uidMatch[1];
|
|
|
+ } else {
|
|
|
+ result.accountId = 'douyin_' + Date.now();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (e) {
|
|
|
+ console.error('[Douyin Extract] Error:', e);
|
|
|
+ }
|
|
|
|
|
|
- console.log('[Baijiahao] Response status:', response.status);
|
|
|
+ console.log('[Douyin Extract] Result:', result);
|
|
|
+ return result;
|
|
|
+ })()
|
|
|
+ `,
|
|
|
+ xiaohongshu: `
|
|
|
+ (function() {
|
|
|
+ const result = { accountId: '', accountName: '', avatarUrl: '', fansCount: 0, worksCount: 0 };
|
|
|
|
|
|
- if (!response.ok) {
|
|
|
- return { success: false, error: 'HTTP ' + response.status };
|
|
|
- }
|
|
|
+ const avatarEl = document.querySelector('.user-avatar img, [class*="avatar"] img');
|
|
|
+ if (avatarEl) result.avatarUrl = avatarEl.src || '';
|
|
|
|
|
|
- const text = await response.text();
|
|
|
- console.log('[Baijiahao] Response text (first 300):', text.substring(0, 300));
|
|
|
+ const nameEl = document.querySelector('.user-name, [class*="userName"], [class*="nickname"]');
|
|
|
+ if (nameEl) result.accountName = nameEl.textContent?.trim() || '';
|
|
|
|
|
|
- let data;
|
|
|
- try {
|
|
|
- data = JSON.parse(text);
|
|
|
- } catch (e) {
|
|
|
- return { success: false, error: 'JSON parse error: ' + e.message };
|
|
|
- }
|
|
|
+ const uidMatch = document.cookie.match(/customerClientId=([^;]+)/) ||
|
|
|
+ document.cookie.match(/web_session=([^;]+)/);
|
|
|
+ if (uidMatch) result.accountId = 'xiaohongshu_' + uidMatch[1].slice(0, 16);
|
|
|
|
|
|
- console.log('[Baijiahao] settingInfo response:', JSON.stringify(data).substring(0, 300));
|
|
|
+ return result;
|
|
|
+ })()
|
|
|
+ `,
|
|
|
+ kuaishou: `
|
|
|
+ (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(/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 {
|
|
|
- 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) {
|
|
|
- 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 已表明登录成功时使用)
|
|
|
@@ -505,44 +582,50 @@ async function quickLoginSuccess(cookies: Electron.Cookie[]) {
|
|
|
ElMessage.success('检测到登录成功!');
|
|
|
}
|
|
|
|
|
|
- // 异步获取账号详细信息
|
|
|
+ // 设置正在获取账号信息状态
|
|
|
+ fetchingAccountInfo.value = true;
|
|
|
+ accountInfo.value = null;
|
|
|
+
|
|
|
+ // 第一步:尝试从当前页面直接提取账号信息(快速)
|
|
|
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) {
|
|
|
- // 获取详情失败,使用默认值
|
|
|
- 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
|
|
|
@@ -619,26 +702,7 @@ async function verifyLoginWithServer(cookies: Electron.Cookie[], silent = false)
|
|
|
cookieData.value = cookieString;
|
|
|
|
|
|
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);
|
|
|
|
|
|
if (result.success && result.accountInfo) {
|
|
|
@@ -646,6 +710,7 @@ async function verifyLoginWithServer(cookies: Electron.Cookie[], silent = false)
|
|
|
if (loginStatus.value !== 'success') {
|
|
|
loginStatus.value = 'success';
|
|
|
accountInfo.value = result.accountInfo;
|
|
|
+ fetchingAccountInfo.value = false;
|
|
|
stopAutoCheck();
|
|
|
|
|
|
// 只显示一次成功消息
|
|
|
@@ -1042,6 +1107,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 {
|
|
|
display: flex;
|
|
|
align-items: center;
|