873b8e55da
✨ 新功能: - 创建了完整的Service层架构,包含所有业务实体的Service接口和实现类 - 新增8个标准化的Controller类,支持完整的CRUD操作 - 实现了统一的Request/Response模式和分页查询功能 - 创建了认证服务(AuthService)和令牌服务(TokenService) - 添加了Redis配置和认证拦截器 🏗️ 架构优化: - 移除Controller层所有try-catch块,使用全局异常处理机制 - 创建了专门的异常类(AuthException, TokenException, CaptchaException) - 统一了API返回格式,完善了Result类的方法 - 实现了标准的分页查询和参数校验 📦 新增文件: - 8个Controller类: Achievement, Comment, CommunityPost, Conversation, CozeApiCall, EmotionAnalysis, Reward, UserStats - 12个Service接口和对应的实现类 - 标准化的DTO类(Request/Response) - 异常处理类和拦截器 - 测试用例 🔧 重构优化: - 重写了AuthController,移除所有业务逻辑到Service层 - 优化了MessageController,使用标准的Request/Response格式 - 更新了全局异常处理器,支持多种异常类型 - 完善了WebConfig配置,添加认证拦截器 📊 代码统计: - 新增文件: 60+个 - 新增代码行数: 8000+行 - 重构代码行数: 1000+行 - 移除过时接口: 4个
271 lines
9.1 KiB
Java
271 lines
9.1 KiB
Java
package com.emotion.controller;
|
|
|
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
import com.emotion.common.PageResult;
|
|
import com.emotion.common.Result;
|
|
import com.emotion.dto.request.PageRequest;
|
|
import com.emotion.dto.response.BaseResponse;
|
|
import com.emotion.entity.UserStats;
|
|
import com.emotion.service.UserStatsService;
|
|
import org.springframework.beans.BeanUtils;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.validation.annotation.Validated;
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
|
import javax.validation.constraints.NotBlank;
|
|
import javax.validation.constraints.NotNull;
|
|
import java.time.format.DateTimeFormatter;
|
|
import java.util.List;
|
|
import java.util.stream.Collectors;
|
|
|
|
/**
|
|
* 用户统计控制器
|
|
*
|
|
* @author emotion-museum
|
|
* @date 2025-07-23
|
|
*/
|
|
@RestController
|
|
@RequestMapping("/user-stats")
|
|
public class UserStatsController {
|
|
|
|
@Autowired
|
|
private UserStatsService userStatsService;
|
|
|
|
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
|
/**
|
|
* 分页查询用户统计
|
|
*/
|
|
@GetMapping("/page")
|
|
public Result<PageResult<UserStatsResponse>> getPage(@Validated PageRequest request) {
|
|
IPage<UserStats> page = userStatsService.getPage(request);
|
|
List<UserStatsResponse> responses = page.getRecords().stream()
|
|
.map(this::convertToResponse)
|
|
.collect(Collectors.toList());
|
|
|
|
PageResult<UserStatsResponse> pageResult = new PageResult<>();
|
|
pageResult.setCurrent(page.getCurrent());
|
|
pageResult.setSize(page.getSize());
|
|
pageResult.setTotal(page.getTotal());
|
|
pageResult.setPages(page.getPages());
|
|
pageResult.setRecords(responses);
|
|
|
|
return Result.success(pageResult);
|
|
}
|
|
|
|
/**
|
|
* 根据用户ID获取统计信息
|
|
*/
|
|
@GetMapping("/user/{userId}")
|
|
public Result<UserStatsResponse> getByUserId(@PathVariable String userId) {
|
|
UserStats stats = userStatsService.getByUserId(userId);
|
|
if (stats == null) {
|
|
return Result.notFound("用户统计不存在");
|
|
}
|
|
return Result.success(convertToResponse(stats));
|
|
}
|
|
|
|
/**
|
|
* 根据用户ID和统计类型获取统计信息
|
|
*/
|
|
@GetMapping("/user/{userId}/type/{statsType}")
|
|
public Result<UserStatsResponse> getByUserIdAndStatsType(@PathVariable String userId, @PathVariable String statsType) {
|
|
UserStats stats = userStatsService.getByUserIdAndStatsType(userId, statsType);
|
|
if (stats == null) {
|
|
return Result.notFound("用户统计不存在");
|
|
}
|
|
return Result.success(convertToResponse(stats));
|
|
}
|
|
|
|
/**
|
|
* 根据统计类型查询统计信息
|
|
*/
|
|
@GetMapping("/type/{statsType}")
|
|
public Result<List<UserStatsResponse>> getByStatsType(@PathVariable String statsType) {
|
|
List<UserStats> statsList = userStatsService.getByStatsType(statsType);
|
|
List<UserStatsResponse> responses = statsList.stream()
|
|
.map(this::convertToResponse)
|
|
.collect(Collectors.toList());
|
|
return Result.success(responses);
|
|
}
|
|
|
|
/**
|
|
* 查询用户的所有统计类型
|
|
*/
|
|
@GetMapping("/user/{userId}/all")
|
|
public Result<List<UserStatsResponse>> getAllStatsByUserId(@PathVariable String userId) {
|
|
List<UserStats> statsList = userStatsService.getAllStatsByUserId(userId);
|
|
List<UserStatsResponse> responses = statsList.stream()
|
|
.map(this::convertToResponse)
|
|
.collect(Collectors.toList());
|
|
return Result.success(responses);
|
|
}
|
|
|
|
/**
|
|
* 查询排名前N的用户统计
|
|
*/
|
|
@GetMapping("/type/{statsType}/top")
|
|
public Result<List<UserStatsResponse>> getTopUsersByStatsType(@PathVariable String statsType, @RequestParam(defaultValue = "10") Integer limit) {
|
|
List<UserStats> statsList = userStatsService.getTopUsersByStatsType(statsType, limit);
|
|
List<UserStatsResponse> responses = statsList.stream()
|
|
.map(this::convertToResponse)
|
|
.collect(Collectors.toList());
|
|
return Result.success(responses);
|
|
}
|
|
|
|
/**
|
|
* 查询用户在指定统计类型中的排名
|
|
*/
|
|
@GetMapping("/user/{userId}/type/{statsType}/rank")
|
|
public Result<Long> getUserRankByStatsType(@PathVariable String userId, @PathVariable String statsType) {
|
|
Long rank = userStatsService.getUserRankByStatsType(userId, statsType);
|
|
return Result.success(rank);
|
|
}
|
|
|
|
/**
|
|
* 创建或更新用户统计
|
|
*/
|
|
@PostMapping
|
|
public Result<UserStatsResponse> createOrUpdate(@RequestBody @Validated UserStatsCreateRequest request) {
|
|
UserStats stats = userStatsService.createOrUpdateUserStats(
|
|
request.getUserId(),
|
|
request.getStatsType(),
|
|
request.getValue(),
|
|
request.getPeriod()
|
|
);
|
|
return Result.success(convertToResponse(stats));
|
|
}
|
|
|
|
/**
|
|
* 更新用户统计值
|
|
*/
|
|
@PutMapping("/user/{userId}/type/{statsType}")
|
|
public Result<Void> updateStatsValue(@PathVariable String userId, @PathVariable String statsType, @RequestParam Double value) {
|
|
boolean updated = userStatsService.updateStatsValue(userId, statsType, value);
|
|
if (!updated) {
|
|
return Result.error("更新失败");
|
|
}
|
|
return Result.success();
|
|
}
|
|
|
|
/**
|
|
* 增加用户统计值
|
|
*/
|
|
@PutMapping("/user/{userId}/type/{statsType}/increment")
|
|
public Result<Void> incrementStatsValue(@PathVariable String userId, @PathVariable String statsType, @RequestParam Double increment) {
|
|
boolean updated = userStatsService.incrementStatsValue(userId, statsType, increment);
|
|
if (!updated) {
|
|
return Result.error("增加失败");
|
|
}
|
|
return Result.success();
|
|
}
|
|
|
|
/**
|
|
* 重新计算用户统计
|
|
*/
|
|
@PutMapping("/user/{userId}/recalculate")
|
|
public Result<Void> recalculateUserStats(@PathVariable String userId) {
|
|
boolean recalculated = userStatsService.recalculateUserStats(userId);
|
|
if (!recalculated) {
|
|
return Result.error("重新计算失败");
|
|
}
|
|
return Result.success();
|
|
}
|
|
|
|
/**
|
|
* 重新计算所有用户统计
|
|
*/
|
|
@PutMapping("/recalculate-all")
|
|
public Result<Void> recalculateAllUserStats() {
|
|
boolean recalculated = userStatsService.recalculateAllUserStats();
|
|
if (!recalculated) {
|
|
return Result.error("重新计算失败");
|
|
}
|
|
return Result.success();
|
|
}
|
|
|
|
/**
|
|
* 查询平均统计值
|
|
*/
|
|
@GetMapping("/type/{statsType}/avg")
|
|
public Result<Double> getAvgValueByStatsType(@PathVariable String statsType) {
|
|
Double avgValue = userStatsService.getAvgValueByStatsType(statsType);
|
|
return Result.success(avgValue);
|
|
}
|
|
|
|
/**
|
|
* 查询最大统计值
|
|
*/
|
|
@GetMapping("/type/{statsType}/max")
|
|
public Result<Double> getMaxValueByStatsType(@PathVariable String statsType) {
|
|
Double maxValue = userStatsService.getMaxValueByStatsType(statsType);
|
|
return Result.success(maxValue);
|
|
}
|
|
|
|
/**
|
|
* 查询最小统计值
|
|
*/
|
|
@GetMapping("/type/{statsType}/min")
|
|
public Result<Double> getMinValueByStatsType(@PathVariable String statsType) {
|
|
Double minValue = userStatsService.getMinValueByStatsType(statsType);
|
|
return Result.success(minValue);
|
|
}
|
|
|
|
/**
|
|
* 删除过期的统计数据
|
|
*/
|
|
@DeleteMapping("/expired")
|
|
public Result<Void> deleteExpiredStats(@RequestParam(defaultValue = "30") Integer days) {
|
|
boolean deleted = userStatsService.deleteExpiredStats(days);
|
|
if (!deleted) {
|
|
return Result.error("删除失败");
|
|
}
|
|
return Result.success();
|
|
}
|
|
|
|
/**
|
|
* 转换为响应对象
|
|
*/
|
|
private UserStatsResponse convertToResponse(UserStats stats) {
|
|
UserStatsResponse response = new UserStatsResponse();
|
|
BeanUtils.copyProperties(stats, response);
|
|
response.setId(stats.getId());
|
|
if (stats.getCreateTime() != null) {
|
|
response.setCreateTime(stats.getCreateTime().format(DATE_TIME_FORMATTER));
|
|
}
|
|
if (stats.getUpdateTime() != null) {
|
|
response.setUpdateTime(stats.getUpdateTime().format(DATE_TIME_FORMATTER));
|
|
}
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* 用户统计创建请求
|
|
*/
|
|
@lombok.Data
|
|
public static class UserStatsCreateRequest {
|
|
@NotBlank(message = "用户ID不能为空")
|
|
private String userId;
|
|
|
|
@NotBlank(message = "统计类型不能为空")
|
|
private String statsType;
|
|
|
|
@NotNull(message = "统计值不能为空")
|
|
private Double value;
|
|
|
|
private String period;
|
|
}
|
|
|
|
/**
|
|
* 用户统计响应类
|
|
*/
|
|
@lombok.Data
|
|
@lombok.EqualsAndHashCode(callSuper = true)
|
|
public static class UserStatsResponse extends BaseResponse {
|
|
private String userId;
|
|
private String statsType;
|
|
private Double value;
|
|
private String period;
|
|
}
|
|
}
|