// 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"` }