package config import "strings" // AboutLink is a configurable link displayed in the about dialog. type AboutLink struct { Title string `json:"title"` Description string `json:"description"` URL string `json:"url"` Icon string `json:"icon"` } // SiteSettings is the single JSON payload stored alongside the SiteConfig row. // The encrypted Umami credential is intentionally kept in this internal type. type SiteSettings struct { SiteName string `json:"siteName"` SiteURL string `json:"siteURL"` SiteIcon string `json:"siteIcon"` SiteDescription string `json:"siteDescription"` SiteKeywords string `json:"siteKeywords"` UserName string `json:"userName"` ProfileImageURL string `json:"profileImageURL"` ICPNumber string `json:"icpNumber"` PoliceNumber string `json:"policeNumber"` PageTitle string `json:"pageTitle"` Favicon string `json:"favicon"` IconLibrary string `json:"iconLibrary"` FontLibrary string `json:"fontLibrary"` FooterYearStart string `json:"footerYearStart"` FooterYearEnd string `json:"footerYearEnd"` ShowVisitTimer bool `json:"showVisitTimer"` RotatingTexts []string `json:"rotatingTexts"` GreetingText string `json:"greetingText"` OnlineStatusText string `json:"onlineStatusText"` FooterLabel string `json:"footerLabel"` ShowAbout bool `json:"showAbout"` ShowSites bool `json:"showSites"` ShowContacts bool `json:"showContacts"` ShowThemeToggle bool `json:"showThemeToggle"` ShowFooter bool `json:"showFooter"` AboutTitle string `json:"aboutTitle"` AboutDescription string `json:"aboutDescription"` AboutLinks []AboutLink `json:"aboutLinks"` SitePageSize int `json:"sitePageSize"` OpenLinksNewTab bool `json:"openLinksInNewTab"` AnalyticsProvider string `json:"analyticsProvider"` UmamiScript string `json:"umamiScript"` UmamiWebsiteID string `json:"umamiWebsiteId"` UmamiAPIMode string `json:"umamiApiMode"` UmamiAPIURL string `json:"umamiApiUrl"` UmamiCredential string `json:"umamiCredential"` UmamiDomains string `json:"umamiDomains"` UmamiDoNotTrack bool `json:"umamiDoNotTrack"` UmamiExcludeSearch bool `json:"umamiExcludeSearch"` UmamiExcludeHash bool `json:"umamiExcludeHash"` UmamiPerformance bool `json:"umamiPerformance"` UmamiTag string `json:"umamiTag"` } var defaultRotatingTexts = []string{ "你好鸭,欢迎来到我的主页!!", "随时可以联系我,期待与你交流。", "愿你历尽千帆,归来仍是少年。", "梦想还是要有的,万一实现了呢?", "I hope you have a happy day every day.", } func DefaultSiteSettings() *SiteSettings { return &SiteSettings{ SiteName: "个人主页", SiteURL: "https://example.com", SiteIcon: "/favicon.ico", SiteDescription: "一个基于Vue3的个人主页", SiteKeywords: "个人主页,Vue3", UserName: "用户", PageTitle: "个人主页", Favicon: "/favicon.ico", FooterYearStart: "", FooterYearEnd: "", ShowVisitTimer: true, RotatingTexts: append([]string(nil), defaultRotatingTexts...), GreetingText: "Hi,", OnlineStatusText: "在线中", FooterLabel: "Made by", ShowAbout: true, ShowSites: true, ShowContacts: true, ShowThemeToggle: true, ShowFooter: true, AboutTitle: "关于本站", AboutLinks: []AboutLink{ {Title: "静态原项目", Description: "Home-Vue", URL: "https://github.com/JLinMr/Home-Vue", Icon: "fab fa-github"}, {Title: "动态现项目", Description: "Home-Vue-go", URL: "https://github.com/QWQLwToo/Home-Vue-go", Icon: "fab fa-github"}, }, SitePageSize: 6, OpenLinksNewTab: true, AnalyticsProvider: "local", UmamiAPIMode: "selfhost", UmamiDoNotTrack: true, UmamiExcludeSearch: false, UmamiExcludeHash: false, UmamiPerformance: false, } } func (s *SiteSettings) Normalize() { defaults := DefaultSiteSettings() if strings.TrimSpace(s.SiteName) == "" { s.SiteName = defaults.SiteName } if strings.TrimSpace(s.SiteURL) == "" { s.SiteURL = defaults.SiteURL } if strings.TrimSpace(s.SiteIcon) == "" { s.SiteIcon = defaults.SiteIcon } if strings.TrimSpace(s.SiteDescription) == "" { s.SiteDescription = defaults.SiteDescription } if strings.TrimSpace(s.SiteKeywords) == "" { s.SiteKeywords = defaults.SiteKeywords } if strings.TrimSpace(s.UserName) == "" { s.UserName = defaults.UserName } if strings.TrimSpace(s.PageTitle) == "" { s.PageTitle = defaults.PageTitle } if strings.TrimSpace(s.Favicon) == "" { s.Favicon = defaults.Favicon } if strings.TrimSpace(s.GreetingText) == "" { s.GreetingText = defaults.GreetingText } if strings.TrimSpace(s.OnlineStatusText) == "" { s.OnlineStatusText = defaults.OnlineStatusText } if strings.TrimSpace(s.FooterLabel) == "" { s.FooterLabel = defaults.FooterLabel } if strings.TrimSpace(s.AboutTitle) == "" { s.AboutTitle = defaults.AboutTitle } if s.SitePageSize != 6 && s.SitePageSize != 9 && s.SitePageSize != 12 { s.SitePageSize = defaults.SitePageSize } if s.AnalyticsProvider != "umami" { s.AnalyticsProvider = "local" } if s.UmamiAPIMode != "cloud" { s.UmamiAPIMode = "selfhost" } filteredTexts := make([]string, 0, 8) for _, text := range s.RotatingTexts { if value := strings.TrimSpace(text); value != "" { filteredTexts = append(filteredTexts, value) } if len(filteredTexts) == 8 { break } } if len(filteredTexts) == 0 { filteredTexts = append([]string(nil), defaults.RotatingTexts...) } s.RotatingTexts = filteredTexts if len(s.AboutLinks) > 8 { s.AboutLinks = s.AboutLinks[:8] } } func (s *SiteSettings) Clone() *SiteSettings { copyValue := *s copyValue.RotatingTexts = append([]string(nil), s.RotatingTexts...) copyValue.AboutLinks = append([]AboutLink(nil), s.AboutLinks...) return ©Value }