V13
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
package com.ruoyi.cai.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.ruoyi.common.constant.DateConstant;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 每日发言统计对象 cai_anchor_im_count_day
|
||||
*
|
||||
* @author 777
|
||||
* @date 2025-08-19
|
||||
*/
|
||||
@Data
|
||||
@TableName("cai_anchor_im_count_day")
|
||||
public class AnchorImCountDay implements Serializable {
|
||||
|
||||
private static final long serialVersionUID=1L;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private String id;
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long userId;
|
||||
/**
|
||||
* 时间
|
||||
*/
|
||||
@DateTimeFormat(pattern = DateConstant.PATTERN_DATE)
|
||||
@JsonFormat(pattern = DateConstant.PATTERN_DATE)
|
||||
private LocalDate countDate;
|
||||
/**
|
||||
* 数量
|
||||
*/
|
||||
private Long imCount;
|
||||
/**
|
||||
* 刷新时间
|
||||
*/
|
||||
private LocalDateTime refreshTime;
|
||||
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -25,6 +25,9 @@ public class UserCount implements Serializable {
|
||||
*/
|
||||
@TableId(value = "user_id",type = IdType.INPUT)
|
||||
private Long userId;
|
||||
|
||||
private Long imCount;
|
||||
private LocalDateTime imRefreshTime;
|
||||
/**
|
||||
* 新增粉丝数
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.ruoyi.cai.dto.admin.vo;
|
||||
|
||||
import com.ruoyi.cai.domain.AnchorImCountDay;
|
||||
import com.ruoyi.common.annotation.Sensitive;
|
||||
import com.ruoyi.common.enums.SensitiveStrategy;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class AnchorImCountDayAdminVO extends AnchorImCountDay {
|
||||
/**
|
||||
* 用户号/ID号
|
||||
*/
|
||||
private String usercode;
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
private String nickname;
|
||||
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
@Sensitive(strategy = SensitiveStrategy.PHONE)
|
||||
private String mobile;
|
||||
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String avatar;
|
||||
/**
|
||||
* 性别
|
||||
*/
|
||||
private Integer gender;
|
||||
private Integer age;
|
||||
private Boolean imSpeck;
|
||||
private Boolean enableIm;
|
||||
private Integer status;
|
||||
}
|
||||
@@ -33,4 +33,6 @@ public class UserCountAdminVo extends UserCount {
|
||||
private Integer age;
|
||||
private Integer isAnchor;
|
||||
private Integer status;
|
||||
private Boolean imSpeck;
|
||||
private Boolean enableIm;
|
||||
}
|
||||
|
||||
@@ -122,7 +122,8 @@ public enum SystemConfigEnum {
|
||||
IPV6_FILTER("0", "是否开启IPV6请求拦截",SystemConfigGroupEnum.SYSTEM, new BooleanSystemConfigCheck()),
|
||||
IPV6_FILTER_PATH("/api/auth/login", "IPV6拦截路由配置(逗号分隔)",SystemConfigGroupEnum.SYSTEM, new BooleanSystemConfigCheck(),"textarea"),
|
||||
VIP_PRIVATE_PLUS("0", "开启VIP隐私模式增强模式",SystemConfigGroupEnum.SYSTEM,new BooleanSystemConfigCheck()),
|
||||
OPEN_USER_CHAT_COUNT("0", "开启用户主动消息统计",SystemConfigGroupEnum.SYSTEM,new BooleanSystemConfigCheck()),
|
||||
OPEN_ANCHOR_CHAT_COUNT("0", "开启主播主动消息统计",SystemConfigGroupEnum.SYSTEM,new BooleanSystemConfigCheck()),
|
||||
// 4-recordId拦截 5-recordId加强拦截 6-性别拦截 7-vip加强拦截
|
||||
IM_FILTER_PLUS("0", "IM拦截配置(勿动,开发配置)",SystemConfigGroupEnum.SYSTEM),
|
||||
COS_DOMAIN("http://ap-shanghai.myqcloud.com/", "文件系统域名前缀",SystemConfigGroupEnum.SYSTEM),
|
||||
PAY_LIMIT("200000", "原生支付的阈值(元)",SystemConfigGroupEnum.SYSTEM, new NumberSystemConfigCheck()),
|
||||
|
||||
@@ -60,6 +60,8 @@ public class ImService {
|
||||
private UserChatFilterService userChatFilterService;
|
||||
@Autowired
|
||||
private SystemConfigManager systemConfigManager;
|
||||
@Autowired
|
||||
private AnchorImCountDayService anchorImCountDayService;
|
||||
|
||||
public ImResp sendMessage(Long fromUserId, ImMessageDTO message) {
|
||||
ChatTypeEnum typeEnum = ChatTypeEnum.getByType(message.getType());
|
||||
@@ -172,6 +174,10 @@ public class ImService {
|
||||
if(filter == 1){
|
||||
userChatFilterService.saveFilter(fromUser, toUser, message.getContent(),content);
|
||||
}
|
||||
boolean bool = systemConfigManager.getSystemConfigOfBool(SystemConfigEnum.OPEN_ANCHOR_CHAT_COUNT);
|
||||
if(bool){
|
||||
anchorImCountDayService.incCount(fromUserId);
|
||||
}
|
||||
resp.setRecordId(record.getId());
|
||||
resp.setFilter(filter);
|
||||
resp.setContent(content);
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.ruoyi.cai.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.ruoyi.cai.domain.AnchorImCountDay;
|
||||
import com.ruoyi.cai.dto.admin.vo.AnchorImCountDayAdminVO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* 每日发言统计Mapper接口
|
||||
*
|
||||
* @author 777
|
||||
* @date 2025-08-19
|
||||
*/
|
||||
public interface AnchorImCountDayMapper extends BaseMapper<AnchorImCountDay> {
|
||||
|
||||
IPage<AnchorImCountDayAdminVO> pageAdmin(@Param("build") Page<Object> build, @Param("bo") AnchorImCountDayAdminVO bo);
|
||||
|
||||
IPage<AnchorImCountDay> totalUserId(IPage<AnchorImCountDay> page);
|
||||
}
|
||||
@@ -27,4 +27,5 @@ public interface UserCountMapper extends BaseMapper<UserCount> {
|
||||
void resetNewVisitorIncs(Long userId);
|
||||
|
||||
Page<UserCountAdminVo> pageAdmin(@Param("build") Page<Object> build, @Param("bo") UserCountAdminVo bo);
|
||||
Page<UserCountAdminVo> pageImCount(@Param("build") Page<Object> build, @Param("bo") UserCountAdminVo bo);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.ruoyi.cai.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.ruoyi.cai.domain.AnchorImCountDay;
|
||||
import com.ruoyi.cai.dto.admin.vo.AnchorImCountDayAdminVO;
|
||||
import com.ruoyi.common.core.domain.PageQuery;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* 每日发言统计Service接口
|
||||
*
|
||||
* @author 777
|
||||
* @date 2025-08-19
|
||||
*/
|
||||
public interface AnchorImCountDayService extends IService<AnchorImCountDay> {
|
||||
|
||||
void totalUserCount();
|
||||
|
||||
IPage<AnchorImCountDayAdminVO> pageAdmin(AnchorImCountDayAdminVO bo, PageQuery pageQuery);
|
||||
|
||||
void incCount(Long userId);
|
||||
|
||||
void refreshCount(LocalDate localDate);
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package com.ruoyi.cai.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.ruoyi.cai.domain.AnchorImCountDay;
|
||||
import com.ruoyi.cai.domain.UserCount;
|
||||
import com.ruoyi.cai.dto.admin.vo.AnchorImCountDayAdminVO;
|
||||
import com.ruoyi.cai.mapper.AnchorImCountDayMapper;
|
||||
import com.ruoyi.cai.service.AnchorImCountDayService;
|
||||
import com.ruoyi.cai.service.UserCountService;
|
||||
import com.ruoyi.common.core.domain.PageQuery;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.redisson.api.RMap;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 每日发言统计Service业务层处理
|
||||
*
|
||||
* @author 777
|
||||
* @date 2025-08-19
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class AnchorImCountDayServiceImpl extends ServiceImpl<AnchorImCountDayMapper, AnchorImCountDay> implements AnchorImCountDayService {
|
||||
@Autowired
|
||||
private RedissonClient redissonClient;
|
||||
@Autowired
|
||||
private UserCountService userCountService;
|
||||
|
||||
@Override
|
||||
public void totalUserCount() {
|
||||
IPage<AnchorImCountDay> page = new Page<>();
|
||||
page.setSize(1000);
|
||||
int i = 0;
|
||||
while (true){
|
||||
i++;
|
||||
if(i > 10000){
|
||||
break;
|
||||
}
|
||||
page.setCurrent(i);
|
||||
IPage<AnchorImCountDay> totalUserId = baseMapper.totalUserId(page);
|
||||
List<AnchorImCountDay> records = totalUserId.getRecords();
|
||||
for (AnchorImCountDay record : records) {
|
||||
userCountService.update(Wrappers.<UserCount>lambdaUpdate()
|
||||
.eq(UserCount::getUserId, record.getUserId())
|
||||
.set(UserCount::getImCount, record.getImCount())
|
||||
.set(UserCount::getImRefreshTime, LocalDateTime.now()));
|
||||
}
|
||||
if(CollectionUtil.isEmpty(records)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public IPage<AnchorImCountDayAdminVO> pageAdmin(AnchorImCountDayAdminVO bo, PageQuery pageQuery) {
|
||||
return baseMapper.pageAdmin(pageQuery.build(),bo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incCount(Long userId){
|
||||
try {
|
||||
String redisKey = getRedisKey(LocalDate.now());
|
||||
RMap<Long, Long> map = redissonClient.getMap(redisKey);
|
||||
Long newScore = map.addAndGet(userId, 1);
|
||||
if(newScore == 1){
|
||||
map.expire(5, TimeUnit.DAYS);
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("主播自增im发言失败",e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshCount(LocalDate localDate){
|
||||
String redisKey = getRedisKey(localDate);
|
||||
RMap<Long, Long> map = redissonClient.getMap(redisKey);
|
||||
Map<Long, Long> longMap = map.readAllMap();
|
||||
for (Map.Entry<Long, Long> entry : longMap.entrySet()) {
|
||||
Long userId = entry.getKey();
|
||||
Long imCount = entry.getValue();
|
||||
AnchorImCountDay one = this.getOne(Wrappers.lambdaQuery(AnchorImCountDay.class)
|
||||
.eq(AnchorImCountDay::getCountDate, localDate)
|
||||
.eq(AnchorImCountDay::getUserId, userId));
|
||||
if(one != null){
|
||||
this.update(Wrappers.lambdaUpdate(AnchorImCountDay.class)
|
||||
.eq(AnchorImCountDay::getId, one.getId())
|
||||
.set(AnchorImCountDay::getImCount, imCount));
|
||||
}else{
|
||||
one = new AnchorImCountDay();
|
||||
one.setImCount(imCount);
|
||||
one.setUserId(userId);
|
||||
one.setRefreshTime(LocalDateTime.now());
|
||||
this.save(one);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getRedisKey(LocalDate localDate){
|
||||
String now = localDate.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
|
||||
return String.format("cai:anchorImCountDay:%s",now);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user