Commit b9f20ac9 authored by lixuan's avatar lixuan

feat: 需求

parent 92e4a0d5
Pipeline #147340 failed with stages
in 0 seconds
...@@ -10,12 +10,14 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -10,12 +10,14 @@ import org.springframework.web.bind.annotation.RestController;
/** /**
* 字段级变更统计对外接口。 * 字段级变更统计对外接口。
* *
* <p>房源侧和经营主体侧完全分开的 4 个 GET 接口:</p> * <p>房源侧、经营主体侧、涉及房源侧的 GET 接口:</p>
* <ul> * <ul>
* <li>{@code /houseResource}:HR 侧明细分页</li> * <li>{@code /houseResource}:HR 侧明细分页</li>
* <li>{@code /houseResource/summary}:HR 侧按字段 + 操作的计数</li> * <li>{@code /houseResource/summary}:HR 侧按字段 + 操作的计数</li>
* <li>{@code /businessEntity}:BE 侧明细分页(展开每个关联房源)</li> * <li>{@code /businessEntity}:BE 侧明细分页(展开每个关联房源)</li>
* <li>{@code /businessEntity/summary}:BE 侧汇总(按日志去重)</li> * <li>{@code /businessEntity/summary}:BE 侧汇总(按日志去重)</li>
* <li>{@code /affectedHouseResources}:HR + BE 涉及房源分页(按房源去重)</li>
* <li>{@code /affectedHouseResources/summary}:HR + BE 涉及房源汇总(按房源去重)</li>
* </ul> * </ul>
* *
* <p>入参形态详见 {@link FieldChangeRecordQuery}。{@code changeStartTime / * <p>入参形态详见 {@link FieldChangeRecordQuery}。{@code changeStartTime /
...@@ -50,4 +52,14 @@ public class DataFieldChangeRecordController { ...@@ -50,4 +52,14 @@ public class DataFieldChangeRecordController {
public AjaxResult summaryBusinessEntity(FieldChangeRecordQuery query) { public AjaxResult summaryBusinessEntity(FieldChangeRecordQuery query) {
return AjaxResult.success(service.summaryBusinessEntityFieldChanges(query)); return AjaxResult.success(service.summaryBusinessEntityFieldChanges(query));
} }
@GetMapping("/affectedHouseResources")
public AjaxResult pageAffectedHouseResources(FieldChangeRecordQuery query) {
return AjaxResult.success(service.pageAffectedHouseResources(query));
}
@GetMapping("/affectedHouseResources/summary")
public AjaxResult summaryAffectedHouseResources(FieldChangeRecordQuery query) {
return AjaxResult.success(service.summaryAffectedHouseResources(query));
}
} }
...@@ -43,6 +43,9 @@ public enum FieldCode { ...@@ -43,6 +43,9 @@ public enum FieldCode {
HR_BUSINESS_STATUS(SubjectType.HOUSE_RESOURCE, FieldValueType.ENUM, HR_BUSINESS_STATUS(SubjectType.HOUSE_RESOURCE, FieldValueType.ENUM,
"businessStatus", "经营场所状态"), "businessStatus", "经营场所状态"),
HR_RESOURCE_TYPE(SubjectType.HOUSE_RESOURCE, FieldValueType.ENUM,
"houseResourceType", "房源类型"),
HR_AREA(SubjectType.HOUSE_RESOURCE, FieldValueType.NUMBER, HR_AREA(SubjectType.HOUSE_RESOURCE, FieldValueType.NUMBER,
"houseArea", "经营场所面积"), "houseArea", "经营场所面积"),
......
package com.ruoyi.system.mapper.fieldchangerecord; package com.ruoyi.system.mapper.fieldchangerecord;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ruoyi.system.domain.fieldchangerecord.vo.FieldChangeAffectedHouseResourceVO;
import com.ruoyi.system.domain.fieldchangerecord.vo.FieldChangeRecordQuery; import com.ruoyi.system.domain.fieldchangerecord.vo.FieldChangeRecordQuery;
import com.ruoyi.system.domain.fieldchangerecord.vo.FieldChangeRecordVO; import com.ruoyi.system.domain.fieldchangerecord.vo.FieldChangeRecordVO;
import com.ruoyi.system.domain.fieldchangerecord.vo.FieldChangeSummaryRow; import com.ruoyi.system.domain.fieldchangerecord.vo.FieldChangeSummaryRow;
...@@ -12,8 +13,8 @@ import java.util.List; ...@@ -12,8 +13,8 @@ import java.util.List;
* 字段级变更查询 Mapper。 * 字段级变更查询 Mapper。
* *
* <p>和 {@link DataFieldChangeRecordMapper}(只负责 batchInsert)分开,职责清晰: * <p>和 {@link DataFieldChangeRecordMapper}(只负责 batchInsert)分开,职责清晰:
* 写入用拦截器走 batchInsert;读取由此 Mapper 承担,包含 HR 侧和 BE 侧两条 * 写入用拦截器走 batchInsert;读取由此 Mapper 承担,包含 HR 侧、BE 侧、
* 完全独立的查询路径。</p> * 涉及房源侧的查询路径。</p>
*/ */
public interface DataFieldChangeRecordQueryMapper { public interface DataFieldChangeRecordQueryMapper {
...@@ -34,4 +35,13 @@ public interface DataFieldChangeRecordQueryMapper { ...@@ -34,4 +35,13 @@ public interface DataFieldChangeRecordQueryMapper {
/** BE 侧汇总。为避免 JOIN 膨胀,对日志 id 做 distinct 计数。 */ /** BE 侧汇总。为避免 JOIN 膨胀,对日志 id 做 distinct 计数。 */
List<FieldChangeSummaryRow> selectBusinessEntityFieldChangeSummary( List<FieldChangeSummaryRow> selectBusinessEntityFieldChangeSummary(
@Param("query") FieldChangeRecordQuery query); @Param("query") FieldChangeRecordQuery query);
/** 字段变更涉及房源分页。HR 直接取房源,BE 通过 mapping 找房源,最终按房源去重。 */
IPage<FieldChangeAffectedHouseResourceVO> selectAffectedHouseResources(
IPage<FieldChangeAffectedHouseResourceVO> page,
@Param("query") FieldChangeRecordQuery query);
/** 字段变更涉及房源汇总。按 operationType 统计去重房源数。 */
List<FieldChangeSummaryRow> selectAffectedHouseResourceSummary(
@Param("query") FieldChangeRecordQuery query);
} }
...@@ -21,6 +21,7 @@ public interface HouseResourceMapper { ...@@ -21,6 +21,7 @@ public interface HouseResourceMapper {
idExpr = "id", idExpr = "id",
fields = { fields = {
FieldCode.HR_BUSINESS_STATUS, FieldCode.HR_BUSINESS_STATUS,
FieldCode.HR_RESOURCE_TYPE,
FieldCode.HR_AREA, FieldCode.HR_AREA,
FieldCode.HR_EQUITY_TEL, FieldCode.HR_EQUITY_TEL,
FieldCode.HR_UNIT_PRICE, FieldCode.HR_UNIT_PRICE,
...@@ -40,6 +41,7 @@ public interface HouseResourceMapper { ...@@ -40,6 +41,7 @@ public interface HouseResourceMapper {
preLoadMapper = "com.ruoyi.system.mapper.house.HouseResourceMapper.selectHouseResourceById", preLoadMapper = "com.ruoyi.system.mapper.house.HouseResourceMapper.selectHouseResourceById",
fields = { fields = {
FieldCode.HR_BUSINESS_STATUS, FieldCode.HR_BUSINESS_STATUS,
FieldCode.HR_RESOURCE_TYPE,
FieldCode.HR_AREA, FieldCode.HR_AREA,
FieldCode.HR_EQUITY_TEL, FieldCode.HR_EQUITY_TEL,
FieldCode.HR_UNIT_PRICE, FieldCode.HR_UNIT_PRICE,
...@@ -59,6 +61,7 @@ public interface HouseResourceMapper { ...@@ -59,6 +61,7 @@ public interface HouseResourceMapper {
idExpr = "list[*].id", idExpr = "list[*].id",
fields = { fields = {
FieldCode.HR_BUSINESS_STATUS, FieldCode.HR_BUSINESS_STATUS,
FieldCode.HR_RESOURCE_TYPE,
FieldCode.HR_AREA, FieldCode.HR_AREA,
FieldCode.HR_EQUITY_TEL, FieldCode.HR_EQUITY_TEL,
FieldCode.HR_UNIT_PRICE, FieldCode.HR_UNIT_PRICE,
......
package com.ruoyi.system.service.fieldchangerecord; package com.ruoyi.system.service.fieldchangerecord;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ruoyi.system.domain.fieldchangerecord.vo.FieldChangeAffectedHouseResourceVO;
import com.ruoyi.system.domain.fieldchangerecord.vo.FieldChangeRecordQuery; import com.ruoyi.system.domain.fieldchangerecord.vo.FieldChangeRecordQuery;
import com.ruoyi.system.domain.fieldchangerecord.vo.FieldChangeRecordVO; import com.ruoyi.system.domain.fieldchangerecord.vo.FieldChangeRecordVO;
import com.ruoyi.system.domain.fieldchangerecord.vo.FieldChangeSummaryRow; import com.ruoyi.system.domain.fieldchangerecord.vo.FieldChangeSummaryRow;
...@@ -22,4 +23,8 @@ public interface DataFieldChangeRecordService { ...@@ -22,4 +23,8 @@ public interface DataFieldChangeRecordService {
IPage<FieldChangeRecordVO> pageBusinessEntityFieldChanges(FieldChangeRecordQuery query); IPage<FieldChangeRecordVO> pageBusinessEntityFieldChanges(FieldChangeRecordQuery query);
List<FieldChangeSummaryRow> summaryBusinessEntityFieldChanges(FieldChangeRecordQuery query); List<FieldChangeSummaryRow> summaryBusinessEntityFieldChanges(FieldChangeRecordQuery query);
IPage<FieldChangeAffectedHouseResourceVO> pageAffectedHouseResources(FieldChangeRecordQuery query);
List<FieldChangeSummaryRow> summaryAffectedHouseResources(FieldChangeRecordQuery query);
} }
...@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; ...@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.domain.changerecord.enums.SubjectType; import com.ruoyi.system.domain.changerecord.enums.SubjectType;
import com.ruoyi.system.domain.fieldchangerecord.enums.FieldCode; import com.ruoyi.system.domain.fieldchangerecord.enums.FieldCode;
import com.ruoyi.system.domain.fieldchangerecord.vo.FieldChangeAffectedHouseResourceVO;
import com.ruoyi.system.domain.fieldchangerecord.vo.FieldChangeRecordQuery; import com.ruoyi.system.domain.fieldchangerecord.vo.FieldChangeRecordQuery;
import com.ruoyi.system.domain.fieldchangerecord.vo.FieldChangeRecordVO; import com.ruoyi.system.domain.fieldchangerecord.vo.FieldChangeRecordVO;
import com.ruoyi.system.domain.fieldchangerecord.vo.FieldChangeSummaryRow; import com.ruoyi.system.domain.fieldchangerecord.vo.FieldChangeSummaryRow;
...@@ -28,7 +29,8 @@ import java.util.stream.Collectors; ...@@ -28,7 +29,8 @@ import java.util.stream.Collectors;
* <ul> * <ul>
* <li>参数校验(时间范围必填、start &lt;= end);</li> * <li>参数校验(时间范围必填、start &lt;= end);</li>
* <li>注入登录人网格权限 {@code wgCodes}(和 HR 侧 dataCollection 一致);</li> * <li>注入登录人网格权限 {@code wgCodes}(和 HR 侧 dataCollection 一致);</li>
* <li>当入参未指定 {@code fieldCodes} 时,补齐为当前主体侧的全部字段;</li> * <li>HR / BE 字段统计接口未指定 {@code fieldCodes} 时,补齐为当前主体侧的全部字段;</li>
* <li>涉及房源接口只按时间、操作类型、网格过滤,不按字段过滤;</li>
* <li>调用 Mapper 查询;</li> * <li>调用 Mapper 查询;</li>
* <li>回填 {@code fieldLabel} / {@code valueType}(从 {@link FieldCode} 反查)。</li> * <li>回填 {@code fieldLabel} / {@code valueType}(从 {@link FieldCode} 反查)。</li>
* </ul> * </ul>
...@@ -98,6 +100,24 @@ public class DataFieldChangeRecordServiceImpl implements DataFieldChangeRecordSe ...@@ -98,6 +100,24 @@ public class DataFieldChangeRecordServiceImpl implements DataFieldChangeRecordSe
return rows; return rows;
} }
@Override
public IPage<FieldChangeAffectedHouseResourceVO> pageAffectedHouseResources(FieldChangeRecordQuery query) {
validateTimeRange(query);
applyWgCodes(query);
Page<FieldChangeAffectedHouseResourceVO> page = new Page<>(
query.getPageNum() == null ? 1 : query.getPageNum(),
query.getPageSize() == null ? 20 : query.getPageSize());
return queryMapper.selectAffectedHouseResources(page, query);
}
@Override
public List<FieldChangeSummaryRow> summaryAffectedHouseResources(FieldChangeRecordQuery query) {
validateTimeRange(query);
applyWgCodes(query);
return queryMapper.selectAffectedHouseResourceSummary(query);
}
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
private void validateTimeRange(FieldChangeRecordQuery query) { private void validateTimeRange(FieldChangeRecordQuery query) {
......
...@@ -28,6 +28,23 @@ ...@@ -28,6 +28,23 @@
<result property="count" column="cnt"/> <result property="count" column="cnt"/>
</resultMap> </resultMap>
<resultMap id="FieldChangeAffectedHouseResourceVO"
type="com.ruoyi.system.domain.fieldchangerecord.vo.FieldChangeAffectedHouseResourceVO">
<id property="houseResourceId" column="house_resource_id"/>
<result property="houseResourceName" column="house_resource_name"/>
<result property="hrType" column="hr_type"/>
<result property="two" column="two"/>
<result property="wgName2" column="wg_name2"/>
<result property="three" column="three"/>
<result property="wgName3" column="wg_name3"/>
<result property="four" column="four"/>
<result property="wgName4" column="wg_name4"/>
<result property="latestOperationTime" column="latest_operation_time"/>
<result property="changeRecordCount" column="change_record_count"/>
<result property="insertCount" column="insert_count"/>
<result property="updateCount" column="update_count"/>
</resultMap>
<!-- ===================================================================== <!-- =====================================================================
HR 侧 HR 侧
===================================================================== --> ===================================================================== -->
...@@ -209,4 +226,137 @@ ...@@ -209,4 +226,137 @@
</where> </where>
</sql> </sql>
<!-- =====================================================================
HR + BE 涉及房源(按房源去重)
===================================================================== -->
<select id="selectAffectedHouseResources" resultMap="FieldChangeAffectedHouseResourceVO">
SELECT
a.house_resource_id,
CONCAT(IFNULL(hr.address, ''), IFNULL(hr.house_number, '')) AS house_resource_name,
hr.type AS hr_type,
hr.two,
g2.wg_name AS wg_name2,
hr.three,
g3.wg_name AS wg_name3,
hr.four,
g4.wg_name AS wg_name4,
a.latest_operation_time,
a.change_record_count,
a.insert_count,
a.update_count
FROM (
SELECT
u.house_resource_id,
MAX(u.operation_time) AS latest_operation_time,
COUNT(DISTINCT u.record_id) AS change_record_count,
COUNT(DISTINCT CASE WHEN u.operation_type = 1 THEN u.record_id END) AS insert_count,
COUNT(DISTINCT CASE WHEN u.operation_type = 2 THEN u.record_id END) AS update_count
FROM (
<include refid="affectedHouseResourceUnion"/>
) u
GROUP BY u.house_resource_id
) a
INNER JOIN house_resource hr ON hr.id = a.house_resource_id AND hr.delete_flag = 0
LEFT JOIN grid_region g2 ON g2.wg_code = hr.two AND g2.is_valid = '1'
LEFT JOIN grid_region g3 ON g3.wg_code = hr.three AND g3.is_valid = '1'
LEFT JOIN grid_region g4 ON g4.wg_code = hr.four AND g4.is_valid = '1'
ORDER BY a.latest_operation_time DESC, a.house_resource_id DESC
</select>
<select id="selectAffectedHouseResourceSummary" resultMap="FieldChangeSummaryRow">
SELECT
u.operation_type,
COUNT(DISTINCT u.house_resource_id) AS cnt
FROM (
<include refid="affectedHouseResourceUnion"/>
) u
GROUP BY u.operation_type
ORDER BY u.operation_type
</select>
<sql id="affectedHouseResourceUnion">
SELECT
r.id AS record_id,
r.operation_type,
hr.id AS house_resource_id,
r.operation_time
FROM data_field_change_record r
INNER JOIN house_resource hr ON hr.id = r.subject_id AND hr.delete_flag = 0
<where>
r.subject_type = 'HOUSE_RESOURCE'
<include refid="affectedRecordCommonWhere"/>
<include refid="affectedHouseResourceWhere"/>
</where>
UNION ALL
SELECT
r.id AS record_id,
r.operation_type,
hr2.id AS house_resource_id,
r.operation_time
FROM data_field_change_record r
INNER JOIN business_entity_info bei
ON bei.id = r.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>
r.subject_type = 'BUSINESS_ENTITY_INFO'
<include refid="affectedRecordCommonWhere"/>
<include refid="affectedBusinessEntityHouseResourceWhere"/>
</where>
</sql>
<sql id="affectedRecordCommonWhere">
<if test="query.changeStartTime != null">
AND r.operation_time &gt;= #{query.changeStartTime}
</if>
<if test="query.changeEndTime != null">
AND r.operation_time &lt;= #{query.changeEndTime}
</if>
<if test="query.operationTypes != null and query.operationTypes.size() > 0">
AND r.operation_type IN
<foreach collection="query.operationTypes" item="ot" open="(" separator="," close=")">
#{ot}
</foreach>
</if>
</sql>
<sql id="affectedHouseResourceWhere">
<if test="query.two != null and query.two != ''">
AND hr.two = #{query.two}
</if>
<if test="query.three != null and query.three != ''">
AND hr.three = #{query.three}
</if>
<if test="query.four != null and query.four != ''">
AND hr.four = #{query.four}
</if>
<if test="query.wgCodes != null and query.wgCodes.size() > 0">
AND hr.two IN
<foreach collection="query.wgCodes" item="wg" open="(" separator="," close=")">
#{wg}
</foreach>
</if>
</sql>
<sql id="affectedBusinessEntityHouseResourceWhere">
<if test="query.two != null and query.two != ''">
AND hr2.two = #{query.two}
</if>
<if test="query.three != null and query.three != ''">
AND hr2.three = #{query.three}
</if>
<if test="query.four != null and query.four != ''">
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>
</sql>
</mapper> </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