通知中心

This commit is contained in:
谢思 2021-09-14 09:45:53 +08:00
parent f30903072e
commit c5bb61cb9a
3 changed files with 247 additions and 122 deletions

View File

@ -62,7 +62,7 @@ function Index(props){
<ul className="securityUl ul-border-buttom"> <ul className="securityUl ul-border-buttom">
<li>消息通知</li> <li>消息通知</li>
<li className={pathname.indexOf("/settings/notice/myNotice")>-1 || pathname.indexOf("/settings/notice/privateLetter")>-1 ?"active":""}><Link to={`/settings/notice/myNotice`}><i className="iconfont icon-wodetongzhi"></i><span className="text-shodow-bold">我的通知</span></Link></li> <li className={pathname.indexOf("/settings/notice/myNotice")>-1 || pathname.indexOf("/settings/notice/privateLetter")>-1 ?"active":""}><Link to={`/settings/notice/myNotice`}><i className="iconfont icon-wodetongzhi"></i><span className="text-shodow-bold">我的通知</span></Link></li>
<li className={pathname.indexOf("/settings/notice/noticeManager")>-1 ?"active":""}><Link to={`/settings/notice/noticeManager`}><i className="iconfont icon-tongzhiguanli"></i><span className="text-shodow-bold">通知管理</span></Link></li> {/* <li className={pathname.indexOf("/settings/notice/noticeManager")>-1 ?"active":""}><Link to={`/settings/notice/noticeManager`}><i className="iconfont icon-tongzhiguanli"></i><span className="text-shodow-bold">通知管理</span></Link></li> */}
</ul> </ul>
<ul className="securityUl"> <ul className="securityUl">
<li>安全设置</li> <li>安全设置</li>

View File

@ -3,37 +3,131 @@ import { Badge, Button, Checkbox, Menu } from 'antd';
import './Index.scss'; import './Index.scss';
import '../manager/Index.scss' import '../manager/Index.scss'
import DelModal from '../../../Wiki/components/ModalFun'; import DelModal from '../../../Wiki/components/ModalFun';
import Axios from 'axios'; import axios from 'axios';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { CheckboxGroup } from 'rsuite';
function MyNotice(props) { function MyNotice(props) {
const [noticeType, setNoticeType] = useState("0");//tab const [noticeType, setNoticeType] = useState("2");//tab
const [selectedNum, setSelectedNum] = useState(0);//@ const [selectedNum, setSelectedNum] = useState(0);//@
const [isBatchDelete, setIsBatchDelete] = useState(false);//@ const [isBatchDelete, setIsBatchDelete] = useState(false);//@
const [batchDeleteCheckedAll, setBatchDeleteCheckAll] = useState(false);//@-- const [batchDeleteCheckedAll, setBatchDeleteCheckAll] = useState(false);//@--
const [batchDeleteList, setBatchDeleteList] = useState([]);//@-- const [batchDeleteList, setBatchDeleteList] = useState([]);//@--
const [atmeList, setAtmeList] = useState([]); const [atmeIds, setAtmeIds] = useState([]);
const [noticeUnreadCount, setNoticeUnreadCount] = useState();// const [noticeUnreadCount, setNoticeUnreadCount] = useState();//
const [letterUnreadCount, setLetterUnreadCount] = useState(0);// const [letterUnreadCount, setLetterUnreadCount] = useState(0);//
const [atUnreadCount, setAtUnreadCount] = useState();//@ const [atUnreadCount, setAtUnreadCount] = useState(2);//@
const [messageList, setMessageList] = useState([]); const [messageList, setMessageList] = useState([
const [onlyUnread, setOnlyUnread] = useState(); {
"id": 1,
useEffect(() => { "status": 1,
const params = { "content": "Atme Message Content 1",
type: noticeType === "0" ? "notification" : noticeType === "2" ? "atme" : "", "notification_url": "http://www.baidu.com",
status: onlyUnread ? onlyUnread : "", "source": "PullRequestAtme",
limit: 20, "time_ago": "1天前",
page: 0, "type": "atme",
"sender": {
"id": 5,
"type": "User",
"name": "testforge2",
"login": "testforge2",
"image_url": "system/lets/letter_avatars/2/T/236_177_85/120.png"
} }
getMessageList(params); },
}, [noticeType, onlyUnread]) {
"id": 2,
"status": 0,
"content": "Atme Message Content 2",
"notification_url": "http://www.baidu.com",
"source": "IssueAtme",
"time_ago": "1天前",
"type": "atme",
"sender": {
"id": 4,
"type": "User",
"name": "testforge1",
"login": "testforge1",
"image_url": "system/lets/letter_avatars/2/T/19_237_174/120.png"
}
},
{
"id": 3,
"status": 1,
"content": "Notification Message Content 1",
"notification_url": "http://www.baidu.com",
"source": "IssueDelete",
"time_ago": "1天前",
"type": "notification"
},
{
"id": 4,
"status": 0,
"content": "Notification Message Content 2",
"notification_url": "http://www.baidu.com",
"source": "IssueChanged",
"time_ago": "1天前",
"type": "notification"
},
{
"id": 5,
"status": 0,
"content": "Notification Message Content 3",
"notification_url": "http://www.baidu.com",
"source": "ProjectJoined",
"time_ago": "1天前",
"type": "notification"
}
]);
const [onlyUnread, setOnlyUnread] = useState();
const noticeType = {
//
IssueAssigned:1, //
IssueAssignerExpire:1, //
IssueAtme:1, // @
IssueChanged:1, //
IssueCreatorExpire:1, //
IssueDeleted:1, //
IssueJournal:1, //
//
LoginIpTip:2, //
//
OrganizationJoined:3, //
OrganizationLeft:3, //
rganizationRole:3, //
ProjectJoined:3, //
ProjectLeft:3, //
ProjectRole:3, //
//
ProjectDelete:4, //
ProjectFollowed:4, //
ProjectForked:4, //
ProjectIssue:4, // /
ProjectSettingChanged:4, //
ProjectTransfer:4, //
ProjectVersion:4, //
//
ProjectPullRequest:5, // /
PullRequestAssigned:5, //
PullReuqestAtme:5, // @
PullRequestChanged:5, //
PullRequestJournal:5, //
//
ProjectMilestone:6, //
};
// useEffect(() => {
// const params = {
// type: noticeType === "0" ? "notification" : noticeType === "2" ? "atme" : "",
// status: onlyUnread ? onlyUnread : "",
// limit: 20,
// page: 0,
// }
// getMessageList(params);
// }, [noticeType, onlyUnread])
function getMessageList(params) { function getMessageList(params) {
Axios.get(`/users/yystopf/messages.json`, { axios.get(`/users/yystopf/messages.json`, {
params: params, params: params,
}).then((response) => { }).then((response) => {
setNoticeUnreadCount(response.data.unread_notification); setNoticeUnreadCount(response.data.unread_notification);
@ -41,12 +135,23 @@ function MyNotice(props) {
setMessageList(response.data.messages); setMessageList(response.data.messages);
}) })
console.log(messageList); console.log(messageList);
const atmeList = new Array(); //@ids
messageList.map(item => { const atmeIds = new Array();
item.type === "atme" ? atmeList.push(item.id.toString()) : ""; }
function readNotice(id){
if(id){
const params = {
type: noticeType === "0" ? "notification" : noticeType === "2" ? "atme" : "",
ids:id,
};
console.log(params);
axios.post(`/users/yystopf/messages/read.json`,{
params:params,
}).then((response)=>{
console.log(response);
}) })
setAtmeList(atmeList); }
console.log(atmeList);
} }
function handleClick(e) { function handleClick(e) {
@ -56,62 +161,64 @@ function MyNotice(props) {
} }
} }
function onChange(batchDeleteList) { function onChange(e) {
setBatchDeleteCheckAll(batchDeleteList.length === atmeList.length) var checkboxNum = 0;
// if(e.target.checked){ let messageListNew=messageList.slice();
// batchDeleteList.has(e.target.name)?"":setBatchDeleteList(batchDeleteList.add(e.target.name)); messageListNew.map((item)=>{
// }else{ if(item.id===e.target.value){
// batchDeleteList.delete(e.target.name); item.checkedBatch = e.target.checked;
// } }
// batchDeleteList.size === atmeCount?setBatchDeleteCheckAll(true):""; item.checkedBatch?checkboxNum++:"";
// console.log(batchDeleteCheckedAll); });
setMessageList(messageListNew);
setSelectedNum(checkboxNum);
setBatchDeleteCheckAll(checkboxNum === atUnreadCount);
} }
function onCheckAllChange(e) { function onChangeAll(e) {
setBatchDeleteCheckAll(e.target.checked); setBatchDeleteCheckAll(e.target.checked);
setBatchDeleteList(e.target.checked ? atmeList : []); setSelectedNum(e.target.checked?messageList.length:0);
// const checkbox = document.getElementsByClassName("atme-checkbox"); let messageListNew=messageList.slice();
// for (var i = 0; i < checkbox.length; i++) { messageListNew.map((item)=>{
// checkbox[i].checked = e.target.checked; item.checkedBatch = e.target.checked;
// } });
// setSelectedNum(e.target.checked ? checkbox.length : 0); setMessageList(messageListNew);
} }
function deleteNotice() { function deleteNotice(id) {
if(id){
DelModal({ DelModal({
title: noticeType === "1" ? '删除私信' : '删除与我相关', title: noticeType === "1" ? '删除私信' : '删除与我相关',
contentTitle: noticeType === "1" ? '您确定要删除与 xxx 的聊天吗?' : selectedNum === 0 ? '您确定要删除这条@我消息吗?' : '您确定要删除选中的' + selectedNum + '条消息吗?', contentTitle: noticeType === "1" ? '您确定要删除与 xxx 的聊天吗?' : id[0] != -1 ? '您确定要删除这条@我消息吗?' : '您确定要删除选中的' + selectedNum + '条消息吗?',
content: noticeType === "1" ? '此操作将删除与xxx的聊天框和xxx的所有聊天记录请进行确认以防数据的丢失' : selectedNum === 0 ? '此操作将删除这条消息,请进行确认以防数据的丢失' : '此操作将删除选中的' + selectedNum + '条消息,请进行确认以防数据的丢失', content: noticeType === "1" ? '此操作将删除与xxx的聊天框和xxx的所有聊天记录请进行确认以防数据的丢失' : id[0] != -1 ? '此操作将删除这条消息,请进行确认以防数据的丢失' : '此操作将删除选中的' + selectedNum + '条消息,请进行确认以防数据的丢失',
onOk: () => { onOk: () => {
const params = {
type: noticeType === "0" ? "notification" : noticeType === "2" ? "atme" : "",
ids:id,
};
// console.log(params);
axios.delete(`/users/yystopf/messages.json`,{
data:params,
}).then((response)=>{
// console.log(response);
})
} }
}); });
} }
function readNotice(id){
alert("消息已读");
console.log(id);
const params = {
type: noticeType === "0" ? "notification" : noticeType === "2" ? "atme" : "",
ids:[id],
};
Axios.post(`/users/yystopf/messages/read.json`,{
params:params,
}).then((response)=>{
console.log(response);
})
} }
return ( return (
<div className="notice01"> <div className="notice01">
<div className="sshHead"> <div className="sshHead">
<Menu mode="horizontal" selectedKeys={noticeType} onClick={handleClick}> <Menu mode="horizontal" selectedKeys={noticeType} onClick={handleClick}>
<Menu.Item key="0"><Badge count={noticeUnreadCount} title="">系统通知</Badge></Menu.Item> <Menu.Item key="0"><Badge count={noticeUnreadCount} title="">系统通知</Badge></Menu.Item>
<Menu.Item key="1" id="item-private"><Badge count={0}>私信</Badge></Menu.Item> {/* <Menu.Item key="1" id="item-private"><Badge count={0}>私信</Badge></Menu.Item> */}
<Menu.Item key="2"><Badge count={atUnreadCount}>@</Badge></Menu.Item> <Menu.Item key="2"><Badge count={atUnreadCount}>@</Badge></Menu.Item>
</Menu> </Menu>
<button>所有{noticeType === "0" ? "系统通知" : noticeType === "1" ? "私信" : "@我"}一键已读</button> <button onClick={()=>{readNotice([-1])}}>所有{noticeType === "0" ? "系统通知" : noticeType === "1" ? "私信" : "@我"}一键已读</button>
</div> </div>
<div className={isBatchDelete ? "invisible " : "visible"}> <div className={isBatchDelete ? "invisible " : "visible"}>
@ -123,17 +230,16 @@ function MyNotice(props) {
<div className={isBatchDelete ? 'visible' : 'invisible'}> <div className={isBatchDelete ? 'visible' : 'invisible'}>
<div className="vertical-center-style"> <div className="vertical-center-style">
{/* <input type="checkbox" id="checkAll" onChange={onCheckAllChange} />&nbsp; */} {/* <input type="checkbox" id="checkAll" onChange={onChangeAll} />&nbsp; */}
<Checkbox onChange={onCheckAllChange} checked={batchDeleteCheckedAll}>全选</Checkbox> <Checkbox onChange={onChangeAll} checked={batchDeleteCheckedAll}>全选</Checkbox>
&nbsp;&nbsp;&nbsp;已选择&nbsp;<span id="numberSpan">{selectedNum}</span>&nbsp; &nbsp;&nbsp;&nbsp;已选择&nbsp;<span id="numberSpan">{selectedNum}</span>&nbsp;
</div> </div>
<div> <div>
<button onClick={() => { setIsBatchDelete(false); setSelectedNum(0); }}>取消</button>&nbsp;&nbsp;&nbsp;&nbsp; <button onClick={() => { setIsBatchDelete(false); setSelectedNum(0); }}>取消</button>&nbsp;&nbsp;&nbsp;&nbsp;
<button className="deleteBut" onClick={selectedNum > 0 ? deleteNotice : () => { }}>删除</button> <button className="deleteBut" onClick={selectedNum > 0 ? ()=>deleteNotice([-1]) : () => { }}>删除</button>
</div> </div>
</div> </div>
<Checkbox.Group className={isBatchDelete ? '' : 'invisible_checkGroup'} onChange={onChange} value={batchDeleteList}>
{messageList.map(item => { {messageList.map(item => {
// //
// //
@ -148,7 +254,7 @@ function MyNotice(props) {
</div> </div>
<div className="mynotice-cont vertical-center-style float-left-little"> <div className="mynotice-cont vertical-center-style float-left-little">
<span className={item.status === 1?"timeSpan":""}>{item.time_ago}</span> <span className={item.status === 1?"timeSpan":""}>{item.time_ago}</span>
{item.status === 1 && <span className="invisable-read" onClick={readNotice(item.id)}>标记为已读</span>} {item.status === 1 && <span className="invisable-read" onClick={()=>readNotice([item.id])}>标记为已读</span>}
</div> </div>
</div> </div>
) )
@ -158,7 +264,7 @@ function MyNotice(props) {
<div className="mynotice-content vertical-center-style" key={item.id}> <div className="mynotice-content vertical-center-style" key={item.id}>
<div className="mynotice-cont vertical-center-style"> <div className="mynotice-cont vertical-center-style">
{/* <input type="checkbox" className={isBatchDelete ? 'atme-checkbox' : 'invisible'} onChange={onChange} /> */} {/* <input type="checkbox" className={isBatchDelete ? 'atme-checkbox' : 'invisible'} onChange={onChange} /> */}
<Checkbox className="atme-checkbox" value={item.id} key={item.id}></Checkbox> <Checkbox value={item.id} className={isBatchDelete ? 'visible-checkbox' : 'invisible-checkbox'} onChange={onChange} checked={item.checkedBatch}></Checkbox>
<img src={`https://testforgeplus.trustie.net//${item.sender.image_url}`} className="currentImg" /> <img src={`https://testforgeplus.trustie.net//${item.sender.image_url}`} className="currentImg" />
<span className="at-length highlightSpan"> <span className="at-length highlightSpan">
{item.status === 1 ? <Badge color="#FA2020" className="at-badge" /> : <span className="system-notice-blank"></span>} {item.status === 1 ? <Badge color="#FA2020" className="at-badge" /> : <span className="system-notice-blank"></span>}
@ -166,13 +272,29 @@ function MyNotice(props) {
</span> </span>
</div> </div>
<div className="mynotice-cont vertical-center-style"> <div className="mynotice-cont vertical-center-style">
<span className="timeSpan">{item.time_ago}</span> <span className={item.status === 1?"timeSpan":""}>{item.time_ago}</span>
<a>标记为已读</a>&nbsp;&nbsp;&nbsp;<a className="float-left-little" onClick={deleteNotice}>删除</a> {item.status === 1 && <span className="invisable-read" onClick={()=>readNotice([item.id])}>标记为已读</span>}&nbsp;&nbsp;&nbsp;
<span className="invisable-read" onClick={()=>deleteNotice([item.id])}>删除</span>
</div> </div>
</div> </div>
) )
} }
})}</Checkbox.Group> })}
{/* 私信 */}
{/* <div className="mynotice-content vertical-center-style">
<Badge count={95}><img src="https://testforgeplus.trustie.net//system/lets/letter_avatars/2/D/208_124_118/120.png" className="currentImg private-letter-img" /></Badge>
<div className="private-letter-right">
<div>
<span>蒋宇航</span>
<span className="timeSpan">4分钟前</span>
<a onClick={deleteNotice}>删除</a>
</div>
<div onClick={() => props.history.push('/settings/notice/privateLetter')}>
<span className="highlightSpan letter-length-limit">最好的OpenStack控制台对标OpenStack社区Horizon项目,最好的OpenStack控制台对标OpenStack社区Horizon项目在易用性页面性能等方面进行深度优化提供简单控制台</span>
</div>
</div>
</div> */}
</div> </div>
) )
} }

View File

@ -6,7 +6,7 @@
} }
.ant-menu-item{ .ant-menu-item{
padding:0px; padding:0px;
// margin-right:34px!important; margin-right:34px!important;
height: 34px; height: 34px;
width: 64px; width: 64px;
text-align: center; text-align: center;
@ -129,9 +129,12 @@ button:active {
.mynotice-cont{ .mynotice-cont{
padding:0; padding:0;
& .atme-checkbox{ & .visible-checkbox{
margin-right: 10px; margin-right: 10px;
} }
& .invisible-checkbox{
display: none;
}
} }
& .ant-badge-count, .ant-badge-dot, .ant-badge .ant-scroll-number-custom-component { & .ant-badge-count, .ant-badge-dot, .ant-badge .ant-scroll-number-custom-component {
@ -197,7 +200,7 @@ button:active {
.at-length{ .at-length{
max-width: 48rem; max-width: 48rem;
margin-left: 18px; margin-left: 12px;
} }
#numberSpan{ #numberSpan{
color: #466AFF; color: #466AFF;
@ -212,14 +215,14 @@ button:active {
margin-right: 10px; margin-right: 10px;
} }
.invisible_checkGroup{ // .invisible_checkGroup{
& .ant-checkbox-inner{ // & .ant-checkbox-inner{
display: none; // display: none;
} // }
} // }
.notice01{ // .notice01{
& .ant-checkbox-group{ // & .ant-checkbox-group{
display: flex; // display: flex;
flex-direction: column; // flex-direction: column;
} // }
} // }