140 lines
3.5 KiB
Go
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)
|
|
}
|