mh_jy_safe_web/src/feui/msg-notice/index.js
2025-08-25 10:08:30 +08:00

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)