From 66c9dad8496a703d19d22c84ba373b8592f9dd2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8D=92?= Date: Mon, 27 Oct 2025 23:59:28 +0800 Subject: [PATCH] 1 --- .../ruoyi/jarvis/domain/ProductJdConfig.java | 26 ++- .../service/impl/InstructionServiceImpl.java | 181 +++++++++++++++++- .../impl/ProductJdConfigServiceImpl.java | 29 +++ 3 files changed, 232 insertions(+), 4 deletions(-) diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/domain/ProductJdConfig.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/domain/ProductJdConfig.java index 5e6af4b..354d36f 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/domain/ProductJdConfig.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/domain/ProductJdConfig.java @@ -18,9 +18,15 @@ public class ProductJdConfig extends BaseEntity /** 京东链接 */ private String jdUrl; - /** 佣金 */ + /** 佣金(旧字段,保留兼容) */ private BigDecimal commission; + /** 佣金(收取) - 从客户收取的佣金 */ + private BigDecimal commissionReceive; + + /** 佣金(支付) - 支付给下单人的佣金 */ + private BigDecimal commissionPay; + public ProductJdConfig() { } @@ -54,12 +60,30 @@ public class ProductJdConfig extends BaseEntity this.commission = commission; } + public BigDecimal getCommissionReceive() { + return commissionReceive; + } + + public void setCommissionReceive(BigDecimal commissionReceive) { + this.commissionReceive = commissionReceive; + } + + public BigDecimal getCommissionPay() { + return commissionPay; + } + + public void setCommissionPay(BigDecimal commissionPay) { + this.commissionPay = commissionPay; + } + @Override public String toString() { return "ProductJdConfig{" + "productModel='" + productModel + '\'' + ", jdUrl='" + jdUrl + '\'' + ", commission=" + commission + + ", commissionReceive=" + commissionReceive + + ", commissionPay=" + commissionPay + '}'; } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/InstructionServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/InstructionServiceImpl.java index f4eeb1c..2e10a50 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/InstructionServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/InstructionServiceImpl.java @@ -344,12 +344,17 @@ public class InstructionServiceImpl implements IInstructionService { singlePayment = Math.round(singlePayment * 100.0) / 100.0; singleRebate = Math.round(singleRebate * 100.0) / 100.0; - // 从Redis获取佣金 + // 从Redis获取佣金(收取) double commission = 0.0; try { com.ruoyi.jarvis.domain.ProductJdConfig config = productJdConfigService.selectProductJdConfigByModel(model); - if (config != null && config.getCommission() != null) { - commission = config.getCommission().doubleValue(); + if (config != null) { + // 优先使用新的佣金(收取)字段,如果没有则使用旧的commission字段 + if (config.getCommissionReceive() != null) { + commission = config.getCommissionReceive().doubleValue(); + } else if (config.getCommission() != null) { + commission = config.getCommission().doubleValue(); + } } } catch (Exception ex) { // 如果获取失败,佣金为0 @@ -399,6 +404,174 @@ public class InstructionServiceImpl implements IInstructionService { } } + // ==================== 追加:按下单人分组统计 ==================== + outputs.add("\n━━━━━━━ 按下单人统计 ━━━━━━━"); + + // 按下单人分组(过滤掉拍错退款) + Map> byBuyer = filtered.stream() + .filter(o -> o.getStatus() == null || !"拍错退款".equals(o.getStatus())) + .filter(o -> o.getBuyer() != null && !o.getBuyer().isEmpty()) + .collect(Collectors.groupingBy(JDOrder::getBuyer)); + + List>> buyerEntries = new ArrayList<>(byBuyer.entrySet()); + buyerEntries.sort(Comparator.comparing(en -> en.getKey() == null ? "" : en.getKey())); + + for (Map.Entry> e : buyerEntries) { + String buyer = e.getKey() != null ? e.getKey() : "未提供"; + List orders = e.getValue(); + + Map byModel = orders.stream() + .collect(Collectors.groupingBy(JDOrder::getModelNumber, Collectors.counting())); + + int totalCount = 0; + StringBuilder summary = new StringBuilder(); + List> modelEntries = new ArrayList<>(byModel.entrySet()); + modelEntries.sort(Comparator.comparing(en -> en.getKey() == null ? "" : en.getKey())); + + // 记录该下单人每个型号的最高单价订单 + Map buyerMaxPriceOrders = new HashMap<>(); + Map buyerModelCounts = new HashMap<>(); + + for (Map.Entry em : modelEntries) { + int c = em.getValue().intValue(); + totalCount += c; + String model = em.getKey() != null ? em.getKey() : "未知"; + + summary.append("型号:").append(model).append(" 数量:").append(c).append("\n"); + + buyerModelCounts.put(model, c); + + // 找到该型号价格最高的订单 + for (JDOrder order : orders) { + if (model.equals(order.getModelNumber())) { + JDOrder currentMax = buyerMaxPriceOrders.get(model); + if (currentMax == null || + (order.getPaymentAmount() != null && + (currentMax.getPaymentAmount() == null || + order.getPaymentAmount() > currentMax.getPaymentAmount()))) { + buyerMaxPriceOrders.put(model, order); + } + } + } + } + summary.append("总计:").append(totalCount).append("\n详情:"); + + List sorted = orders.stream() + .sorted(Comparator.comparing(JDOrder::getRemark, Comparator.nullsFirst(String::compareTo))) + .collect(Collectors.toList()); + StringBuilder detail = new StringBuilder(); + int idx = 0; + for (JDOrder o : sorted) { + if ("拍错退款".equals(o.getStatus())) continue; + idx++; + detail.append("\n").append(idx).append(" ────────────\n") + .append("单:").append(o.getRemark() != null ? o.getRemark() : "未提供").append("\n") + .append("备注:").append(o.getStatus() != null ? o.getStatus() : " ").append("\n") + .append("型号:").append(o.getModelNumber() != null ? o.getModelNumber() : "未提供").append("\n") + .append("地址:").append(o.getAddress() != null ? o.getAddress() : "未提供").append("\n") + .append("物流链接:\n").append(o.getLogisticsLink() != null ? o.getLogisticsLink() : "无"); + } + + // 订单详情 + StringBuilder infoSingle = new StringBuilder(); + infoSingle.append("下单人:").append(buyer).append("\n").append(summary).append(detail).append("\n"); + outputs.add(infoSingle.toString().trim()); + + // 算钱文本(使用佣金支付) + if (!buyerModelCounts.isEmpty()) { + StringBuilder priceText = new StringBuilder(); + priceText.append("下单人:").append(buyer).append("\n"); + + // 先输出型号和数量 + List> sortedEntries = buyerModelCounts.entrySet().stream() + .sorted(Comparator.comparing(Map.Entry::getKey)) + .collect(Collectors.toList()); + + for (Map.Entry entry : sortedEntries) { + String model = entry.getKey(); + int count = entry.getValue(); + priceText.append("型号:").append(model).append(" 数量:").append(count).append("\n"); + } + + priceText.append("\n"); + + // 输出金额计算(使用佣金支付字段) + double grandTotal = 0.0; + StringBuilder calculationLines = new StringBuilder(); + List totalPricesList = new ArrayList<>(); + + for (Map.Entry entry : sortedEntries) { + String model = entry.getKey(); + int count = entry.getValue(); + + // 获取该型号最高价格的订单 + JDOrder maxPriceOrder = buyerMaxPriceOrders.get(model); + double singlePayment = 0.0; + double singleRebate = 0.0; + + if (maxPriceOrder != null) { + singlePayment = maxPriceOrder.getPaymentAmount() != null ? maxPriceOrder.getPaymentAmount() : 0.0; + singleRebate = maxPriceOrder.getRebateAmount() != null ? maxPriceOrder.getRebateAmount() : 0.0; + } + + singlePayment = Math.round(singlePayment * 100.0) / 100.0; + singleRebate = Math.round(singleRebate * 100.0) / 100.0; + + // 从Redis获取佣金(支付)- 支付给下单人的佣金 + double commissionPay = 0.0; + try { + com.ruoyi.jarvis.domain.ProductJdConfig config = productJdConfigService.selectProductJdConfigByModel(model); + if (config != null) { + // 优先使用新的佣金(支付)字段,如果没有则使用旧的commission字段 + if (config.getCommissionPay() != null) { + commissionPay = config.getCommissionPay().doubleValue(); + } else if (config.getCommission() != null) { + commissionPay = config.getCommission().doubleValue(); + } + } + } catch (Exception ex) { + // 如果获取失败,佣金为0 + } + + // 计算净价(单台价格 - 返现 + 佣金支付) + double netPrice = singlePayment - singleRebate + commissionPay; + netPrice = Math.round(netPrice * 100.0) / 100.0; + + // 计算总价 + double totalPrice = netPrice * count; + totalPrice = Math.round(totalPrice * 100.0) / 100.0; + totalPricesList.add(totalPrice); + grandTotal += totalPrice; + + // 格式:单台价格-返现+佣金=净价×数量=总价 + if (count == 1) { + calculationLines.append(String.format("%.2f-%.2f+%.2f=%.2f\n", + singlePayment, singleRebate, commissionPay, totalPrice)); + } else { + calculationLines.append(String.format("%.2f-%.2f+%.2f=%.2f×%d=%.2f\n", + singlePayment, singleRebate, commissionPay, netPrice, count, totalPrice)); + } + } + + priceText.append(calculationLines); + + // 输出汇总 + if (sortedEntries.size() > 1) { + priceText.append("\n"); + for (int i = 0; i < totalPricesList.size(); i++) { + if (i > 0) { + priceText.append("+"); + } + priceText.append(String.format("%.2f", totalPricesList.get(i))); + } + grandTotal = Math.round(grandTotal * 100.0) / 100.0; + priceText.append(String.format("=%.2f", grandTotal)); + } + + outputs.add(priceText.toString().trim()); + } + } + // ==================== 按下单人统计结束 ==================== return outputs.isEmpty() ? Collections.singletonList("无数据") : outputs; } @@ -862,6 +1035,8 @@ private String handleTF(String input) { order.setLogisticsLink(extractFirstUrl(fields.getOrDefault("物流链接", ""))); order.setOrderId(fields.getOrDefault("订单号", null)); order.setBuyer(fields.getOrDefault("下单人", null)); + // 默认参与统计 + order.setIsCountEnabled(1); try { String dateStr = fields.getOrDefault("单", "").split(" ")[0]; java.text.SimpleDateFormat sdf2 = new java.text.SimpleDateFormat("yyyy-MM-dd"); diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/ProductJdConfigServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/ProductJdConfigServiceImpl.java index 9c4c259..8d1f236 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/ProductJdConfigServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/ProductJdConfigServiceImpl.java @@ -81,6 +81,8 @@ public class ProductJdConfigServiceImpl implements IProductJdConfigService ProductJdConfig config = new ProductJdConfig(); config.setProductModel((String) map.get("productModel")); config.setJdUrl((String) map.get("jdUrl")); + + // 处理旧的佣金字段(兼容) Object commissionObj = map.get("commission"); if (commissionObj != null) { if (commissionObj instanceof BigDecimal) { @@ -91,6 +93,31 @@ public class ProductJdConfigServiceImpl implements IProductJdConfigService config.setCommission(new BigDecimal(commissionObj.toString())); } } + + // 处理佣金(收取) + Object commissionReceiveObj = map.get("commissionReceive"); + if (commissionReceiveObj != null) { + if (commissionReceiveObj instanceof BigDecimal) { + config.setCommissionReceive((BigDecimal) commissionReceiveObj); + } else if (commissionReceiveObj instanceof Number) { + config.setCommissionReceive(new BigDecimal(commissionReceiveObj.toString())); + } else { + config.setCommissionReceive(new BigDecimal(commissionReceiveObj.toString())); + } + } + + // 处理佣金(支付) + Object commissionPayObj = map.get("commissionPay"); + if (commissionPayObj != null) { + if (commissionPayObj instanceof BigDecimal) { + config.setCommissionPay((BigDecimal) commissionPayObj); + } else if (commissionPayObj instanceof Number) { + config.setCommissionPay(new BigDecimal(commissionPayObj.toString())); + } else { + config.setCommissionPay(new BigDecimal(commissionPayObj.toString())); + } + } + return config; } return null; @@ -124,6 +151,8 @@ public class ProductJdConfigServiceImpl implements IProductJdConfigService map.put("productModel", productJdConfig.getProductModel()); map.put("jdUrl", productJdConfig.getJdUrl()); map.put("commission", productJdConfig.getCommission() != null ? productJdConfig.getCommission() : BigDecimal.ZERO); + map.put("commissionReceive", productJdConfig.getCommissionReceive() != null ? productJdConfig.getCommissionReceive() : BigDecimal.ZERO); + map.put("commissionPay", productJdConfig.getCommissionPay() != null ? productJdConfig.getCommissionPay() : BigDecimal.ZERO); redisCache.setCacheMap(PRODUCT_JD_CONFIG_KEY + productJdConfig.getProductModel(), map); return 1; }