119 lines
4.2 KiB
Markdown
119 lines
4.2 KiB
Markdown
# 智能体广场跳转后 listChatSessions 传参 agentId
|
||
|
||
- **日期**: 2026-08-04
|
||
- **状态**: 已批准,待实施
|
||
|
||
## 背景
|
||
|
||
从智能体广场(`marketplace.vue`)点击智能体进入前端聊天页面(`Frontend/index.vue`)时,路由携带 `query.agentId`。当前页面已读取该值并在 WebSocket 发送消息时回传,但会话侧边栏调用 `listChatSessions()` 获取会话列表时未携带 `agentId`,导致列表不能按智能体过滤。
|
||
|
||
## 目标
|
||
|
||
从智能体广场跳转进入前端页面后,会话侧边栏调用 `listChatSessions()` 时附带 `agentId` 作为查询参数,后端据此只返回该智能体下的会话。其他入口(无 `agentId`)行为不变。
|
||
|
||
## 非目标
|
||
|
||
- 不修改 `marketplace.vue` 现有跳转逻辑
|
||
- 不修改 WebSocket 消息体(`agentId` 已附带,不在范围内)
|
||
- 不修改其他 list API(`listLlmModels`、`listAgentProjects` 等)
|
||
- 不引入状态管理库(Pinia 等)
|
||
|
||
## 设计
|
||
|
||
### 1. API 层 `src/api/frontend/index.js`
|
||
|
||
`listChatSessions` 改为接收可选 `agentId`,作为 GET 查询参数:
|
||
|
||
```js
|
||
export function listChatSessions(agentId) {
|
||
return chatRequest({
|
||
url: '/llm/chatSession/list',
|
||
method: 'get',
|
||
params: agentId ? { agentId: Number(agentId) } : {}
|
||
})
|
||
}
|
||
```
|
||
|
||
- 不传或传 `null`/`undefined`/空字符串时,`params` 为空对象,行为与现状完全一致
|
||
- `agentId` 通过 `Number()` 转为数字,与 WebSocket 发送处的转换(`messageData.agentId = Number(agentId.value)`)保持一致
|
||
|
||
### 2. 父组件 `src/views/frontend/index.vue`
|
||
|
||
模板中已存在 `<ConversationSidebar ref="conversationSidebarRef" ... />`,新增 `:agent-id` 绑定:
|
||
|
||
```vue
|
||
<ConversationSidebar
|
||
ref="conversationSidebarRef"
|
||
:agent-id="agentId"
|
||
@select="handleConversationSelect"
|
||
@new-session="handleNewSession"
|
||
@ready="switchingConversation = false"
|
||
/>
|
||
```
|
||
|
||
`agentId` ref(第 162 行)已存在,由 `route.query.agentId` 赋值,无需新增状态。
|
||
|
||
### 3. 子组件 `src/views/frontend/components/ConversationSidebar.vue`
|
||
|
||
- 新增 prop 定义:
|
||
|
||
```js
|
||
const props = defineProps({
|
||
agentId: { type: [String, Number], default: null }
|
||
})
|
||
```
|
||
|
||
- 第 131 行 `fetchSessions`:
|
||
```js
|
||
const res = await listChatSessions(props.agentId)
|
||
```
|
||
- 第 207 行 `refreshQuiet`:
|
||
```js
|
||
const res = await listChatSessions(props.agentId)
|
||
```
|
||
|
||
由于 `props.agentId` 是响应式的,直接读取即可拿到最新值,无需 `watch`。
|
||
|
||
## 数据流
|
||
|
||
```
|
||
marketplace.vue (handleAgentClick)
|
||
└─ router.push({ name: 'Frontend', query: { agentId, name } })
|
||
└─ index.vue (onMounted: agentId.value = route.query.agentId)
|
||
└─ <ConversationSidebar :agent-id="agentId" />
|
||
└─ fetchSessions() / refreshQuiet()
|
||
└─ listChatSessions(props.agentId)
|
||
└─ GET /llm/chatSession/list?agentId=<id>
|
||
```
|
||
|
||
## 边界与错误处理
|
||
|
||
| 输入 | 行为 |
|
||
|---|---|
|
||
| `agentId` 未提供 | 不带 `agentId` 参数,返回全部会话 |
|
||
| `agentId = ''` 或 `null` | 同上 |
|
||
| `agentId = '123'`(字符串) | `Number('123') = 123`,作为查询参数 |
|
||
| `agentId = 0` 或无效数字 | 后端按 `0` 处理,与现状一致 |
|
||
|
||
不引入额外的错误处理;网络错误沿用现有的 `console.error` 与 UI 行为。
|
||
|
||
## 验证
|
||
|
||
1. **从智能体广场跳转**:
|
||
- 进入智能体 A → 侧边栏只显示智能体 A 的会话
|
||
- 返回广场,进入智能体 B → 侧边栏只显示智能体 B 的会话
|
||
2. **直接进入 `/frontend`**(无 query):侧边栏显示全部会话,行为与现状一致
|
||
3. **新建会话后**:通过 `refreshQuiet` 刷新时仍按当前 `agentId` 过滤
|
||
4. **删除/重命名会话**:调用 `deleteChatSession`/`renameChatSession`,刷新后列表仍正确过滤
|
||
|
||
## 涉及文件
|
||
|
||
| 文件 | 变更类型 |
|
||
|---|---|
|
||
| `src/api/frontend/index.js` | 修改 `listChatSessions` 签名 |
|
||
| `src/views/frontend/index.vue` | 模板新增 `:agent-id` 绑定 |
|
||
| `src/views/frontend/components/ConversationSidebar.vue` | 新增 prop;两处 `listChatSessions` 调用透传参数 |
|
||
|
||
## 实施依赖
|
||
|
||
无新增依赖。沿用现有 axios、`vue-router`、`@element-plus`。 |