Prechádzať zdrojové kódy

财务回款单新需求改造

wangxy 2 týždňov pred
rodič
commit
0a4b1a6294

+ 9 - 1
fs-common/src/main/java/com/fs/common/utils/poi/ExcelUtil.java

@@ -27,6 +27,7 @@ import org.apache.poi.hssf.usermodel.HSSFSheet;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.ooxml.POIXMLDocumentPart;
 import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.CellRangeAddressList;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.xssf.streaming.SXSSFWorkbook;
@@ -951,9 +952,16 @@ public class ExcelUtil<T>
         {
             Row row = sheet.createRow(sheet.getLastRowNum() + 1);
             Set<Integer> keys = statistics.keySet();
+            int minKey = keys.stream().min(Integer::compareTo).orElse(0);
             Cell cell = row.createCell(0);
             cell.setCellStyle(styles.get("total"));
-            cell.setCellValue("合计");
+            cell.setCellValue("总计");
+
+            // 合并"总计"单元格:从第0列合并到第一个统计列前一列
+            if (minKey > 1)
+            {
+                sheet.addMergedRegion(new CellRangeAddress(row.getRowNum(), row.getRowNum(), 0, minKey - 1));
+            }
 
             for (Integer key : keys)
             {

+ 59 - 2
fs-company/src/main/java/com/fs/company/controller/store/FsFinanceOrderController.java

@@ -13,6 +13,7 @@ import com.fs.his.domain.FsExternalOrder;
 import com.fs.his.domain.vo.FsFinanceOrderListVO;
 import com.fs.his.dto.FsFinanceOrderImportDTO;
 import com.fs.his.dto.FsFinanceOrderImportFailDTO;
+import com.fs.his.dto.FsFinanceOrderImportPreviewDTO;
 import com.fs.his.mapper.FsExternalOrderMapper;
 import org.apache.commons.collections4.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -151,17 +152,73 @@ public class FsFinanceOrderController extends BaseController {
         return null;
     }
 
+    /**
+     * 预览导入数据(解析Excel并匹配订单,不执行写入)
+     */
+    @Log(title = "财务回款导入预览", businessType = BusinessType.OTHER)
+    @PreAuthorize("@ss.hasPermi('store:financeOrder:import')")
+    @PostMapping("/previewImport")
+    public AjaxResult previewImport(MultipartFile file) throws Exception {
+        ExcelUtil<FsFinanceOrderImportDTO> util = new ExcelUtil<>(FsFinanceOrderImportDTO.class);
+        List<FsFinanceOrderImportDTO> importList = util.importExcel(file.getInputStream());
+
+        List<FsFinanceOrderImportPreviewDTO> previewList = new ArrayList<>();
+
+        for (FsFinanceOrderImportDTO dto : importList) {
+            FsFinanceOrderImportPreviewDTO preview = new FsFinanceOrderImportPreviewDTO();
+            preview.setDeliverySn(dto.getDeliverySn());
+            preview.setReturnPrice(dto.getReturnPrice());
+            preview.setReturnTime(dto.getReturnTime());
+
+            // 字段校验
+            String validateMsg = validateImportDto(dto);
+            if (validateMsg != null) {
+                preview.setMatched(false);
+                preview.setFailReason(validateMsg);
+                previewList.add(preview);
+                continue;
+            }
+
+            // 匹配订单
+            FsExternalOrder order = matchOrder(dto);
+            if (order == null) {
+                preview.setMatched(false);
+                preview.setFailReason("快递单号未匹配到订单");
+                previewList.add(preview);
+                continue;
+            }
+
+            preview.setOrderId(order.getOrderId());
+            preview.setOrderCode(order.getOrderCode());
+            preview.setTotalPrice(order.getTotalPrice());
+            preview.setPayPrice(order.getPayPrice());
+            preview.setCollectionPrice(order.getCollectionPrice());
+            preview.setMatched(true);
+            previewList.add(preview);
+        }
+
+        return AjaxResult.success(previewList);
+    }
+
     /** 根据快递单号匹配订单 */
     private FsExternalOrder matchOrder(FsFinanceOrderImportDTO dto) {
         if (dto.getDeliverySn() == null || dto.getDeliverySn().isEmpty()) {
             return null;
         }
-        List<FsExternalOrder> list = fsExternalOrderMapper.selectFsExternalOrderListByDeliverySn(dto.getDeliverySn());
+        return matchOrder(dto.getDeliverySn());
+    }
+
+    /** 根据快递单号匹配订单 */
+    private FsExternalOrder matchOrder(String deliverySn) {
+        if (deliverySn == null || deliverySn.isEmpty()) {
+            return null;
+        }
+        List<FsExternalOrder> list = fsExternalOrderMapper.selectFsExternalOrderListByDeliverySn(deliverySn);
         if (list == null || list.isEmpty()) {
             return null;
         }
         if (list.size() > 1) {
-            logger.warn("快递单号 {} 对应多条订单,取第一条", dto.getDeliverySn());
+            logger.warn("快递单号 {} 对应多条订单,取第一条", deliverySn);
         }
         return list.get(0);
     }

+ 6 - 3
fs-service/src/main/java/com/fs/his/domain/vo/FsFinanceOrderListVO.java

@@ -35,13 +35,16 @@ public class FsFinanceOrderListVO {
     @Excel(name = "运单号")
     private String deliverySn;
 
-    @Excel(name = "订单金额")
+    @Excel(name = "订单金额", isStatistics = true)
     private BigDecimal totalPrice;
 
-    @Excel(name = "代收金额")
+    @Excel(name = "定金", isStatistics = true)
+    private BigDecimal payPrice;
+
+    @Excel(name = "代收金额", isStatistics = true)
     private BigDecimal collectionPrice;
 
-    @Excel(name = "回款金额")
+    @Excel(name = "回款金额", isStatistics = true)
     private BigDecimal returnPrice;
 
     @Excel(name = "收件人电话")

+ 45 - 0
fs-service/src/main/java/com/fs/his/dto/FsFinanceOrderImportPreviewDTO.java

@@ -0,0 +1,45 @@
+package com.fs.his.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 财务回款导入预览DTO
+ */
+@Data
+public class FsFinanceOrderImportPreviewDTO {
+
+    /** 快递单号 */
+    private String deliverySn;
+
+    /** 订单编号(匹配到的) */
+    private String orderCode;
+
+    /** 订单ID(匹配到的) */
+    private Long orderId;
+
+    /** 订单金额(匹配到的) */
+    private BigDecimal totalPrice;
+
+    /** 定金(匹配到的) */
+    private BigDecimal payPrice;
+
+    /** 代收金额(匹配到的) */
+    private BigDecimal collectionPrice;
+
+    /** 回款金额(来自导入文件) */
+    private BigDecimal returnPrice;
+
+    /** 回款时间(来自导入文件) */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date returnTime;
+
+    /** 是否匹配到订单 */
+    private boolean matched;
+
+    /** 失败原因 */
+    private String failReason;
+}

+ 3 - 0
fs-service/src/main/resources/mapper/his/FsExternalOrderMapper.xml

@@ -494,6 +494,7 @@
             o.delivery_name AS deliveryName,
             o.delivery_sn AS deliverySn,
             o.total_price AS totalPrice,
+            o.pay_price AS payPrice,
             o.collection_price AS collectionPrice,
             o.return_price AS returnPrice,
             o.receiver_phone AS receiverPhone,
@@ -927,11 +928,13 @@
     <select id="selectFinanceOrderListVOSum" parameterType="FsExternalOrder" resultType="java.util.Map">
         SELECT
             SUM(t.totalPrice) AS totalPrice,
+            SUM(t.payPrice) AS payPrice,
             SUM(t.collectionPrice) AS collectionPrice,
             SUM(t.returnPrice) AS returnPrice
         FROM (
             SELECT
                 o.total_price AS totalPrice,
+                o.pay_price AS payPrice,
                 o.collection_price AS collectionPrice,
                 o.return_price AS returnPrice
             FROM fs_external_order o

+ 19 - 11
fs-user-app/src/main/java/com/fs/app/controller/UserController.java

@@ -113,20 +113,28 @@ public class UserController extends  AppBaseController {
             return R.ok().put("data",new ArrayList<>());
         }
 
-        // 有销售身份(companyUserToken)可搜全部;否则按客户限制,仅允许 C/D 前缀
-        if (getCompanyUserIdOrNull() == null) {
-            String keywords = param.getKeywords().trim();
-            if (keywords.length() < 2) {
-                return R.ok().put("data", new ArrayList<>());
-            }
+        // 无论是否有销售身份,都判断 keywords 是否带字母前缀,带了就去掉
+        String keywords = param.getKeywords().trim();
+        if (keywords.length() > 0 && Character.isLetter(keywords.charAt(0))) {
             char prefix = Character.toUpperCase(keywords.charAt(0));
-            if (prefix != 'C' && prefix != 'D') {
-                // 非 C/D 开头(如 U 或其他)不给展示
-                return R.ok().put("data", new ArrayList<>());
+            // 非销售身份仅允许 C/D 前缀
+            if (getCompanyUserIdOrNull() == null) {
+                if (keywords.length() < 2) {
+                    return R.ok().put("data", new ArrayList<>());
+                }
+                if (prefix != 'C' && prefix != 'D') {
+                    // 非 C/D 开头(如 U 或其他)不给展示
+                    return R.ok().put("data", new ArrayList<>());
+                }
+                param.setOnlySales(true);
+                param.setSearchPrefix(String.valueOf(prefix));
             }
-            param.setOnlySales(true);
-            param.setSearchPrefix(String.valueOf(prefix));
             param.setKeywords(keywords.substring(1));
+        } else {
+            // 没有带字母前缀的情况,非销售身份不展示
+            if (getCompanyUserIdOrNull() == null) {
+                return R.ok().put("data", new ArrayList<>());
+            }
         }
 
         PageHelper.startPage(param.getPageNum(), param.getPageSize());