Files
vf_react/src/views/Community/components/HeroPanel/columns/renderers.js
zdl e070df5d62 refactor(HeroPanel): 提取表格列定义到 columns 目录
- 新增 renderers.js 通用渲染函数
- 新增 stockColumns.js 事件关联股票列
- 新增 sectorColumns.js 涨停板块列
- 新增 ztStockColumns.js 涨停个股列
- 新增 eventColumns.js 未来事件列
- 使用工厂函数模式,支持 useMemo 缓存

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-13 19:00:42 +08:00

185 lines
3.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// HeroPanel 表格列渲染器
import { Tag, Space, Button, Typography, Tooltip } from "antd";
import {
ClockCircleOutlined,
LinkOutlined,
RobotOutlined,
StockOutlined,
StarFilled,
StarOutlined,
LineChartOutlined,
} from "@ant-design/icons";
import dayjs from "dayjs";
const { Text: AntText } = Typography;
/**
* 渲染星级评分
*/
export const renderStars = (star) => {
const level = parseInt(star, 10) || 0;
return (
<span>
{[1, 2, 3, 4, 5].map((i) => (
<span
key={i}
style={{
color: i <= level ? "#faad14" : "#d9d9d9",
fontSize: "14px",
}}
>
</span>
))}
</span>
);
};
/**
* 渲染涨跌幅
*/
export const renderChangePercent = (val) => {
if (val === null || val === undefined) return "-";
const num = parseFloat(val);
const color = num > 0 ? "#ff4d4f" : num < 0 ? "#52c41a" : "#888";
const prefix = num > 0 ? "+" : "";
return (
<span style={{ color, fontWeight: 600 }}>
{prefix}{num.toFixed(2)}%
</span>
);
};
/**
* 渲染时间
*/
export const renderTime = (time) => (
<Space>
<ClockCircleOutlined />
<AntText>{dayjs(time).format("HH:mm")}</AntText>
</Space>
);
/**
* 渲染标题带tooltip
*/
export const renderTitle = (text) => (
<Tooltip title={text}>
<AntText strong style={{ fontSize: "14px" }}>
{text}
</AntText>
</Tooltip>
);
/**
* 渲染排名样式
*/
export const getRankStyle = (index) => {
if (index === 0) {
return {
background: "linear-gradient(135deg, #FFD700 0%, #FFA500 100%)",
color: "#000",
};
}
if (index === 1) {
return {
background: "linear-gradient(135deg, #C0C0C0 0%, #A9A9A9 100%)",
color: "#000",
};
}
if (index === 2) {
return {
background: "linear-gradient(135deg, #CD7F32 0%, #8B4513 100%)",
color: "#fff",
};
}
return {
background: "rgba(255, 255, 255, 0.08)",
color: "#888",
};
};
/**
* 渲染排名徽章
*/
export const renderRankBadge = (index) => {
const style = getRankStyle(index);
return (
<div
style={{
display: "inline-flex",
alignItems: "center",
justifyContent: "center",
width: 24,
height: 24,
borderRadius: "50%",
fontSize: 12,
fontWeight: "bold",
...style,
}}
>
{index + 1}
</div>
);
};
/**
* 创建查看按钮渲染器
*/
export const createViewButtonRenderer = (onClick, iconType = "link") => {
const icons = {
link: <LinkOutlined />,
robot: <RobotOutlined />,
stock: <StockOutlined />,
chart: <LineChartOutlined />,
};
return (text, record) => (
<Button
type="link"
size="small"
icon={icons[iconType] || icons.link}
onClick={() => onClick(text, record)}
disabled={!text}
>
{text ? "查看" : "无"}
</Button>
);
};
/**
* 创建自选按钮渲染器
*/
export const createWatchlistButtonRenderer = (isInWatchlist, onAdd) => {
return (_, record) => {
const inWatchlist = isInWatchlist(record.code);
return (
<Button
type={inWatchlist ? "primary" : "default"}
size="small"
icon={inWatchlist ? <StarFilled /> : <StarOutlined />}
onClick={() => onAdd(record)}
disabled={inWatchlist}
>
{inWatchlist ? "已添加" : "加自选"}
</Button>
);
};
};
/**
* 创建K线按钮渲染器
*/
export const createKlineButtonRenderer = (showKline) => {
return (_, record) => (
<Button
type="primary"
size="small"
icon={<LineChartOutlined />}
onClick={() => showKline(record)}
>
查看
</Button>
);
};