Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Y
yichengstreet-be
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
yichengstreet
yichengstreet-be
Commits
a33a8369
Commit
a33a8369
authored
Apr 21, 2026
by
lixuan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 需求
parent
bd32f53f
Pipeline
#147218
failed with stages
in 0 seconds
Changes
3
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
68 additions
and
81 deletions
+68
-81
HouseResourceDataCollection.java
...i/system/domain/house/vo/HouseResourceDataCollection.java
+12
-13
HouseResourceServiceImpl.java
...i/system/service/house/impl/HouseResourceServiceImpl.java
+8
-16
HouseResourceMapper.xml
...m/src/main/resources/mapper/house/HouseResourceMapper.xml
+48
-52
No files found.
ruoyi-system/src/main/java/com/ruoyi/system/domain/house/vo/HouseResourceDataCollection.java
View file @
a33a8369
...
@@ -20,15 +20,18 @@ import java.util.List;
...
@@ -20,15 +20,18 @@ import java.util.List;
*
*
* <h3>经营主体(BUSINESS_ENTITY_INFO)维度</h3>
* <h3>经营主体(BUSINESS_ENTITY_INFO)维度</h3>
* <ul>
* <ul>
* <li>{@link #businessEntityInsertCount} / {@link #businessEntityInsertIds}:
* <li>{@link #businessEntityInsert} / {@link #businessEntityUpdate} / {@link #businessEntityDelete}:
* 新增经营主体的数量和 id 列表(可传给 drilldown);</li>
* 结构与房源三桶一致,按关联房源的 {@code house_resource.type} 分组,补齐 type = 1/4/5/6/7 五档;
* <li>{@link #businessEntityUpdateCount} / {@link #businessEntityUpdateIds}:同上;</li>
* 一个经营主体若关联到多种 type 的房源,会在对应的多个 type 桶里各出现一次。</li>
* <li>{@link #businessEntityDeleteCount}:只给 count,无 id。</li>
* <li>{@code insert} / {@code update} 桶的每个档位带 {@code ids} 列表,前端 drilldown 时应同时传
* {@code businessEntityInfoIds} + {@code wgType = type},以和档位计数保持一致;</li>
* <li>{@code delete} 桶同样只给 count 不给 ids。</li>
* </ul>
* </ul>
*
*
* <h3>计数口径</h3>
* <h3>计数口径</h3>
* <p>insert / update 桶会过滤 {@code delete_flag = 0},保证和 pageHouseResources 的 drilldown
* <p>insert / update 桶要求 JOIN 链路 entity / mapping / house 均 {@code delete_flag = 0},保证
* 列表能一一对上;delete 桶不过滤 {@code delete_flag},用于统计窗内发生过删除事件的数量。</p>
* 和 pageHouseResources 的 drilldown 列表能一一对上;delete 桶只要求 entity 历史上至少关联过某个房源,
* 不限 mapping / house 的 {@code delete_flag}。</p>
*/
*/
@Data
@Data
public
class
HouseResourceDataCollection
{
public
class
HouseResourceDataCollection
{
...
@@ -39,13 +42,9 @@ public class HouseResourceDataCollection {
...
@@ -39,13 +42,9 @@ public class HouseResourceDataCollection {
private
List
<
HouseResourceDataCollectionSimpleObject
>
houseResourceDelete
;
private
List
<
HouseResourceDataCollectionSimpleObject
>
houseResourceDelete
;
private
long
businessEntityInsertCoun
t
;
private
List
<
HouseResourceDataCollectionSimpleObject
>
businessEntityInser
t
;
private
List
<
String
>
businessEntityInsertIds
;
private
List
<
HouseResourceDataCollectionSimpleObject
>
businessEntityUpdate
;
private
long
businessEntityUpdateCount
;
private
List
<
HouseResourceDataCollectionSimpleObject
>
businessEntityDelete
;
private
List
<
String
>
businessEntityUpdateIds
;
private
long
businessEntityDeleteCount
;
}
}
ruoyi-system/src/main/java/com/ruoyi/system/service/house/impl/HouseResourceServiceImpl.java
View file @
a33a8369
...
@@ -688,24 +688,16 @@ public class HouseResourceServiceImpl implements HouseResourceService {
...
@@ -688,24 +688,16 @@ public class HouseResourceServiceImpl implements HouseResourceService {
result
.
setHouseResourceUpdate
(
buildHouseTypeBuckets
(
houseDetails
,
OperationType
.
UPDATE
.
getCode
(),
true
));
result
.
setHouseResourceUpdate
(
buildHouseTypeBuckets
(
houseDetails
,
OperationType
.
UPDATE
.
getCode
(),
true
));
result
.
setHouseResourceDelete
(
buildHouseTypeBucketsFromCount
(
houseDeleteRows
));
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
=
List
<
HouseResourceDataCollectionDetailRow
>
entityDetails
=
houseResourceMapper
.
selectBusinessEntityChangeDetails
(
query
);
houseResourceMapper
.
selectBusinessEntityChangeDetails
(
query
);
Map
<
Integer
,
List
<
String
>>
entityIdsByOp
=
entityDetails
.
stream
()
List
<
HouseResourceDataCollectionRow
>
entityDeleteRows
=
.
collect
(
Collectors
.
groupingBy
(
houseResourceMapper
.
selectBusinessEntityDeleteCount
(
query
);
HouseResourceDataCollectionDetailRow:
:
getOperationType
,
Collectors
.
mapping
(
HouseResourceDataCollectionDetailRow:
:
getSubjectId
,
Collectors
.
toList
())));
result
.
setBusinessEntityInsert
(
buildHouseTypeBuckets
(
entityDetails
,
OperationType
.
INSERT
.
getCode
(),
true
));
List
<
String
>
entityInsertIds
=
entityIdsByOp
.
getOrDefault
(
OperationType
.
INSERT
.
getCode
(),
Collections
.
emptyList
());
result
.
setBusinessEntityUpdate
(
buildHouseTypeBuckets
(
entityDetails
,
OperationType
.
UPDATE
.
getCode
(),
true
));
List
<
String
>
entityUpdateIds
=
entityIdsByOp
.
getOrDefault
(
OperationType
.
UPDATE
.
getCode
(),
Collections
.
emptyList
());
result
.
setBusinessEntityDelete
(
buildHouseTypeBucketsFromCount
(
entityDeleteRows
));
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
);
return
result
;
return
result
;
}
}
...
...
ruoyi-system/src/main/resources/mapper/house/HouseResourceMapper.xml
View file @
a33a8369
...
@@ -1005,47 +1005,43 @@
...
@@ -1005,47 +1005,43 @@
</select>
</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 本身必须存活;
* 这里的 type 取自关联房源 hr2.type(经营主体本身无 type 字段)。一个 entity 关联到多种 type
* EXISTS 子查询**恒生效**:要求经营主体至少关联到一条"有效 mapping + 有效 house",
的房源时,会在对应的多个桶里分别出现一次(DISTINCT 已对 (type, operation_type, subject_id) 去重)。
否则 drilldown 侧展示不出来,也就不计入 dataCollection。这样保证 dataCollection 返回的
* INNER JOIN 链路:bei → mapping → house_resource,且三者都要求 delete_flag = 0,与
id 列表都能在 /api/house/page?businessEntityInfoIds=... 里查到对应行。
pageHouseResources 的 drilldown 口径一致,保证 dataCollection 返回的每个 id 在
* 传 two/three/four/wgCodes 时,EXISTS 内部按网格进一步收紧。
/api/house/page?businessEntityInfoIds=...&wgType=type 里都能查到对应行。
* 传 two/three/four/wgCodes 时,按网格进一步收紧 hr2。
-->
-->
<select
id=
"selectBusinessEntityChangeDetails"
<select
id=
"selectBusinessEntityChangeDetails"
resultType=
"com.ruoyi.system.domain.house.vo.HouseResourceDataCollectionDetailRow"
>
resultType=
"com.ruoyi.system.domain.house.vo.HouseResourceDataCollectionDetailRow"
>
SELECT DISTINCT
SELECT DISTINCT
0
AS type,
hr2.type
AS type,
dcr.operation_type AS operationType,
dcr.operation_type AS operationType,
dcr.subject_id AS subjectId
dcr.subject_id AS subjectId
FROM data_change_record dcr
FROM data_change_record dcr
INNER JOIN business_entity_info bei ON bei.id = dcr.subject_id AND bei.delete_flag = 0
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'
WHERE dcr.subject_type = 'BUSINESS_ENTITY_INFO'
AND dcr.operation_type IN (1, 2)
AND dcr.operation_type IN (1, 2)
AND dcr.operation_time
<![CDATA[ >= ]]>
#{query.changeStartTime}
AND dcr.operation_time
<![CDATA[ >= ]]>
#{query.changeStartTime}
AND dcr.operation_time
<![CDATA[ <= ]]>
#{query.changeEndTime}
AND dcr.operation_time
<![CDATA[ <= ]]>
#{query.changeEndTime}
AND EXISTS (
<if
test=
"query.two != null and query.two != ''"
>
SELECT 1
AND hr2.two = #{query.two}
FROM house_resource_business_entity_info_mapping m
</if>
INNER JOIN house_resource hr2 ON hr2.id = m.house_resource_id AND hr2.delete_flag = 0
<if
test=
"query.three != null and query.three != ''"
>
WHERE m.business_entity_info_id = bei.id
AND hr2.three = #{query.three}
AND m.delete_flag = 0
</if>
<if
test=
"query.two != null and query.two != ''"
>
<if
test=
"query.four != null and query.four != ''"
>
AND hr2.two = #{query.two}
AND hr2.four = #{query.four}
</if>
</if>
<if
test=
"query.three != null and query.three != ''"
>
<if
test=
"query.wgCodes != null and query.wgCodes.size() > 0"
>
AND hr2.three = #{query.three}
AND hr2.two IN
</if>
<foreach
collection=
"query.wgCodes"
item=
"wg"
open=
"("
separator=
","
close=
")"
>
#{wg}
</foreach>
<if
test=
"query.four != null and query.four != ''"
>
</if>
AND hr2.four = #{query.four}
</if>
<if
test=
"query.wgCodes != null and query.wgCodes.size() > 0"
>
AND hr2.two IN
<foreach
collection=
"query.wgCodes"
item=
"wg"
open=
"("
separator=
","
close=
")"
>
#{wg}
</foreach>
</if>
)
</select>
</select>
<!--
<!--
...
@@ -1054,41 +1050,41 @@
...
@@ -1054,41 +1050,41 @@
匹配网格的房源"即计入,覆盖"经营主体删除前房源或 mapping 已经被解除"的场景。
匹配网格的房源"即计入,覆盖"经营主体删除前房源或 mapping 已经被解除"的场景。
-->
-->
<!--
<!--
时间窗内经营主体(BUSINESS_ENTITY_INFO)被删除的数量。
时间窗内经营主体(BUSINESS_ENTITY_INFO)被删除的数量,按关联房源 hr2.type 分组。
与 insert/update 口径保持一致:EXISTS 恒生效,要求经营主体历史上至少关联过某个房源(不限
delete_flag,因为被删的 entity 本身的 mapping/house 也可能已被删)。这样"从未挂过房源"的
与 insert/update 口径保持一致:INNER JOIN 链路 bei → mapping → house_resource 恒生效,
孤儿 entity 不计入删除数,保证和看得见的业务实体口径统一。
要求经营主体历史上至少关联过某个房源;但 mapping / hr2 **不**限 delete_flag,因为被删除
的 entity 其 mapping/house 可能也已逻辑删除。一个 entity 若关联过多种 type 的房源,会在
对应的多个 type 桶里分别被 COUNT DISTINCT 计入一次(聚合层面)。"从未挂过房源"的孤儿
entity 不计入删除数,保证和看得见的业务口径统一。
-->
-->
<select
id=
"selectBusinessEntityDeleteCount"
<select
id=
"selectBusinessEntityDeleteCount"
resultType=
"com.ruoyi.system.domain.house.vo.HouseResourceDataCollectionRow"
>
resultType=
"com.ruoyi.system.domain.house.vo.HouseResourceDataCollectionRow"
>
SELECT
SELECT
0
AS type,
hr2.type
AS type,
3 AS operationType,
3 AS operationType,
COUNT(DISTINCT dcr.subject_id) AS count
COUNT(DISTINCT dcr.subject_id) AS count
FROM data_change_record dcr
FROM data_change_record dcr
INNER JOIN business_entity_info bei ON bei.id = dcr.subject_id
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'
WHERE dcr.subject_type = 'BUSINESS_ENTITY_INFO'
AND dcr.operation_type = 3
AND dcr.operation_type = 3
AND dcr.operation_time
<![CDATA[ >= ]]>
#{query.changeStartTime}
AND dcr.operation_time
<![CDATA[ >= ]]>
#{query.changeStartTime}
AND dcr.operation_time
<![CDATA[ <= ]]>
#{query.changeEndTime}
AND dcr.operation_time
<![CDATA[ <= ]]>
#{query.changeEndTime}
AND EXISTS (
<if
test=
"query.two != null and query.two != ''"
>
SELECT 1
AND hr2.two = #{query.two}
FROM house_resource_business_entity_info_mapping m
</if>
INNER JOIN house_resource hr2 ON hr2.id = m.house_resource_id
<if
test=
"query.three != null and query.three != ''"
>
WHERE m.business_entity_info_id = bei.id
AND hr2.three = #{query.three}
<if
test=
"query.two != null and query.two != ''"
>
</if>
AND hr2.two = #{query.two}
<if
test=
"query.four != null and query.four != ''"
>
</if>
AND hr2.four = #{query.four}
<if
test=
"query.three != null and query.three != ''"
>
</if>
AND hr2.three = #{query.three}
<if
test=
"query.wgCodes != null and query.wgCodes.size() > 0"
>
</if>
AND hr2.two IN
<if
test=
"query.four != null and query.four != ''"
>
<foreach
collection=
"query.wgCodes"
item=
"wg"
open=
"("
separator=
","
close=
")"
>
#{wg}
</foreach>
AND hr2.four = #{query.four}
</if>
</if>
GROUP BY hr2.type
<if
test=
"query.wgCodes != null and query.wgCodes.size() > 0"
>
AND hr2.two IN
<foreach
collection=
"query.wgCodes"
item=
"wg"
open=
"("
separator=
","
close=
")"
>
#{wg}
</foreach>
</if>
)
</select>
</select>
</mapper>
</mapper>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment