package com.imutil.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.imutil.entity.UsageStat; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Param; import java.time.OffsetDateTime; /** * 用量统计 Mapper *

* 提供按小时窗口的聚合 upsert(PG ON CONFLICT 幂等,可重复跑)。 * 两个数据源各自 upsert 指定列,避免互相覆盖: * - im_message → im_msg_count / im_dau * - api_call_log → api_call_count * * @author imutil */ public interface UsageStatMapper extends BaseMapper { /** * 从 im_message 聚合某小时窗口的消息量与活跃用户数,upsert 到 usage_stat(stat_level=1 小时) *

* 仅更新 im_msg_count / im_dau,不触碰已有 api_call_count。 * * @param start 窗口起点(含) * @param end 窗口终点(不含) * @param statTime 统计时刻(=窗口起点整点,作为 usage_stat.stat_time) * @return 受影响租户数 */ @Insert("INSERT INTO usage_stat (tenant_id, stat_time, stat_level, im_msg_count, im_dau, " + "api_call_count, trtc_duration_sec, trtc_max_concurrent_room, created_at) " + "SELECT tenant_id, #{statTime}, 1, count(*), count(DISTINCT from_account), 0, 0, 0, now() " + "FROM im_message WHERE created_at >= #{start} AND created_at < #{end} " + "GROUP BY tenant_id " + "ON CONFLICT (tenant_id, stat_time, stat_level) DO UPDATE SET " + "im_msg_count = EXCLUDED.im_msg_count, im_dau = EXCLUDED.im_dau") int aggregateMsgHour(@Param("start") OffsetDateTime start, @Param("end") OffsetDateTime end, @Param("statTime") OffsetDateTime statTime); /** * 从 api_call_log 聚合某小时窗口的腾讯 API 调用次数,upsert 到 usage_stat(stat_level=1 小时) *

* 仅更新 api_call_count,不触碰已有 im_msg_count / im_dau。 * * @return 受影响租户数 */ @Insert("INSERT INTO usage_stat (tenant_id, stat_time, stat_level, im_msg_count, im_dau, " + "api_call_count, trtc_duration_sec, trtc_max_concurrent_room, created_at) " + "SELECT tenant_id, #{statTime}, 1, 0, 0, count(*), 0, 0, now() " + "FROM api_call_log WHERE called_at >= #{start} AND called_at < #{end} " + "GROUP BY tenant_id " + "ON CONFLICT (tenant_id, stat_time, stat_level) DO UPDATE SET " + "api_call_count = EXCLUDED.api_call_count") int aggregateApiCallHour(@Param("start") OffsetDateTime start, @Param("end") OffsetDateTime end, @Param("statTime") OffsetDateTime statTime); }