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

@@ -1,6 +1,7 @@
package filesystem
import (
"context"
"encoding/base64"
"fmt"
"log"
@@ -10,12 +11,14 @@ import (
"path/filepath"
"strings"
"sync"
"time"
)
// LocalFileServer 本地文件服务器(独立的 HTTP 服务器)
type LocalFileServer struct {
server *http.Server
addr string
mu sync.RWMutex
}
var (
@@ -258,3 +261,35 @@ func HandleLocalFile(w http.ResponseWriter, r *http.Request) {
func isAllowedFileType(ext string) bool {
return defaultFileTypeManager.IsAllowed(ext)
}
// Shutdown 优雅关闭文件服务器
func (lfs *LocalFileServer) Shutdown() error {
if lfs == nil || lfs.server == nil {
return nil
}
lfs.mu.Lock()
defer lfs.mu.Unlock()
// 创建带超时的上下文
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
log.Printf("[LocalFileServer] 正在关闭...")
if err := lfs.server.Shutdown(ctx); err != nil {
log.Printf("[LocalFileServer] 关闭失败: %v", err)
return err
}
log.Printf("[LocalFileServer] 已关闭")
return nil
}
// ShutdownLocalFileServer 关闭全局文件服务器
func ShutdownLocalFileServer() error {
if localFileServer != nil {
return localFileServer.Shutdown()
}
return nil
}

View File

@@ -262,7 +262,7 @@ func (s *FileSystemService) DeletePathWithContext(ctx context.Context, path stri
// 返回被删除的文件信息,用于前端更新
return &FileOperationResult{
Path: path,
Path: filepath.ToSlash(path), // 统一使用正斜杠
Name: info.Name(),
Size: info.Size(),
SizeStr: formatBytes(info.Size()),
@@ -297,7 +297,7 @@ func (s *FileSystemService) ListDir(path string) ([]map[string]interface{}, erro
fullPath := filepath.Join(path, entry.Name())
result = append(result, map[string]interface{}{
"name": entry.Name(),
"path": fullPath,
"path": filepath.ToSlash(fullPath), // 统一使用正斜杠
"is_dir": entry.IsDir(),
"size": info.Size(),
"mod_time": info.ModTime().Format("2006-01-02 15:04:05"),
@@ -338,14 +338,14 @@ func (s *FileSystemService) CreateDir(path string) (*FileOperationResult, error)
if err != nil {
// 创建成功但获取信息失败,返回基本信息
return &FileOperationResult{
Path: path,
Path: filepath.ToSlash(path), // 统一使用正斜杠
Name: filepath.Base(path),
IsDir: true,
}, nil
}
return &FileOperationResult{
Path: path,
Path: filepath.ToSlash(path), // 统一使用正斜杠
Name: info.Name(),
Size: info.Size(),
SizeStr: formatBytes(info.Size()),
@@ -385,7 +385,7 @@ func (s *FileSystemService) CreateFile(path string) (*FileOperationResult, error
if err != nil {
// 创建成功但获取信息失败,返回基本信息
return &FileOperationResult{
Path: path,
Path: filepath.ToSlash(path), // 统一使用正斜杠
Name: filepath.Base(path),
IsDir: false,
Size: 0,
@@ -393,7 +393,7 @@ func (s *FileSystemService) CreateFile(path string) (*FileOperationResult, error
}
return &FileOperationResult{
Path: path,
Path: filepath.ToSlash(path), // 统一使用正斜杠
Name: info.Name(),
Size: info.Size(),
SizeStr: formatBytes(info.Size()),
@@ -424,7 +424,7 @@ func (s *FileSystemService) GetFileInfo(path string) (map[string]interface{}, er
return map[string]interface{}{
"name": info.Name(),
"path": path,
"path": filepath.ToSlash(path), // 统一使用正斜杠
"size": info.Size(),
"size_str": formatBytes(info.Size()),
"is_dir": info.IsDir(),
@@ -472,21 +472,21 @@ func (s *FileSystemService) RenamePath(oldPath, newPath string) (*FileOperationR
if err != nil {
// 重命名成功但获取信息失败,返回基本信息
return &FileOperationResult{
Path: newPath,
Path: filepath.ToSlash(newPath), // 统一使用正斜杠
Name: filepath.Base(newPath),
OldPath: oldPath,
OldPath: filepath.ToSlash(oldPath),
}, nil
}
return &FileOperationResult{
Path: newPath,
Path: filepath.ToSlash(newPath), // 统一使用正斜杠
Name: info.Name(),
Size: info.Size(),
SizeStr: formatBytes(info.Size()),
IsDir: info.IsDir(),
ModTime: info.ModTime().Format("2006-01-02 15:04:05"),
Mode: info.Mode().String(),
OldPath: oldPath,
OldPath: filepath.ToSlash(oldPath),
}, nil
}

View File

@@ -181,7 +181,7 @@ func ListZipContents(zipPath string) ([]map[string]interface{}, error) {
entry := map[string]interface{}{
"name": name,
"path": file.Name, // zip 中的完整路径
"path": file.Name, // zip 中的完整路径(已使用 /
"is_dir": isDir,
"size": file.UncompressedSize64,
"compressed": file.CompressedSize64,

View File

@@ -103,7 +103,7 @@ func getCompressionMethodString(method uint16) string {
func createFileInfoMap(file *zip.File, includeExtra ...bool) map[string]interface{} {
info := map[string]interface{}{
"name": filepath.Base(file.Name),
"path": file.Name,
"path": file.Name, // zip 中的路径(已使用 /
"is_dir": file.Mode().IsDir(),
"size": file.UncompressedSize64,
"compressed": file.CompressedSize64,