Private
Public Access
1
0

新增:文件系统导航面包屑

功能:
- 新增 PathBreadcrumb 组件,支持路径快速跳转
- 新增 DropdownItem 通用下拉菜单组件

优化:
- 版本升级流程优化(Pinia 状态管理、进度节流、完整下载验证)
- 模块延迟初始化(数据库、文件系统按需启动)
- API 数据格式统一(蛇形转驼峰)
- CodeMirror 语言包按需动态加载
- Markdown 渲染增强(支持锚点跳转)

重构:
- 迁移到 Pinia 状态管理(stores/config.ts、stores/theme.ts、stores/update.ts)
- 简化 UpdatePanel、UpdateNotification、ThemeToggle 逻辑
- 优化表结构加载逻辑

清理:
- 删除测试组件 index-simple.vue
- 删除旧的 useTheme.ts
This commit is contained in:
2026-02-05 00:17:32 +08:00
parent ce2698f245
commit f7d648ea52
48 changed files with 3930 additions and 1380 deletions

View File

@@ -58,29 +58,30 @@
<!-- 设置抽屉 -->
<SettingsPanel
v-model="showSettings"
:config="appConfig"
:config="configStore.appConfig"
@save="handleSaveConfig"
/>
<!-- 升级提示弹窗 -->
<UpdateNotification
v-model="showUpdateNotification"
:update-info="updateInfo"
@install="handleUpdateInstall"
@skip="handleUpdateSkip"
v-model="updateStore.showUpdate"
:update-info="updateStore.updateInfo"
@install="updateStore.installUpdate"
/>
</a-layout>
</template>
<script setup>
import {computed, onMounted, ref, watch} from 'vue'
import {IconSettings} from '@arco-design/web-vue/es/icon'
import {Message} from '@arco-design/web-vue'
import { computed, watch, ref, onMounted, onUnmounted } from 'vue'
import { IconSettings } from '@arco-design/web-vue/es/icon'
import { Message } from '@arco-design/web-vue'
import DbCli from './views/db-cli/index.vue'
import ThemeToggle from './components/ThemeToggle.vue'
import FileSystem from './components/FileSystem/index.vue'
import SettingsPanel from './components/SettingsPanel.vue'
import UpdateNotification from './components/UpdateNotification.vue'
import { useUpdateStore } from './stores/update'
import { useConfigStore } from './stores/config'
// 存储键
const ACTIVE_TAB_STORAGE_KEY = 'app-active-tab'
@@ -91,124 +92,39 @@ const activeTab = ref((savedTab === 'user' ? 'file-system' : savedTab) || 'file-
const showSettings = ref(false)
const isMaximized = ref(false)
// 更新相关状态
const showUpdateNotification = ref(false)
const updateInfo = ref(null)
const checkedUpdate = ref(false)
// 使用 stores
const updateStore = useUpdateStore()
const configStore = useConfigStore()
// 应用配置
const appConfig = ref({
tabs: [],
visibleTabs: [],
defaultTab: 'file-system'
})
// 应用配置(从 store 获取)
const appConfig = computed(() => configStore.appConfig)
// 可见 Tabs根据配置动态生成
const visibleTabs = computed(() => {
if (!appConfig.value.tabs || appConfig.value.tabs.length === 0) {
// 默认配置
return [
{key: 'file-system', title: '文件管理'},
{key: 'db-cli', title: '数据库'}
]
}
return appConfig.value.tabs
.filter(tab => tab.visible)
.sort((a, b) => {
const aIndex = appConfig.value.visibleTabs.indexOf(a.key)
const bIndex = appConfig.value.visibleTabs.indexOf(b.key)
return aIndex - bIndex
})
})
// 加载配置
const loadConfig = async () => {
try {
// 检查 Wails 绑定是否准备好
if (!window.go || !window.go.main || !window.go.main.App) {
console.warn('Wails 绑定未准备好,等待重试...')
setTimeout(() => loadConfig(), 100)
return
}
const result = await window.go.main.App.GetAppConfig()
if (result.success) {
const tabs = result.data.tabs || []
const visibleTabs = result.data.visibleTabs || []
// 确保 tabs 数组中的 visible 属性与 visibleTabs 同步
const syncedTabs = tabs.map(tab => ({
...tab,
visible: visibleTabs.includes(tab.key)
}))
appConfig.value = {
tabs: syncedTabs,
visibleTabs: visibleTabs,
defaultTab: result.data.defaultTab || 'file-system'
}
// 设置默认 Tab
activeTab.value = appConfig.value.defaultTab
} else {
console.error('加载配置失败:', result.message)
// 使用默认配置
useDefaultConfig()
}
} catch (error) {
console.error('加载配置失败:', error)
// 使用默认配置
useDefaultConfig()
}
}
// 使用默认配置
const useDefaultConfig = () => {
appConfig.value = {
tabs: [
{key: 'file-system', title: '文件管理', visible: true, enabled: true},
{key: 'db-cli', title: '数据库', visible: true, enabled: true}
],
visibleTabs: ['file-system', 'db-cli'],
defaultTab: 'file-system'
}
}
// 可见 Tabs从 store 获取
const visibleTabs = computed(() => configStore.visibleTabs)
// 保存配置
const handleSaveConfig = async (config) => {
try {
const result = await window.go.main.App.SaveAppConfig({
tabs: config.tabs,
visibleTabs: config.visibleTabs,
defaultTab: config.defaultTab
})
await configStore.saveConfig(config)
showSettings.value = false
if (result.success) {
// 更新本地配置
appConfig.value = {
tabs: [...config.tabs],
visibleTabs: [...config.visibleTabs],
defaultTab: config.defaultTab
}
// 如果当前激活的 Tab 被隐藏,切换到默认 Tab
if (!config.visibleTabs.includes(activeTab.value)) {
activeTab.value = config.defaultTab
}
Message.success('配置保存成功')
showSettings.value = false
} else {
Message.error(result.message || '保存配置失败')
throw new Error(result.message)
// 如果当前激活的 Tab 被隐藏,切换到默认 Tab
if (!config.visibleTabs.includes(activeTab.value)) {
activeTab.value = config.defaultTab
}
} catch (error) {
// 错误已在 store 中处理
console.error('保存配置失败:', error)
throw error
}
}
// 加载配置(调用 store 方法)
const loadConfig = async () => {
await configStore.loadConfig()
// 设置默认 Tab
activeTab.value = configStore.defaultTab
}
// 获取组件
const getComponent = (key) => {
const components = {
@@ -218,75 +134,22 @@ const getComponent = (key) => {
return components[key] || null
}
// 检查更新
const checkForUpdates = async () => {
try {
// 等待 Wails 绑定准备好
if (!window.go || !window.go.main || !window.go.main.App) {
console.warn('Wails 绑定未准备好,延迟检查更新...')
setTimeout(() => checkForUpdates(), 1000)
return
}
// 获取更新配置
const configResult = await window.go.main.App.GetUpdateConfig()
if (!configResult.success) {
console.error('获取更新配置失败:', configResult.message)
return
}
const config = configResult.data
const shouldCheck = config.auto_check_enabled
if (!shouldCheck) {
console.log('自动更新检查已关闭')
return
}
console.log('[自动检查] 开始检查更新...')
// 检查更新
const result = await window.go.main.App.CheckUpdate()
if (result.success && result.data) {
checkedUpdate.value = true
// 检查是否已跳过此版本
const skippedVersion = localStorage.getItem('skipped_version')
if (result.data.has_update) {
// 如果是强制更新,或者未跳过此版本,则显示提示
if (result.data.force_update || skippedVersion !== result.data.latest_version) {
console.log('[自动检查] 发现新版本:', result.data.latest_version)
updateInfo.value = result.data
// 延迟显示,让用户先看到应用界面
setTimeout(() => {
showUpdateNotification.value = true
}, 2000)
} else {
console.log('[自动检查] 此版本已跳过')
}
} else {
console.log('[自动检查] 已是最新版本')
}
}
} catch (error) {
console.error('检查更新失败:', error)
}
}
// 组件挂载时加载配置和检查更新
// 组件挂载时加载配置
onMounted(() => {
loadConfig()
// 延迟检查更新,避免阻塞应用启动
// 设置更新事件监听
updateStore.setupEventListeners()
// 延迟检查更新(启动后 3 秒,静默模式)
setTimeout(() => {
if (!checkedUpdate.value) {
checkForUpdates()
}
updateStore.checkForUpdates(true)
}, 3000)
})
// 监听 activeTab 变化,自动保存到 localStorage
watch(activeTab, (newTab) => {
localStorage.setItem(ACTIVE_TAB_STORAGE_KEY, newTab)
// 组件卸载时清理事件监听
onUnmounted(() => {
updateStore.removeEventListeners()
})
// 窗口控制方法
@@ -321,29 +184,6 @@ const handleClose = async () => {
}
}
// 升级提示事件处理
const handleUpdateInstall = async (filePath) => {
try {
const result = await window.go.main.App.InstallUpdate(filePath, true)
if (result.success) {
Message.success({
content: '安装成功!应用将在几秒后重启...',
duration: 3000
})
} else {
Message.error(result.message || '安装失败')
}
} catch (error) {
console.error('安装失败:', error)
Message.error('安装失败:' + (error.message || error))
}
}
const handleUpdateSkip = () => {
// 清除跳过的版本记录(如果用户选择"稍后提醒"
// 版本记录在组件内部处理
}
// 监听 activeTab 变化,如果当前 Tab 不在可见列表中,切换到默认 Tab
watch(activeTab, (newTab) => {
// 保存到 localStorage
@@ -351,8 +191,8 @@ watch(activeTab, (newTab) => {
// 检查 Tab 是否在可见列表中
const isVisible = appConfig.value.visibleTabs.includes(newTab)
if (!isVisible && appConfig.value.visibleTabs.length > 0) {
// 切换到默认 Tab
if (!isVisible && appConfig.value.visibleTabs.length > 0 && newTab !== appConfig.value.defaultTab) {
// 切换到默认 Tab(避免重复触发)
activeTab.value = appConfig.value.defaultTab
}
})