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/)
|
||||
- 测试引擎: [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@fit2cloud.com
|
||||
|
|
|
@ -31,4 +31,5 @@ target
|
|||
.settings
|
||||
.project
|
||||
.classpath
|
||||
.factorypath
|
||||
.factorypath
|
||||
*.jar
|
|
@ -140,11 +140,6 @@
|
|||
</dependency>
|
||||
|
||||
<!-- jmeter -->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.apache.jmeter</groupId>-->
|
||||
<!-- <artifactId>ApacheJMeter_core</artifactId>-->
|
||||
<!-- <version>${jmeter.version}</version>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.jmeter</groupId>
|
||||
|
@ -272,6 +267,24 @@
|
|||
<scope>runtime</scope>
|
||||
</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>
|
||||
|
||||
<build>
|
||||
|
@ -356,6 +369,16 @@
|
|||
<version>2.6</version>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/jmeter/lib/**/*.jar</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
|
@ -383,6 +406,35 @@
|
|||
</execution>
|
||||
</executions>
|
||||
</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>
|
||||
<groupId>org.mybatis.generator</groupId>
|
||||
<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.assertions.Assertions;
|
||||
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 java.util.List;
|
||||
|
@ -35,4 +37,8 @@ public class HttpRequest implements Request {
|
|||
private Assertions assertions;
|
||||
@JSONField(ordinal = 10)
|
||||
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 javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
|
@ -24,14 +25,15 @@ public class JMeterService {
|
|||
private JmeterProperties jmeterProperties;
|
||||
|
||||
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";
|
||||
JMeterUtils.loadJMeterProperties(JMETER_PROPERTIES);
|
||||
JMeterUtils.setJMeterHome(JMETER_HOME);
|
||||
try {
|
||||
Object scriptWrapper = SaveService.loadElement(is);
|
||||
HashTree testPlan = getHashTree(scriptWrapper);
|
||||
addBackendListener(testId, debugReportId, testPlan);
|
||||
addBackendListener(testId, debugReportId, testPlan);
|
||||
|
||||
LocalRunner runner = new LocalRunner(testPlan);
|
||||
runner.run();
|
||||
|
@ -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 {
|
||||
Field field = scriptWrapper.getClass().getDeclaredField("testPlan");
|
||||
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.parse.ApiImportParser;
|
||||
import io.metersphere.api.parse.ApiImportParserFactory;
|
||||
import io.metersphere.api.parse.JmeterDocumentParser;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.ApiTestFileMapper;
|
||||
import io.metersphere.base.mapper.ApiTestMapper;
|
||||
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.utils.BeanUtils;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
|
@ -145,6 +149,8 @@ public class APITestService {
|
|||
MSException.throwException(Translator.get("file_cannot_be_null"));
|
||||
}
|
||||
byte[] bytes = fileService.loadFileAsBytes(file.getFileId());
|
||||
// 解析 xml 处理 mock 数据
|
||||
bytes = JmeterDocumentParser.parse(bytes);
|
||||
InputStream is = new ByteArrayInputStream(bytes);
|
||||
|
||||
APITestResult apiTest = get(request.getId());
|
||||
|
@ -338,7 +344,10 @@ public class APITestService {
|
|||
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = new ByteArrayInputStream(file.getBytes());
|
||||
byte[] bytes = file.getBytes();
|
||||
// 解析 xml 处理 mock 数据
|
||||
bytes = JmeterDocumentParser.parse(bytes);
|
||||
is = new ByteArrayInputStream(bytes);
|
||||
} catch (IOException 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 platform;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
|
@ -313,76 +313,6 @@ public class TestCaseIssuesExample {
|
|||
addCriterion("issues_id not between", value1, value2, "issuesId");
|
||||
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 {
|
||||
|
|
|
@ -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" />
|
||||
<result column="test_case_id" jdbcType="VARCHAR" property="testCaseId" />
|
||||
<result column="issues_id" jdbcType="VARCHAR" property="issuesId" />
|
||||
<result column="platform" jdbcType="VARCHAR" property="platform" />
|
||||
</resultMap>
|
||||
<sql id="Example_Where_Clause">
|
||||
<where>
|
||||
|
@ -66,7 +65,7 @@
|
|||
</where>
|
||||
</sql>
|
||||
<sql id="Base_Column_List">
|
||||
id, test_case_id, issues_id, platform
|
||||
id, test_case_id, issues_id
|
||||
</sql>
|
||||
<select id="selectByExample" parameterType="io.metersphere.base.domain.TestCaseIssuesExample" resultMap="BaseResultMap">
|
||||
select
|
||||
|
@ -99,10 +98,10 @@
|
|||
</if>
|
||||
</delete>
|
||||
<insert id="insert" parameterType="io.metersphere.base.domain.TestCaseIssues">
|
||||
insert into test_case_issues (id, test_case_id, issues_id,
|
||||
platform)
|
||||
values (#{id,jdbcType=VARCHAR}, #{testCaseId,jdbcType=VARCHAR}, #{issuesId,jdbcType=VARCHAR},
|
||||
#{platform,jdbcType=VARCHAR})
|
||||
insert into test_case_issues (id, test_case_id, issues_id
|
||||
)
|
||||
values (#{id,jdbcType=VARCHAR}, #{testCaseId,jdbcType=VARCHAR}, #{issuesId,jdbcType=VARCHAR}
|
||||
)
|
||||
</insert>
|
||||
<insert id="insertSelective" parameterType="io.metersphere.base.domain.TestCaseIssues">
|
||||
insert into test_case_issues
|
||||
|
@ -116,9 +115,6 @@
|
|||
<if test="issuesId != null">
|
||||
issues_id,
|
||||
</if>
|
||||
<if test="platform != null">
|
||||
platform,
|
||||
</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="id != null">
|
||||
|
@ -130,9 +126,6 @@
|
|||
<if test="issuesId != null">
|
||||
#{issuesId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="platform != null">
|
||||
#{platform,jdbcType=VARCHAR},
|
||||
</if>
|
||||
</trim>
|
||||
</insert>
|
||||
<select id="countByExample" parameterType="io.metersphere.base.domain.TestCaseIssuesExample" resultType="java.lang.Long">
|
||||
|
@ -153,9 +146,6 @@
|
|||
<if test="record.issuesId != null">
|
||||
issues_id = #{record.issuesId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.platform != null">
|
||||
platform = #{record.platform,jdbcType=VARCHAR},
|
||||
</if>
|
||||
</set>
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
|
@ -165,8 +155,7 @@
|
|||
update test_case_issues
|
||||
set id = #{record.id,jdbcType=VARCHAR},
|
||||
test_case_id = #{record.testCaseId,jdbcType=VARCHAR},
|
||||
issues_id = #{record.issuesId,jdbcType=VARCHAR},
|
||||
platform = #{record.platform,jdbcType=VARCHAR}
|
||||
issues_id = #{record.issuesId,jdbcType=VARCHAR}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
|
@ -180,17 +169,13 @@
|
|||
<if test="issuesId != null">
|
||||
issues_id = #{issuesId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="platform != null">
|
||||
platform = #{platform,jdbcType=VARCHAR},
|
||||
</if>
|
||||
</set>
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
<update id="updateByPrimaryKey" parameterType="io.metersphere.base.domain.TestCaseIssues">
|
||||
update test_case_issues
|
||||
set test_case_id = #{testCaseId,jdbcType=VARCHAR},
|
||||
issues_id = #{issuesId,jdbcType=VARCHAR},
|
||||
platform = #{platform,jdbcType=VARCHAR}
|
||||
issues_id = #{issuesId,jdbcType=VARCHAR}
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
</mapper>
|
|
@ -132,7 +132,6 @@
|
|||
LEFT JOIN user ON user.id = r.user_id
|
||||
<where>
|
||||
r.id = #{id}
|
||||
AND r.status != 'Debug'
|
||||
</where>
|
||||
ORDER BY r.update_time DESC
|
||||
</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<String> getProjectIdByWorkspaceId(String workspaceId);
|
||||
|
||||
int removeIssuePlatform(@Param("platform") String platform, @Param("orgId") String orgId);
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
<select id="getProjectWithWorkspace" resultType="io.metersphere.dto.ProjectDTO">
|
||||
select p.id, p.workspace_id, p.name, p.description, p.update_time,
|
||||
p.create_time, w.id as workspaceId, w.name as workspaceName, p.tapd_id, p.jira_key
|
||||
from project p
|
||||
join workspace w on p.workspace_id = w.id
|
||||
p.create_time, w.id as workspaceId, w.name as workspaceName, p.tapd_id, p.jira_key
|
||||
from project p
|
||||
join workspace w on p.workspace_id = w.id
|
||||
<where>
|
||||
<if test="proRequest.name != null and proRequest.name != ''">
|
||||
and p.name like #{proRequest.name, jdbcType=VARCHAR}
|
||||
|
@ -28,4 +28,22 @@
|
|||
where workspace_id = #{workspaceId}
|
||||
</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>
|
|
@ -1,5 +1,5 @@
|
|||
package io.metersphere.commons.constants;
|
||||
|
||||
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;
|
||||
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
|
@ -22,7 +23,9 @@ public class RestTemplateUtils {
|
|||
ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
|
||||
return responseEntity.getBody();
|
||||
} 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);
|
||||
return responseEntity.getBody();
|
||||
} 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;
|
||||
|
||||
import io.metersphere.commons.utils.ShiroUtils;
|
||||
import io.metersphere.security.ApiKeyFilter;
|
||||
import io.metersphere.security.LoginFilter;
|
||||
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.web.ShiroFilterFactoryBean;
|
||||
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.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
|
@ -29,6 +29,7 @@ import java.util.Map;
|
|||
import java.util.Objects;
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty(prefix="sso",name = "mode", havingValue = "local", matchIfMissing = true)
|
||||
public class ShiroConfig implements EnvironmentAware {
|
||||
private Environment env;
|
||||
|
||||
|
@ -42,26 +43,8 @@ public class ShiroConfig implements EnvironmentAware {
|
|||
shiroFilterFactoryBean.setSuccessUrl("/");
|
||||
|
||||
shiroFilterFactoryBean.getFilters().put("apikey", new ApiKeyFilter());
|
||||
|
||||
Map<String, String> filterChainDefinitionMap = shiroFilterFactoryBean.getFilterChainDefinitionMap();
|
||||
filterChainDefinitionMap.put("/resource/**", "anon");
|
||||
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");
|
||||
ShiroUtils.loadBaseFilterChain(filterChainDefinitionMap);
|
||||
filterChainDefinitionMap.put("/**", "apikey, authc");
|
||||
return shiroFilterFactoryBean;
|
||||
}
|
||||
|
@ -120,18 +103,7 @@ public class ShiroConfig implements EnvironmentAware {
|
|||
@Bean
|
||||
public SessionManager sessionManager(MemoryConstrainedCacheManager memoryConstrainedCacheManager) {
|
||||
Long sessionTimeout = env.getProperty("session.timeout", Long.class, 1800L); // 默认1800s, 半个小时
|
||||
|
||||
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;
|
||||
return ShiroUtils.getSessionManager(sessionTimeout, memoryConstrainedCacheManager);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.metersphere.controller;
|
||||
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
@ -22,4 +23,15 @@ public class IndexController {
|
|||
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;
|
||||
|
||||
import io.metersphere.commons.constants.SsoMode;
|
||||
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.service.UserService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
@ -15,11 +20,21 @@ public class LoginController {
|
|||
|
||||
@Resource
|
||||
private UserService userService;
|
||||
@Resource
|
||||
private Environment env;
|
||||
|
||||
@GetMapping(value = "/isLogin")
|
||||
public ResultHolder isLogin() {
|
||||
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("");
|
||||
}
|
||||
|
@ -30,9 +45,19 @@ public class LoginController {
|
|||
return userService.login(request);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/currentUser")
|
||||
public ResultHolder currentUser() {
|
||||
return ResultHolder.success(SecurityUtils.getSubject().getSession().getAttribute("user"));
|
||||
}
|
||||
|
||||
@GetMapping(value = "/signout")
|
||||
public ResultHolder logout() {
|
||||
SecurityUtils.getSubject().logout();
|
||||
String ssoMode = env.getProperty("sso.mode");
|
||||
if (ssoMode != null && StringUtils.equalsIgnoreCase(SsoMode.CAS.name(), ssoMode)) {
|
||||
return ResultHolder.error("sso");
|
||||
} else {
|
||||
SecurityUtils.getSubject().logout();
|
||||
}
|
||||
return ResultHolder.success("");
|
||||
}
|
||||
|
||||
|
@ -42,5 +67,4 @@ public class LoginController {
|
|||
return userService.getDefaultLanguage();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.metersphere.dto;
|
||||
|
||||
import io.metersphere.base.domain.Role;
|
||||
import io.metersphere.base.domain.User;
|
||||
import io.metersphere.base.domain.UserRole;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
@ -10,28 +11,7 @@ import java.util.List;
|
|||
|
||||
@Getter
|
||||
@Setter
|
||||
public class UserDTO {
|
||||
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;
|
||||
public class UserDTO extends User {
|
||||
|
||||
private List<Role> roles = new ArrayList<>();
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
|
|||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.commons.utils.ScriptEngineUtils;
|
||||
import io.metersphere.config.KafkaProperties;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.performance.engine.EngineContext;
|
||||
|
@ -377,7 +378,9 @@ public class JmeterDocumentParser implements DocumentParser {
|
|||
elementProp.setAttribute("name", jsonObject.getString("name"));
|
||||
elementProp.setAttribute("elementType", "Argument");
|
||||
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", "="));
|
||||
item.appendChild(elementProp);
|
||||
}
|
||||
|
|
|
@ -49,15 +49,16 @@ public class ShiroDBRealm extends AuthorizingRealm {
|
|||
*/
|
||||
@Override
|
||||
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();
|
||||
|
||||
// roles 内容填充
|
||||
UserDTO userDTO = userService.getUserDTO(userName);
|
||||
UserDTO userDTO = userService.getUserDTO(userId);
|
||||
Set<String> roles = userDTO.getRoles().stream().map(Role::getId).collect(Collectors.toSet());
|
||||
authorizationInfo.setRoles(roles);
|
||||
|
||||
return authorizationInfo;
|
||||
}
|
||||
|
||||
|
@ -148,7 +149,6 @@ public class ShiroDBRealm extends AuthorizingRealm {
|
|||
if (!userService.checkUserPassword(userId, password)) {
|
||||
throw new IncorrectCredentialsException(Translator.get("password_is_incorrect"));
|
||||
}
|
||||
//
|
||||
SessionUser sessionUser = SessionUser.fromUser(user);
|
||||
SessionUtils.putUser(sessionUser);
|
||||
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.ServiceIntegrationExample;
|
||||
import io.metersphere.base.mapper.ServiceIntegrationMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtProjectMapper;
|
||||
import io.metersphere.controller.request.IntegrationRequest;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
@ -20,6 +21,8 @@ public class IntegrationService {
|
|||
|
||||
@Resource
|
||||
private ServiceIntegrationMapper serviceIntegrationMapper;
|
||||
@Resource
|
||||
private ExtProjectMapper extProjectMapper;
|
||||
|
||||
public ServiceIntegration save(ServiceIntegration service) {
|
||||
ServiceIntegrationExample example = new ServiceIntegrationExample();
|
||||
|
@ -63,6 +66,8 @@ public class IntegrationService {
|
|||
.andOrganizationIdEqualTo(orgId)
|
||||
.andPlatformEqualTo(platform);
|
||||
serviceIntegrationMapper.deleteByExample(example);
|
||||
// 删除项目关联的id/key
|
||||
extProjectMapper.removeIssuePlatform(platform, 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.TestResourceMapper;
|
||||
import io.metersphere.base.mapper.TestResourcePoolMapper;
|
||||
import io.metersphere.commons.constants.PerformanceTestStatus;
|
||||
import io.metersphere.commons.constants.ResourceStatusEnum;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
|
@ -25,7 +24,6 @@ import org.springframework.web.client.RestTemplate;
|
|||
import javax.annotation.Resource;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -70,11 +68,9 @@ public class TestResourcePoolService {
|
|||
}
|
||||
|
||||
public void checkTestStatus(String testResourcePoolId) {
|
||||
List list = Arrays.asList(PerformanceTestStatus.Running, PerformanceTestStatus.Starting, PerformanceTestStatus.Error);
|
||||
LoadTestExample example = new LoadTestExample();
|
||||
example.createCriteria()
|
||||
.andTestResourcePoolIdEqualTo(testResourcePoolId)
|
||||
.andStatusIn(list);
|
||||
.andTestResourcePoolIdEqualTo(testResourcePoolId);
|
||||
if (loadTestMapper.countByExample(example) > 0) {
|
||||
MSException.throwException(Translator.get("test_resource_pool_is_use"));
|
||||
}
|
||||
|
|
|
@ -163,6 +163,17 @@ public class UserService {
|
|||
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) {
|
||||
UserExample userExample = new UserExample();
|
||||
UserExample.Criteria criteria = userExample.createCriteria();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package io.metersphere.track.controller;
|
||||
|
||||
import io.metersphere.service.IssuesService;
|
||||
import io.metersphere.track.dto.IssuesDTO;
|
||||
import io.metersphere.base.domain.Issues;
|
||||
import io.metersphere.track.service.IssuesService;
|
||||
import io.metersphere.track.request.testcase.IssuesRequest;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
|
@ -21,7 +21,18 @@ public class TestCaseIssuesController {
|
|||
}
|
||||
|
||||
@GetMapping("/get/{id}")
|
||||
public List<IssuesDTO> getIssues(@PathVariable String id) {
|
||||
public List<Issues> getIssues(@PathVariable String 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.setPassCount(0);
|
||||
moduleResult.setIssuesCount(0);
|
||||
moduleResult.setFailureCount(0);
|
||||
moduleResult.setBlockingCount(0);
|
||||
moduleResult.setPrepareCount(0);
|
||||
moduleResult.setSkipCount(0);
|
||||
moduleResult.setUnderwayCount(0);
|
||||
moduleResult.setModuleId(rootNodeId);
|
||||
}
|
||||
moduleResult.setCaseCount(moduleResult.getCaseCount() + 1);
|
||||
if (StringUtils.equals(testCase.getStatus(), TestPlanTestCaseStatus.Pass.name())) {
|
||||
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 (JSON.parseObject(testCase.getIssues()).getBoolean("hasIssues")) {
|
||||
moduleResult.setIssuesCount(moduleResult.getIssuesCount() + 1);
|
||||
|
|
|
@ -12,4 +12,9 @@ public class TestCaseReportModuleResultDTO {
|
|||
private Integer passCount;
|
||||
private Double passRate;
|
||||
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
|
||||
primary key,
|
||||
test_case_id varchar(50) not null,
|
||||
issues_id varchar(100) not null,
|
||||
platform varchar(50) not null
|
||||
issues_id varchar(100) 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;
|
|
@ -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
|
||||
echo "one shot run."
|
||||
jmeter -n -t ${file} -Jserver.rmi.ssl.disable=${SSL_DISABLED}
|
||||
done
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
import MsUser from "./components/common/head/HeaderUser";
|
||||
import MsHeaderOrgWs from "./components/common/head/HeaderOrgWs";
|
||||
import MsLanguageSwitch from "./components/common/head/LanguageSwitch";
|
||||
import {saveLocalStorage} from "../common/js/utils";
|
||||
|
||||
export default {
|
||||
name: 'app',
|
||||
|
@ -36,7 +37,8 @@
|
|||
beforeCreate() {
|
||||
this.$get("/isLogin").then(response => {
|
||||
if (response.data.success) {
|
||||
this.$setLang(response.data.data);
|
||||
this.$setLang(response.data.data.language);
|
||||
saveLocalStorage(response.data);
|
||||
this.auth = true;
|
||||
} else {
|
||||
window.location.href = "/login"
|
||||
|
|
|
@ -2,17 +2,22 @@
|
|||
<div>
|
||||
<el-radio-group v-model="body.type" size="mini">
|
||||
<el-radio-button :disabled="isReadOnly" :label="type.KV">
|
||||
{{$t('api_test.request.body_kv')}}
|
||||
{{ $t('api_test.request.body_kv') }}
|
||||
</el-radio-button>
|
||||
<el-radio-button :disabled="isReadOnly" :label="type.RAW">
|
||||
{{$t('api_test.request.body_text')}}
|
||||
{{ $t('api_test.request.body_text') }}
|
||||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
|
||||
<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'">
|
||||
<ms-code-edit :mode="body.format" :read-only="isReadOnly" :data.sync="body.raw" :modes="modes" ref="codeEdit"/>
|
||||
</div>
|
||||
|
@ -22,7 +27,7 @@
|
|||
|
||||
<script>
|
||||
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 MsDropdown from "../../../common/components/MsDropdown";
|
||||
import MsApiVariable from "@/business/components/api/test/components/ApiVariable";
|
||||
|
@ -32,6 +37,9 @@ export default {
|
|||
components: {MsApiVariable, MsDropdown, MsCodeEdit, MsApiKeyValue},
|
||||
props: {
|
||||
body: Body,
|
||||
scenario: Scenario,
|
||||
environment: Object,
|
||||
extract: Object,
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
|
@ -40,45 +48,45 @@ export default {
|
|||
|
||||
data() {
|
||||
return {
|
||||
type: BODY_TYPE,
|
||||
modes: ['text', 'json', 'xml', 'html']
|
||||
};
|
||||
},
|
||||
type: BODY_TYPE,
|
||||
modes: ['text', 'json', 'xml', 'html']
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
modeChange(mode) {
|
||||
this.body.format = mode;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
modeChange(mode) {
|
||||
this.body.format = mode;
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
if (!this.body.type) {
|
||||
this.body.type = BODY_TYPE.KV;
|
||||
}
|
||||
if (!this.body.format) {
|
||||
this.body.format = BODY_FORMAT.TEXT;
|
||||
}
|
||||
created() {
|
||||
if (!this.body.type) {
|
||||
this.body.type = BODY_TYPE.KV;
|
||||
}
|
||||
if (!this.body.format) {
|
||||
this.body.format = BODY_FORMAT.TEXT;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.textarea {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.textarea {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.body-raw {
|
||||
padding: 15px 0;
|
||||
height: 300px;
|
||||
}
|
||||
.body-raw {
|
||||
padding: 15px 0;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.el-dropdown {
|
||||
margin-left: 20px;
|
||||
line-height: 30px;
|
||||
}
|
||||
.el-dropdown {
|
||||
margin-left: 20px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.ace_editor {
|
||||
border-radius: 5px;
|
||||
}
|
||||
.ace_editor {
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -34,13 +34,14 @@
|
|||
</el-col>
|
||||
</el-row>
|
||||
</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"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {HttpRequest, KeyValue, Scenario} from "../model/ScenarioModel";
|
||||
import {KeyValue, Scenario} from "../model/ScenarioModel";
|
||||
import {MOCKJS_FUNC} from "@/common/js/constants";
|
||||
import MsApiVariableAdvance from "@/business/components/api/test/components/ApiVariableAdvance";
|
||||
|
||||
|
@ -51,7 +52,7 @@ export default {
|
|||
keyPlaceholder: String,
|
||||
valuePlaceholder: String,
|
||||
description: String,
|
||||
request: HttpRequest,
|
||||
parameters: Array,
|
||||
environment: Object,
|
||||
scenario: Scenario,
|
||||
isReadOnly: {
|
||||
|
@ -63,7 +64,6 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
currentItem: null,
|
||||
parameters: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
</el-col>
|
||||
</el-row>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="变量">
|
||||
<el-tab-pane :label="$t('api_test.variable')">
|
||||
<el-row>
|
||||
<el-col :span="6" class="col-height">
|
||||
<div v-if="environment">
|
||||
|
@ -49,15 +49,14 @@
|
|||
<el-tree :data="preRequestParams" :props="treeProps" @node-click="selectVariable"></el-tree>
|
||||
</div>
|
||||
</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 v-for="(func, funcIndex) in jmeterFuncs"
|
||||
:key="`${itemIndex}-${funcIndex}`">
|
||||
<el-row>
|
||||
<el-radio size="mini" v-model="itemFunc.name" :label="func.name"
|
||||
@change="methodChange(itemFunc, func)"/>
|
||||
</el-row>
|
||||
</div>
|
||||
<h1>{{ $t('api_test.request.jmeter_func') }}</h1>
|
||||
<el-table border :data="jmeterFuncs" class="adjust-table table-content" height="400">
|
||||
<el-table-column prop="type" label="Type" width="150"/>
|
||||
<el-table-column prop="name" label="Functions" width="250"/>
|
||||
<el-table-column prop="description" label="Description"/>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@ -91,13 +90,13 @@
|
|||
</template>
|
||||
|
||||
<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";
|
||||
|
||||
export default {
|
||||
name: "MsApiVariableAdvance",
|
||||
props: {
|
||||
request: HttpRequest,
|
||||
parameters: Array,
|
||||
environment: Object,
|
||||
scenario: Scenario,
|
||||
currentItem: Object,
|
||||
|
@ -163,9 +162,6 @@ export default {
|
|||
this.itemValueVisible = true;
|
||||
},
|
||||
prepareData() {
|
||||
if (this.request) {
|
||||
this.parameters = this.request.parameters;
|
||||
}
|
||||
if (this.scenario) {
|
||||
let variables = this.scenario.variables;
|
||||
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-tab-pane :label="$t('api_test.request.parameters')" name="parameters">
|
||||
<ms-api-variable :is-read-only="isReadOnly"
|
||||
:request="request"
|
||||
:parameters="request.parameters"
|
||||
:environment="request.environment"
|
||||
:scenario="scenario"
|
||||
:extract="request.extract"
|
||||
|
@ -56,7 +56,11 @@
|
|||
<ms-api-key-value :is-read-only="isReadOnly" :suggestions="headerSuggestions" :items="request.headers"/>
|
||||
</el-tab-pane>
|
||||
<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 :label="$t('api_test.request.assertions.label')" name="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">
|
||||
<ms-api-extract :is-read-only="isReadOnly" :extract="request.extract"/>
|
||||
</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-form>
|
||||
</template>
|
||||
|
@ -77,10 +87,13 @@ import MsApiExtract from "../extract/ApiExtract";
|
|||
import ApiRequestMethodSelect from "../collapse/ApiRequestMethodSelect";
|
||||
import {REQUEST_HEADERS} from "@/common/js/constants";
|
||||
import MsApiVariable from "@/business/components/api/test/components/ApiVariable";
|
||||
import MsBeanShellProcessor from "../processor/BeanShellProcessor";
|
||||
|
||||
export default {
|
||||
name: "MsApiHttpRequestForm",
|
||||
components: {MsApiVariable, ApiRequestMethodSelect, MsApiExtract, MsApiAssertions, MsApiBody, MsApiKeyValue},
|
||||
components: {
|
||||
MsBeanShellProcessor,
|
||||
MsApiVariable, ApiRequestMethodSelect, MsApiExtract, MsApiAssertions, MsApiBody, MsApiKeyValue},
|
||||
props: {
|
||||
request: HttpRequest,
|
||||
scenario: Scenario,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="request-form">
|
||||
<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>
|
||||
</template>
|
||||
|
||||
|
@ -10,10 +10,11 @@ import {Request, RequestFactory, Scenario} from "../../model/ScenarioModel";
|
|||
import MsApiHttpRequestForm from "./ApiHttpRequestForm";
|
||||
import MsApiDubboRequestForm from "./ApiDubboRequestForm";
|
||||
import MsScenarioResults from "../../../report/components/ScenarioResults";
|
||||
import MsRequestResultTail from "../../../report/components/RequestResultTail";
|
||||
|
||||
export default {
|
||||
name: "MsApiRequestForm",
|
||||
components: {MsScenarioResults, MsApiDubboRequestForm, MsApiHttpRequestForm},
|
||||
components: {MsRequestResultTail, MsScenarioResults, MsApiDubboRequestForm, MsApiHttpRequestForm},
|
||||
props: {
|
||||
scenario: Scenario,
|
||||
request: Request,
|
||||
|
@ -66,12 +67,13 @@ export default {
|
|||
try {
|
||||
res = JSON.parse(report.content);
|
||||
} catch (e) {
|
||||
console.log(report.content)
|
||||
throw e;
|
||||
}
|
||||
if (res) {
|
||||
this.debugReportLoading = false;
|
||||
this.request.debugReport = res;
|
||||
this.request.debugScenario = res.scenarios[0];
|
||||
this.request.debugRequestResult = this.request.debugScenario.requestResults[0];
|
||||
this.deleteReport(this.debugReportId)
|
||||
} else {
|
||||
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 {
|
||||
constructor(testName, headers) {
|
||||
super('HeaderManager', 'HeaderPanel', 'HeaderManager', testName);
|
||||
this.headers = headers || [];
|
||||
|
||||
let collectionProp = this.collectionProp('HeaderManager.headers');
|
||||
|
||||
|
||||
this.headers.forEach(header => {
|
||||
let elementProp = collectionProp.elementProp('', 'Header');
|
||||
elementProp.stringProp('Header.name', header.name);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {
|
||||
Arguments,
|
||||
Arguments, BeanShellPreProcessor,
|
||||
CookieManager,
|
||||
DubboSample,
|
||||
DurationAssertion,
|
||||
|
@ -302,6 +302,8 @@ export class HttpRequest extends Request {
|
|||
this.environment = undefined;
|
||||
this.useEnvironment = undefined;
|
||||
this.debugReport = undefined;
|
||||
this.beanShellPreProcessor = undefined;
|
||||
this.beanShellPostProcessor = undefined;
|
||||
|
||||
this.set(options);
|
||||
this.sets({parameters: KeyValue, headers: KeyValue}, options);
|
||||
|
@ -313,6 +315,8 @@ export class HttpRequest extends Request {
|
|||
options.body = new Body(options.body);
|
||||
options.assertions = new Assertions(options.assertions);
|
||||
options.extract = new Extract(options.extract);
|
||||
options.beanShellPreProcessor = new BeanShellProcessor(options.beanShellPreProcessor);
|
||||
options.beanShellPostProcessor = new BeanShellProcessor(options.beanShellPostProcessor);
|
||||
return options;
|
||||
}
|
||||
|
||||
|
@ -352,6 +356,7 @@ export class HttpRequest extends Request {
|
|||
showMethod() {
|
||||
return this.method.toUpperCase();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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 {
|
||||
constructor(options) {
|
||||
super(ASSERTION_TYPE.TEXT);
|
||||
|
@ -722,8 +735,6 @@ class JMXHttpRequest {
|
|||
});
|
||||
for (let i = 0; i < parameters.length; i++) {
|
||||
let parameter = parameters[i];
|
||||
// 非 GET 请求中出现了 url 参数
|
||||
parameter.value = calculate(parameter.value);
|
||||
path += (parameter.name + '=' + parameter.value);
|
||||
if (i !== parameters.length - 1) {
|
||||
path += '&';
|
||||
|
@ -820,6 +831,7 @@ class JMXGenerator {
|
|||
} else {
|
||||
this.addRequestBody(sampler, request);
|
||||
}
|
||||
this.addBeanShellProcessor(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) {
|
||||
let bodyFormat = request.body.format;
|
||||
if (bodyFormat) {
|
||||
|
@ -921,9 +943,6 @@ class JMXGenerator {
|
|||
|
||||
addRequestArguments(httpSamplerProxy, request) {
|
||||
let args = this.filterKV(request.parameters);
|
||||
args.forEach(arg => {
|
||||
arg.value = calculate(arg.value);
|
||||
});
|
||||
if (args.length > 0) {
|
||||
httpSamplerProxy.add(new HTTPSamplerArguments(args));
|
||||
}
|
||||
|
@ -933,9 +952,6 @@ class JMXGenerator {
|
|||
let body = [];
|
||||
if (request.body.isKV()) {
|
||||
body = this.filterKV(request.body.kvs);
|
||||
body.forEach(arg => {
|
||||
arg.value = calculate(arg.value);
|
||||
});
|
||||
} else {
|
||||
httpSamplerProxy.boolProp('HTTPSampler.postBodyRaw', true);
|
||||
body.push({name: '', value: request.body.raw, encode: false});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<editor v-model="formatData" :lang="mode" @init="editorInit" theme="chrome"/>
|
||||
<editor v-model="formatData" :lang="mode" @init="editorInit" :theme="theme"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -15,6 +15,12 @@
|
|||
data: {
|
||||
type: String
|
||||
},
|
||||
theme: {
|
||||
type: String,
|
||||
default() {
|
||||
return 'chrome'
|
||||
}
|
||||
},
|
||||
init: {
|
||||
type: Function
|
||||
},
|
||||
|
@ -54,7 +60,7 @@
|
|||
this.modes.forEach(mode => {
|
||||
require('brace/mode/' + mode); //language
|
||||
});
|
||||
require('brace/theme/chrome')
|
||||
require('brace/theme/' + this.theme)
|
||||
require('brace/snippets/javascript') //snippet
|
||||
if (this.readOnly) {
|
||||
editor.setReadOnly(true);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
<script>
|
||||
import {getCurrentUser} from "../../../../common/js/utils";
|
||||
import AboutUs from "./AboutUs";
|
||||
import axios from "axios";
|
||||
|
||||
export default {
|
||||
name: "MsUser",
|
||||
|
@ -35,7 +36,17 @@
|
|||
this.$router.push('/setting/personsetting').catch(error => error);
|
||||
break;
|
||||
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();
|
||||
window.location.href = "/login";
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<el-card class="header-title">
|
||||
<div v-loading="result.loading">
|
||||
<el-card class="header-title" v-loading="result.loading">
|
||||
<div>
|
||||
<div>{{$t('organization.select_defect_platform')}}</div>
|
||||
<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">
|
||||
|
@ -19,14 +19,19 @@
|
|||
<el-input v-model="form.password" auto-complete="new-password"
|
||||
:placeholder="$t('organization.input_api_password')" show-password/>
|
||||
</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>
|
||||
</div>
|
||||
|
||||
<div style="margin-left: 100px">
|
||||
<el-button v-if="showEdit" size="small" @click="edit">{{$t('commons.edit')}}</el-button>
|
||||
<el-button type="primary" v-if="showSave" size="small" @click="save('form')">{{$t('commons.save')}}</el-button>
|
||||
<el-button v-if="showCancel" size="small" @click="cancelEdit">取消编辑</el-button>
|
||||
<el-button type="info" size="small" @click="cancelIntegration('form')" :disabled="!show">
|
||||
<el-button type="primary" size="mini" :disabled="!show" @click="testConnection">{{$t('ldap.test_connect')}}
|
||||
</el-button>
|
||||
<el-button v-if="showEdit" size="mini" @click="edit">{{$t('commons.edit')}}</el-button>
|
||||
<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>
|
||||
</div>
|
||||
|
@ -49,7 +54,7 @@
|
|||
import {getCurrentUser} from "../../../../common/js/utils";
|
||||
|
||||
export default {
|
||||
name: "DefectManagement",
|
||||
name: "IssuesManagement",
|
||||
data() {
|
||||
return {
|
||||
form: {},
|
||||
|
@ -72,7 +77,8 @@
|
|||
],
|
||||
rules: {
|
||||
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);
|
||||
this.$set(this.form, 'account', config.account);
|
||||
this.$set(this.form, 'password', config.password);
|
||||
this.$set(this.form, 'url', config.url);
|
||||
} else {
|
||||
this.clear();
|
||||
}
|
||||
|
@ -138,7 +145,8 @@
|
|||
let param = {};
|
||||
let auth = {
|
||||
account: this.form.account,
|
||||
password: this.form.password
|
||||
password: this.form.password,
|
||||
url: this.form.url
|
||||
};
|
||||
param.organizationId = getCurrentUser().lastOrganizationId;
|
||||
param.platform = this.platform;
|
||||
|
@ -172,6 +180,7 @@
|
|||
let config = JSON.parse(data.configuration);
|
||||
this.$set(this.form, 'account', config.account);
|
||||
this.$set(this.form, 'password', config.password);
|
||||
this.$set(this.form, 'url', config.url);
|
||||
} else {
|
||||
this.clear();
|
||||
}
|
||||
|
@ -180,9 +189,15 @@
|
|||
clear() {
|
||||
this.$set(this.form, 'account', '');
|
||||
this.$set(this.form, 'password', '');
|
||||
this.$set(this.form, 'url', '');
|
||||
this.$nextTick(() => {
|
||||
this.$refs.form.clearValidate();
|
||||
});
|
||||
},
|
||||
testConnection() {
|
||||
this.result = this.$get("issues/auth/" + this.platform, () => {
|
||||
this.$success("验证通过!");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
<script>
|
||||
|
||||
import DefectManagement from "./DefectManagement";
|
||||
import DefectManagement from "./IssuesManagement";
|
||||
|
||||
export default {
|
||||
name: "ServiceIntegration",
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div style="text-align: center">共 {{testCases.length}} 条</div>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-container>
|
||||
|
@ -161,6 +162,8 @@
|
|||
if (this.selectNodeIds && this.selectNodeIds.length > 0) {
|
||||
// param.nodeIds = this.selectNodeIds;
|
||||
this.condition.nodeIds = this.selectNodeIds;
|
||||
} else {
|
||||
this.condition.nodeIds = [];
|
||||
}
|
||||
this.result = this.$post('/test/case/name', this.condition, response => {
|
||||
this.testCases = response.data;
|
||||
|
|
|
@ -207,10 +207,22 @@
|
|||
<el-row>
|
||||
<el-col :span="20" :offset="1" class="issues-edit">
|
||||
<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="status" label="缺陷状态"/>
|
||||
<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-col>
|
||||
</el-row>
|
||||
|
@ -474,11 +486,16 @@
|
|||
})
|
||||
},
|
||||
getIssues(caseId) {
|
||||
this.result = this.$get("/issues/get/"+caseId,response => {
|
||||
this.result = this.$get("/issues/get/" + caseId, response => {
|
||||
let data = response.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>
|
||||
</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
|
||||
prop="executorName"
|
||||
:label="$t('test_track.plan_view.executor')">
|
||||
|
@ -317,6 +339,14 @@
|
|||
let data = response.data;
|
||||
this.total = data.itemCount;
|
||||
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.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-chart-component v-if="preview.id == 3"/>
|
||||
<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'"/>
|
||||
</div>
|
||||
|
||||
|
@ -16,6 +17,7 @@
|
|||
<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"/>
|
||||
<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'"/>
|
||||
</div>
|
||||
|
||||
|
@ -28,10 +30,11 @@
|
|||
import TestResultChartComponent from "./TestResultChartComponent";
|
||||
import RichTextComponent from "./RichTextComponent";
|
||||
import FailureResultComponent from "./FailureResultComponent";
|
||||
import DefectListComponent from "./DefectListComponent";
|
||||
export default {
|
||||
name: "TemplateComponent",
|
||||
components: {
|
||||
FailureResultComponent,
|
||||
FailureResultComponent,DefectListComponent,
|
||||
RichTextComponent, TestResultChartComponent, TestResultComponent, BaseInfoComponent},
|
||||
props: {
|
||||
preview: {
|
||||
|
|
|
@ -18,6 +18,36 @@
|
|||
:label="$t('test_track.plan_view.case_count')"
|
||||
width="180">
|
||||
</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
|
||||
prop="passRate"
|
||||
:label="$t('test_track.pass_rate')">
|
||||
|
@ -50,19 +80,37 @@
|
|||
moduleName: this.$t('test_track.module.module') + '1',
|
||||
caseCount: '14',
|
||||
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',
|
||||
caseCount: '24',
|
||||
passRate: 40,
|
||||
issuesCount: 6
|
||||
moduleName: this.$t('test_track.module.module') + '1',
|
||||
caseCount: '14',
|
||||
passRate: 10.8,
|
||||
issuesCount: 3,
|
||||
passCount:0,
|
||||
failureCount:0,
|
||||
blockingCount:0,
|
||||
skipCount:0,
|
||||
underwayCount:0,
|
||||
prepareCount:0
|
||||
},
|
||||
{
|
||||
moduleName: this.$t('test_track.module.module') + '3',
|
||||
caseCount: '50',
|
||||
passRate: 76.9,
|
||||
issuesCount: 8
|
||||
moduleName: this.$t('test_track.module.module') + '1',
|
||||
caseCount: '14',
|
||||
passRate: 10.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'}],
|
||||
[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'}],
|
||||
[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: [],
|
||||
template: {},
|
||||
isReport: false
|
||||
|
@ -109,12 +110,12 @@
|
|||
this.template = {
|
||||
name: '',
|
||||
content: {
|
||||
components: [1,2,3,4,5],
|
||||
components: [1,2,3,4,5,6],
|
||||
customComponent: new Map()
|
||||
}
|
||||
};
|
||||
this.previews = [];
|
||||
this.components = [5];
|
||||
this.components = [6];
|
||||
if (id) {
|
||||
this.type = 'edit';
|
||||
this.getTemplateById(id);
|
||||
|
@ -144,6 +145,7 @@
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
handleClose() {
|
||||
window.removeEventListener('popstate', this.goBack, false);
|
||||
|
|
|
@ -69,7 +69,8 @@
|
|||
[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'}],
|
||||
[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
|
||||
|
@ -175,6 +176,9 @@
|
|||
if (!this.metric.moduleExecuteResult) {
|
||||
this.metric.moduleExecuteResult = [];
|
||||
}
|
||||
/*缺陷列表*/
|
||||
this.metric.defectList = [];
|
||||
|
||||
if (this.report.startTime) {
|
||||
this.metric.startTime = new Date(this.report.startTime);
|
||||
}
|
||||
|
|
|
@ -113,39 +113,39 @@ export const MOCKJS_FUNC = [
|
|||
]
|
||||
|
||||
export const JMETER_FUNC = [
|
||||
{name: "${__threadNum}"},
|
||||
{name: "${__samplerName}"},
|
||||
{name: "${__machineIP}"},
|
||||
{name: "${__machineName}"},
|
||||
{name: "${__time}"},
|
||||
{name: "${__log}"},
|
||||
{name: "${__logn}"},
|
||||
{name: "${__StringFromFile}"},
|
||||
{name: "${__FileToString}"},
|
||||
{name: "${__CSVRead}"},
|
||||
{name: "${__XPath}"},
|
||||
{name: "${__counter}"},
|
||||
{name: "${__intSum}"},
|
||||
{name: "${__longSum}"},
|
||||
{name: "${__Random}"},
|
||||
{name: "${__RandomString}"},
|
||||
{name: "${__UUID}"},
|
||||
{name: "${__BeanShell}"},
|
||||
{name: "${__javaScript}"},
|
||||
{name: "${__jexl}"},
|
||||
{name: "${__jexl2}"},
|
||||
{name: "${__property}"},
|
||||
{name: "${__P}"},
|
||||
{name: "${__setProperty}"},
|
||||
{name: "${__split}"},
|
||||
{name: "${__V}"},
|
||||
{name: "${__eval}"},
|
||||
{name: "${__evalVar}"},
|
||||
{name: "${__regexFunction}"},
|
||||
{name: "${__escapeOroRegexpChars}"},
|
||||
{name: "${__char}"},
|
||||
{name: "${__unescape}"},
|
||||
{name: "${__unescapeHtml}"},
|
||||
{name: "${__escapeHtml}"},
|
||||
{name: "${__TestPlanName}"},
|
||||
{type: "Information", name: "${__threadNum}", description: "get thread number"},
|
||||
{type: "Information", name: "${__samplerName}", description: "get the sampler name (label)"},
|
||||
{type: "Information", name: "${__machineIP}", description: "get the local machine IP address"},
|
||||
{type: "Information", name: "${__machineName}", description: "get the local machine name"},
|
||||
{type: "Information", name: "${__time}", description: "return current time in various formats"},
|
||||
{type: "Information", name: "${__log}", description: "log (or display) a message (and return the value)"},
|
||||
{type: "Information", name: "${__logn}", description: "log (or display) a message (empty return value)"},
|
||||
{type: "Input", name: "${__StringFromFile}", description: "read a line from a file"},
|
||||
{type: "Input", name: "${__FileToString}", description: "read an entire file"},
|
||||
{type: "Input", name: "${__CSVRead}", description: "read from CSV delimited file"},
|
||||
{type: "Input", name: "${__XPath}", description: "Use an XPath expression to read from a file"},
|
||||
{type: "Calculation", name: "${__counter}", description: "generate an incrementing number"},
|
||||
{type: "Calculation", name: "${__intSum}", description: "add int numbers"},
|
||||
{type: "Calculation", name: "${__longSum}", description: "add long numbers"},
|
||||
{type: "Calculation", name: "${__Random}", description: "generate a random number"},
|
||||
{type: "Calculation", name: "${__RandomString}", description: "generate a random string"},
|
||||
{type: "Calculation", name: "${__UUID}", description: "generate a random type 4 UUID"},
|
||||
{type: "Scripting", name: "${__BeanShell}", description: "run a BeanShell script"},
|
||||
{type: "Scripting", name: "${__javaScript}", description: "process JavaScript (Mozilla Rhino)"},
|
||||
{type: "Scripting", name: "${__jexl}", description: "evaluate a Commons Jexl expression"},
|
||||
{type: "Scripting", name: "${__jexl2}", description: "evaluate a Commons Jexl expression"},
|
||||
{type: "Properties", name: "${__property}", description: "read a property"},
|
||||
{type: "Properties", name: "${__P}", description: "read a property (shorthand method)"},
|
||||
{type: "Properties", name: "${__setProperty}", description: "set a JMeter property"},
|
||||
{type: "Variables", name: "${__split}", description: "Split a string into variables"},
|
||||
{type: "Variables", name: "${__V}", description: "evaluate a variable name"},
|
||||
{type: "Variables", name: "${__eval}", description: "evaluate a variable expression"},
|
||||
{type: "Variables", name: "${__evalVar}", description: "evaluate an expression stored in a variable"},
|
||||
{type: "String", name: "${__regexFunction}", description: "parse previous response using a regular expression"},
|
||||
{type: "String", name: "${__escapeOroRegexpChars}", description: "quote meta chars used by ORO regular expression"},
|
||||
{type: "String", name: "${__char}", description: "generate Unicode char values from a list of numbers"},
|
||||
{type: "String", name: "${__unescape}", description: "Process strings containing Java escapes (e.g. & )"},
|
||||
{type: "String", name: "${__unescapeHtml}", description: "Decode HTML-encoded strings"},
|
||||
{type: "String", name: "${__escapeHtml}", description: "Encode strings using HTML encoding"},
|
||||
{type: "String", name: "${__TestPlanName}", description: "Return name of current test plan"},
|
||||
]
|
||||
|
|
|
@ -353,6 +353,7 @@ export default {
|
|||
input_name: "Please enter the test name",
|
||||
select_project: "Please select project",
|
||||
variable_name: "Variable name",
|
||||
variable: "Variable",
|
||||
copied: "copied",
|
||||
key: "Key",
|
||||
value: "Value",
|
||||
|
@ -401,6 +402,7 @@ export default {
|
|||
url_description: "etc: https://fit2cloud.com",
|
||||
path_description: "etc:/login",
|
||||
parameters: "Query parameters",
|
||||
jmeter_func: "Jmeter Functions",
|
||||
parameters_filter_example: "Example",
|
||||
parameters_filter_tips: "Only support MockJs function result preview",
|
||||
parameters_advance: "Advanced parameter settings",
|
||||
|
@ -610,6 +612,11 @@ export default {
|
|||
delete_confirm: "Confirm delete module:",
|
||||
delete_all_resource: "and all submodules and test cases under the module",
|
||||
module: "Module",
|
||||
title: "Title",
|
||||
describe: "Describe",
|
||||
status: "Status",
|
||||
current_owner: "Current Owner",
|
||||
creation_time: "Creation time"
|
||||
},
|
||||
home: {
|
||||
recent_test: "Recent test",
|
||||
|
@ -649,6 +656,7 @@ export default {
|
|||
result_distribution: "Result distribution",
|
||||
custom_component: "Custom",
|
||||
create_report: "Create report",
|
||||
defect_list:"Defect list",
|
||||
view_report: "View report",
|
||||
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.",
|
||||
|
|
|
@ -354,6 +354,7 @@ export default {
|
|||
input_name: "请输入测试名称",
|
||||
select_project: "请选择项目",
|
||||
variable_name: "变量名",
|
||||
variable: "变量",
|
||||
copied: "已拷贝",
|
||||
key: "键",
|
||||
value: "值",
|
||||
|
@ -402,8 +403,7 @@ export default {
|
|||
path_description: "例如:/login",
|
||||
url_invalid: "URL无效",
|
||||
parameters: "请求参数",
|
||||
parameters_filter: "内置函数",
|
||||
parameters_filter_desc: "使用方法",
|
||||
jmeter_func: "Jmeter 方法",
|
||||
parameters_filter_example: "示例",
|
||||
parameters_filter_tips: "只支持 MockJs 函数结果预览",
|
||||
parameters_advance: "高级参数设置",
|
||||
|
@ -615,6 +615,11 @@ export default {
|
|||
delete_confirm: "确认删除模块: ",
|
||||
delete_all_resource: "以及模块下所有子模块和测试用例",
|
||||
module: "模块",
|
||||
title: "标题",
|
||||
status: "状态",
|
||||
describe: "描述",
|
||||
current_owner: "处理人",
|
||||
creation_time: "创建时间"
|
||||
},
|
||||
home: {
|
||||
recent_test: "最近测试",
|
||||
|
@ -653,6 +658,7 @@ export default {
|
|||
test_result: "测试结果",
|
||||
result_distribution: "测试结果分布",
|
||||
custom_component: "自定义模块",
|
||||
defect_list:"缺陷列表",
|
||||
create_report: "创建测试报告",
|
||||
view_report: "查看测试报告",
|
||||
component_library: "组件库",
|
||||
|
|
|
@ -352,6 +352,7 @@ export default {
|
|||
input_name: "請輸入測試名稱",
|
||||
select_project: "請選擇項目",
|
||||
variable_name: "變數名",
|
||||
variable: "變數",
|
||||
copied: "已拷貝",
|
||||
key: "鍵",
|
||||
value: "值",
|
||||
|
@ -401,6 +402,7 @@ export default {
|
|||
path_description: "例如:/login",
|
||||
url_invalid: "URL無效",
|
||||
parameters: "請求參數",
|
||||
jmeter_func: "Jmeter 方法",
|
||||
parameters_filter_example: "示例",
|
||||
parameters_filter_tips: "只支持MockJs函數結果預覽",
|
||||
parameters_advance: "高級參數設置",
|
||||
|
@ -610,6 +612,11 @@ export default {
|
|||
delete_confirm: "確認刪除模塊: ",
|
||||
delete_all_resource: "以及模塊下所有子模塊和測試用例",
|
||||
module: "模塊",
|
||||
title: "標題",
|
||||
status: "狀態",
|
||||
describe: "描述",
|
||||
current_owner: "處理人",
|
||||
creation_time: "創建時間"
|
||||
},
|
||||
home: {
|
||||
recent_test: "最近測試",
|
||||
|
@ -649,6 +656,7 @@ export default {
|
|||
result_distribution: "測試結果分布",
|
||||
custom_component: "自定義模塊",
|
||||
create_report: "創建測試報告",
|
||||
defect_list:"缺陷清單",
|
||||
view_report: "查看測試報告",
|
||||
component_library: "組件庫",
|
||||
component_library_tip: "拖拽組件庫中組件,添加至右側,預覽報告效果,每個系統組件只能添加壹個。",
|
||||
|
|
|
@ -88,8 +88,15 @@
|
|||
beforeCreate() {
|
||||
this.$get("/isLogin").then(response => {
|
||||
if (!response.data.success) {
|
||||
this.ready = true;
|
||||
if (response.data.message === 'sso') {
|
||||
window.location.href = "/sso/login"
|
||||
} else {
|
||||
this.ready = true;
|
||||
}
|
||||
} else {
|
||||
let user = response.data.data;
|
||||
saveLocalStorage(user);
|
||||
this.getLanguage(user.language);
|
||||
window.location.href = "/"
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue