Initial commit: rdgen with GitHub/Gitea dual build backend

This commit is contained in:
naeeo
2026-09-29 19:56:02 +08:00
commit a3686a49d4
103 changed files with 20007 additions and 0 deletions
@@ -0,0 +1,147 @@
{% extends "base.html" %}
{% block title %}维护设置 · RustDesk 客户端定制平台{% endblock %}
{% block content %}
<nav class="breadcrumb">
<a href="{% url 'dashboard' %}">后台管理</a>
<span class="breadcrumb-sep">/</span>
<span>维护设置</span>
</nav>
<div class="page-head">
<h1 class="page-title">
<svg class="icon"><use href="#i-clock"/></svg>
维护设置
</h1>
<p class="page-subtitle">
定时清理过期构建任务与安装包产物,并自动备份数据库。维护进程随容器启动常驻运行,每小时检查一次。
</p>
</div>
<div class="stat-grid">
<div class="stat-card"><div class="stat-value">{{ status.total_builds }}</div><div class="stat-label">构建任务总数</div></div>
<div class="stat-card is-info"><div class="stat-value">{{ status.in_progress_builds }}</div><div class="stat-label">进行中(不清理)</div></div>
<div class="stat-card is-danger"><div class="stat-value">{{ status.expired_builds }}</div><div class="stat-label">已到期待清理</div></div>
<div class="stat-card"><div class="stat-value">{{ status.db_size|filesizeformat }}</div><div class="stat-label">数据库大小</div></div>
<div class="stat-card"><div class="stat-value">{{ status.artifacts_size|filesizeformat }}</div><div class="stat-label">安装包 / 图片占用</div></div>
<div class="stat-card{% if status.backup_enabled %} is-success{% endif %}"><div class="stat-value">{{ status.backups|length }}</div><div class="stat-label">现存备份份数</div></div>
</div>
<div class="grid-2" style="align-items:start">
{# ===== 维护策略表单 ===== #}
<div class="card">
<div class="card-header"><svg class="icon"><use href="#i-sliders"/></svg> 自动维护策略</div>
<div class="card-body">
<form method="post" action="{% url 'maintenance_settings' %}">
{% csrf_token %}
<div class="field">
<label class="setting-label" for="{{ form.build_retention_days.id_for_label }}">{{ form.build_retention_days.label }}</label>
{{ form.build_retention_days }}
<div class="field-hint">{{ form.build_retention_days.help_text }}</div>
</div>
<div class="field">
<label class="clear-check" for="{{ form.db_backup_enabled.id_for_label }}">
{{ form.db_backup_enabled }} {{ form.db_backup_enabled.label }}
</label>
<div class="field-hint">{{ form.db_backup_enabled.help_text }}</div>
</div>
<div class="field">
<label class="setting-label" for="{{ form.db_backup_keep.id_for_label }}">{{ form.db_backup_keep.label }}</label>
{{ form.db_backup_keep }}
<div class="field-hint">{{ form.db_backup_keep.help_text }}</div>
</div>
<div class="settings-actions">
<div class="btn-row">
<button type="submit" class="btn btn-primary">
<svg class="icon"><use href="#i-save"/></svg> 保存设置
</button>
</div>
</div>
</form>
</div>
</div>
{# ===== 立即执行 ===== #}
<div class="card">
<div class="card-header"><svg class="icon"><use href="#i-play"/></svg> 手动维护</div>
<div class="card-body">
<p class="card-desc">
立即执行一轮维护:清理超过保留期的已结束任务、7 天前的临时配置包,并<strong>立即创建一份新的数据库备份</strong>
(不受每日一次的自动节奏限制)。
</p>
<ul class="config-check-list">
<li class="is-ok"><svg class="icon"><use href="#i-check-circle"/></svg>
当前保留策略:{% if status.retention_days > 0 %}{{ status.retention_days }} 天,预计可清理 {{ status.expired_builds }} 条已结束任务{% else %}永不自动清理{% endif %}
</li>
<li class="{% if status.backup_enabled %}is-ok{% else %}is-warn{% endif %}">
<svg class="icon"><use href="{% if status.backup_enabled %}#i-check-circle{% else %}#i-alert{% endif %}"/></svg>
定时备份:{% if status.backup_enabled %}已开启(每 {{ status.backup_interval_hours }} 小时一次,保留 {{ status.backup_keep }} 份){% else %}已关闭{% endif %}
</li>
<li class="is-ok"><svg class="icon"><use href="#i-database"/></svg>
数据库:<span class="mono text-muted">{{ status.db_path }}</span>({{ status.db_size|filesizeformat }})
</li>
</ul>
<form method="post" action="{% url 'maintenance_run_now' %}"
onsubmit="return confirm('立即执行清理并备份数据库?已到期的任务记录与安装包将被删除。');">
{% csrf_token %}
<button type="submit" class="btn btn-secondary">
<svg class="icon"><use href="#i-zap"/></svg> 立即执行清理与备份
</button>
</form>
</div>
</div>
</div>
{# ===== 备份列表 ===== #}
<div class="card">
<div class="card-header"><svg class="icon"><use href="#i-database"/></svg> 数据库备份</div>
{% if status.backups %}
<div class="table-wrap">
<table class="table">
<thead>
<tr>
<th>备份文件</th>
<th>大小</th>
<th>备份时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for backup in status.backups %}
<tr>
<td class="mono">{{ backup.name }}</td>
<td class="text-muted">{{ backup.size|filesizeformat }}</td>
<td class="text-muted" style="white-space:nowrap">{{ backup.mtime|date:"Y-m-d H:i" }}</td>
<td>
<a class="btn btn-secondary btn-sm" href="{% url 'download_backup' backup.name %}">
<svg class="icon"><use href="#i-download"/></svg> 下载
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="empty-state">
<div class="empty-icon"><svg class="icon" style="width:42px;height:42px"><use href="#i-database"/></svg></div>
<h3>暂无数据库备份</h3>
<p>开启定时备份后会自动生成;也可以点击上方「立即执行清理与备份」马上创建一份。</p>
</div>
{% endif %}
</div>
<div class="card">
<div class="card-header"><svg class="icon"><use href="#i-server"/></svg> 说明</div>
<div class="card-body">
<p class="card-desc">
备份文件是完整的 SQLite 数据库(包含账号、配置方案、构建记录与站点设置),存放在持久化数据卷
<code>data/backups/</code> 中,重建镜像与重新部署均不丢失。<strong>恢复方式</strong>:停止容器,
用备份文件替换数据卷内的 <code>db.sqlite3</code> 后重新启动即可。
也可通过 docker-compose 环境变量 <code>BUILD_RETENTION_DAYS</code>、
<code>DB_BACKUP_ENABLED</code>、<code>DB_BACKUP_KEEP</code> 配置(本页保存的优先级更高)。
</p>
</div>
</div>
{% endblock %}