添加投注定时器脚本
This commit is contained in:
@@ -7,15 +7,21 @@ import * as echarts from 'echarts';
|
|||||||
const input1 = ref('');
|
const input1 = ref('');
|
||||||
const input2 = ref('');
|
const input2 = ref('');
|
||||||
|
|
||||||
|
// 登录模态框数据
|
||||||
|
const loginDialogVisible = ref(false);
|
||||||
|
const isLoggedIn = ref(false);
|
||||||
|
const username = ref('用户名');
|
||||||
|
const accountBalance = ref('账户余额');
|
||||||
|
const loginForm = ref({
|
||||||
|
username: '',
|
||||||
|
password: '',
|
||||||
|
loginUrl: 'https://4701268539-esh.qdk63ayw8g.com'
|
||||||
|
});
|
||||||
|
const loginLoading = ref(false);
|
||||||
|
const loginError = ref('');
|
||||||
|
|
||||||
// 表格数据
|
// 表格数据
|
||||||
const tableData = ref([
|
const tableData = ref([]);
|
||||||
{ id: 1, name: '项目1', value: 120, status: '正常' },
|
|
||||||
{ id: 2, name: '项目2', value: 230, status: '警告' },
|
|
||||||
{ id: 3, name: '项目3', value: 180, status: '正常' },
|
|
||||||
{ id: 4, name: '项目4', value: 90, status: '异常' },
|
|
||||||
{ id: 5, name: '项目5', value: 320, status: '正常' },
|
|
||||||
{ id: 6, name: '项目6', value: 270, status: '警告' },
|
|
||||||
]);
|
|
||||||
const tableLoading = ref(false);
|
const tableLoading = ref(false);
|
||||||
const tableError = ref('');
|
const tableError = ref('');
|
||||||
|
|
||||||
@@ -34,21 +40,34 @@ const chart2 = ref(null);
|
|||||||
|
|
||||||
// 初始化ECharts图表
|
// 初始化ECharts图表
|
||||||
function initCharts() {
|
function initCharts() {
|
||||||
|
console.log('开始初始化图表');
|
||||||
|
console.log('chart1Ref.value:', chart1Ref.value);
|
||||||
|
console.log('chart2Ref.value:', chart2Ref.value);
|
||||||
|
|
||||||
// 初始化图表1
|
// 初始化图表1
|
||||||
if (chart1Ref.value) {
|
if (chart1Ref.value) {
|
||||||
|
console.log('初始化图表1');
|
||||||
chart1.value = echarts.init(chart1Ref.value);
|
chart1.value = echarts.init(chart1Ref.value);
|
||||||
updateChart1();
|
updateChart1();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化图表2
|
// 初始化图表2
|
||||||
if (chart2Ref.value) {
|
if (chart2Ref.value) {
|
||||||
|
console.log('初始化图表2');
|
||||||
chart2.value = echarts.init(chart2Ref.value);
|
chart2.value = echarts.init(chart2Ref.value);
|
||||||
updateChart2();
|
updateChart2();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('图表初始化完成');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新图表1
|
// 更新图表1
|
||||||
function updateChart1() {
|
function updateChart1() {
|
||||||
|
console.log('更新图表1');
|
||||||
|
console.log('chart1.value:', chart1.value);
|
||||||
|
console.log('chartData1.value:', chartData1.value);
|
||||||
|
console.log('chartLabels.value:', chartLabels.value);
|
||||||
|
|
||||||
if (!chart1.value) return;
|
if (!chart1.value) return;
|
||||||
|
|
||||||
const option = {
|
const option = {
|
||||||
@@ -107,11 +126,18 @@ function updateChart1() {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log('设置图表1选项');
|
||||||
chart1.value.setOption(option);
|
chart1.value.setOption(option);
|
||||||
|
console.log('图表1更新完成');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新图表2
|
// 更新图表2
|
||||||
function updateChart2() {
|
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;
|
if (!chart2.value) return;
|
||||||
|
|
||||||
const option = {
|
const option = {
|
||||||
@@ -170,7 +196,9 @@ function updateChart2() {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log('设置图表2选项');
|
||||||
chart2.value.setOption(option);
|
chart2.value.setOption(option);
|
||||||
|
console.log('图表2更新完成');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听窗口大小变化
|
// 监听窗口大小变化
|
||||||
@@ -181,31 +209,54 @@ function handleResize() {
|
|||||||
|
|
||||||
// 从后端获取折线图数据
|
// 从后端获取折线图数据
|
||||||
async function fetchChartData() {
|
async function fetchChartData() {
|
||||||
|
console.log('开始获取图表数据');
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
error.value = '';
|
error.value = '';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 获取折线图1数据
|
// 获取折线图1数据
|
||||||
|
console.log('获取折线图1数据');
|
||||||
const response1 = await axios.get('http://localhost:8080/api/charts/line1');
|
const response1 = await axios.get('http://localhost:8080/api/charts/line1');
|
||||||
|
console.log('折线图1数据响应:', response1.data);
|
||||||
if (response1.data) {
|
if (response1.data) {
|
||||||
chartData1.value = response1.data.data;
|
chartData1.value = response1.data.data || chartData1.value;
|
||||||
chartLabels.value = response1.data.labels;
|
chartLabels.value = response1.data.labels || chartLabels.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取折线图2数据
|
// 获取折线图2数据
|
||||||
|
console.log('获取折线图2数据');
|
||||||
const response2 = await axios.get('http://localhost:8080/api/charts/line2');
|
const response2 = await axios.get('http://localhost:8080/api/charts/line2');
|
||||||
|
console.log('折线图2数据响应:', response2.data);
|
||||||
if (response2.data) {
|
if (response2.data) {
|
||||||
chartData2.value = response2.data.data;
|
chartData2.value = response2.data.data || chartData2.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('图表数据获取完成');
|
||||||
|
console.log('chartData1.value:', chartData1.value);
|
||||||
|
console.log('chartData2.value:', chartData2.value);
|
||||||
|
console.log('chartLabels.value:', chartLabels.value);
|
||||||
|
|
||||||
// 更新图表
|
// 更新图表
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
|
console.log('更新图表数据');
|
||||||
updateChart1();
|
updateChart1();
|
||||||
updateChart2();
|
updateChart2();
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
console.error('获取图表数据失败:', err);
|
||||||
error.value = '获取图表数据失败,请刷新页面重试';
|
error.value = '获取图表数据失败,请刷新页面重试';
|
||||||
console.error('Error fetching chart data:', err);
|
// 使用默认数据
|
||||||
|
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 {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
@@ -243,6 +294,145 @@ onMounted(() => {
|
|||||||
window.addEventListener('resize', handleResize);
|
window.addEventListener('resize', handleResize);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 处理登录
|
||||||
|
async function handleLogin() {
|
||||||
|
loginError.value = '';
|
||||||
|
loginLoading.value = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log('登录信息:', loginForm.value);
|
||||||
|
|
||||||
|
// 验证表单
|
||||||
|
if (!loginForm.value.username || !loginForm.value.password || !loginForm.value.loginUrl) {
|
||||||
|
loginError.value = '请填写完整登录信息';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建登录API地址
|
||||||
|
const loginApiUrl = `http://localhost:8080/api/ocr/saveUserInfo`;
|
||||||
|
console.log('登录API地址:', loginApiUrl);
|
||||||
|
|
||||||
|
// 调用登录API
|
||||||
|
const response = await axios.post(loginApiUrl, {
|
||||||
|
username: loginForm.value.username,
|
||||||
|
password: loginForm.value.password
|
||||||
|
});
|
||||||
|
|
||||||
|
// 处理登录结果
|
||||||
|
if (response.data && response.data.code === 1) {
|
||||||
|
// 登录成功
|
||||||
|
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 = {
|
||||||
|
username: '',
|
||||||
|
password: '',
|
||||||
|
loginUrl: 'https://4701268539-esh.qdk63ayw8g.com'
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('登录成功:', response.data);
|
||||||
|
} else {
|
||||||
|
// 登录失败
|
||||||
|
loginError.value = response.data.message || '登录失败,请检查输入信息';
|
||||||
|
console.error('登录失败:', response.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
loginError.value = '登录失败,请检查网络连接或登录地址';
|
||||||
|
console.error('登录失败:', err);
|
||||||
|
} finally {
|
||||||
|
loginLoading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理退出登录
|
||||||
|
function handleLogout() {
|
||||||
|
console.log('退出登录');
|
||||||
|
isLoggedIn.value = false;
|
||||||
|
// 重置用户名和账户余额
|
||||||
|
username.value = '用户名';
|
||||||
|
accountBalance.value = '账户余额';
|
||||||
|
// 清除登录状态
|
||||||
|
localStorage.removeItem('token');
|
||||||
|
// 这里可以添加其他清理逻辑
|
||||||
|
// 1. 清除用户信息
|
||||||
|
// 2. 重置相关数据
|
||||||
|
// 3. 调用退出登录API(可选)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理确认按钮点击
|
||||||
|
async function handleConfirm() {
|
||||||
|
console.log('确认按钮点击,止盈点:', input1.value, '止亏点:', input2.value);
|
||||||
|
|
||||||
|
// 验证输入
|
||||||
|
if (!input1.value || !input2.value) {
|
||||||
|
alert('请填写完整的止盈止亏点');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 构建提交数据
|
||||||
|
const submitData = {
|
||||||
|
winNum: input1.value,
|
||||||
|
loseNum: input2.value
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('提交数据:', submitData);
|
||||||
|
|
||||||
|
// 调用后端API
|
||||||
|
const response = await axios.post('http://localhost:8080/api/ocr/saveUserInfo', submitData);
|
||||||
|
|
||||||
|
// 处理响应结果
|
||||||
|
if (response.data && response.data.code === 1) {
|
||||||
|
console.log('提交成功:', response.data);
|
||||||
|
alert('设置保存成功');
|
||||||
|
} else {
|
||||||
|
console.error('提交失败:', response.data);
|
||||||
|
alert('设置保存失败: ' + (response.data.message || '未知错误'));
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.error('提交失败:', err);
|
||||||
|
alert('设置保存失败,请检查网络连接');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理停止按钮点击
|
||||||
|
async function handleStop() {
|
||||||
|
console.log('停止按钮点击');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 调用后端停止API
|
||||||
|
const response = await axios.post('http://localhost:8080/api/ocr/saveUserInfo', {
|
||||||
|
onOff: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
// 处理响应结果
|
||||||
|
if (response.data && response.data.code === 1) {
|
||||||
|
console.log('停止成功:', response.data);
|
||||||
|
alert('停止操作成功');
|
||||||
|
} else {
|
||||||
|
console.error('停止失败:', response.data);
|
||||||
|
alert('停止操作失败: ' + (response.data.message || '未知错误'));
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.error('停止失败:', err);
|
||||||
|
alert('停止操作失败,请检查网络连接');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
// 销毁图表
|
// 销毁图表
|
||||||
chart1.value?.dispose();
|
chart1.value?.dispose();
|
||||||
@@ -261,28 +451,65 @@ onUnmounted(() => {
|
|||||||
<div class="account-info">
|
<div class="account-info">
|
||||||
<div class="account-avatar">👤</div>
|
<div class="account-avatar">👤</div>
|
||||||
<div class="account-details">
|
<div class="account-details">
|
||||||
<div class="account-name">用户名</div>
|
<div class="account-name">{{ username }}</div>
|
||||||
<div class="account-role">账户余额</div>
|
<div class="account-role">{{ accountBalance }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="account-actions">
|
<div class="account-actions">
|
||||||
<button type="button" class="login-button">登录</button>
|
<button v-if="!isLoggedIn" type="button" class="login-button" @click="loginDialogVisible = true">登录</button>
|
||||||
<button type="button" class="logout-button">退出</button>
|
<button v-else type="button" class="logout-button" @click="handleLogout">退出</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 登录模态框 -->
|
||||||
|
<div v-if="loginDialogVisible" class="modal-overlay">
|
||||||
|
<div class="modal-content" @click.stop>
|
||||||
|
<div class="modal-header">
|
||||||
|
<h3>登录</h3>
|
||||||
|
<button type="button" class="modal-close" @click="loginDialogVisible = false">×</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div v-if="loginError" class="modal-error">
|
||||||
|
{{ loginError }}
|
||||||
|
</div>
|
||||||
|
<form @submit.prevent="handleLogin">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="username">账号</label>
|
||||||
|
<input type="text" id="username" v-model="loginForm.username" placeholder="请输入账号" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password">密码</label>
|
||||||
|
<input type="password" id="password" v-model="loginForm.password" placeholder="请输入密码" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="loginUrl">登录地址</label>
|
||||||
|
<input type="url" id="loginUrl" v-model="loginForm.loginUrl" placeholder="请输入登录地址" required>
|
||||||
|
</div>
|
||||||
|
<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>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 顶部输入框区域 -->
|
<!-- 顶部输入框区域 -->
|
||||||
<div class="top-inputs">
|
<div class="top-inputs">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<label for="input1">输入1:</label>
|
|
||||||
<div class="input-with-button">
|
<div class="input-with-button">
|
||||||
<input type="text" id="input1" v-model="input1" placeholder="请输入内容">
|
<input type="text" id="input1" v-model="input1" placeholder="请输入止盈点">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<label for="input2">输入2:</label>
|
|
||||||
<div class="input-with-button">
|
<div class="input-with-button">
|
||||||
<input type="text" id="input2" v-model="input2" placeholder="请输入内容">
|
<input type="text" id="input2" v-model="input2" placeholder="请输入止亏点">
|
||||||
<button type="button" class="confirm-button">确认</button>
|
<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>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -354,7 +581,7 @@ onUnmounted(() => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
min-height: 100vh;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
@@ -369,7 +596,6 @@ onUnmounted(() => {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
min-height: 100%;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -512,6 +738,35 @@ onUnmounted(() => {
|
|||||||
transform: translateY(1px);
|
transform: translateY(1px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 按钮组 */
|
||||||
|
.button-group {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 停止按钮 */
|
||||||
|
.stop-button {
|
||||||
|
padding: 10px 16px;
|
||||||
|
background-color: #f44336;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stop-button:hover {
|
||||||
|
background-color: #d32f2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stop-button:active {
|
||||||
|
background-color: #b71c1c;
|
||||||
|
transform: translateY(1px);
|
||||||
|
}
|
||||||
|
|
||||||
/* 表格区域 */
|
/* 表格区域 */
|
||||||
.table-container {
|
.table-container {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@@ -528,18 +783,16 @@ onUnmounted(() => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 30px;
|
gap: 30px;
|
||||||
height: 100%;
|
min-height: 700px;
|
||||||
min-height: 100%;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 图表区域 */
|
/* 图表区域 */
|
||||||
.chart-container {
|
.chart-container {
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 15px;
|
gap: 15px;
|
||||||
min-height: 0;
|
height: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-group label {
|
.input-group label {
|
||||||
@@ -685,6 +938,158 @@ onUnmounted(() => {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 登录模态框 */
|
||||||
|
.modal-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
||||||
|
width: 90%;
|
||||||
|
max-width: 450px;
|
||||||
|
max-height: 80vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20px;
|
||||||
|
border-bottom: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header h3 {
|
||||||
|
margin: 0;
|
||||||
|
color: #333;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-close {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
font-size: 24px;
|
||||||
|
color: #999;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-close:hover {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-body {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-error {
|
||||||
|
background-color: #ffebee;
|
||||||
|
color: #c62828;
|
||||||
|
padding: 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px 12px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
transition: border-color 0.2s ease;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #2196F3;
|
||||||
|
box-shadow: 0 0 0 2px rgba(33, 150, 243, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 12px;
|
||||||
|
margin-top: 30px;
|
||||||
|
padding-top: 20px;
|
||||||
|
border-top: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cancel-button {
|
||||||
|
padding: 10px 20px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
color: #333;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cancel-button:hover {
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-button {
|
||||||
|
padding: 10px 20px;
|
||||||
|
background-color: #2196F3;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-button:hover:not(:disabled) {
|
||||||
|
background-color: #1976D2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-button:active:not(:disabled) {
|
||||||
|
background-color: #1565C0;
|
||||||
|
transform: translateY(1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-button:disabled {
|
||||||
|
background-color: #bdbdbd;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
/* 响应式布局 */
|
/* 响应式布局 */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.main-container {
|
.main-container {
|
||||||
@@ -702,5 +1107,10 @@ onUnmounted(() => {
|
|||||||
.chart-container {
|
.chart-container {
|
||||||
min-height: 300px;
|
min-height: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
width: 95%;
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
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.*;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/lottery")
|
|
||||||
public class LotteryResultController {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private LotteryResultRepository lotteryResultRepository;
|
|
||||||
|
|
||||||
// 获取所有彩票开奖结果
|
|
||||||
@GetMapping("/results")
|
|
||||||
public List<LotteryResult> getAllLotteryResults() {
|
|
||||||
return lotteryResultRepository.findAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 根据期号获取彩票开奖结果
|
|
||||||
@GetMapping("/results/{issue}")
|
|
||||||
public LotteryResult getLotteryResultByIssue(@PathVariable String issue) {
|
|
||||||
return lotteryResultRepository.findAll()
|
|
||||||
.stream()
|
|
||||||
.filter(result -> result.getIssue().equals(issue))
|
|
||||||
.findFirst()
|
|
||||||
.orElse(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package com.tem.bocai.controller;
|
|
||||||
|
|
||||||
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.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
public class TestController {
|
|
||||||
|
|
||||||
|
|
||||||
private final ImageOcrService imageOcrService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public TestController(ImageOcrService imageOcrService) {
|
|
||||||
|
|
||||||
this.imageOcrService = imageOcrService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/ocr/local")
|
|
||||||
public ResponseEntity<String> ocrLocalImage(String imagePath) throws IOException, TesseractException {
|
|
||||||
imagePath = "b.jpg";
|
|
||||||
String result = imageOcrService.ocrLocalImage(imagePath);
|
|
||||||
return ResponseEntity.ok(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/ocr/remote")
|
|
||||||
public ResponseEntity<String> ocrRemoteImage(String imageUrl) throws IOException, TesseractException, InterruptedException {
|
|
||||||
imageUrl = "https://4701268539-esh.qdk63ayw8g.com/code";
|
|
||||||
String result = imageOcrService.ocrRemoteImage();
|
|
||||||
System.out.println("++++"+result);
|
|
||||||
return ResponseEntity.ok(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user