新增查询最新的vip金币赠送记录接口

This commit is contained in:
tianfeng 2026-02-13 14:33:43 +08:00
parent 4276f9c419
commit 62baa3a458
11 changed files with 341 additions and 2 deletions

View File

@ -120,5 +120,18 @@ public interface WalletGoldClientApi {
@RequestParam("monthNumber") Integer monthNumber
);
/**
* 查询用户最新的VIP赠送记录仅返回金币记录信息.
*
* @param userId 用户ID
* @param limit 查询数量限制
* @return VIP赠送金币记录列表
*/
@GetMapping("/latestVipGiveawayRecords")
ResultResponse<List<WalletGoldAssetRecordDTO>> getLatestVipGiveawayRecords(
@RequestParam("userId") Long userId,
@RequestParam(value = "limit", defaultValue = "1") Integer limit
);
}

View File

@ -106,4 +106,9 @@ public class WalletGoldClientCallback implements WalletGoldClient {
log.warn("[listWalletGoldCountExport] sysOrigin={},monthNumber={}", sysOrigin, monthNumber);
return ResultResponse.success(CollectionUtils.newArrayList());
}
@Override
public ResultResponse<List<WalletGoldAssetRecordDTO>> getLatestVipGiveawayRecords(Long userId, Integer limit) {
return ResultResponse.success(CollectionUtils.newArrayList());
}
}

View File

@ -0,0 +1,108 @@
package com.red.circle.wallet.inner.model.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.red.circle.framework.dto.DTO;
import java.math.BigDecimal;
import java.sql.Timestamp;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* VIP赠送金币记录DTO.
*
* @author pengliang
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class VipGiveawayGoldRecordDTO extends DTO {
private static final long serialVersionUID = 1L;
/**
* 流水记录ID.
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 系统来源.
*/
private String sysOrigin;
/**
* 用户id.
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long userId;
/**
* 金额().
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long pennyAmount;
/**
* 金额().
*/
private BigDecimal amount;
/**
* 当前余额().
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long pennyBalance;
/**
* 类型0.收入 1.消耗.
*/
private Integer type;
/**
* 事件类型.
*/
private String eventType;
/**
* 事件描述.
*/
private String eventDesc;
/**
* 事件id(订单关联信息).
*/
private String eventId;
/**
* 操作用户类型(0.app用户 1.后台管理用户).
*/
private Integer opUserType;
/**
* 创建时间.
*/
private Timestamp createTime;
/**
* 修改时间.
*/
private Timestamp updateTime;
/**
* VIP类型.
*/
private String vipType;
/**
* VIP等级.
*/
private Integer vipLevel;
/**
* 登录奖励金额.
*/
private BigDecimal loginRewardsAmount;
}

View File

@ -12,6 +12,9 @@ import com.red.circle.other.inner.model.dto.activity.props.ActivityRewardPropsDT
import java.util.List;
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
import com.red.circle.wallet.inner.endpoint.wallet.WalletGoldClient;
import com.red.circle.wallet.inner.endpoint.wallet.api.WalletGoldClientApi;
import com.red.circle.wallet.inner.model.dto.VipGiveawayGoldRecordDTO;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
@ -98,5 +101,14 @@ public class CheckInRestController extends BaseController {
return checkInService.receive(cmd);
}
/**
* 最新的vip金币赠送记录
* @param cmd
* @return
*/
@GetMapping("/latest-vip-record")
public List<VipGiveawayGoldRecordDTO> getLatestVipGiveawayRecord(AppExtCommand cmd) {
return checkInService.getLatestVipGiveawayRecords(cmd);
}
}

View File

@ -1,7 +1,10 @@
package com.red.circle.other.app.service.task;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.red.circle.common.business.dto.cmd.AppExtCommand;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.dto.ResultResponse;
import com.red.circle.other.app.command.task.CheckInExe;
import com.red.circle.other.app.command.task.query.CheckInLotteryQryExe;
import com.red.circle.other.app.command.task.query.CheckInRewardQryExe;
@ -10,17 +13,35 @@ import com.red.circle.other.app.dto.clientobject.activity.ActivityResourceCO;
import com.red.circle.other.app.dto.clientobject.task.CheckInRewardListCO;
import com.red.circle.other.app.dto.cmd.task.CheckInRewardCmd;
import com.red.circle.other.infra.database.cache.service.other.CheckInCacheService;
import com.red.circle.other.infra.database.rds.entity.props.PropsCommodityStore;
import com.red.circle.other.infra.database.rds.service.props.PropsCommodityStoreService;
import com.red.circle.other.inner.enums.activity.PropsActivityTypeEnum;
import com.red.circle.other.inner.model.dto.activity.props.ActivityRewardPropsDTO;
import java.util.List;
import com.red.circle.other.inner.endpoint.material.props.PropsNobleVipClient;
import com.red.circle.other.inner.model.dto.material.props.NobleVipAbility;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.parse.DataTypeUtils;
import com.red.circle.tool.core.tuple.PennyAmount;
import com.red.circle.wallet.inner.endpoint.wallet.WalletGoldClient;
import com.red.circle.wallet.inner.model.dto.VipGiveawayGoldRecordDTO;
import com.red.circle.wallet.inner.model.dto.WalletGoldAssetRecordDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 打卡服务实现.
*
* @author pengliang on 2020/11/27
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class CheckInServiceImpl implements CheckInService {
@ -30,6 +51,9 @@ public class CheckInServiceImpl implements CheckInService {
private final CheckInCacheService checkInCacheService;
private final CheckInLotteryQryExe checkInLotteryQryExe;
private final SingleGroupRewardPoolCommon singleGroupRewardPoolCommon;
private final WalletGoldClient walletGoldClient;
private final PropsNobleVipClient propsNobleVipClient;
private final PropsCommodityStoreService propsCommodityStoreService;
@Override
@ -72,5 +96,129 @@ public class CheckInServiceImpl implements CheckInService {
return checkInExe.execute(cmd);
}
@Override
public List<VipGiveawayGoldRecordDTO> getLatestVipGiveawayRecords(AppExtCommand cmd) {
Long userId = cmd.getReqUserId();
Integer limit = 1; // 默认查询1条
// 1. 调用wallet客户端查询VIP赠送记录仅包含基础record信息
ResultResponse<List<WalletGoldAssetRecordDTO>> response =
walletGoldClient.getLatestVipGiveawayRecords(userId, limit);
List<WalletGoldAssetRecordDTO> records = ResponseAssert.requiredSuccess(response);
if (CollectionUtils.isEmpty(records)) {
return CollectionUtils.newArrayList();
}
// 2. 收集所有eventId (商品ID)
Set<Long> commodityIds = records.stream()
.map(WalletGoldAssetRecordDTO::getEventId)
.filter(StringUtils::isNotBlank)
.map(DataTypeUtils::toLong)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
if (CollectionUtils.isEmpty(commodityIds)) {
return convertToVipGiveawayRecords(records, CollectionUtils.newHashMap());
}
// 3. 查询PropsCommodityStore获取sourceId
LambdaQueryWrapper<PropsCommodityStore> queryWrapper =
Wrappers.<PropsCommodityStore>lambdaQuery()
.in(PropsCommodityStore::getId, commodityIds);
List<PropsCommodityStore> commodityStores = propsCommodityStoreService.list(queryWrapper);
// 构建 commodityId -> sourceId 映射
Map<Long, Long> commodityToSourceIdMap = commodityStores.stream()
.collect(Collectors.toMap(
PropsCommodityStore::getId,
PropsCommodityStore::getSourceId,
(v1, v2) -> v1
));
// 4. 收集所有VIP sourceId
Set<Long> vipSourceIds = commodityToSourceIdMap.values().stream()
.filter(Objects::nonNull)
.collect(Collectors.toSet());
// 5. 批量查询VIP信息
Map<Long, NobleVipAbility> vipAbilityMap = CollectionUtils.newHashMap();
if (CollectionUtils.isNotEmpty(vipSourceIds)) {
try {
ResultResponse<Map<Long, NobleVipAbility>> vipResponse =
propsNobleVipClient.mapAbilityByIds(vipSourceIds);
if (Objects.nonNull(vipResponse) && vipResponse.checkSuccess() &&
Objects.nonNull(vipResponse.getBody())) {
vipAbilityMap = vipResponse.getBody();
}
} catch (Exception e) {
log.error("查询VIP信息失败, userId={}", userId, e);
}
}
// 6. 组装返回数据record信息 + VIP信息
Map<Long, Long> finalCommodityToSourceIdMap = commodityToSourceIdMap;
Map<Long, NobleVipAbility> finalVipAbilityMap = vipAbilityMap;
return records.stream()
.map(record -> {
VipGiveawayGoldRecordDTO dto = new VipGiveawayGoldRecordDTO()
.setId(record.getId())
.setSysOrigin(record.getSysOrigin())
.setUserId(record.getUserId())
.setPennyAmount(record.getPennyAmount())
.setAmount(PennyAmount.ofPenny(record.getPennyAmount()).getDollarAmount())
.setPennyBalance(record.getPennyBalance())
.setType(record.getType())
.setEventType(record.getEventType())
.setEventDesc(record.getEventDesc())
.setEventId(record.getEventId())
.setOpUserType(record.getOpUserType())
.setCreateTime(record.getCreateTime())
.setUpdateTime(record.getUpdateTime());
// 设置VIP信息
if (StringUtils.isNotBlank(record.getEventId())) {
Long commodityId = DataTypeUtils.toLong(record.getEventId());
if (Objects.nonNull(commodityId)) {
Long sourceId = finalCommodityToSourceIdMap.get(commodityId);
if (Objects.nonNull(sourceId)) {
NobleVipAbility vipAbility = finalVipAbilityMap.get(sourceId);
if (Objects.nonNull(vipAbility)) {
dto.setVipType(vipAbility.vipType())
.setVipLevel(vipAbility.vipLevel())
.setLoginRewardsAmount(vipAbility.loginRewardsAmount());
}
}
}
}
return dto;
})
.collect(Collectors.toList());
}
private List<VipGiveawayGoldRecordDTO> convertToVipGiveawayRecords(
List<WalletGoldAssetRecordDTO> records,
Map<Long, NobleVipAbility> vipAbilityMap) {
return records.stream()
.map(record -> new VipGiveawayGoldRecordDTO()
.setId(record.getId())
.setSysOrigin(record.getSysOrigin())
.setUserId(record.getUserId())
.setPennyAmount(record.getPennyAmount())
.setAmount(PennyAmount.ofPenny(record.getPennyAmount()).getDollarAmount())
.setPennyBalance(record.getPennyBalance())
.setType(record.getType())
.setEventType(record.getEventType())
.setEventDesc(record.getEventDesc())
.setEventId(record.getEventId())
.setOpUserType(record.getOpUserType())
.setCreateTime(record.getCreateTime())
.setUpdateTime(record.getUpdateTime())
)
.collect(Collectors.toList());
}
}

View File

@ -5,6 +5,8 @@ import com.red.circle.other.app.dto.clientobject.task.CheckInRewardListCO;
import com.red.circle.other.app.dto.cmd.task.CheckInRewardCmd;
import com.red.circle.other.inner.enums.activity.PropsActivityTypeEnum;
import com.red.circle.other.inner.model.dto.activity.props.ActivityRewardPropsDTO;
import com.red.circle.wallet.inner.model.dto.VipGiveawayGoldRecordDTO;
import java.util.List;
/**
@ -24,4 +26,5 @@ public interface CheckInService {
Integer receive(CheckInRewardCmd cmd);
List<VipGiveawayGoldRecordDTO> getLatestVipGiveawayRecords(AppExtCommand cmd);
}

View File

@ -48,4 +48,13 @@ public interface WalletGoldAssetRecordService extends BaseService<WalletGoldAsse
*/
boolean existsData(Integer shardingMonth);
/**
* 查询用户最新的VIP赠送记录.
*
* @param userId 用户ID
* @param limit 查询数量限制
* @return VIP赠送记录列表
*/
List<WalletGoldAssetRecord> listLatestVipGiveawayRecords(Long userId, Integer limit);
}

View File

@ -88,6 +88,16 @@ public class WalletGoldAssetRecordServiceImpl extends
return Objects.equals(baseDAO.existsData(shardingMonth), Boolean.TRUE);
}
@Override
public List<WalletGoldAssetRecord> listLatestVipGiveawayRecords(Long userId, Integer limit) {
return query()
.eq(WalletGoldAssetRecord::getUserId, userId)
.eq(WalletGoldAssetRecord::getEventType, "PURCHASE_NOBLE_VIP_GIVEAWAY")
.orderByDesc(WalletGoldAssetRecord::getCreateTime)
.last(PageConstant.formatLimitStrict(limit))
.list();
}
private Date lastDayOfLastMonthStart(int lastDay) {
return DateUtils.setDateTime(DateUtils.minusDays(DateUtils.lastDayOfLastMonth(), lastDay), 0, 0,
0);

View File

@ -112,4 +112,11 @@ public class WalletGoldClientEndpoint implements WalletGoldClientApi {
walletGoldClientService.listWalletGoldCountExport(sysOrigin, monthNumber));
}
@Override
public ResultResponse<List<WalletGoldAssetRecordDTO>> getLatestVipGiveawayRecords(Long userId,
Integer limit) {
return ResultResponse.success(
walletGoldClientService.getLatestVipGiveawayRecords(userId, limit));
}
}

View File

@ -81,5 +81,14 @@ public interface WalletGoldClientService {
*/
List<WalletGoldCountDTO> listWalletGoldCountExport(String sysOrigin, Integer monthNumber);
/**
* 查询用户最新的VIP赠送记录仅返回金币记录信息.
*
* @param userId 用户ID
* @param limit 查询数量限制
* @return VIP赠送金币记录列表
*/
List<WalletGoldAssetRecordDTO> getLatestVipGiveawayRecords(Long userId, Integer limit);
}

View File

@ -454,4 +454,19 @@ public class WalletGoldClientServiceImpl implements WalletGoldClientService {
DataTypeUtils.toInteger(end)));
}
@Override
public List<WalletGoldAssetRecordDTO> getLatestVipGiveawayRecords(Long userId, Integer limit) {
// 查询用户的VIP赠送记录
List<WalletGoldAssetRecord> records = walletGoldAssetRecordService.listLatestVipGiveawayRecords(
userId, limit);
if (CollectionUtils.isEmpty(records)) {
return CollectionUtils.newArrayList();
}
return records.stream()
.map(walletInnerConvertor::toWalletGoldAssetRecordDTO)
.collect(Collectors.toList());
}
}