[fix]优化分账逻辑

This commit is contained in:
wangqx 2025-07-01 16:52:37 +08:00
parent 9b33dbde98
commit d2d8c6ee40
12 changed files with 153 additions and 98 deletions

View File

@ -19,16 +19,22 @@ import java.math.BigDecimal;
@Schema(description="会员账户表 查询 对象") @Schema(description="会员账户表 查询 对象")
@Data @Data
public class MemberAccountBO extends BaseBO { public class MemberAccountBO extends BaseBO {
@Schema(description ="积分余额 精确匹配")
private BigDecimal integralBalance;
@Schema(description ="历史总共积分 精确匹配")
private BigDecimal totalIntegralBalance;
@Schema(description ="ID")
private Long id;
/**
* 账户类型 1 用户 2 商家 3 代理 4 平台
*/
private Integer type;
@Schema(description ="MEMBER_ID") @Schema(description ="MEMBER_ID")
private Long memberId; private Long memberId;
@Schema(description ="积分余额")
private BigDecimal integral;
@Schema(description ="钱包") @Schema(description ="钱包")
private BigDecimal wallet; private BigDecimal wallet;
@ -36,17 +42,17 @@ public class MemberAccountBO extends BaseBO {
@Schema(description ="营收") @Schema(description ="营收")
private BigDecimal revenue; private BigDecimal revenue;
private String phone;
private String name;
@Schema(description ="余额") @Schema(description ="余额")
private BigDecimal moneyBalance; private BigDecimal moneyBalance;
public LambdaQueryWrapper<MemberAccount> toWrapper() { public LambdaQueryWrapper<MemberAccount> toWrapper() {
LambdaQueryWrapper<MemberAccount> queryWrapper = new LambdaQueryWrapper<>(); return new LambdaQueryWrapper<MemberAccount>()
queryWrapper.eq(getIntegralBalance() != null,MemberAccount::getIntegralBalance, integralBalance); .eq(MemberAccount::getId, id)
queryWrapper.eq(getTotalIntegralBalance() != null,MemberAccount::getTotalIntegralBalance, totalIntegralBalance); .eq(MemberAccount::getType, type)
queryWrapper.eq(getMemberId() != null,MemberAccount::getMemberId, memberId) .eq(MemberAccount::getMemberId, id);
;
return queryWrapper;
} }
} }

View File

@ -21,26 +21,29 @@ import java.math.BigDecimal;
@Builder(toBuilder = true) @Builder(toBuilder = true)
public class MemberAccount extends BaseAudit { public class MemberAccount extends BaseAudit {
@Excel(name = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@Schema(description ="MEMBER_ID") @Schema(description ="MEMBER_ID")
@TableId(value="member_id")
private Long memberId; private Long memberId;
private String name;
/**
* 账户类型 1 用户 2 商家 3 代理 4 平台
*/
private Integer type;
@Schema(description ="积分余额") @Schema(description ="积分余额")
private BigDecimal integralBalance; private BigDecimal integral;
@Schema(description ="历史总共积分")
private BigDecimal totalIntegralBalance;
@Schema(description ="余额")
private BigDecimal moneyBalance;
@Schema(description ="钱包") @Schema(description ="钱包")
private BigDecimal wallet; private BigDecimal wallet ;
@Schema(description ="营收") @Schema(description ="营收")
private BigDecimal revenue; private BigDecimal revenue ;
} }

View File

@ -16,16 +16,8 @@ public class MemberAccountVO {
/** MEMBER_ID */ /** MEMBER_ID */
private Long memberId; private Long memberId;
/** 积分余额 */ /** 积分余额 */
@Excel(name = "积分余额") @Excel(name = "积分")
private BigDecimal integralBalance; private BigDecimal integral ;
/** 历史总共积分 */
@Excel(name = "历史总共积分")
private BigDecimal totalIntegralBalance;
@Schema(description ="余额")
@Excel(name = "余额")
private BigDecimal moneyBalance;
@Schema(description ="钱包") @Schema(description ="钱包")
@ -35,4 +27,13 @@ public class MemberAccountVO {
@Schema(description ="营收") @Schema(description ="营收")
@Excel(name = "营收") @Excel(name = "营收")
private BigDecimal revenue; private BigDecimal revenue;
@Schema(description ="id")
private Long id;
@Schema(description ="name")
private String name;
@Schema(description ="phone")
private String phone;
} }

View File

@ -13,15 +13,5 @@ import java.util.List;
* @author zcc * @author zcc
*/ */
public interface MemberAccountMapper extends BaseMapper<MemberAccount> { public interface MemberAccountMapper extends BaseMapper<MemberAccount> {
/**
* 查询会员账户表列表
*
* @param memberAccount 会员账户表
* @return 会员账户表集合
*/
List<MemberAccount> selectByEntity(MemberAccount memberAccount);
int updateIntegralBalance(@Param("amount") BigDecimal amount, @Param("memberId") Long memberId);
int updateIntegral(@Param("useIntegral") BigDecimal useIntegral, @Param("memberId") Long memberId);
} }

View File

@ -35,17 +35,7 @@ public class MemberAccountServiceImpl extends ServiceImpl<MemberAccountMapper,Me
* @return 会员账户表 * @return 会员账户表
*/ */
public IPage<MemberAccount> selectList(MemberAccountBO query, IPage page) { public IPage<MemberAccount> selectList(MemberAccountBO query, IPage page) {
return baseMapper.selectPage(page,query.toWrapper());
QueryWrapper<MemberAccount> qw = new QueryWrapper<>();
BigDecimal integralBalance = query.getIntegralBalance();
if (integralBalance != null) {
qw.eq("integral_balance", integralBalance);
}
BigDecimal totalIntegralBalance = query.getTotalIntegralBalance();
if (totalIntegralBalance != null) {
qw.eq("total_integral_balance", totalIntegralBalance);
}
return baseMapper.selectPage(page,qw);
} }

View File

@ -3,32 +3,4 @@
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wzj.soopin.member.mapper.MemberAccountMapper"> <mapper namespace="com.wzj.soopin.member.mapper.MemberAccountMapper">
<resultMap type="MemberAccount" id="MemberAccountResult">
<result property="memberId" column="member_id"/>
<result property="integralBalance" column="integral_balance"/>
<result property="totalIntegralBalance" column="total_integral_balance"/>
<result property="updateTime" column="update_time"/>
<result property="createTime" column="create_time"/>
</resultMap>
<sql id="selectMemberAccountVo">
select member_id, integral_balance, total_integral_balance, update_time, create_time from ums_member_account
</sql>
<update id="updateIntegralBalance">
update ums_member_account set integral_balance = integral_balance + #{amount},total_integral_balance = total_integral_balance + #{amount},update_time = now()
where member_id = #{memberId}
</update>
<update id="updateIntegral">
update ums_member_account set integral_balance = integral_balance - #{useIntegral},update_time = now()
where member_id = #{memberId}
</update>
<select id="selectByEntity" parameterType="MemberAccount" resultMap="MemberAccountResult">
<include refid="selectMemberAccountVo"/>
<where>
<if test="integralBalance != null "> and integral_balance = #{integralBalance}</if>
<if test="totalIntegralBalance != null "> and total_integral_balance = #{totalIntegralBalance}</if>
</where>
</select>
</mapper> </mapper>

View File

@ -178,6 +178,7 @@ public class Order extends BaseAudit {
@Schema(description = "提现状态1->等待转账2->转帐中;3->转账成功;4->转账失败") @Schema(description = "提现状态1->等待转账2->转帐中;3->转账成功;4->转账失败")
private Integer withdrawStatus; private Integer withdrawStatus;
@Schema(description = "配送方式 1->到店核销2->自提;3->配送;") @Schema(description = "配送方式 1->到店核销2->自提;3->配送;")
private Integer distribution; private Integer distribution;

View File

@ -129,4 +129,6 @@ public class SysTenant extends BaseEntity {
* 入驻时间 * 入驻时间
*/ */
private LocalDateTime joinTime; private LocalDateTime joinTime;
private Long accountId;
} }

View File

@ -50,7 +50,7 @@ public class DivideRuleController {
@Log(title = "修改", businessType = BusinessType.UPDATE) @Log(title = "修改", businessType = BusinessType.UPDATE)
@PostMapping("/update") @PostMapping("/update")
public R update(@RequestBody DivideRuleBO bo) { public R update(@RequestBody DivideRuleBO bo) {
service.save(convert.toPo(bo)); service.updateById(convert.toPo(bo));
return R.ok(); return R.ok();
} }

View File

@ -14,7 +14,9 @@ public enum DivideRuleDetailType {
/** /**
* 代理 * 代理
*/ */
PROXY(3, "代理"); PROXY(3, "代理"),
REFERENCE(4, "推广"),;
private int value; private int value;
private String desc; private String desc;
@ -32,4 +34,13 @@ public enum DivideRuleDetailType {
public String getDesc() { public String getDesc() {
return desc; return desc;
} }
public static DivideRuleDetailType getEnum(int value) {
for (DivideRuleDetailType type : DivideRuleDetailType.values()) {
if (type.getValue() == value) {
return type;
}
}
return null;
}
} }

View File

@ -2,6 +2,10 @@ package com.wzj.soopin.transaction.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wzj.soopin.member.domain.po.Member;
import com.wzj.soopin.member.domain.po.MemberAccount;
import com.wzj.soopin.member.service.IMemberAccountService;
import com.wzj.soopin.member.service.IMemberService;
import com.wzj.soopin.order.domain.entity.Order; import com.wzj.soopin.order.domain.entity.Order;
import com.wzj.soopin.order.service.OrderItemService; import com.wzj.soopin.order.service.OrderItemService;
import com.wzj.soopin.order.service.OrderService; import com.wzj.soopin.order.service.OrderService;
@ -25,6 +29,8 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.service.ConfigService; import org.dromara.common.core.service.ConfigService;
import org.dromara.system.domain.vo.SysTenantVo;
import org.dromara.system.service.ISysTenantService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -63,6 +69,12 @@ public class DivideServiceImpl extends ServiceImpl<DivideMapper, Divide> impleme
private final IYishengService yishengService; private final IYishengService yishengService;
private final IMemberAccountService accountService;
private final ISysTenantService sysTenantService;
private final IMemberService memberService;
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public boolean save(DivideBO bo) { public boolean save(DivideBO bo) {
@ -168,12 +180,15 @@ public class DivideServiceImpl extends ServiceImpl<DivideMapper, Divide> impleme
.build(); .build();
super.save(divide); super.save(divide);
//生成分账明细信息
List<DivideDetail> details = saveDetails(order, divide.getId(), totalFee, totalAmount, rule); List<DivideDetail> details = saveDetails(order, divide.getId(), totalFee, totalAmount, rule);
//同步订单状态
syncOrderStatus(order); syncOrderStatus(order);
//同步易生支付
syncYisheng(details); syncYisheng(details);
return false; return true;
} }
@Override @Override
@ -228,13 +243,19 @@ public class DivideServiceImpl extends ServiceImpl<DivideMapper, Divide> impleme
if (item.getType() == DivideRuleDetailType.PLATFORM.getValue()) { if (item.getType() == DivideRuleDetailType.PLATFORM.getValue()) {
account = getPlatformAccount(); account = getPlatformAccount();
} else if (item.getType() == DivideRuleDetailType.PROXY.getValue()) { } else if (item.getType() == DivideRuleDetailType.PROXY.getValue()) {
account = getProxyAccount(); account = getProxyAccount(Long.valueOf(order.getTenantId()));
} else if (item.getType() == DivideRuleDetailType.SELLER.getValue()) { } else if (item.getType() == DivideRuleDetailType.SELLER.getValue()) {
account = getSellerAccount(); account = getSellerAccount(Long.valueOf(order.getTenantId()));
} else if (item.getType() == DivideRuleDetailType.REFERENCE.getValue()) {
account = getReferenceAccount(order.getMemberId());
}
if (account == null) {
detail.setAccountId(Long.parseLong(account.get("accountId")));
detail.setAccountName(account.get("accountName"));
return detail;
} else {
throw new ServiceException(StringUtils.format("%s未找到分账账户", DivideRuleDetailType.getEnum(item.getType())));
} }
detail.setAccountId(Long.parseLong(account.get("accountId")));
detail.setAccountName(account.get("accountName"));
return detail;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
detailMapper.insertBatch(details); detailMapper.insertBatch(details);
return details; return details;
@ -247,17 +268,75 @@ public class DivideServiceImpl extends ServiceImpl<DivideMapper, Divide> impleme
}}; }};
} }
private Map<String, String> getProxyAccount() { /**
* 获取达人的账户信息
*
* @param memberId
* @return
*/
private Map<String, String> getReferenceAccount(Long memberId) {
Member member = memberService.getById(memberId);
if (member == null) {
return null;
}
//推广人
Long inviteUserId = member.getSpreadUid();
if (inviteUserId == null) {
return null;
}
MemberAccount account = accountService.getMemberAccount(inviteUserId);
if (account == null) {
return null;
}
return new HashMap<>() {{ return new HashMap<>() {{
put("account", "123456"); put("accountId", account.getId() + "");
put("name", "代理"); put("accountName", account.getName());
}}; }};
} }
private Map<String, String> getSellerAccount() { /**
* 获取代理的账户信息
*
* @param sellerId
* @return
*/
private Map<String, String> getProxyAccount(Long sellerId) {
SysTenantVo tenant = sysTenantService.queryById(sellerId);
Long inviteUserId = tenant.getInviteUserId();
if (inviteUserId != null) {
return null;
}
MemberAccount account = accountService.getMemberAccount(inviteUserId);
if (account == null) {
return null;
}
return new HashMap<>() {{ return new HashMap<>() {{
put("account", "123456"); put("accountId", account.getId() + "");
put("name", "卖家"); put("accountName", account.getName());
}};
}
/**
* 获取商家的账户信息
*
* @param sellerId
* @return
*/
private Map<String, String> getSellerAccount(Long sellerId) {
SysTenantVo tenant = sysTenantService.queryById(sellerId);
if (tenant != null) {
return null;
}
MemberAccount account = accountService.getMemberAccount(tenant.getId());
if (account == null) {
return null;
}
return new HashMap<>() {{
put("accountId", account.getId() + "");
put("accountName", account.getName());
}}; }};
} }

View File

@ -74,7 +74,7 @@ public class WithdrawServiceImpl extends ServiceImpl<WithdrawMapper, Withdraw> i
throw new RuntimeException("用户不存在"); throw new RuntimeException("用户不存在");
} }
//检查当前用于的账户余额是否充足 //检查当前用于的账户余额是否充足
BigDecimal balance = memberAccount.getMoneyBalance(); BigDecimal balance = memberAccount.getWallet();
if (balance.compareTo(withdraw.getMoney()) < 0) { if (balance.compareTo(withdraw.getMoney()) < 0) {
throw new RuntimeException("用户余额不足"); throw new RuntimeException("用户余额不足");
@ -104,7 +104,7 @@ public class WithdrawServiceImpl extends ServiceImpl<WithdrawMapper, Withdraw> i
//// TODO: 2025/6/21 测试的时候用计算的 测试完用易生的 //// TODO: 2025/6/21 测试的时候用计算的 测试完用易生的
BigDecimal finalBalance = balance.subtract(withdraw.getMoney()); BigDecimal finalBalance = balance.subtract(withdraw.getMoney());
yishengAccountVO = yishengService.getYishengAccount(withdraw.getMemberId()); yishengAccountVO = yishengService.getYishengAccount(withdraw.getMemberId());
memberAccountService.updateById(memberAccount.toBuilder().moneyBalance(balance.subtract(finalBalance)).build()); memberAccountService.updateById(memberAccount.toBuilder().wallet(balance.subtract(finalBalance)).build());
//生成账户变动记录bh //生成账户变动记录bh
MemberAccountChangeRecord memberAccountChangeRecord = MemberAccountChangeRecord.builder() MemberAccountChangeRecord memberAccountChangeRecord = MemberAccountChangeRecord.builder()
.memberId(withdraw.getMemberId()) .memberId(withdraw.getMemberId())