yt-chat-components 1.4.7 → 1.4.8

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.4.7",
3
+ "version": "1.4.8",
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",
package/public/index.html CHANGED
@@ -116,13 +116,14 @@
116
116
  is-show-side-right=false
117
117
  is-show-side-left=true
118
118
  dialog-index="999999999"
119
- agent-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"
119
+ agent-url="https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/kai_yuan/byz/xinge.png"
120
120
  agent-name="白城医学高等专科学校招生咨询平台"
121
121
  logo-width="27px"
122
122
  logo-font-size="20px"
123
123
  is-title-side-icon=true
124
124
  is-show-upload-button=false
125
125
  drop-man-url="https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/ai/ai_man01.png"
126
+ banner-map='{"a":"https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/school/bcyz/user/ai/banner.png","b":"https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/school/bcyz/user/ai/banner.png","c":"https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/school/bcyz/user/ai/banner.png"}'
126
127
  />
127
128
  </body>
128
129
  </html>
@@ -405,12 +405,20 @@ export default function ChatMessage({
405
405
  </div>,
406
406
  footer: <div key={id} className="msg_operateBox">
407
407
  {isShowReadIcon && <img src={isPlay ? playRunGif : playPng} onClick={() => playVoice(message)}/>}
408
- <img src={copyPng} onClick={() => copyText(message)} />
408
+ <img src={copyPng} onClick={() => copyText(message)}/>
409
+ <div style={{
410
+ fontSize: 10,
411
+ color: '#a3a3a3',
412
+ bottom: 6,
413
+ width: '100%',
414
+ marginLeft:'4px',
415
+ }}>内容由AI生成,无法保证真实准确,仅供参考
416
+ </div>
409
417
  </div>
410
418
  };
411
419
  return resultItem
412
420
  });
413
- return <CustomThoughtChain items={items} size={'small'} />
421
+ return <CustomThoughtChain items={items} size={'small'}/>
414
422
  }
415
423
 
416
424
  const renderBotFormMessage = (form_config) => {
@@ -1,6 +1,6 @@
1
1
  // @ts-nocheck
2
2
  import {extractMessageFromOutput} from './utils';
3
- import React, {Context, useEffect, useRef, useState} from 'react';
3
+ import React, {Context, useCallback, useEffect, useRef, useState} from 'react';
4
4
  import {ChatMessageType, embedAppExtend, InputValueType, MessageItem, MessageType} from './types/chatWidget';
5
5
  import ChatMessage from './chatMessage';
6
6
  import {fetchUploadFile, getChatHistory, sendMessage} from './controllers';
@@ -27,6 +27,7 @@ import CallInterface from './callInterface/index.tsx';
27
27
  import {Image, message as messageTip, Tooltip, Typography} from 'antd';
28
28
  import {isEmpty, isFunction} from 'lodash';
29
29
  import btn_answer from '../../../assets/aicenter/btn_answer.png';
30
+ import {MethodContext} from "../../previewDialogV2";
30
31
 
31
32
 
32
33
  let mediaRecorder = null; // 语音对象,用于录音
@@ -88,7 +89,6 @@ export default function ChatWindow({
88
89
  isShowReadIcon,
89
90
  renderCustomDropDown,
90
91
  isTagsHidden,
91
- MethodContext
92
92
  }: {
93
93
  is_enable_call:boolean;
94
94
  tags: [];
@@ -138,7 +138,6 @@ export default function ChatWindow({
138
138
  isShowReadIcon?:boolean;
139
139
  renderCustomDropDown?: Function;
140
140
  isTagsHidden?: boolean;
141
- MethodContext?:Context<any>;
142
141
  }) {
143
142
  const ref = useRef<HTMLDivElement>(null);
144
143
  const lastMessage = useRef<HTMLDivElement>(null);
@@ -148,6 +147,7 @@ export default function ChatWindow({
148
147
  /* Initial listener for loss of focus that refocuses User input after a small delay */
149
148
  const [nowAIContentList, setNowAIContentList] = useState<Array<MessageItem>>([]);
150
149
  const [receivingMessage, setReceivingMessage] = useState(false);
150
+ const receivingMessageRef = useRef(receivingMessage);
151
151
  const abortControllerRef = useRef(new AbortController());
152
152
  const [fileList, setFileList] = useState<
153
153
  { file: File; fileUrl: string; fileType: string; fileId: string }[]
@@ -159,12 +159,12 @@ export default function ChatWindow({
159
159
  const [recordState, setRecordState] = useState(false); // 录音状态。true为正在录音,false为停止录音
160
160
  const [tagList, setTagList] = useState([]); // 问题标签列表
161
161
  const {isTitleSideIcon, logoWidth, agentUrl} = baseConfig;
162
- const [inputContainerHeight, setInputContainerHeight] = useState('50px')
162
+ const [inputContainerHeight, setInputContainerHeight] = useState('120px')
163
163
  let content_id: string = null
164
164
  let content_ns: string = null
165
165
  let event_latest: string = null
166
166
  const nowAIContentListRef = useRef(nowAIContentList);
167
- const { callDMethod } = React.useContext(MethodContext);
167
+ const {registerChatMethods} = React.useContext(MethodContext);
168
168
  let voiceChunks = []; // 临时存储录制的语音片段
169
169
  // 滚动事件处理,选择文件时,文件内容超出显示框时,显示左右箭头
170
170
  const handleScroll = () => {
@@ -957,10 +957,14 @@ export default function ChatWindow({
957
957
  }, [sessionId]);
958
958
 
959
959
  useEffect(() => {
960
- if (callDMethod) {
961
- callDMethod(handleSendMessage);
960
+ console.log("registerChatMethods",registerChatMethods)
961
+ if (registerChatMethods) {
962
+ registerChatMethods({
963
+ isActiveMessage,
964
+ handleSendMessage,
965
+ })
962
966
  }
963
- }, [callDMethod]);
967
+ }, [registerChatMethods]);
964
968
 
965
969
  /**
966
970
  * 开场白展示优化
@@ -979,6 +983,15 @@ export default function ChatWindow({
979
983
  }
980
984
  return 'cl-drop-horizontal'
981
985
  }
986
+ useEffect(() => {
987
+ receivingMessageRef.current = receivingMessage;
988
+ }, [receivingMessage]);
989
+ /**
990
+ * 对话是否处于活跃状态
991
+ * */
992
+ const isActiveMessage = useCallback(() => {
993
+ return !!receivingMessageRef.current;
994
+ }, []);
982
995
 
983
996
  const renderTipsInfo = () => {
984
997
  if (isFunction(renderCustomDropDown)) {
@@ -1176,9 +1189,9 @@ export default function ChatWindow({
1176
1189
  </div>
1177
1190
  <div className="w_inputBox" style={{height: inputContainerHeight}}>
1178
1191
  <textarea
1179
- onFocus={() => setInputContainerHeight('120px')}
1192
+ // onFocus={() => setInputContainerHeight('120px')}
1180
1193
  maxLength={5000}
1181
- onBlur={() => setTimeout(() => setInputContainerHeight('50px'), 200)}
1194
+ // onBlur={() => setTimeout(() => setInputContainerHeight('50px'), 200)}
1182
1195
  // value={inputValue}
1183
1196
  onChange={(e) => setValue(e.target.value)}
1184
1197
  onKeyDown={(e) => {
@@ -1271,10 +1284,7 @@ export default function ChatWindow({
1271
1284
  }
1272
1285
  if(isTagsHidden){
1273
1286
  return inputNode;
1274
- }else{
1275
-
1276
1287
  }
1277
-
1278
1288
  return (
1279
1289
  <>
1280
1290
  <div
@@ -52,7 +52,6 @@ export default function ChatWidget({
52
52
  isShowReadIcon,
53
53
  renderCustomDropDown,
54
54
  isTagsHidden,
55
- MethodContext
56
55
  }: {
57
56
  is_enable_call:boolean,
58
57
  tags: [];
@@ -98,7 +97,6 @@ export default function ChatWidget({
98
97
  isShowReadIcon: boolean,
99
98
  renderCustomDropDown: Function,
100
99
  isTagsHidden: boolean;
101
- MethodContext: Context<any>;
102
100
  }) {
103
101
  const [open, setOpen] = useState(start_open);
104
102
  const [messages, setMessages] = useState<ChatMessageType[]>([]);
@@ -124,7 +122,6 @@ export default function ChatWidget({
124
122
  return (
125
123
  <div style={{ position: 'relative',height:'100%' }}>
126
124
  <style dangerouslySetInnerHTML={{ __html: styles + markdownBody + yt_style + customThoughtChainStyle + cardStyle }}></style>
127
- <div style={{fontSize: 10, color: '#a3a3a3', position: 'absolute', bottom: 6, width: '100%', display: 'flex', justifyContent: 'center'}}>内容由AI生成,无法保证真实准确,仅供参考</div>
128
125
  <ChatWindow
129
126
  is_enable_call={is_enable_call}
130
127
  tags={tags}
@@ -176,7 +173,6 @@ export default function ChatWidget({
176
173
  isShowReadIcon={isShowReadIcon}
177
174
  renderCustomDropDown={renderCustomDropDown}
178
175
  isTagsHidden={isTagsHidden}
179
- MethodContext={MethodContext}
180
176
  />
181
177
  </div>
182
178
  );
@@ -254,8 +254,7 @@ video {
254
254
 
255
255
  .cl-window {
256
256
  border-radius: 1rem;
257
- padding-top: 1.8rem;
258
- padding-bottom: 1.2rem;
257
+ padding-top: 1.7rem;
259
258
  }
260
259
 
261
260
  .cl-middle-container{
@@ -263,10 +262,10 @@ video {
263
262
  display: flex;
264
263
  flex-direction: column;
265
264
  overflow: hidden;
266
- border-left:0.5px solid #3850FF2E;
267
- border-right:0.5px solid #3850FF2E;
268
- padding-left:1.6rem;
269
- padding-right:1.6rem;
265
+ // border-left:0.5px solid #3850FF2E;
266
+ // border-right:0.5px solid #3850FF2E;
267
+ // padding-left:0.4rem;
268
+ // padding-right:0.4rem;
270
269
  }
271
270
 
272
271
 
@@ -2415,7 +2414,7 @@ export const yt_style = `
2415
2414
  display: flex;
2416
2415
  align-items: center;
2417
2416
  box-shadow: 0px 2px 15px 0px rgba(0,48,187,0.1);
2418
- border-radius: 30px;
2417
+ border-radius: 11px;
2419
2418
  background: #FFFFFF;
2420
2419
  transition: height 0.2s ease;
2421
2420
  }
@@ -1,5 +1,5 @@
1
1
  import React, { useState } from 'react';
2
- import { Tabs, Button, Typography } from 'antd';
2
+ import { Tabs, Button, Typography, ConfigProvider } from 'antd';
3
3
  import { LeftOutlined, RightOutlined, SyncOutlined } from '@ant-design/icons';
4
4
  import styles from './index.module.css';
5
5
 
@@ -18,19 +18,15 @@ const defaultMap = {
18
18
 
19
19
  const TabSelector = ({ map = defaultMap, customUrl, handleRowClick, welcomeWords, isSimple }) => {
20
20
  const [activeKey, setActiveKey] = useState(Object.keys(map)[0]);
21
- const [tabPage, setTabPage] = useState(0);
22
21
  const [valuePage, setValuePage] = useState(0);
23
- const tabsPerPage = isSimple ? 3 : 4; // Number of tabs to show per page
22
+ const [tabLocation, setTabLocation] = useState(0);
24
23
  const valuesPerPage = 5; // Number of values to show per page
25
24
  const [pageLoading, setPageLoading] = useState(false);
25
+ const keyShowSize = isSimple ? 2 : 4;
26
26
 
27
27
  const keys = Object.keys(map);
28
28
  const values = map[activeKey] || [];
29
29
 
30
- // Calculate visible tabs for current page
31
- const visibleTabs = keys.slice(tabPage * tabsPerPage, (tabPage + 1) * tabsPerPage);
32
-
33
- // Calculate visible values for current page
34
30
  const visibleValues = isSimple ? values : values.slice(valuePage * valuesPerPage, (valuePage + 1) * valuesPerPage);
35
31
 
36
32
  const handleTabChange = (key) => {
@@ -39,24 +35,14 @@ const TabSelector = ({ map = defaultMap, customUrl, handleRowClick, welcomeWords
39
35
  };
40
36
 
41
37
  const handleTabPrev = () => {
42
- setTabPage((prev) => {
43
- const maxPage = Math.ceil(keys.length / tabsPerPage) - 1;
44
- return prev > 0 ? prev - 1 : maxPage;
45
- });
46
- // Ensure activeKey is within visible tabs
47
- if ( !visibleTabs.includes(activeKey)) {
48
- setActiveKey(visibleTabs[0]);
38
+ if(tabLocation!==0){
39
+ setTabLocation(tabLocation - 1)
49
40
  }
50
41
  };
51
42
 
52
43
  const handleTabNext = () => {
53
- setTabPage((prev) => {
54
- const maxPage = Math.ceil(keys.length / tabsPerPage) - 1;
55
- return prev < maxPage ? prev + 1 : 0;
56
- });
57
- // Ensure activeKey is within visible tabs
58
- if ( !visibleTabs.includes(activeKey)) {
59
- setActiveKey(visibleTabs[0]);
44
+ if (tabLocation !== keys.length - keyShowSize) {
45
+ setTabLocation(tabLocation + 1)
60
46
  }
61
47
  };
62
48
 
@@ -72,6 +58,13 @@ const TabSelector = ({ map = defaultMap, customUrl, handleRowClick, welcomeWords
72
58
  };
73
59
 
74
60
  return (
61
+ <ConfigProvider theme={{
62
+ components: {
63
+ Tabs: {
64
+ horizontalItemGutter:48,
65
+ }
66
+ }
67
+ }}>
75
68
  <div className={styles.mainContainer} style={{ marginLeft: isSimple ? "0" : '24px' }}>
76
69
  {
77
70
  welcomeWords && <div className={styles.welcome}>{welcomeWords}</div>
@@ -100,37 +93,54 @@ const TabSelector = ({ map = defaultMap, customUrl, handleRowClick, welcomeWords
100
93
  style={{ paddingLeft: isSimple ? "0" : '20px', paddingRight: isSimple ? "0" : '20px' }}
101
94
  >
102
95
  <LeftOutlined className={styles.leftArrow} onClick={handleTabPrev}
103
- style={{ marginBottom: isSimple ? "0" : '14px' }}/>
96
+ style={{
97
+ marginBottom: isSimple ? "0" : '14px',
98
+ marginRight: isSimple ? "0" : '12px',
99
+ cursor: tabLocation === 0 ? 'not-allowed' : 'pointer'
100
+ }}
101
+ />
104
102
  {
105
103
  isSimple ? (
106
104
  <div className={styles.simpleHeader}>
107
- {visibleTabs.map(key => <div
105
+ {keys
106
+ .slice(tabLocation, tabLocation + keyShowSize)
107
+ .map(key => <div
108
108
  className={styles.simplyRow}
109
109
  style={{
110
110
  background: key === activeKey ? "#1974FF" : "#FFFFFF",
111
111
  color: key === activeKey ? "#FFFFFF" : "#A4A4A4",
112
112
  border:key === activeKey ? "unset" : "1px solid #E4E4E4",
113
+ transform: 'translate3d(0px, 0px, 0px)'
113
114
  }}
114
115
  onClick={()=>handleTabChange(key)}
115
116
  >{key}</div>)}
116
117
  </div>
117
118
  )
118
119
  :
119
- <Tabs activeKey={activeKey} onChange={handleTabChange}>
120
- {visibleTabs.map((key) => (
120
+ <Tabs activeKey={activeKey} onChange={handleTabChange} className={styles.headerTabs} horizontalItemGutter={40}>
121
+ {keys
122
+ .slice(tabLocation, tabLocation + keyShowSize)
123
+ .map((key) => (
121
124
  <Tabs.TabPane tab={key} key={key}/>
122
125
  ))}
123
126
  </Tabs>
124
127
  }
125
- <RightOutlined className={styles.rightArrow} onClick={handleTabNext}
126
- style={{ marginBottom: isSimple ? "0" : '14px' }}/>
128
+ <RightOutlined
129
+ className={styles.rightArrow}
130
+ onClick={handleTabNext}
131
+ style={{
132
+ marginBottom: isSimple ? "0" : '14px',
133
+ marginLeft: isSimple ? "0" : '12px',
134
+ cursor: tabLocation === keys.length - keyShowSize ? 'not-allowed' : 'pointer'
135
+ }}
136
+ />
127
137
  </div>
128
138
  <div className={styles.valueList}>
129
139
  {visibleValues.map((item, index) => (
130
140
  <div className={styles.row} key={index} onClick={() => handleRowClick(item)}>
131
141
  <Typography.Paragraph
132
142
  className={styles.text}
133
- style={{ maxWidth: isSimple ? '300px' : '400px' }}
143
+ style={{ maxWidth: isSimple ? '210px' : '300px' }}
134
144
  ellipsis={{ rows: 1, tooltip: `${item}`, }}><span
135
145
  style={{ marginRight: '12px' }}>·</span>{item}
136
146
  </Typography.Paragraph>
@@ -146,6 +156,7 @@ const TabSelector = ({ map = defaultMap, customUrl, handleRowClick, welcomeWords
146
156
  </div>
147
157
  </div>
148
158
  </div>
159
+ </ConfigProvider>
149
160
  );
150
161
  };
151
162
 
@@ -75,6 +75,10 @@
75
75
  color: #1974FF;
76
76
  }
77
77
 
78
+ .headerTabs{
79
+ width: 100%;
80
+ }
81
+
78
82
  .simpleHeader{
79
83
  display: flex;
80
84
  justify-content: space-evenly;
@@ -97,6 +101,8 @@
97
101
  font-size: 16px;
98
102
  color: #000000;
99
103
  overflow-y: auto;
104
+ scrollbar-width: thin !important;
105
+ scrollbar-color: #ced4e3 transparent;
100
106
 
101
107
  .row {
102
108
  padding: 8px 12px;
@@ -104,7 +110,6 @@
104
110
  align-items: center;
105
111
  justify-content: space-between;
106
112
  cursor: pointer;
107
- margin-bottom: 4px;
108
113
  .text{
109
114
  font-size: 16px;
110
115
  margin-bottom: 0;
@@ -5,8 +5,8 @@ import { getFlowInfo, getHistoryList } from '../chatWidget/chatWindow/controller
5
5
  import './index.module.css'
6
6
  import { v4 as uuidv4 } from 'uuid';
7
7
  import historyListEmptyPng from '../../assets/aicenter/history-list-empty.png';
8
- import { isEmpty } from "lodash";
9
- import { Carousel, message as messageTip, Progress, Skeleton, Tooltip } from 'antd'
8
+ import { isEmpty, isFunction } from "lodash";
9
+ import { Carousel, message, message as messageTip, Progress, Skeleton, Tooltip } from 'antd'
10
10
  import Icon, { HistoryOutlined, PlusOutlined } from "@ant-design/icons";
11
11
  import TabSelector from "../components/TabSelector";
12
12
 
@@ -24,11 +24,12 @@ const CommentIcon = (props) => (
24
24
  );
25
25
 
26
26
  const contentStyle = {
27
- height: '160px',
27
+ width:'100%',
28
28
  color: '#fff',
29
29
  lineHeight: '160px',
30
30
  textAlign: 'center',
31
31
  background: '#364d79',
32
+ borderRadius:'11px',
32
33
  };
33
34
 
34
35
  const style = `
@@ -46,22 +47,24 @@ const style = `
46
47
  .p_toolDialog .p_sign{
47
48
  width: calc(100vw - 140px);
48
49
  margin: 0 auto;
50
+ min-width: 1200px;
49
51
  }
50
52
 
51
53
  .dialog_box{
52
- margin: 24px auto 0;
53
- width: calc(100vw - 140px);
54
- height: calc(100vh - 200px);
55
- background: #fff;
56
- border-radius: 15px;
57
- display: flex;
58
- flex-direction: column;
54
+ margin: 24px auto 0;
55
+ width: calc(100vw - 140px);
56
+ height: calc(100vh - 200px);
57
+ background: #fff;
58
+ border-radius: 15px;
59
+ display: flex;
60
+ flex-direction: column;
61
+ min-width: 1200px;
59
62
  }
60
63
  .p_toolDialog .p_toolLeft {
61
64
  display: flex;
62
65
  flex-direction: column;
63
66
  align-items: center;
64
- width: 400px;
67
+ width: 300px;
65
68
  padding: 1.7rem 1.6rem 1.7rem 1.6rem;
66
69
 
67
70
  border-top-left-radius: 8px;
@@ -80,6 +83,9 @@ const style = `
80
83
 
81
84
  .p_toolDialog .dialog_box .p_toolLogo .p_logoImg {
82
85
  width: 48px;
86
+ position: absolute;
87
+ top: 2px;
88
+ transform: scale3d(1.3, 1.3, 1.3);
83
89
  }
84
90
 
85
91
  .p_toolDialog .dialog_box .p_toolLogo .p_logoText {
@@ -103,7 +109,7 @@ const style = `
103
109
  border-image: linear-gradient(180deg, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0)) 1 1;
104
110
  backdrop-filter: blur(10px);
105
111
  position: relative;
106
- max-height:calc(100% - 5.5rem - 60px);
112
+ max-height:calc(100% - 60px);
107
113
  }
108
114
 
109
115
  .p_toolDialog .p_toolLeft .p_historyDialog ::-webkit-scrollbar-thumb {
@@ -140,12 +146,12 @@ const style = `
140
146
  text-align: center;
141
147
  font-size: 12px;
142
148
  color: #999999;
143
- max-height: calc(100% - 3rem);
149
+ max-height: calc(100% - 1.7rem);
144
150
 
145
151
  }
146
152
 
147
153
  .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList {
148
- height: calc(100% - 3rem);
154
+ height: calc(100% - 1.7rem);
149
155
  margin-top: 10px;
150
156
  overflow-y: auto;
151
157
  scrollbar-width: none !important; /* firefox */
@@ -192,15 +198,15 @@ const style = `
192
198
 
193
199
  .p_toolDialog .p_toolRight {
194
200
  flex: 1;
195
- background: #F0F0F0;
201
+ background: #f5f5f5;h
196
202
  }
197
203
 
198
204
  .p_toolRightToRight {
199
205
  height:100%;
200
- width:400px;
206
+ width:300px;
201
207
  display:flex;
202
208
  flex-direction:column;
203
- padding:2rem 1.6rem 1.8rem 1.6rem
209
+ padding:1.7rem 1.6rem 1.8rem 1.6rem
204
210
  }
205
211
  .p_toolRightToRight .p_hot{
206
212
  display:flex;
@@ -226,13 +232,20 @@ const style = `
226
232
  .p_toolRightToRight .p_carousel .slick-dots-bottom{
227
233
  justify-content: end;
228
234
  right:12px;
235
+ bottom:-10px;
236
+ }
237
+ :where(.css-dev-only-do-not-override-1v613y0).ant-carousel .slick-dots li.slick-active::after{
238
+ background:#1974FF;
239
+ }
240
+
241
+ :where(.css-dev-only-do-not-override-1v613y0).ant-carousel .slick-dots li button{
242
+ background: #000000;
229
243
  }
230
244
 
231
245
  .p_newDialog {
232
- width: 352px;
246
+ width: 252px;
233
247
  height: 40px;
234
248
  min-height:40px;
235
- margin-top: 20px;
236
249
  cursor: pointer;
237
250
  display: flex;
238
251
  color:#0060FF;
@@ -276,7 +289,7 @@ const defaultList = [
276
289
 
277
290
  const api_key = 'sk-mniUFDpcWwvNF3iFzssXa6etN-S_Y4AApyHYcBU44L0';
278
291
 
279
- const MethodContext = React.createContext();
292
+ export const MethodContext = React.createContext();
280
293
 
281
294
  export class ToolDialogV2 extends React.Component {
282
295
 
@@ -342,13 +355,18 @@ export class ToolDialogV2 extends React.Component {
342
355
  this.setState({ sessionId });
343
356
  };
344
357
 
345
- callDMethod = (method) => {
346
- this.handleSendMessage = method;
347
- };
358
+ registerChatMethods = ({ isActiveMessage, handleSendMessage }) => {
359
+ this.handleSendMessage = handleSendMessage;
360
+ this.isActiveMessage = isActiveMessage;
361
+ }
362
+
348
363
 
349
364
  handleClick = (word) => {
350
- if (typeof this.handleSendMessage === 'function') {
365
+ if(!this.isActiveMessage()){
351
366
  this.handleSendMessage(word);
367
+ }else{
368
+ message.destroy();
369
+ message.info("请等待回复结束后再发送")
352
370
  }
353
371
  };
354
372
 
@@ -368,9 +386,12 @@ export class ToolDialogV2 extends React.Component {
368
386
  const { title } = this.props;
369
387
  const { currentFlow } = this.state;
370
388
  return <TabSelector handleRowClick={(word)=> {
371
- this.setState({ dropDownList: [] });
372
- if (typeof this.handleSendMessage === 'function') {
389
+ if(!this.isActiveMessage()){
390
+ this.setState({ dropDownList: [] });
373
391
  this.handleSendMessage(word);
392
+ }else{
393
+ message.destroy();
394
+ message.info("请等待回复结束后再发送")
374
395
  }
375
396
  }} welcomeWords={`Hi,欢迎使用${currentFlow.name||title},您可以这样问我:`}/>
376
397
  }
@@ -397,6 +418,7 @@ export class ToolDialogV2 extends React.Component {
397
418
  modalWidth,
398
419
  isShowReadIcon = false,
399
420
  signUrl,
421
+ bannerMap,
400
422
  } = this.props;
401
423
  const { currentFlow = {} } = this.state;
402
424
  return (
@@ -409,7 +431,17 @@ export class ToolDialogV2 extends React.Component {
409
431
  </div>
410
432
  <div className={"dialog_box"}>
411
433
  <div className="p_toolLogo">
412
- <img className="p_logoImg" style={{ width: logoWidth, borderRadius: 15 }} src={agentUrl}/>
434
+ <div style={{
435
+ width: logoWidth,
436
+ height: logoWidth,
437
+ backgroundColor: '#1974FF',
438
+ borderRadius: '22px',
439
+ position: 'relative',
440
+ overflow: 'hidden',
441
+ }}>
442
+ <img className="p_logoImg"
443
+ src={agentUrl}/>
444
+ </div>
413
445
  <div className="p_logoText" style={{ fontSize: logoFontSize }}>{agentName}</div>
414
446
  </div>
415
447
  <div style={{display: 'flex',flexDirection:"row",flex: 1,height: 'calc(100% - 75px)'}}>
@@ -456,7 +488,7 @@ export class ToolDialogV2 extends React.Component {
456
488
  </div>
457
489
  }
458
490
  <div className="p_toolRight">
459
- <MethodContext.Provider value={{ callDMethod: this.callDMethod }}>
491
+ <MethodContext.Provider value={{registerChatMethods:this.registerChatMethods}}>
460
492
  <ChatWidget
461
493
  window_title={currentFlow?.name || title}
462
494
  flow_id={currentFlow?.id || flowId}
@@ -477,27 +509,21 @@ export class ToolDialogV2 extends React.Component {
477
509
  isShowChatHeader={false}
478
510
  renderCustomDropDown={this.renderCustomDropDown}
479
511
  isTagsHidden={true}
480
- MethodContext={MethodContext}
481
512
  placeholder={'请输入您想咨询的问题'}
482
513
  />
483
514
  </MethodContext.Provider>
484
515
  </div>
485
516
  <div className={'p_toolRightToRight'}>
486
517
  <Carousel autoplay={{ dotDuration: true }} autoplaySpeed={4000} className={'p_carousel'}>
487
- <div>
488
- <h3 style={contentStyle}>1</h3>
489
- </div>
490
- <div>
491
- <h3 style={contentStyle}>2</h3>
492
- </div>
493
- <div>
494
- <h3 style={contentStyle}>3</h3>
495
- </div>
496
- <div>
497
- <h3 style={contentStyle}>4</h3>
498
- </div>
518
+ {
519
+ Object.values(bannerMap).map(item => (
520
+ <div key={item}>
521
+ <img style={contentStyle} src={item}/>
522
+ </div>
523
+ ))
524
+ }
499
525
  </Carousel>
500
- <div style={{ height: '1px', background: '#E5E5E5',marginTop: '30px' }}/>
526
+ <div style={{ height: '1px', background: '#E5E5E5',marginTop: '25px' }}/>
501
527
  <div className={'p_hot'}>
502
528
  <img src={'https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/school/bcyz/user/ai/hot.png'}/>
503
529
  <span>热点问题</span>
@@ -1,20 +1,22 @@
1
- .p_closeImg {
1
+ .closeImg {
2
2
  width: 14px;
3
3
  cursor: pointer;
4
4
  }
5
5
 
6
- .p_toolDialog {
7
- height:100%;
8
- border-radius:8px;
6
+ .toolDialog {
7
+ height: 100%;
8
+ border-radius: 8px;
9
9
  display: flex;
10
10
  flex-direction: column;
11
11
  }
12
- .p_toolDialog .p_sign{
12
+
13
+ .toolDialogSign {
13
14
  width: calc(100vw - 140px);
14
15
  margin: 0 auto;
16
+ min-width: 1200px;
15
17
  }
16
18
 
17
- .dialog_box{
19
+ .dialogBox {
18
20
  margin: 24px auto 0;
19
21
  width: calc(100vw - 140px);
20
22
  height: calc(100vh - 200px);
@@ -22,43 +24,46 @@
22
24
  border-radius: 15px;
23
25
  display: flex;
24
26
  flex-direction: column;
27
+ min-width: 1200px;
25
28
  }
26
- .p_toolDialog .p_toolLeft {
29
+
30
+ .toolLeft {
27
31
  display: flex;
28
32
  flex-direction: column;
29
33
  align-items: center;
30
- width: 400px;
34
+ width: 300px;
31
35
  padding: 1.7rem 1.6rem 1.7rem 1.6rem;
32
-
33
36
  border-top-left-radius: 8px;
34
37
  border-bottom-left-radius: 8px;
35
38
  }
36
39
 
37
- .p_toolDialog .dialog_box .p_toolLogo {
40
+ .toolLogo {
38
41
  user-select: none;
39
42
  display: flex;
40
43
  align-items: center;
41
44
  margin-top: 18px;
42
45
  padding-left: 32px;
43
- padding-bottom:12px;
46
+ padding-bottom: 12px;
44
47
  border-bottom: #E5E5E5 solid 1px;
45
48
  }
46
49
 
47
- .p_toolDialog .dialog_box .p_toolLogo .p_logoImg {
50
+ .logoImg {
48
51
  width: 48px;
52
+ position: absolute;
53
+ top: 2px;
54
+ transform: scale3d(1.3, 1.3, 1.3);
49
55
  }
50
56
 
51
- .p_toolDialog .dialog_box .p_toolLogo .p_logoText {
57
+ .logoText {
52
58
  font-weight: bold;
53
59
  margin-left: 10px;
54
60
  font-size: 20px;
55
- background: #000000;
56
- /*background: linear-gradient(to right, #1551FF, #8F4BFF);*/
61
+ /* background: linear-gradient(to right, #1551FF, #8F4BFF); */
57
62
  -webkit-background-clip: text;
58
63
  -webkit-text-fill-color: transparent;
59
64
  }
60
65
 
61
- .p_toolDialog .p_toolLeft .p_historyDialog {
66
+ .historyDialog {
62
67
  user-select: none;
63
68
  margin-top: 20px;
64
69
  margin-bottom: 20px;
@@ -69,36 +74,30 @@
69
74
  border-image: linear-gradient(180deg, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0)) 1 1;
70
75
  backdrop-filter: blur(10px);
71
76
  position: relative;
72
- max-height:calc(100% - 5.5rem - 60px);
77
+ max-height: calc(100% - 60px);
73
78
  }
74
79
 
75
- .p_toolDialog .p_toolLeft .p_historyDialog ::-webkit-scrollbar-thumb {
76
- border-radius: 10px;
77
- -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
78
- background: #535353 !important;
79
- }
80
-
81
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyTitle {
80
+ .historyTitle {
82
81
  display: flex;
83
82
  align-items: center;
84
83
  justify-content: space-between;
85
84
  }
86
85
 
87
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyTitle .p_historyImg {
86
+ .historyImg {
88
87
  width: 25px;
89
88
  }
90
89
 
91
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyTitle .p_dialogTitle {
90
+ .dialogTitle {
92
91
  font-size: 18px;
93
92
  line-height: 16px;
94
93
  text-align: left;
95
94
  font-style: normal;
96
- display:flex;
95
+ display: flex;
97
96
  font-weight: normal;
98
97
  color: #A4A4A4;
99
98
  }
100
99
 
101
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyListEmpty {
100
+ .historyListEmpty {
102
101
  position: absolute;
103
102
  top: 50%;
104
103
  left: 50%;
@@ -106,47 +105,46 @@
106
105
  text-align: center;
107
106
  font-size: 12px;
108
107
  color: #999999;
109
- max-height: calc(100% - 3rem);
110
-
108
+ max-height: calc(100% - 1.7rem);
111
109
  }
112
110
 
113
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList {
114
- height: calc(100% - 3rem);
111
+ .historyList {
112
+ height: calc(100% - 1.7rem);
115
113
  margin-top: 10px;
116
114
  overflow-y: auto;
117
- scrollbar-width: none !important; /* firefox */
115
+ scrollbar-width: none !important;
118
116
  }
119
117
 
120
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList::-webkit-scrollbar{
121
- display:none;
118
+ .historyList::-webkit-scrollbar {
119
+ display: none;
122
120
  }
123
121
 
124
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList:hover {
125
- scrollbar-width: thin !important; /* firefox */
122
+ .historyList:hover {
123
+ scrollbar-width: thin !important;
126
124
  scrollbar-color: #ced4e3 transparent;
127
125
  }
128
126
 
129
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList .p_historyItem {
127
+ .historyItem {
130
128
  padding: 10px 16px;
131
129
  padding-left: 0;
132
- margin-bottom:4px;
130
+ margin-bottom: 4px;
133
131
  }
134
132
 
135
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList .p_historyItem:hover{
133
+ .historyItem:hover {
136
134
  background: #F5F5F5;
137
135
  border-radius: 9px;
138
136
  }
139
137
 
140
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList .p_historyItem:hover .p_historyName{
141
- color: #1552FF
138
+ .historyItem:hover .historyName {
139
+ color: #1552FF;
142
140
  }
143
141
 
144
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList .p_activeItem{
142
+ .activeItem {
145
143
  background: #F5F5F5;
146
144
  border-radius: 9px;
147
145
  }
148
146
 
149
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList .p_historyItem .p_historyName {
147
+ .historyName {
150
148
  color: #333333;
151
149
  overflow: hidden;
152
150
  text-overflow: ellipsis;
@@ -156,70 +154,79 @@
156
154
  align-items: center;
157
155
  }
158
156
 
159
- .p_toolDialog .p_toolRight {
157
+ .toolRight {
160
158
  flex: 1;
161
- background: #F0F0F0;
159
+ background: #f5f5f5;
162
160
  }
163
161
 
164
- .p_toolRightToRight {
165
- height:100%;
166
- width:400px;
167
- display:flex;
168
- flex-direction:column;
169
- padding:2rem 1.6rem 1.8rem 1.6rem
162
+ .toolRightToRight {
163
+ height: 100%;
164
+ width: 300px;
165
+ display: flex;
166
+ flex-direction: column;
167
+ padding: 1.7rem 1.6rem 1.8rem 1.6rem;
170
168
  }
171
- .p_toolRightToRight .p_hot{
172
- display:flex;
169
+
170
+ .hot {
171
+ display: flex;
173
172
  align-items: center;
174
173
  }
175
174
 
176
- .p_toolRightToRight .p_hot img{
177
- width:19px;
178
- margin-right:10px;
175
+ .hot img {
176
+ width: 19px;
177
+ margin-right: 10px;
179
178
  }
180
179
 
181
- .p_toolRightToRight .p_hot span{
180
+ .hot span {
182
181
  font-size: 18px;
183
182
  color: #000000;
184
183
  line-height: 59px;
185
184
  }
186
185
 
187
- .p_toolRightToRight .p_carousel h3{
188
- margin:0;
189
- border-radius:12px;
186
+ .carousel h3 {
187
+ margin: 0;
188
+ border-radius: 12px;
190
189
  }
191
190
 
192
- .p_toolRightToRight .p_carousel .slick-dots-bottom{
191
+ .carousel .slick-dots-bottom {
193
192
  justify-content: end;
194
- right:12px;
193
+ right: 12px;
194
+ bottom: -10px;
195
+ }
196
+
197
+ :where(.css-dev-only-do-not-override-1v613y0).ant-carousel .slick-dots li.slick-active::after {
198
+ background: #1974FF;
195
199
  }
196
200
 
197
- .p_newDialog {
198
- width: 352px;
201
+ :where(.css-dev-only-do-not-override-1v613y0).ant-carousel .slick-dots li button {
202
+ background: #000000;
203
+ }
204
+
205
+ .newDialog {
206
+ width: 252px;
199
207
  height: 40px;
200
- min-height:40px;
201
- margin-top: 20px;
208
+ min-height: 40px;
202
209
  cursor: pointer;
203
210
  display: flex;
204
- color:#0060FF;
211
+ color: #0060FF;
205
212
  align-items: center;
206
213
  background: #EAF3FF;
207
214
  border-radius: 11px;
208
215
  border: 1px solid #1974FF;
209
- transition: all 0.2s ease; /* 添加过渡动画 */
216
+ transition: all 0.2s ease;
210
217
  }
211
218
 
212
- .p_newDialog:hover {
219
+ .newDialog:hover {
213
220
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
214
221
  }
215
222
 
216
- .p_newDialog:active {
223
+ .newDialog:active {
217
224
  background-color: #c4d9ff;
218
225
  border-color: #0040aa;
219
- transform: translateY(2px); /* 模拟按下效果 */
220
- box-shadow: none; /* 取消阴影,增强按下效果 */
226
+ transform: translateY(2px);
227
+ box-shadow: none;
221
228
  }
222
229
 
223
- .p_newDialog .p_newDialogText {
230
+ .newDialogText {
224
231
  margin-left: 6px;
225
232
  }