diff --git a/bocai.db b/bocai.db
index 19ba48e..2dccf35 100644
Binary files a/bocai.db and b/bocai.db differ
diff --git a/frontend/src/components/index.vue b/frontend/src/components/index.vue
index 6448940..bd205c2 100644
--- a/frontend/src/components/index.vue
+++ b/frontend/src/components/index.vue
@@ -64,7 +64,27 @@ function updateChart1() {
left: 'center'
},
tooltip: {
- trigger: 'axis'
+ trigger: 'axis',
+ axisPointer: {
+ type: 'cross',
+ label: {
+ backgroundColor: '#6a7985'
+ }
+ },
+ formatter: function(params) {
+ let result = params[0].name + '
';
+ params.forEach(function(item) {
+ let value = item.value;
+ let color = item.color;
+ let status = value >= 0 ? '盈利' : '亏损';
+ let statusColor = value >= 0 ? '#4CAF50' : '#ff6b6b';
+ result += '';
+ result += item.seriesName + ': ';
+ result += '' + value + ' ';
+ result += '(' + status + ')
';
+ });
+ return result;
+ }
},
legend: {
data: ['数据'],
diff --git a/src/main/java/com/tem/bocai/BocaiApplication.java b/src/main/java/com/tem/bocai/BocaiApplication.java
index 6806c08..6c3d2d3 100644
--- a/src/main/java/com/tem/bocai/BocaiApplication.java
+++ b/src/main/java/com/tem/bocai/BocaiApplication.java
@@ -18,7 +18,7 @@ public class BocaiApplication {
// // 依次执行三个任务
//
// 1. 执行CrawlerSchedule方法
- System.out.println("\n=== 开始执行CrawlerSchedule任务 ===");
+// System.out.println("\n=== 开始执行CrawlerSchedule任务 ===");
// CrawlerSchedule crawlerSchedule = context.getBean(CrawlerSchedule.class);
// crawlerSchedule.executeLotteryDraw();
//
diff --git a/src/main/java/com/tem/bocai/config/TessConfig.java b/src/main/java/com/tem/bocai/config/TessConfig.java
index d685f2c..b94a923 100644
--- a/src/main/java/com/tem/bocai/config/TessConfig.java
+++ b/src/main/java/com/tem/bocai/config/TessConfig.java
@@ -12,7 +12,8 @@ public class TessConfig {
Tesseract instance = new Tesseract();
instance.setLanguage("oci"); // 设置语言包,这里使用英语
- instance.setDatapath("tessdata"); // 设置语言包路径
+ instance.setDatapath("src/main/resources/tessdata"); // 设置语言包路径
+// instance.setDatapath("tessdata"); // 设置语言包路径
return instance;
}
}
diff --git a/src/main/java/com/tem/bocai/schedules/BetSchedule.java b/src/main/java/com/tem/bocai/schedules/BetSchedule.java
index b51e1fd..205a6a0 100644
--- a/src/main/java/com/tem/bocai/schedules/BetSchedule.java
+++ b/src/main/java/com/tem/bocai/schedules/BetSchedule.java
@@ -41,7 +41,7 @@ public class BetSchedule {
private BetRecordRepository betRecordRepository;
// 从7:02分钟起每5分钟执行一次
-// @Scheduled(cron = "30 2/5 * * * ?")
+ @Scheduled(cron = "30 2/5 * * * ?")
public void placeBet() {
LocalDateTime now = LocalDateTime.now();
int hour = now.getHour();
@@ -53,7 +53,7 @@ public class BetSchedule {
String currentTime = now.format(
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
);
- System.out.println(currentTime + " - 不在投注时间范围内,跳过执行");
+ log.info("{}", currentTime + " - 不在投注时间范围内,跳过执行");
return;
}
@@ -64,13 +64,13 @@ public class BetSchedule {
LoginInfoResult loginInfo = loginInfoRepository.findFirstByOrderByCreateTimeDesc().orElse(null);
if (loginInfo == null) {
- System.out.println(currentTime + " - 未找到登录信息,跳过执行");
+ log.info("{}", currentTime + " - 未找到登录信息,跳过执行");
return;
}
// 检查onOff字段是否为1(开启状态)
if (loginInfo.getOnOff() != 1) {
- System.out.println(currentTime + " - 投注功能未开启,跳过执行");
+ log.info("{}", currentTime + " - 投注功能未开启,跳过执行");
return;
}
@@ -84,34 +84,33 @@ public class BetSchedule {
if (startTime != null) {
Double totalResultAmount = completedTodayRepository.sumResultAmountByCreateTimeAfter(startTime);
if (totalResultAmount != null) {
- System.out.println(" - 今日盈亏总和: " + totalResultAmount);
+ log.info(" - 今日盈亏总和: {}", totalResultAmount);
// 判断是否达到止盈点
if (totalResultAmount >= winNum) {
- System.out.println(currentTime + " - 已达到止盈点 " + winNum + ",跳过执行");
+ log.info("{}", currentTime + " - 已达到止盈点 " + winNum + ",跳过执行");
return;
}
// 判断是否达到止亏点
if (totalResultAmount <= -loseNum) {
- System.out.println(currentTime + " - 已达到止亏点 " + loseNum + ",跳过执行");
+ log.info("{}", currentTime + " - 已达到止亏点 " + loseNum + ",跳过执行");
return;
}
}
}
}
- System.out.println(currentTime + " - 开始执行投注...");
+ log.info("{}", currentTime + " - 开始执行投注...");
try {
// 执行投注逻辑
executeBet(loginInfo);
- System.out.println(currentTime + " - 投注执行完成");
+ log.info("{}", currentTime + " - 投注执行完成");
} catch (Exception e) {
- System.err.println(currentTime + " - 投注执行失败:");
- e.printStackTrace();
+ log.error("{} - 投注执行失败:", currentTime, e);
}
}
@@ -130,7 +129,7 @@ public class BetSchedule {
LocalDateTime now = LocalDateTime.now();
// 2. 从BetRecord中获取第一条记录(根据betTime排序)
- System.out.println(" - 从BetRecord中获取第一条记录...");
+ log.info(" - 从BetRecord中获取第一条记录...");
Optional optionalBetRecord = betRecordRepository.findFirstByOrderByBetTimeDesc();
if (optionalBetRecord.isPresent()) {
@@ -138,30 +137,29 @@ public class BetSchedule {
String betData = betRecord.getBetData();
String betTime = betRecord.getBetTime();
- System.out.println(" - 投注时间: " + betTime);
- System.out.println(" - 投注数据: " + betData);
+ log.info(" - 投注时间: {}", betTime);
+ log.info(" - 投注数据: {}", betData);
// 调用投注接口
- System.out.println(" - 提交投注...");
+ log.info(" - 提交投注...");
String betResult = callBetApi(betData, null);
- System.out.println(" - 投注结果: " + betResult);
+ log.info(" - 投注结果: {}", betResult);
// 记录投注结果
- System.out.println(" - 记录投注结果...");
+ log.info(" - 记录投注结果...");
recordBetResult(betData, betResult);
// 投注成功后删除BetRecord记录
if (betResult == null) {
betRecordRepository.delete(betRecord);
- System.out.println(" - 已删除投注记录,期数: " + betRecord.getBetNum());
+ log.info(" - 已删除投注记录,期数: {}", betRecord.getBetNum());
}
} else {
- System.out.println(" - 未找到投注记录");
+ log.info(" - 未找到投注记录");
}
} catch (Exception e) {
- System.err.println(" - 投注执行失败:");
- e.printStackTrace();
+ log.error(" - 投注执行失败:", e);
}
}
@@ -207,6 +205,6 @@ public class BetSchedule {
// 这里可以实现将投注结果记录到数据库或日志文件的逻辑
// 为了简单起见,我们这里只打印日志
String currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
- System.out.println(" - 投注记录: [" + currentTime + "] 数据: " + betData + ", 结果: " + betResult);
+ log.info(" - 投注记录: [{}] 数据: {}, 结果: {}", currentTime, betData, betResult);
}
}
diff --git a/src/main/java/com/tem/bocai/schedules/ExBetScriptSchedule.java b/src/main/java/com/tem/bocai/schedules/ExBetScriptSchedule.java
index 90ddd98..8c6a7b6 100644
--- a/src/main/java/com/tem/bocai/schedules/ExBetScriptSchedule.java
+++ b/src/main/java/com/tem/bocai/schedules/ExBetScriptSchedule.java
@@ -2,6 +2,7 @@ package com.tem.bocai.schedules;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
import org.json.JSONArray;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
@@ -31,6 +32,7 @@ import org.springframework.beans.factory.annotation.Autowired;
/**
* 执行预测脚本
*/
+@Slf4j
@Component
public class ExBetScriptSchedule {
@@ -48,13 +50,13 @@ public class ExBetScriptSchedule {
try {
File currentDataDir = new File(pypath, "current_data");
if (!currentDataDir.exists() || !currentDataDir.isDirectory()) {
- System.out.println("current_data目录不存在");
+ log.info("current_data目录不存在");
return false;
}
File[] files = currentDataDir.listFiles();
if (files == null || files.length == 0) {
- System.out.println("current_data目录为空");
+ log.info("current_data目录为空");
return false;
}
@@ -75,7 +77,7 @@ public class ExBetScriptSchedule {
}
if (latestFile == null) {
- System.out.println("未找到JSON文件");
+ log.info("未找到JSON文件");
return false;
}
@@ -88,19 +90,15 @@ public class ExBetScriptSchedule {
LocalDateTime fiveMinutesAgo = now.minusMinutes(5);
if (fileModifiedTime.isAfter(fiveMinutesAgo)) {
- System.out.println("发现新数据文件: " + latestFile.getName() +
- ", 修改时间: " + fileModifiedTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+ log.info("发现新数据文件: {}, 修改时间: {}", latestFile.getName(), fileModifiedTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
return true;
} else {
- System.out.println("最新数据文件: " + latestFile.getName() +
- ", 修改时间: " + fileModifiedTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) +
- ", 超过5分钟,跳过执行");
+ log.info("最新数据文件: {}, 修改时间: {}, 超过5分钟,跳过执行", latestFile.getName(), fileModifiedTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
return false;
}
} catch (Exception e) {
- System.err.println("检查新数据时发生错误:");
- e.printStackTrace();
+ log.error("检查新数据时发生错误:", e);
return false;
}
}
@@ -127,7 +125,7 @@ public class ExBetScriptSchedule {
}
// 从7:01分钟起每5分钟执行一次
-// @Scheduled(cron = "30 1/5 * * * ?")
+ @Scheduled(cron = "30 1/5 * * * ?")
public void executePythonScript() {
LocalDateTime now = LocalDateTime.now();
int hour = now.getHour();
@@ -138,17 +136,17 @@ public class ExBetScriptSchedule {
String currentTime = now.format(
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
);
- System.out.println(currentTime + " - 不在投注时间范围内,跳过执行");
+ log.info("{}", currentTime + " - 不在投注时间范围内,跳过执行");
return;
}
// 检查PyModel/current_data目录下最新的文件是否存在新数据
if (!checkNewDataExists()) {
- System.out.println("未发现新数据,跳过执行Python脚本");
+ log.info("未发现新数据,跳过执行Python脚本");
return;
}
- System.out.println("开始执行Python脚本...");
+ log.info("开始执行Python脚本...");
// 获取当前时间,格式化为yyyy-MM-dd HH:mm:ss
String currentTime = java.time.LocalDateTime.now().format(
@@ -186,12 +184,12 @@ public class ExBetScriptSchedule {
}
}
- System.out.println("执行命令: " + String.join(" ", command));
+ log.info("执行命令: {}", String.join(" ", command));
// 创建ProcessBuilder并设置工作目录为PyModel
ProcessBuilder pb = new ProcessBuilder(command);
// 设置工作目录为PyModel
- pb.directory(new java.io.File("PyModel"));
+ pb.directory(new java.io.File(pypath));
// 执行Python脚本
Process process = pb.start();
@@ -220,18 +218,17 @@ public class ExBetScriptSchedule {
// 等待脚本执行完成
int exitCode = process.waitFor();
- System.out.println("Python脚本执行完成,退出码: " + exitCode);
- System.out.println("脚本输出:\n" + output.toString());
+ log.info("Python脚本执行完成,退出码: {}", exitCode);
+ log.info("脚本输出:\n{}", output.toString());
if (exitCode != 0) {
- System.err.println("脚本执行错误:\n" + errorOutput.toString());
+ log.error("脚本执行错误:\n{}", errorOutput.toString());
} else {
parseScriptOutput(output.toString());
}
} catch (IOException | InterruptedException e) {
- System.err.println("执行Python脚本时发生错误:");
- e.printStackTrace();
+ log.error("执行Python脚本时发生错误:", e);
}
}
@@ -241,16 +238,16 @@ public class ExBetScriptSchedule {
*/
private void parseScriptOutput(String output) {
try {
- System.out.println("开始解析脚本输出...");
+ log.info("开始解析脚本输出...");
JSONObject jsonOutput = JSON.parseObject(output);
if (jsonOutput == null) {
- System.out.println("输出为空或无法解析为JSON");
+ log.info("输出为空或无法解析为JSON");
return;
}
JSONObject result = jsonOutput.getJSONObject("result");
if (result == null) {
- System.out.println("未找到result字段");
+ log.info("未找到result字段");
return;
}
@@ -274,20 +271,19 @@ public class ExBetScriptSchedule {
}
}
if (!validResults.isEmpty()) {
- System.out.println("提取到的有效预测结果:");
+ log.info("提取到的有效预测结果:");
for (Map.Entry> entry : validResults.entrySet()) {
- System.out.println("位置 " + entry.getKey() + ": " + entry.getValue());
+ log.info("位置 {}: {}", entry.getKey(), entry.getValue());
}
// 生成符合test.json格式的数据
generateOutputData(validResults);
} else {
- System.out.println("未找到有效的预测结果(所有值均为None)");
+ log.info("未找到有效的预测结果(所有值均为None)");
}
} catch (Exception e) {
- System.err.println("解析脚本输出时发生错误:");
- e.printStackTrace();
+ log.error("解析脚本输出时发生错误:", e);
}
}
@@ -367,8 +363,8 @@ public class ExBetScriptSchedule {
outputData.put("fastBets", false);
outputData.put("ignore", false);
- System.out.println("生成的输出数据:");
- System.out.println(outputData.toString(2));
+ log.info("生成的输出数据:");
+ log.info("{}", outputData.toString(2));
// 保存到数据库
try {
@@ -383,13 +379,12 @@ public class ExBetScriptSchedule {
// 检查betNum是否已存在,避免重复保存
if (!betRecordRepository.existsByBetNum(drawNumber)) {
betRecordRepository.save(betRecord);
- System.out.println("保存投注记录到数据库成功,期数: " + drawNumber);
+ log.info("保存投注记录到数据库成功,期数: {}", drawNumber);
} else {
- System.out.println("投注记录已存在,期数: " + drawNumber);
+ log.info("投注记录已存在,期数: {}", drawNumber);
}
} catch (Exception e) {
- System.err.println("保存投注记录到数据库失败:");
- e.printStackTrace();
+ log.error("保存投注记录到数据库失败:", e);
}
}
}
diff --git a/src/main/java/com/tem/bocai/util/TokenCacheService.java b/src/main/java/com/tem/bocai/util/TokenCacheService.java
index 869eaad..13bd9f4 100644
--- a/src/main/java/com/tem/bocai/util/TokenCacheService.java
+++ b/src/main/java/com/tem/bocai/util/TokenCacheService.java
@@ -9,6 +9,7 @@ import lombok.extern.slf4j.Slf4j;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
import org.apache.http.Header;
+import org.apache.http.HttpHost;
import org.apache.http.NameValuePair;
import org.apache.http.client.CookieStore;
import org.apache.http.client.config.RequestConfig;
@@ -372,8 +373,16 @@ public class TokenCacheService {
// 等待一下再发送登录请求
Thread.sleep(1500 + (long) (Math.random() * 1000));
+ // 新增代码:增加代理
+ String proxyHost = "127.0.0.1";
+ int proxyPort = 7890;
+ HttpHost proxy = new HttpHost(proxyHost, proxyPort);
+ RequestConfig proxyConfig = RequestConfig.custom()
+ .setProxy(proxy)
+ .build();
HttpPost loginPost = createLoginRequest(code,loginInfoParam);
-
+ // 新增代码:将代理类放入配置中
+ loginPost.setConfig(proxyConfig);
try (CloseableHttpResponse loginResponse = httpClient.execute(loginPost)) {
return processLoginResponse(loginResponse, cookieStore);
}
@@ -383,13 +392,16 @@ public class TokenCacheService {
* 创建登录请求
*/
private HttpPost createLoginRequest(String code,LoginInfoParam loginInfoParam) throws UnsupportedEncodingException {
+
+
+
HttpPost loginPost = new HttpPost(loginInfoParam.loginUrl + "/login");
+
// 设置请求头
setCommonHeaders(loginPost);
loginPost.setHeader("Referer", loginInfoParam.loginUrl + "/login");
loginPost.setHeader("Origin", loginInfoParam.loginUrl);
loginPost.setHeader("Accept", "application/json, text/plain, */*");
-
// 构建登录参数
List params = new ArrayList<>();
params.add(new BasicNameValuePair("type", "1"));