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
bf6df595
Commit
bf6df595
authored
Aug 03, 2021
by
邓晓峰
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 梳理登录模块
parent
620fd83b
Pipeline
#32469
skipped with stages
Changes
11
Pipelines
1
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
394 additions
and
193 deletions
+394
-193
.eslintrc.js
.eslintrc.js
+2
-1
proxy.js
config/proxy.js
+1
-1
constants.js
src/constants.js
+3
-2
loginMessage.js
src/pages/user/login/js/loginMessage.js
+14
-0
useAccount.js
src/pages/user/login/js/useAccount.js
+59
-0
useIOTComponent.js
src/pages/user/login/js/useIOTComponent.js
+59
-0
useIOTQRCode.js
src/pages/user/login/js/useIOTQRCode.js
+35
-0
usePhone.js
src/pages/user/login/js/usePhone.js
+35
-0
useRenderQcode.js
src/pages/user/login/js/useRenderQcode.js
+184
-0
baseLogin.js
src/pages/user/login/template/baseLogin.js
+0
-0
newYear.js
src/pages/user/login/template/newYear.js
+2
-189
No files found.
.eslintrc.js
View file @
bf6df595
...
...
@@ -87,7 +87,8 @@ module.exports = {
'react/static-property-placement'
:
0
,
'react/destructuring-assignment'
:
0
,
'react/no-array-index-key'
:
'warn'
,
'react-hooks/rules-of-hooks'
:
'error'
,
"react-hooks/rules-of-hooks"
:
"error"
,
"react-hooks/exhaustive-deps"
:
"warn"
,
'react/jsx-closing-tag-location'
:
0
,
'react/forbid-prop-types'
:
0
,
'react/jsx-first-prop-new-line'
:
[
2
,
'multiline'
],
...
...
config/proxy.js
View file @
bf6df595
/* eslint-disable */
// const proxyURL = process.env.NODE_ENV !== 'production' ? 'http://192.168.10.150:8777' : window.location.origin;
const
proxyURL
=
'http
://192.168.19.105:8082
'
;
const
proxyURL
=
'http
s://panda-water.com
'
;
module
.
exports
=
{
assetsRoot
:
process
.
env
.
NODE_ENV
!==
'production'
?
proxyURL
:
'./'
,
dev
:
{
...
...
src/constants.js
View file @
bf6df595
...
...
@@ -18,6 +18,8 @@ export const LOGIN_WAY = {
Mobile
:
'iotPhone'
,
};
export
const
WECHART_APPID
=
'wx8bfa8b02cb95010b'
;
export
const
WX_REDIRECT_URI
=
'https://panda-water.com/civbase/user/login'
;
...
...
@@ -30,4 +32,4 @@ export const REQUEST_POP = 'pop';
export
const
REQUEST_METHOD_GET
=
'get'
;
export
const
REQUEST_METHOD_POST
=
'post'
;
export
const
REQUEST_METHOD_PUT
=
'put'
;
export
const
REQUEST_METHOD_DELETE
=
'delete'
;
\ No newline at end of file
export
const
REQUEST_METHOD_DELETE
=
'delete'
;
src/pages/user/login/js/loginMessage.js
0 → 100644
View file @
bf6df595
import
{
Alert
}
from
'antd'
;
import
React
from
'react'
;
const
LoginMessage
=
({
content
})
=>
(
<
Alert
style
=
{{
marginBottom
:
2
,
}}
message
=
{
content
}
type
=
"error"
showIcon
/>
);
export
default
LoginMessage
;
src/pages/user/login/js/useAccount.js
0 → 100644
View file @
bf6df595
import
{
Checkbox
}
from
'antd'
;
import
React
from
'react'
;
import
LoginForm
from
'../components/Login'
;
import
LoginMessage
from
'./loginMessage'
;
import
{
useIntl
}
from
'@/locales/localeExports'
;
/* eslint-disable */
const
{
UserName
,
Password
,
Submit
}
=
LoginForm
;
const
useAccount
=
props
=>
(
<
LoginForm
onSubmit
=
{
props
.
onSubmit
}
>
{
props
.
status
===
'error'
&&
props
.
type
===
'account'
&&
!
props
.
submitting
&&
(
<
LoginMessage
content
=
{
useIntl
().
formatMessage
({
id
:
'pages.login.accountLogin.errorMessage'
,
})}
/
>
)}
<
UserName
name
=
"userName"
placeholder
=
{
useIntl
().
formatMessage
({
id
:
'pages.login.username.placeholder'
,
})}
rules
=
{[
{
required
:
true
,
message
:
useIntl
().
formatMessage
({
id
:
'pages.login.username.required'
,
}),
},
]}
/
>
<
Password
name
=
"password"
placeholder
=
{
useIntl
().
formatMessage
({
id
:
'pages.login.password.placeholder'
,
})}
rules
=
{[
{
required
:
true
,
message
:
useIntl
().
formatMessage
({
id
:
'pages.login.password.required'
,
}),
},
]}
/
>
<
div
>
<
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
>
<
/LoginForm
>
);
export
default
useAccount
;
src/pages/user/login/js/useIOTComponent.js
0 → 100644
View file @
bf6df595
import
Cookies
from
'js-cookie'
;
import
React
from
'react'
;
import
{
LOGIN_DISPLAY
,
LOGIN_WAY
}
from
'@/constants'
;
import
Account
from
'./useAccount'
;
import
IOTQRCode
from
'./useIOTQRCode'
;
import
Phone
from
'./usePhone'
;
import
{
useIntl
}
from
'@/locales/localeExports'
;
import
styles
from
'../style.less'
;
const
useIOTComponent
=
props
=>
{
const
handlerType
=
type
=>
{
props
.
setType
(
LOGIN_DISPLAY
[
type
]);
props
.
updateLoginMode
(
LOGIN_WAY
[
type
]);
Cookies
.
set
(
'loginMode'
,
LOGIN_WAY
[
type
],
{
expires
:
5
*
60
*
1000
,
path
:
'/'
,
});
};
return
(
<
div
className
=
{
styles
.
wechatQRcode
}
>
{
props
.
type
===
LOGIN_DISPLAY
.
Account
?
(
<
Account
{...
props
}
/
>
)
:
props
.
type
===
LOGIN_DISPLAY
.
WeChart
?
(
<
IOTQRCode
{...
props
}
/
>
)
:
props
.
type
===
LOGIN_DISPLAY
.
Mobile
?
(
<
Phone
{...
props
}
/
>
)
:
(
<
Account
{...
props
}
/
>
)}
<
div
className
=
{
styles
.
loginDisplay
}
>
<
a
onClick
=
{()
=>
handlerType
(
'Account'
)}
style
=
{{
display
:
props
.
type
===
LOGIN_DISPLAY
.
Account
?
'none'
:
'block'
,
}}
>
{
useIntl
().
formatMessage
({
id
:
'pages.login.accountLogin.tab'
})}
<
/a
>
<
a
onClick
=
{()
=>
handlerType
(
'WeChart'
)}
style
=
{{
display
:
props
.
type
===
LOGIN_DISPLAY
.
WeChart
?
'none'
:
'block'
,
}}
>
{
useIntl
().
formatMessage
({
id
:
'pages.login.weChart.tab'
})}
<
/a
>
<
a
onClick
=
{()
=>
handlerType
(
'Mobile'
)}
style
=
{{
display
:
props
.
type
===
LOGIN_DISPLAY
.
Mobile
?
'none'
:
'block'
,
}}
>
{
useIntl
().
formatMessage
({
id
:
'pages.login.phoneLogin.tab'
})}
<
/a
>
<
/div
>
<
/div
>
);
};
export
default
useIOTComponent
;
src/pages/user/login/js/useIOTQRCode.js
0 → 100644
View file @
bf6df595
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
{
encode
}
from
'js-base64'
;
import
Cookies
from
'js-cookie'
;
import
WxLogin
from
'../components/WxLogin'
;
import
{
WECHART_APPID
,
WX_REDIRECT_URI
}
from
'../../../../constants'
;
const
useIOTQRCode
=
()
=>
{
const
[
rstate
,
setRstate
]
=
useState
(()
=>
encode
(
`panda_
${
Math
.
round
(
Math
.
random
()
*
10000
+
Date
.
now
()).
toString
(
16
)}
`
,
),
);
useEffect
(()
=>
{
Cookies
.
set
(
'redirect_state'
,
rstate
,
{
expires
:
5
*
60
*
1000
,
path
:
'/'
,
});
},
[]);
const
props
=
Object
.
assign
(
{},
{
self_redirect
:
false
,
scope
:
'snsapi_login'
,
appid
:
WECHART_APPID
,
state
:
rstate
,
redirect_uri
:
WX_REDIRECT_URI
,
href
:
'https://panda-water.cn/web4/styles/PandaIOTQrcodeStyle.css'
,
},
);
return
<
WxLogin
{...
props
}
/>
;
};
export
default
useIOTQRCode
;
src/pages/user/login/js/usePhone.js
0 → 100644
View file @
bf6df595
import
{
Form
}
from
'antd'
;
import
React
from
'react'
;
import
LoginForm
from
'../components/Login'
;
import
LoginMessage
from
'./loginMessage'
;
const
{
Mobile
,
Captcha
,
Submit
}
=
LoginForm
;
const
usePhone
=
props
=>
{
const
[
form
]
=
Form
.
useForm
();
return
(
<
LoginForm
form
=
{
form
}
onSubmit
=
{
props
.
onSubmit
}
>
{
props
.
status
===
'error'
&&
props
.
type
===
'account'
&&
!
props
.
submitting
&&
<
LoginMessage
content
=
"手机号码未注册"
/>
}
<
Mobile
name
=
"mobile"
placeholder
=
"请输入手机号码"
/>
<
Captcha
name
=
"captcha"
placeholder
=
"请输入短信验证码"
countDown
=
{
60
}
getCaptchaButtonText
=
""
getCaptchaSecondText
=
"秒"
autoComplete
=
"off"
rules
=
{[
{
required
:
true
,
message
:
'请输入短信验证码!'
,
},
]}
/
>
<
Submit
loading
=
{
props
.
submitting
}
style
=
{{
marginTop
:
'0px'
}}
>
登录
<
/Submit
>
<
/LoginForm
>
);
};
export
default
usePhone
;
src/pages/user/login/js/useRenderQcode.js
0 → 100644
View file @
bf6df595
import
React
from
'react'
;
import
classNames
from
'classnames'
;
import
{
Popover
}
from
'antd'
;
import
QRCode
from
'qrcode.react'
;
import
styles
from
'../style.less'
;
const
useRenderQcode
=
props
=>
{
if
(
!
props
.
qrcode
)
{
return
null
;
}
const
qrcodes
=
props
.
qrcode
.
split
(
'|'
);
const
qcodeComponent
=
url
=>
(
<
img
src
=
{
url
}
className
=
"QuickMark-cont"
style
=
{{
width
:
'150px'
,
height
:
'150px'
}}
alt
=
""
/>
);
const
element
=
[];
qrcodes
.
forEach
((
item
,
index
)
=>
{
const
firstValue
=
item
.
split
(
'='
);
switch
(
firstValue
[
0
])
{
case
'小程序'
:
element
.
push
(
<
div
className
=
{
classNames
(
styles
[
'quickMark-single'
],
styles
[
'mini-single'
],
)}
key
=
{
firstValue
[
0
]}
>
<
Popover
placement
=
"top"
content
=
{
qcodeComponent
(
'https://panda-water.cn/web4/assets/images/小程序二维码.jpg'
,
)}
>
<
div
className
=
{
styles
[
'icon-Container'
]}
>
<
span
className
=
{
styles
.
Wechat
}
/
>
<
span
className
=
"iconText WechatText"
>
Wechat
<
/span
>
<
/div
>
<
/Popover
>
<
/div>
,
);
break
;
case
'智联小程序'
:
element
.
push
(
<
div
className
=
{
classNames
(
styles
[
'quickMark-single'
],
'miniIOT-single'
)}
key
=
{
firstValue
[
0
]}
>
<
Popover
placement
=
"top"
content
=
{
qcodeComponent
(
'https://panda-water.cn/web4/assets/images/智联小程序二维码.jpg'
,
)}
>
<
div
className
=
{
styles
[
'icon-Container'
]}
>
<
span
className
=
{
styles
.
Wechat
}
/
>
<
span
className
=
{
classNames
(
styles
.
iconText
,
styles
.
WechatText
)}
>
熊猫智联
<
/span
>
<
/div
>
<
/Popover
>
<
/div>
,
);
break
;
case
'Android'
:
if
(
firstValue
[
1
]
&&
firstValue
[
1
].
replace
(
/ /g
,
''
).
length
>
0
)
{
element
.
push
(
<
div
className
=
{
classNames
(
styles
[
'quickMark-single'
],
'Android-single'
,
)}
key
=
{
firstValue
[
0
]}
>
<
Popover
placement
=
"top"
content
=
{
<
QRCode
value
=
{
firstValue
[
1
].
replace
(
/{ip}/gi
,
props
.
ip
||
window
.
location
.
host
,
)}
/
>
}
>
<
div
className
=
{
styles
[
'icon-Container'
]}
>
<
span
className
=
{
styles
.
Android
}
/
>
<
span
className
=
{
classNames
(
styles
.
iconText
,
styles
.
AndroidText
)}
>
Android
<
/span
>
<
/div
>
<
/Popover
>
<
/div>
,
);
}
break
;
case
'iPhone'
:
if
(
firstValue
[
1
]
&&
firstValue
[
1
].
replace
(
/ /g
,
''
).
length
>
0
)
{
element
.
push
(
<
div
className
=
{
classNames
(
styles
[
'quickMark-single'
],
'iphone-single'
,
)}
key
=
{
firstValue
[
0
]}
>
<
Popover
placement
=
"top"
content
=
{
<
QRCode
value
=
{
firstValue
[
1
].
replace
(
/{ip}/gi
,
props
.
ip
||
window
.
location
.
host
,
)}
/
>
}
>
<
div
className
=
{
styles
[
'icon-Container'
]}
>
<
span
className
=
{
styles
.
Wechat
}
/
>
<
span
className
=
{
classNames
(
styles
.
iconText
,
styles
.
iphoneText
)}
>
iPhone
<
/span
>
<
/div
>
<
/Popover
>
<
/div>
,
);
}
break
;
default
:
if
(
item
&&
item
.
replace
(
/ /g
,
''
).
length
>
0
)
{
const
indexIndex
=
element
.
findIndex
(
// eslint-disable-next-line no-shadow
item
=>
item
.
props
.
className
.
indexOf
(
'Android-single'
)
>
-
1
,
);
element
.
splice
(
indexIndex
,
1
);
element
.
push
(
<
div
className
=
{
classNames
(
styles
[
'quickMark-single'
],
'Android-single'
,
)}
key
=
{
index
}
>
<
Popover
placement
=
"top"
content
=
{
<
QRCode
value
=
{
item
.
replace
(
/{ip}/gi
,
props
.
ip
||
window
.
location
.
host
,
)}
/
>
}
>
<
div
className
=
{
styles
[
'icon-Container'
]}
>
<
span
className
=
{
styles
.
Android
}
/
>
<
span
className
=
{
classNames
(
styles
.
iconText
,
styles
.
AndroidText
)}
>
Android
<
/span
>
<
/div
>
<
/Popover
>
<
/div>
,
);
}
break
;
}
});
return
element
;
};
export
default
useRenderQcode
;
src/pages/user/login/template/baseLogin.js
View file @
bf6df595
This diff is collapsed.
Click to expand it.
src/pages/user/login/template/newYear.js
View file @
bf6df595
...
...
@@ -31,17 +31,17 @@ import {
LOGIN_WAY
,
}
from
'@/constants'
;
import
{
actionCreators
}
from
'@/containers/App/store'
;
// import { appService } from '../../../../api';
import
{
FormattedMessage
,
useIntl
,
}
from
'@/locales/localeExports'
;
import
defaultSetting
from
'../../../../../config/defaultSetting'
;
// import i18n from '../../../../utils/share';
import
LoginForm
from
'../components/Login'
;
import
WxLogin
from
'../components/WxLogin'
;
import
LoginAction
from
'../login'
;
import
LoginMessage
from
'../js/loginMessage'
;
import
useRenderQcode
from
'../js/useRenderQcode'
;
import
styles
from
'../style.less'
;
const
{
...
...
@@ -52,193 +52,6 @@ const {
Submit
,
}
=
LoginForm
;
const
LoginMessage
=
({
content
})
=>
(
<
Alert
style
=
{{
marginBottom
:
2
,
}}
message
=
{
content
}
type
=
"error"
showIcon
/>
);
const
useRenderQcode
=
props
=>
{
if
(
!
props
.
qrcode
)
{
return
null
;
}
const
qrcodes
=
props
.
qrcode
.
split
(
'|'
);
const
qcodeComponent
=
url
=>
(
<
img
src
=
{
url
}
className
=
"QuickMark-cont"
style
=
{{
width
:
'150px'
,
height
:
'150px'
}}
alt
=
""
/>
);
const
element
=
[];
qrcodes
.
forEach
((
item
,
index
)
=>
{
const
firstValue
=
item
.
split
(
'='
);
switch
(
firstValue
[
0
])
{
case
'小程序'
:
element
.
push
(
<
div
className
=
{
classNames
(
styles
[
'quickMark-single'
],
styles
[
'mini-single'
],
)}
key
=
{
firstValue
[
0
]}
>
<
Popover
placement
=
"top"
content
=
{
qcodeComponent
(
'https://panda-water.cn/web4/assets/images/小程序二维码.jpg'
,
)}
>
<
div
className
=
{
styles
[
'icon-Container'
]}
>
<
span
className
=
{
styles
.
Wechat
}
/
>
<
span
className
=
"iconText WechatText"
>
Wechat
<
/span
>
<
/div
>
<
/Popover
>
<
/div>
,
);
break
;
case
'智联小程序'
:
element
.
push
(
<
div
className
=
{
classNames
(
styles
[
'quickMark-single'
],
'miniIOT-single'
)}
key
=
{
firstValue
[
0
]}
>
<
Popover
placement
=
"top"
content
=
{
qcodeComponent
(
'https://panda-water.cn/web4/assets/images/智联小程序二维码.jpg'
,
)}
>
<
div
className
=
{
styles
[
'icon-Container'
]}
>
<
span
className
=
{
styles
.
Wechat
}
/
>
<
span
className
=
{
classNames
(
styles
.
iconText
,
styles
.
WechatText
)}
>
熊猫智联
<
/span
>
<
/div
>
<
/Popover
>
<
/div>
,
);
break
;
case
'Android'
:
if
(
firstValue
[
1
]
&&
firstValue
[
1
].
replace
(
/ /g
,
''
).
length
>
0
)
{
element
.
push
(
<
div
className
=
{
classNames
(
styles
[
'quickMark-single'
],
'Android-single'
,
)}
key
=
{
firstValue
[
0
]}
>
<
Popover
placement
=
"top"
content
=
{
<
QRCode
value
=
{
firstValue
[
1
].
replace
(
/{ip}/gi
,
props
.
ip
||
window
.
location
.
host
,
)}
/
>
}
>
<
div
className
=
{
styles
[
'icon-Container'
]}
>
<
span
className
=
{
styles
.
Android
}
/
>
<
span
className
=
{
classNames
(
styles
.
iconText
,
styles
.
AndroidText
)}
>
Android
<
/span
>
<
/div
>
<
/Popover
>
<
/div>
,
);
}
break
;
case
'iPhone'
:
if
(
firstValue
[
1
]
&&
firstValue
[
1
].
replace
(
/ /g
,
''
).
length
>
0
)
{
element
.
push
(
<
div
className
=
{
classNames
(
styles
[
'quickMark-single'
],
'iphone-single'
,
)}
key
=
{
firstValue
[
0
]}
>
<
Popover
placement
=
"top"
content
=
{
<
QRCode
value
=
{
firstValue
[
1
].
replace
(
/{ip}/gi
,
props
.
ip
||
window
.
location
.
host
,
)}
/
>
}
>
<
div
className
=
{
styles
[
'icon-Container'
]}
>
<
span
className
=
{
styles
.
Wechat
}
/
>
<
span
className
=
{
classNames
(
styles
.
iconText
,
styles
.
iphoneText
)}
>
iPhone
<
/span
>
<
/div
>
<
/Popover
>
<
/div>
,
);
}
break
;
default
:
if
(
item
&&
item
.
replace
(
/ /g
,
''
).
length
>
0
)
{
const
indexIndex
=
element
.
findIndex
(
// eslint-disable-next-line no-shadow
item
=>
item
.
props
.
className
.
indexOf
(
'Android-single'
)
>
-
1
,
);
element
.
splice
(
indexIndex
,
1
);
element
.
push
(
<
div
className
=
{
classNames
(
styles
[
'quickMark-single'
],
'Android-single'
,
)}
key
=
{
index
}
>
<
Popover
placement
=
"top"
content
=
{
<
QRCode
value
=
{
item
.
replace
(
/{ip}/gi
,
props
.
ip
||
window
.
location
.
host
,
)}
/
>
}
>
<
div
className
=
{
styles
[
'icon-Container'
]}
>
<
span
className
=
{
styles
.
Android
}
/
>
<
span
className
=
{
classNames
(
styles
.
iconText
,
styles
.
AndroidText
)}
>
Android
<
/span
>
<
/div
>
<
/Popover
>
<
/div>
,
);
}
break
;
}
});
return
element
;
};
/* eslint-disable */
const
Account
=
props
=>
(
<
LoginForm
onSubmit
=
{
props
.
onSubmit
}
>
...
...
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