Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
client
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
c1952428
authored
Aug 15, 2025
by
孙美琪
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
手机号登录
parent
e587586e
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
196 additions
and
61 deletions
+196
-61
src/api/login.js
+22
-0
src/store/modules/user.js
+14
-2
src/views/login.vue
+160
-59
No files found.
src/api/login.js
View file @
c1952428
...
...
@@ -45,3 +45,25 @@ export function logout() {
method
:
'post'
})
}
// 发送验证码
export
function
sendCode
(
data
)
{
return
request
({
url
:
'/member/auth/send-sms-code'
,
method
:
'post'
,
data
:
data
})
}
// 验证码提交
export
function
submitCode
(
data
)
{
return
request
({
url
:
'/member/auth/sms-login'
,
headers
:
{
isToken
:
false
,
repeatSubmit
:
false
},
method
:
'post'
,
data
:
data
})
}
src/store/modules/user.js
View file @
c1952428
import
{
login
,
logout
,
getInfo
}
from
'@/api/login'
import
{
login
,
logout
,
getInfo
,
submitCode
}
from
'@/api/login'
import
{
getToken
,
setToken
,
removeToken
}
from
'@/utils/auth'
import
defAva
from
'@/assets/images/profile.jpg'
...
...
@@ -20,7 +20,6 @@ const useUserStore = defineStore(
const
password
=
userInfo
.
password
const
code
=
userInfo
.
code
return
new
Promise
((
resolve
,
reject
)
=>
{
login
(
mobile
,
password
,
code
).
then
(
res
=>
{
setToken
(
res
.
data
.
accessToken
)
...
...
@@ -31,6 +30,19 @@ const useUserStore = defineStore(
})
})
},
cellPhoneLogin
(
userInfo
)
{
const
mobile
=
userInfo
.
mobile
.
trim
()
const
code
=
userInfo
.
code
return
new
Promise
((
resolve
,
reject
)
=>
{
submitCode
({
mobile
:
mobile
,
code
:
code
}).
then
(
res
=>
{
setToken
(
res
.
data
.
accessToken
)
this
.
token
=
res
.
data
.
accessToken
resolve
()
}).
catch
(
error
=>
{
reject
(
error
)
})
})
},
// 获取用户信息
getInfo
()
{
return
new
Promise
((
resolve
,
reject
)
=>
{
...
...
src/views/login.vue
View file @
c1952428
...
...
@@ -2,34 +2,69 @@
<div
class=
"login"
>
<el-form
ref=
"loginRef"
:model=
"loginForm"
:rules=
"loginRules"
class=
"login-form"
>
<h3
class=
"title"
>
面向科创园区的普惠算力公共服务平台
</h3>
<el-form-item
prop=
"mobile"
>
<el-input
v-model=
"loginForm.mobile"
type=
"text"
size=
"large"
auto-complete=
"off"
placeholder=
"账号"
>
<template
#
prefix
>
<svg-icon
icon-class=
"user"
class=
"el-input__icon input-icon"
/>
</
template
>
</el-input>
</el-form-item>
<el-form-item
prop=
"password"
>
<el-input
v-model=
"loginForm.password"
type=
"password"
size=
"large"
auto-complete=
"off"
placeholder=
"密码"
@
keyup
.
enter=
"handleLogin"
>
<
template
#
prefix
>
<svg-icon
icon-class=
"password"
class=
"el-input__icon input-icon"
/>
</
template
>
</el-input>
</el-form-item>
<el-tabs
v-model=
"activeName"
class=
"demo-tabs"
@
tab-click=
"handleClick"
>
<el-tab-pane
label=
"手机号登录"
:name=
"0"
style=
"padding-top: 10px;"
>
<el-form-item
prop=
"phoneNumber"
>
<el-input
v-model=
"loginForm.phoneNumber"
type=
"text"
size=
"large"
auto-complete=
"off"
placeholder=
"手机号"
>
<template
#
prefix
>
<svg-icon
icon-class=
"phone"
class=
"el-input__icon input-icon"
/>
</
template
>
</el-input>
</el-form-item>
<el-form-item
prop=
"code"
>
<el-input
v-model=
"loginForm.code"
type=
"text"
size=
"large"
auto-complete=
"off"
placeholder=
"验证码"
>
<
template
#
prefix
>
<svg-icon
icon-class=
"code"
class=
"el-input__icon input-icon"
/>
</
template
>
<
template
#
append
>
<el-button
@
click=
"startCountdown"
:disabled=
"isCounting"
>
{{
isCounting
?
`重新发送(${countdown
}
)`
:
'发送验证码'
}}
<
/el-button
>
<
/template
>
<
/el-input
>
<
/el-form-item
>
<
/el-tab-pane
>
<
el
-
tab
-
pane
label
=
"账号登录"
:
name
=
"1"
style
=
"padding-top: 10px;"
>
<
el
-
form
-
item
prop
=
"mobile"
>
<
el
-
input
v
-
model
=
"loginForm.mobile"
type
=
"text"
size
=
"large"
auto
-
complete
=
"off"
placeholder
=
"账号"
>
<
template
#
prefix
>
<
svg
-
icon
icon
-
class
=
"user"
class
=
"el-input__icon input-icon"
/>
<
/template
>
<
/el-input
>
<
/el-form-item
>
<
el
-
form
-
item
prop
=
"password"
>
<
el
-
input
v
-
model
=
"loginForm.password"
type
=
"password"
size
=
"large"
auto
-
complete
=
"off"
placeholder
=
"密码"
@
keyup
.
enter
=
"handleLogin"
>
<
template
#
prefix
>
<
svg
-
icon
icon
-
class
=
"password"
class
=
"el-input__icon input-icon"
/>
<
/template
>
<
/el-input
>
<
/el-form-item
>
<
/el-tab-pane
>
<
/el-tabs
>
<div
class=
"flex-align-center flex-space-between mb20"
>
<el-checkbox
v-model=
"loginForm.rememberMe"
>
记住密码
</el-checkbox>
<
div
class
=
"flex-align-center flex-space-between mb20"
style
=
"height: 32px;"
>
<
el
-
checkbox
v
-
show
=
"activeName === 1"
v
-
model
=
"loginForm.rememberMe"
>
记住密码
<
/el-checkbox
>
<
div
v
-
if
=
"register"
>
<
router
-
link
class
=
"link-type"
:
to
=
"'/register'"
>
立即注册
<
/router-link
>
<
/div
>
...
...
@@ -41,7 +76,7 @@
size
=
"large"
type
=
"primary"
style
=
"width:100%;"
@
click
.
prevent=
"handleLogin"
>
@
click
.
prevent
=
"handleLogin
(activeName)
"
>
<
span
v
-
if
=
"!loading"
>
登
录
<
/span
>
<
span
v
-
else
>
登
录
中
...
<
/span
>
<
/el-button
>
...
...
@@ -57,9 +92,11 @@
<
script
setup
>
import
Cookies
from
'js-cookie'
import
{
encrypt
,
decrypt
}
from
'@/utils/jsencrypt'
import
{
encrypt
,
decrypt
}
from
'@/utils/jsencrypt'
import
useUserStore
from
'@/store/modules/user'
import
{
useRoute
,
useRouter
}
from
'vue-router'
import
{
useRoute
,
useRouter
}
from
'vue-router'
import
{
sendCode
}
from
"@/api/login.js"
;
import
{
ElMessage
}
from
"element-plus"
;
const
userStore
=
useUserStore
()
const
route
=
useRoute
()
...
...
@@ -71,61 +108,125 @@ const loginForm = ref({
password
:
''
,
rememberMe
:
false
,
code
:
''
,
uuid
:
''
uuid
:
''
,
phoneNumber
:
''
}
)
const
loginRules
=
{
mobile
:
[{
required
:
true
,
trigger
:
'blur'
,
message
:
'请输入您的手机号'
}
],
password
:
[{
required
:
true
,
trigger
:
'blur'
,
message
:
'请输入您的密码'
}
],
code
:
[{
required
:
true
,
trigger
:
'change'
,
message
:
'请输入验证码'
}]
code
:
[{
required
:
true
,
trigger
:
'change'
,
message
:
'请输入验证码'
}
],
phoneNumber
:
[
{
required
:
true
,
trigger
:
'blur'
,
message
:
'请输入手机号码'
}
,
{
validator
:
validatePhone
}
,
]
}
const
codeUrl
=
ref
(
''
)
const
loginRef
=
ref
(
null
)
const
activeName
=
ref
(
0
)
const
loading
=
ref
(
false
)
// 验证码开关
const
captchaEnabled
=
ref
(
tru
e
)
const
captchaEnabled
=
ref
(
fals
e
)
// 注册开关
const
register
=
ref
(
tru
e
)
const
register
=
ref
(
fals
e
)
const
redirect
=
ref
(
undefined
)
const
countdown
=
ref
(
60
);
// 倒计时时间,初始为60秒
const
isCounting
=
ref
(
false
);
// 是否正在倒计时的标志
// 开始倒计时的方法
const
startCountdown
=
()
=>
{
getCode
()
loginRef
.
value
.
validateField
(
'phoneNumber'
,
valid
=>
{
if
(
valid
)
{
if
(
isCounting
.
value
)
return
;
// 如果已经在倒计时,则不重复开始
isCounting
.
value
=
true
;
// 设置正在倒计时的标志为true
const
timer
=
setInterval
(()
=>
{
if
(
countdown
.
value
>
0
)
{
countdown
.
value
--
;
// 倒计时减1
}
else
{
clearInterval
(
timer
);
// 倒计时结束,清除定时器
isCounting
.
value
=
false
;
// 设置正在倒计时的标志为false
countdown
.
value
=
60
;
// 重置倒计时时间
}
}
,
1000
);
// 每1000毫秒(1秒)执行一次
}
}
)
}
;
function
getCode
()
{
sendCode
({
mobile
:
loginForm
.
value
.
mobile
,
scene
:
1
}
).
then
(
res
=>
{
if
(
res
.
data
===
true
)
{
ElMessage
({
message
:
'短信已发送请注意查收'
,
type
:
'success'
}
)
}
}
)
}
function
validatePhone
(
rule
,
value
,
callback
)
{
const
reg
=
/^1
[
3456789
]\d
{9
}
$/
if
(
!
reg
.
test
(
value
))
{
callback
(
new
Error
(
'请输入正确的手机号'
))
return
}
callback
()
}
watch
(
route
,
(
newRoute
)
=>
{
redirect
.
value
=
newRoute
.
query
&&
newRoute
.
query
.
redirect
}
,
{
immediate
:
true
}
)
function
handleLogin
()
{
function
handleClick
()
{
proxy
.
$refs
.
loginRef
.
resetFields
()
}
function
handleLogin
(
num
)
{
proxy
.
$refs
.
loginRef
.
validate
(
valid
=>
{
if
(
valid
)
{
loading
.
value
=
true
// 勾选了需要记住密码设置在 cookie 中设置记住用户名和密码
if
(
loginForm
.
value
.
rememberMe
)
{
Cookies
.
set
(
'mobile'
,
loginForm
.
value
.
mobile
,
{
expires
:
30
})
Cookies
.
set
(
'password'
,
encrypt
(
loginForm
.
value
.
password
),
{
expires
:
30
})
Cookies
.
set
(
'rememberMe'
,
loginForm
.
value
.
rememberMe
,
{
expires
:
30
})
if
(
num
===
1
)
{
// 勾选了需要记住密码设置在 cookie 中设置记住用户名和密码
if
(
loginForm
.
value
.
rememberMe
)
{
Cookies
.
set
(
'mobile'
,
loginForm
.
value
.
mobile
,
{
expires
:
30
}
)
Cookies
.
set
(
'password'
,
encrypt
(
loginForm
.
value
.
password
),
{
expires
:
30
}
)
Cookies
.
set
(
'rememberMe'
,
loginForm
.
value
.
rememberMe
,
{
expires
:
30
}
)
}
else
{
// 否则移除
Cookies
.
remove
(
'mobile'
)
Cookies
.
remove
(
'password'
)
Cookies
.
remove
(
'rememberMe'
)
}
// 调用action的登录方法
userStore
.
login
(
loginForm
.
value
).
then
(()
=>
{
const
query
=
route
.
query
const
otherQueryParams
=
Object
.
keys
(
query
).
reduce
((
acc
,
cur
)
=>
{
if
(
cur
!==
'redirect'
)
{
acc
[
cur
]
=
query
[
cur
]
}
return
acc
}
,
{
}
)
router
.
push
({
path
:
redirect
.
value
||
'/'
,
query
:
otherQueryParams
}
)
}
).
catch
(()
=>
{
loading
.
value
=
false
}
)
}
else
{
// 否则移除
Cookies
.
remove
(
'mobile'
)
Cookies
.
remove
(
'password'
)
Cookies
.
remove
(
'rememberMe'
)
userStore
.
cellPhoneLogin
({
mobile
:
loginForm
.
value
.
phoneNumber
,
code
:
loginForm
.
value
.
code
}
).
then
(
res
=>
{
const
query
=
route
.
query
const
otherQueryParams
=
Object
.
keys
(
query
).
reduce
((
acc
,
cur
)
=>
{
if
(
cur
!==
'redirect'
)
{
acc
[
cur
]
=
query
[
cur
]
}
return
acc
}
,
{
}
)
router
.
push
({
path
:
redirect
.
value
||
'/'
,
query
:
otherQueryParams
}
)
}
).
catch
(()
=>
{
loading
.
value
=
false
}
)
}
// 调用action的登录方法
userStore
.
login
(
loginForm
.
value
).
then
(()
=>
{
const
query
=
route
.
query
const
otherQueryParams
=
Object
.
keys
(
query
).
reduce
((
acc
,
cur
)
=>
{
if
(
cur
!==
'redirect'
)
{
acc
[
cur
]
=
query
[
cur
]
}
return
acc
},
{})
router
.
push
({
path
:
redirect
.
value
||
'/'
,
query
:
otherQueryParams
})
}).
catch
(()
=>
{
loading
.
value
=
false
})
}
}
)
}
function
getCookie
()
{
function
getCookie
()
{
const
mobile
=
Cookies
.
get
(
'mobile'
)
const
password
=
Cookies
.
get
(
'password'
)
const
rememberMe
=
Cookies
.
get
(
'rememberMe'
)
...
...
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