daShangDao_centerBook/image/image.go
2026-02-28 14:27:33 +08:00

140 lines
3.5 KiB
Go

package image
import (
"bytes"
"encoding/json"
"fmt"
"io"
"mime/multipart"
"net/http"
"os"
"path/filepath"
)
// PddUploadResult 用于解析 PDD 上传返回的 result JSON
type PddUploadResult struct {
URL string `json:"url"`
}
// UploadResponse 用于解析上传接口完整响应
type UploadResponse struct {
Data struct {
PddUpload struct {
Result string `json:"result"`
Success bool `json:"success"`
} `json:"pddUpload"`
} `json:"data"`
Success bool `json:"success"`
Message string `json:"message"`
}
// DownloadFile 下载图片到临时文件
func DownloadFile(url string) (string, error) {
resp, err := http.Get(url)
if err != nil {
return "", fmt.Errorf("下载文件失败: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("下载失败, 状态码: %d", resp.StatusCode)
}
tmpFile, err := os.CreateTemp("", "book_image_*.png")
if err != nil {
return "", fmt.Errorf("创建临时文件失败: %w", err)
}
defer tmpFile.Close()
_, err = io.Copy(tmpFile, resp.Body)
if err != nil {
return "", fmt.Errorf("写入临时文件失败: %w", err)
}
return tmpFile.Name(), nil
}
// UploadBookImage 上传图片并返回 PDD URL
func UploadBookImage(filePath, isbn, isKW, goodsName, autoUpload string) (string, error) {
file, err := os.Open(filePath)
if err != nil {
return "", fmt.Errorf("打开文件失败: %w", err)
}
defer file.Close()
var body bytes.Buffer
writer := multipart.NewWriter(&body)
part, err := writer.CreateFormFile("filepath", filepath.Base(file.Name()))
if err != nil {
return "", fmt.Errorf("创建文件字段失败: %w", err)
}
if _, err := io.Copy(part, file); err != nil {
return "", fmt.Errorf("复制文件内容失败: %w", err)
}
fields := map[string]string{
"isbn": isbn,
"isKW": isKW,
"goodsName": goodsName,
"autoUpload": autoUpload,
}
for k, v := range fields {
if err := writer.WriteField(k, v); err != nil {
return "", fmt.Errorf("写入字段 %s 失败: %w", k, err)
}
}
if err := writer.Close(); err != nil {
return "", fmt.Errorf("关闭 writer 失败: %w", err)
}
req, err := http.NewRequest("POST", "http://103.236.81.185:9000/processImage", &body)
if err != nil {
return "", fmt.Errorf("创建请求失败: %w", err)
}
req.Header.Set("Content-Type", writer.FormDataContentType())
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return "", fmt.Errorf("发送请求失败: %w", err)
}
defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("读取响应失败: %w", err)
}
var uploadResp UploadResponse
if err := json.Unmarshal(respBody, &uploadResp); err != nil {
return "", fmt.Errorf("解析响应失败: %w", err)
}
if !uploadResp.Data.PddUpload.Success {
return "", fmt.Errorf("上传失败: %s", uploadResp.Message)
}
// 解析 result 字段中的 JSON
var result PddUploadResult
if err := json.Unmarshal([]byte(uploadResp.Data.PddUpload.Result), &result); err != nil {
return "", fmt.Errorf("解析 PDD result 失败: %w", err)
}
return result.URL, nil
}
// DownloadAndUploadBookImage 下载图片并上传,返回 PDD URL
func DownloadAndUploadBookImage(imageURL, isbn, isKW, goodsName, autoUpload string) (string, error) {
tmpFile, err := DownloadFile(imageURL)
if err != nil {
return "", err
}
defer os.Remove(tmpFile) // 使用完删除临时文件
return UploadBookImage(tmpFile, isbn, isKW, goodsName, autoUpload)
}