From fdc4a4aeb970eaf739a4ebed3349fc31e90c60f2 Mon Sep 17 00:00:00 2001 From: easonzhu Date: Thu, 13 Feb 2025 19:05:42 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B7=B2=E8=AF=BB=E5=92=8C=E7=BB=9F=E8=AE=A1?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E5=88=9D=E5=A7=8B=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 22 -- .../upchina/common/config/cache/CacheKey.java | 73 +----- .../config/cache/HazelcastConfiguration.java | 4 - .../{video => common}/entity/OnlineUser.java | 2 +- .../interceptor/WebSocketSessionHandler.java | 2 +- .../app/AppGroupMessageController.java | 10 + .../upchina/group/entity/GroupCollect.java | 223 ++++++++++++++++++ .../group/entity/GroupMessageRead.java | 81 +++++++ .../group/mapper/GroupCollectMapper.java | 16 ++ .../group/mapper/GroupMessageMapper.java | 24 ++ .../group/mapper/GroupMessageReadMapper.java | 16 ++ .../group/mapper/GroupUserFlowMapper.java | 20 +- .../message/ReadGroupMessageAppQuery.java | 22 ++ .../com/upchina/group/schedule/GroupTask.java | 51 ++++ .../service/app/AppGroupMessageService.java | 6 + .../service/common/GroupCacheService.java | 29 ++- .../service/common/GroupCommonService.java | 223 ++++++++++++++++++ .../service/common/GroupMessageService.java | 2 +- .../group/vo/message/GroupMessageReadVO.java | 34 +++ .../rbac/controller/AuthController.java | 10 + .../com/upchina/rbac/service/AuthService.java | 24 +- .../video/mapper/VideoUserFlowMapper.java | 2 +- .../admin/AdminVideoInteractionService.java | 1 + .../admin/AdminVideoStatisticService.java | 1 + .../service/common/VideoCacheService.java | 1 + .../service/common/VideoCommonService.java | 1 + .../service/common/VideoMessageService.java | 2 +- .../video/vo/message/VideoCustomerVO.java | 2 +- .../video/vo/message/VideoNotificationVO.java | 2 +- src/main/resources/conf/advisorServer.yaml | 17 +- .../group/service/GroupInfoServiceTest.java | 192 --------------- .../admin/AdminGroupMessageServiceTest.java | 134 ----------- .../app/AppGroupMessageServiceTest.java | 208 ---------------- 33 files changed, 794 insertions(+), 663 deletions(-) rename src/main/java/com/upchina/{video => common}/entity/OnlineUser.java (98%) create mode 100644 src/main/java/com/upchina/group/entity/GroupCollect.java create mode 100644 src/main/java/com/upchina/group/entity/GroupMessageRead.java create mode 100644 src/main/java/com/upchina/group/mapper/GroupCollectMapper.java create mode 100644 src/main/java/com/upchina/group/mapper/GroupMessageReadMapper.java create mode 100644 src/main/java/com/upchina/group/query/message/ReadGroupMessageAppQuery.java create mode 100644 src/main/java/com/upchina/group/schedule/GroupTask.java create mode 100644 src/main/java/com/upchina/group/vo/message/GroupMessageReadVO.java delete mode 100644 src/test/java/com/upchina/group/service/GroupInfoServiceTest.java delete mode 100644 src/test/java/com/upchina/group/service/admin/AdminGroupMessageServiceTest.java delete mode 100644 src/test/java/com/upchina/group/service/app/AppGroupMessageServiceTest.java diff --git a/pom.xml b/pom.xml index c94dc1c..5174811 100644 --- a/pom.xml +++ b/pom.xml @@ -180,31 +180,9 @@ 1.7.36 runtime - - - org.junit.jupiter - junit-jupiter - 5.8.2 - test - - - org.mockito - mockito-junit-jupiter - 4.5.1 - test - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.2 - - true - true - - org.springframework.boot spring-boot-maven-plugin diff --git a/src/main/java/com/upchina/common/config/cache/CacheKey.java b/src/main/java/com/upchina/common/config/cache/CacheKey.java index 7a0be3c..bf7deac 100644 --- a/src/main/java/com/upchina/common/config/cache/CacheKey.java +++ b/src/main/java/com/upchina/common/config/cache/CacheKey.java @@ -20,12 +20,8 @@ public class CacheKey { public static final String DISTRIBUTED_LOCK = "distributed_lock"; public static class LockKey { - // 从cache刷新观点互动数量到DB 分布式锁(字符串常量) - public static final String SAVE_VIEW_COUNT_TO_DB_LOCK = "save_view_count_to_db_lock"; // 清除多余定时器日志 public static final String CLEAR_HISTORY_SCHEDULE_LOG = "clearHistoryScheduleLog"; - // 自动解除锁定用户 - public static final String UN_LOCK_USER = "un_lock_user"; // 结束直播中/暂停中的直播 分布式锁(字符串常量) public static final String STOP_LIVING_VIDEO_LOCK = "stop_living_video_lock"; // 刷新视频直播状态 分布式锁(字符串常量) @@ -47,6 +43,9 @@ public class CacheKey { public static final String SYNC_APP_ORDER = "sync_app_order"; public static final String LOAD_USER_BLACK_LIST = "load_user_black_list"; + public static final String SAVE_MESSAGE_READ = "save_message_read"; + public static final String SAVE_GROUP_USER = "save_group_user"; + public static final String COLLECT_GROUP_DATA = "collect_group_data"; } // 消息主题 @@ -135,71 +134,6 @@ public class CacheKey { public static final String USER_ADVISOR_DEPT_MAP = "user_advisor_dept_map"; } - // 观点栏目 - public static final String VIEW_COLUMN = "view_column"; - - public static final class ViewColumnKey { - // columnId -> columnName - public static final String VIEW_COLUMN_MAP = "column_map"; - // List - public static final String APP_COLUMN_LIST = "app_column_list|"; - } - - // 观点 - public static final String VIEW_INFO = "view_info"; - - public static class ViewInfoKey { - // SortedSet (publishTime, viewId) - public static final String APP_PUBLISH_TIME_LIST = "app_publish_time_list"; - // SortedSet (readCount, viewId) - public static final String APP_READ_COUNT_LIST = "app_read_count_list"; - // SortedSet (publishTime, viewId) - public static final String APP_KEYWORD_LIST = "app_keyword_all|"; - // SortedSet (publishTime, viewId) - public static final String APP_COLUMN_LIST = "app_column_list|"; - // SortedSet (publishTime, viewId) - public static final String APP_ADVISOR_LIST = "app_advisor_list|"; - // SortedSet (publishTime, viewId) - public static final String APP_PACKAGE_LIST = "app_package_list|"; - // ViewInfoAppVO - public static final String APP_OBJ = "app_obj|"; - // ViewDetailAppVO - public static final String APP_DETAIL_OBJ = "app_detail_obj|"; - // userId -> Set - public static final String USER_FAVOR_VIEW_IDS = "user_favor_view_ids|"; - // viewId -> PN Counter - public static final String APP_FAVOR_COUNT = "app_favor_count|"; - // viewId -> PN Counter - public static final String APP_READ_COUNT = "app_read_count|"; - // Set - public static final String TEMP_READ_COUNT_SET = "temp_read_count_set"; - } - - // 观点包 - public static final String VIEW_PACKAGE = "view_package"; - - public static class ViewPackageKey { - // id -> ViewPackageAppVO - public static final String APP_OBJ = "app_obj|"; - // SortedSet (weight, subCount, packageId) - public static final String APP_LIST = "app_list"; - // SortedSet (inPackageWeight, subCount, packageId) - public static final String APP_KEYWORD_LIST = "app_keyword_list|"; - // SortedSet (publishTime, viewId) - public static final String APP_COLUMN_LIST = "app_column_list|"; - // SortedSet (publishTime, viewId) - public static final String APP_ADVISOR_LIST = "app_advisor_list|"; - public static final String APP_ADVISOR_ORDER_BY_SUBCOUNT_LIST = "app_advisor_order_by_subcount_list|"; - } - - //观点卡片 - public static final String VIEW_CARD = "view_card"; - - public static class ViewCardKey { - //viewId --> List - public static final String VIEW_CARD_LIST = "view_card_list|"; - } - public static final String ADVERT = "advert"; public static class AdvertKey { @@ -420,6 +354,7 @@ public class CacheKey { public static final String GROUP_MESSAGE_LIST = "group_message_list|"; public static final String GROUP_MESSAGE_DETAIL = "group_message_detail|"; public static final String USER_TOTAL_ONLINE = "user_total_online|"; + public static final String TEMP_READ_LIST = "temp_read_list"; } } diff --git a/src/main/java/com/upchina/common/config/cache/HazelcastConfiguration.java b/src/main/java/com/upchina/common/config/cache/HazelcastConfiguration.java index d938d16..017719b 100644 --- a/src/main/java/com/upchina/common/config/cache/HazelcastConfiguration.java +++ b/src/main/java/com/upchina/common/config/cache/HazelcastConfiguration.java @@ -60,11 +60,7 @@ public class HazelcastConfiguration { configMap.put(DEPT, new LocalMapConfig(10000, 3600)); configMap.put(TAG, new LocalMapConfig(10000, 3600)); - configMap.put(VIEW_COLUMN, new LocalMapConfig(10000, 3600)); configMap.put(ADVISOR_INFO, new LocalMapConfig(10000, 300)); - configMap.put(VIEW_INFO, new LocalMapConfig(10000, 300)); - configMap.put(VIEW_PACKAGE, new LocalMapConfig(10000, 300)); - configMap.put(VIEW_CARD, new LocalMapConfig(10000, 300)); configMap.put(RECOMMEND, new LocalMapConfig(10000, 300)); configMap.put(USER, new LocalMapConfig(10000, 3600)); diff --git a/src/main/java/com/upchina/video/entity/OnlineUser.java b/src/main/java/com/upchina/common/entity/OnlineUser.java similarity index 98% rename from src/main/java/com/upchina/video/entity/OnlineUser.java rename to src/main/java/com/upchina/common/entity/OnlineUser.java index cb9e39b..b6c11e8 100644 --- a/src/main/java/com/upchina/video/entity/OnlineUser.java +++ b/src/main/java/com/upchina/common/entity/OnlineUser.java @@ -1,4 +1,4 @@ -package com.upchina.video.entity; +package com.upchina.common.entity; import io.swagger.annotations.ApiModelProperty; diff --git a/src/main/java/com/upchina/common/interceptor/WebSocketSessionHandler.java b/src/main/java/com/upchina/common/interceptor/WebSocketSessionHandler.java index bb07304..2adc5e8 100644 --- a/src/main/java/com/upchina/common/interceptor/WebSocketSessionHandler.java +++ b/src/main/java/com/upchina/common/interceptor/WebSocketSessionHandler.java @@ -3,10 +3,10 @@ package com.upchina.common.interceptor; import com.hazelcast.map.IMap; import com.upchina.common.constant.IsOrNot; import com.upchina.common.constant.ProductType; +import com.upchina.common.entity.OnlineUser; import com.upchina.common.vo.FrontUserVO; import com.upchina.group.service.common.GroupCacheService; import com.upchina.group.service.common.GroupMessageService; -import com.upchina.video.entity.OnlineUser; import com.upchina.video.service.common.VideoCacheService; import com.upchina.video.service.common.VideoMessageService; import org.springframework.messaging.simp.stomp.StompHeaderAccessor; diff --git a/src/main/java/com/upchina/group/controller/app/AppGroupMessageController.java b/src/main/java/com/upchina/group/controller/app/AppGroupMessageController.java index 62969f4..f56b85b 100644 --- a/src/main/java/com/upchina/group/controller/app/AppGroupMessageController.java +++ b/src/main/java/com/upchina/group/controller/app/AppGroupMessageController.java @@ -6,6 +6,7 @@ import com.upchina.common.result.CommonResult; import com.upchina.common.result.ResponseStatus; import com.upchina.common.vo.FrontUserVO; import com.upchina.group.query.message.ListGroupMessageAppQuery; +import com.upchina.group.query.message.ReadGroupMessageAppQuery; import com.upchina.group.query.message.SendGroupMessageAppQuery; import com.upchina.group.service.app.AppGroupMessageService; import com.upchina.group.vo.message.GroupMessageVO; @@ -48,4 +49,13 @@ public class AppGroupMessageController { return CommonResult.success(vo); } + @ApiOperation("APP保存消息已读") + @PostMapping("/app/group/message/readMessage") + public CommonResult readMessage( + @Validated @RequestBody @ApiParam(required = true) ReadGroupMessageAppQuery query, + @RequestAttribute(value = "frontUser", required = false) FrontUserVO frontUser) { + appGroupMessageService.readMessage(query, frontUser); + return CommonResult.success(); + } + } \ No newline at end of file diff --git a/src/main/java/com/upchina/group/entity/GroupCollect.java b/src/main/java/com/upchina/group/entity/GroupCollect.java new file mode 100644 index 0000000..99e7fca --- /dev/null +++ b/src/main/java/com/upchina/group/entity/GroupCollect.java @@ -0,0 +1,223 @@ +package com.upchina.group.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; + +import java.io.Serializable; +import java.time.LocalDate; +import java.time.LocalDateTime; + +/** + *

+ * 交易圈统计信息 + *

+ * + * @author easonzhu + * @since 2025-02-13 + */ +public class GroupCollect implements Serializable { + + + /** + * ID + */ + @TableId(value = "group_id", type = IdType.AUTO) + private Integer groupId; + + /** + * 日期 + */ + private LocalDate date; + + /** + * 总成员数 + */ + @TableField("total_members") + private Integer totalMembers; + + /** + * 访问成员数 + */ + @TableField("visited_members") + private Integer visitedMembers; + + /** + * 新增成员数 + */ + @TableField("new_members") + private Integer newMembers; + + /** + * 发互动成员数 + */ + @TableField("interaction_members") + private Integer interactionMembers; + + /** + * 发私聊成员数 + */ + @TableField("private_chat_members") + private Integer privateChatMembers; + + /** + * 投顾发布互动数 + */ + @TableField("advisor_group_content") + private Integer advisorGroupContent; + + /** + * 助教发布互动数 + */ + @TableField("assistant_group_content") + private Integer assistantGroupContent; + + /** + * 用户发布互动数 + */ + @TableField("customer_group_content") + private Integer customerGroupContent; + + /** + * 投顾发布私聊数 + */ + @TableField("advisor_private_content") + private Integer advisorPrivateContent; + + /** + * 助教发布私聊数 + */ + @TableField("assistant_private_content") + private Integer assistantPrivateContent; + + /** + * 用户发布私聊数 + */ + @TableField("customer_private_content") + private Integer customerPrivateContent; + + /** + * 创建时间 + */ + @TableField("create_time") + private LocalDateTime createTime; + + public Integer getGroupId() { + return groupId; + } + + public void setGroupId(Integer groupId) { + this.groupId = groupId; + } + public LocalDate getDate() { + return date; + } + + public void setDate(LocalDate date) { + this.date = date; + } + public Integer getTotalMembers() { + return totalMembers; + } + + public void setTotalMembers(Integer totalMembers) { + this.totalMembers = totalMembers; + } + public Integer getVisitedMembers() { + return visitedMembers; + } + + public void setVisitedMembers(Integer visitedMembers) { + this.visitedMembers = visitedMembers; + } + public Integer getNewMembers() { + return newMembers; + } + + public void setNewMembers(Integer newMembers) { + this.newMembers = newMembers; + } + public Integer getInteractionMembers() { + return interactionMembers; + } + + public void setInteractionMembers(Integer interactionMembers) { + this.interactionMembers = interactionMembers; + } + public Integer getPrivateChatMembers() { + return privateChatMembers; + } + + public void setPrivateChatMembers(Integer privateChatMembers) { + this.privateChatMembers = privateChatMembers; + } + public Integer getAdvisorGroupContent() { + return advisorGroupContent; + } + + public void setAdvisorGroupContent(Integer advisorGroupContent) { + this.advisorGroupContent = advisorGroupContent; + } + public Integer getAssistantGroupContent() { + return assistantGroupContent; + } + + public void setAssistantGroupContent(Integer assistantGroupContent) { + this.assistantGroupContent = assistantGroupContent; + } + public Integer getCustomerGroupContent() { + return customerGroupContent; + } + + public void setCustomerGroupContent(Integer customerGroupContent) { + this.customerGroupContent = customerGroupContent; + } + public Integer getAdvisorPrivateContent() { + return advisorPrivateContent; + } + + public void setAdvisorPrivateContent(Integer advisorPrivateContent) { + this.advisorPrivateContent = advisorPrivateContent; + } + public Integer getAssistantPrivateContent() { + return assistantPrivateContent; + } + + public void setAssistantPrivateContent(Integer assistantPrivateContent) { + this.assistantPrivateContent = assistantPrivateContent; + } + public Integer getCustomerPrivateContent() { + return customerPrivateContent; + } + + public void setCustomerPrivateContent(Integer customerPrivateContent) { + this.customerPrivateContent = customerPrivateContent; + } + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + + @Override + public String toString() { + return "GroupCollect{" + + "groupId=" + groupId + + ", date=" + date + + ", totalMembers=" + totalMembers + + ", visitedMembers=" + visitedMembers + + ", newMembers=" + newMembers + + ", interactionMembers=" + interactionMembers + + ", privateChatMembers=" + privateChatMembers + + ", advisorGroupContent=" + advisorGroupContent + + ", assistantGroupContent=" + assistantGroupContent + + ", customerGroupContent=" + customerGroupContent + + ", advisorPrivateContent=" + advisorPrivateContent + + ", assistantPrivateContent=" + assistantPrivateContent + + ", customerPrivateContent=" + customerPrivateContent + + ", createTime=" + createTime + + "}"; + } +} diff --git a/src/main/java/com/upchina/group/entity/GroupMessageRead.java b/src/main/java/com/upchina/group/entity/GroupMessageRead.java new file mode 100644 index 0000000..845ad4a --- /dev/null +++ b/src/main/java/com/upchina/group/entity/GroupMessageRead.java @@ -0,0 +1,81 @@ +package com.upchina.group.entity; + +import com.baomidou.mybatisplus.annotation.TableField; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 交易圈消息已读 + *

+ * + * @author easonzhu + * @since 2025-02-13 + */ +public class GroupMessageRead implements Serializable { + + + /** + * 消息ID + */ + @TableField("message_id") + private Integer messageId; + + /** + * 用户ID + */ + @TableField("user_id") + private String userId; + + /** + * 交易圈ID + */ + @TableField("group_id") + private Integer groupId; + + /** + * 创建时间 + */ + @TableField("create_time") + private LocalDateTime createTime; + + public Integer getMessageId() { + return messageId; + } + + public void setMessageId(Integer messageId) { + this.messageId = messageId; + } + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + public Integer getGroupId() { + return groupId; + } + + public void setGroupId(Integer groupId) { + this.groupId = groupId; + } + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + + @Override + public String toString() { + return "GroupMessageRead{" + + "messageId=" + messageId + + ", userId=" + userId + + ", groupId=" + groupId + + ", createTime=" + createTime + + "}"; + } +} diff --git a/src/main/java/com/upchina/group/mapper/GroupCollectMapper.java b/src/main/java/com/upchina/group/mapper/GroupCollectMapper.java new file mode 100644 index 0000000..aadbc17 --- /dev/null +++ b/src/main/java/com/upchina/group/mapper/GroupCollectMapper.java @@ -0,0 +1,16 @@ +package com.upchina.group.mapper; + +import com.upchina.common.mapper.EasyBaseMapper; +import com.upchina.group.entity.GroupCollect; + +/** + *

+ * 交易圈统计信息 Mapper 接口 + *

+ * + * @author easonzhu + * @since 2025-02-13 + */ +public interface GroupCollectMapper extends EasyBaseMapper { + +} diff --git a/src/main/java/com/upchina/group/mapper/GroupMessageMapper.java b/src/main/java/com/upchina/group/mapper/GroupMessageMapper.java index ce0ac71..e1ab5d7 100644 --- a/src/main/java/com/upchina/group/mapper/GroupMessageMapper.java +++ b/src/main/java/com/upchina/group/mapper/GroupMessageMapper.java @@ -2,9 +2,12 @@ package com.upchina.group.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.upchina.group.entity.GroupMessage; +import com.upchina.group.entity.GroupMessageRead; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.Update; +import java.time.LocalDateTime; import java.util.List; /** @@ -25,4 +28,25 @@ public interface GroupMessageMapper extends BaseMapper { ") t\n" + "WHERE rn = 1") List selectPrivateChatList(@Param("groupId") Integer groupId); + + @Update("") + void replaceBatch(List list); + + @Select("SELECT group_id, interactive_type, user_type, COUNT(0) AS id \n" + + "FROM group_message \n" + + "WHERE create_time >= #{startTime} AND create_time < #{endTime} \n" + + "GROUP BY group_id, interactive_type, user_type") + List collectMessage(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime); + + @Select("SELECT group_id, interactive_type, COUNT(DISTINCT user_id) AS id \n" + + "FROM group_message \n" + + "WHERE user_type = 2 AND create_time >= #{startTime} AND create_time < #{endTime} \n" + + "GROUP BY group_id, interactive_type") + List collectMessageMember(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime); } diff --git a/src/main/java/com/upchina/group/mapper/GroupMessageReadMapper.java b/src/main/java/com/upchina/group/mapper/GroupMessageReadMapper.java new file mode 100644 index 0000000..059a455 --- /dev/null +++ b/src/main/java/com/upchina/group/mapper/GroupMessageReadMapper.java @@ -0,0 +1,16 @@ +package com.upchina.group.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.upchina.group.entity.GroupMessageRead; + +/** + *

+ * 交易圈消息已读 Mapper 接口 + *

+ * + * @author easonzhu + * @since 2025-02-13 + */ +public interface GroupMessageReadMapper extends BaseMapper { + +} diff --git a/src/main/java/com/upchina/group/mapper/GroupUserFlowMapper.java b/src/main/java/com/upchina/group/mapper/GroupUserFlowMapper.java index 4f5eb57..7a277e5 100644 --- a/src/main/java/com/upchina/group/mapper/GroupUserFlowMapper.java +++ b/src/main/java/com/upchina/group/mapper/GroupUserFlowMapper.java @@ -1,13 +1,15 @@ package com.upchina.group.mapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.upchina.common.entity.OnlineUser; +import com.upchina.common.mapper.EasyBaseMapper; +import com.upchina.common.vo.IdCountVO; import com.upchina.group.entity.GroupUserFlow; -import com.upchina.video.entity.OnlineUser; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; +import java.time.LocalDateTime; import java.util.List; /** @@ -18,10 +20,22 @@ import java.util.List; * @author easonzhu * @since 2025-02-04 */ -public interface GroupUserFlowMapper extends BaseMapper { +public interface GroupUserFlowMapper extends EasyBaseMapper { @Select("SELECT h.group_id, h.user_id, h.session_id, 2 as is_online " + "FROM group_user_flow h " + "${ew.customSqlSegment}") List loadHis(@Param(Constants.WRAPPER) LambdaQueryWrapper wrapper); + + @Select("SELECT \n" + + " group_id, \n" + + " COUNT(DISTINCT user_id) AS user_count \n" + + "FROM \n" + + " group_user_flow \n" + + "WHERE \n" + + " time >= #{startTime} \n" + + " AND time < #{endTime} \n" + + "GROUP BY \n" + + " group_id") + List selectGroupUserCount(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime); } diff --git a/src/main/java/com/upchina/group/query/message/ReadGroupMessageAppQuery.java b/src/main/java/com/upchina/group/query/message/ReadGroupMessageAppQuery.java new file mode 100644 index 0000000..1219583 --- /dev/null +++ b/src/main/java/com/upchina/group/query/message/ReadGroupMessageAppQuery.java @@ -0,0 +1,22 @@ +package com.upchina.group.query.message; + +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.NotEmpty; +import java.util.List; + +public class ReadGroupMessageAppQuery { + + @ApiModelProperty("消息ID") + @NotEmpty + private List messageIds; + + public List getMessageIds() { + return messageIds; + } + + public void setMessageIds(List messageIds) { + this.messageIds = messageIds; + } + +} \ No newline at end of file diff --git a/src/main/java/com/upchina/group/schedule/GroupTask.java b/src/main/java/com/upchina/group/schedule/GroupTask.java new file mode 100644 index 0000000..4ca3058 --- /dev/null +++ b/src/main/java/com/upchina/group/schedule/GroupTask.java @@ -0,0 +1,51 @@ +package com.upchina.group.schedule; + +import com.upchina.common.config.cache.CacheKey; +import com.upchina.common.service.CacheService; +import com.upchina.group.service.common.GroupCommonService; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.concurrent.TimeUnit; + +@Component +public class GroupTask { + + @Resource + private CacheService cacheService; + + @Resource + private GroupCommonService groupCommonService; + + /** + * 拉取云端视频转码状态 + */ + @Scheduled(cron = "${cron.saveGroupMessageRead}") + public void saveGroupMessageRead() { + cacheService.lock(CacheKey.LockKey.SAVE_MESSAGE_READ, + 0, TimeUnit.SECONDS, + 4, TimeUnit.MINUTES, + groupCommonService::saveGroupMessageRead + ); + } + + @Scheduled(cron = "${cron.saveGroupUser}") + public void saveGroupUser() { + cacheService.lock(CacheKey.LockKey.SAVE_GROUP_USER, + 0, TimeUnit.SECONDS, + 4, TimeUnit.MINUTES, + groupCommonService::saveGroupUser + ); + } + + @Scheduled(cron = "${cron.collectGroupData}") + public void collectGroupData() { + cacheService.lock(CacheKey.LockKey.COLLECT_GROUP_DATA, + 0, TimeUnit.SECONDS, + 4, TimeUnit.MINUTES, + groupCommonService::collectGroupData + ); + } + +} diff --git a/src/main/java/com/upchina/group/service/app/AppGroupMessageService.java b/src/main/java/com/upchina/group/service/app/AppGroupMessageService.java index 0e15b7d..e832917 100644 --- a/src/main/java/com/upchina/group/service/app/AppGroupMessageService.java +++ b/src/main/java/com/upchina/group/service/app/AppGroupMessageService.java @@ -18,12 +18,14 @@ import com.upchina.group.constant.QueryGroupMessageType; import com.upchina.group.entity.GroupMessage; import com.upchina.group.mapper.GroupMessageMapper; import com.upchina.group.query.message.ListGroupMessageAppQuery; +import com.upchina.group.query.message.ReadGroupMessageAppQuery; import com.upchina.group.query.message.SendGroupMessageAppQuery; import com.upchina.group.service.GroupInfoService; import com.upchina.group.service.common.GroupCacheService; import com.upchina.group.service.common.GroupCommonService; import com.upchina.group.service.common.GroupMessageService; import com.upchina.group.vo.GroupVO; +import com.upchina.group.vo.message.GroupMessageReadVO; import com.upchina.group.vo.message.GroupMessageVO; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -127,4 +129,8 @@ public class AppGroupMessageService { return vo; } + public void readMessage(ReadGroupMessageAppQuery query, FrontUserVO frontUser) { + GroupMessageReadVO vo = new GroupMessageReadVO(frontUser.getUserId(), query.getMessageIds()); + groupCacheService.readMessage(vo); + } } \ No newline at end of file diff --git a/src/main/java/com/upchina/group/service/common/GroupCacheService.java b/src/main/java/com/upchina/group/service/common/GroupCacheService.java index 9d7c525..d3db259 100644 --- a/src/main/java/com/upchina/group/service/common/GroupCacheService.java +++ b/src/main/java/com/upchina/group/service/common/GroupCacheService.java @@ -2,22 +2,23 @@ package com.upchina.group.service.common; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.hazelcast.core.HazelcastInstance; import com.hazelcast.map.IMap; import com.upchina.advisor.vo.AdvisorBasicVO; import com.upchina.common.config.cache.CacheKey; import com.upchina.common.constant.IsOrNot; -import com.upchina.common.handler.BizException; -import com.upchina.common.result.ResponseStatus; +import com.upchina.common.entity.OnlineUser; import com.upchina.common.service.CacheService; import com.upchina.group.constant.GroupInteractiveType; import com.upchina.group.constant.GroupMessageUserType; import com.upchina.group.constant.QueryGroupMessageType; import com.upchina.group.entity.GroupMessage; import com.upchina.group.entity.GroupUserFlow; +import com.upchina.group.mapper.GroupInfoMapper; import com.upchina.group.mapper.GroupMessageMapper; import com.upchina.group.mapper.GroupUserFlowMapper; +import com.upchina.group.vo.message.GroupMessageReadVO; import com.upchina.group.vo.message.GroupMessageVO; -import com.upchina.video.entity.OnlineUser; import org.springframework.stereotype.Service; import javax.annotation.Resource; @@ -28,9 +29,15 @@ import java.util.stream.Collectors; @Service public class GroupCacheService { + @Resource + private HazelcastInstance hazelcastInstance; + @Resource private CacheService cacheService; + @Resource + private GroupInfoMapper groupInfoMapper; + @Resource private GroupMessageMapper groupMessageMapper; @@ -40,15 +47,6 @@ public class GroupCacheService { @Resource private IMap groupCache; -// public void clearMessageCache(Integer msgId, Integer groupId) { -// if (msgId != null) { -// groupCache.remove(CacheKey.GroupKey.GROUP_MESSAGE_DETAIL + msgId); -// } -// if (groupId != null) { -// groupCache.remove(CacheKey.GroupKey.GROUP_MESSAGE_LIST + groupId); -// } -// } - public NavigableSet getMessageIdSet(Integer groupId, String userId, QueryGroupMessageType type) { String cacheKey = buildMessageIdSetKey(userId, type); return cacheService.get(groupCache, cacheKey, () -> { @@ -136,7 +134,7 @@ public class GroupCacheService { } public GroupMessageVO getMessage(GroupMessage message, Map advisorMap) { - GroupMessageVO vo = new GroupMessageVO(message, advisorMap.get(message.getAdvisorId())); + GroupMessageVO vo = new GroupMessageVO(message, advisorMap == null ? null : advisorMap.get(message.getAdvisorId())); vo.setReplyMessage(getMessage(message.getReplyId(), advisorMap)); vo.setQuoteMessage(getMessage(message.getQuoteId(), advisorMap)); return vo; @@ -161,4 +159,9 @@ public class GroupCacheService { } return cacheKey; } + + public void readMessage(GroupMessageReadVO vo) { + hazelcastInstance.getList(CacheKey.GroupKey.TEMP_READ_LIST).add(vo); + } + } \ No newline at end of file diff --git a/src/main/java/com/upchina/group/service/common/GroupCommonService.java b/src/main/java/com/upchina/group/service/common/GroupCommonService.java index bb9e359..d7f78eb 100644 --- a/src/main/java/com/upchina/group/service/common/GroupCommonService.java +++ b/src/main/java/com/upchina/group/service/common/GroupCommonService.java @@ -1,13 +1,236 @@ package com.upchina.group.service.common; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.ListUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.hazelcast.core.HazelcastInstance; +import com.hazelcast.map.IMap; +import com.upchina.common.config.cache.CacheKey; +import com.upchina.common.constant.IsOrNot; +import com.upchina.common.entity.OnlineUser; +import com.upchina.common.vo.IdCountVO; +import com.upchina.group.constant.GroupInteractiveType; +import com.upchina.group.constant.GroupMessageUserType; +import com.upchina.group.entity.*; +import com.upchina.group.mapper.GroupCollectMapper; +import com.upchina.group.mapper.GroupInfoMapper; +import com.upchina.group.mapper.GroupMessageMapper; +import com.upchina.group.mapper.GroupUserFlowMapper; import com.upchina.group.vo.GroupVO; +import com.upchina.group.vo.message.GroupMessageReadVO; +import com.upchina.group.vo.message.GroupMessageVO; +import com.upchina.video.schedule.CollectTask; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; @Service public class GroupCommonService { + @Resource + private HazelcastInstance hazelcastInstance; + + @Resource + private GroupCacheService groupCacheService; + + @Resource + private GroupMessageMapper groupMessageMapper; + + @Resource + private GroupInfoMapper groupInfoMapper; + + @Resource + private GroupUserFlowMapper groupUserFlowMapper; + + @Resource + private GroupCollectMapper groupCollectMapper; + private CollectTask collectTask; + public boolean validateUserPermission(String userId, GroupVO groupVO) { return true; } + @Transactional(rollbackFor = Exception.class) + public void saveGroupMessageRead() { + List cacheList = hazelcastInstance.getList(CacheKey.GroupKey.TEMP_READ_LIST); + // 合并重复项 + Map> map = new HashMap<>(cacheList.size()); + for (GroupMessageReadVO read : cacheList) { + if (read != null) { + read.getMessageIds().stream().forEach(m -> + map.computeIfAbsent(m, k -> new HashSet<>()).add(read.getUserId())); + } + } + List list = map.entrySet().stream() + .map(entry -> { + Integer messageId = entry.getKey(); + GroupMessageVO message = groupCacheService.getMessage(messageId, null); + if (message == null + || !GroupInteractiveType.GROUP.value.equals(message.getInteractiveType()) + || (!GroupMessageUserType.ADVISOR.value.equals(message.getUserType()) && + !GroupMessageUserType.ASSISTANT.value.equals(message.getUserType()))) { + return null; + } + return entry.getValue().stream().map(userId -> { + GroupMessageRead read = new GroupMessageRead(); + read.setMessageId(messageId); + read.setUserId(userId); + read.setGroupId(message.getGroupId()); + return read; + }).collect(Collectors.toList()); + }).filter(Objects::nonNull).flatMap(List::stream).collect(Collectors.toList()); + if (CollUtil.isNotEmpty(list)) { + groupMessageMapper.replaceBatch(list); + } + cacheList.clear(); + } + + /** + * 写入视频用户数据 + */ + @Transactional(rollbackFor = Exception.class) + public void saveGroupUser() { + LocalDateTime now = LocalDateTime.now(); + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery() + .select(GroupInfo::getId, GroupInfo::getStatus); + List groups = groupInfoMapper.selectList(wrapper); + if (CollUtil.isEmpty(groups)) { + return; + } + LocalDateTime time = now.withSecond(0).withNano(0); + LocalDateTime startTime = now.plusMinutes(-1); + + groups.forEach(g -> { + Integer id = g.getId(); + IMap onlineMap = groupCacheService.getTotalOnlineMap(id); + if (onlineMap == null || onlineMap.isEmpty()) { + return; + } + // 将实时在线人落库,并添加是否正在观看 + List onLineList = onlineMap.values().stream() + .filter(u -> IsOrNot.IS.value.equals(u.getIsOnline()) || (u.getExitTime() != null && u.getExitTime().isAfter(startTime))) + .map(o -> { + GroupUserFlow groupUserFlow = new GroupUserFlow(); + groupUserFlow.setGroupId(id); + groupUserFlow.setUserId(o.getUserId()); + groupUserFlow.setSessionId(o.getSessionId()); + groupUserFlow.setTime(time); + groupUserFlow.setEnterTime(o.getCreateTime() != null ? o.getCreateTime().withSecond(0).withNano(0) : null); + groupUserFlow.setExitTime(o.getExitTime() != null ? o.getExitTime().withSecond(0).withNano(0) : null); + return groupUserFlow; + }) + .collect(Collectors.toList()); + if (CollUtil.isNotEmpty(onLineList)) { + ListUtil.split(onLineList, 1000).stream().filter(CollUtil::isNotEmpty).forEach(groupUserFlowMapper::insertBatchSomeColumn); + } + }); + } + + public void collectGroupData() { + LocalDate today = LocalDate.now(); + LocalDate yesterday = today.minusDays(1); + LambdaQueryWrapper groupWrapper = Wrappers.lambdaQuery() + .select(GroupInfo::getId); + List groups = groupInfoMapper.selectList(groupWrapper); + if (CollUtil.isEmpty(groups)) { + return; + } + List groupIds = groups.stream().map(GroupInfo::getId).collect(Collectors.toList()); + // 获取昨日数据 + // 如果昨天数据还是昨天统计的,那需要重新计算;否则不需计算 + QueryWrapper collectWrapper = Wrappers.query() + .select("max(create_time) as create_time") + .eq("date", yesterday); + GroupCollect yesterdayLatest = groupCollectMapper.selectOne(collectWrapper); + if (yesterdayLatest != null && yesterdayLatest.getCreateTime().isBefore(today.atStartOfDay())) { + collectGroupData(groupIds, yesterday); + } + + collectGroupData(groupIds, today); + } + + public void collectGroupData(List groupIds, LocalDate date) { + LocalDateTime startTime = date.atStartOfDay(); + LocalDateTime endTime = date.plusDays(1).atStartOfDay(); + List visitMemberList = groupUserFlowMapper.selectGroupUserCount(startTime, endTime); + Map visitMemberMap = visitMemberList.stream().collect(Collectors.toMap(IdCountVO::getId, IdCountVO::getCount)); + + List messageMemberCollect = groupMessageMapper.collectMessageMember(startTime, endTime); + Map> groupMessageMemberMap = messageMemberCollect.stream().collect(Collectors.groupingBy(GroupMessage::getGroupId)); + + List messageCollect = groupMessageMapper.collectMessage(startTime, endTime); + Map> groupMessageMap = messageCollect.stream().collect(Collectors.groupingBy(GroupMessage::getGroupId)); + + List collectList = groupIds.stream().map(groupId -> { + GroupCollect collect = new GroupCollect(); + collect.setGroupId(groupId); + collect.setDate(date); + collect.setTotalMembers(getTotalMembers(groupId)); + collect.setVisitedMembers(visitMemberMap.getOrDefault(groupId, 0)); + collect.setNewMembers(getNewMembers(groupId)); + collect.setInteractionMembers(0); + collect.setPrivateChatMembers(0); + List messageMemberList = groupMessageMemberMap.get(groupId); + if (CollUtil.isNotEmpty(messageMemberList)) { + for (GroupMessage groupMessage : messageMemberList) { + if (GroupInteractiveType.GROUP.value.equals(groupMessage.getInteractiveType())) { + collect.setInteractionMembers(groupMessage.getId()); + } else if (GroupInteractiveType.PRIVATE.value.equals(groupMessage.getInteractiveType())) { + collect.setPrivateChatMembers(groupMessage.getId()); + } + } + } + collect.setAdvisorGroupContent(0); + collect.setAssistantGroupContent(0); + collect.setCustomerGroupContent(0); + collect.setAdvisorPrivateContent(0); + collect.setAssistantPrivateContent(0); + collect.setCustomerPrivateContent(0); + List messageList = groupMessageMap.get(groupId); + if (CollUtil.isNotEmpty(messageList)) { + for (GroupMessage groupMessage : messageList) { + if (GroupInteractiveType.GROUP.value.equals(groupMessage.getInteractiveType())) { + if (GroupMessageUserType.ADVISOR.value.equals(groupMessage.getUserType())) { + collect.setAdvisorGroupContent(groupMessage.getId()); + } else if (GroupMessageUserType.ASSISTANT.value.equals(groupMessage.getUserType())) { + collect.setAssistantGroupContent(groupMessage.getId()); + } else if (GroupMessageUserType.CUSTOMER.value.equals(groupMessage.getUserType())) { + collect.setCustomerGroupContent(groupMessage.getId()); + } + } else if (GroupInteractiveType.PRIVATE.value.equals(groupMessage.getInteractiveType())) { + if (GroupMessageUserType.ADVISOR.value.equals(groupMessage.getUserType())) { + collect.setAdvisorPrivateContent(groupMessage.getId()); + } else if (GroupMessageUserType.ASSISTANT.value.equals(groupMessage.getUserType())) { + collect.setAssistantPrivateContent(groupMessage.getId()); + } else if (GroupMessageUserType.CUSTOMER.value.equals(groupMessage.getUserType())) { + collect.setCustomerPrivateContent(groupMessage.getId()); + } + } + } + } + return collect; + + }).collect(Collectors.toList()); + if (CollUtil.isNotEmpty(collectList)) { + groupCollectMapper.delete(Wrappers.lambdaQuery().eq(GroupCollect::getDate, date)); + groupCollectMapper.insertBatchSomeColumn(collectList); + } + } + + private Integer getTotalMembers(Integer groupId) { + // TODO + return 0; + } + + private Integer getNewMembers(Integer groupId) { + // TODO + return 0; + } } \ No newline at end of file diff --git a/src/main/java/com/upchina/group/service/common/GroupMessageService.java b/src/main/java/com/upchina/group/service/common/GroupMessageService.java index e0d7c88..27a5673 100644 --- a/src/main/java/com/upchina/group/service/common/GroupMessageService.java +++ b/src/main/java/com/upchina/group/service/common/GroupMessageService.java @@ -6,6 +6,7 @@ import com.hazelcast.topic.ITopic; import com.upchina.advisor.service.AdvisorInfoService; import com.upchina.advisor.vo.AdvisorBasicVO; import com.upchina.common.config.cache.CacheKey; +import com.upchina.common.entity.OnlineUser; import com.upchina.common.vo.FrontUserVO; import com.upchina.group.constant.GroupInteractiveType; import com.upchina.group.constant.GroupMessageChannel; @@ -13,7 +14,6 @@ import com.upchina.group.constant.GroupMessageType; import com.upchina.group.entity.GroupMessage; import com.upchina.group.vo.message.GroupMessageVO; import com.upchina.group.vo.message.GroupWsMessageVO; -import com.upchina.video.entity.OnlineUser; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/upchina/group/vo/message/GroupMessageReadVO.java b/src/main/java/com/upchina/group/vo/message/GroupMessageReadVO.java new file mode 100644 index 0000000..5bb1bbd --- /dev/null +++ b/src/main/java/com/upchina/group/vo/message/GroupMessageReadVO.java @@ -0,0 +1,34 @@ +package com.upchina.group.vo.message; + +import java.io.Serializable; +import java.util.List; + +public class GroupMessageReadVO implements Serializable { + + private String userId; + + private List messageIds; + + public GroupMessageReadVO() {} + + public GroupMessageReadVO(String userId, List messageIds) { + this.userId = userId; + this.messageIds = messageIds; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public List getMessageIds() { + return messageIds; + } + + public void setMessageIds(List messageIds) { + this.messageIds = messageIds; + } +} diff --git a/src/main/java/com/upchina/rbac/controller/AuthController.java b/src/main/java/com/upchina/rbac/controller/AuthController.java index 1bd53f0..cc6c416 100644 --- a/src/main/java/com/upchina/rbac/controller/AuthController.java +++ b/src/main/java/com/upchina/rbac/controller/AuthController.java @@ -6,6 +6,7 @@ import com.upchina.common.result.CommonResult; import com.upchina.common.vo.AuthVO; import com.upchina.common.vo.BackendUserVO; import com.upchina.rbac.query.ChangeMobileQuery; +import com.upchina.rbac.query.ChangePasswordQuery; import com.upchina.rbac.query.LoginDeptQuery; import com.upchina.rbac.query.LoginQuery; import com.upchina.rbac.service.AuthService; @@ -82,6 +83,15 @@ public class AuthController { return CommonResult.success(vo); } + @ApiOperation("修改用户密码") + @PostMapping("/changePassword") + @Auth(role = AccessRole.LOGIN) + public CommonResult changePassword(@Validated @RequestBody @ApiParam(required = true) ChangePasswordQuery query, + @RequestAttribute(value = "backendUser", required = false) BackendUserVO backendUserVO) { + authService.changePassword(query, backendUserVO); + return CommonResult.success(null); + } + @ApiOperation("修改用户手机号") @PostMapping("/changeMobile") @Auth(role = AccessRole.LOGIN) diff --git a/src/main/java/com/upchina/rbac/service/AuthService.java b/src/main/java/com/upchina/rbac/service/AuthService.java index 639e616..42d97e5 100644 --- a/src/main/java/com/upchina/rbac/service/AuthService.java +++ b/src/main/java/com/upchina/rbac/service/AuthService.java @@ -25,10 +25,7 @@ import com.upchina.rbac.entity.UserDept; import com.upchina.rbac.entity.UserLogin; import com.upchina.rbac.mapper.UserDeptMapper; import com.upchina.rbac.mapper.UserLoginMapper; -import com.upchina.rbac.query.ChangeMobileQuery; -import com.upchina.rbac.query.ListRoleByUserIdQuery; -import com.upchina.rbac.query.LoginDeptQuery; -import com.upchina.rbac.query.LoginQuery; +import com.upchina.rbac.query.*; import com.upchina.rbac.vo.*; import com.upchina.video.constant.VideoUserType; import com.wf.captcha.SpecCaptcha; @@ -183,6 +180,25 @@ public class AuthService { } } + @Transactional(rollbackFor = Exception.class) + public void changePassword(ChangePasswordQuery query, BackendUserVO backendUserVO) { + Integer loginId = backendUserVO.getLoginId(); + UserLogin userInDB = userLoginMapper.selectById(loginId); + if (userInDB == null) { + throw new BizException(ResponseStatus.USER_STATUS_ERROR); + } + String originalPassword = query.getOriginalPassword(); + if (!CodecUtil.md5(originalPassword).equals(userInDB.getPassword())) { + throw new BizException(ResponseStatus.ORIGINAL_PASSWORD_ERROR); + } + String md5 = CodecUtil.md5(query.getPassword()); + UserLogin user = new UserLogin(); + user.setLoginId(loginId); + user.setPassword(md5); + userLoginMapper.updateById(user); + userService.clearCache(); + } + @Transactional(rollbackFor = Exception.class) public void changeMobile(ChangeMobileQuery query, BackendUserVO backendUserVO) { Integer loginId = backendUserVO.getLoginId(); diff --git a/src/main/java/com/upchina/video/mapper/VideoUserFlowMapper.java b/src/main/java/com/upchina/video/mapper/VideoUserFlowMapper.java index 19bb1eb..0e04b73 100644 --- a/src/main/java/com/upchina/video/mapper/VideoUserFlowMapper.java +++ b/src/main/java/com/upchina/video/mapper/VideoUserFlowMapper.java @@ -2,8 +2,8 @@ package com.upchina.video.mapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.upchina.common.entity.OnlineUser; import com.upchina.common.mapper.EasyBaseMapper; -import com.upchina.video.entity.OnlineUser; import com.upchina.video.entity.VideoLiveTrend; import com.upchina.video.entity.VideoUserFlow; import org.apache.ibatis.annotations.Param; diff --git a/src/main/java/com/upchina/video/service/admin/AdminVideoInteractionService.java b/src/main/java/com/upchina/video/service/admin/AdminVideoInteractionService.java index 91ca0bb..0660fb3 100644 --- a/src/main/java/com/upchina/video/service/admin/AdminVideoInteractionService.java +++ b/src/main/java/com/upchina/video/service/admin/AdminVideoInteractionService.java @@ -14,6 +14,7 @@ import com.upchina.advisor.entity.AdvisorFollow; import com.upchina.advisor.mapper.AdvisorFollowMapper; import com.upchina.common.constant.IsFollow; import com.upchina.common.constant.IsOrNot; +import com.upchina.common.entity.OnlineUser; import com.upchina.video.constant.VideoLiveStatus; import com.upchina.video.constant.VideoMessageContentType; import com.upchina.video.constant.VideoMessageStatus; diff --git a/src/main/java/com/upchina/video/service/admin/AdminVideoStatisticService.java b/src/main/java/com/upchina/video/service/admin/AdminVideoStatisticService.java index 5223641..ac777fe 100644 --- a/src/main/java/com/upchina/video/service/admin/AdminVideoStatisticService.java +++ b/src/main/java/com/upchina/video/service/admin/AdminVideoStatisticService.java @@ -15,6 +15,7 @@ import com.upchina.common.config.cache.CacheKey; import com.upchina.common.constant.IsOrNot; import com.upchina.common.constant.ProductType; import com.upchina.common.constant.UserType; +import com.upchina.common.entity.OnlineUser; import com.upchina.common.handler.BizException; import com.upchina.common.result.Pager; import com.upchina.common.result.ResponseStatus; diff --git a/src/main/java/com/upchina/video/service/common/VideoCacheService.java b/src/main/java/com/upchina/video/service/common/VideoCacheService.java index 3785a8f..4263b4a 100644 --- a/src/main/java/com/upchina/video/service/common/VideoCacheService.java +++ b/src/main/java/com/upchina/video/service/common/VideoCacheService.java @@ -15,6 +15,7 @@ import com.upchina.common.config.cache.CacheKey; import com.upchina.common.constant.IsActive; import com.upchina.common.constant.IsOrNot; import com.upchina.common.constant.ProductType; +import com.upchina.common.entity.OnlineUser; import com.upchina.common.result.AppPager; import com.upchina.common.service.AdvertService; import com.upchina.common.service.CacheService; diff --git a/src/main/java/com/upchina/video/service/common/VideoCommonService.java b/src/main/java/com/upchina/video/service/common/VideoCommonService.java index 4863031..42bb9c1 100644 --- a/src/main/java/com/upchina/video/service/common/VideoCommonService.java +++ b/src/main/java/com/upchina/video/service/common/VideoCommonService.java @@ -9,6 +9,7 @@ import com.google.common.collect.Table; import com.upchina.common.config.cache.CacheKey; import com.upchina.common.constant.IsOrNot; import com.upchina.common.constant.ProductType; +import com.upchina.common.entity.OnlineUser; import com.upchina.common.handler.BizException; import com.upchina.common.result.ResponseStatus; import com.upchina.common.service.*; diff --git a/src/main/java/com/upchina/video/service/common/VideoMessageService.java b/src/main/java/com/upchina/video/service/common/VideoMessageService.java index cb733e9..681a682 100644 --- a/src/main/java/com/upchina/video/service/common/VideoMessageService.java +++ b/src/main/java/com/upchina/video/service/common/VideoMessageService.java @@ -9,13 +9,13 @@ import com.hazelcast.map.IMap; import com.hazelcast.topic.ITopic; import com.upchina.advisor.service.AdvisorInfoService; import com.upchina.common.constant.IsOrNot; +import com.upchina.common.entity.OnlineUser; import com.upchina.common.handler.BizException; import com.upchina.common.result.ResponseStatus; import com.upchina.common.util.logger.LoggerUtil; import com.upchina.common.vo.FrontUserVO; import com.upchina.rbac.service.UserService; import com.upchina.video.constant.*; -import com.upchina.video.entity.OnlineUser; import com.upchina.video.entity.VideoLive; import com.upchina.video.entity.VideoLiveMessage; import com.upchina.video.helper.VideoHelper; diff --git a/src/main/java/com/upchina/video/vo/message/VideoCustomerVO.java b/src/main/java/com/upchina/video/vo/message/VideoCustomerVO.java index 26e1a3e..847f6c7 100644 --- a/src/main/java/com/upchina/video/vo/message/VideoCustomerVO.java +++ b/src/main/java/com/upchina/video/vo/message/VideoCustomerVO.java @@ -1,6 +1,6 @@ package com.upchina.video.vo.message; -import com.upchina.video.entity.OnlineUser; +import com.upchina.common.entity.OnlineUser; import io.swagger.annotations.ApiModelProperty; import java.io.Serializable; diff --git a/src/main/java/com/upchina/video/vo/message/VideoNotificationVO.java b/src/main/java/com/upchina/video/vo/message/VideoNotificationVO.java index 1393b00..e09dc65 100644 --- a/src/main/java/com/upchina/video/vo/message/VideoNotificationVO.java +++ b/src/main/java/com/upchina/video/vo/message/VideoNotificationVO.java @@ -1,6 +1,6 @@ package com.upchina.video.vo.message; -import com.upchina.video.entity.OnlineUser; +import com.upchina.common.entity.OnlineUser; import com.upchina.video.entity.VideoCart; import com.upchina.video.vo.cart.CouponVO; import com.upchina.video.vo.question.NotifyQuestionVO; diff --git a/src/main/resources/conf/advisorServer.yaml b/src/main/resources/conf/advisorServer.yaml index f261ed2..73c53de 100644 --- a/src/main/resources/conf/advisorServer.yaml +++ b/src/main/resources/conf/advisorServer.yaml @@ -15,16 +15,19 @@ hazelcast: serverPort: 5709 #自己作为缓存服务器监听的端口号 scheduledEnable: true cron: - collectLivingVideo: "30 1/5 * * * ?" #每分钟统计已开始但未结束的视频直播数据 - saveVideoCount: "30 2/2 * * * ?" #从cache刷新视频播放量到DB 每分钟的第10s执行 - saveVideoUserDataToDB: "30 3/5 * * * ?" - saveCustomerDataToDB: "30 4/5 * * * ?" #收集用户信息 - refreshTranscodeStatus: "30 0/5 * * * ?" #从腾讯云拉取录播上传视频信息更新到DB + collectLivingVideo: "30 0/5 * * * ?" #每分钟统计已开始但未结束的视频直播数据 + saveVideoCount: "30 1/2 * * * ?" #从cache刷新视频播放量到DB 每分钟的第10s执行 + saveVideoUserDataToDB: "30 2/5 * * * ?" + saveCustomerDataToDB: "30 3/5 * * * ?" #收集用户信息 + refreshTranscodeStatus: "30 4/5 * * * ?" #从腾讯云拉取录播上传视频信息更新到DB updateLiveStatus: "0 1 * * * ?" #更新视频录播状态 stopLivingVideo: "0 1-5 0 * * ?" #结束前一天直播中/暂停中的视频直播 - saveWatchSeconds: "0 0/5 * * * ?" #保存短视频观看时长 collectLastWeek: "0 30 3 * * ?" #统计一周内的数据 - collectRecentEndVideo: "0 2/5 * * * ?" #每5分钟统计已结束48小时以内的视频直播数据 + saveWatchSeconds: "0 0/5 * * * ?" #保存短视频观看时长 + collectRecentEndVideo: "0 1/5 * * * ?" #每5分钟统计已结束48小时以内的视频直播数据 + saveGroupMessageRead: "0 2/5 * * * ?" #每5分钟统计已结束48小时以内的视频直播数据 + saveGroupUser: "0 3/5 * * * ?" + collectGroupData: "0 4/5 * * * ?" user: admin: roles: 1,3,4,5 #管理员角色id,用逗号隔开 diff --git a/src/test/java/com/upchina/group/service/GroupInfoServiceTest.java b/src/test/java/com/upchina/group/service/GroupInfoServiceTest.java deleted file mode 100644 index e19a72f..0000000 --- a/src/test/java/com/upchina/group/service/GroupInfoServiceTest.java +++ /dev/null @@ -1,192 +0,0 @@ -package com.upchina.group.service; - -import com.hazelcast.map.IMap; -import com.upchina.advisor.entity.AdvisorBasic; -import com.upchina.advisor.service.AdvisorInfoService; -import com.upchina.common.query.OnlyIdQuery; -import com.upchina.common.service.AppUserService; -import com.upchina.common.service.CacheService; -import com.upchina.common.service.SensitiveWordService; -import com.upchina.common.state.StateMachine; -import com.upchina.common.vo.BackendUserVO; -import com.upchina.common.vo.InsertIdVO; -import com.upchina.course.service.PageService; -import com.upchina.group.constant.GroupInfoStatus; -import com.upchina.group.entity.GroupInfo; -import com.upchina.group.mapper.GroupInfoMapper; -import com.upchina.group.query.SaveGroupQuery; -import com.upchina.group.query.UpdateGroupQuery; -import com.upchina.group.query.UpdateGroupStatusQuery; -import com.upchina.rbac.entity.UserDept; -import com.upchina.rbac.service.AuthService; -import com.upchina.rbac.service.UserService; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import java.util.HashMap; -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; - -@ExtendWith(MockitoExtension.class) -class GroupInfoServiceTest { - - @Mock - private GroupInfoMapper groupInfoMapper; - - @Mock - private SensitiveWordService sensitiveWordService; - - @Mock - private StateMachine groupSM; - - @Mock - private AdvisorInfoService advisorInfoService; - - @Mock - private UserService userService; - - @Mock - private AuthService authService; - - @Mock - private PageService pageService; - - @Mock - private CacheService cacheService; - - @Mock - private AppUserService appUserService; - - @Mock - private IMap groupCache; - - @InjectMocks - private GroupInfoService groupInfoService; - - private BackendUserVO mockBackendUser; - - @BeforeEach - void setUp() { - mockBackendUser = new BackendUserVO(); - mockBackendUser.setUserId(1); - mockBackendUser.setAdvisorId(100); - } - - @Test - void save_ShouldSucceed() { - // 准备测试数据 - SaveGroupQuery query = new SaveGroupQuery(); - query.setName("测试群组"); - query.setRemark("测试备注"); - query.setDetail("测试详情"); - query.setAdvisorId(100); - - // 设置模拟行为 - doNothing().when(sensitiveWordService).check(anyString(), anyString(), anyString()); - when(groupInfoMapper.insert(any(GroupInfo.class))).thenReturn(1); - - // 执行测试 - InsertIdVO result = groupInfoService.save(query, mockBackendUser); - - // 验证结果 - assertNotNull(result); - verify(groupInfoMapper).insert(any(GroupInfo.class)); - verify(sensitiveWordService).check(anyString(), anyString(), anyString()); - } - - @Test - void update_ShouldSucceed() { - // 准备测试数据 - UpdateGroupQuery query = new UpdateGroupQuery(); - query.setId(1); - query.setName("更新的群组名"); - - GroupInfo existingGroup = new GroupInfo(); - existingGroup.setId(1); - existingGroup.setStatus(GroupInfoStatus.TO_COMMIT.value); - existingGroup.setAdvisorId(100); - - // 设置模拟行为 - 修改这里的 mock 设置 - when(groupInfoMapper.selectById(1)).thenReturn(existingGroup); - when(groupInfoMapper.updateById(any(GroupInfo.class))).thenReturn(1); - - // 执行测试 - groupInfoService.update(query, mockBackendUser); - - // 验证结果 - verify(groupInfoMapper).updateById(any(GroupInfo.class)); - verify(groupCache).delete(anyString()); - // 验证 sensitiveWordService.check 被调用,使用参数捕获器 - verify(sensitiveWordService).check( - eq("更新的群组名"), // 名称 - isNull(), // 备注 - isNull() // 详情 - ); - } - - @Test - void updateStatus_ShouldSucceed() { - // 准备测试数据 - UpdateGroupStatusQuery query = new UpdateGroupStatusQuery(); - query.setId(1); - query.setEvent(GroupInfoStatus.EVENT_SUBMIT.value); - - GroupInfo existingGroup = new GroupInfo(); - existingGroup.setId(1); - existingGroup.setStatus(GroupInfoStatus.TO_AUDIT.value); - existingGroup.setAdvisorId(100); - - // 设置模拟行为 - when(groupInfoMapper.selectById(1)).thenReturn(existingGroup); - when(groupInfoMapper.updateById(any(GroupInfo.class))).thenReturn(1); - when(groupSM.send(any(), any())).thenReturn(GroupInfoStatus.TO_AUDIT); - - // 执行测试 - groupInfoService.updateStatus(query, mockBackendUser); - - // 验证结果 - verify(groupInfoMapper).updateById(any(GroupInfo.class)); - verify(groupCache).delete(anyString()); - } - - @Test - void get_ShouldReturnGroupVO() { - // 准备测试数据 - OnlyIdQuery query = new OnlyIdQuery(1); - - GroupInfo groupInfo = new GroupInfo(); - groupInfo.setId(1); - groupInfo.setAdvisorId(100); - - Map advisorMap = new HashMap<>(); - AdvisorBasic advisor = new AdvisorBasic(); - advisor.setId(100); - advisorMap.put(100, advisor); - - Map userMap = new HashMap<>(); - UserDept userDept = new UserDept(); - userDept.setUserId(1); - userDept.setName("测试用户"); - userMap.put(1, userDept); - - // 设置模拟行为 - when(groupInfoMapper.selectById(1)).thenReturn(groupInfo); - when(advisorInfoService.getAdvisorMap()).thenReturn(advisorMap); - when(userService.getUserMap()).thenReturn(userMap); - - // 执行测试 - var result = groupInfoService.get(query, mockBackendUser); - - // 验证结果 - assertNotNull(result); - assertEquals(1, result.getId()); - } -} \ No newline at end of file diff --git a/src/test/java/com/upchina/group/service/admin/AdminGroupMessageServiceTest.java b/src/test/java/com/upchina/group/service/admin/AdminGroupMessageServiceTest.java deleted file mode 100644 index d35390b..0000000 --- a/src/test/java/com/upchina/group/service/admin/AdminGroupMessageServiceTest.java +++ /dev/null @@ -1,134 +0,0 @@ -package com.upchina.group.service.admin; - -import com.upchina.common.state.StateMachine; -import com.upchina.common.vo.BackendUserVO; -import com.upchina.common.vo.OnlyIdVO; -import com.upchina.group.constant.GroupMessageChannel; -import com.upchina.group.constant.GroupMessageStatus; -import com.upchina.group.constant.GroupMessageType; -import com.upchina.group.entity.GroupInfo; -import com.upchina.group.entity.GroupMessage; -import com.upchina.group.mapper.GroupInfoMapper; -import com.upchina.group.mapper.GroupMessageMapper; -import com.upchina.group.query.message.GroupMessageProductQuery; -import com.upchina.group.query.message.GroupMessageStatusQuery; -import com.upchina.group.query.message.SendGroupMessageAdminQuery; -import com.upchina.group.service.common.GroupCacheService; -import com.upchina.group.service.common.GroupMessageService; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - -@ExtendWith(MockitoExtension.class) -class AdminGroupMessageServiceTest { - - @Mock - private GroupMessageMapper groupMessageMapper; - - @Mock - private GroupInfoMapper groupInfoMapper; - - @Mock - private GroupMessageService groupMessageService; - - @Mock - private GroupCacheService groupCacheService; - - @Mock - private StateMachine groupMessageSM; - - @InjectMocks - private AdminGroupMessageService adminGroupMessageService; - - private BackendUserVO mockBackendUser; - - @BeforeEach - void setUp() { - mockBackendUser = new BackendUserVO(); - mockBackendUser.setUserId(1); - mockBackendUser.setAdvisorId(100); - } - - @Test - void sendAdvisorMessage_ShouldSucceed() { - // 准备测试数据 - SendGroupMessageAdminQuery query = new SendGroupMessageAdminQuery(); - query.setGroupId(1); - query.setContent("测试消息"); - - when(groupMessageMapper.insert(any(GroupMessage.class))).thenReturn(1); - - // 执行测试 - OnlyIdVO result = adminGroupMessageService.sendAdvisorMessage(query, mockBackendUser); - - // 验证结果 - assertNotNull(result); - verify(groupMessageMapper).insert(any(GroupMessage.class)); - verify(groupMessageService).publishGroupMessage( - eq(GroupMessageChannel.ALL), - eq(GroupMessageType.RECOMMEND_PRODUCT), - eq(query.getGroupId()), - any() - ); - } - - @Test - void sendInteractiveStatusMessage_ShouldSucceed() { - // 准备测试数据 - GroupMessageStatusQuery query = new GroupMessageStatusQuery(); - query.setGroupId(1); - query.setStatus(1); - - GroupInfo mockGroupInfo = new GroupInfo(); - mockGroupInfo.setId(1); - - when(groupInfoMapper.selectById(query.getGroupId())).thenReturn(mockGroupInfo); - when(groupInfoMapper.updateById(any(GroupInfo.class))).thenReturn(1); - - // 执行测试 - adminGroupMessageService.sendInteractiveStatusMessage(query, mockBackendUser); - - // 验证结果 - verify(groupInfoMapper).selectById(query.getGroupId()); - verify(groupInfoMapper).updateById(any(GroupInfo.class)); - verify(groupMessageService).publishGroupMessage( - eq(GroupMessageChannel.APP), - eq(GroupMessageType.OPEN_INTERACTIVE), - eq(query.getGroupId()), - eq(query.getStatus()) - ); - } - - @Test - void saveProductMessage_ShouldSucceed() { - // 准备测试数据 - GroupMessageProductQuery query = new GroupMessageProductQuery(); - query.setGroupId(1); - query.setProductId(100); - query.setProductName("测试产品"); - query.setProductDesc("产品描述"); - query.setProductUrl("http://example.com"); - - when(groupMessageMapper.insert(any(GroupMessage.class))).thenReturn(1); - - // 执行测试 - OnlyIdVO result = adminGroupMessageService.saveProductMessage(query, mockBackendUser); - - // 验证结果 - assertNotNull(result); - verify(groupMessageMapper).insert(any(GroupMessage.class)); - verify(groupMessageService).publishGroupMessage( - eq(GroupMessageChannel.ALL), - eq(GroupMessageType.RECOMMEND_PRODUCT), - eq(query.getGroupId()), - any() - ); - } -} \ No newline at end of file diff --git a/src/test/java/com/upchina/group/service/app/AppGroupMessageServiceTest.java b/src/test/java/com/upchina/group/service/app/AppGroupMessageServiceTest.java deleted file mode 100644 index e9abcd0..0000000 --- a/src/test/java/com/upchina/group/service/app/AppGroupMessageServiceTest.java +++ /dev/null @@ -1,208 +0,0 @@ -package com.upchina.group.service.app; - -import com.hazelcast.map.IMap; -import com.upchina.common.constant.IsOrNot; -import com.upchina.common.handler.BizException; -import com.upchina.common.query.OnlyIdQuery; -import com.upchina.common.result.AppPager; -import com.upchina.common.service.CacheService; -import com.upchina.common.service.SensitiveWordService; -import com.upchina.common.vo.FrontUserVO; -import com.upchina.group.constant.GroupMessageChannel; -import com.upchina.group.constant.GroupMessageType; -import com.upchina.group.constant.QueryGroupMessageType; -import com.upchina.group.entity.GroupMessage; -import com.upchina.group.mapper.GroupMessageMapper; -import com.upchina.group.query.message.ListGroupMessageAppQuery; -import com.upchina.group.query.message.SendGroupMessageAppQuery; -import com.upchina.group.service.GroupInfoService; -import com.upchina.group.service.common.GroupCacheService; -import com.upchina.group.service.common.GroupCommonService; -import com.upchina.group.service.common.GroupMessageService; -import com.upchina.group.vo.GroupVO; -import com.upchina.group.vo.message.GroupMessageVO; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import java.util.NavigableSet; -import java.util.TreeSet; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; - -@ExtendWith(MockitoExtension.class) -class AppGroupMessageServiceTest { - - @Mock - private GroupMessageMapper groupMessageMapper; - - @Mock - private GroupMessageService groupMessageService; - - @Mock - private GroupInfoService groupInfoService; - - @Mock - private GroupCacheService groupCacheService; - - @Mock - private GroupCommonService groupCommonService; - - @Mock - private SensitiveWordService sensitiveWordService; - - @Mock - private CacheService cacheService; - - @Mock - private IMap groupCache; - - @InjectMocks - private AppGroupMessageService appGroupMessageService; - - private FrontUserVO mockFrontUser; - private GroupVO mockGroupVO; - - @BeforeEach - void setUp() { - mockFrontUser = new FrontUserVO(); - mockFrontUser.setUserId("123"); - - mockGroupVO = new GroupVO(); - mockGroupVO.setId(1); - mockGroupVO.setPrivateChatStatus(IsOrNot.IS.value); - } - - @Test - void getMessageList_ShouldSucceed() { - // 准备测试数据 - ListGroupMessageAppQuery query = new ListGroupMessageAppQuery(); - query.setGroupId(1); - query.setType(QueryGroupMessageType.ADVISOR.value); - query.setSize(10); - - NavigableSet mockSet = new TreeSet<>(); - mockSet.add(1); - mockSet.add(2); - - GroupMessageVO mockMessageVO = new GroupMessageVO(); - mockMessageVO.setId(1); - - // 设置模拟行为 - when(groupInfoService.getForApp(any(OnlyIdQuery.class), any())).thenReturn(mockGroupVO); - when(groupCommonService.validateUserPermission(anyString(), any(GroupVO.class))).thenReturn(true); - when(cacheService.get(eq(groupCache), anyString(), any())).thenReturn(mockSet); - - // 执行测试 - AppPager result = appGroupMessageService.getMessageList(query, mockFrontUser); - - // 验证结果 - assertNotNull(result); - assertFalse(result.getList().isEmpty()); - assertEquals(1, result.getList().get(0).getId()); - } - - @Test - void getMessageList_WithPrivateType_ShouldSucceed() { - // 准备测试数据 - ListGroupMessageAppQuery query = new ListGroupMessageAppQuery(); - query.setGroupId(1); - query.setType(QueryGroupMessageType.PRIVATE.value); - query.setSize(10); - - NavigableSet mockSet = new TreeSet<>(); - mockSet.add(1); - - GroupMessageVO mockMessageVO = new GroupMessageVO(); - mockMessageVO.setId(1); - - // 设置模拟行为 - when(groupInfoService.getForApp(any(OnlyIdQuery.class), any())).thenReturn(mockGroupVO); - when(groupCommonService.validateUserPermission(anyString(), any(GroupVO.class))).thenReturn(true); - when(cacheService.get(eq(groupCache), anyString(), any())).thenReturn(mockSet); - - // 执行测试 - AppPager result = appGroupMessageService.getMessageList(query, mockFrontUser); - - // 验证结果 - assertNotNull(result); - assertFalse(result.getList().isEmpty()); - } - - @Test - void sendMessage_ShouldSucceed() { - // 准备测试数据 - SendGroupMessageAppQuery query = new SendGroupMessageAppQuery(); - query.setGroupId(1); - query.setContent("测试消息"); - - // 设置模拟行为 - doNothing().when(sensitiveWordService).check(anyString()); - when(groupMessageMapper.insert(any(GroupMessage.class))).thenReturn(1); - - // 执行测试 - GroupMessageVO result = appGroupMessageService.sendMessage(query, mockFrontUser); - - // 验证结果 - assertNotNull(result); - verify(groupMessageService).publishGroupMessage( - eq(GroupMessageChannel.ALL), - eq(GroupMessageType.NORMAL), - eq(query.getGroupId()), - any(GroupMessageVO.class) - ); - } - - @Test - void sendMessage_WhenGroupClosed_ShouldThrowException() { - // 准备测试数据 - SendGroupMessageAppQuery query = new SendGroupMessageAppQuery(); - query.setGroupId(1); - query.setContent("测试消息"); - - // 设置模拟行为 - doNothing().when(sensitiveWordService).check(anyString()); - - // 执行测试并验证异常 - assertThrows(BizException.class, () -> - appGroupMessageService.sendMessage(query, mockFrontUser) - ); - } - - @Test - void sendMessage_WhenUserForbidden_ShouldThrowException() { - // 准备测试数据 - SendGroupMessageAppQuery query = new SendGroupMessageAppQuery(); - query.setGroupId(1); - query.setContent("测试消息"); - - // 设置模拟行为 - doNothing().when(sensitiveWordService).check(anyString()); - - // 执行测试并验证异常 - assertThrows(BizException.class, () -> - appGroupMessageService.sendMessage(query, mockFrontUser) - ); - } - - @Test - void getMessageList_WithInvalidGroup_ShouldThrowException() { - // 准备测试数据 - ListGroupMessageAppQuery query = new ListGroupMessageAppQuery(); - query.setGroupId(1); - query.setType(QueryGroupMessageType.ADVISOR.value); - - // 设置模拟行为 - when(groupInfoService.getForApp(any(OnlyIdQuery.class), any())).thenReturn(null); - - // 执行测试并验证异常 - assertThrows(BizException.class, () -> - appGroupMessageService.getMessageList(query, mockFrontUser) - ); - } -} \ No newline at end of file