mirror of
https://github.com/crawlab-team/crawlab.git
synced 2026-02-01 18:20:17 +01:00
added batch add schedules
This commit is contained in:
315
frontend/src/components/Common/BatchAddScheduleDialog.vue
Normal file
315
frontend/src/components/Common/BatchAddScheduleDialog.vue
Normal file
@@ -0,0 +1,315 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:visible="visible"
|
||||
width="1200px"
|
||||
:before-close="beforeClose"
|
||||
>
|
||||
<el-table
|
||||
:data="batchScheduleList"
|
||||
>
|
||||
<el-table-column
|
||||
:label="$t('Schedule Name')"
|
||||
width="150px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.name" size="mini" :placeholder="$t('Schedule Name')" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('Cron')"
|
||||
width="150px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.cron" size="mini" :placeholder="$t('Cron')" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('Spider')"
|
||||
width="150px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-select
|
||||
v-model="scope.row.spider_id"
|
||||
size="mini"
|
||||
filterable
|
||||
:placeholder="$t('Spider')"
|
||||
@change="onSpiderChange(scope.row, $event)"
|
||||
>
|
||||
<!-- <el-option :label="$t('Same Above')" value="same-above" :placeholder="$t('Spider')"/>-->
|
||||
<el-option
|
||||
v-for="op in allSpiderList"
|
||||
:key="op._id"
|
||||
:label="`${op.display_name} (${op.name})`"
|
||||
:value="op._id"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('Run Type')"
|
||||
width="150px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-select v-model="scope.row.run_type" size="mini">
|
||||
<el-option value="all-nodes" :label="$t('All Nodes')" />
|
||||
<el-option value="selected-nodes" :label="$t('Selected Nodes')" />
|
||||
<el-option value="random" :label="$t('Random')" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('Nodes')"
|
||||
width="250px"
|
||||
>
|
||||
<template v-if="scope.row.run_type === 'selected-nodes'" slot-scope="scope">
|
||||
<el-select
|
||||
v-model="scope.row.node_ids"
|
||||
size="mini"
|
||||
multiple
|
||||
:placeholder="$t('Nodes')"
|
||||
>
|
||||
<el-option
|
||||
v-for="n in activeNodeList"
|
||||
:key="n._id"
|
||||
:label="n.name"
|
||||
:value="n._id"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('Scrapy Spider')"
|
||||
width="150px"
|
||||
>
|
||||
<template v-if="getSpiderById(scope.row.spider_id).is_scrapy" slot-scope="scope">
|
||||
<el-select
|
||||
v-model="scope.row.scrapy_spider_name"
|
||||
size="mini"
|
||||
:placeholder="$t('Scrapy Spider')"
|
||||
:disabled="!scope.row.scrapy_spider_name"
|
||||
>
|
||||
<el-option
|
||||
v-for="(n, index) in getScrapySpiderNames(scope.row.spider_id)"
|
||||
:key="index"
|
||||
:label="n"
|
||||
:value="n"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('Scrapy Log Level')"
|
||||
width="120px"
|
||||
>
|
||||
<template v-if="getSpiderById(scope.row.spider_id).is_scrapy" slot-scope="scope">
|
||||
<el-select
|
||||
v-model="scope.row.scrapy_log_level"
|
||||
:placeholder="$t('Scrapy Log Level')"
|
||||
size="mini"
|
||||
>
|
||||
<el-option value="INFO" label="INFO" />
|
||||
<el-option value="DEBUG" label="DEBUG" />
|
||||
<el-option value="WARN" label="WARN" />
|
||||
<el-option value="ERROR" label="ERROR" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('Parameters')"
|
||||
min-width="150px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.param" size="mini" :placeholder="$t('Parameters')" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('Description')"
|
||||
width="200px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.description" size="mini" type="textarea" :placeholder="$t('Description')" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('Action')"
|
||||
fixed="right"
|
||||
width="150px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-button icon="el-icon-plus" size="mini" type="primary" @click="onAdd(scope.$index)" />
|
||||
<el-button icon="el-icon-delete" size="mini" type="danger" @click="onRemove(scope.$index)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<template slot="footer">
|
||||
<el-button type="plain" size="small" @click="$emit('close')">{{ $t('Cancel') }}</el-button>
|
||||
<el-button type="plain" size="small" @click="reset">
|
||||
{{ $t('Reset') }}
|
||||
</el-button>
|
||||
<el-button type="primary" size="small" :disabled="isConfirmDisabled" @click="onConfirm">
|
||||
{{ $t('Confirm') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'BatchAddScheduleDialog',
|
||||
props: {
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
scrapySpidersNamesDict: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState('schedule', [
|
||||
'batchScheduleList'
|
||||
]),
|
||||
...mapState('spider', [
|
||||
'allSpiderList'
|
||||
]),
|
||||
...mapState('node', [
|
||||
'nodeList'
|
||||
]),
|
||||
activeNodeList() {
|
||||
return this.nodeList.filter(n => n.status === 'online')
|
||||
},
|
||||
validScheduleList() {
|
||||
return this.batchScheduleList.filter(d => !!d.spider_id && !!d.name && !!d.cron)
|
||||
},
|
||||
isConfirmDisabled() {
|
||||
if (this.validScheduleList.length === 0) {
|
||||
return true
|
||||
}
|
||||
for (let i = 0; i < this.validScheduleList.length; i++) {
|
||||
const row = this.validScheduleList[i]
|
||||
const spider = this.getSpiderById(row.spider_id)
|
||||
if (!spider) {
|
||||
return true
|
||||
}
|
||||
if (spider.is_scrapy && !row.scrapy_spider_name) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
},
|
||||
scrapySpidersIds() {
|
||||
return Array.from(new Set(this.validScheduleList.filter(d => {
|
||||
const spider = this.getSpiderById(d.spider_id)
|
||||
return spider && spider.is_scrapy
|
||||
}).map(d => d.spider_id)))
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
visible() {
|
||||
if (this.visible) {
|
||||
this.fetchAllScrapySpiderNames()
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
beforeClose() {
|
||||
this.$emit('close')
|
||||
},
|
||||
reset() {
|
||||
this.$store.commit('task/SET_BATCH_CRAWL_LIST', [])
|
||||
for (let i = 0; i < 10; i++) {
|
||||
this.batchScheduleList.push({
|
||||
spider_id: '',
|
||||
run_type: 'random',
|
||||
param: '',
|
||||
scrapy_log_level: 'INFO'
|
||||
})
|
||||
}
|
||||
this.$st.sendEv('批量添加定时任务', '重置')
|
||||
},
|
||||
getSpiderById(id) {
|
||||
return this.allSpiderList.filter(d => d._id === id)[0] || {}
|
||||
},
|
||||
async onSpiderChange(row, id) {
|
||||
const spider = this.getSpiderById(id)
|
||||
if (!spider) return
|
||||
if (spider.is_scrapy) {
|
||||
await this.fetchScrapySpiderNames(id)
|
||||
if (this.scrapySpidersNamesDict[id] && this.scrapySpidersNamesDict[id].length > 0) {
|
||||
this.$set(row, 'scrapy_spider_name', this.scrapySpidersNamesDict[id][0])
|
||||
}
|
||||
}
|
||||
this.$st.sendEv('批量添加定时任务', '选择爬虫')
|
||||
},
|
||||
getScrapySpiderNames(id) {
|
||||
if (!this.scrapySpidersNamesDict[id]) return []
|
||||
return this.scrapySpidersNamesDict[id]
|
||||
},
|
||||
async onConfirm() {
|
||||
const res = await this.$request.put('/schedules/batch', this.validScheduleList.map(d => {
|
||||
const spider = this.getSpiderById(d.spider_id)
|
||||
// Scrapy爬虫特殊处理
|
||||
if (spider.type === 'customized' && spider.is_scrapy) {
|
||||
d.param = `${this.scrapySpidersNamesDict[d.spider_id] ? this.scrapySpidersNamesDict[d.spider_id][0] : ''} --loglevel=${d.scrapy_log_level} ${d.param || ''}`
|
||||
}
|
||||
// cron特殊处理
|
||||
d.cron = '0 ' + d.cron
|
||||
return d
|
||||
}))
|
||||
if (res.status !== 200) {
|
||||
this.$message.error(res.data.error)
|
||||
return
|
||||
}
|
||||
this.reset()
|
||||
this.$emit('close')
|
||||
this.$emit('confirm')
|
||||
this.$st.sendEv('批量添加定时任务', '确认添加')
|
||||
},
|
||||
async fetchScrapySpiderNames(id) {
|
||||
if (!this.scrapySpidersNamesDict[id]) {
|
||||
const res = await this.$request.get(`/spiders/${id}/scrapy/spiders`)
|
||||
this.$set(this.scrapySpidersNamesDict, id, res.data.data)
|
||||
}
|
||||
},
|
||||
async fetchAllScrapySpiderNames() {
|
||||
await Promise.all(this.scrapySpidersIds.map(async id => {
|
||||
await this.fetchScrapySpiderNames(id)
|
||||
}))
|
||||
this.validScheduleList.filter(d => {
|
||||
const spider = this.getSpiderById(d.spider_id)
|
||||
return spider && spider.is_scrapy
|
||||
}).forEach(row => {
|
||||
const id = row.spider_id
|
||||
if (this.scrapySpidersNamesDict[id] && this.scrapySpidersNamesDict[id].length > 0) {
|
||||
this.$set(row, 'scrapy_spider_name', this.scrapySpidersNamesDict[id][0])
|
||||
}
|
||||
})
|
||||
},
|
||||
onAdd(rowIndex) {
|
||||
this.batchScheduleList.splice(rowIndex + 1, 0, {
|
||||
spider_id: '',
|
||||
run_type: 'random',
|
||||
param: '',
|
||||
scrapy_log_level: 'INFO'
|
||||
})
|
||||
this.$st.sendEv('批量添加定时任务', '添加')
|
||||
},
|
||||
onRemove(rowIndex) {
|
||||
this.batchScheduleList.splice(rowIndex, 1)
|
||||
this.$st.sendEv('批量添加定时任务', '删除')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.el-table .el-button {
|
||||
padding: 7px;
|
||||
}
|
||||
</style>
|
||||
@@ -157,14 +157,6 @@
|
||||
...mapState('node', [
|
||||
'nodeList'
|
||||
]),
|
||||
isBatchCrawlDialogVisible: {
|
||||
get() {
|
||||
return this.$store.state.task.isBatchCrawlDialogVisible
|
||||
},
|
||||
set(value) {
|
||||
this.$store.commit('task/SET_IS_BATCH_CRAWL_DIALOG_VISIBLE', value)
|
||||
}
|
||||
},
|
||||
activeNodeList() {
|
||||
return this.nodeList.filter(n => n.status === 'online')
|
||||
},
|
||||
@@ -172,6 +164,9 @@
|
||||
return this.batchCrawlList.filter(d => !!d.spider_id)
|
||||
},
|
||||
isConfirmDisabled() {
|
||||
if (this.validCrawlList.length === 0) {
|
||||
return true
|
||||
}
|
||||
for (let i = 0; i < this.validCrawlList.length; i++) {
|
||||
const row = this.validCrawlList[i]
|
||||
const spider = this.getSpiderById(row.spider_id)
|
||||
@@ -243,6 +238,7 @@
|
||||
}))
|
||||
this.reset()
|
||||
this.$emit('close')
|
||||
this.$emit('confirm')
|
||||
this.$st.sendEv('批量运行', '确认批量运行')
|
||||
},
|
||||
async fetchScrapySpiderNames(id) {
|
||||
|
||||
Reference in New Issue
Block a user