From 2fbcf16a48d2a9a89ccc5a8f0fd48d20c9387dc0 Mon Sep 17 00:00:00 2001 From: xm <1350250847@qq.com> Date: Sat, 16 May 2026 15:10:14 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=97=A8=E5=BA=97=E3=80=81?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E5=95=86=E4=BD=A3=E9=87=91=E5=AE=9A=E6=97=B6?= =?UTF-8?q?=E7=BB=93=E7=AE=97=E5=8A=9F=E8=83=BD=EF=BC=8C=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E6=AF=8F=E5=A4=A9=E5=87=8C=E6=99=A8=E4=B8=80=E7=82=B9=E6=89=A7?= =?UTF-8?q?=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/core/config/ConfigProperties.java | 2 +- .../impl/GltTicketOrderServiceImpl.java | 4 +- .../payment/service/WxPayConfigService.java | 2 +- .../controller/ShopDealerOrderController.java | 27 ++- .../shop/dto/ShopDealerSettlementDto.java | 31 ++++ .../shop/dto/ShopDealerSettlementItemDto.java | 26 +++ .../com/gxwebsoft/shop/entity/ShopOrder.java | 6 + .../shop/mapper/ShopDealerOrderMapper.java | 8 + .../shop/mapper/xml/ShopDealerOrderMapper.xml | 22 +++ .../shop/service/ShopDealerUserService.java | 9 + .../impl/ShopDealerUserServiceImpl.java | 47 +++++ .../service/impl/ShopOrderServiceImpl.java | 7 - .../shop/task/OrderSettlementTask.java | 166 ++++++++++++++++++ .../shop/vo/ShopDealerOrderTaskVO.java | 45 +++++ 14 files changed, 381 insertions(+), 21 deletions(-) create mode 100644 src/main/java/com/gxwebsoft/shop/dto/ShopDealerSettlementDto.java create mode 100644 src/main/java/com/gxwebsoft/shop/dto/ShopDealerSettlementItemDto.java create mode 100644 src/main/java/com/gxwebsoft/shop/task/OrderSettlementTask.java create mode 100644 src/main/java/com/gxwebsoft/shop/vo/ShopDealerOrderTaskVO.java diff --git a/src/main/java/com/gxwebsoft/common/core/config/ConfigProperties.java b/src/main/java/com/gxwebsoft/common/core/config/ConfigProperties.java index d500177..dfee5d3 100644 --- a/src/main/java/com/gxwebsoft/common/core/config/ConfigProperties.java +++ b/src/main/java/com/gxwebsoft/common/core/config/ConfigProperties.java @@ -60,7 +60,7 @@ public class ConfigProperties { /** * token过期时间, 单位秒 */ - private Long tokenExpireTime = 60 * 60 * 365 * 24L; + private Long tokenExpireTime = 60 * 60 * 30 * 24L; /** * token快要过期自动刷新时间, 单位分钟 diff --git a/src/main/java/com/gxwebsoft/glt/service/impl/GltTicketOrderServiceImpl.java b/src/main/java/com/gxwebsoft/glt/service/impl/GltTicketOrderServiceImpl.java index d6e24cb..c22951d 100644 --- a/src/main/java/com/gxwebsoft/glt/service/impl/GltTicketOrderServiceImpl.java +++ b/src/main/java/com/gxwebsoft/glt/service/impl/GltTicketOrderServiceImpl.java @@ -194,9 +194,7 @@ public class GltTicketOrderServiceImpl extends ServiceImpl teamSettlement() { + orderSettlementTask.teamSettlement(); + return success("success"); + } } diff --git a/src/main/java/com/gxwebsoft/shop/dto/ShopDealerSettlementDto.java b/src/main/java/com/gxwebsoft/shop/dto/ShopDealerSettlementDto.java new file mode 100644 index 0000000..2c950e2 --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/dto/ShopDealerSettlementDto.java @@ -0,0 +1,31 @@ +package com.gxwebsoft.shop.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +/** + * 分销订单结算 + * @author xm + * @since 2026-05-13 + */ +@Data +@Schema(name = "ShopDealerSettlementDto", description = "分销订单结算") +public class ShopDealerSettlementDto { + + @Schema(description = "变动类型 1-操作冻结账户余额 2-操作提现账户余额【直接结算】 3-解冻 4-退款") + private Integer type; + + @Schema(description = "资金流动类型 (10分销收入 11团队管理津贴收入 12分红收入 13现场推广收入 20提现支出 30转账支出 40转账收入 50佣金解冻 60配送奖励 70佣金退回【退单】)") + private Integer flowType; + + @Schema(description = "描述") + private String comments; + + @Schema(description = "商城ID") + private Integer tenantId; + + @Schema(description = "明细列表") + private List itemList; +} diff --git a/src/main/java/com/gxwebsoft/shop/dto/ShopDealerSettlementItemDto.java b/src/main/java/com/gxwebsoft/shop/dto/ShopDealerSettlementItemDto.java new file mode 100644 index 0000000..7d57e13 --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/dto/ShopDealerSettlementItemDto.java @@ -0,0 +1,26 @@ +package com.gxwebsoft.shop.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 分销订单退款 + * @author xm + * @since 2026-05-13 + */ +@Data +@Schema(name = "ShopDealerSettlementItemDto", description = "分销订单退款") +public class ShopDealerSettlementItemDto { + + @Schema(description = "订单号") + private String no; + + @Schema(description = "分销商用户ID") + private Integer userId; + + @Schema(description = "变更金额") + private BigDecimal money; + +} diff --git a/src/main/java/com/gxwebsoft/shop/entity/ShopOrder.java b/src/main/java/com/gxwebsoft/shop/entity/ShopOrder.java index 586de72..a844a9f 100644 --- a/src/main/java/com/gxwebsoft/shop/entity/ShopOrder.java +++ b/src/main/java/com/gxwebsoft/shop/entity/ShopOrder.java @@ -334,6 +334,12 @@ public class ShopOrder implements Serializable { @Schema(description = "推广核销佣金") private BigDecimal verifyMoney; + @Schema(description = "门店、服务商结算标识 0-未结算 1-已结算") + private Integer teamSettlementFlag; + + @Schema(description = "分红结算标识 0-未结算 1-已结算") + private Integer dividendSettlementFlag; + @Schema(description = "修改时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime updateTime; diff --git a/src/main/java/com/gxwebsoft/shop/mapper/ShopDealerOrderMapper.java b/src/main/java/com/gxwebsoft/shop/mapper/ShopDealerOrderMapper.java index 928b066..10ac5c8 100644 --- a/src/main/java/com/gxwebsoft/shop/mapper/ShopDealerOrderMapper.java +++ b/src/main/java/com/gxwebsoft/shop/mapper/ShopDealerOrderMapper.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.gxwebsoft.shop.entity.ShopDealerOrder; import com.gxwebsoft.shop.param.ShopDealerOrderParam; +import com.gxwebsoft.shop.vo.ShopDealerOrderTaskVO; import org.apache.ibatis.annotations.Param; import java.util.List; @@ -34,4 +35,11 @@ public interface ShopDealerOrderMapper extends BaseMapper { */ List selectListRel(@Param("param") ShopDealerOrderParam param); + /** + * 获取订单门店/分销商待结算数据 + * @param tenantId 租户ID + * @return + */ + List getDealerOrderList(@Param("tenantId") Integer tenantId); + } diff --git a/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopDealerOrderMapper.xml b/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopDealerOrderMapper.xml index b49c42d..d70a745 100644 --- a/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopDealerOrderMapper.xml +++ b/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopDealerOrderMapper.xml @@ -89,5 +89,27 @@ + diff --git a/src/main/java/com/gxwebsoft/shop/service/ShopDealerUserService.java b/src/main/java/com/gxwebsoft/shop/service/ShopDealerUserService.java index dc4131c..9977568 100644 --- a/src/main/java/com/gxwebsoft/shop/service/ShopDealerUserService.java +++ b/src/main/java/com/gxwebsoft/shop/service/ShopDealerUserService.java @@ -3,6 +3,7 @@ package com.gxwebsoft.shop.service; import com.baomidou.mybatisplus.extension.service.IService; import com.gxwebsoft.common.core.web.PageResult; import com.gxwebsoft.shop.dto.ShopDealerRefundDto; +import com.gxwebsoft.shop.dto.ShopDealerSettlementDto; import com.gxwebsoft.shop.dto.ShopDealerUserReduceDto; import com.gxwebsoft.shop.entity.ShopDealerUser; import com.gxwebsoft.shop.param.ShopDealerUserParam; @@ -58,4 +59,12 @@ public interface ShopDealerUserService extends IService { * @return */ Boolean refundOrder(ShopDealerRefundDto refundDto); + + /** + * 用户资金结算 + * @param dto + * @return + */ + Boolean settlementBatch(ShopDealerSettlementDto dto); + } diff --git a/src/main/java/com/gxwebsoft/shop/service/impl/ShopDealerUserServiceImpl.java b/src/main/java/com/gxwebsoft/shop/service/impl/ShopDealerUserServiceImpl.java index 80c00e2..a11d677 100644 --- a/src/main/java/com/gxwebsoft/shop/service/impl/ShopDealerUserServiceImpl.java +++ b/src/main/java/com/gxwebsoft/shop/service/impl/ShopDealerUserServiceImpl.java @@ -1,5 +1,6 @@ package com.gxwebsoft.shop.service.impl; +import cn.hutool.core.bean.BeanUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.gxwebsoft.common.core.enums.ShopDealerCapitalUpdateEnum; @@ -11,6 +12,8 @@ import com.gxwebsoft.common.system.entity.User; import com.gxwebsoft.common.system.mapper.UserMapper; import com.gxwebsoft.common.system.redis.OrderNoUtils; import com.gxwebsoft.shop.dto.ShopDealerRefundDto; +import com.gxwebsoft.shop.dto.ShopDealerSettlementDto; +import com.gxwebsoft.shop.dto.ShopDealerSettlementItemDto; import com.gxwebsoft.shop.dto.ShopDealerUserReduceDto; import com.gxwebsoft.shop.entity.ShopDealerCapital; import com.gxwebsoft.shop.entity.ShopDealerUser; @@ -364,6 +367,50 @@ public class ShopDealerUserServiceImpl extends ServiceImpl itemList = entity.getItemList(); + + List userIdList = itemList.stream().map(ShopDealerSettlementItemDto::getUserId).distinct().collect(Collectors.toList()); + + List shopDealerUserList = baseMapper.selectList(new LambdaQueryWrapper().select(ShopDealerUser::getId, ShopDealerUser::getUserId, + ShopDealerUser::getMoney, ShopDealerUser::getTotalMoney, ShopDealerUser::getFreezeMoney).in(ShopDealerUser::getUserId, userIdList)); + + List updateDealerUserList = new ArrayList<>(); + List capitalList = new ArrayList<>(); + itemList.forEach(item ->{ + ShopDealerUser dealerUser = shopDealerUserList.stream().filter(shopDealerUser -> item.getUserId().equals(shopDealerUser.getUserId())).findFirst().orElse(null); + if(dealerUser != null){ + dealerUser.setMoney(dealerUser.getMoney().add(item.getMoney())); + dealerUser.setTotalMoney(dealerUser.getTotalMoney().add(item.getMoney())); + dealerUser.setUpdateTime(now); + updateDealerUserList.add(dealerUser); + + ShopDealerCapital capital = BeanUtil.toBean(entity, ShopDealerCapital.class); + capital.setNo(item.getNo()); + capital.setUserId(item.getUserId()); + capital.setMoney(item.getMoney()); + capital.setMoneyAfter(dealerUser.getMoney()); + capital.setFreezeMoneyAfter(dealerUser.getFreezeMoney()); + capital.setCreateTime(now); + capitalList.add(capital); + } + }); + + if(CollectionUtils.isNotEmpty(updateDealerUserList)){ + updateBatchById(updateDealerUserList); + } + + if(CollectionUtils.isNotEmpty(capitalList)){ + shopDealerCapitalService.saveBatch(capitalList); + } + } + return Boolean.TRUE; + } + public ShopDealerUser getDealerUser(Integer userId){ ShopDealerUser shopDealerUser = baseMapper.selectOne(new LambdaQueryWrapper().eq(ShopDealerUser::getUserId, userId)); if(shopDealerUser == null){ diff --git a/src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderServiceImpl.java b/src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderServiceImpl.java index 72be190..f5bf420 100644 --- a/src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderServiceImpl.java +++ b/src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderServiceImpl.java @@ -851,13 +851,6 @@ public class ShopOrderServiceImpl extends ServiceImpl orderTaskVOList = shopDealerOrderMapper.getDealerOrderList(10584); + if(CollectionUtils.isNotEmpty(orderTaskVOList)){ + LocalDateTime now = LocalDateTime.now(); + List orderIdList = orderTaskVOList.stream().map(ShopDealerOrderTaskVO::getOrderId).distinct().collect(Collectors.toList()); + List shopDealerIdList = orderTaskVOList.stream().map(ShopDealerOrderTaskVO::getShopDealerOrderId).distinct().collect(Collectors.toList()); + + //2.查询商品订单信息 + List shopOrderList = shopOrderMapper.selectList(new LambdaQueryWrapper().select(ShopOrder::getOrderId, ShopOrder::getTeamSettlementFlag) + .in(ShopOrder::getOrderId, orderIdList)); + + //3.查询商品订单分销信息 + List shopDealerOrderList = shopDealerOrderMapper.selectList(new LambdaQueryWrapper().select(ShopDealerOrder::getId, ShopDealerOrder::getOrderNo) + .in(ShopDealerOrder::getId, shopDealerIdList)); + + //4.结算一级服务商佣金 + Map> firstDealerMap = orderTaskVOList.stream().collect(Collectors.groupingBy(ShopDealerOrderTaskVO::getFirstDividendUser)); + List firstSettlementItemDtoList = new ArrayList<>(); + firstDealerMap.forEach((k, value) ->{ + List orderIds = value.stream().map(ShopDealerOrderTaskVO::getOrderId).distinct().collect(Collectors.toList()); + List shopDealerOrderIds = value.stream().map(ShopDealerOrderTaskVO::getShopDealerOrderId).distinct().collect(Collectors.toList()); + + //4.1 标记商品订单为已结算状态 + List shopOrders = shopOrderList.stream().filter(shopOrder -> orderIds.contains(shopOrder.getOrderId())).collect(Collectors.toList()); + shopOrders.forEach(shopOrder -> shopOrder.setTeamSettlementFlag(1)); + + //4.2 生成分销记录【增加钱包金额】 + BigDecimal firstDividendSum = value.stream().map(ShopDealerOrderTaskVO::getFirstDividend).reduce(BigDecimal.ZERO, BigDecimal::add); + ShopDealerSettlementItemDto itemDto = new ShopDealerSettlementItemDto(); + String no = orderNoUtils.generate("C"); + itemDto.setNo(no); + itemDto.setUserId(k); + itemDto.setMoney(firstDividendSum); + firstSettlementItemDtoList.add(itemDto); + + //4.3更新商品分销记录对应的一级服务商佣金为已结算状态 + List shopDealerOrders = shopDealerOrderList.stream().filter(shopDealerOrder -> shopDealerOrderIds.contains(shopDealerOrder.getId())).collect(Collectors.toList()); + shopDealerOrders.forEach(shopDealerOrder -> { + shopDealerOrder.setFirstDividendFlag(1); + shopDealerOrder.setFirstDividendNo(no); + shopDealerOrder.setFirstDividendTime(now); + }); + }); + + //4.4 一级结算【增加钱包金额】 + if(CollectionUtils.isNotEmpty(firstSettlementItemDtoList)){ + ShopDealerSettlementDto firstSettlementDto = new ShopDealerSettlementDto(); + firstSettlementDto.setType(ShopDealerTypeEnum.WITHDRAW_ACCOUNT.getCode()); + firstSettlementDto.setFlowType(ShopDealerCapitalUpdateEnum.MANAGEMENT_INCOME.getType()); + firstSettlementDto.setComments("团队管理津贴(1)"); + firstSettlementDto.setTenantId(10584); + firstSettlementDto.setItemList(firstSettlementItemDtoList); + shopDealerUserService.settlementBatch(firstSettlementDto); + } + + //5.结算二级服务商佣金 + Map> secondDealerMap = orderTaskVOList.stream().collect(Collectors.groupingBy(ShopDealerOrderTaskVO::getSecondDividendUser)); + List secondSettlementItemDtoList = new ArrayList<>(); + secondDealerMap.forEach((k, value) ->{ + List orderIds = value.stream().map(ShopDealerOrderTaskVO::getOrderId).distinct().collect(Collectors.toList()); + List shopDealerOrderIds = value.stream().map(ShopDealerOrderTaskVO::getShopDealerOrderId).distinct().collect(Collectors.toList()); + + //5.1 标记商品订单为已结算状态 + List shopOrders = shopOrderList.stream().filter(shopOrder -> orderIds.contains(shopOrder.getOrderId())).collect(Collectors.toList()); + shopOrders.forEach(shopOrder -> shopOrder.setTeamSettlementFlag(1)); + + //5.2 生成分销记录【增加钱包金额】 + BigDecimal secondDividendSum = value.stream().map(ShopDealerOrderTaskVO::getSecondDividend).reduce(BigDecimal.ZERO, BigDecimal::add); + ShopDealerSettlementItemDto itemDto = new ShopDealerSettlementItemDto(); + String no = orderNoUtils.generate("C"); + itemDto.setNo(no); + itemDto.setUserId(k); + itemDto.setMoney(secondDividendSum); + secondSettlementItemDtoList.add(itemDto); + + //5.3 更新商品分销记录对应的一级服务商佣金为已结算状态 + List shopDealerOrders = shopDealerOrderList.stream().filter(shopDealerOrder -> shopDealerOrderIds.contains(shopDealerOrder.getId())).collect(Collectors.toList()); + shopDealerOrders.forEach(shopDealerOrder -> { + shopDealerOrder.setSecondDividendFlag(1); + shopDealerOrder.setSecondDividendNo(no); + shopDealerOrder.setSecondDividendTime(now); + }); + }); + + //5.4 二级结算【增加钱包金额】 + if(CollectionUtils.isNotEmpty(secondSettlementItemDtoList)){ + ShopDealerSettlementDto secondSettlementDto = new ShopDealerSettlementDto(); + secondSettlementDto.setType(ShopDealerTypeEnum.WITHDRAW_ACCOUNT.getCode()); + secondSettlementDto.setFlowType(ShopDealerCapitalUpdateEnum.MANAGEMENT_INCOME.getType()); + secondSettlementDto.setComments("团队管理津贴(2)"); + secondSettlementDto.setTenantId(10584); + secondSettlementDto.setItemList(secondSettlementItemDtoList); + shopDealerUserService.settlementBatch(secondSettlementDto); + } + + //6.批量修改订单为已结算状态 + if(CollectionUtils.isNotEmpty(shopOrderList)){ + shopOrderService.updateBatchById(shopOrderList); + } + + //7.批量修改订单分销数据为已结算状态 + if(CollectionUtils.isNotEmpty(shopDealerOrderList)){ + shopDealerOrderService.updateBatchById(shopDealerOrderList); + } + } + } + +} diff --git a/src/main/java/com/gxwebsoft/shop/vo/ShopDealerOrderTaskVO.java b/src/main/java/com/gxwebsoft/shop/vo/ShopDealerOrderTaskVO.java new file mode 100644 index 0000000..dcc772a --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/vo/ShopDealerOrderTaskVO.java @@ -0,0 +1,45 @@ +package com.gxwebsoft.shop.vo; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 订单分销门店/服务商分佣记录 + * @author xm + * @since 2026-05-15 + */ +@Data +@Schema(description = "订单分销门店/服务商分佣记录") +public class ShopDealerOrderTaskVO { + + @Schema(description = "商品订单ID") + private Integer orderId; + + @Schema(description = "主键ID") + private Integer shopDealerOrderId; + + @Excel(name = "订单编号") + private String orderNo; + + @Schema(description = "一级服务商/门店") + private Integer firstDividendUser; + + @Schema(description = "一级服务商/门店管理津贴") + private BigDecimal firstDividend; + + @Schema(description = "一级服务商/门店结算标识 0-否 1-是") + private Integer firstDividendFlag; + + @Schema(description = "二级服务商/门店") + private Integer secondDividendUser; + + @Schema(description = "二级服务商/门店管理津贴") + private BigDecimal secondDividend; + + @Schema(description = "二级服务商/门店结算标识 0-否 1-是") + private Integer secondDividendFlag; + +}