From 9f8b3700ffbcc616a97e7ee2ea283ef4df3d666a Mon Sep 17 00:00:00 2001
From: rk <94314517@qq.com>
Date: 星期四, 04 六月 2026 08:43:55 +0800
Subject: [PATCH] 代码生成

---
 server/services/src/main/java/com/doumee/service/business/impl/DataBoardServiceImpl.java |  213 +++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 199 insertions(+), 14 deletions(-)

diff --git a/server/services/src/main/java/com/doumee/service/business/impl/DataBoardServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/DataBoardServiceImpl.java
index 9514975..5e4cb53 100644
--- a/server/services/src/main/java/com/doumee/service/business/impl/DataBoardServiceImpl.java
+++ b/server/services/src/main/java/com/doumee/service/business/impl/DataBoardServiceImpl.java
@@ -13,7 +13,11 @@
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
 import org.springframework.stereotype.Service;
+
+import javax.servlet.http.HttpServletResponse;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
@@ -150,10 +154,10 @@
         Map<String, Long> map = members.stream()
                 .collect(Collectors.groupingBy(m -> sdf.format(m.getCreateTime()), Collectors.counting()));
 
-        return buildTrendList(range, (date) -> {
+        return buildTrendList(range, (key, label) -> {
             MemberTrendVO vo = new MemberTrendVO();
-            vo.setDate(date);
-            vo.setCount(map.getOrDefault(date, 0L));
+            vo.setDate(label);
+            vo.setCount(map.getOrDefault(key, 0L));
             return vo;
         });
     }
@@ -169,10 +173,10 @@
         Map<String, List<Orders>> grouped = orders.stream()
                 .collect(Collectors.groupingBy(o -> sdf.format(o.getCreateTime())));
 
-        return buildTrendList(range, (date) -> {
-            List<Orders> dayOrders = grouped.getOrDefault(date, Collections.emptyList());
+        return buildTrendList(range, (key, label) -> {
+            List<Orders> dayOrders = grouped.getOrDefault(key, Collections.emptyList());
             OrderTrendVO vo = new OrderTrendVO();
-            vo.setDate(date);
+            vo.setDate(label);
             vo.setLocalCount(dayOrders.stream().filter(o -> Constants.equalsInteger(o.getType(), Constants.ZERO)).count());
             vo.setRemoteCount(dayOrders.stream().filter(o -> Constants.equalsInteger(o.getType(), Constants.ONE)).count());
             return vo;
@@ -227,11 +231,11 @@
             }
         }
 
-        return buildTrendList(range, (date) -> {
+        return buildTrendList(range, (key, label) -> {
             RevenueTrendVO vo = new RevenueTrendVO();
-            vo.setDate(date);
-            long local = localOrderRevenue.getOrDefault(date, 0L);
-            long remote = remoteOrderRevenue.getOrDefault(date, 0L);
+            vo.setDate(label);
+            long local = localOrderRevenue.getOrDefault(key, 0L);
+            long remote = remoteOrderRevenue.getOrDefault(key, 0L);
             vo.setLocalRevenue(BigDecimal.valueOf(local).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP));
             vo.setRemoteRevenue(BigDecimal.valueOf(remote).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP));
             return vo;
@@ -430,6 +434,7 @@
             vo.setNetRevenue(BigDecimal.valueOf(netRev).divide(hundred, 2, RoundingMode.HALF_UP));
             result.add(vo);
         }
+        Collections.reverse(result);
         return result;
     }
 
@@ -642,6 +647,184 @@
         return qw;
     }
 
+    @Override
+    public void revenueTrendExport(TrendQueryDTO query, HttpServletResponse response) {
+        TrendDateRange range = parseTrendDateRange(query);
+        SimpleDateFormat sdf = new SimpleDateFormat(range.pattern);
+
+        // 鏌ヨ璁㈠崟
+        List<Orders> orders = ordersMapper.selectList(new QueryWrapper<Orders>().lambda()
+                .eq(Orders::getDeleted, Constants.ZERO)
+                .in(Orders::getStatus,
+                        Constants.OrderStatus.waitDeposit.getKey(),
+                        Constants.OrderStatus.deposited.getKey(),
+                        Constants.OrderStatus.accepted.getKey(),
+                        Constants.OrderStatus.delivering.getKey(),
+                        Constants.OrderStatus.arrived.getKey(),
+                        Constants.OrderStatus.overdue.getKey(),
+                        Constants.OrderStatus.finished.getKey())
+                .ge(Orders::getCreateTime, range.startDate)
+                .le(Orders::getCreateTime, range.endDate));
+
+        // 鏌ヨ閫炬湡璐圭敤
+        List<Integer> orderIds = orders.stream().map(Orders::getId).collect(Collectors.toList());
+        Map<Integer, Long> overduePaidMap = new HashMap<>();
+        if (!orderIds.isEmpty()) {
+            List<OtherOrders> overdueOrders = otherOrdersMapper.selectList(new QueryWrapper<OtherOrders>().lambda()
+                    .eq(OtherOrders::getType, 2)
+                    .eq(OtherOrders::getPayStatus, Constants.ONE)
+                    .eq(OtherOrders::getDeleted, Constants.ZERO)
+                    .in(OtherOrders::getOrderId, orderIds));
+            for (OtherOrders oo : overdueOrders) {
+                long amt = oo.getPayAccount() != null ? oo.getPayAccount() : 0L;
+                overduePaidMap.merge(oo.getOrderId(), amt, Long::sum);
+            }
+        }
+
+        // 鐢熸垚鏃ユ湡鍒楀ご
+        List<String> dateKeys = new ArrayList<>();
+        List<String> dateLabels = new ArrayList<>();
+        if (range.byMonth) {
+            Calendar loop = Calendar.getInstance();
+            loop.setTime(range.startDate);
+            Calendar end = Calendar.getInstance();
+            end.setTime(range.endDate);
+            while (!loop.after(end)) {
+                dateKeys.add(sdf.format(loop.getTime()));
+                dateLabels.add(sdf.format(loop.getTime()));
+                loop.add(Calendar.DAY_OF_MONTH, 1);
+            }
+        } else {
+            Calendar endCal = Calendar.getInstance();
+            endCal.setTime(range.endDate);
+            int endMonth = endCal.get(Calendar.MONTH);
+            for (int m = 0; m <= endMonth; m++) {
+                dateKeys.add(String.format("%02d", m + 1));
+                dateLabels.add((m + 1) + "鏈�");
+            }
+        }
+
+        // 鏀堕泦鎵�鏈夐棬搴�
+        Map<Integer, String> shopNameMap = new LinkedHashMap<>();
+        for (Orders o : orders) {
+            if (o.getDepositShopId() != null && !shopNameMap.containsKey(o.getDepositShopId())) {
+                ShopInfo shop = shopInfoMapper.selectById(o.getDepositShopId());
+                shopNameMap.put(o.getDepositShopId(), shop != null ? shop.getName() : "鏈煡闂ㄥ簵");
+            }
+        }
+
+        // 鎸夐棬搴�+鏃ユ湡鍒嗙粍璁$畻钀ユ敹
+        // key = shopId + "_" + dateKey
+        Map<String, Long> revenueMap = new HashMap<>();
+        for (Orders o : orders) {
+            String date = sdf.format(o.getCreateTime());
+            long pay = o.getPayAmount() != null ? o.getPayAmount() : 0L;
+            long refund = o.getRefundAmount() != null ? o.getRefundAmount() : 0L;
+            long overdue = overduePaidMap.getOrDefault(o.getId(), 0L);
+            long rev = pay - refund + overdue;
+            Integer shopId = o.getDepositShopId();
+            if (shopId != null) {
+                String key = shopId + "_" + date;
+                revenueMap.merge(key, rev, Long::sum);
+            }
+        }
+
+        // 鏋勫缓Excel
+        try (SXSSFWorkbook wb = new SXSSFWorkbook()) {
+            Sheet sheet = wb.createSheet("钀ユ敹瓒嬪娍");
+
+            // 鍒涘缓鏍峰紡
+            CellStyle titleStyle = wb.createCellStyle();
+            Font titleFont = wb.createFont();
+            titleFont.setBold(true);
+            titleFont.setFontHeightInPoints((short) 16);
+            titleStyle.setFont(titleFont);
+            titleStyle.setAlignment(HorizontalAlignment.CENTER);
+
+            CellStyle headerStyle = wb.createCellStyle();
+            Font headerFont = wb.createFont();
+            headerFont.setBold(true);
+            headerFont.setFontHeightInPoints((short) 12);
+            headerStyle.setFont(headerFont);
+            headerStyle.setAlignment(HorizontalAlignment.CENTER);
+            headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
+            headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+
+            CellStyle dataStyle = wb.createCellStyle();
+            dataStyle.setAlignment(HorizontalAlignment.RIGHT);
+
+            // 鐢熸垚鏍囬
+            String title;
+            int totalCols = dateLabels.size() + 1;
+            if (range.byMonth) {
+                String yearMonth = query.getMonth(); // yyyy-MM
+                String[] ym = yearMonth.split("-");
+                title = "琛屾潕瀵勫瓨闂ㄥ簵" + ym[0] + "骞�" + Integer.valueOf(ym[1]) + "鏈堟棩鎶ヨ〃";
+            } else {
+                title = "琛屾潕瀵勫瓨闂ㄥ簵" + query.getYear() + "骞存湀鎶ヨ〃";
+            }
+
+            // 鍐欐爣棰樿锛堢0琛岋紝鍚堝苟鎵�鏈夊垪锛�
+            Row titleRow = sheet.createRow(0);
+            titleRow.setHeight((short) 600);
+            Cell titleCell = titleRow.createCell(0);
+            titleCell.setCellValue(title);
+            titleCell.setCellStyle(titleStyle);
+            sheet.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(0, 0, 0, totalCols - 1));
+
+            // 鍐欏垪澶达紙绗�1琛岋級
+            Row headerRow = sheet.createRow(1);
+            Cell shopCell = headerRow.createCell(0);
+            shopCell.setCellValue("闂ㄥ簵鍚嶇О");
+            shopCell.setCellStyle(headerStyle);
+            sheet.setColumnWidth(0, 20 * 256);
+
+            for (int i = 0; i < dateLabels.size(); i++) {
+                Cell cell = headerRow.createCell(i + 1);
+                cell.setCellValue(dateLabels.get(i));
+                cell.setCellStyle(headerStyle);
+                sheet.setColumnWidth(i + 1, 14 * 256);
+            }
+
+            // 鍐欐暟鎹锛堢2琛岃捣锛�
+            BigDecimal hundred = BigDecimal.valueOf(100);
+            int rowIndex = 2;
+            for (Map.Entry<Integer, String> entry : shopNameMap.entrySet()) {
+                Row row = sheet.createRow(rowIndex++);
+                row.createCell(0).setCellValue(entry.getValue());
+                for (int i = 0; i < dateKeys.size(); i++) {
+                    String mapKey = entry.getKey() + "_" + dateKeys.get(i);
+                    long rev = revenueMap.getOrDefault(mapKey, 0L);
+                    Cell cell = row.createCell(i + 1);
+                    if (rev > 0) {
+                        cell.setCellValue(BigDecimal.valueOf(rev).divide(hundred, 2, RoundingMode.HALF_UP).toPlainString());
+                    } else {
+                        cell.setCellValue("");
+                    }
+                    cell.setCellStyle(dataStyle);
+                }
+            }
+
+            // 杈撳嚭
+            String fileName;
+            if (StringUtils.isNotBlank(query.getMonth())) {
+                fileName = "钀ユ敹瓒嬪娍瀵煎嚭_" + query.getMonth();
+            } else {
+                fileName = "钀ユ敹瓒嬪娍瀵煎嚭_" + query.getYear();
+            }
+            String encodeFileName = java.net.URLEncoder.encode(fileName, "UTF-8") + ".xlsx";
+            response.setContentType("application/octet-stream");
+            response.setHeader("Content-Disposition", "attachment;filename=" + encodeFileName);
+            response.setHeader("doumee-opera-type", "download");
+            response.setHeader("doumee-download-filename", encodeFileName);
+            wb.write(response.getOutputStream());
+            response.getOutputStream().flush();
+        } catch (Exception e) {
+            log.error("钀ユ敹瓒嬪娍瀵煎嚭寮傚父", e);
+            throw new RuntimeException("瀵煎嚭澶辫触: " + e.getMessage());
+        }
+    }
+
     private TrendDateRange parseTrendDateRange(TrendQueryDTO query) {
         Calendar now = Calendar.getInstance();
         TrendDateRange range = new TrendDateRange();
@@ -718,7 +901,7 @@
 
     @FunctionalInterface
     private interface TrendVOBuilder<T> {
-        T build(String date);
+        T build(String key, String label);
     }
 
     private <T> List<T> buildTrendList(TrendDateRange range, TrendVOBuilder<T> builder) {
@@ -732,7 +915,8 @@
             Calendar end = Calendar.getInstance();
             end.setTime(range.endDate);
             while (!loop.after(end)) {
-                result.add(builder.build(sdf.format(loop.getTime())));
+                String dateStr = sdf.format(loop.getTime());
+                result.add(builder.build(dateStr, dateStr));
                 loop.add(Calendar.DAY_OF_MONTH, 1);
             }
         } else {
@@ -741,8 +925,9 @@
             endCal.setTime(range.endDate);
             int endMonth = endCal.get(Calendar.MONTH); // 0-based
             for (int m = 0; m <= endMonth; m++) {
-                String label = String.format("%02d", m + 1);
-                result.add(builder.build(label));
+                String key = String.format("%02d", m + 1);
+                String label = (m + 1) + "鏈�";
+                result.add(builder.build(key, label));
             }
         }
         return result;

--
Gitblit v1.9.3