完善站点运营设置:分路由管理、登录可见评论、邮件模板内联与关闭注册 SSR。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -9,16 +9,12 @@ import (
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// SettingKeyTimelineGitImport 提交导入适配器 JSON(不进公开 settings)
|
||||
const SettingKeyTimelineGitImport = "timeline_git_import"
|
||||
|
||||
const (
|
||||
maxAdapterJSONBytes = 64 * 1024
|
||||
maxAdapterRegexLen = 512
|
||||
maxAdapterSources = 20
|
||||
maxAdapterRegexLen = 512
|
||||
maxAdapterSources = 20
|
||||
)
|
||||
|
||||
// TimelineGitAdapter 声明式提交导入配置
|
||||
// TimelineGitAdapter 声明式提交导入配置(内置,不可在站点设置中编辑)
|
||||
type TimelineGitAdapter struct {
|
||||
MaxPages int `json:"max_pages"`
|
||||
MaxCommits int `json:"max_commits"`
|
||||
@@ -27,15 +23,15 @@ type TimelineGitAdapter struct {
|
||||
|
||||
// TimelineGitSourceCfg 单个 Git 源
|
||||
type TimelineGitSourceCfg struct {
|
||||
ID string `json:"id"`
|
||||
Host string `json:"host"` // 精确主机或 "*"
|
||||
ListPath string `json:"list_path"`
|
||||
CommitPath string `json:"commit_path,omitempty"` // 单条 commit 页
|
||||
APIURL string `json:"api_url"`
|
||||
CommitAPI string `json:"commit_api,omitempty"`
|
||||
Query map[string]string `json:"query"`
|
||||
Headers map[string]string `json:"headers"`
|
||||
Pagination string `json:"pagination"` // link_header | query_page
|
||||
ID string `json:"id"`
|
||||
Host string `json:"host"` // 精确主机或 "*"
|
||||
ListPath string `json:"list_path"`
|
||||
CommitPath string `json:"commit_path,omitempty"` // 单条 commit 页
|
||||
APIURL string `json:"api_url"`
|
||||
CommitAPI string `json:"commit_api,omitempty"`
|
||||
Query map[string]string `json:"query"`
|
||||
Headers map[string]string `json:"headers"`
|
||||
Pagination string `json:"pagination"` // link_header | query_page
|
||||
Item TimelineGitItemMap `json:"item"`
|
||||
}
|
||||
|
||||
@@ -97,29 +93,6 @@ func DefaultTimelineGitAdapterJSON() string {
|
||||
}`
|
||||
}
|
||||
|
||||
// ValidateTimelineGitAdapterJSON 校验并规范化适配器 JSON
|
||||
func ValidateTimelineGitAdapterJSON(raw string) (string, error) {
|
||||
raw = strings.TrimSpace(raw)
|
||||
if raw == "" {
|
||||
return "", errors.New("适配器不能为空")
|
||||
}
|
||||
if len(raw) > maxAdapterJSONBytes {
|
||||
return "", errors.New("适配器过大")
|
||||
}
|
||||
var cfg TimelineGitAdapter
|
||||
if err := json.Unmarshal([]byte(raw), &cfg); err != nil {
|
||||
return "", fmt.Errorf("JSON 无效: %w", err)
|
||||
}
|
||||
if err := validateTimelineGitAdapter(&cfg); err != nil {
|
||||
return "", err
|
||||
}
|
||||
out, err := json.MarshalIndent(cfg, "", " ")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(out), nil
|
||||
}
|
||||
|
||||
func validateTimelineGitAdapter(cfg *TimelineGitAdapter) error {
|
||||
if cfg.MaxPages < 1 || cfg.MaxPages > 50 {
|
||||
return errors.New("max_pages 须在 1–50")
|
||||
@@ -177,54 +150,14 @@ func validateTimelineGitAdapter(cfg *TimelineGitAdapter) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TimelineGitAdapterJSON 读取站点适配器;缺行返回默认
|
||||
func (s *SettingService) TimelineGitAdapterJSON() (string, error) {
|
||||
v, found, err := s.getValue(SettingKeyTimelineGitImport)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if !found || strings.TrimSpace(v) == "" {
|
||||
return DefaultTimelineGitAdapterJSON(), nil
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// SetTimelineGitAdapterJSON 保存适配器(已校验)
|
||||
func (s *SettingService) SetTimelineGitAdapterJSON(raw string) (string, error) {
|
||||
normalized, err := ValidateTimelineGitAdapterJSON(raw)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if err := s.putValue(SettingKeyTimelineGitImport, normalized); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return normalized, nil
|
||||
}
|
||||
|
||||
// ResetTimelineGitAdapter 恢复默认
|
||||
func (s *SettingService) ResetTimelineGitAdapter() (string, error) {
|
||||
def := DefaultTimelineGitAdapterJSON()
|
||||
normalized, err := ValidateTimelineGitAdapterJSON(def)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if err := s.putValue(SettingKeyTimelineGitImport, normalized); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return normalized, nil
|
||||
}
|
||||
|
||||
func (s *SettingService) loadTimelineGitAdapter() (*TimelineGitAdapter, error) {
|
||||
raw, err := s.TimelineGitAdapterJSON()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
raw := DefaultTimelineGitAdapterJSON()
|
||||
var cfg TimelineGitAdapter
|
||||
if err := json.Unmarshal([]byte(raw), &cfg); err != nil {
|
||||
return nil, errors.New("适配器无效,请在站点设置中修复或恢复默认")
|
||||
return nil, errors.New("内置提交导入规则无效")
|
||||
}
|
||||
if err := validateTimelineGitAdapter(&cfg); err != nil {
|
||||
return nil, errors.New("适配器无效,请在站点设置中修复或恢复默认")
|
||||
return nil, errors.New("内置提交导入规则无效")
|
||||
}
|
||||
return &cfg, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user