Files
cpzs-frontend/Controller.txt
2025-08-01 19:03:57 +08:00

402 lines
18 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.xy.xyaicpzs.controller;
import com.xy.xyaicpzs.common.ErrorCode;
import com.xy.xyaicpzs.common.ResultUtils;
import com.xy.xyaicpzs.common.response.ApiResponse;
import com.xy.xyaicpzs.domain.entity.LotteryDraws;
import com.xy.xyaicpzs.domain.entity.PredictRecord;
import com.xy.xyaicpzs.service.BallAnalysisService;
import com.xy.xyaicpzs.service.LotteryDrawsService;
import com.xy.xyaicpzs.service.PredictRecordService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
* 球号分析控制器
* 提供球号分析算法的API接口
*/
@Slf4j
@RestController
@RequestMapping("/ball-analysis")
@Tag(name = "球号分析", description = "球号分析算法API")
public class BallAnalysisController {
@Autowired
private BallAnalysisService ballAnalysisService;
@Autowired
private LotteryDrawsService lotteryDrawsService;
@Autowired
private PredictRecordService predictRecordService;
@GetMapping("/predict-records/{userId}")
@Operation(summary = "获取用户推测记录", description = "根据用户ID获取该用户的所有推测记录按推测时间倒序排列")
public ApiResponse<List<PredictRecord>> getPredictRecordsByUserId(
@Parameter(description = "用户ID例如1001", required = true)
@PathVariable Long userId
, HttpServletRequest request) {
User loginUser = userService.getLoginUser(request);
if (loginUser == null){
return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "用户未登录");
}
try {
log.info("接收到获取用户推测记录请求用户ID={}", userId);
// 调用服务获取用户推测记录
List<PredictRecord> result = predictRecordService.getPredictRecordsByUserId(userId);
log.info("获取用户推测记录完成用户ID{},返回{}条记录", userId, result.size());
return ResultUtils.success(result);
} catch (Exception e) {
log.error("获取用户推测记录失败:{}", e.getMessage(), e);
return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取用户推测记录失败:" + e.getMessage());
}
}
/**
* 获取近期开奖信息
* @param limit 获取条数可选参数默认15条
* @return 近期开奖信息列表
*/
@GetMapping("/recent-draws")
@Operation(summary = "获取近期开奖信息", description = "获取最近的开奖信息默认返回15条按开奖期号倒序排列")
public ApiResponse<List<LotteryDraws>> getRecentDraws(
@Parameter(description = "获取条数默认15条", required = false)
@RequestParam(required = false, defaultValue = "15") Integer limit) {
try {
log.info("接收到获取近期开奖信息请求:条数={}", limit);
// 调用服务获取近期开奖信息
List<LotteryDraws> result = lotteryDrawsService.getRecentDraws(limit);
log.info("获取近期开奖信息完成,返回{}条记录", result.size());
return ResultUtils.success(result);
} catch (Exception e) {
log.error("获取近期开奖信息失败:{}", e.getMessage(), e);
return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取近期开奖信息失败:" + e.getMessage());
}
}
/**
* 根据日期范围查询开奖信息
* @param startDate 开始日期可选格式yyyy-MM-dd
* @param endDate 结束日期可选格式yyyy-MM-dd
* @return 开奖信息列表
*/
@GetMapping("/query-draws")
@Operation(summary = "按日期范围查询开奖信息", description = "根据日期范围查询开奖信息,支持单边日期查询")
public ApiResponse<List<LotteryDraws>> queryDraws(
@Parameter(description = "开始日期格式yyyy-MM-dd例如2025-01-01", required = false)
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
@Parameter(description = "结束日期格式yyyy-MM-dd例如2025-01-31", required = false)
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate) {
try {
log.info("接收到按日期范围查询开奖信息请求:开始日期={},结束日期={}", startDate, endDate);
// 日期范围验证
if (startDate != null && endDate != null && startDate.after(endDate)) {
return ResultUtils.error(ErrorCode.PARAMS_ERROR, "开始日期不能晚于结束日期");
}
// 调用服务按日期范围查询开奖信息
List<LotteryDraws> result = lotteryDrawsService.getByDateRange(startDate, endDate);
log.info("按日期范围查询开奖信息完成,返回{}条记录", result.size());
return ResultUtils.success(result);
} catch (Exception e) {
log.error("按日期范围查询开奖信息失败:{}", e.getMessage(), e);
return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "查询开奖信息失败:" + e.getMessage());
}
}
/**
* 根据期号精准查询单条开奖信息
* @param drawId 开奖期号
* @return 开奖信息
*/
@GetMapping("/draw/{drawId}")
@Operation(summary = "根据期号查询开奖信息", description = "根据期号精准查询单条开奖信息")
public ApiResponse<LotteryDraws> getDrawById(
@Parameter(description = "开奖期号例如2025056", required = true)
@PathVariable Long drawId) {
try {
log.info("接收到根据期号查询开奖信息请求:期号={}", drawId);
// 调用服务查询开奖信息
LotteryDraws result = lotteryDrawsService.getByDrawId(drawId);
if (result == null) {
log.warn("未找到期号为{}的开奖信息", drawId);
return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, "未找到期号为" + drawId + "的开奖信息");
}
log.info("根据期号查询开奖信息完成:{}", result.getDrawId());
return ResultUtils.success(result);
} catch (Exception e) {
log.error("根据期号查询开奖信息失败:{}", e.getMessage(), e);
return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "查询开奖信息失败:" + e.getMessage());
}
}
/**
* 创建推测记录
* @param userId 用户ID
* @param drawId 开奖期号
* @param drawDate 开奖日期
* @param redBalls 6个红球号码用逗号分隔
* @param blueBall 蓝球号码
* @return 创建的推测记录
*/
@PostMapping("/create-predict")
@Operation(summary = "创建推测记录", description = "向predict_record表插入一条推测记录数据")
public ApiResponse<PredictRecord> createPredictRecord(
@Parameter(description = "用户ID例如1001", required = true)
@RequestParam Long userId,
@Parameter(description = "开奖期号例如2025056", required = true)
@RequestParam Long drawId,
@Parameter(description = "开奖日期格式yyyy-MM-dd", required = true)
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") Date drawDate,
@Parameter(description = "6个红球号码用逗号分隔例如1,5,12,18,25,33", required = true)
@RequestParam String redBalls,
@Parameter(description = "蓝球号码例如8", required = true)
@RequestParam Integer blueBall) {
try {
log.info("接收到创建推测记录请求用户ID={},期号={},开奖日期={},红球={},蓝球={}",
userId, drawId, drawDate, redBalls, blueBall);
// 解析红球号码
List<Integer> redBallList = parseRedBalls(redBalls, 6, "红球");
// 调用服务创建推测记录
PredictRecord result = predictRecordService.createPredictRecord(userId, drawId, drawDate, redBallList, blueBall);
log.info("创建推测记录完成用户ID{}记录ID{}", userId, result.getId());
return ResultUtils.success(result);
} catch (Exception e) {
log.error("创建推测记录失败:{}", e.getMessage(), e);
return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "创建推测记录失败:" + e.getMessage());
}
}
/**
* 球号分析算法
* @param level 高位/中位/低位标识 (H/M/L)
* @param redBalls 6个红球号码用逗号分隔
* @param blueBall 蓝球号码
* @return 分析结果出现频率最高的前11位数字
*/
@PostMapping("/analyze")
@Operation(summary = "首球算法", description = "根据输入的级别、红球和蓝球分析出现频率最高的前11位数字")
public ApiResponse<List<Integer>> analyzeBalls(
@Parameter(description = "级别H(高位)/M(中位)/L(低位)", required = true)
@RequestParam String level,
@Parameter(description = "6个红球号码用逗号分隔例如1,5,12,18,25,33", required = true)
@RequestParam String redBalls,
@Parameter(description = "蓝球号码例如8", required = true)
@RequestParam Integer blueBall) {
try {
log.info("接收到球号分析请求:级别={},红球={},蓝球={}", level, redBalls, blueBall);
// 解析红球号码
List<Integer> redBallList = parseRedBalls(redBalls, 6, "红球");
// 调用分析服务
List<Integer> result = ballAnalysisService.analyzeBalls(level, redBallList, blueBall);
log.info("球号分析完成,结果:{}", result);
return ResultUtils.success(result);
} catch (Exception e) {
log.error("球号分析失败:{}", e.getMessage(), e);
return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "球号分析失败:" + e.getMessage());
}
}
/**
* 跟随球号分析算法
* @param level 高位/中位/低位标识 (H/M/L)
* @param firstThreeRedBalls 前3个红球号码用逗号分隔
* @param lastSixRedBalls 后6个红球号码用逗号分隔
* @param blueBall 蓝球号码
* @return 分析结果出现频率最高的前8位数字
*/
@PostMapping("/fallow")
@Operation(summary = "跟随球号分析算法", description = "根据输入的级别、前3个红球、后6个红球和蓝球分析出现频率最高的前8位数字")
public ApiResponse<List<Integer>> fallowBallAnalysis(
@Parameter(description = "级别H(高位)/M(中位)/L(低位)", required = true)
@RequestParam String level,
@Parameter(description = "前3个红球号码用逗号分隔例如7,24,27", required = true)
@RequestParam String firstThreeRedBalls,
@Parameter(description = "后6个红球号码用逗号分隔例如21,10,5,15,23,28", required = true)
@RequestParam String lastSixRedBalls,
@Parameter(description = "蓝球号码例如16", required = true)
@RequestParam Integer blueBall) {
try {
log.info("接收到跟随球号分析请求:级别={}前3个红球={}后6个红球={},蓝球={}",
level, firstThreeRedBalls, lastSixRedBalls, blueBall);
// 解析红球号码
List<Integer> firstThreeRedBallList = parseRedBalls(firstThreeRedBalls, 3, "前3个红球");
List<Integer> lastSixRedBallList = parseRedBalls(lastSixRedBalls, 6, "后6个红球");
// 调用分析服务
List<Integer> result = ballAnalysisService.fallowBallAnalysis(level, firstThreeRedBallList, lastSixRedBallList, blueBall);
log.info("跟随球号分析完成,结果:{}", result);
return ResultUtils.success(result);
} catch (Exception e) {
log.error("跟随球号分析失败:{}", e.getMessage(), e);
return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "跟随球号分析失败:" + e.getMessage());
}
}
/**
* 解析红球号码字符串
*/
private List<Integer> parseRedBalls(String redBalls, int expectedCount, String ballType) {
if (redBalls == null || redBalls.trim().isEmpty()) {
throw new IllegalArgumentException(ballType + "号码不能为空");
}
try {
String[] parts = redBalls.split(",");
if (parts.length != expectedCount) {
throw new IllegalArgumentException(ballType + "数量必须为" + expectedCount + "个,实际:" + parts.length);
}
List<Integer> result = Arrays.stream(parts)
.map(String::trim)
.map(Integer::parseInt)
.collect(java.util.stream.Collectors.toList());
// 验证红球号码范围
for (Integer ball : result) {
if (ball < 1 || ball > 33) {
throw new IllegalArgumentException(ballType + "号码必须在1-33范围内错误值" + ball);
}
}
return result;
} catch (NumberFormatException e) {
throw new IllegalArgumentException(ballType + "号码格式错误,请使用逗号分隔的数字");
}
}
/**
* 蓝球分析算法
* @param level 高位/中位/低位标识 (H/M/L)
* @param predictedRedBalls 6个推测红球号码用逗号分隔
* @param predictedBlueBalls 2个推测蓝球号码用逗号分隔
* @param lastRedBalls 6个上期红球号码用逗号分隔
* @param lastBlueBall 上期蓝球号码
* @return 分析结果频率最高的前4个蓝球号码
*/
@PostMapping("/blue-ball")
@Operation(summary = "蓝球分析算法", description = "根据输入的级别、推测红球、推测蓝球、上期红球和上期蓝球分析出频率最高的前4个蓝球号码")
public ApiResponse<List<Integer>> blueBallAnalysis(
@Parameter(description = "级别H(高位)/M(中位)/L(低位)", required = true)
@RequestParam String level,
@Parameter(description = "6个推测红球号码用逗号分隔例如26,20,18,32,10,14", required = true)
@RequestParam String predictedRedBalls,
@Parameter(description = "2个推测蓝球号码用逗号分隔例如5,8", required = true)
@RequestParam String predictedBlueBalls,
@Parameter(description = "6个上期红球号码用逗号分隔例如7,24,27,21,10,5", required = true)
@RequestParam String lastRedBalls,
@Parameter(description = "上期蓝球号码例如16", required = true)
@RequestParam Integer lastBlueBall) {
try {
log.info("接收到蓝球分析请求:级别={},推测红球={},推测蓝球={},上期红球={},上期蓝球={}",
level, predictedRedBalls, predictedBlueBalls, lastRedBalls, lastBlueBall);
// 解析球号
List<Integer> predictedRedBallList = parseRedBalls(predictedRedBalls, 6, "推测红球");
List<Integer> predictedBlueBallList = parseBlueBalls(predictedBlueBalls, 2, "推测蓝球");
List<Integer> lastRedBallList = parseRedBalls(lastRedBalls, 6, "上期红球");
// 调用分析服务
List<Integer> result = ballAnalysisService.blueBallAnalysis(
level, predictedRedBallList, predictedBlueBallList, lastRedBallList, lastBlueBall);
log.info("蓝球分析完成,结果:{}", result);
return ResultUtils.success(result);
} catch (Exception e) {
log.error("蓝球分析失败:{}", e.getMessage(), e);
return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "蓝球分析失败:" + e.getMessage());
}
}
/**
* 解析蓝球号码字符串
*/
private List<Integer> parseBlueBalls(String blueBalls, int expectedCount, String ballType) {
if (blueBalls == null || blueBalls.trim().isEmpty()) {
throw new IllegalArgumentException(ballType + "号码不能为空");
}
try {
String[] parts = blueBalls.split(",");
if (parts.length != expectedCount) {
throw new IllegalArgumentException(ballType + "数量必须为" + expectedCount + "个,实际:" + parts.length);
}
List<Integer> result = Arrays.stream(parts)
.map(String::trim)
.map(Integer::parseInt)
.collect(java.util.stream.Collectors.toList());
// 验证蓝球号码范围
for (Integer ball : result) {
if (ball < 1 || ball > 16) {
throw new IllegalArgumentException(ballType + "号码必须在1-16范围内错误值" + ball);
}
}
return result;
} catch (NumberFormatException e) {
throw new IllegalArgumentException(ballType + "号码格式错误,请使用逗号分隔的数字");
}
}
}