feat: 新增发布日期自选、站点 Logo、回收站清空等十项改进
- 编辑页标题改 filled 变体;标签改 tags 选择器(可勾选既有/输入新建) - 笔记发布日期可自选(schema v2 新增 published_at 并回填),前台展示发布日期 - 登录页移除「请输入管理密码以继续」「连续失败将被暂时锁定」文案 - 站点设置每页条数收敛为 10/20/30/50 选择器,后端白名单同源校验 - 站点设置两卡片宽屏左右/窄屏上下;修改密码按钮改常规大小 - 后台各页顶栏固定高度,切换页面不再抖动 - 站点 Logo:settings 新增 site_logo(站内路径),gc/孤儿清单豁免 Logo 图片, 博客 header 站点名前展示,设置页支持上传/更换/清除 - 回收站右上角一键清空(DELETE /api/admin/trash,含确认弹窗) - pn init 写入 Markdown 语法示例文档(slug welcome,公开)与程序生成的示例图片
This commit is contained in:
@@ -14,6 +14,7 @@ const (
|
||||
KeySiteDesc = "site_desc"
|
||||
KeyPageSize = "page_size"
|
||||
KeyBeianNo = "beian_no"
|
||||
KeySiteLogo = "site_logo"
|
||||
)
|
||||
|
||||
// GetSetting 读取单个设置。
|
||||
@@ -39,6 +40,7 @@ type SiteSettings struct {
|
||||
SiteDesc string `json:"site_desc"`
|
||||
PageSize int `json:"page_size"`
|
||||
BeianNo string `json:"beian_no"`
|
||||
SiteLogo string `json:"site_logo"`
|
||||
}
|
||||
|
||||
// Defaults,未初始化时兜底。
|
||||
@@ -49,6 +51,15 @@ const (
|
||||
DefaultBeianNo = ""
|
||||
)
|
||||
|
||||
// ValidPageSize 每页条数可选项(前端选择器同源:10/20/30/50)。
|
||||
func ValidPageSize(n int) bool {
|
||||
switch n {
|
||||
case 10, 20, 30, 50:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// GetSiteSettings 读取站点设置(白名单键,带默认值)。
|
||||
func (s *Store) GetSiteSettings() (*SiteSettings, error) {
|
||||
ss := &SiteSettings{SiteTitle: DefaultSiteTitle, SiteDesc: DefaultSiteDesc, PageSize: DefaultPageSize, BeianNo: DefaultBeianNo}
|
||||
@@ -65,8 +76,9 @@ func (s *Store) GetSiteSettings() (*SiteSettings, error) {
|
||||
if v, ok, err := s.GetSetting(KeyPageSize); err != nil {
|
||||
return nil, err
|
||||
} else if ok {
|
||||
// strconv.Atoi 全文解析:拒绝 "10abc" 类部分解析的脏值(评审 round2 P2-13)
|
||||
if n, err := strconv.Atoi(strings.TrimSpace(v)); err == nil && n >= 1 && n <= 100 {
|
||||
// strconv.Atoi 全文解析:拒绝 "10abc" 类部分解析的脏值(评审 round2 P2-13);
|
||||
// 脏值/越界值回退默认,而非落入任意 [1,100]
|
||||
if n, err := strconv.Atoi(strings.TrimSpace(v)); err == nil && ValidPageSize(n) {
|
||||
ss.PageSize = n
|
||||
}
|
||||
}
|
||||
@@ -75,5 +87,25 @@ func (s *Store) GetSiteSettings() (*SiteSettings, error) {
|
||||
} else if ok {
|
||||
ss.BeianNo = strings.TrimSpace(v)
|
||||
}
|
||||
if v, ok, err := s.GetSetting(KeySiteLogo); err != nil {
|
||||
return nil, err
|
||||
} else if ok {
|
||||
ss.SiteLogo = strings.TrimSpace(v)
|
||||
}
|
||||
return ss, nil
|
||||
}
|
||||
|
||||
// logoImageID 从 site_logo 设置解析受 GC 保护的图片 id(无 logo 或非本站图片路径返回 0)。
|
||||
func (s *Store) logoImageID() int64 {
|
||||
v, ok, err := s.GetSetting(KeySiteLogo)
|
||||
if err != nil || !ok || v == "" {
|
||||
return 0
|
||||
}
|
||||
if m := imageRefRe.FindStringSubmatch(v); m != nil {
|
||||
var id int64
|
||||
if _, err := fmtSscanInt(m[1], &id); err == nil && id > 0 {
|
||||
return id
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user