调整金额

This commit is contained in:
2026-01-31 14:59:18 +08:00
parent 57968c183f
commit 4ff6b4bb24
8 changed files with 261 additions and 77 deletions

BIN
bocai.db

Binary file not shown.

View File

@@ -279,7 +279,8 @@ async function handleLogin() {
// 调用登录API
const response = await axios.post(loginApiUrl, {
username: loginForm.value.username,
password: loginForm.value.password
password: loginForm.value.password,
loginUrl: loginForm.value.loginUrl
});
// 处理登录结果
@@ -291,14 +292,6 @@ async function handleLogin() {
// 更新用户名
username.value = loginForm.value.username;
// 重置表单
loginForm.value = {
username: '',
password: '',
loginUrl: 'https://4701268539-esh.qdk63ayw8g.com'
};
console.log('登录成功:', response.data);
} else {
// 登录失败
@@ -390,6 +383,31 @@ async function handleStop() {
}
}
// 处理开始按钮点击
async function handleStart() {
console.log('开始按钮点击');
try {
// 调用后端开始API
const response = await axios.post('http://localhost:8080/api/ocr/saveUserInfo', {
onOff: 1
});
// 处理响应结果
if (response.data && response.code !== 500) {
console.log('开始成功:', response.data);
alert('开始成功');
} else {
console.error('开始失败:', response.data);
alert('开始失败: ' + (response.data.message || '未知错误'));
}
} catch (err) {
console.error('开始失败:', err);
alert('开始操作失败,请检查网络连接');
}
}
onUnmounted(() => {
// 销毁图表
chart1.value?.dispose();
@@ -411,6 +429,8 @@ onUnmounted(() => {
</div>
<div class="account-actions">
<button type="button" class="login-button" @click="loginDialogVisible = true">账号信息</button>
<button type="button" class="start-button" @click="handleStart">开始</button>
<button type="button" class="stop-button" @click="handleStop">停止</button>
</div>
</div>
@@ -418,7 +438,7 @@ onUnmounted(() => {
<div v-if="loginDialogVisible" class="modal-overlay">
<div class="modal-content" @click.stop>
<div class="modal-header">
<h3>登录</h3>
<h3>账号信息</h3>
<button type="button" class="modal-close" @click="loginDialogVisible = false">×</button>
</div>
<div class="modal-body">
@@ -453,16 +473,17 @@ onUnmounted(() => {
<!-- 顶部输入框区域 -->
<div class="top-inputs">
<div class="input-group">
<label for="input1">止盈点</label>
<div class="input-with-button">
<input type="text" id="input1" v-model="input1" placeholder="请输入止盈点">
</div>
</div>
<div class="input-group">
<label for="input2">止亏点</label>
<div class="input-with-button">
<input type="text" id="input2" v-model="input2" placeholder="请输入止亏点">
<div class="button-group">
<button type="button" class="confirm-button" @click="handleConfirm">确认</button>
<button type="button" class="stop-button" @click="handleStop">停止</button>
</div>
</div>
</div>
@@ -483,17 +504,19 @@ onUnmounted(() => {
<thead>
<tr>
<th>ID</th>
<th>期数</th>
<th>开奖时间</th>
<th>开奖号码</th>
<th>投注金额</th>
<th>结果</th>
<th>金额</th>
<th>投注时间</th>
</tr>
</thead>
<tbody>
<tr v-for="item in tableData" :key="item.id">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.time }}</td>
<td>{{ item.betId }}</td>
<td>{{ item.betAmount }}</td>
<td>{{ item.result }}</td>
<td>{{ item.resultAmount }}</td>
<td>{{ item.time }}</td>
</tr>
</tbody>
</table>
@@ -600,6 +623,13 @@ onUnmounted(() => {
transform: translateY(1px);
}
/* 账号操作中的开始和停止按钮 */
.account-actions .start-button,
.account-actions .stop-button {
padding: 6px 12px;
font-size: 0.85rem;
}
.logout-button {
padding: 6px 12px;
background-color: #6c757d;
@@ -686,6 +716,29 @@ onUnmounted(() => {
gap: 8px;
}
/* 开始按钮 */
.start-button {
padding: 8px 14px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
transition: background-color 0.2s ease;
white-space: nowrap;
}
.start-button:hover {
background-color: #45a049;
}
.start-button:active {
background-color: #3d8b40;
transform: translateY(1px);
}
/* 停止按钮 */
.stop-button {
padding: 10px 16px;

View File

@@ -19,8 +19,8 @@ public class BocaiApplication {
//
// 1. 执行CrawlerSchedule方法
System.out.println("\n=== 开始执行CrawlerSchedule任务 ===");
CrawlerSchedule crawlerSchedule = context.getBean(CrawlerSchedule.class);
crawlerSchedule.executeLotteryDraw();
// CrawlerSchedule crawlerSchedule = context.getBean(CrawlerSchedule.class);
// crawlerSchedule.executeLotteryDraw();
//
// 3. 执行ExBetScriptSchedule方法
// System.out.println("\n=== 开始执行ExBetScriptSchedule任务 ===");

View File

@@ -1,9 +1,7 @@
package com.tem.bocai.controller;
import com.tem.bocai.entity.CompletedToday;
import com.tem.bocai.entity.LotteryResult;
import com.tem.bocai.repository.CompletedTodayRepository;
import com.tem.bocai.repository.LotteryResultRepository;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
@@ -15,9 +13,6 @@ import java.util.*;
@RequestMapping("/api")
public class ChartController {
@Autowired
private LotteryResultRepository lotteryResultRepository;
@Autowired
private CompletedTodayRepository completedTodayRepository;
@@ -27,56 +22,96 @@ public class ChartController {
Map<String, Object> response = new HashMap<>();
try {
// 获取今日日期的字符串表示格式yyyy-MM-dd
String today = new java.text.SimpleDateFormat("yyyy-MM-dd").format(new java.util.Date());
System.out.println("今日日期: " + today);
// 获取今日日期
Date now = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(now);
// 设置为当天00:00:00
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
Date startOfDay = calendar.getTime();
// 计算当前时间
Date currentTime = new Date();
// 从数据库获取今日的CompletedToday数据
List<CompletedToday> completedTodays = completedTodayRepository.findAll();
System.out.println("获取到" + completedTodays.size() + "条CompletedToday数据");
List<CompletedToday> todayData = completedTodayRepository.findByCreateTimeAfter(startOfDay);
// 过滤出今日的数据
List<CompletedToday> todayData = new ArrayList<>();
for (CompletedToday item : completedTodays) {
if (item.getTime() != null && item.getTime().toString().contains(today)) {
todayData.add(item);
// 过滤出当前时间之前的数据
List<CompletedToday> filteredData = new ArrayList<>();
for (CompletedToday item : todayData) {
if (item.getCreateTime().before(currentTime)) {
filteredData.add(item);
}
}
System.out.println("过滤后获取到" + todayData.size() + "条今日数据");
todayData = filteredData;
// 按时间排序
todayData.sort(Comparator.comparing(CompletedToday::getTime));
todayData.sort(Comparator.comparing(CompletedToday::getCreateTime));
// 提取数据
List<Double> data = new ArrayList<>();
// 生成每5分钟的时间间隔标签
List<String> labels = new ArrayList<>();
List<Double> data = new ArrayList<>();
for (CompletedToday item : todayData) {
// 使用resultAmount作为折线图数据
data.add(item.getResultAmount());
// 使用时间作为标签(只保留时分部分)
Date time = item.getTime();
String format = DateFormatUtils.format(time, "yyyy-MM-dd HH:mm:ss");
if (time != null && format.length() >= 16) {
labels.add(format.substring(11, 16)); // 提取时分部分
} else {
labels.add(format);
// 计算累计盈亏
double totalProfit = 0.0;
// 遍历每5分钟间隔
Calendar intervalCalendar = (Calendar) calendar.clone();
while (intervalCalendar.getTime().before(currentTime)) {
// 生成时间标签
String timeLabel = DateFormatUtils.format(intervalCalendar.getTime(), "HH:mm");
labels.add(timeLabel);
// 计算该时间点的累计盈亏
double intervalProfit = 0.0;
for (CompletedToday item : todayData) {
if (item.getCreateTime().before(intervalCalendar.getTime())) {
intervalProfit += item.getResultAmount();
}
}
// 更新总盈亏
totalProfit = intervalProfit;
data.add(totalProfit);
// 增加5分钟
intervalCalendar.add(Calendar.MINUTE, 5);
}
// 如果没有今日数据,使用默认数据
// 添加当前时间点的数据
if (!labels.isEmpty()) {
String currentTimeLabel = DateFormatUtils.format(currentTime, "HH:mm");
labels.add(currentTimeLabel);
data.add(totalProfit);
}
// 如果没有今日数据生成默认的5分钟间隔数据
if (data.isEmpty()) {
data = Arrays.asList(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
labels = Arrays.asList("00:00", "04:00", "08:00", "12:00", "16:00", "20:00", "23:59");
labels = new ArrayList<>();
data = new ArrayList<>();
Calendar defaultCalendar = (Calendar) calendar.clone();
while (defaultCalendar.getTime().before(currentTime)) {
String timeLabel = DateFormatUtils.format(defaultCalendar.getTime(), "HH:mm");
labels.add(timeLabel);
data.add(0.0);
defaultCalendar.add(Calendar.MINUTE, 5);
}
// 添加当前时间点
if (!labels.isEmpty()) {
String currentTimeLabel = DateFormatUtils.format(currentTime, "HH:mm");
labels.add(currentTimeLabel);
data.add(0.0);
}
}
response.put("data", data);
response.put("labels", labels);
response.put("title", "今日盈亏数据");
System.out.println("返回的数据长度: " + data.size());
System.out.println("返回的标签长度: " + labels.size());
System.out.println("返回的标签: " + labels);
response.put("title", "今日累计盈亏数据");
} catch (Exception e) {
System.err.println("获取折线图1数据失败: " + e.getMessage());
e.printStackTrace();
@@ -99,23 +134,28 @@ public class ChartController {
List<Map<String, Object>> tableData = new ArrayList<>();
try {
// 获取今日日期的字符串表示格式yyyy-MM-dd
String today = new java.text.SimpleDateFormat("yyyy-MM-dd").format(new java.util.Date());
System.out.println("今日日期: " + today);
// 从数据库获取今日的CompletedToday数据
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
Date startOfDay = calendar.getTime();
List<CompletedToday> completedTodayList = completedTodayRepository.findByCreateTimeAfter(startOfDay);
// 从数据库获取今日的LotteryResult数据
List<LotteryResult> lotteryResults = lotteryResultRepository.findByTimeContaining(today);
System.out.println("获取到" + lotteryResults.size() + "条今日数据");
// 按时间倒序排序
completedTodayList.sort(Comparator.comparing(CompletedToday::getCreateTime).reversed());
// 将LotteryResult对象转换为前端需要的Map格式
for (LotteryResult result : lotteryResults) {
Map<String, Object> item = new HashMap<>();
item.put("id", result.getId());
item.put("name", result.getIssue()); // 使用期号作为名称
item.put("time", result.getTime()); // 添加开奖时间
// 将List<String>转换为逗号分隔的字符串,避免序列化问题
item.put("result", result.getResult()); // 添加开奖号码
tableData.add(item);
// 将CompletedToday对象转换为前端需要的Map格式
for (CompletedToday item : completedTodayList) {
Map<String, Object> map = new HashMap<>();
map.put("betId", item.getBetId());
map.put("betAmount", item.getBetAmount());
map.put("result", item.getResult());
map.put("resultAmount", item.getResultAmount());
map.put("time", DateFormatUtils.format(item.getTime(), "yyyy-MM-dd HH:mm:ss"));
tableData.add(map);
}
} catch (Exception e) {
System.err.println("获取表格数据失败: " + e.getMessage());

View File

@@ -9,6 +9,7 @@ import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.Date;
import java.util.List;
import java.util.Optional;
@Repository
@@ -19,4 +20,14 @@ public interface CompletedTodayRepository extends JpaRepository<CompletedToday,
@Query("SELECT SUM(ct.resultAmount) FROM CompletedToday ct WHERE ct.time > :startTime")
Double sumResultAmountByCreateTimeAfter(@Param("startTime") Date startTime);
// 根据时间范围查询数据
List<CompletedToday> findByTimeBetween(Date startTime, Date endTime);
// 根据时间查询数据(时间大于等于指定时间)
List<CompletedToday> findByTimeAfter(Date startTime);
// 根据创建时间查询数据(创建时间大于等于指定时间)
@Query("SELECT ct FROM CompletedToday ct WHERE ct.time >= :startTime")
List<CompletedToday> findByCreateTimeAfter(@Param("startTime") Date startTime);
}

View File

@@ -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();

View File

@@ -35,7 +35,7 @@ public class CrawlerSchedule {
/*@Scheduled(cron = "0 6-59/5 7-23 * * ?")
@Scheduled(cron = "0 0-55/5 0-6 * * ?")*/
// 从7:00分30秒起每5分钟执行一次
@Scheduled(cron = "30 0/5 * * * ?")
// @Scheduled(cron = "30 0/5 * * * ?")
public void executeLotteryDraw() {
log.info("开始爬取开奖结果");
int retryCount = 0;
@@ -119,7 +119,7 @@ public class CrawlerSchedule {
// 从7:00分30秒起每5分钟执行一次爬取今日已经结算
@Scheduled(cron = "30 0/5 * * * ?")
// @Scheduled(cron = "30 0/5 * * * ?")
public void executeSettlement() {
log.info("开始爬取今日已经结算...");
int retryCount = 0;

View File

@@ -8,13 +8,21 @@ import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import com.tem.bocai.entity.BetRecord;
import com.tem.bocai.repository.BetRecordRepository;
@@ -32,6 +40,71 @@ public class ExBetScriptSchedule {
@Value("${pypath}")
private String pypath;
/**
* 检查PyModel/current_data目录下最新的文件是否存在新数据
* @return 如果存在新数据返回true否则返回false
*/
private boolean checkNewDataExists() {
try {
File currentDataDir = new File(pypath, "current_data");
if (!currentDataDir.exists() || !currentDataDir.isDirectory()) {
System.out.println("current_data目录不存在");
return false;
}
File[] files = currentDataDir.listFiles();
if (files == null || files.length == 0) {
System.out.println("current_data目录为空");
return false;
}
File latestFile = null;
FileTime latestTime = null;
for (File file : files) {
if (file.getName().endsWith(".json")) {
Path path = Paths.get(file.getAbsolutePath());
BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
FileTime fileTime = attrs.lastModifiedTime();
if (latestTime == null || fileTime.compareTo(latestTime) > 0) {
latestTime = fileTime;
latestFile = file;
}
}
}
if (latestFile == null) {
System.out.println("未找到JSON文件");
return false;
}
LocalDateTime fileModifiedTime = LocalDateTime.ofInstant(
latestTime.toInstant(),
ZoneId.systemDefault()
);
LocalDateTime now = LocalDateTime.now();
LocalDateTime fiveMinutesAgo = now.minusMinutes(5);
if (fileModifiedTime.isAfter(fiveMinutesAgo)) {
System.out.println("发现新数据文件: " + 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分钟跳过执行");
return false;
}
} catch (Exception e) {
System.err.println("检查新数据时发生错误:");
e.printStackTrace();
return false;
}
}
/**
* 处理文件路径,确保路径正确
* @param filePath 文件路径
@@ -54,7 +127,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();
@@ -69,6 +142,12 @@ public class ExBetScriptSchedule {
return;
}
// 检查PyModel/current_data目录下最新的文件是否存在新数据
if (!checkNewDataExists()) {
System.out.println("未发现新数据跳过执行Python脚本");
return;
}
System.out.println("开始执行Python脚本...");
// 获取当前时间格式化为yyyy-MM-dd HH:mm:ss
@@ -81,6 +160,7 @@ public class ExBetScriptSchedule {
executePythonScriptWithParams("batch_predict_betting_v8.py", params);
}
/**
* 执行带参数的Python脚本
* @param scriptPath Python脚本路径
@@ -111,7 +191,7 @@ public class ExBetScriptSchedule {
// 创建ProcessBuilder并设置工作目录为PyModel
ProcessBuilder pb = new ProcessBuilder(command);
// 设置工作目录为PyModel
pb.directory(new java.io.File(pypath));
pb.directory(new java.io.File("PyModel"));
// 执行Python脚本
Process process = pb.start();