Add automatic database backup with download and restore docs.

Back up futures.db and uploads to /root/qihuo_backup on a daily schedule, expose backup downloads in settings, and document cross-server restore.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-26 13:04:48 +08:00
parent 508d85a282
commit 98239d29c1
7 changed files with 630 additions and 4 deletions
+82
View File
@@ -54,6 +54,19 @@
.settings-ctp-fold-body{padding:0 1rem .85rem}
.settings-ctp-fold.is-collapsed .settings-ctp-fold-body{display:none}
.settings-ctp-status{font-size:.82rem;color:var(--text-muted);margin-top:.75rem;line-height:1.5}
.settings-backup-table{width:100%;border-collapse:collapse;font-size:.82rem;margin-top:.65rem}
.settings-backup-table th,.settings-backup-table td{padding:.45rem .5rem;border-bottom:1px solid var(--border);text-align:left}
.settings-backup-table th{color:var(--text-muted);font-weight:600}
.settings-backup-restore{
margin-top:.85rem;padding:.75rem .85rem;border-radius:8px;
border:1px solid var(--border);background:var(--card-inner);
font-size:.82rem;color:var(--text-muted);line-height:1.6;
}
.settings-backup-restore summary{cursor:pointer;color:var(--text-title);font-weight:600}
.settings-backup-meta{font-size:.82rem;color:var(--text-muted);line-height:1.55;margin:.35rem 0 .65rem}
.settings-backup-actions{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem .65rem}
.settings-backup-download{color:var(--accent);text-decoration:none;font-weight:600}
.settings-backup-download:hover{text-decoration:underline}
@media(max-width:900px){
.settings-password-form{grid-template-columns:1fr}
.settings-ctp-cards-row{grid-template-columns:1fr}
@@ -293,6 +306,75 @@
</div>
</div>
<div class="card">
<h2>数据备份与恢复</h2>
<p class="settings-backup-meta">
自动备份目录:<code>{{ backup_dir }}</code>
{% if backup_last_at %} · 上次备份 {{ backup_last_at.replace('T', ' ') }}{% else %} · 尚未备份{% endif %}
{% if backup_running %} · <span style="color:var(--accent)">备份进行中…</span>{% endif %}
</p>
<form action="{{ url_for('settings') }}" method="post" style="margin-bottom:.85rem">
<input type="hidden" name="action" value="backup_config">
<div class="split-grid" style="margin-bottom:.65rem">
<div class="field">
<label style="display:flex;align-items:center;gap:.45rem;cursor:pointer">
<input type="checkbox" name="backup_auto_enabled" value="1" {% if backup_auto_enabled %}checked{% endif %}>
<span>启用每日自动备份</span>
</label>
</div>
<div class="field">
<label>自动备份时刻(023 点)</label>
<input name="backup_auto_hour" type="number" min="0" max="23" step="1" value="{{ backup_auto_hour }}">
</div>
<div class="field">
<label>保留最近份数</label>
<input name="backup_keep_count" type="number" min="5" max="200" step="1" value="{{ backup_keep_count }}">
</div>
</div>
<button type="submit" class="btn-primary">保存备份策略</button>
</form>
<div class="settings-backup-actions">
<form action="{{ url_for('settings') }}" method="post">
<input type="hidden" name="action" value="backup_now">
<button type="submit" class="btn-primary" {% if backup_running %}disabled{% endif %}>立即备份</button>
</form>
</div>
<p class="hint" style="margin:.65rem 0 0">备份包含 <code>futures.db</code><code>uploads/</code>,压缩包可在其他服务器恢复。默认恢复目录 <code>{{ backup_restore_dir }}</code></p>
{% if backup_items %}
<table class="settings-backup-table">
<thead>
<tr><th>文件名</th><th>大小</th><th>时间</th><th></th></tr>
</thead>
<tbody>
{% for item in backup_items %}
<tr>
<td><code>{{ item.name }}</code></td>
<td>{{ item.size_mb }} MB</td>
<td>{{ item.mtime.replace('T', ' ') }}</td>
<td><a href="{{ url_for('api_backup_download', filename=item.name) }}" class="settings-backup-download">下载</a></td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p class="hint" style="margin-top:.65rem;margin-bottom:0">暂无备份文件,可点击「立即备份」生成第一份。</p>
{% endif %}
<details class="settings-backup-restore">
<summary>备份恢复说明</summary>
<ol style="margin:.65rem 0 0 1.1rem;padding:0">
<li>下载上方 <code>.tar.gz</code> 到目标服务器(如 <code>/root/</code>)。</li>
<li>解压:<code>tar -xzf qihuo_backup_YYYYMMDD_HHMMSS.tar.gz</code></li>
<li>进入目录执行:<code>chmod +x restore.sh &amp;&amp; ./restore.sh</code>(默认恢复到 <code>{{ backup_restore_dir }}</code>)。</li>
<li>指定目录:<code>RESTORE_DIR=/opt/qihuo ./restore.sh</code></li>
<li>在新服务器部署 qihuo 代码与虚拟环境,配置 <code>.env</code><code>pm2 restart qihuo</code></li>
<li>恢复前请停止 qihuo,避免覆盖正在使用的数据库。</li>
</ol>
<p style="margin:.65rem 0 0">完整说明见项目文档 <code>docs/BACKUP.md</code>;压缩包内亦含 <code>RESTORE.md</code></p>
</details>
</div>
<div class="split-grid">
<div class="card">
<h2>修改密码</h2>