diff --git a/webapp/packages/chat-sdk/src/components/ChatItem/index.tsx b/webapp/packages/chat-sdk/src/components/ChatItem/index.tsx index 9c7573503..a04120940 100644 --- a/webapp/packages/chat-sdk/src/components/ChatItem/index.tsx +++ b/webapp/packages/chat-sdk/src/components/ChatItem/index.tsx @@ -9,10 +9,10 @@ import { RangeValue, SimilarQuestionType, } from '../../common/type'; -import { useEffect, useState } from 'react'; +import { createContext, useEffect, useRef, useState } from 'react'; import { chatExecute, chatParse, queryData, deleteQuery, switchEntity } from '../../service'; import { PARSE_ERROR_TIP, PREFIX_CLS, SEARCH_EXCEPTION_TIP } from '../../common/constants'; -import { Spin } from 'antd'; +import { message, Spin } from 'antd'; import IconFont from '../IconFont'; import ExpandParseTip from './ExpandParseTip'; import ParseTip from './ParseTip'; @@ -25,6 +25,7 @@ import SimilarQuestionItem from './SimilarQuestionItem'; import { AgentType } from '../../Chat/type'; import dayjs, { Dayjs } from 'dayjs'; import { exportCsvFile } from '../../utils/utils'; +import { useMethodRegister } from '../../hooks'; type Props = { msg: string; @@ -51,6 +52,11 @@ type Props = { onSendMsg?: (msg: string) => void; }; +export const ChartItemContext = createContext({ + register: (...args: any[]) => {}, + call: (...args: any[]) => {}, +}); + const ChatItem: React.FC = ({ msg, conversationId, @@ -433,126 +439,135 @@ const ChatItem: React.FC = ({ const { llmReq, llmResp } = parseInfo?.properties?.CONTEXT || {}; + const { register, call } = useMethodRegister(() => message.error('该条消息暂不支持该操作')); + return ( -
- {!isMobile && } -
-
- {parseTimeCost?.parseStartTime - ? dayjs(parseTimeCost.parseStartTime).format('M月D日 HH:mm') - : ''} -
-
- <> - {currentAgent?.enableFeedback === 1 && !questionId && showExpandParseTip && ( -
- +
+ {!isMobile && } +
+
+ {parseTimeCost?.parseStartTime + ? dayjs(parseTimeCost.parseStartTime).format('M月D日 HH:mm') + : ''} +
+
+ <> + {currentAgent?.enableFeedback === 1 && !questionId && showExpandParseTip && ( +
+ +
+ )} + + {!preParseMode && ( + { + onRefresh(); + }} handlePresetClick={handlePresetClick} /> -
- )} + )} + - {!preParseMode && ( - { - onRefresh(); - }} - handlePresetClick={handlePresetClick} - /> - )} - - - {executeMode && ( - -
- {!isMobile && parseInfo?.sqlInfo && isDeveloper && isDebugMode && !isSimpleMode && ( - +
+ {!isMobile && + parseInfo?.sqlInfo && + isDeveloper && + isDebugMode && + !isSimpleMode && ( + + )} + - )} - + + )} + {executeMode && + !executeLoading && + !isSimpleMode && + parseInfo?.queryMode !== 'PLAIN_TEXT' && ( + -
- - )} - {executeMode && - !executeLoading && - !isSimpleMode && + )} +
+ {(parseTip !== '' || (executeMode && !executeLoading)) && parseInfo?.queryMode !== 'PLAIN_TEXT' && ( - { + onExportData(); + }} + isSimpleMode={isSimpleMode} + onReExecute={queryId => { + deleteQueryInfo(queryId); + }} /> )}
- {(parseTip !== '' || (executeMode && !executeLoading)) && - parseInfo?.queryMode !== 'PLAIN_TEXT' && ( - { - onExportData(); - }} - onReExecute={queryId => { - deleteQueryInfo(queryId); - }} - /> - )}
-
+ ); }; diff --git a/webapp/packages/chat-sdk/src/components/ChatMsg/Bar/index.tsx b/webapp/packages/chat-sdk/src/components/ChatMsg/Bar/index.tsx index c3898a480..df49e877e 100644 --- a/webapp/packages/chat-sdk/src/components/ChatMsg/Bar/index.tsx +++ b/webapp/packages/chat-sdk/src/components/ChatMsg/Bar/index.tsx @@ -7,10 +7,19 @@ import { } from '../../../utils/utils'; import type { ECharts } from 'echarts'; import * as echarts from 'echarts'; -import React, { useEffect, useRef, useState } from 'react'; +import { + forwardRef, + ForwardRefRenderFunction, + useContext, + useEffect, + useImperativeHandle, + useRef, +} from 'react'; import NoPermissionChart from '../NoPermissionChart'; import { ColumnType } from '../../../common/type'; import { Spin } from 'antd'; +import { ChartItemContext } from '../../ChatItem'; +import { useExportByEcharts } from '../../../hooks'; type Props = { data: MsgDataType; @@ -30,7 +39,7 @@ const BarChart: React.FC = ({ onApplyAuth, }) => { const chartRef = useRef(); - const [instance, setInstance] = useState(); + const instanceRef = useRef(); const { queryColumns, queryResults, entityInfo } = data; @@ -41,11 +50,11 @@ const BarChart: React.FC = ({ const renderChart = () => { let instanceObj: any; - if (!instance) { + if (!instanceRef.current) { instanceObj = echarts.init(chartRef.current); - setInstance(instanceObj); + instanceRef.current = instanceObj; } else { - instanceObj = instance; + instanceObj = instanceRef.current; } const data = (queryResults || []).sort( (a: any, b: any) => b[metricColumnName] - a[metricColumnName] @@ -163,8 +172,8 @@ const BarChart: React.FC = ({ }, [queryResults]); useEffect(() => { - if (triggerResize && instance) { - instance.resize(); + if (triggerResize && instanceRef.current) { + instanceRef.current.resize(); } }, [triggerResize]); @@ -180,6 +189,15 @@ const BarChart: React.FC = ({ const prefixCls = `${PREFIX_CLS}-bar`; + const { downloadChartAsImage } = useExportByEcharts({ + instanceRef, + question, + }); + + const { register } = useContext(ChartItemContext); + + register('downloadChartAsImage', downloadChartAsImage); + return (
diff --git a/webapp/packages/chat-sdk/src/components/ChatMsg/MetricTrend/MetricTrendChart.tsx b/webapp/packages/chat-sdk/src/components/ChatMsg/MetricTrend/MetricTrendChart.tsx index ecd846073..b25a7ea50 100644 --- a/webapp/packages/chat-sdk/src/components/ChatMsg/MetricTrend/MetricTrendChart.tsx +++ b/webapp/packages/chat-sdk/src/components/ChatMsg/MetricTrend/MetricTrendChart.tsx @@ -8,12 +8,14 @@ import { } from '../../../utils/utils'; import type { ECharts } from 'echarts'; import * as echarts from 'echarts'; -import React, { useEffect, useRef, useState } from 'react'; +import React, { useContext, useEffect, useRef, useState } from 'react'; import moment from 'moment'; import { ColumnType } from '../../../common/type'; import NoPermissionChart from '../NoPermissionChart'; import classNames from 'classnames'; import { isArray } from 'lodash'; +import { useExportByEcharts } from '../../../hooks'; +import { ChartItemContext } from '../../ChatItem'; type Props = { model?: string; @@ -37,15 +39,15 @@ const MetricTrendChart: React.FC = ({ chartType, }) => { const chartRef = useRef(); - const [instance, setInstance] = useState(); + const instanceRef = useRef(); const renderChart = () => { let instanceObj: any; - if (!instance) { + if (!instanceRef.current) { instanceObj = echarts.init(chartRef.current); - setInstance(instanceObj); + instanceRef.current = instanceObj; } else { - instanceObj = instance; + instanceObj = instanceRef.current; instanceObj.clear(); } @@ -195,6 +197,15 @@ const MetricTrendChart: React.FC = ({ instanceObj.resize(); }; + const { downloadChartAsImage } = useExportByEcharts({ + instanceRef, + question: metricField.name, + }); + + const { register } = useContext(ChartItemContext); + + register('downloadChartAsImage', downloadChartAsImage); + useEffect(() => { if (metricField.authorized) { renderChart(); @@ -202,8 +213,8 @@ const MetricTrendChart: React.FC = ({ }, [resultList, metricField, chartType]); useEffect(() => { - if (triggerResize && instance) { - instance.resize(); + if (triggerResize && instanceRef.current) { + instanceRef.current.resize(); } }, [triggerResize]); diff --git a/webapp/packages/chat-sdk/src/components/ChatMsg/MetricTrend/MultiMetricsTrendChart.tsx b/webapp/packages/chat-sdk/src/components/ChatMsg/MetricTrend/MultiMetricsTrendChart.tsx index fabf3ed89..e7ba2b901 100644 --- a/webapp/packages/chat-sdk/src/components/ChatMsg/MetricTrend/MultiMetricsTrendChart.tsx +++ b/webapp/packages/chat-sdk/src/components/ChatMsg/MetricTrend/MultiMetricsTrendChart.tsx @@ -2,10 +2,12 @@ import { CHART_SECONDARY_COLOR, CLS_PREFIX, THEME_COLOR_LIST } from '../../../co import { getFormattedValue } from '../../../utils/utils'; import type { ECharts } from 'echarts'; import * as echarts from 'echarts'; -import React, { useEffect, useRef, useState } from 'react'; +import React, { useContext, useEffect, useRef, useState } from 'react'; import moment from 'moment'; import { ColumnType } from '../../../common/type'; import { isArray } from 'lodash'; +import { ChartItemContext } from '../../ChatItem'; +import { useExportByEcharts } from '../../../hooks'; type Props = { dateColumnName: string; @@ -13,6 +15,7 @@ type Props = { resultList: any[]; triggerResize?: boolean; chartType?: string; + question: string; }; const MultiMetricsTrendChart: React.FC = ({ @@ -21,17 +24,17 @@ const MultiMetricsTrendChart: React.FC = ({ resultList, triggerResize, chartType, + question, }) => { const chartRef = useRef(); - const [instance, setInstance] = useState(); - + const instanceRef = useRef(); const renderChart = () => { let instanceObj: any; - if (!instance) { + if (!instanceRef.current) { instanceObj = echarts.init(chartRef.current); - setInstance(instanceObj); + instanceRef.current = instanceObj; } else { - instanceObj = instance; + instanceObj = instanceRef.current; instanceObj.clear(); } @@ -132,13 +135,22 @@ const MultiMetricsTrendChart: React.FC = ({ instanceObj.resize(); }; + const { downloadChartAsImage } = useExportByEcharts({ + instanceRef, + question, + }); + + const { register } = useContext(ChartItemContext); + + register('downloadChartAsImage', downloadChartAsImage); + useEffect(() => { renderChart(); }, [resultList, chartType]); useEffect(() => { - if (triggerResize && instance) { - instance.resize(); + if (triggerResize && instanceRef.current) { + instanceRef.current.resize(); } }, [triggerResize]); diff --git a/webapp/packages/chat-sdk/src/components/ChatMsg/MetricTrend/index.tsx b/webapp/packages/chat-sdk/src/components/ChatMsg/MetricTrend/index.tsx index e409a7c42..f75f1b3c5 100644 --- a/webapp/packages/chat-sdk/src/components/ChatMsg/MetricTrend/index.tsx +++ b/webapp/packages/chat-sdk/src/components/ChatMsg/MetricTrend/index.tsx @@ -100,6 +100,7 @@ const MetricTrend: React.FC = ({ void; onReExecute?: (queryId: number) => void; }; @@ -20,6 +29,7 @@ const Tools: React.FC = ({ scoreValue, isLastMessage, isParserError = false, + isSimpleMode = false, onExportData, onReExecute, }) => { @@ -44,6 +54,8 @@ const Tools: React.FC = ({ [`${prefixCls}-feedback-active`]: score === 1, }); + const { call } = useContext(ChartItemContext); + return (
{!isMobile && ( @@ -68,6 +80,18 @@ const Tools: React.FC = ({ 导出数据 + {!isSimpleMode && ( + + )} {isLastMessage && (