feat(web): 存储设置与文件管理的 Alist 存储切换

- 设置 → 媒体库与目录 → 存储:登记 Alist / OpenList(令牌 / 账号密码 / 访客、路径密码、限速与监控选项),
  测试连接显示版本、用户与容量;媒体库目录可选存储
- 文件管理左栏多一组「Alist 存储」,路径显示「存储名:/路径」;移动 / 复制目标可选 Alist 存储;
  上传按钮;Alist 根点刷新才让 Alist 刷新目录缓存
- 运行状态的挂载根列出存储实例(令牌失效单独提示)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-10-06 23:57:33 +08:00
1 parent c1bc389058
commit cf364435eb
18 files changed
+618 -41

No files matched your search

+14 -4
View File
@@ -473,7 +473,7 @@ function Mounts({ d }: { d: SystemHealth }) {
return (
<Card title="挂载根" icon={HardDrive} level={d.mounts.length ? (bad ? "critical" : "ok") : undefined}>
{d.mounts.length === 0 ? (
<p className="text-caption text-muted-foreground">没有启用的媒体库目录或下载目录映射。</p>
<p className="text-caption text-muted-foreground">没有启用的媒体库目录、下载目录映射或 Alist 存储。</p>
) : (
<ul className="divide-y divide-border/60">
{d.mounts.map((m) => (
@@ -481,18 +481,28 @@ function Mounts({ d }: { d: SystemHealth }) {
<div className="min-w-0 flex-1">
<p className="truncate">
<span className="mr-1.5 text-meta text-muted-foreground">
{m.kind === "library_root" ? "媒体库目录" : "下载目录"}
{m.kind === "library_root"
? "媒体库目录"
: m.kind === "storage_instance"
? "Alist 存储"
: "下载目录"}
</span>
{m.name}
</p>
<p className="truncate font-mono text-meta text-muted-foreground" title={m.path}>
{m.path}
{m.sentinelChecked ? "" : " · 只查目录可读"}
{m.kind === "storage_instance" ? " · 连接与根路径" : m.sentinelChecked ? "" : " · 只查目录可读"}
</p>
</div>
<StatusBadge tone={m.status === "online" ? "success" : "destructive"}>
{m.status === "online" ? "在线" : m.status === "timeout" ? "超时" : "离线"}
{m.reason && m.status !== "timeout" ? ` · ${MOUNT_REASON[m.reason] ?? m.reason}` : ""}
{m.reason && m.status !== "timeout"
? ` · ${
m.kind === "storage_instance" && m.reason === "permission_denied"
? "令牌失效或没有权限"
: (MOUNT_REASON[m.reason] ?? m.reason)
}`
: ""}
</StatusBadge>
</li>
))}