package com.fdkankan.tk.service.impl;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.jwt.JWTUtil;
import com.auth0.jwt.JWT;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fdkankan.fyun.face.FYunFileServiceInterface;
import com.fdkankan.redis.constant.RedisKey;
import com.fdkankan.redis.util.RedisUtil;
import com.fdkankan.tk.common.FilePath;
import com.fdkankan.tk.common.PageInfo;
import com.fdkankan.tk.common.ResultCode;
import com.fdkankan.tk.common.WxSharCodePath;
import com.fdkankan.tk.common.util.JwtUtil;
import com.fdkankan.tk.common.util.RedisKeyUtil;
import com.fdkankan.tk.common.util.RoomUtil;
import com.fdkankan.tk.entity.Room;
import com.fdkankan.tk.entity.RoomNum;
import com.fdkankan.tk.entity.RoomUser;
import com.fdkankan.tk.entity.WxUser;
import com.fdkankan.tk.exception.BusinessException;
import com.fdkankan.tk.httpClient.FdKKService;
import com.fdkankan.tk.httpClient.client.FdKKClient;
import com.fdkankan.tk.httpClient.request.FdkkLoginRequest;
import com.fdkankan.tk.httpClient.response.FdkkResponse;
import com.fdkankan.tk.httpClient.response.FdkkUserVo;
import com.fdkankan.tk.mapper.IRoomMapper;
import com.fdkankan.tk.mapper.IRoomUserMapper;
import com.fdkankan.tk.request.RoomAddParam;
import com.fdkankan.tk.request.RoomListParam;
import com.fdkankan.tk.response.DataCount;
import com.fdkankan.tk.response.RoomAddUserParam;
import com.fdkankan.tk.response.RoomVo;
import com.fdkankan.tk.response.SceneVo;
import com.fdkankan.tk.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fdkankan.tk.util.Dateutils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
/**
*
* 服务实现类
*
*
* @author
* @since 2022-09-19
*/
@Service
@Slf4j
public class RoomServiceImpl extends ServiceImpl implements IRoomService {
@Autowired
IRoomNumService roomNumService;
@Autowired
ISceneService sceneService;
@Autowired
FYunFileServiceInterface uploadToOssUtil;
@Autowired
IWxService wxService;
@Value("${fyun.host}")
private String queryPath;
@Autowired
RedisUtil redisUtil;
@Autowired
IWxUserService wxUserService;
@Autowired
RoomUtil roomUtil;
@Autowired
FdKKService fdKKService;
@Autowired
IRoomUserService roomUserService;
@Autowired
IRoomVisitLogService roomVisitLogService;
@Autowired
IRoomDanmakuService roomDanmakuService;
@Override
public PageInfo pageList(RoomListParam param, String token,String wxToken) {
//log.info("roomList--token:{},wxToken:{}",token,wxToken);
if(StringUtils.isBlank(token) && StringUtils.isBlank(wxToken) ){
Page page = new Page<>(param.getPageNum(),param.getPageSize());
return PageInfo.PageInfo(page);
}
Page page = null;
if(StringUtils.isNotBlank(wxToken) ) { //微信小程序调用,返回协作者房间
String wxUserId = JwtUtil.getUserName(wxToken);
WxUser wxUser = wxUserService.getById(wxUserId);
if (wxUser == null || wxUser.getPhoneNumber() == null) {
return PageInfo.PageInfo(new Page<>(param.getPageNum(), param.getPageSize()));
}
param.setUserName(wxUser.getPhoneNumber());
page = this.getBaseMapper().pageWxList(new Page<>(param.getPageNum(), param.getPageSize()), param);
}
if (StringUtils.isNotBlank(token)) {
String fdToken = String.format(RedisKey.TOKEN_V3, token);
if (!redisUtil.hasKey(fdToken)) {
throw new BusinessException(ResultCode.USER_NOT_LOGIN);
}
String userName = JwtUtil.getUserName(token);
redisUtil.expire(fdToken, 6 * 60 * 60);
param.setUserName(userName);
page = this.getBaseMapper().pageList(new Page<>(param.getPageNum(), param.getPageSize()), param);
}
if(page == null){
return PageInfo.PageInfo(new Page<>(param.getPageNum(),param.getPageSize()));
}
FdkkUserVo userInfo = null;
if( StringUtils.isNotBlank(token)){
userInfo = fdKKService.getUserInfo(token);
}
HashMap dataCountMap = roomVisitLogService.getGroupByRoomId();
for (Room record : page.getRecords()) {
DataCount dataCount = dataCountMap.get(record.getRoomId());
if (dataCount != null) {
record.setRoomViewCount(dataCount.getDataCount());
}
if (!record.getRoomUserName().equals(param.getUserName())) {
RoomUser roomUser = roomUserService.getByUserName(record.getRoomId(),param.getUserName());
if (roomUser != null) {
record.setRoomId(record.getRoomId() + "_" + roomUser.getRoomUserId());
record.setHostStatus(roomUser.getHostStatus());
if (roomUser.getLastLookTime() != null) {
record.setLastLookTime(Dateutils.getDate(roomUser.getLastLookTime()));
} else {
record.setLastLookTime(null);
}
if(userInfo != null){
record.setRoomHostName(userInfo.getNickName());
record.setRoomUserName(userInfo.getUserName());
}
record.setIsHomeOwner(false);
}
}
record.setVisitPassword(null);
}
return PageInfo.PageInfo(page);
}
@Override
public Room addOrUpdate(RoomAddParam param, String token) {
if(param.getNumList() == null || param.getNumList().size() <=0){
throw new BusinessException(ResultCode.PARAM_MISS);
}
if(StringUtils.isEmpty(param.getRoomTitle()) ){
throw new BusinessException(ResultCode.PARAM_MISS);
}
Room room = new Room();
BeanUtils.copyProperties(param,room);
room.setRoomUserName(JwtUtil.getUserName(token));
if(StringUtils.isEmpty(room.getRoomHostName())){
room.setRoomHostName(room.getRoomUserName());
}
if(StringUtils.isNotBlank(room.getRoomId())){
room.setUpdateTime(null);
room.setHostStatus(null);
Room byId = this.getById(room.getRoomId());
if(!checkCanDel(byId)){
throw new BusinessException(ResultCode.ROOM_ING);
}
}else {
String roomId = roomUtil.genRoomId(1000);
if(StringUtils.isNotBlank(room.getPlatform()) && room.getPlatform().equals("ucenter")){
roomId = "temp_" + roomId;
}
room.setRoomId(roomId);
}
if(param.getNumList().size() >0){
List list = sceneService.getListByNumList(param.getNumList());
if(list.size() >0){
room.setRoomCoverUrl(list.get(0).getThumb());
}
}
roomUserService.updateByUserObjList(param.getUserObjList(),room);
this.saveOrUpdate(room);
roomNumService.addBatch(room.getRoomId(),param.getNumList());
param.setRoomId(room.getRoomId());
return param;
}
@Override
public Boolean checkCanDel(Room room){
Boolean flag = false;
List roomUserList = roomUserService.getByRoomId(room.getRoomId());
for (RoomUser roomUser : roomUserList) {
if ( roomUser.getRoomStatus() == 1 && roomUser.getHostStatus() == 1){
flag = true;
}
}
if(room.getHostStatus() == 1 || flag){
return false;
}
return true;
}
@Override
public void deleteById(String roomId) {
Room room = this.getById(roomId);
if(room == null ){
throw new BusinessException(ResultCode.ROOM_MISS);
}
if(!checkCanDel(room)){
throw new BusinessException(ResultCode.DEL_ROOM_ING);
}
roomNumService.deleteByRoomId(roomId);
roomUserService.delByRoomId(roomId);
if(StringUtils.isNotBlank(room.getRoomShareUrl())){
try {
uploadToOssUtil.deleteFile(room.getRoomShareUrl());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
this.removeById(roomId);
}
@Override
public RoomVo getRoomInfo(String roomId,String token,String wxToken,String sessionId) {
log.info("getRoomInfo-request-roomId:{},token:{},wxToken:{}",roomId,token,wxToken);
String roomUserId = null;
if(!roomId.contains("temp_") &&roomId.contains("_")){
String[] split = roomId.split("_");
roomId = split[0];
roomUserId = split[1];
}
Room room = this.getById(roomId);
if(room == null){
throw new BusinessException(ResultCode.ROOM_MISS);
}
if(StringUtils.isNotBlank(roomUserId)){
RoomUser roomUser = roomUserService.getById(roomUserId);
if(roomUser == null){
throw new BusinessException(ResultCode.ROOM_MISS);
}
}
List numList = roomNumService.getListByRoomId(roomId);
List list = new ArrayList<>();
if(numList.size() >0){
list = sceneService.getListByNumList(numList);
}
RoomVo roomVo = new RoomVo();
BeanUtils.copyProperties(room,roomVo);
if(StringUtils.isNotBlank(roomUserId)){
roomVo.setRoomId(roomId+"_"+roomUserId);
roomVo.setRoomHostCode("");
roomVo.setRoomShareCode("");
}
String userName = null;
if(StringUtils.isBlank(token)){
roomVo.setVisitPassword(null);
roomVo.setRoomHostName("");
roomVo.setHead("");
}else {
userName = JwtUtil.getUserName(token);
}
if(StringUtils.isNotBlank(roomUserId) && StringUtils.isNotBlank(token)){
FdkkUserVo userInfo = fdKKService.getUserInfo(token);
if(userInfo != null){
roomVo.setRoomHostName(userInfo.getNickName());
roomVo.setRoomUserName(userInfo.getUserName());
roomVo.setHead(userInfo.getHead());
}
}
//
if(StringUtils.isNotBlank(wxToken)){
String redisKey = String.format(RedisKeyUtil.roomPassword, room.getRoomId(), room.getVisitPassword(), wxToken);
log.info("rediskey:{}",redisKey);
if(redisUtil.hasKey(redisKey)){
roomVo.setTakeLookLock(0);
}
WxUser wxUser = wxUserService.getById(JwtUtil.getUserName(wxToken));
userName = wxUser.getPhoneNumber();
}else {
if(StringUtils.isNotBlank(sessionId)){
String redisKey = String.format(RedisKeyUtil.roomPassword, room.getRoomId(), room.getVisitPassword(), sessionId);
log.info("rediskey:{}",redisKey);
if(redisUtil.hasKey(redisKey)){
roomVo.setTakeLookLock(0);
}
}
}
if(roomUserId != null){
RoomUser roomUser = roomUserService.getById(roomUserId);
if(roomUser != null){
roomVo.setRoomHostCode(roomUser.getRoomHostCode());
roomVo.setRoomShareCode(roomUser.getRoomShareCode());
roomVo.setHostStatus(roomUser.getHostStatus());
if(userName!= null && userName.equals(roomUser.getUserName())){
roomVo.setIsHost(1);
}
}
}else if(userName != null && userName.equals(room.getRoomUserName())){
roomVo.setIsHost(1);
}
roomVo.setSceneData(list);
List roomUserList = roomUserService.getByRoomId(roomId);
roomVo.setUserObjList(roomUserList);
log.info("getRoomInfo-response-roomId:{},token:{},wxToken:{},roomVo:{}",roomId,token,wxToken,roomVo);
return roomVo;
}
@Override
public String getWxQrCode(String roomId,String type) {
String roomUserId = null;
RoomUser roomUser = null;
String roomIdDb = roomId;
if(!roomId.contains("temp_") &&roomId.contains("_")){
String[] split = roomId.split("_");
roomIdDb = split[0];
roomUserId = split[1];
roomUser = roomUserService.getById(roomUserId);
if(roomUser == null){
throw new BusinessException(ResultCode.ROOM_MISS);
}
}
Room room = this.getById(roomIdDb);
if(room == null){
throw new BusinessException(ResultCode.ROOM_MISS);
}
String roomShareCode = room.getRoomShareCode();
String roomHostCode = room.getRoomHostCode();
if(roomUser!= null){
roomShareCode = roomUser.getRoomShareCode();
roomHostCode = roomUser.getRoomHostCode();
}
if(type.equals("follower") && StringUtils.isNotBlank(roomShareCode)){ //普通用户二维码
if(uploadToOssUtil.fileExist(roomShareCode) ){
return roomShareCode +"?"+System.currentTimeMillis();
}
}
if(type.equals("leader") && StringUtils.isNotBlank(roomHostCode)){ //主持人二维码
if(uploadToOssUtil.fileExist(roomHostCode) ){
return roomHostCode +"?"+System.currentTimeMillis();
}
}
if(type.equals("leader")){ //检查房间场景可用性
RoomVo roomVo = this.getRoomInfo(roomId,null,null,null);
List sceneData = roomVo.getSceneData();
for (SceneVo sceneDatum : sceneData) {
if(sceneDatum.getStatus() != 2){
throw new BusinessException(ResultCode.SCENE_STATUS_ERROR);
}
}
}
String path = null;
if(type.equals("leader")){
path = String.format(WxSharCodePath.hostCodePath,roomId,type,room.getRoomUserName());
}else {
path = String.format(WxSharCodePath.shardCodePath,roomId,"customer");
}
String localPath = String.format(FilePath.LOCAL_QRCODE_PATH, type,roomId);
String ossPath = String.format(FilePath.OSS_QRCODE_PATH,type, roomId);
wxService.getWxQRCode(path,localPath,0);
if(!new File(localPath).exists()){
throw new BusinessException(ResultCode.QRCODE_MISS);
}
uploadToOssUtil.uploadFile(localPath,ossPath);
if(!uploadToOssUtil.fileExist(ossPath)){
FileUtil.del(localPath);
throw new BusinessException(ResultCode.QRCODE_MISS);
}
if(roomUser != null){
if(type.equals("leader")){
roomUser.setRoomHostCode(queryPath + ossPath);
}else {
roomUser.setRoomShareCode(queryPath + ossPath);
}
roomUserService.updateById(roomUser);
}else {
if(type.equals("leader")){
room.setRoomHostCode(queryPath + ossPath);
}else {
room.setRoomShareCode(queryPath + ossPath);
}
this.updateById(room);
}
FileUtil.del(localPath);
return queryPath + ossPath +"?"+System.currentTimeMillis();
}
/**
* 加入房间,开启带看,退出房间
* type 0 加入房间,1退出房间
* role follower leader
*/
@Override
public void inOrOutRoom(String roomId, String role, Integer type,String userId) {
log.info("inOrOutRoom--roomId:{},role:{},type:{},userId:{}",roomId,role,type,userId);
if(roomId == null || StringUtils.isBlank(role)
|| ( !role.equals("leader") && !role.equals("customer")) ){
throw new BusinessException(ResultCode.PARAM_MISS);
}
String wxRoomId = roomId;
Integer roomUserId = null;
if(!roomId.contains("temp_") && roomId.contains("_")){
String[] split = roomId.split("_");
roomId =split[0];
roomUserId = Integer.parseInt(split[1]);
}
Room room = this.getById(roomId);
if(room == null){
throw new BusinessException(ResultCode.ROOM_MISS);
}
String platform = room.getPlatform();
if(room.getUseStartTime() != null && room.getUseStartTime().getTime() > new Date().getTime()){
throw new BusinessException(ResultCode.ROOM_TIME_ERROR);
}
if(room.getUseEndTime() != null && room.getUseEndTime().getTime() <= new Date().getTime()){
throw new BusinessException(ResultCode.ROOM_END_EX);
}
if(role.equals("customer")){
if(platform.equals("4dkankan")){
roomVisitLogService.addLog(roomId,roomUserId,userId,type,0);
}
this.updateById(room);
return;
}
if(roomUserId != null){ //协作带看
RoomUser roomuser = roomUserService.getById(roomUserId);
roomuser.setLastLookTime(new Date());
if(type == 0 ){ //加入房间,开启带看
roomuser.setRoomStatus(1);
roomuser.setHostStatus(1);
}
if(type == 1 ){ //加入房间,开启带看
roomuser.setHostStatus(0);
}
roomUserService.updateById(roomuser);
}else {
room.setLastLookTime(DateUtil.formatDateTime(new Date()));
if(type == 0) {
room.setHostStatus(1);
}
if(type == 1 ){ //离开房间
room.setHostStatus(0);
}
}
if(type == 0 ){ //加入房间,开启带看
room.setRoomStatus(1);
if( platform.equals("4dkankan")){
roomVisitLogService.addLog(roomId,roomUserId,userId,type,1);
}
}
if(type == 1 ){ //离开房间
if( platform.equals("4dkankan")){
roomVisitLogService.addLog(roomId,roomUserId,userId,type,1);
this.hostLeaveRoom(roomId,roomUserId);
}
}
this.updateById(room);
}
@Override
public Long getCountAndTbStatus() {
return this.getBaseMapper().getCountAndTbStatus();
}
@Override
public List getRunningRoom() {
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.in(Room::getRoomStatus,0,1);
wrapper.eq(Room::getPlatform,"4dkankan");
return this.list(wrapper);
}
@Override
public void stopRoom(String roomId) {
LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(Room::getRoomId,roomId);
wrapper.set(Room::getHostStatus,0);
wrapper.set(Room::getRoomStatus,2);
wrapper.set(Room :: getIsShow,0);
this.update(wrapper);
roomVisitLogService.stopRoom(roomId,null);
roomDanmakuService.saveDanMaku(roomId,null);
List byRoomId = roomUserService.getByRoomId(roomId);
for (RoomUser roomUser : byRoomId) {
roomUserService.stopRoom(roomUser);
}
}
@Override
public void hostLeaveRoom(String roomId, Integer roomUserId) {
roomVisitLogService.stopRoom(roomId,roomUserId);
roomDanmakuService.saveDanMaku(roomId,roomUserId);
}
@Override
public HashMap getByIds(Set roomIds) {
HashMap map = new HashMap<>();
if(roomIds.size() >0){
List rooms = this.listByIds(roomIds);
rooms.forEach(entity -> map.put(entity.getRoomId(),entity));
}
return map;
}
@Override
public List getLikeTitle(String roomTitle) {
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.like(Room::getRoomTitle,roomTitle);
return this.list(wrapper);
}
@Override
public List getRoomByToken(String token) {
String userName = null;
if(StringUtils.isNotBlank(token)){
userName = JwtUtil.getUserName(token);
}
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
if(StringUtils.isNotBlank(userName)){
wrapper.eq(Room::getRoomUserName,userName);
}
return this.list(wrapper);
}
@Override
public void dissolveTheRoom(String roomId) {
this.changRoomStatus(roomId,2);
}
@Override
public void openTheRoom(String roomId) {
this.changRoomStatus(roomId,1);
}
private void changRoomStatus(String roomId,Integer status ){
Room room = this.getById(roomId);
if(room == null){
throw new BusinessException(ResultCode.ROOM_MISS);
}
if(!room.getPlatform().equals("fd") && !room.getPlatform().equals("ucenter") && !room.getPlatform().equals("4dkz")){
throw new BusinessException(ResultCode.ROOM_DISSOLVE_ERROR);
}
LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(Room::getRoomId,room.getRoomId());
wrapper.set(Room::getRoomStatus,status);
this.update(wrapper);
}
@Override
public Room getRoomIdByNum(String num) {
List roomNums = roomNumService.getByNum(num);
List roomIds = roomNums.stream().map(RoomNum::getRoomId).collect(Collectors.toList());
return this.getUcenterPlatform(roomIds);
}
private Room getUcenterPlatform(List roomIds) {
if(roomIds.isEmpty()){
return null;
}
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.in(Room::getRoomId,roomIds);
wrapper.eq(Room::getPlatform,"ucenter");
wrapper.gt(Room::getUseEndTime,new Date());
List list = this.list(wrapper);
if(list.isEmpty()){
return null;
}
return list.get(0);
}
}