Add payment status filter dropdown (paid/unpaid/refunded/suspended)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-06 01:20:37 +08:00
parent 3c1715603d
commit 197c969e41
3 changed files with 72 additions and 9 deletions

View File

@@ -50,6 +50,7 @@ class MailManager {
this.messages = [];
this.selectedId = null;
this.claudePaymentStatuses = {};
this.paymentFilter = '';
this.init();
}
@@ -104,6 +105,13 @@ class MailManager {
// Claude支付检测
document.getElementById('claudePaymentBtn').addEventListener('click', () => this.startClaudePaymentCheck());
// 支付状态筛选
document.getElementById('paymentFilter').addEventListener('change', (e) => {
this.paymentFilter = e.target.value;
this.page = 1;
this.loadAccounts();
});
// 刷新
document.getElementById('refreshAccountsBtn').addEventListener('click', () => this.loadAccounts());
@@ -242,22 +250,22 @@ class MailManager {
tbody.innerHTML = `<tr><td colspan="13"><div class="table-loading"><div class="spinner-border spinner-border-sm"></div> 加载中...</div></td></tr>`;
try {
const params = new URLSearchParams({
page: this.page,
page_size: this.pageSize
});
// 有筛选时加载全部数据,否则分页加载
const params = new URLSearchParams(
this.paymentFilter
? { page: 1, page_size: 9999 }
: { page: this.page, page_size: this.pageSize }
);
if (this.query) params.set('q', this.query);
const resp = await fetch(`/api/accounts/detailed?${params}`);
const result = await resp.json();
if (result.success && result.data) {
this.accounts = result.data.items || [];
this.total = result.data.total || 0;
this.page = result.data.page || 1;
this._allAccounts = result.data.items || [];
this._allTotal = result.data.total || 0;
await this.loadClaudePaymentStatuses();
this.renderAccounts();
this.renderPager();
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>`;
}
@@ -267,6 +275,32 @@ class MailManager {
}
}
_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;
}
}
applyFilterAndRender() {
if (this.paymentFilter) {
const filtered = this._allAccounts.filter(acc => this._matchPaymentFilter(acc.email));
this.total = filtered.length;
const start = (this.page - 1) * this.pageSize;
this.accounts = filtered.slice(start, start + this.pageSize);
} else {
this.accounts = this._allAccounts;
this.total = this._allTotal;
}
this.renderAccounts();
this.renderPager();
}
renderAccounts() {
const tbody = document.getElementById('accountTableBody');
if (!this.accounts.length) {