package face import ( "fmt" "io" "net/http" "os" "path/filepath" "strings" "time" "lone-services/pkg/utils" "github.com/google/uuid" ) // PrepareImagePath 将上传字节或已有路径解析为 insightface 可读的本地路径。 // 返回 cleanup 用于删除临时文件(共享路径不删)。 func PrepareImagePath(file []byte, filePath string) (string, func(), error) { noop := func() {} if len(file) > utils.NumberZero { dir := utils.GetConfigString("file.upload_path") if dir == utils.StringEmpty { dir = os.TempDir() } if err := os.MkdirAll(dir, 0o755); err != nil { return "", noop, err } path := filepath.Join(dir, "face-login-"+uuid.NewString()+".jpg") if err := os.WriteFile(path, file, 0o644); err != nil { return "", noop, err } return path, func() { _ = os.Remove(path) }, nil } path := strings.TrimSpace(filePath) if path == utils.StringEmpty { return "", noop, fmt.Errorf("file or file_path required") } if strings.HasPrefix(path, "http://") || strings.HasPrefix(path, "https://") { local, err := downloadToTemp(path) if err != nil { return "", noop, err } return local, func() { _ = os.Remove(local) }, nil } if filepath.IsAbs(path) { return path, noop, nil } base := utils.GetConfigString("file.upload_path") return filepath.Join(base, strings.TrimPrefix(path, "/")), noop, nil } func downloadToTemp(url string) (string, error) { client := &http.Client{Timeout: 15 * time.Second} resp, err := client.Get(url) if err != nil { return "", err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return "", fmt.Errorf("download face image status %d", resp.StatusCode) } dir := utils.GetConfigString("file.upload_path") if dir == utils.StringEmpty { dir = os.TempDir() } if err = os.MkdirAll(dir, 0o755); err != nil { return "", err } path := filepath.Join(dir, "face-dl-"+uuid.NewString()+".jpg") f, err := os.Create(path) if err != nil { return "", err } defer f.Close() if _, err = io.Copy(f, resp.Body); err != nil { _ = os.Remove(path) return "", err } return path, nil }