Files
fanqie-go/internal/fqapi/manga_proxy.go
T
chenxin 6981148727 🔧 chore: 初始化番茄小说 API 项目结构
新增项目基础框架,包含核心 API 实现、算法模块、HTTP 处理器等完整功能模块
2026-08-28 15:22:22 +08:00

73 lines
1.8 KiB
Go

package fqapi
import (
"encoding/hex"
"fmt"
"time"
)
// HandleMangaImageProxy 处理漫画图片代理请求
func HandleMangaImageProxy(itemID string, index int) ([]byte, string, error) {
// 从缓存获取图片信息
cacheKey := fmt.Sprintf("%s_%d", itemID, index)
mangaCacheMutex.RLock()
imageInfo, exists := mangaImageCache[cacheKey]
mangaCacheMutex.RUnlock()
if !exists {
return nil, "", fmt.Errorf("图片信息不存在,请先调用 /manga 接口")
}
// 检查缓存是否过期(5分钟)
if time.Since(imageInfo.CachedAt) > 5*time.Minute {
// 清理过期缓存
mangaCacheMutex.Lock()
delete(mangaImageCache, cacheKey)
mangaCacheMutex.Unlock()
return nil, "", fmt.Errorf("图片信息已过期,请重新调用 /manga 接口")
}
// 下载加密图片
encryptedData, err := downloadImageWithRetry(imageInfo.PicURL, 2)
if err != nil {
return nil, "", fmt.Errorf("下载图片失败: %w", err)
}
// 解密图片
keyBytes, err := hex.DecodeString(imageInfo.EncryptKey)
if err != nil {
return nil, "", fmt.Errorf("密钥解码失败: %w", err)
}
decryptedData, err := decryptImage(encryptedData, keyBytes)
if err != nil {
return nil, "", fmt.Errorf("解密失败: %w", err)
}
// 识别格式
format := getImageFormat(decryptedData, imageInfo.PicURL)
// 返回图片数据和MIME类型
mimeType := fmt.Sprintf("image/%s", format)
if format == "jpg" {
mimeType = "image/jpeg"
}
return decryptedData, mimeType, nil
}
// CleanExpiredMangaCache 清理过期的漫画图片缓存
func CleanExpiredMangaCache() {
mangaCacheMutex.Lock()
defer mangaCacheMutex.Unlock()
now := time.Now()
for key, info := range mangaImageCache {
if now.Sub(info.CachedAt) > 5*time.Minute {
delete(mangaImageCache, key)
}
}
}