fix(接口自动化): 循环控制器死循环问题修复
This commit is contained in:
parent
e2356c1849
commit
387c685455
|
@ -11,12 +11,11 @@ import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.jmeter.control.ForeachController;
|
import org.apache.jmeter.control.*;
|
||||||
import org.apache.jmeter.control.GenericController;
|
import org.apache.jmeter.reporters.ResultAction;
|
||||||
import org.apache.jmeter.control.LoopController;
|
|
||||||
import org.apache.jmeter.control.WhileController;
|
|
||||||
import org.apache.jmeter.save.SaveService;
|
import org.apache.jmeter.save.SaveService;
|
||||||
import org.apache.jmeter.testelement.TestElement;
|
import org.apache.jmeter.testelement.TestElement;
|
||||||
|
import org.apache.jmeter.timers.ConstantTimer;
|
||||||
import org.apache.jorphan.collections.HashTree;
|
import org.apache.jorphan.collections.HashTree;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -43,11 +42,21 @@ public class MsLoopController extends MsTestElement {
|
||||||
if (!this.isEnable()) {
|
if (!this.isEnable()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GenericController controller = controller();
|
final HashTree groupTree = controller(tree);
|
||||||
if (controller == null) {
|
|
||||||
return;
|
// 不打开执行成功后轮询功能,则成功后就停止循环
|
||||||
|
if (StringUtils.equals(this.loopType, "LOOP_COUNT") && this.countController != null && !countController.isProceed()) {
|
||||||
|
ResultAction resultAction = new ResultAction();
|
||||||
|
resultAction.setName("ResultAction");
|
||||||
|
resultAction.setProperty("OnError.action", "1000");
|
||||||
|
groupTree.add(resultAction);
|
||||||
}
|
}
|
||||||
final HashTree groupTree = tree.add(controller);
|
// 循环间隔时长设置
|
||||||
|
ConstantTimer cnstantTimer = getCnstantTimer();
|
||||||
|
if (cnstantTimer != null) {
|
||||||
|
groupTree.add(cnstantTimer);
|
||||||
|
}
|
||||||
|
|
||||||
if (CollectionUtils.isNotEmpty(hashTree)) {
|
if (CollectionUtils.isNotEmpty(hashTree)) {
|
||||||
hashTree.forEach(el -> {
|
hashTree.forEach(el -> {
|
||||||
el.toHashTree(groupTree, el.getHashTree(), config);
|
el.toHashTree(groupTree, el.getHashTree(), config);
|
||||||
|
@ -58,14 +67,11 @@ public class MsLoopController extends MsTestElement {
|
||||||
private LoopController loopController() {
|
private LoopController loopController() {
|
||||||
LoopController loopController = new LoopController();
|
LoopController loopController = new LoopController();
|
||||||
loopController.setEnabled(true);
|
loopController.setEnabled(true);
|
||||||
loopController.setName(this.getLabel());
|
loopController.setName("LoopController");
|
||||||
loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
|
loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
|
||||||
loopController.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("LoopControlPanel"));
|
loopController.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("LoopControlPanel"));
|
||||||
loopController.setLoops(countController.getLoops());
|
loopController.setLoops(countController.getLoops());
|
||||||
// 不打开执行成功后轮询功能,则成功后就停止循环
|
loopController.setContinueForever(false);
|
||||||
if (!countController.isProceed()) {
|
|
||||||
|
|
||||||
}
|
|
||||||
return loopController;
|
return loopController;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,19 +99,23 @@ public class MsLoopController extends MsTestElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
private WhileController whileController() {
|
private WhileController whileController() {
|
||||||
|
String condition = getCondition();
|
||||||
|
if (StringUtils.isEmpty(condition)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
WhileController controller = new WhileController();
|
WhileController controller = new WhileController();
|
||||||
controller.setEnabled(true);
|
controller.setEnabled(true);
|
||||||
controller.setName(this.getLabel());
|
controller.setName("WhileController");
|
||||||
controller.setProperty(TestElement.TEST_CLASS, WhileController.class.getName());
|
controller.setProperty(TestElement.TEST_CLASS, WhileController.class.getName());
|
||||||
controller.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("WhileControllerGui"));
|
controller.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("WhileControllerGui"));
|
||||||
controller.setCondition(getCondition());
|
controller.setCondition(condition);
|
||||||
return controller;
|
return controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ForeachController foreachController() {
|
private ForeachController foreachController() {
|
||||||
ForeachController controller = new ForeachController();
|
ForeachController controller = new ForeachController();
|
||||||
controller.setEnabled(true);
|
controller.setEnabled(true);
|
||||||
controller.setName(this.getLabel());
|
controller.setName("ForeachController");
|
||||||
controller.setProperty(TestElement.TEST_CLASS, ForeachController.class.getName());
|
controller.setProperty(TestElement.TEST_CLASS, ForeachController.class.getName());
|
||||||
controller.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("ForeachControlPanel"));
|
controller.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("ForeachControlPanel"));
|
||||||
controller.setInputVal(this.forEachController.getInputVal());
|
controller.setInputVal(this.forEachController.getInputVal());
|
||||||
|
@ -114,15 +124,49 @@ public class MsLoopController extends MsTestElement {
|
||||||
return controller;
|
return controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
private GenericController controller() {
|
private HashTree controller(HashTree tree) {
|
||||||
if (StringUtils.equals(this.loopType, "WHILE") && this.whileController != null) {
|
if (StringUtils.equals(this.loopType, "WHILE") && this.whileController != null) {
|
||||||
return whileController();
|
RunTime runTime = new RunTime();
|
||||||
|
runTime.setEnabled(true);
|
||||||
|
runTime.setProperty(TestElement.TEST_CLASS, RunTime.class.getName());
|
||||||
|
runTime.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("RunTimeGui"));
|
||||||
|
long timeout = this.whileController.getTimeout() / 1000;
|
||||||
|
if (timeout < 1) {
|
||||||
|
timeout = 1;
|
||||||
|
}
|
||||||
|
runTime.setRuntime(timeout);
|
||||||
|
// 添加超时处理,防止死循环
|
||||||
|
HashTree hashTree = tree.add(runTime);
|
||||||
|
return hashTree.add(whileController());
|
||||||
}
|
}
|
||||||
if (StringUtils.equals(this.loopType, "FOREACH") && this.forEachController != null) {
|
if (StringUtils.equals(this.loopType, "FOREACH") && this.forEachController != null) {
|
||||||
return foreachController();
|
return tree.add(foreachController());
|
||||||
}
|
}
|
||||||
if (StringUtils.equals(this.loopType, "LOOP_COUNT") && this.countController != null) {
|
if (StringUtils.equals(this.loopType, "LOOP_COUNT") && this.countController != null) {
|
||||||
return loopController();
|
return tree.add(loopController());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConstantTimer getCnstantTimer() {
|
||||||
|
ConstantTimer constantTimer = new ConstantTimer();
|
||||||
|
constantTimer.setEnabled(true);
|
||||||
|
constantTimer.setProperty(TestElement.TEST_CLASS, ConstantTimer.class.getName());
|
||||||
|
constantTimer.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("ConstantTimerGui"));
|
||||||
|
if (StringUtils.equals(this.loopType, "WHILE") && this.whileController != null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (StringUtils.equals(this.loopType, "FOREACH") && this.forEachController != null) {
|
||||||
|
constantTimer.setProperty("ConstantTimer.delay", this.forEachController.getInterval());
|
||||||
|
constantTimer.setDelay(this.forEachController.getInterval());
|
||||||
|
constantTimer.setName(this.forEachController.getInterval() + " ms");
|
||||||
|
return constantTimer;
|
||||||
|
}
|
||||||
|
if (StringUtils.equals(this.loopType, "LOOP_COUNT") && this.countController != null) {
|
||||||
|
constantTimer.setProperty("ConstantTimer.delay", this.countController.getInterval() + "");
|
||||||
|
constantTimer.setDelay(this.countController.getInterval() + "");
|
||||||
|
constantTimer.setName(this.countController.getInterval() + " ms");
|
||||||
|
return constantTimer;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,9 @@ public class MsJSR223Processor extends MsTestElement {
|
||||||
} else {
|
} else {
|
||||||
processor.setName("JSR223Processor");
|
processor.setName("JSR223Processor");
|
||||||
}
|
}
|
||||||
|
if (config != null && StringUtils.isNotEmpty(config.getStep())) {
|
||||||
|
processor.setName(this.getName() + "<->" + config.getStep());
|
||||||
|
}
|
||||||
processor.setProperty(TestElement.TEST_CLASS, JSR223Sampler.class.getName());
|
processor.setProperty(TestElement.TEST_CLASS, JSR223Sampler.class.getName());
|
||||||
processor.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TestBeanGUI"));
|
processor.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TestBeanGUI"));
|
||||||
processor.setProperty("cacheKey", "true");
|
processor.setProperty("cacheKey", "true");
|
||||||
|
|
|
@ -24,6 +24,7 @@ import io.metersphere.commons.utils.ServiceUtils;
|
||||||
import io.metersphere.commons.utils.SessionUtils;
|
import io.metersphere.commons.utils.SessionUtils;
|
||||||
import io.metersphere.i18n.Translator;
|
import io.metersphere.i18n.Translator;
|
||||||
import io.metersphere.track.service.TestPlanReportService;
|
import io.metersphere.track.service.TestPlanReportService;
|
||||||
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
@ -211,13 +212,19 @@ public class ApiScenarioReportService {
|
||||||
}
|
}
|
||||||
|
|
||||||
TestPlanReportService testPlanReportService = CommonBeanFactory.getBean(TestPlanReportService.class);
|
TestPlanReportService testPlanReportService = CommonBeanFactory.getBean(TestPlanReportService.class);
|
||||||
testPlanReportService.updateReport(testPlanReportIdList,ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ReportTriggerMode.SCHEDULE.name());
|
testPlanReportService.updateReport(testPlanReportIdList, ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ReportTriggerMode.SCHEDULE.name());
|
||||||
|
|
||||||
return lastReport;
|
return lastReport;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ApiScenarioReport updateScenario(TestResult result) {
|
public ApiScenarioReport updateScenario(TestResult result) {
|
||||||
ApiScenarioReport lastReport = null;
|
ApiScenarioReport lastReport = null;
|
||||||
|
if (CollectionUtils.isEmpty(result.getScenarios())) {
|
||||||
|
ScenarioResult test = new ScenarioResult();
|
||||||
|
test.setName(result.getTestId());
|
||||||
|
ApiScenarioReport report = editReport(test);
|
||||||
|
return report;
|
||||||
|
}
|
||||||
for (ScenarioResult item : result.getScenarios()) {
|
for (ScenarioResult item : result.getScenarios()) {
|
||||||
// 更新报告状态
|
// 更新报告状态
|
||||||
ApiScenarioReport report = editReport(item);
|
ApiScenarioReport report = editReport(item);
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.jmeter.reporters;
|
||||||
|
|
||||||
|
import org.apache.jmeter.samplers.SampleEvent;
|
||||||
|
import org.apache.jmeter.samplers.SampleListener;
|
||||||
|
import org.apache.jmeter.samplers.SampleResult;
|
||||||
|
import org.apache.jmeter.testelement.OnErrorTestElement;
|
||||||
|
import org.apache.jmeter.threads.JMeterContext.TestLogicalAction;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ResultAction - take action based on the status of the last Result
|
||||||
|
*/
|
||||||
|
public class ResultAction extends OnErrorTestElement implements Serializable, SampleListener {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 242L;
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ResultAction.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor is initially called once for each occurrence in the test plan
|
||||||
|
* For GUI, several more instances are created Then clear is called at start
|
||||||
|
* of test Called several times during test startup The name will not
|
||||||
|
* necessarily have been set at this point.
|
||||||
|
*/
|
||||||
|
public ResultAction() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Examine the sample(s) and take appropriate action
|
||||||
|
*
|
||||||
|
* @see SampleListener#sampleOccurred(SampleEvent)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void sampleOccurred(SampleEvent e) {
|
||||||
|
SampleResult s = e.getResult();
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("ResultStatusHandler {} for {} OK? {}", getName(), s.getSampleLabel(), s.isSuccessful());
|
||||||
|
}
|
||||||
|
if (!s.isSuccessful()) {
|
||||||
|
if (isStopTestNow()) {
|
||||||
|
s.setStopTestNow(true);
|
||||||
|
} else if (isStopTest()) {
|
||||||
|
s.setStopTest(true);
|
||||||
|
} else if (isStopThread()) {
|
||||||
|
s.setStopThread(true);
|
||||||
|
} else if (isStartNextThreadLoop()) {
|
||||||
|
s.setTestLogicalAction(TestLogicalAction.START_NEXT_ITERATION_OF_THREAD);
|
||||||
|
} else if (isStartNextIterationOfCurrentLoop()) {
|
||||||
|
s.setTestLogicalAction(TestLogicalAction.START_NEXT_ITERATION_OF_CURRENT_LOOP);
|
||||||
|
} else if (isBreakCurrentLoop()) {
|
||||||
|
s.setTestLogicalAction(TestLogicalAction.BREAK_CURRENT_LOOP);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (getErrorAction() == 1000) {
|
||||||
|
s.setTestLogicalAction(TestLogicalAction.BREAK_CURRENT_LOOP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void sampleStarted(SampleEvent e) {
|
||||||
|
// not used
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void sampleStopped(SampleEvent e) {
|
||||||
|
// not used
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -110,6 +110,10 @@
|
||||||
if (this.isNotRunning) {
|
if (this.isNotRunning) {
|
||||||
try {
|
try {
|
||||||
this.content = JSON.parse(this.report.content);
|
this.content = JSON.parse(this.report.content);
|
||||||
|
console.log(this.content)
|
||||||
|
if (!this.content) {
|
||||||
|
this.content = {scenarios: []};
|
||||||
|
}
|
||||||
this.$emit('refresh');
|
this.$emit('refresh');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -130,21 +134,23 @@
|
||||||
if (this.isNotRunning) {
|
if (this.isNotRunning) {
|
||||||
this.fails = [];
|
this.fails = [];
|
||||||
this.totalTime = 0
|
this.totalTime = 0
|
||||||
this.content.scenarios.forEach((scenario) => {
|
if (this.content.scenarios) {
|
||||||
this.totalTime = this.totalTime + Number(scenario.responseTime)
|
this.content.scenarios.forEach((scenario) => {
|
||||||
let failScenario = Object.assign({}, scenario);
|
this.totalTime = this.totalTime + Number(scenario.responseTime)
|
||||||
if (scenario.error > 0) {
|
let failScenario = Object.assign({}, scenario);
|
||||||
this.fails.push(failScenario);
|
if (scenario.error > 0) {
|
||||||
failScenario.requestResults = [];
|
this.fails.push(failScenario);
|
||||||
scenario.requestResults.forEach((request) => {
|
failScenario.requestResults = [];
|
||||||
if (!request.success) {
|
scenario.requestResults.forEach((request) => {
|
||||||
let failRequest = Object.assign({}, request);
|
if (!request.success) {
|
||||||
failScenario.requestResults.push(failRequest);
|
let failRequest = Object.assign({}, request);
|
||||||
}
|
failScenario.requestResults.push(failRequest);
|
||||||
})
|
}
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
requestResult(requestResult) {
|
requestResult(requestResult) {
|
||||||
|
|
|
@ -68,6 +68,10 @@
|
||||||
request: {},
|
request: {},
|
||||||
currentScenario: {},
|
currentScenario: {},
|
||||||
node: {},
|
node: {},
|
||||||
|
draggable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
currentEnvironmentId: String,
|
currentEnvironmentId: String,
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
|
|
@ -31,6 +31,10 @@
|
||||||
props: {
|
props: {
|
||||||
scenario: {},
|
scenario: {},
|
||||||
node: {},
|
node: {},
|
||||||
|
draggable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
watch: {},
|
watch: {},
|
||||||
created() {
|
created() {
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
:title="$t('api_test.automation.wait_controller')">
|
:title="$t('api_test.automation.wait_controller')">
|
||||||
|
|
||||||
<template v-slot:headerLeft>
|
<template v-slot:headerLeft>
|
||||||
<el-input-number class="time-input" size="small" v-model="timer.delay" :min="0" :step="1000"/>
|
<el-input-number class="time-input" size="small" v-model="timer.delay" :min="0" :step="1000"/> ms
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</api-base-component>
|
</api-base-component>
|
||||||
|
@ -24,6 +24,10 @@
|
||||||
props: {
|
props: {
|
||||||
timer: {},
|
timer: {},
|
||||||
node: {},
|
node: {},
|
||||||
|
draggable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {}
|
return {}
|
||||||
|
|
|
@ -33,6 +33,10 @@
|
||||||
controller: {},
|
controller: {},
|
||||||
node: {},
|
node: {},
|
||||||
index: Object,
|
index: Object,
|
||||||
|
draggable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -25,8 +25,8 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<span class="ms-span ms-radio">{{$t('loop.interval')}}</span>
|
<span class="ms-span ms-radio">{{$t('loop.interval')}}</span>
|
||||||
<el-input-number size="small" v-model="controller.countController.interval" :placeholder="$t('commons.millisecond')" :max="1000*10000000" :min="0"/>
|
<el-input-number size="small" v-model="controller.countController.interval" :placeholder="$t('commons.millisecond')" :max="1000*10000000" :min="0" :step="1000"/>
|
||||||
<span class="ms-span ms-radio">秒</span>
|
<span class="ms-span ms-radio">ms</span>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<span class="ms-span ms-radio">{{$t('loop.proceed')}}</span>
|
<span class="ms-span ms-radio">{{$t('loop.proceed')}}</span>
|
||||||
|
@ -51,8 +51,8 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="7">
|
<el-col :span="7">
|
||||||
<span class="ms-span ms-radio">{{$t('loop.interval')}}</span>
|
<span class="ms-span ms-radio">{{$t('loop.interval')}}</span>
|
||||||
<el-input-number size="small" v-model="controller.forEachController.interval" :placeholder="$t('commons.millisecond')" :max="1000*10000000" :min="0"/>
|
<el-input-number size="small" v-model="controller.forEachController.interval" :placeholder="$t('commons.millisecond')" :max="1000*10000000" :min="0" :step="1000"/>
|
||||||
<span class="ms-span ms-radio">秒</span>
|
<span class="ms-span ms-radio">ms</span>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
|
@ -65,8 +65,8 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
<el-input size="small" v-model="controller.whileController.value" :placeholder="$t('api_test.value')" v-if="!hasEmptyOperator" style="width: 20%;margin-left: 20px"/>
|
<el-input size="small" v-model="controller.whileController.value" :placeholder="$t('api_test.value')" v-if="!hasEmptyOperator" style="width: 20%;margin-left: 20px"/>
|
||||||
<span class="ms-span ms-radio">{{$t('loop.timeout')}}</span>
|
<span class="ms-span ms-radio">{{$t('loop.timeout')}}</span>
|
||||||
<el-input-number size="small" v-model="controller.whileController.timeout" :placeholder="$t('commons.millisecond')" :max="1000*10000000" :min="0"/>
|
<el-input-number size="small" v-model="controller.whileController.timeout" :placeholder="$t('commons.millisecond')" :max="1000*10000000" :min="1" :step="1000"/>
|
||||||
<span class="ms-span ms-radio">秒</span>
|
<span class="ms-span ms-radio">ms</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</api-base-component>
|
</api-base-component>
|
||||||
|
@ -82,6 +82,10 @@
|
||||||
controller: {},
|
controller: {},
|
||||||
node: {},
|
node: {},
|
||||||
index: Object,
|
index: Object,
|
||||||
|
draggable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
Loading…
Reference in New Issue