Commit 003882fe authored by yyh's avatar yyh

功能

parent 3b960208
This diff is collapsed.
...@@ -43,6 +43,14 @@ const user = { ...@@ -43,6 +43,14 @@ const user = {
...params, ...params,
}); });
}, },
setPwdCode(codeType: number, code: string, params: any) {
return axios.post(`${base}/setPwdCode`, {
code_type: codeType,
code,
country: '86',
...params,
});
},
getUserInfo(id: number = 0) { getUserInfo(id: number = 0) {
return axios.get(`${base}/${id}`); return axios.get(`${base}/${id}`);
}, },
...@@ -51,5 +59,21 @@ const user = { ...@@ -51,5 +59,21 @@ const user = {
...params, ...params,
}); });
}, },
setPhone(code: string, newPhone: string, randomToken: string, params: any) {
return axios.post(`${base}/setPhone`, {
code,
new_phone: newPhone,
random_token: randomToken,
...params,
});
},
setPhoneCode(codeType: string, code: string, params: any) {
return axios.post(`${base}/setPhoneCode`, {
code_type: codeType,
code,
country: '86',
...params,
});
}
}; };
export default user; export default user;
<template> <template>
<svg class="icon" aria-hidden="true" :style="{width:width,height:height}"> <svg class="icon" aria-hidden="true" :style="{width:width,height:height}" style="width:100px;height:100px;">
<use :xlink:href="`#icon-${name}`"></use> <use :xlink:href="`#icon-${name}`"></use>
</svg> </svg>
</template> </template>
......
...@@ -145,6 +145,15 @@ const routes: RouteConfig[] = [ ...@@ -145,6 +145,15 @@ const routes: RouteConfig[] = [
meta: { requiresAuth: true }, meta: { requiresAuth: true },
}, },
{ {
path: '/setPhone',
name: 'SetPhone',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '@/views/userCenter/SetPhone.vue'),
meta: { requiresAuth: true },
},
{
path: '/auth/personal', path: '/auth/personal',
name: 'Personal', name: 'Personal',
// route level code-splitting // route level code-splitting
......
...@@ -226,108 +226,6 @@ export default class Personal extends Vue { ...@@ -226,108 +226,6 @@ export default class Personal extends Vue {
justify-content: space-between; justify-content: space-between;
} }
} }
.toast{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 40px 20px;
border-radius: 10px;
$colors:
hsla(337, 84, 48, 0.75)
hsla(160, 50, 48, 0.75)
hsla(190, 61, 65, 0.75)
hsla( 41, 82, 52, 0.75);
$size: 2.5em;
$thickness: 0.5em;
// Calculated variables.
$lat: ($size - $thickness) / 2;
$offset: $lat - $thickness;
.loader-container{
position: relative;
width: $size;
height: $size;
transform: rotate(165deg);
&:before,
&:after {
content: '';
position: absolute;
top: 50%;
left: 50%;
display: block;
width: $thickness;
height: $thickness;
border-radius: $thickness / 2;
transform: translate(-50%, -50%);
}
&:before {
animation: before 2s infinite;
}
&:after {
animation: after 2s infinite;
}
}
@keyframes before {
0% {
width: $thickness;
box-shadow:
$lat (-$offset) nth($colors, 1),
(-$lat) $offset nth($colors, 3);
}
35% {
width: $size;
box-shadow:
0 (-$offset) nth($colors, 1),
0 $offset nth($colors, 3);
}
70% {
width: $thickness;
box-shadow:
(-$lat) (-$offset) nth($colors, 1),
$lat $offset nth($colors, 3);
}
100% {
box-shadow:
$lat (-$offset) nth($colors, 1),
(-$lat) $offset nth($colors, 3);
}
}
@keyframes after {
0% {
height: $thickness;
box-shadow:
$offset $lat nth($colors, 2),
(-$offset) (-$lat) nth($colors, 4);
}
35% {
height: $size;
box-shadow:
$offset 0 nth($colors, 2),
(-$offset) 0 nth($colors, 4);
}
70% {
height: $thickness;
box-shadow:
$offset (-$lat) nth($colors, 2),
(-$offset) $lat nth($colors, 4);
}
100% {
box-shadow:
$offset $lat nth($colors, 2),
(-$offset) (-$lat) nth($colors, 4);
}
}
.loader{
position: absolute;
top: calc(50% - #{$size / 2});
left: calc(50% - #{$size / 2});
}
}
} }
</style> </style>
\ No newline at end of file
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<common-svg name="jinru" class="icon"></common-svg> <common-svg name="jinru" class="icon"></common-svg>
</div> </div>
</label> </label>
<div class="item"> <div class="item" @click="$router.push({name:'SetPhone'})">
<div class="title">手机号</div> <div class="title">手机号</div>
<div class="right"> <div class="right">
<div class="desc">{{userInfo.phone}}</div> <div class="desc">{{userInfo.phone}}</div>
......
...@@ -7,14 +7,14 @@ ...@@ -7,14 +7,14 @@
<div v-else style="color:#353535;font-size: 20px;font-weight: 500;" @click="toLogin">立即登录</div> <div v-else style="color:#353535;font-size: 20px;font-weight: 500;" @click="toLogin">立即登录</div>
</div> </div>
<div> <div>
<common-svg name="yirenzheng" width="60px" height="22px" v-if="isLogin"></common-svg> <common-svg :name="userInfo.auth_suc ? 'yirenzheng' : 'weirenzheng'" style="width:120px;height:40px;" v-if="isLogin"></common-svg>
<div style="color:#B6B5BA;font-size: 12px;" v-else>登录建立存证溯源</div> <div style="color:#B6B5BA;font-size: 12px;" v-else>登录建立存证溯源</div>
</div> </div>
<common-svg name="shezhi" class="right" v-if="isLogin" @click.native="go('AccountNum')" style="margin: 5px;"></common-svg> <common-svg name="shezhi" class="right" v-if="isLogin" @click.native="go('AccountNum')" style="margin: 5px;"></common-svg>
</header> </header>
<section class="asset" style="margin-top:30px;"> <section class="asset" style="margin-top:30px;">
<div>剩余次数</div> <div>剩余次数</div>
<div style="font-size:30px;font-weight:500;">0</div> <div style="font-size:30px;font-weight:500;">{{chainTimes}}</div>
<router-link tag="div" class="btn" role="button" :to="{name:'Recharge'}">去充值</router-link> <router-link tag="div" class="btn" role="button" :to="{name:'Recharge'}">去充值</router-link>
</section> </section>
<section style="margin-top:30px;"> <section style="margin-top:30px;">
...@@ -34,6 +34,15 @@ import { Component, Prop, Vue, Watch } from 'vue-property-decorator'; ...@@ -34,6 +34,15 @@ import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
import { Cell, Form, Field, CellGroup, Button, Image, Uploader } from 'vant'; import { Cell, Form, Field, CellGroup, Button, Image, Uploader } from 'vant';
import { Getter, State, Action } from 'vuex-class'; import { Getter, State, Action } from 'vuex-class';
import { AuthStatus } from '@/const/enum'; import { AuthStatus } from '@/const/enum';
const authTypeObj: any = {
0: 'Auth',
1: 'Personal',
2: 'Enterprise',
};
const authSucStr: any = {
0: '未认证',
1: '已认证',
};
@Component({ @Component({
components: { components: {
[Form.name]: Form, [Form.name]: Form,
...@@ -63,15 +72,6 @@ export default class Index extends Vue { ...@@ -63,15 +72,6 @@ export default class Index extends Vue {
}; };
get datas() { get datas() {
const { auth_type, auth_suc } = this.userInfo; const { auth_type, auth_suc } = this.userInfo;
const authTypeObj: any = {
0: 'Auth',
1: 'Personal',
2: 'Enterprise',
};
const authSucStr: any = {
0: '未认证',
1: '已认证',
};
return [ return [
{ {
title: '账号信息', title: '账号信息',
......
<template> <template>
<div class="set-passwd"> <div class="set-passwd">
<section v-if="step == '1'"> <section v-if="step == '1'">
<div class="title">设置密码</div> <div class="title">设置密码</div>
<van-field :value="userInfo.phone || userInfo.email" label="" placeholder="请输入你的手机号" class="margin-top30"></van-field> <van-field :value="userInfo.phone || userInfo.email" label="" readonly placeholder="请输入你的手机号" class="margin-top30"></van-field>
<van-button block style="margin-top: 60px;" type="info" @click="sendCode">获取验证码</van-button> <van-button block style="margin-top: 60px;" type="info" @click="step = '2'">获取验证码</van-button>
</section> </section>
<section v-if="step == '2'"> <code-input v-if="step == '2'" :code.sync="code" :codeTo="userInfo.phone || userInfo.email" :sendCode="sendCode" :validateCode="validateCode" :next="showPassWordInputHandler"></code-input>
<div class="title">输入验证码</div> <section v-if="step == '3'">
<div style="font-size: 14px; color: #999999;text-align:left;line-height: 2em;margin-bottom: 30px;">6位验证码已发送至{{phone}}</div> <div class="title">输入密码</div>
<van-password-input <van-field v-model="pwd" label="" placeholder="请输入6~16位密码" class="margin-top30"></van-field>
:value="code" <van-button block type="info" class="margin-top30" @click="setPwd">确定</van-button>
:mask="false" </section>
:focused="showKeyboard" <transition name="van-slide-up">
@focus="showKeyboard = true" <set-success v-if="step == '4'"></set-success>
/> </transition>
<van-number-keyboard </div>
:show="showKeyboard"
@input="onInput"
@delete="onDelete"
@blur="showKeyboard = false"
/>
<div style="color:#737582;font-size: 14px;text-align:left;margin-top:15px;">重新发送(50s)</div>
</section>
<section v-if="step == '3'">
<div class="title">输入密码</div>
<van-field v-model="pwd" label="" placeholder="请输入6~16位密码" class="margin-top30"></van-field>
<van-button block type="info" class="margin-top30" @click="setPwd">确定</van-button>
</section>
<section v-if="step == '4'">
<div class="title" style="text-align:center;">设置成功</div>
<van-image src="@/assets/success.png" width="64px" fit="contain" style="margin-top:41px;"></van-image>
<div style="color:#737582;font-size: 16px;margin-top:16px;">密码设置成功</div>
<van-button block type="info" style="margin-top: 200px;" :to="{name: 'UserCenter'}">返回个人中心</van-button>
<div style="color:#B6B5BA; font-size: 14px;margin-top: 20px;" >5秒后跳转到个人中心</div>
</section>
</div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator'; import { Component, Prop, Vue } from 'vue-property-decorator';
import { Cell, Form, Field, CellGroup, Button, Image, RadioGroup, Radio, PasswordInput, NumberKeyboard } from 'vant'; import { Cell, Form, Field, CellGroup, Button, Image, RadioGroup, Radio, PasswordInput, NumberKeyboard } from 'vant';
import { State, Getter, Action, Mutation } from 'vuex-class'; import { State, Getter, Action, Mutation } from 'vuex-class';
import { Route } from 'vue-router'; import { Route } from 'vue-router';
import SetSuccess from './components/SetSuccess.vue';
import CodeInput from './components/CodeInput.vue';
@Component({ @Component({
components: { components: {
[Form.name]: Form, [Form.name]: Form,
...@@ -53,25 +34,21 @@ import { Route } from 'vue-router'; ...@@ -53,25 +34,21 @@ import { Route } from 'vue-router';
[Radio.name]: Radio, [Radio.name]: Radio,
[PasswordInput.name]: PasswordInput, [PasswordInput.name]: PasswordInput,
[NumberKeyboard.name]: NumberKeyboard, [NumberKeyboard.name]: NumberKeyboard,
SetSuccess,
CodeInput,
}, },
}) })
export default class SetPasswd extends Vue { export default class SetPasswd extends Vue {
@State('userInfo') private userInfo!: any; @State('userInfo') private userInfo!: any;
@Action('getUserInfo') private getUserInfo!: () => void; @Action('getUserInfo') private getUserInfo!: () => void;
private phone: string = '';
private code: string = ''; private code: string = '';
private pwd: string = ''; private pwd: string = '';
private showKeyboard: boolean = false;
private step: string = '1'; private step: string = '1';
private onInput(key: any) { get isPhone() {
this.code = (this.code + key).slice(0, 6); return this.userInfo.phone;
const { length } = this.code;
if (length === 6) {
this.step = '3';
}
} }
private onDelete() { get codeType() {
this.code = this.code.slice(0, this.code.length - 1); return this.isPhone ? 0 : 1;
} }
private sendSms() { private sendSms() {
return this.$api.user.sendSms(this.userInfo.phone , 1); // 1 修改密码 return this.$api.user.sendSms(this.userInfo.phone , 1); // 1 修改密码
...@@ -79,18 +56,26 @@ export default class SetPasswd extends Vue { ...@@ -79,18 +56,26 @@ export default class SetPasswd extends Vue {
private sendEmail() { private sendEmail() {
return this.$api.user.sendEmail(this.userInfo.email, 1); // 1 修改密码 return this.$api.user.sendEmail(this.userInfo.email, 1); // 1 修改密码
} }
private async sendCode() { private async sendCode() {
const { userInfo } = this; if (this.isPhone) {
if (userInfo.phone) {
await this.sendSms(); await this.sendSms();
} else { } else {
await this.sendEmail(); await this.sendEmail();
} }
this.step = '2'; }
private validateCode() {
const { phone, email} = this.userInfo;
return this.$api.user.setPwdCode( this.codeType, this.code, {
phone,
email,
})
}
private showPassWordInputHandler() {
this.step = '3';
} }
private async setPwd() { private async setPwd() {
const { userInfo: { phone, email }, pwd, code } = this; const { userInfo: { phone, email }, pwd, code } = this;
await this.$api.user.setPwd(phone ? 0 : 1, pwd, code , { phone, email }); await this.$api.user.setPwd(this.codeType, pwd, code, { phone, email });
this.step = '4'; this.step = '4';
} }
} }
......
<template>
<div class="set-passwd">
<section v-if="step == '1'" style="color:#353535;text-align:left;line-height: 1.5em;">
<div style="font-size: 20px;">已绑定手机号</div>
<div class="title" style="font-size:25px;margin-top:5px;margin-bottom:22px;">{{userInfo.phone || userInfo.email}}</div>
<div style="font-size:14px;color:#737582;">绑定手机号将作为您身份验证的重要方式,请谨慎操作!</div>
<van-button block style="margin-top: 60px;" type="info" @click="sendCode">更改手机号</van-button>
<div style="font-size:12px;color:#999999;margin-top:17px;">变更手机号后,将自动同步新手机号为登录账号</div>
</section>
<section v-if="step == '2'">
<div class="title">输入验证码</div>
<div style="font-size: 14px; color: #999999;text-align:left;line-height: 2em;margin-bottom: 30px;">6位验证码已发送至{{userInfo.phone || userInfo.email}}</div>
<van-password-input
:value="code"
:mask="false"
:focused="showKeyboard"
@focus="showKeyboard = true"
/>
<van-number-keyboard
:show="showKeyboard"
@input="onInput"
@delete="onDelete"
@blur="showKeyboard = false"
/>
<div style="color:#737582;font-size: 14px;text-align:left;margin-top:15px;" @click="sendCode">重新发送{{count > 0 ? `(${count}s)` : ''}}</div>
</section>
<section v-if="step == '3'">
<div class="title">输入新手机号</div>
<van-field v-model="newPhone" label="" placeholder="请输入新手机号" class="margin-top30"></van-field>
<van-button block type="info" class="margin-top30" @click="sendCode">确定</van-button>
</section>
<section v-if="step == '4'">
<div class="title">输入验证码</div>
<div style="font-size: 14px; color: #999999;text-align:left;line-height: 2em;margin-bottom: 30px;">6位验证码已发送至{{userInfo.phone || userInfo.email}}</div>
<van-password-input
:value="code"
:mask="false"
:focused="showKeyboard"
@focus="showKeyboard = true"
/>
<van-number-keyboard
:show="showKeyboard"
@input="onInput"
@delete="onDelete"
@blur="showKeyboard = false"
/>
<div style="color:#737582;font-size: 14px;text-align:left;margin-top:15px;" @click="sendCode">重新发送{{count > 0 ? `(${count}s)` : ''}}</div>
</section>
<set-success v-if="step === '5'" :tip="'手机号设置成功'"></set-success>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import { Cell, Form, Field, CellGroup, Button, Image, RadioGroup, Radio, PasswordInput, NumberKeyboard } from 'vant';
import { State, Getter, Action, Mutation } from 'vuex-class';
import { Route } from 'vue-router';
import SetSuccess from './components/SetSuccess.vue';
@Component({
components: {
[Form.name]: Form,
[Field.name]: Field,
[Button.name]: Button,
[Image.name]: Image,
[Cell.name]: Cell,
[RadioGroup.name]: RadioGroup,
[Radio.name]: Radio,
[PasswordInput.name]: PasswordInput,
[NumberKeyboard.name]: NumberKeyboard,
SetSuccess,
},
})
export default class SetPhone extends Vue {
@State('userInfo') private userInfo!: any;
@Action('getUserInfo') private getUserInfo!: () => void;
private code: string = '';
private randomToken: string = '';
private newPhone: string = '';
private showKeyboard: boolean = false;
private step: string = '1';
private count: number = 0;
get isPhone() {
return this.userInfo.phone;
}
get codeType() {
return this.isPhone ? 0 : 1;
}
private async onInput(key: any) {
const { userInfo: { phone, email }, code, newPhone } = this;
this.code = (this.code + key).slice(0, 6);
const { length } = this.code;
if (length >= 6) {
const { random_token } = await this.$api.user.setPhoneCode( this.codeType, this.code, {
phone,
email,
});
this.randomToken = random_token;
this.count = 0;
if (!newPhone) {
this.step = '3';
this.code = '';
} else {
await this.setPhone();
}
}
}
private onDelete() {
this.code = this.code.slice(0, this.code.length - 1);
}
private sendSms() {
return this.$api.user.sendSms(this.userInfo.phone , 1); // 1 修改密码
}
private sendEmail() {
return this.$api.user.sendEmail(this.userInfo.email, 1); // 1 修改密码
}
private async sendCode() {
if (this.count > 0 ) { return; }
this.count = 60;
const timer = setInterval(() => { if (this.count > 0) { this.count--; } }, 1000);
this.$once('hook:beforeDestory', () => {
clearTimeout(timer);
});
const { userInfo } = this;
if (this.isPhone) {
await this.sendSms();
} else {
await this.sendEmail();
}
this.step = this.newPhone ? '4' : '2';
}
private async setPhone() {
const {code, newPhone, randomToken } = this;
await this.$api.user.setPhone(code, newPhone, randomToken);
this.step = '5';
}
}
</script>
<style scoped lang="scss">
.set-passwd {
padding: 31px 25px;
.title{
font-size: 22px;
color: #353535;
font-weight: 500;
text-align: left;
}
.margin-top30{
margin-top: 30px;
}
}
</style>
\ No newline at end of file
<template>
<section>
<div class="title">输入验证码</div>
<div style="font-size: 14px; color: #999999;text-align:left;line-height: 2em;margin-bottom: 30px;">6位验证码已发送至{{codeTo}}</div>
<van-password-input
:value="code"
:mask="false"
:focused="showKeyboard"
@focus="showKeyboard = true"
/>
<van-number-keyboard
:show="showKeyboard"
@input="onInput"
@delete="onDelete"
@blur="showKeyboard = false"
/>
<div style="color:#737582;font-size: 14px;text-align:left;margin-top:15px;" @click="timerDown">重新发送{{count > 0 ? `(${count}s)` : ''}}</div>
</section>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import { Button, Image, PasswordInput, NumberKeyboard } from 'vant';
import { State, Getter, Action, Mutation } from 'vuex-class';
import { Route } from 'vue-router';
@Component({
components: {
[Button.name]: Button,
[Image.name]: Image,
[PasswordInput.name]: PasswordInput,
[NumberKeyboard.name]: NumberKeyboard,
},
})
export default class CodeInput extends Vue {
@Prop({
required: true,
})
private codeTo!: string;
@Prop()
private code!: string;
@Prop({
default: () => {},
})
private sendCode!: () => Promise<any>;
@Prop({
default: () => {},
})
private validateCode!: () => Promise<any>;
@Prop({
default: () => {},
})
private next!: () => Promise<any>;
private count: number = 0;
private showKeyboard: boolean = true;
private mounted() {
this.timerDown();
}
private timerDown() {
if (this.count > 0 ) { return; }
this.count = 60;
this.sendCode();
const timer = setInterval(() => {
if ( this.count <= 0) {
clearInterval(timer);
return;
}
this.count--;
}, 1000);
this.$once('hook:beforeDestory', () => {
clearInterval(timer);
});
}
private async onInput(key: any) {
let code = (this.code + key).slice(0, 6);
this.$emit('update:code', code );
if (code.length < 6) { return; }
try {
await this.validateCode();
this.showKeyboard = false;
this.next();
}catch(err){
console.log(err);
}
}
private onDelete() {
const { code, code: { length }} = this;
this.$emit('update:code', code.slice(0, length - 1));
}
}
</script>
<style scoped lang="scss">
.set-passwd {
padding: 31px 25px;
.title{
font-size: 22px;
color: #353535;
font-weight: 500;
text-align: left;
}
.margin-top30{
margin-top: 30px;
}
}
</style>
\ No newline at end of file
<template>
<section class="set-success">
<div class="title" style="text-align:center;">设置成功</div>
<van-image src="@/assets/success.png" width="64px" fit="contain" style="margin-top:41px;"></van-image>
<div style="color:#737582;font-size: 16px;margin-top:16px;">{{tip}}</div>
<van-button block type="info" style="margin-top: 200px;" :to="{name: 'UserCenter'}">返回个人中心</van-button>
<div style="color:#B6B5BA; font-size: 14px;margin-top: 20px;" >{{count}}秒后跳转到个人中心</div>
</section>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import { Button, Image } from 'vant';
import { State, Getter, Action, Mutation } from 'vuex-class';
import { Route } from 'vue-router';
@Component({
components: {
[Button.name]: Button,
[Image.name]: Image,
},
})
export default class SetSuccess extends Vue {
@Prop({
default: '密码设置成功',
})
private tip!: string;
private count: number = 5;
private mounted() {
const timer = setInterval(() => {
const { count } = this;
if ( count <= 0) {
clearInterval(timer);
return this.$router.replace('/userCenter/index');
}
this.count--;
}, 1000);
this.$once('hook:beforeDestory', () => {
clearInterval(timer);
});
}
}
</script>
<style scoped lang="scss">
.set-success {
.title{
font-size: 22px;
color: #353535;
font-weight: 500;
text-align: left;
}
}
</style>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment