1
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
package com.ruoyi.jarvis.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 闲管家订单发货预览:闲鱼订单侧收件信息 vs 拟提交开放平台发货参数(可含京东兜底)
|
||||
*/
|
||||
@Data
|
||||
public class GoofishShipPreviewVo {
|
||||
|
||||
private String orderNo;
|
||||
|
||||
/** 管家 goods.title(表或详情) */
|
||||
private String goodsTitle;
|
||||
|
||||
/** 关联京东单的型号 */
|
||||
private String jdModelNumber;
|
||||
|
||||
/** 关联京东单的整段收件地址快照 */
|
||||
private String jdAddressFull;
|
||||
|
||||
/** 仅从闲鱼开放平台落库的收件人姓名 */
|
||||
private String goofishOrderReceiverName;
|
||||
|
||||
private String goofishOrderReceiverMobile;
|
||||
|
||||
/**
|
||||
* 闲鱼订单侧完整收件串:省市区镇 + detail(与发货流水线中 receiverFieldsToShipParts 一致,不含京东)
|
||||
*/
|
||||
private String goofishOrderFullAddress;
|
||||
|
||||
/** 拟调用发货接口使用的收件人(可能由京东兜底补姓名) */
|
||||
private String shipReceiverName;
|
||||
|
||||
private String shipReceiverMobile;
|
||||
|
||||
/** 拟提交的发货详情地址字符串 */
|
||||
private String shipFullAddress;
|
||||
|
||||
/**
|
||||
* 发货收件地址是否与「闲鱼订单侧」归一化后一致(订单侧任一字段为空时为 null)
|
||||
*/
|
||||
private Boolean receiverAddressMatchesGoofish;
|
||||
|
||||
/** 是否与京东整段地址归一化后一致(无视京东或未维护京东地址时为 null) */
|
||||
private Boolean receiverAddressMatchesJd;
|
||||
|
||||
/** 简短说明比对结论或数据来源 */
|
||||
private String compareHint;
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSONObject;
|
||||
import com.ruoyi.jarvis.domain.ErpGoofishOrder;
|
||||
import com.ruoyi.jarvis.domain.ErpGoofishOrderEventLog;
|
||||
import com.ruoyi.jarvis.domain.ErpGoofishOrderEventLogQuery;
|
||||
import com.ruoyi.jarvis.dto.GoofishShipPreviewVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -31,6 +32,11 @@ public interface IErpGoofishOrderService {
|
||||
|
||||
void refreshDetail(Long id);
|
||||
|
||||
/**
|
||||
* 发货预览:闲鱼订单收件串 vs 即将提交开放平台地址(可与京东快照比对)。
|
||||
*/
|
||||
GoofishShipPreviewVo shipPreview(Long id);
|
||||
|
||||
void retryShip(Long id);
|
||||
|
||||
int syncWaybillAndTryShipBatch(int limit);
|
||||
|
||||
@@ -14,6 +14,7 @@ import com.ruoyi.jarvis.config.JarvisGoofishProperties;
|
||||
import com.ruoyi.jarvis.domain.ErpGoofishOrder;
|
||||
import com.ruoyi.jarvis.domain.ErpOpenConfig;
|
||||
import com.ruoyi.jarvis.domain.JDOrder;
|
||||
import com.ruoyi.jarvis.dto.GoofishShipPreviewVo;
|
||||
import com.ruoyi.jarvis.mapper.ErpGoofishOrderMapper;
|
||||
import com.ruoyi.jarvis.service.IJDOrderService;
|
||||
import com.ruoyi.jarvis.service.IErpOpenConfigService;
|
||||
@@ -310,6 +311,10 @@ public class GoofishOrderPipeline {
|
||||
patch.setReceiverAddress(recv.getString("address"));
|
||||
}
|
||||
}
|
||||
// 开放平台常拆分为省市区 + 明文 detail;明细列为空时用行政区拼接兜底,便于列表与发货解析
|
||||
if (StringUtils.isEmpty(patch.getReceiverAddress()) && StringUtils.isNotEmpty(regionJoined)) {
|
||||
patch.setReceiverAddress(regionJoined.trim());
|
||||
}
|
||||
Integer os = firstInt(data, "order_status", "orderStatus");
|
||||
if (os != null) {
|
||||
patch.setOrderStatus(os);
|
||||
@@ -527,25 +532,7 @@ public class GoofishOrderPipeline {
|
||||
row.getAppKey(), row.getOrderNo());
|
||||
return;
|
||||
}
|
||||
ShipAddressParts addr = parseShipAddress(row.getDetailJson());
|
||||
if (addr == null) {
|
||||
addr = new ShipAddressParts();
|
||||
}
|
||||
enrichShipAddressFromJd(row, addr);
|
||||
if (StringUtils.isEmpty(addr.shipAddress)) {
|
||||
ShipAddressParts fromRow = receiverFieldsToShipParts(row);
|
||||
if (fromRow != null) {
|
||||
if (StringUtils.isEmpty(addr.shipName)) {
|
||||
addr.shipName = fromRow.shipName;
|
||||
}
|
||||
if (StringUtils.isEmpty(addr.shipMobile)) {
|
||||
addr.shipMobile = fromRow.shipMobile;
|
||||
}
|
||||
if (StringUtils.isEmpty(addr.shipAddress)) {
|
||||
addr.shipAddress = fromRow.shipAddress;
|
||||
}
|
||||
}
|
||||
}
|
||||
ShipAddressParts addr = resolveShippingAddressParts(row);
|
||||
if (StringUtils.isEmpty(addr.shipName) || StringUtils.isEmpty(addr.shipMobile)
|
||||
|| StringUtils.isEmpty(addr.shipAddress)) {
|
||||
patchShipError(row, "缺少收货人/手机/地址:详情无字段时请关联京东单并维护地址,或等平台返回收货字段");
|
||||
@@ -704,9 +691,6 @@ public class GoofishOrderPipeline {
|
||||
p.shipCityName = firstNonEmpty(data, "ship_city_name", "receiver_city", "city", "city_name");
|
||||
p.shipAreaName = firstNonEmpty(data, "ship_area_name", "receiver_area", "area", "district", "area_name");
|
||||
String shipTown = firstNonEmpty(data, "town_name", "ship_town_name", "receiver_town");
|
||||
if (StringUtils.isNotEmpty(shipTown) && StringUtils.isEmpty(p.shipAddress)) {
|
||||
p.shipAddress = shipTown;
|
||||
}
|
||||
JSONObject recv = data.getJSONObject("receiver");
|
||||
if (recv != null) {
|
||||
if (StringUtils.isEmpty(p.shipName)) {
|
||||
@@ -722,9 +706,135 @@ public class GoofishOrderPipeline {
|
||||
p.shipAddress = recv.getString("address");
|
||||
}
|
||||
}
|
||||
mergeRegionIntoShipAddress(p, shipTown);
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* 与列表/落库拆分字段对齐:开放平台若只给省市区镇 + detail,拼成单行供发货调用。
|
||||
* 已在 detail 中包含省名开头或与整段行政区一致时不重复前缀。
|
||||
*/
|
||||
private static void mergeRegionIntoShipAddress(ShipAddressParts p, String shipTownName) {
|
||||
if (p == null) {
|
||||
return;
|
||||
}
|
||||
String regionLine = joinWithSpace(p.shipProvName, p.shipCityName, p.shipAreaName, shipTownName);
|
||||
if (StringUtils.isEmpty(regionLine)) {
|
||||
return;
|
||||
}
|
||||
String detail = p.shipAddress;
|
||||
if (StringUtils.isEmpty(detail)) {
|
||||
p.shipAddress = regionLine;
|
||||
return;
|
||||
}
|
||||
detail = detail.trim();
|
||||
String prov = StringUtils.isNotEmpty(p.shipProvName) ? p.shipProvName.trim() : "";
|
||||
if (StringUtils.isNotEmpty(prov) && detail.startsWith(prov)) {
|
||||
return;
|
||||
}
|
||||
if (detail.length() >= regionLine.length() && detail.startsWith(regionLine.trim())) {
|
||||
return;
|
||||
}
|
||||
p.shipAddress = regionLine + " " + detail;
|
||||
}
|
||||
|
||||
/**
|
||||
* 与 {@link #tryAutoShip(ErpGoofishOrder, boolean)} 对齐:detail_json → 京东兜底 → 列表/库字段补全。
|
||||
*/
|
||||
private ShipAddressParts resolveShippingAddressParts(ErpGoofishOrder row) {
|
||||
ShipAddressParts addr = parseShipAddress(row != null ? row.getDetailJson() : null);
|
||||
if (addr == null) {
|
||||
addr = new ShipAddressParts();
|
||||
}
|
||||
enrichShipAddressFromJd(row, addr);
|
||||
if (StringUtils.isEmpty(addr.shipAddress)) {
|
||||
ShipAddressParts fromRow = receiverFieldsToShipParts(row);
|
||||
if (fromRow != null) {
|
||||
if (StringUtils.isEmpty(addr.shipName)) {
|
||||
addr.shipName = fromRow.shipName;
|
||||
}
|
||||
if (StringUtils.isEmpty(addr.shipMobile)) {
|
||||
addr.shipMobile = fromRow.shipMobile;
|
||||
}
|
||||
if (StringUtils.isEmpty(addr.shipAddress)) {
|
||||
addr.shipAddress = fromRow.shipAddress;
|
||||
}
|
||||
}
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 管理端发货预览:闲鱼收件串 vs 实际将提交开放平台地址(可对齐运单回填前自检)。
|
||||
*/
|
||||
public GoofishShipPreviewVo buildShipPreview(ErpGoofishOrder row) {
|
||||
GoofishShipPreviewVo vo = new GoofishShipPreviewVo();
|
||||
if (row == null) {
|
||||
vo.setCompareHint("订单不存在");
|
||||
return vo;
|
||||
}
|
||||
vo.setOrderNo(row.getOrderNo());
|
||||
vo.setGoodsTitle(row.getGoodsTitle());
|
||||
vo.setJdModelNumber(row.getJdModelNumber());
|
||||
vo.setJdAddressFull(row.getJdAddress());
|
||||
|
||||
ShipAddressParts orderSide = receiverFieldsToShipParts(row);
|
||||
if (orderSide != null) {
|
||||
vo.setGoofishOrderReceiverName(orderSide.shipName);
|
||||
vo.setGoofishOrderReceiverMobile(orderSide.shipMobile);
|
||||
vo.setGoofishOrderFullAddress(orderSide.shipAddress != null ? orderSide.shipAddress.trim() : "");
|
||||
}
|
||||
|
||||
ShipAddressParts ship = resolveShippingAddressParts(row);
|
||||
vo.setShipReceiverName(ship.shipName);
|
||||
vo.setShipReceiverMobile(ship.shipMobile);
|
||||
vo.setShipFullAddress(StringUtils.isNotEmpty(ship.shipAddress) ? ship.shipAddress.trim() : "");
|
||||
|
||||
String nGoofishAddr = normalizeAddrComparable(vo.getGoofishOrderFullAddress());
|
||||
String nShipAddr = normalizeAddrComparable(vo.getShipFullAddress());
|
||||
|
||||
boolean goofishHasAddr = StringUtils.isNotEmpty(nGoofishAddr);
|
||||
boolean goofishHasContact = StringUtils.isNotEmpty(vo.getGoofishOrderReceiverName())
|
||||
|| StringUtils.isNotEmpty(vo.getGoofishOrderReceiverMobile());
|
||||
vo.setReceiverAddressMatchesGoofish(goofishHasAddr ? Objects.equals(nGoofishAddr, nShipAddr) : null);
|
||||
|
||||
String nJd = normalizeAddrComparable(vo.getJdAddressFull());
|
||||
boolean jdHasAddr = StringUtils.isNotEmpty(nJd);
|
||||
vo.setReceiverAddressMatchesJd(jdHasAddr ? Objects.equals(nJd, nShipAddr) : null);
|
||||
|
||||
StringBuilder hint = new StringBuilder();
|
||||
if (!goofishHasAddr && StringUtils.isNotEmpty(vo.getShipFullAddress())) {
|
||||
hint.append("闲鱼侧未合并到收件地址文本,发货参数可能仅靠详情解析或京东补全");
|
||||
}
|
||||
if (jdHasAddr && Boolean.FALSE.equals(vo.getReceiverAddressMatchesJd())
|
||||
&& StringUtils.isNotEmpty(vo.getShipFullAddress())) {
|
||||
if (hint.length() > 0) {
|
||||
hint.append(';');
|
||||
}
|
||||
hint.append("与京东单整段地址不完全一致(请核对)");
|
||||
}
|
||||
if (Boolean.FALSE.equals(vo.getReceiverAddressMatchesGoofish())
|
||||
&& goofishHasAddr && StringUtils.isNotEmpty(vo.getShipFullAddress())) {
|
||||
if (hint.length() > 0) {
|
||||
hint.append(';');
|
||||
}
|
||||
hint.append("与闲鱼订单收件串不完全一致(可能已用京东补全或未刷新详情)");
|
||||
}
|
||||
if (hint.length() == 0) {
|
||||
hint.append(goofishHasContact || goofishHasAddr ? "可对照下方两项文本核对收件信息" : "暂无闲鱼收件信息,请先刷新详情或关联京东单");
|
||||
}
|
||||
vo.setCompareHint(hint.toString());
|
||||
return vo;
|
||||
}
|
||||
|
||||
private static String normalizeAddrComparable(String addr) {
|
||||
if (addr == null) {
|
||||
return "";
|
||||
}
|
||||
return addr.trim().replaceAll("\\s+", " ");
|
||||
}
|
||||
|
||||
|
||||
/** 开放平台 goods.images 首元素,或其它常见单图字段 */
|
||||
private static String firstGoodsCoverUrl(JSONObject goods) {
|
||||
if (goods == null) {
|
||||
|
||||
@@ -6,9 +6,8 @@ import com.ruoyi.jarvis.config.JarvisGoofishProperties;
|
||||
import com.ruoyi.jarvis.domain.ErpGoofishOrder;
|
||||
import com.ruoyi.jarvis.domain.ErpGoofishOrderEventLog;
|
||||
import com.ruoyi.jarvis.domain.ErpGoofishOrderEventLogQuery;
|
||||
import com.ruoyi.jarvis.domain.ErpOpenConfig;
|
||||
import com.ruoyi.jarvis.domain.JDOrder;
|
||||
import com.ruoyi.jarvis.dto.GoofishNotifyMessage;
|
||||
import com.ruoyi.jarvis.dto.GoofishShipPreviewVo;
|
||||
import com.ruoyi.jarvis.mapper.ErpGoofishOrderEventLogMapper;
|
||||
import com.ruoyi.jarvis.mapper.ErpGoofishOrderMapper;
|
||||
import com.ruoyi.jarvis.service.IErpGoofishOrderService;
|
||||
@@ -142,6 +141,17 @@ public class ErpGoofishOrderServiceImpl implements IErpGoofishOrderService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GoofishShipPreviewVo shipPreview(Long id) {
|
||||
ErpGoofishOrder row = erpGoofishOrderMapper.selectById(id);
|
||||
if (row == null) {
|
||||
GoofishShipPreviewVo empty = new GoofishShipPreviewVo();
|
||||
empty.setCompareHint("订单不存在");
|
||||
return empty;
|
||||
}
|
||||
return goofishOrderPipeline.buildShipPreview(row);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void retryShip(Long id) {
|
||||
erpGoofishOrderMapper.resetShipForRetry(id);
|
||||
|
||||
Reference in New Issue
Block a user