@@ -5,15 +5,28 @@ import CloseIcon from './components/close'; | |||
import MinimizeIcon from './components/minimize'; | |||
import ZoomIcon from './components/zoom'; | |||
import logoImg from './assets/logo.png'; | |||
import { useModel } from 'umi'; | |||
import UserCenter from './components/userCenter'; | |||
export default function AppHeader(props) { | |||
const { className, style } = props; | |||
const { initialState: { isLogin } = { isLogin: false } } = useModel('@@initialState'); | |||
return ( | |||
<div className={css(styles.appHeader, className)} style={style}> | |||
<div className={styles.left}> | |||
<img src={logoImg} alt="" /> | |||
</div> | |||
<div className={styles.right}> | |||
{ | |||
isLogin | |||
? ( | |||
<> | |||
<UserCenter className={styles.mr16} /> | |||
</> | |||
) | |||
: null | |||
} | |||
<div className={styles.split} /> | |||
<MinimizeIcon className={styles.mr12} /> | |||
<ZoomIcon className={styles.mr12} /> | |||
@@ -0,0 +1,93 @@ | |||
.icon { | |||
cursor: pointer; | |||
color: #A7A8B7; | |||
&:hover, &.active { | |||
color: @primary-color; | |||
} | |||
} | |||
.btn { | |||
height: 20px; | |||
padding: 0; | |||
vertical-align: top; | |||
border: none; | |||
} | |||
.pop { | |||
&Wrapper { | |||
:global(.ant-popover-arrow) { | |||
display: none; | |||
} | |||
:global(.ant-popover-inner) { | |||
background: #FFFFFF; | |||
box-shadow: 0px 3px 11px 1px rgba(0, 0, 0, 0.06); | |||
border-radius: 4px; | |||
} | |||
:global(.ant-popover-inner-content) { | |||
padding: 0; | |||
} | |||
} | |||
&View { | |||
width: 200px; | |||
} | |||
&Header { | |||
display: flex; | |||
flex-direction: row; | |||
justify-content: space-between; | |||
padding: 12px 12px 12px 16px; | |||
height: 68px; | |||
background-color: #ebebf2; | |||
color: rgba(#000, 0.8); | |||
line-height: 1em; | |||
.left, .right { | |||
flex: none; | |||
} | |||
.left { | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: space-between; | |||
} | |||
.name { font-size: 14px; } | |||
.phone { font-size: 12px;} | |||
.avator { | |||
width: 42px; | |||
height: 42px; | |||
border-radius: 50%; | |||
} | |||
} | |||
&Content { | |||
.listGroupTitle { | |||
margin-top: 8px; | |||
font-size: 12px; | |||
color: rgba(0, 0, 0, 0.65); | |||
height: 28px; | |||
line-height: 28px; | |||
> div { | |||
transform: scale(0.83); | |||
} | |||
} | |||
.listItem { | |||
display: flex; | |||
flex-direction: row; | |||
justify-content: space-between; | |||
align-items: center; | |||
height: 36px; | |||
padding: 0 12px 0 16px; | |||
color: rgba(15, 15, 15, 0.7); | |||
// border-bottom: 1px solid ; | |||
cursor: pointer; | |||
box-shadow: 0px 0.5px 0px 0px #EEF2F5; | |||
} | |||
.btnGroup { | |||
padding: 10px 0; | |||
text-align: center; | |||
} | |||
.logout { | |||
color: @primary-color; | |||
} | |||
} | |||
} | |||
.confirmModal { | |||
color: red; | |||
} |
@@ -0,0 +1,92 @@ | |||
import { useModel } from '@/.umi/plugin-model/useModel'; | |||
import { confirm } from '@/components/AModal'; | |||
import OssImage from '@/components/OssImage'; | |||
import SvgIcon from '@/components/SvgIcon'; | |||
import { logout } from '@/services/user'; | |||
import { RightOutlined, QuestionOutlined } from '@ant-design/icons'; | |||
import { Button, Popover, Modal } from 'antd'; | |||
import classNames from 'classnames'; | |||
import React, { CSSProperties } from 'react'; | |||
import { useCallback } from 'react'; | |||
import { useState } from 'react'; | |||
import styles from './UserCenter.less'; | |||
interface UserCenterProps { | |||
className?: string; | |||
style?: CSSProperties; | |||
} | |||
export default function UserCenter(props: UserCenterProps) { | |||
const { className } = props; | |||
const [popVisible, setPopVisible] = useState(false); | |||
const onVisibleChange = useCallback((nextVisible) => { | |||
setPopVisible(nextVisible); | |||
}, []) | |||
return ( | |||
<Popover | |||
overlayClassName={styles.popWrapper} | |||
content={<PopContent />} | |||
trigger="click" | |||
visible={popVisible} | |||
onVisibleChange={onVisibleChange} | |||
placement="bottomRight" | |||
arrowContent={() => null} | |||
> | |||
<Button type="link" className={classNames(styles.btn, className)}> | |||
<SvgIcon className={classNames(styles.icon, popVisible ? styles.active : '')} xlinkHref="usercenter" /> | |||
</Button> | |||
</Popover> | |||
) | |||
} | |||
function PopContent(props) { | |||
const { initialState: { currentUser } = {} } = useModel('@@initialState'); | |||
console.log(currentUser); | |||
const tryLogout = useCallback(() => { | |||
confirm({ | |||
onOk() { | |||
logout(); | |||
}, | |||
content: '确实退出登录?', | |||
}) | |||
}, []) | |||
return ( | |||
<div className={styles.popView}> | |||
<div className={styles.popHeader}> | |||
<div className={styles.left}> | |||
<div className={styles.name}>{currentUser?.cnName}</div> | |||
<div className={styles.phone}>{currentUser?.phone}</div> | |||
</div> | |||
<div className={styles.right}> | |||
<OssImage className={styles.avator} src={currentUser?.headImgUrl} preview={false} /> | |||
</div> | |||
</div> | |||
<div className={styles.popContent}> | |||
{/* <div className={styles.listGroupTitle}><div>账号</div></div> | |||
<div className={styles.listItem}> | |||
<span>账号设置</span> | |||
<RightOutlined color="#8E909F" /> | |||
</div> | |||
<div className={styles.listItem}> | |||
<span>同步设置</span> | |||
<RightOutlined color="#8E909F" /> | |||
</div> | |||
<div className={styles.listGroupTitle}><div>其他</div></div> | |||
<div className={styles.listItem}> | |||
<span>系统版本</span> | |||
<RightOutlined color="#8E909F" /> | |||
</div> | |||
<div className={styles.listItem}> | |||
<span>关于易云</span> | |||
<RightOutlined color="#8E909F" /> | |||
</div> */} | |||
<div className={styles.btnGroup}> | |||
<Button className={styles.logout} type="link" onClick={tryLogout}>退出登录</Button> | |||
</div> | |||
</div> | |||
</div> | |||
) | |||
} |
@@ -0,0 +1 @@ | |||
export { default } from './UserCenter'; |
@@ -7,12 +7,19 @@ | |||
justify-content: space-between; | |||
align-items: center; | |||
flex-direction: row; | |||
box-shadow: 0px 0px 0px 0px #EEF2F5; | |||
box-shadow: 0px 0.5px 0px 0px #EEF2F5; | |||
background-color: #fff; | |||
} | |||
.left, .right { | |||
flex: none; | |||
line-height: 0; | |||
} | |||
.right { | |||
display: flex; | |||
flex-direction: row; | |||
align-items: center; | |||
.mr16 { margin-right: 16px; } | |||
.mr12 { margin-right: 12px;} | |||
.split { | |||
@@ -16,7 +16,8 @@ | |||
.nav { | |||
width: 48px; | |||
padding: 24px 0 0 8px; | |||
box-shadow: 0px 0px 0px 0px #EEF2F5; | |||
box-shadow: 0.5px 0px 0px 0px #EEF2F5; | |||
z-index: 1; | |||
.navItem { | |||
display: block; | |||
width: 32px; | |||