diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/app/UserVisitorAppController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/app/UserVisitorAppController.java index 2fdb25aa..f4971ce5 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/app/UserVisitorAppController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/app/UserVisitorAppController.java @@ -1,6 +1,7 @@ package com.ruoyi.web.controller.cai.app; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.cai.constant.CommonConstant; import com.ruoyi.cai.dto.app.query.StarOrVisitorReq; import com.ruoyi.cai.dto.app.query.VisitorQuery; import com.ruoyi.cai.dto.app.vo.user.UserStarOrVisitorList; @@ -45,7 +46,14 @@ public class UserVisitorAppController { @Log(title = "我的浏览记录、访客查询-分页", businessType = BusinessType.OTHER,isPrintResponseData = false, isSaveDb = false) public R> page(VisitorQuery query, PageQuery pageQuery){ Page res = userVisitorService.pageApp(pageQuery,query); - return R.ok(res.getRecords()); + List records = res.getRecords(); + for (UserStarOrVisitorList record : records) { + if(record.getCity() == null){ + record.setCity(CommonConstant.CITY); + record.setCityId(CommonConstant.CITY_ID); + } + } + return R.ok(records); } } diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/constant/CommonConstant.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/constant/CommonConstant.java new file mode 100644 index 00000000..a12c65b0 --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/constant/CommonConstant.java @@ -0,0 +1,7 @@ +package com.ruoyi.cai.constant; + +public class CommonConstant { + + public static final String CITY = "北京"; + public static final Integer CITY_ID = 110100; +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/mq/AmqpWsProducer.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/mq/AmqpWsProducer.java index 16ac555d..6600822e 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/mq/AmqpWsProducer.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/mq/AmqpWsProducer.java @@ -21,7 +21,6 @@ public class AmqpWsProducer { }); } - @Deprecated public void sendRoomSettleDelay(String message, Integer timeout){ rabbitTemplate.convertAndSend(RoomSettleDelayWsMqConstant.EXCHANGE_NAME, RoomSettleDelayWsMqConstant.ROUTING_KEY, diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/service/impl/DynamicServiceImpl.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/service/impl/DynamicServiceImpl.java index c3f4dce3..c0ac8a66 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/service/impl/DynamicServiceImpl.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/service/impl/DynamicServiceImpl.java @@ -149,7 +149,7 @@ public class DynamicServiceImpl extends ServiceImpl impl List imageList = res.getImageList(); if(CollectionUtil.isNotEmpty(imageList)){ for (DynamicAddReq.DynamicImageAddReq imageVo : imageList) { - CaiFileUtils.FileSize fileSize = CaiFileUtils.getFileSize(imageVo.getUrl()); + CaiFileUtils.FileSize fileSize = CaiFileUtils.getFastFileSize(imageVo.getUrl()); DynamicImages po = new DynamicImages(); po.setUserId(dynamic.getUserId()); po.setDynamicId(dynamic.getId()); diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/util/CaiFileUtils.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/util/CaiFileUtils.java index 5b65dc27..2a2520c6 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/util/CaiFileUtils.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/util/CaiFileUtils.java @@ -20,6 +20,10 @@ public class CaiFileUtils { private static String BASE_URL = "https://nono-1257812345.cos.ap-shanghai.myqcloud.com/"; + public static FileSize getFastFileSize(String url){ + return new FileSize(); + } + public static FileSize getFileSize(String url){ FileSize fileSize = new FileSize(); String suffix = StringUtils.substring(url, url.lastIndexOf("."), url.length()); @@ -36,6 +40,5 @@ public class CaiFileUtils { log.error("获取文件图片大小失败",e); } return new FileSize(); - } } diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/handler/message/CancelMessageHandler.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/handler/message/CancelMessageHandler.java index 17566e96..d80a8925 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/handler/message/CancelMessageHandler.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/handler/message/CancelMessageHandler.java @@ -4,9 +4,12 @@ import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.cai.domain.UserCall; import com.ruoyi.cai.notice.YunxinWsServiceV2; +import com.ruoyi.cai.service.AnchorService; import com.ruoyi.cai.service.UserCallService; +import com.ruoyi.cai.service.UserService; import com.ruoyi.cai.ws.bean.FdCtxData; import com.ruoyi.cai.ws.bean.Room; +import com.ruoyi.cai.ws.bean.UserData; import com.ruoyi.cai.ws.constant.HangUpEnums; import com.ruoyi.cai.ws.constant.RoomStatusEnums; import com.ruoyi.cai.ws.dto.WsRMsgGen; @@ -28,6 +31,10 @@ public class CancelMessageHandler extends AbstractMessageHandle implements IMess private RoomService roomService; @Autowired private YunxinWsServiceV2 yunxinWsService; + @Autowired + private UserService userService; + @Autowired + private AnchorService anchorService; @Override public void processOn(Room room, FdCtxData fdCtxData, JSONObject map) { @@ -54,6 +61,12 @@ public class CancelMessageHandler extends AbstractMessageHandle implements IMess userCallService.update(Wrappers.lambdaUpdate(UserCall.class) .eq(UserCall::getId,roomId) .set(UserCall::getStatus,RoomStatusEnums.STATUS_CALLER_CANCEL.getCode())); + // 释放主播的接听状态 + UserData receiverUserData = room.getReceiverUserData(); + if(receiverUserData != null && receiverUserData.getConnectTime() != null && receiverUserData.getConnectTime() > 0){ + userService.updateVideoStatus(receiverId,0); + anchorService.updateVideoStatus(receiverId,0); + } } } diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/handler/message/RefuseMessageHandler.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/handler/message/RefuseMessageHandler.java index 50bf3cd9..5102ce2c 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/handler/message/RefuseMessageHandler.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/handler/message/RefuseMessageHandler.java @@ -4,9 +4,12 @@ import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.cai.domain.UserCall; import com.ruoyi.cai.notice.YunxinWsServiceV2; +import com.ruoyi.cai.service.AnchorService; import com.ruoyi.cai.service.UserCallService; +import com.ruoyi.cai.service.UserService; import com.ruoyi.cai.ws.bean.FdCtxData; import com.ruoyi.cai.ws.bean.Room; +import com.ruoyi.cai.ws.bean.UserData; import com.ruoyi.cai.ws.constant.HangUpEnums; import com.ruoyi.cai.ws.constant.RoomStatusEnums; import com.ruoyi.cai.ws.dto.WsRMsgGen; @@ -28,6 +31,10 @@ public class RefuseMessageHandler extends AbstractMessageHandle implements IMess private UserCallService userCallService; @Autowired private YunxinWsServiceV2 yunxinWsService; + @Autowired + private UserService userService; + @Autowired + private AnchorService anchorService; @Override public void processOn(Room room, FdCtxData fdCtxData, JSONObject map) { @@ -46,11 +53,16 @@ public class RefuseMessageHandler extends AbstractMessageHandle implements IMess Long receiverId = room.getReceiverId(); Long callerId = room.getCallId(); yunxinWsService.sendToCallNotify(callerId,receiverId, CallNoticeEnum.REFUSE,0L); - // 更新房间状态 userCallService.update(Wrappers.lambdaUpdate(UserCall.class) .eq(UserCall::getId,room.getRoomId()) .set(UserCall::getStatus,RoomStatusEnums.STATUS_REFUSE.getCode())); + // 释放主播的接听状态 + UserData receiverUserData = room.getReceiverUserData(); + if(receiverUserData != null && receiverUserData.getConnectTime() != null && receiverUserData.getConnectTime() > 0){ + userService.updateVideoStatus(receiverId,0); + anchorService.updateVideoStatus(receiverId,0); + } } diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/holder/WebSocketSessionHolder.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/holder/WebSocketSessionHolder.java index 2e0ba192..ffeb8298 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/holder/WebSocketSessionHolder.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/holder/WebSocketSessionHolder.java @@ -28,7 +28,9 @@ public class WebSocketSessionHolder { } public static void addSession(String sessionKey, WebSocketSession session,Long userId) { - log.info("收到sessionId={} userId={}",sessionKey, userId); + Object roomIdObj = session.getAttributes().get("room_id"); + String roomId = String.valueOf(roomIdObj); + log.info("收到sessionId={} roomId={} userId={}",sessionKey, roomId, userId); USER_SESSION_MAP.put(sessionKey, session); if(USER_SESSION_ID_MAP.containsKey(userId)){ // T人动作 String sessionKeyOld = USER_SESSION_ID_MAP.get(userId); @@ -37,10 +39,11 @@ public class WebSocketSessionHolder { if(webSocketSession != null){ if(webSocketSession.isOpen()){ try { - log.info("检测到该用户存在历史的sessionId={} userId={}, 清理掉",sessionKey, userId); + log.info("检测到该用户存在历史的sessionId={} roomId={} userId={}, 清理掉",sessionKey, roomId, userId); webSocketSession.close(new CloseStatus(500100)); } catch (IOException e) { // ignore + log.error("关闭房间失败",e); } } removeSession(sessionKeyOld); diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/service/RoomService.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/service/RoomService.java index 114b3c7e..7e825f28 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/service/RoomService.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/service/RoomService.java @@ -191,12 +191,6 @@ public class RoomService { userService.updateVideoStatus(receiverId,0); anchorService.updateVideoStatus(receiverId,0); } - // 声网踢人 - if(room.getRoomData().getBeginTime() != null && room.getRoomData().getBeginTime() > 0){ - ExecutorConstant.ROOM_EXECUTOR.execute(() -> { - agora.closeChannel(roomId); - }); - } // 修改释放状态 Map map = new HashMap<>(); map.put("releaseRes",true); diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/service/SettleService.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/service/SettleService.java index baaa5e78..5976bbfa 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/service/SettleService.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/service/SettleService.java @@ -4,10 +4,12 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.extra.spring.SpringUtil; import com.ruoyi.cai.dto.video.VideoSettleResp; import com.ruoyi.cai.dto.video.WithholdingFeeUserResp; +import com.ruoyi.cai.executor.ExecutorConstant; import com.ruoyi.cai.manager.ConsumerManager; import com.ruoyi.cai.manager.LockManager; import com.ruoyi.cai.notice.YunxinWsServiceV2; import com.ruoyi.cai.service.AccountService; +import com.ruoyi.cai.trd.Agora; import com.ruoyi.cai.ws.bean.Room; import com.ruoyi.cai.ws.cache.OnlineDataCache; import com.ruoyi.cai.ws.cache.RoomCtxCache; @@ -45,6 +47,8 @@ public class SettleService { private RoomCtxCache roomCtxCache; @Autowired private RedissonClient redissonClient; + @Autowired + private Agora agora; /** @@ -62,17 +66,18 @@ public class SettleService { Long userId = room.getCallUserData().getId(); Integer price = room.getRoomData().getCallPrice(); settleService.withholdingFeeUser(userId,Long.valueOf(price),room); + log.info("roomId={} 拨打方 1分钟扣分成功",roomId); // 给双方推送可通话时长 try { Long time = roomService.canCallTime(room); List keys = roomCtxCache.getSessionKeysByRoomId(roomId); RoomWebSocketUtil.sendSendMessage(keys, WsRMsgGen.canCallTime(time)); }catch (Exception e){ - log.error("扣费后-推送可通话时长失败!",e); + log.error("roomId={} 扣费后-推送可通话时长失败!",roomId, e); } return true; }catch (Exception e){ - log.error("预扣费失败!准备挂断电话",e); + log.error("roomId={} 预扣费失败!准备挂断电话",roomId,e); boolean b = roomService.hangUp(room.getRoomId()); if(b){ // 结算操作 @@ -140,23 +145,30 @@ public class SettleService { * @param room */ private SettleResp deal(Room room){ - if(room.isCanCall()){ // 正在通话中,无需在结算 + if(room.isCanCall()){ + log.info("roomId={} 房间正在通话中,无需结算",room.getRoomId()); return SettleResp.builder().nextRun(true).build(); } - if(room.isSettle()){ // 已经结算了,无需结算 + if(room.isSettle()){ + log.info("roomId={} 已经结算了,无需结算",room.getRoomId()); return SettleResp.builder().nextRun(false).build(); } if(!room.isReleaseRes()){ // 房间资源是否已经释放 roomService.releaseRes(room.getRoomId()); // 释放房间会更新用户和主播的状态 } Long roomId = room.getRoomId(); - // 未通话,无需结算 VideoSettleResp resp = new VideoSettleResp(); if(room.getRoomData().getBeginTime() == null){ roomDataCache.hMSet(roomId,"settleTime", DateUtil.currentSeconds()); }else{ resp = consumerManager.videoSettle(room); } + // 声网踢人 + if(room.getRoomData().getBeginTime() != null && room.getRoomData().getBeginTime() > 0){ + ExecutorConstant.ROOM_EXECUTOR.execute(() -> { + agora.closeChannel(roomId); + }); + } // 修改房间缓存 Map map = new HashMap<>(); map.put("payCoin",resp.getPayCoin()); diff --git a/ruoyi-websocket-boot/src/main/java/com/ruoyi/consumer/RedisConsumer.java b/ruoyi-websocket-boot/src/main/java/com/ruoyi/consumer/RedisConsumer.java index 9eec3b50..2a00adb2 100644 --- a/ruoyi-websocket-boot/src/main/java/com/ruoyi/consumer/RedisConsumer.java +++ b/ruoyi-websocket-boot/src/main/java/com/ruoyi/consumer/RedisConsumer.java @@ -26,9 +26,7 @@ public class RedisConsumer { executorService.execute(() -> { while (true){ try { - System.out.println(); run(); - System.out.println(); }catch (Exception e){ } diff --git a/ruoyi-websocket-boot/src/main/java/com/ruoyi/consumer/RoomSettleDelayMqConsumer.java b/ruoyi-websocket-boot/src/main/java/com/ruoyi/consumer/RoomSettleDelayMqConsumer.java index f4da2086..7d5b0e7d 100644 --- a/ruoyi-websocket-boot/src/main/java/com/ruoyi/consumer/RoomSettleDelayMqConsumer.java +++ b/ruoyi-websocket-boot/src/main/java/com/ruoyi/consumer/RoomSettleDelayMqConsumer.java @@ -23,7 +23,10 @@ public class RoomSettleDelayMqConsumer { boolean next = settleService.withholdingFee(Long.valueOf(message)); if(next){ // 1分钟后继续执行 + log.info("预扣分完成 1分钟后继续后执行 {}", message); amqpWsProducer.sendRoomSettleDelay(message,60); + }else{ + log.info("预扣费失败 可能余额不足 不在继续执行 {}", message); } }catch (Exception e){ log.error("每分钟定时扣费失败!",e); diff --git a/ruoyi-websocket-boot/src/main/java/com/ruoyi/service/RoomCheckJobService.java b/ruoyi-websocket-boot/src/main/java/com/ruoyi/service/RoomCheckJobService.java index 438bcb41..c936b74c 100644 --- a/ruoyi-websocket-boot/src/main/java/com/ruoyi/service/RoomCheckJobService.java +++ b/ruoyi-websocket-boot/src/main/java/com/ruoyi/service/RoomCheckJobService.java @@ -5,7 +5,9 @@ import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.cai.domain.UserCall; import com.ruoyi.cai.notice.YunxinWsServiceV2; +import com.ruoyi.cai.service.AnchorService; import com.ruoyi.cai.service.UserCallService; +import com.ruoyi.cai.service.UserService; import com.ruoyi.cai.ws.bean.Room; import com.ruoyi.cai.ws.bean.UserData; import com.ruoyi.cai.ws.cache.RoomCtxCache; @@ -90,12 +92,15 @@ public class RoomCheckJobService { UserData receiverUserData = room.getReceiverUserData(); boolean timeOut = false; WsR hangup = null; + String logMessage = null; if(isHeartTimeout(callUserData)){ timeOut = true; hangup = WsRMsgGen.hangup("呼叫方连接中断", roomId, HangUpEnums.FROM.getCode()); + logMessage = "呼叫方连接中断"; }else if(isHeartTimeout(receiverUserData)){ timeOut = true; hangup = WsRMsgGen.hangup("接听方连接中断", roomId, HangUpEnums.TO.getCode()); + logMessage = "接听方连接中断"; } if(timeOut){ boolean nextCreateJob = false; @@ -109,6 +114,8 @@ public class RoomCheckJobService { List keys = roomCtxCache.getSessionKeysByRoomId(roomId); RoomWebSocketUtil.sendSendMessage(keys, hangup); roomService.closeAllFd(roomId); + updateAnchorVideoStatus(room); + log.info("roomId={} 心跳检测发现{} 关闭房间",roomId,logMessage); return JobResp.builder().nextCreateJob(nextCreateJob).build(); } return JobResp.builder().nextCreateJob(true).build(); @@ -148,6 +155,8 @@ public class RoomCheckJobService { if(!nextCreateJob){ yunxinWsService.sendToCallNotify(callUserData.getId(),receiverUserData.getId(), CallNoticeEnum.TIMEOUT,0L); } + updateAnchorVideoStatus(room); + log.info("roomId={} 主播两分钟没有接听, 房间关闭 ",room.getRoomId()); return JobResp.builder().nextCreateJob(nextCreateJob).build(); } return JobResp.builder().nextCreateJob(true).build(); @@ -172,6 +181,26 @@ public class RoomCheckJobService { return true; } + @Autowired + private UserService userService; + @Autowired + private AnchorService anchorService; + + private void updateAnchorVideoStatus(Room room){ + try { + // 释放主播的接听状态 + UserData receiverUserData = room.getReceiverUserData(); + if(receiverUserData != null && receiverUserData.getConnectTime() != null && receiverUserData.getConnectTime() > 0){ + userService.updateVideoStatus(receiverUserData.getId(),0); + anchorService.updateVideoStatus(receiverUserData.getId(),0); + } + log.info("roomId={} 主播状态释放完毕",room.getRoomId()); + }catch (Exception e){ + log.info("roomId={} 主播状态释放失败",room.getRoomId(), e); + } + + } +