feat(captcha): add provider configuration tabs

This commit is contained in:
kate522 committed 2026-09-02 16:55:57 +08:00
1 parent ff4ec1eb43
commit 0985d0cb0a
4 files changed
+57 -41

No files matched your search

+43 -25
View File
@@ -17,30 +17,29 @@
>
<template
v-if="isPermissionsLogin"
#field-tencent="{ value, setValue }"
#group-providers
>
<TencentConfig :model-value="value || {}" @update:model-value="setValue" @clear-secret="markCaptchaSecretForClear('tencent', $event)" @restore-secret="unmarkCaptchaSecretForClear('tencent', $event)" />
</template>
<template
v-if="isPermissionsLogin"
#field-aliyun="{ value, setValue }"
>
<AliyunConfig :model-value="value || {}" @update:model-value="setValue" @clear-secret="markCaptchaSecretForClear('aliyun', $event)" @restore-secret="unmarkCaptchaSecretForClear('aliyun', $event)" />
</template>
<template
v-if="isPermissionsLogin"
#field-cloudflare="{ value, setValue }"
>
<CloudflareConfig :model-value="value || {}" @update:model-value="setValue" @clear-secret="markCaptchaSecretForClear('cloudflare', $event)" @restore-secret="unmarkCaptchaSecretForClear('cloudflare', $event)" />
</template>
<template
v-if="isPermissionsLogin"
#field-geetest="{ value, setValue }"
>
<GeetestConfig :model-value="value || {}" @update:model-value="setValue" @clear-secret="markCaptchaSecretForClear('geetest', $event)" @restore-secret="unmarkCaptchaSecretForClear('geetest', $event)" />
<n-tabs
v-model:value="captchaProviderTab"
type="segment"
animated
class="aksrt-tabs aksrt-captcha-provider-tabs"
>
<n-tab-pane
v-for="provider in captchaProviders"
:key="provider.key"
:name="provider.key"
:tab="provider.label"
>
<component
:is="provider.component"
:model-value="getCaptchaProviderConfig(provider.key)"
@update:model-value="setCaptchaProviderConfig(provider.key, $event)"
@clear-secret="markCaptchaSecretForClear(provider.key, $event)"
@restore-secret="unmarkCaptchaSecretForClear(provider.key, $event)"
/>
</n-tab-pane>
</n-tabs>
</template>
<template
@@ -132,6 +131,13 @@ const testLoading = ref(false)
const testResult = ref(null)
const serverSchema = ref(null)
const captchaSecretsToClear = ref(new Set())
const captchaProviders = [
{ key: 'tencent', label: '腾讯云 Captcha', component: TencentConfig },
{ key: 'aliyun', label: '阿里云 CAPTCHA2.0', component: AliyunConfig },
{ key: 'cloudflare', label: 'Cloudflare Turnstile', component: CloudflareConfig },
{ key: 'geetest', label: '极验 Geetest', component: GeetestConfig },
]
const captchaProviderTab = ref('tencent')
/** Resolve domain/section from props or route meta (canonicalDomain + section, with legacy fallback) */
const resolvedDomain = computed(() => normalizeSchemaDomain(props.domain || route.meta?.canonicalDomain || route.meta?.schemaDomain || resolveDomainFromPath(route.path)))
@@ -233,10 +239,11 @@ async function handleSave() {
}
}
function handleReload() {
async function handleReload() {
closeTestModal()
captchaSecretsToClear.value = new Set()
reload()
await reload()
syncCaptchaProviderTab()
message.info('已放弃更改')
}
@@ -255,6 +262,15 @@ function unmarkCaptchaSecretForClear(provider, field) {
captchaSecretsToClear.value = next
}
function setCaptchaProviderConfig(provider, value) {
formData.value = { ...formData.value, [provider]: value || {} }
}
function syncCaptchaProviderTab() {
const provider = formData.value?.active_provider
captchaProviderTab.value = captchaProviders.some(({ key }) => key === provider) ? provider : 'tencent'
}
function getCaptchaProviderConfig(provider) {
if (!formData.value || !provider) return {}
const cfg = formData.value[provider]
@@ -452,6 +468,8 @@ function closeTestModal() {
}
}
watch(() => formData.value?.active_provider, syncCaptchaProviderTab)
watch([resolvedDomain, resolvedSection], ([nextDomain, nextSection], [prevDomain, prevSection]) => {
if (nextDomain !== prevDomain || nextSection !== prevSection) {
closeTestModal()