diff --git a/mall-account/src/main/java/com/suisung/mall/account/service/impl/AccountUserBindConnectServiceImpl.java b/mall-account/src/main/java/com/suisung/mall/account/service/impl/AccountUserBindConnectServiceImpl.java index ff389c85..295e3b20 100644 --- a/mall-account/src/main/java/com/suisung/mall/account/service/impl/AccountUserBindConnectServiceImpl.java +++ b/mall-account/src/main/java/com/suisung/mall/account/service/impl/AccountUserBindConnectServiceImpl.java @@ -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 implements AccountUserBindConnectService { @@ -397,12 +400,26 @@ public class AccountUserBindConnectServiceImpl extends BaseServiceImpl queryWrapper = new QueryWrapper<>(); queryWrapper.eq("bind_id", bindId) .eq("bind_type", bindType) @@ -410,29 +427,44 @@ public class AccountUserBindConnectServiceImpl extends BaseServiceImpl @@ -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; } diff --git a/mall-common/src/main/resources/application-local.yml b/mall-common/src/main/resources/application-local.yml index 213d045f..e58d5ab0 100644 --- a/mall-common/src/main/resources/application-local.yml +++ b/mall-common/src/main/resources/application-local.yml @@ -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 diff --git a/mall-pay/src/main/java/com/suisung/mall/pay/controller/admin/PayController.java b/mall-pay/src/main/java/com/suisung/mall/pay/controller/admin/PayController.java index 2c2ea51c..9ccea544 100644 --- a/mall-pay/src/main/java/com/suisung/mall/pay/controller/admin/PayController.java +++ b/mall-pay/src/main/java/com/suisung/mall/pay/controller/admin/PayController.java @@ -333,6 +333,12 @@ public class PayController { return flag; } + /** + * 订单退款(远程调用) + * + * @param shopOrderReturnList 退款列表 + * @return 是否成功 + */ @RequestMapping(value = "/doRefund", method = RequestMethod.POST) public boolean doRefund(@RequestBody List shopOrderReturnList) { boolean flag = false; diff --git a/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/PayConsumeTradeServiceImpl.java b/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/PayConsumeTradeServiceImpl.java index c17a44f3..ef1f511f 100644 --- a/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/PayConsumeTradeServiceImpl.java +++ b/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/PayConsumeTradeServiceImpl.java @@ -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.*; @@ -174,7 +175,7 @@ public class PayConsumeTradeServiceImpl extends BaseServiceImpl returnRows) { + log.info("执行退款操作开始"); + + if (CollUtil.isEmpty(returnRows)) { + log.warn("退款订单列表为空,停止退款操作"); + return false; + } + + // 存储已支付的退货单ID列表 + List paidReturnIdList = new ArrayList<>(); + + // 获取是否原路退回配置,默认为 false + boolean refundToOriginal = accountBaseConfigService.getConfig("order_refund_flag", false); + + // 提取所有订单ID,并去重 + List orderIdList = returnRows.stream().map(ShopOrderReturn::getOrder_id).distinct().collect(Collectors.toList()); + + // 批量获取订单数据列表 + List orderDataList = shopService.getsShopOrderData(orderIdList); + + // 提取所有店铺ID,并去重 + List storeIdList = returnRows.stream().map(ShopOrderReturn::getStore_id).distinct().collect(Collectors.toList()); + // 批量获取店铺基础信息列表 + List storeList = shopService.getsShopStoreBase(storeIdList); + + // 提取所有买家用户ID,并去重 + List userIdList = returnRows.stream().map(ShopOrderReturn::getBuyer_user_id).distinct().collect(Collectors.toList()); + // 批量获取买家用户资源列表(不使用缓存,防止缓存被保存导致回滚异常) + List payUserResourceList = payUserResourceService.listByIds(userIdList); + // 批量获取订单信息列表 + List orderInfoList = shopService.getsShopOrderInfo(orderIdList); + + // 提取所有退货单ID,并去重 + List returnIdList = returnRows.stream().map(ShopOrderReturn::getReturn_id).distinct().collect(Collectors.toList()); + // 如果退货单ID列表为空,则直接返回 false + if (CollUtil.isEmpty(returnIdList)) { + log.warn("退货单ID列表为空,无法进行退款操作"); + return false; + } + + // 构建查询参数,批量查询退货单商品信息 + Map queryParams = new HashMap<>(); + queryParams.put("return_id:in", returnIdList); + List orderReturnItemList = shopService.findShopOrderReturnItem(queryParams); + // 如果未找到退货单商品信息,则抛出业务异常 + if (CollUtil.isEmpty(orderReturnItemList)) { + String errorMsg = I18nUtil._("没有找到相关的退货商品信息,无法进行退款操作"); + log.error(errorMsg + ", returnIdList:{}", returnIdList); + throw new ApiException(errorMsg); + } + + // 提取所有订单商品ID,并去重 + List orderItemIdList = orderReturnItemList.stream().map(ShopOrderReturnItem::getOrder_item_id).distinct().collect(Collectors.toList()); + // 批量获取订单商品列表 + List 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 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 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 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 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 orderReturnItemRows = orderReturnItemList.stream().filter(s -> ObjectUtil.equal(s.getReturn_id(), returnId)).collect(Collectors.toList()); + // 如果订单商品列表不为空 + if (CollUtil.isNotEmpty(orderItemList)) { + + // 创建订单商品列表 + List orderItemRows = new ArrayList<>(); + // 循环处理每个退货单项目 + for (ShopOrderReturnItem orderReturnItemRow : orderReturnItemRows) { + + // 获取订单商品ID + Long orderItemId = orderReturnItemRow.getOrder_item_id(); + // 从订单商品列表中查找当前订单商品 + Optional 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 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 return_rows) { + // @Override + public boolean doRefundBak(List return_rows) { List paid_return_id_row = new ArrayList<>(); // 原路退回标记 @@ -1026,18 +1559,17 @@ public class PayConsumeTradeServiceImpl extends BaseServiceImpl order_info_rows = shopService.getsShopOrderInfo(order_id_rows); List return_ids = return_rows.stream().map(ShopOrderReturn::getReturn_id).distinct().collect(Collectors.toList()); - - List orderReturnItemList = new ArrayList<>(); - - if (CollUtil.isNotEmpty(return_ids)) { - Map queryParams = new HashMap(); - queryParams.put("return_id:in", return_ids); - orderReturnItemList = shopService.findShopOrderReturnItem(queryParams); - } else { - //异常,不应该出现。 + if (CollUtil.isEmpty(return_ids)) { return false; } + Map queryParams = new HashMap(); + queryParams.put("return_id:in", return_ids); + List orderReturnItemList = shopService.findShopOrderReturnItem(queryParams); + if (CollUtil.isEmpty(orderReturnItemList)) { + throw new ApiException(I18nUtil._("没有找到相关的退货商品信息!")); + } + List order_item_ids = orderReturnItemList.stream().map(ShopOrderReturnItem::getOrder_item_id).distinct().collect(Collectors.toList()); List orderItemList = shopService.getsShopOrderItem(order_item_ids); @@ -1207,7 +1739,6 @@ public class PayConsumeTradeServiceImpl extends BaseServiceImpl 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); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityGroupbookingServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityGroupbookingServiceImpl.java index 070bdbdd..f15c1f56 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityGroupbookingServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityGroupbookingServiceImpl.java @@ -746,7 +746,7 @@ public class ShopActivityGroupbookingServiceImpl extends BaseServiceImpl { 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 { * @param return_next_state_id * @return */ - boolean review(List return_ids, List return_rows, Integer state_id, Integer return_next_state_id); + boolean processReviewList(List return_ids, List return_rows, Integer state_id, Integer return_next_state_id); /** * 卖家拒绝退款 diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java index a0ef2576..4a54206c 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java @@ -744,7 +744,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl return_ids = Convert.toList(String.class, str_return_id); @@ -1140,17 +1141,19 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl return_ids, List return_rows, Integer state_id, Integer return_next_state_id) { + public boolean processReviewList(List return_ids, List 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