Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
q4speed 2020-04-27 17:10:36 +08:00
commit 181c406826
44 changed files with 526 additions and 642 deletions

View File

@ -6,6 +6,8 @@ import io.metersphere.base.domain.*;
import io.metersphere.commons.utils.PageUtils;
import io.metersphere.commons.utils.Pager;
import io.metersphere.controller.request.testcase.QueryTestCaseRequest;
import io.metersphere.controller.request.testcase.TestCaseBatchRequest;
import io.metersphere.controller.request.testcase.TestPlanCaseBatchRequest;
import io.metersphere.excel.domain.ExcelResponse;
import io.metersphere.service.TestCaseService;
import io.metersphere.user.SessionUtils;
@ -82,5 +84,9 @@ public class TestCaseController {
testCaseService.testCaseTemplateExport(response);
}
@PostMapping("/batch/edit")
public void editTestCaseBath(@RequestBody TestCaseBatchRequest request){
testCaseService.editTestCaseBath(request);
}
}

View File

@ -2,12 +2,10 @@ package io.metersphere.controller;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.metersphere.base.domain.TestCaseWithBLOBs;
import io.metersphere.base.domain.TestPlanTestCase;
import io.metersphere.commons.utils.PageUtils;
import io.metersphere.commons.utils.Pager;
import io.metersphere.controller.request.testcase.QueryTestCaseRequest;
import io.metersphere.controller.request.testcase.TestCaseBatchRequest;
import io.metersphere.controller.request.testcase.TestPlanCaseBatchRequest;
import io.metersphere.controller.request.testplancase.QueryTestPlanCaseRequest;
import io.metersphere.dto.TestPlanCaseDTO;
import io.metersphere.service.TestPlanTestCaseService;
@ -40,7 +38,7 @@ public class TestPlanTestCaseController {
}
@PostMapping("/batch/edit")
public void editTestCaseBath(@RequestBody TestCaseBatchRequest request){
public void editTestCaseBath(@RequestBody TestPlanCaseBatchRequest request){
testPlanTestCaseService.editTestCaseBath(request);
}

View File

@ -1,19 +1,19 @@
package io.metersphere.controller.request.testcase;
import io.metersphere.base.domain.TestCase;
import io.metersphere.base.domain.TestCaseWithBLOBs;
import io.metersphere.base.domain.TestPlanTestCase;
import java.util.List;
public class TestCaseBatchRequest extends TestPlanTestCase {
public class TestCaseBatchRequest extends TestCaseWithBLOBs {
private List<Integer> ids;
private List<String> ids;
public List<Integer> getIds() {
public List<String> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
public void setIds(List<String> ids) {
this.ids = ids;
}
}

View File

@ -0,0 +1,19 @@
package io.metersphere.controller.request.testcase;
import io.metersphere.base.domain.TestCase;
import io.metersphere.base.domain.TestPlanTestCase;
import java.util.List;
public class TestPlanCaseBatchRequest extends TestPlanTestCase {
private List<Integer> ids;
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
}

View File

@ -91,14 +91,18 @@ public class TestCaseDataListener extends EasyExcelListener<TestCaseExcelData> {
JSONArray jsonArray = new JSONArray();
String[] stepDesc = new String[0];
String[] stepRes = new String[0];
String[] stepDesc = new String[1];
String[] stepRes = new String[1];
if (data.getStepDesc() != null) {
stepDesc = data.getStepDesc().split("\n");
} else {
stepDesc[0] = "";
}
if (data.getStepResult() != null) {
stepRes = data.getStepResult().split("\n");
} else {
stepRes[0] = "";
}
String pattern = "(^\\d+)(\\.)?";

View File

@ -84,7 +84,7 @@ public class ReportService {
LoadTestReportResultExample example = new LoadTestReportResultExample();
example.createCriteria().andReportIdEqualTo(id).andReportKeyEqualTo(reportKey.name());
List<LoadTestReportResult> loadTestReportResults = loadTestReportResultMapper.selectByExampleWithBLOBs(example);
if (loadTestReportResults.size() != 1) {
if (loadTestReportResults.size() == 0) {
MSException.throwException("get report result error.");
}
return loadTestReportResults.get(0).getReportValue();

View File

@ -1,16 +1,17 @@
package io.metersphere.service;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.*;
import io.metersphere.base.mapper.ext.ExtTestCaseMapper;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.BeanUtils;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.controller.request.testcase.QueryTestCaseRequest;
import io.metersphere.controller.request.testcase.TestCaseBatchRequest;
import io.metersphere.controller.request.testcase.TestPlanCaseBatchRequest;
import io.metersphere.excel.domain.ExcelErrData;
import io.metersphere.excel.domain.ExcelResponse;
import io.metersphere.excel.domain.TestCaseExcelData;
@ -31,7 +32,6 @@ import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;
@ -269,4 +269,16 @@ public class TestCaseService {
list.add(explain);
return list;
}
public void editTestCaseBath(TestCaseBatchRequest request) {
TestCaseExample testCaseExample = new TestCaseExample();
testCaseExample.createCriteria().andIdIn(request.getIds());
TestCaseWithBLOBs testCase = new TestCaseWithBLOBs();
BeanUtils.copyBean(testCase, request);
testCaseMapper.updateByExampleSelective(
testCase,
testCaseExample);
}
}

View File

@ -8,10 +8,12 @@ import io.metersphere.base.mapper.TestPlanTestCaseMapper;
import io.metersphere.base.mapper.ext.ExtTestPlanMapper;
import io.metersphere.commons.constants.TestPlanStatus;
import io.metersphere.commons.constants.TestPlanTestCaseStatus;
import io.metersphere.commons.exception.MSException;
import io.metersphere.controller.request.testcase.PlanCaseRelevanceRequest;
import io.metersphere.controller.request.testcase.QueryTestCaseRequest;
import io.metersphere.controller.request.testcase.QueryTestPlanRequest;
import io.metersphere.dto.TestPlanDTO;
import io.metersphere.i18n.Translator;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
@ -62,8 +64,14 @@ public class TestPlanService {
return testPlanMapper.updateByPrimaryKeySelective(testPlan);
}
public int deleteTestPlan(String testPalnId) {
return testPlanMapper.deleteByPrimaryKey(testPalnId);
public int deleteTestPlan(String testPlanId) {
TestPlanTestCaseExample testPlanTestCaseExample = new TestPlanTestCaseExample();
testPlanTestCaseExample.createCriteria().andPlanIdEqualTo(testPlanId);
List<TestPlanTestCase> testPlanTestCases = testPlanTestCaseMapper.selectByExample(testPlanTestCaseExample);
if (testPlanTestCases.size() > 0) {
MSException.throwException(Translator.get("before_delete_plan"));
}
return testPlanMapper.deleteByPrimaryKey(testPlanId);
}
public List<TestPlanDTO> listTestPlan(QueryTestPlanRequest request) {

View File

@ -6,12 +6,10 @@ import io.metersphere.base.mapper.TestPlanTestCaseMapper;
import io.metersphere.base.mapper.ext.ExtTestCaseMapper;
import io.metersphere.commons.constants.TestPlanTestCaseStatus;
import io.metersphere.commons.utils.BeanUtils;
import io.metersphere.controller.request.testcase.QueryTestCaseRequest;
import io.metersphere.controller.request.testcase.TestCaseBatchRequest;
import io.metersphere.controller.request.testcase.TestPlanCaseBatchRequest;
import io.metersphere.controller.request.testplancase.QueryTestPlanCaseRequest;
import io.metersphere.dto.TestPlanCaseDTO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -44,7 +42,7 @@ public class TestPlanTestCaseService {
return testPlanTestCaseMapper.deleteByPrimaryKey(id);
}
public void editTestCaseBath(TestCaseBatchRequest request) {
public void editTestCaseBath(TestPlanCaseBatchRequest request) {
TestPlanTestCaseExample testPlanTestCaseExample = new TestPlanTestCaseExample();
testPlanTestCaseExample.createCriteria().andIdIn(request.getIds());

View File

@ -1 +1,2 @@
test_case_exist=
test_case_exist=
before_delete_plan=

View File

@ -22,4 +22,5 @@ organization_id_is_null=Organization ID cannot be null
max_thread_insufficient=The number of concurrent users exceeds
cannot_edit_load_test_running=Cannot modify the running test
test_not_found=Test cannot be found:
test_not_running=Test is not running
test_not_running=Test is not running
before_delete_plan=There is an associated test case under this plan, please unlink it first!

View File

@ -1,25 +1,26 @@
test_case_exist=\u8BE5\u9879\u76EE\u4E0B\u5DF2\u5B58\u5728\u7528\u4F8B\uFF1A
error_lang_invalid=\u8BED\u8A00\u53C2\u6570\u9519\u8BEF
load_test_already_exists=\u6D4B\u8BD5\u540D\u79F0\u4E0D\u80FD\u91CD\u590D
project_name_is_null=\u9879\u76EE\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A
project_name_already_exists=\u9879\u76EE\u540D\u79F0\u5DF2\u5B58\u5728
workspace_name_is_null=\u5DE5\u4F5C\u7A7A\u95F4\u540D\u4E0D\u80FD\u4E3A\u7A7A
workspace_name_already_exists=\u5DE5\u4F5C\u7A7A\u95F4\u540D\u5DF2\u5B58\u5728
workspace_does_not_belong_to_user=\u5F53\u524D\u5DE5\u4F5C\u7A7A\u95F4\u4E0D\u5C5E\u4E8E\u5F53\u524D\u7528\u6237
organization_does_not_belong_to_user=\u5F53\u524D\u7EC4\u7EC7\u4E0D\u5C5E\u4E8E\u5F53\u524D\u7528\u6237
file_cannot_be_null=\u6587\u4EF6\u4E0D\u80FD\u4E3A\u7A7A\uFF01
edit_load_test_not_found=\u65E0\u6CD5\u7F16\u8F91\u6D4B\u8BD5\uFF0C\u672A\u627E\u5230\u6D4B\u8BD5\uFF1A
run_load_test_not_found=\u65E0\u6CD5\u8FD0\u884C\u6D4B\u8BD5\uFF0C\u672A\u627E\u5230\u6D4B\u8BD5\uFF1A
run_load_test_file_not_found=\u65E0\u6CD5\u8FD0\u884C\u6D4B\u8BD5\uFF0C\u65E0\u6CD5\u83B7\u53D6\u6D4B\u8BD5\u6587\u4EF6\u5143\u4FE1\u606F\uFF0C\u6D4B\u8BD5ID\uFF1A
run_load_test_file_content_not_found=\u65E0\u6CD5\u8FD0\u884C\u6D4B\u8BD5\uFF0C\u65E0\u6CD5\u83B7\u53D6\u6D4B\u8BD5\u6587\u4EF6\u5185\u5BB9\uFF0C\u6D4B\u8BD5ID\uFF1A
run_load_test_file_init_error=\u65E0\u6CD5\u8FD0\u884C\u6D4B\u8BD5\uFF0C\u521D\u59CB\u5316\u8FD0\u884C\u73AF\u5883\u5931\u8D25\uFF0C\u6D4B\u8BD5ID\uFF1A
load_test_is_running=\u6D4B\u8BD5\u6B63\u5728\u8FD0\u884C, \u8BF7\u7B49\u5F85
node_deep_limit=\u8282\u70B9\u6DF1\u5EA6\u4E0D\u8D85\u8FC75\u5C42\uFF01
no_nodes_message=\u6CA1\u6709\u8282\u70B9\u4FE1\u606F
duplicate_node_ip=\u8282\u70B9 IP \u91CD\u590D
only_one_k8s=\u53EA\u80FD\u6DFB\u52A0\u4E00\u4E2A K8s
organization_id_is_null=\u7EC4\u7EC7 ID \u4E0D\u80FD\u4E3A\u7A7A
max_thread_insufficient=\u5E76\u53D1\u7528\u6237\u6570\u8D85\u989D
cannot_edit_load_test_running=\u4E0D\u80FD\u4FEE\u6539\u6B63\u5728\u8FD0\u884C\u7684\u6D4B\u8BD5
test_not_found=\u6D4B\u8BD5\u4E0D\u5B58\u5728:
test_not_running=\u6D4B\u8BD5\u672A\u8FD0\u884C
test_case_exist=该项目下已存在用例:
error_lang_invalid=语言参数错误
load_test_already_exists=测试名称不能重复
project_name_is_null=项目名称不能为空
project_name_already_exists=项目名称已存在
workspace_name_is_null=工作空间名不能为空
workspace_name_already_exists=工作空间名已存在
workspace_does_not_belong_to_user=当前工作空间不属于当前用户
organization_does_not_belong_to_user=当前组织不属于当前用户
file_cannot_be_null=文件不能为空!
edit_load_test_not_found=无法编辑测试,未找到测试:
run_load_test_not_found=无法运行测试,未找到测试:
run_load_test_file_not_found=无法运行测试无法获取测试文件元信息测试ID
run_load_test_file_content_not_found=无法运行测试无法获取测试文件内容测试ID
run_load_test_file_init_error=无法运行测试初始化运行环境失败测试ID
load_test_is_running=测试正在运行, 请等待
node_deep_limit=节点深度不超过5层
no_nodes_message=没有节点信息
duplicate_node_ip=节点 IP 重复
only_one_k8s=只能添加一个 K8s
organization_id_is_null=组织 ID 不能为空
max_thread_insufficient=并发用户数超额
cannot_edit_load_test_running=不能修改正在运行的测试
test_not_found=测试不存在:
test_not_running=测试未运行
before_delete_plan=该计划下存在关联测试用例,请先取消关联!

View File

@ -1,99 +0,0 @@
package io.metersphere;
import io.metersphere.base.domain.LoadTestReportWithBLOBs;
import io.metersphere.base.mapper.LoadTestReportMapper;
import org.apache.commons.io.FileUtils;
import org.apache.jmeter.report.core.Sample;
import org.apache.jmeter.report.core.SampleMetadata;
import org.apache.jmeter.report.processor.AbstractSummaryConsumer;
import org.apache.jmeter.report.processor.SampleContext;
import org.apache.jmeter.report.processor.Top5ErrorsBySamplerConsumer;
import org.apache.jmeter.util.JMeterUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import java.util.StringTokenizer;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class DashboardConsumerTest {
@Resource
private LoadTestReportMapper loadTestReportMapper;
private AbstractSummaryConsumer<?> summaryConsumer;
// data array can't be initialized in the init()
private static String[] data = {"1527089951383", "0", "Read-compute", "200", "OK", "setupRegion 1-1", "true", "", "492", "0", "1", "1",
"null", "0", "0", "0"};
private SampleMetadata sampleMetaData = createTestMetaData();
@Before
public void init() {
summaryConsumer = new Top5ErrorsBySamplerConsumer();
// timeGraphConsumer.setTitle("graph title");
JMeterUtils.loadJMeterProperties("jmeter.properties"); // 这个路径不存在
}
@Test
public void test() {
SampleContext sampleContext = new SampleContext();
sampleContext.setWorkingDirectory(FileUtils.getTempDirectory());
summaryConsumer.setSampleContext(sampleContext);
Sample sample = new Sample(0, sampleMetaData, data);
summaryConsumer.startConsuming();
summaryConsumer.consume(sample, 0);
summaryConsumer.stopConsuming();
System.out.println(sampleContext.getData());
}
@Test
public void test2() {
int row = 0;
SampleContext sampleContext = new SampleContext();
// sampleContext.setWorkingDirectory(new File("/tmp/test_report/"));
summaryConsumer.setSampleContext(sampleContext);
summaryConsumer.startConsuming();
LoadTestReportWithBLOBs report = loadTestReportMapper.selectByPrimaryKey("7fa4dd2d-d42a-46de-92bf-10feec4c6ccf");
String content = report.getContent();
StringTokenizer tokenizer = new StringTokenizer(content, "\n");
// 去掉第一行
tokenizer.nextToken();
while (tokenizer.hasMoreTokens()) {
String line = tokenizer.nextToken();
String[] data = line.split(",", -1);
Sample sample = new Sample(row++, sampleMetaData, data);
summaryConsumer.consume(sample, 0);
}
summaryConsumer.stopConsuming();
System.out.println("+++++++++" + sampleContext.getData());
}
// Create a static SampleMetadataObject
private SampleMetadata createTestMetaData() {
String columnsString = "timeStamp,elapsed,label,responseCode,responseMessage,threadName,success,failureMessage,bytes,sentBytes,grpThreads,allThreads,URL,Latency,IdleTime,Connect";
columnsString = "timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,failureMessage,bytes,sentBytes,grpThreads,allThreads,URL,Latency,IdleTime,Connect";
String[] columns = new String[17];
int lastComa = 0;
int columnIndex = 0;
for (int i = 0; i < columnsString.length(); i++) {
if (columnsString.charAt(i) == ',') {
columns[columnIndex] = columnsString.substring(lastComa, i);
lastComa = i + 1;
columnIndex++;
} else if (i + 1 == columnsString.length()) {
columns[columnIndex] = columnsString.substring(lastComa, i + 1);
}
}
return new SampleMetadata(',', columns);
}
}

View File

@ -1,45 +0,0 @@
package io.metersphere;
import com.opencsv.bean.CsvToBean;
import com.opencsv.bean.CsvToBeanBuilder;
import com.opencsv.bean.HeaderColumnNameMappingStrategy;
import com.opencsv.bean.MappingStrategy;
import org.junit.Test;
import java.io.File;
import java.io.Reader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
public class GenerateGraphTest {
@Test
public void test1() {
File csvFile = new File("/Users/liuruibin/Desktop/0316.jtl");
HeaderColumnNameMappingStrategy<Metric> ms = new HeaderColumnNameMappingStrategy<>();
ms.setType(Metric.class);
List<Metric> metrics = beanBuilderExample(csvFile.toPath(), ms);
metrics.forEach(c -> {
System.out.println(c.getTimestamp());
});
}
public static List<Metric> beanBuilderExample(Path path, MappingStrategy<Metric> ms) {
try (Reader reader = Files.newBufferedReader(path)) {
CsvToBean<Metric> cb = new CsvToBeanBuilder<Metric>(reader)
.withType(Metric.class)
.withSkipLines(0)
.withMappingStrategy(ms)
.withIgnoreLeadingWhiteSpace(true)
.build();
return cb.parse();
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
}

View File

@ -1,128 +0,0 @@
package io.metersphere;
import io.metersphere.base.domain.LoadTestReportWithBLOBs;
import io.metersphere.base.mapper.LoadTestReportMapper;
import org.apache.commons.io.FileUtils;
import org.apache.jmeter.report.core.Sample;
import org.apache.jmeter.report.core.SampleMetadata;
import org.apache.jmeter.report.dashboard.JsonizerVisitor;
import org.apache.jmeter.report.processor.ListResultData;
import org.apache.jmeter.report.processor.MapResultData;
import org.apache.jmeter.report.processor.ResultData;
import org.apache.jmeter.report.processor.SampleContext;
import org.apache.jmeter.report.processor.graph.AbstractOverTimeGraphConsumer;
import org.apache.jmeter.report.processor.graph.impl.ActiveThreadsGraphConsumer;
import org.apache.jmeter.util.JMeterUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import java.util.Map;
import java.util.StringTokenizer;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class GraphConsumerTest {
@Resource
private LoadTestReportMapper loadTestReportMapper;
private AbstractOverTimeGraphConsumer timeGraphConsumer;
// data array can't be initialized in the init()
private static String[] data = {"1527089951383", "0", "Read-compute", "200", "OK", "setupRegion 1-1", "true", "", "492", "0", "1", "1",
"null", "0", "0", "0"};
private SampleMetadata sampleMetaData = createTestMetaData();
@Before
public void init() {
timeGraphConsumer = new ActiveThreadsGraphConsumer();
// timeGraphConsumer.setTitle("graph title");
timeGraphConsumer.setGranularity(60000);
JMeterUtils.loadJMeterProperties("jmeter.properties"); // 这个路径不存在
}
@Test
public void test() {
SampleContext sampleContext = new SampleContext();
sampleContext.setWorkingDirectory(FileUtils.getTempDirectory());
timeGraphConsumer.setSampleContext(sampleContext);
Sample sample = new Sample(0, sampleMetaData, data);
timeGraphConsumer.initialize();
timeGraphConsumer.startConsuming();
timeGraphConsumer.consume(sample, 0);
timeGraphConsumer.stopConsuming();
System.out.println(sampleContext.getData());
}
@Test
public void test2() {
int row = 0;
SampleContext sampleContext = new SampleContext();
// sampleContext.setWorkingDirectory(new File("/tmp/test_report/"));
timeGraphConsumer.setSampleContext(sampleContext);
timeGraphConsumer.initialize();
timeGraphConsumer.startConsuming();
LoadTestReportWithBLOBs report = loadTestReportMapper.selectByPrimaryKey("7fa4dd2d-d42a-46de-92bf-10feec4c6ccf");
String content = report.getContent();
StringTokenizer tokenizer = new StringTokenizer(content, "\n");
// 去掉第一行
tokenizer.nextToken();
while (tokenizer.hasMoreTokens()) {
String line = tokenizer.nextToken();
String[] data = line.split(",", -1);
Sample sample = new Sample(row++, sampleMetaData, data);
timeGraphConsumer.consume(sample, 0);
}
timeGraphConsumer.stopConsuming();
Map<String, Object> map = sampleContext.getData();
for (String key : map.keySet()) {
MapResultData mapResultData = (MapResultData) map.get(key);
ResultData maxY = mapResultData.getResult("maxY");
ListResultData series = (ListResultData) mapResultData.getResult("series");
if (series.getSize() > 0) {
MapResultData resultData = (MapResultData) series.get(0);
ListResultData data = (ListResultData) resultData.getResult("data");
if (data.getSize() > 0) {
for (int i = 0; i < data.getSize(); i++) {
ListResultData resultData1 = (ListResultData) data.get(i);
String accept = resultData1.accept(new JsonizerVisitor());
String[] split = accept.split(",");
System.out.println(resultData1);
System.out.println(accept);
}
}
}
}
System.out.println("+++++++++" + sampleContext.getData());
}
// Create a static SampleMetadataObject
private SampleMetadata createTestMetaData() {
String columnsString = "timeStamp,elapsed,label,responseCode,responseMessage,threadName,success,failureMessage,bytes,sentBytes,grpThreads,allThreads,URL,Latency,IdleTime,Connect";
columnsString = "timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,failureMessage,bytes,sentBytes,grpThreads,allThreads,URL,Latency,IdleTime,Connect";
String[] columns = new String[17];
int lastComa = 0;
int columnIndex = 0;
for (int i = 0; i < columnsString.length(); i++) {
if (columnsString.charAt(i) == ',') {
columns[columnIndex] = columnsString.substring(lastComa, i);
lastComa = i + 1;
columnIndex++;
} else if (i + 1 == columnsString.length()) {
columns[columnIndex] = columnsString.substring(lastComa, i + 1);
}
}
return new SampleMetadata(',', columns);
}
}

View File

@ -1,7 +1,6 @@
package io.metersphere;
import io.metersphere.config.KafkaProperties;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -23,7 +22,6 @@ import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.FileInputStream;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ -80,8 +78,8 @@ public class JmxFileParseTest {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.transform(domSource, result);
// System.out.println("XML IN String format is: \n" + writer.toString());
FileUtils.writeStringToFile(new File("/tmp/test-jmeter.jmx"), writer.toString(), StandardCharsets.UTF_8);
System.out.println("XML IN String format is: \n" + writer.toString());
// FileUtils.writeStringToFile(new File("/tmp/test-jmeter.jmx"), writer.toString(), StandardCharsets.UTF_8);
}
private void parseHashTree(Element hashTree) {

View File

@ -96,10 +96,16 @@
})
this.$get("/performance/report/content/load_chart/" + this.id, res => {
let data = res.data;
let userList = data.filter(m => m.groupName === "users").map(m => m.yAxis);
let hitsList = data.filter(m => m.groupName === "hits").map(m => m.yAxis);
let userMax = this._getChartMax(userList);
let hitsMax = this._getChartMax(hitsList);
let yAxisList = data.filter(m => m.yAxis2 === -1).map(m => m.yAxis);
let yAxis2List = data.filter(m => m.yAxis === -1).map(m => m.yAxis2);
let yAxisListMax = this._getChartMax(yAxisList);
let yAxis2ListMax = this._getChartMax(yAxis2List);
let yAxisIndex0List = data.filter(m => m.yAxis2 === -1).map(m => m.groupName);
yAxisIndex0List = this._unique(yAxisIndex0List);
let yAxisIndex1List = data.filter(m => m.yAxis === -1).map(m => m.groupName);
yAxisIndex1List = this._unique(yAxisIndex1List);
let loadOption = {
title: {
text: 'Load',
@ -119,17 +125,17 @@
name: 'User',
type: 'value',
min: 0,
max: userMax,
max: yAxisListMax,
splitNumber: 5,
interval: userMax / 5
interval: yAxisListMax / 5
},
{
name: 'Hits/s',
type: 'value',
splitNumber: 5,
min: 0,
max: hitsMax,
interval: hitsMax / 5
max: yAxis2ListMax,
interval: yAxis2ListMax / 5
}
],
series: []
@ -152,15 +158,27 @@
}
]
}
yAxisIndex0List.forEach(item => {
setting["series"].splice(0, 0, {name: item, yAxisIndex: '0'})
})
yAxisIndex1List.forEach(item => {
setting["series"].splice(0, 0, {name: item, yAxisIndex: '1'})
})
this.loadOption = this.generateOption(loadOption, data, setting);
})
this.$get("/performance/report/content/res_chart/" + this.id, res => {
let data = res.data;
let userList = data.filter(m => m.groupName === "users").map(m => m.yAxis);
let responseTimeList = data.filter(m => m.groupName != "users").map(m => m.yAxis);
let responseGroupNameList = data.filter(m => m.groupName != "users").map(m => m.groupName);
let userMax = this._getChartMax(userList);
let resMax = this._getChartMax(responseTimeList);
let yAxisList = data.filter(m => m.yAxis2 === -1).map(m => m.yAxis);
let yAxis2List = data.filter(m => m.yAxis === -1).map(m => m.yAxis2);
let yAxisListMax = this._getChartMax(yAxisList);
let yAxis2ListMax = this._getChartMax(yAxis2List);
let yAxisIndex0List = data.filter(m => m.yAxis2 === -1).map(m => m.groupName);
yAxisIndex0List = this._unique(yAxisIndex0List);
let yAxisIndex1List = data.filter(m => m.yAxis === -1).map(m => m.groupName);
yAxisIndex1List = this._unique(yAxisIndex1List);
let resOption = {
title: {
text: 'Response Time',
@ -197,15 +215,15 @@
name: 'User',
type: 'value',
min: 0,
max: userMax,
interval: userMax / 5
max: yAxisListMax,
interval: yAxisListMax / 5
},
{
name: 'Response Time',
type: 'value',
min: 0,
max: resMax,
interval: resMax / 5
max: yAxis2ListMax,
interval: yAxis2ListMax / 5
}
],
series: []
@ -218,9 +236,15 @@
}
]
}
responseGroupNameList.forEach(item => {
yAxisIndex0List.forEach(item => {
setting["series"].splice(0, 0, {name: item, yAxisIndex: '0'})
})
yAxisIndex1List.forEach(item => {
setting["series"].splice(0, 0, {name: item, yAxisIndex: '1'})
})
this.resOption = this.generateOption(resOption, data, setting);
})
},
@ -245,7 +269,11 @@
legend.push(name)
series[name] = []
}
series[name].splice(xAxis.indexOf(item.xAxis), 0, [item.xAxis, item.yAxis.toFixed(2)]);
if (item.yAxis === -1) {
series[name].splice(xAxis.indexOf(item.xAxis), 0, [item.xAxis, item.yAxis2.toFixed(2)]);
} else {
series[name].splice(xAxis.indexOf(item.xAxis), 0, [item.xAxis, item.yAxis.toFixed(2)]);
}
})
this.$set(option.legend, "data", legend);
this.$set(option.legend, "type", "scroll");
@ -276,6 +304,9 @@
_getChartMax(arr) {
const max = Math.max(...arr);
return Math.ceil(max / 4.5) * 5;
},
_unique(arr) {
return Array.from(new Set(arr));
}
},
watch: {

View File

@ -246,11 +246,6 @@
</script>
<style scoped>
.table-page {
padding-top: 20px;
margin-right: -9px;
float: right;
}
.org-member-name {
float: left;

View File

@ -27,7 +27,7 @@
:total="total"/>
</el-card>
<el-dialog :title="$t('workspace.create')" :visible.sync="createVisible" width="30%">
<el-dialog :title="$t('workspace.create')" :visible.sync="dialogWsAddVisible" width="30%">
<el-form :model="form" :rules="rules" ref="form" label-position="right" label-width="100px" size="small">
<el-form-item :label="$t('commons.name')" prop="name">
<el-input v-model="form.name" autocomplete="off"/>
@ -45,8 +45,8 @@
</el-dialog>
<!-- dialog of workspace member -->
<el-dialog :visible.sync="memberVisible" width="70%" :destroy-on-close="true" @close="closeMemberFunc">
<ms-table-header :condition.sync="dialogCondition" @create="addMember"
<el-dialog :visible.sync="dialogWsMemberVisible" width="70%" :destroy-on-close="true" @close="closeMemberFunc">
<ms-table-header :condition.sync="dialogCondition" @create="addMember" @search="wsMemberList"
:create-tip="dialogBtnTips" :title="$t('commons.member')"/>
<!-- organization member table -->
<el-table :data="memberLineData" style="width: 100%;margin-top: 5px;">
@ -69,12 +69,12 @@
</template>
</el-table-column>
</el-table>
<ms-table-pagination :change="wsMemberList" :current-page.sync="currentMemberPage" :page-size.sync="pageMemberSize"
:total="memberTotal"/>
<ms-table-pagination :change="wsMemberList" :current-page.sync="dialogCurrentPage" :page-size.sync="dialogPageSize"
:total="dialogTotal"/>
</el-dialog>
<!-- add workspace member dialog -->
<el-dialog :title="$t('member.create')" :visible.sync="addMemberVisible" width="30%" :destroy-on-close="true"
<el-dialog :title="$t('member.create')" :visible.sync="dialogWsMemberAddVisible" width="30%" :destroy-on-close="true"
@close="closeFunc">
<el-form :model="memberForm" ref="form" :rules="wsMemberRule" label-position="right" label-width="100px"
size="small">
@ -112,7 +112,7 @@
</el-dialog>
<!-- update workspace member dialog -->
<el-dialog :title="$t('member.modify')" :visible.sync="updateMemberVisible" width="30%" :destroy-on-close="true"
<el-dialog :title="$t('member.modify')" :visible.sync="dialogWsMemberUpdateVisible" width="30%" :destroy-on-close="true"
@close="closeFunc">
<el-form :model="memberForm" label-position="right" label-width="100px" size="small" ref="updateUserForm">
<el-form-item label="ID" prop="id">
@ -171,7 +171,7 @@
},
methods: {
create() {
this.createVisible = true;
this.dialogWsAddVisible = true;
this.form = {};
},
submit(formName) {
@ -182,7 +182,7 @@
saveType = 'update'
}
this.$post("/workspace/" + saveType, this.form, () => {
this.createVisible = false;
this.dialogWsAddVisible = false;
this.list();
Message.success(this.$t('commons.save_success'));
});
@ -192,16 +192,8 @@
});
},
edit(row) {
this.createVisible = true;
this.dialogWsAddVisible = true;
this.form = row;
// let self = this;
// let getUser1 = this.$get("/test/user");
// let getUser2 = this.$get("/test/sleep");
// this.$all([getUser1, getUser2], function (r1, r2) {
// window.console.log(r1.data.data, r2.data.data);
// self.loading = false;
// });
},
del(row) {
this.$confirm(this.$t('workspace.delete_confirm'), '', {
@ -250,7 +242,7 @@
},
addMember() {
this.addMemberVisible = true;
this.dialogWsMemberAddVisible = true;
this.memberForm = {};
this.result = this.$get('/user/list/', response => {
this.$set(this.memberForm, "userList", response.data);
@ -262,7 +254,7 @@
cellClick(row) {
// currentRow
this.currentWorkspaceRow = row;
this.memberVisible = true;
this.dialogWsMemberVisible = true;
let param = {
name: '',
workspaceId: row.id
@ -279,16 +271,14 @@
this.$set(this.memberLineData[i], "roles", roles);
})
}
this.memberTotal = data.itemCount;
this.dialogTotal = data.itemCount;
});
},
wsMemberList() {
let row = this.currentWorkspaceRow;
this.memberVisible = true;
let param = {
name: '',
workspaceId: row.id
};
this.dialogWsMemberVisible = true;
let param = this.dialogCondition;
this.$set(param, 'workspaceId', row.id);
let path = "/user/ws/member/list";
this.result = this.$post(this.buildPagePath(path), param, res => {
let data = res.data;
@ -301,7 +291,7 @@
this.$set(this.memberLineData[i], "roles", roles);
})
}
this.memberTotal = data.itemCount;
this.dialogTotal = data.itemCount;
});
},
closeFunc() {
@ -321,7 +311,7 @@
};
this.result = this.$post("user/ws/member/add", param, () => {
this.cellClick(this.currentWorkspaceRow);
this.addMemberVisible = false;
this.dialogWsMemberAddVisible = false;
})
} else {
return false;
@ -329,7 +319,7 @@
});
},
editMember(row) {
this.updateMemberVisible = true;
this.dialogWsMemberUpdateVisible = true;
this.memberForm = row;
let roleIds = this.memberForm.roles.map(r => r.id);
this.result = this.$get('/role/list/test', response => {
@ -363,19 +353,21 @@
}
this.result = this.$post("/workspace/member/update", param, () => {
this.$success(this.$t('commons.modify_success'));
this.updateMemberVisible = false;
this.dialogWsMemberUpdateVisible = false;
this.cellClick(this.currentWorkspaceRow);
});
},
buildPagePath(path) {
return path + "/" + this.currentMemberPage + "/" + this.pageMemberSize;
return path + "/" + this.dialogCurrentPage + "/" + this.dialogPageSize;
},
},
data() {
return {
result: {},
loading: false,
createVisible: false,
dialogWsAddVisible: false,
dialogWsMemberVisible: false,
dialogWsMemberAddVisible: false,
dialogWsMemberUpdateVisible: false,
btnTips: this.$t('workspace.create'),
dialogBtnTips: this.$t('member.create'),
addTips: this.$t('member.create'),
@ -385,13 +377,9 @@
currentPage: 1,
pageSize: 5,
total: 0,
updateVisible: false,
memberVisible: false,
addMemberVisible: false,
updateMemberVisible: false,
currentMemberPage: 1,
pageMemberSize: 5,
memberTotal: 0,
dialogCurrentPage: 1,
dialogPageSize: 5,
dialogTotal: 0,
memberLineData: [],
memberForm: {},
form: {
@ -419,33 +407,16 @@
</script>
<style scoped>
.search {
width: 240px;
}
.edit {
opacity: 0;
}
.el-table__row:hover .edit {
opacity: 1;
}
.table-page {
padding-top: 20px;
margin-right: -9px;
float: right;
}
.member-size {
text-decoration: underline;
cursor: pointer;
}
.member-title {
margin-bottom: 30px;
}
.select-width {
width: 100%;
}

View File

@ -3,7 +3,7 @@
<el-card>
<template v-slot:header>
<ms-table-header :condition.sync="condition" @search="search" @create="create"
<ms-table-header :condition.sync="condition" @search="initTableData" @create="create"
:create-tip="btnTips" :title="$t('commons.organization')"/>
</template>
<!-- system menu organization table-->
@ -29,9 +29,10 @@
<ms-table-pagination :change="initTableData" :current-page.sync="currentPage" :page-size.sync="pageSize"
:total="total"/>
</el-card>
<!-- dialog of organization member -->
<el-dialog :visible.sync="memberVisible" width="70%" :destroy-on-close="true" @close="closeMemberFunc">
<ms-table-header :condition.sync="dialogCondition" @create="addMember"
<el-dialog :visible.sync="dialogOrgMemberVisible" width="70%" :destroy-on-close="true" @close="closeMemberFunc">
<ms-table-header :condition.sync="dialogCondition" @create="addMember" @search="orgMemberList"
:create-tip="dialogBtnTips" :title="$t('commons.member')"/>
<!-- organization member table -->
<el-table :data="memberLineData" style="width: 100%;margin-top:5px;">
@ -54,13 +55,13 @@
</template>
</el-table-column>
</el-table>
<ms-table-pagination :change="orgMemberList" :current-page.sync="currentMemberPage"
:page-size.sync="pageMemberSize"
:total="memberTotal"/>
<ms-table-pagination :change="orgMemberList" :current-page.sync="dialogCurrentPage"
:page-size.sync="dialogPageSize"
:total="dialogTotal"/>
</el-dialog>
<!-- add organization form -->
<el-dialog :title="$t('organization.create')" :visible.sync="createVisible" width="30%" @closed="closeFunc"
<el-dialog :title="$t('organization.create')" :visible.sync="dialogOrgAddVisible" width="30%" @closed="closeFunc"
:destroy-on-close="true">
<el-form :model="form" label-position="right" label-width="100px" size="small" :rules="rule"
ref="createOrganization">
@ -80,7 +81,8 @@
</el-dialog>
<!-- update organization form -->
<el-dialog :title="$t('organization.modify')" :visible.sync="updateVisible" width="30%" :destroy-on-close="true"
<el-dialog :title="$t('organization.modify')" :visible.sync="dialogOrgUpdateVisible" width="30%"
:destroy-on-close="true"
@close="closeFunc">
<el-form :model="form" label-position="right" label-width="100px" size="small" :rules="rule"
ref="updateOrganizationForm">
@ -101,7 +103,8 @@
</el-dialog>
<!-- add organization member form -->
<el-dialog :title="$t('member.create')" :visible.sync="addMemberVisible" width="30%" :destroy-on-close="true"
<el-dialog :title="$t('member.create')" :visible.sync="dialogOrgMemberAddVisible" width="30%"
:destroy-on-close="true"
@close="closeFunc">
<el-form :model="memberForm" ref="form" :rules="orgMemberRule" label-position="right" label-width="100px"
size="small">
@ -139,7 +142,8 @@
</el-dialog>
<!-- update organization member form -->
<el-dialog :title="$t('member.modify')" :visible.sync="updateMemberVisible" width="30%" :destroy-on-close="true"
<el-dialog :title="$t('member.modify')" :visible.sync="dialogOrgMemberUpdateVisible" width="30%"
:destroy-on-close="true"
@close="closeFunc">
<el-form :model="memberForm" label-position="right" label-width="100px" size="small" ref="updateUserForm">
<el-form-item label="ID" prop="id">
@ -192,18 +196,18 @@
createPath: '/organization/add',
updatePath: '/organization/update',
result: {},
createVisible: false,
updateVisible: false,
memberVisible: false,
addMemberVisible: false,
updateMemberVisible: false,
dialogOrgAddVisible: false,
dialogOrgUpdateVisible: false,
dialogOrgMemberVisible: false,
dialogOrgMemberAddVisible: false,
dialogOrgMemberUpdateVisible: false,
multipleSelection: [],
currentPage: 1,
pageSize: 5,
total: 0,
currentMemberPage: 1,
pageMemberSize: 5,
memberTotal: 0,
dialogCurrentPage: 1,
dialogPageSize: 5,
dialogTotal: 0,
currentRow: {},
btnTips: this.$t('organization.create'),
dialogBtnTips: this.$t('member.create'),
@ -243,10 +247,10 @@
},
methods: {
create() {
this.createVisible = true;
this.dialogOrgAddVisible = true;
},
addMember() {
this.addMemberVisible = true;
this.dialogOrgMemberAddVisible = true;
this.memberForm = {};
this.result = this.$get('/user/list/', response => {
this.$set(this.memberForm, "userList", response.data);
@ -256,11 +260,11 @@
})
},
edit(row) {
this.updateVisible = true;
this.dialogOrgUpdateVisible = true;
this.form = row;
},
editMember(row) {
this.updateMemberVisible = true;
this.dialogOrgMemberUpdateVisible = true;
this.memberForm = row;
let roleIds = this.memberForm.roles.map(r => r.id);
this.result = this.$get('/role/list/org', response => {
@ -272,13 +276,13 @@
cellClick(row) {
// currentRow
this.currentRow = row;
this.memberVisible = true;
this.dialogOrgMemberVisible = true;
let param = {
name: '',
organizationId: row.id
};
let path = "/user/special/org/member/list";
this.result = this.$post(path + "/" + this.currentMemberPage + "/" + this.pageMemberSize, param, res => {
this.result = this.$post(path + "/" + this.dialogCurrentPage + "/" + this.dialogPageSize, param, res => {
let data = res.data;
this.memberLineData = data.listObject;
let url = "/userrole/list/org/" + row.id;
@ -288,18 +292,16 @@
this.$set(this.memberLineData[i], "roles", roles);
})
}
this.memberTotal = data.itemCount;
this.dialogTotal = data.itemCount;
});
},
orgMemberList() {
let row = this.currentRow;
this.memberVisible = true;
let param = {
name: '',
organizationId: row.id
};
this.dialogOrgMemberVisible = true;
let param = this.dialogCondition;
this.$set(param, 'organizationId', row.id);
let path = "/user/special/org/member/list";
this.result = this.$post(path + "/" + this.currentMemberPage + "/" + this.pageMemberSize, param, res => {
this.result = this.$post(path + "/" + this.dialogCurrentPage + "/" + this.dialogPageSize, param, res => {
let data = res.data;
this.memberLineData = data.listObject;
let url = "/userrole/list/org/" + row.id;
@ -309,7 +311,7 @@
this.$set(this.memberLineData[i], "roles", roles);
})
}
this.memberTotal = data.itemCount;
this.dialogTotal = data.itemCount;
});
},
del(row) {
@ -346,7 +348,7 @@
this.result = this.$post(this.createPath, this.form, () => {
this.$success(this.$t('commons.save_success'));
this.initTableData();
this.createVisible = false;
this.dialogOrgAddVisible = false;
});
} else {
return false;
@ -358,7 +360,7 @@
if (valide) {
this.result = this.$post(this.updatePath, this.form, () => {
this.$success(this.$t('commons.modify_success'))
this.updateVisible = false;
this.dialogOrgUpdateVisible = false;
this.initTableData();
});
} else {
@ -366,9 +368,6 @@
}
})
},
search() {
this.initTableData();
},
initTableData() {
this.result = this.$post(this.queryPath + "/" + this.currentPage + "/" + this.pageSize, this.condition, response => {
let data = response.data;
@ -407,7 +406,7 @@
};
this.result = this.$post("user/special/org/member/add", param, () => {
this.cellClick(this.currentRow);
this.addMemberVisible = false;
this.dialogOrgMemberAddVisible = false;
})
} else {
return false;
@ -425,7 +424,7 @@
}
this.result = this.$post("/organization/member/update", param, () => {
this.$success(this.$t('commons.modify_success'))
this.updateMemberVisible = false;
this.dialogOrgMemberUpdateVisible = false;
this.cellClick(this.currentRow);
});
},
@ -435,15 +434,6 @@
</script>
<style scoped>
.search {
width: 240px;
}
.table-page {
padding-top: 20px;
margin-right: -9px;
float: right;
}
.member-size {
text-decoration: underline;
@ -464,7 +454,4 @@
width: 100%;
}
.member-title {
margin-bottom: 30px;
}
</style>

View File

@ -28,7 +28,7 @@
</el-card>
<!-- add workspace dialog -->
<el-dialog :title="$t('workspace.create')" :visible.sync="createVisible" width="30%">
<el-dialog :title="$t('workspace.create')" :visible.sync="dialogWsAddVisible" width="30%">
<el-form :model="form" :rules="rules" ref="form" label-position="right" label-width="100px" size="small">
<el-form-item :label="$t('commons.name')" prop="name">
<el-input v-model="form.name" autocomplete="off"/>
@ -56,7 +56,7 @@
</el-dialog>
<!-- update workspace dialog -->
<el-dialog :title="$t('workspace.update')" :visible.sync="updateVisible" width="30%">
<el-dialog :title="$t('workspace.update')" :visible.sync="dialogWsUpdateVisible" width="30%">
<el-form :model="form" :rules="rules" ref="updateForm" label-position="right" label-width="100px" size="small">
<el-form-item :label="$t('commons.name')" prop="name">
<el-input v-model="form.name" autocomplete="off"/>
@ -86,8 +86,8 @@
</el-dialog>
<!-- dialog of workspace member -->
<el-dialog :visible.sync="memberVisible" width="70%" :destroy-on-close="true" @close="closeMemberFunc">
<ms-table-header :condition.sync="dialogCondition" @create="addMember"
<el-dialog :visible.sync="dialogWsMemberVisible" width="70%" :destroy-on-close="true" @close="closeMemberFunc">
<ms-table-header :condition.sync="dialogCondition" @create="addMember" @search="wsMemberList"
:create-tip="dialogBtnTips" :title="$t('commons.member')"/>
<!-- organization member table -->
<el-table :data="memberLineData" style="width: 100%;margin-top: 5px;">
@ -110,13 +110,13 @@
</template>
</el-table-column>
</el-table>
<ms-table-pagination :change="wsMemberList" :current-page.sync="currentMemberPage"
:page-size.sync="pageMemberSize"
:total="memberTotal"/>
<ms-table-pagination :change="wsMemberList" :current-page.sync="dialogCurrentPage"
:page-size.sync="dialogPageSize"
:total="dialogTotal"/>
</el-dialog>
<!-- add workspace member dialog -->
<el-dialog :title="$t('member.create')" :visible.sync="addMemberVisible" width="30%" :destroy-on-close="true"
<el-dialog :title="$t('member.create')" :visible.sync="dialogWsMemberAddVisible" width="30%" :destroy-on-close="true"
@close="closeFunc">
<el-form :model="memberForm" ref="form" :rules="wsMemberRule" label-position="right" label-width="100px"
size="small">
@ -153,7 +153,7 @@
</el-dialog>
<!-- update workspace member dialog -->
<el-dialog :title="$t('member.modify')" :visible.sync="updateMemberVisible" width="30%" :destroy-on-close="true"
<el-dialog :title="$t('member.modify')" :visible.sync="dialogWsMemberUpdateVisible" width="30%" :destroy-on-close="true"
@close="closeFunc">
<el-form :model="memberForm" label-position="right" label-width="100px" size="small" ref="updateUserForm">
<el-form-item label="ID" prop="id">
@ -206,7 +206,7 @@
},
methods: {
create() {
this.createVisible = true;
this.dialogWsAddVisible = true;
this.form = {};
this.$get("/organization/list", response => {
this.$set(this.form, "orgList", response.data);
@ -220,7 +220,7 @@
saveType = 'update'
}
this.result = this.$post("/workspace/" + saveType, this.form, () => {
this.createVisible = false;
this.dialogWsAddVisible = false;
this.list();
Message.success(this.$t('commons.save_success'));
});
@ -230,7 +230,7 @@
});
},
addMember() {
this.addMemberVisible = true;
this.dialogWsMemberAddVisible = true;
this.memberForm = {};
this.result = this.$get('/user/list/', response => {
this.$set(this.memberForm, "userList", response.data);
@ -242,13 +242,13 @@
cellClick(row) {
// currentRow
this.currentWorkspaceRow = row;
this.memberVisible = true;
this.dialogWsMemberVisible = true;
let param = {
name: '',
workspaceId: row.id
};
let path = "/user/special/ws/member/list";
this.result = this.$post(this.buildPagePath(path), param, res => {
this.result = this.$post(path + "/" + this.dialogCurrentPage + "/" + this.dialogPageSize, param, res => {
let data = res.data;
this.memberLineData = data.listObject;
let url = "/userrole/list/ws/" + row.id;
@ -259,18 +259,16 @@
this.$set(this.memberLineData[i], "roles", roles);
})
}
this.memberTotal = data.itemCount;
this.dialogTotal = data.itemCount;
});
},
wsMemberList() {
let row = this.currentWorkspaceRow;
this.memberVisible = true;
let param = {
name: '',
workspaceId: row.id
};
this.dialogWsMemberVisible = true;
let param = this.dialogCondition;
this.$set(param, 'workspaceId', row.id);
let path = "/user/special/ws/member/list";
this.result = this.$post(this.buildPagePath(path), param, res => {
this.result = this.$post(path + "/" + this.dialogCurrentPage + "/" + this.dialogPageSize, param, res => {
let data = res.data;
this.memberLineData = data.listObject;
let url = "/userrole/list/ws/" + row.id;
@ -281,11 +279,11 @@
this.$set(this.memberLineData[i], "roles", roles);
})
}
this.memberTotal = data.itemCount;
this.dialogTotal = data.itemCount;
});
},
edit(row) {
this.updateVisible = true;
this.dialogWsUpdateVisible = true;
// copy user
this.form = Object.assign({}, row);
this.$get("/organization/list", response => {
@ -297,7 +295,7 @@
if (valide) {
this.result = this.$post("/workspace/special/update", this.form, () => {
this.$success(this.$t('commons.modify_success'));
this.updateVisible = false;
this.dialogWsUpdateVisible = false;
this.list();
});
} else {
@ -348,9 +346,6 @@
this.total = data.itemCount;
});
},
buildPagePath(path) {
return path + "/" + this.currentMemberPage + "/" + this.pageMemberSize;
},
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
@ -361,7 +356,7 @@
};
this.result = this.$post("user/special/ws/member/add", param, () => {
this.cellClick(this.currentWorkspaceRow);
this.addMemberVisible = false;
this.dialogWsMemberAddVisible = false;
})
} else {
return false;
@ -369,7 +364,7 @@
});
},
editMember(row) {
this.updateMemberVisible = true;
this.dialogWsMemberUpdateVisible = true;
this.memberForm = row;
let roleIds = this.memberForm.roles.map(r => r.id);
this.result = this.$get('/role/list/test', response => {
@ -403,7 +398,7 @@
}
this.result = this.$post("/workspace/member/update", param, () => {
this.$success(this.$t('commons.modify_success'));
this.updateMemberVisible = false;
this.dialogWsMemberUpdateVisible = false;
this.cellClick(this.currentWorkspaceRow);
});
},
@ -411,11 +406,11 @@
data() {
return {
result: {},
createVisible: false,
updateVisible: false,
memberVisible: false,
addMemberVisible: false,
updateMemberVisible: false,
dialogWsAddVisible: false,
dialogWsUpdateVisible: false,
dialogWsMemberVisible: false,
dialogWsMemberAddVisible: false,
dialogWsMemberUpdateVisible: false,
btnTips: this.$t('workspace.create'),
dialogBtnTips: this.$t('member.create'),
addTips: this.$t('member.create'),
@ -425,9 +420,9 @@
currentPage: 1,
pageSize: 5,
total: 0,
currentMemberPage: 1,
pageMemberSize: 5,
memberTotal: 0,
dialogCurrentPage: 1,
dialogPageSize: 5,
dialogTotal: 0,
memberLineData: [],
memberForm: {},
form: {
@ -458,24 +453,11 @@
</script>
<style scoped>
.search {
width: 240px;
}
.edit {
opacity: 0;
}
.el-table__row:hover .edit {
opacity: 1;
}
.table-page {
padding-top: 20px;
margin-right: -9px;
float: right;
}
.member-size {
text-decoration: underline;
cursor: pointer;
@ -495,9 +477,5 @@
width: 100%;
}
.member-title {
margin-bottom: 30px;
}
</style>

View File

@ -422,19 +422,6 @@
</script>
<style scoped>
.search {
width: 240px;
}
.form-input {
height: 32px !important;
}
.table-page {
padding-top: 20px;
margin-right: -9px;
float: right;
}
.op {
float: left;

View File

@ -244,13 +244,5 @@
</script>
<style scoped>
.search {
width: 240px;
}
.table-page {
padding-top: 20px;
margin-right: -9px;
float: right;
}
</style>

View File

@ -255,20 +255,11 @@
</script>
<style scoped>
.search {
width: 240px;
}
.el-table__row:hover .edit {
opacity: 1;
}
.table-page {
padding-top: 20px;
margin-right: -9px;
float: right;
}
.select-width {
width: 100%;
}

View File

@ -26,6 +26,18 @@
}
</script>
<style>
.tree-aside {
position: relative;
border: 1px solid #EBEEF5;
box-sizing: border-box;
background: white;
}
</style>
<style scoped>
</style>

View File

@ -14,6 +14,7 @@
@refresh="refresh"
:tree-nodes="treeNodes"
:type="'edit'"
:select-node.sync="selectNode"
ref="nodeTree"/>
</el-aside>
@ -26,6 +27,7 @@
@testCaseCopy="copyTestCase"
@testCaseDetail="showTestCaseDetail"
@refresh="refresh"
@moveToNode="moveToNode"
ref="testCaseList">
</test-case-list>
</el-main>
@ -35,8 +37,12 @@
@refresh="refresh"
:read-only="testCaseReadOnly"
:tree-nodes="treeNodes"
:select-node="selectNode"
ref="testCaseEditDialog">
</test-case-edit>
<test-case-move @refresh="refresh" ref="testCaseMove"/>
</div>
</template>
@ -47,10 +53,11 @@
import {CURRENT_PROJECT} from '../../../../common/js/constants';
import TestCaseList from "./components/TestCaseList";
import SelectMenu from "../common/SelectMenu";
import TestCaseMove from "./components/TestCaseMove";
export default {
name: "TestCase",
components: {TestCaseList, NodeTree, TestCaseEdit, SelectMenu},
components: {TestCaseMove, TestCaseList, NodeTree, TestCaseEdit, SelectMenu},
comments: {},
data() {
return {
@ -63,7 +70,8 @@
treeNodes: [],
selectNodeIds: [],
selectNodeNames: [],
testCaseReadOnly: true
testCaseReadOnly: true,
selectNode: {},
}
},
mounted() {
@ -162,6 +170,7 @@
refresh() {
this.selectNodeIds = [];
this.selectNodeNames = [];
this.selectNode = {};
this.$refs.testCaseList.initTableData();
this.getNodeTree();
},
@ -170,7 +179,8 @@
this.getProjectByCaseId(caseId);
this.$get('/test/case/get/' + caseId, response => {
if (response.data) {
this.openTestCaseEditDialog(response.data);
this.testCaseReadOnly = false;
this.$refs.testCaseEditDialog.open(response.data);
}
});
},
@ -198,6 +208,14 @@
this.treeNodes = response.data;
});
}
},
moveToNode(selectIds) {
if (selectIds.size < 1) {
this.$warning(this.$t('test_track.plan_view.select_manipulate'));
return;
}
this.$refs.testCaseEditDialog.getModuleOptions();
this.$refs.testCaseMove.open(this.$refs.testCaseEditDialog.moduleOptions, selectIds);
}
}
}
@ -209,13 +227,6 @@
margin: 3%;
}
.tree-aside {
position: relative;
border: 1px solid #EBEEF5;
box-sizing: border-box;
background: white;
}
.case-container {
height: calc(100vh - 150px);
min-height: 600px;

View File

@ -2,7 +2,7 @@
<div>
<el-dialog :title="operationType == 'edit' ? $t('test_track.case.edit_case') : $t('test_track.case.create')" :visible.sync="dialogFormVisible" width="65%">
<el-dialog :title="operationType == 'edit' ? ( readOnly ? $t('test_track.case.view_case') : $t('test_track.case.edit_case')) : $t('test_track.case.create')" :visible.sync="dialogFormVisible" width="65%">
<el-form :model="form" :rules="rules" ref="caseFrom">
@ -13,12 +13,13 @@
:label="$t('test_track.case.name')"
:label-width="formLabelWidth"
prop="name">
<el-input :disabled="readOnly" v-model="form.name"></el-input>
<el-input :disabled="readOnly" v-model.trim="form.name"></el-input>
</el-form-item>
</el-col>
<el-col :span="11" :offset="2">
<el-form-item :label="$t('test_track.case.module')" :label-width="formLabelWidth" prop="module">
<el-select
v-model="form.module"
:disabled="readOnly"
@ -186,7 +187,7 @@
<script>
import {CURRENT_PROJECT, WORKSPACE_ID} from '../../../../../common/js/constants';
import {CURRENT_PROJECT, WORKSPACE_ID, TokenKey} from '../../../../../common/js/constants';
import MsDialogFooter from '../../../common/components/MsDialogFooter'
@ -236,8 +237,14 @@
readOnly: {
type: Boolean,
default: true
},
selectNode: {
type: Object
}
},
mounted() {
this.getSelectOptions();
},
methods: {
open(testCase) {
this.resetForm();
@ -255,6 +262,17 @@
tmp.steps = JSON.parse(testCase.steps);
Object.assign(this.form, tmp);
this.form.module = testCase.nodeId;
} else {
if (this.selectNode.data) {
this.form.module = this.selectNode.data.id;
} else {
this.form.module = this.moduleOptions[0].id;
}
let user = JSON.parse(localStorage.getItem(TokenKey));
this.form.priority = 'P3';
this.form.type = 'functional';
this.form.method = 'manual';
this.form.maintainer = user.id;
}
this.dialogFormVisible = true;
},
@ -294,7 +312,7 @@
param.projectId = JSON.parse(localStorage.getItem(CURRENT_PROJECT)).id;
}
this.$post('/test/case/' + this.operationType, param, () => {
this.$message.success(this.$t('commons.save_success'));
this.$success(this.$t('commons.save_success'));
this.dialogFormVisible = false;
this.$emit("refresh");
});

View File

@ -2,8 +2,6 @@
<div>
<ms-table-button icon="el-icon-upload2" :content="$t('test_track.case.import.import')" @click="dialogVisible = true"/>
<el-dialog width="30%" :title="$t('test_track.case.import.case_import')" :visible.sync="dialogVisible"
@close="init">
@ -41,7 +39,6 @@
</el-dialog>
</div>
</template>
@ -67,27 +64,20 @@
},
methods: {
handlePreview(file) {
console.log("init");
this.init();
},
handleExceed(files, fileList) {
this.$message.warning(this.$t('test_track.case.import.upload_limit_count'));
this.$warning(this.$t('test_track.case.import.upload_limit_count'));
},
UploadValidate(file) {
var suffix =file.name.substring(file.name.lastIndexOf('.') + 1);
if (suffix != 'xls' && suffix != 'xlsx') {
this.$message({
message: this.$t('test_track.case.import.upload_limit_format'),
type: 'warning'
});
this.$warning(this.$t('test_track.case.import.upload_limit_format'));
return false;
}
if (file.size / 1024 / 1024 > 20) {
this.$message({
message: this.$t('test_track.case.import.upload_limit_size'),
type: 'warning'
});
this.$warning(this.$t('test_track.case.import.upload_limit_size'));
return false;
}
return true;
@ -95,7 +85,7 @@
handleSuccess(response) {
let res = response.data;
if (res.success) {
this.$message.success(this.$t('test_track.case.import.success'));
this.$success(this.$t('test_track.case.import.success'));
this.dialogVisible = false;
this.$emit("refresh");
} else {
@ -104,11 +94,14 @@
this.fileList = [];
},
handleError(err, file, fileList) {
this.$message.error(err.message);
this.$error(err.message);
},
init() {
this.fileList = [];
this.errList = [];
},
open() {
this.dialogVisible = true;
}
}
}

View File

@ -10,17 +10,25 @@
<node-breadcrumb class="table-title" :node-names="selectNodeNames" @refresh="refresh"/>
</template>
<template v-slot:button>
<test-case-import :projectId="currentProject == null? null : currentProject.id" @refresh="refresh"/>
<ms-table-button icon="el-icon-upload2" :content="$t('test_track.case.import.import')" @click="importTestCase"/>
<ms-table-button icon="el-icon-right" :content="$t('test_track.case.move')" @click="moveToNode"/>
<!--<test-case-export/>-->
</template>
</ms-table-header>
</template>
<test-case-import :projectId="currentProject == null? null : currentProject.id" @refresh="refresh" ref="testCaseImport"/>
<el-table
:data="tableData"
@select-all="handleSelectAll"
@select="handleSelectionChange"
@row-click="showDetail"
row-key="id"
class="test-content">
<el-table-column
type="selection"/>
<el-table-column
prop="name"
:label="$t('commons.name')"
@ -65,7 +73,8 @@
<el-table-column
prop="updateTime"
sortable
:label="$t('commons.update_time')">
:label="$t('commons.update_time')"
show-overflow-tooltip>
<template v-slot:default="scope">
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
</template>
@ -103,10 +112,12 @@
import MethodTableItem from "../../common/tableItems/planview/MethodTableItem";
import MsTableOperator from "../../../common/components/MsTableOperator";
import MsTableOperatorButton from "../../../common/components/MsTableOperatorButton";
import MsTableButton from "../../../common/components/MsTableButton";
export default {
name: "TestCaseList",
components: {
MsTableButton,
MsTableOperatorButton,
MsTableOperator,
MethodTableItem,
@ -120,8 +131,9 @@
condition: {},
tableData: [],
currentPage: 1,
pageSize: 5,
pageSize: 10,
total: 0,
selectIds: new Set(),
priorityFilters: [
{text: 'P0', value: 'P0'},
{text: 'P1', value: 'P1'},
@ -169,6 +181,7 @@
let data = response.data;
this.total = data.itemCount;
this.tableData = data.listObject;
this.selectIds.clear();
});
}
},
@ -201,14 +214,12 @@
let testCaseId = testCase.id;
this.$post('/test/case/delete/' + testCaseId, {}, () => {
this.initTableData();
this.$message({
message: this.$t('commons.delete_success'),
type: 'success'
});
this.$success(this.$t('commons.delete_success'));
});
},
refresh() {
this.condition = {};
this.selectIds.clear();
this.$emit('refresh');
},
filter(value, row, column) {
@ -217,6 +228,28 @@
},
showDetail(row, event, column) {
this.$emit('testCaseDetail', row);
},
handleSelectAll(selection) {
if(selection.length > 0) {
this.tableData.forEach(item => {
this.selectIds.add(item.id);
});
} else {
this.selectIds.clear();
}
},
handleSelectionChange(selection, row) {
if(this.selectIds.has(row.id)){
this.selectIds.delete(row.id);
} else {
this.selectIds.add(row.id);
}
},
importTestCase() {
this.$refs.testCaseImport.open();
},
moveToNode() {
this.$emit('moveToNode', this.selectIds);
}
}
}

View File

@ -0,0 +1,82 @@
<template>
<el-dialog :title="$t('test_track.plan_view.change_executor')"
:visible.sync="dialogVisible"
:before-close="close"
width="20%">
<el-select v-model.trim="module"
:placeholder="$t('test_track.plan_view.select_executor')"
filterable>
<el-option v-for="item in moduleOptions" :key="item.id"
:label="item.path" :value="item.id"></el-option>
</el-select>
<template v-slot:footer>
<ms-dialog-footer
@cancel="close"
@confirm="save"/>
</template>
</el-dialog>
</template>
<script>
import MsDialogFooter from '../../../common/components/MsDialogFooter';
export default {
name: "TestCaseMove",
components: {MsDialogFooter},
data() {
return {
dialogVisible: false,
module: '',
moduleOptions: [],
selectIds: []
}
},
methods: {
save() {
if (this.module === '') {
this.$warning(this.$t('test_track.plan_view.select_execute_result'));
return;
}
let param = {};
param.nodeId = this.module;
this.moduleOptions.forEach(item => {
if (item.id === this.module) {
param.nodePath = item.path;
}
});
if (this.module === '') {
this.$warning(this.$t('test_track.plan_view.select_executor'));
return;
}
param.ids = [...this.selectIds];
this.$post('/test/case/batch/edit' , param, () => {
this.$success(this.$t('commons.save_success'));
this.close();
this.$emit('refresh');
});
},
open(moduleOptions, selectIds) {
this.moduleOptions = moduleOptions;
this.selectIds = selectIds;
this.dialogVisible = true;
},
close() {
this.module = '';
this.selectIds = [];
this.dialogVisible = false;
}
}
}
</script>
<style scoped>
</style>

View File

@ -1,17 +1,18 @@
<template>
<el-dialog :title="$t('test_track.module.add_module')"
<el-dialog :title="type == 'edit' ? $t('test_track.module.rename') : $t('test_track.module.add_module')"
:visible.sync="dialogFormVisible"
:before-close="close"
width="30%">
<el-row type="flex" justify="center">
<el-col :span="18">
<el-form :model="form" :rules="rules">
<el-form :model="form" :rules="rules" ref="nodeForm">
<el-form-item
:label="$t('test_track.module.name')"
:label-width="formLabelWidth"
prop="name">
<el-input v-model="form.name" autocomplete="off"></el-input>
<el-input v-model.trim="form.name" autocomplete="off"></el-input>
</el-form-item>
</el-form>
</el-col>
@ -19,7 +20,7 @@
<template v-slot:footer>
<ms-dialog-footer
@cancel="dialogFormVisible = false"
@cancel="close"
@confirm="saveNode"/>
</template>
@ -59,12 +60,18 @@
this.dialogFormVisible = true;
},
saveNode() {
let param = {};
let url = this.buildParam(param);
this.$post(url, param, () => {
this.$message.success(this.$t('commons.save_success'));
this.$emit('refresh');
this.close();
this.$refs['nodeForm'].validate((valid) => {
if (valid) {
let param = {};
let url = this.buildParam(param);
this.$post(url, param, () => {
this.$success(this.$t('commons.save_success'));
this.$emit('refresh');
this.close();
});
} else {
return false;
}
});
},
buildParam(param, ) {

View File

@ -21,7 +21,7 @@
<template v-slot:default="{node,data}">
<span class="custom-tree-node father" @click="selectNode(node)">
<span class="custom-tree-node father" @click="handleNodeSelect(node)">
<span>{{node.label}}</span>
@ -44,9 +44,6 @@
</span>
<!--<span v-if="type == 'view'" class="custom-tree-node" @click="selectNode(node)">-->
<!--{{node.label}}$$-->
<!--</span>-->
</template>
</el-tree>
@ -70,8 +67,7 @@
defaultProps: {
children: 'children',
label: 'label'
},
// treeNodes: [],
}
};
},
props: {
@ -81,6 +77,9 @@
},
treeNodes: {
type: Array
},
selectNode: {
type: Object
}
},
watch: {
@ -119,19 +118,20 @@
const children = parent.data.children || parent.data;
const index = children.findIndex(d => d.id === data.id);
children.splice(index, 1);
this.$message.success(this.$t('commons.delete_success'));
this.$success(this.$t('commons.delete_success'));
this.$emit("refresh");
});
}
}
});
},
selectNode(node) {
handleNodeSelect(node) {
let nodeIds = [];
let nodeNames = [];
this.getChildNodeId(node, nodeIds);
this.getParentNodeName(node, nodeNames);
this.$emit("nodeSelectEvent", nodeIds, nodeNames);
this.$emit("update:selectNode", node);
},
getChildNodeId(rootNode, nodeIds) {
//ID

View File

@ -1,8 +1,8 @@
<template>
<div>
<ms-tag v-if="value == 'P0'" type="danger" :content="value"/>
<ms-tag v-if="value == 'P1'" effect="light" type="danger" :content="value"/>
<ms-tag v-if="value == 'P2'" type="warning" :content="value"/>
<ms-tag v-if="value == 'P1'" type="warning" :content="value"/>
<ms-tag v-if="value == 'P2'" effect="light" type="danger" :content="value"/>
<ms-tag v-if="value == 'P3'" effect="light" type="warning" :content="value"/>
</div>

View File

@ -2,7 +2,7 @@
<div>
<el-dialog :title="$t('test_track.plan.create_plan')"
<el-dialog :title="operationType == 'edit' ? $t('test_track.plan.edit_plan') : $t('test_track.plan.create_plan')"
:visible.sync="dialogFormVisible"
width="65%">
@ -15,7 +15,7 @@
:label="$t('test_track.plan.plan_name')"
:label-width="formLabelWidth"
prop="name">
<el-input v-model="form.name"></el-input>
<el-input v-model.trim="form.name"></el-input>
</el-form-item>
</el-col>
@ -54,10 +54,11 @@
<el-form-item :label="$t('test_track.plan.plan_stage')" :label-width="formLabelWidth" prop="stage">
<el-select v-model="form.stage" clearable :placeholder="$t('test_track.plan.input_plan_stage')">
<el-option :label="$t('test_track.plan.smoke_test')" value="smoke"></el-option>
<el-option :label="$t('test_track.plan.functional_test')" value="functional"></el-option>
<el-option :label="$t('test_track.plan.integration_testing')" value="integration"></el-option>
<!--<el-option :label="$t('test_track.plan.functional_test')" value="functional"></el-option>-->
<!--<el-option :label="$t('test_track.plan.integration_testing')" value="integration"></el-option>-->
<el-option :label="$t('test_track.plan.system_test')" value="system"></el-option>
<el-option :label="$t('test_track.plan.version_validation')" value="version"></el-option>
<el-option :label="$t('test_track.plan.regression_test')" value="regression"></el-option>
<!--<el-option :label="$t('test_track.plan.version_validation')" value="version"></el-option>-->
</el-select>
</el-form-item>
</el-col>
@ -150,7 +151,7 @@
Object.assign(param, this.form);
param.workspaceId = localStorage.getItem(WORKSPACE_ID);
this.$post('/test/plan/' + this.operationType, param, () => {
this.$message.success(this.$t('commons.save_success'));
this.$success(this.$t('commons.save_success'));
this.dialogFormVisible = false;
this.$emit("refresh");
});
@ -164,10 +165,7 @@
if (response.success) {
this.projects = response.data;
} else {
this.$message()({
type: 'warning',
message: response.message
});
this.$warning()(response.message);
}
});
},

View File

@ -38,6 +38,7 @@
<span v-if="scope.row.stage == 'functional'">{{$t('test_track.plan.functional_test')}}</span>
<span v-if="scope.row.stage == 'integration'">{{$t('test_track.plan.integration_testing')}}</span>
<span v-if="scope.row.stage == 'system'">{{$t('test_track.plan.system_test')}}</span>
<span v-if="scope.row.stage == 'regression'">{{$t('test_track.plan.regression_test')}}</span>
<span v-if="scope.row.stage == 'version'">{{$t('test_track.plan.version_validation')}}</span>
</template>
</el-table-column>
@ -47,13 +48,15 @@
show-overflow-tooltip>
</el-table-column>
<el-table-column
:label="$t('commons.create_time')">
:label="$t('commons.create_time')"
show-overflow-tooltip>
<template v-slot:default="scope">
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
</template>
</el-table-column>
<el-table-column
:label="$t('commons.update_time')">
:label="$t('commons.update_time')"
show-overflow-tooltip>
<template v-slot:default="scope">
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
</template>
@ -99,6 +102,13 @@
tableData: [],
}
},
watch: {
'$route'(to, from) {
if (to.path.indexOf("/track/plan/all") >= 0){
this.initTableData();
}
}
},
created() {
this.projectId = this.$route.params.projectId;
this.initTableData();
@ -134,10 +144,7 @@
let testPlanId = testPlan.id;
this.$post('/test/plan/delete/' + testPlanId, {}, () => {
this.initTableData();
this.$message({
message: this.$t('commons.delete_success'),
type: 'success'
});
this.$success(this.$t('commons.delete_success'));
});
},
intoPlan(row, event, column) {

View File

@ -122,13 +122,6 @@
min-height: 600px;
}
.tree-aside {
position: relative;
border: 1px solid #EBEEF5;
box-sizing: border-box;
background: white;
}
.el-main {
padding: 15px;
}

View File

@ -56,7 +56,7 @@
this.$post('/test/plan/case/batch/edit' , param, () => {
this.executor = '';
this.selectIds.clear();
this.$message.success(this.$t('commons.save_success'));
this.$success(this.$t('commons.save_success'));
this.executorEditVisible = false;
this.$emit('refresh');
});

View File

@ -43,7 +43,7 @@
saveStatus() {
let param = {};
if (this.status === '') {
this.$message.warning(this.$t('test_track.plan_view.select_execute_result'));
this.$warning(this.$t('test_track.plan_view.select_execute_result'));
return;
}
param.status = this.status;
@ -51,7 +51,7 @@
this.$post('/test/plan/case/batch/edit' , param, () => {
this.selectIds.clear();
this.status = '';
this.$message.success(this.$t('commons.save_success'));
this.$success(this.$t('commons.save_success'));
this.statusEditVisible = false;
this.$emit('refresh');
});

View File

@ -8,7 +8,7 @@
width="50%">
<el-container class="main-content">
<el-aside class="node-tree" width="250px">
<el-aside class="tree-aside" width="250px">
<node-tree class="node-tree"
@nodeSelectEvent="nodeChange"
@refresh="refresh"
@ -18,7 +18,7 @@
<el-container>
<el-main class="case-content" v-loading="result.loading">
<el-scrollbar style="height:100%">
<el-scrollbar>
<el-table
:data="testCases"
row-key="id"
@ -96,7 +96,7 @@
param.testCaseIds = [...this.selectIds];
this.$post('/test/plan/relevance' , param, () => {
this.selectIds.clear();
this.$message.success("保存成功");
this.$success("保存成功");
this.dialogFormVisible = false;
this.$emit('refresh');
});
@ -185,11 +185,17 @@
}
.case-content {
height: 100%;
height: 500px;
/*border: 1px solid #EBEEF5;*/
}
.main-content {
min-height: 300px;
/*border: 1px solid #EBEEF5;*/
}
.el-scrollbar {
height: 100%;
}
</style>

View File

@ -216,7 +216,7 @@
return;
}
this.$refs.drawer.closeDrawer();
this.$message.success(this.$t('commons.save_success'));
this.$success(this.$t('commons.save_success'));
this.$emit('refresh');
});
},

View File

@ -29,7 +29,8 @@
<el-table-column
prop="name"
:label="$t('commons.name')">
:label="$t('commons.name')"
show-overflow-tooltip>
</el-table-column>
<el-table-column
prop="priority"
@ -81,7 +82,8 @@
<el-table-column
sortable
prop="updateTime"
:label="$t('commons.update_time')">
:label="$t('commons.update_time')"
show-overflow-tooltip>
<template v-slot:default="scope">
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
</template>
@ -89,7 +91,9 @@
<el-table-column
:label="$t('commons.operating')">
<template v-slot:default="scope">
<ms-table-operator @editClick="handleEdit(scope.row, scope.$index)" @deleteClick="handleDelete(scope.row)"/>
<ms-table-operator-button :tip="$t('commons.edit')" icon="el-icon-edit" @exec="handleEdit(scope.row)" />
<ms-table-operator-button :tip="$t('test_track.plan_view.cancel_relevance')" icon="el-icon-unlock" type="danger" @exec="handleDelete(scope.row)"/>
<!--<ms-table-operator @editClick="handleEdit(scope.row, scope.$index)" @deleteClick="handleDelete(scope.row)"/>-->
</template>
</el-table-column>
</el-table>
@ -123,10 +127,12 @@
import TypeTableItem from "../../../common/tableItems/planview/TypeTableItem";
import MethodTableItem from "../../../common/tableItems/planview/MethodTableItem";
import MsTableOperator from "../../../../common/components/MsTableOperator";
import MsTableOperatorButton from "../../../../common/components/MsTableOperatorButton";
export default {
name: "TestPlanTestCaseList",
components: {
MsTableOperatorButton,
MsTableOperator,
MethodTableItem,
TypeTableItem,
@ -141,7 +147,7 @@
showMyTestCase: false,
tableData: [],
currentPage: 1,
pageSize: 5,
pageSize: 10,
total: 0,
selectIds: new Set(),
priorityFilters: [
@ -198,11 +204,13 @@
let data = response.data;
this.total = data.itemCount;
this.tableData = data.listObject;
this.selectIds.clear();
});
}
},
refresh() {
this.condition = {};
this.selectIds.clear();
this.$emit('refresh');
},
search() {
@ -228,10 +236,7 @@
let testCaseId = testCase.id;
this.$post('/test/plan/case/delete/' + testCaseId, {}, () => {
this.$emit("refresh");
this.$message({
message: this.$t('commons.delete_success'),
type: 'success'
});
this.$success(this.$t('commons.delete_success'));
});
},
handleSelectAll(selection) {
@ -252,7 +257,7 @@
},
handleBatch(type){
if (this.selectIds.size < 1) {
this.$message.warning(this.$t('test_track.plan_view.select_manipulate'));
this.$warning(this.$t('test_track.plan_view.select_manipulate'));
return;
}
if (type === 'executor'){

View File

@ -185,10 +185,12 @@ export default {
recent_plan: "Recent plan",
recent_case: "Recent case",
case: {
test_case: "Test Case",
case_list: "Test Case List",
create_case: "Create Case",
eitd_case: "Eidt Case",
test_case: "Test case",
move: "Move case",
case_list: "Test case list",
create_case: "Create case",
edit_case: "Edit case",
view_case: "Test case",
no_project: "There is no project in this workspace, please create the project first",
priority: "Priority",
type: "Type",
@ -233,14 +235,16 @@ export default {
plan: {
test_plan: "Test Plan",
create_plan: "Create test plan",
edit_plan: "Edit test plan",
plan_name: "Test plan name",
plan_project: "Related project",
plan_stage: "Testing phase",
plan_status: "Status",
smoke_test: "Smoke test",
functional_test: "Functional test",
integration_testing: "Integration testing",
integration_testing: "Integration test",
system_test: "System test",
regression_test: "Regression test",
version_validation: "Version validation",
plan_principal: "Principal",
input_plan_name: "Please input plan name",
@ -280,6 +284,7 @@ export default {
change_executor: "Change executor",
select_executor: "Select executor",
select_execute_result: "Select execute result",
cancel_relevance: "Cancel relevance",
confirm_cancel_relevance: "Confirm cancel relevance",
select_manipulate: "Select the data you want to manipulate",
}

View File

@ -231,9 +231,11 @@ export default {
recent_case: "最近的用例",
case: {
test_case: "测试用例",
move: "移动用例",
case_list: "用例列表",
create_case: "创建用例",
edit_case: "编辑用例",
view_case: "查看用例",
no_project: "该工作空间下无项目,请先创建项目",
priority: "优先级",
type: "类型",
@ -276,12 +278,14 @@ export default {
plan: {
test_plan: "测试计划",
create_plan: "创建测试计划",
edit_plan: "编辑测试计划",
plan_name: "计划名称",
plan_project: "所属项目",
plan_stage: "测试阶段",
plan_status: "当前状态",
smoke_test: "冒烟测试",
functional_test: "功能测试",
regression_test: "回归测试",
integration_testing: "集成测试",
system_test: "系统测试",
version_validation: "版本验证",
@ -323,6 +327,7 @@ export default {
change_executor: "更改执行人",
select_executor: "请选择执行人",
select_execute_result: "选择执行结果",
cancel_relevance: "取消关联",
confirm_cancel_relevance: "确认取消关联",
select_manipulate: "请选择需要操作的数据",
}

3
package-lock.json generated Normal file
View File

@ -0,0 +1,3 @@
{
"lockfileVersion": 1
}