package storage import ( "io" "os" "path/filepath" "strings" "gotest/internal/config" ) // LocalStorage 本地文件存储实现 type LocalStorage struct { path string // 文件存储根目录 } // NewLocalStorage 创建本地存储实例 func NewLocalStorage(cfg *config.LocalStorage) *LocalStorage { return &LocalStorage{ path: cfg.Path, } } // Upload 上传文件到本地磁盘 func (s *LocalStorage) Upload(key string, reader io.Reader, contentType string) (string, error) { fullPath := filepath.Join(s.path, key) // 自动创建目录 if err := os.MkdirAll(filepath.Dir(fullPath), 0755); err != nil { return "", err } // 创建文件 file, err := os.Create(fullPath) if err != nil { return "", err } defer file.Close() // 写入内容 if _, err := io.Copy(file, reader); err != nil { return "", err } return s.GetURL(key), nil } // Delete 删除本地文件 func (s *LocalStorage) Delete(key string) error { fullPath := filepath.Join(s.path, key) return os.Remove(fullPath) } // GetURL 拼接 base path 返回文件访问 URL func (s *LocalStorage) GetURL(key string) string { base := s.path // 规范化为以 / 开头的 URL 路径 base = strings.TrimPrefix(base, "./") base = strings.TrimPrefix(base, ".") if !strings.HasPrefix(base, "/") { base = "/" + base } return strings.TrimRight(base, "/") + "/" + key }