优化图片处理逻辑:优先使用最小变体以节省流量,并新增 normalizeImageUrl 函数处理相对路径问题

This commit is contained in:
2026-01-30 14:28:14 +08:00
parent 845dc7d045
commit 52fb8c9328
4 changed files with 85 additions and 3 deletions

View File

@@ -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{}

View File

@@ -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) {

View File

@@ -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 状态码枚举
*/

View File

@@ -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)
}