Browse Source

feat(stock): 添加股票信息获取功能并集成到网站页面

- 新增 getStockInfo 函数用于获取股票数据,默认显示睿能科技股票信息
- 新增 fetchStockFromSina 函数从新浪财经接口获取实时股票数据
- 在 footer 组件中添加股票价格和涨跌幅动态显示功能
- 在投资页面中集成股票信息展示模块,包括价格、涨跌、高低、成交量等指标
- 添加页面定时刷新机制确保股票数据及时更新
- 实现股票涨跌颜色动态变色功能
- 集成缓存机制减少接口请求频率,提升性能
master
zhangf@suq.cn 2 weeks ago
parent
commit
84f1bf69ca
  1. 103
      app/common.php
  2. 45
      public/themes/website/1/zh/demo/components/footer.html
  3. 30
      public/themes/website/1/zh/demo/investment.html

103
app/common.php

@ -1731,3 +1731,106 @@ if (!function_exists('getDescriptionSeparate')) {
}
}
}
/**
* 获取股票信息
* @param string $stockCode 股票代码
* @return array 股票数据
*/
if (!function_exists('getStockInfo')) {
function getStockInfo(string $stockCode = '603933'): array
{
// 默认返回数据
$defaultData = [
'code' => $stockCode,
'name' => '睿能科技',
'price' => '--',
'change' => '--',
'changePercent' => '--',
'high' => '--',
'low' => '--',
'volume' => '--',
'amount' => '--',
'updateTime' => date('Y-m-d H:i:s')
];
try {
// 尝试从缓存获取
$cacheKey = 'stock_info_' . $stockCode;
$cached = \think\facade\Cache::get($cacheKey);
if (!empty($cached)) {
return $cached;
}
// 从新浪财经获取数据
$data = fetchStockFromSina($stockCode);
if ($data) {
// 缓存14分50秒
\think\facade\Cache::set($cacheKey, $data, 60*15-10);
return $data;
}
return $defaultData;
} catch (\Exception $e) {
return $defaultData;
}
}
}
/**
* 从新浪财经获取股票数据
* @param string $stockCode 股票代码
* @return array|null
*/
if (!function_exists('fetchStockFromSina')) {
function fetchStockFromSina(string $stockCode): ?array
{
$market = substr($stockCode, 0, 1) == '6' ? 'sh' : 'sz';
$url = "https://hq.sinajs.cn/list={$market}{$stockCode}";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Referer: https://finance.sina.com.cn'
]);
$response = curl_exec($ch);
curl_close($ch);
if (empty($response)) {
return null;
}
// 解析新浪数据格式:var hq_str_sh603933="名称,开盘价,昨收,当前价,最高,最低,...";
if (preg_match('/="(.+)"/', $response, $matches)) {
$fields = explode(',', $matches[1]);
if (count($fields) >= 32) {
$price = floatval($fields[3]);
$prevClose = floatval($fields[2]);
$change = round($price - $prevClose, 2);
$changePercent = $prevClose > 0 ? round(($change / $prevClose) * 100, 2) : 0;
return [
'code' => $stockCode,
'name' => $fields[0],
'price' => $price > 0 ? number_format($price, 2) : '--',
'change' => $price > 0 ? (($change >= 0 ? '+' : '') . number_format($change, 2)) : '--',
'changePercent' => $price > 0 ? (($changePercent >= 0 ? '+' : '') . number_format($changePercent, 2) . '%') : '--',
'high' => floatval($fields[4]) > 0 ? number_format(floatval($fields[4]), 2) : '--',
'low' => floatval($fields[5]) > 0 ? number_format(floatval($fields[5]), 2) : '--',
'volume' => floatval($fields[8]) > 0 ? round(floatval($fields[8]) / 10000, 2) : '--',
'amount' => floatval($fields[9]) > 0 ? round(floatval($fields[9]) / 10000, 2) : '--',
'updateTime' => $fields[30] . ' ' . $fields[31]
];
}
}
return null;
}
}

45
public/themes/website/1/zh/demo/components/footer.html

@ -7,10 +7,11 @@
<img src="{hcTaglib:setting name='dark_logo' type='2' /}" alt="RAYNEN 睿能科技" width="252" height="26" />
</div>
<p class="site-footer__stock">股票代码: 603933</p>
<p class="site-footer__quote" aria-label="股票行情占位">
<span class="site-footer__quote-price">20.34</span>
<span class="site-footer__quote-price">{$stockInfo.price}</span>
<span class="site-footer__quote-unit"></span>
<span class="site-footer__quote-change">+2.34 +9.99%</span>
<span class="site-footer__quote-change">{$stockInfo.change}&nbsp;&nbsp;{$stockInfo.changePercent}</span>
</p>
<p class="site-footer__follow">关注我们:</p>
<div class="site-footer__qrs">
@ -57,4 +58,42 @@
</div>
</div>
</div>
</footer>
</footer>
<script>
(function() {
// 股票数据刷新 - 使用页面内嵌数据,定时刷新整个页面
var refreshInterval = 60000*15; // 1分钟
var stockTimer = null;
// 定时刷新页面
function startStockRefresh() {
stockTimer = setInterval(function() {
// 重新加载当前页面
window.location.reload();
}, refreshInterval);
}
// 页面加载完成后开始
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', startStockRefresh);
} else {
startStockRefresh();
}
// 页面可见性变化时处理
document.addEventListener('visibilitychange', function() {
if (document.hidden) {
// 页面隐藏时停止定时器
if (stockTimer) {
clearInterval(stockTimer);
stockTimer = null;
}
} else {
// 页面显示时重新开始
if (!stockTimer) {
startStockRefresh();
}
}
});
})();
</script>

30
public/themes/website/1/zh/demo/investment.html

@ -141,35 +141,49 @@
</section>
{/hcTaglib:category}
{php}
// 获取股票信息
$stockInfo = getStockInfo('603933');
// 判断涨跌颜色
$priceColor = '';
if ($stockInfo['change'] !== '--') {
$changeVal = floatval(str_replace(['+', '-'], '', $stockInfo['change']));
if ($stockInfo['change'][0] === '+') {
$priceColor = 'color: #ef4335'; // 上涨红色
} elseif ($stockInfo['change'][0] === '-') {
$priceColor = 'color: #00b894'; // 下跌绿色
}
}
{/php}
<section class="iv-stock section__wrap" id="stock" data-header-dark>
<h2 class="iv-stock__title">股票信息</h2>
<div class="iv-stock__body">
<div class="iv-stock__data">
<p class="iv-stock__code">股票代码:603933</p>
<p class="iv-stock__code">股票代码:{$stockInfo.code}</p>
<div class="iv-stock__quote">
<span class="iv-stock__price">20.98</span>
<span class="iv-stock__price" id="stock-price" style="{$priceColor}">{$stockInfo.price}</span>
<span class="iv-stock__unit"></span>
<span class="iv-stock__change">+0.37&nbsp;&nbsp;+1.75%</span>
<span class="iv-stock__change" id="stock-change" style="{$priceColor}">{$stockInfo.change}&nbsp;&nbsp;{$stockInfo.changePercent}</span>
</div>
<ul class="iv-stock__metrics">
<li>
<span class="iv-stock__metric-label">最高(元)</span>
<strong class="iv-stock__metric-value">20.98</strong>
<strong class="iv-stock__metric-value" id="stock-high">{$stockInfo.high}</strong>
</li>
<li>
<span class="iv-stock__metric-label">最低(元)</span>
<strong class="iv-stock__metric-value">20.23</strong>
<strong class="iv-stock__metric-value" id="stock-low">{$stockInfo.low}</strong>
</li>
<li>
<span class="iv-stock__metric-label">成交量(万手)</span>
<strong class="iv-stock__metric-value">3.25</strong>
<strong class="iv-stock__metric-value" id="stock-volume">{$stockInfo.volume}</strong>
</li>
<li>
<span class="iv-stock__metric-label">成交额(万元)</span>
<strong class="iv-stock__metric-value">6684.00</strong>
<strong class="iv-stock__metric-value" id="stock-amount">{$stockInfo.amount}</strong>
</li>
</ul>
<p class="iv-stock__note">截止 2026-08-14 09:40:31*报价有十五分钟或以上延迟。</p>
<p class="iv-stock__note" id="stock-time">截止 {$stockInfo.updateTime}*报价有十五分钟或以上延迟。</p>
</div>
<div class="iv-stock__chart">
<img src="/themes/dist_static/static/images/section-3-img-CK6u5Hdw.png" alt="股票走势图" width="720" height="450" />

Loading…
Cancel
Save