package com.ruoyi.cai.chat; import com.ruoyi.cai.domain.Account; import com.ruoyi.cai.domain.Anchor; import com.ruoyi.cai.domain.User; import com.ruoyi.cai.domain.UserCall; import com.ruoyi.cai.dto.app.dto.GuardNum; import com.ruoyi.cai.dto.app.query.CallReq; import com.ruoyi.cai.dto.app.vo.chat.CallResp; import com.ruoyi.cai.dto.app.vo.chat.GetRoomResp; import com.ruoyi.cai.enums.SystemConfigEnum; import com.ruoyi.cai.manager.IdManager; import com.ruoyi.cai.manager.SystemConfigManager; import com.ruoyi.cai.service.*; import com.ruoyi.cai.ws.bean.Room; import com.ruoyi.cai.ws.constant.RedisConstant; import com.ruoyi.cai.ws.dto.WsToken; import com.ruoyi.cai.ws.manager.WebSocketManager; import com.ruoyi.common.utils.MapGetUtil; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.helper.LoginHelper; import org.redisson.api.RMap; import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.time.Duration; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; @Component public class ChatManager { @Autowired private UserService userService; @Autowired private AnchorService anchorService; @Autowired private WebSocketManager webSocketManager; @Autowired private UserCallService userCallService; @Autowired private SystemConfigManager systemConfigManager; @Autowired private GuardTotalService guardTotalService; @Autowired private RedissonClient redissonClient; @Autowired private AccountService accountService; private String setWsToken(Long roomId,Long fromUid,Long toUid,Long userId){ String token = IdManager.nextIdStr(); String tokenKey = String.format(RedisConstant.WS_TOKEN, token); Map map = new HashMap<>(); map.put("roomId",roomId); map.put("fromUid",fromUid); map.put("toUid",toUid); map.put("userId",userId); RMap mapRedis = redissonClient.getMap(tokenKey); mapRedis.putAll(map); mapRedis.expire(Duration.ofDays(1)); return token; } public WsToken getToken(String token){ String tokenKey = String.format(RedisConstant.WS_TOKEN, token); RMap mapRedis = redissonClient.getMap(tokenKey); Map entries = mapRedis.readAllMap(); if(entries.isEmpty()){ return null; } WsToken wsToken = new WsToken(); wsToken.setRoomId(MapGetUtil.getLong(entries.get("roomId"))); wsToken.setFromUid(MapGetUtil.getLong(entries.get("fromUid"))); wsToken.setToUid(MapGetUtil.getLong(entries.get("toUid"))); wsToken.setUserId(MapGetUtil.getLong(entries.get("userId"))); return wsToken; } public CallResp call(CallReq callReq){ Long userId = LoginHelper.getUserId(); User fromUser = userService.getById(userId); User toUser = userService.getById(callReq.getToUid()); if(toUser == null){ throw new ServiceException("主播不存在"); } if(toUser.getIsAnchor() != 1){ throw new ServiceException("对方未通过女神认证,不能接听视频"); } if(fromUser.getGender() == 1 && toUser.getGender() == 1){ throw new ServiceException("主播和主播之间,不可以拨打视频哦~"); } Anchor anchor = anchorService.getByUserId(toUser.getId()); if(anchor == null){ throw new ServiceException("主播技能不存在"); } Account account = accountService.getByUserId(userId); if(account == null){ throw new ServiceException("账户异常,请联系客服"); } long coin = account.getIncomeCoin() + account.getCoin(); if(coin < anchor.getPrice()*2){ throw new ServiceException("您的余额不足,请充值"); } Long roomId = null; Room room = webSocketManager.checkOnlineRoom(fromUser.getId(), toUser.getId()); if(room == null){ UserCall call = userCallService.createCall(fromUser, toUser, anchor); roomId = webSocketManager.createRoom(call.getId()); }else{ roomId = room.getRoomId(); } String wsSocketUrlFormat = systemConfigManager.getWebSocketUrl(); String token = setWsToken(roomId, fromUser.getId(), toUser.getId(),userId); String weSocketUrl = String.format(wsSocketUrlFormat,token,roomId); Long guardPrice = systemConfigManager.getSystemConfigOfLong(SystemConfigEnum.GUARD_PRICE); // 获取鉴黄规则 TODO CallResp callResp = new CallResp(); callResp.setRoomId(roomId); callResp.setFromUid(fromUser.getId()); callResp.setFromNickname(fromUser.getNickname()); callResp.setFromAvatar(fromUser.getAvatar()); callResp.setToUid(toUser.getId()); callResp.setToNickname(toUser.getNickname()); callResp.setToAvatar(toUser.getAvatar()); callResp.setSocketUrl(weSocketUrl); callResp.setPrice(anchor.getPrice()); callResp.setScore(anchor.getGiveScore()); callResp.setServiceCount(anchor.getServiceCount()); callResp.setServiceTime(anchor.getServiceTime()); GuardNum guardNum = guardTotalService.getGuardNum(fromUser.getId(), toUser.getId()); callResp.setGuardDiffNum(guardNum.getDiffNum()); callResp.setGuardPrice(guardPrice); return callResp; } public GetRoomResp getRoom(String roomId){ Long userId = LoginHelper.getUserId(); UserCall userCall = userCallService.getById(roomId); if(userCall == null){ throw new ServiceException("房间不存在"); } if(!userCall.getFromUid().equals(userId) && !userCall.getToUid().equals(userId)){ throw new ServiceException("无权限操作房间"); } Room room = webSocketManager.checkOnlineRoom(userCall.getFromUid(), userCall.getToUid()); if (room == null) { throw new ServiceException("'对方已取消通话'"); } List userList = userService.listByIds(Arrays.asList(userCall.getFromUid(), userCall.getToUid())); Map userMap = userList.stream().collect(Collectors.toMap(User::getId, Function.identity())); User fromUser = userMap.get(userCall.getFromUid()); User toUser = userMap.get(userCall.getToUid()); Anchor anchor = anchorService.getByUserId(toUser.getId()); String wsSocketUrlFormat = systemConfigManager.getWebSocketUrl(); String token = setWsToken(room.getRoomId(), fromUser.getId(), toUser.getId(), userId); String weSocketUrl = String.format(wsSocketUrlFormat,token,room.getRoomId()); GetRoomResp getRoomResp = new GetRoomResp(); getRoomResp.setRoomId(room.getRoomId()+""); getRoomResp.setFromUid(userCall.getFromUid()); getRoomResp.setFromNickname(fromUser.getNickname()); getRoomResp.setFromAvatar(fromUser.getAvatar()); getRoomResp.setToUid(userCall.getToUid()); getRoomResp.setToNickname(toUser.getNickname()); getRoomResp.setToAvatar(toUser.getAvatar()); getRoomResp.setSocketUrl(weSocketUrl); getRoomResp.setPrice(anchor.getPrice()); getRoomResp.setScore(anchor.getGiveScore()); getRoomResp.setServiceCount(anchor.getServiceCount()); getRoomResp.setServiceTime(anchor.getServiceTime()); return getRoomResp; } }