feat: 抽离关联描述组件
This commit is contained in:
@@ -7,6 +7,7 @@ import dayjs from 'dayjs';
|
|||||||
import { stockService } from '../../services/eventService';
|
import { stockService } from '../../services/eventService';
|
||||||
import { logger } from '../../utils/logger';
|
import { logger } from '../../utils/logger';
|
||||||
import RiskDisclaimer from '../RiskDisclaimer';
|
import RiskDisclaimer from '../RiskDisclaimer';
|
||||||
|
import { RelationDescription } from '../StockRelation';
|
||||||
|
|
||||||
const StockChartModal = ({
|
const StockChartModal = ({
|
||||||
isOpen,
|
isOpen,
|
||||||
@@ -24,27 +25,6 @@ const StockChartModal = ({
|
|||||||
const [chartData, setChartData] = useState(null);
|
const [chartData, setChartData] = useState(null);
|
||||||
const [preloadedData, setPreloadedData] = useState({});
|
const [preloadedData, setPreloadedData] = useState({});
|
||||||
|
|
||||||
// 处理关联描述(兼容对象和字符串格式)- 使用 useMemo 缓存计算结果
|
|
||||||
const relationDesc = useMemo(() => {
|
|
||||||
const desc = stock?.relation_desc;
|
|
||||||
|
|
||||||
if (!desc) return null;
|
|
||||||
|
|
||||||
if (typeof desc === 'string') {
|
|
||||||
return desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof desc === 'object' && desc.data && Array.isArray(desc.data)) {
|
|
||||||
// 新格式:{data: [{query_part: "...", sentences: "..."}]}
|
|
||||||
return desc.data
|
|
||||||
.map(item => item.query_part || item.sentences || '')
|
|
||||||
.filter(s => s)
|
|
||||||
.join(';') || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}, [stock?.relation_desc]);
|
|
||||||
|
|
||||||
// 预加载数据
|
// 预加载数据
|
||||||
const preloadData = async (type) => {
|
const preloadData = async (type) => {
|
||||||
if (!stock || preloadedData[type]) return;
|
if (!stock || preloadedData[type]) return;
|
||||||
@@ -563,21 +543,7 @@ const StockChartModal = ({
|
|||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* 关联描述 */}
|
{/* 关联描述 */}
|
||||||
{relationDesc && (
|
<RelationDescription relationDesc={stock?.relation_desc} />
|
||||||
<Box p={4} borderTop="1px solid" borderTopColor="gray.200">
|
|
||||||
<Text fontSize="sm" fontWeight="bold" mb={2} color="gray.700">
|
|
||||||
关联描述:
|
|
||||||
</Text>
|
|
||||||
<Text
|
|
||||||
fontSize="sm"
|
|
||||||
color="gray.600"
|
|
||||||
lineHeight="1.7"
|
|
||||||
whiteSpace="pre-wrap"
|
|
||||||
>
|
|
||||||
{relationDesc}
|
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* 风险提示 */}
|
{/* 风险提示 */}
|
||||||
<Box px={4} pb={4}>
|
<Box px={4} pb={4}>
|
||||||
|
|||||||
121
src/components/StockRelation/RelationDescription.tsx
Normal file
121
src/components/StockRelation/RelationDescription.tsx
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
/**
|
||||||
|
* 关联描述组件
|
||||||
|
*
|
||||||
|
* 用于显示股票与事件的关联描述信息
|
||||||
|
* 固定标题为"关联描述:"
|
||||||
|
* 自动处理多种数据格式(字符串、对象数组)
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```tsx
|
||||||
|
* // 基础使用 - 传入原始 relation_desc 数据
|
||||||
|
* <RelationDescription relationDesc={stock.relation_desc} />
|
||||||
|
*
|
||||||
|
* // 自定义样式
|
||||||
|
* <RelationDescription
|
||||||
|
* relationDesc={stock.relation_desc}
|
||||||
|
* fontSize="md"
|
||||||
|
* titleColor="blue.700"
|
||||||
|
* />
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { useMemo } from 'react';
|
||||||
|
import { Box, Text, BoxProps } from '@chakra-ui/react';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关联描述数据类型
|
||||||
|
* - 字符串格式:直接的描述文本
|
||||||
|
* - 对象格式:包含多个句子的数组
|
||||||
|
*/
|
||||||
|
export type RelationDescType =
|
||||||
|
| string
|
||||||
|
| {
|
||||||
|
data: Array<{
|
||||||
|
query_part?: string;
|
||||||
|
sentences?: string;
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
| 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<RelationDescriptionProps> = ({
|
||||||
|
relationDesc,
|
||||||
|
fontSize = 'sm',
|
||||||
|
titleColor = 'gray.700',
|
||||||
|
textColor = 'gray.600',
|
||||||
|
lineHeight = '1.7',
|
||||||
|
containerProps = {}
|
||||||
|
}) => {
|
||||||
|
// 处理关联描述(兼容对象和字符串格式)
|
||||||
|
const processedDesc = useMemo(() => {
|
||||||
|
if (!relationDesc) return null;
|
||||||
|
|
||||||
|
// 字符串格式:直接返回
|
||||||
|
if (typeof relationDesc === 'string') {
|
||||||
|
return relationDesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对象格式:提取并拼接文本
|
||||||
|
if (typeof relationDesc === 'object' && relationDesc.data && Array.isArray(relationDesc.data)) {
|
||||||
|
return (
|
||||||
|
relationDesc.data
|
||||||
|
.map((item) => item.query_part || item.sentences || '')
|
||||||
|
.filter((s) => s)
|
||||||
|
.join(';') || null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}, [relationDesc]);
|
||||||
|
|
||||||
|
// 如果没有有效的描述内容,不渲染组件
|
||||||
|
if (!processedDesc) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
p={4}
|
||||||
|
borderTop="1px solid"
|
||||||
|
borderTopColor="gray.200"
|
||||||
|
{...containerProps}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
fontSize={fontSize}
|
||||||
|
fontWeight="bold"
|
||||||
|
mb={2}
|
||||||
|
color={titleColor}
|
||||||
|
>
|
||||||
|
关联描述:
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
fontSize={fontSize}
|
||||||
|
color={textColor}
|
||||||
|
lineHeight={lineHeight}
|
||||||
|
whiteSpace="pre-wrap"
|
||||||
|
>
|
||||||
|
{processedDesc}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
6
src/components/StockRelation/index.ts
Normal file
6
src/components/StockRelation/index.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* StockRelation 组件导出入口
|
||||||
|
*/
|
||||||
|
|
||||||
|
export { RelationDescription } from './RelationDescription';
|
||||||
|
export type { RelationDescriptionProps, RelationDescType } from './RelationDescription';
|
||||||
Reference in New Issue
Block a user