Merge branch 'master' of codeup.aliyun.com:pig/pigx/pigx-ui-pro into leng_dev

This commit is contained in:
lbw 2023-02-09 10:45:18 +08:00
commit 4d94a94cab
12 changed files with 1409 additions and 1 deletions

60
src/api/daemon/job.ts Normal file
View File

@ -0,0 +1,60 @@
import request from "/@/utils/request"
export function fetchList(query?: Object) {
return request({
url: '/admin/sys-job/page',
method: 'get',
params: query
})
}
export function addObj(obj?: Object) {
return request({
url: '/admin/sys-job',
method: 'post',
data: obj
})
}
export function getObj(id?: string) {
return request({
url: '/admin/sys-job/' + id,
method: 'get'
})
}
export function delObj(id?: string) {
return request({
url: '/admin/sys-job/' + id,
method: 'delete'
})
}
export function putObj(obj?: Object) {
return request({
url: '/admin/sys-job',
method: 'put',
data: obj
})
}
export function startJobRa(jobId:string) {
return request({
url: '/admin/sys-job/start-job/' + jobId,
method: 'post'
})
}
export function runJobRa(jobId: string) {
return request({
url: '/admin/sys-job/run-job/' + jobId,
method: 'post'
})
}
export function shutDownJobRa(jobId: string) {
return request({
url: '/admin/sys-job/shutdown-job/' + jobId,
method: 'post'
})
}

View File

@ -0,0 +1,4 @@
import Cron from './src/cron.vue'
export default Cron

View File

@ -0,0 +1,634 @@
<template>
<div class="crontab">
<el-button class="language" type="primary" link style="margin-top: 4px" @click="switchLang">{{ i18n }}</el-button>
<el-scrollbar height="260px">
<el-tabs type="border-card">
<el-tab-pane>
<template #label>
<span>
{{ text.Seconds.name }}
</span>
</template>
<div class="tabBody">
<el-row>
<el-radio v-model="second.cronEvery" label="1">{{ text.Seconds.every }}</el-radio>
</el-row>
<el-row>
<el-radio v-model="second.cronEvery" label="2"
>{{ text.Seconds.interval[0] }}
<el-input-number v-model="second.incrementIncrement" size="small" :min="1" :max="60"></el-input-number>
{{ text.Seconds.interval[1] || '' }}
<el-input-number v-model="second.incrementStart" size="small" :min="0" :max="59"></el-input-number>
{{ text.Seconds.interval[2] || '' }}
</el-radio>
</el-row>
<el-row>
<el-radio v-model="second.cronEvery" class="long" label="3"
>{{ text.Seconds.specific }}
<el-select v-model="second.specificSpecific" size="small" multiple>
<el-option v-for="val in 60" :key="val" :value="val - 1">{{ val - 1 }}</el-option>
</el-select>
</el-radio>
</el-row>
<el-row>
<el-radio v-model="second.cronEvery" label="4"
>{{ text.Seconds.cycle[0] }}
<el-input-number v-model="second.rangeStart" size="small" :min="1" :max="60"></el-input-number>
{{ text.Seconds.cycle[1] || '' }}
<el-input-number v-model="second.rangeEnd" size="small" :min="0" :max="59"></el-input-number>
{{ text.Seconds.cycle[2] || '' }}
</el-radio>
</el-row>
</div>
</el-tab-pane>
<el-tab-pane>
<template #label>
<span>
{{ text.Minutes.name }}
</span>
</template>
<div class="tabBody">
<el-row>
<el-radio v-model="minute.cronEvery" label="1">{{ text.Minutes.every }}</el-radio>
</el-row>
<el-row>
<el-radio v-model="minute.cronEvery" label="2"
>{{ text.Minutes.interval[0] }}
<el-input-number v-model="minute.incrementIncrement" size="small" :min="1" :max="60"></el-input-number>
{{ text.Minutes.interval[1] }}
<el-input-number v-model="minute.incrementStart" size="small" :min="0" :max="59"></el-input-number>
{{ text.Minutes.interval[2] || '' }}
</el-radio>
</el-row>
<el-row>
<el-radio v-model="minute.cronEvery" class="long" label="3"
>{{ text.Minutes.specific }}
<el-select v-model="minute.specificSpecific" size="small" multiple>
<el-option v-for="val in 60" :key="val" :value="val - 1">{{ val - 1 }}</el-option>
</el-select>
</el-radio>
</el-row>
<el-row>
<el-radio v-model="minute.cronEvery" label="4"
>{{ text.Minutes.cycle[0] }}
<el-input-number v-model="minute.rangeStart" size="small" :min="1" :max="60"></el-input-number>
{{ text.Minutes.cycle[1] }}
<el-input-number v-model="minute.rangeEnd" size="small" :min="0" :max="59"></el-input-number>
{{ text.Minutes.cycle[2] }}
</el-radio>
</el-row>
</div>
</el-tab-pane>
<el-tab-pane>
<template #label>
<span>
{{ text.Hours.name }}
</span>
</template>
<div class="tabBody">
<el-row>
<el-radio v-model="hour.cronEvery" label="1">{{ text.Hours.every }}</el-radio>
</el-row>
<el-row>
<el-radio v-model="hour.cronEvery" label="2"
>{{ text.Hours.interval[0] }}
<el-input-number v-model="hour.incrementIncrement" size="small" :min="0" :max="23"></el-input-number>
{{ text.Hours.interval[1] }}
<el-input-number v-model="hour.incrementStart" size="small" :min="0" :max="23"></el-input-number>
{{ text.Hours.interval[2] }}
</el-radio>
</el-row>
<el-row>
<el-radio v-model="hour.cronEvery" class="long" label="3"
>{{ text.Hours.specific }}
<el-select v-model="hour.specificSpecific" size="small" multiple>
<el-option v-for="val in 24" :key="val" :value="val - 1">{{ val - 1 }}</el-option>
</el-select>
</el-radio>
</el-row>
<el-row>
<el-radio v-model="hour.cronEvery" label="4"
>{{ text.Hours.cycle[0] }}
<el-input-number v-model="hour.rangeStart" size="small" :min="0" :max="23"></el-input-number>
{{ text.Hours.cycle[1] }}
<el-input-number v-model="hour.rangeEnd" size="small" :min="0" :max="23"></el-input-number>
{{ text.Hours.cycle[2] }}
</el-radio>
</el-row>
</div>
</el-tab-pane>
<el-tab-pane>
<template #label>
<span>
{{ text.Day.name }}
</span>
</template>
<div class="tabBody">
<el-row>
<el-radio v-model="day.cronEvery" label="1">{{ text.Day.every }}</el-radio>
</el-row>
<el-row>
<el-radio v-model="day.cronEvery" label="2"
>{{ text.Day.intervalWeek[0] }}
<el-input-number v-model="week.incrementIncrement" size="small" :min="1" :max="7"></el-input-number>
{{ text.Day.intervalWeek[1] }}
<el-select v-model="week.incrementStart" size="small">
<el-option v-for="val in 7" :key="val" :label="text.Week[val - 1]" :value="val"></el-option>
</el-select>
{{ text.Day.intervalWeek[2] }}
</el-radio>
</el-row>
<el-row>
<el-radio v-model="day.cronEvery" label="3"
>{{ text.Day.intervalDay[0] }}
<el-input-number v-model="day.incrementIncrement" size="small" :min="1" :max="31"></el-input-number>
{{ text.Day.intervalDay[1] }}
<el-input-number v-model="day.incrementStart" size="small" :min="1" :max="31"></el-input-number>
{{ text.Day.intervalDay[2] }}
</el-radio>
</el-row>
<el-row>
<el-radio v-model="day.cronEvery" class="long" label="4"
>{{ text.Day.specificWeek }}
<el-select v-model="week.specificSpecific" size="small" multiple>
<el-option
v-for="val in 7"
:key="val"
:label="text.Week[val - 1]"
:value="['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'][val - 1]"
></el-option>
</el-select>
</el-radio>
</el-row>
<el-row>
<el-radio v-model="day.cronEvery" class="long" label="5"
>{{ text.Day.specificDay }}
<el-select v-model="day.specificSpecific" size="small" multiple>
<el-option v-for="val in 31" :key="val" :value="val">{{ val }}</el-option>
</el-select>
</el-radio>
</el-row>
<el-row>
<el-radio v-model="day.cronEvery" label="6">{{ text.Day.lastDay }}</el-radio>
</el-row>
<el-row>
<el-radio v-model="day.cronEvery" label="7">{{ text.Day.lastWeekday }}</el-radio>
</el-row>
<el-row>
<el-radio v-model="day.cronEvery" label="8"
>{{ text.Day.lastWeek[0] }}
<el-select v-model="day.cronLastSpecificDomDay" size="small">
<el-option v-for="val in 7" :key="val" :label="text.Week[val - 1]" :value="val"></el-option>
</el-select>
{{ text.Day.lastWeek[1] || '' }}
</el-radio>
</el-row>
<el-row>
<el-radio v-model="day.cronEvery" label="9">
<el-input-number v-model="day.cronDaysBeforeEomMinus" size="small" :min="1" :max="31"></el-input-number>
{{ text.Day.beforeEndMonth[0] }}
</el-radio>
</el-row>
<el-row>
<el-radio v-model="day.cronEvery" label="10"
>{{ text.Day.nearestWeekday[0] }}
<el-input-number v-model="day.cronDaysNearestWeekday" size="small" :min="1" :max="31"></el-input-number>
{{ text.Day.nearestWeekday[1] }}
</el-radio>
</el-row>
<el-row>
<el-radio v-model="day.cronEvery" label="11"
>{{ text.Day.someWeekday[0] }}
<el-input-number v-model="week.cronNthDayNth" size="small" :min="1" :max="5"></el-input-number>
<el-select v-model="week.cronNthDayDay" size="small">
<el-option v-for="val in 7" :key="val" :label="text.Week[val - 1]" :value="val"></el-option>
</el-select>
{{ text.Day.someWeekday[1] }}
</el-radio>
</el-row>
</div>
</el-tab-pane>
<el-tab-pane>
<template #label>
<span>
{{ text.Month.name }}
</span>
</template>
<div class="tabBody">
<el-row>
<el-radio v-model="month.cronEvery" label="1">{{ text.Month.every }}</el-radio>
</el-row>
<el-row>
<el-radio v-model="month.cronEvery" label="2"
>{{ text.Month.interval[0] }}
<el-input-number v-model="month.incrementIncrement" size="small" :min="0" :max="12"></el-input-number>
{{ text.Month.interval[1] }}
<el-input-number v-model="month.incrementStart" size="small" :min="0" :max="12"></el-input-number>
</el-radio>
</el-row>
<el-row>
<el-radio v-model="month.cronEvery" class="long" label="3"
>{{ text.Month.specific }}
<el-select v-model="month.specificSpecific" size="small" multiple>
<el-option v-for="val in 12" :key="val" :label="val" :value="val"></el-option>
</el-select>
</el-radio>
</el-row>
<el-row>
<el-radio v-model="month.cronEvery" label="4"
>{{ text.Month.cycle[0] }}
<el-input-number v-model="month.rangeStart" size="small" :min="1" :max="12"></el-input-number>
{{ text.Month.cycle[1] }}
<el-input-number v-model="month.rangeEnd" size="small" :min="1" :max="12"></el-input-number>
</el-radio>
</el-row>
</div>
</el-tab-pane>
<el-tab-pane>
<template #label>
<span> {{ text.Year.name }} </span>
</template>
<div class="tabBody">
<el-row>
<el-radio v-model="year.cronEvery" label="1">{{ text.Year.every }}</el-radio>
</el-row>
<el-row>
<el-radio v-model="year.cronEvery" label="2"
>{{ text.Year.interval[0] }}
<el-input-number v-model="year.incrementIncrement" size="small" :min="1" :max="99"></el-input-number>
{{ text.Year.interval[1] }}
<el-input-number v-model="year.incrementStart" size="small" :min="2018" :max="2118"></el-input-number>
</el-radio>
</el-row>
<el-row>
<el-radio v-model="year.cronEvery" class="long" label="3"
>{{ text.Year.specific }}
<el-select v-model="year.specificSpecific" size="small" filterable multiple>
<el-option v-for="val in 100" :key="val" :label="2017 + val" :value="2017 + val"></el-option>
</el-select>
</el-radio>
</el-row>
<el-row>
<el-radio v-model="year.cronEvery" label="4"
>{{ text.Year.cycle[0] }}
<el-input-number v-model="year.rangeStart" size="small" :min="2018" :max="2118"></el-input-number>
{{ text.Year.cycle[1] }}
<el-input-number v-model="year.rangeEnd" size="small" :min="2018" :max="2118"></el-input-number>
</el-radio>
</el-row>
</div>
</el-tab-pane>
</el-tabs>
</el-scrollbar>
<div class="bottom">
<p class="value">{{ cron }}</p>
<el-button size="default" @click="close">{{ text.Close }}</el-button>
<el-button type="primary" size="default" @click="submit">{{ text.Save }}</el-button>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import Language from './language/index'
export default defineComponent({
name: 'FastCron',
props: ['data', 'lang'],
data() {
return {
i18n: this.lang,
second: {
cronEvery: '',
incrementStart: 3,
incrementIncrement: 5,
rangeStart: '',
rangeEnd: '',
specificSpecific: []
},
minute: {
cronEvery: '',
incrementStart: 3,
incrementIncrement: 5,
rangeStart: '',
rangeEnd: '',
specificSpecific: []
},
hour: {
cronEvery: '',
incrementStart: 3,
incrementIncrement: 5,
rangeStart: '',
rangeEnd: '',
specificSpecific: []
},
day: {
cronEvery: '',
incrementStart: 1,
incrementIncrement: 1,
rangeStart: '',
rangeEnd: '',
specificSpecific: [],
cronLastSpecificDomDay: 1,
cronDaysBeforeEomMinus: '',
cronDaysNearestWeekday: ''
},
week: {
cronEvery: '',
incrementStart: 1,
incrementIncrement: 1,
specificSpecific: [],
cronNthDayDay: 1,
cronNthDayNth: 1
},
month: {
cronEvery: '',
incrementStart: 3,
incrementIncrement: 5,
rangeStart: '',
rangeEnd: '',
specificSpecific: []
},
year: {
cronEvery: '',
incrementStart: 2017,
incrementIncrement: 1,
rangeStart: '',
rangeEnd: '',
specificSpecific: []
},
output: {
second: '',
minute: '',
hour: '',
day: '',
month: '',
Week: '',
year: ''
}
}
},
computed: {
text(): any {
return (Language as any)[this.i18n || 'zh-CN']
},
secondsText() {
let seconds = ''
let cronEvery = this.second.cronEvery
switch (cronEvery.toString()) {
case '1':
seconds = '*'
break
case '2':
seconds = this.second.incrementStart + '/' + this.second.incrementIncrement
break
case '3':
this.second.specificSpecific.map(val => {
seconds += val + ','
})
seconds = seconds.slice(0, -1)
break
case '4':
seconds = this.second.rangeStart + '-' + this.second.rangeEnd
break
}
return seconds
},
minutesText() {
let minutes = ''
let cronEvery = this.minute.cronEvery
switch (cronEvery.toString()) {
case '1':
minutes = '*'
break
case '2':
minutes = this.minute.incrementStart + '/' + this.minute.incrementIncrement
break
case '3':
this.minute.specificSpecific.map(val => {
minutes += val + ','
})
minutes = minutes.slice(0, -1)
break
case '4':
minutes = this.minute.rangeStart + '-' + this.minute.rangeEnd
break
}
return minutes
},
hoursText() {
let hours = ''
let cronEvery = this.hour.cronEvery
switch (cronEvery.toString()) {
case '1':
hours = '*'
break
case '2':
hours = this.hour.incrementStart + '/' + this.hour.incrementIncrement
break
case '3':
this.hour.specificSpecific.map(val => {
hours += val + ','
})
hours = hours.slice(0, -1)
break
case '4':
hours = this.hour.rangeStart + '-' + this.hour.rangeEnd
break
}
return hours
},
daysText() {
let days = ''
let cronEvery = this.day.cronEvery
switch (cronEvery.toString()) {
case '1':
break
case '2':
case '4':
case '11':
days = '?'
break
case '3':
days = this.day.incrementStart + '/' + this.day.incrementIncrement
break
case '5':
this.day.specificSpecific.map(val => {
days += val + ','
})
days = days.slice(0, -1)
break
case '6':
days = 'L'
break
case '7':
days = 'LW'
break
case '8':
days = this.day.cronLastSpecificDomDay + 'L'
break
case '9':
days = 'L-' + this.day.cronDaysBeforeEomMinus
break
case '10':
days = this.day.cronDaysNearestWeekday + 'W'
break
}
return days
},
weeksText() {
let weeks = ''
let cronEvery = this.day.cronEvery
switch (cronEvery.toString()) {
case '1':
case '3':
case '5':
weeks = '?'
break
case '2':
weeks = this.week.incrementStart + '/' + this.week.incrementIncrement
break
case '4':
this.week.specificSpecific.map(val => {
weeks += val + ','
})
weeks = weeks.slice(0, -1)
break
case '6':
case '7':
case '8':
case '9':
case '10':
weeks = '?'
break
case '11':
weeks = this.week.cronNthDayDay + '#' + this.week.cronNthDayNth
break
}
return weeks
},
monthsText() {
let months = ''
let cronEvery = this.month.cronEvery
switch (cronEvery.toString()) {
case '1':
months = '*'
break
case '2':
months = this.month.incrementStart + '/' + this.month.incrementIncrement
break
case '3':
this.month.specificSpecific.map(val => {
months += val + ','
})
months = months.slice(0, -1)
break
case '4':
months = this.month.rangeStart + '-' + this.month.rangeEnd
break
}
return months
},
yearsText() {
let years = ''
let cronEvery = this.year.cronEvery
switch (cronEvery.toString()) {
case '1':
years = '*'
break
case '2':
years = this.year.incrementStart + '/' + this.year.incrementIncrement
break
case '3':
this.year.specificSpecific.map(val => {
years += val + ','
})
years = years.slice(0, -1)
break
case '4':
years = this.year.rangeStart + '-' + this.year.rangeEnd
break
}
return years
},
cron() {
return `${this.secondsText || '*'} ${this.minutesText || '*'} ${this.hoursText || '*'} ${this.daysText || '*'} ${this.monthsText || '*'} ${
this.weeksText || '?'
} ${this.yearsText || '*'}`
}
},
watch: {
data() {
this.rest(this.$data)
},
lang(vl) {
this.i18n = vl
}
},
methods: {
getValue() {
return this.cron
},
submit() {
this.$emit('submit', this.cron)
this.close()
},
close() {
this.$emit('close')
},
rest(data: any) {
for (let i in data) {
if (data[i] instanceof Object) {
this.rest(data[i])
} else {
switch (typeof data[i]) {
case 'object':
data[i] = []
break
case 'string':
data[i] = ''
break
}
}
}
},
switchLang() {
this.i18n = this.i18n === 'en-US' ? 'zh-CN' : 'en-US'
}
}
})
</script>
<style lang="scss" scoped>
.crontab {
.language {
position: absolute;
right: 25px;
z-index: 1;
}
.el-tabs {
box-shadow: none;
}
.tabBody {
.el-row {
margin: 10px 0;
.long {
.el-select {
width: 350px;
}
}
.el-input-number {
width: 110px;
}
}
}
.bottom {
width: 100%;
text-align: center;
margin-top: 5px;
position: relative;
.value {
font-size: 18px;
vertical-align: middle;
}
}
}
</style>

View File

@ -0,0 +1,54 @@
export default {
Seconds: {
name: 'Seconds',
every: 'Every second',
interval: ['Every', 'second(s) starting at second'],
specific: 'Specific second (choose one or many)',
cycle: ['Every second between second', 'and second']
},
Minutes: {
name: 'Minutes',
every: 'Every minute',
interval: ['Every', 'minute(s) starting at minute'],
specific: 'Specific minute (choose one or many)',
cycle: ['Every minute between minute', 'and minute']
},
Hours: {
name: 'Hours',
every: 'Every hour',
interval: ['Every', 'hour(s) starting at hour'],
specific: 'Specific hour (choose one or many)',
cycle: ['Every hour between hour', 'and hour']
},
Day: {
name: 'Day',
every: 'Every day',
intervalWeek: ['Every', 'day(s) starting on'],
intervalDay: ['Every', 'day(s) starting at the', 'of the month'],
specificWeek: 'Specific day of week (choose one or many)',
specificDay: 'Specific day of month (choose one or many)',
lastDay: 'On the last day of the month',
lastWeekday: 'On the last weekday of the month',
lastWeek: ['On the last', ' of the month'],
beforeEndMonth: ['day(s) before the end of the month'],
nearestWeekday: ['Nearest weekday (Monday to Friday) to the', 'of the month'],
someWeekday: ['On the', 'of the month']
},
Week: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
Month: {
name: 'Month',
every: 'Every month',
interval: ['Every', 'month(s) starting in'],
specific: 'Specific month (choose one or many)',
cycle: ['Every month between', 'and']
},
Year: {
name: 'Year',
every: 'Any year',
interval: ['Every', 'year(s) starting in'],
specific: 'Specific year (choose one or many)',
cycle: ['Every year between', 'and']
},
Save: 'Save',
Close: 'Close'
}

View File

@ -0,0 +1,7 @@
import en from './en-US'
import cn from './zh-CN'
export default {
'en-US': en,
'zh-CN': cn
}

View File

@ -0,0 +1,54 @@
export default {
Seconds: {
name: '秒',
every: '每一秒钟',
interval: ['每隔', '秒执行 从', '秒开始'],
specific: '具体秒数(可多选)',
cycle: ['周期从', '到', '秒']
},
Minutes: {
name: '分',
every: '每一分钟',
interval: ['每隔', '分执行 从', '分开始'],
specific: '具体分钟数(可多选)',
cycle: ['周期从', '到', '分']
},
Hours: {
name: '时',
every: '每一小时',
interval: ['每隔', '小时执行 从', '小时开始'],
specific: '具体小时数(可多选)',
cycle: ['周期从', '到', '小时']
},
Day: {
name: '天',
every: '每一天',
intervalWeek: ['每隔', '周执行 从', '开始'],
intervalDay: ['每隔', '天执行 从', '天开始'],
specificWeek: '具体星期几(可多选)',
specificDay: '具体天数(可多选)',
lastDay: '在这个月的最后一天',
lastWeekday: '在这个月的最后一个工作日',
lastWeek: ['在这个月的最后一个'],
beforeEndMonth: ['在本月底前', '天'],
nearestWeekday: ['最近的工作日(周一至周五)至本月', '日'],
someWeekday: ['在这个月的第', '个']
},
Week: ['天', '一', '二', '三', '四', '五', '六'].map(val => '星期' + val),
Month: {
name: '月',
every: '每一月',
interval: ['每隔', '月执行 从', '月开始'],
specific: '具体月数(可多选)',
cycle: ['从', '到', '月之间的每个月']
},
Year: {
name: '年',
every: '每一年',
interval: ['每隔', '年执行 从', '年开始'],
specific: '具体年份(可多选)',
cycle: ['从', '到', '年之间的每一年']
},
Save: '确定',
Close: '取消'
}

View File

@ -0,0 +1,188 @@
<template>
<el-dialog v-model="visible" :close-on-click-modal="false"
:title="form.jobId ? $t('common.editBtn') : $t('common.addBtn')" draggable>
<el-form ref="dataFormRef" :model="form" :rules="dataRules" formDialogRef label-width="120px">
<el-row :gutter="24">
<el-col :span="12" class="mb20">
<el-form-item :label="t('job.jobName')" prop="jobName">
<el-input v-model="form.jobName" :placeholder="t('job.inputjobNameTip')"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item :label="t('job.jobGroup')" prop="jobGroup">
<el-input v-model="form.jobGroup" :placeholder="t('job.inputjobGroupTip')"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item :label="t('job.jobType')" prop="jobType">
<el-select v-model="form.jobType" :placeholder="t('job.jobType')">
<el-option v-for="(item, index) in job_type" :key="index" :label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item :label="t('job.executePath')" prop="executePath">
<el-input v-model="form.executePath" :placeholder="t('job.inputexecutePathTip')"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item :label="t('job.className')" prop="className">
<el-input v-model="form.className" :placeholder="t('job.inputclassNameTip')"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item :label="t('job.methodName')" prop="methodName">
<el-input v-model="form.methodName" :placeholder="t('job.inputmethodNameTip')"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item :label="t('job.methodParamsValue')" prop="methodParamsValue">
<el-input v-model="form.methodParamsValue" :placeholder="t('job.inputmethodParamsValueTip')"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item :label="t('job.cronExpression')" prop="cronExpression">
<el-popover ref="cronPopover" :width="550" trigger="click" placement="left">
<crontab @submit="changeCron" @close="cronPopover.hide()"></crontab>
<template #reference>
<el-input v-model="form.cronExpression" :placeholder="t('job.inputcronExpressionTip')"/>
</template>
</el-popover>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item :label="t('job.misfirePolicy')" prop="misfirePolicy">
<el-select v-model="form.misfirePolicy" :placeholder="t('job.inputmisfirePolicyTip')">
<el-option v-for="(item, index) in misfire_policy" :key="index" :label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24" class="mb20">
<el-form-item :label="t('job.remark')" prop="remark">
<el-input v-model="form.remark" :placeholder="t('job.inputremarkTip')" type="textarea"/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button formDialogRef @click="visible = false">{{ $t('common.cancelButtonText') }}</el-button>
<el-button formDialogRef type="primary" @click="onSubmit">{{ $t('common.confirmButtonText') }}</el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts" name="SysJobDialog" setup>
// /
import {useDict} from '/@/hooks/dict';
import {useMessage} from "/@/hooks/message";
import {addObj, getObj, putObj} from '/@/api/daemon/job'
import {useI18n} from "vue-i18n"
const emit = defineEmits(['refresh']);
const Crontab = defineAsyncComponent(() => import('/@/components/Cron/index'))
const {t} = useI18n();
//
const dataFormRef = ref();
const cronPopover = ref();
const visible = ref(false)
//
const {job_status, job_execute_status,misfire_policy,job_type} = useDict('job_status', 'job_execute_status','misfire_policy','job_type')
//
const form = reactive({
jobId: '',
jobName: '',
jobGroup: '',
jobType: '',
executePath: '',
className: '',
methodName: '',
methodParamsValue: '',
cronExpression: '',
misfirePolicy: '',
jobStatus: '',
jobExecuteStatus: '',
remark: '',
});
const changeCron = (e: string) => {
form.cronExpression = e
}
//
const dataRules = ref({})
//
const openDialog = (id: string) => {
visible.value = true
form.jobId = ''
//
if (dataFormRef.value) {
dataFormRef.value.resetFields()
}
// sysJob
if (id) {
form.jobId = id
getsysJobData(id)
}
};
//
const onSubmit = () => {
dataFormRef.value.validate((valid: boolean) => {
if (!valid) {
return false
}
//
if (form.jobId) {
putObj(form).then(() => {
useMessage().success(t('common.editSuccessText'))
visible.value = false //
emit('refresh')
}).catch((err: any) => {
useMessage().error(err.msg)
})
} else {
addObj(form).then(() => {
useMessage().success(t('common.addSuccessText'))
visible.value = false //
emit('refresh')
}).catch((err: any) => {
useMessage().error(err.msg)
})
}
})
}
//
const getsysJobData = (id: string) => {
//
getObj(id).then((res: any) => {
Object.assign(form, res.data)
})
};
//
defineExpose({
openDialog
});
</script>

View File

@ -0,0 +1,56 @@
export default {
job: {
index: 'index',
importsysJobTip: 'import SysJob',
jobId: 'jobId',
jobName: 'jobName',
jobGroup: 'jobGroup',
jobOrder: 'jobOrder',
jobType: 'jobType',
executePath: 'executePath',
className: 'className',
methodName: 'methodName',
methodParamsValue: 'methodParamsValue',
cronExpression: 'cronExpression',
misfirePolicy: 'misfirePolicy',
jobTenantType: 'jobTenantType',
jobStatus: 'jobStatus',
jobExecuteStatus: 'jobExecuteStatus',
createBy: 'createBy',
createTime: 'createTime',
updateBy: 'updateBy',
updateTime: 'updateTime',
startTime: 'startTime',
previousTime: 'previousTime',
nextTime: 'nextTime',
tenantId: 'tenantId',
remark: 'remark',
jobMessage: 'jobMessage',
jobLogStatus: 'jobLogStatus',
executeTime: 'executeTime',
exceptionInfo: 'exceptionInfo',
inputjobIdTip: 'input jobId',
inputjobNameTip: 'input jobName',
inputjobGroupTip: 'input jobGroup',
inputjobOrderTip: 'input jobOrder',
inputjobTypeTip: 'input jobType',
inputexecutePathTip: 'input executePath',
inputclassNameTip: 'input className',
inputmethodNameTip: 'input methodName',
inputmethodParamsValueTip: 'input methodParamsValue',
inputcronExpressionTip: 'input cronExpression',
inputmisfirePolicyTip: 'input misfirePolicy',
inputjobTenantTypeTip: 'input jobTenantType',
inputjobStatusTip: 'input jobStatus',
inputjobExecuteStatusTip: 'input jobExecuteStatus',
inputcreateByTip: 'input createBy',
inputcreateTimeTip: 'input createTime',
inputupdateByTip: 'input updateBy',
inputupdateTimeTip: 'input updateTime',
inputstartTimeTip: 'input startTime',
inputpreviousTimeTip: 'input previousTime',
inputnextTimeTip: 'input nextTime',
inputtenantIdTip: 'input tenantId',
inputremarkTip: 'input remark',
}
}

View File

@ -0,0 +1,56 @@
export default {
job: {
index: '序号',
importsysJobTip: '导入定时任务调度表',
jobId: '任务id',
jobName: '任务名称',
jobGroup: '任务组名',
jobOrder: '组内执行顺利',
jobType: '类型',
executePath: '执行路径',
className: '执行文件',
methodName: '执行方法',
methodParamsValue: '参数值',
cronExpression: 'cron表达式',
misfirePolicy: '错失执行策略',
jobTenantType: '1、多租户任务;2、非多租户任务',
jobStatus: '任务状态',
jobExecuteStatus: '执行状态',
createBy: '创建者',
createTime: '创建时间',
updateBy: '更新者',
updateTime: '更新时间',
startTime: '初次执行时间',
previousTime: '上次执行时间',
nextTime: '下次执行时间',
tenantId: '租户',
remark: '备注信息',
jobMessage: '日志信息',
jobLogStatus: '执行状态',
executeTime: '执行时间',
exceptionInfo: '异常信息',
inputjobIdTip: '请输入任务id',
inputjobNameTip: '请输入任务名称',
inputjobGroupTip: '请输入任务组名',
inputjobOrderTip: '请输入组内执行顺利',
inputjobTypeTip: '请输入类型',
inputexecutePathTip: '请输入执行路径',
inputclassNameTip: '请输入执行文件',
inputmethodNameTip: '请输入执行方法',
inputmethodParamsValueTip: '请输入参数值',
inputcronExpressionTip: '请输入cron表达式',
inputmisfirePolicyTip: '请输入错失执行策略',
inputjobTenantTypeTip: '请输入1、多租户任务;2、非多租户任务',
inputjobStatusTip: '请输入任务状态',
inputjobExecuteStatusTip: '请输入执行状态',
inputcreateByTip: '请输入创建者',
inputcreateTimeTip: '请输入创建时间',
inputupdateByTip: '请输入更新者',
inputupdateTimeTip: '请输入更新时间',
inputstartTimeTip: '请输入初次执行时间',
inputpreviousTimeTip: '请输入上次执行时间',
inputnextTimeTip: '请输入下次执行时间',
inputtenantIdTip: '请输入租户',
inputremarkTip: '请输入备注信息',
}
}

View File

@ -0,0 +1,217 @@
<template>
<div class="layout-padding">
<el-card class="layout-padding-auto">
<el-row>
<div class="mb8" style="width: 100%">
<el-button class="ml10" formDialogRef icon="folder-add" type="primary" @click="formDialogRef.openDialog()">
{{ $t('common.addBtn') }}
</el-button>
<el-button class="ml10" formDialogRef icon="Download" type="primary" @click="exportExcel">
{{ $t('common.exportBtn') }}
</el-button>
<el-button :disabled="multiple" class="ml10" formDialogRef icon="Delete" type="primary"
@click="handleDelete(undefined)">
{{ $t('common.delBtn') }}
</el-button>
<right-toolbar v-model:showSearch="showSearch" class="ml10" style="float: right;margin-right: 20px"
@queryTable="getDataList"></right-toolbar>
</div>
</el-row>
<el-table v-loading="state.loading" :data="state.dataList" style="width: 100%"
@selection-change="handleSelectionChange">
<el-table-column align="center" type="selection" width="50"/>
<el-table-column :label="t('job.index')" type="index" width="80" fixed="left"/>
<el-table-column :label="t('job.jobName')" prop="jobName" show-overflow-tooltip width="120" fixed="left"/>
<el-table-column :label="t('job.jobGroup')" prop="jobGroup" show-overflow-tooltip width="120"/>
<el-table-column :label="t('job.jobStatus')" prop="jobStatus" show-overflow-tooltip width="120">
<template #default="scope">
<dict-tag :options="job_status" :value="scope.row.jobStatus"></dict-tag>
</template>
</el-table-column>
<el-table-column :label="t('job.jobExecuteStatus')" prop="jobExecuteStatus" show-overflow-tooltip width="120">
<template #default="scope">
<dict-tag :options="job_execute_status" :value="scope.row.jobExecuteStatus"></dict-tag>
</template>
</el-table-column>
<el-table-column :label="t('job.startTime')" prop="startTime" show-overflow-tooltip width="120"/>
<el-table-column :label="t('job.previousTime')" prop="previousTime" show-overflow-tooltip width="120"/>
<el-table-column :label="t('job.nextTime')" prop="nextTime" show-overflow-tooltip width="120"/>
<el-table-column :label="t('job.jobType')" prop="jobType" show-overflow-tooltip width="120">
<template #default="scope">
<dict-tag :options="job_type" :value="scope.row.jobType"></dict-tag>
</template>
</el-table-column>
<el-table-column :label="t('job.executePath')" prop="executePath" show-overflow-tooltip width="120"/>
<el-table-column :label="t('job.className')" prop="className" show-overflow-tooltip width="120"/>
<el-table-column :label="t('job.methodName')" prop="methodName" show-overflow-tooltip width="120"/>
<el-table-column :label="t('job.methodParamsValue')" prop="methodParamsValue" show-overflow-tooltip width="120"/>
<el-table-column :label="t('job.cronExpression')" prop="cronExpression" show-overflow-tooltip width="120"/>
<el-table-column :label="t('job.misfirePolicy')" prop="misfirePolicy" show-overflow-tooltip width="200">
<template #default="scope">
<dict-tag :options="misfire_policy" :value="scope.row.misfirePolicy"></dict-tag>
</template>
</el-table-column>
<el-table-column :label="$t('common.action')" width="300" fixed="right">
<template #default="scope">
<el-button size="small" text type="primary" @click="handleJobLog(scope.row)">日志</el-button>
<el-button size="small" text type="primary" @click="handleStartJob(scope.row)">启动</el-button>
<el-button size="small" text type="primary" @click="handleShutDownJob(scope.row)">暂停</el-button>
<el-button size="small" text type="primary" @click="handleEditJob(scope.row)">{{ $t('common.editBtn') }}</el-button>
<el-button size="small" text type="primary" @click="handleRunJob(scope.row)">执行</el-button>
<el-button size="small" text type="primary" @click="handleDelete(scope.row)">{{$t('common.delBtn') }}</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-bind="state.pagination" @size-change="sizeChangeHandle" @current-change="currentChangeHandle"/>
</el-card>
<!-- 编辑新增 -->
<form-dialog ref="formDialogRef" @refresh="getDataList()"/>
<job-log ref="jobLogRef"></job-log>
</div>
</template>
<script lang="ts" name="systemSysJob" setup>
import {BasicTableProps, useTable} from "/@/hooks/table";
import {delObj, fetchList, startJobRa, runJobRa, shutDownJobRa} from "/@/api/daemon/job";
import {useMessage, useMessageBox} from "/@/hooks/message";
import {useDict} from '/@/hooks/dict';
import {useI18n} from "vue-i18n";
//
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
const JobLog = defineAsyncComponent(() => import('./job-log.vue'));
const {t} = useI18n()
//
const {job_status, job_execute_status,misfire_policy,job_type} = useDict('job_status', 'job_execute_status','misfire_policy','job_type')
//
const formDialogRef = ref()
const jobLogRef = ref()
//
const queryRef = ref()
const showSearch = ref(true)
//
const selectObjs = ref([])
const multiple = ref(true)
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: {},
pageList: fetchList
})
// table hook
const {
getDataList,
currentChangeHandle,
sizeChangeHandle,
downBlobFile
} = useTable(state)
//
const resetQuery = () => {
queryRef.value.resetFields()
getDataList()
}
//
const handleSelectionChange = (val: any) => {
selectObjs.value = val
multiple.value = !val.length
}
// excel
const exportExcel = () => {
downBlobFile('/pigx/job/export', state.queryForm, 'job.xlsx')
}
const handleJobLog = (row: any) => {
jobLogRef.value.openDialog(row.jobId)
}
const handleEditJob = (row: any) => {
const jobStatus = row.jobStatus;
if (jobStatus === "1" || jobStatus === "3") {
formDialogRef.value.openDialog(row.jobId)
}else {
useMessage().error("运行中定时任务不可修改,请先暂停后操作")
}
}
const handleStartJob = (row: any) =>{
const jobStatus = row.jobStatus;
if (jobStatus === "1" || jobStatus === "3"){
useMessageBox().confirm("即将发布或启动(任务名称:" + row.jobName + "), 是否继续?").then(() => {
startJobRa(row.jobId).then(() => {
getDataList();
useMessage().success(t('common.optSuccessText'));
}).catch((err: any) => {
useMessage().error(err.msg)
})
})
}else{
useMessage().error("定时任务已运行");
}
}
const handleShutDownJob = (row: any) => {
const jobStatus = row.jobStatus;
if (jobStatus === "2") {
useMessageBox().confirm("即将暂停(任务名称:" + row.jobName + "), 是否继续?").then(() => {
shutDownJobRa(row.jobId).then(() => {
getDataList();
useMessage().success(t('common.optSuccessText'));
}).catch((err: any) => {
useMessage().error(err.msg)
})
})
}else {
useMessage().error("已暂停,不要重复操作")
}
}
const handleRunJob = (row: any) => {
useMessageBox().confirm("立刻执行一次任务(任务名称:" + row.jobName + "), 是否继续?",).then(() => {
runJobRa(row.jobId).then(() => {
getDataList();
useMessage().success(t('common.optSuccessText'));
}).catch((err: any) => {
useMessage().error(err.msg)
})
})
}
//
const handleDelete = (row: any) => {
if (!row) {
selectObjs.value.forEach((val: any) => {
handleDelete(val)
});
return
}
useMessageBox().confirm(t('common.delConfirmText') +"(任务名称:" + row.jobName + ")")
.then(() => {
delObj(row.jobId).then(() => {
getDataList();
useMessage().success(t('common.delSuccessText'));
}).catch((err: any) => {
useMessage().error(err.msg)
})
})
};
</script>

View File

@ -0,0 +1,74 @@
<template>
<el-dialog v-model="visible" :close-on-click-modal="false" fullscreen
title="运行日志" draggable>
<el-table v-loading="state.loading" :data="state.dataList" style="width: 100%">
<el-table-column prop="jobId" :label="t('job.jobId')" show-overflow-tooltip/>
<el-table-column prop="jobName" :label="t('job.jobName')" show-overflow-tooltip/>
<el-table-column prop="jobGroup" :label="t('job.jobGroup')" show-overflow-tooltip/>
<el-table-column prop="jobOrder" :label="t('job.jobOrder')" show-overflow-tooltip/>
<el-table-column prop="jobType" :label="t('job.jobType')" show-overflow-tooltip>
<template #default="scope">
<dict-tag :options="job_type" :value="scope.row.jobType"></dict-tag>
</template>
</el-table-column>
<el-table-column prop="executePath" :label="t('job.executePath')" show-overflow-tooltip/>
<el-table-column prop="className" :label="t('job.className')" show-overflow-tooltip/>
<el-table-column prop="methodName" :label="t('job.methodName')" show-overflow-tooltip/>
<el-table-column prop="methodParamsValue" :label="t('job.methodParamsValue')" show-overflow-tooltip/>
<el-table-column prop="cronExpression" :label="t('job.cronExpression')" show-overflow-tooltip/>
<el-table-column prop="jobMessage" :label="t('job.jobMessage')" show-overflow-tooltip/>
<el-table-column prop="jobLogStatus" :label="t('job.jobLogStatus')" show-overflow-tooltip>
<template #default="scope">
<dict-tag :options="job_execute_status" :value="scope.row.jobLogStatus"></dict-tag>
</template>
</el-table-column>
<el-table-column prop="executeTime" :label="t('job.executeTime')" show-overflow-tooltip/>
<el-table-column prop="exceptionInfo" :label="t('job.exceptionInfo')" show-overflow-tooltip/>
<el-table-column prop="createTime" :label="t('job.createTime')" show-overflow-tooltip/>
</el-table>
<pagination v-bind="state.pagination" @size-change="sizeChangeHandle" @current-change="currentChangeHandle"/>
</el-dialog>
</template>
<script setup lang="ts" name="job-log">
import {BasicTableProps, useTable} from "/@/hooks/table";
import {fetchList} from "/@/api/daemon/job";
import {useI18n} from "vue-i18n";
import { useDict } from '/@/hooks/dict';
const {t} = useI18n()
const visible = ref(false)
const { job_type,job_execute_status } = useDict('job_type','job_execute_status')
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: {
jobId: ''
},
pageList: fetchList,
createdIsNeed: false
})
const {
getDataList,
currentChangeHandle,
sizeChangeHandle
} = useTable(state)
const openDialog = (id: string) => {
visible.value = true
state.queryForm.jobId = id
getDataList()
};
//
defineExpose({
openDialog
});
</script>
<style scoped>
</style>

View File

@ -102,7 +102,8 @@ const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: {
dsName: 'master'
},
pageList: fetchList
pageList: fetchList,
createdIsNeed: false
})
// table hook
@ -117,6 +118,9 @@ const {
onMounted(() => {
list().then(res => {
datasourceList.value = res.data
//
state.queryForm.dsName = datasourceList.value[0].name
getDataList()
})
})