소스 검색

Merge branch 'release_lutong_bug' into sit

lutong 2 달 전
부모
커밋
f31eb9ab3f

+ 29 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/StoreOperationalStatisticsComparisonVo.java

@@ -6,6 +6,7 @@ import lombok.Data;
 
 import java.io.Serializable;
 import java.math.BigDecimal;
+import java.util.List;
 
 /**
  * 商家经营统计数据对比VO(包含当期、上期和变化率)
@@ -66,6 +67,12 @@ public class StoreOperationalStatisticsComparisonVo implements Serializable {
     private ServiceQualityDataComparison serviceQualityData;
 
     /**
+     * 价目表排名数据对比
+     */
+    @ApiModelProperty("价目表排名数据对比")
+    private List<PriceListRankingComparison> priceListRanking;
+
+    /**
      * 基础对比数据
      */
     @Data
@@ -268,4 +275,26 @@ public class StoreOperationalStatisticsComparisonVo implements Serializable {
         @ApiModelProperty("差评申诉成功占比对比")
         private BaseComparisonData negativeReviewAppealsSuccessRatio;
     }
+
+    /**
+     * 价目表排名数据对比
+     */
+    @Data
+    @ApiModel("价目表排名数据对比")
+    public static class PriceListRankingComparison implements Serializable {
+        @ApiModelProperty("价目表ID")
+        private Integer priceId;
+
+        @ApiModelProperty("价目表名称")
+        private String priceListItemName;
+
+        @ApiModelProperty("浏览量对比")
+        private BaseComparisonData pageViews;
+
+        @ApiModelProperty("访客数对比")
+        private BaseComparisonData visitors;
+
+        @ApiModelProperty("分享数对比")
+        private BaseComparisonData shares;
+    }
 }

+ 58 - 0
alien-store/src/main/java/shop/alien/store/service/impl/StoreOperationalStatisticsServiceImpl.java

@@ -187,6 +187,7 @@ public class StoreOperationalStatisticsServiceImpl implements StoreOperationalSt
         comparison.setCouponData(buildCouponDataComparison(currentStatistics.getCouponData(), previousStatistics.getCouponData()));
         comparison.setVoucherData(buildVoucherDataComparison(currentStatistics.getVoucherData(), previousStatistics.getVoucherData()));
         comparison.setServiceQualityData(buildServiceQualityDataComparison(currentStatistics.getServiceQualityData(), previousStatistics.getServiceQualityData()));
+        comparison.setPriceListRanking(buildPriceListRankingComparison(currentStatistics.getPriceListRanking(), previousStatistics.getPriceListRanking()));
 
         // 不再在此处保存历史记录,历史记录只在 generateStatisticsComparisonPdf 接口中保存
 
@@ -761,6 +762,63 @@ public class StoreOperationalStatisticsServiceImpl implements StoreOperationalSt
     }
 
     /**
+     * 构建价目表排名数据对比
+     */
+    private List<StoreOperationalStatisticsComparisonVo.PriceListRankingComparison> buildPriceListRankingComparison(
+            List<StoreOperationalStatisticsVo.PriceListRanking> current, List<StoreOperationalStatisticsVo.PriceListRanking> previous) {
+        List<StoreOperationalStatisticsComparisonVo.PriceListRankingComparison> result = new ArrayList<>();
+        
+        // 如果当期数据为空,返回空列表
+        if (current == null || current.isEmpty()) {
+            return result;
+        }
+        
+        // 如果上期数据为空,创建空列表
+        if (previous == null) {
+            previous = new ArrayList<>();
+        }
+        
+        // 创建上期数据的Map,以priceId为key,方便查找
+        Map<Integer, StoreOperationalStatisticsVo.PriceListRanking> previousMap = new HashMap<>();
+        for (StoreOperationalStatisticsVo.PriceListRanking prev : previous) {
+            if (prev.getPriceId() != null) {
+                previousMap.put(prev.getPriceId(), prev);
+            }
+        }
+        
+        // 遍历当期数据,构建对比
+        for (StoreOperationalStatisticsVo.PriceListRanking curr : current) {
+            StoreOperationalStatisticsComparisonVo.PriceListRankingComparison comparison = 
+                new StoreOperationalStatisticsComparisonVo.PriceListRankingComparison();
+            
+            comparison.setPriceId(curr.getPriceId());
+            comparison.setPriceListItemName(curr.getPriceListItemName());
+            
+            // 获取上期对应的价目表数据
+            StoreOperationalStatisticsVo.PriceListRanking prev = previousMap.get(curr.getPriceId());
+            
+            // 构建浏览量对比
+            Long currentPageViews = curr.getPageViews() != null ? curr.getPageViews() : 0L;
+            Long previousPageViews = (prev != null && prev.getPageViews() != null) ? prev.getPageViews() : 0L;
+            comparison.setPageViews(buildComparisonData(currentPageViews, previousPageViews));
+            
+            // 构建访客数对比
+            Long currentVisitors = curr.getVisitors() != null ? curr.getVisitors() : 0L;
+            Long previousVisitors = (prev != null && prev.getVisitors() != null) ? prev.getVisitors() : 0L;
+            comparison.setVisitors(buildComparisonData(currentVisitors, previousVisitors));
+            
+            // 构建分享数对比
+            Long currentShares = curr.getShares() != null ? curr.getShares() : 0L;
+            Long previousShares = (prev != null && prev.getShares() != null) ? prev.getShares() : 0L;
+            comparison.setShares(buildComparisonData(currentShares, previousShares));
+            
+            result.add(comparison);
+        }
+        
+        return result;
+    }
+
+    /**
      * 构建对比数据
      */
     private StoreOperationalStatisticsComparisonVo.BaseComparisonData buildComparisonData(Object current, Object previous) {

+ 68 - 0
alien-store/src/main/java/shop/alien/store/util/StatisticsComparisonImageUtil.java

@@ -115,6 +115,12 @@ public class StatisticsComparisonImageUtil {
                     buildServiceQualityDataRows(comparison.getServiceQualityData()));
             }
             
+            // 绘制价目表排名数据
+            if (comparison.getPriceListRanking() != null && !comparison.getPriceListRanking().isEmpty()) {
+                currentY = drawPriceListRankingSection(g2d, currentY, "价目表排名", 
+                    comparison.getPriceListRanking());
+            }
+            
             g2d.dispose();
             
             // 转换为字节数组
@@ -153,6 +159,10 @@ public class StatisticsComparisonImageUtil {
         if (comparison.getServiceQualityData() != null) {
             rowCount += 12; // 服务质量数据行数(12个字段)
         }
+        if (comparison.getPriceListRanking() != null && !comparison.getPriceListRanking().isEmpty()) {
+            // 价目表数据:每个价目表3个指标(浏览量、访客数、分享数)
+            rowCount += comparison.getPriceListRanking().size() * 3;
+        }
         
         height += rowCount * ROW_HEIGHT;
         height += (rowCount / 6 + 4) * SECTION_SPACING; // 区块间距
@@ -631,6 +641,64 @@ public class StatisticsComparisonImageUtil {
     }
 
     /**
+     * 绘制价目表排名数据区块(特殊格式,每个价目表显示3个指标)
+     */
+    private static int drawPriceListRankingSection(Graphics2D g2d, int y, String sectionTitle, 
+                                                   List<StoreOperationalStatisticsComparisonVo.PriceListRankingComparison> rankings) {
+        if (rankings == null || rankings.isEmpty()) {
+            return y;
+        }
+        
+        // 绘制区块标题
+        Font sectionFont = new Font(FONT_NAME, Font.BOLD, SECTION_TITLE_FONT_SIZE);
+        g2d.setFont(sectionFont);
+        g2d.setColor(SECTION_TITLE_COLOR);
+        g2d.drawString(sectionTitle, PADDING, y);
+        y += 30;
+        
+        Font dataFont = new Font(FONT_NAME, Font.PLAIN, DATA_FONT_SIZE);
+        Font labelFont = new Font(FONT_NAME, Font.PLAIN, LABEL_FONT_SIZE);
+        
+        // 遍历每个价目表
+        for (StoreOperationalStatisticsComparisonVo.PriceListRankingComparison ranking : rankings) {
+            // 绘制价目表名称(作为子标题)
+            g2d.setFont(new Font(FONT_NAME, Font.BOLD, LABEL_FONT_SIZE));
+            g2d.setColor(new Color(66, 66, 66));
+            String priceListName = ranking.getPriceListItemName() != null ? ranking.getPriceListItemName() : 
+                ("价目表ID: " + ranking.getPriceId());
+            g2d.drawString(priceListName, PADDING + 20, y);
+            y += 25;
+            
+            // 绘制表头
+            y = drawTableHeader(g2d, y);
+            
+            // 绘制该价目表的3个指标
+            List<DataRow> rows = new ArrayList<>();
+            if (ranking.getPageViews() != null) {
+                rows.add(new DataRow("浏览量", ranking.getPageViews().getCurrent(), 
+                    ranking.getPageViews().getPrevious(), ranking.getPageViews().getChangeRate()));
+            }
+            if (ranking.getVisitors() != null) {
+                rows.add(new DataRow("访客", ranking.getVisitors().getCurrent(), 
+                    ranking.getVisitors().getPrevious(), ranking.getVisitors().getChangeRate()));
+            }
+            if (ranking.getShares() != null) {
+                rows.add(new DataRow("分享数", ranking.getShares().getCurrent(), 
+                    ranking.getShares().getPrevious(), ranking.getShares().getChangeRate()));
+            }
+            
+            // 绘制数据行
+            for (DataRow row : rows) {
+                y = drawDataRow(g2d, y, row, dataFont, labelFont);
+            }
+            
+            y += SECTION_SPACING / 2; // 价目表之间的间距
+        }
+        
+        return y + SECTION_SPACING;
+    }
+
+    /**
      * 数据行内部类
      */
     private static class DataRow {