1
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user