Merge branch 'main' into dev
This commit is contained in:
commit
142f2414a9
@ -41,4 +41,7 @@ public class RedisConstant {
|
||||
// 您有新的订单来了
|
||||
public static final String New_Order_Push_Flag_Key = ConstantRedis.Cache_NameSpace + "new:order:comimg:";
|
||||
|
||||
// 预约订单任务新增键
|
||||
public static final String Order_Booking_Task_Key = ConstantRedis.Cache_NameSpace + "new:order:booking:task:";
|
||||
|
||||
}
|
||||
|
||||
@ -21,8 +21,8 @@ public class IdUtil {
|
||||
private static final long DATA_CENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;
|
||||
private static final long TIMESTAMP_LEFT_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATA_CENTER_ID_BITS;
|
||||
private static final long SEQUENCE_MASK = ~(-1L << SEQUENCE_BITS);
|
||||
private long workerId;
|
||||
private long dataCenterId;
|
||||
private final long workerId;
|
||||
private final long dataCenterId;
|
||||
private long sequence = 0L;
|
||||
private long lastTimestamp = -1L;
|
||||
|
||||
@ -116,4 +116,5 @@ public class IdUtil {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -750,6 +750,24 @@ public final class StringUtils extends org.apache.commons.lang3.StringUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取货单号格式化
|
||||
*
|
||||
* @param pickNum 一般是 Long 类型
|
||||
* @return
|
||||
*/
|
||||
public static String fmtPickNum(Long pickNum) {
|
||||
if (pickNum == null || pickNum <= 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (pickNum > 9999999) {
|
||||
return String.valueOf(pickNum);
|
||||
}
|
||||
|
||||
return String.format("%07d", pickNum);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成的随机数类型
|
||||
*/
|
||||
|
||||
@ -30,6 +30,10 @@ public class UpdateOrderSeparateJob extends QuartzJobBean {
|
||||
Integer processedCount = lakalaApiService.fixUnSuccessSeparateStatusJob();
|
||||
|
||||
logger.info("[分账状态修复定时任务] 执行完成,共处理 {} 条记录", processedCount);
|
||||
|
||||
processedCount = lakalaApiService.fixUnSuccessDrawedStatusJob();
|
||||
logger.info("[提现状态修复定时任务] 执行完成,共处理 {} 条记录", processedCount);
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("[分账状态修复定时任务] 执行过程中发生异常", e);
|
||||
throw new JobExecutionException(e);
|
||||
|
||||
@ -6,6 +6,7 @@ import com.suisung.mall.common.utils.LogUtil;
|
||||
import com.suisung.mall.shop.config.SpringUtil;
|
||||
import com.suisung.mall.shop.distribution.service.ShopDistributionUserOrderService;
|
||||
import com.suisung.mall.shop.order.service.ShopOrderBaseService;
|
||||
import com.suisung.mall.shop.order.service.ShopOrderBookingService;
|
||||
import com.suisung.mall.shop.order.service.ShopOrderInfoService;
|
||||
import com.suisung.mall.shop.sixun.utils.CommonUtil;
|
||||
import org.quartz.JobExecutionContext;
|
||||
@ -31,6 +32,7 @@ public class UpdateOrderStatusJob extends QuartzJobBean {
|
||||
ShopOrderBaseService shopOrderBaseService = SpringUtil.getBean(ShopOrderBaseService.class);
|
||||
ShopOrderInfoService shopOrderInfoService = SpringUtil.getBean(ShopOrderInfoService.class);
|
||||
ShopDistributionUserOrderService shopDistributionUserOrderService = SpringUtil.getBean(ShopDistributionUserOrderService.class);
|
||||
ShopOrderBookingService shopOrderBookingService = SpringUtil.getBean(ShopOrderBookingService.class);
|
||||
|
||||
// 在UpdateOrderStatusJob.execute方法开始添加日志
|
||||
logger.info("UpdateOrderStatusJob 方法开始执行");
|
||||
@ -56,35 +58,45 @@ public class UpdateOrderStatusJob extends QuartzJobBean {
|
||||
}
|
||||
}
|
||||
}
|
||||
// 自动确认收货
|
||||
//shopOrderBaseService.autoReceive();
|
||||
// 自动确认收货
|
||||
//shopOrderBaseService.autoReceive();
|
||||
|
||||
// 2. 更新为确认收货
|
||||
List<String> order_id_receipt = shopOrderInfoService.getAutoFinishOrderId();
|
||||
if (CollUtil.isNotEmpty(order_id_receipt)) {
|
||||
for (String order_id : order_id_receipt) {
|
||||
try {
|
||||
if (!shopOrderBaseService.receive(order_id, null)) {
|
||||
LogUtil.error(String.format(I18nUtil._("order_id : %s 确认收货出错"), order_id));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(String.format(I18nUtil._("order_id : %s 确认收货出错"), order_id), e);
|
||||
// 2. 更新为确认收货
|
||||
List<String> order_id_receipt = shopOrderInfoService.getAutoFinishOrderId();
|
||||
if (CollUtil.isNotEmpty(order_id_receipt)) {
|
||||
for (String order_id : order_id_receipt) {
|
||||
try {
|
||||
if (!shopOrderBaseService.receive(order_id, null)) {
|
||||
LogUtil.error(String.format(I18nUtil._("order_id : %s 确认收货出错"), order_id));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(String.format(I18nUtil._("order_id : %s 确认收货出错"), order_id), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3.分销结算
|
||||
List<String> order_id_settle_commission = shopOrderBaseService.getWaitingSettleCommissionOrder(null, null);
|
||||
if (CollUtil.isNotEmpty(order_id_settle_commission)) {
|
||||
for (String order_id : order_id_settle_commission) {
|
||||
try {
|
||||
if (!shopDistributionUserOrderService.settleDistributionUserOrder(order_id)) {
|
||||
LogUtil.error(String.format(I18nUtil._("order_id : %s 确认佣金结算出错"), order_id));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(String.format(I18nUtil._("order_id : %s 确认佣金结算出错"), order_id), e);
|
||||
}
|
||||
// 3.分销结算
|
||||
List<String> order_id_settle_commission = shopOrderBaseService.getWaitingSettleCommissionOrder(null, null);
|
||||
if (CollUtil.isNotEmpty(order_id_settle_commission)) {
|
||||
for (String order_id : order_id_settle_commission) {
|
||||
try {
|
||||
if (!shopDistributionUserOrderService.settleDistributionUserOrder(order_id)) {
|
||||
LogUtil.error(String.format(I18nUtil._("order_id : %s 确认佣金结算出错"), order_id));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(String.format(I18nUtil._("order_id : %s 确认佣金结算出错"), order_id), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 预约订单定时任务,同步到 redis
|
||||
try {
|
||||
int count = shopOrderBookingService.syncOrderBooking2RedisTask();
|
||||
logger.info("同步预约订单任务到 redis 定时任务成功,成功数量:" + count);
|
||||
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(String.format(I18nUtil._("同步预约订单任务到 redis 定时任务失败")), e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -222,7 +222,7 @@ public class LakalaController extends BaseControllerImpl {
|
||||
@ApiOperation(value = "拉卡拉提现结果通知", notes = "拉卡拉提现结果通知")
|
||||
@RequestMapping(value = "/ewallet/drawNotify", method = RequestMethod.POST)
|
||||
public ResponseEntity<JSONObject> ewalletWithDrawNotify(HttpServletRequest request) {
|
||||
JSONObject resp = lakalaPayService.ewalletWithDrawNotify(request);
|
||||
JSONObject resp = lakalaPayService.ewalletWithDrawNotify(request, "", "");
|
||||
if (resp != null && "SUCCESS".equals(resp.get("code"))) {
|
||||
return ResponseEntity.ok(resp);
|
||||
}
|
||||
|
||||
@ -272,6 +272,17 @@ public interface LakalaApiService {
|
||||
*/
|
||||
JSONObject sacsQuery(String merchantNo, String separateNo);
|
||||
|
||||
/**
|
||||
* 提现结果查询
|
||||
* <p>
|
||||
* 参考:https://o.lakala.com/#/home/document/detail?id=366
|
||||
*
|
||||
* @param merchantNo 分账方商户号
|
||||
* @param drawJnl 提款流水号
|
||||
* @return 提现结果数据
|
||||
*/
|
||||
JSONObject ewalletWithdrawQuery(String merchantNo, String drawJnl);
|
||||
|
||||
|
||||
/**
|
||||
* 商户分账业务信息查询
|
||||
@ -304,6 +315,15 @@ public interface LakalaApiService {
|
||||
*/
|
||||
Integer fixUnSuccessSeparateStatusJob();
|
||||
|
||||
/**
|
||||
* 更改已经提现的状态(定时任务用途)
|
||||
* 该方法用于处理3天前未成功提现的订单记录,通过主动查询拉卡拉提现状态来更新本地记录
|
||||
* 每条记录最多处理5次,避免无限重试
|
||||
*
|
||||
* @return 成功处理的记录数量
|
||||
*/
|
||||
Integer fixUnSuccessDrawedStatusJob();
|
||||
|
||||
/**
|
||||
* 检测修复补全商户的商户分账业务信息及分账接收方绑定关系(分账业务申请异步通知的补偿机制)
|
||||
*
|
||||
@ -346,13 +366,15 @@ public interface LakalaApiService {
|
||||
Boolean ewalletWithDrawD1(String mercId, String merOrderNo, String drawAmt, String orderId, String summary);
|
||||
|
||||
/**
|
||||
* 拉卡拉账户D1提现结果通知
|
||||
* 拉卡拉账户D1提现结果通知处理(有补偿机制参数)
|
||||
* 参考:https://o.lakala.com/#/home/document/detail?id=367
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
* @param request HTTP请求对象,包含拉卡拉提现结果通知的参数
|
||||
* @param merchantNo 商户号 (补偿必选)
|
||||
* @param drawJnl 提现流水号 (补偿必选)
|
||||
* @return JSONObject 响应结果对象
|
||||
*/
|
||||
JSONObject ewalletWithDrawNotify(HttpServletRequest request);
|
||||
JSONObject ewalletWithDrawNotify(HttpServletRequest request, String merchantNo, String drawJnl);
|
||||
|
||||
/**
|
||||
* 商户分账参数计算及评估
|
||||
|
||||
@ -11,6 +11,9 @@ package com.suisung.mall.shop.lakala.service;
|
||||
import com.suisung.mall.common.modules.lakala.LklOrderDraw;
|
||||
import com.suisung.mall.core.web.service.IBaseService;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public interface LklOrderDrawService extends IBaseService<LklOrderDraw> {
|
||||
|
||||
/**
|
||||
@ -30,6 +33,18 @@ public interface LklOrderDrawService extends IBaseService<LklOrderDraw> {
|
||||
*/
|
||||
LklOrderDraw getByByMercIdAndMerOrderNo(String mercId, String merOrderNo);
|
||||
|
||||
|
||||
/**
|
||||
* 分页获取未成功提现的记录
|
||||
*
|
||||
* @param beginDate 开始时间(必须)
|
||||
* @param endDate 结束时间(可选,为空时默认为当前时间)
|
||||
* @param page 页码(从1开始)
|
||||
* @param pageSize 每页大小
|
||||
* @return 未成功提现的记录列表,参数无效时返回空列表而非null
|
||||
*/
|
||||
List<LklOrderDraw> getUnSuccessDrawedList(Date beginDate, Date endDate, Integer page, Integer pageSize);
|
||||
|
||||
/**
|
||||
* 判断订单是否已经提现完成
|
||||
*
|
||||
@ -37,4 +52,13 @@ public interface LklOrderDrawService extends IBaseService<LklOrderDraw> {
|
||||
* @return
|
||||
*/
|
||||
Boolean isOrderDrawed(String orderId);
|
||||
|
||||
/**
|
||||
* 判断订单是否已经提现完成
|
||||
*
|
||||
* @param merchantNo 商户号
|
||||
* @param drawJnl 提现流水号
|
||||
* @return 如果订单已提现完成返回true,否则返回false
|
||||
*/
|
||||
Boolean isOrderDrawed(String merchantNo, String drawJnl);
|
||||
}
|
||||
|
||||
@ -2110,6 +2110,87 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 提现结果查询
|
||||
* <p>
|
||||
* 参考:https://o.lakala.com/#/home/document/detail?id=366
|
||||
*
|
||||
* @param merchantNo 分账方商户号
|
||||
* @param drawJnl 提款流水号
|
||||
* @return 提现结果数据
|
||||
*/
|
||||
@Override
|
||||
public JSONObject ewalletWithdrawQuery(String merchantNo, String drawJnl) {
|
||||
// 1. 参数校验
|
||||
if (StrUtil.isBlank(merchantNo) || StrUtil.isBlank(drawJnl)) {
|
||||
log.warn("[提现结果查询] 参数校验失败:缺少必要参数, merchantNo={}, drawJnl={}", merchantNo, drawJnl);
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
// 查询提现表lkl_order_draw是否已经提现完成?
|
||||
Boolean isDrawed = lklOrderDrawService.isOrderDrawed(merchantNo, drawJnl);
|
||||
if (isDrawed != null && isDrawed) {
|
||||
log.warn("[提现结果查询] 已提现无效更新提现数据, merchantNo={}, drawJnl={}", merchantNo, drawJnl);
|
||||
return null;
|
||||
}
|
||||
|
||||
// 2. 配置初始化
|
||||
log.debug("[提现结果查询] 初始化拉卡拉SDK");
|
||||
initLKLSDK();
|
||||
|
||||
// 3. 装配数据
|
||||
log.debug("[提现结果查询] 装配请求参数,merchantNo={}, drawJnl={}", merchantNo, drawJnl);
|
||||
V2LaepIndustryEwalletWithdrawQueryRequest req = new V2LaepIndustryEwalletWithdrawQueryRequest();
|
||||
req.setOrgNo(orgCode);
|
||||
req.setMerchantNo(merchantNo);
|
||||
req.setDrawJnl(drawJnl);
|
||||
|
||||
// 4. 发送请求
|
||||
log.info("[提现结果查询] 开始查询提现结果,merchantNo={}, drawJnl={}", merchantNo, drawJnl);
|
||||
String responseStr = LKLSDK.httpPost(req);
|
||||
|
||||
if (StrUtil.isBlank(responseStr)) {
|
||||
log.error("[提现结果查询] 服务器无返回值, merchantNo={}, drawJnl={}", merchantNo, drawJnl);
|
||||
return null;
|
||||
}
|
||||
|
||||
JSONObject lakalaRespJSON = JSONUtil.parseObj(responseStr);
|
||||
if (lakalaRespJSON == null) {
|
||||
log.error("[提现结果查询] 响应数据解析失败, merchantNo={}, drawJnl={}, response={}",
|
||||
merchantNo, drawJnl, responseStr);
|
||||
return null;
|
||||
}
|
||||
|
||||
// 5. 检查业务状态码
|
||||
String retCode = lakalaRespJSON.getStr("retCode");
|
||||
if (!lklSuccessCode.equals(retCode)) {
|
||||
log.warn("[提现结果查询] 业务处理失败, merchantNo={}, drawJnl={}, retCode={}, retMsg={}",
|
||||
merchantNo, drawJnl, retCode, lakalaRespJSON.getStr("retMsg"));
|
||||
return null;
|
||||
}
|
||||
|
||||
// 6. 检查响应数据
|
||||
JSONObject respData = lakalaRespJSON.getJSONObject("respData");
|
||||
if (respData == null) {
|
||||
log.warn("[提现结果查询] 响应数据为空, merchantNo={}, drawJnl={}, response={}",
|
||||
merchantNo, drawJnl, responseStr);
|
||||
return null;
|
||||
}
|
||||
|
||||
log.info("[提现结果查询] 查询成功, merchantNo={}, drawJnl={}", merchantNo, drawJnl);
|
||||
return respData;
|
||||
|
||||
} catch (SDKException e) {
|
||||
log.error("[提现结果查询] SDK调用异常, merchantNo={}, drawJnl={}", merchantNo, drawJnl, e);
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
log.error("[提现结果查询] 查询过程中发生未知异常, merchantNo={}, drawJnl={}", merchantNo, drawJnl, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 商户分账业务信息查询
|
||||
* 参考:https://o.lakala.com/#/home/document/detail?id=381
|
||||
@ -3160,6 +3241,126 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更改已经提现的状态(定时任务用途)
|
||||
* 该方法用于处理3天前未成功提现的订单记录,通过主动查询拉卡拉提现状态来更新本地记录
|
||||
* 每条记录最多处理5次,避免无限重试
|
||||
*
|
||||
* @return 成功处理的记录数量
|
||||
*/
|
||||
@Override
|
||||
public Integer fixUnSuccessDrawedStatusJob() {
|
||||
log.info("[提现状态修复任务] 开始执行未成功提现记录的状态修复任务");
|
||||
|
||||
// 获取3天前提现状态未成功的记录
|
||||
Date endDate = new Date();
|
||||
Date beginDate = DateUtils.addDays(endDate, -3); // 3天前
|
||||
|
||||
// 分页参数
|
||||
int pageSize = 200;
|
||||
int currentPage = 1;
|
||||
int totalSuccessCount = 0;
|
||||
int totalProcessed = 0;
|
||||
|
||||
// 记录处理开始时间
|
||||
long startTime = System.currentTimeMillis();
|
||||
String redisPrefKey = "lkl:draw:status:retry:";
|
||||
|
||||
try {
|
||||
List<LklOrderDraw> lklOrderDraws;
|
||||
do {
|
||||
// 分页获取未成功提现的记录
|
||||
lklOrderDraws = lklOrderDrawService.getUnSuccessDrawedList(beginDate, endDate, currentPage, pageSize);
|
||||
|
||||
if (CollectionUtil.isEmpty(lklOrderDraws)) {
|
||||
break;
|
||||
}
|
||||
|
||||
log.info("[提现状态修复任务] 获取到第{}页数据,共{}条记录", currentPage, lklOrderDraws.size());
|
||||
|
||||
// 按处理次数排序,从未处理过的记录优先处理,处理次数越多优先级越低
|
||||
lklOrderDraws.sort((o1, o2) -> {
|
||||
String redisKey1 = redisPrefKey + o1.getDraw_jnl();
|
||||
String redisKey2 = redisPrefKey + o2.getDraw_jnl();
|
||||
|
||||
int retryCount1 = Convert.toInt(redisService.get(redisKey1), 0);
|
||||
int retryCount2 = Convert.toInt(redisService.get(redisKey2), 0);
|
||||
|
||||
return Integer.compare(retryCount1, retryCount2);
|
||||
});
|
||||
|
||||
// 处理当前页中的记录
|
||||
for (LklOrderDraw record : lklOrderDraws) {
|
||||
// 检查该记录的处理次数是否已达到上限(5次)
|
||||
String redisKey = redisPrefKey + record.getDraw_jnl();
|
||||
int retryCount = Convert.toInt(redisService.get(redisKey), 0);
|
||||
|
||||
if (retryCount >= 5) {
|
||||
log.warn("[提现状态修复任务] 记录已达到最大重试次数,跳过处理: merchantNo={}, drawJnl={}",
|
||||
record.getMerc_id(), record.getDraw_jnl());
|
||||
continue;
|
||||
}
|
||||
|
||||
totalProcessed++;
|
||||
// 每处理10条记录才输出一次详细日志,减少日志量
|
||||
if (totalProcessed % 10 == 1) {
|
||||
log.info("[提现状态修复任务] 正在处理第 {} 条记录: merchantNo={}, drawJnl={}, 已重试{}次",
|
||||
totalProcessed, record.getMerc_id(), record.getDraw_jnl(), retryCount);
|
||||
}
|
||||
|
||||
try {
|
||||
// 增加处理次数计数并设置3天过期时间
|
||||
redisService.incr(redisKey, 1);
|
||||
redisService.expire(redisKey, 3 * 24 * 60 * 60);
|
||||
|
||||
// 调用拉卡拉提现查询接口进行状态补偿
|
||||
JSONObject drawResult = ewalletWithDrawNotify(null, record.getMerc_id(), record.getDraw_jnl());
|
||||
|
||||
// 检查处理结果
|
||||
if (drawResult != null && "SUCCESS".equals(drawResult.getStr("code", ""))) {
|
||||
totalSuccessCount++;
|
||||
log.debug("[提现状态修复任务] 记录处理成功: merchantNo={}, drawJnl={}",
|
||||
record.getMerc_id(), record.getDraw_jnl());
|
||||
} else {
|
||||
log.warn("[提现状态修复任务] 记录处理失败: merchantNo={}, drawJnl={}",
|
||||
record.getMerc_id(), record.getDraw_jnl());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("[提现状态修复任务] 处理记录时发生异常: merchantNo={}, drawJnl={}",
|
||||
record.getMerc_id(), record.getDraw_jnl(), e);
|
||||
}
|
||||
}
|
||||
|
||||
log.info("[提现状态修复任务] 第{}页处理完成,已处理 {} 条记录,总成功 {} 条",
|
||||
currentPage, totalProcessed, totalSuccessCount);
|
||||
|
||||
// 如果当前页数据少于页面大小,说明已经是最后一页
|
||||
if (lklOrderDraws.size() < pageSize) {
|
||||
break;
|
||||
}
|
||||
|
||||
currentPage++;
|
||||
|
||||
// 添加短暂延迟,避免对系统造成过大压力
|
||||
Thread.sleep(100);
|
||||
|
||||
} while (!CollectionUtil.isEmpty(lklOrderDraws));
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
log.warn("[提现状态修复任务] 任务被中断");
|
||||
Thread.currentThread().interrupt();
|
||||
} catch (Exception e) {
|
||||
log.error("[提现状态修复任务] 任务执行过程中发生异常", e);
|
||||
}
|
||||
|
||||
long endTime = System.currentTimeMillis();
|
||||
log.info("[提现状态修复任务] 任务执行完成,总共处理 {} 条记录,成功处理 {} 条记录,耗时 {} ms",
|
||||
totalProcessed, totalSuccessCount, (endTime - startTime));
|
||||
|
||||
return totalSuccessCount;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检测修复补全商户的商户分账业务信息及分账接收方绑定关系(分账业务申请异步通知的补偿机制)
|
||||
*
|
||||
@ -3629,29 +3830,40 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
|
||||
|
||||
/**
|
||||
* 拉卡拉账户D1提现结果通知处理
|
||||
* 拉卡拉账户D1提现结果通知处理(有补偿机制参数)
|
||||
* 参考:https://o.lakala.com/#/home/document/detail?id=367
|
||||
*
|
||||
* @param request HTTP请求对象,包含拉卡拉提现结果通知的参数
|
||||
* @param request HTTP请求对象,包含拉卡拉提现结果通知的参数
|
||||
* @param merchantNo 商户号 (补偿必选)
|
||||
* @param drawJnl 提现流水号 (补偿必选)
|
||||
* @return JSONObject 响应结果对象
|
||||
*/
|
||||
@Override
|
||||
public JSONObject ewalletWithDrawNotify(HttpServletRequest request) {
|
||||
public JSONObject ewalletWithDrawNotify(HttpServletRequest request, String merchantNo, String drawJnl) {
|
||||
log.debug("[拉卡拉D1提现结果通知] 开始处理拉卡拉提现结果通知");
|
||||
|
||||
try {
|
||||
// 1. 验签处理 - 验证通知来源的合法性
|
||||
Pair<Boolean, String> signCheckResult = LakalaUtil.chkLklApiNotifySign(request, lklNotifyCerPath, false);
|
||||
if (!signCheckResult.getFirst()) {
|
||||
log.warn("[拉卡拉D1提现结果通知] 验签失败: {}", signCheckResult.getSecond());
|
||||
return JSONUtil.createObj()
|
||||
.set("code", "FAIL")
|
||||
.set("message", signCheckResult.getSecond());
|
||||
JSONObject paramsJSON;
|
||||
Pair<Boolean, String> signCheckResult = null;
|
||||
if (request != null) {
|
||||
// 1. 验签处理 - 验证通知来源的合法性
|
||||
signCheckResult = LakalaUtil.chkLklApiNotifySign(request, lklNotifyCerPath, false);
|
||||
if (signCheckResult != null && !signCheckResult.getFirst()) {
|
||||
log.warn("[拉卡拉D1提现结果通知] 验签失败: {}", signCheckResult.getSecond());
|
||||
return JSONUtil.createObj()
|
||||
.set("code", "FAIL")
|
||||
.set("message", signCheckResult.getSecond());
|
||||
}
|
||||
|
||||
// 2. 解析回调参数
|
||||
paramsJSON = JSONUtil.parseObj(signCheckResult.getSecond());
|
||||
} else {
|
||||
// 补偿机制。主动从拉卡拉上获取提现结果
|
||||
paramsJSON = ewalletWithdrawQuery(merchantNo, drawJnl);
|
||||
}
|
||||
|
||||
// 2. 解析回调参数
|
||||
JSONObject paramsJSON = JSONUtil.parseObj(signCheckResult.getSecond());
|
||||
if (paramsJSON == null) {
|
||||
|
||||
if (JSONUtil.isNull(paramsJSON)) {
|
||||
log.warn("[拉卡拉D1提现结果通知] 回调参数解析失败");
|
||||
return JSONUtil.createObj()
|
||||
.set("code", "FAIL")
|
||||
@ -3661,16 +3873,25 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
String drawState = paramsJSON.getStr("drawState");
|
||||
String mercId = paramsJSON.getStr("mercId");
|
||||
String merOrderNo = paramsJSON.getStr("merOrderNo");
|
||||
String drawJnlRemote = paramsJSON.getStr("drawJnl");
|
||||
|
||||
log.info("[拉卡拉D1提现结果通知] 提现通知参数: drawState={}, mercId={}, merOrderNo={}", drawState, mercId, merOrderNo);
|
||||
log.info("[拉卡拉D1提现结果通知] 提现通知参数: drawState={}, mercId={}, merOrderNo={},drawJnlRemote={}", drawState, mercId, merOrderNo, drawJnlRemote);
|
||||
|
||||
if (StrUtil.hasBlank(mercId, merOrderNo, drawState)) {
|
||||
log.warn("[拉卡拉提现结果通知] 回调参数缺失: drawState={}, mercId={}, merOrderNo={}", drawState, mercId, merOrderNo);
|
||||
if (StrUtil.hasBlank(mercId, merOrderNo, drawJnl, drawState)) {
|
||||
log.warn("[拉卡拉提现结果通知] 回调参数缺失: drawState={}, mercId={}, merOrderNo={}, drawJnlRemote={}", drawState, mercId, merOrderNo, drawJnlRemote);
|
||||
return JSONUtil.createObj()
|
||||
.set("code", "FAIL")
|
||||
.set("message", "回调参数错误");
|
||||
}
|
||||
|
||||
Boolean isCompensate = lklOrderDrawService.isOrderDrawed(mercId, drawJnl);
|
||||
if (isCompensate) {
|
||||
log.warn("[拉卡拉D1提现结果通知] 提现结果通知已处理,忽略处理: mercId={}, merOrderNo={}, drawJnl={}", mercId, merOrderNo, drawJnl);
|
||||
return JSONUtil.createObj()
|
||||
.set("code", "SUCCESS")
|
||||
.set("message", "提现结果通知已处理");
|
||||
}
|
||||
|
||||
// 只处理成功的提现状态
|
||||
if (!"DRAW.SUCCESS".equals(drawState)) {
|
||||
log.debug("[拉卡拉D1提现结果通知] 提现状态未成功,忽略处理: drawState={}", drawState);
|
||||
|
||||
@ -2,6 +2,7 @@ package com.suisung.mall.shop.lakala.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.suisung.mall.common.modules.lakala.LklOrderDraw;
|
||||
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
|
||||
import com.suisung.mall.shop.lakala.mapper.LklOrderDrawMapper;
|
||||
@ -9,6 +10,10 @@ import com.suisung.mall.shop.lakala.service.LklOrderDrawService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class LklOrderDrawServiceImpl extends BaseServiceImpl<LklOrderDrawMapper, LklOrderDraw> implements LklOrderDrawService {
|
||||
@ -103,6 +108,70 @@ public class LklOrderDrawServiceImpl extends BaseServiceImpl<LklOrderDrawMapper,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 分页获取未成功提现的记录
|
||||
*
|
||||
* @param beginDate 开始时间(必须)
|
||||
* @param endDate 结束时间(可选,为空时默认为当前时间)
|
||||
* @param page 页码(从1开始)
|
||||
* @param pageSize 每页大小
|
||||
* @return 未成功提现的记录列表,参数无效时返回空列表而非null
|
||||
*/
|
||||
@Override
|
||||
public List<LklOrderDraw> getUnSuccessDrawedList(Date beginDate, Date endDate, Integer page, Integer pageSize) {
|
||||
// 1. 参数校验
|
||||
if (beginDate == null) {
|
||||
log.warn("[分页查询未成功提现记录] 开始时间不能为空");
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if (page == null || page < 1) {
|
||||
log.warn("[分页查询未成功提现记录] 页码必须大于0,当前页码: {}", page);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if (pageSize == null || pageSize <= 0) {
|
||||
log.warn("[分页查询未成功提现记录] 页面大小必须大于0,当前大小: {}", pageSize);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// 2. 处理结束时间默认值
|
||||
Date actualEndDate = (endDate != null) ? endDate : new Date();
|
||||
|
||||
// 3. 参数合理性校验
|
||||
if (beginDate.after(actualEndDate)) {
|
||||
log.warn("[分页查询未成功提现记录] 开始时间{}不能晚于结束时间{}", beginDate, actualEndDate);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
try {
|
||||
// 4. 构造查询条件
|
||||
QueryWrapper<LklOrderDraw> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.select("id", "merc_id", "draw_jnl", "draw_state", "created_at")
|
||||
.isNotNull("draw_jnl")
|
||||
.isNotNull("merc_id")
|
||||
.ne("draw_state", "DRAW.SUCCESS")
|
||||
.ge("created_at", beginDate)
|
||||
.le("created_at", actualEndDate)
|
||||
.orderByDesc("id");
|
||||
|
||||
// 5. 执行分页查询
|
||||
Page<LklOrderDraw> resultPage = lists(queryWrapper, page, pageSize);
|
||||
List<LklOrderDraw> result = resultPage.getRecords();
|
||||
|
||||
log.info("[分页查询未成功提现记录] 查询完成,开始时间={},结束时间={},页码={},页面大小={},结果数量={}",
|
||||
beginDate, actualEndDate, page, pageSize, (result != null ? result.size() : 0));
|
||||
|
||||
return result != null ? result : Collections.emptyList();
|
||||
} catch (Exception e) {
|
||||
log.error("[分页查询未成功提现记录] 查询过程中发生异常,开始时间={},结束时间={},页码={},页面大小={}",
|
||||
beginDate, endDate, page, pageSize, e);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断订单是否已经提现完成
|
||||
*
|
||||
@ -121,7 +190,7 @@ public class LklOrderDrawServiceImpl extends BaseServiceImpl<LklOrderDrawMapper,
|
||||
// 查询提现成功的记录
|
||||
LklOrderDraw lklOrderDraw = findOne(new QueryWrapper<LklOrderDraw>()
|
||||
.eq("order_id", orderId)
|
||||
.eq("draw_state", "DRAW.SUCCESS")
|
||||
// .eq("draw_state", "DRAW.SUCCESS")
|
||||
.orderByDesc("id"));
|
||||
|
||||
// 根据查询结果判断是否已提现
|
||||
@ -137,4 +206,42 @@ public class LklOrderDrawServiceImpl extends BaseServiceImpl<LklOrderDrawMapper,
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断订单是否已经提现完成
|
||||
*
|
||||
* @param merchantNo 商户号
|
||||
* @param drawJnl 提现流水号
|
||||
* @return 如果订单已提现完成返回true,否则返回false
|
||||
*/
|
||||
@Override
|
||||
public Boolean isOrderDrawed(String merchantNo, String drawJnl) {
|
||||
// 参数校验
|
||||
if (StrUtil.hasBlank(merchantNo, drawJnl)) {
|
||||
log.warn("[LklOrderDraw] 参数校验失败:商户号或提现流水号为空, merchantNo={}, drawJnl={}", merchantNo, drawJnl);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
log.debug("[LklOrderDraw] 开始查询订单提现状态, merchantNo={}, drawJnl={}", merchantNo, drawJnl);
|
||||
|
||||
// 查询提现成功的记录
|
||||
LklOrderDraw lklOrderDraw = findOne(new QueryWrapper<LklOrderDraw>()
|
||||
.eq("merc_id", merchantNo)
|
||||
.eq("draw_jnl", drawJnl)
|
||||
.eq("draw_state", "DRAW.SUCCESS")
|
||||
.orderByDesc("id"));
|
||||
|
||||
boolean isDrawed = lklOrderDraw != null;
|
||||
|
||||
log.debug("[LklOrderDraw] 订单提现状态查询完成, merchantNo={}, drawJnl={}, isDrawed={}",
|
||||
merchantNo, drawJnl, isDrawed);
|
||||
|
||||
return isDrawed;
|
||||
} catch (Exception e) {
|
||||
log.error("[LklOrderDraw] 查询订单提现状态异常, merchantNo={}, drawJnl={}", merchantNo, drawJnl, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -149,15 +149,20 @@ public class OrderPayedListener {
|
||||
if (order_state_id == StateCode.ORDER_STATE_WAIT_PAY
|
||||
|| order_state_id == StateCode.ORDER_STATE_WAIT_REVIEW
|
||||
|| order_state_id == StateCode.ORDER_STATE_WAIT_FINANCE_REVIEW) {
|
||||
|
||||
// 是预约订单吗?
|
||||
boolean isBookingOrder = shopOrderInfoService.isBookingOrder(orderInfoOld);
|
||||
|
||||
// 已支付的订单,生成取单号,打票机并打印订单
|
||||
Long orderPickupNum = shopOrderInfoService.isPaidOrderGenPickNumAndPrint(orderInfoOld.getStore_id(), orderId);
|
||||
|
||||
// 如果配送方式是 顺丰同城下单
|
||||
// 如果配送方式是 顺丰同城, 且立即下单,则触发顺丰同城下单
|
||||
if (CheckUtil.isNotEmpty(orderInfoOld.getDelivery_type_id())
|
||||
&& orderInfoOld.getDelivery_type_id().equals(StateCode.DELIVERY_TYPE_SAME_CITY)
|
||||
&& CheckUtil.isNotEmpty(orderPickupNum)) {
|
||||
&& CheckUtil.isNotEmpty(orderPickupNum)
|
||||
&& !isBookingOrder) {
|
||||
|
||||
// 顺丰同城下单
|
||||
// 如果是立即下单,将触发顺丰同城下单,否则(预约下单) redis+cron 定时触发顺丰同城下单
|
||||
Pair<Boolean, String> pairCreateSfOrder = sfExpressApiService.innerCreateSfExpressOrder(orderId, orderPickupNum);
|
||||
if (pairCreateSfOrder == null) {
|
||||
logger.error("[订单支付监听] 顺丰同城下单失败,无返回值 订单ID: {}", orderId);
|
||||
@ -183,24 +188,28 @@ public class OrderPayedListener {
|
||||
}
|
||||
|
||||
// 同城配送或普通快递,都发送 unipush 推送:您有一个新的订单,请查收!
|
||||
String orderType = orderInfoOld.getDelivery_type_id() == StateCode.DELIVERY_TYPE_SAME_CITY ? "同城" : "";
|
||||
String bookingTip = isBookingOrder ? "预约" : "";
|
||||
|
||||
String orderType = orderInfoOld.getDelivery_type_id() == StateCode.DELIVERY_TYPE_SAME_CITY ? "同城" + bookingTip : bookingTip;
|
||||
String title = String.format("您有一笔新的%s订单,请注意查收。", orderType);
|
||||
String content = String.format("这笔新%s订单:%s,用户于%s下的单,请注意查收。", orderType, orderId, DateTimeUtils.formatDateTime(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss"));
|
||||
String content = String.format("这笔新的%s订单:%s,用户于%s下的单,请注意查收。", orderType, orderId, DateTimeUtils.formatDateTime(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss"));
|
||||
JSONObject payload = new JSONObject();
|
||||
payload.put("category", CommonConstant.PUSH_MSG_CATE_MCH_ONLINE_ORDER_LIST);
|
||||
payload.put("orderId", orderId);
|
||||
pushMessageService.noticeMerchantEmployeeOrderAction(orderInfoOld.getStore_id(), orderId, title, content, payload);
|
||||
|
||||
// 发送延迟消息 25分钟拣货配送时间(提前5分钟,下单20分钟后,提醒商家及时拣货)
|
||||
Long mchOrderExpireSeconds = shopOrderBaseService.sameCityOrderExpireSeconds(1500L) - 300;
|
||||
redisService.set(RedisConstant.SF_Order_Proc_WillExpire_Key + String.format("%d&%s", orderInfoOld.getStore_id(), orderId), orderId, mchOrderExpireSeconds);
|
||||
if (!isBookingOrder) { // 非预约下单的情况
|
||||
// 发送延迟消息 25分钟拣货配送时间(提前5分钟,下单20分钟后,提醒商家及时拣货)
|
||||
Long mchOrderExpireSeconds = shopOrderBaseService.sameCityOrderExpireSeconds(1500L) - 300;
|
||||
redisService.set(RedisConstant.SF_Order_Proc_WillExpire_Key + String.format("%d&%s", orderInfoOld.getStore_id(), orderId), orderId, mchOrderExpireSeconds);
|
||||
|
||||
// 发送延迟消息 25分钟拣货配送时间(下单25分钟后,提醒商家及时拣货)
|
||||
mchOrderExpireSeconds = shopOrderBaseService.sameCityOrderExpireSeconds(1500L);
|
||||
redisService.set(RedisConstant.SF_Order_Proc_Expire_Key + String.format("%d&%s", orderInfoOld.getStore_id(), orderId), orderId, mchOrderExpireSeconds);
|
||||
// 发送延迟消息 25分钟拣货配送时间(下单25分钟后,提醒商家及时拣货)
|
||||
mchOrderExpireSeconds = shopOrderBaseService.sameCityOrderExpireSeconds(1500L);
|
||||
redisService.set(RedisConstant.SF_Order_Proc_Expire_Key + String.format("%d&%s", orderInfoOld.getStore_id(), orderId), orderId, mchOrderExpireSeconds);
|
||||
|
||||
// 记录推送已发送状态,避免重复推送
|
||||
redisService.set(pushFlagKey, "1", 24 * 3600); // 24小时过期
|
||||
// 记录推送已发送状态,避免重复推送
|
||||
redisService.set(pushFlagKey, "1", 24 * 3600); // 24小时过期
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("[订单支付监听] 发送推送消息失败. 订单ID: {}", orderId, e);
|
||||
|
||||
@ -15,9 +15,12 @@ import cn.hutool.json.JSONObject;
|
||||
import com.suisung.mall.common.constant.CommonConstant;
|
||||
import com.suisung.mall.common.constant.RedisConstant;
|
||||
import com.suisung.mall.shop.message.service.PushMessageService;
|
||||
import com.suisung.mall.shop.order.service.ShopOrderInfoService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.data.redis.connection.Message;
|
||||
import org.springframework.data.redis.connection.MessageListener;
|
||||
import org.springframework.data.util.Pair;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@ -27,6 +30,10 @@ public class RedisKeyExpiredListener implements MessageListener {
|
||||
@Resource
|
||||
private PushMessageService pushMessageService;
|
||||
|
||||
@Lazy
|
||||
@Resource
|
||||
private ShopOrderInfoService shopOrderInfoService;
|
||||
|
||||
/**
|
||||
* Callback for processing received objects through Redis.
|
||||
*
|
||||
@ -83,6 +90,24 @@ public class RedisKeyExpiredListener implements MessageListener {
|
||||
} else {
|
||||
log.error("[Redis过期监听] 订单即将超时事件处理失败. 店铺ID: {}, 订单号: {}", args[0], args[1]);
|
||||
}
|
||||
} else if (expiredKey.startsWith(RedisConstant.Order_Booking_Task_Key)) {
|
||||
// 预约订单向顺丰同城下单
|
||||
log.debug("[预约订单顺丰同城下单Redis过期监听] 开始处理预约订单顺丰同城下单超时事件. 过期键: {}", expiredKey);
|
||||
|
||||
// orderId
|
||||
String orderId = expiredKey.replace(RedisConstant.Order_Booking_Task_Key, "");
|
||||
if (StrUtil.isBlank(orderId)) {
|
||||
log.error("[预约订单顺丰同城下单Redis过期监听] 键: {} 不符合预期格式,无法解析订单号", expiredKey);
|
||||
return;
|
||||
}
|
||||
|
||||
// 重要:预约订单向顺丰同城下单
|
||||
Pair<Boolean, String> result = shopOrderInfoService.runBookingOrder2SfExpressOrder(orderId);
|
||||
if (result == null || !result.getFirst()) {
|
||||
log.error("[预约订单顺丰同城下单Redis过期监听] 顺丰同城下单失败:{}, 订单号: {}", result != null ? result.getSecond() : "", orderId);
|
||||
} else {
|
||||
log.info("[预约订单顺丰同城下单Redis过期监听] 顺丰同城下单成功. 订单号: {}", orderId);
|
||||
}
|
||||
} else {
|
||||
//log.debug("[Redis过期监听] 忽略非订单超时事件. 过期键: {}", expiredKey);
|
||||
}
|
||||
|
||||
@ -10,6 +10,17 @@ package com.suisung.mall.shop.order.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.suisung.mall.common.modules.order.ShopOrderBooking;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ShopOrderBookingMapper extends BaseMapper<ShopOrderBooking> {
|
||||
|
||||
/**
|
||||
* 查询有效的(未到下单时机,执行时间未过期,订单状态正确)预约订单任务
|
||||
*
|
||||
* @param limit_count
|
||||
* @return
|
||||
*/
|
||||
List<ShopOrderBooking> selectValidBookingList(@Param("limit_count") Integer limit_count);
|
||||
}
|
||||
|
||||
@ -8,10 +8,60 @@
|
||||
|
||||
package com.suisung.mall.shop.order.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.suisung.mall.common.modules.order.ShopOrderBooking;
|
||||
import com.suisung.mall.core.web.service.IBaseService;
|
||||
|
||||
public interface ShopOrderBookingService extends IBaseService<ShopOrderBooking> {
|
||||
|
||||
/**
|
||||
* 添加预约订单任务
|
||||
*
|
||||
* @param orderId 订单ID
|
||||
* @param bookingAt 预约时间
|
||||
* @return 是否添加成功
|
||||
*/
|
||||
Boolean setupRedisBookingTask(String orderId, Long bookingAt);
|
||||
|
||||
}
|
||||
/**
|
||||
* 添加或更新预约订单任务
|
||||
*
|
||||
* @param shopOrderBooking 预约订单任务信息
|
||||
* @return 操作后的预约订单任务实例
|
||||
*/
|
||||
ShopOrderBooking addOrUpdate(ShopOrderBooking shopOrderBooking);
|
||||
|
||||
/**
|
||||
* 查询有效的预约订单任务分页列表(按预约时间升序排序)
|
||||
*
|
||||
* @param pageNum 页码
|
||||
* @param pageSize 页大小
|
||||
* @return 分页结果
|
||||
*/
|
||||
Page<ShopOrderBooking> findValidBookingList(Integer pageNum, Integer pageSize);
|
||||
|
||||
/**
|
||||
* 更新预约订单任务
|
||||
*
|
||||
* @param updateWrapper 更新条件包装器
|
||||
* @return 是否更新成功
|
||||
*/
|
||||
Boolean update(UpdateWrapper<ShopOrderBooking> updateWrapper);
|
||||
|
||||
/**
|
||||
* 更改预约订单任务下单完成状态(同时删除 redis 的定时任务)
|
||||
*
|
||||
* @param orderId 订单ID
|
||||
* @return 是否完成同城下单
|
||||
*/
|
||||
Boolean updateOrderBookingFinishState(String orderId);
|
||||
|
||||
/**
|
||||
* 同步预约订单任务到 redis 定时任务
|
||||
*
|
||||
* @return 同步数量
|
||||
*/
|
||||
Integer syncOrderBooking2RedisTask();
|
||||
|
||||
}
|
||||
@ -116,4 +116,21 @@ public interface ShopOrderInfoService extends IBaseService<ShopOrderInfo> {
|
||||
* @return
|
||||
*/
|
||||
Pair<Boolean, String> checkBookingOrderArgs(Integer storeId, Integer bookingState, String bookingBeginTime, String bookingEndTime);
|
||||
|
||||
|
||||
/**
|
||||
* 判断订单是否为预约订单
|
||||
*
|
||||
* @param orderInfo 订单信息
|
||||
* @return 是否为预约订单
|
||||
*/
|
||||
Boolean isBookingOrder(ShopOrderInfo orderInfo);
|
||||
|
||||
/**
|
||||
* 预约订单到点后生成顺丰订单
|
||||
*
|
||||
* @param orderId 订单ID
|
||||
* @return
|
||||
*/
|
||||
Pair<Boolean, String> runBookingOrder2SfExpressOrder(String orderId);
|
||||
}
|
||||
|
||||
@ -97,10 +97,8 @@ import com.suisung.mall.shop.product.pojo.vo.FixOrderVo;
|
||||
import com.suisung.mall.shop.product.service.*;
|
||||
import com.suisung.mall.shop.sfexpress.service.SFExpressApiService;
|
||||
import com.suisung.mall.shop.store.service.*;
|
||||
import com.suisung.mall.shop.sync.service.SyncThirdDataService;
|
||||
import com.suisung.mall.shop.user.service.*;
|
||||
import com.suisung.mall.shop.wechat.service.WxOrderShippingService;
|
||||
import io.seata.common.util.StringUtils;
|
||||
import io.seata.core.context.RootContext;
|
||||
import io.seata.core.exception.TransactionException;
|
||||
import io.seata.spring.annotation.GlobalTransactional;
|
||||
@ -383,7 +381,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private SyncThirdDataService syncThirdDataService;
|
||||
private ShopOrderBookingService shopOrderBookingService;
|
||||
|
||||
@Autowired
|
||||
private ThreadPoolExecutor executor;
|
||||
@ -6641,12 +6639,16 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
info_row.setBooking_at(bookingBeginTime.getTime() / 1000); // 预订单到达时间戳(秒)
|
||||
info_row.setBooking_begin_time(bookingBeginTime);
|
||||
info_row.setBooking_end_time(bookingEndTime);
|
||||
|
||||
// 重要:预约订单任务创建处理
|
||||
Boolean isSuccess = shopOrderBookingService.setupRedisBookingTask(info_row.getOrder_id(), info_row.getBooking_at());
|
||||
if (!isSuccess) {
|
||||
throw new ApiException(I18nUtil._("保存预约订单任务失败!"));
|
||||
}
|
||||
}
|
||||
|
||||
info_row.setActivity_json(JSONUtil.toJsonStr(store_item.get("discount_detail_rows")));
|
||||
|
||||
info_row.setPayment_form_id(payment_form_id);
|
||||
|
||||
UserDto user = getCurrentUser();
|
||||
if (ObjectUtil.isNotEmpty(user) && user.isChain()) {
|
||||
info_row.setChain_id(Convert.toInt(user.getChain_id()));
|
||||
@ -8697,8 +8699,12 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
orderItems.add(ent.rebuild());
|
||||
}
|
||||
|
||||
// 7位数取单号,位数不够向左补0 (同城配送的取单号)String.format("%07d", m.get("order_pickup_num"))
|
||||
m.put("order_pickup_num_str", fmtPickNum(Convert.toLong(m.get("order_pickup_num"))));
|
||||
// 是否预约订单?
|
||||
Integer booking_state = Convert.toInt(m.getOrDefault("booking_state", 1));
|
||||
boolean isBookingOrder = booking_state.equals(CommonConstant.Order_Booking_State_YY) && m.get("booking_begin_time") != null;
|
||||
|
||||
// 7位数取单号,位数不够向左补0 (同城配送的取单号)
|
||||
m.put("order_pickup_num_str", StringUtils.fmtPickNum(Convert.toLong(m.get("order_pickup_num"))));
|
||||
m.put("seller_message", "");//卖家留言
|
||||
m.put("order_items", orderItems);//订单商品列表
|
||||
m.put("order_items_count", orderItems.size());//商品数量
|
||||
@ -8713,7 +8719,14 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
|
||||
// 配送时间= 支付时间+35分钟
|
||||
Long mchOrderExpireSeconds = shopOrderBaseService.sameCityOrderExpireSeconds(2100L);
|
||||
m.put("delivery_time", DateUtil.offsetSecond((Date) m.get("payment_time"), mchOrderExpireSeconds.intValue()));
|
||||
// 配送时间
|
||||
Date paymentTime = Convert.toDate(m.get("payment_time"));
|
||||
if (isBookingOrder && paymentTime != null) {
|
||||
// 预约送达时间
|
||||
paymentTime = Convert.toDate(m.get("booking_begin_time"));
|
||||
}
|
||||
m.put("delivery_time", DateUtil.offsetSecond(paymentTime, mchOrderExpireSeconds.intValue()));
|
||||
|
||||
// 配送方式
|
||||
String deliveryTypeName = StateCode.DELIVERY_TYPE_MAP.getOrDefault(m.getOrDefault("delivery_type_id", StateCode.DELIVERY_TYPE_SAME_CITY), "普通快递");
|
||||
m.put("delivery_type_name", deliveryTypeName);
|
||||
@ -8725,6 +8738,8 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
m.put("yajin", 0.00); // 押金
|
||||
m.put("cashier", m.getOrDefault("store_name", "店长")); // 收银员
|
||||
m.put("order_source", "微信小程序"); // 订单来源
|
||||
m.put("is_booking_order", isBookingOrder);
|
||||
m.put("booking_state", booking_state); //订单配送预约状态:1-立即配送;2-预约配送;
|
||||
|
||||
return m;
|
||||
}
|
||||
@ -8748,6 +8763,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
|
||||
ShopOrderBase shopOrderBase = shopOrderBaseService.getById(shopOrderId);
|
||||
ShopOrderData shopOrderData = shopOrderDataService.get(shopOrderId);
|
||||
|
||||
QueryWrapper<ShopOrderItem> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("order_id", shopOrderId);
|
||||
List<ShopOrderItem> shopOrderItemList = shopOrderItemService.list(queryWrapper);
|
||||
@ -8771,6 +8787,11 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
return null;
|
||||
}
|
||||
|
||||
// if (CheckUtil.isEmpty(orderPickupNum) && CheckUtil.isEmpty(shopOrderInfo.getOrder_pickup_num())) {
|
||||
// logger.error("构建顺丰订单失败:无法获取取单号,订单ID={},storeId={}", shopOrderId, storeId);
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// 顺丰同城给的测试店铺id
|
||||
String shopId = "3243279847393";
|
||||
//3269768224353 到时启用这个正式店铺 type:便利店
|
||||
@ -8795,9 +8816,22 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
sfCreateOrderReq.setOrder_source(shopStoreBase.getStore_name()); //订单来源
|
||||
sfCreateOrderReq.setRemark(shopOrderData.getOrder_message()); // 订单留言
|
||||
|
||||
// 7位数取单号,位数不够向左补0
|
||||
String orderPickupNumStr = String.format("%07d", orderPickupNum);
|
||||
sfCreateOrderReq.setOrder_sequence(orderPickupNumStr); //拣货编号
|
||||
// 获取并格式化取单号
|
||||
String orderPickupNumStr = "";
|
||||
// 如果传入取单号为空,从订单信息中获取
|
||||
if (CheckUtil.isEmpty(orderPickupNum)) {
|
||||
ShopOrderInfo shopOrderInfo = shopOrderInfoService.get(shopOrderId);
|
||||
orderPickupNum = shopOrderInfo != null ? shopOrderInfo.getOrder_pickup_num() : 0L;
|
||||
}
|
||||
|
||||
// 格式化取单号并设置到顺丰订单
|
||||
if (CheckUtil.isNotEmpty(orderPickupNum)) {
|
||||
orderPickupNumStr = StringUtils.fmtPickNum(orderPickupNum);
|
||||
sfCreateOrderReq.setOrder_sequence(orderPickupNumStr);
|
||||
} else {
|
||||
logger.error("构建顺丰订单失败:取单号错误,订单ID={},storeId={}", shopOrderId, storeId);
|
||||
}
|
||||
|
||||
sfCreateOrderReq.setVersion(19);
|
||||
sfCreateOrderReq.setReturn_flag(511);
|
||||
|
||||
@ -8974,7 +9008,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
}
|
||||
|
||||
// 格式化取货号
|
||||
order.setOrder_pickup_num_str(fmtPickNum(order.getOrder_pickup_num()));
|
||||
order.setOrder_pickup_num_str(StringUtils.fmtPickNum(order.getOrder_pickup_num()));
|
||||
|
||||
// 订单是否禁止退款
|
||||
int isOrderDenyReturn = shopOrderReturnService.isOrderDenyReturn(order.getOrder_id()) ? 1 : 2;
|
||||
@ -9080,7 +9114,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
}
|
||||
|
||||
// 格式化取货号
|
||||
orderDetail.setOrder_pickup_num_str(fmtPickNum(orderDetail.getOrder_pickup_num()));
|
||||
orderDetail.setOrder_pickup_num_str(StringUtils.fmtPickNum(orderDetail.getOrder_pickup_num()));
|
||||
|
||||
// 订单是否禁止退款
|
||||
int isOrderDenyReturn = shopOrderReturnService.isOrderDenyReturn(orderId) ? 1 : 2;
|
||||
@ -9308,17 +9342,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
* @param pickNum 一般是 Long 类型
|
||||
* @return
|
||||
*/
|
||||
protected String fmtPickNum(Long pickNum) {
|
||||
if (pickNum == null || pickNum <= 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (pickNum > 9999999) {
|
||||
return String.valueOf(pickNum);
|
||||
}
|
||||
|
||||
return String.format("%07d", pickNum);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算平台与代理商的总分账金额
|
||||
|
||||
@ -8,15 +8,251 @@
|
||||
|
||||
package com.suisung.mall.shop.order.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.suisung.mall.common.constant.CommonConstant;
|
||||
import com.suisung.mall.common.constant.RedisConstant;
|
||||
import com.suisung.mall.common.modules.order.ShopOrderBooking;
|
||||
import com.suisung.mall.common.utils.CheckUtil;
|
||||
import com.suisung.mall.core.web.service.RedisService;
|
||||
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
|
||||
import com.suisung.mall.shop.order.mapper.ShopOrderBookingMapper;
|
||||
import com.suisung.mall.shop.order.service.ShopOrderBookingService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ShopOrderBookingServiceImpl extends BaseServiceImpl<ShopOrderBookingMapper, ShopOrderBooking> implements ShopOrderBookingService {
|
||||
|
||||
}
|
||||
private static final Long MINUTES_BEFORE_BOOKING = 35L;
|
||||
|
||||
@Resource
|
||||
private ShopOrderBookingMapper shopOrderBookingMapper;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
/**
|
||||
* 添加预约订单任务
|
||||
*
|
||||
* @param orderId 订单ID
|
||||
* @param bookingAt 预约时间
|
||||
* @return 是否添加成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean setupRedisBookingTask(String orderId, Long bookingAt) {
|
||||
log.debug("设置预约订单任务: orderId={}, bookingAt={}", orderId, bookingAt);
|
||||
|
||||
// 参数校验
|
||||
if (StringUtils.isEmpty(orderId) || CheckUtil.isEmpty(bookingAt)) {
|
||||
log.warn("参数无效: orderId={}, bookingAt={}", orderId, bookingAt);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
// 计算执行时间(预约时间前35分钟)
|
||||
long runAt = bookingAt - TimeUnit.MINUTES.toSeconds(MINUTES_BEFORE_BOOKING);
|
||||
|
||||
ShopOrderBooking shopOrderBooking = new ShopOrderBooking();
|
||||
shopOrderBooking.setOrder_id(orderId);
|
||||
shopOrderBooking.setBooking_at(bookingAt);
|
||||
shopOrderBooking.setRun_at(runAt);
|
||||
shopOrderBooking.setStatus(CommonConstant.Enable);
|
||||
|
||||
shopOrderBooking = addOrUpdate(shopOrderBooking);
|
||||
|
||||
// 如果保存成功,设置Redis过期键
|
||||
if (shopOrderBooking != null) {
|
||||
String redisKey = RedisConstant.Order_Booking_Task_Key + orderId;
|
||||
// 设置过期时间为runAt时间点(相对于当前时间的秒数)
|
||||
if (runAt > 0) {
|
||||
redisService.set(redisKey, Convert.toStr(shopOrderBooking.getRun_at()), runAt);
|
||||
log.debug("Redis键设置成功: key={}, bookingAt={}, runAt={}", redisKey, bookingAt, runAt);
|
||||
} else {
|
||||
log.warn("过期时间无效,未设置Redis键: key={}, bookingAt={}, runAt={}", redisKey, bookingAt, runAt);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
log.error("保存预约订单任务失败: orderId={}, bookingAt={}", orderId, bookingAt);
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("设置预约订单任务时发生异常: orderId={}, bookingAt={}", orderId, bookingAt, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShopOrderBooking addOrUpdate(ShopOrderBooking shopOrderBooking) {
|
||||
log.debug("添加或更新预约订单任务: {}", shopOrderBooking);
|
||||
if (shopOrderBooking == null) {
|
||||
log.warn("预约订单任务信息为空");
|
||||
return null;
|
||||
}
|
||||
|
||||
// 参数校验:order_id 和 booking_at 是必须项目
|
||||
if (StrUtil.isBlank(shopOrderBooking.getOrder_id()) || CheckUtil.isEmpty(shopOrderBooking.getBooking_at())) {
|
||||
log.warn("缺少必要参数: order_id 或 booking_at");
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
if (CheckUtil.isEmpty(shopOrderBooking.getRun_at())) {
|
||||
long runAt = shopOrderBooking.getBooking_at() - TimeUnit.MINUTES.toSeconds(MINUTES_BEFORE_BOOKING);
|
||||
shopOrderBooking.setRun_at(runAt);
|
||||
}
|
||||
|
||||
// 如果 id 有值,直接更新
|
||||
if (CheckUtil.isNotEmpty(shopOrderBooking.getId())) {
|
||||
log.debug("根据ID直接更新记录: {}", shopOrderBooking.getId());
|
||||
boolean updated = this.updateById(shopOrderBooking);
|
||||
return updated ? shopOrderBooking : null;
|
||||
}
|
||||
|
||||
// 如果 order_id 有值,先查询记录是否存在
|
||||
QueryWrapper<ShopOrderBooking> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("order_id", shopOrderBooking.getOrder_id()).eq("status", CommonConstant.Enable);
|
||||
ShopOrderBooking existingBooking = this.getOne(queryWrapper);
|
||||
|
||||
if (existingBooking != null) {
|
||||
// 存在则更新
|
||||
shopOrderBooking.setId(existingBooking.getId());
|
||||
log.debug("更新已存在的记录,ID: {}", shopOrderBooking.getId());
|
||||
boolean updated = this.updateById(shopOrderBooking);
|
||||
return updated ? shopOrderBooking : null;
|
||||
} else {
|
||||
// 不存在则保存
|
||||
log.debug("保存新记录");
|
||||
boolean saved = this.save(shopOrderBooking);
|
||||
return saved ? shopOrderBooking : null;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("添加或更新预约订单任务时发生异常: orderId={}, bookingAt={}",
|
||||
shopOrderBooking.getOrder_id(), shopOrderBooking.getBooking_at(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<ShopOrderBooking> findValidBookingList(Integer pageNum, Integer pageSize) {
|
||||
log.debug("查询有效的预约订单任务分页列表,页码: {},页大小: {}", pageNum, pageSize);
|
||||
if (pageNum == null || pageNum <= 0) {
|
||||
log.warn("页码无效,使用默认值 1");
|
||||
pageNum = 1;
|
||||
}
|
||||
if (pageSize == null || pageSize <= 0) {
|
||||
log.warn("页大小无效,使用默认值 10");
|
||||
pageSize = 10;
|
||||
}
|
||||
|
||||
Page<ShopOrderBooking> page = new Page<>(pageNum, pageSize);
|
||||
QueryWrapper<ShopOrderBooking> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("status", CommonConstant.Enable);
|
||||
queryWrapper.gt("run_at", System.currentTimeMillis() / 1000);
|
||||
queryWrapper.orderByAsc("run_at");
|
||||
return this.page(page, queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean update(UpdateWrapper<ShopOrderBooking> updateWrapper) {
|
||||
log.debug("更新预约订单任务");
|
||||
if (updateWrapper == null) {
|
||||
log.warn("更新条件不能为空");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
return this.update(updateWrapper);
|
||||
} catch (Exception e) {
|
||||
log.error("更新预约订单任务时发生异常", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更改预约订单任务下单完成状态(同时删除 redis 的定时任务)
|
||||
*
|
||||
* @param orderId 订单ID
|
||||
* @return 是否完成同城下单
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateOrderBookingFinishState(String orderId) {
|
||||
log.debug("完成预约订单任务的同城配送下单: orderId={}", orderId);
|
||||
|
||||
// 参数校验
|
||||
if (StrUtil.isBlank(orderId)) {
|
||||
log.warn("订单ID不能为空");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
// 构建更新条件
|
||||
UpdateWrapper<ShopOrderBooking> updateWrapper = new UpdateWrapper<>();
|
||||
updateWrapper.eq("order_id", orderId);
|
||||
updateWrapper.set("status", CommonConstant.Disable2);
|
||||
|
||||
// 执行更新操作
|
||||
boolean result = this.update(updateWrapper);
|
||||
|
||||
if (result) {
|
||||
log.debug("成功完成预约订单任务的同城配送下单: orderId={}", orderId);
|
||||
|
||||
// 同时删除对应的Redis键
|
||||
String redisKey = RedisConstant.Order_Booking_Task_Key + orderId;
|
||||
redisService.del(redisKey);
|
||||
log.debug("已清理对应的Redis定时任务键: {}", redisKey);
|
||||
} else {
|
||||
log.warn("未找到对应的预约订单任务,无法完成同城配送下单: orderId={}", orderId);
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
log.error("完成预约订单任务的同城配送下单时发生异常: orderId={}", orderId, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步预约订单任务到 redis 定时任务
|
||||
*
|
||||
* @return 同步数量
|
||||
*/
|
||||
@Override
|
||||
public Integer syncOrderBooking2RedisTask() {
|
||||
List<ShopOrderBooking> list = shopOrderBookingMapper.selectValidBookingList(200);
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
log.debug("未找到有效的预约订单任务");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
for (ShopOrderBooking shopOrderBooking : list) {
|
||||
String redisKey = RedisConstant.Order_Booking_Task_Key + shopOrderBooking.getOrder_id();
|
||||
if (redisService.get(redisKey) != null) {
|
||||
log.debug("已存在对应的Redis定时任务键: {},不需要同步", redisKey);
|
||||
continue;
|
||||
}
|
||||
|
||||
redisService.set(redisKey, Convert.toStr(shopOrderBooking.getRun_at()), shopOrderBooking.getRun_at());
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -35,6 +35,7 @@ import com.suisung.mall.shop.base.service.AccountBaseConfigService;
|
||||
import com.suisung.mall.shop.base.service.ShopBaseStateCodeService;
|
||||
import com.suisung.mall.shop.distribution.service.ShopDistributionUserCommissionService;
|
||||
import com.suisung.mall.shop.distribution.service.ShopDistributionUserWithdrawService;
|
||||
import com.suisung.mall.shop.message.service.PushMessageService;
|
||||
import com.suisung.mall.shop.order.mapper.ShopOrderInfoMapper;
|
||||
import com.suisung.mall.shop.order.service.*;
|
||||
import com.suisung.mall.shop.plantform.service.ShopPlantformActivityItemService;
|
||||
@ -57,6 +58,7 @@ import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
@ -120,10 +122,18 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
@Autowired
|
||||
private ShopStoreSfOrderService shopStoreSfOrderService;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private ShopOrderBookingService shopOrderBookingService;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private SFExpressApiService sfExpressApiService;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private PushMessageService pushMessageService;
|
||||
|
||||
@Autowired
|
||||
private ThreadPoolExecutor executor;
|
||||
|
||||
@ -367,33 +377,60 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
* @param orderId
|
||||
* @return 取货单号
|
||||
*/
|
||||
@Transactional
|
||||
// @Transactional
|
||||
@Override
|
||||
public Long isPaidOrderGenPickNumAndPrint(Integer storeId, String orderId) {
|
||||
logger.info("####开始生成订单{}的取单号####", orderId);
|
||||
ShopOrderInfo orderInfoOld = get(orderId);
|
||||
if (orderInfoOld != null
|
||||
&& orderInfoOld.getOrder_express_print().equals(CommonConstant.Enable)
|
||||
&& orderInfoOld.getOrder_pickup_num() != null && orderInfoOld.getOrder_pickup_num() > 0) {
|
||||
// 已打印过,无需打印
|
||||
logger.info("####以前生成的订单{}的取单号####", orderInfoOld.getOrder_pickup_num());
|
||||
return orderInfoOld.getOrder_pickup_num();
|
||||
}
|
||||
logger.info("####开始处理订单{}的取单号生成和打印####", orderId);
|
||||
|
||||
ShopOrderInfo orderInfo = new ShopOrderInfo();
|
||||
orderInfo.setOrder_id(orderId);
|
||||
// 生成取单号,写入order_info
|
||||
Long orderPickupNum = genTodayPickupNum(storeId);
|
||||
orderInfo.setOrder_pickup_num(orderPickupNum);
|
||||
orderInfo.setOrder_express_print(CommonConstant.Enable); // 打印标记 1-已打印
|
||||
if (!edit(orderInfo)) {
|
||||
// 参数校验
|
||||
if (storeId == null || orderId == null) {
|
||||
logger.warn("参数校验失败: storeId或orderId为空");
|
||||
return 0L;
|
||||
}
|
||||
|
||||
// 订单状态处理成功之后,打印小票
|
||||
shopStorePrinterService.printShopStoreOrder(storeId, orderId);
|
||||
logger.info("####新生成订单{}的取单号####", orderPickupNum);
|
||||
return orderPickupNum;
|
||||
ShopOrderInfo orderInfoOld = get(orderId);
|
||||
if (orderInfoOld == null) {
|
||||
logger.warn("未找到订单信息: orderId={}", orderId);
|
||||
return 0L;
|
||||
}
|
||||
|
||||
// 检查是否已经生成过取单号并打印
|
||||
if (orderInfoOld.getOrder_express_print() != null
|
||||
&& orderInfoOld.getOrder_express_print().equals(CommonConstant.Enable)
|
||||
&& orderInfoOld.getOrder_pickup_num() != null
|
||||
&& orderInfoOld.getOrder_pickup_num() > 0) {
|
||||
logger.info("订单{}已处理过,取单号: {}", orderId, orderInfoOld.getOrder_pickup_num());
|
||||
return orderInfoOld.getOrder_pickup_num();
|
||||
}
|
||||
|
||||
try {
|
||||
// 生成取单号
|
||||
Long orderPickupNum = genTodayPickupNum(storeId);
|
||||
if (orderPickupNum == null || orderPickupNum <= 0) {
|
||||
logger.error("生成取单号失败: storeId={}", storeId);
|
||||
return 0L;
|
||||
}
|
||||
|
||||
// 更新订单信息
|
||||
ShopOrderInfo orderInfo = new ShopOrderInfo();
|
||||
orderInfo.setOrder_id(orderId);
|
||||
orderInfo.setOrder_pickup_num(orderPickupNum);
|
||||
orderInfo.setOrder_express_print(CommonConstant.Enable); // 打印标记 1-已打印
|
||||
|
||||
if (!edit(orderInfo)) {
|
||||
logger.error("更新订单取单号失败: orderId={}", orderId);
|
||||
return 0L;
|
||||
}
|
||||
|
||||
// 打印小票
|
||||
shopStorePrinterService.printShopStoreOrder(storeId, orderId);
|
||||
logger.info("####成功生成并打印订单{}的取单号: {}####", orderId, orderPickupNum);
|
||||
return orderPickupNum;
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("处理订单取单号时发生异常: orderId={}", orderId, e);
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -872,14 +909,107 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
return Pair.of(false, "[预约订单校验] 请在店铺营业时间内预约下单");
|
||||
}
|
||||
|
||||
// 7. 预约时间范围检查 - 仅能预约45分钟后的订单
|
||||
Date fortyFiveMinutesLater = DateUtil.offsetMinute(new Date(), 45);
|
||||
// 7. 预约时间范围检查 - 仅能预约50分钟后的订单
|
||||
Date fortyFiveMinutesLater = DateUtil.offsetMinute(new Date(), 50);
|
||||
if (!bookingBeginTime.after(fortyFiveMinutesLater)) {
|
||||
return Pair.of(false, "[预约订单校验] 仅能预约45分后的订单");
|
||||
return Pair.of(false, "[预约订单校验] 请预约50分后的订单");
|
||||
}
|
||||
|
||||
return Pair.of(true, "[预约订单校验] 成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断订单是否为预约订单
|
||||
*
|
||||
* @param orderInfo 订单信息
|
||||
* @return 是否为预约订单
|
||||
*/
|
||||
@Override
|
||||
public Boolean isBookingOrder(ShopOrderInfo orderInfo) {
|
||||
return orderInfo != null
|
||||
&& CommonConstant.Order_Booking_State_YY.equals(orderInfo.getBooking_state())
|
||||
&& !CheckUtil.isEmpty(orderInfo.getBooking_at())
|
||||
&& orderInfo.getBooking_at().longValue() >= System.currentTimeMillis() / 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行预约订单到点后向顺丰同城订单任务
|
||||
*
|
||||
* @param orderId 订单ID
|
||||
* @return 处理结果Pair,第一个元素表示是否成功,第二个元素为结果描述
|
||||
*/
|
||||
@Transactional
|
||||
@Override
|
||||
public Pair<Boolean, String> runBookingOrder2SfExpressOrder(String orderId) {
|
||||
// 参数校验
|
||||
if (StrUtil.isBlank(orderId)) {
|
||||
logger.warn("[预约订单顺丰下单] 订单ID为空");
|
||||
return Pair.of(false, "订单ID不能为空");
|
||||
}
|
||||
|
||||
try {
|
||||
// 获取订单信息
|
||||
ShopOrderInfo shopOrderInfo = get(orderId);
|
||||
if (shopOrderInfo == null) {
|
||||
logger.warn("[预约订单顺丰下单] 订单不存在: {}", orderId);
|
||||
return Pair.of(false, "订单不存在");
|
||||
}
|
||||
|
||||
Integer orderState = shopOrderInfo.getOrder_state_id();
|
||||
|
||||
// 验证订单是否为有效的预约订单
|
||||
if (!isBookingOrder(shopOrderInfo) || CheckUtil.isEmpty(orderState)
|
||||
|| orderState.intValue() >= StateCode.ORDER_STATE_SHIPPED) {
|
||||
logger.warn("[预约订单顺丰下单] 订单不是预约订单或者状态不正确: orderId: {}, orderState: {}", orderId, orderState);
|
||||
return Pair.of(false, "订单不是预约订单或者状态不正确");
|
||||
}
|
||||
|
||||
// 检查顺丰同城订单是否已经存在?
|
||||
String sfOrderId = shopStoreSfOrderService.getSfOrderIdByShopOrderId(orderId);
|
||||
if (StrUtil.isNotBlank(sfOrderId)) {
|
||||
logger.warn("[预约订单顺丰下单] 预约订单已下过单: orderId: {}, sfOrderId: {}", orderId, sfOrderId);
|
||||
return Pair.of(false, "预约订单已下过单,请勿重复操作");
|
||||
}
|
||||
|
||||
|
||||
// 调用顺丰接口创建订单
|
||||
Pair<Boolean, String> sfResult = sfExpressApiService.innerCreateSfExpressOrder(orderId, 0L);
|
||||
if (sfResult == null) {
|
||||
logger.error("[预约订单顺丰下单] 调用顺丰接口无返回值, orderId={}", orderId);
|
||||
throw new RuntimeException("预约订单顺丰下单失败,接口无响应");
|
||||
}
|
||||
|
||||
if (!sfResult.getFirst()) {
|
||||
logger.error("[预约订单顺丰下单] 调用顺丰接口失败: {}, orderId={}", sfResult.getSecond(), orderId);
|
||||
throw new RuntimeException("预约订单顺丰下单失败," + sfResult.getSecond());
|
||||
}
|
||||
|
||||
// 更新订单预约状态为立即下单状态
|
||||
UpdateWrapper<ShopOrderInfo> updateWrapper = new UpdateWrapper<>();
|
||||
updateWrapper.eq("order_id", orderId)
|
||||
.set("booking_state", CommonConstant.Order_Booking_State_LJ);
|
||||
this.update(updateWrapper);
|
||||
|
||||
// 标记预约任务完成
|
||||
shopOrderBookingService.updateOrderBookingFinishState(orderId);
|
||||
|
||||
// 发送推送消息给商家
|
||||
String title = "您有一笔新的订单,请注意查收。";
|
||||
String content = String.format("这笔新的订单:%s,用户于%s下的单,请注意查收。",
|
||||
orderId, DateTimeUtils.formatDateTime(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss"));
|
||||
JSONObject payload = new JSONObject();
|
||||
payload.set("category", CommonConstant.PUSH_MSG_CATE_MCH_ONLINE_ORDER_LIST);
|
||||
payload.set("orderId", orderId);
|
||||
pushMessageService.noticeMerchantEmployeeOrderAction(null, orderId, title, content, payload);
|
||||
|
||||
logger.info("[预约订单顺丰下单] 成功, orderId={}", orderId);
|
||||
return Pair.of(true, "预约订单在顺丰下单成功");
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("[预约订单顺丰下单] 异常, orderId={}", orderId, e);
|
||||
throw new RuntimeException("系统异常,预约订单顺丰下单失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1470,7 +1470,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
shopOrderReturn.setReturn_state_id(return_next_state_id);
|
||||
|
||||
//商家 收货确认0,增加库存?todo 流程已改,商家接单或者商家发货都是出库扣减库存的,审核也需要加回来库存
|
||||
if (ObjectUtil.equal(return_state_id, StateCode.RETURN_PROCESS_RECEIVED)||ObjectUtil.equal(return_state_id, StateCode.RETURN_PROCESS_CHECK)) {
|
||||
if (ObjectUtil.equal(return_state_id, StateCode.RETURN_PROCESS_RECEIVED) || ObjectUtil.equal(return_state_id, StateCode.RETURN_PROCESS_CHECK)) {
|
||||
//查询订单退货详情表,得到退货商品数量
|
||||
QueryWrapper<ShopOrderReturnItem> returnItemQueryWrapper = new QueryWrapper<>();
|
||||
returnItemQueryWrapper.in("return_id", return_ids);
|
||||
@ -1508,7 +1508,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
// 增加库存
|
||||
Integer returnNum = returnItem.getReturn_item_num();
|
||||
if (returnNum != null) {
|
||||
Integer lestFrozenQuantity= productItem.getItem_quantity_frozen()-returnNum;//增加了退回的库存,也要释放锁定的库存
|
||||
Integer lestFrozenQuantity = productItem.getItem_quantity_frozen() - returnNum;//增加了退回的库存,也要释放锁定的库存
|
||||
if (lestFrozenQuantity.compareTo(0) < 0) {
|
||||
lestFrozenQuantity = 0;
|
||||
}
|
||||
@ -2119,25 +2119,25 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
public boolean ifDenyReturn(ShopOrderInfo shopOrderInfo, ShopOrderItem shopOrderItem, ShopProductIndex shopProductIndex) {
|
||||
// 1. 参数校验
|
||||
if (shopOrderItem == null) {
|
||||
log.debug("[是否禁止退货] 订单商品数据为空 true");
|
||||
log.debug("[是否禁止退货] 订单商品数据为空,不允许退货");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (shopOrderInfo == null) {
|
||||
log.debug("[是否禁止退货] 订单信息为空 true");
|
||||
log.debug("[是否禁止退货] 订单信息为空,不允许退货");
|
||||
return true;
|
||||
}
|
||||
|
||||
String orderId = shopOrderInfo.getOrder_id();
|
||||
Integer orderStateId = shopOrderInfo.getOrder_state_id();
|
||||
if (StrUtil.isBlank(orderId) || CheckUtil.isEmpty(orderStateId)) {
|
||||
log.debug("[是否禁止退货] 订单ID或订单状态为空 true");
|
||||
log.debug("[是否禁止退货] 订单ID或订单状态为空,不允许退货");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (orderStateId.intValue() == StateCode.ORDER_STATE_CANCEL ||
|
||||
orderStateId.intValue() == StateCode.ORDER_STATE_WAIT_PAY) {
|
||||
log.debug("[是否禁止退货] 订单已取消或未支付,true order_id: {}", orderId);
|
||||
log.debug("[是否禁止退货] 订单已取消或未支付,不允许退货 order_id: {}", orderId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2152,11 +2152,11 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
|
||||
// 检查是否超过退货期限
|
||||
if (orderDealTime != null && withdrawTime.compareTo(orderDealTime) > 0) {
|
||||
log.debug("[是否禁止退货] 订单已超过退货期限 true,order_id: {}", orderId);
|
||||
log.debug("[是否禁止退货] 订单已超过退货期限,不允许退货,order_id: {}", orderId);
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("[是否禁止退货] 检查订单退货期限时发生异常 true,order_id: {}", orderId, e);
|
||||
log.error("[是否禁止退货] 检查订单退货期限时发生异常,不允许退货,order_id: {}", orderId, e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2167,17 +2167,17 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
boolean isDrawn = lklOrderDrawService.isOrderDrawed(orderId);
|
||||
|
||||
if (isSeparated && isDrawn) {
|
||||
log.debug("[是否禁止退货] 拉卡拉分账订单已提现,不允许退货 true,order_id: {}", orderId);
|
||||
log.debug("[是否禁止退货] 拉卡拉分账订单已提现,不允许退货,order_id: {}", orderId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("[是否禁止退货] 检查拉卡拉分账状态时发生异常,order_id: {}", orderId, e);
|
||||
log.error("[是否禁止退货] 检查拉卡拉分账状态时发生异常,不允许退货,order_id: {}", orderId, e);
|
||||
}
|
||||
|
||||
Long productId = shopOrderItem.getProduct_id();
|
||||
if (CheckUtil.isEmpty(productId)) {
|
||||
log.debug("[是否禁止退货] 商品ID为空 true");
|
||||
log.debug("[是否禁止退货] 商品ID为空,不允许退货");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2189,7 +2189,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
}
|
||||
|
||||
if (productIndex == null) {
|
||||
log.debug("[是否禁止退货] 商品索引信息不存在 true,product_id: {}", productId);
|
||||
log.debug("[是否禁止退货] 商品索引信息不存在,不允许退货,product_id: {}", productId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2199,16 +2199,17 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
try {
|
||||
List<Integer> contractTypeIds = Convert.toList(Integer.class, contractTypeIdsStr);
|
||||
if (contractTypeIds != null && contractTypeIds.contains(StateCode.CONTRACT_TYPE_DENY_RETURN)) {
|
||||
log.debug("[是否禁止退货] 商品设置了禁止退货标识 true,order_id: {}, product_id: {}", orderId, productId);
|
||||
log.debug("[是否禁止退货] 商品设置了禁止退货标识,不允许退货,order_id: {}, product_id: {}", orderId, productId);
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("[是否禁止退货] 解析商品保障类型失败 true,order_id: {}, product_id: {}", orderId, productId, e);
|
||||
log.error("[是否禁止退货] 解析商品保障类型失败,不允许退货,order_id: {}, product_id: {}", orderId, productId, e);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 默认允许退货
|
||||
log.debug("[是否禁止退货] false}");
|
||||
log.debug("[是否禁止退货] 允许退货}");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2245,7 +2246,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
public boolean isOrderDenyReturn(String orderId) {
|
||||
// 参数校验
|
||||
if (StrUtil.isBlank(orderId)) {
|
||||
log.warn("[订单是否禁止退货] 订单ID为空,无法判断退货状态");
|
||||
log.warn("[订单是否禁止退货] 订单ID为空,不允许退货,无法判断退货状态");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2253,20 +2254,20 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
// 获取订单信息
|
||||
ShopOrderInfo shopOrderInfo = shopOrderInfoService.get(orderId);
|
||||
if (shopOrderInfo == null) {
|
||||
log.error("[订单是否禁止退货] 订单信息不存在,订单ID: {}", orderId);
|
||||
log.error("[订单是否禁止退货] 订单信息不存在,不允许退货,订单ID: {}", orderId);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 检查订单状态是否已收货或已完成
|
||||
Integer orderStateId = shopOrderInfo.getOrder_state_id();
|
||||
if (CheckUtil.isEmpty(orderStateId)) {
|
||||
log.warn("[订单是否禁止退货] 订单状态为空");
|
||||
log.warn("[订单是否禁止退货] 订单状态为空,不允许退货");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (orderStateId.intValue() == StateCode.ORDER_STATE_CANCEL ||
|
||||
orderStateId.intValue() == StateCode.ORDER_STATE_WAIT_PAY) {
|
||||
log.debug("[是否禁止退货] 订单已取消或未支付,order_id: {}", orderId);
|
||||
log.debug("[是否禁止退货] 订单已取消或未支付,不允许退货, order_id: {}", orderId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2296,7 +2297,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
return false;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("[订单是否禁止退货] 查询订单{}退货状态异常", orderId, e);
|
||||
log.error("[订单是否禁止退货] 查询订单{}退货状态异常,不允许退货", orderId, e);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -568,7 +568,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
@Override
|
||||
public Pair<Boolean, String> innerCreateSfExpressOrder(String shopOrderId, Long orderPickupNum) {
|
||||
logger.info("开始顺丰同城下单");
|
||||
if (StrUtil.isBlank(shopOrderId) || orderPickupNum == null || orderPickupNum <= 0) {
|
||||
if (StrUtil.isBlank(shopOrderId) || orderPickupNum == null) {
|
||||
return Pair.of(false, "顺丰同城下单时,缺少必要参数!");
|
||||
}
|
||||
|
||||
@ -1108,7 +1108,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
String order_id = shopStoreSfOrder.getShop_order_id();
|
||||
itemQueryWrapper.eq("order_id", order_id);
|
||||
List<ShopOrderItem> order_item_rows = shopOrderItemService.find(itemQueryWrapper);
|
||||
if(picking(order_item_rows)){
|
||||
if (picking(order_item_rows)) {
|
||||
logger.info("顺丰发货商品扣减库存成功");
|
||||
}
|
||||
if (!order_item_rows.isEmpty()) {
|
||||
@ -1266,7 +1266,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
}
|
||||
Pair<Boolean, String> pair = wxOrderShippingService.uploadShippingInfoToWx(2, shopOrderBase.getOrder_id());
|
||||
if (pair.getFirst()) {
|
||||
Integer orderStatus = StateCode.ORDER_STATE_SHIPPED;//已发货
|
||||
Integer orderStatus = StateCode.ORDER_STATE_SHIPPED;//已发货
|
||||
Integer orderIsOutStatus = StateCode.ORDER_PICKING_STATE_YES; // 已出库
|
||||
shopOrderInfoService.changeOrderStatus(orderId, orderStatus, orderIsOutStatus, 0);
|
||||
//完成订单后修改订单异常操作流程进入完成订单环节
|
||||
@ -1277,7 +1277,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
QueryWrapper<ShopOrderItem> itemQueryWrapper = new QueryWrapper<>();
|
||||
itemQueryWrapper.eq("order_id", orderId);
|
||||
List<ShopOrderItem> order_item_rows = shopOrderItemService.find(itemQueryWrapper);
|
||||
if(picking(order_item_rows)){
|
||||
if (picking(order_item_rows)) {
|
||||
logger.info("自行发货商品扣减库存成功");
|
||||
}
|
||||
if (!order_item_rows.isEmpty()) {
|
||||
@ -1292,7 +1292,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
return CommonResult.success("操作成功");
|
||||
//出库扣减思迅库存end
|
||||
}
|
||||
return CommonResult.failed("操作失败:"+pair.getSecond());
|
||||
return CommonResult.failed("操作失败:" + pair.getSecond());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1309,18 +1309,20 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
// 送达后,发出催促微信用户确认收货通知 (同城配送不能调用微信的确认收货)
|
||||
shopOrderInfoService.changeOrderStatus(shopOrderId, orderStatus, 0, 0);
|
||||
//完成订单后修改订单异常操作流程
|
||||
ShopOrderBase updateShopOrderBase=new ShopOrderBase();
|
||||
ShopOrderBase updateShopOrderBase = new ShopOrderBase();
|
||||
updateShopOrderBase.setOrder_id(shopOrderId);
|
||||
updateShopOrderBase.setOperate_flag("2");
|
||||
shopOrderBaseService.updateById(updateShopOrderBase);
|
||||
return CommonResult.success("操作成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据订单列表扣除商品库存
|
||||
*
|
||||
* @param order_item_rows
|
||||
* @return
|
||||
*/
|
||||
public boolean picking(List<ShopOrderItem> order_item_rows){
|
||||
public boolean picking(List<ShopOrderItem> order_item_rows) {
|
||||
logger.info("出库商品扣除库存--开始");
|
||||
List<ShopProductItem> updateProductItems = new ArrayList<>();
|
||||
for (ShopOrderItem shopOrderItem : order_item_rows) {
|
||||
@ -1329,7 +1331,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
if (productItem == null) {
|
||||
throw new ApiException(String.format(_("SKU【%s】不存在!"), item_id));
|
||||
}
|
||||
Integer item_change_quantity=shopOrderItem.getOrder_item_quantity()*-1;
|
||||
Integer item_change_quantity = shopOrderItem.getOrder_item_quantity() * -1;
|
||||
Integer quantity = productItem.getItem_quantity() + item_change_quantity;
|
||||
if (quantity.compareTo(0) < 0) {
|
||||
quantity = 0;
|
||||
@ -1343,7 +1345,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
productItem.setItem_quantity_frozen(tmp_quantity);
|
||||
updateProductItems.add(productItem);
|
||||
}
|
||||
return shopProductItemService.updateBatchById(updateProductItems,updateProductItems.size());
|
||||
return shopProductItemService.updateBatchById(updateProductItems, updateProductItems.size());
|
||||
}
|
||||
|
||||
// 私有方法
|
||||
|
||||
@ -535,6 +535,7 @@
|
||||
a.order_id,a.store_id,a.store_name,a.buyer_user_id,
|
||||
a.buyer_user_name,a.order_time,a.order_payment_amount,a.order_product_amount,
|
||||
b.order_title, b.delivery_type_id, b.payment_type_id, b.payment_time, b.order_pickup_num,
|
||||
CASE WHEN b.booking_state = 2 THEN 2 ELSE 1 END AS booking_state, b.booking_begin_time,
|
||||
c.order_message, c.order_item_amount, c.order_shipping_fee, c.order_shipping_fee_amount, c.delivery_time,
|
||||
(c.order_discount_amount + c.voucher_price + c.order_points_fee + c.order_adjust_fee) as total_discount_amount,
|
||||
c.packing_fee,
|
||||
|
||||
@ -5,4 +5,23 @@
|
||||
<sql id="Base_Column_List">
|
||||
*
|
||||
</sql>
|
||||
|
||||
<select id="selectValidBookingList" resultType="com.suisung.mall.common.modules.order.ShopOrderBooking">
|
||||
SELECT a.*
|
||||
FROM shop_order_booking a
|
||||
JOIN shop_order_info b ON a.order_id = b.order_id
|
||||
LEFT JOIN shop_store_sf_order c ON a.order_id = c.shop_order_id
|
||||
WHERE a.status = 1
|
||||
AND a.run_at > UNIX_TIMESTAMP()
|
||||
AND b.booking_state = 2
|
||||
AND b.booking_begin_time IS NOT NULL
|
||||
AND b.order_state_id < 2040
|
||||
AND c.shop_order_id IS NULL
|
||||
ORDER BY a.run_at ASC
|
||||
|
||||
<if test="limit_count != null and limit_count>0">
|
||||
LIMIT #{limit_count}
|
||||
</if>
|
||||
|
||||
</select>
|
||||
</mapper>
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
示例格式化后的:
|
||||
<CB>小发同城</CB><BR>
|
||||
<CB><B>预约订单</B></CB><BR>
|
||||
--------------------------------<BR>
|
||||
<CB>#00019232</CB><BR>
|
||||
<L>买家备注:不用敲门,放在门口旁边的外卖箱,打个电话告知送达就行,谢谢!!!</L><BR>
|
||||
@ -57,4 +58,7 @@
|
||||
<CB>${store_name}</CB><BR>--------------------------------<BR><CB>#${order_pickup_num_str}</CB><BR><L>买家备注:${order_message!'-'}</L><BR><BOLD>配送时间:${payment_time?string('MM-dd HH:mm')}~${delivery_time?string('HH:mm')}</BOLD><BR>--------------------------------<BR>订单编号:${order_id}<BR>订单来源:微信小程序<BR>支付方式:微信支付<BR>配送来源:顺丰同城<BR>付款时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}<BR>--------------------------------<BR><L>商品名称 数量 金额</L><BR>--------------------------------<BR><#list order_items as item><L>${item.s_name}</L><L><BOLD>${item.s_quantity}</BOLD></L><L>${item.s_amount}</L><BR><#if item.s_name_segs??><#list item.s_name_segs as seg><L>${seg}</L><BR></#list></#if><BOLD><#if item.product_sn?default("")?trim?length gt 1>${item.product_sn}</BOLD><BR></#if></#list>--------------------------------<BR>商品总件数:<BOLD>${order_items_count!0}</BOLD><BR>商品总额:<BOLD>¥${order_product_amount?string('0.00')}</BOLD><BR>押金:<BOLD>¥${(yajin!0)?string('0.00')}</BOLD><BR>运费:<BOLD>¥${order_shipping_fee?string('0.00')}</BOLD><BR>会员权益:<BOLD>-¥${(quanyi!0)?string('0.00')}</BOLD><BR>秒杀:<BOLD>-¥${(miaosha!0)?string('0.00')}</BOLD><BR>实付金额:<BOLD>¥${order_payment_amount?string('0.00')}</BOLD><BR><#if seller_message?default("")?trim?length gt 1>--------------------------------<BR><BOLD>商家备注:${seller_message!'-'}</BOLD><BR></#if>--------------------------------<BR><BOLD>收货人:${buyer_user_name!''}</BOLD><BR><BOLD>收货人手机:${da_mobile!'-'}</BOLD><BR><BOLD>收货地址:${da_province!'-'}${da_city!'-'}${da_address!'-'}</BOLD><BR>--------------------------------<BR>门店:${store_name}<BR>门店电话:<BOLD>${store_tel!'-'}</BOLD><BR>收银员:${cashier!'店长'}<BR>
|
||||
|
||||
第二版带变量的模版:
|
||||
<CB>${store_name}</CB><BR>--------------------------------<BR><CB>#${order_pickup_num_str}</CB><BR><L>买家备注:${order_message!'-'}</L><BR><BOLD>配送时间:${payment_time?string('MM-dd HH:mm')}~${delivery_time?string('HH:mm')}</BOLD><BR>--------------------------------<BR>订单编号:${order_id}<BR>订单来源:微信小程序<BR>支付方式:微信支付<BR>配送来源:顺丰同城<BR>付款时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}<BR>--------------------------------<BR><L>商品名称 数量 金额</L><BR>--------------------------------<BR><#list order_items as item><L>${item.s_name}</L><L><BOLD>${item.s_quantity}</BOLD></L><L>${item.s_amount}</L><BR><#if item.s_name_segs??><#list item.s_name_segs as seg><L>${seg}</L><BR></#list></#if><BOLD><#if item.product_sn?default("")?trim?length gt 1>${item.product_sn}</BOLD><BR></#if></#list>--------------------------------<BR>商品总件数:<BOLD>${order_items_count!0}</BOLD><BR>商品总额:<BOLD>¥${order_product_amount?string('0.00')}</BOLD><BR>运费:<BOLD>¥${order_shipping_fee?string('0.00')}</BOLD><BR><#if packing_fee?? && (packing_fee > 0)>打包费:<BOLD>¥${packing_fee?string('0.00')}</BOLD><BR></#if>优惠金额:<BOLD>-¥${(quanyi!0)?string('0.00')}</BOLD><BR>实付金额:<BOLD>¥${order_payment_amount?string('0.00')}</BOLD><BR><#if seller_message?default("")?trim?length gt 1>--------------------------------<BR><BOLD>商家备注:${seller_message!'-'}</BOLD><BR></#if>--------------------------------<BR><BOLD>收货人:${buyer_user_name!''}</BOLD><BR><BOLD>收货人手机:${da_mobile!'-'}</BOLD><BR><BOLD>收货地址:${da_province!'-'}${da_city!'-'}${da_address!'-'}</BOLD><BR>--------------------------------<BR>门店:${store_name}<BR>门店电话:<BOLD>${store_tel!'-'}</BOLD><BR>收银员:${cashier!'店长'}<BR>
|
||||
<CB>${store_name}</CB><BR>--------------------------------<BR><CB>#${order_pickup_num_str}</CB><BR><L>买家备注:${order_message!'-'}</L><BR><BOLD>配送时间:${payment_time?string('MM-dd HH:mm')}~${delivery_time?string('HH:mm')}</BOLD><BR>--------------------------------<BR>订单编号:${order_id}<BR>订单来源:微信小程序<BR>支付方式:微信支付<BR>配送来源:顺丰同城<BR>付款时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}<BR>--------------------------------<BR><L>商品名称 数量 金额</L><BR>--------------------------------<BR><#list order_items as item><L>${item.s_name}</L><L><BOLD>${item.s_quantity}</BOLD></L><L>${item.s_amount}</L><BR><#if item.s_name_segs??><#list item.s_name_segs as seg><L>${seg}</L><BR></#list></#if><BOLD><#if item.product_sn?default("")?trim?length gt 1>${item.product_sn}</BOLD><BR></#if></#list>--------------------------------<BR>商品总件数:<BOLD>${order_items_count!0}</BOLD><BR>商品总额:<BOLD>¥${order_product_amount?string('0.00')}</BOLD><BR>运费:<BOLD>¥${order_shipping_fee?string('0.00')}</BOLD><BR><#if packing_fee?? && (packing_fee > 0)>打包费:<BOLD>¥${packing_fee?string('0.00')}</BOLD><BR></#if>优惠金额:<BOLD>-¥${(quanyi!0)?string('0.00')}</BOLD><BR>实付金额:<BOLD>¥${order_payment_amount?string('0.00')}</BOLD><BR><#if seller_message?default("")?trim?length gt 1>--------------------------------<BR><BOLD>商家备注:${seller_message!'-'}</BOLD><BR></#if>--------------------------------<BR><BOLD>收货人:${buyer_user_name!''}</BOLD><BR><BOLD>收货人手机:${da_mobile!'-'}</BOLD><BR><BOLD>收货地址:${da_province!'-'}${da_city!'-'}${da_address!'-'}</BOLD><BR>--------------------------------<BR>门店:${store_name}<BR>门店电话:<BOLD>${store_tel!'-'}</BOLD><BR>收银员:${cashier!'店长'}<BR>
|
||||
|
||||
第三版带变量的模版(有预约订单)
|
||||
<CB>${store_name}</CB><BR><#if is_booking_order><CB><B>预约订单</B></CB><BR></#if>--------------------------------<BR><CB>#${order_pickup_num_str}</CB><BR><L>买家备注:${order_message!'-'}</L><BR><BOLD>配送时间:${payment_time?string('MM-dd HH:mm')}~${delivery_time?string('HH:mm')}</BOLD><BR>--------------------------------<BR>订单编号:${order_id}<BR>订单来源:微信小程序<BR>支付方式:微信支付<BR>配送来源:顺丰同城<BR>付款时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}<BR>--------------------------------<BR><L>商品名称 数量 金额</L><BR>--------------------------------<BR><#list order_items as item><L>${item.s_name}</L><L><BOLD>${item.s_quantity}</BOLD></L><L>${item.s_amount}</L><BR><#if item.s_name_segs??><#list item.s_name_segs as seg><L>${seg}</L><BR></#list></#if><BOLD><#if item.product_sn?default("")?trim?length gt 1>${item.product_sn}</BOLD><BR></#if></#list>--------------------------------<BR>商品总件数:<BOLD>${order_items_count!0}</BOLD><BR>商品总额:<BOLD>¥${order_product_amount?string('0.00')}</BOLD><BR>运费:<BOLD>¥${order_shipping_fee?string('0.00')}</BOLD><BR><#if packing_fee?? && (packing_fee > 0)>打包费:<BOLD>¥${packing_fee?string('0.00')}</BOLD><BR></#if>优惠金额:<BOLD>-¥${(quanyi!0)?string('0.00')}</BOLD><BR>实付金额:<BOLD>¥${order_payment_amount?string('0.00')}</BOLD><BR><#if seller_message?default("")?trim?length gt 1>--------------------------------<BR><BOLD>商家备注:${seller_message!'-'}</BOLD><BR></#if>--------------------------------<BR><BOLD>收货人:${buyer_user_name!''}</BOLD><BR><BOLD>收货人手机:${da_mobile!'-'}</BOLD><BR><BOLD>收货地址:${da_province!'-'}${da_city!'-'}${da_address!'-'}</BOLD><BR>--------------------------------<BR>门店:${store_name}<BR>门店电话:<BOLD>${store_tel!'-'}</BOLD><BR>收银员:${cashier!'店长'}<BR>
|
||||
Loading…
Reference in New Issue
Block a user