/**
* 关联描述组件
*
* 用于显示股票与事件的关联描述信息
* 固定标题为"关联描述:"
* 自动处理多种数据格式(字符串、对象数组)
* 支持悬停显示来源信息
*
* @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 && ';'}
))}
)}
);
};