yt-chat-components 1.0.0 → 1.0.2

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 (42) hide show
  1. package/.idea/modules.xml +1 -1
  2. package/.idea/sonarlint/issuestore/index.pb +3 -31
  3. package/dist/build/static/js/bundle.min.js +1 -0
  4. package/package.json +76 -76
  5. package/public/index.html +108 -108
  6. package/src/YtChatView/chatWidget/chatWindow/chatMessage/index.tsx +464 -464
  7. package/src/YtChatView/chatWidget/chatWindow/controllers/index.ts +249 -249
  8. package/src/YtChatView/chatWidget/chatWindow/index.module.css +196 -196
  9. package/src/YtChatView/chatWidget/chatWindow/index.tsx +1054 -1041
  10. package/src/YtChatView/chatWidget/chatWindow/types/chatWidget/index.ts +50 -50
  11. package/src/YtChatView/chatWidget/index.tsx +2586 -2586
  12. package/src/YtChatView/logoBtn/index.css +3 -3
  13. package/src/YtChatView/logoBtn/index.jsx +103 -103
  14. package/src/YtChatView/logoSplitBtn/index.css +3 -3
  15. package/src/YtChatView/logoSplitBtn/index.jsx +105 -105
  16. package/src/YtChatView/mobileChat/index.jsx +944 -848
  17. package/src/YtChatView/mobileChat/index.module.css +253 -253
  18. package/src/YtChatView/previewDialog/index.jsx +600 -600
  19. package/src/YtChatView/previewDialog/index.module.css +253 -253
  20. package/src/chatWidget/chatWindow/index.tsx +426 -426
  21. package/src/chatWidget/index.tsx +2193 -2193
  22. package/src/index.tsx +10 -10
  23. package/webpack.config.js +50 -50
  24. package/.idea/sonarlint/issuestore/3/6/364385cedcce4c06de1901392ffeeac0caef0f3c +0 -0
  25. package/.idea/sonarlint/issuestore/3/9/39129446b425a1d640160c068e4194e96639eedf +0 -0
  26. package/.idea/sonarlint/issuestore/4/a/4a2f33951ce07c1ff7184f91877aa13db05d3785 +0 -0
  27. package/.idea/sonarlint/issuestore/4/a/4a7b99bdbee5792679d347b6474463bf5e14b66d +0 -0
  28. package/.idea/sonarlint/issuestore/4/b/4b015aa5428c4d4c3d672893ec23f5fe3969f9be +0 -0
  29. package/.idea/sonarlint/issuestore/4/b/4b6989b8ccae808ebc45d02230d336ea53800365 +0 -0
  30. package/.idea/sonarlint/issuestore/6/1/61ebb9fd6e8cf9082658121d5d81e297791dacd0 +0 -0
  31. package/.idea/sonarlint/issuestore/6/c/6c024c1d0ad64656b9d4b0695ec3c49c0454addf +0 -0
  32. package/.idea/sonarlint/issuestore/6/e/6e75fc1c07c3a427a86fc213ca9479caaaff00ea +0 -0
  33. package/.idea/sonarlint/issuestore/8/d/8d6123af13a140f93e06299fff7ea23c547e9ec8 +0 -0
  34. package/.idea/sonarlint/issuestore/c/c/cc2352788140b6778ac06df4b33f50b390d2d8be +0 -0
  35. package/.idea/sonarlint/issuestore/d/5/d5595158cc48f9bf3e51b06f6e6805a8fd2d6262 +0 -0
  36. package/.idea/sonarlint/issuestore/d/7/d747cbed4201192dfa83a1a51345b020a050b647 +0 -0
  37. package/.idea/sonarlint/issuestore/d/9/d938938695d447dadda115e28781c6541f53fc4f +0 -0
  38. package/build/static/js/bundle.min.js +0 -2
  39. package/build/static/js/bundle.min.js.LICENSE.txt +0 -132
  40. /package/.idea/{langflow-embedded-chat.iml → langflow-embedded-chat-clone.iml} +0 -0
  41. /package/.idea/sonarlint/issuestore/{0/f/0f8c0c92cf798431ebb931ff6e997b1af86ecee5 → 7/0/7030d0b2f71b999ff89a343de08c414af32fc93a} +0 -0
  42. /package/.idea/sonarlint/issuestore/{2/7/27e69cb561aeea20c1afbdd32d260dd60b89a81b → 9/c/9cfff9a6d27bd6c255aa751213163c7901fb8ce7} +0 -0
@@ -1,848 +1,944 @@
1
- /* global wx */
2
- import React from 'react';
3
- import aiAvatarPng from '../../assets/aicenter/aiavatar.png';
4
- import historyPng from '../../assets/aicenter/history.png';
5
- import closePng from '../../assets/aicenter/close.png';
6
- import { getFlowInfo, getHistoryList, getSceneInfo } from '../chatWidget/chatWindow/controllers/index';
7
- import './index.module.css'
8
- import { v4 as uuidv4 } from 'uuid';
9
- import historyListEmptyPng from '../../assets/aicenter/history-list-empty.png';
10
- import addPng from '../../assets/aicenter/add.png';
11
- import {isEmpty, isFunction} from "lodash";
12
- import { Button, message as messageTip, Progress, Skeleton, Drawer } from 'antd'
13
- import { CloseOutlined } from "@ant-design/icons";
14
- import moreAi from '../../assets/aicenter/moreAi.png';
15
- import moreBg from '../../assets/aicenter/moreBg.png';
16
- import icon_history from '../../assets/aicenter/icon_history.png';
17
- import icon_agents from '../../assets/aicenter/icon_agents.png';
18
- import icon_history_upload from '../../assets/aicenter/icon_history_upload.png';
19
- import icon_history_headerbg from '../../assets/aicenter/icon_history_headerbg.png';
20
- import icon_history_add from '../../assets/aicenter/icon_history_add.png';
21
- import self_knowledge from '../../assets/aicenter/self_knowledge.png';
22
- import self_skills from '../../assets/aicenter/self_skills.png';
23
- import ChatWidget from "../chatWidget";
24
-
25
-
26
- const style=`
27
- .p_closeImg {
28
- width: 14px;
29
- cursor: pointer;
30
- }
31
-
32
- .p_toolDialog {
33
- display: flex;
34
- height:100%;
35
- background:url('https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/ai/ai_modal_bg.png');
36
- background-size: cover;
37
- border-radius:8px;
38
- }
39
-
40
- .p_toolDialog .p_toolLeft {
41
- display: flex;
42
- flex-direction: column;
43
- align-items: center;
44
- width: 300px;
45
- padding: 1.7rem 1.6rem 1.7rem 1.6rem;
46
-
47
- border-top-left-radius: 8px;
48
- border-bottom-left-radius: 8px;
49
- }
50
-
51
- .p_toolDialog .p_toolLeft .p_toolLogo {
52
- user-select: none;
53
- display: flex;
54
- align-items: center;
55
- }
56
-
57
- .p_toolDialog .p_toolLeft .p_toolLogo .p_logoImg {
58
- width: 48px;
59
- }
60
-
61
- .p_toolDialog .p_toolLeft .p_toolLogo .p_logoText {
62
- font-weight: bold;
63
- margin-left: 10px;
64
- font-size: 30px;
65
- background: linear-gradient(to right, #1551FF, #8F4BFF);
66
- -webkit-background-clip: text;
67
- -webkit-text-fill-color: transparent;
68
- }
69
-
70
- .p_toolDialog .p_toolLeft .p_historyDialog {
71
- user-select: none;
72
- margin-top: 20px;
73
- margin-bottom: 20px;
74
- border-radius: 10px;
75
- flex: 1;
76
- width: 100%;
77
- background: linear-gradient(180deg, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%);
78
- border-image: linear-gradient(180deg, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0)) 1 1;
79
- backdrop-filter: blur(10px);
80
- position: relative;
81
- max-height:calc(100% - 5.5rem - 60px);
82
- }
83
-
84
- .p_toolDialog .p_toolLeft .p_historyDialog ::-webkit-scrollbar-thumb {
85
- border-radius: 10px;
86
- -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
87
- background: #535353 !important;
88
- }
89
-
90
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyTitle {
91
- padding: 1.3rem 16px 0 16px;
92
- display: flex;
93
- align-items: center;
94
- }
95
-
96
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyTitle .p_historyImg {
97
- width: 25px;
98
- }
99
-
100
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyTitle .p_dialogTitle {
101
- margin-left: 10px;
102
- font-weight: 500;
103
- font-size: 18px;
104
- color: #333333;
105
- line-height: 16px;
106
- text-align: left;
107
- font-style: normal;
108
- }
109
-
110
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyListEmpty {
111
- position: absolute;
112
- top: 50%;
113
- left: 50%;
114
- transform: translate(-50%, -50%);
115
- text-align: center;
116
- font-size: 12px;
117
- color: #999999;
118
- max-height: calc(100% - 3rem);
119
-
120
- }
121
-
122
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList {
123
- height: calc(100% - 3rem);
124
- margin-top: 10px;
125
- overflow-y: auto;
126
- scrollbar-width: none !important; /* firefox */
127
- }
128
-
129
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList::-webkit-scrollbar{
130
- display:none;
131
- }
132
-
133
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList:hover {
134
- scrollbar-width: thin !important; /* firefox */
135
- scrollbar-color: #ced4e3 transparent;
136
- }
137
-
138
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList .p_historyItem {
139
- padding: 7px 16px;
140
- }
141
-
142
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList .p_historyItem .p_activeHistoryName {
143
- color: #1552FF !important;
144
- }
145
-
146
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList .p_historyItem .p_historyName {
147
- color: #333333;
148
- overflow: hidden;
149
- text-overflow: ellipsis;
150
- white-space: nowrap;
151
- cursor: pointer;
152
- }
153
-
154
- .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList .p_historyItem .p_historyName:hover {
155
- color: #171717;
156
- }
157
-
158
- .p_toolDialog .p_toolRight {
159
- flex: 1;
160
- }
161
-
162
- .p_toolRightToRight {
163
- width:300px;
164
- display:flex;
165
- flex-direction:column;
166
- padding:2rem 1.6rem 1.8rem 1.6rem
167
- }
168
- .rightInnerContainer{
169
- height:calc(100% - 80px);
170
- flex:1;
171
- display:flex;
172
- flex-direction:column;
173
- justify-content: space-between;
174
- }
175
- .p_toolRightToRight .rightSideTitle{
176
- margin-bottom:1.4rem;
177
- margin-top:10px;
178
- margin-top:0;
179
- font-size:18px;
180
- font-weight:500;
181
- display:flex;
182
- align-items: center;
183
- }
184
- .p_toolRightToRight .rightSideTitle img{
185
- margin-right:4px;
186
- }
187
-
188
- .p_toolRightToRight .rightSideTitle .titleSideColumn{
189
- color:#1551FF;
190
- }
191
-
192
- .p_toolRightToRight .rightSkillContainer{
193
- min-height:40%;
194
- }
195
- .p_toolRightToRight .rightSkillContainer .rightSkillList{
196
- display: flex;
197
- flex-wrap: wrap;
198
- grid-template-columns: repeat(3, 1fr);
199
- gap: 10px;
200
- }
201
- .p_toolRightToRight .rightSkillContainer .rightSkillList .rightSkillItem{
202
- text-align: center;
203
- cursor:pointer;
204
- width:30%;
205
- }
206
- .p_toolRightToRight .rightSkillContainer .rightSkillList .rightSkillItem img{
207
- width: 40px;
208
- height: 40px;
209
- border-radius:10px;
210
- }
211
- .p_toolRightToRight .rightSkillContainer .rightSkillList .rightSkillItem p{
212
- margin-top:0px;
213
- margin-bottom:4px;
214
- overflow: hidden;
215
- text-overflow: ellipsis;
216
- white-space: nowrap;
217
- color: #333333;
218
- }
219
- .p_toolRightToRight .rightKnowledgeTitle{
220
- nargin-top: 2.2rem;
221
- margin-bottom: 1.4rem;
222
- font-size:18px;
223
- font-weight:500;
224
- display:flex;
225
- align-items: center;
226
- }
227
-
228
- .p_toolRightToRight .rightKnowledgeTitle img{
229
- margin-right:4px;
230
- }
231
-
232
- .p_toolRightToRight .rightKnowledgeContainer{
233
- position:relative;
234
- }
235
- .p_toolRightToRight .rightMoreButton{
236
- background: url(${moreAi});
237
- background-size: 85% auto;
238
- background-repeat: no-repeat;
239
- background-position: bottom;
240
- position: absolute;
241
- bottom: 8px;
242
- left: 0;
243
- width: 100%;
244
- height: 100%;
245
- z-index: 1;
246
- display: flex;
247
- justify-content: center;
248
- align-items: flex-end;
249
- }
250
- .p_toolRightToRight .rightMoreButton div{
251
- width:calc(100% - 50px);
252
- padding: 16px 16px 10px 20px;
253
- font-weight: 500;
254
- color: #ffffff;
255
- line-height: 17px;
256
- font-size: 12px;
257
- cursor:pointer;
258
- }
259
-
260
- .p_newDialog {
261
- width: 252px;
262
- height: 40px;
263
- min-height:40px;
264
- background: linear-gradient( 45deg, #1551FF 0%, #8F4BFF 100%);
265
- margin-top: 20px;
266
- border-radius: 20px;
267
- cursor: pointer;
268
- display: flex;
269
- align-items: center;
270
- justify-content: center;
271
- }
272
-
273
- .p_newDialog img {
274
- width: 18px;
275
- }
276
-
277
- .p_newDialog .p_newDialogText {
278
- color: #fff;
279
- margin-left: 6px;
280
- }
281
-
282
- .drawer-history-header {
283
- margin-top: 40px;
284
- }
285
-
286
- .drawer-history-header-title {
287
- display: flex;
288
- flex-direction: row;
289
- align-items: center;
290
-
291
- > img {
292
- width:35px
293
- }
294
-
295
- > span {
296
- }
297
- }
298
-
299
- .drawer-history-header .drawer-history-header-tool {
300
-
301
- > img {
302
- }
303
-
304
- > span {
305
- }
306
- }
307
-
308
- .drawer-history-content {
309
- }
310
- .drawer-history-footer {
311
- }
312
-
313
- `
314
-
315
- const defaultList = [
316
- {
317
- backgroundImg: 'https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/ai/drop-down-item-card-01.png',
318
- title: '我这学期的课程安排是什么样?',
319
- },
320
- {
321
- backgroundImg: 'https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/ai/drop-down-item-card-02.png',
322
- title: '我上个学期的成绩是多少?',
323
- },
324
- {
325
- backgroundImg: 'https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/ai/drop-down-item-card-03.png',
326
- title: '哪里可以找到心理咨询服务?',
327
- },
328
- ];
329
-
330
- const formatFileSize = (bytes) => {
331
- // 如果字节数为0,直接返回
332
- if(isEmpty(bytes)) {
333
- return { formattedSize: 0, unit: 'B' };
334
- }
335
- if(bytes === 0) return { formattedSize: 0, unit: 'B' };
336
-
337
- // 定义单位和对应的字节数(1024进制)
338
- const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
339
- // 计算合适的单位索引
340
- const index = Math.floor(Math.log(bytes) / Math.log(1024));
341
- // 将字节数转换为目标单位
342
- const size = bytes / Math.pow(1024, index);
343
- // 保留两位小数,并去除多余的0
344
- const formattedSize = size.toFixed(2).replace(/\.?0+$/, '');
345
- return { formattedSize, unit: units[index] }
346
- }
347
-
348
-
349
- const api_key = 'sk-mniUFDpcWwvNF3iFzssXa6etN-S_Y4AApyHYcBU44L0';
350
-
351
-
352
- export class MobileChatPage extends React.Component {
353
- state = {
354
- historyList: [], // 历史对话列表
355
- sessionId: uuidv4(), // 当前激活的对话对应的sessionId
356
- dropDownList: [],
357
- sceneInfo: {},
358
- currentFlow: {},
359
- historyDrawerVisible: false, // 抽屉历史记录状态
360
- agentDrawerVisible: false, // 多智能体切换抽屉状态
361
- };
362
-
363
- async componentDidMount() {
364
- if(isEmpty(this.props.sceneId)){
365
- // 兼容非场景打开的情况
366
- this.getHistoryList({},true);
367
- }else{
368
- const sceneData = await this.getSceneInfo();
369
- if(isEmpty(sceneData)) {
370
- this.getHistoryList({},true);
371
- } else {
372
- this.setWindowTitle(sceneData.name)
373
- this.getHistoryList(sceneData,true);
374
- }
375
- }
376
- }
377
-
378
- setWindowTitle = (title) => {
379
- if (!isEmpty(title)){
380
- document.title = title;
381
- window.document.title = title;
382
- }
383
- }
384
-
385
- getCurrentFlowHistory=(flowId)=>{
386
- let { userInfo = {} } = this.props;
387
- const { sessionId } = this.state;
388
- if(isEmpty(userInfo.code)) {
389
- userInfo.code = sessionId;
390
- }
391
- const operationId = userInfo['code'] || '';
392
- console.log('getCurrentFlowHistory', flowId, operationId)
393
- getHistoryList(this.props.hostUrl, flowId, operationId).then((res) => {
394
- if(res.status === 200){
395
- console.log('getCurrentFlowHistory', res.data)
396
- this.setState({ historyList: res.data });
397
- }
398
- });
399
- }
400
-
401
- // 获取历史对话列表
402
- getHistoryList = (sceneData, isRefreshWords) => {
403
- const { sceneId, appId: flowId, isShowSideLeft } = this.props;
404
- if(isEmpty(sceneId)){
405
- // 单独组件情况
406
- if(isRefreshWords){
407
- this.getFlowInfo().then(currentFlow=>{
408
- const dropDownList = this.getDropDownList(currentFlow.welcome_words);
409
- this.setState({ dropDownList, currentFlow })
410
- })
411
- }
412
- if(isShowSideLeft) {
413
- this.getCurrentFlowHistory(flowId)
414
- }
415
- }else{
416
- const currentScene = sceneData||this.state.sceneInfo;
417
- const currentFlow = currentScene.flows[0];
418
- console.log('getHistoryList', sceneData, currentFlow)
419
- const dropDownList = this.getDropDownList(currentFlow.welcome_words);
420
- if(!isEmpty(sceneData)){
421
- this.setState({ currentFlow, dropDownList })
422
- }else if(isEmpty(this.state.sceneInfo)){
423
- this.setState({ dropDownList:defaultList })
424
- }
425
- if(isShowSideLeft) {
426
- this.getCurrentFlowHistory(currentFlow.id)
427
- }
428
- }
429
- };
430
-
431
- getSceneInfo = async ()=>{
432
- const res = await getSceneInfo(this.props.hostUrl, this.props.sceneId, api_key);
433
- if(res.status === 200){
434
- this.setState({ sceneInfo: res.data });
435
- }
436
- return res.data;
437
- }
438
-
439
- getFlowInfo = async () => {
440
- const res = await getFlowInfo(this.props.hostUrl, this.props.appId, api_key);
441
- if(res.status === 200) {
442
- this.setState({ sceneInfo: res.data });
443
- }
444
- return res.data;
445
- }
446
-
447
- // 新建对话
448
- newDialog = () => {
449
- if(this.state.dropDownList) {
450
- messageTip.info("当前已是最新对话")
451
- return;
452
- }
453
- this.setState({ sessionId: uuidv4() });
454
- this.setState({ dropDownList: this.getDropDownList(this.state.currentFlow.welcome_words), drawerVisible: false })
455
- }
456
-
457
- updateSessionId = (sessionId) => {
458
- this.setState({ sessionId });
459
- };
460
-
461
- getDropDownList = (welcome_words)=>{
462
- if(isEmpty(welcome_words)){
463
- return defaultList;
464
- }
465
- return welcome_words.map((question,index)=>(
466
- {
467
- backgroundImg:defaultList[index].backgroundImg,
468
- title:question,
469
- }
470
- ))
471
- }
472
-
473
- render() {
474
- const {
475
- title,
476
- appId: flowId,
477
- hostUrl,
478
- setDialogVisible,
479
- userInfo,
480
- boxStyle,
481
- isShowSideRight,
482
- isShowSideLeft = true,
483
- tags = [],
484
- agentUrl = aiAvatarPng,
485
- agentName = '校园智多星',
486
- logoWidth = '42px',
487
- logoFontSize = '26px',
488
- isTitleSideIcon = false,// 是否将左侧历史顶部icon移到中间顶部左侧蓝点位置
489
- modalIndex,
490
- isShowVoiceButton,
491
- isShowUploadButton,
492
- dropManUrl,
493
- modalWidth,
494
- isLogin = false,
495
- isShowLogin = false,
496
- loginBtnClick,
497
- } = this.props;
498
- const { sceneInfo, currentFlow = {} } = this.state;
499
- const { flows = [], name: sceneName, character } = sceneInfo;
500
- return (
501
- <div style={boxStyle}>
502
- <style dangerouslySetInnerHTML={{ __html: style }}></style>
503
- <div style={{ position: 'absolute', top: '15px', right: '14px', zIndex: modalIndex }}>
504
- {isFunction(setDialogVisible) &&
505
- <img onClick={() => setDialogVisible(false)} className="p_closeImg" src={closePng}/>}
506
- </div>
507
- <div className="p_toolDialog" style={{borderRadius:0, backgroundImage:'url(https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/kai_yuan/yt/agent_list_bg2.png)'}}>
508
- {
509
- isShowSideLeft && (
510
- <>
511
- <img
512
- src={icon_history}
513
- style={{
514
- width: '40px',
515
- height: '40px',
516
- position: 'absolute',
517
- left: '0px',
518
- top: '0px',
519
- zIndex: 1000
520
- }}
521
- onClick={() => this.setState({drawerVisible: true})}
522
- />
523
- <Drawer
524
- title={null}
525
- closable={false}
526
- placement="left"
527
- width={'80%'}
528
- bodyStyle={{padding: 0}}
529
- onClose={() => this.setState({drawerVisible: false})}
530
- open={this.state.drawerVisible}
531
- >
532
- <div className="drawer-history-header" style={{marginTop:0, padding: '54px 14px 14px 14px', background: 'linear-gradient( 71deg, #E1E9FF 0%, #FFFFFF 100%)', position: "relative"}}>
533
- <img src={icon_history_headerbg} style={{position: 'absolute', right: 0, bottom: 0, width: '40%', zIndex:0}}/>
534
- <div className="drawer-history-header-title" style={{display: 'flex', flexDirection: 'row', alignItems: 'center'}}>
535
- <img style={{width: 35}} src={agentUrl}/>
536
- <span style={{fontSize: 24, marginLeft: 10}}>{agentName}</span>
537
- </div>
538
- <div className="drawer-history-header-tool" style={{display: 'flex',flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginTop: 32 }}>
539
- <div
540
- style={{display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'center', marginRight: 20, height: 44,background: '#fff', borderRadius: 5,width: '45%'}}
541
- onClick={() => {this.newDialog()}}
542
- >
543
- <img src={icon_history_add} style={{width: '20px', height: '20px', marginRight: 10}}/>
544
- <span>新建对话</span>
545
- </div>
546
- <div
547
- style={{
548
- display: 'flex',
549
- flexDirection: 'row',
550
- alignItems: 'center',
551
- justifyContent: 'center',
552
- marginRight: 20,
553
- height: 44,
554
- background: '#fff',
555
- borderRadius: 5,
556
- width: '45%',
557
- zIndex: 0
558
- }}
559
- onClick={() => messageTip.info("敬请期待")}
560
- >
561
- <img src={icon_history_upload} style={{width: '20px', height: '20px', marginRight: 10}}/>
562
- <span>个人知识库</span>
563
- </div>
564
- </div>
565
- </div>
566
- <div
567
- className="p_historyDialog"
568
- style={{
569
- height: 'calc(100% - 179px - 114px)',
570
- boxSizing: 'border-box',
571
- userSelect: 'none',
572
- flex: 1,
573
- padding: '30px 14px 0 14px',
574
- background: 'linear-gradient(180deg, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%)',
575
- borderImage: 'linear-gradient(180deg, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0)) 1 1',
576
- backdropFilter: 'blur(10px)',
577
- position: 'relative',
578
- }}
579
- >
580
- <div className="p_historyTitle" style={{display: 'flex', flexDirection: 'row', alignItems: 'center', marginBottom: 20}}>
581
- <img className="p_historyImg" src={historyPng} style={{width: '20px', height: '20px', marginRight: 10}}/>
582
- <div className="p_dialogTitle" style={{fontSize: 18, fontWeight: 400, color: '#333'}}>对话记录</div>
583
- </div>
584
- {this.state.historyList.length > 0 ? (
585
- <div className="p_historyList" style={{overflowY: 'auto',height: 'calc(100% - 50px)'}}>
586
- {this.state.historyList?.map((item) => (
587
- <div
588
- key={item.session_id}
589
- className="p_historyItem"
590
- style={{
591
- display: 'flex',
592
- height: 44,
593
- alignItems: 'center',
594
- paddingLeft: 30,
595
- paddingRight: 30,
596
- fontWeight: 400,
597
- fontSize: 14,
598
- color: '#333',
599
- borderRadius: 10,
600
- background: item.session_id === this.state.sessionId ? '#F5F5FF' : '#fff',
601
- }}
602
- onClick={() => {
603
- this.setState({dropDownList: undefined, drawerVisible: false})
604
- this.updateSessionId(item.session_id);
605
- }}
606
- >
607
- <div
608
- className={`p_historyName ${
609
- item.session_id === this.state.sessionId ? 'p_activeHistoryName' : ''
610
- }`}
611
- style={{
612
- whiteSpace: 'nowrap',
613
- overflow: 'hidden',
614
- textOverflow: 'ellipsis',
615
- color: item.session_id === this.state.sessionId ? '#1551FF' : '#333',
616
- }}
617
- >
618
- {item.text}
619
- </div>
620
- </div>
621
- ))}
622
- </div>
623
- ) : (
624
- <div className="p_historyListEmpty" style={{display: 'flex', flexDirection: 'column', alignItems: 'center', marginTop: 50}}>
625
- <img src={historyListEmptyPng} style={{width: '100px', height: '100px', marginBottom: 20}}/>
626
- <div className="p_historyListEmptyText" style={{fontSize: 16, color: '#999' }}>暂无对话记录</div>
627
- </div>
628
- )}
629
- </div>
630
- <div style={{display: 'flex', justifyContent: 'center', alignItems: 'center', marginTop: 20, marginBottom: 50}}>
631
- {
632
- isShowLogin &&
633
- <div
634
- style={{
635
- display: 'flex',
636
- justifyContent: 'center',
637
- alignItems: 'center',
638
- width: '80%',
639
- height: 44,
640
- color: '#fff',
641
- background: 'linear-gradient( 30deg, #1551FF 0%, #8F4BFF 100%)',
642
- borderRadius: 10
643
- }}
644
- onClick={() => {
645
- if (isFunction(loginBtnClick)){
646
- loginBtnClick()
647
- }else {
648
- if (typeof wx !== 'undefined' && wx.miniProgram) {
649
- wx.miniProgram.navigateTo({url: '/pages/login/index'});
650
- }
651
- }
652
- }}
653
- >
654
- {isLogin ? '退出登录' : '登录'}
655
- </div>
656
- }
657
- </div>
658
- </Drawer>
659
- </>
660
- )
661
- }
662
- <div className="p_toolRight">
663
- <ChatWidget
664
- input_container_style={{zIndex:2}}
665
- chat_window_style={{paddingTop: 0}}
666
- bot_message_style={{background: '#fff'}}
667
- window_title={currentFlow?.name || title}
668
- flow_id={currentFlow?.id || flowId}
669
- tags={currentFlow?.keywords || tags}
670
- host_url={hostUrl}
671
- api_key={api_key}
672
- session_id={this.state.sessionId}
673
- userInfo={userInfo}
674
- getHistoryList={this.getHistoryList}
675
- setDropDownList={(list) => this.setState({dropDownList: list})}
676
- dropDownList={this.state.dropDownList}
677
- baseConfig={{isTitleSideIcon, logoWidth, agentUrl}}
678
- isShowVoiceButton={isShowVoiceButton}
679
- isShowUploadButton={isShowUploadButton}
680
- dropManUrl={character || dropManUrl}
681
- modalWidth={modalWidth}
682
- isMobile={true}
683
- isShowChatHeader={false}
684
- />
685
- </div>
686
- {
687
- isShowSideRight && (
688
- <>
689
- <img
690
- src={icon_agents}
691
- style={{
692
- width: '60px',
693
- height: '60px',
694
- position: 'absolute',
695
- right: '0px',
696
- bottom: '200px',
697
- zIndex: 1000
698
- }}
699
- onClick={() => this.setState({agentDrawerVisible: true})}
700
- />
701
- <Drawer
702
- title={'专项技能'}
703
- // closable={false}
704
- placement="right"
705
- width={'100%'}
706
- style={{
707
- backgroundImage: 'url(https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/kai_yuan/yt/agent_list_bg.png)',
708
- backgroundSize: 'cover',
709
- backgroundRepeat: 'no-repeat',
710
- backgroundPosition: 'center'
711
- }}
712
- bodyStyle={{
713
- padding: 0,
714
- }}
715
- onClose={() => this.setState({agentDrawerVisible: false})}
716
- open={this.state.agentDrawerVisible}
717
- >
718
- <div
719
- className={"p_toolRightToRight"}
720
- style={{
721
- width:'100%',
722
- display:'flex',
723
- boxSizing:'border-box',
724
- flexDirection:'column',
725
- padding: '1rem 1rem 1rem 1rem',
726
- }}
727
- >
728
- <div
729
- className={"rightInnerContainer"}
730
- style={{
731
- width:'100%',
732
- display:'flex',
733
- flexDirection:'row',
734
- justifyContent:'space-between',
735
-
736
- }}
737
- >
738
- <div style={{width:'100%'}}>
739
- {/*<h3 className={"rightSideTitle"}>*/}
740
- {/* <img width={15} src={self_skills}/>*/}
741
- {/* <span style={{color: "#333333"}}>专项技能</span>*/}
742
- {/*</h3>*/}
743
- {
744
- isEmpty(flows) ?
745
- <Skeleton
746
- title={false}
747
- active
748
- paragraph={{rows: 5, width: '100%'}}
749
- />
750
- :
751
- <div className={"rightSkillContainer"} style={{width:'100%'}}>
752
- <div
753
- className={"rightSkillList"}
754
- style={{
755
- width:'100%',
756
- display: 'grid',
757
- gridTemplateColumns: 'repeat(2, 1fr)', /* 每行 2 列 */
758
- gap: 20 /* 设置列和行之间的间距 */
759
- }}>
760
- {flows.slice(0, 12).map((item) => (
761
- <div
762
- key={item.id}
763
- className={"rightSkillItem"}
764
- style={{
765
- display: 'flex',
766
- flexDirection: 'column',
767
- background: '#fff',
768
- borderRadius: 22,
769
- opacity: 0.7,
770
- width:'100%',
771
- height: '45vw',
772
- boxSizing: 'border-box',
773
- padding: '18px',
774
- }}
775
- onClick={() => {
776
- // 右侧点击一个技能,更新sessionId,切换当前flow信息,重新查询历史记录
777
- this.setState({
778
- sessionId: uuidv4(),
779
- currentFlow: item,
780
- dropDownList: this.getDropDownList(item.welcome_words),
781
- agentDrawerVisible: false,
782
- });
783
- this.setWindowTitle(item.name)
784
- this.getCurrentFlowHistory(item.id);
785
- }}
786
- >
787
- <img
788
- src={item.icon}
789
- alt={item.name}
790
- style={{width: '40px', height: '40px'}}
791
- />
792
- <div style={{marginTop: '12px', color: '#333333', fontWeight: "bold", fontSize: '14px', textAlign: "left"}}>{item.name}</div>
793
- <div style={{marginTop: '8px', color: '#333333', fontSize: '10px', textAlign: "left"}}>{item.content}</div>
794
- </div>
795
- ))}
796
- </div>
797
- </div>
798
- }
799
- </div>
800
- {/*<div>*/}
801
- {/* <h3 className={"rightKnowledgeTitle"}>*/}
802
- {/* <img width={15} src={self_knowledge}/>*/}
803
- {/* <span style={{color: "#333333"}}>个人知识库</span>*/}
804
- {/* </h3>*/}
805
- {/* {*/}
806
- {/* isEmpty(currentFlow) ?*/}
807
- {/* <Skeleton*/}
808
- {/* title={false}*/}
809
- {/* active*/}
810
- {/* paragraph={{rows: 5, width: '100%'}}*/}
811
- {/* /> :*/}
812
- {/* <div className={"rightKnowledgeContainer"}>*/}
813
- {/* <img src={moreBg}/>*/}
814
- {/* <div style={{position: 'absolute', top: '40px', left: '16px'}}>*/}
815
- {/* <div>文件总数<span style={{*/}
816
- {/* padding: 8,*/}
817
- {/* fontSize: '20px',*/}
818
- {/* fontWeight: 700*/}
819
- {/* }}>{currentFlow.k_count || 0}</span>个*/}
820
- {/* </div>*/}
821
- {/* <div style={{marginTop: 10}}>文件总量<span style={{*/}
822
- {/* padding: 8,*/}
823
- {/* fontSize: '20px',*/}
824
- {/* fontWeight: 700*/}
825
- {/* }}>{formatFileSize(currentFlow.k_size).formattedSize}</span>{formatFileSize(currentFlow.k_size).unit}*/}
826
- {/* </div>*/}
827
- {/* </div>*/}
828
- {/* <div className={"rightMoreButton"}>*/}
829
- {/* <div className={"rightMoreTitle"}*/}
830
- {/* onClick={() => messageTip.info("敬请期待")}>训练你的专属知识库*/}
831
- {/* </div>*/}
832
- {/* </div>*/}
833
- {/* </div>*/}
834
- {/* }*/}
835
- {/*</div>*/}
836
- </div>
837
- </div>
838
- </Drawer>
839
- </>
840
- )
841
- }
842
- </div>
843
- </div>
844
- );
845
- }
846
- }
847
-
848
- export default MobileChatPage;
1
+ /* global wx */
2
+ import React from 'react';
3
+ import aiAvatarPng from '../../assets/aicenter/aiavatar.png';
4
+ import historyPng from '../../assets/aicenter/history.png';
5
+ import closePng from '../../assets/aicenter/close.png';
6
+ import { getFlowInfo, getHistoryList, getSceneInfo } from '../chatWidget/chatWindow/controllers/index';
7
+ import './index.module.css'
8
+ import { v4 as uuidv4 } from 'uuid';
9
+ import historyListEmptyPng from '../../assets/aicenter/history-list-empty.png';
10
+ import {isEmpty, isFunction} from "lodash";
11
+ import {Button, message as messageTip, Progress, Skeleton, Drawer, Tabs} from 'antd'
12
+ import moreAi from '../../assets/aicenter/moreAi.png';
13
+ import icon_history from '../../assets/aicenter/icon_history.png';
14
+ import icon_agents from '../../assets/aicenter/icon_agents.png';
15
+ import icon_history_upload from '../../assets/aicenter/icon_history_upload.png';
16
+ import icon_history_headerbg from '../../assets/aicenter/icon_history_headerbg.png';
17
+ import icon_history_add from '../../assets/aicenter/icon_history_add.png';
18
+ import ChatWidget from "../chatWidget";
19
+ import Draggable from 'react-draggable';
20
+
21
+
22
+ const style=`
23
+ .p_closeImg {
24
+ width: 14px;
25
+ cursor: pointer;
26
+ }
27
+
28
+ .p_toolDialog {
29
+ display: flex;
30
+ height:100%;
31
+ background:url('https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/ai/ai_modal_bg.png');
32
+ background-size: cover;
33
+ border-radius:8px;
34
+ }
35
+
36
+ .p_toolDialog .p_toolLeft {
37
+ display: flex;
38
+ flex-direction: column;
39
+ align-items: center;
40
+ width: 300px;
41
+ padding: 1.7rem 1.6rem 1.7rem 1.6rem;
42
+
43
+ border-top-left-radius: 8px;
44
+ border-bottom-left-radius: 8px;
45
+ }
46
+
47
+ .p_toolDialog .p_toolLeft .p_toolLogo {
48
+ user-select: none;
49
+ display: flex;
50
+ align-items: center;
51
+ }
52
+
53
+ .p_toolDialog .p_toolLeft .p_toolLogo .p_logoImg {
54
+ width: 48px;
55
+ }
56
+
57
+ .p_toolDialog .p_toolLeft .p_toolLogo .p_logoText {
58
+ font-weight: bold;
59
+ margin-left: 10px;
60
+ font-size: 30px;
61
+ background: linear-gradient(to right, #1551FF, #8F4BFF);
62
+ -webkit-background-clip: text;
63
+ -webkit-text-fill-color: transparent;
64
+ }
65
+
66
+ .p_toolDialog .p_toolLeft .p_historyDialog {
67
+ user-select: none;
68
+ margin-top: 20px;
69
+ margin-bottom: 20px;
70
+ border-radius: 10px;
71
+ flex: 1;
72
+ width: 100%;
73
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%);
74
+ border-image: linear-gradient(180deg, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0)) 1 1;
75
+ backdrop-filter: blur(10px);
76
+ position: relative;
77
+ max-height:calc(100% - 5.5rem - 60px);
78
+ }
79
+
80
+ .p_toolDialog .p_toolLeft .p_historyDialog ::-webkit-scrollbar-thumb {
81
+ border-radius: 10px;
82
+ -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
83
+ background: #535353 !important;
84
+ }
85
+
86
+ .p_toolDialog .p_toolLeft .p_historyDialog .p_historyTitle {
87
+ padding: 1.3rem 16px 0 16px;
88
+ display: flex;
89
+ align-items: center;
90
+ }
91
+
92
+ .p_toolDialog .p_toolLeft .p_historyDialog .p_historyTitle .p_historyImg {
93
+ width: 25px;
94
+ }
95
+
96
+ .p_toolDialog .p_toolLeft .p_historyDialog .p_historyTitle .p_dialogTitle {
97
+ margin-left: 10px;
98
+ font-weight: 500;
99
+ font-size: 18px;
100
+ color: #333333;
101
+ line-height: 16px;
102
+ text-align: left;
103
+ font-style: normal;
104
+ }
105
+
106
+ .p_toolDialog .p_toolLeft .p_historyDialog .p_historyListEmpty {
107
+ position: absolute;
108
+ top: 50%;
109
+ left: 50%;
110
+ transform: translate(-50%, -50%);
111
+ text-align: center;
112
+ font-size: 12px;
113
+ color: #999999;
114
+ max-height: calc(100% - 3rem);
115
+
116
+ }
117
+
118
+ .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList {
119
+ height: calc(100% - 3rem);
120
+ margin-top: 10px;
121
+ overflow-y: auto;
122
+ scrollbar-width: none !important; /* firefox */
123
+ }
124
+
125
+ .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList::-webkit-scrollbar{
126
+ display:none;
127
+ }
128
+
129
+ .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList:hover {
130
+ scrollbar-width: thin !important; /* firefox */
131
+ scrollbar-color: #ced4e3 transparent;
132
+ }
133
+
134
+ .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList .p_historyItem {
135
+ padding: 7px 16px;
136
+ }
137
+
138
+ .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList .p_historyItem .p_activeHistoryName {
139
+ color: #1552FF !important;
140
+ }
141
+
142
+ .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList .p_historyItem .p_historyName {
143
+ color: #333333;
144
+ overflow: hidden;
145
+ text-overflow: ellipsis;
146
+ white-space: nowrap;
147
+ cursor: pointer;
148
+ }
149
+
150
+ .p_toolDialog .p_toolLeft .p_historyDialog .p_historyList .p_historyItem .p_historyName:hover {
151
+ color: #171717;
152
+ }
153
+
154
+ .p_toolDialog .p_toolRight {
155
+ flex: 1;
156
+ }
157
+
158
+ .p_toolRightToRight {
159
+ width:300px;
160
+ display:flex;
161
+ flex-direction:column;
162
+ padding:2rem 1.6rem 1.8rem 1.6rem
163
+ }
164
+ .rightInnerContainer{
165
+ height:calc(100% - 80px);
166
+ flex:1;
167
+ display:flex;
168
+ flex-direction:column;
169
+ justify-content: space-between;
170
+ }
171
+ .p_toolRightToRight .rightSideTitle{
172
+ margin-bottom:1.4rem;
173
+ margin-top:10px;
174
+ margin-top:0;
175
+ font-size:18px;
176
+ font-weight:500;
177
+ display:flex;
178
+ align-items: center;
179
+ }
180
+ .p_toolRightToRight .rightSideTitle img{
181
+ margin-right:4px;
182
+ }
183
+
184
+ .p_toolRightToRight .rightSideTitle .titleSideColumn{
185
+ color:#1551FF;
186
+ }
187
+
188
+ .p_toolRightToRight .rightSkillContainer{
189
+ min-height:40%;
190
+ }
191
+ .p_toolRightToRight .rightSkillContainer .rightSkillList{
192
+ display: flex;
193
+ flex-wrap: wrap;
194
+ grid-template-columns: repeat(3, 1fr);
195
+ gap: 10px;
196
+ }
197
+ .p_toolRightToRight .rightSkillContainer .rightSkillList .rightSkillItem{
198
+ text-align: center;
199
+ cursor:pointer;
200
+ width:30%;
201
+ }
202
+ .p_toolRightToRight .rightSkillContainer .rightSkillList .rightSkillItem img{
203
+ width: 40px;
204
+ height: 40px;
205
+ border-radius:10px;
206
+ }
207
+ .p_toolRightToRight .rightSkillContainer .rightSkillList .rightSkillItem p{
208
+ margin-top:0px;
209
+ margin-bottom:4px;
210
+ overflow: hidden;
211
+ text-overflow: ellipsis;
212
+ white-space: nowrap;
213
+ color: #333333;
214
+ }
215
+ .p_toolRightToRight .rightKnowledgeTitle{
216
+ nargin-top: 2.2rem;
217
+ margin-bottom: 1.4rem;
218
+ font-size:18px;
219
+ font-weight:500;
220
+ display:flex;
221
+ align-items: center;
222
+ }
223
+
224
+ .p_toolRightToRight .rightKnowledgeTitle img{
225
+ margin-right:4px;
226
+ }
227
+
228
+ .p_toolRightToRight .rightKnowledgeContainer{
229
+ position:relative;
230
+ }
231
+ .p_toolRightToRight .rightMoreButton{
232
+ background: url(${moreAi});
233
+ background-size: 85% auto;
234
+ background-repeat: no-repeat;
235
+ background-position: bottom;
236
+ position: absolute;
237
+ bottom: 8px;
238
+ left: 0;
239
+ width: 100%;
240
+ height: 100%;
241
+ z-index: 1;
242
+ display: flex;
243
+ justify-content: center;
244
+ align-items: flex-end;
245
+ }
246
+ .p_toolRightToRight .rightMoreButton div{
247
+ width:calc(100% - 50px);
248
+ padding: 16px 16px 10px 20px;
249
+ font-weight: 500;
250
+ color: #ffffff;
251
+ line-height: 17px;
252
+ font-size: 12px;
253
+ cursor:pointer;
254
+ }
255
+
256
+ .p_newDialog {
257
+ width: 252px;
258
+ height: 40px;
259
+ min-height:40px;
260
+ background: linear-gradient( 45deg, #1551FF 0%, #8F4BFF 100%);
261
+ margin-top: 20px;
262
+ border-radius: 20px;
263
+ cursor: pointer;
264
+ display: flex;
265
+ align-items: center;
266
+ justify-content: center;
267
+ }
268
+
269
+ .p_newDialog img {
270
+ width: 18px;
271
+ }
272
+
273
+ .p_newDialog .p_newDialogText {
274
+ color: #fff;
275
+ margin-left: 6px;
276
+ }
277
+
278
+ .drawer-history-header {
279
+ margin-top: 40px;
280
+ }
281
+
282
+ .drawer-history-header-title {
283
+ display: flex;
284
+ flex-direction: row;
285
+ align-items: center;
286
+
287
+ > img {
288
+ width:35px
289
+ }
290
+
291
+ > span {
292
+ }
293
+ }
294
+
295
+ .drawer-history-header .drawer-history-header-tool {
296
+
297
+ > img {
298
+ }
299
+
300
+ > span {
301
+ }
302
+ }
303
+
304
+ .drawer-history-content {
305
+ }
306
+ .drawer-history-footer {
307
+ }
308
+
309
+ `
310
+
311
+ const defaultList = [
312
+ {
313
+ backgroundImg: 'https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/ai/drop-down-item-card-01.png',
314
+ title: '我这学期的课程安排是什么样?',
315
+ },
316
+ {
317
+ backgroundImg: 'https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/ai/drop-down-item-card-02.png',
318
+ title: '我上个学期的成绩是多少?',
319
+ },
320
+ {
321
+ backgroundImg: 'https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/ai/drop-down-item-card-03.png',
322
+ title: '哪里可以找到心理咨询服务?',
323
+ },
324
+ ];
325
+
326
+ const formatFileSize = (bytes) => {
327
+ // 如果字节数为0,直接返回
328
+ if(isEmpty(bytes)) {
329
+ return { formattedSize: 0, unit: 'B' };
330
+ }
331
+ if(bytes === 0) return { formattedSize: 0, unit: 'B' };
332
+
333
+ // 定义单位和对应的字节数(1024进制)
334
+ const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
335
+ // 计算合适的单位索引
336
+ const index = Math.floor(Math.log(bytes) / Math.log(1024));
337
+ // 将字节数转换为目标单位
338
+ const size = bytes / Math.pow(1024, index);
339
+ // 保留两位小数,并去除多余的0
340
+ const formattedSize = size.toFixed(2).replace(/\.?0+$/, '');
341
+ return { formattedSize, unit: units[index] }
342
+ }
343
+
344
+
345
+ const api_key = 'sk-mniUFDpcWwvNF3iFzssXa6etN-S_Y4AApyHYcBU44L0';
346
+ const drawerTabs = [
347
+ {id:'agent', name:'专项技能',icon:'https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/ai/icon/icon_tab_agent.png',activeIcon:'https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/ai/icon/icon_tab_agent_1.png'},
348
+ {id:'history', name:'对话记录',icon:'https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/ai/icon/icon_tab_history.png',activeIcon:'https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/ai/icon/icon_tab_history_1.png'}
349
+ ]
350
+
351
+ export class MobileChatPage extends React.Component {
352
+ state = {
353
+ historyList: [], // 历史对话列表
354
+ sessionId: uuidv4(), // 当前激活的对话对应的sessionId
355
+ dropDownList: [],
356
+ sceneInfo: {},
357
+ currentFlow: {},
358
+ currentTabKey:'agent',
359
+ historyDrawerVisible: false, // 抽屉历史记录状态
360
+ agentDrawerVisible: false, // 多智能体切换抽屉状态
361
+ };
362
+
363
+ constructor(props) {
364
+ super(props);
365
+ this.dragging = false;
366
+ }
367
+
368
+ async componentDidMount() {
369
+ if(isEmpty(this.props.sceneId)){
370
+ // 兼容非场景打开的情况
371
+ this.getHistoryList({},true);
372
+ }else{
373
+ const sceneData = await this.getSceneInfo();
374
+ if(isEmpty(sceneData)) {
375
+ this.getHistoryList({},true);
376
+ } else {
377
+ this.setWindowTitle(sceneData.name)
378
+ this.getHistoryList(sceneData,true);
379
+ }
380
+ }
381
+ }
382
+
383
+ setWindowTitle = (title) => {
384
+ if (!isEmpty(title)){
385
+ document.title = title;
386
+ window.document.title = title;
387
+ }
388
+ }
389
+
390
+ getCurrentFlowHistory=(flowId)=>{
391
+ let { userInfo = {} } = this.props;
392
+ const { sessionId } = this.state;
393
+ if(isEmpty(userInfo.code)) {
394
+ userInfo.code = sessionId;
395
+ }
396
+ const operationId = userInfo['code'] || '';
397
+ console.log('getCurrentFlowHistory', flowId, operationId)
398
+ getHistoryList(this.props.hostUrl, flowId, operationId).then((res) => {
399
+ if(res.status === 200){
400
+ console.log('getCurrentFlowHistory', res.data)
401
+ this.setState({ historyList: res.data });
402
+ }
403
+ });
404
+ }
405
+
406
+ // 获取历史对话列表
407
+ getHistoryList = (sceneData, isRefreshWords) => {
408
+ const { sceneId, appId: flowId, isShowSideLeft } = this.props;
409
+ if(isEmpty(sceneId)){
410
+ // 单独组件情况
411
+ if(isRefreshWords){
412
+ this.getFlowInfo().then(currentFlow=>{
413
+ const dropDownList = this.getDropDownList(currentFlow.welcome_words);
414
+ this.setState({ dropDownList, currentFlow })
415
+ })
416
+ }
417
+ if(isShowSideLeft) {
418
+ this.getCurrentFlowHistory(flowId)
419
+ }
420
+ }else{
421
+ const currentScene = sceneData||this.state.sceneInfo;
422
+ const currentFlow = currentScene.flows[0];
423
+ console.log('getHistoryList', sceneData, currentFlow)
424
+ const dropDownList = this.getDropDownList(currentFlow.welcome_words);
425
+ if(!isEmpty(sceneData)){
426
+ this.setState({ currentFlow, dropDownList })
427
+ }else if(isEmpty(this.state.sceneInfo)){
428
+ this.setState({ dropDownList:defaultList })
429
+ }
430
+ if(isShowSideLeft) {
431
+ this.getCurrentFlowHistory(currentFlow.id)
432
+ }
433
+ }
434
+ };
435
+
436
+ getSceneInfo = async ()=>{
437
+ const res = await getSceneInfo(this.props.hostUrl, this.props.sceneId, api_key);
438
+ if(res.status === 200){
439
+ this.setState({ sceneInfo: res.data });
440
+ }
441
+ return res.data;
442
+ }
443
+
444
+ getFlowInfo = async () => {
445
+ const res = await getFlowInfo(this.props.hostUrl, this.props.appId, api_key);
446
+ if(res.status === 200) {
447
+ this.setState({ sceneInfo: res.data });
448
+ }
449
+ return res.data;
450
+ }
451
+
452
+ // 新建对话
453
+ newDialog = () => {
454
+ if(this.state.dropDownList) {
455
+ messageTip.info("当前已是最新对话")
456
+ return;
457
+ }
458
+ this.setState({ sessionId: uuidv4() });
459
+ this.setState({ dropDownList: this.getDropDownList(this.state.currentFlow.welcome_words), drawerVisible: false })
460
+ }
461
+
462
+ updateSessionId = (sessionId) => {
463
+ this.setState({ sessionId });
464
+ };
465
+
466
+ getDropDownList = (welcome_words)=>{
467
+ if(isEmpty(welcome_words)){
468
+ return defaultList;
469
+ }
470
+ return welcome_words.map((question,index)=>(
471
+ {
472
+ backgroundImg:defaultList[index].backgroundImg,
473
+ title:question,
474
+ }
475
+ ))
476
+ }
477
+
478
+ render() {
479
+ const {
480
+ title,
481
+ appId: flowId,
482
+ hostUrl,
483
+ setDialogVisible,
484
+ userInfo,
485
+ boxStyle,
486
+ isShowSideRight,
487
+ isShowSideLeft = true,
488
+ tags = [],
489
+ agentUrl = aiAvatarPng,
490
+ agentName = '校园智多星',
491
+ logoWidth = '42px',
492
+ logoFontSize = '26px',
493
+ isTitleSideIcon = false,// 是否将左侧历史顶部icon移到中间顶部左侧蓝点位置
494
+ modalIndex,
495
+ isShowVoiceButton,
496
+ isShowUploadButton,
497
+ dropManUrl,
498
+ modalWidth,
499
+ isLogin = false,
500
+ isShowLogin = false,
501
+ loginBtnClick,
502
+ } = this.props;
503
+ const { sceneInfo, currentFlow = {} } = this.state;
504
+ const { flows = [], name: sceneName, character } = sceneInfo;
505
+ return (
506
+ <div style={boxStyle}>
507
+ <style dangerouslySetInnerHTML={{ __html: style }}></style>
508
+ <div style={{ position: 'absolute', top: '15px', right: '14px', zIndex: modalIndex }}>
509
+ {isFunction(setDialogVisible) &&
510
+ <img onClick={() => setDialogVisible(false)} className="p_closeImg" src={closePng}/>}
511
+ </div>
512
+ <div className="p_toolDialog" style={{borderRadius:0, backgroundImage:'url(https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/kai_yuan/yt/agent_list_bg2.png)'}}>
513
+ {
514
+ isShowSideLeft && (
515
+ <>
516
+ <img
517
+ src={icon_history}
518
+ style={{
519
+ width: '40px',
520
+ height: '40px',
521
+ position: 'absolute',
522
+ left: '0px',
523
+ top: '0px',
524
+ zIndex: 1000,
525
+ display: 'none',
526
+ }}
527
+ onClick={() => this.setState({drawerVisible: true})}
528
+ />
529
+ <Drawer
530
+ title={null}
531
+ closable={false}
532
+ placement="left"
533
+ width={'80%'}
534
+ bodyStyle={{padding: 0}}
535
+ onClose={() => this.setState({drawerVisible: false})}
536
+ open={this.state.drawerVisible}
537
+ >
538
+ <div className="drawer-history-header" style={{marginTop:0, padding: '54px 14px 14px 14px', background: 'linear-gradient( 71deg, #E1E9FF 0%, #FFFFFF 100%)', position: "relative"}}>
539
+ <img src={icon_history_headerbg} style={{position: 'absolute', right: 0, bottom: 0, width: '40%', zIndex:0}}/>
540
+ <div className="drawer-history-header-title" style={{display: 'flex', flexDirection: 'row', alignItems: 'center'}}>
541
+ <img style={{width: 35}} src={agentUrl}/>
542
+ <span style={{fontSize: 24, marginLeft: 10}}>{agentName}</span>
543
+ </div>
544
+ {/*<div className="drawer-history-header-tool" style={{display: 'flex',flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginTop: 32 }}>*/}
545
+ {/* <div*/}
546
+ {/* style={{display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'center', marginRight: 20, height: 44,background: '#fff', borderRadius: 5,width: '45%'}}*/}
547
+ {/* onClick={() => {this.newDialog()}}*/}
548
+ {/* >*/}
549
+ {/* <img src={icon_history_add} style={{width: '20px', height: '20px', marginRight: 10}}/>*/}
550
+ {/* <span>新建对话</span>*/}
551
+ {/* </div>*/}
552
+ {/* <div*/}
553
+ {/* style={{*/}
554
+ {/* display: 'flex',*/}
555
+ {/* flexDirection: 'row',*/}
556
+ {/* alignItems: 'center',*/}
557
+ {/* justifyContent: 'center',*/}
558
+ {/* marginRight: 20,*/}
559
+ {/* height: 44,*/}
560
+ {/* background: '#fff',*/}
561
+ {/* borderRadius: 5,*/}
562
+ {/* width: '45%',*/}
563
+ {/* zIndex: 0*/}
564
+ {/* }}*/}
565
+ {/* onClick={() => messageTip.info("敬请期待")}*/}
566
+ {/* >*/}
567
+ {/* <img src={icon_history_upload} style={{width: '20px', height: '20px', marginRight: 10}}/>*/}
568
+ {/* <span>个人知识库</span>*/}
569
+ {/* </div>*/}
570
+ {/*</div>*/}
571
+ </div>
572
+ <div
573
+ className="p_historyDialog"
574
+ style={{
575
+ height: 'calc(100% - 146px - 50px)',
576
+ boxSizing: 'border-box',
577
+ userSelect: 'none',
578
+ flex: 1,
579
+ background: 'linear-gradient(180deg, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%)',
580
+ borderImage: 'linear-gradient(180deg, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0)) 1 1',
581
+ backdropFilter: 'blur(10px)',
582
+ position: 'relative',
583
+ }}
584
+ >
585
+ <div style={{display: 'flex', flexDirection: 'row', justifyContent: 'space-between'}}>
586
+ {
587
+ drawerTabs.map((item, index) => (
588
+ <div id={item.id} style={{
589
+ width:'50%',
590
+ display: 'flex',
591
+ WebkitTapHighlightColor: 'transparent',
592
+ userSelect: 'none',
593
+ WebkitUserSelect: 'none',
594
+ WebkitTouchCallout: 'none',
595
+ flexDirection: 'row',
596
+ alignItems: 'center',
597
+ justifyContent: 'center',
598
+ cursor: 'pointer',
599
+ padding: '30px 14px 15px 14px',
600
+ borderBottom: this.state.currentTabKey === item.id ? '2px solid #2850FF' : '2px solid #fff'
601
+ }}
602
+ onClick={() => this.setState({currentTabKey: item.id})}
603
+ >
604
+ <img style={{width:16, marginRight: 8}} src={this.state.currentTabKey === item.id ? item.activeIcon : item.icon} />
605
+ <div style={{fontSize:16, fontWeight: 'bold', color: this.state.currentTabKey === item.id ? '#2850FF' : '#333'}}>{item.name}</div>
606
+ </div>
607
+ ))
608
+ }
609
+ </div>
610
+ {/*专项技能*/}
611
+ {
612
+ this.state.currentTabKey === 'agent' &&
613
+ <div className="p_historyList" style={{overflowY: 'auto', height: 'calc(100% - 90px)'}}>
614
+ {[...flows,...flows,...flows]?.map((item) => (
615
+ <div
616
+ key={item.id}
617
+ className="p_historyItem"
618
+ style={{
619
+ display: 'flex',
620
+ height: 44,
621
+ alignItems: 'center',
622
+ paddingLeft: 30,
623
+ paddingRight: 30,
624
+ fontWeight: 400,
625
+ fontSize: 14,
626
+ color: '#333',
627
+ borderRadius: 10,
628
+ marginBottom: 24,
629
+ }}
630
+ onClick={() => {
631
+ // 右侧点击一个技能,更新sessionId,切换当前flow信息,重新查询历史记录
632
+ this.setState({
633
+ sessionId: uuidv4(),
634
+ currentFlow: item,
635
+ dropDownList: this.getDropDownList(item.welcome_words),
636
+ agentDrawerVisible: false,
637
+ });
638
+ this.setWindowTitle(item.name)
639
+ this.getCurrentFlowHistory(item.id);
640
+ }}
641
+ >
642
+ <div
643
+ style={{
644
+ width:'100%',
645
+ display: 'flex',
646
+ flexDirection: 'row',
647
+ alignItems: 'center',
648
+ justifyContent: 'space-between',
649
+ whiteSpace: 'nowrap',
650
+ overflow: 'hidden',
651
+ textOverflow: 'ellipsis',
652
+ color: item.session_id === this.state.sessionId ? '#1551FF' : '#333',
653
+ }}
654
+ >
655
+ <div style={{display: 'flex', flexDirection: 'row', alignItems: 'center', color:'#333', fontSize:'16px', textAlign:'left', fontWeight:'bold'}}>
656
+ <img
657
+ src={item.icon}
658
+ alt={item.name}
659
+ style={{width: '36px', borderRadius:5, marginRight: 10}}
660
+ />
661
+ {item.name}
662
+ </div>
663
+
664
+ <img
665
+ src={'https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/ai/icon/icon_arrow_right.png'}
666
+ style={{ height: '5px'}}
667
+ />
668
+ </div>
669
+ </div>
670
+ ))}
671
+ </div>
672
+ }
673
+
674
+ {/*对话记录*/}
675
+ {
676
+ this.state.currentTabKey === 'history' &&
677
+ (this.state.historyList.length > 0 ? (
678
+ <div className="p_historyList" style={{overflowY: 'auto', height: 'calc(100% - 70px)'}}>
679
+ {[...this.state.historyList, ...this.state.historyList, ...this.state.historyList, ...this.state.historyList]?.map((item) => (
680
+ <div
681
+ key={item.session_id}
682
+ className="p_historyItem"
683
+ style={{
684
+ display: 'flex',
685
+ height: 44,
686
+ alignItems: 'center',
687
+ paddingLeft: 30,
688
+ paddingRight: 30,
689
+ fontWeight: 400,
690
+ fontSize: 14,
691
+ color: '#333',
692
+ borderRadius: 10,
693
+ background: item.session_id === this.state.sessionId ? '#F5F5FF' : '#fff',
694
+ }}
695
+ onClick={() => {
696
+ this.setState({dropDownList: undefined, drawerVisible: false})
697
+ this.updateSessionId(item.session_id);
698
+ }}
699
+ >
700
+ <div
701
+ className={`p_historyName ${
702
+ item.session_id === this.state.sessionId ? 'p_activeHistoryName' : ''
703
+ }`}
704
+ style={{
705
+ whiteSpace: 'nowrap',
706
+ overflow: 'hidden',
707
+ textOverflow: 'ellipsis',
708
+ color: item.session_id === this.state.sessionId ? '#1551FF' : '#333',
709
+ }}
710
+ >
711
+ {item.text}
712
+ </div>
713
+ </div>
714
+ ))}
715
+ </div>
716
+ ) : (
717
+ <div className="p_historyListEmpty" style={{display: 'flex', flexDirection: 'column', alignItems: 'center', marginTop: 50}}>
718
+ <img src={historyListEmptyPng} style={{width: '100px', height: '100px', marginBottom: 20}}/>
719
+ <div className="p_historyListEmptyText" style={{fontSize: 16, color: '#999' }}>暂无对话记录</div>
720
+ </div>
721
+ ))
722
+ }
723
+ </div>
724
+ <div style={{display: 'flex', justifyContent: 'center', alignItems: 'center', marginTop: 10, marginBottom: 20}}>
725
+ {
726
+ isShowLogin &&
727
+ <div
728
+ style={{
729
+ display: 'flex',
730
+ justifyContent: 'center',
731
+ alignItems: 'center',
732
+ width: '80%',
733
+ height: 44,
734
+ color: '#fff',
735
+ background: 'linear-gradient( 30deg, #1551FF 0%, #8F4BFF 100%)',
736
+ borderRadius: 10
737
+ }}
738
+ onClick={() => {
739
+ this.setState({drawerVisible: false})
740
+ this.newDialog()
741
+ }}
742
+ >
743
+ 新建对话
744
+ </div>
745
+ }
746
+ </div>
747
+ </Drawer>
748
+ </>
749
+ )
750
+ }
751
+ <div className="p_toolRight">
752
+ <ChatWidget
753
+ input_container_style={{zIndex:2}}
754
+ chat_window_style={{paddingTop: 0}}
755
+ bot_message_style={{background: '#fff'}}
756
+ window_title={currentFlow?.name || title}
757
+ flow_id={currentFlow?.id || flowId}
758
+ tags={currentFlow?.keywords || tags}
759
+ host_url={hostUrl}
760
+ api_key={api_key}
761
+ session_id={this.state.sessionId}
762
+ userInfo={userInfo}
763
+ getHistoryList={this.getHistoryList}
764
+ setDropDownList={(list) => this.setState({dropDownList: list})}
765
+ dropDownList={this.state.dropDownList}
766
+ baseConfig={{isTitleSideIcon, logoWidth, agentUrl}}
767
+ isShowVoiceButton={isShowVoiceButton}
768
+ isShowUploadButton={isShowUploadButton}
769
+ dropManUrl={character || dropManUrl}
770
+ modalWidth={modalWidth}
771
+ isMobile={true}
772
+ isShowChatHeader={false}
773
+ />
774
+ </div>
775
+ {
776
+ isShowSideRight && (
777
+ <>
778
+ <Draggable onStart={() => { this.dragging = false; }}
779
+ onDrag={() => { this.dragging = true; }}
780
+ onStop={(e) => {
781
+ if (!this.dragging) {
782
+ this.setState({drawerVisible: true})
783
+ }
784
+ }}>
785
+ <img
786
+ src={icon_agents}
787
+ style={{
788
+ width: '60px',
789
+ height: '60px',
790
+ position: 'absolute',
791
+ right: '0px',
792
+ bottom: '200px',
793
+ zIndex: 1000
794
+ }}
795
+ />
796
+ </Draggable>
797
+ <Drawer
798
+ title={'专项技能'}
799
+ // closable={false}
800
+ placement="right"
801
+ width={'100%'}
802
+ style={{
803
+ backgroundImage: 'url(https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/kai_yuan/yt/agent_list_bg.png)',
804
+ backgroundSize: 'cover',
805
+ backgroundRepeat: 'no-repeat',
806
+ backgroundPosition: 'center'
807
+ }}
808
+ bodyStyle={{
809
+ padding: 0,
810
+ }}
811
+ onClose={() => this.setState({agentDrawerVisible: false})}
812
+ open={this.state.agentDrawerVisible}
813
+ >
814
+ <div
815
+ className={"p_toolRightToRight"}
816
+ style={{
817
+ width:'100%',
818
+ display:'flex',
819
+ boxSizing:'border-box',
820
+ flexDirection:'column',
821
+ padding: '1rem 1rem 1rem 1rem',
822
+ }}
823
+ >
824
+ <div
825
+ className={"rightInnerContainer"}
826
+ style={{
827
+ width:'100%',
828
+ display:'flex',
829
+ flexDirection:'row',
830
+ justifyContent:'space-between',
831
+
832
+ }}
833
+ >
834
+ <div style={{width:'100%'}}>
835
+ {/*<h3 className={"rightSideTitle"}>*/}
836
+ {/* <img width={15} src={self_skills}/>*/}
837
+ {/* <span style={{color: "#333333"}}>专项技能</span>*/}
838
+ {/*</h3>*/}
839
+ {
840
+ isEmpty(flows) ?
841
+ <Skeleton
842
+ title={false}
843
+ active
844
+ paragraph={{rows: 5, width: '100%'}}
845
+ />
846
+ :
847
+ <div className={"rightSkillContainer"} style={{width:'100%'}}>
848
+ <div
849
+ className={"rightSkillList"}
850
+ style={{
851
+ width:'100%',
852
+ display: 'grid',
853
+ gridTemplateColumns: 'repeat(2, 1fr)', /* 每行 2 列 */
854
+ gap: 20 /* 设置列和行之间的间距 */
855
+ }}>
856
+ {flows.slice(0, 12).map((item) => (
857
+ <div
858
+ key={item.id}
859
+ className={"rightSkillItem"}
860
+ style={{
861
+ display: 'flex',
862
+ flexDirection: 'column',
863
+ background: '#fff',
864
+ borderRadius: 22,
865
+ opacity: 0.7,
866
+ width:'100%',
867
+ height: '45vw',
868
+ boxSizing: 'border-box',
869
+ padding: '18px',
870
+ }}
871
+ onClick={() => {
872
+ // 右侧点击一个技能,更新sessionId,切换当前flow信息,重新查询历史记录
873
+ this.setState({
874
+ sessionId: uuidv4(),
875
+ currentFlow: item,
876
+ dropDownList: this.getDropDownList(item.welcome_words),
877
+ agentDrawerVisible: false,
878
+ });
879
+ this.setWindowTitle(item.name)
880
+ this.getCurrentFlowHistory(item.id);
881
+ }}
882
+ >
883
+ <img
884
+ src={item.icon}
885
+ alt={item.name}
886
+ style={{width: '40px', height: '40px'}}
887
+ />
888
+ <div style={{marginTop: '12px', color: '#333333', fontWeight: "bold", fontSize: '14px', textAlign: "left"}}>{item.name}</div>
889
+ <div style={{marginTop: '8px', color: '#333333', fontSize: '10px', textAlign: "left"}}>{item.content}</div>
890
+ </div>
891
+ ))}
892
+ </div>
893
+ </div>
894
+ }
895
+ </div>
896
+ {/*<div>*/}
897
+ {/* <h3 className={"rightKnowledgeTitle"}>*/}
898
+ {/* <img width={15} src={self_knowledge}/>*/}
899
+ {/* <span style={{color: "#333333"}}>个人知识库</span>*/}
900
+ {/* </h3>*/}
901
+ {/* {*/}
902
+ {/* isEmpty(currentFlow) ?*/}
903
+ {/* <Skeleton*/}
904
+ {/* title={false}*/}
905
+ {/* active*/}
906
+ {/* paragraph={{rows: 5, width: '100%'}}*/}
907
+ {/* /> :*/}
908
+ {/* <div className={"rightKnowledgeContainer"}>*/}
909
+ {/* <img src={moreBg}/>*/}
910
+ {/* <div style={{position: 'absolute', top: '40px', left: '16px'}}>*/}
911
+ {/* <div>文件总数<span style={{*/}
912
+ {/* padding: 8,*/}
913
+ {/* fontSize: '20px',*/}
914
+ {/* fontWeight: 700*/}
915
+ {/* }}>{currentFlow.k_count || 0}</span>个*/}
916
+ {/* </div>*/}
917
+ {/* <div style={{marginTop: 10}}>文件总量<span style={{*/}
918
+ {/* padding: 8,*/}
919
+ {/* fontSize: '20px',*/}
920
+ {/* fontWeight: 700*/}
921
+ {/* }}>{formatFileSize(currentFlow.k_size).formattedSize}</span>{formatFileSize(currentFlow.k_size).unit}*/}
922
+ {/* </div>*/}
923
+ {/* </div>*/}
924
+ {/* <div className={"rightMoreButton"}>*/}
925
+ {/* <div className={"rightMoreTitle"}*/}
926
+ {/* onClick={() => messageTip.info("敬请期待")}>训练你的专属知识库*/}
927
+ {/* </div>*/}
928
+ {/* </div>*/}
929
+ {/* </div>*/}
930
+ {/* }*/}
931
+ {/*</div>*/}
932
+ </div>
933
+ </div>
934
+ </Drawer>
935
+ </>
936
+ )
937
+ }
938
+ </div>
939
+ </div>
940
+ );
941
+ }
942
+ }
943
+
944
+ export default MobileChatPage;