add totalNumberValue for rank

This commit is contained in:
Timi
2026-08-14 18:58:04 +08:00
parent ab4a164680
commit 457e716b38
4 changed files with 174 additions and 130 deletions
@@ -282,13 +282,29 @@ public class GaoEventRecordServiceImplement extends AbstractEntityService<GaoEve
@Override @Override
public PageResult<GaoCustomerEventRankView> pageRankByRange(GaoEventRecordRankPage page) { public PageResult<GaoCustomerEventRankView> pageRankByRange(GaoEventRecordRankPage page) {
TimiException.required(page.getStoreId(), "not found page.storeId"); TimiException.required(page.getStoreId(), "not found page.storeId");
validateRankPage(page);
if (page.getRankType() == GaoEventRecordRankPage.RankType.CONTINUOUS_DAYS) {
page.setTodayDateValue(dateValue(Time.now())); page.setTodayDateValue(dateValue(Time.now()));
}
PageResult<GaoCustomerEventRankView> result = new PageResult<>(); PageResult<GaoCustomerEventRankView> result = new PageResult<>();
result.setTotal(mapper.countRankByRange(page)); result.setTotal(mapper.countRankByRange(page));
result.setList(mapper.selectRankByRange(page)); result.setList(mapper.selectRankByRange(page));
return result; return result;
} }
/// 校验登记数值排行的事件范围
///
/// @param page 排行榜查询请求
private void validateRankPage(GaoEventRecordRankPage page) {
if (page.getRankType() != GaoEventRecordRankPage.RankType.TOTAL_NUMBER_VALUE) {
return;
}
List<String> eventIdList = page.getEventIdList();
TimiException.requiredTrue(eventIdList != null && eventIdList.size() == 1, "按登记数值排行必须选择单个事件");
GaoEvent event = eventService.mapByIdList(eventIdList).get(eventIdList.get(0));
TimiException.requiredTrue(event != null && event.getValueType() == GaoEvent.ValueType.NUMBER, "按登记数值排行只能选择 NUMBER 事件");
}
private void checkEventPermission(GaoEvent event) { private void checkEventPermission(GaoEvent event) {
List<String> roleCodeList = eventService.listRoleCode(event.getId()); List<String> roleCodeList = eventService.listRoleCode(event.getId());
TimiException.requiredTrue(roleCodeList != null && !roleCodeList.isEmpty(), "登记事件未配置可登记角色"); TimiException.requiredTrue(roleCodeList != null && !roleCodeList.isEmpty(), "登记事件未配置可登记角色");
@@ -29,6 +29,9 @@ public class GaoCustomerEventRankView {
/// 最近连续登记天数 /// 最近连续登记天数
private Long recentContinuousEventDays; private Long recentContinuousEventDays;
/// 登记数值合计
private Long totalNumberValue;
/// 最后登记时间 /// 最后登记时间
private Long latestRegisteredAt; private Long latestRegisteredAt;
} }
@@ -41,6 +41,8 @@ public class GaoEventRecordRankPage extends BasePage {
/// 按累计登记次数 /// 按累计登记次数
TOTAL_COUNT, TOTAL_COUNT,
/// 按最近连续登记天数 /// 按最近连续登记天数
CONTINUOUS_DAYS CONTINUOUS_DAYS,
/// 按登记数值合计
TOTAL_NUMBER_VALUE
} }
} }
@@ -160,6 +160,9 @@
#{eventId} #{eventId}
</foreach> </foreach>
</if> </if>
<if test="rankType != null and rankType.name() == 'TOTAL_NUMBER_VALUE'">
AND r.`number_value` IS NOT NULL
</if>
</sql> </sql>
<select id="countRankByRange" resultType="long"> <select id="countRankByRange" resultType="long">
SELECT SELECT
@@ -170,12 +173,69 @@
<include refid="rankWhere"/> <include refid="rankWhere"/>
</select> </select>
<select id="selectRankByRange" resultType="com.imyeyu.api.modules.gao.vo.GaoCustomerEventRankView"> <select id="selectRankByRange" resultType="com.imyeyu.api.modules.gao.vo.GaoCustomerEventRankView">
<choose>
<when test="rankType == null or rankType.name() == 'TOTAL_DAYS'">
SELECT
ROW_NUMBER() OVER (
ORDER BY COUNT(DISTINCT r.`registered_date_value`) DESC, r.`customer_id`
) AS `rank`,
r.`customer_id` AS `customerId`,
COUNT(DISTINCT r.`registered_date_value`) AS `totalEventDays`,
NULL AS `totalEventCount`,
NULL AS `recentContinuousEventDays`,
NULL AS `totalNumberValue`,
NULL AS `latestRegisteredAt`
FROM `gao_event_record` r
LEFT JOIN `gao_customer` c ON r.`customer_id` = c.`id`
WHERE
<include refid="rankWhere"/>
GROUP BY r.`customer_id`
ORDER BY `rank`
LIMIT #{offset}, #{limit}
</when>
<when test="rankType.name() == 'TOTAL_COUNT'">
SELECT
ROW_NUMBER() OVER (
ORDER BY COUNT(1) DESC, r.`customer_id`
) AS `rank`,
r.`customer_id` AS `customerId`,
NULL AS `totalEventDays`,
COUNT(1) AS `totalEventCount`,
NULL AS `recentContinuousEventDays`,
NULL AS `totalNumberValue`,
NULL AS `latestRegisteredAt`
FROM `gao_event_record` r
LEFT JOIN `gao_customer` c ON r.`customer_id` = c.`id`
WHERE
<include refid="rankWhere"/>
GROUP BY r.`customer_id`
ORDER BY `rank`
LIMIT #{offset}, #{limit}
</when>
<when test="rankType.name() == 'TOTAL_NUMBER_VALUE'">
SELECT
ROW_NUMBER() OVER (
ORDER BY SUM(r.`number_value`) DESC, r.`customer_id`
) AS `rank`,
r.`customer_id` AS `customerId`,
NULL AS `totalEventDays`,
NULL AS `totalEventCount`,
NULL AS `recentContinuousEventDays`,
SUM(r.`number_value`) AS `totalNumberValue`,
NULL AS `latestRegisteredAt`
FROM `gao_event_record` r
LEFT JOIN `gao_customer` c ON r.`customer_id` = c.`id`
WHERE
<include refid="rankWhere"/>
GROUP BY r.`customer_id`
ORDER BY `rank`
LIMIT #{offset}, #{limit}
</when>
<otherwise>
WITH RECURSIVE `daily_stat` AS ( WITH RECURSIVE `daily_stat` AS (
SELECT SELECT
r.`customer_id` AS `customerId`, r.`customer_id` AS `customerId`,
r.`registered_date_value` AS `registeredDateValue`, r.`registered_date_value` AS `registeredDateValue`
COUNT(1) AS `dailyCount`,
MAX(r.`registered_at`) AS `latestRegisteredAt`
FROM `gao_event_record` r FROM `gao_event_record` r
LEFT JOIN `gao_customer` c ON r.`customer_id` = c.`id` LEFT JOIN `gao_customer` c ON r.`customer_id` = c.`id`
WHERE WHERE
@@ -216,15 +276,6 @@
AND b.`deleted_at` IS NULL AND b.`deleted_at` IS NULL
WHERE COALESCE(b.`status`, 'OPEN') != 'CLOSED' WHERE COALESCE(b.`status`, 'OPEN') != 'CLOSED'
), ),
`rank_stat` AS (
SELECT
`customerId`,
COUNT(1) AS `totalEventDays`,
SUM(`dailyCount`) AS `totalEventCount`,
MAX(`latestRegisteredAt`) AS `latestRegisteredAt`
FROM `daily_stat`
GROUP BY `customerId`
),
`continuous_ordered` AS ( `continuous_ordered` AS (
SELECT SELECT
d.`customerId`, d.`customerId`,
@@ -253,51 +304,23 @@
AND 1 = 0 AND 1 = 0
</if> </if>
GROUP BY o.`customerId` GROUP BY o.`customerId`
),
`ranked` AS (
SELECT
ROW_NUMBER() OVER (
ORDER BY
<choose>
<when test="rankType != null and rankType.name() == 'TOTAL_COUNT'">
r.`totalEventCount` DESC,
r.`totalEventDays` DESC,
r.`latestRegisteredAt` DESC,
r.`customerId`
</when>
<when test="rankType != null and rankType.name() == 'CONTINUOUS_DAYS'">
COALESCE(c.`recentContinuousEventDays`, 0) DESC,
r.`totalEventDays` DESC,
r.`totalEventCount` DESC,
r.`latestRegisteredAt` DESC,
r.`customerId`
</when>
<otherwise>
r.`totalEventDays` DESC,
r.`totalEventCount` DESC,
r.`latestRegisteredAt` DESC,
r.`customerId`
</otherwise>
</choose>
) AS `rank`,
r.`customerId`,
r.`totalEventDays`,
r.`totalEventCount`,
COALESCE(c.`recentContinuousEventDays`, 0) AS `recentContinuousEventDays`,
r.`latestRegisteredAt`
FROM `rank_stat` r
LEFT JOIN `continuous_stat` c ON r.`customerId` = c.`customerId`
) )
SELECT SELECT
`rank`, ROW_NUMBER() OVER (
`customerId`, ORDER BY COALESCE(c.`recentContinuousEventDays`, 0) DESC, r.`customerId`
`totalEventDays`, ) AS `rank`,
`totalEventCount`, r.`customerId`,
`recentContinuousEventDays`, NULL AS `totalEventDays`,
`latestRegisteredAt` NULL AS `totalEventCount`,
FROM `ranked` COALESCE(c.`recentContinuousEventDays`, 0) AS `recentContinuousEventDays`,
NULL AS `totalNumberValue`,
NULL AS `latestRegisteredAt`
FROM (SELECT DISTINCT `customerId` FROM `daily_stat`) r
LEFT JOIN `continuous_stat` c ON r.`customerId` = c.`customerId`
ORDER BY `rank` ORDER BY `rank`
LIMIT #{offset}, #{limit} LIMIT #{offset}, #{limit}
</otherwise>
</choose>
</select> </select>
<sql id="storeChartRangeWhere"> <sql id="storeChartRangeWhere">