商家退款,放开了 条件,已发货之后的订单也能退款了。

This commit is contained in:
Jack 2025-09-20 12:19:45 +08:00
parent 20b90b6c34
commit cf01dcd472
3 changed files with 136 additions and 63 deletions

View File

@ -32,7 +32,6 @@ import java.util.stream.Collectors;
@RestControllerAdvice
public class GlobalExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
private static final String DB_ERROR_MSG = "数据库操作失败,请稍后重试";
/**
* 处理参数校验异常
@ -85,7 +84,6 @@ public class GlobalExceptionHandler {
*/
@ExceptionHandler({NumberFormatException.class, IllegalArgumentException.class})
public CommonResult handleParameterException(Exception e, HttpServletRequest req) {
String errorMessage = e.getMessage();
logError(req, "参数异常", e);
return CommonResult.validateFailed("数据格式输入有误,请检查!");
}
@ -98,7 +96,7 @@ public class GlobalExceptionHandler {
logError(req, e.getMessage(), e);
if (e instanceof SQLException || e instanceof DataAccessException) {
return CommonResult.failed(DB_ERROR_MSG);
return CommonResult.failed("系统数据异常,请联系管理员!");
}
return CommonResult.failed("系统内部异常,请联系管理员!");
}

View File

@ -2706,7 +2706,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
Date threeDaysAgo = DateUtils.addHours(now, -72);
// 分页参数
int pageSize = 100; // 每页处理100条记录
int pageSize = 100;
int currentPage = 1;
int totalSuccessCount = 0;
int totalProcessed = 0;
@ -2738,50 +2738,51 @@ public class LakalaApiServiceImpl implements LakalaApiService {
return Integer.compare(retryCount1, retryCount2);
});
int batchSuccessCount = 0;
// 处理当前页中的记录
for (LklOrderSeparate lklOrderSeparate : lklOrderSeparates) {
for (LklOrderSeparate record : lklOrderSeparates) {
// 检查该记录的处理次数是否已达到上限5次
String redisKey = redisPrefKey + lklOrderSeparate.getSeparate_no();
String redisKey = redisPrefKey + record.getSeparate_no();
int retryCount = Convert.toInt(redisService.get(redisKey), 0);
if (retryCount >= 5) {
log.warn("[分账状态修复任务] 记录已达到最大重试次数,跳过处理: merchantNo={}, separateNo={}",
lklOrderSeparate.getMerchant_no(), lklOrderSeparate.getSeparate_no());
record.getMerchant_no(), record.getSeparate_no());
continue;
}
totalProcessed++;
log.info("[分账状态修复任务] 正在处理第 {} 条记录: merchantNo={}, separateNo={}, 已重试{}次",
totalProcessed, lklOrderSeparate.getMerchant_no(), lklOrderSeparate.getSeparate_no(), retryCount);
// 每处理10条记录才输出一次详细日志减少日志量
if (totalProcessed % 10 == 1) {
log.info("[分账状态修复任务] 正在处理第 {} 条记录: merchantNo={}, separateNo={}, 已重试{}次",
totalProcessed, record.getMerchant_no(), record.getSeparate_no(), retryCount);
}
try {
// 增加处理次数计数
// 增加处理次数计数并设置3天过期时间
redisService.incr(redisKey, 1);
// 设置3天过期时间
redisService.expire(redisKey, 3 * 24 * 60 * 60);
// 调用分账通知回调接口进行状态补偿
JSONObject notifyResp = sacsSeparateNotify(null, lklOrderSeparate.getMerchant_no(), lklOrderSeparate.getSeparate_no());
JSONObject notifyResp = sacsSeparateNotify(null, record.getMerchant_no(), record.getSeparate_no());
// 检查处理结果
if (notifyResp != null && "SUCCESS".equals(notifyResp.getStr("code"))) {
batchSuccessCount++;
totalSuccessCount++;
log.debug("[分账状态修复任务] 记录处理成功: merchantNo={}, separateNo={}",
lklOrderSeparate.getMerchant_no(), lklOrderSeparate.getSeparate_no());
record.getMerchant_no(), record.getSeparate_no());
} else {
String errorMsg = notifyResp != null ? notifyResp.getStr("message") : "未知错误";
log.warn("[分账状态修复任务] 记录处理失败: merchantNo={}, separateNo={}, errorMsg={}",
lklOrderSeparate.getMerchant_no(), lklOrderSeparate.getSeparate_no(), errorMsg);
record.getMerchant_no(), record.getSeparate_no(), errorMsg);
}
} catch (Exception e) {
log.error("[分账状态修复任务] 处理记录时发生异常: merchantNo={}, separateNo={}",
lklOrderSeparate.getMerchant_no(), lklOrderSeparate.getSeparate_no(), e);
record.getMerchant_no(), record.getSeparate_no(), e);
}
}
totalSuccessCount += batchSuccessCount;
log.info("[分账状态修复任务] 第{}页处理完成: 处理了 {} 条记录,成功 {} 条", currentPage, lklOrderSeparates.size(), batchSuccessCount);
log.info("[分账状态修复任务] 第{}页处理完成,已处理 {} 条记录,总成功 {} 条",
currentPage, totalProcessed, totalSuccessCount);
// 如果当前页数据少于页面大小说明已经是最后一页
if (lklOrderSeparates.size() < pageSize) {

View File

@ -528,19 +528,26 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
// 获取订单商品信息
ShopOrderItem shopOrderItem = shopOrderItemService.get(returnItemInputVo.getOrder_item_id());
if (shopOrderItem == null) {
throw new ApiException(I18nUtil._("此订单商品订单数据有误!"));
throw new ApiException("订单商品不存在请检查商品ID是否正确: " + returnItemInputVo.getOrder_item_id());
}
// 验证是否为当前订单的商品
if (!order_id.equals(shopOrderItem.getOrder_id())) {
throw new ApiException("商品ID " + returnItemInputVo.getOrder_item_id() + " 不属于订单 " + order_id);
}
// 获取商品索引信息
ShopProductIndex shopProductIndex = shopProductIndexService.get(shopOrderItem.getProduct_id());
if (shopProductIndex == null) {
throw new ApiException(I18nUtil._("此订单商品数据有误!"));
throw new ApiException("商品信息不存在请检查商品ID是否正确: " + shopOrderItem.getProduct_id());
}
// 检查是否允许退货
boolean is_denyreturn = ifDenyReturn(shopOrderInfo, shopOrderItem, shopProductIndex);
if (is_denyreturn) {
throw new ApiException(I18nUtil._("此商品不允许退货!"));
// 获取更详细的拒绝退货原因
String denyReason = getDenyReturnReason(shopOrderInfo, shopOrderItem, shopProductIndex);
throw new ApiException(denyReason);
}
// 构建退款单明细
@ -548,10 +555,34 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
Integer return_item_num = returnItemInputVo.getReturn_item_num();
if (return_item_num <= 0) {
throw new ApiException(I18nUtil._("退款数量不正确!"));
throw new ApiException("退款数量必须大于0请检查商品 " + shopOrderItem.getItem_name() + " 的退款数量");
}
// 检查退款数量是否超过可退数量
Integer order_item_quantity = shopOrderItem.getOrder_item_quantity();
Integer order_item_return_agree_num = ObjectUtil.defaultIfNull(shopOrderItem.getOrder_item_return_agree_num(), 0);
Integer available_return_num = order_item_quantity - order_item_return_agree_num;
if (return_item_num > available_return_num) {
throw new ApiException(String.format("商品 %s 的退款数量超过可退数量,最多可退 %d 件",
shopOrderItem.getItem_name(), available_return_num));
}
BigDecimal return_refund_amount = returnItemInputVo.getReturn_refund_amount();
// 检查退款金额是否合理
BigDecimal order_item_payment_amount = shopOrderItem.getOrder_item_payment_amount();
BigDecimal order_item_return_agree_amount = ObjectUtil.defaultIfNull(shopOrderItem.getOrder_item_return_agree_amount(), BigDecimal.ZERO);
BigDecimal available_return_amount = order_item_payment_amount.subtract(order_item_return_agree_amount);
if (return_refund_amount.compareTo(BigDecimal.ZERO) <= 0) {
throw new ApiException("退款金额必须大于0请检查商品 " + shopOrderItem.getItem_name() + " 的退款金额");
}
if (return_refund_amount.compareTo(available_return_amount) > 0) {
throw new ApiException(String.format("商品 %s 的退款金额超过可退金额,最多可退 %.2f 元",
shopOrderItem.getItem_name(), available_return_amount));
}
String return_item_image = ObjectUtil.defaultIfBlank(
orderReturnInputVo.getRefund_pic(),
orderReturnInputVo.getUpload_img());
@ -1031,7 +1062,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
ShopOrderItem order_item_row = order_item_rows.stream().filter(s -> s.getOrder_item_id().equals(orderReturnItem.getOrder_item_id())).findFirst().orElse(null);
if (order_item_row == null) {
throw new ApiException(I18nUtil._("订单商品表信息错误!"));
throw new ApiException("订单商品表信息错误!商品ID: " + orderReturnItem.getOrder_item_id() + " 不存在");
}
BigDecimal return_item_subtotal = NumberUtil.round(orderReturnItem.getReturn_item_subtotal(), 6);
@ -1040,7 +1071,8 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
BigDecimal new_order_item_payment_amount = NumberUtil.round(NumberUtil.sub(order_item_payment_amount, order_item_return_agree_amount), 6);
if (return_item_subtotal.compareTo(BigDecimal.ZERO) < 0 || return_item_subtotal.compareTo(new_order_item_payment_amount) > 0) {
throw new ApiException(I18nUtil._("退货单金额错误!"));
throw new ApiException(String.format("退货单金额错误!商品 %s 的退货金额应在 0-%.2f 之间",
order_item_row.getItem_name(), new_order_item_payment_amount));
}
Integer order_item_quantity = order_item_row.getOrder_item_quantity();
@ -1048,7 +1080,8 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
Integer return_item_num = orderReturnItem.getReturn_item_num();
if ((order_item_quantity - order_item_return_agree_num) < return_item_num) {
throw new ApiException(I18nUtil._("退货单商品数量错误!"));
throw new ApiException(String.format("退货单商品数量错误!商品 %s 的退货数量不能超过 %d",
order_item_row.getItem_name(), (order_item_quantity - order_item_return_agree_num)));
}
BigDecimal d_return = CheckUtil.isNotEmpty(orderReturn.getReturn_refund_amount()) ? orderReturn.getReturn_refund_amount() : BigDecimal.ZERO;
@ -2097,9 +2130,9 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
/**
* 该函数用于判断某个订单商品是否禁止退货
* 参数校验检查订单商品和商品信息是否为空若为空则抛出异常
* 商品是否禁止退货从商品信息中获取消费者保障类型如果包含禁止退货则标记为不可退货
* 商品是否禁止退货从商品信息中获取消费者保障类型如果包含"禁止退货"则标记为不可退货
* 订单状态是否超过退货期限
* 如果订单状态为已收货已完成并且当前时间超过允许提现时间则标记为不可退货
* 如果订单状态为"已收货""已完成"并且当前时间超过允许提现时间则标记为不可退货
*
* @param shopOrderInfo
* @param shopOrderItem
@ -2107,6 +2140,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
* @return
*/
public boolean ifDenyReturn(ShopOrderInfo shopOrderInfo, ShopOrderItem shopOrderItem, ShopProductIndex shopProductIndex) {
// 默认允许退货
boolean is_denyreturn = false;
if (shopOrderItem == null) {
@ -2127,8 +2161,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
// 1商品是否允许
if (contractTypeIds.contains(new Integer(StateCode.CONTRACT_TYPE_DENY_RETURN))) {
is_denyreturn = true;
//throw new ApiException(I18nUtil._("此商品不允许退货!"));
return is_denyreturn;
throw new ApiException(I18nUtil._("此商品不允许退货!"));
}
// 2是否已经可结算, 进入可结算不允许退货
@ -2138,33 +2171,10 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
//order_qs_time
if (withdrawTime.compareTo(shopOrderInfo.getOrder_deal_time()) > 0) {
is_denyreturn = true;
//throw new ApiException(I18nUtil._("此商品已过退货期,不允许退货!"));
return is_denyreturn;
throw new ApiException(I18nUtil._("此商品已过退货期,不允许退货!"));
}
}
/*
float withdraw_received_day = accountBaseConfigService.getConfig("withdraw_received_day", 7f);
int second = NumberUtil.mul(withdraw_received_day, 60, 60, 24).intValue();
if (withdraw_received_day >= 0) {
//计算withdraw_received_day天内的订单额度
Long time = DateUtil.offsetSecond(new Date(), -second).getTime();
if (shopOrderInfo.getOrder_state_id().intValue() == StateCode.ORDER_STATE_RECEIVED || shopOrderInfo.getOrder_state_id().intValue() == StateCode.ORDER_STATE_FINISH)
{
//order_qs_time
if (time.compareTo(shopOrderInfo.getOrder_deal_time()) > 0) {
is_denyreturn = true;
return is_denyreturn;
//throw new ApiException(I18nUtil._("此商品已过退货期,不允许退货!"));
}
}
}
*/
//end判断是否可以申请退款
return is_denyreturn;
}
@ -2564,14 +2574,19 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
return CommonResult.failed("订单未付款,无法退款");
}
// if (orderInfo.getOrder_state_id() != null
// && orderInfo.getOrder_state_id() >= StateCode.ORDER_STATE_SHIPPED
// && orderInfo.getOrder_state_id() <= StateCode.ORDER_STATE_CANCEL) {
// return CommonResult.failed("已发货、已取消的订单无法退款");
// }
if (orderInfo.getOrder_state_id() != null
&& orderInfo.getOrder_state_id() >= StateCode.ORDER_STATE_SHIPPED
&& orderInfo.getOrder_state_id() <= StateCode.ORDER_STATE_CANCEL) {
return CommonResult.failed("已发货、已取消的订单无法退款");
&& StateCode.ORDER_STATE_CANCEL == orderInfo.getOrder_state_id().intValue()) {
return CommonResult.failed("已取消的订单无法退款");
}
if (orderInfo.getStore_id() != null && !orderInfo.getStore_id().equals(Convert.toInt(currentUser.getStore_id()))) {
return CommonResult.failed("无权处理其他店铺订单");
return CommonResult.failed("无权处理订单");
}
List<ShopOrderItem> orderItems = shopOrderItemService.find(new QueryWrapper<ShopOrderItem>().eq("order_id", orderId));
@ -2599,6 +2614,10 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
if (StrUtil.isNotBlank(requestParams.getStr("order_return_vo"))) {
orderReturnInputVo = JSONUtil.toBean(requestParams.getStr("order_return_vo"), OrderReturnInputVo.class);
// 如果orderReturnInputVo中的order_id为空则使用上层参数中的order_id
if (orderReturnInputVo != null && StrUtil.isBlank(orderReturnInputVo.getOrder_id())) {
orderReturnInputVo.setOrder_id(orderId);
}
// 传入参数商品种类数量>0的
isPartialRefund = orderReturnInputVo != null && CollectionUtil.isNotEmpty(orderReturnInputVo.getReturn_items());
}
@ -2614,16 +2633,19 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
if (isPartialRefund) {
// 单个订单退款
List<Long> validItemIds = orderItems.stream().map(ShopOrderItem::getOrder_item_id).collect(Collectors.toList());
orderReturnInputVo.getReturn_items().stream()
boolean validItems = orderReturnInputVo.getReturn_items().stream()
.allMatch(item -> validItemIds.contains(item.getOrder_item_id())
&& item.getReturn_refund_amount().compareTo(BigDecimal.ZERO) > 0
&& item.getReturn_item_num() > 0);
if (!validItems) {
return CommonResult.failed("退款商品信息不正确请检查商品ID、退款金额和数量是否有效");
}
List<OrderReturnItemInputVo> orderReturnItems = orderReturnInputVo.getReturn_items();
refundGoodsAmount = orderReturnItems.stream().map(OrderReturnItemInputVo::getReturn_refund_amount).reduce(BigDecimal.ZERO, BigDecimal::add);
if (refundGoodsAmount.compareTo(orderGoodsAmount) > 0) {
return CommonResult.failed("退款金额有误!");
return CommonResult.failed("退款金额有误!退款金额不能大于订单商品总金额");
}
refundRequest.setReturn_buyer_message(StrUtil.isBlank(reason) ? "订单部分商品退款" : reason);
@ -2646,7 +2668,12 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
CommonResult createResult = addItem(refundRequest, false);
if (createResult == null || createResult.getStatus() != 200) {
log.error("退货单创建失败params:{}", refundRequest);
return createResult;
// 提供更详细的错误信息
String errorMsg = "退货单创建失败";
if (createResult != null && createResult.getMsg() != null) {
errorMsg += "" + createResult.getMsg();
}
return CommonResult.failed(errorMsg);
}
refundOrder = findOne(new QueryWrapper<ShopOrderReturn>()
@ -2681,8 +2708,55 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
return CommonResult.success();
} catch (Exception e) {
log.error("商家处理退款异常", e);
return CommonResult.failed(e.getMessage());
// 提供更具体的错误信息
String errorMsg = "退款处理异常";
if (e instanceof ApiException) {
errorMsg = e.getMessage();
} else if (e.getCause() instanceof ApiException) {
errorMsg = e.getCause().getMessage();
}
return CommonResult.failed(errorMsg);
}
}
/**
* 获取拒绝退货的详细原因
*
* @param shopOrderInfo
* @param shopOrderItem
* @param shopProductIndex
* @return
*/
public String getDenyReturnReason(ShopOrderInfo shopOrderInfo, ShopOrderItem shopOrderItem, ShopProductIndex shopProductIndex) {
if (shopOrderItem == null) {
return "订单商品信息不存在";
}
if (shopProductIndex == null) {
shopProductIndex = shopProductIndexService.get(shopOrderItem.getProduct_id());
if (shopProductIndex == null) {
return "商品信息不存在";
}
}
List<Integer> contractTypeIds = Convert.toList(Integer.class, shopProductIndex.getContract_type_ids());
// 1商品是否允许退货
if (contractTypeIds.contains(new Integer(StateCode.CONTRACT_TYPE_DENY_RETURN))) {
return "商品 " + shopProductIndex.getProduct_name() + " 不支持退货";
}
// 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
if (withdrawTime.compareTo(shopOrderInfo.getOrder_deal_time()) > 0) {
return "订单已超过退货期限,无法退货";
}
}
return "商品不支持退货";
}
}