Merge branch 'master' of https://gitlink.org.cn/Gitlink/microservices into ccf_tmp
This commit is contained in:
commit
73b42af29f
|
|
@ -249,6 +249,18 @@ public class CacheConstants {
|
|||
return ZONE_PROJECT_SORT_BY_SCORE + "*:" + zoneId + ":*";
|
||||
}
|
||||
|
||||
/**
|
||||
* 专区统计数据缓存前缀
|
||||
*/
|
||||
private final static String ZONE_STATISTICS_KEY = "zone:statistics:";
|
||||
|
||||
/**
|
||||
* 获取专区统计数据缓存key
|
||||
*/
|
||||
public static String getZoneStatisticsKey(Long zoneId) {
|
||||
return ZONE_STATISTICS_KEY + zoneId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件打包是否完成(0:代表未完成;1:代表已完成;-1:代表打包失败,需要重新打包)
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -237,6 +237,14 @@ public interface IZoneDetailService {
|
|||
|
||||
ZoneStatisticsVo getZoneStatistics(Long zoneId);
|
||||
|
||||
/**
|
||||
* 计算专区统计数据(内部方法,用于定时任务调用)
|
||||
*
|
||||
* @param zoneId 专区ID
|
||||
* @return 统计数据
|
||||
*/
|
||||
ZoneStatisticsVo calculateZoneStatistics(Long zoneId);
|
||||
|
||||
/**
|
||||
* 判断专区是否为积分专区
|
||||
*
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ import com.microservices.zone.resource.mapper.ZoneResourceTypeMapper;
|
|||
import com.microservices.zone.specialProject.domain.ZoneSpecialProject;
|
||||
import com.microservices.zone.specialProject.service.IZoneSpecialProjectService;
|
||||
import com.microservices.zone.utils.ZoneConstants;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
|
|
@ -67,6 +68,7 @@ import java.time.LocalDate;
|
|||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
|
|
@ -76,6 +78,7 @@ import java.util.stream.Collectors;
|
|||
* @date 2023-05-09
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class ZoneDetailServiceImpl implements IZoneDetailService {
|
||||
@Autowired
|
||||
private ZoneDetailMapper zoneDetailMapper;
|
||||
|
|
@ -224,13 +227,13 @@ public class ZoneDetailServiceImpl implements IZoneDetailService {
|
|||
Date[] lastWeek = getLastWeek();
|
||||
//专区文章数统计
|
||||
ZoneDetailDataVo articlesGroupByKey = zoneDetailMapper
|
||||
.countArticlesGroupByKey(lastWeek[0], lastWeek[1], zoneDetail.getKey());
|
||||
.countArticlesGroupByKey(lastWeek[0],lastWeek[1],zoneDetail.getKey()) ;
|
||||
if (articlesGroupByKey != null) {
|
||||
zoneDetailDataVo.setWeekArticles(articlesGroupByKey.getWeekArticles());
|
||||
}
|
||||
//专区浏览数据统计
|
||||
ZoneDetailDataVo puVsGroupByKey = zoneDetailMapper
|
||||
.countPUVsGroupByKey(lastWeek[0], lastWeek[1], zoneDetail.getKey());
|
||||
.countPUVsGroupByKey(lastWeek[0],lastWeek[1],zoneDetail.getKey()) ;
|
||||
if (puVsGroupByKey != null) {
|
||||
zoneDetailDataVo.setWeekPV(puVsGroupByKey.getWeekPV());
|
||||
zoneDetailDataVo.setWeekUV(puVsGroupByKey.getWeekUV());
|
||||
|
|
@ -917,17 +920,32 @@ public class ZoneDetailServiceImpl implements IZoneDetailService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ZoneStatisticsVo getZoneStatistics(Long zoneId) {
|
||||
public ZoneStatisticsVo calculateZoneStatistics(Long zoneId) {
|
||||
ZoneStatisticsVo zoneStatisticsVo = new ZoneStatisticsVo();
|
||||
|
||||
ZoneDetail zoneDetail = zoneDetailMapper.selectZoneDetailById(zoneId);
|
||||
Set<String> usernameSet = new HashSet<>();
|
||||
// 获取专区会员数
|
||||
ZoneMember zoneMemberSearch = new ZoneMember();
|
||||
zoneMemberSearch.setZoneId(zoneId);
|
||||
zoneMemberSearch.setIsAudit(ZoneConstants.MEMBER_AUDIT_PASS);
|
||||
Integer zoneMemberCount = zoneMemberMapper.selectCountByZoneId(zoneMemberSearch);
|
||||
ZoneMemberSearchVo zoneMemberSearchVo = new ZoneMemberSearchVo();
|
||||
zoneMemberSearchVo.setZoneId(zoneId);
|
||||
List<ZoneMember> zoneMemberList = zoneMemberMapper.selectZoneMemberList(zoneMemberSearchVo);
|
||||
zoneMemberList.forEach(x -> {
|
||||
if (x.getSysUser() != null) {
|
||||
usernameSet.add(x.getSysUser().getUserName());
|
||||
}
|
||||
});
|
||||
|
||||
// 获取专区内用户列表
|
||||
GenericsTableDataInfo<SysUserDeptRole> userTable = FeignUtils.getReturnData(
|
||||
remoteUserService.searchUserIdentifierListByDept(zoneDetail.getDeptId(), null, null, null, SecurityConstants.INNER)
|
||||
);
|
||||
if (userTable != null && userTable.getTotal() > 0) {
|
||||
userTable.getRows().forEach(x -> {
|
||||
if (x.getSysUser() != null) {
|
||||
usernameSet.add(x.getSysUser().getUserName());
|
||||
}
|
||||
});
|
||||
}
|
||||
// 获取仓库贡献者数量
|
||||
ZoneProjectSearchVo zoneProjectSearchVo = new ZoneProjectSearchVo();
|
||||
zoneProjectSearchVo.setZoneId(zoneId);
|
||||
|
|
@ -948,7 +966,7 @@ public class ZoneDetailServiceImpl implements IZoneDetailService {
|
|||
}
|
||||
}
|
||||
}
|
||||
zoneStatisticsVo.setCommunityUserCount((long) usernameSet.size() + zoneMemberCount);
|
||||
zoneStatisticsVo.setCommunityUserCount((long) usernameSet.size());
|
||||
Long cmsDocCount = FeignUtils.getReturnData(remoteCmsService.getCmsCountByDeptId(zoneDetail.getDeptId(), SecurityConstants.INNER));
|
||||
zoneStatisticsVo.setCmsDocCount(cmsDocCount == null ? 0L : cmsDocCount);
|
||||
Long cmsDocVisits = FeignUtils.getReturnData(remoteCmsService.getCmsDocVisitsByDeptId(zoneDetail.getDeptId(), SecurityConstants.INNER));
|
||||
|
|
@ -956,7 +974,8 @@ public class ZoneDetailServiceImpl implements IZoneDetailService {
|
|||
|
||||
ZoneResource zoneResource = new ZoneResource();
|
||||
zoneResource.setZoneId(zoneId);
|
||||
zoneStatisticsVo.setResourceCount(Long.valueOf(zoneResourceMapper.selectZoneResourceCount(zoneResource)));
|
||||
List<ZoneResource> zoneResourceList = zoneResourceMapper.selectZoneResourceList(zoneResource);
|
||||
zoneStatisticsVo.setResourceCount((long) zoneResourceList.size());
|
||||
|
||||
ZoneSpecialProject zoneSpecialProject = new ZoneSpecialProject();
|
||||
zoneSpecialProject.setZoneId(zoneId);
|
||||
|
|
@ -966,6 +985,35 @@ public class ZoneDetailServiceImpl implements IZoneDetailService {
|
|||
return zoneStatisticsVo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ZoneStatisticsVo getZoneStatistics(Long zoneId) {
|
||||
String cacheKey = CacheConstants.getZoneStatisticsKey(zoneId);
|
||||
|
||||
try {
|
||||
// 1. 尝试从Redis缓存获取
|
||||
ZoneStatisticsVo cachedStatistics = redisService.getCacheObject(cacheKey);
|
||||
if (cachedStatistics != null) {
|
||||
log.debug("专区[{}]统计数据来自缓存", zoneId);
|
||||
return cachedStatistics;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("专区[{}]统计数据缓存读取失败,执行降级逻辑", zoneId, e);
|
||||
}
|
||||
|
||||
// 2. 缓存异常或未命中,执行实时计算
|
||||
log.info("专区[{}]统计数据缓存未命中,执行实时计算", zoneId);
|
||||
ZoneStatisticsVo statistics = calculateZoneStatistics(zoneId);
|
||||
|
||||
// 3. 尝试缓存计算结果(失败不影响主流程)
|
||||
try {
|
||||
redisService.setCacheObject(cacheKey, statistics, 7200L, TimeUnit.SECONDS);
|
||||
} catch (Exception e) {
|
||||
log.warn("专区[{}]统计数据缓存写入失败", zoneId, e);
|
||||
}
|
||||
|
||||
return statistics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPointsZone(Long zoneId) {
|
||||
ZoneDetail zoneDetail = zoneDetailMapper.selectZoneDetailById(zoneId);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
package com.microservices.zone.task;
|
||||
|
||||
import com.microservices.common.core.constant.CacheConstants;
|
||||
import com.microservices.common.redis.service.RedisService;
|
||||
import com.microservices.zone.detail.domain.vo.ZoneBaseDataVo;
|
||||
import com.microservices.zone.detail.service.IZoneDetailService;
|
||||
import com.microservices.zone.project.domain.vo.ZoneStatisticsVo;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 专区统计数据预计算定时任务
|
||||
*/
|
||||
@Component
|
||||
public class ZoneStatisticsJob {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ZoneStatisticsJob.class);
|
||||
|
||||
@Autowired
|
||||
private IZoneDetailService zoneDetailService;
|
||||
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
/**
|
||||
* 应用启动时执行专区统计数据预计算
|
||||
* 确保服务启动后接口立即可用
|
||||
*/
|
||||
@PostConstruct
|
||||
public void initZoneStatistics() {
|
||||
logger.info("应用启动,执行专区统计数据初始化");
|
||||
calculateZoneStatistics();
|
||||
}
|
||||
|
||||
/**
|
||||
* 每小时执行一次专区统计数据预计算
|
||||
* cron表达式: 每小时的第5分钟执行
|
||||
*/
|
||||
@Scheduled(cron = "0 5 * * * ?")
|
||||
public void calculateZoneStatistics() {
|
||||
logger.info("开始执行专区统计数据预计算任务");
|
||||
|
||||
try {
|
||||
// 获取所有已发布的专区列表
|
||||
List<ZoneBaseDataVo> zoneList = zoneDetailService.selectPublishedZoneBaseList();
|
||||
logger.info("发现已发布专区数量: {}", zoneList.size());
|
||||
|
||||
int successCount = 0;
|
||||
int failCount = 0;
|
||||
|
||||
for (ZoneBaseDataVo zone : zoneList) {
|
||||
try {
|
||||
// 计算单个专区的统计数据
|
||||
ZoneStatisticsVo statistics = zoneDetailService.calculateZoneStatistics(zone.getId());
|
||||
|
||||
// 存储到Redis缓存
|
||||
String cacheKey = CacheConstants.getZoneStatisticsKey(zone.getId());
|
||||
redisService.setCacheObject(cacheKey, statistics, 7200L, TimeUnit.SECONDS);
|
||||
|
||||
successCount++;
|
||||
logger.debug("专区[{}]统计数据计算完成", zone.getId());
|
||||
|
||||
} catch (Exception e) {
|
||||
failCount++;
|
||||
logger.error("专区[{}]统计数据计算失败", zone.getId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("专区统计数据预计算任务完成 - 成功: {}, 失败: {}", successCount, failCount);
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("专区统计数据预计算任务执行失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue