Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Pangea-Agent
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
2
Merge Requests
2
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Gavin-Group
Pangea-Agent
Commits
8bcd41e5
Commit
8bcd41e5
authored
Dec 22, 2025
by
ligaowei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Push all changes to Git server
parent
ae753c87
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
127 additions
and
106 deletions
+127
-106
TimelineContainer.vue
frontend/src/components/TimelineContainer.vue
+3
-3
WorkArea.vue
frontend/src/components/WorkArea.vue
+3
-3
README.md
frontend/src/services/README.md
+0
-85
TimelineService.ts
frontend/src/services/TimelineService.ts
+121
-15
No files found.
frontend/src/components/TimelineContainer.vue
View file @
8bcd41e5
...
...
@@ -17,7 +17,7 @@ import { ref, onUnmounted, onMounted } from 'vue'
import
type
{
TimelineEvent
,
ToolResultEvent
}
from
'../types/timeline'
import
{
eventTypeLabels
}
from
'../types/timeline'
import
{
SimplifiedTimelineService
}
from
'../services/Simplified
TimelineService'
import
{
TimelineService
}
from
'../services/
TimelineService'
import
TimelinePanel
from
'./TimelinePanel.vue'
// 事件数据
...
...
@@ -65,7 +65,7 @@ const hasValidToolOutput = (event: TimelineEvent): boolean => {
};
// 时间轴服务不再需要,因为我们现在直接处理事件
// const
simplifiedTimelineService = new Simplified
TimelineService((event: TimelineEvent) => {
// const
timelineService = new
TimelineService((event: TimelineEvent) => {
// // 添加事件到列表
// events.value.push(event);
// console.log('[TimelineContainer] 成功添加事件:', event.type, event.title);
...
...
@@ -81,7 +81,7 @@ const addEvent = (event: any) => {
// 清除时间轴
const
handleClearTimeline
=
()
=>
{
events
.
value
=
[];
// 不再调用
simplifiedT
imelineService.clearTimeline(),因为它是空实现
// 不再调用
t
imelineService.clearTimeline(),因为它是空实现
// stateManager.clearAllStates();
// cacheService.clearAllCaches();
};
...
...
frontend/src/components/WorkArea.vue
View file @
8bcd41e5
...
...
@@ -15,12 +15,12 @@
import
{
ref
,
onMounted
,
onUnmounted
}
from
'vue'
import
TimelineContainer
from
'./TimelineContainer.vue'
import
WebpageBrowser
from
'./WebpageBrowser.vue'
import
{
SimplifiedTimelineService
}
from
'../services/Simplified
TimelineService'
import
{
TimelineService
}
from
'../services/
TimelineService'
const
activeTab
=
ref
(
'timeline'
)
const
timelineContainerRef
=
ref
<
InstanceType
<
typeof
TimelineContainer
>
|
null
>
(
null
)
const
webBrowser
=
ref
()
let
timelineService
:
Simplified
TimelineService
|
null
=
null
let
timelineService
:
TimelineService
|
null
=
null
// 添加事件到时间轴
const
addEvent
=
(
event
:
any
):
void
=>
{
...
...
@@ -30,7 +30,7 @@ const addEvent = (event: any): void => {
// 初始化Timeline服务
const
initTimelineService
=
()
=>
{
if
(
timelineContainerRef
.
value
)
{
timelineService
=
new
Simplified
TimelineService
((
event
:
any
)
=>
{
timelineService
=
new
TimelineService
((
event
:
any
)
=>
{
addEvent
(
event
)
})
timelineService
.
connectSSE
()
...
...
frontend/src/services/README.md
deleted
100644 → 0
View file @
ae753c87
# 前端服务层优化说明
## 概述
本文档介绍了前端服务层的一系列优化措施,旨在提高代码质量、可维护性和性能。
## 优化内容
### 1. 统一类型定义
-
**文件**
:
`types/timeline.ts`
-
**功能**
: 统一定义了所有时间轴相关的事件类型和标签映射
-
**优势**
: 避免类型重复定义,提高类型安全性
### 2. 工具函数库
-
**文件**
:
`utils/timelineUtils.ts`
-
**功能**
: 包含时间轴相关的工具函数,如事件类型判断、输入输出验证等
-
**优势**
: 集中管理工具函数,避免重复实现
### 3. 类型守卫函数
-
**文件**
:
`utils/typeGuards.ts`
-
**功能**
: 提供类型守卫函数,用于精确的类型检查
-
**优势**
: 提高类型安全性,减少运行时错误
### 4. 事件去重服务
-
**文件**
:
`services/EventDeduplicationService.ts`
-
**功能**
: 统一处理事件去重逻辑
-
**优势**
: 避免重复事件处理,节省资源
### 5. 对象池服务
-
**文件**
:
`services/ObjectPoolService.ts`
-
**功能**
: 提供通用的对象池实现
-
**优势**
: 减少对象创建和垃圾回收压力,提高性能
### 6. 优化的事件处理服务
-
**文件**
:
`services/OptimizedEventProcessingService.ts`
-
**功能**
: 使用对象池优化事件对象的创建和管理
-
**优势**
: 提高性能,减少内存分配
### 7. 统一事件处理器
-
**文件**
:
`services/UnifiedEventProcessor.ts`
-
**功能**
: 整合所有事件处理逻辑
-
**优势**
: 统一事件处理流程,便于维护
## 使用方法
### 1. 类型和工具函数使用
```
typescript
import
type
{
TimelineEvent
}
from
'../types/timeline'
;
import
{
isToolEventType
,
hasValidToolInput
}
from
'../utils/timelineUtils'
;
import
{
isThoughtEvent
}
from
'../utils/typeGuards'
;
```
### 2. 事件处理服务使用
```
typescript
import
{
UnifiedEventProcessor
}
from
'../services/UnifiedEventProcessor'
;
const
eventProcessor
=
new
UnifiedEventProcessor
();
eventProcessor
.
registerHandler
((
event
:
TimelineEvent
)
=>
{
// 处理事件
});
```
### 3. 性能监控
在TimelineContainer组件中提供了性能监控功能:
```
typescript
// 显示性能统计信息
showPerformanceStats
();
// 定期输出性能统计(每30秒)
// 在控制台查看: [TimelineContainer] 定期性能统计
```
## 性能优化效果
通过对象池和事件去重等优化措施,预期可以获得以下性能提升:
1.
减少对象创建次数,降低垃圾回收压力
2.
避免重复事件处理,节省CPU资源
3.
提高事件处理速度,改善用户体验
## 维护建议
1.
定期查看性能监控数据,评估优化效果
2.
新增事件类型时,需在
`types/timeline.ts`
中定义相应类型
3.
新增工具函数时,应添加到
`utils/timelineUtils.ts`
中
4.
保持服务层的单一职责原则,避免功能交叉
\ No newline at end of file
frontend/src/services/
Simplified
TimelineService.ts
→
frontend/src/services/TimelineService.ts
View file @
8bcd41e5
...
...
@@ -2,7 +2,7 @@
* Timeline服务类
* 整合了SSE管理功能,减少服务层级
*/
export
class
Simplified
TimelineService
{
export
class
TimelineService
{
private
eventSource
:
EventSource
|
null
=
null
;
private
retryCount
=
0
;
private
maxRetries
=
5
;
...
...
@@ -26,23 +26,16 @@ export class SimplifiedTimelineService {
// 从localStorage获取token
const
token
=
localStorage
.
getItem
(
'token'
);
// 创建一个包含token的URL对象
const
url
=
new
URL
(
eventSourceUrl
,
window
.
location
.
origin
);
// 使用请求头而不是URL参数传递token
if
(
token
)
{
url
.
searchParams
.
append
(
'token'
,
token
);
}
eventSourceUrl
=
url
.
toString
().
replace
(
window
.
location
.
origin
,
''
);
// 如果是相对路径,确保以/开头
if
(
!
eventSourceUrl
.
startsWith
(
'/'
))
{
eventSourceUrl
=
'/'
+
eventSourceUrl
;
// 创建自定义的EventSource实现,支持添加请求头
const
eventSource
=
new
EventSourceWithAuth
(
eventSourceUrl
,
token
);
this
.
eventSource
=
eventSource
as
unknown
as
EventSource
;
}
else
{
// 如果没有token,仍然使用标准EventSource
this
.
eventSource
=
new
EventSource
(
eventSourceUrl
);
}
console
.
log
(
'[TimelinePanel] 尝试连接SSE:'
,
eventSourceUrl
);
// 建立连接
this
.
eventSource
=
new
EventSource
(
eventSourceUrl
);
this
.
eventSource
.
onmessage
=
this
.
handleMessage
.
bind
(
this
);
this
.
eventSource
.
onerror
=
this
.
handleError
.
bind
(
this
);
this
.
eventSource
.
onopen
=
this
.
handleOpen
.
bind
(
this
);
...
...
@@ -301,3 +294,116 @@ export class SimplifiedTimelineService {
return
event
.
type
===
'tool_result'
&&
event
.
toolOutput
!==
null
&&
event
.
toolOutput
!==
undefined
;
}
}
// 自定义EventSource实现,支持添加Authorization请求头
class
EventSourceWithAuth
extends
EventTarget
{
private
xhr
:
XMLHttpRequest
|
null
=
null
;
private
timeoutId
:
number
|
null
=
null
;
private
_readyState
:
number
;
private
_url
:
string
;
private
_token
:
string
;
static
readonly
CONNECTING
=
0
;
static
readonly
OPEN
=
1
;
static
readonly
CLOSED
=
2
;
constructor
(
url
:
string
,
token
:
string
)
{
super
();
this
.
_url
=
url
;
this
.
_token
=
token
;
this
.
_readyState
=
EventSourceWithAuth
.
CONNECTING
;
this
.
connect
();
}
private
connect
()
{
if
(
this
.
xhr
)
{
this
.
xhr
.
abort
();
}
this
.
xhr
=
new
XMLHttpRequest
();
this
.
xhr
.
open
(
'GET'
,
this
.
_url
,
true
);
this
.
xhr
.
setRequestHeader
(
'Accept'
,
'text/event-stream'
);
this
.
xhr
.
setRequestHeader
(
'Cache-Control'
,
'no-cache'
);
this
.
xhr
.
setRequestHeader
(
'Authorization'
,
`Bearer
${
this
.
_token
}
`
);
this
.
xhr
.
withCredentials
=
true
;
this
.
xhr
.
onreadystatechange
=
()
=>
{
if
(
this
.
xhr
?.
readyState
===
XMLHttpRequest
.
HEADERS_RECEIVED
)
{
if
(
this
.
xhr
.
status
===
200
)
{
this
.
_readyState
=
EventSourceWithAuth
.
OPEN
;
this
.
dispatchEvent
(
new
Event
(
'open'
));
}
else
{
this
.
handleError
();
}
}
};
this
.
xhr
.
onprogress
=
()
=>
{
if
(
this
.
xhr
)
{
const
lines
=
this
.
xhr
.
responseText
.
split
(
'
\
n'
);
for
(
const
line
of
lines
)
{
if
(
line
.
startsWith
(
'data: '
))
{
const
data
=
line
.
slice
(
6
);
const
event
=
new
MessageEvent
(
'message'
,
{
data
});
this
.
dispatchEvent
(
event
);
}
}
}
};
this
.
xhr
.
onload
=
()
=>
{
this
.
_readyState
=
EventSourceWithAuth
.
CLOSED
;
this
.
dispatchEvent
(
new
Event
(
'close'
));
};
this
.
xhr
.
onerror
=
()
=>
{
this
.
handleError
();
};
this
.
xhr
.
send
();
// 每30秒重新连接一次,保持连接活跃
this
.
timeoutId
=
window
.
setTimeout
(()
=>
{
this
.
reconnect
();
},
30000
);
}
private
handleError
()
{
this
.
_readyState
=
EventSourceWithAuth
.
CLOSED
;
if
(
this
.
timeoutId
)
{
clearTimeout
(
this
.
timeoutId
);
}
this
.
dispatchEvent
(
new
Event
(
'error'
));
// 尝试重新连接
setTimeout
(()
=>
this
.
reconnect
(),
3000
);
}
private
reconnect
()
{
if
(
this
.
_readyState
!==
EventSourceWithAuth
.
CLOSED
)
{
this
.
connect
();
}
}
close
()
{
this
.
_readyState
=
EventSourceWithAuth
.
CLOSED
;
if
(
this
.
xhr
)
{
this
.
xhr
.
abort
();
}
if
(
this
.
timeoutId
)
{
clearTimeout
(
this
.
timeoutId
);
}
this
.
dispatchEvent
(
new
Event
(
'close'
));
}
get
readyState
()
{
return
this
.
_readyState
;
}
get
url
()
{
return
this
.
_url
;
}
get
withCredentials
()
{
return
false
;
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment