diff --git a/backend/main.go b/backend/main.go index b6fbe795..6aa755e7 100644 --- a/backend/main.go +++ b/backend/main.go @@ -224,6 +224,7 @@ func main() { authGroup.POST("/spiders/:id/git/reset", routes.PostSpiderResetGit) // 爬虫 Git 重置 authGroup.POST("/spiders-cancel", routes.CancelSelectedSpider) // 停止所选爬虫任务 authGroup.POST("/spiders-run", routes.RunSelectedSpider) // 运行所选爬虫 + authGroup.POST("/spiders-set-projects", routes.SetProjectsSelectedSpider) // 批量设置爬虫项目 } // 可配置爬虫 { @@ -250,6 +251,7 @@ func main() { authGroup.GET("/tasks/:id/results", routes.GetTaskResults) // 任务结果 authGroup.GET("/tasks/:id/results/download", routes.DownloadTaskResultsCsv) // 下载任务结果 authGroup.POST("/tasks/:id/restart", routes.RestartTask) // 重新开始任务 + authGroup.POST("/tasks-cancel", routes.CancelSelectedTask) // 批量取消任务 } // 定时任务 { diff --git a/backend/routes/spider.go b/backend/routes/spider.go index c6ec2fbb..310d802b 100644 --- a/backend/routes/spider.go +++ b/backend/routes/spider.go @@ -869,6 +869,39 @@ func RunSelectedSpider(c *gin.Context) { }) } +func SetProjectsSelectedSpider(c *gin.Context) { + type ReqBody struct { + ProjectId bson.ObjectId `json:"project_id"` + SpiderIds []bson.ObjectId `json:"spider_ids"` + } + + var reqBody ReqBody + if err := c.ShouldBindJSON(&reqBody); err != nil { + HandleErrorF(http.StatusBadRequest, c, "invalid request") + return + } + + for _, spiderId := range reqBody.SpiderIds { + spider, err := model.GetSpider(spiderId) + if err != nil { + log.Errorf(err.Error()) + debug.PrintStack() + continue + } + spider.ProjectId = reqBody.ProjectId + if err := spider.Save(); err != nil { + log.Errorf(err.Error()) + debug.PrintStack() + continue + } + } + + c.JSON(http.StatusOK, Response{ + Status: "ok", + Message: "success", + }) +} + // @Summary Get task list // @Description Get task list // @Tags spider diff --git a/backend/routes/task.go b/backend/routes/task.go index 081b156e..ac30935f 100644 --- a/backend/routes/task.go +++ b/backend/routes/task.go @@ -321,7 +321,7 @@ func DeleteTaskByStatus(c *gin.Context) { func DeleteSelectedTask(c *gin.Context) { ids := make(map[string][]string) if err := c.ShouldBindJSON(&ids); err != nil { - HandleError(http.StatusInternalServerError, c, err) + HandleError(http.StatusBadRequest, c, err) return } list := ids["ids"] @@ -364,6 +364,22 @@ func DeleteTask(c *gin.Context) { HandleSuccess(c) } +func CancelSelectedTask(c *gin.Context) { + ids := make(map[string][]string) + if err := c.ShouldBindJSON(&ids); err != nil { + HandleError(http.StatusBadRequest, c, err) + return + } + list := ids["ids"] + for _, id := range list { + if err := services.CancelTask(id); err != nil { + HandleError(http.StatusInternalServerError, c, err) + return + } + } + HandleSuccess(c) +} + // @Summary Get task log // @Description Get task log // @Tags task diff --git a/frontend/src/i18n/zh.js b/frontend/src/i18n/zh.js index 91ba5a3b..70e123b8 100644 --- a/frontend/src/i18n/zh.js +++ b/frontend/src/i18n/zh.js @@ -275,6 +275,8 @@ export default { 'Restart': '重新运行', 'Redirect to task detail': '跳转到任务详情页', 'Retry (Maximum 5 Times)': '是否重试(最多 5 次)', + 'Delete Tasks': '删除任务', + 'Stop Tasks': '停止任务', // 任务列表 'Node': '节点', @@ -663,6 +665,9 @@ export default { 'Are you sure to download this spider?': '您确定要下载该爬虫?', 'Downloaded successfully': '下载成功', 'Unable to submit because of some errors': '有错误,无法提交', + 'Are you sure to stop these tasks': '确认停止这些任务?', + 'Are you sure to delete these tasks': '确认删除这些任务?', + 'Stopped successfully': '成功停止', // 其他 'Star crawlab-team/crawlab on GitHub': '在 GitHub 上为 Crawlab 加星吧' diff --git a/frontend/src/store/modules/task.js b/frontend/src/store/modules/task.js index 61653045..e4a4ecd8 100644 --- a/frontend/src/store/modules/task.js +++ b/frontend/src/store/modules/task.js @@ -250,13 +250,14 @@ const actions = { link.click() link.remove() }, - cancelTask({ state, dispatch }, id) { - return new Promise(resolve => { - request.post(`/tasks/${id}/cancel`) - .then(res => { - dispatch('getTaskData', id) - resolve(res) - }) + async cancelTask({ state, dispatch }, id) { + const res = await request.post(`/tasks/${id}/cancel`) + dispatch('getTaskData', id) + return res + }, + async cancelTaskMultiple({ dispatch }, ids) { + return await request.post(`/tasks-cancel`, { + ids }) } } diff --git a/frontend/src/views/task/TaskList.vue b/frontend/src/views/task/TaskList.vue index 65804344..4c7639a8 100644 --- a/frontend/src/views/task/TaskList.vue +++ b/frontend/src/views/task/TaskList.vue @@ -46,8 +46,25 @@