mirror of
https://github.com/crawlab-team/crawlab.git
synced 2026-01-21 17:21:09 +01:00
added batch stop tasks
This commit is contained in:
@@ -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) // 批量取消任务
|
||||
}
|
||||
// 定时任务
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 加星吧'
|
||||
|
||||
@@ -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
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,8 +46,25 @@
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="right">
|
||||
<el-button class="btn-delete" size="small" type="danger" @click="onRemoveMultipleTask">
|
||||
删除任务
|
||||
<el-button
|
||||
v-if="selectedRunningTasks.length > 0"
|
||||
icon="el-icon-video-pause"
|
||||
class="btn-stop"
|
||||
size="small"
|
||||
type="info"
|
||||
@click="onStopMultipleTask"
|
||||
>
|
||||
{{ $t('Cancel') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="selectedTasks.length > 0"
|
||||
icon="el-icon-delete"
|
||||
class="btn-delete"
|
||||
size="small"
|
||||
type="danger"
|
||||
@click="onRemoveMultipleTask"
|
||||
>
|
||||
{{ $t('Remove') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -255,7 +272,7 @@
|
||||
// { name: 'avg_num_results', label: 'Average Results Count per Second', width: '80' }
|
||||
],
|
||||
|
||||
multipleSelection: [],
|
||||
selectedTasks: [],
|
||||
|
||||
// tutorial
|
||||
tourSteps: [
|
||||
@@ -346,6 +363,9 @@
|
||||
}
|
||||
return false
|
||||
})
|
||||
},
|
||||
selectedRunningTasks() {
|
||||
return this.selectedTasks.filter(d => ['pending', 'running'].includes(d.status))
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@@ -373,24 +393,42 @@
|
||||
this.$st.sendEv('任务列表', '搜索')
|
||||
},
|
||||
onRemoveMultipleTask() {
|
||||
if (this.multipleSelection.length === 0) {
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '请选择要删除的任务'
|
||||
})
|
||||
return
|
||||
}
|
||||
this.$confirm('确定删除任务', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
this.$confirm(this.$t('Are you sure to delete these tasks'), this.$t('Notification'), {
|
||||
confirmButtonText: this.$t('Confirm'),
|
||||
cancelButtonText: this.$t('Cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
const ids = this.multipleSelection.map(item => item._id)
|
||||
const ids = this.selectedTasks.map(item => item._id)
|
||||
this.$store.dispatch('task/deleteTaskMultiple', ids).then((resp) => {
|
||||
if (resp.data.status === 'ok') {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '删除任务成功'
|
||||
message: this.$t('Deleted successfully')
|
||||
})
|
||||
this.$store.dispatch('task/getTaskList')
|
||||
this.$refs['table'].clearSelection()
|
||||
return
|
||||
}
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: resp.data.error
|
||||
})
|
||||
})
|
||||
}).catch(() => {
|
||||
})
|
||||
},
|
||||
onStopMultipleTask() {
|
||||
this.$confirm(this.$t('Are you sure to stop these tasks'), this.$t('Notification'), {
|
||||
confirmButtonText: this.$t('Confirm'),
|
||||
cancelButtonText: this.$t('Cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
const ids = this.selectedRunningTasks.map(item => item._id)
|
||||
this.$store.dispatch('task/cancelTaskMultiple', ids).then((resp) => {
|
||||
if (resp.data.status === 'ok') {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: this.$t('Stopped successfully')
|
||||
})
|
||||
this.$store.dispatch('task/getTaskList')
|
||||
this.$refs['table'].clearSelection()
|
||||
@@ -477,7 +515,7 @@
|
||||
}
|
||||
},
|
||||
onSelectionChange(val) {
|
||||
this.multipleSelection = val
|
||||
this.selectedTasks = val
|
||||
},
|
||||
onFilterChange() {
|
||||
this.$store.dispatch('task/getTaskList')
|
||||
|
||||
Reference in New Issue
Block a user