package router import ( "database/sql" "encoding/json" "fmt" "net/http" "os" "os/exec" "runtime" "strconv" "bilidown/internal/task" "bilidown/internal/util" ) func createTask(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() if r.Method != http.MethodPost { util.Res{Success: false, Message: "不支持的请求方法"}.Write(w) return } var body []task.TaskInDB err := json.NewDecoder(r.Body).Decode(&body) if err != nil { util.Res{Success: false, Message: "参数错误"}.Write(w) return } db := util.MustGetDB() defer db.Close() // 预先获取下载目录,避免循环中重复查询 folder, err := util.GetCurrentFolder(db) if err != nil { util.Res{Success: false, Message: fmt.Sprintf("获取下载目录失败: %v", err)}.Write(w) return } for _, item := range body { if !util.CheckBvidFormat(item.Bvid) { util.Res{Success: false, Message: "bvid 格式错误"}.Write(w) return } if item.Cover == "" || item.Title == "" || item.Owner == "" { util.Res{Success: false, Message: "参数错误"}.Write(w) return } if !util.IsValidURL(item.Cover) { util.Res{Success: false, Message: "封面链接格式错误"}.Write(w) return } if !util.IsValidURL(item.Audio) { util.Res{Success: false, Message: "音频链接格式错误"}.Write(w) return } if !util.IsValidURL(item.Video) { util.Res{Success: false, Message: "视频链接格式错误"}.Write(w) return } if !util.IsValidFormatCode(item.Format) { util.Res{Success: false, Message: "清晰度代码错误"}.Write(w) return } item.Folder = folder item.Status = "waiting" _task := task.Task{TaskInDB: item} _task.Title = util.FilterFileName(_task.Title) err = _task.Create(db) if err != nil { util.Res{Success: false, Message: fmt.Sprintf("_task.Create: %v.", err)}.Write(w) return } go _task.Start() } util.Res{Success: true, Message: "创建成功"}.Write(w) } func getActiveTask(w http.ResponseWriter, r *http.Request) { util.Res{Success: true, Data: task.GlobalTaskList}.Write(w) } func getTaskList(w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err != nil { util.Res{Success: false, Message: "参数错误"}.Write(w) return } db := util.MustGetDB() defer db.Close() page, err := strconv.Atoi(r.FormValue("page")) if err != nil { page = 0 } pageSize, err := strconv.Atoi(r.FormValue("pageSize")) if err != nil { pageSize = 360 } tasks, err := task.GetTaskList(db, page, pageSize) if err != nil { util.Res{Success: false, Message: err.Error()}.Write(w) return } util.Res{Success: true, Message: "获取成功", Data: tasks}.Write(w) } // showFile 调用 Explorer 查看文件位置 func showFile(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { util.Res{Success: false, Message: "参数错误"}.Write(w) return } filePath := r.FormValue("filePath") var cmd *exec.Cmd // 根据操作系统选择命令 switch runtime.GOOS { case "windows": // Windows 使用 explorer cmd = exec.Command("explorer", "/select,", filePath) case "darwin": // macOS 使用 open cmd = exec.Command("open", "-R", filePath) case "linux": // Linux 使用 xdg-open cmd = exec.Command("xdg-open", filePath) default: util.Res{Success: false, Message: "不支持的操作系统"}.Write(w) return } err := cmd.Start() if err != nil { util.Res{Success: false, Message: err.Error()}.Write(w) return } util.Res{Success: true, Message: "操作成功"}.Write(w) } func deleteTask(w http.ResponseWriter, r *http.Request) { taskIDStr := r.FormValue("id") taskID, err := strconv.Atoi(taskIDStr) if err != nil { util.Res{Success: false, Message: "参数错误"}.Write(w) return } db := util.MustGetDB() defer db.Close() _task, err := task.GetTask(db, taskID) if err == sql.ErrNoRows { util.Res{Success: true, Message: "数据库中没有该条记录,所以本次操作被忽略,可以算作成功。"}.Write(w) return } if err != nil { util.Res{Success: false, Message: fmt.Sprintf("task.GetTask: %v", err)}.Write(w) return } filePath := _task.FilePath() err = os.Remove(filePath) if err != nil && !os.IsNotExist(err) { util.Res{Success: false, Message: fmt.Sprintf("文件删除失败 os.Remove: %v", err)}.Write(w) return } err = task.DeleteTask(db, taskID) if err != nil { util.Res{Success: false, Message: fmt.Sprintf("task.DeleteTask: %v", err)}.Write(w) return } util.Res{Success: true, Message: "删除成功"}.Write(w) }