Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
X
xiaomai-cloud-class-web
Overview
Overview
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
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
xiaomai-cloud-class
xiaomai-cloud-class-web
Commits
1bad31cd
Commit
1bad31cd
authored
Jun 24, 2021
by
zhangleyuan
Browse files
Options
Browse Files
Download
Plain Diff
feat:解决合并代码后的冲突
parents
58c58cfc
be13851c
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
529 additions
and
489 deletions
+529
-489
src/common/less/icon-font.less
+8
-11
src/index.html
+99
-87
src/modules/root/Header.jsx
+110
-108
src/modules/root/Header.less
+47
-39
src/modules/root/Login.jsx
+163
-142
src/modules/root/Login.less
+27
-33
src/modules/root/WechatLogin.less
+10
-11
src/modules/root/WechatLogin.tsx
+65
-58
No files found.
src/common/less/icon-font.less
View file @
1bad31cd
@font-face {
font-family: 'iconfont'; /* project id 2223403 */
src: url('//at.alicdn.com/t/font_2223403_boiin24pch6.eot');
src: url('//at.alicdn.com/t/font_2223403_boiin24pch6.eot?#iefix') format('embedded-opentype'),
url('//at.alicdn.com/t/font_2223403_boiin24pch6.woff2') format('woff2'),
url('//at.alicdn.com/t/font_2223403_boiin24pch6.woff') format('woff'),
url('//at.alicdn.com/t/font_2223403_boiin24pch6.ttf') format('truetype'),
url('//at.alicdn.com/t/font_2223403_boiin24pch6.svg#iconfont') format('svg');
font-family: 'iconfont'; /* Project id 2223403 */
src: url('//at.alicdn.com/t/font_2223403_oe5p510553.woff2?t=1624259078391') format('woff2'),
url('//at.alicdn.com/t/font_2223403_oe5p510553.woff?t=1624259078391') format('woff'),
url('//at.alicdn.com/t/font_2223403_oe5p510553.ttf?t=1624259078391') format('truetype');
}
.iconfont{
font-family:
"iconfont"
!important;
font-size:16px;
font-style:normal;
.iconfont
{
font-family:
'iconfont'
!important;
font-size:
16px;
font-style:
normal;
}
src/index.html
View file @
1bad31cd
<!--
* @Author: 吴文洁
* @Date: 2020-08-24 12:20:57
* @LastEditors:
wufan
* @LastEditTime: 2021-0
5-27 10:24:06
* @LastEditors:
fusanqiasng
* @LastEditTime: 2021-0
6-21 15:06:27
* @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有
-->
...
...
@@ -13,17 +13,23 @@
<link
rel=
"icon"
href=
""
/>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1"
/>
<meta
name=
"theme-color"
content=
"#000000"
/>
<meta
name=
"description"
content=
"小麦企学院,一站式企业培训数字化服务商,通过“工具+内容”,帮助企业快速从0到1搭建数字化培训体系,并让整个培训过程可视化,降低培训成本,提升培训效率。"
>
<meta
name=
"keywords"
content=
"小麦企学院,企业培训,员工培训,企业大学,企业内训,企业外训,培训计划,培训素材,企培,企训,资料云盘,培训课程,培训任务,直播课,视频课,图文课,线下课,知识库,作业,考试,排行榜,培训类别管理,定制培训计划,管理数据,学习数据,企学院,资料共享,培训数字化,数字化培训,培训工具,在线培训,线上培训,培训saas,培训管理,企业微信培训,对客培训,客户培训,直播培训,互联网培训,新员工培训,管理培训,管理者培训,工人培训,制造业培训,餐饮培训,服务业培训,零售培训,门店培训,工厂培训,车间培训,培训补贴,人事培训,财务培训,职场培训,企业学院平台,教育企业学院,教育企业平台,教育平台学院,企业学习,酷学院,小鹅通,企业学院,云学堂,时代光华,云课堂,魔学院,云大学,米知云,授课学堂"
>
<meta
name=
"description"
content=
"小麦企学院,一站式企业培训数字化服务商,通过“工具+内容”,帮助企业快速从0到1搭建数字化培训体系,并让整个培训过程可视化,降低培训成本,提升培训效率。"
/>
<meta
name=
"keywords"
content=
"小麦企学院,企业培训,员工培训,企业大学,企业内训,企业外训,培训计划,培训素材,企培,企训,资料云盘,培训课程,培训任务,直播课,视频课,图文课,线下课,知识库,作业,考试,排行榜,培训类别管理,定制培训计划,管理数据,学习数据,企学院,资料共享,培训数字化,数字化培训,培训工具,在线培训,线上培训,培训saas,培训管理,企业微信培训,对客培训,客户培训,直播培训,互联网培训,新员工培训,管理培训,管理者培训,工人培训,制造业培训,餐饮培训,服务业培训,零售培训,门店培训,工厂培训,车间培训,培训补贴,人事培训,财务培训,职场培训,企业学院平台,教育企业学院,教育企业平台,教育平台学院,企业学习,酷学院,小鹅通,企业学院,云学堂,时代光华,云课堂,魔学院,云大学,米知云,授课学堂"
/>
<!-- <link rel="apple-touch-icon" href="../src/common/images/logo.png" /> -->
<link
rel=
"shortcut icon"
href=
"https://image.xiaomaiketang.com/xm/c4KiP2epBP.png"
>
<link
rel=
"shortcut icon"
href=
"https://image.xiaomaiketang.com/xm/c4KiP2epBP.png"
/
>
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link
rel=
"manifest"
href=
"%PUBLIC_URL%/manifest.json"
/>
<link
rel=
"stylesheet"
href=
"//at.alicdn.com/t/font_2223403_o
qqm4z9s35j.css"
>
<link
rel=
"stylesheet"
href=
"//at.alicdn.com/t/font_2223403_o
e5p510553.css"
/
>
<!--
Notice the use of %PUBLIC_URL% in the tags above.
...
...
@@ -69,146 +75,152 @@
// Browser globals (root is window)
root
.
download
=
factory
();
}
}(
this
,
function
()
{
})(
this
,
function
()
{
return
function
download
(
data
,
strFileName
,
strMimeType
)
{
var
self
=
window
,
// this script is only for browsers anyway...
defaultMime
=
"application/octet-stream"
,
// this default mime also triggers iframe downloads
defaultMime
=
'application/octet-stream'
,
// this default mime also triggers iframe downloads
mimeType
=
strMimeType
||
defaultMime
,
payload
=
data
,
url
=
!
strFileName
&&
!
strMimeType
&&
payload
,
anchor
=
document
.
createElement
(
"a"
),
toString
=
function
(
a
){
return
String
(
a
);},
myBlob
=
(
self
.
Blob
||
self
.
MozBlob
||
self
.
WebKitBlob
||
toString
),
fileName
=
strFileName
||
"download"
,
anchor
=
document
.
createElement
(
'a'
),
toString
=
function
(
a
)
{
return
String
(
a
);
},
myBlob
=
self
.
Blob
||
self
.
MozBlob
||
self
.
WebKitBlob
||
toString
,
fileName
=
strFileName
||
'download'
,
blob
,
reader
;
myBlob
=
myBlob
.
call
?
myBlob
.
bind
(
self
)
:
Blob
;
myBlob
=
myBlob
.
call
?
myBlob
.
bind
(
self
)
:
Blob
;
if
(
String
(
this
)
===
"true"
){
//reverse arguments, allowing download.bind(true, "text/xml", "export.xml") to act as a callback
payload
=
[
payload
,
mimeType
];
mimeType
=
payload
[
0
];
payload
=
payload
[
1
];
if
(
String
(
this
)
===
'true'
)
{
//reverse arguments, allowing download.bind(true, "text/xml", "export.xml") to act as a callback
payload
=
[
payload
,
mimeType
];
mimeType
=
payload
[
0
];
payload
=
payload
[
1
];
}
if
(
url
&&
url
.
length
<
2048
){
// if no filename and no mime, assume a url was passed as the only argument
fileName
=
url
.
split
(
"/"
).
pop
().
split
(
"?"
)[
0
];
if
(
url
&&
url
.
length
<
2048
)
{
// if no filename and no mime, assume a url was passed as the only argument
fileName
=
url
.
split
(
'/'
).
pop
().
split
(
'?'
)[
0
];
anchor
.
href
=
url
;
// assign href prop to temp anchor
if
(
anchor
.
href
.
indexOf
(
url
)
!==
-
1
){
// if the browser determines that it's a potentially valid url path:
var
ajax
=
new
XMLHttpRequest
();
ajax
.
open
(
"GET"
,
url
,
true
);
if
(
anchor
.
href
.
indexOf
(
url
)
!==
-
1
)
{
// if the browser determines that it's a potentially valid url path:
var
ajax
=
new
XMLHttpRequest
();
ajax
.
open
(
'GET'
,
url
,
true
);
ajax
.
responseType
=
'blob'
;
ajax
.
onload
=
function
(
e
){
ajax
.
onload
=
function
(
e
)
{
download
(
e
.
target
.
response
,
fileName
,
defaultMime
);
};
setTimeout
(
function
(){
ajax
.
send
();},
0
);
// allows setting custom ajax headers using the return:
setTimeout
(
function
()
{
ajax
.
send
();
},
0
);
// allows setting custom ajax headers using the return:
return
ajax
;
}
// end if valid url?
}
// end if url?
//go ahead and download dataURLs right away
if
(
/^data
\:[\w
+
\-]
+
\/[\w
+
\-]
+
[
,;
]
/
.
test
(
payload
)){
if
(
payload
.
length
>
(
1024
*
1024
*
1.999
)
&&
myBlob
!==
toString
){
payload
=
dataUrlToBlob
(
payload
);
mimeType
=
payload
.
type
||
defaultMime
;
}
else
{
return
navigator
.
msSaveBlob
?
// IE10 can't do a[download], only Blobs:
navigator
.
msSaveBlob
(
dataUrlToBlob
(
payload
),
fileName
)
:
saver
(
payload
)
;
// everyone else can save dataURLs un-processed
if
(
/^data
\:[\w
+
\-]
+
\/[\w
+
\-]
+
[
,;
]
/
.
test
(
payload
))
{
if
(
payload
.
length
>
1024
*
1024
*
1.999
&&
myBlob
!==
toString
)
{
payload
=
dataUrlToBlob
(
payload
);
mimeType
=
payload
.
type
||
defaultMime
;
}
else
{
return
navigator
.
msSaveBlob
// IE10 can't do a[download], only Blobs:
?
navigator
.
msSaveBlob
(
dataUrlToBlob
(
payload
),
fileName
)
:
saver
(
payload
);
// everyone else can save dataURLs un-processed
}
}
//end if dataURL passed?
}
//end if dataURL passed?
blob
=
payload
instanceof
myBlob
?
payload
:
new
myBlob
([
payload
],
{
type
:
mimeType
})
;
blob
=
payload
instanceof
myBlob
?
payload
:
new
myBlob
([
payload
],
{
type
:
mimeType
});
function
dataUrlToBlob
(
strUrl
)
{
var
parts
=
strUrl
.
split
(
/
[
:;,
]
/
),
type
=
parts
[
1
],
decoder
=
parts
[
2
]
==
"base64"
?
atob
:
decodeURIComponent
,
binData
=
decoder
(
parts
.
pop
()
),
mx
=
binData
.
length
,
i
=
0
,
uiArr
=
new
Uint8Array
(
mx
);
var
parts
=
strUrl
.
split
(
/
[
:;,
]
/
),
type
=
parts
[
1
],
decoder
=
parts
[
2
]
==
'base64'
?
atob
:
decodeURIComponent
,
binData
=
decoder
(
parts
.
pop
()
),
mx
=
binData
.
length
,
i
=
0
,
uiArr
=
new
Uint8Array
(
mx
);
for
(
i
;
i
<
mx
;
++
i
)
uiArr
[
i
]
=
binData
.
charCodeAt
(
i
);
for
(
i
;
i
<
mx
;
++
i
)
uiArr
[
i
]
=
binData
.
charCodeAt
(
i
);
return
new
myBlob
([
uiArr
],
{
type
:
type
});
return
new
myBlob
([
uiArr
],
{
type
:
type
});
}
function
saver
(
url
,
winMode
){
if
(
'download'
in
anchor
)
{
//html5 A[download]
function
saver
(
url
,
winMode
)
{
if
(
'download'
in
anchor
)
{
//html5 A[download]
anchor
.
href
=
url
;
anchor
.
setAttribute
(
"download"
,
fileName
);
anchor
.
className
=
"download-js-link"
;
anchor
.
innerHTML
=
"downloading..."
;
anchor
.
style
.
display
=
"none"
;
anchor
.
setAttribute
(
'download'
,
fileName
);
anchor
.
className
=
'download-js-link'
;
anchor
.
innerHTML
=
'downloading...'
;
anchor
.
style
.
display
=
'none'
;
document
.
body
.
appendChild
(
anchor
);
setTimeout
(
function
()
{
setTimeout
(
function
()
{
anchor
.
click
();
document
.
body
.
removeChild
(
anchor
);
if
(
winMode
===
true
){
setTimeout
(
function
(){
self
.
URL
.
revokeObjectURL
(
anchor
.
href
);},
250
);}
if
(
winMode
===
true
)
{
setTimeout
(
function
()
{
self
.
URL
.
revokeObjectURL
(
anchor
.
href
);
},
250
);
}
},
66
);
return
true
;
}
// handle non-a[download] safari as best we can:
if
(
/
(
Version
)\/(\d
+
)\.(\d
+
)(?:\.(\d
+
))?
.*Safari
\/
/
.
test
(
navigator
.
userAgent
))
{
url
=
url
.
replace
(
/^data:
([\w\/\-\+]
+
)
/
,
defaultMime
);
if
(
!
window
.
open
(
url
)){
// popup blocked, offer direct download:
if
(
confirm
(
"Displaying New Document
\
n
\
nUse Save As... to download, then click back to return to this page."
)){
location
.
href
=
url
;
}
if
(
/
(
Version
)\/(\d
+
)\.(\d
+
)(?:\.(\d
+
))?
.*Safari
\/
/
.
test
(
navigator
.
userAgent
))
{
url
=
url
.
replace
(
/^data:
([\w\/\-\+]
+
)
/
,
defaultMime
);
if
(
!
window
.
open
(
url
))
{
// popup blocked, offer direct download:
if
(
confirm
(
'Displaying New Document
\
n
\
nUse Save As... to download, then click back to return to this page.'
))
{
location
.
href
=
url
;
}
}
return
true
;
}
//do iframe dataURL download (old ch+FF):
var
f
=
document
.
createElement
(
"iframe"
);
var
f
=
document
.
createElement
(
'iframe'
);
document
.
body
.
appendChild
(
f
);
if
(
!
winMode
){
// force a mime that will download:
url
=
"data:"
+
url
.
replace
(
/^data:
([\w\/\-\+]
+
)
/
,
defaultMime
);
if
(
!
winMode
)
{
// force a mime that will download:
url
=
'data:'
+
url
.
replace
(
/^data:
([\w\/\-\+]
+
)
/
,
defaultMime
);
}
f
.
src
=
url
;
setTimeout
(
function
(){
document
.
body
.
removeChild
(
f
);
},
333
);
}
//end saver
if
(
navigator
.
msSaveBlob
)
{
// IE10+ : (has Blob, but not a[download] or URL)
f
.
src
=
url
;
setTimeout
(
function
()
{
document
.
body
.
removeChild
(
f
);
},
333
);
}
//end saver
if
(
navigator
.
msSaveBlob
)
{
// IE10+ : (has Blob, but not a[download] or URL)
return
navigator
.
msSaveBlob
(
blob
,
fileName
);
}
if
(
self
.
URL
){
// simple fast and modern way using Blob and URL:
if
(
self
.
URL
)
{
// simple fast and modern way using Blob and URL:
saver
(
self
.
URL
.
createObjectURL
(
blob
),
true
);
}
else
{
}
else
{
// handle non-Blob()+non-URL browsers:
if
(
typeof
blob
===
"string"
||
blob
.
constructor
===
toString
)
{
try
{
return
saver
(
"data:"
+
mimeType
+
";base64,"
+
self
.
btoa
(
blob
)
);
}
catch
(
y
)
{
return
saver
(
"data:"
+
mimeType
+
","
+
encodeURIComponent
(
blob
)
);
if
(
typeof
blob
===
'string'
||
blob
.
constructor
===
toString
)
{
try
{
return
saver
(
'data:'
+
mimeType
+
';base64,'
+
self
.
btoa
(
blob
)
);
}
catch
(
y
)
{
return
saver
(
'data:'
+
mimeType
+
','
+
encodeURIComponent
(
blob
)
);
}
}
// Blob but not URL support:
reader
=
new
FileReader
();
reader
.
onload
=
function
(
e
)
{
reader
=
new
FileReader
();
reader
.
onload
=
function
(
e
)
{
saver
(
this
.
result
);
};
reader
.
readAsDataURL
(
blob
);
}
return
true
;
};
/* end download() */
})
)
})
;
</script>
</body>
</html>
src/modules/root/Header.jsx
View file @
1bad31cd
...
...
@@ -2,33 +2,33 @@
* @Author: 吴文洁
* @Date: 2019-09-10 18:26:03
* @LastEditors: Please set LastEditors
* @LastEditTime: 2021-06-2
3 16:11:49
* @LastEditTime: 2021-06-2
4 19:28:14
* @Description:
*/
import
React
,
{
useRef
,
useContext
,
useEffect
,
useState
}
from
"react"
;
import
"./Header.less"
;
import
{
Radio
,
Button
,
Dropdown
,
Modal
,
Tooltip
,
message
}
from
"antd"
;
import
{
LIVE_SHARE
}
from
"@/domains/course-domain/constants"
;
import
User
from
"@/common/js/user"
;
import
Service
from
"@/common/js/service"
;
import
StoreService
from
"@/domains/store-domain/storeService"
;
import
BaseService
from
"@/domains/basic-domain/baseService"
;
import
{
XMContext
}
from
"@/store/context"
;
import
logoImg
from
"@/common/images/logo.png"
;
import
CourseService
from
"@/domains/course-domain/CourseService"
;
import
qrcode
from
"@/libs/qrcode/qrcode.js"
;
import
React
,
{
useRef
,
useContext
,
useEffect
,
useState
}
from
'react'
;
import
'./Header.less'
;
import
{
Radio
,
Button
,
Dropdown
,
Modal
,
Tooltip
,
message
}
from
'antd'
;
import
{
LIVE_SHARE
}
from
'@/domains/course-domain/constants'
;
import
User
from
'@/common/js/user'
;
import
Service
from
'@/common/js/service'
;
import
StoreService
from
'@/domains/store-domain/storeService'
;
import
BaseService
from
'@/domains/basic-domain/baseService'
;
import
{
XMContext
}
from
'@/store/context'
;
import
logoImg
from
'@/common/images/logo.png'
;
import
CourseService
from
'@/domains/course-domain/CourseService'
;
import
qrcode
from
'@/libs/qrcode/qrcode.js'
;
import
Bus
from
'@/core/tbus'
;
import
ClickOutside
from
'../../components/ClickOutside'
;
import
_
from
"underscore"
;
import
_
from
'underscore'
;
const
baseImg
=
"https://image.xiaomaiketang.com/xm/rJeQaZxtc7.png"
;
const
baseImg
=
'https://image.xiaomaiketang.com/xm/rJeQaZxtc7.png'
;
const
{
confirm
}
=
Modal
;
const
RadioGroup
=
Radio
.
Group
;
function
Header
(
props
)
{
const
{
menuType
,
handleMenuType
}
=
props
;
const
[
storeId
,
setStoreId
]
=
useState
(
User
.
getStoreId
());
const
[
storeName
,
setStoreName
]
=
useState
(
User
.
getStoreName
())
const
[
storeName
,
setStoreName
]
=
useState
(
User
.
getStoreName
())
;
const
[
avatar
,
setAvatar
]
=
useState
(
''
);
const
[
nickName
,
setNickName
]
=
useState
(
''
);
const
[
phone
,
setPhone
]
=
useState
(
''
);
...
...
@@ -37,10 +37,11 @@ function Header(props) {
const
[
instScroll
,
setInstScroll
]
=
useState
(
false
);
const
ctx
=
useContext
(
XMContext
);
const
htmlUrl
=
`
${
LIVE_SHARE
}
store/index?id=
${
User
.
getStoreId
()}
&userId=
${
User
.
getUserId
()}
&from=work_weixin`
;
const
helpCenterUrl
=
'https://www.yuque.com/wangzhong-zkqw0/qixue'
;
// 帮助中心
const
storeUserId
=
User
.
getStoreUserId
();
const
enterpriseId
=
User
.
getEnterpriseId
();
const
messageHelpRef
=
useRef
(
null
)
const
messageHelpRef
=
useRef
(
null
)
;
const
domRef
=
useRef
(
null
);
const
listRef
=
useRef
(
list
);
...
...
@@ -58,16 +59,16 @@ function Header(props) {
enterpriseId
?
getEnterpriseUser
()
:
User
.
setIsAdmin
(
false
);
},
[
storeUserId
]);
useEffect
(()
=>
{
useEffect
(()
=>
{
if
(
!
messageHelpRef
.
current
)
{
return
return
;
}
if
(
menuType
)
{
messageHelpRef
.
current
.
style
.
marginLeft
=
"194px"
messageHelpRef
.
current
.
style
.
marginLeft
=
'194px'
;
}
else
{
messageHelpRef
.
current
.
style
.
marginLeft
=
"76px"
messageHelpRef
.
current
.
style
.
marginLeft
=
'76px'
;
}
},
[
menuType
])
},
[
menuType
]);
function
getUserInfo
()
{
const
param
=
{
...
...
@@ -85,7 +86,7 @@ function Header(props) {
const
params
=
{
enterpriseId
,
userId
:
User
.
getUserId
(),
}
}
;
BaseService
.
getEnterpriseUser
(
params
).
then
((
res
)
=>
{
const
{
isAdmin
}
=
res
.
result
;
User
.
setIsAdmin
(
isAdmin
);
...
...
@@ -99,7 +100,7 @@ function Header(props) {
userId
:
User
.
getUserId
(),
};
Service
.
Hades
(
'public/customerHades/getStoreListUser'
,
params
).
then
((
res
)
=>
{
const
newList
=
_
.
filter
(
res
.
result
,
item
=>
item
.
state
===
'VALID'
);
const
newList
=
_
.
filter
(
res
.
result
,
(
item
)
=>
item
.
state
===
'VALID'
);
setList
(
newList
);
listRef
.
current
=
newList
;
});
...
...
@@ -124,48 +125,47 @@ function Header(props) {
}
else
{
setInstScroll
(
true
);
}
}
;
}
function
userMenu
()
{
return
(
<
div
className=
"user-center-dropdown"
>
<
div
className=
"user-detail"
>
<
div
className=
"box"
>
<
div
className=
'user-center-dropdown'
>
<
div
className=
'user-detail'
>
<
div
className=
'box'
>
<
Tooltip
title=
{
nickName
}
>
<
div
className=
"name"
>
{
nickName
}
</
div
>
<
div
className=
'name'
>
{
nickName
}
</
div
>
</
Tooltip
>
<
span
className=
"phone"
>
{
phone
}
</
span
>
<
span
className=
'phone'
>
{
phone
}
</
span
>
</
div
>
<
span
className=
"setting"
onClick=
{
()
=>
toPersonalInfoPage
()
}
>
个人设置
<
span
className=
"iconfont icon"
>

</
span
>
<
span
className=
'setting'
onClick=
{
()
=>
toPersonalInfoPage
()
}
>
个人设置
<
span
className=
'iconfont icon'
>

</
span
>
</
span
>
</
div
>
<
div
className=
"menu"
>
{
User
.
getEnterpriseId
()
&&
<
div
className=
'menu'
>
{
User
.
getEnterpriseId
()
&&
(
<
div
className=
"menu-item"
key=
"1"
className=
'menu-item'
key=
'1'
onClick=
{
()
=>
{
window
.
RCHistory
.
push
({
pathname
:
'/college-manage'
,
});
}
}
>
<
span
className=
"menu-before iconfont icon"
>

</
span
>
}
}
>
<
span
className=
'menu-before iconfont icon'
>

</
span
>
<
span
>
进入管理后台
</
span
>
<
span
className=
"menu-after iconfont icon"
>

</
span
>
<
span
className=
'menu-after iconfont icon'
>

</
span
>
</
div
>
}
)
}
<
div
className=
"menu-item"
key=
"2"
className=
'menu-item'
key=
'2'
onClick=
{
(
e
)
=>
{
handleLogoutConfirm
();
}
}
>
<
span
className=
"menu-before iconfont icon"
>

</
span
>
}
}
>
<
span
className=
'menu-before iconfont icon'
>

</
span
>
<
span
>
退出登录
</
span
>
<
span
className=
"menu-after iconfont icon"
>

</
span
>
<
span
className=
'menu-after iconfont icon'
>

</
span
>
</
div
>
</
div
>
</
div
>
...
...
@@ -184,13 +184,11 @@ function Header(props) {
function
handleLogoutConfirm
()
{
return
confirm
({
title
:
"你确定要退出登录吗?"
,
content
:
"退出后,需重新登录"
,
icon
:
(
<
span
className=
"icon iconfont default-confirm-icon"
>

</
span
>
),
okText
:
"退出登录"
,
cancelText
:
"点错了"
,
title
:
'你确定要退出登录吗?'
,
content
:
'退出后,需重新登录'
,
icon
:
<
span
className=
'icon iconfont default-confirm-icon'
>

</
span
>,
okText
:
'退出登录'
,
cancelText
:
'点错了'
,
onOk
:
()
=>
{
handleLogout
();
},
...
...
@@ -198,14 +196,13 @@ function Header(props) {
}
function
handleLogout
()
{
BaseService
.
logout
({
identifier
:
User
.
getIdentifier
()
}).
then
((
res
)
=>
{
BaseService
.
logout
({
identifier
:
User
.
getIdentifier
()
}).
then
((
res
)
=>
{
User
.
removeUserId
();
User
.
removeToken
();
User
.
removeEnterpriseId
();
User
.
clearUserInfo
();
const
url
=
`
${
LIVE_SHARE
}
store/index?id=
${
User
.
getCustomerStoreId
()
||
User
.
getStoreId
()}
&userId=
${
User
.
getUserId
()}
&from=work_weixin`
;
const
url
=
`
${
LIVE_SHARE
}
store/index?id=
${
User
.
getCustomerStoreId
()
||
User
.
getStoreId
()}
&userId=
${
User
.
getUserId
()}
&from=work_weixin`
;
window
.
location
.
href
=
url
;
});
}
...
...
@@ -214,7 +211,7 @@ function Header(props) {
urls
:
[
htmlUrl
],
}).
then
((
res
)
=>
{
const
{
result
=
[]
}
=
res
;
const
qrcodeWrapDom
=
document
.
querySelector
(
"#h5-qrcode"
);
const
qrcodeWrapDom
=
document
.
querySelector
(
'#h5-qrcode'
);
const
qrcodeNode
=
new
qrcode
({
text
:
result
[
0
].
shortUrl
,
size
:
110
,
...
...
@@ -231,12 +228,12 @@ function Header(props) {
}
return
(
<
div
id=
"top-container"
className=
"top-container"
>
<
div
className=
"top top-nav"
>
<
div
id=
'top-container'
className=
'top-container'
>
<
div
className=
'top top-nav'
>
{
/* <div>
<img src={topLeftLogo} className="logo" alt="" />
</div> */
}
<
div
className=
"message-help"
ref=
{
messageHelpRef
}
>
<
div
className=
'message-help'
ref=
{
messageHelpRef
}
>
{
list
.
length
?
(
<
ClickOutside
onClickOutside=
{
()
=>
{
...
...
@@ -244,32 +241,35 @@ function Header(props) {
setOpenDropdown
(
false
);
}
}
}
className=
"college-container"
>
className=
'college-container'
>
<
div
style=
{
{
width
:
'100%'
,
height
:
'100%'
}
}
>
<
div
className=
"college"
onClick=
{
()
=>
setOpenDropdown
(
false
)
}
>
<
div
className=
'college'
onClick=
{
()
=>
setOpenDropdown
(
false
)
}
>
<
span
className=
"college-name"
className=
'college-name'
onClick=
{
(
e
)
=>
{
e
.
stopPropagation
();
setOpenDropdown
(
!
openDropdown
);
addShadow
();
}
}
>
{
storeName
}
</
span
>
{
list
.
length
>
1
&&
<
span
}
}
>
{
storeName
}
</
span
>
{
list
.
length
>
1
&&
(
<
span
className=
{
`icon iconfont ${list.length > 1 ? 'select' : ''}`
}
onClick=
{
(
e
)
=>
{
e
.
stopPropagation
();
setOpenDropdown
(
!
openDropdown
);
addShadow
();
}
}
>

</
span
>
}
}
}
>

</
span
>
)
}
</
div
>
<
div
className=
{
`select-college ${openDropdown ? 'active' : ''}`
}
>
<
h2
>
切换学院
</
h2
>
<
RadioGroup
onChange=
{
(
e
)
=>
{
setStoreId
(
e
.
target
.
value
)
setStoreId
(
e
.
target
.
value
)
;
User
.
setStoreId
(
e
.
target
.
value
);
list
.
map
((
item
)
=>
{
if
(
item
.
id
===
e
.
target
.
value
){
...
...
@@ -283,15 +283,14 @@ function Header(props) {
window
.
location
.
reload
();
}
}
value=
{
storeId
}
id=
"college-radio-group"
>
id=
'college-radio-group'
>
{
_
.
map
(
list
,
(
item
)
=>
(
<
Radio
value=
{
item
.
id
}
key=
{
item
.
id
}
>
<
span
className=
"name"
>
{
item
.
storeName
}
</
span
>
<
span
className=
'name'
>
{
item
.
storeName
}
</
span
>
</
Radio
>
))
}
</
RadioGroup
>
{
instScroll
&&
<
div
className=
"scroll-shadow"
></
div
>
}
{
instScroll
&&
<
div
className=
'scroll-shadow'
></
div
>
}
{
/* <div className="control">
<Button
size="small"
...
...
@@ -316,61 +315,64 @@ function Header(props) {
</
div
>
</
ClickOutside
>
)
:
(
<
div
className=
"store-related"
>
<
div
className=
"store-name"
>
{
storeName
}
</
div
>
<
div
className=
'store-related'
>
<
div
className=
'store-name'
>
{
storeName
}
</
div
>
</
div
>
)
}
<
div
className=
"right-box"
>
<
div
className=
"right-bg-img"
>
<
img
src=
"https://image.xiaomaiketang.com/xm/WCwjyyXYda.png"
></
img
>
<
div
className=
'right-box'
>
<
div
className=
'right-bg-img'
>
<
img
src=
'https://image.xiaomaiketang.com/xm/WCwjyyXYda.png'
></
img
>
</
div
>
<
div
className=
"link-to-store"
>
<
div
className=
"link"
>
<
span
className=
"link-btn"
>
<
span
className=
"icon iconfont tool-tip-right"
>

</
span
>
<
span
className=
"text"
>
前往学院
</
span
>
<
div
className=
'link-to-store'
>
<
div
className=
'link'
>
<
span
className=
'link-btn'
>
<
span
className=
'icon iconfont tool-tip-right'
>

</
span
>
<
span
className=
'text'
>
前往学院
</
span
>
</
span
>
<
div
className=
"store-popover"
>
<
div
className=
"pc-url"
>
<
div
className=
"name"
>
网页端学院
</
div
>
<
div
className=
'store-popover'
>
<
div
className=
'pc-url'
>
<
div
className=
'name'
>
网页端学院
</
div
>
<
div
className=
"url-link"
className=
'url-link'
onClick=
{
()
=>
{
window
.
open
(
htmlUrl
);
}
}
>
{
"立即前往 >"
}
}
}
>
{
'立即前往 >'
}
</
div
>
</
div
>
<
div
className=
"h5-url"
>
<
div
className=
"name"
>
手机端学院
</
div
>
<
div
id=
"h5-qrcode"
></
div
>
<
div
className=
"tip"
>
微信扫码,打开学院
</
div
>
<
div
className=
'h5-url'
>
<
div
className=
'name'
>
手机端学院
</
div
>
<
div
id=
'h5-qrcode'
></
div
>
<
div
className=
'tip'
>
微信扫码,打开学院
</
div
>
</
div
>
</
div
>
</
div
>
<
div
className=
"share"
onClick=
{
handleCopy
}
>
<
span
className=
"share-btn"
>
<
span
className=
"icon iconfont tool-tip-right"
>

</
span
>
<
span
className=
"text"
>
分享学院
</
span
>
<
div
className=
'share'
onClick=
{
handleCopy
}
>
<
span
className=
'share-btn'
>
<
span
className=
'icon iconfont tool-tip-right'
>

</
span
>
<
span
className=
'text'
>
分享学院
</
span
>
</
span
>
</
div
>
<
div
className=
'help'
>
<
a
href=
{
helpCenterUrl
}
target=
'_blank'
className=
'help-btn'
>
<
span
className=
'icon iconfont tool-tip-right'
>

</
span
>
<
span
className=
'text'
>
帮助中心
</
span
>
</
a
>
</
div
>
</
div
>
<
Dropdown
overlay=
{
userMenu
()
}
arrow
>
<
div
className=
"user"
>
<
div
className=
'user'
>
<
img
style=
{
{
width
:
32
+
"px"
,
height
:
32
+
"px"
,
borderRadius
:
"50%"
,
overflow
:
"hidden"
,
width
:
32
+
'px'
,
height
:
32
+
'px'
,
borderRadius
:
'50%'
,
overflow
:
'hidden'
,
flexShrink
:
0
,
}
}
src=
{
avatar
||
baseImg
}
/>
<
span
className=
"name"
>
{
nickName
}
</
span
>
<
span
className=
'name'
>
{
nickName
}
</
span
>
</
div
>
</
Dropdown
>
</
div
>
...
...
src/modules/root/Header.less
View file @
1bad31cd
@import
"../../core/variables.less"
;
@import
'../../core/variables.less'
;
@top-height: 60px;
@icon-color: #939393;
.top-container {
...
...
@@ -7,16 +7,23 @@
left: 0;
right: 0;
height: @top-height;
background-color: #2966
FF
;
background-color: #2966
ff
;
// z-index:2;
&::after{
content:'';
width:100%;
height:60px;
background: linear-gradient(180deg, #2966FF 0%, rgba(41, 102, 255, 0.82) 29%, rgba(41, 102, 255, 0.58) 55%, rgba(41, 102, 255, 0.27) 77%, rgba(7, 78, 255, 0) 100%);
position:absolute;
z-index:2;
top:59px;
&::after {
content: '';
width: 100%;
height: 60px;
background: linear-gradient(
180deg,
#2966ff 0%,
rgba(41, 102, 255, 0.82) 29%,
rgba(41, 102, 255, 0.58) 55%,
rgba(41, 102, 255, 0.27) 77%,
rgba(7, 78, 255, 0) 100%
);
position: absolute;
z-index: 2;
top: 59px;
}
.logo {
display: inline-block;
...
...
@@ -26,7 +33,7 @@
.logo-name {
font-size: 14px;
font-weight: 500;
color: #2966
FF
;
color: #2966
ff
;
line-height: 20px;
vertical-align: middle;
font-weight: bold;
...
...
@@ -204,7 +211,7 @@
cursor: pointer;
}
.college-name {
color:
#FFFFFF
;
color:
#ffffff
;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
...
...
@@ -213,9 +220,9 @@
.icon {
font-size: 14px;
margin-left: 8px;
color: #
FFF
;
color: #
fff
;
&:hover {
color:
#FFF
;
color:
#fff
;
}
}
}
...
...
@@ -283,7 +290,7 @@
align-items: center;
.store-name {
font-size: 14px;
color: #
FFF
;
color: #
fff
;
line-height: 49px;
margin-left: 8px;
white-space: nowrap;
...
...
@@ -296,17 +303,17 @@
width: 1px;
height: 16px;
background-color: #f4f4f4;
margin-right:16px;
margin-right:
16px;
}
}
.right-box {
display: flex;
align-items: center;
}
.right-bg-img{
img{
width:277px;
height:60px;
.right-bg-img
{
img
{
width:
277px;
height:
60px;
}
}
.link-to-store {
...
...
@@ -315,31 +322,27 @@
line-height: 49px;
.text {
font-size: 14px;
color: #
FFF
;
color: #
fff
;
line-height: 49px;
margin-left: 7px;
}
.iconfont {
color: #
FFF
;
color: #
fff
;
}
.link {
cursor: pointer;
position: relative;
.link-btn{
padding:3px 12px;
.link-btn
{
padding:
3px 12px;
border: 1px solid rgba(255, 255, 255, 0.5);
border-radius: 4px;
&:hover{
&:hover
{
border: 1px solid rgba(255, 255, 255, 1);
}
}
.store-popover {
display: none;
}
&:hover {
.store-popover {
position: absolute;
display: flex
;
display: none
;
width: 216px;
height: 260px;
top: 49px;
...
...
@@ -362,7 +365,7 @@
line-height: 20px;
}
.url-link {
color: #2966FF
;
color: #2966ff
;
font-size: 14px;
line-height: 20px;
}
...
...
@@ -386,19 +389,24 @@
line-height: 41px;
width: 130px;
}
}
}
&:hover {
.store-popover {
display: flex;
}
}
}
.share {
.share,
.help {
cursor: pointer;
margin-left: 16px;
.share-btn{
padding:3px 12px;
.share-btn,
.help-btn {
padding: 3px 12px;
border: 1px solid rgba(255, 255, 255, 0.5);
border-radius: 4px;
&:hover{
&:hover
{
border: 1px solid rgba(255, 255, 255, 1);
}
}
...
...
@@ -529,7 +537,7 @@
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color:
#FFF
;
color:
#fff
;
}
}
}
...
...
@@ -588,7 +596,7 @@
.user-detail {
position: relative;
padding-bottom: 16px;
border-bottom: 1px solid #
E8E8E
8;
border-bottom: 1px solid #
e8e8e
8;
display: flex;
align-items: center;
justify-content: space-between;
...
...
@@ -625,7 +633,7 @@
cursor: pointer;
color: #333;
.menu-before {
color: #
BFBFBF
;
color: #
bfbfbf
;
margin-right: 8px;
font-size: 14px;
}
...
...
src/modules/root/Login.jsx
View file @
1bad31cd
import
React
,
{
useEffect
,
useState
}
from
'react'
import
{
withRouter
}
from
'react-router-dom'
import
'./Login.less'
import
{
Input
,
Popover
,
message
,
Tabs
,
Button
}
from
'antd'
import
CheckBeforeSendCode
from
'../../components/CheckBeforeSendCode'
import
User
from
'@/common/js/user'
import
WechatLogin
from
'./WechatLogin'
import
BaseService
from
'@/domains/basic-domain/baseService'
import
axios
from
'axios'
import
_
from
'underscore'
import
user
from
'@/common/js/user'
const
{
TabPane
}
=
Tabs
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
{
withRouter
}
from
'react-router-dom'
;
import
'./Login.less'
;
import
{
Input
,
Popover
,
message
,
Tabs
,
Button
}
from
'antd'
;
import
CheckBeforeSendCode
from
'../../components/CheckBeforeSendCode'
;
import
User
from
'@/common/js/user'
;
import
WechatLogin
from
'./WechatLogin'
;
import
BaseService
from
'@/domains/basic-domain/baseService'
;
import
axios
from
'axios'
;
import
_
from
'underscore'
;
import
user
from
'@/common/js/user'
;
const
{
TabPane
}
=
Tabs
;
function
Login
(
props
)
{
const
[
phone
,
setPhone
]
=
useState
(
''
)
// 登录手机号
const
[
phoneverify
,
setPhoneverify
]
=
useState
(
''
)
// 密码登录验证码
const
[
openCheck1
,
setOpenCheck1
]
=
useState
(
false
)
const
[
checking1
,
setChecking1
]
=
useState
(
false
)
const
[
codeText
,
setCodeText
]
=
useState
(
'获取验证码'
)
// 验证码提示语
const
[
waitStatus
,
setWaitStatus
]
=
useState
(
false
)
// 验证码是否在倒计时
const
[
errorMessage
,
setErrorMessage
]
=
useState
(
''
)
const
[
phoneError
,
setPhoneError
]
=
useState
(
false
)
const
[
checkObject1
,
setCheckObject1
]
=
useState
({})
/**
* 手机登陆入口,暂时隐藏,此页注释代码勿删
*/
// const [phone, setPhone] = useState(''); // 登录手机号
// const [phoneverify, setPhoneverify] = useState(''); // 密码登录验证码
// const [openCheck1, setOpenCheck1] = useState(false);
// const [checking1, setChecking1] = useState(false);
// const [codeText, setCodeText] = useState('获取验证码'); // 验证码提示语
// const [waitStatus, setWaitStatus] = useState(false); // 验证码是否在倒计时
// const [errorMessage, setErrorMessage] = useState('');
// const [phoneError, setPhoneError] = useState(false);
// const [checkObject1, setCheckObject1] = useState({});
/**
* 手机登陆入口,暂时隐藏,此页注释代码勿删
*/
useEffect
(()
=>
{
const
enterpriseId
=
getParameterByName
(
'enterpriseId'
)
const
userId
=
getParameterByName
(
'userId'
)
const
from
=
getParameterByName
(
'from'
)
const
storeId
=
getParameterByName
(
'storeId'
)
const
enterpriseId
=
getParameterByName
(
'enterpriseId'
)
;
const
userId
=
getParameterByName
(
'userId'
)
;
const
from
=
getParameterByName
(
'from'
)
;
const
storeId
=
getParameterByName
(
'storeId'
)
;
if
(
storeId
)
{
User
.
setCustomerStoreId
(
storeId
)
User
.
setCustomerStoreId
(
storeId
)
;
}
if
(
from
===
'customer'
&&
enterpriseId
&&
userId
)
{
if
(
!
user
.
getToken
()
||
enterpriseId
!==
user
.
getEnterpriseId
()
||
userId
!==
User
.
getUserId
())
{
getWXWorkLoginNoCheck
(
enterpriseId
,
userId
)
getWXWorkLoginNoCheck
(
enterpriseId
,
userId
)
;
}
else
{
window
.
RCHistory
.
push
({
pathname
:
`/switch-route`
})
pathname
:
`/switch-route`
,
})
;
}
}
else
{
User
.
removeUserId
()
User
.
removeToken
()
User
.
removeEnterpriseId
()
User
.
removeUserId
()
;
User
.
removeToken
()
;
User
.
removeEnterpriseId
()
;
}
},
[])
},
[])
;
function
getWXWorkLoginNoCheck
(
enterpriseId
,
userId
)
{
const
params
=
{
appTermEnum
:
'XIAOMAI_CLOUD_CLASS_PC_WEB_ADMIN'
,
enterpriseId
,
userId
}
userId
,
}
;
BaseService
.
getWXWorkLoginNoCheck
(
params
).
then
((
res
)
=>
{
User
.
setUserId
(
res
.
result
.
loginInfo
.
userId
)
User
.
setToken
(
res
.
result
.
loginInfo
.
xmToken
)
...
...
@@ -60,117 +68,129 @@ function Login(props) {
window
.
currentStoreUserInfo
.
enterpriseId
=
res
.
result
.
enterpriseId
;
User
.
setIdentifier
(
res
.
result
.
identifier
)
window
.
RCHistory
.
push
({
pathname
:
`/switch-route`
})
})
}
async
function
checkAccount
(
code
,
callback
=
()
=>
{})
{
callback
()
}
function
checkSend
(
code
)
{
if
(
!
phone
)
{
setPhoneError
(
true
)
setErrorMessage
(
'请输入手机号'
)
return
}
if
(
phone
.
length
!=
11
)
{
setPhoneError
(
true
)
setErrorMessage
(
'请输入11位手机号'
)
return
}
!
_
.
isEmpty
(
checkObject1
)
&&
checkObject1
.
reset
()
setOpenCheck1
(
true
)
}
function
handleSendSMSCode
(
checkData
,
userType
)
{
if
(
waitStatus
)
return
let
timer
const
params
=
{
phone
:
phone
,
sig
:
checkData
.
sig
,
sessionId
:
checkData
.
csessionid
,
token
:
checkData
.
token
,
scene
:
'nc_login'
,
serverType
:
'CLOUD_CLASS_LOGIN'
,
appTermEnum
:
'XIAOMAI_CLOUD_CLASS_PC_WEB_ADMIN'
}
BaseService
.
sendLoginAuthCode
(
params
).
then
((
res
)
=>
{
if
(
!
res
.
success
)
{
setErrorMessage
(
res
.
message
)
}
else
{
timeSub
(
60
)
setChecking1
(
true
)
}
})
function
timeSub
(
waitTime
,
unit
)
{
clearTimeout
(
timer
)
timer
=
setTimeout
(
function
()
{
if
(
waitTime
===
0
)
{
setCodeText
(
'发送验证码'
)
setChecking1
(
false
)
setWaitStatus
(
false
)
clearTimeout
(
timer
)
}
else
{
setCodeText
(
`
${
waitTime
}
秒后重发`
)
setWaitStatus
(
true
)
timeSub
(
--
waitTime
,
1000
)
}
},
unit
||
0
)
}
pathname
:
`/switch-route`
,
});
});
}
function
handleSubmit
()
{
if
(
!
phone
)
{
setPhoneError
(
true
)
setErrorMessage
(
'请输入手机号'
)
return
}
if
(
phone
.
length
!=
11
)
{
setPhoneError
(
true
)
setErrorMessage
(
'请输入11位手机号'
)
return
}
if
(
!
phoneverify
)
{
setErrorMessage
(
'请输入验证码'
)
return
}
const
params
=
{
phone
,
authCode
:
phoneverify
,
appTermEnum
:
'XIAOMAI_CLOUD_CLASS_PC_WEB_ADMIN'
}
BaseService
.
login
(
params
).
then
((
res
)
=>
{
if
(
!
res
.
success
)
{
setErrorMessage
(
res
.
message
)
}
else
{
User
.
setUserId
(
res
.
result
.
userId
)
User
.
setToken
(
res
.
result
.
xmToken
)
window
.
currentStoreUserInfo
=
{}
window
.
currentStoreUserInfo
.
userId
=
res
.
result
.
userId
;
window
.
currentStoreUserInfo
.
token
=
res
.
result
.
xmToken
;
window
.
RCHistory
.
push
({
pathname
:
`/switch-route`
})
}
})
}
/**
* 手机登陆入口,暂时隐藏,此页注释代码勿删
*/
// async function checkAccount(code, callback = () => {}) {
// callback();
// }
// function checkSend(code) {
// if (!phone) {
// setPhoneError(true);
// setErrorMessage('请输入手机号');
// return;
// }
// if (phone.length != 11) {
// setPhoneError(true);
// setErrorMessage('请输入11位手机号');
// return;
// }
// !_.isEmpty(checkObject1) && checkObject1.reset();
// setOpenCheck1(true);
// }
// function handleSendSMSCode(checkData, userType) {
// if (waitStatus) return;
// let timer;
// const params = {
// phone: phone,
// sig: checkData.sig,
// sessionId: checkData.csessionid,
// token: checkData.token,
// scene: 'nc_login',
// serverType: 'CLOUD_CLASS_LOGIN',
// appTermEnum: 'XIAOMAI_CLOUD_CLASS_PC_WEB_ADMIN',
// };
// BaseService.sendLoginAuthCode(params).then((res) => {
// if (!res.success) {
// setErrorMessage(res.message);
// } else {
// timeSub(60);
// setChecking1(true);
// }
// });
// function timeSub(waitTime, unit) {
// clearTimeout(timer);
// timer = setTimeout(function () {
// if (waitTime === 0) {
// setCodeText('发送验证码');
// setChecking1(false);
// setWaitStatus(false);
// clearTimeout(timer);
// } else {
// setCodeText(`${waitTime}秒后重发`);
// setWaitStatus(true);
// timeSub(--waitTime, 1000);
// }
// }, unit || 0);
// }
// }
// function handleSubmit() {
// if (!phone) {
// setPhoneError(true);
// setErrorMessage('请输入手机号');
// return;
// }
// if (phone.length != 11) {
// setPhoneError(true);
// setErrorMessage('请输入11位手机号');
// return;
// }
// if (!phoneverify) {
// setErrorMessage('请输入验证码');
// return;
// }
// const params = {
// phone,
// authCode: phoneverify,
// appTermEnum: 'XIAOMAI_CLOUD_CLASS_PC_WEB_ADMIN',
// };
// BaseService.login(params).then((res) => {
// if (!res.success) {
// setErrorMessage(res.message);
// } else {
// User.setUserId(res.result.userId);
// User.setToken(res.result.xmToken);
// window.RCHistory.push({
// pathname: `/switch-route`,
// });
// }
// });
// }
/**
* 手机登陆入口,暂时隐藏,此页注释代码勿删
*/
return
(
<
div
className=
"login-page"
>
<
div
className=
"logo-img-box"
><
img
src=
"https://image.xiaomaiketang.com/xm/6k8PPCmywG.png"
className=
"logo-img"
/></
div
>
<
div
className=
"login-main"
>
<
div
className=
"left-banner"
>
<
div
className=
"img-box"
><
img
src=
"https://image.xiaomaiketang.com/xm/CDCcdAdaPs.png"
alt=
""
/></
div
>
<
div
className=
'login-page'
>
<
div
className=
'logo-img-box'
>
<
img
src=
'https://image.xiaomaiketang.com/xm/6k8PPCmywG.png'
className=
'logo-img'
/>
</
div
>
<
div
className=
"login-box"
>
<
div
className=
"left-top-block color-block"
></
div
>
<
div
className=
"right-bottom-block color-block"
></
div
>
<
div
className=
"login"
>
<
div
className=
"r"
>
<
Tabs
defaultActiveKey=
"1"
>
<
TabPane
tab=
"企业微信登录"
key=
"1"
>
<
div
className=
'login-main'
>
<
div
className=
'left-banner'
>
<
div
className=
'img-box'
>
<
img
src=
'https://image.xiaomaiketang.com/xm/CDCcdAdaPs.png'
alt=
''
/>
</
div
>
</
div
>
<
div
className=
'login-box'
>
<
div
className=
'left-top-block color-block'
></
div
>
<
div
className=
'right-bottom-block color-block'
></
div
>
<
div
className=
'login'
>
<
div
className=
'r'
>
<
Tabs
defaultActiveKey=
'1'
>
<
TabPane
tab=
'企业微信登录'
key=
'1'
>
<
WechatLogin
></
WechatLogin
>
</
TabPane
>
<
TabPane
tab=
'手机号登录'
key=
'2'
>
{
/* 手机登陆入口,暂时隐藏,此页注释代码勿删 */
}
{
/* <TabPane tab='手机号登录' key='2'>
<div className='login-form'>
<div className='form'>
<div className='username' style={{ marginBottom: 16 }}>
...
...
@@ -251,14 +271,15 @@ function Login(props) {
</div>
</div>
</div>
</
TabPane
>
</TabPane> */
}
{
/* 手机登陆入口,暂时隐藏,此页注释代码勿删 */
}
</
Tabs
>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
)
)
;
}
export
default
withRouter
(
Login
)
export
default
withRouter
(
Login
)
;
src/modules/root/Login.less
View file @
1bad31cd
@import url(
"../../core/variables.less"
);
@import url(
'../../core/variables.less'
);
.login-page {
position: static;
font-family:
"微软雅黑"
;
font-family:
'微软雅黑'
;
padding: 0;
min-width: 1200px;
background: #
F4F6FA
;
background: #
f4f6fa
;
height: 100%;
overflow-y: hidden;
.logo-img-box{
.logo-img-box
{
position: absolute;
top:24px;
right:32px;
z-index:1;
.logo-img{
width:120px;
top:
24px;
right:
32px;
z-index:
1;
.logo-img
{
width:
120px;
display: inline-block;
}
}
...
...
@@ -27,7 +27,7 @@
width: 540px;
height: 100vh;
.img-box {
background: #2966
FF
;
background: #2966
ff
;
width: 540px;
height: 100vh;
img {
...
...
@@ -36,7 +36,7 @@
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
transform: translate(-50%,
-50%);
}
}
}
...
...
@@ -50,10 +50,10 @@
height: 256px;
background: rgba(41, 102, 255, 0.05);
position: absolute;
top:0;
top:
0;
left: 0;
&.right-bottom-block {
top:auto;
top:
auto;
left: auto;
bottom: 0;
right: 0;
...
...
@@ -90,8 +90,8 @@
height: 420px;
position: absolute;
left: 50%;
top:50%;
transform: translate(-50%,-50%);
top:
50%;
transform: translate(-50%,
-50%);
overflow: hidden;
background-color: #ffffff;
border-radius: 4px;
...
...
@@ -107,7 +107,7 @@
.ant-tabs-tab-active {
.ant-tabs-tab-btn {
color: #333333;
font-weight:
500
!important;
font-weight:
500
!important;
}
}
.ant-tabs-nav::before {
...
...
@@ -115,7 +115,7 @@
}
.ant-tabs-tab {
text-align: center;
margin:0;
margin:
0;
}
.ant-tabs > .ant-tabs-nav .ant-tabs-nav-list {
margin: 0 auto;
...
...
@@ -128,13 +128,7 @@
width: 280px;
height: 100%;
background: @primary;
background: -webkit-gradient(
linear,
left top,
left bottom,
from(#ffaa1a),
to(#ff8634)
) !important;
background: -webkit-gradient(linear, left top, left bottom, from(#ffaa1a), to(#ff8634)) !important;
display: flex;
display: -webkit-flex;
-webkit-flex-direction: column;
...
...
@@ -197,8 +191,8 @@
}
}
}
.login-form{
margin-top:32px;
.login-form
{
margin-top:
32px;
}
.qrcode {
display: none;
...
...
@@ -281,7 +275,7 @@
font-weight: 500;
color: #333;
&::after {
content:
""
;
content:
''
;
display: block;
width: 24px;
height: 4px;
...
...
@@ -383,12 +377,12 @@
border-radius: 3px;
margin-top: 60px;
font-size: 14px; // font-weight: 300;
color:
#2966FF
;
color:
#2966ff
;
&:hover {
color: #2966
FF
;
color: #2966
ff
;
}
&::before {
content:
""
;
content:
''
;
display: block;
height: 20px;
width: 1px;
...
...
@@ -416,7 +410,7 @@
}
.refresh {
font-size: 14px;
color: #2966
FF
;
color: #2966
ff
;
cursor: pointer;
}
}
...
...
@@ -466,10 +460,10 @@
transition: all 0.3s;
cursor: pointer;
border: none;
text-align:center;
text-align:
center;
&:hover {
opacity: 0.7;
background: #5
C8AFF
;
background: #5
c8aff
;
}
}
}
...
...
src/modules/root/WechatLogin.less
View file @
1bad31cd
...
...
@@ -9,7 +9,7 @@
color: #999999;
line-height: 20px;
}
.rwm{
.rwm
{
position: relative;
width: 210px;
height: 210px;
...
...
@@ -18,29 +18,28 @@
margin-top: 24px;
border: 1px solid #e8e8e8;
border-radius: 2px;
padding:15px;
.error{
padding:
15px;
.error
{
position: absolute;
width: 200px;
height: 200px;
background: rgba(255, 255, 255, 0.95);
display: flex;
align-items:
center;
justify-content:
center;
left:
5px;
top:
5px;
div
{
align-items:
center;
justify-content:
center;
left:
5px;
top:
5px;
div
{
margin: 0 10px;
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #333333;
line-height: 20px;
}
.ope
{
.ope
{
cursor: pointer;
color:
rgba(82, 137, 250, 1);
color:
rgba(82, 137, 250, 1);
}
}
}
...
...
src/modules/root/WechatLogin.tsx
View file @
1bad31cd
import
React
,
{
useState
,
useRef
,
useEffect
}
from
'react'
;
import
qrcode
from
"@/libs/qrcode/qrcode.js"
;
import
Service
from
"@/common/js/service"
;
import
qrcode
from
'@/libs/qrcode/qrcode.js'
;
import
Service
from
'@/common/js/service'
;
import
User
from
'@/common/js/user'
;
import
{
PATH
}
from
'@/domains/basic-domain/constants'
;
import
'./WechatLogin.less'
const
Logo
=
require
(
"@/common/images/logo.png"
)
import
'./WechatLogin.less'
;
const
Logo
=
require
(
'@/common/images/logo.png'
);
declare
var
location
:
any
;
declare
var
window
:
any
;
...
...
@@ -13,33 +13,28 @@ export default function WechatLogin(props: any) {
const
init
:
any
=
null
;
const
[
status
,
setStatus
]
=
useState
(
0
);
const
[
ticket
,
setTicket
]
=
useState
(
''
);
const
[
leftTime
,
setLeftTime
]
=
useState
(
freshTime
)
const
[
leftTime
,
setLeftTime
]
=
useState
(
freshTime
);
const
QRCode
=
useRef
(
init
);
const
timer
=
useRef
(
init
);
const
leftTimeRef
=
useRef
(
init
);
useEffect
(()
=>
{
leftTimeRef
.
current
=
leftTime
;
},
[
leftTime
])
},
[
leftTime
]);
useEffect
(()
=>
{
clearInterval
(
timer
.
current
as
any
);
if
(
status
===
0
)
{
Service
.
Hades
(
"anon/hades/getTicket"
,
{}).
then
((
res
:
any
)
=>
{
setTicket
(
res
.
result
)
const
redirect
=
`
${
PATH
}
?ticket=
${
res
.
result
}
&appTermEnum=XIAOMAI_CLOUD_CLASS_PC_WEB_ADMIN&env=
${
process
.
env
.
DEPLOY_ENV
||
'dev'
}
`
// console.log(redirect)
// const url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=ww409ccf9c6e31f19e&redirect_uri=${encodeURIComponent(redirect)}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`
// console.log(url)
const
qrcodeWrapDom
:
any
=
document
.
querySelector
(
'#qrcode'
);
Service
.
Hades
(
'anon/hades/getTicket'
,
{}).
then
((
res
:
any
)
=>
{
setTicket
(
res
.
result
);
const
redirect
=
`
${
PATH
}
?ticket=
${
res
.
result
}
&appTermEnum=XIAOMAI_CLOUD_CLASS_PC_WEB_ADMIN&env=
${
process
.
env
.
DEPLOY_ENV
||
'dev'
}
`
;
const
qrcodeWrapDom
:
any
=
document
.
querySelector
(
'#qrcode'
);
let
qrnode
=
new
qrcode
({
text
:
redirect
,
correctLevel
:
2
,
size
:
180
,
// image: 'https://image.xiaomaiketang.com/xm/Newk4NrxKC.png',
image
:
'https://image.xiaomaiketang.com/xm/bFkRBz7teA.png'
,
imageSize
:
50
imageSize
:
50
,
});
qrcodeWrapDom
.
innerHTML
=
''
;
qrcodeWrapDom
&&
qrcodeWrapDom
.
appendChild
(
qrnode
);
...
...
@@ -50,83 +45,95 @@ export default function WechatLogin(props: any) {
if
(
leftTimeRef
.
current
==
0
)
{
clearInterval
(
timer
.
current
);
setStatus
(
1
);
return
return
;
}
setLeftTime
(
leftTimeRef
.
current
-
1
);
},
1000
)
})
},
1000
);
});
}
return
()
=>
{
clearInterval
(
timer
.
current
);
}
},
[
status
])
};
},
[
status
]);
useEffect
(()
=>
{
if
(
leftTime
==
60
||
!
ticket
)
{
return
return
;
}
Service
.
Hades
(
'anon/hades/getTicketState'
,
{
ticket
ticket
,
}).
then
((
res
:
any
)
=>
{
if
(
res
.
result
===
'AUTH_SUCCESS'
)
{
Service
.
Hades
(
'anon/hades/getTicketWXWorkLogin'
,
{
ticket
ticket
,
}).
then
((
_res
:
any
)
=>
{
User
.
setUserId
(
_res
.
result
.
loginInfo
.
userId
);
User
.
setToken
(
_res
.
result
.
loginInfo
.
xmToken
);
User
.
setEnterpriseId
(
_res
.
result
.
enterpriseId
);
User
.
setIdentifier
(
_res
.
result
.
identifier
);
window
.
currentStoreUserInfo
=
{}
window
.
currentStoreUserInfo
.
userId
=
_res
.
result
.
loginInfo
.
userId
;
window
.
currentStoreUserInfo
.
token
=
_res
.
result
.
loginInfo
.
xmToken
;
window
.
currentStoreUserInfo
.
enterpriseId
=
_res
.
result
.
enterpriseId
;
User
.
setIdentifier
(
_res
.
result
.
identifier
)
window
.
RCHistory
.
push
({
pathname
:
`/switch-route`
,
})
})
});
});
}
});
},
[
leftTime
]);
})
},
[
leftTime
])
return
<
div
className=
'wechatLoginBox'
>
<
div
className=
"rwm"
>
<
div
id=
"qrcode"
></
div
>
return
(
<
div
className=
'wechatLoginBox'
>
<
div
className=
'rwm'
>
<
div
id=
'qrcode'
></
div
>
{
status
===
1
&&
<
div
className=
"error"
>
<
div
>
二维码已过期
<
p
className=
"ope"
onClick=
{
()
=>
{
setStatus
(
0
)
}
}
>
刷新
</
p
>
{
status
===
1
&&
(
<
div
className=
'error'
>
<
div
>
二维码已过期
<
p
className=
'ope'
onClick=
{
()
=>
{
setStatus
(
0
);
}
}
>
刷新
</
p
>
</
div
>
</
div
>
}
{
status
===
2
&&
<
div
className=
"error"
>
<
div
>
所在企业还未注册学院
<
p
className=
"ope"
onClick=
{
()
=>
{
setStatus
(
0
)
}
}
>
我知道了
</
p
>
)
}
{
status
===
2
&&
(
<
div
className=
'error'
>
<
div
>
所在企业还未注册学院
<
p
className=
'ope'
onClick=
{
()
=>
{
setStatus
(
0
);
}
}
>
我知道了
</
p
>
</
div
>
</
div
>
}
{
status
===
3
&&
<
div
className=
"error"
>
<
div
>
你还不是学院员工,请联系企业管理员
<
p
className=
"ope"
onClick=
{
()
=>
{
setStatus
(
0
)
}
}
>
我知道了
</
p
>
)
}
{
status
===
3
&&
(
<
div
className=
'error'
>
<
div
>
你还不是学院员工,请联系企业管理员
<
p
className=
'ope'
onClick=
{
()
=>
{
setStatus
(
0
);
}
}
>
我知道了
</
p
>
</
div
>
</
div
>
}
)
}
</
div
>
<
p
className=
'text'
>
请使用企业微信扫码登录
</
p
>
</
div
>
);
}
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