mirror of
https://gitee.com/fit2cloud-feizhiyun/MeterSphere.git
synced 2024-11-30 11:08:38 +08:00
Scheduler 前端组件
This commit is contained in:
parent
32ddafa8b1
commit
268b03dac6
@ -48,7 +48,9 @@
|
||||
"rules": {
|
||||
"vue/no-unused-components": "off",
|
||||
"no-console": "off",
|
||||
"no-unused-vars": "off"
|
||||
"no-unused-vars": "off",
|
||||
"no-unused-expressions": "off",
|
||||
"no-unused-labels": "off"
|
||||
},
|
||||
"parserOptions": {
|
||||
"parser": "babel-eslint"
|
||||
|
@ -4,7 +4,7 @@
|
||||
<el-card>
|
||||
<el-container class="test-container" v-loading="result.loading">
|
||||
<el-header>
|
||||
<el-row type="flex" align="middle">
|
||||
<el-row>
|
||||
<el-input :disabled="isReadOnly" class="test-name" v-model="test.name" maxlength="60"
|
||||
:placeholder="$t('api_test.input_name')"
|
||||
show-word-limit>
|
||||
@ -47,7 +47,7 @@
|
||||
|
||||
<ms-api-report-dialog :test-id="id" ref="reportDialog"/>
|
||||
|
||||
<scheduler-config/>
|
||||
<ms-scheduler-config/>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<ms-api-scenario-config :is-read-only="isReadOnly" :scenarios="test.scenarioDefinition" ref="config"/>
|
||||
@ -63,12 +63,12 @@
|
||||
import MsApiReportStatus from "../report/ApiReportStatus";
|
||||
import MsApiReportDialog from "./ApiReportDialog";
|
||||
import {checkoutTestManagerOrTestUser, downloadFile} from "../../../../common/js/utils";
|
||||
import SchedulerConfig from "./SchedulerConfig";
|
||||
import MsSchedulerConfig from "../../common/components/MsSchedulerConfig";
|
||||
|
||||
export default {
|
||||
name: "MsApiTestConfig",
|
||||
|
||||
components: {SchedulerConfig, MsApiReportDialog, MsApiReportStatus, MsApiScenarioConfig},
|
||||
components: {MsSchedulerConfig, MsApiReportDialog, MsApiReportStatus, MsApiScenarioConfig},
|
||||
|
||||
props: ["id"],
|
||||
|
||||
@ -248,4 +248,8 @@
|
||||
.test-container .more {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.scheduler-config {
|
||||
float: right;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,48 +0,0 @@
|
||||
<template>
|
||||
<div class="scheduler-config">
|
||||
<i class="el-icon-date" size="small"></i>
|
||||
<span class="character">SCHEDULER</span>
|
||||
<el-button type="primary" size="mini" icon="el-icon-plus" plain @click="schedulerEdit"/>
|
||||
<scheduler-edit ref="schedulerEdit"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SchedulerEdit from "./SchedulerEdit";
|
||||
export default {
|
||||
name: "SchedulerConfig",
|
||||
components: {SchedulerEdit},
|
||||
methods: {
|
||||
schedulerEdit() {
|
||||
this.$refs.schedulerEdit.open();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.scheduler-config {
|
||||
float: right;
|
||||
background: #44b349;
|
||||
width: 180px;
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
.el-col {
|
||||
line-height: 28px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.el-icon-date {
|
||||
font-size: 20px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.character {
|
||||
font-weight: bold;
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
</style>
|
@ -1,47 +0,0 @@
|
||||
<template>
|
||||
<el-dialog :title="'编辑定时任务'" :visible.sync="dialogVisible">
|
||||
<div id="app">
|
||||
<div class="box">
|
||||
<el-input v-model="input" placeholder class="inp"></el-input>
|
||||
<el-button type="primary" @click="showDialog">生成 cron</el-button>
|
||||
</div>
|
||||
<el-dialog title="生成 cron" :visible.sync="showCron">
|
||||
<!-- <vcrontab @hide="showCron=false" @fill="crontabFill" :expression="expression"/>-->
|
||||
</el-dialog>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import vcrontab from "../../common/cron/Crontab";
|
||||
|
||||
export default {
|
||||
name: "SchedulerEdit",
|
||||
// comments: {vcrontab},
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
input: "",
|
||||
expression: "",
|
||||
showCron: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
open() {
|
||||
this.dialogVisible = true;
|
||||
},
|
||||
crontabFill(value) {
|
||||
//确定后回传的值
|
||||
this.input = value;
|
||||
},
|
||||
showDialog() {
|
||||
this.expression = this.input;//传入的 cron 表达式,可以反解析到 UI 上
|
||||
this.showCron = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<div class="scheduler-config">
|
||||
<div>
|
||||
<span class="cron-ico">
|
||||
<i class="el-icon-date" size="small"></i>
|
||||
<span class="character" @click="schedulerEdit">SCHEDULER</span>
|
||||
</span>
|
||||
<el-switch v-model="isActive"/>
|
||||
<!-- <el-button class="add-button" type="primary" size="mini" icon="el-icon-plus" plain @click="schedulerEdit"/>-->
|
||||
<ms-scheduler-edit ref="schedulerEdit"/>
|
||||
</div>
|
||||
<div>
|
||||
<span :class="{'disable-character': !isActive}"> 下次执行时间:2020-06-19 12:07:09 </span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsSchedulerEdit from "./MsSchedulerEdit";
|
||||
export default {
|
||||
name: "MsSchedulerConfig",
|
||||
components: {MsSchedulerEdit},
|
||||
data() {
|
||||
return {
|
||||
isActive: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
schedulerEdit() {
|
||||
this.$refs.schedulerEdit.open();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.scheduler-config {
|
||||
float: right;
|
||||
width: 250px;
|
||||
height: 15px;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
.el-icon-date {
|
||||
font-size: 20px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.character {
|
||||
font-weight: bold;
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.disable-character {
|
||||
color: #cccccc;
|
||||
}
|
||||
|
||||
/*.scheduler-config >>> .el-switch__core::after {*/
|
||||
/* height: 12px;*/
|
||||
/* width: 12px;*/
|
||||
/*}*/
|
||||
|
||||
/*.scheduler-config >>> .el-switch__core {*/
|
||||
/* height: 15px;*/
|
||||
/*}*/
|
||||
|
||||
/*.scheduler-config >>> .el-switch.is-checked .el-switch__core::after {*/
|
||||
/* margin-left: -13px;*/
|
||||
/*}*/
|
||||
|
||||
.el-switch {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.cron-ico {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
</style>
|
@ -0,0 +1,92 @@
|
||||
<template>
|
||||
<el-dialog width="30%" class="scheduler-edit" :title="'编辑定时任务'" :visible.sync="dialogVisible" @close="close">
|
||||
<div id="app">
|
||||
<el-form :model="form" :rules="rules" ref="from">
|
||||
<el-form-item
|
||||
:placeholder="'请输入 Cron 表达式'"
|
||||
prop="cronValue">
|
||||
<el-input v-model="form.cronValue" placeholder class="inp"/>
|
||||
<el-button type="primary" @click="showCronDialog">生成 Cron</el-button>
|
||||
<el-button type="primary" @click="save">保存</el-button>
|
||||
</el-form-item>
|
||||
<crontab-result :ex="cronExpression"/>
|
||||
</el-form>
|
||||
<el-dialog title="生成 cron" :visible.sync="showCron" :modal="false">
|
||||
<crontab @hide="showCron=false" @fill="crontabFill" :expression="cronExpression"/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import Crontab from "../cron/Crontab";
|
||||
import CrontabResult from "../cron/CrontabResult";
|
||||
import {cronValidate} from "../../../../common/js/cron";
|
||||
|
||||
export default {
|
||||
name: "MsSchedulerEdit",
|
||||
components: {CrontabResult, Crontab},
|
||||
data() {
|
||||
const validateCron = (rule, cronValue, callback) => {
|
||||
if (!cronValidate(cronValue)) {
|
||||
callback(new Error('Cron 表达式格式错误'));
|
||||
} else {
|
||||
this.cronExpression = cronValue;
|
||||
callback();
|
||||
}
|
||||
};
|
||||
return {
|
||||
dialogVisible: false,
|
||||
cronExpression: null,
|
||||
showCron: false,
|
||||
form: {
|
||||
cronValue: ""
|
||||
},
|
||||
rules: {
|
||||
cronValue :[{required: true, validator: validateCron, trigger: 'blur'}],
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
open() {
|
||||
this.dialogVisible = true;
|
||||
},
|
||||
crontabFill(value) {
|
||||
//确定后回传的值
|
||||
this.cronExpression = value;
|
||||
this.form.cronValue = value;
|
||||
this.$refs['from'].validate();
|
||||
},
|
||||
showCronDialog() {
|
||||
this.showCron = true;
|
||||
},
|
||||
save () {
|
||||
if (!this.formValidate()) {
|
||||
return;
|
||||
}
|
||||
console.log("save");
|
||||
},
|
||||
formValidate() {
|
||||
this.$refs['from'].validate((valid) => {
|
||||
if (!valid) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
close() {
|
||||
this.cronExpression = null;
|
||||
this.$refs['from'].resetFields();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.inp {
|
||||
width: 50%;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
</style>
|
@ -1,133 +0,0 @@
|
||||
<template>
|
||||
</template>
|
||||
<el-form size="small">
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="1">
|
||||
秒,允许的通配符[, - * /]
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="2">
|
||||
周期从
|
||||
<el-input-number v-model='cycle01' :min="0" :max="60" /> -
|
||||
<el-input-number v-model='cycle02' :min="0" :max="60" /> 秒
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="3">
|
||||
从
|
||||
<el-input-number v-model='average01' :min="0" :max="60" /> 秒开始,每
|
||||
<el-input-number v-model='average02' :min="0" :max="60" /> 秒执行一次
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="4">
|
||||
指定
|
||||
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
|
||||
<el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option>
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
radioValue: 1,
|
||||
cycle01: 1,
|
||||
cycle02: 2,
|
||||
average01: 0,
|
||||
average02: 1,
|
||||
checkboxList: [],
|
||||
checkNum: this.$options.propsData.check
|
||||
}
|
||||
},
|
||||
name: 'crontab-second',
|
||||
props: ['check', 'radioParent'],
|
||||
methods: {
|
||||
// 单选按钮值变化时
|
||||
radioChange() {
|
||||
switch (this.radioValue) {
|
||||
case 1:
|
||||
this.$emit('update', 'second', '*', 'second');
|
||||
this.$emit('update', 'min', '*', 'second');
|
||||
break;
|
||||
case 2:
|
||||
this.$emit('update', 'second', this.cycle01 + '-' + this.cycle02);
|
||||
break;
|
||||
case 3:
|
||||
this.$emit('update', 'second', this.average01 + '/' + this.average02);
|
||||
break;
|
||||
case 4:
|
||||
this.$emit('update', 'second', this.checkboxString);
|
||||
break;
|
||||
}
|
||||
},
|
||||
// 周期两个值变化时
|
||||
cycleChange() {
|
||||
if (this.radioValue == '2') {
|
||||
this.$emit('update', 'second', this.cycleTotal);
|
||||
}
|
||||
},
|
||||
// 平均两个值变化时
|
||||
averageChange() {
|
||||
if (this.radioValue == '3') {
|
||||
this.$emit('update', 'second', this.averageTotal);
|
||||
}
|
||||
},
|
||||
// checkbox值变化时
|
||||
checkboxChange() {
|
||||
if (this.radioValue == '4') {
|
||||
this.$emit('update', 'second', this.checkboxString);
|
||||
}
|
||||
},
|
||||
othChange() {
|
||||
//反解析
|
||||
let ins = this.cron.second
|
||||
('反解析 second', ins);
|
||||
if (ins === '*') {
|
||||
this.radioValue = 1;
|
||||
} else if (ins.indexOf('-') > -1) {
|
||||
this.radioValue = 2
|
||||
} else if (ins.indexOf('/') > -1) {
|
||||
this.radioValue = 3
|
||||
} else {
|
||||
this.radioValue = 4
|
||||
this.checkboxList = ins.split(',')
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
"radioValue": "radioChange",
|
||||
'cycleTotal': 'cycleChange',
|
||||
'averageTotal': 'averageChange',
|
||||
'checkboxString': 'checkboxChange',
|
||||
radioParent() {
|
||||
this.radioValue = this.radioParent
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 计算两个周期值
|
||||
cycleTotal: function () {
|
||||
this.cycle01 = this.checkNum(this.cycle01, 0, 59)
|
||||
this.cycle02 = this.checkNum(this.cycle02, 0, 59)
|
||||
return this.cycle01 + '-' + this.cycle02;
|
||||
},
|
||||
// 计算平均用到的值
|
||||
averageTotal: function () {
|
||||
this.average01 = this.checkNum(this.average01, 0, 59)
|
||||
this.average02 = this.checkNum(this.average02, 1, 59)
|
||||
return this.average01 + '/' + this.average02;
|
||||
},
|
||||
// 计算勾选的checkbox值合集
|
||||
checkboxString: function () {
|
||||
let str = this.checkboxList.join();
|
||||
return str == '' ? '*' : str;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -2,11 +2,15 @@
|
||||
<div>
|
||||
<el-tabs type="border-card">
|
||||
<el-tab-pane label="秒" v-if="shouldHide('second')">
|
||||
<CrontabSecond @update="updateContabValue" :check="checkNumber" ref="cronsecond" />
|
||||
<crontab-second
|
||||
@update="updateContabValue"
|
||||
:check="checkNumber"
|
||||
ref="cronsecond"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="分钟" v-if="shouldHide('min')">
|
||||
<CrontabMin
|
||||
<crontab-min
|
||||
@update="updateContabValue"
|
||||
:check="checkNumber"
|
||||
:cron="contabValueObj"
|
||||
@ -15,7 +19,7 @@
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="小时" v-if="shouldHide('hour')">
|
||||
<CrontabHour
|
||||
<crontab-hour
|
||||
@update="updateContabValue"
|
||||
:check="checkNumber"
|
||||
:cron="contabValueObj"
|
||||
@ -24,7 +28,7 @@
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="日" v-if="shouldHide('day')">
|
||||
<CrontabDay
|
||||
<crontab-day
|
||||
@update="updateContabValue"
|
||||
:check="checkNumber"
|
||||
:cron="contabValueObj"
|
||||
@ -33,7 +37,7 @@
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="月" v-if="shouldHide('mouth')">
|
||||
<CrontabMouth
|
||||
<crontab-mouth
|
||||
@update="updateContabValue"
|
||||
:check="checkNumber"
|
||||
:cron="contabValueObj"
|
||||
@ -42,7 +46,7 @@
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="周" v-if="shouldHide('week')">
|
||||
<CrontabWeek
|
||||
<crontab-week
|
||||
@update="updateContabValue"
|
||||
:check="checkNumber"
|
||||
:cron="contabValueObj"
|
||||
@ -51,17 +55,15 @@
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="年" v-if="shouldHide('year')">
|
||||
<CrontabYear
|
||||
@update="updateContabValue"
|
||||
:check="checkNumber"
|
||||
:cron="contabValueObj"
|
||||
ref="cronyear"
|
||||
/>
|
||||
<crontab-year @update="updateContabValue"
|
||||
:check="checkNumber"
|
||||
:cron="contabValueObj"
|
||||
ref="cronyear"/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<div class="popup-main">
|
||||
<div class="popup-result">
|
||||
<div class="popup-result-container">
|
||||
<p class="title">时间表达式</p>
|
||||
<table>
|
||||
<thead>
|
||||
@ -96,7 +98,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<CrontabResult :ex="contabValueString"></CrontabResult>
|
||||
<crontab-result :ex="contabValueString"/>
|
||||
|
||||
<div class="pop_btn">
|
||||
<el-button size="small" type="primary" @click="submitFill">确定</el-button>
|
||||
@ -108,16 +110,17 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CrontabSecond from "./Crontab-Second.vue";
|
||||
import CrontabMin from "./Crontab-Min.vue";
|
||||
import CrontabHour from "./Crontab-Hour.vue";
|
||||
import CrontabDay from "./Crontab-Day.vue";
|
||||
import CrontabMouth from "./Crontab-Mouth.vue";
|
||||
import CrontabWeek from "./Crontab-Week.vue";
|
||||
import CrontabYear from "./Crontab-Year.vue";
|
||||
import CrontabResult from "./Crontab-Result.vue";
|
||||
import CrontabSecond from "./CrontabSecond.vue";
|
||||
import CrontabMin from "./CrontabMin.vue";
|
||||
import CrontabHour from "./CrontabHour.vue";
|
||||
import CrontabDay from "./CrontabDay.vue";
|
||||
import CrontabMouth from "./CrontabMouth.vue";
|
||||
import CrontabWeek from "./CrontabWeek.vue";
|
||||
import CrontabYear from "./CrontabYear.vue";
|
||||
import CrontabResult from "./CrontabResult.vue";
|
||||
|
||||
export default {
|
||||
name: "Crontab",
|
||||
data() {
|
||||
return {
|
||||
tabTitles: ["秒", "分钟", "小时", "日", "月", "周", "年"],
|
||||
@ -134,7 +137,6 @@
|
||||
},
|
||||
};
|
||||
},
|
||||
name: "vcrontab",
|
||||
props: ["expression", "hideComponent"],
|
||||
methods: {
|
||||
shouldHide(key) {
|
||||
@ -382,7 +384,7 @@
|
||||
padding-top: 6px;
|
||||
background: #f2f2f2;
|
||||
}
|
||||
.popup-result {
|
||||
.popup-result-container {
|
||||
box-sizing: border-box;
|
||||
line-height: 24px;
|
||||
margin: 25px auto;
|
||||
@ -390,7 +392,7 @@
|
||||
border: 1px solid #ccc;
|
||||
position: relative;
|
||||
}
|
||||
.popup-result .title {
|
||||
.popup-result-container .title {
|
||||
position: absolute;
|
||||
top: -28px;
|
||||
left: 50%;
|
||||
@ -401,12 +403,12 @@
|
||||
line-height: 30px;
|
||||
background: #fff;
|
||||
}
|
||||
.popup-result table {
|
||||
.popup-result-container table {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.popup-result table span {
|
||||
.popup-result-container table span {
|
||||
display: block;
|
||||
width: 100%;
|
||||
font-family: arial;
|
||||
@ -416,10 +418,5 @@
|
||||
overflow: hidden;
|
||||
border: 1px solid #e8e8e8;
|
||||
}
|
||||
.popup-result-scroll {
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
height: 10em;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -66,7 +66,7 @@ export default {
|
||||
checkNum: this.$options.propsData.check
|
||||
}
|
||||
},
|
||||
name: 'crontab-day',
|
||||
name: 'CrontabDay',
|
||||
props: ['check', 'cron'],
|
||||
methods: {
|
||||
// 单选按钮值变化时
|
||||
@ -176,4 +176,4 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
@ -46,7 +46,7 @@ export default {
|
||||
checkNum: this.$options.propsData.check
|
||||
}
|
||||
},
|
||||
name: 'crontab-hour',
|
||||
name: 'CrontabHour',
|
||||
props: ['check', 'cron'],
|
||||
methods: {
|
||||
// 单选按钮值变化时
|
||||
@ -119,4 +119,4 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
@ -47,7 +47,7 @@ export default {
|
||||
checkNum: this.$options.propsData.check
|
||||
}
|
||||
},
|
||||
name: 'crontab-min',
|
||||
name: 'CrontabMin',
|
||||
props: ['check', 'cron'],
|
||||
methods: {
|
||||
// 单选按钮值变化时
|
||||
@ -117,4 +117,4 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
@ -46,7 +46,7 @@ export default {
|
||||
checkNum: this.check
|
||||
}
|
||||
},
|
||||
name: 'crontab-mouth',
|
||||
name: 'CrontabMouth',
|
||||
props: ['check', 'cron'],
|
||||
methods: {
|
||||
// 单选按钮值变化时
|
||||
@ -56,7 +56,7 @@ export default {
|
||||
this.$emit('update', 'year', '*');
|
||||
} else {
|
||||
if (this.cron.day === '*') {
|
||||
this.$emit('update', 'day', '0', 'mouth');
|
||||
this.$emit('update', 'day', '1', 'mouth');
|
||||
}
|
||||
if (this.cron.hour === '*') {
|
||||
this.$emit('update', 'hour', '0', 'mouth');
|
||||
@ -125,4 +125,4 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
@ -2,16 +2,16 @@
|
||||
<div class="popup-result">
|
||||
<p class="title">最近5次运行时间</p>
|
||||
<ul class="popup-result-scroll">
|
||||
<template v-if='isShow'>
|
||||
<template>
|
||||
<li v-for='item in resultList' :key="item">{{item}}</li>
|
||||
</template>
|
||||
<li v-else>计算结果中...</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'CrontabResult',
|
||||
data() {
|
||||
return {
|
||||
dayRule: '',
|
||||
@ -21,13 +21,23 @@ export default {
|
||||
isShow: false
|
||||
}
|
||||
},
|
||||
name: 'crontab-result',
|
||||
watch: {
|
||||
'ex': 'expressionChange'
|
||||
},
|
||||
props: ['ex'],
|
||||
mounted: function () {
|
||||
// 初始化 获取一次结果
|
||||
this.expressionChange();
|
||||
},
|
||||
methods: {
|
||||
// 表达式值变化时,开始去计算结果
|
||||
expressionChange() {
|
||||
|
||||
// 计算开始-隐藏结果
|
||||
this.isShow = false;
|
||||
if (!this.ex) {
|
||||
this.resultList = [];
|
||||
return;
|
||||
}
|
||||
// 获取规则数组[0秒、1分、2时、3日、4月、5星期、6年]
|
||||
let ruleArr = this.$options.propsData.ex.split(' ');
|
||||
// 用于记录进入循环的次数
|
||||
@ -552,15 +562,30 @@ export default {
|
||||
let format = this.formatDate(time)
|
||||
return value == format ? true : false;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'ex': 'expressionChange'
|
||||
},
|
||||
props: ['ex'],
|
||||
mounted: function () {
|
||||
// 初始化 获取一次结果
|
||||
this.expressionChange();
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
</script>
|
||||
<style>
|
||||
|
||||
.title {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.popup-result-scroll {
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
height: 10em;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.popup-result {
|
||||
box-sizing: border-box;
|
||||
line-height: 24px;
|
||||
margin: 25px auto;
|
||||
padding: 15px 10px 10px;
|
||||
border: 1px solid #ccc;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
</style>
|
133
frontend/src/business/components/common/cron/CrontabSecond.vue
Normal file
133
frontend/src/business/components/common/cron/CrontabSecond.vue
Normal file
@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<el-form size="small">
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="1">
|
||||
秒,允许的通配符[, - * /]
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="2">
|
||||
周期从
|
||||
<el-input-number v-model='cycle01' :min="0" :max="60" /> -
|
||||
<el-input-number v-model='cycle02' :min="0" :max="60" /> 秒
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="3">
|
||||
从
|
||||
<el-input-number v-model='average01' :min="0" :max="60" /> 秒开始,每
|
||||
<el-input-number v-model='average02' :min="0" :max="60" /> 秒执行一次
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="4">
|
||||
指定
|
||||
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
|
||||
<el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option>
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
radioValue: 1,
|
||||
cycle01: 1,
|
||||
cycle02: 2,
|
||||
average01: 0,
|
||||
average02: 1,
|
||||
checkboxList: [],
|
||||
checkNum: this.$options.propsData.check
|
||||
}
|
||||
},
|
||||
name: 'CrontabSecond',
|
||||
props: ['check', 'radioParent'],
|
||||
methods: {
|
||||
// 单选按钮值变化时
|
||||
radioChange() {
|
||||
switch (this.radioValue) {
|
||||
case 1:
|
||||
this.$emit('update', 'second', '*', 'second');
|
||||
this.$emit('update', 'min', '*', 'second');
|
||||
break;
|
||||
case 2:
|
||||
this.$emit('update', 'second', this.cycle01 + '-' + this.cycle02);
|
||||
break;
|
||||
case 3:
|
||||
this.$emit('update', 'second', this.average01 + '/' + this.average02);
|
||||
break;
|
||||
case 4:
|
||||
this.$emit('update', 'second', this.checkboxString);
|
||||
break;
|
||||
}
|
||||
},
|
||||
// 周期两个值变化时
|
||||
cycleChange() {
|
||||
if (this.radioValue == '2') {
|
||||
this.$emit('update', 'second', this.cycleTotal);
|
||||
}
|
||||
},
|
||||
// 平均两个值变化时
|
||||
averageChange() {
|
||||
if (this.radioValue == '3') {
|
||||
this.$emit('update', 'second', this.averageTotal);
|
||||
}
|
||||
},
|
||||
// checkbox值变化时
|
||||
checkboxChange() {
|
||||
if (this.radioValue == '4') {
|
||||
this.$emit('update', 'second', this.checkboxString);
|
||||
}
|
||||
},
|
||||
othChange() {
|
||||
//反解析
|
||||
let ins = this.cron.second
|
||||
// ('反解析 second', ins);
|
||||
if (ins === '*') {
|
||||
this.radioValue = 1;
|
||||
} else if (ins.indexOf('-') > -1) {
|
||||
this.radioValue = 2
|
||||
} else if (ins.indexOf('/') > -1) {
|
||||
this.radioValue = 3
|
||||
} else {
|
||||
this.radioValue = 4
|
||||
this.checkboxList = ins.split(',')
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
"radioValue": "radioChange",
|
||||
'cycleTotal': 'cycleChange',
|
||||
'averageTotal': 'averageChange',
|
||||
'checkboxString': 'checkboxChange',
|
||||
radioParent() {
|
||||
this.radioValue = this.radioParent
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 计算两个周期值
|
||||
cycleTotal: function () {
|
||||
this.cycle01 = this.checkNum(this.cycle01, 0, 59);
|
||||
this.cycle02 = this.checkNum(this.cycle02, 0, 59);
|
||||
return this.cycle01 + '-' + this.cycle02;
|
||||
},
|
||||
// 计算平均用到的值
|
||||
averageTotal: function () {
|
||||
this.average01 = this.checkNum(this.average01, 0, 59)
|
||||
this.average02 = this.checkNum(this.average02, 1, 59)
|
||||
return this.average01 + '/' + this.average02;
|
||||
},
|
||||
// 计算勾选的checkbox值合集
|
||||
checkboxString: function () {
|
||||
let str = this.checkboxList.join();
|
||||
return str == '' ? '*' : str;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -62,7 +62,7 @@ export default {
|
||||
checkNum: this.$options.propsData.check
|
||||
}
|
||||
},
|
||||
name: 'crontab-week',
|
||||
name: 'CrontabWeek',
|
||||
props: ['check', 'cron'],
|
||||
methods: {
|
||||
// 单选按钮值变化时
|
||||
@ -72,10 +72,10 @@ export default {
|
||||
this.$emit('update', 'year', '*');
|
||||
} else {
|
||||
if (this.cron.mouth === '*') {
|
||||
this.$emit('update', 'mouth', '0', 'week');
|
||||
this.$emit('update', 'mouth', '1', 'week');
|
||||
}
|
||||
if (this.cron.day === '*') {
|
||||
this.$emit('update', 'day', '0', 'week');
|
||||
this.$emit('update', 'day', '1', 'week');
|
||||
}
|
||||
if (this.cron.hour === '*') {
|
||||
this.$emit('update', 'hour', '0', 'week');
|
||||
@ -160,8 +160,8 @@ export default {
|
||||
// 计算勾选的checkbox值合集
|
||||
checkboxString: function () {
|
||||
let str = this.checkboxList.join();
|
||||
return str == '' ? '*' : str;
|
||||
return str == '' ? '?' : str;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
@ -54,16 +54,16 @@ export default {
|
||||
checkNum: this.$options.propsData.check
|
||||
}
|
||||
},
|
||||
name: 'crontab-year',
|
||||
name: 'CrontabYear',
|
||||
props: ['check', 'mouth', 'cron'],
|
||||
methods: {
|
||||
// 单选按钮值变化时
|
||||
radioChange() {
|
||||
if (this.cron.mouth === '*') {
|
||||
this.$emit('update', 'mouth', '0', 'year');
|
||||
this.$emit('update', 'mouth', '1', 'year');
|
||||
}
|
||||
if (this.cron.day === '*') {
|
||||
this.$emit('update', 'day', '0', 'year');
|
||||
this.$emit('update', 'day', '1', 'year');
|
||||
}
|
||||
if (this.cron.hour === '*') {
|
||||
this.$emit('update', 'hour', '0', 'year');
|
||||
@ -141,4 +141,4 @@ export default {
|
||||
this.fullYear = Number(new Date().getFullYear());
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
334
frontend/src/common/js/cron.js
Normal file
334
frontend/src/common/js/cron.js
Normal file
@ -0,0 +1,334 @@
|
||||
/**
|
||||
* Validates a cron expression.
|
||||
*
|
||||
* @param cronExpression The expression to validate
|
||||
* @return True is expression is valid
|
||||
*/
|
||||
export function cronValidate(cronExpression ){
|
||||
//alert("校验函数的开始!");
|
||||
var cronParams = cronExpression.split(" ");
|
||||
|
||||
if (cronParams.length < 6 || cronParams.length > 7) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//CronTrigger cronTrigger = new CronTrigger();
|
||||
//cronTrigger.setCronExpression( cronExpression );
|
||||
|
||||
if (cronParams[3] == "?" || cronParams[5]=="?") {
|
||||
//Check seconds param
|
||||
if (!checkSecondsField(cronParams[0])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Check minutes param
|
||||
if (!checkMinutesField(cronParams[1])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Check hours param
|
||||
if (!checkHoursField(cronParams[2])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Check day-of-month param
|
||||
if (!checkDayOfMonthField(cronParams[3])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Check months param
|
||||
if (!checkMonthsField(cronParams[4])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Check day-of-week param
|
||||
if (!checkDayOfWeekField(cronParams[5])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Check year param
|
||||
if (cronParams.length == 7) {
|
||||
if (!checkYearField(cronParams[6])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function checkSecondsField(secondsField) {
|
||||
return checkField(secondsField, 0, 59);
|
||||
}
|
||||
|
||||
|
||||
function checkField(secondsField, minimal, maximal) {
|
||||
if (secondsField.indexOf("-") > -1 ) {
|
||||
var startValue = secondsField.substring(0, secondsField.indexOf( "-" ));
|
||||
var endValue = secondsField.substring(secondsField.indexOf( "-" ) + 1);
|
||||
|
||||
if (!(checkIntValue(startValue, minimal, maximal, true) && checkIntValue(endValue, minimal, maximal, true))) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
var startVal = parseInt(startValue, 10);
|
||||
var endVal = parseInt(endValue, 10);
|
||||
|
||||
return endVal > startVal;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
} else if (secondsField.indexOf(",") > -1) {
|
||||
return checkListField(secondsField, minimal, maximal);
|
||||
} else if (secondsField.indexOf( "/" ) > -1) {
|
||||
return checkIncrementField( secondsField, minimal, maximal );
|
||||
} else if (secondsField.indexOf( "*" ) != -1) {
|
||||
return true;
|
||||
} else {
|
||||
return checkIntValue(secondsField, minimal, maximal);
|
||||
}
|
||||
}
|
||||
|
||||
function checkIntValue(value, minimal, maximal, checkExtremity) {
|
||||
try {
|
||||
var val = parseInt(value, 10);
|
||||
//判断是否为整数
|
||||
if (value == val) {
|
||||
if (checkExtremity) {
|
||||
if (val < minimal || val > maximal) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function checkMinutesField(minutesField) {
|
||||
return checkField(minutesField, 0, 59);
|
||||
}
|
||||
|
||||
function checkHoursField(hoursField) {
|
||||
return checkField(hoursField, 0, 23);
|
||||
}
|
||||
|
||||
function checkDayOfMonthField(dayOfMonthField) {
|
||||
if (dayOfMonthField == "?") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (dayOfMonthField.indexOf("L") >= 0) {
|
||||
return checkFieldWithLetter(dayOfMonthField, "L", 1, 7, -1, -1);
|
||||
} else if ( dayOfMonthField.indexOf("W") >= 0) {
|
||||
return checkFieldWithLetter(dayOfMonthField, "W", 1, 31, -1, -1);
|
||||
} else if (dayOfMonthField.indexOf("C") >= 0) {
|
||||
return checkFieldWithLetter(dayOfMonthField, "C", 1, 31, -1, -1);
|
||||
} else {
|
||||
return checkField( dayOfMonthField, 1, 31 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function checkMonthsField(monthsField) {
|
||||
/* monthsField = StringUtils.replace( monthsField, "JAN", "1" );
|
||||
monthsField = StringUtils.replace( monthsField, "FEB", "2" );
|
||||
monthsField = StringUtils.replace( monthsField, "MAR", "3" );
|
||||
monthsField = StringUtils.replace( monthsField, "APR", "4" );
|
||||
monthsField = StringUtils.replace( monthsField, "MAY", "5" );
|
||||
monthsField = StringUtils.replace( monthsField, "JUN", "6" );
|
||||
monthsField = StringUtils.replace( monthsField, "JUL", "7" );
|
||||
monthsField = StringUtils.replace( monthsField, "AUG", "8" );
|
||||
monthsField = StringUtils.replace( monthsField, "SEP", "9" );
|
||||
monthsField = StringUtils.replace( monthsField, "OCT", "10" );
|
||||
monthsField = StringUtils.replace( monthsField, "NOV", "11" );
|
||||
monthsField = StringUtils.replace( monthsField, "DEC", "12" );*/
|
||||
|
||||
monthsField.replace("JAN", "1");
|
||||
monthsField.replace("FEB", "2");
|
||||
monthsField.replace("MAR", "3");
|
||||
monthsField.replace("APR", "4");
|
||||
monthsField.replace("MAY", "5");
|
||||
monthsField.replace("JUN", "6");
|
||||
monthsField.replace("JUL", "7");
|
||||
monthsField.replace("AUG", "8");
|
||||
monthsField.replace("SEP", "9");
|
||||
monthsField.replace("OCT", "10");
|
||||
monthsField.replace("NOV", "11");
|
||||
monthsField.replace("DEC", "12");
|
||||
|
||||
return checkField(monthsField, 1, 31);
|
||||
}
|
||||
|
||||
function checkDayOfWeekField(dayOfWeekField) {
|
||||
/* dayOfWeekField = StringUtils.replace( dayOfWeekField, "SUN", "1" );
|
||||
dayOfWeekField = StringUtils.replace( dayOfWeekField, "MON", "2" );
|
||||
dayOfWeekField = StringUtils.replace( dayOfWeekField, "TUE", "3" );
|
||||
dayOfWeekField = StringUtils.replace( dayOfWeekField, "WED", "4" );
|
||||
dayOfWeekField = StringUtils.replace( dayOfWeekField, "THU", "5" );
|
||||
dayOfWeekField = StringUtils.replace( dayOfWeekField, "FRI", "6" );
|
||||
dayOfWeekField = StringUtils.replace( dayOfWeekField, "SAT", "7" );*/
|
||||
|
||||
dayOfWeekField.replace("SUN", "1" );
|
||||
dayOfWeekField.replace("MON", "2" );
|
||||
dayOfWeekField.replace("TUE", "3" );
|
||||
dayOfWeekField.replace("WED", "4" );
|
||||
dayOfWeekField.replace("THU", "5" );
|
||||
dayOfWeekField.replace("FRI", "6" );
|
||||
dayOfWeekField.replace("SAT", "7" );
|
||||
|
||||
if (dayOfWeekField == "?") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (dayOfWeekField.indexOf("L") >= 0) {
|
||||
return checkFieldWithLetter(dayOfWeekField, "L", 1, 7, -1, -1);
|
||||
} else if (dayOfWeekField.indexOf("C") >= 0) {
|
||||
return checkFieldWithLetter(dayOfWeekField, "C", 1, 7, -1, -1);
|
||||
} else if (dayOfWeekField.indexOf("#") >= 0) {
|
||||
return checkFieldWithLetter(dayOfWeekField, "#", 1, 7, 1, 5);
|
||||
} else {
|
||||
return checkField(dayOfWeekField, 1, 7);
|
||||
}
|
||||
}
|
||||
|
||||
function checkYearField(yearField) {
|
||||
return checkField(yearField, 1970, 2099);
|
||||
}
|
||||
|
||||
|
||||
function checkFieldWithLetter(value, letter, minimalBefore, maximalBefore,
|
||||
minimalAfter, maximalAfter) {
|
||||
var canBeAlone = false;
|
||||
var canHaveIntBefore = false;
|
||||
var canHaveIntAfter = false;
|
||||
var mustHaveIntBefore = false;
|
||||
var mustHaveIntAfter = false;
|
||||
|
||||
if (letter == "L") {
|
||||
canBeAlone = true;
|
||||
canHaveIntBefore = true;
|
||||
canHaveIntAfter = false;
|
||||
mustHaveIntBefore = false;
|
||||
mustHaveIntAfter = false;
|
||||
}
|
||||
if (letter == "W" || letter == "C") {
|
||||
canBeAlone = false;
|
||||
canHaveIntBefore = true;
|
||||
canHaveIntAfter = false;
|
||||
mustHaveIntBefore = true;
|
||||
mustHaveIntAfter = false;
|
||||
}
|
||||
if (letter == "#") {
|
||||
canBeAlone = false;
|
||||
canHaveIntBefore = true;
|
||||
canHaveIntAfter = true;
|
||||
mustHaveIntBefore = true;
|
||||
mustHaveIntAfter = true;
|
||||
}
|
||||
|
||||
var beforeLetter = "";
|
||||
var afterLetter = "";
|
||||
|
||||
if (value.indexOf(letter) >= 0 ) {
|
||||
beforeLetter = value.substring( 0, value.indexOf(letter));
|
||||
}
|
||||
|
||||
if (!value.endsWith(letter)) {
|
||||
afterLetter = value.substring( value.indexOf( letter ) + 1 );
|
||||
}
|
||||
|
||||
if (value.indexOf(letter) >= 0) {
|
||||
if (letter == value) {
|
||||
return canBeAlone;
|
||||
}
|
||||
|
||||
if (canHaveIntBefore) {
|
||||
if (mustHaveIntBefore && beforeLetter.length == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!checkIntValue(beforeLetter, minimalBefore, maximalBefore, true)){
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (beforeLetter.length > 0 ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (canHaveIntAfter) {
|
||||
if ( mustHaveIntAfter && afterLetter.length == 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!checkIntValue(afterLetter, minimalAfter, maximalAfter, true)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (afterLetter.length > 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* function checkIntValue(value, minimal, maximal) {
|
||||
return checkIntValue(value, minimal, maximal, true);
|
||||
} */
|
||||
|
||||
function checkIncrementField(value, minimal, maximal) {
|
||||
var start = value.substring(0, value.indexOf("/"));
|
||||
|
||||
var increment = value.substring(value.indexOf("/") + 1);
|
||||
|
||||
if (!("*" == start)) {
|
||||
return checkIntValue(start, minimal, maximal, true) && checkIntValue(increment, minimal, maximal, false);
|
||||
} else {
|
||||
return checkIntValue(increment, minimal, maximal, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function checkListField(value, minimal, maximal ) {
|
||||
var st = value.split(",");
|
||||
|
||||
var values = new Array(st.length);
|
||||
|
||||
for(var j = 0; j < st.length; j++) {
|
||||
values[j] = st[j];
|
||||
}
|
||||
|
||||
var previousValue = -1;
|
||||
|
||||
for (var i= 0; i < values.length; i++) {
|
||||
var currentValue = values[i];
|
||||
|
||||
if (!checkIntValue(currentValue, minimal, maximal, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
var val = parseInt(currentValue, 10);
|
||||
|
||||
if (val <= previousValue) {
|
||||
return false;
|
||||
} else {
|
||||
previousValue = val;
|
||||
}
|
||||
} catch (e) {
|
||||
// we have always an int
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
Loading…
Reference in New Issue
Block a user