feat(frontend): 搭建桌面端基础界面与 Workspace

- App Shell 壳层:主导航、次导航、Title Bar、状态栏
- Vault 入口页:最近 Vault、打开/创建 Vault、AI Core 状态
- Workspace 与文件树:浏览、打开、创建笔记/文件夹
- Design Token:浅色/深色主题 CSS Variables
- Contracts / Service / Store / Router 基础架构
- 统一 ApiClient 与 SseClient,对接后端 API 契约
This commit is contained in:
2026-08-29 10:36:16 +08:00
parent 694c1b27c1
commit f9efc4f4a2
42 changed files with 8044 additions and 167 deletions
+93
View File
@@ -0,0 +1,93 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
import type { AiCoreStatus, IndexStatus } from '@/contracts'
import { mockIndexStatus } from '@/services/indexService'
export const useSettingsStore = defineStore('settings', () => {
// General
const restoreLastVault = ref(true)
const autoSaveInterval = ref(1500)
const language = ref<'zh-CN' | 'en'>('zh-CN')
const appVersion = ref('0.1.0')
const aiCoreVersion = ref('0.1.0')
// Editor
const defaultEditorMode = ref<'wysiwyg' | 'source'>('wysiwyg')
const editorFontSize = ref(15)
const editorLineHeight = ref(1.7)
const editorLineWidth = ref(80)
const spellCheck = ref(false)
// AI Core
const aiCoreStatus = ref<AiCoreStatus>('running')
const aiCoreAddress = ref('http://127.0.0.1:8000')
// Index
const indexStatus = ref<IndexStatus>(mockIndexStatus)
// Permissions
const permissionPolicy = ref<Record<string, 'allow' | 'confirm' | 'deny'>>({
'notes.read': 'allow',
'notes.search': 'allow',
'notes.write': 'confirm',
'notes.delete': 'confirm',
'tasks.read': 'allow',
'tasks.write': 'confirm',
'attachments.read': 'confirm',
'network.request': 'confirm',
'secrets.use': 'confirm',
})
function setAutoSaveInterval(ms: number) {
autoSaveInterval.value = ms
}
function setDefaultEditorMode(mode: 'wysiwyg' | 'source') {
defaultEditorMode.value = mode
}
function setPermission(permission: string, policy: 'allow' | 'confirm' | 'deny') {
permissionPolicy.value[permission] = policy
}
function setAiCoreStatus(status: AiCoreStatus) {
aiCoreStatus.value = status
}
async function restartAiCore(): Promise<boolean> {
aiCoreStatus.value = 'starting'
await new Promise((r) => setTimeout(r, 1500))
aiCoreStatus.value = 'running'
return true
}
async function rebuildIndex(scope: 'full' | 'fts' | 'vector' = 'full') {
indexStatus.value.status = 'indexing'
setTimeout(() => {
indexStatus.value.status = 'idle'
}, 3000)
}
return {
restoreLastVault,
autoSaveInterval,
language,
appVersion,
aiCoreVersion,
defaultEditorMode,
editorFontSize,
editorLineHeight,
editorLineWidth,
spellCheck,
aiCoreStatus,
aiCoreAddress,
indexStatus,
permissionPolicy,
setAutoSaveInterval,
setDefaultEditorMode,
setPermission,
setAiCoreStatus,
restartAiCore,
rebuildIndex,
}
})