feat(wallpaper): 平台配置脱敏回显 + 图库元字段补齐
Some checks failed
Build and Deploy (service.xpcool.com) / build-and-deploy (push) Failing after 28s
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 统一处理凭据抹除,避免以后再加配置项时漏抹。
This commit is contained in:
parent
582485ba2b
commit
d0a084b80e
@ -36,6 +36,11 @@ type Item struct {
|
|||||||
Tags string `json:"tags"`
|
Tags string `json:"tags"`
|
||||||
Category string `json:"category"`
|
Category string `json:"category"`
|
||||||
Filesize int64 `json:"filesize"`
|
Filesize int64 `json:"filesize"`
|
||||||
|
// Enabled / Sort / Remark 仅自建图库有值,供后台列表展示与就地编辑;
|
||||||
|
// 开源平台条目恒为默认值,前台不关心。
|
||||||
|
Enabled int `json:"enabled"`
|
||||||
|
Sort int `json:"sort"`
|
||||||
|
Remark string `json:"remark"`
|
||||||
CreatedAt string `json:"createdAt"`
|
CreatedAt string `json:"createdAt"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,6 +55,22 @@ type SourceInfo struct {
|
|||||||
Hint string `json:"hint"` // 不可用原因
|
Hint string `json:"hint"` // 不可用原因
|
||||||
Remark string `json:"remark"`
|
Remark string `json:"remark"`
|
||||||
HasApiKey bool `json:"hasApiKey"` // 只回传「是否已设置」,不回传明文
|
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"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
@ -167,7 +167,9 @@ func (c *Controller) SourceList(ctx context.Context, req *wallpaperv1.AdminSourc
|
|||||||
}
|
}
|
||||||
out := make([]*wallpaperv1.SourceInfo, 0, len(list))
|
out := make([]*wallpaperv1.SourceInfo, 0, len(list))
|
||||||
for i := range list {
|
for i := range list {
|
||||||
out = append(out, toAPISource(&list[i]))
|
// 后台带配置:编辑界面需要回显 defaultQuery / purity / baseUrl 等,
|
||||||
|
// 否则用户只改开关也会把这些字段一并清空。
|
||||||
|
out = append(out, toAPISource(&list[i], true))
|
||||||
}
|
}
|
||||||
return &wallpaperv1.AdminSourceListRes{List: out}, nil
|
return &wallpaperv1.AdminSourceListRes{List: out}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,6 +37,9 @@ func toAPIItem(v *dto.WallpaperItem) *wallpaperv1.Item {
|
|||||||
Tags: v.Tags,
|
Tags: v.Tags,
|
||||||
Category: v.Category,
|
Category: v.Category,
|
||||||
Filesize: v.Filesize,
|
Filesize: v.Filesize,
|
||||||
|
Enabled: v.Enabled,
|
||||||
|
Sort: v.Sort,
|
||||||
|
Remark: v.Remark,
|
||||||
CreatedAt: v.CreatedAt,
|
CreatedAt: v.CreatedAt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -51,8 +54,11 @@ func toAPIItems(list []dto.WallpaperItem) []*wallpaperv1.Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// toAPISource 把平台信息转成接口输出结构。
|
// toAPISource 把平台信息转成接口输出结构。
|
||||||
func toAPISource(v *dto.WallpaperSourceInfo) *wallpaperv1.SourceInfo {
|
//
|
||||||
return &wallpaperv1.SourceInfo{
|
// withConfig 控制是否下发脱敏后的配置:后台需要它回显,前台不需要
|
||||||
|
// (自建反代地址之类属于内部信息,没必要给公网浏览器)。
|
||||||
|
func toAPISource(v *dto.WallpaperSourceInfo, withConfig bool) *wallpaperv1.SourceInfo {
|
||||||
|
out := &wallpaperv1.SourceInfo{
|
||||||
Code: v.Code,
|
Code: v.Code,
|
||||||
Name: v.Name,
|
Name: v.Name,
|
||||||
Enabled: v.Enabled,
|
Enabled: v.Enabled,
|
||||||
@ -63,4 +69,15 @@ func toAPISource(v *dto.WallpaperSourceInfo) *wallpaperv1.SourceInfo {
|
|||||||
Remark: v.Remark,
|
Remark: v.Remark,
|
||||||
HasApiKey: v.HasApiKey,
|
HasApiKey: v.HasApiKey,
|
||||||
}
|
}
|
||||||
|
if withConfig && v.Config != nil {
|
||||||
|
out.Config = &wallpaperv1.SourceConfig{
|
||||||
|
ApiKey: v.Config.ApiKey,
|
||||||
|
ApiSecret: v.Config.ApiSecret,
|
||||||
|
DefaultQuery: v.Config.DefaultQuery,
|
||||||
|
Purity: v.Config.Purity,
|
||||||
|
Categories: v.Config.Categories,
|
||||||
|
BaseUrl: v.Config.BaseUrl,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,7 +37,8 @@ func (c *OpenController) Sources(ctx context.Context, req *wallpaperv1.OpenSourc
|
|||||||
|
|
||||||
out := make([]*wallpaperv1.SourceInfo, 0, len(list))
|
out := make([]*wallpaperv1.SourceInfo, 0, len(list))
|
||||||
for i := range list {
|
for i := range list {
|
||||||
out = append(out, toAPISource(&list[i]))
|
// 前台不带平台配置:公开接口没必要下发 baseUrl 等内部信息。
|
||||||
|
out = append(out, toAPISource(&list[i], false))
|
||||||
}
|
}
|
||||||
return &wallpaperv1.OpenSourceListRes{List: out, MineCount: mineCount}, nil
|
return &wallpaperv1.OpenSourceListRes{List: out, MineCount: mineCount}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,6 +37,11 @@ type WallpaperItem struct {
|
|||||||
Tags string `json:"tags"`
|
Tags string `json:"tags"`
|
||||||
Category string `json:"category"`
|
Category string `json:"category"`
|
||||||
Filesize int64 `json:"filesize"`
|
Filesize int64 `json:"filesize"`
|
||||||
|
// Enabled / Sort / Remark 只有自建图库有值(开源平台条目恒为默认值),
|
||||||
|
// 后台列表要显示启用状态并支持就地编辑,前台不关心这三个字段。
|
||||||
|
Enabled int `json:"enabled"`
|
||||||
|
Sort int `json:"sort"`
|
||||||
|
Remark string `json:"remark"`
|
||||||
CreatedAt string `json:"createdAt"`
|
CreatedAt string `json:"createdAt"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,6 +59,11 @@ type WallpaperSourceInfo struct {
|
|||||||
Available bool `json:"available"`
|
Available bool `json:"available"`
|
||||||
Hint string `json:"hint"` // 不可用原因,可用时为空
|
Hint string `json:"hint"` // 不可用原因,可用时为空
|
||||||
Remark string `json:"remark"`
|
Remark string `json:"remark"`
|
||||||
|
// Config 是脱敏后的平台配置,供后台编辑界面回显。
|
||||||
|
// apiKey / apiSecret 一律置空不回传明文,是否已设置由 HasApiKey 表达;
|
||||||
|
// 界面上留空提交即表示「不修改已保存的 Key」。
|
||||||
|
// 前台接口不下发本字段(避免暴露自建反代地址等内部信息)。
|
||||||
|
Config *WallpaperSourceConfig `json:"config"`
|
||||||
// Config 是脱敏后的配置(apiKey 只回传是否已设置,不回传明文)。
|
// Config 是脱敏后的配置(apiKey 只回传是否已设置,不回传明文)。
|
||||||
HasApiKey bool `json:"hasApiKey"`
|
HasApiKey bool `json:"hasApiKey"`
|
||||||
}
|
}
|
||||||
|
|||||||
@ -161,6 +161,9 @@ func (s *service) toItem(e *entity.Wallpaper) dto.WallpaperItem {
|
|||||||
Tags: e.Tags,
|
Tags: e.Tags,
|
||||||
Category: e.Category,
|
Category: e.Category,
|
||||||
Filesize: e.Filesize,
|
Filesize: e.Filesize,
|
||||||
|
Enabled: e.Enabled,
|
||||||
|
Sort: e.Sort,
|
||||||
|
Remark: e.Remark,
|
||||||
CreatedAt: e.CreatedAt,
|
CreatedAt: e.CreatedAt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,6 +48,7 @@ func (s *service) Sources(ctx context.Context) ([]dto.WallpaperSourceInfo, error
|
|||||||
Configured: !p.RequiresKey(),
|
Configured: !p.RequiresKey(),
|
||||||
Available: false,
|
Available: false,
|
||||||
Hint: "尚未在后台启用",
|
Hint: "尚未在后台启用",
|
||||||
|
Config: sanitizeSourceConfig(dto.WallpaperSourceConfig{}),
|
||||||
})
|
})
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -61,6 +62,7 @@ func (s *service) Sources(ctx context.Context) ([]dto.WallpaperSourceInfo, error
|
|||||||
Configured: configured,
|
Configured: configured,
|
||||||
Available: e.Enabled == 1 && configured,
|
Available: e.Enabled == 1 && configured,
|
||||||
Remark: e.Remark,
|
Remark: e.Remark,
|
||||||
|
Config: sanitizeSourceConfig(cfg),
|
||||||
HasApiKey: cfg.ApiKey != "",
|
HasApiKey: cfg.ApiKey != "",
|
||||||
}
|
}
|
||||||
switch {
|
switch {
|
||||||
@ -216,3 +218,15 @@ func ParseSourceConfig(raw string) dto.WallpaperSourceConfig {
|
|||||||
}
|
}
|
||||||
return cfg
|
return cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sanitizeSourceConfig 生成可安全下发给前端的配置副本:抹掉全部凭据。
|
||||||
|
//
|
||||||
|
// 后台需要它来「回显」用户此前填过的 defaultQuery / purity / baseUrl,
|
||||||
|
// 否则用户只想改个开关也会把这些字段一起清空;
|
||||||
|
// 但凭据明文不能出后端,故这里只清 apiKey / apiSecret,
|
||||||
|
// 是否已设置改由 HasApiKey 布尔表达。
|
||||||
|
func sanitizeSourceConfig(cfg dto.WallpaperSourceConfig) *dto.WallpaperSourceConfig {
|
||||||
|
cfg.ApiKey = ""
|
||||||
|
cfg.ApiSecret = ""
|
||||||
|
return &cfg
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user