新增用户红包手续费字段

This commit is contained in:
tianfeng 2026-01-09 18:27:15 +08:00
parent d2a3c8e6e1
commit cc5fbde032
7 changed files with 47 additions and 13 deletions

View File

@ -5,7 +5,6 @@ import com.red.circle.other.app.convertor.UserRedPacketAppConvertor;
import com.red.circle.other.app.dto.clientobject.UserRedPacketCO;
import com.red.circle.other.app.dto.cmd.SendUserRedPacketCmd;
import com.red.circle.other.domain.gateway.UserRedPacketGateway;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.redpacket.RoomRedPacketType;
import com.red.circle.other.domain.redpacket.UserRedPacket;
import com.red.circle.other.domain.redpacket.UserRedPacketStatus;
@ -39,6 +38,11 @@ public class SendUserRedPacketCmdExe {
private final UserRedPacketCacheService userRedPacketCacheService;
private final WalletGoldClient walletGoldClient;
/**
* 手续费比例10%
*/
private static final double HANDLING_FEE_RATE = 0.1;
/**
* 执行发用户红包
*/
@ -55,36 +59,44 @@ public class SendUserRedPacketCmdExe {
LocalDateTime expireTime = LocalDateTime.now().plusHours(24);
UserRedPacket redPacket = buildRedPacket(cmd, senderUserId, receiverUserId, packetId, expireTime);
Long handlingFee = calculateHandlingFee(cmd.getTotalAmount());
UserRedPacket redPacket = buildRedPacket(cmd, senderUserId, receiverUserId, packetId, expireTime, handlingFee);
userRedPacketGateway.save(redPacket);
deductUserGold(senderUserId, cmd, packetId);
deductUserGold(senderUserId, cmd, packetId, handlingFee);
cacheRedPacketData(redPacket);
log.info("发用户红包成功 senderUserId={} receiverUserId={} packetId={} amount={}",
senderUserId, receiverUserId, packetId, cmd.getTotalAmount());
return UserRedPacketAppConvertor.toCO(redPacket);
}
/**
* 计算手续费10%
*/
private Long calculateHandlingFee(Long totalAmount) {
return (long) Math.ceil(totalAmount * HANDLING_FEE_RATE);
}
/**
* 参数校验
*/
private void validateParams(SendUserRedPacketCmd cmd) {
if (cmd.getTotalAmount() < 100 || cmd.getTotalAmount() > 50000) {
if (cmd.getTotalAmount() < 500 || cmd.getTotalAmount() > 250000) {
throw new RuntimeException(OtherErrorCode.RED_PACKET_AMOUNT_ERROR.getMessage());
}
}
/**
* 扣除用户金币
* 扣除用户金币红包金额 + 手续费
*/
private void deductUserGold(Long userId, SendUserRedPacketCmd cmd, String packetId) {
private void deductUserGold(Long userId, SendUserRedPacketCmd cmd, String packetId, Long handlingFee) {
Long totalDeduct = cmd.getTotalAmount() + handlingFee;
GoldReceiptCmd build = GoldReceiptCmd.builder()
.appExpenditure()
.userId(userId)
.amount(PennyAmount.ofDollar(cmd.getTotalAmount()))
.amount(PennyAmount.ofDollar(totalDeduct))
.eventId(packetId)
.sysOrigin(cmd.getReqSysOrigin().getOrigin())
.origin(GoldOrigin.USER_RED_PACKET)
@ -93,7 +105,7 @@ public class SendUserRedPacketCmdExe {
try {
walletGoldClient.changeBalance(build);
} catch (Exception e) {
log.error("扣除金币失败 userId={} amount={} packetId={}", userId, cmd.getTotalAmount(), packetId, e);
log.error("扣除金币失败 userId={} totalDeduct={} packetId={}", userId, totalDeduct, packetId, e);
ResponseAssert.isTrue(WalletErrorCode.INSUFFICIENT_BALANCE, false);
}
}
@ -102,13 +114,15 @@ public class SendUserRedPacketCmdExe {
* 构建红包对象
*/
private UserRedPacket buildRedPacket(SendUserRedPacketCmd cmd, Long senderUserId,
Long receiverUserId, String packetId, LocalDateTime expireTime) {
Long receiverUserId, String packetId, LocalDateTime expireTime,
Long handlingFee) {
return UserRedPacket.builder()
.packetId(packetId)
.senderUserId(senderUserId)
.receiverUserId(receiverUserId)
.packetType(RoomRedPacketType.FIXED.getCode())
.totalAmount(cmd.getTotalAmount())
.handlingFee(handlingFee)
.expireTime(expireTime)
.status(UserRedPacketStatus.PENDING.getCode())
.refundStatus(0)
@ -125,6 +139,7 @@ public class SendUserRedPacketCmdExe {
packetData.put("senderUserId", redPacket.getSenderUserId());
packetData.put("receiverUserId", redPacket.getReceiverUserId());
packetData.put("totalAmount", redPacket.getTotalAmount());
packetData.put("handlingFee", redPacket.getHandlingFee());
packetData.put("expireTime", redPacket.getExpireTime().toString());
packetData.put("status", redPacket.getStatus());

View File

@ -5,7 +5,6 @@ import com.red.circle.other.app.dto.clientobject.SimpleUserInfoCO;
import com.red.circle.other.app.dto.clientobject.UserRedPacketCO;
import com.red.circle.other.domain.redpacket.UserRedPacket;
import java.sql.Time;
import java.sql.Timestamp;
/**
@ -22,6 +21,7 @@ public class UserRedPacketAppConvertor {
.senderUserId(domain.getSenderUserId())
.receiverUserId(domain.getReceiverUserId())
.totalAmount(domain.getTotalAmount())
.handlingFee(domain.getHandlingFee())
.status(domain.getStatus())
.expireTime(domain.getExpireTime() != null ? Timestamp.valueOf(domain.getExpireTime()) : null)
.grabbedAt(domain.getGrabbedAt() != null ? Timestamp.valueOf(domain.getGrabbedAt()) : null)
@ -40,6 +40,7 @@ public class UserRedPacketAppConvertor {
.senderInfo(senderInfo)
.receiverInfo(receiverInfo)
.totalAmount(domain.getTotalAmount())
.handlingFee(domain.getHandlingFee())
.status(domain.getStatus())
.expireTime(domain.getExpireTime() != null ? Timestamp.valueOf(domain.getExpireTime()) : null)
.grabbedAt(domain.getGrabbedAt() != null ? Timestamp.valueOf(domain.getGrabbedAt()) : null)

View File

@ -47,6 +47,11 @@ public class UserRedPacketCO {
*/
private Long totalAmount;
/**
* 手续费金币10%
*/
private Long handlingFee;
/**
* 状态1-待领取 2-已领取 3-已过期
*/

View File

@ -46,6 +46,11 @@ public class UserRedPacket {
*/
private Long totalAmount;
/**
* 手续费10%
*/
private Long handlingFee;
/**
* 过期时间
*/

View File

@ -19,6 +19,7 @@ public class UserRedPacketConvertor {
.receiverUserId(entity.getReceiverUserId())
.packetType(entity.getPacketType())
.totalAmount(entity.getTotalAmount())
.handlingFee(entity.getHandlingFee())
.expireTime(entity.getExpireTime())
.status(entity.getStatus())
.refundStatus(entity.getRefundStatus())
@ -39,6 +40,7 @@ public class UserRedPacketConvertor {
entity.setReceiverUserId(domain.getReceiverUserId());
entity.setPacketType(domain.getPacketType());
entity.setTotalAmount(domain.getTotalAmount());
entity.setHandlingFee(domain.getHandlingFee());
entity.setExpireTime(domain.getExpireTime());
entity.setStatus(domain.getStatus());
entity.setRefundStatus(domain.getRefundStatus());

View File

@ -45,6 +45,11 @@ public class UserRedPacketEntity {
*/
private Long totalAmount;
/**
* 手续费10%
*/
private Long handlingFee;
/**
* 过期时间
*/

View File

@ -9,6 +9,7 @@
<result column="receiver_user_id" property="receiverUserId"/>
<result column="packet_type" property="packetType"/>
<result column="total_amount" property="totalAmount"/>
<result column="handling_fee" property="handlingFee"/>
<result column="expire_time" property="expireTime"/>
<result column="status" property="status"/>
<result column="refund_status" property="refundStatus"/>