1
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package com.ruoyi.web.controller.common;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
@@ -15,7 +16,8 @@ import java.security.NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* 闲管家开放平台推送回调(请在开放平台填写真实 URL)
|
||||
* 订单:建议 POST .../open/callback/order/receive
|
||||
* 订单:POST .../open/callback/order/receive?appid=×tamp=&sign=
|
||||
* 响应须与平台「强校验」一致:一般 {@code {"code":0,"msg":"OK","data":{}}} ,勿使用 {@code result} 等非标准字段。
|
||||
*/
|
||||
@Anonymous
|
||||
@RestController
|
||||
@@ -32,61 +34,95 @@ public class OpenCallbackController {
|
||||
public JSONObject receiveProductCallback(
|
||||
@RequestParam("appid") String appid,
|
||||
@RequestParam(value = "timestamp", required = false) Long timestamp,
|
||||
@RequestParam(value = "seller_id", required = false) Long sellerId,
|
||||
@RequestParam("sign") String sign,
|
||||
@RequestBody JSONObject body
|
||||
@RequestBody(required = false) String rawBody
|
||||
) {
|
||||
String normalizedBody = normalizeJsonBody(rawBody);
|
||||
IERPAccount account = erpAccountResolver.resolveStrict(appid);
|
||||
if (!verifySign(account, timestamp, sign, body)) {
|
||||
JSONObject fail = new JSONObject();
|
||||
fail.put("result", "fail");
|
||||
fail.put("msg", "签名失败");
|
||||
return fail;
|
||||
if (!verifyGoofishSign(account, timestamp, sellerId, sign, normalizedBody)) {
|
||||
return failCallback(1, "签名失败");
|
||||
}
|
||||
JSONObject ok = new JSONObject();
|
||||
ok.put("result", "success");
|
||||
ok.put("msg", "接收成功");
|
||||
return ok;
|
||||
return successCallback();
|
||||
}
|
||||
|
||||
@PostMapping("/order/receive")
|
||||
public JSONObject receiveOrderCallback(
|
||||
@RequestParam("appid") String appid,
|
||||
@RequestParam(value = "timestamp", required = false) Long timestamp,
|
||||
@RequestParam(value = "seller_id", required = false) Long sellerId,
|
||||
@RequestParam("sign") String sign,
|
||||
@RequestBody JSONObject body
|
||||
@RequestBody(required = false) String rawBody
|
||||
) {
|
||||
String normalizedBody = normalizeJsonBody(rawBody);
|
||||
IERPAccount account = erpAccountResolver.resolveStrict(appid);
|
||||
if (!verifySign(account, timestamp, sign, body)) {
|
||||
JSONObject fail = new JSONObject();
|
||||
fail.put("result", "fail");
|
||||
fail.put("msg", "签名失败");
|
||||
return fail;
|
||||
if (account == null) {
|
||||
return failCallback(1, "未找到启用的 AppKey 配置");
|
||||
}
|
||||
if (!verifyGoofishSign(account, timestamp, sellerId, sign, normalizedBody)) {
|
||||
return failCallback(1, "签名失败");
|
||||
}
|
||||
JSONObject body;
|
||||
try {
|
||||
body = "{}".equals(normalizedBody) ? new JSONObject() : JSON.parseObject(normalizedBody);
|
||||
} catch (Exception e) {
|
||||
return failCallback(2, "请求体不是合法JSON");
|
||||
}
|
||||
try {
|
||||
erpGoofishOrderService.publishOrProcessNotify(appid, timestamp, body);
|
||||
} catch (Exception e) {
|
||||
JSONObject fail = new JSONObject();
|
||||
fail.put("result", "fail");
|
||||
fail.put("msg", "入队异常");
|
||||
return fail;
|
||||
return failCallback(3, "入队异常");
|
||||
}
|
||||
JSONObject ok = new JSONObject();
|
||||
ok.put("result", "success");
|
||||
ok.put("msg", "接收成功");
|
||||
return ok;
|
||||
return successCallback();
|
||||
}
|
||||
|
||||
private boolean verifySign(IERPAccount account, Long timestamp, String sign, JSONObject body) {
|
||||
/**
|
||||
* 与开放平台示例一致:签名字符串 = md5(appKey + "," + md5(body原文) + "," + timestamp + [,sellerId] + "," + appSecret)
|
||||
* body 须与推送原文完全一致后做 MD5,不能用解析后再 toJSONString(字段顺序变化会导致验签失败)。
|
||||
*/
|
||||
private boolean verifyGoofishSign(IERPAccount account, Long timestamp, Long sellerId, String sign, String bodyExactForMd5) {
|
||||
if (account == null || StringUtils.isEmpty(sign)) {
|
||||
return false;
|
||||
}
|
||||
String json = body == null ? "{}" : body.toJSONString();
|
||||
String data = account.getApiKey() + "," + md5(json) + "," + (timestamp == null ? 0 : timestamp) + "," + account.getApiKeySecret();
|
||||
String local = md5(data);
|
||||
return StringUtils.equalsIgnoreCase(local, sign);
|
||||
String jsonForMd5 = bodyExactForMd5 == null || bodyExactForMd5.isEmpty() ? "{}" : bodyExactForMd5;
|
||||
String bodyMd5 = md5Hex(jsonForMd5);
|
||||
long ts = timestamp == null ? 0L : timestamp;
|
||||
String data;
|
||||
if (sellerId != null) {
|
||||
data = account.getApiKey() + "," + bodyMd5 + "," + ts + "," + sellerId + "," + account.getApiKeySecret();
|
||||
} else {
|
||||
data = account.getApiKey() + "," + bodyMd5 + "," + ts + "," + account.getApiKeySecret();
|
||||
}
|
||||
String local = md5Hex(data);
|
||||
return StringUtils.equalsIgnoreCase(local, sign.trim());
|
||||
}
|
||||
|
||||
private String md5(String str) {
|
||||
private static String normalizeJsonBody(String rawBody) {
|
||||
if (rawBody == null) {
|
||||
return "{}";
|
||||
}
|
||||
String t = rawBody.trim();
|
||||
return t.isEmpty() ? "{}" : t;
|
||||
}
|
||||
|
||||
/** 与平台开放接口成功响应字段类型对齐:code 为数值、msg 为字符串、data 为对象 */
|
||||
private static JSONObject successCallback() {
|
||||
JSONObject ok = new JSONObject();
|
||||
ok.put("code", 0);
|
||||
ok.put("msg", "OK");
|
||||
ok.put("data", new JSONObject());
|
||||
return ok;
|
||||
}
|
||||
|
||||
private static JSONObject failCallback(int code, String msg) {
|
||||
JSONObject j = new JSONObject();
|
||||
j.put("code", code);
|
||||
j.put("msg", msg == null ? "fail" : msg);
|
||||
j.put("data", new JSONObject());
|
||||
return j;
|
||||
}
|
||||
|
||||
private String md5Hex(String str) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
byte[] digest = md.digest(str.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
@@ -52,4 +52,17 @@ public class JarvisGoofishProperties {
|
||||
private int pullFullHistoryDays = 1095;
|
||||
|
||||
private int autoShipBatchSize = 20;
|
||||
|
||||
/**
|
||||
* 允许触发闲鱼开放平台「发货」的本地 order_status(逗号分隔,与推送/列表一致)。默认 12 通常表示待发货。
|
||||
*/
|
||||
private String autoShipOrderStatuses = "12";
|
||||
|
||||
/**
|
||||
* 未在 erp_open_config 配置 express_code 时,自动发货使用的默认快递公司编码(官方列表中日日顺多为 rrs)。
|
||||
*/
|
||||
private String defaultShipExpressCode = "rrs";
|
||||
|
||||
/** 与 defaultShipExpressCode 配套的展示名称 */
|
||||
private String defaultShipExpressName = "日日顺";
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ public interface ErpGoofishOrderMapper {
|
||||
|
||||
int update(ErpGoofishOrder row);
|
||||
|
||||
List<ErpGoofishOrder> selectPendingShip(@Param("limit") int limit);
|
||||
List<ErpGoofishOrder> selectPendingShip(@Param("statuses") List<Integer> statuses, @Param("limit") int limit);
|
||||
|
||||
int resetShipForRetry(@Param("id") Long id);
|
||||
}
|
||||
|
||||
@@ -34,4 +34,9 @@ public interface IErpGoofishOrderService {
|
||||
int syncWaybillAndTryShipBatch(int limit);
|
||||
|
||||
void applyListOrNotifyItem(String appKey, JSONObject item, String lastNotifyJson);
|
||||
|
||||
/**
|
||||
* 京东单物流扫描已得到运单号并写入 Redis 后调用:同步到闲鱼单并尝试开放平台发货。
|
||||
*/
|
||||
void notifyJdWaybillReady(Long jdOrderId);
|
||||
}
|
||||
|
||||
@@ -51,9 +51,10 @@ public class GoofishOrderPipeline {
|
||||
|
||||
public void runFullPipeline(String appid, JSONObject notifyBody) {
|
||||
try {
|
||||
JSONObject shape = sourceForNotifyUpsert(notifyBody);
|
||||
ErpGoofishOrder row = upsertFromNotify(appid, notifyBody, notifyBody.toJSONString());
|
||||
tryLinkJdOrder(row);
|
||||
mergeSummaryFromOrderDetailShape(row, notifyBody);
|
||||
mergeSummaryFromOrderDetailShape(row, shape);
|
||||
refreshDetail(row);
|
||||
syncWaybillFromRedis(row);
|
||||
tryAutoShip(row);
|
||||
@@ -74,24 +75,29 @@ public class GoofishOrderPipeline {
|
||||
tryAutoShip(row);
|
||||
}
|
||||
|
||||
public ErpGoofishOrder upsertFromNotify(String appKey, JSONObject body, String lastNotifyJson) {
|
||||
public ErpGoofishOrder upsertFromNotify(String appKey, JSONObject rawBody, String lastNotifyJson) {
|
||||
JSONObject body = sourceForNotifyUpsert(rawBody);
|
||||
Date now = DateUtils.getNowDate();
|
||||
String orderNo = body.getString("order_no");
|
||||
String orderNo = notifyFirstString(body, "order_no", "orderNo");
|
||||
if (StringUtils.isEmpty(orderNo)) {
|
||||
throw new IllegalArgumentException("缺少 order_no");
|
||||
}
|
||||
ErpGoofishOrder existing = erpGoofishOrderMapper.selectByAppKeyAndOrderNo(appKey, orderNo);
|
||||
ErpGoofishOrder e = new ErpGoofishOrder();
|
||||
e.setAppKey(appKey);
|
||||
e.setSellerId(body.getLong("seller_id"));
|
||||
e.setUserName(body.getString("user_name"));
|
||||
Long sid = notifyFirstLong(body, "seller_id", "sellerId");
|
||||
e.setSellerId(sid);
|
||||
e.setUserName(notifyFirstString(body, "user_name", "userName", "seller_name"));
|
||||
e.setOrderNo(orderNo);
|
||||
e.setOrderType(body.getInteger("order_type"));
|
||||
e.setOrderStatus(body.getInteger("order_status"));
|
||||
e.setRefundStatus(body.getInteger("refund_status"));
|
||||
e.setModifyTime(body.getLong("modify_time"));
|
||||
e.setProductId(body.getLong("product_id"));
|
||||
e.setItemId(body.getLong("item_id"));
|
||||
e.setOrderType(notifyFirstInteger(body, "order_type", "orderType"));
|
||||
e.setOrderStatus(notifyFirstInteger(body, "order_status", "orderStatus"));
|
||||
e.setRefundStatus(notifyFirstInteger(body, "refund_status", "refundStatus"));
|
||||
Long mt = notifyFirstLong(body, "modify_time", "order_modify_time", "update_time", "modifyTime");
|
||||
e.setModifyTime(mt);
|
||||
Long pid = notifyFirstLong(body, "product_id", "productId");
|
||||
e.setProductId(pid);
|
||||
Long iid = notifyFirstLong(body, "item_id", "itemId");
|
||||
e.setItemId(iid);
|
||||
e.setLastNotifyJson(lastNotifyJson);
|
||||
e.setUpdateTime(now);
|
||||
if (existing == null) {
|
||||
@@ -254,11 +260,11 @@ public class GoofishOrderPipeline {
|
||||
patch.setReceiverAddress(recv.getString("address"));
|
||||
}
|
||||
}
|
||||
Integer os = data.getInteger("order_status");
|
||||
Integer os = firstInt(data, "order_status", "orderStatus");
|
||||
if (os != null) {
|
||||
patch.setOrderStatus(os);
|
||||
}
|
||||
Integer rs = data.getInteger("refund_status");
|
||||
Integer rs = firstInt(data, "refund_status", "refundStatus");
|
||||
if (rs != null) {
|
||||
patch.setRefundStatus(rs);
|
||||
}
|
||||
@@ -394,7 +400,8 @@ public class GoofishOrderPipeline {
|
||||
if (row == null || row.getId() == null) {
|
||||
return;
|
||||
}
|
||||
if (row.getOrderStatus() == null || row.getOrderStatus() != 12) {
|
||||
List<Integer> awaiting = resolveAutoShipOrderStatuses();
|
||||
if (row.getOrderStatus() == null || !awaiting.contains(row.getOrderStatus())) {
|
||||
return;
|
||||
}
|
||||
if (row.getRefundStatus() != null && row.getRefundStatus() != 0) {
|
||||
@@ -411,10 +418,18 @@ public class GoofishOrderPipeline {
|
||||
return;
|
||||
}
|
||||
ErpOpenConfig cfg = erpOpenConfigService.selectByAppKey(row.getAppKey());
|
||||
String expressCode = cfg != null ? cfg.getExpressCode() : null;
|
||||
String expressName = cfg != null && StringUtils.isNotEmpty(cfg.getExpressName()) ? cfg.getExpressName() : "日日顺";
|
||||
String expressCode = cfg != null && StringUtils.isNotEmpty(cfg.getExpressCode()) ? cfg.getExpressCode() : null;
|
||||
if (StringUtils.isEmpty(expressCode)) {
|
||||
log.info("闲管家自动发货跳过:未配置 express_code appKey={} orderNo={}", row.getAppKey(), row.getOrderNo());
|
||||
expressCode = goofishProperties.getDefaultShipExpressCode();
|
||||
}
|
||||
// 业务约定:对闲鱼回传物流名称固定为「日日顺」(编码以配置 / 默认 rrs 为准)
|
||||
String expressName = goofishProperties.getDefaultShipExpressName();
|
||||
if (StringUtils.isEmpty(expressName)) {
|
||||
expressName = "日日顺";
|
||||
}
|
||||
if (StringUtils.isEmpty(expressCode)) {
|
||||
log.info("闲管家自动发货跳过:无快递公司编码(请配置 erp_open_config.express_code 或 jarvis.goofish-order.default-ship-express-code) appKey={} orderNo={}",
|
||||
row.getAppKey(), row.getOrderNo());
|
||||
return;
|
||||
}
|
||||
ShipAddressParts addr = parseShipAddress(row.getDetailJson());
|
||||
@@ -656,6 +671,91 @@ public class GoofishOrderPipeline {
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<Integer> resolveAutoShipOrderStatuses() {
|
||||
String raw = goofishProperties.getAutoShipOrderStatuses();
|
||||
List<Integer> list = new ArrayList<>();
|
||||
if (StringUtils.isNotEmpty(raw)) {
|
||||
for (String part : raw.split(",")) {
|
||||
String t = part.trim();
|
||||
if (t.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
list.add(Integer.parseInt(t));
|
||||
} catch (NumberFormatException ignored) {
|
||||
// ignore invalid token
|
||||
}
|
||||
}
|
||||
}
|
||||
if (list.isEmpty()) {
|
||||
list.add(12);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 推送回调体可能是扁平订单字段,也可能包在 data / data.list[0] / order 中(与列表项 schema 对齐的优先解包)。
|
||||
*/
|
||||
private static JSONObject sourceForNotifyUpsert(JSONObject rawBody) {
|
||||
if (rawBody == null) {
|
||||
return new JSONObject();
|
||||
}
|
||||
if (StringUtils.isNotEmpty(rawBody.getString("order_no")) || StringUtils.isNotEmpty(rawBody.getString("orderNo"))) {
|
||||
return rawBody;
|
||||
}
|
||||
JSONObject data = rawBody.getJSONObject("data");
|
||||
if (data != null) {
|
||||
if (StringUtils.isNotEmpty(data.getString("order_no")) || StringUtils.isNotEmpty(data.getString("orderNo"))) {
|
||||
return data;
|
||||
}
|
||||
JSONObject order = data.getJSONObject("order");
|
||||
if (order != null && (StringUtils.isNotEmpty(order.getString("order_no"))
|
||||
|| StringUtils.isNotEmpty(order.getString("orderNo")))) {
|
||||
return order;
|
||||
}
|
||||
JSONArray list = data.getJSONArray("list");
|
||||
if (list != null && !list.isEmpty()) {
|
||||
Object first = list.get(0);
|
||||
if (first instanceof JSONObject) {
|
||||
JSONObject row = (JSONObject) first;
|
||||
if (StringUtils.isNotEmpty(row.getString("order_no")) || StringUtils.isNotEmpty(row.getString("orderNo"))) {
|
||||
return row;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
JSONObject order = rawBody.getJSONObject("order");
|
||||
if (order != null && (StringUtils.isNotEmpty(order.getString("order_no"))
|
||||
|| StringUtils.isNotEmpty(order.getString("orderNo")))) {
|
||||
return order;
|
||||
}
|
||||
return rawBody;
|
||||
}
|
||||
|
||||
private static String notifyFirstString(JSONObject o, String... keys) {
|
||||
return firstNonEmpty(o, keys);
|
||||
}
|
||||
|
||||
private static Integer notifyFirstInteger(JSONObject o, String... keys) {
|
||||
return firstInt(o, keys);
|
||||
}
|
||||
|
||||
private static Long notifyFirstLong(JSONObject o, String... keys) {
|
||||
if (o == null) {
|
||||
return null;
|
||||
}
|
||||
for (String k : keys) {
|
||||
if (!o.containsKey(k)) {
|
||||
continue;
|
||||
}
|
||||
Long v = o.getLong(k);
|
||||
if (v != null) {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 增量拉单:按 update_time ∈ [now−lookbackHours, now]
|
||||
*/
|
||||
@@ -837,7 +937,8 @@ public class GoofishOrderPipeline {
|
||||
}
|
||||
|
||||
public int syncWaybillAndTryShipBatch(int limit) {
|
||||
List<ErpGoofishOrder> rows = erpGoofishOrderMapper.selectPendingShip(limit);
|
||||
List<Integer> statuses = resolveAutoShipOrderStatuses();
|
||||
List<ErpGoofishOrder> rows = erpGoofishOrderMapper.selectPendingShip(statuses, limit);
|
||||
if (rows == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -138,4 +138,25 @@ public class ErpGoofishOrderServiceImpl implements IErpGoofishOrderService {
|
||||
public void applyListOrNotifyItem(String appKey, JSONObject item, String lastNotifyJson) {
|
||||
goofishOrderPipeline.applyListOrNotifyItem(appKey, item, lastNotifyJson);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyJdWaybillReady(Long jdOrderId) {
|
||||
if (jdOrderId == null) {
|
||||
return;
|
||||
}
|
||||
ErpGoofishOrder query = new ErpGoofishOrder();
|
||||
query.setJdOrderId(jdOrderId);
|
||||
List<ErpGoofishOrder> list = erpGoofishOrderMapper.selectList(query);
|
||||
if (list == null || list.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (ErpGoofishOrder ref : list) {
|
||||
ErpGoofishOrder full = erpGoofishOrderMapper.selectById(ref.getId());
|
||||
if (full == null) {
|
||||
continue;
|
||||
}
|
||||
goofishOrderPipeline.syncWaybillFromRedis(full);
|
||||
goofishOrderPipeline.tryAutoShip(full);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.ruoyi.common.utils.http.HttpUtils;
|
||||
import com.ruoyi.jarvis.domain.JDOrder;
|
||||
import com.ruoyi.jarvis.domain.WeComShareLinkLogisticsJob;
|
||||
import com.ruoyi.jarvis.mapper.WeComShareLinkLogisticsJobMapper;
|
||||
import com.ruoyi.jarvis.service.IErpGoofishOrderService;
|
||||
import com.ruoyi.jarvis.service.ILogisticsService;
|
||||
import com.ruoyi.jarvis.service.IJDOrderService;
|
||||
import com.ruoyi.system.service.ISysConfigService;
|
||||
@@ -81,6 +82,9 @@ public class LogisticsServiceImpl implements ILogisticsService {
|
||||
|
||||
@Resource
|
||||
private IJDOrderService jdOrderService;
|
||||
|
||||
@Resource
|
||||
private IErpGoofishOrderService erpGoofishOrderService;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
@@ -215,6 +219,15 @@ public class LogisticsServiceImpl implements ILogisticsService {
|
||||
}
|
||||
}
|
||||
|
||||
/** 京东单已写入 Redis 运单后,联动闲鱼单同步并发货(失败不影响物流主流程) */
|
||||
private void safeNotifyGoofishShip(Long jdOrderId) {
|
||||
try {
|
||||
erpGoofishOrderService.notifyJdWaybillReady(jdOrderId);
|
||||
} catch (Exception e) {
|
||||
logger.warn("闲鱼发货联动异常 jdOrderId={} err={}", jdOrderId, e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fetchLogisticsAndPush(JDOrder order) {
|
||||
if (order == null || order.getId() == null) {
|
||||
@@ -375,6 +388,7 @@ public class LogisticsServiceImpl implements ILogisticsService {
|
||||
logger.info("订单运单号已存在且一致,说明之前已推送过,跳过重复推送 - 订单ID: {}, waybill_no: {}", orderId, waybillNo);
|
||||
// 更新过期时间,确保记录不会过期
|
||||
stringRedisTemplate.opsForValue().set(redisKey, waybillNo, 30, TimeUnit.DAYS);
|
||||
safeNotifyGoofishShip(orderId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -392,6 +406,7 @@ public class LogisticsServiceImpl implements ILogisticsService {
|
||||
logger.info("订单创建时间较早({}),且Redis中无记录但已获取到运单号,视为之前已推送过,直接标记为已处理,跳过推送 - 订单ID: {}, waybill_no: {}",
|
||||
order.getCreateTime(), orderId, waybillNo);
|
||||
stringRedisTemplate.opsForValue().set(redisKey, waybillNo, 30, TimeUnit.DAYS);
|
||||
safeNotifyGoofishShip(orderId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -418,7 +433,8 @@ public class LogisticsServiceImpl implements ILogisticsService {
|
||||
// 更新过期时间,确保记录不会过期
|
||||
stringRedisTemplate.opsForValue().set(redisKey, waybillNo, 30, TimeUnit.DAYS);
|
||||
}
|
||||
|
||||
safeNotifyGoofishShip(orderId);
|
||||
|
||||
// 记录最终处理结果
|
||||
if (logisticsLinkUpdated) {
|
||||
logger.info("========== 物流信息获取并推送成功(已更新物流链接) - 订单ID: {}, 订单号: {}, waybill_no: {}, 新链接: {} ==========",
|
||||
|
||||
@@ -79,7 +79,14 @@
|
||||
|
||||
<select id="selectPendingShip" resultMap="ErpGoofishOrderResult">
|
||||
<include refid="selectJoinVo"/>
|
||||
where e.order_status = 12 and (e.ship_status is null or e.ship_status != 1) and e.jd_order_id is not null
|
||||
where e.jd_order_id is not null
|
||||
and (e.ship_status is null or e.ship_status != 1)
|
||||
<if test="statuses != null and statuses.size() > 0">
|
||||
and e.order_status in
|
||||
<foreach collection="statuses" item="st" open="(" separator="," close=")">
|
||||
#{st}
|
||||
</foreach>
|
||||
</if>
|
||||
order by e.update_time asc
|
||||
limit #{limit}
|
||||
</select>
|
||||
|
||||
Reference in New Issue
Block a user