补充结果总览模型区人员分页查询

This commit is contained in:
wkc
2026-03-20 11:13:29 +08:00
parent aae2d44c07
commit 12fa064a48
4 changed files with 160 additions and 1 deletions

View File

@@ -2,6 +2,7 @@ package com.ruoyi.ccdi.project.domain.dto;
import jakarta.validation.constraints.Pattern;
import java.util.List;
import java.util.stream.Collectors;
import lombok.Data;
/**
@@ -31,4 +32,15 @@ public class CcdiProjectRiskModelPeopleQueryDTO {
/** 每页数量 */
private Integer pageSize;
public String getModelCodesCsv() {
if (modelCodes == null || modelCodes.isEmpty()) {
return null;
}
return modelCodes.stream()
.filter(item -> item != null && !item.isBlank())
.map(String::trim)
.distinct()
.collect(Collectors.joining(","));
}
}

View File

@@ -1,8 +1,11 @@
package com.ruoyi.ccdi.project.mapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskModelPeopleQueryDTO;
import com.ruoyi.ccdi.project.domain.CcdiProject;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeRiskAggregateVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectRiskModelCardVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectRiskModelPeopleItemVO;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Mapper;
@@ -46,6 +49,18 @@ public interface CcdiProjectOverviewMapper {
*/
List<CcdiProjectRiskModelCardVO> selectRiskModelCardsByProjectId(@Param("projectId") Long projectId);
/**
* 分页查询风险模型命中人员
*
* @param page 分页参数
* @param query 查询条件
* @return 命中人员分页结果
*/
Page<CcdiProjectRiskModelPeopleItemVO> selectRiskModelPeoplePage(
Page<CcdiProjectRiskModelPeopleItemVO> page,
@Param("query") CcdiProjectRiskModelPeopleQueryDTO query
);
/**
* 查询项目风险人数汇总
*

View File

@@ -18,17 +18,34 @@
<result property="riskLevelSort" column="risk_level_sort"/>
</resultMap>
<resultMap id="RiskModelPeopleItemResultMap" type="com.ruoyi.ccdi.project.domain.vo.CcdiProjectRiskModelPeopleItemVO">
<id property="idNo" column="staff_id_card"/>
<result property="staffName" column="staff_name"/>
<result property="staffCode" column="staff_code"/>
<result property="department" column="department"/>
<collection property="modelNames"
column="{projectId=project_id,staffIdCard=staff_id_card,selectedModelCodes=selected_model_codes}"
ofType="java.lang.String"
select="selectRiskModelNamesByScope"/>
<collection property="hitTagList"
column="{projectId=project_id,staffIdCard=staff_id_card,selectedModelCodes=selected_model_codes}"
ofType="com.ruoyi.ccdi.project.domain.vo.CcdiProjectRiskHitTagVO"
select="selectRiskHitTagsByScope"/>
</resultMap>
<sql id="resolvedEmployeeRiskBaseSql">
select distinct
tr.id,
tr.project_id,
coalesce(direct_staff.id_card, statement_staff.id_card, family_staff.id_card) as staff_id_card,
coalesce(direct_staff.name, statement_staff.name, family_staff.name) as staff_name,
cast(coalesce(direct_staff.staff_id, statement_staff.staff_id, family_staff.staff_id) as char) as staff_code,
coalesce(direct_staff.dept_id, statement_staff.dept_id, family_staff.dept_id) as dept_id,
tr.rule_code,
tr.rule_name,
tr.model_code,
tr.model_name
tr.model_name,
tr.risk_level
from ccdi_bank_statement_tag_result tr
left join ccdi_base_staff direct_staff
on tr.object_type = 'STAFF_ID_CARD'
@@ -193,6 +210,76 @@
order by warning_count desc, model_code asc
</select>
<select id="selectRiskModelPeoplePage" resultMap="RiskModelPeopleItemResultMap">
select
base.project_id,
base.staff_id_card,
max(base.staff_name) as staff_name,
max(base.staff_code) as staff_code,
max(dept.dept_name) as department,
#{query.modelCodesCsv} as selected_model_codes
from (
<include refid="resolvedEmployeeRiskBaseSql"/>
) base
left join sys_dept dept on base.dept_id = dept.dept_id
where 1 = 1
<if test="query.modelCodes != null and query.modelCodes.size() > 0">
and base.model_code in
<foreach collection="query.modelCodes" item="modelCode" open="(" separator="," close=")">
#{modelCode}
</foreach>
</if>
<if test="query.keyword != null and query.keyword != ''">
and (
base.staff_name like concat('%', trim(#{query.keyword}), '%')
or cast(base.staff_code as char) like concat('%', trim(#{query.keyword}), '%')
)
</if>
<if test="query.deptId != null">
and base.dept_id = #{query.deptId}
</if>
group by base.project_id, base.staff_id_card
<if test="query.modelCodes != null and query.modelCodes.size() > 0 and query.matchMode == 'ALL'">
having count(distinct base.model_code) = #{query.modelCodes.size}
</if>
order by max(base.staff_name) asc, base.staff_id_card asc
</select>
<select id="selectRiskModelNamesByScope" resultType="java.lang.String">
select distinct scoped.model_name
from (
<include refid="resolvedEmployeeRiskBaseSql"/>
) scoped
where scoped.project_id = #{projectId}
and scoped.staff_id_card = #{staffIdCard}
<if test="selectedModelCodes != null and selectedModelCodes != ''">
and find_in_set(scoped.model_code, #{selectedModelCodes})
</if>
order by scoped.model_code asc
</select>
<select id="selectRiskHitTagsByScope" resultType="com.ruoyi.ccdi.project.domain.vo.CcdiProjectRiskHitTagVO">
select
scoped.rule_code,
max(scoped.rule_name) as rule_name,
max(scoped.risk_level) as risk_level
from (
<include refid="resolvedEmployeeRiskBaseSql"/>
) scoped
where scoped.project_id = #{projectId}
and scoped.staff_id_card = #{staffIdCard}
<if test="selectedModelCodes != null and selectedModelCodes != ''">
and find_in_set(scoped.model_code, #{selectedModelCodes})
</if>
group by scoped.rule_code
order by case max(scoped.risk_level)
when 'HIGH' then 1
when 'MEDIUM' then 2
else 3
end,
scoped.rule_code asc
</select>
<select id="selectRiskCountSummaryByProjectId" resultType="map">
select
coalesce(sum(case when agg.rule_count >= 5 then 1 else 0 end), 0) as highRiskCount,

View File

@@ -0,0 +1,45 @@
package com.ruoyi.ccdi.project.mapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskModelPeopleQueryDTO;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Path;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
class CcdiProjectOverviewMapperRiskModelPeopleTest {
@Test
void shouldExposeRiskModelPeoplePageMapperMethod() throws Exception {
Method method = CcdiProjectOverviewMapper.class.getMethod(
"selectRiskModelPeoplePage",
Page.class,
CcdiProjectRiskModelPeopleQueryDTO.class
);
assertEquals(Page.class, method.getReturnType());
assertEquals(Page.class, method.getParameterTypes()[0]);
assertEquals(CcdiProjectRiskModelPeopleQueryDTO.class, method.getParameterTypes()[1]);
}
@Test
void shouldDefineRiskModelPeopleSqlForAnyAllKeywordDeptAndScopedCollections() throws Exception {
String xml = Files.readString(Path.of("src/main/resources/mapper/ccdi/project/CcdiProjectOverviewMapper.xml"));
assertTrue(xml.contains("<select id=\"selectRiskModelPeoplePage\""));
assertTrue(xml.contains("query.modelCodes != null and query.modelCodes.size() > 0"));
assertTrue(xml.contains("query.matchMode == 'ALL'"));
assertTrue(xml.contains("count(distinct base.model_code) = #{query.modelCodes.size}"));
assertTrue(xml.contains("base.staff_name like concat('%', trim(#{query.keyword}), '%')"));
assertTrue(xml.contains("cast(base.staff_code as char) like concat('%', trim(#{query.keyword}), '%')"));
assertTrue(xml.contains("base.dept_id = #{query.deptId}"));
assertTrue(xml.contains("select=\"selectRiskModelNamesByScope\""));
assertTrue(xml.contains("select=\"selectRiskHitTagsByScope\""));
assertTrue(xml.contains("find_in_set(scoped.model_code, #{selectedModelCodes})"));
assertTrue(xml.contains("order by case max(scoped.risk_level)"));
assertTrue(xml.contains("scoped.rule_code asc"));
}
}