Add refund received toggle button and filter options
- Add refund_received column to claude_payment_status table
- API endpoint POST /api/tools/refund-received/{email} to toggle
- Clickable badge in table to mark refund as received/not received
- Filter options: refund received / refund not received
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -131,6 +131,15 @@ class MailManager {
|
||||
}
|
||||
});
|
||||
|
||||
// 退款到账按钮 — 事件委托
|
||||
document.getElementById('accountTableBody').addEventListener('click', (e) => {
|
||||
const btn = e.target.closest('.refund-received-btn');
|
||||
if (!btn) return;
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.toggleRefundReceived(btn.dataset.email);
|
||||
});
|
||||
|
||||
// 代理按钮 — 事件委托打开弹窗 + 复制代理
|
||||
document.getElementById('accountTableBody').addEventListener('click', (e) => {
|
||||
// 复制代理
|
||||
@@ -248,7 +257,7 @@ class MailManager {
|
||||
|
||||
async loadAccounts() {
|
||||
const tbody = document.getElementById('accountTableBody');
|
||||
tbody.innerHTML = `<tr><td colspan="13"><div class="table-loading"><div class="spinner-border spinner-border-sm"></div> 加载中...</div></td></tr>`;
|
||||
tbody.innerHTML = `<tr><td colspan="14"><div class="table-loading"><div class="spinner-border spinner-border-sm"></div> 加载中...</div></td></tr>`;
|
||||
|
||||
try {
|
||||
// 有筛选时加载全部数据,否则分页加载
|
||||
@@ -268,23 +277,25 @@ class MailManager {
|
||||
await this.loadClaudePaymentStatuses();
|
||||
this.applyFilterAndRender();
|
||||
} else {
|
||||
tbody.innerHTML = `<tr><td colspan="13"><div class="no-data"><i class="bi bi-exclamation-circle"></i><div>${this.escapeHtml(result.message || '加载失败')}</div></div></td></tr>`;
|
||||
tbody.innerHTML = `<tr><td colspan="14"><div class="no-data"><i class="bi bi-exclamation-circle"></i><div>${this.escapeHtml(result.message || '加载失败')}</div></div></td></tr>`;
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('加载账号失败:', err);
|
||||
tbody.innerHTML = `<tr><td colspan="13"><div class="no-data"><i class="bi bi-wifi-off"></i><div>网络错误</div></div></td></tr>`;
|
||||
tbody.innerHTML = `<tr><td colspan="14"><div class="no-data"><i class="bi bi-wifi-off"></i><div>网络错误</div></div></td></tr>`;
|
||||
}
|
||||
}
|
||||
|
||||
_matchPaymentFilter(email) {
|
||||
const info = this.claudePaymentStatuses[email];
|
||||
switch (this.paymentFilter) {
|
||||
case 'paid': return info && !!info.payment_time;
|
||||
case 'unpaid': return !info || !info.payment_time;
|
||||
case 'refunded': return info && !!info.refund_time;
|
||||
case 'suspended': return info && !!info.suspended_time;
|
||||
case 'unchecked': return !info;
|
||||
default: return true;
|
||||
case 'paid': return info && !!info.payment_time;
|
||||
case 'unpaid': return !info || !info.payment_time;
|
||||
case 'refunded': return info && !!info.refund_time;
|
||||
case 'refund_received': return info && info.refund_received === '1';
|
||||
case 'refund_not_received': return info && !!info.refund_time && info.refund_received !== '1';
|
||||
case 'suspended': return info && !!info.suspended_time;
|
||||
case 'unchecked': return !info;
|
||||
default: return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,7 +316,7 @@ class MailManager {
|
||||
renderAccounts() {
|
||||
const tbody = document.getElementById('accountTableBody');
|
||||
if (!this.accounts.length) {
|
||||
tbody.innerHTML = `<tr><td colspan="13"><div class="no-data"><i class="bi bi-inbox"></i><div>暂无邮箱数据</div></div></td></tr>`;
|
||||
tbody.innerHTML = `<tr><td colspan="14"><div class="no-data"><i class="bi bi-inbox"></i><div>暂无邮箱数据</div></div></td></tr>`;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -694,6 +705,25 @@ class MailManager {
|
||||
// Claude 支付检测
|
||||
// ====================================================================
|
||||
|
||||
async toggleRefundReceived(email) {
|
||||
try {
|
||||
const resp = await fetch(`/api/tools/refund-received/${encodeURIComponent(email)}`, { method: 'POST' });
|
||||
const result = await resp.json();
|
||||
if (result.success) {
|
||||
// 更新本地状态
|
||||
if (this.claudePaymentStatuses[email]) {
|
||||
this.claudePaymentStatuses[email].refund_received = result.data.refund_received;
|
||||
}
|
||||
this.renderAccounts();
|
||||
this.showToast(result.data.refund_received === '1' ? '已标记到账' : '已取消到账', 'success');
|
||||
} else {
|
||||
this.showToast(result.message || '操作失败', 'danger');
|
||||
}
|
||||
} catch (e) {
|
||||
this.showToast('网络错误', 'danger');
|
||||
}
|
||||
}
|
||||
|
||||
async loadClaudePaymentStatuses() {
|
||||
try {
|
||||
const resp = await fetch('/api/tools/claude-payment-status');
|
||||
@@ -709,6 +739,7 @@ class MailManager {
|
||||
if (!info) {
|
||||
return `<td><span class="claude-badge claude-unknown">未检测</span></td>
|
||||
<td><span class="claude-badge claude-unknown">未检测</span></td>
|
||||
<td>-</td>
|
||||
<td class="claude-time">-</td>
|
||||
<td class="claude-time">-</td>
|
||||
<td class="claude-time">-</td>
|
||||
@@ -746,8 +777,12 @@ class MailManager {
|
||||
? `<span class="claude-badge claude-suspended">${fmtTime(info.suspended_time)}</span>`
|
||||
: '-';
|
||||
|
||||
const isRefundReceived = info.refund_received === '1';
|
||||
const refundReceivedBtn = `<button class="claude-badge ${isRefundReceived ? 'claude-paid' : 'claude-unknown'} refund-received-btn" data-email="${this.escapeHtml(email)}" style="cursor:pointer;border:none;" title="点击切换">${isRefundReceived ? '已到账' : '未到账'}</button>`;
|
||||
|
||||
return `<td>${paidBadge}</td>
|
||||
<td>${refundBadge}</td>
|
||||
<td>${refundReceivedBtn}</td>
|
||||
<td class="claude-time">${fmtTime(info.payment_time)}</td>
|
||||
<td class="claude-time">${fmtTime(info.refund_time)}</td>
|
||||
<td>${suspendedHtml}</td>
|
||||
|
||||
Reference in New Issue
Block a user