Files
duplicati_preview/public/index.html
T

232 lines
11 KiB
HTML

<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>数据源控制台</title>
<link rel="stylesheet" href="/styles.css">
</head>
<body>
<main class="shell">
<section class="hero hero-compact">
<div>
<p class="eyebrow">Zero-Bandwidth Duplicati Web Client</p>
<h1>数据源控制台</h1>
</div>
<p class="lead">
这里负责管理任务数据库、Server DB 元数据、全局 WebDAV 默认值,以及站点级 HTTPS/TLS 配置。
目录浏览、增强、预览和下载继续放在单个数据源工作台与文件页里。
</p>
</section>
<div class="auth-toolbar">
<span id="authStatus" class="auth-status">正在读取登录状态...</span>
<button id="logoutButton" class="ghost-button" type="button">退出登录</button>
</div>
<div id="feedback" class="feedback" hidden></div>
<section class="workspace-shell">
<aside class="workspace-nav" aria-label="数据源控制台菜单">
<a class="workspace-nav-link" href="#overview" data-view-link="overview">总览</a>
<a class="workspace-nav-link" href="#sources" data-view-link="sources">数据源列表</a>
<a class="workspace-nav-link" href="#upload" data-view-link="upload">新增任务库</a>
<a class="workspace-nav-link" href="#server-db" data-view-link="server-db">Server DB</a>
<a class="workspace-nav-link" href="#defaults" data-view-link="defaults">全局 WebDAV</a>
<a class="workspace-nav-link" href="#tls" data-view-link="tls">HTTPS / TLS</a>
</aside>
<div class="workspace-content">
<section class="workspace-panel" data-view-panel="overview">
<div class="panel stack-gap">
<div class="panel-header">
<div>
<p class="section-label">Overview</p>
<h2>系统总览</h2>
</div>
</div>
<div id="overviewSummary" class="summary-card">正在读取系统总览...</div>
</div>
</section>
<section class="workspace-panel" data-view-panel="sources" hidden>
<div class="panel panel-spacious">
<div class="panel-header">
<div>
<p class="section-label">Sources</p>
<h2>已上传任务数据库</h2>
</div>
<button id="refreshButton" class="ghost-button" type="button">刷新</button>
</div>
<p class="panel-copy">
每个上传的 Duplicati 任务数据库都会变成一个独立 source。进入工作台后,可以继续浏览目录、执行增强,或跳转到文件页做预览和下载。
</p>
<div id="sourceList" class="source-list empty-state">正在读取数据源列表...</div>
</div>
</section>
<section class="workspace-panel" data-view-panel="upload" hidden>
<div class="panel">
<div class="panel-header">
<div>
<p class="section-label">Task DB</p>
<h2>上传新的任务库</h2>
</div>
</div>
<p class="panel-copy">
上传随机名任务数据库,例如 <code>TMQRJYNADS.sqlite</code>。重复上传同一个数据库时,系统会复用现有 source,而不是重复创建。
</p>
<form id="uploadForm" class="upload-form">
<label class="file-picker">
<span>选择任务 SQLite 文件</span>
<input id="databaseInput" name="database" type="file" accept=".sqlite,.db,application/octet-stream">
</label>
<div class="form-actions">
<button id="uploadButton" class="primary-button" type="submit">上传为新数据源</button>
</div>
</form>
</div>
</section>
<section class="workspace-panel" data-view-panel="server-db" hidden>
<div class="panel stack-gap">
<div class="panel-header">
<div>
<p class="section-label">Server DB</p>
<h2>上传 Duplicati-server.sqlite</h2>
</div>
</div>
<p class="panel-copy">
上传后,界面可以自动解析任务名称,并尽量从 Duplicati 元数据中推导默认目标 URL。
</p>
<form id="serverDbForm" class="upload-form">
<label class="file-picker">
<span>选择服务器数据库</span>
<input id="serverDbInput" name="database" type="file" accept=".sqlite,.db,application/octet-stream">
</label>
<div class="form-actions">
<button id="serverDbUploadButton" class="ghost-button" type="submit">上传 Server DB</button>
</div>
</form>
<div id="serverDbSummary" class="summary-card">正在读取 Server DB 状态...</div>
</div>
</section>
<section class="workspace-panel" data-view-panel="defaults" hidden>
<div class="panel stack-gap">
<div class="panel-header">
<div>
<p class="section-label">Global WebDAV</p>
<h2>共享默认值</h2>
</div>
</div>
<p class="panel-copy">
如果大多数任务共用同一套 WebDAV 认证和口令,可以在这里统一保存一次。
</p>
<form id="globalDefaultsForm" class="secret-form">
<label>
<span>兜底 WebDAV Base URL</span>
<input id="globalWebdavBaseUrl" name="webdavBaseUrl" type="url" placeholder="可选,共享兜底 URL">
</label>
<label>
<span>认证方式</span>
<select id="globalAuthMode" name="authMode">
<option value="">自动 / 继承</option>
<option value="basic">Basic</option>
<option value="anonymous">匿名</option>
</select>
</label>
<label>
<span>用户名</span>
<input id="globalUsername" name="username" type="text" placeholder="可选,共享用户名">
</label>
<label>
<span>密码</span>
<input id="globalPassword" name="password" type="password" placeholder="可选,共享密码">
</label>
<label>
<span>备份口令</span>
<input id="globalPassphrase" name="passphrase" type="password" placeholder="可选,共享备份口令">
</label>
<div class="form-actions">
<button id="globalDefaultsSaveButton" class="ghost-button" type="submit">保存默认值</button>
</div>
</form>
<div id="globalDefaultsSummary" class="summary-card">正在读取 WebDAV 默认值...</div>
</div>
</section>
<section class="workspace-panel" data-view-panel="tls" hidden>
<div class="panel stack-gap">
<div class="panel-header">
<div>
<p class="section-label">HTTPS / TLS</p>
<h2>域名与证书设置</h2>
</div>
</div>
<p class="panel-copy">
HTTP 和 HTTPS 会同时可用。没有自定义证书时,系统会自动维护一张自签证书,保证 HTTPS 始终可访问。
</p>
<div id="tlsSummary" class="summary-card">正在读取 TLS 配置...</div>
<form id="tlsJsonForm" class="secret-form">
<label>
<span>证书模式</span>
<select id="tlsMode" name="mode">
<option value="self-signed">自签证书</option>
<option value="custom-pem">自定义 PEM</option>
</select>
</label>
<label>
<span>主域名</span>
<input id="tlsPrimaryDomain" name="primaryDomain" type="text" placeholder="例如:preview.example.com">
</label>
<label>
<span>额外 SAN 条目</span>
<textarea id="tlsSubjectAltNames" name="subjectAltNames" rows="3" placeholder="每行一个域名或 IP,也支持逗号分隔"></textarea>
</label>
<label>
<span>证书 PEM</span>
<textarea id="tlsCertPem" name="certPem" rows="8" placeholder="-----BEGIN CERTIFICATE-----"></textarea>
</label>
<label>
<span>私钥 PEM</span>
<textarea id="tlsKeyPem" name="keyPem" rows="8" placeholder="-----BEGIN PRIVATE KEY-----"></textarea>
</label>
<label>
<span>可选链证书 PEM</span>
<textarea id="tlsChainPem" name="chainPem" rows="6" placeholder="可选,中间证书链"></textarea>
</label>
<div class="form-actions">
<button id="tlsSaveButton" class="primary-button" type="submit">保存并应用</button>
<button id="tlsDeleteCustomButton" class="ghost-button danger-button" type="button">删除自定义证书并回退</button>
</div>
</form>
<form id="tlsUploadForm" class="upload-form">
<label class="file-picker">
<span>上传证书文件</span>
<input id="tlsCertificateInput" name="certificate" type="file" accept=".pem,.crt,.cer,text/plain">
</label>
<label class="file-picker">
<span>上传私钥文件</span>
<input id="tlsPrivateKeyInput" name="privateKey" type="file" accept=".pem,.key,text/plain">
</label>
<label class="file-picker">
<span>上传可选链证书文件</span>
<input id="tlsChainInput" name="chain" type="file" accept=".pem,.crt,.cer,text/plain">
</label>
<div class="form-actions">
<button id="tlsUploadButton" class="ghost-button" type="submit">应用上传的证书</button>
</div>
</form>
</div>
</section>
</div>
</section>
</main>
<script type="module" src="/app.js"></script>
</body>
</html>