235 lines
6.6 KiB
JavaScript
235 lines
6.6 KiB
JavaScript
|
|
import React, { Component } from 'react'
|
||
|
|
import { connect } from 'dva'
|
||
|
|
import { Icon, Modal, Badge, List, Avatar, Button, Pagination, Card, notification } from 'antd'
|
||
|
|
import IFComponent from '../common/IFComponent'
|
||
|
|
import Socket from '../utils/socket'
|
||
|
|
import { initFilter } from '../utils/common'
|
||
|
|
import { cloneDeep } from 'lodash'
|
||
|
|
|
||
|
|
class MsgNotice extends Component {
|
||
|
|
constructor (props) {
|
||
|
|
super(props)
|
||
|
|
this.state = {
|
||
|
|
visible: false,
|
||
|
|
currentNoticeDetail: null,
|
||
|
|
current: 1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
componentDidMount () {
|
||
|
|
this.refOfSocket = new Socket({
|
||
|
|
url: this.props.webSocketHost,
|
||
|
|
onmessage: this.handleWebSocketData
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
componentWillUnmount () {
|
||
|
|
this.refOfSocket.close()
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 处理 websocket 的消息
|
||
|
|
* @param {*} res
|
||
|
|
*/
|
||
|
|
handleWebSocketData = (res) => {
|
||
|
|
if (res) {
|
||
|
|
const { TypeCode, Data } = JSON.parse(res)
|
||
|
|
if (TypeCode === 'M001' && Data) {
|
||
|
|
const __html = Data.Message.replace(/[\n\r]/g, '<br/>')
|
||
|
|
switch (Data.ShowInfoType) {
|
||
|
|
case 0:
|
||
|
|
this.addNotification(Data)
|
||
|
|
Modal.info({
|
||
|
|
title: Data.Title || '通知',
|
||
|
|
content: <div dangerouslySetInnerHTML={{ __html }} />,
|
||
|
|
onOk: () => {
|
||
|
|
this.acceptedNotification(Data)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
break
|
||
|
|
case 1:
|
||
|
|
notification.info({
|
||
|
|
message: Data.Title || '通知',
|
||
|
|
description: <div dangerouslySetInnerHTML={{ __html }} />
|
||
|
|
})
|
||
|
|
this.addNotification(Data)
|
||
|
|
this.acceptedNotification(Data)
|
||
|
|
break
|
||
|
|
default:
|
||
|
|
break
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 显示隐藏通知面板
|
||
|
|
* @param {*} visible
|
||
|
|
*/
|
||
|
|
toggleVisible = (visible) => {
|
||
|
|
this.setState({
|
||
|
|
visible,
|
||
|
|
currentNoticeDetail: null
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 消息详情显示和已读
|
||
|
|
* @param {*} value
|
||
|
|
*/
|
||
|
|
onReading = (value) => {
|
||
|
|
this.setState({ currentNoticeDetail: value })
|
||
|
|
!value.IsAccepted && this.acceptedNotification(value)
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 渲染弹窗 footer
|
||
|
|
*/
|
||
|
|
renderFooter = () => {
|
||
|
|
const { login, dispatch } = this.props
|
||
|
|
const { OrgId, userId } = login
|
||
|
|
const { TotalCount, ErrorMessage } = login.Notifications || {}
|
||
|
|
const { currentNoticeDetail, current } = this.state
|
||
|
|
const pageConfig = {
|
||
|
|
key: 'pagination',
|
||
|
|
size: 'small',
|
||
|
|
total: TotalCount,
|
||
|
|
current,
|
||
|
|
showTotal: total => `共 ${total} 条, 未读 ${ErrorMessage || 0} 条`,
|
||
|
|
onChange: page => {
|
||
|
|
dispatch({
|
||
|
|
type: 'login/getNotices',
|
||
|
|
payload: initFilter(OrgId, '', 'CREATE_TIME', 1, page, userId)
|
||
|
|
}).then(res => {
|
||
|
|
if (res && res.IsSuccessful) {
|
||
|
|
this.setState({ current: page })
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (currentNoticeDetail) {
|
||
|
|
return (
|
||
|
|
<Button key='cancel' onClick={() => this.setState({ currentNoticeDetail: null })}>
|
||
|
|
返回列表
|
||
|
|
</Button>
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
return <Pagination {...pageConfig} />
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* websocket 新通知追加到列表中
|
||
|
|
* @param {*} data
|
||
|
|
*/
|
||
|
|
addNotification = (data) => {
|
||
|
|
const { dispatch, login } = this.props
|
||
|
|
let arr = JSON.parse(JSON.stringify(login.Notifications))
|
||
|
|
!arr && (arr = { Data: [], TotalCount: 0 })
|
||
|
|
arr.Data.splice(0, 0, data)
|
||
|
|
data.NotificatoinType === 0 && dispatch({
|
||
|
|
type: 'login/save',
|
||
|
|
payload: {
|
||
|
|
Notifications: arr
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* websocket 新通知设置已读
|
||
|
|
* @param {*} data
|
||
|
|
* @param {*} cb
|
||
|
|
*/
|
||
|
|
acceptedNotification = (data) => {
|
||
|
|
const { NotificationId } = data
|
||
|
|
const { login, dispatch } = this.props
|
||
|
|
const { OrgId, userId } = login
|
||
|
|
const json = initFilter(OrgId, NotificationId, '', 0, 1, userId)
|
||
|
|
dispatch({
|
||
|
|
type: 'app/acceptNotification',
|
||
|
|
payload: json,
|
||
|
|
onComplete: (res) => {
|
||
|
|
if (res) {
|
||
|
|
const copyData = cloneDeep(login.Notifications)
|
||
|
|
const errorMessage = Number(copyData.ErrorMessage)
|
||
|
|
const findData = copyData.Data.find(item => item.NotificationId === NotificationId)
|
||
|
|
if (findData) {
|
||
|
|
findData.IsAccepted = true
|
||
|
|
errorMessage > 0 && (copyData.ErrorMessage = errorMessage - 1)
|
||
|
|
dispatch({
|
||
|
|
type: 'login/save',
|
||
|
|
payload: {
|
||
|
|
Notifications: copyData
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
render () {
|
||
|
|
const { Notifications } = this.props.login
|
||
|
|
const { Data = [], ErrorMessage } = Notifications || {}
|
||
|
|
const { visible, currentNoticeDetail } = this.state
|
||
|
|
|
||
|
|
return (
|
||
|
|
<React.Fragment>
|
||
|
|
<Badge dot={ErrorMessage > 0} onClick={() => this.toggleVisible(true)}>
|
||
|
|
<Icon type='bell' className={`msg-notice__icon ${this.props.theme}`} />
|
||
|
|
</Badge>
|
||
|
|
<Modal
|
||
|
|
title='消息'
|
||
|
|
maskClosable={false}
|
||
|
|
visible={visible}
|
||
|
|
wrapClassName='msg-notice__modal'
|
||
|
|
bodyStyle={{ padding: 0 }}
|
||
|
|
footer={this.renderFooter()}
|
||
|
|
onCancel={() => this.toggleVisible(false)}
|
||
|
|
>
|
||
|
|
<IFComponent
|
||
|
|
IF={!currentNoticeDetail}
|
||
|
|
ELSE={
|
||
|
|
<Card bordered={false}>
|
||
|
|
<Card.Meta
|
||
|
|
avatar={<Avatar>{currentNoticeDetail ? String(currentNoticeDetail.UserName)[0] || '?' : ''}</Avatar>}
|
||
|
|
title={currentNoticeDetail ? currentNoticeDetail.Time + ' ' + currentNoticeDetail.Title : '通知'}
|
||
|
|
description={currentNoticeDetail ? currentNoticeDetail.Message : '无'}
|
||
|
|
/>
|
||
|
|
</Card>
|
||
|
|
}
|
||
|
|
>
|
||
|
|
<List
|
||
|
|
dataSource={Data}
|
||
|
|
renderItem={item => (
|
||
|
|
<List.Item
|
||
|
|
className='msg-notice__list'
|
||
|
|
onClick={() => this.onReading(item)}
|
||
|
|
actions={
|
||
|
|
<IFComponent IF={!item.IsAccepted}>
|
||
|
|
<a onClick={(e) => {
|
||
|
|
e.stopPropagation()
|
||
|
|
this.acceptedNotification(item)
|
||
|
|
}}
|
||
|
|
>标记已读</a>
|
||
|
|
</IFComponent>
|
||
|
|
}
|
||
|
|
>
|
||
|
|
<List.Item.Meta
|
||
|
|
avatar={<Avatar>{String(item.UserName)[0] || '?'}</Avatar>}
|
||
|
|
title={`${item.Title ? item.Time + ' ' + item.Title : '通知'}`}
|
||
|
|
description={<div className='msg-notice__msg'>{item.Message || '无'}</div>}
|
||
|
|
/>
|
||
|
|
</List.Item>
|
||
|
|
)}
|
||
|
|
/>
|
||
|
|
</IFComponent>
|
||
|
|
</Modal>
|
||
|
|
</React.Fragment>
|
||
|
|
)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export default connect(({ login }) => ({ login }))(MsgNotice)
|