1
This commit is contained in:
@@ -423,48 +423,48 @@ public class InstructionServiceImpl implements IInstructionService {
|
|||||||
|
|
||||||
// ==================== 追加:按下单人分组统计 ====================
|
// ==================== 追加:按下单人分组统计 ====================
|
||||||
outputs.add("\n━━━━━━━ 按下单人统计 ━━━━━━━");
|
outputs.add("\n━━━━━━━ 按下单人统计 ━━━━━━━");
|
||||||
|
|
||||||
// 按下单人分组(过滤掉拍错退款)
|
// 按下单人分组(过滤掉拍错退款)
|
||||||
Map<String, List<JDOrder>> byBuyer = filtered.stream()
|
Map<String, List<JDOrder>> byBuyer = filtered.stream()
|
||||||
.filter(o -> o.getStatus() == null || !"拍错退款".equals(o.getStatus()))
|
.filter(o -> o.getStatus() == null || !"拍错退款".equals(o.getStatus()))
|
||||||
.filter(o -> o.getBuyer() != null && !o.getBuyer().isEmpty())
|
.filter(o -> o.getBuyer() != null && !o.getBuyer().isEmpty())
|
||||||
.collect(Collectors.groupingBy(JDOrder::getBuyer));
|
.collect(Collectors.groupingBy(JDOrder::getBuyer));
|
||||||
|
|
||||||
List<Map.Entry<String, List<JDOrder>>> buyerEntries = new ArrayList<>(byBuyer.entrySet());
|
List<Map.Entry<String, List<JDOrder>>> buyerEntries = new ArrayList<>(byBuyer.entrySet());
|
||||||
buyerEntries.sort(Comparator.comparing(en -> en.getKey() == null ? "" : en.getKey()));
|
buyerEntries.sort(Comparator.comparing(en -> en.getKey() == null ? "" : en.getKey()));
|
||||||
|
|
||||||
for (Map.Entry<String, List<JDOrder>> e : buyerEntries) {
|
for (Map.Entry<String, List<JDOrder>> e : buyerEntries) {
|
||||||
String buyer = e.getKey() != null ? e.getKey() : "未提供";
|
String buyer = e.getKey() != null ? e.getKey() : "未提供";
|
||||||
List<JDOrder> orders = e.getValue();
|
List<JDOrder> orders = e.getValue();
|
||||||
|
|
||||||
Map<String, Long> byModel = orders.stream()
|
Map<String, Long> byModel = orders.stream()
|
||||||
.collect(Collectors.groupingBy(JDOrder::getModelNumber, Collectors.counting()));
|
.collect(Collectors.groupingBy(JDOrder::getModelNumber, Collectors.counting()));
|
||||||
|
|
||||||
int totalCount = 0;
|
int totalCount = 0;
|
||||||
StringBuilder summary = new StringBuilder();
|
StringBuilder summary = new StringBuilder();
|
||||||
List<Map.Entry<String, Long>> modelEntries = new ArrayList<>(byModel.entrySet());
|
List<Map.Entry<String, Long>> modelEntries = new ArrayList<>(byModel.entrySet());
|
||||||
modelEntries.sort(Comparator.comparing(en -> en.getKey() == null ? "" : en.getKey()));
|
modelEntries.sort(Comparator.comparing(en -> en.getKey() == null ? "" : en.getKey()));
|
||||||
|
|
||||||
// 记录该下单人每个型号的最高单价订单
|
// 记录该下单人每个型号的最高单价订单
|
||||||
Map<String, JDOrder> buyerMaxPriceOrders = new HashMap<>();
|
Map<String, JDOrder> buyerMaxPriceOrders = new HashMap<>();
|
||||||
Map<String, Integer> buyerModelCounts = new HashMap<>();
|
Map<String, Integer> buyerModelCounts = new HashMap<>();
|
||||||
|
|
||||||
for (Map.Entry<String, Long> em : modelEntries) {
|
for (Map.Entry<String, Long> em : modelEntries) {
|
||||||
int c = em.getValue().intValue();
|
int c = em.getValue().intValue();
|
||||||
totalCount += c;
|
totalCount += c;
|
||||||
String model = em.getKey() != null ? em.getKey() : "未知";
|
String model = em.getKey() != null ? em.getKey() : "未知";
|
||||||
|
|
||||||
summary.append("型号:").append(model).append(" 数量:").append(c).append("\n");
|
summary.append("型号:").append(model).append(" 数量:").append(c).append("\n");
|
||||||
|
|
||||||
buyerModelCounts.put(model, c);
|
buyerModelCounts.put(model, c);
|
||||||
|
|
||||||
// 找到该型号价格最高的订单
|
// 找到该型号价格最高的订单
|
||||||
for (JDOrder order : orders) {
|
for (JDOrder order : orders) {
|
||||||
if (model.equals(order.getModelNumber())) {
|
if (model.equals(order.getModelNumber())) {
|
||||||
JDOrder currentMax = buyerMaxPriceOrders.get(model);
|
JDOrder currentMax = buyerMaxPriceOrders.get(model);
|
||||||
if (currentMax == null ||
|
if (currentMax == null ||
|
||||||
(order.getPaymentAmount() != null &&
|
(order.getPaymentAmount() != null &&
|
||||||
(currentMax.getPaymentAmount() == null ||
|
(currentMax.getPaymentAmount() == null ||
|
||||||
order.getPaymentAmount() > currentMax.getPaymentAmount()))) {
|
order.getPaymentAmount() > currentMax.getPaymentAmount()))) {
|
||||||
buyerMaxPriceOrders.put(model, order);
|
buyerMaxPriceOrders.put(model, order);
|
||||||
}
|
}
|
||||||
@@ -472,7 +472,7 @@ public class InstructionServiceImpl implements IInstructionService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
summary.append("总计:").append(totalCount).append("\n详情:");
|
summary.append("总计:").append(totalCount).append("\n详情:");
|
||||||
|
|
||||||
List<JDOrder> sorted = orders.stream()
|
List<JDOrder> sorted = orders.stream()
|
||||||
.sorted(Comparator.comparing(JDOrder::getRemark, Comparator.nullsFirst(String::compareTo)))
|
.sorted(Comparator.comparing(JDOrder::getRemark, Comparator.nullsFirst(String::compareTo)))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
@@ -488,52 +488,52 @@ public class InstructionServiceImpl implements IInstructionService {
|
|||||||
.append("地址:").append(o.getAddress() != null ? o.getAddress() : "未提供").append("\n")
|
.append("地址:").append(o.getAddress() != null ? o.getAddress() : "未提供").append("\n")
|
||||||
.append("物流链接:\n").append(o.getLogisticsLink() != null ? o.getLogisticsLink() : "无");
|
.append("物流链接:\n").append(o.getLogisticsLink() != null ? o.getLogisticsLink() : "无");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 订单详情
|
// 订单详情
|
||||||
StringBuilder infoSingle = new StringBuilder();
|
StringBuilder infoSingle = new StringBuilder();
|
||||||
infoSingle.append("下单人:").append(buyer).append("\n").append(summary).append(detail).append("\n");
|
infoSingle.append("下单人:").append(buyer).append("\n").append(summary).append(detail).append("\n");
|
||||||
outputs.add(infoSingle.toString().trim());
|
outputs.add(infoSingle.toString().trim());
|
||||||
|
|
||||||
// 算钱文本(使用佣金支付)
|
// 算钱文本(使用佣金支付)
|
||||||
if (!buyerModelCounts.isEmpty()) {
|
if (!buyerModelCounts.isEmpty()) {
|
||||||
StringBuilder priceText = new StringBuilder();
|
StringBuilder priceText = new StringBuilder();
|
||||||
priceText.append("下单人:").append(buyer).append("\n");
|
priceText.append("下单人:").append(buyer).append("\n");
|
||||||
|
|
||||||
// 先输出型号和数量
|
// 先输出型号和数量
|
||||||
List<Map.Entry<String, Integer>> sortedEntries = buyerModelCounts.entrySet().stream()
|
List<Map.Entry<String, Integer>> sortedEntries = buyerModelCounts.entrySet().stream()
|
||||||
.sorted(Comparator.comparing(Map.Entry::getKey))
|
.sorted(Comparator.comparing(Map.Entry::getKey))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
for (Map.Entry<String, Integer> entry : sortedEntries) {
|
for (Map.Entry<String, Integer> entry : sortedEntries) {
|
||||||
String model = entry.getKey();
|
String model = entry.getKey();
|
||||||
int count = entry.getValue();
|
int count = entry.getValue();
|
||||||
priceText.append("型号:").append(model).append(" 数量:").append(count).append("\n");
|
priceText.append("型号:").append(model).append(" 数量:").append(count).append("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
priceText.append("\n");
|
priceText.append("\n");
|
||||||
|
|
||||||
// 输出金额计算(使用佣金支付字段)
|
// 输出金额计算(使用佣金支付字段)
|
||||||
double grandTotal = 0.0;
|
double grandTotal = 0.0;
|
||||||
StringBuilder calculationLines = new StringBuilder();
|
StringBuilder calculationLines = new StringBuilder();
|
||||||
List<Double> totalPricesList = new ArrayList<>();
|
List<Double> totalPricesList = new ArrayList<>();
|
||||||
|
|
||||||
for (Map.Entry<String, Integer> entry : sortedEntries) {
|
for (Map.Entry<String, Integer> entry : sortedEntries) {
|
||||||
String model = entry.getKey();
|
String model = entry.getKey();
|
||||||
int count = entry.getValue();
|
int count = entry.getValue();
|
||||||
|
|
||||||
// 获取该型号最高价格的订单
|
// 获取该型号最高价格的订单
|
||||||
JDOrder maxPriceOrder = buyerMaxPriceOrders.get(model);
|
JDOrder maxPriceOrder = buyerMaxPriceOrders.get(model);
|
||||||
double singlePayment = 0.0;
|
double singlePayment = 0.0;
|
||||||
double singleRebate = 0.0;
|
double singleRebate = 0.0;
|
||||||
|
|
||||||
if (maxPriceOrder != null) {
|
if (maxPriceOrder != null) {
|
||||||
singlePayment = maxPriceOrder.getPaymentAmount() != null ? maxPriceOrder.getPaymentAmount() : 0.0;
|
singlePayment = maxPriceOrder.getPaymentAmount() != null ? maxPriceOrder.getPaymentAmount() : 0.0;
|
||||||
singleRebate = maxPriceOrder.getRebateAmount() != null ? maxPriceOrder.getRebateAmount() : 0.0;
|
singleRebate = maxPriceOrder.getRebateAmount() != null ? maxPriceOrder.getRebateAmount() : 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
singlePayment = Math.round(singlePayment * 100.0) / 100.0;
|
singlePayment = Math.round(singlePayment * 100.0) / 100.0;
|
||||||
singleRebate = Math.round(singleRebate * 100.0) / 100.0;
|
singleRebate = Math.round(singleRebate * 100.0) / 100.0;
|
||||||
|
|
||||||
// 从Redis获取佣金(支付)- 支付给下单人的佣金
|
// 从Redis获取佣金(支付)- 支付给下单人的佣金
|
||||||
double commissionPay = 0.0;
|
double commissionPay = 0.0;
|
||||||
try {
|
try {
|
||||||
@@ -549,17 +549,17 @@ public class InstructionServiceImpl implements IInstructionService {
|
|||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
// 如果获取失败,佣金为0
|
// 如果获取失败,佣金为0
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算净价(单台价格 - 返现 + 佣金支付)
|
// 计算净价(单台价格 - 返现 + 佣金支付)
|
||||||
double netPrice = singlePayment - singleRebate + commissionPay;
|
double netPrice = singlePayment - singleRebate + commissionPay;
|
||||||
netPrice = Math.round(netPrice * 100.0) / 100.0;
|
netPrice = Math.round(netPrice * 100.0) / 100.0;
|
||||||
|
|
||||||
// 计算总价
|
// 计算总价
|
||||||
double totalPrice = netPrice * count;
|
double totalPrice = netPrice * count;
|
||||||
totalPrice = Math.round(totalPrice * 100.0) / 100.0;
|
totalPrice = Math.round(totalPrice * 100.0) / 100.0;
|
||||||
totalPricesList.add(totalPrice);
|
totalPricesList.add(totalPrice);
|
||||||
grandTotal += totalPrice;
|
grandTotal += totalPrice;
|
||||||
|
|
||||||
// 格式:单台价格-返现+佣金=净价×数量=总价
|
// 格式:单台价格-返现+佣金=净价×数量=总价
|
||||||
if (count == 1) {
|
if (count == 1) {
|
||||||
calculationLines.append(String.format("%.2f-%.2f+%.2f=%.2f\n",
|
calculationLines.append(String.format("%.2f-%.2f+%.2f=%.2f\n",
|
||||||
@@ -569,9 +569,9 @@ public class InstructionServiceImpl implements IInstructionService {
|
|||||||
singlePayment, singleRebate, commissionPay, netPrice, count, totalPrice));
|
singlePayment, singleRebate, commissionPay, netPrice, count, totalPrice));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
priceText.append(calculationLines);
|
priceText.append(calculationLines);
|
||||||
|
|
||||||
// 输出汇总
|
// 输出汇总
|
||||||
if (sortedEntries.size() > 1) {
|
if (sortedEntries.size() > 1) {
|
||||||
priceText.append("\n");
|
priceText.append("\n");
|
||||||
@@ -584,7 +584,7 @@ public class InstructionServiceImpl implements IInstructionService {
|
|||||||
grandTotal = Math.round(grandTotal * 100.0) / 100.0;
|
grandTotal = Math.round(grandTotal * 100.0) / 100.0;
|
||||||
priceText.append(String.format("=%.2f", grandTotal));
|
priceText.append(String.format("=%.2f", grandTotal));
|
||||||
}
|
}
|
||||||
|
|
||||||
outputs.add(priceText.toString().trim());
|
outputs.add(priceText.toString().trim());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -606,12 +606,12 @@ public class InstructionServiceImpl implements IInstructionService {
|
|||||||
static {
|
static {
|
||||||
/*
|
/*
|
||||||
|
|
||||||
13103996539
|
13103996539
|
||||||
15514755615
|
15514755615
|
||||||
17746927935
|
17746927935
|
||||||
13140433517
|
13140433517
|
||||||
17746921532
|
17746921532
|
||||||
15514786055
|
15514786055
|
||||||
*/
|
*/
|
||||||
phoneWithTF.add("13103996539");
|
phoneWithTF.add("13103996539");
|
||||||
phoneWithTF.add("15514755615");
|
phoneWithTF.add("15514755615");
|
||||||
@@ -660,12 +660,12 @@ private String handleTF(String input) {
|
|||||||
// if ("13243039070".equals(phone) || "17530176250".equals(phone)) {
|
// if ("13243039070".equals(phone) || "17530176250".equals(phone)) {
|
||||||
// String today = new java.text.SimpleDateFormat("yyyy-MM-dd").format(new Date());
|
// String today = new java.text.SimpleDateFormat("yyyy-MM-dd").format(new Date());
|
||||||
// String usedPhonesKey = "phone_used_today:" + today;
|
// String usedPhonesKey = "phone_used_today:" + today;
|
||||||
|
|
||||||
// if (stringRedisTemplate != null) {
|
// if (stringRedisTemplate != null) {
|
||||||
// try {
|
// try {
|
||||||
// // 获取今天已经使用过的号码集合
|
// // 获取今天已经使用过的号码集合
|
||||||
// Set<String> usedPhonesToday = stringRedisTemplate.opsForSet().members(usedPhonesKey);
|
// Set<String> usedPhonesToday = stringRedisTemplate.opsForSet().members(usedPhonesKey);
|
||||||
|
|
||||||
// // 找出今天还没使用过的号码
|
// // 找出今天还没使用过的号码
|
||||||
// List<String> availablePhones = new ArrayList<>();
|
// List<String> availablePhones = new ArrayList<>();
|
||||||
// for (String p : phoneWithTF) {
|
// for (String p : phoneWithTF) {
|
||||||
@@ -673,7 +673,7 @@ private String handleTF(String input) {
|
|||||||
// availablePhones.add(p);
|
// availablePhones.add(p);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// if (!availablePhones.isEmpty()) {
|
// if (!availablePhones.isEmpty()) {
|
||||||
// // 随机选择一个今天还没用过的号码
|
// // 随机选择一个今天还没用过的号码
|
||||||
// phone = availablePhones.get(new Random().nextInt(availablePhones.size()));
|
// phone = availablePhones.get(new Random().nextInt(availablePhones.size()));
|
||||||
@@ -684,7 +684,7 @@ private String handleTF(String input) {
|
|||||||
// // phoneWithTF 中的号码今天都用完了,使用备用号码(轮换使用)
|
// // phoneWithTF 中的号码今天都用完了,使用备用号码(轮换使用)
|
||||||
// String backupUsedKey = "backup_phone_used_today:" + today;
|
// String backupUsedKey = "backup_phone_used_today:" + today;
|
||||||
// Set<String> backupUsedToday = stringRedisTemplate.opsForSet().members(backupUsedKey);
|
// Set<String> backupUsedToday = stringRedisTemplate.opsForSet().members(backupUsedKey);
|
||||||
|
|
||||||
// // 检查两个备用号码哪个还没用过
|
// // 检查两个备用号码哪个还没用过
|
||||||
// if (backupUsedToday == null || !backupUsedToday.contains("15639125541")) {
|
// if (backupUsedToday == null || !backupUsedToday.contains("15639125541")) {
|
||||||
// phone = "15639125541";
|
// phone = "15639125541";
|
||||||
@@ -700,7 +700,7 @@ private String handleTF(String input) {
|
|||||||
// phone = "15639125541";
|
// phone = "15639125541";
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// // 记录今天使用的备用号码
|
// // 记录今天使用的备用号码
|
||||||
// stringRedisTemplate.opsForSet().add(backupUsedKey, phone);
|
// stringRedisTemplate.opsForSet().add(backupUsedKey, phone);
|
||||||
// stringRedisTemplate.expire(backupUsedKey, 1, TimeUnit.DAYS);
|
// stringRedisTemplate.expire(backupUsedKey, 1, TimeUnit.DAYS);
|
||||||
@@ -1026,7 +1026,7 @@ private String handleTF(String input) {
|
|||||||
private String generateOrderText(String shengInput) {
|
private String generateOrderText(String shengInput) {
|
||||||
return generateOrderText(shengInput, null);
|
return generateOrderText(shengInput, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String generateOrderText(String shengInput, String providedThirdPartyOrderNo) {
|
private String generateOrderText(String shengInput, String providedThirdPartyOrderNo) {
|
||||||
String[] split = shengInput.split("\n");
|
String[] split = shengInput.split("\n");
|
||||||
// 第一行可能是 生 或 生{备注}
|
// 第一行可能是 生 或 生{备注}
|
||||||
@@ -1117,7 +1117,7 @@ private String handleTF(String input) {
|
|||||||
thirdPartyOrderNo = extractOrderNumber(fenxiao);
|
thirdPartyOrderNo = extractOrderNumber(fenxiao);
|
||||||
}
|
}
|
||||||
String thirdPartyOrderNoValue = (thirdPartyOrderNo != null && !thirdPartyOrderNo.isEmpty()) ? thirdPartyOrderNo : "";
|
String thirdPartyOrderNoValue = (thirdPartyOrderNo != null && !thirdPartyOrderNo.isEmpty()) ? thirdPartyOrderNo : "";
|
||||||
|
|
||||||
for (int i = 0; i < total; i++) {
|
for (int i = 0; i < total; i++) {
|
||||||
int currentCount = startCount + i;
|
int currentCount = startCount + i;
|
||||||
String orderId = today + String.format("%03d", currentCount);
|
String orderId = today + String.format("%03d", currentCount);
|
||||||
@@ -1236,7 +1236,7 @@ private String handleTF(String input) {
|
|||||||
if (existingByOrderId != null) {
|
if (existingByOrderId != null) {
|
||||||
// 如果是更新同一条记录(remark相同),则不提示重复
|
// 如果是更新同一条记录(remark相同),则不提示重复
|
||||||
if (!order.getRemark().equals(existingByOrderId.getRemark())) {
|
if (!order.getRemark().equals(existingByOrderId.getRemark())) {
|
||||||
String warn = "[炸弹] [炸弹] [炸弹] 录单警告!!! \n订单号重复!\n" +
|
String warn = "[炸弹] [炸弹] [炸弹] 录单警告!!! \n订单号重复!\n" +
|
||||||
"订单号:" + order.getOrderId() + "\n" +
|
"订单号:" + order.getOrderId() + "\n" +
|
||||||
"已存在的订单:" + existingByOrderId.getRemark() + "\n" +
|
"已存在的订单:" + existingByOrderId.getRemark() + "\n" +
|
||||||
"下单时间:" + new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(existingByOrderId.getOrderTime());
|
"下单时间:" + new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(existingByOrderId.getOrderTime());
|
||||||
@@ -1251,7 +1251,7 @@ private String handleTF(String input) {
|
|||||||
if (existingByLogistics != null) {
|
if (existingByLogistics != null) {
|
||||||
// 如果是更新同一条记录(remark相同),则不提示重复
|
// 如果是更新同一条记录(remark相同),则不提示重复
|
||||||
if (!order.getRemark().equals(existingByLogistics.getRemark())) {
|
if (!order.getRemark().equals(existingByLogistics.getRemark())) {
|
||||||
String warn = "[炸弹] [炸弹] [炸弹] 录单警告!!! \n物流链接重复!\n" +
|
String warn = "[炸弹] [炸弹] [炸弹] 录单警告!!! \n物流链接重复!\n" +
|
||||||
"物流链接:" + order.getLogisticsLink() + "\n" +
|
"物流链接:" + order.getLogisticsLink() + "\n" +
|
||||||
"已存在的订单:" + existingByLogistics.getRemark() + "\n" +
|
"已存在的订单:" + existingByLogistics.getRemark() + "\n" +
|
||||||
"下单时间:" + new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(existingByLogistics.getOrderTime());
|
"下单时间:" + new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(existingByLogistics.getOrderTime());
|
||||||
@@ -1315,7 +1315,7 @@ private String handleTF(String input) {
|
|||||||
try {
|
try {
|
||||||
if (tencentDocDelayedPushService != null) {
|
if (tencentDocDelayedPushService != null) {
|
||||||
tencentDocDelayedPushService.triggerDelayedPush();
|
tencentDocDelayedPushService.triggerDelayedPush();
|
||||||
System.out.println("✓ H-TF订单已触发延迟推送 - 单号: " + order.getRemark() +
|
System.out.println("✓ H-TF订单已触发延迟推送 - 单号: " + order.getRemark() +
|
||||||
", 第三方单号: " + order.getThirdPartyOrderNo());
|
", 第三方单号: " + order.getThirdPartyOrderNo());
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -1339,10 +1339,10 @@ private String handleTF(String input) {
|
|||||||
*/
|
*/
|
||||||
private String formatOrderForm(JDOrder order, String originalInput) {
|
private String formatOrderForm(JDOrder order, String originalInput) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
// 从原始输入中提取完整的物流链接
|
// 从原始输入中提取完整的物流链接
|
||||||
String originalLogisticsLink = extractOriginalLogisticsLink(originalInput);
|
String originalLogisticsLink = extractOriginalLogisticsLink(originalInput);
|
||||||
|
|
||||||
sb.append("单:\n");
|
sb.append("单:\n");
|
||||||
sb.append(order.getRemark() != null ? order.getRemark() : "").append("\n");
|
sb.append(order.getRemark() != null ? order.getRemark() : "").append("\n");
|
||||||
sb.append("备注:").append(order.getStatus() != null ? order.getStatus() : "").append("\n");
|
sb.append("备注:").append(order.getStatus() != null ? order.getStatus() : "").append("\n");
|
||||||
@@ -1367,10 +1367,10 @@ private String handleTF(String input) {
|
|||||||
sb.append(order.getBuyer() != null ? order.getBuyer() : "").append("\n");
|
sb.append(order.getBuyer() != null ? order.getBuyer() : "").append("\n");
|
||||||
sb.append("京粉实际价格:\n");
|
sb.append("京粉实际价格:\n");
|
||||||
sb.append(order.getJingfenActualPrice() != null ? order.getJingfenActualPrice().toString() : "").append("\n");
|
sb.append(order.getJingfenActualPrice() != null ? order.getJingfenActualPrice().toString() : "").append("\n");
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从原始输入中提取完整的物流链接文本(不做清理)
|
* 从原始输入中提取完整的物流链接文本(不做清理)
|
||||||
*/
|
*/
|
||||||
@@ -1393,15 +1393,15 @@ private String handleTF(String input) {
|
|||||||
private JDOrder parseOrderFromText(String input) {
|
private JDOrder parseOrderFromText(String input) {
|
||||||
// 不要替换所有空格,保留换行符用于正确解析
|
// 不要替换所有空格,保留换行符用于正确解析
|
||||||
Map<String, String> fields = new HashMap<>();
|
Map<String, String> fields = new HashMap<>();
|
||||||
|
|
||||||
// 先尝试新格式(带第三方单号和京粉实际价格)
|
// 先尝试新格式(带第三方单号和京粉实际价格)
|
||||||
extractField(input, fields, "单:", "备注:");
|
extractField(input, fields, "单:", "备注:");
|
||||||
extractField(input, fields, "备注:", "分销标记:");
|
extractField(input, fields, "备注:", "分销标记:");
|
||||||
|
|
||||||
// 检查是否有"第三方单号:"字段,如果没有则是旧格式
|
// 检查是否有"第三方单号:"字段,如果没有则是旧格式
|
||||||
boolean hasThirdPartyOrderNo = input.contains("第三方单号:");
|
boolean hasThirdPartyOrderNo = input.contains("第三方单号:");
|
||||||
boolean hasJingfenPrice = input.contains("京粉实际价格:");
|
boolean hasJingfenPrice = input.contains("京粉实际价格:");
|
||||||
|
|
||||||
if (hasThirdPartyOrderNo) {
|
if (hasThirdPartyOrderNo) {
|
||||||
// 新格式:有第三方单号字段
|
// 新格式:有第三方单号字段
|
||||||
extractField(input, fields, "分销标记:", "第三方单号:");
|
extractField(input, fields, "分销标记:", "第三方单号:");
|
||||||
@@ -1410,7 +1410,7 @@ private String handleTF(String input) {
|
|||||||
// 旧格式:分销标记后面直接是型号
|
// 旧格式:分销标记后面直接是型号
|
||||||
extractField(input, fields, "分销标记:", "型号:");
|
extractField(input, fields, "分销标记:", "型号:");
|
||||||
}
|
}
|
||||||
|
|
||||||
extractField(input, fields, "型号:", "链接:");
|
extractField(input, fields, "型号:", "链接:");
|
||||||
extractField(input, fields, "链接:", "下单付款:");
|
extractField(input, fields, "链接:", "下单付款:");
|
||||||
extractField(input, fields, "下单付款:", "后返金额:");
|
extractField(input, fields, "下单付款:", "后返金额:");
|
||||||
@@ -1418,7 +1418,7 @@ private String handleTF(String input) {
|
|||||||
extractField(input, fields, "地址:", "物流链接:");
|
extractField(input, fields, "地址:", "物流链接:");
|
||||||
extractField(input, fields, "物流链接:", "订单号:");
|
extractField(input, fields, "物流链接:", "订单号:");
|
||||||
extractField(input, fields, "订单号:", "下单人:");
|
extractField(input, fields, "订单号:", "下单人:");
|
||||||
|
|
||||||
// 京粉实际价格不从表单解析,而是从数据库查询获取
|
// 京粉实际价格不从表单解析,而是从数据库查询获取
|
||||||
// 如果表单中有这个字段,也提取出来(但不会使用,仅用于兼容)
|
// 如果表单中有这个字段,也提取出来(但不会使用,仅用于兼容)
|
||||||
if (hasJingfenPrice) {
|
if (hasJingfenPrice) {
|
||||||
@@ -1427,7 +1427,7 @@ private String handleTF(String input) {
|
|||||||
} else {
|
} else {
|
||||||
extractField(input, fields, "下单人:", "");
|
extractField(input, fields, "下单人:", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用正则提取下单人(兼容新旧格式)
|
// 使用正则提取下单人(兼容新旧格式)
|
||||||
String nextField = hasJingfenPrice ? "京粉实际价格:" : "单:";
|
String nextField = hasJingfenPrice ? "京粉实际价格:" : "单:";
|
||||||
java.util.regex.Pattern buyerPattern = java.util.regex.Pattern.compile("下单人:\\s*(.*?)\\s*(?=" + nextField + "|\\Z)", java.util.regex.Pattern.DOTALL);
|
java.util.regex.Pattern buyerPattern = java.util.regex.Pattern.compile("下单人:\\s*(.*?)\\s*(?=" + nextField + "|\\Z)", java.util.regex.Pattern.DOTALL);
|
||||||
@@ -1443,7 +1443,7 @@ private String handleTF(String input) {
|
|||||||
|
|
||||||
JDOrder order = new JDOrder();
|
JDOrder order = new JDOrder();
|
||||||
order.setRemark(fields.getOrDefault("单", null));
|
order.setRemark(fields.getOrDefault("单", null));
|
||||||
|
|
||||||
// 处理分销标记:如果提取的内容包含换行符,说明可能提取过度了,只取第一行
|
// 处理分销标记:如果提取的内容包含换行符,说明可能提取过度了,只取第一行
|
||||||
String distributionMark = fields.getOrDefault("分销标记", null);
|
String distributionMark = fields.getOrDefault("分销标记", null);
|
||||||
if (distributionMark != null && distributionMark.contains("\n")) {
|
if (distributionMark != null && distributionMark.contains("\n")) {
|
||||||
@@ -1464,7 +1464,7 @@ private String handleTF(String input) {
|
|||||||
distributionMark = "H-TF";
|
distributionMark = "H-TF";
|
||||||
}
|
}
|
||||||
order.setDistributionMark(distributionMark);
|
order.setDistributionMark(distributionMark);
|
||||||
|
|
||||||
// 优先从字段中获取第三方单号,如果没有则从分销标记中提取
|
// 优先从字段中获取第三方单号,如果没有则从分销标记中提取
|
||||||
String thirdPartyOrderNo = fields.getOrDefault("第三方单号", null);
|
String thirdPartyOrderNo = fields.getOrDefault("第三方单号", null);
|
||||||
if (thirdPartyOrderNo != null) {
|
if (thirdPartyOrderNo != null) {
|
||||||
@@ -1681,7 +1681,7 @@ private String handleTF(String input) {
|
|||||||
if (v == null) return "";
|
if (v == null) return "";
|
||||||
|
|
||||||
// 如果长度大于4,进行截取
|
// 如果长度大于4,进行截取
|
||||||
if (v.length() > 4) {
|
if (v.length() > 5) {
|
||||||
// 查找第一个左括号的位置
|
// 查找第一个左括号的位置
|
||||||
int leftParenIndex = v.indexOf('(');
|
int leftParenIndex = v.indexOf('(');
|
||||||
if (leftParenIndex > 0) {
|
if (leftParenIndex > 0) {
|
||||||
@@ -1730,7 +1730,7 @@ private String handleTF(String input) {
|
|||||||
/**
|
/**
|
||||||
* 异步写入订单到腾讯文档
|
* 异步写入订单到腾讯文档
|
||||||
* 当订单的分销标识是 H-TF 时,自动追加到腾讯文档表格
|
* 当订单的分销标识是 H-TF 时,自动追加到腾讯文档表格
|
||||||
*
|
*
|
||||||
* @param order 订单对象
|
* @param order 订单对象
|
||||||
*/
|
*/
|
||||||
private void asyncWriteToTencentDoc(JDOrder order) {
|
private void asyncWriteToTencentDoc(JDOrder order) {
|
||||||
@@ -1739,7 +1739,7 @@ private String handleTF(String input) {
|
|||||||
try {
|
try {
|
||||||
// Redis key前缀(用于获取文档配置)
|
// Redis key前缀(用于获取文档配置)
|
||||||
final String REDIS_KEY_PREFIX = "tencent:doc:auto:config:";
|
final String REDIS_KEY_PREFIX = "tencent:doc:auto:config:";
|
||||||
|
|
||||||
// 1. 从Token服务获取access-token(会自动从Redis读取并刷新)
|
// 1. 从Token服务获取access-token(会自动从Redis读取并刷新)
|
||||||
String accessToken = null;
|
String accessToken = null;
|
||||||
try {
|
try {
|
||||||
@@ -1749,12 +1749,12 @@ private String handleTF(String input) {
|
|||||||
System.err.println(" 提示:请先完成腾讯文档授权,访问 /jarvis/tendoc/authUrl 获取授权URL");
|
System.err.println(" 提示:请先完成腾讯文档授权,访问 /jarvis/tendoc/authUrl 获取授权URL");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 从Redis获取文档配置(fileId、sheetId 和 startRow)
|
// 2. 从Redis获取文档配置(fileId、sheetId 和 startRow)
|
||||||
String fileId = redisCache.getCacheObject(REDIS_KEY_PREFIX + "fileId");
|
String fileId = redisCache.getCacheObject(REDIS_KEY_PREFIX + "fileId");
|
||||||
String sheetId = redisCache.getCacheObject(REDIS_KEY_PREFIX + "sheetId");
|
String sheetId = redisCache.getCacheObject(REDIS_KEY_PREFIX + "sheetId");
|
||||||
Integer startRow = redisCache.getCacheObject(REDIS_KEY_PREFIX + "startRow");
|
Integer startRow = redisCache.getCacheObject(REDIS_KEY_PREFIX + "startRow");
|
||||||
|
|
||||||
// 如果Redis中没有,则使用配置文件中的默认值
|
// 如果Redis中没有,则使用配置文件中的默认值
|
||||||
if (fileId == null || fileId.isEmpty()) {
|
if (fileId == null || fileId.isEmpty()) {
|
||||||
fileId = tencentDocConfig.getFileId();
|
fileId = tencentDocConfig.getFileId();
|
||||||
@@ -1765,34 +1765,34 @@ private String handleTF(String input) {
|
|||||||
if (startRow == null) {
|
if (startRow == null) {
|
||||||
startRow = tencentDocConfig.getStartRow();
|
startRow = tencentDocConfig.getStartRow();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 验证配置是否完整
|
// 3. 验证配置是否完整
|
||||||
if (fileId == null || fileId.isEmpty() || sheetId == null || sheetId.isEmpty()) {
|
if (fileId == null || fileId.isEmpty() || sheetId == null || sheetId.isEmpty()) {
|
||||||
System.err.println("✗ H-TF订单文档配置不完整,跳过自动写入。" +
|
System.err.println("✗ H-TF订单文档配置不完整,跳过自动写入。" +
|
||||||
"\n 提示:请通过 POST /jarvis/tencentDoc/config 接口配置文档ID和工作表ID" +
|
"\n 提示:请通过 POST /jarvis/tencentDoc/config 接口配置文档ID和工作表ID" +
|
||||||
"\n fileId: " + (fileId != null && !fileId.isEmpty() ? fileId : "未配置") +
|
"\n fileId: " + (fileId != null && !fileId.isEmpty() ? fileId : "未配置") +
|
||||||
"\n sheetId: " + (sheetId != null && !sheetId.isEmpty() ? sheetId : "未配置") +
|
"\n sheetId: " + (sheetId != null && !sheetId.isEmpty() ? sheetId : "未配置") +
|
||||||
"\n startRow: " + (startRow != null ? startRow : "默认3"));
|
"\n startRow: " + (startRow != null ? startRow : "默认3"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. 调用腾讯文档服务追加订单数据
|
// 4. 调用腾讯文档服务追加订单数据
|
||||||
com.alibaba.fastjson2.JSONObject result = tencentDocService.appendLogisticsToSheet(
|
com.alibaba.fastjson2.JSONObject result = tencentDocService.appendLogisticsToSheet(
|
||||||
accessToken, fileId, sheetId, startRow, order);
|
accessToken, fileId, sheetId, startRow, order);
|
||||||
|
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
System.out.println("✓ H-TF订单已自动追加到腾讯文档" +
|
System.out.println("✓ H-TF订单已自动追加到腾讯文档" +
|
||||||
"\n 单号: " + order.getRemark() +
|
"\n 单号: " + order.getRemark() +
|
||||||
"\n 第三方单号: " + order.getThirdPartyOrderNo() +
|
"\n 第三方单号: " + order.getThirdPartyOrderNo() +
|
||||||
"\n 文档: " + fileId + "/" + sheetId);
|
"\n 文档: " + fileId + "/" + sheetId);
|
||||||
} else {
|
} else {
|
||||||
System.err.println("✗ 订单追加到腾讯文档失败 - 单号: " + order.getRemark() +
|
System.err.println("✗ 订单追加到腾讯文档失败 - 单号: " + order.getRemark() +
|
||||||
"\n API返回null,请检查access-token是否有效或文档是否存在");
|
"\n API返回null,请检查access-token是否有效或文档是否存在");
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// 写入失败不影响录单结果,仅记录错误日志
|
// 写入失败不影响录单结果,仅记录错误日志
|
||||||
System.err.println("✗ 异步写入腾讯文档失败 - 单号: " + order.getRemark() +
|
System.err.println("✗ 异步写入腾讯文档失败 - 单号: " + order.getRemark() +
|
||||||
"\n 错误: " + e.getMessage() +
|
"\n 错误: " + e.getMessage() +
|
||||||
"\n 提示:" +
|
"\n 提示:" +
|
||||||
"\n 1. 检查腾讯文档授权是否有效" +
|
"\n 1. 检查腾讯文档授权是否有效" +
|
||||||
"\n 2. 检查文档ID和工作表ID是否正确" +
|
"\n 2. 检查文档ID和工作表ID是否正确" +
|
||||||
|
|||||||
Reference in New Issue
Block a user