|
@@ -1,5 +1,8 @@
|
|
package cn.iocoder.yudao.module.statistics.service.product;
|
|
package cn.iocoder.yudao.module.statistics.service.product;
|
|
|
|
|
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
|
+import cn.hutool.core.date.DatePattern;
|
|
|
|
+import cn.hutool.core.date.LocalDateTimeUtil;
|
|
import cn.hutool.core.util.ArrayUtil;
|
|
import cn.hutool.core.util.ArrayUtil;
|
|
import cn.hutool.core.util.ObjUtil;
|
|
import cn.hutool.core.util.ObjUtil;
|
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
@@ -10,13 +13,18 @@ import cn.iocoder.yudao.module.statistics.controller.admin.product.vo.ProductSta
|
|
import cn.iocoder.yudao.module.statistics.controller.admin.product.vo.ProductStatisticsRespVO;
|
|
import cn.iocoder.yudao.module.statistics.controller.admin.product.vo.ProductStatisticsRespVO;
|
|
import cn.iocoder.yudao.module.statistics.dal.dataobject.product.ProductStatisticsDO;
|
|
import cn.iocoder.yudao.module.statistics.dal.dataobject.product.ProductStatisticsDO;
|
|
import cn.iocoder.yudao.module.statistics.dal.mysql.product.ProductStatisticsMapper;
|
|
import cn.iocoder.yudao.module.statistics.dal.mysql.product.ProductStatisticsMapper;
|
|
|
|
+import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
import jakarta.annotation.Resource;
|
|
import jakarta.annotation.Resource;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
+import org.springframework.util.StopWatch;
|
|
import org.springframework.validation.annotation.Validated;
|
|
import org.springframework.validation.annotation.Validated;
|
|
|
|
|
|
import java.time.Duration;
|
|
import java.time.Duration;
|
|
import java.time.LocalDateTime;
|
|
import java.time.LocalDateTime;
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
+import java.util.stream.IntStream;
|
|
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -31,17 +39,6 @@ public class ProductStatisticsServiceImpl implements ProductStatisticsService {
|
|
@Resource
|
|
@Resource
|
|
private ProductStatisticsMapper productStatisticsMapper;
|
|
private ProductStatisticsMapper productStatisticsMapper;
|
|
|
|
|
|
- @Override
|
|
|
|
- public Long createProductStatistics(ProductStatisticsDO entity) {
|
|
|
|
- // 计算 访客支付转化率(百分比)
|
|
|
|
- if (entity.getBrowseUserCount() != null && ObjUtil.notEqual(entity.getBrowseUserCount(), 0)) {
|
|
|
|
- entity.setBrowseConvertPercent(100 * entity.getOrderPayCount() / entity.getBrowseUserCount());
|
|
|
|
- }
|
|
|
|
- // 插入
|
|
|
|
- productStatisticsMapper.insert(entity);
|
|
|
|
- // 返回
|
|
|
|
- return entity.getId();
|
|
|
|
- }
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public PageResult<ProductStatisticsDO> getProductStatisticsRankPage(ProductStatisticsReqVO reqVO, SortablePageParam pageParam) {
|
|
public PageResult<ProductStatisticsDO> getProductStatisticsRankPage(ProductStatisticsReqVO reqVO, SortablePageParam pageParam) {
|
|
@@ -69,4 +66,58 @@ public class ProductStatisticsServiceImpl implements ProductStatisticsService {
|
|
return productStatisticsMapper.selectListByTimeBetween(reqVO);
|
|
return productStatisticsMapper.selectListByTimeBetween(reqVO);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
+ public String statisticsProduct(Integer days) {
|
|
|
|
+ LocalDateTime today = LocalDateTime.now();
|
|
|
|
+ return IntStream.rangeClosed(1, days)
|
|
|
|
+ .mapToObj(day -> statisticsProduct(today.minusDays(day)))
|
|
|
|
+ .sorted()
|
|
|
|
+ .collect(Collectors.joining("\n"));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 统计商品数据
|
|
|
|
+ *
|
|
|
|
+ * @param date 需要统计的日期
|
|
|
|
+ * @return 统计结果
|
|
|
|
+ */
|
|
|
|
+ private String statisticsProduct(LocalDateTime date) {
|
|
|
|
+ // 1. 处理统计时间范围
|
|
|
|
+ LocalDateTime beginTime = LocalDateTimeUtil.beginOfDay(date);
|
|
|
|
+ LocalDateTime endTime = LocalDateTimeUtil.endOfDay(date);
|
|
|
|
+ String dateStr = DatePattern.NORM_DATE_FORMATTER.format(date);
|
|
|
|
+ // 2. 检查该日是否已经统计过
|
|
|
|
+ Long count = productStatisticsMapper.selectCountByTimeBetween(beginTime, endTime);
|
|
|
|
+ if (count != null && count > 0) {
|
|
|
|
+ return dateStr + " 数据已存在,如果需要重新统计,请先删除对应的数据";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 3. 统计数据
|
|
|
|
+ StopWatch stopWatch = new StopWatch(dateStr);
|
|
|
|
+ stopWatch.start();
|
|
|
|
+
|
|
|
|
+ // 分页统计,避免商品表数据较多时,出现超时问题
|
|
|
|
+ final int pageSize = 100;
|
|
|
|
+ for (int pageNo = 1; ; pageNo ++) {
|
|
|
|
+ IPage<ProductStatisticsDO> page = productStatisticsMapper.selectStatisticsResultPageByTimeBetween(
|
|
|
|
+ Page.of(pageNo, pageSize, false), beginTime, endTime);
|
|
|
|
+ if (CollUtil.isEmpty(page.getRecords())) {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (ProductStatisticsDO record : page.getRecords()) {
|
|
|
|
+ record.setTime(date.toLocalDate());
|
|
|
|
+ // 计算 访客支付转化率(百分比)
|
|
|
|
+ if (record.getBrowseUserCount() != null && ObjUtil.notEqual(record.getBrowseUserCount(), 0)) {
|
|
|
|
+ record.setBrowseConvertPercent(100 * record.getOrderPayCount() / record.getBrowseUserCount());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 4. 插入数据
|
|
|
|
+ productStatisticsMapper.insertBatch(page.getRecords());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return stopWatch.prettyPrint();
|
|
|
|
+ }
|
|
|
|
+
|
|
}
|
|
}
|