补全交互操作

This commit is contained in:
easonzhu 2025-02-05 12:08:59 +08:00
parent e8b1c20be8
commit b2514267bc
27 changed files with 919 additions and 162 deletions

View File

@ -20,6 +20,9 @@ public class ListAdvisorInfoQuery extends PageQuery {
@ApiModelProperty("营业部id")
private String deptId;
@ApiModelProperty("指定营业部")
private String selectDeptId;
@ApiModelProperty("是否过滤掉自己 1:过滤 2:不过滤")
private Integer filterSelf;
@ -63,6 +66,14 @@ public class ListAdvisorInfoQuery extends PageQuery {
this.deptId = deptId;
}
public String getSelectDeptId() {
return selectDeptId;
}
public void setSelectDeptId(String selectDeptId) {
this.selectDeptId = selectDeptId;
}
public Integer getFilterSelf() {
return filterSelf;
}

View File

@ -142,6 +142,7 @@ public class AdvisorInfoService {
String showName = query.getShowName();
Integer status = query.getStatus();
String deptId = query.getDeptId();
String selectDeptId = query.getSelectDeptId();
Integer filterSelf = query.getFilterSelf();
Map<String, Dept> deptMap = deptService.getDeptMap();
Dept dept = deptMap.get(deptId);
@ -157,6 +158,7 @@ public class AdvisorInfoService {
.like(StrUtil.isNotEmpty(showName), "show_name", showName)
.eq(status != null, "status", status)
.eq(StrUtil.isNotBlank(deptId), "dept_id", deptId)
.eq(StrUtil.isNotBlank(selectDeptId), "dept_id", deptId)
.ne(IsOrNot.IS.value.equals(filterSelf) && backendUserVO.getAdvisorId() != null, "id", backendUserVO.getAdvisorId());
Page<AdvisorInfo> page = advisorInfoMapper.selectPage(query.toPage(), wrapper);
List<AdvisorInfoAdminVO> list = page.getRecords().stream().map(advisorInfo -> {

View File

@ -3,6 +3,7 @@ package com.upchina.common.config;
import com.upchina.common.handler.WebSocketErrorHandler;
import com.upchina.common.interceptor.WebSocketAuthChannelInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.messaging.simp.config.ChannelRegistration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
@ -33,6 +34,7 @@ public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
private WebSocketErrorHandler webSocketErrorHandler;
@Resource
@Lazy
private WebSocketAuthChannelInterceptor clientInChannelInterceptor;
/**

View File

@ -414,10 +414,11 @@ public class CacheKey {
}
public static class GroupKey {
public static final String GROUP_INFO = "group|info|";
public static final String MAIN_GROUP_LIST = "group|main|list|";
public static final String GROUP_MESSAGE_LIST = "group|message|list|";
public static final String GROUP_MESSAGE_DETAIL = "group|message|detail|";
public static final String GROUP_INFO = "group_info|";
public static final String MAIN_GROUP_LIST = "group_main_list|";
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|";
}
}

View File

@ -0,0 +1,19 @@
package com.upchina.common.interceptor;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class SessionInfo {
private String userId;
private Integer productType;
private Integer productId;
private String sessionId;
private String sessionKey;
public boolean isValid() {
return userId != null && productType != null && productId != null
&& sessionId != null && sessionKey != null;
}
}

View File

@ -1,6 +1,8 @@
package com.upchina.common.interceptor;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.ImmutableSet;
import com.upchina.common.constant.ProductType;
import com.upchina.common.filter.AuthFilter;
import com.upchina.common.handler.BizException;
import com.upchina.common.result.ResponseStatus;
@ -13,6 +15,7 @@ import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Map;
import java.util.Set;
@Slf4j
@Component
@ -21,6 +24,8 @@ public class WebSocketAuthHandler {
@Resource
private AuthFilter authFilter;
private Set<Integer> VALID_PRODUCT_TYPES = ImmutableSet.of(ProductType.VIDEO_SINGLE.value, ProductType.GROUP.value);
public Message<?> handleConnect(Message<?> message, StompHeaderAccessor header) {
validateHeaders(header);
Map<String, Object> attributes = header.getSessionAttributes();
@ -31,9 +36,12 @@ public class WebSocketAuthHandler {
}
String sessionId = header.getFirstNativeHeader("sessionId");
Integer videoId = getVideoId(header);
populateAttributes(attributes, userId, sessionId, videoId);
Integer productType = getInteger(header, "productType");
if (productType == null || !VALID_PRODUCT_TYPES.contains(productType)) {
throw new BizException(ResponseStatus.PARM_ERROR, "产品类型错误" + productType);
}
Integer productId = getInteger(header, "productId");
populateAttributes(attributes, userId, sessionId, productType, productId);
return message;
}
@ -71,16 +79,16 @@ public class WebSocketAuthHandler {
return null;
}
private Integer getVideoId(StompHeaderAccessor header) {
String groupId = header.getFirstNativeHeader("GroupId");
return StrUtil.isNotEmpty(groupId) ? Integer.parseInt(groupId) : null;
private Integer getInteger(StompHeaderAccessor header, String headerName) {
String value = header.getFirstNativeHeader(headerName);
return StrUtil.isNotEmpty(value) ? Integer.parseInt(value) : null;
}
private void populateAttributes(Map<String, Object> attributes, String userId,
String sessionId, Integer videoId) {
private void populateAttributes(Map<String, Object> attributes, String userId, String sessionId, Integer productType, Integer productId) {
attributes.put("userId", userId);
attributes.put("sessionId", sessionId);
attributes.put("videoId", videoId);
attributes.put("productType", productType);
attributes.put("productId", productId);
attributes.put("sessionKey", userId + "-" + sessionId);
}
}

View File

@ -2,8 +2,10 @@ package com.upchina.common.interceptor;
import com.hazelcast.map.IMap;
import com.upchina.common.constant.IsOrNot;
import com.upchina.common.model.SessionInfo;
import com.upchina.common.constant.ProductType;
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;
@ -23,6 +25,12 @@ public class WebSocketSessionHandler {
@Resource
private VideoMessageService videoMessageService;
@Resource
private GroupCacheService groupCacheService;
@Resource
private GroupMessageService groupMessageService;
public void handleConnect(StompHeaderAccessor header) {
Map<String, Object> attributes = header.getSessionAttributes();
FrontUserVO frontUser = (FrontUserVO) attributes.get("frontUser");
@ -36,8 +44,8 @@ public class WebSocketSessionHandler {
}
OnlineUser onlineUser = createOnlineUser(sessionInfo, frontUser);
updateOnlineStatus(sessionInfo.getVideoId(), sessionInfo.getSessionKey(), onlineUser);
notifyUserConnect(sessionInfo.getVideoId(), frontUser, onlineUser);
updateOnlineStatus(sessionInfo.getProductType(), sessionInfo.getProductId(), sessionInfo.getSessionKey(), onlineUser);
notifyUserConnect(sessionInfo.getProductType(), sessionInfo.getProductId(), frontUser, onlineUser);
}
public void handleDisconnect(StompHeaderAccessor header) {
@ -58,7 +66,8 @@ public class WebSocketSessionHandler {
private SessionInfo extractSessionInfo(Map<String, Object> attributes) {
return SessionInfo.builder()
.userId((String) attributes.get("userId"))
.videoId((Integer) attributes.get("videoId"))
.productType((Integer) attributes.get("productType"))
.productId((Integer)attributes.get("productId"))
.sessionId((String) attributes.get("sessionId"))
.sessionKey((String) attributes.get("sessionKey"))
.build();
@ -66,7 +75,8 @@ public class WebSocketSessionHandler {
private OnlineUser createOnlineUser(SessionInfo sessionInfo, FrontUserVO frontUser) {
return new OnlineUser(
sessionInfo.getVideoId(),
sessionInfo.getProductType(),
sessionInfo.getProductId(),
sessionInfo.getUserId(),
frontUser.getUserName(),
frontUser.getImgUrl(),
@ -77,23 +87,28 @@ public class WebSocketSessionHandler {
);
}
private void updateOnlineStatus(Integer videoId, String sessionKey, OnlineUser onlineUser) {
IMap<String, OnlineUser> totalOnlineMap = videoCacheService.getTotalOnlineMap(videoId);
private void updateOnlineStatus(Integer productType, Integer productId, String sessionKey, OnlineUser onlineUser) {
IMap<String, OnlineUser> totalOnlineMap = getTotalOnlineMap(productType, productId);
if (totalOnlineMap != null) {
totalOnlineMap.put(sessionKey, onlineUser);
}
}
private void notifyUserConnect(Integer videoId, FrontUserVO frontUser, OnlineUser onlineUser) {
videoMessageService.memberNotify(videoId, onlineUser);
videoMessageService.publishEnterMessage(videoId, frontUser);
private void notifyUserConnect(Integer productType, Integer productId, FrontUserVO frontUser, OnlineUser onlineUser) {
memberNotify(productType, productId, onlineUser);
publishEnterMessage(productType, productId, frontUser);
}
private void handleUserDisconnect(SessionInfo sessionInfo) {
IMap<String, OnlineUser> totalOnlineMap = videoCacheService.getTotalOnlineMap(sessionInfo.getVideoId());
OnlineUser onlineUser = totalOnlineMap.get(sessionInfo.getSessionKey());
Integer productType = sessionInfo.getProductType();
Integer productId = sessionInfo.getProductId();
String sessionKey = sessionInfo.getSessionKey();
IMap<String, OnlineUser> totalOnlineMap = getTotalOnlineMap(productType, productId);
OnlineUser onlineUser = totalOnlineMap.get(sessionKey);
if (onlineUser != null) {
updateOfflineStatus(onlineUser);
totalOnlineMap.put(sessionInfo.getSessionKey(), onlineUser);
videoMessageService.memberNotify(sessionInfo.getVideoId(), onlineUser);
totalOnlineMap.put(sessionKey, onlineUser);
memberNotify(productType, productId, onlineUser);
}
}
@ -102,4 +117,29 @@ public class WebSocketSessionHandler {
onlineUser.setIsPlay(IsOrNot.NOT.value);
onlineUser.setExitTime(LocalDateTime.now());
}
private IMap<String, OnlineUser> getTotalOnlineMap(Integer productType, Integer productId) {
if (ProductType.VIDEO_SINGLE.value.equals(productType)) {
return videoCacheService.getTotalOnlineMap(productId);
} else if (ProductType.GROUP.value.equals(productType)) {
return groupCacheService.getTotalOnlineMap(productId);
}
return null;
}
private void memberNotify(Integer productType, Integer productId, OnlineUser onlineUser) {
if (ProductType.VIDEO_SINGLE.value.equals(productType)) {
videoMessageService.memberNotify(productId, onlineUser);
} else if (ProductType.GROUP.value.equals(productType)) {
groupMessageService.memberNotify(productId, onlineUser);
}
}
private void publishEnterMessage(Integer productType, Integer productId, FrontUserVO frontUser) {
if (ProductType.VIDEO_SINGLE.value.equals(productType)) {
videoMessageService.publishEnterMessage(productId, frontUser);
} else if (ProductType.GROUP.value.equals(productType)) {
groupMessageService.publishEnterMessage(productId, frontUser);
}
}
}

View File

@ -1,18 +0,0 @@
package com.upchina.common.model;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class SessionInfo {
private String userId;
private Integer videoId;
private String sessionId;
private String sessionKey;
public boolean isValid() {
return userId != null && videoId != null &&
sessionId != null && sessionKey != null;
}
}

View File

@ -99,4 +99,30 @@ public class AdminGroupMessageController {
adminGroupMessageService.setShowMemberCount(query, backendUser);
return CommonResult.success();
}
@ApiOperation("设置显示昵称")
@PostMapping("/admin/group/message/setShowNickName")
public CommonResult<Void> setShowNickName(
@Validated @RequestBody @ApiParam(required = true) GroupMessageStatusQuery query,
@RequestAttribute(value = "backendUser", required = false) BackendUserVO backendUser) {
if (backendUser == null) {
throw new BizException(ResponseStatus.SESSION_EXPIRY);
}
adminGroupMessageService.setShowNickName(query, backendUser);
return CommonResult.success();
}
@ApiOperation("设置先审后发")
@PostMapping("/admin/group/message/setFirstAudit")
public CommonResult<Void> setFirstAudit(
@Validated @RequestBody @ApiParam(required = true) GroupMessageStatusQuery query,
@RequestAttribute(value = "backendUser", required = false) BackendUserVO backendUser) {
if (backendUser == null) {
throw new BizException(ResponseStatus.SESSION_EXPIRY);
}
adminGroupMessageService.setFirstAudit(query, backendUser);
return CommonResult.success();
}
}

View File

@ -14,7 +14,7 @@ import java.time.LocalDateTime;
* </p>
*
* @author easonzhu
* @since 2025-01-29
* @since 2025-02-05
*/
public class GroupInfo implements Serializable {
@ -71,11 +71,23 @@ public class GroupInfo implements Serializable {
private Integer privateChatStatus;
/**
* 显示成员人数 1:开启 2:关闭
* 显示人数 1:开启 2:关闭
*/
@TableField("show_member_count")
private Integer showMemberCount;
/**
* 显示昵称 1:开启 2:关闭
*/
@TableField("show_nick_name")
private Integer showNickName;
/**
* 先审后发 1:开启 2:关闭
*/
@TableField("first_audit")
private Integer firstAudit;
/**
* 落地页ID
*/
@ -244,7 +256,6 @@ public class GroupInfo implements Serializable {
public void setInteractiveStatus(Integer interactiveStatus) {
this.interactiveStatus = interactiveStatus;
}
public Integer getPrivateChatStatus() {
return privateChatStatus;
}
@ -259,6 +270,20 @@ public class GroupInfo implements Serializable {
public void setShowMemberCount(Integer showMemberCount) {
this.showMemberCount = showMemberCount;
}
public Integer getShowNickName() {
return showNickName;
}
public void setShowNickName(Integer showNickName) {
this.showNickName = showNickName;
}
public Integer getFirstAudit() {
return firstAudit;
}
public void setFirstAudit(Integer firstAudit) {
this.firstAudit = firstAudit;
}
public Integer getPageId() {
return pageId;
}
@ -403,7 +428,11 @@ public class GroupInfo implements Serializable {
", applicableUser=" + applicableUser +
", detail=" + detail +
", welcomeMessage=" + welcomeMessage +
", interactiveStatus=" + interactiveStatus +
", privateChatStatus=" + privateChatStatus +
", showMemberCount=" + showMemberCount +
", showNickName=" + showNickName +
", firstAudit=" + firstAudit +
", pageId=" + pageId +
", originalPrice=" + originalPrice +
", activityPrice=" + activityPrice +

View File

@ -0,0 +1,108 @@
package com.upchina.group.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
* 交易圈在线流水表
* </p>
*
* @author easonzhu
* @since 2025-02-04
*/
public class GroupUserFlow implements Serializable {
/**
* 交易圈id
*/
@TableField("group_id")
private Integer groupId;
/**
* 用户userId
*/
@TableField("user_id")
private String userId;
/**
* session所属设备
*/
@TableField("session_id")
private String sessionId;
/**
* 时间yyyy-MM-dd HH:ss
*/
private LocalDateTime time;
/**
* 进入时间
*/
@TableField("enter_time")
private LocalDateTime enterTime;
/**
* 退出时间
*/
@TableField("exit_time")
private LocalDateTime exitTime;
public Integer getGroupId() {
return groupId;
}
public void setGroupId(Integer groupId) {
this.groupId = groupId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getSessionId() {
return sessionId;
}
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
public LocalDateTime getTime() {
return time;
}
public void setTime(LocalDateTime time) {
this.time = time;
}
public LocalDateTime getEnterTime() {
return enterTime;
}
public void setEnterTime(LocalDateTime enterTime) {
this.enterTime = enterTime;
}
public LocalDateTime getExitTime() {
return exitTime;
}
public void setExitTime(LocalDateTime exitTime) {
this.exitTime = exitTime;
}
@Override
public String toString() {
return "GroupUserFlow{" +
"groupId=" + groupId +
", userId=" + userId +
", sessionId=" + sessionId +
", time=" + time +
", enterTime=" + enterTime +
", exitTime=" + exitTime +
"}";
}
}

View File

@ -9,7 +9,7 @@ import com.upchina.group.entity.GroupInfo;
* </p>
*
* @author easonzhu
* @since 2025-01-29
* @since 2025-02-05
*/
public interface GroupInfoMapper extends BaseMapper<GroupInfo> {

View File

@ -1,7 +1,7 @@
package com.upchina.group.mapper;
import com.upchina.group.entity.GroupMessage;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.upchina.group.entity.GroupMessage;
/**
* <p>

View File

@ -0,0 +1,27 @@
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.group.entity.GroupUserFlow;
import com.upchina.video.entity.OnlineUser;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* <p>
* 交易圈在线流水表 Mapper 接口
* </p>
*
* @author easonzhu
* @since 2025-02-04
*/
public interface GroupUserFlowMapper extends BaseMapper<GroupUserFlow> {
@Select("SELECT h.group_id, h.user_id, h.session_id, 2 as is_online " +
"FROM group_user_flow h " +
"${ew.customSqlSegment}")
List<OnlineUser> loadHis(@Param(Constants.WRAPPER) LambdaQueryWrapper<GroupUserFlow> wrapper);
}

View File

@ -34,10 +34,21 @@ public class SaveGroupQuery {
@ApiModelProperty("欢迎语")
private String welcomeMessage;
@ApiModelProperty("互动状态 1:开启 2:关闭")
private Integer interactiveStatus;
@ApiModelProperty("私聊状态 1:开启 2:关闭")
@NotNull
private Integer privateChatStatus;
@ApiModelProperty("显示人数 1:开启 2:关闭")
private Integer showMemberCount;
@ApiModelProperty("显示昵称 1:开启 2:关闭")
private Integer showNickName;
@ApiModelProperty("先审后发 1:开启 2:关闭")
private Integer firstAudit;
@ApiModelProperty("落地页ID")
private Integer pageId;
@ -76,7 +87,11 @@ public class SaveGroupQuery {
groupInfo.setApplicableUser(applicableUser);
groupInfo.setDetail(detail);
groupInfo.setWelcomeMessage(welcomeMessage);
groupInfo.setInteractiveStatus(interactiveStatus);
groupInfo.setPrivateChatStatus(privateChatStatus);
groupInfo.setShowMemberCount(showMemberCount);
groupInfo.setShowNickName(showNickName);
groupInfo.setFirstAudit(firstAudit);
groupInfo.setPageId(pageId);
groupInfo.setOriginalPrice(originalPrice);
groupInfo.setActivityPrice(activityPrice);
@ -141,6 +156,14 @@ public class SaveGroupQuery {
this.welcomeMessage = welcomeMessage;
}
public Integer getInteractiveStatus() {
return interactiveStatus;
}
public void setInteractiveStatus(Integer interactiveStatus) {
this.interactiveStatus = interactiveStatus;
}
public Integer getPrivateChatStatus() {
return privateChatStatus;
}
@ -149,6 +172,30 @@ public class SaveGroupQuery {
this.privateChatStatus = privateChatStatus;
}
public Integer getShowMemberCount() {
return showMemberCount;
}
public void setShowMemberCount(Integer showMemberCount) {
this.showMemberCount = showMemberCount;
}
public Integer getShowNickName() {
return showNickName;
}
public void setShowNickName(Integer showNickName) {
this.showNickName = showNickName;
}
public Integer getFirstAudit() {
return firstAudit;
}
public void setFirstAudit(Integer firstAudit) {
this.firstAudit = firstAudit;
}
public Integer getPageId() {
return pageId;
}
@ -220,4 +267,6 @@ public class SaveGroupQuery {
public void setWechatWorkId(Integer wechatWorkId) {
this.wechatWorkId = wechatWorkId;
}
}

View File

@ -41,6 +41,22 @@ public class GroupMessageStatusQuery {
return groupInfo;
}
public GroupInfo toShowNickNamePO() {
GroupInfo groupInfo = new GroupInfo();
groupInfo.setId(groupId);
groupInfo.setShowNickName(status);
groupInfo.setUpdateTime(LocalDateTime.now());
return groupInfo;
}
public GroupInfo toFirstAuditPO() {
GroupInfo groupInfo = new GroupInfo();
groupInfo.setId(groupId);
groupInfo.setFirstAudit(status);
groupInfo.setUpdateTime(LocalDateTime.now());
return groupInfo;
}
public Integer getGroupId() {
return groupId;
}

View File

@ -47,9 +47,16 @@ public class AdminGroupMessageService {
@Transactional(rollbackFor = Exception.class)
public OnlyIdVO sendAdvisorMessage(SendGroupMessageAdminQuery query, BackendUserVO backendUser) {
GroupInfo group = groupInfoMapper.selectById(query.getGroupId());
if (group == null) {
throw new BizException(ResponseStatus.ID_NOT_EXIST_ERROR, "交易圈不存在");
}
GroupMessage message = query.toPO(backendUser);
groupMessageMapper.insert(message);
groupMessageService.publishGroupMessage(GroupMessageChannel.ALL, GroupMessageType.RECOMMEND_PRODUCT, query.getGroupId(), message.getContent());
groupMessageService.publishGroupMessage(GroupMessageChannel.ALL, GroupMessageType.NORMAL, query.getGroupId(), message.getContent());
groupCacheService.addMessage(message);
return new OnlyIdVO(message.getId());
}
@ -59,6 +66,11 @@ public class AdminGroupMessageService {
if (groupMessageInDB == null) {
throw new BizException(ResponseStatus.ID_NOT_EXIST_ERROR);
}
Integer groupId = groupMessageInDB.getGroupId();
GroupInfo group = groupInfoMapper.selectById(groupId);
if (group == null) {
throw new BizException(ResponseStatus.ID_NOT_EXIST_ERROR, "交易圈不存在");
}
// 状态机扭转
GroupMessageStatus dbStatus = GroupMessageStatus.fromValue(groupMessageInDB.getStatus());
@ -66,7 +78,15 @@ public class AdminGroupMessageService {
GroupMessage groupMessage = query.toPO(targetStatus, backendUserVO);
groupMessageMapper.updateById(groupMessage);
groupCacheService.clearMessageCache(query.getId(), groupMessage.getGroupId());
if (GroupMessageStatus.DELETED.equals(targetStatus)) {
groupCacheService.removeMessage(groupMessageInDB);
} else if (GroupMessageStatus.AUDITED.equals(targetStatus)) {
if (!IsOrNot.IS.value.equals(group.getFirstAudit())) {
groupMessageService.publishGroupMessage(GroupMessageChannel.ALL, GroupMessageType.NORMAL, groupId, groupMessageInDB.getContent());
groupCacheService.addMessage(groupMessageInDB);
}
}
}
public AppPager<GroupMessageVO> getMessageList(ListGroupMessageQuery query, BackendUserVO backendUser) {
@ -134,7 +154,7 @@ public class AdminGroupMessageService {
GroupInfo group = query.toInteractivePO();
groupInfoMapper.updateById(group);
groupMessageService.publishGroupMessage(GroupMessageChannel.APP, GroupMessageType.OPEN_INTERACTIVE, groupId, query.getStatus());
groupMessageService.publishGroupMessage(GroupMessageChannel.ALL, GroupMessageType.OPEN_INTERACTIVE, groupId, query.getStatus());
}
/**
@ -150,7 +170,7 @@ public class AdminGroupMessageService {
GroupInfo group = query.toPrivatePO();
groupInfoMapper.updateById(group);
groupMessageService.publishGroupMessage(GroupMessageChannel.APP, GroupMessageType.OPEN_PRIVATE_CHAT, groupId, query.getStatus());
groupMessageService.publishGroupMessage(GroupMessageChannel.ALL, GroupMessageType.OPEN_PRIVATE_CHAT, groupId, query.getStatus());
}
/**
@ -163,10 +183,37 @@ public class AdminGroupMessageService {
throw new BizException(ResponseStatus.ID_NOT_EXIST_ERROR);
}
GroupInfo group = query.toPrivatePO();
GroupInfo group = query.toShowMemberCountPO();
groupInfoMapper.updateById(group);
groupMessageService.publishGroupMessage(GroupMessageChannel.APP, GroupMessageType.SHOW_GROUP_MEMBER_COUNT, groupId, query.getStatus());
groupMessageService.publishGroupMessage(GroupMessageChannel.ALL, GroupMessageType.SHOW_GROUP_MEMBER_COUNT, groupId, query.getStatus());
}
public void setShowNickName(GroupMessageStatusQuery query, BackendUserVO backendUser) {
Integer groupId = query.getGroupId();
GroupInfo groupInfo = groupInfoMapper.selectById(groupId);
if (groupInfo == null) {
throw new BizException(ResponseStatus.ID_NOT_EXIST_ERROR);
}
GroupInfo group = query.toShowNickNamePO();
groupInfoMapper.updateById(group);
groupMessageService.publishGroupMessage(GroupMessageChannel.ALL, GroupMessageType.SHOW_FULL_NICKNAME, groupId, query.getStatus());
}
public void setFirstAudit(GroupMessageStatusQuery query, BackendUserVO backendUser) {
Integer groupId = query.getGroupId();
GroupInfo groupInfo = groupInfoMapper.selectById(groupId);
if (groupInfo == null) {
throw new BizException(ResponseStatus.ID_NOT_EXIST_ERROR);
}
GroupInfo group = query.toFirstAuditPO();
groupInfoMapper.updateById(group);
groupMessageService.publishGroupMessage(GroupMessageChannel.ALL, GroupMessageType.PRE_CHECK_SEND, groupId, query.getStatus());
}
}

View File

@ -1,28 +1,21 @@
package com.upchina.group.service.app;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hazelcast.map.IMap;
import com.upchina.common.config.cache.CacheKey;
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.result.ResponseStatus;
import com.upchina.common.service.CacheService;
import com.upchina.common.service.SensitiveWordService;
import com.upchina.common.util.TextUtil;
import com.upchina.common.vo.FrontUserVO;
import com.upchina.group.constant.GroupMessageChannel;
import com.upchina.group.constant.GroupMessageType;
import com.upchina.group.constant.GroupMessageUserType;
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.admin.AdminGroupMessageService;
import com.upchina.group.service.common.GroupCacheService;
import com.upchina.group.service.common.GroupCommonService;
import com.upchina.group.service.common.GroupMessageService;
@ -32,7 +25,10 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NavigableSet;
@Service
public class AppGroupMessageService {
@ -55,15 +51,6 @@ public class AppGroupMessageService {
@Resource
private SensitiveWordService sensitiveWordService;
@Resource
private AdminGroupMessageService adminGroupMessageService;
@Resource
private CacheService cacheService;
@Resource
private IMap<String, Object> groupCache;
public AppPager<GroupMessageVO> getMessageList(ListGroupMessageAppQuery query, FrontUserVO frontUser) {
Integer groupId = query.getGroupId();
Integer lastId = query.getLastId();
@ -79,7 +66,7 @@ public class AppGroupMessageService {
// TODO 验证权限
groupCommonService.validateUserPermission(userId, groupVO);
QueryGroupMessageType msgType = QueryGroupMessageType.fromValue(type);
NavigableSet<Integer> sortedSet = this.getMsgIdSet(groupId, userId, msgType);
NavigableSet<Integer> sortedSet = groupCacheService.getMessageIdSet(groupId, userId, msgType);
if (lastId != null && lastId != 0) {
sortedSet = sortedSet.tailSet(lastId, false);
}
@ -96,30 +83,6 @@ public class AppGroupMessageService {
return new AppPager<>(list, it.hasNext());
}
private NavigableSet<Integer> getMsgIdSet(Integer groupId, String userId, QueryGroupMessageType msgType) {
if (QueryGroupMessageType.CUSTOMER.equals(msgType)) {
throw new BizException(ResponseStatus.PARM_ERROR, "查询类型错误");
}
String cacheKey = CacheKey.GroupKey.GROUP_MESSAGE_LIST + msgType.value;
if (QueryGroupMessageType.PRIVATE.equals(msgType)) {
cacheKey += "|" + userId;
}
return cacheService.get(groupCache, cacheKey, () -> {
LambdaQueryWrapper<GroupMessage> wrapper = Wrappers.<GroupMessage>lambdaQuery()
.select(GroupMessage::getId)
.eq(GroupMessage::getGroupId, groupId)
.in(QueryGroupMessageType.ADVISOR.equals(msgType), GroupMessage::getUserType, GroupMessageUserType.ADVISOR.value, GroupMessageUserType.ASSISTANT.value)
.eq(QueryGroupMessageType.CUSTOMER.equals(msgType), GroupMessage::getUserType, GroupMessageUserType.CUSTOMER.value)
.eq(QueryGroupMessageType.SELECTED.equals(msgType), GroupMessage::getIsRecommend, IsOrNot.IS.value)
.eq(QueryGroupMessageType.PRIVATE.equals(msgType), GroupMessage::getPrivateUserId, userId);
List<Object> objList = groupMessageMapper.selectObjs(wrapper);
NavigableSet<Integer> set = new TreeSet<>(Comparator.reverseOrder());
objList.stream().map(obj -> (Integer) obj).forEach(set::add);
return set;
});
}
@Transactional(rollbackFor = Exception.class)
public GroupMessageVO sendMessage(SendGroupMessageAppQuery query, FrontUserVO frontUser) {
Integer groupId = query.getGroupId();
@ -128,22 +91,29 @@ public class AppGroupMessageService {
sensitiveWordService.check(content);
// 检查交易圈状态
if (!groupCommonService.checkGroupStatus(groupId)) {
throw new BizException(ResponseStatus.STATUS_ERROR, "交易圈未开启");
GroupVO groupVO = groupInfoService.getForApp(new OnlyIdQuery(groupId), null);
if (groupVO == null) {
throw new BizException(ResponseStatus.ID_NOT_EXIST_ERROR, "交易圈不存在");
}
if (!IsOrNot.IS.value.equals(groupVO.getInteractiveStatus())) {
throw new BizException(ResponseStatus.MESSAGE_PERMISSION_ERROR, "互动已关闭");
}
// 检查用户是否被禁言
if (groupCommonService.checkUserForbidden(frontUser.getUserId())) {
throw new BizException(ResponseStatus.COMMENT_BLACK_USER_ERROR, "您已被禁言");
}
// TODO 禁言check
// if (groupCommonService.checkUserForbidden(frontUser.getUserId())) {
// throw new BizException(ResponseStatus.COMMENT_BLACK_USER_ERROR, "您已被禁言");
// }
GroupMessage message = query.toPO(frontUser);
message.setContent(TextUtil.cleanUnsafeHtml(content));
groupMessageMapper.insert(message);
GroupMessageVO vo = new GroupMessageVO(message);
if (!IsOrNot.IS.value.equals(groupVO.getFirstAudit())) {
groupMessageService.publishGroupMessage(GroupMessageChannel.ALL, GroupMessageType.NORMAL, groupId, vo);
groupCacheService.addMessage(message);
}
return vo;
}

View File

@ -1,14 +1,31 @@
package com.upchina.group.service.common;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hazelcast.map.IMap;
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.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.GroupMessageMapper;
import com.upchina.group.mapper.GroupUserFlowMapper;
import com.upchina.group.vo.message.GroupMessageVO;
import com.upchina.video.entity.OnlineUser;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List;
import java.util.NavigableSet;
import java.util.TreeSet;
import java.util.function.Function;
import java.util.stream.Collectors;
@Service
public class GroupCacheService {
@ -19,16 +36,97 @@ public class GroupCacheService {
@Resource
private GroupMessageMapper groupMessageMapper;
@Resource
private GroupUserFlowMapper groupUserFlowMapper;
@Resource
private IMap<String, Object> groupCache;
public void clearMessageCache(Integer msgId, Integer groupId) {
if (msgId != null) {
groupCache.remove(CacheKey.GroupKey.GROUP_MESSAGE_DETAIL + msgId);
// 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<Integer> getMessageIdSet(Integer groupId, String userId, QueryGroupMessageType type) {
if (QueryGroupMessageType.CUSTOMER.equals(type)) {
throw new BizException(ResponseStatus.PARM_ERROR, "查询类型错误");
}
if (groupId != null) {
groupCache.remove(CacheKey.GroupKey.GROUP_MESSAGE_LIST + groupId);
String cacheKey = buildMessageIdSetKey(userId, type);
return cacheService.get(groupCache, cacheKey, () -> {
LambdaQueryWrapper<GroupMessage> wrapper = Wrappers.<GroupMessage>lambdaQuery()
.select(GroupMessage::getId)
.eq(GroupMessage::getGroupId, groupId)
.in(QueryGroupMessageType.ADVISOR.equals(type), GroupMessage::getUserType, GroupMessageUserType.ADVISOR.value, GroupMessageUserType.ASSISTANT.value)
.eq(QueryGroupMessageType.CUSTOMER.equals(type), GroupMessage::getUserType, GroupMessageUserType.CUSTOMER.value)
.eq(QueryGroupMessageType.SELECTED.equals(type), GroupMessage::getIsRecommend, IsOrNot.IS.value)
.eq(QueryGroupMessageType.PRIVATE.equals(type), GroupMessage::getPrivateUserId, userId);
List<Object> objList = groupMessageMapper.selectObjs(wrapper);
NavigableSet<Integer> set = new TreeSet<>(Comparator.reverseOrder());
objList.stream().map(obj -> (Integer) obj).forEach(set::add);
return set;
});
}
public void removeMessage(GroupMessage message) {
String privateUserId = message.getPrivateUserId();
Integer groupId = message.getGroupId();
Integer messageId = message.getId();
Integer interactiveType = message.getInteractiveType();
Integer userType = message.getUserType();
Integer isRecommend = message.getIsRecommend();
if (GroupInteractiveType.GROUP.value.equals(interactiveType)) {
removeMessage(groupId, null, QueryGroupMessageType.ALL, messageId);
if (GroupMessageUserType.ADVISOR.value.equals(userType)) {
removeMessage(groupId, null, QueryGroupMessageType.ADVISOR, messageId);
} else if (GroupMessageUserType.CUSTOMER.value.equals(userType)) {
removeMessage(groupId, null, QueryGroupMessageType.CUSTOMER, messageId);
}
if (IsOrNot.IS.value.equals(isRecommend)) {
removeMessage(groupId, null, QueryGroupMessageType.SELECTED, messageId);
}
} else if (GroupInteractiveType.PRIVATE.value.equals(interactiveType)) {
removeMessage(groupId, privateUserId, QueryGroupMessageType.PRIVATE, messageId);
}
}
private void removeMessage(Integer groupId, String userId, QueryGroupMessageType type, Integer messageId) {
NavigableSet<Integer> set = getMessageIdSet(groupId, userId, type);
set.remove(messageId);
String cacheKey = buildMessageIdSetKey(userId, type);
groupCache.put(cacheKey, set);
}
public void addMessage(GroupMessage message) {
String privateUserId = message.getPrivateUserId();
Integer groupId = message.getGroupId();
Integer messageId = message.getId();
Integer interactiveType = message.getInteractiveType();
Integer userType = message.getUserType();
Integer isRecommend = message.getIsRecommend();
if (GroupInteractiveType.GROUP.value.equals(interactiveType)) {
addMessage(groupId, null, QueryGroupMessageType.ALL, messageId);
if (GroupMessageUserType.ADVISOR.value.equals(userType)) {
addMessage(groupId, null, QueryGroupMessageType.ADVISOR, messageId);
} else if (GroupMessageUserType.CUSTOMER.value.equals(userType)) {
addMessage(groupId, null, QueryGroupMessageType.CUSTOMER, messageId);
}
if (IsOrNot.IS.value.equals(isRecommend)) {
addMessage(groupId, null, QueryGroupMessageType.SELECTED, messageId);
}
} else if (GroupInteractiveType.PRIVATE.value.equals(interactiveType)) {
addMessage(groupId, privateUserId, QueryGroupMessageType.PRIVATE, messageId);
}
}
private void addMessage(Integer groupId, String userId, QueryGroupMessageType type, Integer messageId) {
NavigableSet<Integer> set = getMessageIdSet(groupId, userId, type);
set.add(messageId);
String cacheKey = buildMessageIdSetKey(userId, type);
groupCache.put(cacheKey, set);
}
public GroupMessageVO getMessage(Integer messageId) {
@ -41,4 +139,24 @@ public class GroupCacheService {
return new GroupMessageVO(message);
});
}
public IMap<String, OnlineUser> getTotalOnlineMap(Integer groupId) {
return cacheService.getMap(CacheKey.GroupKey.USER_TOTAL_ONLINE + groupId, () -> {
synchronized (GroupCacheService.class) {
List<OnlineUser> hisList = groupUserFlowMapper.loadHis(Wrappers.<GroupUserFlow>lambdaQuery()
.eq(GroupUserFlow::getGroupId, groupId)
.groupBy(GroupUserFlow::getUserId, GroupUserFlow::getSessionId));
return hisList.stream()
.collect(Collectors.toMap(h -> h.getUserId() + "-" + h.getSessionId(), Function.identity()));
}
});
}
private static String buildMessageIdSetKey(String userId, QueryGroupMessageType type) {
String cacheKey = CacheKey.GroupKey.GROUP_MESSAGE_LIST + type.value;
if (QueryGroupMessageType.PRIVATE.equals(type)) {
cacheKey += "|" + userId;
}
return cacheKey;
}
}

View File

@ -1,7 +1,5 @@
package com.upchina.group.service.common;
import com.upchina.group.constant.GroupInfoStatus;
import com.upchina.group.entity.GroupInfo;
import com.upchina.group.mapper.GroupInfoMapper;
import com.upchina.group.vo.GroupVO;
import org.springframework.stereotype.Service;
@ -15,11 +13,6 @@ public class GroupCommonService {
@Resource
private GroupInfoMapper groupInfoMapper;
public boolean checkGroupStatus(Integer groupId) {
GroupInfo group = groupInfoMapper.selectById(groupId);
return GroupInfoStatus.AUDITED.value.equals(group.getStatus());
}
public boolean checkUserForbidden(String userId) {
// 实现用户禁言检查逻辑
return false;

View File

@ -3,28 +3,33 @@ package com.upchina.group.service.common;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.topic.ITopic;
import com.upchina.common.config.cache.CacheKey;
import com.upchina.common.vo.FrontUserVO;
import com.upchina.group.constant.GroupMessageChannel;
import com.upchina.group.constant.GroupMessageType;
import com.upchina.group.mapper.GroupMessageMapper;
import com.upchina.group.vo.message.GroupWsMessageVO;
import com.upchina.video.entity.OnlineUser;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
@Service
public class GroupMessageService {
@Resource
private GroupMessageMapper groupMessageMapper;
@Resource
private SimpMessagingTemplate simpMessagingTemplate;
@Resource
private HazelcastInstance hazelcastInstance;
private final Map<Integer, Long> lastEnterMessageTimeMap = new HashMap<>();
// 进入消息频率控制(本节点)
private final long enterMessageInterval = 2000;
public ITopic<GroupWsMessageVO<?>> adminGroupTopic = null;
public ITopic<GroupWsMessageVO<?>> adminPrivateTopic = null;
@ -124,4 +129,18 @@ public class GroupMessageService {
}
}
public void memberNotify(Integer groupId, OnlineUser onlineUser) {
publishGroupMessage(GroupMessageChannel.ADMIN, GroupMessageType.USER_ONLINE_OFFLINE, groupId, onlineUser);
}
public void publishEnterMessage(Integer groupId, FrontUserVO frontUser) {
Long lastEnterMessageTime = lastEnterMessageTimeMap.get(groupId);
long now = System.currentTimeMillis();
if (lastEnterMessageTime != null && now - lastEnterMessageTime < enterMessageInterval) {
// 频率控制,如果周期内推送过就不推送该次消息
return;
}
publishGroupMessage(GroupMessageChannel.ALL, GroupMessageType.ENTER_GROUP, groupId, frontUser.getUserName());
lastEnterMessageTimeMap.put(groupId, now);
}
}

View File

@ -6,14 +6,10 @@ import com.upchina.course.vo.PageVO;
import com.upchina.group.entity.GroupInfo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@ApiModel("交易圈详情")
public class GroupVO {
@ -41,9 +37,21 @@ public class GroupVO {
@ApiModelProperty("欢迎语")
private String welcomeMessage;
@ApiModelProperty("私聊状态")
@ApiModelProperty("互动状态 1:开启 2:关闭")
private Integer interactiveStatus;
@ApiModelProperty("私聊状态 1:开启 2:关闭")
private Integer privateChatStatus;
@ApiModelProperty("显示人数 1:开启 2:关闭")
private Integer showMemberCount;
@ApiModelProperty("显示昵称 1:开启 2:关闭")
private Integer showNickName;
@ApiModelProperty("先审后发 1:开启 2:关闭")
private Integer firstAudit;
@ApiModelProperty("落地页")
private PageVO page;
@ -104,6 +112,8 @@ public class GroupVO {
@ApiModelProperty("权限结果")
private AuthResultVO authResultVo;
public GroupVO() {}
public GroupVO(GroupInfo groupInfo, AdvisorBasic advisor, String createUserName, String auditUserName, PageVO page) {
this.id = groupInfo.getId();
this.advisorId = groupInfo.getAdvisorId();
@ -114,6 +124,10 @@ public class GroupVO {
this.detail = groupInfo.getDetail();
this.welcomeMessage = groupInfo.getWelcomeMessage();
this.privateChatStatus = groupInfo.getPrivateChatStatus();
this.interactiveStatus = groupInfo.getInteractiveStatus();
this.showMemberCount = groupInfo.getShowMemberCount();
this.showNickName = groupInfo.getShowNickName();
this.firstAudit = groupInfo.getFirstAudit();
this.page = page;
this.originalPrice = groupInfo.getOriginalPrice();
this.activityPrice = groupInfo.getActivityPrice();
@ -134,4 +148,268 @@ public class GroupVO {
this.mainPageText = groupInfo.getMainPageText();
this.wechatWorkId = groupInfo.getWechatWorkId();
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getAdvisorId() {
return advisorId;
}
public void setAdvisorId(Integer advisorId) {
this.advisorId = advisorId;
}
public AdvisorBasic getAdvisor() {
return advisor;
}
public void setAdvisor(AdvisorBasic advisor) {
this.advisor = advisor;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public String getApplicableUser() {
return applicableUser;
}
public void setApplicableUser(String applicableUser) {
this.applicableUser = applicableUser;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
public String getWelcomeMessage() {
return welcomeMessage;
}
public void setWelcomeMessage(String welcomeMessage) {
this.welcomeMessage = welcomeMessage;
}
public Integer getInteractiveStatus() {
return interactiveStatus;
}
public void setInteractiveStatus(Integer interactiveStatus) {
this.interactiveStatus = interactiveStatus;
}
public Integer getPrivateChatStatus() {
return privateChatStatus;
}
public void setPrivateChatStatus(Integer privateChatStatus) {
this.privateChatStatus = privateChatStatus;
}
public Integer getShowMemberCount() {
return showMemberCount;
}
public void setShowMemberCount(Integer showMemberCount) {
this.showMemberCount = showMemberCount;
}
public Integer getShowNickName() {
return showNickName;
}
public void setShowNickName(Integer showNickName) {
this.showNickName = showNickName;
}
public Integer getFirstAudit() {
return firstAudit;
}
public void setFirstAudit(Integer firstAudit) {
this.firstAudit = firstAudit;
}
public PageVO getPage() {
return page;
}
public void setPage(PageVO page) {
this.page = page;
}
public BigDecimal getOriginalPrice() {
return originalPrice;
}
public void setOriginalPrice(BigDecimal originalPrice) {
this.originalPrice = originalPrice;
}
public BigDecimal getActivityPrice() {
return activityPrice;
}
public void setActivityPrice(BigDecimal activityPrice) {
this.activityPrice = activityPrice;
}
public String getPaymentUrl() {
return paymentUrl;
}
public void setPaymentUrl(String paymentUrl) {
this.paymentUrl = paymentUrl;
}
public String getAuthorityId() {
return authorityId;
}
public void setAuthorityId(String authorityId) {
this.authorityId = authorityId;
}
public Integer getMemberLimit() {
return memberLimit;
}
public void setMemberLimit(Integer memberLimit) {
this.memberLimit = memberLimit;
}
public String getCoverImage() {
return coverImage;
}
public void setCoverImage(String coverImage) {
this.coverImage = coverImage;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
public Integer getRiskLevel() {
return riskLevel;
}
public void setRiskLevel(Integer riskLevel) {
this.riskLevel = riskLevel;
}
public LocalDateTime getCreateTime() {
return createTime;
}
public void setCreateTime(LocalDateTime createTime) {
this.createTime = createTime;
}
public LocalDateTime getUpdateTime() {
return updateTime;
}
public void setUpdateTime(LocalDateTime updateTime) {
this.updateTime = updateTime;
}
public LocalDateTime getAuditTime() {
return auditTime;
}
public void setAuditTime(LocalDateTime auditTime) {
this.auditTime = auditTime;
}
public String getCreateUserName() {
return createUserName;
}
public void setCreateUserName(String createUserName) {
this.createUserName = createUserName;
}
public String getAuditUserName() {
return auditUserName;
}
public void setAuditUserName(String auditUserName) {
this.auditUserName = auditUserName;
}
public Integer getIsRecommend() {
return isRecommend;
}
public void setIsRecommend(Integer isRecommend) {
this.isRecommend = isRecommend;
}
public Integer getIsDisplay() {
return isDisplay;
}
public void setIsDisplay(Integer isDisplay) {
this.isDisplay = isDisplay;
}
public String getMainPageText() {
return mainPageText;
}
public void setMainPageText(String mainPageText) {
this.mainPageText = mainPageText;
}
public Integer getWechatWorkId() {
return wechatWorkId;
}
public void setWechatWorkId(Integer wechatWorkId) {
this.wechatWorkId = wechatWorkId;
}
public AuthResultVO getAuthResultVo() {
return authResultVo;
}
public void setAuthResultVo(AuthResultVO authResultVo) {
this.authResultVo = authResultVo;
}
}

View File

@ -9,8 +9,11 @@ public class OnlineUser implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("视频id")
private Integer videoId;
@ApiModelProperty("产品类型 3:直播 41:交易圈")
private Integer productType;
@ApiModelProperty("产品ID")
private Integer productId;
@ApiModelProperty("用户id")
private String userId;
@ -39,8 +42,9 @@ public class OnlineUser implements Serializable {
public OnlineUser() {
}
public OnlineUser(Integer videoId, String userId, String userName, String img, String sessionId, Integer isOnline, Integer isPlay, LocalDateTime createTime) {
this.videoId = videoId;
public OnlineUser(Integer productType, Integer productId, String userId, String userName, String img, String sessionId, Integer isOnline, Integer isPlay, LocalDateTime createTime) {
this.productType = productType;
this.productId = productId;
this.userId = userId;
this.userName = userName;
this.img = img;
@ -50,6 +54,30 @@ public class OnlineUser implements Serializable {
this.createTime = createTime;
}
public Integer getProductType() {
return productType;
}
public void setProductType(Integer productType) {
this.productType = productType;
}
public Integer getProductId() {
return productId;
}
public void setProductId(Integer productId) {
this.productId = productId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
@ -66,22 +94,6 @@ public class OnlineUser implements Serializable {
this.img = img;
}
public Integer getVideoId() {
return videoId;
}
public void setVideoId(Integer videoId) {
this.videoId = videoId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getSessionId() {
return sessionId;
}

View File

@ -563,7 +563,10 @@ public class AdminVideoInteractionService {
@Transactional(rollbackFor = Exception.class)
public void saveVideoUserDataToDB() {
LocalDateTime now = LocalDateTime.now();
List<VideoLive> videoLives = videoLiveMapper.selectList(Wrappers.emptyWrapper());
LambdaQueryWrapper<VideoLive> wrapper = Wrappers.<VideoLive>lambdaQuery()
.select(VideoLive::getId, VideoLive::getLiveStatus)
.ge(VideoLive::getStartTime, now.plusDays(-7));
List<VideoLive> videoLives = videoLiveMapper.selectList(wrapper);
if (CollUtil.isEmpty(videoLives)) {
return;
}

View File

@ -13,7 +13,7 @@ file:
hazelcast:
members: 127.0.0.1:5709 #缓存集群的ip端口号
serverPort: 5709 #自己作为缓存服务器监听的端口号
scheduledEnable: false
scheduledEnable: true
cron:
saveVideoCount: "10 * * * * ?" #从cache刷新视频播放量到DB 每分钟的第10s执行
refreshTranscodeStatus: "2 3/5 * * * ?" #从腾讯云拉取录播上传视频信息更新到DB

View File

@ -145,7 +145,6 @@ class AppGroupMessageServiceTest {
// 设置模拟行为
doNothing().when(sensitiveWordService).check(anyString());
when(groupCommonService.checkGroupStatus(anyInt())).thenReturn(true);
when(groupCommonService.checkUserForbidden(anyString())).thenReturn(false);
when(groupMessageMapper.insert(any(GroupMessage.class))).thenReturn(1);
@ -171,7 +170,6 @@ class AppGroupMessageServiceTest {
// 设置模拟行为
doNothing().when(sensitiveWordService).check(anyString());
when(groupCommonService.checkGroupStatus(anyInt())).thenReturn(false);
// 执行测试并验证异常
assertThrows(BizException.class, () ->
@ -188,7 +186,6 @@ class AppGroupMessageServiceTest {
// 设置模拟行为
doNothing().when(sensitiveWordService).check(anyString());
when(groupCommonService.checkGroupStatus(anyInt())).thenReturn(true);
when(groupCommonService.checkUserForbidden(anyString())).thenReturn(true);
// 执行测试并验证异常