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.PageUtils;
import io.metersphere.commons.utils.Pager; import io.metersphere.commons.utils.Pager;
import io.metersphere.controller.request.testcase.QueryTestCaseRequest; 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.excel.domain.ExcelResponse;
import io.metersphere.service.TestCaseService; import io.metersphere.service.TestCaseService;
import io.metersphere.user.SessionUtils; import io.metersphere.user.SessionUtils;
@ -82,5 +84,9 @@ public class TestCaseController {
testCaseService.testCaseTemplateExport(response); 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.Page;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import io.metersphere.base.domain.TestCaseWithBLOBs;
import io.metersphere.base.domain.TestPlanTestCase; import io.metersphere.base.domain.TestPlanTestCase;
import io.metersphere.commons.utils.PageUtils; import io.metersphere.commons.utils.PageUtils;
import io.metersphere.commons.utils.Pager; import io.metersphere.commons.utils.Pager;
import io.metersphere.controller.request.testcase.QueryTestCaseRequest; import io.metersphere.controller.request.testcase.TestPlanCaseBatchRequest;
import io.metersphere.controller.request.testcase.TestCaseBatchRequest;
import io.metersphere.controller.request.testplancase.QueryTestPlanCaseRequest; import io.metersphere.controller.request.testplancase.QueryTestPlanCaseRequest;
import io.metersphere.dto.TestPlanCaseDTO; import io.metersphere.dto.TestPlanCaseDTO;
import io.metersphere.service.TestPlanTestCaseService; import io.metersphere.service.TestPlanTestCaseService;
@ -40,7 +38,7 @@ public class TestPlanTestCaseController {
} }
@PostMapping("/batch/edit") @PostMapping("/batch/edit")
public void editTestCaseBath(@RequestBody TestCaseBatchRequest request){ public void editTestCaseBath(@RequestBody TestPlanCaseBatchRequest request){
testPlanTestCaseService.editTestCaseBath(request); testPlanTestCaseService.editTestCaseBath(request);
} }

View File

@ -1,19 +1,19 @@
package io.metersphere.controller.request.testcase; 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 io.metersphere.base.domain.TestPlanTestCase;
import java.util.List; 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; return ids;
} }
public void setIds(List<Integer> ids) { public void setIds(List<String> ids) {
this.ids = 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(); JSONArray jsonArray = new JSONArray();
String[] stepDesc = new String[0]; String[] stepDesc = new String[1];
String[] stepRes = new String[0]; String[] stepRes = new String[1];
if (data.getStepDesc() != null) { if (data.getStepDesc() != null) {
stepDesc = data.getStepDesc().split("\n"); stepDesc = data.getStepDesc().split("\n");
} else {
stepDesc[0] = "";
} }
if (data.getStepResult() != null) { if (data.getStepResult() != null) {
stepRes = data.getStepResult().split("\n"); stepRes = data.getStepResult().split("\n");
} else {
stepRes[0] = "";
} }
String pattern = "(^\\d+)(\\.)?"; String pattern = "(^\\d+)(\\.)?";

View File

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

View File

@ -1,16 +1,17 @@
package io.metersphere.service; package io.metersphere.service;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcelFactory; import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import io.metersphere.base.domain.*; import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.*; import io.metersphere.base.mapper.*;
import io.metersphere.base.mapper.ext.ExtTestCaseMapper; import io.metersphere.base.mapper.ext.ExtTestCaseMapper;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.BeanUtils;
import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.LogUtil;
import io.metersphere.controller.request.testcase.QueryTestCaseRequest; 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.ExcelErrData;
import io.metersphere.excel.domain.ExcelResponse; import io.metersphere.excel.domain.ExcelResponse;
import io.metersphere.excel.domain.TestCaseExcelData; import io.metersphere.excel.domain.TestCaseExcelData;
@ -31,7 +32,6 @@ import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.net.URLEncoder;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -269,4 +269,16 @@ public class TestCaseService {
list.add(explain); list.add(explain);
return list; 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.base.mapper.ext.ExtTestPlanMapper;
import io.metersphere.commons.constants.TestPlanStatus; import io.metersphere.commons.constants.TestPlanStatus;
import io.metersphere.commons.constants.TestPlanTestCaseStatus; 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.PlanCaseRelevanceRequest;
import io.metersphere.controller.request.testcase.QueryTestCaseRequest; import io.metersphere.controller.request.testcase.QueryTestCaseRequest;
import io.metersphere.controller.request.testcase.QueryTestPlanRequest; import io.metersphere.controller.request.testcase.QueryTestPlanRequest;
import io.metersphere.dto.TestPlanDTO; import io.metersphere.dto.TestPlanDTO;
import io.metersphere.i18n.Translator;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType; import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSession;
@ -62,8 +64,14 @@ public class TestPlanService {
return testPlanMapper.updateByPrimaryKeySelective(testPlan); return testPlanMapper.updateByPrimaryKeySelective(testPlan);
} }
public int deleteTestPlan(String testPalnId) { public int deleteTestPlan(String testPlanId) {
return testPlanMapper.deleteByPrimaryKey(testPalnId); 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) { 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.base.mapper.ext.ExtTestCaseMapper;
import io.metersphere.commons.constants.TestPlanTestCaseStatus; import io.metersphere.commons.constants.TestPlanTestCaseStatus;
import io.metersphere.commons.utils.BeanUtils; import io.metersphere.commons.utils.BeanUtils;
import io.metersphere.controller.request.testcase.QueryTestCaseRequest; import io.metersphere.controller.request.testcase.TestPlanCaseBatchRequest;
import io.metersphere.controller.request.testcase.TestCaseBatchRequest;
import io.metersphere.controller.request.testplancase.QueryTestPlanCaseRequest; import io.metersphere.controller.request.testplancase.QueryTestPlanCaseRequest;
import io.metersphere.dto.TestPlanCaseDTO; import io.metersphere.dto.TestPlanCaseDTO;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -44,7 +42,7 @@ public class TestPlanTestCaseService {
return testPlanTestCaseMapper.deleteByPrimaryKey(id); return testPlanTestCaseMapper.deleteByPrimaryKey(id);
} }
public void editTestCaseBath(TestCaseBatchRequest request) { public void editTestCaseBath(TestPlanCaseBatchRequest request) {
TestPlanTestCaseExample testPlanTestCaseExample = new TestPlanTestCaseExample(); TestPlanTestCaseExample testPlanTestCaseExample = new TestPlanTestCaseExample();
testPlanTestCaseExample.createCriteria().andIdIn(request.getIds()); testPlanTestCaseExample.createCriteria().andIdIn(request.getIds());

View File

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

View File

@ -23,3 +23,4 @@ max_thread_insufficient=The number of concurrent users exceeds
cannot_edit_load_test_running=Cannot modify the running test cannot_edit_load_test_running=Cannot modify the running test
test_not_found=Test cannot be found: 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 test_case_exist=该项目下已存在用例:
error_lang_invalid=\u8BED\u8A00\u53C2\u6570\u9519\u8BEF error_lang_invalid=语言参数错误
load_test_already_exists=\u6D4B\u8BD5\u540D\u79F0\u4E0D\u80FD\u91CD\u590D load_test_already_exists=测试名称不能重复
project_name_is_null=\u9879\u76EE\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A project_name_is_null=项目名称不能为空
project_name_already_exists=\u9879\u76EE\u540D\u79F0\u5DF2\u5B58\u5728 project_name_already_exists=项目名称已存在
workspace_name_is_null=\u5DE5\u4F5C\u7A7A\u95F4\u540D\u4E0D\u80FD\u4E3A\u7A7A workspace_name_is_null=工作空间名不能为空
workspace_name_already_exists=\u5DE5\u4F5C\u7A7A\u95F4\u540D\u5DF2\u5B58\u5728 workspace_name_already_exists=工作空间名已存在
workspace_does_not_belong_to_user=\u5F53\u524D\u5DE5\u4F5C\u7A7A\u95F4\u4E0D\u5C5E\u4E8E\u5F53\u524D\u7528\u6237 workspace_does_not_belong_to_user=当前工作空间不属于当前用户
organization_does_not_belong_to_user=\u5F53\u524D\u7EC4\u7EC7\u4E0D\u5C5E\u4E8E\u5F53\u524D\u7528\u6237 organization_does_not_belong_to_user=当前组织不属于当前用户
file_cannot_be_null=\u6587\u4EF6\u4E0D\u80FD\u4E3A\u7A7A\uFF01 file_cannot_be_null=文件不能为空!
edit_load_test_not_found=\u65E0\u6CD5\u7F16\u8F91\u6D4B\u8BD5\uFF0C\u672A\u627E\u5230\u6D4B\u8BD5\uFF1A edit_load_test_not_found=无法编辑测试,未找到测试:
run_load_test_not_found=\u65E0\u6CD5\u8FD0\u884C\u6D4B\u8BD5\uFF0C\u672A\u627E\u5230\u6D4B\u8BD5\uFF1A run_load_test_not_found=无法运行测试,未找到测试:
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_not_found=无法运行测试无法获取测试文件元信息测试ID
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_content_not_found=无法运行测试无法获取测试文件内容测试ID
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 run_load_test_file_init_error=无法运行测试初始化运行环境失败测试ID
load_test_is_running=\u6D4B\u8BD5\u6B63\u5728\u8FD0\u884C, \u8BF7\u7B49\u5F85 load_test_is_running=测试正在运行, 请等待
node_deep_limit=\u8282\u70B9\u6DF1\u5EA6\u4E0D\u8D85\u8FC75\u5C42\uFF01 node_deep_limit=节点深度不超过5层
no_nodes_message=\u6CA1\u6709\u8282\u70B9\u4FE1\u606F no_nodes_message=没有节点信息
duplicate_node_ip=\u8282\u70B9 IP \u91CD\u590D duplicate_node_ip=节点 IP 重复
only_one_k8s=\u53EA\u80FD\u6DFB\u52A0\u4E00\u4E2A K8s only_one_k8s=只能添加一个 K8s
organization_id_is_null=\u7EC4\u7EC7 ID \u4E0D\u80FD\u4E3A\u7A7A organization_id_is_null=组织 ID 不能为空
max_thread_insufficient=\u5E76\u53D1\u7528\u6237\u6570\u8D85\u989D max_thread_insufficient=并发用户数超额
cannot_edit_load_test_running=\u4E0D\u80FD\u4FEE\u6539\u6B63\u5728\u8FD0\u884C\u7684\u6D4B\u8BD5 cannot_edit_load_test_running=不能修改正在运行的测试
test_not_found=\u6D4B\u8BD5\u4E0D\u5B58\u5728: test_not_found=测试不存在:
test_not_running=\u6D4B\u8BD5\u672A\u8FD0\u884C 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; package io.metersphere;
import io.metersphere.config.KafkaProperties; import io.metersphere.config.KafkaProperties;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -23,7 +22,6 @@ import javax.xml.transform.stream.StreamResult;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.StringWriter; import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ -80,8 +78,8 @@ public class JmxFileParseTest {
TransformerFactory tf = TransformerFactory.newInstance(); TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer(); Transformer transformer = tf.newTransformer();
transformer.transform(domSource, result); transformer.transform(domSource, result);
// System.out.println("XML IN String format is: \n" + writer.toString()); System.out.println("XML IN String format is: \n" + writer.toString());
FileUtils.writeStringToFile(new File("/tmp/test-jmeter.jmx"), writer.toString(), StandardCharsets.UTF_8); // FileUtils.writeStringToFile(new File("/tmp/test-jmeter.jmx"), writer.toString(), StandardCharsets.UTF_8);
} }
private void parseHashTree(Element hashTree) { private void parseHashTree(Element hashTree) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
<div> <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"> <el-form :model="form" :rules="rules" ref="caseFrom">
@ -13,12 +13,13 @@
:label="$t('test_track.case.name')" :label="$t('test_track.case.name')"
:label-width="formLabelWidth" :label-width="formLabelWidth"
prop="name"> 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-form-item>
</el-col> </el-col>
<el-col :span="11" :offset="2"> <el-col :span="11" :offset="2">
<el-form-item :label="$t('test_track.case.module')" :label-width="formLabelWidth" prop="module"> <el-form-item :label="$t('test_track.case.module')" :label-width="formLabelWidth" prop="module">
<el-select <el-select
v-model="form.module" v-model="form.module"
:disabled="readOnly" :disabled="readOnly"
@ -186,7 +187,7 @@
<script> <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' import MsDialogFooter from '../../../common/components/MsDialogFooter'
@ -236,8 +237,14 @@
readOnly: { readOnly: {
type: Boolean, type: Boolean,
default: true default: true
},
selectNode: {
type: Object
} }
}, },
mounted() {
this.getSelectOptions();
},
methods: { methods: {
open(testCase) { open(testCase) {
this.resetForm(); this.resetForm();
@ -255,6 +262,17 @@
tmp.steps = JSON.parse(testCase.steps); tmp.steps = JSON.parse(testCase.steps);
Object.assign(this.form, tmp); Object.assign(this.form, tmp);
this.form.module = testCase.nodeId; 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; this.dialogFormVisible = true;
}, },
@ -294,7 +312,7 @@
param.projectId = JSON.parse(localStorage.getItem(CURRENT_PROJECT)).id; param.projectId = JSON.parse(localStorage.getItem(CURRENT_PROJECT)).id;
} }
this.$post('/test/case/' + this.operationType, param, () => { 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.dialogFormVisible = false;
this.$emit("refresh"); this.$emit("refresh");
}); });

View File

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

View File

@ -10,17 +10,25 @@
<node-breadcrumb class="table-title" :node-names="selectNodeNames" @refresh="refresh"/> <node-breadcrumb class="table-title" :node-names="selectNodeNames" @refresh="refresh"/>
</template> </template>
<template v-slot:button> <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/>--> <!--<test-case-export/>-->
</template> </template>
</ms-table-header> </ms-table-header>
</template> </template>
<test-case-import :projectId="currentProject == null? null : currentProject.id" @refresh="refresh" ref="testCaseImport"/>
<el-table <el-table
:data="tableData" :data="tableData"
@select-all="handleSelectAll"
@select="handleSelectionChange"
@row-click="showDetail" @row-click="showDetail"
row-key="id"
class="test-content"> class="test-content">
<el-table-column
type="selection"/>
<el-table-column <el-table-column
prop="name" prop="name"
:label="$t('commons.name')" :label="$t('commons.name')"
@ -65,7 +73,8 @@
<el-table-column <el-table-column
prop="updateTime" prop="updateTime"
sortable sortable
:label="$t('commons.update_time')"> :label="$t('commons.update_time')"
show-overflow-tooltip>
<template v-slot:default="scope"> <template v-slot:default="scope">
<span>{{ scope.row.updateTime | timestampFormatDate }}</span> <span>{{ scope.row.updateTime | timestampFormatDate }}</span>
</template> </template>
@ -103,10 +112,12 @@
import MethodTableItem from "../../common/tableItems/planview/MethodTableItem"; 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";
export default { export default {
name: "TestCaseList", name: "TestCaseList",
components: { components: {
MsTableButton,
MsTableOperatorButton, MsTableOperatorButton,
MsTableOperator, MsTableOperator,
MethodTableItem, MethodTableItem,
@ -120,8 +131,9 @@
condition: {}, condition: {},
tableData: [], tableData: [],
currentPage: 1, currentPage: 1,
pageSize: 5, pageSize: 10,
total: 0, total: 0,
selectIds: new Set(),
priorityFilters: [ priorityFilters: [
{text: 'P0', value: 'P0'}, {text: 'P0', value: 'P0'},
{text: 'P1', value: 'P1'}, {text: 'P1', value: 'P1'},
@ -169,6 +181,7 @@
let data = response.data; let data = response.data;
this.total = data.itemCount; this.total = data.itemCount;
this.tableData = data.listObject; this.tableData = data.listObject;
this.selectIds.clear();
}); });
} }
}, },
@ -201,14 +214,12 @@
let testCaseId = testCase.id; let testCaseId = testCase.id;
this.$post('/test/case/delete/' + testCaseId, {}, () => { this.$post('/test/case/delete/' + testCaseId, {}, () => {
this.initTableData(); this.initTableData();
this.$message({ this.$success(this.$t('commons.delete_success'));
message: this.$t('commons.delete_success'),
type: 'success'
});
}); });
}, },
refresh() { refresh() {
this.condition = {}; this.condition = {};
this.selectIds.clear();
this.$emit('refresh'); this.$emit('refresh');
}, },
filter(value, row, column) { filter(value, row, column) {
@ -217,6 +228,28 @@
}, },
showDetail(row, event, column) { showDetail(row, event, column) {
this.$emit('testCaseDetail', row); 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> <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" :visible.sync="dialogFormVisible"
:before-close="close"
width="30%"> width="30%">
<el-row type="flex" justify="center"> <el-row type="flex" justify="center">
<el-col :span="18"> <el-col :span="18">
<el-form :model="form" :rules="rules"> <el-form :model="form" :rules="rules" ref="nodeForm">
<el-form-item <el-form-item
:label="$t('test_track.module.name')" :label="$t('test_track.module.name')"
:label-width="formLabelWidth" :label-width="formLabelWidth"
prop="name"> 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-item>
</el-form> </el-form>
</el-col> </el-col>
@ -19,7 +20,7 @@
<template v-slot:footer> <template v-slot:footer>
<ms-dialog-footer <ms-dialog-footer
@cancel="dialogFormVisible = false" @cancel="close"
@confirm="saveNode"/> @confirm="saveNode"/>
</template> </template>
@ -59,12 +60,18 @@
this.dialogFormVisible = true; this.dialogFormVisible = true;
}, },
saveNode() { saveNode() {
let param = {}; this.$refs['nodeForm'].validate((valid) => {
let url = this.buildParam(param); if (valid) {
this.$post(url, param, () => { let param = {};
this.$message.success(this.$t('commons.save_success')); let url = this.buildParam(param);
this.$emit('refresh'); this.$post(url, param, () => {
this.close(); this.$success(this.$t('commons.save_success'));
this.$emit('refresh');
this.close();
});
} else {
return false;
}
}); });
}, },
buildParam(param, ) { buildParam(param, ) {

View File

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

View File

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

View File

@ -2,7 +2,7 @@
<div> <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" :visible.sync="dialogFormVisible"
width="65%"> width="65%">
@ -15,7 +15,7 @@
:label="$t('test_track.plan.plan_name')" :label="$t('test_track.plan.plan_name')"
:label-width="formLabelWidth" :label-width="formLabelWidth"
prop="name"> prop="name">
<el-input v-model="form.name"></el-input> <el-input v-model.trim="form.name"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -54,10 +54,11 @@
<el-form-item :label="$t('test_track.plan.plan_stage')" :label-width="formLabelWidth" prop="stage"> <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-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.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.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.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.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-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -150,7 +151,7 @@
Object.assign(param, this.form); Object.assign(param, this.form);
param.workspaceId = localStorage.getItem(WORKSPACE_ID); param.workspaceId = localStorage.getItem(WORKSPACE_ID);
this.$post('/test/plan/' + this.operationType, param, () => { 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.dialogFormVisible = false;
this.$emit("refresh"); this.$emit("refresh");
}); });
@ -164,10 +165,7 @@
if (response.success) { if (response.success) {
this.projects = response.data; this.projects = response.data;
} else { } else {
this.$message()({ this.$warning()(response.message);
type: 'warning',
message: 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 == '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 == '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 == '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> <span v-if="scope.row.stage == 'version'">{{$t('test_track.plan.version_validation')}}</span>
</template> </template>
</el-table-column> </el-table-column>
@ -47,13 +48,15 @@
show-overflow-tooltip> show-overflow-tooltip>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
:label="$t('commons.create_time')"> :label="$t('commons.create_time')"
show-overflow-tooltip>
<template v-slot:default="scope"> <template v-slot:default="scope">
<span>{{ scope.row.createTime | timestampFormatDate }}</span> <span>{{ scope.row.createTime | timestampFormatDate }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
:label="$t('commons.update_time')"> :label="$t('commons.update_time')"
show-overflow-tooltip>
<template v-slot:default="scope"> <template v-slot:default="scope">
<span>{{ scope.row.updateTime | timestampFormatDate }}</span> <span>{{ scope.row.updateTime | timestampFormatDate }}</span>
</template> </template>
@ -99,6 +102,13 @@
tableData: [], tableData: [],
} }
}, },
watch: {
'$route'(to, from) {
if (to.path.indexOf("/track/plan/all") >= 0){
this.initTableData();
}
}
},
created() { created() {
this.projectId = this.$route.params.projectId; this.projectId = this.$route.params.projectId;
this.initTableData(); this.initTableData();
@ -134,10 +144,7 @@
let testPlanId = testPlan.id; let testPlanId = testPlan.id;
this.$post('/test/plan/delete/' + testPlanId, {}, () => { this.$post('/test/plan/delete/' + testPlanId, {}, () => {
this.initTableData(); this.initTableData();
this.$message({ this.$success(this.$t('commons.delete_success'));
message: this.$t('commons.delete_success'),
type: 'success'
});
}); });
}, },
intoPlan(row, event, column) { intoPlan(row, event, column) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

3
package-lock.json generated Normal file
View File

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