切换结果总览查询到员工结果表
This commit is contained in:
@@ -8,6 +8,8 @@ import lombok.Data;
|
||||
@Data
|
||||
public class CcdiProjectOverviewEmployeeRuleSummaryVO {
|
||||
|
||||
private String modelCode;
|
||||
|
||||
private String ruleCode;
|
||||
|
||||
private String ruleName;
|
||||
|
||||
@@ -103,6 +103,7 @@ public class CcdiProjectOverviewEmployeeResultBuilder {
|
||||
.map(rows -> {
|
||||
CcdiProjectOverviewEmployeeRuleSummaryVO summary = new CcdiProjectOverviewEmployeeRuleSummaryVO();
|
||||
CcdiProjectOverviewEmployeeHitRowVO first = rows.getFirst();
|
||||
summary.setModelCode(first.getModelCode());
|
||||
summary.setRuleCode(first.getRuleCode());
|
||||
summary.setRuleName(first.getRuleName());
|
||||
summary.setRiskLevel(first.getRiskLevel());
|
||||
|
||||
@@ -33,6 +33,29 @@
|
||||
select="selectRiskHitTagsByScope"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="digitTableSql">
|
||||
select 0 as digit
|
||||
union all select 1
|
||||
union all select 2
|
||||
union all select 3
|
||||
union all select 4
|
||||
union all select 5
|
||||
union all select 6
|
||||
union all select 7
|
||||
union all select 8
|
||||
union all select 9
|
||||
</sql>
|
||||
|
||||
<sql id="jsonArrayIndexSql">
|
||||
select ones.digit + tens.digit * 10 as idx
|
||||
from (
|
||||
<include refid="digitTableSql"/>
|
||||
) ones
|
||||
cross join (
|
||||
<include refid="digitTableSql"/>
|
||||
) tens
|
||||
</sql>
|
||||
|
||||
<sql id="resolvedEmployeeRiskBaseSql">
|
||||
select distinct
|
||||
tr.id,
|
||||
@@ -186,14 +209,60 @@
|
||||
</select>
|
||||
|
||||
<select id="selectRiskPeopleOverviewByProjectId" resultMap="EmployeeRiskAggregateResultMap">
|
||||
<include refid="employeeRiskAggregateSql"/>
|
||||
order by risk_level_sort asc, model_count desc, rule_count desc, staff_id_card asc
|
||||
select
|
||||
result.staff_id_card,
|
||||
result.staff_name,
|
||||
result.dept_id,
|
||||
result.dept_name,
|
||||
result.rule_count,
|
||||
result.model_count,
|
||||
result.hit_count,
|
||||
null as top_rule_code,
|
||||
null as top_rule_name,
|
||||
result.risk_point,
|
||||
result.risk_level_code,
|
||||
case
|
||||
when result.risk_level_code = 'HIGH' then '高风险'
|
||||
when result.risk_level_code = 'MEDIUM' then '中风险'
|
||||
else '低风险'
|
||||
end as risk_level_name,
|
||||
case
|
||||
when result.risk_level_code = 'HIGH' then 1
|
||||
when result.risk_level_code = 'MEDIUM' then 2
|
||||
else 3
|
||||
end as risk_level_sort
|
||||
from ccdi_project_overview_employee_result result
|
||||
where result.project_id = #{projectId}
|
||||
order by risk_level_sort asc, result.model_count desc, result.rule_count desc, result.staff_id_card asc
|
||||
</select>
|
||||
|
||||
<select id="selectTopRiskPeopleByProjectId" resultMap="EmployeeRiskAggregateResultMap">
|
||||
<include refid="employeeRiskAggregateSql"/>
|
||||
where rule_count >= 2
|
||||
order by risk_level_sort asc, model_count desc, rule_count desc, staff_id_card asc
|
||||
select
|
||||
result.staff_id_card,
|
||||
result.staff_name,
|
||||
result.dept_id,
|
||||
result.dept_name,
|
||||
result.rule_count,
|
||||
result.model_count,
|
||||
result.hit_count,
|
||||
null as top_rule_code,
|
||||
null as top_rule_name,
|
||||
result.risk_point,
|
||||
result.risk_level_code,
|
||||
case
|
||||
when result.risk_level_code = 'HIGH' then '高风险'
|
||||
when result.risk_level_code = 'MEDIUM' then '中风险'
|
||||
else '低风险'
|
||||
end as risk_level_name,
|
||||
case
|
||||
when result.risk_level_code = 'HIGH' then 1
|
||||
when result.risk_level_code = 'MEDIUM' then 2
|
||||
else 3
|
||||
end as risk_level_sort
|
||||
from ccdi_project_overview_employee_result result
|
||||
where result.project_id = #{projectId}
|
||||
and result.risk_level_code in ('HIGH', 'MEDIUM')
|
||||
order by risk_level_sort asc, result.model_count desc, result.rule_count desc, result.staff_id_card asc
|
||||
limit 10
|
||||
</select>
|
||||
|
||||
@@ -213,13 +282,18 @@
|
||||
) models
|
||||
left join (
|
||||
select
|
||||
base.model_code,
|
||||
count(1) as warning_count,
|
||||
count(distinct base.staff_id_card) as people_count
|
||||
from (
|
||||
<include refid="resolvedEmployeeRiskBaseSql"/>
|
||||
) base
|
||||
group by base.model_code
|
||||
json_unquote(json_extract(result.model_hit_summary_json, concat('$[', idx.idx, '].modelCode'))) as model_code,
|
||||
sum(cast(json_unquote(json_extract(
|
||||
result.model_hit_summary_json,
|
||||
concat('$[', idx.idx, '].warningCount')
|
||||
)) as unsigned)) as warning_count,
|
||||
count(distinct result.staff_id_card) as people_count
|
||||
from ccdi_project_overview_employee_result result
|
||||
join (
|
||||
<include refid="jsonArrayIndexSql"/>
|
||||
) idx on idx.idx < json_length(result.model_hit_summary_json)
|
||||
where result.project_id = #{projectId}
|
||||
group by json_unquote(json_extract(result.model_hit_summary_json, concat('$[', idx.idx, '].modelCode')))
|
||||
) stats on models.model_code = stats.model_code
|
||||
order by warning_count desc, model_code asc
|
||||
</select>
|
||||
@@ -227,73 +301,88 @@
|
||||
<select id="selectRiskModelPeoplePage" resultMap="RiskModelPeopleItemResultMap">
|
||||
<bind name="projectId" value="query.projectId"/>
|
||||
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,
|
||||
result.project_id,
|
||||
result.staff_id_card,
|
||||
result.staff_name,
|
||||
result.staff_code,
|
||||
result.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
|
||||
from ccdi_project_overview_employee_result result
|
||||
where 1 = 1
|
||||
and result.project_id = #{query.projectId}
|
||||
<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>
|
||||
<choose>
|
||||
<when test="query.matchMode == 'ALL'">
|
||||
<foreach collection="query.modelCodes" item="modelCode">
|
||||
and find_in_set(#{modelCode}, result.model_codes_csv)
|
||||
</foreach>
|
||||
</when>
|
||||
<otherwise>
|
||||
and (
|
||||
<foreach collection="query.modelCodes" item="modelCode" separator=" or ">
|
||||
find_in_set(#{modelCode}, result.model_codes_csv)
|
||||
</foreach>
|
||||
)
|
||||
</otherwise>
|
||||
</choose>
|
||||
</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}), '%')
|
||||
result.staff_name like concat('%', trim(#{query.keyword}), '%')
|
||||
or result.staff_code like concat('%', trim(#{query.keyword}), '%')
|
||||
)
|
||||
</if>
|
||||
<if test="query.deptId != null">
|
||||
and base.dept_id = #{query.deptId}
|
||||
and result.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.modelCodesCount}
|
||||
</if>
|
||||
order by max(base.staff_name) asc, base.staff_id_card asc
|
||||
order by result.staff_name asc, result.staff_id_card asc
|
||||
</select>
|
||||
|
||||
<select id="selectRiskModelNamesByScope" resultType="java.lang.String">
|
||||
select scoped.model_name
|
||||
from (
|
||||
<include refid="resolvedEmployeeRiskBaseSql"/>
|
||||
) scoped
|
||||
where scoped.project_id = #{projectId}
|
||||
and scoped.staff_id_card = #{staffIdCard}
|
||||
select
|
||||
json_unquote(json_extract(result.model_hit_summary_json, concat('$[', idx.idx, '].modelName'))) as model_name
|
||||
from ccdi_project_overview_employee_result result
|
||||
join (
|
||||
<include refid="jsonArrayIndexSql"/>
|
||||
) idx on idx.idx < json_length(result.model_hit_summary_json)
|
||||
where result.project_id = #{projectId}
|
||||
and result.staff_id_card = #{staffIdCard}
|
||||
<if test="selectedModelCodes != null and selectedModelCodes != ''">
|
||||
and find_in_set(scoped.model_code, #{selectedModelCodes})
|
||||
and find_in_set(
|
||||
json_unquote(json_extract(result.model_hit_summary_json, concat('$[', idx.idx, '].modelCode'))),
|
||||
#{selectedModelCodes}
|
||||
)
|
||||
</if>
|
||||
group by scoped.model_code, scoped.model_name
|
||||
order by scoped.model_code asc
|
||||
group by
|
||||
json_unquote(json_extract(result.model_hit_summary_json, concat('$[', idx.idx, '].modelCode'))),
|
||||
json_unquote(json_extract(result.model_hit_summary_json, concat('$[', idx.idx, '].modelName')))
|
||||
order by json_unquote(json_extract(result.model_hit_summary_json, concat('$[', idx.idx, '].modelCode'))) 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}
|
||||
json_unquote(json_extract(result.hit_rules_json, concat('$[', idx.idx, '].ruleCode'))) as rule_code,
|
||||
max(json_unquote(json_extract(result.hit_rules_json, concat('$[', idx.idx, '].ruleName')))) as rule_name,
|
||||
max(json_unquote(json_extract(result.hit_rules_json, concat('$[', idx.idx, '].riskLevel')))) as risk_level
|
||||
from ccdi_project_overview_employee_result result
|
||||
join (
|
||||
<include refid="jsonArrayIndexSql"/>
|
||||
) idx on idx.idx < json_length(result.hit_rules_json)
|
||||
where result.project_id = #{projectId}
|
||||
and result.staff_id_card = #{staffIdCard}
|
||||
<if test="selectedModelCodes != null and selectedModelCodes != ''">
|
||||
and find_in_set(scoped.model_code, #{selectedModelCodes})
|
||||
and find_in_set(
|
||||
json_unquote(json_extract(result.hit_rules_json, concat('$[', idx.idx, '].modelCode'))),
|
||||
#{selectedModelCodes}
|
||||
)
|
||||
</if>
|
||||
group by scoped.rule_code
|
||||
order by case max(scoped.risk_level)
|
||||
group by json_unquote(json_extract(result.hit_rules_json, concat('$[', idx.idx, '].ruleCode')))
|
||||
order by case max(json_unquote(json_extract(result.hit_rules_json, concat('$[', idx.idx, '].riskLevel'))))
|
||||
when 'HIGH' then 1
|
||||
when 'MEDIUM' then 2
|
||||
else 3
|
||||
end,
|
||||
scoped.rule_code asc
|
||||
json_unquote(json_extract(result.hit_rules_json, concat('$[', idx.idx, '].ruleCode'))) asc
|
||||
</select>
|
||||
|
||||
<select id="selectRiskCountSummaryByProjectId" resultType="map">
|
||||
|
||||
@@ -17,18 +17,19 @@ class CcdiProjectOverviewMapperRiskModelCardsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldDefineRiskModelCardsSqlUsingEmployeeResolvedBase() throws Exception {
|
||||
void shouldDefineRiskModelCardsSqlUsingEmployeeResultSnapshot() throws Exception {
|
||||
String xml = Files.readString(Path.of("src/main/resources/mapper/ccdi/project/CcdiProjectOverviewMapper.xml"));
|
||||
|
||||
assertTrue(xml.contains("<select id=\"selectRiskModelCardsByProjectId\""));
|
||||
assertTrue(xml.contains("from ("));
|
||||
assertTrue(xml.contains("from ccdi_project_overview_employee_result"));
|
||||
assertTrue(xml.contains("from ccdi_bank_tag_rule"));
|
||||
assertTrue(xml.contains("where enabled = 1"));
|
||||
assertTrue(xml.contains("left join ("));
|
||||
assertTrue(xml.contains("<include refid=\"resolvedEmployeeRiskBaseSql\"/>"));
|
||||
assertTrue(xml.contains("model_hit_summary_json"));
|
||||
assertTrue(xml.contains("json_extract("));
|
||||
assertTrue(xml.contains("coalesce(stats.warning_count, 0) as warning_count"));
|
||||
assertTrue(xml.contains("coalesce(stats.people_count, 0) as people_count"));
|
||||
assertTrue(xml.contains("count(1) as warning_count"));
|
||||
assertTrue(xml.contains(".warningCount"));
|
||||
assertTrue(xml.contains("order by warning_count desc, model_code asc"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,18 +34,19 @@ class CcdiProjectOverviewMapperRiskModelPeopleTest {
|
||||
assertTrue(xml.contains("query.modelCodes != null and query.modelCodes.size() > 0"));
|
||||
assertTrue(xml.contains("query.matchMode == 'ALL'"));
|
||||
assertFalse(xml.contains("#{query.modelCodes.size}"));
|
||||
assertTrue(xml.contains("count(distinct base.model_code) = #{query.modelCodesCount}"));
|
||||
assertTrue(xml.contains("find_in_set(#{modelCode}, result.model_codes_csv)"));
|
||||
assertTrue(xml.contains("<bind name=\"projectId\" value=\"query.projectId\"/>"));
|
||||
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("result.staff_name like concat('%', trim(#{query.keyword}), '%')"));
|
||||
assertTrue(xml.contains("result.staff_code like concat('%', trim(#{query.keyword}), '%')"));
|
||||
assertTrue(xml.contains("result.dept_id = #{query.deptId}"));
|
||||
assertTrue(xml.contains("select=\"selectRiskModelNamesByScope\""));
|
||||
assertTrue(xml.contains("select=\"selectRiskHitTagsByScope\""));
|
||||
assertTrue(xml.contains("find_in_set(scoped.model_code, #{selectedModelCodes})"));
|
||||
assertFalse(xml.contains("select distinct scoped.model_name"));
|
||||
assertTrue(xml.contains("group by scoped.model_code, scoped.model_name"));
|
||||
assertTrue(xml.contains("order by scoped.model_code asc"));
|
||||
assertTrue(xml.contains("order by case max(scoped.risk_level)"));
|
||||
assertTrue(xml.contains("scoped.rule_code asc"));
|
||||
assertTrue(xml.contains("model_hit_summary_json"));
|
||||
assertTrue(xml.contains("hit_rules_json"));
|
||||
assertTrue(xml.contains("json_extract("));
|
||||
assertTrue(xml.contains(".modelCode"));
|
||||
assertTrue(xml.contains(".modelName"));
|
||||
assertTrue(xml.contains(".ruleCode"));
|
||||
assertTrue(xml.contains(".riskLevel"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,18 +11,30 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
class CcdiProjectOverviewMapperSqlTest {
|
||||
|
||||
@Test
|
||||
void shouldContainEmployeeRiskAggregationSql() throws Exception {
|
||||
void shouldReadOverviewQueriesFromEmployeeResultTable() throws Exception {
|
||||
String xml = Files.readString(Path.of("src/main/resources/mapper/ccdi/project/CcdiProjectOverviewMapper.xml"));
|
||||
String riskPeopleSql = extractSelect(xml, "selectRiskPeopleOverviewByProjectId");
|
||||
String topRiskPeopleSql = extractSelect(xml, "selectTopRiskPeopleByProjectId");
|
||||
String riskModelCardsSql = extractSelect(xml, "selectRiskModelCardsByProjectId");
|
||||
String riskModelPeopleSql = extractSelect(xml, "selectRiskModelPeoplePage");
|
||||
|
||||
assertTrue(xml.contains("count(distinct base.rule_code)"));
|
||||
assertTrue(xml.contains("count(distinct base.model_code)"));
|
||||
assertTrue(xml.contains("count(1) as hit_count"));
|
||||
assertTrue(xml.contains("agg.hit_count"));
|
||||
assertTrue(xml.contains("when agg.rule_count >= 5 then 'HIGH'"));
|
||||
assertTrue(xml.contains("when agg.rule_count between 2 and 4 then 'MEDIUM'"));
|
||||
assertTrue(xml.contains("group_concat("));
|
||||
assertTrue(xml.contains("as risk_point"));
|
||||
assertTrue(xml.contains("order by grouped.hit_count desc, grouped.rule_code asc"));
|
||||
assertTrue(riskPeopleSql.contains("from ccdi_project_overview_employee_result"));
|
||||
assertTrue(riskPeopleSql.contains("risk_level_code"));
|
||||
assertTrue(riskPeopleSql.contains("model_count"));
|
||||
assertTrue(riskPeopleSql.contains("risk_point"));
|
||||
assertFalse(riskPeopleSql.contains("resolvedEmployeeRiskBaseSql"));
|
||||
|
||||
assertTrue(topRiskPeopleSql.contains("from ccdi_project_overview_employee_result"));
|
||||
assertTrue(topRiskPeopleSql.contains("risk_level_code in ('HIGH', 'MEDIUM')"));
|
||||
assertFalse(topRiskPeopleSql.contains("resolvedEmployeeRiskBaseSql"));
|
||||
|
||||
assertTrue(riskModelCardsSql.contains("from ccdi_project_overview_employee_result"));
|
||||
assertTrue(riskModelCardsSql.contains("model_hit_summary_json"));
|
||||
assertFalse(riskModelCardsSql.contains("resolvedEmployeeRiskBaseSql"));
|
||||
|
||||
assertTrue(riskModelPeopleSql.contains("from ccdi_project_overview_employee_result"));
|
||||
assertTrue(riskModelPeopleSql.contains("model_codes_csv"));
|
||||
assertFalse(riskModelPeopleSql.contains("resolvedEmployeeRiskBaseSql"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -30,6 +42,13 @@ class CcdiProjectOverviewMapperSqlTest {
|
||||
String xml = Files.readString(Path.of("src/main/resources/mapper/ccdi/project/CcdiProjectOverviewMapper.xml"));
|
||||
|
||||
assertFalse(xml.contains("row_number() over"), xml);
|
||||
assertTrue(xml.contains("not exists"), xml);
|
||||
assertFalse(xml.contains("json_table("), xml);
|
||||
}
|
||||
|
||||
private String extractSelect(String xml, String selectId) {
|
||||
String start = "<select id=\"" + selectId + "\"";
|
||||
int startIndex = xml.indexOf(start);
|
||||
int endIndex = xml.indexOf("</select>", startIndex);
|
||||
return xml.substring(startIndex, endIndex);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user