diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/domain/ErpGoofishOrder.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/domain/ErpGoofishOrder.java index ed98cb7..01b41b8 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/domain/ErpGoofishOrder.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/domain/ErpGoofishOrder.java @@ -64,6 +64,8 @@ public class ErpGoofishOrder { private String jdRemark; /** 联查:本地京东单收件地址 jd_order.address(闲鱼详情常不返回明文地址) */ private String jdAddress; + /** 联查:京东单型号 jd_order.model_number */ + private String jdModelNumber; // --------- 以下为列表查询扩展条件(不参与 insert/update) --------- /** 运单关键字:命中详情运单号或本地运单号(模糊) */ diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/wecom/WxSendGoofishNotifyClient.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/wecom/WxSendGoofishNotifyClient.java index 827a4b1..67000dd 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/wecom/WxSendGoofishNotifyClient.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/wecom/WxSendGoofishNotifyClient.java @@ -1,8 +1,12 @@ package com.ruoyi.jarvis.wecom; import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.jarvis.domain.ErpGoofishOrder; +import com.ruoyi.jarvis.mapper.ErpGoofishOrderMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; @@ -13,6 +17,7 @@ import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Date; import java.util.List; /** @@ -40,6 +45,9 @@ public class WxSendGoofishNotifyClient { @Value("${jarvis.wecom.goofish-notify-touser:}") private String goofishNotifyTouser; + @Autowired(required = false) + private ErpGoofishOrderMapper erpGoofishOrderMapper; + /** * 闲鱼订单事件通知 wxSend(由 wxSend 转企微应用消息)。 * @@ -56,7 +64,7 @@ public class WxSendGoofishNotifyClient { if (!StringUtils.hasText(toUser)) { return; } - String content = buildContent(orderNo, eventType, source, message); + String content = composeNotifyContent(orderNo, eventType, source, message); if (!StringUtils.hasText(content)) { return; } @@ -111,14 +119,185 @@ public class WxSendGoofishNotifyClient { } /** - * 企微短通知:场景标题 + 订单号 + 必要字段行(不再展示数据来源等冗长前缀)。 + * 企微短通知:标题 + 型号/地址/日期 + 闲鱼订单号 + 事件明细。 */ - private static String buildContent(String orderNo, String eventType, String source, String message) { + private String composeNotifyContent(String orderNo, String eventType, String source, String message) { + String snapshot = buildOrderSnapshotBlock(orderNo); + return assembleContent(orderNo, eventType, source, message, snapshot); + } + + /** + * 从库中按闲鱼订单号取一条较「全」的快照,拼装通用上下文(所有订单类通知共用)。 + */ + private String buildOrderSnapshotBlock(String orderNo) { + if (!StringUtils.hasText(orderNo) || erpGoofishOrderMapper == null) { + return ""; + } + List list; + try { + list = erpGoofishOrderMapper.selectByGoofishOrderNo(orderNo.trim()); + } catch (Exception e) { + log.debug("通知上下文查询闲鱼订单跳过 orderNo={} err={}", orderNo, e.toString()); + return ""; + } + if (list == null || list.isEmpty()) { + return ""; + } + ErpGoofishOrder r = pickPreferredGoofishSnapshot(list); + if (r == null) { + return ""; + } + StringBuilder sb = new StringBuilder(); + String model = resolveModelLine(r); + if (StringUtils.hasText(model)) { + sb.append("型号:").append(clampOneLine(model, 200)).append('\n'); + } + String addr = buildDisplayAddress(r); + if (StringUtils.hasText(addr)) { + sb.append("收货地址:").append(clampOneLine(addr, 500)).append('\n'); + } + if (r.getCreateTime() != null) { + sb.append("入库时间:") + .append(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, r.getCreateTime())) + .append('\n'); + } + String modified = formatPlatformModifyTime(r.getModifyTime()); + if (StringUtils.hasText(modified)) { + sb.append("平台更新:").append(modified).append('\n'); + } + return sb.toString(); + } + + private static ErpGoofishOrder pickPreferredGoofishSnapshot(List list) { + ErpGoofishOrder best = list.get(0); + int bs = snapshotRichness(best); + for (int i = 1; i < list.size(); i++) { + ErpGoofishOrder x = list.get(i); + int s = snapshotRichness(x); + if (s > bs) { + best = x; + bs = s; + } + } + return best; + } + + private static int snapshotRichness(ErpGoofishOrder r) { + if (r == null) { + return 0; + } + int s = 0; + if (r.getJdOrderId() != null) { + s += 2; + } + if (StringUtils.hasText(trim(r.getJdModelNumber()))) { + s += 5; + } + if (StringUtils.hasText(trim(r.getJdAddress()))) { + s += 4; + } + if (StringUtils.hasText(trim(r.getReceiverAddress()))) { + s += 2; + } + if (StringUtils.hasText(trim(r.getGoodsTitle()))) { + s += 1; + } + return s; + } + + private static String resolveModelLine(ErpGoofishOrder r) { + String m = trim(r.getJdModelNumber()); + if (StringUtils.hasText(m)) { + return m; + } + return abbrevTitle(r.getGoodsTitle(), 180); + } + + private static String abbrevTitle(String title, int max) { + String t = trim(title); + if (!StringUtils.hasText(t)) { + return ""; + } + if (t.length() <= max) { + return t; + } + return t.substring(0, Math.max(0, max - 1)) + '…'; + } + + private static String buildDisplayAddress(ErpGoofishOrder r) { + if (r == null) { + return ""; + } + String jd = trim(r.getJdAddress()); + if (StringUtils.hasText(jd)) { + return jd; + } + String regionLine = trim(r.getReceiverRegion()); + if (!StringUtils.hasText(regionLine)) { + regionLine = joinWithSpace( + r.getRecvProvName(), r.getRecvCityName(), r.getRecvAreaName(), r.getRecvTownName()); + } + String addr = trim(r.getReceiverAddress()); + if (StringUtils.hasText(regionLine) && StringUtils.hasText(addr)) { + return regionLine + " " + addr; + } + return StringUtils.hasText(addr) ? addr : regionLine; + } + + private static String joinWithSpace(String... parts) { + if (parts == null) { + return ""; + } + StringBuilder sb = new StringBuilder(); + for (String p : parts) { + String t = trim(p); + if (!StringUtils.hasText(t)) { + continue; + } + if (sb.length() > 0) { + sb.append(' '); + } + sb.append(t); + } + return sb.toString(); + } + + private static String formatPlatformModifyTime(Long modifyTime) { + if (modifyTime == null) { + return ""; + } + long ms = modifyTime > 9_999_999_999L ? modifyTime : modifyTime * 1000L; + return DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, new Date(ms)); + } + + private static String clampOneLine(String s, int max) { + String t = trim(s); + if (!StringUtils.hasText(t)) { + return ""; + } + t = t.replace('\r', ' ').replace('\n', ' ').replace(',', ' '); + t = t.trim().replaceAll("\\s+", " "); + if (t.length() <= max) { + return t; + } + return t.substring(0, Math.max(0, max - 1)) + '…'; + } + + private static String trim(String x) { + return x == null ? "" : x.trim(); + } + + private static String assembleContent(String orderNo, String eventType, String source, String message, + String snapshotBlock) { String on = orderNo != null ? orderNo : "-"; String head = resolveNotifyHeadline(eventType, message); String detail = normalizeNotifyDetailLines(eventType, message); StringBuilder sb = new StringBuilder(); - sb.append(head).append("\n订单号:").append(on).append('\n'); + sb.append(head).append('\n'); + if (StringUtils.hasText(snapshotBlock)) { + sb.append(snapshotBlock); + } + sb.append("闲鱼订单号:").append(on).append('\n'); if (StringUtils.hasText(detail)) { sb.append(detail); } diff --git a/ruoyi-system/src/main/resources/mapper/jarvis/ErpGoofishOrderMapper.xml b/ruoyi-system/src/main/resources/mapper/jarvis/ErpGoofishOrderMapper.xml index 3a13fbf..2c69b80 100644 --- a/ruoyi-system/src/main/resources/mapper/jarvis/ErpGoofishOrderMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/jarvis/ErpGoofishOrderMapper.xml @@ -42,6 +42,7 @@ + @@ -51,7 +52,8 @@ e.receiver_region, e.recv_prov_name, e.recv_city_name, e.recv_area_name, e.recv_town_name, e.detail_json, e.last_notify_json, e.jd_order_id, e.local_waybill_no, e.ship_status, e.ship_error, e.ship_time, e.ship_express_code, e.create_time, e.update_time, - o.third_party_order_no as jd_third_party_order_no, o.remark as jd_remark, o.address as jd_address + o.third_party_order_no as jd_third_party_order_no, o.remark as jd_remark, o.address as jd_address, + o.model_number as jd_model_number from erp_goofish_order e left join jd_order o on e.jd_order_id = o.id