You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

104 lines
2.6 KiB

<script setup lang="ts">
import { clientRegisterSchema, type RegisterInput } from 'shared/auth-schema'
const props = defineProps<{
captchaSvg: string
captchaToken: string
}>()
const emit = defineEmits<{
'refresh-captcha': []
success: []
error: [message: string]
}>()
const loading = ref(false)
const formRef = ref()
const state = reactive<RegisterInput>({
username: '',
password: '',
confirmPassword: '',
captchaText: '',
})
const password = computed(() => state.password)
async function onSubmit() {
if (loading.value) return
loading.value = true
try {
const res = await $fetch<{ code: number; message: string; data: { id?: number; username?: string; field?: string } | null }>(
'/api/auth/register',
{
method: 'POST',
body: {
username: state.username,
password: state.password,
confirmPassword: state.confirmPassword,
captchaToken: props.captchaToken,
captchaText: state.captchaText,
},
}
)
if (res.code !== 0) {
const field = res.data && 'field' in (res.data || {}) ? (res.data as { field: string }).field : undefined
if (field && formRef.value) {
formRef.value.setFieldError(field, res.message)
} else {
emit('error', res.message)
}
// Auto-refresh captcha on captcha-related errors
if (res.message.includes('验证码')) {
emit('refresh-captcha')
state.captchaText = ''
}
return
}
emit('success')
} catch {
emit('error', '注册失败,请稍后重试')
} finally {
loading.value = false
}
}
</script>
<template>
<UForm ref="formRef" :state="state" :schema="clientRegisterSchema" @submit="onSubmit">
<UFormField name="username" label="用户名" required class="mb-4">
<UInput v-model="state.username" placeholder="请输入用户名" :disabled="loading" />
</UFormField>
<PasswordInput
v-model="state.password"
label="密码"
placeholder="至少8个字符"
:disabled="loading"
class="mb-4"
/>
<PasswordStrength :password="password" />
<PasswordInput
v-model="state.confirmPassword"
label="确认密码"
placeholder="请再次输入密码"
:disabled="loading"
class="mb-4 mt-2"
/>
<CaptchaField
v-model="state.captchaText"
:svg="captchaSvg"
:loading="loading"
class="mb-4"
@refresh="emit('refresh-captcha')"
/>
<UButton type="submit" block :loading="loading" class="mt-6">
{{ loading ? '注册中...' : '注册' }}
</UButton>
</UForm>
</template>