소스 검색

直播间在线用户 直播还是录播判断 区分在线用户

yuhongqi 1 주 전
부모
커밋
ef6d1b9509

+ 2 - 0
fs-common/src/main/java/com/fs/common/constant/LiveKeysConstant.java

@@ -27,6 +27,8 @@ public class LiveKeysConstant {
     public static final String LIVE_HOME_PAGE_CONFIG_DRAW = "live:config:%s:draw:%s"; //抽奖记录
     public static final String TOP_MSG = "topMsg"; //抽奖记录
 
+    public static final String LIVE_FLAG_CACHE = "live:flag:%s"; //直播间直播/回放状态缓存
+    public static final Integer LIVE_FLAG_CACHE_EXPIRE = 60; //直播间状态缓存过期时间(秒)
 
 
 }

+ 3 - 2
fs-live-app/src/main/java/com/fs/live/websocket/handle/LiveChatHandler.java

@@ -175,8 +175,9 @@ public class LiveChatHandler extends SimpleChannelInboundHandler<TextWebSocketFr
                     liveMsg.setCreateTime(new Date());
 
                     if (userType == 0) {
-                        List<LiveWatchUser> liveWatchUser = liveWatchUserService.getByLiveIdAndUserId(msg.getLiveId(), msg.getUserId());
-                        if(!liveWatchUser.isEmpty() && liveWatchUser.get(0).getMsgStatus() == 1){
+                        Map<String, Integer> liveFlagWithCache = liveWatchUserService.getLiveFlagWithCache(liveId);
+                        LiveWatchUser liveWatchUser = liveWatchUserService.selectLiveWatchUserByFlag(msg.getLiveId(), msg.getUserId(), liveFlagWithCache.get("liveFlag"),  liveFlagWithCache.get("replayFlag"));
+                        if(liveWatchUser != null && liveWatchUser.getMsgStatus() == 1){
                             sendMessage(channelHandlerContext.channel(), JSONObject.toJSONString(R.error("你以被禁言")));
                             return;
                         }

+ 0 - 3
fs-live-app/src/main/java/com/fs/live/websocket/service/WebSocketServer.java

@@ -204,9 +204,6 @@ public class WebSocketServer {
             }
 
 
-
-
-
             // 直播间在线人数 -1
             redisCache.incr(ONLINE_USERS_KEY + liveId, -1);
             // 从在线用户Set中移除用户ID

+ 18 - 0
fs-service/src/main/java/com/fs/live/mapper/LiveMapper.java

@@ -152,4 +152,22 @@ public interface LiveMapper
 
     @Select("select * from live where is_audit = 1 and is_del = 0 and status in (1,2,4) and live_type in (2,3) order by create_time desc")
     List<Live> liveListAll();
+
+    /**
+     * 查询直播间是直播还是回放状态
+     * 判断标准:当前直播间开始时间 + 视频类型为1的视频时长,如果大于当前时间,返回1,否则返回0
+     * @param liveId 直播间ID
+     * @return 1表示直播中,0表示回放中
+     */
+    @Select("SELECT CASE " +
+            "WHEN l.start_time IS NOT NULL AND " +
+            "     (l.start_time + INTERVAL COALESCE(SUM(CASE WHEN lv.video_type = 1 THEN lv.duration ELSE 0 END), 0) SECOND) > NOW() " +
+            "THEN 1 " +
+            "ELSE 0 " +
+            "END AS liveFlag " +
+            "FROM live l " +
+            "LEFT JOIN live_video lv ON l.live_id = lv.live_id AND lv.video_type = 1 " +
+            "WHERE l.live_id = #{liveId} " +
+            "GROUP BY l.live_id, l.start_time")
+    Integer selectLiveFlagByLiveId(@Param("liveId") Long liveId);
 }

+ 5 - 10
fs-service/src/main/java/com/fs/live/mapper/LiveWatchUserMapper.java

@@ -87,25 +87,20 @@ public interface LiveWatchUserMapper {
 
     /**
      * 根据直播间ID和用户ID查询观看用户信息
-     * @param liveId    直播间ID
-     * @param userId    观看用户ID
+     * @param params    参数Map,包含liveId、userId、liveFlag、replayFlag
      * @return LiveWatchUserVO
      */
-    LiveWatchUserVO selectWatchUserByLiveIdAndUserId(@Param("liveId") Long liveId, @Param("userId") Long userId);
+    LiveWatchUserVO selectWatchUserByLiveIdAndUserId(@Param("params") Map<String, Object> params);
 
 
 
     List<LiveWatchUserVO> selectOnlineUserList(LiveWatchUser param);
 
-    List<LiveWatchUser> checkOnlineNoRewardUser(@Param("liveId") Long liveId,@Param("now") Date now);
+    List<LiveWatchUser> checkOnlineNoRewardUser(@Param("params") Map<String, Object> params);
 
-    @Select("select a.*,fu.nickname as nick_name from (select lws.* from live_watch_user lws where live_id=#{liveId} and online = 0 and " +
-            "user_id in (select user_id from live_lottery_registration where live_id = #{liveId} and lottery_id=#{lotteryId} and registration_id >= " +
-            "(SELECT FLOOR(RAND() * (SELECT MAX(registration_id) FROM live_lottery_registration)))) ) a left join fs_user fu on fu.user_id = a.user_id")
-    List<LiveWatchUser> selectLiveWatchAndRegisterUser(@Param("liveId") Long liveId,@Param("lotteryId") Long lotteryId);
+    List<LiveWatchUser> selectLiveWatchAndRegisterUser(@Param("params") Map<String, Object> params);
 
-    @Select("select * from live_watch_user where live_id = #{liveId} and user_id = #{userId}")
-    List<LiveWatchUser> selectUserByLiveIdAndUserId(@Param("liveId") long liveId,@Param("userId")  long userId);
+    List<LiveWatchUser> selectUserByLiveIdAndUserId(@Param("params") Map<String, Object> params);
 
     /**
      * 根据唯一索引查询:live_id, user_id, live_flag, replay_flag

+ 4 - 0
fs-service/src/main/java/com/fs/live/service/ILiveWatchUserService.java

@@ -75,6 +75,8 @@ public interface ILiveWatchUserService {
 
     List<LiveWatchUser> getByLiveIdAndUserId(long liveId, long userId);
 
+    Map<String, Integer> getLiveFlagWithCache(Long liveId);
+
     LiveWatchUser join(long liveId, long userId, String location);
     LiveWatchUser joinWithoutLocation(long liveId, long userId);
     LiveWatchUser close(long liveId, long userId);
@@ -121,4 +123,6 @@ public interface ILiveWatchUserService {
     void updateGlobalVisible(long liveId, int i);
 
     void updateSingleVisible(long liveId, Integer status,long userId);
+
+    LiveWatchUser selectLiveWatchUserByFlag(Long liveId, Long userId, Integer liveFlag, Integer replayFlag);
 }

+ 108 - 98
fs-service/src/main/java/com/fs/live/service/impl/LiveWatchUserServiceImpl.java

@@ -95,6 +95,12 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
         } else if ("silenced".equals(liveWatchUser.getTabName())) {
             liveWatchUser.setMsgStatus(1);
         }
+        // 先查缓存,获取liveFlag和replayFlag
+        if (liveWatchUser != null && liveWatchUser.getLiveId() != null) {
+            Map<String, Integer> flagMap = getLiveFlagWithCache(liveWatchUser.getLiveId());
+            liveWatchUser.setLiveFlag(flagMap.get("liveFlag"));
+            liveWatchUser.setReplayFlag(flagMap.get("replayFlag"));
+        }
         return baseMapper.selectLiveWatchUserList(liveWatchUser);
     }
 
@@ -150,7 +156,47 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
 
     @Override
     public List<LiveWatchUser> getByLiveIdAndUserId(long liveId, long userId) {
-        return baseMapper.selectUserByLiveIdAndUserId(liveId, userId);
+        // 先查缓存,获取liveFlag和replayFlag
+        Map<String, Integer> flagMap = getLiveFlagWithCache(liveId);
+        Map<String, Object> params = new HashMap<>();
+        params.put("liveId", liveId);
+        params.put("userId", userId);
+        params.put("liveFlag", flagMap.get("liveFlag"));
+        params.put("replayFlag", flagMap.get("replayFlag"));
+        return baseMapper.selectUserByLiveIdAndUserId(params);
+    }
+
+    /**
+     * 获取直播间的直播/回放状态(带缓存)
+     * @param liveId 直播间ID
+     * @return Map包含liveFlag和replayFlag
+     */
+    @Override
+    public Map<String, Integer> getLiveFlagWithCache(Long liveId) {
+        String cacheKey = String.format(LiveKeysConstant.LIVE_FLAG_CACHE, liveId);
+
+        // 先查缓存
+        Map<String, Integer> cached = redisCache.getCacheObject(cacheKey);
+        if (cached != null && cached.containsKey("liveFlag") && cached.containsKey("replayFlag")) {
+            return cached;
+        }
+
+        // 缓存不存在,查询数据库
+        Integer liveFlag = liveMapper.selectLiveFlagByLiveId(liveId);
+        if (liveFlag == null) {
+            liveFlag = 0;
+        }
+        Integer replayFlag = 1 - liveFlag; // 反数
+
+        // 构建结果
+        Map<String, Integer> result = new HashMap<>();
+        result.put("liveFlag", liveFlag);
+        result.put("replayFlag", replayFlag);
+
+        // 缓存结果,过期时间1分钟
+        redisCache.setCacheObject(cacheKey, result, LiveKeysConstant.LIVE_FLAG_CACHE_EXPIRE, TimeUnit.SECONDS);
+
+        return result;
     }
 
     @Override
@@ -164,37 +210,10 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
             throw new RuntimeException("直播间不存在");
         }
 
-        // 查询直播间录播视频时长(video_type IN (1, 2))
-        List<LiveVideo> videos = liveVideoMapper.selectByLiveIdAndType(liveId,1);
-        long totalDuration = 0L;
-        if (videos != null && !videos.isEmpty()) {
-            totalDuration = videos.stream()
-                    .filter(v -> v.getVideoType() != null && (v.getVideoType() == 1 || v.getVideoType() == 2))
-                    .filter(v -> v.getDuration() != null)
-                    .mapToLong(LiveVideo::getDuration)
-                    .sum();
-        }
-
-        // 判断是直播还是回放:开播时间 + 视频时长
-        Integer liveFlag = 0;
-        Integer replayFlag = 0;
-
-        if (live.getStartTime() != null) {
-            // 将 LocalDateTime 转换为 Date
-            Date startTime = java.sql.Timestamp.valueOf(live.getStartTime());
-            // 计算结束时间:开播时间 + 视频时长(秒)
-            Date endTime = new Date(startTime.getTime() + totalDuration * 1000);
-
-            if (now.before(endTime)) {
-                // 当前时间 < 开播时间 + 视频时长,说明是直播
-                liveFlag = 1;
-                replayFlag = 0;
-            } else {
-                // 当前时间 >= 开播时间 + 视频时长,说明是回放
-                liveFlag = 0;
-                replayFlag = 1;
-            }
-        }
+        // 获取直播/回放状态(带缓存)
+        Map<String, Integer> flagMap = getLiveFlagWithCache(liveId);
+        Integer liveFlag = flagMap.get("liveFlag");
+        Integer replayFlag = flagMap.get("replayFlag");
 
         // 使用唯一索引查询:live_id, user_id, live_flag, replay_flag
         LiveWatchUser liveWatchUser = baseMapper.selectByUniqueIndex(liveId, userId, liveFlag, replayFlag);
@@ -241,37 +260,10 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
             throw new RuntimeException("直播间不存在");
         }
 
-        // 查询直播间录播视频时长(video_type IN (1, 2))
-        List<LiveVideo> videos = liveVideoMapper.selectByLiveIdAndType(liveId,1);
-        long totalDuration = 0L;
-        if (videos != null && !videos.isEmpty()) {
-            totalDuration = videos.stream()
-                    .filter(v -> v.getVideoType() != null && (v.getVideoType() == 1 || v.getVideoType() == 2))
-                    .filter(v -> v.getDuration() != null)
-                    .mapToLong(LiveVideo::getDuration)
-                    .sum();
-        }
-
-        // 判断是直播还是回放:开播时间 + 视频时长
-        Integer liveFlag = 0;
-        Integer replayFlag = 0;
-
-        if (live.getStartTime() != null) {
-            // 将 LocalDateTime 转换为 Date
-            Date startTime = java.sql.Timestamp.valueOf(live.getStartTime());
-            // 计算结束时间:开播时间 + 视频时长(秒)
-            Date endTime = new Date(startTime.getTime() + totalDuration * 1000);
-
-            if (now.before(endTime)) {
-                // 当前时间 < 开播时间 + 视频时长,说明是直播
-                liveFlag = 1;
-                replayFlag = 0;
-            } else {
-                // 当前时间 >= 开播时间 + 视频时长,说明是回放
-                liveFlag = 0;
-                replayFlag = 1;
-            }
-        }
+        // 获取直播/回放状态(带缓存)
+        Map<String, Integer> flagMap = getLiveFlagWithCache(liveId);
+        Integer liveFlag = flagMap.get("liveFlag");
+        Integer replayFlag = flagMap.get("replayFlag");
 
         // 使用唯一索引查询:live_id, user_id, live_flag, replay_flag
         LiveWatchUser liveWatchUser = baseMapper.selectByUniqueIndex(liveId, userId, liveFlag, replayFlag);
@@ -304,7 +296,6 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
     }
     @Override
     public LiveWatchUser close(long liveId, long userId) {
-        Date now = DateUtils.getNowDate();
 
         // 查询直播间信息
         Live live = liveMapper.selectLiveByLiveId(liveId);
@@ -312,37 +303,10 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
             throw new RuntimeException("直播间不存在");
         }
 
-        // 查询直播间录播视频时长(video_type IN (1, 2))
-        List<LiveVideo> videos = liveVideoMapper.selectByLiveIdAndType(liveId,1);
-        long totalDuration = 0L;
-        if (videos != null && !videos.isEmpty()) {
-            totalDuration = videos.stream()
-                    .filter(v -> v.getVideoType() != null && (v.getVideoType() == 1 || v.getVideoType() == 2))
-                    .filter(v -> v.getDuration() != null)
-                    .mapToLong(LiveVideo::getDuration)
-                    .sum();
-        }
-
-        // 判断是直播还是回放:开播时间 + 视频时长
-        Integer liveFlag = 0;
-        Integer replayFlag = 0;
-
-        if (live.getStartTime() != null) {
-            // 将 LocalDateTime 转换为 Date
-            Date startTime = java.sql.Timestamp.valueOf(live.getStartTime());
-            // 计算结束时间:开播时间 + 视频时长(秒)
-            Date endTime = new Date(startTime.getTime() + totalDuration * 1000);
-
-            if (now.before(endTime)) {
-                // 当前时间 < 开播时间 + 视频时长,说明是直播
-                liveFlag = 1;
-                replayFlag = 0;
-            } else {
-                // 当前时间 >= 开播时间 + 视频时长,说明是回放
-                liveFlag = 0;
-                replayFlag = 1;
-            }
-        }
+        // 获取直播/回放状态(带缓存)
+        Map<String, Integer> flagMap = getLiveFlagWithCache(liveId);
+        Integer liveFlag = flagMap.get("liveFlag");
+        Integer replayFlag = flagMap.get("replayFlag");
 
         // 使用唯一索引查询:live_id, user_id, live_flag, replay_flag
         LiveWatchUser liveWatchUser = baseMapper.selectByUniqueIndex(liveId, userId, liveFlag, replayFlag);
@@ -369,6 +333,13 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
      */
     @Override
     public List<LiveWatchUserVO> selectWatchUserList(Map<String, Object> params) {
+        // 先查缓存,获取liveFlag和replayFlag
+        if (params != null && params.containsKey("liveId")) {
+            Long liveId = Long.valueOf(params.get("liveId").toString());
+            Map<String, Integer> flagMap = getLiveFlagWithCache(liveId);
+            params.put("liveFlag", flagMap.get("liveFlag"));
+            params.put("replayFlag", flagMap.get("replayFlag"));
+        }
         return baseMapper.selectWatchUserListByLiveId(params);
     }
 
@@ -400,17 +371,37 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
      */
     @Override
     public LiveWatchUserVO selectWatchUserByLiveIdAndUserId(Long liveId, Long userId) {
-        return baseMapper.selectWatchUserByLiveIdAndUserId(liveId, userId);
+        // 先查缓存,获取liveFlag和replayFlag
+        Map<String, Integer> flagMap = getLiveFlagWithCache(liveId);
+        Map<String, Object> params = new HashMap<>();
+        params.put("liveId", liveId);
+        params.put("userId", userId);
+        params.put("liveFlag", flagMap.get("liveFlag"));
+        params.put("replayFlag", flagMap.get("replayFlag"));
+        return baseMapper.selectWatchUserByLiveIdAndUserId(params);
     }
 
     @Override
     public List<LiveWatchUserVO> selectOnlineUserList(LiveWatchUser param) {
+        // 先查缓存,获取liveFlag和replayFlag
+        if (param != null && param.getLiveId() != null) {
+            Map<String, Integer> flagMap = getLiveFlagWithCache(param.getLiveId());
+            param.setLiveFlag(flagMap.get("liveFlag"));
+            param.setReplayFlag(flagMap.get("replayFlag"));
+        }
         return baseMapper.selectOnlineUserList(param);
     }
 
     @Override
     public List<LiveWatchUser> checkOnlineNoRewardUser(Long liveId, Date now) {
-        return baseMapper.checkOnlineNoRewardUser(liveId,now);
+        // 先查缓存,获取liveFlag和replayFlag
+        Map<String, Integer> flagMap = getLiveFlagWithCache(liveId);
+        Map<String, Object> params = new HashMap<>();
+        params.put("liveId", liveId);
+        params.put("now", now);
+        params.put("liveFlag", flagMap.get("liveFlag"));
+        params.put("replayFlag", flagMap.get("replayFlag"));
+        return baseMapper.checkOnlineNoRewardUser(params);
     }
 
     @Override
@@ -423,7 +414,14 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
 
     @Override
     public List<LiveWatchUser> selectLiveWatchAndRegisterUser(Long liveId, Long lotteryId) {
-        return baseMapper.selectLiveWatchAndRegisterUser(liveId, lotteryId);
+        // 先查缓存,获取liveFlag和replayFlag
+        Map<String, Integer> flagMap = getLiveFlagWithCache(liveId);
+        Map<String, Object> params = new HashMap<>();
+        params.put("liveId", liveId);
+        params.put("lotteryId", lotteryId);
+        params.put("liveFlag", flagMap.get("liveFlag"));
+        params.put("replayFlag", flagMap.get("replayFlag"));
+        return baseMapper.selectLiveWatchAndRegisterUser(params);
     }
 
     @Override
@@ -480,6 +478,13 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
 
     @Override
     public List<LiveWatchUserVO> dashBoardWatchUserList(Map<String, Object> param) {
+        // 先查缓存,获取liveFlag和replayFlag
+        if (param != null && param.containsKey("liveId")) {
+            Long liveId = Long.valueOf(param.get("liveId").toString());
+            Map<String, Integer> flagMap = getLiveFlagWithCache(liveId);
+            param.put("liveFlag", flagMap.get("liveFlag"));
+            param.put("replayFlag", flagMap.get("replayFlag"));
+        }
         if (param != null && param.containsKey("all") && "1".equals(param.get("all"))) {
             return baseMapper.selectWatchUserListAllByLiveId(param);
         } else {
@@ -500,4 +505,9 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
         baseMapper.updateSingleVisible(liveId, status,userId);
     }
 
+    @Override
+    public LiveWatchUser selectLiveWatchUserByFlag(Long liveId, Long userId, Integer liveFlag, Integer replayFlag) {
+        return baseMapper.selectByUniqueIndex(liveId, userId, liveFlag, replayFlag);
+    }
+
 }

+ 36 - 3
fs-service/src/main/resources/mapper/live/LiveWatchUserMapper.xml

@@ -32,6 +32,8 @@
         <where>
             <if test="liveId != null "> and live_id = #{liveId}</if>
             <if test="userId != null "> and user_id = #{userId}</if>
+            <if test="liveFlag != null "> and live_flag = #{liveFlag}</if>
+            <if test="replayFlag != null "> and replay_flag = #{replayFlag}</if>
             <if test="msgStatus != null "> and msg_status = #{msgStatus}</if>
             <if test="online != null "> and online = #{online}</if>
             <if test="onlineSeconds != null "> and online_seconds = #{onlineSeconds}</if>
@@ -56,6 +58,8 @@
         from live_watch_user lwu
         left join fs_user fu on lwu.user_id = fu.user_id
         where lwu.live_id = #{params.liveId} and fu.status = 1
+        <if test="params.liveFlag != null "> and lwu.live_flag = #{params.liveFlag}</if>
+        <if test="params.replayFlag != null "> and lwu.replay_flag = #{params.replayFlag}</if>
         <if test="params.msgStatus != null "> and msg_status = #{params.msgStatus}</if>
         <if test="params.online != null "> and online = #{params.online}</if>
         <if test="params.userName != null and params.userName != ''"> and fu.nick_name like concat('%',#{params.userName},'%')</if>
@@ -75,6 +79,8 @@
         from live_watch_user lwu
         left join fs_user fu on lwu.user_id = fu.user_id
         where lwu.live_id = #{params.liveId} and fu.status = 1
+        <if test="params.liveFlag != null "> and lwu.live_flag = #{params.liveFlag}</if>
+        <if test="params.replayFlag != null "> and lwu.replay_flag = #{params.replayFlag}</if>
         <if test="params.userName != null and params.userName != ''"> and fu.nick_name like concat('%',#{params.userName},'%')</if>
         order by lwu.create_time desc
 
@@ -97,7 +103,9 @@
             lwu.single_visible  singleVisible
         from live_watch_user lwu
                  left join fs_user fu on lwu.user_id = fu.user_id
-        where lwu.live_id = #{liveId} and lwu.user_id = #{userId}
+        where lwu.live_id = #{params.liveId} and lwu.user_id = #{params.userId}
+        <if test="params.liveFlag != null "> and lwu.live_flag = #{params.liveFlag}</if>
+        <if test="params.replayFlag != null "> and lwu.replay_flag = #{params.replayFlag}</if>
     </select>
 
     <select id="selectOnlineUserList" parameterType="LiveWatchUser" resultType="com.fs.live.vo.LiveWatchUserVO">
@@ -109,6 +117,8 @@
         left join fs_user fu on lwu.user_id = fu.user_id
         <where>
             <if test="liveId != null "> and live_id = #{liveId}</if>
+            <if test="liveFlag != null "> and live_flag = #{liveFlag}</if>
+            <if test="replayFlag != null "> and replay_flag = #{replayFlag}</if>
             <if test="online != null "> and online = #{online}</if>
         </where>
     </select>
@@ -187,18 +197,41 @@
     <select id="checkOnlineNoRewardUser" resultType="com.fs.live.domain.LiveWatchUser">
         SELECT lwu.*
         FROM live_watch_user lwu
-        WHERE lwu.live_id = #{liveId}
+        WHERE lwu.live_id = #{params.liveId}
           AND lwu.online = 0
+          <if test="params.liveFlag != null "> and lwu.live_flag = #{params.liveFlag}</if>
+          <if test="params.replayFlag != null "> and lwu.replay_flag = #{params.replayFlag}</if>
           AND NOT EXISTS (
             SELECT 1
             FROM live_reward_record lrr
             WHERE lrr.user_id = lwu.user_id
               AND lrr.live_id = lwu.live_id
               and lrr.source_type = 3
-              AND DATE(lrr.create_time) = DATE(#{now})
+              AND DATE(lrr.create_time) = DATE(#{params.now})
         )
     </select>
 
+    <select id="selectLiveWatchAndRegisterUser" resultType="com.fs.live.domain.LiveWatchUser">
+        select a.*,fu.nickname as nick_name from (
+            select lws.* from live_watch_user lws 
+            where live_id=#{params.liveId} and online = 0
+            <if test="params.liveFlag != null "> and live_flag = #{params.liveFlag}</if>
+            <if test="params.replayFlag != null "> and replay_flag = #{params.replayFlag}</if>
+            and user_id in (
+                select user_id from live_lottery_registration 
+                where live_id = #{params.liveId} and lottery_id=#{params.lotteryId} 
+                and registration_id >= (SELECT FLOOR(RAND() * (SELECT MAX(registration_id) FROM live_lottery_registration)))
+            )
+        ) a left join fs_user fu on fu.user_id = a.user_id
+    </select>
+
+    <select id="selectUserByLiveIdAndUserId" resultType="com.fs.live.domain.LiveWatchUser">
+        select * from live_watch_user 
+        where live_id = #{params.liveId} and user_id = #{params.userId}
+        <if test="params.liveFlag != null "> and live_flag = #{params.liveFlag}</if>
+        <if test="params.replayFlag != null "> and replay_flag = #{params.replayFlag}</if>
+    </select>
+
     <!-- 根据唯一索引查询:live_id, user_id, live_flag, replay_flag -->
     <select id="selectByUniqueIndex" resultMap="LiveWatchUserResult">
         <include refid="selectLiveWatchUserVo"/>