Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
T
traceSourceMb
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
yanyanhong
traceSourceMb
Commits
003882fe
Commit
003882fe
authored
Jul 23, 2020
by
yyh
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
功能
parent
3b960208
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
396 additions
and
168 deletions
+396
-168
UI规范.png
UI规范.png
+0
-0
user.ts
src/api/modules/user.ts
+24
-0
CommonSvg.vue
src/components/svg/CommonSvg.vue
+1
-1
index.ts
src/router/index.ts
+9
-0
Personal.vue
src/views/auth/Personal.vue
+2
-103
AccountNum.vue
src/views/userCenter/AccountNum.vue
+1
-1
Index.vue
src/views/userCenter/Index.vue
+11
-11
SetPasswd.vue
src/views/userCenter/SetPasswd.vue
+37
-52
SetPhone.vue
src/views/userCenter/SetPhone.vue
+153
-0
CodeInput.vue
src/views/userCenter/components/CodeInput.vue
+105
-0
SetSuccess.vue
src/views/userCenter/components/SetSuccess.vue
+53
-0
No files found.
UI规范.png
0 → 100644
View file @
003882fe
This diff is collapsed.
Click to expand it.
src/api/modules/user.ts
View file @
003882fe
...
@@ -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
;
src/components/svg/CommonSvg.vue
View file @
003882fe
<
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
>
...
...
src/router/index.ts
View file @
003882fe
...
@@ -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
...
...
src/views/auth/Personal.vue
View file @
003882fe
...
@@ -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
src/views/userCenter/AccountNum.vue
View file @
003882fe
...
@@ -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>
...
...
src/views/userCenter/Index.vue
View file @
003882fe
...
@@ -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
:
'账号信息'
,
...
...
src/views/userCenter/SetPasswd.vue
View file @
003882fe
<
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
onDelet
e
()
{
get
codeTyp
e
()
{
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'
;
}
}
}
}
...
...
src/views/userCenter/SetPhone.vue
0 → 100644
View file @
003882fe
<
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
:
31
px
25
px
;
.
title
{
font
-
size
:
22
px
;
color
:
#
353535
;
font
-
weight
:
500
;
text
-
align
:
left
;
}
.
margin
-
top30
{
margin
-
top
:
30
px
;
}
}
<
/style>
\ No newline at end of file
src/views/userCenter/components/CodeInput.vue
0 → 100644
View file @
003882fe
<
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
:
31
px
25
px
;
.
title
{
font
-
size
:
22
px
;
color
:
#
353535
;
font
-
weight
:
500
;
text
-
align
:
left
;
}
.
margin
-
top30
{
margin
-
top
:
30
px
;
}
}
<
/style>
\ No newline at end of file
src/views/userCenter/components/SetSuccess.vue
0 → 100644
View file @
003882fe
<
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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment