Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
CivWeb
Project
Project
Details
Activity
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
ReactWeb5
CivWeb
Commits
0e5eecd5
Commit
0e5eecd5
authored
Dec 17, 2024
by
周宏民
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: 验证码登录
parent
464eb3b2
Pipeline
#94688
passed with stages
Changes
7
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
106 additions
and
107 deletions
+106
-107
reducer.js
src/containers/App/store/reducer.js
+5
-0
LoginItem.js
src/pages/user/login/components/Login/LoginItem.js
+53
-7
index.js
src/pages/user/login/components/Login/index.js
+4
-1
index.less
src/pages/user/login/components/Login/index.less
+1
-0
useAccount.js
src/pages/user/login/js/useAccount.js
+2
-7
login.js
src/pages/user/login/login.js
+2
-1
baseLogin.js
src/pages/user/login/template/baseLogin.js
+39
-91
No files found.
src/containers/App/store/reducer.js
View file @
0e5eecd5
...
...
@@ -92,7 +92,12 @@ const appReducer = (state = initialState, action) => {
window
.
__INITIAL_STATE__
.
menu
=
'banner-left'
;
const
temp
=
AppConfig
(
window
.
__INITIAL_STATE__
);
temp
.
displayMode
=
window
.
__INITIAL_STATE__
?.
displayMode
||
''
;
// 验证码开启 系统配置表里配置
temp
.
isVerification
=
action
.
data
.
isVerification
||
''
;
// 验证码配置 站点设置里配置 只针对该站点
temp
.
isVerificationCode
=
action
.
data
.
VerificationConfig
?.
IsVerificationCode
||
false
;
temp
.
verificationCodeTimeOut
=
action
.
data
.
VerificationConfig
?.
VerificationCodeTimeOut
||
1
;
temp
.
verificationCodeType
=
action
.
data
.
VerificationConfig
?.
VerificationCodeType
||
''
;
window
.
globalConfig
=
temp
;
// eslint-disable-next-line no-undef
...
...
src/pages/user/login/components/Login/LoginItem.js
View file @
0e5eecd5
...
...
@@ -2,7 +2,7 @@ import 'kit_logger';
import
React
,
{
useCallback
,
useEffect
,
useState
,
useRef
}
from
'react'
;
import
{
FieldNumberOutlined
,
ReloadOutlined
}
from
'@ant-design/icons'
;
import
{
Button
,
Form
,
Input
,
message
}
from
'antd'
;
import
{
Button
,
Form
,
Input
,
message
,
Space
}
from
'antd'
;
import
omit
from
'omit.js'
;
import
{
useIntl
}
from
'@wisdom-utils/components'
;
...
...
@@ -38,6 +38,8 @@ const ValidateCode = props => {
const
codeUrl
=
window
?.
globalConfig
?.
hasGateWay
?
'/PandaCore/Identity/GetVerificationCode'
:
'/PandaCore/GCK/BussinessAuth/GetVerificationCode'
;
const
verificationCodeTimeOut
=
(
window
?.
globalConfig
?.
verificationCodeTimeOut
||
1
)
*
60
;
const
onTimeOver
=
()
=>
{
console
.
log
(
'超时了'
);
setIsOver
(
true
);
...
...
@@ -75,14 +77,13 @@ const ValidateCode = props => {
},
[]);
useEffect
(()
=>
{
if
(
!
isOver
)
{
console
.
log
(
'开始计时'
);
if
(
timer
.
current
)
{
clearInterval
(
timer
.
current
);
timer
.
current
=
null
;
}
timer
.
current
=
setTimeout
(()
=>
{
onTimeOver
();
},
60
*
1000
);
},
verificationCodeTimeOut
*
1000
);
}
return
()
=>
{
if
(
timer
.
current
)
{
...
...
@@ -119,7 +120,8 @@ const ValidateCode = props => {
};
const
LoginItem
=
props
=>
{
const
[
count
,
setCount
]
=
useState
(
props
.
countDown
||
0
);
const
{
isVerificationCode
,
verificationCodeType
,
verificationCodeTimeOut
}
=
window
.
globalConfig
;
const
[
count
,
setCount
]
=
useState
(
props
.
countDown
||
(
verificationCodeTimeOut
||
1
)
*
60
);
const
[
timing
,
setTiming
]
=
useState
(
false
);
const
[
ext
,
setExt
]
=
useState
(
''
);
const
intl
=
useIntl
();
...
...
@@ -136,7 +138,9 @@ const LoginItem = props => {
tabUtil
,
...
restProps
}
=
props
;
if
(
isVerificationCode
&&
(
verificationCodeType
&&
verificationCodeType
!==
'图片验证码'
)
&&
customProps
?.
size
)
{
customProps
.
size
=
''
;
}
const
onGetCaptcha
=
useCallback
(
mobile
=>
{
// eslint-disable-next-line no-undef
if
(
window
.
globalConfig
?.
hasGateWay
)
{
...
...
@@ -178,21 +182,23 @@ const LoginItem = props => {
useEffect
(()
=>
{
let
interval
=
0
;
const
{
countDown
}
=
props
;
const
timeDown
=
countDown
||
(
verificationCodeTimeOut
||
1
)
*
60
;
if
(
timing
)
{
interval
=
window
.
setInterval
(()
=>
{
setCount
(
preSecond
=>
{
if
(
preSecond
<=
1
)
{
setTiming
(
false
);
clearInterval
(
interval
);
return
countDown
||
60
;
return
timeDown
;
}
return
preSecond
-
1
;
});
},
1000
);
}
return
()
=>
clearInterval
(
interval
);
},
[
props
,
timing
]);
},
[
props
.
countDown
,
timing
]);
if
(
!
name
)
{
return
null
;
...
...
@@ -256,6 +262,46 @@ const LoginItem = props => {
}
if
(
type
===
'Validate'
)
{
// 短信验证码
if
(
verificationCodeType
===
'阿里云短信验证码'
)
{
const
inputProps
=
omit
(
otherProps
,
[
'onGetCaptcha'
,
'countDown'
]);
return
(
<>
<
FormItem
name
=
"mobile"
rules
=
{
ItemMap
.
Mobile
.
rules
}
>
<
Input
{...
ItemMap
.
Mobile
.
props
}
size
=
"middle"
placeholder
=
"请输入手机号码"
/>
<
/FormItem
>
<
FormItem
shouldUpdate
style
=
{{
marginBottom
:
'0px'
}}
>
{({
getFieldValue
,
validateFields
})
=>
(
<
Space
align
=
"start"
>
<
FormItem
name
=
{
name
}
{...
options
}
rules
=
{
rules
}
>
<
Input
{...
customProps
}
{...
inputProps
}
/
>
<
/FormItem
>
<
Button
disabled
=
{
timing
}
className
=
{
styles
.
getCaptcha
}
style
=
{{
lineHeight
:
'32px'
,
width
:
'110px'
,
textAlign
:
'center'
}}
size
=
"large"
onClick
=
{()
=>
{
validateFields
([
'mobile'
])
.
then
(
values
=>
{
onGetCaptcha
(
values
.
mobile
);
})
.
catch
(
error
=>
{
Logger
.
log
(
error
);
});
}}
>
{
timing
?
`
${
intl
.
formatMessage
({
id
:
'pages.login.phoneLogin.sendCationCode'
})}
(
${
count
}
)`
:
intl
.
formatMessage
({
id
:
'pages.login.phoneLogin.getVerificationCode'
})}
<
/Button
>
<
/Space
>
)}
<
/FormItem
>
<
/
>
);
}
// 图形验证码
return
(
<
Form
.
Item
name
=
{
name
}
{...
options
}
>
<
ValidateCode
{...
customProps
}
{...
otherProps
}
/
>
...
...
src/pages/user/login/components/Login/index.js
View file @
0e5eecd5
...
...
@@ -14,6 +14,7 @@ const Login = props => {
const
intl
=
useIntl
();
const
{
className
}
=
props
;
const
otherChildren
=
[];
React
.
Children
.
forEach
(
props
.
children
,
child
=>
{
if
(
!
child
)
{
return
;
...
...
@@ -25,7 +26,9 @@ const Login = props => {
<
div
className
=
{
classNames
(
className
,
styles
.
login
)}
>
{
props
.
welcome
===
void
0
?
(
<
div
className
=
{
styles
.
desc
}
>
{
intl
.
formatMessage
({
id
:
'pages.login.welcome'
})}
<
/div
>
)
:
props
.
welcome
}
)
:
(
props
.
welcome
)}
<
Form
form
=
{
props
.
from
}
onFinish
=
{
values
=>
{
...
...
src/pages/user/login/components/Login/index.less
View file @
0e5eecd5
...
...
@@ -113,6 +113,7 @@
width: 100%;
height: 100%;
object-fit: contain;
margin: 0;
}
.validate_invalid {
...
...
src/pages/user/login/js/useAccount.js
View file @
0e5eecd5
...
...
@@ -44,16 +44,11 @@ const useAccount = props => (
/
>
{
props
?.
isValidate
?
<
Validate
name
=
"validate"
/>
:
null
}
<
div
>
<
Checkbox
checked
=
{
props
.
autoLogin
}
onChange
=
{
e
=>
props
.
setAutoLogin
(
e
.
target
.
checked
)}
>
<
Checkbox
checked
=
{
props
.
autoLogin
}
onChange
=
{
e
=>
props
.
setAutoLogin
(
e
.
target
.
checked
)}
>
{
useIntl
().
formatMessage
({
id
:
'pages.login.rememberMe'
})}
<
/Checkbox
>
<
/div
>
<
Submit
loading
=
{
props
.
submitting
}
>
{
useIntl
().
formatMessage
({
id
:
'pages.login.submit'
})}
<
/Submit
>
<
Submit
loading
=
{
props
.
submitting
}
>
{
useIntl
().
formatMessage
({
id
:
'pages.login.submit'
})}
<
/Submit
>
<
/LoginForm
>
);
...
...
src/pages/user/login/login.js
View file @
0e5eecd5
...
...
@@ -1567,7 +1567,8 @@ class Login {
loginHandlerValidate
(
user
,
pwd
,
userPhone
,
isRememberPWD
,
ref
,
validateCode
=
''
)
{
const
self
=
this
;
if
((
this
.
globalConfig
?.
isVerification
||
0
)
*
1
===
1
)
// isVerification 取自系统配置表,isVerificationCode 取自 站点配置,isVerificationCode为1 会默认把 isVerificationCode改为true
if
((
this
.
globalConfig
?.
isVerification
||
0
)
*
1
===
1
||
this
.
globalConfig
.
isVerificationCode
)
return
self
.
loginValidate
(
user
,
pwd
,
userPhone
,
isRememberPWD
,
SERVICE_APP_LOGIN_MODE
.
password
,
validateCode
);
if
(
user
&&
pwd
)
{
if
(
self
.
loginFailed
&&
self
.
captchaObj
)
{
...
...
src/pages/user/login/template/baseLogin.js
View file @
0e5eecd5
...
...
@@ -37,23 +37,19 @@ const Login = forwardRef((props, _ref) => {
const
[
action
,
setAction
]
=
useState
(()
=>
new
LoginAction
(
Object
.
assign
({},
props
,
{
history
}),
setVisible
,
false
));
const
[
showVideo
,
setShowVideo
]
=
useState
(
false
);
let
{
ddCode
}
=
props
.
global
;
const
{
isVerificationCode
,
isVerification
,
verificationCodeType
}
=
window
.
globalConfig
;
const
isValidate
=
(
isVerification
||
0
)
*
1
===
1
||
isVerificationCode
;
const
loginMode
=
Cookies
.
get
(
'loginMode'
)
||
null
;
if
(
loginMode
&&
loginMode
===
'iotWechat'
)
ddCode
=
null
;
// useEffect(() => {
// action.globalConfig = props.global;
// }, [props.global]);
const
handleSubmit
=
values
=>
{
/* eslint-disable */
action
&&
(
type
===
'Account'
?
action
.
loginHandler
(
values
.
userName
,
values
.
password
,
null
,
autoLogin
,
sliVerify
,
)
?
isValidate
?
action
.
loginHandlerValidate
(
values
.
userName
,
values
.
password
,
null
,
autoLogin
,
'none'
,
values
?.
validate
)
:
action
.
loginHandler
(
values
.
userName
,
values
.
password
,
null
,
autoLogin
,
sliVerify
)
:
type
===
'Mobile'
?
action
.
phoneLoginFormHandler
(
values
.
mobile
,
values
.
captcha
)
:
null
);
...
...
@@ -85,7 +81,7 @@ const Login = forwardRef((props, _ref) => {
});
action
.
events
.
on
(
'loginHomePage'
,
()
=>
{
props
.
history
.
push
(
`/homePage`
);
})
});
action
.
events
.
on
(
'loginIndustry'
,
()
=>
{
props
.
history
.
push
(
`/industry`
);
});
...
...
@@ -95,24 +91,19 @@ const Login = forwardRef((props, _ref) => {
action
&&
action
.
events
&&
action
.
events
.
removeAllListeners
(
'loginVisible'
);
action
&&
action
.
events
&&
action
.
events
.
removeAllListeners
(
'loginHomePage'
);
action
&&
action
.
events
&&
action
.
events
.
removeAllListeners
(
'loginIndustry'
);
}
}
;
},
[
props
.
loginMode
]);
let
loginTimeInterval
=
null
;
let
videoTimeout
=
null
;
useEffect
(()
=>
{
if
(
loginTimeInterval
)
clearInterval
(
loginTimeInterval
),
(
loginTimeInterval
=
null
);
if
(
loginTimeInterval
)
clearInterval
(
loginTimeInterval
),
(
loginTimeInterval
=
null
);
loginTimeInterval
=
setInterval
(()
=>
{
const
date
=
new
Date
();
const
weekday
=
[
'周日'
,
'周一'
,
'周二'
,
'周三'
,
'周四'
,
'周五'
,
'周六'
];
const
time
=
`
${
date
.
getHours
()
<
10
?
`0
${
date
.
getHours
()}
`
:
date
.
getHours
()
}
:
${
const
time
=
`
${
date
.
getHours
()
<
10
?
`0
${
date
.
getHours
()}
`
:
date
.
getHours
()}
:
${
date
.
getMinutes
()
<
10
?
`0
${
date
.
getMinutes
()}
`
:
date
.
getMinutes
()
}
:
${
date
.
getSeconds
()
<
10
?
`0
${
date
.
getSeconds
()}
`
:
date
.
getSeconds
()
}
`
;
}
:
${
date
.
getSeconds
()
<
10
?
`0
${
date
.
getSeconds
()}
`
:
date
.
getSeconds
()}
`
;
setCurrentDate
({
time
,
dayofweek
:
weekday
[
date
.
getDay
()],
...
...
@@ -125,7 +116,7 @@ const Login = forwardRef((props, _ref) => {
},
[]);
useEffect
(()
=>
{
if
(
ddCode
&&
loginMode
===
'qywx'
)
{
if
(
ddCode
&&
loginMode
===
'qywx'
)
{
setShowVideo
(
false
);
}
else
{
setShowVideo
(
true
);
...
...
@@ -176,11 +167,11 @@ const Login = forwardRef((props, _ref) => {
switch
(
template
)
{
case
'DarkCloud.html'
:
case
'Dark.html'
:
return
<
Account
{...
params
}
/>
;
return
<
Account
{...
params
}
isValidate
=
{
isValidate
}
/>
;
case
'Dark - IOTMultiLogin.html'
:
return
<
IotComponent
{...
params
}
/>
;
default
:
return
<
Account
{...
params
}
/>
;
return
<
Account
{...
params
}
isValidate
=
{
isValidate
}
/>
;
}
};
/* eslint-disable */
...
...
@@ -192,78 +183,45 @@ const Login = forwardRef((props, _ref) => {
<
meta
name
=
"description"
content
=
{
props
.
global
.
title
||
defaultSetting
.
title
}
/
>
<
/Helmet
>
<
div
className
=
{
styles
.
main
}
>
{
showVideo
&&
<
video
src
=
{
require
(
"../../../../assets/videos/beforPage.mp4"
)
}
{
showVideo
&&
(
<
video
src
=
{
require
(
'../../../../assets/videos/beforPage.mp4'
)}
className
=
{
styles
.
videLayer
}
autoPlay
=
"autoPlay"
muted
playsInline
=
"playsinline"
ref
=
{
videoRef
}
/>
}
/
>
)}
<
div
className
=
{
styles
.
inner
}
>
<
div
className
=
{
classNames
(
styles
.
loginTime
,
styles
.
caseHide
)}
ref
=
{
loginRef
}
>
<
div
className
=
{
classNames
(
styles
.
loginTime
,
styles
.
caseHide
)}
ref
=
{
loginRef
}
>
<
img
role
=
"logo"
src
=
{
props
.
global
&&
props
.
global
.
transformDevAssetsBaseURL
&&
props
.
global
.
transformDevAssetsBaseURL
(
props
.
global
.
logo
)}
src
=
{
props
.
global
&&
props
.
global
.
transformDevAssetsBaseURL
&&
props
.
global
.
transformDevAssetsBaseURL
(
props
.
global
.
logo
)
}
/
>
<
div
className
=
{
classNames
(
styles
.
titleCase
,
styles
.
caseHide
,
'animated'
,
)}
ref
=
{
titleRef
}
>
<
div
className
=
{
classNames
(
styles
.
titleCase
,
styles
.
caseHide
,
'animated'
)}
ref
=
{
titleRef
}
>
<
span
className
=
{
styles
.
title
}
>
{
props
.
global
.
title
}
<
/span
>
<
span
className
=
{
styles
.
subtitle
}
>
{
window
.
globalConfig
&&
window
.
globalConfig
.
subtitle
}
<
/span
>
<
span
className
=
{
styles
.
subtitle
}
>
{
window
.
globalConfig
&&
window
.
globalConfig
.
subtitle
}
<
/span
>
<
/div
>
<
/div
>
<
span
className
=
{
classNames
(
styles
.
divider
,
styles
.
caseHide
,
'animate__animated'
,
)}
/
>
<
div
className
=
{
classNames
(
styles
.
timeCase
,
styles
.
caseHide
,
'animate__animated'
,
)}
ref
=
{
timeRef
}
>
<
span
className
=
{
classNames
(
styles
.
divider
,
styles
.
caseHide
,
'animate__animated'
)}
/
>
<
div
className
=
{
classNames
(
styles
.
timeCase
,
styles
.
caseHide
,
'animate__animated'
)}
ref
=
{
timeRef
}
>
<
span
className
=
{
styles
.
time
}
>
{
currentDate
.
time
}
<
/span
>
<
span
className
=
{
styles
.
dayofweek
}
>
{
currentDate
.
dayofweek
}
<
/span
>
<
span
className
=
{
styles
.
date
}
>
{
currentDate
.
date
}
<
/span
>
<
/div
>
<
div
className
=
{
classNames
(
styles
[
'login-block'
],
styles
.
caseHide
,
'animate__animated'
,
)}
ref
=
{
loginFormRef
}
>
<
div
className
=
{
classNames
(
styles
[
'login-block'
],
styles
.
caseHide
,
'animate__animated'
)}
ref
=
{
loginFormRef
}
>
<
div
>
<
img
src
=
{
require
(
'@/assets/images/login/dark/login.png'
)}
/
>
<
/div
>
<
div
className
=
{
styles
[
'login-form'
]}
>
{
renderPlatform
()}
<
/div
>
<
/div
>
<
/div
>
<
div
className
=
{
classNames
(
styles
.
footerCase
,
styles
.
caseHide
,
'animate__animated'
,
)}
ref
=
{
footerRef
}
>
<
div
className
=
{
classNames
(
styles
.
footerCase
,
styles
.
caseHide
,
'animate__animated'
)}
ref
=
{
footerRef
}
>
<
div
className
=
{
classNames
(
styles
.
quickMark
)}
>
{
renderAddons
}
<
/div
>
<
span
className
=
{
classNames
(
styles
.
copyright
)}
>
Copyright
©
...
...
@@ -271,32 +229,22 @@ const Login = forwardRef((props, _ref) => {
熊猫智慧水务
<
/a
>
{
new
Date
().
getFullYear
()}
All
Rights
Reserved
{
' '
}
{
window
.
location
.
host
.
includes
(
"panda-water"
)
?
{
window
.
location
.
host
.
includes
(
'panda-water'
)
?
(
<
a
target
=
"_blank"
id
=
"IndexCaseNumber"
href
=
"https://beian.miit.gov.cn"
>
沪
ICP
备
18045097
号
-
1
<
/a> : ""
}
<
/a
>
)
:
(
''
)}
<
span
className
=
"addons"
>
<
span
className
=
"split"
/>
<
a
id
=
"qrcode"
>
<
span
className
=
"glyphicon glyphicon-qrcode"
role
=
"button"
title
=
"手持APP下载"
/>
<
span
className
=
"glyphicon glyphicon-qrcode"
role
=
"button"
title
=
"手持APP下载"
/>
<
/a
>
<
/span
>
<
/span
>
<
/div
>
<
Modal
centered
visible
=
{
visible
}
width
=
{
340
}
footer
=
{
null
}
closable
=
{
false
}
bodyStyle
=
{{
padding
:
'15px'
}}
>
<
Modal
centered
visible
=
{
visible
}
width
=
{
340
}
footer
=
{
null
}
closable
=
{
false
}
bodyStyle
=
{{
padding
:
'15px'
}}
>
<
div
ref
=
{
sliVerify
}
/
>
<
/Modal
>
<
/div
>
...
...
@@ -326,4 +274,4 @@ const mapDispatchToProps = dispatch => ({
export
default
connect
(
mapStateToProps
,
mapDispatchToProps
,
)(
(
Login
)
);
)(
Login
);
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