mirror of
https://git.fightbot.fun/hxuanyu/BingPaper.git
synced 2026-02-15 05:59:32 +08:00
优化图片处理逻辑:优先使用最小变体以节省流量,并新增 normalizeImageUrl 函数处理相对路径问题
This commit is contained in:
@@ -218,7 +218,7 @@ func ListImages(c *gin.Context) {
|
||||
|
||||
result := []gin.H{}
|
||||
for _, img := range images {
|
||||
result = append(result, formatMeta(&img))
|
||||
result = append(result, formatMetaSummary(&img))
|
||||
}
|
||||
c.JSON(http.StatusOK, result)
|
||||
}
|
||||
@@ -300,6 +300,49 @@ func serveLocal(c *gin.Context, key string, etag string, maxAge int) {
|
||||
io.Copy(c.Writer, reader)
|
||||
}
|
||||
|
||||
func formatMetaSummary(img *model.Image) gin.H {
|
||||
cfg := config.GetConfig()
|
||||
|
||||
// 找到最小的变体(Size 最小)
|
||||
var smallest *model.ImageVariant
|
||||
for i := range img.Variants {
|
||||
v := &img.Variants[i]
|
||||
if smallest == nil || v.Size < smallest.Size {
|
||||
smallest = v
|
||||
}
|
||||
}
|
||||
|
||||
variants := []gin.H{}
|
||||
if smallest != nil {
|
||||
url := smallest.PublicURL
|
||||
if url == "" && cfg.API.Mode == "redirect" && img.URLBase != "" {
|
||||
url = fmt.Sprintf("https://www.bing.com%s_%s.jpg", img.URLBase, smallest.Variant)
|
||||
} else if cfg.API.Mode == "local" || url == "" {
|
||||
url = fmt.Sprintf("%s/api/v1/image/date/%s?variant=%s&format=%s&mkt=%s", cfg.Server.BaseURL, img.Date, smallest.Variant, smallest.Format, img.Mkt)
|
||||
}
|
||||
variants = append(variants, gin.H{
|
||||
"variant": smallest.Variant,
|
||||
"format": smallest.Format,
|
||||
"size": smallest.Size,
|
||||
"url": url,
|
||||
"storage_key": smallest.StorageKey,
|
||||
})
|
||||
}
|
||||
|
||||
return gin.H{
|
||||
"date": img.Date,
|
||||
"mkt": img.Mkt,
|
||||
"title": img.Title,
|
||||
"copyright": img.Copyright,
|
||||
"copyrightlink": img.CopyrightLink,
|
||||
"quiz": img.Quiz,
|
||||
"startdate": img.StartDate,
|
||||
"fullstartdate": img.FullStartDate,
|
||||
"hsh": img.HSH,
|
||||
"variants": variants,
|
||||
}
|
||||
}
|
||||
|
||||
func formatMeta(img *model.Image) gin.H {
|
||||
cfg := config.GetConfig()
|
||||
variants := []gin.H{}
|
||||
|
||||
@@ -66,6 +66,21 @@ func TestHandleImageResponseRedirect(t *testing.T) {
|
||||
assert.Contains(t, variants[0]["url"].(string), "myserver.com")
|
||||
assert.Contains(t, variants[0]["url"].(string), "/api/v1/image/date/")
|
||||
})
|
||||
|
||||
t.Run("FormatMetaSummary should only return the smallest variant", func(t *testing.T) {
|
||||
imgWithMultipleVariants := &model.Image{
|
||||
Date: "2026-01-26",
|
||||
Variants: []model.ImageVariant{
|
||||
{Variant: "UHD", Size: 1000, Format: "jpg"},
|
||||
{Variant: "640x480", Size: 200, Format: "jpg"},
|
||||
{Variant: "1920x1080", Size: 500, Format: "jpg"},
|
||||
},
|
||||
}
|
||||
meta := formatMetaSummary(imgWithMultipleVariants)
|
||||
variants := meta["variants"].([]gin.H)
|
||||
assert.Equal(t, 1, len(variants))
|
||||
assert.Equal(t, "640x480", variants[0]["variant"])
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetRegions(t *testing.T) {
|
||||
|
||||
@@ -35,6 +35,26 @@ export const buildApiUrl = (endpoint: string): string => {
|
||||
return `${API_BASE_URL}${normalizedEndpoint}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 标准化图片 URL
|
||||
* 当后端返回相对路径且配置了绝对 API 基础地址时,自动拼接完整域名
|
||||
*/
|
||||
export const normalizeImageUrl = (url: string | undefined): string => {
|
||||
if (!url) return ''
|
||||
if (url.startsWith('http')) return url
|
||||
|
||||
// 处理相对路径问题:如果配置了绝对 API 基础地址,则拼接 Origin
|
||||
if (API_BASE_URL.startsWith('http')) {
|
||||
try {
|
||||
const origin = new URL(API_BASE_URL).origin
|
||||
return url.startsWith('/') ? origin + url : origin + '/' + url
|
||||
} catch (e) {
|
||||
// 解析失败则返回原样
|
||||
}
|
||||
}
|
||||
return url
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP 状态码枚举
|
||||
*/
|
||||
|
||||
@@ -156,7 +156,7 @@
|
||||
</div>
|
||||
|
||||
<!-- 图片网格 -->
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-6">
|
||||
<div
|
||||
v-for="(image, index) in images"
|
||||
:key="image.date || index"
|
||||
@@ -264,6 +264,7 @@
|
||||
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
|
||||
import { useImageList } from '@/composables/useImages'
|
||||
import { bingPaperApi } from '@/lib/api-service'
|
||||
import { normalizeImageUrl } from '@/lib/api-config'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { getDefaultMkt, setSavedMkt, SUPPORTED_REGIONS, setSupportedRegions } from '@/lib/mkt-utils'
|
||||
import {
|
||||
@@ -570,8 +571,11 @@ const getLatestImageUrl = () => {
|
||||
return bingPaperApi.getImageUrlByDate(latestImage.value.date, 'UHD', 'jpg', latestImage.value.mkt)
|
||||
}
|
||||
|
||||
// 获取图片 URL(缩略图 - 使用较小分辨率节省流量)
|
||||
// 获取图片 URL(缩略图 - 优先使用后端返回的最小变体以节省流量)
|
||||
const getImageUrl = (image: any) => {
|
||||
if (image.variants && image.variants.length > 0) {
|
||||
return normalizeImageUrl(image.variants[0].url)
|
||||
}
|
||||
return bingPaperApi.getImageUrlByDate(image.date!, '640x480', 'jpg', image.mkt)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user