From 13cdff58bb98f0ec0d322533e3ea9d51fb97ee5e Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Sat, 29 Nov 2025 13:44:31 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E8=81=8A=E5=A4=A9=E4=BC=9A=E5=91=98?= =?UTF-8?q?=E9=99=90=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/member/enums/MemberErrorCode.java | 4 + .../module/member/client/service/ChatApi.java | 10 ++- .../member/client/service/ChatApiImpl.java | 39 ++++++++-- .../member/client/tool/ChatApiTool.java | 1 + .../ChatPrivateTotalMessageTotalReqVo.java | 26 +++++++ .../ChatPrivateTotalMessageTotalResVo.java | 33 +++++++++ .../app/chat/AppChatController.java | 8 +- .../service/opentype/OpenTypeService.java | 12 ++- .../service/opentype/OpenTypeServiceImpl.java | 74 +++++++++++++++---- 9 files changed, 180 insertions(+), 27 deletions(-) create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/vo/chat/privatemsg/ChatPrivateTotalMessageTotalReqVo.java create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/vo/chat/privatemsg/ChatPrivateTotalMessageTotalResVo.java diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/MemberErrorCode.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/MemberErrorCode.java index 93201c2..049e027 100644 --- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/MemberErrorCode.java +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/MemberErrorCode.java @@ -80,4 +80,8 @@ public interface MemberErrorCode { //========== 会员开通类型 1-004-017-000 ========== ErrorCode FEEDBACK_NOT_EXISTS = new ErrorCode(1_004_017_000, "反馈不存在"); + + //========== 聊天相关 1-004-018-000 ========== + ErrorCode CHAT_USER_COUNT_EXCEED = new ErrorCode(1_004_018_000, "当天免费聊天人数已用完"); + ErrorCode CHAT_MSG_COUNT_EXCEED = new ErrorCode(1_004_018_001, "当天免费聊天次数已用完"); } \ No newline at end of file diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/service/ChatApi.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/service/ChatApi.java index 6c4ef5e..a494b86 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/service/ChatApi.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/service/ChatApi.java @@ -2,10 +2,7 @@ package cn.iocoder.yudao.module.member.client.service; import cn.iocoder.yudao.module.member.client.vo.chat.ChatTableRespVO; import cn.iocoder.yudao.module.member.client.vo.chat.friend.ChatAddFriendReqVo; -import cn.iocoder.yudao.module.member.client.vo.chat.privatemsg.ChatPrivateMessageCountReqVO; -import cn.iocoder.yudao.module.member.client.vo.chat.privatemsg.ChatPrivateMessageInfoReqVO; -import cn.iocoder.yudao.module.member.client.vo.chat.privatemsg.ChatPrivateMessageReqVO; -import cn.iocoder.yudao.module.member.client.vo.chat.privatemsg.ChatPrivateMessageRespVO; +import cn.iocoder.yudao.module.member.client.vo.chat.privatemsg.*; import cn.iocoder.yudao.module.member.client.vo.chat.sensitive.*; import cn.iocoder.yudao.module.member.client.vo.chat.user.*; @@ -85,6 +82,11 @@ public interface ChatApi { */ List privateCount(ChatPrivateMessageCountReqVO dto); + /** + * 私聊消息发送消息的统计 + */ + List privateTotal(ChatPrivateTotalMessageTotalReqVo dto); + /* *************************************** end 私聊 end *************************************** */ } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/service/ChatApiImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/service/ChatApiImpl.java index be605fb..7e40ac3 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/service/ChatApiImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/service/ChatApiImpl.java @@ -8,10 +8,7 @@ import cn.iocoder.yudao.module.member.client.tool.ChatApiTool; import cn.iocoder.yudao.module.member.client.vo.chat.ChatBaseRespVo; import cn.iocoder.yudao.module.member.client.vo.chat.ChatTableRespVO; import cn.iocoder.yudao.module.member.client.vo.chat.friend.ChatAddFriendReqVo; -import cn.iocoder.yudao.module.member.client.vo.chat.privatemsg.ChatPrivateMessageCountReqVO; -import cn.iocoder.yudao.module.member.client.vo.chat.privatemsg.ChatPrivateMessageInfoReqVO; -import cn.iocoder.yudao.module.member.client.vo.chat.privatemsg.ChatPrivateMessageReqVO; -import cn.iocoder.yudao.module.member.client.vo.chat.privatemsg.ChatPrivateMessageRespVO; +import cn.iocoder.yudao.module.member.client.vo.chat.privatemsg.*; import cn.iocoder.yudao.module.member.client.vo.chat.sensitive.*; import cn.iocoder.yudao.module.member.client.vo.chat.user.*; import cn.iocoder.yudao.module.member.framework.web.config.ChatProperties; @@ -415,7 +412,7 @@ public class ChatApiImpl implements ChatApi { log.error("私聊消息统计,返回json解析错误"); return null; } - return null; + return vo; } catch (Exception e) { e.printStackTrace(); log.error("私聊消息统计,意外的错误", e); @@ -423,6 +420,38 @@ public class ChatApiImpl implements ChatApi { } } + /** + * 私聊消息发送消息的统计 + */ + @Override + public List privateTotal(ChatPrivateTotalMessageTotalReqVo dto) { + ChatApiTool.API api = setApiConfig(ChatApiTool.PRIVATE_MSG_TOTAL); + try { + String body = JSONUtil.toJsonStr(dto); + String res = HttpRequest.post(api.getFullPath()).header(apiCountersign(body)).body(body).execute().body(); + log.debug("私聊消息发送消息的统计,res:{}", res); + if (ObjectUtil.isEmpty(res)) { + log.error("私聊消息发送消息的统计,res为空"); + return null; + } + ChatBaseRespVo baseRes = JSONUtil.toBean(res, ChatBaseRespVo.class); + if (ObjectUtil.isEmpty(baseRes) || !baseRes.isSuccess()) { + log.error("私聊消息发送消息的统计,返回错误"); + return null; + } + List vo = JSONUtil.toList(baseRes.getData(), ChatPrivateTotalMessageTotalResVo.class); + if (ObjectUtil.isEmpty(vo)) { + log.error("私聊消息发送消息的统计,返回json解析错误"); + return null; + } + return vo; + } catch (Exception e) { + e.printStackTrace(); + log.error("私聊消息发送消息的统计,意外的错误", e); + return null; + } + } + /* *************************************** end 私聊 end *************************************** */ private ChatApiTool.API setApiConfig(ChatApiTool.API api) { diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/tool/ChatApiTool.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/tool/ChatApiTool.java index c0d31d6..8aa73aa 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/tool/ChatApiTool.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/tool/ChatApiTool.java @@ -29,6 +29,7 @@ public class ChatApiTool { public static final API PRIVATE_MSG_PAGE = API.builder().summary("私聊分页").url("/third/privateMsg/page").method(HttpMethod.POST).build(); public static final API PRIVATE_MSG_INFO = API.builder().summary("私聊详情").url("/third/privateMsg/getById").method(HttpMethod.POST).build(); public static final API PRIVATE_MSG_COUNT = API.builder().summary("私聊统计").url("/third/privateMsg/dailyCount").method(HttpMethod.POST).build(); + public static final API PRIVATE_MSG_TOTAL = API.builder().summary("私聊消息发送消息的统计").url("/third/privateMsg/total").method(HttpMethod.POST).build(); // 敏感词 public static final API SENSITIVE_PAGE = API.builder().summary("敏感词分页").url("/third/sensitive/page").method(HttpMethod.POST).build(); diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/vo/chat/privatemsg/ChatPrivateTotalMessageTotalReqVo.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/vo/chat/privatemsg/ChatPrivateTotalMessageTotalReqVo.java new file mode 100644 index 0000000..58bf1b1 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/vo/chat/privatemsg/ChatPrivateTotalMessageTotalReqVo.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.member.client.vo.chat.privatemsg; + +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class ChatPrivateTotalMessageTotalReqVo { + + /** + * 发送人id + */ + private Long sendId; + + /** + * 接收人id + */ + private Long receiveId; + + /** + * 发送时间范围 + */ + private LocalDateTime[] timeRange; + + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/vo/chat/privatemsg/ChatPrivateTotalMessageTotalResVo.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/vo/chat/privatemsg/ChatPrivateTotalMessageTotalResVo.java new file mode 100644 index 0000000..1baaa99 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/client/vo/chat/privatemsg/ChatPrivateTotalMessageTotalResVo.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.member.client.vo.chat.privatemsg; + +import lombok.Data; + +@Data +public class ChatPrivateTotalMessageTotalResVo { + + /** + * 发送者id + */ + private Long sendId; + + /** + * 发送名 + */ + private String sendName; + + /** + * 接受者id + */ + private Long receiveId; + + /** + * 接收者名称 + */ + private String receiveName; + + /** + * 消息总数 + */ + private Long messageTotal; + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/chat/AppChatController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/chat/AppChatController.java index fdd830f..8a64fa5 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/chat/AppChatController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/chat/AppChatController.java @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.member.client.service.ChatApi; import cn.iocoder.yudao.module.member.client.vo.chat.friend.ChatAddFriendReqVo; import cn.iocoder.yudao.module.member.client.vo.chat.user.ChatPrivateMessageSendReqVO; import cn.iocoder.yudao.module.member.client.vo.chat.user.ChatPrivateMessageSendResVO; +import cn.iocoder.yudao.module.member.service.opentype.OpenTypeService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.validation.annotation.Validated; @@ -21,13 +22,18 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti @Validated public class AppChatController { + @Resource + private OpenTypeService openTypeService; + @Resource private ChatApi chatApi; @GetMapping("/send-private-msg") @Operation(summary = "创建用户反馈") public CommonResult sendPrivateMsg(@RequestBody ChatPrivateMessageSendReqVO body) { - body.setSendId(getLoginUserId()); + Long sendId = getLoginUserId(); + openTypeService.isUserCanSendMessage(sendId, body.getRecvId()); + body.setSendId(sendId); body.setTerminal(1); return success(chatApi.send(body)); } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/opentype/OpenTypeService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/opentype/OpenTypeService.java index b05f263..41848ff 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/opentype/OpenTypeService.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/opentype/OpenTypeService.java @@ -49,8 +49,18 @@ public interface OpenTypeService { */ Long payOpenType(AppPayOpenReqType dto); + /** + * 当前用户是否是会员 + */ + boolean isUserOpenType(Long memberId); + + /** + * 当前用户是否是会员 + */ + boolean isUserOpenType(); + /** * 判断用户是否还可以发送消息 */ - boolean isUserCanSendMessage(Long userId); + boolean isUserCanSendMessage(Long sendId, Long receiveId); } \ No newline at end of file diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/opentype/OpenTypeServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/opentype/OpenTypeServiceImpl.java index 7774e7d..fd6d32d 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/opentype/OpenTypeServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/opentype/OpenTypeServiceImpl.java @@ -6,12 +6,16 @@ import cn.iocoder.yudao.module.member.client.service.ChatApi; import cn.iocoder.yudao.module.member.client.vo.chat.ChatTableRespVO; import cn.iocoder.yudao.module.member.client.vo.chat.privatemsg.ChatPrivateMessageReqVO; import cn.iocoder.yudao.module.member.client.vo.chat.privatemsg.ChatPrivateMessageRespVO; +import cn.iocoder.yudao.module.member.client.vo.chat.privatemsg.ChatPrivateTotalMessageTotalReqVo; +import cn.iocoder.yudao.module.member.client.vo.chat.privatemsg.ChatPrivateTotalMessageTotalResVo; import cn.iocoder.yudao.module.member.controller.app.opentype.vo.AppPayOpenReqType; +import cn.iocoder.yudao.module.member.dal.dataobject.config.MemberConfigDO; import cn.iocoder.yudao.module.member.dal.dataobject.opentype.OpenTypeUserDO; import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; import cn.iocoder.yudao.module.member.dal.mysql.opentype.OpenTypeUserMapper; import cn.iocoder.yudao.module.member.enums.MemberErrorCode; import cn.iocoder.yudao.module.member.enums.opentype.OpenTypeUserStatusEnum; +import cn.iocoder.yudao.module.member.service.config.MemberConfigService; import cn.iocoder.yudao.module.member.service.user.MemberUserService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -37,6 +41,7 @@ import java.util.Date; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; /** * 会员类型 Service 实现类 @@ -53,6 +58,9 @@ public class OpenTypeServiceImpl implements OpenTypeService { @Resource private OpenTypeUserMapper openTypeUserMapper; + @Resource + private MemberConfigService memberConfigService; + @Resource private ChatApi chatApi; @@ -147,29 +155,63 @@ public class OpenTypeServiceImpl implements OpenTypeService { return openTypeUserObj.getId(); } + /** + * 当前用户是否是会员 + */ + @Override + public boolean isUserOpenType(Long memberId) { + OpenTypeUserDO openTypeUserDO = openTypeUserMapper.selectEnableByUserId(memberId); + return ObjectUtil.isNotEmpty(openTypeUserDO); + } + + /** + * 当前用户是否是会员 + */ + @Override + public boolean isUserOpenType() { + return isUserOpenType(getLoginUserId()); + } + /** * 判断用户是否还可以发送消息 */ @Override - public boolean isUserCanSendMessage(Long userId) { + public boolean isUserCanSendMessage(Long sendId, Long receiveId) { + // 判断是否是会员 + if (isUserOpenType(sendId)) return true; + // 获取配置 + MemberConfigDO config = memberConfigService.getConfig(); + // 普通用户每天可以和几个人聊天 + Integer defaultChatUserCout = config.getDefaultChatUserCout(); + if (ObjectUtil.isEmpty(defaultChatUserCout)) defaultChatUserCout = 3; + // 普通用户每天可以和人发几次消息 + Integer defaultChatUserMsgCout = config.getDefaultChatUserMsgCout(); + if (ObjectUtil.isEmpty(defaultChatUserMsgCout)) defaultChatUserMsgCout = 3; + LocalDateTime now = LocalDateTime.now(); + LocalDateTime startDate = now.withHour(0).withMinute(0).withSecond(0); + LocalDateTime endDate = now.withHour(23).withMinute(59).withSecond(59); - Date startDate = Date.from(now.withHour(0).withMinute(0).withSecond(0).atZone(ZoneId.systemDefault()).toInstant()); - Date endDate = Date.from(now.withHour(23).withMinute(59).withSecond(59).atZone(ZoneId.systemDefault()).toInstant()); - - ChatPrivateMessageReqVO dto = new ChatPrivateMessageReqVO(); - dto.setPageNum(1); - dto.setPageSize(100); - dto.setSendId(userId); - dto.setSendTimeList(new ArrayList() {{ - add(startDate); - add(endDate); - }}); + ChatPrivateTotalMessageTotalReqVo dto = new ChatPrivateTotalMessageTotalReqVo(); + dto.setSendId(sendId); + dto.setTimeRange(new LocalDateTime[]{ + startDate, + endDate + }); try { - ChatTableRespVO page = chatApi.privateMsgPage(dto); - if (ObjectUtil.isEmpty(page) || ObjectUtil.isEmpty(page.getRows())) return true; - List rows = page.getRows(); - + List msgList = chatApi.privateTotal(dto); + if (ObjectUtil.isEmpty(msgList)) return true; + // 普通用户聊天人数是否超过上限 + if (msgList.size() > defaultChatUserCout) { + throw exception(MemberErrorCode.CHAT_USER_COUNT_EXCEED); + } + // 聊天人数已经超过限制 + ChatPrivateTotalMessageTotalResVo targetCount = msgList.stream().filter(item -> ObjectUtil.equals(item.getSendId(), sendId) && ObjectUtil.equals(item.getReceiveId(), receiveId)).findFirst().orElse(null); + if (ObjectUtil.isEmpty(targetCount)) return true; + if (targetCount.getMessageTotal() > defaultChatUserMsgCout) { + throw exception(MemberErrorCode.CHAT_MSG_COUNT_EXCEED); + } + return true; } catch (Exception e) { e.printStackTrace(); log.error("|判断用户是否还可以发送消息|意外的错误:{}", e.getMessage());