适配第二版验证码

This commit is contained in:
biss committed 2026-09-12 08:37:12 +08:00
1 parent 564ffecfed
commit c1451d0e6d
5 files changed
+79 -14

No files matched your search

+38 -6
View File
@@ -2,13 +2,21 @@
import { onMounted, ref, watch } from 'vue'
import http from '../api/http'
interface CaptchaImage {
interface CaptchaChoice {
id: string
label: string
}
interface CaptchaChallenge {
captchaId: string
imageData: string
type: 'TextImage' | 'Selection' | 'OneClick'
prompt?: string
choices?: CaptchaChoice[]
imageData?: string
}
const emit = defineEmits<{ change: [captchaId: string, captchaCode: string] }>()
const captcha = ref<CaptchaImage | null>(null)
const captcha = ref<CaptchaChallenge | null>(null)
const code = ref('')
const loading = ref(false)
@@ -24,6 +32,9 @@ async function refresh() {
}
watch([captcha, code], () => emit('change', captcha.value?.captchaId ?? '', code.value))
function choose(answer: string) {
code.value = answer
}
onMounted(refresh)
defineExpose({ refresh })
</script>
@@ -35,8 +46,26 @@ defineExpose({ refresh })
<button type="button" :disabled="loading" @click="refresh">换一张</button>
</div>
<div v-loading="loading" class="captcha-input">
<img v-if="captcha" :src="captcha.imageData" alt="验证码图片,点击可更换" @click="refresh" />
<el-input v-model="code" maxlength="8" autocomplete="off" placeholder="输入图中字符" />
<template v-if="captcha?.type === 'TextImage'">
<img v-if="captcha.imageData" :src="captcha.imageData" alt="验证码图片,点击可更换" @click="refresh" />
<el-input v-model="code" maxlength="8" autocomplete="off" placeholder="输入图中字符" />
</template>
<div v-else-if="captcha" class="captcha-question">
<p>{{ captcha.prompt }}</p>
<div v-if="captcha.type === 'Selection'" class="captcha-choices" role="group" aria-label="验证码选项">
<el-button
v-for="choice in captcha.choices ?? []"
:key="choice.id"
:type="code === choice.id ? 'primary' : 'default'"
@click="choose(choice.id)"
>
{{ choice.label }}
</el-button>
</div>
<el-button v-else type="primary" :plain="code !== 'CONFIRM'" @click="choose('CONFIRM')">
我确认是本人操作
</el-button>
</div>
</div>
</section>
</template>
@@ -45,7 +74,10 @@ defineExpose({ refresh })
.login-captcha { display: grid; gap: 8px; }
.captcha-heading { display: flex; justify-content: space-between; align-items: center; font-size: 14px; font-weight: 650; color: #233b54; }
.captcha-heading button { border: 0; background: transparent; color: #467cae; cursor: pointer; font: inherit; }
.captcha-input { display: grid; grid-template-columns: 150px minmax(0, 1fr); gap: 10px; align-items: center; }
.captcha-input { min-height: 50px; display: grid; grid-template-columns: 150px minmax(0, 1fr); gap: 10px; align-items: center; }
.captcha-input img { width: 150px; height: 50px; object-fit: contain; border: 1px solid #d7e2ed; border-radius: 6px; cursor: pointer; background: #f7fafc; }
.captcha-question { grid-column: 1 / -1; display: grid; gap: 8px; padding: 10px 12px; border: 1px solid #d7e2ed; border-radius: 6px; background: #f7fafc; }
.captcha-question p { margin: 0; color: #233b54; font-size: 14px; }
.captcha-choices { display: flex; flex-wrap: wrap; gap: 8px; }
@media (max-width: 420px) { .captcha-input { grid-template-columns: 130px minmax(0, 1fr); } .captcha-input img { width: 130px; } }
</style>