feat: 验证码loading

This commit is contained in:
dap 2025-04-03 13:57:32 +08:00
parent 2d58a2172d
commit 56e7e840b3
2 changed files with 68 additions and 26 deletions

View File

@ -30,13 +30,23 @@ const captchaInfo = ref<CaptchaResponse>({
img: '',
uuid: '',
});
// loading
const captchaLoading = ref(false);
async function loadCaptcha() {
const resp = await captchaImage();
if (resp.captchaEnabled) {
resp.img = `data:image/png;base64,${resp.img}`;
try {
captchaLoading.value = true;
const resp = await captchaImage();
if (resp.captchaEnabled) {
resp.img = `data:image/png;base64,${resp.img}`;
}
captchaInfo.value = resp;
} catch (error) {
console.error(error);
} finally {
captchaLoading.value = false;
}
captchaInfo.value = resp;
}
const tenantInfo = ref<TenantResp>({
@ -116,6 +126,7 @@ const formSchema = computed((): VbenFormSchema[] => {
class: 'focus:border-primary',
onCaptchaClick: loadCaptcha,
placeholder: $t('authentication.code'),
loading: captchaLoading.value,
},
dependencies: {
if: () => captchaInfo.value.captchaEnabled,

View File

@ -1,22 +1,23 @@
<script setup lang="ts">
import { Input as VbenInput } from '../../ui/input';
withDefaults(
defineProps<{
captcha?: string;
label?: string;
placeholder?: string;
}>(),
{
captcha: '',
label: '验证码',
placeholder: '请输入验证码',
},
);
interface Props {
captcha?: string;
label?: string;
loading?: boolean;
placeholder?: string;
}
withDefaults(defineProps<Props>(), {
captcha: '',
label: '验证码',
loading: false,
placeholder: '请输入验证码',
});
defineEmits<{ captchaClick: [] }>();
const modelValue = defineModel({ default: '', type: String });
const modelValue = defineModel<string>({ default: '' });
</script>
<!-- 图片验证码 -->
@ -24,26 +25,56 @@ const modelValue = defineModel({ default: '', type: String });
<div class="flex w-full">
<div class="flex-1">
<VbenInput
autocomplete="off"
id="code"
name="code"
type="text"
autocomplete="off"
required
v-model="modelValue"
:class="$attrs?.class ?? {}"
:label="label"
:placeholder="placeholder"
name="code"
required
type="text"
/>
</div>
<img
:src="captcha"
class="h-[40px] w-[115px] cursor-pointer rounded-r-md"
@click="$emit('captchaClick')"
/>
<div class="captcha-image--container relative">
<img
:src="captcha"
class="h-[40px] w-[115px] cursor-pointer rounded-r-md"
:class="{ 'pointer-events-none': loading }"
@click="$emit('captchaClick')"
/>
<div
v-if="loading"
class="absolute inset-0 flex cursor-not-allowed items-center justify-center rounded-r-md bg-black/30"
>
<span class="captcha-loading"></span>
</div>
</div>
</div>
</template>
<style lang="scss">
@keyframes loading-rotation {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.captcha-loading {
box-sizing: border-box;
display: inline-block;
width: 18px;
height: 18px;
border: 2px solid #fff;
border-bottom-color: transparent;
border-radius: 50%;
animation: loading-rotation 1s linear infinite;
}
/**
验证码输入框样式
去除右边的圆角