Merge remote-tracking branch 'origin/master'
# Conflicts: # backend/src/main/java/io/metersphere/xpack
This commit is contained in:
commit
cadcf9eb7b
|
@ -187,6 +187,12 @@ v1.1.0 是 v1.0.0 之后的功能版本。
|
||||||
- 基础设施: [Docker](https://www.docker.com/), [Kubernetes](https://kubernetes.io/)
|
- 基础设施: [Docker](https://www.docker.com/), [Kubernetes](https://kubernetes.io/)
|
||||||
- 测试引擎: [JMeter](https://jmeter.apache.org/)
|
- 测试引擎: [JMeter](https://jmeter.apache.org/)
|
||||||
|
|
||||||
|
## 致谢
|
||||||
|
|
||||||
|
- [BlazeMeter](https://www.blazemeter.com/):感谢 BlazeMeter 提供的设计思路
|
||||||
|
- [JMeter](https://jmeter.apache.org/):MeterSphere 使用了 JMeter 作为测试引擎
|
||||||
|
- [Element](https://element.eleme.cn/#/):感谢 Element 提供的优秀组件库
|
||||||
|
|
||||||
## 加入 MeterSphere 团队
|
## 加入 MeterSphere 团队
|
||||||
|
|
||||||
我们正在招聘 MeterSphere 技术布道师,一起打造开源明星项目,请发简历到 metersphere@fit2cloud.com
|
我们正在招聘 MeterSphere 技术布道师,一起打造开源明星项目,请发简历到 metersphere@fit2cloud.com
|
||||||
|
|
|
@ -32,3 +32,4 @@ target
|
||||||
.project
|
.project
|
||||||
.classpath
|
.classpath
|
||||||
.factorypath
|
.factorypath
|
||||||
|
*.jar
|
|
@ -140,11 +140,6 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- jmeter -->
|
<!-- jmeter -->
|
||||||
<!-- <dependency>-->
|
|
||||||
<!-- <groupId>org.apache.jmeter</groupId>-->
|
|
||||||
<!-- <artifactId>ApacheJMeter_core</artifactId>-->
|
|
||||||
<!-- <version>${jmeter.version}</version>-->
|
|
||||||
<!-- </dependency>-->
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.jmeter</groupId>
|
<groupId>org.apache.jmeter</groupId>
|
||||||
|
@ -272,6 +267,24 @@
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- buji-pac4j -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.pac4j</groupId>
|
||||||
|
<artifactId>pac4j-cas</artifactId>
|
||||||
|
<version>3.0.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.buji</groupId>
|
||||||
|
<artifactId>buji-pac4j</artifactId>
|
||||||
|
<version>4.0.0</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>shiro-web</artifactId>
|
||||||
|
<groupId>org.apache.shiro</groupId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -356,6 +369,16 @@
|
||||||
<version>2.6</version>
|
<version>2.6</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/jmeter/lib/**/*.jar</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-antrun-plugin</artifactId>
|
<artifactId>maven-antrun-plugin</artifactId>
|
||||||
|
@ -383,6 +406,35 @@
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>copy</id>
|
||||||
|
<phase>generate-resources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<artifactItems>
|
||||||
|
<artifactItem>
|
||||||
|
<groupId>org.apache.jmeter</groupId>
|
||||||
|
<artifactId>ApacheJMeter_functions</artifactId>
|
||||||
|
<version>${jmeter.version}</version>
|
||||||
|
<type>jar</type>
|
||||||
|
<overWrite>true</overWrite>
|
||||||
|
<outputDirectory>src/main/resources/jmeter/lib/ext</outputDirectory>
|
||||||
|
<destFileName>ApacheJMeter_functions.jar</destFileName>
|
||||||
|
</artifactItem>
|
||||||
|
</artifactItems>
|
||||||
|
<outputDirectory>${project.build.directory}/wars</outputDirectory>
|
||||||
|
<overWriteReleases>false</overWriteReleases>
|
||||||
|
<overWriteSnapshots>true</overWriteSnapshots>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.mybatis.generator</groupId>
|
<groupId>org.mybatis.generator</groupId>
|
||||||
<artifactId>mybatis-generator-maven-plugin</artifactId>
|
<artifactId>mybatis-generator-maven-plugin</artifactId>
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package io.metersphere.api.dto.scenario.processor;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class BeanShellPostProcessor extends BeanShellProcessor {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package io.metersphere.api.dto.scenario.processor;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class BeanShellPreProcessor extends BeanShellProcessor {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package io.metersphere.api.dto.scenario.processor;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class BeanShellProcessor {
|
||||||
|
private String script;
|
||||||
|
}
|
|
@ -6,6 +6,8 @@ import io.metersphere.api.dto.scenario.Body;
|
||||||
import io.metersphere.api.dto.scenario.KeyValue;
|
import io.metersphere.api.dto.scenario.KeyValue;
|
||||||
import io.metersphere.api.dto.scenario.assertions.Assertions;
|
import io.metersphere.api.dto.scenario.assertions.Assertions;
|
||||||
import io.metersphere.api.dto.scenario.extract.Extract;
|
import io.metersphere.api.dto.scenario.extract.Extract;
|
||||||
|
import io.metersphere.api.dto.scenario.processor.BeanShellPostProcessor;
|
||||||
|
import io.metersphere.api.dto.scenario.processor.BeanShellPreProcessor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -35,4 +37,8 @@ public class HttpRequest implements Request {
|
||||||
private Assertions assertions;
|
private Assertions assertions;
|
||||||
@JSONField(ordinal = 10)
|
@JSONField(ordinal = 10)
|
||||||
private Extract extract;
|
private Extract extract;
|
||||||
|
@JSONField(ordinal = 11)
|
||||||
|
private BeanShellPreProcessor beanShellPreProcessor;
|
||||||
|
@JSONField(ordinal = 12)
|
||||||
|
private BeanShellPostProcessor beanShellPostProcessor;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.apache.jorphan.collections.HashTree;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
@ -24,7 +25,8 @@ public class JMeterService {
|
||||||
private JmeterProperties jmeterProperties;
|
private JmeterProperties jmeterProperties;
|
||||||
|
|
||||||
public void run(String testId, String debugReportId, InputStream is) {
|
public void run(String testId, String debugReportId, InputStream is) {
|
||||||
String JMETER_HOME = jmeterProperties.getHome();
|
String JMETER_HOME = getJmeterHome();
|
||||||
|
|
||||||
String JMETER_PROPERTIES = JMETER_HOME + "/bin/jmeter.properties";
|
String JMETER_PROPERTIES = JMETER_HOME + "/bin/jmeter.properties";
|
||||||
JMeterUtils.loadJMeterProperties(JMETER_PROPERTIES);
|
JMeterUtils.loadJMeterProperties(JMETER_PROPERTIES);
|
||||||
JMeterUtils.setJMeterHome(JMETER_HOME);
|
JMeterUtils.setJMeterHome(JMETER_HOME);
|
||||||
|
@ -41,6 +43,20 @@ public class JMeterService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getJmeterHome() {
|
||||||
|
String home = getClass().getResource("/").getPath() + "jmeter";
|
||||||
|
try {
|
||||||
|
File file = new File(home);
|
||||||
|
if (file.exists()) {
|
||||||
|
return home;
|
||||||
|
} else {
|
||||||
|
return jmeterProperties.getHome();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return jmeterProperties.getHome();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private HashTree getHashTree(Object scriptWrapper) throws Exception {
|
private HashTree getHashTree(Object scriptWrapper) throws Exception {
|
||||||
Field field = scriptWrapper.getClass().getDeclaredField("testPlan");
|
Field field = scriptWrapper.getClass().getDeclaredField("testPlan");
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
|
|
|
@ -0,0 +1,222 @@
|
||||||
|
package io.metersphere.api.parse;
|
||||||
|
|
||||||
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
|
import io.metersphere.commons.utils.ScriptEngineUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
import org.xml.sax.InputSource;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.transform.Transformer;
|
||||||
|
import javax.xml.transform.TransformerException;
|
||||||
|
import javax.xml.transform.TransformerFactory;
|
||||||
|
import javax.xml.transform.dom.DOMSource;
|
||||||
|
import javax.xml.transform.stream.StreamResult;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class JmeterDocumentParser {
|
||||||
|
private final static String HASH_TREE_ELEMENT = "hashTree";
|
||||||
|
private final static String STRING_PROP = "stringProp";
|
||||||
|
private final static String ARGUMENTS = "Arguments";
|
||||||
|
private final static String COLLECTION_PROP = "collectionProp";
|
||||||
|
private final static String HTTP_SAMPLER_PROXY = "HTTPSamplerProxy";
|
||||||
|
private final static String ELEMENT_PROP = "elementProp";
|
||||||
|
|
||||||
|
public static byte[] parse(byte[] source) {
|
||||||
|
|
||||||
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||||
|
try (
|
||||||
|
ByteArrayInputStream byteStream = new ByteArrayInputStream(source)
|
||||||
|
) {
|
||||||
|
InputSource inputSource = new InputSource(byteStream);
|
||||||
|
DocumentBuilder docBuilder = factory.newDocumentBuilder();
|
||||||
|
final Document document = docBuilder.parse(inputSource);
|
||||||
|
final Element jmeterTestPlan = document.getDocumentElement();
|
||||||
|
|
||||||
|
NodeList childNodes = jmeterTestPlan.getChildNodes();
|
||||||
|
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||||
|
Node node = childNodes.item(i);
|
||||||
|
if (node instanceof Element) {
|
||||||
|
Element ele = (Element) node;
|
||||||
|
parseHashTree(ele);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return documentToBytes(document);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.error(e);
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] documentToBytes(Document document) throws TransformerException {
|
||||||
|
DOMSource domSource = new DOMSource(document);
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
StreamResult result = new StreamResult(writer);
|
||||||
|
TransformerFactory tf = TransformerFactory.newInstance();
|
||||||
|
Transformer transformer = tf.newTransformer();
|
||||||
|
transformer.transform(domSource, result);
|
||||||
|
return writer.toString().getBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void parseHashTree(Element hashTree) {
|
||||||
|
if (invalid(hashTree)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hashTree.getChildNodes().getLength() > 0) {
|
||||||
|
final NodeList childNodes = hashTree.getChildNodes();
|
||||||
|
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||||
|
Node node = childNodes.item(i);
|
||||||
|
if (node instanceof Element) {
|
||||||
|
Element ele = (Element) node;
|
||||||
|
if (invalid(ele)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nodeNameEquals(ele, HASH_TREE_ELEMENT)) {
|
||||||
|
parseHashTree(ele);
|
||||||
|
} else if (nodeNameEquals(ele, ARGUMENTS)) {
|
||||||
|
processArguments(ele);
|
||||||
|
} else if (nodeNameEquals(ele, HTTP_SAMPLER_PROXY)) {
|
||||||
|
processHttpSamplerProxy(ele);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void processHttpSamplerProxy(Element ele) {
|
||||||
|
if (invalid(ele)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
NodeList childNodes = ele.getChildNodes();
|
||||||
|
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||||
|
Node item = childNodes.item(i);
|
||||||
|
if (!(item instanceof Element)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Element element = (Element) item;
|
||||||
|
if (nodeNameEquals(element, ELEMENT_PROP) && "HTTPsampler.Arguments".equals(element.getAttribute("name"))) {
|
||||||
|
processArguments(element);
|
||||||
|
} else if ("HTTPSampler.path".equals(element.getAttribute("name"))) {
|
||||||
|
processStringProp(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void processArguments(Element ele) {
|
||||||
|
if (invalid(ele)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
NodeList childNodes = ele.getChildNodes();
|
||||||
|
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||||
|
Node item = childNodes.item(i);
|
||||||
|
if (!(item instanceof Element)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Element element = (Element) item;
|
||||||
|
if (nodeNameEquals(item, COLLECTION_PROP) && "Arguments.arguments".equals(element.getAttribute("name"))) {
|
||||||
|
NodeList elementProps = item.getChildNodes();
|
||||||
|
for (int j = 0; j < elementProps.getLength(); j++) {
|
||||||
|
Node elementProp = elementProps.item(j);
|
||||||
|
if (!(elementProp instanceof Element)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
NodeList stringProps = elementProp.getChildNodes();
|
||||||
|
for (int k = 0; k < stringProps.getLength(); k++) {
|
||||||
|
Node stringProp = stringProps.item(k);
|
||||||
|
if (!(stringProp instanceof Element)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
processStringProp((Element) stringProp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void processStringProp(Element ele) {
|
||||||
|
String name = ele.getAttribute("name");
|
||||||
|
switch (name) {
|
||||||
|
case "HTTPSampler.path":
|
||||||
|
String path = ele.getTextContent();
|
||||||
|
Map<String, String> parser = parserUrl(path);
|
||||||
|
String url = parser.get("URL");
|
||||||
|
String params = parser.keySet().stream().filter(k -> !"URL".equals(k)).reduce("", (u, k) -> {
|
||||||
|
String v = parser.get(k);
|
||||||
|
u += "&" + k + "=" + ScriptEngineUtils.calculate(v);
|
||||||
|
return u;
|
||||||
|
});
|
||||||
|
ele.setTextContent(url + params);
|
||||||
|
break;
|
||||||
|
case "Argument.value":
|
||||||
|
String textContent = ele.getTextContent();
|
||||||
|
ele.setTextContent(ScriptEngineUtils.calculate(textContent));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean nodeNameEquals(Node node, String desiredName) {
|
||||||
|
return desiredName.equals(node.getNodeName()) || desiredName.equals(node.getLocalName());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean invalid(Element ele) {
|
||||||
|
return !StringUtils.isBlank(ele.getAttribute("enabled")) && !Boolean.parseBoolean(ele.getAttribute("enabled"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, String> parserUrl(String url) {
|
||||||
|
// 传递的URL参数
|
||||||
|
Map<String, String> strUrlParas = new HashMap<>();
|
||||||
|
|
||||||
|
String strUrl;
|
||||||
|
String strUrlParams;
|
||||||
|
|
||||||
|
|
||||||
|
// 解析访问地址
|
||||||
|
if (url.contains("?")) {
|
||||||
|
String[] strUrlPatten = url.split("\\?");
|
||||||
|
strUrl = strUrlPatten[0];
|
||||||
|
strUrlParams = strUrlPatten[1];
|
||||||
|
|
||||||
|
} else {
|
||||||
|
strUrl = url;
|
||||||
|
strUrlParams = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
strUrlParas.put("URL", strUrl);
|
||||||
|
// 解析参数
|
||||||
|
String[] params = null;
|
||||||
|
|
||||||
|
if (strUrlParams.contains("&")) {
|
||||||
|
params = strUrlParams.split("&");
|
||||||
|
} else {
|
||||||
|
params = new String[]{strUrlParams};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存参数到参数容器
|
||||||
|
for (String p : params) {
|
||||||
|
if (p.contains("=")) {
|
||||||
|
String[] param = p.split("=");
|
||||||
|
if (param.length == 1) {
|
||||||
|
strUrlParas.put(param[0], "");
|
||||||
|
} else {
|
||||||
|
|
||||||
|
String key = param[0];
|
||||||
|
String value = param[1];
|
||||||
|
|
||||||
|
strUrlParas.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strUrlParas;
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,11 +8,15 @@ import io.metersphere.api.dto.scenario.request.dubbo.RegistryCenter;
|
||||||
import io.metersphere.api.jmeter.JMeterService;
|
import io.metersphere.api.jmeter.JMeterService;
|
||||||
import io.metersphere.api.parse.ApiImportParser;
|
import io.metersphere.api.parse.ApiImportParser;
|
||||||
import io.metersphere.api.parse.ApiImportParserFactory;
|
import io.metersphere.api.parse.ApiImportParserFactory;
|
||||||
|
import io.metersphere.api.parse.JmeterDocumentParser;
|
||||||
import io.metersphere.base.domain.*;
|
import io.metersphere.base.domain.*;
|
||||||
import io.metersphere.base.mapper.ApiTestFileMapper;
|
import io.metersphere.base.mapper.ApiTestFileMapper;
|
||||||
import io.metersphere.base.mapper.ApiTestMapper;
|
import io.metersphere.base.mapper.ApiTestMapper;
|
||||||
import io.metersphere.base.mapper.ext.ExtApiTestMapper;
|
import io.metersphere.base.mapper.ext.ExtApiTestMapper;
|
||||||
import io.metersphere.commons.constants.*;
|
import io.metersphere.commons.constants.APITestStatus;
|
||||||
|
import io.metersphere.commons.constants.FileType;
|
||||||
|
import io.metersphere.commons.constants.ScheduleGroup;
|
||||||
|
import io.metersphere.commons.constants.ScheduleType;
|
||||||
import io.metersphere.commons.exception.MSException;
|
import io.metersphere.commons.exception.MSException;
|
||||||
import io.metersphere.commons.utils.BeanUtils;
|
import io.metersphere.commons.utils.BeanUtils;
|
||||||
import io.metersphere.commons.utils.LogUtil;
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
|
@ -145,6 +149,8 @@ public class APITestService {
|
||||||
MSException.throwException(Translator.get("file_cannot_be_null"));
|
MSException.throwException(Translator.get("file_cannot_be_null"));
|
||||||
}
|
}
|
||||||
byte[] bytes = fileService.loadFileAsBytes(file.getFileId());
|
byte[] bytes = fileService.loadFileAsBytes(file.getFileId());
|
||||||
|
// 解析 xml 处理 mock 数据
|
||||||
|
bytes = JmeterDocumentParser.parse(bytes);
|
||||||
InputStream is = new ByteArrayInputStream(bytes);
|
InputStream is = new ByteArrayInputStream(bytes);
|
||||||
|
|
||||||
APITestResult apiTest = get(request.getId());
|
APITestResult apiTest = get(request.getId());
|
||||||
|
@ -338,7 +344,10 @@ public class APITestService {
|
||||||
|
|
||||||
InputStream is = null;
|
InputStream is = null;
|
||||||
try {
|
try {
|
||||||
is = new ByteArrayInputStream(file.getBytes());
|
byte[] bytes = file.getBytes();
|
||||||
|
// 解析 xml 处理 mock 数据
|
||||||
|
bytes = JmeterDocumentParser.parse(bytes);
|
||||||
|
is = new ByteArrayInputStream(bytes);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package io.metersphere.base.domain;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Issues implements Serializable {
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
private Long createTime;
|
||||||
|
|
||||||
|
private Long updateTime;
|
||||||
|
|
||||||
|
private String reporter;
|
||||||
|
|
||||||
|
private String lastmodify;
|
||||||
|
|
||||||
|
private String platform;
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
|
@ -0,0 +1,740 @@
|
||||||
|
package io.metersphere.base.domain;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class IssuesExample {
|
||||||
|
protected String orderByClause;
|
||||||
|
|
||||||
|
protected boolean distinct;
|
||||||
|
|
||||||
|
protected List<Criteria> oredCriteria;
|
||||||
|
|
||||||
|
public IssuesExample() {
|
||||||
|
oredCriteria = new ArrayList<Criteria>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrderByClause(String orderByClause) {
|
||||||
|
this.orderByClause = orderByClause;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrderByClause() {
|
||||||
|
return orderByClause;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDistinct(boolean distinct) {
|
||||||
|
this.distinct = distinct;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDistinct() {
|
||||||
|
return distinct;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Criteria> getOredCriteria() {
|
||||||
|
return oredCriteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void or(Criteria criteria) {
|
||||||
|
oredCriteria.add(criteria);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria or() {
|
||||||
|
Criteria criteria = createCriteriaInternal();
|
||||||
|
oredCriteria.add(criteria);
|
||||||
|
return criteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria createCriteria() {
|
||||||
|
Criteria criteria = createCriteriaInternal();
|
||||||
|
if (oredCriteria.size() == 0) {
|
||||||
|
oredCriteria.add(criteria);
|
||||||
|
}
|
||||||
|
return criteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Criteria createCriteriaInternal() {
|
||||||
|
Criteria criteria = new Criteria();
|
||||||
|
return criteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
oredCriteria.clear();
|
||||||
|
orderByClause = null;
|
||||||
|
distinct = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract static class GeneratedCriteria {
|
||||||
|
protected List<Criterion> criteria;
|
||||||
|
|
||||||
|
protected GeneratedCriteria() {
|
||||||
|
super();
|
||||||
|
criteria = new ArrayList<Criterion>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValid() {
|
||||||
|
return criteria.size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Criterion> getAllCriteria() {
|
||||||
|
return criteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Criterion> getCriteria() {
|
||||||
|
return criteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addCriterion(String condition) {
|
||||||
|
if (condition == null) {
|
||||||
|
throw new RuntimeException("Value for condition cannot be null");
|
||||||
|
}
|
||||||
|
criteria.add(new Criterion(condition));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addCriterion(String condition, Object value, String property) {
|
||||||
|
if (value == null) {
|
||||||
|
throw new RuntimeException("Value for " + property + " cannot be null");
|
||||||
|
}
|
||||||
|
criteria.add(new Criterion(condition, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addCriterion(String condition, Object value1, Object value2, String property) {
|
||||||
|
if (value1 == null || value2 == null) {
|
||||||
|
throw new RuntimeException("Between values for " + property + " cannot be null");
|
||||||
|
}
|
||||||
|
criteria.add(new Criterion(condition, value1, value2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdIsNull() {
|
||||||
|
addCriterion("id is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdIsNotNull() {
|
||||||
|
addCriterion("id is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdEqualTo(String value) {
|
||||||
|
addCriterion("id =", value, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdNotEqualTo(String value) {
|
||||||
|
addCriterion("id <>", value, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdGreaterThan(String value) {
|
||||||
|
addCriterion("id >", value, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("id >=", value, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdLessThan(String value) {
|
||||||
|
addCriterion("id <", value, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("id <=", value, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdLike(String value) {
|
||||||
|
addCriterion("id like", value, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdNotLike(String value) {
|
||||||
|
addCriterion("id not like", value, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdIn(List<String> values) {
|
||||||
|
addCriterion("id in", values, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdNotIn(List<String> values) {
|
||||||
|
addCriterion("id not in", values, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdBetween(String value1, String value2) {
|
||||||
|
addCriterion("id between", value1, value2, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("id not between", value1, value2, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTitleIsNull() {
|
||||||
|
addCriterion("title is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTitleIsNotNull() {
|
||||||
|
addCriterion("title is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTitleEqualTo(String value) {
|
||||||
|
addCriterion("title =", value, "title");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTitleNotEqualTo(String value) {
|
||||||
|
addCriterion("title <>", value, "title");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTitleGreaterThan(String value) {
|
||||||
|
addCriterion("title >", value, "title");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTitleGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("title >=", value, "title");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTitleLessThan(String value) {
|
||||||
|
addCriterion("title <", value, "title");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTitleLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("title <=", value, "title");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTitleLike(String value) {
|
||||||
|
addCriterion("title like", value, "title");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTitleNotLike(String value) {
|
||||||
|
addCriterion("title not like", value, "title");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTitleIn(List<String> values) {
|
||||||
|
addCriterion("title in", values, "title");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTitleNotIn(List<String> values) {
|
||||||
|
addCriterion("title not in", values, "title");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTitleBetween(String value1, String value2) {
|
||||||
|
addCriterion("title between", value1, value2, "title");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andTitleNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("title not between", value1, value2, "title");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusIsNull() {
|
||||||
|
addCriterion("`status` is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusIsNotNull() {
|
||||||
|
addCriterion("`status` is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusEqualTo(String value) {
|
||||||
|
addCriterion("`status` =", value, "status");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusNotEqualTo(String value) {
|
||||||
|
addCriterion("`status` <>", value, "status");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusGreaterThan(String value) {
|
||||||
|
addCriterion("`status` >", value, "status");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("`status` >=", value, "status");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusLessThan(String value) {
|
||||||
|
addCriterion("`status` <", value, "status");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("`status` <=", value, "status");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusLike(String value) {
|
||||||
|
addCriterion("`status` like", value, "status");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusNotLike(String value) {
|
||||||
|
addCriterion("`status` not like", value, "status");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusIn(List<String> values) {
|
||||||
|
addCriterion("`status` in", values, "status");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusNotIn(List<String> values) {
|
||||||
|
addCriterion("`status` not in", values, "status");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusBetween(String value1, String value2) {
|
||||||
|
addCriterion("`status` between", value1, value2, "status");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("`status` not between", value1, value2, "status");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateTimeIsNull() {
|
||||||
|
addCriterion("create_time is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateTimeIsNotNull() {
|
||||||
|
addCriterion("create_time is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateTimeEqualTo(Long value) {
|
||||||
|
addCriterion("create_time =", value, "createTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateTimeNotEqualTo(Long value) {
|
||||||
|
addCriterion("create_time <>", value, "createTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateTimeGreaterThan(Long value) {
|
||||||
|
addCriterion("create_time >", value, "createTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateTimeGreaterThanOrEqualTo(Long value) {
|
||||||
|
addCriterion("create_time >=", value, "createTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateTimeLessThan(Long value) {
|
||||||
|
addCriterion("create_time <", value, "createTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateTimeLessThanOrEqualTo(Long value) {
|
||||||
|
addCriterion("create_time <=", value, "createTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateTimeIn(List<Long> values) {
|
||||||
|
addCriterion("create_time in", values, "createTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateTimeNotIn(List<Long> values) {
|
||||||
|
addCriterion("create_time not in", values, "createTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateTimeBetween(Long value1, Long value2) {
|
||||||
|
addCriterion("create_time between", value1, value2, "createTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateTimeNotBetween(Long value1, Long value2) {
|
||||||
|
addCriterion("create_time not between", value1, value2, "createTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateTimeIsNull() {
|
||||||
|
addCriterion("update_time is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateTimeIsNotNull() {
|
||||||
|
addCriterion("update_time is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateTimeEqualTo(Long value) {
|
||||||
|
addCriterion("update_time =", value, "updateTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateTimeNotEqualTo(Long value) {
|
||||||
|
addCriterion("update_time <>", value, "updateTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateTimeGreaterThan(Long value) {
|
||||||
|
addCriterion("update_time >", value, "updateTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateTimeGreaterThanOrEqualTo(Long value) {
|
||||||
|
addCriterion("update_time >=", value, "updateTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateTimeLessThan(Long value) {
|
||||||
|
addCriterion("update_time <", value, "updateTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateTimeLessThanOrEqualTo(Long value) {
|
||||||
|
addCriterion("update_time <=", value, "updateTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateTimeIn(List<Long> values) {
|
||||||
|
addCriterion("update_time in", values, "updateTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateTimeNotIn(List<Long> values) {
|
||||||
|
addCriterion("update_time not in", values, "updateTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateTimeBetween(Long value1, Long value2) {
|
||||||
|
addCriterion("update_time between", value1, value2, "updateTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUpdateTimeNotBetween(Long value1, Long value2) {
|
||||||
|
addCriterion("update_time not between", value1, value2, "updateTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andReporterIsNull() {
|
||||||
|
addCriterion("reporter is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andReporterIsNotNull() {
|
||||||
|
addCriterion("reporter is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andReporterEqualTo(String value) {
|
||||||
|
addCriterion("reporter =", value, "reporter");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andReporterNotEqualTo(String value) {
|
||||||
|
addCriterion("reporter <>", value, "reporter");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andReporterGreaterThan(String value) {
|
||||||
|
addCriterion("reporter >", value, "reporter");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andReporterGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("reporter >=", value, "reporter");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andReporterLessThan(String value) {
|
||||||
|
addCriterion("reporter <", value, "reporter");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andReporterLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("reporter <=", value, "reporter");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andReporterLike(String value) {
|
||||||
|
addCriterion("reporter like", value, "reporter");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andReporterNotLike(String value) {
|
||||||
|
addCriterion("reporter not like", value, "reporter");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andReporterIn(List<String> values) {
|
||||||
|
addCriterion("reporter in", values, "reporter");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andReporterNotIn(List<String> values) {
|
||||||
|
addCriterion("reporter not in", values, "reporter");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andReporterBetween(String value1, String value2) {
|
||||||
|
addCriterion("reporter between", value1, value2, "reporter");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andReporterNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("reporter not between", value1, value2, "reporter");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andLastmodifyIsNull() {
|
||||||
|
addCriterion("lastmodify is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andLastmodifyIsNotNull() {
|
||||||
|
addCriterion("lastmodify is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andLastmodifyEqualTo(String value) {
|
||||||
|
addCriterion("lastmodify =", value, "lastmodify");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andLastmodifyNotEqualTo(String value) {
|
||||||
|
addCriterion("lastmodify <>", value, "lastmodify");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andLastmodifyGreaterThan(String value) {
|
||||||
|
addCriterion("lastmodify >", value, "lastmodify");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andLastmodifyGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("lastmodify >=", value, "lastmodify");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andLastmodifyLessThan(String value) {
|
||||||
|
addCriterion("lastmodify <", value, "lastmodify");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andLastmodifyLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("lastmodify <=", value, "lastmodify");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andLastmodifyLike(String value) {
|
||||||
|
addCriterion("lastmodify like", value, "lastmodify");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andLastmodifyNotLike(String value) {
|
||||||
|
addCriterion("lastmodify not like", value, "lastmodify");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andLastmodifyIn(List<String> values) {
|
||||||
|
addCriterion("lastmodify in", values, "lastmodify");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andLastmodifyNotIn(List<String> values) {
|
||||||
|
addCriterion("lastmodify not in", values, "lastmodify");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andLastmodifyBetween(String value1, String value2) {
|
||||||
|
addCriterion("lastmodify between", value1, value2, "lastmodify");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andLastmodifyNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("lastmodify not between", value1, value2, "lastmodify");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andPlatformIsNull() {
|
||||||
|
addCriterion("platform is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andPlatformIsNotNull() {
|
||||||
|
addCriterion("platform is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andPlatformEqualTo(String value) {
|
||||||
|
addCriterion("platform =", value, "platform");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andPlatformNotEqualTo(String value) {
|
||||||
|
addCriterion("platform <>", value, "platform");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andPlatformGreaterThan(String value) {
|
||||||
|
addCriterion("platform >", value, "platform");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andPlatformGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("platform >=", value, "platform");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andPlatformLessThan(String value) {
|
||||||
|
addCriterion("platform <", value, "platform");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andPlatformLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("platform <=", value, "platform");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andPlatformLike(String value) {
|
||||||
|
addCriterion("platform like", value, "platform");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andPlatformNotLike(String value) {
|
||||||
|
addCriterion("platform not like", value, "platform");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andPlatformIn(List<String> values) {
|
||||||
|
addCriterion("platform in", values, "platform");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andPlatformNotIn(List<String> values) {
|
||||||
|
addCriterion("platform not in", values, "platform");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andPlatformBetween(String value1, String value2) {
|
||||||
|
addCriterion("platform between", value1, value2, "platform");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andPlatformNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("platform not between", value1, value2, "platform");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Criteria extends GeneratedCriteria {
|
||||||
|
|
||||||
|
protected Criteria() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Criterion {
|
||||||
|
private String condition;
|
||||||
|
|
||||||
|
private Object value;
|
||||||
|
|
||||||
|
private Object secondValue;
|
||||||
|
|
||||||
|
private boolean noValue;
|
||||||
|
|
||||||
|
private boolean singleValue;
|
||||||
|
|
||||||
|
private boolean betweenValue;
|
||||||
|
|
||||||
|
private boolean listValue;
|
||||||
|
|
||||||
|
private String typeHandler;
|
||||||
|
|
||||||
|
public String getCondition() {
|
||||||
|
return condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getSecondValue() {
|
||||||
|
return secondValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNoValue() {
|
||||||
|
return noValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSingleValue() {
|
||||||
|
return singleValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBetweenValue() {
|
||||||
|
return betweenValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isListValue() {
|
||||||
|
return listValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTypeHandler() {
|
||||||
|
return typeHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Criterion(String condition) {
|
||||||
|
super();
|
||||||
|
this.condition = condition;
|
||||||
|
this.typeHandler = null;
|
||||||
|
this.noValue = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Criterion(String condition, Object value, String typeHandler) {
|
||||||
|
super();
|
||||||
|
this.condition = condition;
|
||||||
|
this.value = value;
|
||||||
|
this.typeHandler = typeHandler;
|
||||||
|
if (value instanceof List<?>) {
|
||||||
|
this.listValue = true;
|
||||||
|
} else {
|
||||||
|
this.singleValue = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Criterion(String condition, Object value) {
|
||||||
|
this(condition, value, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
|
||||||
|
super();
|
||||||
|
this.condition = condition;
|
||||||
|
this.value = value;
|
||||||
|
this.secondValue = secondValue;
|
||||||
|
this.typeHandler = typeHandler;
|
||||||
|
this.betweenValue = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Criterion(String condition, Object value, Object secondValue) {
|
||||||
|
this(condition, value, secondValue, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,7 +11,5 @@ public class TestCaseIssues implements Serializable {
|
||||||
|
|
||||||
private String issuesId;
|
private String issuesId;
|
||||||
|
|
||||||
private String platform;
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
}
|
}
|
|
@ -313,76 +313,6 @@ public class TestCaseIssuesExample {
|
||||||
addCriterion("issues_id not between", value1, value2, "issuesId");
|
addCriterion("issues_id not between", value1, value2, "issuesId");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andPlatformIsNull() {
|
|
||||||
addCriterion("platform is null");
|
|
||||||
return (Criteria) this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Criteria andPlatformIsNotNull() {
|
|
||||||
addCriterion("platform is not null");
|
|
||||||
return (Criteria) this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Criteria andPlatformEqualTo(String value) {
|
|
||||||
addCriterion("platform =", value, "platform");
|
|
||||||
return (Criteria) this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Criteria andPlatformNotEqualTo(String value) {
|
|
||||||
addCriterion("platform <>", value, "platform");
|
|
||||||
return (Criteria) this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Criteria andPlatformGreaterThan(String value) {
|
|
||||||
addCriterion("platform >", value, "platform");
|
|
||||||
return (Criteria) this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Criteria andPlatformGreaterThanOrEqualTo(String value) {
|
|
||||||
addCriterion("platform >=", value, "platform");
|
|
||||||
return (Criteria) this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Criteria andPlatformLessThan(String value) {
|
|
||||||
addCriterion("platform <", value, "platform");
|
|
||||||
return (Criteria) this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Criteria andPlatformLessThanOrEqualTo(String value) {
|
|
||||||
addCriterion("platform <=", value, "platform");
|
|
||||||
return (Criteria) this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Criteria andPlatformLike(String value) {
|
|
||||||
addCriterion("platform like", value, "platform");
|
|
||||||
return (Criteria) this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Criteria andPlatformNotLike(String value) {
|
|
||||||
addCriterion("platform not like", value, "platform");
|
|
||||||
return (Criteria) this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Criteria andPlatformIn(List<String> values) {
|
|
||||||
addCriterion("platform in", values, "platform");
|
|
||||||
return (Criteria) this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Criteria andPlatformNotIn(List<String> values) {
|
|
||||||
addCriterion("platform not in", values, "platform");
|
|
||||||
return (Criteria) this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Criteria andPlatformBetween(String value1, String value2) {
|
|
||||||
addCriterion("platform between", value1, value2, "platform");
|
|
||||||
return (Criteria) this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Criteria andPlatformNotBetween(String value1, String value2) {
|
|
||||||
addCriterion("platform not between", value1, value2, "platform");
|
|
||||||
return (Criteria) this;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Criteria extends GeneratedCriteria {
|
public static class Criteria extends GeneratedCriteria {
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package io.metersphere.base.mapper;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.Issues;
|
||||||
|
import io.metersphere.base.domain.IssuesExample;
|
||||||
|
import java.util.List;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
public interface IssuesMapper {
|
||||||
|
long countByExample(IssuesExample example);
|
||||||
|
|
||||||
|
int deleteByExample(IssuesExample example);
|
||||||
|
|
||||||
|
int deleteByPrimaryKey(String id);
|
||||||
|
|
||||||
|
int insert(Issues record);
|
||||||
|
|
||||||
|
int insertSelective(Issues record);
|
||||||
|
|
||||||
|
List<Issues> selectByExampleWithBLOBs(IssuesExample example);
|
||||||
|
|
||||||
|
List<Issues> selectByExample(IssuesExample example);
|
||||||
|
|
||||||
|
Issues selectByPrimaryKey(String id);
|
||||||
|
|
||||||
|
int updateByExampleSelective(@Param("record") Issues record, @Param("example") IssuesExample example);
|
||||||
|
|
||||||
|
int updateByExampleWithBLOBs(@Param("record") Issues record, @Param("example") IssuesExample example);
|
||||||
|
|
||||||
|
int updateByExample(@Param("record") Issues record, @Param("example") IssuesExample example);
|
||||||
|
|
||||||
|
int updateByPrimaryKeySelective(Issues record);
|
||||||
|
|
||||||
|
int updateByPrimaryKeyWithBLOBs(Issues record);
|
||||||
|
|
||||||
|
int updateByPrimaryKey(Issues record);
|
||||||
|
}
|
|
@ -0,0 +1,323 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="io.metersphere.base.mapper.IssuesMapper">
|
||||||
|
<resultMap id="BaseResultMap" type="io.metersphere.base.domain.Issues">
|
||||||
|
<id column="id" jdbcType="VARCHAR" property="id" />
|
||||||
|
<result column="title" jdbcType="VARCHAR" property="title" />
|
||||||
|
<result column="status" jdbcType="VARCHAR" property="status" />
|
||||||
|
<result column="create_time" jdbcType="BIGINT" property="createTime" />
|
||||||
|
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
|
||||||
|
<result column="reporter" jdbcType="VARCHAR" property="reporter" />
|
||||||
|
<result column="lastmodify" jdbcType="VARCHAR" property="lastmodify" />
|
||||||
|
<result column="platform" jdbcType="VARCHAR" property="platform" />
|
||||||
|
</resultMap>
|
||||||
|
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.Issues">
|
||||||
|
<result column="description" jdbcType="LONGVARCHAR" property="description" />
|
||||||
|
</resultMap>
|
||||||
|
<sql id="Example_Where_Clause">
|
||||||
|
<where>
|
||||||
|
<foreach collection="oredCriteria" item="criteria" separator="or">
|
||||||
|
<if test="criteria.valid">
|
||||||
|
<trim prefix="(" prefixOverrides="and" suffix=")">
|
||||||
|
<foreach collection="criteria.criteria" item="criterion">
|
||||||
|
<choose>
|
||||||
|
<when test="criterion.noValue">
|
||||||
|
and ${criterion.condition}
|
||||||
|
</when>
|
||||||
|
<when test="criterion.singleValue">
|
||||||
|
and ${criterion.condition} #{criterion.value}
|
||||||
|
</when>
|
||||||
|
<when test="criterion.betweenValue">
|
||||||
|
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
|
||||||
|
</when>
|
||||||
|
<when test="criterion.listValue">
|
||||||
|
and ${criterion.condition}
|
||||||
|
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
|
||||||
|
#{listItem}
|
||||||
|
</foreach>
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
</foreach>
|
||||||
|
</trim>
|
||||||
|
</if>
|
||||||
|
</foreach>
|
||||||
|
</where>
|
||||||
|
</sql>
|
||||||
|
<sql id="Update_By_Example_Where_Clause">
|
||||||
|
<where>
|
||||||
|
<foreach collection="example.oredCriteria" item="criteria" separator="or">
|
||||||
|
<if test="criteria.valid">
|
||||||
|
<trim prefix="(" prefixOverrides="and" suffix=")">
|
||||||
|
<foreach collection="criteria.criteria" item="criterion">
|
||||||
|
<choose>
|
||||||
|
<when test="criterion.noValue">
|
||||||
|
and ${criterion.condition}
|
||||||
|
</when>
|
||||||
|
<when test="criterion.singleValue">
|
||||||
|
and ${criterion.condition} #{criterion.value}
|
||||||
|
</when>
|
||||||
|
<when test="criterion.betweenValue">
|
||||||
|
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
|
||||||
|
</when>
|
||||||
|
<when test="criterion.listValue">
|
||||||
|
and ${criterion.condition}
|
||||||
|
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
|
||||||
|
#{listItem}
|
||||||
|
</foreach>
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
</foreach>
|
||||||
|
</trim>
|
||||||
|
</if>
|
||||||
|
</foreach>
|
||||||
|
</where>
|
||||||
|
</sql>
|
||||||
|
<sql id="Base_Column_List">
|
||||||
|
id, title, `status`, create_time, update_time, reporter, lastmodify, platform
|
||||||
|
</sql>
|
||||||
|
<sql id="Blob_Column_List">
|
||||||
|
description
|
||||||
|
</sql>
|
||||||
|
<select id="selectByExampleWithBLOBs" parameterType="io.metersphere.base.domain.IssuesExample" resultMap="ResultMapWithBLOBs">
|
||||||
|
select
|
||||||
|
<if test="distinct">
|
||||||
|
distinct
|
||||||
|
</if>
|
||||||
|
<include refid="Base_Column_List" />
|
||||||
|
,
|
||||||
|
<include refid="Blob_Column_List" />
|
||||||
|
from issues
|
||||||
|
<if test="_parameter != null">
|
||||||
|
<include refid="Example_Where_Clause" />
|
||||||
|
</if>
|
||||||
|
<if test="orderByClause != null">
|
||||||
|
order by ${orderByClause}
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
<select id="selectByExample" parameterType="io.metersphere.base.domain.IssuesExample" resultMap="BaseResultMap">
|
||||||
|
select
|
||||||
|
<if test="distinct">
|
||||||
|
distinct
|
||||||
|
</if>
|
||||||
|
<include refid="Base_Column_List" />
|
||||||
|
from issues
|
||||||
|
<if test="_parameter != null">
|
||||||
|
<include refid="Example_Where_Clause" />
|
||||||
|
</if>
|
||||||
|
<if test="orderByClause != null">
|
||||||
|
order by ${orderByClause}
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="ResultMapWithBLOBs">
|
||||||
|
select
|
||||||
|
<include refid="Base_Column_List" />
|
||||||
|
,
|
||||||
|
<include refid="Blob_Column_List" />
|
||||||
|
from issues
|
||||||
|
where id = #{id,jdbcType=VARCHAR}
|
||||||
|
</select>
|
||||||
|
<delete id="deleteByPrimaryKey" parameterType="java.lang.String">
|
||||||
|
delete from issues
|
||||||
|
where id = #{id,jdbcType=VARCHAR}
|
||||||
|
</delete>
|
||||||
|
<delete id="deleteByExample" parameterType="io.metersphere.base.domain.IssuesExample">
|
||||||
|
delete from issues
|
||||||
|
<if test="_parameter != null">
|
||||||
|
<include refid="Example_Where_Clause" />
|
||||||
|
</if>
|
||||||
|
</delete>
|
||||||
|
<insert id="insert" parameterType="io.metersphere.base.domain.Issues">
|
||||||
|
insert into issues (id, title, `status`,
|
||||||
|
create_time, update_time, reporter,
|
||||||
|
lastmodify, platform, description
|
||||||
|
)
|
||||||
|
values (#{id,jdbcType=VARCHAR}, #{title,jdbcType=VARCHAR}, #{status,jdbcType=VARCHAR},
|
||||||
|
#{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT}, #{reporter,jdbcType=VARCHAR},
|
||||||
|
#{lastmodify,jdbcType=VARCHAR}, #{platform,jdbcType=VARCHAR}, #{description,jdbcType=LONGVARCHAR}
|
||||||
|
)
|
||||||
|
</insert>
|
||||||
|
<insert id="insertSelective" parameterType="io.metersphere.base.domain.Issues">
|
||||||
|
insert into issues
|
||||||
|
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="id != null">
|
||||||
|
id,
|
||||||
|
</if>
|
||||||
|
<if test="title != null">
|
||||||
|
title,
|
||||||
|
</if>
|
||||||
|
<if test="status != null">
|
||||||
|
`status`,
|
||||||
|
</if>
|
||||||
|
<if test="createTime != null">
|
||||||
|
create_time,
|
||||||
|
</if>
|
||||||
|
<if test="updateTime != null">
|
||||||
|
update_time,
|
||||||
|
</if>
|
||||||
|
<if test="reporter != null">
|
||||||
|
reporter,
|
||||||
|
</if>
|
||||||
|
<if test="lastmodify != null">
|
||||||
|
lastmodify,
|
||||||
|
</if>
|
||||||
|
<if test="platform != null">
|
||||||
|
platform,
|
||||||
|
</if>
|
||||||
|
<if test="description != null">
|
||||||
|
description,
|
||||||
|
</if>
|
||||||
|
</trim>
|
||||||
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="id != null">
|
||||||
|
#{id,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="title != null">
|
||||||
|
#{title,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="status != null">
|
||||||
|
#{status,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="createTime != null">
|
||||||
|
#{createTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
|
<if test="updateTime != null">
|
||||||
|
#{updateTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
|
<if test="reporter != null">
|
||||||
|
#{reporter,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="lastmodify != null">
|
||||||
|
#{lastmodify,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="platform != null">
|
||||||
|
#{platform,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="description != null">
|
||||||
|
#{description,jdbcType=LONGVARCHAR},
|
||||||
|
</if>
|
||||||
|
</trim>
|
||||||
|
</insert>
|
||||||
|
<select id="countByExample" parameterType="io.metersphere.base.domain.IssuesExample" resultType="java.lang.Long">
|
||||||
|
select count(*) from issues
|
||||||
|
<if test="_parameter != null">
|
||||||
|
<include refid="Example_Where_Clause" />
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
<update id="updateByExampleSelective" parameterType="map">
|
||||||
|
update issues
|
||||||
|
<set>
|
||||||
|
<if test="record.id != null">
|
||||||
|
id = #{record.id,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="record.title != null">
|
||||||
|
title = #{record.title,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="record.status != null">
|
||||||
|
`status` = #{record.status,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="record.createTime != null">
|
||||||
|
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
|
<if test="record.updateTime != null">
|
||||||
|
update_time = #{record.updateTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
|
<if test="record.reporter != null">
|
||||||
|
reporter = #{record.reporter,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="record.lastmodify != null">
|
||||||
|
lastmodify = #{record.lastmodify,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="record.platform != null">
|
||||||
|
platform = #{record.platform,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="record.description != null">
|
||||||
|
description = #{record.description,jdbcType=LONGVARCHAR},
|
||||||
|
</if>
|
||||||
|
</set>
|
||||||
|
<if test="_parameter != null">
|
||||||
|
<include refid="Update_By_Example_Where_Clause" />
|
||||||
|
</if>
|
||||||
|
</update>
|
||||||
|
<update id="updateByExampleWithBLOBs" parameterType="map">
|
||||||
|
update issues
|
||||||
|
set id = #{record.id,jdbcType=VARCHAR},
|
||||||
|
title = #{record.title,jdbcType=VARCHAR},
|
||||||
|
`status` = #{record.status,jdbcType=VARCHAR},
|
||||||
|
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||||
|
update_time = #{record.updateTime,jdbcType=BIGINT},
|
||||||
|
reporter = #{record.reporter,jdbcType=VARCHAR},
|
||||||
|
lastmodify = #{record.lastmodify,jdbcType=VARCHAR},
|
||||||
|
platform = #{record.platform,jdbcType=VARCHAR},
|
||||||
|
description = #{record.description,jdbcType=LONGVARCHAR}
|
||||||
|
<if test="_parameter != null">
|
||||||
|
<include refid="Update_By_Example_Where_Clause" />
|
||||||
|
</if>
|
||||||
|
</update>
|
||||||
|
<update id="updateByExample" parameterType="map">
|
||||||
|
update issues
|
||||||
|
set id = #{record.id,jdbcType=VARCHAR},
|
||||||
|
title = #{record.title,jdbcType=VARCHAR},
|
||||||
|
`status` = #{record.status,jdbcType=VARCHAR},
|
||||||
|
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||||
|
update_time = #{record.updateTime,jdbcType=BIGINT},
|
||||||
|
reporter = #{record.reporter,jdbcType=VARCHAR},
|
||||||
|
lastmodify = #{record.lastmodify,jdbcType=VARCHAR},
|
||||||
|
platform = #{record.platform,jdbcType=VARCHAR}
|
||||||
|
<if test="_parameter != null">
|
||||||
|
<include refid="Update_By_Example_Where_Clause" />
|
||||||
|
</if>
|
||||||
|
</update>
|
||||||
|
<update id="updateByPrimaryKeySelective" parameterType="io.metersphere.base.domain.Issues">
|
||||||
|
update issues
|
||||||
|
<set>
|
||||||
|
<if test="title != null">
|
||||||
|
title = #{title,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="status != null">
|
||||||
|
`status` = #{status,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="createTime != null">
|
||||||
|
create_time = #{createTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
|
<if test="updateTime != null">
|
||||||
|
update_time = #{updateTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
|
<if test="reporter != null">
|
||||||
|
reporter = #{reporter,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="lastmodify != null">
|
||||||
|
lastmodify = #{lastmodify,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="platform != null">
|
||||||
|
platform = #{platform,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="description != null">
|
||||||
|
description = #{description,jdbcType=LONGVARCHAR},
|
||||||
|
</if>
|
||||||
|
</set>
|
||||||
|
where id = #{id,jdbcType=VARCHAR}
|
||||||
|
</update>
|
||||||
|
<update id="updateByPrimaryKeyWithBLOBs" parameterType="io.metersphere.base.domain.Issues">
|
||||||
|
update issues
|
||||||
|
set title = #{title,jdbcType=VARCHAR},
|
||||||
|
`status` = #{status,jdbcType=VARCHAR},
|
||||||
|
create_time = #{createTime,jdbcType=BIGINT},
|
||||||
|
update_time = #{updateTime,jdbcType=BIGINT},
|
||||||
|
reporter = #{reporter,jdbcType=VARCHAR},
|
||||||
|
lastmodify = #{lastmodify,jdbcType=VARCHAR},
|
||||||
|
platform = #{platform,jdbcType=VARCHAR},
|
||||||
|
description = #{description,jdbcType=LONGVARCHAR}
|
||||||
|
where id = #{id,jdbcType=VARCHAR}
|
||||||
|
</update>
|
||||||
|
<update id="updateByPrimaryKey" parameterType="io.metersphere.base.domain.Issues">
|
||||||
|
update issues
|
||||||
|
set title = #{title,jdbcType=VARCHAR},
|
||||||
|
`status` = #{status,jdbcType=VARCHAR},
|
||||||
|
create_time = #{createTime,jdbcType=BIGINT},
|
||||||
|
update_time = #{updateTime,jdbcType=BIGINT},
|
||||||
|
reporter = #{reporter,jdbcType=VARCHAR},
|
||||||
|
lastmodify = #{lastmodify,jdbcType=VARCHAR},
|
||||||
|
platform = #{platform,jdbcType=VARCHAR}
|
||||||
|
where id = #{id,jdbcType=VARCHAR}
|
||||||
|
</update>
|
||||||
|
</mapper>
|
|
@ -5,7 +5,6 @@
|
||||||
<id column="id" jdbcType="VARCHAR" property="id" />
|
<id column="id" jdbcType="VARCHAR" property="id" />
|
||||||
<result column="test_case_id" jdbcType="VARCHAR" property="testCaseId" />
|
<result column="test_case_id" jdbcType="VARCHAR" property="testCaseId" />
|
||||||
<result column="issues_id" jdbcType="VARCHAR" property="issuesId" />
|
<result column="issues_id" jdbcType="VARCHAR" property="issuesId" />
|
||||||
<result column="platform" jdbcType="VARCHAR" property="platform" />
|
|
||||||
</resultMap>
|
</resultMap>
|
||||||
<sql id="Example_Where_Clause">
|
<sql id="Example_Where_Clause">
|
||||||
<where>
|
<where>
|
||||||
|
@ -66,7 +65,7 @@
|
||||||
</where>
|
</where>
|
||||||
</sql>
|
</sql>
|
||||||
<sql id="Base_Column_List">
|
<sql id="Base_Column_List">
|
||||||
id, test_case_id, issues_id, platform
|
id, test_case_id, issues_id
|
||||||
</sql>
|
</sql>
|
||||||
<select id="selectByExample" parameterType="io.metersphere.base.domain.TestCaseIssuesExample" resultMap="BaseResultMap">
|
<select id="selectByExample" parameterType="io.metersphere.base.domain.TestCaseIssuesExample" resultMap="BaseResultMap">
|
||||||
select
|
select
|
||||||
|
@ -99,10 +98,10 @@
|
||||||
</if>
|
</if>
|
||||||
</delete>
|
</delete>
|
||||||
<insert id="insert" parameterType="io.metersphere.base.domain.TestCaseIssues">
|
<insert id="insert" parameterType="io.metersphere.base.domain.TestCaseIssues">
|
||||||
insert into test_case_issues (id, test_case_id, issues_id,
|
insert into test_case_issues (id, test_case_id, issues_id
|
||||||
platform)
|
)
|
||||||
values (#{id,jdbcType=VARCHAR}, #{testCaseId,jdbcType=VARCHAR}, #{issuesId,jdbcType=VARCHAR},
|
values (#{id,jdbcType=VARCHAR}, #{testCaseId,jdbcType=VARCHAR}, #{issuesId,jdbcType=VARCHAR}
|
||||||
#{platform,jdbcType=VARCHAR})
|
)
|
||||||
</insert>
|
</insert>
|
||||||
<insert id="insertSelective" parameterType="io.metersphere.base.domain.TestCaseIssues">
|
<insert id="insertSelective" parameterType="io.metersphere.base.domain.TestCaseIssues">
|
||||||
insert into test_case_issues
|
insert into test_case_issues
|
||||||
|
@ -116,9 +115,6 @@
|
||||||
<if test="issuesId != null">
|
<if test="issuesId != null">
|
||||||
issues_id,
|
issues_id,
|
||||||
</if>
|
</if>
|
||||||
<if test="platform != null">
|
|
||||||
platform,
|
|
||||||
</if>
|
|
||||||
</trim>
|
</trim>
|
||||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
<if test="id != null">
|
<if test="id != null">
|
||||||
|
@ -130,9 +126,6 @@
|
||||||
<if test="issuesId != null">
|
<if test="issuesId != null">
|
||||||
#{issuesId,jdbcType=VARCHAR},
|
#{issuesId,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
<if test="platform != null">
|
|
||||||
#{platform,jdbcType=VARCHAR},
|
|
||||||
</if>
|
|
||||||
</trim>
|
</trim>
|
||||||
</insert>
|
</insert>
|
||||||
<select id="countByExample" parameterType="io.metersphere.base.domain.TestCaseIssuesExample" resultType="java.lang.Long">
|
<select id="countByExample" parameterType="io.metersphere.base.domain.TestCaseIssuesExample" resultType="java.lang.Long">
|
||||||
|
@ -153,9 +146,6 @@
|
||||||
<if test="record.issuesId != null">
|
<if test="record.issuesId != null">
|
||||||
issues_id = #{record.issuesId,jdbcType=VARCHAR},
|
issues_id = #{record.issuesId,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
<if test="record.platform != null">
|
|
||||||
platform = #{record.platform,jdbcType=VARCHAR},
|
|
||||||
</if>
|
|
||||||
</set>
|
</set>
|
||||||
<if test="_parameter != null">
|
<if test="_parameter != null">
|
||||||
<include refid="Update_By_Example_Where_Clause" />
|
<include refid="Update_By_Example_Where_Clause" />
|
||||||
|
@ -165,8 +155,7 @@
|
||||||
update test_case_issues
|
update test_case_issues
|
||||||
set id = #{record.id,jdbcType=VARCHAR},
|
set id = #{record.id,jdbcType=VARCHAR},
|
||||||
test_case_id = #{record.testCaseId,jdbcType=VARCHAR},
|
test_case_id = #{record.testCaseId,jdbcType=VARCHAR},
|
||||||
issues_id = #{record.issuesId,jdbcType=VARCHAR},
|
issues_id = #{record.issuesId,jdbcType=VARCHAR}
|
||||||
platform = #{record.platform,jdbcType=VARCHAR}
|
|
||||||
<if test="_parameter != null">
|
<if test="_parameter != null">
|
||||||
<include refid="Update_By_Example_Where_Clause" />
|
<include refid="Update_By_Example_Where_Clause" />
|
||||||
</if>
|
</if>
|
||||||
|
@ -180,17 +169,13 @@
|
||||||
<if test="issuesId != null">
|
<if test="issuesId != null">
|
||||||
issues_id = #{issuesId,jdbcType=VARCHAR},
|
issues_id = #{issuesId,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
<if test="platform != null">
|
|
||||||
platform = #{platform,jdbcType=VARCHAR},
|
|
||||||
</if>
|
|
||||||
</set>
|
</set>
|
||||||
where id = #{id,jdbcType=VARCHAR}
|
where id = #{id,jdbcType=VARCHAR}
|
||||||
</update>
|
</update>
|
||||||
<update id="updateByPrimaryKey" parameterType="io.metersphere.base.domain.TestCaseIssues">
|
<update id="updateByPrimaryKey" parameterType="io.metersphere.base.domain.TestCaseIssues">
|
||||||
update test_case_issues
|
update test_case_issues
|
||||||
set test_case_id = #{testCaseId,jdbcType=VARCHAR},
|
set test_case_id = #{testCaseId,jdbcType=VARCHAR},
|
||||||
issues_id = #{issuesId,jdbcType=VARCHAR},
|
issues_id = #{issuesId,jdbcType=VARCHAR}
|
||||||
platform = #{platform,jdbcType=VARCHAR}
|
|
||||||
where id = #{id,jdbcType=VARCHAR}
|
where id = #{id,jdbcType=VARCHAR}
|
||||||
</update>
|
</update>
|
||||||
</mapper>
|
</mapper>
|
|
@ -132,7 +132,6 @@
|
||||||
LEFT JOIN user ON user.id = r.user_id
|
LEFT JOIN user ON user.id = r.user_id
|
||||||
<where>
|
<where>
|
||||||
r.id = #{id}
|
r.id = #{id}
|
||||||
AND r.status != 'Debug'
|
|
||||||
</where>
|
</where>
|
||||||
ORDER BY r.update_time DESC
|
ORDER BY r.update_time DESC
|
||||||
</select>
|
</select>
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package io.metersphere.base.mapper.ext;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.Issues;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface ExtIssuesMapper {
|
||||||
|
|
||||||
|
List<Issues> getIssues(@Param("caseId") String caseId, @Param("platform") String platform);
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||||
|
<mapper namespace="io.metersphere.base.mapper.ext.ExtIssuesMapper">
|
||||||
|
|
||||||
|
<select id="getIssues" resultType="io.metersphere.base.domain.Issues">
|
||||||
|
select issues.*
|
||||||
|
from test_case_issues, issues
|
||||||
|
where test_case_issues.issues_id = issues.id
|
||||||
|
and test_case_issues.test_case_id = #{caseId}
|
||||||
|
and issues.platform = #{platform};
|
||||||
|
</select>
|
||||||
|
</mapper>
|
|
@ -11,4 +11,6 @@ public interface ExtProjectMapper {
|
||||||
List<ProjectDTO> getProjectWithWorkspace(@Param("proRequest") ProjectRequest request);
|
List<ProjectDTO> getProjectWithWorkspace(@Param("proRequest") ProjectRequest request);
|
||||||
|
|
||||||
List<String> getProjectIdByWorkspaceId(String workspaceId);
|
List<String> getProjectIdByWorkspaceId(String workspaceId);
|
||||||
|
|
||||||
|
int removeIssuePlatform(@Param("platform") String platform, @Param("orgId") String orgId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,4 +28,22 @@
|
||||||
where workspace_id = #{workspaceId}
|
where workspace_id = #{workspaceId}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<update id="removeIssuePlatform">
|
||||||
|
update project
|
||||||
|
<set>
|
||||||
|
<if test="platform == 'Jira'">
|
||||||
|
jira_key = null
|
||||||
|
</if>
|
||||||
|
<if test="platform == 'Tapd'">
|
||||||
|
tapd_id = null
|
||||||
|
</if>
|
||||||
|
</set>
|
||||||
|
where project.id in (select id from (select id
|
||||||
|
from project
|
||||||
|
where workspace_id in
|
||||||
|
(select workspace.id
|
||||||
|
from workspace
|
||||||
|
where organization_id = #{orgId})) as a)
|
||||||
|
</update>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
|
@ -1,5 +1,5 @@
|
||||||
package io.metersphere.commons.constants;
|
package io.metersphere.commons.constants;
|
||||||
|
|
||||||
public enum IssuesManagePlatform {
|
public enum IssuesManagePlatform {
|
||||||
Tapd, Jira
|
Tapd, Jira, Local
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package io.metersphere.commons.constants;
|
||||||
|
|
||||||
|
public enum SsoMode {
|
||||||
|
CAS,LOCAL
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package io.metersphere.commons.utils;
|
package io.metersphere.commons.utils;
|
||||||
|
|
||||||
|
import io.metersphere.commons.exception.MSException;
|
||||||
import org.springframework.http.HttpEntity;
|
import org.springframework.http.HttpEntity;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
|
@ -22,7 +23,9 @@ public class RestTemplateUtils {
|
||||||
ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
|
ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
|
||||||
return responseEntity.getBody();
|
return responseEntity.getBody();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("调用接口失败", e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
|
MSException.throwException("Tapd接口调用失败:" + e.getMessage());
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +37,9 @@ public class RestTemplateUtils {
|
||||||
ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
|
ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
|
||||||
return responseEntity.getBody();
|
return responseEntity.getBody();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("调用接口失败", e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
|
MSException.throwException("Tapd接口调用失败:" + e.getMessage());
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package io.metersphere.commons.utils;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
|
||||||
|
import javax.script.ScriptEngine;
|
||||||
|
import javax.script.ScriptEngineManager;
|
||||||
|
import javax.script.ScriptException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
public class ScriptEngineUtils {
|
||||||
|
private static final String ENGINE_NAME = "graal.js";
|
||||||
|
private static ScriptEngine engine;
|
||||||
|
|
||||||
|
static {
|
||||||
|
final ScriptEngineManager engineManager = new ScriptEngineManager();
|
||||||
|
engine = engineManager.getEngineByName(ENGINE_NAME);
|
||||||
|
try {
|
||||||
|
String script = IOUtils.toString(ScriptEngineUtils.class.getResource("/javascript/func.js"), StandardCharsets.UTF_8);
|
||||||
|
engine.eval(script);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String calculate(String input) {
|
||||||
|
try {
|
||||||
|
return engine.eval("calculate('" + input + "')").toString();
|
||||||
|
} catch (ScriptException e) {
|
||||||
|
LogUtil.error(e);
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package io.metersphere.commons.utils;
|
||||||
|
|
||||||
|
import org.apache.shiro.cache.CacheManager;
|
||||||
|
import org.apache.shiro.session.mgt.SessionManager;
|
||||||
|
import org.apache.shiro.web.servlet.Cookie;
|
||||||
|
import org.apache.shiro.web.servlet.SimpleCookie;
|
||||||
|
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ShiroUtils {
|
||||||
|
|
||||||
|
public static void loadBaseFilterChain(Map<String, String> filterChainDefinitionMap){
|
||||||
|
|
||||||
|
filterChainDefinitionMap.put("/resource/**", "anon");
|
||||||
|
filterChainDefinitionMap.put("/signin", "anon");
|
||||||
|
filterChainDefinitionMap.put("/ldap/signin", "anon");
|
||||||
|
filterChainDefinitionMap.put("/ldap/open", "anon");
|
||||||
|
filterChainDefinitionMap.put("/isLogin", "anon");
|
||||||
|
filterChainDefinitionMap.put("/css/**", "anon");
|
||||||
|
filterChainDefinitionMap.put("/js/**", "anon");
|
||||||
|
filterChainDefinitionMap.put("/img/**", "anon");
|
||||||
|
filterChainDefinitionMap.put("/fonts/**", "anon");
|
||||||
|
|
||||||
|
// for swagger
|
||||||
|
filterChainDefinitionMap.put("/swagger-ui.html", "anon");
|
||||||
|
filterChainDefinitionMap.put("/swagger-ui/**", "anon");
|
||||||
|
filterChainDefinitionMap.put("/v3/api-docs/**", "anon");
|
||||||
|
|
||||||
|
filterChainDefinitionMap.put("/403", "anon");
|
||||||
|
filterChainDefinitionMap.put("/anonymous/**", "anon");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Cookie getSessionIdCookie(){
|
||||||
|
SimpleCookie sessionIdCookie = new SimpleCookie();
|
||||||
|
sessionIdCookie.setPath("/");
|
||||||
|
sessionIdCookie.setName("MS_SESSION_ID");
|
||||||
|
return sessionIdCookie;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SessionManager getSessionManager(Long sessionTimeout, CacheManager cacheManager){
|
||||||
|
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
|
||||||
|
sessionManager.setSessionIdUrlRewritingEnabled(false);
|
||||||
|
sessionManager.setDeleteInvalidSessions(true);
|
||||||
|
sessionManager.setSessionValidationSchedulerEnabled(true);
|
||||||
|
sessionManager.setSessionIdCookie(ShiroUtils.getSessionIdCookie());
|
||||||
|
sessionManager.setGlobalSessionTimeout(sessionTimeout * 1000);// 超时时间ms
|
||||||
|
sessionManager.setCacheManager(cacheManager);
|
||||||
|
|
||||||
|
//sessionManager.setSessionIdCookieEnabled(true);
|
||||||
|
return sessionManager;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package io.metersphere.config;
|
package io.metersphere.config;
|
||||||
|
|
||||||
|
import io.metersphere.commons.utils.ShiroUtils;
|
||||||
import io.metersphere.security.ApiKeyFilter;
|
import io.metersphere.security.ApiKeyFilter;
|
||||||
import io.metersphere.security.LoginFilter;
|
import io.metersphere.security.LoginFilter;
|
||||||
import io.metersphere.security.ShiroDBRealm;
|
import io.metersphere.security.ShiroDBRealm;
|
||||||
|
@ -9,9 +10,8 @@ import org.apache.shiro.spring.LifecycleBeanPostProcessor;
|
||||||
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
|
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
|
||||||
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
|
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
|
||||||
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
|
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
|
||||||
import org.apache.shiro.web.servlet.SimpleCookie;
|
|
||||||
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
|
|
||||||
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
|
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.EnvironmentAware;
|
import org.springframework.context.EnvironmentAware;
|
||||||
|
@ -29,6 +29,7 @@ import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
@ConditionalOnProperty(prefix="sso",name = "mode", havingValue = "local", matchIfMissing = true)
|
||||||
public class ShiroConfig implements EnvironmentAware {
|
public class ShiroConfig implements EnvironmentAware {
|
||||||
private Environment env;
|
private Environment env;
|
||||||
|
|
||||||
|
@ -42,26 +43,8 @@ public class ShiroConfig implements EnvironmentAware {
|
||||||
shiroFilterFactoryBean.setSuccessUrl("/");
|
shiroFilterFactoryBean.setSuccessUrl("/");
|
||||||
|
|
||||||
shiroFilterFactoryBean.getFilters().put("apikey", new ApiKeyFilter());
|
shiroFilterFactoryBean.getFilters().put("apikey", new ApiKeyFilter());
|
||||||
|
|
||||||
Map<String, String> filterChainDefinitionMap = shiroFilterFactoryBean.getFilterChainDefinitionMap();
|
Map<String, String> filterChainDefinitionMap = shiroFilterFactoryBean.getFilterChainDefinitionMap();
|
||||||
filterChainDefinitionMap.put("/resource/**", "anon");
|
ShiroUtils.loadBaseFilterChain(filterChainDefinitionMap);
|
||||||
filterChainDefinitionMap.put("/", "anon");
|
|
||||||
filterChainDefinitionMap.put("/signin", "anon");
|
|
||||||
filterChainDefinitionMap.put("/ldap/signin", "anon");
|
|
||||||
filterChainDefinitionMap.put("/ldap/open", "anon");
|
|
||||||
filterChainDefinitionMap.put("/isLogin", "anon");
|
|
||||||
filterChainDefinitionMap.put("/css/**", "anon");
|
|
||||||
filterChainDefinitionMap.put("/js/**", "anon");
|
|
||||||
filterChainDefinitionMap.put("/img/**", "anon");
|
|
||||||
filterChainDefinitionMap.put("/fonts/**", "anon");
|
|
||||||
|
|
||||||
// for swagger
|
|
||||||
filterChainDefinitionMap.put("/swagger-ui.html", "anon");
|
|
||||||
filterChainDefinitionMap.put("/swagger-ui/**", "anon");
|
|
||||||
filterChainDefinitionMap.put("/v3/api-docs/**", "anon");
|
|
||||||
|
|
||||||
filterChainDefinitionMap.put("/403", "anon");
|
|
||||||
filterChainDefinitionMap.put("/anonymous/**", "anon");
|
|
||||||
filterChainDefinitionMap.put("/**", "apikey, authc");
|
filterChainDefinitionMap.put("/**", "apikey, authc");
|
||||||
return shiroFilterFactoryBean;
|
return shiroFilterFactoryBean;
|
||||||
}
|
}
|
||||||
|
@ -120,18 +103,7 @@ public class ShiroConfig implements EnvironmentAware {
|
||||||
@Bean
|
@Bean
|
||||||
public SessionManager sessionManager(MemoryConstrainedCacheManager memoryConstrainedCacheManager) {
|
public SessionManager sessionManager(MemoryConstrainedCacheManager memoryConstrainedCacheManager) {
|
||||||
Long sessionTimeout = env.getProperty("session.timeout", Long.class, 1800L); // 默认1800s, 半个小时
|
Long sessionTimeout = env.getProperty("session.timeout", Long.class, 1800L); // 默认1800s, 半个小时
|
||||||
|
return ShiroUtils.getSessionManager(sessionTimeout, memoryConstrainedCacheManager);
|
||||||
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
|
|
||||||
sessionManager.setSessionIdUrlRewritingEnabled(false);
|
|
||||||
sessionManager.setGlobalSessionTimeout(sessionTimeout * 1000);// 超时时间ms
|
|
||||||
sessionManager.setDeleteInvalidSessions(true);
|
|
||||||
sessionManager.setSessionValidationSchedulerEnabled(true);
|
|
||||||
SimpleCookie sessionIdCookie = new SimpleCookie();
|
|
||||||
sessionManager.setSessionIdCookie(sessionIdCookie);
|
|
||||||
sessionIdCookie.setPath("/");
|
|
||||||
sessionIdCookie.setName("MS_SESSION_ID");
|
|
||||||
sessionManager.setCacheManager(memoryConstrainedCacheManager);
|
|
||||||
return sessionManager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package io.metersphere.controller;
|
package io.metersphere.controller;
|
||||||
|
|
||||||
import io.metersphere.commons.utils.SessionUtils;
|
import io.metersphere.commons.utils.SessionUtils;
|
||||||
|
import org.apache.shiro.SecurityUtils;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
@ -22,4 +23,15 @@ public class IndexController {
|
||||||
return "redirect:/";
|
return "redirect:/";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/sso/login")
|
||||||
|
public String ossLogin() {
|
||||||
|
return "redirect:/";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/sso/logout")
|
||||||
|
public void ossLogout() {
|
||||||
|
SecurityUtils.getSubject().logout();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
package io.metersphere.controller;
|
package io.metersphere.controller;
|
||||||
|
|
||||||
|
import io.metersphere.commons.constants.SsoMode;
|
||||||
import io.metersphere.commons.constants.UserSource;
|
import io.metersphere.commons.constants.UserSource;
|
||||||
|
import io.metersphere.commons.user.SessionUser;
|
||||||
|
import io.metersphere.commons.utils.SessionUtils;
|
||||||
import io.metersphere.controller.request.LoginRequest;
|
import io.metersphere.controller.request.LoginRequest;
|
||||||
import io.metersphere.service.UserService;
|
import io.metersphere.service.UserService;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.shiro.SecurityUtils;
|
import org.apache.shiro.SecurityUtils;
|
||||||
import org.springframework.context.i18n.LocaleContextHolder;
|
import org.springframework.context.i18n.LocaleContextHolder;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
@ -15,11 +20,21 @@ public class LoginController {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private UserService userService;
|
private UserService userService;
|
||||||
|
@Resource
|
||||||
|
private Environment env;
|
||||||
|
|
||||||
@GetMapping(value = "/isLogin")
|
@GetMapping(value = "/isLogin")
|
||||||
public ResultHolder isLogin() {
|
public ResultHolder isLogin() {
|
||||||
if (SecurityUtils.getSubject().isAuthenticated()) {
|
if (SecurityUtils.getSubject().isAuthenticated()) {
|
||||||
return ResultHolder.success(LocaleContextHolder.getLocale());
|
SessionUser user = SessionUtils.getUser();
|
||||||
|
if (StringUtils.isBlank(user.getLanguage())) {
|
||||||
|
user.setLanguage(LocaleContextHolder.getLocale().toString());
|
||||||
|
}
|
||||||
|
return ResultHolder.success(user);
|
||||||
|
}
|
||||||
|
String ssoMode = env.getProperty("sso.mode");
|
||||||
|
if (ssoMode != null && StringUtils.equalsIgnoreCase(SsoMode.CAS.name(), ssoMode)) {
|
||||||
|
return ResultHolder.error("sso");
|
||||||
}
|
}
|
||||||
return ResultHolder.error("");
|
return ResultHolder.error("");
|
||||||
}
|
}
|
||||||
|
@ -30,9 +45,19 @@ public class LoginController {
|
||||||
return userService.login(request);
|
return userService.login(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/currentUser")
|
||||||
|
public ResultHolder currentUser() {
|
||||||
|
return ResultHolder.success(SecurityUtils.getSubject().getSession().getAttribute("user"));
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping(value = "/signout")
|
@GetMapping(value = "/signout")
|
||||||
public ResultHolder logout() {
|
public ResultHolder logout() {
|
||||||
|
String ssoMode = env.getProperty("sso.mode");
|
||||||
|
if (ssoMode != null && StringUtils.equalsIgnoreCase(SsoMode.CAS.name(), ssoMode)) {
|
||||||
|
return ResultHolder.error("sso");
|
||||||
|
} else {
|
||||||
SecurityUtils.getSubject().logout();
|
SecurityUtils.getSubject().logout();
|
||||||
|
}
|
||||||
return ResultHolder.success("");
|
return ResultHolder.success("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,5 +67,4 @@ public class LoginController {
|
||||||
return userService.getDefaultLanguage();
|
return userService.getDefaultLanguage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package io.metersphere.dto;
|
package io.metersphere.dto;
|
||||||
|
|
||||||
import io.metersphere.base.domain.Role;
|
import io.metersphere.base.domain.Role;
|
||||||
|
import io.metersphere.base.domain.User;
|
||||||
import io.metersphere.base.domain.UserRole;
|
import io.metersphere.base.domain.UserRole;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
@ -10,28 +11,7 @@ import java.util.List;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class UserDTO {
|
public class UserDTO extends User {
|
||||||
private String id;
|
|
||||||
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
private String email;
|
|
||||||
|
|
||||||
private String phone;
|
|
||||||
|
|
||||||
private String status;
|
|
||||||
|
|
||||||
private String source;
|
|
||||||
|
|
||||||
private Long createTime;
|
|
||||||
|
|
||||||
private Long updateTime;
|
|
||||||
|
|
||||||
private String language;
|
|
||||||
|
|
||||||
private String lastWorkspaceId;
|
|
||||||
|
|
||||||
private String lastOrganizationId;
|
|
||||||
|
|
||||||
private List<Role> roles = new ArrayList<>();
|
private List<Role> roles = new ArrayList<>();
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import io.metersphere.commons.exception.MSException;
|
import io.metersphere.commons.exception.MSException;
|
||||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
|
import io.metersphere.commons.utils.ScriptEngineUtils;
|
||||||
import io.metersphere.config.KafkaProperties;
|
import io.metersphere.config.KafkaProperties;
|
||||||
import io.metersphere.i18n.Translator;
|
import io.metersphere.i18n.Translator;
|
||||||
import io.metersphere.performance.engine.EngineContext;
|
import io.metersphere.performance.engine.EngineContext;
|
||||||
|
@ -377,7 +378,9 @@ public class JmeterDocumentParser implements DocumentParser {
|
||||||
elementProp.setAttribute("name", jsonObject.getString("name"));
|
elementProp.setAttribute("name", jsonObject.getString("name"));
|
||||||
elementProp.setAttribute("elementType", "Argument");
|
elementProp.setAttribute("elementType", "Argument");
|
||||||
elementProp.appendChild(createStringProp(document, "Argument.name", jsonObject.getString("name")));
|
elementProp.appendChild(createStringProp(document, "Argument.name", jsonObject.getString("name")));
|
||||||
elementProp.appendChild(createStringProp(document, "Argument.value", jsonObject.getString("value")));
|
// 处理 mock data
|
||||||
|
String value = jsonObject.getString("value");
|
||||||
|
elementProp.appendChild(createStringProp(document, "Argument.value", ScriptEngineUtils.calculate(value)));
|
||||||
elementProp.appendChild(createStringProp(document, "Argument.metadata", "="));
|
elementProp.appendChild(createStringProp(document, "Argument.metadata", "="));
|
||||||
item.appendChild(elementProp);
|
item.appendChild(elementProp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,15 +49,16 @@ public class ShiroDBRealm extends AuthorizingRealm {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
|
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
|
||||||
|
String userId = (String) principals.getPrimaryPrincipal();
|
||||||
|
return getAuthorizationInfo(userId, userService);
|
||||||
|
}
|
||||||
|
|
||||||
String userName = (String) principals.getPrimaryPrincipal();
|
public static AuthorizationInfo getAuthorizationInfo(String userId, UserService userService) {
|
||||||
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
|
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
|
||||||
|
|
||||||
// roles 内容填充
|
// roles 内容填充
|
||||||
UserDTO userDTO = userService.getUserDTO(userName);
|
UserDTO userDTO = userService.getUserDTO(userId);
|
||||||
Set<String> roles = userDTO.getRoles().stream().map(Role::getId).collect(Collectors.toSet());
|
Set<String> roles = userDTO.getRoles().stream().map(Role::getId).collect(Collectors.toSet());
|
||||||
authorizationInfo.setRoles(roles);
|
authorizationInfo.setRoles(roles);
|
||||||
|
|
||||||
return authorizationInfo;
|
return authorizationInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +149,6 @@ public class ShiroDBRealm extends AuthorizingRealm {
|
||||||
if (!userService.checkUserPassword(userId, password)) {
|
if (!userService.checkUserPassword(userId, password)) {
|
||||||
throw new IncorrectCredentialsException(Translator.get("password_is_incorrect"));
|
throw new IncorrectCredentialsException(Translator.get("password_is_incorrect"));
|
||||||
}
|
}
|
||||||
//
|
|
||||||
SessionUser sessionUser = SessionUser.fromUser(user);
|
SessionUser sessionUser = SessionUser.fromUser(user);
|
||||||
SessionUtils.putUser(sessionUser);
|
SessionUtils.putUser(sessionUser);
|
||||||
return new SimpleAuthenticationInfo(userId, password, getName());
|
return new SimpleAuthenticationInfo(userId, password, getName());
|
||||||
|
|
|
@ -3,6 +3,7 @@ package io.metersphere.service;
|
||||||
import io.metersphere.base.domain.ServiceIntegration;
|
import io.metersphere.base.domain.ServiceIntegration;
|
||||||
import io.metersphere.base.domain.ServiceIntegrationExample;
|
import io.metersphere.base.domain.ServiceIntegrationExample;
|
||||||
import io.metersphere.base.mapper.ServiceIntegrationMapper;
|
import io.metersphere.base.mapper.ServiceIntegrationMapper;
|
||||||
|
import io.metersphere.base.mapper.ext.ExtProjectMapper;
|
||||||
import io.metersphere.controller.request.IntegrationRequest;
|
import io.metersphere.controller.request.IntegrationRequest;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
@ -20,6 +21,8 @@ public class IntegrationService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ServiceIntegrationMapper serviceIntegrationMapper;
|
private ServiceIntegrationMapper serviceIntegrationMapper;
|
||||||
|
@Resource
|
||||||
|
private ExtProjectMapper extProjectMapper;
|
||||||
|
|
||||||
public ServiceIntegration save(ServiceIntegration service) {
|
public ServiceIntegration save(ServiceIntegration service) {
|
||||||
ServiceIntegrationExample example = new ServiceIntegrationExample();
|
ServiceIntegrationExample example = new ServiceIntegrationExample();
|
||||||
|
@ -63,6 +66,8 @@ public class IntegrationService {
|
||||||
.andOrganizationIdEqualTo(orgId)
|
.andOrganizationIdEqualTo(orgId)
|
||||||
.andPlatformEqualTo(platform);
|
.andPlatformEqualTo(platform);
|
||||||
serviceIntegrationMapper.deleteByExample(example);
|
serviceIntegrationMapper.deleteByExample(example);
|
||||||
|
// 删除项目关联的id/key
|
||||||
|
extProjectMapper.removeIssuePlatform(platform, orgId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ServiceIntegration> getAll(String orgId) {
|
public List<ServiceIntegration> getAll(String orgId) {
|
||||||
|
|
|
@ -1,177 +0,0 @@
|
||||||
package io.metersphere.service;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
|
||||||
import io.metersphere.base.domain.*;
|
|
||||||
import io.metersphere.base.mapper.TestCaseIssuesMapper;
|
|
||||||
import io.metersphere.commons.constants.IssuesManagePlatform;
|
|
||||||
import io.metersphere.commons.exception.MSException;
|
|
||||||
import io.metersphere.commons.user.SessionUser;
|
|
||||||
import io.metersphere.commons.utils.EncryptUtils;
|
|
||||||
import io.metersphere.commons.utils.RestTemplateUtils;
|
|
||||||
import io.metersphere.commons.utils.SessionUtils;
|
|
||||||
import io.metersphere.controller.ResultHolder;
|
|
||||||
import io.metersphere.controller.request.IntegrationRequest;
|
|
||||||
import io.metersphere.track.dto.IssuesDTO;
|
|
||||||
import io.metersphere.track.request.testcase.IssuesRequest;
|
|
||||||
import io.metersphere.track.service.TestCaseService;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.HttpMethod;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
|
||||||
import org.springframework.util.MultiValueMap;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public class IssuesService {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private IntegrationService integrationService;
|
|
||||||
@Resource
|
|
||||||
private TestCaseIssuesMapper testCaseIssuesMapper;
|
|
||||||
@Resource
|
|
||||||
private ProjectService projectService;
|
|
||||||
@Resource
|
|
||||||
private TestCaseService testCaseService;
|
|
||||||
|
|
||||||
|
|
||||||
public void testAuth() {
|
|
||||||
String url = "https://api.tapd.cn/quickstart/testauth";
|
|
||||||
ResultHolder call = call(url);
|
|
||||||
System.out.println(call.getData());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addIssues(IssuesRequest issuesRequest) {
|
|
||||||
String url = "https://api.tapd.cn/bugs";
|
|
||||||
String testCaseId = issuesRequest.getTestCaseId();
|
|
||||||
String tapdId = getTapdProjectId(testCaseId);
|
|
||||||
|
|
||||||
if (StringUtils.isBlank(tapdId)) {
|
|
||||||
MSException.throwException("未关联Tapd 项目ID");
|
|
||||||
}
|
|
||||||
|
|
||||||
MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<>();
|
|
||||||
paramMap.add("title", issuesRequest.getTitle());
|
|
||||||
paramMap.add("workspace_id", tapdId);
|
|
||||||
paramMap.add("description", issuesRequest.getContent());
|
|
||||||
|
|
||||||
ResultHolder result = call(url, HttpMethod.POST, paramMap);
|
|
||||||
|
|
||||||
String listJson = JSON.toJSONString(result.getData());
|
|
||||||
JSONObject jsonObject = JSONObject.parseObject(listJson);
|
|
||||||
String issuesId = jsonObject.getObject("Bug", IssuesDTO.class).getId();
|
|
||||||
|
|
||||||
// 用例与第三方缺陷平台中的缺陷关联
|
|
||||||
TestCaseIssues issues = new TestCaseIssues();
|
|
||||||
issues.setId(UUID.randomUUID().toString());
|
|
||||||
issues.setIssuesId(issuesId);
|
|
||||||
issues.setTestCaseId(testCaseId);
|
|
||||||
testCaseIssuesMapper.insert(issues);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ResultHolder call(String url) {
|
|
||||||
return call(url, HttpMethod.GET, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ResultHolder call(String url, HttpMethod httpMethod, Object params) {
|
|
||||||
String responseJson;
|
|
||||||
|
|
||||||
String config = tapdConfig();
|
|
||||||
JSONObject object = JSON.parseObject(config);
|
|
||||||
|
|
||||||
if (object == null) {
|
|
||||||
MSException.throwException("tapd config is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
String account = object.getString("account");
|
|
||||||
String password = object.getString("password");
|
|
||||||
|
|
||||||
HttpHeaders header = tapdAuth(account, password);
|
|
||||||
|
|
||||||
if (httpMethod.equals(HttpMethod.GET)) {
|
|
||||||
responseJson = RestTemplateUtils.get(url, header);
|
|
||||||
} else {
|
|
||||||
responseJson = RestTemplateUtils.post(url, params, header);
|
|
||||||
}
|
|
||||||
|
|
||||||
ResultHolder result = JSON.parseObject(responseJson, ResultHolder.class);
|
|
||||||
|
|
||||||
if (!result.isSuccess()) {
|
|
||||||
MSException.throwException(result.getMessage());
|
|
||||||
}
|
|
||||||
return JSON.parseObject(responseJson, ResultHolder.class);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private String tapdConfig() {
|
|
||||||
SessionUser user = SessionUtils.getUser();
|
|
||||||
String orgId = user.getLastOrganizationId();
|
|
||||||
|
|
||||||
IntegrationRequest request = new IntegrationRequest();
|
|
||||||
if (StringUtils.isBlank(orgId)) {
|
|
||||||
MSException.throwException("organization id is null");
|
|
||||||
}
|
|
||||||
request.setOrgId(orgId);
|
|
||||||
request.setPlatform(IssuesManagePlatform.Tapd.toString());
|
|
||||||
|
|
||||||
ServiceIntegration integration = integrationService.get(request);
|
|
||||||
return integration.getConfiguration();
|
|
||||||
}
|
|
||||||
|
|
||||||
private HttpHeaders tapdAuth(String apiUser, String password) {
|
|
||||||
String authKey = EncryptUtils.base64Encoding(apiUser + ":" + password);
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
|
||||||
headers.add("Authorization", "Basic " + authKey);
|
|
||||||
return headers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IssuesDTO getTapdIssues(String projectId, String issuesId) {
|
|
||||||
String url = "https://api.tapd.cn/bugs?workspace_id=" + projectId + "&id=" + issuesId;
|
|
||||||
ResultHolder call = call(url);
|
|
||||||
String listJson = JSON.toJSONString(call.getData());
|
|
||||||
if (StringUtils.equals(Boolean.FALSE.toString(), listJson)) {
|
|
||||||
return new IssuesDTO();
|
|
||||||
}
|
|
||||||
JSONObject jsonObject = JSONObject.parseObject(listJson);
|
|
||||||
return jsonObject.getObject("Bug", IssuesDTO.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<IssuesDTO> getIssues(String caseId) {
|
|
||||||
List<IssuesDTO> list = new ArrayList<>();
|
|
||||||
String tapdId = getTapdProjectId(caseId);
|
|
||||||
|
|
||||||
TestCaseIssuesExample example = new TestCaseIssuesExample();
|
|
||||||
example.createCriteria().andTestCaseIdEqualTo(caseId);
|
|
||||||
|
|
||||||
List<TestCaseIssues> issues = testCaseIssuesMapper.selectByExample(example);
|
|
||||||
List<String> issuesIds = issues.stream().map(issue -> issue.getIssuesId()).collect(Collectors.toList());
|
|
||||||
issuesIds.forEach(issuesId -> {
|
|
||||||
IssuesDTO dto = getTapdIssues(tapdId, issuesId);
|
|
||||||
if (StringUtils.isBlank(dto.getId())) {
|
|
||||||
// 缺陷不存在,解除用例和缺陷的关联
|
|
||||||
TestCaseIssuesExample issuesExample = new TestCaseIssuesExample();
|
|
||||||
issuesExample.createCriteria()
|
|
||||||
.andTestCaseIdEqualTo(caseId)
|
|
||||||
.andIssuesIdEqualTo(issuesId);
|
|
||||||
testCaseIssuesMapper.deleteByExample(issuesExample);
|
|
||||||
} else {
|
|
||||||
list.add(dto);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTapdProjectId(String testCaseId) {
|
|
||||||
TestCaseWithBLOBs testCase = testCaseService.getTestCase(testCaseId);
|
|
||||||
Project project = projectService.getProjectById(testCase.getProjectId());
|
|
||||||
return project.getTapdId();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,7 +5,6 @@ import io.metersphere.base.domain.*;
|
||||||
import io.metersphere.base.mapper.LoadTestMapper;
|
import io.metersphere.base.mapper.LoadTestMapper;
|
||||||
import io.metersphere.base.mapper.TestResourceMapper;
|
import io.metersphere.base.mapper.TestResourceMapper;
|
||||||
import io.metersphere.base.mapper.TestResourcePoolMapper;
|
import io.metersphere.base.mapper.TestResourcePoolMapper;
|
||||||
import io.metersphere.commons.constants.PerformanceTestStatus;
|
|
||||||
import io.metersphere.commons.constants.ResourceStatusEnum;
|
import io.metersphere.commons.constants.ResourceStatusEnum;
|
||||||
import io.metersphere.commons.exception.MSException;
|
import io.metersphere.commons.exception.MSException;
|
||||||
import io.metersphere.commons.utils.LogUtil;
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
|
@ -25,7 +24,6 @@ import org.springframework.web.client.RestTemplate;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -70,11 +68,9 @@ public class TestResourcePoolService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkTestStatus(String testResourcePoolId) {
|
public void checkTestStatus(String testResourcePoolId) {
|
||||||
List list = Arrays.asList(PerformanceTestStatus.Running, PerformanceTestStatus.Starting, PerformanceTestStatus.Error);
|
|
||||||
LoadTestExample example = new LoadTestExample();
|
LoadTestExample example = new LoadTestExample();
|
||||||
example.createCriteria()
|
example.createCriteria()
|
||||||
.andTestResourcePoolIdEqualTo(testResourcePoolId)
|
.andTestResourcePoolIdEqualTo(testResourcePoolId);
|
||||||
.andStatusIn(list);
|
|
||||||
if (loadTestMapper.countByExample(example) > 0) {
|
if (loadTestMapper.countByExample(example) > 0) {
|
||||||
MSException.throwException(Translator.get("test_resource_pool_is_use"));
|
MSException.throwException(Translator.get("test_resource_pool_is_use"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,6 +163,17 @@ public class UserService {
|
||||||
userMapper.insertSelective(user);
|
userMapper.insertSelective(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void createOssUser(User user) {
|
||||||
|
user.setCreateTime(System.currentTimeMillis());
|
||||||
|
user.setUpdateTime(System.currentTimeMillis());
|
||||||
|
user.setStatus(UserStatus.NORMAL);
|
||||||
|
if (StringUtils.isBlank(user.getEmail())) {
|
||||||
|
user.setEmail(user.getId() + "@metershpere.io");
|
||||||
|
}
|
||||||
|
userMapper.insertSelective(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void checkEmailIsExist(String email) {
|
private void checkEmailIsExist(String email) {
|
||||||
UserExample userExample = new UserExample();
|
UserExample userExample = new UserExample();
|
||||||
UserExample.Criteria criteria = userExample.createCriteria();
|
UserExample.Criteria criteria = userExample.createCriteria();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package io.metersphere.track.controller;
|
package io.metersphere.track.controller;
|
||||||
|
|
||||||
import io.metersphere.service.IssuesService;
|
import io.metersphere.base.domain.Issues;
|
||||||
import io.metersphere.track.dto.IssuesDTO;
|
import io.metersphere.track.service.IssuesService;
|
||||||
import io.metersphere.track.request.testcase.IssuesRequest;
|
import io.metersphere.track.request.testcase.IssuesRequest;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@ -21,7 +21,18 @@ public class TestCaseIssuesController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/get/{id}")
|
@GetMapping("/get/{id}")
|
||||||
public List<IssuesDTO> getIssues(@PathVariable String id) {
|
public List<Issues> getIssues(@PathVariable String id) {
|
||||||
return issuesService.getIssues(id);
|
return issuesService.getIssues(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/auth/{platform}")
|
||||||
|
public void testAuth(@PathVariable String platform) {
|
||||||
|
issuesService.testAuth(platform);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/close/{id}")
|
||||||
|
public void closeLocalIssue(@PathVariable String id) {
|
||||||
|
issuesService.closeLocalIssue(id);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,12 +86,32 @@ public class ReportResultComponent extends ReportComponent {
|
||||||
moduleResult.setCaseCount(0);
|
moduleResult.setCaseCount(0);
|
||||||
moduleResult.setPassCount(0);
|
moduleResult.setPassCount(0);
|
||||||
moduleResult.setIssuesCount(0);
|
moduleResult.setIssuesCount(0);
|
||||||
|
moduleResult.setFailureCount(0);
|
||||||
|
moduleResult.setBlockingCount(0);
|
||||||
|
moduleResult.setPrepareCount(0);
|
||||||
|
moduleResult.setSkipCount(0);
|
||||||
|
moduleResult.setUnderwayCount(0);
|
||||||
moduleResult.setModuleId(rootNodeId);
|
moduleResult.setModuleId(rootNodeId);
|
||||||
}
|
}
|
||||||
moduleResult.setCaseCount(moduleResult.getCaseCount() + 1);
|
moduleResult.setCaseCount(moduleResult.getCaseCount() + 1);
|
||||||
if (StringUtils.equals(testCase.getStatus(), TestPlanTestCaseStatus.Pass.name())) {
|
if (StringUtils.equals(testCase.getStatus(), TestPlanTestCaseStatus.Pass.name())) {
|
||||||
moduleResult.setPassCount(moduleResult.getPassCount() + 1);
|
moduleResult.setPassCount(moduleResult.getPassCount() + 1);
|
||||||
}
|
}
|
||||||
|
if (StringUtils.equals(testCase.getStatus(), TestPlanTestCaseStatus.Prepare.name())) {
|
||||||
|
moduleResult.setPrepareCount(moduleResult.getPrepareCount() + 1);
|
||||||
|
}
|
||||||
|
if (StringUtils.equals(testCase.getStatus(), TestPlanTestCaseStatus.Underway.name())) {
|
||||||
|
moduleResult.setUnderwayCount(moduleResult.getUnderwayCount() + 1);
|
||||||
|
}
|
||||||
|
if (StringUtils.equals(testCase.getStatus(), TestPlanTestCaseStatus.Failure.name())) {
|
||||||
|
moduleResult.setFailureCount(moduleResult.getFailureCount() + 1);
|
||||||
|
}
|
||||||
|
if (StringUtils.equals(testCase.getStatus(), TestPlanTestCaseStatus.Skip.name())) {
|
||||||
|
moduleResult.setSkipCount(moduleResult.getSkipCount() + 1);
|
||||||
|
}
|
||||||
|
if (StringUtils.equals(testCase.getStatus(), TestPlanTestCaseStatus.Blocking.name())) {
|
||||||
|
moduleResult.setBlockingCount(moduleResult.getBlockingCount() + 1);
|
||||||
|
}
|
||||||
if (StringUtils.isNotBlank(testCase.getIssues())) {
|
if (StringUtils.isNotBlank(testCase.getIssues())) {
|
||||||
if (JSON.parseObject(testCase.getIssues()).getBoolean("hasIssues")) {
|
if (JSON.parseObject(testCase.getIssues()).getBoolean("hasIssues")) {
|
||||||
moduleResult.setIssuesCount(moduleResult.getIssuesCount() + 1);
|
moduleResult.setIssuesCount(moduleResult.getIssuesCount() + 1);
|
||||||
|
|
|
@ -12,4 +12,9 @@ public class TestCaseReportModuleResultDTO {
|
||||||
private Integer passCount;
|
private Integer passCount;
|
||||||
private Double passRate;
|
private Double passRate;
|
||||||
private Integer issuesCount;
|
private Integer issuesCount;
|
||||||
|
private Integer prepareCount;
|
||||||
|
private Integer skipCount;
|
||||||
|
private Integer failureCount;
|
||||||
|
private Integer blockingCount;
|
||||||
|
private Integer underwayCount;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,494 @@
|
||||||
|
package io.metersphere.track.service;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import io.metersphere.base.domain.*;
|
||||||
|
import io.metersphere.base.mapper.IssuesMapper;
|
||||||
|
import io.metersphere.base.mapper.TestCaseIssuesMapper;
|
||||||
|
import io.metersphere.base.mapper.ext.ExtIssuesMapper;
|
||||||
|
import io.metersphere.commons.constants.IssuesManagePlatform;
|
||||||
|
import io.metersphere.commons.exception.MSException;
|
||||||
|
import io.metersphere.commons.user.SessionUser;
|
||||||
|
import io.metersphere.commons.utils.EncryptUtils;
|
||||||
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
|
import io.metersphere.commons.utils.RestTemplateUtils;
|
||||||
|
import io.metersphere.commons.utils.SessionUtils;
|
||||||
|
import io.metersphere.controller.ResultHolder;
|
||||||
|
import io.metersphere.controller.request.IntegrationRequest;
|
||||||
|
import io.metersphere.service.IntegrationService;
|
||||||
|
import io.metersphere.service.ProjectService;
|
||||||
|
import io.metersphere.track.request.testcase.IssuesRequest;
|
||||||
|
import org.springframework.http.HttpEntity;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
|
import org.springframework.util.MultiValueMap;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.web.client.HttpClientErrorException;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public class IssuesService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IntegrationService integrationService;
|
||||||
|
@Resource
|
||||||
|
private TestCaseIssuesMapper testCaseIssuesMapper;
|
||||||
|
@Resource
|
||||||
|
private ProjectService projectService;
|
||||||
|
@Resource
|
||||||
|
private TestCaseService testCaseService;
|
||||||
|
@Resource
|
||||||
|
private IssuesMapper issuesMapper;
|
||||||
|
@Resource
|
||||||
|
private ExtIssuesMapper extIssuesMapper;
|
||||||
|
|
||||||
|
|
||||||
|
public void testAuth(String platform) {
|
||||||
|
if (StringUtils.equals(platform, IssuesManagePlatform.Tapd.toString())) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
String tapdConfig = platformConfig(IssuesManagePlatform.Tapd.toString());
|
||||||
|
JSONObject object = JSON.parseObject(tapdConfig);
|
||||||
|
String account = object.getString("account");
|
||||||
|
String password = object.getString("password");
|
||||||
|
HttpHeaders headers = auth(account, password);
|
||||||
|
HttpEntity<MultiValueMap> requestEntity = new HttpEntity<>(headers);
|
||||||
|
RestTemplate restTemplate = new RestTemplate();
|
||||||
|
restTemplate.exchange("https://api.tapd.cn/quickstart/testauth", HttpMethod.GET, requestEntity, String.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.error(e.getMessage(), e);
|
||||||
|
MSException.throwException("验证失败!");
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
try {
|
||||||
|
String config = platformConfig(IssuesManagePlatform.Jira.toString());
|
||||||
|
JSONObject object = JSON.parseObject(config);
|
||||||
|
String account = object.getString("account");
|
||||||
|
String password = object.getString("password");
|
||||||
|
String url = object.getString("url");
|
||||||
|
HttpHeaders headers = auth(account, password);
|
||||||
|
HttpEntity<MultiValueMap> requestEntity = new HttpEntity<>(headers);
|
||||||
|
RestTemplate restTemplate = new RestTemplate();
|
||||||
|
restTemplate.exchange(url + "rest/api/2/issue/createmeta", HttpMethod.GET, requestEntity, String.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.error(e.getMessage(), e);
|
||||||
|
MSException.throwException("验证失败!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResultHolder call(String url) {
|
||||||
|
return call(url, HttpMethod.GET, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResultHolder call(String url, HttpMethod httpMethod, Object params) {
|
||||||
|
String responseJson;
|
||||||
|
|
||||||
|
String config = platformConfig(IssuesManagePlatform.Tapd.toString());
|
||||||
|
JSONObject object = JSON.parseObject(config);
|
||||||
|
|
||||||
|
if (object == null) {
|
||||||
|
MSException.throwException("tapd config is null");
|
||||||
|
}
|
||||||
|
|
||||||
|
String account = object.getString("account");
|
||||||
|
String password = object.getString("password");
|
||||||
|
|
||||||
|
HttpHeaders header = auth(account, password);
|
||||||
|
|
||||||
|
if (httpMethod.equals(HttpMethod.GET)) {
|
||||||
|
responseJson = RestTemplateUtils.get(url, header);
|
||||||
|
} else {
|
||||||
|
responseJson = RestTemplateUtils.post(url, params, header);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultHolder result = JSON.parseObject(responseJson, ResultHolder.class);
|
||||||
|
|
||||||
|
if (!result.isSuccess()) {
|
||||||
|
MSException.throwException(result.getMessage());
|
||||||
|
}
|
||||||
|
return JSON.parseObject(responseJson, ResultHolder.class);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String platformConfig(String platform) {
|
||||||
|
SessionUser user = SessionUtils.getUser();
|
||||||
|
String orgId = user.getLastOrganizationId();
|
||||||
|
|
||||||
|
IntegrationRequest request = new IntegrationRequest();
|
||||||
|
if (StringUtils.isBlank(orgId)) {
|
||||||
|
MSException.throwException("organization id is null");
|
||||||
|
}
|
||||||
|
request.setOrgId(orgId);
|
||||||
|
request.setPlatform(platform);
|
||||||
|
|
||||||
|
ServiceIntegration integration = integrationService.get(request);
|
||||||
|
return integration.getConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
private HttpHeaders auth(String apiUser, String password) {
|
||||||
|
String authKey = EncryptUtils.base64Encoding(apiUser + ":" + password);
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.add("Authorization", "Basic " + authKey);
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addIssues(IssuesRequest issuesRequest) {
|
||||||
|
SessionUser user = SessionUtils.getUser();
|
||||||
|
String orgId = user.getLastOrganizationId();
|
||||||
|
|
||||||
|
boolean tapd = isIntegratedPlatform(orgId, IssuesManagePlatform.Tapd.toString());
|
||||||
|
boolean jira = isIntegratedPlatform(orgId, IssuesManagePlatform.Jira.toString());
|
||||||
|
|
||||||
|
String tapdId = getTapdProjectId(issuesRequest.getTestCaseId());
|
||||||
|
String jiraKey = getJiraProjectKey(issuesRequest.getTestCaseId());
|
||||||
|
|
||||||
|
if (tapd) {
|
||||||
|
// 是否关联了项目
|
||||||
|
if (StringUtils.isNotBlank(tapdId)) {
|
||||||
|
addTapdIssues(issuesRequest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jira) {
|
||||||
|
if (StringUtils.isNotBlank(jiraKey)) {
|
||||||
|
addJiraIssues(issuesRequest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(tapdId) && StringUtils.isBlank(jiraKey)) {
|
||||||
|
addLocalIssues(issuesRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addTapdIssues(IssuesRequest issuesRequest) {
|
||||||
|
String url = "https://api.tapd.cn/bugs";
|
||||||
|
String testCaseId = issuesRequest.getTestCaseId();
|
||||||
|
String tapdId = getTapdProjectId(testCaseId);
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(tapdId)) {
|
||||||
|
MSException.throwException("未关联Tapd 项目ID");
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<>();
|
||||||
|
paramMap.add("title", issuesRequest.getTitle());
|
||||||
|
paramMap.add("workspace_id", tapdId);
|
||||||
|
paramMap.add("description", issuesRequest.getContent());
|
||||||
|
|
||||||
|
ResultHolder result = call(url, HttpMethod.POST, paramMap);
|
||||||
|
|
||||||
|
String listJson = JSON.toJSONString(result.getData());
|
||||||
|
JSONObject jsonObject = JSONObject.parseObject(listJson);
|
||||||
|
String issuesId = jsonObject.getObject("Bug", Issues.class).getId();
|
||||||
|
|
||||||
|
// 用例与第三方缺陷平台中的缺陷关联
|
||||||
|
TestCaseIssues testCaseIssues = new TestCaseIssues();
|
||||||
|
testCaseIssues.setId(UUID.randomUUID().toString());
|
||||||
|
testCaseIssues.setIssuesId(issuesId);
|
||||||
|
testCaseIssues.setTestCaseId(testCaseId);
|
||||||
|
testCaseIssuesMapper.insert(testCaseIssues);
|
||||||
|
|
||||||
|
// 插入缺陷表
|
||||||
|
Issues issues = new Issues();
|
||||||
|
issues.setId(issuesId);
|
||||||
|
issues.setPlatform(IssuesManagePlatform.Tapd.toString());
|
||||||
|
issuesMapper.insert(issues);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addJiraIssues(IssuesRequest issuesRequest) {
|
||||||
|
String config = platformConfig(IssuesManagePlatform.Jira.toString());
|
||||||
|
JSONObject object = JSON.parseObject(config);
|
||||||
|
|
||||||
|
if (object == null) {
|
||||||
|
MSException.throwException("jira config is null");
|
||||||
|
}
|
||||||
|
|
||||||
|
String account = object.getString("account");
|
||||||
|
String password = object.getString("password");
|
||||||
|
String url = object.getString("url");
|
||||||
|
String auth = EncryptUtils.base64Encoding(account + ":" + password);
|
||||||
|
|
||||||
|
String testCaseId = issuesRequest.getTestCaseId();
|
||||||
|
String jiraKey = getJiraProjectKey(testCaseId);
|
||||||
|
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(jiraKey)) {
|
||||||
|
MSException.throwException("未关联Jira 项目Key");
|
||||||
|
}
|
||||||
|
|
||||||
|
String json = "{\n" +
|
||||||
|
" \"fields\":{\n" +
|
||||||
|
" \"project\":{\n" +
|
||||||
|
" \"key\":\"" + jiraKey + "\"\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"summary\":\"" + issuesRequest.getTitle() + "\",\n" +
|
||||||
|
" \"description\":\"" + issuesRequest.getContent() + "\",\n" +
|
||||||
|
" \"issuetype\":{\n" +
|
||||||
|
" \"id\":\"10009\",\n" +
|
||||||
|
" \"name\":\"Defect\"\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
"}";
|
||||||
|
|
||||||
|
String result = addJiraIssue(url, auth, json);
|
||||||
|
|
||||||
|
JSONObject jsonObject = JSON.parseObject(result);
|
||||||
|
String id = jsonObject.getString("id");
|
||||||
|
|
||||||
|
// 用例与第三方缺陷平台中的缺陷关联
|
||||||
|
TestCaseIssues testCaseIssues = new TestCaseIssues();
|
||||||
|
testCaseIssues.setId(UUID.randomUUID().toString());
|
||||||
|
testCaseIssues.setIssuesId(id);
|
||||||
|
testCaseIssues.setTestCaseId(testCaseId);
|
||||||
|
testCaseIssuesMapper.insert(testCaseIssues);
|
||||||
|
|
||||||
|
// 插入缺陷表
|
||||||
|
Issues issues = new Issues();
|
||||||
|
issues.setId(id);
|
||||||
|
issues.setPlatform(IssuesManagePlatform.Jira.toString());
|
||||||
|
issuesMapper.insert(issues);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String addJiraIssue(String url, String auth, String json) {
|
||||||
|
HttpHeaders requestHeaders = new HttpHeaders();
|
||||||
|
requestHeaders.add("Authorization", "Basic " + auth);
|
||||||
|
requestHeaders.setContentType(org.springframework.http.MediaType.APPLICATION_JSON);
|
||||||
|
//HttpEntity
|
||||||
|
HttpEntity<String> requestEntity = new HttpEntity<>(json, requestHeaders);
|
||||||
|
RestTemplate restTemplate = new RestTemplate();
|
||||||
|
//post
|
||||||
|
ResponseEntity<String> responseEntity = null;
|
||||||
|
try {
|
||||||
|
responseEntity = restTemplate.exchange(url + "/rest/api/2/issue", HttpMethod.POST, requestEntity, String.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.error(e.getMessage(), e);
|
||||||
|
MSException.throwException("调用Jira接口创建缺陷失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
return responseEntity.getBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addLocalIssues(IssuesRequest request) {
|
||||||
|
SessionUser user = SessionUtils.getUser();
|
||||||
|
String id = UUID.randomUUID().toString();
|
||||||
|
Issues issues = new Issues();
|
||||||
|
issues.setId(id);
|
||||||
|
issues.setStatus("new");
|
||||||
|
issues.setReporter(user.getId());
|
||||||
|
issues.setTitle(request.getTitle());
|
||||||
|
issues.setDescription(request.getContent());
|
||||||
|
issues.setCreateTime(System.currentTimeMillis());
|
||||||
|
issues.setUpdateTime(System.currentTimeMillis());
|
||||||
|
issues.setPlatform(IssuesManagePlatform.Local.toString());
|
||||||
|
issuesMapper.insert(issues);
|
||||||
|
|
||||||
|
TestCaseIssues testCaseIssues = new TestCaseIssues();
|
||||||
|
testCaseIssues.setId(UUID.randomUUID().toString());
|
||||||
|
testCaseIssues.setIssuesId(id);
|
||||||
|
testCaseIssues.setTestCaseId(request.getTestCaseId());
|
||||||
|
testCaseIssuesMapper.insert(testCaseIssues);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Issues getTapdIssues(String projectId, String issuesId) {
|
||||||
|
String url = "https://api.tapd.cn/bugs?workspace_id=" + projectId + "&id=" + issuesId;
|
||||||
|
ResultHolder call = call(url);
|
||||||
|
String listJson = JSON.toJSONString(call.getData());
|
||||||
|
if (StringUtils.equals(Boolean.FALSE.toString(), listJson)) {
|
||||||
|
return new Issues();
|
||||||
|
}
|
||||||
|
JSONObject jsonObject = JSONObject.parseObject(listJson);
|
||||||
|
return jsonObject.getObject("Bug", Issues.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Issues getJiraIssues(HttpHeaders headers, String url, String issuesId) {
|
||||||
|
HttpEntity<MultiValueMap> requestEntity = new HttpEntity<>(headers);
|
||||||
|
RestTemplate restTemplate = new RestTemplate();
|
||||||
|
//post
|
||||||
|
ResponseEntity<String> responseEntity;
|
||||||
|
Issues issues = new Issues();
|
||||||
|
try {
|
||||||
|
responseEntity = restTemplate.exchange(url + "/rest/api/2/issue/" + issuesId, HttpMethod.GET, requestEntity, String.class);
|
||||||
|
String body = responseEntity.getBody();
|
||||||
|
|
||||||
|
JSONObject obj = JSONObject.parseObject(body);
|
||||||
|
JSONObject fields = (JSONObject) obj.get("fields");
|
||||||
|
JSONObject statusObj = (JSONObject) fields.get("status");
|
||||||
|
JSONObject statusCategory = (JSONObject) statusObj.get("statusCategory");
|
||||||
|
|
||||||
|
String id = obj.getString("id");
|
||||||
|
String title = fields.getString("summary");
|
||||||
|
String description = fields.getString("description");
|
||||||
|
String status = statusCategory.getString("key");
|
||||||
|
|
||||||
|
issues.setId(id);
|
||||||
|
issues.setTitle(title);
|
||||||
|
issues.setDescription(description);
|
||||||
|
issues.setStatus(status);
|
||||||
|
issues.setPlatform(IssuesManagePlatform.Jira.toString());
|
||||||
|
} catch (HttpClientErrorException.NotFound e) {
|
||||||
|
LogUtil.error(e.getStackTrace(), e);
|
||||||
|
return new Issues();
|
||||||
|
} catch (HttpClientErrorException.Unauthorized e) {
|
||||||
|
LogUtil.error(e.getStackTrace(), e);
|
||||||
|
MSException.throwException("获取Jira缺陷失败,检查Jira配置信息");
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.error(e.getMessage(), e);
|
||||||
|
MSException.throwException("调用Jira接口获取缺陷失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
return issues;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Issues> getIssues(String caseId) {
|
||||||
|
List<Issues> list = new ArrayList<>();
|
||||||
|
SessionUser user = SessionUtils.getUser();
|
||||||
|
String orgId = user.getLastOrganizationId();
|
||||||
|
|
||||||
|
boolean tapd = isIntegratedPlatform(orgId, IssuesManagePlatform.Tapd.toString());
|
||||||
|
boolean jira = isIntegratedPlatform(orgId, IssuesManagePlatform.Jira.toString());
|
||||||
|
|
||||||
|
if (tapd) {
|
||||||
|
// 是否关联了项目
|
||||||
|
String tapdId = getTapdProjectId(caseId);
|
||||||
|
if (StringUtils.isNotBlank(tapdId)) {
|
||||||
|
list.addAll(getTapdIssues(caseId));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jira) {
|
||||||
|
String jiraKey = getJiraProjectKey(caseId);
|
||||||
|
if (StringUtils.isNotBlank(jiraKey)) {
|
||||||
|
list.addAll(getJiraIssues(caseId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list.addAll(getLocalIssues(caseId));
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Issues> getTapdIssues(String caseId) {
|
||||||
|
List<Issues> list = new ArrayList<>();
|
||||||
|
String tapdId = getTapdProjectId(caseId);
|
||||||
|
|
||||||
|
TestCaseIssuesExample example = new TestCaseIssuesExample();
|
||||||
|
example.createCriteria().andTestCaseIdEqualTo(caseId);
|
||||||
|
|
||||||
|
List<Issues> issues = extIssuesMapper.getIssues(caseId, IssuesManagePlatform.Tapd.toString());
|
||||||
|
|
||||||
|
List<String> issuesIds = issues.stream().map(Issues::getId).collect(Collectors.toList());
|
||||||
|
issuesIds.forEach(issuesId -> {
|
||||||
|
Issues dto = getTapdIssues(tapdId, issuesId);
|
||||||
|
if (StringUtils.isBlank(dto.getId())) {
|
||||||
|
// 缺陷不存在,解除用例和缺陷的关联
|
||||||
|
TestCaseIssuesExample issuesExample = new TestCaseIssuesExample();
|
||||||
|
issuesExample.createCriteria()
|
||||||
|
.andTestCaseIdEqualTo(caseId)
|
||||||
|
.andIssuesIdEqualTo(issuesId);
|
||||||
|
testCaseIssuesMapper.deleteByExample(issuesExample);
|
||||||
|
issuesMapper.deleteByPrimaryKey(issuesId);
|
||||||
|
} else {
|
||||||
|
dto.setPlatform(IssuesManagePlatform.Tapd.toString());
|
||||||
|
// 缺陷状态为 关闭,则不显示
|
||||||
|
if (!StringUtils.equals("closed", dto.getStatus())) {
|
||||||
|
list.add(dto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Issues> getJiraIssues(String caseId) {
|
||||||
|
List<Issues> list = new ArrayList<>();
|
||||||
|
|
||||||
|
String config = platformConfig(IssuesManagePlatform.Jira.toString());
|
||||||
|
JSONObject object = JSON.parseObject(config);
|
||||||
|
|
||||||
|
if (object == null) {
|
||||||
|
MSException.throwException("tapd config is null");
|
||||||
|
}
|
||||||
|
|
||||||
|
String account = object.getString("account");
|
||||||
|
String password = object.getString("password");
|
||||||
|
String url = object.getString("url");
|
||||||
|
HttpHeaders headers = auth(account, password);
|
||||||
|
|
||||||
|
TestCaseIssuesExample example = new TestCaseIssuesExample();
|
||||||
|
example.createCriteria().andTestCaseIdEqualTo(caseId);
|
||||||
|
|
||||||
|
List<Issues> issues = extIssuesMapper.getIssues(caseId, IssuesManagePlatform.Jira.toString());
|
||||||
|
|
||||||
|
List<String> issuesIds = issues.stream().map(Issues::getId).collect(Collectors.toList());
|
||||||
|
issuesIds.forEach(issuesId -> {
|
||||||
|
Issues dto = getJiraIssues(headers, url, issuesId);
|
||||||
|
if (StringUtils.isBlank(dto.getId())) {
|
||||||
|
// 缺陷不存在,解除用例和缺陷的关联
|
||||||
|
TestCaseIssuesExample issuesExample = new TestCaseIssuesExample();
|
||||||
|
issuesExample.createCriteria()
|
||||||
|
.andTestCaseIdEqualTo(caseId)
|
||||||
|
.andIssuesIdEqualTo(issuesId);
|
||||||
|
testCaseIssuesMapper.deleteByExample(issuesExample);
|
||||||
|
issuesMapper.deleteByPrimaryKey(issuesId);
|
||||||
|
} else {
|
||||||
|
// 缺陷状态为 完成,则不显示
|
||||||
|
if (!StringUtils.equals("done", dto.getStatus())) {
|
||||||
|
list.add(dto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Issues> getLocalIssues(String caseId) {
|
||||||
|
List<Issues> list = extIssuesMapper.getIssues(caseId, IssuesManagePlatform.Local.toString());
|
||||||
|
List<Issues> issues = list.stream()
|
||||||
|
.filter(l -> !StringUtils.equals(l.getStatus(), "closed"))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
return issues;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTapdProjectId(String testCaseId) {
|
||||||
|
TestCaseWithBLOBs testCase = testCaseService.getTestCase(testCaseId);
|
||||||
|
Project project = projectService.getProjectById(testCase.getProjectId());
|
||||||
|
return project.getTapdId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getJiraProjectKey(String testCaseId) {
|
||||||
|
TestCaseWithBLOBs testCase = testCaseService.getTestCase(testCaseId);
|
||||||
|
Project project = projectService.getProjectById(testCase.getProjectId());
|
||||||
|
return project.getJiraKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否关联平台
|
||||||
|
*/
|
||||||
|
public boolean isIntegratedPlatform(String orgId, String platform) {
|
||||||
|
IntegrationRequest request = new IntegrationRequest();
|
||||||
|
request.setPlatform(platform);
|
||||||
|
request.setOrgId(orgId);
|
||||||
|
ServiceIntegration integration = integrationService.get(request);
|
||||||
|
return StringUtils.isNotBlank(integration.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closeLocalIssue(String issueId) {
|
||||||
|
Issues issues = new Issues();
|
||||||
|
issues.setId(issueId);
|
||||||
|
issues.setStatus("closed");
|
||||||
|
issuesMapper.updateByPrimaryKeySelective(issues);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1 +1 @@
|
||||||
Subproject commit 9b9208204ce138e2cb49d9549eac140019293160
|
Subproject commit 8eff343619df1572e1cded52f173257ef4b518a1
|
|
@ -13,6 +13,19 @@ create table if not exists test_case_issues
|
||||||
id varchar(50) not null
|
id varchar(50) not null
|
||||||
primary key,
|
primary key,
|
||||||
test_case_id varchar(50) not null,
|
test_case_id varchar(50) not null,
|
||||||
issues_id varchar(100) not null,
|
issues_id varchar(100) not null
|
||||||
platform varchar(50) not null
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
create table if not exists issues
|
||||||
|
(
|
||||||
|
id varchar(50) not null
|
||||||
|
primary key,
|
||||||
|
title varchar(50) null,
|
||||||
|
description text null,
|
||||||
|
status varchar(50) null,
|
||||||
|
create_time bigint(13) null,
|
||||||
|
update_time bigint(13) null,
|
||||||
|
reporter varchar(50) null comment 'case issues creator',
|
||||||
|
lastmodify varchar(50) null,
|
||||||
|
platform varchar(50) null
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
@ -1,4 +1,4 @@
|
||||||
|
export HEAP=$(cat /proc/meminfo | grep MemTotal | awk '{ mem=int($2/1024/1024 * 3/4 + 0.5); metasize=int(mem/4+0.5)"g"; if(mem<1) mem=1; if (metasize == "0g") metasize="256m"; HEAP="-Xms"mem"g -Xmx"mem"g -XX:MaxMetaspaceSize="metasize; print HEAP }')
|
||||||
for file in ${TESTS_DIR}/*.jmx; do
|
for file in ${TESTS_DIR}/*.jmx; do
|
||||||
echo "one shot run."
|
|
||||||
jmeter -n -t ${file} -Jserver.rmi.ssl.disable=${SSL_DISABLED}
|
jmeter -n -t ${file} -Jserver.rmi.ssl.disable=${SSL_DISABLED}
|
||||||
done
|
done
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
import MsUser from "./components/common/head/HeaderUser";
|
import MsUser from "./components/common/head/HeaderUser";
|
||||||
import MsHeaderOrgWs from "./components/common/head/HeaderOrgWs";
|
import MsHeaderOrgWs from "./components/common/head/HeaderOrgWs";
|
||||||
import MsLanguageSwitch from "./components/common/head/LanguageSwitch";
|
import MsLanguageSwitch from "./components/common/head/LanguageSwitch";
|
||||||
|
import {saveLocalStorage} from "../common/js/utils";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'app',
|
name: 'app',
|
||||||
|
@ -36,7 +37,8 @@
|
||||||
beforeCreate() {
|
beforeCreate() {
|
||||||
this.$get("/isLogin").then(response => {
|
this.$get("/isLogin").then(response => {
|
||||||
if (response.data.success) {
|
if (response.data.success) {
|
||||||
this.$setLang(response.data.data);
|
this.$setLang(response.data.data.language);
|
||||||
|
saveLocalStorage(response.data);
|
||||||
this.auth = true;
|
this.auth = true;
|
||||||
} else {
|
} else {
|
||||||
window.location.href = "/login"
|
window.location.href = "/login"
|
||||||
|
|
|
@ -11,8 +11,13 @@
|
||||||
|
|
||||||
<ms-dropdown :default-command="body.format" v-if="body.type == 'Raw'" :commands="modes" @command="modeChange"/>
|
<ms-dropdown :default-command="body.format" v-if="body.type == 'Raw'" :commands="modes" @command="modeChange"/>
|
||||||
|
|
||||||
<ms-api-variable :is-read-only="isReadOnly" :items="body.kvs" v-if="body.isKV()"/>
|
<ms-api-variable :is-read-only="isReadOnly"
|
||||||
|
:parameters="body.kvs"
|
||||||
|
:environment="environment"
|
||||||
|
:scenario="scenario"
|
||||||
|
:extract="extract"
|
||||||
|
:description="$t('api_test.request.parameters_desc')"
|
||||||
|
v-if="body.isKV()"/>
|
||||||
<div class="body-raw" v-if="body.type == 'Raw'">
|
<div class="body-raw" v-if="body.type == 'Raw'">
|
||||||
<ms-code-edit :mode="body.format" :read-only="isReadOnly" :data.sync="body.raw" :modes="modes" ref="codeEdit"/>
|
<ms-code-edit :mode="body.format" :read-only="isReadOnly" :data.sync="body.raw" :modes="modes" ref="codeEdit"/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -22,7 +27,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import MsApiKeyValue from "./ApiKeyValue";
|
import MsApiKeyValue from "./ApiKeyValue";
|
||||||
import {Body, BODY_FORMAT, BODY_TYPE} from "../model/ScenarioModel";
|
import {Body, BODY_FORMAT, BODY_TYPE, Scenario} from "../model/ScenarioModel";
|
||||||
import MsCodeEdit from "../../../common/components/MsCodeEdit";
|
import MsCodeEdit from "../../../common/components/MsCodeEdit";
|
||||||
import MsDropdown from "../../../common/components/MsDropdown";
|
import MsDropdown from "../../../common/components/MsDropdown";
|
||||||
import MsApiVariable from "@/business/components/api/test/components/ApiVariable";
|
import MsApiVariable from "@/business/components/api/test/components/ApiVariable";
|
||||||
|
@ -32,6 +37,9 @@ export default {
|
||||||
components: {MsApiVariable, MsDropdown, MsCodeEdit, MsApiKeyValue},
|
components: {MsApiVariable, MsDropdown, MsCodeEdit, MsApiKeyValue},
|
||||||
props: {
|
props: {
|
||||||
body: Body,
|
body: Body,
|
||||||
|
scenario: Scenario,
|
||||||
|
environment: Object,
|
||||||
|
extract: Object,
|
||||||
isReadOnly: {
|
isReadOnly: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
|
|
@ -34,13 +34,14 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
<ms-api-variable-advance ref="variableAdvance" :environment="environment" :scenario="scenario" :request="request"
|
<ms-api-variable-advance ref="variableAdvance" :environment="environment" :scenario="scenario"
|
||||||
|
:parameters="parameters"
|
||||||
:current-item="currentItem"/>
|
:current-item="currentItem"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {HttpRequest, KeyValue, Scenario} from "../model/ScenarioModel";
|
import {KeyValue, Scenario} from "../model/ScenarioModel";
|
||||||
import {MOCKJS_FUNC} from "@/common/js/constants";
|
import {MOCKJS_FUNC} from "@/common/js/constants";
|
||||||
import MsApiVariableAdvance from "@/business/components/api/test/components/ApiVariableAdvance";
|
import MsApiVariableAdvance from "@/business/components/api/test/components/ApiVariableAdvance";
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ export default {
|
||||||
keyPlaceholder: String,
|
keyPlaceholder: String,
|
||||||
valuePlaceholder: String,
|
valuePlaceholder: String,
|
||||||
description: String,
|
description: String,
|
||||||
request: HttpRequest,
|
parameters: Array,
|
||||||
environment: Object,
|
environment: Object,
|
||||||
scenario: Scenario,
|
scenario: Scenario,
|
||||||
isReadOnly: {
|
isReadOnly: {
|
||||||
|
@ -63,7 +64,6 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
currentItem: null,
|
currentItem: null,
|
||||||
parameters: [],
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="变量">
|
<el-tab-pane :label="$t('api_test.variable')">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="6" class="col-height">
|
<el-col :span="6" class="col-height">
|
||||||
<div v-if="environment">
|
<div v-if="environment">
|
||||||
|
@ -49,15 +49,14 @@
|
||||||
<el-tree :data="preRequestParams" :props="treeProps" @node-click="selectVariable"></el-tree>
|
<el-tree :data="preRequestParams" :props="treeProps" @node-click="selectVariable"></el-tree>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6" v-for="(itemFunc, itemIndex) in jmeterVariableFuncs" :key="itemIndex" class="col-height">
|
<el-col :span="18" class="col-height">
|
||||||
<div>
|
<div>
|
||||||
<div v-for="(func, funcIndex) in jmeterFuncs"
|
<h1>{{ $t('api_test.request.jmeter_func') }}</h1>
|
||||||
:key="`${itemIndex}-${funcIndex}`">
|
<el-table border :data="jmeterFuncs" class="adjust-table table-content" height="400">
|
||||||
<el-row>
|
<el-table-column prop="type" label="Type" width="150"/>
|
||||||
<el-radio size="mini" v-model="itemFunc.name" :label="func.name"
|
<el-table-column prop="name" label="Functions" width="250"/>
|
||||||
@change="methodChange(itemFunc, func)"/>
|
<el-table-column prop="description" label="Description"/>
|
||||||
</el-row>
|
</el-table>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
@ -91,13 +90,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {calculate, HttpRequest, Scenario} from "@/business/components/api/test/model/ScenarioModel";
|
import {calculate, Scenario} from "@/business/components/api/test/model/ScenarioModel";
|
||||||
import {JMETER_FUNC, MOCKJS_FUNC} from "@/common/js/constants";
|
import {JMETER_FUNC, MOCKJS_FUNC} from "@/common/js/constants";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MsApiVariableAdvance",
|
name: "MsApiVariableAdvance",
|
||||||
props: {
|
props: {
|
||||||
request: HttpRequest,
|
parameters: Array,
|
||||||
environment: Object,
|
environment: Object,
|
||||||
scenario: Scenario,
|
scenario: Scenario,
|
||||||
currentItem: Object,
|
currentItem: Object,
|
||||||
|
@ -163,9 +162,6 @@ export default {
|
||||||
this.itemValueVisible = true;
|
this.itemValueVisible = true;
|
||||||
},
|
},
|
||||||
prepareData() {
|
prepareData() {
|
||||||
if (this.request) {
|
|
||||||
this.parameters = this.request.parameters;
|
|
||||||
}
|
|
||||||
if (this.scenario) {
|
if (this.scenario) {
|
||||||
let variables = this.scenario.variables;
|
let variables = this.scenario.variables;
|
||||||
this.scenarioParams = [
|
this.scenarioParams = [
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
<template>
|
||||||
|
<div class="script-content">
|
||||||
|
<ms-code-edit mode="java" :read-only="isReadOnly" :data.sync="beanShellProcessor.script" theme="eclipse" :modes="['java']" ref="codeEdit"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import MsCodeEdit from "../../../../common/components/MsCodeEdit";
|
||||||
|
export default {
|
||||||
|
name: "MsBeanShellProcessor",
|
||||||
|
components: {MsCodeEdit},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
isReadOnly: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
beanShellProcessor: {
|
||||||
|
type: Object,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
.ace_editor {
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.script-content {
|
||||||
|
padding: 15px 0;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
|
@ -46,7 +46,7 @@
|
||||||
<el-tabs v-model="activeName">
|
<el-tabs v-model="activeName">
|
||||||
<el-tab-pane :label="$t('api_test.request.parameters')" name="parameters">
|
<el-tab-pane :label="$t('api_test.request.parameters')" name="parameters">
|
||||||
<ms-api-variable :is-read-only="isReadOnly"
|
<ms-api-variable :is-read-only="isReadOnly"
|
||||||
:request="request"
|
:parameters="request.parameters"
|
||||||
:environment="request.environment"
|
:environment="request.environment"
|
||||||
:scenario="scenario"
|
:scenario="scenario"
|
||||||
:extract="request.extract"
|
:extract="request.extract"
|
||||||
|
@ -56,7 +56,11 @@
|
||||||
<ms-api-key-value :is-read-only="isReadOnly" :suggestions="headerSuggestions" :items="request.headers"/>
|
<ms-api-key-value :is-read-only="isReadOnly" :suggestions="headerSuggestions" :items="request.headers"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane :label="$t('api_test.request.body')" name="body" v-if="isNotGet">
|
<el-tab-pane :label="$t('api_test.request.body')" name="body" v-if="isNotGet">
|
||||||
<ms-api-body :is-read-only="isReadOnly" :body="request.body"/>
|
<ms-api-body :is-read-only="isReadOnly"
|
||||||
|
:body="request.body"
|
||||||
|
:scenario="scenario"
|
||||||
|
:extract="request.extract"
|
||||||
|
:environment="request.environment"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane :label="$t('api_test.request.assertions.label')" name="assertions">
|
<el-tab-pane :label="$t('api_test.request.assertions.label')" name="assertions">
|
||||||
<ms-api-assertions :is-read-only="isReadOnly" :assertions="request.assertions"/>
|
<ms-api-assertions :is-read-only="isReadOnly" :assertions="request.assertions"/>
|
||||||
|
@ -64,6 +68,12 @@
|
||||||
<el-tab-pane :label="$t('api_test.request.extract.label')" name="extract">
|
<el-tab-pane :label="$t('api_test.request.extract.label')" name="extract">
|
||||||
<ms-api-extract :is-read-only="isReadOnly" :extract="request.extract"/>
|
<ms-api-extract :is-read-only="isReadOnly" :extract="request.extract"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
<el-tab-pane :label="'预执行脚本'" name="beanShellPreProcessor">
|
||||||
|
<ms-bean-shell-processor :is-read-only="isReadOnly" :bean-shell-processor="request.beanShellPreProcessor"/>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane :label="'后执行脚本'" name="beanShellPostProcessor">
|
||||||
|
<ms-bean-shell-processor :is-read-only="isReadOnly" :bean-shell-processor="request.beanShellPostProcessor"/>
|
||||||
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</el-form>
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
|
@ -77,10 +87,13 @@ import MsApiExtract from "../extract/ApiExtract";
|
||||||
import ApiRequestMethodSelect from "../collapse/ApiRequestMethodSelect";
|
import ApiRequestMethodSelect from "../collapse/ApiRequestMethodSelect";
|
||||||
import {REQUEST_HEADERS} from "@/common/js/constants";
|
import {REQUEST_HEADERS} from "@/common/js/constants";
|
||||||
import MsApiVariable from "@/business/components/api/test/components/ApiVariable";
|
import MsApiVariable from "@/business/components/api/test/components/ApiVariable";
|
||||||
|
import MsBeanShellProcessor from "../processor/BeanShellProcessor";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MsApiHttpRequestForm",
|
name: "MsApiHttpRequestForm",
|
||||||
components: {MsApiVariable, ApiRequestMethodSelect, MsApiExtract, MsApiAssertions, MsApiBody, MsApiKeyValue},
|
components: {
|
||||||
|
MsBeanShellProcessor,
|
||||||
|
MsApiVariable, ApiRequestMethodSelect, MsApiExtract, MsApiAssertions, MsApiBody, MsApiKeyValue},
|
||||||
props: {
|
props: {
|
||||||
request: HttpRequest,
|
request: HttpRequest,
|
||||||
scenario: Scenario,
|
scenario: Scenario,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="request-form">
|
<div class="request-form">
|
||||||
<component @runDebug="runDebug" :is="component" :is-read-only="isReadOnly" :request="request" :scenario="scenario"/>
|
<component @runDebug="runDebug" :is="component" :is-read-only="isReadOnly" :request="request" :scenario="scenario"/>
|
||||||
<ms-scenario-results v-loading="debugReportLoading" v-if="isCompleted" :scenarios="isCompleted ? request.debugReport.scenarios : []"/>
|
<ms-request-result-tail v-loading="debugReportLoading" v-if="isCompleted" :request="request.debugRequestResult ? request.debugRequestResult : {responseResult: {}, subRequestResults: []}" :scenario-name="request.debugScenario ? request.debugScenario.name : ''"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -10,10 +10,11 @@ import {Request, RequestFactory, Scenario} from "../../model/ScenarioModel";
|
||||||
import MsApiHttpRequestForm from "./ApiHttpRequestForm";
|
import MsApiHttpRequestForm from "./ApiHttpRequestForm";
|
||||||
import MsApiDubboRequestForm from "./ApiDubboRequestForm";
|
import MsApiDubboRequestForm from "./ApiDubboRequestForm";
|
||||||
import MsScenarioResults from "../../../report/components/ScenarioResults";
|
import MsScenarioResults from "../../../report/components/ScenarioResults";
|
||||||
|
import MsRequestResultTail from "../../../report/components/RequestResultTail";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MsApiRequestForm",
|
name: "MsApiRequestForm",
|
||||||
components: {MsScenarioResults, MsApiDubboRequestForm, MsApiHttpRequestForm},
|
components: {MsRequestResultTail, MsScenarioResults, MsApiDubboRequestForm, MsApiHttpRequestForm},
|
||||||
props: {
|
props: {
|
||||||
scenario: Scenario,
|
scenario: Scenario,
|
||||||
request: Request,
|
request: Request,
|
||||||
|
@ -66,12 +67,13 @@ export default {
|
||||||
try {
|
try {
|
||||||
res = JSON.parse(report.content);
|
res = JSON.parse(report.content);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(report.content)
|
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
if (res) {
|
if (res) {
|
||||||
this.debugReportLoading = false;
|
this.debugReportLoading = false;
|
||||||
this.request.debugReport = res;
|
this.request.debugReport = res;
|
||||||
|
this.request.debugScenario = res.scenarios[0];
|
||||||
|
this.request.debugRequestResult = this.request.debugScenario.requestResults[0];
|
||||||
this.deleteReport(this.debugReportId)
|
this.deleteReport(this.debugReportId)
|
||||||
} else {
|
} else {
|
||||||
setTimeout(this.getReport, 2000)
|
setTimeout(this.getReport, 2000)
|
||||||
|
|
|
@ -405,12 +405,40 @@ export class ResponseHeadersAssertion extends ResponseAssertion {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class BeanShellProcessor extends DefaultTestElement {
|
||||||
|
constructor(tag, guiclass, testclass, testname, processor) {
|
||||||
|
super(tag, guiclass, testclass, testname);
|
||||||
|
this.processor = processor || {};
|
||||||
|
this.boolProp('resetInterpreter', false);
|
||||||
|
this.stringProp('parameters');
|
||||||
|
this.stringProp('filename');
|
||||||
|
this.stringProp('script', processor.script);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class BeanShellPreProcessor extends BeanShellProcessor {
|
||||||
|
constructor(testName, processor) {
|
||||||
|
super('BeanShellPreProcessor', 'TestBeanGUI', 'BeanShellPreProcessor', testName, processor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class BeanShellPostProcessor extends BeanShellProcessor {
|
||||||
|
constructor(testName, script) {
|
||||||
|
let processor = {
|
||||||
|
script: script,
|
||||||
|
};
|
||||||
|
super('BeanShellPostProcessor', 'TestBeanGUI', 'BeanShellPostProcessor', testName, processor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class HeaderManager extends DefaultTestElement {
|
export class HeaderManager extends DefaultTestElement {
|
||||||
constructor(testName, headers) {
|
constructor(testName, headers) {
|
||||||
super('HeaderManager', 'HeaderPanel', 'HeaderManager', testName);
|
super('HeaderManager', 'HeaderPanel', 'HeaderManager', testName);
|
||||||
this.headers = headers || [];
|
this.headers = headers || [];
|
||||||
|
|
||||||
let collectionProp = this.collectionProp('HeaderManager.headers');
|
let collectionProp = this.collectionProp('HeaderManager.headers');
|
||||||
|
|
||||||
|
|
||||||
this.headers.forEach(header => {
|
this.headers.forEach(header => {
|
||||||
let elementProp = collectionProp.elementProp('', 'Header');
|
let elementProp = collectionProp.elementProp('', 'Header');
|
||||||
elementProp.stringProp('Header.name', header.name);
|
elementProp.stringProp('Header.name', header.name);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {
|
import {
|
||||||
Arguments,
|
Arguments, BeanShellPreProcessor,
|
||||||
CookieManager,
|
CookieManager,
|
||||||
DubboSample,
|
DubboSample,
|
||||||
DurationAssertion,
|
DurationAssertion,
|
||||||
|
@ -302,6 +302,8 @@ export class HttpRequest extends Request {
|
||||||
this.environment = undefined;
|
this.environment = undefined;
|
||||||
this.useEnvironment = undefined;
|
this.useEnvironment = undefined;
|
||||||
this.debugReport = undefined;
|
this.debugReport = undefined;
|
||||||
|
this.beanShellPreProcessor = undefined;
|
||||||
|
this.beanShellPostProcessor = undefined;
|
||||||
|
|
||||||
this.set(options);
|
this.set(options);
|
||||||
this.sets({parameters: KeyValue, headers: KeyValue}, options);
|
this.sets({parameters: KeyValue, headers: KeyValue}, options);
|
||||||
|
@ -313,6 +315,8 @@ export class HttpRequest extends Request {
|
||||||
options.body = new Body(options.body);
|
options.body = new Body(options.body);
|
||||||
options.assertions = new Assertions(options.assertions);
|
options.assertions = new Assertions(options.assertions);
|
||||||
options.extract = new Extract(options.extract);
|
options.extract = new Extract(options.extract);
|
||||||
|
options.beanShellPreProcessor = new BeanShellProcessor(options.beanShellPreProcessor);
|
||||||
|
options.beanShellPostProcessor = new BeanShellProcessor(options.beanShellPostProcessor);
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,6 +356,7 @@ export class HttpRequest extends Request {
|
||||||
showMethod() {
|
showMethod() {
|
||||||
return this.method.toUpperCase();
|
return this.method.toUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DubboRequest extends Request {
|
export class DubboRequest extends Request {
|
||||||
|
@ -564,6 +569,14 @@ export class AssertionType extends BaseConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class BeanShellProcessor extends BaseConfig {
|
||||||
|
constructor(options) {
|
||||||
|
super();
|
||||||
|
this.script = undefined;
|
||||||
|
this.set(options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class Text extends AssertionType {
|
export class Text extends AssertionType {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
super(ASSERTION_TYPE.TEXT);
|
super(ASSERTION_TYPE.TEXT);
|
||||||
|
@ -722,8 +735,6 @@ class JMXHttpRequest {
|
||||||
});
|
});
|
||||||
for (let i = 0; i < parameters.length; i++) {
|
for (let i = 0; i < parameters.length; i++) {
|
||||||
let parameter = parameters[i];
|
let parameter = parameters[i];
|
||||||
// 非 GET 请求中出现了 url 参数
|
|
||||||
parameter.value = calculate(parameter.value);
|
|
||||||
path += (parameter.name + '=' + parameter.value);
|
path += (parameter.name + '=' + parameter.value);
|
||||||
if (i !== parameters.length - 1) {
|
if (i !== parameters.length - 1) {
|
||||||
path += '&';
|
path += '&';
|
||||||
|
@ -820,6 +831,7 @@ class JMXGenerator {
|
||||||
} else {
|
} else {
|
||||||
this.addRequestBody(sampler, request);
|
this.addRequestBody(sampler, request);
|
||||||
}
|
}
|
||||||
|
this.addBeanShellProcessor(sampler, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.addRequestAssertion(sampler, request);
|
this.addRequestAssertion(sampler, request);
|
||||||
|
@ -888,6 +900,16 @@ class JMXGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addBeanShellProcessor(httpSamplerProxy, request) {
|
||||||
|
let name = request.name;
|
||||||
|
if (request.beanShellPreProcessor && request.beanShellPreProcessor.script) {
|
||||||
|
httpSamplerProxy.put(new BeanShellPreProcessor(name, request.beanShellPreProcessor));
|
||||||
|
}
|
||||||
|
if (request.beanShellPostProcessor && request.beanShellPostProcessor.script) {
|
||||||
|
httpSamplerProxy.put(new BeanShellPreProcessor(name, request.beanShellPostProcessor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
addBodyFormat(request) {
|
addBodyFormat(request) {
|
||||||
let bodyFormat = request.body.format;
|
let bodyFormat = request.body.format;
|
||||||
if (bodyFormat) {
|
if (bodyFormat) {
|
||||||
|
@ -921,9 +943,6 @@ class JMXGenerator {
|
||||||
|
|
||||||
addRequestArguments(httpSamplerProxy, request) {
|
addRequestArguments(httpSamplerProxy, request) {
|
||||||
let args = this.filterKV(request.parameters);
|
let args = this.filterKV(request.parameters);
|
||||||
args.forEach(arg => {
|
|
||||||
arg.value = calculate(arg.value);
|
|
||||||
});
|
|
||||||
if (args.length > 0) {
|
if (args.length > 0) {
|
||||||
httpSamplerProxy.add(new HTTPSamplerArguments(args));
|
httpSamplerProxy.add(new HTTPSamplerArguments(args));
|
||||||
}
|
}
|
||||||
|
@ -933,9 +952,6 @@ class JMXGenerator {
|
||||||
let body = [];
|
let body = [];
|
||||||
if (request.body.isKV()) {
|
if (request.body.isKV()) {
|
||||||
body = this.filterKV(request.body.kvs);
|
body = this.filterKV(request.body.kvs);
|
||||||
body.forEach(arg => {
|
|
||||||
arg.value = calculate(arg.value);
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
httpSamplerProxy.boolProp('HTTPSampler.postBodyRaw', true);
|
httpSamplerProxy.boolProp('HTTPSampler.postBodyRaw', true);
|
||||||
body.push({name: '', value: request.body.raw, encode: false});
|
body.push({name: '', value: request.body.raw, encode: false});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<editor v-model="formatData" :lang="mode" @init="editorInit" theme="chrome"/>
|
<editor v-model="formatData" :lang="mode" @init="editorInit" :theme="theme"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -15,6 +15,12 @@
|
||||||
data: {
|
data: {
|
||||||
type: String
|
type: String
|
||||||
},
|
},
|
||||||
|
theme: {
|
||||||
|
type: String,
|
||||||
|
default() {
|
||||||
|
return 'chrome'
|
||||||
|
}
|
||||||
|
},
|
||||||
init: {
|
init: {
|
||||||
type: Function
|
type: Function
|
||||||
},
|
},
|
||||||
|
@ -54,7 +60,7 @@
|
||||||
this.modes.forEach(mode => {
|
this.modes.forEach(mode => {
|
||||||
require('brace/mode/' + mode); //language
|
require('brace/mode/' + mode); //language
|
||||||
});
|
});
|
||||||
require('brace/theme/chrome')
|
require('brace/theme/' + this.theme)
|
||||||
require('brace/snippets/javascript') //snippet
|
require('brace/snippets/javascript') //snippet
|
||||||
if (this.readOnly) {
|
if (this.readOnly) {
|
||||||
editor.setReadOnly(true);
|
editor.setReadOnly(true);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
<script>
|
<script>
|
||||||
import {getCurrentUser} from "../../../../common/js/utils";
|
import {getCurrentUser} from "../../../../common/js/utils";
|
||||||
import AboutUs from "./AboutUs";
|
import AboutUs from "./AboutUs";
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MsUser",
|
name: "MsUser",
|
||||||
|
@ -35,7 +36,17 @@
|
||||||
this.$router.push('/setting/personsetting').catch(error => error);
|
this.$router.push('/setting/personsetting').catch(error => error);
|
||||||
break;
|
break;
|
||||||
case "logout":
|
case "logout":
|
||||||
this.$get("/signout", function () {
|
axios.get("/signout").then(response => {
|
||||||
|
if (response.data.success) {
|
||||||
|
localStorage.clear();
|
||||||
|
window.location.href = "/login";
|
||||||
|
} else {
|
||||||
|
if (response.data.message === 'sso') {
|
||||||
|
localStorage.clear();
|
||||||
|
window.location.href = "/sso/logout"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
window.location.href = "/login";
|
window.location.href = "/login";
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<el-card class="header-title">
|
<el-card class="header-title" v-loading="result.loading">
|
||||||
<div v-loading="result.loading">
|
<div>
|
||||||
<div>{{$t('organization.select_defect_platform')}}</div>
|
<div>{{$t('organization.select_defect_platform')}}</div>
|
||||||
<el-radio-group v-model="platform" style="margin-top: 10px" @change="change">
|
<el-radio-group v-model="platform" style="margin-top: 10px" @change="change">
|
||||||
<el-radio v-for="(item, index) in platforms" :key="index" :label="item.value" size="small">
|
<el-radio v-for="(item, index) in platforms" :key="index" :label="item.value" size="small">
|
||||||
|
@ -19,14 +19,19 @@
|
||||||
<el-input v-model="form.password" auto-complete="new-password"
|
<el-input v-model="form.password" auto-complete="new-password"
|
||||||
:placeholder="$t('organization.input_api_password')" show-password/>
|
:placeholder="$t('organization.input_api_password')" show-password/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="JIRA 地址" prop="url" v-if="platform === 'Jira'">
|
||||||
|
<el-input v-model="form.url" placeholder="请输入Jira地址"/>
|
||||||
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="margin-left: 100px">
|
<div style="margin-left: 100px">
|
||||||
<el-button v-if="showEdit" size="small" @click="edit">{{$t('commons.edit')}}</el-button>
|
<el-button type="primary" size="mini" :disabled="!show" @click="testConnection">{{$t('ldap.test_connect')}}
|
||||||
<el-button type="primary" v-if="showSave" size="small" @click="save('form')">{{$t('commons.save')}}</el-button>
|
</el-button>
|
||||||
<el-button v-if="showCancel" size="small" @click="cancelEdit">取消编辑</el-button>
|
<el-button v-if="showEdit" size="mini" @click="edit">{{$t('commons.edit')}}</el-button>
|
||||||
<el-button type="info" size="small" @click="cancelIntegration('form')" :disabled="!show">
|
<el-button type="primary" v-if="showSave" size="mini" @click="save('form')">{{$t('commons.save')}}</el-button>
|
||||||
|
<el-button v-if="showCancel" size="mini" @click="cancelEdit">取消编辑</el-button>
|
||||||
|
<el-button type="info" size="mini" @click="cancelIntegration('form')" :disabled="!show">
|
||||||
取消集成
|
取消集成
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -49,7 +54,7 @@
|
||||||
import {getCurrentUser} from "../../../../common/js/utils";
|
import {getCurrentUser} from "../../../../common/js/utils";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "DefectManagement",
|
name: "IssuesManagement",
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
form: {},
|
form: {},
|
||||||
|
@ -72,7 +77,8 @@
|
||||||
],
|
],
|
||||||
rules: {
|
rules: {
|
||||||
account: {required: true, message: this.$t('organization.input_api_account'), trigger: ['change', 'blur']},
|
account: {required: true, message: this.$t('organization.input_api_account'), trigger: ['change', 'blur']},
|
||||||
password: {required: true, message: this.$t('organization.input_api_password'), trigger: ['change', 'blur']}
|
password: {required: true, message: this.$t('organization.input_api_password'), trigger: ['change', 'blur']},
|
||||||
|
url: {required: true, message: '请输入url', trigger: ['change', 'blur']}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -91,6 +97,7 @@
|
||||||
let config = JSON.parse(data.configuration);
|
let config = JSON.parse(data.configuration);
|
||||||
this.$set(this.form, 'account', config.account);
|
this.$set(this.form, 'account', config.account);
|
||||||
this.$set(this.form, 'password', config.password);
|
this.$set(this.form, 'password', config.password);
|
||||||
|
this.$set(this.form, 'url', config.url);
|
||||||
} else {
|
} else {
|
||||||
this.clear();
|
this.clear();
|
||||||
}
|
}
|
||||||
|
@ -138,7 +145,8 @@
|
||||||
let param = {};
|
let param = {};
|
||||||
let auth = {
|
let auth = {
|
||||||
account: this.form.account,
|
account: this.form.account,
|
||||||
password: this.form.password
|
password: this.form.password,
|
||||||
|
url: this.form.url
|
||||||
};
|
};
|
||||||
param.organizationId = getCurrentUser().lastOrganizationId;
|
param.organizationId = getCurrentUser().lastOrganizationId;
|
||||||
param.platform = this.platform;
|
param.platform = this.platform;
|
||||||
|
@ -172,6 +180,7 @@
|
||||||
let config = JSON.parse(data.configuration);
|
let config = JSON.parse(data.configuration);
|
||||||
this.$set(this.form, 'account', config.account);
|
this.$set(this.form, 'account', config.account);
|
||||||
this.$set(this.form, 'password', config.password);
|
this.$set(this.form, 'password', config.password);
|
||||||
|
this.$set(this.form, 'url', config.url);
|
||||||
} else {
|
} else {
|
||||||
this.clear();
|
this.clear();
|
||||||
}
|
}
|
||||||
|
@ -180,9 +189,15 @@
|
||||||
clear() {
|
clear() {
|
||||||
this.$set(this.form, 'account', '');
|
this.$set(this.form, 'account', '');
|
||||||
this.$set(this.form, 'password', '');
|
this.$set(this.form, 'password', '');
|
||||||
|
this.$set(this.form, 'url', '');
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs.form.clearValidate();
|
this.$refs.form.clearValidate();
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
testConnection() {
|
||||||
|
this.result = this.$get("issues/auth/" + this.platform, () => {
|
||||||
|
this.$success("验证通过!");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
import DefectManagement from "./DefectManagement";
|
import DefectManagement from "./IssuesManagement";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ServiceIntegration",
|
name: "ServiceIntegration",
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
<div style="text-align: center">共 {{testCases.length}} 条</div>
|
||||||
</el-main>
|
</el-main>
|
||||||
</el-container>
|
</el-container>
|
||||||
</el-container>
|
</el-container>
|
||||||
|
@ -161,6 +162,8 @@
|
||||||
if (this.selectNodeIds && this.selectNodeIds.length > 0) {
|
if (this.selectNodeIds && this.selectNodeIds.length > 0) {
|
||||||
// param.nodeIds = this.selectNodeIds;
|
// param.nodeIds = this.selectNodeIds;
|
||||||
this.condition.nodeIds = this.selectNodeIds;
|
this.condition.nodeIds = this.selectNodeIds;
|
||||||
|
} else {
|
||||||
|
this.condition.nodeIds = [];
|
||||||
}
|
}
|
||||||
this.result = this.$post('/test/case/name', this.condition, response => {
|
this.result = this.$post('/test/case/name', this.condition, response => {
|
||||||
this.testCases = response.data;
|
this.testCases = response.data;
|
||||||
|
|
|
@ -207,10 +207,22 @@
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="20" :offset="1" class="issues-edit">
|
<el-col :span="20" :offset="1" class="issues-edit">
|
||||||
<el-table border class="adjust-table" :data="issues" style="width: 100%">
|
<el-table border class="adjust-table" :data="issues" style="width: 100%">
|
||||||
<el-table-column prop="id" label="缺陷ID"/>
|
<el-table-column prop="id" label="缺陷ID" show-overflow-tooltip/>
|
||||||
<el-table-column prop="title" label="缺陷标题"/>
|
<el-table-column prop="title" label="缺陷标题"/>
|
||||||
<el-table-column prop="status" label="缺陷状态"/>
|
|
||||||
<el-table-column prop="description" label="缺陷描述" show-overflow-tooltip/>
|
<el-table-column prop="description" label="缺陷描述" show-overflow-tooltip/>
|
||||||
|
<el-table-column prop="status" label="缺陷状态"/>
|
||||||
|
<el-table-column prop="platform" label="平台"/>
|
||||||
|
<el-table-column label="操作">
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<el-tooltip content="关闭缺陷"
|
||||||
|
placement="right">
|
||||||
|
<el-button type="danger" icon="el-icon-circle-close" size="mini"
|
||||||
|
circle v-if="scope.row.platform === 'Local'"
|
||||||
|
@click="closeIssue(scope.row)"
|
||||||
|
/>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
@ -477,8 +489,13 @@
|
||||||
this.result = this.$get("/issues/get/" + caseId, response => {
|
this.result = this.$get("/issues/get/" + caseId, response => {
|
||||||
let data = response.data;
|
let data = response.data;
|
||||||
this.issues = data;
|
this.issues = data;
|
||||||
console.log(data);
|
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
closeIssue(row) {
|
||||||
|
this.result = this.$get("/issues/close/" + row.id, () => {
|
||||||
|
this.getIssues(this.testCase.caseId);
|
||||||
|
this.$success("关闭成功");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,6 +102,28 @@
|
||||||
show-overflow-tooltip>
|
show-overflow-tooltip>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="nodePath"
|
||||||
|
label="缺陷"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<el-popover
|
||||||
|
placement="right"
|
||||||
|
width="400"
|
||||||
|
trigger="hover">
|
||||||
|
<el-table border class="adjust-table" :data="scope.row.issuesContent" style="width: 100%">
|
||||||
|
<!-- <el-table-column prop="id" label="缺陷ID" show-overflow-tooltip/>-->
|
||||||
|
<el-table-column prop="title" label="缺陷标题"/>
|
||||||
|
<el-table-column prop="description" label="缺陷描述" show-overflow-tooltip/>
|
||||||
|
<!-- <el-table-column prop="status" label="缺陷状态"/>-->
|
||||||
|
<el-table-column prop="platform" label="平台"/>
|
||||||
|
</el-table>
|
||||||
|
<el-button slot="reference" type="text">{{scope.row.issuesSize}}</el-button>
|
||||||
|
</el-popover>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="executorName"
|
prop="executorName"
|
||||||
:label="$t('test_track.plan_view.executor')">
|
:label="$t('test_track.plan_view.executor')">
|
||||||
|
@ -317,6 +339,14 @@
|
||||||
let data = response.data;
|
let data = response.data;
|
||||||
this.total = data.itemCount;
|
this.total = data.itemCount;
|
||||||
this.tableData = data.listObject;
|
this.tableData = data.listObject;
|
||||||
|
for (let i = 0; i < this.tableData.length; i++) {
|
||||||
|
this.$set(this.tableData[i], "issuesSize", 0);
|
||||||
|
this.$get("/issues/get/" + this.tableData[i].caseId, response => {
|
||||||
|
let issues = response.data;
|
||||||
|
this.$set(this.tableData[i], "issuesSize", issues.length);
|
||||||
|
this.$set(this.tableData[i], "issuesContent", issues);
|
||||||
|
})
|
||||||
|
}
|
||||||
// this.selectIds.clear();
|
// this.selectIds.clear();
|
||||||
this.selectRows.clear();
|
this.selectRows.clear();
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
<template>
|
||||||
|
<common-component :title="$t('test_track.plan_view.defect_list')">
|
||||||
|
<template>
|
||||||
|
<el-table
|
||||||
|
row-key="id"
|
||||||
|
:data="defectList"
|
||||||
|
>
|
||||||
|
<el-table-column
|
||||||
|
prop="id"
|
||||||
|
:label="$t('commons.id')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="module"
|
||||||
|
:label="$t('test_track.module.module')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="title"
|
||||||
|
:label="$t('test_track.module.title')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="description"
|
||||||
|
:label="$t('test_track.module.describe')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="status"
|
||||||
|
:label="$t('test_track.module.status')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="currentOwner"
|
||||||
|
:label="$t('test_track.module.current_owner')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="created"
|
||||||
|
:label="$t('test_track.module.creation_time')">
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</common-component>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import CommonComponent from "./CommonComponent";
|
||||||
|
import PriorityTableItem from "../../../../../common/tableItems/planview/PriorityTableItem";
|
||||||
|
import TypeTableItem from "../../../../../common/tableItems/planview/TypeTableItem";
|
||||||
|
import MethodTableItem from "../../../../../common/tableItems/planview/MethodTableItem";
|
||||||
|
import StatusTableItem from "../../../../../common/tableItems/planview/StatusTableItem";
|
||||||
|
export default {
|
||||||
|
name: "DefectListComponent",
|
||||||
|
components: {StatusTableItem, MethodTableItem, TypeTableItem, PriorityTableItem, CommonComponent},
|
||||||
|
props: {
|
||||||
|
defectList: {
|
||||||
|
type: Array,
|
||||||
|
default() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
id: "1023",
|
||||||
|
module: "模块e",
|
||||||
|
title: 'testCase1',
|
||||||
|
description: "第一个模块测试",
|
||||||
|
status: "接受/处理",
|
||||||
|
currentOwner: "Andy",
|
||||||
|
created: "2010.3.3",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -7,6 +7,7 @@
|
||||||
<test-result-component v-if="preview.id == 2"/>
|
<test-result-component v-if="preview.id == 2"/>
|
||||||
<test-result-chart-component v-if="preview.id == 3"/>
|
<test-result-chart-component v-if="preview.id == 3"/>
|
||||||
<failure-result-component v-if="preview.id == 4"/>
|
<failure-result-component v-if="preview.id == 4"/>
|
||||||
|
<defect-list-component v-if="preview.id == 5"/>
|
||||||
<rich-text-component :preview="preview" v-if="preview.type != 'system'"/>
|
<rich-text-component :preview="preview" v-if="preview.type != 'system'"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -16,6 +17,7 @@
|
||||||
<test-result-component :test-results="metric.moduleExecuteResult" v-if="preview.id == 2"/>
|
<test-result-component :test-results="metric.moduleExecuteResult" v-if="preview.id == 2"/>
|
||||||
<test-result-chart-component :execute-result="metric.executeResult" v-if="preview.id == 3"/>
|
<test-result-chart-component :execute-result="metric.executeResult" v-if="preview.id == 3"/>
|
||||||
<failure-result-component :failure-test-cases="metric.failureTestCases" v-if="preview.id == 4"/>
|
<failure-result-component :failure-test-cases="metric.failureTestCases" v-if="preview.id == 4"/>
|
||||||
|
<defect-list-component :defect-list="metric.defectList" v-if="preview.id == 5"/>
|
||||||
<rich-text-component :is-report-view="isReportView" :preview="preview" v-if="preview.type != 'system'"/>
|
<rich-text-component :is-report-view="isReportView" :preview="preview" v-if="preview.type != 'system'"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -28,10 +30,11 @@
|
||||||
import TestResultChartComponent from "./TestResultChartComponent";
|
import TestResultChartComponent from "./TestResultChartComponent";
|
||||||
import RichTextComponent from "./RichTextComponent";
|
import RichTextComponent from "./RichTextComponent";
|
||||||
import FailureResultComponent from "./FailureResultComponent";
|
import FailureResultComponent from "./FailureResultComponent";
|
||||||
|
import DefectListComponent from "./DefectListComponent";
|
||||||
export default {
|
export default {
|
||||||
name: "TemplateComponent",
|
name: "TemplateComponent",
|
||||||
components: {
|
components: {
|
||||||
FailureResultComponent,
|
FailureResultComponent,DefectListComponent,
|
||||||
RichTextComponent, TestResultChartComponent, TestResultComponent, BaseInfoComponent},
|
RichTextComponent, TestResultChartComponent, TestResultComponent, BaseInfoComponent},
|
||||||
props: {
|
props: {
|
||||||
preview: {
|
preview: {
|
||||||
|
|
|
@ -18,6 +18,36 @@
|
||||||
:label="$t('test_track.plan_view.case_count')"
|
:label="$t('test_track.plan_view.case_count')"
|
||||||
width="180">
|
width="180">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="passCount"
|
||||||
|
:label="$t('test_track.plan_view.pass')"
|
||||||
|
width="180">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="failureCount"
|
||||||
|
:label="$t('test_track.plan_view.failure')"
|
||||||
|
width="180">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="blockingCount"
|
||||||
|
:label="$t('test_track.plan_view.blocking')"
|
||||||
|
width="180">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="skipCount"
|
||||||
|
:label="$t('test_track.plan_view.skip')"
|
||||||
|
width="180">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="underwayCount"
|
||||||
|
:label="$t('test_track.plan.plan_status_running')"
|
||||||
|
width="180">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="prepareCount"
|
||||||
|
:label="$t('test_track.plan.plan_status_prepare')"
|
||||||
|
width="180">
|
||||||
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="passRate"
|
prop="passRate"
|
||||||
:label="$t('test_track.pass_rate')">
|
:label="$t('test_track.pass_rate')">
|
||||||
|
@ -50,19 +80,37 @@
|
||||||
moduleName: this.$t('test_track.module.module') + '1',
|
moduleName: this.$t('test_track.module.module') + '1',
|
||||||
caseCount: '14',
|
caseCount: '14',
|
||||||
passRate: 10.8,
|
passRate: 10.8,
|
||||||
issuesCount: 3
|
issuesCount: 3,
|
||||||
|
passCount:0,
|
||||||
|
failureCount:0,
|
||||||
|
blockingCount:0,
|
||||||
|
skipCount:0,
|
||||||
|
underwayCount:0,
|
||||||
|
prepareCount:0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
moduleName: this.$t('test_track.module.module') + '2',
|
moduleName: this.$t('test_track.module.module') + '1',
|
||||||
caseCount: '24',
|
caseCount: '14',
|
||||||
passRate: 40,
|
passRate: 10.8,
|
||||||
issuesCount: 6
|
issuesCount: 3,
|
||||||
|
passCount:0,
|
||||||
|
failureCount:0,
|
||||||
|
blockingCount:0,
|
||||||
|
skipCount:0,
|
||||||
|
underwayCount:0,
|
||||||
|
prepareCount:0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
moduleName: this.$t('test_track.module.module') + '3',
|
moduleName: this.$t('test_track.module.module') + '1',
|
||||||
caseCount: '50',
|
caseCount: '14',
|
||||||
passRate: 76.9,
|
passRate: 10.8,
|
||||||
issuesCount: 8
|
issuesCount: 3,
|
||||||
|
passCount:0,
|
||||||
|
failureCount:0,
|
||||||
|
blockingCount:0,
|
||||||
|
skipCount:0,
|
||||||
|
underwayCount:0,
|
||||||
|
prepareCount:0
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,10 +77,11 @@
|
||||||
[2, { name: this.$t('test_track.plan_view.test_result'), id: 2 , type: 'system'}],
|
[2, { name: this.$t('test_track.plan_view.test_result'), id: 2 , type: 'system'}],
|
||||||
[3, { name: this.$t('test_track.plan_view.result_distribution'), id: 3 ,type: 'system'}],
|
[3, { name: this.$t('test_track.plan_view.result_distribution'), id: 3 ,type: 'system'}],
|
||||||
[4, { name: this.$t('test_track.plan_view.failure_case'), id: 4 ,type: 'system'}],
|
[4, { name: this.$t('test_track.plan_view.failure_case'), id: 4 ,type: 'system'}],
|
||||||
[5, { name: this.$t('test_track.plan_view.custom_component'), id: 5 ,type: 'custom'}]
|
[5, { name: this.$t('test_track.plan_view.defect_list'), id: 5 ,type: 'system'}],
|
||||||
|
[6, { name: this.$t('test_track.plan_view.custom_component'), id:6,type: 'custom'}]
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
components: [5],
|
components: [6],
|
||||||
previews: [],
|
previews: [],
|
||||||
template: {},
|
template: {},
|
||||||
isReport: false
|
isReport: false
|
||||||
|
@ -109,12 +110,12 @@
|
||||||
this.template = {
|
this.template = {
|
||||||
name: '',
|
name: '',
|
||||||
content: {
|
content: {
|
||||||
components: [1,2,3,4,5],
|
components: [1,2,3,4,5,6],
|
||||||
customComponent: new Map()
|
customComponent: new Map()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.previews = [];
|
this.previews = [];
|
||||||
this.components = [5];
|
this.components = [6];
|
||||||
if (id) {
|
if (id) {
|
||||||
this.type = 'edit';
|
this.type = 'edit';
|
||||||
this.getTemplateById(id);
|
this.getTemplateById(id);
|
||||||
|
@ -144,6 +145,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
handleClose() {
|
handleClose() {
|
||||||
window.removeEventListener('popstate', this.goBack, false);
|
window.removeEventListener('popstate', this.goBack, false);
|
||||||
|
|
|
@ -69,7 +69,8 @@
|
||||||
[2, { name: this.$t('test_track.plan_view.test_result'), id: 2 , type: 'system'}],
|
[2, { name: this.$t('test_track.plan_view.test_result'), id: 2 , type: 'system'}],
|
||||||
[3, { name: this.$t('test_track.plan_view.result_distribution'), id: 3 ,type: 'system'}],
|
[3, { name: this.$t('test_track.plan_view.result_distribution'), id: 3 ,type: 'system'}],
|
||||||
[4, { name: this.$t('test_track.plan_view.failure_case'), id: 4 ,type: 'system'}],
|
[4, { name: this.$t('test_track.plan_view.failure_case'), id: 4 ,type: 'system'}],
|
||||||
[5, { name: this.$t('test_track.plan_view.custom_component'), id: 5 ,type: 'custom'}]
|
[5, { name: this.$t('test_track.plan_view.defect_list'), id: 5 ,type: 'system'}],
|
||||||
|
[6, { name: this.$t('test_track.plan_view.custom_component'), id: 6 ,type: 'custom'}]
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
isTestManagerOrTestUser: false
|
isTestManagerOrTestUser: false
|
||||||
|
@ -175,6 +176,9 @@
|
||||||
if (!this.metric.moduleExecuteResult) {
|
if (!this.metric.moduleExecuteResult) {
|
||||||
this.metric.moduleExecuteResult = [];
|
this.metric.moduleExecuteResult = [];
|
||||||
}
|
}
|
||||||
|
/*缺陷列表*/
|
||||||
|
this.metric.defectList = [];
|
||||||
|
|
||||||
if (this.report.startTime) {
|
if (this.report.startTime) {
|
||||||
this.metric.startTime = new Date(this.report.startTime);
|
this.metric.startTime = new Date(this.report.startTime);
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,39 +113,39 @@ export const MOCKJS_FUNC = [
|
||||||
]
|
]
|
||||||
|
|
||||||
export const JMETER_FUNC = [
|
export const JMETER_FUNC = [
|
||||||
{name: "${__threadNum}"},
|
{type: "Information", name: "${__threadNum}", description: "get thread number"},
|
||||||
{name: "${__samplerName}"},
|
{type: "Information", name: "${__samplerName}", description: "get the sampler name (label)"},
|
||||||
{name: "${__machineIP}"},
|
{type: "Information", name: "${__machineIP}", description: "get the local machine IP address"},
|
||||||
{name: "${__machineName}"},
|
{type: "Information", name: "${__machineName}", description: "get the local machine name"},
|
||||||
{name: "${__time}"},
|
{type: "Information", name: "${__time}", description: "return current time in various formats"},
|
||||||
{name: "${__log}"},
|
{type: "Information", name: "${__log}", description: "log (or display) a message (and return the value)"},
|
||||||
{name: "${__logn}"},
|
{type: "Information", name: "${__logn}", description: "log (or display) a message (empty return value)"},
|
||||||
{name: "${__StringFromFile}"},
|
{type: "Input", name: "${__StringFromFile}", description: "read a line from a file"},
|
||||||
{name: "${__FileToString}"},
|
{type: "Input", name: "${__FileToString}", description: "read an entire file"},
|
||||||
{name: "${__CSVRead}"},
|
{type: "Input", name: "${__CSVRead}", description: "read from CSV delimited file"},
|
||||||
{name: "${__XPath}"},
|
{type: "Input", name: "${__XPath}", description: "Use an XPath expression to read from a file"},
|
||||||
{name: "${__counter}"},
|
{type: "Calculation", name: "${__counter}", description: "generate an incrementing number"},
|
||||||
{name: "${__intSum}"},
|
{type: "Calculation", name: "${__intSum}", description: "add int numbers"},
|
||||||
{name: "${__longSum}"},
|
{type: "Calculation", name: "${__longSum}", description: "add long numbers"},
|
||||||
{name: "${__Random}"},
|
{type: "Calculation", name: "${__Random}", description: "generate a random number"},
|
||||||
{name: "${__RandomString}"},
|
{type: "Calculation", name: "${__RandomString}", description: "generate a random string"},
|
||||||
{name: "${__UUID}"},
|
{type: "Calculation", name: "${__UUID}", description: "generate a random type 4 UUID"},
|
||||||
{name: "${__BeanShell}"},
|
{type: "Scripting", name: "${__BeanShell}", description: "run a BeanShell script"},
|
||||||
{name: "${__javaScript}"},
|
{type: "Scripting", name: "${__javaScript}", description: "process JavaScript (Mozilla Rhino)"},
|
||||||
{name: "${__jexl}"},
|
{type: "Scripting", name: "${__jexl}", description: "evaluate a Commons Jexl expression"},
|
||||||
{name: "${__jexl2}"},
|
{type: "Scripting", name: "${__jexl2}", description: "evaluate a Commons Jexl expression"},
|
||||||
{name: "${__property}"},
|
{type: "Properties", name: "${__property}", description: "read a property"},
|
||||||
{name: "${__P}"},
|
{type: "Properties", name: "${__P}", description: "read a property (shorthand method)"},
|
||||||
{name: "${__setProperty}"},
|
{type: "Properties", name: "${__setProperty}", description: "set a JMeter property"},
|
||||||
{name: "${__split}"},
|
{type: "Variables", name: "${__split}", description: "Split a string into variables"},
|
||||||
{name: "${__V}"},
|
{type: "Variables", name: "${__V}", description: "evaluate a variable name"},
|
||||||
{name: "${__eval}"},
|
{type: "Variables", name: "${__eval}", description: "evaluate a variable expression"},
|
||||||
{name: "${__evalVar}"},
|
{type: "Variables", name: "${__evalVar}", description: "evaluate an expression stored in a variable"},
|
||||||
{name: "${__regexFunction}"},
|
{type: "String", name: "${__regexFunction}", description: "parse previous response using a regular expression"},
|
||||||
{name: "${__escapeOroRegexpChars}"},
|
{type: "String", name: "${__escapeOroRegexpChars}", description: "quote meta chars used by ORO regular expression"},
|
||||||
{name: "${__char}"},
|
{type: "String", name: "${__char}", description: "generate Unicode char values from a list of numbers"},
|
||||||
{name: "${__unescape}"},
|
{type: "String", name: "${__unescape}", description: "Process strings containing Java escapes (e.g. & )"},
|
||||||
{name: "${__unescapeHtml}"},
|
{type: "String", name: "${__unescapeHtml}", description: "Decode HTML-encoded strings"},
|
||||||
{name: "${__escapeHtml}"},
|
{type: "String", name: "${__escapeHtml}", description: "Encode strings using HTML encoding"},
|
||||||
{name: "${__TestPlanName}"},
|
{type: "String", name: "${__TestPlanName}", description: "Return name of current test plan"},
|
||||||
]
|
]
|
||||||
|
|
|
@ -353,6 +353,7 @@ export default {
|
||||||
input_name: "Please enter the test name",
|
input_name: "Please enter the test name",
|
||||||
select_project: "Please select project",
|
select_project: "Please select project",
|
||||||
variable_name: "Variable name",
|
variable_name: "Variable name",
|
||||||
|
variable: "Variable",
|
||||||
copied: "copied",
|
copied: "copied",
|
||||||
key: "Key",
|
key: "Key",
|
||||||
value: "Value",
|
value: "Value",
|
||||||
|
@ -401,6 +402,7 @@ export default {
|
||||||
url_description: "etc: https://fit2cloud.com",
|
url_description: "etc: https://fit2cloud.com",
|
||||||
path_description: "etc:/login",
|
path_description: "etc:/login",
|
||||||
parameters: "Query parameters",
|
parameters: "Query parameters",
|
||||||
|
jmeter_func: "Jmeter Functions",
|
||||||
parameters_filter_example: "Example",
|
parameters_filter_example: "Example",
|
||||||
parameters_filter_tips: "Only support MockJs function result preview",
|
parameters_filter_tips: "Only support MockJs function result preview",
|
||||||
parameters_advance: "Advanced parameter settings",
|
parameters_advance: "Advanced parameter settings",
|
||||||
|
@ -610,6 +612,11 @@ export default {
|
||||||
delete_confirm: "Confirm delete module:",
|
delete_confirm: "Confirm delete module:",
|
||||||
delete_all_resource: "and all submodules and test cases under the module",
|
delete_all_resource: "and all submodules and test cases under the module",
|
||||||
module: "Module",
|
module: "Module",
|
||||||
|
title: "Title",
|
||||||
|
describe: "Describe",
|
||||||
|
status: "Status",
|
||||||
|
current_owner: "Current Owner",
|
||||||
|
creation_time: "Creation time"
|
||||||
},
|
},
|
||||||
home: {
|
home: {
|
||||||
recent_test: "Recent test",
|
recent_test: "Recent test",
|
||||||
|
@ -649,6 +656,7 @@ export default {
|
||||||
result_distribution: "Result distribution",
|
result_distribution: "Result distribution",
|
||||||
custom_component: "Custom",
|
custom_component: "Custom",
|
||||||
create_report: "Create report",
|
create_report: "Create report",
|
||||||
|
defect_list:"Defect list",
|
||||||
view_report: "View report",
|
view_report: "View report",
|
||||||
component_library: "Component library",
|
component_library: "Component library",
|
||||||
component_library_tip: "Drag and drop the component from the component library, add to the right, preview the report effect, only one can be added per system component.",
|
component_library_tip: "Drag and drop the component from the component library, add to the right, preview the report effect, only one can be added per system component.",
|
||||||
|
|
|
@ -354,6 +354,7 @@ export default {
|
||||||
input_name: "请输入测试名称",
|
input_name: "请输入测试名称",
|
||||||
select_project: "请选择项目",
|
select_project: "请选择项目",
|
||||||
variable_name: "变量名",
|
variable_name: "变量名",
|
||||||
|
variable: "变量",
|
||||||
copied: "已拷贝",
|
copied: "已拷贝",
|
||||||
key: "键",
|
key: "键",
|
||||||
value: "值",
|
value: "值",
|
||||||
|
@ -402,8 +403,7 @@ export default {
|
||||||
path_description: "例如:/login",
|
path_description: "例如:/login",
|
||||||
url_invalid: "URL无效",
|
url_invalid: "URL无效",
|
||||||
parameters: "请求参数",
|
parameters: "请求参数",
|
||||||
parameters_filter: "内置函数",
|
jmeter_func: "Jmeter 方法",
|
||||||
parameters_filter_desc: "使用方法",
|
|
||||||
parameters_filter_example: "示例",
|
parameters_filter_example: "示例",
|
||||||
parameters_filter_tips: "只支持 MockJs 函数结果预览",
|
parameters_filter_tips: "只支持 MockJs 函数结果预览",
|
||||||
parameters_advance: "高级参数设置",
|
parameters_advance: "高级参数设置",
|
||||||
|
@ -615,6 +615,11 @@ export default {
|
||||||
delete_confirm: "确认删除模块: ",
|
delete_confirm: "确认删除模块: ",
|
||||||
delete_all_resource: "以及模块下所有子模块和测试用例",
|
delete_all_resource: "以及模块下所有子模块和测试用例",
|
||||||
module: "模块",
|
module: "模块",
|
||||||
|
title: "标题",
|
||||||
|
status: "状态",
|
||||||
|
describe: "描述",
|
||||||
|
current_owner: "处理人",
|
||||||
|
creation_time: "创建时间"
|
||||||
},
|
},
|
||||||
home: {
|
home: {
|
||||||
recent_test: "最近测试",
|
recent_test: "最近测试",
|
||||||
|
@ -653,6 +658,7 @@ export default {
|
||||||
test_result: "测试结果",
|
test_result: "测试结果",
|
||||||
result_distribution: "测试结果分布",
|
result_distribution: "测试结果分布",
|
||||||
custom_component: "自定义模块",
|
custom_component: "自定义模块",
|
||||||
|
defect_list:"缺陷列表",
|
||||||
create_report: "创建测试报告",
|
create_report: "创建测试报告",
|
||||||
view_report: "查看测试报告",
|
view_report: "查看测试报告",
|
||||||
component_library: "组件库",
|
component_library: "组件库",
|
||||||
|
|
|
@ -352,6 +352,7 @@ export default {
|
||||||
input_name: "請輸入測試名稱",
|
input_name: "請輸入測試名稱",
|
||||||
select_project: "請選擇項目",
|
select_project: "請選擇項目",
|
||||||
variable_name: "變數名",
|
variable_name: "變數名",
|
||||||
|
variable: "變數",
|
||||||
copied: "已拷貝",
|
copied: "已拷貝",
|
||||||
key: "鍵",
|
key: "鍵",
|
||||||
value: "值",
|
value: "值",
|
||||||
|
@ -401,6 +402,7 @@ export default {
|
||||||
path_description: "例如:/login",
|
path_description: "例如:/login",
|
||||||
url_invalid: "URL無效",
|
url_invalid: "URL無效",
|
||||||
parameters: "請求參數",
|
parameters: "請求參數",
|
||||||
|
jmeter_func: "Jmeter 方法",
|
||||||
parameters_filter_example: "示例",
|
parameters_filter_example: "示例",
|
||||||
parameters_filter_tips: "只支持MockJs函數結果預覽",
|
parameters_filter_tips: "只支持MockJs函數結果預覽",
|
||||||
parameters_advance: "高級參數設置",
|
parameters_advance: "高級參數設置",
|
||||||
|
@ -610,6 +612,11 @@ export default {
|
||||||
delete_confirm: "確認刪除模塊: ",
|
delete_confirm: "確認刪除模塊: ",
|
||||||
delete_all_resource: "以及模塊下所有子模塊和測試用例",
|
delete_all_resource: "以及模塊下所有子模塊和測試用例",
|
||||||
module: "模塊",
|
module: "模塊",
|
||||||
|
title: "標題",
|
||||||
|
status: "狀態",
|
||||||
|
describe: "描述",
|
||||||
|
current_owner: "處理人",
|
||||||
|
creation_time: "創建時間"
|
||||||
},
|
},
|
||||||
home: {
|
home: {
|
||||||
recent_test: "最近測試",
|
recent_test: "最近測試",
|
||||||
|
@ -649,6 +656,7 @@ export default {
|
||||||
result_distribution: "測試結果分布",
|
result_distribution: "測試結果分布",
|
||||||
custom_component: "自定義模塊",
|
custom_component: "自定義模塊",
|
||||||
create_report: "創建測試報告",
|
create_report: "創建測試報告",
|
||||||
|
defect_list:"缺陷清單",
|
||||||
view_report: "查看測試報告",
|
view_report: "查看測試報告",
|
||||||
component_library: "組件庫",
|
component_library: "組件庫",
|
||||||
component_library_tip: "拖拽組件庫中組件,添加至右側,預覽報告效果,每個系統組件只能添加壹個。",
|
component_library_tip: "拖拽組件庫中組件,添加至右側,預覽報告效果,每個系統組件只能添加壹個。",
|
||||||
|
|
|
@ -88,8 +88,15 @@
|
||||||
beforeCreate() {
|
beforeCreate() {
|
||||||
this.$get("/isLogin").then(response => {
|
this.$get("/isLogin").then(response => {
|
||||||
if (!response.data.success) {
|
if (!response.data.success) {
|
||||||
this.ready = true;
|
if (response.data.message === 'sso') {
|
||||||
|
window.location.href = "/sso/login"
|
||||||
} else {
|
} else {
|
||||||
|
this.ready = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let user = response.data.data;
|
||||||
|
saveLocalStorage(user);
|
||||||
|
this.getLanguage(user.language);
|
||||||
window.location.href = "/"
|
window.location.href = "/"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue