Some checks failed
Build and Deploy (service.xpcool.com) / build-and-deploy (push) Failing after 28s
后台做完界面才发现的两个接口缺口: 1) 平台配置不回显 → 用户只改一个开关,defaultQuery / purity / baseUrl 会被一起清空(SaveSource 只对 apiKey/apiSecret 做了"留空即保留")。 现在 Sources() 返回脱敏后的 config(凭据一律置空,是否已设置由 HasApiKey 表达),前台接口不下发该字段 —— toAPISource 加 withConfig 开关,公开接口没必要泄露自建反代地址等内部信息。 2) Item 缺 enabled / sort / remark → 后台列表无法显示启用状态, 编辑抽屉也拿不到当前值。补齐字段并在 library.toItem 中填充, 开源平台条目保持默认值(这三个字段对前台无意义)。 另抽出 sanitizeSourceConfig 统一处理凭据抹除,避免以后再加配置项时漏抹。
258 lines
9.7 KiB
Go
258 lines
9.7 KiB
Go
// Package wallpaper_v1 壁纸模块接口契约。
|
||
//
|
||
// 分成两组:
|
||
// - open 组(/api/service/open/wallpaper/*):给 xpcool.com 前台调用,免鉴权;
|
||
// - admin 组(/api/service/admin/wallpaper/*):后台管理,走 RBAC 权限。
|
||
//
|
||
// 规范(2026-08-27 起):全部 POST;URL 不含参数;入参一律 body。
|
||
// 唯一例外是「上传」——文件必须走 multipart,其余字段随之走表单而不是 JSON。
|
||
package wallpaper
|
||
|
||
import "github.com/gogf/gf/v2/frame/g"
|
||
import "github.com/gogf/gf/v2/net/ghttp"
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// 公共数据结构
|
||
// ---------------------------------------------------------------------------
|
||
|
||
// Item 是壁纸的统一输出条目。开源平台与自建图库填的是同一个结构,
|
||
// 前端因此只需要一套渲染逻辑。
|
||
type Item 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方形
|
||
ThumbUrl string `json:"thumbUrl"` // 列表网格用(480px)
|
||
PreviewUrl string `json:"previewUrl"` // 全屏展示用(长边 1920)
|
||
FullUrl string `json:"fullUrl"` // 下载用(原图)
|
||
Source string `json:"source"`
|
||
SourceName string `json:"sourceName"`
|
||
FromOpen bool `json:"fromOpen"`
|
||
Author string `json:"author"`
|
||
AuthorUrl string `json:"authorUrl"`
|
||
PageUrl string `json:"pageUrl"`
|
||
License string `json:"license"`
|
||
Tags string `json:"tags"`
|
||
Category string `json:"category"`
|
||
Filesize int64 `json:"filesize"`
|
||
// Enabled / Sort / Remark 仅自建图库有值,供后台列表展示与就地编辑;
|
||
// 开源平台条目恒为默认值,前台不关心。
|
||
Enabled int `json:"enabled"`
|
||
Sort int `json:"sort"`
|
||
Remark string `json:"remark"`
|
||
CreatedAt string `json:"createdAt"`
|
||
}
|
||
|
||
// SourceInfo 开源平台的可用性描述。
|
||
type SourceInfo 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"`
|
||
HasApiKey bool `json:"hasApiKey"` // 只回传「是否已设置」,不回传明文
|
||
// Config 是脱敏后的平台配置,供后台编辑界面回显(前台接口不下发)。
|
||
// apiKey / apiSecret 恒为空串 —— 提交时留空即表示「不修改已保存的 Key」。
|
||
Config *SourceConfig `json:"config"`
|
||
}
|
||
|
||
// SourceConfig 是平台可配置项,与 dto.WallpaperSourceConfig 一一对应。
|
||
type SourceConfig struct {
|
||
ApiKey string `json:"apiKey"`
|
||
ApiSecret string `json:"apiSecret"`
|
||
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"`
|
||
}
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// open 组:前台
|
||
// ---------------------------------------------------------------------------
|
||
|
||
// OpenSourceListReq 取全部来源清单(含开源平台 + 自建图库计数)。
|
||
type OpenSourceListReq struct {
|
||
g.Meta `path:"/wallpaper/sources" method:"post" tags:"Open/Wallpaper" summary:"壁纸来源清单"`
|
||
}
|
||
|
||
type OpenSourceListRes struct {
|
||
List []*SourceInfo `json:"list"`
|
||
// MineCount 只统计「启用」的自建图片数量,为 0 时前台隐藏「我的图库」入口
|
||
MineCount int `json:"mineCount"`
|
||
}
|
||
|
||
// OpenListReq 按来源分页取图。
|
||
type OpenListReq struct {
|
||
g.Meta `path:"/wallpaper/list" method:"post" tags:"Open/Wallpaper" summary:"壁纸列表(按来源)"`
|
||
Source string `json:"source" d:"mine" dc:"来源编码:mine=自建图库,其余为平台编码"`
|
||
Query string `json:"query" dc:"搜索词(仅部分平台与自建图库支持)"`
|
||
Orientation int `json:"orientation" dc:"0不限 1横版 2竖版 3方形"`
|
||
Tag string `json:"tag" dc:"标签(仅自建图库)"`
|
||
Page int `json:"page" d:"1"`
|
||
Size int `json:"size" d:"24"`
|
||
}
|
||
|
||
type OpenListRes struct {
|
||
List []*Item `json:"list"`
|
||
Total int `json:"total"`
|
||
Page int `json:"page"`
|
||
Size int `json:"size"`
|
||
}
|
||
|
||
// OpenRandomReq 跨来源随机取一张。
|
||
type OpenRandomReq struct {
|
||
g.Meta `path:"/wallpaper/random" method:"post" tags:"Open/Wallpaper" summary:"随机取一张壁纸"`
|
||
Sources []string `json:"sources" dc:"限定来源;为空则在所有可用来源中随机"`
|
||
Orientation int `json:"orientation" dc:"0不限 1横版 2竖版 3方形"`
|
||
}
|
||
|
||
type OpenRandomRes struct {
|
||
Item *Item `json:"item"`
|
||
}
|
||
|
||
// OpenTrackDownloadReq 通知平台「这张图被下载了」。
|
||
// 目前只有 Unsplash 需要(其 API 许可的硬性要求),其它平台为空操作。
|
||
type OpenTrackDownloadReq struct {
|
||
g.Meta `path:"/wallpaper/download-track" method:"post" tags:"Open/Wallpaper" summary:"下载回调(平台统计)"`
|
||
Source string `json:"source"`
|
||
Id string `json:"id"`
|
||
}
|
||
|
||
type OpenTrackDownloadRes struct {
|
||
Message string `json:"message"`
|
||
}
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// admin 组:自建图库
|
||
// ---------------------------------------------------------------------------
|
||
|
||
// AdminListReq 后台图库列表(含已停用项)。
|
||
type AdminListReq struct {
|
||
g.Meta `path:"/wallpaper/list" method:"post" tags:"Admin/Wallpaper" summary:"图库列表(含停用)"`
|
||
Query string `json:"query"`
|
||
Orientation int `json:"orientation"`
|
||
Enabled int `json:"enabled" d:"-1" dc:"-1全部 0停用 1启用"`
|
||
Page int `json:"page" d:"1"`
|
||
Size int `json:"size" d:"24"`
|
||
}
|
||
|
||
type AdminListRes struct {
|
||
List []*Item `json:"list"`
|
||
Total int `json:"total"`
|
||
}
|
||
|
||
// AdminUploadReq 上传壁纸(文件走 multipart,其余字段为表单字段)。
|
||
type AdminUploadReq struct {
|
||
g.Meta `path:"/wallpaper/upload" method:"post" mime:"multipart/form-data" tags:"Admin/Wallpaper" summary:"上传壁纸(可多选)"`
|
||
Files []*ghttp.UploadFile `json:"files" type:"file" dc:"图片文件,可多选"`
|
||
Title string `json:"title" dc:"标题,留空则用文件名"`
|
||
Tags string `json:"tags"`
|
||
Category string `json:"category"`
|
||
Sort int `json:"sort"`
|
||
}
|
||
|
||
// UploadItem 单个文件的处理结果。
|
||
// 批量上传时允许部分失败,故逐条返回,而不是整体成功/失败。
|
||
type UploadItem struct {
|
||
FileName string `json:"fileName"`
|
||
Ok bool `json:"ok"`
|
||
Duplicated bool `json:"duplicated"` // 内容重复,命中了已有图片(秒传)
|
||
Message string `json:"message"`
|
||
Item *Item `json:"item"`
|
||
}
|
||
|
||
type AdminUploadRes struct {
|
||
List []*UploadItem `json:"list"`
|
||
OkCount int `json:"okCount"`
|
||
FailCount int `json:"failCount"`
|
||
}
|
||
|
||
// AdminSaveReq 编辑壁纸元数据(不涉及文件)。
|
||
type AdminSaveReq struct {
|
||
g.Meta `path:"/wallpaper/save" method:"post" tags:"Admin/Wallpaper" summary:"保存壁纸信息"`
|
||
Id uint64 `json:"id" v:"required"`
|
||
Title string `json:"title"`
|
||
Tags string `json:"tags"`
|
||
Category string `json:"category"`
|
||
Enabled int `json:"enabled"`
|
||
Sort int `json:"sort"`
|
||
Remark string `json:"remark"`
|
||
}
|
||
|
||
type AdminSaveRes struct {
|
||
Message string `json:"message"`
|
||
}
|
||
|
||
// AdminDeleteReq 删除壁纸(同时清理原图与派生图)。
|
||
type AdminDeleteReq struct {
|
||
g.Meta `path:"/wallpaper/delete" method:"post" tags:"Admin/Wallpaper" summary:"删除壁纸"`
|
||
Id uint64 `json:"id" v:"required"`
|
||
}
|
||
|
||
type AdminDeleteRes struct {
|
||
Message string `json:"message"`
|
||
}
|
||
|
||
// AdminStatsReq 图库概览。
|
||
type AdminStatsReq struct {
|
||
g.Meta `path:"/wallpaper/stats" method:"post" tags:"Admin/Wallpaper" summary:"图库统计"`
|
||
}
|
||
|
||
type AdminStatsRes 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"`
|
||
}
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// admin 组:开源平台配置
|
||
// ---------------------------------------------------------------------------
|
||
|
||
// AdminSourceListReq 平台配置列表。
|
||
type AdminSourceListReq struct {
|
||
g.Meta `path:"/wallpaper/source/list" method:"post" tags:"Admin/Wallpaper" summary:"平台配置列表"`
|
||
}
|
||
|
||
type AdminSourceListRes struct {
|
||
List []*SourceInfo `json:"list"`
|
||
}
|
||
|
||
// AdminSourceSaveReq 保存平台配置。
|
||
type AdminSourceSaveReq struct {
|
||
g.Meta `path:"/wallpaper/source/save" method:"post" tags:"Admin/Wallpaper" summary:"保存平台配置"`
|
||
Code string `json:"code" v:"required"`
|
||
Name string `json:"name"`
|
||
Enabled int `json:"enabled"`
|
||
Sort int `json:"sort"`
|
||
Remark string `json:"remark"`
|
||
// Config 是平台配置的 JSON 字符串。
|
||
// 其中 apiKey 留空表示「不修改已保存的 Key」—— 界面不回传密钥明文,
|
||
// 用户只改开关时不必重新粘贴。
|
||
Config string `json:"config"`
|
||
}
|
||
|
||
type AdminSourceSaveRes struct {
|
||
Message string `json:"message"`
|
||
}
|
||
|
||
// AdminSourceTestReq 测试平台连通性。
|
||
type AdminSourceTestReq struct {
|
||
g.Meta `path:"/wallpaper/source/test" method:"post" tags:"Admin/Wallpaper" summary:"测试平台连通性"`
|
||
Code string `json:"code" v:"required"`
|
||
}
|
||
|
||
type AdminSourceTestRes struct {
|
||
Ok bool `json:"ok"`
|
||
Message string `json:"message"`
|
||
}
|