package com.emotion.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.emotion.dto.response.analytics.AnalyticsPreferenceItem; import com.emotion.dto.response.analytics.AnalyticsTopEventItem; import com.emotion.dto.response.analytics.AnalyticsTrendItem; import com.emotion.dto.response.analytics.AnalyticsUserItem; import com.emotion.entity.AnalyticsEvent; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import java.time.LocalDateTime; import java.util.List; @Mapper public interface AnalyticsEventMapper extends BaseMapper { @Select("SELECT COUNT(*) FROM t_analytics_event WHERE is_deleted = 0 AND occurred_at >= #{start} AND occurred_at < #{end}") Long countAll(@Param("start") LocalDateTime start, @Param("end") LocalDateTime end); @Select("SELECT COUNT(*) FROM t_analytics_event WHERE is_deleted = 0 AND event_name = #{eventName} AND occurred_at >= #{start} AND occurred_at < #{end}") Long countEvent(@Param("eventName") String eventName, @Param("start") LocalDateTime start, @Param("end") LocalDateTime end); @Select("SELECT COUNT(DISTINCT COALESCE(user_id, anonymous_id)) FROM t_analytics_event WHERE is_deleted = 0 AND occurred_at >= #{start} AND occurred_at < #{end} AND COALESCE(user_id, anonymous_id) IS NOT NULL") Long countUniqueVisitors(@Param("start") LocalDateTime start, @Param("end") LocalDateTime end); @Select("SELECT COUNT(DISTINCT COALESCE(user_id, anonymous_id)) FROM t_analytics_event WHERE is_deleted = 0 AND user_id IS NOT NULL AND occurred_at >= #{start} AND occurred_at < #{end}") Long countActiveUsers(@Param("start") LocalDateTime start, @Param("end") LocalDateTime end); @Select("SELECT COALESCE(AVG(duration_ms), 0) FROM t_analytics_event WHERE is_deleted = 0 AND event_name = 'page_leave' AND duration_ms IS NOT NULL AND duration_ms >= 0 AND occurred_at >= #{start} AND occurred_at < #{end}") Double avgStayMs(@Param("start") LocalDateTime start, @Param("end") LocalDateTime end); @Select("SELECT event_name AS eventName, event_type AS eventType, page_path AS pagePath, " + "JSON_UNQUOTE(JSON_EXTRACT(properties, '$.api_path')) AS apiPath, " + "COUNT(*) AS count, COUNT(DISTINCT COALESCE(user_id, anonymous_id)) AS users " + "FROM t_analytics_event WHERE is_deleted = 0 AND occurred_at >= #{start} AND occurred_at < #{end} " + "GROUP BY event_name, event_type, page_path, JSON_UNQUOTE(JSON_EXTRACT(properties, '$.api_path')) " + "ORDER BY count DESC LIMIT #{limit}") List selectTopEvents(@Param("start") LocalDateTime start, @Param("end") LocalDateTime end, @Param("limit") int limit); @Select("SELECT DATE_FORMAT(occurred_at, #{dateFormat}) AS bucket, event_name AS eventName, COUNT(*) AS count, COUNT(DISTINCT COALESCE(user_id, anonymous_id)) AS users " + "FROM t_analytics_event WHERE is_deleted = 0 AND occurred_at >= #{start} AND occurred_at < #{end} " + "GROUP BY DATE_FORMAT(occurred_at, #{dateFormat}), event_name ORDER BY bucket ASC, count DESC") List selectTrend(@Param("start") LocalDateTime start, @Param("end") LocalDateTime end, @Param("dateFormat") String dateFormat); @Select("SELECT event_name AS eventName, COUNT(DISTINCT COALESCE(user_id, anonymous_id)) AS users " + "FROM t_analytics_event WHERE is_deleted = 0 AND event_name IN ('app_launch', 'page_view', 'script_inspiration_click', 'script_generate_start', 'script_generate_success', 'script_detail_view', 'path_select', 'script_tts_play') " + "AND occurred_at >= #{start} AND occurred_at < #{end} AND COALESCE(user_id, anonymous_id) IS NOT NULL " + "GROUP BY event_name") List selectFunnelUsers(@Param("start") LocalDateTime start, @Param("end") LocalDateTime end); @Select("SELECT #{dimension} AS dimension, JSON_UNQUOTE(JSON_EXTRACT(properties, CONCAT('$.', #{dimension}))) AS value, COUNT(*) AS count, COUNT(DISTINCT COALESCE(user_id, anonymous_id)) AS users " + "FROM t_analytics_event WHERE is_deleted = 0 AND properties IS NOT NULL AND occurred_at >= #{start} AND occurred_at < #{end} " + "GROUP BY JSON_UNQUOTE(JSON_EXTRACT(properties, CONCAT('$.', #{dimension}))) " + "HAVING value IS NOT NULL AND value <> '' ORDER BY count DESC LIMIT #{limit}") List selectPreference(@Param("dimension") String dimension, @Param("start") LocalDateTime start, @Param("end") LocalDateTime end, @Param("limit") int limit); @Select("SELECT user_id AS userId, anonymous_id AS anonymousId, COUNT(*) AS eventCount, MAX(occurred_at) AS lastActiveTime " + "FROM t_analytics_event WHERE is_deleted = 0 AND occurred_at >= #{start} AND occurred_at < #{end} " + "GROUP BY user_id, anonymous_id ORDER BY eventCount DESC, lastActiveTime DESC LIMIT #{limit}") List selectUsers(@Param("start") LocalDateTime start, @Param("end") LocalDateTime end, @Param("limit") int limit); }