Add Redis caching, email refresh button, optimize page loading

- Add Redis service (docker-compose) for caching accounts, messages, payment status
- Cache accounts list (5min), messages (3min), payment status (10min)
- Auto-invalidate cache on import/delete/payment-check/note-update
- Add refresh button to email list panel (force re-fetch from IMAP)
- Messages API supports refresh=true param to bypass cache
- New cache.py module with RedisCache class

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

View File

@@ -211,6 +211,7 @@ class MailManager {
document.getElementById('backToAccounts').addEventListener('click', () => this.showAccountView());
document.getElementById('mobileMailToggle').addEventListener('click', () => this.toggleMobileMailList());
document.getElementById('mobileOverlay').addEventListener('click', () => this.closeMobileMailList());
document.getElementById('refreshEmailsBtn').addEventListener('click', () => this.refreshEmails());
}
// ====================================================================
@@ -495,7 +496,19 @@ class MailManager {
// 邮件查看 — 数据
// ====================================================================
async loadEmails() {
async refreshEmails() {
const btn = document.getElementById('refreshEmailsBtn');
btn.classList.add('spinning');
btn.disabled = true;
try {
await this.loadEmails(true);
} finally {
btn.classList.remove('spinning');
btn.disabled = false;
}
}
async loadEmails(refresh = false) {
const container = document.getElementById('emailListContent');
container.innerHTML = '<div class="loading-state"><div class="spinner-border spinner-border-sm"></div><p>加载邮件中...</p></div>';
@@ -505,6 +518,7 @@ class MailManager {
folder: this.currentFolder,
top: 20
});
if (refresh) params.set('refresh', 'true');
const resp = await fetch(`/api/messages?${params}`);
const result = await resp.json();