223 lines
7.1 KiB
HTML
223 lines
7.1 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>指数行情 - 价值投资盯盘系统</title>
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.2/font/bootstrap-icons.css">
|
|
<style>
|
|
body {
|
|
background-color: #f8f9fa;
|
|
}
|
|
.navbar {
|
|
background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
|
|
height: 50px;
|
|
padding: 0;
|
|
}
|
|
.navbar-brand {
|
|
color: white;
|
|
font-size: 16px;
|
|
text-decoration: none;
|
|
margin-right: 50px;
|
|
}
|
|
.navbar-nav {
|
|
display: flex;
|
|
list-style: none;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
.nav-item {
|
|
margin-right: 30px;
|
|
}
|
|
.nav-link {
|
|
color: white !important;
|
|
text-decoration: none;
|
|
font-size: 14px;
|
|
line-height: 50px;
|
|
padding: 0;
|
|
}
|
|
.nav-link.active {
|
|
font-weight: bold;
|
|
}
|
|
.iconfont {
|
|
font-size: 14px;
|
|
margin-right: 4px;
|
|
}
|
|
.index-container {
|
|
padding: 20px;
|
|
}
|
|
.index-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
|
gap: 20px;
|
|
margin: 0 auto;
|
|
max-width: 1400px;
|
|
}
|
|
.index-card {
|
|
background: white;
|
|
border-radius: 12px;
|
|
padding: 20px;
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
}
|
|
.index-name {
|
|
font-size: 18px;
|
|
font-weight: 600;
|
|
margin-bottom: 10px;
|
|
color: #1e3c72;
|
|
}
|
|
.index-price {
|
|
font-size: 24px;
|
|
font-weight: bold;
|
|
}
|
|
.index-change {
|
|
font-size: 14px;
|
|
padding: 4px 10px;
|
|
border-radius: 6px;
|
|
background: rgba(0,0,0,0.05);
|
|
}
|
|
.index-chart {
|
|
width: 100%;
|
|
height: 200px;
|
|
margin-top: 15px;
|
|
}
|
|
.positive-value {
|
|
color: #28a745;
|
|
}
|
|
.negative-value {
|
|
color: #dc3545;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<nav class="navbar navbar-expand navbar-dark">
|
|
<div class="container">
|
|
<span class="navbar-brand">
|
|
<i class="bi bi-graph-up"></i>
|
|
价值投资盯盘系统
|
|
</span>
|
|
<div class="navbar-nav">
|
|
<a class="nav-link" href="/">监控列表</a>
|
|
<a class="nav-link active" href="/market">指数行情</a>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<div class="index-container">
|
|
<div class="index-grid" id="indexList">
|
|
<!-- 指数数据将通过JavaScript动态添加 -->
|
|
</div>
|
|
</div>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
|
|
<script>
|
|
// 获取指数数据
|
|
async function refreshIndexData() {
|
|
try {
|
|
const response = await fetch('/api/index_info');
|
|
const data = await response.json();
|
|
updateIndexDisplay(data);
|
|
} catch (error) {
|
|
console.error('获取指数数据失败:', error);
|
|
}
|
|
}
|
|
|
|
// 更新指数显示
|
|
function updateIndexDisplay(indexData) {
|
|
const indexList = document.getElementById('indexList');
|
|
indexList.innerHTML = '';
|
|
|
|
indexData.forEach(index => {
|
|
const card = document.createElement('div');
|
|
card.className = 'index-card';
|
|
|
|
const changeClass = index.change >= 0 ? 'positive-value' : 'negative-value';
|
|
const changeSign = index.change >= 0 ? '+' : '';
|
|
|
|
card.innerHTML = `
|
|
<div class="index-name">${index.name}</div>
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div class="index-price">${index.price.toFixed(2)}</div>
|
|
<div class="index-change ${changeClass}">${changeSign}${index.change.toFixed(2)}%</div>
|
|
</div>
|
|
<div class="index-chart" id="chart_${index.code.replace('.', '_')}"></div>
|
|
`;
|
|
|
|
indexList.appendChild(card);
|
|
|
|
// 创建K线图
|
|
setTimeout(() => {
|
|
createKlineChart(index.code, index.kline_data);
|
|
}, 0);
|
|
});
|
|
}
|
|
|
|
// 创建K线图
|
|
function createKlineChart(code, klineData) {
|
|
const chartDom = document.getElementById(`chart_${code.replace('.', '_')}`);
|
|
const myChart = echarts.init(chartDom);
|
|
|
|
const dates = klineData.map(item => item.date);
|
|
const data = klineData.map(item => [item.open, item.close, item.low, item.high]);
|
|
|
|
const option = {
|
|
animation: false,
|
|
grid: {
|
|
left: '8%',
|
|
right: '8%',
|
|
top: '10%',
|
|
bottom: '10%'
|
|
},
|
|
xAxis: {
|
|
type: 'category',
|
|
data: dates,
|
|
axisLine: {
|
|
lineStyle: {
|
|
color: '#ddd'
|
|
}
|
|
},
|
|
axisLabel: {
|
|
formatter: value => value.substring(4),
|
|
color: '#666'
|
|
}
|
|
},
|
|
yAxis: {
|
|
type: 'value',
|
|
scale: true,
|
|
splitLine: {
|
|
lineStyle: {
|
|
color: '#eee'
|
|
}
|
|
},
|
|
axisLabel: {
|
|
color: '#666'
|
|
}
|
|
},
|
|
series: [{
|
|
type: 'candlestick',
|
|
data: data,
|
|
itemStyle: {
|
|
color: '#ef5350',
|
|
color0: '#26a69a',
|
|
borderColor: '#ef5350',
|
|
borderColor0: '#26a69a'
|
|
}
|
|
}]
|
|
};
|
|
|
|
myChart.setOption(option);
|
|
|
|
// 监听窗口大小变化
|
|
window.addEventListener('resize', () => {
|
|
myChart.resize();
|
|
});
|
|
}
|
|
|
|
// 页面加载时获取数据
|
|
document.addEventListener('DOMContentLoaded', refreshIndexData);
|
|
// 每分钟更新一次数据
|
|
setInterval(refreshIndexData, 60000);
|
|
</script>
|
|
</body>
|
|
</html> |