火箭后台接口完善

This commit is contained in:
tianfeng 2025-11-12 00:03:26 +08:00
parent e279ad51db
commit 89a26758bc
15 changed files with 923 additions and 0 deletions

View File

@ -0,0 +1,16 @@
package com.red.circle.other.inner.endpoint.rocket;
import com.red.circle.other.inner.endpoint.rocket.api.RocketConfigClientApi;
import org.springframework.cloud.openfeign.FeignClient;
/**
* 火箭配置Feign客户端
*
* @author system
* @date 2025-01-15
*/
@FeignClient(name = "rocketConfigClient", url = "${feign.other.url}" +
RocketConfigClientApi.API_PREFIX)
public interface RocketConfigClient extends RocketConfigClientApi {
}

View File

@ -0,0 +1,59 @@
package com.red.circle.other.inner.endpoint.rocket.api;
import com.red.circle.framework.dto.ResultResponse;
import com.red.circle.other.inner.model.dto.rocket.RocketConfigDTO;
import com.red.circle.other.inner.model.dto.rocket.RocketStatisticsDTO;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
/**
* 火箭配置客户端API
*
* @author system
* @date 2025-01-15
*/
public interface RocketConfigClientApi {
String API_PREFIX = "/rocket-config/client";
/**
* 查询所有配置
*/
@GetMapping("/queryAll")
ResultResponse<List<RocketConfigDTO>> queryAll(@RequestParam(value = "status", required = false) Integer status);
/**
* 根据ID查询配置
*/
@GetMapping("/queryById")
ResultResponse<RocketConfigDTO> queryById(@RequestParam("id") Long id);
/**
* 根据等级查询配置
*/
@GetMapping("/queryByLevel")
ResultResponse<RocketConfigDTO> queryByLevel(@RequestParam("level") Integer level);
/**
* 更新配置
*/
@PostMapping("/update")
ResultResponse<Void> update(@RequestBody RocketConfigDTO dto);
/**
* 更新状态
*/
@PostMapping("/updateStatus")
ResultResponse<Void> updateStatus(@RequestParam("id") Long id,
@RequestParam("status") Integer status);
/**
* 查询统计数据
*/
@GetMapping("/statistics")
ResultResponse<RocketStatisticsDTO> queryStatistics();
}

View File

@ -0,0 +1,61 @@
package com.red.circle.other.inner.model.dto.rocket;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 火箭配置DTO
*
* @author system
* @date 2025-01-15
*/
@Data
public class RocketConfigDTO {
/**
* 配置ID
*/
private Long id;
/**
* 火箭等级 1/2/3
*/
private Integer level;
/**
* 最大能量值
*/
private Long maxEnergy;
/**
* 奖励配置(JSON)
*/
private String rewardConfig;
/**
* 贡献者奖励比例%
*/
private BigDecimal contributorRewardRate;
/**
* 普通用户奖励配置(JSON)
*/
private String normalRewardConfig;
/**
* 状态 1:启用 0:禁用
*/
private Integer status;
/**
* 创建时间
*/
private LocalDateTime createdAt;
/**
* 更新时间
*/
private LocalDateTime updatedAt;
}

View File

@ -0,0 +1,70 @@
package com.red.circle.other.inner.model.dto.rocket;
import lombok.Data;
import java.util.Map;
/**
* 火箭统计数据DTO
*
* @author system
* @date 2025-01-15
*/
@Data
public class RocketStatisticsDTO {
/**
* 今日发射次数
*/
private Long todayLaunches;
/**
* 本周发射次数
*/
private Long weekLaunches;
/**
* 本月发射次数
*/
private Long monthLaunches;
/**
* 总发射次数
*/
private Long totalLaunches;
/**
* 各等级发射次数分布
*/
private Map<Integer, Long> launchByLevel;
/**
* 今日奖励发放总额
*/
private Long todayRewardSent;
/**
* 本月奖励发放总额
*/
private Long monthRewardSent;
/**
* 总奖励发放额
*/
private Long totalRewardSent;
/**
* 今日领取人数
*/
private Long todayClaimUsers;
/**
* 本月领取人数
*/
private Long monthClaimUsers;
/**
* 总领取人数
*/
private Long totalClaimUsers;
}

View File

@ -0,0 +1,75 @@
package com.red.circle.console.adapter.admin;
import com.red.circle.console.app.command.rocket.RocketConfigQueryExe;
import com.red.circle.console.app.command.rocket.RocketConfigUpdateExe;
import com.red.circle.console.app.command.rocket.RocketStatisticsQueryExe;
import com.red.circle.console.app.dto.clienobject.RocketConfigCO;
import com.red.circle.console.app.dto.clienobject.RocketStatisticsCO;
import com.red.circle.console.app.dto.cmd.RocketConfigQueryCmd;
import com.red.circle.console.app.dto.cmd.RocketConfigUpdateCmd;
import com.red.circle.console.app.service.RocketConfigService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 火箭配置管理控制器
*
* @author system
* @date 2025-01-15
*/
@Slf4j
@RestController
@RequestMapping("/admin/rocket/config")
@RequiredArgsConstructor
public class RocketConfigRestController {
private final RocketConfigService rocketConfigService;
private final RocketConfigUpdateExe rocketConfigUpdateExe;
private final RocketStatisticsQueryExe rocketStatisticsQueryExe;
private final RocketConfigQueryExe rocketConfigQueryExe;
/**
* 查询所有火箭配置
*/
@GetMapping("/list")
public List<RocketConfigCO> queryAll(RocketConfigQueryCmd cmd) {
return rocketConfigQueryExe.queryAll(cmd);
}
/**
* 根据ID查询配置
*/
@GetMapping("/detail")
public RocketConfigCO queryById(@RequestParam("id") Long id) {
return rocketConfigQueryExe.queryById(id);
}
/**
* 更新配置
*/
@PostMapping("/update")
public void update(@Valid @RequestBody RocketConfigUpdateCmd cmd) {
rocketConfigUpdateExe.execute(cmd);
}
/**
* 启用/禁用配置
*/
@PostMapping("/updateStatus")
public void updateStatus(@RequestParam("id") Long id,
@RequestParam("status") Integer status) {
rocketConfigUpdateExe.updateStatus(id, status);
}
/**
* 查询统计数据
*/
@GetMapping("/statistics")
public RocketStatisticsCO queryStatistics() {
return rocketStatisticsQueryExe.execute();
}
}

View File

@ -0,0 +1,94 @@
package com.red.circle.console.app.command.rocket;
import com.red.circle.console.app.dto.clienobject.RocketConfigCO;
import com.red.circle.console.app.dto.cmd.RocketConfigQueryCmd;
import com.red.circle.framework.dto.ResultResponse;
import com.red.circle.other.inner.endpoint.rocket.RocketConfigClient;
import com.red.circle.other.inner.model.dto.rocket.RocketConfigDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
/**
* 火箭配置查询执行器
*
* @author system
* @date 2025-01-15
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class RocketConfigQueryExe {
private final RocketConfigClient rocketConfigClient;
/**
* 查询所有配置
*/
public List<RocketConfigCO> queryAll(RocketConfigQueryCmd cmd) {
ResultResponse<List<RocketConfigDTO>> response = rocketConfigClient.queryAll(cmd.getStatus());
if (!response.checkSuccess() || response.getBody() == null) {
throw new RuntimeException("查询火箭配置失败: " + response.getErrorMsg());
}
return response.getBody().stream()
.map(this::toConfigCO)
.collect(Collectors.toList());
}
/**
* 根据ID查询
*/
public RocketConfigCO queryById(Long id) {
ResultResponse<RocketConfigDTO> response = rocketConfigClient.queryById(id);
if (!response.checkSuccess() || response.getBody() == null) {
throw new RuntimeException("查询火箭配置失败: " + response.getErrorMsg());
}
return toConfigCO(response.getBody());
}
/**
* DTO转CO
*/
private RocketConfigCO toConfigCO(RocketConfigDTO dto) {
if (dto == null) {
return null;
}
RocketConfigCO co = new RocketConfigCO();
co.setId(dto.getId());
co.setLevel(dto.getLevel());
co.setLevelName(getLevelName(dto.getLevel()));
co.setMaxEnergy(dto.getMaxEnergy());
co.setRewardConfig(dto.getRewardConfig());
co.setContributorRewardRate(dto.getContributorRewardRate());
co.setNormalRewardConfig(dto.getNormalRewardConfig());
co.setStatus(dto.getStatus());
co.setStatusDesc(dto.getStatus() == 1 ? "启用" : "禁用");
co.setCreatedAt(dto.getCreatedAt());
co.setUpdatedAt(dto.getUpdatedAt());
return co;
}
/**
* 获取等级名称
*/
private String getLevelName(Integer level) {
if (level == null) {
return "";
}
return switch (level) {
case 1 -> "一级火箭";
case 2 -> "二级火箭";
case 3 -> "三级火箭";
default -> "未知等级";
};
}
}

View File

@ -0,0 +1,96 @@
package com.red.circle.console.app.command.rocket;
import com.red.circle.console.app.dto.cmd.RocketConfigUpdateCmd;
import com.red.circle.framework.dto.ResultResponse;
import com.red.circle.other.inner.endpoint.rocket.RocketConfigClient;
import com.red.circle.other.inner.model.dto.rocket.RocketConfigDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* 火箭配置更新执行器
*
* @author system
* @date 2025-01-15
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class RocketConfigUpdateExe {
private final RocketConfigClient rocketConfigClient;
/**
* 更新配置
*/
public void execute(RocketConfigUpdateCmd cmd) {
log.info("更新火箭配置: id={}, maxEnergy={}, status={}",
cmd.getId(), cmd.getMaxEnergy(), cmd.getStatus());
// 参数校验
validateConfig(cmd);
// 转换为DTO
RocketConfigDTO dto = new RocketConfigDTO();
dto.setId(cmd.getId());
dto.setMaxEnergy(cmd.getMaxEnergy());
dto.setRewardConfig(cmd.getRewardConfig());
dto.setContributorRewardRate(cmd.getContributorRewardRate());
dto.setNormalRewardConfig(cmd.getNormalRewardConfig());
dto.setStatus(cmd.getStatus());
// 调用Feign Client
ResultResponse<Void> response = rocketConfigClient.update(dto);
if (!response.checkSuccess()) {
throw new RuntimeException("更新火箭配置失败: " + response.getErrorMsg());
}
log.info("火箭配置更新成功: id={}", cmd.getId());
}
/**
* 更新状态
*/
public void updateStatus(Long id, Integer status) {
log.info("更新火箭配置状态: id={}, status={}", id, status);
// 校验参数
if (id == null) {
throw new RuntimeException("配置ID不能为空");
}
if (status == null || (status != 0 && status != 1)) {
throw new RuntimeException("状态值不合法");
}
// 调用Feign Client
ResultResponse<Void> response = rocketConfigClient.updateStatus(id, status);
if (!response.checkSuccess()) {
throw new RuntimeException("更新火箭配置状态失败: " + response.getErrorMsg());
}
log.info("火箭配置状态更新成功: id={}, status={}", id, status);
}
/**
* 校验配置
*/
private void validateConfig(RocketConfigUpdateCmd cmd) {
if (cmd.getMaxEnergy() != null && cmd.getMaxEnergy() <= 0) {
throw new RuntimeException("最大能量值必须大于0");
}
if (cmd.getContributorRewardRate() != null) {
if (cmd.getContributorRewardRate().doubleValue() < 0
|| cmd.getContributorRewardRate().doubleValue() > 100) {
throw new RuntimeException("贡献者奖励比例必须在0-100之间");
}
}
if (cmd.getStatus() != null && cmd.getStatus() != 0 && cmd.getStatus() != 1) {
throw new RuntimeException("状态值不合法");
}
}
}

View File

@ -0,0 +1,57 @@
package com.red.circle.console.app.command.rocket;
import com.red.circle.console.app.dto.clienobject.RocketStatisticsCO;
import com.red.circle.framework.dto.ResultResponse;
import com.red.circle.other.inner.endpoint.rocket.RocketConfigClient;
import com.red.circle.other.inner.model.dto.rocket.RocketStatisticsDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* 火箭统计查询执行器
*
* @author system
* @date 2025-01-15
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class RocketStatisticsQueryExe {
private final RocketConfigClient rocketConfigClient;
/**
* 查询统计数据
*/
public RocketStatisticsCO execute() {
ResultResponse<RocketStatisticsDTO> response = rocketConfigClient.queryStatistics();
if (!response.checkSuccess() || response.getBody() == null) {
log.warn("查询火箭统计数据失败: {}", response.getErrorMsg());
// 返回空数据
return new RocketStatisticsCO();
}
return toStatisticsCO(response.getBody());
}
/**
* DTO转CO
*/
private RocketStatisticsCO toStatisticsCO(RocketStatisticsDTO dto) {
RocketStatisticsCO co = new RocketStatisticsCO();
co.setTodayLaunches(dto.getTodayLaunches());
co.setWeekLaunches(dto.getWeekLaunches());
co.setMonthLaunches(dto.getMonthLaunches());
co.setTotalLaunches(dto.getTotalLaunches());
co.setLaunchByLevel(dto.getLaunchByLevel());
co.setTodayRewardSent(dto.getTodayRewardSent());
co.setMonthRewardSent(dto.getMonthRewardSent());
co.setTotalRewardSent(dto.getTotalRewardSent());
co.setTodayClaimUsers(dto.getTodayClaimUsers());
co.setMonthClaimUsers(dto.getMonthClaimUsers());
co.setTotalClaimUsers(dto.getTotalClaimUsers());
return co;
}
}

View File

@ -0,0 +1,71 @@
package com.red.circle.console.app.dto.clienobject;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 火箭配置客户端对象
*
* @author system
* @date 2025-01-15
*/
@Data
public class RocketConfigCO {
/**
* 配置ID
*/
private Long id;
/**
* 火箭等级
*/
private Integer level;
/**
* 等级名称
*/
private String levelName;
/**
* 最大能量值
*/
private Long maxEnergy;
/**
* 奖励配置(JSON)
*/
private String rewardConfig;
/**
* 贡献者奖励比例%
*/
private BigDecimal contributorRewardRate;
/**
* 普通用户奖励配置(JSON)
*/
private String normalRewardConfig;
/**
* 状态 1:启用 0:禁用
*/
private Integer status;
/**
* 状态描述
*/
private String statusDesc;
/**
* 创建时间
*/
private LocalDateTime createdAt;
/**
* 更新时间
*/
private LocalDateTime updatedAt;
}

View File

@ -0,0 +1,72 @@
package com.red.circle.console.app.dto.clienobject;
import lombok.Data;
import java.util.Map;
/**
* 火箭数据统计客户端对象
*
* @author system
* @date 2025-01-15
*/
@Data
public class RocketStatisticsCO {
/**
* 今日发射次数
*/
private Long todayLaunches;
/**
* 本周发射次数
*/
private Long weekLaunches;
/**
* 本月发射次数
*/
private Long monthLaunches;
/**
* 总发射次数
*/
private Long totalLaunches;
/**
* 各等级发射次数分布
* key: level (1/2/3)
* value: count
*/
private Map<Integer, Long> launchByLevel;
/**
* 今日奖励发放总额
*/
private Long todayRewardSent;
/**
* 本月奖励发放总额
*/
private Long monthRewardSent;
/**
* 总奖励发放额
*/
private Long totalRewardSent;
/**
* 今日领取人数
*/
private Long todayClaimUsers;
/**
* 本月领取人数
*/
private Long monthClaimUsers;
/**
* 总领取人数
*/
private Long totalClaimUsers;
}

View File

@ -0,0 +1,24 @@
package com.red.circle.console.app.dto.cmd;
import com.red.circle.common.business.dto.cmd.AppExtCommand;
import lombok.Data;
/**
* 火箭配置查询命令
*
* @author system
* @date 2025-01-15
*/
@Data
public class RocketConfigQueryCmd extends AppExtCommand {
/**
* 等级可选
*/
private Integer level;
/**
* 状态可选1:启用 0:禁用
*/
private Integer status;
}

View File

@ -0,0 +1,49 @@
package com.red.circle.console.app.dto.cmd;
import com.red.circle.common.business.dto.cmd.AppExtCommand;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.math.BigDecimal;
/**
* 火箭配置更新命令
*
* @author system
* @date 2025-01-15
*/
@Data
public class RocketConfigUpdateCmd extends AppExtCommand {
/**
* 配置ID
*/
@NotNull(message = "配置ID不能为空")
private Long id;
/**
* 最大能量值
*/
@NotNull(message = "最大能量值不能为空")
private Long maxEnergy;
/**
* 奖励配置(JSON)
*/
private String rewardConfig;
/**
* 贡献者奖励比例%
*/
private BigDecimal contributorRewardRate;
/**
* 普通用户奖励配置(JSON)
*/
private String normalRewardConfig;
/**
* 状态 1:启用 0:禁用
*/
private Integer status;
}

View File

@ -0,0 +1,42 @@
package com.red.circle.console.app.service;
import com.red.circle.console.app.dto.clienobject.RocketConfigCO;
import com.red.circle.console.app.dto.clienobject.RocketStatisticsCO;
import com.red.circle.console.app.dto.cmd.RocketConfigQueryCmd;
import com.red.circle.console.app.dto.cmd.RocketConfigUpdateCmd;
import java.util.List;
/**
* 火箭配置管理服务
*
* @author system
* @date 2025-01-15
*/
public interface RocketConfigService {
/**
* 查询所有配置
*/
List<RocketConfigCO> queryAll(RocketConfigQueryCmd cmd);
/**
* 根据ID查询配置
*/
RocketConfigCO queryById(Long id);
/**
* 更新配置
*/
void update(RocketConfigUpdateCmd cmd);
/**
* 启用/禁用配置
*/
void updateStatus(Long id, Integer status);
/**
* 查询火箭数据统计
*/
RocketStatisticsCO queryStatistics();
}

View File

@ -0,0 +1,28 @@
package com.red.circle.other.app.inner.convertor;
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;
/**
* 火箭内部接口转换器
*
* @author system
* @date 2025-01-15
*/
@Mapper(componentModel = "spring")
public interface RocketInnerConvertor {
RocketInnerConvertor INSTANCE = Mappers.getMapper(RocketInnerConvertor.class);
/**
* Domain转DTO
*/
RocketConfigDTO toDTO(RocketConfig config);
/**
* DTO转Domain
*/
RocketConfig toDomain(RocketConfigDTO dto);
}

View File

@ -0,0 +1,109 @@
package com.red.circle.other.app.inner.endpoint.rocket;
import com.red.circle.framework.dto.ResultResponse;
import com.red.circle.other.app.inner.convertor.RocketInnerConvertor;
import com.red.circle.other.domain.gateway.RocketConfigGateway;
import com.red.circle.other.domain.rocket.RocketConfig;
import com.red.circle.other.inner.endpoint.rocket.api.RocketConfigClientApi;
import com.red.circle.other.inner.model.dto.rocket.RocketConfigDTO;
import com.red.circle.other.inner.model.dto.rocket.RocketStatisticsDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
/**
* 火箭配置内部端点实现
*
* @author system
* @date 2025-01-15
*/
@Slf4j
@RestController
@RequiredArgsConstructor
public class RocketConfigEndpoint implements RocketConfigClientApi {
private final RocketConfigGateway rocketConfigGateway;
private final RocketInnerConvertor rocketInnerConvertor;
@Override
public ResultResponse<List<RocketConfigDTO>> queryAll(Integer status) {
List<RocketConfig> configs;
if (status != null) {
if (status == 1) {
configs = rocketConfigGateway.findAllEnabled();
} else {
configs = rocketConfigGateway.findAll();
}
} else {
configs = rocketConfigGateway.findAll();
}
List<RocketConfigDTO> dtoList = configs.stream()
.map(rocketInnerConvertor::toDTO)
.collect(Collectors.toList());
return ResultResponse.success(dtoList);
}
@Override
public ResultResponse<RocketConfigDTO> queryById(Long id) {
// 通过等级查询id就是等级
RocketConfig config = rocketConfigGateway.findByLevel(id.intValue());
if (config == null) {
return ResultResponse.failure("配置不存在");
}
return ResultResponse.success(rocketInnerConvertor.toDTO(config));
}
@Override
public ResultResponse<RocketConfigDTO> queryByLevel(Integer level) {
RocketConfig config = rocketConfigGateway.findByLevel(level);
if (config == null) {
return ResultResponse.failure("配置不存在");
}
return ResultResponse.success(rocketInnerConvertor.toDTO(config));
}
@Override
public ResultResponse<Void> update(RocketConfigDTO dto) {
RocketConfig config = rocketInnerConvertor.toDomain(dto);
rocketConfigGateway.update(config);
return ResultResponse.success();
}
@Override
public ResultResponse<Void> updateStatus(Long id, Integer status) {
RocketConfig config = rocketConfigGateway.findByLevel(id.intValue());
if (config == null) {
return ResultResponse.failure("配置不存在");
}
config.setStatus(status);
rocketConfigGateway.update(config);
return ResultResponse.success();
}
@Override
public ResultResponse<RocketStatisticsDTO> queryStatistics() {
// TODO: 实现真实的统计逻辑
// 需要查询 MongoDB rocket_launch_history MySQL rocket_reward_claim_log
RocketStatisticsDTO statistics = new RocketStatisticsDTO();
statistics.setTodayLaunches(0L);
statistics.setWeekLaunches(0L);
statistics.setMonthLaunches(0L);
statistics.setTotalLaunches(0L);
statistics.setLaunchByLevel(new HashMap<>());
statistics.setTodayRewardSent(0L);
statistics.setMonthRewardSent(0L);
statistics.setTotalRewardSent(0L);
statistics.setTodayClaimUsers(0L);
statistics.setMonthClaimUsers(0L);
statistics.setTotalClaimUsers(0L);
return ResultResponse.success(statistics);
}
}