This commit is contained in:
van
2026-04-01 17:26:44 +08:00
parent 2fb9777342
commit 94b65fb760
2 changed files with 80 additions and 45 deletions

View File

@@ -658,17 +658,6 @@ public class InstructionServiceImpl implements IInstructionService {
}
if (input.startsWith("")) {
String primary = handleDanWriteDb(input, forceGenerate, isFromConsole);
String norm = input.trim().replace("", "");
if (isNewOrderFormInput(norm)) {
JDOrder parsedForSummary = parseOrderFromText(norm);
String compact = buildNewFormDanCompactSummary(parsedForSummary);
if (compact != null) {
List<String> two = new ArrayList<>(2);
two.add(primary);
two.add(compact);
return two;
}
}
return Collections.singletonList(primary);
}
return Collections.singletonList(helpText());
@@ -1312,32 +1301,6 @@ public class InstructionServiceImpl implements IInstructionService {
|| originalInput.contains("备注(下单号码有变动/没法带分机号的写这里):");
}
/**
* 新模板录单时追加的精简文案:型号、地址、物流(物流为主链接,与解析入库一致)。
*/
private String buildNewFormDanCompactSummary(JDOrder order) {
if (order == null) {
return null;
}
String model = order.getModelNumber();
String address = order.getAddress();
String logistics = order.getLogisticsLink();
if (isEmpty(model) && isEmpty(address) && isEmpty(logistics)) {
return null;
}
StringBuilder sb = new StringBuilder();
if (!isEmpty(model)) {
sb.append("型号:").append(model.trim()).append('\n');
}
if (!isEmpty(address)) {
sb.append("地址:").append(normalizeWhitespace(address.trim())).append('\n');
}
if (!isEmpty(logistics)) {
sb.append("物流:").append(logistics.trim());
}
return sb.toString().trim();
}
// ===== "单 …" 写库 =====
private String handleDanWriteDb(String input) {
return handleDanWriteDb(input, false, false);
@@ -1476,10 +1439,58 @@ public class InstructionServiceImpl implements IInstructionService {
}
}
// 返回完整的表单格式,使用原始输入保留完整物流链接
if (isNewOrderFormInput(originalInput)) {
return buildDanRecordSuccessMessage(order, originalInput);
}
return formatOrderForm(order, originalInput);
}
/**
* 新模板录单成功:简短提示 + 必要字段(企微/控制台共用)。
*/
private String buildDanRecordSuccessMessage(JDOrder order, String originalInput) {
StringBuilder sb = new StringBuilder();
sb.append("录单成功\n");
sb.append("单号:").append(nvl(order.getRemark())).append("\n");
sb.append("订单号:").append(nvl(order.getOrderId())).append("\n");
if (!isEmpty(order.getThirdPartyOrderNo())) {
sb.append("第三方单号:").append(order.getThirdPartyOrderNo().trim()).append("\n");
}
sb.append("分销标记:").append(nvl(order.getDistributionMark())).append("\n");
sb.append("型号:").append(nvl(order.getModelNumber())).append("\n");
sb.append("下单人:").append(nvl(order.getBuyer())).append("\n");
sb.append("付款:").append(order.getPaymentAmount() != null ? order.getPaymentAmount().toString() : "").append("\n");
sb.append("后返:").append(order.getRebateAmount() != null ? order.getRebateAmount().toString() : "").append("\n");
String logistics = extractOriginalLogisticsLinkNew(originalInput);
if (logistics == null && order.getLogisticsLink() != null) {
logistics = order.getLogisticsLink();
}
if (!isEmpty(logistics)) {
sb.append("物流:").append(shortenLogisticsLineForReply(logistics)).append("\n");
}
if (order.getJingfenActualPrice() != null) {
sb.append("京粉实际价:").append(order.getJingfenActualPrice());
}
return sb.toString().trim();
}
/** 物流块多行时只保留主链接或首行,避免企微回显过长 */
private String shortenLogisticsLineForReply(String logisticsBlock) {
if (logisticsBlock == null) {
return "";
}
Matcher m = Pattern.compile("https?://3\\.cn/[A-Za-z0-9\\-]+").matcher(logisticsBlock);
if (m.find()) {
return m.group();
}
String[] lines = logisticsBlock.split("\\r?\\n");
String first = lines.length > 0 ? lines[0].trim() : logisticsBlock.trim();
if (first.length() > 220) {
return first.substring(0, 217) + "...";
}
return first;
}
private boolean isEmpty(String s) {
return s == null || s.isEmpty();
}

View File

@@ -19,7 +19,8 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* LinPingFan全部指令其他人员须在超级管理员中识别为本人wxid=企微 UserID**或** 企微 UserID 出现在 touser 逗号分隔列表中),且仅「京*」指令 + 京东分享物流链接流程
* LinPingFan全部指令其他人员须在超级管理员中识别为本人wxid=企微 UserID**或** 企微 UserID 出现在 touser 逗号分隔列表中),且仅「京*」指令 + 京东分享物流链接流程
* 例外:以「单」或「开始」开头且含「分销标记」的录单正文优先于物流(不进入 3.cn 多轮、不占用物流监听)。
* 多轮会话使用 Redis{@link WeComChatSession},键 interaction_state:wecom:{FromUserName}与旧版「开通礼金」interaction_state 思路一致。
*/
@Service
@@ -55,6 +56,8 @@ public class WeComInboundServiceImpl implements IWeComInboundService {
return "无权限:请在后台「超级管理员」将您的企微 UserID 填到 wxid或加入该行的 touser逗号分隔";
}
final boolean danRecordPriority = isDanRecordPriorityOverLogistics(content);
WeComChatSession session = weComChatSessionService.get(from);
if (session != null && !session.matchLogisticsWaitRemark()) {
weComChatSessionService.delete(from);
@@ -67,14 +70,16 @@ public class WeComInboundServiceImpl implements IWeComInboundService {
weComChatSessionService.delete(from);
return "已取消物流链接录入";
}
if (isJdShareLogisticsMessage(content)) {
if (danRecordPriority) {
weComChatSessionService.delete(from);
log.info("企微用户 {} 在录单优先下退出物流备注会话", from);
} else if (isJdShareLogisticsMessage(content)) {
String url = extractJd3cnUrl(content);
if (url != null) {
weComChatSessionService.put(from, WeComChatSession.startLogisticsWaitRemark(url));
return "收到物流链接 " + url + " ,请输入备注信息";
}
}
if (t.startsWith("")) {
} else if (t.startsWith("")) {
weComChatSessionService.delete(from);
log.info("企微用户 {} 在京指令下中断物流备注会话", from);
} else {
@@ -87,7 +92,7 @@ public class WeComInboundServiceImpl implements IWeComInboundService {
}
}
if (isJdShareLogisticsMessage(content)) {
if (!danRecordPriority && isJdShareLogisticsMessage(content)) {
String url = extractJd3cnUrl(content);
if (url != null) {
weComChatSessionService.put(from, WeComChatSession.startLogisticsWaitRemark(url));
@@ -98,8 +103,8 @@ public class WeComInboundServiceImpl implements IWeComInboundService {
if (!isSuper) {
String cmd = content.trim();
if (!cmd.startsWith("")) {
return "当前账号仅支持:以「京」开头的指令,或发送含 3.cn 京东物流分享链接";
if (!cmd.startsWith("") && !danRecordPriority) {
return "当前账号仅支持:以「京」开头的指令,或发送含 3.cn 京东物流分享链接,或以「单/开始」开头且含「分销标记」的录单";
}
}
@@ -114,6 +119,25 @@ public class WeComInboundServiceImpl implements IWeComInboundService {
return reply;
}
/**
* 录单正文(指令层走「单…」写库)优先于物流:与 {@link InstructionServiceImpl} 新模板一致。
* 典型:以「单:」开头、含「分销标记」「下单链接(必须用这个)」等;同条含 3.cn 也先录单、不进物流多轮。
*/
private static boolean isDanRecordPriorityOverLogistics(String text) {
if (!StringUtils.hasText(text)) {
return false;
}
String t = text.trim().replaceFirst("^\uFEFF", "");
if (!t.contains("分销标记")) {
return false;
}
if (t.startsWith("") || t.startsWith("开始")) {
return true;
}
return t.contains("单:")
&& (t.contains("下单链接(必须用这个)") || t.contains("—————————") || t.contains("下单地址(注意带分机)"));
}
private static boolean isJdShareLogisticsMessage(String text) {
if (!StringUtils.hasText(text)) {
return false;