@gientech/modual 1.5.0 → 1.5.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 (28) hide show
  1. package/dist/assets/GientechStreamReader-KtCNi1G3.js +447 -0
  2. package/dist/assets/style3.css +1 -1
  3. package/dist/chat.js +911 -2202
  4. package/dist/index.js +1 -1
  5. package/dist/package.json +1 -1
  6. package/dist/streamFilesReader.js +1 -1
  7. package/dist/worker/pdf.worker1.min.js +23 -0
  8. package/package.json +1 -1
  9. package/public/worker/pdf.worker1.min.js +23 -0
  10. package/src/main.tsx.backup +5 -5
  11. package/src/modules/chat/ReferenceBar.tsx +520 -11
  12. package/src/modules/chat/index.tsx +21 -29
  13. package/src/{utils/gientechCommon/components → modules/chat}/referenceCom/DrawerTitle.tsx +1 -1
  14. package/src/{utils/gientechCommon/components → modules/chat}/referenceCom/TagCom.tsx +1 -1
  15. package/src/{utils/gientechCommon/components → modules/chat}/utils/index.ts +6 -6
  16. package/src/utils/gientechCommon/components/Messages/GientechNewChatWelcome.tsx +231 -18
  17. package/src/utils/testconfigs/index.ts +1 -1
  18. package/stats.html +1 -1
  19. package/dist/assets/GientechStreamReader-BE_oxQLt.js +0 -446
  20. package/src/utils/gientechCommon/components/ReferenceListDrawer.tsx +0 -542
  21. package/src/utils/gientechCommon/components/hooks/useAichatEvent.ts +0 -10
  22. /package/src/{utils/gientechCommon/components → modules/chat}/referenceCom/DeleteModal.tsx +0 -0
  23. /package/src/{utils/gientechCommon/components → modules/chat}/referenceCom/DrawerContent.tsx +0 -0
  24. /package/src/{utils/gientechCommon/components → modules/chat}/referenceCom/DrawerDatabase.tsx +0 -0
  25. /package/src/{utils/gientechCommon/components → modules/chat}/referenceCom/DrawerGraphPreview.tsx +0 -0
  26. /package/src/{utils/gientechCommon/components → modules/chat}/referenceCom/DrawerPreview.tsx +0 -0
  27. /package/src/{utils/gientechCommon/components → modules/chat}/referenceCom/RenameModal.tsx +0 -0
  28. /package/src/{utils/gientechCommon/components → modules/chat}/style.css +0 -0
@@ -1,5 +1,6 @@
1
- import React, { useEffect, useMemo, useState, useRef } from 'react';
2
- import { Popover } from 'antd';
1
+ import { useEffect, useMemo, useState, useRef } from 'react';
2
+ import { Popover, Input } from 'antd';
3
+ import { Search, X, ChevronLeft, ChevronRight } from 'lucide-react';
3
4
  import { type Styles, defaultTheme } from '@mxmweb/zui';
4
5
  import { uid } from 'uid';
5
6
  import defaultWeLogo from './defaultWeLogo.svg';
@@ -48,14 +49,81 @@ const createWelcomeStyles = (colors: any, classId: string) => {
48
49
  box-shadow: inset 0 0 0 1px ${c.border};
49
50
  }
50
51
  .g-welcome-${classId} .g-welcome-pagination-btn {
52
+ background: transparent;
53
+ border: none;
54
+ color: ${c.disabled};
55
+ padding: 6px 10px;
56
+ border-radius: 9999px;
57
+ transition: all 0.2s;
58
+ font-size: 14px;
59
+ line-height: 1;
60
+ min-width: 32px;
61
+ height: 32px;
62
+ display: inline-flex;
63
+ align-items: center;
64
+ justify-content: center;
65
+ }
66
+ .g-welcome-${classId} .g-welcome-pagination-btn:hover:not(:disabled) {
67
+ color: ${c.text};
68
+ background-color: ${c.border}33;
69
+ }
70
+ .g-welcome-${classId} .g-welcome-pagination-btn.active {
51
71
  color: ${c.primary};
72
+ background: radial-gradient(100% 100% at 50% 50%, ${c.primary}10 0%, ${c.primary}08 100%);
73
+ box-shadow: 0 2px 10px ${c.primary}12, inset 0 0 0 1px ${c.primary}1A;
52
74
  }
53
75
  .g-welcome-${classId} .g-welcome-pagination-btn:disabled {
54
76
  color: ${c.disabled};
55
77
  cursor: not-allowed;
78
+ background: transparent;
56
79
  }
57
80
  .g-welcome-${classId} .g-welcome-pagination-text {
81
+ color: ${c.disabled};
82
+ font-size: 14px;
83
+ padding: 0 8px;
84
+ }
85
+ .g-welcome-${classId} .g-welcome-pagination-dot {
86
+ width: 6px;
87
+ height: 6px;
88
+ border-radius: 50%;
89
+ background-color: ${c.border};
90
+ transition: all 0.2s;
91
+ }
92
+ .g-welcome-${classId} .g-welcome-pagination-dot.active {
93
+ background-color: ${c.primary};
94
+ width: 20px;
95
+ border-radius: 3px;
96
+ }
97
+ .g-welcome-${classId} .g-welcome-search-btn {
98
+ background-color: #ffffff;
99
+ border: 1px solid ${c.border};
58
100
  color: ${c.text};
101
+ padding: 8px 8px;
102
+ border-radius: 100%;
103
+ cursor: pointer;
104
+ transition: all 0.2s;
105
+ display: flex;
106
+ align-items: center;
107
+ gap: 6px;
108
+ font-size: 14px;
109
+ box-shadow: 0 1px 2px rgba(31,35,41,0.04);
110
+ }
111
+ .g-welcome-${classId} .g-welcome-search-btn:hover {
112
+ border-color: ${c.primary};
113
+ color: ${c.primary};
114
+ box-shadow: 0 2px 6px rgba(31,35,41,0.08);
115
+ }
116
+ .g-welcome-${classId} .g-welcome-search-input {
117
+ border: 1px solid ${c.border};
118
+ border-radius: 9999px;
119
+ transition: all 0.2s;
120
+ height: 40px;
121
+ padding: 0 14px;
122
+ }
123
+ .g-welcome-${classId} .g-welcome-search-input:focus,
124
+ .g-welcome-${classId} .g-welcome-search-input:hover {
125
+ border-color: ${c.primary};
126
+ box-shadow: 0 0 0 2px ${c.primary}1A;
59
127
  }
60
128
  `;
61
129
  }
@@ -162,6 +230,8 @@ interface GientechNewChatWelcomeProps {
162
230
  function GientechNewChatWelcome(props: GientechNewChatWelcomeProps) {
163
231
  const { assistantList, eventsEmit, styles, selectedId, onSelectAssistant, productLogo } = props;
164
232
  const [currentPage, setCurrentPage] = useState(1);
233
+ const [searchVisible, setSearchVisible] = useState(false);
234
+ const [searchKeyword, setSearchKeyword] = useState('');
165
235
  const pageSize = 12;
166
236
 
167
237
  // 只在 selectedId 变化时触发事件,且去重
@@ -199,11 +269,30 @@ function GientechNewChatWelcome(props: GientechNewChatWelcomeProps) {
199
269
  return JSON.parse(selectAssistant?.configJson || '{}');
200
270
  }, [selectAssistant]);
201
271
 
272
+ // 搜索过滤逻辑
273
+ const filteredAssistants = useMemo(() => {
274
+ if (!searchKeyword.trim()) {
275
+ return assistantList || [];
276
+ }
277
+ const keyword = searchKeyword.toLowerCase().trim();
278
+ return (assistantList || []).filter(assistant => {
279
+ const name = assistant.name?.toLowerCase() || '';
280
+ // 也可以搜索配置中的信息
281
+ try {
282
+ const cfg = JSON.parse(assistant.configJson || '{}');
283
+ const configName = cfg.config_name?.toLowerCase() || '';
284
+ return name.includes(keyword) || configName.includes(keyword);
285
+ } catch {
286
+ return name.includes(keyword);
287
+ }
288
+ });
289
+ }, [assistantList, searchKeyword]);
290
+
202
291
  // 分页逻辑
203
- const totalPages = Math.ceil((assistantList?.length || 0) / pageSize);
204
- const currentAssistants = assistantList?.slice((currentPage - 1) * pageSize, currentPage * pageSize) || [];
292
+ const totalPages = Math.ceil((filteredAssistants?.length || 0) / pageSize);
293
+ const currentAssistants = filteredAssistants?.slice((currentPage - 1) * pageSize, currentPage * pageSize) || [];
205
294
 
206
- // 当选中助手时,自动跳转到对应页面
295
+ // 当选中助手时,自动跳转到对应页面(基于完整列表)
207
296
  useEffect(() => {
208
297
  if (selectedId && assistantList) {
209
298
  const selectedIndex = assistantList.findIndex(a => a.id === selectedId);
@@ -214,11 +303,20 @@ function GientechNewChatWelcome(props: GientechNewChatWelcomeProps) {
214
303
  }
215
304
  }, [selectedId, assistantList, pageSize]);
216
305
 
306
+ // 当搜索关键词变化时,重置到第一页(但如果正在选择助手,则跳过重置,让选择助手的跳转逻辑生效)
307
+ useEffect(() => {
308
+ // 如果有选中的助手,说明用户正在选择助手,此时不应该重置到第一页
309
+ // 让选择助手的跳转逻辑来决定页面
310
+ if (!selectedId) {
311
+ setCurrentPage(1);
312
+ }
313
+ }, [searchKeyword, selectedId]);
314
+
217
315
  const prologue = selectAssistantConfig.prologue || '您好,欢迎使用小鲸智能问答';
218
316
  const prologueTypewriter = useTypewriter(prologue, [selectedId], 30);
219
317
 
220
318
  return (
221
- <div className={`flex flex-col items-center justify-center h-full w-full g-welcome-${classId}`}>
319
+ <div className={`flex flex-col relative items-center justify-center h-full w-full g-welcome-${classId}`}>
222
320
  {/* 产品Logo */}
223
321
  <img
224
322
  src={productLogo || (defaultWeLogo as unknown as string)}
@@ -229,9 +327,47 @@ function GientechNewChatWelcome(props: GientechNewChatWelcomeProps) {
229
327
  <div className="text-3xl font-bold mb-2 g-welcome-title">{prologueTypewriter}</div>
230
328
  <div className="text-sm text-gray-500 mb-20">请选择一个智能助手,开始你的智能问答之旅</div>
231
329
  {!selectedId && <div className="flex mb-2 g-welcome-subtitle">请选择一个智能助手</div>}
232
- <div className="flex flex-wrap gap-3 px-5 justify-center mb-4">
330
+
331
+ <div
332
+ style={{
333
+ maxWidth: '1200px',
334
+ }}
335
+ className="flex flex-wrap gap-3
336
+ max-w-[1200px] px-8 w-full mx-auto justify-center mb-4">
337
+ {/* 搜索按钮/输入框 - 永远渲染为第一个元素 */}
338
+ {!searchVisible ? (
339
+ <button type="button" className="g-welcome-search-btn" onClick={() => setSearchVisible(true)}>
340
+ <Search size={16} />
341
+ </button>
342
+ ) : (
343
+ <div className="flex items-center gap-2 px-5 w-full" style={{ flexBasis: '100%' }}>
344
+ <Input
345
+ className="g-welcome-search-input w-full"
346
+ placeholder="搜索助手名称"
347
+ prefix={<Search size={16} />}
348
+ suffix={
349
+ <button
350
+ type="button"
351
+ onClick={() => {
352
+ setSearchVisible(false);
353
+ setSearchKeyword('');
354
+ }}
355
+ style={{ background: 'transparent', border: 'none', cursor: 'pointer' }}
356
+ >
357
+ <X size={14} />
358
+ </button>
359
+ }
360
+ value={searchKeyword}
361
+ onChange={(e) => setSearchKeyword(e.target.value)}
362
+ autoFocus
363
+ />
364
+ </div>
365
+ )}
366
+
367
+ {/* 助手列表或空状态 */}
233
368
  {currentAssistants && currentAssistants.length > 0 ? (
234
- currentAssistants.map(assistant => {
369
+ <>
370
+ {currentAssistants.map(assistant => {
235
371
  const isActive = selectedId === assistant.id;
236
372
  // 图标解析:优先 assistant.icon,其次配置中的 icon/avatar/logo,最后使用默认
237
373
  let iconSrc: string | undefined = assistant.icon;
@@ -250,8 +386,19 @@ function GientechNewChatWelcome(props: GientechNewChatWelcomeProps) {
250
386
  placement="bottom"
251
387
  >
252
388
  <button
389
+ type="button"
253
390
  className={`g-welcome-btn px-3 cursor-pointer rounded-full border font-medium min-w-[160px] text-sm transition-all flex items-center gap-2 ${isActive ? 'active' : ''}`}
254
- onClick={() => onSelectAssistant?.(assistant.id)}
391
+ onClick={() => {
392
+ onSelectAssistant?.(assistant.id);
393
+ // 若在搜索视图中选择了助手,则延迟清空并收起搜索,让跳转页面的逻辑先执行
394
+ if (searchVisible || searchKeyword) {
395
+ // 使用 setTimeout 延迟清空搜索,确保 selectedId 变化触发的跳转逻辑先执行
396
+ setTimeout(() => {
397
+ setSearchKeyword('');
398
+ setSearchVisible(false);
399
+ }, 0);
400
+ }
401
+ }}
255
402
  title={assistant.name}
256
403
  >
257
404
  <span className="icon-badge">
@@ -261,30 +408,96 @@ function GientechNewChatWelcome(props: GientechNewChatWelcomeProps) {
261
408
  </button>
262
409
  </Popover>
263
410
  );
264
- })
411
+ })}
412
+ </>
265
413
  ) : (
266
414
  <div className="g-welcome-subtitle">暂无可用助手</div>
267
415
  )}
268
416
  </div>
269
417
  {/* 分页控制 */}
270
418
  {totalPages > 1 && (
271
- <div className="flex items-center gap-3 text-sm">
419
+ <div className="flex items-center gap-2">
272
420
  <button
273
- className="g-welcome-pagination-btn px-3 py-1 rounded transition-colors"
421
+ type="button"
422
+ className="g-welcome-pagination-btn"
274
423
  onClick={() => setCurrentPage(p => Math.max(1, p - 1))}
275
424
  disabled={currentPage === 1}
276
425
  >
277
- 上一页
426
+ <ChevronLeft size={16} />
278
427
  </button>
279
- <span className="g-welcome-pagination-text">
280
- {currentPage} / {totalPages}
281
- </span>
428
+
429
+ {/* 页码显示 */}
430
+ <div className="flex items-center gap-1">
431
+ {(() => {
432
+ const pages: (number | string)[] = [];
433
+ const maxVisible = 7; // 最多显示7个页码
434
+
435
+ if (totalPages <= maxVisible) {
436
+ // 如果总页数少于等于7,显示所有页码
437
+ for (let i = 1; i <= totalPages; i++) {
438
+ pages.push(i);
439
+ }
440
+ } else {
441
+ // 总是显示第一页
442
+ pages.push(1);
443
+
444
+ if (currentPage <= 4) {
445
+ // 当前页在前4页,显示 1 2 3 4 5 ... totalPages
446
+ for (let i = 2; i <= 5; i++) {
447
+ pages.push(i);
448
+ }
449
+ pages.push('...');
450
+ pages.push(totalPages);
451
+ } else if (currentPage >= totalPages - 3) {
452
+ // 当前页在后4页,显示 1 ... totalPages-4 totalPages-3 totalPages-2 totalPages-1 totalPages
453
+ pages.push('...');
454
+ for (let i = totalPages - 4; i <= totalPages; i++) {
455
+ pages.push(i);
456
+ }
457
+ } else {
458
+ // 当前页在中间,显示 1 ... currentPage-1 currentPage currentPage+1 ... totalPages
459
+ pages.push('...');
460
+ for (let i = currentPage - 1; i <= currentPage + 1; i++) {
461
+ pages.push(i);
462
+ }
463
+ pages.push('...');
464
+ pages.push(totalPages);
465
+ }
466
+ }
467
+
468
+ return pages.map((page, index) => {
469
+ if (page === '...') {
470
+ return (
471
+ <span key={`ellipsis-${index}`} className="g-welcome-pagination-text px-1">
472
+ ...
473
+ </span>
474
+ );
475
+ }
476
+
477
+ const pageNum = page as number;
478
+ const isActive = currentPage === pageNum;
479
+
480
+ return (
481
+ <button
482
+ type="button"
483
+ key={pageNum}
484
+ className={`g-welcome-pagination-btn ${isActive ? 'active' : ''}`}
485
+ onClick={() => setCurrentPage(pageNum)}
486
+ >
487
+ {pageNum}
488
+ </button>
489
+ );
490
+ });
491
+ })()}
492
+ </div>
493
+
282
494
  <button
283
- className="g-welcome-pagination-btn px-3 py-1 rounded transition-colors"
495
+ type="button"
496
+ className="g-welcome-pagination-btn"
284
497
  onClick={() => setCurrentPage(p => Math.min(totalPages, p + 1))}
285
498
  disabled={currentPage === totalPages}
286
499
  >
287
- 下一页
500
+ <ChevronRight size={16} />
288
501
  </button>
289
502
  </div>
290
503
  )}
@@ -1,5 +1,5 @@
1
1
  const token =
2
- 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJHSUVOLVJBRyIsImF1ZCI6IkpJQUJJTkJJTjAwIiwidXNlcklkIjoxMjQzLCJ1c2VyTmFtZSI6IkpJQUJJTkJJTjAwIiwic3ViIjoibWl4ZWRRdWFudHVtIiwiZXhwIjoxNzYyOTE0NTAyLCJpYXQiOjE3NjI4MjgxMDJ9.K8A7FNhhJXJyeBfpYfpTbmUX65ur5c1tax4afv2UNBs';
2
+ 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJHSUVOLVJBRyIsImF1ZCI6IkpJQUJJTkJJTjAwIiwidXNlcklkIjoxMjQzLCJ1c2VyTmFtZSI6IkpJQUJJTkJJTjAwIiwic3ViIjoibWl4ZWRRdWFudHVtIiwiZXhwIjoxNzYyOTMxOTA4LCJpYXQiOjE3NjI4NDU1MDh9.mqneHIhe-T0isGc9JrdZDpWrzaogBqec13XBVlWsZOQ';
3
3
  export const rag_dev_server = {
4
4
  token,
5
5