fix(测试计划): 查询测试计划UI用例时不再循环查询所属环境

--bug=1025646 --user=宋天阳 【测试跟踪】测试计划-进入接口场景和UI用例列表-每个用例都会调用一次环境接口
https://www.tapd.cn/55049933/s/1365167
This commit is contained in:
song-tianyang 2023-04-21 13:45:46 +08:00 committed by 建国
parent 6c7f823f5c
commit 3812c7b1d9
5 changed files with 532 additions and 387 deletions

View File

@ -35,4 +35,6 @@ public class ApiScenarioDTO extends ApiScenarioWithBLOBs {
private String creator;
private String workspaceName;
private String workspaceId;
//用于测试计划场景表格中环境展示
private Map<String, String> tableShowEnv;
}

View File

@ -0,0 +1,52 @@
package io.metersphere.service;
import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs;
import io.metersphere.base.domain.Project;
import io.metersphere.base.mapper.ApiTestEnvironmentMapper;
import io.metersphere.environment.service.BaseEnvGroupProjectService;
import jakarta.annotation.Resource;
import jakarta.transaction.Transactional;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@Service
@Transactional
public class EnvironmentService {
@Resource
private BaseEnvGroupProjectService envGroupProjectService;
@Resource
private ApiTestEnvironmentMapper apiTestEnvironmentMapper;
@Resource
private BaseProjectService baseProjectService;
public Map<String, String> getEnvNameMap(String groupId) {
Map<String, String> map = envGroupProjectService.getEnvMap(groupId);
Set<String> set = map.keySet();
HashMap<String, String> envMap = new HashMap<>(16);
if (set.isEmpty()) {
return envMap;
}
for (String projectId : set) {
String envId = map.get(projectId);
if (StringUtils.isBlank(envId)) {
continue;
}
Project project = baseProjectService.getProjectById(projectId);
ApiTestEnvironmentWithBLOBs environment = apiTestEnvironmentMapper.selectByPrimaryKey(envId);
if (project == null || environment == null) {
continue;
}
String projectName = project.getName();
String envName = environment.getName();
if (StringUtils.isBlank(projectName) || StringUtils.isBlank(envName)) {
continue;
}
envMap.put(projectName, envName);
}
return envMap;
}
}

View File

@ -34,10 +34,7 @@ import io.metersphere.environment.service.BaseEnvironmentService;
import io.metersphere.i18n.Translator;
import io.metersphere.log.vo.OperatingLogDetails;
import io.metersphere.request.ResetOrderRequest;
import io.metersphere.service.BaseProjectApplicationService;
import io.metersphere.service.BaseProjectService;
import io.metersphere.service.BaseUserService;
import io.metersphere.service.ServiceUtils;
import io.metersphere.service.*;
import io.metersphere.service.definition.ApiDefinitionExecResultService;
import io.metersphere.service.plan.remote.TestPlanService;
import io.metersphere.service.scenario.ApiScenarioModuleService;
@ -111,19 +108,46 @@ public class TestPlanScenarioCaseService {
@Lazy
@Resource
private ApiScenarioReportStructureService apiScenarioReportStructureService;
@Resource
private EnvironmentService environmentService;
public List<ApiScenarioDTO> list(TestPlanScenarioRequest request) {
request.setProjectId(null);
request.setOrders(ServiceUtils.getDefaultSortOrder(request.getOrders()));
List<ApiScenarioDTO> apiTestCases = extTestPlanScenarioCaseMapper.list(request);
if (CollectionUtils.isEmpty(apiTestCases)) {
return apiTestCases;
List<ApiScenarioDTO> scenarioDTOList = extTestPlanScenarioCaseMapper.list(request);
if (CollectionUtils.isEmpty(scenarioDTOList)) {
return scenarioDTOList;
}
buildProjectInfo(apiTestCases);
buildUserInfo(apiTestCases);
return apiTestCases;
buildProjectInfo(scenarioDTOList);
buildUserInfo(scenarioDTOList);
return buildEnvironment(scenarioDTOList);
}
private List<ApiScenarioDTO> buildEnvironment(List<ApiScenarioDTO> scenarioDTOList) {
List<ApiScenarioDTO> returnData = new ArrayList<>();
scenarioDTOList.forEach(scenario -> {
if (StringUtils.equalsIgnoreCase(scenario.getEnvironmentType(), EnvironmentType.GROUP.name())) {
if (StringUtils.isNotEmpty(scenario.getEnvironmentGroupId())) {
Map<String, String> map = environmentService.getEnvNameMap(scenario.getEnvironmentGroupId());
scenario.setTableShowEnv(map);
}
} else if (StringUtils.equalsIgnoreCase(scenario.getEnvironmentType(), EnvironmentType.JSON.name())) {
try {
if (StringUtils.isNotEmpty(scenario.getEnvironment())) {
Map<String, String> environmentMap = this.getScenarioCaseEnv(JSON.parseMap(scenario.getEnvironment()));
scenario.setTableShowEnv(environmentMap);
}
} catch (Exception e) {
LogUtil.error("测试计划场景环境解析报错!", e);
}
}
returnData.add(scenario);
});
return returnData;
}
public void buildProjectInfo(List<? extends ApiScenarioDTO> apiTestCases) {
List<String> projectIds = apiTestCases.stream()
.map(ApiScenarioDTO::getProjectId)

View File

@ -87,7 +87,7 @@
:filters="apiscenariofilters.LEVEL_FILTERS"
>
<template v-slot:default="scope">
<priority-table-item :value="scope.row.level" ref="level"/>
<priority-table-item :value="scope.row.level" ref="level" />
</template>
</ms-table-column>
@ -107,16 +107,16 @@
<el-tag type="success" size="mini" effect="plain">
{{ k }}
</el-tag>
<br/>
<br />
</span>
<el-popover placement="top" width="350" trigger="click">
<div v-for="(k, v, index) in row.envs" :key="index">
<span class="plan-case-env"
>{{ v }}:
>{{ v }}:
<el-tag type="success" size="mini" effect="plain">{{
k
}}</el-tag
><br/>
k
}}</el-tag
><br />
</span>
</div>
<el-link
@ -141,20 +141,26 @@
:showOverflowTooltip="false"
>
<template v-slot:default="scope">
<el-tooltip class="item" effect="dark" placement="top">
<div v-html="getTagToolTips(scope.row.tags)" slot="content"></div>
<div class="oneLine">
<ms-tag
v-for="(itemName, index) in scope.row.tags"
:key="index"
type="success"
effect="plain"
:show-tooltip="scope.row.tags.length === 1 && itemName.length * 12 <= 100"
:content="itemName"
style="margin-left: 0px; margin-right: 2px"/>
</div>
</el-tooltip>
</template>
<el-tooltip class="item" effect="dark" placement="top">
<div
v-html="getTagToolTips(scope.row.tags)"
slot="content"
></div>
<div class="oneLine">
<ms-tag
v-for="(itemName, index) in scope.row.tags"
:key="index"
type="success"
effect="plain"
:show-tooltip="
scope.row.tags.length === 1 && itemName.length * 12 <= 100
"
:content="itemName"
style="margin-left: 0px; margin-right: 2px"
/>
</div>
</el-tooltip>
</template>
</ms-table-column>
<ms-table-column
@ -189,8 +195,8 @@
min-width="120"
/>
<ms-update-time-column :field="item" :fields-width="fieldsWidth"/>
<ms-create-time-column :field="item" :fields-width="fieldsWidth"/>
<ms-update-time-column :field="item" :fields-width="fieldsWidth" />
<ms-create-time-column :field="item" :fields-width="fieldsWidth" />
<ms-table-column
:field="item"
@ -212,7 +218,7 @@
@click="showReport(row)"
:disabled="!row.lastResult || row.lastResult === 'PENDING'"
>
<ms-test-plan-api-status :status="row.lastResult"/>
<ms-test-plan-api-status :status="row.lastResult" />
</el-link>
</template>
</ms-table-column>
@ -268,7 +274,7 @@
@close="search"
/>
<ms-task-center ref="taskCenter" :show-menu="false"/>
<ms-task-center ref="taskCenter" :show-menu="false" />
</div>
</template>
@ -280,7 +286,7 @@ import {
getCurrentProjectID,
getCurrentWorkspaceId,
} from "metersphere-frontend/src/utils/token";
import {getUUID, strMapToObj} from "metersphere-frontend/src/utils";
import { getUUID, strMapToObj } from "metersphere-frontend/src/utils";
import {
hasLicense,
hasPermission,
@ -293,36 +299,31 @@ import {
getCustomTableWidth,
initCondition,
} from "metersphere-frontend/src/utils/tableUtils";
import {
ENV_TYPE,
TEST_PLAN_SCENARIO_CASE,
} from "metersphere-frontend/src/utils/constants";
import { TEST_PLAN_SCENARIO_CASE } from "metersphere-frontend/src/utils/constants";
import HeaderLabelOperate from "metersphere-frontend/src/components/head/HeaderLabelOperate";
import BatchEdit from "@/business/case/components/BatchEdit";
import MsPlanRunMode from "@/business/plan/common/PlanRunModeWithEnv";
import PriorityTableItem from "@/business/common/tableItems/planview/PriorityTableItem";
import {API_SCENARIO_FILTERS} from "metersphere-frontend/src/utils/table-constants";
import { API_SCENARIO_FILTERS } from "metersphere-frontend/src/utils/table-constants";
import MsTaskCenter from "metersphere-frontend/src/components/task/TaskCenter";
import MsTable from "metersphere-frontend/src/components/table/MsTable";
import MsTableColumn from "metersphere-frontend/src/components/table/MsTableColumn";
import MsUpdateTimeColumn from "metersphere-frontend/src/components/table/MsUpdateTimeColumn";
import MsCreateTimeColumn from "metersphere-frontend/src/components/table/MsCreateTimeColumn";
import {editTestPlanScenarioCaseOrder} from "@/api/remote/plan/test-plan";
import { editTestPlanScenarioCaseOrder } from "@/api/remote/plan/test-plan";
import {
testPlanScenarioCaseBatchDelete,
testPlanScenarioCaseBatchUpdateEnv,
testPlanScenarioCaseDelete,
testPlanScenarioCaseRun,
testPlanScenarioCaseSelectAllTableRows,
testPlanScenarioEnv,
testPlanScenarioList,
} from "@/api/remote/plan/test-plan-scenario";
import {environmentGroupGetProjectMapName} from "@/api/environment-group";
import {apiAutomationReduction} from "@/api/remote/api/api-automation";
import { apiAutomationReduction } from "@/api/remote/api/api-automation";
import MicroApp from "metersphere-frontend/src/components/MicroApp";
import MsTestPlanApiStatus from "@/business/plan/view/comonents/api/TestPlanApiStatus";
import {getVersionFilters} from "@/business/utils/sdk-utils";
import {TEST_PLAN_API_SCENARIO_CONFIGS} from "metersphere-frontend/src/components/search/search-components";
import { getVersionFilters } from "@/business/utils/sdk-utils";
import { TEST_PLAN_API_SCENARIO_CONFIGS } from "metersphere-frontend/src/components/search/search-components";
import MsTestPlanRunModeWithEnv from "@/business/plan/common/TestPlanRunModeWithEnv";
export default {
@ -484,7 +485,7 @@ export default {
if (this.planId) {
this.condition.planId = this.planId;
testPlanScenarioList(
{pageNum: this.currentPage, pageSize: this.pageSize},
{ pageNum: this.currentPage, pageSize: this.pageSize },
this.condition
).then((response) => {
let data = response.data;
@ -497,25 +498,9 @@ export default {
});
this.tableData.forEach((item) => {
try {
let envs;
const type = item.environmentType;
if (type === ENV_TYPE.GROUP && item.environmentGroupId) {
environmentGroupGetProjectMapName(item.environmentGroupId).then(
(res) => {
let data = res.data;
if (data) {
envs = new Map(Object.entries(data));
this.$set(item, "envs", res.data);
}
}
);
} else if (type === ENV_TYPE.JSON) {
envs = JSON.parse(item.environment);
if (envs) {
testPlanScenarioEnv(envs).then((res) => {
this.$set(item, "envs", res.data);
});
}
let data = item.tableShowEnv;
if (data) {
this.$set(item, "envs", data);
}
} catch (error) {
this.$set(item, "envs", {});
@ -558,7 +543,7 @@ export default {
let rows = this.orderBySelectRows(this.$refs.table.selectRows);
if (this.planId) {
let selectParam = buildBatchParam(this);
let param = {config: config, planCaseIds: []};
let param = { config: config, planCaseIds: [] };
param.ids = rows.map((r) => r.id);
rows.forEach((row) => {
this.buildExecuteParam(param, row);
@ -577,7 +562,7 @@ export default {
},
execute(row) {
this.infoDb = false;
let param = {planCaseIds: []};
let param = { planCaseIds: [] };
this.reportId = "";
this.buildExecuteParam(param, row);
param.triggerMode = "MANUAL";
@ -695,25 +680,25 @@ export default {
openById(item) {
let automationData = this.$router.resolve(
"/api/automation/default/" +
getUUID() +
"/scenario/edit:" +
item.caseId +
"/" +
item.projectId +
"/" +
getCurrentWorkspaceId()
getUUID() +
"/scenario/edit:" +
item.caseId +
"/" +
item.projectId +
"/" +
getCurrentWorkspaceId()
);
window.open(automationData.href, "_blank");
},
getTagToolTips(tags) {
try {
let showTips = '';
let showTips = "";
tags.forEach((item) => {
showTips += item + ',';
showTips += item + ",";
});
return showTips.substr(0, showTips.length - 1);
} catch (e) {
return '';
return "";
}
},
},