This commit is contained in:
chenjianxing 2021-02-22 12:09:43 +08:00
commit adb134e56f
19 changed files with 610 additions and 445 deletions

View File

@ -10,16 +10,11 @@ import io.metersphere.api.dto.datacount.response.ApiDataCountDTO;
import io.metersphere.api.dto.datacount.response.ExecutedCaseInfoDTO; import io.metersphere.api.dto.datacount.response.ExecutedCaseInfoDTO;
import io.metersphere.api.dto.datacount.response.TaskInfoResult; import io.metersphere.api.dto.datacount.response.TaskInfoResult;
import io.metersphere.api.dto.definition.RunDefinitionRequest; import io.metersphere.api.dto.definition.RunDefinitionRequest;
import io.metersphere.api.dto.definition.request.MsTestElement;
import io.metersphere.api.dto.scenario.request.dubbo.RegistryCenter; import io.metersphere.api.dto.scenario.request.dubbo.RegistryCenter;
import io.metersphere.api.service.*; import io.metersphere.api.service.*;
import io.metersphere.base.domain.ApiDefinition;
import io.metersphere.base.domain.ApiTest; import io.metersphere.base.domain.ApiTest;
import io.metersphere.base.domain.LoadTest;
import io.metersphere.base.domain.Schedule; import io.metersphere.base.domain.Schedule;
import io.metersphere.commons.constants.PerformanceTestStatus;
import io.metersphere.commons.constants.RoleConstants; import io.metersphere.commons.constants.RoleConstants;
import io.metersphere.commons.constants.ScheduleGroup;
import io.metersphere.commons.utils.CronUtils; import io.metersphere.commons.utils.CronUtils;
import io.metersphere.commons.utils.PageUtils; import io.metersphere.commons.utils.PageUtils;
import io.metersphere.commons.utils.Pager; import io.metersphere.commons.utils.Pager;
@ -28,24 +23,14 @@ import io.metersphere.controller.request.QueryScheduleRequest;
import io.metersphere.dto.ScheduleDao; import io.metersphere.dto.ScheduleDao;
import io.metersphere.performance.service.PerformanceTestService; import io.metersphere.performance.service.PerformanceTestService;
import io.metersphere.service.CheckPermissionService; import io.metersphere.service.CheckPermissionService;
import io.metersphere.service.FileService;
import io.metersphere.service.ScheduleService; import io.metersphere.service.ScheduleService;
import io.metersphere.track.request.testplan.SaveTestPlanRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.entity.ContentType;
import org.apache.jorphan.collections.HashTree; import org.apache.jorphan.collections.HashTree;
import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles; import org.apache.shiro.authz.annotation.RequiresRoles;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
@ -393,7 +378,7 @@ public class APITestController {
String testName = runRequest.getName(); String testName = runRequest.getName();
//将jmx处理封装为通用方法 //将jmx处理封装为通用方法
jmxString = apiTestService.updateJmxString(jmxString,testName,true); jmxString = apiTestService.updateJmxString(jmxString,testName,false);
JmxInfoDTO dto = new JmxInfoDTO(); JmxInfoDTO dto = new JmxInfoDTO();
dto.setName(runRequest.getName() + ".jmx"); dto.setName(runRequest.getName() + ".jmx");

View File

@ -160,5 +160,11 @@ public class ApiAutomationController {
return apiAutomationService.export(request); return apiAutomationService.export(request);
} }
@PostMapping(value = "/export/jmx")
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
public List<ApiScenrioExportJmx> exportJmx(@RequestBody ApiScenarioBatchRequest request) {
return apiAutomationService.exportJmx(request);
}
} }

View File

@ -0,0 +1,16 @@
package io.metersphere.api.dto.automation;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class ApiScenrioExportJmx {
private String name;
private String jmx;
public ApiScenrioExportJmx(String name, String jmx) {
this.name = name;
this.jmx = jmx;
}
}

View File

@ -89,7 +89,7 @@ public class MsJmeterParser extends ApiImportAbstractParser<ScenarioImport> {
preInitPool(request.getProjectId(), testPlan); preInitPool(request.getProjectId(), testPlan);
MsScenario scenario = new MsScenario(); MsScenario scenario = new MsScenario();
scenario.setReferenced("REF"); scenario.setReferenced("IMPORT");
jmterHashTree(testPlan, scenario); jmterHashTree(testPlan, scenario);
this.projectId = request.getProjectId(); this.projectId = request.getProjectId();
ScenarioImport scenarioImport = new ScenarioImport(); ScenarioImport scenarioImport = new ScenarioImport();
@ -234,24 +234,24 @@ public class MsJmeterParser extends ApiImportAbstractParser<ScenarioImport> {
elementNode.setConsumerAndService(consumerAndService); elementNode.setConsumerAndService(consumerAndService);
List<MethodArgument> methodArguments = Constants.getMethodArgs(sampler); List<MethodArgument> methodArguments = Constants.getMethodArgs(sampler);
List<KeyValue> methodArgs = new LinkedList<>();
if (CollectionUtils.isNotEmpty(methodArguments)) { if (CollectionUtils.isNotEmpty(methodArguments)) {
List<KeyValue> methodArgs = new LinkedList<>();
methodArguments.forEach(item -> { methodArguments.forEach(item -> {
KeyValue keyValue = new KeyValue(item.getParamType(), item.getParamValue()); KeyValue keyValue = new KeyValue(item.getParamType(), item.getParamValue());
methodArgs.add(keyValue); methodArgs.add(keyValue);
}); });
elementNode.setArgs(methodArgs);
} }
elementNode.setArgs(methodArgs);
List<MethodArgument> arguments = Constants.getAttachmentArgs(sampler); List<MethodArgument> arguments = Constants.getAttachmentArgs(sampler);
List<KeyValue> attachmentArgs = new LinkedList<>();
if (CollectionUtils.isNotEmpty(arguments)) { if (CollectionUtils.isNotEmpty(arguments)) {
List<KeyValue> methodArgs = new LinkedList<>();
arguments.forEach(item -> { arguments.forEach(item -> {
KeyValue keyValue = new KeyValue(item.getParamType(), item.getParamValue()); KeyValue keyValue = new KeyValue(item.getParamType(), item.getParamValue());
methodArgs.add(keyValue); attachmentArgs.add(keyValue);
}); });
elementNode.setAttachmentArgs(methodArgs);
} }
elementNode.setAttachmentArgs(attachmentArgs);
} }
/** /**

View File

@ -164,9 +164,9 @@ public abstract class MsTestElement {
} }
public Arguments addArguments(ParameterConfig config) { public Arguments addArguments(ParameterConfig config) {
Arguments arguments = new Arguments();
if (config != null && config.getConfig() != null && config.getConfig().getCommonConfig() != null if (config != null && config.getConfig() != null && config.getConfig().getCommonConfig() != null
&& CollectionUtils.isNotEmpty(config.getConfig().getCommonConfig().getVariables())) { && CollectionUtils.isNotEmpty(config.getConfig().getCommonConfig().getVariables())) {
Arguments arguments = new Arguments();
arguments.setEnabled(true); arguments.setEnabled(true);
arguments.setName(name + "Variables"); arguments.setName(name + "Variables");
arguments.setProperty(TestElement.TEST_CLASS, Arguments.class.getName()); arguments.setProperty(TestElement.TEST_CLASS, Arguments.class.getName());
@ -174,8 +174,9 @@ public abstract class MsTestElement {
config.getConfig().getCommonConfig().getVariables().stream().filter(KeyValue::isValid).filter(KeyValue::isEnable).forEach(keyValue -> config.getConfig().getCommonConfig().getVariables().stream().filter(KeyValue::isValid).filter(KeyValue::isEnable).forEach(keyValue ->
arguments.addArgument(keyValue.getName(), keyValue.getValue(), "=") arguments.addArgument(keyValue.getName(), keyValue.getValue(), "=")
); );
return arguments;
} }
return arguments; return null;
} }
protected EnvironmentConfig getEnvironmentConfig(String environmentId) { protected EnvironmentConfig getEnvironmentConfig(String environmentId) {

View File

@ -95,17 +95,18 @@ public class MsJDBCSampler extends MsTestElement {
} }
private Arguments arguments(String name, List<KeyValue> variables) { private Arguments arguments(String name, List<KeyValue> variables) {
Arguments arguments = new Arguments();
if (CollectionUtils.isNotEmpty(variables)) { if (CollectionUtils.isNotEmpty(variables)) {
Arguments arguments = new Arguments();
arguments.setEnabled(true); arguments.setEnabled(true);
arguments.setName(name); arguments.setName(name + "JDBC_Argument");
arguments.setProperty(TestElement.TEST_CLASS, Arguments.class.getName()); arguments.setProperty(TestElement.TEST_CLASS, Arguments.class.getName());
arguments.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("ArgumentsPanel")); arguments.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("ArgumentsPanel"));
variables.stream().filter(KeyValue::isValid).filter(KeyValue::isEnable).forEach(keyValue -> variables.stream().filter(KeyValue::isValid).filter(KeyValue::isEnable).forEach(keyValue ->
arguments.addArgument(keyValue.getName(), keyValue.getValue(), "=") arguments.addArgument(keyValue.getName(), keyValue.getValue(), "=")
); );
return arguments;
} }
return arguments; return null;
} }
private JDBCSampler jdbcSampler(ParameterConfig config) { private JDBCSampler jdbcSampler(ParameterConfig config) {

View File

@ -35,6 +35,7 @@ import org.aspectj.util.FileUtil;
import org.dom4j.Document; import org.dom4j.Document;
import org.dom4j.DocumentHelper; import org.dom4j.DocumentHelper;
import org.dom4j.Element; import org.dom4j.Element;
import org.dom4j.QName;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@ -461,56 +462,44 @@ public class APITestService {
}); });
} }
public String updateJmxString(String jmxString,String testName,boolean updateHTTPSamplerProxyName) { /**
* 更新jmx数据处理jmx里的各种参数
*
* 与1.7分支合并时如果该方法产生冲突请以master为准
* @author song tianyang
* @param jmxString 原JMX文件
* @param testNameParam 某些节点要替换的testName
* @param isFromScenario 是否来源于场景 来源于场景的话testName要进行处理
* @return
*/
public String updateJmxString(String jmxString, String testNameParam, boolean isFromScenario) {
// 与1.7分支合并时如果该方法产生冲突请以master为准
String attribute_testName = "testname";
String [] requestElementNameArr = new String[]{"HTTPSamplerProxy","TCPSampler","JDBCSampler","DubboSample"};
try { try {
//将ThreadGroup的testname改为接口名称 //将ThreadGroup的testname改为接口名称
Document doc = DocumentHelper.parseText(jmxString);// 获取可续保保单列表报文模板 Document doc = DocumentHelper.parseText(jmxString);// 获取可续保保单列表报文模板
Element root = doc.getRootElement(); Element root = doc.getRootElement();
Element rootHashTreeElement = root.element("hashTree"); Element rootHashTreeElement = root.element("hashTree");
Element innerHashTreeElement = rootHashTreeElement.elements("hashTree").get(0);
Element theadGroupElement = innerHashTreeElement.elements("ThreadGroup").get(0);
theadGroupElement.attribute("testname").setText(testName);
List<Element> thirdHashTreeElementList = innerHashTreeElement.elements("hashTree"); List<Element> innerHashTreeElementList = rootHashTreeElement.elements("hashTree");
for (Element element : thirdHashTreeElementList) { for (Element innerHashTreeElement : innerHashTreeElementList) {
if(updateHTTPSamplerProxyName){ List<Element> thirdHashTreeElementList = innerHashTreeElement.elements("hashTree");
List<Element> sampleProxyElementList = element.elements("HTTPSamplerProxy"); List<Element> theadGroupElementList = innerHashTreeElement.elements("ThreadGroup");
for (Element itemElement : sampleProxyElementList) { for (Element theadGroupElement : theadGroupElementList) {
itemElement.attribute("testname").setText(testName); if(StringUtils.isNotEmpty(testNameParam)){
theadGroupElement.attribute(attribute_testName).setText(testNameParam);
} }
} }
//检查有没有自定义参数
List<Element> scriptHashTreeElementList = element.elements("hashTree");
for (Element scriptHashTreeElement : scriptHashTreeElementList) {
boolean isRemove = false;
List<Element> removeElement = new ArrayList<>();
List<Element> scriptElementItemList = scriptHashTreeElement.elements();
for (Element hashTreeItemElement : scriptElementItemList) {
String className = hashTreeItemElement.attributeValue("testclass");
String qname = hashTreeItemElement.getQName().getName();
if (isRemove) { for (Element element : thirdHashTreeElementList) {
if (org.apache.commons.lang3.StringUtils.equals("hashTree", qname)) { String testName = testNameParam;
removeElement.add(hashTreeItemElement);
}
}
isRemove = false;
if (org.apache.commons.lang3.StringUtils.equals(className, "JSR223PostProcessor")) {
List<Element> scriptElements = hashTreeItemElement.elements("stringProp");
for (Element scriptElement : scriptElements) {
String scriptName = scriptElement.attributeValue("name");
String contentValue = scriptElement.getStringValue();
if ("script".equals(scriptName) && contentValue.startsWith("io.metersphere.api.jmeter.JMeterVars.addVars")) { //更新请求类节点的部份属性
isRemove = true; this.updateRequestElementInfo(element,testNameParam,requestElementNameArr,isFromScenario);
removeElement.add(hashTreeItemElement); //检查有无jmeter不是别的自定义参数
} this.checkPrivateFunctionNode(element);
}
}
}
for (Element itemElement : removeElement) {
scriptHashTreeElement.remove(itemElement);
}
} }
} }
jmxString = root.asXML(); jmxString = root.asXML();
@ -519,4 +508,69 @@ public class APITestService {
} }
return jmxString; return jmxString;
} }
private void checkPrivateFunctionNode(Element element) {
List<Element> scriptHashTreeElementList = element.elements("hashTree");
for (Element scriptHashTreeElement : scriptHashTreeElementList) {
boolean isRemove = false;
List<Element> removeElement = new ArrayList<>();
List<Element> scriptElementItemList = scriptHashTreeElement.elements();
for (Element hashTreeItemElement : scriptElementItemList) {
String className = hashTreeItemElement.attributeValue("testclass");
String qname = hashTreeItemElement.getQName().getName();
if (isRemove) {
if (org.apache.commons.lang3.StringUtils.equals("hashTree", qname)) {
removeElement.add(hashTreeItemElement);
}
}
isRemove = false;
if (org.apache.commons.lang3.StringUtils.equals(className, "JSR223PostProcessor")) {
List<Element> scriptElements = hashTreeItemElement.elements("stringProp");
for (Element scriptElement : scriptElements) {
String scriptName = scriptElement.attributeValue("name");
String contentValue = scriptElement.getStringValue();
if ("script".equals(scriptName) && contentValue.startsWith("io.metersphere.api.jmeter.JMeterVars.addVars")) {
isRemove = true;
removeElement.add(hashTreeItemElement);
}
}
}
}
for (Element itemElement : removeElement) {
scriptHashTreeElement.remove(itemElement);
}
}
}
private void updateRequestElementInfo(Element element,String testNameParam,String [] requestElementNameArr,boolean isFromScenario){
String attribute_testName = "testname";
String scenarioCaseNameSplit = "<->";
String testName = testNameParam;
for(String requestElementName : requestElementNameArr){
List<Element> sampleProxyElementList = element.elements(requestElementName);
for (Element itemElement : sampleProxyElementList) {
if(isFromScenario){
testName = itemElement.attributeValue(attribute_testName);
String[] testNameArr = testName.split(scenarioCaseNameSplit);
if (testNameArr.length > 0) {
testName = testNameArr[0];
}
}
itemElement.attribute(attribute_testName).setText(testName);
//double的话有额外处理方式
if(StringUtils.equals(requestElementName,"DubboSample")){
//dubbo节点要更新 标签guiClass testClass
itemElement.setName("io.github.ningyu.jmeter.plugin.dubbo.sample.DubboSample");
itemElement.attribute("testclass").setText("io.github.ningyu.jmeter.plugin.dubbo.sample.DubboSample");
itemElement.attribute("guiclass").setText("io.github.ningyu.jmeter.plugin.dubbo.gui.DubboSampleGui");
}
}
}
}
} }

View File

@ -435,6 +435,47 @@ public class ApiAutomationService {
return jmeterHashTree; return jmeterHashTree;
} }
private String generateJmx(ApiScenarioWithBLOBs apiScenario) {
HashTree jmeterHashTree = new ListedHashTree();
MsTestPlan testPlan = new MsTestPlan();
testPlan.setHashTree(new LinkedList<>());
try {
MsThreadGroup group = new MsThreadGroup();
group.setLabel(apiScenario.getName());
group.setName(apiScenario.getName());
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
JSONObject element = JSON.parseObject(apiScenario.getScenarioDefinition());
MsScenario scenario = JSONObject.parseObject(apiScenario.getScenarioDefinition(), MsScenario.class);
// 多态JSON普通转换会丢失内容需要通过 ObjectMapper 获取
if (element != null && StringUtils.isNotEmpty(element.getString("hashTree"))) {
LinkedList<MsTestElement> elements = mapper.readValue(element.getString("hashTree"),
new TypeReference<LinkedList<MsTestElement>>() {
});
scenario.setHashTree(elements);
}
if (StringUtils.isNotEmpty(element.getString("variables"))) {
LinkedList<ScenarioVariable> variables = mapper.readValue(element.getString("variables"),
new TypeReference<LinkedList<ScenarioVariable>>() {
});
scenario.setVariables(variables);
}
group.setEnableCookieShare(scenario.isEnableCookieShare());
group.setHashTree(new LinkedList<MsTestElement>() {{
this.add(scenario);
}});
testPlan.getHashTree().add(group);
} catch (Exception ex) {
MSException.throwException(ex.getMessage());
}
testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), new ParameterConfig());
return testPlan.getJmx(jmeterHashTree);
}
/** /**
* 场景测试执行 * 场景测试执行
* *
@ -515,7 +556,6 @@ public class ApiAutomationService {
ParameterConfig config = new ParameterConfig(); ParameterConfig config = new ParameterConfig();
config.setConfig(envConfig); config.setConfig(envConfig);
HashTree hashTree = request.getTestElement().generateHashTree(config); HashTree hashTree = request.getTestElement().generateHashTree(config);
System.out.println(request.getTestElement().getJmx(hashTree));
// 调用执行方法 // 调用执行方法
createScenarioReport(request.getId(), request.getScenarioId(), request.getScenarioName(), ReportTriggerMode.MANUAL.name(), request.getExecuteType(), request.getProjectId(), createScenarioReport(request.getId(), request.getScenarioId(), request.getScenarioName(), ReportTriggerMode.MANUAL.name(), request.getExecuteType(), request.getProjectId(),
SessionUtils.getUserId()); SessionUtils.getUserId());
@ -668,7 +708,7 @@ public class ApiAutomationService {
HashTree jmeterHashTree = generateHashTree(apiScenarios, request, null); HashTree jmeterHashTree = generateHashTree(apiScenarios, request, null);
String jmx = testPlan.getJmx(jmeterHashTree); String jmx = testPlan.getJmx(jmeterHashTree);
jmx = apiTestService.updateJmxString(jmx,testName,false); jmx = apiTestService.updateJmxString(jmx, testName, true);
//将ThreadGroup的testname改为接口名称 //将ThreadGroup的testname改为接口名称
// Document doc = DocumentHelper.parseText(jmx);// 获取可续保保单列表报文模板 // Document doc = DocumentHelper.parseText(jmx);// 获取可续保保单列表报文模板
@ -807,16 +847,32 @@ public class ApiAutomationService {
return apiImport; return apiImport;
} }
public ApiScenrioExportResult export(ApiScenarioBatchRequest request) { private List<ApiScenarioWithBLOBs> getExportResult(ApiScenarioBatchRequest request) {
ServiceUtils.getSelectAllIds(request, request.getCondition(), ServiceUtils.getSelectAllIds(request, request.getCondition(),
(query) -> extApiScenarioMapper.selectIdsByQuery((ApiScenarioRequest) query)); (query) -> extApiScenarioMapper.selectIdsByQuery((ApiScenarioRequest) query));
ApiScenarioExample example = new ApiScenarioExample(); ApiScenarioExample example = new ApiScenarioExample();
example.createCriteria().andIdIn(request.getIds()); example.createCriteria().andIdIn(request.getIds());
List<ApiScenarioWithBLOBs> apiScenarioWithBLOBs = apiScenarioMapper.selectByExampleWithBLOBs(example); List<ApiScenarioWithBLOBs> apiScenarioWithBLOBs = apiScenarioMapper.selectByExampleWithBLOBs(example);
ApiScenrioExportResult result = new ApiScenrioExportResult(); return apiScenarioWithBLOBs;
result.setData(apiScenarioWithBLOBs); }
public ApiScenrioExportResult export(ApiScenarioBatchRequest request) {
ApiScenrioExportResult result = new ApiScenrioExportResult();
result.setData(getExportResult(request));
result.setProjectId(request.getProjectId()); result.setProjectId(request.getProjectId());
result.setVersion(System.getenv("MS_VERSION")); result.setVersion(System.getenv("MS_VERSION"));
return result; return result;
} }
public List<ApiScenrioExportJmx> exportJmx(ApiScenarioBatchRequest request) {
List<ApiScenarioWithBLOBs> apiScenarioWithBLOBs = getExportResult(request);
// 生成jmx
List<ApiScenrioExportJmx> resList = new ArrayList<>();
apiScenarioWithBLOBs.forEach(item -> {
ApiScenrioExportJmx scenrioExportJmx = new ApiScenrioExportJmx(item.getName(), apiTestService.updateJmxString(generateJmx(item), item.getName(), true));
resList.add(scenrioExportJmx);
});
return resList;
}
} }

@ -1 +1 @@
Subproject commit 5e0b365f1080197e84055e80071165787e2e79c5 Subproject commit b9042074b780205e275c674f64417799110519fd

View File

@ -9,6 +9,7 @@
@setNodeTree="setNodeTree" @setNodeTree="setNodeTree"
@enableTrash="enableTrash" @enableTrash="enableTrash"
@exportAPI="exportAPI" @exportAPI="exportAPI"
@exportJmx="exportJmx"
@refreshAll="refreshAll" @refreshAll="refreshAll"
:type="'edit'" :type="'edit'"
ref="nodeTree"/> ref="nodeTree"/>
@ -69,7 +70,6 @@
import MsApiScenarioModule from "@/business/components/api/automation/scenario/ApiScenarioModule"; import MsApiScenarioModule from "@/business/components/api/automation/scenario/ApiScenarioModule";
import MsEditApiScenario from "./scenario/EditApiScenario"; import MsEditApiScenario from "./scenario/EditApiScenario";
import {getCurrentProjectID} from "../../../../common/js/utils"; import {getCurrentProjectID} from "../../../../common/js/utils";
import {PROJECT_NAME} from "../../../../common/js/constants";
export default { export default {
name: "ApiAutomation", name: "ApiAutomation",
@ -133,6 +133,9 @@
exportAPI() { exportAPI() {
this.$refs.apiScenarioList.exportApi(); this.$refs.apiScenarioList.exportApi();
}, },
exportJmx(){
this.$refs.apiScenarioList.exportJmx();
},
checkRedirectEditPage(redirectParam) { checkRedirectEditPage(redirectParam) {
if (redirectParam != null) { if (redirectParam != null) {
let selectParamArr = redirectParam.split("edit:"); let selectParamArr = redirectParam.split("edit:");

View File

@ -167,50 +167,50 @@
</template> </template>
<script> <script>
import MsTableHeader from "@/business/components/common/components/MsTableHeader"; import MsTableHeader from "@/business/components/common/components/MsTableHeader";
import MsTablePagination from "@/business/components/common/pagination/TablePagination"; import MsTablePagination from "@/business/components/common/pagination/TablePagination";
import ShowMoreBtn from "@/business/components/track/case/components/ShowMoreBtn"; import ShowMoreBtn from "@/business/components/track/case/components/ShowMoreBtn";
import MsTag from "../../../common/components/MsTag"; import MsTag from "../../../common/components/MsTag";
import {downloadFile, getCurrentProjectID, getCurrentUser, getUUID} from "@/common/js/utils"; import {downloadFile, getCurrentProjectID, getCurrentUser, getUUID} from "@/common/js/utils";
import MsApiReportDetail from "../report/ApiReportDetail"; import MsApiReportDetail from "../report/ApiReportDetail";
import MsTableMoreBtn from "./TableMoreBtn"; import MsTableMoreBtn from "./TableMoreBtn";
import MsScenarioExtendButtons from "@/business/components/api/automation/scenario/ScenarioExtendBtns"; import MsScenarioExtendButtons from "@/business/components/api/automation/scenario/ScenarioExtendBtns";
import MsTestPlanList from "./testplan/TestPlanList"; import MsTestPlanList from "./testplan/TestPlanList";
import MsTableHeaderSelectPopover from "@/business/components/common/components/table/MsTableHeaderSelectPopover"; import MsTableHeaderSelectPopover from "@/business/components/common/components/table/MsTableHeaderSelectPopover";
import {API_SCENARIO_CONFIGS} from "@/business/components/common/components/search/search-components"; import {API_SCENARIO_CONFIGS} from "@/business/components/common/components/search/search-components";
import MsTableOperatorButton from "@/business/components/common/components/MsTableOperatorButton"; import MsTableOperatorButton from "@/business/components/common/components/MsTableOperatorButton";
import PriorityTableItem from "../../../track/common/tableItems/planview/PriorityTableItem"; import PriorityTableItem from "../../../track/common/tableItems/planview/PriorityTableItem";
import PlanStatusTableItem from "../../../track/common/tableItems/plan/PlanStatusTableItem"; import PlanStatusTableItem from "../../../track/common/tableItems/plan/PlanStatusTableItem";
import BatchEdit from "../../../track/case/components/BatchEdit"; import BatchEdit from "../../../track/case/components/BatchEdit";
import {API_SCENARIO_LIST, TEST_CASE_LIST, TEST_PLAN_LIST, WORKSPACE_ID} from "../../../../../common/js/constants"; import {API_SCENARIO_LIST, TEST_CASE_LIST, TEST_PLAN_LIST, WORKSPACE_ID} from "../../../../../common/js/constants";
import {PROJECT_NAME} from "../../../../../common/js/constants"; import {PROJECT_NAME} from "../../../../../common/js/constants";
import EnvironmentSelect from "../../definition/components/environment/EnvironmentSelect"; import EnvironmentSelect from "../../definition/components/environment/EnvironmentSelect";
import BatchMove from "../../../track/case/components/BatchMove"; import BatchMove from "../../../track/case/components/BatchMove";
import {_sort} from "@/common/js/tableUtils"; import {_sort} from "@/common/js/tableUtils";
import {Api_Scenario_List} from "@/business/components/common/model/JsonData"; import {Api_Scenario_List} from "@/business/components/common/model/JsonData";
import HeaderCustom from "@/business/components/common/head/HeaderCustom"; import HeaderCustom from "@/business/components/common/head/HeaderCustom";
import { import {
_filter, _filter,
_handleSelect, _handleSelect,
_handleSelectAll, _handleSelectAll,
getSelectDataCounts, getSelectDataCounts,
setUnSelectIds, toggleAllSelection setUnSelectIds, toggleAllSelection
} from "@/common/js/tableUtils"; } from "@/common/js/tableUtils";
export default { export default {
name: "MsApiScenarioList", name: "MsApiScenarioList",
components: { components: {
HeaderCustom, HeaderCustom,
BatchMove, BatchMove,
EnvironmentSelect, EnvironmentSelect,
BatchEdit, BatchEdit,
PlanStatusTableItem, PlanStatusTableItem,
PriorityTableItem, PriorityTableItem,
MsTableHeaderSelectPopover, MsTableHeaderSelectPopover,
MsTablePagination, MsTablePagination,
MsTableMoreBtn, MsTableMoreBtn,
ShowMoreBtn, ShowMoreBtn,
MsTableHeader, MsTableHeader,
MsTag, MsTag,
MsApiReportDetail, MsApiReportDetail,
MsScenarioExtendButtons, MsScenarioExtendButtons,
@ -554,12 +554,15 @@ export default {
_handleSelectAll(this, selection, this.tableData, this.selectRows); _handleSelectAll(this, selection, this.tableData, this.selectRows);
setUnSelectIds(this.tableData, this.condition, this.selectRows); setUnSelectIds(this.tableData, this.condition, this.selectRows);
this.selectDataCounts = getSelectDataCounts(this.condition, this.total, this.selectRows); this.selectDataCounts = getSelectDataCounts(this.condition, this.total, this.selectRows);
this.$emit('selection', selection);
}, },
handleSelect(selection, row) { handleSelect(selection, row) {
_handleSelect(this, selection, row, this.selectRows); _handleSelect(this, selection, row, this.selectRows);
setUnSelectIds(this.tableData, this.condition, this.selectRows); setUnSelectIds(this.tableData, this.condition, this.selectRows);
this.selectDataCounts = getSelectDataCounts(this.condition, this.total, this.selectRows); this.selectDataCounts = getSelectDataCounts(this.condition, this.total, this.selectRows);
this.$emit('selection', selection);
}, },
isSelectDataAll(data) { isSelectDataAll(data) {
this.condition.selectAll = data; this.condition.selectAll = data;
setUnSelectIds(this.tableData, this.condition, this.selectRows); setUnSelectIds(this.tableData, this.condition, this.selectRows);
@ -672,6 +675,25 @@ export default {
downloadFile("Metersphere_Scenario_" + localStorage.getItem(PROJECT_NAME) + ".json", JSON.stringify(obj)); downloadFile("Metersphere_Scenario_" + localStorage.getItem(PROJECT_NAME) + ".json", JSON.stringify(obj));
}); });
}, },
exportJmx() {
let param = {};
this.buildBatchParam(param);
if (param.ids === undefined || param.ids.length < 1) {
this.$warning(this.$t("api_test.automation.scenario.check_case"));
return;
}
this.loading = true;
this.result = this.$post("/api/automation/export/jmx", param, response => {
this.loading = false;
let obj = response.data;
console.log(obj)
if (obj && obj.length > 0) {
obj.forEach(item => {
downloadFile(item.name + ".jmx", item.jmx);
})
}
});
},
buildApiPath(scenarios) { buildApiPath(scenarios) {
scenarios.forEach((scenario) => { scenarios.forEach((scenario) => {
this.moduleOptions.forEach(item => { this.moduleOptions.forEach(item => {

View File

@ -25,7 +25,8 @@
<el-dropdown-menu slot="dropdown"> <el-dropdown-menu slot="dropdown">
<el-dropdown-item command="add-scenario">{{ $t('api_test.automation.add_scenario') }}</el-dropdown-item> <el-dropdown-item command="add-scenario">{{ $t('api_test.automation.add_scenario') }}</el-dropdown-item>
<el-dropdown-item command="import">{{ $t('api_test.api_import.label') }}</el-dropdown-item> <el-dropdown-item command="import">{{ $t('api_test.api_import.label') }}</el-dropdown-item>
<el-dropdown-item command="export">{{ $t('report.export') }}</el-dropdown-item> <el-dropdown-item command="export">{{ $t('report.export') }}MS</el-dropdown-item>
<el-dropdown-item command="exportJmx">{{ $t('report.export') }}JMX</el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</el-dropdown> </el-dropdown>
</template> </template>
@ -33,14 +34,14 @@
<module-trash-button v-if="!isReadOnly" :condition="condition" :exe="enableTrash"/> <module-trash-button v-if="!isReadOnly" :condition="condition" :exe="enableTrash"/>
<!-- 是否保留这个 --> <!-- 是否保留这个 -->
<!--<api-scenario-module-header--> <!--<api-scenario-module-header-->
<!--:condition="condition"--> <!--:condition="condition"-->
<!--:current-module="currentModule"--> <!--:current-module="currentModule"-->
<!--:is-read-only="isReadOnly"--> <!--:is-read-only="isReadOnly"-->
<!--:project-id="projectId"--> <!--:project-id="projectId"-->
<!--@exportAPI="exportAPI"--> <!--@exportAPI="exportAPI"-->
<!--@addScenario="addScenario"--> <!--@addScenario="addScenario"-->
<!--@refreshTable="$emit('refreshTable')"--> <!--@refreshTable="$emit('refreshTable')"-->
<!--@refresh="refresh"/>--> <!--@refresh="refresh"/>-->
</template> </template>
</ms-node-tree> </ms-node-tree>
@ -56,27 +57,26 @@
</template> </template>
<script> <script>
import SelectMenu from "../../../track/common/SelectMenu"; import SelectMenu from "../../../track/common/SelectMenu";
import MsAddBasisScenario from "@/business/components/api/automation/scenario/AddBasisScenario"; import MsAddBasisScenario from "@/business/components/api/automation/scenario/AddBasisScenario";
import {getCurrentProjectID} from "@/common/js/utils"; import {getCurrentProjectID} from "@/common/js/utils";
import MsNodeTree from "../../../track/common/NodeTree"; import MsNodeTree from "../../../track/common/NodeTree";
import {buildNodePath} from "../../definition/model/NodeTree"; import {buildNodePath} from "../../definition/model/NodeTree";
import ModuleTrashButton from "../../definition/components/module/ModuleTrashButton"; import ModuleTrashButton from "../../definition/components/module/ModuleTrashButton";
import ApiScenarioModuleHeader from "@/business/components/api/automation/scenario/module/ApiScenarioModuleHeader"; import ApiImport from "./common/ScenarioImport";
import ApiImport from "./common/ScenarioImport";
export default { export default {
name: 'MsApiScenarioModule', name: 'MsApiScenarioModule',
components: { components: {
ApiImport, ApiImport,
ModuleTrashButton, ModuleTrashButton,
MsNodeTree, MsNodeTree,
MsAddBasisScenario, MsAddBasisScenario,
SelectMenu, SelectMenu,
}, },
props: { props: {
isReadOnly: { isReadOnly: {
type: Boolean, type: Boolean,
default() { default() {
return false return false
} }
@ -145,6 +145,9 @@ export default {
case "export": case "export":
this.$emit('exportAPI'); this.$emit('exportAPI');
break; break;
case "exportJmx":
this.$emit('exportJmx');
break;
} }
}, },
list() { list() {

View File

@ -2,13 +2,13 @@
<relevance-dialog :title="$t('api_test.automation.scenario_import')" ref="relevanceDialog"> <relevance-dialog :title="$t('api_test.automation.scenario_import')" ref="relevanceDialog">
<template v-slot:aside> <template v-slot:aside>
<ms-api-scenario-module <ms-api-scenario-module
@nodeSelectEvent="nodeChange" @nodeSelectEvent="nodeChange"
@refreshTable="refresh" @refreshTable="refresh"
@setModuleOptions="setModuleOptions" @setModuleOptions="setModuleOptions"
@enableTrash="false" @enableTrash="false"
:is-read-only="true" :is-read-only="true"
ref="nodeTree"/> ref="nodeTree"/>
</template> </template>
<ms-api-scenario-list <ms-api-scenario-list
@ -27,94 +27,98 @@
</template> </template>
<script> <script>
import ScenarioRelevanceCaseList from "./RelevanceCaseList"; import ScenarioRelevanceCaseList from "./RelevanceCaseList";
import MsApiModule from "../../../definition/components/module/ApiModule"; import MsApiModule from "../../../definition/components/module/ApiModule";
import MsContainer from "../../../../common/components/MsContainer"; import MsContainer from "../../../../common/components/MsContainer";
import MsAsideContainer from "../../../../common/components/MsAsideContainer"; import MsAsideContainer from "../../../../common/components/MsAsideContainer";
import MsMainContainer from "../../../../common/components/MsMainContainer"; import MsMainContainer from "../../../../common/components/MsMainContainer";
import ScenarioRelevanceApiList from "./RelevanceApiList"; import ScenarioRelevanceApiList from "./RelevanceApiList";
import MsApiScenarioModule from "../ApiScenarioModule"; import MsApiScenarioModule from "../ApiScenarioModule";
import MsApiScenarioList from "../ApiScenarioList"; import MsApiScenarioList from "../ApiScenarioList";
import {getUUID} from "../../../../../../common/js/utils"; import {getUUID} from "../../../../../../common/js/utils";
import RelevanceDialog from "../../../../track/plan/view/comonents/base/RelevanceDialog"; import RelevanceDialog from "../../../../track/plan/view/comonents/base/RelevanceDialog";
export default {
name: "ScenarioRelevance", export default {
components: { name: "ScenarioRelevance",
RelevanceDialog, components: {
MsApiScenarioList, RelevanceDialog,
MsApiScenarioModule, MsApiScenarioList,
MsMainContainer, MsAsideContainer, MsContainer}, MsApiScenarioModule,
data() { MsMainContainer, MsAsideContainer, MsContainer
return { },
result: {}, data() {
currentProtocol: null, return {
selectNodeIds: [], result: {},
moduleOptions: {}, currentProtocol: null,
isApiListEnable: true, selectNodeIds: [],
currentScenario: [], moduleOptions: {},
currentScenarioIds: [], isApiListEnable: true,
} currentScenario: [],
currentScenarioIds: [],
}
},
methods: {
reference() {
let scenarios = [];
if (!this.currentScenario || this.currentScenario.length < 1) {
this.$emit('请选择场景');
return;
}
this.currentScenario.forEach(item => {
let obj = {id: item.id, name: item.name, type: "scenario", referenced: 'REF', resourceId: getUUID()};
scenarios.push(obj);
});
this.$emit('save', scenarios);
this.close();
}, },
methods: { copy() {
reference() { let scenarios = [];
let scenarios = []; if (!this.currentScenarioIds || this.currentScenarioIds.length < 1) {
if (!this.currentScenario || this.currentScenario.length < 1) { this.$warning('请选择场景');
this.$emit('请选择场景'); return;
return; }
} this.result = this.$post("/api/automation/getApiScenarios/", this.currentScenarioIds, response => {
this.currentScenario.forEach(item => { if (response.data) {
let obj = {id: item.id, name: item.name, type: "scenario", referenced: 'REF', resourceId: getUUID()}; response.data.forEach(item => {
scenarios.push(obj); let scenarioDefinition = JSON.parse(item.scenarioDefinition);
}); if (scenarioDefinition && scenarioDefinition.hashTree) {
this.$emit('save', scenarios);
this.close();
},
copy() {
let scenarios = [];
if (!this.currentScenarioIds || this.currentScenarioIds.length < 1) {
this.$emit('请选择场景');
return;
}
this.result = this.$post("/api/automation/getApiScenarios/", this.currentScenarioIds, response => {
if (response.data) {
response.data.forEach(item => {
let scenarioDefinition = JSON.parse(item.scenarioDefinition);
let obj = {id: item.id, name: item.name, type: "scenario", referenced: 'Copy', resourceId: getUUID(), hashTree: scenarioDefinition.hashTree}; let obj = {id: item.id, name: item.name, type: "scenario", referenced: 'Copy', resourceId: getUUID(), hashTree: scenarioDefinition.hashTree};
scenarios.push(obj); scenarios.push(obj);
}); }
this.$emit('save', scenarios); });
this.close(); this.$emit('save', scenarios);
} this.close();
})
},
close() {
this.refresh();
this.$refs.relevanceDialog.close();
},
open() {
this.$refs.relevanceDialog.open();
if (this.$refs.apiScenarioList) {
this.$refs.apiScenarioList.search();
} }
}, })
nodeChange(node, nodeIds, pNodes) { },
this.selectNodeIds = nodeIds; close() {
}, this.refresh();
handleProtocolChange(protocol) { this.$refs.relevanceDialog.close();
this.currentProtocol = protocol; },
}, open() {
setModuleOptions(data) { this.$refs.relevanceDialog.open();
this.moduleOptions = data; if (this.$refs.apiScenarioList) {
}, this.$refs.apiScenarioList.search();
refresh() { }
this.$refs.apiScenarioList.search(); },
}, nodeChange(node, nodeIds, pNodes) {
setData(data) { this.selectNodeIds = nodeIds;
this.currentScenario = Array.from(data).map(row => row); },
this.currentScenarioIds = Array.from(data).map(row => row.id); handleProtocolChange(protocol) {
}, this.currentProtocol = protocol;
} },
setModuleOptions(data) {
this.moduleOptions = data;
},
refresh() {
this.$refs.apiScenarioList.search();
},
setData(data) {
this.currentScenario = Array.from(data).map(row => row);
this.currentScenarioIds = Array.from(data).map(row => row.id);
},
} }
}
</script> </script>
<style scoped> <style scoped>

View File

@ -1,5 +1,5 @@
<template> <template>
<el-dialog :close-on-click-modal="false" :title="$t('api_test.api_import.title')" width="30%" <el-dialog :close-on-click-modal="false" :title="$t('api_test.automation.scenario_import')" width="30%"
:visible.sync="visible" class="api-import" v-loading="result.loading" @close="close"> :visible.sync="visible" class="api-import" v-loading="result.loading" @close="close">
<div class="header-bar"> <div class="header-bar">

View File

@ -22,23 +22,23 @@
</template> </template>
<script> <script>
import MsSqlBasisParameters from "../../../definition/components/request/database/BasisParameters"; import MsSqlBasisParameters from "../../../definition/components/request/database/BasisParameters";
import MsTcpBasisParameters from "../../../definition/components/request/tcp/TcpBasisParameters"; import MsTcpBasisParameters from "../../../definition/components/request/tcp/TcpBasisParameters";
import MsDubboBasisParameters from "../../../definition/components/request/dubbo/BasisParameters"; import MsDubboBasisParameters from "../../../definition/components/request/dubbo/BasisParameters";
import MsApiRequestForm from "../../../definition/components/request/http/ApiHttpRequestForm"; import MsApiRequestForm from "../../../definition/components/request/http/ApiHttpRequestForm";
import ApiBaseComponent from "../common/ApiBaseComponent"; import ApiBaseComponent from "../common/ApiBaseComponent";
export default { export default {
name: "ApiScenarioComponent", name: "ApiScenarioComponent",
props: { props: {
scenario: {}, scenario: {},
node: {}, node: {},
draggable: { draggable: {
type: Boolean, type: Boolean,
default: false, default: false,
},
}, },
}, watch: {},
watch: {},
created() { created() {
if (this.scenario.id && this.scenario.referenced === 'REF' && !this.scenario.loaded) { if (this.scenario.id && this.scenario.referenced === 'REF' && !this.scenario.loaded) {
this.result = this.$get("/api/automation/getApiScenario/" + this.scenario.id, response => { this.result = this.$get("/api/automation/getApiScenario/" + this.scenario.id, response => {
@ -79,8 +79,10 @@ export default {
this.$emit('remove', this.scenario, this.node); this.$emit('remove', this.scenario, this.node);
}, },
active(item) { active(item) {
item.active = !item.active; if (item && item.active) {
this.reload(); item.active = !item.active;
this.reload();
}
}, },
copyRow() { copyRow() {
this.$emit('copyRow', this.scenario, this.node); this.$emit('copyRow', this.scenario, this.node);

View File

@ -1,83 +1,86 @@
<template> <template>
<el-form :model="config" :rules="rules" ref="config" label-width="100px" size="small" :disabled="isReadOnly"> <el-form :model="config" :rules="rules" ref="config" label-width="100px" size="small" :disabled="isReadOnly">
<div class="dubbo-form-description" v-if="description"> <el-row>
{{ description }} <div class="dubbo-form-description" v-if="description">
</div> {{ description }}
<el-form-item label="Protocol" prop="protocol" class="dubbo-form-item"> </div>
<el-select v-model="config.protocol" class="select-100" clearable> </el-row>
<el-option v-for="p in protocols" :key="p" :label="p" :value="p"/>
</el-select>
</el-form-item>
<el-form-item label="Group" prop="group" class="dubbo-form-item"> <el-row>
<el-input v-model="config.group" maxlength="300" show-word-limit <el-form-item label="Protocol" prop="protocol" class="dubbo-form-item">
:placeholder="$t('commons.input_content')"/> <el-select v-model="config.protocol" class="select-100" clearable>
</el-form-item> <el-option v-for="p in protocols" :key="p" :label="p" :value="p"/>
</el-select>
</el-form-item>
<el-form-item label="Group" prop="group" class="dubbo-form-item">
<el-input v-model="config.group" maxlength="300" show-word-limit
:placeholder="$t('commons.input_content')"/>
</el-form-item>
<el-form-item label="Namespace" prop="namespace" class="dubbo-form-item">
<el-input v-model="config.namespace" maxlength="300" show-word-limit
:placeholder="$t('commons.input_content')"/>
</el-form-item>
<el-form-item label="Timeout" prop="timeout" class="dubbo-form-item">
<el-input type="number" v-model="config.timeout" :placeholder="$t('commons.input_content')"/>
</el-form-item>
</el-row>
<el-row>
<el-form-item label="Address" prop="address" class="dubbo-form-item-long">
<el-input v-model="config.address" maxlength="300" show-word-limit
:placeholder="$t('commons.input_content')"/>
</el-form-item>
<el-form-item label="Namespace" prop="namespace" class="dubbo-form-item"> <el-form-item label="UserName" prop="username" class="dubbo-form-item">
<el-input v-model="config.namespace" maxlength="300" show-word-limit <el-input v-model="config.username" maxlength="100" show-word-limit
:placeholder="$t('commons.input_content')"/> :placeholder="$t('commons.input_content')"/>
</el-form-item> </el-form-item>
<el-form-item label="Timeout" prop="timeout" class="dubbo-form-item">
<el-input type="number" v-model="config.timeout" :placeholder="$t('commons.input_content')"/>
</el-form-item>
<el-form-item label="Address" prop="address" class="dubbo-form-item-long">
<el-input v-model="config.address" maxlength="300" show-word-limit
:placeholder="$t('commons.input_content')"/>
</el-form-item>
<el-form-item label="UserName" prop="username" class="dubbo-form-item">
<el-input v-model="config.username" maxlength="100" show-word-limit
:placeholder="$t('commons.input_content')"/>
</el-form-item>
<el-form-item label="Password" prop="password" class="dubbo-form-item">
<el-input v-model="config.password" maxlength="30" show-word-limit show-password autocomplete="new-password"
:placeholder="$t('commons.input_content')"/>
</el-form-item>
<el-form-item label="Password" prop="password" class="dubbo-form-item">
<el-input v-model="config.password" maxlength="30" show-word-limit show-password autocomplete="new-password"
:placeholder="$t('commons.input_content')"/>
</el-form-item>
</el-row>
</el-form> </el-form>
</template> </template>
<script> <script>
import './dubbo.css' import './dubbo.css'
import {ConfigCenter} from "@/business/components/api/definition/model/ApiTestModel"; import {ConfigCenter} from "@/business/components/api/definition/model/ApiTestModel";
export default { export default {
name: "MsDubboConfigCenter", name: "MsDubboConfigCenter",
props: { props: {
description: String, description: String,
config: {}, config: {},
isReadOnly: { isReadOnly: {
type: Boolean, type: Boolean,
default: false default: false
} }
}, },
data() { data() {
return { return {
protocols: ConfigCenter.PROTOCOLS, protocols: ConfigCenter.PROTOCOLS,
methods: [], methods: [],
rules: { rules: {
group: [ group: [
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'} {max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
], ],
namespace: [ namespace: [
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'} {max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
], ],
username: [ username: [
{max: 100, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'} {max: 100, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
], ],
password: [ password: [
{max: 30, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'} {max: 30, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
], ],
address: [ address: [
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'} {max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
] ]
}
} }
} }
} }
}
</script> </script>

View File

@ -1,82 +1,86 @@
<template> <template>
<el-form :model="consumer" :rules="rules" ref="consumer" label-width="100px" size="small" :disabled="isReadOnly"> <el-form :model="consumer" :rules="rules" ref="consumer" label-width="100px" size="small" :disabled="isReadOnly">
<div class="dubbo-form-description" v-if="description"> <el-row>
{{ description }} <div class="dubbo-form-description" v-if="description">
</div> {{ description }}
<el-form-item label="Timeout" prop="timeout" class="dubbo-form-item"> </div>
<el-input type="number" v-model="consumer.timeout" :placeholder="$t('commons.input_content')"/> </el-row>
</el-form-item> <el-row>
<el-form-item label="Timeout" prop="timeout" class="dubbo-form-item">
<el-input type="number" v-model="consumer.timeout" :placeholder="$t('commons.input_content')"/>
</el-form-item>
<el-form-item label="Version" prop="version" class="dubbo-form-item">
<el-input v-model="consumer.version" maxlength="30" show-word-limit
:placeholder="$t('commons.input_content')"/>
</el-form-item>
<el-form-item label="Version" prop="version" class="dubbo-form-item"> <el-form-item label="Retries" prop="retries" class="dubbo-form-item">
<el-input v-model="consumer.version" maxlength="30" show-word-limit <el-input type="number" v-model="consumer.retries" :placeholder="$t('commons.input_content')"/>
:placeholder="$t('commons.input_content')"/> </el-form-item>
</el-form-item>
<el-form-item label="Retries" prop="retries" class="dubbo-form-item"> <el-form-item label="Cluster" prop="cluster" class="dubbo-form-item">
<el-input type="number" v-model="consumer.retries" :placeholder="$t('commons.input_content')"/> <el-input v-model="consumer.cluster" maxlength="300" show-word-limit
</el-form-item> :placeholder="$t('commons.input_content')"/>
</el-form-item>
</el-row>
<el-row>
<el-form-item label="Group" prop="group" class="dubbo-form-item">
<el-input v-model="consumer.group" maxlength="300" show-word-limit
:placeholder="$t('commons.input_content')"/>
</el-form-item>
<el-form-item label="Cluster" prop="cluster" class="dubbo-form-item"> <el-form-item label="Connections" prop="connections" class="dubbo-form-item">
<el-input v-model="consumer.cluster" maxlength="300" show-word-limit <el-input type="number" v-model="consumer.connections" :placeholder="$t('commons.input_content')"/>
:placeholder="$t('commons.input_content')"/> </el-form-item>
</el-form-item>
<el-form-item label="Group" prop="group" class="dubbo-form-item"> <el-form-item label="Async" prop="async" class="dubbo-form-item">
<el-input v-model="consumer.group" maxlength="300" show-word-limit <el-select v-model="consumer.async" class="select-100" clearable>
:placeholder="$t('commons.input_content')"/> <el-option v-for="option in asyncOptions" :key="option" :label="option" :value="option"/>
</el-form-item> </el-select>
</el-form-item>
<el-form-item label="Connections" prop="connections" class="dubbo-form-item"> <el-form-item label="LoadBalance" prop="loadBalance" class="dubbo-form-item">
<el-input type="number" v-model="consumer.connections" :placeholder="$t('commons.input_content')"/> <el-select v-model="consumer.loadBalance" class="select-100" clearable>
</el-form-item> <el-option v-for="option in loadBalances" :key="option" :label="option" :value="option"/>
</el-select>
<el-form-item label="Async" prop="async" class="dubbo-form-item"> </el-form-item>
<el-select v-model="consumer.async" class="select-100" clearable> </el-row>
<el-option v-for="option in asyncOptions" :key="option" :label="option" :value="option"/>
</el-select>
</el-form-item>
<el-form-item label="LoadBalance" prop="loadBalance" class="dubbo-form-item">
<el-select v-model="consumer.loadBalance" class="select-100" clearable>
<el-option v-for="option in loadBalances" :key="option" :label="option" :value="option"/>
</el-select>
</el-form-item>
</el-form> </el-form>
</template> </template>
<script> <script>
import './dubbo.css' import './dubbo.css'
import {ConsumerAndService, RegistryCenter} from "@/business/components/api/definition/model/ApiTestModel"; import {ConsumerAndService, RegistryCenter} from "@/business/components/api/definition/model/ApiTestModel";
export default { export default {
name: "MsDubboConsumerService", name: "MsDubboConsumerService",
props: { props: {
description: String, description: String,
consumer: {}, consumer: {},
isReadOnly: { isReadOnly: {
type: Boolean, type: Boolean,
default: false default: false
} }
}, },
data() { data() {
return { return {
asyncOptions: ConsumerAndService.ASYNC_OPTIONS, asyncOptions: ConsumerAndService.ASYNC_OPTIONS,
loadBalances: ConsumerAndService.LOAD_BALANCE_OPTIONS, loadBalances: ConsumerAndService.LOAD_BALANCE_OPTIONS,
methods: [], methods: [],
rules: { rules: {
version: [ version: [
{max: 30, message: this.$t('commons.input_limit', [0, 30]), trigger: 'blur'} {max: 30, message: this.$t('commons.input_limit', [0, 30]), trigger: 'blur'}
], ],
cluster: [ cluster: [
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'} {max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
], ],
group: [ group: [
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'} {max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
] ]
}
} }
} }
} }
}
</script> </script>

View File

@ -117,7 +117,7 @@
<style scoped> <style scoped>
.get-provider { .get-provider {
margin-bottom: 22px; margin: 5px 5px 10px;
} }
.select-100 { .select-100 {

View File

@ -1,73 +1,78 @@
<template> <template>
<el-form :model="registry" :rules="rules" ref="registry" label-width="100px" size="small" :disabled="isReadOnly"> <el-form :model="registry" :rules="rules" ref="registry" label-width="100px" size="small" :disabled="isReadOnly">
<div class="dubbo-form-description" v-if="description"> <el-row>
{{ description }} <div class="dubbo-form-description" v-if="description">
</div> {{ description }}
<el-form-item label="Protocol" prop="protocol" class="dubbo-form-item"> </div>
<el-select v-model="registry.protocol" class="select-100" clearable> </el-row>
<el-option v-for="p in protocols" :key="p" :label="p" :value="p"/> <el-row>
</el-select> <el-form-item label="Protocol" prop="protocol" class="dubbo-form-item">
</el-form-item> <el-select v-model="registry.protocol" class="select-100" clearable>
<el-option v-for="p in protocols" :key="p" :label="p" :value="p"/>
</el-select>
</el-form-item>
<el-form-item label="Group" prop="group" class="dubbo-form-item"> <el-form-item label="Group" prop="group" class="dubbo-form-item">
<el-input v-model="registry.group" maxlength="300" show-word-limit <el-input v-model="registry.group" maxlength="300" show-word-limit
:placeholder="$t('commons.input_content')"/> :placeholder="$t('commons.input_content')"/>
</el-form-item> </el-form-item>
<el-form-item label="UserName" prop="username" class="dubbo-form-item"> <el-form-item label="UserName" prop="username" class="dubbo-form-item">
<el-input v-model="registry.username" maxlength="100" show-word-limit <el-input v-model="registry.username" maxlength="100" show-word-limit
:placeholder="$t('commons.input_content')"/> :placeholder="$t('commons.input_content')"/>
</el-form-item> </el-form-item>
<el-form-item label="Password" prop="password" class="dubbo-form-item"> <el-form-item label="Password" prop="password" class="dubbo-form-item">
<el-input v-model="registry.password" maxlength="30" show-word-limit show-password autocomplete="new-password" <el-input v-model="registry.password" maxlength="30" show-word-limit show-password autocomplete="new-password"
:placeholder="$t('commons.input_content')"/> :placeholder="$t('commons.input_content')"/>
</el-form-item> </el-form-item>
</el-row>
<el-row>
<el-form-item label="Address" prop="address" class="dubbo-form-item-long">
<el-input v-model="registry.address" maxlength="300" show-word-limit
:placeholder="$t('commons.input_content')"/>
</el-form-item>
<el-form-item label="Address" prop="address" class="dubbo-form-item-long"> <el-form-item label="Timeout" prop="timeout" class="dubbo-form-item">
<el-input v-model="registry.address" maxlength="300" show-word-limit <el-input type="number" v-model="registry.timeout" :placeholder="$t('commons.input_content')"/>
:placeholder="$t('commons.input_content')"/> </el-form-item>
</el-form-item> </el-row>
<el-form-item label="Timeout" prop="timeout" class="dubbo-form-item">
<el-input type="number" v-model="registry.timeout" :placeholder="$t('commons.input_content')"/>
</el-form-item>
</el-form> </el-form>
</template> </template>
<script> <script>
import './dubbo.css' import './dubbo.css'
import {RegistryCenter} from "@/business/components/api/definition/model/ApiTestModel"; import {RegistryCenter} from "@/business/components/api/definition/model/ApiTestModel";
export default { export default {
name: "MsDubboRegistryCenter", name: "MsDubboRegistryCenter",
props: { props: {
description: String, description: String,
registry: {}, registry: {},
isReadOnly: { isReadOnly: {
type: Boolean, type: Boolean,
default: false default: false
} }
}, },
data() { data() {
return { return {
protocols: RegistryCenter.PROTOCOLS, protocols: RegistryCenter.PROTOCOLS,
methods: [], methods: [],
rules: { rules: {
group: [ group: [
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'} {max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
], ],
username: [ username: [
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'} {max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
], ],
password: [ password: [
{max: 30, message: this.$t('commons.input_limit', [0, 30]), trigger: 'blur'} {max: 30, message: this.$t('commons.input_limit', [0, 30]), trigger: 'blur'}
], ],
address: [ address: [
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'} {max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
] ]
}
} }
} }
} }
}
</script> </script>