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