zjk
2026-09-29 54dcf0a82e7490fa58b1c056d5c0b9cb739c2931
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
<?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.tcm.training.admin.live.mapper.LiveWatchRecordMapper">
 
    <sql id="HasReserveExpr">
        EXISTS (
            SELECT 1
            FROM tcm_live_reserve rr
            WHERE rr.session_id = w.session_id
              AND rr.app_user_id = w.app_user_id
              AND rr.is_cancel = 0
              AND rr.reserve_time <![CDATA[<=]]> w.watch_start
        )
    </sql>
 
    <sql id="GlobalWatchColumns">
        w.id,
        w.live_course_id AS courseId,
        w.session_id AS sessionId,
        w.app_user_id AS userId,
        u.nickname AS userNickname,
        u.phone AS userPhone,
        u.avatar AS userAvatar,
        cl.name AS clinicName,
        CASE
            WHEN cl.province_name IS NOT NULL AND cl.province_name != '' THEN
                CONCAT(
                    cl.province_name,
                    IFNULL(cl.city_name, ''),
                    IFNULL(cl.district_name, '')
                )
            ELSE NULL
        END AS clinicArea,
        c.title AS courseTitle,
        NULL AS categoryName,
        s.start_time AS startTime,
        CASE WHEN <include refid="HasReserveExpr"/> THEN 1 ELSE 0 END AS hasReserve,
        w.watch_start AS watchStart,
        w.watch_end AS watchEnd,
        w.duration_seconds AS durationSeconds,
        w.is_completed AS isCompleted,
        w.is_effective AS isEffective
    </sql>
 
    <sql id="GlobalWatchJoin">
        FROM tcm_live_watch_record w
        INNER JOIN tcm_live_course c ON c.id = w.live_course_id AND c.deleted = 0
        INNER JOIN tcm_live_session s ON s.id = w.session_id AND s.deleted = 0
        LEFT JOIN tcm_app_user u ON u.id = w.app_user_id AND u.deleted = 0
        LEFT JOIN tcm_clinic cl ON cl.id = u.clinic_id AND cl.deleted = 0
    </sql>
 
    <sql id="GlobalWatchWhere">
        WHERE 1 = 1
        <if test="courseId != null">
            AND w.live_course_id = #{courseId}
        </if>
        <if test="sessionId != null">
            AND w.session_id = #{sessionId}
        </if>
        <if test="regionCode != null and regionCode.trim() != ''">
            AND (
                cl.province_code = #{regionCode}
                OR cl.city_code = #{regionCode}
                OR cl.district_code = #{regionCode}
            )
        </if>
        <if test="clinicName != null and clinicName.trim() != ''">
            AND cl.name LIKE CONCAT('%', #{clinicName}, '%')
        </if>
        <if test="phone != null and phone.trim() != ''">
            AND u.phone LIKE CONCAT('%', #{phone}, '%')
        </if>
        <if test="courseName != null and courseName.trim() != ''">
            AND c.title LIKE CONCAT('%', #{courseName}, '%')
        </if>
        <if test="hasReserve != null and hasReserve == 1">
            AND <include refid="HasReserveExpr"/>
        </if>
        <if test="hasReserve != null and hasReserve == 0">
            AND NOT <include refid="HasReserveExpr"/>
        </if>
        <if test="isCompleted != null">
            AND w.is_completed = #{isCompleted}
        </if>
        <if test="isEffective != null">
            AND w.is_effective = #{isEffective}
        </if>
        <if test="watchFrom != null">
            AND w.watch_start <![CDATA[>=]]> #{watchFrom}
        </if>
        <if test="watchTo != null">
            AND w.watch_start <![CDATA[<=]]> #{watchTo}
        </if>
    </sql>
 
    <!-- 观看记录分页列表(动态筛选) -->
    <select id="selectWatchPage"
            resultType="com.tcm.training.admin.live.vo.LiveWatchRow">
        SELECT
            w.id,
            w.app_user_id AS userId,
            s.nickname AS userNickname,
            s.phone AS userPhone,
            s.avatar AS userAvatar,
            w.watch_start AS watchStart,
            w.watch_end AS watchEnd,
            w.duration_seconds AS durationSeconds,
            w.is_completed AS isCompleted,
            w.is_effective AS isEffective
        FROM tcm_live_watch_record w
        LEFT JOIN tcm_app_user s ON s.id = w.app_user_id AND s.deleted = 0
        WHERE w.live_course_id = #{courseId} AND w.session_id = #{sessionId}
        <if test="keyword != null and keyword.trim() != ''">
            AND (s.nickname LIKE CONCAT('%', #{keyword}, '%')
              OR s.phone LIKE CONCAT('%', #{keyword}, '%'))
        </if>
        <if test="isCompleted != null">
            AND w.is_completed = #{isCompleted}
        </if>
        <if test="isEffective != null">
            AND w.is_effective = #{isEffective}
        </if>
        ORDER BY w.id DESC
    </select>
 
    <select id="selectGlobalWatchPage"
            resultType="com.tcm.training.admin.live.vo.LiveWatchRow">
        SELECT
            <include refid="GlobalWatchColumns"/>
        <include refid="GlobalWatchJoin"/>
        <include refid="GlobalWatchWhere"/>
        ORDER BY w.watch_start DESC, w.id DESC
    </select>
 
    <select id="selectGlobalWatchList"
            resultType="com.tcm.training.admin.live.vo.LiveWatchRow">
        SELECT
            <include refid="GlobalWatchColumns"/>
        <include refid="GlobalWatchJoin"/>
        <include refid="GlobalWatchWhere"/>
        ORDER BY w.watch_start DESC, w.id DESC
    </select>
 
    <select id="selectGlobalWatchSummary"
            resultType="com.tcm.training.admin.live.vo.LiveWatchSummaryRow">
        SELECT
            COUNT(1) AS watchUserTotal,
            COALESCE(SUM(CASE WHEN grouped.completedFlag = 1 THEN 1 ELSE 0 END), 0) AS completedUserTotal,
            COALESCE(SUM(CASE WHEN grouped.effectiveFlag = 1 THEN 1 ELSE 0 END), 0) AS effectiveUserTotal
        FROM (
            SELECT
                w.session_id,
                w.app_user_id,
                MAX(w.is_completed) AS completedFlag,
                MAX(w.is_effective) AS effectiveFlag
            <include refid="GlobalWatchJoin"/>
            <include refid="GlobalWatchWhere"/>
            GROUP BY w.session_id, w.app_user_id
        ) grouped
    </select>
 
</mapper>