This commit is contained in:
张良(004796)
2024-05-06 16:39:56 +08:00
parent e0389ad597
commit 4b35d1d089
23 changed files with 394 additions and 8 deletions

View File

@@ -18,6 +18,8 @@ public class RedisHttpConstant {
public static final String RECHARGE_RANK_REDIS = REDIS_P + "rechargeRank:%s:%s";
public static final String ANCHOR_COUNT_REDIS = REDIS_P + "anchorCount:%s";
public static final String CHECK_LOGIN_NUM = REDIS_P + "checkLoginNum:%s";
public static final String MIN_USER_IM_REDIS = REDIS_P + "minUserIm:%s";
public static final String CHAT_RECORD_CACHE_REDIS = REDIS_P + "chatRecordCache:%s";
public static final String HOME_RECOMMEND_TOP_REDIS = REDIS_P + "homeRecommendAnchorTop";
public static final String HOME_RECOMMEND_REDIS = REDIS_P + "homeRecommendAnchor";

View File

@@ -0,0 +1,13 @@
package com.ruoyi.cai.dto.commom.user;
import lombok.Data;
@Data
public class MinUser {
private Long id;
private Integer gender;
/**
* 隐身模式 0-关闭 1-打开
*/
private Integer noGreet;
}

View File

@@ -92,6 +92,8 @@ public enum SystemConfigEnum {
PASSWORD_ADMIN("", "公用密码",SystemConfigGroupEnum.SYSTEM),
IPV6_FILTER("0", "是否开启IPV6请求拦截",SystemConfigGroupEnum.SYSTEM, new BooleanSystemConfigCheck()),
IPV6_FILTER_PATH("/api/auth/login", "IPV6拦截路由配置逗号分隔",SystemConfigGroupEnum.SYSTEM, new BooleanSystemConfigCheck(),"textarea"),
VIP_PRIVATE_PLUS("0", "开启VIP隐私模式增强模式",SystemConfigGroupEnum.SYSTEM,new BooleanSystemConfigCheck()),
IM_FILTER_PLUS("4", "IM拦截配置勿动开发配置",SystemConfigGroupEnum.SYSTEM),
COS_DOMAIN("http://nono-1257812345.cos.ap-shanghai.myqcloud.com/", "文件系统域名前缀",SystemConfigGroupEnum.SYSTEM),
SYSTEM_CUSTOMER_SERVICE("2,4", "系统客服",SystemConfigGroupEnum.SYSTEM),
PRIVACY_AGREEMENT("/#/agreement/privacy", "隐私协议地址",SystemConfigGroupEnum.SYSTEM),

View File

@@ -0,0 +1,20 @@
package com.ruoyi.cai.im;
import lombok.Data;
@Data
public class ImCheckResp {
private int errCode = 0;
private int responseCode;
public static ImCheckResp ok(){
return new ImCheckResp();
}
public static ImCheckResp fail(){
ImCheckResp resp = new ImCheckResp();
resp.setErrCode(1);
resp.setResponseCode(20001);
return resp;
}
}

View File

@@ -1,8 +1,13 @@
package com.ruoyi.cai.im;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.cai.domain.UserChatRecord;
import com.ruoyi.cai.dto.commom.user.MinUser;
import com.ruoyi.cai.enums.SystemConfigEnum;
import com.ruoyi.cai.manager.SystemConfigManager;
import com.ruoyi.cai.service.UserChatRecordService;
import com.ruoyi.cai.service.UserService;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.yunxin.client.ImUserClient;
import com.ruoyi.yunxin.client.ImUserRefClient;
@@ -13,6 +18,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
@Slf4j
@Component
@@ -23,6 +32,10 @@ public class ImManager {
private ImUserRefClient userRefClient;
@Resource
private ImUserClient imUserClient;
@Autowired
private UserService userService;
@Autowired
private UserChatRecordService userChatRecordService;
public boolean blockUser(Long userId,Long blackUserId){
SetSpecialRelationReq req = new SetSpecialRelationReq();
@@ -110,4 +123,74 @@ public class ImManager {
log.error("云信调用失败!【updateImInfo】",e);
}
}
private final static Set<Long> INNER_USER_ID = new HashSet<>();
static {
INNER_USER_ID.add(2L);
INNER_USER_ID.add(4L);
}
private final static String RECORD_ID_FILTER = "4";
private final static String RECORD_ID_PLUS_FILTER = "5";
private final static String GENDER_FILTER = "6";
private final static String VIP_PLUS_FILTER = "7";
// 4-recordId拦截 5-recordId加强拦截 6-性别拦截 7-vip加强拦截
public boolean filterMessage(JSONObject body){
String eventType = body.getString("eventType");
String msgType = body.getString("msgType");
Long fromUserId = body.getLong("fromAccount");
Long toUserId = body.getLong("to");
if(INNER_USER_ID.contains(fromUserId) || INNER_USER_ID.contains(toUserId)){
return true;
}
if(!"1".equals(eventType)){
return true;
}
if(!"TEXT".equals(msgType) && !"PICTURE".equals(msgType)){
return true;
}
String filterString = systemConfigManager.getSystemConfig(SystemConfigEnum.IM_FILTER_PLUS);
if(StringUtils.isBlank(filterString)){
return true;
}
Set<String> filterSet = Arrays.stream(filterString.split(",")).collect(Collectors.toSet());
if(filterSet.contains(RECORD_ID_FILTER)){
String ext = body.getString("ext");
JSONObject extJson = JSON.parseObject(ext);
String recordId = extJson.getString("recordId");
if(StringUtils.isEmpty(recordId) || "0".equals(recordId)){
log.error("IM拦截成功! 拦截到用户脚本请求数据={}",body.toJSONString());
return false;
}
if(filterSet.contains(RECORD_ID_PLUS_FILTER)){
UserChatRecord userChatRecord = userChatRecordService.getByCache(recordId);
if(userChatRecord == null){
log.error("IM拦截成功! recordId增强模式 拦截到用户脚本请求数据={}",body.toJSONString());
return false;
}
}
}
if(filterSet.contains(GENDER_FILTER)){
MinUser fromUser = userService.getMinUserByIdBomCache(fromUserId);
MinUser toUser = userService.getMinUserByIdBomCache(toUserId);
if(fromUser == null){
log.error("IM拦截成功! 发送人用户不存在={}",body.toJSONString());
return false;
}
if(toUser == null){
log.error("IM拦截成功! 接受人用户不存在={}",body.toJSONString());
return false;
}
if(fromUser.getGender().equals(toUser.getGender())){
log.error("IM拦截成功! 同性用户不能发送消息={}",body.toJSONString());
return false;
}
}
return true;
}
}

View File

@@ -13,6 +13,7 @@ import com.ruoyi.cai.dto.app.vo.ImResp;
import com.ruoyi.cai.dto.commom.im.ImgContentDTO;
import com.ruoyi.cai.enums.ChatTypeEnum;
import com.ruoyi.cai.enums.GenderEnum;
import com.ruoyi.cai.enums.SystemConfigEnum;
import com.ruoyi.cai.enums.UserMemberTypeEnum;
import com.ruoyi.cai.enums.im.ImImgStatusEnum;
import com.ruoyi.cai.mq.AmqpHttpProducer;
@@ -57,6 +58,8 @@ public class ImService {
private SensitiveWordBs sensitiveWordBs;
@Autowired
private UserChatFilterService userChatFilterService;
@Autowired
private SystemConfigManager systemConfigManager;
public ImResp sendMessage(Long fromUserId, ImMessageDTO message) {
ChatTypeEnum typeEnum = ChatTypeEnum.getByType(message.getType());
@@ -96,13 +99,6 @@ public class ImService {
resp.setContent(message.getContent());
return resp;
}
boolean fileType = typeEnum.isFileType();
if(fileType){
boolean star = userFollowService.checkStar(toUserId, fromUserId);
if(!star){
throw new ServiceException("对方关注你才能发送图片|语音|视频");
}
}
if(fromUserId.equals(toUserId)){
throw new ServiceException("不能给自己发送哦!");
}
@@ -134,6 +130,26 @@ public class ImService {
if (fromUser.getIsAnchor().equals(0) && toUser.getIsAnchor().equals(0)) {
throw new ServiceException("目前只能和女神私信!");
}
boolean star = false;
boolean starFlag = false;
boolean fileType = typeEnum.isFileType();
if(fileType){
star = userFollowService.checkStar(toUserId, fromUserId);
starFlag = true;
if(!star){
throw new ServiceException("对方关注你才能发送图片|语音|视频");
}
}
boolean vipPricePlus = systemConfigManager.getSystemConfigOfBool(SystemConfigEnum.VIP_PRIVATE_PLUS);
// 判断隐私模式
if(vipPricePlus && fromUser.getNoGreet().equals(1)){
if(!starFlag){
star = userFollowService.checkStar(toUserId, fromUserId);
}
if(!star){
throw new ServiceException("对方开启隐私模式,关注你才能发送消息");
}
}
int filter = 0;
String content = message.getContent();
// 正则判断违规数据替换

View File

@@ -120,6 +120,15 @@ public class SystemConfigManager {
}
public Set<String> getSystemConfigOfSet(SystemConfigEnum systemConfig) {
String value = getSystemConfig(systemConfig);
if(StringUtils.isBlank(value)){
value = systemConfig.getDefaultValue();
}
return Stream.of(value.split(",")).collect(Collectors.toSet());
}
/**
* 获取所有配置
* @return
@@ -147,4 +156,5 @@ public class SystemConfigManager {
}
redisTemplate.opsForHash().put(RedisHttpConstant.SYSTEM_CONFIG, key,value);
}
}

View File

@@ -8,6 +8,7 @@ import com.ruoyi.cai.dto.app.query.index.GreetQuery;
import com.ruoyi.cai.dto.app.query.index.UserMapperQuery;
import com.ruoyi.cai.dto.app.query.index.UserQuery;
import com.ruoyi.cai.dto.app.vo.user.UserListVo;
import com.ruoyi.cai.dto.commom.user.MinUser;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@@ -25,4 +26,6 @@ public interface UserMapper extends BaseMapper<User> {
Page<UserListVo> greetPageApp(@Param("build") Page<Object> build, @Param("query") GreetQuery query);
List<Long> getGreetNumId(@Param("userId") Long userId);
MinUser getMinUserById(@Param("userId") Long userId);
}

View File

@@ -13,7 +13,9 @@ import com.ruoyi.cai.dto.app.query.im.ImMessageDTO;
*/
public interface UserChatRecordService extends IService<UserChatRecord> {
UserChatRecord saveRecord(User fromUser, User toUser,Long traceId, ImMessageDTO message);
UserChatRecord getByCache(String recordId);
UserChatRecord saveRecord(User fromUser, User toUser, Long traceId, ImMessageDTO message);
void clearChatRecord(Integer hours);
}

View File

@@ -37,6 +37,8 @@ public interface UserMemberService extends IService<UserMember> {
void relieveMember(Long id);
void checkAndUpdateUser(Long userId);
MemberInfoVo memberApp(Long userId, Integer type);
void updateRankHide(UpdateRankHideReq updateRankHideReq);

View File

@@ -9,6 +9,7 @@ import com.ruoyi.cai.dto.app.query.index.UserQuery;
import com.ruoyi.cai.dto.app.vo.user.UserInfoVo;
import com.ruoyi.cai.dto.app.vo.user.UserListVo;
import com.ruoyi.cai.dto.app.vo.user.UserMinInfoVo;
import com.ruoyi.cai.dto.commom.user.MinUser;
import com.ruoyi.common.core.domain.PageQuery;
/**
@@ -21,6 +22,10 @@ public interface UserService extends IService<User> {
User getByUsername(String username);
MinUser getMinUserByIdBomCache(Long userId);
MinUser getMinUserById(Long userId);
Page<UserAdminVo> pageAdmin(PageQuery pageQuery, UserAdminVo query);
Page<UserListVo> pageApp(PageQuery page, UserQuery query);

View File

@@ -2,6 +2,7 @@ package com.ruoyi.cai.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.cai.constant.RedisHttpConstant;
import com.ruoyi.cai.domain.User;
import com.ruoyi.cai.domain.UserChatRecord;
import com.ruoyi.cai.dto.app.query.im.ImMessageDTO;
@@ -9,10 +10,14 @@ import com.ruoyi.cai.mapper.UserChatRecordMapper;
import com.ruoyi.cai.service.UserChatRecordService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
@@ -25,6 +30,16 @@ import java.util.stream.Collectors;
@Service
public class UserChatRecordServiceImpl extends ServiceImpl<UserChatRecordMapper,UserChatRecord> implements UserChatRecordService {
@Autowired
private RedissonClient redissonClient;
@Override
public UserChatRecord getByCache(String recordId){
String key = String.format(RedisHttpConstant.CHAT_RECORD_CACHE_REDIS, recordId);
RBucket<UserChatRecord> bucket = redissonClient.getBucket(key);
return bucket.get();
}
@Override
public UserChatRecord saveRecord(User fromUser, User toUser,Long traceId, ImMessageDTO message) {
UserChatRecord userChatRecord = new UserChatRecord();
@@ -37,6 +52,9 @@ public class UserChatRecordServiceImpl extends ServiceImpl<UserChatRecordMapper,
userChatRecord.setCreateTime(LocalDateTime.now());
userChatRecord.setTraceId(traceId);
this.save(userChatRecord);
String key = String.format(RedisHttpConstant.CHAT_RECORD_CACHE_REDIS, userChatRecord.getId());
RBucket<UserChatRecord> bucket = redissonClient.getBucket(key);
bucket.set(userChatRecord,10, TimeUnit.MINUTES);
return userChatRecord;
}

View File

@@ -102,6 +102,17 @@ public class UserMemberServiceImpl extends ServiceImpl<UserMemberMapper, UserMem
.set(UserMember::getMemberStatus, MemberStatusEnum.FAIL.getCode()));
}
@Override
public void checkAndUpdateUser(Long userId){
UserMemberTypeEnum typeEnum = checkUserIsMember(userId);
if(typeEnum == null){
userService.update(Wrappers.lambdaUpdate(User.class).eq(User::getId, userId)
.set(User::getNoGreet, 0)
.set(User::getRankHide, 0));
}
}
@Override
public MemberInfoVo memberApp(Long userId, Integer type) {
User user = userService.getById(userId);

View File

@@ -5,12 +5,14 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.cai.auth.CaiLoginManager;
import com.ruoyi.cai.constant.RedisHttpConstant;
import com.ruoyi.cai.domain.*;
import com.ruoyi.cai.dto.admin.vo.UserAdminVo;
import com.ruoyi.cai.dto.app.query.index.GreetQuery;
import com.ruoyi.cai.dto.app.query.index.UserMapperQuery;
import com.ruoyi.cai.dto.app.query.index.UserQuery;
import com.ruoyi.cai.dto.app.vo.user.*;
import com.ruoyi.cai.dto.commom.user.MinUser;
import com.ruoyi.cai.enums.GenderEnum;
import com.ruoyi.cai.im.ImManager;
import com.ruoyi.cai.mapper.UserMapper;
@@ -23,12 +25,15 @@ import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* 用户Service业务层处理
@@ -81,6 +86,8 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
private ImManager imManager;
@Autowired
private YunxinHttpService yunxinHttpService;
@Autowired
private RedissonClient redissonClient;
@Override
public User getByUsername(String username) {
@@ -88,6 +95,30 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
.eq(User::getMobile,username));
}
@Override
public MinUser getMinUserByIdBomCache(Long userId){
if(userId == null){
return null;
}
String redisKey = String.format(RedisHttpConstant.MIN_USER_IM_REDIS, userId);
RBucket<MinUser> bucket = redissonClient.getBucket(redisKey);
MinUser user = bucket.get();
if(user != null){
return user;
}
MinUser minUser = this.getMinUserById(userId);
if(minUser == null){
return null;
}
bucket.set(minUser,3, TimeUnit.HOURS);
return minUser;
}
@Override
public MinUser getMinUserById(Long userId) {
return baseMapper.getMinUserById(userId);
}
@Override
public Page<UserAdminVo> pageAdmin(PageQuery pageQuery, UserAdminVo query) {
return baseMapper.pageAdmin(pageQuery.build(),query);