diff --git a/ruoyi-xq/src/main/java/com/ruoyi/xq/controller/app/ImAppController.java b/ruoyi-xq/src/main/java/com/ruoyi/xq/controller/app/ImAppController.java new file mode 100644 index 0000000..f753ece --- /dev/null +++ b/ruoyi-xq/src/main/java/com/ruoyi/xq/controller/app/ImAppController.java @@ -0,0 +1,49 @@ +package com.ruoyi.xq.controller.app; + +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.helper.LoginHelper; +import com.ruoyi.xq.dto.app.im.ImMessageDTO; +import com.ruoyi.xq.dto.app.im.ImResp; +import com.ruoyi.xq.manager.ImManager; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/im") +@Tag(name = "IM相关的接口") +@Slf4j +public class ImAppController { + + @Autowired + private ImManager imManager; + + @PostMapping("/send/message") + @Operation(summary = "发送消息") + @Log(title = "发送消息", businessType = BusinessType.OTHER, isSaveDb = false) + public R sendMessage(@Validated @RequestBody ImMessageDTO imMessageDTO){ + imMessageDTO.setFromUserId(LoginHelper.getUserId()); + ImResp resp = imManager.sendMessage(imMessageDTO); + return R.ok(resp); + } + + /*@PostMapping("/send/saveSendImImg") + @Operation(summary = "更新发送的图片消息") + @Log(title = "更新发送的图片消息", businessType = BusinessType.OTHER, isSaveDb = false) + public R saveSendImImg(@Validated @RequestBody SaveSendImImgReq saveSendImImgReq){ + imService.saveSendImImg(saveSendImImgReq); + return R.ok(); + }*/ + + + + +} diff --git a/ruoyi-xq/src/main/java/com/ruoyi/xq/dto/app/im/ImMessageDTO.java b/ruoyi-xq/src/main/java/com/ruoyi/xq/dto/app/im/ImMessageDTO.java new file mode 100644 index 0000000..e0caa00 --- /dev/null +++ b/ruoyi-xq/src/main/java/com/ruoyi/xq/dto/app/im/ImMessageDTO.java @@ -0,0 +1,24 @@ +package com.ruoyi.xq.dto.app.im; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +@Data +public class ImMessageDTO { + + @Schema(description = "发送消息的类型 0.文本 1.图片 2.语音 3.视频 100.自定义") + @NotNull(message = "参数异常") + private Integer type; + @Schema(hidden = true) + private Long fromUserId; + @Schema(description = "接收消息的用户") + @NotNull(message = "接受消息的用户不能为空") + private Long toUserId; + + @Schema(description = "消息内容") + @NotNull(message = "消息内容不能为空") + private String content; + +} diff --git a/ruoyi-xq/src/main/java/com/ruoyi/xq/dto/app/im/ImResp.java b/ruoyi-xq/src/main/java/com/ruoyi/xq/dto/app/im/ImResp.java new file mode 100644 index 0000000..edced9e --- /dev/null +++ b/ruoyi-xq/src/main/java/com/ruoyi/xq/dto/app/im/ImResp.java @@ -0,0 +1,14 @@ +package com.ruoyi.xq.dto.app.im; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class ImResp { + @Schema(description = "是否过滤 1-过滤 0-未过滤") + private Integer filter = 0; + @Schema(description = "过滤后的消息内容") + private String content; + @Schema(description = "聊天记录ID") + private Long recordId; +} diff --git a/ruoyi-xq/src/main/java/com/ruoyi/xq/manager/ImManager.java b/ruoyi-xq/src/main/java/com/ruoyi/xq/manager/ImManager.java new file mode 100644 index 0000000..ccdddd6 --- /dev/null +++ b/ruoyi-xq/src/main/java/com/ruoyi/xq/manager/ImManager.java @@ -0,0 +1,105 @@ +package com.ruoyi.xq.manager; + +import com.github.houbb.sensitive.word.bs.SensitiveWordBs; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.xq.domain.User; +import com.ruoyi.xq.domain.UserChatRecord; +import com.ruoyi.xq.domain.UserVip; +import com.ruoyi.xq.dto.app.im.ImMessageDTO; +import com.ruoyi.xq.dto.app.im.ImResp; +import com.ruoyi.xq.enums.ErrorEnum; +import com.ruoyi.xq.service.UserChatFilterService; +import com.ruoyi.xq.service.UserChatRecordService; +import com.ruoyi.xq.service.UserService; +import com.ruoyi.xq.service.UserVipService; +import com.ruoyi.yunxin.enums.YxImTypeEnum; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +@Slf4j +public class ImManager { + + @Autowired + private UserChatRecordService userChatRecordService; + @Autowired + private SensitiveWordBs sensitiveWordBs; + @Autowired + private UserChatFilterService userChatFilterService; + @Autowired + private UserService userService; + @Autowired + private UserVipService userVipService; + + public ImResp sendMessage(ImMessageDTO message) { + Long fromUserId = message.getFromUserId(); + YxImTypeEnum typeEnum = YxImTypeEnum.getByCode(message.getType()); + if(typeEnum == null || fromUserId == null){ + throw new ServiceException("参数异常"); + } + // 检测用户是否被封号 + User fromUser = userService.getById(fromUserId); + if(fromUser == null){ + throw new ServiceException("发送人不存在!"); + } + if(fromUser.getStatus() == 1){ + throw new ServiceException("发送人账号不可用!"); + } + Long toUserId = message.getToUserId(); + User toUser = userService.getById(toUserId); + if(toUser == null){ + throw new ServiceException("接收人不存在!"); + } + if(toUser.getStatus() == 1){ + throw new ServiceException("接收人账号不可用!"); + } + // 自定义消息跳过所有流程 + if(typeEnum == YxImTypeEnum.CUSTOM){ + ImResp resp = new ImResp(); + resp.setContent(message.getContent()); + return resp; + } + boolean inner = fromUser.getType().equals(1) || toUser.getType().equals(1); + // 有内部用户参与的 跳过所有校验 + if(inner){ + ImResp resp = new ImResp(); + resp.setContent(message.getContent()); + return resp; + } + boolean fileType = typeEnum.isFileType(); + if(fileType){ + // 发送文件 + } + if(fromUserId.equals(toUserId)){ + throw new ServiceException("不能给自己发送哦!"); + } + // 判断VIP 只有VIP才可以发送消息 + UserVip userVip = userVipService.getByUserVipMaster(fromUserId); + if(userVip == null){ + throw new ServiceException(ErrorEnum.VIP_AUTH); + } + // 检查拉黑 + int filter = 0; + String content = message.getContent(); + // 正则判断违规数据替换 + if(typeEnum == YxImTypeEnum.TXT){ + boolean contains = sensitiveWordBs.contains(message.getContent()); + if(contains){ + filter = 1; + content = sensitiveWordBs.replace(message.getContent()); + } + } + UserChatRecord record = userChatRecordService.saveRecord(fromUser, toUser, message); + if(filter == 1){ + userChatFilterService.saveFilter(fromUser, toUser, message.getContent(),content); + } + ImResp resp = new ImResp(); + resp.setRecordId(record.getId()); + resp.setFilter(filter); + resp.setContent(content); + return resp; + } + + +} diff --git a/ruoyi-xq/src/main/java/com/ruoyi/xq/service/UserChatFilterService.java b/ruoyi-xq/src/main/java/com/ruoyi/xq/service/UserChatFilterService.java index af19174..370d0db 100644 --- a/ruoyi-xq/src/main/java/com/ruoyi/xq/service/UserChatFilterService.java +++ b/ruoyi-xq/src/main/java/com/ruoyi/xq/service/UserChatFilterService.java @@ -1,6 +1,7 @@ package com.ruoyi.xq.service; import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.xq.domain.User; import com.ruoyi.xq.domain.UserChatFilter; /** @@ -11,4 +12,5 @@ import com.ruoyi.xq.domain.UserChatFilter; */ public interface UserChatFilterService extends IService { + void saveFilter(User fromUser, User toUser, String sourceContent, String filterContent); } diff --git a/ruoyi-xq/src/main/java/com/ruoyi/xq/service/UserChatRecordService.java b/ruoyi-xq/src/main/java/com/ruoyi/xq/service/UserChatRecordService.java index 1771589..b31a5d7 100644 --- a/ruoyi-xq/src/main/java/com/ruoyi/xq/service/UserChatRecordService.java +++ b/ruoyi-xq/src/main/java/com/ruoyi/xq/service/UserChatRecordService.java @@ -1,7 +1,9 @@ package com.ruoyi.xq.service; import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.xq.domain.User; import com.ruoyi.xq.domain.UserChatRecord; +import com.ruoyi.xq.dto.app.im.ImMessageDTO; /** * 聊天记录Service接口 @@ -11,4 +13,5 @@ import com.ruoyi.xq.domain.UserChatRecord; */ public interface UserChatRecordService extends IService { + UserChatRecord saveRecord(User fromUser, User toUser, ImMessageDTO message); } diff --git a/ruoyi-xq/src/main/java/com/ruoyi/xq/service/impl/UserChatFilterServiceImpl.java b/ruoyi-xq/src/main/java/com/ruoyi/xq/service/impl/UserChatFilterServiceImpl.java index 73ab72e..9c0b102 100644 --- a/ruoyi-xq/src/main/java/com/ruoyi/xq/service/impl/UserChatFilterServiceImpl.java +++ b/ruoyi-xq/src/main/java/com/ruoyi/xq/service/impl/UserChatFilterServiceImpl.java @@ -1,6 +1,7 @@ package com.ruoyi.xq.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.xq.domain.User; import com.ruoyi.xq.domain.UserChatFilter; import com.ruoyi.xq.mapper.UserChatFilterMapper; import com.ruoyi.xq.service.UserChatFilterService; @@ -14,4 +15,15 @@ import org.springframework.stereotype.Service; */ @Service public class UserChatFilterServiceImpl extends ServiceImpl implements UserChatFilterService { + @Override + public void saveFilter(User fromUser, User toUser, String sourceContent, String filterContent) { + UserChatFilter chatFilter = new UserChatFilter(); + chatFilter.setFromUid(fromUser.getId()); + chatFilter.setFromUsercode(fromUser.getUsercode()); + chatFilter.setToUid(toUser.getId()); + chatFilter.setToUsercode(toUser.getUsercode()); + chatFilter.setContent(sourceContent); + chatFilter.setFilterContent(filterContent); + this.save(chatFilter); + } } diff --git a/ruoyi-xq/src/main/java/com/ruoyi/xq/service/impl/UserChatRecordServiceImpl.java b/ruoyi-xq/src/main/java/com/ruoyi/xq/service/impl/UserChatRecordServiceImpl.java index 84590b0..76c7057 100644 --- a/ruoyi-xq/src/main/java/com/ruoyi/xq/service/impl/UserChatRecordServiceImpl.java +++ b/ruoyi-xq/src/main/java/com/ruoyi/xq/service/impl/UserChatRecordServiceImpl.java @@ -1,11 +1,15 @@ package com.ruoyi.xq.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.xq.domain.User; import com.ruoyi.xq.domain.UserChatRecord; +import com.ruoyi.xq.dto.app.im.ImMessageDTO; import com.ruoyi.xq.mapper.UserChatRecordMapper; import com.ruoyi.xq.service.UserChatRecordService; import org.springframework.stereotype.Service; +import java.time.LocalDateTime; + /** * 聊天记录Service业务层处理 * @@ -14,4 +18,17 @@ import org.springframework.stereotype.Service; */ @Service public class UserChatRecordServiceImpl extends ServiceImpl implements UserChatRecordService { + @Override + public UserChatRecord saveRecord(User fromUser, User toUser, ImMessageDTO message) { + UserChatRecord userChatRecord = new UserChatRecord(); + userChatRecord.setFromUid(fromUser.getId()); + userChatRecord.setFromUsercode(fromUser.getUsercode()); + userChatRecord.setToUid(toUser.getId()); + userChatRecord.setToUsercode(toUser.getUsercode()); + userChatRecord.setContent(message.getContent()); + userChatRecord.setType(message.getType()); + userChatRecord.setCreateTime(LocalDateTime.now()); + this.save(userChatRecord); + return userChatRecord; + } } diff --git a/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/enums/YxImTypeEnum.java b/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/enums/YxImTypeEnum.java index dea691a..53aef69 100644 --- a/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/enums/YxImTypeEnum.java +++ b/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/enums/YxImTypeEnum.java @@ -25,4 +25,20 @@ public enum YxImTypeEnum { this.code = code; this.text = text; } + + public boolean isFileType(){ + if(this.getCode().equals(1) || this.getCode().equals(2) || this.getCode().equals(3)){ + return true; + } + return false; + } + + public static YxImTypeEnum getByCode(Integer code) { + for (YxImTypeEnum value : values()) { + if (value.code.equals(code)) { + return value; + } + } + return null; + } }