送礼记录-雪花主键-无锁化唯一主键插入

This commit is contained in:
2025-09-23 17:10:35 +08:00
committed by 杨志恒
parent abb0b2e9f3
commit 1ece3f668f
10 changed files with 206 additions and 10 deletions

View File

@@ -9,6 +9,7 @@ import lombok.Data;
*/
@Data
public class GiftMessage extends BaseMqMessage {
private Long id;
private String messId; // 消息唯一标识
private Long messTime; // 消息创建时间
private Long sendUid; // 发送者UID

View File

@@ -1,7 +1,6 @@
package com.accompany.business.service.gift;
import com.accompany.business.event.ActivityOfDayConsumeEvent;
import com.accompany.business.event.AnchorFansSendGiftEvent;
import com.accompany.business.event.GiftMessageEvent;
import com.accompany.business.event.RoomPKEvent;
import com.accompany.business.message.ActivityOfDayConsumeMessage;
@@ -20,6 +19,7 @@ import com.accompany.core.service.base.BaseService;
import com.accompany.core.vo.vip.VipBaseInfoVO;
import com.accompany.sharding.model.GiftSendRecord;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
@@ -48,6 +48,8 @@ public class GiftMessageService extends BaseService {
private ActivityUserLevelExpService activityUserLevelExpService;
@Autowired
private GiftRateService giftRateService;
@Autowired
private IdentifierGenerator identifierGenerator;
public void handleGiftMessage(GiftMessage giftMessage) {
// 防止消息被重复消费
@@ -132,7 +134,92 @@ public class GiftMessageService extends BaseService {
//发布事件
applicationContext.publishEvent(new GiftMessageEvent(giftMessage));
applicationContext.publishEvent(new RoomPKEvent(giftMessage));
applicationContext.publishEvent(new AnchorFansSendGiftEvent(giftSendRecord));
// applicationContext.publishEvent(new AnchorFansSendGiftEvent(giftSendRecord));
// 删除该标识,表示消息已经消费过
jedisService.hdel(RedisKey.mq_gift_status.getKey(), giftMessage.getMessId());
}
public void handleGiftMessageV2(GiftMessage giftMessage) {
logger.info("【处理礼物mq】 giftMessage: {}", giftMessage);
long totalGoldNum = giftMessage.getGoldNum();
byte giftType = giftMessage.getGiftType();
giftMessage.setRealGoldNum(totalGoldNum);
if (Constant.GiftType.SUPER_LUCKY == giftType
|| Constant.GiftType.LUCKY_24 == giftType
|| Constant.GiftType.BRAVO_GIFT == giftType
|| Constant.GiftType.LUCKY_25 == giftType){
giftMessage.setGoldNum(0L);
}
//只用来insert,下面还会算一次普通礼物的钻石流水,这里的流水不给事件消费,因为幸运礼物是单独走的消费
Double diamondFlow = giftRateService.calDiamondFlow(giftMessage.getPartitionId(), giftMessage.getRoomUid(), giftType, giftMessage.getRealGoldNum());
GiftSendRecord giftSendRecord = buildGiftSendRecord(giftMessage, diamondFlow);
// 先插入giftSendRecord
int row = giftSendRecordService.insertRecordIgnore(giftSendRecord);
if (row <= 0){
return;
}
logger.info("【处理礼物mq】 giftMessageId {} 插入gift_send_record {}", giftMessage.getMessId(), JSON.toJSONString(giftSendRecord));
String objId = giftSendRecord.getSendRecordId().toString();
double amount = giftMessage.getRealGoldNum().doubleValue();
BillObjTypeEnum inEnum = BillObjTypeEnum.GIFT_PERSON_INCOME;
BillObjTypeEnum outEnum = BillObjTypeEnum.GIFT_PERSON_PAY;
if (giftMessage.getRoomUid() != null && giftMessage.getRoomUid() > 0) {
inEnum = BillObjTypeEnum.GIFT_ROOM_INCOME;
outEnum = BillObjTypeEnum.GIFT_ROOM_PAY;
}
if (giftMessage.getGiftType() == GiftTypeEnum.LUCKY_24.getType()){
outEnum = BillObjTypeEnum.LUCKY_24_GIFT_PAY;
} else if (giftMessage.getGiftType() == GiftTypeEnum.BRAVO.getType()) {
outEnum = BillObjTypeEnum.BRAVO_GIFT_PAY;
} else if (giftMessage.getGiftType() == GiftTypeEnum.LUCKY_25.getType()) {
outEnum = BillObjTypeEnum.LUCKY_25_GIFT_PAY;
}
Date giftSendTime = new Date(giftMessage.getMessTime());
// 背包送礼不算钱
if (null != giftMessage.getGiftSource() && Constant.GiftSource.BACKPACK == giftMessage.getGiftSource()) {
amount = 0D;
if (null != giftMessage.getAfterPurse()){
giftMessage.getAfterPurse().setUpdateTime(giftSendTime);
}
}
// 插入账单记录表(发送礼物用户)
billRecordService.insertGiftSendBillRecord(giftMessage.getSendUid(), giftMessage.getRecvUid(),
giftMessage.getRoomUid(), objId, outEnum, amount,
giftMessage.getGiftId(), giftMessage.getGiftNum(), totalGoldNum, giftSendTime,
giftMessage.getAfterPurse());
Double diamondNum = 0D;//钻石流水
//处理逻辑
if (Constant.GiftType.SUPER_LUCKY != giftType
&& Constant.GiftType.LUCKY_24 != giftType
&& Constant.GiftType.BRAVO_GIFT != giftType
&& Constant.GiftType.LUCKY_25 != giftType) {
//按配置比例分配主播、 会长、房主收益
diamondNum = giftEarnAllotService.allotGiftEarn(giftSendRecord, objId, inEnum);
//增加送礼用户和收礼用户的财富或魅力经验
addUserExperience(giftMessage);
applicationContext.publishEvent(new ActivityOfDayConsumeEvent(ActivityOfDayConsumeMessage.builder()
.sendUid(giftMessage.getSendUid())
.messTime(new Date(giftMessage.getMessTime()))
.totalDiamondNum(giftMessage.getGoldNum().doubleValue()).consumeType("Normal Gift").build()));
}
giftMessage.setDiamondNum(diamondNum);
//发布事件
applicationContext.publishEvent(new GiftMessageEvent(giftMessage));
applicationContext.publishEvent(new RoomPKEvent(giftMessage));
// applicationContext.publishEvent(new AnchorFansSendGiftEvent(giftSendRecord));
// 删除该标识,表示消息已经消费过
jedisService.hdel(RedisKey.mq_gift_status.getKey(), giftMessage.getMessId());
@@ -200,6 +287,35 @@ public class GiftMessageService extends BaseService {
return new BigDecimal(goldNum).multiply(BigDecimal.valueOf(1 + Double.parseDouble(levelBuff.getItemValue()))).setScale(0, BigDecimal.ROUND_DOWN).longValue();
}
/**
* 组装礼物赠送记录对象
*
* @param giftMessage 礼物消息
* @param diamondFlow 钻石流水
* @return GiftSendRecord对象
*/
private GiftSendRecord buildGiftSendRecord(GiftMessage giftMessage, Double diamondFlow) {
// 插入送礼物记录
final GiftSendRecord giftSendRecord = new GiftSendRecord();
giftSendRecord.setSendRecordId(giftMessage.getId());
giftSendRecord.setGiftId(giftMessage.getGiftId());
giftSendRecord.setReciveUid(giftMessage.getRecvUid());
giftSendRecord.setRoomUid(giftMessage.getRoomUid());
giftSendRecord.setRoomType(giftMessage.getRoomType());
giftSendRecord.setGiftNum(giftMessage.getGiftNum());
giftSendRecord.setSendEnv(giftMessage.getSendType());
giftSendRecord.setUid(giftMessage.getSendUid());
giftSendRecord.setPartitionId(giftMessage.getPartitionId());
giftSendRecord.setTotalGoldNum(giftMessage.getGoldNum());
giftSendRecord.setTotalDiamondNum(diamondFlow);
giftSendRecord.setGiftType(giftMessage.getGiftType());
giftSendRecord.setCreateTime(new Date(giftMessage.getMessTime()));
giftSendRecord.setGiftSource(giftMessage.getGiftSource().byteValue());
giftSendRecord.setMessId(giftMessage.getMessId());
return giftSendRecord;
}
/**
* 插入礼物赠送记录
*
@@ -208,6 +324,7 @@ public class GiftMessageService extends BaseService {
private GiftSendRecord insertGiftSendRecord(GiftMessage giftMessage, Double diamondFlow) {
// 插入送礼物记录
final GiftSendRecord giftSendRecord = new GiftSendRecord();
giftSendRecord.setSendRecordId(null != giftMessage.getId()? giftMessage.getId(): identifierGenerator.nextId(null).longValue());
giftSendRecord.setGiftId(giftMessage.getGiftId());
giftSendRecord.setReciveUid(giftMessage.getRecvUid());
giftSendRecord.setRoomUid(giftMessage.getRoomUid());
@@ -226,7 +343,7 @@ public class GiftMessageService extends BaseService {
giftSendRecordService.insertGiftSendRecord(giftSendRecord);
logger.info("[处理礼物mq] insert giftSendRecored finish, sendUid:{}, partitionId:{}, recvUid:{}, goldNum:{}, messId:{}" +
", giftRecordId:{}", giftMessage.getSendUid(), giftMessage.getPartitionId(), giftMessage.getRecvUid(),
", giftRecordId:{}", giftMessage.getSendUid(), giftMessage.getPartitionId(), giftMessage.getRecvUid(),
giftMessage.getGoldNum(), giftMessage.getMessId(), giftSendRecord.getSendRecordId());
return giftSendRecord;

View File

@@ -1,6 +1,5 @@
package com.accompany.business.service.gift;
import com.accompany.business.model.userevent.UserEventData;
import com.accompany.common.constant.Constant;
import com.accompany.common.result.BusiResult;
import com.accompany.common.status.BusiStatus;
@@ -36,6 +35,10 @@ public class GiftSendRecordService extends ServiceImpl<GiftSendRecordMapper, Gif
@Autowired
private GiftSendRecordMapperExpand giftSendRecordMapperExpand;
public int insertRecordIgnore(GiftSendRecord record) {
return baseMapper.insertIgnore(record);
}
public void insertGiftSendRecord(GiftSendRecord giftSendRecord) {
for (int i = 0; i < 3; i++) {
try {

View File

@@ -51,6 +51,7 @@ import com.accompany.core.vo.vip.VipBaseInfoVO;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
@@ -107,6 +108,8 @@ public class GiftSendService extends BaseService {
private BravoGiftSendService bravoGiftSendService;
@Autowired
private Lucky25GiftSendService lucky25GiftSendService;
@Autowired
private IdentifierGenerator identifierGenerator;
/**
@@ -206,6 +209,7 @@ public class GiftSendService extends BaseService {
Integer giftSource, Boolean luckyBagGift, String giftSendUuid, Integer luckyBagId,
Date sendGiftTime, Integer partitionId, UserPurse afterPurse) {
GiftMessage message = new GiftMessage();
message.setId(identifierGenerator.nextId( null).longValue());
message.setSendUid(sendUid);
message.setRecvUid(recvUid);
message.setRoomUid(roomUid);

View File

@@ -43,7 +43,7 @@ public class RocketMQService {
List<Message<String>> messageList = giftMessages.stream()
.map(giftMessage -> MessageBuilder.withPayload(JSON.toJSONString(giftMessage)).build())
.collect(Collectors.toList());
mqMessageProducer.send(MqConstant.GIFT_TOPIC, messageList,
mqMessageProducer.send(MqConstant.GIFT_TOPIC_V2, messageList,
sendResult -> log.info("sendGiftMessage success result: {} message: {}", JSON.toJSONString(sendResult), messageList),
throwable -> log.error("sendGiftMessage fail message: {}", messageList, throwable));
}