179 lines
5.4 KiB
Vue
179 lines
5.4 KiB
Vue
<script setup lang="ts">
|
|
import type {
|
|
FormProps,
|
|
UploadInstanceFunctions,
|
|
FormInstanceFunctions,
|
|
} from 'tdesign-vue-next';
|
|
import type { IAPIResponse } from '~/utils/APIResponse';
|
|
const store = useLoginStore();
|
|
const { registerForm, currentType } = storeToRefs(store);
|
|
const rules: FormProps['rules'] = {
|
|
email: [
|
|
{ required: true, message: '请输入邮箱', trigger: 'blur' },
|
|
{ email: true, message: '请输入邮箱', trigger: 'change' },
|
|
],
|
|
identifyingCode: [
|
|
{ required: true, message: '请输入验证码', trigger: 'blur' },
|
|
],
|
|
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
|
|
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
|
|
passwordRepeat: [
|
|
{ required: true, message: '请再次输入密码', trigger: 'blur' },
|
|
{
|
|
validator: (val) => val === registerForm.value.password,
|
|
message: '两次输入密码不一致',
|
|
trigger: 'change',
|
|
},
|
|
],
|
|
birth: [{ required: true, message: '请输入出生日期', trigger: 'change' }],
|
|
};
|
|
const uploadImage = ref<UploadInstanceFunctions>();
|
|
const form = ref<FormInstanceFunctions>();
|
|
const coldTime = ref(0);
|
|
const avatarURL = ref('');
|
|
async function submitForm() {
|
|
if (!form.value) return;
|
|
const result = await form.value.validate();
|
|
if (registerForm.value.avatarFile === '') {
|
|
await MessagePlugin.error('请上传头像');
|
|
return;
|
|
}
|
|
if (typeof result === 'boolean' && result) {
|
|
form.value.submit();
|
|
}
|
|
}
|
|
async function sendIdentifyingCode() {
|
|
if (await store.sendRegisterIdentifyingCode()) {
|
|
coldTime.value = 60;
|
|
const timer: NodeJS.Timeout = setInterval(() => {
|
|
if (coldTime.value > 0) coldTime.value--;
|
|
else {
|
|
clearInterval(timer);
|
|
}
|
|
}, 1000);
|
|
}
|
|
}
|
|
|
|
function backToLogin() {
|
|
form.value?.reset();
|
|
registerForm.value.avatarFile = '';
|
|
currentType.value = PageType.login;
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="w-full">
|
|
<div class="flex md:flex-row flex-col items-center gap-4 justify-around">
|
|
<div class="flex flex-col items-center gap-4 max-w-96">
|
|
<t-form
|
|
ref="form"
|
|
:label-width="10"
|
|
:data="registerForm"
|
|
:rules="rules"
|
|
@submit="() => store.register(backToLogin)"
|
|
>
|
|
<t-form-item name="email">
|
|
<div class="flex flex-row items-center gap-2">
|
|
<TInput v-model="registerForm.email" placeholder="请输入邮箱" />
|
|
<TButton :disabled="coldTime > 0" @click="sendIdentifyingCode">{{
|
|
coldTime > 0 ? coldTime : '发送验证码'
|
|
}}</TButton>
|
|
</div>
|
|
</t-form-item>
|
|
<t-form-item name="identifyingCode">
|
|
<TInput
|
|
v-model="registerForm.identifyingCode"
|
|
placeholder="请输入验证码"
|
|
/>
|
|
</t-form-item>
|
|
<t-form-item name="username">
|
|
<TInput
|
|
v-model="registerForm.username"
|
|
placeholder="请输入用户名"
|
|
/>
|
|
</t-form-item>
|
|
<t-form-item name="password">
|
|
<TInput
|
|
v-model="registerForm.password"
|
|
placeholder="请输入密码"
|
|
type="password"
|
|
/>
|
|
</t-form-item>
|
|
<t-form-item name="passwordRepeat">
|
|
<TInput
|
|
v-model="registerForm.passwordRepeat"
|
|
placeholder="请再次输入密码"
|
|
type="password"
|
|
/>
|
|
</t-form-item>
|
|
<t-form-item name="birth">
|
|
<TDatePicker
|
|
v-model="registerForm.birth"
|
|
placeholder="请输入出生日期"
|
|
/>
|
|
</t-form-item>
|
|
</t-form>
|
|
</div>
|
|
|
|
<TUpload
|
|
ref="uploadImage"
|
|
action="/api/file/uploadAvatar"
|
|
class="set-width-length bg-white bg-opacity-70"
|
|
theme="custom"
|
|
accept="image/*"
|
|
:draggable="true"
|
|
:format-response="
|
|
(res) => {
|
|
res = res as IAPIResponse<{
|
|
avatarFilePath: string;
|
|
avatarFileURL: string;
|
|
}>;
|
|
if (res.code === 200) {
|
|
registerForm.avatarFile = res.data.avatarFilePath;
|
|
avatarURL = res.data.avatarFileURL;
|
|
return { url: res.data.avatarFileURL };
|
|
}
|
|
return { fail: res.message };
|
|
}
|
|
"
|
|
>
|
|
<div v-if="registerForm.avatarFile" class="aspect-square h-full">
|
|
<t-image
|
|
:src="avatarURL"
|
|
class="w-40 h-40 object-cover rounded-md"
|
|
fit="contain"
|
|
/>
|
|
</div>
|
|
<div v-else>
|
|
<span class="text-blue-400">点击上传头像</span>
|
|
<span> / 拖拽到此区域 </span>
|
|
</div>
|
|
</TUpload>
|
|
</div>
|
|
|
|
<div
|
|
class="flex flex-row items-center bg-gray-600 w-full h-10 justify-around rounded-b-md mt-4"
|
|
>
|
|
<button class="text-white" @click="submitForm">注册用户</button>
|
|
<button class="text-white" @click="backToLogin">返回登录 </button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped lang="less">
|
|
:deep(.t-upload__dragger),
|
|
.set-width-length {
|
|
@apply w-64;
|
|
@apply h-40;
|
|
@apply p-0;
|
|
@apply border-0;
|
|
}
|
|
// {
|
|
// @apply w-40;
|
|
// @apply h-40;
|
|
//}
|
|
:deep(.t-date-picker) {
|
|
@apply w-full;
|
|
}
|
|
</style>
|