Compare commits
24 Commits
76b378d205
...
97ecfa3c79
| Author | SHA1 | Date | |
|---|---|---|---|
| 97ecfa3c79 | |||
| 6398635707 | |||
| a65fb441cb | |||
| 2b03dee62d | |||
| aeb3c0d029 | |||
| 69b195322e | |||
| 8058773aac | |||
| 3f75c6f191 | |||
| b60f4d9210 | |||
| 12523f13da | |||
| 986e8acb00 | |||
| 2471d2b4c2 | |||
| 66498ff82d | |||
| 4959f8ae64 | |||
| 10bc17df0e | |||
| 501d3761e6 | |||
| 8abac2a5b3 | |||
| 56a62f6673 | |||
| 6637180cbf | |||
| e252475a34 | |||
| 71a2b5acb8 | |||
| a334cfce29 | |||
| d061510a5e | |||
| b7701a8685 |
@ -121,4 +121,8 @@ public class CommonConstant {
|
||||
public static final Integer Agent_Level_2nd = 2;
|
||||
|
||||
|
||||
// 订单配送预约状态:1-立即配送;2-预约配送
|
||||
public static final Integer Order_Booking_State_LJ = 1;
|
||||
public static final Integer Order_Booking_State_YY = 2;
|
||||
|
||||
}
|
||||
|
||||
@ -110,6 +110,9 @@ public class LklOrderDraw {
|
||||
@ApiModelProperty(value = "商户订单号", example = "MER2023100100001")
|
||||
private String mer_order_no;
|
||||
|
||||
@ApiModelProperty(value = "商城订单Id")
|
||||
private String order_id;
|
||||
|
||||
/**
|
||||
* 结算流水号
|
||||
*/
|
||||
|
||||
@ -75,7 +75,7 @@ public class ShopOrderInfo implements Serializable {
|
||||
@ApiModelProperty(value = "下单时间:检索使用")
|
||||
private Long order_time;
|
||||
|
||||
@ApiModelProperty(value = "当前状态的处理时间")
|
||||
@ApiModelProperty(value = "当前状态的处理时间,一般是确认收货时间")
|
||||
private Long order_deal_time;
|
||||
|
||||
@ApiModelProperty(value = "买家删除(BOOL): 1-是; 0-否")
|
||||
@ -204,6 +204,15 @@ public class ShopOrderInfo implements Serializable {
|
||||
@ApiModelProperty(value = "拣货完成时间戳")
|
||||
private Long order_picked_time;
|
||||
|
||||
@ApiModelProperty(value = "订单配送预约状态:1-立即配送;2-预约配送")
|
||||
private Integer booking_state;
|
||||
|
||||
@ApiModelProperty(value = "预约送达起始时间,格式如:yyyy-MM-dd HH:mm:ss")
|
||||
private Date booking_begin_time;
|
||||
|
||||
@ApiModelProperty(value = "预约送达截止时间,格式如:yyyy-MM-dd HH:mm:ss")
|
||||
private Date booking_end_time;
|
||||
|
||||
@ApiModelProperty(value = "新建时间")
|
||||
private Date created_at;
|
||||
|
||||
|
||||
@ -91,6 +91,6 @@ public class MchOrderInfoDTO implements Serializable {
|
||||
private BigDecimal order_income_amount;
|
||||
@ApiModelProperty(value = "两点距离,单位米")
|
||||
private Integer distance;
|
||||
|
||||
// 快递鸟物流信息
|
||||
@ApiModelProperty(value = "是否禁止退款:1-是;2-否;")
|
||||
private Integer is_deny_return;
|
||||
}
|
||||
|
||||
@ -61,4 +61,7 @@ public class MchOrderItemDTO implements Serializable {
|
||||
|
||||
@ApiModelProperty(value = "退款金额:同意额度")
|
||||
private BigDecimal order_item_return_agree_amount;
|
||||
|
||||
@ApiModelProperty(value = "是否禁止退款:1-是;2-否;")
|
||||
private Integer is_deny_return;
|
||||
}
|
||||
|
||||
@ -62,7 +62,7 @@ public class LklSeparateWithTotalAmountDTO {
|
||||
// 测试用例1: 所有参与方都参与分账(符合比例要求)
|
||||
System.out.println("=== 测试用例1: 所有参与方都参与分账 ===");
|
||||
LklSeparateWithTotalAmountDTO dto1 = new LklSeparateWithTotalAmountDTO();
|
||||
dto1.setTotalSeparateAmount(5500); // 总金额100元(10000分)
|
||||
dto1.setTotalSeparateAmount(1696); // 总金额100元(10000分)
|
||||
dto1.setShippingFee(500);
|
||||
// dto1.setRefCanSeparateAmount(1496);
|
||||
dto1.setLklRatio(new BigDecimal("0.0025")); // 拉卡拉分账比例0.25%
|
||||
|
||||
@ -33,7 +33,7 @@ public class AddressParseResultTO implements java.io.Serializable {
|
||||
private String joinArea;
|
||||
|
||||
/**
|
||||
* 详细地址
|
||||
* (去掉省市县的)详细地址
|
||||
*/
|
||||
private String detailAddress;
|
||||
|
||||
|
||||
@ -112,7 +112,7 @@ public class AddressUtil {
|
||||
* System.out.println("详细地址: " + parsedAddress.getDetailAddress()); // 西山镇新安街粤桂花城1102号
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
String fullAddress = "广西壮族自治区贵港市桂平市西山镇新安街粤桂花城1102号";
|
||||
String fullAddress = "广西壮族自治区贵港市桂平市桂平西山镇新安街粤桂花城1102号";
|
||||
AddressParseResultTO parsedAddress = AddressUtil.parseAddress(fullAddress);
|
||||
System.out.println("省: " + parsedAddress.getProvince());
|
||||
System.out.println("市: " + parsedAddress.getCity());
|
||||
|
||||
@ -8,6 +8,7 @@ import java.text.SimpleDateFormat;
|
||||
import java.time.*;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeFormatterBuilder;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.time.temporal.ChronoField;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
@ -62,6 +63,121 @@ public class DateTimeUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证日期时间字符串是否符合支持的日期时间格式
|
||||
* 支持的格式包括:
|
||||
* - yyyy-MM-dd HH:mm (如 2023-12-01 09:30)
|
||||
* - yyyy-MM-dd HH:mm:ss (如 2023-12-01 09:30:45)
|
||||
* - yyyy-MM-dd HH:mm:ss.SSS (如 2023-12-01 09:30:45.123)
|
||||
* - yyyy-MM-dd HH:mm:ss.SSSSSS (如 2023-12-01 09:30:45.123456)
|
||||
* - yyyy-MM-dd HH:mm:ss.SSSSSSSSS (如 2023-12-01 09:30:45.123456789)
|
||||
* - yyyy/MM/dd HH:mm:ss (如 2023/12/01 09:30:45)
|
||||
* - yyyy.MM.dd HH:mm:ss (如 2023.12.01 09:30:45)
|
||||
*
|
||||
* @param dateTimeStr 待验证的日期时间字符串
|
||||
* @return true表示符合日期时间格式,false表示不符合
|
||||
*/
|
||||
public static LocalDateTime tryParseDateTime(String dateTimeStr) {
|
||||
// 空值检查
|
||||
if (dateTimeStr == null || dateTimeStr.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
dateTimeStr = dateTimeStr.trim();
|
||||
|
||||
// 使用正则表达式验证日期时间格式
|
||||
// 支持多种日期分隔符和从分钟到纳秒的各种时间格式
|
||||
String dateTimePattern = "^\\d{4}[-/.]\\d{1,2}[-/.]\\d{1,2}\\s+([01]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?(\\.\\d{1,9})?$";
|
||||
|
||||
if (!dateTimeStr.matches(dateTimePattern)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
// 尝试解析日期时间,确保日期时间值有效
|
||||
// 支持三种常见分隔符:-, /, .
|
||||
if (dateTimeStr.contains("-")) {
|
||||
return parseDateTime(dateTimeStr, "yyyy-MM-dd HH:mm", "yyyy-MM-dd HH:mm:ss",
|
||||
"yyyy-MM-dd HH:mm:ss.SSS", "yyyy-MM-dd HH:mm:ss.SSSSSS",
|
||||
"yyyy-MM-dd HH:mm:ss.SSSSSSSSS");
|
||||
} else if (dateTimeStr.contains("/")) {
|
||||
return parseDateTime(dateTimeStr, "yyyy/MM/dd HH:mm", "yyyy/MM/dd HH:mm:ss",
|
||||
"yyyy/MM/dd HH:mm:ss.SSS", "yyyy/MM/dd HH:mm:ss.SSSSSS",
|
||||
"yyyy/MM/dd HH:mm:ss.SSSSSSSSS");
|
||||
} else if (dateTimeStr.contains(".")) {
|
||||
return parseDateTime(dateTimeStr, "yyyy.MM.dd HH:mm", "yyyy.MM.dd HH:mm:ss",
|
||||
"yyyy.MM.dd HH:mm:ss.SSS", "yyyy.MM.dd HH:mm:ss.SSSSSS",
|
||||
"yyyy.MM.dd HH:mm:ss.SSSSSSSSS");
|
||||
}
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
// 解析失败说明日期时间值无效
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证并解析日期时间字符串为Date对象
|
||||
* 支持的格式包括:
|
||||
* - yyyy-MM-dd HH:mm (如 2023-12-01 09:30)
|
||||
* - yyyy-MM-dd HH:mm:ss (如 2023-12-01 09:30:45)
|
||||
* - yyyy-MM-dd HH:mm:ss.SSS (如 2023-12-01 09:30:45.123)
|
||||
* - yyyy-MM-dd HH:mm:ss.SSSSSS (如 2023-12-01 09:30:45.123456)
|
||||
* - yyyy-MM-dd HH:mm:ss.SSSSSSSSS (如 2023-12-01 09:30:45.123456789)
|
||||
* - yyyy/MM/dd HH:mm:ss (如 2023/12/01 09:30:45)
|
||||
* - yyyy.MM.dd HH:mm:ss (如 2023.12.01 09:30:45)
|
||||
*
|
||||
* @param dateTimeStr 待解析的日期时间字符串
|
||||
* @return 解析后的Date对象,解析失败返回null
|
||||
*/
|
||||
public static Date tryParseDateTimeToDate(String dateTimeStr) {
|
||||
LocalDateTime localDateTime = tryParseDateTime(dateTimeStr);
|
||||
if (localDateTime != null) {
|
||||
return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析日期时间字符串
|
||||
*
|
||||
* @param dateTimeStr 日期时间字符串
|
||||
* @param patterns 可能的日期时间格式模式
|
||||
* @return 解析后的 LocalDateTime 对象
|
||||
*/
|
||||
private static LocalDateTime parseDateTime(String dateTimeStr, String... patterns) {
|
||||
for (String pattern : patterns) {
|
||||
try {
|
||||
// 检查模式和字符串长度是否匹配
|
||||
if (isMatchingDateTimePattern(dateTimeStr, pattern)) {
|
||||
return LocalDateTime.parse(dateTimeStr, DateTimeFormatter.ofPattern(pattern));
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
// 继续尝试下一个格式
|
||||
}
|
||||
}
|
||||
|
||||
// 如果所有格式都失败,则抛出异常
|
||||
throw new DateTimeParseException("无法解析日期时间字符串: " + dateTimeStr, dateTimeStr, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断日期时间字符串是否与格式模式匹配
|
||||
*
|
||||
* @param dateTimeStr 日期时间字符串
|
||||
* @param pattern 格式模式字符串
|
||||
* @return 是否匹配
|
||||
*/
|
||||
private static boolean isMatchingDateTimePattern(String dateTimeStr, String pattern) {
|
||||
try {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
|
||||
LocalDateTime.parse(dateTimeStr, formatter);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将多种日期格式转换为 yyyy-MM-dd
|
||||
@ -233,8 +349,8 @@ public class DateTimeUtils {
|
||||
/**
|
||||
* 判断指定时间是否在两个时间点之间(包含边界)
|
||||
*
|
||||
* @param startTimeStr 开始时间字符串,格式为 HH:mm
|
||||
* @param endTimeStr 结束时间字符串,格式为 HH:mm
|
||||
* @param startTimeStr 开始时间字符串,支持格式如 HH:mm, HH:mm:ss, HH:mm:ss.SSS 等
|
||||
* @param endTimeStr 结束时间字符串,支持格式如 HH:mm, HH:mm:ss, HH:mm:ss.SSS 等
|
||||
* @param currentTime 要判断的时间点
|
||||
* @return 如果在时间段内返回true,否则返回false。出现异常时返回false,不影响主流程
|
||||
*/
|
||||
@ -247,11 +363,11 @@ public class DateTimeUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 解析开始时间
|
||||
LocalTime startTime = LocalTime.parse(startTimeStr, DateTimeFormatter.ofPattern("HH:mm"));
|
||||
// 解析开始时间 - 支持多种时间格式
|
||||
LocalTime startTime = parseTime(startTimeStr);
|
||||
|
||||
// 解析结束时间
|
||||
LocalTime endTime = LocalTime.parse(endTimeStr, DateTimeFormatter.ofPattern("HH:mm"));
|
||||
// 解析结束时间 - 支持多种时间格式
|
||||
LocalTime endTime = parseTime(endTimeStr);
|
||||
|
||||
// 获取当前时间的时间部分
|
||||
LocalTime nowTime = currentTime.toLocalTime();
|
||||
@ -273,18 +389,114 @@ public class DateTimeUtils {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断指定时间是否在两个时间点之间(包含边界)
|
||||
*
|
||||
* @param startTimeStr 开始时间字符串,支持格式如 HH:mm, HH:mm:ss, HH:mm:ss.SSS 等
|
||||
* @param endTimeStr 结束时间字符串,支持格式如 HH:mm, HH:mm:ss, HH:mm:ss.SSS 等
|
||||
* @param currentTime 要判断的时间点
|
||||
* @return 如果在时间段内返回true,否则返回false。出现异常时返回false,不影响主流程
|
||||
*/
|
||||
public static boolean isTimeInRange(String startTimeStr, String endTimeStr, Date currentTime) {
|
||||
if (currentTime == null) {
|
||||
log.warn("时间参数不能为空,startTimeStr: {}, endTimeStr: {}, currentTime: null",
|
||||
startTimeStr, endTimeStr);
|
||||
return false;
|
||||
}
|
||||
// 将Date转换为LocalDateTime并调用已有的方法
|
||||
LocalDateTime localDateTime = currentTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||||
return isTimeInRange(startTimeStr, endTimeStr, localDateTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前时间是否在两个时间点之间(包含边界)
|
||||
*
|
||||
* @param startTimeStr 开始时间字符串,格式为 HH:mm
|
||||
* @param endTimeStr 结束时间字符串,格式为 HH:mm
|
||||
* @param startTimeStr 开始时间字符串,支持格式如 HH:mm, HH:mm:ss, HH:mm:ss.SSS 等
|
||||
* @param endTimeStr 结束时间字符串,支持格式如 HH:mm, HH:mm:ss, HH:mm:ss.SSS 等
|
||||
* @return 如果在时间段内返回true,否则返回false
|
||||
* @throws IllegalArgumentException 当时间字符串格式不正确时抛出异常
|
||||
*/
|
||||
public static boolean isCurrentTimeInRange(String startTimeStr, String endTimeStr) {
|
||||
return isTimeInRange(startTimeStr, endTimeStr, LocalDateTime.now());
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析时间字符串,支持多种时间格式
|
||||
*
|
||||
* @param timeStr 时间字符串,支持格式如 HH:mm, HH:mm:ss, HH:mm:ss.SSS 等
|
||||
* @return 解析后的 LocalTime 对象
|
||||
*/
|
||||
private static LocalTime parseTime(String timeStr) {
|
||||
if (timeStr == null || timeStr.isEmpty()) {
|
||||
throw new IllegalArgumentException("时间字符串不能为空");
|
||||
}
|
||||
|
||||
try {
|
||||
// 尝试使用不同的格式解析时间字符串
|
||||
// 按照精度从高到低排序,避免精度损失
|
||||
DateTimeFormatter[] formatters = {
|
||||
DateTimeFormatter.ofPattern("HH:mm:ss.SSSSSSSSS"), // 纳秒(9位)
|
||||
DateTimeFormatter.ofPattern("HH:mm:ss.SSSSSS"), // 微秒(6位)
|
||||
DateTimeFormatter.ofPattern("HH:mm:ss.SSS"), // 毫秒(3位)
|
||||
DateTimeFormatter.ofPattern("HH:mm:ss"), // 秒
|
||||
DateTimeFormatter.ofPattern("HH:mm") // 分钟
|
||||
};
|
||||
|
||||
// 先尝试精确匹配长度的格式
|
||||
for (DateTimeFormatter formatter : formatters) {
|
||||
try {
|
||||
// 根据格式长度进行预筛选
|
||||
String pattern = formatter.toString();
|
||||
if (isMatchingTimePattern(timeStr, pattern)) {
|
||||
return LocalTime.parse(timeStr, formatter);
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
// 继续尝试下一个格式
|
||||
}
|
||||
}
|
||||
|
||||
// 如果精确匹配失败,按原有方式尝试所有格式
|
||||
for (DateTimeFormatter formatter : formatters) {
|
||||
try {
|
||||
return LocalTime.parse(timeStr, formatter);
|
||||
} catch (Exception ignored) {
|
||||
// 继续尝试下一个格式
|
||||
}
|
||||
}
|
||||
|
||||
// 如果所有格式都失败,则抛出异常
|
||||
throw new DateTimeParseException("无法解析时间字符串: " + timeStr, timeStr, 0);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.warn("时间解析失败,timeStr: {}", timeStr, e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断时间字符串是否与格式模式匹配
|
||||
*
|
||||
* @param timeStr 时间字符串
|
||||
* @param pattern 格式模式字符串
|
||||
* @return 是否匹配
|
||||
*/
|
||||
private static boolean isMatchingTimePattern(String timeStr, String pattern) {
|
||||
// 简单的长度匹配检查
|
||||
switch (pattern) {
|
||||
case "HH:mm":
|
||||
return timeStr.length() == 5 && timeStr.charAt(2) == ':';
|
||||
case "HH:mm:ss":
|
||||
return timeStr.length() == 8 && timeStr.charAt(2) == ':' && timeStr.charAt(5) == ':';
|
||||
case "HH:mm:ss.SSS":
|
||||
return timeStr.length() == 12 && timeStr.charAt(2) == ':' && timeStr.charAt(5) == ':' && timeStr.charAt(8) == '.';
|
||||
case "HH:mm:ss.SSSSSS":
|
||||
return timeStr.length() == 15 && timeStr.charAt(2) == ':' && timeStr.charAt(5) == ':' && timeStr.charAt(8) == '.';
|
||||
case "HH:mm:ss.SSSSSSSSS":
|
||||
return timeStr.length() == 18 && timeStr.charAt(2) == ':' && timeStr.charAt(5) == ':' && timeStr.charAt(8) == '.';
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// System.out.println(convertLklDate("2021-02-19")); // 2025-01-02
|
||||
@ -310,8 +522,9 @@ public class DateTimeUtils {
|
||||
boolean isWorkTime = isCurrentTimeInRange("09:00", "22:36");
|
||||
|
||||
// 判断特定时间是否在夜间时间(22:00-06:00)内
|
||||
LocalDateTime testTime = LocalDateTime.of(2025, 1, 1, 23, 30);
|
||||
boolean isNight = isTimeInRange("22:00", "06:00", testTime);
|
||||
// LocalDateTime testTime = LocalDateTime.of(2025, 1, 1, 23, 30);
|
||||
Date testTime = Date.from(LocalDateTime.of(2025, 10, 23, 21, 30).atZone(ZoneId.systemDefault()).toInstant());
|
||||
boolean isNight = isTimeInRange("08:30", "22:20", testTime);
|
||||
|
||||
System.out.println("当前时间是否在工作时间内:" + isWorkTime);
|
||||
System.out.println("特定时间是否在夜间时间段内:" + isNight);
|
||||
|
||||
@ -49,7 +49,7 @@ public class LakalaAdminController extends BaseControllerImpl {
|
||||
}
|
||||
|
||||
// 执行业务逻辑
|
||||
Boolean success = lakalaPayService.ewalletWithDrawD1(paramsJSON.getStr("mercId"), paramsJSON.getStr("merOrderNo"), paramsJSON.getStr("drawAmt"), paramsJSON.getStr("summary"));
|
||||
Boolean success = lakalaPayService.ewalletWithDrawD1(paramsJSON.getStr("mercId"), paramsJSON.getStr("merOrderNo"), paramsJSON.getStr("drawAmt"), paramsJSON.getStr("orderId"), paramsJSON.getStr("summary"));
|
||||
if (success) {
|
||||
return CommonResult.success("账户D1提现提交成功");
|
||||
}
|
||||
|
||||
@ -208,9 +208,10 @@ public interface LakalaApiService {
|
||||
* @param lklMerchantNo 拉卡拉商户号
|
||||
* @param receiveTradeNo 收货交易号(对应拉卡拉的trade_no)
|
||||
* @param receiveLogNo 收货流水号(对应拉卡拉的log_no)
|
||||
* @param logDate posp日期,yyyyMMdd,查清结算用, 一般是值交易完成日期(确认收货的日期)
|
||||
* @return Pair<Boolean, String> 处理结果对,first为是否成功,second为结果描述信息
|
||||
*/
|
||||
Pair<Boolean, String> innerDoOrderSeparateByMerchantAndLogNo(String lklMerchantNo, String receiveTradeNo, String receiveLogNo);
|
||||
Pair<Boolean, String> innerDoOrderSeparateByMerchantAndLogNo(String lklMerchantNo, String receiveTradeNo, String receiveLogNo, String logDate);
|
||||
|
||||
/**
|
||||
* 分账结果通知
|
||||
@ -339,9 +340,10 @@ public interface LakalaApiService {
|
||||
* @param mercId 822商户号或receiveNo
|
||||
* @param merOrderNo 商户订单号
|
||||
* @param drawAmt 提现金额(分)
|
||||
* @param orderId 商城订单Id
|
||||
* @param summary
|
||||
*/
|
||||
Boolean ewalletWithDrawD1(String mercId, String merOrderNo, String drawAmt, String summary);
|
||||
Boolean ewalletWithDrawD1(String mercId, String merOrderNo, String drawAmt, String orderId, String summary);
|
||||
|
||||
/**
|
||||
* 拉卡拉账户D1提现结果通知
|
||||
|
||||
@ -29,4 +29,12 @@ public interface LklOrderDrawService extends IBaseService<LklOrderDraw> {
|
||||
* @return
|
||||
*/
|
||||
LklOrderDraw getByByMercIdAndMerOrderNo(String mercId, String merOrderNo);
|
||||
|
||||
/**
|
||||
* 判断订单是否已经提现完成
|
||||
*
|
||||
* @param orderId
|
||||
* @return
|
||||
*/
|
||||
Boolean isOrderDrawed(String orderId);
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ package com.suisung.mall.shop.lakala.service.impl;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONArray;
|
||||
@ -823,7 +824,14 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
// 分账用途
|
||||
String logNo = paramsJSON.getStr("log_no");
|
||||
String tradeNo = paramsJSON.getStr("trade_no");
|
||||
log.debug("[确认收货通知] 获取基础交易信息: logNo={} tradeNo={}", logNo, tradeNo);
|
||||
String tradeTime = paramsJSON.getStr("trade_time"); // 实际交易完成时间。yyyyMMddHHmmss
|
||||
// 直接截取前8位,获取日期部分
|
||||
String logDate = tradeTime != null && tradeTime.length() >= 8 ? tradeTime.substring(0, 8) : null;
|
||||
if (logDate == null) {
|
||||
logDate = DateUtil.format(new Date(), "yyyyMMdd"); // 当前时间
|
||||
}
|
||||
|
||||
log.debug("[确认收货通知] 获取基础交易信息: logNo={} tradeNo={} logDate={}", logNo, tradeNo, logDate);
|
||||
|
||||
// 查询用途
|
||||
String originTradeNo = paramsJSON.getStr("origin_trade_no");
|
||||
@ -900,7 +908,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
// 重要:准备发起分账指令
|
||||
log.info("[确认收货通知] 开始发起分账指令: merchantNo={}, receiveTradeNo={}, logNo={}",
|
||||
merchantNo, shopOrderLkl.getLkl_receive_trade_no(), logNo);
|
||||
Pair<Boolean, String> separateResult = innerDoOrderSeparateByMerchantAndLogNo(merchantNo, shopOrderLkl.getLkl_receive_trade_no(), shopOrderLkl.getLkl_receive_log_no());
|
||||
Pair<Boolean, String> separateResult = innerDoOrderSeparateByMerchantAndLogNo(merchantNo, shopOrderLkl.getLkl_receive_trade_no(), shopOrderLkl.getLkl_receive_log_no(), logDate);
|
||||
if (!separateResult.getFirst()) {
|
||||
|
||||
shopOrderLkl.setSeparate_msg(separateResult.getSecond());
|
||||
@ -2451,15 +2459,16 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
* @param lklMerchantNo 拉卡拉商户号
|
||||
* @param receiveTradeNo 收货交易号(对应拉卡拉的trade_no)
|
||||
* @param receiveLogNo 收货流水号(对应拉卡拉的log_no)
|
||||
* @param logDate posp日期,yyyyMMdd,查清结算用, 一般是值交易完成日期(确认收货的日期)
|
||||
* @return Pair<Boolean, String> 处理结果对,first为是否成功,second为结果描述信息
|
||||
*/
|
||||
@Transactional
|
||||
@Override
|
||||
public Pair<Boolean, String> innerDoOrderSeparateByMerchantAndLogNo(String lklMerchantNo, String receiveTradeNo, String receiveLogNo) {
|
||||
public Pair<Boolean, String> innerDoOrderSeparateByMerchantAndLogNo(String lklMerchantNo, String receiveTradeNo, String receiveLogNo, String logDate) {
|
||||
// 1. 输入参数校验
|
||||
if (StrUtil.hasBlank(lklMerchantNo, receiveTradeNo, receiveLogNo)) {
|
||||
log.warn("[分账操作] 参数校验失败:缺少必要参数, lklMerchantNo={}, receiveTradeNo={}, receiveLogNo={}",
|
||||
lklMerchantNo, receiveTradeNo, receiveLogNo);
|
||||
if (StrUtil.hasBlank(lklMerchantNo, receiveTradeNo, receiveLogNo, logDate)) {
|
||||
log.warn("[分账操作] 参数校验失败:缺少必要参数, lklMerchantNo={}, receiveTradeNo={}, receiveLogNo={}, logDate={}",
|
||||
lklMerchantNo, receiveTradeNo, receiveLogNo, logDate);
|
||||
return Pair.of(false, "缺少必要参数");
|
||||
}
|
||||
|
||||
@ -2639,7 +2648,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
receiver.setSeparateValue(Convert.toStr(merchantAmount));
|
||||
recvDatas.add(receiver);
|
||||
}
|
||||
|
||||
|
||||
// 是否有二级代理商?
|
||||
boolean has2ndAgent = CheckUtil.isNotEmpty(agent2ndSplitRatio) && agent2ndReceiver != null &&
|
||||
StrUtil.isNotBlank(agent2ndReceiver.getReceiver_no()) &&
|
||||
@ -2695,7 +2704,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
separateRequest.setMerchantNo(merchantNo);
|
||||
separateRequest.setOutSeparateNo(shopOrderLkl.getOut_separate_no());
|
||||
separateRequest.setLogNo(shopOrderLkl.getLkl_receive_log_no()); // 使用确认收货流水号作为分账流水号
|
||||
separateRequest.setLogDate(shopOrderLkl.getLkl_log_date());
|
||||
separateRequest.setLogDate(logDate); // 重要:确认收货后的交易时间
|
||||
separateRequest.setTotalAmt(refCanSeparateAmt.toString());
|
||||
separateRequest.setLklOrgNo(orgCode);
|
||||
separateRequest.setCalType("0"); // 0- 按照指定金额,1- 按照指定比例。默认 0
|
||||
@ -2799,11 +2808,12 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
public JSONObject sacsSeparateNotify(HttpServletRequest request, String merchantNoParam, String separateNoParam) {
|
||||
String channel = "";
|
||||
try {
|
||||
JSONObject paramsJson = null;
|
||||
JSONObject paramsJson;
|
||||
if (!StrUtil.hasBlank(merchantNoParam, separateNoParam)) {
|
||||
channel = "(补偿)";
|
||||
log.info("[拉卡拉分账通知] 开始处理拉卡拉分账结果通知异步回调{},merchantNoParam={},separateNoParam={}",
|
||||
channel, merchantNoParam, separateNoParam);
|
||||
// 主动从拉卡拉获取分账结果
|
||||
paramsJson = sacsQuery(merchantNoParam, separateNoParam);
|
||||
} else {
|
||||
log.info("[拉卡拉分账通知] 开始处理拉卡拉分账结果通知异步回调");
|
||||
@ -2922,13 +2932,15 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 分账成功之后,立即申请提现
|
||||
String recvNo = Convert.toStr(detailData.get("recv_no"), "");
|
||||
String amt = Convert.toStr(detailData.get("amt"), "");
|
||||
if (StrUtil.isNotBlank(recvNo) && StrUtil.isNotBlank(amt)) {
|
||||
String outSeparateNoTemp = String.format("%s_%d", outSeparateNo, idx);
|
||||
Boolean drawSuccess = ewalletWithDrawD1(recvNo, outSeparateNoTemp, amt, JSONUtil.toJsonStr(detailDatas));
|
||||
String merOrderNo = String.format("%s_%d", outSeparateNo, idx);
|
||||
// 账户D1提现
|
||||
Boolean drawSuccess = ewalletWithDrawD1(recvNo, merOrderNo, amt, outSeparateNo, JSONUtil.toJsonStr(detailDatas));
|
||||
log.info("[拉卡拉分账通知] 账户D1提现{},商户号={},分账单号={},金额={}分",
|
||||
Boolean.TRUE.equals(drawSuccess) ? "成功" : "失败", recvNo, outSeparateNoTemp, amt);
|
||||
Boolean.TRUE.equals(drawSuccess) ? "成功" : "失败", recvNo, merOrderNo, amt);
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
@ -3038,9 +3050,9 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
public Integer fixUnSuccessSeparateStatusJob() {
|
||||
log.info("[分账状态修复任务] 开始执行未成功分账记录的状态修复任务");
|
||||
|
||||
// 获取2天前分账状态未成功的记录
|
||||
Date now = new Date();
|
||||
Date threeDaysAgo = DateUtils.addHours(now, -48);
|
||||
// 获取3天前分账状态未成功的记录
|
||||
Date endDate = new Date();
|
||||
Date beginDate = DateUtils.addDays(endDate, -3); // 3天前
|
||||
|
||||
// 分页参数
|
||||
int pageSize = 200;
|
||||
@ -3050,100 +3062,104 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
|
||||
// 记录处理开始时间
|
||||
long startTime = System.currentTimeMillis();
|
||||
String redisPrefKey = "lkl:separate:status:retry:";
|
||||
|
||||
List<LklOrderSeparate> lklOrderSeparates;
|
||||
do {
|
||||
// 分页获取未成功分账的记录
|
||||
lklOrderSeparates = lklOrderSeparateService.getUnSuccessSeparateList(threeDaysAgo, now, currentPage, pageSize);
|
||||
try {
|
||||
List<LklOrderSeparate> lklOrderSeparates;
|
||||
do {
|
||||
// 分页获取未成功分账的记录
|
||||
lklOrderSeparates = lklOrderSeparateService.getUnSuccessSeparateList(beginDate, endDate, currentPage, pageSize);
|
||||
|
||||
if (CollectionUtil.isEmpty(lklOrderSeparates)) {
|
||||
break;
|
||||
}
|
||||
|
||||
log.info("[分账状态修复任务] 获取到第{}页数据,共{}条记录", currentPage, lklOrderSeparates.size());
|
||||
|
||||
String redisPrefKey = "lkl:separate:status:retry:";
|
||||
|
||||
// 按处理次数排序,从未处理过的记录优先处理,处理次数越多优先级越低
|
||||
lklOrderSeparates.sort((o1, o2) -> {
|
||||
String redisKey1 = redisPrefKey + o1.getSeparate_no();
|
||||
String redisKey2 = redisPrefKey + o2.getSeparate_no();
|
||||
|
||||
int retryCount1 = Convert.toInt(redisService.get(redisKey1), 0);
|
||||
int retryCount2 = Convert.toInt(redisService.get(redisKey2), 0);
|
||||
|
||||
return Integer.compare(retryCount1, retryCount2);
|
||||
});
|
||||
|
||||
// 处理当前页中的记录
|
||||
for (LklOrderSeparate record : lklOrderSeparates) {
|
||||
// 检查该记录的处理次数是否已达到上限(5次)
|
||||
String redisKey = redisPrefKey + record.getSeparate_no();
|
||||
int retryCount = Convert.toInt(redisService.get(redisKey), 0);
|
||||
|
||||
if (retryCount >= 5) {
|
||||
log.warn("[分账状态修复任务] 记录已达到最大重试次数,跳过处理: merchantNo={}, separateNo={}",
|
||||
record.getMerchant_no(), record.getSeparate_no());
|
||||
continue;
|
||||
if (CollectionUtil.isEmpty(lklOrderSeparates)) {
|
||||
break;
|
||||
}
|
||||
|
||||
totalProcessed++;
|
||||
// 每处理10条记录才输出一次详细日志,减少日志量
|
||||
if (totalProcessed % 10 == 1) {
|
||||
log.info("[分账状态修复任务] 正在处理第 {} 条记录: merchantNo={}, separateNo={}, 已重试{}次",
|
||||
totalProcessed, record.getMerchant_no(), record.getSeparate_no(), retryCount);
|
||||
}
|
||||
log.info("[分账状态修复任务] 获取到第{}页数据,共{}条记录", currentPage, lklOrderSeparates.size());
|
||||
|
||||
try {
|
||||
// 增加处理次数计数并设置3天过期时间
|
||||
redisService.incr(redisKey, 1);
|
||||
redisService.expire(redisKey, 3 * 24 * 60 * 60);
|
||||
// 按处理次数排序,从未处理过的记录优先处理,处理次数越多优先级越低
|
||||
lklOrderSeparates.sort((o1, o2) -> {
|
||||
String redisKey1 = redisPrefKey + o1.getSeparate_no();
|
||||
String redisKey2 = redisPrefKey + o2.getSeparate_no();
|
||||
|
||||
// 调用分账通知回调接口进行状态补偿
|
||||
JSONObject notifyResp = sacsSeparateNotify(null, record.getMerchant_no(), record.getSeparate_no());
|
||||
int retryCount1 = Convert.toInt(redisService.get(redisKey1), 0);
|
||||
int retryCount2 = Convert.toInt(redisService.get(redisKey2), 0);
|
||||
|
||||
// 检查处理结果
|
||||
if (notifyResp != null && "SUCCESS".equals(notifyResp.getStr("code"))) {
|
||||
totalSuccessCount++;
|
||||
log.debug("[分账状态修复任务] 记录处理成功: merchantNo={}, separateNo={}",
|
||||
return Integer.compare(retryCount1, retryCount2);
|
||||
});
|
||||
|
||||
// 处理当前页中的记录
|
||||
for (LklOrderSeparate record : lklOrderSeparates) {
|
||||
// 检查该记录的处理次数是否已达到上限(5次)
|
||||
String redisKey = redisPrefKey + record.getSeparate_no();
|
||||
int retryCount = Convert.toInt(redisService.get(redisKey), 0);
|
||||
|
||||
if (retryCount >= 5) {
|
||||
log.warn("[分账状态修复任务] 记录已达到最大重试次数,跳过处理: merchantNo={}, separateNo={}",
|
||||
record.getMerchant_no(), record.getSeparate_no());
|
||||
} else {
|
||||
String errorMsg = notifyResp != null ? notifyResp.getStr("message") : "未知错误";
|
||||
log.warn("[分账状态修复任务] 记录处理失败: merchantNo={}, separateNo={}, errorMsg={}",
|
||||
record.getMerchant_no(), record.getSeparate_no(), errorMsg);
|
||||
continue;
|
||||
}
|
||||
|
||||
totalProcessed++;
|
||||
// 每处理10条记录才输出一次详细日志,减少日志量
|
||||
if (totalProcessed % 10 == 1) {
|
||||
log.info("[分账状态修复任务] 正在处理第 {} 条记录: merchantNo={}, separateNo={}, 已重试{}次",
|
||||
totalProcessed, record.getMerchant_no(), record.getSeparate_no(), retryCount);
|
||||
}
|
||||
|
||||
try {
|
||||
// 增加处理次数计数并设置3天过期时间
|
||||
redisService.incr(redisKey, 1);
|
||||
redisService.expire(redisKey, 3 * 24 * 60 * 60);
|
||||
|
||||
// 调用拉卡拉分账通知回调接口进行状态补偿
|
||||
JSONObject notifyResp = sacsSeparateNotify(null, record.getMerchant_no(), record.getSeparate_no());
|
||||
|
||||
// 检查处理结果
|
||||
if (notifyResp != null && "SUCCESS".equals(notifyResp.getStr("code"))) {
|
||||
totalSuccessCount++;
|
||||
log.debug("[分账状态修复任务] 记录处理成功: merchantNo={}, separateNo={}",
|
||||
record.getMerchant_no(), record.getSeparate_no());
|
||||
} else {
|
||||
String errorMsg = notifyResp != null ? notifyResp.getStr("message") : "未知错误";
|
||||
log.warn("[分账状态修复任务] 记录处理失败: merchantNo={}, separateNo={}, errorMsg={}",
|
||||
record.getMerchant_no(), record.getSeparate_no(), errorMsg);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("[分账状态修复任务] 处理记录时发生异常: merchantNo={}, separateNo={}",
|
||||
record.getMerchant_no(), record.getSeparate_no(), e);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("[分账状态修复任务] 处理记录时发生异常: merchantNo={}, separateNo={}",
|
||||
record.getMerchant_no(), record.getSeparate_no(), e);
|
||||
}
|
||||
}
|
||||
|
||||
log.info("[分账状态修复任务] 第{}页处理完成,已处理 {} 条记录,总成功 {} 条",
|
||||
currentPage, totalProcessed, totalSuccessCount);
|
||||
log.info("[分账状态修复任务] 第{}页处理完成,已处理 {} 条记录,总成功 {} 条",
|
||||
currentPage, totalProcessed, totalSuccessCount);
|
||||
|
||||
// 如果当前页数据少于页面大小,说明已经是最后一页
|
||||
if (lklOrderSeparates.size() < pageSize) {
|
||||
break;
|
||||
}
|
||||
// 如果当前页数据少于页面大小,说明已经是最后一页
|
||||
if (lklOrderSeparates.size() < pageSize) {
|
||||
break;
|
||||
}
|
||||
|
||||
currentPage++;
|
||||
currentPage++;
|
||||
|
||||
// 添加短暂延迟,避免对系统造成过大压力
|
||||
try {
|
||||
// 添加短暂延迟,避免对系统造成过大压力
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
break;
|
||||
}
|
||||
|
||||
} while (!CollectionUtil.isEmpty(lklOrderSeparates));
|
||||
} while (!CollectionUtil.isEmpty(lklOrderSeparates));
|
||||
|
||||
} 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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检测修复补全商户的商户分账业务信息及分账接收方绑定关系(分账业务申请异步通知的补偿机制)
|
||||
*
|
||||
@ -3499,11 +3515,12 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
* @param mercId 822商户号或receiveNo
|
||||
* @param merOrderNo 商户订单号
|
||||
* @param drawAmt 提现金额(分)
|
||||
* @param orderId 商城订单Id
|
||||
* @param summary 摘要信息
|
||||
* @return 操作结果,成功返回true,失败返回false
|
||||
*/
|
||||
@Override
|
||||
public Boolean ewalletWithDrawD1(String mercId, String merOrderNo, String drawAmt, String summary) {
|
||||
public Boolean ewalletWithDrawD1(String mercId, String merOrderNo, String drawAmt, String orderId, String summary) {
|
||||
// 1. 参数校验
|
||||
if (StrUtil.hasBlank(mercId, merOrderNo, drawAmt)) {
|
||||
log.warn("[D1提现申请] D1提现参数校验失败,关键参数为空: mercId={}, merOrderNo={}, drawAmt={}",
|
||||
@ -3548,7 +3565,8 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
if (StrUtil.isNotBlank(summary)) {
|
||||
request.setSummary(summary);
|
||||
}
|
||||
request.setNotifyUrl(projectDomain + "/api/mobile/shop/lakala/ewallet/ewallet/drawNotify");
|
||||
|
||||
request.setNotifyUrl(projectDomain + "/api/mobile/shop/lakala/ewallet/drawNotify");
|
||||
|
||||
// 4. 发送请求
|
||||
String responseStr = LKLSDK.httpPost(request);
|
||||
@ -3574,6 +3592,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
LklOrderDraw lklOrderDraw = new LklOrderDraw();
|
||||
lklOrderDraw.setMerc_id(mercId);
|
||||
lklOrderDraw.setMer_order_no(merOrderNo);
|
||||
lklOrderDraw.setOrder_id(orderId);
|
||||
lklOrderDraw.setDraw_jnl(Convert.toStr(drawJnl));
|
||||
lklOrderDraw.setDraw_amt(drawAmtYuan);
|
||||
lklOrderDraw.setBatch_auto_settle(payType);
|
||||
@ -3618,13 +3637,13 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
*/
|
||||
@Override
|
||||
public JSONObject ewalletWithDrawNotify(HttpServletRequest request) {
|
||||
log.debug("[拉卡拉提现结果通知] 开始处理拉卡拉提现结果通知");
|
||||
log.debug("[拉卡拉D1提现结果通知] 开始处理拉卡拉提现结果通知");
|
||||
|
||||
try {
|
||||
// 1. 验签处理 - 验证通知来源的合法性
|
||||
Pair<Boolean, String> signCheckResult = LakalaUtil.chkLklApiNotifySign(request, lklNotifyCerPath, false);
|
||||
if (!signCheckResult.getFirst()) {
|
||||
log.warn("[LklOrderDraw] 验签失败: {}", signCheckResult.getSecond());
|
||||
log.warn("[拉卡拉D1提现结果通知] 验签失败: {}", signCheckResult.getSecond());
|
||||
return JSONUtil.createObj()
|
||||
.set("code", "FAIL")
|
||||
.set("message", signCheckResult.getSecond());
|
||||
@ -3633,7 +3652,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
// 2. 解析回调参数
|
||||
JSONObject paramsJSON = JSONUtil.parseObj(signCheckResult.getSecond());
|
||||
if (paramsJSON == null) {
|
||||
log.warn("[拉卡拉提现结果通知] 回调参数解析失败");
|
||||
log.warn("[拉卡拉D1提现结果通知] 回调参数解析失败");
|
||||
return JSONUtil.createObj()
|
||||
.set("code", "FAIL")
|
||||
.set("message", "回调参数解析失败");
|
||||
@ -3643,9 +3662,9 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
String mercId = paramsJSON.getStr("mercId");
|
||||
String merOrderNo = paramsJSON.getStr("merOrderNo");
|
||||
|
||||
log.info("[拉卡拉提现结果通知] 提现通知参数: drawState={}, mercId={}, merOrderNo={}", drawState, mercId, merOrderNo);
|
||||
log.info("[拉卡拉D1提现结果通知] 提现通知参数: drawState={}, mercId={}, merOrderNo={}", drawState, mercId, merOrderNo);
|
||||
|
||||
if (StrUtil.isBlank(mercId) || StrUtil.isBlank(merOrderNo) || StrUtil.isBlank(drawState)) {
|
||||
if (StrUtil.hasBlank(mercId, merOrderNo, drawState)) {
|
||||
log.warn("[拉卡拉提现结果通知] 回调参数缺失: drawState={}, mercId={}, merOrderNo={}", drawState, mercId, merOrderNo);
|
||||
return JSONUtil.createObj()
|
||||
.set("code", "FAIL")
|
||||
@ -3654,16 +3673,16 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
|
||||
// 只处理成功的提现状态
|
||||
if (!"DRAW.SUCCESS".equals(drawState)) {
|
||||
log.debug("[拉卡拉提现结果通知] 提现状态未成功,忽略处理: drawState={}", drawState);
|
||||
log.debug("[拉卡拉D1提现结果通知] 提现状态未成功,忽略处理: drawState={}", drawState);
|
||||
return JSONUtil.createObj()
|
||||
.set("code", "SUCCESS") // 返回成功,避免重复通知
|
||||
.set("code", "FAIL") // 返回成功,避免重复通知
|
||||
.set("message", "状态未成功,忽略处理");
|
||||
}
|
||||
|
||||
// 3. 转换参数并更新数据
|
||||
String snakeCaseJson = StringUtils.convertCamelToSnake(signCheckResult.getSecond());
|
||||
if (StringUtils.isBlank(snakeCaseJson)) {
|
||||
log.error("[拉卡拉提现结果通知] 回调参数转换失败,mercId={} merOrderNo={}", mercId, merOrderNo);
|
||||
log.error("[拉卡拉D1提现结果通知] 回调参数转换失败,mercId={} merOrderNo={}", mercId, merOrderNo);
|
||||
return JSONUtil.createObj()
|
||||
.set("code", "FAIL")
|
||||
.set("message", "回调参数转换失败");
|
||||
@ -3671,7 +3690,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
|
||||
LklOrderDraw lklOrderDraw = JSONUtil.toBean(snakeCaseJson, LklOrderDraw.class);
|
||||
if (lklOrderDraw == null) {
|
||||
log.error("[拉卡拉提现结果通知] 回调参数转换为对象失败,mercId={} merOrderNo={}", mercId, merOrderNo);
|
||||
log.error("[拉卡拉D1提现结果通知] 回调参数转换为对象失败,mercId={} merOrderNo={}", mercId, merOrderNo);
|
||||
return JSONUtil.createObj()
|
||||
.set("code", "FAIL")
|
||||
.set("message", "回调参数转换失败");
|
||||
@ -3679,13 +3698,13 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
|
||||
boolean isSuccess = lklOrderDrawService.addOrUpdateByMercIdAndMerOrderNo(lklOrderDraw);
|
||||
if (!isSuccess) {
|
||||
log.error("[拉卡拉提现结果通知] 数据更新失败,mercId={} merOrderNo={}", mercId, merOrderNo);
|
||||
log.error("[拉卡拉D1提现结果通知] 数据更新失败,mercId={} merOrderNo={}", mercId, merOrderNo);
|
||||
return JSONUtil.createObj()
|
||||
.set("code", "FAIL")
|
||||
.set("message", "数据更新失败");
|
||||
}
|
||||
|
||||
log.info("[拉卡拉提现结果通知] 拉卡拉提现结果通知处理成功,mercId={} merOrderNo={}", mercId, merOrderNo);
|
||||
log.info("[拉卡拉D1提现结果通知] 拉卡拉提现结果通知处理成功,mercId={} merOrderNo={}", mercId, merOrderNo);
|
||||
|
||||
// 4. 返回成功响应
|
||||
return JSONUtil.createObj()
|
||||
@ -3693,7 +3712,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
.set("message", "处理成功");
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("[拉卡拉提现结果通知] 处理拉卡拉提现结果通知异常", e);
|
||||
log.error("[拉卡拉D1提现结果通知] 处理拉卡拉提现结果通知异常", e);
|
||||
return JSONUtil.createObj()
|
||||
.set("code", "FAIL")
|
||||
.set("message", "系统处理异常");
|
||||
|
||||
@ -38,7 +38,7 @@ public class LklOrderDrawServiceImpl extends BaseServiceImpl<LklOrderDrawMapper,
|
||||
queryWrapper.eq("draw_jnl", record.getDraw_jnl());
|
||||
}
|
||||
|
||||
LklOrderDraw existsRecord = getOne(queryWrapper);
|
||||
LklOrderDraw existsRecord = findOne(queryWrapper);
|
||||
if (existsRecord != null && existsRecord.getId() != null && existsRecord.getId() > 0) {
|
||||
// 更新记录
|
||||
log.info("[LklOrderDraw] 记录已存在,执行更新操作,ID={}", existsRecord.getId());
|
||||
@ -102,4 +102,39 @@ public class LklOrderDrawServiceImpl extends BaseServiceImpl<LklOrderDrawMapper,
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断订单是否已经提现完成
|
||||
*
|
||||
* @param orderId 订单ID
|
||||
* @return 如果订单已提现完成返回true,否则返回false
|
||||
*/
|
||||
@Override
|
||||
public Boolean isOrderDrawed(String orderId) {
|
||||
// 参数校验
|
||||
if (StrUtil.isBlank(orderId)) {
|
||||
log.warn("订单ID为空,无法判断提现状态");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
// 查询提现成功的记录
|
||||
LklOrderDraw lklOrderDraw = findOne(new QueryWrapper<LklOrderDraw>()
|
||||
.eq("order_id", orderId)
|
||||
.eq("draw_state", "DRAW.SUCCESS")
|
||||
.orderByDesc("id"));
|
||||
|
||||
// 根据查询结果判断是否已提现
|
||||
if (lklOrderDraw != null) {
|
||||
log.debug("订单[{}]提现已完成", orderId);
|
||||
return true;
|
||||
} else {
|
||||
log.debug("订单[{}]提现未完成或不存在提现记录", orderId);
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("查询订单[{}]提现状态异常", orderId, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,7 +103,7 @@ public class ShopOrderBaseController extends BaseControllerImpl {
|
||||
public CommonResult cancel(@RequestParam(name = "order_id") String order_id) {
|
||||
return shopOrderBaseService.cancel(order_id);
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation(value = "确认收货", notes = "确认收货")
|
||||
@RequestMapping(value = "/receive", method = {RequestMethod.GET, RequestMethod.POST})
|
||||
public CommonResult receive(@RequestParam(name = "order_id") String order_id) {
|
||||
@ -326,9 +326,12 @@ public class ShopOrderBaseController extends BaseControllerImpl {
|
||||
return CommonResult.failed(ResultCode.FORBIDDEN);
|
||||
}
|
||||
|
||||
// 同城订单超时秒数
|
||||
// 初定同城订单超时的秒数
|
||||
long mchOrderExpireSeconds = shopOrderBaseService.sameCityOrderExpireSeconds(2100L); // 35分钟超时,60秒*35分钟 = 2100秒
|
||||
|
||||
//同城配送订单状态(delivery=1时才生效):无值 or 0-全部订单;1-进行中订单;2-异常(超时)订单;3-退款订单;9-已完成订单
|
||||
Integer status = params.getInt("status");
|
||||
|
||||
// === 构建响应数据 ===
|
||||
Map<String, Object> respMap = new HashMap<>();
|
||||
// 订单列表数据(缓存时间25分钟)
|
||||
@ -336,7 +339,7 @@ public class ShopOrderBaseController extends BaseControllerImpl {
|
||||
storeId,
|
||||
params.getStr("keyword"),
|
||||
params.getInt("delivery"),
|
||||
params.getInt("status"),
|
||||
status,
|
||||
params.getInt("logistics_status"),
|
||||
mchOrderExpireSeconds,
|
||||
params.getLong("begin_time"),
|
||||
@ -388,6 +391,7 @@ public class ShopOrderBaseController extends BaseControllerImpl {
|
||||
return CommonResult.failed(ResultCode.FORBIDDEN);
|
||||
}
|
||||
|
||||
|
||||
// 5. 返回结果
|
||||
return CommonResult.success(mchOrderInfoDTO);
|
||||
} catch (Exception e) {
|
||||
|
||||
@ -113,7 +113,7 @@ public class UserOrderController extends BaseControllerImpl {
|
||||
return CommonResult.success(shopOrderBaseService.detail(order_id));
|
||||
}
|
||||
|
||||
@ApiOperation(value = "添加订单详细信息", notes = "添加订单详细信息")
|
||||
@ApiOperation(value = "添加订单详细信息", notes = "添加订单详细信息(提交订单)")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "ud_id", value = "收货地址编号", paramType = "query", required = true, dataType = "int"),
|
||||
@ApiImplicitParam(name = "is_edu", value = "是教育", paramType = "query", required = false, dataType = "int"),
|
||||
|
||||
@ -85,7 +85,8 @@ public class UserReturnController extends BaseControllerImpl {
|
||||
return CommonResult.failed(ResultCode.NEED_LOGIN);
|
||||
}
|
||||
|
||||
return shopOrderReturnService.addWholeItems(order_id, false, "");
|
||||
// return shopOrderReturnService.addWholeItems(order_id, false, "");
|
||||
return shopOrderReturnService.addRemainingItems(order_id, true, "");
|
||||
}
|
||||
|
||||
@ApiOperation(value = "取消退款订单", notes = "取消退款订单")
|
||||
|
||||
@ -9,6 +9,7 @@ import com.suisung.mall.common.constant.CommonConstant;
|
||||
import com.suisung.mall.common.constant.MqConstant;
|
||||
import com.suisung.mall.common.constant.RedisConstant;
|
||||
import com.suisung.mall.common.modules.order.ShopOrderInfo;
|
||||
import com.suisung.mall.common.utils.CheckUtil;
|
||||
import com.suisung.mall.common.utils.DateTimeUtils;
|
||||
import com.suisung.mall.core.web.service.RedisService;
|
||||
import com.suisung.mall.shop.message.service.PushMessageService;
|
||||
@ -138,10 +139,10 @@ public class OrderPayedListener {
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("[订单支付监听] 支付异步通知回调处理结果: {}, 订单ID: {}", flag, orderId);
|
||||
logger.info("[订单支付监听] 订单ID: {},支付异步通知回调处理是否成功: {} ", flag, orderId);
|
||||
|
||||
// 生成取单号和打印小票
|
||||
if (flag) {
|
||||
// TODO 以下仅处理下单打印的情况,还需要处理退单打印分支。
|
||||
|
||||
// 原始状态 2010-待付款;2011--待订单审核;2013-待财务审核 变成 2020-待配货;2016-已经付款 的时候
|
||||
// 生成取单号,打票机打印订单,向顺丰同城下单
|
||||
@ -152,12 +153,14 @@ public class OrderPayedListener {
|
||||
Long orderPickupNum = shopOrderInfoService.isPaidOrderGenPickNumAndPrint(orderInfoOld.getStore_id(), orderId);
|
||||
|
||||
// 如果配送方式是 顺丰同城下单
|
||||
if (orderInfoOld.getDelivery_type_id() != null && orderInfoOld.getDelivery_type_id().equals(StateCode.DELIVERY_TYPE_SAME_CITY)
|
||||
&& orderPickupNum > 0) {
|
||||
// 发送顺丰同城快递
|
||||
if (CheckUtil.isNotEmpty(orderInfoOld.getDelivery_type_id())
|
||||
&& orderInfoOld.getDelivery_type_id().equals(StateCode.DELIVERY_TYPE_SAME_CITY)
|
||||
&& CheckUtil.isNotEmpty(orderPickupNum)) {
|
||||
|
||||
// 顺丰同城下单
|
||||
Pair<Boolean, String> pairCreateSfOrder = sfExpressApiService.innerCreateSfExpressOrder(orderId, orderPickupNum);
|
||||
if (pairCreateSfOrder == null) {
|
||||
logger.error("[订单支付监听] 顺丰同城下单失败!pairCreateSfOrder 返回空值. 订单ID: {}", orderId);
|
||||
logger.error("[订单支付监听] 顺丰同城下单失败,无返回值 订单ID: {}", orderId);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ package com.suisung.mall.shop.order.service;
|
||||
import com.suisung.mall.common.api.CommonResult;
|
||||
import com.suisung.mall.common.modules.order.ShopOrderInfo;
|
||||
import com.suisung.mall.core.web.service.IBaseService;
|
||||
import org.springframework.data.util.Pair;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -91,6 +92,7 @@ public interface ShopOrderInfoService extends IBaseService<ShopOrderInfo> {
|
||||
|
||||
/**
|
||||
* 分页查询取消订单
|
||||
*
|
||||
* @param pageNum
|
||||
* @param pageSize
|
||||
* @return
|
||||
@ -99,7 +101,19 @@ public interface ShopOrderInfoService extends IBaseService<ShopOrderInfo> {
|
||||
|
||||
/**
|
||||
* 查询取消订单总数
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
long countgetAutoCancelOrderId();
|
||||
|
||||
/**
|
||||
* 检查订单预约参数是否合法
|
||||
*
|
||||
* @param storeId 店铺ID
|
||||
* @param bookingState 预约配送状态
|
||||
* @param bookingBeginTime 预约开始时间
|
||||
* @param bookingEndTime 预约截止时间
|
||||
* @return
|
||||
*/
|
||||
Pair<Boolean, String> checkBookingOrderArgs(Integer storeId, Integer bookingState, String bookingBeginTime, String bookingEndTime);
|
||||
}
|
||||
|
||||
@ -159,6 +159,28 @@ public interface ShopOrderReturnService extends IBaseService<ShopOrderReturn> {
|
||||
*/
|
||||
boolean ifDenyReturn(Long order_item_id);
|
||||
|
||||
/**
|
||||
* 判断订单中某个商品是否禁止退货
|
||||
* <p>
|
||||
* 该方法用于检查指定订单中的特定商品是否允许退货,主要检查以下几种情况:
|
||||
* 1. 商品是否设置了"禁止退货"的消费者保障标识
|
||||
* 2. 订单是否已超过退货期限(已收货或已完成状态,且超过可提现时间)
|
||||
* 3. 拉卡拉分账订单是否已完成提现
|
||||
*
|
||||
* @param orderId 订单ID
|
||||
* @param productId 商品ID
|
||||
* @return boolean true表示禁止退货,false表示允许退货
|
||||
*/
|
||||
boolean ifOrderItemDenyReturn(String orderId, Long productId);
|
||||
|
||||
/**
|
||||
* 判断订单是否禁止退货
|
||||
*
|
||||
* @param orderId 订单ID
|
||||
* @return 如果订单禁止退货返回true,否则返回false
|
||||
*/
|
||||
boolean isOrderDenyReturn(String orderId);
|
||||
|
||||
/**
|
||||
* 该方法用于处理整单退货申请,具体功能如下:
|
||||
* 根据订单ID获取订单信息,若为空则抛异常。
|
||||
@ -201,4 +223,6 @@ public interface ShopOrderReturnService extends IBaseService<ShopOrderReturn> {
|
||||
* @return
|
||||
*/
|
||||
CommonResult doRefundForMch(JSONObject params);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -99,6 +99,7 @@ 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;
|
||||
@ -376,6 +377,10 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
@Autowired
|
||||
private LakalaApiService lakalaApiService;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private WxOrderShippingService wxOrderShippingService;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private SyncThirdDataService syncThirdDataService;
|
||||
@ -665,6 +670,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
Integer user_id = user.getId();
|
||||
log.debug("当前用户ID: {}", user_id);
|
||||
|
||||
|
||||
QueryWrapper<ShopDistributionUserOrder> userOrderQueryWrapper = new QueryWrapper<>();
|
||||
userOrderQueryWrapper.eq("user_id", user_id).in("order_id", order_ids);
|
||||
ShopDistributionUserOrder distributionUserOrder = shopDistributionUserOrderService.findOne(userOrderQueryWrapper);
|
||||
@ -756,11 +762,14 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
throw new ApiException(I18nUtil._("无该订单访问权限!"));
|
||||
}
|
||||
|
||||
// 是否禁止退款
|
||||
int isOrderDenyReturn = shopOrderReturnService.isOrderDenyReturn(order_id) ? 1 : 2;
|
||||
data.put("is_deny_return", isOrderDenyReturn);
|
||||
|
||||
log.info("订单详情获取完成,订单ID: {}", order_id);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param order_id
|
||||
* @param base_row shopOrderBase
|
||||
@ -1597,6 +1606,21 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
}
|
||||
}
|
||||
|
||||
// 预约订单检测
|
||||
Integer bookingState = Convert.toInt(getParameter("booking_state"));
|
||||
if (CheckUtil.isNotEmpty(bookingState) && CommonConstant.Order_Booking_State_YY.equals(bookingState)) {
|
||||
String bookingBeginTime = getParameter("booking_begin_time");
|
||||
String bookingEndTime = getParameter("booking_end_time");
|
||||
Pair<Boolean, String> pair = shopOrderInfoService.checkBookingOrderArgs(checkedStore, bookingState, bookingBeginTime, bookingEndTime);
|
||||
if (!pair.getFirst()) {
|
||||
throw new ApiException(I18nUtil._(pair.getSecond()));
|
||||
}
|
||||
|
||||
cartData.put("booking_state", bookingState);
|
||||
cartData.put("booking_begin_time", bookingBeginTime);
|
||||
cartData.put("booking_end_time", bookingEndTime);
|
||||
}
|
||||
|
||||
// 添加保存订单(关键方法)
|
||||
List<String> orderIdRow = addOrder(cartData, true, false, null);
|
||||
|
||||
@ -5037,6 +5061,9 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
continue;
|
||||
}
|
||||
|
||||
/// 服务号确认收货通知跳转链接设置
|
||||
wxOrderShippingService.setMsgJumpPath(order_id);
|
||||
|
||||
BigDecimal order_points_add = order_data_row.getOrder_points_add();
|
||||
BigDecimal order_double_points_add = order_data_row.getOrder_double_points_add();
|
||||
BigDecimal order_points_add_all = order_points_add != null ? order_points_add : BigDecimal.ZERO;
|
||||
@ -6605,13 +6632,21 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
info_row.setCoupon_type_id(shopProductIndex.getCoupon_type_id());
|
||||
}
|
||||
|
||||
// 预约订单关键字段保存处理
|
||||
Integer bookingState = Convert.toInt(cart_data.get("booking_state"));
|
||||
Date bookingBeginTime = DateTimeUtils.tryParseDateTimeToDate(Convert.toStr(cart_data.get("booking_begin_time")));
|
||||
Date bookingEndTime = DateTimeUtils.tryParseDateTimeToDate(Convert.toStr(cart_data.get("booking_end_time")));
|
||||
if (CommonConstant.Order_Booking_State_YY.equals(bookingState) && bookingBeginTime != null && bookingEndTime != null) {
|
||||
info_row.setBooking_state(bookingState);
|
||||
info_row.setBooking_begin_time(bookingBeginTime);
|
||||
info_row.setBooking_end_time(bookingEndTime);
|
||||
}
|
||||
|
||||
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()));
|
||||
}
|
||||
@ -8560,13 +8595,18 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取(确认收货之后)多久后可提现(时间戳毫秒)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Long getWithdrawTime() {
|
||||
//订单可提现时间
|
||||
Date now = new Date();
|
||||
Long withdraw_time = now.getTime();
|
||||
Long withdraw_time;
|
||||
|
||||
float withdraw_received_day = accountBaseConfigService.getConfig("withdraw_received_day", 7f);
|
||||
float withdraw_received_day = accountBaseConfigService.getConfig("withdraw_received_day", 1f); // 确认收货之后多久可以提现,默认1天
|
||||
int second = NumberUtil.mul(withdraw_received_day, 60, 60, 24).intValue();
|
||||
|
||||
if (withdraw_received_day >= 0) {
|
||||
@ -8907,17 +8947,16 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
} catch (Exception e) {
|
||||
logger.error("获取物流轨迹失败,订单ID:{}", order.getOrder_id(), e);
|
||||
}
|
||||
}
|
||||
// 处理顺丰同城物流轨迹
|
||||
else if (CommonService.isSFExpress(deliveryTypeId)
|
||||
&& orderStateId >= StateCode.ORDER_STATE_SHIPPED
|
||||
&& orderStateId <= StateCode.ORDER_STATE_FINISH
|
||||
} else if (CommonService.isSFExpress(deliveryTypeId)
|
||||
&& orderStateId.intValue() >= StateCode.ORDER_STATE_SHIPPED
|
||||
&& orderStateId.intValue() <= StateCode.ORDER_STATE_FINISH
|
||||
&& order.getSf_order_info() != null
|
||||
&& order.getSf_order_info().getFeed() == null) {
|
||||
&& StrUtil.isBlank(order.getSf_order_info().getFeed())) {
|
||||
// 获取顺丰同城的物流轨迹
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("order_id", order.getSf_order_info().getSf_order_id());
|
||||
try {
|
||||
|
||||
ThirdApiRes feedRes = sfExpressApiService.listOrderFeed(params);
|
||||
logger.info("获取配送员物流轨迹:{}", feedRes);
|
||||
if (feedRes != null && feedRes.getError_code() != null && feedRes.getError_code().equals(0)) {
|
||||
@ -8926,6 +8965,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
order.getSf_order_info().setFeed(JSONUtil.toJsonStr(result.get("feed")));
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("获取顺丰同城物流轨迹失败,订单ID:{}", order.getOrder_id(), e);
|
||||
}
|
||||
@ -8934,6 +8974,16 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
|
||||
// 格式化取货号
|
||||
order.setOrder_pickup_num_str(fmtPickNum(order.getOrder_pickup_num()));
|
||||
|
||||
// 订单是否禁止退款
|
||||
int isOrderDenyReturn = shopOrderReturnService.isOrderDenyReturn(order.getOrder_id()) ? 1 : 2;
|
||||
order.setIs_deny_return(isOrderDenyReturn);
|
||||
|
||||
// 订单商品列表是否禁止退款
|
||||
order.getOrder_items().forEach(item -> {
|
||||
item.setIs_deny_return(isOrderDenyReturn);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
return pageList;
|
||||
@ -9031,10 +9081,18 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
// 格式化取货号
|
||||
orderDetail.setOrder_pickup_num_str(fmtPickNum(orderDetail.getOrder_pickup_num()));
|
||||
|
||||
// 订单是否禁止退款
|
||||
int isOrderDenyReturn = shopOrderReturnService.isOrderDenyReturn(orderId) ? 1 : 2;
|
||||
orderDetail.setIs_deny_return(isOrderDenyReturn);
|
||||
|
||||
// 订单商品列表是否禁止退款
|
||||
orderDetail.getOrder_items().forEach(item -> {
|
||||
item.setIs_deny_return(isOrderDenyReturn);
|
||||
});
|
||||
|
||||
return orderDetail;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 商家订单各个分类和状态的订单数量
|
||||
*
|
||||
|
||||
@ -25,9 +25,11 @@ import com.suisung.mall.common.modules.order.ShopOrderStateLog;
|
||||
import com.suisung.mall.common.modules.pay.PayPlantformResource;
|
||||
import com.suisung.mall.common.modules.plantform.ShopPlantformFeedback;
|
||||
import com.suisung.mall.common.modules.product.ShopProductComment;
|
||||
import com.suisung.mall.common.modules.store.ShopStoreInfo;
|
||||
import com.suisung.mall.common.pojo.res.ThirdApiRes;
|
||||
import com.suisung.mall.common.utils.CheckUtil;
|
||||
import com.suisung.mall.common.utils.CommonUtil;
|
||||
import com.suisung.mall.common.utils.DateTimeUtils;
|
||||
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
|
||||
import com.suisung.mall.shop.base.service.AccountBaseConfigService;
|
||||
import com.suisung.mall.shop.base.service.ShopBaseStateCodeService;
|
||||
@ -41,12 +43,14 @@ import com.suisung.mall.shop.product.service.ShopProductBaseService;
|
||||
import com.suisung.mall.shop.product.service.ShopProductCommentService;
|
||||
import com.suisung.mall.shop.sfexpress.service.SFExpressApiService;
|
||||
import com.suisung.mall.shop.store.service.ShopStoreBaseService;
|
||||
import com.suisung.mall.shop.store.service.ShopStoreInfoService;
|
||||
import com.suisung.mall.shop.store.service.ShopStorePrinterService;
|
||||
import com.suisung.mall.shop.store.service.ShopStoreSfOrderService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.data.util.Pair;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
@ -84,6 +88,8 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
@Autowired
|
||||
private ShopStoreBaseService shopStoreBaseService;
|
||||
@Autowired
|
||||
private ShopStoreInfoService shopStoreInfoService;
|
||||
@Autowired
|
||||
private ShopDistributionUserCommissionService shopDistributionUserCommissionService;
|
||||
@Autowired
|
||||
private AccountBaseConfigService accountBaseConfigService;
|
||||
@ -182,8 +188,6 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取能自动确认收货的订单号
|
||||
*
|
||||
@ -437,7 +441,7 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
|
||||
Integer times = orderInfo.getOrder_picked_notice_count() == null ? 0 : orderInfo.getOrder_picked_notice_count();
|
||||
if (times > 3) {
|
||||
return CommonResult.success("已提交,请勿重复提交");
|
||||
return CommonResult.success("已通知配送人员,请稍候");
|
||||
}
|
||||
|
||||
// 更新订单拣货时间
|
||||
@ -502,7 +506,7 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
updateWrapper.eq("order_id", orderId)
|
||||
.ne("order_is_received", CommonConstant.Enable);
|
||||
updateWrapper.set("order_is_received", CommonConstant.Enable)
|
||||
.set("order_deal_time", System.currentTimeMillis());
|
||||
.set("order_deal_time", System.currentTimeMillis()); // 确认收货时间戳
|
||||
|
||||
boolean result = update(updateWrapper);
|
||||
if (result) {
|
||||
@ -789,7 +793,7 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
@Override
|
||||
public List<String> getAutoCancelOrderIdByPage(Integer pageNum, Integer pageSize) {
|
||||
QueryWrapper<ShopOrderInfo> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.select("order_id","order_state_id");
|
||||
queryWrapper.select("order_id", "order_state_id");
|
||||
queryWrapper.eq("order_state_id", StateCode.ORDER_STATE_WAIT_PAY)
|
||||
.eq("order_is_paid", StateCode.ORDER_PAID_STATE_NO)
|
||||
.eq("payment_type_id", StateCode.PAYMENT_TYPE_ONLINE);
|
||||
@ -798,7 +802,7 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
int second = NumberUtil.mul(order_autocancel_time, 60, 60).intValue();
|
||||
long time = DateUtil.offsetSecond(new Date(), -second).getTime();
|
||||
queryWrapper.lt("order_time", time);
|
||||
List<ShopOrderInfo> shopOrderInfos=this.lists(queryWrapper,pageNum,pageSize).getRecords();
|
||||
List<ShopOrderInfo> shopOrderInfos = this.lists(queryWrapper, pageNum, pageSize).getRecords();
|
||||
return shopOrderInfos.stream().map(ShopOrderInfo::getOrder_id).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@ -816,5 +820,56 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
return this.count(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查订单预约参数是否合法
|
||||
*
|
||||
* @param storeId 店铺ID
|
||||
* @param bookingState 预约配送状态
|
||||
* @param bookingBeginTimeStr 预约开始时间
|
||||
* @param bookingEndTimeStr 预约截止时间
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Pair<Boolean, String> checkBookingOrderArgs(Integer storeId, Integer bookingState, String bookingBeginTimeStr, String bookingEndTimeStr) {
|
||||
if (CheckUtil.isEmpty(storeId) || CheckUtil.isEmpty(bookingState)) {
|
||||
return Pair.of(false, "[预约订单校验] 缺少必要参数");
|
||||
}
|
||||
|
||||
if (!CommonConstant.Order_Booking_State_YY.equals(bookingState)) {
|
||||
return Pair.of(true, "[预约订单校验] 非预订单,跳过验证");
|
||||
}
|
||||
|
||||
if (StrUtil.hasBlank(bookingBeginTimeStr, bookingEndTimeStr)) {
|
||||
return Pair.of(false, "[预约订单校验] 预约时间不能为空");
|
||||
}
|
||||
|
||||
Date bookingBeginTime = DateTimeUtils.tryParseDateTimeToDate(bookingBeginTimeStr);
|
||||
Date bookingEndTime = DateTimeUtils.tryParseDateTimeToDate(bookingEndTimeStr);
|
||||
if (bookingBeginTime == null || bookingBeginTime == null) {
|
||||
return Pair.of(false, "[预约订单校验] 预约时间格式有误");
|
||||
}
|
||||
|
||||
// 验证开始时间是否早于结束时间
|
||||
if (bookingBeginTime.after(bookingEndTime)) {
|
||||
return Pair.of(false, "[预约订单校验] 开始时间不能晚于截止时间");
|
||||
}
|
||||
|
||||
// 判断预约订单开始时间是否在店铺的营业时间段里?
|
||||
ShopStoreInfo shopStoreInfo = shopStoreInfoService.getShopStoreInfoByStoreId(storeId);
|
||||
if (shopStoreInfo == null) {
|
||||
return Pair.of(false, "[预约订单校验] 店铺信息有误");
|
||||
}
|
||||
|
||||
if (StrUtil.isBlank(shopStoreInfo.getStore_opening_hours()) || StrUtil.isBlank(shopStoreInfo.getStore_close_hours())) {
|
||||
return Pair.of(false, "[预约订单校验] 店铺营业时间未设置");
|
||||
}
|
||||
|
||||
if (!DateTimeUtils.isTimeInRange(shopStoreInfo.getStore_opening_hours(), shopStoreInfo.getStore_close_hours(), bookingBeginTime)) {
|
||||
return Pair.of(false, "[预约订单校验] 预约时间不在店铺营业时间内");
|
||||
}
|
||||
|
||||
return Pair.of(true, "[预约订单校验] 成功");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -519,11 +519,11 @@ public class ShopOrderLklServiceImpl extends BaseServiceImpl<ShopOrderLklMapper,
|
||||
*
|
||||
* @param lklReceiveLogNo 拉卡拉确认收货对账单流水号
|
||||
* @param separateStatus 分账状态:1-已分账;2-未分账;3-分账已失败;
|
||||
* @param separateRemark 分账问题备注;
|
||||
* @param separateMsg 分账问题备注;
|
||||
* @return 更新结果 true-成功 false-失败
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateSeparateStatusByReceiveLogNo(String lklReceiveLogNo, Integer separateStatus, String separateRemark) {
|
||||
public Boolean updateSeparateStatusByReceiveLogNo(String lklReceiveLogNo, Integer separateStatus, String separateMsg) {
|
||||
// 检查参数是否全部为空
|
||||
if (StringUtils.isBlank(lklReceiveLogNo) || separateStatus == null) {
|
||||
log.warn("[更新分账状态] 参数校验失败:缺少必要参数, lklReceiveLogNo={}, separateStatus={}", lklReceiveLogNo, separateStatus);
|
||||
@ -536,8 +536,8 @@ public class ShopOrderLklServiceImpl extends BaseServiceImpl<ShopOrderLklMapper,
|
||||
UpdateWrapper<ShopOrderLkl> updateWrapper = new UpdateWrapper<>();
|
||||
updateWrapper.eq("lkl_receive_log_no", lklReceiveLogNo);
|
||||
updateWrapper.set("separate_status", separateStatus);
|
||||
if (StrUtil.isNotBlank(separateRemark)) {
|
||||
updateWrapper.set("separate_remark", separateRemark);
|
||||
if (StrUtil.isNotBlank(separateMsg)) {
|
||||
updateWrapper.set("separate_msg", separateMsg);
|
||||
}
|
||||
|
||||
boolean result = update(updateWrapper);
|
||||
|
||||
@ -43,6 +43,7 @@ import com.suisung.mall.shop.base.service.ShopBaseStateCodeService;
|
||||
import com.suisung.mall.shop.distribution.service.ShopDistributionUserCommissionService;
|
||||
import com.suisung.mall.shop.distribution.service.ShopDistributionUserOrderItemService;
|
||||
import com.suisung.mall.shop.distribution.service.ShopDistributionUserOrderService;
|
||||
import com.suisung.mall.shop.lakala.service.LklOrderDrawService;
|
||||
import com.suisung.mall.shop.lakala.service.LklOrderSeparateService;
|
||||
import com.suisung.mall.shop.message.service.PushMessageService;
|
||||
import com.suisung.mall.shop.number.service.ShopNumberSeqService;
|
||||
@ -196,7 +197,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private ShopOrderLklService shopOrderLklService;
|
||||
private LklOrderDrawService lklOrderDrawService;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
@ -553,6 +554,9 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
if (is_denyreturn) {
|
||||
// 获取更详细的拒绝退货原因
|
||||
String denyReason = getDenyReturnReason(shopOrderInfo, shopOrderItem, shopProductIndex);
|
||||
if (StrUtil.isBlank(denyReason)) {
|
||||
denyReason = "此商品不允许退货!";
|
||||
}
|
||||
throw new ApiException(denyReason);
|
||||
}
|
||||
|
||||
@ -1513,10 +1517,10 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
|
||||
// RMK 第三方数据同步相关:redis 新增返还思迅库存
|
||||
Map<String, Integer> stockDeltaMap = new HashMap<>();
|
||||
String item_src_id= productItem.getItem_src_id();
|
||||
String item_src_id = productItem.getItem_src_id();
|
||||
stockDeltaMap.put(item_src_id + "-" + shopOrderItem.getOrder_id(), returnNum);
|
||||
syncThirdDataService.incrProductStockToRedis(stockDeltaMap);
|
||||
logger.info("退货返回给思迅,存入redis成功,item_src_id:{},订单号:{},数量:{}",item_src_id,shopOrderReturn.getOrder_id(),returnNum);
|
||||
logger.info("退货返回给思迅,存入redis成功,item_src_id:{},订单号:{},数量:{}", item_src_id, shopOrderReturn.getOrder_id(), returnNum);
|
||||
} else {
|
||||
logger.warn("退货数量为空,无法增加库存,订单项ID: {}", orderItemId);
|
||||
}
|
||||
@ -1602,12 +1606,8 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
// 当前订单状态
|
||||
Integer order_state_id = info_row.getOrder_state_id();
|
||||
|
||||
// 没有发货没有完成订单之前,允许取消订单和退运费(这个存在争议)
|
||||
List<Integer> forbiddenStates = Arrays.asList(
|
||||
StateCode.ORDER_STATE_SHIPPED,
|
||||
StateCode.ORDER_STATE_RECEIVED,
|
||||
StateCode.ORDER_STATE_FINISH);
|
||||
if (order_state_id != null && !forbiddenStates.contains(order_state_id)) {
|
||||
// 订单不是禁止退货(能退货)的情况下
|
||||
if (order_state_id != null && !isOrderDenyReturn(order_id)) {
|
||||
logger.info("处理运费和打包费事宜:{}", order_id);
|
||||
ShopOrderData order_data_row = shopOrderDataService.get(order_id);
|
||||
|
||||
@ -2098,56 +2098,203 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
}
|
||||
|
||||
/**
|
||||
* 该函数用于判断某个订单商品是否禁止退货。
|
||||
* 该函数用于判断订单某个商品是否禁止退货。(判断订单的商品)
|
||||
* 参数校验:检查订单商品和商品信息是否为空,若为空则抛出异常。
|
||||
* 商品是否禁止退货:从商品信息中获取消费者保障类型,如果包含"禁止退货",则标记为不可退货。
|
||||
* 订单状态是否超过退货期限:
|
||||
* 如果订单状态为"已收货"或"已完成",并且当前时间超过允许提现时间,则标记为不可退货。
|
||||
*
|
||||
* @param shopOrderInfo
|
||||
* @param shopOrderItem
|
||||
* @param shopProductIndex
|
||||
* @return
|
||||
* @param shopOrderInfo 订单信息
|
||||
* @param shopOrderItem 订单商品项
|
||||
* @param shopProductIndex 商品索引信息
|
||||
* @return boolean true表示禁止退货,false表示允许退货
|
||||
*/
|
||||
public boolean ifDenyReturn(ShopOrderInfo shopOrderInfo, ShopOrderItem shopOrderItem, ShopProductIndex shopProductIndex) {
|
||||
// 默认允许退货
|
||||
boolean is_denyreturn = false;
|
||||
|
||||
// 1. 参数校验
|
||||
if (shopOrderItem == null) {
|
||||
throw new ApiException(I18nUtil._("此订单商品订单数据有误!"));
|
||||
log.debug("[是否禁止退货] 订单商品数据为空 true");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (shopProductIndex == null) {
|
||||
shopProductIndex = shopProductIndexService.get(shopOrderItem.getProduct_id());
|
||||
if (shopOrderInfo == null) {
|
||||
log.debug("[是否禁止退货] 订单信息为空 true");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (shopProductIndex == null) {
|
||||
throw new ApiException(I18nUtil._("此订单商品数据有误!"));
|
||||
String orderId = shopOrderInfo.getOrder_id();
|
||||
Integer orderStateId = shopOrderInfo.getOrder_state_id();
|
||||
if (StrUtil.isBlank(orderId) || CheckUtil.isEmpty(orderStateId)) {
|
||||
log.debug("[是否禁止退货] 订单ID或订单状态为空 true");
|
||||
return true;
|
||||
}
|
||||
|
||||
List<Integer> contractTypeIds = Convert.toList(Integer.class, shopProductIndex.getContract_type_ids());
|
||||
|
||||
//start判断是否可以申请退款
|
||||
// 1、商品是否允许
|
||||
if (contractTypeIds.contains(new Integer(StateCode.CONTRACT_TYPE_DENY_RETURN))) {
|
||||
is_denyreturn = true;
|
||||
throw new ApiException(I18nUtil._("此商品不允许退货!"));
|
||||
if (orderStateId.intValue() == StateCode.ORDER_STATE_CANCEL ||
|
||||
orderStateId.intValue() == StateCode.ORDER_STATE_WAIT_PAY) {
|
||||
log.debug("[是否禁止退货] 订单已取消或未支付,true order_id: {}", orderId);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 2、是否已经可结算, 进入可结算,不允许退货。
|
||||
if (shopOrderInfo.getOrder_state_id().intValue() == StateCode.ORDER_STATE_RECEIVED || shopOrderInfo.getOrder_state_id().intValue() == StateCode.ORDER_STATE_FINISH) {
|
||||
Long withdrawTime = shopOrderBaseService.getWithdrawTime();
|
||||
// 2. 先判断整个订单是否可以退货(订单级别检查)
|
||||
// 2.1 检查订单状态是否为已收货或已完成
|
||||
if (orderStateId.intValue() == StateCode.ORDER_STATE_RECEIVED ||
|
||||
orderStateId.intValue() == StateCode.ORDER_STATE_FINISH) {
|
||||
try {
|
||||
// 获取可提现时间戳
|
||||
Long withdrawTime = shopOrderBaseService.getWithdrawTime();
|
||||
Long orderDealTime = shopOrderInfo.getOrder_deal_time();
|
||||
|
||||
//order_qs_time
|
||||
if (withdrawTime.compareTo(shopOrderInfo.getOrder_deal_time()) > 0) {
|
||||
is_denyreturn = true;
|
||||
throw new ApiException(I18nUtil._("此商品已过退货期,不允许退货!"));
|
||||
// 检查是否超过退货期限
|
||||
if (orderDealTime != null && withdrawTime.compareTo(orderDealTime) > 0) {
|
||||
log.debug("[是否禁止退货] 订单已超过退货期限 true,order_id: {}", orderId);
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("[是否禁止退货] 检查订单退货期限时发生异常 true,order_id: {}", orderId, e);
|
||||
}
|
||||
}
|
||||
|
||||
return is_denyreturn;
|
||||
// 2.2 检查拉卡拉分账订单是否已提现
|
||||
try {
|
||||
if (lklOrderSeparateService != null && lklOrderDrawService != null) {
|
||||
boolean isSeparated = lklOrderSeparateService.isOrderSeparated(orderId);
|
||||
boolean isDrawn = lklOrderDrawService.isOrderDrawed(orderId);
|
||||
|
||||
if (isSeparated && isDrawn) {
|
||||
log.debug("[是否禁止退货] 拉卡拉分账订单已提现,不允许退货 true,order_id: {}", orderId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("[是否禁止退货] 检查拉卡拉分账状态时发生异常,order_id: {}", orderId, e);
|
||||
}
|
||||
|
||||
Long productId = shopOrderItem.getProduct_id();
|
||||
if (CheckUtil.isEmpty(productId)) {
|
||||
log.debug("[是否禁止退货] 商品ID为空 true");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 3. 再判断具体商品是否可以退货(商品级别检查)
|
||||
// 获取商品索引信息
|
||||
ShopProductIndex productIndex = shopProductIndex;
|
||||
if (productIndex == null) {
|
||||
productIndex = shopProductIndexService.get(productId);
|
||||
}
|
||||
|
||||
if (productIndex == null) {
|
||||
log.debug("[是否禁止退货] 商品索引信息不存在 true,product_id: {}", productId);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 3.1 检查商品是否设置了禁止退货标识
|
||||
String contractTypeIdsStr = productIndex.getContract_type_ids();
|
||||
if (StrUtil.isNotBlank(contractTypeIdsStr)) {
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("[是否禁止退货] 解析商品保障类型失败 true,order_id: {}, product_id: {}", orderId, productId, e);
|
||||
}
|
||||
}
|
||||
|
||||
// 默认允许退货
|
||||
log.debug("[是否禁止退货] false}");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断订单中某个商品是否禁止退货
|
||||
* <p>
|
||||
* 该方法用于检查指定订单中的特定商品是否允许退货,主要检查以下几种情况:
|
||||
* 1. 商品是否设置了"禁止退货"的消费者保障标识
|
||||
* 2. 订单是否已超过退货期限(已收货或已完成状态,且超过可提现时间)
|
||||
* 3. 拉卡拉分账订单是否已完成提现
|
||||
*
|
||||
* @param orderId 订单ID
|
||||
* @param productId 商品ID
|
||||
* @return boolean true表示禁止退货,false表示允许退货
|
||||
*/
|
||||
public boolean ifOrderItemDenyReturn(String orderId, Long productId) {
|
||||
// 复用已有的方法逻辑,避免重复代码
|
||||
return ifDenyReturn(
|
||||
shopOrderInfoService.get(orderId),
|
||||
null, // 不需要具体的订单商品项信息
|
||||
shopProductIndexService.get(productId)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断订单是否禁止退货
|
||||
*
|
||||
* @param orderId 订单ID
|
||||
* @return 如果订单禁止退货返回true,否则返回false
|
||||
*/
|
||||
@Override
|
||||
public boolean isOrderDenyReturn(String orderId) {
|
||||
// 参数校验
|
||||
if (StrUtil.isBlank(orderId)) {
|
||||
log.warn("[订单是否禁止退货] 订单ID为空,无法判断退货状态");
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
// 获取订单信息
|
||||
ShopOrderInfo shopOrderInfo = shopOrderInfoService.get(orderId);
|
||||
if (shopOrderInfo == null) {
|
||||
log.error("[订单是否禁止退货] 订单信息不存在,订单ID: {}", orderId);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 检查订单状态是否已收货或已完成
|
||||
Integer orderStateId = shopOrderInfo.getOrder_state_id();
|
||||
if (CheckUtil.isEmpty(orderStateId)) {
|
||||
log.warn("[订单是否禁止退货] 订单状态为空");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (orderStateId.intValue() == StateCode.ORDER_STATE_CANCEL ||
|
||||
orderStateId.intValue() == StateCode.ORDER_STATE_WAIT_PAY) {
|
||||
log.debug("[是否禁止退货] 订单已取消或未支付,order_id: {}", orderId);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (orderStateId.intValue() == StateCode.ORDER_STATE_RECEIVED ||
|
||||
orderStateId.intValue() == StateCode.ORDER_STATE_FINISH) {
|
||||
|
||||
// 获取可提现时间戳
|
||||
Long withdrawTime = shopOrderBaseService.getWithdrawTime();
|
||||
Long orderDealTime = shopOrderInfo.getOrder_deal_time();
|
||||
log.debug("[订单是否禁止退货] 订单:{} 可提现时间戳: {},确认收货时间:{}", orderId, withdrawTime, orderDealTime);
|
||||
|
||||
// 如果订单成交时间早于可提现时间,说明已过退货期
|
||||
if (orderDealTime != null && withdrawTime.compareTo(orderDealTime) > 0) {
|
||||
log.debug("[订单是否禁止退货] 订单:{} 已过退货期,不允许退货", orderId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查拉卡拉分账和提现状态
|
||||
if (lklOrderSeparateService.isOrderSeparated(orderId) &&
|
||||
lklOrderDrawService.isOrderDrawed(orderId)) {
|
||||
log.debug("[订单是否禁止退货] 订单[{}]已提现,不允许退货", orderId);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 默认允许退货
|
||||
return false;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("[订单是否禁止退货] 查询订单{}退货状态异常", orderId, e);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 该函数用于判断指定订单商品是否禁止退货。
|
||||
* 根据 order_item_id 获取订单商品信息;
|
||||
@ -2210,7 +2357,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
}
|
||||
|
||||
if (StrUtil.isBlank(remark)) {
|
||||
remark = "整单退!";
|
||||
remark = "整单退款";
|
||||
}
|
||||
|
||||
// 判断此订单商品是否已有退款单。
|
||||
@ -2291,7 +2438,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
}
|
||||
|
||||
if (StrUtil.isBlank(remark)) {
|
||||
remark = "剩余商品退款!";
|
||||
remark = "整单退款!";
|
||||
}
|
||||
|
||||
// 获取订单中所有商品
|
||||
@ -2561,12 +2708,14 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
}
|
||||
|
||||
if (lklOrderSeparateService.isOrderSeparated(orderId)) {
|
||||
// TODO 后期如果已经分账的订单,一定强硬退款,可能需要拉卡拉撤销分账,再退款
|
||||
// TODO 后期如果已经分账的订单,一定强硬退款,可能需要拉卡拉撤销分账,再退款,已提现的,真的没有办法退款了
|
||||
return CommonResult.failed("订单已三方结清,无法退款");
|
||||
}
|
||||
|
||||
List<ShopOrderItem> orderItems = shopOrderItemService.find(new QueryWrapper<ShopOrderItem>().eq("order_id", orderId));
|
||||
if (CollectionUtil.isEmpty(orderItems)) return CommonResult.failed("无可退货商品");
|
||||
if (CollectionUtil.isEmpty(orderItems)) {
|
||||
return CommonResult.failed("无可退货商品");
|
||||
}
|
||||
|
||||
// === 3. 检查退货单 ===
|
||||
ShopOrderReturn refundOrder = findOne(new QueryWrapper<ShopOrderReturn>()
|
||||
@ -2723,9 +2872,10 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
|
||||
// 2、是否已经超过退货期
|
||||
if (shopOrderInfo.getOrder_state_id().intValue() == StateCode.ORDER_STATE_RECEIVED || shopOrderInfo.getOrder_state_id().intValue() == StateCode.ORDER_STATE_FINISH) {
|
||||
// 可提现时间
|
||||
Long withdrawTime = shopOrderBaseService.getWithdrawTime();
|
||||
|
||||
//order_qs_time
|
||||
//order_deal_time 当前状态的处理时间
|
||||
if (withdrawTime.compareTo(shopOrderInfo.getOrder_deal_time()) > 0) {
|
||||
return "订单已超过退货期限,无法退货";
|
||||
}
|
||||
|
||||
@ -26,10 +26,8 @@ import com.suisung.mall.common.modules.store.ShopStoreSameCityTransportBase;
|
||||
import com.suisung.mall.common.modules.store.ShopStoreSfOrder;
|
||||
import com.suisung.mall.common.pojo.req.*;
|
||||
import com.suisung.mall.common.pojo.res.ThirdApiRes;
|
||||
import com.suisung.mall.common.utils.CheckUtil;
|
||||
import com.suisung.mall.common.utils.CommonUtil;
|
||||
import com.suisung.mall.common.utils.I18nUtil;
|
||||
import com.suisung.mall.common.utils.JsonUtil;
|
||||
import com.suisung.mall.common.pojo.to.AddressParseResultTO;
|
||||
import com.suisung.mall.common.utils.*;
|
||||
import com.suisung.mall.shop.message.service.PushMessageService;
|
||||
import com.suisung.mall.shop.order.service.ShopOrderBaseService;
|
||||
import com.suisung.mall.shop.order.service.ShopOrderInfoService;
|
||||
@ -172,15 +170,23 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
return Pair.of(false, "联系人手机号不能为空");
|
||||
}
|
||||
|
||||
|
||||
AddressParseResultTO addressParseResultTO = AddressUtil.parseAddress(shopMchEntry.getStore_address());
|
||||
// 解析城市名称
|
||||
String cityName = "桂平市"; // 默认城市
|
||||
|
||||
// 去掉省市区的详细地址
|
||||
String storeAddress = addressParseResultTO.getDetailAddress();
|
||||
|
||||
if (StrUtil.isNotBlank(shopMchEntry.getStore_area())) {
|
||||
String[] areaNames = shopMchEntry.getStore_area().split("/");
|
||||
if (areaNames.length > 0) {
|
||||
if (areaNames.length >= 3) {
|
||||
cityName = areaNames[areaNames.length - 1];
|
||||
} else {
|
||||
cityName = shopMchEntry.getStore_area().replace("/", "");
|
||||
}
|
||||
} else {
|
||||
cityName = addressParseResultTO.getCity();
|
||||
}
|
||||
|
||||
// 如果解析后城市名为空,使用默认值
|
||||
@ -199,7 +205,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
Convert.toInt(shopMchEntry.getStore_id()),
|
||||
shopStoreName,
|
||||
cityName,
|
||||
shopMchEntry.getStore_address(),
|
||||
storeAddress,
|
||||
shopMchEntry.getContact_name(),
|
||||
contactMobile,
|
||||
shopMchEntry.getStore_longitude(),
|
||||
@ -1040,7 +1046,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
pushRemark = "已完成配送";
|
||||
orderStatus = StateCode.ORDER_STATE_RECEIVED; //已签收
|
||||
|
||||
// 通知微信用户确认收货(同城配送不能调用微信的确认收货)
|
||||
// 顺丰送达后,发出催促微信用户确认收货通知 (同城配送不能调用微信的确认收货)
|
||||
wxOrderShippingService.notifyConfirmReceive(shopStoreSfOrder.getShop_order_id());
|
||||
|
||||
// 不要提前 订单确认收货,等微信拉卡拉确认通知
|
||||
@ -1136,13 +1142,14 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
throw new ApiException(I18nUtil._("状态处理失败!"));
|
||||
}
|
||||
|
||||
// 通知微信用户确认收货(同城配送不能调用该微信接口)
|
||||
// wxOrderShippingService.notifyConfirmReceive(shopStoreSfOrder.getShop_order_id());
|
||||
String orderId = shopStoreSfOrder.getShop_order_id();
|
||||
|
||||
// 顺丰送达后,发出催促微信用户确认收货通知 (同城配送不能调用微信的确认收货)
|
||||
wxOrderShippingService.notifyConfirmReceive(orderId);
|
||||
|
||||
// 订单确认收货
|
||||
// shopOrderBaseService.receive(shopStoreSfOrder.getShop_order_id(), null);
|
||||
|
||||
String orderId = shopStoreSfOrder.getShop_order_id();
|
||||
|
||||
// 消息推送
|
||||
// JSONObject payload = new JSONObject();
|
||||
@ -1150,7 +1157,6 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
// payload.put("orderId", orderId);
|
||||
// pushMessageService.noticeMerchantEmployeeOrderAction(null, orderId, "", "顺丰同城订单[" + orderId + "]已完成配送。", null);
|
||||
|
||||
|
||||
return new ThirdApiRes().success("success");
|
||||
}
|
||||
|
||||
|
||||
@ -20,6 +20,14 @@ public interface ShopStoreInfoService extends IBaseService<ShopStoreInfo> {
|
||||
|
||||
Map getStoreInfoById(Integer store_id);
|
||||
|
||||
/**
|
||||
* 根据店铺id获取店铺信息
|
||||
*
|
||||
* @param storeId
|
||||
* @return
|
||||
*/
|
||||
ShopStoreInfo getShopStoreInfoByStoreId(Integer storeId);
|
||||
|
||||
Map getInfoList(QueryWrapper<ShopStoreInfo> queryWrapper, Integer pageNum, Integer pageSize);
|
||||
|
||||
/**
|
||||
|
||||
@ -80,7 +80,6 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
@ -176,9 +175,6 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
|
||||
@Autowired
|
||||
private ShopPageModuleService shopPageModuleService;
|
||||
@Lazy
|
||||
@Resource
|
||||
private ShopStoreSameCityTransportBaseService storeSameCityTransportBaseService;
|
||||
@Lazy
|
||||
@Autowired
|
||||
private ShopMchEntryService shopMchEntryService;
|
||||
@Autowired
|
||||
@ -3277,54 +3273,58 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
|
||||
return Pair.of(0, "店铺ID获取失败");
|
||||
}
|
||||
|
||||
// 创建店铺信息
|
||||
ShopStoreInfo shopStoreInfo = new ShopStoreInfo();
|
||||
shopStoreInfo.setStore_id(storeId);
|
||||
shopStoreInfo.setStore_start_time(DateUtil.date());
|
||||
shopStoreInfo.setStore_end_time(DateUtil.offsetDay(DateUtil.date(), 365 * 5));
|
||||
shopStoreInfo.setStore_opening_hours("07:30");
|
||||
shopStoreInfo.setStore_close_hours("23:00");
|
||||
shopStoreInfo.setStore_discount(BigDecimal.valueOf(10));
|
||||
shopStoreInfo.setStore_banner(storeFacadeImage);
|
||||
|
||||
// 处理联系人信息
|
||||
String contact_mobile = StrUtil.isNotBlank(shopMchEntry.getLegal_person_mobile()) ?
|
||||
shopMchEntry.getLegal_person_mobile() : shopMchEntry.getLogin_mobile();
|
||||
shopStoreInfo.setStore_tel(contact_mobile);
|
||||
shopStoreInfo.setContact_mobile(contact_mobile);
|
||||
shopStoreInfo.setContact_name(shopMchEntry.getContact_name());
|
||||
|
||||
// 构建幻灯片
|
||||
JSONArray list = new JSONArray();
|
||||
if (StrUtil.isNotBlank(storeFacadeImage)) {
|
||||
JSONObject slide = new JSONObject();
|
||||
slide.put("img", storeFacadeImage);
|
||||
slide.put("name", "店铺门面照片");
|
||||
slide.put("check", true);
|
||||
slide.put("url", "https://www.gpxscs.cn");
|
||||
list.put(slide);
|
||||
}
|
||||
if (StrUtil.isNotBlank(shopMchEntry.getEnvironment_image())) {
|
||||
JSONObject slide = new JSONObject();
|
||||
slide.put("img", shopMchEntry.getEnvironment_image());
|
||||
slide.put("name", "店铺环境照片");
|
||||
slide.put("check", true);
|
||||
slide.put("url", "https://www.gpxscs.cn");
|
||||
list.put(slide);
|
||||
}
|
||||
shopStoreInfo.setStore_slide(list.toString());
|
||||
// 创建店铺信息
|
||||
ShopStoreInfo shopStoreInfo = shopStoreInfoService.getShopStoreInfoByStoreId(storeId); // new ShopStoreInfo();
|
||||
if (shopStoreInfo == null) {
|
||||
shopStoreInfo = new ShopStoreInfo();
|
||||
shopStoreInfo.setStore_id(storeId);
|
||||
shopStoreInfo.setStore_start_time(DateUtil.date());
|
||||
shopStoreInfo.setStore_end_time(DateUtil.offsetDay(DateUtil.date(), 365 * 5));
|
||||
shopStoreInfo.setStore_opening_hours("08:00");
|
||||
shopStoreInfo.setStore_close_hours("21:30");
|
||||
shopStoreInfo.setStore_discount(BigDecimal.valueOf(10));
|
||||
shopStoreInfo.setStore_banner(storeFacadeImage);
|
||||
|
||||
shopStoreInfo.setStore_tel(contact_mobile);
|
||||
shopStoreInfo.setContact_mobile(contact_mobile);
|
||||
shopStoreInfo.setContact_name(shopMchEntry.getContact_name());
|
||||
|
||||
if (shopMchEntry.getStore_address() != null) {
|
||||
shopStoreInfo.setStore_address(shopMchEntry.getStore_address());
|
||||
}
|
||||
shopStoreInfo.setStore_state_id(StateCode.STORE_STATE_YES);
|
||||
|
||||
if (!shopStoreInfoService.save(shopStoreInfo)) {
|
||||
logger.error("生成店铺:新增店铺info失败");
|
||||
if (Boolean.TRUE.equals(allowThrown)) {
|
||||
throw new ApiException("新增店铺信息失败");
|
||||
// 构建幻灯片
|
||||
JSONArray list = new JSONArray();
|
||||
if (StrUtil.isNotBlank(storeFacadeImage)) {
|
||||
JSONObject slide = new JSONObject();
|
||||
slide.put("img", storeFacadeImage);
|
||||
slide.put("name", "店铺门面照片");
|
||||
slide.put("check", true);
|
||||
slide.put("url", "https://www.gpxscs.cn");
|
||||
list.put(slide);
|
||||
}
|
||||
if (StrUtil.isNotBlank(shopMchEntry.getEnvironment_image())) {
|
||||
JSONObject slide = new JSONObject();
|
||||
slide.put("img", shopMchEntry.getEnvironment_image());
|
||||
slide.put("name", "店铺环境照片");
|
||||
slide.put("check", true);
|
||||
slide.put("url", "https://www.gpxscs.cn");
|
||||
list.put(slide);
|
||||
}
|
||||
shopStoreInfo.setStore_slide(list.toString());
|
||||
|
||||
if (shopMchEntry.getStore_address() != null) {
|
||||
shopStoreInfo.setStore_address(shopMchEntry.getStore_address());
|
||||
}
|
||||
shopStoreInfo.setStore_state_id(StateCode.STORE_STATE_YES);
|
||||
|
||||
if (!shopStoreInfoService.save(shopStoreInfo)) {
|
||||
logger.error("生成店铺:新增店铺info失败");
|
||||
if (Boolean.TRUE.equals(allowThrown)) {
|
||||
throw new ApiException("新增店铺信息失败");
|
||||
}
|
||||
return Pair.of(0, "新增店铺信息失败");
|
||||
}
|
||||
return Pair.of(0, "新增店铺信息失败");
|
||||
}
|
||||
|
||||
// 创建店铺公司信息
|
||||
@ -3887,14 +3887,14 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
|
||||
bizState = CommonConstant.Disable2;
|
||||
}
|
||||
|
||||
String store_opening_hours=getParameter("store_opening_hours");
|
||||
String store_close_hours=getParameter("store_close_hours");
|
||||
String store_opening_hours = getParameter("store_opening_hours");
|
||||
String store_close_hours = getParameter("store_close_hours");
|
||||
try {
|
||||
if(StringUtils.isNotEmpty(store_close_hours)){
|
||||
UpdateWrapper<ShopStoreInfo> shopStoreInfoUpdateWrapper=new UpdateWrapper<>();
|
||||
shopStoreInfoUpdateWrapper.eq("store_id",storeId);
|
||||
shopStoreInfoUpdateWrapper.set("store_opening_hours",store_opening_hours);
|
||||
shopStoreInfoUpdateWrapper.set("store_close_hours",store_close_hours);
|
||||
if (StringUtils.isNotEmpty(store_close_hours)) {
|
||||
UpdateWrapper<ShopStoreInfo> shopStoreInfoUpdateWrapper = new UpdateWrapper<>();
|
||||
shopStoreInfoUpdateWrapper.eq("store_id", storeId);
|
||||
shopStoreInfoUpdateWrapper.set("store_opening_hours", store_opening_hours);
|
||||
shopStoreInfoUpdateWrapper.set("store_close_hours", store_close_hours);
|
||||
shopStoreInfoService.update(shopStoreInfoUpdateWrapper);
|
||||
}
|
||||
// 使用 UpdateWrapper 更新店铺营业状态
|
||||
|
||||
@ -53,6 +53,13 @@ public class ShopStoreInfoServiceImpl extends BaseServiceImpl<ShopStoreInfoMappe
|
||||
return shopStoreInfoMapper.getStoreInfoById(store_id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShopStoreInfo getShopStoreInfoByStoreId(Integer storeId) {
|
||||
QueryWrapper<ShopStoreInfo> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("store_id", storeId);
|
||||
return findOne(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map getInfoList(QueryWrapper<ShopStoreInfo> queryWrapper, Integer pageNum, Integer pageSize) {
|
||||
Page<ShopStoreInfo> lists = lists(queryWrapper, pageNum, pageSize);
|
||||
|
||||
@ -128,21 +128,17 @@ public class WxOrderShippingServiceImpl implements WxOrderShippingService {
|
||||
|
||||
// Step 4: Prepare request payload
|
||||
JSONArray shippingList = new JSONArray().put(shippingItem);
|
||||
// String mchId = orderBaseInfo.getMch_id();
|
||||
|
||||
JSONObject paramsJSON = new JSONObject()
|
||||
.set("order_key", new JSONObject().set("order_number_type", 2).set("transaction_id", orderBaseInfo.getTransaction_id()))
|
||||
// .set("order_key", new JSONObject().set("order_number_type", 1).set("out_trade_no", orderBaseInfo.getOut_trade_no()).set("mchid", mchId))
|
||||
.set("delivery_mode", 1)
|
||||
.set("logistics_type", logisticsType)
|
||||
.set("shipping_list", shippingList)
|
||||
.set("upload_time", DateTimeUtils.formatDateTimeRFC3339(new Date()))
|
||||
.set("payer", new JSONObject().set("openid", orderBaseInfo.getOpen_id()));
|
||||
|
||||
|
||||
// Step 5: Send request to WeChat API
|
||||
String postUrl = "https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token=" + accessToken;
|
||||
log.debug("发货信息录入请求: {} \n {}", postUrl, paramsJSON);
|
||||
log.debug("发货信息录入请求: {} \n 响应数据 {}", postUrl, paramsJSON);
|
||||
|
||||
JSONObject respObj = RestTemplateHttpUtil.sendPost(
|
||||
postUrl,
|
||||
@ -161,7 +157,7 @@ public class WxOrderShippingServiceImpl implements WxOrderShippingService {
|
||||
return Pair.of(false, "发货信息录入失败: " + errorMsg);
|
||||
}
|
||||
|
||||
// 跳转链接设置
|
||||
// 服务号发货通知跳转链接设置
|
||||
setMsgJumpPath(orderId);
|
||||
|
||||
log.info("发货信息录入成功, 订单ID: {}", orderId);
|
||||
@ -235,9 +231,9 @@ public class WxOrderShippingServiceImpl implements WxOrderShippingService {
|
||||
return Pair.of(false, "通知微信用户确认收货失败: " + errorMsg);
|
||||
}
|
||||
|
||||
// 跳转链接设置
|
||||
/// 服务号催促确认收货通知跳转链接设置
|
||||
setMsgJumpPath(orderId);
|
||||
|
||||
|
||||
log.info("通知微信用户确认收货成功, 订单ID: {}", orderId);
|
||||
return Pair.of(true, "通知微信用户确认收货成功");
|
||||
|
||||
|
||||
@ -655,6 +655,7 @@
|
||||
<!--refundstatus 退款状态:0-是无退款;1-是部分退款;2-是全部退款
|
||||
orderstatus 订单状态:2010-待付款;2011-待订单审核;2012-待发货;2013-待财务审核;2014-待配货/待出库审核;2020-待发货;
|
||||
2030-待发货/待收货确认;2040-已发货/待收货确认;2050-已签收;2060-已完成/已签收;2070-已取消/已作废;2080-自提-->
|
||||
<!-- status: 同城配送订单状态(delivery=1时才生效):无值 or 0-全部订单;1-进行中订单;2-异常(超时)订单;3-退款订单;9-已完成订单-->
|
||||
<!-- 公共的where条件片段 -->
|
||||
<sql id="mchOrderWhereCondition">
|
||||
<where>
|
||||
@ -684,12 +685,12 @@
|
||||
<choose>
|
||||
<!-- 1-进行中订单 -->
|
||||
<when test="status != null and status == 1 and expireSeconds != null and expireSeconds > 0">
|
||||
AND ob.order_state_id IN (2011,2012,2013, 2014, 2020, 2030, 2040)
|
||||
AND ob.order_state_id IN (2011,2012,2013,2014,2020,2030,2040)
|
||||
AND (oi.order_time + #{expireSeconds}*1000) <![CDATA[>=]]> UNIX_TIMESTAMP() * 1000
|
||||
</when>
|
||||
<!-- 2-异常(超时)订单 -->
|
||||
<when test="status != null and status == 2 and expireSeconds != null and expireSeconds > 0">
|
||||
AND ob.order_state_id IN (2011,2012,2013, 2014, 2020, 2030, 2040)
|
||||
AND ob.order_state_id IN (2011,2012,2013,2014,2020,2030,2040)
|
||||
AND (oi.order_time + #{expireSeconds}*1000) <![CDATA[<]]> UNIX_TIMESTAMP() * 1000
|
||||
</when>
|
||||
<!-- 3-退款订单 -->
|
||||
|
||||
@ -11,7 +11,8 @@
|
||||
order_is_received, chain_id, delivery_type_id, order_is_offline, cart_type_id, order_express_print, activity_id,
|
||||
activity_type_id, salesperson_id, order_is_sync, store_is_selfsupport, store_type, order_erp_id,
|
||||
distributor_user_id, order_is_cb, order_is_cb_sync, src_order_id, order_is_transfer, order_is_transfer_note,
|
||||
order_fx_is_settlemented, order_fx_settlement_time, order_pickup_num,order_picked_notice_count,order_picked_time
|
||||
order_fx_is_settlemented, order_fx_settlement_time, order_pickup_num,order_picked_notice_count,order_picked_time,
|
||||
booking_state, booking_begin_time, booking_end_time,created_at, updated_at
|
||||
</sql>
|
||||
|
||||
<!--// refundstatus 退款状态:0-是无退款;1-是部分退款;2-是全部退款
|
||||
|
||||
Loading…
Reference in New Issue
Block a user