Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
pptist
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
viitto
pptist
Commits
89130ab2
Commit
89130ab2
authored
May 24, 2024
by
罗超
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
完成密码找回流程
parent
ed357085
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
257 additions
and
3 deletions
+257
-3
global.scss
src/assets/styles/global.scss
+1
-1
index.ts
src/router/index.ts
+1
-1
router.ts
src/router/router.ts
+7
-0
UserService.ts
src/services/UserService.ts
+14
-0
Forgot.vue
src/views/Auth/Forgot.vue
+132
-0
Login.vue
src/views/Auth/Login.vue
+4
-1
Regist.vue
src/views/Auth/Regist.vue
+3
-0
VerifyCode.vue
src/views/components/element/Verify/VerifyCode.vue
+95
-0
No files found.
src/assets/styles/global.scss
View file @
89130ab2
...
...
@@ -144,5 +144,5 @@ textarea {
--el-color-primary-light-9
:
#dedcff
!
important
;
--el-color-primary-dark-2
:
#281ae6
!
important
;
--el-border-color
:
#e8eaec
!
important
;
--el-border-radius-base
:
8
px
!
important
;
--el-border-radius-base
:
6
px
!
important
;
}
\ No newline at end of file
src/router/index.ts
View file @
89130ab2
...
...
@@ -9,7 +9,7 @@ const router = createRouter({
})
const
whiteList
=
[
'/autoLogin'
,
'/login'
,
'/notfound'
,
'/regist'
,
'/'
]
const
whiteList
=
[
'/autoLogin'
,
'/login'
,
'/notfound'
,
'/regist'
,
'/'
,
'/forgot'
]
const
managerMenu
=
[
'/market'
,
'/editor_admin'
]
let
loadingInstance
:
any
=
null
...
...
src/router/router.ts
View file @
89130ab2
...
...
@@ -53,6 +53,13 @@ const routes: RouteRecordRaw[] = [
title
:
'注册 Travel Design'
}
},
{
path
:
'/forgot'
,
component
:
()
=>
import
(
'@/views/Auth/Forgot.vue'
),
meta
:{
title
:
'忘记密码 Travel Design'
}
},
{
path
:
'/notfound'
,
component
:
()
=>
import
(
'@/views/ErrorNotFound.vue'
),
...
...
src/services/UserService.ts
View file @
89130ab2
...
...
@@ -81,5 +81,19 @@ class UserServices{
let
msg
=
{}
return
Api
.
Post
(
"travel_login_verify"
,
msg
)
}
static
async
SendResetPassCodeAsync
(
mail
:
string
):
Promise
<
HttpResponse
>
{
let
msg
=
{
mail
}
return
Api
.
Post
(
"travel_forgot_pass"
,
msg
)
}
static
async
VerifyResetPassCodeAsync
(
mail
:
string
,
code
:
string
,
v_token
:
string
):
Promise
<
HttpResponse
>
{
let
msg
:
any
=
{
code
}
if
(
mail
!=
''
)
msg
.
mail
=
mail
if
(
v_token
!=
''
)
msg
.
v_token
=
v_token
return
Api
.
Post
(
"travel_verify_forgotcode"
,
msg
)
}
static
async
ResetPasswordAsync
(
pw
:
string
,
v_token
:
string
):
Promise
<
HttpResponse
>
{
let
msg
:
any
=
{
pw
,
v_token
}
return
Api
.
Post
(
"travel_reset_password"
,
msg
)
}
}
export
default
UserServices
;
\ No newline at end of file
src/views/Auth/Forgot.vue
0 → 100644
View file @
89130ab2
<
template
>
<div
class=
"full-width window-height row"
style=
"background-color: #F1F2F4;"
>
<div
class=
"col"
>
<div
class=
" full-height column"
style=
"padding: 50px 0; width:435px;margin:0 auto"
>
<div>
<img
src=
"https://imgfile.oytour.com/static/pptdefault1.png"
style=
"height: 25px;width: auto;"
>
</div>
<div
class=
"col column items-center flex-center full-width"
>
<div
class=
"text-center full-width"
v-if=
"!resetToken"
>
<div
class=
"text-weight-bold text-dark"
style=
"font-size: 23px;"
>
忘记密码?
</div>
<div
class=
"text-info q-mt-md q-mb-xl"
style=
"font-size: 14px; font-weight: 500;"
>
输入你的注册邮箱,重置你的密码。
</div>
<el-input
v-model=
"email"
placeholder=
"邮箱"
size=
"large"
clearable
class=
"pingfangr full-width"
:readonly=
"isSend"
style=
"height:50px !important;"
>
<template
#
suffix
>
<el-button
link
:loading=
"sending"
v-if=
"!isCountdown && isSend"
@
click=
"sendVerifyCode"
>
重新发送
</el-button>
<template
v-if=
"isCountdown"
>
<el-countdown
title=
""
format=
"ss"
:value=
"countValue"
value-style=
"font-size:14px;color:#f89c53;"
class=
"inline q-mx-sm"
@
finish=
"()=>isCountdown=false"
/>
s
</
template
>
</template>
</el-input>
<div
class=
"q-mt-lg"
v-if=
"isSend"
>
<div
class=
"text-small text-info text-left q-mb-md"
>
请输入邮件验证码:
</div>
<VerifyCode
v-model=
"code"
:digit=
"6"
></VerifyCode>
</div>
<el-button
type=
"primary"
size=
"large"
class=
"q-mt-lg ppt-button"
:disabled=
"!mailRegex.test(email)"
@
click=
"sendVerifyCode"
:loading=
"sending"
v-if=
"!isSend"
>
发送验证码
</el-button>
<el-button
type=
"primary"
size=
"large"
class=
"q-mt-lg ppt-button"
:disabled=
"code.length!=6"
:loading=
"sending"
v-if=
"isSend && !sending"
@
click=
"verifyHandler"
>
提交验证码
</el-button>
</div>
<div
class=
"full-width"
v-if=
"resetToken"
>
<div
class=
"text-weight-bold text-dark"
style=
"font-size: 16px;"
>
重新设置你的密码
</div>
<div
class=
"text-weight-bold text-dark q-mt-md"
style=
"font-size: 24px;"
>
{{ resetToken.mail }}
</div>
<div
class=
"text-info q-mt-md q-mb-xl"
style=
"font-size: 14px; font-weight: 500;"
>
我们建议你的密码包含大写+小写+数字+特殊字符进行组合
</div>
<el-input
v-model=
"resetModel.newPassword"
type=
"password"
placeholder=
"新密码"
size=
"large"
show-password
class=
"pingfangr full-width"
style=
"height:50px !important;"
/>
<el-input
v-model=
"resetModel.confirmPassword"
type=
"password"
placeholder=
"确认密码"
size=
"large"
show-password
class=
"pingfangr full-width q-mt-lg"
style=
"height:50px !important;"
/>
<div>
<el-button
type=
"primary"
size=
"large"
class=
"q-mt-lg ppt-button"
@
click=
"resetPassword"
:loading=
"loading"
>
确认密码
</el-button>
</div>
</div>
</div>
<div>
<el-button
link
icon=
"Back"
size=
"large"
class=
"ppt-button text-weight-bolder"
@
click=
"forwardHandler('/login')"
>
返回登录
</el-button>
</div>
</div>
</div>
<div
class=
"col forgot-right-panel column flex-center items-center"
>
<img
src=
"https://viitto-1301420277.cos.ap-chengdu.myqcloud.com/Upload/Goods/638521566644129630.png"
style=
"width:400px;user-select: none"
>
</div>
</div>
</template>
<
script
lang=
"ts"
setup
>
import
{
ApiResult
}
from
"@/configs/axios"
;
import
UserServices
from
"@/services/UserService"
;
import
{
ElMessage
}
from
"element-plus"
;
import
{
reactive
,
ref
}
from
"vue"
;
import
VerifyCode
from
"@/views/components/element/Verify/VerifyCode.vue"
;
import
{
useRouter
}
from
"vue-router"
;
const
email
=
ref
(
''
)
const
mailRegex
=
/^
[
A-Za-z0-9
\u
4e00-
\u
9fa5
]
+@
[
a-zA-Z0-9_-
]
+
(
.
[
a-zA-Z0-9_-
]
+
)
+$/
const
loading
=
ref
(
false
)
const
sending
=
ref
(
false
)
const
code
=
ref
(
''
)
const
isSend
=
ref
(
false
)
const
isCountdown
=
ref
(
false
)
const
countValue
=
ref
<
number
>
(
0
)
const
resetToken
=
ref
<
any
>
()
const
resetModel
=
reactive
({
newPassword
:
''
,
confirmPassword
:
''
})
const
router
=
useRouter
()
const
sendVerifyCode
=
async
()
=>
{
if
(
!
mailRegex
.
test
(
email
.
value
)
||
sending
.
value
)
return
sending
.
value
=
true
const
response
=
await
UserServices
.
SendResetPassCodeAsync
(
email
.
value
)
if
(
response
.
data
.
resultCode
==
ApiResult
.
SUCCESS
){
ElMessage
.
success
({
message
:
'验证码已发送,请前往邮箱查看'
})
isCountdown
.
value
=
true
countValue
.
value
=
Date
.
now
()
+
1000
*
60
isSend
.
value
=
true
}
else
{
ElMessage
.
error
({
message
:
response
.
data
.
message
})
}
sending
.
value
=
false
}
const
verifyHandler
=
async
()
=>
{
if
(
code
.
value
.
length
!=
6
||
!
mailRegex
.
test
(
email
.
value
)
||
sending
.
value
||
loading
.
value
)
return
loading
.
value
=
true
const
response
=
await
UserServices
.
VerifyResetPassCodeAsync
(
email
.
value
,
code
.
value
,
''
)
if
(
response
.
data
.
resultCode
==
ApiResult
.
SUCCESS
){
resetToken
.
value
=
response
.
data
.
data
ElMessage
.
success
({
message
:
'验证成功,请重新设置你的密码'
})
}
else
{
ElMessage
.
error
({
message
:
response
.
data
.
message
})
}
loading
.
value
=
false
}
const
resetPassword
=
async
()
=>
{
if
(
resetModel
.
newPassword
.
length
<
6
||
resetModel
.
newPassword
.
length
>
20
){
ElMessage
.
error
({
message
:
'新密码长度应为6-20位'
})
return
}
if
(
resetModel
.
newPassword
!=
resetModel
.
confirmPassword
){
ElMessage
.
error
({
message
:
'两次输入的密码不一致, 请重新输入'
})
return
}
if
(
loading
.
value
)
return
loading
.
value
=
true
const
response
=
await
UserServices
.
ResetPasswordAsync
(
resetModel
.
newPassword
,
resetToken
.
value
.
r_token
)
if
(
response
.
data
.
resultCode
==
ApiResult
.
SUCCESS
){
ElMessage
.
success
({
message
:
'密码更新成功,正在前往登录页面'
})
setTimeout
(()
=>
{
forwardHandler
(
'/login'
)
},
1000
);
return
}
ElMessage
.
error
({
message
:
response
.
data
.
message
})
loading
.
value
=
false
}
const
forwardHandler
=
(
path
:
string
)
=>
{
router
.
push
({
path
})
}
</
script
>
<
style
>
.forgot-right-panel
{
background-image
:
url('https://viitto-1301420277.cos.ap-chengdu.myqcloud.com/Upload/Goods/638521440349462315.png')
;
background-position
:
center
;
background-size
:
cover
;
}
</
style
>
\ No newline at end of file
src/views/Auth/Login.vue
View file @
89130ab2
...
...
@@ -50,7 +50,7 @@
<div
class=
"col"
>
<vue-hcaptcha
ref=
"invisibleHcaptcha"
sitekey=
"46e00e53-ddb2-4e7b-9c51-621534c2f1f5"
@
verify=
"verifyHandler"
v-if=
"needVerify"
></vue-hcaptcha>
</div>
<el-button
link
type=
"primary"
>
忘记密码?
</el-button>
<el-button
link
type=
"primary"
@
click=
"redicetToForgot"
>
忘记密码?
</el-button>
</div>
</el-form-item>
<el-form-item>
...
...
@@ -190,6 +190,9 @@ const forwardWorkspaceHandler = ()=>{
const
redicetToRegist
=
()
=>
{
location
.
href
=
'/regist'
}
const
redicetToForgot
=
()
=>
{
location
.
href
=
'/forgot'
}
const
clearCompanyChoosenHandler
=
()
=>
{
multipleUsers
.
value
=
[]
model
.
value
.
tid
=
''
...
...
src/views/Auth/Regist.vue
View file @
89130ab2
...
...
@@ -171,9 +171,12 @@ const sendVerifyCode = async () => {
const
response
=
await
UserServices
.
SendRegistCodeAsync
(
model
.
value
.
mail
)
if
(
response
.
data
.
resultCode
==
ApiResult
.
SUCCESS
){
ElMessage
.
success
({
message
:
'验证码已发送,请前往邮箱查看'
})
isCountdown
.
value
=
true
countValue
.
value
=
Date
.
now
()
+
1000
*
60
isSend
.
value
=
true
}
else
{
ElMessage
.
error
({
message
:
response
.
data
.
message
})
}
sending
.
value
=
false
...
...
src/views/components/element/Verify/VerifyCode.vue
0 → 100644
View file @
89130ab2
<
template
>
<form
autocorrect=
"off"
autocapitalize=
"off"
autocomplete=
"off"
spellcheck=
"false"
>
<div
class=
"row flex-between"
>
<div
v-for=
"(x, i) in formatStyle.col"
:key=
"i"
class=
"override-verfity-ipt"
style=
"width: 60px"
>
<el-input
style=
"height: 60px"
v-model=
"formatStyle.col[i]"
@
focus=
"codeFocus($event)"
:ref=
"setRef"
@
keyup=
"changFocus($event, i)"
maxlength=
"1"
/>
</div>
<div
class=
"q-my-md negative f12"
v-if=
"hasError"
>
{{
errorMsg
}}
</div>
</div>
</form>
</
template
>
<
script
>
import
{
reactive
,
ref
}
from
'vue'
export
default
{
props
:
{
/**
* @description 请传入能够被12整除的整数
*/
digit
:
Number
,
/**
* @description 提示语
*/
hint
:
String
,
/**
* @description 绑定值
*/
modelValue
:
[
String
,
Number
]
},
setup
(
props
,
context
)
{
const
cols
=
reactive
([])
const
hasError
=
ref
(
false
)
const
errorMsg
=
ref
(
''
)
for
(
let
i
=
0
;
i
<
props
.
digit
;
i
++
)
{
cols
.
push
(
''
)
}
const
formatStyle
=
reactive
({
col
:
reactive
(
cols
),
colStyle
:
ref
(
`col-
${
12
/
props
.
digit
}
`
)
})
const
myRef
=
ref
([])
const
setRef
=
el
=>
{
myRef
.
value
.
push
(
el
)
}
const
changFocus
=
(
event
,
index
)
=>
{
if
(
event
.
key
==
'Backspace'
)
{
if
(
index
!=
0
)
{
myRef
.
value
[
index
-
1
].
focus
()
}
}
else
if
(
index
<
props
.
digit
)
{
if
(
formatStyle
.
col
[
index
]
!=
''
)
{
myRef
.
value
[
index
+
1
].
focus
()
}
}
updateValue
()
}
const
updateValue
=
()
=>
{
let
tempValue
=
ref
(
''
)
formatStyle
.
col
.
forEach
(
x
=>
{
tempValue
.
value
+=
x
.
toString
()
})
context
.
emit
(
'update:modelValue'
,
tempValue
.
value
)
}
const
codeFocus
=
e
=>
{
e
.
target
.
select
()
}
const
validate
=
()
=>
{
if
(
props
.
modelValue
.
length
!=
formatStyle
.
col
.
length
)
{
errorMsg
.
value
=
'请输入正确的验证码'
hasError
.
value
=
true
}
else
{
errorMsg
.
value
=
''
hasError
.
value
=
false
}
}
return
{
formatStyle
,
changFocus
,
setRef
,
codeFocus
,
validate
,
hasError
,
errorMsg
}
}
}
</
script
>
<
style
>
/* .override-verfity-ipt .q-field--dense .q-field__control,
.override-verfity-ipt .q-field--dense .q-field__marginal {
} */
.override-verfity-ipt
.el-input__inner
{
text-align
:
center
;
height
:
50px
!important
;
text-align
:
center
;
font-family
:
pingfangr
;
font-weight
:
bold
;
font-size
:
32px
;
}
</
style
>
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