diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml index c60e3f7..cc196b3 100644 --- a/ruoyi-admin/src/main/resources/application-dev.yml +++ b/ruoyi-admin/src/main/resources/application-dev.yml @@ -70,7 +70,7 @@ spring: # 端口,默认为6379 port: 36379 # 数据库索引 - database: 9 + database: 7 # 密码 password: redis_6PZ52S # 连接超时时间 diff --git a/ruoyi-admin/src/main/resources/application-prod.yml b/ruoyi-admin/src/main/resources/application-prod.yml index 779c9e6..f8a778a 100644 --- a/ruoyi-admin/src/main/resources/application-prod.yml +++ b/ruoyi-admin/src/main/resources/application-prod.yml @@ -70,7 +70,7 @@ spring: # 端口,默认为6379 port: 6379 # 数据库索引 - database: 9 + database: 7 # 密码 password: redis_6PZ52S # 连接超时时间 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 393993d..e1a660c 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 @@ -36,6 +36,27 @@ public class InstructionServiceImpl implements IInstructionService { @Resource private StringRedisTemplate stringRedisTemplate; + // 录单模板(与 jd/JDUtil 中 WENAN_D 保持一致) + private static final String WENAN_D = "单:\n" + + "{单号} \n备注:{单的备注}\n" + + "分销标记:{分销标记}\n" + + "型号:\n" + + "{型号}\n" + + "链接:\n" + + "{链接}\n" + + "下单付款:\n" + + "\n" + + "后返金额:\n" + + "\n" + + "地址:\n" + + "{地址}\n" + + "物流链接:\n" + + "\n" + + "订单号:\n" + + "\n" + + "下单人:\n" + + "\n"; + @Override public String execute(String command) { if (command == null || command.trim().isEmpty()) { @@ -172,37 +193,37 @@ public class InstructionServiceImpl implements IInstructionService { } // ===== TF/H/生 处理 ===== - private static final Map PRODUCT_WITH_JF = new HashMap<>(); + private static final HashMap productWithJF = new HashMap<>(); static { - PRODUCT_WITH_JF.put("ZQD130F-EB130", "https://u.jd.com/Y6ZKmwN"); - PRODUCT_WITH_JF.put("ZQD130F-EB130B", "https://u.jd.com/YGZKHZS"); - PRODUCT_WITH_JF.put("ZQD150F-EB150", " https://u.jd.com/YDZK5rD"); - PRODUCT_WITH_JF.put("ZQD180F-EB200", "https://u.jd.com/YDZKmb2"); - PRODUCT_WITH_JF.put("CXW-298-IQ92DPRO", "https://u.jd.com/Y1AMT2l"); + productWithJF.put("ZQD130F-EB130", "https://u.jd.com/Y6ZKmwN"); + productWithJF.put("ZQD130F-EB130B", "https://u.jd.com/YGZKHZS"); + productWithJF.put("ZQD150F-EB150", " https://u.jd.com/YDZK5rD"); + productWithJF.put("ZQD180F-EB200", "https://u.jd.com/YDZKmb2"); + productWithJF.put("CXW-298-IQ92DPRO", "https://u.jd.com/Y1AMT2l"); } private String handleTF(String input) { - String raw = input.replaceFirst("^TF", "").trim(); - if (raw.isEmpty()) return "TF 指令格式:TF\t型号\t数量\t地址(可含其它字段)"; - String[] parts = raw.split("\t"); - if (parts.length < 3) return "TF 指令至少包含:型号、数量、地址 三段(以制表符分隔)"; - String model = sanitizeModel(parts[0]); - String quantityStr = parts[1].trim(); - int quantity; - try { quantity = Integer.parseInt(quantityStr); } catch (Exception e) { return "数量格式错误"; } - StringBuilder address = new StringBuilder(); - for (int i = 2; i < parts.length; i++) address.append(parts[i]); - String addressClean = sanitizeAddress(address.toString()); - String jf = PRODUCT_WITH_JF.getOrDefault(model, ""); + String[] parts = input.replace("TF", "").split("\t"); // 使用制表符分割 + if (parts.length >= 3) { + String modelNumber = parts[0].replace("\\n", ""); // 型号 + String quantityStr = parts[1]; // 数量 + StringBuilder address = new StringBuilder(); + // 使用正则表达式提取中文字符 + Pattern pattern = Pattern.compile("[\\u4E00-\\u9FA5]+"); + Matcher matcher = pattern.matcher(parts[2]); + if (matcher.find()) { + address = new StringBuilder(matcher.group()); + } + for (int i = 3; i < parts.length; i++) { + address.append(parts[i]); + } + String jf = productWithJF.get(modelNumber); - StringBuilder sheng = new StringBuilder(); - sheng.append("生\n") - .append("H-TF\n") - .append(model).append("\n") - .append(jf).append("\n") - .append(quantity).append("\n") - .append(addressClean); - return generateOrderText(sheng.toString()); + StringBuilder order = new StringBuilder(); + order.append("生").append("\n").append("H-TF").append("\n").append(modelNumber).append("\n").append(jf).append("\n").append(quantityStr).append("\n").append(address); + return generateOrderText(order.toString()); + } + return "TF 指令格式:TF\t型号\t数量\t地址(可含其它字段)"; } private String handleH(String input) { @@ -248,31 +269,75 @@ public class InstructionServiceImpl implements IInstructionService { String[] split = shengInput.split("\n"); // 第一行可能是 生 或 生{备注} String head = split[0].trim(); - String remark = head.replace("生", "").trim(); + String remark = head.replace("{生}", "").replace("生", "").replace("\n", "").trim(); String fenxiao = split[1].trim(); String model = split[2].trim(); String link = split[3].trim(); int num = 1; try { num = Integer.parseInt(split[4].trim()); } catch (Exception ignore) {} String address = split[5].trim(); + + // 与 JDUtil 一致:地址 24 小时去重校验(白名单放行) + if (stringRedisTemplate != null) { + String addressKey = "address:" + address; + String existed = stringRedisTemplate.opsForValue().get(addressKey); + if (existed != null) { + if (!(existed.contains("李波") || existed.contains("吴胜硕") || existed.contains("小硕硕"))) { + String warn = "[炸弹] [炸弹] [炸弹] 此地址已经存在,请勿重复生成订单 [炸弹] [炸弹] [炸弹] "; + StringBuilder warnOut = new StringBuilder(); + for (int i = 0; i < 5; i++) warnOut.append(warn).append("\n"); + return warnOut.toString().trim(); + } + } + stringRedisTemplate.opsForValue().set(addressKey, address, 1, TimeUnit.DAYS); + } + String today = new java.text.SimpleDateFormat("yyyy-MM-dd ").format(new Date()); - String redisKey = "order_count:" + today; + String todayNoSpace = today.trim(); + String keyWithSpace = "order_count:" + today; // 带空格 + String keyNoSpace = "order_count:" + todayNoSpace; // 不带空格 + String redisKey = keyNoSpace; + if (stringRedisTemplate != null) { + try { + Boolean noSpaceExists = stringRedisTemplate.hasKey(keyNoSpace); + Boolean spaceExists = stringRedisTemplate.hasKey(keyWithSpace); + if (Boolean.TRUE.equals(noSpaceExists)) { + redisKey = keyNoSpace; + } else if (Boolean.TRUE.equals(spaceExists)) { + redisKey = keyWithSpace; + } else { + redisKey = keyNoSpace; // 默认使用不带空格 + } + } catch (Exception ignore) { + redisKey = keyNoSpace; + } + } StringBuilder out = new StringBuilder(); int total = Math.max(1, num); + + int startCount = 1; + if (stringRedisTemplate != null) { + try { + String s = stringRedisTemplate.opsForValue().get(redisKey); + int count = s != null ? Integer.parseInt(s) : 0; + startCount = count + 1; + int endCount = count + total; + stringRedisTemplate.opsForValue().set(redisKey, String.valueOf(endCount), 1, TimeUnit.DAYS); + } catch (Exception ignore) {} + } + for (int i = 0; i < total; i++) { - Long curr = stringRedisTemplate != null ? stringRedisTemplate.opsForValue().increment(redisKey) : null; - if (curr != null && Boolean.TRUE.equals(stringRedisTemplate.getExpire(redisKey) == null || stringRedisTemplate.getExpire(redisKey) <= 0 ? Boolean.TRUE : Boolean.FALSE)) { - stringRedisTemplate.expire(redisKey, 1, TimeUnit.DAYS); - } - String seq = curr == null ? String.format("%03d", i + 1) : String.format("%03d", curr); - String orderId = today + seq; - out.append("单:\n").append(orderId) - .append(" \n备注:").append(remark) - .append("\n分销标记:").append(fenxiao) - .append("\n型号:\n").append(model) - .append("\n链接:\n").append(link) - .append("\n下单付款:\n\n后返金额:\n\n地址:\n").append(address) - .append("\n物流链接:\n\n订单号:\n\n下单人:\n\n"); + int currentCount = startCount + i; + String orderId = today + String.format("%03d", currentCount); + String current = WENAN_D + .replace("{单号}", orderId) + .replace("{单的备注}", remark) + .replace("{分销标记}", fenxiao) + .replace("{链接}", link) + .replace("{地址}", address) + .replace("{型号}", model) + .replaceAll("[|]", ""); + out.append(current); if (i < total - 1) out.append("\n"); } return out.toString();