适配第二版验证码
This commit is contained in:
1 parent
564ffecfed
commit
c1451d0e6d
5 files changed
+79
-14
No files matched your search
@@ -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>
|
||||
Reference in new issue
Block a user