diff --git a/rc-service/rc-inner-api/wallet-inner/wallet-inner-api/src/main/java/com/red/circle/wallet/inner/endpoint/wallet/api/WalletGoldClientApi.java b/rc-service/rc-inner-api/wallet-inner/wallet-inner-api/src/main/java/com/red/circle/wallet/inner/endpoint/wallet/api/WalletGoldClientApi.java index 396fe4cf..6b365b71 100644 --- a/rc-service/rc-inner-api/wallet-inner/wallet-inner-api/src/main/java/com/red/circle/wallet/inner/endpoint/wallet/api/WalletGoldClientApi.java +++ b/rc-service/rc-inner-api/wallet-inner/wallet-inner-api/src/main/java/com/red/circle/wallet/inner/endpoint/wallet/api/WalletGoldClientApi.java @@ -120,5 +120,18 @@ public interface WalletGoldClientApi { @RequestParam("monthNumber") Integer monthNumber ); + /** + * 查询用户最新的VIP赠送记录(仅返回金币记录信息). + * + * @param userId 用户ID + * @param limit 查询数量限制 + * @return VIP赠送金币记录列表 + */ + @GetMapping("/latestVipGiveawayRecords") + ResultResponse> getLatestVipGiveawayRecords( + @RequestParam("userId") Long userId, + @RequestParam(value = "limit", defaultValue = "1") Integer limit + ); + } diff --git a/rc-service/rc-inner-api/wallet-inner/wallet-inner-api/src/main/java/com/red/circle/wallet/inner/endpoint/wallet/callback/WalletGoldClientCallback.java b/rc-service/rc-inner-api/wallet-inner/wallet-inner-api/src/main/java/com/red/circle/wallet/inner/endpoint/wallet/callback/WalletGoldClientCallback.java index c2e3c96a..9751b145 100644 --- a/rc-service/rc-inner-api/wallet-inner/wallet-inner-api/src/main/java/com/red/circle/wallet/inner/endpoint/wallet/callback/WalletGoldClientCallback.java +++ b/rc-service/rc-inner-api/wallet-inner/wallet-inner-api/src/main/java/com/red/circle/wallet/inner/endpoint/wallet/callback/WalletGoldClientCallback.java @@ -106,4 +106,9 @@ public class WalletGoldClientCallback implements WalletGoldClient { log.warn("[listWalletGoldCountExport] sysOrigin={},monthNumber={}", sysOrigin, monthNumber); return ResultResponse.success(CollectionUtils.newArrayList()); } + + @Override + public ResultResponse> getLatestVipGiveawayRecords(Long userId, Integer limit) { + return ResultResponse.success(CollectionUtils.newArrayList()); + } } diff --git a/rc-service/rc-inner-api/wallet-inner/wallet-inner-model/src/main/java/com/red/circle/wallet/inner/model/dto/VipGiveawayGoldRecordDTO.java b/rc-service/rc-inner-api/wallet-inner/wallet-inner-model/src/main/java/com/red/circle/wallet/inner/model/dto/VipGiveawayGoldRecordDTO.java new file mode 100644 index 00000000..ad67c14c --- /dev/null +++ b/rc-service/rc-inner-api/wallet-inner/wallet-inner-model/src/main/java/com/red/circle/wallet/inner/model/dto/VipGiveawayGoldRecordDTO.java @@ -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; + +} diff --git a/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/sys/task/CheckInRestController.java b/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/sys/task/CheckInRestController.java index d32be29b..a3d879c3 100644 --- a/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/sys/task/CheckInRestController.java +++ b/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/sys/task/CheckInRestController.java @@ -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 getLatestVipGiveawayRecord(AppExtCommand cmd) { + return checkInService.getLatestVipGiveawayRecords(cmd); + } } diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/task/CheckInServiceImpl.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/task/CheckInServiceImpl.java index 9c838d8c..74b02ff5 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/task/CheckInServiceImpl.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/task/CheckInServiceImpl.java @@ -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 getLatestVipGiveawayRecords(AppExtCommand cmd) { + Long userId = cmd.getReqUserId(); + Integer limit = 1; // 默认查询1条 + + // 1. 调用wallet客户端查询VIP赠送记录(仅包含基础record信息) + ResultResponse> response = + walletGoldClient.getLatestVipGiveawayRecords(userId, limit); + + List records = ResponseAssert.requiredSuccess(response); + + if (CollectionUtils.isEmpty(records)) { + return CollectionUtils.newArrayList(); + } + + // 2. 收集所有eventId (商品ID) + Set 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 queryWrapper = + Wrappers.lambdaQuery() + .in(PropsCommodityStore::getId, commodityIds); + List commodityStores = propsCommodityStoreService.list(queryWrapper); + + // 构建 commodityId -> sourceId 映射 + Map commodityToSourceIdMap = commodityStores.stream() + .collect(Collectors.toMap( + PropsCommodityStore::getId, + PropsCommodityStore::getSourceId, + (v1, v2) -> v1 + )); + + // 4. 收集所有VIP sourceId + Set vipSourceIds = commodityToSourceIdMap.values().stream() + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // 5. 批量查询VIP信息 + Map vipAbilityMap = CollectionUtils.newHashMap(); + if (CollectionUtils.isNotEmpty(vipSourceIds)) { + try { + ResultResponse> 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 finalCommodityToSourceIdMap = commodityToSourceIdMap; + Map 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 convertToVipGiveawayRecords( + List records, + Map 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()); + } } diff --git a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/service/task/CheckInService.java b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/service/task/CheckInService.java index f7707a6c..ce189b41 100644 --- a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/service/task/CheckInService.java +++ b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/service/task/CheckInService.java @@ -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 getLatestVipGiveawayRecords(AppExtCommand cmd); } diff --git a/rc-service/rc-service-wallet/wallet-infrastructure/src/main/java/com/red/circle/wallet/infra/database/rds/service/WalletGoldAssetRecordService.java b/rc-service/rc-service-wallet/wallet-infrastructure/src/main/java/com/red/circle/wallet/infra/database/rds/service/WalletGoldAssetRecordService.java index 585bf88a..d5225a9d 100644 --- a/rc-service/rc-service-wallet/wallet-infrastructure/src/main/java/com/red/circle/wallet/infra/database/rds/service/WalletGoldAssetRecordService.java +++ b/rc-service/rc-service-wallet/wallet-infrastructure/src/main/java/com/red/circle/wallet/infra/database/rds/service/WalletGoldAssetRecordService.java @@ -48,4 +48,13 @@ public interface WalletGoldAssetRecordService extends BaseService listLatestVipGiveawayRecords(Long userId, Integer limit); + } diff --git a/rc-service/rc-service-wallet/wallet-infrastructure/src/main/java/com/red/circle/wallet/infra/database/rds/service/impl/WalletGoldAssetRecordServiceImpl.java b/rc-service/rc-service-wallet/wallet-infrastructure/src/main/java/com/red/circle/wallet/infra/database/rds/service/impl/WalletGoldAssetRecordServiceImpl.java index fca39081..1ae259f1 100644 --- a/rc-service/rc-service-wallet/wallet-infrastructure/src/main/java/com/red/circle/wallet/infra/database/rds/service/impl/WalletGoldAssetRecordServiceImpl.java +++ b/rc-service/rc-service-wallet/wallet-infrastructure/src/main/java/com/red/circle/wallet/infra/database/rds/service/impl/WalletGoldAssetRecordServiceImpl.java @@ -88,6 +88,16 @@ public class WalletGoldAssetRecordServiceImpl extends return Objects.equals(baseDAO.existsData(shardingMonth), Boolean.TRUE); } + @Override + public List 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); diff --git a/rc-service/rc-service-wallet/wallet-inner-endpoint/src/main/java/com/red/circle/wallet/inner/endpoint/wallet/WalletGoldClientEndpoint.java b/rc-service/rc-service-wallet/wallet-inner-endpoint/src/main/java/com/red/circle/wallet/inner/endpoint/wallet/WalletGoldClientEndpoint.java index a75309b1..c5ff2fb0 100644 --- a/rc-service/rc-service-wallet/wallet-inner-endpoint/src/main/java/com/red/circle/wallet/inner/endpoint/wallet/WalletGoldClientEndpoint.java +++ b/rc-service/rc-service-wallet/wallet-inner-endpoint/src/main/java/com/red/circle/wallet/inner/endpoint/wallet/WalletGoldClientEndpoint.java @@ -112,4 +112,11 @@ public class WalletGoldClientEndpoint implements WalletGoldClientApi { walletGoldClientService.listWalletGoldCountExport(sysOrigin, monthNumber)); } + @Override + public ResultResponse> getLatestVipGiveawayRecords(Long userId, + Integer limit) { + return ResultResponse.success( + walletGoldClientService.getLatestVipGiveawayRecords(userId, limit)); + } + } diff --git a/rc-service/rc-service-wallet/wallet-inner-endpoint/src/main/java/com/red/circle/wallet/inner/service/wallet/WalletGoldClientService.java b/rc-service/rc-service-wallet/wallet-inner-endpoint/src/main/java/com/red/circle/wallet/inner/service/wallet/WalletGoldClientService.java index f26b86aa..11100eb4 100644 --- a/rc-service/rc-service-wallet/wallet-inner-endpoint/src/main/java/com/red/circle/wallet/inner/service/wallet/WalletGoldClientService.java +++ b/rc-service/rc-service-wallet/wallet-inner-endpoint/src/main/java/com/red/circle/wallet/inner/service/wallet/WalletGoldClientService.java @@ -81,5 +81,14 @@ public interface WalletGoldClientService { */ List listWalletGoldCountExport(String sysOrigin, Integer monthNumber); + /** + * 查询用户最新的VIP赠送记录(仅返回金币记录信息). + * + * @param userId 用户ID + * @param limit 查询数量限制 + * @return VIP赠送金币记录列表 + */ + List getLatestVipGiveawayRecords(Long userId, Integer limit); + } diff --git a/rc-service/rc-service-wallet/wallet-inner-endpoint/src/main/java/com/red/circle/wallet/inner/service/wallet/impl/WalletGoldClientServiceImpl.java b/rc-service/rc-service-wallet/wallet-inner-endpoint/src/main/java/com/red/circle/wallet/inner/service/wallet/impl/WalletGoldClientServiceImpl.java index 2dc08357..b29cafc4 100644 --- a/rc-service/rc-service-wallet/wallet-inner-endpoint/src/main/java/com/red/circle/wallet/inner/service/wallet/impl/WalletGoldClientServiceImpl.java +++ b/rc-service/rc-service-wallet/wallet-inner-endpoint/src/main/java/com/red/circle/wallet/inner/service/wallet/impl/WalletGoldClientServiceImpl.java @@ -454,4 +454,19 @@ public class WalletGoldClientServiceImpl implements WalletGoldClientService { DataTypeUtils.toInteger(end))); } + @Override + public List getLatestVipGiveawayRecords(Long userId, Integer limit) { + // 查询用户的VIP赠送记录 + List records = walletGoldAssetRecordService.listLatestVipGiveawayRecords( + userId, limit); + + if (CollectionUtils.isEmpty(records)) { + return CollectionUtils.newArrayList(); + } + + return records.stream() + .map(walletInnerConvertor::toWalletGoldAssetRecordDTO) + .collect(Collectors.toList()); + } + }