yt-chat-components 1.3.8 → 1.3.9

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yt-chat-components",
3
- "version": "1.3.8",
3
+ "version": "1.3.9",
4
4
  "main": "build/static/js/bundle.min.js",
5
5
  "module": "build/static/js/bundle.min.js",
6
6
  "types": "build/static/js/index.d.ts",
@@ -11,7 +11,6 @@
11
11
  },
12
12
  "dependencies": {
13
13
  "@ant-design/icons": "5.0.0",
14
- "@ant-design/x": "^1.1.1",
15
14
  "@testing-library/jest-dom": "^5.16.5",
16
15
  "@testing-library/react": "^13.4.0",
17
16
  "@testing-library/user-event": "^13.5.0",
package/public/index.html CHANGED
@@ -14,9 +14,9 @@
14
14
  height="50"
15
15
  title="菜鸟驿站"
16
16
  icon-url="https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/school/ccit/user/xc//image/ebfaf4da-c1d9-46fb-a0b1-f159e95cffc2_AI招生咨询小助手.png"
17
- host-url="https://ai-api.yuntu.cn"
18
- user-info='{"id": "123", "name": "John Doe", "code":"1606451129" }'
19
- app-id="263070d6-3560-4f4d-a6c4-003f4a586e6e"
17
+ host-url="http://localhost:7860"
18
+ user-info='{"id": "123", "name": "John Doe", "code":"2020230608" }'
19
+ app-id="c3148c58-c2a2-45a2-a872-bb6e7fc2dd7e"
20
20
  is-show-side-left=true
21
21
  is-show-side-right=false
22
22
  modal-index="9999999999"
@@ -28,6 +28,7 @@
28
28
  logo-font-size="26px"
29
29
  logo-position="fixed"
30
30
  is-title-side-icon=false
31
+ is-show-upload-button=true
31
32
  />
32
33
  </body>
33
34
 
@@ -50,7 +51,6 @@
50
51
  <!-- is-title-side-icon=true-->
51
52
  <!-- is-show-upload-button=false-->
52
53
  <!-- drop-man-url="https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/ai/ai_man01.png"-->
53
- <!--is-show-read-icon=false-->
54
54
  <!--/>-->
55
55
  <!--</body>-->
56
56
 
@@ -77,7 +77,6 @@
77
77
  <!-- logo-position="fixed"-->
78
78
  <!-- is-title-side-icon=false-->
79
79
  <!-- is-show-upload-button=false-->
80
- <!--is-show-read-icon=false-->
81
80
  <!--/>-->
82
81
  <!--</body>-->
83
82
 
@@ -104,7 +103,6 @@
104
103
  <!-- is-title-side-icon=true-->
105
104
  <!-- is-show-upload-button=false-->
106
105
  <!-- drop-man-url="https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/ai/ai_man01.png"-->
107
- <!--is-show-read-icon=false-->
108
106
  <!--/>-->
109
107
  <!--</body>-->
110
108
  </html>
@@ -0,0 +1,123 @@
1
+ .custom-thought-chain {
2
+ display: flex;
3
+ flex-direction: column;
4
+ width: 100%;
5
+ }
6
+
7
+ /* 思维链节点项样式 */
8
+ .custom-thought-chain-item {
9
+ position: relative;
10
+ display: flex;
11
+ flex-direction: column;
12
+ padding-left: 40px;
13
+ margin-bottom: 16px;
14
+ }
15
+
16
+ .custom-thought-chain-item-last {
17
+ position: relative;
18
+ display: flex;
19
+ flex-direction: column;
20
+ padding-left: 40px;
21
+ margin-bottom: 16px;
22
+ }
23
+
24
+ .custom-thought-chain-item-last::before {
25
+ content: '';
26
+ position: absolute;
27
+ top: 24px;
28
+ left: 20px;
29
+ width: 2px;
30
+ height: calc(100% - 8px);
31
+ background-color: #4270f5;
32
+ z-index: 1;
33
+ }
34
+
35
+ /* 节点连接线样式 */
36
+ .custom-thought-chain-item::before {
37
+ content: '';
38
+ position: absolute;
39
+ top: 24px;
40
+ left: 20px;
41
+ width: 2px;
42
+ height: calc(100% - 8px);
43
+ background-color: #52c41a;
44
+ z-index: 1;
45
+ }
46
+
47
+ /* 节点头部样式 */
48
+ .custom-thought-chain-item-header {
49
+ display: flex;
50
+ align-items: flex-start;
51
+ margin-bottom: 8px;
52
+ }
53
+
54
+ /* 节点图标样式 */
55
+ .custom-thought-chain-item-icon {
56
+ position: absolute;
57
+ left: 9px;
58
+ top: -1px;
59
+ width: 25px;
60
+ height: 25px;
61
+ display: flex;
62
+ align-items: center;
63
+ justify-content: center;
64
+ background-color: #52c41a;
65
+ border-radius: 50%;
66
+ color: white;
67
+ font-size: 15px;
68
+ z-index: 2;
69
+ }
70
+
71
+ .custom-thought-chain-item-icon-last {
72
+ position: absolute;
73
+ left: 9px;
74
+ top: -1px;
75
+ width: 25px;
76
+ height: 25px;
77
+ display: flex;
78
+ align-items: center;
79
+ justify-content: center;
80
+ background-color: #4270f5;
81
+ border-radius: 50%;
82
+ color: white;
83
+ font-size: 15px;
84
+ z-index: 2;
85
+ }
86
+
87
+ /* 标题容器样式 */
88
+ .custom-thought-chain-item-title-container {
89
+ flex: 1;
90
+ }
91
+
92
+ /* 标题样式 */
93
+ .custom-thought-chain-item-title {
94
+ font-weight: 500;
95
+ color: rgba(0, 0, 0, 0.85);
96
+ margin-bottom: 4px;
97
+ display: flex;
98
+ align-items: center;
99
+ margin-left: 8px;
100
+ }
101
+
102
+ /* 描述样式 */
103
+ .custom-thought-chain-item-description {
104
+ font-size: 14px;
105
+ color: rgba(0, 0, 0, 0.45);
106
+ }
107
+
108
+ /* 内容样式 */
109
+ .custom-thought-chain-item-content {
110
+ margin-bottom: 8px;
111
+ background: white;
112
+ padding: 12px;
113
+ border-radius: 8px;
114
+ border: 1px solid #f0f0f0;
115
+ margin-left: -30px;
116
+ z-index: 2;
117
+ }
118
+
119
+ /* 页脚样式 */
120
+ .custom-thought-chain-item-footer {
121
+ display: flex;
122
+ gap: 8px;
123
+ }
@@ -0,0 +1,214 @@
1
+ // @ts-nocheck
2
+ import React from 'react';
3
+ import { CheckCircleOutlined, EllipsisOutlined, InfoCircleOutlined } from '@ant-design/icons';
4
+
5
+ export const customThoughtChainStyle = `
6
+ /* 思维链容器样式 */
7
+ .custom-thought-chain {
8
+ display: flex;
9
+ flex-direction: column;
10
+ width: 100%;
11
+ }
12
+
13
+ /* 思维链节点项样式 */
14
+ .custom-thought-chain-item {
15
+ position: relative;
16
+ display: flex;
17
+ flex-direction: column;
18
+ padding-left: 40px;
19
+ margin-bottom: 16px;
20
+ }
21
+
22
+ .custom-thought-chain-item-last {
23
+ position: relative;
24
+ display: flex;
25
+ flex-direction: column;
26
+ padding-left: 40px;
27
+ margin-bottom: 16px;
28
+ }
29
+
30
+ .custom-thought-chain-item-last::before {
31
+ content: '';
32
+ position: absolute;
33
+ top: 24px;
34
+ left: 20px;
35
+ width: 2px;
36
+ height: calc(100% - 8px);
37
+ background-color: #4270f5;
38
+ z-index: 1;
39
+ }
40
+
41
+ /* 节点连接线样式 */
42
+ .custom-thought-chain-item::before {
43
+ content: '';
44
+ position: absolute;
45
+ top: 24px;
46
+ left: 20px;
47
+ width: 2px;
48
+ height: calc(100% - 8px);
49
+ background-color: #52c41a;
50
+ z-index: 1;
51
+ }
52
+
53
+ /* 节点头部样式 */
54
+ .custom-thought-chain-item-header {
55
+ display: flex;
56
+ align-items: flex-start;
57
+ margin-bottom: 8px;
58
+ }
59
+
60
+ /* 节点图标样式 */
61
+ .custom-thought-chain-item-icon {
62
+ position: absolute;
63
+ left: 9px;
64
+ top: -1px;
65
+ width: 25px;
66
+ height: 25px;
67
+ display: flex;
68
+ align-items: center;
69
+ justify-content: center;
70
+ background-color: #52c41a;
71
+ border-radius: 50%;
72
+ color: white;
73
+ font-size: 15px;
74
+ z-index: 2;
75
+ }
76
+
77
+ .custom-thought-chain-item-icon-last {
78
+ position: absolute;
79
+ left: 9px;
80
+ top: -1px;
81
+ width: 25px;
82
+ height: 25px;
83
+ display: flex;
84
+ align-items: center;
85
+ justify-content: center;
86
+ background-color: #4270f5;
87
+ border-radius: 50%;
88
+ color: white;
89
+ font-size: 15px;
90
+ z-index: 2;
91
+ }
92
+
93
+ /* 标题容器样式 */
94
+ .custom-thought-chain-item-title-container {
95
+ flex: 1;
96
+ }
97
+
98
+ /* 标题样式 */
99
+ .custom-thought-chain-item-title {
100
+ font-weight: 500;
101
+ color: rgba(0, 0, 0, 0.85);
102
+ margin-bottom: 4px;
103
+ display: flex;
104
+ align-items: center;
105
+ margin-left: 8px;
106
+ }
107
+
108
+ /* 描述样式 */
109
+ .custom-thought-chain-item-description {
110
+ font-size: 14px;
111
+ color: rgba(0, 0, 0, 0.45);
112
+ }
113
+
114
+ /* 内容样式 */
115
+ .custom-thought-chain-item-content {
116
+ margin-bottom: 8px;
117
+ background: white;
118
+ padding: 12px;
119
+ border-radius: 8px;
120
+ border: 1px solid #f0f0f0;
121
+ margin-left: -30px;
122
+ z-index: 2;
123
+ }
124
+
125
+ /* 页脚样式 */
126
+ .custom-thought-chain-item-footer {
127
+ display: flex;
128
+ gap: 8px;
129
+ }
130
+ `
131
+
132
+ /**
133
+ * 自定义思维链节点项接口
134
+ */
135
+ export interface CustomThoughtChainItem {
136
+ title: React.ReactNode;
137
+ description?: React.ReactNode;
138
+ content?: React.ReactNode;
139
+ footer?: React.ReactNode;
140
+ icon?: React.ReactNode;
141
+ status?: 'pending' | 'success' | 'error';
142
+ key?: string;
143
+ }
144
+
145
+ /**
146
+ * 自定义思维链组件接口
147
+ */
148
+ export interface CustomThoughtChainProps {
149
+ items: CustomThoughtChainItem[];
150
+ size?: 'large' | 'middle' | 'small';
151
+ collapsible?: boolean;
152
+ styles?: Record<string, React.CSSProperties>;
153
+ classNames?: Record<string, string>;
154
+ }
155
+
156
+ /**
157
+ * 思维链节点项组件
158
+ * @param props 节点项属性
159
+ * @returns 思维链节点项组件
160
+ */
161
+ const ThoughtChainItem: React.FC<CustomThoughtChainItem & {
162
+ size?: 'large' | 'middle' | 'small';
163
+ }> = (props) => {
164
+ const { title, description, content, footer, icon, status = 'success', size = 'middle', isLast } = props;
165
+ return (
166
+ <div className={`${status === 'pending' ? 'custom-thought-chain-item-last' : 'custom-thought-chain-item'}`}>
167
+ <div className="custom-thought-chain-item-header">
168
+ <div className={`${status === 'pending' ? 'custom-thought-chain-item-icon-last' : 'custom-thought-chain-item-icon'}`}>
169
+ {icon}
170
+ </div>
171
+ <div className="custom-thought-chain-item-title-container">
172
+ {title && <div className="custom-thought-chain-item-title">{title}</div>}
173
+ {description && <div className="custom-thought-chain-item-description">{description}</div>}
174
+ </div>
175
+ </div>
176
+ {content && (
177
+ <div className="custom-thought-chain-item-content">
178
+ {content}
179
+ </div>
180
+ )}
181
+ {footer && (
182
+ <div className="custom-thought-chain-item-footer">
183
+ {footer}
184
+ </div>
185
+ )}
186
+ </div>
187
+ );
188
+ };
189
+
190
+ /**
191
+ * 自定义思维链组件
192
+ * @param props 思维链组件属性
193
+ * @returns 思维链组件
194
+ */
195
+ const CustomThoughtChain: React.FC<CustomThoughtChainProps> = (props) => {
196
+ const { items, size = 'middle', collapsible = false, styles = {}, classNames = {} } = props;
197
+
198
+ return (
199
+ <div
200
+ className={`custom-thought-chain ${classNames.item || ''}`}
201
+ style={styles.item}
202
+ >
203
+ {items.map((item, index) => (
204
+ <ThoughtChainItem
205
+ key={item.key || index}
206
+ {...item}
207
+ size={size}
208
+ />
209
+ ))}
210
+ </div>
211
+ );
212
+ };
213
+
214
+ export default CustomThoughtChain;
@@ -18,11 +18,11 @@ import typeRPubPng from '../../../../assets/aicenter/type-rpub.png';
18
18
  import playPng from '../../../../assets/aicenter/play.png';
19
19
  import playRunGif from '../../../../assets/aicenter/play-run.gif';
20
20
  import copyPng from '../../../../assets/aicenter/copy.png';
21
- import type {ThoughtChainItem} from '@ant-design/x';
22
- import {ThoughtChain} from '@ant-design/x';
23
21
  import {CheckCircleOutlined, EllipsisOutlined, InfoCircleOutlined, ClockCircleOutlined} from '@ant-design/icons';
24
22
  import ChatMessagePlaceholder, {ChatMessagePlaceholderInThought} from "../chatPlaceholder";
25
23
  import {UrlCard} from "./urlCard"
24
+ import {CustomThoughtChainItem, CustomThoughtChainProps} from "./CustomThoughtChain";
25
+ import CustomThoughtChain from "./CustomThoughtChain";
26
26
  let speechSynth = window.speechSynthesis;
27
27
  let utterance = null;
28
28
 
@@ -230,12 +230,12 @@ export default function ChatMessage({
230
230
  }
231
231
 
232
232
  const renderLoading = (type:MessageType, height:number) => {
233
- const skeletonContainerId = `skeleton-container-${Math.random().toString(36).substring(2, 9)}`;
233
+ const skeletonContainerId = `skeleton-container`;
234
234
  if(type == MessageType.echart || type == MessageType.form){
235
235
  return (
236
236
  <div
237
- id={skeletonContainerId}
238
- style={{minWidth: 500, width: '100%', height, display: 'flex', justifyContent: 'center', alignItems: 'center'}}
237
+ id={skeletonContainerId}
238
+ style={{minWidth: 500, width: '100%', height, display: 'flex', justifyContent: 'center', alignItems: 'center'}}
239
239
  >
240
240
  {
241
241
  <Skeleton.Image active={true} style={{width: '100%', height: '100%'}}/>
@@ -251,8 +251,8 @@ export default function ChatMessage({
251
251
  }else if(type === MessageType.url){
252
252
  return (
253
253
  <div
254
- id={skeletonContainerId}
255
- style={{minWidth: 80, width: '100%', height, display: 'flex', justifyContent: 'center', alignItems: 'center'}}
254
+ id={skeletonContainerId}
255
+ style={{minWidth: 80, width: '100%', height, display: 'flex', justifyContent: 'center', alignItems: 'center'}}
256
256
  >
257
257
  {
258
258
  <Skeleton.Button active={true} shape={'default'} block={true} style={{width: '100%', height: '100%'}}/>
@@ -310,9 +310,7 @@ export default function ChatMessage({
310
310
  const {app_name, form_name, form_url} = url_config;
311
311
 
312
312
  // 渲染组件
313
- return (
314
- <UrlCard url={form_url} appName={app_name} menuName={form_name}/>
315
- )
313
+ return <UrlCard url={form_url} appName={app_name} menuName={form_name}/>
316
314
  } catch (error) {
317
315
  return renderLoading(MessageType.url, 50);
318
316
  }
@@ -322,7 +320,7 @@ export default function ChatMessage({
322
320
  },
323
321
  }), [isSubmittingForm]); // 依赖 isSubmittingForm 刷新ui
324
322
 
325
- const getStatusIcon = (status: ThoughtChainItem['status'], icon?: React.ReactNode) => {
323
+ const getStatusIcon = (status: CustomThoughtChainItem['status'], icon?: React.ReactNode) => {
326
324
  switch (status) {
327
325
  case 'success':
328
326
  default:
@@ -351,14 +349,14 @@ export default function ChatMessage({
351
349
  const renderBotTextMessage = () => {
352
350
  const items = messageItemList.map((item, index) => {
353
351
  const {id, thinkMessage, message, loadingMessage, type, name, toolCallInfo, rawInfo} = item;
354
- const isLatest = index === messageItemList.length - 1;
352
+ const isLatestItem = index === messageItemList.length - 1;
355
353
  let status = 'success'
356
354
  // 只有在接收信息的时候有 pending 状态,最后的信息才为 pending
357
- if (receivingMessage && isLatest){
355
+ if (receivingMessage && isLatest && isLatestItem){
358
356
  status = 'pending'
359
357
  }
360
358
 
361
- const resultItem: ThoughtChainItem = {
359
+ const resultItem: CustomThoughtChainItem = {
362
360
  title: <div style={{display:"flex", flexDirection: 'row', alignItems: 'center'}}>
363
361
  {getAvatarByName(name)}
364
362
  <span>{name}</span>
@@ -403,7 +401,7 @@ export default function ChatMessage({
403
401
  };
404
402
  return resultItem
405
403
  });
406
- return <ThoughtChain items={items} size={'small'} />
404
+ return <CustomThoughtChain items={items} size={'small'} />
407
405
  }
408
406
 
409
407
  const renderBotFormMessage = (form_config) => {
@@ -1,11 +1,10 @@
1
- import {ChatMessageType} from "../types/chatWidget";
2
1
  import React from "react";
3
2
 
4
3
  /**
5
4
  * URL卡片样式定义
6
5
  * 用于展示可点击的应用卡片
7
6
  */
8
- const cardStyle= `
7
+ export const cardStyle= `
9
8
  .boxUrlCard{
10
9
  display: inline-block;
11
10
  }
@@ -118,7 +117,6 @@ export const UrlCard= ({
118
117
  }: UrlCardProps) => {
119
118
  return (
120
119
  <div className="boxUrlCard" onClick={() => window.open(url, '_blank')}>
121
- <style dangerouslySetInnerHTML={{ __html: cardStyle }}></style>
122
120
  <div className="section_1">
123
121
  <div className="image-text_2">
124
122
  <img
@@ -3,6 +3,8 @@ import { useRef, useState } from 'react';
3
3
  import ChatWindow from './chatWindow';
4
4
  import { ChatMessageType } from './chatWindow/types/chatWidget';
5
5
  import { styles, yt_style, markdownBody } from "./style"
6
+ import { customThoughtChainStyle } from "./chatWindow/chatMessage/CustomThoughtChain"
7
+ import { cardStyle } from "./chatWindow/chatMessage/urlCard"
6
8
 
7
9
  export default function ChatWidget({
8
10
  is_enable_call,
@@ -115,7 +117,7 @@ export default function ChatWidget({
115
117
 
116
118
  return (
117
119
  <div style={{ position: 'relative',height:'100%' }}>
118
- <style dangerouslySetInnerHTML={{ __html: styles + markdownBody + yt_style }}></style>
120
+ <style dangerouslySetInnerHTML={{ __html: styles + markdownBody + yt_style + customThoughtChainStyle + cardStyle }}></style>
119
121
  <div style={{fontSize: 10, color: '#a3a3a3', position: 'absolute', bottom: 6, width: '100%', display: 'flex', justifyContent: 'center'}}>内容由AI生成,无法保证真实准确,仅供参考</div>
120
122
  <ChatWindow
121
123
  is_enable_call={is_enable_call}