|
@@ -31,6 +31,35 @@
|
|
|
@blur="isAccountInputOver=true"
|
|
@blur="isAccountInputOver=true"
|
|
|
>
|
|
>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+ <div class="form-item form-item-verifi">
|
|
|
|
|
+ <div class="title">
|
|
|
|
|
+ <img
|
|
|
|
|
+ src="@/assets/images/icon-mail.png"
|
|
|
|
|
+ alt=""
|
|
|
|
|
+ draggable="false"
|
|
|
|
|
+ >
|
|
|
|
|
+ <span>邮箱验证码</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="row">
|
|
|
|
|
+ <input
|
|
|
|
|
+ v-model="verifiCode"
|
|
|
|
|
+ placeholder="请输入4位验证码"
|
|
|
|
|
+ :class="{
|
|
|
|
|
+ invalid: isVerifiCodeInputOver && !isVerifiCodeValid
|
|
|
|
|
+ }"
|
|
|
|
|
+ @blur="isVerifiCodeInputOver=true"
|
|
|
|
|
+ >
|
|
|
|
|
+ <button
|
|
|
|
|
+ class="get-verifi-code"
|
|
|
|
|
+ :class="{
|
|
|
|
|
+ disabled: isVerifiCodeSent
|
|
|
|
|
+ }"
|
|
|
|
|
+ @click="onClickVerifiCode"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ isVerifiCodeSent ? `${verifiCodeCountDown}s` : '发送验证码' }}
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
<div class="form-item">
|
|
<div class="form-item">
|
|
|
<div class="title">
|
|
<div class="title">
|
|
|
<img
|
|
<img
|
|
@@ -88,44 +117,12 @@
|
|
|
@blur="isPasswordRepeatInputOver=true"
|
|
@blur="isPasswordRepeatInputOver=true"
|
|
|
>
|
|
>
|
|
|
</div>
|
|
</div>
|
|
|
- <div class="form-item form-item-verifi">
|
|
|
|
|
- <div class="title">
|
|
|
|
|
- <!-- <img
|
|
|
|
|
- src="@/assets/images/icon-lock.png"
|
|
|
|
|
- alt=""
|
|
|
|
|
- draggable="false"
|
|
|
|
|
- > -->
|
|
|
|
|
- <span>验证码</span>
|
|
|
|
|
- </div>
|
|
|
|
|
- <div class="row">
|
|
|
|
|
- <input
|
|
|
|
|
- v-model="verifiCode"
|
|
|
|
|
- placeholder="请输入验证码"
|
|
|
|
|
- :class="{
|
|
|
|
|
- invalid: isVerifiCodeInputOver && !isVerifiCodeValid
|
|
|
|
|
- }"
|
|
|
|
|
- @blur="isVerifiCodeInputOver=true"
|
|
|
|
|
- >
|
|
|
|
|
- <button
|
|
|
|
|
- class="get-verifi-code"
|
|
|
|
|
- @click="onClickVerifiCode"
|
|
|
|
|
- >
|
|
|
|
|
- <img
|
|
|
|
|
- v-if="isShowVerifiCode"
|
|
|
|
|
- class=""
|
|
|
|
|
- :src="`${$env.VUE_APP_DEPLOY_ORIGIN}/api/show/getRandCode`"
|
|
|
|
|
- alt=""
|
|
|
|
|
- draggable="false"
|
|
|
|
|
- >
|
|
|
|
|
- </button>
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
|
|
|
<button
|
|
<button
|
|
|
class="submit"
|
|
class="submit"
|
|
|
@click="submit"
|
|
@click="submit"
|
|
|
>
|
|
>
|
|
|
- 注册并登录
|
|
|
|
|
|
|
+ 注册
|
|
|
</button>
|
|
</button>
|
|
|
<button
|
|
<button
|
|
|
class="return"
|
|
class="return"
|
|
@@ -140,8 +137,8 @@
|
|
|
import { ref, computed, watch, onMounted, nextTick, inject } from "vue"
|
|
import { ref, computed, watch, onMounted, nextTick, inject } from "vue"
|
|
|
import { useRoute, useRouter } from "vue-router"
|
|
import { useRoute, useRouter } from "vue-router"
|
|
|
import { useStore } from "vuex"
|
|
import { useStore } from "vuex"
|
|
|
-import { showDialog } from 'vant'
|
|
|
|
|
-import { signUp, login } from '@/api.js'
|
|
|
|
|
|
|
+import { showDialog, showNotify } from 'vant'
|
|
|
|
|
+import { sendEmail, signUp, login } from '@/api.js'
|
|
|
|
|
|
|
|
const route = useRoute()
|
|
const route = useRoute()
|
|
|
const router = useRouter()
|
|
const router = useRouter()
|
|
@@ -155,14 +152,17 @@ const {
|
|
|
} = useSizeAdapt(390, 752)
|
|
} = useSizeAdapt(390, 752)
|
|
|
|
|
|
|
|
const account = ref('')
|
|
const account = ref('')
|
|
|
|
|
+const verifiCode = ref('')
|
|
|
const phone = ref('')
|
|
const phone = ref('')
|
|
|
const password = ref('')
|
|
const password = ref('')
|
|
|
const passwordRepeat = ref('')
|
|
const passwordRepeat = ref('')
|
|
|
-const verifiCode = ref('')
|
|
|
|
|
|
|
|
|
|
const accountTrimed = computed(() => {
|
|
const accountTrimed = computed(() => {
|
|
|
return account.value.trim()
|
|
return account.value.trim()
|
|
|
})
|
|
})
|
|
|
|
|
+const verifiCodeTrimed = computed(() => {
|
|
|
|
|
+ return verifiCode.value.trim()
|
|
|
|
|
+})
|
|
|
const phoneTrimed = computed(() => {
|
|
const phoneTrimed = computed(() => {
|
|
|
return phone.value.toString().trim()
|
|
return phone.value.toString().trim()
|
|
|
})
|
|
})
|
|
@@ -172,12 +172,14 @@ const passwordTrimed = computed(() => {
|
|
|
const passwordRepeatTrimed = computed(() => {
|
|
const passwordRepeatTrimed = computed(() => {
|
|
|
return passwordRepeat.value.trim()
|
|
return passwordRepeat.value.trim()
|
|
|
})
|
|
})
|
|
|
-const verifiCodeTrimed = computed(() => {
|
|
|
|
|
- return verifiCode.value.trim()
|
|
|
|
|
-})
|
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
const isAccountValid = computed(() => {
|
|
const isAccountValid = computed(() => {
|
|
|
- return !!accountTrimed.value
|
|
|
|
|
|
|
+ const pattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
|
|
|
|
|
+ return pattern.test(accountTrimed.value)
|
|
|
|
|
+})
|
|
|
|
|
+const isVerifiCodeValid = computed(() => {
|
|
|
|
|
+ return verifiCodeTrimed.value.length > 0
|
|
|
})
|
|
})
|
|
|
const isPhoneValid = computed(() => {
|
|
const isPhoneValid = computed(() => {
|
|
|
return phoneTrimed.value.length === 11
|
|
return phoneTrimed.value.length === 11
|
|
@@ -188,33 +190,71 @@ const isPasswordValid = computed(() => {
|
|
|
const isPasswordRepeatValid = computed(() => {
|
|
const isPasswordRepeatValid = computed(() => {
|
|
|
return passwordTrimed.value === passwordRepeatTrimed.value
|
|
return passwordTrimed.value === passwordRepeatTrimed.value
|
|
|
})
|
|
})
|
|
|
-const isVerifiCodeValid = computed(() => {
|
|
|
|
|
- return verifiCodeTrimed.value.length > 0
|
|
|
|
|
-})
|
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
const isAccountInputOver = ref(false)
|
|
const isAccountInputOver = ref(false)
|
|
|
|
|
+const isVerifiCodeInputOver = ref(false)
|
|
|
const isPhoneInputOver = ref(false)
|
|
const isPhoneInputOver = ref(false)
|
|
|
const isPasswordInputOver = ref(false)
|
|
const isPasswordInputOver = ref(false)
|
|
|
const isPasswordRepeatInputOver = ref(false)
|
|
const isPasswordRepeatInputOver = ref(false)
|
|
|
-const isVerifiCodeInputOver = ref(false)
|
|
|
|
|
|
|
|
|
|
-const isShowVerifiCode = ref(true)
|
|
|
|
|
|
|
+// todo: 倒计时搬移到组件外部
|
|
|
|
|
+const isVerifiCodeSent = ref(false)
|
|
|
|
|
+const verifiCodeCountDown = ref(60)
|
|
|
|
|
+watch(isVerifiCodeSent, (v) => {
|
|
|
|
|
+ if (v) {
|
|
|
|
|
+ setInterval(() => {
|
|
|
|
|
+ verifiCodeCountDown.value--
|
|
|
|
|
+ if (verifiCodeCountDown.value === 0) {
|
|
|
|
|
+ isVerifiCodeSent.value = false
|
|
|
|
|
+ verifiCodeCountDown.value = 60
|
|
|
|
|
+ }
|
|
|
|
|
+ }, 1000)
|
|
|
|
|
+ }
|
|
|
|
|
+})
|
|
|
const onClickVerifiCode = utils.throttle(() => {
|
|
const onClickVerifiCode = utils.throttle(() => {
|
|
|
- isShowVerifiCode.value = false
|
|
|
|
|
- nextTick(() => {
|
|
|
|
|
- isShowVerifiCode.value = true
|
|
|
|
|
|
|
+ if (isVerifiCodeSent.value) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!isAccountValid.value) {
|
|
|
|
|
+ showDialog({
|
|
|
|
|
+ message: '请正确输入邮箱',
|
|
|
|
|
+ theme: 'round-button',
|
|
|
|
|
+ })
|
|
|
|
|
+ isAccountInputOver.value = true
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ sendEmail(accountTrimed.value).then(() => {
|
|
|
|
|
+ showNotify({
|
|
|
|
|
+ type: 'success',
|
|
|
|
|
+ message: `验证码已发送至邮箱${accountTrimed.value},请在邮箱中查收`,
|
|
|
|
|
+ })
|
|
|
|
|
+ isVerifiCodeSent.value = true
|
|
|
|
|
+ }).catch((e) => {
|
|
|
|
|
+ showDialog({
|
|
|
|
|
+ message: e,
|
|
|
|
|
+ theme: 'round-button',
|
|
|
|
|
+ })
|
|
|
})
|
|
})
|
|
|
}, 333)
|
|
}, 333)
|
|
|
|
|
|
|
|
function submit() {
|
|
function submit() {
|
|
|
if (!isAccountValid.value) {
|
|
if (!isAccountValid.value) {
|
|
|
showDialog({
|
|
showDialog({
|
|
|
- message: '请正确输入邮箱',
|
|
|
|
|
|
|
+ message: '请输入正确的邮箱信息',
|
|
|
theme: 'round-button',
|
|
theme: 'round-button',
|
|
|
})
|
|
})
|
|
|
isAccountInputOver.value = true
|
|
isAccountInputOver.value = true
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
+ if (!isVerifiCodeValid.value) {
|
|
|
|
|
+ showDialog({
|
|
|
|
|
+ message: '正确输入验证码',
|
|
|
|
|
+ theme: 'round-button',
|
|
|
|
|
+ })
|
|
|
|
|
+ isVerifiCodeInputOver.value = true
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
if (!isPhoneValid.value) {
|
|
if (!isPhoneValid.value) {
|
|
|
showDialog({
|
|
showDialog({
|
|
|
message: '请正确输入手机号',
|
|
message: '请正确输入手机号',
|
|
@@ -239,22 +279,12 @@ function submit() {
|
|
|
isPasswordRepeatInputOver.value = true
|
|
isPasswordRepeatInputOver.value = true
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
- if (!isVerifiCodeValid.value) {
|
|
|
|
|
- showDialog({
|
|
|
|
|
- message: '请输入验证码',
|
|
|
|
|
- theme: 'round-button',
|
|
|
|
|
- })
|
|
|
|
|
- isVerifiCodeInputOver.value = true
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
signUp(accountTrimed.value, phoneTrimed.value, passwordTrimed.value, verifiCodeTrimed.value).then(() => {
|
|
signUp(accountTrimed.value, phoneTrimed.value, passwordTrimed.value, verifiCodeTrimed.value).then(() => {
|
|
|
showDialog({
|
|
showDialog({
|
|
|
message: '注册成功',
|
|
message: '注册成功',
|
|
|
theme: 'round-button',
|
|
theme: 'round-button',
|
|
|
}).then(() => {
|
|
}).then(() => {
|
|
|
- login(accountTrimed.value, passwordTrimed.value)
|
|
|
|
|
- }).then(() => {
|
|
|
|
|
router.replace({
|
|
router.replace({
|
|
|
name: 'HomeView'
|
|
name: 'HomeView'
|
|
|
})
|
|
})
|
|
@@ -341,24 +371,6 @@ function submit() {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
>.form-item{
|
|
>.form-item{
|
|
|
- >.title{
|
|
|
|
|
- width: 100%;
|
|
|
|
|
- display: flex;
|
|
|
|
|
- align-items: center;
|
|
|
|
|
- margin-bottom: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
|
|
- >img{
|
|
|
|
|
- width: calc(22 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
|
|
- height: calc(22 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
|
|
- margin-right: calc(10 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
|
|
- }
|
|
|
|
|
- >span{
|
|
|
|
|
- font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
|
|
- font-family: Source Han Sans SC, Source Han Sans SC;
|
|
|
|
|
- font-weight: 400;
|
|
|
|
|
- color: #D1B489;
|
|
|
|
|
- line-height: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
>div.row{
|
|
>div.row{
|
|
|
display: flex;
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
justify-content: space-between;
|
|
@@ -385,9 +397,19 @@ function submit() {
|
|
|
border-bottom: 1px solid red;
|
|
border-bottom: 1px solid red;
|
|
|
}
|
|
}
|
|
|
>button.get-verifi-code{
|
|
>button.get-verifi-code{
|
|
|
- height: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
|
|
- >img{
|
|
|
|
|
- height: 100%;
|
|
|
|
|
|
|
+ width: calc(108 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
|
|
+ height: calc(34 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
|
|
+ background: #FFFFFF;
|
|
|
|
|
+ border-radius: calc(3 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
|
|
+ border: 1px solid #D1B489;
|
|
|
|
|
+ font-family: Source Han Sans SC, Source Han Sans SC;
|
|
|
|
|
+ font-weight: 400;
|
|
|
|
|
+ font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
|
|
+ color: #D1B489;
|
|
|
|
|
+ line-height: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ &.disabled{
|
|
|
|
|
+ pointer-events: none;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|