feat(接口定义): 合并master 最新代码
This commit is contained in:
commit
22108b3048
|
@ -6,11 +6,11 @@ ARG MS_VERSION=dev
|
||||||
|
|
||||||
RUN mkdir -p /opt/apps && mkdir -p /opt/jmeter
|
RUN mkdir -p /opt/apps && mkdir -p /opt/jmeter
|
||||||
|
|
||||||
COPY backend/target/backend-1.4.jar /opt/apps
|
COPY backend/target/backend-1.5.jar /opt/apps
|
||||||
|
|
||||||
COPY backend/target/classes/jmeter/ /opt/jmeter/
|
COPY backend/target/classes/jmeter/ /opt/jmeter/
|
||||||
|
|
||||||
ENV JAVA_APP_JAR=/opt/apps/backend-1.4.jar
|
ENV JAVA_APP_JAR=/opt/apps/backend-1.5.jar
|
||||||
|
|
||||||
ENV AB_OFF=true
|
ENV AB_OFF=true
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>metersphere-server</artifactId>
|
<artifactId>metersphere-server</artifactId>
|
||||||
<groupId>io.metersphere</groupId>
|
<groupId>io.metersphere</groupId>
|
||||||
<version>1.4</version>
|
<version>1.5</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
@ -156,7 +156,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.python</groupId>
|
<groupId>org.python</groupId>
|
||||||
<artifactId>jython-standalone</artifactId>
|
<artifactId>jython-standalone</artifactId>
|
||||||
<version>2.7.2</version>
|
<version>2.7.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -146,7 +146,12 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
|
||||||
ScenarioResult scenarioResult;
|
ScenarioResult scenarioResult;
|
||||||
if (!scenarios.containsKey(scenarioId)) {
|
if (!scenarios.containsKey(scenarioId)) {
|
||||||
scenarioResult = new ScenarioResult();
|
scenarioResult = new ScenarioResult();
|
||||||
scenarioResult.setId(scenarioId);
|
try {
|
||||||
|
scenarioResult.setId(Integer.parseInt(scenarioId));
|
||||||
|
} catch (Exception e) {
|
||||||
|
scenarioResult.setId(0);
|
||||||
|
LogUtil.error("场景ID转换异常: " + e.getMessage());
|
||||||
|
}
|
||||||
scenarioResult.setName(scenarioName);
|
scenarioResult.setName(scenarioName);
|
||||||
scenarios.put(scenarioId, scenarioResult);
|
scenarios.put(scenarioId, scenarioResult);
|
||||||
} else {
|
} else {
|
||||||
|
@ -203,13 +208,13 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
|
||||||
testPlanTestCaseService.updateTestCaseStates(ids, TestPlanTestCaseStatus.Failure.name());
|
testPlanTestCaseService.updateTestCaseStates(ids, TestPlanTestCaseStatus.Failure.name());
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
sendTask(report, testResult);
|
sendTask(report, testResult);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import java.util.List;
|
||||||
@Data
|
@Data
|
||||||
public class ScenarioResult {
|
public class ScenarioResult {
|
||||||
|
|
||||||
private String id;
|
private Integer id;
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ public class JmeterDocumentParser {
|
||||||
}
|
}
|
||||||
return documentToBytes(document);
|
return documentToBytes(document);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,7 +161,9 @@ public class JmeterDocumentParser {
|
||||||
break;
|
break;
|
||||||
case "Argument.value":
|
case "Argument.value":
|
||||||
String textContent = ele.getTextContent();
|
String textContent = ele.getTextContent();
|
||||||
|
if (StringUtils.startsWith(textContent, "@")) {
|
||||||
ele.setTextContent(ScriptEngineUtils.calculate(textContent));
|
ele.setTextContent(ScriptEngineUtils.calculate(textContent));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -8,6 +8,7 @@ import io.metersphere.api.dto.scenario.request.dubbo.RegistryCenter;
|
||||||
import io.metersphere.api.jmeter.JMeterService;
|
import io.metersphere.api.jmeter.JMeterService;
|
||||||
import io.metersphere.api.parse.ApiImportParser;
|
import io.metersphere.api.parse.ApiImportParser;
|
||||||
import io.metersphere.api.parse.ApiImportParserFactory;
|
import io.metersphere.api.parse.ApiImportParserFactory;
|
||||||
|
import io.metersphere.api.parse.JmeterDocumentParser;
|
||||||
import io.metersphere.base.domain.*;
|
import io.metersphere.base.domain.*;
|
||||||
import io.metersphere.base.mapper.ApiTestFileMapper;
|
import io.metersphere.base.mapper.ApiTestFileMapper;
|
||||||
import io.metersphere.base.mapper.ApiTestMapper;
|
import io.metersphere.base.mapper.ApiTestMapper;
|
||||||
|
@ -85,9 +86,9 @@ public class APITestService {
|
||||||
return extApiTestMapper.listByIds(request.getIds());
|
return extApiTestMapper.listByIds(request.getIds());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void create(SaveAPITestRequest request, List<MultipartFile> bodyFiles) {
|
public void create(SaveAPITestRequest request, MultipartFile file, List<MultipartFile> bodyFiles) {
|
||||||
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds());
|
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds());
|
||||||
ApiTest test = createTest(request);
|
ApiTest test = createTest(request, file);
|
||||||
createBodyFiles(test, bodyUploadIds, bodyFiles);
|
createBodyFiles(test, bodyUploadIds, bodyFiles);
|
||||||
}
|
}
|
||||||
private ApiTest createTest(SaveAPITestRequest request, MultipartFile file) {
|
private ApiTest createTest(SaveAPITestRequest request, MultipartFile file) {
|
||||||
|
@ -101,13 +102,17 @@ public class APITestService {
|
||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(SaveAPITestRequest request, List<MultipartFile> bodyFiles) {
|
public void update(SaveAPITestRequest request, MultipartFile file, List<MultipartFile> bodyFiles) {
|
||||||
|
if (file == null) {
|
||||||
|
throw new IllegalArgumentException(Translator.get("file_cannot_be_null"));
|
||||||
|
}
|
||||||
deleteFileByTestId(request.getId());
|
deleteFileByTestId(request.getId());
|
||||||
|
|
||||||
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds());
|
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds());
|
||||||
request.setBodyUploadIds(null);
|
request.setBodyUploadIds(null);
|
||||||
ApiTest test = updateTest(request);
|
ApiTest test = updateTest(request);
|
||||||
createBodyFiles(test, bodyUploadIds, bodyFiles);
|
createBodyFiles(test, bodyUploadIds, bodyFiles);
|
||||||
|
saveFile(test.getId(), file);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createBodyFiles(ApiTest test, List<String> bodyUploadIds, List<MultipartFile> bodyFiles) {
|
private void createBodyFiles(ApiTest test, List<String> bodyUploadIds, List<MultipartFile> bodyFiles) {
|
||||||
|
@ -126,7 +131,7 @@ public class APITestService {
|
||||||
file.createNewFile();
|
file.createNewFile();
|
||||||
FileUtil.copyStream(in, out);
|
FileUtil.copyStream(in, out);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
MSException.throwException(Translator.get("upload_fail"));
|
MSException.throwException(Translator.get("upload_fail"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,7 +174,7 @@ public class APITestService {
|
||||||
try {
|
try {
|
||||||
FileUtil.copyDir(sourceFile, new File(targetDir));
|
FileUtil.copyDir(sourceFile, new File(targetDir));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
MSException.throwException(Translator.get("upload_fail"));
|
MSException.throwException(Translator.get("upload_fail"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,14 +217,27 @@ public class APITestService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String run(SaveAPITestRequest request,String runMode) {
|
public String run(SaveAPITestRequest request) {
|
||||||
|
ApiTestFile file = getFileByTestId(request.getId());
|
||||||
|
if (file == null) {
|
||||||
|
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());
|
APITestResult apiTest = get(request.getId());
|
||||||
if (SessionUtils.getUser() == null) {
|
if (SessionUtils.getUser() == null) {
|
||||||
apiTest.setUserId(request.getUserId());
|
apiTest.setUserId(request.getUserId());
|
||||||
}
|
}
|
||||||
String reportId = apiReportService.create(apiTest, request.getTriggerMode());
|
String reportId = apiReportService.create(apiTest, request.getTriggerMode());
|
||||||
|
/*if (request.getTriggerMode().equals("SCHEDULE")) {
|
||||||
|
List<Notice> notice = noticeService.queryNotice(request.getId());
|
||||||
|
mailService.sendHtml(reportId,notice,"api");
|
||||||
|
}*/
|
||||||
changeStatus(request.getId(), APITestStatus.Running);
|
changeStatus(request.getId(), APITestStatus.Running);
|
||||||
jMeterService.run(request.getId(), request.getName(), request.getScenarioDefinition(), null,runMode);
|
jMeterService.run(request.getId(), null, is);
|
||||||
return reportId;
|
return reportId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,8 +278,6 @@ public class APITestService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private ApiTest createTest(SaveAPITestRequest request) {
|
private ApiTest createTest(SaveAPITestRequest request) {
|
||||||
checkQuota();
|
|
||||||
request.setBodyUploadIds(null);
|
|
||||||
checkNameExist(request);
|
checkNameExist(request);
|
||||||
final ApiTest test = new ApiTest();
|
final ApiTest test = new ApiTest();
|
||||||
test.setId(request.getId());
|
test.setId(request.getId());
|
||||||
|
@ -276,6 +292,14 @@ public class APITestService {
|
||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void saveFile(String testId, MultipartFile file) {
|
||||||
|
final FileMetadata fileMetadata = fileService.saveFile(file);
|
||||||
|
ApiTestFile apiTestFile = new ApiTestFile();
|
||||||
|
apiTestFile.setTestId(testId);
|
||||||
|
apiTestFile.setFileId(fileMetadata.getId());
|
||||||
|
apiTestFileMapper.insert(apiTestFile);
|
||||||
|
}
|
||||||
|
|
||||||
private void deleteFileByTestId(String testId) {
|
private void deleteFileByTestId(String testId) {
|
||||||
ApiTestFileExample ApiTestFileExample = new ApiTestFileExample();
|
ApiTestFileExample ApiTestFileExample = new ApiTestFileExample();
|
||||||
ApiTestFileExample.createCriteria().andTestIdEqualTo(testId);
|
ApiTestFileExample.createCriteria().andTestIdEqualTo(testId);
|
||||||
|
@ -287,12 +311,17 @@ public class APITestService {
|
||||||
fileService.deleteFileByIds(fileIds);
|
fileService.deleteFileByIds(fileIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void saveFile(String testId, MultipartFile file) {
|
|
||||||
final FileMetadata fileMetadata = fileService.saveFile(file);
|
private ApiTestFile getFileByTestId(String testId) {
|
||||||
ApiTestFile apiTestFile = new ApiTestFile();
|
ApiTestFileExample ApiTestFileExample = new ApiTestFileExample();
|
||||||
apiTestFile.setTestId(testId);
|
ApiTestFileExample.createCriteria().andTestIdEqualTo(testId);
|
||||||
apiTestFile.setFileId(fileMetadata.getId());
|
final List<ApiTestFile> ApiTestFiles = apiTestFileMapper.selectByExample(ApiTestFileExample);
|
||||||
apiTestFileMapper.insert(apiTestFile);
|
apiTestFileMapper.selectByExample(ApiTestFileExample);
|
||||||
|
if (!CollectionUtils.isEmpty(ApiTestFiles)) {
|
||||||
|
return ApiTestFiles.get(0);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateSchedule(Schedule request) {
|
public void updateSchedule(Schedule request) {
|
||||||
|
@ -312,17 +341,6 @@ public class APITestService {
|
||||||
schedule.setType(ScheduleType.CRON.name());
|
schedule.setType(ScheduleType.CRON.name());
|
||||||
return schedule;
|
return schedule;
|
||||||
}
|
}
|
||||||
private ApiTestFile getFileByTestId(String testId) {
|
|
||||||
ApiTestFileExample ApiTestFileExample = new ApiTestFileExample();
|
|
||||||
ApiTestFileExample.createCriteria().andTestIdEqualTo(testId);
|
|
||||||
final List<ApiTestFile> ApiTestFiles = apiTestFileMapper.selectByExample(ApiTestFileExample);
|
|
||||||
apiTestFileMapper.selectByExample(ApiTestFileExample);
|
|
||||||
if (!CollectionUtils.isEmpty(ApiTestFiles)) {
|
|
||||||
return ApiTestFiles.get(0);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addOrUpdateApiTestCronJob(Schedule request) {
|
private void addOrUpdateApiTestCronJob(Schedule request) {
|
||||||
scheduleService.addOrUpdateCronJob(request, ApiTestJob.getJobKey(request.getResourceId()), ApiTestJob.getTriggerKey(request.getResourceId()), ApiTestJob.class);
|
scheduleService.addOrUpdateCronJob(request, ApiTestJob.getJobKey(request.getResourceId()), ApiTestJob.getTriggerKey(request.getResourceId()), ApiTestJob.class);
|
||||||
|
@ -398,7 +416,10 @@ public class APITestService {
|
||||||
return schedules;
|
return schedules;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String runDebug(SaveAPITestRequest request, List<MultipartFile> bodyFiles,String runMode) {
|
public String runDebug(SaveAPITestRequest request, MultipartFile file, List<MultipartFile> bodyFiles) {
|
||||||
|
if (file == null) {
|
||||||
|
throw new IllegalArgumentException(Translator.get("file_cannot_be_null"));
|
||||||
|
}
|
||||||
updateTest(request);
|
updateTest(request);
|
||||||
APITestResult apiTest = get(request.getId());
|
APITestResult apiTest = get(request.getId());
|
||||||
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds());
|
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds());
|
||||||
|
@ -409,7 +430,17 @@ public class APITestService {
|
||||||
}
|
}
|
||||||
String reportId = apiReportService.createDebugReport(apiTest);
|
String reportId = apiReportService.createDebugReport(apiTest);
|
||||||
|
|
||||||
jMeterService.run(request.getId(), request.getName(), request.getScenarioDefinition(), reportId,runMode);
|
InputStream is = null;
|
||||||
|
try {
|
||||||
|
byte[] bytes = file.getBytes();
|
||||||
|
// 解析 xml 处理 mock 数据
|
||||||
|
bytes = JmeterDocumentParser.parse(bytes);
|
||||||
|
is = new ByteArrayInputStream(bytes);
|
||||||
|
} catch (IOException e) {
|
||||||
|
LogUtil.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
jMeterService.run(request.getId(), reportId, is);
|
||||||
return reportId;
|
return reportId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,12 +451,10 @@ public class APITestService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void mergeCreate(SaveAPITestRequest request, List<String> selectIds) {
|
public void mergeCreate(SaveAPITestRequest request, MultipartFile file, List<String> selectIds) {
|
||||||
ApiTest test = createTest(request);
|
ApiTest test = createTest(request, file);
|
||||||
selectIds.forEach(sourceId -> copyBodyFiles(test.getId(), sourceId));
|
selectIds.forEach(sourceId -> {
|
||||||
}
|
copyBodyFiles(test.getId(), sourceId);
|
||||||
|
});
|
||||||
public String getJMX(SaveAPITestRequest request) {
|
|
||||||
return jMeterService.getJMX(jMeterService.getHashTree(request.getId(), request.getName(), request.getScenarioDefinition()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,6 +133,7 @@
|
||||||
LEFT JOIN user ON user.id = r.user_id
|
LEFT JOIN user ON user.id = r.user_id
|
||||||
<where>
|
<where>
|
||||||
r.test_id = #{testId}
|
r.test_id = #{testId}
|
||||||
|
and r.status != 'Debug'
|
||||||
</where>
|
</where>
|
||||||
ORDER BY r.update_time DESC
|
ORDER BY r.update_time DESC
|
||||||
</select>
|
</select>
|
||||||
|
|
|
@ -258,7 +258,8 @@
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="list" resultType="io.metersphere.track.dto.TestCaseDTO">
|
<select id="list" resultType="io.metersphere.track.dto.TestCaseDTO">
|
||||||
select test_case.* from test_case
|
select <include refid="io.metersphere.base.mapper.TestCaseMapper.Base_Column_List"/>
|
||||||
|
from test_case
|
||||||
<where>
|
<where>
|
||||||
<if test="request.combine != null">
|
<if test="request.combine != null">
|
||||||
<include refid="combine">
|
<include refid="combine">
|
||||||
|
|
|
@ -95,8 +95,7 @@ public interface ParamConstants {
|
||||||
PASSWORD("smtp.password", 4),
|
PASSWORD("smtp.password", 4),
|
||||||
SSL("smtp.ssl", 5),
|
SSL("smtp.ssl", 5),
|
||||||
TLS("smtp.tls", 6),
|
TLS("smtp.tls", 6),
|
||||||
SMTP("smtp.smtp", 7);
|
ANON("smtp.anon", 7);
|
||||||
/* ANON("smtp.anon", 7);*/
|
|
||||||
|
|
||||||
private String key;
|
private String key;
|
||||||
private Integer value;
|
private Integer value;
|
||||||
|
|
|
@ -88,7 +88,7 @@ public class CompressUtils {
|
||||||
gzip.finish();
|
gzip.finish();
|
||||||
return obj.toByteArray();
|
return obj.toByteArray();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@ public class CompressUtils {
|
||||||
baos.flush();
|
baos.flush();
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,10 +48,6 @@ public class JsonPathUtils {
|
||||||
String o_json_path = "$" + jsonPath.next().replaceAll("/", ".");
|
String o_json_path = "$" + jsonPath.next().replaceAll("/", ".");
|
||||||
String value = JSONPath.eval(jsonObject, o_json_path).toString();
|
String value = JSONPath.eval(jsonObject, o_json_path).toString();
|
||||||
|
|
||||||
if(o_json_path.toLowerCase().contains("id")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(value.equals("") || value.equals("[]") || o_json_path.equals("")) {
|
if(value.equals("") || value.equals("[]") || o_json_path.equals("")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ public class ScriptEngineUtils {
|
||||||
String script = IOUtils.toString(ScriptEngineUtils.class.getResource("/javascript/func.js"), StandardCharsets.UTF_8);
|
String script = IOUtils.toString(ScriptEngineUtils.class.getResource("/javascript/func.js"), StandardCharsets.UTF_8);
|
||||||
engine.eval(script);
|
engine.eval(script);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ public class ScriptEngineUtils {
|
||||||
try {
|
try {
|
||||||
return engine.eval("calculate('" + input + "')").toString();
|
return engine.eval("calculate('" + input + "')").toString();
|
||||||
} catch (ScriptException e) {
|
} catch (ScriptException e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ public class ShiroConfig implements EnvironmentAware {
|
||||||
Map<String, String> filterChainDefinitionMap = shiroFilterFactoryBean.getFilterChainDefinitionMap();
|
Map<String, String> filterChainDefinitionMap = shiroFilterFactoryBean.getFilterChainDefinitionMap();
|
||||||
ShiroUtils.loadBaseFilterChain(filterChainDefinitionMap);
|
ShiroUtils.loadBaseFilterChain(filterChainDefinitionMap);
|
||||||
filterChainDefinitionMap.put("/display/info", "anon");
|
filterChainDefinitionMap.put("/display/info", "anon");
|
||||||
filterChainDefinitionMap.put("/display/file/*", "anon");
|
filterChainDefinitionMap.put("/display/file/**", "anon");
|
||||||
filterChainDefinitionMap.put("/**", "apikey, authc");
|
filterChainDefinitionMap.put("/**", "apikey, authc");
|
||||||
return shiroFilterFactoryBean;
|
return shiroFilterFactoryBean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,13 +53,13 @@ public class TestResourcePoolController {
|
||||||
|
|
||||||
@GetMapping("list/all/valid")
|
@GetMapping("list/all/valid")
|
||||||
@RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER, RoleConstants.TEST_VIEWER}, logical = Logical.OR)
|
@RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER, RoleConstants.TEST_VIEWER}, logical = Logical.OR)
|
||||||
public List<TestResourcePool> listValidResourcePools() {
|
public List<TestResourcePoolDTO> listValidResourcePools() {
|
||||||
return testResourcePoolService.listValidResourcePools();
|
return testResourcePoolService.listValidResourcePools();
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("list/quota/valid")
|
@GetMapping("list/quota/valid")
|
||||||
@RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER, RoleConstants.TEST_VIEWER}, logical = Logical.OR)
|
@RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER, RoleConstants.TEST_VIEWER}, logical = Logical.OR)
|
||||||
public List<TestResourcePool> listValidQuotaResourcePools() {
|
public List<TestResourcePoolDTO> listValidQuotaResourcePools() {
|
||||||
return testResourcePoolService.listValidQuotaResourcePools();
|
return testResourcePoolService.listValidQuotaResourcePools();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,4 +7,5 @@ import lombok.Setter;
|
||||||
@Setter
|
@Setter
|
||||||
public class QueryResourcePoolRequest {
|
public class QueryResourcePoolRequest {
|
||||||
private String name;
|
private String name;
|
||||||
|
private String status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,13 +72,15 @@ public class AppStartListener implements ApplicationListener<ApplicationReadyEve
|
||||||
*/
|
*/
|
||||||
private void loadJars() {
|
private void loadJars() {
|
||||||
List<JarConfig> jars = jarConfigService.list();
|
List<JarConfig> jars = jarConfigService.list();
|
||||||
try {
|
|
||||||
jars.forEach(jarConfig -> {
|
jars.forEach(jarConfig -> {
|
||||||
|
try {
|
||||||
NewDriverManager.loadJar(jarConfig.getPath());
|
NewDriverManager.loadJar(jarConfig.getPath());
|
||||||
});
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
LogUtil.error(e.getMessage(), e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ public class DingTaskService {
|
||||||
try {
|
try {
|
||||||
response = client.execute(request);
|
response = client.execute(request);
|
||||||
} catch (ApiException e) {
|
} catch (ApiException e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
System.out.println(response.getErrcode());
|
System.out.println(response.getErrcode());
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,7 @@ package io.metersphere.notice.service;
|
||||||
|
|
||||||
import io.metersphere.base.domain.*;
|
import io.metersphere.base.domain.*;
|
||||||
import io.metersphere.base.mapper.UserMapper;
|
import io.metersphere.base.mapper.UserMapper;
|
||||||
import io.metersphere.commons.constants.APITestStatus;
|
import io.metersphere.commons.constants.*;
|
||||||
import io.metersphere.commons.constants.NoticeConstants;
|
|
||||||
import io.metersphere.commons.constants.ParamConstants;
|
|
||||||
import io.metersphere.commons.constants.PerformanceTestStatus;
|
|
||||||
import io.metersphere.commons.user.SessionUser;
|
import io.metersphere.commons.user.SessionUser;
|
||||||
import io.metersphere.commons.utils.EncryptUtils;
|
import io.metersphere.commons.utils.EncryptUtils;
|
||||||
import io.metersphere.commons.utils.LogUtil;
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
|
@ -22,6 +19,7 @@ import io.metersphere.track.request.testreview.SaveTestCaseReviewRequest;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.apache.commons.collections4.MapUtils;
|
import org.apache.commons.collections4.MapUtils;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import org.apache.commons.lang3.RegExUtils;
|
import org.apache.commons.lang3.RegExUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.mail.MailException;
|
import org.springframework.mail.MailException;
|
||||||
|
@ -67,7 +65,7 @@ public class MailService {
|
||||||
}
|
}
|
||||||
sendApiOrLoadNotification(addresseeIdList(messageDetail, userIds, eventType), context, performanceTemplate, loadTestReport.getTriggerMode());
|
sendApiOrLoadNotification(addresseeIdList(messageDetail, userIds, eventType), context, performanceTemplate, loadTestReport.getTriggerMode());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +86,7 @@ public class MailService {
|
||||||
}
|
}
|
||||||
sendApiOrLoadNotification(addresseeIdList(messageDetail, userIds, eventType), context, apiTemplate, apiTestReport.getTriggerMode());
|
sendApiOrLoadNotification(addresseeIdList(messageDetail, userIds, eventType), context, apiTemplate, apiTestReport.getTriggerMode());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +118,7 @@ public class MailService {
|
||||||
try {
|
try {
|
||||||
javaMailSender.send(mimeMessage);
|
javaMailSender.send(mimeMessage);
|
||||||
} catch (MailException e) {
|
} catch (MailException e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//测试评审
|
//测试评审
|
||||||
|
@ -131,7 +129,7 @@ public class MailService {
|
||||||
String endTemplate = IOUtils.toString(this.getClass().getResource("/mail/ReviewEnd.html"), StandardCharsets.UTF_8);
|
String endTemplate = IOUtils.toString(this.getClass().getResource("/mail/ReviewEnd.html"), StandardCharsets.UTF_8);
|
||||||
sendReviewNotice(addresseeIdList(messageDetail, userIds, eventType), context, endTemplate);
|
sendReviewNotice(addresseeIdList(messageDetail, userIds, eventType), context, endTemplate);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +139,7 @@ public class MailService {
|
||||||
String endTemplate = IOUtils.toString(this.getClass().getResource("/mail/ReviewDelete.html"), StandardCharsets.UTF_8);
|
String endTemplate = IOUtils.toString(this.getClass().getResource("/mail/ReviewDelete.html"), StandardCharsets.UTF_8);
|
||||||
sendReviewNotice(addresseeIdList(messageDetail, userIds, eventType), context, endTemplate);
|
sendReviewNotice(addresseeIdList(messageDetail, userIds, eventType), context, endTemplate);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +156,7 @@ public class MailService {
|
||||||
String commentTemplate = IOUtils.toString(this.getClass().getResource("/mail/ReviewComments.html"), StandardCharsets.UTF_8);
|
String commentTemplate = IOUtils.toString(this.getClass().getResource("/mail/ReviewComments.html"), StandardCharsets.UTF_8);
|
||||||
sendReviewNotice(addresseeIdList(messageDetail, userIds, eventType), context, commentTemplate);
|
sendReviewNotice(addresseeIdList(messageDetail, userIds, eventType), context, commentTemplate);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,7 +166,7 @@ public class MailService {
|
||||||
String reviewerTemplate = IOUtils.toString(this.getClass().getResource("/mail/ReviewInitiate.html"), StandardCharsets.UTF_8);
|
String reviewerTemplate = IOUtils.toString(this.getClass().getResource("/mail/ReviewInitiate.html"), StandardCharsets.UTF_8);
|
||||||
sendReviewNotice(addresseeIdList(messageDetail, userIds, eventType), context, reviewerTemplate);
|
sendReviewNotice(addresseeIdList(messageDetail, userIds, eventType), context, reviewerTemplate);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +205,7 @@ public class MailService {
|
||||||
String endTemplate = IOUtils.toString(this.getClass().getResource("/mail/TestPlanStart.html"), StandardCharsets.UTF_8);
|
String endTemplate = IOUtils.toString(this.getClass().getResource("/mail/TestPlanStart.html"), StandardCharsets.UTF_8);
|
||||||
sendTestPlanNotice(addresseeIdList(messageDetail, userIds, eventType), context, endTemplate);
|
sendTestPlanNotice(addresseeIdList(messageDetail, userIds, eventType), context, endTemplate);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,7 +217,7 @@ public class MailService {
|
||||||
String endTemplate = IOUtils.toString(this.getClass().getResource("/mail/TestPlanEnd.html"), StandardCharsets.UTF_8);
|
String endTemplate = IOUtils.toString(this.getClass().getResource("/mail/TestPlanEnd.html"), StandardCharsets.UTF_8);
|
||||||
sendTestPlanNotice(addresseeIdList(messageDetail, userIds, eventType), context, endTemplate);
|
sendTestPlanNotice(addresseeIdList(messageDetail, userIds, eventType), context, endTemplate);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,7 +229,7 @@ public class MailService {
|
||||||
String endTemplate = IOUtils.toString(this.getClass().getResource("/mail/TestPlanDelete.html"), StandardCharsets.UTF_8);
|
String endTemplate = IOUtils.toString(this.getClass().getResource("/mail/TestPlanDelete.html"), StandardCharsets.UTF_8);
|
||||||
sendTestPlanNotice(addresseeIdList(messageDetail, userIds, eventType), context, endTemplate);
|
sendTestPlanNotice(addresseeIdList(messageDetail, userIds, eventType), context, endTemplate);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,7 +266,7 @@ public class MailService {
|
||||||
String endTemplate = IOUtils.toString(this.getClass().getResource("/mail/IssuesCreate.html"), StandardCharsets.UTF_8);
|
String endTemplate = IOUtils.toString(this.getClass().getResource("/mail/IssuesCreate.html"), StandardCharsets.UTF_8);
|
||||||
sendIssuesNotice(addresseeIdList(messageDetail, userIds, eventType), context, endTemplate);
|
sendIssuesNotice(addresseeIdList(messageDetail, userIds, eventType), context, endTemplate);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,6 +319,15 @@ public class MailService {
|
||||||
context.put("start", start);
|
context.put("start", start);
|
||||||
context.put("end", end);
|
context.put("end", end);
|
||||||
context.put("id", reviewRequest.getId());
|
context.put("id", reviewRequest.getId());
|
||||||
|
String status = "";
|
||||||
|
if (StringUtils.equals(TestPlanStatus.Underway.name(), reviewRequest.getStatus())) {
|
||||||
|
status = "进行中";
|
||||||
|
} else if (StringUtils.equals(TestPlanStatus.Prepare.name(), reviewRequest.getStatus())) {
|
||||||
|
status = "未开始";
|
||||||
|
} else if (StringUtils.equals(TestPlanStatus.Completed.name(), reviewRequest.getStatus())) {
|
||||||
|
status = "已完成";
|
||||||
|
}
|
||||||
|
context.put("status", status);
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,19 +354,29 @@ public class MailService {
|
||||||
context.put("start", start);
|
context.put("start", start);
|
||||||
context.put("end", end);
|
context.put("end", end);
|
||||||
context.put("id", testPlan.getId());
|
context.put("id", testPlan.getId());
|
||||||
|
String status = "";
|
||||||
|
if (StringUtils.equals(TestPlanStatus.Underway.name(), testPlan.getStatus())) {
|
||||||
|
status = "进行中";
|
||||||
|
} else if (StringUtils.equals(TestPlanStatus.Prepare.name(), testPlan.getStatus())) {
|
||||||
|
status = "未开始";
|
||||||
|
} else if (StringUtils.equals(TestPlanStatus.Completed.name(), testPlan.getStatus())) {
|
||||||
|
status = "已完成";
|
||||||
|
}
|
||||||
|
context.put("status", status);
|
||||||
User user = userMapper.selectByPrimaryKey(testPlan.getCreator());
|
User user = userMapper.selectByPrimaryKey(testPlan.getCreator());
|
||||||
context.put("creator", user.getName());
|
context.put("creator", user.getName());
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private JavaMailSenderImpl getMailSender() {
|
private JavaMailSenderImpl getMailSender() {
|
||||||
|
Properties props = new Properties();
|
||||||
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
|
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
|
||||||
List<SystemParameter> paramList = systemParameterService.getParamList(ParamConstants.Classify.MAIL.getValue());
|
List<SystemParameter> paramList = systemParameterService.getParamList(ParamConstants.Classify.MAIL.getValue());
|
||||||
javaMailSender.setDefaultEncoding("UTF-8");
|
javaMailSender.setDefaultEncoding("UTF-8");
|
||||||
javaMailSender.setProtocol("smtps");
|
javaMailSender.setProtocol("smtp");
|
||||||
|
props.put("mail.smtp.auth", "true");
|
||||||
|
|
||||||
for (SystemParameter p : paramList) {
|
for (SystemParameter p : paramList) {
|
||||||
switch (p.getParamKey()) {
|
switch (p.getParamKey()) {
|
||||||
case "smtp.host":
|
case "smtp.host":
|
||||||
|
@ -374,14 +391,30 @@ public class MailService {
|
||||||
case "smtp.password":
|
case "smtp.password":
|
||||||
javaMailSender.setPassword(EncryptUtils.aesDecrypt(p.getParamValue()).toString());
|
javaMailSender.setPassword(EncryptUtils.aesDecrypt(p.getParamValue()).toString());
|
||||||
break;
|
break;
|
||||||
|
case "smtp.ssl":
|
||||||
|
javaMailSender.setProtocol("smtps");
|
||||||
|
if (BooleanUtils.toBoolean(p.getParamValue())) {
|
||||||
|
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "smtp.tls":
|
||||||
|
String result = BooleanUtils.toString(BooleanUtils.toBoolean(p.getParamValue()), "true", "false");
|
||||||
|
props.put("mail.smtp.starttls.enable", result);
|
||||||
|
props.put("mail.smtp.starttls.required", result);
|
||||||
|
break;
|
||||||
|
case "smtp.anon":
|
||||||
|
boolean isAnon = BooleanUtils.toBoolean(p.getParamValue());
|
||||||
|
if (isAnon) {
|
||||||
|
props.put("mail.smtp.auth", "false");
|
||||||
|
javaMailSender.setUsername(null);
|
||||||
|
javaMailSender.setPassword(null);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Properties props = new Properties();
|
|
||||||
props.put("mail.smtp.auth", "true");
|
|
||||||
props.put("mail.smtp.starttls.enable", "true");
|
|
||||||
props.put("mail.smtp.starttls.required", "true");
|
|
||||||
props.put("mail.smtp.timeout", "30000");
|
props.put("mail.smtp.timeout", "30000");
|
||||||
props.put("mail.smtp.connectiontimeout", "5000");
|
props.put("mail.smtp.connectiontimeout", "5000");
|
||||||
javaMailSender.setJavaMailProperties(props);
|
javaMailSender.setJavaMailProperties(props);
|
||||||
|
@ -396,6 +429,7 @@ public class MailService {
|
||||||
} else {
|
} else {
|
||||||
template = RegExUtils.replaceAll(template, "\\$\\{" + k + "}", "未设置");
|
template = RegExUtils.replaceAll(template, "\\$\\{" + k + "}", "未设置");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return template;
|
return template;
|
||||||
|
@ -405,7 +439,7 @@ public class MailService {
|
||||||
List<String> addresseeIdList = new ArrayList<>();
|
List<String> addresseeIdList = new ArrayList<>();
|
||||||
if (StringUtils.equals(eventType, messageDetail.getEvent())) {
|
if (StringUtils.equals(eventType, messageDetail.getEvent())) {
|
||||||
messageDetail.getUserIds().forEach(u -> {
|
messageDetail.getUserIds().forEach(u -> {
|
||||||
if (!StringUtils.equals(NoticeConstants.EXECUTOR, u) && !StringUtils.equals(NoticeConstants.EXECUTOR, u) && !StringUtils.equals(NoticeConstants.MAINTAINER, u)) {
|
if (!StringUtils.equals(NoticeConstants.EXECUTOR, u) && !StringUtils.equals(NoticeConstants.FOUNDER, u) && !StringUtils.equals(NoticeConstants.MAINTAINER, u)) {
|
||||||
addresseeIdList.add(u);
|
addresseeIdList.add(u);
|
||||||
}
|
}
|
||||||
if (StringUtils.equals(NoticeConstants.CREATE, eventType) && StringUtils.equals(NoticeConstants.EXECUTOR, u)) {
|
if (StringUtils.equals(NoticeConstants.CREATE, eventType) && StringUtils.equals(NoticeConstants.EXECUTOR, u)) {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import io.metersphere.notice.controller.request.MessageRequest;
|
||||||
import io.metersphere.notice.domain.MessageDetail;
|
import io.metersphere.notice.domain.MessageDetail;
|
||||||
import io.metersphere.notice.domain.MessageSettingDetail;
|
import io.metersphere.notice.domain.MessageSettingDetail;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ public class NoticeService {
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
String identification = UUID.randomUUID().toString();
|
String identification = UUID.randomUUID().toString();
|
||||||
list.getUserIds().forEach(m -> {
|
list.getUserIds().forEach(m -> {
|
||||||
checkUserIdExist(m, list);
|
checkUserIdExist(m, list,orgId);
|
||||||
MessageTask message = new MessageTask();
|
MessageTask message = new MessageTask();
|
||||||
message.setId(UUID.randomUUID().toString());
|
message.setId(UUID.randomUUID().toString());
|
||||||
message.setEvent(list.getEvent());
|
message.setEvent(list.getEvent());
|
||||||
|
@ -68,9 +69,13 @@ public class NoticeService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkUserIdExist(String userId, MessageDetail list) {
|
private void checkUserIdExist(String userId, MessageDetail list,String orgId) {
|
||||||
MessageTaskExample example = new MessageTaskExample();
|
MessageTaskExample example = new MessageTaskExample();
|
||||||
example.createCriteria().andUserIdEqualTo(userId).andEventEqualTo(list.getEvent()).andTypeEqualTo(list.getType()).andTaskTypeEqualTo(list.getTaskType()).andWebhookEqualTo(list.getWebhook());
|
if (StringUtils.isBlank(list.getTestId())) {
|
||||||
|
example.createCriteria().andUserIdEqualTo(userId).andEventEqualTo(list.getEvent()).andTypeEqualTo(list.getType()).andTaskTypeEqualTo(list.getTaskType()).andWebhookEqualTo(list.getWebhook()).andOrganizationIdEqualTo(orgId);
|
||||||
|
} else {
|
||||||
|
example.createCriteria().andUserIdEqualTo(userId).andEventEqualTo(list.getEvent()).andTypeEqualTo(list.getType()).andTaskTypeEqualTo(list.getTaskType()).andWebhookEqualTo(list.getWebhook()).andTestIdEqualTo(list.getTestId()).andOrganizationIdEqualTo(orgId);
|
||||||
|
}
|
||||||
if (messageTaskMapper.countByExample(example) > 0) {
|
if (messageTaskMapper.countByExample(example) > 0) {
|
||||||
MSException.throwException(Translator.get("message_task_already_exists"));
|
MSException.throwException(Translator.get("message_task_already_exists"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ public class WxChatTaskService {
|
||||||
SendResult result = WxChatbotClient.send(Webhook, message);
|
SendResult result = WxChatbotClient.send(Webhook, message);
|
||||||
System.out.println(result);
|
System.out.println(result);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -139,10 +139,10 @@ public class EngineFactory {
|
||||||
String content = engineSourceParser.parse(engineContext, source);
|
String content = engineSourceParser.parse(engineContext, source);
|
||||||
engineContext.setContent(content);
|
engineContext.setContent(content);
|
||||||
} catch (MSException e) {
|
} catch (MSException e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
throw e;
|
throw e;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
MSException.throwException(e);
|
MSException.throwException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,10 +64,10 @@ public class DockerTestEngine extends AbstractEngine {
|
||||||
try {
|
try {
|
||||||
context = EngineFactory.createContext(loadTest, resource.getId(), ratio, this.getStartTime(), this.getReportId(), resourceIndex);
|
context = EngineFactory.createContext(loadTest, resource.getId(), ratio, this.getStartTime(), this.getReportId(), resourceIndex);
|
||||||
} catch (MSException e) {
|
} catch (MSException e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
throw e;
|
throw e;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
MSException.throwException(e);
|
MSException.throwException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class PerformanceNoticeTask {
|
||||||
//查询定时任务是否关闭
|
//查询定时任务是否关闭
|
||||||
Thread.sleep(1000 * 30);// 每分钟检查 loadtest 的状态
|
Thread.sleep(1000 * 30);// 每分钟检查 loadtest 的状态
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -258,7 +258,7 @@ public class PerformanceTestService {
|
||||||
soc.close();
|
soc.close();
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
MSException.throwException(Translator.get("load_test_kafka_invalid"));
|
MSException.throwException(Translator.get("load_test_kafka_invalid"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -304,7 +304,7 @@ public class PerformanceTestService {
|
||||||
} catch (MSException e) {
|
} catch (MSException e) {
|
||||||
// 启动失败之后清理任务
|
// 启动失败之后清理任务
|
||||||
engine.stop();
|
engine.stop();
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
loadTest.setStatus(PerformanceTestStatus.Error.name());
|
loadTest.setStatus(PerformanceTestStatus.Error.name());
|
||||||
loadTest.setDescription(e.getMessage());
|
loadTest.setDescription(e.getMessage());
|
||||||
loadTestMapper.updateByPrimaryKeySelective(loadTest);
|
loadTestMapper.updateByPrimaryKeySelective(loadTest);
|
||||||
|
|
|
@ -119,7 +119,7 @@ public class JarConfigService {
|
||||||
file.createNewFile();
|
file.createNewFile();
|
||||||
FileUtil.copyStream(in, out);
|
FileUtil.copyStream(in, out);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
MSException.throwException(Translator.get("upload_fail"));
|
MSException.throwException(Translator.get("upload_fail"));
|
||||||
}
|
}
|
||||||
return filePath;
|
return filePath;
|
||||||
|
|
|
@ -87,7 +87,14 @@ public class SystemParameterService {
|
||||||
javaMailSender.setUsername(hashMap.get(ParamConstants.MAIL.ACCOUNT.getKey()));
|
javaMailSender.setUsername(hashMap.get(ParamConstants.MAIL.ACCOUNT.getKey()));
|
||||||
javaMailSender.setPassword(hashMap.get(ParamConstants.MAIL.PASSWORD.getKey()));
|
javaMailSender.setPassword(hashMap.get(ParamConstants.MAIL.PASSWORD.getKey()));
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
|
boolean isAnon = Boolean.parseBoolean(hashMap.get(ParamConstants.MAIL.ANON.getKey()));
|
||||||
|
if (isAnon) {
|
||||||
|
props.put("mail.smtp.auth", "false");
|
||||||
|
javaMailSender.setUsername(null);
|
||||||
|
javaMailSender.setPassword(null);
|
||||||
|
} else {
|
||||||
props.put("mail.smtp.auth", "true");
|
props.put("mail.smtp.auth", "true");
|
||||||
|
}
|
||||||
if (BooleanUtils.toBoolean(hashMap.get(ParamConstants.MAIL.SSL.getKey()))) {
|
if (BooleanUtils.toBoolean(hashMap.get(ParamConstants.MAIL.SSL.getKey()))) {
|
||||||
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
|
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
|
||||||
}
|
}
|
||||||
|
@ -100,7 +107,7 @@ public class SystemParameterService {
|
||||||
try {
|
try {
|
||||||
javaMailSender.testConnection();
|
javaMailSender.testConnection();
|
||||||
} catch (MessagingException e) {
|
} catch (MessagingException e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
MSException.throwException(Translator.get("connection_failed"));
|
MSException.throwException(Translator.get("connection_failed"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,7 +135,7 @@ public class TestResourcePoolService {
|
||||||
MSException.throwException("Resource Pool is invalid.");
|
MSException.throwException("Resource Pool is invalid.");
|
||||||
}
|
}
|
||||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,6 +145,9 @@ public class TestResourcePoolService {
|
||||||
if (StringUtils.isNotBlank(request.getName())) {
|
if (StringUtils.isNotBlank(request.getName())) {
|
||||||
criteria.andNameLike(StringUtils.wrapIfMissing(request.getName(), "%"));
|
criteria.andNameLike(StringUtils.wrapIfMissing(request.getName(), "%"));
|
||||||
}
|
}
|
||||||
|
if (StringUtils.isNotBlank(request.getStatus())) {
|
||||||
|
criteria.andStatusEqualTo(request.getStatus());
|
||||||
|
}
|
||||||
example.setOrderByClause("update_time desc");
|
example.setOrderByClause("update_time desc");
|
||||||
List<TestResourcePool> testResourcePools = testResourcePoolMapper.selectByExample(example);
|
List<TestResourcePool> testResourcePools = testResourcePoolMapper.selectByExample(example);
|
||||||
List<TestResourcePoolDTO> testResourcePoolDTOS = new ArrayList<>();
|
List<TestResourcePoolDTO> testResourcePoolDTOS = new ArrayList<>();
|
||||||
|
@ -158,7 +161,7 @@ public class TestResourcePoolService {
|
||||||
testResourcePoolDTO.setResources(testResources);
|
testResourcePoolDTO.setResources(testResources);
|
||||||
testResourcePoolDTOS.add(testResourcePoolDTO);
|
testResourcePoolDTOS.add(testResourcePoolDTO);
|
||||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return testResourcePoolDTOS;
|
return testResourcePoolDTOS;
|
||||||
|
@ -207,7 +210,7 @@ public class TestResourcePoolService {
|
||||||
ResponseEntity<String> entity = restTemplateWithTimeOut.getForEntity(String.format(nodeControllerUrl, node.getIp(), node.getPort()), String.class);
|
ResponseEntity<String> entity = restTemplateWithTimeOut.getForEntity(String.format(nodeControllerUrl, node.getIp(), node.getPort()), String.class);
|
||||||
return HttpStatus.OK.equals(entity.getStatusCode());
|
return HttpStatus.OK.equals(entity.getStatusCode());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -232,7 +235,7 @@ public class TestResourcePoolService {
|
||||||
return testResourcePoolMapper.selectByPrimaryKey(resourcePoolId);
|
return testResourcePoolMapper.selectByPrimaryKey(resourcePoolId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<TestResourcePool> listValidResourcePools() {
|
public List<TestResourcePoolDTO> listValidResourcePools() {
|
||||||
QueryResourcePoolRequest request = new QueryResourcePoolRequest();
|
QueryResourcePoolRequest request = new QueryResourcePoolRequest();
|
||||||
List<TestResourcePoolDTO> testResourcePools = listResourcePools(request);
|
List<TestResourcePoolDTO> testResourcePools = listResourcePools(request);
|
||||||
// 重新校验 pool
|
// 重新校验 pool
|
||||||
|
@ -249,16 +252,15 @@ public class TestResourcePoolService {
|
||||||
testResourcePoolMapper.updateByPrimaryKeySelective(pool);
|
testResourcePoolMapper.updateByPrimaryKeySelective(pool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TestResourcePoolExample example = new TestResourcePoolExample();
|
request.setStatus(VALID.name());
|
||||||
example.createCriteria().andStatusEqualTo(ResourceStatusEnum.VALID.name());
|
return listResourcePools(request);
|
||||||
return testResourcePoolMapper.selectByExample(example);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<TestResourcePool> listValidQuotaResourcePools() {
|
public List<TestResourcePoolDTO> listValidQuotaResourcePools() {
|
||||||
return filterQuota(listValidResourcePools());
|
return filterQuota(listValidResourcePools());
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<TestResourcePool> filterQuota(List<TestResourcePool> list) {
|
private List<TestResourcePoolDTO> filterQuota(List<TestResourcePoolDTO> list) {
|
||||||
QuotaService quotaService = CommonBeanFactory.getBean(QuotaService.class);
|
QuotaService quotaService = CommonBeanFactory.getBean(QuotaService.class);
|
||||||
if (quotaService != null) {
|
if (quotaService != null) {
|
||||||
Set<String> pools = quotaService.getQuotaResourcePools();
|
Set<String> pools = quotaService.getQuotaResourcePools();
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
package io.metersphere.track.issue;
|
|
||||||
|
|
||||||
import io.metersphere.commons.utils.EncryptUtils;
|
|
||||||
|
|
||||||
public class ZentaoUtils {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param code Zentao 应用代号
|
|
||||||
* @param key Zentao 密钥
|
|
||||||
* @return token
|
|
||||||
*/
|
|
||||||
public static String getToken(String code, String key, String time) {
|
|
||||||
return (String) EncryptUtils.md5Encrypt(code + key + time);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param url Zentao url
|
|
||||||
* @param code Zentao 应用代号
|
|
||||||
* @param key Zentao 密钥
|
|
||||||
* @return url
|
|
||||||
*/
|
|
||||||
public static String getUrl(String url, String code, String key) {
|
|
||||||
String time = String.valueOf(System.currentTimeMillis());;
|
|
||||||
return url + "api.php?" + "code=" + code + "&time=" + time + "&token=" + getToken(code, key, time);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -116,7 +116,7 @@ public class IssuesService {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@ public class TestCaseCommentService {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,7 +127,7 @@ public class TestCaseReviewService {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -187,7 +187,6 @@ public class TestCaseReviewService {
|
||||||
testCaseReviewMapper.updateByPrimaryKeySelective(testCaseReview);
|
testCaseReviewMapper.updateByPrimaryKeySelective(testCaseReview);
|
||||||
List<String> userIds = new ArrayList<>();
|
List<String> userIds = new ArrayList<>();
|
||||||
userIds.addAll(testCaseReview.getUserIds());
|
userIds.addAll(testCaseReview.getUserIds());
|
||||||
if (StringUtils.equals(TestPlanStatus.Completed.name(), testCaseReview.getStatus())) {
|
|
||||||
try {
|
try {
|
||||||
String context = getReviewContext(testCaseReview, NoticeConstants.UPDATE);
|
String context = getReviewContext(testCaseReview, NoticeConstants.UPDATE);
|
||||||
MessageSettingDetail messageSettingDetail = noticeService.searchMessage();
|
MessageSettingDetail messageSettingDetail = noticeService.searchMessage();
|
||||||
|
@ -201,13 +200,12 @@ public class TestCaseReviewService {
|
||||||
wxChatTaskService.sendWechatRobot(r, userIds, context, NoticeConstants.UPDATE);
|
wxChatTaskService.sendWechatRobot(r, userIds, context, NoticeConstants.UPDATE);
|
||||||
break;
|
break;
|
||||||
case NoticeConstants.EMAIL:
|
case NoticeConstants.EMAIL:
|
||||||
mailService.sendReviewerNotice(r, userIds, testCaseReview, NoticeConstants.UPDATE);
|
mailService.sendEndNotice(r, userIds, testCaseReview, NoticeConstants.UPDATE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -318,7 +316,7 @@ public class TestCaseReviewService {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -468,7 +466,7 @@ public class TestCaseReviewService {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -585,7 +583,15 @@ public class TestCaseReviewService {
|
||||||
if (StringUtils.equals(NoticeConstants.CREATE, type)) {
|
if (StringUtils.equals(NoticeConstants.CREATE, type)) {
|
||||||
context = "测试评审任务通知:" + user.getName() + "发起的" + "'" + reviewRequest.getName() + "'" + "待开始,计划开始时间是" + start + "计划结束时间为" + end + "请跟进";
|
context = "测试评审任务通知:" + user.getName() + "发起的" + "'" + reviewRequest.getName() + "'" + "待开始,计划开始时间是" + start + "计划结束时间为" + end + "请跟进";
|
||||||
} else if (StringUtils.equals(NoticeConstants.UPDATE, type)) {
|
} else if (StringUtils.equals(NoticeConstants.UPDATE, type)) {
|
||||||
context = "测试评审任务通知:" + user.getName() + "发起的" + "'" + reviewRequest.getName() + "'" + "已完成,计划开始时间是" + start + "计划结束时间为" + end + "已完成";
|
String status = "";
|
||||||
|
if (StringUtils.equals(TestPlanStatus.Underway.name(), reviewRequest.getStatus())) {
|
||||||
|
status = "进行中";
|
||||||
|
} else if (StringUtils.equals(TestPlanStatus.Prepare.name(), reviewRequest.getStatus())) {
|
||||||
|
status = "未开始";
|
||||||
|
} else if (StringUtils.equals(TestPlanStatus.Completed.name(), reviewRequest.getStatus())) {
|
||||||
|
status = "已完成";
|
||||||
|
}
|
||||||
|
context = "测试评审任务通知:" + user.getName() + "发起的" + "'" + reviewRequest.getName() + "'" + "计划开始时间是" + start + "计划结束时间为" + end + status;
|
||||||
} else if (StringUtils.equals(NoticeConstants.DELETE, type)) {
|
} else if (StringUtils.equals(NoticeConstants.DELETE, type)) {
|
||||||
context = "测试评审任务通知:" + user.getName() + "发起的" + "'" + reviewRequest.getName() + "'" + "计划开始时间是" + start + "计划结束时间为" + end + "已删除";
|
context = "测试评审任务通知:" + user.getName() + "发起的" + "'" + reviewRequest.getName() + "'" + "计划开始时间是" + start + "计划结束时间为" + end + "已删除";
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,7 @@ public class TestPlanService {
|
||||||
@Resource
|
@Resource
|
||||||
UserMapper userMapper;
|
UserMapper userMapper;
|
||||||
|
|
||||||
public void addTestPlan(AddTestPlanRequest testPlan) {
|
public synchronized void addTestPlan(AddTestPlanRequest testPlan) {
|
||||||
if (getTestPlanByName(testPlan.getName()).size() > 0) {
|
if (getTestPlanByName(testPlan.getName()).size() > 0) {
|
||||||
MSException.throwException(Translator.get("plan_name_already_exists"));
|
MSException.throwException(Translator.get("plan_name_already_exists"));
|
||||||
}
|
}
|
||||||
|
@ -137,11 +137,11 @@ public class TestPlanService {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized List<TestPlan> getTestPlanByName(String name) {
|
public List<TestPlan> getTestPlanByName(String name) {
|
||||||
TestPlanExample example = new TestPlanExample();
|
TestPlanExample example = new TestPlanExample();
|
||||||
example.createCriteria().andWorkspaceIdEqualTo(SessionUtils.getCurrentWorkspaceId())
|
example.createCriteria().andWorkspaceIdEqualTo(SessionUtils.getCurrentWorkspaceId())
|
||||||
.andNameEqualTo(name);
|
.andNameEqualTo(name);
|
||||||
|
@ -159,13 +159,16 @@ public class TestPlanService {
|
||||||
//进行中状态,写入实际开始时间
|
//进行中状态,写入实际开始时间
|
||||||
if (TestPlanStatus.Underway.name().equals(testPlan.getStatus())) {
|
if (TestPlanStatus.Underway.name().equals(testPlan.getStatus())) {
|
||||||
testPlan.setActualStartTime(System.currentTimeMillis());
|
testPlan.setActualStartTime(System.currentTimeMillis());
|
||||||
|
|
||||||
} else if (TestPlanStatus.Completed.name().equals(testPlan.getStatus())) {
|
} else if (TestPlanStatus.Completed.name().equals(testPlan.getStatus())) {
|
||||||
|
//已完成,写入实际完成时间
|
||||||
|
testPlan.setActualEndTime(System.currentTimeMillis());
|
||||||
|
|
||||||
|
}
|
||||||
List<String> userIds = new ArrayList<>();
|
List<String> userIds = new ArrayList<>();
|
||||||
userIds.add(testPlan.getPrincipal());
|
userIds.add(testPlan.getPrincipal());
|
||||||
AddTestPlanRequest testPlans = new AddTestPlanRequest();
|
AddTestPlanRequest testPlans = new AddTestPlanRequest();
|
||||||
//已完成,写入实际完成时间
|
int i = testPlanMapper.updateByPrimaryKeySelective(testPlan);
|
||||||
testPlan.setActualEndTime(System.currentTimeMillis());
|
if (!StringUtils.isBlank(testPlan.getStatus())) {
|
||||||
try {
|
try {
|
||||||
BeanUtils.copyBean(testPlans, getTestPlan(testPlan.getId()));
|
BeanUtils.copyBean(testPlans, getTestPlan(testPlan.getId()));
|
||||||
String context = getTestPlanContext(testPlans, NoticeConstants.UPDATE);
|
String context = getTestPlanContext(testPlans, NoticeConstants.UPDATE);
|
||||||
|
@ -180,16 +183,15 @@ public class TestPlanService {
|
||||||
wxChatTaskService.sendWechatRobot(r, userIds, context, NoticeConstants.UPDATE);
|
wxChatTaskService.sendWechatRobot(r, userIds, context, NoticeConstants.UPDATE);
|
||||||
break;
|
break;
|
||||||
case NoticeConstants.EMAIL:
|
case NoticeConstants.EMAIL:
|
||||||
mailService.sendTestPlanStartNotice(r, userIds, testPlans, NoticeConstants.UPDATE);
|
mailService.sendTestPlanEndNotice(r, userIds, testPlans, NoticeConstants.UPDATE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return i;
|
||||||
return testPlanMapper.updateByPrimaryKeySelective(testPlan);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void editTestPlanProject(TestPlanDTO testPlan) {
|
private void editTestPlanProject(TestPlanDTO testPlan) {
|
||||||
|
@ -270,7 +272,7 @@ public class TestPlanService {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
@ -511,7 +513,7 @@ public class TestPlanService {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,11 +559,19 @@ public class TestPlanService {
|
||||||
}
|
}
|
||||||
String context = "";
|
String context = "";
|
||||||
if (StringUtils.equals(NoticeConstants.CREATE, type)) {
|
if (StringUtils.equals(NoticeConstants.CREATE, type)) {
|
||||||
context = "测试计划任务通知:" + user.getName() + "创建的" + "'" + testPlan.getName() + "'" + "待开始,计划开始时间是" + start + "计划结束时间为" + end + "请跟进";
|
context = "测试计划任务通知:" + user.getName() + "创建的" + "'" + testPlan.getName() + "'" + "待开始,计划开始时间是:" + "'" + start + "'" + ";" + "计划结束时间是:" + "'" + end + "'" + " " + "请跟进";
|
||||||
} else if (StringUtils.equals(NoticeConstants.UPDATE, type)) {
|
} else if (StringUtils.equals(NoticeConstants.UPDATE, type)) {
|
||||||
context = "测试计划任务通知:" + user.getName() + "创建的" + "'" + testPlan.getName() + "'" + "已完成,计划开始时间是" + start + "计划结束时间为" + end + "已完成";
|
String status = "";
|
||||||
|
if (StringUtils.equals(TestPlanStatus.Underway.name(), testPlan.getStatus())) {
|
||||||
|
status = "进行中";
|
||||||
|
} else if (StringUtils.equals(TestPlanStatus.Prepare.name(), testPlan.getStatus())) {
|
||||||
|
status = "未开始";
|
||||||
|
} else if (StringUtils.equals(TestPlanStatus.Completed.name(), testPlan.getStatus())) {
|
||||||
|
status = "已完成";
|
||||||
|
}
|
||||||
|
context = "测试计划任务通知:" + user.getName() + "创建的" + "'" + testPlan.getName() + "'" + "计划开始时间是:" + "'" + start + "'" + ";" + "计划结束时间是:" + "'" + end + "'" + " " + status;
|
||||||
} else if (StringUtils.equals(NoticeConstants.DELETE, type)) {
|
} else if (StringUtils.equals(NoticeConstants.DELETE, type)) {
|
||||||
context = "测试计划任务通知:" + user.getName() + "创建的" + "'" + testPlan.getName() + "'" + "计划开始时间是" + start + "计划结束时间为" + end + "已删除";
|
context = "测试计划任务通知:" + user.getName() + "创建的" + "'" + testPlan.getName() + "'" + "计划开始时间是:" + "'" + start + "'" + ";" + "计划结束时间是:" + "'" + end + "'" + " " + "已删除";
|
||||||
}
|
}
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@ public class ReportWebSocket {
|
||||||
}
|
}
|
||||||
Thread.sleep(20 * 1000L);
|
Thread.sleep(20 * 1000L);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -283,17 +283,20 @@ public class XmindCaseParser {
|
||||||
|
|
||||||
// 测试步骤处理
|
// 测试步骤处理
|
||||||
List<Attached> steps = new LinkedList<>();
|
List<Attached> steps = new LinkedList<>();
|
||||||
|
StringBuilder rc = new StringBuilder();
|
||||||
if (attacheds != null && !attacheds.isEmpty()) {
|
if (attacheds != null && !attacheds.isEmpty()) {
|
||||||
attacheds.forEach(item -> {
|
attacheds.forEach(item -> {
|
||||||
if (isAvailable(item.getTitle(), PC_REGEX)) {
|
if (isAvailable(item.getTitle(), PC_REGEX)) {
|
||||||
testCase.setPrerequisite(replace(item.getTitle(), PC_REGEX));
|
testCase.setPrerequisite(replace(item.getTitle(), PC_REGEX));
|
||||||
} else if (isAvailable(item.getTitle(), RC_REGEX)) {
|
} else if (isAvailable(item.getTitle(), RC_REGEX)) {
|
||||||
testCase.setRemark(replace(item.getTitle(), RC_REGEX));
|
rc.append(replace(item.getTitle(), RC_REGEX));
|
||||||
|
rc.append("\n");
|
||||||
} else {
|
} else {
|
||||||
steps.add(item);
|
steps.add(item);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
testCase.setRemark(rc.toString());
|
||||||
testCase.setSteps(this.getSteps(steps));
|
testCase.setSteps(this.getSteps(steps));
|
||||||
testCases.add(testCase);
|
testCases.add(testCase);
|
||||||
// 校验合规性
|
// 校验合规性
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div>
|
<div>
|
||||||
<p style="text-align: left"> ${maintainer} 维护的<br/>
|
<p style="text-align: left"> ${maintainer}为 <br/>
|
||||||
${testCaseName}<br/>
|
${testCaseName}<br/>
|
||||||
添加评论:${description}<br/>
|
添加评论:${description}<br/>
|
||||||
点击下面链接进入用例评审页面</p>
|
点击下面链接进入用例评审页面</p>
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
<body>
|
<body>
|
||||||
<div>
|
<div>
|
||||||
<p style="text-align: left">${creator} 发起的:<br>
|
<p style="text-align: left">${creator} 发起的:<br>
|
||||||
${reviewName}已完成<br>
|
${reviewName}<br>
|
||||||
计划开始时间是:${start}<br>
|
计划开始时间是:${start}<br>
|
||||||
计划结束时间为:${end}<br>
|
计划结束时间为:${end}<br>
|
||||||
已完成<br>
|
${status}<br>
|
||||||
点击下面链接进入用例评审页面</p>
|
点击下面链接进入用例评审页面</p>
|
||||||
<a href="${url}/#/track/review/view">${url}/#/track/review/view</a>
|
<a href="${url}/#/track/review/view">${url}/#/track/review/view</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
<body>
|
<body>
|
||||||
<div>
|
<div>
|
||||||
<p style="text-align: left">${creator} 创建的:<br>
|
<p style="text-align: left">${creator} 创建的:<br>
|
||||||
${testPlanName}已完成<br>
|
${testPlanName}<br>
|
||||||
计划开始时间是:${start}<br>
|
计划开始时间是:${start}<br>
|
||||||
计划结束时间为:${end}<br>
|
计划结束时间为:${end}<br>
|
||||||
已完成!<br>
|
${status}!<br>
|
||||||
点击下面链接进入测试计划页面</p>
|
点击下面链接进入测试计划页面</p>
|
||||||
<a href="${url}/#/track/plan/view/${id}">${url}/#/track/plan/view</a>
|
<a href="${url}/#/track/plan/view/${id}">${url}/#/track/plan/view</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>metersphere-server</artifactId>
|
<artifactId>metersphere-server</artifactId>
|
||||||
<groupId>io.metersphere</groupId>
|
<groupId>io.metersphere</groupId>
|
||||||
<version>1.4</version>
|
<version>1.5</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
|
@ -7,8 +7,7 @@
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row id="header-top" type="flex" justify="space-between" align="middle">
|
<el-row id="header-top" type="flex" justify="space-between" align="middle">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<img v-if="logoId" :src="'/display/file/' + logoId" style="width: 156px;height: 37px;" alt="">
|
<img :src="'/display/file/logo'" style="width: 156px;height: 37px;" alt="">
|
||||||
<a v-else class="logo"/>
|
|
||||||
<ms-top-menus/>
|
<ms-top-menus/>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
|
|
|
@ -46,10 +46,9 @@ import MsScenarioResults from "./components/ScenarioResults";
|
||||||
import MsContainer from "@/business/components/common/components/MsContainer";
|
import MsContainer from "@/business/components/common/components/MsContainer";
|
||||||
import MsMainContainer from "@/business/components/common/components/MsMainContainer";
|
import MsMainContainer from "@/business/components/common/components/MsMainContainer";
|
||||||
import MsApiReportExport from "./ApiReportExport";
|
import MsApiReportExport from "./ApiReportExport";
|
||||||
import {exportPdf} from "@/common/js/utils";
|
|
||||||
import html2canvas from "html2canvas";
|
|
||||||
import MsApiReportViewHeader from "./ApiReportViewHeader";
|
import MsApiReportViewHeader from "./ApiReportViewHeader";
|
||||||
import {RequestFactory} from "../test/model/ScenarioModel";
|
import {RequestFactory} from "../test/model/ScenarioModel";
|
||||||
|
import {windowPrint} from "../../../../common/js/utils";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MsApiReportViewDetail",
|
name: "MsApiReportViewDetail",
|
||||||
|
@ -154,23 +153,16 @@ export default {
|
||||||
this.scenarioName = requestResult.scenarioName;
|
this.scenarioName = requestResult.scenarioName;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleExport(name) {
|
handleExport() {
|
||||||
this.loading = true;
|
|
||||||
this.reportExportVisible = true;
|
this.reportExportVisible = true;
|
||||||
let reset = this.exportReportReset;
|
let reset = this.exportReportReset;
|
||||||
|
this.$nextTick(() => {
|
||||||
this.$nextTick(function () {
|
windowPrint('apiTestReport', 0.57);
|
||||||
html2canvas(document.getElementById('apiTestReport'), {
|
|
||||||
// scale: 2,
|
|
||||||
}).then(function (canvas) {
|
|
||||||
exportPdf(name, [canvas]);
|
|
||||||
reset();
|
reset();
|
||||||
});
|
});
|
||||||
});
|
|
||||||
},
|
},
|
||||||
exportReportReset() {
|
exportReportReset() {
|
||||||
this.reportExportVisible = false;
|
this.$router.go(0);
|
||||||
this.loading = false;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,7 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
search() {
|
search() {
|
||||||
this.condition.excludeId = this.excludeId;
|
this.condition.excludeId = this.excludeId;
|
||||||
|
this.condition.projectId = this.projectId;
|
||||||
let url = "/api/list/" + this.currentPage + "/" + this.pageSize;
|
let url = "/api/list/" + this.currentPage + "/" + this.pageSize;
|
||||||
this.result = this.$post(url, this.condition, response => {
|
this.result = this.$post(url, this.condition, response => {
|
||||||
let data = response.data;
|
let data = response.data;
|
||||||
|
|
|
@ -17,10 +17,9 @@
|
||||||
:scenario="scenario"
|
:scenario="scenario"
|
||||||
:extract="extract"
|
:extract="extract"
|
||||||
type="body"
|
type="body"
|
||||||
:description="$t('api_test.request.parameters_desc')"
|
|
||||||
v-if="body.isKV()"/>
|
v-if="body.isKV()"/>
|
||||||
<div class="body-raw" v-if="body.type == 'Raw'">
|
<div class="body-raw" v-if="body.type == 'Raw'">
|
||||||
<ms-code-edit :mode="body.format" :read-only="isReadOnly" :data.sync="body.raw" :modes="modes" ref="codeEdit"/>
|
<ms-code-edit :mode="body.format" :enable-format="false" :read-only="isReadOnly" :data.sync="body.raw" :modes="modes" ref="codeEdit"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="$t('api_test.request.sql.pool_max')" prop="poolMax">
|
<el-form-item :label="$t('api_test.request.sql.pool_max')" prop="poolMax">
|
||||||
<el-input-number size="small" :disabled="isReadOnly" v-model="currentConfig.poolMax" :placeholder="$t('commons.please_select')" :max="1000*10000000" :min="0"/>
|
<el-input-number size="small" :disabled="isReadOnly" v-model="currentConfig.poolMax" :placeholder="$t('commons.please_select')" :max="100" :min="0"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -157,7 +157,7 @@ export class Test extends BaseConfig {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
super();
|
super();
|
||||||
this.type = "MS API CONFIG";
|
this.type = "MS API CONFIG";
|
||||||
this.version = '1.4.0';
|
this.version = '1.5.0';
|
||||||
this.id = uuid();
|
this.id = uuid();
|
||||||
this.name = undefined;
|
this.name = undefined;
|
||||||
this.projectId = undefined;
|
this.projectId = undefined;
|
||||||
|
@ -609,8 +609,8 @@ export class DatabaseConfig extends BaseConfig {
|
||||||
super();
|
super();
|
||||||
this.id = undefined;
|
this.id = undefined;
|
||||||
this.name = undefined;
|
this.name = undefined;
|
||||||
this.poolMax = undefined;
|
this.poolMax = 1;
|
||||||
this.timeout = undefined;
|
this.timeout = 100000;
|
||||||
this.driver = undefined;
|
this.driver = undefined;
|
||||||
this.dbUrl = undefined;
|
this.dbUrl = undefined;
|
||||||
this.username = undefined;
|
this.username = undefined;
|
||||||
|
|
|
@ -28,6 +28,12 @@
|
||||||
init: {
|
init: {
|
||||||
type: Function
|
type: Function
|
||||||
},
|
},
|
||||||
|
enableFormat: {
|
||||||
|
type: Boolean,
|
||||||
|
default() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
readOnly: {
|
readOnly: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default() {
|
default() {
|
||||||
|
@ -74,6 +80,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
format() {
|
format() {
|
||||||
|
if (this.enableFormat) {
|
||||||
switch (this.mode) {
|
switch (this.mode) {
|
||||||
case 'json':
|
case 'json':
|
||||||
this.formatData = formatJson(this.data);
|
this.formatData = formatJson(this.data);
|
||||||
|
@ -89,6 +96,9 @@
|
||||||
this.formatData = this.data;
|
this.formatData = this.data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
this.formatData = this.data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,11 @@
|
||||||
<br/>
|
<br/>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
<el-row class="tip" v-if="withTip">
|
||||||
|
<span>
|
||||||
|
<slot class="tip"></slot>
|
||||||
|
</span>
|
||||||
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="15">
|
<el-col :span="15">
|
||||||
<el-input v-model="value" :placeholder="$t('commons.input_content')"/>
|
<el-input v-model="value" :placeholder="$t('commons.input_content')"/>
|
||||||
|
@ -41,6 +46,12 @@
|
||||||
default() {
|
default() {
|
||||||
return this.$t('commons.title')
|
return this.$t('commons.title')
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
withTip: {
|
||||||
|
type: Boolean,
|
||||||
|
default() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -80,5 +91,9 @@
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tip {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -73,7 +73,9 @@
|
||||||
this.$emit('scheduleChange');
|
this.$emit('scheduleChange');
|
||||||
},
|
},
|
||||||
flashResultList() {
|
flashResultList() {
|
||||||
|
if (this.$refs.crontabResult) {
|
||||||
this.$refs.crontabResult.expressionChange();
|
this.$refs.crontabResult.expressionChange();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
cancelRefresh() {
|
cancelRefresh() {
|
||||||
if (this.refreshScheduler) {
|
if (this.refreshScheduler) {
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane :label="$t('schedule.task_notification')" name="second">
|
<el-tab-pane :label="$t('schedule.task_notification')" name="second">
|
||||||
<schedule-task-notification :test-id="testId" :schedule-receiver-options="scheduleReceiverOptions"></schedule-task-notification>
|
<schedule-task-notification :is-tester-permission="isTesterPermission" :test-id="testId" :schedule-receiver-options="scheduleReceiverOptions"></schedule-task-notification>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</div>
|
</div>
|
||||||
|
@ -46,6 +46,7 @@ import CrontabResult from "../cron/CrontabResult";
|
||||||
import {cronValidate} from "@/common/js/cron";
|
import {cronValidate} from "@/common/js/cron";
|
||||||
import {listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
import {listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
||||||
import ScheduleTaskNotification from "../../settings/organization/components/ScheduleTaskNotification";
|
import ScheduleTaskNotification from "../../settings/organization/components/ScheduleTaskNotification";
|
||||||
|
import {checkoutTestManagerOrTestUser} from "../../../../common/js/utils";
|
||||||
function defaultCustomValidate() {
|
function defaultCustomValidate() {
|
||||||
return {pass: true};
|
return {pass: true};
|
||||||
}
|
}
|
||||||
|
@ -113,10 +114,13 @@ export default {
|
||||||
name: '',
|
name: '',
|
||||||
organizationId: this.currentUser().lastOrganizationId
|
organizationId: this.currentUser().lastOrganizationId
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (this.isTesterPermission) {
|
||||||
this.result = this.$post('user/org/member/list/all', param, response => {
|
this.result = this.$post('user/org/member/list/all', param, response => {
|
||||||
this.scheduleReceiverOptions = response.data
|
this.scheduleReceiverOptions = response.data
|
||||||
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
/* handleClick() {
|
/* handleClick() {
|
||||||
if (this.activeName === "second") {
|
if (this.activeName === "second") {
|
||||||
|
@ -188,6 +192,11 @@ export default {
|
||||||
let time1 = new Date(resultList[0]);
|
let time1 = new Date(resultList[0]);
|
||||||
let time2 = new Date(resultList[1]);
|
let time2 = new Date(resultList[1]);
|
||||||
return time2 - time1;
|
return time2 - time1;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isTesterPermission() {
|
||||||
|
return checkoutTestManagerOrTestUser();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="report-right">
|
<div class="report-right">
|
||||||
<div class="test">
|
|
||||||
<img class="logo" src="@/assets/logo-MeterSphere.png">
|
<img class="logo" src="@/assets/logo-MeterSphere.png">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -271,12 +271,14 @@ export default {
|
||||||
let reset = this.exportReportReset;
|
let reset = this.exportReportReset;
|
||||||
|
|
||||||
this.$nextTick(function () {
|
this.$nextTick(function () {
|
||||||
|
setTimeout(() => {
|
||||||
html2canvas(document.getElementById('performanceReportExport'), {
|
html2canvas(document.getElementById('performanceReportExport'), {
|
||||||
// scale: 2
|
scale: 2
|
||||||
}).then(function (canvas) {
|
}).then(function (canvas) {
|
||||||
exportPdf(name, [canvas]);
|
exportPdf(name, [canvas]);
|
||||||
reset();
|
reset();
|
||||||
});
|
});
|
||||||
|
}, 1000);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
exportReportReset() {
|
exportReportReset() {
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
:placeholder="$t('load_test.input_thread_num')"
|
:placeholder="$t('load_test.input_thread_num')"
|
||||||
v-model="threadGroup.threadNumber"
|
v-model="threadGroup.threadNumber"
|
||||||
@change="calculateChart(threadGroup)"
|
@change="calculateChart(threadGroup)"
|
||||||
:min="1"
|
:min="resourcePoolResourceLength"
|
||||||
size="mini"/>
|
size="mini"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<br>
|
<br>
|
||||||
|
@ -141,6 +141,7 @@ export default {
|
||||||
activeNames: ["0"],
|
activeNames: ["0"],
|
||||||
threadGroups: [],
|
threadGroups: [],
|
||||||
serializeThreadgroups: false,
|
serializeThreadgroups: false,
|
||||||
|
resourcePoolResourceLength: 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -368,6 +369,11 @@ export default {
|
||||||
if (handler.rampUpTime < handler.step) {
|
if (handler.rampUpTime < handler.step) {
|
||||||
handler.step = handler.rampUpTime;
|
handler.step = handler.rampUpTime;
|
||||||
}
|
}
|
||||||
|
// 线程数不能小于资源池节点的数量
|
||||||
|
let resourcePool = this.resourcePools.filter(v => v.id === this.resourcePool)[0];
|
||||||
|
if (resourcePool) {
|
||||||
|
this.resourcePoolResourceLength = resourcePool.resources.length;
|
||||||
|
}
|
||||||
handler.options = {
|
handler.options = {
|
||||||
xAxis: {
|
xAxis: {
|
||||||
type: 'category',
|
type: 'category',
|
||||||
|
|
|
@ -204,6 +204,7 @@ export default {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
submit(formName) {
|
submit(formName) {
|
||||||
this.$refs[formName].validate((valid) => {
|
this.$refs[formName].validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
|
@ -282,7 +283,18 @@ export default {
|
||||||
},
|
},
|
||||||
openEnvironmentConfig(project) {
|
openEnvironmentConfig(project) {
|
||||||
this.$refs.environmentConfig.open(project.id);
|
this.$refs.environmentConfig.open(project.id);
|
||||||
|
},
|
||||||
|
handleEvent(event) {
|
||||||
|
if (event.keyCode === 13) {
|
||||||
|
this.submit('form')
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
document.addEventListener('keydown', this.handleEvent)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
document.removeEventListener('keydown', this.handleEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<div>
|
<div>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="10">
|
<el-col :span="10">
|
||||||
<el-button icon="el-icon-circle-plus-outline" plain size="mini" @click="handleAddTaskModel('scheduleTask')">
|
<el-button :disabled="!isTesterPermission" icon="el-icon-circle-plus-outline" plain size="mini" @click="handleAddTaskModel('scheduleTask')">
|
||||||
{{ $t('organization.message.create_new_notification') }}
|
{{ $t('organization.message.create_new_notification') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
@ -69,12 +69,14 @@
|
||||||
type="primary"
|
type="primary"
|
||||||
size="mini"
|
size="mini"
|
||||||
v-show="scope.row.isSet"
|
v-show="scope.row.isSet"
|
||||||
|
:disabled="!isTesterPermission"
|
||||||
@click="handleAddTask(scope.$index,scope.row)"
|
@click="handleAddTask(scope.$index,scope.row)"
|
||||||
>{{ $t('commons.add') }}
|
>{{ $t('commons.add') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
size="mini"
|
size="mini"
|
||||||
v-show="scope.row.isSet"
|
v-show="scope.row.isSet"
|
||||||
|
:disabled="!isTesterPermission"
|
||||||
@click.native.prevent="removeRowTask(scope.$index,form.scheduleTask)"
|
@click.native.prevent="removeRowTask(scope.$index,form.scheduleTask)"
|
||||||
>{{ $t('commons.cancel') }}
|
>{{ $t('commons.cancel') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
@ -82,6 +84,7 @@
|
||||||
type="primary"
|
type="primary"
|
||||||
size="mini"
|
size="mini"
|
||||||
v-show="!scope.row.isSet"
|
v-show="!scope.row.isSet"
|
||||||
|
:disabled="!isTesterPermission"
|
||||||
@click="handleEditTask(scope.$index,scope.row)"
|
@click="handleEditTask(scope.$index,scope.row)"
|
||||||
>{{ $t('commons.edit') }}</el-button>
|
>{{ $t('commons.edit') }}</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
|
@ -89,6 +92,7 @@
|
||||||
icon="el-icon-delete"
|
icon="el-icon-delete"
|
||||||
size="mini"
|
size="mini"
|
||||||
v-show="!scope.row.isSet"
|
v-show="!scope.row.isSet"
|
||||||
|
:disabled="!isTesterPermission"
|
||||||
@click.native.prevent="deleteRowTask(scope.$index,scope.row)"
|
@click.native.prevent="deleteRowTask(scope.$index,scope.row)"
|
||||||
></el-button>
|
></el-button>
|
||||||
</template>
|
</template>
|
||||||
|
@ -106,6 +110,10 @@ export default {
|
||||||
props: {
|
props: {
|
||||||
testId:String,
|
testId:String,
|
||||||
scheduleReceiverOptions:Array,
|
scheduleReceiverOptions:Array,
|
||||||
|
isTesterPermission: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -120,7 +128,6 @@ export default {
|
||||||
identification: "",
|
identification: "",
|
||||||
isReadOnly: false,
|
isReadOnly: false,
|
||||||
testId:this.testId,
|
testId:this.testId,
|
||||||
|
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
scheduleEventOptions: [
|
scheduleEventOptions: [
|
||||||
|
@ -193,7 +200,6 @@ export default {
|
||||||
},
|
},
|
||||||
addTask(data) {
|
addTask(data) {
|
||||||
let list = [];
|
let list = [];
|
||||||
data.isSet = false;
|
|
||||||
list.push(data);
|
list.push(data);
|
||||||
let param = {};
|
let param = {};
|
||||||
param.messageDetail = list;
|
param.messageDetail = list;
|
||||||
|
|
|
@ -86,6 +86,7 @@
|
||||||
import MsDialogFooter from "../../common/components/MsDialogFooter";
|
import MsDialogFooter from "../../common/components/MsDialogFooter";
|
||||||
import {getCurrentUser, listenGoBack, removeGoBackListener} from "../../../../common/js/utils";
|
import {getCurrentUser, listenGoBack, removeGoBackListener} from "../../../../common/js/utils";
|
||||||
import MsTableOperatorButton from "../../common/components/MsTableOperatorButton";
|
import MsTableOperatorButton from "../../common/components/MsTableOperatorButton";
|
||||||
|
import {PHONE_REGEX} from "@/common/js/regex";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MsPersonSetting",
|
name: "MsPersonSetting",
|
||||||
|
@ -115,7 +116,7 @@
|
||||||
phone: [
|
phone: [
|
||||||
{
|
{
|
||||||
required: false,
|
required: false,
|
||||||
pattern: '^1(3|4|5|7|8)\\d{9}$',
|
pattern: PHONE_REGEX,
|
||||||
message: this.$t('member.mobile_number_format_is_incorrect'),
|
message: this.$t('member.mobile_number_format_is_incorrect'),
|
||||||
trigger: 'blur'
|
trigger: 'blur'
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
<el-checkbox v-model="formInline.TLS" :label="$t('system_parameter_setting.TLS')"></el-checkbox>
|
<el-checkbox v-model="formInline.TLS" :label="$t('system_parameter_setting.TLS')"></el-checkbox>
|
||||||
</div>
|
</div>
|
||||||
<div style="border: 0px;margin-bottom: 20px">
|
<div style="border: 0px;margin-bottom: 20px">
|
||||||
<el-checkbox v-model="formInline.SMTP" :label="$t('system_parameter_setting.SMTP')"></el-checkbox>
|
<el-checkbox v-model="formInline.ANON" :label="$t('system_parameter_setting.SMTP')"></el-checkbox>
|
||||||
</div>
|
</div>
|
||||||
<template v-slot:footer>
|
<template v-slot:footer>
|
||||||
</template>
|
</template>
|
||||||
|
@ -120,7 +120,7 @@ export default {
|
||||||
this.$set(this.formInline, "password", response.data[3].paramValue);
|
this.$set(this.formInline, "password", response.data[3].paramValue);
|
||||||
this.$set(this.formInline, "SSL", JSON.parse(response.data[4].paramValue));
|
this.$set(this.formInline, "SSL", JSON.parse(response.data[4].paramValue));
|
||||||
this.$set(this.formInline, "TLS", JSON.parse(response.data[5].paramValue));
|
this.$set(this.formInline, "TLS", JSON.parse(response.data[5].paramValue));
|
||||||
this.$set(this.formInline, "SMTP", JSON.parse(response.data[6].paramValue));
|
this.$set(this.formInline, "ANON", JSON.parse(response.data[6].paramValue));
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs.formInline.clearValidate();
|
this.$refs.formInline.clearValidate();
|
||||||
})
|
})
|
||||||
|
@ -143,7 +143,7 @@ export default {
|
||||||
"smtp.password": this.formInline.password,
|
"smtp.password": this.formInline.password,
|
||||||
"smtp.ssl": this.formInline.SSL,
|
"smtp.ssl": this.formInline.SSL,
|
||||||
"smtp.tls": this.formInline.TLS,
|
"smtp.tls": this.formInline.TLS,
|
||||||
"smtp.smtp": this.formInline.SMTP,
|
"smtp.anon": this.formInline.ANON,
|
||||||
};
|
};
|
||||||
this.$refs[formInline].validate((valid) => {
|
this.$refs[formInline].validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
|
@ -173,7 +173,7 @@ export default {
|
||||||
{paramKey: "smtp.password", paramValue: this.formInline.password, type: "password", sort: 4},
|
{paramKey: "smtp.password", paramValue: this.formInline.password, type: "password", sort: 4},
|
||||||
{paramKey: "smtp.ssl", paramValue: this.formInline.SSL, type: "text", sort: 5},
|
{paramKey: "smtp.ssl", paramValue: this.formInline.SSL, type: "text", sort: 5},
|
||||||
{paramKey: "smtp.tls", paramValue: this.formInline.TLS, type: "text", sort: 6},
|
{paramKey: "smtp.tls", paramValue: this.formInline.TLS, type: "text", sort: 6},
|
||||||
{paramKey: "smtp.smtp", paramValue: this.formInline.SMTP, type: "text", sort: 7}
|
{paramKey: "smtp.anon", paramValue: this.formInline.ANON, type: "text", sort: 7}
|
||||||
]
|
]
|
||||||
|
|
||||||
this.$refs[formInline].validate(valid => {
|
this.$refs[formInline].validate(valid => {
|
||||||
|
|
|
@ -338,6 +338,7 @@ import {hasRole, listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
||||||
import MsRolesTag from "../../common/components/MsRolesTag";
|
import MsRolesTag from "../../common/components/MsRolesTag";
|
||||||
import {ROLE_ADMIN} from "@/common/js/constants";
|
import {ROLE_ADMIN} from "@/common/js/constants";
|
||||||
import {getCurrentUser} from "../../../../common/js/utils";
|
import {getCurrentUser} from "../../../../common/js/utils";
|
||||||
|
import {PHONE_REGEX} from "@/common/js/regex";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MsUser",
|
name: "MsUser",
|
||||||
|
@ -380,7 +381,7 @@ export default {
|
||||||
rule: {
|
rule: {
|
||||||
id: [
|
id: [
|
||||||
{required: true, message: this.$t('user.input_id'), trigger: 'blur'},
|
{required: true, message: this.$t('user.input_id'), trigger: 'blur'},
|
||||||
{min: 2, max: 50, message: this.$t('commons.input_limit', [2, 50]), trigger: 'blur'},
|
{min: 1, max: 50, message: this.$t('commons.input_limit', [1, 50]), trigger: 'blur'},
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
pattern: '^[^\u4e00-\u9fa5]+$',
|
pattern: '^[^\u4e00-\u9fa5]+$',
|
||||||
|
@ -401,7 +402,7 @@ export default {
|
||||||
{required: true, message: this.$t('user.input_phone'), trigger: 'blur'},
|
{required: true, message: this.$t('user.input_phone'), trigger: 'blur'},
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
pattern: '^1(3|4|5|7|8)\\d{9}$',
|
pattern: PHONE_REGEX,
|
||||||
message: this.$t('user.mobile_number_format_is_incorrect'),
|
message: this.$t('user.mobile_number_format_is_incorrect'),
|
||||||
trigger: 'blur'
|
trigger: 'blur'
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,8 @@
|
||||||
name: "TestCase",
|
name: "TestCase",
|
||||||
components: {
|
components: {
|
||||||
MsMainContainer,
|
MsMainContainer,
|
||||||
MsAsideContainer, MsContainer, TestCaseMove, TestCaseList, NodeTree, TestCaseEdit, SelectMenu, BatchMove},
|
MsAsideContainer, MsContainer, TestCaseMove, TestCaseList, NodeTree, TestCaseEdit, SelectMenu, BatchMove
|
||||||
|
},
|
||||||
comments: {},
|
comments: {},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -161,6 +161,7 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
result: {},
|
result: {},
|
||||||
|
testCase: {},
|
||||||
dialogFormVisible: false,
|
dialogFormVisible: false,
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
form: {
|
form: {
|
||||||
|
@ -190,9 +191,15 @@ export default {
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$get('test/case/get/' + this.testCaseId, response => {
|
||||||
|
this.testCase = response.data;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
methods: {},
|
||||||
props: {
|
props: {
|
||||||
testCase: {
|
testCaseId: {
|
||||||
type: Object
|
type: String
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -256,9 +256,9 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
import {TokenKey, WORKSPACE_ID} from '../../../../../common/js/constants';
|
import {TokenKey, WORKSPACE_ID} from '@/common/js/constants';
|
||||||
import MsDialogFooter from '../../../common/components/MsDialogFooter'
|
import MsDialogFooter from '../../../common/components/MsDialogFooter'
|
||||||
import {listenGoBack, removeGoBackListener} from "../../../../../common/js/utils";
|
import {listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
||||||
import {LIST_CHANGE, TrackEvent} from "@/business/components/common/head/ListEvent";
|
import {LIST_CHANGE, TrackEvent} from "@/business/components/common/head/ListEvent";
|
||||||
import {Message} from "element-ui";
|
import {Message} from "element-ui";
|
||||||
import TestCaseAttachment from "@/business/components/track/case/components/TestCaseAttachment";
|
import TestCaseAttachment from "@/business/components/track/case/components/TestCaseAttachment";
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
:tip="$t('commons.search_by_name_or_id')"
|
:tip="$t('commons.search_by_name_or_id')"
|
||||||
:create-tip="$t('test_track.case.create')" @create="testCaseCreate">
|
:create-tip="$t('test_track.case.create')" @create="testCaseCreate">
|
||||||
<template v-slot:title>
|
<template v-slot:title>
|
||||||
<node-breadcrumb class="table-title" :nodes="selectParentNodes" @refresh="showAll"/>
|
<node-breadcrumb class="table-title" :nodes="selectParentNodes" @refresh="refresh"/>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:button>
|
<template v-slot:button>
|
||||||
<ms-table-button :is-tester-permission="true" icon="el-icon-download"
|
<ms-table-button :is-tester-permission="true" icon="el-icon-download"
|
||||||
|
@ -35,6 +35,7 @@
|
||||||
@filter-change="filter"
|
@filter-change="filter"
|
||||||
@select-all="handleSelectAll"
|
@select-all="handleSelectAll"
|
||||||
@select="handleSelectionChange"
|
@select="handleSelectionChange"
|
||||||
|
@cell-mouse-enter="showPopover"
|
||||||
row-key="id"
|
row-key="id"
|
||||||
class="test-content adjust-table">
|
class="test-content adjust-table">
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
@ -65,7 +66,7 @@
|
||||||
width="60%"
|
width="60%"
|
||||||
trigger="hover"
|
trigger="hover"
|
||||||
>
|
>
|
||||||
<test-case-detail :test-case="scope.row"/>
|
<test-case-detail v-if="currentCaseId === scope.row.id" :test-case-id="currentCaseId"/>
|
||||||
<span slot="reference">{{ scope.row.name }}</span>
|
<span slot="reference">{{ scope.row.name }}</span>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</template>
|
</template>
|
||||||
|
@ -166,11 +167,11 @@ import MethodTableItem from "../../common/tableItems/planview/MethodTableItem";
|
||||||
import MsTableOperator from "../../../common/components/MsTableOperator";
|
import MsTableOperator from "../../../common/components/MsTableOperator";
|
||||||
import MsTableOperatorButton from "../../../common/components/MsTableOperatorButton";
|
import MsTableOperatorButton from "../../../common/components/MsTableOperatorButton";
|
||||||
import MsTableButton from "../../../common/components/MsTableButton";
|
import MsTableButton from "../../../common/components/MsTableButton";
|
||||||
import {_filter, _sort} from "../../../../../common/js/utils";
|
import {_filter, _sort} from "@/common/js/utils";
|
||||||
import {TEST_CASE_CONFIGS} from "../../../common/components/search/search-components";
|
import {TEST_CASE_CONFIGS} from "../../../common/components/search/search-components";
|
||||||
import ShowMoreBtn from "./ShowMoreBtn";
|
import ShowMoreBtn from "./ShowMoreBtn";
|
||||||
import BatchEdit from "./BatchEdit";
|
import BatchEdit from "./BatchEdit";
|
||||||
import {WORKSPACE_ID} from "../../../../../common/js/constants";
|
import {WORKSPACE_ID} from "@/common/js/constants";
|
||||||
import {LIST_CHANGE, TrackEvent} from "@/business/components/common/head/ListEvent";
|
import {LIST_CHANGE, TrackEvent} from "@/business/components/common/head/ListEvent";
|
||||||
import StatusTableItem from "@/business/components/track/common/tableItems/planview/StatusTableItem";
|
import StatusTableItem from "@/business/components/track/common/tableItems/planview/StatusTableItem";
|
||||||
import TestCaseDetail from "./TestCaseDetail";
|
import TestCaseDetail from "./TestCaseDetail";
|
||||||
|
@ -262,7 +263,8 @@ export default {
|
||||||
{name: this.$t('test_track.case.auto'), id: 'auto'}
|
{name: this.$t('test_track.case.auto'), id: 'auto'}
|
||||||
],
|
],
|
||||||
maintainer: [],
|
maintainer: [],
|
||||||
}
|
},
|
||||||
|
currentCaseId: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
@ -290,6 +292,8 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initTableData() {
|
initTableData() {
|
||||||
|
this.condition.planId = "";
|
||||||
|
this.condition.nodeIds = [];
|
||||||
if (this.planId) {
|
if (this.planId) {
|
||||||
// param.planId = this.planId;
|
// param.planId = this.planId;
|
||||||
this.condition.planId = this.planId;
|
this.condition.planId = this.planId;
|
||||||
|
@ -322,10 +326,16 @@ export default {
|
||||||
this.$emit('testCaseEdit');
|
this.$emit('testCaseEdit');
|
||||||
},
|
},
|
||||||
handleEdit(testCase) {
|
handleEdit(testCase) {
|
||||||
|
this.$get('test/case/get/' + testCase.id, response => {
|
||||||
|
let testCase = response.data;
|
||||||
this.$emit('testCaseEdit', testCase);
|
this.$emit('testCaseEdit', testCase);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
handleCopy(testCase) {
|
handleCopy(testCase) {
|
||||||
|
this.$get('test/case/get/' + testCase.id, response => {
|
||||||
|
let testCase = response.data;
|
||||||
this.$emit('testCaseCopy', testCase);
|
this.$emit('testCaseCopy', testCase);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
handleDelete(testCase) {
|
handleDelete(testCase) {
|
||||||
this.$alert(this.$t('test_track.case.delete_confirm') + '\'' + testCase.name + '\'' + "?", '', {
|
this.$alert(this.$t('test_track.case.delete_confirm') + '\'' + testCase.name + '\'' + "?", '', {
|
||||||
|
@ -369,10 +379,6 @@ export default {
|
||||||
this.selectRows.clear();
|
this.selectRows.clear();
|
||||||
this.$emit('refresh');
|
this.$emit('refresh');
|
||||||
},
|
},
|
||||||
showAll() {
|
|
||||||
this.condition = {components: TEST_CASE_CONFIGS};
|
|
||||||
this.getData();
|
|
||||||
},
|
|
||||||
showDetail(row, event, column) {
|
showDetail(row, event, column) {
|
||||||
this.$emit('testCaseDetail', row);
|
this.$emit('testCaseDetail', row);
|
||||||
},
|
},
|
||||||
|
@ -488,6 +494,11 @@ export default {
|
||||||
this.$post('/user/ws/member/tester/list', {workspaceId: workspaceId}, response => {
|
this.$post('/user/ws/member/tester/list', {workspaceId: workspaceId}, response => {
|
||||||
this.valueArr.maintainer = response.data;
|
this.valueArr.maintainer = response.data;
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
showPopover(row, column, cell) {
|
||||||
|
if (column.property === 'name') {
|
||||||
|
this.currentCaseId = row.id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,8 +193,7 @@ export default {
|
||||||
let param = {};
|
let param = {};
|
||||||
Object.assign(param, this.form);
|
Object.assign(param, this.form);
|
||||||
param.name = param.name.trim();
|
param.name = param.name.trim();
|
||||||
if (param.name === '') {
|
if (!this.validate(param)) {
|
||||||
this.$warning(this.$t('test_track.plan.input_plan_name'));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
param.workspaceId = localStorage.getItem(WORKSPACE_ID);
|
param.workspaceId = localStorage.getItem(WORKSPACE_ID);
|
||||||
|
@ -227,6 +226,17 @@ export default {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
validate(param) {
|
||||||
|
if (param.name === '') {
|
||||||
|
this.$warning(this.$t('test_track.plan.input_plan_name'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (param.plannedStartTime > param.plannedEndTime) {
|
||||||
|
this.$warning(this.$t('commons.date.data_time_error'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
editTestPlan(param) {
|
editTestPlan(param) {
|
||||||
this.$post('/test/plan/' + this.operationType, param, () => {
|
this.$post('/test/plan/' + this.operationType, param, () => {
|
||||||
this.$success(this.$t('commons.save_success'));
|
this.$success(this.$t('commons.save_success'));
|
||||||
|
|
|
@ -137,7 +137,9 @@
|
||||||
|
|
||||||
<test-report-template-list @openReport="openReport" ref="testReportTemplateList"/>
|
<test-report-template-list @openReport="openReport" ref="testReportTemplateList"/>
|
||||||
<test-case-report-view @refresh="initTableData" ref="testCaseReportView"/>
|
<test-case-report-view @refresh="initTableData" ref="testCaseReportView"/>
|
||||||
<ms-delete-confirm :title="$t('test_track.plan.plan_delete')" @delete="_handleDelete" ref="deleteConfirm"/>
|
<ms-delete-confirm :title="$t('test_track.plan.plan_delete')" @delete="_handleDelete" ref="deleteConfirm" :with-tip="enableDeleteTip">
|
||||||
|
{{$t('test_track.plan.plan_delete_tip')}}
|
||||||
|
</ms-delete-confirm>
|
||||||
|
|
||||||
</el-card>
|
</el-card>
|
||||||
</template>
|
</template>
|
||||||
|
@ -171,6 +173,7 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
result: {},
|
result: {},
|
||||||
|
enableDeleteTip: false,
|
||||||
queryPath: "/test/plan/list",
|
queryPath: "/test/plan/list",
|
||||||
deletePath: "/test/plan/delete",
|
deletePath: "/test/plan/delete",
|
||||||
condition: {
|
condition: {
|
||||||
|
@ -249,6 +252,7 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleDelete(testPlan) {
|
handleDelete(testPlan) {
|
||||||
|
this.enableDeleteTip = testPlan.status === 'Underway' ? true : false;
|
||||||
this.$refs.deleteConfirm.open(testPlan);
|
this.$refs.deleteConfirm.open(testPlan);
|
||||||
},
|
},
|
||||||
_handleDelete(testPlan) {
|
_handleDelete(testPlan) {
|
||||||
|
|
|
@ -215,6 +215,16 @@
|
||||||
item.checked = false;
|
item.checked = false;
|
||||||
});
|
});
|
||||||
flag ? this.testCases = tableData : this.testCases = this.testCases.concat(tableData);
|
flag ? this.testCases = tableData : this.testCases = this.testCases.concat(tableData);
|
||||||
|
// 去重处理
|
||||||
|
let hash = {}
|
||||||
|
this.testCases = this.testCases.reduce((item, next) => {
|
||||||
|
if (!hash[next.id]) {
|
||||||
|
hash[next.id] = true
|
||||||
|
item.push(next)
|
||||||
|
}
|
||||||
|
return item
|
||||||
|
}, [])
|
||||||
|
|
||||||
this.lineStatus = tableData.length === 50 && this.testCases.length < this.total;
|
this.lineStatus = tableData.length === 50 && this.testCases.length < this.total;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -210,14 +210,15 @@
|
||||||
let reset = this.exportReportReset;
|
let reset = this.exportReportReset;
|
||||||
|
|
||||||
this.$nextTick(function () {
|
this.$nextTick(function () {
|
||||||
|
setTimeout(() => {
|
||||||
html2canvas(document.getElementById('testCaseReportExport'), {
|
html2canvas(document.getElementById('testCaseReportExport'), {
|
||||||
// scale: 2
|
scale: 2
|
||||||
}).then(function(canvas) {
|
}).then(function(canvas) {
|
||||||
exportPdf(name, [canvas]);
|
exportPdf(name, [canvas]);
|
||||||
reset();
|
reset();
|
||||||
});
|
});
|
||||||
|
}, 1000);
|
||||||
});
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
exportReportReset() {
|
exportReportReset() {
|
||||||
this.reportExportVisible = false;
|
this.reportExportVisible = false;
|
||||||
|
@ -225,7 +226,7 @@
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>cd
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
||||||
|
|
|
@ -23,9 +23,10 @@
|
||||||
resize="none"
|
resize="none"
|
||||||
:autosize="{ minRows: 4, maxRows: 4}"
|
:autosize="{ minRows: 4, maxRows: 4}"
|
||||||
@keyup.ctrl.enter.native="sendComment"
|
@keyup.ctrl.enter.native="sendComment"
|
||||||
|
:disabled="isReadOnly"
|
||||||
>
|
>
|
||||||
</el-input>
|
</el-input>
|
||||||
<el-button type="primary" size="mini" class="send-btn" @click="sendComment">
|
<el-button type="primary" size="mini" class="send-btn" @click="sendComment" :disabled="isReadOnly">
|
||||||
{{ $t('test_track.comment.send') }}
|
{{ $t('test_track.comment.send') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -34,6 +35,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ReviewCommentItem from "./ReviewCommentItem";
|
import ReviewCommentItem from "./ReviewCommentItem";
|
||||||
|
import {checkoutTestManagerOrTestUser} from "@/common/js/utils";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ReviewComment",
|
name: "ReviewComment",
|
||||||
|
@ -47,8 +49,12 @@ export default {
|
||||||
return {
|
return {
|
||||||
result: {},
|
result: {},
|
||||||
textarea: '',
|
textarea: '',
|
||||||
|
isReadOnly: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
|
this.isReadOnly = !checkoutTestManagerOrTestUser();
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
sendComment() {
|
sendComment() {
|
||||||
let comment = {};
|
let comment = {};
|
||||||
|
|
|
@ -219,6 +219,15 @@
|
||||||
item.checked = false;
|
item.checked = false;
|
||||||
});
|
});
|
||||||
flag ? this.testReviews = tableData : this.testReviews = this.testReviews.concat(tableData);
|
flag ? this.testReviews = tableData : this.testReviews = this.testReviews.concat(tableData);
|
||||||
|
// 去重处理
|
||||||
|
let hash = {}
|
||||||
|
this.testReviews = this.testReviews.reduce((item, next) => {
|
||||||
|
if (!hash[next.id]) {
|
||||||
|
hash[next.id] = true
|
||||||
|
item.push(next)
|
||||||
|
}
|
||||||
|
return item
|
||||||
|
}, [])
|
||||||
this.lineStatus = tableData.length === 50 && this.testReviews.length < this.total;
|
this.lineStatus = tableData.length === 50 && this.testReviews.length < this.total;
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -108,3 +108,9 @@ body {
|
||||||
margin: 5px 0;
|
margin: 5px 0;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 修复带长度限制的文本框,内容太长造成的无法查看内容的问题 */
|
||||||
|
|
||||||
|
.el-input__inner[maxlength] {
|
||||||
|
padding-right: 60px;
|
||||||
|
}
|
||||||
|
|
|
@ -43,8 +43,10 @@ export default {
|
||||||
success(response.data);
|
success(response.data);
|
||||||
} else {
|
} else {
|
||||||
window.console.warn(response.data);
|
window.console.warn(response.data);
|
||||||
|
if (response.data.message) {
|
||||||
Message.warning(response.data.message);
|
Message.warning(response.data.message);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
result.loading = false;
|
result.loading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
export const PHONE_REGEX = '^1(3|4|5|7|8|9)\\d{9}$';
|
|
@ -275,3 +275,17 @@ export function exportPdf(name, canvasList) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function windowPrint(id, zoom) {
|
||||||
|
//根据div标签ID拿到div中的局部内容
|
||||||
|
let bdhtml=window.document.body.innerHTML;
|
||||||
|
let el = document.getElementById(id);
|
||||||
|
var jubuData = el.innerHTML;
|
||||||
|
document.getElementsByTagName('body')[0].style.zoom=zoom;
|
||||||
|
//把获取的 局部div内容赋给body标签, 相当于重置了 body里的内容
|
||||||
|
window.document.body.innerHTML= jubuData;
|
||||||
|
//调用打印功能
|
||||||
|
window.print();
|
||||||
|
window.document.body.innerHTML=bdhtml;//重新给页面内容赋值;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -893,6 +893,7 @@ export default {
|
||||||
actual_start_time: "Actual Start Time",
|
actual_start_time: "Actual Start Time",
|
||||||
actual_end_time: "Actual End Time",
|
actual_end_time: "Actual End Time",
|
||||||
plan_delete_confirm: "All use cases under this plan will be deleted,confirm delete test plan: ",
|
plan_delete_confirm: "All use cases under this plan will be deleted,confirm delete test plan: ",
|
||||||
|
plan_delete_tip: "The test plan is under way, please confirm and delete it!",
|
||||||
plan_delete: "Delete test plan",
|
plan_delete: "Delete test plan",
|
||||||
},
|
},
|
||||||
review: {
|
review: {
|
||||||
|
|
|
@ -470,7 +470,7 @@ export default {
|
||||||
title: "jar包管理",
|
title: "jar包管理",
|
||||||
jar_file: "jar包",
|
jar_file: "jar包",
|
||||||
delete_tip: "删除需重启服务后生效",
|
delete_tip: "删除需重启服务后生效",
|
||||||
file_exist: "该项目下已存在改jar包",
|
file_exist: "该项目下已存在该jar包",
|
||||||
upload_limit_size: "上传文件大小不能超过 30MB!",
|
upload_limit_size: "上传文件大小不能超过 30MB!",
|
||||||
},
|
},
|
||||||
definition: {
|
definition: {
|
||||||
|
@ -896,6 +896,7 @@ export default {
|
||||||
actual_start_time: "实际开始",
|
actual_start_time: "实际开始",
|
||||||
actual_end_time: "实际结束",
|
actual_end_time: "实际结束",
|
||||||
plan_delete_confirm: "将删除该测试计划下所有用例,确认删除测试计划: ",
|
plan_delete_confirm: "将删除该测试计划下所有用例,确认删除测试计划: ",
|
||||||
|
plan_delete_tip: "该测试计划正在进行中,请确认再删除!",
|
||||||
plan_delete: "删除计划",
|
plan_delete: "删除计划",
|
||||||
},
|
},
|
||||||
review: {
|
review: {
|
||||||
|
@ -1063,7 +1064,7 @@ export default {
|
||||||
SMTP_password: 'SMTP密码',
|
SMTP_password: 'SMTP密码',
|
||||||
SSL: '开启SSL(如果SMTP端口是465,通常需要启用SSL)',
|
SSL: '开启SSL(如果SMTP端口是465,通常需要启用SSL)',
|
||||||
TLS: '开启TLS(如果SMTP端口是587,通常需要启用TLS)',
|
TLS: '开启TLS(如果SMTP端口是587,通常需要启用TLS)',
|
||||||
SMTP: '是否匿名 SMTP',
|
SMTP: '是否免密 SMTP',
|
||||||
host: '主机号不能为空',
|
host: '主机号不能为空',
|
||||||
port: '端口号不能为空',
|
port: '端口号不能为空',
|
||||||
account: '账户不能为空',
|
account: '账户不能为空',
|
||||||
|
|
|
@ -470,7 +470,7 @@ export default {
|
||||||
title: "jar包管理",
|
title: "jar包管理",
|
||||||
jar_file: "jar包",
|
jar_file: "jar包",
|
||||||
delete_tip: "刪除需重啟服務後生效",
|
delete_tip: "刪除需重啟服務後生效",
|
||||||
file_exist: "該項目下已存在改jar包",
|
file_exist: "該項目下已存在該jar包",
|
||||||
upload_limit_size: "上傳文件大小不能超過 30MB!",
|
upload_limit_size: "上傳文件大小不能超過 30MB!",
|
||||||
},
|
},
|
||||||
definition: {
|
definition: {
|
||||||
|
@ -894,6 +894,7 @@ export default {
|
||||||
actual_start_time: "實際開始",
|
actual_start_time: "實際開始",
|
||||||
actual_end_time: "實際結束",
|
actual_end_time: "實際結束",
|
||||||
plan_delete_confirm: "將刪除該測試計劃下所有用例,確認刪除測試計劃: ",
|
plan_delete_confirm: "將刪除該測試計劃下所有用例,確認刪除測試計劃: ",
|
||||||
|
plan_delete_tip: "該測試計劃正在進行中,請確認再刪除!",
|
||||||
plan_delete: "刪除計劃",
|
plan_delete: "刪除計劃",
|
||||||
},
|
},
|
||||||
review: {
|
review: {
|
||||||
|
@ -1061,7 +1062,7 @@ export default {
|
||||||
SMTP_password: 'SMTP密碼',
|
SMTP_password: 'SMTP密碼',
|
||||||
SSL: '開啟SSL(如果SMTP端口是465,通常需要啟用SSL)',
|
SSL: '開啟SSL(如果SMTP端口是465,通常需要啟用SSL)',
|
||||||
TLS: '開啟TLS(如果SMTP端口是587,通常需要啟用TLS)',
|
TLS: '開啟TLS(如果SMTP端口是587,通常需要啟用TLS)',
|
||||||
SMTP: '是否匿名 SMTP',
|
SMTP: '是否免密 SMTP',
|
||||||
host: '主機號不能為空',
|
host: '主機號不能為空',
|
||||||
port: '端口號不能為空',
|
port: '端口號不能為空',
|
||||||
account: '賬戶不能為空',
|
account: '賬戶不能為空',
|
||||||
|
|
|
@ -4,8 +4,7 @@
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form :model="form" :rules="rules" ref="form">
|
<el-form :model="form" :rules="rules" ref="form">
|
||||||
<div class="logo">
|
<div class="logo">
|
||||||
<img v-if="loginLogoId" :src="'/display/file/' + loginLogoId" style="width: 224px;height: 45px;" alt="">
|
<img :src="'/display/file/loginLogo'" style="width: 224px;height: 45px;" alt="">
|
||||||
<img v-else src="../assets/logo-dark-MeterSphere.svg" style="width: 224px; " alt="">
|
|
||||||
</div>
|
</div>
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<span id="s1">{{ loginTitle }}</span>
|
<span id="s1">{{ loginTitle }}</span>
|
||||||
|
@ -41,8 +40,7 @@
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<img v-if="loginImageId" :src="'/display/file/' + loginImageId" style="height: 560px; width: 100%">
|
<img :src="'/display/file/loginImage'" style="height: 560px; width: 100%">
|
||||||
<img v-else src="../assets/info.png" style="height: 560px; width: 100%">
|
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
|
@ -86,8 +84,6 @@ export default {
|
||||||
msg: '',
|
msg: '',
|
||||||
ready: false,
|
ready: false,
|
||||||
openLdap: false,
|
openLdap: false,
|
||||||
loginLogoId: '_blank',
|
|
||||||
loginImageId: '_blank',
|
|
||||||
loginTitle: this.$t("commons.login") + " MeterSphere"
|
loginTitle: this.$t("commons.login") + " MeterSphere"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -264,6 +260,10 @@ export default {
|
||||||
background: url(../assets/info.png);
|
background: url(../assets/info.png);
|
||||||
height: 560px;
|
height: 560px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.login-logo {
|
||||||
|
background: url(../assets/logo-dark-MeterSphere.svg);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
2
pom.xml
2
pom.xml
|
@ -4,7 +4,7 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>io.metersphere</groupId>
|
<groupId>io.metersphere</groupId>
|
||||||
<artifactId>metersphere-server</artifactId>
|
<artifactId>metersphere-server</artifactId>
|
||||||
<version>1.4</version>
|
<version>1.5</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
|
|
Loading…
Reference in New Issue