feat(shop): 更新数据库配置并添加订单状态关联查询
- 修改 application-glt2.yml 中的数据源配置,将数据库从 modules 更改为 gltdb - 修改 application-glt3.yml 中的数据源配置,将数据库从 modules 更改为 gltdb - 在 ShopDealerCapital 实体类中添加 orderStatus 字段用于存储订单状态 - 更新 ShopDealerCapitalMapper.xml 查询语句,关联 shop_order 表获取订单状态 - 添加 LEFT JOIN 条件连接 shop_order 表以获取订单状态信息
This commit is contained in:
@@ -146,7 +146,9 @@ public class DealerOrderSettlement10584Task {
|
||||
.eq(ShopOrder::getTenantId, TENANT_ID)
|
||||
.eq(ShopOrder::getDeleted, 0)
|
||||
.eq(ShopOrder::getPayStatus, true)
|
||||
.eq(ShopOrder::getIsSettled, 0);
|
||||
.eq(ShopOrder::getIsSettled, 0)
|
||||
// 退款/取消订单不结算,避免“退款后仍发放分红/分润/佣金”
|
||||
.and(w -> w.notIn(ShopOrder::getOrderStatus, 2, 4, 5, 6, 7).or().isNull(ShopOrder::getOrderStatus));
|
||||
|
||||
if (waterFormIds != null && !waterFormIds.isEmpty()) {
|
||||
qw.and(w -> w.eq(ShopOrder::getDeliveryStatus, 20).or().in(ShopOrder::getFormId, waterFormIds));
|
||||
@@ -162,7 +164,9 @@ public class DealerOrderSettlement10584Task {
|
||||
LambdaUpdateWrapper<ShopOrder> uw = new LambdaUpdateWrapper<ShopOrder>()
|
||||
.eq(ShopOrder::getOrderId, orderId)
|
||||
.eq(ShopOrder::getTenantId, TENANT_ID)
|
||||
.eq(ShopOrder::getIsSettled, 0);
|
||||
.eq(ShopOrder::getIsSettled, 0)
|
||||
// 二次防御:退款/取消订单不允许被“认领结算”
|
||||
.and(w -> w.notIn(ShopOrder::getOrderStatus, 2, 4, 5, 6, 7).or().isNull(ShopOrder::getOrderStatus));
|
||||
|
||||
if (waterFormIds != null && !waterFormIds.isEmpty()) {
|
||||
uw.and(w -> w.eq(ShopOrder::getDeliveryStatus, 20).or().in(ShopOrder::getFormId, waterFormIds));
|
||||
|
||||
@@ -105,6 +105,8 @@ public class ShopOrderController extends BaseController {
|
||||
private ShopStoreFenceService shopStoreFenceService;
|
||||
@Resource
|
||||
private GltTicketRevokeService gltTicketRevokeService;
|
||||
@Resource
|
||||
private ShopDealerCommissionRollbackService shopDealerCommissionRollbackService;
|
||||
|
||||
@Operation(summary = "分页查询订单")
|
||||
@GetMapping("/page")
|
||||
@@ -559,6 +561,24 @@ public class ShopOrderController extends BaseController {
|
||||
current.getTenantId(), current.getOrderId(), current.getOrderNo(), e);
|
||||
}
|
||||
|
||||
// 退款成功后回退分红/分润/佣金(从 ShopDealerUser 中扣回;以 ShopDealerCapital 明细为准)
|
||||
try {
|
||||
Integer tenantId = ObjectUtil.defaultIfNull(current.getTenantId(), getTenantId());
|
||||
ShopOrder rollbackOrder = new ShopOrder();
|
||||
rollbackOrder.setTenantId(tenantId);
|
||||
rollbackOrder.setOrderNo(current.getOrderNo());
|
||||
rollbackOrder.setPayPrice(current.getPayPrice());
|
||||
rollbackOrder.setTotalPrice(current.getTotalPrice());
|
||||
boolean rollbackOk = shopDealerCommissionRollbackService.rollbackOnOrderRefund(rollbackOrder, refundAmount);
|
||||
if (!rollbackOk) {
|
||||
logger.error("退款成功但回退分红/分润/佣金失败 - tenantId={}, orderId={}, orderNo={}",
|
||||
tenantId, current.getOrderId(), current.getOrderNo());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("退款成功但回退分红/分润/佣金异常 - tenantId={}, orderId={}, orderNo={}",
|
||||
current.getTenantId(), current.getOrderId(), current.getOrderNo(), e);
|
||||
}
|
||||
|
||||
logger.info("订单退款请求成功 - 订单号: {}, 退款单号: {}, 微信退款单号: {}",
|
||||
current.getOrderNo(), refundNo, refundResponse.getTransactionId());
|
||||
return success("退款成功");
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.gxwebsoft.shop.service;
|
||||
|
||||
import com.gxwebsoft.shop.entity.ShopOrder;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 分销/分红/分润:订单退款回退
|
||||
*/
|
||||
public interface ShopDealerCommissionRollbackService {
|
||||
|
||||
/**
|
||||
* 订单退款成功后,按订单号回退已入账(冻结/可提现)的分销佣金/分红/分润等金额。
|
||||
*
|
||||
* @param order 订单(必须包含 tenantId、orderNo)
|
||||
* @param refundAmount 退款金额(允许为空;为空则按全额退款处理)
|
||||
* @return true=执行成功或无可回退数据;false=执行失败
|
||||
*/
|
||||
boolean rollbackOnOrderRefund(ShopOrder order, BigDecimal refundAmount);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
package com.gxwebsoft.shop.service.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.gxwebsoft.shop.entity.ShopDealerCapital;
|
||||
import com.gxwebsoft.shop.entity.ShopDealerOrder;
|
||||
import com.gxwebsoft.shop.entity.ShopDealerUser;
|
||||
import com.gxwebsoft.shop.entity.ShopOrder;
|
||||
import com.gxwebsoft.shop.service.ShopDealerCapitalService;
|
||||
import com.gxwebsoft.shop.service.ShopDealerCommissionRollbackService;
|
||||
import com.gxwebsoft.shop.service.ShopDealerOrderService;
|
||||
import com.gxwebsoft.shop.service.ShopDealerUserService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ShopDealerCommissionRollbackServiceImpl implements ShopDealerCommissionRollbackService {
|
||||
|
||||
private static final int FLOW_TYPE_COMMISSION_INCOME = 10;
|
||||
private static final int FLOW_TYPE_COMMISSION_UNFREEZE_MARKER = 50;
|
||||
private static final int FLOW_TYPE_DELIVERY_REWARD = 60;
|
||||
|
||||
@Resource
|
||||
private ShopDealerCapitalService shopDealerCapitalService;
|
||||
|
||||
@Resource
|
||||
private ShopDealerUserService shopDealerUserService;
|
||||
|
||||
@Resource
|
||||
private ShopDealerOrderService shopDealerOrderService;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean rollbackOnOrderRefund(ShopOrder order, BigDecimal refundAmount) {
|
||||
if (order == null || order.getTenantId() == null || order.getOrderNo() == null || order.getOrderNo().isBlank()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Integer tenantId = order.getTenantId();
|
||||
String orderNo = order.getOrderNo();
|
||||
|
||||
BigDecimal orderBaseAmount = ObjectUtil.defaultIfNull(order.getPayPrice(), order.getTotalPrice());
|
||||
BigDecimal ratio = resolveRefundRatio(orderBaseAmount, refundAmount);
|
||||
|
||||
List<ShopDealerCapital> capitals = shopDealerCapitalService.list(
|
||||
new LambdaQueryWrapper<ShopDealerCapital>()
|
||||
.eq(ShopDealerCapital::getTenantId, tenantId)
|
||||
.eq(ShopDealerCapital::getOrderNo, orderNo)
|
||||
.in(ShopDealerCapital::getFlowType, FLOW_TYPE_COMMISSION_INCOME, FLOW_TYPE_DELIVERY_REWARD)
|
||||
.isNotNull(ShopDealerCapital::getUserId)
|
||||
.isNotNull(ShopDealerCapital::getMoney)
|
||||
.gt(ShopDealerCapital::getMoney, BigDecimal.ZERO)
|
||||
);
|
||||
|
||||
if (capitals == null || capitals.isEmpty()) {
|
||||
// 仍标记分销订单失效,避免后续统计误判
|
||||
markDealerOrderInvalid(tenantId, orderNo);
|
||||
return true;
|
||||
}
|
||||
|
||||
Map<Integer, BigDecimal> freezeDeductByUser = new HashMap<>();
|
||||
Map<Integer, BigDecimal> moneyDeductByUser = new HashMap<>();
|
||||
Map<Integer, BigDecimal> totalDeductByUser = new HashMap<>();
|
||||
|
||||
for (ShopDealerCapital cap : capitals) {
|
||||
Integer dealerUserId = cap.getUserId();
|
||||
BigDecimal amount = cap.getMoney();
|
||||
if (dealerUserId == null || amount == null || amount.signum() <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BigDecimal rollbackAmount = amount.multiply(ratio).setScale(2, RoundingMode.HALF_UP);
|
||||
if (rollbackAmount.signum() <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
totalDeductByUser.merge(dealerUserId, rollbackAmount, BigDecimal::add);
|
||||
|
||||
Integer flowType = cap.getFlowType();
|
||||
if (flowType != null && flowType == FLOW_TYPE_DELIVERY_REWARD) {
|
||||
moneyDeductByUser.merge(dealerUserId, rollbackAmount, BigDecimal::add);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 佣金收入:若已解冻(有 flowType=50 marker),则从可提现扣回;否则从冻结扣回
|
||||
boolean unfrozen = hasUnfreezeMarker(tenantId, cap);
|
||||
if (unfrozen) {
|
||||
moneyDeductByUser.merge(dealerUserId, rollbackAmount, BigDecimal::add);
|
||||
} else {
|
||||
freezeDeductByUser.merge(dealerUserId, rollbackAmount, BigDecimal::add);
|
||||
}
|
||||
}
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
for (Map.Entry<Integer, BigDecimal> entry : totalDeductByUser.entrySet()) {
|
||||
Integer dealerUserId = entry.getKey();
|
||||
BigDecimal totalDeduct = entry.getValue();
|
||||
if (dealerUserId == null || totalDeduct == null || totalDeduct.signum() <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BigDecimal freezeDeduct = freezeDeductByUser.getOrDefault(dealerUserId, BigDecimal.ZERO);
|
||||
BigDecimal moneyDeduct = moneyDeductByUser.getOrDefault(dealerUserId, BigDecimal.ZERO);
|
||||
|
||||
LambdaUpdateWrapper<ShopDealerUser> uw = new LambdaUpdateWrapper<ShopDealerUser>()
|
||||
.eq(ShopDealerUser::getTenantId, tenantId)
|
||||
.eq(ShopDealerUser::getUserId, dealerUserId)
|
||||
.setSql("total_money = IFNULL(total_money,0) - " + totalDeduct.toPlainString())
|
||||
.set(ShopDealerUser::getUpdateTime, now);
|
||||
|
||||
if (freezeDeduct.signum() > 0) {
|
||||
uw.setSql("freeze_money = IFNULL(freeze_money,0) - " + freezeDeduct.toPlainString());
|
||||
}
|
||||
if (moneyDeduct.signum() > 0) {
|
||||
uw.setSql("money = IFNULL(money,0) - " + moneyDeduct.toPlainString());
|
||||
}
|
||||
|
||||
boolean updated = shopDealerUserService.update(uw);
|
||||
if (!updated) {
|
||||
log.warn("订单退款扣回分销金额失败:未找到分销账户 - tenantId={}, orderNo={}, dealerUserId={}, totalDeduct={}, freezeDeduct={}, moneyDeduct={}",
|
||||
tenantId, orderNo, dealerUserId, totalDeduct, freezeDeduct, moneyDeduct);
|
||||
}
|
||||
}
|
||||
|
||||
markDealerOrderInvalid(tenantId, orderNo);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean hasUnfreezeMarker(Integer tenantId, ShopDealerCapital cap) {
|
||||
if (tenantId == null || cap == null || cap.getId() == null || cap.getUserId() == null || cap.getOrderNo() == null) {
|
||||
return false;
|
||||
}
|
||||
String markerComment = buildUnfreezeMarkerComment(cap.getId());
|
||||
return shopDealerCapitalService.count(
|
||||
new LambdaQueryWrapper<ShopDealerCapital>()
|
||||
.eq(ShopDealerCapital::getTenantId, tenantId)
|
||||
.eq(ShopDealerCapital::getFlowType, FLOW_TYPE_COMMISSION_UNFREEZE_MARKER)
|
||||
.eq(ShopDealerCapital::getUserId, cap.getUserId())
|
||||
.eq(ShopDealerCapital::getOrderNo, cap.getOrderNo())
|
||||
.eq(ShopDealerCapital::getComments, markerComment)
|
||||
) > 0;
|
||||
}
|
||||
|
||||
private String buildUnfreezeMarkerComment(Integer capitalId) {
|
||||
return "佣金解冻(capitalId=" + capitalId + ")";
|
||||
}
|
||||
|
||||
private BigDecimal resolveRefundRatio(BigDecimal orderBaseAmount, BigDecimal refundAmount) {
|
||||
if (refundAmount == null || refundAmount.signum() <= 0) {
|
||||
return BigDecimal.ONE;
|
||||
}
|
||||
if (orderBaseAmount == null || orderBaseAmount.signum() <= 0) {
|
||||
return BigDecimal.ONE;
|
||||
}
|
||||
if (refundAmount.compareTo(orderBaseAmount) >= 0) {
|
||||
return BigDecimal.ONE;
|
||||
}
|
||||
return refundAmount.divide(orderBaseAmount, 10, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
private void markDealerOrderInvalid(Integer tenantId, String orderNo) {
|
||||
if (tenantId == null || orderNo == null || orderNo.isBlank()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
shopDealerOrderService.update(
|
||||
new LambdaUpdateWrapper<ShopDealerOrder>()
|
||||
.eq(ShopDealerOrder::getTenantId, tenantId)
|
||||
.eq(ShopDealerOrder::getOrderNo, orderNo)
|
||||
.set(ShopDealerOrder::getIsInvalid, 1)
|
||||
.set(ShopDealerOrder::getUpdateTime, LocalDateTime.now())
|
||||
);
|
||||
} catch (Exception e) {
|
||||
log.warn("订单退款标记分销订单失效失败 - tenantId={}, orderNo={}", tenantId, orderNo, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user