diff --git a/PyModel/save_valid_bet_data_sqlite.py b/PyModel/save_valid_bet_data_sqlite.py new file mode 100644 index 0000000..131c363 --- /dev/null +++ b/PyModel/save_valid_bet_data_sqlite.py @@ -0,0 +1,122 @@ +import json +import sqlite3 +import os + +# 获取当前脚本所在目录 +script_dir = os.path.dirname(os.path.abspath(__file__)) + +# 定义JSON文件路径 +json_file_path = os.path.join(script_dir, 'data_test_predict', 'betting_predictions_final_1_20.json') + +# 定义SQLite数据库路径 +db_path = os.path.join(script_dir, 'bet_records.db') + +# 确保目录存在 +os.makedirs(os.path.join(script_dir, 'data_test_predict'), exist_ok=True) + +def create_table(): + """创建SQLite表""" + conn = sqlite3.connect(db_path) + cursor = conn.cursor() + + # 创建bet_records表,包含id、bet_time和bet_data字段 + cursor.execute(''' + CREATE TABLE IF NOT EXISTS bet_records ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + bet_time TEXT NOT NULL, + bet_data TEXT NOT NULL + ) + ''') + + conn.commit() + conn.close() + print("SQLite表创建成功") + +def process_bet_data(): + """处理投注数据并保存到SQLite""" + try: + # 读取JSON文件 + with open(json_file_path, 'r', encoding='utf-8') as f: + bet_data_array = json.load(f) + + print(f"成功读取投注预测数据,共{len(bet_data_array)}条记录") + + # 连接SQLite数据库 + conn = sqlite3.connect(db_path) + cursor = conn.cursor() + + # 处理每条投注数据 + for i, bet_data in enumerate(bet_data_array): + bet_time = bet_data.get('time', '') + result = bet_data.get('result', {}) + + print(f"处理投注时间: {bet_time}") + + # 提取有效投注数据(result中值不为null的对象) + valid_bet_data = {} + for pos, pos_data in result.items(): + for num, value in pos_data.items(): + if value is not None: + if pos not in valid_bet_data: + valid_bet_data[pos] = {} + valid_bet_data[pos][num] = value + + # 将有效投注数据转换为JSON字符串 + bet_data_json = json.dumps(valid_bet_data, ensure_ascii=False) + + # 插入数据到SQLite表 + cursor.execute( + "INSERT INTO bet_records (bet_time, bet_data) VALUES (?, ?)", + (bet_time, bet_data_json) + ) + + print(f" - 有效投注数据: {bet_data_json}") + + # 提交事务 + conn.commit() + print(f"成功保存{len(bet_data_array)}条投注记录到SQLite数据库") + + except FileNotFoundError: + print(f"错误: JSON文件不存在 - {json_file_path}") + except json.JSONDecodeError: + print("错误: JSON文件格式不正确") + except Exception as e: + print(f"错误: {str(e)}") + finally: + if 'conn' in locals(): + conn.close() + +def verify_data(): + """验证数据是否成功保存""" + try: + conn = sqlite3.connect(db_path) + cursor = conn.cursor() + + # 查询记录数 + cursor.execute("SELECT COUNT(*) FROM bet_records") + count = cursor.fetchone()[0] + print(f"SQLite数据库中共有{count}条投注记录") + + # 查询前5条记录 + cursor.execute("SELECT id, bet_time, bet_data FROM bet_records LIMIT 5") + records = cursor.fetchall() + + print("前5条记录:") + for record in records: + print(f"ID: {record[0]}") + print(f"投注时间: {record[1]}") + print(f"投注数据: {record[2]}") + print("-" * 50) + + except Exception as e: + print(f"验证数据时出错: {str(e)}") + finally: + if 'conn' in locals(): + conn.close() + +if __name__ == "__main__": + print("开始处理投注数据并保存到SQLite数据库...") + create_table() + process_bet_data() + verify_data() + print("处理完成") diff --git a/PyModel/test.json b/PyModel/test.json new file mode 100644 index 0000000..d8c1d34 --- /dev/null +++ b/PyModel/test.json @@ -0,0 +1,22 @@ +{ + "lottery": "SGFT", + "drawNumber": "20260126174", + "bets": [ + { + "game": "B2", + "contents": "4", + "amount": 1, + "odds": 9.599, + "title": "亚军" + }, + { + "game": "B8", + "contents": "3", + "amount": 1, + "odds": 9.599, + "title": "第八名" + } + ], + "fastBets": false, + "ignore": false +} \ No newline at end of file diff --git a/bocai.db b/bocai.db index c8a7079..8f9a501 100644 Binary files a/bocai.db and b/bocai.db differ diff --git a/bocai.db-journal b/bocai.db-journal new file mode 100644 index 0000000..7ca60eb Binary files /dev/null and b/bocai.db-journal differ diff --git a/src/main/java/com/tem/bocai/entity/BetRecord.java b/src/main/java/com/tem/bocai/entity/BetRecord.java new file mode 100644 index 0000000..1d47410 --- /dev/null +++ b/src/main/java/com/tem/bocai/entity/BetRecord.java @@ -0,0 +1,30 @@ +package com.tem.bocai.entity; + +import jakarta.persistence.*; +import lombok.Data; + +import java.util.Date; + +@Entity +@Data +@Table(name = "bet_records") +public class BetRecord { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "bet_time") + private String betTime; + + @Column(name = "bet_data", columnDefinition = "TEXT") + private String betData; + + @Column(name = "create_time") + private Date createTime; + + @Column(name = "update_time") + private Date updateTime; + + @Column(name = "bet_num") + private Integer betNum; +} diff --git a/src/main/java/com/tem/bocai/repository/BetRecordRepository.java b/src/main/java/com/tem/bocai/repository/BetRecordRepository.java new file mode 100644 index 0000000..408aa24 --- /dev/null +++ b/src/main/java/com/tem/bocai/repository/BetRecordRepository.java @@ -0,0 +1,9 @@ +package com.tem.bocai.repository; + +import com.tem.bocai.entity.BetRecord; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface BetRecordRepository extends JpaRepository { +} diff --git a/src/main/java/com/tem/bocai/schedules/BetSchedule.java b/src/main/java/com/tem/bocai/schedules/BetSchedule.java index e4ce7d7..08e6dfc 100644 --- a/src/main/java/com/tem/bocai/schedules/BetSchedule.java +++ b/src/main/java/com/tem/bocai/schedules/BetSchedule.java @@ -152,18 +152,22 @@ public class BetSchedule { }); System.out.println(" - 投注号码: " + betNumbers.toString()); + // 生成betNum (年月日+001-288) + Integer betNum = generateBetNum(); + System.out.println(" - 投注编号: " + betNum); + // 计算投注金额 double betAmount = loginInfo.getAmount(); // 固定投注金额 System.out.println(" - 投注金额: " + betAmount); // 调用投注接口 System.out.println(" - 提交投注..."); - String betResult = callBetApi(betNumbers, betAmount, loginInfo); + String betResult = callBetApi(betNumbers, loginInfo); System.out.println(" - 投注结果: " + betResult); // 记录投注结果 System.out.println(" - 记录投注结果..."); - recordBetResult(betNumbers, betAmount, betResult); + recordBetResult(betNumbers, betAmount, betResult, betNum); } } catch (Exception e) { @@ -171,6 +175,22 @@ public class BetSchedule { e.printStackTrace(); } } + + /** + * 生成betNum,格式为年月日+001-288 + */ + private Integer generateBetNum() { + // 获取当前日期,格式为YYYYMMDD + String dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")); + + // 生成001-288的序号 + int seq = (int) (Math.random() * 288) + 1; + String seqStr = String.format("%03d", seq); + + // 组合成betNum + String betNumStr = dateStr + seqStr; + return Integer.parseInt(betNumStr); + } /** * 从json文件中读取投注数据 @@ -192,14 +212,14 @@ public class BetSchedule { /** * 调用投注接口 */ - private String callBetApi(JSONArray betNumbers, double betAmount, LoginInfoResult loginInfo) throws IOException, InterruptedException { + private String callBetApi(JSONArray betNumbers, LoginInfoResult loginInfo) throws IOException, InterruptedException { // 假设投注接口地址为http://localhost:8080/api/bet String apiUrl = "https://4701268539-esh.qdk63ayw8g.com/member/bet"; // 构建请求体 JSONObject requestBody = new JSONObject(); requestBody.put("lottery", "SGFT"); - requestBody.put("drawNumber", betAmount); + requestBody.put("drawNumber", 0); requestBody.put("fastBets", false); requestBody.put("ignore", false); requestBody.put("bets", betNumbers); @@ -231,10 +251,10 @@ public class BetSchedule { /** * 记录投注结果 */ - private void recordBetResult(JSONArray betNumbers, double betAmount, String betResult) { + private void recordBetResult(JSONArray betNumbers, double betAmount, String betResult, Integer betNum) { // 这里可以实现将投注结果记录到数据库或日志文件的逻辑 // 为了简单起见,我们这里只打印日志 String currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); - System.out.println(" - 投注记录: [" + currentTime + "] 号码: " + betNumbers.toString() + ", 金额: " + betAmount + ", 结果: " + betResult); + System.out.println(" - 投注记录: [" + currentTime + "] 号码: " + betNumbers.toString() + ", 金额: " + betAmount + ", 结果: " + betResult + ", 编号: " + betNum); } } diff --git a/src/main/java/com/tem/bocai/schedules/GenBetRecordSchedule.java b/src/main/java/com/tem/bocai/schedules/GenBetRecordSchedule.java new file mode 100644 index 0000000..393d348 --- /dev/null +++ b/src/main/java/com/tem/bocai/schedules/GenBetRecordSchedule.java @@ -0,0 +1,180 @@ +package com.tem.bocai.schedules; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.io.FileReader; +import java.io.IOException; +import java.io.FileWriter; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Date; + +import com.tem.bocai.entity.BetRecord; +import com.tem.bocai.repository.BetRecordRepository; + +import org.json.JSONArray; +import org.json.JSONObject; +import org.json.JSONTokener; + +@Component +public class GenBetRecordSchedule { + + @Autowired + private BetRecordRepository betRecordRepository; + + public static void main(String[] args) { + GenBetRecordSchedule genBetRecordSchedule = new GenBetRecordSchedule(); + genBetRecordSchedule.processBetPredictions(); + } + + // 每天00:01执行 + @Scheduled(cron = "0 1 00 * * ?") + // @Scheduled(cron = "0 * * * * ?") + public void processBetPredictions() { + LocalDateTime now = LocalDateTime.now(); + String currentTime = now.format( + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") + ); + System.out.println(currentTime + " - 开始处理投注预测数据..."); + + try { + // 读取投注预测数据 + JSONArray betDataArray = readBetDataFromJson(); + System.out.println(" - 成功读取投注预测数据,共" + betDataArray.length() + "条记录"); + + // 处理每条投注预测数据 + for (int i = 0; i < betDataArray.length(); i++) { + JSONObject betData = betDataArray.getJSONObject(i); + String time = betData.getString("time"); + System.out.println(" - 处理投注时间: " + time); + + // 获取result中值不为null的对象 + JSONObject result = betData.getJSONObject("result"); + + // 生成符合test.json格式的数据 + JSONObject outputData = generateOutputData(betData, result); + + // 打印处理结果 + System.out.println(" - 生成的投注数据: " + outputData.toString()); + + // 保存处理结果到数据库 + saveToDatabase(outputData, time); + } + + System.out.println(currentTime + " - 投注预测数据处理完成"); + + } catch (Exception e) { + System.err.println(currentTime + " - 处理投注预测数据失败:"); + e.printStackTrace(); + } + } + + /** + * 生成符合test.json格式的数据 + */ + private JSONObject generateOutputData(JSONObject betData, JSONObject result) { + JSONObject outputData = new JSONObject(); + + // 设置固定字段 + outputData.put("lottery", "SGFT"); + + // 生成drawNumber: 年份月份日期序号 + String id = betData.getString("id"); + outputData.put("drawNumber", id); + + // 生成bets数组 + JSONArray betsArray = new JSONArray(); + + // 位置标题映射 + String[] titles = {"冠军", "亚军", "季军", "第四名", "第五名", "第六名", "第七名", "第八名", "第九名", "第十名"}; + + for (String pos : result.keySet()) { + JSONObject posData = result.getJSONObject(pos); + for (String num : posData.keySet()) { + Object value = posData.get(num); + if (value != null && !"null".equals(value.toString())) { + JSONObject betObject = new JSONObject(); + + // 生成game字段: "B" + 位置 + int position = Integer.parseInt(pos); + betObject.put("game", "B" + (position + 1)); + + // 设置投注内容 + betObject.put("contents", num); + + // 设置固定字段 + betObject.put("amount", 1); + betObject.put("odds", 9.599); + + // 设置标题 + if (position >= 0 && position < titles.length) { + betObject.put("title", titles[position]); + } else { + betObject.put("title", "位置" + (position + 1)); + } + + betsArray.put(betObject); + } + } + } + + outputData.put("bets", betsArray); + outputData.put("fastBets", false); + outputData.put("ignore", false); + + return outputData; + } + + /** + * 从json文件中读取投注预测数据 + */ + private JSONArray readBetDataFromJson() throws IOException { + // 使用绝对路径读取文件 + String projectRoot = System.getProperty("user.dir"); + String filePath = projectRoot + "/PyModel/data_test_predict/betting_predictions_final_1_20.json"; + System.out.println(" - 读取投注预测数据文件: " + filePath); + + FileReader reader = new FileReader(filePath); + JSONTokener tokener = new JSONTokener(reader); + JSONArray betData = new JSONArray(tokener); + reader.close(); + return betData; + } + + /** + * 保存有效投注结果到文件 + */ + private void saveValidResults(JSONObject validResults, String time) throws IOException { + // 使用绝对路径保存文件 + String projectRoot = System.getProperty("user.dir"); + String filePath = projectRoot + "/PyModel/bet_output_" + time.replace(":", "-") + ".json"; + System.out.println(" - 保存有效投注结果到文件: " + filePath); + + FileWriter writer = new FileWriter(filePath); + writer.write(validResults.toString(2)); // 格式化输出,缩进2个空格 + writer.close(); + } + + /** + * 保存有效投注结果到数据库 + */ + private void saveToDatabase(JSONObject validResults, String time) { + try { + // 创建BetRecord实体 + BetRecord betRecord = new BetRecord(); + betRecord.setBetTime(time); + betRecord.setBetData(validResults.toString()); + betRecord.setCreateTime(new Date()); + betRecord.setUpdateTime(new Date()); + + // 保存到数据库 + BetRecord savedRecord = betRecordRepository.save(betRecord); + System.out.println(" - 保存有效投注结果到数据库,ID: " + savedRecord.getId()); + } catch (Exception e) { + System.err.println(" - 保存有效投注结果到数据库失败: " + e.getMessage()); + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/tem/bocai/service/BetRecordService.java b/src/main/java/com/tem/bocai/service/BetRecordService.java new file mode 100644 index 0000000..494c74b --- /dev/null +++ b/src/main/java/com/tem/bocai/service/BetRecordService.java @@ -0,0 +1,10 @@ +package com.tem.bocai.service; + +import com.tem.bocai.entity.BetRecord; +import java.util.List; + +public interface BetRecordService { + BetRecord save(BetRecord betRecord); + List findAll(); + long count(); +} diff --git a/src/main/java/com/tem/bocai/service/impl/BetRecordServiceImpl.java b/src/main/java/com/tem/bocai/service/impl/BetRecordServiceImpl.java new file mode 100644 index 0000000..aa1d71e --- /dev/null +++ b/src/main/java/com/tem/bocai/service/impl/BetRecordServiceImpl.java @@ -0,0 +1,31 @@ +package com.tem.bocai.service.impl; + +import com.tem.bocai.entity.BetRecord; +import com.tem.bocai.repository.BetRecordRepository; +import com.tem.bocai.service.BetRecordService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class BetRecordServiceImpl implements BetRecordService { + + @Autowired + private BetRecordRepository betRecordRepository; + + @Override + public BetRecord save(BetRecord betRecord) { + return betRecordRepository.save(betRecord); + } + + @Override + public List findAll() { + return betRecordRepository.findAll(); + } + + @Override + public long count() { + return betRecordRepository.count(); + } +}