diff --git a/rc-service/rc-inner-api/other-inner/other-inner-model/src/main/java/com/red/circle/other/inner/model/dto/rocket/RocketConfigDTO.java b/rc-service/rc-inner-api/other-inner/other-inner-model/src/main/java/com/red/circle/other/inner/model/dto/rocket/RocketConfigDTO.java index 96086e9c..26e3fba9 100644 --- a/rc-service/rc-inner-api/other-inner/other-inner-model/src/main/java/com/red/circle/other/inner/model/dto/rocket/RocketConfigDTO.java +++ b/rc-service/rc-inner-api/other-inner/other-inner-model/src/main/java/com/red/circle/other/inner/model/dto/rocket/RocketConfigDTO.java @@ -1,5 +1,7 @@ package com.red.circle.other.inner.model.dto.rocket; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; import lombok.Data; import java.math.BigDecimal; @@ -32,7 +34,7 @@ public class RocketConfigDTO { /** * 奖励配置(JSON) */ - private String rewardConfig; + private JSONArray rewardConfig; /** * 贡献者奖励比例% @@ -42,7 +44,7 @@ public class RocketConfigDTO { /** * 普通用户奖励配置(JSON) */ - private String normalRewardConfig; + private JSONArray normalRewardConfig; /** * 状态 1:启用 0:禁用 diff --git a/rc-service/rc-service-console/console-client/src/main/java/com/red/circle/console/app/dto/clienobject/RocketConfigCO.java b/rc-service/rc-service-console/console-client/src/main/java/com/red/circle/console/app/dto/clienobject/RocketConfigCO.java index 0b115aaf..48c1a7df 100644 --- a/rc-service/rc-service-console/console-client/src/main/java/com/red/circle/console/app/dto/clienobject/RocketConfigCO.java +++ b/rc-service/rc-service-console/console-client/src/main/java/com/red/circle/console/app/dto/clienobject/RocketConfigCO.java @@ -1,5 +1,6 @@ package com.red.circle.console.app.dto.clienobject; +import com.alibaba.fastjson.JSONArray; import lombok.Data; import java.math.BigDecimal; @@ -33,22 +34,22 @@ public class RocketConfigCO { * 最大能量值 */ private Long maxEnergy; - + /** * 奖励配置(JSON) */ - private String rewardConfig; + private JSONArray rewardConfig; /** * 贡献者奖励比例% */ private BigDecimal contributorRewardRate; - + /** * 普通用户奖励配置(JSON) */ - private String normalRewardConfig; - + private JSONArray normalRewardConfig; + /** * 状态 1:启用 0:禁用 */ diff --git a/rc-service/rc-service-console/console-client/src/main/java/com/red/circle/console/app/dto/cmd/RocketConfigUpdateCmd.java b/rc-service/rc-service-console/console-client/src/main/java/com/red/circle/console/app/dto/cmd/RocketConfigUpdateCmd.java index 1af2c923..3aa0ac44 100644 --- a/rc-service/rc-service-console/console-client/src/main/java/com/red/circle/console/app/dto/cmd/RocketConfigUpdateCmd.java +++ b/rc-service/rc-service-console/console-client/src/main/java/com/red/circle/console/app/dto/cmd/RocketConfigUpdateCmd.java @@ -1,5 +1,6 @@ package com.red.circle.console.app.dto.cmd; +import com.alibaba.fastjson.JSONArray; import com.red.circle.common.business.dto.cmd.AppExtCommand; import jakarta.validation.constraints.NotNull; import lombok.Data; @@ -26,21 +27,21 @@ public class RocketConfigUpdateCmd extends AppExtCommand { */ @NotNull(message = "最大能量值不能为空") private Long maxEnergy; - + /** * 奖励配置(JSON) */ - private String rewardConfig; + private JSONArray rewardConfig; /** * 贡献者奖励比例% */ private BigDecimal contributorRewardRate; - + /** * 普通用户奖励配置(JSON) */ - private String normalRewardConfig; + private JSONArray normalRewardConfig; /** * 状态 1:启用 0:禁用 diff --git a/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/RocketRestController.java b/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/RocketRestController.java index 4c05b069..e72d80da 100644 --- a/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/RocketRestController.java +++ b/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/RocketRestController.java @@ -5,10 +5,14 @@ import com.red.circle.other.app.dto.clientobject.RocketStatusCO; import com.red.circle.other.app.dto.cmd.RocketRewardClaimCmd; import com.red.circle.other.app.dto.cmd.RocketStatusQueryCmd; import com.red.circle.other.app.service.RocketService; +import com.red.circle.other.domain.gateway.RocketConfigGateway; +import com.red.circle.other.domain.rocket.RocketConfig; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; +import java.util.List; + /** * 火箭REST控制器 * @@ -21,6 +25,7 @@ import org.springframework.web.bind.annotation.*; public class RocketRestController { private final RocketService rocketService; + private final RocketConfigGateway rocketConfigGateway; /** * 查询火箭状态 @@ -30,10 +35,18 @@ public class RocketRestController { return rocketService.queryStatus(cmd); } + /** + * 查询所有启用的火箭配置 + */ + @GetMapping("/config/enabled") + public List queryEnabledConfigs() { + return rocketConfigGateway.findAllEnabled(); + } + /** * 领取奖励 */ - @PostMapping("/claim") +// @PostMapping("/claim") public RocketRewardCO claimReward(@Valid @RequestBody RocketRewardClaimCmd cmd) { return rocketService.claimReward(cmd); } diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/rocket/RocketStatusQryExe.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/rocket/RocketStatusQryExe.java index 23447f36..e20a2ebf 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/rocket/RocketStatusQryExe.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/rocket/RocketStatusQryExe.java @@ -1,15 +1,19 @@ package com.red.circle.other.app.command.rocket; +import com.red.circle.other.app.convertor.RocketConvertor; import com.red.circle.other.app.dto.clientobject.RocketContributorCO; import com.red.circle.other.app.dto.clientobject.RocketStatusCO; import com.red.circle.other.app.dto.cmd.RocketStatusQueryCmd; -import com.red.circle.other.domain.gateway.RocketStatusGateway; import com.red.circle.other.domain.rocket.RocketContributor; +import com.red.circle.other.domain.rocket.RocketLevel; import com.red.circle.other.domain.rocket.RocketStatus; +import com.red.circle.other.domain.rocket.RocketStatusEnum; +import com.red.circle.other.infra.gateway.RocketStatusGatewayImpl; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import java.math.BigDecimal; import java.time.LocalDate; import java.util.ArrayList; import java.util.Comparator; @@ -27,7 +31,7 @@ import java.util.stream.Collectors; @RequiredArgsConstructor public class RocketStatusQryExe { - private final RocketStatusGateway rocketStatusGateway; + private final RocketStatusGatewayImpl rocketStatusGateway; /** * Top排行显示数量 @@ -35,20 +39,21 @@ public class RocketStatusQryExe { private static final int TOP_DISPLAY_COUNT = 10; /** - * 执行查询 + * 执行查询(只返回Top10贡献者) */ public RocketStatusCO execute(RocketStatusQueryCmd cmd) { - // 1. 查询火箭状态 + // 1. 查询火箭状态(性能优化) String today = LocalDate.now().toString(); - RocketStatus rocketStatus = rocketStatusGateway.findByRoomIdAndDate(cmd.getRoomId(), today); + RocketStatus rocketStatus = rocketStatusGateway + .findByRoomIdAndDateWithoutContributors(cmd.getRoomId(), today); if (rocketStatus == null) { // 返回初始状态 return buildInitialStatus(cmd.getRoomId()); } - // 2. 转换为CO - RocketStatusCO statusCO = convertToStatusCO(rocketStatus); + // 2. 使用转换器转换为CO + RocketStatusCO statusCO = RocketConvertor.toStatusCO(rocketStatus); // 3. 填充当前用户相关信息 if (cmd.getReqUserId() != null) { @@ -58,6 +63,27 @@ public class RocketStatusQryExe { return statusCO; } + /** + * 查询完整状态(包含所有贡献者) + * 用于:需要完整数据的特殊场景 + */ + public RocketStatusCO executeWithFullContributors(RocketStatusQueryCmd cmd) { + String today = LocalDate.now().toString(); + RocketStatus rocketStatus = rocketStatusGateway.findByRoomIdAndDate(cmd.getRoomId(), today); + + if (rocketStatus == null) { + return buildInitialStatus(cmd.getRoomId()); + } + + RocketStatusCO statusCO = RocketConvertor.toStatusCO(rocketStatus); + + if (cmd.getReqUserId() != null) { + fillUserInfo(statusCO, rocketStatus, cmd.getReqUserId()); + } + + return statusCO; + } + /** * 构建初始状态 */ @@ -69,8 +95,8 @@ public class RocketStatusQryExe { statusCO.setLevelName("一级火箭"); statusCO.setCurrentEnergy(0L); statusCO.setMaxEnergy(150000L); - statusCO.setEnergyPercent(java.math.BigDecimal.ZERO); - statusCO.setStatus("CHARGING"); + statusCO.setEnergyPercent(BigDecimal.ZERO); + statusCO.setStatus(RocketStatusEnum.CHARGING.name()); statusCO.setStatusDesc("充能中"); statusCO.setTopContributors(new ArrayList<>()); statusCO.setTotalContributors(0); @@ -80,61 +106,6 @@ public class RocketStatusQryExe { return statusCO; } - /** - * 转换为CO - */ - private RocketStatusCO convertToStatusCO(RocketStatus rocketStatus) { - RocketStatusCO statusCO = new RocketStatusCO(); - statusCO.setRoomId(rocketStatus.getRoomId()); - statusCO.setDate(rocketStatus.getDate()); - statusCO.setLevel(rocketStatus.getLevel().getLevel()); - statusCO.setLevelName(rocketStatus.getLevel().getName()); - statusCO.setCurrentEnergy(rocketStatus.getCurrentEnergy()); - statusCO.setMaxEnergy(rocketStatus.getMaxEnergy()); - statusCO.setEnergyPercent(rocketStatus.getEnergyPercent()); - statusCO.setStatus(rocketStatus.getStatus().name()); - statusCO.setStatusDesc(rocketStatus.getStatus().getDesc()); - statusCO.setLaunchTime(rocketStatus.getLaunchTime()); - statusCO.setClaimExpireTime(rocketStatus.getClaimExpireTime()); - statusCO.setClaimCount(rocketStatus.getClaimCount()); - - // 转换Top贡献者 - if (rocketStatus.getContributors() != null && !rocketStatus.getContributors().isEmpty()) { - List topContributors = rocketStatus.getContributors().stream() - .sorted(Comparator.comparing(RocketContributor::getEnergy).reversed()) - .limit(TOP_DISPLAY_COUNT) - .map(this::convertToContributorCO) - .collect(Collectors.toList()); - - // 设置排名 - for (int i = 0; i < topContributors.size(); i++) { - topContributors.get(i).setRank(i + 1); - } - - statusCO.setTopContributors(topContributors); - statusCO.setTotalContributors(rocketStatus.getContributors().size()); - } else { - statusCO.setTopContributors(new ArrayList<>()); - statusCO.setTotalContributors(0); - } - - return statusCO; - } - - /** - * 转换贡献者CO - */ - private RocketContributorCO convertToContributorCO(RocketContributor contributor) { - RocketContributorCO contributorCO = new RocketContributorCO(); - contributorCO.setUserId(contributor.getUserId()); - contributorCO.setUserName(contributor.getUserName()); - contributorCO.setUserAvatar(contributor.getUserAvatar()); - contributorCO.setEnergy(contributor.getEnergy()); - contributorCO.setContributionRate(contributor.getContributionRate()); - contributorCO.setGiftCount(contributor.getGiftCount()); - return contributorCO; - } - /** * 填充当前用户信息 */ @@ -142,10 +113,12 @@ public class RocketStatusQryExe { // 判断是否可领取 statusCO.setCanClaim(rocketStatus.canClaim()); - // TODO: 查询是否已领取 (需要查询MySQL) + // TODO: 查询是否已领取 (需要查询MySQL rocket_reward_claim_log) statusCO.setHasClaimed(false); // 查找当前用户贡献 + // 注意:如果使用了Top查询,这里可能查不到(用户不在Top10内) + // 可以考虑单独查询该用户的贡献数据 if (rocketStatus.getContributors() != null) { rocketStatus.getContributors().stream() .filter(c -> c.getUserId().equals(userId)) @@ -155,5 +128,12 @@ public class RocketStatusQryExe { statusCO.setMyContributionRate(contributor.getContributionRate()); }); } + + // 如果用户不在Top10内,可以单独查询(可选优化) + if (statusCO.getMyContribution() == null) { + // TODO: 使用聚合查询单独获取该用户的贡献数据 + statusCO.setMyContribution(0L); + statusCO.setMyContributionRate(BigDecimal.ZERO); + } } } diff --git a/rc-service/rc-service-other/other-domain/src/main/java/com/red/circle/other/domain/rocket/RocketConfig.java b/rc-service/rc-service-other/other-domain/src/main/java/com/red/circle/other/domain/rocket/RocketConfig.java index 0b1d2bff..e44880ce 100644 --- a/rc-service/rc-service-other/other-domain/src/main/java/com/red/circle/other/domain/rocket/RocketConfig.java +++ b/rc-service/rc-service-other/other-domain/src/main/java/com/red/circle/other/domain/rocket/RocketConfig.java @@ -1,5 +1,7 @@ package com.red.circle.other.domain.rocket; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; import lombok.Data; import java.math.BigDecimal; @@ -30,9 +32,9 @@ public class RocketConfig { private Long maxEnergy; /** - * 奖励配置(JSON预留) + * 奖励配置(JSON对象) */ - private String rewardConfig; + private JSONArray rewardConfig; /** * 贡献者奖励比例% @@ -40,9 +42,9 @@ public class RocketConfig { private BigDecimal contributorRewardRate; /** - * 普通用户奖励配置(JSON预留) + * 普通用户奖励配置(JSON对象) */ - private String normalRewardConfig; + private JSONArray normalRewardConfig; /** * 状态 1:启用 0:禁用 diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/convertor/RocketConfigConvertor.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/convertor/RocketConfigConvertor.java index 30adb13c..e0bf2484 100644 --- a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/convertor/RocketConfigConvertor.java +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/convertor/RocketConfigConvertor.java @@ -1,10 +1,12 @@ package com.red.circle.other.infra.convertor; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; import com.red.circle.other.domain.rocket.RocketConfig; import com.red.circle.other.infra.database.rds.entity.RocketConfigEntity; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; /** * 火箭配置转换器 @@ -12,20 +14,87 @@ import org.mapstruct.factory.Mappers; * @author system * @date 2025-01-15 */ -@Mapper(componentModel = "spring") -public interface RocketConfigConvertor { - - RocketConfigConvertor INSTANCE = Mappers.getMapper(RocketConfigConvertor.class); +public class RocketConfigConvertor { /** * Entity转Domain + * 将JSON字符串转换为JSONObject */ - RocketConfig toRocketConfig(RocketConfigEntity entity); + public static RocketConfig toRocketConfig(RocketConfigEntity entity) { + if (entity == null) { + return null; + } + + RocketConfig config = new RocketConfig(); + config.setId(entity.getId()); + config.setLevel(entity.getLevel()); + config.setMaxEnergy(entity.getMaxEnergy()); + + // 将JSON字符串转换为JSONObject + if (StringUtils.hasText(entity.getRewardConfig())) { + try { + config.setRewardConfig(JSON.parseArray(entity.getRewardConfig())); + } catch (Exception e) { + // 解析失败时设置为空对象 + config.setRewardConfig(new JSONArray()); + } + } else { + config.setRewardConfig(new JSONArray()); + } + + config.setContributorRewardRate(entity.getContributorRewardRate()); + + // 将JSON字符串转换为JSONObject + if (StringUtils.hasText(entity.getNormalRewardConfig())) { + try { + config.setNormalRewardConfig(JSON.parseArray(entity.getNormalRewardConfig())); + } catch (Exception e) { + config.setNormalRewardConfig(new JSONArray()); + } + } else { + config.setNormalRewardConfig(new JSONArray()); + } + + config.setStatus(entity.getStatus()); +// config.setCreatedAt(entity.getCreatedAt()); +// config.setUpdatedAt(entity.getUpdatedAt()); + + return config; + } /** * Domain转Entity + * 将JSONObject转换为JSON字符串 */ - @Mapping(target = "createdAt", ignore = true) - @Mapping(target = "updatedAt", ignore = true) - RocketConfigEntity toEntity(RocketConfig config); + public static RocketConfigEntity toEntity(RocketConfig config) { + if (config == null) { + return null; + } + + RocketConfigEntity entity = new RocketConfigEntity(); + entity.setId(config.getId()); + entity.setLevel(config.getLevel()); + entity.setMaxEnergy(config.getMaxEnergy()); + + // 将JSONObject转换为JSON字符串 + if (config.getRewardConfig() != null && !config.getRewardConfig().isEmpty()) { + entity.setRewardConfig(config.getRewardConfig().toJSONString()); + } else { + entity.setRewardConfig(null); + } + + entity.setContributorRewardRate(config.getContributorRewardRate()); + + // 将JSONObject转换为JSON字符串 + if (config.getNormalRewardConfig() != null && !config.getNormalRewardConfig().isEmpty()) { + entity.setNormalRewardConfig(config.getNormalRewardConfig().toJSONString()); + } else { + entity.setNormalRewardConfig(null); + } + + entity.setStatus(config.getStatus()); + // createdAt 和 updatedAt 由数据库自动管理 + + return entity; + } } diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/repository/RocketStatusRepository.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/repository/RocketStatusRepository.java index ea3e5971..70374e97 100644 --- a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/repository/RocketStatusRepository.java +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/repository/RocketStatusRepository.java @@ -2,6 +2,7 @@ package com.red.circle.other.infra.database.mongo.repository; import com.red.circle.other.infra.database.mongo.document.RocketStatusDocument; import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.data.mongodb.repository.Query; import org.springframework.stereotype.Repository; import java.util.List; @@ -17,17 +18,40 @@ import java.util.Optional; public interface RocketStatusRepository extends MongoRepository { /** - * 根据房间ID和日期查询 + * 根据房间ID和日期查询(完整数据,包含所有贡献者) + * 注意:用于需要完整贡献者列表的场景(如发射火箭保存历史) */ Optional findByRoomIdAndDate(Long roomId, String date); /** - * 根据房间ID列表和日期查询 + * 根据房间ID和日期查询(排除贡献者列表,性能优化) + * 用于:仅需要火箭状态,不需要贡献者详情的场景 */ - List findByRoomIdInAndDate(List roomIds, String date); + @Query(value = "{ 'room_id': ?0, 'date': ?1 }", fields = "{ 'contributors': 0 }") + Optional findByRoomIdAndDateWithoutContributors(Long roomId, String date); /** - * 查询所有处于充能状态的火箭 + * 根据房间ID和日期查询(只包含Top N贡献者) + * 用于:前端展示Top榜单的场景 + */ + @Query(value = "{ 'room_id': ?0, 'date': ?1 }", + fields = "{ 'contributors': { $slice: ?2 } }") + Optional findByRoomIdAndDateWithTopContributors(Long roomId, String date, Integer topN); + + /** + * 根据房间ID列表和日期查询(排除贡献者列表) + */ + @Query(value = "{ 'room_id': { $in: ?0 }, 'date': ?1 }", fields = "{ 'contributors': 0 }") + List findByRoomIdInAndDateWithoutContributors(List roomIds, String date); + + /** + * 查询所有处于充能状态的火箭(排除贡献者列表) + */ + @Query(value = "{ 'status': ?0, 'date': ?1 }", fields = "{ 'contributors': 0 }") + List findByStatusAndDateWithoutContributors(Integer status, String date); + + /** + * 查询所有处于充能状态的火箭(完整数据) */ List findByStatusAndDate(Integer status, String date); diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/entity/RocketConfigEntity.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/entity/RocketConfigEntity.java index 060caff3..c1ddf98e 100644 --- a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/entity/RocketConfigEntity.java +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/rds/entity/RocketConfigEntity.java @@ -1,6 +1,5 @@ package com.red.circle.other.infra.database.rds.entity; -import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.math.BigDecimal; @@ -13,7 +12,6 @@ import java.time.LocalDateTime; * @date 2025-01-15 */ @Data -@TableName("rocket_config") public class RocketConfigEntity { /** @@ -32,7 +30,7 @@ public class RocketConfigEntity { private Long maxEnergy; /** - * 奖励配置(JSON) + * 奖励配置(JSON字符串) */ private String rewardConfig; @@ -42,7 +40,7 @@ public class RocketConfigEntity { private BigDecimal contributorRewardRate; /** - * 普通用户奖励配置(JSON) + * 普通用户奖励配置(JSON字符串) */ private String normalRewardConfig; diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/gateway/RocketConfigGatewayImpl.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/gateway/RocketConfigGatewayImpl.java index 8b217058..d26cc5c4 100644 --- a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/gateway/RocketConfigGatewayImpl.java +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/gateway/RocketConfigGatewayImpl.java @@ -24,19 +24,18 @@ import java.util.stream.Collectors; public class RocketConfigGatewayImpl implements RocketConfigGateway { private final RocketConfigDAO rocketConfigDAO; - private final RocketConfigConvertor rocketConfigConvertor; @Override public RocketConfig findByLevel(Integer level) { RocketConfigEntity entity = rocketConfigDAO.selectByLevel(level); - return rocketConfigConvertor.toRocketConfig(entity); + return RocketConfigConvertor.toRocketConfig(entity); } @Override public List findAll() { List entities = rocketConfigDAO.selectAll(); return entities.stream() - .map(rocketConfigConvertor::toRocketConfig) + .map(RocketConfigConvertor::toRocketConfig) .collect(Collectors.toList()); } @@ -44,20 +43,20 @@ public class RocketConfigGatewayImpl implements RocketConfigGateway { public List findAllEnabled() { List entities = rocketConfigDAO.selectAllEnabled(); return entities.stream() - .map(rocketConfigConvertor::toRocketConfig) + .map(RocketConfigConvertor::toRocketConfig) .collect(Collectors.toList()); } @Override public void save(RocketConfig config) { - RocketConfigEntity entity = rocketConfigConvertor.toEntity(config); + RocketConfigEntity entity = RocketConfigConvertor.toEntity(config); rocketConfigDAO.insert(entity); config.setId(entity.getId()); } @Override public void update(RocketConfig config) { - RocketConfigEntity entity = rocketConfigConvertor.toEntity(config); + RocketConfigEntity entity = RocketConfigConvertor.toEntity(config); rocketConfigDAO.update(entity); } } diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/gateway/RocketStatusGatewayImpl.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/gateway/RocketStatusGatewayImpl.java index 3cc45284..af649f3c 100644 --- a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/gateway/RocketStatusGatewayImpl.java +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/gateway/RocketStatusGatewayImpl.java @@ -31,6 +31,26 @@ public class RocketStatusGatewayImpl implements RocketStatusGateway { .orElse(null); } + /** + * 查询火箭状态(不包含贡献者列表,性能优化) + * 用于:只需要基础信息的场景 + */ + public RocketStatus findByRoomIdAndDateWithoutContributors(Long roomId, String date) { + return rocketStatusRepository.findByRoomIdAndDateWithoutContributors(roomId, date) + .map(this::toDomain) + .orElse(null); + } + + /** + * 查询火箭状态(只包含Top N贡献者) + * 用于:前端展示排行榜 + */ + public RocketStatus findByRoomIdAndDateWithTopContributors(Long roomId, String date, Integer topN) { + return rocketStatusRepository.findByRoomIdAndDateWithTopContributors(roomId, date, topN) + .map(this::toDomain) + .orElse(null); + } + @Override public void save(RocketStatus rocketStatus) { RocketStatusDocument document = toDocument(rocketStatus); @@ -41,7 +61,9 @@ public class RocketStatusGatewayImpl implements RocketStatusGateway { @Override public List findByRoomIds(List roomIds, String date) { - List documents = rocketStatusRepository.findByRoomIdInAndDate(roomIds, date); + // 批量查询时不返回贡献者列表(性能优化) + List documents = rocketStatusRepository + .findByRoomIdInAndDateWithoutContributors(roomIds, date); return documents.stream() .map(this::toDomain) .collect(Collectors.toList()); @@ -49,6 +71,22 @@ public class RocketStatusGatewayImpl implements RocketStatusGateway { @Override public List findAllCharging(String date) { + // 定时任务查询时不需要贡献者列表(性能优化) + List documents = rocketStatusRepository + .findByStatusAndDateWithoutContributors( + RocketStatusEnum.CHARGING.getCode(), + date + ); + return documents.stream() + .map(this::toDomain) + .collect(Collectors.toList()); + } + + /** + * 查询所有充能状态的火箭(包含完整贡献者列表) + * 用于:需要保存历史记录的场景 + */ + public List findAllChargingWithContributors(String date) { List documents = rocketStatusRepository.findByStatusAndDate( RocketStatusEnum.CHARGING.getCode(), date @@ -76,7 +114,7 @@ public class RocketStatusGatewayImpl implements RocketStatusGateway { status.setMaxEnergy(doc.getMaxEnergy()); status.setStatus(RocketStatusEnum.of(doc.getStatus())); - // 转换贡献者 + // 转换贡献者(可能为null,如果使用了投影查询) if (doc.getContributors() != null) { List contributors = doc.getContributors().stream() .map(c -> { diff --git a/rc-service/rc-service-other/other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/convertor/RocketInnerConvertor.java b/rc-service/rc-service-other/other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/convertor/RocketInnerConvertor.java index 5d60df55..30806f52 100644 --- a/rc-service/rc-service-other/other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/convertor/RocketInnerConvertor.java +++ b/rc-service/rc-service-other/other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/convertor/RocketInnerConvertor.java @@ -1,9 +1,11 @@ package com.red.circle.other.app.inner.convertor; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.red.circle.other.domain.rocket.RocketConfig; import com.red.circle.other.inner.model.dto.rocket.RocketConfigDTO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; /** * 火箭内部接口转换器 @@ -11,18 +13,70 @@ import org.mapstruct.factory.Mappers; * @author system * @date 2025-01-15 */ -@Mapper(componentModel = "spring") -public interface RocketInnerConvertor { - - RocketInnerConvertor INSTANCE = Mappers.getMapper(RocketInnerConvertor.class); +@Component +public class RocketInnerConvertor { /** * Domain转DTO + * 将JSONObject转换为JSON字符串 */ - RocketConfigDTO toDTO(RocketConfig config); + public RocketConfigDTO toDTO(RocketConfig config) { + if (config == null) { + return null; + } + + RocketConfigDTO dto = new RocketConfigDTO(); + dto.setId(config.getId()); + dto.setLevel(config.getLevel()); + dto.setMaxEnergy(config.getMaxEnergy()); + + // 将JSONObject转换为JSON字符串 + if (config.getRewardConfig() != null && !config.getRewardConfig().isEmpty()) { + dto.setRewardConfig(config.getRewardConfig()); + } else { + dto.setRewardConfig(null); + } + + dto.setContributorRewardRate(config.getContributorRewardRate()); + + // 将JSONObject转换为JSON字符串 + if (config.getNormalRewardConfig() != null && !config.getNormalRewardConfig().isEmpty()) { + dto.setNormalRewardConfig(config.getNormalRewardConfig()); + } else { + dto.setNormalRewardConfig(null); + } + + dto.setStatus(config.getStatus()); + dto.setCreatedAt(config.getCreatedAt()); + dto.setUpdatedAt(config.getUpdatedAt()); + + return dto; + } /** * DTO转Domain + * 将JSON字符串转换为JSONObject */ - RocketConfig toDomain(RocketConfigDTO dto); + public RocketConfig toDomain(RocketConfigDTO dto) { + if (dto == null) { + return null; + } + + RocketConfig config = new RocketConfig(); + config.setId(dto.getId()); + config.setLevel(dto.getLevel()); + config.setMaxEnergy(dto.getMaxEnergy()); + + config.setRewardConfig(dto.getRewardConfig()); + + config.setContributorRewardRate(dto.getContributorRewardRate()); + + config.setNormalRewardConfig(dto.getNormalRewardConfig()); + + config.setStatus(dto.getStatus()); + config.setCreatedAt(dto.getCreatedAt()); + config.setUpdatedAt(dto.getUpdatedAt()); + + return config; + } }