From 238c45af2339810d98d05dd10fd1d31068c12938 Mon Sep 17 00:00:00 2001
From: sen <sen@qq.com>
Date: 星期一, 18 八月 2025 10:16:42 +0800
Subject: [PATCH] 修改

---
 service/src/main/java/com/ruoyi/cwgl/service/impl/DispatchOrderServiceImpl.java |  315 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 311 insertions(+), 4 deletions(-)

diff --git a/service/src/main/java/com/ruoyi/cwgl/service/impl/DispatchOrderServiceImpl.java b/service/src/main/java/com/ruoyi/cwgl/service/impl/DispatchOrderServiceImpl.java
index dd052f5..dc5a30e 100644
--- a/service/src/main/java/com/ruoyi/cwgl/service/impl/DispatchOrderServiceImpl.java
+++ b/service/src/main/java/com/ruoyi/cwgl/service/impl/DispatchOrderServiceImpl.java
@@ -1,9 +1,44 @@
 package com.ruoyi.cwgl.service.impl;
 
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.lang.reflect.Method;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
 import java.util.List;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.PageUtil;
+import com.github.pagehelper.Page;
+import com.itextpdf.text.Document;
+import com.itextpdf.text.Font;
+import com.itextpdf.text.PageSize;
+import com.itextpdf.text.pdf.BaseFont;
+import com.itextpdf.text.pdf.PdfWriter;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.config.RuoYiConfig;
+import com.ruoyi.common.core.redis.RedisCache;
 import com.ruoyi.common.utils.DateUtils;
 import javax.annotation.Resource;
+
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.bean.BeanUtils;
+import com.ruoyi.common.utils.file.DownloadExportUtil;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.cwgl.domain.vo.DispatchOrderVo;
+import com.ruoyi.cwgl.enums.FeeTypeEnums;
+import com.ruoyi.cwgl.utils.MultiPagePdfWithImageUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.ruoyi.cwgl.domain.DispatchOrderItem;
+import com.ruoyi.cwgl.domain.vo.DispatchOrderAttachmentVo;
+import com.ruoyi.cwgl.domain.vo.DispatchOrderItemVo;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.stereotype.Service;
 import org.springframework.scheduling.annotation.Async;
@@ -33,7 +68,8 @@
     protected final Logger logger = LoggerFactory.getLogger(getClass());
     @Resource
     private DispatchOrderMapper dispatchOrderMapper;
-
+    @Autowired
+    private RedisCache redisCache;
 
     /**
      * 鏌ヨ璋冨害鍗�
@@ -83,7 +119,7 @@
     @Override
     public List<DispatchOrder> selectDispatchOrderList2(DispatchOrder dispatchOrder)
     {
-        return dispatchOrderMapper.selectDispatchOrderList(dispatchOrder);
+        return dispatchOrderMapper.selectDispatchOrderList2(dispatchOrder);
     }
 
     /**
@@ -93,16 +129,203 @@
      * @param exportKey 瀵煎嚭鍔熻兘鐨勫敮涓�鏍囪瘑
      * @return 璋冨害鍗曢泦鍚�
      */
-    @DataSource(DataSourceType.SLAVE)
+    @DataSource(DataSourceType.CWSJ)
     @Async
     @Override
     public void export(DispatchOrder dispatchOrder,String exportKey) {
 
         super.export(DispatchOrder.class,exportKey,"dispatchOrderData",(pageNum)->{
             PageUtils.startPage(pageNum, Constants.EXPORT_PATE_SIZE);
-            return selectDispatchOrderList(dispatchOrder);
+            return selectDispatchOrderList2(dispatchOrder);
         });
     }
+
+    @DataSource(DataSourceType.CWSJ)
+    @Async
+    @Override
+    public void export2(DispatchOrder dispatchOrder,String exportKey) {
+
+        //鏌ヨ骞跺鍑烘暟鎹枃浠�
+        String fileName =selectListExport(dispatchOrder,  "鍙拌处淇℃伅");
+        //璁剧疆鏂囦欢缂撳瓨
+        DownloadExportUtil.setDownloadFile(redisCache, exportKey, fileName);
+    }
+
+    @DataSource(DataSourceType.CWSJ)
+    public String selectListExport(DispatchOrder dispatchOrder, String  fileName)
+    {
+         fileName =ExcelUtil.encodeFileName(fileName);
+        //鏁版嵁闆嗗悎
+        List<DispatchOrder> dataList = new ArrayList<>();
+        //瀵煎嚭琛ㄦ牸瀵硅薄
+        ExcelUtil<DispatchOrderVo> excelUtil = new ExcelUtil<>(DispatchOrderVo.class);
+        excelUtil.initialize("鍙拌处淇℃伅", null, Excel.Type.EXPORT);
+
+        List<DispatchOrderVo> exportList;//瀵煎嚭鐨勬暟缁�
+        int pageNum =1,i = 1;
+        boolean have=true;
+        //region寰幆鍒嗛〉鑾峰彇鏁版嵁
+        while (have) {
+            Page<Object> page = PageUtils.startPage(pageNum, Constants.EXPORT_PATE_SIZE);
+            List<DispatchOrder> dispatchOrders = selectDispatchOrderList2(dispatchOrder);
+            if (dispatchOrders != null && !dispatchOrders.isEmpty()) {
+                // 瀵煎嚭褰撳墠椤电殑鏁版嵁
+                exportList=structureData(dispatchOrders,i);
+                excelUtil.exportExcel(exportList);
+                pageNum++;
+            } else {
+                // 娌℃湁鏁版嵁鏃堕��鍑�
+                have = false;
+            }
+        }
+        excelUtil.finishExport(fileName);
+        return fileName;
+    }
+    /**
+     * 灏佽鏁版嵁
+     * @param list
+     * @return
+     */
+    @DataSource(DataSourceType.CWSJ)
+    private List<DispatchOrderVo> structureData(List<DispatchOrder> list,int i) {
+        List<DispatchOrderVo> exportList = new ArrayList<>();
+        Set<String> dispatchNos = list.stream().map(DispatchOrder::getDispatchNo).collect(Collectors.toSet());
+        Map<String, List<DispatchOrderItemVo>> itemMap = selectDispatchOrderItems(dispatchNos)
+                .stream().collect(Collectors.groupingBy(DispatchOrderItemVo::getDispatchNo));
+
+        for (DispatchOrder order : list) {
+            try {
+                DispatchOrderVo vo = BeanUtil.copyProperties(order, DispatchOrderVo.class);
+                vo.setId(i++);
+
+                // 鍒濆鍖栬垂鐢ㄧ粨鏋勶細Map<瑙掕壊_甯佺, Map<璐圭敤绫诲瀷, 閲戦>>
+                Map<String, Map<FeeTypeEnums, BigDecimal>> feeMap = initFeeMap();
+                Map<String, BigDecimal> totalMap = initTotalMap();
+                List<DispatchOrderItemVo> items = itemMap.get(order.getDispatchNo());
+                if (items != null) {
+                    for (DispatchOrderItemVo item : items) {
+                        if (!StringUtils.isNotEmpty(item.getFeeItem()) || item.getIsSettlement() == 0) continue;
+
+                        FeeTypeEnums feeType = FeeTypeEnums.from(item.getFeeItem());
+                        String actualCurrency = Optional.ofNullable(item.getActualFeeCurrency()).orElse("CNY");
+                        String receivableCurrency = Optional.ofNullable(item.getReceivableFeeCurrency()).orElse("CNY");
+
+
+                        addFee(feeMap, "customer_" + actualCurrency, feeType, item.getActualFee());
+                        addTotal(totalMap, "customer_" + actualCurrency, item.getActualFee());
+
+                        addFee(feeMap, "supplier_" + receivableCurrency, feeType, item.getReceivableFee());
+                        addTotal(totalMap, "supplier_" + receivableCurrency, item.getReceivableFee());
+
+
+                    }
+                }
+
+                // 璁剧疆 VO 瀛楁
+                setFeeToVo(vo, feeMap, totalMap);
+
+                exportList.add(vo);
+            } catch (Exception e) {
+                logger.error("鏁版嵁澶勭悊澶辫触 id锛歿}", order, e);
+            }
+        }
+
+        return exportList;
+    }
+    private Map<String, Map<FeeTypeEnums, BigDecimal>> initFeeMap() {
+        Map<String, Map<FeeTypeEnums, BigDecimal>> map = new HashMap<>();
+        for (String key : Arrays.asList("customer_CNY", "customer_HKD", "supplier_CNY", "supplier_HKD")) {
+            Map<FeeTypeEnums, BigDecimal> subMap = new EnumMap<>(FeeTypeEnums.class);
+            for (FeeTypeEnums feeType : FeeTypeEnums.values()) {
+                subMap.put(feeType, BigDecimal.ZERO);
+            }
+            map.put(key, subMap);
+        }
+        return map;
+    }
+
+    private Map<String, BigDecimal> initTotalMap() {
+        Map<String, BigDecimal> totalMap = new HashMap<>();
+        for (String key : Arrays.asList("customer_CNY", "customer_HKD", "supplier_CNY", "supplier_HKD")) {
+            totalMap.put(key, BigDecimal.ZERO);
+        }
+        return totalMap;
+    }
+
+    private void addFee(Map<String, Map<FeeTypeEnums, BigDecimal>> map, String key, FeeTypeEnums feeType, BigDecimal amount) {
+        if (amount == null) return;
+        Map<FeeTypeEnums, BigDecimal> subMap = map.get(key);
+        subMap.put(feeType, subMap.get(feeType).add(amount));
+    }
+    private void addTotal(Map<String, BigDecimal> totalMap, String key, BigDecimal amount) {
+        if (amount == null) return;
+        totalMap.put(key, totalMap.get(key).add(amount));
+    }
+
+    private void setFeeToVo(DispatchOrderVo vo,
+                            Map<String, Map<FeeTypeEnums, BigDecimal>> map,
+                            Map<String, BigDecimal> totalMap) {
+
+        for (String role : Arrays.asList("Customer", "Supplier")) {
+            for (String currency : Arrays.asList("Rmb", "Hkd")) {
+                String mapKey = role.toLowerCase() + "_" + ("Rmb".equals(currency) ? "CNY" : "HKD");
+                Map<FeeTypeEnums, BigDecimal> feeTypeMap = map.get(mapKey);
+
+                for (FeeTypeEnums feeType : FeeTypeEnums.values()) {
+                    String methodName = "set" + role + feeType.getFieldSuffix() + currency;
+                    invokeSetter(vo, methodName, feeTypeMap.get(feeType));
+                }
+
+                // 璁剧疆 total 瀛楁
+                String totalMethod = "set" + role + "Total" + currency;
+                invokeSetter(vo, totalMethod, totalMap.get(mapKey));
+            }
+        }
+    }
+    private void invokeSetter(Object obj, String methodName, BigDecimal value) {
+        try {
+            Method method = obj.getClass().getMethod(methodName, BigDecimal.class);
+            method.invoke(obj, value);
+        } catch (Exception e) {
+            logger.warn("璋冪敤鏂规硶澶辫触: {}", methodName, e);
+        }
+    }
+
+
+    @DataSource(DataSourceType.CWSJ)
+    public List<DispatchOrderItemVo> selectDispatchOrderItems( Set<String> nos) {
+        // 浣跨敤Map鏉ヤ复鏃跺瓨鍌ㄥ垎缁勭粨鏋�
+        List<DispatchOrderItemVo> vos = new ArrayList<>();
+        List<DispatchOrderItem> dispatchOrderItems=dispatchOrderMapper.selectDispatchOrderItemByNos(nos);
+        for (DispatchOrderItem dispatchOrderItem : dispatchOrderItems) {
+            HashSet<String> settableFeeItemSet = new HashSet<>(
+                    Arrays.asList(Optional.ofNullable(dispatchOrderItem.getSettableFeeItems()).orElse("").split(",")));
+
+            // 鍒ゆ柇鏄惁鍙粨绠�
+            String feeItem = Optional.ofNullable(dispatchOrderItem.getFeeItem()).orElse("");
+            int isSettable = settableFeeItemSet.contains(feeItem)?1:0;
+            // 濡傛灉Map涓笉瀛樺湪璇ヨ垂鐢ㄧ被鍨嬶紝鍒欏垱寤烘柊鏉$洰
+
+                DispatchOrderItemVo summary = new DispatchOrderItemVo();
+                summary.setDispatchNo(dispatchOrderItem.getDispatchNo());
+                summary.setFeeItem(feeItem);
+                summary.setReceivableFee(BigDecimal.ZERO);
+                summary.setActualFee(BigDecimal.ZERO);
+                summary.setIsSettlement(isSettable);
+
+            if ("R".equals(dispatchOrderItem.getBillType())) { // 搴旀敹
+                summary.setReceivableFee(dispatchOrderItem.getSettleFee());
+                summary.setReceivableFeeCurrency(dispatchOrderItem.getCurrencyType());
+            } else if ("P".equals(dispatchOrderItem.getBillType())) { // 搴斾粯
+                summary.setActualFee(dispatchOrderItem.getSettleFee());
+                summary.setActualFeeCurrency(dispatchOrderItem.getCurrencyType());
+
+            }
+            vos.add( summary);
+        }
+        return vos;
+    }
+
 
 
     /**
@@ -191,4 +414,88 @@
     {
         return dispatchOrderMapper.deleteDispatchOrderById(id);
     }
+
+    @DataSource(DataSourceType.CWSJ)
+    @Override
+    public List<DispatchOrderItemVo> selectDispatchOrderItem(String no) {
+        // 浣跨敤Map鏉ヤ复鏃跺瓨鍌ㄥ垎缁勭粨鏋�
+        Map<String, DispatchOrderItemVo> summaryMap = new HashMap<>();
+
+        List<DispatchOrderItem> dispatchOrderItems=dispatchOrderMapper.selectDispatchOrderItemByNo(no);
+        Set<String> settableFeeItemSet = null;
+        for (DispatchOrderItem dispatchOrderItem : dispatchOrderItems) {
+            String settableFeeItems = dispatchOrderItem.getSettableFeeItems();
+            if (settableFeeItemSet==null) {
+                settableFeeItemSet = new HashSet<>(
+                        Arrays.asList(settableFeeItems.split(",")));
+            }
+            // 鍒ゆ柇鏄惁鍙粨绠�
+            String feeItem = dispatchOrderItem.getFeeItem();
+            int isSettable = isFeeItemSettable(feeItem, settableFeeItemSet);
+            // 濡傛灉Map涓笉瀛樺湪璇ヨ垂鐢ㄧ被鍨嬶紝鍒欏垱寤烘柊鏉$洰
+            if (!summaryMap.containsKey(feeItem)) {
+                DispatchOrderItemVo summary = new DispatchOrderItemVo();
+                summary.setFeeItem(feeItem);
+                summary.setReceivableFee(BigDecimal.ZERO);
+                summary.setActualFee(BigDecimal.ZERO);
+                summary.setIsSettlement(isSettable);
+                summaryMap.put(feeItem, summary);
+            }
+            // 鏍规嵁璐﹀崟绫诲瀷绱姞閲戦
+            DispatchOrderItemVo summary = summaryMap.get(feeItem);
+            if ("R".equals(dispatchOrderItem.getBillType())) { // 搴旀敹
+                summary.setReceivableFee(summary.getReceivableFee().add(dispatchOrderItem.getSettleFee()));
+                summary.setReceivableFeeCurrency(dispatchOrderItem.getCurrencyType());
+            } else if ("P".equals(dispatchOrderItem.getBillType())) { // 搴斾粯
+                summary.setActualFee(summary.getActualFee().add(dispatchOrderItem.getSettleFee()));
+                summary.setActualFeeCurrency(dispatchOrderItem.getCurrencyType());
+
+            }
+        }
+           // 杞崲涓篖ist骞惰繃婊ゃ�佹帓搴�
+        return summaryMap.values().stream()
+                // 杩囨护鎺夊簲鏀跺簲浠橀兘涓�0鐨勮褰�
+                .filter(dto -> dto.getReceivableFee().compareTo(BigDecimal.ZERO) != 0
+                        || dto.getActualFee().compareTo(BigDecimal.ZERO) != 0)
+                // 鎺掑簭锛氬彲缁撶畻鐨勫湪鍓嶏紝涓嶅彲缁撶畻鐨勫湪鍚庯紱鐒跺悗鎸夋�婚噾棰濋檷搴�
+                .sorted(Comparator.comparing(DispatchOrderItemVo::getIsSettlement).reversed()
+                        .thenComparing(dto -> dto.getReceivableFee().add(dto.getActualFee()),
+                                Comparator.reverseOrder()))
+                .collect(Collectors.toList());
+    }
+
+
+
+    /**
+     * 鍒ゆ柇璐圭敤绫诲瀷鏄惁鍙粨绠�
+     */
+    private static int isFeeItemSettable(String feeItem, Set<String> settableFeeItemSet) {
+        if (feeItem == null || settableFeeItemSet == null) {
+            return 0;
+        }
+
+
+            if (settableFeeItemSet.contains(feeItem)) {
+                return 1;
+            }
+
+        return 0;
+    }
+
+    @DataSource(DataSourceType.CWSJ)
+    @Override
+    public List<DispatchOrderAttachmentVo> selectDispatchOrderAttachment(String no) {
+        return dispatchOrderMapper.selectDispatchOrderAttachment(no);
+    }
+
+    @DataSource(DataSourceType.CWSJ)
+    @Override
+    public String  downAttachment(String no) throws Exception {
+        List<DispatchOrderAttachmentVo> dispatchOrderAttachmentVos = selectDispatchOrderAttachment(no);
+        return MultiPagePdfWithImageUtils.createPdf(dispatchOrderAttachmentVos, no);
+    }
+
+
+
+
 }

--
Gitblit v1.8.0