需求:前台壁纸站支持切换到开源壁纸平台,并能展示后台上传的自家图库, 保留原有「浏览器实时生成」能力(扩展而非替换),PC / 移动双端一致。 设计要点(受服务器 5M 出口带宽约束): - 开源平台图片一律走官方 CDN 直链,后端只代理元数据,零带宽消耗。 - 自建图库落盘到 /data/www/wallpaper,由 nginx 的 /wallpaper/ 直出, Go 服务不参与传图;三档尺寸(480 缩略 / 1920 预览 / 原图仅供下载)。 - 内存缓存平台响应(Bing 1h、搜索类 10min),避免撞第三方配额。 内容: - 平台插件:Bing 每日一图、Picsum、Unsplash、Pexels、Wallhaven。 新增平台 = 写一个 provider_xxx.go 并在 allProviders() 加一行, 刻意不用 init() 自注册,避免隐式副作用。所有适配器支持 config.baseUrl 覆盖,用于绕开 DNS 污染(实测 wallhaven.cc 解析到境外无关 IP)。 - 自建图库:上传(MD5 秒传去重 / 尺寸前置校验 / 失败清理孤儿文件)、 元信息编辑、删除、统计;随机取图用「数总数 → 随机偏移」而非 ORDER BY RAND()。 - 接口:open 组 4 个(sources / list / random / download-track), admin 组 8 个(list / upload / save / delete / stats / source.list|save|test)。 全部 POST 且 URL 无参数,符合工作空间接口规范;上传走 multipart 例外。 - 安全:purity 默认锁死 SFW;apiKey 只回传布尔不回传明文; 保存时留空表示保留旧值;open 组错误信息对外脱敏。 - 配置:clientMaxBodySize 提到 64M(gf 默认 8M 会截断 20MB 原图); wallpaper.root / baseUrl 支持环境变量注入并在占位符未替换时兜底。 依赖:golang.org/x/image@v0.23.0(仅用于缩略图缩放,保持 go 1.23.0 不变)。
122 lines
5.3 KiB
Go
122 lines
5.3 KiB
Go
// Package dto 壁纸模块的数据传输对象。
|
||
//
|
||
// 设计要点:**把「开源平台」和「自建图库」两种来源统一成同一个输出形状
|
||
// (WallpaperItem)**,前端拿到的东西长得一模一样 —— 分页、渲染、下载、
|
||
// 全屏都只需要一套代码。来源差异只在后端消化。
|
||
package dto
|
||
|
||
// WallpaperItem 是壁纸模块对外的统一输出条目。
|
||
//
|
||
// 无论图片来自开源平台还是自建图库,都填这个结构:
|
||
// - FromOpen=true 时 Id 为平台内 id(用于下载上报),Url 指向平台 CDN;
|
||
// - FromOpen=false 时 Id 为库内主键,Url 指向本站 nginx 直出的原图。
|
||
type WallpaperItem struct {
|
||
// ---- 通用 ----
|
||
Id string `json:"id"`
|
||
Title string `json:"title"`
|
||
Width int `json:"width"`
|
||
Height int `json:"height"`
|
||
Orientation int `json:"orientation"` // 0未知 1横版 2竖版 3方形
|
||
// ---- 三档图片地址 ----
|
||
// Thumb 用于列表网格、Preview 用于全屏展示、Full 用于下载。
|
||
// 自建图库这三者分别是 480px 缩略图 / 长边 1920 预览图 / 原图;
|
||
// 开源平台则取各平台 CDN 提供的对应尺寸,没有的就退回上一档。
|
||
ThumbUrl string `json:"thumbUrl"`
|
||
PreviewUrl string `json:"previewUrl"`
|
||
FullUrl string `json:"fullUrl"`
|
||
// ---- 归属 ----
|
||
Source string `json:"source"` // 平台编码,自建图库固定为 "mine"
|
||
SourceName string `json:"sourceName"` // 平台显示名,用于界面标注
|
||
FromOpen bool `json:"fromOpen"` // true=开源平台 false=自建图库
|
||
// ---- 版权信息(自建图库留空)----
|
||
Author string `json:"author"`
|
||
AuthorUrl string `json:"authorUrl"`
|
||
PageUrl string `json:"pageUrl"` // 平台详情页,用于「查看原页面」
|
||
License string `json:"license"` // 许可说明,如 "Unsplash License"
|
||
// ---- 自建图库专有 ----
|
||
Tags string `json:"tags"`
|
||
Category string `json:"category"`
|
||
Filesize int64 `json:"filesize"`
|
||
CreatedAt string `json:"createdAt"`
|
||
}
|
||
|
||
// WallpaperSourceInfo 是开源平台的可用性描述,供前端渲染平台切换器。
|
||
//
|
||
// Enabled 与 Configured 要分开看:前者是用户的开关,后者是凭据是否齐备。
|
||
// 两者都为真时 Available 才为真 —— 前端据此把平台置灰并给出 Hint,
|
||
// 而不是点了没反应。
|
||
type WallpaperSourceInfo struct {
|
||
Code string `json:"code"`
|
||
Name string `json:"name"`
|
||
Enabled int `json:"enabled"`
|
||
Sort int `json:"sort"`
|
||
Configured bool `json:"configured"`
|
||
Available bool `json:"available"`
|
||
Hint string `json:"hint"` // 不可用原因,可用时为空
|
||
Remark string `json:"remark"`
|
||
// Config 是脱敏后的配置(apiKey 只回传是否已设置,不回传明文)。
|
||
HasApiKey bool `json:"hasApiKey"`
|
||
}
|
||
|
||
// WallpaperSourceConfig 对应 wallpaper_source.config 字段的 JSON。
|
||
//
|
||
// 全部字段可选:缺失即用该平台的默认值。解析失败不报错、回退全默认,
|
||
// 避免一个平台的脏配置拖垮整个来源列表。
|
||
type WallpaperSourceConfig struct {
|
||
// ApiKey / ApiSecret 平台凭据。Bing 与 Picsum 不需要。
|
||
ApiKey string `json:"apiKey"`
|
||
ApiSecret string `json:"apiSecret"`
|
||
// DefaultQuery 默认搜索词,用户没传关键词时用。
|
||
DefaultQuery string `json:"defaultQuery"`
|
||
// Purity 分级过滤(Wallhaven):sfw / sketchy / nsfw。默认只放 sfw。
|
||
Purity string `json:"purity"`
|
||
// Categories 分类(Wallhaven):general/anime/people 的组合,逗号分隔。
|
||
Categories string `json:"categories"`
|
||
// BaseUrl 可选覆盖平台接口地址(便于自建反代或走镜像)。
|
||
BaseUrl string `json:"baseUrl"`
|
||
}
|
||
|
||
// WallpaperSourceSaveInput 是后台保存开源平台配置的入参。
|
||
type WallpaperSourceSaveInput struct {
|
||
Code string `json:"code"`
|
||
Name string `json:"name"`
|
||
Enabled int `json:"enabled"`
|
||
Sort int `json:"sort"`
|
||
Remark string `json:"remark"`
|
||
// Config 是 dto.WallpaperSourceConfig 的 JSON 字符串。
|
||
// 其中 apiKey 允许留空 —— 留空表示「不修改已保存的 Key」,
|
||
// 这样后台就不必把密钥明文回传到前端再原样传回来。
|
||
Config string `json:"config"`
|
||
}
|
||
|
||
// WallpaperQuery 是列表查询条件,开源平台与自建图库共用。
|
||
type WallpaperQuery struct {
|
||
Source string // 平台编码;"mine" 表示自建图库
|
||
Query string // 搜索词(自建图库匹配标题/标签/分类)
|
||
Orientation int // 0不限 1横版 2竖版 3方形
|
||
Tag string // 标签(仅自建图库)
|
||
Page int
|
||
Size int
|
||
}
|
||
|
||
// WallpaperSaveInput 是后台编辑壁纸元数据的入参(不含文件本身)。
|
||
type WallpaperSaveInput struct {
|
||
Id uint64 `json:"id"`
|
||
Title string `json:"title"`
|
||
Tags string `json:"tags"`
|
||
Category string `json:"category"`
|
||
Enabled int `json:"enabled"`
|
||
Sort int `json:"sort"`
|
||
Remark string `json:"remark"`
|
||
}
|
||
|
||
// WallpaperStat 是图库概览统计。
|
||
type WallpaperStat struct {
|
||
Total int `json:"total"` // 总数
|
||
Enabled int `json:"enabled"` // 启用数
|
||
Disabled int `json:"disabled"` // 停用数
|
||
Portrait int `json:"portrait"` // 竖版数
|
||
Landscape int `json:"landscape"` // 横版数
|
||
TotalBytes int64 `json:"totalBytes"` // 原图占用字节
|
||
}
|