This commit is contained in:
shiziyuan9527 2020-12-17 17:43:23 +08:00
commit d7b4c140b7
39 changed files with 1898 additions and 169 deletions

View File

@ -1,153 +1,297 @@
package io.metersphere.api.controller;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.metersphere.api.dto.*;
import io.metersphere.api.dto.scenario.request.dubbo.RegistryCenter;
import io.metersphere.api.service.APITestService;
import io.metersphere.base.domain.ApiTest;
import io.metersphere.base.domain.Schedule;
import io.metersphere.commons.constants.RoleConstants;
import io.metersphere.commons.utils.PageUtils;
import io.metersphere.commons.utils.Pager;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.controller.request.QueryScheduleRequest;
import io.metersphere.dto.ScheduleDao;
import io.metersphere.service.CheckOwnerService;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import static io.metersphere.commons.utils.JsonPathUtils.getListJson;
@RestController
@RequestMapping(value = "/api")
@RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER, RoleConstants.TEST_VIEWER}, logical = Logical.OR)
public class APITestController {
@Resource
private APITestService apiTestService;
@Resource
private CheckOwnerService checkownerService;
@GetMapping("recent/{count}")
public List<APITestResult> recentTest(@PathVariable int count) {
String currentWorkspaceId = SessionUtils.getCurrentWorkspaceId();
QueryAPITestRequest request = new QueryAPITestRequest();
request.setWorkspaceId(currentWorkspaceId);
request.setUserId(SessionUtils.getUserId());
PageHelper.startPage(1, count, true);
return apiTestService.recentTest(request);
}
@PostMapping("/list/{goPage}/{pageSize}")
public Pager<List<APITestResult>> list(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryAPITestRequest request) {
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
request.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
request.setProjectId(SessionUtils.getCurrentProjectId());
return PageUtils.setPageInfo(page, apiTestService.list(request));
}
@PostMapping("/list/ids")
public List<ApiTest> listByIds(@RequestBody QueryAPITestRequest request) {
return apiTestService.listByIds(request);
}
@GetMapping("/list/{projectId}")
public List<ApiTest> list(@PathVariable String projectId) {
checkownerService.checkProjectOwner(projectId);
return apiTestService.getApiTestByProjectId(projectId);
}
@PostMapping(value = "/schedule/update")
public void updateSchedule(@RequestBody Schedule request) {
apiTestService.updateSchedule(request);
}
@PostMapping(value = "/schedule/create")
public void createSchedule(@RequestBody Schedule request) {
apiTestService.createSchedule(request);
}
@PostMapping(value = "/create", consumes = {"multipart/form-data"})
public void create(@RequestPart("request") SaveAPITestRequest request, @RequestPart(value = "file") MultipartFile file, @RequestPart(value = "files") List<MultipartFile> bodyFiles) {
apiTestService.create(request, file, bodyFiles);
}
@PostMapping(value = "/create/merge", consumes = {"multipart/form-data"})
public void mergeCreate(@RequestPart("request") SaveAPITestRequest request, @RequestPart(value = "file") MultipartFile file, @RequestPart(value = "selectIds") List<String> selectIds) {
apiTestService.mergeCreate(request, file, selectIds);
}
@PostMapping(value = "/update", consumes = {"multipart/form-data"})
public void update(@RequestPart("request") SaveAPITestRequest request, @RequestPart(value = "file") MultipartFile file, @RequestPart(value = "files") List<MultipartFile> bodyFiles) {
checkownerService.checkApiTestOwner(request.getId());
apiTestService.update(request, file, bodyFiles);
}
@PostMapping(value = "/copy")
public void copy(@RequestBody SaveAPITestRequest request) {
apiTestService.copy(request);
}
@GetMapping("/get/{testId}")
public APITestResult get(@PathVariable String testId) {
checkownerService.checkApiTestOwner(testId);
return apiTestService.get(testId);
}
@PostMapping("/delete")
public void delete(@RequestBody DeleteAPITestRequest request) {
checkownerService.checkApiTestOwner(request.getId());
apiTestService.delete(request);
}
@PostMapping(value = "/run")
public String run(@RequestBody SaveAPITestRequest request) {
return apiTestService.run(request);
}
@PostMapping(value = "/run/debug", consumes = {"multipart/form-data"})
public String runDebug(@RequestPart("request") SaveAPITestRequest request, @RequestPart(value = "file") MultipartFile file, @RequestPart(value = "files") List<MultipartFile> bodyFiles) {
return apiTestService.runDebug(request, file, bodyFiles);
}
@PostMapping(value = "/checkName")
public void checkName(@RequestBody SaveAPITestRequest request) {
apiTestService.checkName(request);
}
@PostMapping(value = "/import", consumes = {"multipart/form-data"})
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
public ApiTest testCaseImport(@RequestPart(value = "file", required = false) MultipartFile file, @RequestPart("request") ApiTestImportRequest request) {
return apiTestService.apiTestImport(file, request);
}
@PostMapping("/dubbo/providers")
public List<DubboProvider> getProviders(@RequestBody RegistryCenter registry) {
return apiTestService.getProviders(registry);
}
@PostMapping("/list/schedule/{goPage}/{pageSize}")
public List<ScheduleDao> listSchedule(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryScheduleRequest request) {
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
return apiTestService.listSchedule(request);
}
@PostMapping("/list/schedule")
public List<ScheduleDao> listSchedule(@RequestBody QueryScheduleRequest request) {
return apiTestService.listSchedule(request);
}
@PostMapping("/getJsonPaths")
public List<HashMap> getJsonPaths(@RequestBody QueryJsonPathRequest request) {
return getListJson(request.getJsonPath());
}
}
package io.metersphere.api.controller;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.metersphere.api.dto.*;
import io.metersphere.api.dto.dataCount.ApiDataCountResult;
import io.metersphere.api.dto.dataCount.ExecutedCaseInfoResult;
import io.metersphere.api.dto.dataCount.request.ScheduleInfoRequest;
import io.metersphere.api.dto.dataCount.response.ApiDataCountDTO;
import io.metersphere.api.dto.dataCount.response.ExecutedCaseInfoDTO;
import io.metersphere.api.dto.dataCount.response.TaskInfoResult;
import io.metersphere.api.dto.scenario.request.dubbo.RegistryCenter;
import io.metersphere.api.service.*;
import io.metersphere.base.domain.ApiTest;
import io.metersphere.base.domain.Schedule;
import io.metersphere.commons.constants.RoleConstants;
import io.metersphere.commons.constants.ScheduleGroup;
import io.metersphere.commons.utils.*;
import io.metersphere.controller.request.QueryScheduleRequest;
import io.metersphere.dto.ScheduleDao;
import io.metersphere.service.CheckOwnerService;
import io.metersphere.service.ScheduleService;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import static io.metersphere.commons.utils.JsonPathUtils.getListJson;
@RestController
@RequestMapping(value = "/api")
@RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER, RoleConstants.TEST_VIEWER}, logical = Logical.OR)
public class APITestController {
@Resource
private APITestService apiTestService;
@Resource
private ApiDefinitionService apiDefinitionService;
@Resource
private CheckOwnerService checkownerService;
@Resource
private ApiTestCaseService apiTestCaseService;
@Resource
private ApiDefinitionExecResultService apiDefinitionExecResultService;
@Resource
private ApiAutomationService apiAutomationService;
@Resource
private ApiScenarioReportService apiScenarioReportService;
@Resource
private ScheduleService scheduleService;
@Resource
private APIReportService apiReportService;
@GetMapping("recent/{count}")
public List<APITestResult> recentTest(@PathVariable int count) {
String currentWorkspaceId = SessionUtils.getCurrentWorkspaceId();
QueryAPITestRequest request = new QueryAPITestRequest();
request.setWorkspaceId(currentWorkspaceId);
request.setUserId(SessionUtils.getUserId());
PageHelper.startPage(1, count, true);
return apiTestService.recentTest(request);
}
@PostMapping("/list/{goPage}/{pageSize}")
public Pager<List<APITestResult>> list(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryAPITestRequest request) {
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
request.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
request.setProjectId(SessionUtils.getCurrentProjectId());
return PageUtils.setPageInfo(page, apiTestService.list(request));
}
@PostMapping("/list/ids")
public List<ApiTest> listByIds(@RequestBody QueryAPITestRequest request) {
return apiTestService.listByIds(request);
}
@GetMapping("/list/{projectId}")
public List<ApiTest> list(@PathVariable String projectId) {
checkownerService.checkProjectOwner(projectId);
return apiTestService.getApiTestByProjectId(projectId);
}
@PostMapping(value = "/schedule/update")
public void updateSchedule(@RequestBody Schedule request) {
apiTestService.updateSchedule(request);
}
@PostMapping(value = "/schedule/create")
public void createSchedule(@RequestBody Schedule request) {
apiTestService.createSchedule(request);
}
@PostMapping(value = "/create", consumes = {"multipart/form-data"})
public void create(@RequestPart("request") SaveAPITestRequest request, @RequestPart(value = "file") MultipartFile file, @RequestPart(value = "files") List<MultipartFile> bodyFiles) {
apiTestService.create(request, file, bodyFiles);
}
@PostMapping(value = "/create/merge", consumes = {"multipart/form-data"})
public void mergeCreate(@RequestPart("request") SaveAPITestRequest request, @RequestPart(value = "file") MultipartFile file, @RequestPart(value = "selectIds") List<String> selectIds) {
apiTestService.mergeCreate(request, file, selectIds);
}
@PostMapping(value = "/update", consumes = {"multipart/form-data"})
public void update(@RequestPart("request") SaveAPITestRequest request, @RequestPart(value = "file") MultipartFile file, @RequestPart(value = "files") List<MultipartFile> bodyFiles) {
checkownerService.checkApiTestOwner(request.getId());
apiTestService.update(request, file, bodyFiles);
}
@PostMapping(value = "/copy")
public void copy(@RequestBody SaveAPITestRequest request) {
apiTestService.copy(request);
}
@GetMapping("/get/{testId}")
public APITestResult get(@PathVariable String testId) {
checkownerService.checkApiTestOwner(testId);
return apiTestService.get(testId);
}
@PostMapping("/delete")
public void delete(@RequestBody DeleteAPITestRequest request) {
checkownerService.checkApiTestOwner(request.getId());
apiTestService.delete(request);
}
@PostMapping(value = "/run")
public String run(@RequestBody SaveAPITestRequest request) {
return apiTestService.run(request);
}
@PostMapping(value = "/run/debug", consumes = {"multipart/form-data"})
public String runDebug(@RequestPart("request") SaveAPITestRequest request, @RequestPart(value = "file") MultipartFile file, @RequestPart(value = "files") List<MultipartFile> bodyFiles) {
return apiTestService.runDebug(request, file, bodyFiles);
}
@PostMapping(value = "/checkName")
public void checkName(@RequestBody SaveAPITestRequest request) {
apiTestService.checkName(request);
}
@PostMapping(value = "/import", consumes = {"multipart/form-data"})
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
public ApiTest testCaseImport(@RequestPart(value = "file", required = false) MultipartFile file, @RequestPart("request") ApiTestImportRequest request) {
return apiTestService.apiTestImport(file, request);
}
@PostMapping("/dubbo/providers")
public List<DubboProvider> getProviders(@RequestBody RegistryCenter registry) {
return apiTestService.getProviders(registry);
}
@PostMapping("/list/schedule/{goPage}/{pageSize}")
public List<ScheduleDao> listSchedule(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryScheduleRequest request) {
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
return apiTestService.listSchedule(request);
}
@PostMapping("/list/schedule")
public List<ScheduleDao> listSchedule(@RequestBody QueryScheduleRequest request) {
return apiTestService.listSchedule(request);
}
@PostMapping("/getJsonPaths")
public List<HashMap> getJsonPaths(@RequestBody QueryJsonPathRequest request) {
return getListJson(request.getJsonPath());
}
@GetMapping("/apiCount/{projectId}")
public ApiDataCountDTO apiCount(@PathVariable String projectId) {
ApiDataCountDTO apiCountResult = new ApiDataCountDTO();
List<ApiDataCountResult> countResultList = apiDefinitionService.countProtocolByProjectID(projectId);
apiCountResult.countByApiDefinitionCountResult(countResultList);
long dateCountByCreateInThisWeek = apiDefinitionService.countByProjectIDAndCreateInThisWeek(projectId);
apiCountResult.setThisWeekAddedCount(dateCountByCreateInThisWeek);
return apiCountResult;
}
@GetMapping("/testCaseInfoCount/{projectId}")
public ApiDataCountDTO testCaseInfoCount(@PathVariable String projectId) {
ApiDataCountDTO apiCountResult = new ApiDataCountDTO();
List<ApiDataCountResult> countResultList = apiTestCaseService.countProtocolByProjectID(projectId);
apiCountResult.countByApiDefinitionCountResult(countResultList);
long dateCountByCreateInThisWeek = apiTestCaseService.countByProjectIDAndCreateInThisWeek(projectId);
apiCountResult.setThisWeekAddedCount(dateCountByCreateInThisWeek);
long executedInThisWeekCountNumber = apiDefinitionExecResultService.countByTestCaseIDInProjectAndExecutedInThisWeek(projectId);
apiCountResult.setThisWeekExecutedCount(executedInThisWeekCountNumber);
long executedCountNumber = apiDefinitionExecResultService.countByTestCaseIDInProject(projectId);
apiCountResult.setExecutedCount(executedCountNumber);
return apiCountResult;
}
@GetMapping("/testSceneInfoCount/{projectId}")
public ApiDataCountDTO testSceneInfoCount(@PathVariable String projectId) {
ApiDataCountDTO apiCountResult = new ApiDataCountDTO();
long scenarioCountNumber = apiAutomationService.countScenarioByProjectID(projectId);
apiCountResult.setAllApiDataCountNumber(scenarioCountNumber);
/**
* 本周新增通过测试场景的createTime
* 本周执行: 查询本周生成的测试报告
* 历史总执行查询所有的测试报告
* */
long dateCountByCreateInThisWeek = apiAutomationService.countScenarioByProjectIDAndCreatInThisWeek(projectId);
apiCountResult.setThisWeekAddedCount(dateCountByCreateInThisWeek);
long executedInThisWeekCountNumber = apiScenarioReportService.countByProjectIDAndCreateInThisWeek(projectId);
apiCountResult.setThisWeekExecutedCount(executedInThisWeekCountNumber);
long executedCountNumber = apiScenarioReportService.countByProjectID(projectId);
apiCountResult.setExecutedCount(executedCountNumber);
return apiCountResult;
}
@GetMapping("/scheduleTaskInfoCount/{workSpaceID}")
public ApiDataCountDTO scheduleTaskInfoCount(@PathVariable String workSpaceID) {
ApiDataCountDTO apiCountResult = new ApiDataCountDTO();
long allTaskCount = scheduleService.countTaskByWorkspaceIdAndGroup(workSpaceID,ScheduleGroup.API_TEST.name());
apiCountResult.setAllApiDataCountNumber(allTaskCount);
long taskCountInThisWeek = scheduleService.countTaskByWorkspaceIdAndGroupInThisWeek(workSpaceID,ScheduleGroup.API_TEST.name());
apiCountResult.setThisWeekAddedCount(taskCountInThisWeek);
long executedInThisWeekCountNumber = apiReportService.countByWorkspaceIdAndGroupAndCreateInThisWeek(workSpaceID,ScheduleGroup.API_TEST.name());
apiCountResult.setThisWeekExecutedCount(executedInThisWeekCountNumber);
long executedCountNumber = apiReportService.countByWorkspaceIdAndGroup(workSpaceID,ScheduleGroup.API_TEST.name());
apiCountResult.setExecutedCount(executedCountNumber);
return apiCountResult;
}
@GetMapping("/faliureCaseAboutTestPlan/{projectId}/{limitNumber}")
public List<ExecutedCaseInfoDTO> faliureCaseAboutTestPlan(@PathVariable String projectId, @PathVariable int limitNumber) {
List<ExecutedCaseInfoResult> selectDataList = apiDefinitionExecResultService.findFaliureCaseInfoByProjectIDAndLimitNumberInSevenDays(projectId,limitNumber);
List<ExecutedCaseInfoDTO> returnList = new ArrayList<>(limitNumber);
for(int dataIndex = 0;dataIndex < limitNumber;dataIndex ++){
ExecutedCaseInfoDTO dataDTO = new ExecutedCaseInfoDTO();
dataDTO.setSortIndex(dataIndex+1);
if(dataIndex<selectDataList.size()){
ExecutedCaseInfoResult selectData = selectDataList.get(dataIndex);
dataDTO.setCaseName(selectData.getCaseName());
dataDTO.setTestPlan(selectData.getTestPlan());
dataDTO.setFailureTimes(selectData.getFailureTimes());
}else {
dataDTO.setCaseName("");
dataDTO.setTestPlan("");
}
returnList.add(dataDTO);
}
return returnList;
}
@GetMapping("/runningTask/{workspaceID}")
public List<TaskInfoResult> runningTask(@PathVariable String workspaceID) {
List<TaskInfoResult> resultList = scheduleService.findRunningTaskInfoByWorkspaceID(workspaceID);
for (TaskInfoResult taskInfo :
resultList) {
Date nextExecutionTime = CronUtils.getNextTriggerTime(taskInfo.getRule());
if(nextExecutionTime!=null){
taskInfo.setNextExecutionTime(nextExecutionTime.getTime());
}
}
return resultList;
}
@PostMapping(value = "/schedule/updateEnableByPrimyKey")
public void updateScheduleEnableByPrimyKey(@RequestBody ScheduleInfoRequest request) {
Schedule schedule = scheduleService.getSchedule(request.getTaskID());
schedule.setEnable(request.isEnable());
apiTestService.updateSchedule(schedule);
}
}

View File

@ -0,0 +1,16 @@
package io.metersphere.api.dto.dataCount;
import lombok.Getter;
import lombok.Setter;
/**
* API数据统计查询结果类
*/
@Getter
@Setter
public class ApiDataCountResult {
//分组统计字段
private String groupField;
//数据统计
private long countNumber;
}

View File

@ -0,0 +1,18 @@
package io.metersphere.api.dto.dataCount;
import lombok.Getter;
import lombok.Setter;
/**
* 已执行的案例
*/
@Getter
@Setter
public class ExecutedCaseInfoResult {
//案例名称
private String caseName;
//所属测试计划
private String testPlan;
//失败次数
private Long failureTimes;
}

View File

@ -0,0 +1,16 @@
package io.metersphere.api.dto.dataCount.request;
import lombok.Getter;
import lombok.Setter;
/**
* @author song.tianyang
* @Date 2020/12/17 5:04 下午
* @Description
*/
@Getter
@Setter
public class ScheduleInfoRequest {
private String taskID;
private boolean enable;
}

View File

@ -0,0 +1,65 @@
package io.metersphere.api.dto.dataCount.response;
import io.metersphere.api.dto.dataCount.ApiDataCountResult;
import io.metersphere.api.dto.scenario.request.RequestType;
import io.metersphere.base.domain.ApiDefinition;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.Locale;
/**
* 接口数据统计返回
*/
@Getter
@Setter
public class ApiDataCountDTO {
//接口统计
private long allApiDataCountNumber = 0;
//http接口统计
private long httpApiDataCountNumber = 0;
//rpc接口统计
private long rpcApiDataCountNumber = 0;
//tcp接口统计
private long tcpApiDataCountNumber = 0;
//sql接口统计
private long sqlApiDataCountNumber = 0;
//本周新增数量
private long thisWeekAddedCount = 0;
//本周执行数量
private long thisWeekExecutedCount = 0;
//历史总执行数量
private long executedCount = 0;
public ApiDataCountDTO(){}
/**
* 通过ApiDefinitionCountResult统计查询结果进行数据合计
* @param countResultList
*/
public void countByApiDefinitionCountResult(List<ApiDataCountResult> countResultList){
for (ApiDataCountResult countResult :
countResultList) {
switch (countResult.getGroupField().toUpperCase()){
case RequestType.DUBBO:
this.rpcApiDataCountNumber += countResult.getCountNumber();
break;
case RequestType.HTTP:
this.httpApiDataCountNumber += countResult.getCountNumber();
break;
case RequestType.SQL:
this.sqlApiDataCountNumber += countResult.getCountNumber();
break;
case RequestType.TCP:
this.tcpApiDataCountNumber += countResult.getCountNumber();
break;
default:
break;
}
allApiDataCountNumber += countResult.getCountNumber();
}
}
}

View File

@ -0,0 +1,20 @@
package io.metersphere.api.dto.dataCount.response;
import lombok.Getter;
import lombok.Setter;
/**
* 已执行的案例
*/
@Getter
@Setter
public class ExecutedCaseInfoDTO {
//排名
private int sortIndex;
//案例名称
private String caseName;
//所属测试计划
private String testPlan;
//失败次数
private Long failureTimes;
}

View File

@ -0,0 +1,30 @@
package io.metersphere.api.dto.dataCount.response;
import lombok.Getter;
import lombok.Setter;
import org.python.antlr.ast.Str;
/**
* 任务信息 返回DTO
*/
@Getter
@Setter
public class TaskInfoResult {
//序号
private int index;
//任务ID
private String taskID;
//场景名称
private String scenario;
//规则
private String rule;
//任务状态
private boolean taskStatus;
//下次执行时间
private Long nextExecutionTime;
//创建人
private String creator;
//更新时间
private Long updateTime;
}

View File

@ -15,6 +15,7 @@ import io.metersphere.base.mapper.ext.ExtApiTestReportMapper;
import io.metersphere.commons.constants.APITestStatus;
import io.metersphere.commons.constants.ReportTriggerMode;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.DateUtils;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.commons.utils.ServiceUtils;
import io.metersphere.commons.utils.SessionUtils;
@ -30,10 +31,7 @@ import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.*;
@Service
@Transactional(rollbackFor = Exception.class)
@ -212,4 +210,21 @@ public class APIReportService {
apiTestReportExample.createCriteria().andIdIn(reportRequest.getIds());
apiTestReportMapper.deleteByExample(apiTestReportExample);
}
public long countByWorkspaceIdAndGroupAndCreateInThisWeek(String workspaceID, String group) {
Map<String, Date> startAndEndDateInWeek = DateUtils.getWeedFirstTimeAndLastTime(new Date());
Date firstTime = startAndEndDateInWeek.get("firstTime");
Date lastTime = startAndEndDateInWeek.get("lastTime");
if(firstTime==null || lastTime == null){
return 0;
}else {
return apiTestReportMapper.countByProjectIDAndCreateInThisWeek(workspaceID,group,firstTime.getTime(),lastTime.getTime());
}
}
public long countByWorkspaceIdAndGroup(String workspaceID, String group) {
return apiTestReportMapper.countByWorkspaceIdAndGroup(workspaceID,group);
}
}

View File

@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.client.utils.StringUtils;
import io.github.ningyu.jmeter.plugin.dubbo.sample.ProviderService;
import io.metersphere.api.dto.*;
import io.metersphere.api.dto.dataCount.ApiDataCountResult;
import io.metersphere.api.dto.parse.ApiImport;
import io.metersphere.api.dto.scenario.request.dubbo.RegistryCenter;
import io.metersphere.api.jmeter.JMeterService;

View File

@ -22,6 +22,7 @@ import io.metersphere.commons.constants.APITestStatus;
import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.ReportTriggerMode;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.DateUtils;
import io.metersphere.commons.utils.ServiceUtils;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.i18n.Translator;
@ -355,4 +356,20 @@ public class ApiAutomationService {
return "success";
}
public long countScenarioByProjectID(String projectId) {
return apiScenarioMapper.countByProjectID(projectId);
}
public long countScenarioByProjectIDAndCreatInThisWeek(String projectId) {
Map<String, Date> startAndEndDateInWeek = DateUtils.getWeedFirstTimeAndLastTime(new Date());
Date firstTime = startAndEndDateInWeek.get("firstTime");
Date lastTime = startAndEndDateInWeek.get("lastTime");
if(firstTime==null || lastTime == null){
return 0;
}else {
return apiScenarioMapper.countByProjectIDAndCreatInThisWeek(projectId,firstTime.getTime(),lastTime.getTime());
}
}
}

View File

@ -1,25 +1,32 @@
package io.metersphere.api.service;
import com.alibaba.fastjson.JSON;
import io.metersphere.api.dto.dataCount.ExecutedCaseInfoResult;
import io.metersphere.api.jmeter.TestResult;
import io.metersphere.base.domain.ApiDefinitionExecResult;
import io.metersphere.base.mapper.ApiDefinitionExecResultMapper;
import io.metersphere.base.mapper.ext.ExtApiDefinitionExecResultMapper;
import io.metersphere.commons.utils.DateUtils;
import io.metersphere.commons.utils.SessionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.Objects;
import java.util.UUID;
import java.util.*;
@Service
@Transactional(rollbackFor = Exception.class)
public class ApiDefinitionExecResultService {
@Resource
private ApiDefinitionExecResultMapper apiDefinitionExecResultMapper;
@Resource
private ExtApiDefinitionExecResultMapper extApiDefinitionExecResultMapper;
public void saveApiResult(TestResult result) {
result.getScenarios().get(0).getRequestResults().forEach(item -> {
// 清理原始资源每个执行 保留一条结果
extApiDefinitionExecResultMapper.deleteByResourceId(item.getName());
ApiDefinitionExecResult saveResult = new ApiDefinitionExecResult();
saveResult.setId(UUID.randomUUID().toString());
saveResult.setUserId(Objects.requireNonNull(SessionUtils.getUser()).getId());
@ -32,4 +39,40 @@ public class ApiDefinitionExecResultService {
apiDefinitionExecResultMapper.insert(saveResult);
});
}
public long countByTestCaseIDInProjectAndExecutedInThisWeek(String projectId) {
Map<String, Date> startAndEndDateInWeek = DateUtils.getWeedFirstTimeAndLastTime(new Date());
Date firstTime = startAndEndDateInWeek.get("firstTime");
Date lastTime = startAndEndDateInWeek.get("lastTime");
if(firstTime==null || lastTime == null){
return 0;
}else {
return apiDefinitionExecResultMapper.countByProjectIDAndCreateInThisWeek(projectId,firstTime.getTime(),lastTime.getTime());
}
}
public long countByTestCaseIDInProject(String projectId) {
return apiDefinitionExecResultMapper.countByTestCaseIDInProject(projectId);
}
public List<ExecutedCaseInfoResult> findFaliureCaseInfoByProjectIDAndLimitNumberInSevenDays(String projectId, int limitNumber) {
//获取7天之前的日期
Date startDay = DateUtils.dateSum(new Date(),-6);
//将日期转化为 00:00:00 的时间戳
Date startTime = null;
try{
startTime = DateUtils.getDayStartTime(startDay);
}catch (Exception e){
}
if(startTime==null){
return new ArrayList<>(0);
}else {
return apiDefinitionExecResultMapper.findFaliureCaseInfoByProjectIDAndExecuteTimeAndLimitNumber(projectId,startTime.getTime(),limitNumber);
}
}
}

View File

@ -6,6 +6,7 @@ import io.metersphere.api.dto.APIReportResult;
import io.metersphere.api.dto.ApiTestImportRequest;
import io.metersphere.api.dto.automation.ApiScenarioRequest;
import io.metersphere.api.dto.automation.ReferenceDTO;
import io.metersphere.api.dto.dataCount.ApiDataCountResult;
import io.metersphere.api.dto.definition.*;
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
import io.metersphere.api.dto.scenario.request.RequestType;
@ -23,10 +24,7 @@ import io.metersphere.base.mapper.ext.ExtTestPlanMapper;
import io.metersphere.commons.constants.APITestStatus;
import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.BeanUtils;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.commons.utils.ServiceUtils;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.commons.utils.*;
import io.metersphere.i18n.Translator;
import io.metersphere.service.FileService;
import io.metersphere.track.request.testcase.QueryTestPlanRequest;
@ -43,10 +41,7 @@ import sun.security.util.Cache;
import javax.annotation.Resource;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@ -388,4 +383,30 @@ public class ApiDefinitionService {
apiDefinitionMapper.updateByExampleSelective(definitionWithBLOBs, definitionExample);
}
/**
* 数据统计-接口类型
* @param projectId 项目ID
* @return
*/
public List<ApiDataCountResult> countProtocolByProjectID(String projectId) {
return apiDefinitionMapper.countProtocolByProjectID(projectId);
}
/**
* 统计本周创建的数据总量
* @param projectId
* @return
*/
public long countByProjectIDAndCreateInThisWeek(String projectId) {
Map<String, Date> startAndEndDateInWeek = DateUtils.getWeedFirstTimeAndLastTime(new Date());
Date firstTime = startAndEndDateInWeek.get("firstTime");
Date lastTime = startAndEndDateInWeek.get("lastTime");
if(firstTime==null || lastTime == null){
return 0;
}else {
return apiDefinitionMapper.countByProjectIDAndCreateInThisWeek(projectId,firstTime.getTime(),lastTime.getTime());
}
}
}

View File

@ -14,6 +14,7 @@ import io.metersphere.base.mapper.ApiScenarioReportMapper;
import io.metersphere.base.mapper.ext.ExtApiScenarioReportMapper;
import io.metersphere.commons.constants.APITestStatus;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.DateUtils;
import io.metersphere.commons.utils.ServiceUtils;
import io.metersphere.i18n.Translator;
import org.apache.commons.lang3.StringUtils;
@ -24,7 +25,9 @@ import sun.security.util.Cache;
import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@Service
@ -205,4 +208,20 @@ public class ApiScenarioReportService {
apiScenarioReportMapper.deleteByExample(apiTestReportExample);
}
public long countByProjectID(String projectId) {
return apiScenarioReportMapper.countByProjectID(projectId);
}
public long countByProjectIDAndCreateInThisWeek(String projectId) {
Map<String, Date> startAndEndDateInWeek = DateUtils.getWeedFirstTimeAndLastTime(new Date());
Date firstTime = startAndEndDateInWeek.get("firstTime");
Date lastTime = startAndEndDateInWeek.get("lastTime");
if(firstTime==null || lastTime == null){
return 0;
}else {
return apiScenarioReportMapper.countByProjectIDAndCreateInThisWeek(projectId,firstTime.getTime(),lastTime.getTime());
}
}
}

View File

@ -1,6 +1,10 @@
package io.metersphere.api.service;
import com.alibaba.fastjson.JSONObject;
import io.metersphere.api.dto.dataCount.ApiDataCountResult;
import io.metersphere.api.dto.definition.ApiTestCaseRequest;
import io.metersphere.api.dto.definition.ApiTestCaseResult;
import io.metersphere.api.dto.definition.SaveApiTestCaseRequest;
import io.metersphere.api.dto.ApiCaseBatchRequest;
import io.metersphere.api.dto.definition.*;
import io.metersphere.base.domain.*;
@ -243,4 +247,22 @@ public class ApiTestCaseService {
example.createCriteria().andIdIn(ids);
apiTestCaseMapper.deleteByExample(example);
}
public List<ApiDataCountResult> countProtocolByProjectID(String projectId) {
return apiTestCaseMapper.countProtocolByProjectID(projectId);
}
public long countByProjectIDAndCreateInThisWeek(String projectId) {
Map<String, Date> startAndEndDateInWeek = DateUtils.getWeedFirstTimeAndLastTime(new Date());
Date firstTime = startAndEndDateInWeek.get("firstTime");
Date lastTime = startAndEndDateInWeek.get("lastTime");
if(firstTime==null || lastTime == null){
return 0;
}else {
return apiTestCaseMapper.countByProjectIDAndCreateInThisWeek(projectId,firstTime.getTime(),lastTime.getTime());
}
}
}

View File

@ -1,8 +1,10 @@
package io.metersphere.base.mapper;
import io.metersphere.api.dto.dataCount.ExecutedCaseInfoResult;
import io.metersphere.base.domain.ApiDefinitionExecResult;
import io.metersphere.base.domain.ApiDefinitionExecResultExample;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@ -34,4 +36,42 @@ public interface ApiDefinitionExecResultMapper {
int updateByPrimaryKeyWithBLOBs(ApiDefinitionExecResult record);
int updateByPrimaryKey(ApiDefinitionExecResult record);
@Select({
"SELECT count(id) AS countNumber FROM api_definition_exec_result ",
"WHERE resource_id IN ( ",
"SELECT testCase.id FROM api_test_case testCase ",
"WHERE testCase.project_id = #{projectId}) ",
"and start_time BETWEEN #{firstDayTimestamp} AND #{lastDayTimestamp} "
})
long countByProjectIDAndCreateInThisWeek(@Param("projectId") String projectId, @Param("firstDayTimestamp") long firstDayTimestamp, @Param("lastDayTimestamp") long lastDayTimestamp);
@Select({
"SELECT count(id) AS countNumber FROM api_definition_exec_result ",
"WHERE resource_id IN ( ",
"SELECT testCase.id FROM api_test_case testCase ",
"WHERE testCase.project_id = #{projectId}) ",
})
long countByTestCaseIDInProject(String projectId);
// AS testPlan FROM ( SELECT apiCase.id AS testCaseID,apiCase.`name` AS testCaseNa' at line 1
@Select({
"SELECT testCase.testCaseName AS caseName,testCase.testPlanName AS testPlan ,caseErrorCountData.dataCountNumber AS failureTimes FROM ( ",
"SELECT apiCase.id AS testCaseID,apiCase.`name` AS testCaseName,group_concat(testPlan.`name`) AS testPlanName FROM api_test_case apiCase ",
"LEFT JOIN test_plan testPlan ON testPlan.api_ids like concat('%\"',apiCase.id,'\"%') ",
"GROUP BY apiCase.id ",
"ORDER BY apiCase.create_time DESC ",
")testCase ",
"INNER JOIN ( ",
"SELECT resource_id AS testCaseID,COUNT(id) AS dataCountNumber,start_time AS executeTime FROM api_definition_exec_result ",
"WHERE resource_id IN ( ",
"SELECT id FROM api_test_case WHERE project_id = #{projectId} ",
") and `status` = 'error' GROUP BY resource_id ",
") caseErrorCountData ON caseErrorCountData.testCaseID =testCase.testCaseID ",
"WHERE caseErrorCountData.executeTime >= #{startTimestamp} ",
"ORDER BY caseErrorCountData.dataCountNumber DESC ",
"limit #{limitNumber} "
})
List<ExecutedCaseInfoResult> findFaliureCaseInfoByProjectIDAndExecuteTimeAndLimitNumber(@Param("projectId") String projectId, @Param("startTimestamp") long startTimestamp, @Param("limitNumber") int limitNumber);
}

View File

@ -1,9 +1,12 @@
package io.metersphere.base.mapper;
import io.metersphere.api.dto.dataCount.ApiDataCountResult;
import io.metersphere.api.dto.dataCount.response.ApiDataCountDTO;
import io.metersphere.base.domain.ApiDefinition;
import io.metersphere.base.domain.ApiDefinitionExample;
import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@ -35,4 +38,14 @@ public interface ApiDefinitionMapper {
int updateByPrimaryKeyWithBLOBs(ApiDefinitionWithBLOBs record);
int updateByPrimaryKey(ApiDefinition record);
@Select("SELECT protocol AS groupField,count(id) AS countNumber FROM api_definition WHERE project_id = #{0} GROUP BY protocol;")
List<ApiDataCountResult> countProtocolByProjectID(String projectId);
@Select({
"SELECT count(id) AS countNumber FROM api_definition ",
"WHERE project_id = #{projectId} ",
"AND create_time BETWEEN #{firstDayTimestamp} AND #{lastDayTimestamp} "
})
long countByProjectIDAndCreateInThisWeek(@Param("projectId") String projectId, @Param("firstDayTimestamp") long firstDayTimestamp, @Param("lastDayTimestamp") long lastDayTimestamp);
}

View File

@ -4,6 +4,7 @@ import io.metersphere.base.domain.ApiScenario;
import io.metersphere.base.domain.ApiScenarioExample;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
public interface ApiScenarioMapper {
long countByExample(ApiScenarioExample example);
@ -33,4 +34,14 @@ public interface ApiScenarioMapper {
int updateByPrimaryKeyWithBLOBs(ApiScenario record);
int updateByPrimaryKey(ApiScenario record);
@Select("SELECT COUNT(id) AS countNumber FROM api_scenario WHERE project_id = #{0} ")
long countByProjectID(String projectId);
@Select({
"SELECT count(id) AS countNumber FROM api_scenario ",
"WHERE project_id = #{projectId} ",
"AND create_time BETWEEN #{firstDayTimestamp} AND #{lastDayTimestamp} "
})
long countByProjectIDAndCreatInThisWeek(@Param("projectId") String projectId, @Param("firstDayTimestamp") long firstDayTimestamp, @Param("lastDayTimestamp") long lastDayTimestamp);
}

View File

@ -4,6 +4,7 @@ import io.metersphere.base.domain.ApiScenarioReport;
import io.metersphere.base.domain.ApiScenarioReportExample;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
public interface ApiScenarioReportMapper {
long countByExample(ApiScenarioReportExample example);
@ -27,4 +28,14 @@ public interface ApiScenarioReportMapper {
int updateByPrimaryKeySelective(ApiScenarioReport record);
int updateByPrimaryKey(ApiScenarioReport record);
@Select("SELECT count(id) AS countNumber FROM api_scenario_report WHERE project_id = #{0} ")
long countByProjectID(String projectId);
@Select({
"SELECT count(id) AS countNumber FROM api_scenario_report ",
"WHERE project_id = #{projectId} ",
"AND create_time BETWEEN #{firstDayTimestamp} AND #{lastDayTimestamp} "
})
long countByProjectIDAndCreateInThisWeek(@Param("projectId") String projectId, @Param("firstDayTimestamp") long firstDayTimestamp, @Param("lastDayTimestamp") long lastDayTimestamp);
}

View File

@ -1,9 +1,11 @@
package io.metersphere.base.mapper;
import io.metersphere.api.dto.dataCount.ApiDataCountResult;
import io.metersphere.base.domain.ApiTestCase;
import io.metersphere.base.domain.ApiTestCaseExample;
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@ -35,4 +37,20 @@ public interface ApiTestCaseMapper {
int updateByPrimaryKeyWithBLOBs(ApiTestCaseWithBLOBs record);
int updateByPrimaryKey(ApiTestCase record);
@Select({
"SELECT apiDef.protocol AS groupField,COUNT(testCase.id) AS countNumber FROM api_test_case testCase ",
"INNER JOIN api_definition apiDef ON testCase.api_definition_id = apiDef.id ",
"WHERE testCase.project_id = #{0} ",
"GROUP BY apiDef.protocol "
})
List<ApiDataCountResult> countProtocolByProjectID(String projectId);
@Select({
"SELECT count(testCase.id) AS countNumber FROM api_test_case testCase ",
"INNER JOIN api_definition apiDef ON testCase.api_definition_id = apiDef.id ",
"WHERE testCase.project_id = #{projectId} ",
"AND testCase.create_time BETWEEN #{firstDayTimestamp} AND #{lastDayTimestamp} "
})
long countByProjectIDAndCreateInThisWeek(@Param("projectId") String projectId, @Param("firstDayTimestamp") long firstDayTimestamp, @Param("lastDayTimestamp") long lastDayTimestamp);
}

View File

@ -4,6 +4,7 @@ import io.metersphere.base.domain.ApiTestReport;
import io.metersphere.base.domain.ApiTestReportExample;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
public interface ApiTestReportMapper {
long countByExample(ApiTestReportExample example);
@ -27,4 +28,21 @@ public interface ApiTestReportMapper {
int updateByPrimaryKeySelective(ApiTestReport record);
int updateByPrimaryKey(ApiTestReport record);
@Select({
"SELECT COUNT(testReportDetail.report_id) AS countNumber FROM api_test_report_detail testReportDetail ",
"INNER JOIN `schedule` sch ON sch.resource_id = testReportDetail.test_id ",
"INNER JOIN api_test_report testReport ON testReportDetail.report_id = testReport.id ",
"WHERE workspace_id = #{workspaceID} AND `group` = #{group} ",
})
long countByWorkspaceIdAndGroup(@Param("workspaceID") String workspaceID, @Param("group")String group);
@Select({
"SELECT COUNT(testReportDetail.report_id) AS countNumber FROM api_test_report_detail testReportDetail ",
"INNER JOIN `schedule` sch ON sch.resource_id = testReportDetail.test_id ",
"INNER JOIN api_test_report testReport ON testReportDetail.report_id = testReport.id ",
"WHERE workspace_id = #{workspaceID} AND `group` = #{group} ",
"AND testReport.create_time BETWEEN #{startTime} and #{endTime} ",
})
long countByProjectIDAndCreateInThisWeek(@Param("workspaceID") String workspaceID, @Param("group")String group, @Param("startTime") long startTime, @Param("endTime")long endTime);
}

View File

@ -1,9 +1,13 @@
package io.metersphere.base.mapper;
import io.metersphere.api.dto.dataCount.response.TaskInfoResult;
import io.metersphere.base.domain.Schedule;
import io.metersphere.base.domain.ScheduleExample;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.python.antlr.ast.Str;
public interface ScheduleMapper {
long countByExample(ScheduleExample example);
@ -33,4 +37,25 @@ public interface ScheduleMapper {
int updateByPrimaryKeyWithBLOBs(Schedule record);
int updateByPrimaryKey(Schedule record);
@Select("SELECT COUNT(id) AS countNumber FROM `schedule` WHERE `workspace_id` = #{workspaceId} AND `group` = #{group} ")
long countTaskByWorkspaceIdAndGroup(@Param("workspaceId") String workspaceId,@Param("group") String group);
@Select({
"SELECT COUNT(id) AS countNumber FROM `schedule` ",
"WHERE workspace_id = #{workspaceId} ",
"AND `group` = #{group} ",
"AND create_time BETWEEN #{startTime} and #{endTime}; "
})
long countTaskByWorkspaceIdAndGroupAndCreateTimeRange(@Param("workspaceId")String workspaceId,@Param("group") String group, @Param("startTime") long startTime, @Param("endTime") long endTime);
@Select({
"SELECT apiTest.`name` AS scenario,sch.id AS taskID,sch.`value` AS rule,sch.`enable` AS `taskStatus`,u.`name` AS creator,sch.update_time AS updateTime ",
"FROM api_test apiTest ",
"INNER JOIN `schedule` sch ON apiTest.id = sch.resource_id ",
"INNER JOIN `user` u ON u.id = sch.user_id ",
"WHERE sch.`enable` = true AND sch.workspace_id = #{0,jdbcType=VARCHAR}"
})
List<TaskInfoResult> findRunningTaskInfoByWorkspaceID(String workspaceID);
}

View File

@ -0,0 +1,62 @@
package io.metersphere.commons.utils;
import org.quartz.CronExpression;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.TriggerBuilder;
import java.util.Date;
/**
* @author song.tianyang
* @Date 2020/12/17 4:06 下午
* @Description CRON解析类
*/
public class CronUtils {
/**
* 解析表达式获取CronTrigger
* @param cron
* @return
*/
public static CronTrigger getCronTrigger(String cron) {
if (!CronExpression.isValidExpression(cron)) {
throw new RuntimeException("cron :" + cron + "表达式解析错误");
}
return TriggerBuilder.newTrigger().withIdentity("Caclulate Date").withSchedule(CronScheduleBuilder.cronSchedule(cron)).build();
}
/**
* 获取以指定时间为开始时间的下一次执行时间
* @param cron
* @param start
* @return
*/
public static Date getNextTriggerTime(String cron, Date start) {
if (start == null) {
return getNextTriggerTime(cron);
}else{
CronTrigger trigger = getCronTrigger(cron);
return trigger.getFireTimeAfter(start);
}
}
/**
* 获取以当前日期为准的下一次执行时间
* @param cron
* @return
*/
public static Date getNextTriggerTime(String cron) {
Date date = null;
try{
CronTrigger trigger = getCronTrigger(cron);
Date startDate = trigger.getStartTime();
date = trigger.getFireTimeAfter(startDate);
}catch (Exception e){
}
return date;
}
}

View File

@ -0,0 +1,121 @@
package io.metersphere.commons.utils;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class DateUtils {
public static final String DATE_PATTERM = "yyyy-MM-dd";
public static final String TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
public static Date getDate(String dateString) throws Exception {
SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_PATTERM);
return dateFormat.parse(dateString);
}
public static Date getTime(String timeString) throws Exception {
SimpleDateFormat dateFormat = new SimpleDateFormat(TIME_PATTERN);
return dateFormat.parse(timeString);
}
public static String getDateString(Date date) throws Exception {
SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_PATTERM);
return dateFormat.format(date);
}
public static String getDateString(long timeStamp) throws Exception {
SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_PATTERM);
return dateFormat.format(timeStamp);
}
public static String getTimeString(Date date) throws Exception {
SimpleDateFormat dateFormat = new SimpleDateFormat(TIME_PATTERN);
return dateFormat.format(date);
}
public static String getTimeString(long timeStamp) throws Exception {
SimpleDateFormat dateFormat = new SimpleDateFormat(TIME_PATTERN);
return dateFormat.format(timeStamp);
}
public static Date dateSum (Date date,int countDays){
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.DAY_OF_MONTH,countDays);
return calendar.getTime();
}
/**
* 获取入参日期所在周的周一周末日期 日期对应的时间为当日的零点
*
* @return Map<String, String>(2); key取值范围firstTime/lastTime
*/
public static Map<String, Date> getWeedFirstTimeAndLastTime(Date date) {
Map<String, Date> returnMap = new HashMap<>();
Calendar calendar = Calendar.getInstance();
//Calendar默认一周的开始是周日业务需求从周一开始算所以要"+1"
int weekDayAdd = 1;
try {
calendar.setTime(date);
calendar.set(Calendar.DAY_OF_WEEK, calendar.getActualMinimum(Calendar.DAY_OF_WEEK));
calendar.add(Calendar.DAY_OF_MONTH,weekDayAdd);
//第一天的时分秒是 00:00:00 这里直接取日期默认就是零点零分
Date thisWeekFirstTime = getDate(getDateString(calendar.getTime()));
calendar.clear();
calendar.setTime(date);
calendar.set(Calendar.DAY_OF_WEEK, calendar.getActualMaximum(Calendar.DAY_OF_WEEK));
calendar.add(Calendar.DAY_OF_MONTH,weekDayAdd);
//最后一天的时分秒应当是23:59:59 处理方式是增加一天计算日期再-1
calendar.add(Calendar.DAY_OF_MONTH,1);
Date nextWeekFirstDay = getDate(getDateString(calendar.getTime()));
Date thisWeekLastTime = getTime(getTimeString(nextWeekFirstDay.getTime()-1));
returnMap.put("firstTime", thisWeekFirstTime);
returnMap.put("lastTime", thisWeekLastTime);
} catch (Exception e) {
e.printStackTrace();
}
return returnMap;
}
public static void main(String[] args) throws Exception {
System.out.println("start:");
Date paramTime = getTime(getTimeString(new Long("1607672440731")));
Map<String, Date> weekDate = getWeedFirstTimeAndLastTime(paramTime);
for (Map.Entry<String, Date> entry :
weekDate.entrySet()) {
System.out.println(entry.getKey() + ":" + getTimeString(entry.getValue())+":"+entry.getValue().getTime());
}
long countTimeLong = new Long("1607672440731");
System.out.println(getTimeString(--countTimeLong));
}
/**
* 获取当天的起始时间Date
* @param time 指定日期 2020-12-13 06:12:42
* @return 当天起始时间 2020-12-13 00:00:00
* @throws Exception
*/
public static Date getDayStartTime(Date time) throws Exception {
return getDate(getDateString(time));
}
}

View File

@ -1,6 +1,7 @@
package io.metersphere.service;
import com.alibaba.fastjson.JSON;
import io.metersphere.api.dto.dataCount.response.TaskInfoResult;
import io.metersphere.base.domain.Schedule;
import io.metersphere.base.domain.ScheduleExample;
import io.metersphere.base.domain.User;
@ -9,6 +10,7 @@ import io.metersphere.base.mapper.ScheduleMapper;
import io.metersphere.base.mapper.UserMapper;
import io.metersphere.base.mapper.ext.ExtScheduleMapper;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.DateUtils;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.commons.utils.ServiceUtils;
import io.metersphere.commons.utils.SessionUtils;
@ -25,6 +27,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@ -162,4 +165,26 @@ public class ScheduleService {
schedule.setUserName(userMap.get(schedule.getUserId()));
});
}
public long countTaskByWorkspaceIdAndGroup(String workspaceId,String group) {
return scheduleMapper.countTaskByWorkspaceIdAndGroup(workspaceId,group);
}
public long countTaskByWorkspaceIdAndGroupInThisWeek(String workspaceID, String group) {
Map<String, Date> startAndEndDateInWeek = DateUtils.getWeedFirstTimeAndLastTime(new Date());
Date firstTime = startAndEndDateInWeek.get("firstTime");
Date lastTime = startAndEndDateInWeek.get("lastTime");
if(firstTime==null || lastTime == null){
return 0;
}else {
return scheduleMapper.countTaskByWorkspaceIdAndGroupAndCreateTimeRange(workspaceID,group,firstTime.getTime(),lastTime.getTime());
}
}
public List<TaskInfoResult> findRunningTaskInfoByWorkspaceID(String workspaceID) {
List<TaskInfoResult> runningTaskInfoList = scheduleMapper.findRunningTaskInfoByWorkspaceID(workspaceID);
return runningTaskInfoList;
}
}

View File

@ -0,0 +1,127 @@
<template>
<ms-container>
<ms-main-container v-loading="result.loading">
<el-row :gutter="0"></el-row>
<el-row :gutter="0">
<el-col :span="4" >
<ms-api-info-card :api-count-data="apiCountData"/>
</el-col>
<el-col :span="4" :offset="2">
<ms-test-case-info-card :test-case-count-data="testCaseCountData"/>
</el-col>
<el-col :span="4" :offset="2">
<ms-scene-info-card :scene-count-data="sceneCountData"/>
</el-col>
<el-col :span="4" :offset="2">
<ms-schedule-task-info-card :schedule-task-count-data="scheduleTaskCountData"/>
</el-col>
</el-row>
<el-row>
<el-col :span="4" >
<ms-api-detail-card :api-count-data="apiCountData"/>
</el-col>
<el-col :span="4" :offset="2">
<ms-test-case-detail-card :test-case-count-data="testCaseCountData"/>
</el-col>
<el-col :span="4" :offset="2">
<ms-scene-detail-card :scene-count-data="sceneCountData"/>
</el-col>
<el-col :span="4" :offset="2">
<ms-schedule-task-detail-card :schedule-task-count-data="scheduleTaskCountData"/>
</el-col>
</el-row>
<el-row :gutter="20" >
<el-col :span="11" >
<ms-failure-test-case-list/>
</el-col>
<el-col :span="13" >
<ms-running-task-list/>
</el-col>
</el-row>
</ms-main-container>
</ms-container>
</template>
<script>
import MsContainer from "@/business/components/common/components/MsContainer";
import MsMainContainer from "@/business/components/common/components/MsMainContainer";
import MsApiInfoCard from "./components/ApiInfoCard";
import MsSceneInfoCard from "./components/SceneInfoCard";
import MsScheduleTaskInfoCard from "./components/ScheduleTaskInfoCard";
import MsTestCaseInfoCard from "./components/TestCaseInfoCard";
import MsApiDetailCard from "./components/ApiDetailCard";
import MsSceneDetailCard from "./components/SceneDetailCard";
import MsScheduleTaskDetailCard from "./components/ScheduleTaskDetailCard";
import MsTestCaseDetailCard from "./components/TestCaseDetailCard";
import MsFailureTestCaseList from "./components/FailureTestCaseList";
import MsRunningTaskList from "./components/RunningTaskList"
import {getCurrentProjectID,getCurrentWorkspaceId} from "@/common/js/utils";
export default {
name: "ApiTestHome",
components: {
MsApiInfoCard, MsSceneInfoCard, MsScheduleTaskInfoCard, MsTestCaseInfoCard,
MsApiDetailCard, MsSceneDetailCard, MsScheduleTaskDetailCard, MsTestCaseDetailCard,
MsFailureTestCaseList,MsRunningTaskList,
MsMainContainer, MsContainer
},
data() {
return {
values: [],
apiCountData:{},
sceneCountData:{},
testCaseCountData:{},
scheduleTaskCountData:{},
result: {},
}
},
// activated() {
// this.getValues();
// },
// mounted() {
// this.getValues();
// },
created() {
this.search();
},
methods: {
search() {
let selectProjectId = getCurrentProjectID();
this.$get("/api/apiCount/"+selectProjectId, response => {
this.apiCountData = response.data;
});
this.$get("/api/testSceneInfoCount/"+selectProjectId, response => {
this.sceneCountData = response.data;
});
this.$get("/api/testCaseInfoCount/"+selectProjectId, response => {
this.testCaseCountData = response.data;
});
let workSpaceID = getCurrentWorkspaceId();
this.$get("/api/scheduleTaskInfoCount/"+workSpaceID, response => {
this.scheduleTaskCountData = response.data;
});
},
}
}
</script>
<style scoped>
.el-row {
margin-bottom: 20px;
margin-left: 20px;
margin-right: 20px;
}
</style>

View File

@ -0,0 +1,62 @@
<template>
<el-card class="table-card" v-loading="result.loading">
<template v-slot:header>
<span class="title">
{{$t('api_test.home_page.api_details_card.title')}}
</span>
</template>
<el-container>
<el-main>
<div class="text item">
{{$t('api_test.home_page.api_details_card.this_week_add',[apiCountData.thisWeekAddedCount])}}
</div>
</el-main>
</el-container>
</el-card>
</template>
<script>
export default {
name: "MsApiDetailCard",
components: {},
data() {
return {
result: {},
loading: false
}
},
props:{
apiCountData:{},
},
methods: {
search() {
// this.result = this.$get("/api/apiCount/5", response => {
// this.apiCountData = response.data;
// });
},
// link(row) {
// this.$router.push({
// path: '/api/report/view/' + row.id,
// })
// }
},
created() {
this.search();
},
activated() {
this.search();
}
}
</script>
<style>
.el-aside {
/*background-color: #D3DCE6;*/
/*color: #333;*/
text-align: center;
/*line-height: 20;*/
}
</style>

View File

@ -0,0 +1,63 @@
<template>
<el-card class="table-card" v-loading="result.loading">
<template v-slot:header>
<span class="title">
{{$t('api_test.home_page.api_count_card.title')}}
</span>
</template>
<el-container>
<el-aside width="40%">
<span class="countNumber">
{{apiCountData.allApiDataCountNumber}}
</span>
{{$t('api_test.home_page.unit_of_measurement')}}
</el-aside>
<el-container>
<el-main>
<div class="text item">
{{'HTTP: '+apiCountData.httpApiDataCountNumber}}
</div>
<div class="text item">
{{'RPC:'+apiCountData.rpcApiDataCountNumber}}
</div>
<div class="text item">
{{'TCP:'+apiCountData.tcpApiDataCountNumber}}
</div>
<div class="text item">
{{'SQL:'+apiCountData.sqlApiDataCountNumber}}
</div>
</el-main>
</el-container>
</el-container>
</el-card>
</template>
<script>
export default {
name: "MsApiInfoCard",
components: {},
data() {
return {
result: {},
loading: false
}
},
props:{
apiCountData:{},
},
}
</script>
<style>
.el-aside {
/*background-color: #D3DCE6;*/
/*color: #333;*/
text-align: center;
/*line-height: 20;*/
}
.countNumber{
font-size: 40px;
}
</style>

View File

@ -0,0 +1,57 @@
<template>
<el-card class="table-card" v-loading="result.loading">
<template v-slot:header>
<span class="title">
{{$t('api_test.home_page.failed_case_list.title')}}
</span>
</template>
<el-table border :data="tableData" class="adjust-table table-content" height="300px">
<el-table-column prop="sortIndex" :label="$t('api_test.home_page.failed_case_list.table_coloum.index')" width="100" show-overflow-tooltip/>
<el-table-column prop="caseName" :label="$t('api_test.home_page.failed_case_list.table_coloum.case_name')" width="250" show-overflow-tooltip/>
<el-table-column prop="testPlan" :label="$t('api_test.home_page.failed_case_list.table_coloum.test_plan')" show-overflow-tooltip/>
<el-table-column prop="failureTimes" :label="$t('api_test.home_page.failed_case_list.table_coloum.failure_times')" width="100" show-overflow-tooltip/>
</el-table>
</el-card>
</template>
<script>
import {getCurrentProjectID} from "@/common/js/utils";
export default {
name: "MsFailureTestCaseList",
data() {
return {
result: {},
tableData: [],
loading: false
}
},
methods: {
search() {
let projectID = getCurrentProjectID();
this.result = this.$get("/api/faliureCaseAboutTestPlan/"+projectID+"/10", response => {
this.tableData = response.data;
});
},
},
created() {
this.search();
},
activated() {
this.search();
}
}
</script>
<style scoped>
.el-table {
cursor:pointer;
}
</style>

View File

@ -0,0 +1,79 @@
<template>
<el-card class="table-card" v-loading="result.loading">
<template v-slot:header>
<span class="title">
{{$t('api_test.home_page.running_task_list.title')}}
</span>
</template>
<el-table border :data="tableData" class="adjust-table table-content" height="300px">
<el-table-column prop="index" :label="$t('api_test.home_page.running_task_list.table_coloum.index')" width="80" show-overflow-tooltip/>
<el-table-column prop="scenario" :label="$t('api_test.home_page.running_task_list.table_coloum.scenario')" width="200" show-overflow-tooltip/>
<el-table-column prop="rule" :label="$t('api_test.home_page.running_task_list.table_coloum.run_rule')" width="120" show-overflow-tooltip/>
<el-table-column width="100" :label="$t('api_test.home_page.running_task_list.table_coloum.task_status')">
<template v-slot:default="scope">
<el-switch @click.stop.native v-model="scope.row.taskStatus" @change="updateTask(scope.row)"/>
</template>
</el-table-column>
<el-table-column width="200" :label="$t('api_test.home_page.running_task_list.table_coloum.next_execution_time')">
<template v-slot:default="scope">
<span>{{ scope.row.nextExecutionTime | timestampFormatDate }}</span>
</template>
</el-table-column>
<el-table-column prop="creator" :label="$t('api_test.home_page.running_task_list.table_coloum.create_user')" width="150" show-overflow-tooltip/>
<el-table-column width="200" :label="$t('api_test.home_page.running_task_list.table_coloum.update_time')">
<template v-slot:default="scope">
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
</template>
</el-table-column>
</el-table>
</el-card>
</template>
<script>
import {getCurrentProjectID,getCurrentWorkspaceId} from "@/common/js/utils";
export default {
name: "MsRunningTaskList",
data() {
return {
value: '100',
result: {},
tableData: [],
loading: false
}
},
methods: {
search() {
let workSpaceID = getCurrentWorkspaceId();
this.result = this.$get("/api/runningTask/"+workSpaceID, response => {
this.tableData = response.data;
});
},
updateTask(taskRow){
this.result = this.$post('/api/schedule/updateEnableByPrimyKey', taskRow, response => {
this.search();
});
}
},
created() {
this.search();
},
activated() {
this.search();
}
}
</script>
<style scoped>
.el-table {
cursor:pointer;
}
</style>

View File

@ -0,0 +1,52 @@
<template>
<el-card class="table-card" v-loading="result.loading">
<template v-slot:header>
<span class="title">
{{$t('api_test.home_page.test_scene_details_card.title')}}
</span>
</template>
<el-container>
<el-main>
<div class="text item">
{{$t('api_test.home_page.test_scene_details_card.this_week_add',[sceneCountData.thisWeekAddedCount])}}
</div>
<div class="text item">
{{$t('api_test.home_page.test_scene_details_card.this_week_execute',[sceneCountData.thisWeekExecutedCount])}}
</div>
<div class="text item">
{{$t('api_test.home_page.test_scene_details_card.executed',[sceneCountData.executedCount])}}
</div>
</el-main>
</el-container>
</el-card>
</template>
<script>
export default {
name: "MsSceneDetailCard",
components: {},
data() {
return {
result: {},
loading: false
}
},
methods: {
},
props:{
sceneCountData:{},
},
}
</script>
<style>
.el-aside {
/*background-color: #D3DCE6;*/
/*color: #333;*/
text-align: center;
line-height: 100px;
}
</style>

View File

@ -0,0 +1,64 @@
<template>
<el-card class="table-card" v-loading="result.loading">
<template v-slot:header>
<span class="title">
{{$t('api_test.home_page.test_scene_count_card.title')}}
</span>
</template>
<el-container>
<el-aside width="40%">
<span class="countNumber">
{{sceneCountData.allApiDataCountNumber}}
</span>
{{$t('api_test.home_page.unit_of_measurement')}}
</el-aside>
<el-container>
<el-main>
<div class="text item">
</div>
<div class="text item">
</div>
<div class="text item">
</div>
<div class="text item">
</div>
</el-main>
</el-container>
</el-container>
</el-card>
</template>
<script>
export default {
name: "MsSceneInfoCard",
components: {},
data() {
return {
result: {},
loading: false
}
},
props:{
sceneCountData:{},
},
methods: {
},
}
</script>
<style>
.el-aside {
/*background-color: #D3DCE6;*/
/*color: #333;*/
text-align: center;
line-height: 100px;
}
.countNumber{
font-size: 40px;
}
</style>

View File

@ -0,0 +1,58 @@
<template>
<el-card class="table-card" v-loading="result.loading">
<template v-slot:header>
<span class="title">
{{$t('api_test.home_page.schedule_task_details_card.title')}}
</span>
</template>
<el-container>
<el-main>
<div class="text item">
{{$t('api_test.home_page.schedule_task_details_card.this_week_add',[scheduleTaskCountData.thisWeekAddedCount])}}
</div>
<div class="text item">
{{$t('api_test.home_page.schedule_task_details_card.this_week_execute',[scheduleTaskCountData.thisWeekExecutedCount])}}
</div>
<div class="text item">
{{$t('api_test.home_page.schedule_task_details_card.executed',[scheduleTaskCountData.executedCount])}}
</div>
</el-main>
</el-container>
</el-card>
</template>
<script>
export default {
name: "MsTestCaseDetailCard",
components: {},
data() {
return {
result: {},
loading: false
}
},
props:{
scheduleTaskCountData:{},
},
methods: {
},
created() {
},
activated() {
}
}
</script>
<style>
.el-aside {
/*background-color: #D3DCE6;*/
/*color: #333;*/
text-align: center;
/*line-height: 200px;*/
}
</style>

View File

@ -0,0 +1,72 @@
<template>
<el-card class="table-card" v-loading="result.loading">
<template v-slot:header>
<span class="title">
{{$t('api_test.home_page.schedule_task_count_card.title')}}
</span>
</template>
<el-container>
<el-aside width="40%">
<span class="countNumber">
{{scheduleTaskCountData.allApiDataCountNumber}}
</span>
{{$t('api_test.home_page.unit_of_measurement')}}
</el-aside>
<el-container>
<el-main>
<div class="text item">
</div>
<div class="text item">
</div>
<div class="text item">
</div>
<div class="text item">
</div>
</el-main>
</el-container>
</el-container>
</el-card>
</template>
<script>
export default {
name: "MsScheduleTaskInfoCard",
components: {},
data() {
return {
result: {},
apiCountData: {},
loading: false
}
},
props:{
scheduleTaskCountData:{},
},
methods: {
},
created() {
},
activated() {
}
}
</script>
<style>
.el-aside {
/*background-color: #D3DCE6;*/
/*color: #333;*/
text-align: center;
/*line-height: 200px;*/
}
.countNumber{
font-size: 40px;
}
</style>

View File

@ -0,0 +1,58 @@
<template>
<el-card class="table-card" v-loading="result.loading">
<template v-slot:header>
<span class="title">
{{$t('api_test.home_page.test_case_details_card.title')}}
</span>
</template>
<el-container>
<el-main>
<div class="text item">
{{$t('api_test.home_page.test_case_details_card.this_week_add',[testCaseCountData.thisWeekAddedCount])}}
</div>
<div class="text item">
{{$t('api_test.home_page.test_case_details_card.this_week_execute',[testCaseCountData.thisWeekExecutedCount])}}
</div>
<div class="text item">
{{$t('api_test.home_page.test_case_details_card.executed',[testCaseCountData.executedCount])}}
</div>
</el-main>
</el-container>
</el-card>
</template>
<script>
export default {
name: "MsTestCaseDetailCard",
components: {},
data() {
return {
result: {},
loading: false
}
},
props:{
testCaseCountData:{},
},
methods: {
},
created() {
},
activated() {
}
}
</script>
<style>
.el-aside {
/*background-color: #D3DCE6;*/
/*color: #333;*/
text-align: center;
/*line-height: 200px;*/
}
</style>

View File

@ -0,0 +1,71 @@
<template>
<el-card class="table-card" v-loading="result.loading">
<template v-slot:header>
<span class="title">
{{$t('api_test.home_page.test_case_count_card.title')}}
</span>
</template>
<el-container>
<el-aside width="40%">
<span class="countNumber">
{{testCaseCountData.allApiDataCountNumber}}
</span>
{{$t('api_test.home_page.unit_of_measurement')}}
</el-aside>
<el-container>
<el-main>
<div class="text item">
{{'HTTP: '+testCaseCountData.httpApiDataCountNumber}}
</div>
<div class="text item">
{{'RPC:'+testCaseCountData.rpcApiDataCountNumber}}
</div>
<div class="text item">
{{'TCP:'+testCaseCountData.tcpApiDataCountNumber}}
</div>
<div class="text item">
{{'SQL:'+testCaseCountData.sqlApiDataCountNumber}}
</div>
</el-main>
</el-container>
</el-container>
</el-card>
</template>
<script>
export default {
name: "MsTestCaseInfoCard",
components: {},
data() {
return {
result: {},
loading: false
}
},
props:{
testCaseCountData:{},
},
methods: {
},
created() {
},
activated() {
}
}
</script>
<style>
.el-aside {
/*background-color: #D3DCE6;*/
/*color: #333;*/
text-align: center;
/*line-height: 200px;*/
}
.countNumber{
font-size: 40px;
}
</style>

View File

@ -11,7 +11,8 @@ export default {
{
path: 'home',
name: 'fucHome',
component: () => import('@/business/components/api/home/ApiTestHome'),
// component: () => import('@/business/components/api/home/ApiTestHome'),
component: () => import('@/business/components/api/homepage/ApiTestHomePage'),
},
{
path: "test/:type",
@ -53,7 +54,7 @@ export default {
path: "automation/report",
name: "ApiReportList",
component: () => import('@/business/components/api/automation/report/ApiReportList'),
},
},
{
path: 'monitor/view',
name: 'ApiMonitor',

View File

@ -791,6 +791,64 @@ export default {
swagger_export_tip: "Export jSON-formatted files via Swagger website",
suffixFormatErr: "The file format does not meet the requirements",
swagger_url_import: "Import using URL",
},
home_page:{
unit_of_measurement:"",
api_count_card:{
title: "API count",
},
test_case_count_card:{
title: "Test case count",
},
test_scene_count_card:{
title: "Scene count",
},
schedule_task_count_card:{
title: "Schedule task count",
},
api_details_card:{
title: "API",
this_week_add:"Added {0} this week",
},
test_case_details_card:{
title: "Test case",
this_week_add:"Added {0} this week",
this_week_execute:"Executed {0} this week",
executed:"Executed {0} in history",
},
test_scene_details_card:{
title: "Scene",
this_week_add:"Added {0} this week",
this_week_execute:"Executed {0} this week",
executed:"Executed {0} in history",
},
schedule_task_details_card:{
title: "Schedule task",
this_week_add:"Added {0} this week",
this_week_execute:"Executed {0} this week",
executed:"Executed {0} in history",
},
failed_case_list:{
title: "Top 10 failure process set cases in the past 7 days",
table_coloum:{
index: "Ranking",
case_name: "Case name",
test_plan: "Test plan",
failure_times: "Failure times",
},
},
running_task_list:{
title: "Running task",
table_coloum:{
index: "Index",
scenario: "Scene",
run_rule: "Rule",
task_status: "Status",
next_execution_time: "Next Execution Time",
create_user: "Creator",
update_time: "Update time",
},
}
}
},
api_report: {

View File

@ -792,6 +792,64 @@ export default {
swagger_export_tip: "通过 Swagger 页面导出",
suffixFormatErr: "文件格式不符合要求",
swagger_url_import: "使用URL导入",
},
home_page:{
unit_of_measurement:"个",
api_count_card:{
title: "接口总数",
},
test_case_count_card:{
title: "用例总数",
},
test_scene_count_card:{
title: "场景总数",
},
schedule_task_count_card:{
title: "定时任务总数",
},
api_details_card:{
title: "接口",
this_week_add:"本周新增{0}个",
},
test_case_details_card:{
title: "用例",
this_week_add:"本周新增: {0}个",
this_week_execute:"本周执行: {0}次",
executed:"历史总执行: {0}次",
},
test_scene_details_card:{
title: "场景",
this_week_add:"本周新增: {0}个",
this_week_execute:"本周执行: {0}次",
executed:"历史总执行: {0}次",
},
schedule_task_details_card:{
title: "定时任务",
this_week_add:"本周新增: {0}个",
this_week_execute:"本周执行: {0}次",
executed:"历史总执行: {0}次",
},
failed_case_list:{
title: "过去7天流程集失败用例TOP 10",
table_coloum:{
index: "排名",
case_name: "用例名称",
test_plan: "所属测试计划",
failure_times: "失败次数",
},
},
running_task_list:{
title: "运行中的任务",
table_coloum:{
index: "序号",
scenario: "场景名称",
run_rule: "运行规则",
task_status: "任务状态",
next_execution_time: "下次执行时间",
create_user: "创建人",
update_time: "更新时间",
},
}
}
},
api_report: {

View File

@ -791,6 +791,64 @@ export default {
swagger_export_tip: "通過 Swagger 頁面導出",
suffixFormatErr: "文件格式不符合要求",
swagger_url_import: "使用URL導入",
},
home_page:{
unit_of_measurement:"個",
api_count_card:{
title: "接口總數",
},
test_case_count_card:{
title: "用例總數",
},
test_scene_count_card:{
title: "場景總數",
},
schedule_task_count_card:{
title: "定時任務總數",
},
api_details_card:{
title: "接口",
this_week_add:"本週新增{0}个",
},
test_case_details_card:{
title: "用例",
this_week_add:"本週新增: {0}个",
this_week_execute:"本週執行: {0}次",
executed:"歷史總執行: {0}次",
},
test_scene_details_card:{
title: "場景",
this_week_add:"本週新增: {0}个",
this_week_execute:"本週執行: {0}次",
executed:"歷史總執行: {0}次",
},
schedule_task_details_card:{
title: "定時任務",
this_week_add:"本週新增: {0}个",
this_week_execute:"本週執行: {0}次",
executed:"歷史總執行: {0}次",
},
failed_case_list:{
title: "過去7天流程集失敗用例TOP 10",
table_coloum:{
index: "排名",
case_name: "用例名稱",
test_plan: "所屬測試計畫",
failure_times: "失敗次數",
},
},
running_task_list:{
title: "運行中的任務",
table_coloum:{
index: "序號",
scenario: "場景名稱",
run_rule: "運行規則",
task_status: "任務狀態",
next_execution_time: "下次執行時間",
create_user: "創建人",
update_time: "更新時間",
},
}
}
},
api_report: {