feat(测试计划): 计划详情页&&用例弹窗支持高级筛选

--story=1015917 --user=宋昌昌 【通用】高级搜索与自定义视图 https://www.tapd.cn/55049933/s/1589897
This commit is contained in:
song-cc-rock 2024-10-10 11:50:27 +08:00 committed by Craftsman
parent fe08cc90ba
commit 7a9a2d74f2
14 changed files with 501 additions and 654 deletions

View File

@ -180,7 +180,7 @@
<if test="condition.name == 'createUser'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="api_definition_mock.create_user"/>
<property name="column" value="m.create_user"/>
</include>
</if>
<include refid="io.metersphere.system.mapper.BaseMapper.queryType">

View File

@ -333,7 +333,7 @@
</include>
</if>
<!-- 执行结果 -->
<if test="condition.name == 'lastReportStatus'">
<if test="condition.name == 'lastExecuteResult'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="api_scenario.last_report_status"/>
@ -346,13 +346,6 @@
<property name="column" value="api_scenario.step_total"/>
</include>
</if>
<!-- 步骤数 -->
<if test="condition.name == 'stepTotal'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="api_scenario.step_total"/>
</include>
</if>
<!-- 通过率 -->
<if test="condition.name == 'passRate'">
<choose>

View File

@ -587,12 +587,12 @@
<if test="condition.name == 'createUser'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="api_test_case.create_user"/>
<property name="column" value="atc.create_user"/>
</include>
</if>
<if test="condition.name == 'follower'">
<include refid="io.metersphere.system.mapper.BaseMapper.associationCondition">
<property name="mainIdColumn" value="api_test_case.id"/>
<property name="mainIdColumn" value="atc.id"/>
<property name="associationTable" value="api_test_case_follower"/>
<property name="associationIdColumn" value="case_id"/>
<property name="searchColumn" value="user_id"/>
@ -677,7 +677,7 @@
</include>
</if>
<!-- 执行结果 -->
<if test="condition.name == 'lastReportStatus'">
<if test="condition.name == 'lastExecuteResult'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="atc.last_report_status"/>

View File

@ -231,12 +231,12 @@
<if test="condition.name == 'createUser'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="bug.create_user"/>
<property name="column" value="b.create_user"/>
</include>
</if>
<if test="condition.name == 'follower'">
<include refid="io.metersphere.system.mapper.BaseMapper.associationCondition">
<property name="mainIdColumn" value="bug.id"/>
<property name="mainIdColumn" value="b.id"/>
<property name="associationTable" value="bug_follower"/>
<property name="associationIdColumn" value="bug_id"/>
<property name="searchColumn" value="user_id"/>
@ -340,12 +340,6 @@
or b.tags like concat('%', #{request.keyword},'%')
)
</if>
<include refid="filter"/>
<include refid="combine">
<property name="combineSearch" value="request.combineSearch"/>
<property name="projectId" value="${request.projectId}"/>
<property name="deleted" value="${request.useTrash}"/>
</include>
</sql>
</mapper>

View File

@ -310,18 +310,21 @@
<property name="condition" value="condition"/>
<property name="tablePrefix" value="functional_case"/>
</include>
<!-- 评审结果 -->
<if test="condition.name == 'reviewStatus'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="functional_case.review_status"/>
</include>
</if>
<!-- 执行结果 -->
<if test="condition.name == 'lastExecuteResult'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="functional_case.last_execute_result"/>
</include>
</if>
<!-- 关联需求 -->
<if test="condition.name == 'demand'">
<include refid="io.metersphere.system.mapper.BaseMapper.associationCondition">
<property name="mainIdColumn" value="functional_case.id"/>
@ -331,6 +334,7 @@
<property name="condition" value="condition"/>
</include>
</if>
<!-- 关联附件 -->
<if test="condition.name == 'attachment'">
<include refid="io.metersphere.system.mapper.BaseMapper.associationCondition">
<property name="mainIdColumn" value="functional_case.id"/>

View File

@ -28,7 +28,29 @@ public enum UserViewType implements ValueEnum {
API_SCENARIO("api-scenario",
List.of(InternalUserView.ALL_DATA, InternalUserView.MY_FOLLOW, InternalUserView.MY_CREATE)),
BUG("bug",
List.of(InternalUserView.ALL_DATA, InternalUserView.MY_FOLLOW, InternalUserView.MY_CREATE));
List.of(InternalUserView.ALL_DATA, InternalUserView.MY_FOLLOW, InternalUserView.MY_CREATE)),
/**
* 计划详情用例&&缺陷列表
*/
PLAN_FUNCTIONAL_CASE("plan-functional-case",
List.of(InternalUserView.ALL_DATA, InternalUserView.MY_CREATE)),
PLAN_API_CASE("plan-api-case",
List.of(InternalUserView.ALL_DATA, InternalUserView.MY_CREATE)),
PLAN_API_SCENARIO("plan-api-scenario",
List.of(InternalUserView.ALL_DATA, InternalUserView.MY_CREATE)),
PLAN_BUG("plan-bug",
List.of(InternalUserView.ALL_DATA, InternalUserView.MY_CREATE)),
/**
* 计划关联用例&&缺陷弹窗
*/
PLAN_FUNCTIONAL_CASE_DRAWER("plan-functional-case-drawer",
List.of(InternalUserView.ALL_DATA, InternalUserView.MY_CREATE)),
PLAN_API_CASE_DRAWER("plan-api-case-drawer",
List.of(InternalUserView.ALL_DATA, InternalUserView.MY_CREATE)),
PLAN_API_SCENARIO_DRAWER("plan-api-scenario-drawer",
List.of(InternalUserView.ALL_DATA, InternalUserView.MY_CREATE)),
PLAN_BUG_DRAWER("plan-bug--drawer",
List.of(InternalUserView.ALL_DATA, InternalUserView.MY_CREATE));
private String value;

View File

@ -16,6 +16,7 @@ import io.metersphere.plan.dto.response.TestPlanApiCasePageResponse;
import io.metersphere.project.dto.DropNode;
import io.metersphere.project.dto.ModuleCountDTO;
import io.metersphere.project.dto.NodeSortQueryParam;
import io.metersphere.system.interceptor.BaseConditionFilter;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@ -36,8 +37,10 @@ public interface ExtTestPlanApiCaseMapper {
List<TestPlanCaseRunResultCount> selectCaseExecResultCount(String testPlanId);
@BaseConditionFilter
List<ApiDefinitionDTO> list(@Param("request") TestPlanApiRequest request, @Param("isRepeat") boolean isRepeat);
@BaseConditionFilter
List<TestPlanApiCasePageResponse> relateApiCaseList(@Param("request") TestPlanApiCaseRequest request, @Param("deleted") boolean deleted);
List<FunctionalCaseModuleCountDTO> countModuleIdByRequest(@Param("request") TestPlanApiCaseRequest request, @Param("deleted") boolean deleted);
@ -52,6 +55,7 @@ public interface ExtTestPlanApiCaseMapper {
List<ApiCaseModuleDTO> selectBaseByProjectIdAndTestPlanId(@Param("testPlanId") String testPlanId);
@BaseConditionFilter
List<String> getIds(@Param("request") TestPlanApiCaseBatchRequest request, @Param("deleted") boolean deleted);
void batchUpdateExecutor(@Param("ids") List<String> ids, @Param("userId") String userId);

View File

@ -84,53 +84,49 @@
</select>
<select id="list" resultMap="ApiDefinitionDTO">
select
api_definition.id, api_definition.`name`, api_definition.protocol, api_definition.`method`,
api_definition.`path`, api_definition.`status`, api_definition.num, api_definition.tags, api_definition.pos,
api_definition.project_id, api_definition.module_id, api_definition.latest, api_definition.version_id,
api_definition.ref_id, api_definition.description, api_definition.create_time, api_definition.create_user,
api_definition.update_time, api_definition.update_user, api_definition.delete_user, api_definition.delete_time,
api_definition.deleted, project_version.name as version_name
from api_definition
LEFT JOIN project_version ON project_version.id = api_definition.version_id
where api_definition.deleted = false
select a.id, a.`name`, a.protocol, a.`method`, a.`path`, a.`status`, a.num, a.tags, a.pos,
a.project_id, a.module_id, a.latest, a.version_id, a.ref_id, a.description,
a.create_time, a.create_user, a.update_time, a.update_user, a.delete_user, a.delete_time, a.deleted,
project_version.name as version_name
from api_definition a left join project_version on project_version.id = a.version_id
where a.deleted = false
<include refid="queryWhereCondition"/>
and exists (
select id
from api_test_case c
where c.api_definition_id = api_definition.id and c.deleted = false
<if test="!isRepeat">
and not exists (
select id
from test_plan_api_case t
where t.api_case_id = c.id
and t.test_plan_id = #{request.testPlanId}
)
</if>
from api_test_case atc
where atc.api_definition_id = a.id and atc.deleted = false
<if test="!isRepeat">
and not exists (
select id
from test_plan_api_case t
where t.api_case_id = atc.id
and t.test_plan_id = #{request.testPlanId}
)
</if>
)
</select>
<sql id="queryWhereCondition">
<if test="request.moduleIds != null and request.moduleIds.size() > 0">
and api_definition.module_id in
and a.module_id in
<foreach collection="request.moduleIds" item="moduleId" separator="," open="(" close=")">
#{moduleId}
</foreach>
</if>
<if test="request.keyword != null and request.keyword != ''">
and (
api_definition.name like concat('%', #{request.keyword},'%')
or api_definition.num like concat('%', #{request.keyword},'%')
or api_definition.path like concat('%', #{request.keyword},'%')
or api_definition.tags like concat('%', #{request.keyword},'%')
a.name like concat('%', #{request.keyword},'%')
or a.num like concat('%', #{request.keyword},'%')
or a.path like concat('%', #{request.keyword},'%')
or a.tags like concat('%', #{request.keyword},'%')
)
</if>
<if test="request.projectId != null and request.projectId != ''">
and api_definition.project_id = #{request.projectId}
and a.project_id = #{request.projectId}
</if>
<if test="request.protocols != null and request.protocols.size() > 0">
AND api_definition.protocol in
and a.protocol in
<foreach collection="request.protocols" item="protocol" separator="," open="(" close=")">
#{protocol}
</foreach>
@ -138,19 +134,13 @@
<include refid="filters">
<property name="filter" value="request.filter"/>
</include>
<choose>
<when test='request.searchMode == "AND"'>
AND
<include refid="queryCombine"/>
</when>
<when test='request.searchMode == "OR"'>
and (
<include refid="queryCombine"/>
)
</when>
</choose>
<include refid="combine">
<property name="combineSearch" value="request.combineSearch"/>
</include>
<include refid="queryVersionCondition">
<property name="versionTable" value="api_definition"/>
<property name="versionTable" value="a"/>
</include>
</sql>
@ -200,195 +190,6 @@
</if>
</sql>
<sql id="queryCombine">
<if test="request.combine != null">
<include refid="combine">
<property name="condition" value="request.combine"/>
<property name="searchMode" value="request.searchMode"/>
</include>
</if>
1=1
</sql>
<sql id="combine">
<!-- 名称 -->
<if test='${condition}.name != null'>
api_definition.name
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.name"/>
</include>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!-- id -->
<if test='${condition}.id != null'>
api_definition.num
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.id"/>
</include>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!-- 所属模块 -->
<if test='${condition}.moduleId != null'>
api_definition.moduleId
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.moduleId"/>
</include>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!-- 创建人 -->
<if test='${condition}.createUser != null'>
api_definition.create_user
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.createUser"/>
</include>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!-- 创建时间 -->
<if test='${condition}.createTime != null'>
api_definition.create_time
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.createTime"/>
</include>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!-- 更新人 -->
<if test='${condition}.updateUser != null'>
api_definition.update_user
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.updateUser"/>
</include>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!-- 更新时间 -->
<if test='${condition}.updateTime != null'>
api_definition.update_time
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.updateTime"/>
</include>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!-- 状态 -->
<if test="${condition}.status != null">
api_definition.status
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.status"/>
</include>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!-- 路径 -->
<if test="${condition}.path != null">
api_definition.path
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.path"/>
</include>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!-- 方法 -->
<if test="${condition}.method != null">
api_definition.method
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.method"/>
</include>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!-- 标签 -->
<if test='${condition}.tags != null'>
<include refid="queryTag">
<property name="searchMode" value="${searchMode}"/>
<property name="combineTag" value="${condition}.tags"/>
</include>
</if>
<if test="${condition}.customs != null and ${condition}.customs.size() > 0">
<foreach collection="${condition}.customs" item="custom" separator="" open="" close="">
api_definition.id ${custom.operator} (
select api_id from api_definition_custom_field where field_id = #{custom.id}
<choose>
<when test="custom.type == 'List'">
and JSON_CONTAINS(`value`, json_array(#{custom.value}))
</when>
<when test="custom.type == 'date' or custom.type == 'datetime'">
and `value`
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="custom"/>
</include>
</when>
<otherwise>
and trim(both '"' from `value`)
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="custom"/>
</include>
</otherwise>
</choose>
)
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</foreach>
</if>
</sql>
<sql id="queryTag">
<!-- 不包含 -->
<if test='${combineTag}.value.size() > 0 and ${combineTag}.operator == "not like"'>
(
api_definition.tags is null or api_definition.tags = '[]' or
<foreach collection="${combineTag}.value" item="tag" separator="and" open="(" close=")">
!JSON_CONTAINS(api_definition.tags, JSON_ARRAY(#{tag}))
</foreach>
)
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!-- 包含 -->
<if test='${combineTag}.value.size() > 0 and ${combineTag}.operator == "like"'>
<foreach collection="${combineTag}.value" item="tag" separator="or" open="(" close=")">
JSON_CONTAINS(api_definition.tags, JSON_ARRAY(#{tag}))
</foreach>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!---->
<if test='${combineTag}.operator == "is null"'>
(api_definition.tags is null or api_definition.tags = '[]')
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
</sql>
<sql id="queryType">
<choose>
<when test='${searchMode} == "AND"'>
AND
</when>
<when test='${searchMode} == "OR"'>
OR
</when>
</choose>
</sql>
<sql id="queryVersionCondition">
<choose>
<when test="request.versionId != null and request.versionId != ''">
@ -437,6 +238,7 @@
and t.test_plan_id = #{request.testPlanId}
<include refid="queryApiCaseWhereCondition"/>
</select>
<select id="selectByTestPlanIdAndNotDeleted" resultType="io.metersphere.plan.domain.TestPlanApiCase">
SELECT t.*
FROM test_plan_api_case t
@ -498,6 +300,11 @@
<property name="filter" value="request.filter"/>
<property name="nullExecutorKey" value="request.nullExecutorKey"/>
</include>
<include refid="combine">
<property name="combineSearch" value="request.combineSearch"/>
</include>
<include refid="queryApiCaseVersionCondition">
<property name="versionTable" value="atc"/>
</include>
@ -576,6 +383,116 @@
</if>
</sql>
<sql id="combine">
<trim prefix="AND">
<trim prefix="(" suffix=")" suffixOverrides="AND|OR">
<if test="${combineSearch} != null">
<foreach collection="${combineSearch}.userViewConditions" item="condition">
<if test="condition.name == 'createUser'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="atc.create_user"/>
</include>
</if>
<include refid="io.metersphere.system.mapper.BaseMapper.queryType">
<property name="searchMode" value="${combineSearch}.searchMode"/>
</include>
</foreach>
<foreach collection="${combineSearch}.systemFieldConditions" item="condition">
<include refid="io.metersphere.system.mapper.BaseMapper.commonSystemFieldConditions">
<property name="condition" value="condition"/>
<property name="tablePrefix" value="atc"/>
</include>
<!-- 协议 -->
<if test="condition.name == 'protocol'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="a.protocol"/>
</include>
</if>
<!-- 用例等级 -->
<if test="condition.name == 'priority'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="atc.priority"/>
</include>
</if>
<!-- 路径 -->
<if test="condition.name == 'path'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="a.path"/>
</include>
</if>
<!-- 状态 -->
<if test="condition.name == 'status'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="atc.status"/>
</include>
</if>
<!-- 用例通过率 -->
<if test="condition.name == 'passRate'">
<choose>
<when test="condition.operator == 'NOT_EMPTY'">
atc.id in (
select atcr.api_test_case_id as id
from api_report ar left join api_test_case_record atcr on atcr.api_report_id = ar.id
group by atcr.api_test_case_id
)
</when>
<when test="condition.operator == 'EMPTY'">
atc.id not in (
select atcr.api_test_case_id as id
from api_report ar left join api_test_case_record atcr on atcr.api_report_id = ar.id
group by atcr.api_test_case_id
)
</when>
<when test="(condition.operator == 'LT' and condition.value == 0) or (condition.operator == 'GT' and condition.value &gt; 100 )">
1=2
</when>
<otherwise>
atc.id in (
select atcr.api_test_case_id as id, format(sum(if(ar.`status` = 'success', 1, 0)) / count(ar.id) * 100, 2) as passRate
from api_report ar left join api_test_case_record atcr on atcr.api_report_id = ar.id
group by atcr.api_test_case_id having
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="passRate"/>
</include>
)
</otherwise>
</choose>
</if>
<!-- 用例环境 -->
<if test="condition.name == 'env'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="atc.environment_id"/>
</include>
</if>
<!-- 执行人 -->
<if test="condition.name == 'executeUser'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="t.execute_user"/>
</include>
</if>
<!-- 执行结果 -->
<if test="condition.name == 'lastExecuteResult'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="t.last_exec_result"/>
</include>
</if>
<include refid="io.metersphere.system.mapper.BaseMapper.queryType">
<property name="searchMode" value="${combineSearch}.searchMode"/>
</include>
</foreach>
</if>
</trim>
</trim>
</sql>
<sql id="queryApiCaseVersionCondition">
<if test="request.versionId != null and request.versionId != ''">
@ -689,6 +606,9 @@
<property name="filter" value="request.condition.filter"/>
<property name="nullExecutorKey" value="request.nullExecutorKey"/>
</include>
<include refid="combine">
<property name="combineSearch" value="request.condition.combineSearch"/>
</include>
</sql>
<update id="batchUpdateExecutor">

View File

@ -15,6 +15,7 @@ import io.metersphere.plan.dto.response.TestPlanApiScenarioPageResponse;
import io.metersphere.project.dto.DropNode;
import io.metersphere.project.dto.ModuleCountDTO;
import io.metersphere.project.dto.NodeSortQueryParam;
import io.metersphere.system.interceptor.BaseConditionFilter;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@ -37,6 +38,7 @@ public interface ExtTestPlanApiScenarioMapper {
List<TestPlanApiScenario> selectByTestPlanIdAndNotDeleted(String testPlanId);
@BaseConditionFilter
List<TestPlanApiScenarioPageResponse> relateApiScenarioList(@Param("request") TestPlanApiScenarioRequest request, @Param("deleted") boolean deleted);
List<FunctionalCaseModuleCountDTO> countModuleIdByRequest(@Param("request") TestPlanApiScenarioModuleRequest request, @Param("deleted") boolean deleted);
@ -61,6 +63,7 @@ public interface ExtTestPlanApiScenarioMapper {
List<TestPlanApiScenario> getScenarioExecuteInfoByIds(@Param("ids") List<String> ids);
@BaseConditionFilter
List<String> getIds(@Param("request") BasePlanCaseBatchRequest request, @Param("deleted") boolean deleted);
void batchUpdateExecutor(@Param("ids") List<String> ids, @Param("userId") String userId);

View File

@ -147,13 +147,9 @@
<property name="nullExecutorKey" value="request.nullExecutorKey"/>
</include>
<if test="request.combine != null and request.combine != ''">
<include refid="combine">
<property name="condition" value="request.combine"/>
<property name="name" value="request.name"/>
<property name="ObjectTags" value="request.combine.tags"/>
</include>
</if>
<include refid="combine">
<property name="combineSearch" value="request.combineSearch"/>
</include>
<include refid="queryVersionCondition">
<property name="versionTable" value="api_scenario"/>
@ -253,93 +249,91 @@
</sql>
<sql id="combine">
<if test='${condition}.name != null and (${name} == null or ${name} == "")'>
and api_scenario.name
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.name"/>
</include>
</if>
<if test='${condition}.id != null'>
and api_scenario.num
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.id"/>
</include>
</if>
<if test="${condition}.updateTime != null">
and api_scenario.update_time
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.updateTime"/>
</include>
</if>
<if test="${condition}.createTime != null">
and api_scenario.create_time
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.createTime"/>
</include>
</if>
<if test="${condition}.status != null">
and api_scenario.status
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.status"/>
</include>
</if>
<if test='${condition}.tags != null and ${ObjectTags}.operator == "not like"'>
and (api_scenario.tags is null or api_scenario.tags
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.tags"/>
</include>
)
</if>
<if test='${condition}.tags != null and ${ObjectTags}.operator == "like"'>
and api_scenario.tags
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.tags"/>
</include>
</if>
<if test="${condition}.customs != null and ${condition}.customs.size() > 0">
<foreach collection="${condition}.customs" item="custom" separator="" open="" close="">
<if test="custom.value != ''">
<if test='custom.operator == "not like" or custom.operator == "not in"'>
and api_scenario.id not in (
</if>
<if test='custom.operator != "not like" and custom.operator != "not in"'>
and api_scenario.id in (
</if>
select api_id from api_definition_custom_field where field_id = #{custom.id}
<choose>
<when test="custom.type == 'TEXTAREA' or custom.operator == 'current user'">
and `value`
<trim prefix="AND">
<trim prefix="(" suffix=")" suffixOverrides="AND|OR">
<if test="${combineSearch} != null">
<foreach collection="${combineSearch}.userViewConditions" item="condition">
<if test="condition.name == 'createUser'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="custom"/>
<property name="condition" value="condition"/>
<property name="column" value="api_scenario.create_user"/>
</include>
</when>
<when test="custom.type == 'MULTIPLE_MEMBER' or custom.type == 'CHECKBOX' or custom.type == 'MULTIPLE_SELECT'">
and ${custom.value}
</when>
<when test="custom.type == 'DATE' or custom.type == 'DATETIME'">
and left(replace(unix_timestamp(trim(both '"' from `value`)), '.', ''), 13)
</if>
<include refid="io.metersphere.system.mapper.BaseMapper.queryType">
<property name="searchMode" value="${combineSearch}.searchMode"/>
</include>
</foreach>
<foreach collection="${combineSearch}.systemFieldConditions" item="condition">
<include refid="io.metersphere.system.mapper.BaseMapper.commonSystemFieldConditions">
<property name="condition" value="condition"/>
<property name="tablePrefix" value="api_scenario"/>
</include>
<!-- 场景等级 -->
<if test="condition.name == 'priority'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="custom"/>
<property name="condition" value="condition"/>
<property name="column" value="api_scenario.priority"/>
</include>
</when>
<otherwise>
and trim(both '"' from `value`)
</if>
<!-- 状态 -->
<if test="condition.name == 'status'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="custom"/>
<property name="condition" value="condition"/>
<property name="column" value="api_scenario.status"/>
</include>
</otherwise>
</choose>
)
</if>
<!-- 执行人 -->
<if test="condition.name == 'executeUser'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="test_plan_api_scenario.execute_user"/>
</include>
</if>
<!-- 执行结果 -->
<if test="condition.name == 'lastExecuteResult'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="test_plan_api_scenario.last_exec_result"/>
</include>
</if>
<!-- 步骤数 -->
<if test="condition.name == 'stepTotal'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="api_scenario.step_total"/>
</include>
</if>
<!-- 通过率 -->
<if test="condition.name == 'passRate'">
<choose>
<when test="condition.operator == 'NOT_EMPTY'">
api_scenario.request_pass_rate is not null and api_scenario.request_pass_rate != '' and api_scenario.request_pass_rate != 'Calculating'
</when>
<when test="condition.operator == 'EMPTY'">
api_scenario.request_pass_rate is null or api_scenario.request_pass_rate == '' or api_scenario.request_pass_rate == 'Calculating'
</when>
<when test="(condition.operator == 'LT' and condition.value == 0) or (condition.operator == 'GT' and condition.value &gt; 100 )">
1=2
</when>
<otherwise>
api_scenario.request_pass_rate ${condition.operator} #{condition.value}
</otherwise>
</choose>
</if>
<!-- 环境 -->
<if test="condition.name == 'env'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="api_scenario.environment_id"/>
</include>
</if>
<include refid="io.metersphere.system.mapper.BaseMapper.queryType">
<property name="searchMode" value="${combineSearch}.searchMode"/>
</include>
</foreach>
</if>
</foreach>
</if>
</trim>
</trim>
</sql>
<sql id="queryVersionCondition">
@ -501,13 +495,9 @@
<property name="filter" value="request.condition.filter"/>
<property name="nullExecutorKey" value="request.nullExecutorKey"/>
</include>
<if test="request.condition.combine != null and request.condition.combine != ''">
<include refid="combine">
<property name="condition" value="request.condition.combine"/>
<property name="name" value="request.name"/>
<property name="ObjectTags" value="request.condition.combine.tags"/>
</include>
</if>
<include refid="combine">
<property name="combineSearch" value="request.condition.combineSearch"/>
</include>
</sql>
<select id="getPlanScenarioCaseNotDeletedByCollectionIds"

View File

@ -4,10 +4,14 @@ import io.metersphere.plan.dto.TestPlanBugCaseDTO;
import io.metersphere.plan.dto.TestPlanCaseBugDTO;
import io.metersphere.plan.dto.request.TestPlanBugPageRequest;
import io.metersphere.plan.dto.response.TestPlanBugPageResponse;
import io.metersphere.system.interceptor.BaseConditionFilter;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author song-cc-rock
*/
public interface ExtTestPlanBugMapper {
/**
@ -15,6 +19,7 @@ public interface ExtTestPlanBugMapper {
* @param request 请求参数
* @return 缺陷列表
*/
@BaseConditionFilter
List<TestPlanBugPageResponse> list(@Param("request") TestPlanBugPageRequest request);
/**

View File

@ -16,9 +16,9 @@
<property name="filter" value="request.filter"/>
</include>
<include refid="combine">
<property name="condition" value="request.combine"/>
<property name="searchMode" value="request.searchMode"/>
<property name="combineTag" value="request.combine.tag"/>
<property name="combineSearch" value="request.combineSearch"/>
<property name="projectId" value="${request.projectId}"/>
<property name="deleted" value="${request.useTrash}"/>
</include>
group by brc.bug_id
</select>
@ -102,180 +102,108 @@
</sql>
<sql id="combine">
<if test="request.combine != null">
and (
<!-- 任意/所有拼接 -->
<include refid="prefixMode">
<property name="searchMode" value="${searchMode}"/>
</include>
<!-- ID -->
<if test='${condition}.num != null'>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
b.num
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.num"/>
</include>
</if>
<!-- 名称 -->
<if test='${condition}.title != null'>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
b.title
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.title"/>
</include>
</if>
<!-- 所属平台 -->
<if test='${condition}.platform != null'>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
b.platform
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.platform"/>
</include>
</if>
<!-- 处理人 -->
<if test='${condition}.handleUser != null'>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
b.handle_user
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.handleUser"/>
</include>
</if>
<!-- 状态 -->
<if test='${condition}.status != null'>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
b.status
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.status"/>
</include>
</if>
<!-- 创建人 -->
<if test='${condition}.createUser != null'>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
b.create_user
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.createUser"/>
</include>
</if>
<!-- 创建时间 -->
<if test='${condition}.createTime != null'>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
b.create_time
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.createTime"/>
</include>
</if>
<!-- 标签 -->
<if test='${condition}.tags != null'>
<include refid="queryTag">
<property name="searchMode" value="${searchMode}"/>
<property name="combineTag" value="${condition}.tags"/>
</include>
</if>
<!-- 自定义字段 -->
<if test="${condition}.customs != null and ${condition}.customs.size() > 0">
<foreach collection="${condition}.customs" item="custom" separator="" open="" close="">
<if test="custom.value != ''">
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
<trim prefix="AND">
<trim prefix="(" suffix=")" suffixOverrides="AND|OR">
<if test="${combineSearch} != null">
<foreach collection="${combineSearch}.userViewConditions" item="condition">
<if test="condition.name == 'createUser'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="b.create_user"/>
</include>
</if>
<if test="condition.name == 'follower'">
<include refid="io.metersphere.system.mapper.BaseMapper.associationCondition">
<property name="mainIdColumn" value="b.id"/>
<property name="associationTable" value="bug_follower"/>
<property name="associationIdColumn" value="bug_id"/>
<property name="searchColumn" value="user_id"/>
<property name="condition" value="condition"/>
</include>
</if>
<include refid="io.metersphere.system.mapper.BaseMapper.queryType">
<property name="searchMode" value="${combineSearch}.searchMode"/>
</include>
<if test='custom.operator == "not like" or custom.operator == "not in"'>
b.id not in (
</foreach>
<foreach collection="${combineSearch}.systemFieldConditions" item="condition">
<include refid="io.metersphere.system.mapper.BaseMapper.commonSystemFieldConditions">
<property name="condition" value="condition"/>
<property name="tablePrefix" value="b"/>
</include>
<!-- 状态 -->
<if test="condition.name == 'status'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="b.status"/>
</include>
</if>
<if test='custom.operator != "not like" and custom.operator != "not in"'>
b.id in (
<!-- 处理人 -->
<if test="condition.name == 'handleUser'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="b.handle_user"/>
</include>
</if>
select bug_id from bug_custom_field where field_id = #{custom.id} and
<choose>
<when test="custom.type == 'array'">
<foreach collection="custom.value" item="val" separator="or" open="(" close=")">
JSON_CONTAINS(`value`, JSON_ARRAY(#{val}))
</foreach>
</when>
<when test="custom.type == 'time'">
left(replace(unix_timestamp(trim(both '"' from `value`)), '.', ''), 13)
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="custom"/>
</include>
</when>
<otherwise>
trim(both '"' from `value`)
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="custom"/>
</include>
</otherwise>
</choose>
)
</if>
</foreach>
</if>
)
</if>
</sql>
<sql id="prefixMode">
<choose>
<when test='${searchMode} == "AND"'>
1 = 1
</when>
<when test='${searchMode} == "OR"'>
1 = 2
</when>
</choose>
</sql>
<sql id="queryType">
<choose>
<when test='${searchMode} == "AND"'>
and
</when>
<when test='${searchMode} == "OR"'>
or
</when>
</choose>
</sql>
<sql id="queryTag">
<!-- 不包含 -->
<if test='${combineTag}.value.size() > 0 and ${combineTag}.operator == "not like"'>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
(
b.tags is null or b.tags = '[]' or
<foreach collection="${combineTag}.value" item="tag" separator="and" open="(" close=")">
!JSON_CONTAINS(b.tags, JSON_ARRAY(#{tag}))
</foreach>
)
</if>
<!-- 包含 -->
<if test='${combineTag}.value.size() > 0 and ${combineTag}.operator == "like"'>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
<foreach collection="${combineTag}.value" item="tag" separator="or" open="(" close=")">
JSON_CONTAINS(b.tags, JSON_ARRAY(#{tag}))
</foreach>
</if>
<!---->
<if test='${combineTag}.operator == "is null"'>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
(b.tags is null or b.tags = '[]')
</if>
<!-- 所属平台 -->
<if test="condition.name == 'platform'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="b.platform"/>
</include>
</if>
<!-- 用例数 -->
<if test="condition.name == 'caseTotal'">
<choose>
<when test="condition.operator == 'NOT_EMPTY'">
b.id in (
select distinct b.id from bug b join bug_relation_case brc on b.id = brc.bug_id
where deleted = ${deleted} and project_id = '${projectId}'
)
</when>
<when test="condition.operator == 'EMPTY'">
b.id not in (
select distinct b.id from bug b join bug_relation_case brc on b.id = brc.bug_id
where deleted = ${deleted} and project_id = '${projectId}'
)
</when>
<when test="(condition.operator == 'LT' and condition.value &lt; 1) or (condition.operator == 'EQUALS' and condition.value &lt; 0)">
1=2
</when>
<otherwise>
<if test="condition.operator == 'LT' or (condition.operator == 'EQUALS' and condition.value == 0)">
b.id not in (
select distinct b.id from bug b join bug_relation_case brc on b.id = brc.bug_id
where deleted = ${deleted} and project_id = '${projectId}'
)
<if test="condition.value &gt; 1">
OR
</if>
</if>
<if test="(condition.operator == 'EQUALS' and condition.value &gt; 0) or (condition.operator == 'LT' and condition.value &gt; 1) or condition.operator == 'GT'">
b.id in (
select distinct b.id from bug b join bug_relation_case brc on b.id = brc.bug_id
where deleted = ${deleted} and project_id = '${projectId}' group b.id having
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="count(b.id)"/>
</include>
)
</if>
</otherwise>
</choose>
</if>
<include refid="io.metersphere.system.mapper.BaseMapper.queryType">
<property name="searchMode" value="${combineSearch}.searchMode"/>
</include>
</foreach>
<include refid="io.metersphere.system.mapper.BaseMapper.customFiledConditions">
<property name="mainIdColumn" value="bug.id"/>
<property name="associationTable" value="bug_custom_field"/>
<property name="associationIdColumn" value="bug_id"/>
<property name="combineSearch" value="${combineSearch}"/>
</include>
</if>
</trim>
</trim>
</sql>
</mapper>

View File

@ -16,6 +16,7 @@ import io.metersphere.plan.dto.response.TestPlanCasePageResponse;
import io.metersphere.project.dto.DropNode;
import io.metersphere.project.dto.ModuleCountDTO;
import io.metersphere.project.dto.NodeSortQueryParam;
import io.metersphere.system.interceptor.BaseConditionFilter;
import org.apache.ibatis.annotations.Param;
import java.util.Collection;
@ -37,6 +38,7 @@ public interface ExtTestPlanFunctionalCaseMapper {
DropNode selectNodeByPosOperator(NodeSortQueryParam nodeSortQueryParam);
@BaseConditionFilter
List<TestPlanCasePageResponse> getCasePage(@Param("request") TestPlanCaseRequest request, @Param("deleted") boolean deleted, @Param("sort") String sort);
List<TestPlanFunctionalCase> selectByTestPlanIdAndNotDeleted(String testPlanId);
@ -49,6 +51,7 @@ public interface ExtTestPlanFunctionalCaseMapper {
long caseCount(@Param("request") TestPlanCaseRequest request, @Param("deleted") boolean deleted);
@BaseConditionFilter
List<String> getIds(@Param("request") BasePlanCaseBatchRequest request, @Param("deleted") boolean deleted);
/**

View File

@ -166,17 +166,9 @@
<property name="filter" value="request.filter"/>
<property name="nullExecutorKey" value="request.nullExecutorKey"/>
</include>
<choose>
<when test='request.searchMode == "AND"'>
AND
<include refid="queryCombine"/>
</when>
<when test='request.searchMode == "OR"'>
and (
<include refid="queryCombine"/>
)
</when>
</choose>
<include refid="combine">
<property name="combineSearch" value="request.combineSearch"/>
</include>
<include refid="queryVersionCondition">
<property name="versionTable" value="functional_case"/>
</include>
@ -210,17 +202,9 @@
<property name="filter" value="request.condition.filter"/>
<property name="nullExecutorKey" value="request.nullExecutorKey"/>
</include>
<choose>
<when test='request.condition.searchMode == "AND"'>
AND
<include refid="batchQueryCombine"/>
</when>
<when test='request.condition.searchMode == "OR"'>
and (
<include refid="batchQueryCombine"/>
)
</when>
</choose>
<include refid="combine">
<property name="combineSearch" value="request.condition.combineSearch"/>
</include>
</sql>
<sql id="filters">
@ -308,131 +292,128 @@
</if>
</sql>
<sql id="batchQueryCombine">
<if test="request.condition.combine != null">
<include refid="combine">
<property name="condition" value="request.condition.combine"/>
<property name="searchMode" value="request.condition.searchMode"/>
</include>
</if>
1=1
</sql>
<sql id="queryCombine">
<if test="request.combine != null">
<include refid="combine">
<property name="condition" value="request.combine"/>
<property name="searchMode" value="request.searchMode"/>
</include>
</if>
1=1
</sql>
<sql id="combine">
<!-- 名称 -->
<if test='${condition}.name != null'>
functional_case.name
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.name"/>
</include>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!-- id -->
<if test='${condition}.id != null'>
functional_case.num
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.id"/>
</include>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!-- 所属模块 -->
<if test='${condition}.moduleId != null'>
functional_case.moduleId
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.moduleId"/>
</include>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!-- 创建人 -->
<if test='${condition}.createUser != null'>
functional_case.create_user
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.createUser"/>
</include>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!-- 创建时间 -->
<if test='${condition}.createTime != null'>
functional_case.create_time
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.createTime"/>
</include>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!-- 更新人 -->
<if test='${condition}.updateUser != null'>
functional_case.update_user
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.updateUser"/>
</include>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!-- 更新时间 -->
<if test='${condition}.updateTime != null'>
functional_case.update_time
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.updateTime"/>
</include>
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</if>
<!-- 标签 -->
<if test='${condition}.tags != null'>
<include refid="queryTag">
<property name="searchMode" value="${searchMode}"/>
<property name="combineTag" value="${condition}.tags"/>
</include>
</if>
<if test="${condition}.customs != null and ${condition}.customs.size() > 0">
<foreach collection="${condition}.customs" item="custom" separator="" open="" close="">
functional_case.id ${custom.operator} (
select case_id from functional_case_custom_field where field_id = #{custom.id}
<trim prefix="AND">
<trim prefix="(" suffix=")" suffixOverrides="AND|OR">
<if test="${combineSearch} != null">
<foreach collection="${combineSearch}.userViewConditions" item="condition">
<if test="condition.name == 'createUser'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="functional_case.create_user"/>
</include>
</if>
<include refid="io.metersphere.system.mapper.BaseMapper.queryType">
<property name="searchMode" value="${combineSearch}.searchMode"/>
</include>
</foreach>
<foreach collection="${combineSearch}.systemFieldConditions" item="condition">
<include refid="io.metersphere.system.mapper.BaseMapper.commonSystemFieldConditions">
<property name="condition" value="condition"/>
<property name="tablePrefix" value="functional_case"/>
</include>
<!-- 评审结果 -->
<if test="condition.name == 'reviewStatus'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="functional_case.review_status"/>
</include>
</if>
<!-- 执行人 -->
<if test="condition.name == 'executeUser'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="test_plan_functional_case.execute_user"/>
</include>
</if>
<!-- 执行结果 -->
<if test="condition.name == 'lastExecuteResult'">
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="condition" value="condition"/>
<property name="column" value="test_plan_functional_case.last_exec_result"/>
</include>
</if>
<!-- 关联需求 -->
<if test="condition.name == 'demand'">
<include refid="io.metersphere.system.mapper.BaseMapper.associationCondition">
<property name="mainIdColumn" value="functional_case.id"/>
<property name="associationTable" value="functional_case_demand"/>
<property name="associationIdColumn" value="case_id"/>
<property name="searchColumn" value="demand_name"/>
<property name="condition" value="condition"/>
</include>
</if>
<!-- 关联附件 -->
<if test="condition.name == 'attachment'">
<include refid="io.metersphere.system.mapper.BaseMapper.associationCondition">
<property name="mainIdColumn" value="functional_case.id"/>
<property name="associationTable" value="functional_case_attachment"/>
<property name="associationIdColumn" value="case_id"/>
<property name="searchColumn" value="file_name"/>
<property name="condition" value="condition"/>
</include>
<choose>
<when test="condition.operator == 'NOT_IN' or condition.operator == 'NOT_EQUALS' or condition.operator == 'NOT_CONTAINS'">
and
</when>
<otherwise>
or
</otherwise>
</choose>
<include refid="associationAttachmentCondition">
<property name="condition" value="condition"/>
</include>
</if>
<include refid="io.metersphere.system.mapper.BaseMapper.queryType">
<property name="searchMode" value="${combineSearch}.searchMode"/>
</include>
</foreach>
<include refid="io.metersphere.system.mapper.BaseMapper.customFiledConditions">
<property name="mainIdColumn" value="functional_case.id"/>
<property name="associationTable" value="functional_case_custom_field"/>
<property name="associationIdColumn" value="case_id"/>
<property name="combineSearch" value="${combineSearch}"/>
</include>
</if>
</trim>
</trim>
</sql>
<sql id="associationAttachmentCondition">
<choose>
<when test="${condition}.operator == 'EMPTY'">
functional_case.id not in (
select file_association.source_id from file_association where file_association.source_type = 'FUNCTIONAL_CASE'
)
</when>
<otherwise>
(
functional_case.id
<if test="${condition}.operator == 'NOT_IN' or ${condition}.operator == 'NOT_EQUALS' or ${condition}.operator == 'NOT_CONTAINS'">
not
</if>
in (
select file_association.source_id from file_association join file_metadata on file_association.file_id = file_metadata.id
and file_association.source_type = 'FUNCTIONAL_CASE' and
<choose>
<when test="custom.type == 'List'">
and JSON_CONTAINS(`value`, json_array(#{custom.value}))
</when>
<when test="custom.type == 'date' or custom.type == 'datetime'">
and `value`
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="custom"/>
<when test="${condition}.operator == 'NOT_IN' or ${condition}.operator == 'NOT_EQUALS' or ${condition}.operator == 'NOT_CONTAINS'">
<include refid="io.metersphere.system.mapper.BaseMapper.associationReversalCondition">
<property name="condition" value="${condition}"/>
<property name="column" value="file_metadata.original_name"/>
</include>
</when>
<otherwise>
and trim(both '"' from `value`)
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="custom"/>
<property name="condition" value="${condition}"/>
<property name="column" value="file_metadata.original_name"/>
</include>
</otherwise>
</choose>
)
<include refid="queryType">
<property name="searchMode" value="${searchMode}"/>
</include>
</foreach>
</if>
)
</otherwise>
</choose>
</sql>
<sql id="queryVersionCondition">