feat(downloads): 多下载器路由:默认下载器、站点指定下载器、别名

照 MP(chain/download/submission.py:明确指定 or 站点下载器 or 默认):
- 迁移 0063:downloader_instance.is_default(至多一个,唯一索引)、site.downloader_instance_id
- pickInstance:明确指定 > 站点指定 > 默认 > 第一个可用;自动下载(gates)与手动下载共用
- 设置:下载器名称改称别名,新增「设为默认下载器」;站点编辑新增「下载器」选择
- 测试 downloader-routing.test.ts

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-10-02 20:32:29 +08:00
1 parent 64e1dfb1d2
commit 135c50048f
12 files changed
+196 -11

No files matched your search

+12 -1
View File
@@ -68,6 +68,8 @@ export const DownloaderInstance = EntityBase.extend({
/** 共享缓存卷标识:多 qB 共用同一卷时按此汇总水位 */
cacheVolumeKey: z.string().nullable(),
enabled: z.boolean(),
/** 默认下载器(至多一个):订阅 / 手动没指定、站点也没指定时用它 */
isDefault: z.boolean(),
healthStatus: InstanceHealth,
lastSeenAt: Timestamp.nullable(),
versionInfo: JsonObject,
@@ -82,9 +84,18 @@ export const DownloaderInstanceCreate = DownloaderInstance.pick({
managedTag: true,
cacheVolumeKey: true,
enabled: true,
isDefault: true,
settings: true,
})
.partial({ kind: true, username: true, managedTag: true, cacheVolumeKey: true, enabled: true, settings: true })
.partial({
kind: true,
username: true,
managedTag: true,
cacheVolumeKey: true,
enabled: true,
isDefault: true,
settings: true,
})
.extend({
credential: Credential.optional(),
/** 认证方式,写入 settings.authKind;缺省按"有用户名 → 账密,否则有凭证 → API Key,否则无认证"推断 */
+4
View File
@@ -185,6 +185,8 @@ export const Site = EntityBase.extend({
proxy: z.boolean(),
/** 默认参与资源搜索(站点选择弹层的"默认"集合) */
searchDefault: z.boolean(),
/** 该站资源用的下载器;null = 默认下载器(订阅 / 手动明确指定时以指定为准) */
downloaderInstanceId: Id.nullable(),
});
export type Site = z.infer<typeof Site>;
export const SiteCreate = Site.pick({
@@ -200,6 +202,7 @@ export const SiteCreate = Site.pick({
snapshotIntervalSec: true,
proxy: true,
searchDefault: true,
downloaderInstanceId: true,
})
.partial({
key: true,
@@ -211,6 +214,7 @@ export const SiteCreate = Site.pick({
snapshotIntervalSec: true,
proxy: true,
searchDefault: true,
downloaderInstanceId: true,
})
.extend({
/**