Commit a33a8369 authored by lixuan's avatar lixuan

feat: 需求

parent bd32f53f
Pipeline #147218 failed with stages
in 0 seconds
......@@ -20,15 +20,18 @@ import java.util.List;
*
* <h3>经营主体(BUSINESS_ENTITY_INFO)维度</h3>
* <ul>
* <li>{@link #businessEntityInsertCount} / {@link #businessEntityInsertIds}:
* 新增经营主体的数量和 id 列表(可传给 drilldown);</li>
* <li>{@link #businessEntityUpdateCount} / {@link #businessEntityUpdateIds}:同上;</li>
* <li>{@link #businessEntityDeleteCount}:只给 count,无 id。</li>
* <li>{@link #businessEntityInsert} / {@link #businessEntityUpdate} / {@link #businessEntityDelete}:
* 结构与房源三桶一致,按关联房源的 {@code house_resource.type} 分组,补齐 type = 1/4/5/6/7 五档;
* 一个经营主体若关联到多种 type 的房源,会在对应的多个 type 桶里各出现一次。</li>
* <li>{@code insert} / {@code update} 桶的每个档位带 {@code ids} 列表,前端 drilldown 时应同时传
* {@code businessEntityInfoIds} + {@code wgType = type},以和档位计数保持一致;</li>
* <li>{@code delete} 桶同样只给 count 不给 ids。</li>
* </ul>
*
* <h3>计数口径</h3>
* <p>insert / update 桶会过滤 {@code delete_flag = 0},保证和 pageHouseResources 的 drilldown
* 列表能一一对上;delete 桶不过滤 {@code delete_flag},用于统计窗内发生过删除事件的数量。</p>
* <p>insert / update 桶要求 JOIN 链路 entity / mapping / house 均 {@code delete_flag = 0},保证
* 和 pageHouseResources 的 drilldown 列表能一一对上;delete 桶只要求 entity 历史上至少关联过某个房源,
* 不限 mapping / house 的 {@code delete_flag}。</p>
*/
@Data
public class HouseResourceDataCollection {
......@@ -39,13 +42,9 @@ public class HouseResourceDataCollection {
private List<HouseResourceDataCollectionSimpleObject> houseResourceDelete;
private long businessEntityInsertCount;
private List<HouseResourceDataCollectionSimpleObject> businessEntityInsert;
private List<String> businessEntityInsertIds;
private List<HouseResourceDataCollectionSimpleObject> businessEntityUpdate;
private long businessEntityUpdateCount;
private List<String> businessEntityUpdateIds;
private long businessEntityDeleteCount;
private List<HouseResourceDataCollectionSimpleObject> businessEntityDelete;
}
......@@ -688,24 +688,16 @@ public class HouseResourceServiceImpl implements HouseResourceService {
result.setHouseResourceUpdate(buildHouseTypeBuckets(houseDetails, OperationType.UPDATE.getCode(), true));
result.setHouseResourceDelete(buildHouseTypeBucketsFromCount(houseDeleteRows));
// BUSINESS_ENTITY_INFO: insert / update 拿 ids + count;delete 只拿 count。
// BUSINESS_ENTITY_INFO:结构与房源对称,按关联房源 hr2.type 分桶(1/4/5/6/7)。
// insert / update 出详情(带 ids,前端 drilldown 时需配合 wgType = type 使用),delete 只出 count。
List<HouseResourceDataCollectionDetailRow> entityDetails =
houseResourceMapper.selectBusinessEntityChangeDetails(query);
Map<Integer, List<String>> entityIdsByOp = entityDetails.stream()
.collect(Collectors.groupingBy(
HouseResourceDataCollectionDetailRow::getOperationType,
Collectors.mapping(HouseResourceDataCollectionDetailRow::getSubjectId, Collectors.toList())));
List<String> entityInsertIds = entityIdsByOp.getOrDefault(OperationType.INSERT.getCode(), Collections.emptyList());
List<String> entityUpdateIds = entityIdsByOp.getOrDefault(OperationType.UPDATE.getCode(), Collections.emptyList());
result.setBusinessEntityInsertIds(entityInsertIds);
result.setBusinessEntityInsertCount(entityInsertIds.size());
result.setBusinessEntityUpdateIds(entityUpdateIds);
result.setBusinessEntityUpdateCount(entityUpdateIds.size());
long entityDeleteCount = houseResourceMapper.selectBusinessEntityDeleteCount(query).stream()
.mapToLong(HouseResourceDataCollectionRow::getCount)
.sum();
result.setBusinessEntityDeleteCount(entityDeleteCount);
List<HouseResourceDataCollectionRow> entityDeleteRows =
houseResourceMapper.selectBusinessEntityDeleteCount(query);
result.setBusinessEntityInsert(buildHouseTypeBuckets(entityDetails, OperationType.INSERT.getCode(), true));
result.setBusinessEntityUpdate(buildHouseTypeBuckets(entityDetails, OperationType.UPDATE.getCode(), true));
result.setBusinessEntityDelete(buildHouseTypeBucketsFromCount(entityDeleteRows));
return result;
}
......
......@@ -1005,33 +1005,30 @@
</select>
<!--
时间窗内经营主体(BUSINESS_ENTITY_INFO)的新增 / 修改**详情**行:每行一个 (operation_type, subject_id)。
时间窗内经营主体(BUSINESS_ENTITY_INFO)的新增 / 修改**详情**行:每行一个 (type, operation_type, subject_id)。
口径对齐 pageHouseResources 的 drilldown(t1.delete_flag = 0 + t3.delete_flag = 0 + t4.delete_flag = 0):
* bei.delete_flag = 0:entity 本身必须存活;
* EXISTS 子查询**恒生效**:要求经营主体至少关联到一条"有效 mapping + 有效 house",
否则 drilldown 侧展示不出来,也就不计入 dataCollection。这样保证 dataCollection 返回的
id 列表都能在 /api/house/page?businessEntityInfoIds=... 里查到对应行。
* 传 two/three/four/wgCodes 时,EXISTS 内部按网格进一步收紧。
说明:
* 这里的 type 取自关联房源 hr2.type(经营主体本身无 type 字段)。一个 entity 关联到多种 type
的房源时,会在对应的多个桶里分别出现一次(DISTINCT 已对 (type, operation_type, subject_id) 去重)。
* INNER JOIN 链路:bei → mapping → house_resource,且三者都要求 delete_flag = 0,与
pageHouseResources 的 drilldown 口径一致,保证 dataCollection 返回的每个 id 在
/api/house/page?businessEntityInfoIds=...&wgType=type 里都能查到对应行。
* 传 two/three/four/wgCodes 时,按网格进一步收紧 hr2。
-->
<select id="selectBusinessEntityChangeDetails"
resultType="com.ruoyi.system.domain.house.vo.HouseResourceDataCollectionDetailRow">
SELECT DISTINCT
0 AS type,
hr2.type AS type,
dcr.operation_type AS operationType,
dcr.subject_id AS subjectId
FROM data_change_record dcr
INNER JOIN business_entity_info bei ON bei.id = dcr.subject_id AND bei.delete_flag = 0
INNER JOIN house_resource_business_entity_info_mapping m ON m.business_entity_info_id = bei.id AND m.delete_flag = 0
INNER JOIN house_resource hr2 ON hr2.id = m.house_resource_id AND hr2.delete_flag = 0
WHERE dcr.subject_type = 'BUSINESS_ENTITY_INFO'
AND dcr.operation_type IN (1, 2)
AND dcr.operation_time <![CDATA[ >= ]]> #{query.changeStartTime}
AND dcr.operation_time <![CDATA[ <= ]]> #{query.changeEndTime}
AND EXISTS (
SELECT 1
FROM house_resource_business_entity_info_mapping m
INNER JOIN house_resource hr2 ON hr2.id = m.house_resource_id AND hr2.delete_flag = 0
WHERE m.business_entity_info_id = bei.id
AND m.delete_flag = 0
<if test="query.two != null and query.two != ''">
AND hr2.two = #{query.two}
</if>
......@@ -1045,7 +1042,6 @@
AND hr2.two IN
<foreach collection="query.wgCodes" item="wg" open="(" separator="," close=")">#{wg}</foreach>
</if>
)
</select>
<!--
......@@ -1054,28 +1050,28 @@
匹配网格的房源"即计入,覆盖"经营主体删除前房源或 mapping 已经被解除"的场景。
-->
<!--
时间窗内经营主体(BUSINESS_ENTITY_INFO)被删除的数量。
与 insert/update 口径保持一致:EXISTS 恒生效,要求经营主体历史上至少关联过某个房源(不限
delete_flag,因为被删的 entity 本身的 mapping/house 也可能已被删)。这样"从未挂过房源"的
孤儿 entity 不计入删除数,保证和看得见的业务实体口径统一。
时间窗内经营主体(BUSINESS_ENTITY_INFO)被删除的数量,按关联房源 hr2.type 分组。
与 insert/update 口径保持一致:INNER JOIN 链路 bei → mapping → house_resource 恒生效,
要求经营主体历史上至少关联过某个房源;但 mapping / hr2 **不**限 delete_flag,因为被删除
的 entity 其 mapping/house 可能也已逻辑删除。一个 entity 若关联过多种 type 的房源,会在
对应的多个 type 桶里分别被 COUNT DISTINCT 计入一次(聚合层面)。"从未挂过房源"的孤儿
entity 不计入删除数,保证和看得见的业务口径统一。
-->
<select id="selectBusinessEntityDeleteCount"
resultType="com.ruoyi.system.domain.house.vo.HouseResourceDataCollectionRow">
SELECT
0 AS type,
hr2.type AS type,
3 AS operationType,
COUNT(DISTINCT dcr.subject_id) AS count
FROM data_change_record dcr
INNER JOIN business_entity_info bei ON bei.id = dcr.subject_id
INNER JOIN house_resource_business_entity_info_mapping m ON m.business_entity_info_id = bei.id
INNER JOIN house_resource hr2 ON hr2.id = m.house_resource_id
WHERE dcr.subject_type = 'BUSINESS_ENTITY_INFO'
AND dcr.operation_type = 3
AND dcr.operation_time <![CDATA[ >= ]]> #{query.changeStartTime}
AND dcr.operation_time <![CDATA[ <= ]]> #{query.changeEndTime}
AND EXISTS (
SELECT 1
FROM house_resource_business_entity_info_mapping m
INNER JOIN house_resource hr2 ON hr2.id = m.house_resource_id
WHERE m.business_entity_info_id = bei.id
<if test="query.two != null and query.two != ''">
AND hr2.two = #{query.two}
</if>
......@@ -1089,6 +1085,6 @@
AND hr2.two IN
<foreach collection="query.wgCodes" item="wg" open="(" separator="," close=")">#{wg}</foreach>
</if>
)
GROUP BY hr2.type
</select>
</mapper>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment