分销分钱具体逻辑
This commit is contained in:
@@ -52,7 +52,7 @@ public class DistributionController {
|
||||
@SaAdminCheckPermission(value = "distribution:edit", name = "分销修改")
|
||||
@SaCheckMainShop
|
||||
@PutMapping
|
||||
public CzgResult<Boolean> edit(@Validated({UpdateGroup.class, Default.class}) @RequestBody MkDistributionConfigDTO dto) {
|
||||
public CzgResult<Boolean> edit( @RequestBody MkDistributionConfigDTO dto) {
|
||||
return CzgResult.success(configService.edit(StpKit.USER.getShopId(), dto));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
|
||||
package com.czg.market.dto;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import lombok.experimental.Accessors;
|
||||
import java.io.Serial;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 分销记录表 实体类。
|
||||
*
|
||||
* @author ww
|
||||
* @since 2025-10-27
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
public class MkDistributionFlowDTO implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 店铺用户id
|
||||
*/
|
||||
private Long shopUserId;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 店铺id
|
||||
*/
|
||||
private Long shopId;
|
||||
|
||||
/**
|
||||
* 分销员id
|
||||
*/
|
||||
private Long distributionUserId;
|
||||
|
||||
/**
|
||||
* 等级id
|
||||
*/
|
||||
private Long levelId;
|
||||
|
||||
/**
|
||||
* 等级名称
|
||||
*/
|
||||
private String levelName;
|
||||
|
||||
/**
|
||||
* 用户名称
|
||||
*/
|
||||
private String nickname;
|
||||
|
||||
/**
|
||||
* 订单编号
|
||||
*/
|
||||
private String orderNo;
|
||||
|
||||
/**
|
||||
* 订单总金额
|
||||
*/
|
||||
private BigDecimal amount;
|
||||
|
||||
/**
|
||||
* 奖励金额
|
||||
*/
|
||||
private BigDecimal rewardAmount;
|
||||
|
||||
/**
|
||||
* order订单 recharge充值
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* pending待入账 success已入账
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package com.czg.market.entity;
|
||||
|
||||
import com.mybatisflex.annotation.Column;
|
||||
import com.mybatisflex.annotation.Id;
|
||||
import com.mybatisflex.annotation.KeyType;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 分销记录表 实体类。
|
||||
*
|
||||
* @author ww
|
||||
* @since 2025-10-27
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table("mk_distribution_flow")
|
||||
@Accessors(chain = true)
|
||||
public class MkDistributionFlow implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Id(keyType = KeyType.Auto)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 店铺用户id
|
||||
*/
|
||||
private Long shopUserId;
|
||||
|
||||
|
||||
/**
|
||||
* 店铺id
|
||||
*/
|
||||
private Long shopId;
|
||||
|
||||
/**
|
||||
* 分销员id
|
||||
*/
|
||||
private Long distributionUserId;
|
||||
|
||||
/**
|
||||
* 等级id
|
||||
*/
|
||||
private Long levelId;
|
||||
|
||||
/**
|
||||
* 等级
|
||||
*/
|
||||
private Integer level;
|
||||
|
||||
/**
|
||||
* 用户名称
|
||||
*/
|
||||
private String nickname;
|
||||
private String sourceNickName;
|
||||
|
||||
/**
|
||||
* 订单编号
|
||||
*/
|
||||
private String orderNo;
|
||||
|
||||
private Long sourceId;
|
||||
/**
|
||||
* 订单总金额
|
||||
*/
|
||||
private BigDecimal amount;
|
||||
|
||||
/**
|
||||
* 奖励金额
|
||||
*/
|
||||
private BigDecimal rewardAmount;
|
||||
|
||||
/**
|
||||
* order订单 recharge充值
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* pending待入账 success已入账
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@Column(onInsertValue = "now()")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
@Column(onInsertValue = "now()", onUpdateValue = "now()")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 来源用户id
|
||||
*/
|
||||
private Long sourceShopUserId;
|
||||
|
||||
}
|
||||
@@ -16,7 +16,7 @@ import java.util.Map;
|
||||
* @since 2025-10-25
|
||||
*/
|
||||
public interface MkDistributionConfigService extends IService<MkDistributionConfig> {
|
||||
MkDistributionConfigVO detail(Long mainShopId);
|
||||
MkDistributionConfigVO detail(Long shopId);
|
||||
|
||||
Boolean edit(Long shopId, MkDistributionConfigDTO dto);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.czg.market.service;
|
||||
|
||||
import com.mybatisflex.core.service.IService;
|
||||
import com.czg.market.entity.MkDistributionFlow;
|
||||
|
||||
/**
|
||||
* 分销记录表 服务层。
|
||||
*
|
||||
* @author ww
|
||||
* @since 2025-10-27
|
||||
*/
|
||||
public interface MkDistributionFlowService extends IService<MkDistributionFlow> {
|
||||
|
||||
}
|
||||
@@ -54,6 +54,19 @@ public interface MkDistributionUserService extends IService<MkDistributionUser>
|
||||
*/
|
||||
void open(Long userId, BigDecimal amount, Long shopId, Long sourceId);
|
||||
|
||||
/**
|
||||
* 分销商户运营余额充值回调
|
||||
*/
|
||||
void rechargeCallBack(Long userId, Long shopId, BigDecimal amount, Long paymentId);
|
||||
|
||||
/**
|
||||
* 发放分销奖励
|
||||
* @param orderId 订单id
|
||||
* @param orderNo 订单编号
|
||||
* @param amount 金额
|
||||
* @param userId 用户id
|
||||
* @param shopId 店铺id
|
||||
*/
|
||||
void distribute(Long orderId, String orderNo, BigDecimal amount, Long userId, Long shopId, String type);
|
||||
|
||||
}
|
||||
|
||||
@@ -58,6 +58,23 @@ public interface TableValueConstant {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
interface DistributionFlow {
|
||||
@Getter
|
||||
enum Status {
|
||||
PENDING("pending", "待入账"),
|
||||
SUCCESS("sub", "已入账"),
|
||||
SELF_RECHARGE("self_recharge", "自助充值");
|
||||
private final String code;
|
||||
private final String msg;
|
||||
|
||||
Status(String code, String msg) {
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
interface EnableConfig {
|
||||
@Getter
|
||||
|
||||
@@ -5,7 +5,9 @@ import com.czg.account.dto.shopinfo.ShopInfoSubVO;
|
||||
import com.czg.account.entity.ShopInfo;
|
||||
import com.mybatisflex.core.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -17,4 +19,7 @@ import java.util.List;
|
||||
public interface ShopInfoMapper extends BaseMapper<ShopInfo> {
|
||||
|
||||
List<ShopInfoSubVO> getSubList(@Param("lng") String lng, @Param("lat") String lat, @Param("distance") float distance);
|
||||
|
||||
@Update("update tb_shop_info set amount = amount + #{amount} where id = #{id} and amount + #{amount} >= 0")
|
||||
boolean updateAmount(@Param("id") Long id, @Param("amount") BigDecimal amount);
|
||||
}
|
||||
|
||||
@@ -453,9 +453,11 @@ public class ShopInfoServiceImpl extends ServiceImpl<ShopInfoMapper, ShopInfo> i
|
||||
if (shopInfo.getAmount() == null) {
|
||||
shopInfo.setAmount(BigDecimal.ZERO);
|
||||
}
|
||||
shopInfo.setAmount(shopInfo.getAmount().add(amount));
|
||||
updateById(shopInfo);
|
||||
return shopInfo.getAmount();
|
||||
boolean flag = mapper.updateAmount(id, amount);
|
||||
if (!flag) {
|
||||
throw new CzgException("更新失败");
|
||||
}
|
||||
return shopInfo.getAmount().add(amount);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ public class Main {
|
||||
// String packageName = "product";
|
||||
String packageName = "market";
|
||||
// tableName 指定需要生成的表
|
||||
String tableName = "mk_distribution_amount_flow";
|
||||
String tableName = "mk_distribution_flow";
|
||||
String author = "ww";
|
||||
//是否生成DTO实体 默认生成
|
||||
boolean isGenerateDto = true;
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.czg.service.market.mapper;
|
||||
|
||||
import com.mybatisflex.core.BaseMapper;
|
||||
import com.czg.market.entity.MkDistributionFlow;
|
||||
|
||||
/**
|
||||
* 分销记录表 映射层。
|
||||
*
|
||||
* @author ww
|
||||
* @since 2025-10-27
|
||||
*/
|
||||
public interface MkDistributionFlowMapper extends BaseMapper<MkDistributionFlow> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.czg.service.market.service.impl;
|
||||
|
||||
import com.mybatisflex.spring.service.impl.ServiceImpl;
|
||||
import com.czg.market.entity.MkDistributionFlow;
|
||||
import com.czg.market.service.MkDistributionFlowService;
|
||||
import com.czg.service.market.mapper.MkDistributionFlowMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 分销记录表 服务层实现。
|
||||
*
|
||||
* @author ww
|
||||
* @since 2025-10-27
|
||||
*/
|
||||
@Service
|
||||
public class MkDistributionFlowServiceImpl extends ServiceImpl<MkDistributionFlowMapper, MkDistributionFlow> implements MkDistributionFlowService{
|
||||
|
||||
}
|
||||
@@ -10,14 +10,8 @@ import com.czg.account.service.ShopUserService;
|
||||
import com.czg.constant.TableValueConstant;
|
||||
import com.czg.exception.CzgException;
|
||||
import com.czg.market.dto.MkDistributionUserDTO;
|
||||
import com.czg.market.entity.MkDistributionAmountFlow;
|
||||
import com.czg.market.entity.MkDistributionConfig;
|
||||
import com.czg.market.entity.MkDistributionLevelConfig;
|
||||
import com.czg.market.entity.MkDistributionUser;
|
||||
import com.czg.market.service.MkDistributionAmountFlowService;
|
||||
import com.czg.market.service.MkDistributionConfigService;
|
||||
import com.czg.market.service.MkDistributionLevelConfigService;
|
||||
import com.czg.market.service.MkDistributionUserService;
|
||||
import com.czg.market.entity.*;
|
||||
import com.czg.market.service.*;
|
||||
import com.czg.market.vo.MkDistributionConfigVO;
|
||||
import com.czg.order.dto.MkDistributionPayDTO;
|
||||
import com.czg.order.entity.OrderPayment;
|
||||
@@ -26,14 +20,17 @@ import com.czg.sa.StpKit;
|
||||
import com.czg.service.market.mapper.MkDistributionUserMapper;
|
||||
import com.czg.system.service.WxService;
|
||||
import com.czg.utils.AssertUtil;
|
||||
import com.czg.utils.FunUtils;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import com.mybatisflex.spring.service.impl.ServiceImpl;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@@ -46,6 +43,7 @@ import java.util.stream.Collectors;
|
||||
* @author ww
|
||||
* @since 2025-10-27
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class MkDistributionUserServiceImpl extends ServiceImpl<MkDistributionUserMapper, MkDistributionUser> implements MkDistributionUserService {
|
||||
|
||||
@@ -55,6 +53,9 @@ public class MkDistributionUserServiceImpl extends ServiceImpl<MkDistributionUse
|
||||
private MkDistributionLevelConfigService levelConfigService;
|
||||
@Resource
|
||||
private MkDistributionAmountFlowService distributionAmountFlowService;
|
||||
@Resource
|
||||
private MkDistributionFlowService distributionFlowService;
|
||||
|
||||
@DubboReference
|
||||
private ShopUserService shopUserService;
|
||||
@DubboReference
|
||||
@@ -188,4 +189,69 @@ public class MkDistributionUserServiceImpl extends ServiceImpl<MkDistributionUse
|
||||
.setMainShopId(mainShopId).setShopId(shopId).setAmount(finalAmount).setChangeAmount(amount).setSourceId(paymentId)
|
||||
.setRemark("自助充值").setOpAccount(StpKit.USER.getAccount()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void distribute(Long sourceId, String orderNo, BigDecimal amount, Long sourceUserId, Long shopId, String type) {
|
||||
FunUtils.safeRunVoid(() -> {
|
||||
AssertUtil.isTrue(amount.compareTo(BigDecimal.ZERO) == 0, "分销金额不能为0");
|
||||
MkDistributionConfigVO config = mkDistributionConfigService.detail(shopId);
|
||||
AssertUtil.isTrue(config.getIsEnable() != 1, "分销未开启");
|
||||
|
||||
// 当前用户上级分销员
|
||||
ShopUser sourceShopUserInfo = shopUserService.getShopUserInfo(shopId, sourceUserId);
|
||||
if (sourceShopUserInfo.getDistributionUserId() == null) {
|
||||
return;
|
||||
}
|
||||
MkDistributionUser distributionUser = getOne(new QueryWrapper().eq(MkDistributionUser::getId, sourceShopUserInfo));
|
||||
AssertUtil.isNull(distributionUser, "分销员不存在");
|
||||
AssertUtil.isTrue(distributionUser.getStatus() != 1, "分销员未开启");
|
||||
|
||||
// 上上级分销员
|
||||
if (distributionUser.getParentId() != null) {
|
||||
|
||||
}
|
||||
|
||||
MkDistributionLevelConfig level = levelConfigService.getById(distributionUser.getDistributionLevelId());
|
||||
AssertUtil.isNull(level, "分销等级不存在");
|
||||
|
||||
if (config.getRewardCount() != null && config.getRewardCount() > 0) {
|
||||
long count = distributionFlowService.count(new QueryWrapper().eq(MkDistributionFlow::getSourceShopUserId, sourceUserId)
|
||||
.eq(MkDistributionFlow::getShopUserId, distributionUser.getShopUserId()));
|
||||
if (count >= config.getRewardCount()) {
|
||||
log.info("分销员{}已达到奖励次数上限, 次数: {}", distributionUser.getShopUserId(), config.getRewardCount());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 店铺信息
|
||||
ShopInfo shopInfo = shopInfoService.getById(shopId);
|
||||
BigDecimal oneAmount = amount.multiply(level.getLevelOneCommission().divide(BigDecimal.valueOf(100), RoundingMode.DOWN));
|
||||
|
||||
boolean flag = true;
|
||||
BigDecimal finalAmount = BigDecimal.ZERO;
|
||||
try {
|
||||
shopInfoService.updateAmount(shopId, oneAmount.negate());
|
||||
}catch (Exception e) {
|
||||
flag = false;
|
||||
}
|
||||
|
||||
MkDistributionFlow mkDistributionFlow = new MkDistributionFlow().setShopUserId(distributionUser.getShopUserId()).setShopId(distributionUser.getShopId()).setDistributionUserId(distributionUser.getId())
|
||||
.setLevelId(distributionUser.getDistributionLevelId()).setLevel(level.getLevel()).setSourceNickName(sourceShopUserInfo.getNickName()).setOrderNo(orderNo)
|
||||
.setSourceId(sourceId).setAmount(amount).setType(type).setStatus(flag ? TableValueConstant.DistributionFlow.Status.SUCCESS.getCode() :
|
||||
TableValueConstant.DistributionFlow.Status.PENDING.getCode())
|
||||
.setRewardAmount(oneAmount);
|
||||
distributionFlowService.save(mkDistributionFlow);
|
||||
|
||||
if (flag) {
|
||||
distributionAmountFlowService.save(new MkDistributionAmountFlow()
|
||||
.setType(TableValueConstant.DistributionAmountFlow.Type.SELF_RECHARGE.getCode())
|
||||
.setShopId(shopId).setAmount(finalAmount).setChangeAmount(amount).setSourceId(mkDistributionFlow.getId())
|
||||
.setRemark("自助充值").setOpAccount(StpKit.USER.getAccount()));
|
||||
}
|
||||
|
||||
|
||||
}, "分销方法执行失败");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.czg.service.market.mapper.MkDistributionFlowMapper">
|
||||
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user