Major Changes: - Add StreamingService with OpenAI Compatible format - Upgrade Chat component V2 with Ant Design X integration - Implement AIA module with 12 intelligent agents - Update API routes to unified /api/v1 prefix - Update system documentation Backend (~1300 lines): - common/streaming: OpenAI Compatible adapter - modules/aia: 12 agents, conversation service, streaming integration - Update route versions (RVW, PKB to v1) Frontend (~3500 lines): - modules/aia: AgentHub + ChatWorkspace (100% prototype restoration) - shared/Chat: AIStreamChat, ThinkingBlock, useAIStream Hook - Update API endpoints to v1 Documentation: - AIA module status guide - Universal capabilities catalog - System overview updates - All module documentation sync Tested: Stream response verified, authentication working Status: AIA V2.0 core completed (85%)
7.5 KiB
用户体验优化报告
日期: 2025-11-21
任务: å®¡æ ¸å·¥ä½œå<C593>°UX优化
**状�*: �已完�
📋 优化内容
1. 进度显示优化 â?
问题
- 进度æ<EFBFBD>¡ä»Ž0%直接跳到100%
- 看ä¸<EFBFBD>到ä¸é—´è¿‡ç¨?
- 用户体验ä¸<EFBFBD>å<EFBFBD>‹å¥½ï¼Œç‰å¾…时没有å<EFBFBD><EFBFBD>é¦?
åŽŸå› åˆ†æž<EFBFBD>
- **å‰<C3A5>端轮询间隔太长**ï¼?ç§?æ¬?
- **å<>Žç«¯æ›´æ–°é¢‘率ä½?*:æ¯<C3A6>10æ<30>¡æ›´æ–°ä¸€æ¬?
对于少é‡<EFBFBD>文献ï¼?-20篇),æ¯<C3A6>10æ<30>¡æ›´æ–°æ„<C3A6>味ç<C2B3>€å‡ 乎看ä¸<C3A4>到ä¸é—´è¿‡ç¨‹ã€?
解决方案
å‰<EFBFBD>端优化 (useScreeningTask.ts):
// 修改�
pollingInterval = 2000 // 2ç§?
// 修改å<C2B9>?
pollingInterval = 1000 // 1秒,更å<C2B4>Šæ—?
å<EFBFBD>Žç«¯ä¼˜åŒ– (screeningService.ts):
// 修改å‰<C3A5>:æ¯?0æ<30>¡æ›´æ–°ä¸€æ¬?
if (processedCount % 10 === 0 || processedCount === literatures.length) {
await prisma.aslScreeningTask.update({ ... });
}
// 修改å<C2B9>Žï¼šæ¯?æ<>¡æ›´æ–°ä¸€æ¬?
await prisma.aslScreeningTask.update({
where: { id: taskId },
data: {
processedItems: processedCount,
successItems: successCount,
conflictItems: conflictCount,
failedItems: processedCount - successCount,
},
});
效果�
- âœ?æ¯<C3A6>处ç<E2809E>†å®Œ1篇文献,立å<E280B9>³æ›´æ–°æ•°æ<C2B0>®åº?
- âœ?å‰<C3A5>端æ¯?秒轮询一æ¬?
- �用户能看到平滑的进度增长
2. æ·»åŠ æ¨¡åž‹å¤„ç<E2809E>†æ•°é‡<C3A9>显示 â?
需�
在进度æ<EFBFBD>¡ä¸‹æ–¹æ˜¾ç¤ºï¼?
- DeepSeek 处ç<E2809E>†äº†å‡ ç¯?
- Qwen-Max 处ç<E2809E>†äº†å‡ ç¯?
实现
å‰<EFBFBD>端 (ScreeningWorkbench.tsx):
{task && (
<>
<div className="text-sm text-gray-500 mt-2">
已处ç<EFBFBD>? {task.processedItems} / {task.totalItems} ç¯?·
æˆ<EFBFBD>功: {task.successItems} ·
冲çª<EFBFBD>: {task.conflictItems} ·
失败: {task.failedItems}
</div>
<div className="text-xs text-gray-400 mt-1">
<Tag color="blue" className="text-xs">DeepSeek-V3</Tag>
已处ç<EFBFBD>?{task.processedItems} ç¯?·
<Tag color="purple" className="text-xs">Qwen-Max</Tag>
已处ç<EFBFBD>?{task.processedItems} ç¯?
</div>
</>
)}
显示效果�
已处ç<EFBFBD>? 3 / 5 ç¯?· æˆ<C3A6>功: 3 · 冲çª<C3A7>: 1 · 失败: 0
[DeepSeek-V3] 已处ç<E2809E>?3 ç¯?· [Qwen-Max] 已处ç<E2809E>?3 ç¯?
说明�
- å<EFBFBD>Œæ¨¡åž‹æ˜¯å¹¶è¡Œå¤„ç<EFBFBD>†ï¼Œæ‰€ä»¥ä¸¤ä¸ªæ¨¡åž‹çš„处ç<EFBFBD>†æ•°é‡<EFBFBD>始终相å<EFBFBD>Œ
- 使用ä¸<EFBFBD>å<EFBFBD>Œé¢œè‰²çš„Tag区分模型(è“<EFBFBD>è‰?紫色ï¼?
3. ä¿®å¤<C3A5>列表显示顺åº<C3A5> â?
问题
- Excel顺åº<EFBFBD>:aã€<EFBFBD>bã€<EFBFBD>cã€<EFBFBD>d
- 设置与å<EFBFBD>¯åŠ¨é¢„è§ˆï¼šaã€<EFBFBD>bã€<EFBFBD>cã€<EFBFBD>d âœ?
- å®¡æ ¸å·¥ä½œå<EFBFBD>°æ˜¾ç¤ºï¼šdã€<EFBFBD>cã€<EFBFBD>bã€<EFBFBD>a â<>?*å<EFBFBD><EFBFBD>了ï¼?
原å›
å<EFBFBD>Žç«¯æŸ¥è¯¢ä½¿ç”¨äº?orderBy: { createdAt: 'desc' }(é™<EFBFBD>åº<EFBFBD>),导致最新创建的排在å‰<EFBFBD>é<EFBFBD>¢ã€?
由于文献是按Excel顺åº<EFBFBD>ä¾<EFBFBD>次导入的:
a(最早创建) �b �c �d(最晚创建)
é™<EFBFBD>åº<EFBFBD>排列å<EFBFBD>Žï¼š
d(最晚创建,排第1ï¼?â†?c â†?b â†?a(最早创建,排最å<E282AC>Žï¼‰
解决方案
å<EFBFBD>Žç«¯ (screeningController.ts):
// 修改�
orderBy: [
{ conflictStatus: 'desc' },
{ createdAt: 'desc' }, // â<>?é™<C3A9>åº<C3A5>,最新的在å‰<C3A5>
]
// 修改å<C2B9>?
orderBy: [
{ conflictStatus: 'desc' }, // ä¿<C3A4>æŒ<C3A6>冲çª<C3A7>的排å‰<C3A5>é<EFBFBD>¢
{ createdAt: 'asc' }, // âœ?å<>‡åº<C3A5>,ä¿<C3A4>æŒ<C3A6>Excel原始顺åº<C3A5>
]
**排åº<C3A5>逻辑**ï¼?
- **优先çº?**:冲çª<C3A7>状æ€<C3A6>(conflict > noneï¼?
- 有冲çª<EFBFBD>的文献排在å‰<EFBFBD>é<EFBFBD>¢
- 方便用户优先处ç<EFBFBD>†å†²çª<EFBFBD>
- **优先çº?**:创建时间(å<CB86>‡åº<C3A5>ï¼?
- ä¿<EFBFBD>æŒ<EFBFBD>Excel原始顺åº<EFBFBD>
- 符å<EFBFBD>ˆç”¨æˆ·é¢„期
效果�
å®¡æ ¸å·¥ä½œå<EFBFBD>°æ˜¾ç¤ºï¼šaã€<EFBFBD>bã€<EFBFBD>cã€<EFBFBD>d âœ?
(如果c有冲çª<C3A7>:cã€<C3A3>aã€<C3A3>bã€<C3A3>dï¼?
📊 优化效果对比
进度显示
| æ–¹é<EFBFBD>¢ | 优化å‰? | 优化å<EFBFBD>? |
|---|---|---|
| 轮询间隔 | 2� | 1� |
| å<EFBFBD>Žç«¯æ›´æ–° | æ¯?0æ<30>? | æ¯?æ<>? |
| 用户体验 | 0% â†?ç‰å¾… â†?100% | 0% â†?20% â†?40% â†?60% â†?80% â†?100% |
| 模型信æ<EFBFBD>¯ | æ—? | 显示DeepSeekå’ŒQwen处ç<EFBFBD>†æ•? |
列表顺åº<EFBFBD>
| 场景 | 优化å‰? | 优化å<EFBFBD>? |
|---|---|---|
| Excel顺åº<EFBFBD> | a, b, c, d | a, b, c, d |
| 预览顺åº<EFBFBD> | a, b, c, d | a, b, c, d |
| å®¡æ ¸å·¥ä½œå<EFBFBD>? | d, c, b, a â<>? | a, b, c, d âœ? |
🔧 修改文件清å<E280A6>•
å‰<EFBFBD>端
-
�
frontend-v2/src/modules/asl/hooks/useScreeningTask.ts- 轮询间隔���1�
-
�
frontend-v2/src/modules/asl/pages/ScreeningWorkbench.tsx- æ·»åŠ æ¨¡åž‹å¤„ç<EFBFBD>†æ•°é‡<EFBFBD>显示
å<EFBFBD>Žç«¯
-
�
backend/src/modules/asl/services/screeningService.ts- 进度更新:æ¯<EFBFBD>10æ<EFBFBD>?â†?æ¯?æ<>?
-
�
backend/src/modules/asl/controllers/screeningController.ts- 排åº<EFBFBD>:
createdAt: 'desc'�createdAt: 'asc'
- 排åº<EFBFBD>:
🧪 测试验è¯<C3A8>
测试场景
- ä¸Šä¼ 5篇文çŒ?
- 点击"开始AIåˆ<C3A5>ç›"
- è§‚å¯Ÿå®¡æ ¸å·¥ä½œå<EFBFBD>?
预期效果
1. 进度显示
åˆ<EFBFBD>å§‹: 0%
10ç§’å<E28099>Ž: 20% â†?âœ?能看到进度ï¼<C3AF>
20ç§’å<E28099>Ž: 40%
30ç§’å<E28099>Ž: 60%
40ç§’å<E28099>Ž: 80%
50ç§’å<E28099>Ž: 100%
底部显示:
已处ç<E2809E>? 3 / 5 ç¯?· æˆ<C3A6>功: 3 · 冲çª<C3A7>: 1 · 失败: 0
[DeepSeek-V3] 已处ç<E2809E>?3 ç¯?· [Qwen-Max] 已处ç<E2809E>?3 ç¯?
2. 列表顺åº<C3A5>
Excel: 文献A, 文献B, 文献C, 文献D, 文献E
å®¡æ ¸å·¥ä½œå<C593>? 文献A, 文献B, 文献C, 文献D, 文献E âœ?
(如果文献C有冲çª<C3A7>)
å®¡æ ¸å·¥ä½œå<C593>? 文献C, 文献A, 文献B, 文献D, 文献E âœ?
💡 技术细�
为什么æ¯<EFBFBD>1æ<EFBFBD>¡å°±æ›´æ–°ï¼?
**æ<>ƒè¡¡**ï¼?
- 优点:实时å<EFBFBD><EFBFBD>馈,用户体验å¥?
- 缺点:数æ<EFBFBD>®åº“写入频ç¹<EFBFBD>
- **评估**:对于少é‡<C3A9>文献(5-200篇),数æ<C2B0>®åº“压力å<E280BA>¯æŽ¥å<C2A5>?
**如果文献数é‡<C3A9>很大**ï¼?000+篇),å<C592>¯ä»¥ä¼˜åŒ–为ï¼?
// 动æ€<C3A6>调整更新频çŽ?
const updateInterval = literatures.length > 500 ? 10 : 1;
if (processedCount % updateInterval === 0 || processedCount === literatures.length) {
await prisma.aslScreeningTask.update({ ... });
}
为什么轮询间隔是1秒?
**æ<>ƒè¡¡**ï¼?
- 优点:å<EFBFBD>Šæ—¶æ›´æ–°ï¼Œå»¶è¿Ÿå°?
- 缺点:API调用频ç¹<EFBFBD>
- **评估**�
- æ¯<EFBFBD>次API调用耗时 < 100ms
- ç›é€‰è¿‡ç¨‹æŒ<EFBFBD>ç»æ—¶é—´ï¼š1-30分钟
- API调用次数ï¼?0-1800次(å<CB86>¯æŽ¥å<C2A5>—)
**如果需è¦<C3A8>优åŒ?*,å<C592>¯ä»¥ä½¿ç”?WebSocket 实时推é€<C3A9>:
// 未æ<C2AA>¥ä¼˜åŒ–方案
socket.on('screening-progress', (data) => {
setProgress(data.progress);
});
ðŸ“<EFBFBD> 关于æµ<C3A6>览器è¦å‘?
è¦å‘Šä¿¡æ<EFBFBD>¯
[Violation]'setTimeout' handler took 72ms
[Violation]'setTimeout' handler took 269ms
说明
- 这是Chrome性能æ<EFBFBD><EFBFBD>示,ä¸<EFBFBD>是错è¯?
- 表示æŸ<EFBFBD>个setTimeout处ç<EFBFBD>†å‡½æ•°æ‰§è¡Œæ—¶é—´è¾ƒé•¿
- 通常由React大é‡<EFBFBD>DOM更新引起
是å<EFBFBD>¦éœ€è¦<EFBFBD>优化?
çŸæœŸï¼šä¸<EFBFBD>需è¦?
- ä¸<EFBFBD>å½±å“<EFBFBD>功èƒ?
- 用户体验æ£å¸¸
- 处ç<EFBFBD>†æ—¶é—´åœ¨å<EFBFBD>¯æŽ¥å<EFBFBD>—范围内(< 300msï¼?
长期:å<EFBFBD>¯ä»¥ä¼˜åŒ?
- 使用
React.memoå‡<C3A5>å°‘é‡<C3A9>渲æŸ? - 使用虚拟列表(如果文献很多)
- 优化大型组件的渲染逻辑
🎯 å<>Žç»ä¼˜åŒ–建议
çŸæœŸï¼ˆå<EFBFBD>¯é€‰ï¼‰
- æ·»åŠ "æš‚å<E2809A>œ"按钮(暂å<E2809A>œç›é€‰ä»»åŠ¡ï¼‰
- æ·»åŠ "估计剩余时间"(基于已处ç<E2809E>†é€Ÿåº¦ï¼?
- 显示当å‰<EFBFBD>æ£åœ¨å¤„ç<EFBFBD>†çš„æ–‡çŒ®æ ‡é¢?
䏿œŸ
- 使用WebSocket替代轮询(实时推é€<EFBFBD>)
- æ·»åŠ æ‰¹é‡<EFBFBD>é‡<EFBFBD>试失败文献功能
- 支æŒ<EFBFBD>任务å<EFBFBD>–消
长期
- 分布å¼<EFBFBD>处ç<EFBFBD>†ï¼ˆå¤šä¸ªworker并行ï¼?
- æ–点ç»ä¼ ï¼ˆä»»åŠ¡ä¸æ–å<EFBFBD>Žå<EFBFBD>¯æ<EFBFBD>¢å¤<EFBFBD>)
- 性能监控和分�
📊 性能数æ<C2B0>®
优化å‰<EFBFBD>å<EFBFBD>Žå¯¹æ¯”ï¼?篇文献)
| æŒ‡æ ‡ | 优化å‰? | 优化å<EFBFBD>? | 改善 |
|---|---|---|---|
| 进度å<EFBFBD>¯è§<EFBFBD>æ€? | 0% â†?100% | 0â†?0â†?0â†?0â†?0â†?00% | âœ?5å€<C3A5>æ<EFBFBD><C3A6>å<EFBFBD>? |
| å<EFBFBD><EFBFBD>馈延迟 | ~20ç§? | ~1ç§? | âœ?20å€<C3A5>æ<EFBFBD><C3A6>å<EFBFBD>? |
| 列表顺åº<EFBFBD> | å<EFBFBD><EFBFBD>å<EFBFBD>‘ | æ£ç¡® | âœ?ä¿®å¤<C3A5> |
| ä¿¡æ<EFBFBD>¯å®Œæ•´æ€? | 基本 | 详细(å<EFBFBD>«æ¨¡åž‹æ•°ï¼‰ | âœ?æ<><C3A6>å<EFBFBD>‡ |
**报告�*: AI Assistant
日期: 2025-11-21
版本: v1.0.0