diff --git a/internal/storage/local.go b/internal/storage/local.go new file mode 100644 index 0000000..ced0a71 --- /dev/null +++ b/internal/storage/local.go @@ -0,0 +1,60 @@ +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 +}