diff --git a/test-ui/src/views/test/performance/performanceAdd.vue b/test-ui/src/views/test/performance/performanceAdd.vue index 7c3687e..dc1a143 100644 --- a/test-ui/src/views/test/performance/performanceAdd.vue +++ b/test-ui/src/views/test/performance/performanceAdd.vue @@ -210,6 +210,29 @@ export default { handleWithSave() { this.validationForm() if (this.validation === false) { return } + + // 如果开启了定时任务,验证 crontab 表达式 + if (this.addForm.crontabStatus === 1) { + const crontab = this.addForm.crontab.trim(); + if (!crontab) { + this.$message({ message: '请输入 Crontab 表达式', type: 'warning' }) + return + } + + // 验证 crontab 表达式格式 + if (!this.validateCrontab(crontab)) { + this.$message.error('无效的 crontab 表达式格式,请输入正确的 crontab 表达式'); + return; + } + + try { + parser.parseExpression(crontab); + } catch (error) { + this.$message.error('无效的 crontab 表达式,请修正后再保存'); + return; + } + } + this.changeList.forEach(item => { var par = { testCaseId: item.id, @@ -300,6 +323,51 @@ export default { this.dialogVisibleTime = false this.addForm.crontabStatus = false }, + // 添加 crontab 表达式验证函数 + validateCrontab(crontab) { + // crontab 表达式必须包含 5 个或 6 个空格分隔的字段 + const fields = crontab.trim().split(/\s+/); + if (fields.length < 5 || fields.length > 6) { + return false; + } + + // 验证每个字段的格式 + const patterns = { + seconds: /^(\*|([0-9]|[1-5][0-9])(,[0-9]|[1-5][0-9])*|\*\/[1-9][0-9]?|[0-9]|[1-5][0-9]\/[1-9][0-9]?)$/, + minutes: /^(\*|([0-9]|[1-5][0-9])(,[0-9]|[1-5][0-9])*|\*\/[1-9][0-9]?|[0-9]|[1-5][0-9]\/[1-9][0-9]?)$/, + hours: /^(\*|([0-9]|1[0-9]|2[0-3])(,[0-9]|1[0-9]|2[0-3])*|\*\/[1-9][0-9]?|[0-9]|1[0-9]|2[0-3]\/[1-9][0-9]?)$/, + dayOfMonth: /^(\*|([1-9]|[12][0-9]|3[01])(,[1-9]|[12][0-9]|3[01])*|\*\/[1-9][0-9]?|[1-9]|[12][0-9]|3[01]\/[1-9][0-9]?|\?|L|W|LW|1W|2W|3W|4W|5W|6W|7W|8W|9W|10W|11W|12W|13W|14W|15W|16W|17W|18W|19W|20W|21W|22W|23W|24W|25W|26W|27W|28W|29W|30W|31W)$/, + month: /^(\*|([1-9]|1[0-2])(,[1-9]|1[0-2])*|\*\/[1-9][0-9]?|[1-9]|1[0-2]\/[1-9][0-9]?|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)$/, + dayOfWeek: /^(\*|([0-6]|SUN|MON|TUE|WED|THU|FRI|SAT)(,[0-6]|SUN|MON|TUE|WED|THU|FRI|SAT)*|\*\/[1-9][0-9]?|[0-6]\/[1-9][0-9]?|\?|L|6L|5L|4L|3L|2L|1L|1#1|1#2|1#3|1#4|1#5|2#1|2#2|2#3|2#4|2#5|3#1|3#2|3#3|3#4|3#5|4#1|4#2|4#3|4#4|4#5|5#1|5#2|5#3|5#4|5#5|6#1|6#2|6#3|6#4|6#5|7#1|7#2|7#3|7#4|7#5)$/ + }; + + // 根据字段数量确定验证顺序 + const validationOrder = fields.length === 6 + ? ['seconds', 'minutes', 'hours', 'dayOfMonth', 'month', 'dayOfWeek'] + : ['minutes', 'hours', 'dayOfMonth', 'month', 'dayOfWeek']; + + // 验证每个字段 + const isValid = fields.every((field, index) => { + const pattern = patterns[validationOrder[index]]; + return pattern && pattern.test(field); + }); + + if (!isValid) { + return false; + } + + // 检查 dayOfMonth 和 dayOfWeek 不能同时为具体值 + const dayOfMonthIndex = fields.length === 6 ? 3 : 2; + const dayOfWeekIndex = fields.length === 6 ? 5 : 4; + const dayOfMonth = fields[dayOfMonthIndex]; + const dayOfWeek = fields[dayOfWeekIndex]; + + if (dayOfMonth !== '*' && dayOfWeek !== '*' && dayOfMonth !== '?' && dayOfWeek !== '?') { + return false; + } + + return true; + }, // 更新执行时间列表 updateExecutionTimes() { const crontab = this.addForm.crontab.trim(); @@ -309,6 +377,14 @@ export default { return; } + // 首先验证 crontab 表达式格式 + if (!this.validateCrontab(crontab)) { + this.$message.error('无效的 crontab 表达式格式'); + this.executionTimeList = []; + this.nextExecutionTime = ''; + return; + } + try { // 解析crontab表达式 const interval = parser.parseExpression(crontab); @@ -325,7 +401,7 @@ export default { this.executionTimeList = times; this.nextExecutionTime = times[0].time; // 设置下次执行时间 } catch (error) { - this.$message.error('无效的crontab表达式'); + this.$message.error('无效的 crontab 表达式'); this.executionTimeList = []; this.nextExecutionTime = ''; } @@ -342,17 +418,24 @@ export default { }, // 修改确定按钮的处理函数 handleDialogConfirm() { - if (!this.addForm.crontab.trim()) { - this.$message.warning('请输入Crontab表达式'); + const crontab = this.addForm.crontab.trim(); + if (!crontab) { + this.$message.warning('请输入 Crontab 表达式'); + return; + } + + // 首先验证 crontab 表达式格式 + if (!this.validateCrontab(crontab)) { + this.$message.error('无效的 crontab 表达式格式,请输入正确的 crontab 表达式'); return; } try { - parser.parseExpression(this.addForm.crontab.trim()); + parser.parseExpression(crontab); this.updateExecutionTimes(); this.dialogVisibleTime = false; } catch (error) { - this.$message.error('无效的crontab表达式,请修正后再确定'); + this.$message.error('无效的 crontab 表达式,请修正后再确定'); return; } }, diff --git a/test-ui/src/views/test/performance/performanceEdit.vue b/test-ui/src/views/test/performance/performanceEdit.vue index 51bd6c3..1b7054e 100644 --- a/test-ui/src/views/test/performance/performanceEdit.vue +++ b/test-ui/src/views/test/performance/performanceEdit.vue @@ -233,6 +233,29 @@ export default { handleWithSave() { this.validationForm() if (this.validation === false) { return } + + // 如果开启了定时任务,验证 crontab 表达式 + if (this.addForm.crontabStatus === 1) { + const crontab = this.addForm.crontab.trim(); + if (!crontab) { + this.$message({ message: '请输入 Crontab 表达式', type: 'warning' }) + return + } + + // 验证 crontab 表达式格式 + if (!this.validateCrontab(crontab)) { + this.$message.error('无效的 crontab 表达式格式,请输入正确的 crontab 表达式'); + return; + } + + try { + parser.parseExpression(crontab); + } catch (error) { + this.$message.error('无效的 crontab 表达式,请修正后再保存'); + return; + } + } + this.addForm.performanceTestCaseVOList = this.changeList editTest(this.addForm).then(res => { if (res.code === 200) { @@ -365,6 +388,51 @@ export default { this.dialogVisibleTime = false this.addForm.crontabStatus = 0 }, + // 添加 crontab 表达式验证函数 + validateCrontab(crontab) { + // crontab 表达式必须包含 5 个或 6 个空格分隔的字段 + const fields = crontab.trim().split(/\s+/); + if (fields.length < 5 || fields.length > 6) { + return false; + } + + // 验证每个字段的格式 + const patterns = { + seconds: /^(\*|([0-9]|[1-5][0-9])(,[0-9]|[1-5][0-9])*|\*\/[1-9][0-9]?|[0-9]|[1-5][0-9]\/[1-9][0-9]?)$/, + minutes: /^(\*|([0-9]|[1-5][0-9])(,[0-9]|[1-5][0-9])*|\*\/[1-9][0-9]?|[0-9]|[1-5][0-9]\/[1-9][0-9]?)$/, + hours: /^(\*|([0-9]|1[0-9]|2[0-3])(,[0-9]|1[0-9]|2[0-3])*|\*\/[1-9][0-9]?|[0-9]|1[0-9]|2[0-3]\/[1-9][0-9]?)$/, + dayOfMonth: /^(\*|([1-9]|[12][0-9]|3[01])(,[1-9]|[12][0-9]|3[01])*|\*\/[1-9][0-9]?|[1-9]|[12][0-9]|3[01]\/[1-9][0-9]?|\?|L|W|LW|1W|2W|3W|4W|5W|6W|7W|8W|9W|10W|11W|12W|13W|14W|15W|16W|17W|18W|19W|20W|21W|22W|23W|24W|25W|26W|27W|28W|29W|30W|31W)$/, + month: /^(\*|([1-9]|1[0-2])(,[1-9]|1[0-2])*|\*\/[1-9][0-9]?|[1-9]|1[0-2]\/[1-9][0-9]?|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)$/, + dayOfWeek: /^(\*|([0-6]|SUN|MON|TUE|WED|THU|FRI|SAT)(,[0-6]|SUN|MON|TUE|WED|THU|FRI|SAT)*|\*\/[1-9][0-9]?|[0-6]\/[1-9][0-9]?|\?|L|6L|5L|4L|3L|2L|1L|1#1|1#2|1#3|1#4|1#5|2#1|2#2|2#3|2#4|2#5|3#1|3#2|3#3|3#4|3#5|4#1|4#2|4#3|4#4|4#5|5#1|5#2|5#3|5#4|5#5|6#1|6#2|6#3|6#4|6#5|7#1|7#2|7#3|7#4|7#5)$/ + }; + + // 根据字段数量确定验证顺序 + const validationOrder = fields.length === 6 + ? ['seconds', 'minutes', 'hours', 'dayOfMonth', 'month', 'dayOfWeek'] + : ['minutes', 'hours', 'dayOfMonth', 'month', 'dayOfWeek']; + + // 验证每个字段 + const isValid = fields.every((field, index) => { + const pattern = patterns[validationOrder[index]]; + return pattern && pattern.test(field); + }); + + if (!isValid) { + return false; + } + + // 检查 dayOfMonth 和 dayOfWeek 不能同时为具体值 + const dayOfMonthIndex = fields.length === 6 ? 3 : 2; + const dayOfWeekIndex = fields.length === 6 ? 5 : 4; + const dayOfMonth = fields[dayOfMonthIndex]; + const dayOfWeek = fields[dayOfWeekIndex]; + + if (dayOfMonth !== '*' && dayOfWeek !== '*' && dayOfMonth !== '?' && dayOfWeek !== '?') { + return false; + } + + return true; + }, // 更新执行时间列表 updateExecutionTimes() { const crontab = this.addForm.crontab.trim(); @@ -374,6 +442,14 @@ export default { return; } + // 首先验证 crontab 表达式格式 + if (!this.validateCrontab(crontab)) { + this.$message.error('无效的 crontab 表达式格式'); + this.executionTimeList = []; + this.nextExecutionTime = ''; + return; + } + try { // 解析crontab表达式 const interval = parser.parseExpression(crontab); @@ -390,7 +466,7 @@ export default { this.executionTimeList = times; this.nextExecutionTime = times[0].time; // 设置下次执行时间 } catch (error) { - this.$message.error('无效的crontab表达式'); + this.$message.error('无效的 crontab 表达式'); this.executionTimeList = []; this.nextExecutionTime = ''; } @@ -407,17 +483,24 @@ export default { }, // 修改确定按钮的处理函数 handleDialogConfirm() { - if (!this.addForm.crontab.trim()) { - this.$message.warning('请输入Crontab表达式'); + const crontab = this.addForm.crontab.trim(); + if (!crontab) { + this.$message.warning('请输入 Crontab 表达式'); + return; + } + + // 首先验证 crontab 表达式格式 + if (!this.validateCrontab(crontab)) { + this.$message.error('无效的 crontab 表达式格式,请输入正确的 crontab 表达式'); return; } try { - parser.parseExpression(this.addForm.crontab.trim()); + parser.parseExpression(crontab); this.updateExecutionTimes(); this.dialogVisibleTime = false; } catch (error) { - this.$message.error('无效的crontab表达式,请修正后再确定'); + this.$message.error('无效的 crontab 表达式,请修正后再确定'); return; } },