diff --git a/src/main/java/com/xy/xyaicpzs/service/BallAnalysisService.java b/src/main/java/com/xy/xyaicpzs/service/BallAnalysisService.java index 3d6b863..ac45a13 100644 --- a/src/main/java/com/xy/xyaicpzs/service/BallAnalysisService.java +++ b/src/main/java/com/xy/xyaicpzs/service/BallAnalysisService.java @@ -1047,9 +1047,9 @@ public class BallAnalysisService { allNumbers.addAll(lastTwoOfFirstThree); log.info("前3个红球的后两个:{}", lastTwoOfFirstThree); - // 第五步:用上期蓝球从T5表获取12个蓝球号码 - log.info("第五步:用上期蓝球{}从T5表获取12个蓝球号码", blueBall); - List blueNumbers = getTop12FromT5(blueBall); + // 第五步:用上期蓝球从T4表获取17个蓝球号码 + log.info("第五步:用上期蓝球{}从T4表获取17个蓝球号码", blueBall); + List blueNumbers = getTop17FromT4(blueBall); allNumbers.addAll(blueNumbers); log.info("蓝球{}获取到{}个数字:{}", blueBall, blueNumbers.size(), blueNumbers); @@ -2012,9 +2012,9 @@ public class BallAnalysisService { log.info("第四步:添加预测的2个蓝球号码:{}", predictedBlueBalls); allNumbers.addAll(predictedBlueBalls); - // 第五步:用上期蓝球从T5表获取5个蓝球号码 - log.info("第五步:用上期蓝球{}从T5表获取5个蓝球号码,使用{}级别算法", lastBlueBall, level); - List t5Numbers = getSimpleTop5FromT5ByLevel(lastBlueBall, level); + // 第五步:用上期蓝球从T5表获取最大值向下12个蓝球号码 + log.info("第五步:用上期蓝球{}从T5表获取最大值向下12个蓝球号码", lastBlueBall); + List t5Numbers = getTop12FromT5(lastBlueBall); allNumbers.addAll(t5Numbers); log.info("上期蓝球{}从T5表获取到{}个蓝球号码:{}", lastBlueBall, t5Numbers.size(), t5Numbers); @@ -3151,4 +3151,66 @@ public class BallAnalysisService { log.debug("T5表主球{}最终选择的{}个从球:{}", masterBallNumber, result.size(), result); return result; } + + /** + * 从T4表获取指定主球的17个从球号,取线系数最大值向下17个数字 + * @param masterBallNumber 主球号 + */ + private List getTop17FromT4(Integer masterBallNumber) { + log.debug("从T4表查询主球{}的线系数数据,取前17个", masterBallNumber); + + // 查询指定主球的所有数据,按线系数降序排列 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("masterBallNumber", masterBallNumber) + .orderByDesc("lineCoefficient") + .orderByAsc("slaveBallNumber"); // 线系数相同时按从球号升序 + + List t4List = t4Mapper.selectList(queryWrapper); + + if (t4List.isEmpty()) { + log.warn("T4表中主球{}没有数据", masterBallNumber); + return new ArrayList<>(); + } + + if (t4List.size() < 17) { + log.warn("T4表数据不足17条,实际{}条", t4List.size()); + return t4List.stream().map(T4::getSlaveBallNumber).collect(Collectors.toList()); + } + + // 获取前16个 + List result = new ArrayList<>(); + for (int i = 0; i < 16; i++) { + result.add(t4List.get(i).getSlaveBallNumber()); + } + + // 处理第17个位置:检查是否有相同的线系数 + Double targetCoefficient = t4List.get(16).getLineCoefficient(); + List candidatesFor17th = new ArrayList<>(); + + // 找出所有线系数等于第17个位置线系数的记录 + for (int i = 16; i < t4List.size(); i++) { + if (t4List.get(i).getLineCoefficient().equals(targetCoefficient)) { + candidatesFor17th.add(t4List.get(i)); + } else { + break; // 线系数不同,停止查找 + } + } + + if (candidatesFor17th.size() == 1) { + // 只有一个候选,直接添加 + result.add(candidatesFor17th.get(0).getSlaveBallNumber()); + } else { + // 有多个候选,通过history_top_100表的点系数排序 + log.debug("第17位有{}个相同线系数的候选:{}", candidatesFor17th.size(), + candidatesFor17th.stream().map(T4::getSlaveBallNumber).collect(Collectors.toList())); + + Integer bestBall = selectBestBallFromHistoryTop100( + candidatesFor17th.stream().map(T4::getSlaveBallNumber).collect(Collectors.toList()) + ); + result.add(bestBall); + } + + log.debug("T4表主球{}最终选择的17个从球:{}", masterBallNumber, result); + return result; + } } \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/util/ExcelDataImporter.java b/src/main/java/com/xy/xyaicpzs/util/ExcelDataImporter.java index db7fa85..badc74f 100644 --- a/src/main/java/com/xy/xyaicpzs/util/ExcelDataImporter.java +++ b/src/main/java/com/xy/xyaicpzs/util/ExcelDataImporter.java @@ -33,6 +33,21 @@ import com.xy.xyaicpzs.mapper.T8Mapper; import com.xy.xyaicpzs.mapper.T11Mapper; import com.xy.xyaicpzs.mapper.LotteryDrawsMapper; import com.xy.xyaicpzs.service.T3Service; +import com.xy.xyaicpzs.service.T4Service; +import com.xy.xyaicpzs.service.T5Service; +import com.xy.xyaicpzs.service.T6Service; +import com.xy.xyaicpzs.service.T7Service; +import com.xy.xyaicpzs.service.T8Service; +import com.xy.xyaicpzs.service.T11Service; +import com.xy.xyaicpzs.service.LotteryDrawsService; +import com.xy.xyaicpzs.service.HistoryAllService; +import com.xy.xyaicpzs.service.History100Service; +import com.xy.xyaicpzs.service.HistoryTopService; +import com.xy.xyaicpzs.service.HistoryTop100Service; +import com.xy.xyaicpzs.service.BlueHistoryAllService; +import com.xy.xyaicpzs.service.BlueHistory100Service; +import com.xy.xyaicpzs.service.BlueHistoryTopService; +import com.xy.xyaicpzs.service.BlueHistoryTop100Service; import lombok.extern.slf4j.Slf4j; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; @@ -110,6 +125,51 @@ public class ExcelDataImporter { @Autowired private T3Service t3Service; + @Autowired + private T4Service t4Service; + + @Autowired + private T5Service t5Service; + + @Autowired + private T6Service t6Service; + + @Autowired + private T7Service t7Service; + + @Autowired + private T8Service t8Service; + + @Autowired + private T11Service t11Service; + + @Autowired + private LotteryDrawsService lotteryDrawsService; + + @Autowired + private HistoryAllService historyAllService; + + @Autowired + private History100Service history100Service; + + @Autowired + private HistoryTopService historyTopService; + + @Autowired + private HistoryTop100Service historyTop100Service; + + @Autowired + private BlueHistoryAllService blueHistoryAllService; + + @Autowired + private BlueHistory100Service blueHistory100Service; + + @Autowired + private BlueHistoryTopService blueHistoryTopService; + + @Autowired + private BlueHistoryTop100Service blueHistoryTop100Service; + /** * 导入Excel数据到数据库 * @param filePath Excel文件路径 @@ -161,7 +221,7 @@ public class ExcelDataImporter { log.info("开始导入T3数据(红球线系数)"); List dataList = readT3DataFromSheet(t3Sheet); if (!dataList.isEmpty()) { - // clearExistingData() is called at the beginning, so we just save. + // 批量插入 t3Service.saveBatch(dataList); log.info("成功导入{}条T3数据(红球线系数)", dataList.size()); } else { @@ -176,10 +236,14 @@ public class ExcelDataImporter { Sheet t4Sheet = workbook.getSheet("T4"); if (t4Sheet != null) { log.info("开始导入T4数据(蓝球组红球线系数)"); - - // 读取T4数据并插入到t4表 - importT4Data(t4Sheet); - + List t4DataList = readT4DataFromSheet(t4Sheet); + if (!t4DataList.isEmpty()) { + // 批量插入 + t4Service.saveBatch(t4DataList); + log.info("成功导入{}条T4数据(蓝球组红球线系数)", t4DataList.size()); + } else { + log.warn("未找到有效的T4数据"); + } log.info("T4数据(蓝球组红球线系数)导入完成"); } else { log.warn("未找到T4工作表"); @@ -188,12 +252,16 @@ public class ExcelDataImporter { // 处理T5 sheet(蓝球组蓝球线系数数据) Sheet t5Sheet = workbook.getSheet("T5"); if (t5Sheet != null) { - log.info("开始导入T5数据(蓝球组蓝球线系数)"); - - // 读取T5数据并插入到t5表 - importT5Data(t5Sheet); - - log.info("T5数据(蓝球组蓝球线系数)导入完成"); + log.info("开始导入T5数据(蓝球组蓝球的线系数)"); + List t5DataList = readT5DataFromSheet(t5Sheet); + if (!t5DataList.isEmpty()) { + // 批量插入 + t5Service.saveBatch(t5DataList); + log.info("成功导入{}条T5数据(蓝球组蓝球的线系数)", t5DataList.size()); + } else { + log.warn("未找到有效的T5数据"); + } + log.info("T5数据(蓝球组蓝球的线系数)导入完成"); } else { log.warn("未找到T5工作表"); } @@ -202,10 +270,14 @@ public class ExcelDataImporter { Sheet t6Sheet = workbook.getSheet("T6"); if (t6Sheet != null) { log.info("开始导入T6数据(红球组蓝球线系数)"); - - // 读取T6数据并插入到t6表 - importT6Data(t6Sheet); - + List t6DataList = readT6DataFromSheet(t6Sheet); + if (!t6DataList.isEmpty()) { + // 批量插入 + t6Service.saveBatch(t6DataList); + log.info("成功导入{}条T6数据(红球组蓝球线系数)", t6DataList.size()); + } else { + log.warn("未找到有效的T6数据"); + } log.info("T6数据(红球组蓝球线系数)导入完成"); } else { log.warn("未找到T6工作表"); @@ -228,10 +300,13 @@ public class ExcelDataImporter { Sheet t8Sheet = workbook.getSheet("T8"); if (t8Sheet != null) { log.info("开始导入T8数据(红球组蓝球面系数)"); - - // 读取T8数据并插入到t8表 - importT8Data(t8Sheet); - + List t8DataList = readT8DataFromSheet(t8Sheet); + if (!t8DataList.isEmpty()) { + t8Service.saveBatch(t8DataList); + log.info("成功导入{}条T8数据(红球组蓝球面系数)", t8DataList.size()); + } else { + log.warn("未找到有效的T8数据"); + } log.info("T8数据(红球组蓝球面系数)导入完成"); } else { log.warn("未找到T8工作表"); @@ -254,10 +329,13 @@ public class ExcelDataImporter { Sheet t11Sheet = workbook.getSheet("T11"); if (t11Sheet != null) { log.info("开始导入T11数据(蓝球组红球面系数)"); - - // 读取T11数据并插入到t11表 - importT11Data(t11Sheet); - + List t11DataList = readT11DataFromSheet(t11Sheet); + if (!t11DataList.isEmpty()) { + t11Service.saveBatch(t11DataList); + log.info("成功导入{}条T11数据(蓝球组红球面系数)", t11DataList.size()); + } else { + log.warn("未找到有效的T11数据"); + } log.info("T11数据(蓝球组红球面系数)导入完成"); } else { log.warn("未找到T11工作表"); @@ -423,7 +501,7 @@ public class ExcelDataImporter { // 批量插入 if (!dataList.isEmpty()) { - dataList.forEach(historyAllMapper::insert); + historyAllService.saveBatch(dataList); log.info("成功导入{}条全部历史数据", dataList.size()); } } @@ -466,7 +544,7 @@ public class ExcelDataImporter { // 批量插入 if (!dataList.isEmpty()) { - dataList.forEach(history100Mapper::insert); + history100Service.saveBatch(dataList); log.info("成功导入{}条最近100期数据", dataList.size()); } } @@ -500,7 +578,7 @@ public class ExcelDataImporter { // 批量插入 if (!dataList.isEmpty()) { - dataList.forEach(historyTopMapper::insert); + historyTopService.saveBatch(dataList); log.info("成功导入{}条历史数据排行", dataList.size()); } } @@ -534,7 +612,7 @@ public class ExcelDataImporter { // 批量插入 if (!dataList.isEmpty()) { - dataList.forEach(historyTop100Mapper::insert); + historyTop100Service.saveBatch(dataList); log.info("成功导入{}条100期数据排行", dataList.size()); } } @@ -657,7 +735,7 @@ public class ExcelDataImporter { // 批量插入 if (!dataList.isEmpty()) { - dataList.forEach(blueHistoryAllMapper::insert); + blueHistoryAllService.saveBatch(dataList); log.info("成功导入{}条蓝球全部历史数据", dataList.size()); } } @@ -700,7 +778,7 @@ public class ExcelDataImporter { // 批量插入 if (!dataList.isEmpty()) { - dataList.forEach(blueHistory100Mapper::insert); + blueHistory100Service.saveBatch(dataList); log.info("成功导入{}条蓝球最近100期数据", dataList.size()); } } @@ -734,7 +812,7 @@ public class ExcelDataImporter { // 批量插入 if (!dataList.isEmpty()) { - dataList.forEach(blueHistoryTopMapper::insert); + blueHistoryTopService.saveBatch(dataList); log.info("成功导入{}条蓝球历史数据排行", dataList.size()); } } @@ -768,7 +846,7 @@ public class ExcelDataImporter { // 批量插入 if (!dataList.isEmpty()) { - dataList.forEach(blueHistoryTop100Mapper::insert); + blueHistoryTop100Service.saveBatch(dataList); log.info("成功导入{}条蓝球100期数据排行", dataList.size()); } } @@ -832,29 +910,22 @@ public class ExcelDataImporter { // 批量插入 if (!dataList.isEmpty()) { - dataList.forEach(t3Mapper::insert); + t3Service.saveBatch(dataList); log.info("成功导入{}条T3数据(红球线系数)", dataList.size()); } else { log.warn("未找到有效的T3数据"); } } - // ==================== T4数据导入方法 ==================== + // ==================== T4数据读取方法 ==================== - /** - * 导入T4数据(蓝球组红球的线系数) - * 数据结构:每三列为一组,每组有33行数据 - * 蓝球号码范围:1-16(主球) - * 红球号码范围:1-33(从球,对应行号) - * 线系数在C、F、I、L...列 - */ - private void importT4Data(Sheet sheet) { - log.info("开始导入T4数据(蓝球组红球的线系数)..."); + public List readT4DataFromSheet(Sheet sheet) { + log.info("开始读取T4数据(蓝球组红球的线系数)..."); List dataList = new ArrayList<>(); // 获取数据行数,跳过标题行,应该有33行数据 int lastRowNum = sheet.getLastRowNum(); - + // 计算组数,每组占用3列,从A列开始 int totalCols = 0; if (lastRowNum > 0) { @@ -863,19 +934,20 @@ public class ExcelDataImporter { totalCols = firstDataRow.getLastCellNum(); } } - + int groupCount = totalCols / 3; // 每组3列 // 蓝球号码范围是1-16,所以最多16组 groupCount = Math.min(groupCount, 16); - + log.info("检测到{}组数据,共{}列,预期33行数据", groupCount, totalCols); // 遍历每组数据(蓝球1-16号) for (int group = 0; group < groupCount; group++) { int masterBallNumber = group + 1; // 蓝球号从1开始 - int lineCoefCol = group * 3 + 2; // 线系数列:2,5,8,11...(C,F,I,L列) - - log.info("处理第{}组数据(蓝球{}号),线系数列位置:{}", group + 1, masterBallNumber, lineCoefCol); + int slaveBallCol = group * 3 + 1; // 从球号列:B,E,H,... + int lineCoefCol = group * 3 + 2; // 线系数列:C,F,I,... + + log.info("处理第{}组数据(蓝球{}号),从球号列:{},线系数列位置:{}", group + 1, masterBallNumber, slaveBallCol, lineCoefCol); // 遍历33行数据(红球1-33号,跳过标题行) for (int i = 1; i <= lastRowNum && i <= 33; i++) { @@ -884,175 +956,29 @@ public class ExcelDataImporter { T4 entity = new T4(); entity.setMasterBallNumber(masterBallNumber); // 蓝球号 - - // 从球号固定为行号(红球1-33) - Integer slaveBallNumber = i; - - // 线系数(从对应组的第三列读取) + + // 从对应组的第一列读取从球号 + Double slaveBallDouble = getCellNumericValue(row.getCell(slaveBallCol)); + Integer slaveBallNumber = (slaveBallDouble != null) ? slaveBallDouble.intValue() : null; + + // 线系数(从对应组的第二列读取) Double lineCoefficient = getCellNumericValue(row.getCell(lineCoefCol)); - if (lineCoefficient != null) { + if (slaveBallNumber != null && lineCoefficient != null) { entity.setSlaveBallNumber(slaveBallNumber); entity.setLineCoefficient(roundToTwoDecimalPlaces(lineCoefficient)); dataList.add(entity); } else { - log.warn("第{}组第{}行线系数为空,跳过", group + 1, i); + log.warn("第{}组第{}行从球号或线系数为空,跳过", group + 1, i); } } } - - // 批量插入 - if (!dataList.isEmpty()) { - dataList.forEach(t4Mapper::insert); - log.info("成功导入{}条T4数据(蓝球组红球的线系数)", dataList.size()); - log.info("预期数据量:16个蓝球 × 33个红球 = 528条记录"); - } else { - log.warn("未找到有效的T4数据"); - } + return dataList; } - // ==================== T5数据导入方法 ==================== + // ==================== T5数据读取方法 ==================== - /** - * 导入T5数据(蓝球组蓝球的线系数) - * 数据结构:每三列为一组,每组有16行数据 - * 蓝球号码范围:1-16(主球和从球都是) - * 线系数在C、F、I、L...列 - */ - private void importT5Data(Sheet sheet) { - log.info("开始导入T5数据(蓝球组蓝球的线系数)..."); - List dataList = new ArrayList<>(); - - // 获取数据行数,跳过标题行,应该有16行数据 - int lastRowNum = sheet.getLastRowNum(); - - // 计算组数,每组占用3列,从A列开始 - int totalCols = 0; - if (lastRowNum > 0) { - Row firstDataRow = sheet.getRow(1); - if (firstDataRow != null) { - totalCols = firstDataRow.getLastCellNum(); - } - } - - int groupCount = totalCols / 3; // 每组3列 - // 蓝球号码范围是1-16,所以最多16组 - groupCount = Math.min(groupCount, 16); - - log.info("检测到{}组数据,共{}列,预期16行数据", groupCount, totalCols); - - // 遍历每组数据(蓝球1-16号) - for (int group = 0; group < groupCount; group++) { - int masterBallNumber = group + 1; // 主蓝球号从1开始 - int lineCoefCol = group * 3 + 2; // 线系数列:2,5,8,11...(C,F,I,L列) - - log.info("处理第{}组数据(主蓝球{}号),线系数列位置:{}", group + 1, masterBallNumber, lineCoefCol); - - // 遍历16行数据(从蓝球1-16号,跳过标题行) - for (int i = 1; i <= lastRowNum && i <= 16; i++) { - Row row = sheet.getRow(i); - if (row == null) continue; - - T5 entity = new T5(); - entity.setMasterBallNumber(masterBallNumber); // 主蓝球号 - - // 从球号固定为行号(从蓝球1-16) - Integer slaveBallNumber = i; - - // 线系数(从对应组的第三列读取) - Double lineCoefficient = getCellNumericValue(row.getCell(lineCoefCol)); - - if (lineCoefficient != null) { - entity.setSlaveBallNumber(slaveBallNumber); - entity.setLineCoefficient(roundToTwoDecimalPlaces(lineCoefficient)); - dataList.add(entity); - } else { - log.warn("第{}组第{}行线系数为空,跳过", group + 1, i); - } - } - } - - // 批量插入 - if (!dataList.isEmpty()) { - dataList.forEach(t5Mapper::insert); - log.info("成功导入{}条T5数据(蓝球组蓝球的线系数)", dataList.size()); - log.info("预期数据量:16个蓝球 × 16个蓝球 = 256条记录"); - } else { - log.warn("未找到有效的T5数据"); - } - } - - // ==================== T6数据导入方法 ==================== - - /** - * 导入T6数据(红球组蓝球的线系数) - * 数据结构:每三列为一组,每组有16行数据 - * 红球号码范围:1-33(主球) - * 蓝球号码范围:1-16(从球) - * 线系数在C、F、I、L...列 - */ - private void importT6Data(Sheet sheet) { - log.info("开始导入T6数据(红球组蓝球的线系数)..."); - List dataList = new ArrayList<>(); - - // 获取数据行数,跳过标题行,应该有16行数据 - int lastRowNum = sheet.getLastRowNum(); - - // 计算组数,每组占用3列,从A列开始 - int totalCols = 0; - if (lastRowNum > 0) { - Row firstDataRow = sheet.getRow(1); - if (firstDataRow != null) { - totalCols = firstDataRow.getLastCellNum(); - } - } - - int groupCount = totalCols / 3; // 每组3列 - // 红球号码范围是1-33,所以最多33组 - groupCount = Math.min(groupCount, 33); - - log.info("检测到{}组数据,共{}列,预期16行数据", groupCount, totalCols); - - // 遍历每组数据(红球1-33号) - for (int group = 0; group < groupCount; group++) { - int masterBallNumber = group + 1; // 主红球号从1开始 - int lineCoefCol = group * 3 + 2; // 线系数列:2,5,8,11...(C,F,I,L列) - - log.info("处理第{}组数据(主红球{}号),线系数列位置:{}", group + 1, masterBallNumber, lineCoefCol); - - // 遍历16行数据(从蓝球1-16号,跳过标题行) - for (int i = 1; i <= lastRowNum && i <= 16; i++) { - Row row = sheet.getRow(i); - if (row == null) continue; - - T6 entity = new T6(); - entity.setMasterBallNumber(masterBallNumber); // 主红球号 - - // 从球号固定为行号(从蓝球1-16) - Integer slaveBallNumber = i; - - // 线系数(从对应组的第三列读取) - Double lineCoefficient = getCellNumericValue(row.getCell(lineCoefCol)); - - if (lineCoefficient != null) { - entity.setSlaveBallNumber(slaveBallNumber); - entity.setLineCoefficient(roundToTwoDecimalPlaces(lineCoefficient)); - dataList.add(entity); - } else { - log.warn("第{}组第{}行线系数为空,跳过", group + 1, i); - } - } - } - - // 批量插入 - if (!dataList.isEmpty()) { - dataList.forEach(t6Mapper::insert); - log.info("成功导入{}条T6数据(红球组蓝球的线系数)", dataList.size()); - log.info("预期数据量:33个红球 × 16个蓝球 = 528条记录"); - } else { - log.warn("未找到有效的T6数据"); - } - } + // ==================== T6数据读取方法 ==================== // ==================== T7数据导入方法 ==================== @@ -1155,7 +1081,7 @@ public class ExcelDataImporter { // 批量插入 if (!dataList.isEmpty()) { - dataList.forEach(t7Mapper::insert); + t7Service.saveBatch(dataList); log.info("成功导入{}条T7数据(红球组红球的面系数)", dataList.size()); log.info("预期数据量:33个红球 × 32个红球(排除自己) = 1056条记录"); @@ -1241,149 +1167,9 @@ public class ExcelDataImporter { } } - // ==================== T8数据导入方法 ==================== + // ==================== T8数据读取方法 ==================== - /** - * 导入T8数据(红球组蓝球的面系数) - * 数据结构:每三列为一组,每组有16行数据 - * 红球号码范围:1-33(主球) - * 蓝球号码范围:1-16(从球) - * 面系数在C、F、I、L...列 - */ - private void importT8Data(Sheet sheet) { - log.info("开始导入T8数据(红球组蓝球的面系数)..."); - List dataList = new ArrayList<>(); - - // 获取数据行数,跳过标题行,应该有16行数据 - int lastRowNum = sheet.getLastRowNum(); - - // 计算组数,每组占用3列,从A列开始 - int totalCols = 0; - if (lastRowNum > 0) { - Row firstDataRow = sheet.getRow(1); - if (firstDataRow != null) { - totalCols = firstDataRow.getLastCellNum(); - } - } - - int groupCount = totalCols / 3; // 每组3列 - // 红球号码范围是1-33,所以最多33组 - groupCount = Math.min(groupCount, 33); - - log.info("检测到{}组数据,共{}列,预期16行数据", groupCount, totalCols); - - // 遍历每组数据(红球1-33号) - for (int group = 0; group < groupCount; group++) { - int masterBallNumber = group + 1; // 主红球号从1开始 - int faceCoefCol = group * 3 + 2; // 面系数列:2,5,8,11...(C,F,I,L列) - - log.info("处理第{}组数据(主红球{}号),面系数列位置:{}", group + 1, masterBallNumber, faceCoefCol); - - // 遍历16行数据(从蓝球1-16号,跳过标题行) - for (int i = 1; i <= lastRowNum && i <= 16; i++) { - Row row = sheet.getRow(i); - if (row == null) continue; - - T8 entity = new T8(); - entity.setMasterBallNumber(masterBallNumber); // 主红球号 - - // 从球号固定为行号(从蓝球1-16) - Integer slaveBallNumber = i; - - // 面系数(从对应组的第三列读取) - Double faceCoefficient = getCellNumericValue(row.getCell(faceCoefCol)); - - if (faceCoefficient != null) { - entity.setSlaveBallNumber(slaveBallNumber); - entity.setFaceCoefficient(roundToTwoDecimalPlaces(faceCoefficient)); - dataList.add(entity); - } else { - log.warn("第{}组第{}行面系数为空,跳过", group + 1, i); - } - } - } - - // 批量插入 - if (!dataList.isEmpty()) { - dataList.forEach(t8Mapper::insert); - log.info("成功导入{}条T8数据(红球组蓝球的面系数)", dataList.size()); - log.info("预期数据量:33个红球 × 16个蓝球 = 528条记录"); - } else { - log.warn("未找到有效的T8数据"); - } - } - - // ==================== T11数据导入方法 ==================== - - /** - * 导入T11数据(蓝球组红球的面系数) - * 数据结构:每三列为一组,每组有33行数据 - * 蓝球号码范围:1-16(主球) - * 红球号码范围:1-33(从球) - * 面系数在C、F、I、L...列 - */ - private void importT11Data(Sheet sheet) { - log.info("开始导入T11数据(蓝球组红球的面系数)..."); - List dataList = new ArrayList<>(); - - // 获取数据行数,跳过标题行,应该有33行数据 - int lastRowNum = sheet.getLastRowNum(); - - // 计算组数,每组占用3列,从A列开始 - int totalCols = 0; - if (lastRowNum > 0) { - Row firstDataRow = sheet.getRow(1); - if (firstDataRow != null) { - totalCols = firstDataRow.getLastCellNum(); - } - } - - int groupCount = totalCols / 3; // 每组3列 - // 蓝球号码范围是1-16,所以最多16组 - groupCount = Math.min(groupCount, 16); - - log.info("检测到{}组数据,共{}列,预期33行数据", groupCount, totalCols); - - // 遍历每组数据(蓝球1-16号) - for (int group = 0; group < groupCount; group++) { - int masterBallNumber = group + 1; // 蓝球号从1开始 - int faceCoefCol = group * 3 + 2; // 面系数列:2,5,8,11...(C,F,I,L列) - - log.info("处理第{}组数据(蓝球{}号),面系数列位置:{}", group + 1, masterBallNumber, faceCoefCol); - - // 遍历33行数据(红球1-33号,跳过标题行) - for (int i = 1; i <= lastRowNum && i <= 33; i++) { - Row row = sheet.getRow(i); - if (row == null) continue; - - T11 entity = new T11(); - entity.setMasterBallNumber(masterBallNumber); // 蓝球号 - - // 从球号固定为行号(红球1-33) - Integer slaveBallNumber = i; - - // 面系数(从对应组的第三列读取) - Double faceCoefficient = getCellNumericValue(row.getCell(faceCoefCol)); - - if (faceCoefficient != null) { - entity.setSlaveBallNumber(slaveBallNumber); - entity.setFaceCoefficient(roundToTwoDecimalPlaces(faceCoefficient)); - dataList.add(entity); - } else { - log.warn("第{}组第{}行面系数为空,跳过", group + 1, i); - } - } - } - - // 批量插入 - if (!dataList.isEmpty()) { - dataList.forEach(t11Mapper::insert); - log.info("成功导入{}条T11数据(蓝球组红球的面系数)", dataList.size()); - log.info("预期数据量:16个蓝球 × 33个红球 = 528条记录"); - } else { - log.warn("未找到有效的T11数据"); - } - } + // ==================== T11数据读取方法 ==================== // ==================== T10数据导入方法 ==================== @@ -1462,7 +1248,7 @@ public class ExcelDataImporter { // 批量插入 if (!dataList.isEmpty()) { - dataList.forEach(lotteryDrawsMapper::insert); + lotteryDrawsService.saveBatch(dataList); log.info("成功导入{}条T10数据(彩票开奖信息)", dataList.size()); } else { log.warn("未找到有效的T10数据"); @@ -1650,7 +1436,7 @@ public class ExcelDataImporter { // 批量插入新数据 if (!dataList.isEmpty()) { - dataList.forEach(lotteryDrawsMapper::insert); + lotteryDrawsService.saveBatch(dataList); log.info("成功追加导入{}条新的T10数据(彩票开奖信息)", dataList.size()); } else { log.info("没有新的T10数据需要导入"); @@ -1734,4 +1520,252 @@ public class ExcelDataImporter { } return dataList; } -} \ No newline at end of file + + /** + * 从Sheet中读取T6数据(红球组蓝球的线系数) + * @param sheet Excel工作表 + * @return T6数据列表 + */ + public List readT6DataFromSheet(Sheet sheet) { + log.info("开始读取T6数据(红球组蓝球的线系数)..."); + List dataList = new ArrayList<>(); + + // 获取数据行数,跳过标题行,应该有16行数据 + int lastRowNum = sheet.getLastRowNum(); + + // 计算组数,每组占用3列,从A列开始 + int totalCols = 0; + if (lastRowNum > 0) { + Row firstDataRow = sheet.getRow(1); + if (firstDataRow != null) { + totalCols = firstDataRow.getLastCellNum(); + } + } + + int groupCount = totalCols / 3; // 每组3列 + // 红球号码范围是1-33,所以最多33组 + groupCount = Math.min(groupCount, 33); + + log.info("检测到{}组数据,共{}列,预期16行数据", groupCount, totalCols); + + // 遍历每组数据(红球1-33号) + for (int group = 0; group < groupCount; group++) { + int masterBallNumber = group + 1; // 主红球号从1开始 + int slaveBallCol = group * 3 + 1; // 从球号列:B,E,H,... + int lineCoefCol = group * 3 + 2; // 线系数列:C,F,I,... + + log.info("处理第{}组数据(主红球{}号),从球号列:{},线系数列位置:{}", group + 1, masterBallNumber, slaveBallCol, lineCoefCol); + + // 遍历16行数据(从蓝球1-16号,跳过标题行) + for (int i = 1; i <= lastRowNum && i <= 16; i++) { + Row row = sheet.getRow(i); + if (row == null) continue; + + T6 entity = new T6(); + entity.setMasterBallNumber(masterBallNumber); // 主红球号 + + // 从对应组的第一列读取从球号 + Double slaveBallDouble = getCellNumericValue(row.getCell(slaveBallCol)); + Integer slaveBallNumber = (slaveBallDouble != null) ? slaveBallDouble.intValue() : null; + + // 线系数(从对应组的第二列读取) + Double lineCoefficient = getCellNumericValue(row.getCell(lineCoefCol)); + + if (slaveBallNumber != null && lineCoefficient != null) { + entity.setSlaveBallNumber(slaveBallNumber); + entity.setLineCoefficient(roundToTwoDecimalPlaces(lineCoefficient)); + dataList.add(entity); + } else { + log.warn("第{}组第{}行从球号或线系数为空,跳过", group + 1, i); + } + } + } + return dataList; + } + + /** + * 从Sheet中读取T8数据(红球组蓝球的面系数) + * @param sheet Excel工作表 + * @return T8数据列表 + */ + public List readT8DataFromSheet(Sheet sheet) { + log.info("开始读取T8数据(红球组蓝球的面系数)..."); + List dataList = new ArrayList<>(); + + // 获取数据行数,跳过标题行,应该有16行数据 + int lastRowNum = sheet.getLastRowNum(); + + // 计算组数,每组占用3列,从A列开始 + int totalCols = 0; + if (lastRowNum > 0) { + Row firstDataRow = sheet.getRow(1); + if (firstDataRow != null) { + totalCols = firstDataRow.getLastCellNum(); + } + } + + int groupCount = totalCols / 3; // 每组3列 + // 红球号码范围是1-33,所以最多33组 + groupCount = Math.min(groupCount, 33); + + log.info("检测到{}组数据,共{}列,预期16行数据", groupCount, totalCols); + + // 遍历每组数据(红球1-33号) + for (int group = 0; group < groupCount; group++) { + int masterBallNumber = group + 1; // 主红球号从1开始 + int slaveBallCol = group * 3 + 1; // 从球号列:B,E,H,... + int faceCoefCol = group * 3 + 2; // 面系数列:C,F,I,... + + log.info("处理第{}组数据(主红球{}号),从球号列:{},面系数列位置:{}", group + 1, masterBallNumber, slaveBallCol, faceCoefCol); + + // 遍历16行数据(从蓝球1-16号,跳过标题行) + for (int i = 1; i <= lastRowNum && i <= 16; i++) { + Row row = sheet.getRow(i); + if (row == null) continue; + + T8 entity = new T8(); + entity.setMasterBallNumber(masterBallNumber); // 主红球号 + + // 从对应组的第一列读取从球号 + Double slaveBallDouble = getCellNumericValue(row.getCell(slaveBallCol)); + Integer slaveBallNumber = (slaveBallDouble != null) ? slaveBallDouble.intValue() : null; + + // 面系数(从对应组的第二列读取) + Double faceCoefficient = getCellNumericValue(row.getCell(faceCoefCol)); + + if (slaveBallNumber != null && faceCoefficient != null) { + entity.setSlaveBallNumber(slaveBallNumber); + entity.setFaceCoefficient(roundToTwoDecimalPlaces(faceCoefficient)); + dataList.add(entity); + } else { + log.warn("第{}组第{}行从球号或面系数为空,跳过", group + 1, i); + } + } + } + return dataList; + } + + /** + * 从Sheet中读取T11数据(蓝球组红球的面系数) + * @param sheet Excel工作表 + * @return T11数据列表 + */ + public List readT11DataFromSheet(Sheet sheet) { + log.info("开始读取T11数据(蓝球组红球的面系数)..."); + List dataList = new ArrayList<>(); + + // 获取数据行数,跳过标题行,应该有33行数据 + int lastRowNum = sheet.getLastRowNum(); + + // 计算组数,每组占用3列,从A列开始 + int totalCols = 0; + if (lastRowNum > 0) { + Row firstDataRow = sheet.getRow(1); + if (firstDataRow != null) { + totalCols = firstDataRow.getLastCellNum(); + } + } + + int groupCount = totalCols / 3; // 每组3列 + // 蓝球号码范围是1-16,所以最多16组 + groupCount = Math.min(groupCount, 16); + + log.info("检测到{}组数据,共{}列,预期33行数据", groupCount, totalCols); + + // 遍历每组数据(蓝球1-16号) + for (int group = 0; group < groupCount; group++) { + int masterBallNumber = group + 1; // 蓝球号从1开始 + int slaveBallCol = group * 3 + 1; // 从球号列:B,E,H,... + int faceCoefCol = group * 3 + 2; // 面系数列:C,F,I,... + + log.info("处理第{}组数据(蓝球{}号),从球号列:{},面系数列位置:{}", group + 1, masterBallNumber, slaveBallCol, faceCoefCol); + + // 遍历33行数据(红球1-33号,跳过标题行) + for (int i = 1; i <= lastRowNum && i <= 33; i++) { + Row row = sheet.getRow(i); + if (row == null) continue; + + T11 entity = new T11(); + entity.setMasterBallNumber(masterBallNumber); // 蓝球号 + + // 从对应组的第一列读取从球号 + Double slaveBallDouble = getCellNumericValue(row.getCell(slaveBallCol)); + Integer slaveBallNumber = (slaveBallDouble != null) ? slaveBallDouble.intValue() : null; + + // 面系数(从对应组的第二列读取) + Double faceCoefficient = getCellNumericValue(row.getCell(faceCoefCol)); + + if (slaveBallNumber != null && faceCoefficient != null) { + entity.setSlaveBallNumber(slaveBallNumber); + entity.setFaceCoefficient(roundToTwoDecimalPlaces(faceCoefficient)); + dataList.add(entity); + } else { + log.warn("第{}组第{}行从球号或面系数为空,跳过", group + 1, i); + } + } + } + return dataList; + } + + /** + * 从Sheet中读取T5数据(蓝球组蓝球的线系数) + * @param sheet Excel工作表 + * @return T5数据列表 + */ + public List readT5DataFromSheet(Sheet sheet) { + log.info("开始读取T5数据(蓝球组蓝球的线系数)..."); + List dataList = new ArrayList<>(); + + // 获取数据行数,跳过标题行,应该有16行数据 + int lastRowNum = sheet.getLastRowNum(); + + // 计算组数,每组占用3列,从A列开始 + int totalCols = 0; + if (lastRowNum > 0) { + Row firstDataRow = sheet.getRow(1); + if (firstDataRow != null) { + totalCols = firstDataRow.getLastCellNum(); + } + } + + int groupCount = totalCols / 3; // 每组3列 + // 蓝球号码范围是1-16,所以最多16组 + groupCount = Math.min(groupCount, 16); + + log.info("检测到{}组数据,共{}列,预期16行数据", groupCount, totalCols); + + // 遍历每组数据(蓝球1-16号) + for (int group = 0; group < groupCount; group++) { + int masterBallNumber = group + 1; // 主蓝球号从1开始 + int slaveBallCol = group * 3 + 1; // 从球号列:B,E,H,... + int lineCoefCol = group * 3 + 2; // 线系数列:C,F,I,... + + log.info("处理第{}组数据(主蓝球{}号),从球号列:{},线系数列位置:{}", group + 1, masterBallNumber, slaveBallCol, lineCoefCol); + + // 遍历16行数据(从蓝球1-16号,跳过标题行) + for (int i = 1; i <= lastRowNum && i <= 16; i++) { + Row row = sheet.getRow(i); + if (row == null) continue; + + T5 entity = new T5(); + entity.setMasterBallNumber(masterBallNumber); // 主蓝球号 + + // 从对应组的第一列读取从球号 + Double slaveBallDouble = getCellNumericValue(row.getCell(slaveBallCol)); + Integer slaveBallNumber = (slaveBallDouble != null) ? slaveBallDouble.intValue() : null; + + // 线系数(从对应组的第二列读取) + Double lineCoefficient = getCellNumericValue(row.getCell(lineCoefCol)); + + if (slaveBallNumber != null && lineCoefficient != null) { + entity.setSlaveBallNumber(slaveBallNumber); + entity.setLineCoefficient(roundToTwoDecimalPlaces(lineCoefficient)); + dataList.add(entity); + } else { + log.warn("第{}组第{}行从球号或线系数为空,跳过", group + 1, i); + } + } + } + return dataList; + } +} \ No newline at end of file