diff --git a/sql/ddl.sql b/sql/ddl.sql index b303653..4d64dd9 100644 --- a/sql/ddl.sql +++ b/sql/ddl.sql @@ -203,6 +203,7 @@ CREATE TABLE IF NOT EXISTS `predict_record` ( `redBall5` INT NOT NULL COMMENT '红5', `redBall6` INT NOT NULL COMMENT '红6', `blueBall` INT NOT NULL COMMENT '蓝球', + `type` VARCHAR(100) NOT NULL COMMENT '预测类型(双色球/组六/大乐透)', `predictStatus` VARCHAR(100) default '待开奖' NOT NULL COMMENT '预测状态(待开奖/已开奖)', `predictResult` VARCHAR(100) default '待开奖' NOT NULL COMMENT '预测结果(未中奖/三等奖/二等奖/一等奖)', `predictTime` datetime default CURRENT_TIMESTAMP not null comment '预测时间', @@ -221,14 +222,9 @@ CREATE TABLE IF NOT EXISTS `vip_code` ( usedUserId bigint null comment '使用人', usedUserName varchar(36) null comment '使用人名称', `createTime` datetime DEFAULT CURRENT_TIMESTAMP NOT NULL COMMENT '创建时间', - `updateTime` datetime NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - PRIMARY KEY (`id`), - UNIQUE KEY `Order_OrderNo_uindex` (`code`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='会员码表'; + `updateTime` datetime NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='会员码表'; -INSERT INTO `vip_code` (`id`, `code`, `vipExpireTime`, `vipNumber`, `isUse`, `createTime`, `updateTime`) VALUES -(1, 'A3B4C5D6E7F8G9H1', 1, '000001', 0, NOW(), NOW()), -(2, 'I2J3K4L5M6N7O8P9', 12, '000002', 0, NOW(), NOW()); CREATE TABLE IF NOT EXISTS `vip_exchange_record` ( @@ -241,7 +237,7 @@ CREATE TABLE IF NOT EXISTS `vip_exchange_record` ( `isUse` int NOT NULL COMMENT '是否兑换(未兑换/已兑换)', `exchangeTime` datetime DEFAULT CURRENT_TIMESTAMP NOT NULL COMMENT '兑换时间', `updateTime` datetime DEFAULT CURRENT_TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='会员兑换表'; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='会员兑换表'; CREATE TABLE IF NOT EXISTS `operation_history` ( `id` BIGINT AUTO_INCREMENT COMMENT '唯一标识符' PRIMARY KEY, @@ -252,7 +248,7 @@ CREATE TABLE IF NOT EXISTS `operation_history` ( `resultMessage` TEXT COMMENT '结果消息', `operationTime` DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL COMMENT '操作时间', `updateTime` DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='操作历史记录表'; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='操作历史记录表'; CREATE TABLE IF NOT EXISTS `chat_message` diff --git a/src/main/java/com/xy/xyaicpzs/exception/GlobalExceptionHandler.java b/src/main/java/com/xy/xyaicpzs/exception/GlobalExceptionHandler.java index d6cd857..c6ff72e 100644 --- a/src/main/java/com/xy/xyaicpzs/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/xy/xyaicpzs/exception/GlobalExceptionHandler.java @@ -3,6 +3,7 @@ package com.xy.xyaicpzs.exception; import com.xy.xyaicpzs.common.ErrorCode; import com.xy.xyaicpzs.common.ResultUtils; import com.xy.xyaicpzs.common.response.ApiResponse; +import io.swagger.v3.oas.annotations.Hidden; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; @@ -10,7 +11,8 @@ import org.springframework.web.bind.annotation.RestControllerAdvice; /** * 全局异常处理器 */ -//@RestControllerAdvice +@Hidden +@RestControllerAdvice @Slf4j public class GlobalExceptionHandler { diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index c21ab00..bba2d5c 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -4,24 +4,32 @@ spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/cpzs - username: root - password: root + username: cpzs_root + password: cpzs_123456 # datasource: # driver-class-name: com.mysql.cj.jdbc.Driver -# url: jdbc:mysql://47.117.22.239:3306/cpzs +# url: jdbc:mysql://47.117.22.239:3306/cpzs?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&failOverReadOnly=false&connectTimeout=10000&socketTimeout=30000 # username: cpzs_root # password: cpzs_123456 - data: - redis: - host: localhost - port: 6379 - database: 0 +# hikari: +# connection-timeout: 30000 # 连接超时时间(毫秒) +# idle-timeout: 600000 # 空闲连接存活最大时间(毫秒) +# maximum-pool-size: 10 # 连接池最大连接数 +# minimum-idle: 5 # 最小空闲连接数 +# max-lifetime: 1800000 # 连接的最大生命周期(毫秒) +# auto-commit: true # 自动提交 +# connection-test-query: SELECT 1 # 测试连接是否可用的查询语句 # data: # redis: -# host: 47.117.22.239 +# host: localhost # port: 6379 # database: 0 -# password: cpzs_123456 + data: + redis: + host: 47.117.22.239 + port: 6379 + database: 0 + password: cpzs_123456 server: port: 8123 servlet: diff --git a/src/test/java/com/xy/xyaicpzs/BallAnalysisFrequencyTest.java b/src/test/java/com/xy/xyaicpzs/BallAnalysisFrequencyTest.java deleted file mode 100644 index 170ffa5..0000000 --- a/src/test/java/com/xy/xyaicpzs/BallAnalysisFrequencyTest.java +++ /dev/null @@ -1,173 +0,0 @@ -package com.xy.xyaicpzs; - -import com.xy.xyaicpzs.mapper.T7Mapper; -import com.xy.xyaicpzs.service.BallAnalysisService; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import java.util.Arrays; -import java.util.List; - -/** - * 球号分析算法频次筛选测试 - * 验证当频次相同的球号超过11个时,使用T3表线系数进行二次筛选的功能 - */ -@Slf4j -@SpringBootTest -public class BallAnalysisFrequencyTest { - - @Autowired - private BallAnalysisService ballAnalysisService; - - /** - * 测试高位算法的频次筛选功能 - */ - @Test - public void testHighLevelFrequencySelection() { - log.info("=== 测试高位算法的频次筛选功能 ==="); - - // 输入参数 - String level = "H"; - List redBalls = Arrays.asList(7, 24, 27, 21, 10, 5); - Integer blueBall = 16; - - // 执行分析 - List result = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); - - // 验证结果 - log.info("高位算法结果:{}", result); - log.info("结果数量:{}", result.size()); - - // 断言 - assert result.size() == 11 : "结果应该包含11个球号"; - assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; - assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; - } - - /** - * 测试中位算法的频次筛选功能 - */ - @Test - public void testMiddleLevelFrequencySelection() { - log.info("=== 测试中位算法的频次筛选功能 ==="); - - // 输入参数 - String level = "M"; - List redBalls = Arrays.asList(2, 9, 14, 20, 25, 32); - Integer blueBall = 12; - - // 执行分析 - List result = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); - - // 验证结果 - log.info("中位算法结果:{}", result); - log.info("结果数量:{}", result.size()); - - // 断言 - assert result.size() == 11 : "结果应该包含11个球号"; - assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; - assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; - } - - /** - * 测试低位算法的频次筛选功能 - */ - @Test - public void testLowLevelFrequencySelection() { - log.info("=== 测试低位算法的频次筛选功能 ==="); - - // 输入参数 - String level = "L"; - List redBalls = Arrays.asList(3, 7, 11, 17, 22, 29); - Integer blueBall = 8; - - // 执行分析 - List result = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); - - // 验证结果 - log.info("低位算法结果:{}", result); - log.info("结果数量:{}", result.size()); - - // 断言 - assert result.size() == 11 : "结果应该包含11个球号"; - assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; - assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; - } - - /** - * 测试用户提供的示例场景 - * 模拟频次相同导致超过11个球号的情况 - */ - @Test - public void testUserExampleScenario() { - log.info("=== 测试用户示例场景 ==="); - log.info("模拟场景:"); - log.info("26出现了8次 - 直接选择"); - log.info("17出现了7次 - 直接选择"); - log.info("14出现了7次 - 直接选择"); - log.info("7出现了6次 - 直接选择"); - log.info("3出现了6次 - 直接选择"); - log.info("20出现了6次 - 直接选择"); - log.info("2,9,1,22,32,13出现了5次 - 需要T3表线系数筛选"); - - // 使用特定的红球和蓝球组合来模拟这种情况 - String level = "H"; - List redBalls = Arrays.asList(26, 17, 14, 7, 3, 20); - Integer blueBall = 2; - - // 执行分析 - List result = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); - - // 验证结果 - log.info("示例场景结果:{}", result); - log.info("结果数量:{}", result.size()); - - // 断言 - assert result.size() == 11 : "结果应该包含11个球号"; - assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; - assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; - - log.info("频次筛选测试完成!"); - } - - /** - * 测试边界情况:恰好11个球号 - */ - @Test - public void testExactly11Balls() { - log.info("=== 测试边界情况:恰好11个球号 ==="); - - String level = "M"; - List redBalls = Arrays.asList(5, 10, 15, 18, 24, 30); - Integer blueBall = 6; - - List result = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); - - log.info("边界情况结果:{}", result); - assert result.size() == 11 : "结果应该包含11个球号"; - } - - /** - * 测试极端情况:验证T3表线系数筛选的稳定性 - */ - @Test - public void testT3LineCoefficientStability() { - log.info("=== 测试T3表线系数筛选的稳定性 ==="); - - String level = "H"; - List redBalls = Arrays.asList(1, 2, 3, 4, 5, 6); - Integer blueBall = 1; - - // 多次执行同样的分析,结果应该一致 - List result1 = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); - List result2 = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); - - log.info("第一次结果:{}", result1); - log.info("第二次结果:{}", result2); - - assert result1.equals(result2) : "相同输入应该产生相同输出"; - log.info("T3表线系数筛选稳定性测试通过!"); - } -} \ No newline at end of file diff --git a/src/test/java/com/xy/xyaicpzs/BallAnalysisMultiLevelFilteringTest.java b/src/test/java/com/xy/xyaicpzs/BallAnalysisMultiLevelFilteringTest.java deleted file mode 100644 index 3123fba..0000000 --- a/src/test/java/com/xy/xyaicpzs/BallAnalysisMultiLevelFilteringTest.java +++ /dev/null @@ -1,232 +0,0 @@ -package com.xy.xyaicpzs; - -import com.xy.xyaicpzs.service.BallAnalysisService; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import java.util.Arrays; -import java.util.List; - -/** - * 球号分析多级筛选测试 - * 测试analyzeBalls方法的多级筛选功能 - */ -@Slf4j -@SpringBootTest -public class BallAnalysisMultiLevelFilteringTest { - - @Autowired - private BallAnalysisService ballAnalysisService; - - /** - * 测试高位算法的多级筛选 - */ - @Test - public void testHighLevelMultiLevelFiltering() { - log.info("=== 测试高位算法的多级筛选 ==="); - - // 输入参数 - String level = "H"; - List redBalls = Arrays.asList(1, 5, 12, 18, 25, 33); - Integer blueBall = 8; - - // 执行分析 - List result = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); - - // 验证结果 - log.info("高位算法多级筛选结果:{}", result); - log.info("结果数量:{}", result.size()); - - // 断言 - assert result.size() == 11 : "结果应该包含11个球号"; - assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; - assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; - - log.info("高位算法多级筛选测试通过!"); - } - - /** - * 测试中位算法的多级筛选 - */ - @Test - public void testMiddleLevelMultiLevelFiltering() { - log.info("=== 测试中位算法的多级筛选 ==="); - - // 输入参数 - String level = "M"; - List redBalls = Arrays.asList(2, 8, 15, 22, 28, 31); - Integer blueBall = 12; - - // 执行分析 - List result = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); - - // 验证结果 - log.info("中位算法多级筛选结果:{}", result); - log.info("结果数量:{}", result.size()); - - // 断言 - assert result.size() == 11 : "结果应该包含11个球号"; - assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; - assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; - - log.info("中位算法多级筛选测试通过!"); - } - - /** - * 测试低位算法的多级筛选 - */ - @Test - public void testLowLevelMultiLevelFiltering() { - log.info("=== 测试低位算法的多级筛选 ==="); - - // 输入参数 - String level = "L"; - List redBalls = Arrays.asList(3, 9, 16, 23, 29, 32); - Integer blueBall = 4; - - // 执行分析 - List result = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); - - // 验证结果 - log.info("低位算法多级筛选结果:{}", result); - log.info("结果数量:{}", result.size()); - - // 断言 - assert result.size() == 11 : "结果应该包含11个球号"; - assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; - assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; - - log.info("低位算法多级筛选测试通过!"); - } - - /** - * 测试可能触发多级筛选的特殊情况 - * 使用容易产生频率冲突的球号组合 - */ - @Test - public void testSpecialCaseForMultiLevelFiltering() { - log.info("=== 测试可能触发多级筛选的特殊情况 ==="); - - // 输入参数 - 使用一些常见的球号,可能会产生更多的频率冲突 - String level = "H"; - List redBalls = Arrays.asList(7, 14, 21, 28, 1, 8); - Integer blueBall = 16; - - // 执行分析 - List result = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); - - // 验证结果 - log.info("特殊情况多级筛选结果:{}", result); - log.info("结果数量:{}", result.size()); - - // 断言 - assert result.size() == 11 : "结果应该包含11个球号"; - assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; - assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; - - log.info("特殊情况多级筛选测试通过!"); - } - - /** - * 测试多次运行的一致性 - * 验证随机选择部分的稳定性 - */ - @Test - public void testConsistencyOfMultipleRuns() { - log.info("=== 测试多次运行的一致性 ==="); - - // 输入参数 - String level = "M"; - List redBalls = Arrays.asList(6, 13, 20, 27, 2, 9); - Integer blueBall = 11; - - // 执行多次分析 - List result1 = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); - List result2 = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); - List result3 = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); - - // 验证结果 - log.info("第1次结果:{}", result1); - log.info("第2次结果:{}", result2); - log.info("第3次结果:{}", result3); - - // 断言 - 每次结果都应该是11个不重复的球号 - assert result1.size() == 11 : "第1次结果应该包含11个球号"; - assert result2.size() == 11 : "第2次结果应该包含11个球号"; - assert result3.size() == 11 : "第3次结果应该包含11个球号"; - - assert result1.stream().distinct().count() == result1.size() : "第1次结果不应该有重复的球号"; - assert result2.stream().distinct().count() == result2.size() : "第2次结果不应该有重复的球号"; - assert result3.stream().distinct().count() == result3.size() : "第3次结果不应该有重复的球号"; - - // 注意:由于有随机选择的部分,结果可能不完全相同,但大部分应该是相同的 - log.info("多次运行一致性测试通过!"); - } - - /** - * 测试边界情况:所有球号频率都不同 - */ - @Test - public void testBoundaryCase_AllDifferentFrequencies() { - log.info("=== 测试边界情况:所有球号频率都不同 ==="); - - // 输入参数 - 使用差异较大的球号,减少频率冲突 - String level = "H"; - List redBalls = Arrays.asList(1, 11, 22, 33, 5, 15); - Integer blueBall = 1; - - // 执行分析 - List result = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); - - // 验证结果 - log.info("边界情况结果:{}", result); - log.info("结果数量:{}", result.size()); - - // 断言 - assert result.size() == 11 : "结果应该包含11个球号"; - assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; - assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; - - log.info("边界情况测试通过!"); - } - - /** - * 测试三种级别算法的对比 - */ - @Test - public void testAllLevelsComparison() { - log.info("=== 测试三种级别算法的对比 ==="); - - // 输入参数 - List redBalls = Arrays.asList(4, 10, 17, 24, 30, 6); - Integer blueBall = 14; - - // 执行三种级别的分析 - List resultH = ballAnalysisService.analyzeBalls("H", redBalls, blueBall); - List resultM = ballAnalysisService.analyzeBalls("M", redBalls, blueBall); - List resultL = ballAnalysisService.analyzeBalls("L", redBalls, blueBall); - - // 验证结果 - log.info("高位算法结果:{}", resultH); - log.info("中位算法结果:{}", resultM); - log.info("低位算法结果:{}", resultL); - - // 断言 - assert resultH.size() == 11 : "高位算法结果应该包含11个球号"; - assert resultM.size() == 11 : "中位算法结果应该包含11个球号"; - assert resultL.size() == 11 : "低位算法结果应该包含11个球号"; - - assert resultH.stream().distinct().count() == resultH.size() : "高位算法结果不应该有重复的球号"; - assert resultM.stream().distinct().count() == resultM.size() : "中位算法结果不应该有重复的球号"; - assert resultL.stream().distinct().count() == resultL.size() : "低位算法结果不应该有重复的球号"; - - // 分析结果差异 - log.info("高位与中位的交集:{}", resultH.stream().filter(resultM::contains).collect(java.util.stream.Collectors.toList())); - log.info("高位与低位的交集:{}", resultH.stream().filter(resultL::contains).collect(java.util.stream.Collectors.toList())); - log.info("中位与低位的交集:{}", resultM.stream().filter(resultL::contains).collect(java.util.stream.Collectors.toList())); - - log.info("三种级别算法对比测试通过!"); - } -} \ No newline at end of file diff --git a/src/test/java/com/xy/xyaicpzs/BlueBallAnalysisTest.java b/src/test/java/com/xy/xyaicpzs/BlueBallAnalysisTest.java deleted file mode 100644 index 71f5c1a..0000000 --- a/src/test/java/com/xy/xyaicpzs/BlueBallAnalysisTest.java +++ /dev/null @@ -1,204 +0,0 @@ -package com.xy.xyaicpzs; - -import com.xy.xyaicpzs.service.BallAnalysisService; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import java.util.Arrays; -import java.util.List; - -/** - * 蓝球分析算法测试类 - */ -@Slf4j -@SpringBootTest -public class BlueBallAnalysisTest { - - @Autowired - private BallAnalysisService ballAnalysisService; - - @Test - public void testBlueBallAnalysisHigh() { - log.info("=== 测试蓝球分析算法 - 高位算法 ==="); - - // 测试数据26 20 18 32 10 14 - String level = "H"; - List predictedRedBalls = Arrays.asList(26, 20, 18, 32, 10, 14); // 6个预测红球 - List predictedBlueBalls = Arrays.asList(5, 8); // 2个预测蓝球 - List lastRedBalls = Arrays.asList(7, 24, 27, 21, 10, 5); // 6个上期红球 - Integer lastBlueBall = 16; // 1个上期蓝球 - - log.info("输入参数:"); - log.info("级别:{}", level); - log.info("预测红球:{}", predictedRedBalls); - log.info("预测蓝球:{}", predictedBlueBalls); - log.info("上期红球:{}", lastRedBalls); - log.info("上期蓝球:{}", lastBlueBall); - - List result = ballAnalysisService.blueBallAnalysis( - level, predictedRedBalls, predictedBlueBalls, lastRedBalls, lastBlueBall); - - log.info("高位算法结果:{}", result); - - // 验证结果 - assert result != null : "结果不能为空"; - assert result.size() <= 4 : "结果数量不能超过4个"; - log.info("高位算法测试通过"); - } - - @Test - public void testBlueBallAnalysisMiddle() { - log.info("=== 测试蓝球分析算法 - 中位算法 ==="); - - // 测试数据 - String level = "M"; - List predictedRedBalls = Arrays.asList(3, 9, 14, 21, 27, 32); // 6个预测红球 - List predictedBlueBalls = Arrays.asList(5, 11); // 2个预测蓝球 - List lastRedBalls = Arrays.asList(4, 10, 16, 22, 29, 30); // 6个上期红球 - Integer lastBlueBall = 7; // 1个上期蓝球 - - log.info("输入参数:"); - log.info("级别:{}", level); - log.info("预测红球:{}", predictedRedBalls); - log.info("预测蓝球:{}", predictedBlueBalls); - log.info("上期红球:{}", lastRedBalls); - log.info("上期蓝球:{}", lastBlueBall); - - List result = ballAnalysisService.blueBallAnalysis( - level, predictedRedBalls, predictedBlueBalls, lastRedBalls, lastBlueBall); - - log.info("中位算法结果:{}", result); - - // 验证结果 - assert result != null : "结果不能为空"; - assert result.size() <= 4 : "结果数量不能超过4个"; - log.info("中位算法测试通过"); - } - - @Test - public void testBlueBallAnalysisLow() { - log.info("=== 测试蓝球分析算法 - 低位算法 ==="); - - // 测试数据 - String level = "L"; - List predictedRedBalls = Arrays.asList(6, 11, 17, 23, 26, 33); // 6个预测红球 - List predictedBlueBalls = Arrays.asList(2, 14); // 2个预测蓝球 - List lastRedBalls = Arrays.asList(1, 8, 13, 19, 24, 32); // 6个上期红球 - Integer lastBlueBall = 16; // 1个上期蓝球 - - log.info("输入参数:"); - log.info("级别:{}", level); - log.info("预测红球:{}", predictedRedBalls); - log.info("预测蓝球:{}", predictedBlueBalls); - log.info("上期红球:{}", lastRedBalls); - log.info("上期蓝球:{}", lastBlueBall); - - List result = ballAnalysisService.blueBallAnalysis( - level, predictedRedBalls, predictedBlueBalls, lastRedBalls, lastBlueBall); - - log.info("低位算法结果:{}", result); - - // 验证结果 - assert result != null : "结果不能为空"; - assert result.size() <= 4 : "结果数量不能超过4个"; - log.info("低位算法测试通过"); - } - - @Test - public void testBlueBallAnalysisAllLevels() { - log.info("=== 测试蓝球分析算法 - 三种级别对比 ==="); - - // 相同的测试数据 - List predictedRedBalls = Arrays.asList(7, 12, 18, 24, 29, 33); // 6个预测红球 - List predictedBlueBalls = Arrays.asList(4, 9); // 2个预测蓝球 - List lastRedBalls = Arrays.asList(3, 8, 14, 20, 25, 31); // 6个上期红球 - Integer lastBlueBall = 6; // 1个上期蓝球 - - log.info("使用相同输入测试三种级别算法:"); - log.info("预测红球:{}", predictedRedBalls); - log.info("预测蓝球:{}", predictedBlueBalls); - log.info("上期红球:{}", lastRedBalls); - log.info("上期蓝球:{}", lastBlueBall); - - // 高位算法 - List highResult = ballAnalysisService.blueBallAnalysis( - "H", predictedRedBalls, predictedBlueBalls, lastRedBalls, lastBlueBall); - log.info("高位算法结果:{}", highResult); - - // 中位算法 - List middleResult = ballAnalysisService.blueBallAnalysis( - "M", predictedRedBalls, predictedBlueBalls, lastRedBalls, lastBlueBall); - log.info("中位算法结果:{}", middleResult); - - // 低位算法 - List lowResult = ballAnalysisService.blueBallAnalysis( - "L", predictedRedBalls, predictedBlueBalls, lastRedBalls, lastBlueBall); - log.info("低位算法结果:{}", lowResult); - - // 验证结果 - assert highResult != null && highResult.size() <= 4 : "高位算法结果异常"; - assert middleResult != null && middleResult.size() <= 4 : "中位算法结果异常"; - assert lowResult != null && lowResult.size() <= 4 : "低位算法结果异常"; - - log.info("三种级别算法对比测试通过"); - } - - @Test - public void testBlueBallAnalysisParameterValidation() { - log.info("=== 测试蓝球分析算法 - 参数验证 ==="); - - // 测试无效级别 - try { - ballAnalysisService.blueBallAnalysis( - "X", Arrays.asList(1, 2, 3, 4, 5, 6), Arrays.asList(1, 2), - Arrays.asList(7, 8, 9, 10, 11, 12), 1); - assert false : "应该抛出异常"; - } catch (IllegalArgumentException e) { - log.info("无效级别测试通过:{}", e.getMessage()); - } - - // 测试预测红球数量错误 - try { - ballAnalysisService.blueBallAnalysis( - "H", Arrays.asList(1, 2, 3, 4, 5), Arrays.asList(1, 2), - Arrays.asList(7, 8, 9, 10, 11, 12), 1); - assert false : "应该抛出异常"; - } catch (IllegalArgumentException e) { - log.info("预测红球数量错误测试通过:{}", e.getMessage()); - } - - // 测试预测蓝球数量错误 - try { - ballAnalysisService.blueBallAnalysis( - "H", Arrays.asList(1, 2, 3, 4, 5, 6), Arrays.asList(1), - Arrays.asList(7, 8, 9, 10, 11, 12), 1); - assert false : "应该抛出异常"; - } catch (IllegalArgumentException e) { - log.info("预测蓝球数量错误测试通过:{}", e.getMessage()); - } - - // 测试红球号码超出范围 - try { - ballAnalysisService.blueBallAnalysis( - "H", Arrays.asList(1, 2, 3, 4, 5, 34), Arrays.asList(1, 2), - Arrays.asList(7, 8, 9, 10, 11, 12), 1); - assert false : "应该抛出异常"; - } catch (IllegalArgumentException e) { - log.info("红球号码超出范围测试通过:{}", e.getMessage()); - } - - // 测试蓝球号码超出范围 - try { - ballAnalysisService.blueBallAnalysis( - "H", Arrays.asList(1, 2, 3, 4, 5, 6), Arrays.asList(1, 17), - Arrays.asList(7, 8, 9, 10, 11, 12), 1); - assert false : "应该抛出异常"; - } catch (IllegalArgumentException e) { - log.info("蓝球号码超出范围测试通过:{}", e.getMessage()); - } - - log.info("参数验证测试全部通过"); - } -} \ No newline at end of file diff --git a/src/test/java/com/xy/xyaicpzs/DecimalPrecisionTest.java b/src/test/java/com/xy/xyaicpzs/DecimalPrecisionTest.java deleted file mode 100644 index 8358e76..0000000 --- a/src/test/java/com/xy/xyaicpzs/DecimalPrecisionTest.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.xy.xyaicpzs; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -import java.math.BigDecimal; -import java.math.RoundingMode; - -/** - * 小数精度处理测试类 - */ -@SpringBootTest -public class DecimalPrecisionTest { - - /** - * 测试小数位数处理方法 - */ - @Test - public void testDecimalPrecision() { - System.out.println("=== 小数位数处理测试 ==="); - - // 测试数据 - double[] testValues = { - 123.456789, // 多位小数 - 12.1, // 一位小数 - 5.0, // 整数 - 0.999, // 四舍五入测试 - 0.001, // 小数点后多位 - 99.999 // 进位测试 - }; - - for (double value : testValues) { - Double result = roundToTwoDecimalPlaces(value); - System.out.printf("原值:%f → 结果:%.2f%n", value, result); - } - } - - /** - * 将数值保留两位小数的辅助方法(与ExcelDataImporter中的方法相同) - */ - private Double roundToTwoDecimalPlaces(double value) { - if (Double.isNaN(value) || Double.isInfinite(value)) { - return null; - } - - try { - BigDecimal bd = new BigDecimal(Double.toString(value)); - return bd.setScale(2, RoundingMode.HALF_UP).doubleValue(); - } catch (Exception e) { - System.err.println("数值格式化失败:" + value); - return value; - } - } - - /** - * 测试边界情况 - */ - @Test - public void testEdgeCases() { - System.out.println("=== 边界情况测试 ==="); - - // 测试特殊值 - double[] edgeCases = { - Double.NaN, - Double.POSITIVE_INFINITY, - Double.NEGATIVE_INFINITY, - 0.0, - -0.0, - -123.456 - }; - - for (double value : edgeCases) { - Double result = roundToTwoDecimalPlaces(value); - System.out.printf("特殊值:%f → 结果:%s%n", value, result); - } - } -} \ No newline at end of file diff --git a/src/test/java/com/xy/xyaicpzs/ExcelImportTest.java b/src/test/java/com/xy/xyaicpzs/ExcelImportTest.java deleted file mode 100644 index 6906e9a..0000000 --- a/src/test/java/com/xy/xyaicpzs/ExcelImportTest.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.xy.xyaicpzs; - -import com.xy.xyaicpzs.service.ExcelImportService; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -/** - * Excel导入功能测试类 - */ -@SpringBootTest -public class ExcelImportTest { - - @Autowired - private ExcelImportService excelImportService; - - /** - * 测试通过文件路径导入Excel数据 - * 需要将kaifa1.xlsx文件放在项目根目录下 - * 现在会同时导入T1(红球)和T2(蓝球)的数据 - */ - @Test - public void testImportExcelByPath() { - // 假设Excel文件在项目根目录下 - String filePath = "kaifa1.xlsx"; - - try { - String result = excelImportService.importExcelFileByPath(filePath); - System.out.println("导入结果:" + result); - System.out.println("注意:系统会自动导入T1(红球)、T2(蓝球)、T3(红球线系数)、T4(蓝球组红球线系数)、T5(蓝球组蓝球线系数)、T6(红球组蓝球线系数)和T7(红球组红球面系数)七个工作表的数据"); - } catch (Exception e) { - System.err.println("导入失败:" + e.getMessage()); - e.printStackTrace(); - } - } - - /** - * 测试导入绝对路径的Excel文件 - * 请根据实际情况修改文件路径 - * 现在会同时导入T1(红球)和T2(蓝球)的数据 - */ - @Test - public void testImportExcelByAbsolutePath() { - // 请根据实际情况修改文件路径 - String filePath = "D:/code/xy-ai-cpzs/kaifa1.xlsx"; - - try { - String result = excelImportService.importExcelFileByPath(filePath); - System.out.println("导入结果:" + result); - System.out.println("数据导入详情:"); - System.out.println("- T1工作表 → 红球数据表(history_all, history_100, history_top, history_top_100)"); - System.out.println("- T2工作表 → 蓝球数据表(blue_history_all, blue_history_100, blue_history_top, blue_history_top_100)"); - System.out.println("- T3工作表 → 红球线系数表(t3,33×33=1089条记录)"); - System.out.println("- T4工作表 → 蓝球组红球线系数表(t4,16×33=528条记录)"); - System.out.println("- T5工作表 → 蓝球组蓝球线系数表(t5,16×16=256条记录)"); - System.out.println("- T6工作表 → 红球组蓝球线系数表(t6,33×16=528条记录)"); - System.out.println("- T7工作表 → 红球组红球面系数表(t7,33×32=1056条记录,排除自己组合)"); - } catch (Exception e) { - System.err.println("导入失败:" + e.getMessage()); - e.printStackTrace(); - } - } -} \ No newline at end of file diff --git a/src/test/java/com/xy/xyaicpzs/FallowBallAnalysisApiTest.java b/src/test/java/com/xy/xyaicpzs/FallowBallAnalysisApiTest.java deleted file mode 100644 index 8d754c5..0000000 --- a/src/test/java/com/xy/xyaicpzs/FallowBallAnalysisApiTest.java +++ /dev/null @@ -1,245 +0,0 @@ -package com.xy.xyaicpzs; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.xy.xyaicpzs.common.requset.FallowBallAnalysisRequest; -import com.xy.xyaicpzs.controller.BallAnalysisController; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.http.MediaType; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; - -import java.util.Arrays; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*; - -/** - * 跟随球号分析API接口测试 - * 测试REST API的功能和响应 - */ -@Slf4j -@SpringBootTest -@AutoConfigureMockMvc -public class FallowBallAnalysisApiTest { - - @Autowired - private MockMvc mockMvc; - - @Autowired - private ObjectMapper objectMapper; - - /** - * 测试表单参数方式的跟随球号分析接口 - */ - @Test - public void testFallowBallAnalysisWithFormParams() throws Exception { - log.info("=== 测试表单参数方式的跟随球号分析接口 ==="); - - mockMvc.perform(post("/api/ball-analysis/fallow") - .contentType(MediaType.APPLICATION_FORM_URLENCODED) - .param("level", "H") - .param("firstThreeRedBalls", "7,24,27") - .param("lastSixRedBalls", "21,10,5,15,23,28") - .param("blueBall", "16")) - .andDo(print()) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.success").value(true)) - .andExpect(jsonPath("$.data").isArray()) - .andExpect(jsonPath("$.data.length()").value(8)); - - log.info("表单参数方式测试通过!"); - } - - /** - * 测试JSON请求体方式的跟随球号分析接口 - */ - @Test - public void testFallowBallAnalysisWithJsonBody() throws Exception { - log.info("=== 测试JSON请求体方式的跟随球号分析接口 ==="); - - // 构建请求对象 - FallowBallAnalysisRequest request = - new FallowBallAnalysisRequest(); - request.setLevel("M"); - request.setFirstThreeRedBalls(Arrays.asList(26, 31, 28)); - request.setLastSixRedBalls(Arrays.asList(7, 24, 27, 21, 10, 5)); - request.setBlueBall(16); - - String requestJson = objectMapper.writeValueAsString(request); - log.info("请求JSON: {}", requestJson); - - mockMvc.perform(post("/api/ball-analysis/fallow-json") - .contentType(MediaType.APPLICATION_JSON) - .content(requestJson)) - .andDo(print()) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.success").value(true)) - .andExpect(jsonPath("$.data").isArray()) - .andExpect(jsonPath("$.data.length()").value(8)); - - log.info("JSON请求体方式测试通过!"); - } - - /** - * 测试获取算法说明接口 - */ - @Test - public void testGetFallowAlgorithmInfo() throws Exception { - log.info("=== 测试获取算法说明接口 ==="); - - mockMvc.perform(get("/api/ball-analysis/fallow-info")) - .andDo(print()) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.success").value(true)) - .andExpect(jsonPath("$.data").isString()) - .andExpect(jsonPath("$.data").value(org.hamcrest.Matchers.containsString("跟随球号分析算法说明"))); - - log.info("获取算法说明接口测试通过!"); - } - - /** - * 测试不同级别的算法 - */ - @Test - public void testAllLevelsWithJsonBody() throws Exception { - log.info("=== 测试不同级别的算法 ==="); - - String[] levels = {"H", "M", "L"}; - - for (String level : levels) { - log.info("测试{}级别算法", level); - - // 构建请求对象 - FallowBallAnalysisRequest request = - new FallowBallAnalysisRequest(); - request.setLevel(level); - request.setFirstThreeRedBalls(Arrays.asList(1, 15, 23)); - request.setLastSixRedBalls(Arrays.asList(28, 31, 33, 2, 8, 12)); - request.setBlueBall(8); - - String requestJson = objectMapper.writeValueAsString(request); - - mockMvc.perform(post("/api/ball-analysis/fallow-json") - .contentType(MediaType.APPLICATION_JSON) - .content(requestJson)) - .andDo(print()) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.success").value(true)) - .andExpect(jsonPath("$.data").isArray()) - .andExpect(jsonPath("$.data.length()").value(8)); - - log.info("{}级别算法测试通过!", level); - } - } - - /** - * 测试参数验证 - 错误的级别 - */ - @Test - public void testInvalidLevel() throws Exception { - log.info("=== 测试参数验证 - 错误的级别 ==="); - - mockMvc.perform(post("/api/ball-analysis/fallow") - .contentType(MediaType.APPLICATION_FORM_URLENCODED) - .param("level", "X") // 错误的级别 - .param("firstThreeRedBalls", "7,24,27") - .param("lastSixRedBalls", "21,10,5,15,23,28") - .param("blueBall", "16")) - .andDo(print()) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.success").value(false)) - .andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString("级别必须为H、M或L"))); - - log.info("错误级别参数验证测试通过!"); - } - - /** - * 测试参数验证 - 前3个红球数量错误 - */ - @Test - public void testInvalidFirstThreeRedBalls() throws Exception { - log.info("=== 测试参数验证 - 前3个红球数量错误 ==="); - - mockMvc.perform(post("/api/ball-analysis/fallow") - .contentType(MediaType.APPLICATION_FORM_URLENCODED) - .param("level", "H") - .param("firstThreeRedBalls", "7,24") // 只有2个球,应该是3个 - .param("lastSixRedBalls", "21,10,5,15,23,28") - .param("blueBall", "16")) - .andDo(print()) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.success").value(false)) - .andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString("前3个红球数量必须为3个"))); - - log.info("前3个红球数量错误参数验证测试通过!"); - } - - /** - * 测试参数验证 - 后6个红球数量错误 - */ - @Test - public void testInvalidLastSixRedBalls() throws Exception { - log.info("=== 测试参数验证 - 后6个红球数量错误 ==="); - - mockMvc.perform(post("/api/ball-analysis/fallow") - .contentType(MediaType.APPLICATION_FORM_URLENCODED) - .param("level", "H") - .param("firstThreeRedBalls", "7,24,27") - .param("lastSixRedBalls", "21,10,5,15,23") // 只有5个球,应该是6个 - .param("blueBall", "16")) - .andDo(print()) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.success").value(false)) - .andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString("后6个红球数量必须为6个"))); - - log.info("后6个红球数量错误参数验证测试通过!"); - } - - /** - * 测试参数验证 - 红球号码超出范围 - */ - @Test - public void testRedBallOutOfRange() throws Exception { - log.info("=== 测试参数验证 - 红球号码超出范围 ==="); - - mockMvc.perform(post("/api/ball-analysis/fallow") - .contentType(MediaType.APPLICATION_FORM_URLENCODED) - .param("level", "H") - .param("firstThreeRedBalls", "7,24,35") // 35超出范围 - .param("lastSixRedBalls", "21,10,5,15,23,28") - .param("blueBall", "16")) - .andDo(print()) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.success").value(false)) - .andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString("前3个红球号码必须在1-33范围内"))); - - log.info("红球号码超出范围参数验证测试通过!"); - } - - /** - * 测试边界情况 - 前3个红球和后6个红球有重叠 - */ - @Test - public void testOverlappingRedBalls() throws Exception { - log.info("=== 测试边界情况 - 前3个红球和后6个红球有重叠 ==="); - - // 前3个红球和后6个红球有重叠是允许的 - mockMvc.perform(post("/api/ball-analysis/fallow") - .contentType(MediaType.APPLICATION_FORM_URLENCODED) - .param("level", "H") - .param("firstThreeRedBalls", "7,24,27") - .param("lastSixRedBalls", "7,24,5,15,23,28") // 7和24重叠 - .param("blueBall", "16")) - .andDo(print()) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.success").value(true)) - .andExpect(jsonPath("$.data").isArray()) - .andExpect(jsonPath("$.data.length()").value(8)); - - log.info("前3个红球和后6个红球重叠测试通过!"); - } -} \ No newline at end of file diff --git a/src/test/java/com/xy/xyaicpzs/FallowBallAnalysisMultiLevelFilteringTest.java b/src/test/java/com/xy/xyaicpzs/FallowBallAnalysisMultiLevelFilteringTest.java deleted file mode 100644 index 59d639d..0000000 --- a/src/test/java/com/xy/xyaicpzs/FallowBallAnalysisMultiLevelFilteringTest.java +++ /dev/null @@ -1,250 +0,0 @@ -package com.xy.xyaicpzs; - -import com.xy.xyaicpzs.service.BallAnalysisService; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import java.util.Arrays; -import java.util.List; - -/** - * fallowBallAnalysis方法多级筛选功能测试 - * 测试T7面系数筛选后的多级筛选机制: - * 1. T7面系数总和筛选 - * 2. history_top_100排名筛选 - * 3. history_top点系数筛选 - * 4. 随机选择 - */ -@Slf4j -@SpringBootTest -public class FallowBallAnalysisMultiLevelFilteringTest { - - @Autowired - private BallAnalysisService ballAnalysisService; - - /** - * 测试高级算法的多级筛选 - */ - @Test - public void testHighLevelMultiLevelFiltering() { - log.info("=== 测试fallowBallAnalysis高级算法多级筛选 ==="); - - // 使用可能触发多级筛选的输入 - List firstThreeRedBalls = Arrays.asList(1, 2, 3); - List lastSixRedBalls = Arrays.asList(10, 15, 20, 25, 30, 33); - Integer blueBall = 5; - - List result = ballAnalysisService.fallowBallAnalysis("H", firstThreeRedBalls, lastSixRedBalls, blueBall); - - log.info("高级算法结果:{}", result); - - // 验证结果 - assert result != null : "结果不能为null"; - assert result.size() == 8 : "结果应该包含8个球号,实际:" + result.size(); - - // 验证球号范围 - for (Integer ball : result) { - assert ball >= 1 && ball <= 33 : "球号应该在1-33范围内,实际:" + ball; - } - - // 验证无重复 - assert result.stream().distinct().count() == result.size() : "结果不应该有重复球号"; - - log.info("高级算法多级筛选测试通过"); - } - - /** - * 测试中级算法的多级筛选 - */ - @Test - public void testMiddleLevelMultiLevelFiltering() { - log.info("=== 测试fallowBallAnalysis中级算法多级筛选 ==="); - - List firstThreeRedBalls = Arrays.asList(5, 8, 12); - List lastSixRedBalls = Arrays.asList(14, 18, 22, 26, 29, 32); - Integer blueBall = 8; - - List result = ballAnalysisService.fallowBallAnalysis("M", firstThreeRedBalls, lastSixRedBalls, blueBall); - - log.info("中级算法结果:{}", result); - - // 验证结果 - assert result != null : "结果不能为null"; - assert result.size() == 8 : "结果应该包含8个球号,实际:" + result.size(); - - // 验证球号范围 - for (Integer ball : result) { - assert ball >= 1 && ball <= 33 : "球号应该在1-33范围内,实际:" + ball; - } - - // 验证无重复 - assert result.stream().distinct().count() == result.size() : "结果不应该有重复球号"; - - log.info("中级算法多级筛选测试通过"); - } - - /** - * 测试低级算法的多级筛选 - */ - @Test - public void testLowLevelMultiLevelFiltering() { - log.info("=== 测试fallowBallAnalysis低级算法多级筛选 ==="); - - List firstThreeRedBalls = Arrays.asList(7, 11, 16); - List lastSixRedBalls = Arrays.asList(19, 21, 24, 27, 31, 33); - Integer blueBall = 12; - - List result = ballAnalysisService.fallowBallAnalysis("L", firstThreeRedBalls, lastSixRedBalls, blueBall); - - log.info("低级算法结果:{}", result); - - // 验证结果 - assert result != null : "结果不能为null"; - assert result.size() == 8 : "结果应该包含8个球号,实际:" + result.size(); - - // 验证球号范围 - for (Integer ball : result) { - assert ball >= 1 && ball <= 33 : "球号应该在1-33范围内,实际:" + ball; - } - - // 验证无重复 - assert result.stream().distinct().count() == result.size() : "结果不应该有重复球号"; - - log.info("低级算法多级筛选测试通过"); - } - - /** - * 测试可能触发多级筛选的特殊情况 - */ - @Test - public void testSpecialCasesForMultiLevelFiltering() { - log.info("=== 测试fallowBallAnalysis特殊情况多级筛选 ==="); - - // 使用连续数字,可能产生相同的面系数 - List firstThreeRedBalls = Arrays.asList(1, 2, 3); - List lastSixRedBalls = Arrays.asList(4, 5, 6, 7, 8, 9); - Integer blueBall = 1; - - List result = ballAnalysisService.fallowBallAnalysis("H", firstThreeRedBalls, lastSixRedBalls, blueBall); - - log.info("特殊情况结果:{}", result); - - // 验证结果 - assert result != null : "结果不能为null"; - assert result.size() == 8 : "结果应该包含8个球号,实际:" + result.size(); - - // 验证球号范围 - for (Integer ball : result) { - assert ball >= 1 && ball <= 33 : "球号应该在1-33范围内,实际:" + ball; - } - - // 验证无重复 - assert result.stream().distinct().count() == result.size() : "结果不应该有重复球号"; - - log.info("特殊情况多级筛选测试通过"); - } - - /** - * 测试多次运行的一致性(在相同输入下) - */ - @Test - public void testConsistencyAcrossMultipleRuns() { - log.info("=== 测试fallowBallAnalysis多次运行一致性 ==="); - - List firstThreeRedBalls = Arrays.asList(6, 13, 17); - List lastSixRedBalls = Arrays.asList(20, 23, 25, 28, 30, 32); - Integer blueBall = 10; - - // 运行多次并比较结果 - List result1 = ballAnalysisService.fallowBallAnalysis("M", firstThreeRedBalls, lastSixRedBalls, blueBall); - List result2 = ballAnalysisService.fallowBallAnalysis("M", firstThreeRedBalls, lastSixRedBalls, blueBall); - List result3 = ballAnalysisService.fallowBallAnalysis("M", firstThreeRedBalls, lastSixRedBalls, blueBall); - - log.info("第1次结果:{}", result1); - log.info("第2次结果:{}", result2); - log.info("第3次结果:{}", result3); - - // 验证所有结果都有效 - for (List result : Arrays.asList(result1, result2, result3)) { - assert result != null : "结果不能为null"; - assert result.size() == 8 : "结果应该包含8个球号"; - assert result.stream().distinct().count() == result.size() : "结果不应该有重复球号"; - } - - // 注意:由于最后一级是随机选择,结果可能不完全一致 - // 但前面几级的筛选应该是确定性的 - log.info("多次运行一致性测试完成(注意:最后一级随机选择可能导致结果不同)"); - } - - /** - * 测试边界情况 - */ - @Test - public void testBoundaryCases() { - log.info("=== 测试fallowBallAnalysis边界情况 ==="); - - // 测试最小值 - List firstThreeRedBalls = Arrays.asList(1, 2, 3); - List lastSixRedBalls = Arrays.asList(4, 5, 6, 7, 8, 9); - Integer blueBall = 1; - - List result1 = ballAnalysisService.fallowBallAnalysis("L", firstThreeRedBalls, lastSixRedBalls, blueBall); - log.info("最小值边界结果:{}", result1); - - // 测试最大值 - List firstThreeRedBalls2 = Arrays.asList(31, 32, 33); - List lastSixRedBalls2 = Arrays.asList(25, 26, 27, 28, 29, 30); - Integer blueBall2 = 16; - - List result2 = ballAnalysisService.fallowBallAnalysis("H", firstThreeRedBalls2, lastSixRedBalls2, blueBall2); - log.info("最大值边界结果:{}", result2); - - // 验证结果 - for (List result : Arrays.asList(result1, result2)) { - assert result != null : "结果不能为null"; - assert result.size() == 8 : "结果应该包含8个球号"; - assert result.stream().distinct().count() == result.size() : "结果不应该有重复球号"; - - for (Integer ball : result) { - assert ball >= 1 && ball <= 33 : "球号应该在1-33范围内,实际:" + ball; - } - } - - log.info("边界情况测试通过"); - } - - /** - * 测试三种级别算法的比较 - */ - @Test - public void testComparisonBetweenLevels() { - log.info("=== 测试fallowBallAnalysis三种级别算法比较 ==="); - - List firstThreeRedBalls = Arrays.asList(9, 14, 18); - List lastSixRedBalls = Arrays.asList(21, 24, 26, 29, 31, 33); - Integer blueBall = 7; - - List highResult = ballAnalysisService.fallowBallAnalysis("H", firstThreeRedBalls, lastSixRedBalls, blueBall); - List midResult = ballAnalysisService.fallowBallAnalysis("M", firstThreeRedBalls, lastSixRedBalls, blueBall); - List lowResult = ballAnalysisService.fallowBallAnalysis("L", firstThreeRedBalls, lastSixRedBalls, blueBall); - - log.info("高级算法结果:{}", highResult); - log.info("中级算法结果:{}", midResult); - log.info("低级算法结果:{}", lowResult); - - // 验证所有结果都有效 - for (List result : Arrays.asList(highResult, midResult, lowResult)) { - assert result != null : "结果不能为null"; - assert result.size() == 8 : "结果应该包含8个球号"; - assert result.stream().distinct().count() == result.size() : "结果不应该有重复球号"; - - for (Integer ball : result) { - assert ball >= 1 && ball <= 33 : "球号应该在1-33范围内,实际:" + ball; - } - } - - log.info("三种级别算法比较测试通过"); - } -} \ No newline at end of file diff --git a/src/test/java/com/xy/xyaicpzs/FallowBallAnalysisTest.java b/src/test/java/com/xy/xyaicpzs/FallowBallAnalysisTest.java deleted file mode 100644 index 2d46d29..0000000 --- a/src/test/java/com/xy/xyaicpzs/FallowBallAnalysisTest.java +++ /dev/null @@ -1,291 +0,0 @@ -package com.xy.xyaicpzs; - -import com.xy.xyaicpzs.service.BallAnalysisService; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import java.util.Arrays; -import java.util.List; - -/** - * 跟随球号分析算法测试 - * 验证fallowBallAnalysis方法的功能 - */ -@Slf4j -@SpringBootTest -public class FallowBallAnalysisTest { - - @Autowired - private BallAnalysisService ballAnalysisService; - - /** - * 测试高位算法的跟随球号分析 - */ - @Test - public void testHighLevelFallowBallAnalysis() { - log.info("=== 测试高位算法的跟随球号分析 ==="); - - // 输入参数 - String level = "H"; - List firstThreeRedBalls = Arrays.asList(26, 31, 28); // 前3个红球(独立的) - List lastSixRedBalls = Arrays.asList(7, 24, 27, 21, 10, 5);; // 后6个红球(独立的) - Integer blueBall = 16; - - // 执行分析 - List result = ballAnalysisService.fallowBallAnalysis(level, firstThreeRedBalls, lastSixRedBalls, blueBall); - - // 验证结果 - log.info("高位算法结果:{}", result); - log.info("结果数量:{}", result.size()); - - // 断言 - assert result.size() == 8 : "结果应该包含8个球号"; - assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; - assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; - - log.info("高位算法测试通过!"); - } - - /** - * 测试中位算法的跟随球号分析 - */ - @Test - public void testMiddleLevelFallowBallAnalysis() { - log.info("=== 测试中位算法的跟随球号分析 ==="); - - // 输入参数 - String level = "M"; - List firstThreeRedBalls = Arrays.asList(2, 9, 14); // 前3个红球(独立的) - List lastSixRedBalls = Arrays.asList(20, 25, 32, 1, 15, 23); // 后6个红球(独立的) - Integer blueBall = 12; - - // 执行分析 - List result = ballAnalysisService.fallowBallAnalysis(level, firstThreeRedBalls, lastSixRedBalls, blueBall); - - // 验证结果 - log.info("中位算法结果:{}", result); - log.info("结果数量:{}", result.size()); - - // 断言 - assert result.size() == 8 : "结果应该包含8个球号"; - assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; - assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; - - log.info("中位算法测试通过!"); - } - - /** - * 测试低位算法的跟随球号分析 - */ - @Test - public void testLowLevelFallowBallAnalysis() { - log.info("=== 测试低位算法的跟随球号分析 ==="); - - // 输入参数 - String level = "L"; - List firstThreeRedBalls = Arrays.asList(3, 7, 11); // 前3个红球(独立的) - List lastSixRedBalls = Arrays.asList(17, 22, 29, 4, 8, 13); // 后6个红球(独立的) - Integer blueBall = 8; - - // 执行分析 - List result = ballAnalysisService.fallowBallAnalysis(level, firstThreeRedBalls, lastSixRedBalls, blueBall); - - // 验证结果 - log.info("低位算法结果:{}", result); - log.info("结果数量:{}", result.size()); - - // 断言 - assert result.size() == 8 : "结果应该包含8个球号"; - assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; - assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; - - log.info("低位算法测试通过!"); - } - - /** - * 测试参数验证功能 - */ - @Test - public void testParameterValidation() { - log.info("=== 测试参数验证功能 ==="); - - String level = "H"; - List validFirstThree = Arrays.asList(1, 2, 3); - List validLastSix = Arrays.asList(4, 5, 6, 7, 8, 9); - Integer validBlueBall = 1; - - // 测试前3个红球数量错误 - try { - ballAnalysisService.fallowBallAnalysis(level, Arrays.asList(1, 2), validLastSix, validBlueBall); - assert false : "应该抛出异常"; - } catch (IllegalArgumentException e) { - log.info("前3个红球数量验证通过:{}", e.getMessage()); - } - - // 测试后6个红球数量错误 - try { - ballAnalysisService.fallowBallAnalysis(level, validFirstThree, Arrays.asList(1, 2, 3, 4, 5), validBlueBall); - assert false : "应该抛出异常"; - } catch (IllegalArgumentException e) { - log.info("后6个红球数量验证通过:{}", e.getMessage()); - } - - // 测试红球范围错误 - try { - ballAnalysisService.fallowBallAnalysis(level, Arrays.asList(1, 2, 34), validLastSix, validBlueBall); - assert false : "应该抛出异常"; - } catch (IllegalArgumentException e) { - log.info("红球范围验证通过:{}", e.getMessage()); - } - - // 测试蓝球范围错误 - try { - ballAnalysisService.fallowBallAnalysis(level, validFirstThree, validLastSix, 17); - assert false : "应该抛出异常"; - } catch (IllegalArgumentException e) { - log.info("蓝球范围验证通过:{}", e.getMessage()); - } - - // 测试前3个红球重复 - try { - ballAnalysisService.fallowBallAnalysis(level, Arrays.asList(1, 1, 3), validLastSix, validBlueBall); - assert false : "应该抛出异常"; - } catch (IllegalArgumentException e) { - log.info("前3个红球重复验证通过:{}", e.getMessage()); - } - - // 测试后6个红球重复 - try { - ballAnalysisService.fallowBallAnalysis(level, validFirstThree, Arrays.asList(4, 5, 6, 7, 8, 8), validBlueBall); - assert false : "应该抛出异常"; - } catch (IllegalArgumentException e) { - log.info("后6个红球重复验证通过:{}", e.getMessage()); - } - - // 测试级别错误 - try { - ballAnalysisService.fallowBallAnalysis("X", validFirstThree, validLastSix, validBlueBall); - assert false : "应该抛出异常"; - } catch (IllegalArgumentException e) { - log.info("级别验证通过:{}", e.getMessage()); - } - - log.info("参数验证测试全部通过!"); - } - - /** - * 测试数据收集的完整性 - */ - @Test - public void testDataCollectionCompleteness() { - log.info("=== 测试数据收集的完整性 ==="); - - String level = "H"; - List firstThreeRedBalls = Arrays.asList(1, 2, 3); - List lastSixRedBalls = Arrays.asList(4, 5, 6, 7, 8, 9); - Integer blueBall = 1; - - List result = ballAnalysisService.fallowBallAnalysis(level, firstThreeRedBalls, lastSixRedBalls, blueBall); - - log.info("数据收集完整性测试结果:{}", result); - - // 验证数据收集的逻辑 - // 第1个红球从T7表获取10个数字 - // 后6个红球每个从T3表获取26个数字,共6*26=156个数字 - // history_top_100表获取3个数字 - // 前3个红球的后两个,共2个数字 - // 蓝球从T4表获取10个数字 - // 总计:10 + 156 + 3 + 2 + 10 = 181个数字 - - log.info("预期数据收集:10(T7) + 156(T3) + 3(history_top_100) + 2(前3红球后2个) + 10(T4) = 181个数字"); - log.info("数据收集完整性测试通过!"); - } - - /** - * 测试算法稳定性 - */ - @Test - public void testAlgorithmStability() { - log.info("=== 测试算法稳定性 ==="); - - String level = "M"; - List firstThreeRedBalls = Arrays.asList(5, 10, 15); - List lastSixRedBalls = Arrays.asList(18, 24, 30, 12, 19, 26); - Integer blueBall = 6; - - // 多次执行同样的分析,结果应该一致 - List result1 = ballAnalysisService.fallowBallAnalysis(level, firstThreeRedBalls, lastSixRedBalls, blueBall); - List result2 = ballAnalysisService.fallowBallAnalysis(level, firstThreeRedBalls, lastSixRedBalls, blueBall); - - log.info("第一次结果:{}", result1); - log.info("第二次结果:{}", result2); - - assert result1.equals(result2) : "相同输入应该产生相同输出"; - log.info("算法稳定性测试通过!"); - } - - /** - * 测试边界情况 - */ - @Test - public void testBoundaryConditions() { - log.info("=== 测试边界情况 ==="); - - // 测试最小值边界 - String level = "L"; - List firstThreeRedBalls = Arrays.asList(1, 2, 3); - List lastSixRedBalls = Arrays.asList(4, 5, 6, 7, 8, 9); - Integer blueBall = 1; - - List result1 = ballAnalysisService.fallowBallAnalysis(level, firstThreeRedBalls, lastSixRedBalls, blueBall); - log.info("最小值边界测试结果:{}", result1); - - // 测试最大值边界 - firstThreeRedBalls = Arrays.asList(31, 32, 33); - lastSixRedBalls = Arrays.asList(25, 26, 27, 28, 29, 30); - blueBall = 16; - - List result2 = ballAnalysisService.fallowBallAnalysis(level, firstThreeRedBalls, lastSixRedBalls, blueBall); - log.info("最大值边界测试结果:{}", result2); - - // 验证结果 - assert result1.size() == 8 : "最小值边界结果应该包含8个球号"; - assert result2.size() == 8 : "最大值边界结果应该包含8个球号"; - - log.info("边界情况测试通过!"); - } - - /** - * 测试用户提供的示例场景 - * 模拟频次相同导致超过8个球号的情况 - */ - @Test - public void testUserExampleScenario() { - log.info("=== 测试用户示例场景 ==="); - log.info("模拟场景:"); - log.info("当频次相同的球号超过8个时"); - log.info("使用T7表面系数总和进行二次筛选"); - - // 使用特定的红球和蓝球组合来模拟这种情况 - String level = "H"; - List firstThreeRedBalls = Arrays.asList(26, 31, 28); - List lastSixRedBalls = Arrays.asList(7, 24, 27, 21, 10, 5); - Integer blueBall = 16; - - // 执行分析 - List result = ballAnalysisService.fallowBallAnalysis(level, firstThreeRedBalls, lastSixRedBalls, blueBall); - - // 验证结果 - log.info("示例场景结果:{}", result); - log.info("结果数量:{}", result.size()); - - // 断言 - assert result.size() == 8 : "结果应该包含8个球号"; - assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; - assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; - - log.info("频次筛选测试完成!"); - } -} \ No newline at end of file diff --git a/src/test/java/com/xy/xyaicpzs/GenerateVipCodesTest.java b/src/test/java/com/xy/xyaicpzs/GenerateVipCodesTest.java deleted file mode 100644 index 42e9935..0000000 --- a/src/test/java/com/xy/xyaicpzs/GenerateVipCodesTest.java +++ /dev/null @@ -1,126 +0,0 @@ -package com.xy.xyaicpzs; - -import com.xy.xyaicpzs.service.VipCodeService; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.ActiveProfiles; - -import jakarta.annotation.Resource; - -/** - * 生成会员码功能测试 - */ -@Slf4j -@SpringBootTest -@ActiveProfiles("test") -public class GenerateVipCodesTest { - - @Resource - private VipCodeService vipCodeService; - - @Test - public void testGenerateVipCodes() { - try { - // 测试生成10个1个月的会员码 - int numCodes = 10; - int vipExpireTime = 1; - - log.info("开始测试生成会员码功能,数量:{},有效月数:{}", numCodes, vipExpireTime); - - int result = vipCodeService.generateVipCodes(numCodes, vipExpireTime); - - log.info("生成会员码测试结果:{}", result); - - } catch (Exception e) { - log.error("生成会员码测试失败:{}", e.getMessage(), e); - } - } - - @Test - public void testGenerateVipCodesWithLargeQuantity() { - try { - // 测试生成50个12个月的会员码 - int numCodes = 50; - int vipExpireTime = 12; - - log.info("开始测试大批量生成会员码功能,数量:{},有效月数:{}", numCodes, vipExpireTime); - - int result = vipCodeService.generateVipCodes(numCodes, vipExpireTime); - - log.info("大批量生成会员码测试结果:{}", result); - - } catch (Exception e) { - log.error("大批量生成会员码测试失败:{}", e.getMessage(), e); - } - } - - @Test - public void testGenerateVipCodesWithInvalidParams() { - try { - // 测试无效参数 - int numCodes = -1; - int vipExpireTime = 1; - - log.info("开始测试无效参数的会员码生成,数量:{},有效月数:{}", numCodes, vipExpireTime); - - vipCodeService.generateVipCodes(numCodes, vipExpireTime); - - } catch (IllegalArgumentException e) { - log.info("预期的异常:{}", e.getMessage()); - } catch (Exception e) { - log.error("意外的异常:{}", e.getMessage(), e); - } - } - - @Test - public void testGetAvailableVipCode() { - try { - // 测试获取1个月的可用会员码 - int vipExpireTime = 1; - - log.info("开始测试获取可用会员码功能,有效月数:{}", vipExpireTime); - - String code = vipCodeService.getAvailableVipCode(vipExpireTime); - - log.info("获取可用会员码测试结果:{}", code); - - } catch (Exception e) { - log.error("获取可用会员码测试失败:{}", e.getMessage(), e); - } - } - - @Test - public void testGetAvailableVipCodeWith12Months() { - try { - // 测试获取12个月的可用会员码 - int vipExpireTime = 12; - - log.info("开始测试获取12个月可用会员码功能,有效月数:{}", vipExpireTime); - - String code = vipCodeService.getAvailableVipCode(vipExpireTime); - - log.info("获取12个月可用会员码测试结果:{}", code); - - } catch (Exception e) { - log.error("获取12个月可用会员码测试失败:{}", e.getMessage(), e); - } - } - - @Test - public void testGetAvailableVipCodeWithInvalidMonth() { - try { - // 测试无效的月数参数 - int vipExpireTime = 6; - - log.info("开始测试无效月数参数的获取可用会员码,有效月数:{}", vipExpireTime); - - vipCodeService.getAvailableVipCode(vipExpireTime); - - } catch (IllegalArgumentException e) { - log.info("预期的异常:{}", e.getMessage()); - } catch (Exception e) { - log.error("意外的异常:{}", e.getMessage(), e); - } - } -} \ No newline at end of file diff --git a/src/test/java/com/xy/xyaicpzs/UserControllerTest.java b/src/test/java/com/xy/xyaicpzs/UserControllerTest.java deleted file mode 100644 index 0519ecb..0000000 --- a/src/test/java/com/xy/xyaicpzs/UserControllerTest.java +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/test/java/com/xy/xyaicpzs/VipCodeActivateTest.java b/src/test/java/com/xy/xyaicpzs/VipCodeActivateTest.java deleted file mode 100644 index 072158c..0000000 --- a/src/test/java/com/xy/xyaicpzs/VipCodeActivateTest.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.xy.xyaicpzs; - -import com.xy.xyaicpzs.service.VipCodeService; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.ActiveProfiles; - -import jakarta.annotation.Resource; - -/** - * 会员码激活功能测试 - */ -@Slf4j -@SpringBootTest -@ActiveProfiles("test") -public class VipCodeActivateTest { - - @Resource - private VipCodeService vipCodeService; - - @Test - public void testActivateVipCode() { - try { - // 测试参数:用户ID=1,会员码=TEST_CODE_001 - // 实际测试时需要确保数据库中有对应的测试数据 - Long userId = 1L; - String code = "TEST_CODE_001"; - - log.info("开始测试会员码激活功能,用户ID:{},会员码:{}", userId, code); - - boolean result = vipCodeService.activateVipCode(userId, code); - - log.info("会员码激活测试结果:{}", result); - - } catch (Exception e) { - log.error("会员码激活测试失败:{}", e.getMessage(), e); - } - } - - @Test - public void testActivateVipCodeWithInvalidUser() { - try { - // 测试无效用户ID - Long userId = 999999L; - String code = "TEST_CODE_001"; - - log.info("开始测试无效用户ID的会员码激活,用户ID:{},会员码:{}", userId, code); - - vipCodeService.activateVipCode(userId, code); - - } catch (IllegalArgumentException e) { - log.info("预期的异常:{}", e.getMessage()); - } catch (Exception e) { - log.error("意外的异常:{}", e.getMessage(), e); - } - } - - @Test - public void testActivateVipCodeWithInvalidCode() { - try { - // 测试无效会员码 - Long userId = 1L; - String code = "INVALID_CODE"; - - log.info("开始测试无效会员码的激活,用户ID:{},会员码:{}", userId, code); - - vipCodeService.activateVipCode(userId, code); - - } catch (IllegalArgumentException e) { - log.info("预期的异常:{}", e.getMessage()); - } catch (Exception e) { - log.error("意外的异常:{}", e.getMessage(), e); - } - } -} \ No newline at end of file diff --git a/src/test/java/com/xy/xyaicpzs/mapper/T7MapperTest.java b/src/test/java/com/xy/xyaicpzs/mapper/T7MapperTest.java deleted file mode 100644 index 2a322fa..0000000 --- a/src/test/java/com/xy/xyaicpzs/mapper/T7MapperTest.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.xy.xyaicpzs.mapper; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import static org.junit.jupiter.api.Assertions.*; - - -@SpringBootTest -class T7MapperTest { - - @Autowired - private T7Mapper t7Mapper; - -} \ No newline at end of file