refactor(测试跟踪): 优化首页样式及展示面板
This commit is contained in:
parent
ef3a211e19
commit
202e85f23f
|
@ -351,15 +351,15 @@ export default {
|
|||
test_rate: "Test Rate",
|
||||
tested_case: "Tested Case",
|
||||
review_progress: "Review Progress",
|
||||
case_count: "Statistics of the number of use cases",
|
||||
relevance_case: "Related Case",
|
||||
case_maintenance: "Use case person responsible distribution",
|
||||
bug_count: "Statistics of test plan remaining defects",
|
||||
case_count: "Statistics of cases",
|
||||
relevance_case: "Statistics of related cases",
|
||||
case_maintenance: "Statistics of case maintenance",
|
||||
bug_count: "Statistics of test plan unclosed bugs",
|
||||
case_review: "Use case review",
|
||||
review_rate: "Reviewed",
|
||||
coverage: "Coverage",
|
||||
function_case_count: "Functional Case Count",
|
||||
relevance_case_count: "Related Case Count",
|
||||
function_case_count: "Functional Case",
|
||||
relevance_case_count: "Related Case",
|
||||
serial_number: "Index",
|
||||
test_plan_name: "Plan Name",
|
||||
case_size: "Case Count",
|
||||
|
|
|
@ -66,11 +66,19 @@ public class IssuesRequest extends BaseQueryRequest {
|
|||
private List<String> exportIds;
|
||||
|
||||
/**
|
||||
* 本周遗留缺陷
|
||||
* 本周测试计划遗留缺陷
|
||||
*/
|
||||
private Boolean thisWeekUnClosedIssue = false;
|
||||
private Boolean thisWeekUnClosedTestPlanIssue = false;
|
||||
/**
|
||||
* 本周遗留缺陷ID
|
||||
* 测试计划遗留的缺陷
|
||||
*/
|
||||
private List<String> thisWeekUncloseIds;
|
||||
private Boolean unClosedTestPlanIssue = false;
|
||||
/**
|
||||
* 测试计划关联所有缺陷
|
||||
*/
|
||||
private Boolean allTestPlanIssue = false;
|
||||
/**
|
||||
* 过滤缺陷ID
|
||||
*/
|
||||
private List<String> filterIds;
|
||||
}
|
||||
|
|
|
@ -48,4 +48,6 @@ public interface ExtIssuesMapper {
|
|||
Long getThisWeekIssueCount(@Param("ids") List<String> ids, @Param("projectId") String projectId);
|
||||
|
||||
List<String> getTestPlanThisWeekIssue(String projectId);
|
||||
|
||||
List<String> getTestPlanIssue(String projectId);
|
||||
}
|
||||
|
|
|
@ -179,6 +179,15 @@
|
|||
and tp.project_id = #{projectId}
|
||||
</select>
|
||||
|
||||
<select id="getTestPlanIssue" resultType="java.lang.String">
|
||||
select distinct tci.issues_id
|
||||
from test_plan_test_case tptc
|
||||
join test_plan tp on tp.id = tptc.plan_id
|
||||
join test_case_issues tci on tptc.id = tci.resource_id
|
||||
join issues on tci.issues_id = issues.id
|
||||
where tptc.is_del != 1 and tp.project_id = #{projectId}
|
||||
</select>
|
||||
|
||||
<select id="getIssueCustomFields" resultType="io.metersphere.xpack.track.dto.IssuesDao">
|
||||
select cfi.field_id as fieldId,
|
||||
cf.type fieldType,
|
||||
|
@ -247,9 +256,9 @@
|
|||
#{value}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="request.thisWeekUnClosedIssue and request.thisWeekUncloseIds != null and request.thisWeekUncloseIds.size() > 0">
|
||||
<if test="request.filterIds != null and request.filterIds.size() > 0">
|
||||
and issues.id in
|
||||
<foreach collection="request.thisWeekUncloseIds" item="value" separator="," open="(" close=")">
|
||||
<foreach collection="request.filterIds" item="value" separator="," open="(" close=")">
|
||||
#{value}
|
||||
</foreach>
|
||||
</if>
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
package io.metersphere.constants;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public enum IssueStatus {
|
||||
status_new("new", "new"),
|
||||
status_resolved("resolved", "resolved"),
|
||||
status_closed("closed", "closed"),
|
||||
status_active("active", "active"),
|
||||
status_delete("delete", "delete"),
|
||||
status_in_progress("in_progress", "in_progress"),
|
||||
status_rejected("rejected", "rejected"),
|
||||
status_upcoming("upcoming", "upcoming"),
|
||||
status_reopened("reopened", "reopened");
|
||||
|
||||
private String name;
|
||||
private String i18nKey;
|
||||
|
||||
IssueStatus(String name, String i18nKey) {
|
||||
this.name = name;
|
||||
this.i18nKey = i18nKey;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getI18nKey() {
|
||||
return i18nKey;
|
||||
}
|
||||
|
||||
public static IssueStatus getEnumByName(String name) {
|
||||
IssueStatus[] issueStatus = IssueStatus.values();
|
||||
for (int i = 0; i < issueStatus.length; i++) {
|
||||
if (StringUtils.equals(issueStatus[i].getName(), name)) {
|
||||
return issueStatus[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -48,9 +48,7 @@ public class IssuesController {
|
|||
@PostMapping("/list/{goPage}/{pageSize}")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_TRACK_ISSUE_READ)
|
||||
public Pager<List<IssuesDao>> list(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody IssuesRequest request) {
|
||||
if (request.getThisWeekUnClosedIssue()) {
|
||||
issuesService.setThisWeekUnclosedIds(request);
|
||||
}
|
||||
issuesService.setFilterIds(request);
|
||||
Page<List<Issues>> page = PageHelper.startPage(goPage, pageSize, true);
|
||||
return PageUtils.setPageInfo(page, issuesService.list(request));
|
||||
}
|
||||
|
|
|
@ -54,10 +54,6 @@ public class TrackController {
|
|||
statistics.setReviewPassRage(df.format(reviewPass) + "%");
|
||||
}
|
||||
|
||||
statistics.setP0CountStr("P0 <br/><br/>" + statistics.getP0CaseCountNumber());
|
||||
statistics.setP1CountStr("P1 <br/><br/>" + statistics.getP1CaseCountNumber());
|
||||
statistics.setP2CountStr("P2 <br/><br/>" + statistics.getP2CaseCountNumber());
|
||||
statistics.setP3CountStr("P3 <br/><br/>" + statistics.getP3CaseCountNumber());
|
||||
return statistics;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import lombok.Setter;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
|
@ -21,4 +22,5 @@ public class BugStatistics {
|
|||
private String unClosedRage;
|
||||
private String bugCaseRage;
|
||||
private List<TestPlanBugCount> list = new ArrayList<>();
|
||||
private Map<String, Integer> chartData;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
package io.metersphere.dto;
|
||||
|
||||
import io.metersphere.excel.converter.TestReviewCaseStatus;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.request.testcase.TrackCount;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 用例数量统计数据
|
||||
|
@ -107,33 +110,31 @@ public class TrackStatisticsDTO {
|
|||
*/
|
||||
private long unPassCount = 0;
|
||||
|
||||
/**
|
||||
* 面板数据
|
||||
*/
|
||||
private Map<String, Integer> chartData;
|
||||
|
||||
|
||||
/**
|
||||
* 按照 Priority 统计
|
||||
* @param trackCountResults 统计结果
|
||||
*/
|
||||
public void countPriority(List<TrackCountResult> trackCountResults) {
|
||||
Map<String, Integer> chartData = new HashMap<>();
|
||||
for (TrackCountResult countResult : trackCountResults) {
|
||||
if (StringUtils.isNotBlank(countResult.getGroupField())) {
|
||||
switch (countResult.getGroupField().toUpperCase()){
|
||||
case TrackCount.P0:
|
||||
this.p0CaseCountNumber += countResult.getCountNumber();
|
||||
break;
|
||||
case TrackCount.P1:
|
||||
this.p1CaseCountNumber += countResult.getCountNumber();
|
||||
break;
|
||||
case TrackCount.P2:
|
||||
this.p2CaseCountNumber += countResult.getCountNumber();
|
||||
break;
|
||||
case TrackCount.P3:
|
||||
this.p3CaseCountNumber += countResult.getCountNumber();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
Integer count = chartData.get(countResult.getGroupField());
|
||||
if (count == null) {
|
||||
chartData.put(countResult.getGroupField(), (int) countResult.getCountNumber());
|
||||
} else {
|
||||
count += (int) countResult.getCountNumber();
|
||||
chartData.put(countResult.getGroupField(), count);
|
||||
}
|
||||
}
|
||||
this.allCaseCountNumber += countResult.getCountNumber();
|
||||
}
|
||||
this.chartData = chartData;
|
||||
}
|
||||
|
||||
public void countStatus(List<TrackCountResult> statusResults) {
|
||||
|
@ -149,24 +150,38 @@ public class TrackStatisticsDTO {
|
|||
}
|
||||
|
||||
public void countRelevance(List<TrackCountResult> relevanceResults) {
|
||||
Map<String, Integer> chartData = new HashMap<>();
|
||||
for (TrackCountResult countResult : relevanceResults) {
|
||||
switch (countResult.getGroupField()){
|
||||
case TrackCount.TESTCASE:
|
||||
this.apiCaseCount += countResult.getCountNumber();
|
||||
this.allRelevanceCaseCount += countResult.getCountNumber();
|
||||
break;
|
||||
case TrackCount.PERFORMANCE:
|
||||
this.performanceCaseCount += countResult.getCountNumber();
|
||||
this.allRelevanceCaseCount += countResult.getCountNumber();
|
||||
break;
|
||||
case TrackCount.AUTOMATION:
|
||||
this.scenarioCaseCount += countResult.getCountNumber();
|
||||
this.allRelevanceCaseCount += countResult.getCountNumber();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (StringUtils.equalsIgnoreCase(TrackCount.TESTCASE, countResult.getGroupField())) {
|
||||
Integer count = chartData.get(Translator.get("api_case"));
|
||||
if (count == null) {
|
||||
chartData.put(Translator.get("api_case"), (int) countResult.getCountNumber());
|
||||
} else {
|
||||
count += (int) countResult.getCountNumber();
|
||||
chartData.put(Translator.get("api_case"), count);
|
||||
}
|
||||
}
|
||||
if (StringUtils.equalsIgnoreCase(TrackCount.PERFORMANCE, countResult.getGroupField())) {
|
||||
Integer count = chartData.get(Translator.get("performance_case"));
|
||||
if (count == null) {
|
||||
chartData.put(Translator.get("performance_case"), (int) countResult.getCountNumber());
|
||||
} else {
|
||||
count += (int) countResult.getCountNumber();
|
||||
chartData.put(Translator.get("performance_case"), count);
|
||||
}
|
||||
}
|
||||
if (StringUtils.equalsIgnoreCase(TrackCount.AUTOMATION, countResult.getGroupField())) {
|
||||
Integer count = chartData.get(Translator.get("scenario_case"));
|
||||
if (count == null) {
|
||||
chartData.put(Translator.get("scenario_case"), (int) countResult.getCountNumber());
|
||||
} else {
|
||||
count += (int) countResult.getCountNumber();
|
||||
chartData.put(Translator.get("scenario_case"), count);
|
||||
}
|
||||
}
|
||||
this.allRelevanceCaseCount += countResult.getCountNumber();
|
||||
}
|
||||
this.chartData = chartData;
|
||||
}
|
||||
|
||||
public void countCoverage(List<TrackCountResult> coverageResults) {
|
||||
|
|
|
@ -1456,16 +1456,26 @@ public class IssuesService {
|
|||
});
|
||||
}
|
||||
|
||||
public void setThisWeekUnclosedIds(IssuesRequest request) {
|
||||
List<String> issueIds = extIssuesMapper.getTestPlanThisWeekIssue(request.getProjectId());
|
||||
public void setFilterIds(IssuesRequest request) {
|
||||
List<String> issueIds = new ArrayList<>();
|
||||
if (request.getThisWeekUnClosedTestPlanIssue()) {
|
||||
issueIds = extIssuesMapper.getTestPlanThisWeekIssue(request.getProjectId());
|
||||
} else if (request.getAllTestPlanIssue() || request.getUnClosedTestPlanIssue()) {
|
||||
issueIds = extIssuesMapper.getTestPlanIssue(request.getProjectId());
|
||||
}
|
||||
|
||||
Map<String, String> statusMap = customFieldIssuesService.getIssueStatusMap(issueIds, request.getProjectId());
|
||||
if (MapUtils.isEmpty(statusMap)) {
|
||||
request.setThisWeekUncloseIds(issueIds);
|
||||
request.setFilterIds(issueIds);
|
||||
} else {
|
||||
if (request.getThisWeekUnClosedTestPlanIssue() || request.getUnClosedTestPlanIssue()) {
|
||||
List<String> unClosedIds = issueIds.stream()
|
||||
.filter(id -> !StringUtils.equals(statusMap.getOrDefault(id, StringUtils.EMPTY).replaceAll("\"", StringUtils.EMPTY), "closed"))
|
||||
.collect(Collectors.toList());
|
||||
request.setThisWeekUncloseIds(unClosedIds);
|
||||
request.setFilterIds(unClosedIds);
|
||||
} else {
|
||||
request.setFilterIds(issueIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,21 @@
|
|||
package io.metersphere.service;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.metersphere.base.domain.CustomField;
|
||||
import io.metersphere.base.domain.TestPlan;
|
||||
import io.metersphere.base.domain.TestPlanExample;
|
||||
import io.metersphere.base.mapper.TestPlanMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtIssuesMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtTestCaseMapper;
|
||||
import io.metersphere.commons.utils.DateUtils;
|
||||
import io.metersphere.constants.IssueStatus;
|
||||
import io.metersphere.constants.SystemCustomField;
|
||||
import io.metersphere.dto.BugStatistics;
|
||||
import io.metersphere.dto.TestPlanBugCount;
|
||||
import io.metersphere.dto.TestPlanDTOWithMetric;
|
||||
import io.metersphere.dto.TrackCountResult;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.plan.dto.ChartsData;
|
||||
import io.metersphere.plan.service.TestPlanService;
|
||||
import io.metersphere.xpack.track.dto.IssuesDao;
|
||||
|
@ -37,6 +43,8 @@ public class TrackService {
|
|||
@Resource
|
||||
private CustomFieldIssuesService customFieldIssuesService;
|
||||
@Resource
|
||||
private BaseCustomFieldService baseCustomFieldService;
|
||||
@Resource
|
||||
private TestPlanService testPlanService;
|
||||
|
||||
@Resource
|
||||
|
@ -110,27 +118,21 @@ public class TrackService {
|
|||
}
|
||||
|
||||
public BugStatistics getBugStatistics(String projectId) {
|
||||
List<TestPlanBugCount> list = new ArrayList<>();
|
||||
BugStatistics bugStatistics = new BugStatistics();
|
||||
TestPlanExample example = new TestPlanExample();
|
||||
example.createCriteria().andProjectIdEqualTo(projectId);
|
||||
List<TestPlan> plans = testPlanMapper.selectByExample(example);
|
||||
List<TestPlanBugCount> list = new ArrayList<>();
|
||||
BugStatistics bugStatistics = new BugStatistics();
|
||||
List<String> planIds = plans.stream().map(TestPlan::getId).collect(Collectors.toList());
|
||||
int index = 1;
|
||||
int totalUnClosedPlanBugSize = 0;
|
||||
int totalPlanBugSize = 0;
|
||||
int newCount = 0;
|
||||
int resolvedCount = 0;
|
||||
int rejectedCount = 0;
|
||||
int unKnownCount = 0;
|
||||
int thisWeekCount = 0;
|
||||
Map<String, Integer> bugStatusMap = getPlanBugStatusSize(planIds, projectId);
|
||||
for (TestPlan plan : plans) {
|
||||
Map<String, Integer> bugSizeMap = getPlanBugSize(plan.getId(), projectId);
|
||||
int planBugSize = bugSizeMap.get("total");
|
||||
int unClosedPlanBugSize = bugSizeMap.get("unClosed");
|
||||
newCount += bugSizeMap.get("newCount");
|
||||
resolvedCount += bugSizeMap.get("resolvedCount");
|
||||
rejectedCount += bugSizeMap.get("rejectedCount");
|
||||
unKnownCount += bugSizeMap.get("unKnownCount");
|
||||
thisWeekCount += bugSizeMap.get("thisWeekCount");
|
||||
totalUnClosedPlanBugSize += unClosedPlanBugSize;
|
||||
totalPlanBugSize += planBugSize;
|
||||
|
@ -138,7 +140,6 @@ public class TrackService {
|
|||
if (unClosedPlanBugSize == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TestPlanBugCount testPlanBug = new TestPlanBugCount();
|
||||
testPlanBug.setIndex(index++);
|
||||
testPlanBug.setPlanName(plan.getName());
|
||||
|
@ -158,12 +159,8 @@ public class TrackService {
|
|||
float rage = totalPlanBugSize == 0 ? 0 : (float) totalUnClosedPlanBugSize * 100 / totalPlanBugSize;
|
||||
DecimalFormat df = new DecimalFormat("0.0");
|
||||
bugStatistics.setUnClosedRage(df.format(rage) + "%");
|
||||
|
||||
bugStatistics.setNewCount(newCount);
|
||||
bugStatistics.setResolvedCount(resolvedCount);
|
||||
bugStatistics.setRejectedCount(rejectedCount);
|
||||
bugStatistics.setUnKnownCount(unKnownCount);
|
||||
bugStatistics.setThisWeekCount(thisWeekCount);
|
||||
bugStatistics.setChartData(bugStatusMap);
|
||||
return bugStatistics;
|
||||
}
|
||||
|
||||
|
@ -177,13 +174,11 @@ public class TrackService {
|
|||
Map<String, String> statusMap = customFieldIssuesService.getIssueStatusMap(issueIds, projectId);
|
||||
Map<String, Integer> bugSizeMap = new HashMap<>();
|
||||
bugSizeMap.put("total", issueIds.size());
|
||||
|
||||
// 缺陷是否有状态
|
||||
List<String> unClosedIds;
|
||||
if (MapUtils.isEmpty(statusMap)) {
|
||||
unClosedIds = issueIds;
|
||||
bugSizeMap.put("unClosed", issueIds.size());
|
||||
bugSizeMap.put("newCount", issueIds.size());
|
||||
} else {
|
||||
unClosedIds = issueIds.stream()
|
||||
.filter(id -> !StringUtils.equals(statusMap.getOrDefault(id, StringUtils.EMPTY).replaceAll("\"", StringUtils.EMPTY), "closed"))
|
||||
|
@ -196,29 +191,59 @@ public class TrackService {
|
|||
thisWeekCount = extIssuesMapper.getThisWeekIssueCount(unClosedIds, projectId).intValue();
|
||||
}
|
||||
bugSizeMap.put("thisWeekCount", thisWeekCount);
|
||||
// 如果没有严重程度字段
|
||||
int newCount = 0;
|
||||
int resolvedCount = 0;
|
||||
int rejectedCount = 0;
|
||||
int unKnownCount = 0;
|
||||
for (String unClosedId : unClosedIds) {
|
||||
String status = statusMap.getOrDefault(unClosedId, StringUtils.EMPTY).replaceAll("\"", StringUtils.EMPTY);
|
||||
if (StringUtils.equalsIgnoreCase(status, "new")) {
|
||||
newCount += 1;
|
||||
} else if (StringUtils.equalsIgnoreCase(status, "resolved")) {
|
||||
resolvedCount += 1;
|
||||
} else if (StringUtils.equalsIgnoreCase(status, "rejected")) {
|
||||
rejectedCount += 1;
|
||||
} else {
|
||||
unKnownCount += 1;
|
||||
}
|
||||
return bugSizeMap;
|
||||
}
|
||||
|
||||
bugSizeMap.put("newCount", newCount);
|
||||
bugSizeMap.put("resolvedCount", resolvedCount);
|
||||
bugSizeMap.put("rejectedCount", rejectedCount);
|
||||
bugSizeMap.put("unKnownCount", unKnownCount);
|
||||
return bugSizeMap;
|
||||
private Map<String, Integer> getPlanBugStatusSize(List<String> planIds, String projectId) {
|
||||
CustomField customField = baseCustomFieldService.getCustomFieldByName(projectId, SystemCustomField.ISSUE_STATUS);
|
||||
JSONArray statusArray = JSONArray.parseArray(customField.getOptions());
|
||||
Map<String, Integer> bugStatusMap = new HashMap<>();
|
||||
if (CollectionUtils.isNotEmpty(planIds)) {
|
||||
planIds.forEach(planId -> {
|
||||
List<String> issueIds = extTestCaseMapper.getTestPlanBug(planId);
|
||||
Map<String, String> statusMap = customFieldIssuesService.getIssueStatusMap(issueIds, projectId);
|
||||
if (MapUtils.isEmpty(statusMap)) {
|
||||
Integer count = bugStatusMap.get(Translator.get("new"));
|
||||
if (count == null) {
|
||||
bugStatusMap.put(Translator.get("new"), issueIds.size());
|
||||
} else {
|
||||
count += issueIds.size();
|
||||
bugStatusMap.put(Translator.get("new"), count);
|
||||
}
|
||||
} else {
|
||||
List<String> unClosedIds = issueIds.stream()
|
||||
.filter(id -> !StringUtils.equals(statusMap.getOrDefault(id, StringUtils.EMPTY).replaceAll("\"", StringUtils.EMPTY), "closed"))
|
||||
.collect(Collectors.toList());
|
||||
for (String unClosedId : unClosedIds) {
|
||||
String status = statusMap.getOrDefault(unClosedId, StringUtils.EMPTY).replaceAll("\"", StringUtils.EMPTY);
|
||||
IssueStatus statusEnum = IssueStatus.getEnumByName(status);
|
||||
if (statusEnum != null) {
|
||||
Integer count = bugStatusMap.get(Translator.get(statusEnum.getI18nKey()));
|
||||
if (count == null) {
|
||||
bugStatusMap.put(Translator.get(statusEnum.getI18nKey()), 1);
|
||||
} else {
|
||||
count += 1;
|
||||
bugStatusMap.put(Translator.get(statusEnum.getI18nKey()), count);
|
||||
}
|
||||
} else {
|
||||
statusArray.forEach(item -> {
|
||||
JSONObject statusObj = (JSONObject) item;
|
||||
if (StringUtils.equals(status, statusObj.get("value").toString())) {
|
||||
Integer count = bugStatusMap.get(statusObj.get("text").toString());
|
||||
if (count == null) {
|
||||
bugStatusMap.put(statusObj.get("text").toString(), 1);
|
||||
} else {
|
||||
count += 1;
|
||||
bugStatusMap.put(statusObj.get("text").toString(), count);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return bugStatusMap;
|
||||
}
|
||||
|
||||
private int getAllUnClosedBugSize(String projectId) {
|
||||
|
|
|
@ -63,6 +63,16 @@ can_not_be_null=Can not be null
|
|||
excel_field_not_exist=Not exist
|
||||
options_not_exist=Incorrect option value
|
||||
format_error=Format error
|
||||
# issue status
|
||||
new=new
|
||||
resolved=resolved
|
||||
closed=closed
|
||||
active=active
|
||||
delete=delete
|
||||
in_progress=in_progress
|
||||
rejected=rejected
|
||||
upcoming=upcoming
|
||||
reopened=reopened
|
||||
#project
|
||||
project_name_is_null=Project name cannot be null
|
||||
project_name_already_exists=The project name already exists
|
||||
|
|
|
@ -40,6 +40,16 @@ can_not_be_null=不能为空
|
|||
excel_field_not_exist=不存在该字段
|
||||
options_not_exist=选项值有误
|
||||
format_error=格式有误
|
||||
# issue status
|
||||
new=新建
|
||||
resolved=已解决
|
||||
closed=已关闭
|
||||
active=激活
|
||||
delete=删除
|
||||
in_progress=接受/处理
|
||||
rejected=已拒绝
|
||||
upcoming=待办
|
||||
reopened=重新打开
|
||||
#project
|
||||
project_name_is_null=项目名称不能为空
|
||||
project_name_already_exists=项目名称已存在
|
||||
|
|
|
@ -40,6 +40,16 @@ can_not_be_null=不能爲空
|
|||
excel_field_not_exist=不存在該字段
|
||||
options_not_exist=選項值有誤
|
||||
format_error=格式有誤
|
||||
#issue status
|
||||
new=新建
|
||||
resolved=已解決
|
||||
closed=已關閉
|
||||
active=激活
|
||||
delete=刪除
|
||||
in_progress=接受/處理
|
||||
rejected=已拒絕
|
||||
upcoming=待辦
|
||||
reopened=重新打開
|
||||
#project
|
||||
project_name_is_null=項目名稱不能為空
|
||||
project_name_already_exists=項目名稱已存在
|
||||
|
|
|
@ -5,3 +5,8 @@ export const TEST_CASE_STATUS_MAP = {
|
|||
'Completed': i18n.t('test_track.plan.plan_status_completed'),
|
||||
'Trash': i18n.t('test_track.plan.plan_status_trash')
|
||||
}
|
||||
|
||||
export const DASHBOARD_CHART_COLOR = [
|
||||
'#AA4FBF', '#FFD131', '#10CECE', '#4E83FD',
|
||||
'#935AF6', '#50CEFB', '#FFA53D', '#62D256',
|
||||
];
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div style="background-color:#F5F6F7">
|
||||
<div style="background-color:#F5F6F7; overflow: auto">
|
||||
<ms-container>
|
||||
<ms-main-container style="overflow-y: hidden">
|
||||
<ms-main-container style="padding: 0px">
|
||||
<div class="track-home-layout">
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
|
@ -14,7 +14,7 @@
|
|||
|
||||
<el-row :gutter="16" style="margin-top: 16px">
|
||||
<el-col :span="12">
|
||||
<bug-count-card />
|
||||
<bug-count-card @redirectPage="redirectPage"/>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<case-maintenance />
|
||||
|
@ -22,19 +22,19 @@
|
|||
</el-row>
|
||||
|
||||
<el-row style="margin-top: 16px">
|
||||
<el-col style="background-color: #FFFFFF;">
|
||||
<el-col style="height: 369px; background-color: #FFFFFF;">
|
||||
<ms-failure-test-case-list :select-function-case="true" @redirectPage="redirectPage"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row style="margin-top: 16px">
|
||||
<el-col style="background-color: #FFFFFF;">
|
||||
<el-col style="height: 369px; background-color: #FFFFFF;">
|
||||
<review-list/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row style="margin-top: 16px">
|
||||
<el-col style="background-color: #FFFFFF;">
|
||||
<el-col style="height: 369px; background-color: #FFFFFF;">
|
||||
<ms-running-task-list :call-from="'track_home'" @redirectPage="redirectPage"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@ -55,7 +55,6 @@ import BugCountCard from "./components/BugCountCard";
|
|||
import ReviewList from "./components/ReviewList";
|
||||
import MsRunningTaskList from "./components/RunningTaskList";
|
||||
import {getUUID} from "metersphere-frontend/src/utils";
|
||||
import {getCurrentProjectID} from "metersphere-frontend/src/utils/token";
|
||||
import MsFailureTestCaseList from "@/business/home/components/FailureTestCaseList";
|
||||
|
||||
require('echarts/lib/component/legend');
|
||||
|
@ -76,11 +75,6 @@ export default {
|
|||
return {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
projectId() {
|
||||
return getCurrentProjectID();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
redirectPage(page, dataType, selectType, title) {
|
||||
//api页面跳转
|
||||
|
@ -103,6 +97,8 @@ export default {
|
|||
case "api":
|
||||
home = this.$router.resolve('/api/definition/' + uuid + "/" + dataType + "/" + selectType);
|
||||
break;
|
||||
case "issue":
|
||||
home = this.$router.resolve('/track/issue/' + uuid + "/" + dataType + "/" + selectType);
|
||||
}
|
||||
if (home) {
|
||||
window.open(home.href, '_blank');
|
||||
|
@ -193,4 +189,8 @@ export default {
|
|||
color: #1F2329;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.track-home-layout :deep(.el-card) {
|
||||
border: 0;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
<template>
|
||||
<el-card class="table-card" shadow="never" body-style="padding:10px 5px;">
|
||||
<div slot="header">
|
||||
<span class="title">
|
||||
{{ $t('test_track.home.bug_count') }}
|
||||
</span>
|
||||
<div class="dashboard-card">
|
||||
<el-card shadow="never" class="box-card" style="height: 100%">
|
||||
<div slot="header" class="clearfix">
|
||||
<span class="dashboard-title">{{ $t('test_track.home.bug_count') }}</span>
|
||||
</div>
|
||||
|
||||
<div v-loading="loading" element-loading-background="#FFFFFF">
|
||||
<div v-show="loadError"
|
||||
style="width: 100%; height: 300px; display: flex; flex-direction: column; justify-content: center;align-items: center">
|
||||
style="width: 100%; height: 300px; display: flex; flex-direction: column; justify-content: center; align-items: center">
|
||||
<img style="height: 100px;width: 100px;"
|
||||
src="/assets/figma/icon_load_error.svg"/>
|
||||
<span class="addition-info-title" style="color: #646A73">{{ $t("home.dashboard.public.load_error") }}</span>
|
||||
</div>
|
||||
<div v-show="!loadError">
|
||||
<div class="main-info">
|
||||
<bug-count-chart :bug-data="bugData" ref="countChart" @redirectPage="redirectPage"/>
|
||||
<count-chart :chart-data="bugData.chartData" :main-title="chartMainTitle"
|
||||
:week-count="bugData.thisWeekAddedCount" :chart-sub-link="chartRedirectLink" ref="countChart" @redirectPage="redirectPage"/>
|
||||
</div>
|
||||
<div class="addition-info">
|
||||
<el-row :gutter="24" style="margin: 0">
|
||||
|
@ -34,7 +34,7 @@
|
|||
{{ $t('home.bug_dashboard.un_closed_count') }}
|
||||
</span>
|
||||
<div class="common-amount">
|
||||
<el-link class="addition-info-num">
|
||||
<el-link class="addition-info-num" @click="redirectPage('unClosedRelatedTestPlan')">
|
||||
{{ formatAmount(bugData.bugUnclosedCount) }}
|
||||
</el-link>
|
||||
</div>
|
||||
|
@ -44,7 +44,7 @@
|
|||
{{ $t('home.bug_dashboard.total_count') }}
|
||||
</span>
|
||||
<div class="common-amount">
|
||||
<el-link class="addition-info-num">
|
||||
<el-link class="addition-info-num" @click="redirectPage('AllRelatedTestPlan')">
|
||||
{{ formatAmount(bugData.bugTotalCount) }}
|
||||
</el-link>
|
||||
</div>
|
||||
|
@ -59,24 +59,28 @@
|
|||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import bugCountChart from "@/business/home/components/chart/BugCountChart";
|
||||
import countChart from "@/business/home/components/chart/CountChart";
|
||||
import hoverCard from "@/business/home/components/card/HoverCard";
|
||||
import {getCurrentProjectID} from "metersphere-frontend/src/utils/token";
|
||||
import {getTrackBugCount} from "@/api/track";
|
||||
import {formatNumber} from "@/api/track"
|
||||
import {getUUID} from "metersphere-frontend/src/utils";
|
||||
|
||||
export default {
|
||||
name: "BugCountCard",
|
||||
components: {bugCountChart, hoverCard},
|
||||
components: {countChart, hoverCard},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
loadError: false,
|
||||
unClosedBugRangeToolTip: this.$t('home.bug_dashboard.un_closed_range_tips'),
|
||||
unClosedBugCaseRangeToolTip: this.$t('home.bug_dashboard.un_closed_bug_case_range_tips'),
|
||||
chartMainTitle: this.$t("home.bug_dashboard.un_closed_bug_count"),
|
||||
chartRedirectLink: "/#/track/issue/" + getUUID() + "/" + getCurrentProjectID() + "/thisWeekUnClosedIssue",
|
||||
bugData: {
|
||||
bugCaseRage:" 0%",
|
||||
bugTotalCount: 0,
|
||||
|
@ -87,7 +91,8 @@ export default {
|
|||
resolvedCount: 0,
|
||||
rejectedCount: 0,
|
||||
unKnownCount: 0,
|
||||
thisWeekCount: 0
|
||||
thisWeekCount: 0,
|
||||
chartData: {}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
@ -114,7 +119,8 @@ export default {
|
|||
return formatNumber(number);
|
||||
},
|
||||
redirectPage(clickType) {
|
||||
this.$emit("redirectPage", "testCase", "relationCase", clickType);
|
||||
let currentProjectId = getCurrentProjectID();
|
||||
this.$emit("redirectPage", "issue", currentProjectId, clickType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
<template>
|
||||
<el-card class="table-card" shadow="never" body-style="padding: 10px 5px;">
|
||||
<div slot="header">
|
||||
<span class="title">
|
||||
{{ $t('test_track.home.case_count') }}
|
||||
</span>
|
||||
<div class="dashboard-card">
|
||||
<el-card shadow="never" class="box-card" style="height: 100%">
|
||||
<div slot="header" class="clearfix">
|
||||
<span class="dashboard-title">{{ $t('test_track.home.case_count') }}</span>
|
||||
</div>
|
||||
|
||||
<div v-loading="loading" element-loading-background="#FFFFFF">
|
||||
<div v-show="loadError"
|
||||
style="width: 100%; height: 300px; display: flex; flex-direction: column; justify-content: center;align-items: center">
|
||||
style="width: 100%; height: 300px; display: flex; flex-direction: column; justify-content: center; align-items: center">
|
||||
<img style="height: 100px;width: 100px;"
|
||||
src="/assets/figma/icon_load_error.svg"/>
|
||||
<span class="addition-info-title" style="color: #646A73">{{ $t("home.dashboard.public.load_error") }}</span>
|
||||
</div>
|
||||
<div v-show="!loadError">
|
||||
<div class="main-info">
|
||||
<case-count-chart :track-data="trackData" ref="countChart" @redirectPage="redirectPage"/>
|
||||
<count-chart :chart-data="trackData.chartData" :main-title="chartMainTitle"
|
||||
:week-count="trackData.thisWeekAddedCount" :chart-sub-link="chartRedirectLink" ref="countChart" @redirectPage="redirectPage"/>
|
||||
</div>
|
||||
<div class="addition-info">
|
||||
<el-row :gutter="16" style="margin: 0">
|
||||
|
@ -34,7 +34,7 @@
|
|||
{{ $t('home.case_review_dashboard.not_review') }}
|
||||
</span>
|
||||
<div class="common-amount">
|
||||
<el-link class="addition-info-num" @click="redirectPage('notReviewed')" v-permission-disable="['PROJECT_TRACK_CASE:READ']">
|
||||
<el-link class="addition-info-num" @click="redirectPage('notReviewed')">
|
||||
{{ formatAmount(trackData.prepareCount) }}
|
||||
</el-link>
|
||||
</div>
|
||||
|
@ -44,7 +44,7 @@
|
|||
{{ $t('home.case_review_dashboard.finished_review') }}
|
||||
</span>
|
||||
<div class="common-amount">
|
||||
<el-link class="addition-info-num" @click="redirectPage('reviewed')" v-permission-disable="['PROJECT_TRACK_CASE:READ']">
|
||||
<el-link class="addition-info-num" @click="redirectPage('reviewed')">
|
||||
{{ formatAmount(trackData.passCount + trackData.unPassCount) }}
|
||||
</el-link>
|
||||
</div>
|
||||
|
@ -70,7 +70,7 @@
|
|||
{{ $t("home.case_review_dashboard.not_pass") }}
|
||||
</span>
|
||||
<div class="common-amount">
|
||||
<el-link class="addition-info-num" @click="redirectPage('UnPass')" v-permission-disable="['PROJECT_TRACK_CASE:READ']">
|
||||
<el-link class="addition-info-num" @click="redirectPage('UnPass')">
|
||||
{{ formatAmount(trackData.unPassCount) }}
|
||||
</el-link>
|
||||
</div>
|
||||
|
@ -80,7 +80,7 @@
|
|||
{{ $t("home.case_review_dashboard.pass") }}
|
||||
</span>
|
||||
<div class="common-amount">
|
||||
<el-link class="addition-info-num" @click="redirectPage('Pass')" v-permission-disable="['PROJECT_TRACK_CASE:READ']">
|
||||
<el-link class="addition-info-num" @click="redirectPage('Pass')">
|
||||
{{ formatAmount(trackData.passCount) }}
|
||||
</el-link>
|
||||
</div>
|
||||
|
@ -95,25 +95,28 @@
|
|||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import caseCountChart from "@/business/home/components/chart/CaseCountChart";
|
||||
import countChart from "@/business/home/components/chart/CountChart";
|
||||
import hoverCard from "@/business/home/components/card/HoverCard";
|
||||
import {getUUID} from "metersphere-frontend/src/utils";
|
||||
import {getCurrentProjectID} from "metersphere-frontend/src/utils/token";
|
||||
import {getTrackCount} from "@/api/track";
|
||||
import {formatNumber} from "@/api/track"
|
||||
import {hasPermission} from "@/business/utils/sdk-utils";
|
||||
|
||||
export default {
|
||||
name: "CaseCountCard",
|
||||
components: {caseCountChart, hoverCard},
|
||||
components: {countChart, hoverCard},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
loadError: false,
|
||||
caseReviewRangeToolTip: this.$t('api_test.home_page.formula.review'),
|
||||
caseFinishedReviewPassRageToolTip: this.$t('home.dashboard.case_finished_review_pass_tip'),
|
||||
chartMainTitle: this.$t("home.case_review_dashboard.case_count"),
|
||||
chartRedirectLink: "/#/track/case/all/" + getUUID() + "/case/thisWeekCount",
|
||||
trackData: {
|
||||
allCaseCountNumber: 0,
|
||||
allRelevanceCaseCount: 0,
|
||||
|
@ -135,7 +138,8 @@ export default {
|
|||
scenarioCaseStr: "",
|
||||
thisWeekAddedCount: 0,
|
||||
unPassCount: 0,
|
||||
uncoverageCount: 0
|
||||
uncoverageCount: 0,
|
||||
chartData: {},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
@ -163,9 +167,6 @@ export default {
|
|||
return formatNumber(number);
|
||||
},
|
||||
redirectPage(clickType) {
|
||||
if (!hasPermission('PROJECT_TRACK_CASE:READ')) {
|
||||
return;
|
||||
}
|
||||
this.$emit("redirectPage", "testCase", "case", clickType);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
<template>
|
||||
<el-card class="table-card" shadow="never" body-style="padding:10px;">
|
||||
<div slot="header">
|
||||
<span class="title">
|
||||
{{ $t('test_track.home.case_maintenance') }}
|
||||
</span>
|
||||
<div class="dashboard-card">
|
||||
<el-card shadow="never" class="box-card" style="height: 100%">
|
||||
<div slot="header" class="clearfix">
|
||||
<span class="dashboard-title">{{ $t('test_track.home.case_maintenance') }}</span>
|
||||
</div>
|
||||
|
||||
<div v-loading="loading" element-loading-background="#FFFFFF">
|
||||
|
@ -15,11 +14,12 @@
|
|||
</div>
|
||||
<div v-show="!loadError">
|
||||
<el-container>
|
||||
<ms-chart ref="chart1" :options="caseOption" :autoresize="true" style="width: 100%;height: 323px"></ms-chart>
|
||||
<ms-chart ref="chart1" :options="caseOption" :autoresize="true" style="width: 100%;height: 323px;"></ms-chart>
|
||||
</el-container>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -88,12 +88,21 @@ export default {
|
|||
show: false
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: 0,
|
||||
containLabel: true,
|
||||
bottom: 24,
|
||||
top: 60,
|
||||
right: 24,
|
||||
width: 600,
|
||||
height: 250
|
||||
},
|
||||
legend: {
|
||||
itemWidth: 8,
|
||||
itemHeight: 8,
|
||||
data: [{icon: 'rect', name: this.$t('test_track.home.function_case_count')}, {icon: 'rect', name: this.$t('test_track.home.relevance_case_count')}],
|
||||
orient: 'horizontal',
|
||||
left: '30',
|
||||
left: '0',
|
||||
top: '10'
|
||||
},
|
||||
series: [
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<el-card class="table-card" shadow="never" v-loading="loading" body-style="padding:10px;">
|
||||
<el-card class="table-card" shadow="never" v-loading="loading">
|
||||
<template v-slot:header>
|
||||
<span class="table-title">
|
||||
{{ $t('api_test.home_page.failed_case_list.title') }}
|
||||
|
@ -14,8 +14,8 @@
|
|||
</div>
|
||||
<div v-show="!loadError">
|
||||
<el-table :data="tableData" class="adjust-table table-content"
|
||||
:header-cell-style="{backgroundColor: '#F5F6F7'}" max-height="224px">
|
||||
<el-table-column type="index" :label="$t('home.case.index')" show-overflow-tooltip/>
|
||||
header-cell-class-name="home-table-cell" max-height="226px">
|
||||
<el-table-column type="index" :label="$t('home.case.index')" width="100" show-overflow-tooltip/>
|
||||
<el-table-column prop="caseName" :label="$t('home.case.case_name')">
|
||||
<template v-slot:default="{row}">
|
||||
<el-link type="info" @click="redirect(row.caseType,row.id)"
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
<template>
|
||||
<el-card class="table-card" shadow="never" body-style="padding:10px 5px;">
|
||||
<div slot="header">
|
||||
<span class="title">
|
||||
{{ $t('test_track.home.relevance_case') }}
|
||||
</span>
|
||||
<div class="dashboard-card">
|
||||
<el-card shadow="never" class="box-card" style="height: 100%">
|
||||
<div slot="header" class="clearfix">
|
||||
<span class="dashboard-title">{{ $t('test_track.home.relevance_case') }}</span>
|
||||
</div>
|
||||
|
||||
<div v-loading="loading" element-loading-background="#FFFFFF">
|
||||
<div v-show="loadError"
|
||||
style="width: 100%; height: 300px; display: flex; flex-direction: column; justify-content: center;align-items: center">
|
||||
style="width: 100%; height: 300px; display: flex; flex-direction: column; justify-content: center; align-items: center">
|
||||
<img style="height: 100px;width: 100px;"
|
||||
src="/assets/figma/icon_load_error.svg"/>
|
||||
<span class="addition-info-title" style="color: #646A73">{{ $t("home.dashboard.public.load_error") }}</span>
|
||||
</div>
|
||||
<div v-show="!loadError">
|
||||
<div class="main-info">
|
||||
<relevance-count-chart :relevance-data="relevanceData" ref="countChart" @redirectPage="redirectPage"/>
|
||||
<count-chart :chart-data="relevanceData.chartData" :main-title="chartMainTitle"
|
||||
:week-count="relevanceData.thisWeekAddedCount" :chart-sub-link="chartRedirectLink" ref="countChart" @redirectPage="redirectPage"/>
|
||||
</div>
|
||||
<div class="addition-info">
|
||||
<el-row :gutter="24" style="margin: 0">
|
||||
|
@ -34,7 +34,7 @@
|
|||
{{ $t('home.relevance_dashboard.not_cover') }}
|
||||
</span>
|
||||
<div class="common-amount">
|
||||
<el-link class="addition-info-num" @click="redirectPage('uncoverage')" v-permission-disable="['PROJECT_TRACK_CASE:READ']">
|
||||
<el-link class="addition-info-num" @click="redirectPage('uncoverage')">
|
||||
{{ formatAmount(relevanceData.uncoverageCount) }}
|
||||
</el-link>
|
||||
</div>
|
||||
|
@ -44,7 +44,7 @@
|
|||
{{ $t('home.relevance_dashboard.cover') }}
|
||||
</span>
|
||||
<div class="common-amount">
|
||||
<el-link class="addition-info-num" @click="redirectPage('coverage')" v-permission-disable="['PROJECT_TRACK_CASE:READ']">
|
||||
<el-link class="addition-info-num" @click="redirectPage('coverage')">
|
||||
{{ formatAmount(relevanceData.coverageCount) }}
|
||||
</el-link>
|
||||
</div>
|
||||
|
@ -59,23 +59,27 @@
|
|||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import relevanceCountChart from "@/business/home/components/chart/RelevanceCountChart";
|
||||
import countChart from "@/business/home/components/chart/CountChart";
|
||||
import hoverCard from "@/business/home/components/card/HoverCard";
|
||||
import {getCurrentProjectID} from "metersphere-frontend/src/utils/token";
|
||||
import {getTrackRelevanceCount} from "@/api/track";
|
||||
import {formatNumber} from "@/api/track"
|
||||
import {getUUID} from "metersphere-frontend/src/utils";
|
||||
|
||||
export default {
|
||||
name: "RelevanceCaseCard",
|
||||
components: {relevanceCountChart, hoverCard},
|
||||
components: {countChart, hoverCard},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
loadError: false,
|
||||
coverRangeToolTip: this.$t('api_test.home_page.formula.testplan_coverage'),
|
||||
chartMainTitle: this.$t("home.relevance_dashboard.relevance_case_count"),
|
||||
chartRedirectLink: "/#/track/case/all/" + getUUID() + "/case/thisWeekRelevanceCount",
|
||||
relevanceData: {
|
||||
allCaseCountNumber: 0,
|
||||
allRelevanceCaseCount: 0,
|
||||
|
@ -97,7 +101,8 @@ export default {
|
|||
scenarioCaseStr: "",
|
||||
thisWeekAddedCount: 0,
|
||||
unPassCount: 0,
|
||||
uncoverageCount: 0
|
||||
uncoverageCount: 0,
|
||||
chartData: {}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
</span>
|
||||
|
||||
<div class="btn-group">
|
||||
<ms-table-button icon="" :class="!showMyCreator ? 'hover' : 'reviewedBtn'" :content="$t('test_track.review.reviewed_by_me')" @click="searchMyCreator('false')" style="border-color: #FFFFFF"/>
|
||||
<ms-table-button icon="" :class="showMyCreator ? 'hover' : 'createBtn'" :content="$t('test_track.review.my_create')" @click="searchMyCreator('true')" style="border-color: #FFFFFF; margin-left: 3px"/>
|
||||
<ms-table-button icon="" :class="!showMyCreator ? 'hover reviewedBtn' : 'reviewedBtn'" :content="$t('test_track.review.reviewed_by_me')" @click="searchMyCreator('false')" style="border-color: #FFFFFF"/>
|
||||
<ms-table-button icon="" :class="showMyCreator ? 'hover createBtn' : 'createBtn'" :content="$t('test_track.review.my_create')" @click="searchMyCreator('true')" style="border-color: #FFFFFF; margin-left: 3px"/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-loading="loading" element-loading-background="#FFFFFF">
|
||||
|
@ -19,8 +19,8 @@
|
|||
</div>
|
||||
<div v-show="!loadError">
|
||||
<el-table class="adjust-table" :data="tableData" @row-click="intoPlan"
|
||||
:header-cell-style="{backgroundColor: '#F5F6F7'}" max-height="224px">
|
||||
<el-table-column type="index" :label="$t('home.table.index')" show-overflow-tooltip />
|
||||
header-cell-class-name="home-table-cell" max-height="226px">
|
||||
<el-table-column type="index" width="100" :label="$t('home.table.index')" show-overflow-tooltip />
|
||||
<el-table-column prop="name" :label="$t('commons.name')" show-overflow-tooltip />
|
||||
<el-table-column prop="status" :label="$t('test_track.plan.plan_status')">
|
||||
<template v-slot:default="scope">
|
||||
|
@ -146,26 +146,59 @@ export default {
|
|||
border: 1px solid #BBBFC4;
|
||||
border-radius: 4px;
|
||||
margin: 1px;
|
||||
width: 182px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
:deep(button.el-button.el-button--mini.is-plain.hover) {
|
||||
background: rgba(120, 56, 135, 0.1);
|
||||
border-radius: 4px;
|
||||
color: #783887;
|
||||
background-color: rgba(120, 56, 135, 0.1);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.reviewedBtn.el-button--mini.is-plain:hover {
|
||||
:deep(button.el-button.el-button--mini.is-plain.createBtn) {
|
||||
width: 100px;
|
||||
height: 24px;
|
||||
position: relative;
|
||||
left: 4px;
|
||||
top: 4px;
|
||||
}
|
||||
|
||||
:deep(button.el-button.el-button--mini.is-plain.reviewedBtn) {
|
||||
width: 72px;
|
||||
height: 24px;
|
||||
position: relative;
|
||||
left: 4px;
|
||||
top: 4px;
|
||||
}
|
||||
|
||||
:deep(.reviewedBtn.el-button--mini.is-plain:hover) {
|
||||
background: rgba(120, 56, 135, 0.1);
|
||||
border-radius: 4px;
|
||||
color: #783887;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.createBtn.el-button--mini.is-plain:hover {
|
||||
:deep(.createBtn.el-button--mini.is-plain:hover) {
|
||||
background: rgba(120, 56, 135, 0.1);
|
||||
border-radius: 4px;
|
||||
color: #783887;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
:deep(button.el-button.el-button--mini.is-plain span) {
|
||||
font-family: 'PingFang SC';
|
||||
font-style: normal;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
flex: none;
|
||||
order: 0;
|
||||
flex-grow: 0;
|
||||
position: relative;
|
||||
right: 3px;
|
||||
bottom: 8px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
:enable-selection="false"
|
||||
:condition="condition"
|
||||
:data="tableData"
|
||||
:header-cell-style="{ backgroundColor: '#F5F6F7' }"
|
||||
@refresh="search" max-height="224px">
|
||||
<el-table-column type="index" :label="$t('home.table.index')" show-overflow-tooltip/>
|
||||
@refresh="search"
|
||||
header-cell-class-name="home-table-cell" max-height="226px">
|
||||
<el-table-column type="index" width="100" :label="$t('home.table.index')" show-overflow-tooltip/>
|
||||
<el-table-column prop="name" :label="$t('commons.name')">
|
||||
<template v-slot:default="{row}">
|
||||
<!-- 若为只读用户不可点击之后跳转-->
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<div v-show="!isHover" class="transition-box">
|
||||
<div style="margin:16px 0 0 16px">
|
||||
<span class="addition-info-title"> {{ title }}</span>
|
||||
<el-tooltip class="item" effect="light" :content="toolTip" placement="top-start">
|
||||
<el-tooltip class="item" effect="dark" :content="toolTip" placement="top-start">
|
||||
<img style="height: 14px;width: 14px;margin-left: 4px" src="/assets/figma/icon_question.svg"/>
|
||||
</el-tooltip>
|
||||
<div class="common-amount" @mouseenter="isHover=true">
|
||||
|
|
|
@ -1,222 +0,0 @@
|
|||
<template>
|
||||
<div v-if="reloadOver">
|
||||
<el-row type="flex" justify="left" align="left">
|
||||
<div style="height: 184px;width: 184px;margin-left: 30px;margin-right: 30px;">
|
||||
<ms-chart :options="options"
|
||||
:height="184"
|
||||
:width="184"
|
||||
:autoresize="true"/>
|
||||
</div>
|
||||
|
||||
<!-- 总数统计 -->
|
||||
<div style="margin: auto;width: 260px;padding-right: 30px">
|
||||
<div class="count-row">
|
||||
<span class="ms-point-new"/>
|
||||
<span class="count-title">{{ $t('test_track.issue.status_new') }}</span>
|
||||
<span class="count-value">
|
||||
{{ formatAmount(bugData.newCount) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="count-row">
|
||||
<span class="ms-point-resolved"/>
|
||||
<span class="count-title">{{ $t('test_track.issue.status_resolved') }}</span>
|
||||
<span class="count-value">
|
||||
{{ formatAmount(bugData.resolvedCount) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="count-row">
|
||||
<span class="ms-point-rejected"/>
|
||||
<span class="count-title">{{ $t('test_track.issue.status_rejected') }}</span>
|
||||
<span class="count-value">
|
||||
{{ formatAmount(bugData.rejectedCount) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsChart from "metersphere-frontend/src/components/chart/MsChart";
|
||||
import {getUUID} from "metersphere-frontend/src/utils";
|
||||
import {formatNumber} from "@/api/track";
|
||||
import {getCurrentProjectID} from "@/business/utils/sdk-utils";
|
||||
|
||||
export default {
|
||||
name: "CountChart",
|
||||
components: {MsChart},
|
||||
props: {
|
||||
bugData: Object,
|
||||
totalTime: Number,
|
||||
isExport: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
reloadOver: true,
|
||||
pieChartStyle: {
|
||||
amountFontSize: 32,
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
},
|
||||
methods: {
|
||||
reload() {
|
||||
this.reloadOver = false;
|
||||
this.$nextTick(() => {
|
||||
this.reloadOver = true;
|
||||
});
|
||||
},
|
||||
getTotal() {
|
||||
let total = 0;
|
||||
if (this.bugData.newCount) {
|
||||
total += this.bugData.newCount;
|
||||
}
|
||||
if (this.bugData.resolvedCount) {
|
||||
total += this.bugData.resolvedCount;
|
||||
}
|
||||
if (this.bugData.rejectedCount) {
|
||||
total += this.bugData.rejectedCount;
|
||||
}
|
||||
return total;
|
||||
},
|
||||
getAmount() {
|
||||
let total = this.getTotal();
|
||||
if (total > 999999999) {
|
||||
this.pieChartStyle.amountFontSize = 20;
|
||||
} else if (total > 99999999) {
|
||||
this.pieChartStyle.amountFontSize = 22;
|
||||
} else if (total > 9999999) {
|
||||
this.pieChartStyle.amountFontSize = 24;
|
||||
} else if (total > 999999) {
|
||||
this.pieChartStyle.amountFontSize = 26;
|
||||
} else {
|
||||
this.pieChartStyle.amountFontSize = 32;
|
||||
}
|
||||
total = this.formatAmount(total);
|
||||
return total;
|
||||
},
|
||||
formatAmount(param) {
|
||||
return formatNumber(param);
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
options() {
|
||||
let protocolData = [{value: 0}];
|
||||
let colorArr = ['#DEE0E3'];
|
||||
if (this.getTotal() > 0) {
|
||||
colorArr = ['#AA4FBF', '#14E1C6', '#FAD355',]
|
||||
protocolData = [
|
||||
{value: this.bugData.newCount, name: this.$t('test_track.issue.status_new')},
|
||||
{value: this.bugData.resolvedCount, name: this.$t('test_track.issue.status_resolved')},
|
||||
{value: this.bugData.rejectedCount, name: this.$t('test_track.issue.status_rejected')},
|
||||
];
|
||||
}
|
||||
let optionData = {
|
||||
color: colorArr,
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
title: {
|
||||
text: "{mainTitle|" + this.$t("home.bug_dashboard.un_closed_bug_count") + "}\n\n{number|" + this.getAmount() + "}\n\n",
|
||||
subtext: this.$t("home.dashboard.public.this_week") + ": +" + this.bugData.thisWeekCount + " >",
|
||||
top: "center",
|
||||
left: "center",
|
||||
textStyle: {
|
||||
rich: {
|
||||
mainTitle: {
|
||||
color: '#646A73',
|
||||
fontSize: 12,
|
||||
},
|
||||
number: {
|
||||
fontSize: this.pieChartStyle.amountFontSize,
|
||||
fontWeight: 500,
|
||||
fontStyle: "normal",
|
||||
fontFamily: "PinfFang SC",
|
||||
margin: "112px 0px 0px 2px0",
|
||||
},
|
||||
}
|
||||
},
|
||||
sublink: "/#/track/issue/" + getUUID() + "/" + getCurrentProjectID() + "/thisWeekUnClosedIssue",
|
||||
subtextStyle: {
|
||||
color: "#1F2329",
|
||||
fontSize: 12,
|
||||
width: 105,
|
||||
ellipsis: '... >',
|
||||
overflow: "truncate",
|
||||
},
|
||||
itemGap: -60,
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['75%', '96%'],
|
||||
avoidLabelOverlap: false,
|
||||
hoverAnimation: true,
|
||||
label: {
|
||||
show: false,
|
||||
},
|
||||
itemStyle: {
|
||||
borderColor: "#FFF",
|
||||
borderWidth: 3,
|
||||
borderRadius: 1,
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: protocolData,
|
||||
}
|
||||
]
|
||||
};
|
||||
return optionData;
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.count-row {
|
||||
padding: 8px 0px 8px 0px;
|
||||
}
|
||||
|
||||
.count-title {
|
||||
color: #646A73;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.count-value {
|
||||
color: #646A73;
|
||||
float: right;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.ms-point-rejected {
|
||||
height: 8px;
|
||||
width: 8px;
|
||||
margin-right: 8px;
|
||||
display: inline-block;
|
||||
background-color: #FAD355;
|
||||
}
|
||||
|
||||
.ms-point-resolved {
|
||||
height: 8px;
|
||||
width: 8px;
|
||||
margin-right: 8px;
|
||||
display: inline-block;
|
||||
background-color: #14E1C6;
|
||||
}
|
||||
|
||||
.ms-point-new {
|
||||
height: 8px;
|
||||
width: 8px;
|
||||
margin-right: 8px;
|
||||
display: inline-block;
|
||||
background-color: #AA4FBF;
|
||||
}
|
||||
</style>
|
|
@ -1,242 +0,0 @@
|
|||
<template>
|
||||
<div v-if="reloadOver">
|
||||
<el-row type="flex" justify="left" align="left">
|
||||
<div style="height: 184px;width: 184px;margin-left: 30px;margin-right: 30px;">
|
||||
<ms-chart :options="options"
|
||||
:height="184"
|
||||
:width="184"
|
||||
:autoresize="true"/>
|
||||
</div>
|
||||
|
||||
<!-- 总数统计 -->
|
||||
<div style="margin: auto;width: 260px;padding-right: 30px">
|
||||
<div class="count-row">
|
||||
<div>
|
||||
<span class="ms-point-p0"/>
|
||||
<span class="count-title">P0</span>
|
||||
<span class="count-value">
|
||||
{{ formatAmount(trackData.p0CaseCountNumber) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="count-row">
|
||||
<span class="ms-point-p1"/>
|
||||
<span class="count-title">P1</span>
|
||||
<span class="count-value">
|
||||
{{ formatAmount(trackData.p1CaseCountNumber) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="count-row">
|
||||
<span class="ms-point-p2"/>
|
||||
<span class="count-title">P2</span>
|
||||
<span class="count-value">
|
||||
{{ formatAmount(trackData.p2CaseCountNumber) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="count-row">
|
||||
<span class="ms-point-p3"/>
|
||||
<span class="count-title">P3</span>
|
||||
<span class="count-value">
|
||||
{{ formatAmount(trackData.p3CaseCountNumber) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsChart from "metersphere-frontend/src/components/chart/MsChart";
|
||||
import {getUUID} from "metersphere-frontend/src/utils";
|
||||
import {formatNumber} from "@/api/track";
|
||||
import {hasPermission} from "@/business/utils/sdk-utils";
|
||||
|
||||
export default {
|
||||
name: "CaseCountChart",
|
||||
components: {MsChart},
|
||||
props: {
|
||||
trackData: Object,
|
||||
totalTime: Number,
|
||||
isExport: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
reloadOver: true,
|
||||
pieChartStyle: {
|
||||
amountFontSize: 32,
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
},
|
||||
methods: {
|
||||
reload() {
|
||||
this.reloadOver = false;
|
||||
this.$nextTick(() => {
|
||||
this.reloadOver = true;
|
||||
});
|
||||
},
|
||||
getTotal() {
|
||||
let total = 0;
|
||||
if (this.trackData.p0CaseCountNumber) {
|
||||
total += this.trackData.p0CaseCountNumber;
|
||||
}
|
||||
if (this.trackData.p0CaseCountNumber) {
|
||||
total += this.trackData.p1CaseCountNumber;
|
||||
}
|
||||
if (this.trackData.p0CaseCountNumber) {
|
||||
total += this.trackData.p2CaseCountNumber;
|
||||
}
|
||||
if (this.trackData.p0CaseCountNumber) {
|
||||
total += this.trackData.p3CaseCountNumber;
|
||||
}
|
||||
return total;
|
||||
},
|
||||
getAmount() {
|
||||
let total = this.getTotal();
|
||||
if (total > 999999999) {
|
||||
this.pieChartStyle.amountFontSize = 20;
|
||||
} else if (total > 99999999) {
|
||||
this.pieChartStyle.amountFontSize = 22;
|
||||
} else if (total > 9999999) {
|
||||
this.pieChartStyle.amountFontSize = 24;
|
||||
} else if (total > 999999) {
|
||||
this.pieChartStyle.amountFontSize = 26;
|
||||
} else {
|
||||
this.pieChartStyle.amountFontSize = 32;
|
||||
}
|
||||
total = this.formatAmount(total);
|
||||
return total;
|
||||
},
|
||||
formatAmount(param) {
|
||||
return formatNumber(param);
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
options() {
|
||||
let protocolData = [{value: 0}];
|
||||
let colorArr = ['#DEE0E3'];
|
||||
if (this.getTotal() > 0) {
|
||||
colorArr = ['#F76964', '#FFD131', '#AA4FBF', '#10CECE']
|
||||
protocolData = [
|
||||
{value: this.trackData.p0CaseCountNumber, name: 'P0'},
|
||||
{value: this.trackData.p1CaseCountNumber, name: 'P1'},
|
||||
{value: this.trackData.p2CaseCountNumber, name: 'P2'},
|
||||
{value: this.trackData.p3CaseCountNumber, name: 'P3'},
|
||||
];
|
||||
}
|
||||
let optionData = {
|
||||
color: colorArr,
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
title: {
|
||||
text: "{mainTitle|" + this.$t("home.case_review_dashboard.case_count") + "}\n\n{number|" + this.getAmount() + "}\n\n",
|
||||
subtext: this.$t("home.dashboard.public.this_week") + ": +" + this.trackData.thisWeekAddedCount + " >",
|
||||
top: "center",
|
||||
left: "center",
|
||||
textStyle: {
|
||||
rich: {
|
||||
mainTitle: {
|
||||
color: '#646A73',
|
||||
fontSize: 12,
|
||||
},
|
||||
number: {
|
||||
fontSize: this.pieChartStyle.amountFontSize,
|
||||
fontWeight: 500,
|
||||
fontStyle: "normal",
|
||||
fontFamily: "PinfFang SC",
|
||||
margin: "112px 0px 0px 2px0",
|
||||
},
|
||||
}
|
||||
},
|
||||
sublink: hasPermission('PROJECT_TRACK_CASE:READ') ? "/#/track/case/all/" + getUUID() + "/case/thisWeekCount" : '',
|
||||
subtextStyle: {
|
||||
color: "#1F2329",
|
||||
fontSize: 12,
|
||||
width: 105,
|
||||
ellipsis: '...',
|
||||
overflow: "truncate",
|
||||
},
|
||||
itemGap: -60,
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['70%', '96%'],
|
||||
avoidLabelOverlap: false,
|
||||
hoverAnimation: true,
|
||||
label: {
|
||||
show: false,
|
||||
},
|
||||
itemStyle: {
|
||||
borderColor: "#FFF",
|
||||
borderWidth: 3,
|
||||
borderRadius: 1,
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: protocolData,
|
||||
}
|
||||
]
|
||||
};
|
||||
return optionData;
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.count-row {
|
||||
padding: 8px 0px 8px 0px;
|
||||
}
|
||||
|
||||
.count-title {
|
||||
color: #646A73;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.count-value {
|
||||
color: #646A73;
|
||||
float: right;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.ms-point-p0 {
|
||||
height: 8px;
|
||||
width: 8px;
|
||||
margin-right: 8px;
|
||||
display: inline-block;
|
||||
background-color: #F76964;
|
||||
}
|
||||
|
||||
.ms-point-p1 {
|
||||
height: 8px;
|
||||
width: 8px;
|
||||
margin-right: 8px;
|
||||
display: inline-block;
|
||||
background-color: #FFD131;
|
||||
}
|
||||
|
||||
.ms-point-p2 {
|
||||
height: 8px;
|
||||
width: 8px;
|
||||
margin-right: 8px;
|
||||
display: inline-block;
|
||||
background-color: #AA4FBF;
|
||||
}
|
||||
|
||||
.ms-point-p3 {
|
||||
height: 8px;
|
||||
width: 8px;
|
||||
margin-right: 8px;
|
||||
display: inline-block;
|
||||
background-color: #14E1C6;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,228 @@
|
|||
<template>
|
||||
<div v-if="reloadOver">
|
||||
<el-row type="flex" justify="left" align="left">
|
||||
<div style="height: 184px; width: 100%; margin-left: 30px; margin-right: 30px;">
|
||||
<ms-chart :options="options"
|
||||
:height="184"
|
||||
width="100%"
|
||||
:autoresize="true"/>
|
||||
</div>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsChart from "metersphere-frontend/src/components/chart/MsChart";
|
||||
import {formatNumber} from "@/api/track";
|
||||
import {DASHBOARD_CHART_COLOR} from "@/business/constants/table-constants";
|
||||
|
||||
export default {
|
||||
name: "CountChart",
|
||||
components: {MsChart},
|
||||
props: {
|
||||
chartData: Object,
|
||||
weekCount: Number,
|
||||
totalTime: Number,
|
||||
mainTitle: String,
|
||||
chartSubLink: String,
|
||||
isExport: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
reloadOver: true,
|
||||
pieChartStyle: {
|
||||
amountFontSize: 32,
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.reload();
|
||||
},
|
||||
methods: {
|
||||
reload() {
|
||||
this.reloadOver = false;
|
||||
this.$nextTick(() => {
|
||||
this.reloadOver = true;
|
||||
});
|
||||
},
|
||||
getTotal() {
|
||||
let total = 0;
|
||||
for (let name in this.chartData) {
|
||||
total += this.chartData[name];
|
||||
}
|
||||
return total;
|
||||
},
|
||||
getAmount() {
|
||||
let total = this.getTotal();
|
||||
if (total > 999999999) {
|
||||
this.pieChartStyle.amountFontSize = 20;
|
||||
} else if (total > 99999999) {
|
||||
this.pieChartStyle.amountFontSize = 22;
|
||||
} else if (total > 9999999) {
|
||||
this.pieChartStyle.amountFontSize = 24;
|
||||
} else if (total > 999999) {
|
||||
this.pieChartStyle.amountFontSize = 26;
|
||||
} else {
|
||||
this.pieChartStyle.amountFontSize = 32;
|
||||
}
|
||||
total = this.formatAmount(total);
|
||||
return total;
|
||||
},
|
||||
formatAmount(param) {
|
||||
return formatNumber(param);
|
||||
},
|
||||
getChartData(empty) {
|
||||
let elementArr = [];
|
||||
if (empty) {
|
||||
for (let name in this.chartData) {
|
||||
let element = {name: name, value: 0};
|
||||
elementArr.push(element);
|
||||
}
|
||||
return elementArr;
|
||||
} else {
|
||||
for (let name in this.chartData) {
|
||||
let element = {name: name, value: this.chartData[name]};
|
||||
elementArr.push(element);
|
||||
}
|
||||
}
|
||||
return elementArr;
|
||||
},
|
||||
getChartColor(size, empty) {
|
||||
let colorArr = [];
|
||||
if (empty) {
|
||||
for (let i = 0; i < size; i++) {
|
||||
colorArr.push("#DEE0E3");
|
||||
}
|
||||
} else {
|
||||
colorArr = DASHBOARD_CHART_COLOR.slice(0, size);
|
||||
}
|
||||
return colorArr;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
options() {
|
||||
let dataIsNotEmpty = false;
|
||||
let borderWidth = 0;
|
||||
let elementArr = this.getChartData(true);
|
||||
let colorArr = this.getChartColor(elementArr.length, true);
|
||||
if (this.getTotal() > 0) {
|
||||
borderWidth = 3;
|
||||
dataIsNotEmpty = true;
|
||||
elementArr = this.getChartData(false);
|
||||
colorArr = this.getChartColor(elementArr.length, false);
|
||||
}
|
||||
let optionData = {
|
||||
color: colorArr,
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
icon: "rect",
|
||||
selectedMode: dataIsNotEmpty,
|
||||
itemGap: 16,
|
||||
left: '45%',
|
||||
y: 'center',
|
||||
itemHeight: 8,
|
||||
itemWidth: 8, //修改icon图形大小
|
||||
itemStyle: {
|
||||
borderWidth: 0.1
|
||||
},
|
||||
textStyle: {
|
||||
align: 'right',
|
||||
rich: {
|
||||
protocol: {
|
||||
fontSize: 14,
|
||||
color: '#646A73',
|
||||
fontWeight: 400,
|
||||
width: 50,
|
||||
align: 'left',
|
||||
lineHeight: 22,
|
||||
},
|
||||
num: {
|
||||
fontSize: 14,
|
||||
align: 'right',
|
||||
lineHeight: 22,
|
||||
color: '#646A73',
|
||||
fontWeight: 500,
|
||||
padding: [0, 0, 0, 140]
|
||||
}
|
||||
}
|
||||
},
|
||||
data: elementArr,
|
||||
formatter: function (name) {
|
||||
//通过name获取到数组对象中的单个对象
|
||||
let singleData = elementArr.filter(function (item) {
|
||||
return item.name === name
|
||||
});
|
||||
let value = singleData[0].value;
|
||||
return [`{protocol|${name}}`, `{num|${value}}`].join("");
|
||||
}
|
||||
},
|
||||
title: {
|
||||
text: "{mainTitle|" + this.mainTitle + "}\n\n{number|" + this.getAmount() + "}\n\n",
|
||||
subtext: this.$t("home.dashboard.public.this_week") + ": +" + formatNumber(this.weekCount) + " >",
|
||||
top: "center",
|
||||
left: "86px",
|
||||
textAlign: 'center',
|
||||
textStyle: {
|
||||
rich: {
|
||||
mainTitle: {
|
||||
color: '#646A73',
|
||||
fontSize: 12,
|
||||
align: 'center'
|
||||
},
|
||||
number: {
|
||||
fontSize: this.pieChartStyle.amountFontSize,
|
||||
fontWeight: 500,
|
||||
fontStyle: "normal",
|
||||
fontFamily: "PinfFang SC",
|
||||
margin: "112px 0px 0px 2px0",
|
||||
},
|
||||
}
|
||||
},
|
||||
sublink: this.chartSubLink,
|
||||
subtextStyle: {
|
||||
color: "#1F2329",
|
||||
fontSize: 12,
|
||||
width: 105,
|
||||
ellipsis: '...',
|
||||
overflow: "truncate",
|
||||
},
|
||||
itemGap: -60,
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['70%', '96%'],
|
||||
center: ['92px', '50%'],
|
||||
avoidLabelOverlap: false,
|
||||
hoverAnimation: dataIsNotEmpty,
|
||||
legendHoverLink: false,
|
||||
label: {
|
||||
show: false,
|
||||
},
|
||||
itemStyle: {
|
||||
borderColor: "#FFF",
|
||||
borderWidth: borderWidth,
|
||||
borderRadius: 1,
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: elementArr,
|
||||
}
|
||||
]
|
||||
};
|
||||
return optionData;
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -1,224 +0,0 @@
|
|||
<template>
|
||||
<div v-if="reloadOver">
|
||||
<el-row type="flex" justify="left" align="left">
|
||||
<div style="height: 184px;width: 184px;margin-left: 30px;margin-right: 30px;">
|
||||
<ms-chart :options="options"
|
||||
:height="184"
|
||||
:width="184"
|
||||
:autoresize="true"/>
|
||||
</div>
|
||||
|
||||
<!-- 总数统计 -->
|
||||
<div style="margin: auto;width: 260px;padding-right: 30px">
|
||||
<div class="count-row">
|
||||
<div>
|
||||
<span class="ms-point-api"/>
|
||||
<span class="count-title">{{ $t('home.relevance_dashboard.api_case') }}</span>
|
||||
<span class="count-value">
|
||||
{{ formatAmount(relevanceData.apiCaseCount) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="count-row">
|
||||
<span class="ms-point-scenario"/>
|
||||
<span class="count-title">{{ $t('home.relevance_dashboard.scenario_case') }}</span>
|
||||
<span class="count-value">
|
||||
{{ formatAmount(relevanceData.scenarioCaseCount) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="count-row">
|
||||
<span class="ms-point-performance"/>
|
||||
<span class="count-title">{{ $t('home.relevance_dashboard.performance_case') }}</span>
|
||||
<span class="count-value">
|
||||
{{ formatAmount(relevanceData.performanceCaseCount) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsChart from "metersphere-frontend/src/components/chart/MsChart";
|
||||
import {getUUID} from "metersphere-frontend/src/utils";
|
||||
import {formatNumber} from "@/api/track";
|
||||
import {hasPermission} from "@/business/utils/sdk-utils";
|
||||
|
||||
export default {
|
||||
name: "RelevanceCountChart",
|
||||
components: {MsChart},
|
||||
props: {
|
||||
relevanceData: Object,
|
||||
totalTime: Number,
|
||||
isExport: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
reloadOver: true,
|
||||
pieChartStyle: {
|
||||
amountFontSize: 32,
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
},
|
||||
methods: {
|
||||
reload() {
|
||||
this.reloadOver = false;
|
||||
this.$nextTick(() => {
|
||||
this.reloadOver = true;
|
||||
});
|
||||
},
|
||||
getTotal() {
|
||||
let total = 0;
|
||||
if (this.relevanceData.apiCaseCount) {
|
||||
total += this.relevanceData.apiCaseCount;
|
||||
}
|
||||
if (this.relevanceData.scenarioCaseCount) {
|
||||
total += this.relevanceData.scenarioCaseCount;
|
||||
}
|
||||
if (this.relevanceData.performanceCaseCount) {
|
||||
total += this.relevanceData.performanceCaseCount;
|
||||
}
|
||||
return total;
|
||||
},
|
||||
getAmount() {
|
||||
let total = this.getTotal();
|
||||
if (total > 999999999) {
|
||||
this.pieChartStyle.amountFontSize = 20;
|
||||
} else if (total > 99999999) {
|
||||
this.pieChartStyle.amountFontSize = 22;
|
||||
} else if (total > 9999999) {
|
||||
this.pieChartStyle.amountFontSize = 24;
|
||||
} else if (total > 999999) {
|
||||
this.pieChartStyle.amountFontSize = 26;
|
||||
} else {
|
||||
this.pieChartStyle.amountFontSize = 32;
|
||||
}
|
||||
total = this.formatAmount(total);
|
||||
return total;
|
||||
},
|
||||
formatAmount(param) {
|
||||
return formatNumber(param);
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
options() {
|
||||
let protocolData = [{value: 0}];
|
||||
let colorArr = ['#DEE0E3'];
|
||||
if (this.getTotal() > 0) {
|
||||
colorArr = ['#AA4FBF', '#FFD131', '#10CECE', '#4261F6',]
|
||||
protocolData = [
|
||||
{value: this.relevanceData.apiCaseCount, name: this.$t('home.relevance_dashboard.api_case')},
|
||||
{value: this.relevanceData.scenarioCaseCount, name: this.$t('home.relevance_dashboard.scenario_case')},
|
||||
{value: this.relevanceData.performanceCaseCount, name: this.$t('home.relevance_dashboard.performance_case')}
|
||||
];
|
||||
}
|
||||
let optionData = {
|
||||
color: colorArr,
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
title: {
|
||||
text: "{mainTitle|" + this.$t("home.relevance_dashboard.relevance_case_count") + "}\n\n{number|" + this.getAmount() + "}\n\n",
|
||||
subtext: this.$t("home.dashboard.public.this_week") + ": +" + this.relevanceData.thisWeekAddedCount + " >",
|
||||
top: "center",
|
||||
left: "center",
|
||||
textStyle: {
|
||||
rich: {
|
||||
mainTitle: {
|
||||
color: '#646A73',
|
||||
fontSize: 12,
|
||||
},
|
||||
number: {
|
||||
fontSize: this.pieChartStyle.amountFontSize,
|
||||
fontWeight: 500,
|
||||
fontStyle: "normal",
|
||||
fontFamily: "PinfFang SC",
|
||||
margin: "112px 0px 0px 2px0",
|
||||
},
|
||||
}
|
||||
},
|
||||
sublink: hasPermission('PROJECT_TRACK_CASE:READ') ? "/#/track/case/all/" + getUUID() + "/case/thisWeekRelevanceCount" : "",
|
||||
subtextStyle: {
|
||||
color: "#1F2329",
|
||||
fontSize: 12,
|
||||
width: 105,
|
||||
ellipsis: '...',
|
||||
overflow: "truncate",
|
||||
},
|
||||
itemGap: -60,
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['70%', '96%'],
|
||||
avoidLabelOverlap: false,
|
||||
hoverAnimation: true,
|
||||
label: {
|
||||
show: false,
|
||||
},
|
||||
itemStyle: {
|
||||
borderColor: "#FFF",
|
||||
borderWidth: 3,
|
||||
borderRadius: 1,
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: protocolData,
|
||||
}
|
||||
]
|
||||
};
|
||||
return optionData;
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.count-row {
|
||||
padding: 8px 0px 8px 0px;
|
||||
}
|
||||
|
||||
.count-title {
|
||||
color: #646A73;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.count-value {
|
||||
color: #646A73;
|
||||
float: right;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.ms-point-api {
|
||||
height: 8px;
|
||||
width: 8px;
|
||||
margin-right: 8px;
|
||||
display: inline-block;
|
||||
background-color: #AA4FBF;
|
||||
}
|
||||
|
||||
.ms-point-scenario {
|
||||
height: 8px;
|
||||
width: 8px;
|
||||
margin-right: 8px;
|
||||
display: inline-block;
|
||||
background-color: #FFD131;
|
||||
}
|
||||
|
||||
.ms-point-performance {
|
||||
height: 8px;
|
||||
width: 8px;
|
||||
margin-right: 8px;
|
||||
display: inline-block;
|
||||
background-color: #10CECE;
|
||||
}
|
||||
</style>
|
|
@ -381,7 +381,11 @@ export default {
|
|||
},
|
||||
getIssues() {
|
||||
if (this.dataSelectRange === 'thisWeekUnClosedIssue') {
|
||||
this.page.condition.thisWeekUnClosedIssue = true;
|
||||
this.page.condition.thisWeekUnClosedTestPlanIssue = true;
|
||||
} else if (this.dataSelectRange === 'unClosedRelatedTestPlan') {
|
||||
this.page.condition.unClosedTestPlanIssue = true;
|
||||
} else if (this.dataSelectRange === 'AllRelatedTestPlan') {
|
||||
this.page.condition.allTestPlanIssue = true;
|
||||
}
|
||||
this.page.condition.projectId = this.projectId;
|
||||
this.page.condition.workspaceId= this.workspaceId;
|
||||
|
|
|
@ -29,14 +29,14 @@ const message = {
|
|||
},
|
||||
dashboard: {
|
||||
public: {
|
||||
this_week: "This week ",
|
||||
this_week: "Week ",
|
||||
load_error: "Loading failure",
|
||||
no_data: "No data",
|
||||
},
|
||||
case_finished_review_pass_tip: "Reviewed cases/All reviewed cases *100%"
|
||||
},
|
||||
case_review_dashboard: {
|
||||
case_count: "Case count",
|
||||
case_count: "Case",
|
||||
not_review: "Not reviewed",
|
||||
finished_review: "Reviewed",
|
||||
not_pass: "Not pass",
|
||||
|
@ -46,18 +46,18 @@ const message = {
|
|||
api_case: "Api case",
|
||||
scenario_case: "Scenario case",
|
||||
performance_case: "Performance case",
|
||||
relevance_case_count: "Relevance case count",
|
||||
relevance_case_count: "Relevance case",
|
||||
not_cover: "Not cover",
|
||||
cover: "Cover",
|
||||
},
|
||||
bug_dashboard: {
|
||||
un_closed_bug_count: "Unclosed bug count",
|
||||
un_closed_range: "Unclosed bug range",
|
||||
un_closed_bug_count: "Unclosed bug",
|
||||
un_closed_range: "Unclosed bug rate",
|
||||
un_closed_range_tips: "Unclosed bugs/all associated bugs *100%",
|
||||
un_closed_bug_case_range: "Unclosed bug case range",
|
||||
un_closed_bug_case_range: "Unclosed bug case rate",
|
||||
un_closed_bug_case_range_tips: "Unclosed bugs/all associated cases *100%",
|
||||
un_closed_count: "Unclosed bug count",
|
||||
total_count: "Bug total",
|
||||
un_closed_count: "Unclosed bug",
|
||||
total_count: "All related bug",
|
||||
case_count: "Case count",
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue