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

View File

@ -1,22 +1,23 @@
<script setup lang="ts"> <script setup lang="ts">
import { Input as VbenInput } from '../../ui/input'; import { Input as VbenInput } from '../../ui/input';
withDefaults( interface Props {
defineProps<{ captcha?: string;
captcha?: string; label?: string;
label?: string; loading?: boolean;
placeholder?: string; placeholder?: string;
}>(), }
{
captcha: '', withDefaults(defineProps<Props>(), {
label: '验证码', captcha: '',
placeholder: '请输入验证码', label: '验证码',
}, loading: false,
); placeholder: '请输入验证码',
});
defineEmits<{ captchaClick: [] }>(); defineEmits<{ captchaClick: [] }>();
const modelValue = defineModel({ default: '', type: String }); const modelValue = defineModel<string>({ default: '' });
</script> </script>
<!-- 图片验证码 --> <!-- 图片验证码 -->
@ -24,26 +25,56 @@ const modelValue = defineModel({ default: '', type: String });
<div class="flex w-full"> <div class="flex w-full">
<div class="flex-1"> <div class="flex-1">
<VbenInput <VbenInput
autocomplete="off"
id="code" id="code"
name="code"
type="text"
autocomplete="off"
required
v-model="modelValue" v-model="modelValue"
:class="$attrs?.class ?? {}" :class="$attrs?.class ?? {}"
:label="label" :label="label"
:placeholder="placeholder" :placeholder="placeholder"
name="code"
required
type="text"
/> />
</div> </div>
<img <div class="captcha-image--container relative">
:src="captcha" <img
class="h-[40px] w-[115px] cursor-pointer rounded-r-md" :src="captcha"
@click="$emit('captchaClick')" 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> </div>
</template> </template>
<style lang="scss"> <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;
}
/** /**
验证码输入框样式 验证码输入框样式
去除右边的圆角 去除右边的圆角