refactor(html): 优化前端页面

This commit is contained in:
cnlimiter
2026-03-19 01:58:57 +08:00
parent 9e6faecd6b
commit 93ab984200
8 changed files with 202 additions and 101 deletions

View File

@@ -439,6 +439,30 @@ body {
color: var(--text-secondary); color: var(--text-secondary);
} }
.btn-copy-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
padding: 0;
font-size: 11px;
line-height: 1;
background: var(--surface-hover);
border: 1px solid var(--border);
border-radius: 50%;
cursor: pointer;
color: var(--text-muted);
flex-shrink: 0;
transition: background 0.15s, color 0.15s;
}
.btn-copy-icon:hover {
background: var(--primary-light);
color: var(--primary-color);
border-color: var(--primary-color);
}
.btn-ghost:hover:not(:disabled) { .btn-ghost:hover:not(:disabled) {
background: var(--surface-hover); background: var(--surface-hover);
color: var(--text-primary); color: var(--text-primary);

View File

@@ -172,6 +172,7 @@ function initEventListeners() {
document.addEventListener('click', () => { document.addEventListener('click', () => {
elements.exportMenu.classList.remove('active'); elements.exportMenu.classList.remove('active');
uploadMenu.classList.remove('active'); uploadMenu.classList.remove('active');
document.querySelectorAll('#accounts-table .dropdown-menu.active').forEach(m => m.classList.remove('active'));
}); });
} }
@@ -289,21 +290,21 @@ function renderAccounts(accounts) {
</td> </td>
<td>${account.id}</td> <td>${account.id}</td>
<td> <td>
<span class="email-cell" title="${escapeHtml(account.email)}"> <span style="display:inline-flex;align-items:center;gap:4px;">
${escapeHtml(account.email)} <span class="email-cell" title="${escapeHtml(account.email)}">${escapeHtml(account.email)}</span>
<button class="btn-copy-icon copy-email-btn" data-email="${escapeHtml(account.email)}" title="复制邮箱">📋</button>
</span> </span>
</td> </td>
<td class="password-cell"> <td class="password-cell">
${account.password ${account.password
? `<span class="password-hidden" onclick="togglePassword(this, '${escapeHtml(account.password)}')" title="点击查看">${escapeHtml(account.password.substring(0, 4) + '****')}</span>` ? `<span style="display:inline-flex;align-items:center;gap:4px;">
<span class="password-hidden" data-pwd="${escapeHtml(account.password)}" onclick="togglePassword(this, this.dataset.pwd)" title="点击查看">${escapeHtml(account.password.substring(0, 4) + '****')}</span>
<button class="btn-copy-icon copy-pwd-btn" data-pwd="${escapeHtml(account.password)}" title="复制密码">📋</button>
</span>`
: '-'} : '-'}
</td> </td>
<td>${getServiceTypeText(account.email_service)}</td> <td>${getServiceTypeText(account.email_service)}</td>
<td> <td>${getStatusIcon(account.status)}</td>
<span class="status-badge ${getStatusClass('account', account.status)}">
${getStatusText('account', account.status)}
</span>
</td>
<td> <td>
<div class="cpa-status"> <div class="cpa-status">
${account.cpa_uploaded ${account.cpa_uploaded
@@ -320,26 +321,17 @@ function renderAccounts(accounts) {
</td> </td>
<td>${format.date(account.last_refresh) || '-'}</td> <td>${format.date(account.last_refresh) || '-'}</td>
<td> <td>
<div class="action-buttons"> <div style="display:flex;gap:4px;align-items:center;white-space:nowrap;">
<button class="btn btn-ghost btn-sm" onclick="refreshToken(${account.id})" title="刷新Token"> <button class="btn btn-secondary btn-sm" onclick="viewAccount(${account.id})">详情</button>
🔄 <div class="dropdown" style="position:relative;">
</button> <button class="btn btn-secondary btn-sm" onclick="event.stopPropagation();toggleMoreMenu(this)">更多</button>
<button class="btn btn-ghost btn-sm" onclick="uploadAccount(${account.id})" title="上传账号"> <div class="dropdown-menu" style="min-width:100px;">
☁️ <a href="#" class="dropdown-item" onclick="event.preventDefault();closeMoreMenu(this);refreshToken(${account.id})">刷新</a>
</button> <a href="#" class="dropdown-item" onclick="event.preventDefault();closeMoreMenu(this);uploadAccount(${account.id})">上传</a>
<button class="btn btn-ghost btn-sm" onclick="markSubscription(${account.id})" title="标记订阅"> <a href="#" class="dropdown-item" onclick="event.preventDefault();closeMoreMenu(this);markSubscription(${account.id})">标记</a>
🏷️ </div>
</button> </div>
<button class="btn btn-ghost btn-sm" onclick="viewAccount(${account.id})" title="查看详情"> <button class="btn btn-danger btn-sm" onclick="deleteAccount(${account.id}, '${escapeHtml(account.email)}')">删除</button>
👁️
</button>
<button class="btn btn-ghost btn-sm" onclick="copyEmail('${escapeHtml(account.email)}')" title="复制邮箱">
📋
</button>
${account.password ? `<button class="btn btn-ghost btn-sm" onclick="copyToClipboard('${escapeHtml(account.password)}')" title="复制密码">🔑</button>` : ''}
<button class="btn btn-ghost btn-sm" onclick="deleteAccount(${account.id}, '${escapeHtml(account.email)}')" title="删除">
🗑️
</button>
</div> </div>
</td> </td>
</tr> </tr>
@@ -365,6 +357,22 @@ function renderAccounts(accounts) {
}); });
}); });
// 绑定复制邮箱按钮
elements.table.querySelectorAll('.copy-email-btn').forEach(btn => {
btn.addEventListener('click', (e) => {
e.stopPropagation();
copyToClipboard(btn.dataset.email);
});
});
// 绑定复制密码按钮
elements.table.querySelectorAll('.copy-pwd-btn').forEach(btn => {
btn.addEventListener('click', (e) => {
e.stopPropagation();
copyToClipboard(btn.dataset.pwd);
});
});
// 渲染后同步全选框状态 // 渲染后同步全选框状态
const allCbs = elements.table.querySelectorAll('input[type="checkbox"][data-id]'); const allCbs = elements.table.querySelectorAll('input[type="checkbox"][data-id]');
const checkedCbs = elements.table.querySelectorAll('input[type="checkbox"][data-id]:checked'); const checkedCbs = elements.table.querySelectorAll('input[type="checkbox"][data-id]:checked');
@@ -1106,6 +1114,20 @@ async function handleBatchUploadTm() {
} }
} }
// 更多菜单切换
function toggleMoreMenu(btn) {
const menu = btn.nextElementSibling;
const isActive = menu.classList.contains('active');
// 关闭所有其他更多菜单
document.querySelectorAll('.dropdown-menu.active').forEach(m => m.classList.remove('active'));
if (!isActive) menu.classList.add('active');
}
function closeMoreMenu(el) {
const menu = el.closest('.dropdown-menu');
if (menu) menu.classList.remove('active');
}
// 保存账号 Cookies // 保存账号 Cookies
async function saveCookies(id) { async function saveCookies(id) {
const textarea = document.getElementById(`cookies-input-${id}`); const textarea = document.getElementById(`cookies-input-${id}`);

View File

@@ -898,27 +898,33 @@ async function loadRecentAccounts() {
<tr data-id="${account.id}"> <tr data-id="${account.id}">
<td>${account.id}</td> <td>${account.id}</td>
<td> <td>
<span title="${escapeHtml(account.email)}">${escapeHtml(account.email)}</span> <span style="display:inline-flex;align-items:center;gap:4px;">
</td> <span title="${escapeHtml(account.email)}">${escapeHtml(account.email)}</span>
<td class="password-cell"> <button class="btn-copy-icon copy-email-btn" data-email="${escapeHtml(account.email)}" title="复制邮箱">📋</button>
${account.password ? `<span class="password-hidden" title="点击查看">${escapeHtml(account.password.substring(0, 8))}...</span>` : '-'}
</td>
<td>
<span class="status-badge ${getStatusClass('account', account.status)}" style="font-size: 0.7rem;">
${getStatusText('account', account.status)}
</span> </span>
</td> </td>
<td class="password-cell">
${account.password
? `<span style="display:inline-flex;align-items:center;gap:4px;">
<span class="password-hidden" title="点击查看">${escapeHtml(account.password.substring(0, 8))}...</span>
<button class="btn-copy-icon copy-pwd-btn" data-pwd="${escapeHtml(account.password)}" title="复制密码">📋</button>
</span>`
: '-'}
</td>
<td> <td>
<div class="action-buttons"> ${getStatusIcon(account.status)}
<button class="btn btn-ghost btn-sm" onclick="copyToClipboard('${escapeHtml(account.email)}')" title="复制邮箱">
📋
</button>
${account.password ? `<button class="btn btn-ghost btn-sm" onclick="copyToClipboard('${escapeHtml(account.password)}')" title="复制密码">🔑</button>` : ''}
</div>
</td> </td>
</tr> </tr>
`).join(''); `).join('');
// 绑定复制按钮事件
elements.recentAccountsTable.querySelectorAll('.copy-email-btn').forEach(btn => {
btn.addEventListener('click', (e) => { e.stopPropagation(); copyToClipboard(btn.dataset.email); });
});
elements.recentAccountsTable.querySelectorAll('.copy-pwd-btn').forEach(btn => {
btn.addEventListener('click', (e) => { e.stopPropagation(); copyToClipboard(btn.dataset.pwd); });
});
} catch (error) { } catch (error) {
console.error('加载账号列表失败:', error); console.error('加载账号列表失败:', error);
} }

View File

@@ -145,6 +145,23 @@ function initEventListeners() {
// 临时邮箱配置 // 临时邮箱配置
elements.tempmailForm.addEventListener('submit', handleSaveTempmail); elements.tempmailForm.addEventListener('submit', handleSaveTempmail);
elements.testTempmailBtn.addEventListener('click', handleTestTempmail); elements.testTempmailBtn.addEventListener('click', handleTestTempmail);
// 点击其他地方关闭更多菜单
document.addEventListener('click', () => {
document.querySelectorAll('.dropdown-menu.active').forEach(m => m.classList.remove('active'));
});
}
function toggleEmailMoreMenu(btn) {
const menu = btn.nextElementSibling;
const isActive = menu.classList.contains('active');
document.querySelectorAll('.dropdown-menu.active').forEach(m => m.classList.remove('active'));
if (!isActive) menu.classList.add('active');
}
function closeEmailMoreMenu(el) {
const menu = el.closest('.dropdown-menu');
if (menu) menu.classList.remove('active');
} }
// 切换添加表单子类型 // 切换添加表单子类型
@@ -211,19 +228,20 @@ async function loadOutlookServices() {
${service.config?.has_oauth ? 'OAuth' : '密码'} ${service.config?.has_oauth ? 'OAuth' : '密码'}
</span> </span>
</td> </td>
<td> <td title="${service.enabled ? '已启用' : '已禁用'}">${service.enabled ? '✅' : '⭕'}</td>
<span class="status-badge ${service.enabled ? 'active' : 'disabled'}">
${service.enabled ? '启用' : '禁用'}
</span>
</td>
<td>${service.priority}</td> <td>${service.priority}</td>
<td>${format.date(service.last_used)}</td> <td>${format.date(service.last_used)}</td>
<td> <td>
<div class="action-buttons"> <div style="display:flex;gap:4px;align-items:center;white-space:nowrap;">
<button class="btn btn-ghost btn-sm" onclick="editOutlookService(${service.id})" title="编辑">✏️</button> <button class="btn btn-secondary btn-sm" onclick="editOutlookService(${service.id})">编辑</button>
<button class="btn btn-ghost btn-sm" onclick="toggleService(${service.id}, ${!service.enabled})" title="${service.enabled ? '禁用' : '启用'}">${service.enabled ? '🔇' : '🔊'}</button> <div class="dropdown" style="position:relative;">
<button class="btn btn-ghost btn-sm" onclick="testService(${service.id})" title="测试">🔌</button> <button class="btn btn-secondary btn-sm" onclick="event.stopPropagation();toggleEmailMoreMenu(this)">更多</button>
<button class="btn btn-ghost btn-sm" onclick="deleteService(${service.id}, '${escapeHtml(service.name)}')" title="删除">🗑️</button> <div class="dropdown-menu" style="min-width:80px;">
<a href="#" class="dropdown-item" onclick="event.preventDefault();closeEmailMoreMenu(this);toggleService(${service.id}, ${!service.enabled})">${service.enabled ? '禁用' : '启用'}</a>
<a href="#" class="dropdown-item" onclick="event.preventDefault();closeEmailMoreMenu(this);testService(${service.id})">测试</a>
</div>
</div>
<button class="btn btn-danger btn-sm" onclick="deleteService(${service.id}, '${escapeHtml(service.name)}')">删除</button>
</div> </div>
</td> </td>
</tr> </tr>
@@ -281,15 +299,20 @@ async function loadCustomServices() {
<td>${escapeHtml(service.name)}</td> <td>${escapeHtml(service.name)}</td>
<td>${typeLabel}</td> <td>${typeLabel}</td>
<td style="font-size: 0.75rem;">${escapeHtml(addr)}</td> <td style="font-size: 0.75rem;">${escapeHtml(addr)}</td>
<td><span class="status-badge ${service.enabled ? 'active' : 'disabled'}">${service.enabled ? '启用' : '禁用'}</span></td> <td title="${service.enabled ? '已启用' : '已禁用'}">${service.enabled ? '' : ''}</td>
<td>${service.priority}</td> <td>${service.priority}</td>
<td>${format.date(service.last_used)}</td> <td>${format.date(service.last_used)}</td>
<td> <td>
<div class="action-buttons"> <div style="display:flex;gap:4px;align-items:center;white-space:nowrap;">
<button class="btn btn-ghost btn-sm" onclick="editCustomService(${service.id}, '${service._subType}')" title="编辑">✏️</button> <button class="btn btn-secondary btn-sm" onclick="editCustomService(${service.id}, '${service._subType}')">编辑</button>
<button class="btn btn-ghost btn-sm" onclick="toggleService(${service.id}, ${!service.enabled})" title="${service.enabled ? '禁用' : '启用'}">${service.enabled ? '🔇' : '🔊'}</button> <div class="dropdown" style="position:relative;">
<button class="btn btn-ghost btn-sm" onclick="testService(${service.id})" title="测试">🔌</button> <button class="btn btn-secondary btn-sm" onclick="event.stopPropagation();toggleEmailMoreMenu(this)">更多</button>
<button class="btn btn-ghost btn-sm" onclick="deleteService(${service.id}, '${escapeHtml(service.name)}')" title="删除">🗑️</button> <div class="dropdown-menu" style="min-width:80px;">
<a href="#" class="dropdown-item" onclick="event.preventDefault();closeEmailMoreMenu(this);toggleService(${service.id}, ${!service.enabled})">${service.enabled ? '禁用' : '启用'}</a>
<a href="#" class="dropdown-item" onclick="event.preventDefault();closeEmailMoreMenu(this);testService(${service.id})">测试</a>
</div>
</div>
<button class="btn btn-danger btn-sm" onclick="deleteService(${service.id}, '${escapeHtml(service.name)}')">删除</button>
</div> </div>
</td> </td>
</tr>`; </tr>`;

View File

@@ -90,6 +90,10 @@ document.addEventListener('DOMContentLoaded', () => {
initEventListeners(); initEventListeners();
}); });
document.addEventListener('click', () => {
document.querySelectorAll('.dropdown-menu.active').forEach(m => m.classList.remove('active'));
});
// 初始化标签页 // 初始化标签页
function initTabs() { function initTabs() {
elements.tabs.forEach(btn => { elements.tabs.forEach(btn => {
@@ -424,11 +428,7 @@ function renderEmailServices(services) {
</td> </td>
<td>${escapeHtml(service.name)}</td> <td>${escapeHtml(service.name)}</td>
<td>${getServiceTypeText(service.service_type)}</td> <td>${getServiceTypeText(service.service_type)}</td>
<td> <td title="${service.enabled ? '已启用' : '已禁用'}">${service.enabled ? '✅' : '⭕'}</td>
<span class="status-badge ${service.enabled ? 'active' : 'disabled'}">
${service.enabled ? '已启用' : '已禁用'}
</span>
</td>
<td>${service.priority}</td> <td>${service.priority}</td>
<td>${format.date(service.last_used)}</td> <td>${format.date(service.last_used)}</td>
<td> <td>
@@ -811,32 +811,38 @@ function renderProxies(proxies) {
: `<button class="btn btn-ghost btn-sm" onclick="handleSetProxyDefault(${proxy.id})" title="设为默认">设默认</button>` : `<button class="btn btn-ghost btn-sm" onclick="handleSetProxyDefault(${proxy.id})" title="设为默认">设默认</button>`
} }
</td> </td>
<td> <td title="${proxy.enabled ? '已启用' : '已禁用'}">${proxy.enabled ? '✅' : '⭕'}</td>
<span class="status-badge ${proxy.enabled ? 'active' : 'disabled'}">
${proxy.enabled ? '已启用' : '已禁用'}
</span>
</td>
<td>${format.date(proxy.last_used)}</td> <td>${format.date(proxy.last_used)}</td>
<td> <td>
<div class="action-buttons"> <div style="display:flex;gap:4px;align-items:center;white-space:nowrap;">
<button class="btn btn-ghost btn-sm" onclick="testProxyItem(${proxy.id})" title="测试"> <button class="btn btn-secondary btn-sm" onclick="editProxyItem(${proxy.id})">编辑</button>
🔌 <div class="dropdown" style="position:relative;">
</button> <button class="btn btn-secondary btn-sm" onclick="event.stopPropagation();toggleSettingsMoreMenu(this)">更多</button>
<button class="btn btn-ghost btn-sm" onclick="editProxyItem(${proxy.id})" title="编辑"> <div class="dropdown-menu" style="min-width:80px;">
✏️ <a href="#" class="dropdown-item" onclick="event.preventDefault();closeSettingsMoreMenu(this);testProxyItem(${proxy.id})">测试</a>
</button> <a href="#" class="dropdown-item" onclick="event.preventDefault();closeSettingsMoreMenu(this);toggleProxyItem(${proxy.id}, ${!proxy.enabled})">${proxy.enabled ? '禁用' : '启用'}</a>
<button class="btn btn-ghost btn-sm" onclick="toggleProxyItem(${proxy.id}, ${!proxy.enabled})" title="${proxy.enabled ? '禁用' : '启用'}"> ${!proxy.is_default ? `<a href="#" class="dropdown-item" onclick="event.preventDefault();closeSettingsMoreMenu(this);handleSetProxyDefault(${proxy.id})">设为默认</a>` : ''}
${proxy.enabled ? '🔒' : '🔓'} </div>
</button> </div>
<button class="btn btn-ghost btn-sm" onclick="deleteProxyItem(${proxy.id})" title="删除"> <button class="btn btn-danger btn-sm" onclick="deleteProxyItem(${proxy.id})">删除</button>
🗑️
</button>
</div> </div>
</td> </td>
</tr> </tr>
`).join(''); `).join('');
} }
function toggleSettingsMoreMenu(btn) {
const menu = btn.nextElementSibling;
const isActive = menu.classList.contains('active');
document.querySelectorAll('.dropdown-menu.active').forEach(m => m.classList.remove('active'));
if (!isActive) menu.classList.add('active');
}
function closeSettingsMoreMenu(el) {
const menu = el.closest('.dropdown-menu');
if (menu) menu.classList.remove('active');
}
// 设为默认代理 // 设为默认代理
async function handleSetProxyDefault(id) { async function handleSetProxyDefault(id) {
try { try {
@@ -1070,11 +1076,7 @@ function renderTmServicesTable(services) {
<tr> <tr>
<td>${escapeHtml(s.name)}</td> <td>${escapeHtml(s.name)}</td>
<td style="font-size:0.85rem;color:var(--text-muted);">${escapeHtml(s.api_url)}</td> <td style="font-size:0.85rem;color:var(--text-muted);">${escapeHtml(s.api_url)}</td>
<td> <td style="text-align:center;" title="${s.enabled ? '已启用' : '已禁用'}">${s.enabled ? '✅' : '⭕'}</td>
<span class="badge" style="background:${s.enabled ? 'var(--success-color)' : 'var(--border)'};color:${s.enabled ? '#fff' : 'var(--text-muted)'};font-size:0.75rem;padding:2px 8px;border-radius:10px;">
${s.enabled ? '启用' : '禁用'}
</span>
</td>
<td style="text-align:center;">${s.priority}</td> <td style="text-align:center;">${s.priority}</td>
<td style="white-space:nowrap;"> <td style="white-space:nowrap;">
<button class="btn btn-secondary btn-sm" onclick="editTmService(${s.id})">编辑</button> <button class="btn btn-secondary btn-sm" onclick="editTmService(${s.id})">编辑</button>
@@ -1235,11 +1237,7 @@ function renderCpaServicesTable(services) {
<tr> <tr>
<td>${escapeHtml(s.name)}</td> <td>${escapeHtml(s.name)}</td>
<td style="font-size:0.85rem;color:var(--text-muted);">${escapeHtml(s.api_url)}</td> <td style="font-size:0.85rem;color:var(--text-muted);">${escapeHtml(s.api_url)}</td>
<td> <td style="text-align:center;" title="${s.enabled ? '已启用' : '已禁用'}">${s.enabled ? '✅' : '⭕'}</td>
<span class="badge" style="background:${s.enabled ? 'var(--success-color)' : 'var(--border)'};color:${s.enabled ? '#fff' : 'var(--text-muted)'};font-size:0.75rem;padding:2px 8px;border-radius:10px;">
${s.enabled ? '启用' : '禁用'}
</span>
</td>
<td style="text-align:center;">${s.priority}</td> <td style="text-align:center;">${s.priority}</td>
<td style="white-space:nowrap;"> <td style="white-space:nowrap;">
<button class="btn btn-secondary btn-sm" onclick="editCpaService(${s.id})">编辑</button> <button class="btn btn-secondary btn-sm" onclick="editCpaService(${s.id})">编辑</button>
@@ -1402,11 +1400,7 @@ function renderSub2ApiServices(services) {
<tr> <tr>
<td>${escapeHtml(s.name)}</td> <td>${escapeHtml(s.name)}</td>
<td style="font-size:0.85rem;color:var(--text-muted);">${escapeHtml(s.api_url)}</td> <td style="font-size:0.85rem;color:var(--text-muted);">${escapeHtml(s.api_url)}</td>
<td> <td style="text-align:center;" title="${s.enabled ? '已启用' : '已禁用'}">${s.enabled ? '✅' : '⭕'}</td>
<span class="badge" style="background:${s.enabled ? 'var(--success-color)' : 'var(--border)'};color:${s.enabled ? '#fff' : 'var(--text-muted)'};font-size:0.75rem;padding:2px 8px;border-radius:10px;">
${s.enabled ? '启用' : '禁用'}
</span>
</td>
<td style="text-align:center;">${s.priority}</td> <td style="text-align:center;">${s.priority}</td>
<td style="white-space:nowrap;"> <td style="white-space:nowrap;">
<button class="btn btn-secondary btn-sm" onclick="editSub2ApiService(${s.id})">编辑</button> <button class="btn btn-secondary btn-sm" onclick="editSub2ApiService(${s.id})">编辑</button>

View File

@@ -368,6 +368,19 @@ function getServiceTypeText(type) {
return statusMap.service[type] || type; return statusMap.service[type] || type;
} }
const accountStatusIconMap = {
active: { icon: '🟢', title: '活跃' },
expired: { icon: '🟡', title: '过期' },
banned: { icon: '🔴', title: '封禁' },
failed: { icon: '❌', title: '失败' },
};
function getStatusIcon(status) {
const s = accountStatusIconMap[status];
if (!s) return `<span title="${status}">⚪</span>`;
return `<span title="${s.title}">${s.icon}</span>`;
}
// ============================================ // ============================================
// 确认对话框 // 确认对话框
// ============================================ // ============================================
@@ -420,10 +433,29 @@ function confirm(message, title = '确认操作') {
// ============================================ // ============================================
async function copyToClipboard(text) { async function copyToClipboard(text) {
if (navigator.clipboard && navigator.clipboard.writeText) {
try {
await navigator.clipboard.writeText(text);
toast.success('已复制到剪贴板');
return true;
} catch (err) {
// 降级到 execCommand
}
}
try { try {
await navigator.clipboard.writeText(text); const ta = document.createElement('textarea');
toast.success('已复制到剪贴板'); ta.value = text;
return true; ta.style.cssText = 'position:fixed;top:0;left:0;opacity:0;pointer-events:none;';
document.body.appendChild(ta);
ta.focus();
ta.select();
const ok = document.execCommand('copy');
document.body.removeChild(ta);
if (ok) {
toast.success('已复制到剪贴板');
return true;
}
throw new Error('execCommand failed');
} catch (err) { } catch (err) {
toast.error('复制失败'); toast.error('复制失败');
return false; return false;
@@ -498,3 +530,4 @@ window.throttle = throttle;
window.getStatusText = getStatusText; window.getStatusText = getStatusText;
window.getStatusClass = getStatusClass; window.getStatusClass = getStatusClass;
window.getServiceTypeText = getServiceTypeText; window.getServiceTypeText = getServiceTypeText;
window.getStatusIcon = getStatusIcon;

View File

@@ -172,7 +172,7 @@
<th style="width: 80px;">CPA</th> <th style="width: 80px;">CPA</th>
<th style="width: 80px;">订阅</th> <th style="width: 80px;">订阅</th>
<th style="width: 140px;">最后刷新</th> <th style="width: 140px;">最后刷新</th>
<th style="width: 170px;">操作</th> <th style="width: 160px;">操作</th>
</tr> </tr>
</thead> </thead>
<tbody id="accounts-table"> <tbody id="accounts-table">

View File

@@ -386,7 +386,6 @@
<th>邮箱</th> <th>邮箱</th>
<th style="width: 120px;">密码</th> <th style="width: 120px;">密码</th>
<th style="width: 80px;">状态</th> <th style="width: 80px;">状态</th>
<th style="width: 80px;">操作</th>
</tr> </tr>
</thead> </thead>
<tbody id="recent-accounts-table"> <tbody id="recent-accounts-table">