Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
B
bigwood
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
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
罗超
bigwood
Commits
5c5d1c41
Commit
5c5d1c41
authored
Nov 02, 2022
by
罗超
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
完善找回密碼等功能
parent
6c0074f5
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
241 additions
and
3 deletions
+241
-3
user.ts
src/api/user.ts
+4
-0
permission.ts
src/boot/permission.ts
+5
-2
index.ts
src/i18n/zh-TW/index.ts
+17
-1
loginModule.ts
src/module/user/loginModule.ts
+2
-0
forget.vue
src/pages/auth/forget.vue
+1
-0
newpassword.vue
src/pages/auth/newpassword.vue
+208
-0
routes.ts
src/router/routes.ts
+4
-0
No files found.
src/api/user.ts
View file @
5c5d1c41
...
...
@@ -180,6 +180,10 @@ class UserService {
static
sendVerify
(
data
:
any
):
Promise
<
HttpResponse
>
{
return
request
(
"b2b_post_send_verify"
,
data
);
}
static
resetPassword
(
certificate
:
string
,
password
:
string
):
Promise
<
HttpResponse
>
{
return
request
(
"b2b_post_reset_password"
,{
certificate
,
password
});
}
}
export
default
UserService
src/boot/permission.ts
View file @
5c5d1c41
...
...
@@ -4,6 +4,7 @@ import router from '../router/index'
import
{
getAuth
,
getUserAllMenu
}
from
'../utils/auth'
import
{
LoadingBar
}
from
'quasar'
import
{
url
}
from
'inspector'
LoadingBar
.
setDefaults
({
color
:
'primary'
,
size
:
'3px'
,
...
...
@@ -12,7 +13,7 @@ LoadingBar.setDefaults({
let
loadAsyncRouter
=
false
const
whiteList
=
[
'/auth/login'
,
'/auth/regist'
,
'/auth/forget'
]
const
whiteList
=
[
'/auth/login'
,
'/auth/regist'
,
'/auth/forget'
,
'/auth/newpassword'
]
router
.
beforeEach
((
to
,
from
,
next
)
=>
{
localStorage
.
setItem
(
'routerBefore'
,
from
.
path
)
...
...
@@ -71,7 +72,9 @@ router.beforeEach((to, from, next) => {
}
}
}
else
{
if
(
whiteList
.
indexOf
(
to
.
path
)
!==
-
1
)
{
let
urlPath
=
to
.
matched
[
0
].
path
if
(
urlPath
.
indexOf
(
'/:'
)
!=-
1
)
urlPath
=
urlPath
.
substring
(
0
,
urlPath
.
indexOf
(
'/:'
))
if
(
whiteList
.
indexOf
(
urlPath
)
!==
-
1
)
{
console
.
log
(
whiteList
,
to
.
path
)
next
()
}
else
{
...
...
src/i18n/zh-TW/index.ts
View file @
5c5d1c41
...
...
@@ -27,12 +27,28 @@ export default {
title
:
"忘記密碼"
,
subtitle
:
"輸入您的郵箱,以重置密碼"
,
notaccess
:
"已經是會員了?"
,
registlink
:
"登
錄
"
,
registlink
:
"登
入
"
,
account
:
"帳戶(EMail)"
,
submit
:
"提交"
,
cancel
:
"取消"
,
goback
:
"返回"
,
mailResult
:
"郵件已發送到您的郵箱,請根據郵件提示修改密碼"
,
resultBtn
:
"我已知曉"
},
newpwd
:{
pageTitle
:
"設置新密碼"
,
title
:
"設置新密碼"
,
subtitle
:
"為了您的帳戶安全,建議您定期修改密碼"
,
notaccess
:
"你已經重置密碼了嗎?"
,
registlink
:
"登入"
,
pass
:
"新密碼"
,
passTips
:
"使用8個或8個以上的字母、數字和符號的組合"
,
passvalidate
:
"請按照提示要求設置密碼"
,
repeatPassvalidate
:
"兩次輸入密碼不一致"
,
repeatPass
:
"再次輸入密碼"
,
notEmptyPass
:
'新密碼最少為8位'
,
maxLengthPass
:
'密碼長度應為8-16位'
,
updateResult
:
'新密碼已經設置成功,可以立即登入'
,
resultBtn
:
"立即登入"
}
}
src/module/user/loginModule.ts
View file @
5c5d1c41
...
...
@@ -49,6 +49,8 @@ const userUserLoginModule = () => {
if
(
!
r
[
0
]){
message
.
errorMsg
(
r
[
1
])
stateManager
.
subLogin
=
false
}
else
{
location
.
href
=
'/index'
}
}
}
...
...
src/pages/auth/forget.vue
View file @
5c5d1c41
...
...
@@ -104,6 +104,7 @@ export default defineComponent({
let
methods
=
{
sendVerifyCode
(){
if
(
data
.
loading
)
return
const
accountRefVal
=
accountRef
as
any
console
.
log
(
accountRef
.
value
)
...
...
src/pages/auth/newpassword.vue
0 → 100644
View file @
5c5d1c41
<
template
>
<div
class=
"row full-height"
>
<div
class=
"col q-pa-xl fit row justify-center height"
>
<div
style=
"width: 450px"
class=
"column justify-between content-between"
>
<div
class=
"row items-center"
>
<div
class=
"col"
>
<q-btn
round
flat
size=
"md"
@
click=
"goback"
>
<svg-icon
icon=
"Navigation/Arrow-left.svg"
:size=
"24"
tips=
"$t('newpwd.goback')"
></svg-icon>
</q-btn>
</div>
<div
class=
"text-grey-6 text-weight-bold text-right"
>
<span>
{{
$t
(
'newpwd.notaccess'
)
}}
</span>
<router-link
:to=
"
{ path: '/auth/login' }" class="text-primary pfb text-subtitle">
{{
$t
(
'newpwd.registlink'
)
}}
</router-link>
</div>
</div>
<div
class=
"q-py-xxl full-width"
>
<div
class=
"text-h3 text-weight-bold"
>
{{
$t
(
'newpwd.title'
)
}}
</div>
<div
class=
"text-grey-6 q-mt-sm q-mb-lg"
>
{{
$t
(
'newpwd.subtitle'
)
}}
</div>
<div
class=
"form-box q-my-lg"
>
<div
class=
"q-mb-xl"
>
<q-input
:label=
"$t('newpwd.pass')"
:hint=
"$t('newpwd.passTips')"
type=
"password"
standout
v-model=
"password"
dense
ref=
"passwordRef"
:rules=
"passRules"
/>
<div
class=
"row q-mt-sm"
>
<div
class=
"col rounded-borders"
style=
"height:8px"
:class=
"
{'bg-positive':level.indexOf('low')!=-1,'bg-grey-3':level.indexOf('low')==-1}">
</div>
<div
class=
"col q-mx-md rounded-borders"
style=
"height:8px"
:class=
"
{'bg-positive':level.indexOf('middle')!=-1,'bg-grey-3':level.indexOf('middle')==-1}">
</div>
<div
class=
"col rounded-borders"
style=
"height:8px"
:class=
"
{'bg-positive':level.indexOf('high')!=-1,'bg-grey-3':level.indexOf('high')==-1}">
</div>
</div>
</div>
<div
class=
"q-mb-lg"
>
<q-input
:label=
"$t('newpwd.repeatPass')"
type=
"password"
standout
v-model=
"repeatPassWord"
dense
ref=
"repeatPassWordRef"
:rules=
"[(val: any) => val == password || $t('newpwd.repeatPassvalidate')]"
/>
</div>
</div>
<div
class=
"row items-center"
:class=
"
{ row: $q.platform.is.desktop, column: $q.platform.is.mobile }">
<div
class=
"col"
>
<q-btn
size=
"md"
class=
"q-px-lg"
color=
"primary"
:loading=
"loading"
@
click=
"resetPassword"
unelevated
:label=
"$t('forget.submit')"
/>
</div>
</div>
</div>
<div>
<q-select
borderless
v-model=
"currentLang"
:options=
"langs"
map-options
option-value=
"langLocale"
option-label=
"langName"
style=
"width: 180px"
>
<template
v-slot:selected
>
{{
$t
(
'lanuage'
)
}}
:
<q-chip
dense
square
color=
"white"
text-color=
"primary"
class=
"q-my-none q-ml-xs q-mr-none"
>
{{
currentLang
.
langName
}}
</q-chip>
</
template
>
</q-select>
</div>
</div>
</div>
<div
class=
"col right-bg full-height mobile-hide"
></div>
</div>
<q-dialog
no-esc-dismiss
persistent
v-model=
"successModel"
>
<q-card
:class=
"{'q-pa-xl':$q.platform.is.desktop,'q-pa-lg':$q.platform.is.mobile}"
>
<q-card-section>
<div
class=
"text-center q-mb-md"
>
<svg-icon
icon=
"Code/Done-circle.svg"
color=
"success"
:size=
"80"
></svg-icon>
</div>
<div>
{{$t('newpwd.updateResult')}}
</div>
<div
class=
"text-center q-mt-xl"
>
<q-btn
color=
"primary"
@
click=
"goback"
unelevated
:label=
"$t('newpwd.resultBtn')"
/>
</div>
</q-card-section>
</q-card>
</q-dialog>
</template>
<
script
lang=
"ts"
>
import
{
defineComponent
,
reactive
,
ref
,
toRefs
}
from
'vue'
import
useMetaModule
from
'../../module/meta/metaModule'
import
{
useI18n
}
from
'vue-i18n'
import
{
getLangs
}
from
'../../utils/tools'
import
{
SitLang
}
from
'../../@types'
import
svgIcon
from
'../../components/global/svg-icon.vue'
import
UserService
from
'../../api/user'
import
message
from
'../../utils/message'
import
{
ApiResult
}
from
'../../@types/enumHelper'
import
router
from
'../../router'
;
export
default
defineComponent
({
components
:
{
svgIcon
},
setup
()
{
let
{
setTitle
}
=
useMetaModule
()
const
{
locale
,
t
}
=
useI18n
()
setTitle
(
t
(
'newpwd.pageTitle'
))
const
data
=
reactive
({
currentLang
:
{}
as
SitLang
,
langs
:
[]
as
SitLang
[],
password
:
''
,
loading
:
false
,
successModel
:
false
,
passwordRef
:
null
,
repeatPassWord
:
''
,
repeatPassWordRef
:
null
,
level
:
[]
as
string
[],
accountCertificate
:
''
as
(
string
|
undefined
),
passRules
:
[(
val
:
string
|
undefined
)
=>
(
val
&&
val
.
length
>=
8
)
||
t
(
'newpwd.notEmptyPass'
),
(
val
:
string
|
undefined
)
=>
(
val
&&
val
.
length
<=
16
)
||
t
(
'newpwd.maxLengthPass'
),(
val
:
string
)
=>
methods
.
checkPassword
(
val
)
||
''
]
})
data
.
accountCertificate
=
router
.
currentRoute
.
value
.
params
.
code
?.
toString
()
if
(
!
data
.
accountCertificate
){
//window.history.go(-1)
}
console
.
log
(
data
.
accountCertificate
)
data
.
langs
=
getLangs
()
if
(
data
.
langs
&&
data
.
langs
.
length
>
0
)
{
data
.
currentLang
=
data
.
langs
.
find
(
x
=>
x
.
langLocale
==
locale
.
value
)
??
{}
}
let
methods
=
{
resetPassword
()
{
if
(
data
.
loading
)
return
const
passRefVal
=
data
.
passwordRef
as
any
const
repassRefVal
=
data
.
repeatPassWordRef
as
any
passRefVal
.
validate
()
repassRefVal
.
validate
()
if
(
!
passRefVal
.
hasError
&&!
repassRefVal
.
hasError
)
{
data
.
loading
=
true
//hasError
UserService
.
resetPassword
(
data
.
accountCertificate
as
string
,
data
.
password
)
.
then
(
r
=>
{
data
.
loading
=
false
if
(
r
.
data
.
resultCode
==
ApiResult
.
SUCCESS
)
{
data
.
successModel
=
true
}
else
{
message
.
errorMsg
(
r
.
data
.
message
)
}
})
.
catch
(
e
=>
{
data
.
loading
=
false
message
.
errorMsg
(
e
.
message
)
})
}
},
goback
()
{
window
.
location
.
href
=
'/auth/login'
},
checkPassword
(
value
:
string
):
boolean
{
data
.
level
=
[]
if
(
value
&&
value
.
length
>=
8
&&
value
.
length
<=
16
)
{
// 校验是数字
const
regex1
=
/^
\d
+$/
// 校验字母
const
regex2
=
/^
[
A-Za-z
]
+$/
// 校验符号
const
regex3
=
/^
[
`~!@#$%^&*()_
\-
+=<>?:"{}|,.
\/
;'
\\
[
\]
·~!@#¥%……&*()——
\-
+={}|《》?:“”【】、;‘',。、
]
+$/
if
(
regex1
.
test
(
value
))
{
data
.
level
.
push
(
'low'
)
}
else
if
(
regex2
.
test
(
value
))
{
data
.
level
.
push
(
'low'
)
}
else
if
(
regex3
.
test
(
value
))
{
data
.
level
.
push
(
'low'
)
}
else
if
(
/^
[
A-Za-z
\d]
+$/
.
test
(
value
))
{
data
.
level
.
push
(
'low'
)
data
.
level
.
push
(
'middle'
)
}
else
if
(
/^
[
`~!@#$%^&*()_
\-
+=<>?:"{}|,.
\/
;'
\\
[
\]
·~!@#¥%……&*()——
\-
+={}|《》?:“”【】、;‘',。、
\d]
+$/
.
test
(
value
))
{
data
.
level
.
push
(
'low'
)
data
.
level
.
push
(
'middle'
)
}
else
if
(
/^
[
`~!@#$%^&*()_
\-
+=<>?:"{}|,.
\/
;'
\\
[
\]
·~!@#¥%……&*()——
\-
+={}|《》?:“”【】、;‘',。、A-Za-z
]
+$/
.
test
(
value
))
{
data
.
level
.
push
(
'low'
)
data
.
level
.
push
(
'middle'
)
}
else
if
(
/^
[
`~!@#$%^&*()_
\-
+=<>?:"{}|,.
\/
;'
\\
[
\]
·~!@#¥%……&*()——
\-
+={}|《》?:“”【】、;‘',。、A-Za-z
\d]
+$/
.
test
(
value
))
{
data
.
level
.
push
(
'low'
)
data
.
level
.
push
(
'middle'
)
data
.
level
.
push
(
'high'
)
}
return
true
}
return
false
}
}
return
{
...
toRefs
(
data
),
...
methods
}
}
})
</
script
>
<
style
>
.login-bg
{
background-image
:
url(../../assets/images/8.png)
;
background-position-x
:
center
;
background-position-y
:
bottom
;
background-repeat
:
no-repeat
;
background-size
:
contain
;
}
.w-450
{
width
:
450px
;
box-shadow
:
0
0.5rem
1.5rem
0.5rem
rgba
(
0
,
0
,
0
,
0.075
)
!important
;
border-radius
:
0.475rem
!important
;
}
.w-450-only
{
width
:
450px
;
}
.right-bg
{
background-image
:
url(../../assets/images/login-right-bg.png)
;
background-position-x
:
left
;
background-position-y
:
center
;
background-repeat
:
no-repeat
;
background-size
:
cover
;
}
.top-bg
{
background-image
:
url(https://preview.keenthemes.com/metronic8/demo1/assets/media/auth/bg11.png)
;
background-position-x
:
-100px
;
background-position-y
:
-85vh
;
background-repeat
:
no-repeat
;
background-size
:
cover
;
}
</
style
>
src/router/routes.ts
View file @
5c5d1c41
...
...
@@ -18,6 +18,10 @@ const routes: RouteRecordRaw[] = [
path
:
'/auth/forget'
,
component
:
()
=>
import
(
'../pages/auth/forget.vue'
)
},
{
path
:
'/auth/newpassword/:code'
,
component
:
()
=>
import
(
'../pages/auth/newpassword.vue'
)
},
// Always leave this as last one,
// but you can also remove it
{
...
...
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