| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- <template>
- <div class="root">
- <div class="logo">
- <img alt="哪吒乐跑" src="/logo.svg" height="40">
- <span class="title">哪吒乐跑 | 用户注册</span>
- </div>
- <a-form size="large" ref="formRef" :model="form" :rules="[]" class="form" @submit="handleSubmit">
- <a-form-item field="username" hide-label
- :rules="[{ required: true, message: '用户名不能为空' }, { minLength: 4, maxLength: 12, message: '用户名长度需在4~12位间' }]"
- :validate-trigger="['change']">
- <a-input placeholder="请输入用户名" allow-clear v-model="form.username">
- <template #prefix>
- <icon-user />
- </template>
- </a-input>
- </a-form-item>
- <a-form-item field="password" hide-label
- :rules="[{ required: true, message: '密码不能为空' }, { maxLength: 16, minLength: 8, message: '密码长度需在8~16位之间' }]"
- :validate-trigger="['change']">
- <a-input-password placeholder="请输入密码" allow-clear v-model="form.password">
- <template #prefix>
- <icon-lock />
- </template>
- </a-input-password>
- </a-form-item>
- <a-form-item field="password2" hide-label
- :rules="[{ required: true, message: '请再次输入密码' }, { maxLength: 16, minLength: 8, message: '密码长度需在8~16位之间' }]"
- :validate-trigger="['change']">
- <a-input-password placeholder="请再次输入密码" allow-clear v-model="form.password2">
- <template #prefix>
- <icon-lock />
- </template>
- </a-input-password>
- </a-form-item>
- <!-- <a-form-item field="email" hide-label :rules="[{ type: 'email', required: true, message: '请填写正确的邮箱地址' }]"
- :validate-trigger="['change']">
- <a-input placeholder="请输入邮箱" allow-clear v-model="form.email">
- <template #prefix>
- <icon-email />
- </template>
- </a-input>
- </a-form-item> -->
- <a-form-item field="captcha" hide-label :rules="[{ length: 4, required: true, message: '请正确填写图片验证码' }]">
- <a-input placeholder="请输入图片验证码" allow-clear v-model="form.captcha">
- <template #prefix>
- <icon-check-circle />
- </template>
- <template #append>
- <img alt="!点我重试" :src="ImageCaptcha" class="captcha" @click="getCaptcha()"
- v-if="!captchaLoading">
- <icon-loading v-else />
- </template>
- </a-input>
- </a-form-item>
- <!-- <a-form-item field="code" hide-label :rules="[{ length: 6, required: true, message: '请正确填写邮箱验证码' }]">
- <a-input placeholder="请输入邮箱验证码" allow-clear v-model="form.code">
- <template #prefix>
- <icon-code-square />
- </template>
- <template #append>
- <a-button type="text" style="width: 80px" @click="SendEmail" :disabled="state.smsSendBtn">
- <span v-if="!state.smsSendBtn">获取验证码</span>
- <span v-else>{{ state.time }} s</span>
- </a-button>
- </template>
- </a-input>
- </a-form-item> -->
- <a-button type="text" class="forgetpass" @click="emit('changeMode', 'login')">已有账号,去登录</a-button>
- <a-button :style="{ marginTop: '15px' }" class="formitem" type="primary" html-type="submit"
- :loading="state.okButton">立即注册</a-button>
- </a-form>
- </div>
- </template>
- <script setup>
- import { getImageCaptcha, sendEmail, register } from '@/api/login'
- import { Notification, Message } from '@arco-design/web-vue';
- import { ref, reactive, defineEmits } from 'vue'
- const emit = defineEmits(['changeMode'])
- const formRef = ref(null)
- let captchaLoading = ref(false)
- let CaptchaId = ref('')
- let ImageCaptcha = ref('')
- let form = reactive({
- username: '',
- password: '',
- password2: '',
- email: '',
- code: '',
- captcha: ''
- })
- let state = reactive({
- smsSendBtn: false,
- time: 60,
- okButton: false
- })
- const SendEmail = async () => {
- try {
- const v = await formRef.value.validateField(['email', 'captcha'])
- if (v) return
- let email = form.email
- let text = form.captcha
- state.smsSendBtn = true
- const interval = window.setInterval(() => {
- if (state.time-- <= 0) {
- state.time = 60
- state.smsSendBtn = false
- window.clearInterval(interval)
- }
- }, 1000)
- Message.loading('验证码发送中..')
- const res = await sendEmail({ email, text, id: CaptchaId.value, type: 'register' })
- if (!res || res.code != 0) {
- state.time = 60
- state.smsSendBtn = false
- window.clearInterval(interval)
- getImageCaptcha()
- form.captcha = ''
- if (res.code === -10501) {
- return Notification.error({
- title: '验证码输入错误',
- content: res?.msg ?? '请求出现错误,请稍后再试'
- })
- }
- return Notification.error({
- title: '获取验证码失败',
- content: res?.msg ?? '请求出现错误,请稍后再试'
- })
- }
- } catch (error) {
- Message.error('验证码发送失败')
- }
- }
- const getCaptcha = async () => {
- try {
- captchaLoading.value = true
- const res = await getImageCaptcha()
- if (!res || res.code != 0)
- return requestFailed('获取图片验证码失败!' + res?.msg ?? '')
- ImageCaptcha.value = res.data.img
- CaptchaId.value = res.data.id
- } catch (error) {
- requestFailed('获取图片验证码失败!')
- } finally {
- captchaLoading.value = false
- }
- }
- getCaptcha()
- const handleSubmit = async ({ values, errors }) => {
- try {
- state.okButton = true
- const v = await formRef.value.validate()
- if (v) return
- let data = { ...values }
- if (data.password !== data.password2) return Message.error('请确保两次输入的密码一致!')
- data.password = btoa(data.password)
- data.id = CaptchaId.value
- const res = await register(data)
- if (!res || res.code !== 0)
- return requestFailed(res.msg)
- Message.success('注册成功!请登录')
- emit('changeMode', 'login')
- } catch (error) {
- requestFailed(error.message)
- } finally {
- state.okButton = false
- }
- }
- const requestFailed = (msg) => {
- Notification.error({
- title: '错误',
- content: msg || '请求出现错误,请稍后再试',
- })
- }
- </script>
- <style scoped>
- .root {
- display: flex;
- gap: 40px;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- margin: 20px
- }
- .form {
- width: 100%;
- }
- .formitem {
- width: 350px;
- min-height: 35px
- }
- .logo {
- display: flex
- }
- .logo .title {
- color: #f53f3f;
- font-size: 1.8em;
- font-weight: bold;
- margin-left: 15px;
- font-family: Alimama ShuHeiTi, -apple-system, BlinkMacSystemFont;
- }
- .forgetpass {
- width: 130px;
- margin-top: -10px;
- }
- .captcha {
- max-height: 35px;
- margin-right: -10px;
- }
- </style>
|