added batch stop tasks

This commit is contained in:
marvzhang
2020-07-18 11:26:09 +08:00
parent d973aa39a7
commit 00ef72f6e8
6 changed files with 119 additions and 24 deletions

View File

@@ -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) // 批量取消任务
}
// 定时任务
{

View File

@@ -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

View File

@@ -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

View File

@@ -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 加星吧'

View File

@@ -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
})
}
}

View File

@@ -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')