Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
admin
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
2205526a
authored
Sep 06, 2024
by
scholar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
优化代码实现。
parent
f01dc0a5
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
252 additions
and
119 deletions
+252
-119
src/api/login/index.ts
+7
-1
src/api/login/types.ts
+7
-0
src/views/Login/components/RegisterForm.vue
+238
-118
No files found.
src/api/login/index.ts
View file @
2205526a
import
request
from
'@/config/axios'
import
{
getRefreshToken
}
from
'@/utils/auth'
import
type
{
UserLoginVO
}
from
'./types'
import
type
{
RegisterVO
,
UserLoginVO
}
from
'./types'
export
interface
SmsCodeVO
{
mobile
:
string
...
...
@@ -17,6 +17,12 @@ export const login = (data: UserLoginVO) => {
return
request
.
post
({
url
:
'/system/auth/login'
,
data
})
}
// 注册
export
const
register
=
(
data
:
RegisterVO
)
=>
{
console
.
log
(
"data: RegisterVO========="
,
data
)
return
request
.
post
({
url
:
'/system/auth/register'
,
data
})
}
// 刷新访问令牌
export
const
refreshToken
=
()
=>
{
return
request
.
post
({
url
:
'/system/auth/refresh-token?refreshToken='
+
getRefreshToken
()
})
...
...
src/api/login/types.ts
View file @
2205526a
...
...
@@ -29,3 +29,10 @@ export type UserVO = {
loginIp
:
string
loginDate
:
string
}
export
type
RegisterVO
=
{
tenantName
:
string
username
:
string
password
:
string
captchaVerification
:
string
}
src/views/Login/components/RegisterForm.vue
View file @
2205526a
<
template
>
<
F
orm
<
el-f
orm
v-show=
"getShow"
:rules=
"rules
"
:
schema=
"schema
"
class=
"dark:(border-1 border-[var(--el-border-color)] border-solid)
"
hide-required-asterisk
ref=
"formLogin
"
:
model=
"registerData.registerForm
"
:rules=
"registerRules
"
class=
"login-form"
label-position=
"top"
label-width=
"120px"
size=
"large"
@
register=
"register"
>
<template
#
title
>
<LoginFormTitle
style=
"width: 100%"
/>
</
template
>
<
template
#
code=
"form"
>
<div
class=
"w-[100%] flex"
>
<el-input
v-model=
"form['code']"
:placeholder=
"t('login.codePlaceholder')"
/>
</div>
</
template
>
<
template
#
register
>
<div
class=
"w-[100%]"
>
<XButton
:loading=
"loading"
:title=
"t('login.register')"
class=
"w-[100%]"
type=
"primary"
@
click=
"loginRegister()"
/>
</div>
<div
class=
"mt-15px w-[100%]"
>
<XButton
:title=
"t('login.hasUser')"
class=
"w-[100%]"
@
click=
"handleBackLogin()"
/>
</div>
</
template
>
</Form>
<el-row
style=
"margin-right: -10px; margin-left: -10px"
>
<el-col
:span=
"24"
style=
"padding-right: 10px; padding-left: 10px"
>
<el-form-item>
<LoginFormTitle
style=
"width: 100%"
/>
</el-form-item>
</el-col>
<el-col
:span=
"24"
style=
"padding-right: 10px; padding-left: 10px"
>
<el-form-item
v-if=
"registerData.tenantEnable === 'true'"
prop=
"tenantName"
>
<el-input
v-model=
"registerData.registerForm.tenantName"
:placeholder=
"t('login.tenantname')"
:prefix-icon=
"iconHouse"
link
type=
"primary"
size=
"large"
/>
</el-form-item>
</el-col>
<el-col
:span=
"24"
style=
"padding-right: 10px; padding-left: 10px"
>
<el-form-item
prop=
"username"
>
<el-input
v-model=
"registerData.registerForm.username"
:placeholder=
"t('login.username')"
size=
"large"
:prefix-icon=
"iconAvatar"
/>
</el-form-item>
</el-col>
<el-col
:span=
"24"
style=
"padding-right: 10px; padding-left: 10px"
>
<el-form-item
prop=
"password"
>
<el-input
v-model=
"registerData.registerForm.password"
type=
"password"
auto-complete=
"off"
:placeholder=
"t('login.password')"
size=
"large"
:prefix-icon=
"iconLock"
show-password
/>
</el-form-item>
</el-col>
<el-col
:span=
"24"
style=
"padding-right: 10px; padding-left: 10px"
>
<el-form-item
prop=
"confirmPassword"
>
<el-input
v-model=
"registerData.registerForm.confirmPassword"
type=
"password"
size=
"large"
auto-complete=
"off"
:placeholder=
"t('login.checkPassword')"
:prefix-icon=
"iconLock"
show-password
/>
</el-form-item>
</el-col>
<el-col
:span=
"24"
style=
"padding-right: 10px; padding-left: 10px"
>
<el-form-item>
<XButton
:loading=
"loginLoading"
:title=
"t('login.register')"
class=
"w-[100%]"
type=
"primary"
@
click=
"getCode()"
/>
</el-form-item>
</el-col>
<Verify
ref=
"verify"
:captchaType=
"captchaType"
:imgSize=
"
{ width: '400px', height: '200px' }"
mode="pop"
@success="handleRegister"
/>
</el-row>
<XButton
:title=
"t('login.hasUser')"
class=
"w-[100%]"
@
click=
"handleBackLogin()"
/>
</el-form>
</
template
>
<
script
lang=
"ts"
setup
>
import
type
{
FormRules
}
from
'element-plus'
import
{
useForm
}
from
'@/hooks/web/useForm'
import
{
useValidator
}
from
'@/hooks/web/useValidator'
import
{
ElLoading
,
ElMessageBox
}
from
'element-plus'
import
LoginFormTitle
from
'./LoginFormTitle.vue'
import
type
{
RouteLocationNormalizedLoaded
}
from
'vue-router'
import
{
useIcon
}
from
'@/hooks/web/useIcon'
import
*
as
authUtil
from
'@/utils/auth'
import
{
usePermissionStore
}
from
'@/store/modules/permission'
import
*
as
LoginApi
from
'@/api/login'
import
{
LoginStateEnum
,
useLoginState
}
from
'./useLogin'
import
{
FormSchema
}
from
'@/types/form'
defineOptions
({
name
:
'
Register
Form'
})
defineOptions
({
name
:
'
Login
Form'
})
const
{
t
}
=
useI18n
()
const
{
required
}
=
useValidator
()
const
{
register
,
elFormRef
}
=
useForm
()
const
iconHouse
=
useIcon
({
icon
:
'ep:house'
})
const
iconAvatar
=
useIcon
({
icon
:
'ep:avatar'
})
const
iconLock
=
useIcon
({
icon
:
'ep:lock'
})
const
formLogin
=
ref
()
const
{
handleBackLogin
,
getLoginState
}
=
useLoginState
()
const
{
currentRoute
,
push
}
=
useRouter
()
const
permissionStore
=
usePermissionStore
()
const
redirect
=
ref
<
string
>
(
''
)
const
loginLoading
=
ref
(
false
)
const
verify
=
ref
()
const
captchaType
=
ref
(
'blockPuzzle'
)
// blockPuzzle 滑块 clickWord 点击文字
const
getShow
=
computed
(()
=>
unref
(
getLoginState
)
===
LoginStateEnum
.
REGISTER
)
const
schema
=
reactive
<
FormSchema
[]
>
([
{
field
:
'title'
,
colProps
:
{
span
:
24
}
},
{
field
:
'username'
,
label
:
t
(
'login.username'
),
value
:
''
,
component
:
'Input'
,
colProps
:
{
span
:
24
},
componentProps
:
{
placeholder
:
t
(
'login.usernamePlaceholder'
)
}
},
{
field
:
'password'
,
label
:
t
(
'login.password'
),
value
:
''
,
component
:
'InputPassword'
,
colProps
:
{
span
:
24
},
componentProps
:
{
style
:
{
width
:
'100%'
},
strength
:
true
,
placeholder
:
t
(
'login.passwordPlaceholder'
)
}
},
{
field
:
'check_password'
,
label
:
t
(
'login.checkPassword'
),
value
:
''
,
component
:
'InputPassword'
,
colProps
:
{
span
:
24
},
componentProps
:
{
style
:
{
width
:
'100%'
},
strength
:
true
,
placeholder
:
t
(
'login.passwordPlaceholder'
)
}
},
{
field
:
'code'
,
label
:
t
(
'login.code'
),
colProps
:
{
span
:
24
}
},
{
field
:
'register'
,
colProps
:
{
span
:
24
}
const
equalToPassword
=
(
rule
,
value
,
callback
)
=>
{
if
(
registerData
.
registerForm
.
password
!==
value
)
{
callback
(
new
Error
(
"两次输入的密码不一致"
));
}
else
{
callback
();
}
])
};
const
rules
:
FormRules
=
{
username
:
[
required
()],
password
:
[
required
()],
check_password
:
[
required
()],
code
:
[
required
()]
const
registerRules
=
{
tenantName
:
[
{
required
:
true
,
trigger
:
"blur"
,
message
:
"请输入您所属的租户"
},
{
min
:
2
,
max
:
20
,
message
:
"租户账号长度必须介于 2 和 20 之间"
,
trigger
:
"blur"
}
],
username
:
[
{
required
:
true
,
trigger
:
"blur"
,
message
:
"请输入您的账号"
},
{
min
:
2
,
max
:
20
,
message
:
"用户账号长度必须介于 2 和 20 之间"
,
trigger
:
"blur"
}
],
password
:
[
{
required
:
true
,
trigger
:
"blur"
,
message
:
"请输入您的密码"
},
{
min
:
5
,
max
:
20
,
message
:
"用户密码长度必须介于 5 和 20 之间"
,
trigger
:
"blur"
},
{
pattern
:
/^
[^
<>"'|
\\]
+$/
,
message
:
"不能包含非法字符:
<
>
\
" ' \\\ |"
,
trigger
:
"blur"
}
],
confirmPassword
:
[
{
required
:
true
,
trigger
:
"blur"
,
message
:
"请再次输入您的密码"
},
{
required
:
true
,
validator
:
equalToPassword
,
trigger
:
"blur"
}
]
}
const
loading
=
ref
(
false
)
const
registerData
=
reactive
({
isShowPassword
:
false
,
captchaEnable
:
import
.
meta
.
env
.
VITE_APP_CAPTCHA_ENABLE
,
tenantEnable
:
import
.
meta
.
env
.
VITE_APP_TENANT_ENABLE
,
registerForm
:
{
tenantName
:
''
,
nickname
:
"芋艿"
,
tenantId
:
0
,
username
:
''
,
password
:
''
,
confirmPassword
:
""
,
captchaVerification
:
''
}
})
async
function
handleRegister
()
{
loading
.
value
=
true
await
getTenantId
()
registerData
.
registerForm
.
tenantId
=
authUtil
.
getTenantId
()
const
loginRegister
=
async
()
=>
{
const
formRef
=
unref
(
elFormRef
)
formRef
?.
validate
(
async
(
valid
)
=>
{
if
(
valid
)
{
try
{
loading
.
value
=
true
}
finally
{
loading
.
value
=
false
LoginApi
.
register
(
registerData
.
registerForm
).
then
(()
=>
{
const
username
=
registerData
.
registerForm
.
username
;
ElMessageBox
.
alert
(
"
<
font
color
=
'green'
>
恭喜你,您的账号
" + username + "
注册成功!
<
/font>", "系统提示",
{
dangerouslyUseHTMLString
:
true
,
type
:
"success"
,
}).
then
(
async
()
=>
{
const
res
=
await
LoginApi
.
login
(
registerData
.
registerForm
)
if
(
!
res
)
{
return
}
loading
.
value
=
ElLoading
.
service
({
lock
:
true
,
text
:
'正在加载系统中...'
,
background
:
'rgba(0, 0, 0, 0.7)'
})
authUtil
.
removeLoginForm
()
authUtil
.
setToken
(
res
)
if
(
!
redirect
.
value
)
{
redirect
.
value
=
'/'
}
// 判断是否为SSO登录
if
(
redirect
.
value
.
indexOf
(
'sso'
)
!==
-
1
)
{
window
.
location
.
href
=
window
.
location
.
href
.
replace
(
'/login?redirect='
,
''
)
}
else
{
push
({
path
:
redirect
.
value
||
permissionStore
.
addRouters
[
0
].
path
})
}
}
loginLoading
.
value
=
false
loading
.
value
.
close
()
})
})
}
// 获取验证码
const
getCode
=
async
()
=>
{
// 情况一,未开启:则直接登录
if
(
registerData
.
captchaEnable
===
'false'
)
{
await
handleRegister
()
}
else
{
// 情况二,已开启:则展示验证码;只有完成验证码的情况,才进行登录
// 弹出验证码
verify
.
value
.
show
()
}
}
// 获取租户 ID
const
getTenantId
=
async
()
=>
{
if
(
registerData
.
tenantEnable
===
'true'
)
{
const
res
=
await
LoginApi
.
getTenantIdByName
(
registerData
.
registerForm
.
tenantName
)
authUtil
.
setTenantId
(
res
)
}
}
// 根据域名,获得租户信息
const
getTenantByWebsite
=
async
()
=>
{
const
website
=
location
.
host
const
res
=
await
LoginApi
.
getTenantByWebsite
(
website
)
if
(
res
)
{
registerData
.
registerForm
.
tenantName
=
res
.
name
authUtil
.
setTenantId
(
res
.
id
)
}
}
const
loading
=
ref
()
// ElLoading.service 返回的实例
watch
(
()
=>
currentRoute
.
value
,
(
route
:
RouteLocationNormalizedLoaded
)
=>
{
redirect
.
value
=
route
?.
query
?.
redirect
as
string
},
{
immediate
:
true
}
)
onMounted
(()
=>
{
// getCookie()
getTenantByWebsite
()
})
</
script
>
<
style
lang=
"scss"
scoped
>
:deep
(
.anticon
)
{
&:hover
{
color
:
var
(
--el-color-primary
)
!important
;
}
}
.login-code
{
float
:
right
;
width
:
100%
;
height
:
38px
;
img
{
width
:
100%
;
height
:
auto
;
max-width
:
100px
;
vertical-align
:
middle
;
cursor
:
pointer
;
}
}
</
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