diff --git a/backend/internal/handler/admin/setting_handler.go b/backend/internal/handler/admin/setting_handler.go index 13bb4835..f00c213a 100644 --- a/backend/internal/handler/admin/setting_handler.go +++ b/backend/internal/handler/admin/setting_handler.go @@ -60,6 +60,7 @@ type UpdateSettingsRequest struct { SiteSubtitle string `json:"site_subtitle"` ApiBaseUrl string `json:"api_base_url"` ContactInfo string `json:"contact_info"` + DocUrl string `json:"doc_url"` // 默认配置 DefaultConcurrency int `json:"default_concurrency"` @@ -104,6 +105,7 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) { SiteSubtitle: req.SiteSubtitle, ApiBaseUrl: req.ApiBaseUrl, ContactInfo: req.ContactInfo, + DocUrl: req.DocUrl, DefaultConcurrency: req.DefaultConcurrency, DefaultBalance: req.DefaultBalance, } diff --git a/backend/internal/model/setting.go b/backend/internal/model/setting.go index ec95030a..ec937e16 100644 --- a/backend/internal/model/setting.go +++ b/backend/internal/model/setting.go @@ -42,6 +42,7 @@ const ( SettingKeySiteSubtitle = "site_subtitle" // 网站副标题 SettingKeyApiBaseUrl = "api_base_url" // API端点地址(用于客户端配置和导入) SettingKeyContactInfo = "contact_info" // 客服联系方式 + SettingKeyDocUrl = "doc_url" // 文档链接 // 默认配置 SettingKeyDefaultConcurrency = "default_concurrency" // 新用户默认并发量 @@ -80,6 +81,7 @@ type SystemSettings struct { SiteSubtitle string `json:"site_subtitle"` ApiBaseUrl string `json:"api_base_url"` ContactInfo string `json:"contact_info"` + DocUrl string `json:"doc_url"` // 默认配置 DefaultConcurrency int `json:"default_concurrency"` @@ -97,5 +99,6 @@ type PublicSettings struct { SiteSubtitle string `json:"site_subtitle"` ApiBaseUrl string `json:"api_base_url"` ContactInfo string `json:"contact_info"` + DocUrl string `json:"doc_url"` Version string `json:"version"` } diff --git a/backend/internal/service/setting_service.go b/backend/internal/service/setting_service.go index f717bbc8..87c3372c 100644 --- a/backend/internal/service/setting_service.go +++ b/backend/internal/service/setting_service.go @@ -54,6 +54,7 @@ func (s *SettingService) GetPublicSettings(ctx context.Context) (*model.PublicSe model.SettingKeySiteSubtitle, model.SettingKeyApiBaseUrl, model.SettingKeyContactInfo, + model.SettingKeyDocUrl, } settings, err := s.settingRepo.GetMultiple(ctx, keys) @@ -71,6 +72,7 @@ func (s *SettingService) GetPublicSettings(ctx context.Context) (*model.PublicSe SiteSubtitle: s.getStringOrDefault(settings, model.SettingKeySiteSubtitle, "Subscription to API Conversion Platform"), ApiBaseUrl: settings[model.SettingKeyApiBaseUrl], ContactInfo: settings[model.SettingKeyContactInfo], + DocUrl: settings[model.SettingKeyDocUrl], }, nil } @@ -106,6 +108,7 @@ func (s *SettingService) UpdateSettings(ctx context.Context, settings *model.Sys updates[model.SettingKeySiteSubtitle] = settings.SiteSubtitle updates[model.SettingKeyApiBaseUrl] = settings.ApiBaseUrl updates[model.SettingKeyContactInfo] = settings.ContactInfo + updates[model.SettingKeyDocUrl] = settings.DocUrl // 默认配置 updates[model.SettingKeyDefaultConcurrency] = strconv.Itoa(settings.DefaultConcurrency) @@ -210,6 +213,7 @@ func (s *SettingService) parseSettings(settings map[string]string) *model.System SiteSubtitle: s.getStringOrDefault(settings, model.SettingKeySiteSubtitle, "Subscription to API Conversion Platform"), ApiBaseUrl: settings[model.SettingKeyApiBaseUrl], ContactInfo: settings[model.SettingKeyContactInfo], + DocUrl: settings[model.SettingKeyDocUrl], } // 解析整数类型 diff --git a/frontend/src/api/admin/settings.ts b/frontend/src/api/admin/settings.ts index 9b528dcf..56a74ccc 100644 --- a/frontend/src/api/admin/settings.ts +++ b/frontend/src/api/admin/settings.ts @@ -21,6 +21,7 @@ export interface SystemSettings { site_subtitle: string; api_base_url: string; contact_info: string; + doc_url: string; // SMTP settings smtp_host: string; smtp_port: number; diff --git a/frontend/src/i18n/locales/en.ts b/frontend/src/i18n/locales/en.ts index 1d063f57..203868e9 100644 --- a/frontend/src/i18n/locales/en.ts +++ b/frontend/src/i18n/locales/en.ts @@ -2,6 +2,8 @@ export default { // Home Page home: { viewOnGithub: 'View on GitHub', + viewDocs: 'View Documentation', + docs: 'Docs', switchToLight: 'Switch to Light Mode', switchToDark: 'Switch to Dark Mode', dashboard: 'Dashboard', @@ -1077,6 +1079,8 @@ export default { contactInfo: 'Contact Info', contactInfoPlaceholder: 'e.g., QQ: 123456789', contactInfoHint: 'Customer support contact info, displayed on redeem page, profile, etc.', + docUrl: 'Documentation URL', + docUrlHint: 'Link to your documentation site. Leave empty to hide the documentation link.', siteLogo: 'Site Logo', uploadImage: 'Upload Image', remove: 'Remove', diff --git a/frontend/src/i18n/locales/zh.ts b/frontend/src/i18n/locales/zh.ts index d71148ae..4c688365 100644 --- a/frontend/src/i18n/locales/zh.ts +++ b/frontend/src/i18n/locales/zh.ts @@ -2,6 +2,8 @@ export default { // Home Page home: { viewOnGithub: '在 GitHub 上查看', + viewDocs: '查看文档', + docs: '文档', switchToLight: '切换到浅色模式', switchToDark: '切换到深色模式', dashboard: '控制台', @@ -1301,6 +1303,8 @@ export default { contactInfo: '客服联系方式', contactInfoPlaceholder: '例如:QQ: 123456789', contactInfoHint: '填写客服联系方式,将展示在兑换页面、个人资料等位置', + docUrl: '文档链接', + docUrlHint: '文档网站的链接。留空则隐藏文档链接。', siteLogo: '站点Logo', uploadImage: '上传图片', remove: '移除', diff --git a/frontend/src/stores/app.ts b/frontend/src/stores/app.ts index e3d76cff..09140cbe 100644 --- a/frontend/src/stores/app.ts +++ b/frontend/src/stores/app.ts @@ -25,6 +25,7 @@ export const useAppStore = defineStore('app', () => { const siteVersion = ref(''); const contactInfo = ref(''); const apiBaseUrl = ref(''); + const docUrl = ref(''); // Version cache state const versionLoaded = ref(false); @@ -297,6 +298,7 @@ export const useAppStore = defineStore('app', () => { site_subtitle: '', api_base_url: apiBaseUrl.value, contact_info: contactInfo.value, + doc_url: docUrl.value, version: siteVersion.value, }; } @@ -314,6 +316,7 @@ export const useAppStore = defineStore('app', () => { siteVersion.value = data.version || ''; contactInfo.value = data.contact_info || ''; apiBaseUrl.value = data.api_base_url || ''; + docUrl.value = data.doc_url || ''; publicSettingsLoaded.value = true; return data; } catch (error) { @@ -347,6 +350,7 @@ export const useAppStore = defineStore('app', () => { siteVersion, contactInfo, apiBaseUrl, + docUrl, // Version state versionLoaded, diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts index 23592a5d..efb5c8d0 100644 --- a/frontend/src/types/index.ts +++ b/frontend/src/types/index.ts @@ -53,6 +53,7 @@ export interface PublicSettings { site_subtitle: string; api_base_url: string; contact_info: string; + doc_url: string; version: string; } diff --git a/frontend/src/views/HomeView.vue b/frontend/src/views/HomeView.vue index b3da51b3..4d111b89 100644 --- a/frontend/src/views/HomeView.vue +++ b/frontend/src/views/HomeView.vue @@ -24,16 +24,17 @@ - + - - + + @@ -253,10 +254,29 @@ @@ -277,6 +297,7 @@ const authStore = useAuthStore(); const siteName = ref('Sub2API'); const siteLogo = ref(''); const siteSubtitle = ref('AI API Gateway Platform'); +const docUrl = ref(''); // Theme const isDark = ref(document.documentElement.classList.contains('dark')); @@ -322,6 +343,7 @@ onMounted(async () => { siteName.value = settings.site_name || 'Sub2API'; siteLogo.value = settings.site_logo || ''; siteSubtitle.value = settings.site_subtitle || 'AI API Gateway Platform'; + docUrl.value = settings.doc_url || ''; } catch (error) { console.error('Failed to load public settings:', error); } diff --git a/frontend/src/views/admin/SettingsView.vue b/frontend/src/views/admin/SettingsView.vue index 50b34fd5..3206e57b 100644 --- a/frontend/src/views/admin/SettingsView.vue +++ b/frontend/src/views/admin/SettingsView.vue @@ -287,6 +287,20 @@

{{ t('admin.settings.site.contactInfoHint') }}

+ +
+ + +

{{ t('admin.settings.site.docUrlHint') }}

+
+