Compare commits

...

2 Commits

Author SHA1 Message Date
9fea9d86ed Merge remote-tracking branch 'origin/master' 2026-01-23 14:53:02 +08:00
c53e7a6076 调整 2026-01-23 14:52:07 +08:00
7 changed files with 162 additions and 299 deletions

View File

@@ -10,8 +10,7 @@ const input2 = ref('');
// 登录模态框数据
const loginDialogVisible = ref(false);
const isLoggedIn = ref(false);
const username = ref('用户名');
const accountBalance = ref('账户余额');
const username = ref('未记录');
const loginForm = ref({
username: '',
password: '',
@@ -25,39 +24,51 @@ const tableData = ref([]);
const tableLoading = ref(false);
const tableError = ref('');
// 生成从7:00到第二天6:55的时间标签每隔5分钟
function generateTimeLabels() {
const labels = [];
// 从7:00到23:55
for (let hour = 7; hour < 24; hour++) {
for (let minute = 0; minute < 60; minute += 5) {
labels.push(`${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`);
}
}
// 从0:00到6:55
for (let hour = 0; hour < 6; hour++) {
for (let minute = 0; minute < 60; minute += 5) {
labels.push(`${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`);
}
}
return labels;
}
// 生成对应长度的随机数据
function generateRandomData(length) {
return Array.from({ length }, () => Math.floor(Math.random() * 100) + 10);
}
// 折线图数据
const chartData1 = ref([65, 59, 80, 81, 56, 55, 40]);
const chartData2 = ref([28, 48, 40, 19, 86, 27, 90]);
const chartLabels = ref(['1月', '2月', '3月', '4月', '5月', '6月', '7月']);
const chartLabels = ref(generateTimeLabels());
const chartData1 = ref(generateRandomData(chartLabels.value.length));
const loading = ref(false);
const error = ref('');
// ECharts实例
const chart1Ref = ref(null);
const chart2Ref = ref(null);
const chart1 = ref(null);
const chart2 = ref(null);
// 初始化ECharts图表
function initCharts() {
console.log('开始初始化图表');
console.log('chart1Ref.value:', chart1Ref.value);
console.log('chart2Ref.value:', chart2Ref.value);
// 初始化图表1
// 初始化图表
if (chart1Ref.value) {
console.log('初始化图表1');
console.log('初始化图表');
chart1.value = echarts.init(chart1Ref.value);
updateChart1();
}
// 初始化图表2
if (chart2Ref.value) {
console.log('初始化图表2');
chart2.value = echarts.init(chart2Ref.value);
updateChart2();
}
console.log('图表初始化完成');
}
@@ -85,14 +96,19 @@ function updateChart1() {
grid: {
left: '3%',
right: '4%',
bottom: '15%',
bottom: '30%',
top: '20%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: chartLabels.value
data: chartLabels.value,
axisLabel: {
rotate: 45,
interval: 11, // 每12个标签显示一个避免重叠
fontSize: 10
}
},
yAxis: {
type: 'value'
@@ -131,80 +147,9 @@ function updateChart1() {
console.log('图表1更新完成');
}
// 更新图表2
function updateChart2() {
console.log('更新图表2');
console.log('chart2.value:', chart2.value);
console.log('chartData2.value:', chartData2.value);
console.log('chartLabels.value:', chartLabels.value);
if (!chart2.value) return;
const option = {
title: {
text: '折线图2',
left: 'center'
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['数据'],
bottom: 0
},
grid: {
left: '3%',
right: '4%',
bottom: '15%',
top: '20%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: chartLabels.value
},
yAxis: {
type: 'value'
},
series: [
{
name: '数据',
type: 'line',
smooth: true,
data: chartData2.value,
itemStyle: {
color: '#2196F3'
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0,
color: 'rgba(33, 150, 243, 0.3)'
}, {
offset: 1,
color: 'rgba(33, 150, 243, 0.1)'
}]
}
}
}
]
};
console.log('设置图表2选项');
chart2.value.setOption(option);
console.log('图表2更新完成');
}
// 监听窗口大小变化
function handleResize() {
chart1.value?.resize();
chart2.value?.resize();
}
// 从后端获取折线图数据
@@ -214,33 +159,28 @@ async function fetchChartData() {
error.value = '';
try {
// 获取折线图1数据
console.log('获取折线图1数据');
const response1 = await axios.get('http://localhost:8080/api/charts/line1');
console.log('折线图1数据响应:', response1.data);
if (response1.data) {
chartData1.value = response1.data.data || chartData1.value;
chartLabels.value = response1.data.labels || chartLabels.value;
}
// 获取折线图2数据
console.log('获取折线图2数据');
const response2 = await axios.get('http://localhost:8080/api/charts/line2');
console.log('折线图2数据响应:', response2.data);
if (response2.data) {
chartData2.value = response2.data.data || chartData2.value;
// 获取折线图数据
console.log('获取折线图数据');
const response = await axios.get('http://localhost:8080/api/charts/line1');
console.log('折线图数据响应:', response.data);
if (response.data && response.data.data) {
chartData1.value = response.data.data;
// 确保数据长度与标签长度一致
if (chartData1.value.length !== chartLabels.value.length) {
console.warn('数据长度与标签长度不一致,使用默认数据');
chartData1.value = generateRandomData(chartLabels.value.length);
}
}
console.log('图表数据获取完成');
console.log('chartData1.value:', chartData1.value);
console.log('chartData2.value:', chartData2.value);
console.log('chartLabels.value:', chartLabels.value);
console.log('标签数量:', chartLabels.value.length);
// 更新图表
nextTick(() => {
console.log('更新图表数据');
updateChart1();
updateChart2();
});
} catch (err) {
console.error('获取图表数据失败:', err);
@@ -248,14 +188,12 @@ async function fetchChartData() {
// 使用默认数据
console.log('使用默认数据');
console.log('默认 chartData1.value:', chartData1.value);
console.log('默认 chartData2.value:', chartData2.value);
console.log('默认 chartLabels.value:', chartLabels.value);
// 更新图表
nextTick(() => {
console.log('使用默认数据更新图表');
updateChart1();
updateChart2();
});
} finally {
loading.value = false;
@@ -280,12 +218,48 @@ async function fetchTableData() {
}
}
// 从后端获取用户设置数据(用户名、止盈点、止亏点)
async function fetchUserSettings() {
console.log('开始获取用户设置数据');
try {
// 获取用户设置数据
console.log('获取用户设置数据');
const response = await axios.get('http://localhost:8080/api/ocr/userSettings');
console.log('用户设置数据响应:', response.data);
if (response.data) {
// 更新用户名
if (response.data.username) {
username.value = response.data.username;
isLoggedIn.value = true;
}
// 更新止盈点
if (response.data.winNum) {
input1.value = response.data.winNum;
}
// 更新止亏点
if (response.data.loseNum) {
input2.value = response.data.loseNum;
}
}
console.log('用户设置数据获取完成');
console.log('username.value:', username.value);
console.log('input1.value:', input1.value);
console.log('input2.value:', input2.value);
} catch (err) {
console.error('获取用户设置数据失败:', err);
// 失败时不显示错误,使用默认值
}
}
onMounted(() => {
console.log('组件挂载完成');
// 从后端获取数据
fetchChartData();
fetchTableData();
fetchUserSettings();
// 初始化图表延迟一点时间确保DOM完全渲染
setTimeout(() => {
@@ -325,20 +299,14 @@ async function handleLogin() {
});
// 处理登录结果
if (response.data && response.data.code === 1) {
if (response.data && response.code !== 500) {
// 登录成功
loginLoading.value = false;
loginDialogVisible.value = false;
isLoggedIn.value = true;
// 更新用户名和账户余额
// 更新用户名
username.value = loginForm.value.username;
accountBalance.value = response.data.balance || '¥10000.00';
// 保存登录信息(可选)
if (response.data.token) {
localStorage.setItem('token', response.data.token);
}
// 重置表单
loginForm.value = {
@@ -368,7 +336,6 @@ function handleLogout() {
isLoggedIn.value = false;
// 重置用户名和账户余额
username.value = '用户名';
accountBalance.value = '账户余额';
// 清除登录状态
localStorage.removeItem('token');
// 这里可以添加其他清理逻辑
@@ -400,7 +367,7 @@ async function handleConfirm() {
const response = await axios.post('http://localhost:8080/api/ocr/saveUserInfo', submitData);
// 处理响应结果
if (response.data && response.data.code === 1) {
if (response.data && response.code !== 500) {
console.log('提交成功:', response.data);
alert('设置保存成功');
} else {
@@ -425,12 +392,12 @@ async function handleStop() {
});
// 处理响应结果
if (response.data && response.data.code === 1) {
if (response.data && response.code !== 500) {
console.log('停止成功:', response.data);
alert('停止操作成功');
alert('停止成功');
} else {
console.error('停止失败:', response.data);
alert('停止操作失败: ' + (response.data.message || '未知错误'));
alert('停止失败: ' + (response.data.message || '未知错误'));
}
} catch (err) {
@@ -442,7 +409,6 @@ async function handleStop() {
onUnmounted(() => {
// 销毁图表
chart1.value?.dispose();
chart2.value?.dispose();
// 移除事件监听器
window.removeEventListener('resize', handleResize);
@@ -458,11 +424,9 @@ onUnmounted(() => {
<div class="account-avatar">👤</div>
<div class="account-details">
<div class="account-name">{{ username }}</div>
<div class="account-role">{{ accountBalance }}</div>
</div>
<div class="account-actions">
<button v-if="!isLoggedIn" type="button" class="login-button" @click="loginDialogVisible = true">登录</button>
<button v-else type="button" class="logout-button" @click="handleLogout">退出</button>
<button type="button" class="login-button" @click="loginDialogVisible = true">账号信息</button>
</div>
</div>
@@ -493,8 +457,8 @@ onUnmounted(() => {
<div class="form-actions">
<button type="button" class="cancel-button" @click="loginDialogVisible = false">取消</button>
<button type="submit" class="submit-button" :disabled="loginLoading">
<span v-if="loginLoading">登录中...</span>
<span v-else>登录</span>
<span v-if="loginLoading">保存中...</span>
<span v-else>保存</span>
</button>
</div>
</form>
@@ -535,21 +499,17 @@ onUnmounted(() => {
<thead>
<tr>
<th>ID</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.value }}</td>
<td>
<span :class="`status-badge ${item.status === '正常' ? 'status-normal' : item.status === '警告' ? 'status-warning' : 'status-error'}`">
{{ item.status }}
</span>
</td>
<td>{{ item.time }}</td>
<td>{{ item.result }}</td>
</tr>
</tbody>
</table>
@@ -568,14 +528,7 @@ onUnmounted(() => {
<div v-if="loading" class="chart-loading">
加载中...
</div>
<div v-else ref="chart1Ref" class="echart-container" style="width: 100%; height: 300px; border: 1px solid #ddd;"></div>
</div>
<div class="chart-container">
<div v-if="loading" class="chart-loading">
加载中...
</div>
<div v-else ref="chart2Ref" class="echart-container" style="width: 100%; height: 300px; border: 1px solid #ddd;"></div>
<div v-else ref="chart1Ref" class="echart-container" style="width: 100%; height: 100%; border: 1px solid #ddd;"></div>
</div>
</div>
</div>
@@ -794,10 +747,11 @@ onUnmounted(() => {
/* 图表区域 */
.chart-container {
flex: 1;
display: flex;
flex-direction: column;
gap: 15px;
height: 300px;
min-height: 0;
}
.input-group label {

View File

@@ -1,5 +1,8 @@
package com.tem.bocai.controller;
import com.tem.bocai.entity.LotteryResult;
import com.tem.bocai.repository.LotteryResultRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -8,6 +11,9 @@ import java.util.*;
@RestController
@RequestMapping("/api")
public class ChartController {
@Autowired
private LotteryResultRepository lotteryResultRepository;
// 获取折线图1数据
@GetMapping("/charts/line1")
@@ -24,79 +30,35 @@ public class ChartController {
return response;
}
// 获取折线图2数据
@GetMapping("/charts/line2")
public Map<String, Object> getLineChartData2() {
Map<String, Object> response = new HashMap<>();
// 模拟数据 - 实际项目中应该从数据库获取
List<Integer> data = Arrays.asList(28, 48, 40, 19, 86, 27, 90);
List<String> labels = Arrays.asList("1月", "2月", "3月", "4月", "5月", "6月", "7月");
response.put("data", data);
response.put("labels", labels);
response.put("title", "折线图2数据");
return response;
}
// 获取表格数据
@GetMapping("/table")
public List<Map<String, Object>> getTableData() {
List<Map<String, Object>> tableData = new ArrayList<>();
// 模拟数据 - 实际项目中应该从数据库获取
Map<String, Object> item1 = new HashMap<>();
item1.put("id", 1);
item1.put("name", "项目1");
item1.put("value", 120);
item1.put("status", "正常");
tableData.add(item1);
Map<String, Object> item2 = new HashMap<>();
item2.put("id", 2);
item2.put("name", "项目2");
item2.put("value", 230);
item2.put("status", "警告");
tableData.add(item2);
Map<String, Object> item3 = new HashMap<>();
item3.put("id", 3);
item3.put("name", "项目3");
item3.put("value", 180);
item3.put("status", "正常");
tableData.add(item3);
Map<String, Object> item4 = new HashMap<>();
item4.put("id", 4);
item4.put("name", "项目4");
item4.put("value", 90);
item4.put("status", "异常");
tableData.add(item4);
Map<String, Object> item5 = new HashMap<>();
item5.put("id", 5);
item5.put("name", "项目5");
item5.put("value", 320);
item5.put("status", "正常");
tableData.add(item5);
Map<String, Object> item6 = new HashMap<>();
item6.put("id", 6);
item6.put("name", "项目6");
item6.put("value", 270);
item6.put("status", "警告");
tableData.add(item6);
tableData.add(item6);
tableData.add(item6);
tableData.add(item6);
tableData.add(item6);
tableData.add(item6);
tableData.add(item6);
tableData.add(item6);
tableData.add(item6);
tableData.add(item6);
try {
// 获取今日日期的字符串表示格式yyyy-MM-dd
String today = new java.text.SimpleDateFormat("yyyy-MM-dd").format(new java.util.Date());
System.out.println("今日日期: " + today);
// 从数据库获取今日的LotteryResult数据
List<LotteryResult> lotteryResults = lotteryResultRepository.findByTimeContaining(today);
System.out.println("获取到" + lotteryResults.size() + "条今日数据");
// 将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);
}
} catch (Exception e) {
System.err.println("获取表格数据失败: " + e.getMessage());
e.printStackTrace();
}
return tableData;
}

View File

@@ -3,14 +3,11 @@ package com.tem.bocai.controller;
import com.tem.bocai.entity.LoginInfoResult;
import com.tem.bocai.param.LoginInfoParam;
import com.tem.bocai.service.LoginService;
import com.tem.bocai.util.ImageOcrService;
import net.sourceforge.tess4j.TesseractException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.Date;
@RestController
@RequestMapping("api/ocr")
@@ -43,6 +40,13 @@ public class LoginCrawler {
return ResponseEntity.ok(result);
}
// 获取用户设置信息
@GetMapping("/userSettings")
public ResponseEntity<LoginInfoResult> getUserSettings(){
LoginInfoResult result = loginService.getUserSettings();
return ResponseEntity.ok(result);
}
}

View File

@@ -29,7 +29,7 @@ public class LotteryResult {
private String time; // 开奖时间
@Column(name = "result")
private List<String> result; // 开奖号码
private String result; // 开奖号码
@Column(name = "winner", nullable = false)
private String winner; //
@@ -54,83 +54,4 @@ public class LotteryResult {
@Column(name = "glh_result", nullable = false)
private String glh_result; //[ "龙", "龙", "龙", "虎", "虎" ] 龙虎
public String getIssue() {
return issue;
}
public void setIssue(String issue) {
this.issue = issue;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public List<String> getResult() {
return result;
}
public void setResult(List<String> result) {
this.result = result;
}
public String getWinner() {
return winner;
}
public void setWinner(String winner) {
this.winner = winner;
}
public String getSum1() {
return sum1;
}
public void setSum1(String sum1) {
this.sum1 = sum1;
}
public String getSum2() {
return sum2;
}
public void setSum2(String sum2) {
this.sum2 = sum2;
}
public String getGd2() {
return gd2;
}
public void setGd2(String gd2) {
this.gd2 = gd2;
}
public String getGd1() {
return gd1;
}
public void setGd1(String gd1) {
this.gd1 = gd1;
}
public String getGlh_result() {
return glh_result;
}
public void setGlh_result(String glh_result) {
this.glh_result = glh_result;
}
}

View File

@@ -4,7 +4,10 @@ import com.tem.bocai.entity.LotteryResult;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface LotteryResultRepository extends JpaRepository<LotteryResult, Long> {
// 可以添加自定义查询方法
// 根据时间查询使用like匹配日期部分
List<LotteryResult> findByTimeContaining(String date);
}

View File

@@ -13,4 +13,7 @@ public interface LoginService {
String saveUserInfo(LoginInfoResult loginInfoResult);
// 获取用户设置信息
LoginInfoResult getUserSettings();
}

View File

@@ -251,5 +251,21 @@ public class LoginServiceImpl implements LoginService {
return SQLiteUtil.addOrUpdateLoginInfo(loginInfo);
}
@Override
public LoginInfoResult getUserSettings() {
try {
// 获取最新的用户设置信息
Optional<LoginInfoResult> existingUser = loginInfoRepository.findFirstByOrderByCreateTimeDesc();
if (existingUser.isPresent()) {
return existingUser.get();
}
// 如果没有找到,返回一个空的对象
return new LoginInfoResult();
} catch (Exception e) {
System.err.println("获取用户设置信息失败: " + e.getMessage());
return new LoginInfoResult();
}
}
}