live-forum/server/admin/browser-extension/live-forum-cookie/popup/popup.js
2026-03-24 11:27:37 +08:00

389 lines
10 KiB
JavaScript

/**
* 帅库之家Cookie管理 - 弹出页面脚本
*/
// 平台配置
const PLATFORMS = {
'commerce': {
name: '巨量百应-达人账号',
code: 'commerce'
},
'entertainment': {
name: '字节联盟-主播排行',
code: 'entertainment'
}
};
// DOM元素
let notConfiguredEl;
let platformListEl;
let modalEl;
let modalTitleEl;
let modalHintEl;
let cookieTextareaEl;
let modalCopyBtn;
let modalUploadBtn;
let modalCancelBtn;
// 当前操作的平台代码
let currentPlatformCode = null;
// 弹窗模式: 'view' | 'edit'
let modalMode = 'view';
/**
* 初始化
*/
document.addEventListener('DOMContentLoaded', async () => {
notConfiguredEl = document.getElementById('not-configured');
platformListEl = document.getElementById('platform-list');
modalEl = document.getElementById('cookie-modal');
modalTitleEl = document.getElementById('modal-title');
modalHintEl = document.getElementById('modal-hint');
cookieTextareaEl = document.getElementById('cookie-textarea');
modalCopyBtn = document.getElementById('modal-copy');
modalUploadBtn = document.getElementById('modal-upload');
modalCancelBtn = document.getElementById('modal-cancel');
// 绑定事件
document.getElementById('btn-config').addEventListener('click', openSettings);
document.getElementById('btn-refresh').addEventListener('click', refreshStatus);
document.getElementById('btn-settings').addEventListener('click', openSettings);
// 弹窗事件
document.getElementById('modal-close').addEventListener('click', closeModal);
document.querySelector('.modal-overlay').addEventListener('click', closeModal);
modalCopyBtn.addEventListener('click', copyCookie);
modalUploadBtn.addEventListener('click', uploadManualCookie);
modalCancelBtn.addEventListener('click', closeModal);
// 加载数据
await loadData();
});
/**
* 加载数据
*/
async function loadData() {
try {
// 获取配置
const configResponse = await sendMessage({ action: 'getConfig' });
const config = configResponse.data;
// 检查是否已配置
if (!config.apiKey) {
notConfiguredEl.style.display = 'flex';
renderPlatforms({});
return;
}
notConfiguredEl.style.display = 'none';
// 获取状态
const statusResponse = await sendMessage({ action: 'getStatus' });
const status = statusResponse.data || {};
renderPlatforms(status);
} catch (error) {
console.error('加载数据失败:', error);
}
}
/**
* 渲染平台列表
*/
function renderPlatforms(status) {
platformListEl.innerHTML = '';
for (const [code, platform] of Object.entries(PLATFORMS)) {
const platformStatus = status[code] || {};
const isValid = platformStatus.isValid === true;
const lastRunStatus = platformStatus.lastRunStatus;
const isCookieExpired = lastRunStatus === 3 || !isValid;
const statusText = isCookieExpired ? 'Cookie已过期' :
isValid ? 'Cookie有效' : '未上传';
const statusClass = isCookieExpired ? 'expired' :
isValid ? 'valid' : 'unknown';
const lastUpdate = platformStatus.updatedAt ?
formatDate(new Date(platformStatus.updatedAt)) : '从未';
const el = document.createElement('div');
el.className = 'platform-item';
el.innerHTML = `
<div class="platform-header">
<span class="platform-name">${platform.name}</span>
<span class="platform-status">
<span class="status-dot ${statusClass}"></span>
<span>${statusText}</span>
</span>
</div>
<div class="platform-info">
<p>最后更新: ${lastUpdate}</p>
${platformStatus.lastRunMessage ? `<p>最后状态: ${platformStatus.lastRunMessage}</p>` : ''}
</div>
<div class="platform-actions">
<button class="btn btn-primary btn-upload" data-code="${code}" title="从浏览器获取Cookie并上传">
上传
</button>
<button class="btn btn-secondary btn-view" data-code="${code}" title="查看当前Cookie">
查看
</button>
<button class="btn btn-secondary btn-edit" data-code="${code}" title="手动输入Cookie上传">
手动
</button>
${isCookieExpired ? `
<button class="btn btn-danger btn-login" data-code="${code}" title="跳转到登录页">
登录
</button>
` : ''}
</div>
`;
platformListEl.appendChild(el);
}
// 绑定按钮事件
document.querySelectorAll('.btn-upload').forEach(btn => {
btn.addEventListener('click', () => uploadCookie(btn.dataset.code));
});
document.querySelectorAll('.btn-view').forEach(btn => {
btn.addEventListener('click', () => viewCookie(btn.dataset.code));
});
document.querySelectorAll('.btn-edit').forEach(btn => {
btn.addEventListener('click', () => editCookie(btn.dataset.code));
});
document.querySelectorAll('.btn-login').forEach(btn => {
btn.addEventListener('click', () => openLogin(btn.dataset.code));
});
}
/**
* 上传Cookie (从浏览器获取)
*/
async function uploadCookie(code) {
const btn = document.querySelector(`.btn-upload[data-code="${code}"]`);
const originalText = btn.textContent;
try {
btn.disabled = true;
btn.innerHTML = '<span class="loading"></span>';
const response = await sendMessage({ action: 'uploadCookie', code });
if (response.success) {
btn.textContent = '成功';
btn.classList.add('success');
setTimeout(() => {
btn.textContent = originalText;
btn.classList.remove('success');
loadData();
}, 1000);
} else {
throw new Error(response.error);
}
} catch (error) {
alert('上传失败: ' + error.message);
btn.textContent = originalText;
} finally {
btn.disabled = false;
}
}
/**
* 查看Cookie
*/
async function viewCookie(code) {
currentPlatformCode = code;
modalMode = 'view';
try {
const response = await sendMessage({ action: 'getCookieString', code });
if (response.success) {
const platformName = PLATFORMS[code]?.name || code;
modalTitleEl.textContent = `查看Cookie - ${platformName}`;
modalHintEl.textContent = '当前浏览器中的Cookie字符串';
cookieTextareaEl.value = response.data;
cookieTextareaEl.readOnly = true;
modalCopyBtn.style.display = 'inline-block';
modalUploadBtn.style.display = 'none';
showModal();
} else {
alert('获取Cookie失败: ' + response.error);
}
} catch (error) {
alert('获取Cookie失败: ' + error.message);
}
}
/**
* 手动编辑Cookie
*/
function editCookie(code) {
currentPlatformCode = code;
modalMode = 'edit';
const platformName = PLATFORMS[code]?.name || code;
modalTitleEl.textContent = `手动设置Cookie - ${platformName}`;
modalHintEl.textContent = '粘贴从浏览器DevTools复制的Cookie字符串';
cookieTextareaEl.value = '';
cookieTextareaEl.readOnly = false;
cookieTextareaEl.placeholder = 'name=value; name2=value2; ...';
modalCopyBtn.style.display = 'none';
modalUploadBtn.style.display = 'inline-block';
showModal();
}
/**
* 复制Cookie
*/
async function copyCookie() {
try {
await navigator.clipboard.writeText(cookieTextareaEl.value);
const originalText = modalCopyBtn.textContent;
modalCopyBtn.textContent = '已复制';
setTimeout(() => {
modalCopyBtn.textContent = originalText;
}, 1500);
} catch (error) {
// 降级方案
cookieTextareaEl.select();
document.execCommand('copy');
const originalText = modalCopyBtn.textContent;
modalCopyBtn.textContent = '已复制';
setTimeout(() => {
modalCopyBtn.textContent = originalText;
}, 1500);
}
}
/**
* 手动上传Cookie
*/
async function uploadManualCookie() {
const cookieString = cookieTextareaEl.value.trim();
if (!cookieString) {
alert('请输入Cookie字符串');
return;
}
try {
modalUploadBtn.disabled = true;
modalUploadBtn.textContent = '上传中...';
const response = await sendMessage({
action: 'uploadCookie',
code: currentPlatformCode,
cookieString: cookieString
});
if (response.success) {
modalUploadBtn.textContent = '成功';
setTimeout(() => {
closeModal();
loadData();
}, 1000);
} else {
throw new Error(response.error);
}
} catch (error) {
alert('上传失败: ' + error.message);
modalUploadBtn.textContent = '上传';
} finally {
modalUploadBtn.disabled = false;
}
}
/**
* 显示弹窗
*/
function showModal() {
modalEl.style.display = 'flex';
if (modalMode === 'edit') {
cookieTextareaEl.focus();
}
}
/**
* 关闭弹窗
*/
function closeModal() {
modalEl.style.display = 'none';
cookieTextareaEl.value = '';
currentPlatformCode = null;
modalUploadBtn.textContent = '上传';
modalUploadBtn.disabled = false;
}
/**
* 打开登录页面
*/
async function openLogin(code) {
await sendMessage({ action: 'openLogin', code });
}
/**
* 刷新状态
*/
async function refreshStatus() {
const btn = document.getElementById('btn-refresh');
const originalText = btn.innerHTML;
try {
btn.disabled = true;
btn.innerHTML = '<span class="loading"></span> 刷新中...';
await sendMessage({ action: 'pollStatus' });
await loadData();
} catch (error) {
console.error('刷新失败:', error);
} finally {
btn.innerHTML = originalText;
btn.disabled = false;
}
}
/**
* 打开设置页面
*/
function openSettings() {
chrome.runtime.openOptionsPage();
}
/**
* 发送消息到后台
*/
function sendMessage(message) {
return new Promise((resolve, reject) => {
chrome.runtime.sendMessage(message, (response) => {
if (chrome.runtime.lastError) {
reject(new Error(chrome.runtime.lastError.message));
} else {
resolve(response);
}
});
});
}
/**
* 格式化日期
*/
function formatDate(date) {
const now = new Date();
const diff = now - date;
if (diff < 60000) {
return '刚刚';
} else if (diff < 3600000) {
return Math.floor(diff / 60000) + '分钟前';
} else if (diff < 86400000) {
return Math.floor(diff / 3600000) + '小时前';
} else {
return date.toLocaleDateString('zh-CN');
}
}