商品库存累加减公共方法修正

This commit is contained in:
Jack 2025-06-14 16:41:48 +08:00
parent 669bd33b5f
commit 13b5acfea9
12 changed files with 661 additions and 67 deletions

View File

@ -19,7 +19,9 @@ import com.suisung.mall.common.pojo.req.WxUserInfoReq;
import com.suisung.mall.common.utils.I18nUtil;
import com.suisung.mall.common.utils.phone.PhoneNumberUtils;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -37,6 +39,7 @@ import java.util.UUID;
* @author Xinze
* @since 2021-04-28
*/
@Slf4j
@Service
public class AccountUserBindConnectServiceImpl extends BaseServiceImpl<AccountUserBindConnectMapper, AccountUserBindConnect> implements AccountUserBindConnectService {
@ -397,12 +400,26 @@ public class AccountUserBindConnectServiceImpl extends BaseServiceImpl<AccountUs
return null;
}
/**
* 初始化账户用户绑定信息
*
* @param bindId 绑定ID
* @param bindType 绑定类型
* @param userId 用户ID
* @param userType 用户类型
* @return 账户用户绑定连接对象如果初始化失败则返回null
*/
public AccountUserBindConnect initAccountUserBindConnect(String bindId, Integer bindType, Integer userId, Integer userType) {
if (StrUtil.isBlank(bindId) || bindType == null || userId == null || userType == null) {
// 1. 校验入参任何一个为空直接返回null
if (StrUtil.isBlank(bindId)
|| ObjectUtil.isNull(bindType)
|| ObjectUtil.isNull(bindType)
|| ObjectUtil.isNull(bindType)) {
log.warn("初始化账户用户绑定信息失败参数存在空值bindId={}, bindType={}, userId={}, userType={}", bindId, bindType, userId, userType);
return null;
}
// 2. 查询是否已存在绑定关系
QueryWrapper<AccountUserBindConnect> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("bind_id", bindId)
.eq("bind_type", bindType)
@ -410,29 +427,44 @@ public class AccountUserBindConnectServiceImpl extends BaseServiceImpl<AccountUs
.eq("user_id", userId)
.eq("bind_active", CommonConstant.Enable);
AccountUserBindConnect accountUserBindConnect = findOne(queryWrapper);
if (accountUserBindConnect != null) {
return accountUserBindConnect;
AccountUserBindConnect existingBindConnect = findOne(queryWrapper);
if (existingBindConnect != null) {
log.info("账户用户绑定信息已存在bindId={}, bindType={}, userId={}, userType={}", bindId, bindType, userId, userType);
return existingBindConnect;
}
// 新增一条绑定数据
AccountUserBindConnect record = new AccountUserBindConnect();
record.setBind_id(bindId);
record.setBind_type(bindType);
record.setUser_id(userId);
record.setUser_type(userType);
record.setBind_active(CommonConstant.Enable);
record.setBind_time(new Date());
record.setBind_expires_in(0);
record.setBind_token_ttl(0);
record.setBind_level(0);
record.setBind_vip(0);
// 3. 创建新的绑定关系
AccountUserBindConnect newBindConnect = new AccountUserBindConnect();
newBindConnect.setBind_id(bindId);
newBindConnect.setBind_type(bindType);
newBindConnect.setUser_id(userId);
newBindConnect.setUser_type(userType);
newBindConnect.setBind_active(CommonConstant.Enable);
newBindConnect.setBind_time(new Date());
newBindConnect.setBind_expires_in(0);
newBindConnect.setBind_token_ttl(0);
newBindConnect.setBind_level(0);
newBindConnect.setBind_vip(0);
// 一定是 insert 新增不能 saveOrUpdate
if (add(record)) {
return record;
// log.debug("准备创建新的账户用户绑定信息: {}", JSONUtil.toJsonStr(newBindConnect));
// 4. 插入新的绑定关系处理唯一索引冲突异常
try {
if (add(newBindConnect)) {
log.info("成功创建账户用户绑定信息: bindId={}, bindType={}, userId={}, userType={}", bindId, bindType, userId, userType);
return newBindConnect;
} else {
log.error("创建账户用户绑定信息失败数据库操作返回false");
return null;
}
} catch (DuplicateKeyException e) {
// 5. 捕获唯一索引冲突异常
log.error("创建账户用户绑定信息失败违反唯一约束bindId={}, bindType={}, userId={}, userType={}", bindId, bindType, userId, userType, e);
return null;
} catch (Exception e) {
// 6. 捕获其他异常
log.error("创建账户用户绑定信息时发生未知异常bindId={}, bindType={}, userId={}, userType={}", bindId, bindType, userId, userType, e);
return null;
}
}
}

View File

@ -12,6 +12,7 @@ import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* <p>
@ -101,4 +102,9 @@ public class PayUserResource implements Serializable {
@ApiModelProperty(value = "乐观锁")
private Integer version;
@ApiModelProperty(value = "新增时间,默认当前时间")
private Date created_at;
@ApiModelProperty(value = "最后更新时间,默认当前时间")
private Date updated_at;
}

View File

@ -28,16 +28,6 @@ redis:
separator: ":"
expire: 3600
redisson:
address: redis://@redis.host@:@redis.port@
database: @redis.database@ # Redis 库索引
password: @redis.password@ # Redis 密码
connectionPoolSize: 64 # 连接池大小
connectionMinimumIdleSize: 10 # 最小空闲连接数
idleConnectionTimeout: 10000 # 空闲连接超时时间(毫秒)
connectTimeout: 10000 # 连接超时时间(毫秒)
timeout: 3000 # 命令等待超时时间(毫秒)
baidu:
map:
app_id: 116444176

View File

@ -333,6 +333,12 @@ public class PayController {
return flag;
}
/**
* 订单退款远程调用
*
* @param shopOrderReturnList 退款列表
* @return 是否成功
*/
@RequestMapping(value = "/doRefund", method = RequestMethod.POST)
public boolean doRefund(@RequestBody List<ShopOrderReturn> shopOrderReturnList) {
boolean flag = false;

View File

@ -26,6 +26,7 @@ import com.suisung.mall.pay.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.*;
@ -1002,13 +1003,545 @@ public class PayConsumeTradeServiceImpl extends BaseServiceImpl<PayConsumeTradeM
return payConsumeTradeMapper.getOrderPaymentAmount(queryMap);
}
/**
* 执行退款操作
* 订单退款的逻辑处理了买家退款卖家扣款订单状态更新以及相关流水记录的生成
*
* @param returnRows 包含退货订单信息的列表
* @return boolean 退款是否成功成功返回 true失败返回 false
*/
@Transactional
@Override
public boolean doRefund(List<ShopOrderReturn> returnRows) {
log.info("执行退款操作开始");
if (CollUtil.isEmpty(returnRows)) {
log.warn("退款订单列表为空,停止退款操作");
return false;
}
// 存储已支付的退货单ID列表
List<String> paidReturnIdList = new ArrayList<>();
// 获取是否原路退回配置默认为 false
boolean refundToOriginal = accountBaseConfigService.getConfig("order_refund_flag", false);
// 提取所有订单ID并去重
List<String> orderIdList = returnRows.stream().map(ShopOrderReturn::getOrder_id).distinct().collect(Collectors.toList());
// 批量获取订单数据列表
List<ShopOrderData> orderDataList = shopService.getsShopOrderData(orderIdList);
// 提取所有店铺ID并去重
List<Integer> storeIdList = returnRows.stream().map(ShopOrderReturn::getStore_id).distinct().collect(Collectors.toList());
// 批量获取店铺基础信息列表
List<Map> storeList = shopService.getsShopStoreBase(storeIdList);
// 提取所有买家用户ID并去重
List<Integer> userIdList = returnRows.stream().map(ShopOrderReturn::getBuyer_user_id).distinct().collect(Collectors.toList());
// 批量获取买家用户资源列表不使用缓存防止缓存被保存导致回滚异常
List<PayUserResource> payUserResourceList = payUserResourceService.listByIds(userIdList);
// 批量获取订单信息列表
List<ShopOrderInfo> orderInfoList = shopService.getsShopOrderInfo(orderIdList);
// 提取所有退货单ID并去重
List<String> returnIdList = returnRows.stream().map(ShopOrderReturn::getReturn_id).distinct().collect(Collectors.toList());
// 如果退货单ID列表为空则直接返回 false
if (CollUtil.isEmpty(returnIdList)) {
log.warn("退货单ID列表为空无法进行退款操作");
return false;
}
// 构建查询参数批量查询退货单商品信息
Map<String, Object> queryParams = new HashMap<>();
queryParams.put("return_id:in", returnIdList);
List<ShopOrderReturnItem> orderReturnItemList = shopService.findShopOrderReturnItem(queryParams);
// 如果未找到退货单商品信息则抛出业务异常
if (CollUtil.isEmpty(orderReturnItemList)) {
String errorMsg = I18nUtil._("没有找到相关的退货商品信息,无法进行退款操作");
log.error(errorMsg + ", returnIdList:{}", returnIdList);
throw new ApiException(errorMsg);
}
// 提取所有订单商品ID并去重
List<Long> orderItemIdList = orderReturnItemList.stream().map(ShopOrderReturnItem::getOrder_item_id).distinct().collect(Collectors.toList());
// 批量获取订单商品列表
List<ShopOrderItem> orderItemList = shopService.getsShopOrderItem(orderItemIdList);
// 获取当前时间
Date currentTime = new Date();
// 获取当前日期格式化为 yyyy-MM-dd
DateTime ymdTime = DateUtil.parse(DateUtil.format(currentTime, "yyyy-MM-dd"));
// 获取积分价值比例配置
float pointsValueRate = accountBaseConfigService.getConfig("points_vaue_rate", 0f);
// 循环处理每个退货单
for (ShopOrderReturn returnRow : returnRows) {
try {
// 获取买家用户ID
Integer buyerUserId = returnRow.getBuyer_user_id();
// 如果买家用户ID为空则抛出业务异常
if (CheckUtil.isEmpty(buyerUserId)) {
throw new ApiException(I18nUtil._("买家信息有误!"));
}
// 获取买家店铺ID
Integer buyerStoreId = returnRow.getBuyer_store_id();
// 获取店铺ID
Integer storeId = returnRow.getStore_id();
// 从店铺列表中查找当前店铺信息
Optional<Map> storeOptional = storeList.stream().filter(s -> ObjectUtil.equal(Convert.toInt(s.get("store_id")), storeId)).findFirst();
// 如果店铺信息不存在则创建一个新的 HashMap
Map storeRow = storeOptional.orElseGet(HashMap::new);
// 获取卖家用户ID
Integer sellerUserId = (Integer) storeRow.get("user_id");
// 如果卖家用户ID为空则抛出业务异常
if (CheckUtil.isEmpty(sellerUserId)) {
throw new ApiException(I18nUtil._("卖家信息有误!"));
}
// 从用户资源列表中查找买家用户资源信息
Optional<PayUserResource> userResourceOptional = payUserResourceList.stream().filter(s -> ObjectUtil.equal(buyerUserId, s.getUser_id())).findFirst();
// 如果买家用户资源信息不存在则创建一个新的 PayUserResource 对象
PayUserResource userResourceRow = userResourceOptional.orElseGet(PayUserResource::new);
// TODO: 判断是否需要退佣金 $return_row['return_commision_fee']
BigDecimal returnCommissionFee = BigDecimal.ZERO;
// 获取订单ID
String orderId = returnRow.getOrder_id();
// 获取是否退运费标记
Integer returnIsShippingFee = returnRow.getReturn_is_shipping_fee();
// 如果不是退运费则计算是否需要退佣金
if (CheckUtil.isEmpty(returnIsShippingFee)) {
// 获取提现到账天数配置
float withdrawReceivedDay = Convert.toFloat(accountBaseConfigService.getConfig("withdraw_received_day"));
// 如果提现到账天数配置为 0则默认为 7
if (withdrawReceivedDay == 0) {
withdrawReceivedDay = 7f;
}
// 如果提现到账天数大于等于 0
if (withdrawReceivedDay >= 0) {
// 从订单信息列表中查找当前订单信息
Optional<ShopOrderInfo> orderInfoOptional = orderInfoList.stream().filter(s -> ObjectUtil.equal(orderId, s.getOrder_id())).findFirst();
// 如果订单信息不存在则创建一个新的 ShopOrderInfo 对象
ShopOrderInfo orderInfoRow = orderInfoOptional.orElseGet(ShopOrderInfo::new);
// 获取订单状态ID
Integer orderStateId = orderInfoRow.getOrder_state_id();
// 获取订单支付状态
Integer orderIsPaid = orderInfoRow.getOrder_is_paid();
// 获取订单交易完成时间
Long orderDealTime = orderInfoRow.getOrder_deal_time();
// 计算 7 天前的时间戳
long time = DateUtil.offsetDay(currentTime, -7).getTime();
// 如果订单已完成已支付且未到可结算时间则不退佣金
if (ObjectUtil.equal(orderStateId, StateCode.ORDER_STATE_FINISH)
&& ObjectUtil.equal(orderIsPaid, StateCode.ORDER_PAID_STATE_YES)
&& orderDealTime < time) {
returnCommissionFee = BigDecimal.ZERO;
} else {
// 否则退还退货单中的佣金
returnCommissionFee = returnRow.getReturn_commision_fee();
}
}
}
// 获取等待退款金额
BigDecimal waitingRefundAmount = returnRow.getReturn_refund_amount();
// 如果等待退款金额不为空
if (CheckUtil.isNotEmpty(waitingRefundAmount)) {
// 从订单数据列表中查找当前订单数据
Optional<ShopOrderData> orderDataOptional = orderDataList.stream().filter(s -> ObjectUtil.equal(s.getOrder_id(), orderId)).findFirst();
// 如果订单数据不存在则创建一个新的 ShopOrderData 对象
ShopOrderData orderDataRow = orderDataOptional.orElseGet(ShopOrderData::new);
// 获取订单使用的积分
BigDecimal orderPointsFee = orderDataRow.getOrder_points_fee();
// 获取订单已退积分
BigDecimal orderRefundAgreePoints = orderDataRow.getOrder_refund_agree_points();
// 买家用户余额初始值为等待退款金额
BigDecimal buyerUserMoney = waitingRefundAmount;
// 买家用户积分初始值为 0
BigDecimal buyerUserPoints = BigDecimal.ZERO;
// 卖家用户余额初始值为等待退款金额的负数
BigDecimal sellerUserMoney = waitingRefundAmount.negate();
// 获取退货单ID
String returnId = returnRow.getReturn_id();
// 创建买家消费记录对象
PayConsumeRecord buyerConsumeRecordRow = new PayConsumeRecord();
// 设置买家消费记录的订单ID
buyerConsumeRecordRow.setOrder_id(returnId);
// 设置买家消费记录的用户ID
buyerConsumeRecordRow.setUser_id(buyerUserId);
// 设置买家消费记录的店铺ID
buyerConsumeRecordRow.setStore_id(buyerStoreId);
// 设置买家消费记录的用户昵称TODO: 补充 User_nickname
buyerConsumeRecordRow.setUser_nickname("");
// 设置买家消费记录的记录日期
buyerConsumeRecordRow.setRecord_date(ymdTime);
// 设置买家消费记录的记录年份
buyerConsumeRecordRow.setRecord_year(DateUtil.year(ymdTime));
// 设置买家消费记录的记录月份
buyerConsumeRecordRow.setRecord_month(DateUtil.month(ymdTime) + 1);
// 设置买家消费记录的记录日
buyerConsumeRecordRow.setRecord_day(DateUtil.dayOfMonth(ymdTime));
// 设置买家消费记录的记录标题
buyerConsumeRecordRow.setRecord_title(I18nUtil._("退款单:") + returnId);
// 设置买家消费记录的记录时间
buyerConsumeRecordRow.setRecord_time(currentTime);
// 设置买家消费记录的支付方式ID
buyerConsumeRecordRow.setPayment_met_id(PaymentType.PAYMENT_MET_MONEY);
// 增加买家流水
buyerConsumeRecordRow.setRecord_money(waitingRefundAmount); // 佣金问题
// 设置买家消费记录的交易类型ID
buyerConsumeRecordRow.setTrade_type_id(StateCode.TRADE_TYPE_REFUND_GATHERING);
// 创建卖家消费记录对象克隆买家消费记录
PayConsumeRecord sellerConsumeRecordRow = ObjectUtil.clone(buyerConsumeRecordRow);
// 设置卖家消费记录的用户ID
sellerConsumeRecordRow.setUser_id(sellerUserId);
// 设置卖家消费记录的店铺ID
sellerConsumeRecordRow.setStore_id(storeId);
// 设置卖家消费记录的记录金额等待退款金额的负数 + 退还佣金
sellerConsumeRecordRow.setRecord_money(NumberUtil.add(waitingRefundAmount.negate(), returnCommissionFee));
// 设置卖家消费记录的记录佣金退还佣金的负数
sellerConsumeRecordRow.setRecord_commission_fee(returnCommissionFee.negate());
// 设置卖家消费记录的交易类型ID
sellerConsumeRecordRow.setTrade_type_id(StateCode.TRADE_TYPE_REFUND_PAY);
// 设置订单的已退款金额原已退款金额 + 等待退款金额
orderDataRow.setOrder_refund_agree_amount(NumberUtil.add(waitingRefundAmount, orderRefundAgreePoints));
// TODO: 不能在这里统计并发情况下 Seata 操作同一张表数据会导致无法回滚的问题
// 原因A 线程修改完数据记录到 undo_log 表中回滚的时候发现 B 线程也修改了这个数据
// 平台佣金总额
/*if (CheckUtil.isNotEmpty(returnCommissionFee)) {
PayPlantformResource plantform_resource_row = payPlantformResourceService.get(DATA_ID);
if (plantform_resource_row == null) {
plantform_resource_row = new PayPlantformResource();
plantform_resource_row.setPlantform_resource_id(DATA_ID);
}
plantform_resource_row.setPlantform_commission_fee(NumberUtil.add(returnCommissionFee.negate(), plantform_resource_row.getPlantform_commission_fee()));
if (!payPlantformResourceService.saveOrUpdate(plantform_resource_row)) {
throw new ApiException(ResultCode.FAILED);
}
BigDecimal order_commission_fee_refund = order_data_row.getOrder_commission_fee_refund();
order_data_row.setOrder_commission_fee_refund(NumberUtil.add(order_commission_fee_refund, returnCommissionFee));
}*/
// 读取退货单项目列表
List<ShopOrderReturnItem> orderReturnItemRows = orderReturnItemList.stream().filter(s -> ObjectUtil.equal(s.getReturn_id(), returnId)).collect(Collectors.toList());
// 如果订单商品列表不为空
if (CollUtil.isNotEmpty(orderItemList)) {
// 创建订单商品列表
List<ShopOrderItem> orderItemRows = new ArrayList<>();
// 循环处理每个退货单项目
for (ShopOrderReturnItem orderReturnItemRow : orderReturnItemRows) {
// 获取订单商品ID
Long orderItemId = orderReturnItemRow.getOrder_item_id();
// 从订单商品列表中查找当前订单商品
Optional<ShopOrderItem> orderItemOptional = orderItemList.stream().filter(s -> ObjectUtil.equal(orderItemId, s.getOrder_item_id())).findFirst();
// 如果订单商品存在
if (orderItemOptional.isPresent()) {
// 获取订单商品
ShopOrderItem orderItemRow = orderItemOptional.get();
// 获取退货商品小计
BigDecimal returnItemSubtotal = orderReturnItemRow.getReturn_item_subtotal();
// 获取退货商品数量
Integer returnItemNum = orderReturnItemRow.getReturn_item_num();
// 获取订单商品已退金额
BigDecimal orderItemReturnAgreeAmount = orderItemRow.getOrder_item_return_agree_amount();
// 获取订单商品已退数量
Integer orderItemReturnAgreeNum = ObjectUtil.defaultIfNull(orderItemRow.getOrder_item_return_agree_num(), 0);
// 设置订单商品已退金额原已退金额 + 退货商品小计
orderItemRow.setOrder_item_return_agree_amount(NumberUtil.add(orderItemReturnAgreeAmount, returnItemSubtotal));
// 设置订单商品已退数量原已退数量 + 退货商品数量
orderItemRow.setOrder_item_return_agree_num(orderItemReturnAgreeNum + returnItemNum);
// 订单未结算才发放佣金
if (CheckUtil.isNotEmpty(returnCommissionFee)) {
// 获取退货商品佣金
BigDecimal returnItemCommissionFee = orderReturnItemRow.getReturn_item_commision_fee();
// 获取订单商品已退佣金
BigDecimal orderItemCommissionFeeRefund = ObjectUtil.defaultIfNull(orderItemRow.getOrder_item_commission_fee_refund(), BigDecimal.ZERO);
// 设置订单商品已退佣金原已退佣金 + 退货商品佣金
orderItemRow.setOrder_item_commission_fee_refund(NumberUtil.add(returnItemCommissionFee, orderItemCommissionFeeRefund));
}
// 将订单商品添加到订单商品列表中
orderItemRows.add(orderItemRow);
}
}
// 如果订单商品列表不为空
if (CollUtil.isNotEmpty(orderItemRows)) {
// 批量修改订单商品
if (!shopService.editsShopOrderItem(orderItemRows)) {
throw new ApiException(I18nUtil._("修改订单商品数据失败!"));
}
}
}
// 保存买家消费记录
if (!payConsumeRecordService.saveOrUpdate(buyerConsumeRecordRow)) {
throw new ApiException(I18nUtil._("添加买家流水数据失败!"));
}
// 如果混合了积分优先退积分
if (orderPointsFee.compareTo(BigDecimal.ZERO) > 0
&& orderPointsFee.compareTo(orderRefundAgreePoints) > 0) {
// 计算可退积分
BigDecimal refundPoints = NumberUtil.round(NumberUtil.min(NumberUtil.sub(orderPointsFee, orderRefundAgreePoints)), 2);
// 计算扣除积分后的买家余额
buyerUserMoney = NumberUtil.round(NumberUtil.sub(buyerUserMoney, refundPoints), 2);
// 如果积分价值比例大于 0
if (pointsValueRate > 0) {
// 计算买家可退积分
buyerUserPoints = NumberUtil.div(refundPoints, pointsValueRate);
}
// 设置订单已退积分原已退积分 + 本次退还积分
orderDataRow.setOrder_refund_agree_points(NumberUtil.add(orderRefundAgreePoints, refundPoints));
}
// TODO: 优化代码
// 如果需要原路退回
if (refundToOriginal) {
// 读取在线支付信息如果无在线支付信息则余额支付 否则在线支付联合支付判断
QueryWrapper<PayConsumeDeposit> depositQueryWrapper = new QueryWrapper<>();
depositQueryWrapper.apply(orderId != null, "FIND_IN_SET ('" + orderId + "', order_id )");
PayConsumeDeposit consumeRow = payConsumeDepositService.findOne(depositQueryWrapper);
// 如果存在在线支付信息
if (consumeRow != null) {
// 获取支付渠道ID
Integer paymentChannelId = consumeRow.getPayment_channel_id();
// 获取支付渠道信息
PayPaymentChannel paymentChannelRow = payPaymentChannelService.get(paymentChannelId);
// 获取支付渠道代码
String paymentChannelCode = paymentChannelRow.getPayment_channel_code();
// 获取支付总金额
BigDecimal depositTotalFee = consumeRow.getDeposit_total_fee();
log.debug("支付渠道代码: {}, 支付总金额: {}", paymentChannelCode, depositTotalFee);
// 如果支付渠道编号为支付宝或微信原生支付
if (Arrays.asList("alipay", "wx_native").contains(paymentChannelCode)) {
// 计算买家余额差额退款的金额
BigDecimal moneyDifference = NumberUtil.round(NumberUtil.sub(buyerUserMoney, depositTotalFee), 2);
// 如果余额差额退款的金额大于 0
if (moneyDifference.compareTo(BigDecimal.ZERO) > 0) {
// 获取买家用户资源
PayUserResource payUserResource = payUserResourceService.getById(buyerUserId);
// 设置买家用户余额原余额 + 余额差额
payUserResource.setUser_money(NumberUtil.add(payUserResource.getUser_money(), moneyDifference));
// 修改买家用户资源
if (!payUserResourceService.edit(payUserResource)) {
throw new ApiException(I18nUtil._("用户退款失败!"));
}
}
// 如果买家用户积分大于 0
if (buyerUserPoints.compareTo(BigDecimal.ZERO) > 0) {
// 退还用户积分
if (!payUserResourceService.points(buyerUserId, buyerUserPoints, PointsType.POINTS_TYPE_CONSUME_RETRUN, returnId, storeId, null, returnId)) {
throw new ApiException(I18nUtil._("用户退积分失败!"));
}
}
// 获取在线支付交易号
String depositTradeNo = consumeRow.getDeposit_trade_no();
// 创建订单退货单对象
ShopOrderReturn orderReturn = new ShopOrderReturn();
// 设置退货单ID
orderReturn.setReturn_id(returnId);
// 设置退货渠道代码
orderReturn.setReturn_channel_code(paymentChannelCode);
// 设置在线支付交易号
orderReturn.setDeposit_trade_no(depositTradeNo);
// 设置支付渠道ID
orderReturn.setPayment_channel_id(paymentChannelId);
// 设置交易支付金额
orderReturn.setTrade_payment_amount(depositTotalFee);
// 修改订单退货单
if (!shopService.editShopOrderReturn(orderReturn)) {
throw new ApiException(I18nUtil._("修改退单信息失败!"));
}
} else {
// 非微信支付宝支付的情况
// 如果买家用户余额大于 0
if (buyerUserMoney.compareTo(BigDecimal.ZERO) > 0) {
// 获取买家用户资源
PayUserResource payUserResource = payUserResourceService.getById(buyerUserId);
// 设置买家用户余额原余额 + 买家余额
payUserResource.setUser_money(NumberUtil.add(payUserResource.getUser_money(), buyerUserMoney));
// 修改买家用户资源
if (!payUserResourceService.edit(payUserResource)) {
throw new ApiException(I18nUtil._("用户退款失败!"));
}
}
// 如果买家用户积分大于 0
if (buyerUserPoints.compareTo(BigDecimal.ZERO) > 0) {
// 退还用户积分
if (!payUserResourceService.points(buyerUserId, buyerUserPoints, PointsType.POINTS_TYPE_CONSUME_RETRUN, returnId, storeId, null, returnId)) {
throw new ApiException(I18nUtil._("用户退积分失败!"));
}
}
// 创建订单退货单对象
ShopOrderReturn orderReturn = new ShopOrderReturn();
// 设置退货单ID
orderReturn.setReturn_id(returnId);
// 设置退货渠道标记
orderReturn.setReturn_channel_flag(1);
// 修改订单退货单
if (!shopService.editShopOrderReturn(orderReturn)) {
throw new ApiException(I18nUtil._("修改退单信息失败!"));
}
}
} else {
// 如果买家用户余额大于 0
if (buyerUserMoney.compareTo(BigDecimal.ZERO) > 0) {
// 获取买家用户资源
PayUserResource payUserResource = payUserResourceService.getById(buyerUserId);
// 设置买家用户余额原余额 + 买家余额
payUserResource.setUser_money(NumberUtil.add(payUserResource.getUser_money(), buyerUserMoney));
// 修改买家用户资源
if (!payUserResourceService.edit(payUserResource)) {
throw new ApiException(I18nUtil._("用户退款失败!"));
}
}
// 如果买家用户积分大于 0
if (buyerUserPoints.compareTo(BigDecimal.ZERO) > 0) {
// 退还用户积分
if (!payUserResourceService.points(buyerUserId, buyerUserPoints, PointsType.POINTS_TYPE_CONSUME_RETRUN, returnId, storeId, null, returnId)) {
throw new ApiException(I18nUtil._("用户退积分失败!"));
}
}
// 创建订单退货单对象
ShopOrderReturn orderReturn = new ShopOrderReturn();
// 设置退货单ID
orderReturn.setReturn_id(returnId);
// 设置退货渠道标记
orderReturn.setReturn_channel_flag(1);
// 修改订单退货单
if (!shopService.editShopOrderReturn(orderReturn)) {
throw new ApiException(I18nUtil._("修改退单信息失败!"));
}
}
} else {
// 如果买家用户余额大于 0
if (buyerUserMoney.compareTo(BigDecimal.ZERO) > 0) {
// 获取买家用户资源
PayUserResource payUserResource = payUserResourceService.getById(buyerUserId);
// 设置买家用户余额原余额 + 买家余额
payUserResource.setUser_money(NumberUtil.add(payUserResource.getUser_money(), buyerUserMoney));
// 修改买家用户资源
if (!payUserResourceService.edit(payUserResource)) {
throw new ApiException(I18nUtil._("用户退款失败!"));
}
}
// 如果买家用户积分大于 0
if (buyerUserPoints.compareTo(BigDecimal.ZERO) > 0) {
// 退还用户积分
if (!payUserResourceService.points(buyerUserId, buyerUserPoints, PointsType.POINTS_TYPE_CONSUME_RETRUN, returnId, storeId, null, returnId)) {
throw new ApiException(I18nUtil._("用户退积分失败!"));
}
}
// 创建订单退货单对象
ShopOrderReturn orderReturn = new ShopOrderReturn();
// 设置退货单ID
orderReturn.setReturn_id(returnId);
// 设置退货渠道标记
orderReturn.setReturn_channel_flag(1);
// 修改订单退货单
if (!shopService.editShopOrderReturn(orderReturn)) {
throw new ApiException(I18nUtil._("修改退单信息失败!"));
}
}
// 修改订单数据
if (!shopService.editShopOrderData(orderDataRow)) {
throw new ApiException(I18nUtil._("修改详细信息失败!"));
}
// TODO: 修改订单状态
// 如果买家余额不为空
if (buyerUserMoney != null) {
// 保存卖家消费记录
if (!payConsumeRecordService.saveOrUpdate(sellerConsumeRecordRow)) {
throw new ApiException(I18nUtil._("写入卖家信息失败!"));
}
// 计算卖家余额
sellerUserMoney = NumberUtil.add(buyerUserMoney.negate(), returnCommissionFee);
// 获取卖家用户资源
PayUserResource payUserResource = payUserResourceService.getById(sellerUserId);
// 设置卖家用户余额
payUserResource.setUser_money(NumberUtil.add(payUserResource.getUser_money(), sellerUserMoney));
// 修改卖家用户资源
if (!payUserResourceService.edit(payUserResource)) {
throw new ApiException(I18nUtil._("卖家用户退款失败!"));
}
}
// 将已支付的退货单ID添加到列表中
paidReturnIdList.add(returnId);
}
} catch (ApiException e) {
// 捕获业务异常记录日志并继续处理下一个退货单
log.error("处理退货单异常, returnRow:{}, error:{}", returnRow, e.getMessage());
}
}
// 如果已支付的退货单ID列表不为空
if (CollUtil.isNotEmpty(paidReturnIdList)) {
// 远程服务器订单更改放入
// 本地服务器订单更改
// 批量更新退货单状态为已退款
if (!shopService.setReturnPaidYes(paidReturnIdList)) {
throw new ApiException(ResultCode.FAILED);
}
}
log.info("执行退款操作完成已支付的退货单ID列表: {}", paidReturnIdList);
// 返回退款成功
return true;
}
/**
* 执行退款操作
* 订单退款的逻辑处理了买家退款卖家扣款订单状态更新以及相关流水记录的生成
*
* @param return_rows 订单信息
*/
@Override
public boolean doRefund(List<ShopOrderReturn> return_rows) {
// @Override
public boolean doRefundBak(List<ShopOrderReturn> return_rows) {
List<String> paid_return_id_row = new ArrayList<>();
// 原路退回标记
@ -1026,16 +1559,15 @@ public class PayConsumeTradeServiceImpl extends BaseServiceImpl<PayConsumeTradeM
List<ShopOrderInfo> order_info_rows = shopService.getsShopOrderInfo(order_id_rows);
List<String> return_ids = return_rows.stream().map(ShopOrderReturn::getReturn_id).distinct().collect(Collectors.toList());
if (CollUtil.isEmpty(return_ids)) {
return false;
}
List<ShopOrderReturnItem> orderReturnItemList = new ArrayList<>();
if (CollUtil.isNotEmpty(return_ids)) {
Map queryParams = new HashMap();
queryParams.put("return_id:in", return_ids);
orderReturnItemList = shopService.findShopOrderReturnItem(queryParams);
} else {
//异常不应该出现
return false;
List<ShopOrderReturnItem> orderReturnItemList = shopService.findShopOrderReturnItem(queryParams);
if (CollUtil.isEmpty(orderReturnItemList)) {
throw new ApiException(I18nUtil._("没有找到相关的退货商品信息!"));
}
List<Long> order_item_ids = orderReturnItemList.stream().map(ShopOrderReturnItem::getOrder_item_id).distinct().collect(Collectors.toList());
@ -1207,7 +1739,6 @@ public class PayConsumeTradeServiceImpl extends BaseServiceImpl<PayConsumeTradeM
}
// 如果混合了积分优先退积分
if (order_points_fee.compareTo(BigDecimal.ZERO) > 0
&& order_points_fee.compareTo(order_refund_agree_points) > 0) {
BigDecimal refund_points = NumberUtil.round(NumberUtil.min(NumberUtil.sub(order_points_fee, order_refund_agree_points)), 2);

View File

@ -746,7 +746,7 @@ public class ShopActivityGroupbookingServiceImpl extends BaseServiceImpl<ShopAct
Integer return_next_state_id = StateCode.RETURN_PROCESS_FINISH;
//执行退货申请
flag = shopOrderReturnService.review(Collections.singletonList(return_id), Collections.singletonList(orderReturn), StateCode.RETURN_PROCESS_CHECK, return_next_state_id);
flag = shopOrderReturnService.processReviewList(Collections.singletonList(return_id), Collections.singletonList(orderReturn), StateCode.RETURN_PROCESS_CHECK, return_next_state_id);
if (!flag) {
throw new ApiException(ResultCode.FAILED);

View File

@ -76,7 +76,7 @@ public class ShopOrderReturnController extends BaseControllerImpl {
return CommonResult.success(shopOrderReturnService.saveOrUpdate(shopOrderReturn));
}
@ApiOperation(value = "退货单审核 - 同意退款退库", notes = "退货单审核 - 同意退款退库")
@ApiOperation(value = "退货单审核 - 商家同意退款退库", notes = "退货单审核 - 同意退款退库")
@RequestMapping(value = "/review", method = RequestMethod.POST)
public CommonResult review(@RequestParam(name = "return_id") String return_id,
@RequestParam(name = "return_flag", defaultValue = "0") Integer return_flag,
@ -86,10 +86,10 @@ public class ShopOrderReturnController extends BaseControllerImpl {
shopOrderReturn.setReturn_id(return_id);
shopOrderReturn.setReturn_flag(return_flag);
shopOrderReturn.setReturn_store_message(return_store_message);
return CommonResult.success(shopOrderReturnService.review(shopOrderReturn, receiving_address));
return CommonResult.success(shopOrderReturnService.processReviewList(shopOrderReturn, receiving_address));
}
@ApiOperation(value = "退货单审核 - 家拒绝退款", notes = "退货单审核 - 卖家拒绝退款")
@ApiOperation(value = "退货单审核 - 家拒绝退款", notes = "退货单审核 - 卖家拒绝退款")
@RequestMapping(value = "/refused", method = RequestMethod.POST)
public CommonResult refused(ShopOrderReturn shopOrderReturn) {
String return_store_message = shopOrderReturn.getReturn_store_message();
@ -123,7 +123,7 @@ public class ShopOrderReturnController extends BaseControllerImpl {
ShopOrderReturn shopOrderReturn = shopOrderReturnService.get(return_id);
if (CheckUtil.checkDataRights(store_id, shopOrderReturn, ShopOrderReturn::getStore_id)) {
shopOrderReturnService.review(Collections.singletonList(return_id), Collections.singletonList(shopOrderReturn), StateCode.RETURN_PROCESS_RECEIVED, null);
shopOrderReturnService.processReviewList(Collections.singletonList(return_id), Collections.singletonList(shopOrderReturn), StateCode.RETURN_PROCESS_RECEIVED, null);
} else {
throw new ApiException(ResultCode.FORBIDDEN);
}

View File

@ -58,7 +58,7 @@ public class UserReturnController extends BaseControllerImpl {
return shopOrderReturnService.returnItem();
}
@ApiOperation(value = "添加退款退货-发货退货,卖家也可以决定不退货退款,买家申请退款不支持。卖家可以主动退款。", notes = "添加退款退货-发货退货,卖家也可以决定不退货退款,买家申请退款不支持。卖家可以主动退款。")
@ApiOperation(value = "添加退款退货-部分退货,卖家也可以决定不退货退款,买家申请退款不支持。卖家可以主动退款。", notes = "添加退款退货-发货退货,卖家也可以决定不退货退款,买家申请退款不支持。卖家可以主动退款。")
@RequestMapping(value = "/addItem", method = RequestMethod.GET)
public CommonResult addItem(OrderReturnVo orderReturnVo) {
OrderReturnInputVo orderReturnInput = BeanUtil.copyProperties(orderReturnVo, OrderReturnInputVo.class);

View File

@ -43,7 +43,7 @@ public interface ShopOrderReturnService extends IBaseService<ShopOrderReturn> {
Map getReturnDetail(String return_id);
boolean review(ShopOrderReturn shopOrderReturn, Integer receiving_address);
boolean processReviewList(ShopOrderReturn shopOrderReturn, Integer receiving_address);
/**
* 退单审核
@ -54,7 +54,7 @@ public interface ShopOrderReturnService extends IBaseService<ShopOrderReturn> {
* @param return_next_state_id
* @return
*/
boolean review(List<String> return_ids, List<ShopOrderReturn> return_rows, Integer state_id, Integer return_next_state_id);
boolean processReviewList(List<String> return_ids, List<ShopOrderReturn> return_rows, Integer state_id, Integer return_next_state_id);
/**
* 卖家拒绝退款

View File

@ -744,7 +744,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
ShopOrderReturn orderReturn = get(return_id);
if (CheckUtil.checkDataRights(store_id, orderReturn, ShopOrderReturn::getStore_id)) {
review(Collections.singletonList(return_id), Collections.singletonList(orderReturn), StateCode.RETURN_PROCESS_REFUND, null);
processReviewList(Collections.singletonList(return_id), Collections.singletonList(orderReturn), StateCode.RETURN_PROCESS_REFUND, null);
} else {
throw new ApiException(I18nUtil._("无操作权限!"));
}
@ -875,7 +875,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
}
// 订单审核
review(return_ids, Collections.singletonList(shopOrderReturn), StateCode.RETURN_PROCESS_CHECK, null);
processReviewList(return_ids, Collections.singletonList(shopOrderReturn), StateCode.RETURN_PROCESS_CHECK, null);
} else {
throw new ApiException(ResultCode.FORBIDDEN);
}
@ -1115,22 +1115,23 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
}
/**
* 退货单审核 - 同意退款退库
* 退货单审核 - 商家同意退款退库
*
* @param shopOrderReturn
* @return
*/
@Override
@GlobalTransactional
public boolean review(ShopOrderReturn shopOrderReturn, Integer receiving_address) {
public boolean processReviewList(ShopOrderReturn shopOrderReturn, Integer receiving_address) {
Integer store_id = null;
Integer store_id;
if (shopOrderReturn.getStore_id() == null) {
UserDto user = getCurrentUser();
store_id = Convert.toInt(user.getStore_id());
} else {
store_id = shopOrderReturn.getStore_id();
}
String str_return_id = shopOrderReturn.getReturn_id();
List<String> return_ids = Convert.toList(String.class, str_return_id);
@ -1140,17 +1141,19 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
Integer return_flag = shopOrderReturn.getReturn_flag();
if (ObjectUtil.equal(return_flag, 0)) {
//无需退货直接修改退货单状态为完成并调用 review 方法进行审核
if (!edit(shopOrderReturn)) {
throw new ApiException(I18nUtil._("修改订单信息失败!"));
}
Integer return_next_state_id = StateCode.RETURN_PROCESS_FINISH;
// 订单审核
if (!review(return_ids, orderReturns, StateCode.RETURN_PROCESS_CHECK, return_next_state_id)) {
if (!processReviewList(return_ids, orderReturns, StateCode.RETURN_PROCESS_CHECK, return_next_state_id)) {
throw new ApiException(I18nUtil._("审核失败!"));
}
} else {
//需要退货获取收货地址信息并更新退货单的相关字段如地址联系方式等随后调用 review 方法进行审核
ShopStoreShippingAddress address_row = shopStoreShippingAddressService.get(receiving_address);
if (address_row != null) {
String return_addr = address_row.getSs_province() + address_row.getSs_city() + address_row.getSs_county() + address_row.getSs_address();
@ -1167,7 +1170,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
}
// 订单审核
if (!review(return_ids, orderReturns, StateCode.RETURN_PROCESS_CHECK, 0)) {
if (!processReviewList(return_ids, orderReturns, StateCode.RETURN_PROCESS_CHECK, 0)) {
throw new ApiException(I18nUtil._("审核失败!"));
}
} else {
@ -1175,8 +1178,10 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
}
}
} else {
// 没有权限
throw new ApiException(ResultCode.FORBIDDEN);
}
// 通知买家退货退款成功
String message_id = "refunds-and-reminders";
Map args = new HashMap();
@ -1184,7 +1189,6 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
args.put("return_refund_amount", shopOrderReturn.getReturn_refund_amount());
messageService.sendNoticeMsg(shopOrderReturn.getBuyer_user_id(), 0, message_id, args);
return true;
}
@ -1224,7 +1228,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
}
@Override
public boolean review(List<String> return_ids, List<ShopOrderReturn> return_rows, Integer state_id, Integer return_next_state_id) {
public boolean processReviewList(List<String> return_ids, List<ShopOrderReturn> return_rows, Integer state_id, Integer return_next_state_id) {
if (CollUtil.isEmpty(return_ids)) {
throw new ApiException(I18nUtil._("请选择需要审核的退单!"));
}
@ -1278,9 +1282,17 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
*
* @param return_ids 退货订单id
* @param store_id 所属店铺
* @param return_state_id
* @param return_rows
* @param return_next_state_id 当前订单状态
* @param return_state_id 当前退单状态
* RETURN_PROCESS_SUBMIT = 3100; //客户提交退单1ReturnReturn
* RETURN_PROCESS_CHECK = 3105; //退单审核1ReturnReturn
* RETURN_PROCESS_RECEIVED = 3110; //收货确认0ReturnReturn
* RETURN_PROCESS_REFUND = 3115; //退款确认0ReturnReturn
* RETURN_PROCESS_RECEIPT_CONFIRMATION = 3120; //客户收款确认0ReturnReturn
* RETURN_PROCESS_FINISH = 3125; //完成1ReturnReturn3130-商家拒绝退货
* RETURN_PROCESS_REFUSED = 3130; //-商家拒绝退货
* RETURN_PROCESS_CANCEL = 3135; //-买家取消
* @param return_rows 退货订单列表
* @param return_next_state_id 下一个退单状态
* @return
*/
@GlobalTransactional
@ -1333,6 +1345,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
}
}
// 判断是否需要退款
if (shopStoreConfigService.checkNeedRefund(return_state_id, return_next_state_id)) {
// 执行真正退款逻辑
// 卖家账户扣款买家账户增加
@ -1346,6 +1359,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
}
}
//修改退货订单及其相关商品为下一个待处理状态
editReturnNextState(return_ids, return_state_id, shopOrderReturn);
// 当前状态 - 旧状态
@ -1457,7 +1471,8 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
}
/**
* 修改订单为下一个待处理状态
* 修改退货订单及其相关商品为下一个待处理状态
* 这段代码实现了一个方法用于将退货订单及其相关商品的状态更新为下一个待处理状态
*
* @param return_ids 退货订单id
* @param return_state_id 前订单状态

View File

@ -198,6 +198,20 @@ public class ShopStoreConfigServiceImpl extends BaseServiceImpl<ShopStoreConfigM
}
}
/**
* 检查是否需要退款
*
* @param return_state_id RETURN_PROCESS_SUBMIT = 3100; //客户提交退单1ReturnReturn
* RETURN_PROCESS_CHECK = 3105; //退单审核1ReturnReturn
* RETURN_PROCESS_RECEIVED = 3110; //收货确认0ReturnReturn
* RETURN_PROCESS_REFUND = 3115; //退款确认0ReturnReturn
* RETURN_PROCESS_RECEIPT_CONFIRMATION = 3120; //客户收款确认0ReturnReturn
* RETURN_PROCESS_FINISH = 3125; //完成1ReturnReturn3130-商家拒绝退货
* RETURN_PROCESS_REFUSED = 3130; //-商家拒绝退货
* RETURN_PROCESS_CANCEL = 3135; //-买家取消
* @param return_next_state_id
* @return
*/
@Override
public boolean checkNeedRefund(Integer return_state_id, Integer return_next_state_id) {
Integer return_process_refund = StateCode.RETURN_PROCESS_MAP.get(StateCode.RETURN_PROCESS_REFUND);

View File

@ -760,7 +760,7 @@ public class SyncThirdDataServiceImpl extends SyncBaseThirdSxAbstract implements
// 使用 Redis HINCRBY 保证原子性和高性能
redisTemplate.opsForHash().increment(RedisKey.STOREDATARELEASE, productKey, delta);
} catch (Exception e) {
logger.error("库存累失败productKey={}, delta={}, error={}", productKey, delta, e.getMessage(), e);
logger.error("库存累失败productKey={}, delta={}, error={}", productKey, delta, e.getMessage(), e);
}
}
}