yt-chat-components 1.4.7 → 1.4.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.4.7",
3
+ "version": "1.4.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",
package/public/index.html CHANGED
@@ -116,13 +116,15 @@
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"}'
127
+ asset-map='{"sendMessageUrl":"https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/school/bcyz/user/ai/sendMessage.png","stopMessageUrl":"https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/school/bcyz/user/ai/stopMessage.png","speakUrl":"https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/school/bcyz/user/ai/speak.png"}'
126
128
  />
127
129
  </body>
128
130
  </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 }[]
@@ -158,13 +158,13 @@ export default function ChatWindow({
158
158
  const isStream = true;//是否流式输出(手动开关)
159
159
  const [recordState, setRecordState] = useState(false); // 录音状态。true为正在录音,false为停止录音
160
160
  const [tagList, setTagList] = useState([]); // 问题标签列表
161
- const {isTitleSideIcon, logoWidth, agentUrl} = baseConfig;
162
- const [inputContainerHeight, setInputContainerHeight] = useState('50px')
161
+ const {isTitleSideIcon, logoWidth, agentUrl, stopMessageUrl, sendMessageUrl, speakUrl} = baseConfig;
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) => {
@@ -1206,7 +1219,7 @@ export default function ChatWindow({
1206
1219
  style={receivingMessage ? {cursor: 'not-allowed'} : {}}
1207
1220
  onClick={startRecord}
1208
1221
  >
1209
- <img src={recordState ? soundWavePng : luyinPng} style={{width: 23}}
1222
+ <img src={recordState ? soundWavePng : (speakUrl || luyinPng)} style={{width: 35}}
1210
1223
  className={recordState ? "w_recordIng" : ''}></img>
1211
1224
  </div>
1212
1225
  </Tooltip>
@@ -1260,7 +1273,10 @@ export default function ChatWindow({
1260
1273
  }
1261
1274
  }}
1262
1275
  >
1263
- <img src={receivingMessage ? stopmessagePng : sendmessagePng} style={{width: 55}}/>
1276
+ <img
1277
+ src={receivingMessage ? (stopMessageUrl || stopmessagePng) : (sendMessageUrl || sendmessagePng)}
1278
+ style={{width: 35}}
1279
+ />
1264
1280
  </button>
1265
1281
  </Tooltip>
1266
1282
  </div>
@@ -1271,10 +1287,7 @@ export default function ChatWindow({
1271
1287
  }
1272
1288
  if(isTagsHidden){
1273
1289
  return inputNode;
1274
- }else{
1275
-
1276
1290
  }
1277
-
1278
1291
  return (
1279
1292
  <>
1280
1293
  <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
 
@@ -738,7 +737,7 @@ margin-bottom:1rem;
738
737
  }
739
738
 
740
739
  .cl-input-element::placeholder {
741
- line-height:45px;
740
+ // line-height:45px;
742
741
  }
743
742
 
744
743
  .cl-input-element:focus {
@@ -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
 
@@ -16,7 +16,7 @@ const commentSvg = ()=> (
16
16
  p-id="3118" width="24" height="20">
17
17
  <path
18
18
  d="M806.9 155.2H217.2c-64 0-116.1 55.6-116.1 124v380c0 68.4 52.1 124 116.1 124h101.3l-5.9 101.6c-0.5 9.4 4.5 18.3 12.8 22.6 3.5 1.8 7.3 2.8 11.2 2.8 5.2 0 10.4-1.7 14.7-5.1l156.8-122h298.7c64 0 116.1-55.6 116.1-124v-380c0.1-68.3-52-123.9-116-123.9zM303 528.7c-33.1 0-60-26.9-60-60s26.9-60 60-60 60 26.9 60 60-26.8 60-60 60z m209 1c-33.1 0-60-26.9-60-60s26.9-60 60-60 60 26.9 60 60-26.8 60-60 60z m209-1c-33.1 0-60-26.9-60-60s26.9-60 60-60 60 26.9 60 60-26.8 60-60 60z"
19
- p-id="3119" fill="#bfbfbf"></path>
19
+ p-id="3119"></path>
20
20
  </svg>
21
21
  )
22
22
  const CommentIcon = (props) => (
@@ -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 = `
@@ -42,26 +43,29 @@ const style = `
42
43
  border-radius:8px;
43
44
  display: flex;
44
45
  flex-direction: column;
46
+ justify-content: space-between;
45
47
  }
46
48
  .p_toolDialog .p_sign{
47
49
  width: calc(100vw - 140px);
48
50
  margin: 0 auto;
51
+ min-width: 1200px;
49
52
  }
50
53
 
51
54
  .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;
55
+ margin: 1.5rem auto 0;
56
+ width: calc(100vw - 140px);
57
+ height: calc(100vh - 192px);
58
+ background: #fff;
59
+ border-radius: 15px;
60
+ display: flex;
61
+ flex-direction: column;
62
+ min-width: 1200px;
59
63
  }
60
64
  .p_toolDialog .p_toolLeft {
61
65
  display: flex;
62
66
  flex-direction: column;
63
67
  align-items: center;
64
- width: 400px;
68
+ width: 300px;
65
69
  padding: 1.7rem 1.6rem 1.7rem 1.6rem;
66
70
 
67
71
  border-top-left-radius: 8px;
@@ -80,6 +84,9 @@ const style = `
80
84
 
81
85
  .p_toolDialog .dialog_box .p_toolLogo .p_logoImg {
82
86
  width: 48px;
87
+ position: absolute;
88
+ top: 2px;
89
+ transform: scale3d(1.3, 1.3, 1.3);
83
90
  }
84
91
 
85
92
  .p_toolDialog .dialog_box .p_toolLogo .p_logoText {
@@ -94,8 +101,8 @@ const style = `
94
101
 
95
102
  .p_toolDialog .p_toolLeft .p_historyDialog {
96
103
  user-select: none;
97
- margin-top: 20px;
98
- margin-bottom: 20px;
104
+ margin-top: 24px;
105
+ margin-bottom: 24px;
99
106
  border-radius: 10px;
100
107
  flex: 1;
101
108
  width: 100%;
@@ -103,7 +110,7 @@ const style = `
103
110
  border-image: linear-gradient(180deg, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0)) 1 1;
104
111
  backdrop-filter: blur(10px);
105
112
  position: relative;
106
- max-height:calc(100% - 5.5rem - 60px);
113
+ max-height:calc(100% - 60px);
107
114
  }
108
115
 
109
116
  .p_toolDialog .p_toolLeft .p_historyDialog ::-webkit-scrollbar-thumb {
@@ -140,12 +147,12 @@ const style = `
140
147
  text-align: center;
141
148
  font-size: 12px;
142
149
  color: #999999;
143
- max-height: calc(100% - 3rem);
150
+ max-height: calc(100% - 1.7rem);
144
151
 
145
152
  }
146
153
 
147
154
  .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList {
148
- height: calc(100% - 3rem);
155
+ height: calc(100% - 1.7rem);
149
156
  margin-top: 10px;
150
157
  overflow-y: auto;
151
158
  scrollbar-width: none !important; /* firefox */
@@ -163,25 +170,26 @@ const style = `
163
170
  .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList .p_historyItem {
164
171
  padding: 10px 16px;
165
172
  padding-left: 0;
166
- margin-bottom:4px;
173
+
167
174
  }
168
175
 
169
176
  .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList .p_historyItem:hover{
170
177
  background: #F5F5F5;
171
178
  border-radius: 9px;
179
+ color: #1552FF
172
180
  }
173
181
 
174
182
  .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList .p_historyItem:hover .p_historyName{
175
- color: #1552FF
183
+
176
184
  }
177
185
 
178
186
  .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList .p_activeItem{
179
- background: #F5F5F5;
187
+ background: #1974FF !important;
180
188
  border-radius: 9px;
189
+ color:#FFFFFF !important;
181
190
  }
182
191
 
183
192
  .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList .p_historyItem .p_historyName {
184
- color: #333333;
185
193
  overflow: hidden;
186
194
  text-overflow: ellipsis;
187
195
  white-space: nowrap;
@@ -192,15 +200,15 @@ const style = `
192
200
 
193
201
  .p_toolDialog .p_toolRight {
194
202
  flex: 1;
195
- background: #F0F0F0;
203
+ background: #f5f5f5;h
196
204
  }
197
205
 
198
206
  .p_toolRightToRight {
199
207
  height:100%;
200
- width:400px;
208
+ width:300px;
201
209
  display:flex;
202
210
  flex-direction:column;
203
- padding:2rem 1.6rem 1.8rem 1.6rem
211
+ padding:1.7rem 1.6rem 1.8rem 1.6rem
204
212
  }
205
213
  .p_toolRightToRight .p_hot{
206
214
  display:flex;
@@ -226,13 +234,20 @@ const style = `
226
234
  .p_toolRightToRight .p_carousel .slick-dots-bottom{
227
235
  justify-content: end;
228
236
  right:12px;
237
+ bottom:-10px;
238
+ }
239
+ :where(.css-dev-only-do-not-override-1v613y0).ant-carousel .slick-dots li.slick-active::after{
240
+ background:#1974FF;
241
+ }
242
+
243
+ :where(.css-dev-only-do-not-override-1v613y0).ant-carousel .slick-dots li button{
244
+ background: #000000;
229
245
  }
230
246
 
231
247
  .p_newDialog {
232
- width: 352px;
248
+ width: 252px;
233
249
  height: 40px;
234
250
  min-height:40px;
235
- margin-top: 20px;
236
251
  cursor: pointer;
237
252
  display: flex;
238
253
  color:#0060FF;
@@ -257,6 +272,11 @@ const style = `
257
272
  .p_newDialog .p_newDialogText {
258
273
  margin-left: 6px;
259
274
  }
275
+ .p_footer{
276
+ text-align: center;
277
+ margin-bottom: 1.5rem;
278
+ margin-top: 1.5rem;
279
+ }
260
280
  `
261
281
 
262
282
  const defaultList = [
@@ -276,7 +296,7 @@ const defaultList = [
276
296
 
277
297
  const api_key = 'sk-mniUFDpcWwvNF3iFzssXa6etN-S_Y4AApyHYcBU44L0';
278
298
 
279
- const MethodContext = React.createContext();
299
+ export const MethodContext = React.createContext();
280
300
 
281
301
  export class ToolDialogV2 extends React.Component {
282
302
 
@@ -342,13 +362,18 @@ export class ToolDialogV2 extends React.Component {
342
362
  this.setState({ sessionId });
343
363
  };
344
364
 
345
- callDMethod = (method) => {
346
- this.handleSendMessage = method;
347
- };
365
+ registerChatMethods = ({ isActiveMessage, handleSendMessage }) => {
366
+ this.handleSendMessage = handleSendMessage;
367
+ this.isActiveMessage = isActiveMessage;
368
+ }
369
+
348
370
 
349
371
  handleClick = (word) => {
350
- if (typeof this.handleSendMessage === 'function') {
372
+ if(!this.isActiveMessage()){
351
373
  this.handleSendMessage(word);
374
+ }else{
375
+ message.destroy();
376
+ message.info("请等待回复结束后再发送")
352
377
  }
353
378
  };
354
379
 
@@ -368,9 +393,12 @@ export class ToolDialogV2 extends React.Component {
368
393
  const { title } = this.props;
369
394
  const { currentFlow } = this.state;
370
395
  return <TabSelector handleRowClick={(word)=> {
371
- this.setState({ dropDownList: [] });
372
- if (typeof this.handleSendMessage === 'function') {
396
+ if(!this.isActiveMessage()){
397
+ this.setState({ dropDownList: [] });
373
398
  this.handleSendMessage(word);
399
+ }else{
400
+ message.destroy();
401
+ message.info("请等待回复结束后再发送")
374
402
  }
375
403
  }} welcomeWords={`Hi,欢迎使用${currentFlow.name||title},您可以这样问我:`}/>
376
404
  }
@@ -391,12 +419,14 @@ export class ToolDialogV2 extends React.Component {
391
419
  logoWidth = '42px',
392
420
  logoFontSize = '26px',
393
421
  isTitleSideIcon = false,// 是否将左侧历史顶部icon移到中间顶部左侧蓝点位置
422
+ assetMap,
394
423
  modalIndex,
395
424
  isShowUploadButton = false,
396
425
  dropManUrl,
397
426
  modalWidth,
398
427
  isShowReadIcon = false,
399
428
  signUrl,
429
+ bannerMap,
400
430
  } = this.props;
401
431
  const { currentFlow = {} } = this.state;
402
432
  return (
@@ -405,11 +435,21 @@ export class ToolDialogV2 extends React.Component {
405
435
  <div className="p_toolDialog">
406
436
  {/*对话上边的学校标志,定位到左上角header上端*/}
407
437
  <div className={'p_sign'} >
408
- <img src={signUrl} style={{ width: 600, marginTop: '50px', }}/>
438
+ <img src={signUrl} style={{ width: 600, marginTop: '1.5rem', }}/>
409
439
  </div>
410
440
  <div className={"dialog_box"}>
411
441
  <div className="p_toolLogo">
412
- <img className="p_logoImg" style={{ width: logoWidth, borderRadius: 15 }} src={agentUrl}/>
442
+ <div style={{
443
+ width: logoWidth,
444
+ height: logoWidth,
445
+ backgroundColor: '#1974FF',
446
+ borderRadius: '22px',
447
+ position: 'relative',
448
+ overflow: 'hidden',
449
+ }}>
450
+ <img className="p_logoImg"
451
+ src={agentUrl}/>
452
+ </div>
413
453
  <div className="p_logoText" style={{ fontSize: logoFontSize }}>{agentName}</div>
414
454
  </div>
415
455
  <div style={{display: 'flex',flexDirection:"row",flex: 1,height: 'calc(100% - 75px)'}}>
@@ -440,7 +480,10 @@ export class ToolDialogV2 extends React.Component {
440
480
  <div
441
481
  className={`p_historyName ${item.session_id === this.state.sessionId ? 'p_activeHistoryName' : ''}`}
442
482
  >
443
- <CommentIcon style={{marginRight:'8px'}}/>
483
+ <CommentIcon style={{
484
+ marginRight: '8px',
485
+ fill: item.session_id === this.state.sessionId ? '#FFFFFF' : '#bfbfbf'
486
+ }}/>
444
487
  <span>{item.text}</span>
445
488
  </div>
446
489
  </div>
@@ -456,7 +499,7 @@ export class ToolDialogV2 extends React.Component {
456
499
  </div>
457
500
  }
458
501
  <div className="p_toolRight">
459
- <MethodContext.Provider value={{ callDMethod: this.callDMethod }}>
502
+ <MethodContext.Provider value={{registerChatMethods:this.registerChatMethods}}>
460
503
  <ChatWidget
461
504
  window_title={currentFlow?.name || title}
462
505
  flow_id={currentFlow?.id || flowId}
@@ -469,7 +512,7 @@ export class ToolDialogV2 extends React.Component {
469
512
  getHistoryList={this.getHistoryList}
470
513
  setDropDownList={(list) => this.setState({ dropDownList: list })}
471
514
  dropDownList={this.state.dropDownList}
472
- baseConfig={{ isTitleSideIcon, logoWidth, agentUrl }}
515
+ baseConfig={{ isTitleSideIcon, logoWidth, agentUrl, ...assetMap }}
473
516
  isShowUploadButton={isShowUploadButton}
474
517
  dropManUrl={currentFlow.character}
475
518
  modalWidth={modalWidth}
@@ -477,27 +520,21 @@ export class ToolDialogV2 extends React.Component {
477
520
  isShowChatHeader={false}
478
521
  renderCustomDropDown={this.renderCustomDropDown}
479
522
  isTagsHidden={true}
480
- MethodContext={MethodContext}
481
523
  placeholder={'请输入您想咨询的问题'}
482
524
  />
483
525
  </MethodContext.Provider>
484
526
  </div>
485
527
  <div className={'p_toolRightToRight'}>
486
528
  <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>
529
+ {
530
+ Object.values(bannerMap).map(item => (
531
+ <div key={item}>
532
+ <img style={contentStyle} src={item}/>
533
+ </div>
534
+ ))
535
+ }
499
536
  </Carousel>
500
- <div style={{ height: '1px', background: '#E5E5E5',marginTop: '30px' }}/>
537
+ <div style={{ height: '1px', background: '#E5E5E5',marginTop: '25px' }}/>
501
538
  <div className={'p_hot'}>
502
539
  <img src={'https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/school/bcyz/user/ai/hot.png'}/>
503
540
  <span>热点问题</span>
@@ -511,7 +548,7 @@ export class ToolDialogV2 extends React.Component {
511
548
  </div>
512
549
  </div>
513
550
  </div>
514
- <div style={{textAlign: 'center', marginTop: 20}}><span style={{fontSize: 16}}>技术支持:北京云图科技有限公司</span></div>
551
+ <div className={'p_footer'}><span style={{fontSize: 16}}>技术支持:北京云图科技有限公司</span></div>
515
552
  </div>
516
553
  </div>
517
554
  );
@@ -1,67 +1,73 @@
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
+ justify-content: space-between;
11
12
  }
12
- .p_toolDialog .p_sign{
13
+
14
+ .toolDialogSign {
13
15
  width: calc(100vw - 140px);
14
16
  margin: 0 auto;
17
+ min-width: 1200px;
15
18
  }
16
19
 
17
- .dialog_box{
18
- margin: 24px auto 0;
20
+ .dialogBox {
21
+ margin: 1.5rem auto 0;
19
22
  width: calc(100vw - 140px);
20
- height: calc(100vh - 200px);
23
+ height: calc(100vh - 192px);
21
24
  background: #fff;
22
25
  border-radius: 15px;
23
26
  display: flex;
24
27
  flex-direction: column;
28
+ min-width: 1200px;
25
29
  }
26
- .p_toolDialog .p_toolLeft {
30
+
31
+ .toolLeft {
27
32
  display: flex;
28
33
  flex-direction: column;
29
34
  align-items: center;
30
- width: 400px;
35
+ width: 300px;
31
36
  padding: 1.7rem 1.6rem 1.7rem 1.6rem;
32
-
33
37
  border-top-left-radius: 8px;
34
38
  border-bottom-left-radius: 8px;
35
39
  }
36
40
 
37
- .p_toolDialog .dialog_box .p_toolLogo {
41
+ .toolLogo {
38
42
  user-select: none;
39
43
  display: flex;
40
44
  align-items: center;
41
45
  margin-top: 18px;
42
46
  padding-left: 32px;
43
- padding-bottom:12px;
47
+ padding-bottom: 12px;
44
48
  border-bottom: #E5E5E5 solid 1px;
45
49
  }
46
50
 
47
- .p_toolDialog .dialog_box .p_toolLogo .p_logoImg {
51
+ .logoImg {
48
52
  width: 48px;
53
+ position: absolute;
54
+ top: 2px;
55
+ transform: scale3d(1.3, 1.3, 1.3);
49
56
  }
50
57
 
51
- .p_toolDialog .dialog_box .p_toolLogo .p_logoText {
58
+ .logoText {
52
59
  font-weight: bold;
53
60
  margin-left: 10px;
54
61
  font-size: 20px;
55
- background: #000000;
56
- /*background: linear-gradient(to right, #1551FF, #8F4BFF);*/
62
+ /* background: linear-gradient(to right, #1551FF, #8F4BFF); */
57
63
  -webkit-background-clip: text;
58
64
  -webkit-text-fill-color: transparent;
59
65
  }
60
66
 
61
- .p_toolDialog .p_toolLeft .p_historyDialog {
67
+ .historyDialog {
62
68
  user-select: none;
63
- margin-top: 20px;
64
- margin-bottom: 20px;
69
+ margin-top: 24px;
70
+ margin-bottom: 24px;
65
71
  border-radius: 10px;
66
72
  flex: 1;
67
73
  width: 100%;
@@ -69,36 +75,30 @@
69
75
  border-image: linear-gradient(180deg, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0)) 1 1;
70
76
  backdrop-filter: blur(10px);
71
77
  position: relative;
72
- max-height:calc(100% - 5.5rem - 60px);
78
+ max-height: calc(100% - 60px);
73
79
  }
74
80
 
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 {
81
+ .historyTitle {
82
82
  display: flex;
83
83
  align-items: center;
84
84
  justify-content: space-between;
85
85
  }
86
86
 
87
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyTitle .p_historyImg {
87
+ .historyImg {
88
88
  width: 25px;
89
89
  }
90
90
 
91
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyTitle .p_dialogTitle {
91
+ .dialogTitle {
92
92
  font-size: 18px;
93
93
  line-height: 16px;
94
94
  text-align: left;
95
95
  font-style: normal;
96
- display:flex;
96
+ display: flex;
97
97
  font-weight: normal;
98
98
  color: #A4A4A4;
99
99
  }
100
100
 
101
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyListEmpty {
101
+ .historyListEmpty {
102
102
  position: absolute;
103
103
  top: 50%;
104
104
  left: 50%;
@@ -106,48 +106,43 @@
106
106
  text-align: center;
107
107
  font-size: 12px;
108
108
  color: #999999;
109
- max-height: calc(100% - 3rem);
110
-
109
+ max-height: calc(100% - 1.7rem);
111
110
  }
112
111
 
113
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList {
114
- height: calc(100% - 3rem);
112
+ .historyList {
113
+ height: calc(100% - 1.7rem);
115
114
  margin-top: 10px;
116
115
  overflow-y: auto;
117
116
  scrollbar-width: none !important; /* firefox */
118
117
  }
119
118
 
120
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList::-webkit-scrollbar{
121
- display:none;
119
+ .historyList::-webkit-scrollbar {
120
+ display: none;
122
121
  }
123
122
 
124
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList:hover {
123
+ .historyList:hover {
125
124
  scrollbar-width: thin !important; /* firefox */
126
125
  scrollbar-color: #ced4e3 transparent;
127
126
  }
128
127
 
129
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList .p_historyItem {
128
+ .historyItem {
130
129
  padding: 10px 16px;
131
130
  padding-left: 0;
132
- 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;
136
+ color: #1552FF;
138
137
  }
139
138
 
140
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList .p_historyItem:hover .p_historyName{
141
- color: #1552FF
142
- }
143
-
144
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList .p_activeItem{
145
- background: #F5F5F5;
139
+ .activeItem {
140
+ background: #1974FF !important;
146
141
  border-radius: 9px;
142
+ color: #FFFFFF !important;
147
143
  }
148
144
 
149
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList .p_historyItem .p_historyName {
150
- color: #333333;
145
+ .historyName {
151
146
  overflow: hidden;
152
147
  text-overflow: ellipsis;
153
148
  white-space: nowrap;
@@ -156,70 +151,85 @@
156
151
  align-items: center;
157
152
  }
158
153
 
159
- .p_toolDialog .p_toolRight {
154
+ .toolRight {
160
155
  flex: 1;
161
- background: #F0F0F0;
156
+ background: #f5f5f5;
162
157
  }
163
158
 
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
159
+ .toolRightToRight {
160
+ height: 100%;
161
+ width: 300px;
162
+ display: flex;
163
+ flex-direction: column;
164
+ padding: 1.7rem 1.6rem 1.8rem 1.6rem;
170
165
  }
171
- .p_toolRightToRight .p_hot{
172
- display:flex;
166
+
167
+ .hot {
168
+ display: flex;
173
169
  align-items: center;
174
170
  }
175
171
 
176
- .p_toolRightToRight .p_hot img{
177
- width:19px;
178
- margin-right:10px;
172
+ .hot img {
173
+ width: 19px;
174
+ margin-right: 10px;
179
175
  }
180
176
 
181
- .p_toolRightToRight .p_hot span{
177
+ .hot span {
182
178
  font-size: 18px;
183
179
  color: #000000;
184
180
  line-height: 59px;
185
181
  }
186
182
 
187
- .p_toolRightToRight .p_carousel h3{
188
- margin:0;
189
- border-radius:12px;
183
+ .carousel h3 {
184
+ margin: 0;
185
+ border-radius: 12px;
190
186
  }
191
187
 
192
- .p_toolRightToRight .p_carousel .slick-dots-bottom{
188
+ .carousel .slickDotsBottom {
193
189
  justify-content: end;
194
- right:12px;
190
+ right: 12px;
191
+ bottom: -10px;
192
+ }
193
+
194
+ .antCarousel .slickDots li.slickActive::after {
195
+ background: #1974FF;
195
196
  }
196
197
 
197
- .p_newDialog {
198
- width: 352px;
198
+ .antCarousel .slickDots li button {
199
+ background: #000000;
200
+ }
201
+
202
+ .newDialog {
203
+ width: 252px;
199
204
  height: 40px;
200
- min-height:40px;
201
- margin-top: 20px;
205
+ min-height: 40px;
202
206
  cursor: pointer;
203
207
  display: flex;
204
- color:#0060FF;
208
+ color: #0060FF;
205
209
  align-items: center;
206
210
  background: #EAF3FF;
207
211
  border-radius: 11px;
208
212
  border: 1px solid #1974FF;
209
- transition: all 0.2s ease; /* 添加过渡动画 */
213
+ transition: all 0.2s ease;
210
214
  }
211
215
 
212
- .p_newDialog:hover {
216
+ .newDialog:hover {
213
217
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
214
218
  }
215
219
 
216
- .p_newDialog:active {
220
+ .newDialog:active {
217
221
  background-color: #c4d9ff;
218
222
  border-color: #0040aa;
219
- transform: translateY(2px); /* 模拟按下效果 */
220
- box-shadow: none; /* 取消阴影,增强按下效果 */
223
+ transform: translateY(2px);
224
+ box-shadow: none;
221
225
  }
222
226
 
223
- .p_newDialog .p_newDialogText {
227
+ .newDialogText {
224
228
  margin-left: 6px;
229
+ }
230
+
231
+ .footer {
232
+ text-align: center;
233
+ margin-bottom: 1.5rem;
234
+ margin-top: 1.5rem;
225
235
  }