1
This commit is contained in:
@@ -1290,9 +1290,9 @@ public class InstructionServiceImpl implements IInstructionService {
|
|||||||
// 与 JDUtil.parseOrderFromText 一致的模板字段
|
// 与 JDUtil.parseOrderFromText 一致的模板字段
|
||||||
JDOrder order = parseOrderFromText(originalInput);
|
JDOrder order = parseOrderFromText(originalInput);
|
||||||
|
|
||||||
// 字段校验并返回缺失项
|
// 字段校验并返回缺失项(根据新模板格式,单号存储在remark字段中)
|
||||||
StringBuilder missing = new StringBuilder();
|
StringBuilder missing = new StringBuilder();
|
||||||
if (isEmpty(order.getOrderId())) missing.append("单号\n");
|
if (isEmpty(order.getRemark())) missing.append("单号\n");
|
||||||
if (isEmpty(order.getBuyer())) missing.append("下单人\n");
|
if (isEmpty(order.getBuyer())) missing.append("下单人\n");
|
||||||
if (order.getPaymentAmount() == null || order.getPaymentAmount() == 0) missing.append("下单价格\n");
|
if (order.getPaymentAmount() == null || order.getPaymentAmount() == 0) missing.append("下单价格\n");
|
||||||
if (order.getRebateAmount() == null) missing.append("后返金额\n");
|
if (order.getRebateAmount() == null) missing.append("后返金额\n");
|
||||||
@@ -1480,58 +1480,41 @@ public class InstructionServiceImpl implements IInstructionService {
|
|||||||
|
|
||||||
// 参照 JDUtil.parseOrderFromText
|
// 参照 JDUtil.parseOrderFromText
|
||||||
private JDOrder parseOrderFromText(String input) {
|
private JDOrder parseOrderFromText(String input) {
|
||||||
// 不要替换所有空格,保留换行符用于正确解析
|
// 检测是否是新格式(包含分隔线"—————————"或新格式字段标签)
|
||||||
|
boolean isNewFormat = input.contains("—————————") ||
|
||||||
|
input.contains("下单链接(必须用这个):") ||
|
||||||
|
input.contains("下单地址(注意带分机):") ||
|
||||||
|
input.contains("下单人(需填):") ||
|
||||||
|
input.contains("下单付款(注意核对):") ||
|
||||||
|
input.contains("后返金额(注意核对):") ||
|
||||||
|
input.contains("订单号(需填):") ||
|
||||||
|
input.contains("物流链接(需填):") ||
|
||||||
|
input.contains("备注(下单号码有变动/没法带分机号的写这里):");
|
||||||
|
|
||||||
|
System.out.println("=== 开始解析订单文本 ===");
|
||||||
|
System.out.println("是否为新格式: " + isNewFormat);
|
||||||
|
System.out.println("输入文本长度: " + (input != null ? input.length() : 0));
|
||||||
|
|
||||||
Map<String, String> fields = new HashMap<>();
|
Map<String, String> fields = new HashMap<>();
|
||||||
|
|
||||||
// 先尝试新格式(带第三方单号和京粉实际价格)
|
if (isNewFormat) {
|
||||||
extractField(input, fields, "单:", "备注:");
|
// 新格式:使用新的解析方法(支持分隔线)
|
||||||
extractField(input, fields, "备注:", "分销标记:");
|
System.out.println("使用新格式解析方法");
|
||||||
|
parseNewFormat(input, fields);
|
||||||
// 检查是否有"第三方单号:"字段,如果没有则是旧格式
|
|
||||||
boolean hasThirdPartyOrderNo = input.contains("第三方单号:");
|
|
||||||
boolean hasJingfenPrice = input.contains("京粉实际价格:");
|
|
||||||
|
|
||||||
if (hasThirdPartyOrderNo) {
|
|
||||||
// 新格式:有第三方单号字段
|
|
||||||
extractField(input, fields, "分销标记:", "第三方单号:");
|
|
||||||
extractField(input, fields, "第三方单号:", "型号:");
|
|
||||||
} else {
|
} else {
|
||||||
// 旧格式:分销标记后面直接是型号
|
// 旧格式:保持原有逻辑不变
|
||||||
extractField(input, fields, "分销标记:", "型号:");
|
System.out.println("使用旧格式解析方法");
|
||||||
|
parseOldFormat(input, fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
extractField(input, fields, "型号:", "链接:");
|
System.out.println("解析到的字段: " + fields);
|
||||||
extractField(input, fields, "链接:", "下单付款:");
|
|
||||||
extractField(input, fields, "下单付款:", "后返金额:");
|
|
||||||
extractField(input, fields, "后返金额:", "地址:");
|
|
||||||
extractField(input, fields, "地址:", "物流链接:");
|
|
||||||
extractField(input, fields, "物流链接:", "订单号:");
|
|
||||||
extractField(input, fields, "订单号:", "下单人:");
|
|
||||||
|
|
||||||
// 京粉实际价格不从表单解析,而是从数据库查询获取
|
|
||||||
// 如果表单中有这个字段,也提取出来(但不会使用,仅用于兼容)
|
|
||||||
if (hasJingfenPrice) {
|
|
||||||
extractField(input, fields, "下单人:", "京粉实际价格:");
|
|
||||||
extractField(input, fields, "京粉实际价格:", "");
|
|
||||||
} else {
|
|
||||||
extractField(input, fields, "下单人:", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用正则提取下单人(兼容新旧格式)
|
|
||||||
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.Matcher buyerMatcher = buyerPattern.matcher(input);
|
|
||||||
if (buyerMatcher.find()) {
|
|
||||||
String buyer = buyerMatcher.group(1).trim();
|
|
||||||
// 如果提取的内容包含换行符,可能是提取过度了,只取第一行
|
|
||||||
if (buyer.contains("\n")) {
|
|
||||||
buyer = buyer.split("\n")[0].trim();
|
|
||||||
}
|
|
||||||
fields.put("下单人", buyer);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// 构建 JDOrder 对象
|
||||||
JDOrder order = new JDOrder();
|
JDOrder order = new JDOrder();
|
||||||
order.setRemark(fields.getOrDefault("单", null));
|
// 单号(格式:2025-12-13 006)
|
||||||
|
String orderNo = fields.getOrDefault("单", "").trim();
|
||||||
|
order.setRemark(orderNo);
|
||||||
|
System.out.println("单号(remark): " + orderNo);
|
||||||
|
|
||||||
// 处理分销标记:如果提取的内容包含换行符,说明可能提取过度了,只取第一行
|
// 处理分销标记:如果提取的内容包含换行符,说明可能提取过度了,只取第一行
|
||||||
String distributionMark = fields.getOrDefault("分销标记", null);
|
String distributionMark = fields.getOrDefault("分销标记", null);
|
||||||
@@ -1568,34 +1551,218 @@ public class InstructionServiceImpl implements IInstructionService {
|
|||||||
// 保存第三方单号到订单对象
|
// 保存第三方单号到订单对象
|
||||||
order.setThirdPartyOrderNo(thirdPartyOrderNo != null && !thirdPartyOrderNo.trim().isEmpty() ? thirdPartyOrderNo.trim() : null);
|
order.setThirdPartyOrderNo(thirdPartyOrderNo != null && !thirdPartyOrderNo.trim().isEmpty() ? thirdPartyOrderNo.trim() : null);
|
||||||
order.setModelNumber(fields.getOrDefault("型号", null));
|
order.setModelNumber(fields.getOrDefault("型号", null));
|
||||||
order.setLink(fields.getOrDefault("链接", null));
|
System.out.println("型号: " + order.getModelNumber());
|
||||||
|
|
||||||
|
// 下单链接(新格式)或链接(旧格式)
|
||||||
|
String link = fields.getOrDefault("下单链接(必须用这个)", null);
|
||||||
|
if (link == null) {
|
||||||
|
link = fields.getOrDefault("链接", null);
|
||||||
|
}
|
||||||
|
order.setLink(link);
|
||||||
|
System.out.println("链接: " + link);
|
||||||
|
|
||||||
|
// 备注字段
|
||||||
order.setStatus(fields.getOrDefault("备注", null));
|
order.setStatus(fields.getOrDefault("备注", null));
|
||||||
try {
|
System.out.println("备注: " + order.getStatus());
|
||||||
order.setPaymentAmount(Double.parseDouble(fields.getOrDefault("下单付款", "0")));
|
|
||||||
} catch (Exception ignore) {
|
// 下单付款(新格式)或下单付款(旧格式)
|
||||||
|
String paymentStr = fields.getOrDefault("下单付款(注意核对)", null);
|
||||||
|
if (paymentStr == null) {
|
||||||
|
paymentStr = fields.getOrDefault("下单付款", "0");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
order.setRebateAmount(Double.parseDouble(fields.getOrDefault("后返金额", "0")));
|
paymentStr = paymentStr.trim();
|
||||||
} catch (Exception ignore) {
|
if (!paymentStr.isEmpty() && !paymentStr.equals("0")) {
|
||||||
|
order.setPaymentAmount(Double.parseDouble(paymentStr));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("解析下单付款失败: " + paymentStr + ", error: " + e.getMessage());
|
||||||
}
|
}
|
||||||
order.setAddress(fields.getOrDefault("地址", null));
|
System.out.println("下单付款: " + order.getPaymentAmount());
|
||||||
// 写入数据库时清理物流链接,只保留URL
|
|
||||||
order.setLogisticsLink(extractFirstUrl(fields.getOrDefault("物流链接", "")));
|
// 后返金额(新格式)或后返金额(旧格式)
|
||||||
order.setOrderId(fields.getOrDefault("订单号", null));
|
String rebateStr = fields.getOrDefault("后返金额(注意核对)", null);
|
||||||
order.setBuyer(fields.getOrDefault("下单人", null));
|
if (rebateStr == null) {
|
||||||
|
rebateStr = fields.getOrDefault("后返金额", "0");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
rebateStr = rebateStr.trim();
|
||||||
|
if (!rebateStr.isEmpty() && !rebateStr.equals("0")) {
|
||||||
|
order.setRebateAmount(Double.parseDouble(rebateStr));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("解析后返金额失败: " + rebateStr + ", error: " + e.getMessage());
|
||||||
|
}
|
||||||
|
System.out.println("后返金额: " + order.getRebateAmount());
|
||||||
|
|
||||||
|
// 下单地址(新格式)或地址(旧格式)
|
||||||
|
String address = fields.getOrDefault("下单地址(注意带分机)", null);
|
||||||
|
if (address == null) {
|
||||||
|
address = fields.getOrDefault("地址", null);
|
||||||
|
}
|
||||||
|
order.setAddress(address);
|
||||||
|
System.out.println("地址: " + (address != null && address.length() > 50 ? address.substring(0, 50) + "..." : address));
|
||||||
|
|
||||||
|
// 物流链接(新格式)或物流链接(旧格式)
|
||||||
|
String logisticsLink = fields.getOrDefault("物流链接(需填)", null);
|
||||||
|
if (logisticsLink == null) {
|
||||||
|
logisticsLink = fields.getOrDefault("物流链接", "");
|
||||||
|
}
|
||||||
|
order.setLogisticsLink(extractFirstUrl(logisticsLink));
|
||||||
|
System.out.println("物流链接: " + order.getLogisticsLink());
|
||||||
|
|
||||||
|
// 订单号(新格式)或订单号(旧格式)
|
||||||
|
String orderId = fields.getOrDefault("订单号(需填)", null);
|
||||||
|
if (orderId == null) {
|
||||||
|
orderId = fields.getOrDefault("订单号", null);
|
||||||
|
}
|
||||||
|
order.setOrderId(orderId);
|
||||||
|
System.out.println("订单号: " + orderId);
|
||||||
|
|
||||||
|
// 下单人(新格式)或下单人(旧格式)
|
||||||
|
String buyer = fields.getOrDefault("下单人(需填)", null);
|
||||||
|
if (buyer == null) {
|
||||||
|
buyer = fields.getOrDefault("下单人", null);
|
||||||
|
}
|
||||||
|
order.setBuyer(buyer);
|
||||||
|
System.out.println("下单人: " + buyer);
|
||||||
// 京粉实际价格不从表单解析,而是从数据库order_rows表中查询获取
|
// 京粉实际价格不从表单解析,而是从数据库order_rows表中查询获取
|
||||||
// 默认参与统计
|
// 默认参与统计
|
||||||
order.setIsCountEnabled(1);
|
order.setIsCountEnabled(1);
|
||||||
|
|
||||||
|
// 设置下单时间
|
||||||
try {
|
try {
|
||||||
String dateStr = fields.getOrDefault("单", "").split(" ")[0];
|
if (!orderNo.isEmpty()) {
|
||||||
java.text.SimpleDateFormat sdf2 = new java.text.SimpleDateFormat("yyyy-MM-dd");
|
String dateStr = orderNo.split("\\s+")[0]; // 从"2025-12-13 006"中提取日期部分
|
||||||
order.setOrderTime(sdf2.parse(dateStr));
|
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
order.setOrderTime(sdf.parse(dateStr));
|
||||||
|
System.out.println("下单时间: " + order.getOrderTime());
|
||||||
|
} else {
|
||||||
|
order.setOrderTime(new Date());
|
||||||
|
System.out.println("下单时间(默认): " + order.getOrderTime());
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
order.setOrderTime(new Date());
|
order.setOrderTime(new Date());
|
||||||
|
System.out.println("解析下单时间失败: " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
System.out.println("=== 解析完成 ===");
|
||||||
return order;
|
return order;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 解析新格式(带分隔线)
|
||||||
|
private void parseNewFormat(String input, Map<String, String> fields) {
|
||||||
|
extractFieldWithSeparator(input, fields, "单:", "分销标记:");
|
||||||
|
extractFieldWithSeparator(input, fields, "分销标记:", "第三方单号:");
|
||||||
|
extractFieldWithSeparator(input, fields, "第三方单号:", "下单链接(必须用这个):");
|
||||||
|
extractFieldWithSeparator(input, fields, "下单链接(必须用这个):", "下单地址(注意带分机):");
|
||||||
|
extractFieldWithSeparator(input, fields, "下单地址(注意带分机):", "型号:");
|
||||||
|
extractFieldWithSeparator(input, fields, "型号:", "下单人(需填):");
|
||||||
|
extractFieldWithSeparator(input, fields, "下单人(需填):", "下单付款(注意核对):");
|
||||||
|
extractFieldWithSeparator(input, fields, "下单付款(注意核对):", "后返金额(注意核对):");
|
||||||
|
extractFieldWithSeparator(input, fields, "后返金额(注意核对):", "订单号(需填):");
|
||||||
|
extractFieldWithSeparator(input, fields, "订单号(需填):", "物流链接(需填):");
|
||||||
|
extractFieldWithSeparator(input, fields, "物流链接(需填):", "备注(下单号码有变动/没法带分机号的写这里):");
|
||||||
|
|
||||||
|
// 手动提取"备注"字段(最后一个字段,可能后面有分隔线或"京粉实际价格")
|
||||||
|
java.util.regex.Pattern remarkPattern = java.util.regex.Pattern.compile("备注(下单号码有变动/没法带分机号的写这里):[\\s\\n]*([\\s\\S]*?)[\\s\\n]*(?=—————————|京粉实际价格|\\Z)", java.util.regex.Pattern.DOTALL);
|
||||||
|
java.util.regex.Matcher remarkMatcher = remarkPattern.matcher(input);
|
||||||
|
if (remarkMatcher.find()) {
|
||||||
|
String remarkValue = remarkMatcher.group(1);
|
||||||
|
if (remarkValue != null) {
|
||||||
|
remarkValue = remarkValue.trim();
|
||||||
|
// 去掉可能的分隔线
|
||||||
|
remarkValue = remarkValue.replaceAll("^—————————[\\s\\n]*", "").trim();
|
||||||
|
if (!remarkValue.isEmpty()) {
|
||||||
|
fields.put("备注", remarkValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析旧格式(保持原有逻辑不变)
|
||||||
|
private void parseOldFormat(String input, Map<String, String> fields) {
|
||||||
|
extractField(input, fields, "单:", "备注:");
|
||||||
|
extractField(input, fields, "备注:", "分销标记:");
|
||||||
|
|
||||||
|
// 检查是否有"第三方单号:"字段
|
||||||
|
boolean hasThirdPartyOrderNo = input.contains("第三方单号:");
|
||||||
|
boolean hasJingfenPrice = input.contains("京粉实际价格:");
|
||||||
|
|
||||||
|
if (hasThirdPartyOrderNo) {
|
||||||
|
extractField(input, fields, "分销标记:", "第三方单号:");
|
||||||
|
extractField(input, fields, "第三方单号:", "型号:");
|
||||||
|
} else {
|
||||||
|
extractField(input, fields, "分销标记:", "型号:");
|
||||||
|
}
|
||||||
|
|
||||||
|
extractField(input, fields, "型号:", "链接:");
|
||||||
|
extractField(input, fields, "链接:", "下单付款:");
|
||||||
|
extractField(input, fields, "下单付款:", "后返金额:");
|
||||||
|
extractField(input, fields, "后返金额:", "地址:");
|
||||||
|
extractField(input, fields, "地址:", "物流链接:");
|
||||||
|
extractField(input, fields, "物流链接:", "订单号:");
|
||||||
|
extractField(input, fields, "订单号:", "下单人:");
|
||||||
|
|
||||||
|
if (hasJingfenPrice) {
|
||||||
|
extractField(input, fields, "下单人:", "京粉实际价格:");
|
||||||
|
extractField(input, fields, "京粉实际价格:", "");
|
||||||
|
} else {
|
||||||
|
extractField(input, fields, "下单人:", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用正则提取下单人(兼容新旧格式)
|
||||||
|
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.Matcher buyerMatcher = buyerPattern.matcher(input);
|
||||||
|
if (buyerMatcher.find()) {
|
||||||
|
String buyer = buyerMatcher.group(1).trim();
|
||||||
|
if (buyer.contains("\n")) {
|
||||||
|
buyer = buyer.split("\n")[0].trim();
|
||||||
|
}
|
||||||
|
fields.put("下单人", buyer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取字段的方法(支持分隔线,用于新格式)
|
||||||
|
private void extractFieldWithSeparator(String input, Map<String, String> map, String startKeyword, String endKeyword) {
|
||||||
|
try {
|
||||||
|
String escapedStart = java.util.regex.Pattern.quote(startKeyword);
|
||||||
|
String escapedEnd = java.util.regex.Pattern.quote(endKeyword);
|
||||||
|
|
||||||
|
// 匹配模式:startKeyword + 可选的空白和换行 + 字段值(非贪婪,支持多行) + 后面是换行+endKeyword或换行+分隔线或结束
|
||||||
|
String patternStr = escapedStart + "[\\s\\n]*([\\s\\S]*?)(?=\\s*\\n?\\s*" + escapedEnd + "|\\s*\\n?\\s*—————————|\\Z)";
|
||||||
|
java.util.regex.Pattern pattern = java.util.regex.Pattern.compile(patternStr, java.util.regex.Pattern.DOTALL);
|
||||||
|
java.util.regex.Matcher matcher = pattern.matcher(input);
|
||||||
|
|
||||||
|
if (matcher.find()) {
|
||||||
|
String value = matcher.group(1);
|
||||||
|
if (value != null) {
|
||||||
|
value = value.trim();
|
||||||
|
// 去掉可能的分隔线(在值的前后)
|
||||||
|
value = value.replaceAll("^—————————[\\s\\n]*", "").replaceAll("[\\s\\n]*—————————$", "").trim();
|
||||||
|
// 去掉字段标签本身(如果被匹配到了)
|
||||||
|
value = value.replaceAll("^" + escapedStart, "").trim();
|
||||||
|
// 保存字段值,使用去掉冒号的key
|
||||||
|
String key = startKeyword.replace(":", "").trim();
|
||||||
|
if (!value.isEmpty()) {
|
||||||
|
map.put(key, value);
|
||||||
|
System.out.println(" ✓ 提取字段成功: " + key + " = " + (value.length() > 50 ? value.substring(0, 50) + "..." : value));
|
||||||
|
} else {
|
||||||
|
System.out.println(" ✗ 字段值为空: " + key);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println(" ✗ 未找到字段值: " + startKeyword);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println(" ✗ 正则未匹配: " + startKeyword + " -> " + endKeyword);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println(" ✗ 提取字段异常: " + startKeyword + " -> " + endKeyword + ", error: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void extractField(String input, Map<String, String> map, String startKeyword, String endKeyword) {
|
private void extractField(String input, Map<String, String> map, String startKeyword, String endKeyword) {
|
||||||
// 如果结束关键词为空,匹配到字符串末尾
|
// 如果结束关键词为空,匹配到字符串末尾
|
||||||
String endPattern = endKeyword.isEmpty() ? "\\Z" : endKeyword;
|
String endPattern = endKeyword.isEmpty() ? "\\Z" : endKeyword;
|
||||||
|
|||||||
Reference in New Issue
Block a user