prod-test-chat-sdk 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/.prettierrc.js +24 -0
  2. package/README.md +46 -0
  3. package/config/env.js +104 -0
  4. package/config/getHttpsConfig.js +66 -0
  5. package/config/jest/babelTransform.js +29 -0
  6. package/config/jest/cssTransform.js +14 -0
  7. package/config/jest/fileTransform.js +40 -0
  8. package/config/modules.js +134 -0
  9. package/config/paths.js +77 -0
  10. package/config/webpack/persistentCache/createEnvironmentHash.js +9 -0
  11. package/config/webpack.config.js +785 -0
  12. package/config/webpackDevServer.config.js +127 -0
  13. package/dist/Chat/AgentList/index.d.ts +9 -0
  14. package/dist/Chat/ChatFooter/index.d.ts +17 -0
  15. package/dist/Chat/Conversation/index.d.ts +11 -0
  16. package/dist/Chat/MessageContainer/index.d.ts +19 -0
  17. package/dist/Chat/MobileAgents/index.d.ts +11 -0
  18. package/dist/Chat/components/AgentTip/index.d.ts +8 -0
  19. package/dist/Chat/components/ConversationModal/index.d.ts +10 -0
  20. package/dist/Chat/components/CopilotAvatar/index.d.ts +2 -0
  21. package/dist/Chat/components/Message.d.ts +10 -0
  22. package/dist/Chat/components/RecommendQuestions/index.d.ts +6 -0
  23. package/dist/Chat/components/Text.d.ts +9 -0
  24. package/dist/Chat/constants.d.ts +19 -0
  25. package/dist/Chat/index.d.ts +17 -0
  26. package/dist/Chat/service.d.ts +11 -0
  27. package/dist/Chat/type.d.ts +97 -0
  28. package/dist/Copilot/constants.d.ts +11 -0
  29. package/dist/Copilot/index.d.ts +13 -0
  30. package/dist/ShowCase/index.d.ts +8 -0
  31. package/dist/ShowCase/service.d.ts +2 -0
  32. package/dist/ShowCase/type.d.ts +11 -0
  33. package/dist/common/constants.d.ts +58 -0
  34. package/dist/common/env.d.ts +3 -0
  35. package/dist/common/type.d.ts +247 -0
  36. package/dist/components/ChatItem/ExecuteItem.d.ts +25 -0
  37. package/dist/components/ChatItem/ExpandParseTip.d.ts +20 -0
  38. package/dist/components/ChatItem/FilterItem.d.ts +17 -0
  39. package/dist/components/ChatItem/Loading.d.ts +2 -0
  40. package/dist/components/ChatItem/ParseTip.d.ts +26 -0
  41. package/dist/components/ChatItem/ParseTipUtils.d.ts +10 -0
  42. package/dist/components/ChatItem/SimilarQuestionItem.d.ts +10 -0
  43. package/dist/components/ChatItem/SqlItem.d.ts +17 -0
  44. package/dist/components/ChatItem/SwitchEntity.d.ts +9 -0
  45. package/dist/components/ChatItem/Text.d.ts +6 -0
  46. package/dist/components/ChatItem/Typing.d.ts +2 -0
  47. package/dist/components/ChatItem/index.d.ts +33 -0
  48. package/dist/components/ChatMsg/ApplyAuth/index.d.ts +7 -0
  49. package/dist/components/ChatMsg/Bar/index.d.ts +13 -0
  50. package/dist/components/ChatMsg/DateOptions/index.d.ts +9 -0
  51. package/dist/components/ChatMsg/FilterSection/index.d.ts +8 -0
  52. package/dist/components/ChatMsg/MarkDown/index.d.ts +10 -0
  53. package/dist/components/ChatMsg/Message/index.d.ts +18 -0
  54. package/dist/components/ChatMsg/MetricCard/PeriodCompareItem.d.ts +7 -0
  55. package/dist/components/ChatMsg/MetricCard/index.d.ts +10 -0
  56. package/dist/components/ChatMsg/MetricTrend/MetricInfo.d.ts +8 -0
  57. package/dist/components/ChatMsg/MetricTrend/MetricTrendChart.d.ts +14 -0
  58. package/dist/components/ChatMsg/MetricTrend/MultiMetricsTrendChart.d.ts +12 -0
  59. package/dist/components/ChatMsg/MetricTrend/index.d.ts +16 -0
  60. package/dist/components/ChatMsg/NoPermissionChart/index.d.ts +8 -0
  61. package/dist/components/ChatMsg/Pie/PieChart.d.ts +11 -0
  62. package/dist/components/ChatMsg/Pie/index.d.ts +14 -0
  63. package/dist/components/ChatMsg/Table/index.d.ts +12 -0
  64. package/dist/components/ChatMsg/Text/index.d.ts +9 -0
  65. package/dist/components/ChatMsg/WebPage/index.d.ts +8 -0
  66. package/dist/components/ChatMsg/index.d.ts +15 -0
  67. package/dist/components/DrillDownDimensions/DimensionSection.d.ts +11 -0
  68. package/dist/components/DrillDownDimensions/index.d.ts +13 -0
  69. package/dist/components/IconFont/index.d.ts +3 -0
  70. package/dist/components/MetricOptions/index.d.ts +11 -0
  71. package/dist/components/RecommendOptions/index.d.ts +9 -0
  72. package/dist/components/Tools/FeedbackModal.d.ts +9 -0
  73. package/dist/components/Tools/index.d.ts +12 -0
  74. package/dist/demo/Chat.d.ts +2 -0
  75. package/dist/demo/ChatDemo.d.ts +4 -0
  76. package/dist/demo/CopilotDemo.d.ts +2 -0
  77. package/dist/hooks/index.d.ts +3 -0
  78. package/dist/hooks/useComposing.d.ts +5 -0
  79. package/dist/hooks/useExportByEcharts.d.ts +10 -0
  80. package/dist/hooks/useMethodRegister.d.ts +4 -0
  81. package/dist/index.d.ts +10 -0
  82. package/dist/index.es.js +1 -0
  83. package/dist/service/axiosInstance.d.ts +3 -0
  84. package/dist/service/index.d.ts +25 -0
  85. package/dist/utils/utils.d.ts +45 -0
  86. package/package.json +214 -0
  87. package/public/favicon.ico +0 -0
  88. package/public/index.html +43 -0
  89. package/public/manifest.json +15 -0
  90. package/public/robots.txt +3 -0
  91. package/rollup/rollup.config.mjs +37 -0
  92. package/rollup/rollup.esm.config.mjs +21 -0
  93. package/rollup/rollup.umd.config.mjs +30 -0
  94. package/scripts/build.js +217 -0
  95. package/scripts/start.js +154 -0
  96. package/scripts/test.js +52 -0
  97. package/src/Chat/AgentList/index.tsx +52 -0
  98. package/src/Chat/AgentList/style.module.less +83 -0
  99. package/src/Chat/ChatFooter/index.tsx +423 -0
  100. package/src/Chat/ChatFooter/style.module.less +225 -0
  101. package/src/Chat/Conversation/index.tsx +236 -0
  102. package/src/Chat/Conversation/style.module.less +171 -0
  103. package/src/Chat/MessageContainer/index.tsx +145 -0
  104. package/src/Chat/MessageContainer/style.module.less +53 -0
  105. package/src/Chat/MobileAgents/index.tsx +62 -0
  106. package/src/Chat/MobileAgents/style.module.less +55 -0
  107. package/src/Chat/components/AgentTip/index.tsx +48 -0
  108. package/src/Chat/components/AgentTip/style.module.less +44 -0
  109. package/src/Chat/components/ConversationModal/index.tsx +65 -0
  110. package/src/Chat/components/CopilotAvatar/index.tsx +8 -0
  111. package/src/Chat/components/CopilotAvatar/style.module.less +13 -0
  112. package/src/Chat/components/Message.tsx +38 -0
  113. package/src/Chat/components/RecommendQuestions/index.tsx +64 -0
  114. package/src/Chat/components/RecommendQuestions/style.module.less +36 -0
  115. package/src/Chat/components/Text.tsx +42 -0
  116. package/src/Chat/components/style.module.less +311 -0
  117. package/src/Chat/constants.ts +37 -0
  118. package/src/Chat/index.tsx +526 -0
  119. package/src/Chat/service.ts +49 -0
  120. package/src/Chat/style.module.less +119 -0
  121. package/src/Chat/type.ts +107 -0
  122. package/src/Copilot/constants.ts +11 -0
  123. package/src/Copilot/index.tsx +149 -0
  124. package/src/Copilot/style.module.less +151 -0
  125. package/src/ShowCase/index.tsx +120 -0
  126. package/src/ShowCase/service.ts +12 -0
  127. package/src/ShowCase/style.module.less +46 -0
  128. package/src/ShowCase/type.ts +14 -0
  129. package/src/common/constants.ts +93 -0
  130. package/src/common/env.ts +5 -0
  131. package/src/common/type.ts +270 -0
  132. package/src/components/ChatItem/ExecuteItem.tsx +211 -0
  133. package/src/components/ChatItem/ExpandParseTip.tsx +333 -0
  134. package/src/components/ChatItem/FilterItem.tsx +209 -0
  135. package/src/components/ChatItem/Loading.tsx +14 -0
  136. package/src/components/ChatItem/ParseTip.tsx +322 -0
  137. package/src/components/ChatItem/ParseTipUtils.tsx +205 -0
  138. package/src/components/ChatItem/SimilarQuestionItem.tsx +84 -0
  139. package/src/components/ChatItem/SqlItem.tsx +410 -0
  140. package/src/components/ChatItem/SwitchEntity.tsx +52 -0
  141. package/src/components/ChatItem/Text.tsx +17 -0
  142. package/src/components/ChatItem/Typing.tsx +19 -0
  143. package/src/components/ChatItem/index.tsx +843 -0
  144. package/src/components/ChatItem/style.less +670 -0
  145. package/src/components/ChatMsg/ApplyAuth/index.tsx +30 -0
  146. package/src/components/ChatMsg/ApplyAuth/style.less +13 -0
  147. package/src/components/ChatMsg/Bar/index.tsx +223 -0
  148. package/src/components/ChatMsg/Bar/style.less +60 -0
  149. package/src/components/ChatMsg/DateOptions/index.tsx +46 -0
  150. package/src/components/ChatMsg/DateOptions/style.less +43 -0
  151. package/src/components/ChatMsg/FilterSection/index.tsx +42 -0
  152. package/src/components/ChatMsg/FilterSection/style.less +37 -0
  153. package/src/components/ChatMsg/MarkDown/index.tsx +26 -0
  154. package/src/components/ChatMsg/MarkDown/style.less +9 -0
  155. package/src/components/ChatMsg/Message/index.tsx +105 -0
  156. package/src/components/ChatMsg/Message/style.less +119 -0
  157. package/src/components/ChatMsg/MetricCard/PeriodCompareItem.tsx +29 -0
  158. package/src/components/ChatMsg/MetricCard/index.tsx +80 -0
  159. package/src/components/ChatMsg/MetricCard/style.less +126 -0
  160. package/src/components/ChatMsg/MetricTrend/MetricInfo.tsx +60 -0
  161. package/src/components/ChatMsg/MetricTrend/MetricTrendChart.tsx +235 -0
  162. package/src/components/ChatMsg/MetricTrend/MultiMetricsTrendChart.tsx +162 -0
  163. package/src/components/ChatMsg/MetricTrend/index.tsx +127 -0
  164. package/src/components/ChatMsg/MetricTrend/style.less +195 -0
  165. package/src/components/ChatMsg/NoPermissionChart/index.tsx +28 -0
  166. package/src/components/ChatMsg/NoPermissionChart/style.less +26 -0
  167. package/src/components/ChatMsg/Pie/PieChart.tsx +134 -0
  168. package/src/components/ChatMsg/Pie/index.tsx +88 -0
  169. package/src/components/ChatMsg/Pie/style.less +43 -0
  170. package/src/components/ChatMsg/Table/index.tsx +105 -0
  171. package/src/components/ChatMsg/Table/style.less +131 -0
  172. package/src/components/ChatMsg/Text/index.tsx +70 -0
  173. package/src/components/ChatMsg/Text/style.less +38 -0
  174. package/src/components/ChatMsg/WebPage/index.tsx +125 -0
  175. package/src/components/ChatMsg/index.tsx +428 -0
  176. package/src/components/ChatMsg/style.less +28 -0
  177. package/src/components/DrillDownDimensions/DimensionSection.tsx +99 -0
  178. package/src/components/DrillDownDimensions/index.tsx +76 -0
  179. package/src/components/DrillDownDimensions/style.less +64 -0
  180. package/src/components/IconFont/index.tsx +7 -0
  181. package/src/components/MetricOptions/index.tsx +75 -0
  182. package/src/components/MetricOptions/style.less +69 -0
  183. package/src/components/RecommendOptions/index.tsx +126 -0
  184. package/src/components/RecommendOptions/style.less +24 -0
  185. package/src/components/Tools/FeedbackModal.tsx +55 -0
  186. package/src/components/Tools/index.tsx +126 -0
  187. package/src/components/Tools/style.less +67 -0
  188. package/src/demo/Chat.tsx +73 -0
  189. package/src/demo/ChatDemo.tsx +14 -0
  190. package/src/demo/CopilotDemo.tsx +43 -0
  191. package/src/demo/style.module.less +19 -0
  192. package/src/hooks/index.ts +3 -0
  193. package/src/hooks/useComposing.ts +31 -0
  194. package/src/hooks/useExportByEcharts.ts +41 -0
  195. package/src/hooks/useMethodRegister.ts +25 -0
  196. package/src/index.tsx +44 -0
  197. package/src/service/axiosInstance.ts +58 -0
  198. package/src/service/index.ts +174 -0
  199. package/src/setupProxy.js +18 -0
  200. package/src/setupTests.ts +5 -0
  201. package/src/styles/global.less +52 -0
  202. package/src/styles/index.less +39 -0
  203. package/src/styles/reboot.less +14 -0
  204. package/src/styles/variables.less +80 -0
  205. package/src/typings.d.ts +179 -0
  206. package/src/utils/utils.ts +346 -0
  207. package/tsconfig.build.json +20 -0
  208. package/tsconfig.json +27 -0
@@ -0,0 +1,333 @@
1
+ import React, { ReactNode, useState, useEffect } from 'react';
2
+ import { ChatContextType, DateInfoType, EntityInfoType, FilterItemType } from '../../common/type';
3
+ import { Button, DatePicker, Row, Col } from 'antd';
4
+ import { CheckCircleFilled, CloseCircleFilled } from '@ant-design/icons';
5
+ import Loading from './Loading';
6
+ import FilterItem from './FilterItem';
7
+ import classNames from 'classnames';
8
+ import { isMobile } from '../../utils/utils';
9
+ import dayjs, { Dayjs } from 'dayjs';
10
+ import quarterOfYear from 'dayjs/plugin/quarterOfYear';
11
+ import { prefixCls, getTipNode } from './ParseTipUtils';
12
+ import MarkDown from '../ChatMsg/MarkDown';
13
+ import { getDataSetDetail } from '../../service';
14
+
15
+ import 'dayjs/locale/zh-cn';
16
+
17
+ dayjs.extend(quarterOfYear);
18
+ dayjs.locale('zh-cn');
19
+
20
+ const { RangePicker } = DatePicker;
21
+
22
+ type Props = {
23
+ isSimpleMode?: boolean;
24
+ parseInfoOptions: ChatContextType[];
25
+ agentId?: number;
26
+ integrateSystem?: string;
27
+ parseTimeCost?: number;
28
+ isDeveloper?: boolean;
29
+ onSelectParseInfo: (parseInfo: ChatContextType) => void;
30
+ onSwitchEntity: (entityId: string) => void;
31
+ onFiltersChange: (filters: FilterItemType[]) => void;
32
+ onDateInfoChange: (dateRange: any) => void;
33
+ onRefresh: (parseInfo?: ChatContextType) => void;
34
+ handlePresetClick: any;
35
+ setSelectedDataSetIds: (ids: number[]) => void;
36
+ };
37
+
38
+ type RangeValue = [Dayjs, Dayjs];
39
+ type RangeKeys = '近7日' | '近14日' | '近30日' | '本周' | '本月' | '上月' | '本季度' | '本年';
40
+
41
+ const ExpandParseTip: React.FC<Props> = ({
42
+ isSimpleMode = false,
43
+ parseInfoOptions,
44
+ agentId,
45
+ integrateSystem,
46
+ parseTimeCost,
47
+ isDeveloper,
48
+ onSelectParseInfo,
49
+ onSwitchEntity,
50
+ onFiltersChange,
51
+ onDateInfoChange,
52
+ onRefresh,
53
+ handlePresetClick,
54
+ setSelectedDataSetIds,
55
+ }) => {
56
+ const [currentParseInfo, setCurrentParseInfo] = useState<ChatContextType>();
57
+ const [availableDataSets, setAvailableDataSets] = useState<any[]>([]);
58
+ const [loadingDataSets, setLoadingDataSets] = useState(false);
59
+
60
+ useEffect(() => {
61
+ const fetchDataSets = async () => {
62
+ // 优先使用parseInfoOptions中的所有数据集选项,确保切换后仍然显示所有可用数据集
63
+ const dataSetsFromOptions = parseInfoOptions.map(option => option.dataSet).filter(Boolean);
64
+
65
+ const currentDataSetIds = currentParseInfo?.dataSetIds;
66
+ if (currentDataSetIds && currentDataSetIds.length > 1) {
67
+ setLoadingDataSets(true);
68
+ try {
69
+ const dataSetDetails = await Promise.all(
70
+ currentDataSetIds.map(async (dataSetId: number) => {
71
+ try {
72
+ const response = await getDataSetDetail(dataSetId);
73
+ return response.data?.data || response.data;
74
+ } catch (error) {
75
+ console.error(`Failed to fetch dataset ${dataSetId}:`, error);
76
+ return null;
77
+ }
78
+ })
79
+ );
80
+ const validDataSets = dataSetDetails.filter(Boolean);
81
+ if (validDataSets.length > 0) {
82
+ setAvailableDataSets(validDataSets);
83
+ } else {
84
+ // 回退到parseInfoOptions中的数据集信息
85
+ setAvailableDataSets(dataSetsFromOptions);
86
+ }
87
+ } catch (error) {
88
+ console.error('Failed to fetch datasets:', error);
89
+ setAvailableDataSets(dataSetsFromOptions);
90
+ } finally {
91
+ setLoadingDataSets(false);
92
+ }
93
+ } else {
94
+ // 始终使用parseInfoOptions中的数据集信息,确保显示所有可用数据集
95
+ setAvailableDataSets(dataSetsFromOptions);
96
+ }
97
+ };
98
+
99
+ fetchDataSets();
100
+ }, [currentParseInfo?.dataSetIds, parseInfoOptions]);
101
+
102
+ const ranges: Record<RangeKeys, RangeValue> = {
103
+ 近7日: [dayjs().subtract(7, 'day'), dayjs()],
104
+ 近14日: [dayjs().subtract(14, 'day'), dayjs()],
105
+ 近30日: [dayjs().subtract(30, 'day'), dayjs()],
106
+ 本周: [dayjs().startOf('week'), dayjs().endOf('week')],
107
+ 本月: [dayjs().startOf('month'), dayjs().endOf('month')],
108
+ 上月: [
109
+ dayjs().subtract(1, 'month').startOf('month'),
110
+ dayjs().subtract(1, 'month').endOf('month'),
111
+ ],
112
+ 本季度: [dayjs().startOf('quarter'), dayjs().endOf('quarter')], // 使用 quarterOfYear 插件
113
+ 本年: [dayjs().startOf('year'), dayjs().endOf('year')],
114
+ };
115
+
116
+ const getNode = (tipTitle: ReactNode, tipNode?: ReactNode, failed?: boolean) => {
117
+ return (
118
+ <div className={`${prefixCls}-parse-tip`}>
119
+ {isSimpleMode ? (
120
+ <></>
121
+ ) : (
122
+ <div className={`${prefixCls}-title-bar`}>
123
+ {!failed ? (
124
+ <CheckCircleFilled className={`${prefixCls}-step-icon`} />
125
+ ) : (
126
+ <CloseCircleFilled className={`${prefixCls}-step-error-icon`} />
127
+ )}
128
+ <div className={`${prefixCls}-step-title`}>
129
+ {tipTitle}
130
+ {tipNode === undefined && <Loading />}
131
+ </div>
132
+ </div>
133
+ )}
134
+
135
+ {(tipNode || tipNode === null) && (
136
+ <div
137
+ className={classNames(
138
+ !isSimpleMode && `${prefixCls}-content-container`,
139
+ tipNode === null && `${prefixCls}-empty-content-container`,
140
+ failed && `${prefixCls}-content-container-failed`
141
+ )}
142
+ >
143
+ {tipNode}
144
+ </div>
145
+ )}
146
+ </div>
147
+ );
148
+ };
149
+
150
+ const { modelId, queryMode, entity, nativeQuery } = currentParseInfo || {};
151
+
152
+ const entityAlias = entity?.alias?.[0]?.split('.')?.[0];
153
+
154
+ const getFilterContent = (filters: any, dateInfo: DateInfoType) => {
155
+ const itemValueClass = `${prefixCls}-tip-item-value`;
156
+ const { startDate, endDate } = dateInfo || {};
157
+ const tipItemOptionClass = classNames(`${prefixCls}-tip-item-option`, {
158
+ [`${prefixCls}-mobile-tip-item-option`]: isMobile,
159
+ });
160
+ const disabled = true;
161
+ return (
162
+ <div className={`${prefixCls}-tip-item-filter-content`}>
163
+ {!!dateInfo && (
164
+ <div className={tipItemOptionClass}>
165
+ <span className={`${prefixCls}-tip-item-filter-name`}>数据时间:</span>
166
+ {nativeQuery ? (
167
+ <span className={itemValueClass}>
168
+ {startDate === endDate ? startDate : `${startDate} ~ ${endDate}`}
169
+ </span>
170
+ ) : (
171
+ <RangePicker
172
+ value={[dayjs(startDate), dayjs(endDate)]}
173
+ onChange={onDateInfoChange}
174
+ format="YYYY-MM-DD"
175
+ disabled={disabled}
176
+ renderExtraFooter={() => (
177
+ <Row gutter={[28, 28]}>
178
+ {Object.keys(ranges).map(key => (
179
+ <Col key={key}>
180
+ <Button
181
+ size="small"
182
+ onClick={() => handlePresetClick(ranges[key as RangeKeys])}
183
+ >
184
+ {key}
185
+ </Button>
186
+ </Col>
187
+ ))}
188
+ </Row>
189
+ )}
190
+ />
191
+ )}
192
+ </div>
193
+ )}
194
+ {filters?.map((filter: any, index: number) => (
195
+ <FilterItem
196
+ disabled={disabled}
197
+ modelId={modelId!}
198
+ filters={filters}
199
+ filter={filter}
200
+ index={index}
201
+ chatContext={currentParseInfo!}
202
+ entityAlias={entityAlias}
203
+ agentId={agentId}
204
+ integrateSystem={integrateSystem}
205
+ onFiltersChange={onFiltersChange}
206
+ onSwitchEntity={onSwitchEntity}
207
+ key={`${filter.name}_${index}`}
208
+ />
209
+ ))}
210
+ </div>
211
+ );
212
+ };
213
+
214
+ const getFiltersNode = parseInfo => {
215
+ const { dateInfo, dimensionFilters } = parseInfo;
216
+ return (
217
+ <>
218
+ {(!!dateInfo || !!dimensionFilters?.length) && (
219
+ <div className={`${prefixCls}-tip-item`}>
220
+ <div className={`${prefixCls}-tip-item-name`}>筛选条件:</div>
221
+ <div className={`${prefixCls}-tip-item-content`}>
222
+ {getFilterContent(dimensionFilters, dateInfo)}
223
+ </div>
224
+ </div>
225
+ )}
226
+ </>
227
+ );
228
+ };
229
+
230
+ return getNode(
231
+ <div className={`${prefixCls}-title-bar`}>
232
+ <div>
233
+ 意图确认
234
+ {!!parseTimeCost && isDeveloper && (
235
+ <span className={`${prefixCls}-title-tip`}>(耗时: {parseTimeCost}ms)</span>
236
+ )}
237
+ </div>
238
+ </div>,
239
+
240
+ <>
241
+ <div>
242
+ {parseInfoOptions.map((parseInfo, index) => {
243
+ const { queryMode, properties, textInfo, id, dimensionFilters, entityInfo } =
244
+ parseInfo || {};
245
+ const { type: agentType } = properties || {};
246
+ return isSimpleMode ? (
247
+ <>
248
+ <div style={{ marginBottom: 10 }}>
249
+ <span
250
+ className={`${prefixCls}-content-parser-options-title`}
251
+ style={{ display: 'flex' }}
252
+ >
253
+ <span style={{ paddingTop: 3, marginRight: 10 }}>解析{index + 1}: </span>{' '}
254
+ <MarkDown markdown={textInfo} />
255
+ </span>
256
+ </div>
257
+ </>
258
+ ) : (
259
+ <div
260
+ style={{ marginBottom: 10, paddingBottom: 10, borderBottom: '1px solid #eee' }}
261
+ key={`${id}-${textInfo}`}
262
+ >
263
+ <div style={{ marginBottom: 10, height: '30px', lineHeight: '30px' }}>
264
+ <span className={`${prefixCls}-content-parser-options-title`}>
265
+ 解析{index + 1}:
266
+ </span>
267
+ </div>
268
+ <div className={`${prefixCls}-tip`}>
269
+ <>
270
+ {getTipNode({
271
+ parseInfo,
272
+ dimensionFilters,
273
+ entityInfo,
274
+ onSwitchDataSet: (selectedDataSet) => {
275
+ // 使用新选择的数据集ID重新调用查询
276
+ setSelectedDataSetIds([selectedDataSet.id]);
277
+ // 先更新状态,然后调用onRefresh
278
+ setTimeout(() => {
279
+ onRefresh({
280
+ ...parseInfo,
281
+ dataSet: selectedDataSet,
282
+ dataSetIds: [selectedDataSet.id],
283
+ id: parseInfo?.id || 0,
284
+ } as ChatContextType);
285
+ }, 0);
286
+ },
287
+ availableDataSets,
288
+ loadingDataSets
289
+ })}
290
+ {!(!!agentType && queryMode !== 'LLM_S2SQL') && getFiltersNode(parseInfo)}
291
+ </>
292
+ </div>
293
+ </div>
294
+ );
295
+ })}
296
+
297
+ {parseInfoOptions?.length > 1 && (
298
+ <div className={`${prefixCls}-content-parser-container`}>
299
+ <div className={`${prefixCls}-content-options`}>
300
+ {!currentParseInfo && (
301
+ <span className={`${prefixCls}-breathing-text`}>
302
+ 请选择适合的解析意图,并进行下一步:
303
+ </span>
304
+ )}
305
+
306
+ {parseInfoOptions.map((parseInfo, index) => (
307
+ <div
308
+ className={`${prefixCls}-content-option ${
309
+ parseInfo.id === currentParseInfo?.id
310
+ ? `${prefixCls}-content-option-active`
311
+ : ''
312
+ } ${currentParseInfo ? `${prefixCls}-content-option-disabled` : ''}`}
313
+ onClick={() => {
314
+ if (currentParseInfo) {
315
+ return;
316
+ }
317
+ setCurrentParseInfo(parseInfo);
318
+ onSelectParseInfo(parseInfo);
319
+ }}
320
+ key={parseInfo.id}
321
+ >
322
+ 解析{index + 1}
323
+ </div>
324
+ ))}
325
+ </div>
326
+ </div>
327
+ )}
328
+ </div>
329
+ </>
330
+ );
331
+ };
332
+
333
+ export default ExpandParseTip;
@@ -0,0 +1,209 @@
1
+ import { Select, Spin, InputNumber, DatePicker } from 'antd';
2
+ import { PREFIX_CLS } from '../../common/constants';
3
+ import { ChatContextType, FilterItemType } from '../../common/type';
4
+ import { useEffect, useMemo, useRef, useState } from 'react';
5
+ import { queryDimensionValues } from '../../service';
6
+ import { debounce, isArray } from 'lodash';
7
+ import SwicthEntity from './SwitchEntity';
8
+ import dayjs from 'dayjs';
9
+
10
+ type Props = {
11
+ modelId: number;
12
+ filters: FilterItemType[];
13
+ filter: FilterItemType;
14
+ index: number;
15
+ chatContext: ChatContextType;
16
+ agentId?: number;
17
+ disabled?: boolean;
18
+ entityAlias?: string;
19
+ integrateSystem?: string;
20
+ onFiltersChange: (filters: FilterItemType[]) => void;
21
+ onSwitchEntity: (entityId: string) => void;
22
+ };
23
+
24
+ const FilterItem: React.FC<Props> = ({
25
+ disabled = false,
26
+ modelId,
27
+ filters,
28
+ filter,
29
+ index,
30
+ chatContext,
31
+ agentId,
32
+ entityAlias,
33
+ integrateSystem,
34
+ onFiltersChange,
35
+ onSwitchEntity,
36
+ }) => {
37
+ const [options, setOptions] = useState<{ label: string; value: string | null }[]>([]);
38
+ const [loading, setLoading] = useState(false);
39
+ const fetchRef = useRef(0);
40
+
41
+ const prefixCls = `${PREFIX_CLS}-filter-item`;
42
+
43
+ const initData = async () => {
44
+ const { data } = await queryDimensionValues(
45
+ modelId,
46
+ filter.bizName,
47
+ agentId!,
48
+ filter.elementID,
49
+ ''
50
+ );
51
+ setOptions(
52
+ data?.resultList?.map((item: any) => ({
53
+ label: item[filter.bizName],
54
+ value: item[filter.bizName],
55
+ })) || []
56
+ );
57
+ };
58
+
59
+ useEffect(() => {
60
+ if (
61
+ (typeof filter.value === 'string' || isArray(filter.value)) &&
62
+ options.length === 0 &&
63
+ integrateSystem !== 'showcase'
64
+ ) {
65
+ initData();
66
+ }
67
+ }, []);
68
+
69
+ const debounceFetcher = useMemo(() => {
70
+ const loadOptions = (value: string) => {
71
+ fetchRef.current += 1;
72
+ const fetchId = fetchRef.current;
73
+ setOptions([]);
74
+ setLoading(true);
75
+ queryDimensionValues(modelId, filter.bizName, agentId!, filter.elementID, value).then(
76
+ newOptions => {
77
+ if (fetchId !== fetchRef.current) {
78
+ return;
79
+ }
80
+ setOptions(
81
+ newOptions.data?.resultList.map((item: any) => ({
82
+ label: item[filter.bizName],
83
+ value: item[filter.bizName],
84
+ })) || []
85
+ );
86
+ setLoading(false);
87
+ }
88
+ );
89
+ };
90
+
91
+ return debounce(loadOptions, 500);
92
+ }, [queryDimensionValues]);
93
+
94
+ const onOperatorChange = (value: string) => {
95
+ const newFilters = filters.map((item, indexValue) => {
96
+ if (item.bizName === filter.bizName && index === indexValue) {
97
+ item.operator = value;
98
+ }
99
+ return item;
100
+ });
101
+ onFiltersChange(newFilters);
102
+ };
103
+
104
+ const onChange = (value: string | string[] | number | null) => {
105
+ const newFilters = filters.map((item, indexValue) => {
106
+ if (item.bizName === filter.bizName && index === indexValue) {
107
+ item.value =
108
+ typeof filter.value === 'number' || filter.value === null
109
+ ? value
110
+ : isArray(value)
111
+ ? value
112
+ : `${value}`;
113
+ if (isArray(value)) {
114
+ if (value.length === 1) {
115
+ item.operator = '=';
116
+ item.value = value[0];
117
+ } else {
118
+ item.operator = 'IN';
119
+ item.value = value;
120
+ }
121
+ } else {
122
+ item.value =
123
+ typeof filter.value === 'number' || filter.value === null ? value : `${value}`;
124
+ }
125
+ }
126
+ return item;
127
+ });
128
+ onFiltersChange(newFilters);
129
+ };
130
+
131
+ const onDateChange = (_: any, date: string | string[]) => {
132
+ const newFilters = filters.map((item, indexValue) => {
133
+ if (item.bizName === filter.bizName && index === indexValue) {
134
+ item.value = date;
135
+ }
136
+ return item;
137
+ });
138
+ onFiltersChange(newFilters);
139
+ };
140
+
141
+ return (
142
+ <span className={prefixCls}>
143
+ <span className={`${prefixCls}-filter-name`}>{filter.name}:</span>
144
+ {(typeof filter.value === 'number' ||
145
+ filter.value === null ||
146
+ (filter.operator && !['IN', '=', 'LIKE'].includes(filter.operator))) &&
147
+ !filter.bizName?.includes('_id') && (
148
+ <Select
149
+ options={[
150
+ { label: '大于等于', value: '>=' },
151
+ { label: '大于', value: '>' },
152
+ { label: '等于', value: '=' },
153
+ { label: '小于等于', value: '<=' },
154
+ { label: '小于', value: '<' },
155
+ ]}
156
+ disabled={disabled}
157
+ className={`${prefixCls}-operator-control`}
158
+ value={filter.operator}
159
+ onChange={onOperatorChange}
160
+ />
161
+ )}
162
+ {(typeof filter.value === 'number' || filter.value === null) &&
163
+ !filter.bizName?.includes('_id') ? (
164
+ <InputNumber
165
+ disabled={disabled}
166
+ className={`${prefixCls}-input-number-control`}
167
+ value={filter.value}
168
+ onChange={onChange}
169
+ />
170
+ ) : typeof filter.value === 'string' && dayjs(filter.value, 'YYYY-MM-DD').isValid() ? (
171
+ <DatePicker value={dayjs(filter.value)} onChange={onDateChange} allowClear={false} />
172
+ ) : (typeof filter.value === 'string' || isArray(filter.value)) &&
173
+ !filter.bizName?.includes('_id') ? (
174
+ <Select
175
+ disabled={disabled}
176
+ value={filter.value}
177
+ options={options.filter(option => option.value !== '' && option.value !== null)}
178
+ className={`${prefixCls}-select-control`}
179
+ onSearch={debounceFetcher}
180
+ notFoundContent={loading ? <Spin size="small" /> : null}
181
+ onChange={onChange}
182
+ mode="multiple"
183
+ showSearch
184
+ allowClear
185
+ />
186
+ ) : entityAlias &&
187
+ ['歌曲', '艺人'].includes(entityAlias) &&
188
+ filter.bizName?.includes('_id') ? (
189
+ <>
190
+ <SwicthEntity
191
+ entityName={filter.value}
192
+ chatContext={chatContext}
193
+ onSwitchEntity={onSwitchEntity}
194
+ />
195
+ <span className={`${prefixCls}-switch-entity-tip`}>
196
+ (如未匹配到相关{entityAlias},可点击{entityAlias === '艺人' ? '歌手' : entityAlias}
197
+ ID切换)
198
+ </span>
199
+ </>
200
+ ) : (
201
+ <span className={`${prefixCls}-filter-value`}>
202
+ {typeof filter.value !== 'object' ? filter.value : ''}
203
+ </span>
204
+ )}
205
+ </span>
206
+ );
207
+ };
208
+
209
+ export default FilterItem;
@@ -0,0 +1,14 @@
1
+ import { PREFIX_CLS } from '../../common/constants';
2
+
3
+ const Loading = () => {
4
+ const prefixCls = `${PREFIX_CLS}-item`;
5
+ return (
6
+ <span className={`${prefixCls}-loading`}>
7
+ <span className={`${prefixCls}-loading-dot`} />
8
+ <span className={`${prefixCls}-loading-dot`} />
9
+ <span className={`${prefixCls}-loading-dot`} />
10
+ </span>
11
+ );
12
+ };
13
+
14
+ export default Loading;