heropanel修改

This commit is contained in:
2026-01-09 07:40:21 +08:00
parent 30f6346252
commit eb61f6bc65
2 changed files with 47 additions and 58 deletions

13
app.py
View File

@@ -11306,7 +11306,10 @@ def get_events_effectiveness_stats():
if prev_trading_day: if prev_trading_day:
prev_date_str = prev_trading_day.strftime('%Y%m%d') prev_date_str = prev_trading_day.strftime('%Y%m%d')
# 查询所有 A 股的最新价格(排除指数和北交所 # 查询所有 A 股的最新价格(排除指数)
# 上证股票: 60xxxx.SH (主板), 68xxxx.SH (科创板)
# 深证股票: 00xxxx.SZ (主板), 30xxxx.SZ (创业板)
# 排除: 399xxx.SZ (深证指数), 000xxx.SH (上证指数)
market_price_query = """ market_price_query = """
SELECT SELECT
code, code,
@@ -11314,9 +11317,11 @@ def get_events_effectiveness_stats():
FROM stock_minute FROM stock_minute
WHERE timestamp >= %(start)s WHERE timestamp >= %(start)s
AND timestamp <= %(end)s AND timestamp <= %(end)s
AND (code LIKE '%%.SH' OR code LIKE '%%.SZ') AND (
AND code NOT LIKE '399%%' (code LIKE '6%%.SH') -- 上证主板和科创板
AND code NOT LIKE '000%%' OR (code LIKE '0%%.SZ' AND code NOT LIKE '399%%') -- 深证主板(排除指数)
OR (code LIKE '3%%.SZ' AND code NOT LIKE '399%%') -- 创业板(排除指数)
)
GROUP BY code GROUP BY code
""" """
market_data = client.execute(market_price_query, { market_data = client.execute(market_price_query, {

View File

@@ -69,8 +69,8 @@ const getRateColor = (rate) => {
}; };
/** /**
* 半圆仪表盘组件 - 参考用户提供的设计 * 半圆仪表盘组件 - 使用 SVG 实现渐变弧线
* 使用渐变色:左侧绿色 -> 中间黄色 -> 右侧红色 * 渐变色:左侧绿色 -> 中间黄色 -> 右侧红色
*/ */
const SemiCircleGauge = ({ rate, label, size = 'normal' }) => { const SemiCircleGauge = ({ rate, label, size = 'normal' }) => {
const validRate = Math.min(100, Math.max(0, rate || 0)); const validRate = Math.min(100, Math.max(0, rate || 0));
@@ -79,57 +79,43 @@ const SemiCircleGauge = ({ rate, label, size = 'normal' }) => {
const gaugeColor = getRateColor(validRate); const gaugeColor = getRateColor(validRate);
const isSmall = size === 'small'; const isSmall = size === 'small';
const gaugeWidth = isSmall ? 80 : 100; const svgSize = isSmall ? 80 : 100;
const gaugeHeight = gaugeWidth / 2; const strokeWidth = isSmall ? 6 : 8;
const needleLength = isSmall ? 30 : 38; const radius = (svgSize - strokeWidth) / 2;
const needleLength = isSmall ? 28 : 35;
const gradientId = `gauge-gradient-${label.replace(/\s/g, '-')}`;
// 计算半圆弧的路径(从左到右)
const arcPath = `M ${strokeWidth / 2} ${svgSize / 2} A ${radius} ${radius} 0 0 1 ${svgSize - strokeWidth / 2} ${svgSize / 2}`;
return ( return (
<Box position="relative" w={`${gaugeWidth}px`} h={`${gaugeHeight + 20}px`}> <Box position="relative" w={`${svgSize}px`} h={`${svgSize / 2 + 18}px`}>
{/* 半圆背景(渐变色弧线) */} {/* SVG 半圆弧 */}
<Box <svg
position="absolute" width={svgSize}
bottom="16px" height={svgSize / 2 + 2}
left="0" style={{ position: 'absolute', top: 0, left: 0 }}
w={`${gaugeWidth}px`} >
h={`${gaugeHeight}px`} <defs>
borderTopLeftRadius={`${gaugeHeight}px`} <linearGradient id={gradientId} x1="0%" y1="0%" x2="100%" y2="0%">
borderTopRightRadius={`${gaugeHeight}px`} <stop offset="0%" stopColor="#52C41A" />
bg="transparent" <stop offset="50%" stopColor="#FADB14" />
overflow="hidden" <stop offset="100%" stopColor="#FF4D4F" />
_before={{ </linearGradient>
content: '""', </defs>
position: 'absolute', <path
top: '0', d={arcPath}
left: '0', fill="none"
right: '0', stroke={`url(#${gradientId})`}
bottom: '0', strokeWidth={strokeWidth}
borderTopLeftRadius: `${gaugeHeight}px`, strokeLinecap="round"
borderTopRightRadius: `${gaugeHeight}px`, />
border: `${isSmall ? '6px' : '8px'} solid transparent`, </svg>
borderBottom: 'none',
background: 'linear-gradient(90deg, #52C41A 0%, #FADB14 50%, #FF4D4F 100%) border-box',
mask: 'linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0)',
maskComposite: 'exclude',
WebkitMaskComposite: 'destination-out',
}}
/>
{/* 内部遮罩(让弧线更细) */}
<Box
position="absolute"
bottom="16px"
left={`${isSmall ? 10 : 12}px`}
w={`${gaugeWidth - (isSmall ? 20 : 24)}px`}
h={`${gaugeHeight - (isSmall ? 10 : 12)}px`}
borderTopLeftRadius={`${gaugeHeight - (isSmall ? 10 : 12)}px`}
borderTopRightRadius={`${gaugeHeight - (isSmall ? 10 : 12)}px`}
bg="rgba(17, 24, 39, 0.95)"
/>
{/* 指针 */} {/* 指针 */}
<Box <Box
position="absolute" position="absolute"
bottom="16px" bottom="18px"
left="50%" left="50%"
w="2px" w="2px"
h={`${needleLength}px`} h={`${needleLength}px`}
@@ -144,7 +130,7 @@ const SemiCircleGauge = ({ rate, label, size = 'normal' }) => {
{/* 指针中心点 */} {/* 指针中心点 */}
<Box <Box
position="absolute" position="absolute"
bottom="13px" bottom="15px"
left="50%" left="50%"
transform="translateX(-50%)" transform="translateX(-50%)"
w="6px" w="6px"
@@ -157,21 +143,19 @@ const SemiCircleGauge = ({ rate, label, size = 'normal' }) => {
{/* 刻度标记 */} {/* 刻度标记 */}
<Text <Text
position="absolute" position="absolute"
bottom="16px" bottom="18px"
left="0" left="2px"
fontSize="2xs" fontSize="2xs"
color="gray.600" color="gray.600"
transform="translateX(2px)"
> >
0 0
</Text> </Text>
<Text <Text
position="absolute" position="absolute"
bottom="16px" bottom="18px"
right="0" right="2px"
fontSize="2xs" fontSize="2xs"
color="gray.600" color="gray.600"
transform="translateX(-2px)"
> >
100 100
</Text> </Text>