181 lines
5.0 KiB
Go
181 lines
5.0 KiB
Go
package services
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"os"
|
||
"os/exec"
|
||
"path/filepath"
|
||
"runtime"
|
||
"strings"
|
||
)
|
||
|
||
// FileService 文件服务
|
||
type FileService struct{}
|
||
|
||
// NewFileService 创建文件服务实例
|
||
func NewFileService() *FileService {
|
||
return &FileService{}
|
||
}
|
||
|
||
// SelectFolder 选择文件夹(返回路径)
|
||
func (s *FileService) SelectFolder(ctx context.Context) (string, error) {
|
||
LogDebug("开始选择文件夹...")
|
||
|
||
// 根据操作系统使用不同的方法
|
||
switch runtime.GOOS {
|
||
case "darwin": // macOS
|
||
return s.selectFolderMacOS()
|
||
case "windows":
|
||
return s.selectFolderWindows()
|
||
case "linux":
|
||
return s.selectFolderLinux()
|
||
default:
|
||
return "", fmt.Errorf("不支持的操作系统: %s", runtime.GOOS)
|
||
}
|
||
}
|
||
|
||
// selectFolderMacOS 在 macOS 上选择文件夹
|
||
func (s *FileService) selectFolderMacOS() (string, error) {
|
||
// 使用 AppleScript 打开文件夹选择对话框
|
||
script := `tell application "System Events"
|
||
activate
|
||
set folderPath to choose folder with prompt "请选择文件夹"
|
||
return POSIX path of folderPath
|
||
end tell`
|
||
|
||
cmd := exec.Command("osascript", "-e", script)
|
||
output, err := cmd.Output()
|
||
if err != nil {
|
||
LogErrorf("选择文件夹失败: %v", err)
|
||
return "", fmt.Errorf("选择文件夹失败: %v", err)
|
||
}
|
||
|
||
path := strings.TrimSpace(string(output))
|
||
LogInfof("选择的文件夹路径: %s", path)
|
||
return path, nil
|
||
}
|
||
|
||
// selectFolderWindows 在 Windows 上选择文件夹
|
||
func (s *FileService) selectFolderWindows() (string, error) {
|
||
// 使用 PowerShell 打开文件夹选择对话框
|
||
script := `Add-Type -AssemblyName System.Windows.Forms
|
||
$folderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog
|
||
$folderBrowser.Description = "请选择文件夹"
|
||
$result = $folderBrowser.ShowDialog()
|
||
if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
|
||
Write-Output $folderBrowser.SelectedPath
|
||
}`
|
||
|
||
cmd := exec.Command("powershell", "-Command", script)
|
||
output, err := cmd.Output()
|
||
if err != nil {
|
||
LogErrorf("选择文件夹失败: %v", err)
|
||
return "", fmt.Errorf("选择文件夹失败: %v", err)
|
||
}
|
||
|
||
path := strings.TrimSpace(string(output))
|
||
LogInfof("选择的文件夹路径: %s", path)
|
||
return path, nil
|
||
}
|
||
|
||
// selectFolderLinux 在 Linux 上选择文件夹
|
||
func (s *FileService) selectFolderLinux() (string, error) {
|
||
// 使用 zenity 或 kdialog 打开文件夹选择对话框
|
||
var cmd *exec.Cmd
|
||
|
||
// 先尝试使用 zenity
|
||
if _, err := exec.LookPath("zenity"); err == nil {
|
||
cmd = exec.Command("zenity", "--file-selection", "--directory", "--title=请选择文件夹")
|
||
} else if _, err := exec.LookPath("kdialog"); err == nil {
|
||
cmd = exec.Command("kdialog", "--getexistingdirectory", "$HOME", "--title", "请选择文件夹")
|
||
} else {
|
||
return "", fmt.Errorf("未找到 zenity 或 kdialog,无法打开文件夹选择对话框")
|
||
}
|
||
|
||
output, err := cmd.Output()
|
||
if err != nil {
|
||
LogErrorf("选择文件夹失败: %v", err)
|
||
return "", fmt.Errorf("选择文件夹失败: %v", err)
|
||
}
|
||
|
||
path := strings.TrimSpace(string(output))
|
||
LogInfof("选择的文件夹路径: %s", path)
|
||
return path, nil
|
||
}
|
||
|
||
// SelectFile 选择文件(返回路径)
|
||
func (s *FileService) SelectFile(ctx context.Context, filter string) (string, error) {
|
||
// 在 Wails3 中,文件选择需要通过前端实现
|
||
return "", nil
|
||
}
|
||
|
||
// OpenFolder 打开文件夹
|
||
func (s *FileService) OpenFolder(ctx context.Context, folderPath string) error {
|
||
LogDebugf("打开文件夹: %s", folderPath)
|
||
|
||
// 检查文件夹是否存在
|
||
if _, err := os.Stat(folderPath); os.IsNotExist(err) {
|
||
return fmt.Errorf("文件夹不存在: %s", folderPath)
|
||
}
|
||
|
||
// 根据操作系统使用不同的命令
|
||
var cmd *exec.Cmd
|
||
switch runtime.GOOS {
|
||
case "darwin": // macOS
|
||
cmd = exec.Command("open", folderPath)
|
||
case "windows":
|
||
cmd = exec.Command("explorer", folderPath)
|
||
case "linux":
|
||
cmd = exec.Command("xdg-open", folderPath)
|
||
default:
|
||
return fmt.Errorf("不支持的操作系统: %s", runtime.GOOS)
|
||
}
|
||
|
||
err := cmd.Run()
|
||
if err != nil {
|
||
LogErrorf("打开文件夹失败: %v", err)
|
||
return fmt.Errorf("打开文件夹失败: %v", err)
|
||
}
|
||
|
||
LogInfo("文件夹已打开")
|
||
return nil
|
||
}
|
||
|
||
// FileExists 检查文件是否存在
|
||
func (s *FileService) FileExists(ctx context.Context, filePath string) (bool, error) {
|
||
_, err := os.Stat(filePath)
|
||
if err == nil {
|
||
return true, nil
|
||
}
|
||
if os.IsNotExist(err) {
|
||
return false, nil
|
||
}
|
||
return false, err
|
||
}
|
||
|
||
// GetFileSize 获取文件大小(字节)
|
||
func (s *FileService) GetFileSize(ctx context.Context, filePath string) (int64, error) {
|
||
info, err := os.Stat(filePath)
|
||
if err != nil {
|
||
return 0, err
|
||
}
|
||
return info.Size(), nil
|
||
}
|
||
|
||
// EnsureDirectory 确保目录存在
|
||
func (s *FileService) EnsureDirectory(ctx context.Context, dirPath string) error {
|
||
return os.MkdirAll(dirPath, 0755)
|
||
}
|
||
|
||
// ListFiles 列出目录中的文件
|
||
func (s *FileService) ListFiles(ctx context.Context, dirPath string, pattern string) ([]string, error) {
|
||
patternPath := filepath.Join(dirPath, pattern)
|
||
matches, err := filepath.Glob(patternPath)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return matches, nil
|
||
}
|
||
|