|
@@ -0,0 +1,78 @@
|
|
|
|
|
+<script setup lang="ts">
|
|
|
|
|
+import { onMounted, ref, watch } from 'vue';
|
|
|
|
|
+
|
|
|
|
|
+interface Props {
|
|
|
|
|
+ modelValue?: string;
|
|
|
|
|
+ placeholder?: string;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const props = withDefaults(defineProps<Props>(), {
|
|
|
|
|
+ modelValue: '',
|
|
|
|
|
+ placeholder: '请输入验证码',
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+const emit = defineEmits(['update:modelValue', 'refresh']);
|
|
|
|
|
+
|
|
|
|
|
+const captchaValue = ref(props.modelValue);
|
|
|
|
|
+const captchaUrl = ref('');
|
|
|
|
|
+
|
|
|
|
|
+watch(
|
|
|
|
|
+ () => props.modelValue,
|
|
|
|
|
+ (val) => {
|
|
|
|
|
+ captchaValue.value = val;
|
|
|
|
|
+ },
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+watch(captchaValue, (val) => {
|
|
|
|
|
+ emit('update:modelValue', val);
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+function handleRefresh() {
|
|
|
|
|
+ const random = randomString(16);
|
|
|
|
|
+ captchaUrl.value = `/File/ImageCheckCode?w=130&h=40&len=4&key=${random}`;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function handleInput(e: Event) {
|
|
|
|
|
+ const target = e.target as HTMLInputElement;
|
|
|
|
|
+ captchaValue.value = target.value;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function randomString(length: number): string {
|
|
|
|
|
+ let result = '';
|
|
|
|
|
+ const characters =
|
|
|
|
|
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
|
|
|
+ const charactersLength = characters.length;
|
|
|
|
|
+ for (let i = 0; i < length; i++) {
|
|
|
|
|
+ result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+onMounted(() => {
|
|
|
|
|
+ handleRefresh();
|
|
|
|
|
+});
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div class="flex items-center gap-2">
|
|
|
|
|
+ <input
|
|
|
|
|
+ :placeholder="placeholder"
|
|
|
|
|
+ :value="captchaValue"
|
|
|
|
|
+ class="h-[38px] flex-1 rounded-md border border-gray-300 px-3 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-[#8B0046]"
|
|
|
|
|
+ type="text"
|
|
|
|
|
+ @input="handleInput"
|
|
|
|
|
+ />
|
|
|
|
|
+ <div
|
|
|
|
|
+ class="flex h-[38px] w-[120px] cursor-pointer items-center justify-center overflow-hidden rounded-md border border-gray-300 bg-gray-100"
|
|
|
|
|
+ @click="handleRefresh"
|
|
|
|
|
+ >
|
|
|
|
|
+ <img
|
|
|
|
|
+ v-if="captchaUrl"
|
|
|
|
|
+ :src="captchaUrl"
|
|
|
|
|
+ alt="验证码"
|
|
|
|
|
+ class="h-full w-full object-contain"
|
|
|
|
|
+ />
|
|
|
|
|
+ <span v-else class="text-xs text-gray-500">点击刷新</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|