fix(测试计划): 关联用例列表执行人支持过滤筛选

--bug=1044867 --user=宋昌昌 【测试计划】计划详情-功能用例/接口用例/场景用例列表-执行人不支持筛选 https://www.tapd.cn/55049933/s/1559945
This commit is contained in:
song-cc-rock 2024-08-08 15:06:42 +08:00 committed by 刘瑞斌
parent 336a3ee47c
commit 4e1d8064c7
6 changed files with 216 additions and 112 deletions

View File

@ -3,7 +3,7 @@
<mapper namespace="io.metersphere.plan.mapper.ExtTestPlanApiCaseMapper">
<resultMap id="ApiDefinitionDTO" type="io.metersphere.api.dto.definition.ApiDefinitionDTO">
<result column="tags" jdbcType="VARCHAR" property="tags" typeHandler="io.metersphere.handler.ListTypeHandler" />
<result column="tags" jdbcType="VARCHAR" property="tags" typeHandler="io.metersphere.handler.ListTypeHandler"/>
</resultMap>
<update id="updatePos">
@ -140,7 +140,8 @@
</include>
<choose>
<when test='request.searchMode == "AND"'>
AND <include refid="queryCombine"/>
AND
<include refid="queryCombine"/>
</when>
<when test='request.searchMode == "OR"'>
and (
@ -180,14 +181,16 @@
</when>
<when test="key.startsWith('custom_single')">
and api_definition.id in (
select api_id from api_definition_custom_field where concat('custom_single_', field_id) = #{key}
select api_id from api_definition_custom_field where concat('custom_single_', field_id) =
#{key}
and trim(both '"' from `value`) in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
)
</when>
<when test="key.startsWith('custom_multiple')">
and api_definition.id in (
select api_id from api_definition_custom_field where concat('custom_multiple_', field_id) = #{key}
select api_id from api_definition_custom_field where concat('custom_multiple_', field_id) =
#{key}
and JSON_CONTAINS(`value`, json_array(#{value}))
)
</when>
@ -545,6 +548,11 @@
(#{value})
</foreach>
</when>
<!-- 执行人 -->
<when test="key == 'executeUserName'">
and t.execute_user in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
</when>
</choose>
</if>
</foreach>
@ -562,7 +570,8 @@
</sql>
<select id="countModuleIdByRequest" resultType="io.metersphere.functional.dto.FunctionalCaseModuleCountDTO">
SELECT CASE WHEN a.module_id = 'root' THEN CONCAT(atc.project_id, '_', a.module_id) ELSE a.module_id END AS moduleId,
SELECT CASE WHEN a.module_id = 'root' THEN CONCAT(atc.project_id, '_', a.module_id) ELSE a.module_id END AS
moduleId,
count(atc.id) AS dataCount, atc.project_id AS projectId, project.name AS projectName
FROM test_plan_api_case t
INNER JOIN api_test_case atc ON t.api_case_id = atc.id
@ -577,9 +586,13 @@
<select id="selectIdByProjectIdAndTestPlanId" resultType="java.lang.String">
SELECT adm.id, adm.project_id
FROM api_definition_module adm
WHERE adm.id IN (
SELECT ad.module_id FROM api_definition ad LEFT JOIN api_test_case atc on atc.api_definition_id = ad.id LEFT JOIN test_plan_api_case tpac ON tpac.api_case_id = atc.id WHERE tpac.test_plan_id = #{testPlanId} AND atc.deleted = false and atc.project_id = #{projectId}
)
WHERE adm.id IN (SELECT ad.module_id
FROM api_definition ad
LEFT JOIN api_test_case atc on atc.api_definition_id = ad.id
LEFT JOIN test_plan_api_case tpac ON tpac.api_case_id = atc.id
WHERE tpac.test_plan_id = #{testPlanId}
AND atc.deleted = false
and atc.project_id = #{projectId})
</select>
<select id="caseCount"
@ -609,7 +622,12 @@
FROM api_definition_module adm
LEFT JOIN project p ON adm.project_id = p.id
WHERE adm.id IN
(SELECT ad.module_id FROM api_definition ad LEFT JOIN api_test_case atc on atc.api_definition_id = ad.id LEFT JOIN test_plan_api_case tpac ON tpac.api_case_id = atc.id WHERE tpac.test_plan_id = #{testPlanId} AND atc.deleted = false)
(SELECT ad.module_id
FROM api_definition ad
LEFT JOIN api_test_case atc on atc.api_definition_id = ad.id
LEFT JOIN test_plan_api_case tpac ON tpac.api_case_id = atc.id
WHERE tpac.test_plan_id = #{testPlanId}
AND atc.deleted = false)
ORDER BY pos
</select>

View File

@ -199,6 +199,11 @@
and api_scenario.delete_user in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
</when>
<!-- 执行人 -->
<when test="key == 'executeUserName'">
and test_plan_api_scenario.execute_user in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
</when>
<when test="key=='versionId'">
and api_scenario.version_id in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
@ -333,7 +338,8 @@
<select id="countModuleIdByRequest" resultType="io.metersphere.functional.dto.FunctionalCaseModuleCountDTO">
SELECT CASE WHEN api_scenario.module_id = 'root' THEN CONCAT(api_scenario.project_id, '_', api_scenario.module_id) ELSE api_scenario.module_id END AS moduleId,
SELECT CASE WHEN api_scenario.module_id = 'root' THEN CONCAT(api_scenario.project_id, '_',
api_scenario.module_id) ELSE api_scenario.module_id END AS moduleId,
count(api_scenario.id) AS dataCount, api_scenario.project_id AS projectId, project.name AS projectName
FROM test_plan_api_scenario
INNER JOIN api_scenario on api_scenario.id = test_plan_api_scenario.api_scenario_id
@ -357,9 +363,13 @@
<select id="selectIdByProjectIdAndTestPlanId" resultType="java.lang.String">
SELECT asm.id, asm.project_id
FROM api_scenario_module asm
WHERE asm.id IN (
SELECT api_scenario.module_id FROM api_scenario LEFT JOIN test_plan_api_scenario on api_scenario.id = test_plan_api_scenario.api_scenario_id WHERE test_plan_api_scenario.test_plan_id = #{testPlanId} AND api_scenario.deleted = false and api_scenario.project_id = #{projectId}
)
WHERE asm.id IN (SELECT api_scenario.module_id
FROM api_scenario
LEFT JOIN test_plan_api_scenario
on api_scenario.id = test_plan_api_scenario.api_scenario_id
WHERE test_plan_api_scenario.test_plan_id = #{testPlanId}
AND api_scenario.deleted = false
and api_scenario.project_id = #{projectId})
</select>
<select id="collectionCountByRequest" resultType="io.metersphere.project.dto.ModuleCountDTO">
@ -392,7 +402,11 @@
FROM api_scenario_module asm
LEFT JOIN project p ON asm.project_id = p.id
WHERE asm.id IN
(SELECT api_scenario.module_id FROM api_scenario LEFT JOIN test_plan_api_scenario ON api_scenario.id = test_plan_api_scenario.api_scenario_id WHERE test_plan_api_scenario.test_plan_id = #{testPlanId} AND api_scenario.deleted = false)
(SELECT api_scenario.module_id
FROM api_scenario
LEFT JOIN test_plan_api_scenario ON api_scenario.id = test_plan_api_scenario.api_scenario_id
WHERE test_plan_api_scenario.test_plan_id = #{testPlanId}
AND api_scenario.deleted = false)
ORDER BY pos
</select>
@ -442,8 +456,10 @@
<include refid="queryWhereConditionByBatchQueryRequest"/>
</select>
<select id="getIdsByReportIdAndCollectionId" resultType="java.lang.String">
select id from test_plan_report_api_scenario
where test_plan_report_id = #{testPlanReportId} and test_plan_collection_id = #{collectionId}
select id
from test_plan_report_api_scenario
where test_plan_report_id = #{testPlanReportId}
and test_plan_collection_id = #{collectionId}
order by pos desc
</select>
<sql id="queryWhereConditionByBatchQueryRequest">
@ -475,7 +491,8 @@
</if>
</sql>
<select id="getPlanScenarioCaseNotDeletedByCollectionIds" resultType="io.metersphere.plan.domain.TestPlanApiScenario">
<select id="getPlanScenarioCaseNotDeletedByCollectionIds"
resultType="io.metersphere.plan.domain.TestPlanApiScenario">
SELECT t.*
FROM test_plan_api_scenario t
INNER JOIN api_scenario a ON t.api_scenario_id = a.id

View File

@ -163,7 +163,8 @@
</include>
<choose>
<when test='request.searchMode == "AND"'>
AND <include refid="queryCombine"/>
AND
<include refid="queryCombine"/>
</when>
<when test='request.searchMode == "OR"'>
and (
@ -198,7 +199,8 @@
</include>
<choose>
<when test='request.condition.searchMode == "AND"'>
AND <include refid="batchQueryCombine"/>
AND
<include refid="batchQueryCombine"/>
</when>
<when test='request.condition.searchMode == "OR"'>
and (
@ -240,7 +242,8 @@
<!-- 自定义多选 -->
<when test="key.startsWith('custom_multiple')">
and functional_case.id in (
select field_id from functional_case_custom_field where concat('custom_multiple-',field_id) =
select field_id from functional_case_custom_field where concat('custom_multiple-',field_id)
=
#{key}
and JSON_CONTAINS(`value`, json_array(#{value}))
</when>
@ -266,6 +269,10 @@
and functional_case.delete_user in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
</when>
<when test="key == 'executeUserName'">
and test_plan_functional_case.execute_user in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
</when>
</choose>
</if>
</foreach>
@ -470,12 +477,17 @@
FROM functional_case_module fcm
LEFT JOIN project p ON fcm.project_id = p.id
WHERE fcm.id IN
(SELECT fc.module_id FROM functional_case fc LEFT JOIN test_plan_functional_case tpfc ON tpfc.functional_case_id = fc.id WHERE tpfc.test_plan_id = #{testPlanId} AND fc.deleted = false)
(SELECT fc.module_id
FROM functional_case fc
LEFT JOIN test_plan_functional_case tpfc ON tpfc.functional_case_id = fc.id
WHERE tpfc.test_plan_id = #{testPlanId}
AND fc.deleted = false)
ORDER BY pos
</select>
<select id="countModuleIdByRequest" resultType="io.metersphere.functional.dto.FunctionalCaseModuleCountDTO">
SELECT CASE WHEN functional_case.module_id = 'root' THEN concat(functional_case.project_id, '_', functional_case.module_id) ElSE functional_case.module_id END AS moduleId,
SELECT CASE WHEN functional_case.module_id = 'root' THEN concat(functional_case.project_id, '_',
functional_case.module_id) ElSE functional_case.module_id END AS moduleId,
count(functional_case.id) As dataCount, functional_case.project_id As projectId, project.name As projectName
FROM test_plan_functional_case
LEFT JOIN functional_case ON test_plan_functional_case.functional_case_id = functional_case.id
@ -489,14 +501,16 @@
<select id="caseCount"
resultType="java.lang.Long">
SELECT count(functional_case.id)
FROM test_plan_functional_case LEFT JOIN functional_case ON test_plan_functional_case.functional_case_id = functional_case.id
FROM test_plan_functional_case LEFT JOIN functional_case ON test_plan_functional_case.functional_case_id =
functional_case.id
WHERE test_plan_functional_case.test_plan_id = #{request.testPlanId}
AND functional_case.deleted = #{deleted}
<include refid="queryWhereCondition"/>
</select>
<select id="getPlanFunctionalCaseByIds" resultType="io.metersphere.plan.domain.TestPlanFunctionalCase">
select tpfc.test_plan_id testPlanId, tpfc.functional_case_id functionalCaseId, tpfc.last_exec_result lastExecResult
select tpfc.test_plan_id testPlanId, tpfc.functional_case_id functionalCaseId, tpfc.last_exec_result
lastExecResult
from test_plan_functional_case tpfc join functional_case fc on fc.id = tpfc.functional_case_id
<where>
fc.deleted = false

View File

@ -136,6 +136,7 @@
import useModal from '@/hooks/useModal';
import useOpenNewPage from '@/hooks/useOpenNewPage';
import useTableStore from '@/hooks/useTableStore';
import useAppStore from '@/store/modules/app';
import { characterLimit } from '@/utils';
import { hasAllPermission, hasAnyPermission } from '@/utils/permission';
@ -144,7 +145,7 @@
import { ReportEnum } from '@/enums/reportEnum';
import { ApiTestRouteEnum } from '@/enums/routeEnum';
import { TableKeyEnum } from '@/enums/tableEnum';
import { FilterSlotNameEnum } from '@/enums/tableFilterEnum';
import { FilterRemoteMethodsEnum, FilterSlotNameEnum } from '@/enums/tableFilterEnum';
import { casePriorityOptions, lastReportStatusListOptions } from '@/views/api-test/components/config';
@ -171,6 +172,7 @@
const tableStore = useTableStore();
const { openModal } = useModal();
const { openNewPage } = useOpenNewPage();
const appStore = useAppStore();
const keyword = ref('');
const moduleNamePath = computed(() => {
@ -293,6 +295,14 @@
showTooltip: true,
width: 130,
showDrag: true,
filterConfig: {
mode: 'remote',
loadOptionParams: {
projectId: appStore.currentProjectId,
},
remoteMethod: FilterRemoteMethodsEnum.PROJECT_PERMISSION_MEMBER,
placeholderText: t('caseManagement.featureCase.PleaseSelect'),
},
},
{
title: hasOperationPermission.value ? 'common.operation' : '',
@ -358,7 +368,9 @@
}
return moduleIds;
}
const collectionId = computed(() => (props.activeModule === 'all' ? '' : props.activeModule));
async function getTableParams(isBatch: boolean) {
const selectModules = await getModuleIds();
const commonParams = {
@ -413,6 +425,7 @@
});
}
}
watch([() => props.activeModule, () => props.selectedProtocols], () => {
loadCaseList();
});
@ -429,6 +442,7 @@
//
const reportVisible = ref(false);
const reportId = ref('');
function showReport(record: PlanDetailApiCaseItem) {
if (!record.lastExecReportId) return;
reportVisible.value = true;
@ -443,6 +457,7 @@
condition: {},
currentSelectCount: 0,
});
function handleTableSelect(arr: (string | number)[]) {
tableSelected.value = arr;
}
@ -472,6 +487,7 @@
//
const disassociateLoading = ref(false);
async function handleDisassociateCase(record: PlanDetailApiCaseItem, done?: () => void) {
try {
disassociateLoading.value = true;

View File

@ -134,6 +134,7 @@
import useModal from '@/hooks/useModal';
import useOpenNewPage from '@/hooks/useOpenNewPage';
import useTableStore from '@/hooks/useTableStore';
import useAppStore from '@/store/modules/app';
import { characterLimit } from '@/utils';
import { hasAllPermission, hasAnyPermission } from '@/utils/permission';
@ -142,7 +143,7 @@
import { ReportEnum } from '@/enums/reportEnum';
import { ApiTestRouteEnum } from '@/enums/routeEnum';
import { TableKeyEnum } from '@/enums/tableEnum';
import { FilterSlotNameEnum } from '@/enums/tableFilterEnum';
import { FilterRemoteMethodsEnum, FilterSlotNameEnum } from '@/enums/tableFilterEnum';
import { casePriorityOptions, lastReportStatusListOptions } from '@/views/api-test/components/config';
@ -168,6 +169,7 @@
const tableStore = useTableStore();
const { openModal } = useModal();
const { openNewPage } = useOpenNewPage();
const appStore = useAppStore();
const keyword = ref('');
const moduleNamePath = computed(() => {
@ -275,6 +277,14 @@
showTooltip: true,
width: 130,
showDrag: true,
filterConfig: {
mode: 'remote',
loadOptionParams: {
projectId: appStore.currentProjectId,
},
remoteMethod: FilterRemoteMethodsEnum.PROJECT_PERMISSION_MEMBER,
placeholderText: t('caseManagement.featureCase.PleaseSelect'),
},
},
{
title: hasOperationPermission.value ? 'common.operation' : '',
@ -340,7 +350,9 @@
}
return moduleIds;
}
const collectionId = computed(() => (props.activeModule === 'all' ? '' : props.activeModule));
async function getTableParams(isBatch: boolean) {
const selectModules = await getModuleIds();
const commonParams = {
@ -394,6 +406,7 @@
});
}
}
watch(
() => props.activeModule,
() => {
@ -413,6 +426,7 @@
//
const reportVisible = ref(false);
const reportId = ref('');
function showReport(record: PlanDetailApiScenarioItem) {
if (!record.lastExecReportId) return;
reportVisible.value = true;
@ -427,6 +441,7 @@
condition: {},
currentSelectCount: 0,
});
function handleTableSelect(arr: (string | number)[]) {
tableSelected.value = arr;
}
@ -456,6 +471,7 @@
//
const disassociateLoading = ref(false);
async function handleDisassociateCase(record: PlanDetailApiScenarioItem, done?: () => void) {
try {
disassociateLoading.value = true;

View File

@ -216,7 +216,7 @@
import { LastExecuteResults } from '@/enums/caseEnum';
import { TestPlanRouteEnum } from '@/enums/routeEnum';
import { TableKeyEnum } from '@/enums/tableEnum';
import { FilterSlotNameEnum } from '@/enums/tableFilterEnum';
import { FilterRemoteMethodsEnum, FilterSlotNameEnum } from '@/enums/tableFilterEnum';
import { casePriorityOptions } from '@/views/api-test/components/config';
import { executionResultMap, getCaseLevels } from '@/views/case-management/caseManagementFeature/components/utils';
@ -245,6 +245,7 @@
const testPlanFeatureCaseStore = useTestPlanFeatureCaseStore();
const moduleTree = computed(() => unref(testPlanFeatureCaseStore.moduleTree));
async function initModules() {
await testPlanFeatureCaseStore.initModules(route.query.id as string, props.treeType);
}
@ -350,6 +351,14 @@
showTooltip: true,
width: 150,
showDrag: true,
filterConfig: {
mode: 'remote',
loadOptionParams: {
projectId: appStore.currentProjectId,
},
remoteMethod: FilterRemoteMethodsEnum.PROJECT_PERMISSION_MEMBER,
placeholderText: t('caseManagement.featureCase.PleaseSelect'),
},
},
{
title: hasOperationPermission.value ? 'common.operation' : '',
@ -426,7 +435,9 @@
}
return moduleIds;
}
const collectionId = computed(() => (props.activeModule === 'all' ? '' : props.activeModule));
async function getTableParams(isBatch: boolean) {
const selectModules = await getModuleIds();
const commonParams = {
@ -490,6 +501,7 @@
});
}
}
watch(
() => props.activeModule,
() => {
@ -504,6 +516,7 @@
});
const modulesCount = computed(() => testPlanFeatureCaseStore.modulesCount);
async function getModuleCount() {
let params;
const tableParams = await getTableParams(false);
@ -524,6 +537,7 @@
* @param getCount 获取模块树数量
*/
const msTestPlanFeatureCaseMinderRef = ref<InstanceType<typeof MsTestPlanFeatureCaseMinder>>();
async function refresh(getCount = true) {
if (showType.value === 'list') {
loadCaseList(getCount);
@ -565,6 +579,7 @@
condition: {},
currentSelectCount: 0,
});
function handleTableSelect(arr: (string | number)[]) {
tableSelected.value = arr;
}
@ -614,6 +629,7 @@
//
const disassociateLoading = ref(false);
async function handleDisassociateCase(record: PlanDetailFeatureCaseItem, done?: () => void) {
try {
disassociateLoading.value = true;
@ -679,6 +695,7 @@
const batchLoading = ref(false);
const batchExecuteModalVisible = ref(false);
const batchExecuteForm = ref<ExecuteFeatureCaseFormParams>({ ...defaultExecuteForm });
async function handleBatchExecute() {
try {
batchLoading.value = true;
@ -729,6 +746,7 @@
break;
}
}
//
function handleMinderOperation(type: string, node: MinderJsonNode) {
minderSelectData.value = node.data;
@ -782,19 +800,24 @@
:deep(.param-input:not(.arco-input-focus, .arco-select-view-focus)) {
&:not(:hover) {
border-color: transparent !important;
.arco-input::placeholder {
@apply invisible;
}
.arco-select-view-icon {
@apply invisible;
}
.arco-select-view-value {
color: var(--color-text-brand);
}
}
}
.list-show-type {
padding: 0;
:deep(.arco-radio-button-content) {
padding: 4px 6px;
}