新增 cp用户送礼物记录

(cherry picked from commit 569a2045cba1648c91b058a33f114afcc698bf9a)
This commit is contained in:
tianfeng 2026-04-28 11:26:40 +08:00
parent 4dd52b44d2
commit c4c4b10789
11 changed files with 398 additions and 86 deletions

View File

@ -4,6 +4,9 @@ import com.red.circle.common.business.dto.cmd.AppExtCommand;
import com.red.circle.common.business.dto.cmd.UserIdCmd;
import com.red.circle.framework.web.controller.BaseController;
import com.red.circle.other.app.command.user.LoveLetterQueryCmdExe;
import com.red.circle.other.app.command.user.query.CpGiftRecordQryExe;
import com.red.circle.other.app.dto.clientobject.user.user.CpGiftRecordCO;
import com.red.circle.other.app.dto.cmd.user.user.CpGiftRecordQueryCmd;
import com.red.circle.other.app.dto.clientobject.user.relation.cp.CoupleSpaceCO;
import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpPairUserProfileCO;
import com.red.circle.other.app.dto.cmd.user.relation.cp.CoupleSpaceQryCmd;
@ -43,6 +46,7 @@ public class CpRelationshipRestController extends BaseController {
private final UserCpRelationService userCpRelationService;
private final LoveLetterQueryCmdExe loveLetterQueryCmdExe;
private final CpGiftRecordQryExe cpGiftRecordQryExe;
/**
* 获取我的-cp对象.
@ -148,6 +152,20 @@ public class CpRelationshipRestController extends BaseController {
return loveLetterQueryCmdExe.queryLatestReceived(cmd);
}
/**
* CP道具赠送记录.
*
* @eo.name CP道具赠送记录
* @eo.url /gift-record
* @eo.method get
* @eo.request-type formdata
*/
@GetMapping("/gift-record")
public List<CpGiftRecordCO> getCpGiftRecord(@Validated CpGiftRecordQueryCmd cmd) {
return cpGiftRecordQryExe.execute(cmd);
}
/**
* CP空间.
*

View File

@ -0,0 +1,86 @@
package com.red.circle.other.app.command.user.query;
import com.google.common.collect.Lists;
import com.red.circle.other.app.dto.clientobject.user.user.CpGiftRecordCO;
import com.red.circle.other.app.dto.cmd.user.user.CpGiftRecordQueryCmd;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.model.user.UserProfile;
import com.red.circle.other.infra.database.rds.entity.gift.GiftConfig;
import com.red.circle.other.infra.database.rds.entity.user.user.CpGiftRecord;
import com.red.circle.other.infra.database.rds.service.gift.GiftConfigService;
import com.red.circle.other.infra.database.rds.service.user.user.CpGiftRecordService;
import com.red.circle.tool.core.collection.CollectionUtils;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* CP道具赠送记录查询.
*
* @author pengliang
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class CpGiftRecordQryExe {
private static final String TYPE_SEND = "send";
private final CpGiftRecordService cpGiftRecordService;
private final UserProfileGateway userProfileGateway;
private final GiftConfigService giftConfigService;
public List<CpGiftRecordCO> execute(CpGiftRecordQueryCmd cmd) {
Long reqUserId = cmd.requiredReqUserId();
boolean isSend = TYPE_SEND.equals(cmd.getType());
List<CpGiftRecord> records = isSend
? cpGiftRecordService.pageSendList(reqUserId, cmd.getLastId())
: cpGiftRecordService.pageReceiveList(reqUserId, cmd.getLastId());
if (CollectionUtils.isEmpty(records)) {
return Lists.newArrayList();
}
// 批量查对方用户信息
Set<Long> counterpartIds = records.stream()
.map(r -> isSend ? r.getReceiverUserId() : r.getSenderUserId())
.collect(Collectors.toSet());
Map<Long, UserProfile> profileMap = userProfileGateway.mapByUserIds(counterpartIds);
// 批量查礼物配置获取 giftIcon / giftName
Set<Long> giftIds = records.stream().map(CpGiftRecord::getGiftId).collect(Collectors.toSet());
Map<Long, GiftConfig> giftConfigMap = giftConfigService.mapByIds(giftIds);
return records.stream().map(r -> {
Long counterpartId = isSend ? r.getReceiverUserId() : r.getSenderUserId();
UserProfile profile = profileMap.get(counterpartId);
GiftConfig giftConfig = giftConfigMap.get(r.getGiftId());
CpGiftRecordCO co = new CpGiftRecordCO();
co.setId(r.getId());
co.setGiftId(r.getGiftId());
co.setGiftCount(r.getGiftCount());
co.setTotalValue(r.getTotalValue());
co.setCreateTime(r.getCreateTime() != null ? r.getCreateTime().getTime() : null);
if (Objects.nonNull(giftConfig)) {
co.setGiftIcon(giftConfig.getGiftPhoto());
co.setGiftName(giftConfig.getGiftName());
}
if (Objects.nonNull(profile)) {
co.setUserName(profile.getUserNickname());
co.setAccount(profile.getDisplayAccount());
co.setUserAvatar(profile.getUserAvatar());
}
return co;
}).collect(Collectors.toList());
}
}

View File

@ -114,82 +114,4 @@ public class GiftPrizeAcceptStrategy implements GiftStrategy {
// giftGiveRunningWaterService.addLog(runningWater.getId(),"结束:接收奖品策略(礼物墙、积分/钻石发放)");
}
/**
* yolo钻石工资统计
*
* @param runningWater
* @param acceptUsers
*/
private void yoloSalaryDiamondCount(GiftGiveRunningWater runningWater, GiftAcceptUser acceptUsers) {
log.warn("yolo钻石入账1:{}\n{}", runningWater, acceptUsers);
if (!Objects.equals(runningWater.getSysOrigin(), SysOriginPlatformEnum.YOLO.name())) {
// 如果不是YOLO就停止入账
return;
}
if (acceptUsers.getAcceptAmount().compareTo(BigDecimal.ZERO) <= 0) {
log.warn("小于0不入账:{}", acceptUsers.getAcceptAmount());
return;
}
/*if (Objects.equals(salaryDiamondRunningWaterClient.existsTrackId(acceptUsers.getAcceptUserId(), UserBankWaterEvent.ACCEPT_GIFTS.name(), runningWater.getId().toString()).getBody(),
Boolean.TRUE)) {
log.warn("重复处理:{}", runningWater.getId());
return;
}*/
// RegionConfig sendRegion = getUserRegion(acceptAnchorUser.getAcceptUserId());
// BigDecimal ratio = getAssistGiftToOtherGoldRatio(sendRegion.getId());
//
// log.warn("yolo钻石入账2:{}\n{}", sendRegion, ratio);
/*BigDecimal quantity = runningWater.getGiftValue().getUnitPrice()
.multiply(new BigDecimal(runningWater.getGiftValue().getQuantity()))
.multiply(acceptUsers.getPercentage()).setScale(0, RoundingMode.DOWN);*/
salaryDiamondBalanceClient.changeSalaryBalanceAsync(new UserSalaryDiamondCmd()
.setUserId(acceptUsers.getAcceptUserId())
.setQuantity(acceptUsers.getAcceptAmount())
.setSysOrigin(runningWater.getSysOrigin()));
TeamMember sendMember = teamMemberService.getByMemberId(acceptUsers.getAcceptUserId());
Long teamId = 0L;
if (Objects.nonNull(sendMember)) {
teamId = sendMember.getTeamId();
}
salaryDiamondRunningWaterClient.addAsync(new UserSalaryDiamondRunningWaterDTO()
.setId(IdWorkerUtils.getId())
.setUserId(acceptUsers.getAcceptUserId())
.setTeamId(teamId)
.setSysOrigin(runningWater.getSysOrigin())
.setType(ReceiptType.INCOME.getType())
.setTrackId(runningWater.getId()+"")
.setAmount(acceptUsers.getAcceptAmount())
.setSalaryEvent(UserBankWaterEvent.ACCEPT_GIFTS.name())
.setEventDesc(UserBankWaterEvent.ACCEPT_GIFTS.getDescribe())
.setRemark(UserBankWaterEvent.ACCEPT_GIFTS.getDescribe())
.setBalance(
ResponseAssert.requiredSuccess(
salaryDiamondBalanceClient.getBalance(acceptUsers.getAcceptUserId())).getBalance())
.setCreateTime(TimestampUtils.now())
.setCreateUser(0L)
.setCreateUserOrigin(0)
);
}
private RegionConfig getUserRegion(Long userId) {
return userRegionGateway.getRegionConfigByUserId(userId);
}
/**
* 赠送礼物给别人返还金币比例.
*/
private BigDecimal getAssistGiftToOtherGoldRatio(String regionId) {
return userRegionGateway.getAssistGiftToOtherGoldRatio(regionId);
}
/**
* 赠送礼物给别人返还金币比例.
*/
private BigDecimal getAssistGiftToOwnGoldRatio(String regionId) {
return userRegionGateway.getAssistGiftToOwnGoldRatio(regionId);
}
}

View File

@ -34,6 +34,8 @@ import com.red.circle.other.infra.database.cache.service.other.ActivityConfigCac
import com.red.circle.other.infra.database.mongo.service.sys.SysActivityCountService;
import com.red.circle.other.infra.database.mongo.service.user.count.WeekCpValueCountService;
import com.red.circle.other.infra.database.rds.entity.user.user.CpRelationship;
import com.red.circle.other.infra.database.rds.entity.user.user.CpGiftRecord;
import com.red.circle.other.infra.database.rds.service.user.user.CpGiftRecordService;
import com.red.circle.other.infra.database.rds.service.user.user.CpRelationshipService;
import com.red.circle.other.infra.database.rds.service.user.user.CpValueService;
import com.red.circle.other.inner.enums.activity.KingQueenType;
@ -75,6 +77,7 @@ public class RankCountStrategy implements GiftStrategy {
private final AppRankCountService appRankCountService;
private final GameLuckyGiftCommon gameLuckyGiftCommon;
private final CpRelationshipService cpRelationshipService;
private final CpGiftRecordService cpGiftRecordService;
private final UserCpValueCacheService userCpValueCacheService;
private final WeekCpValueCountService weekCpValueCountService;
private final SysActivityCountService sysActivityCountService;
@ -307,6 +310,9 @@ public class RankCountStrategy implements GiftStrategy {
.forEach(cp -> {
cpValueService.incrValue(cp.getCpValId(), acceptAmount);
// 写入CP道具赠送记录
saveCpGiftRecord(runningWater, cp, acceptAmount);
// 排序CP用户ID
ImmutablePair<Long, Long> sortedPair = sortCpUserIds(cp.getUserId(), cp.getCpUserId());
Long orderedUserOne = sortedPair.getLeft();
@ -329,16 +335,32 @@ public class RankCountStrategy implements GiftStrategy {
orderedUserTwo,
acceptAmount.longValue());
});
// 更新cp用户赠送的礼物价值
// cpRelationshipService.updateAccountByUserId(cpRelationship.getUserId(),
// cpRelationship.getAmount().add(acceptAmount));
// 根据两个cp用户谁赠送的多确定区域
// String userRegionCode =
// cpRelationship.getAmount().add(acceptAmount).compareTo(relationship.getAmount()) >= 0
// ? userRegionGateway.getRegionCode(cpRelationship.getUserId()) :
// userRegionGateway.getRegionCode(relationship.getUserId());
}
/**
* 保存CP道具赠送记录.
*/
private void saveCpGiftRecord(GiftGiveRunningWater runningWater, CpRelationship cp,
BigDecimal acceptAmount) {
try {
GiftValue giftValue = runningWater.getGiftValue();
CpGiftRecord record = CpGiftRecord.builder()
.sysOrigin(runningWater.getSysOrigin())
.senderUserId(runningWater.getUserId())
.receiverUserId(cp.getCpUserId())
.cpValId(cp.getCpValId())
.giftId(runningWater.getGiftId())
.giftCount(giftValue.getQuantity() != null ? giftValue.getQuantity() : 1)
.giftValue(giftValue.getGiftValue().longValue())
.totalValue(acceptAmount.longValue())
.runningWaterId(runningWater.getId())
.build();
cpGiftRecordService.save(record);
} catch (Exception e) {
log.error("【CP送礼记录】写入失败, runningWaterId={}, cpUserId={}",
runningWater.getId(), cp.getCpUserId(), e);
}
}
/**

View File

@ -0,0 +1,58 @@
package com.red.circle.other.app.dto.clientobject.user.user;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* CP道具赠送记录 CO.
*
* @author pengliang
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class CpGiftRecordCO implements Serializable {
private static final long serialVersionUID = 1L;
/** 记录ID. */
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/** 对方用户昵称. */
private String userName;
/** 对方用户账号. */
private String account;
/** 对方用户头像. */
private String userAvatar;
/** 礼物ID. */
@JsonSerialize(using = ToStringSerializer.class)
private Long giftId;
/** 礼物图标. */
private String giftIcon;
/** 礼物名称. */
private String giftName;
/** 赠送数量. */
private Integer giftCount;
/** 总价值(金币). */
private Long totalValue;
/** 赠送时间时间戳ms. */
private Long createTime;
}

View File

@ -0,0 +1,26 @@
package com.red.circle.other.app.dto.cmd.user.user;
import com.red.circle.framework.core.dto.AppCommand;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* CP道具赠送记录查询 Cmd.
*
* @author pengliang
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class CpGiftRecordQueryCmd extends AppCommand {
/**
* 查询方向send-送出receive-收到.
*/
private String type;
/**
* 最后一条记录ID首页不传.
*/
private Long lastId;
}

View File

@ -242,6 +242,13 @@ public class UserProfile implements Serializable {
return checkOwnSpecialIdAvailable() ? this.ownSpecialId.getAccount() : this.account;
}
/**
* 获取展示账号优先靓号无靓号则返回普通账号.
*/
public String getDisplayAccount() {
return checkOwnSpecialIdAvailable() ? this.ownSpecialId.getAccount() : this.account;
}
/**
* 过滤道具.
*/

View File

@ -0,0 +1,13 @@
package com.red.circle.other.infra.database.rds.dao.user.user;
import com.red.circle.framework.mybatis.dao.BaseDAO;
import com.red.circle.other.infra.database.rds.entity.user.user.CpGiftRecord;
/**
* CP道具赠送记录 DAO.
*
* @author pengliang
*/
public interface CpGiftRecordDAO extends BaseDAO<CpGiftRecord> {
}

View File

@ -0,0 +1,85 @@
package com.red.circle.other.infra.database.rds.entity.user.user;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.red.circle.framework.mybatis.entity.TimestampBaseEntity;
import java.io.Serial;
import java.io.Serializable;
import java.sql.Timestamp;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* CP道具赠送记录.
*
* @author pengliang
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Builder
@AllArgsConstructor
@NoArgsConstructor
@TableName("cp_gift_record")
public class CpGiftRecord implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 主键id雪花. */
@TableId(value = "id", type = IdType.ASSIGN_ID)
private Long id;
/** 系统平台. */
@TableField("sys_origin")
private String sysOrigin;
/** 送礼用户ID. */
@TableField("sender_user_id")
private Long senderUserId;
/** 收礼用户IDCP对象. */
@TableField("receiver_user_id")
private Long receiverUserId;
/** CP关系值ID. */
@TableField("cp_val_id")
private Long cpValId;
/** 礼物ID. */
@TableField("gift_id")
private Long giftId;
/** 礼物图标URL冗余. */
@TableField("gift_icon")
private String giftIcon;
/** 礼物名称(冗余). */
@TableField("gift_name")
private String giftName;
/** 赠送数量. */
@TableField("gift_count")
private Integer giftCount;
/** 礼物单价(金币). */
@TableField("gift_value")
private Long giftValue;
/** 总价值gift_value * gift_count. */
@TableField("total_value")
private Long totalValue;
/** 礼物流水ID. */
@TableField("running_water_id")
private Long runningWaterId;
@TableField("create_time")
private Timestamp createTime;
}

View File

@ -0,0 +1,32 @@
package com.red.circle.other.infra.database.rds.service.user.user;
import com.red.circle.framework.mybatis.service.BaseService;
import com.red.circle.other.infra.database.rds.entity.user.user.CpGiftRecord;
import java.util.List;
/**
* CP道具赠送记录 服务类.
*
* @author pengliang
*/
public interface CpGiftRecordService extends BaseService<CpGiftRecord> {
/**
* 分页查询送出记录我送给CP的.
*
* @param senderUserId 送礼人ID
* @param lastId 上一页最后一条ID首页传null
* @return 记录列表
*/
List<CpGiftRecord> pageSendList(Long senderUserId, Long lastId);
/**
* 分页查询收到记录CP送给我的.
*
* @param receiverUserId 收礼人ID
* @param lastId 上一页最后一条ID首页传null
* @return 记录列表
*/
List<CpGiftRecord> pageReceiveList(Long receiverUserId, Long lastId);
}

View File

@ -0,0 +1,43 @@
package com.red.circle.other.infra.database.rds.service.user.user.impl;
import com.red.circle.framework.mybatis.constant.PageConstant;
import com.red.circle.framework.mybatis.service.impl.BaseServiceImpl;
import com.red.circle.other.infra.database.rds.dao.user.user.CpGiftRecordDAO;
import com.red.circle.other.infra.database.rds.entity.user.user.CpGiftRecord;
import com.red.circle.other.infra.database.rds.service.user.user.CpGiftRecordService;
import java.util.List;
import java.util.Objects;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
/**
* CP道具赠送记录 服务实现类.
*
* @author pengliang
*/
@AllArgsConstructor
@Service
public class CpGiftRecordServiceImpl extends
BaseServiceImpl<CpGiftRecordDAO, CpGiftRecord> implements CpGiftRecordService {
@Override
public List<CpGiftRecord> pageSendList(Long senderUserId, Long lastId) {
return query()
.eq(CpGiftRecord::getSenderUserId, senderUserId)
.lt(Objects.nonNull(lastId), CpGiftRecord::getId, lastId)
.orderByDesc(CpGiftRecord::getId)
.last(PageConstant.formatLimit(20))
.list();
}
@Override
public List<CpGiftRecord> pageReceiveList(Long receiverUserId, Long lastId) {
return query()
.eq(CpGiftRecord::getReceiverUserId, receiverUserId)
.lt(Objects.nonNull(lastId), CpGiftRecord::getId, lastId)
.orderByDesc(CpGiftRecord::getId)
.last(PageConstant.formatLimit(20))
.list();
}
}