From c39cf2cc8ae75ae3208e699be45e84e2fa212a9a Mon Sep 17 00:00:00 2001 From: liwq <122639653@qq.com> Date: Mon, 26 Jan 2026 15:22:56 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=8A=95=E6=B3=A8=E8=AE=B0?= =?UTF-8?q?=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PyModel/save_valid_bet_data_sqlite.py | 122 ++++++++++++ PyModel/test.json | 22 +++ bocai.db | Bin 122880 -> 233472 bytes bocai.db-journal | Bin 0 -> 12824 bytes .../java/com/tem/bocai/entity/BetRecord.java | 30 +++ .../bocai/repository/BetRecordRepository.java | 9 + .../com/tem/bocai/schedules/BetSchedule.java | 32 +++- .../bocai/schedules/GenBetRecordSchedule.java | 180 ++++++++++++++++++ .../tem/bocai/service/BetRecordService.java | 10 + .../service/impl/BetRecordServiceImpl.java | 31 +++ 10 files changed, 430 insertions(+), 6 deletions(-) create mode 100644 PyModel/save_valid_bet_data_sqlite.py create mode 100644 PyModel/test.json create mode 100644 bocai.db-journal create mode 100644 src/main/java/com/tem/bocai/entity/BetRecord.java create mode 100644 src/main/java/com/tem/bocai/repository/BetRecordRepository.java create mode 100644 src/main/java/com/tem/bocai/schedules/GenBetRecordSchedule.java create mode 100644 src/main/java/com/tem/bocai/service/BetRecordService.java create mode 100644 src/main/java/com/tem/bocai/service/impl/BetRecordServiceImpl.java 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 c8a70796af22593efb6e8a5adfe66f171b14038d..8f9a50193d3df95c762b5b7257837ff709ef3a45 100644 GIT binary patch literal 233472 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 K{r5?y(tiM6k0?|C diff --git a/bocai.db-journal b/bocai.db-journal new file mode 100644 index 0000000000000000000000000000000000000000..7ca60ebc57edf1688f4a5c87b20528ea2cdb205e GIT binary patch literal 12824 zcmeHNPi)&%7`NN5X|rZ243rB)Z|@LIBo2*`K!__y9C*)3Yx~tNC8!66o~0)5z3+QJ zfA9Cc-)A>A$N9(Z!LNDLLw{Z9YtT2a*8iD-d;+bmtG~<*JVGDrU<@z@7z2y}#sFi0 zF~Au3R}AbdZpQn$+$RdhojaG!WG6;5(r7jVq{%`qQ^;iQ3#z58m)zPiw1k3yJu*@@ zBTeQqf+%P!hG{{eP*rprih^!B4zxCq-|ee!m63fJI<`=F_r9>A)R3DnBcVa1X1azW z6eLlon1%xl>?2Gdi>a!pnI9X^=S9KM939VT?0nhS*%uy&K1!B~GEPG|eD*nslB1$X zcx}G z0%7-PAiR&%h`!w-fhMUy*g^wpJp7sj!jwiwgm;q$bolfO63E-)Xe69nG^EDfrib*N zC{z{Onep=5%l-%a{-3Yx{nh+Ls_LhxDm&gzRau+_XQ-++ncRu2sN(EMR@A+2bfT(u zsn?OJ+KHhfRkcl+PE^%a=bfmkoftY&6}6t?%F~gm+7`o8RCUQy)ur8o-+n|Fxo+=w zfaDKc@+b7c4#ogufHA-rU<@z@7z2y}#sFi0F~AsL3@`?s0|o}Wx`(>Z55=+tE2gE| z+()nS-LrjiU`RG~Rc`(CJRwW1_dodCx8^kmf~slN6bIzcn;<;Ty$Jw%OW-@SaQu$Q z(eXBF^c;22Hy>zInh0a8`b#3tbMf9WZs3~>OUb8wAD|$}cTmIJ zC{$z3G~k8+H1vdY1zP?j!>t`hkcf+*VnM}$-iZJ{o9!sIH4(UL2%Q{G*Oy+1r7mCQ zw_T3}-CWTOSu?7p-|7ib;E#i0O+AhVG#{P${fcR>Y7l&&Se3hqHJlwEPlrPbT7Y3X zz;Jb41WkO`(ut|MX+s$;)jxx2$Y!dFG~VVSZZX1-yZdr zSTSpBI&`2aJEp2^5Zy#*IfOBsggB~JF{tV$x)1lYjZJ8ckzxa`q1|&~xJE?fiv?|0 zccMW=(6rJ5z<7R53`BNXlAg%4slndVtr4En3>AK8-_z0m9kSv&rq`DVf@FypxRB`K z`f#G&?Cr&SaL3z%7K{xM4@LzN-R{s95XNC#q(n3`o&1Blb|wOB`@so7b6D|w0r zB&rHz>0&5qp^fK%<$9V9Ur*C@rLU=zW+iXE(uD2;a2nb~w=1+*i1 TG|Cb&(2MfjQ`7Fj@8ACoqU2~D literal 0 HcmV?d00001 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(); + } +}