Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
2e7818d6
Commit
2e7818d6
authored
Dec 24, 2025
by
shaw
Browse files
feat(settings): 添加文档链接配置功能
- 后台系统设置新增文档链接(doc_url)配置项 - 首页顶部导航栏显示文档链接图标(条件渲染) - Footer区域添加文档链接和GitHub链接 - 支持中英文国际化
parent
e65e9587
Changes
10
Hide whitespace changes
Inline
Side-by-side
backend/internal/handler/admin/setting_handler.go
View file @
2e7818d6
...
...
@@ -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
,
}
...
...
backend/internal/model/setting.go
View file @
2e7818d6
...
...
@@ -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"`
}
backend/internal/service/setting_service.go
View file @
2e7818d6
...
...
@@ -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
],
}
// 解析整数类型
...
...
frontend/src/api/admin/settings.ts
View file @
2e7818d6
...
...
@@ -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
;
...
...
frontend/src/i18n/locales/en.ts
View file @
2e7818d6
...
...
@@ -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
'
,
...
...
frontend/src/i18n/locales/zh.ts
View file @
2e7818d6
...
...
@@ -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
:
'
移除
'
,
...
...
frontend/src/stores/app.ts
View file @
2e7818d6
...
...
@@ -25,6 +25,7 @@ export const useAppStore = defineStore('app', () => {
const
siteVersion
=
ref
<
string
>
(
''
);
const
contactInfo
=
ref
<
string
>
(
''
);
const
apiBaseUrl
=
ref
<
string
>
(
''
);
const
docUrl
=
ref
<
string
>
(
''
);
// Version cache state
const
versionLoaded
=
ref
<
boolean
>
(
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
,
...
...
frontend/src/types/index.ts
View file @
2e7818d6
...
...
@@ -53,6 +53,7 @@ export interface PublicSettings {
site_subtitle
:
string
;
api_base_url
:
string
;
contact_info
:
string
;
doc_url
:
string
;
version
:
string
;
}
...
...
frontend/src/views/HomeView.vue
View file @
2e7818d6
...
...
@@ -24,16 +24,17 @@
<!-- Language Switcher -->
<LocaleSwitcher
/>
<!--
GitHub
Link -->
<!--
Doc
Link -->
<a
:href=
"githubUrl"
v-if=
"docUrl"
:href=
"docUrl"
target=
"_blank"
rel=
"noopener noreferrer"
class=
"p-2 rounded-lg text-gray-500 hover:text-gray-700 dark:text-dark-400 dark:hover:text-white hover:bg-gray-100 dark:hover:bg-dark-800 transition-colors"
:title=
"t('home.view
OnGithub
')"
:title=
"t('home.view
Docs
')"
>
<svg
class=
"w-5 h-5"
fill=
"
currentColor
"
viewBox=
"0 0 24 24"
>
<path
fill-rule=
"evenodd"
clip-rule=
"evenodd"
d=
"M12 2C6.477 2 2 6.477 2 12c0 4.42 2.865 8.17 6.839 9.49.5.092.682-.217.682-.482 0-.237-.008-.866-.013-1.7-2.782.604-3.369-1.34-3.369-1.34-.454-1.156-1.11-1.464-1.11-1.464-.908-.62.069-.608.069-.608 1.003.07 1.531 1.03 1.531 1.03.892 1.529 2.341 1.087 2.91.831.092-.646.35-1.086.636-1.336-2.22-.253-4.555-1.11-4.555-4.943 0-1.091.39-1.984 1.029-2.683-.103-.253-.446-1.27.098-2.647 0 0 .84-.269 2.75 1.025A9.578 9.578 0 0112 6.836c.85.004 1.705.114 2.504.336 1.909-1.294 2.747-1.025 2.747-1.025.546 1.377.203 2.394.1 2.647.64.699 1.028 1.592 1.028 2.683 0 3.842-2.339 4.687-4.566 4.935.359.309.678.919.678 1.852 0 1.336-.012 2.415-.012 2.743 0 .267.18.578.688.48C19.138 20.167 22 16.418 22 12c0-5.523-4.477-10-10-10z
"
/>
<svg
class=
"w-5 h-5"
fill=
"
none
"
viewBox=
"0 0 24 24"
stroke=
"currentColor"
stroke-width=
"1.5"
>
<path
stroke-linecap=
"round"
stroke-linejoin=
"round"
d=
"M12 6.042A8.967 8.967 0 006 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 016 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 016-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0018 18a8.967 8.967 0 00-6 2.292m0-14.25v14.25
"
/>
</svg>
</a>
...
...
@@ -253,10 +254,29 @@
<!-- Footer -->
<footer
class=
"relative z-10 px-6 py-8 border-t border-gray-200/50 dark:border-dark-800/50"
>
<div
class=
"max-w-6xl mx-auto
text-center
"
>
<div
class=
"max-w-6xl mx-auto
flex flex-col sm:flex-row items-center justify-center gap-4 text-center sm:text-left
"
>
<p
class=
"text-sm text-gray-500 dark:text-dark-400"
>
©
{{
currentYear
}}
{{
siteName
}}
.
{{
t
(
'
home.footer.allRightsReserved
'
)
}}
</p>
<div
class=
"flex items-center gap-4"
>
<a
v-if=
"docUrl"
:href=
"docUrl"
target=
"_blank"
rel=
"noopener noreferrer"
class=
"text-sm text-gray-500 hover:text-gray-700 dark:text-dark-400 dark:hover:text-white transition-colors"
>
{{
t
(
'
home.docs
'
)
}}
</a>
<a
:href=
"githubUrl"
target=
"_blank"
rel=
"noopener noreferrer"
class=
"text-sm text-gray-500 hover:text-gray-700 dark:text-dark-400 dark:hover:text-white transition-colors"
>
GitHub
</a>
</div>
</div>
</footer>
</div>
...
...
@@ -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
);
}
...
...
frontend/src/views/admin/SettingsView.vue
View file @
2e7818d6
...
...
@@ -287,6 +287,20 @@
<p
class=
"mt-1.5 text-xs text-gray-500 dark:text-gray-400"
>
{{
t
(
'
admin.settings.site.contactInfoHint
'
)
}}
</p>
</div>
<!-- Doc URL -->
<div>
<label
class=
"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
>
{{
t
(
'
admin.settings.site.docUrl
'
)
}}
</label>
<input
v-model=
"form.doc_url"
type=
"url"
class=
"input font-mono text-sm"
placeholder=
"https://docs.example.com"
/>
<p
class=
"mt-1.5 text-xs text-gray-500 dark:text-gray-400"
>
{{
t
(
'
admin.settings.site.docUrlHint
'
)
}}
</p>
</div>
<!-- Site Logo Upload -->
<div>
<label
class=
"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
>
...
...
@@ -541,6 +555,7 @@ const form = reactive<SystemSettings>({
site_subtitle
:
'
Subscription to API Conversion Platform
'
,
api_base_url
:
''
,
contact_info
:
''
,
doc_url
:
''
,
smtp_host
:
''
,
smtp_port
:
587
,
smtp_username
:
''
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment