feat(测试跟踪): 功能用例关联用例弹窗模块树显示数量
--story=1011262 --user=宋昌昌 【Bug转需求】【测试跟踪】功能用例-编辑-关联测试用例-接口/场景/UI/性能用例-关联弹框-模块树和标题均未显示用例数量 https://www.tapd.cn/55049933/s/1359679
This commit is contained in:
parent
374c85f159
commit
60ed39d2f5
|
@ -48,6 +48,8 @@ public interface ExtApiDefinitionMapper {
|
|||
|
||||
List<ApiModuleDTO> moduleCountByCollection(@Param("request") ApiDefinitionRequest request);
|
||||
|
||||
List<ApiModuleDTO> moduleCaseCountByCollection(@Param("request") ApiDefinitionRequest request);
|
||||
|
||||
int checkOriginalStatusByIds(@Param("ids") List<String> ids);
|
||||
|
||||
List<String> getIdsOrderByUpdateTime(@Param("projectId") String projectId);
|
||||
|
|
|
@ -706,6 +706,72 @@
|
|||
GROUP BY module_id
|
||||
</select>
|
||||
|
||||
<select id="moduleCaseCountByCollection" resultType="io.metersphere.api.dto.definition.ApiModuleDTO">
|
||||
select ad.module_id AS id, count(atc.id) AS caseNum
|
||||
from api_test_case atc join api_definition ad on atc.api_definition_id = ad.id
|
||||
where (atc.status is null or atc.status != 'Trash')
|
||||
<if test="request.protocol != null and request.protocol!=''">
|
||||
and ad.protocol = #{request.protocol}
|
||||
</if>
|
||||
<if test="request.projectId != null and request.projectId!=''">
|
||||
and ad.project_id = #{request.projectId}
|
||||
</if>
|
||||
<if test="request.name != null and request.name!=''">
|
||||
and (atc.name like CONCAT('%', #{request.name},'%')
|
||||
or atc.tags like CONCAT('%', #{request.name},'%')
|
||||
or atc.num like CONCAT('%', #{request.name},'%'))
|
||||
</if>
|
||||
<if test="request.notInIds != null and request.notInIds.size() > 0">
|
||||
and atc.id not in
|
||||
<foreach collection="request.notInIds" item="notInId" separator="," open="(" close=")">
|
||||
#{notInId}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="request.moduleIds != null and request.moduleIds.size() > 0">
|
||||
and ad.module_id in
|
||||
<foreach collection="request.moduleIds" item="nodeId" separator="," open="(" close=")">
|
||||
#{nodeId}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="request.combine != null">
|
||||
<include refid="relevanceApiCombine">
|
||||
<property name="condition" value="request.combine"/>
|
||||
<property name="name" value="request.name"/>
|
||||
<property name="objectKey" value="request.combine.tags"/>
|
||||
</include>
|
||||
</if>
|
||||
<include refid="relevanceApiVersionCondition">
|
||||
<property name="versionTable" value="ad"/>
|
||||
</include>
|
||||
<if test="request.filters != null and request.filters.size() > 0">
|
||||
<foreach collection="request.filters.entrySet()" index="key" item="values">
|
||||
<if test="values != null and values.size() > 0">
|
||||
<choose>
|
||||
<when test="key == 'priority'">
|
||||
and atc.priority in
|
||||
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||
#{value}
|
||||
</foreach>
|
||||
</when>
|
||||
<when test="key=='status'">
|
||||
and atc.status in
|
||||
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||
#{value}
|
||||
</foreach>
|
||||
</when>
|
||||
<when test="key=='version_id'">
|
||||
and atc.version_id in
|
||||
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||
#{value}
|
||||
</foreach>
|
||||
</when>
|
||||
</choose>
|
||||
</if>
|
||||
</foreach>
|
||||
</if>
|
||||
GROUP BY module_id
|
||||
</select>
|
||||
|
||||
<sql id="filter">
|
||||
<if test="request.filters != null and request.filters.size() > 0">
|
||||
<foreach collection="request.filters.entrySet()" index="key" item="values">
|
||||
|
@ -1215,4 +1281,57 @@
|
|||
</where>
|
||||
</sql>
|
||||
|
||||
<sql id="relevanceApiCombine">
|
||||
<if test='${condition}.name != null and (${name} == null or ${name} == "")'>
|
||||
and atc.name
|
||||
<include refid="condition">
|
||||
<property name="object" value="${condition}.name"/>
|
||||
</include>
|
||||
</if>
|
||||
<if test="${condition}.updateTime != null">
|
||||
and atc.update_time
|
||||
<include refid="condition">
|
||||
<property name="object" value="${condition}.updateTime"/>
|
||||
</include>
|
||||
</if>
|
||||
<if test="${condition}.createTime != null">
|
||||
and atc.create_time
|
||||
<include refid="condition">
|
||||
<property name="object" value="${condition}.createTime"/>
|
||||
</include>
|
||||
</if>
|
||||
<if test="${condition}.priority != null">
|
||||
and atc.priority
|
||||
<include refid="condition">
|
||||
<property name="object" value="${condition}.priority"/>
|
||||
</include>
|
||||
</if>
|
||||
<if test="${condition}.status != null">
|
||||
and atc.status
|
||||
<include refid="condition">
|
||||
<property name="object" value="${condition}.status"/>
|
||||
</include>
|
||||
</if>
|
||||
<if test='${condition}.tags != null and ${objectKey}.operator == "like"'>
|
||||
and atc.tags
|
||||
<include refid="condition">
|
||||
<property name="object" value="${condition}.tags"/>
|
||||
</include>
|
||||
</if>
|
||||
<if test="${condition}.creator != null">
|
||||
and atc.create_user_id
|
||||
<include refid="condition">
|
||||
<property name="object" value="${condition}.creator"/>
|
||||
</include>
|
||||
</if>
|
||||
</sql>
|
||||
|
||||
<sql id="relevanceApiVersionCondition">
|
||||
<if test="request.versionId != null">
|
||||
and ${versionTable}.version_id = #{request.versionId}
|
||||
</if>
|
||||
<if test="request.versionId == null and request.id == null">
|
||||
and ${versionTable}.latest = 1
|
||||
</if>
|
||||
</sql>
|
||||
</mapper>
|
||||
|
|
|
@ -30,6 +30,13 @@ public class ApiModuleController {
|
|||
return apiModuleService.getNodeTreeByProjectId(projectId, protocol, null);
|
||||
}
|
||||
|
||||
@PostMapping("/relevance/list/{projectId}/{protocol}")
|
||||
public List<ApiModuleDTO> getRelevanceNodeByProjectId(@PathVariable String projectId, @PathVariable String protocol, @RequestBody ApiDefinitionRequest request) {
|
||||
String userId = SessionUtils.getUserId();
|
||||
ApiDefinitionDefaultApiTypeUtil.addUserSelectApiType(userId, protocol);
|
||||
return apiModuleService.getNodeTreeByCondition(projectId, protocol, null, request, true);
|
||||
}
|
||||
|
||||
@GetMapping("/list/{projectId}/{protocol}/{versionId}")
|
||||
public List<ApiModuleDTO> getNodeByProjectId(@PathVariable String projectId, @PathVariable String protocol,
|
||||
@PathVariable String versionId) {
|
||||
|
@ -42,7 +49,7 @@ public class ApiModuleController {
|
|||
public List<ApiModuleDTO> searchNodeByProjectId(@PathVariable String projectId, @PathVariable String protocol, @RequestBody ApiDefinitionRequest request) {
|
||||
String userId = SessionUtils.getUserId();
|
||||
ApiDefinitionDefaultApiTypeUtil.addUserSelectApiType(userId, protocol);
|
||||
return apiModuleService.getNodeTreeByCondition(projectId, protocol, null, request);
|
||||
return apiModuleService.getNodeTreeByCondition(projectId, protocol, null, request, false);
|
||||
}
|
||||
|
||||
@GetMapping("/trash/list/{projectId}/{protocol}/{versionId}")
|
||||
|
|
|
@ -142,10 +142,10 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
|
|||
|
||||
public List<ApiModuleDTO> getNodeTreeByProjectId(String projectId, String protocol, String versionId) {
|
||||
ApiDefinitionRequest request = new ApiDefinitionRequest();
|
||||
return getNodeTreeByCondition(projectId, protocol, versionId, request);
|
||||
return getNodeTreeByCondition(projectId, protocol, versionId, request, false);
|
||||
}
|
||||
|
||||
public List<ApiModuleDTO> getNodeTreeByCondition(String projectId, String protocol, String versionId, ApiDefinitionRequest request) {
|
||||
public List<ApiModuleDTO> getNodeTreeByCondition(String projectId, String protocol, String versionId, ApiDefinitionRequest request, boolean isCaseRelevance) {
|
||||
List<ApiModuleDTO> apiModules = getApiModulesByProjectAndPro(projectId, protocol);
|
||||
LogUtil.info("当前API模块节点:", apiModules.size());
|
||||
|
||||
|
@ -153,7 +153,7 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
|
|||
request.setProtocol(protocol);
|
||||
Map<String, List<String>> filters = new LinkedHashMap<>();
|
||||
filters.put(ApiTestConstants.STATUS, ApiTestConstants.STATUS_ALL);
|
||||
if (MapUtils.isEmpty(request.getFilters()) || !request.getFilters().containsKey(ApiTestConstants.STATUS)) {
|
||||
if ((MapUtils.isEmpty(request.getFilters()) || !request.getFilters().containsKey(ApiTestConstants.STATUS)) && !isCaseRelevance) {
|
||||
request.setFilters(filters);
|
||||
}
|
||||
request.setModuleIds(new ArrayList<>());
|
||||
|
@ -161,7 +161,12 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
|
|||
request.setVersionId(versionId);
|
||||
}
|
||||
apiDefinitionService.checkFilterHasCoverage(request);
|
||||
List<ApiModuleDTO> countMNodes = extApiDefinitionMapper.moduleCountByCollection(request);
|
||||
List<ApiModuleDTO> countMNodes;
|
||||
if (isCaseRelevance) {
|
||||
countMNodes = extApiDefinitionMapper.moduleCaseCountByCollection(request);
|
||||
} else {
|
||||
countMNodes = extApiDefinitionMapper.moduleCountByCollection(request);
|
||||
}
|
||||
return getNodeTrees(apiModules, getCountMap(countMNodes));
|
||||
}
|
||||
|
||||
|
|
|
@ -149,6 +149,10 @@ export function getModuleByUrl(url) {
|
|||
return get('/environment/relate' + url);
|
||||
}
|
||||
|
||||
export function getCaseRelateModuleByCondition(url, params) {
|
||||
return post('/environment/relate' + url, params)
|
||||
}
|
||||
|
||||
export function getCodeSnippetPages(goPage, pageSize, params) {
|
||||
if (currentModuleName === 'project') {
|
||||
return post(`/custom/func/list/${goPage}/${pageSize}`, params);
|
||||
|
|
|
@ -63,6 +63,11 @@ public class EnvironmentRelateController {
|
|||
return microService.getForData(MicroServiceName.API_TEST, "/api/module/list/" + projectId + "/" + protocol);
|
||||
}
|
||||
|
||||
@PostMapping("/api/module/relevance/list/{projectId}/{protocol}")
|
||||
public Object getRelevanceNodeByProjectId(@PathVariable String projectId, @PathVariable String protocol, @RequestBody Object request) {
|
||||
return microService.postForData(MicroServiceName.API_TEST, "/api/module/relevance/list/" + projectId + "/" + protocol, request);
|
||||
}
|
||||
|
||||
@PostMapping("/custom/func/list/{goPage}/{pageSize}")
|
||||
public Object query(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody Object request) {
|
||||
return microService.postForData(MicroServiceName.PROJECT_MANAGEMENT, String.format("/custom/func/list/%s/%s", goPage, pageSize), request);
|
||||
|
|
|
@ -268,7 +268,10 @@ export default {
|
|||
? this.contentObject.content.value
|
||||
: this.contentObject.content.defaultValue;
|
||||
if(!tempValue || Array.isArray(tempValue) && tempValue.length <= 0){
|
||||
let customVal = this.model[this.contentObject.content.name];
|
||||
let customVal;
|
||||
if (this.model) {
|
||||
customVal = this.model[this.contentObject.content.name];
|
||||
}
|
||||
if (customVal) {
|
||||
this.isCustomNone = false;
|
||||
tempValue = customVal;
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
import ApiModuleHeader from "metersphere-frontend/src/components/environment/snippet/ext/module/ApiModuleHeader";
|
||||
import {buildTree} from "metersphere-frontend/src//model/NodeTree";
|
||||
import {getCurrentProjectID} from "metersphere-frontend/src/utils/token";
|
||||
import {getModuleByUrl, getUserDefaultApiType} from "metersphere-frontend/src/api/environment";
|
||||
import {getModuleByUrl, getUserDefaultApiType, getCaseRelateModuleByCondition} from "metersphere-frontend/src/api/environment";
|
||||
|
||||
export default {
|
||||
name: 'MsApiModule',
|
||||
|
@ -111,7 +111,8 @@
|
|||
default() {
|
||||
return OPTIONS;
|
||||
}
|
||||
}
|
||||
},
|
||||
caseCondition: Object
|
||||
},
|
||||
computed: {
|
||||
isPlanModel() {
|
||||
|
@ -212,22 +213,18 @@
|
|||
},
|
||||
list(projectId) {
|
||||
let url = undefined;
|
||||
if (this.isPlanModel) {
|
||||
url = '/api/module/list/plan/' + this.planId + '/' + this.condition.protocol;
|
||||
} else if (this.isRelevanceModel) {
|
||||
url = "/api/module/list/" + this.relevanceProjectId + "/" + this.condition.protocol +
|
||||
(this.currentVersion ? '/' + this.currentVersion : '');
|
||||
} else if (this.isTrashData) {
|
||||
url = "/api/module/trash/list/" + (projectId ? projectId : this.projectId) + "/" + this.condition.protocol +
|
||||
if (this.isRelevanceModel) {
|
||||
url = "/api/module/relevance/list/" + this.relevanceProjectId + "/" + this.condition.protocol +
|
||||
(this.currentVersion ? '/' + this.currentVersion : '');
|
||||
} else {
|
||||
url = "/api/module/list/" + (projectId ? projectId : this.projectId) + "/" + this.condition.protocol +
|
||||
url = "/api/module/relevance/list/" + (projectId ? projectId : this.projectId) + "/" + this.condition.protocol +
|
||||
(this.currentVersion ? '/' + this.currentVersion : '');
|
||||
if (!this.projectId) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.loading = getModuleByUrl(url).then(response => {
|
||||
|
||||
this.loading = getCaseRelateModuleByCondition(url, this.caseCondition).then(response => {
|
||||
if (response.data) {
|
||||
this.data = response.data;
|
||||
this.data.forEach(node => {
|
||||
|
@ -236,10 +233,7 @@
|
|||
});
|
||||
this.$emit('setModuleOptions', this.data);
|
||||
this.$emit('setNodeTree', this.data);
|
||||
this.$emit("nodeSelectEvent", null, []);
|
||||
if (this.$refs.nodeTree) {
|
||||
this.$refs.nodeTree.filter(this.condition.filterText);
|
||||
}
|
||||
this.setCurrentNode();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
@ -262,47 +256,14 @@
|
|||
} else {
|
||||
this.$emit("nodeSelectEvent", node, nodeIds, pNodes);
|
||||
}
|
||||
this.nohupReloadTree(node.data.id);
|
||||
this.setCurrentNode(node.data.id);
|
||||
},
|
||||
nohupReloadTree(selectNodeId) {
|
||||
let url = undefined;
|
||||
if (this.isPlanModel) {
|
||||
url = '/api/module/list/plan/' + this.planId + '/' + this.condition.protocol;
|
||||
} else if (this.isRelevanceModel) {
|
||||
url = "/api/module/list/" + this.relevanceProjectId + "/" + this.condition.protocol +
|
||||
(this.currentVersion ? '/' + this.currentVersion : '');
|
||||
} else if (this.isTrashData) {
|
||||
if (!this.projectId) {
|
||||
return;
|
||||
}
|
||||
url = "/api/module/trash/list/" + this.projectId + "/" + this.condition.protocol +
|
||||
(this.currentVersion ? '/' + this.currentVersion : '');
|
||||
setCurrentNode(selectNodeId) {
|
||||
if (selectNodeId) {
|
||||
this.$refs.nodeTree.justSetCurrentKey(selectNodeId);
|
||||
} else {
|
||||
if (!this.projectId) {
|
||||
return;
|
||||
}
|
||||
url = "/api/module/list/" + this.projectId + "/" + this.condition.protocol +
|
||||
(this.currentVersion ? '/' + this.currentVersion : '');
|
||||
this.$refs.nodeTree.justSetCurrentKey(this.currentModule.id);
|
||||
}
|
||||
getModuleByUrl(url).then(response => {
|
||||
if (response.data) {
|
||||
let treeData = response.data;
|
||||
treeData.forEach(node => {
|
||||
node.name = node.name === '未规划接口' ? this.$t('api_test.definition.unplanned_api') : node.name
|
||||
buildTree(node, {path: ''});
|
||||
});
|
||||
this.data = treeData;
|
||||
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.nodeTree) {
|
||||
this.$refs.nodeTree.filter(this.condition.filterText);
|
||||
if (selectNodeId) {
|
||||
this.$refs.nodeTree.justSetCurrentKey(selectNodeId);
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
//创建根目录的模块---供父类使用
|
||||
createRootModel() {
|
||||
|
|
|
@ -9,12 +9,12 @@
|
|||
<template v-slot:aside>
|
||||
<ms-api-module
|
||||
:relevance-project-id="projectId"
|
||||
:show-case-num="false"
|
||||
@nodeSelectEvent="nodeChange"
|
||||
@protocolChange="handleProtocolChange"
|
||||
@refreshTable="refresh"
|
||||
@setModuleOptions="setModuleOptions"
|
||||
:is-read-only="true"
|
||||
:case-condition="condition"
|
||||
ref="nodeTree"
|
||||
/>
|
||||
</template>
|
||||
|
@ -26,6 +26,7 @@
|
|||
:not-in-ids="notInIds"
|
||||
:versionEnable="versionEnable"
|
||||
@selectCountChange="setSelectCounts"
|
||||
@setCondition="setCondition"
|
||||
ref="apiCaseList"
|
||||
/>
|
||||
</test-case-relevance-base>
|
||||
|
@ -73,7 +74,6 @@ export default {
|
|||
}
|
||||
},
|
||||
open() {
|
||||
this.init();
|
||||
this.$refs.baseRelevance.open();
|
||||
if (this.$refs.apiCaseList) {
|
||||
this.$refs.apiCaseList.clear();
|
||||
|
@ -113,6 +113,10 @@ export default {
|
|||
setSelectCounts(data) {
|
||||
this.$refs.baseRelevance.selectCounts = data;
|
||||
},
|
||||
setCondition(data) {
|
||||
this.condition = data;
|
||||
this.$refs.nodeTree.list(this.projectId);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -173,6 +173,7 @@ export default {
|
|||
},
|
||||
},
|
||||
created: function () {
|
||||
this.$emit('setCondition', this.condition);
|
||||
this.initTable();
|
||||
this.getVersionOptions();
|
||||
},
|
||||
|
@ -186,8 +187,8 @@ export default {
|
|||
projectId() {
|
||||
this.condition.versionId = null;
|
||||
this.getVersionOptions();
|
||||
this.initTable();
|
||||
},
|
||||
this.initTable(this.projectId);
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
selectRows() {
|
||||
|
@ -218,6 +219,7 @@ export default {
|
|||
this.condition.protocol = this.currentProtocol;
|
||||
}
|
||||
this.condition.notInIds = this.notInIds; // 查询排除哪些用例
|
||||
this.$emit('setCondition', this.condition);
|
||||
getTestCaseRelevanceApiList(
|
||||
this.currentPage,
|
||||
this.pageSize,
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
<template v-slot:aside>
|
||||
<ms-api-scenario-module
|
||||
:relevance-project-id="projectId"
|
||||
:show-case-num="false"
|
||||
@nodeSelectEvent="nodeChange"
|
||||
@refreshTable="refresh"
|
||||
@setModuleOptions="setModuleOptions"
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
<template v-slot:aside>
|
||||
<ui-scenario-module
|
||||
:relevance-project-id="projectId"
|
||||
:show-case-num="false"
|
||||
@nodeSelectEvent="nodeChange"
|
||||
@refreshTable="refresh"
|
||||
@setModuleOptions="setModuleOptions"
|
||||
|
|
|
@ -70,7 +70,6 @@
|
|||
<select-menu
|
||||
:data="projects"
|
||||
v-if="multipleProject"
|
||||
width="155px"
|
||||
:current-data="currentProject"
|
||||
:title="$t('case.project') + ':'"
|
||||
@dataChange="changeProject"
|
||||
|
|
|
@ -73,16 +73,14 @@ export default {
|
|||
}
|
||||
.select-menu :deep(.el-input__inner) {
|
||||
border: none;
|
||||
padding-left: 0px !important;
|
||||
padding-left: 0 !important;
|
||||
display: inline-block !important;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
width: px2rem(80);
|
||||
}
|
||||
.select-menu :deep(.el-select--small) {
|
||||
width: px2rem(80) !important;
|
||||
max-width: px2rem(200);
|
||||
}
|
||||
|
||||
.select-menu :deep(.el-input__suffix-inner .el-select__caret::before) {
|
||||
color: #646a73;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue