Files
affiliate_dash/backend/cmd/cache_images/main.go
T
yml2213 5f642eb7a6 feat: 优化发货交付页面与凭据生成,支持一键复制结果图片及官方商品图片本地缓存
- 交付界面重构:隐藏内部订单号、流水号与发货渠道,展示聚焦于买家游戏UID、角色名与交付时间
- 发货结果凭据生成:采用 Canvas 生成高清发货存证图,优化存证说明文案与自适应排版
- 一键复制图片:支持直接将结果凭证图片写入系统剪贴板,方便客服在聊天窗口快捷粘贴
- 官方图片本地化缓存:全量下载乐玩商品官方主图并建立本地持久化路由,规避外部源站跨域及破损问题
- 修复乐玩渠道角色UID提取与履约状态幂等回填逻辑
2026-09-14 17:19:12 +08:00

93 lines
2.3 KiB
Go

package main
import (
"context"
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"time"
"affiliate_dash/internal/config"
"affiliate_dash/internal/pkg/lewan"
)
func main() {
cfg := config.Load()
client := lewan.NewClient(lewan.Config{
BaseURL: cfg.LewanBaseURL,
AccessKey: cfg.LewanAccessKey,
SecretKey: cfg.LewanSecretKey,
ApplicationID: cfg.LewanApplicationID,
}, nil)
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
list, err := client.ListProducts(ctx, 1, 100, "")
if err != nil {
fmt.Printf("ListProducts error: %v\n", err)
return
}
fmt.Printf("Found %d products (total: %d)\n", len(list.Items), list.Total)
uploadDir := cfg.UploadDir
if uploadDir == "" {
uploadDir = "data/uploads"
}
cacheDir := filepath.Join(uploadDir, "products")
_ = os.MkdirAll(cacheDir, 0755)
httpClient := &http.Client{Timeout: 15 * time.Second}
for i, item := range list.Items {
fmt.Printf("[%d/%d] ID: %s, Name: %s, Thumb: %s\n", i+1, len(list.Items), item.ID, item.Name, item.ThumbnailUrl)
if item.ThumbnailUrl == "" {
continue
}
// 存储为 item.ID + 原扩展名
ext := filepath.Ext(item.ThumbnailUrl)
if ext == "" || len(ext) > 5 {
ext = ".webp"
}
destPath := filepath.Join(cacheDir, item.ID+ext)
// 同时也用 url hash 存一个软链或备份,以便 proxy 按 url 精准命中
urlHash := sha256.Sum256([]byte(item.ThumbnailUrl))
hashPath := filepath.Join(cacheDir, hex.EncodeToString(urlHash[:])+ext)
if _, err := os.Stat(destPath); err == nil {
fmt.Printf(" -> 已存在缓存: %s\n", destPath)
continue
}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, item.ThumbnailUrl, nil)
if err != nil {
fmt.Printf(" -> 构建请求失败: %v\n", err)
continue
}
resp, err := httpClient.Do(req)
if err != nil {
fmt.Printf(" -> 下载失败: %v\n", err)
continue
}
if resp.StatusCode != http.StatusOK {
fmt.Printf(" -> 状态码错误: %d\n", resp.StatusCode)
resp.Body.Close()
continue
}
data, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
fmt.Printf(" -> 读取失败: %v\n", err)
continue
}
_ = os.WriteFile(destPath, data, 0644)
_ = os.WriteFile(hashPath, data, 0644)
fmt.Printf(" -> 成功缓存: %s (大小: %d 字节)\n", destPath, len(data))
}
}