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:
2026-03-16 13:10:26 +08:00
parent 3f546f7e70
commit 7fe347d7bc
4 changed files with 236 additions and 2 deletions

View File

@@ -146,7 +146,9 @@ public class DealerOrderSettlement10584Task {
.eq(ShopOrder::getTenantId, TENANT_ID) .eq(ShopOrder::getTenantId, TENANT_ID)
.eq(ShopOrder::getDeleted, 0) .eq(ShopOrder::getDeleted, 0)
.eq(ShopOrder::getPayStatus, true) .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()) { if (waterFormIds != null && !waterFormIds.isEmpty()) {
qw.and(w -> w.eq(ShopOrder::getDeliveryStatus, 20).or().in(ShopOrder::getFormId, waterFormIds)); 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>() LambdaUpdateWrapper<ShopOrder> uw = new LambdaUpdateWrapper<ShopOrder>()
.eq(ShopOrder::getOrderId, orderId) .eq(ShopOrder::getOrderId, orderId)
.eq(ShopOrder::getTenantId, TENANT_ID) .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()) { if (waterFormIds != null && !waterFormIds.isEmpty()) {
uw.and(w -> w.eq(ShopOrder::getDeliveryStatus, 20).or().in(ShopOrder::getFormId, waterFormIds)); uw.and(w -> w.eq(ShopOrder::getDeliveryStatus, 20).or().in(ShopOrder::getFormId, waterFormIds));

View File

@@ -105,6 +105,8 @@ public class ShopOrderController extends BaseController {
private ShopStoreFenceService shopStoreFenceService; private ShopStoreFenceService shopStoreFenceService;
@Resource @Resource
private GltTicketRevokeService gltTicketRevokeService; private GltTicketRevokeService gltTicketRevokeService;
@Resource
private ShopDealerCommissionRollbackService shopDealerCommissionRollbackService;
@Operation(summary = "分页查询订单") @Operation(summary = "分页查询订单")
@GetMapping("/page") @GetMapping("/page")
@@ -559,6 +561,24 @@ public class ShopOrderController extends BaseController {
current.getTenantId(), current.getOrderId(), current.getOrderNo(), e); 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("订单退款请求成功 - 订单号: {}, 退款单号: {}, 微信退款单号: {}", logger.info("订单退款请求成功 - 订单号: {}, 退款单号: {}, 微信退款单号: {}",
current.getOrderNo(), refundNo, refundResponse.getTransactionId()); current.getOrderNo(), refundNo, refundResponse.getTransactionId());
return success("退款成功"); return success("退款成功");

View File

@@ -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);
}

View File

@@ -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);
}
}
}