Private
Public Access
1
0

优化:文件服务器安全重构+编辑器增强+搜索排序+更新面板Markdown渲染

- 路径校验提取validateFilePath+sentinel error替代字符串匹配
- requireUpdateAPI收敛7处重复nil检查
- 端口18765统一为8073,消除分散魔法数字
- CodeMirror添加搜索功能+滚动位置LRU缓存恢复
- 文件列表新增列排序+搜索过滤
- Toolbar重排:快捷访问内嵌+搜索框集成+历史改图标
- 重命名零闪烁:updateFilePath草稿迁移
- changelog用marked渲染+sanitizeHtml防XSS
- MigrateTabConfig扩展map驱动覆盖openclaw-manager→version迁移

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-21 21:53:31 +08:00
parent 691e38604f
commit 72fef3e56f
23 changed files with 614 additions and 257 deletions

72
app.go
View File

@@ -3,7 +3,6 @@ package main
import (
"context"
"fmt"
"net/http"
"os"
"path/filepath"
stdruntime "runtime"
@@ -30,7 +29,6 @@ type App struct {
updateAPI *api.UpdateAPI
configAPI *api.ConfigAPI
pdfAPI *api.PdfAPI
fileServer *http.Server
filesystem *filesystem.FileSystemService
isAlwaysOnTop bool
}
@@ -194,7 +192,7 @@ func (a *App) startFileServer() {
return
}
fmt.Println("[文件服务器] 启动在 http://localhost:18765")
fmt.Println("[文件服务器] 启动在 http://localhost:8073")
}
// Shutdown 应用关闭时调用
@@ -415,7 +413,7 @@ func (a *App) GetCommonPaths() (map[string]string, error) {
// Windows: 从注册表读取特殊文件夹真实路径(用户可能已修改位置)
folderGUIDs := map[string]string{
"desktop": "{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}",
"documents": "{D20B4C7F-5EA7-40D4B25E-039F6F1FCC8A}",
"documents": "{D20B4C7F-5EA7-424C-B25E-039F6F1FCC8A}",
"downloads": "{374DE290-123F-4565-9164-39C4925E467B}",
}
for name, guid := range folderGUIDs {
@@ -603,68 +601,84 @@ func (a *App) ListSqlTabs() ([]map[string]interface{}, error) {
// ========== 版本更新管理接口 ==========
// CheckUpdate 检查更新UpdateAPI 可能尚未初始化完成)
func (a *App) CheckUpdate() (map[string]interface{}, error) {
// requireUpdateAPI 检查 updateAPI 是否已初始化,未初始化返回统一错误
func (a *App) requireUpdateAPI() (*api.UpdateAPI, error) {
if a.updateAPI == nil {
return nil, fmt.Errorf("更新功能正在初始化中")
}
return a.updateAPI.CheckUpdate()
return a.updateAPI, nil
}
// CheckUpdate 检查更新UpdateAPI 可能尚未初始化完成)
func (a *App) CheckUpdate() (map[string]interface{}, error) {
api, err := a.requireUpdateAPI()
if err != nil {
return nil, err
}
return api.CheckUpdate()
}
// GetCurrentVersion 获取当前版本号
func (a *App) GetCurrentVersion() (map[string]interface{}, error) {
if a.updateAPI == nil {
return nil, fmt.Errorf("更新功能正在初始化中")
api, err := a.requireUpdateAPI()
if err != nil {
return nil, err
}
return a.updateAPI.GetCurrentVersion()
return api.GetCurrentVersion()
}
// GetUpdateConfig 获取更新配置
func (a *App) GetUpdateConfig() (map[string]interface{}, error) {
if a.updateAPI == nil {
return nil, fmt.Errorf("更新功能正在初始化中")
api, err := a.requireUpdateAPI()
if err != nil {
return nil, err
}
return a.updateAPI.GetUpdateConfig()
return api.GetUpdateConfig()
}
// SetUpdateConfig 设置更新配置
func (a *App) SetUpdateConfig(autoCheckEnabled bool, checkIntervalMinutes int, checkURL string) (map[string]interface{}, error) {
if a.updateAPI == nil {
return nil, fmt.Errorf("更新功能正在初始化中")
api, err := a.requireUpdateAPI()
if err != nil {
return nil, err
}
return a.updateAPI.SetUpdateConfig(autoCheckEnabled, checkIntervalMinutes, checkURL)
return api.SetUpdateConfig(autoCheckEnabled, checkIntervalMinutes, checkURL)
}
// DownloadUpdate 下载更新包
func (a *App) DownloadUpdate(downloadURL string) (map[string]interface{}, error) {
if a.updateAPI == nil {
return nil, fmt.Errorf("更新功能正在初始化中")
api, err := a.requireUpdateAPI()
if err != nil {
return nil, err
}
return a.updateAPI.DownloadUpdate(downloadURL)
return api.DownloadUpdate(downloadURL)
}
// InstallUpdate 安装更新包
func (a *App) InstallUpdate(installerPath string, autoRestart bool) (map[string]interface{}, error) {
if a.updateAPI == nil {
return nil, fmt.Errorf("更新功能正在初始化中")
api, err := a.requireUpdateAPI()
if err != nil {
return nil, err
}
return a.updateAPI.InstallUpdate(installerPath, autoRestart)
return api.InstallUpdate(installerPath, autoRestart)
}
// InstallUpdateWithHash 安装更新包(带哈希验证)
func (a *App) InstallUpdateWithHash(installerPath string, autoRestart bool, expectedHash string, hashType string) (map[string]interface{}, error) {
if a.updateAPI == nil {
return nil, fmt.Errorf("更新功能正在初始化中")
api, err := a.requireUpdateAPI()
if err != nil {
return nil, err
}
return a.updateAPI.InstallUpdateWithHash(installerPath, autoRestart, expectedHash, hashType)
return api.InstallUpdateWithHash(installerPath, autoRestart, expectedHash, hashType)
}
// VerifyUpdateFile 验证更新文件哈希值
func (a *App) VerifyUpdateFile(filePath string, expectedHash string, hashType string) (map[string]interface{}, error) {
if a.updateAPI == nil {
return nil, fmt.Errorf("更新功能正在初始化中")
api, err := a.requireUpdateAPI()
if err != nil {
return nil, err
}
return a.updateAPI.VerifyUpdateFile(filePath, expectedHash, hashType)
return api.VerifyUpdateFile(filePath, expectedHash, hashType)
}
// startAutoUpdateCheck 启动自动更新检查
@@ -753,7 +767,7 @@ func (a *App) GetAuditLogs(limit int) ([]map[string]interface{}, error) {
// GetFileServerURL 获取本地文件服务器的URL
func (a *App) GetFileServerURL() string {
return "http://localhost:18765"
return "http://localhost:8073"
}
// DetectFileTypeByContent 通过文件内容检测文件类型(用于小文件)