From 86caa5765d0cf1a06051ab9ffbe3cac93e1372da Mon Sep 17 00:00:00 2001 From: yw1573 Date: Thu, 9 Apr 2026 11:46:32 +0800 Subject: [PATCH] feat: create season subdirectory when downloading season MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 下载合集时创建以合集标题命名的子目录: - 前端 TaskInitData 增加 seasonTitle 字段 - 前端下载时传递合集 seasonTitle - 后端 TaskInitOption 增加 SeasonTitle 字段 - 后端创建任务时根据 seasonTitle 创建子目录 Co-Authored-By: AI --- internal/task/task.go | 11 +++++++++++ web/src/work/type.ts | 2 ++ web/src/work/view/parseModal.ts | 3 +++ 3 files changed, 16 insertions(+) diff --git a/internal/task/task.go b/internal/task/task.go index a2a482b..4c60180 100644 --- a/internal/task/task.go +++ b/internal/task/task.go @@ -37,6 +37,7 @@ type TaskInitOption struct { Video string `json:"video"` Duration int `json:"duration"` DownloadType string `json:"downloadType"` + SeasonTitle string `json:"seasonTitle"` // 合集标题,用于创建子目录 } // TaskInDB 任务数据库中的数据 @@ -164,6 +165,16 @@ func (task *Task) Start() { return } + // 如果有合集标题,创建子目录 + if task.SeasonTitle != "" { + seasonFolder := filepath.Join(task.Folder, task.SeasonTitle) + if err := os.MkdirAll(seasonFolder, os.ModePerm); err != nil { + task.UpdateStatus(db, "error", fmt.Errorf("创建合集目录失败: %v", err)) + return + } + task.Folder = seasonFolder + } + client := &bilibili.BiliClient{SESSDATA: sessdata} GlobalDownloadSem.Acquire() diff --git a/web/src/work/type.ts b/web/src/work/type.ts index 2ee88d0..0e321fe 100644 --- a/web/src/work/type.ts +++ b/web/src/work/type.ts @@ -245,6 +245,8 @@ export type TaskInitData = { video: string duration: number downloadType: 'audio' | 'video' | 'merge' + /** 合集标题,用于创建子目录 */ + seasonTitle?: string } /** 任务数据库中的数据 */ diff --git a/web/src/work/view/parseModal.ts b/web/src/work/view/parseModal.ts index 723f852..804448a 100644 --- a/web/src/work/view/parseModal.ts +++ b/web/src/work/view/parseModal.ts @@ -143,6 +143,8 @@ export class ParseModalComp implements VanComponent { : workRoute.videoInfoCardData.val.owner.name.trim() const activeVideoInfo = getActiveFormatVideo(info.info!, info.info!.accept_quality[info.formatIndex.val], this.preferredCodec.val) const pagesLength = workRoute.videoInfoCardData.val.pages.length + // 合集标题,用于创建子目录 + const seasonTitle = workRoute.videoInfoCardMode.val == 'season' ? cardTitle.trim() : undefined return ({ bvid: info.page.bvid, @@ -169,6 +171,7 @@ export class ParseModalComp implements VanComponent { audio: getAudioURL(info.info!, this.preferHiResAudio.val), duration: info.info!.dash.duration, downloadType: this.downloadType.val, + seasonTitle, ...activeVideoInfo }) })).then(() => {