feat: 初始化
This commit is contained in:
60
pages/user/personalInformation/email/index.scss
Normal file
60
pages/user/personalInformation/email/index.scss
Normal file
@ -0,0 +1,60 @@
|
||||
.container {
|
||||
padding: 0 16px 24px;
|
||||
.title {
|
||||
margin: 14px 0 15px;
|
||||
}
|
||||
.content {
|
||||
.subTitle {
|
||||
margin-top: 32px;
|
||||
margin-bottom: 37px;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
}
|
||||
.inputsWrapper {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
column-gap: 7px;
|
||||
.input {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border: 1px solid #e5e5e5;
|
||||
::v-deep .uni-easyinput__content-input {
|
||||
height: 48px;
|
||||
}
|
||||
::v-deep .uni-input-input {
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.codeInput {
|
||||
width: 1000px;
|
||||
height: 1px;
|
||||
opacity: 0;
|
||||
}
|
||||
.resendCode {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
column-gap: 4px;
|
||||
margin: 28px 0 45px;
|
||||
font-size: 14px;
|
||||
color: #4dc0e5;
|
||||
.resendIcon {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
&.loading {
|
||||
animation: rotate infinite 2s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@keyframes rotate {
|
||||
0% {
|
||||
transform: rotateZ(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotateZ(360deg);
|
||||
}
|
||||
}
|
124
pages/user/personalInformation/email/index.vue
Normal file
124
pages/user/personalInformation/email/index.vue
Normal file
@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<NavBar />
|
||||
<view class="container">
|
||||
<view class="title">
|
||||
<PageTitle :title="$t('verifyEmail.pageTitle')" />
|
||||
</view>
|
||||
<view class="content">
|
||||
<view class="subTitle">
|
||||
<text>{{ $t('verifyEmail.subTitleBefore') }}</text>
|
||||
<text style="color: #29bbe4; word-break: break-all">{{ userEmail }}</text>
|
||||
<text>{{ $t('verifyEmail.subTitleAfter') }}</text>
|
||||
</view>
|
||||
<view class="inputsWrapper">
|
||||
<view @click="clickCodeInput" style="position: absolute; z-index: 10; width: 100%; height: 100%"></view>
|
||||
<view class="input" v-for="index in 6" :key="index">
|
||||
<uni-forms-item :name="`code${index}`">
|
||||
<uni-easyinput
|
||||
:ref="`codeInput${index}`"
|
||||
:maxlength="6"
|
||||
trim="all"
|
||||
primaryColor="#29BBE4"
|
||||
:inputBorder="false"
|
||||
:clearable="false"
|
||||
v-model="emailForm[`code${index}`]"
|
||||
></uni-easyinput>
|
||||
</uni-forms-item>
|
||||
</view>
|
||||
</view>
|
||||
<view style="overflow: hidden">
|
||||
<view class="codeInput">
|
||||
<uni-easyinput maxlength="6" primaryColor="#29BBE4" :focus="codeInputFocus" @blur="codeInputBlur" @input="codeInput"></uni-easyinput>
|
||||
</view>
|
||||
</view>
|
||||
<view class="resendCode" @click="sendCode">
|
||||
<image src="/static/reload.png" mode="aspectFit" :class="['resendIcon', sendCodeBtnLoading ? 'loading' : '']"></image>
|
||||
<text>{{ $t('form.verificationCode.invalid') }}</text>
|
||||
</view>
|
||||
<view>
|
||||
<button class="primaryButton" @click="handleVerifyEmail">{{ $t('form.verifyNow') }}</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { useUserStore } from '@/stores/user';
|
||||
import { sendCodePersonal, verifyEmail } from '@/services/user/completeInfo.ts';
|
||||
import { UserLanguage } from '@/utils/const.ts';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
userEmail: undefined,
|
||||
emailForm: {},
|
||||
sendCodeBtnLoading: false,
|
||||
codeInputFocus: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
clickCodeInput() {
|
||||
this.codeInputFocus = true;
|
||||
},
|
||||
codeInputBlur() {
|
||||
this.codeInputFocus = false;
|
||||
},
|
||||
codeInput(val, index) {
|
||||
for (let i = 0; i < 6; i++) {
|
||||
this.emailForm[`code${i + 1}`] = val.charAt(i) ?? '';
|
||||
}
|
||||
},
|
||||
async sendCode() {
|
||||
const userStore = useUserStore();
|
||||
this.sendCodeBtnLoading = true;
|
||||
const res = await sendCodePersonal({
|
||||
email: userStore.userInfo.email,
|
||||
qcc_language: UserLanguage
|
||||
});
|
||||
this.sendCodeBtnLoading = false;
|
||||
let success = false;
|
||||
if (res && res.code === 0) {
|
||||
this.$cusModal.showModal({
|
||||
type: 'message',
|
||||
status: 'success',
|
||||
contentText: this.$t('form.verificationCode.sendSuccess')
|
||||
});
|
||||
success = true;
|
||||
} else {
|
||||
this.$cusModal.showModal({
|
||||
type: 'message',
|
||||
status: 'warning',
|
||||
contentText: res.msg ?? this.$t('common.error.sysError')
|
||||
});
|
||||
}
|
||||
return success;
|
||||
},
|
||||
async handleVerifyEmail() {
|
||||
const code = Object.values(this.emailForm).join('');
|
||||
const res = await verifyEmail({
|
||||
code,
|
||||
qcc_language: UserLanguage
|
||||
});
|
||||
if (res && res.code === 0) {
|
||||
uni.redirectTo({
|
||||
url: '/pages/user/personalInformation/email/success/index'
|
||||
});
|
||||
} else {
|
||||
this.$cusModal.showModal({
|
||||
type: 'message',
|
||||
status: 'warning',
|
||||
contentText: res.msg ?? this.$t('common.error.sysError')
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const userStore = useUserStore();
|
||||
this.userEmail = userStore.userInfo.email;
|
||||
this.sendCode();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './index.scss';
|
||||
</style>
|
70
pages/user/personalInformation/email/success/index.scss
Normal file
70
pages/user/personalInformation/email/success/index.scss
Normal file
@ -0,0 +1,70 @@
|
||||
.container {
|
||||
padding: 0 24px 24px 16px;
|
||||
.title {
|
||||
margin: 14px 0 15px;
|
||||
}
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
row-gap: 10px;
|
||||
margin-top: 62px;
|
||||
.successTitle {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
color: #333333;
|
||||
text-align: center;
|
||||
}
|
||||
.successTitle2 {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: #333333;
|
||||
text-align: center;
|
||||
}
|
||||
.successDesc {
|
||||
margin-top: 19px;
|
||||
font-size: 12px;
|
||||
color: #aaaaaa;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.btns {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: 12px;
|
||||
.btn {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.stepsWrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
row-gap: 8px;
|
||||
color: #999999;
|
||||
font-size: 12px;
|
||||
margin: 34px 0 20px;
|
||||
.steps {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
column-gap: 3px;
|
||||
width: 100%;
|
||||
height: 10px;
|
||||
padding: 0 3px;
|
||||
border: 1px solid #e5e5e5;
|
||||
border-radius: 10px;
|
||||
box-sizing: border-box;
|
||||
.stepItem {
|
||||
flex: 1;
|
||||
height: 5px;
|
||||
background-color: #e5e5e5;
|
||||
border-radius: 10px;
|
||||
box-sizing: border-box;
|
||||
&.active {
|
||||
background-image: linear-gradient(to right, #103776 0%, #6474af 100%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
76
pages/user/personalInformation/email/success/index.vue
Normal file
76
pages/user/personalInformation/email/success/index.vue
Normal file
@ -0,0 +1,76 @@
|
||||
<template>
|
||||
<NavBar />
|
||||
<view class="container">
|
||||
<view class="title">
|
||||
<PageTitle :title="$t('verifyEmail.pageTitle')" />
|
||||
</view>
|
||||
<view class="content">
|
||||
<image src="/static/success.png" mode="aspectFit" style="width: 56px; height: 56px"></image>
|
||||
<text class="successTitle">{{ $t('verifyEmail.mailSuccess') }}</text>
|
||||
|
||||
<text class="successTitle2" style="padding: 40px 0px;">{{ $t('verifyEmail.successText') }}</text>
|
||||
</view>
|
||||
<view class="btns">
|
||||
<button class="btn primaryButton" type="button" @click="start2">
|
||||
{{ $t('verifyEmail.start2') }}
|
||||
</button>
|
||||
</view>
|
||||
<view class="stepsWrapper">
|
||||
<view class="steps">
|
||||
<view :class="['stepItem', currentStep >= 1 ? 'active' : '']"></view>
|
||||
<view :class="['stepItem', currentStep >= 2 ? 'active' : '']"></view>
|
||||
<view :class="['stepItem', currentStep >= 3 ? 'active' : '']"></view>
|
||||
</view>
|
||||
<text>{{ $t('form.personalData.personalInformation.progress') + `${completePercent}` }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getPersonalAuthStatus } from '@/services/user.ts';
|
||||
export default {
|
||||
name: '',
|
||||
data() {
|
||||
return {
|
||||
authStatus: {}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
start2() {
|
||||
uni.redirectTo({
|
||||
url: `/pages/user/personalInformation/identity/index?proven=${this.getProven()}&authStatus=${JSON.stringify(this.authStatus)}`
|
||||
});
|
||||
},
|
||||
async getAuthStatus() {
|
||||
const res = await getPersonalAuthStatus();
|
||||
if (res && res.code === 0) {
|
||||
this.authStatus = res.data;
|
||||
}
|
||||
},
|
||||
getProven() {
|
||||
if (this.authStatus.identity === 1){
|
||||
return true;
|
||||
}else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getAuthStatus();
|
||||
},
|
||||
computed: {
|
||||
currentStep() {
|
||||
const keys = Object.keys(this.authStatus);
|
||||
return keys.filter((key) => this.authStatus[key] === 1).length;
|
||||
},
|
||||
completePercent() {
|
||||
const keys = Object.keys(this.authStatus);
|
||||
return `${keys.filter((key) => this.authStatus[key] === 1).length} / ${keys.length}`;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './index.scss';
|
||||
</style>
|
Reference in New Issue
Block a user