chore(frontend): 补充状态与服务边界注释

This commit is contained in:
2026-08-30 22:59:58 +08:00
parent 629a6bda9c
commit 49c856a69c
11 changed files with 31 additions and 2 deletions
+2
View File
@@ -53,6 +53,7 @@ export const useAgentStore = defineStore('agent', () => {
}
function processEvent(event: AgentEvent) {
// 服务端会先回放历史再发送实时事件,以 run_id + sequence 去重保证幂等。
if (events.value.some((item) => item.run_id === event.run_id && item.sequence === event.sequence)) return
events.value.push(event)
events.value.sort((a, b) => a.sequence - b.sequence)
@@ -100,6 +101,7 @@ export const useAgentStore = defineStore('agent', () => {
}
function subscribe(runId: string) {
// 任一时刻只保留当前运行的事件流,防止切换详情后旧事件污染新页面。
eventStream?.cancel()
isRunning.value = true
error.value = null
+3
View File
@@ -16,6 +16,8 @@ export const useChatStore = defineStore('chat', () => {
const selectedModel = ref('mock-1')
let sseClient: SseClient | null = null
// TODO(chat): 会话持久化接口完成后移除 mockConversations/mockMessages 数据源。
const activeConversation = computed(() =>
conversations.value.find((c) => c.conversation_id === activeConversationId.value) || null
)
@@ -56,6 +58,7 @@ export const useChatStore = defineStore('chat', () => {
inputText.value = ''
isStreaming.value = true
// 先插入占位消息,随后将 SSE 增量原位合并,避免每个 token 重建消息列表。
const aiMsg: ChatMessage = {
message_id: `msg-${Date.now() + 1}`,
conversation_id: conversationId,
+4
View File
@@ -47,6 +47,7 @@ export const useEditorStore = defineStore('editor', () => {
async function save() {
if (!currentFilePath.value) return
if (pendingSave) return pendingSave
// 保存路径与正文都取快照;请求完成时用户可能已继续输入或切换文件。
const targetPath = currentFilePath.value
const snapshot = content.value
saveStatus.value = 'saving'
@@ -82,6 +83,7 @@ export const useEditorStore = defineStore('editor', () => {
if (saveStatus.value === 'dirty' || saveStatus.value === 'save_failed') {
throw new Error('当前文件保存失败,已阻止切换以避免内容丢失。')
}
// 版本号使较慢的旧读取不能覆盖用户后选择的新文件。
const version = ++loadVersion
const previousStatus = saveStatus.value
saveStatus.value = 'saving'
@@ -117,6 +119,8 @@ export const useEditorStore = defineStore('editor', () => {
}
}
// TODO(editor): 桌面文件监听接入后提供冲突对比/合并界面,而非只阻止切换。
function closeFile() {
loadVersion++
if (saveTimer) clearTimeout(saveTimer)
+2
View File
@@ -49,6 +49,7 @@ export const useThemeStore = defineStore('theme', () => {
}
function initTheme() {
// 先恢复外观再开放 watch 持久化,避免 immediate watcher 覆盖本地设置。
const savedAppearance = localStorage.getItem('editor-appearance')
if (savedAppearance) {
try {
@@ -90,6 +91,7 @@ export const useThemeStore = defineStore('theme', () => {
}))
watch(resolvedCodeBlockTheme, (theme) => {
// CSS 与 Shiki 共用该属性,确保代码块背景和 token 配色始终成套切换。
document.documentElement.setAttribute('data-code-theme', theme)
}, { immediate: true })
+1
View File
@@ -118,6 +118,7 @@ export const useWorkspaceStore = defineStore('workspace', () => {
function renamePath(oldPath: string, newPath: string, newName: string) {
const node = findNodeByPath(fileTree.value, oldPath)
if (!node) return
// 文件夹重命名必须同步改写所有后代、标签页和当前文件路径。
const updateNodePath = (current: FileNode) => {
if (current.path === oldPath) current.name = newName
if (current.path === oldPath || current.path.startsWith(`${oldPath}/`)) {