test-chat-sdk 0.0.0

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 +210 -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 +208 -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 +120 -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 +103 -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,423 @@
1
+ import IconFont from '../../components/IconFont';
2
+ import { getTextWidth, groupByColumn, isMobile } from '../../utils/utils';
3
+ import { AutoComplete, Select, Tag } from 'antd';
4
+ import classNames from 'classnames';
5
+ import { debounce } from 'lodash';
6
+ import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
7
+ import type { ForwardRefRenderFunction } from 'react';
8
+ import { SemanticTypeEnum, SEMANTIC_TYPE_MAP, HOLDER_TAG } from '../constants';
9
+ import { AgentType, ModelType } from '../type';
10
+ import { searchRecommend } from '../../service';
11
+ import styles from './style.module.less';
12
+ import { useComposing } from '../../hooks/useComposing';
13
+
14
+ type Props = {
15
+ inputMsg: string;
16
+ chatId?: number;
17
+ currentAgent?: AgentType;
18
+ agentList: AgentType[];
19
+ onToggleHistoryVisible: () => void;
20
+ onOpenAgents: () => void;
21
+ onInputMsgChange: (value: string) => void;
22
+ onSendMsg: (msg: string, dataSetId?: number) => void;
23
+ onAddConversation: (agent?: AgentType) => void;
24
+ onSelectAgent: (agent: AgentType) => void;
25
+ onOpenShowcase: () => void;
26
+ };
27
+
28
+ const { OptGroup, Option } = Select;
29
+ let isPinyin = false;
30
+ let isSelect = false;
31
+
32
+ const compositionStartEvent = () => {
33
+ isPinyin = true;
34
+ };
35
+
36
+ const compositionEndEvent = () => {
37
+ isPinyin = false;
38
+ };
39
+
40
+ const ChatFooter: ForwardRefRenderFunction<any, Props> = (
41
+ {
42
+ inputMsg,
43
+ chatId,
44
+ currentAgent,
45
+ agentList,
46
+ onToggleHistoryVisible,
47
+ onOpenAgents,
48
+ onInputMsgChange,
49
+ onSendMsg,
50
+ onAddConversation,
51
+ onSelectAgent,
52
+ onOpenShowcase,
53
+ },
54
+ ref
55
+ ) => {
56
+ const [modelOptions, setModelOptions] = useState<(ModelType | AgentType)[]>([]);
57
+ const [stepOptions, setStepOptions] = useState<Record<string, any[]>>({});
58
+ const [open, setOpen] = useState(false);
59
+ const [focused, setFocused] = useState(false);
60
+ const inputRef = useRef<any>();
61
+ const fetchRef = useRef(0);
62
+
63
+ const inputFocus = () => {
64
+ inputRef.current?.focus();
65
+ };
66
+
67
+ const inputBlur = () => {
68
+ inputRef.current?.blur();
69
+ };
70
+
71
+ useImperativeHandle(ref, () => ({
72
+ inputFocus,
73
+ inputBlur,
74
+ }));
75
+
76
+ const initEvents = () => {
77
+ const autoCompleteEl = document.getElementById('chatInput');
78
+ autoCompleteEl!.addEventListener('compositionstart', compositionStartEvent);
79
+ autoCompleteEl!.addEventListener('compositionend', compositionEndEvent);
80
+ };
81
+
82
+ const removeEvents = () => {
83
+ const autoCompleteEl = document.getElementById('chatInput');
84
+ if (autoCompleteEl) {
85
+ autoCompleteEl.removeEventListener('compositionstart', compositionStartEvent);
86
+ autoCompleteEl.removeEventListener('compositionend', compositionEndEvent);
87
+ }
88
+ };
89
+
90
+ useEffect(() => {
91
+ initEvents();
92
+ return () => {
93
+ removeEvents();
94
+ };
95
+ }, []);
96
+
97
+ const getStepOptions = (recommends: any[]) => {
98
+ const data = groupByColumn(recommends, 'dataSetName');
99
+ return isMobile && recommends.length > 6
100
+ ? Object.keys(data)
101
+ .slice(0, 4)
102
+ .reduce((result, key) => {
103
+ result[key] = data[key].slice(
104
+ 0,
105
+ Object.keys(data).length > 2 ? 2 : Object.keys(data).length > 1 ? 3 : 6
106
+ );
107
+ return result;
108
+ }, {})
109
+ : data;
110
+ };
111
+
112
+ const processMsg = (msg: string) => {
113
+ let msgValue = msg;
114
+ let dataSetId: number | undefined;
115
+ if (msg?.[0] === '/') {
116
+ const agent = agentList.find(item => msg.includes(`/${item.name}`));
117
+ msgValue = agent ? msg.replace(`/${agent.name}`, '') : msg;
118
+ }
119
+ return { msgValue, dataSetId };
120
+ };
121
+
122
+ const debounceGetWordsFunc = useCallback(() => {
123
+ const getAssociateWords = async (msg: string, chatId?: number, currentAgent?: AgentType) => {
124
+ if (isPinyin) {
125
+ return;
126
+ }
127
+ if (msg === '' || (msg.length === 1 && msg[0] === '@')) {
128
+ return;
129
+ }
130
+ fetchRef.current += 1;
131
+ const fetchId = fetchRef.current;
132
+ const { msgValue, dataSetId } = processMsg(msg);
133
+ const res = await searchRecommend(msgValue.trim(), chatId, dataSetId, currentAgent?.id);
134
+ if (fetchId !== fetchRef.current) {
135
+ return;
136
+ }
137
+ const recommends = msgValue ? res.data || [] : [];
138
+ const stepOptionList = recommends.map((item: any) => item.subRecommend);
139
+ if (stepOptionList.length > 0 && stepOptionList.every((item: any) => item !== null)) {
140
+ setStepOptions(getStepOptions(recommends));
141
+ } else {
142
+ setStepOptions({});
143
+ }
144
+ setOpen(recommends.length > 0);
145
+ };
146
+ return debounce(getAssociateWords, 200);
147
+ }, []);
148
+
149
+ const [debounceGetWords] = useState<any>(debounceGetWordsFunc);
150
+
151
+ useEffect(() => {
152
+ if (inputMsg.length === 1 && inputMsg[0] === '/') {
153
+ setOpen(true);
154
+ setModelOptions(agentList);
155
+ setStepOptions({});
156
+ return;
157
+ }
158
+ if (modelOptions.length > 0) {
159
+ setTimeout(() => {
160
+ setModelOptions([]);
161
+ }, 50);
162
+ }
163
+ if (!isSelect) {
164
+ debounceGetWords(inputMsg, chatId, currentAgent);
165
+ } else {
166
+ isSelect = false;
167
+ }
168
+ if (!inputMsg) {
169
+ setStepOptions({});
170
+ fetchRef.current = 0;
171
+ }
172
+ }, [inputMsg]);
173
+
174
+ useEffect(() => {
175
+ if (!focused) {
176
+ setOpen(false);
177
+ }
178
+ }, [focused]);
179
+
180
+ useEffect(() => {
181
+ const autoCompleteDropdown = document.querySelector(
182
+ `.${styles.autoCompleteDropdown}`
183
+ ) as HTMLElement;
184
+ if (!autoCompleteDropdown) {
185
+ return;
186
+ }
187
+ const textWidth = getTextWidth(inputMsg);
188
+ if (Object.keys(stepOptions).length > 0) {
189
+ autoCompleteDropdown.style.marginLeft = `${textWidth}px`;
190
+ } else {
191
+ setTimeout(() => {
192
+ autoCompleteDropdown.style.marginLeft = `0px`;
193
+ }, 200);
194
+ }
195
+ }, [stepOptions]);
196
+
197
+ const sendMsg = (value: string) => {
198
+ const option = Object.keys(stepOptions)
199
+ .reduce((result: any[], item) => {
200
+ result = result.concat(stepOptions[item]);
201
+ return result;
202
+ }, [])
203
+ .find(item =>
204
+ Object.keys(stepOptions).length === 1
205
+ ? item.recommend === value
206
+ : `${item.dataSetName || ''}${item.recommend}` === value
207
+ );
208
+
209
+ if (option && isSelect) {
210
+ onSendMsg(option.recommend, option.dataSetIds);
211
+ } else {
212
+ onSendMsg(value.trim(), option?.dataSetId);
213
+ }
214
+ };
215
+
216
+ const autoCompleteDropdownClass = classNames(styles.autoCompleteDropdown, {
217
+ [styles.mobile]: isMobile,
218
+ [styles.modelOptions]: modelOptions.length > 0,
219
+ });
220
+
221
+ const onSelect = (value: string) => {
222
+ isSelect = true;
223
+ if (modelOptions.length > 0) {
224
+ const agent = agentList.find(item => value.includes(item.name));
225
+ if (agent) {
226
+ if (agent.id !== currentAgent?.id) {
227
+ onSelectAgent(agent);
228
+ }
229
+ onInputMsgChange('');
230
+ }
231
+ } else {
232
+ onInputMsgChange(value.replace(HOLDER_TAG, ''));
233
+ }
234
+ setOpen(false);
235
+ setTimeout(() => {
236
+ isSelect = false;
237
+ }, 200);
238
+ };
239
+
240
+ const chatFooterClass = classNames(styles.chatFooter, {
241
+ [styles.mobile]: isMobile,
242
+ });
243
+
244
+ const modelOptionNodes = modelOptions.map(model => {
245
+ return (
246
+ <Option key={model.id} value={`/${model.name} `} className={styles.searchOption}>
247
+ {model.name}
248
+ </Option>
249
+ );
250
+ });
251
+
252
+ const associateOptionNodes = Object.keys(stepOptions).map(key => {
253
+ return (
254
+ <OptGroup key={key} label={key}>
255
+ {stepOptions[key].map(option => {
256
+ let optionValue =
257
+ Object.keys(stepOptions).length === 1
258
+ ? option.recommend
259
+ : `${option.dataSetName || ''}${option.recommend}`;
260
+ if (inputMsg[0] === '/') {
261
+ const agent = agentList.find(item => inputMsg.includes(item.name));
262
+ optionValue = agent ? `/${agent.name} ${option.recommend}` : optionValue;
263
+ }
264
+ return (
265
+ <Option
266
+ key={`${option.recommend}${option.dataSetName ? `_${option.dataSetName}` : ''}`}
267
+ value={`${optionValue}${HOLDER_TAG}`}
268
+ className={styles.searchOption}
269
+ >
270
+ <div className={styles.optionContent}>
271
+ {option.schemaElementType && (
272
+ <Tag
273
+ className={styles.semanticType}
274
+ color={
275
+ option.schemaElementType === SemanticTypeEnum.DIMENSION ||
276
+ option.schemaElementType === SemanticTypeEnum.MODEL
277
+ ? 'blue'
278
+ : option.schemaElementType === SemanticTypeEnum.VALUE
279
+ ? 'geekblue'
280
+ : 'cyan'
281
+ }
282
+ >
283
+ {SEMANTIC_TYPE_MAP[option.schemaElementType] ||
284
+ option.schemaElementType ||
285
+ '维度'}
286
+ </Tag>
287
+ )}
288
+ {option.subRecommend}
289
+ </div>
290
+ </Option>
291
+ );
292
+ })}
293
+ </OptGroup>
294
+ );
295
+ });
296
+
297
+ const fixWidthBug = () => {
298
+ setTimeout(() => {
299
+ const dropdownDom = document.querySelector(
300
+ '.' + styles.autoCompleteDropdown + ' .rc-virtual-list-holder-inner'
301
+ );
302
+
303
+ if (!dropdownDom) {
304
+ fixWidthBug();
305
+ } else {
306
+ // 获取popoverDom样式
307
+ const popoverDomStyle = window.getComputedStyle(dropdownDom);
308
+ // 在获取popoverDom中增加样式 width: fit-content
309
+ dropdownDom.setAttribute('style', `${popoverDomStyle.cssText};width: fit-content`);
310
+ // 获取popoverDom的宽度
311
+ const popoverDomWidth = dropdownDom.clientWidth;
312
+ // 将popoverDom的宽度赋值给他的父元素
313
+ const offset = 20; // 预增加20px的宽度,预留空间给虚拟渲染出来的元素
314
+ dropdownDom.parentElement!.style.width = popoverDomWidth + offset + 'px';
315
+ }
316
+ });
317
+ };
318
+
319
+ useEffect(() => {
320
+ if (modelOptionNodes.length || associateOptionNodes.length) fixWidthBug();
321
+ }, [modelOptionNodes.length, associateOptionNodes.length]);
322
+
323
+ const { isComposing } = useComposing(document.getElementById('chatInput'));
324
+
325
+ return (
326
+ <div className={chatFooterClass}>
327
+ <div className={styles.tools}>
328
+ <div
329
+ className={styles.toolItem}
330
+ onClick={() => {
331
+ onAddConversation();
332
+ }}
333
+ >
334
+ <IconFont type="icon-c003xiaoxiduihua" className={styles.toolIcon} />
335
+ <div>新对话</div>
336
+ </div>
337
+ {!isMobile && (
338
+ <div className={styles.toolItem} onClick={onToggleHistoryVisible}>
339
+ <IconFont type="icon-lishi" className={styles.toolIcon} />
340
+ <div>历史对话</div>
341
+ </div>
342
+ )}
343
+ {agentList?.length > 1 && (
344
+ <div className={styles.toolItem} onClick={onOpenAgents}>
345
+ <IconFont type="icon-zhinengzhuli" className={styles.toolIcon} />
346
+ <div>智能助理</div>
347
+ </div>
348
+ )}
349
+ <div className={styles.toolItem} onClick={onOpenShowcase}>
350
+ <IconFont type="icon-showcase" className={styles.toolIcon} />
351
+ <div>showcase</div>
352
+ </div>
353
+ </div>
354
+ <div className={styles.composer}>
355
+ <div className={styles.composerInputWrapper}>
356
+ <AutoComplete
357
+ className={styles.composerInput}
358
+ placeholder={
359
+ currentAgent
360
+ ? `【${currentAgent.name}】将与您对话,点击${!isMobile ? '左侧' : ''}【智能助理】${
361
+ !isMobile ? '列表' : ''
362
+ }可切换`
363
+ : '请输入您的问题'
364
+ }
365
+ value={inputMsg}
366
+ onChange={(value: string) => {
367
+ onInputMsgChange(value);
368
+ }}
369
+ onSelect={onSelect}
370
+ autoFocus={!isMobile}
371
+ ref={inputRef}
372
+ id="chatInput"
373
+ onKeyDown={e => {
374
+ if (e.code === 'Enter' || e.code === 'NumpadEnter') {
375
+ const chatInputEl: any = document.getElementById('chatInput');
376
+ const agent = agentList.find(
377
+ item => chatInputEl.value[0] === '/' && chatInputEl.value.includes(item.name)
378
+ );
379
+ if (agent) {
380
+ if (agent.id !== currentAgent?.id) {
381
+ onSelectAgent(agent);
382
+ }
383
+ onInputMsgChange('');
384
+ return;
385
+ }
386
+ if (!isSelect && !isComposing) {
387
+ sendMsg(chatInputEl.value);
388
+ setOpen(false);
389
+ }
390
+ }
391
+ }}
392
+ onFocus={() => {
393
+ setFocused(true);
394
+ }}
395
+ onBlur={() => {
396
+ setFocused(false);
397
+ }}
398
+ dropdownClassName={autoCompleteDropdownClass}
399
+ listHeight={500}
400
+ allowClear
401
+ open={open}
402
+ defaultActiveFirstOption={false}
403
+ getPopupContainer={triggerNode => triggerNode.parentNode}
404
+ >
405
+ {modelOptions.length > 0 ? modelOptionNodes : associateOptionNodes}
406
+ </AutoComplete>
407
+ <div
408
+ className={classNames(styles.sendBtn, {
409
+ [styles.sendBtnActive]: inputMsg?.length > 0,
410
+ })}
411
+ onClick={() => {
412
+ sendMsg(inputMsg);
413
+ }}
414
+ >
415
+ <IconFont type="icon-ios-send" />
416
+ </div>
417
+ </div>
418
+ </div>
419
+ </div>
420
+ );
421
+ };
422
+
423
+ export default forwardRef(ChatFooter);
@@ -0,0 +1,225 @@
1
+ .chatFooter {
2
+ position: relative;
3
+ z-index: 10;
4
+ display: flex;
5
+ flex-direction: column;
6
+ margin: 6px 20px 20px;
7
+
8
+ .tools {
9
+ display: flex;
10
+ align-items: center;
11
+ margin-bottom: 6px;
12
+ column-gap: 8px;
13
+
14
+ .toolItem {
15
+ display: flex;
16
+ align-items: center;
17
+ padding: 2px 6px;
18
+ color: var(--text-color-secondary);
19
+ font-size: 12px;
20
+ column-gap: 6px;
21
+ background-color: #f6f6f6;
22
+ border-radius: 6px;
23
+ cursor: pointer;
24
+
25
+ &:hover {
26
+ background-color: #f1f1f1;
27
+ }
28
+ }
29
+ }
30
+
31
+ .composer {
32
+ display: flex;
33
+ height: 70px;
34
+
35
+ .collapseBtn {
36
+ height: 46px;
37
+ margin: 0 10px;
38
+ color: var(--text-color-third);
39
+ font-size: 20px;
40
+ line-height: 46px;
41
+ cursor: pointer;
42
+
43
+ &:hover {
44
+ color: var(--chat-blue);
45
+ }
46
+ }
47
+
48
+ .addConversation {
49
+ height: 46px;
50
+ margin: 0 20px 0 10px;
51
+ color: var(--text-color-fourth);
52
+ font-size: 26px;
53
+ line-height: 54px;
54
+ cursor: pointer;
55
+
56
+ &:hover {
57
+ color: var(--chat-blue);
58
+ }
59
+ }
60
+
61
+ .composerInputWrapper {
62
+ position: relative;
63
+ flex: 1;
64
+
65
+ .composerInput {
66
+ width: 100%;
67
+ height: 100%;
68
+ :global {
69
+ .ant-select-selector {
70
+ box-sizing: border-box;
71
+ height: 100%;
72
+ overflow: hidden;
73
+ color: rgba(0, 0, 0, 0.87);
74
+ font-size: 14px;
75
+ word-break: break-all;
76
+ background: #f9f9f9;
77
+ border: 0;
78
+ border-radius: 8px;
79
+ transition: border-color 0.15s ease-in-out;
80
+ resize: none;
81
+
82
+ .ant-select-selection-search-input {
83
+ height: 40px !important;
84
+ padding: 0 12px;
85
+ }
86
+
87
+ .ant-select-selection-search {
88
+ right: 0 !important;
89
+ left: 0 !important;
90
+ }
91
+
92
+ .ant-select-selection-placeholder {
93
+ line-height: 40px;
94
+ margin-bottom: 30px;
95
+ }
96
+ }
97
+
98
+ .ant-select-clear {
99
+ right: auto;
100
+ left: 500px;
101
+ width: 16px;
102
+ height: 16px;
103
+ margin-top: -8px;
104
+ font-size: 16px;
105
+ }
106
+ }
107
+ }
108
+
109
+ :global {
110
+ .ant-select-focused {
111
+ .ant-select-selector {
112
+ box-shadow: rgb(74, 114, 245) 0px 0px 3px !important;
113
+ }
114
+ }
115
+ }
116
+ }
117
+ }
118
+
119
+ .sendBtn {
120
+ position: absolute;
121
+ right: 10px;
122
+ bottom: 10px;
123
+ display: flex;
124
+ align-items: center;
125
+ justify-content: center;
126
+ width: 30px;
127
+ height: 30px;
128
+ color: #fff;
129
+ font-size: 20px;
130
+ background-color: rgb(184, 184, 191);
131
+ border: unset;
132
+ border-radius: 50%;
133
+ transition: background-color 0.3s ease 0s;
134
+
135
+ &.sendBtnActive {
136
+ background-color: var(--chat-blue);
137
+ }
138
+ }
139
+
140
+ &.mobile {
141
+ margin: 6px 10px 10px;
142
+
143
+ .addConversation {
144
+ height: 40px;
145
+ margin: 0 12px 0 4px;
146
+ }
147
+
148
+ .composer {
149
+ height: 40px;
150
+ :global {
151
+ .ant-select-selector {
152
+ font-size: 14px !important;
153
+ }
154
+
155
+ .ant-select-selection-search-input {
156
+ padding: 0 10px !important;
157
+ }
158
+
159
+ .ant-select-selection-placeholder {
160
+ margin-bottom: 0 !important;
161
+ padding-left: 0 !important;
162
+ line-height: 38px !important;
163
+ }
164
+ }
165
+ }
166
+
167
+ .sendBtn {
168
+ right: 4px;
169
+ bottom: 6px;
170
+ }
171
+ }
172
+ }
173
+
174
+ .searchOption {
175
+ padding: 6px 20px;
176
+ color: #212121;
177
+ font-size: 16px;
178
+ }
179
+
180
+ .mobile {
181
+ .searchOption {
182
+ min-height: 26px;
183
+ padding: 2px 12px;
184
+ font-size: 14px;
185
+ }
186
+ }
187
+
188
+ .model {
189
+ margin-top: 2px;
190
+ color: var(--text-color-fourth);
191
+ font-size: 13px;
192
+ line-height: 12px;
193
+ }
194
+
195
+ .autoCompleteDropdown {
196
+ left: 20px !important;
197
+ width: fit-content !important;
198
+ min-width: 100px !important;
199
+ border-radius: 6px;
200
+
201
+ &.modelOptions {
202
+ width: 150px !important;
203
+
204
+ .searchOption {
205
+ padding: 0 10px;
206
+ color: var(--text-color-secondary);
207
+ font-size: 14px;
208
+ }
209
+
210
+ :global {
211
+ .ant-select-item {
212
+ height: 30px !important;
213
+ line-height: 30px !important;
214
+ }
215
+ }
216
+ }
217
+ }
218
+
219
+ .semanticType {
220
+ margin-right: 10px;
221
+ }
222
+
223
+ .quoteText {
224
+ color: var(--chat-blue);
225
+ }