This commit is contained in:
张良(004796)
2024-01-11 13:38:35 +08:00
parent acccdc9f79
commit fc2b6ef12d
17 changed files with 85 additions and 23 deletions

View File

@@ -1,5 +1,6 @@
package com.ruoyi.cai.chat; package com.ruoyi.cai.chat;
import cn.hutool.core.map.MapUtil;
import com.ruoyi.cai.config.CaiProperties; import com.ruoyi.cai.config.CaiProperties;
import com.ruoyi.cai.domain.Anchor; import com.ruoyi.cai.domain.Anchor;
import com.ruoyi.cai.domain.User; import com.ruoyi.cai.domain.User;
@@ -9,19 +10,24 @@ 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.CallResp;
import com.ruoyi.cai.dto.app.vo.chat.GetRoomResp; import com.ruoyi.cai.dto.app.vo.chat.GetRoomResp;
import com.ruoyi.cai.enums.SystemConfigEnum; import com.ruoyi.cai.enums.SystemConfigEnum;
import com.ruoyi.cai.manager.IdManager;
import com.ruoyi.cai.manager.SystemConfigManager; import com.ruoyi.cai.manager.SystemConfigManager;
import com.ruoyi.cai.service.AnchorService; import com.ruoyi.cai.service.AnchorService;
import com.ruoyi.cai.service.GuardTotalService; import com.ruoyi.cai.service.GuardTotalService;
import com.ruoyi.cai.service.UserCallService; import com.ruoyi.cai.service.UserCallService;
import com.ruoyi.cai.service.UserService; import com.ruoyi.cai.service.UserService;
import com.ruoyi.cai.ws.bean.Room; 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.cai.ws.manager.WebSocketManager;
import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper; import com.ruoyi.common.helper.LoginHelper;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
@@ -43,6 +49,19 @@ public class ChatManager {
private CaiProperties properties; private CaiProperties properties;
@Autowired @Autowired
private GuardTotalService guardTotalService; private GuardTotalService guardTotalService;
@Autowired
private StringRedisTemplate redisTemplate;
private String setWsToken(Long roomId,Long fromUid,Long toUid){
String token = IdManager.nextIdStr();
String tokenKey = String.format(RedisConstant.WS_TOKEN, token);
Map<String,Object> map = new HashMap<>();
map.put("roomId",roomId);
map.put("fromUid",fromUid);
map.put("toUid",toUid);
redisTemplate.opsForHash().putAll(tokenKey,map);
return token;
}
public CallResp call(CallReq callReq){ public CallResp call(CallReq callReq){
Long userId = LoginHelper.getUserId(); Long userId = LoginHelper.getUserId();
@@ -64,7 +83,9 @@ public class ChatManager {
UserCall call = userCallService.createCall(fromUser, toUser, anchor); UserCall call = userCallService.createCall(fromUser, toUser, anchor);
roomId = webSocketManager.createRoom(call.getId()); roomId = webSocketManager.createRoom(call.getId());
} }
String weSocketUrl = String.format(properties.getWebSocketUrl(),"token",roomId); String wsSocketUrlFormat = systemConfigManager.getSystemConfig(SystemConfigEnum.WS_SOCKET_URL);
String token = setWsToken(roomId, fromUser.getId(), toUser.getId());
String weSocketUrl = String.format(wsSocketUrlFormat,token,roomId);
Long guardPrice = systemConfigManager.getSystemConfigOfLong(SystemConfigEnum.GUARD_PRICE); Long guardPrice = systemConfigManager.getSystemConfigOfLong(SystemConfigEnum.GUARD_PRICE);
// 获取鉴黄规则 TODO // 获取鉴黄规则 TODO
CallResp callResp = new CallResp(); CallResp callResp = new CallResp();

View File

@@ -1,10 +1,10 @@
package com.ruoyi.cai.controller.app; package com.ruoyi.cai.controller.app;
import cn.dev33.satoken.annotation.SaIgnore; import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.util.PhoneUtil;
import com.ruoyi.cai.auth.*; import com.ruoyi.cai.auth.*;
import com.ruoyi.cai.domain.User; import com.ruoyi.cai.domain.User;
import com.ruoyi.cai.enums.CodeEnum; import com.ruoyi.cai.enums.CodeEnum;
import com.ruoyi.cai.manager.CodeManager;
import com.ruoyi.cai.service.SmsVerifyService; import com.ruoyi.cai.service.SmsVerifyService;
import com.ruoyi.cai.service.UserService; import com.ruoyi.cai.service.UserService;
import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.domain.R;
@@ -38,6 +38,10 @@ public class AuthAppController {
@PostMapping("/register") @PostMapping("/register")
@Operation(summary = "注册") @Operation(summary = "注册")
public R<Map<String, Object>> register(@Validated @RequestBody CaiRegisterUser caiUser){ public R<Map<String, Object>> register(@Validated @RequestBody CaiRegisterUser caiUser){
boolean mobile = PhoneUtil.isMobile(caiUser.getUsername());
if(!mobile){
return R.fail(600,"请输入正确的手机格式");
}
String token = caiLoginManager.register(caiUser); String token = caiLoginManager.register(caiUser);
Map<String, Object> ajax = new HashMap<>(); Map<String, Object> ajax = new HashMap<>();
ajax.put("token",token); ajax.put("token",token);
@@ -47,6 +51,10 @@ public class AuthAppController {
@PostMapping("/register/code") @PostMapping("/register/code")
@Operation(summary = "获取注册验证码") @Operation(summary = "获取注册验证码")
public R<Map<String,String>> registerCode(@Validated @RequestBody RegisterCode code){ public R<Map<String,String>> registerCode(@Validated @RequestBody RegisterCode code){
boolean mobile = PhoneUtil.isMobile(code.getMobile());
if(!mobile){
return R.fail(600,"请输入正确的手机格式");
}
smsVerifyService.put(CodeEnum.REGISTER,code.getMobile()); smsVerifyService.put(CodeEnum.REGISTER,code.getMobile());
return R.ok("发送成功"); return R.ok("发送成功");
} }
@@ -54,6 +62,10 @@ public class AuthAppController {
@PostMapping("/resetPassword/code") @PostMapping("/resetPassword/code")
@Operation(summary = "获取重置密码验证码") @Operation(summary = "获取重置密码验证码")
public R<Map<String,String>> resetPasswordCode(@Validated @RequestBody RegisterCode code){ public R<Map<String,String>> resetPasswordCode(@Validated @RequestBody RegisterCode code){
boolean mobile = PhoneUtil.isMobile(code.getMobile());
if(!mobile){
return R.fail(600,"请输入正确的手机格式");
}
User user = userService.getByUsername(code.getMobile()); User user = userService.getByUsername(code.getMobile());
if(user == null){ if(user == null){
throw new ServiceException("用户不存在"); throw new ServiceException("用户不存在");

View File

@@ -1,5 +1,6 @@
package com.ruoyi.cai.controller.app; package com.ruoyi.cai.controller.app;
import com.ruoyi.cai.dto.ConsumeResp;
import com.ruoyi.cai.dto.app.query.GiveGiftRes; import com.ruoyi.cai.dto.app.query.GiveGiftRes;
import com.ruoyi.cai.dto.app.query.GiveGuardReq; import com.ruoyi.cai.dto.app.query.GiveGuardReq;
import com.ruoyi.cai.service.GuardTotalService; import com.ruoyi.cai.service.GuardTotalService;
@@ -26,14 +27,14 @@ public class ConsumeController {
@PostMapping("/give/guard") @PostMapping("/give/guard")
@Operation(summary = "赠送主播守护") @Operation(summary = "赠送主播守护")
public R<Boolean> giveGuard(@RequestBody GiveGuardReq query){ public R<Boolean> giveGuard(@RequestBody GiveGuardReq query){
boolean res = guardTotalService.giveGuard(query); ConsumeResp resp = guardTotalService.giveGuard(query);
return R.ok(res); return R.ok(resp.isSuccess());
} }
@PostMapping("/give/gift") @PostMapping("/give/gift")
@Operation(summary = "赠送主播礼物") @Operation(summary = "赠送主播礼物")
public R<Boolean> giveGift(@RequestBody GiveGiftRes query){ public R<Boolean> giveGift(@RequestBody GiveGiftRes query){
boolean res = userGiftService.giveGift(query); ConsumeResp resp = userGiftService.giveGift(query);
return R.ok(res); return R.ok(resp.isSuccess());
} }
} }

View File

@@ -30,10 +30,12 @@ public class UserCall implements Serializable {
* *
*/ */
private Long fromUid; private Long fromUid;
private String fromUsercode;
/** /**
* *
*/ */
private Long toUid; private Long toUid;
private String toUsercode;
/** /**
* 状态 0 创建通话 1 呼叫方连接上 2呼叫方取消通话 3 接收方连接上 4收到通话取消通话 5.超时未接听 6接听方已拒绝 7 已接听 8通话结束 9已评分 10通话完成 * 状态 0 创建通话 1 呼叫方连接上 2呼叫方取消通话 3 接收方连接上 4收到通话取消通话 5.超时未接听 6接听方已拒绝 7 已接听 8通话结束 9已评分 10通话完成
*/ */

View File

@@ -0,0 +1,9 @@
package com.ruoyi.cai.dto;
import lombok.Data;
@Data
public class ConsumeResp {
private Long consumeLogId;
private boolean success;
}

View File

@@ -24,10 +24,6 @@ public class CallResp {
private String toAvatar; private String toAvatar;
@Schema(description = "wsUrl") @Schema(description = "wsUrl")
private String socketUrl; private String socketUrl;
@Schema(description = "技能名称")
private String skillName;
@Schema(description = "技能头像")
private String skillIcon;
@Schema(description = "价格") @Schema(description = "价格")
private Long price; private Long price;
@Schema(description = "评分") @Schema(description = "评分")

View File

@@ -31,7 +31,6 @@ public class GetRoomResp {
private Long price; private Long price;
@Schema(description = "评分") @Schema(description = "评分")
private BigDecimal score; private BigDecimal score;
@Schema(description = "服务次数") @Schema(description = "服务次数")
private Long serviceCount; private Long serviceCount;
@Schema(description = "服务时间") @Schema(description = "服务时间")

View File

@@ -28,6 +28,7 @@ public enum SystemConfigEnum {
SMS_CODE_ADMIN("", "万能验证码",SystemConfigGroupEnum.SYSTEM), SMS_CODE_ADMIN("", "万能验证码",SystemConfigGroupEnum.SYSTEM),
PASSWORD_ADMIN("", "公用密码",SystemConfigGroupEnum.SYSTEM), PASSWORD_ADMIN("", "公用密码",SystemConfigGroupEnum.SYSTEM),
SYSTEM_CUSTOMER_SERVICE("", "系统客服",SystemConfigGroupEnum.SYSTEM), SYSTEM_CUSTOMER_SERVICE("", "系统客服",SystemConfigGroupEnum.SYSTEM),
WS_SOCKET_URL("ws://localhost:8080?token=%s&room_id=%s", "ws通讯地址",SystemConfigGroupEnum.SYSTEM),
; ;

View File

@@ -3,6 +3,7 @@ package com.ruoyi.cai.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.cai.domain.GuardTotal; import com.ruoyi.cai.domain.GuardTotal;
import com.ruoyi.cai.dto.ConsumeResp;
import com.ruoyi.cai.dto.app.dto.GuardNum; import com.ruoyi.cai.dto.app.dto.GuardNum;
import com.ruoyi.cai.dto.app.query.GiveGuardReq; import com.ruoyi.cai.dto.app.query.GiveGuardReq;
import com.ruoyi.cai.dto.app.vo.index.GuardIndexVo; import com.ruoyi.cai.dto.app.vo.index.GuardIndexVo;
@@ -19,7 +20,7 @@ public interface GuardTotalService extends IService<GuardTotal> {
GuardIndexVo guardInfoVo(Long fromUserId,Long toUserId, Integer limit); GuardIndexVo guardInfoVo(Long fromUserId,Long toUserId, Integer limit);
boolean giveGuard(GiveGuardReq query); ConsumeResp giveGuard(GiveGuardReq query);
GuardNum getGuardNum(Long fromUserId, Long toUserId); GuardNum getGuardNum(Long fromUserId, Long toUserId);

View File

@@ -2,6 +2,7 @@ package com.ruoyi.cai.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.cai.domain.UserGift; import com.ruoyi.cai.domain.UserGift;
import com.ruoyi.cai.dto.ConsumeResp;
import com.ruoyi.cai.dto.app.query.GiveGiftRes; import com.ruoyi.cai.dto.app.query.GiveGiftRes;
import com.ruoyi.cai.dto.app.vo.index.UserGiftIndexVo; import com.ruoyi.cai.dto.app.vo.index.UserGiftIndexVo;
@@ -17,6 +18,6 @@ public interface UserGiftService extends IService<UserGift> {
List<UserGiftIndexVo> selectGiftList(Long userId); List<UserGiftIndexVo> selectGiftList(Long userId);
boolean giveGift(GiveGiftRes query); ConsumeResp giveGift(GiveGiftRes query);
} }

View File

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.cai.domain.*; import com.ruoyi.cai.domain.*;
import com.ruoyi.cai.dto.ConsumeResp;
import com.ruoyi.cai.dto.app.dto.GuardNum; import com.ruoyi.cai.dto.app.dto.GuardNum;
import com.ruoyi.cai.dto.app.query.GiveGuardReq; import com.ruoyi.cai.dto.app.query.GiveGuardReq;
import com.ruoyi.cai.dto.app.dto.GuardTotalDTO; import com.ruoyi.cai.dto.app.dto.GuardTotalDTO;
@@ -78,7 +79,7 @@ public class GuardTotalServiceImpl extends ServiceImpl<GuardTotalMapper, GuardTo
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public boolean giveGuard(GiveGuardReq query) { public ConsumeResp giveGuard(GiveGuardReq query) {
Long fromUserId = LoginHelper.getUserId(); Long fromUserId = LoginHelper.getUserId();
User fromUser = userService.getById(fromUserId); User fromUser = userService.getById(fromUserId);
User toUser = userService.getById(query.getToUserId()); User toUser = userService.getById(query.getToUserId());
@@ -101,6 +102,7 @@ public class GuardTotalServiceImpl extends ServiceImpl<GuardTotalMapper, GuardTo
if(lock.isLocked()){ if(lock.isLocked()){
throw new ServiceException("您点击太快了"); throw new ServiceException("您点击太快了");
} }
ConsumeResp resp = new ConsumeResp();
try { try {
lock.lock(3, TimeUnit.SECONDS); lock.lock(3, TimeUnit.SECONDS);
Long guardValue = query.getGuardNum() * guardPrice; Long guardValue = query.getGuardNum() * guardPrice;
@@ -111,7 +113,8 @@ public class GuardTotalServiceImpl extends ServiceImpl<GuardTotalMapper, GuardTo
consumeLog.setType(ConsumeLogType.GUARD.getCode()); consumeLog.setType(ConsumeLogType.GUARD.getCode());
consumeLog.setAmount(guardValue); consumeLog.setAmount(guardValue);
consumeLog.setTargetRate(anchor.getGuardRate()); consumeLog.setTargetRate(anchor.getGuardRate());
accountService.decr(consumeLog, AccountBusinessEnum.GUARD); consumeLog = accountService.decr(consumeLog, AccountBusinessEnum.GUARD);
resp.setConsumeLogId(consumeLog.getId());
GuardLog guardLog = new GuardLog(); GuardLog guardLog = new GuardLog();
guardLog.setFromUserId(fromUserId); guardLog.setFromUserId(fromUserId);
guardLog.setFromUsercode(fromUser.getUsercode()); guardLog.setFromUsercode(fromUser.getUsercode());
@@ -141,7 +144,8 @@ public class GuardTotalServiceImpl extends ServiceImpl<GuardTotalMapper, GuardTo
}finally { }finally {
lock.unlock(); lock.unlock();
} }
return true; resp.setSuccess(true);
return resp;
} }
@Override @Override

View File

@@ -36,14 +36,14 @@ public class UserCallServiceImpl extends ServiceImpl<UserCallMapper, UserCall> i
throw new ServiceException("不能给自己拨打哦!"); throw new ServiceException("不能给自己拨打哦!");
} }
if(anchor == null){ if(anchor == null){
throw new ServiceException("主播技能不存在"); throw new ServiceException("主播不存在");
} }
if(anchor.getOpenVideoStatus() == 0){ if(anchor.getOpenVideoStatus() == 0){
throw new ServiceException("对方未开启视频接听!"); throw new ServiceException("对方未开启视频接听!");
} }
Account account = accountService.getByUserId(fromUid); Account account = accountService.getByUserId(fromUid);
if(account.getIncomeCoin() + account.getCoin() < anchor.getPrice() * 2){ if(account.getIncomeCoin() + account.getCoin() < anchor.getPrice() * 2){
throw new ServiceException("你的紫贝不足!"); throw new ServiceException("你的余额不足!");
} }
UserCall userCall = new UserCall(); UserCall userCall = new UserCall();
userCall.setFromUid(fromUid); userCall.setFromUid(fromUid);

View File

@@ -2,6 +2,7 @@ package com.ruoyi.cai.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.cai.domain.*; import com.ruoyi.cai.domain.*;
import com.ruoyi.cai.dto.ConsumeResp;
import com.ruoyi.cai.dto.app.query.GiveGiftRes; import com.ruoyi.cai.dto.app.query.GiveGiftRes;
import com.ruoyi.cai.dto.app.vo.index.UserGiftIndexVo; import com.ruoyi.cai.dto.app.vo.index.UserGiftIndexVo;
import com.ruoyi.cai.enums.AccountBusinessEnum; import com.ruoyi.cai.enums.AccountBusinessEnum;
@@ -51,7 +52,7 @@ public class UserGiftServiceImpl extends ServiceImpl<UserGiftMapper, UserGift> i
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public boolean giveGift(GiveGiftRes query) { public ConsumeResp giveGift(GiveGiftRes query) {
Long fromUserId = LoginHelper.getUserId(); Long fromUserId = LoginHelper.getUserId();
Gift gift = giftService.getById(query.getGiftId()); Gift gift = giftService.getById(query.getGiftId());
if(gift == null){ if(gift == null){
@@ -62,6 +63,7 @@ public class UserGiftServiceImpl extends ServiceImpl<UserGiftMapper, UserGift> i
if(lock.isLocked()){ if(lock.isLocked()){
throw new ServiceException("您点击太快了"); throw new ServiceException("您点击太快了");
} }
ConsumeResp resp = new ConsumeResp();
try { try {
lock.lock(3, TimeUnit.SECONDS); lock.lock(3, TimeUnit.SECONDS);
User fromUser = userService.getById(fromUserId); User fromUser = userService.getById(fromUserId);
@@ -76,7 +78,8 @@ public class UserGiftServiceImpl extends ServiceImpl<UserGiftMapper, UserGift> i
consumeLog.setType(ConsumeLogType.GIFT.getCode()); consumeLog.setType(ConsumeLogType.GIFT.getCode());
consumeLog.setAmount(giftAmount); consumeLog.setAmount(giftAmount);
consumeLog.setTargetRate(anchor.getGiftRate()); consumeLog.setTargetRate(anchor.getGiftRate());
accountService.decr(consumeLog, AccountBusinessEnum.GIFT); consumeLog = accountService.decr(consumeLog, AccountBusinessEnum.GIFT);
resp.setConsumeLogId(consumeLog.getId());
UserGift userGift = new UserGift(); UserGift userGift = new UserGift();
userGift.setType(query.getType()); userGift.setType(query.getType());
userGift.setFromUid(fromUserId); userGift.setFromUid(fromUserId);
@@ -96,6 +99,7 @@ public class UserGiftServiceImpl extends ServiceImpl<UserGiftMapper, UserGift> i
}finally { }finally {
lock.unlock(); lock.unlock();
} }
return true; resp.setSuccess(true);
return resp;
} }
} }

View File

@@ -2,6 +2,7 @@ package com.ruoyi.cai.ws.constant;
public class RedisConstant { public class RedisConstant {
public static final String REDIS_P = "caiws-"; public static final String REDIS_P = "caiws-";
public static final String WS_TOKEN = REDIS_P + "wxToken:%s";
public static final String ONLINE_ROOM_DATA = REDIS_P + "onlineRoomData"; public static final String ONLINE_ROOM_DATA = REDIS_P + "onlineRoomData";
public static final String ROOM_DATA = REDIS_P + "roomData:%s"; public static final String ROOM_DATA = REDIS_P + "roomData:%s";
public static final String FDCTX_DATA = REDIS_P + "fdctx:%s"; public static final String FDCTX_DATA = REDIS_P + "fdctx:%s";

View File

@@ -8,7 +8,7 @@ public enum RoomStatusEnums {
/** /**
* 刚创建 * 刚创建
*/ */
STATUS_CREATE(0,"创建"), STATUS_CREATE(0,"创建通话"),
/** /**
* 呼叫方连接上 * 呼叫方连接上
*/ */

View File

@@ -0,0 +1,10 @@
package com.ruoyi.cai.ws.dto;
import lombok.Data;
@Data
public class WsToken {
private Long roomId;
private Long fromUid;
private Long toUid;
}

View File

@@ -59,7 +59,7 @@ public class WebSocketManager {
if(userCall == null){ if(userCall == null){
throw new ServiceException("无效房间"); throw new ServiceException("无效房间");
} }
Room room = checkOnlineRoom(userCall.getFromUid(), userCall.getToUid()); Room room = this.checkOnlineRoom(userCall.getFromUid(), userCall.getToUid());
if(room != null && room.isCanCall()){ // 缓存中存在旧房间,直接返回 if(room != null && room.isCanCall()){ // 缓存中存在旧房间,直接返回
return room.getRoomId(); return room.getRoomId();
} }