/** * 关联描述组件 * * 用于显示股票与事件的关联描述信息 * 固定标题为"关联描述:" * 自动处理多种数据格式(字符串、对象数组) * 支持悬停显示来源信息 * * @example * ```tsx * // 基础使用 - 传入原始 relation_desc 数据 * * * // 自定义样式 * * ``` */ import React, { useMemo } from 'react'; import { Box, Text, BoxProps, Tooltip } from '@chakra-ui/react'; /** * 关联描述数据项类型 */ export interface RelationDescItem { query_part?: string; sentences?: string; organization?: string; report_title?: string; declare_date?: string; author?: string; match_score?: string; } /** * 关联描述数据类型 * - 字符串格式:直接的描述文本 * - 对象格式:包含多个句子的数组 */ export type RelationDescType = | string | { data: Array; } | null | undefined; export interface RelationDescriptionProps { /** 原始关联描述数据(支持字符串或对象格式) */ relationDesc: RelationDescType; /** 字体大小,默认 'sm' */ fontSize?: string; /** 标题颜色,默认 'gray.700' */ titleColor?: string; /** 文本颜色,默认 'gray.600' */ textColor?: string; /** 行高,默认 '1.7' */ lineHeight?: string; /** 容器额外属性 */ containerProps?: BoxProps; } export const RelationDescription: React.FC = ({ relationDesc, fontSize = 'sm', titleColor = 'gray.700', textColor = 'gray.600', lineHeight = '1.7', containerProps = {} }) => { // 判断是否为对象格式(带来源信息) const isObjectFormat = useMemo(() => { return typeof relationDesc === 'object' && relationDesc?.data && Array.isArray(relationDesc.data); }, [relationDesc]); // 处理关联描述数据 const descData = useMemo(() => { if (!relationDesc) return null; // 字符串格式:直接返回 if (typeof relationDesc === 'string') { return { type: 'string' as const, content: relationDesc }; } // 对象格式:返回数据数组 if (isObjectFormat && relationDesc && typeof relationDesc === 'object') { const items = relationDesc.data.filter((item) => item.query_part); if (items.length === 0) return null; return { type: 'array' as const, items }; } return null; }, [relationDesc, isObjectFormat]); // 如果没有有效的描述内容,不渲染组件 if (!descData) { return null; } // 格式化日期 const formatDate = (dateStr?: string) => { if (!dateStr) return ''; try { return new Date(dateStr).toLocaleDateString('zh-CN'); } catch { return dateStr; } }; return ( 关联描述: {descData.type === 'string' ? ( {descData.content} ) : ( {descData.items.map((item, index, arr) => ( {item.sentences && ( {item.sentences} )} 来源:{item.organization || '未知'} {item.report_title && ( {item.report_title} )} {item.declare_date && ( {formatDate(item.declare_date)} )} } placement="top" hasArrow bg="rgba(20, 20, 20, 0.95)" maxW="420px" > {item.query_part} {index < arr.length - 1 && ';'} ))} )} ); };