sequenceDiagram participant Browser as 坐席浏览器 participant App as Vue3 App participant Store as Pinia Store participant API as Backend API participant DB as PostgreSQL Note over Browser,App: 页面加载 Browser->>App: 挂载 Workspace.vue App->>Store: 初始化 conversationStore Store->>API: GET /api/conversations API->>DB: SELECT * FROM conversations WHERE status IN ('queued','serving') ORDER BY ... DB-->>API: 会话列表 API-->>Store: 会话数据 Store-->>App: 渲染会话列表 loop 每3秒 setInterval App->>Store: pollConversations() Store->>API: GET /api/conversations?page=1&page_size=50 API->>DB: SELECT ... (同上) DB-->>API: 最新会话列表 API-->>Store: 最新数据 alt 数据有变化 Store->>Store: diff 比较,更新变化的会话 Store-->>App: 触发响应式更新 App->>App: 更新列表项标签/排序/未读数 else 数据无变化 Store-->>App: 无需更新 end end Note over App: 用户点击某个会话 App->>Store: selectConversation(id) Store->>API: GET /api/conversations/{id}/messages?limit=50 API->>DB: SELECT * FROM messages WHERE conversation_id=... ORDER BY created_at DB-->>API: 消息列表 API-->>Store: messages Store-->>App: 渲染对话区 loop 选中会话的消息轮询 App->>Store: pollMessages(conv_id) Store->>API: GET /api/conversations/{id}/messages?limit=20&before=latest_id API->>DB: SELECT ... WHERE created_at > latest DB-->>API: 新消息 API-->>Store: 新消息列表 alt 有新消息 Store->>Store: 追加消息到列表 Store-->>App: 滚动到底部,显示新消息 end end Note over App: 坐席发送回复 App->>Store: sendMessage(conv_id, content) Store->>API: POST /api/conversations/{id}/messages {content} API->>DB: INSERT INTO messages ... API-->>Store: 发送的消息对象 Store->>Store: 追加到消息列表 Store-->>App: 显示在对话区