1.调整订单分销、分润、分红结算算法功能
2.商品订单支付成功增加执行分销员分销、统计门店/服务商分销业务、执行总分红业务功能 3.配送员完成配送增加解冻商品订单业务功能 4.订单分销记录增加关联结算单号、结算状态字段,方便门店/服务商做计算做准备
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -2,11 +2,11 @@ package com.gxwebsoft.glt.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.gxwebsoft.common.core.annotation.IgnoreTenant;
|
||||
import com.gxwebsoft.glt.entity.GltTicketTemplate;
|
||||
import com.gxwebsoft.glt.entity.GltUserTicket;
|
||||
import com.gxwebsoft.glt.entity.GltUserTicketLog;
|
||||
import com.gxwebsoft.glt.entity.GltUserTicketRelease;
|
||||
import com.gxwebsoft.glt.task.DealerOrderSettlement10584Task;
|
||||
import com.gxwebsoft.shop.entity.ShopOrder;
|
||||
import com.gxwebsoft.shop.entity.ShopOrderGoods;
|
||||
import com.gxwebsoft.shop.service.ShopOrderGoodsService;
|
||||
@@ -15,7 +15,6 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
@@ -56,6 +55,7 @@ public class GltTicketIssueService {
|
||||
private final GltUserTicketReleaseService gltUserTicketReleaseService;
|
||||
private final GltUserTicketLogService gltUserTicketLogService;
|
||||
private final TransactionTemplate transactionTemplate;
|
||||
private final DealerOrderSettlement10584Task dealerOrderSettlement;
|
||||
|
||||
/**
|
||||
* 扫描“今日订单”,执行套票发放。
|
||||
@@ -140,7 +140,10 @@ public class GltTicketIssueService {
|
||||
//1.发送水票
|
||||
suerTicketRelease(orderNo, tenantId);
|
||||
|
||||
//2.优惠券扣减、积分发送、消息通知
|
||||
//2.执行分销员分销、统计门店/服务商分销业务
|
||||
dealerOrderSettlement.orderSettlement(orderNo);
|
||||
|
||||
//3.执行平台分红业务 TODO 待开发
|
||||
|
||||
}
|
||||
|
||||
@@ -149,6 +152,7 @@ public class GltTicketIssueService {
|
||||
* @param orderNo 订单号
|
||||
* @param tenantId 租户ID
|
||||
*/
|
||||
@Transactional
|
||||
public void suerTicketRelease(String orderNo, Integer tenantId){
|
||||
//1.订单为空跳过执行
|
||||
ShopOrder shopOrder = shopOrderService.getByOrderNo(orderNo, tenantId);
|
||||
|
||||
@@ -4,6 +4,8 @@ import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.common.core.enums.ShopDealerCapitalUpdateEnum;
|
||||
import com.gxwebsoft.common.core.enums.ShopDealerTypeEnum;
|
||||
import com.gxwebsoft.common.core.exception.BusinessException;
|
||||
import com.gxwebsoft.common.core.web.PageParam;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
@@ -19,6 +21,7 @@ import com.gxwebsoft.glt.param.GltTicketOrderParam;
|
||||
import com.gxwebsoft.glt.service.GltTicketOrderService;
|
||||
import com.gxwebsoft.glt.service.GltUserTicketLogService;
|
||||
import com.gxwebsoft.glt.service.GltUserTicketService;
|
||||
import com.gxwebsoft.shop.dto.ShopDealerUserReduceDto;
|
||||
import com.gxwebsoft.shop.entity.*;
|
||||
import com.gxwebsoft.shop.mapper.ShopUserAddressMapper;
|
||||
import com.gxwebsoft.shop.service.ShopDealerCapitalService;
|
||||
@@ -765,6 +768,25 @@ public class GltTicketOrderServiceImpl extends ServiceImpl<GltTicketOrderMapper,
|
||||
}
|
||||
}
|
||||
|
||||
//查询未完成订单,完成资金解冻
|
||||
LambdaQueryWrapper<ShopOrder> orderLambdaQueryWrapper;
|
||||
if(shopOrderId != null){
|
||||
orderLambdaQueryWrapper = new LambdaQueryWrapper<ShopOrder>().eq(ShopOrder::getOrderId, shopOrderId).eq(ShopOrder::getOrderStatus, 0);
|
||||
}else{
|
||||
orderLambdaQueryWrapper = new LambdaQueryWrapper<ShopOrder>().eq(ShopOrder::getOrderId, shopOrderNo).eq(ShopOrder::getOrderStatus, 0);
|
||||
}
|
||||
ShopOrder order = shopOrderService.getOne(orderLambdaQueryWrapper);
|
||||
if(order != null){
|
||||
ShopDealerUserReduceDto reduceDto = new ShopDealerUserReduceDto();
|
||||
reduceDto.setTypeEnum(ShopDealerTypeEnum.DEFROST);
|
||||
reduceDto.setOrderUserId(order.getUserId());
|
||||
reduceDto.setOrderNo(order.getOrderNo());
|
||||
reduceDto.setUpdateEnum(ShopDealerCapitalUpdateEnum.FREEZE_MONEY_THAW);
|
||||
|
||||
//按订单号资金解冻
|
||||
shopDealerUserService.reduceBalance(reduceDto);
|
||||
}
|
||||
|
||||
LambdaUpdateWrapper<ShopOrder> uw = new LambdaUpdateWrapper<ShopOrder>()
|
||||
.eq(ShopOrder::getTenantId, tenantId)
|
||||
.eq(ShopOrder::getDeleted, 0)
|
||||
@@ -776,7 +798,6 @@ public class GltTicketOrderServiceImpl extends ServiceImpl<GltTicketOrderMapper,
|
||||
} else {
|
||||
uw.eq(ShopOrder::getOrderNo, shopOrderNo);
|
||||
}
|
||||
|
||||
boolean updated = shopOrderService.update(uw);
|
||||
if (updated) {
|
||||
return;
|
||||
|
||||
@@ -1,41 +1,37 @@
|
||||
package com.gxwebsoft.glt.task;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.gxwebsoft.common.core.annotation.IgnoreTenant;
|
||||
import com.gxwebsoft.glt.entity.GltTicketTemplate;
|
||||
import com.gxwebsoft.glt.service.GltTicketTemplateService;
|
||||
import com.gxwebsoft.shop.entity.ShopDealerCapital;
|
||||
import com.gxwebsoft.shop.entity.ShopDealerOrder;
|
||||
import com.gxwebsoft.shop.entity.ShopDealerReferee;
|
||||
import com.gxwebsoft.shop.entity.ShopDealerSetting;
|
||||
import com.gxwebsoft.shop.entity.ShopDealerUser;
|
||||
import com.gxwebsoft.shop.entity.ShopGoods;
|
||||
import com.gxwebsoft.shop.entity.ShopOrder;
|
||||
import com.gxwebsoft.shop.entity.ShopOrderGoods;
|
||||
import com.gxwebsoft.common.core.enums.ShopDealerCapitalUpdateEnum;
|
||||
import com.gxwebsoft.common.core.enums.ShopDealerTypeEnum;
|
||||
import com.gxwebsoft.common.system.entity.User;
|
||||
import com.gxwebsoft.common.system.mapper.UserMapper;
|
||||
import com.gxwebsoft.shop.service.ShopDealerCapitalService;
|
||||
import com.gxwebsoft.shop.service.ShopDealerOrderService;
|
||||
import com.gxwebsoft.shop.service.ShopDealerRefereeService;
|
||||
import com.gxwebsoft.shop.service.ShopDealerSettingService;
|
||||
import com.gxwebsoft.shop.service.ShopDealerUserService;
|
||||
import com.gxwebsoft.shop.service.ShopGoodsService;
|
||||
import com.gxwebsoft.shop.service.ShopOrderService;
|
||||
import com.gxwebsoft.shop.service.ShopOrderGoodsService;
|
||||
import com.gxwebsoft.glt.entity.GltTicketTemplate;
|
||||
import com.gxwebsoft.glt.service.GltTicketTemplateService;
|
||||
import com.gxwebsoft.shop.dto.ShopDealerUserReduceDto;
|
||||
import com.gxwebsoft.shop.entity.*;
|
||||
import com.gxwebsoft.shop.mapper.ShopDealerRefereeMapper;
|
||||
import com.gxwebsoft.shop.mapper.ShopOrderMapper;
|
||||
import com.gxwebsoft.shop.service.*;
|
||||
import com.gxwebsoft.shop.util.UpstreamUserFinder;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.gxwebsoft.shop.vo.ShopOrderGoodsVO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* 租户10584:分销订单结算任务
|
||||
@@ -50,7 +46,6 @@ public class DealerOrderSettlement10584Task {
|
||||
|
||||
private static final BigDecimal RATE_0_10 = new BigDecimal("0.10");
|
||||
private static final BigDecimal RATE_0_05 = new BigDecimal("0.05");
|
||||
private static final BigDecimal RATE_0_03 = new BigDecimal("0.03");
|
||||
private static final BigDecimal RATE_0_02 = new BigDecimal("0.02");
|
||||
private static final BigDecimal RATE_0_01 = new BigDecimal("0.01");
|
||||
private static final BigDecimal TOTAL_DEALER_DIVIDEND_RATE = RATE_0_01;
|
||||
@@ -92,14 +87,23 @@ public class DealerOrderSettlement10584Task {
|
||||
@Resource
|
||||
private GltTicketTemplateService gltTicketTemplateService;
|
||||
|
||||
@Resource
|
||||
private ShopOrderMapper shopOrderMapper;
|
||||
|
||||
@Resource
|
||||
private ShopDealerRefereeMapper shopDealerRefereeMapper;
|
||||
|
||||
/**
|
||||
* 每10秒执行一次。
|
||||
*/
|
||||
@Scheduled(cron = "0/10 * * * * ?")
|
||||
// @Scheduled(cron = "0/10 * * * * ?")
|
||||
@IgnoreTenant("该定时任务仅处理租户10584,但需要显式按tenantId过滤,避免定时任务线程无租户上下文导致查询异常")
|
||||
public void settleTenant10584Orders() {
|
||||
try {
|
||||
//获取水票模板对应的商品信息列表
|
||||
Set<Integer> waterFormIds = loadWaterFormIds();
|
||||
|
||||
//查询商品列表存在已支付未核销订单数据
|
||||
List<ShopOrder> orders = findUnsettledPaidOrders(waterFormIds);
|
||||
if (orders.isEmpty()) {
|
||||
return;
|
||||
@@ -108,7 +112,11 @@ public class DealerOrderSettlement10584Task {
|
||||
// Per-run caches to reduce DB chatter across orders.
|
||||
Map<Integer, Integer> level1ParentCache = new HashMap<>();
|
||||
Map<Integer, Boolean> shopRoleCache = new HashMap<>();
|
||||
|
||||
//获取系统设置分销等级
|
||||
DealerBasicSetting dealerBasicSetting = findDealerBasicSetting();
|
||||
|
||||
//获取分销员type=2第一个分销人作为平台总分红人
|
||||
ShopDealerUser totalDealerUser = findTotalDealerUser();
|
||||
if (totalDealerUser == null || totalDealerUser.getUserId() == null) {
|
||||
log.warn("未找到分红账号,订单仍可结算但不会发放分红 - tenantId={}", TENANT_ID);
|
||||
@@ -124,6 +132,7 @@ public class DealerOrderSettlement10584Task {
|
||||
try {
|
||||
transactionTemplate.executeWithoutResult(status -> {
|
||||
// 先“认领”订单:并发/多实例下避免重复结算(update=0 表示被其他线程/实例处理)
|
||||
//更新商品订单为已结算状态
|
||||
if (!claimOrderToSettle(order.getOrderId(), waterFormIds)) {
|
||||
return;
|
||||
}
|
||||
@@ -138,6 +147,88 @@ public class DealerOrderSettlement10584Task {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 每10分钟执行一次。
|
||||
*/
|
||||
@Scheduled(cron = "0 0/10 * * * ?")
|
||||
@IgnoreTenant("该定时任务仅处理租户10584,但需要显式按tenantId过滤,避免定时任务线程无租户上下文导致查询异常")
|
||||
public void settleTenant10584OrdersV2() {
|
||||
try {
|
||||
//获取水票模板对应的商品信息列表
|
||||
Set<Integer> waterFormIds = loadWaterFormIds();
|
||||
|
||||
//查询商品列表存在已支付未核销订单数据【isSettled = 0, payStatus= 1, orderStatus 不在列表(2, 3, 4, 5, 6, 7)】
|
||||
List<ShopOrder> orders = findUnsettledPaidOrders(waterFormIds);
|
||||
if (orders.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Per-run caches to reduce DB chatter across orders.
|
||||
Map<Integer, Integer> level1ParentCache = new HashMap<>();
|
||||
Map<Integer, Boolean> shopRoleCache = new HashMap<>();
|
||||
|
||||
//获取系统设置分销等级
|
||||
DealerBasicSetting dealerBasicSetting = findDealerBasicSetting();
|
||||
|
||||
//获取分销员type=2第一个分销人作为平台总分红人
|
||||
ShopDealerUser totalDealerUser = findTotalDealerUser();
|
||||
if (totalDealerUser == null || totalDealerUser.getUserId() == null) {
|
||||
log.warn("未找到分红账号,订单仍可结算但不会发放分红 - tenantId={}", TENANT_ID);
|
||||
}
|
||||
log.debug("租户{}分销设置 - level={}", TENANT_ID, dealerBasicSetting.level);
|
||||
|
||||
log.info("租户{}待结算订单数: {}, orderNos(sample)={}",
|
||||
TENANT_ID,
|
||||
orders.size(),
|
||||
orders.stream().limit(10).map(ShopOrder::getOrderNo).toList());
|
||||
|
||||
for (ShopOrder order : orders) {
|
||||
try {
|
||||
transactionTemplate.executeWithoutResult(status -> {
|
||||
// 先“认领”订单:并发/多实例下避免重复结算(update=0 表示被其他线程/实例处理)
|
||||
//更新商品订单为已结算状态
|
||||
if (!claimOrderToSettle(order.getOrderId(), waterFormIds)) {
|
||||
return;
|
||||
}
|
||||
settleOneOrderV2(order, level1ParentCache, shopRoleCache, totalDealerUser, dealerBasicSetting.level);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
log.error("订单结算失败,将回滚本订单并在下次任务重试 - orderId={}, orderNo={}", order.getOrderId(), order.getOrderNo(), e);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("租户{}分销订单结算任务执行失败", TENANT_ID, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单分销金、分润金结算
|
||||
*/
|
||||
@Transactional
|
||||
public void orderSettlement(String orderNo){
|
||||
LambdaQueryWrapper<ShopOrder> orderLambdaQueryWrapper = new LambdaQueryWrapper<ShopOrder>().eq(ShopOrder::getOrderNo, orderNo).eq(ShopOrder::getIsSettled, 0).eq(ShopOrder::getPayStatus, 1);
|
||||
ShopOrder order = shopOrderService.getOne(orderLambdaQueryWrapper);
|
||||
if(order != null){
|
||||
//获取系统设置分销等级
|
||||
DealerBasicSetting dealerBasicSetting = findDealerBasicSetting();
|
||||
|
||||
//获取分销员type=2第一个分销人作为平台总分红人
|
||||
ShopDealerUser totalDealerUser = findTotalDealerUser();
|
||||
|
||||
Map<Integer, Integer> level1ParentCache = new HashMap<>();
|
||||
Map<Integer, Boolean> shopRoleCache = new HashMap<>();
|
||||
|
||||
transactionTemplate.executeWithoutResult(status -> {
|
||||
// 先“认领”订单:并发/多实例下避免重复结算(update=0 表示被其他线程/实例处理)
|
||||
//更新商品订单为已结算状态
|
||||
if (!claimOrderToSettleV2(order.getOrderId())) {
|
||||
return;
|
||||
}
|
||||
settleOneOrderV2(order, level1ParentCache, shopRoleCache, totalDealerUser, dealerBasicSetting.level);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private List<ShopOrder> findUnsettledPaidOrders(Set<Integer> waterFormIds) {
|
||||
// 租户10584约定:
|
||||
// - 普通订单:以发货为准(deliveryStatus=20)才结算;
|
||||
@@ -148,7 +239,7 @@ public class DealerOrderSettlement10584Task {
|
||||
.eq(ShopOrder::getPayStatus, true)
|
||||
.eq(ShopOrder::getIsSettled, 0)
|
||||
// 退款/取消订单不结算,避免“退款后仍发放分红/分润/佣金”
|
||||
.and(w -> w.notIn(ShopOrder::getOrderStatus, 2, 4, 5, 6, 7).or().isNull(ShopOrder::getOrderStatus));
|
||||
.and(w -> w.notIn(ShopOrder::getOrderStatus, 2, 3, 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));
|
||||
@@ -178,6 +269,17 @@ public class DealerOrderSettlement10584Task {
|
||||
return shopOrderService.update(uw);
|
||||
}
|
||||
|
||||
private boolean claimOrderToSettleV2(Integer orderId) {
|
||||
LambdaUpdateWrapper<ShopOrder> uw = new LambdaUpdateWrapper<ShopOrder>()
|
||||
.eq(ShopOrder::getOrderId, orderId)
|
||||
.eq(ShopOrder::getTenantId, TENANT_ID)
|
||||
.eq(ShopOrder::getIsSettled, 0)
|
||||
// 二次防御:退款/取消订单不允许被“认领结算”
|
||||
.and(w -> w.notIn(ShopOrder::getOrderStatus, 2, 3, 4, 5, 6, 7).or().isNull(ShopOrder::getOrderStatus));
|
||||
uw.set(ShopOrder::getIsSettled, 1);
|
||||
return shopOrderService.update(uw);
|
||||
}
|
||||
|
||||
private Set<Integer> loadWaterFormIds() {
|
||||
try {
|
||||
return gltTicketTemplateService.list(
|
||||
@@ -252,6 +354,45 @@ public class DealerOrderSettlement10584Task {
|
||||
log.info("订单结算完成 - orderId={}, orderNo={}, baseAmount={}", order.getOrderId(), order.getOrderNo(), baseAmount);
|
||||
}
|
||||
|
||||
private void settleOneOrderV2(ShopOrder order, Map<Integer, Integer> level1ParentCache, Map<Integer, Boolean> shopRoleCache,
|
||||
ShopDealerUser totalDealerUser, int dealerLevel) {
|
||||
if (order.getUserId() == null || order.getOrderNo() == null) {
|
||||
throw new IllegalStateException("订单关键信息缺失,无法结算 - orderId=" + order.getOrderId());
|
||||
}
|
||||
|
||||
BigDecimal totalPrice = order.getTotalPrice();
|
||||
BigDecimal payPrice = order.getPayPrice();
|
||||
BigDecimal rate = payPrice.divide(totalPrice, 2, RoundingMode.HALF_UP);
|
||||
|
||||
if(payPrice.compareTo(BigDecimal.ZERO) <= 0){
|
||||
log.info("订单号:{},实付金额为0,无需执行分销逻辑" + order.getOrderNo());
|
||||
return;
|
||||
}
|
||||
|
||||
//查询订单号订单所有已开启分销的商品分润信息
|
||||
List<ShopOrderGoodsVO> orderGoodsVOList = shopOrderMapper.getOrderGoodsInfo(order.getOrderNo());
|
||||
if(CollectionUtils.isNotEmpty(orderGoodsVOList)){
|
||||
// 1) 直推/间推(直接增加冻结账户余额)
|
||||
DealerRefereeCommissionV2 dealerRefereeCommission = settleDealerRefereeCommissionV2(order, rate, orderGoodsVOList, dealerLevel);
|
||||
|
||||
// 2) 门店分润上级:从下单用户开始逐级向上找,命中 ShopDealerUser.type=1 的最近两级(直推门店/间推门店)【只统计数据,不对分销账户进行处理,
|
||||
// 已日结形式,统计分销记录表:shop_dealer_order 做对应一级二级管理津贴结算】
|
||||
ShopRoleCommission shopRoleCommission = settleShopRoleRefereeCommissionV2(order, rate, orderGoodsVOList, level1ParentCache, shopRoleCache);
|
||||
|
||||
// 3) 分红:固定比率,每个订单都分 TODO 总分红未开发,还按原逻辑走
|
||||
int goodsQty = orderGoodsVOList.stream().mapToInt(ShopOrderGoodsVO::getTotalNum).sum();
|
||||
TotalDealerCommission totalDealerCommission = settleTotalDealerCommissionV2(order, goodsQty, totalDealerUser);
|
||||
|
||||
// 4) 写入分销订单记录(用于排查/统计;详细分佣以 ShopDealerCapital 为准)
|
||||
createDealerOrderRecordV2(order, dealerRefereeCommission, shopRoleCommission, totalDealerCommission);
|
||||
|
||||
log.info("订单结算完成 - orderId={}, orderNo={}, baseAmount={}", order.getOrderId(), order.getOrderNo(), payPrice);
|
||||
}else {
|
||||
log.error("订单号:{},未找到下单分销商品数据!", order.getOrderNo());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private DealerRefereeCommission settleDealerRefereeCommission(
|
||||
ShopOrder order,
|
||||
BigDecimal baseAmount,
|
||||
@@ -329,6 +470,85 @@ public class DealerOrderSettlement10584Task {
|
||||
return new DealerRefereeCommission(directDealerId, directMoney, simpleDealerId, simpleMoney, thirdDealerId, thirdMoney);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分销员分销霍金数据
|
||||
* @param order
|
||||
* @param orderGoodsVOList
|
||||
* @param dealerLevel
|
||||
* @return
|
||||
*/
|
||||
private DealerRefereeCommissionV2 settleDealerRefereeCommissionV2(ShopOrder order, BigDecimal rate, List<ShopOrderGoodsVO> orderGoodsVOList, int dealerLevel) {
|
||||
Integer directDealerId = null;
|
||||
Integer simpleDealerId = null;
|
||||
AtomicReference<BigDecimal> directMoney = new AtomicReference<>(BigDecimal.ZERO);
|
||||
AtomicReference<BigDecimal> simpleMoney = new AtomicReference<>(BigDecimal.ZERO);
|
||||
|
||||
|
||||
if (dealerLevel >= 1) {
|
||||
Integer dealerId = shopDealerRefereeMapper.getDealerIdByUserId(order.getUserId());
|
||||
if(dealerId != null){
|
||||
directDealerId = dealerId;
|
||||
}
|
||||
}
|
||||
if (dealerLevel >= 2 && directDealerId != null) {
|
||||
Integer dealerId = shopDealerRefereeMapper.getDealerIdByUserId(directDealerId);
|
||||
if(dealerId != null){
|
||||
simpleDealerId = dealerId;
|
||||
}
|
||||
}
|
||||
|
||||
if(directDealerId != null || simpleDealerId != null){
|
||||
Integer finalDirectDealerId = directDealerId;
|
||||
Integer finalSimpleDealerId = simpleDealerId;
|
||||
orderGoodsVOList.forEach(orderGoodsVO -> {
|
||||
//获取商品分润比例/金额
|
||||
BigDecimal firstMoney = orderGoodsVO.getFirstMoney();
|
||||
BigDecimal secondMoney = orderGoodsVO.getSecondMoney();
|
||||
|
||||
//按实付比例计算单项应参与分润金额
|
||||
BigDecimal itemRatePrice = orderGoodsVO.getPrice().multiply(BigDecimal.valueOf(orderGoodsVO.getTotalNum())).multiply(rate);
|
||||
|
||||
//一级分销员存在(type = 0)且单项实付金额大于0及商品设置了一级分销比例/金额
|
||||
if(finalDirectDealerId != null && itemRatePrice.compareTo(BigDecimal.ZERO) > 0 && firstMoney.compareTo(BigDecimal.ZERO) > 0){
|
||||
BigDecimal one = calcMoneyByCommissionType(itemRatePrice, firstMoney, orderGoodsVO.getTotalNum(), 2, orderGoodsVO.getCommissionType());
|
||||
directMoney.accumulateAndGet(one, BigDecimal::add);
|
||||
}
|
||||
|
||||
//一级分销员存在(type = 0)且单项实付金额大于0及商品设置了一级分销比例/金额
|
||||
if(finalSimpleDealerId != null && itemRatePrice.compareTo(BigDecimal.ZERO) > 0 && secondMoney.compareTo(BigDecimal.ZERO) > 0 ){
|
||||
BigDecimal two = calcMoneyByCommissionType(itemRatePrice, secondMoney, orderGoodsVO.getTotalNum(), 2, orderGoodsVO.getCommissionType());
|
||||
simpleMoney.accumulateAndGet(two, BigDecimal::add);
|
||||
}
|
||||
});
|
||||
|
||||
//一级分销员账户增加冻结金额
|
||||
if (directDealerId != null && directMoney.get().compareTo(BigDecimal.ZERO) > 0) {
|
||||
ShopDealerUserReduceDto reduceDto = new ShopDealerUserReduceDto();
|
||||
reduceDto.setTypeEnum(ShopDealerTypeEnum.FREEZE_ACCOUNT);
|
||||
reduceDto.setUserId(directDealerId);
|
||||
reduceDto.setOrderUserId(order.getUserId());
|
||||
reduceDto.setOrderNo(order.getOrderNo());
|
||||
reduceDto.setPrice(directMoney.get());
|
||||
reduceDto.setUpdateEnum(ShopDealerCapitalUpdateEnum.DISTRIBUTION_INCOME);
|
||||
shopDealerUserService.reduceBalance(reduceDto);
|
||||
}
|
||||
|
||||
//二级分销员账户增加冻结金额
|
||||
if (simpleDealerId != null && simpleMoney.get().compareTo(BigDecimal.ZERO) > 0) {
|
||||
ShopDealerUserReduceDto reduceDto = new ShopDealerUserReduceDto();
|
||||
reduceDto.setTypeEnum(ShopDealerTypeEnum.FREEZE_ACCOUNT);
|
||||
reduceDto.setUserId(simpleDealerId);
|
||||
reduceDto.setOrderUserId(order.getUserId());
|
||||
reduceDto.setOrderNo(order.getOrderNo());
|
||||
reduceDto.setPrice(simpleMoney.get());
|
||||
reduceDto.setUpdateEnum(ShopDealerCapitalUpdateEnum.DISTRIBUTION_INCOME);
|
||||
shopDealerUserService.reduceBalance(reduceDto);
|
||||
}
|
||||
return new DealerRefereeCommissionV2(directDealerId, directMoney.get(), simpleDealerId, simpleMoney.get());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Integer getDealerRefereeId(Integer userId) {
|
||||
return getDealerRefereeId(userId, 1);
|
||||
}
|
||||
@@ -412,6 +632,54 @@ public class DealerOrderSettlement10584Task {
|
||||
return new ShopRoleCommission(shopRoleReferees.get(0), storeDirectMoney, shopRoleReferees.get(1), storeSimpleMoney);
|
||||
}
|
||||
|
||||
private ShopRoleCommission settleShopRoleRefereeCommissionV2(ShopOrder order, BigDecimal rate, List<ShopOrderGoodsVO> orderGoodsVOList, Map<Integer, Integer> level1ParentCache, Map<Integer, Boolean> shopRoleCache) {
|
||||
List<Integer> shopRoleReferees = findFirstTwoShopRoleReferees(order.getUserId(), level1ParentCache, shopRoleCache);
|
||||
log.info("门店分润命中结果(type=1门店角色取前两级) - orderNo={}, buyerUserId={}, shopRoleReferees={}",
|
||||
order.getOrderNo(), order.getUserId(), shopRoleReferees);
|
||||
if (shopRoleReferees.isEmpty()) {
|
||||
return ShopRoleCommission.empty();
|
||||
}
|
||||
|
||||
if(CollectionUtils.isNotEmpty(shopRoleReferees)){
|
||||
Integer storeDirectUserId;
|
||||
Integer storeSimpleUserId = null;
|
||||
AtomicReference<BigDecimal> storeDirectMoney = new AtomicReference<>(BigDecimal.ZERO);
|
||||
AtomicReference<BigDecimal> storeSimpleMoney = new AtomicReference<>(BigDecimal.ZERO);
|
||||
|
||||
if(shopRoleReferees.size() == 1){
|
||||
storeDirectUserId = shopRoleReferees.get(0);
|
||||
}else {
|
||||
storeDirectUserId = shopRoleReferees.get(0);
|
||||
storeSimpleUserId = shopRoleReferees.get(1);
|
||||
}
|
||||
|
||||
|
||||
Integer finalStoreDirectUserId = storeDirectUserId;
|
||||
Integer finalStoreSimpleUserId = storeSimpleUserId;
|
||||
orderGoodsVOList.forEach(orderGoodsVO ->{
|
||||
//获取商品对应服务商管理费分润比例/金额
|
||||
BigDecimal firstMoney = orderGoodsVO.getFirstDividend();
|
||||
BigDecimal secondMoney = orderGoodsVO.getSecondDividend();
|
||||
|
||||
//按实付比例计算单项应参与分润金额
|
||||
BigDecimal itemRatePrice = orderGoodsVO.getPrice().multiply(BigDecimal.valueOf(orderGoodsVO.getTotalNum())).multiply(rate);
|
||||
|
||||
if(finalStoreDirectUserId != null && itemRatePrice.compareTo(BigDecimal.ZERO) > 0){
|
||||
BigDecimal one = calcMoneyByCommissionType(itemRatePrice, firstMoney, orderGoodsVO.getTotalNum(), 2, orderGoodsVO.getCommissionType());
|
||||
storeDirectMoney.accumulateAndGet(one, BigDecimal::add);
|
||||
}
|
||||
|
||||
if(finalStoreSimpleUserId != null && itemRatePrice.compareTo(BigDecimal.ZERO) > 0){
|
||||
BigDecimal two = calcMoneyByCommissionType(itemRatePrice, secondMoney, orderGoodsVO.getTotalNum(), 2, orderGoodsVO.getCommissionType());
|
||||
storeSimpleMoney.accumulateAndGet(two, BigDecimal::add);
|
||||
}
|
||||
});
|
||||
return new ShopRoleCommission(storeDirectUserId, storeDirectMoney.get(), storeSimpleUserId, storeSimpleMoney.get());
|
||||
}else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private TotalDealerCommission settleTotalDealerCommission(
|
||||
ShopOrder order,
|
||||
BigDecimal baseAmount,
|
||||
@@ -438,6 +706,32 @@ public class DealerOrderSettlement10584Task {
|
||||
return new TotalDealerCommission(totalDealerUser.getUserId(), money);
|
||||
}
|
||||
|
||||
private TotalDealerCommission settleTotalDealerCommissionV2(ShopOrder order, int goodsQty, ShopDealerUser totalDealerUser) {
|
||||
if (totalDealerUser == null || totalDealerUser.getUserId() == null) {
|
||||
return TotalDealerCommission.empty();
|
||||
}
|
||||
BigDecimal rate = safePositive(totalDealerUser.getRate());
|
||||
if (rate.signum() <= 0) {
|
||||
rate = TOTAL_DEALER_DIVIDEND_RATE;
|
||||
}
|
||||
BigDecimal money = calcMoneyByCommissionType(order.getPayPrice(), rate, goodsQty, DIVIDEND_SCALE, 20);
|
||||
|
||||
//一级分销员账户增加冻结金额
|
||||
if (money.compareTo(BigDecimal.ZERO) > 0) {
|
||||
ShopDealerUserReduceDto reduceDto = new ShopDealerUserReduceDto();
|
||||
reduceDto.setTypeEnum(ShopDealerTypeEnum.FREEZE_ACCOUNT);
|
||||
reduceDto.setUserId(totalDealerUser.getUserId());
|
||||
reduceDto.setOrderUserId(order.getUserId());
|
||||
reduceDto.setOrderNo(order.getOrderNo());
|
||||
reduceDto.setPrice(money);
|
||||
reduceDto.setUpdateEnum(ShopDealerCapitalUpdateEnum.DIVIDEND_INCOME);
|
||||
shopDealerUserService.reduceBalance(reduceDto);
|
||||
|
||||
return new TotalDealerCommission(totalDealerUser.getUserId(), money);
|
||||
}
|
||||
return TotalDealerCommission.empty();
|
||||
}
|
||||
|
||||
private ShopDealerUser findTotalDealerUser() {
|
||||
return shopDealerUserService.getOne(
|
||||
new LambdaQueryWrapper<ShopDealerUser>()
|
||||
@@ -756,6 +1050,92 @@ public class DealerOrderSettlement10584Task {
|
||||
order.getOrderNo(), dealerOrder.getFirstUserId(), dealerOrder.getSecondUserId(), dealerOrder.getFirstDividendUser(), dealerOrder.getSecondDividendUser());
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录订单分销业务
|
||||
* @param order 商品订单
|
||||
* @param dealerRefereeCommission 一级、二级分销员分销数据
|
||||
* @param shopRoleCommission 门店/服务商一级、二级管理津贴数据
|
||||
*/
|
||||
private void createDealerOrderRecordV2(ShopOrder order, DealerRefereeCommissionV2 dealerRefereeCommission, ShopRoleCommission shopRoleCommission, TotalDealerCommission totalDealerCommission) {
|
||||
// 幂等:同一订单只写一条(依赖 order_no + tenant_id 作为业务唯一)
|
||||
ShopDealerOrder existed = shopDealerOrderService.getOne(
|
||||
new LambdaQueryWrapper<ShopDealerOrder>()
|
||||
.eq(ShopDealerOrder::getTenantId, TENANT_ID)
|
||||
.eq(ShopDealerOrder::getOrderNo, order.getOrderNo())
|
||||
.last("limit 1")
|
||||
);
|
||||
if (existed != null) {
|
||||
// 允许“补发”门店分润时回填分润字段,避免订单已结算但分润字段一直为空,影响排查/对账。
|
||||
LambdaUpdateWrapper<ShopDealerOrder> uw = new LambdaUpdateWrapper<ShopDealerOrder>()
|
||||
.eq(ShopDealerOrder::getTenantId, TENANT_ID)
|
||||
.eq(ShopDealerOrder::getOrderNo, order.getOrderNo());
|
||||
boolean needUpdate = false;
|
||||
if (shopRoleCommission != null && shopRoleCommission.storeDirectUserId != null) {
|
||||
Integer existedUser = existed.getFirstDividendUser();
|
||||
boolean needSetUser = existedUser == null;
|
||||
boolean needSetMoney = existed.getFirstDividend() == null || existed.getFirstDividend().signum() == 0;
|
||||
if (needSetUser) {
|
||||
uw.set(ShopDealerOrder::getFirstDividendUser, shopRoleCommission.storeDirectUserId);
|
||||
needUpdate = true;
|
||||
}
|
||||
boolean sameUser = existedUser == null || Objects.equals(existedUser, shopRoleCommission.storeDirectUserId);
|
||||
if (sameUser && needSetMoney && shopRoleCommission.storeDirectMoney != null && shopRoleCommission.storeDirectMoney.signum() > 0) {
|
||||
uw.set(ShopDealerOrder::getFirstDividend, shopRoleCommission.storeDirectMoney);
|
||||
needUpdate = true;
|
||||
}
|
||||
}
|
||||
if (shopRoleCommission != null && shopRoleCommission.storeSimpleUserId != null) {
|
||||
Integer existedUser = existed.getSecondDividendUser();
|
||||
boolean needSetUser = existedUser == null;
|
||||
boolean needSetMoney = existed.getSecondDividend() == null || existed.getSecondDividend().signum() == 0;
|
||||
if (needSetUser) {
|
||||
uw.set(ShopDealerOrder::getSecondDividendUser, shopRoleCommission.storeSimpleUserId);
|
||||
needUpdate = true;
|
||||
}
|
||||
boolean sameUser = existedUser == null || Objects.equals(existedUser, shopRoleCommission.storeSimpleUserId);
|
||||
if (sameUser && needSetMoney && shopRoleCommission.storeSimpleMoney != null && shopRoleCommission.storeSimpleMoney.signum() > 0) {
|
||||
uw.set(ShopDealerOrder::getSecondDividend, shopRoleCommission.storeSimpleMoney);
|
||||
needUpdate = true;
|
||||
}
|
||||
}
|
||||
if (needUpdate) {
|
||||
shopDealerOrderService.update(uw);
|
||||
log.info("ShopDealerOrder已存在,回填门店分润字段 - orderNo={}, firstDividendUser={}, secondDividendUser={}",
|
||||
order.getOrderNo(), shopRoleCommission.storeDirectUserId, shopRoleCommission.storeSimpleUserId);
|
||||
} else {
|
||||
log.info("ShopDealerOrder已存在,跳过写入 - orderNo={}", order.getOrderNo());
|
||||
}
|
||||
return;
|
||||
}else {
|
||||
|
||||
ShopDealerOrder dealerOrder = new ShopDealerOrder();
|
||||
dealerOrder.setUserId(order.getUserId()); // 买家用户ID
|
||||
dealerOrder.setOrderNo(order.getOrderNo());
|
||||
dealerOrder.setOrderPrice(order.getTotalPrice());
|
||||
dealerOrder.setPayPrice(order.getPayPrice());
|
||||
|
||||
//一级、二级分销员分销佣金统计
|
||||
dealerOrder.setFirstUserId(dealerRefereeCommission != null ? dealerRefereeCommission.directDealerId : null);
|
||||
dealerOrder.setFirstMoney(dealerRefereeCommission != null ? dealerRefereeCommission.directMoney : BigDecimal.ZERO);
|
||||
dealerOrder.setSecondUserId(dealerRefereeCommission != null ? dealerRefereeCommission.simpleDealerId : null);
|
||||
dealerOrder.setSecondMoney(dealerRefereeCommission != null ? dealerRefereeCommission.simpleMoney : BigDecimal.ZERO);
|
||||
|
||||
//门店(角色shop)两级分润单独落字段(详细以 ShopDealerCapital 为准)
|
||||
dealerOrder.setFirstDividendUser(shopRoleCommission != null ? shopRoleCommission.storeDirectUserId : null);
|
||||
dealerOrder.setFirstDividend(shopRoleCommission != null ? shopRoleCommission.storeDirectMoney : BigDecimal.ZERO);
|
||||
dealerOrder.setSecondDividendUser(shopRoleCommission != null ? shopRoleCommission.storeSimpleUserId : null);
|
||||
dealerOrder.setSecondDividend(shopRoleCommission != null ? shopRoleCommission.storeSimpleMoney : BigDecimal.ZERO);
|
||||
|
||||
dealerOrder.setIsSettled(1);
|
||||
dealerOrder.setSettleTime(LocalDateTime.now());
|
||||
dealerOrder.setMonth(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM")));
|
||||
dealerOrder.setTenantId(TENANT_ID);
|
||||
dealerOrder.setComments(buildCommissionTraceCommentV2(dealerRefereeCommission, shopRoleCommission, totalDealerCommission));
|
||||
|
||||
shopDealerOrderService.save(dealerOrder);
|
||||
}
|
||||
}
|
||||
|
||||
private String buildCommissionTraceComment(
|
||||
DealerRefereeCommission dealerRefereeCommission,
|
||||
ShopRoleCommission shopRoleCommission,
|
||||
@@ -770,6 +1150,30 @@ public class DealerOrderSettlement10584Task {
|
||||
+ ",totalDealer=" + totalDealerCommission.userId + ":" + totalDealerCommission.money;
|
||||
}
|
||||
|
||||
private String buildCommissionTraceCommentV2(
|
||||
DealerRefereeCommissionV2 dealerRefereeCommission,
|
||||
ShopRoleCommission shopRoleCommission,
|
||||
TotalDealerCommission totalDealerCommission
|
||||
) {
|
||||
// 轻量“过程”留痕,方便排查;详细分佣以 ShopDealerCapital 为准。
|
||||
Integer direct = dealerRefereeCommission != null ? dealerRefereeCommission.directDealerId : null;
|
||||
BigDecimal directMoney = dealerRefereeCommission != null ? dealerRefereeCommission.directMoney : BigDecimal.ZERO;
|
||||
Integer simpleDealerId = dealerRefereeCommission != null ? dealerRefereeCommission.simpleDealerId : null;
|
||||
BigDecimal simpleMoney = dealerRefereeCommission != null ? dealerRefereeCommission.simpleMoney : BigDecimal.ZERO;
|
||||
Integer storeDirectUserId = shopRoleCommission != null ? shopRoleCommission.storeDirectUserId : null;
|
||||
BigDecimal storeDirectMoney = shopRoleCommission != null ? shopRoleCommission.storeDirectMoney : BigDecimal.ZERO;
|
||||
Integer storeSimpleUserId = shopRoleCommission != null ? shopRoleCommission.storeSimpleUserId : null;
|
||||
BigDecimal storeSimpleMoney = shopRoleCommission != null ? shopRoleCommission.storeSimpleMoney : BigDecimal.ZERO;
|
||||
Integer userId = totalDealerCommission != null ? totalDealerCommission.userId : null;
|
||||
BigDecimal money = totalDealerCommission != null ? totalDealerCommission.money : BigDecimal.ZERO;
|
||||
|
||||
return "direct=" + direct + ":" + directMoney
|
||||
+ ",simple=" + simpleDealerId + ":" + simpleMoney
|
||||
+ ",dividend1=" + storeDirectUserId + ":" + storeDirectMoney
|
||||
+ ",dividend2=" + storeSimpleUserId + ":" + storeSimpleMoney
|
||||
+ ",totalDealer=" + userId + ":" + money;
|
||||
}
|
||||
|
||||
private BigDecimal getOrderBaseAmount(ShopOrder order) {
|
||||
if (order == null) {
|
||||
return null;
|
||||
@@ -962,6 +1366,25 @@ public class DealerOrderSettlement10584Task {
|
||||
}
|
||||
}
|
||||
|
||||
private static class DealerRefereeCommissionV2 {
|
||||
private final Integer directDealerId;
|
||||
private final BigDecimal directMoney;
|
||||
private final Integer simpleDealerId;
|
||||
private final BigDecimal simpleMoney;
|
||||
|
||||
private DealerRefereeCommissionV2(
|
||||
Integer directDealerId,
|
||||
BigDecimal directMoney,
|
||||
Integer simpleDealerId,
|
||||
BigDecimal simpleMoney
|
||||
) {
|
||||
this.directDealerId = directDealerId;
|
||||
this.directMoney = directMoney != null ? directMoney : BigDecimal.ZERO;
|
||||
this.simpleDealerId = simpleDealerId;
|
||||
this.simpleMoney = simpleMoney != null ? simpleMoney : BigDecimal.ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ShopRoleCommission {
|
||||
private final Integer storeDirectUserId;
|
||||
private final BigDecimal storeDirectMoney;
|
||||
|
||||
@@ -7,6 +7,8 @@ import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import java.io.Serializable;
|
||||
|
||||
@@ -23,6 +25,7 @@ import lombok.EqualsAndHashCode;
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Schema(name = "ShopDealerOrder对象", description = "分销商订单记录表")
|
||||
@TableName("shop_dealer_order")
|
||||
public class ShopDealerOrder implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -66,6 +69,9 @@ public class ShopDealerOrder implements Serializable {
|
||||
@TableField(exist = false)
|
||||
private String firstNickname;
|
||||
|
||||
@Schema(description = "分销佣金(一级)")
|
||||
private BigDecimal firstMoney;
|
||||
|
||||
@Schema(description = "分销商用户id(二级)")
|
||||
private Integer secondUserId;
|
||||
|
||||
@@ -73,42 +79,57 @@ public class ShopDealerOrder implements Serializable {
|
||||
@TableField(exist = false)
|
||||
private String secondNickname;
|
||||
|
||||
@Schema(description = "分销商用户id(三级)")
|
||||
private Integer thirdUserId;
|
||||
|
||||
@Schema(description = "分销商用户昵称(三级)")
|
||||
@TableField(exist = false)
|
||||
private String thirdNickname;
|
||||
|
||||
@Schema(description = "分销佣金(一级)")
|
||||
private BigDecimal firstMoney;
|
||||
|
||||
@Schema(description = "分销佣金(二级)")
|
||||
private BigDecimal secondMoney;
|
||||
|
||||
@Schema(description = "分销佣金(三级)")
|
||||
@Schema(description = "分销商用户id(弃用)")
|
||||
private Integer thirdUserId;
|
||||
|
||||
@Schema(description = "分销商用户昵称(弃用)")
|
||||
@TableField(exist = false)
|
||||
private String thirdNickname;
|
||||
|
||||
@Schema(description = "分销佣金(弃用)")
|
||||
private BigDecimal thirdMoney;
|
||||
|
||||
@Schema(description = "门店(一级)")
|
||||
@Schema(description = "一级服务商/门店")
|
||||
private Integer firstDividendUser;
|
||||
|
||||
@Schema(description = "门店名称(一级)")
|
||||
@Schema(description = "一级服务商/门店名称")
|
||||
@TableField(exist = false)
|
||||
private String firstDividendUserName;
|
||||
|
||||
@Schema(description = "分红(一级)")
|
||||
@Schema(description = "一级服务商/门店管理津贴")
|
||||
private BigDecimal firstDividend;
|
||||
|
||||
@Schema(description = "门店(二级)")
|
||||
@Schema(description = "一级服务商/门店结算标识 0-否 1-是")
|
||||
private Integer firstDividendFlag;
|
||||
|
||||
@Schema(description = "一级服务商/门店结算单号")
|
||||
private String firstDividendNo;
|
||||
|
||||
@Schema(description = "一级服务商/门店结算时间")
|
||||
private LocalDateTime firstDividendTime;
|
||||
|
||||
@Schema(description = "二级服务商/门店")
|
||||
private Integer secondDividendUser;
|
||||
|
||||
@Schema(description = "门店名称(二级)")
|
||||
@Schema(description = "二级服务商/门店名称")
|
||||
@TableField(exist = false)
|
||||
private String secondDividendUserName;
|
||||
|
||||
@Schema(description = "分红(二级)")
|
||||
@Schema(description = "二级服务商/门店管理津贴")
|
||||
private BigDecimal secondDividend;
|
||||
|
||||
@Schema(description = "二级服务商/门店结算标识 0-否 1-是")
|
||||
private Integer secondDividendFlag;
|
||||
|
||||
@Schema(description = "二级服务商/门店结算单号")
|
||||
private String secondDividendNo;
|
||||
|
||||
@Schema(description = "二级服务商/门店结算时间")
|
||||
private LocalDateTime secondDividendTime;
|
||||
|
||||
@Schema(description = "佣金比例")
|
||||
private BigDecimal rate;
|
||||
|
||||
|
||||
@@ -34,4 +34,11 @@ public interface ShopDealerRefereeMapper extends BaseMapper<ShopDealerReferee> {
|
||||
*/
|
||||
List<ShopDealerReferee> selectListRel(@Param("param") ShopDealerRefereeParam param);
|
||||
|
||||
/**
|
||||
* 通过用户ID查询上一级分销人信息【type = 0】
|
||||
* @param userId 用户ID
|
||||
* @return
|
||||
*/
|
||||
Integer getDealerIdByUserId(@Param("userId") Integer userId);
|
||||
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.gxwebsoft.shop.entity.ShopOrder;
|
||||
import com.gxwebsoft.shop.param.ShopOrderParam;
|
||||
import com.gxwebsoft.shop.vo.ShopOrderGoodsVO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
@@ -60,4 +60,11 @@ public interface ShopOrderMapper extends BaseMapper<ShopOrder> {
|
||||
Map<String, Object> selectUserOrderStats(@Param("userId") Integer userId,
|
||||
@Param("tenantId") Integer tenantId,
|
||||
@Param("type") Integer type);
|
||||
|
||||
/**
|
||||
* 通过订单号查询订单所有商品分润信息
|
||||
* @param orderNo 订单号
|
||||
* @return
|
||||
*/
|
||||
List<ShopOrderGoodsVO> getOrderGoodsInfo(@Param("orderNo") String orderNo);
|
||||
}
|
||||
|
||||
@@ -57,5 +57,16 @@
|
||||
<select id="selectListRel" resultType="com.gxwebsoft.shop.entity.ShopDealerReferee">
|
||||
<include refid="selectSql"></include>
|
||||
</select>
|
||||
<select id="getDealerIdByUserId" resultType="java.lang.Integer">
|
||||
SELECT
|
||||
a.dealer_id
|
||||
FROM
|
||||
shop_dealer_referee a
|
||||
LEFT JOIN shop_dealer_user b ON a.dealer_id = b.user_id
|
||||
WHERE
|
||||
b.is_delete = 0
|
||||
AND b.type = 0
|
||||
AND a.user_id = #{userId}
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -320,6 +320,28 @@
|
||||
<select id="getByOutTradeNo" resultType="com.gxwebsoft.shop.entity.ShopOrder">
|
||||
SELECT * FROM shop_order WHERE order_no = #{outTradeNo}
|
||||
</select>
|
||||
<select id="getOrderGoodsInfo" resultType="com.gxwebsoft.shop.vo.ShopOrderGoodsVO">
|
||||
SELECT
|
||||
a.order_no,
|
||||
b.goods_id,
|
||||
c.`name`,
|
||||
b.total_num,
|
||||
b.price,
|
||||
c.first_money,
|
||||
c.second_money,
|
||||
c.first_dividend,
|
||||
c.second_dividend,
|
||||
c.commission_type
|
||||
FROM
|
||||
shop_order a
|
||||
LEFT JOIN shop_order_goods b ON a.order_id = b.order_id
|
||||
LEFT JOIN shop_goods c ON b.goods_id = c.goods_id
|
||||
WHERE
|
||||
a.deleted = 0
|
||||
AND c.deleted = 0
|
||||
AND c.is_open_commission = 1
|
||||
AND a.order_no = #{orderNo}
|
||||
</select>
|
||||
|
||||
<!-- 根据订单号修改订单 -->
|
||||
<update id="updateByOutTradeNo" parameterType="com.gxwebsoft.cms.entity.CmsWebsite">
|
||||
|
||||
47
src/main/java/com/gxwebsoft/shop/vo/ShopOrderGoodsVO.java
Normal file
47
src/main/java/com/gxwebsoft/shop/vo/ShopOrderGoodsVO.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package com.gxwebsoft.shop.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 订单商品信息
|
||||
* @author xm
|
||||
* @since 2025-01-12
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "订单商品信息")
|
||||
public class ShopOrderGoodsVO {
|
||||
|
||||
@Schema(description = "订单号")
|
||||
private String orderNo;
|
||||
|
||||
@Schema(description = "商品ID")
|
||||
private Integer goodsId;
|
||||
|
||||
@Schema(description = "品名")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "购买数量")
|
||||
private Integer totalNum;
|
||||
|
||||
@Schema(description = "单价")
|
||||
private BigDecimal price;
|
||||
|
||||
@Schema(description = "结算方式 10按金额 20按比率")
|
||||
private Integer commissionType;
|
||||
|
||||
@Schema(description = "一级分销员佣金比例/金额")
|
||||
private BigDecimal firstMoney;
|
||||
|
||||
@Schema(description = "二级分销员佣金比例/金额")
|
||||
private BigDecimal secondMoney;
|
||||
|
||||
@Schema(description = "一级服务商管理津贴比例/金额")
|
||||
private BigDecimal firstDividend;
|
||||
|
||||
@Schema(description = "二级服务商管理津贴比例/金额")
|
||||
private BigDecimal secondDividend;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user