<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.ai.mapper.AiStatisticsMapper">
    
    <resultMap type="AiStatistics" id="AiStatisticsResult">
        <result property="dateKey"    column="date_key"    />
        <result property="source"    column="source"    />
        <result property="addUserCount"    column="add_user_count"    />
        <result property="visitorCount"    column="visitor_count"    />
        <result property="generateCount"    column="generate_count"    />
    </resultMap>

    <sql id="selectAiStatisticsVo">
        select date_key, source, add_user_count, visitor_count, generate_count from ai_statistics
    </sql>

    <select id="selectAiStatisticsList" parameterType="AiStatistics" resultMap="AiStatisticsResult">
        <include refid="selectAiStatisticsVo"/>
        <where>  
            <if test="addUserCount != null "> and add_user_count = #{addUserCount}</if>
            <if test="visitorCount != null "> and visitor_count = #{visitorCount}</if>
            <if test="generateCount != null "> and generate_count = #{generateCount}</if>
        </where>
    </select>
    
    <select id="selectAiStatisticsByDateKey" parameterType="String" resultMap="AiStatisticsResult">
        <include refid="selectAiStatisticsVo"/>
        where date_key = #{dateKey}
    </select>

    <select id="getTitleTotal" resultType="com.ruoyi.ai.domain.AiStatistics">
        SELECT
            -- 用户总数量
            (select COUNT(0) from ai_user) AS totalUserCount,
            SUM(CASE WHEN DATE_FORMAT(date_key, '%Y-%m-%d') = CURDATE() THEN add_user_count ELSE 0 END) AS todayAddUserCount,
            -- 今日访客数量（visitor_count 今日总和）
            SUM(CASE WHEN DATE_FORMAT(date_key, '%Y-%m-%d') = CURDATE() THEN visitor_count ELSE 0 END) AS todayVisitorCount,
            -- 访客总数量（visitor_count 所有日期总和）
            SUM(visitor_count) AS totalVisitorCount,
            -- 今日生成量（generate_count 今日总和）
            SUM(CASE WHEN DATE_FORMAT(date_key, '%Y-%m-%d') = CURDATE() THEN generate_count ELSE 0 END) AS todayGenerateCount,
            -- 总生成量（generate_count 所有日期总和）
            SUM(generate_count) AS totalGenerateCount,
            -- 今日充值（recharge_amount 今日总和）
            SUM(CASE WHEN DATE_FORMAT(date_key, '%Y-%m-%d') = CURDATE() THEN recharge_amount ELSE 0 END) AS todayRechargeAmount,
            -- 总生成量（generate_count 所有日期总和）
            SUM(recharge_amount) AS totalRechargeAmount
        FROM ai_statistics
    </select>

    <select id="getTodayHourlyAddUserWithZero" resultType="Long">
        WITH RECURSIVE hours AS (
        SELECT DATE_FORMAT(NOW(), '%Y-%m-%d 00:00:00') AS hour_time
        UNION ALL
        SELECT DATE_ADD(hour_time, INTERVAL 1 HOUR)
        FROM hours
        WHERE hour_time &lt; DATE_FORMAT(NOW(), '%Y-%m-%d %H:00:00')
        )
        SELECT
        COALESCE(SUM(t.add_user_count), 0) AS add_user_count
        FROM
        hours h
        LEFT JOIN
        ai_statistics t ON DATE_FORMAT(t.date_key, '%Y-%m-%d %H:00:00') = h.hour_time  <if test="source != null">and t.source = #{source}</if>
        GROUP BY
        h.hour_time
        ORDER BY
        h.hour_time ASC;
    </select>

    <select id="getWeeklyAddUserCount" resultType="Long">
        WITH RECURSIVE week_dates AS (
        SELECT DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY) AS day_date
        UNION ALL
        SELECT DATE_ADD(day_date, INTERVAL 1 DAY)
        FROM week_dates
        WHERE day_date &lt; DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) - 6 DAY)
        )
        SELECT
        IFNULL(t.add_user_count, 0) AS a
        FROM week_dates w
        LEFT JOIN (
        SELECT
        DATE(date_key) AS stat_date,
        SUM(add_user_count) AS add_user_count
        FROM ai_statistics
        WHERE DATE(date_key) BETWEEN
        DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY)
        AND DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) - 6 DAY)
        <if test="source != null">and source = #{source}</if>
        GROUP BY DATE(date_key)
        ) t ON w.day_date = t.stat_date
        ORDER BY w.day_date;
    </select>

    <select id="getMonthlyAddUserCount" resultType="Long">
        WITH RECURSIVE month_dates AS (
        -- 本月第一天
        SELECT DATE_FORMAT(CURDATE(), '%Y-%m-01') AS day_date
        UNION ALL
        SELECT DATE_ADD(day_date, INTERVAL 1 DAY)
        FROM month_dates
        WHERE day_date &lt; LAST_DAY(CURDATE())
        )
        -- 2. 左连接业务表统计每日新增用户数
        SELECT
        IFNULL(t.add_user_count, 0) AS a
        FROM month_dates w
        LEFT JOIN (
        -- 按日期分组统计新增用户数
        SELECT
        DATE(date_key) AS stat_date,
             SUM(add_user_count) AS add_user_count -- 或SUM(add_user_count)，根据业务表结构调整
        FROM ai_statistics
        -- 筛选本月数据
        WHERE DATE_FORMAT(date_key, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m')
        <if test="source != null">and source = #{source}</if>
        GROUP BY DATE(date_key)
        ) t ON w.day_date = t.stat_date
        ORDER BY w.day_date;
    </select>


    <select id="getMonthlyAddUserCountByRange" resultType="Long">
        WITH RECURSIVE month_range AS (
        SELECT
        DATE_FORMAT(#{startDate}, '%Y-%m-01') AS month_date -- 起始月第一天
        UNION ALL
        SELECT
        DATE_ADD(month_date, INTERVAL 1 MONTH)
        FROM month_range
        WHERE month_date &lt; DATE_FORMAT(#{endDate}, '%Y-%m-01') -- 结束月第一天
        )
        SELECT
        IFNULL(t.add_user_count, 0) AS a
        FROM month_range w
        LEFT JOIN (
        -- 按月份分组统计
        SELECT
        DATE_FORMAT(date_key, '%Y-%m-01') AS stat_month,
        SUM(add_user_count) AS add_user_count -- 或SUM(add_user_count)，根据业务表调整
        FROM ai_statistics
        WHERE date_key BETWEEN #{startDate} AND #{endDate}
        <if test="source != null">and source = #{source}</if>
        GROUP BY DATE_FORMAT(date_key, '%Y-%m-01')
        ) t ON w.month_date = t.stat_month
        ORDER BY w.month_date;
    </select>

    <select id="getAllSource" resultType="java.lang.String">
        SELECT DISTINCT source
        FROM ai_statistics
        WHERE source IS NOT NULL and source != ''
    </select>

    <select id="getTodayHourlyRechargeWithZero" resultType="java.lang.Long">
        WITH RECURSIVE hours AS (
        SELECT DATE_FORMAT(NOW(), '%Y-%m-%d 00:00:00') AS hour_time
        UNION ALL
        SELECT DATE_ADD(hour_time, INTERVAL 1 HOUR)
        FROM hours
        WHERE hour_time &lt; DATE_FORMAT(NOW(), '%Y-%m-%d %H:00:00')
        )
        SELECT
        COALESCE(SUM(t.recharge_amount), 0) AS recharge_amount
        FROM
        hours h
        LEFT JOIN
        ai_statistics t ON DATE_FORMAT(t.date_key, '%Y-%m-%d %H:00:00') = h.hour_time  <if test="source != null">and t.source = #{source}</if>
        GROUP BY
        h.hour_time
        ORDER BY
        h.hour_time ASC;
    </select>

    <select id="getWeeklyRecharge" resultType="java.lang.Long">
        WITH RECURSIVE week_dates AS (
        SELECT DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY) AS day_date
        UNION ALL
        SELECT DATE_ADD(day_date, INTERVAL 1 DAY)
        FROM week_dates
        WHERE day_date &lt; DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) - 6 DAY)
        )
        SELECT
        IFNULL(t.recharge_amount, 0) AS a
        FROM week_dates w
        LEFT JOIN (
        SELECT
        DATE(date_key) AS stat_date,
        SUM(recharge_amount) AS recharge_amount
        FROM ai_statistics
        WHERE DATE(date_key) BETWEEN
        DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY)
        AND DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) - 6 DAY)
        <if test="source != null">and source = #{source}</if>
        GROUP BY DATE(date_key)
        ) t ON w.day_date = t.stat_date
        ORDER BY w.day_date;
    </select>

    <select id="getMonthlyRecharge" resultType="java.lang.Long">
        WITH RECURSIVE month_dates AS (
        -- 本月第一天
        SELECT DATE_FORMAT(CURDATE(), '%Y-%m-01') AS day_date
        UNION ALL
        SELECT DATE_ADD(day_date, INTERVAL 1 DAY)
        FROM month_dates
        WHERE day_date &lt; LAST_DAY(CURDATE())
        )
        -- 2. 左连接业务表统计每日新增用户数
        SELECT
        IFNULL(t.recharge_amount, 0) AS a
        FROM month_dates w
        LEFT JOIN (
        -- 按日期分组统计新增用户数
        SELECT
        DATE(date_key) AS stat_date,
        SUM(recharge_amount) AS recharge_amount -- 或SUM(add_user_count)，根据业务表结构调整
        FROM ai_statistics
        -- 筛选本月数据
        WHERE DATE_FORMAT(date_key, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m')
        <if test="source != null">and source = #{source}</if>
        GROUP BY DATE(date_key)
        ) t ON w.day_date = t.stat_date
        ORDER BY w.day_date;
    </select>

    <select id="getMonthlyRechargeByRange" resultType="java.lang.Long">
        WITH RECURSIVE month_range AS (
        SELECT
        DATE_FORMAT(#{startDate}, '%Y-%m-01') AS month_date -- 起始月第一天
        UNION ALL
        SELECT
        DATE_ADD(month_date, INTERVAL 1 MONTH)
        FROM month_range
        WHERE month_date &lt; DATE_FORMAT(#{endDate}, '%Y-%m-01') -- 结束月第一天
        )
        SELECT
        IFNULL(t.recharge_amount, 0) AS a
        FROM month_range w
        LEFT JOIN (
        -- 按月份分组统计
        SELECT
        DATE_FORMAT(date_key, '%Y-%m-01') AS stat_month,
        SUM(recharge_amount) AS recharge_amount -- 或SUM(add_user_count)，根据业务表调整
        FROM ai_statistics
        WHERE date_key BETWEEN #{startDate} AND #{endDate}
        <if test="source != null">and source = #{source}</if>
        GROUP BY DATE_FORMAT(date_key, '%Y-%m-01')
        ) t ON w.month_date = t.stat_month
        ORDER BY w.month_date;
    </select>


<!--  ======================================================================  -->

    <select id="getTodayHourlyVisitorWithZero" resultType="java.lang.Long">
        WITH RECURSIVE hours AS (
        SELECT DATE_FORMAT(NOW(), '%Y-%m-%d 00:00:00') AS hour_time
        UNION ALL
        SELECT DATE_ADD(hour_time, INTERVAL 1 HOUR)
        FROM hours
        WHERE hour_time &lt; DATE_FORMAT(NOW(), '%Y-%m-%d %H:00:00')
        )
        SELECT
        COALESCE(SUM(t.visitor_count), 0) AS visitor_count
        FROM
        hours h
        LEFT JOIN
        ai_statistics t ON DATE_FORMAT(t.date_key, '%Y-%m-%d %H:00:00') = h.hour_time  <if test="source != null">and t.source = #{source}</if>
        GROUP BY
        h.hour_time
        ORDER BY
        h.hour_time ASC;
    </select>

    <select id="getWeeklyVisitor" resultType="java.lang.Long">
        WITH RECURSIVE week_dates AS (
        SELECT DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY) AS day_date
        UNION ALL
        SELECT DATE_ADD(day_date, INTERVAL 1 DAY)
        FROM week_dates
        WHERE day_date &lt; DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) - 6 DAY)
        )
        SELECT
        IFNULL(t.visitor_count, 0) AS a
        FROM week_dates w
        LEFT JOIN (
        SELECT
        DATE(date_key) AS stat_date,
        SUM(visitor_count) AS visitor_count
        FROM ai_statistics
        WHERE DATE(date_key) BETWEEN
        DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY)
        AND DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) - 6 DAY)
        <if test="source != null">and source = #{source}</if>
        GROUP BY DATE(date_key)
        ) t ON w.day_date = t.stat_date
        ORDER BY w.day_date;
    </select>

    <select id="getMonthlyVisitor" resultType="java.lang.Long">
        WITH RECURSIVE month_dates AS (
        -- 本月第一天
        SELECT DATE_FORMAT(CURDATE(), '%Y-%m-01') AS day_date
        UNION ALL
        SELECT DATE_ADD(day_date, INTERVAL 1 DAY)
        FROM month_dates
        WHERE day_date &lt; LAST_DAY(CURDATE())
        )
        -- 2. 左连接业务表统计每日新增用户数
        SELECT
        IFNULL(t.visitor_count, 0) AS a
        FROM month_dates w
        LEFT JOIN (
        -- 按日期分组统计新增用户数
        SELECT
        DATE(date_key) AS stat_date,
        SUM(visitor_count) AS visitor_count -- 或SUM(add_user_count)，根据业务表结构调整
        FROM ai_statistics
        -- 筛选本月数据
        WHERE DATE_FORMAT(date_key, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m')
        <if test="source != null">and source = #{source}</if>
        GROUP BY DATE(date_key)
        ) t ON w.day_date = t.stat_date
        ORDER BY w.day_date;
    </select>

    <select id="getMonthlyVisitorByRange" resultType="java.lang.Long">
        WITH RECURSIVE month_range AS (
        SELECT
        DATE_FORMAT(#{startDate}, '%Y-%m-01') AS month_date -- 起始月第一天
        UNION ALL
        SELECT
        DATE_ADD(month_date, INTERVAL 1 MONTH)
        FROM month_range
        WHERE month_date &lt; DATE_FORMAT(#{endDate}, '%Y-%m-01') -- 结束月第一天
        )
        SELECT
        IFNULL(t.visitor_count, 0) AS a
        FROM month_range w
        LEFT JOIN (
        -- 按月份分组统计
        SELECT
        DATE_FORMAT(date_key, '%Y-%m-01') AS stat_month,
        SUM(visitor_count) AS visitor_count -- 或SUM(add_user_count)，根据业务表调整
        FROM ai_statistics
        WHERE date_key BETWEEN #{startDate} AND #{endDate}
        <if test="source != null">and source = #{source}</if>
        GROUP BY DATE_FORMAT(date_key, '%Y-%m-01')
        ) t ON w.month_date = t.stat_month
        ORDER BY w.month_date;
    </select>
<!--  ======================================================================  -->

    <select id="getTodayHourlyGenerateWithZero" resultType="java.lang.Long">
        WITH RECURSIVE hours AS (
        SELECT DATE_FORMAT(NOW(), '%Y-%m-%d 00:00:00') AS hour_time
        UNION ALL
        SELECT DATE_ADD(hour_time, INTERVAL 1 HOUR)
        FROM hours
        WHERE hour_time &lt; DATE_FORMAT(NOW(), '%Y-%m-%d %H:00:00')
        )
        SELECT
        COALESCE(SUM(t.generate_count), 0) AS generate_count
        FROM
        hours h
        LEFT JOIN
        ai_statistics t ON DATE_FORMAT(t.date_key, '%Y-%m-%d %H:00:00') = h.hour_time  <if test="source != null">and t.source = #{source}</if>
        GROUP BY
        h.hour_time
        ORDER BY
        h.hour_time ASC;
    </select>

    <select id="getWeeklyGenerate" resultType="java.lang.Long">
        WITH RECURSIVE week_dates AS (
        SELECT DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY) AS day_date
        UNION ALL
        SELECT DATE_ADD(day_date, INTERVAL 1 DAY)
        FROM week_dates
        WHERE day_date &lt; DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) - 6 DAY)
        )
        SELECT
        IFNULL(t.generate_count, 0) AS a
        FROM week_dates w
        LEFT JOIN (
        SELECT
        DATE(date_key) AS stat_date,
        SUM(generate_count) AS generate_count
        FROM ai_statistics
        WHERE DATE(date_key) BETWEEN
        DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY)
        AND DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) - 6 DAY)
        <if test="source != null">and source = #{source}</if>
        GROUP BY DATE(date_key)
        ) t ON w.day_date = t.stat_date
        ORDER BY w.day_date;
    </select>

    <select id="getMonthlyGenerate" resultType="java.lang.Long">
        WITH RECURSIVE month_dates AS (
        -- 本月第一天
        SELECT DATE_FORMAT(CURDATE(), '%Y-%m-01') AS day_date
        UNION ALL
        SELECT DATE_ADD(day_date, INTERVAL 1 DAY)
        FROM month_dates
        WHERE day_date &lt; LAST_DAY(CURDATE())
        )
        -- 2. 左连接业务表统计每日新增用户数
        SELECT
        IFNULL(t.generate_count, 0) AS a
        FROM month_dates w
        LEFT JOIN (
        -- 按日期分组统计新增用户数
        SELECT
        DATE(date_key) AS stat_date,
        SUM(generate_count) AS generate_count -- 或SUM(add_user_count)，根据业务表结构调整
        FROM ai_statistics
        -- 筛选本月数据
        WHERE DATE_FORMAT(date_key, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m')
        <if test="source != null">and source = #{source}</if>
        GROUP BY DATE(date_key)
        ) t ON w.day_date = t.stat_date
        ORDER BY w.day_date;
    </select>

    <select id="getMonthlyVisitorGenerate" resultType="java.lang.Long">
        WITH RECURSIVE month_range AS (
        SELECT
        DATE_FORMAT(#{startDate}, '%Y-%m-01') AS month_date -- 起始月第一天
        UNION ALL
        SELECT
        DATE_ADD(month_date, INTERVAL 1 MONTH)
        FROM month_range
        WHERE month_date &lt; DATE_FORMAT(#{endDate}, '%Y-%m-01') -- 结束月第一天
        )
        SELECT
        IFNULL(t.generate_count, 0) AS a
        FROM month_range w
        LEFT JOIN (
        -- 按月份分组统计
        SELECT
        DATE_FORMAT(date_key, '%Y-%m-01') AS stat_month,
        SUM(generate_count) AS generate_count -- 或SUM(add_user_count)，根据业务表调整
        FROM ai_statistics
        WHERE date_key BETWEEN #{startDate} AND #{endDate}
        <if test="source != null">and source = #{source}</if>
        GROUP BY DATE_FORMAT(date_key, '%Y-%m-01')
        ) t ON w.month_date = t.stat_month
        ORDER BY w.month_date;
    </select>


    <select id="getMapStatistics" resultType="com.ruoyi.ai.domain.MapValue">
        SELECT
            c.cn_name AS name,
            IFNULL(COUNT(u.id), 0) AS `value`
        FROM
            ai_country c
                LEFT JOIN
            ai_user u
            ON
                c.cn_name = u.country
        GROUP BY
            c.id, c.en_name, c.cn_name
    </select>


    <insert id="insertAiStatistics" parameterType="AiStatistics">
        insert into ai_statistics
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="dateKey != null">date_key,</if>
            <if test="source != null">source,</if>
            <if test="addUserCount != null">add_user_count,</if>
            <if test="visitorCount != null">visitor_count,</if>
            <if test="generateCount != null">generate_count,</if>
         </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="dateKey != null">#{dateKey},</if>
            <if test="source != null">#{source},</if>
            <if test="addUserCount != null">#{addUserCount},</if>
            <if test="visitorCount != null">#{visitorCount},</if>
            <if test="generateCount != null">#{generateCount},</if>
         </trim>
    </insert>

    <insert id="saveOrUpdateData">
        insert into ai_statistics
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="dateKey != null">date_key,</if>
            <if test="source != null">source,</if>
            <if test="addUserCount != null">add_user_count,</if>
            <if test="visitorCount != null">visitor_count,</if>
            <if test="generateCount != null">generate_count,</if>
            <if test="rechargeAmount != null">recharge_amount,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="dateKey != null">#{dateKey},</if>
            <if test="source != null">#{source},</if>
            <if test="addUserCount != null">#{addUserCount},</if>
            <if test="visitorCount != null">#{visitorCount},</if>
            <if test="generateCount != null">#{generateCount},</if>
            <if test="rechargeAmount != null">#{rechargeAmount},</if>
        </trim>
        ON DUPLICATE KEY UPDATE
        <trim suffixOverrides=",">
            <if test="addUserCount != null">add_user_count = add_user_count + #{addUserCount},</if>
            <if test="visitorCount != null">visitor_count = visitor_count + #{visitorCount},</if>
            <if test="generateCount != null">generate_count = generate_count + #{generateCount},</if>
            <if test="rechargeAmount != null">recharge_amount = recharge_amount + #{rechargeAmount},</if>
        </trim>
    </insert>

    <update id="updateAiStatistics" parameterType="AiStatistics">
        update ai_statistics
        <trim prefix="SET" suffixOverrides=",">
            <if test="source != null">source = #{source},</if>
            <if test="addUserCount != null">add_user_count = #{addUserCount},</if>
            <if test="visitorCount != null">visitor_count = #{visitorCount},</if>
            <if test="generateCount != null">generate_count = #{generateCount},</if>
        </trim>
        where date_key = #{dateKey}
    </update>

    <delete id="deleteAiStatisticsByDateKey" parameterType="String">
        delete from ai_statistics where date_key = #{dateKey}
    </delete>

    <delete id="deleteAiStatisticsByDateKeys" parameterType="String">
        delete from ai_statistics where date_key in 
        <foreach item="dateKey" collection="array" open="(" separator="," close=")">
            #{dateKey}
        </foreach>
    </delete>
</mapper>