站内信消息通知
This commit is contained in:
parent
a635255bad
commit
1383c70817
361
src/components/NoticeModal/NoticeModal.tsx
Normal file
361
src/components/NoticeModal/NoticeModal.tsx
Normal file
@ -0,0 +1,361 @@
|
|||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import './noticeModal.css'
|
||||||
|
import { get, put,del } from '../../util/AjaxUtils'
|
||||||
|
import {
|
||||||
|
Table,
|
||||||
|
// Pagination,
|
||||||
|
Select,
|
||||||
|
Button,
|
||||||
|
Input,
|
||||||
|
message,
|
||||||
|
Spin
|
||||||
|
} from 'antd';
|
||||||
|
import type { TableColumnsType } from 'antd';
|
||||||
|
import {
|
||||||
|
MailOutlined,
|
||||||
|
MailFilled
|
||||||
|
} from '@ant-design/icons';
|
||||||
|
const { Search } = Input;
|
||||||
|
interface DataType {
|
||||||
|
// key: React.Key;
|
||||||
|
// title: string;
|
||||||
|
// time: string;
|
||||||
|
// type: string;
|
||||||
|
// orderId: number;
|
||||||
|
// status: boolean
|
||||||
|
content: string;
|
||||||
|
gmtCreate: string;
|
||||||
|
title: string;
|
||||||
|
userMsgId: string;
|
||||||
|
isRead: number
|
||||||
|
}
|
||||||
|
export default function NoticeModal() {
|
||||||
|
const [messageApi, contextHolder] = message.useMessage();
|
||||||
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
|
const columns: TableColumnsType<DataType> = [
|
||||||
|
{
|
||||||
|
title: '序号',
|
||||||
|
dataIndex: 'index',
|
||||||
|
align: 'center',
|
||||||
|
width: 80,
|
||||||
|
render: (text, record, index) =>(page - 1)*10 + index + 1, // 显示序号,从1开始
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: <div title='站内信' style={{cursor:'pointer'}}>站内信</div>,
|
||||||
|
dataIndex: 'content',
|
||||||
|
// align: 'center',
|
||||||
|
render: (text: string, record: DataType) => <div style={{
|
||||||
|
cursor: 'pointer', color: record.isRead ? '#b9b9b9' : '', textAlign: 'left',
|
||||||
|
// overflow: 'hidden', // 隐藏超出容器的内容
|
||||||
|
// textOverflow: 'ellipsis', // 使用省略号表示被截断的内容
|
||||||
|
// whiteSpace: 'nowrap', // 防止文本换行
|
||||||
|
}} onClick={() => {
|
||||||
|
// alert('一度')
|
||||||
|
|
||||||
|
// console.log(record.isRead);
|
||||||
|
// console.log(record.userMsgId);
|
||||||
|
if (!record.isRead) {
|
||||||
|
put<any>({
|
||||||
|
messageApi,
|
||||||
|
url: `/api/user-msg/update-read/self`,
|
||||||
|
body: {
|
||||||
|
ids: [record.userMsgId]
|
||||||
|
},
|
||||||
|
onBefore() {
|
||||||
|
|
||||||
|
},
|
||||||
|
onSuccess(data) {
|
||||||
|
console.log(data);
|
||||||
|
getNoticeData()
|
||||||
|
},
|
||||||
|
onFinally() {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}}>
|
||||||
|
{record.isRead ? <MailOutlined style={{ marginRight: '8px' }} /> : <MailFilled style={{ marginRight: '8px' }} />}
|
||||||
|
{text}
|
||||||
|
</div>,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
title: '消息类型',
|
||||||
|
dataIndex: 'title',
|
||||||
|
align: 'center',
|
||||||
|
width: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '接收时间',
|
||||||
|
dataIndex: 'gmtCreate',
|
||||||
|
align: 'center',
|
||||||
|
width: 180
|
||||||
|
},
|
||||||
|
|
||||||
|
];
|
||||||
|
// 搜索条件
|
||||||
|
//类型 已读1 未读 0
|
||||||
|
const [isRead, setIsRead] = useState('')
|
||||||
|
//关键字
|
||||||
|
const [keywords, setKeywords] = useState('')
|
||||||
|
|
||||||
|
// 分页
|
||||||
|
const [page, setPage] = useState(1)
|
||||||
|
// 数据总数
|
||||||
|
const [total, setTotal] = useState(0)
|
||||||
|
// 被选中的消息数组
|
||||||
|
const [selectArray, setSelectArray] = useState<any[]>([])
|
||||||
|
// 被选中的消息id数组
|
||||||
|
const [ids, setIds] = useState<string[]>([])
|
||||||
|
const [selectedRowKeys, setSelectedRowKeys] = useState<any[]>([]); // 选中的行键
|
||||||
|
const [data, setData] = useState<DataType[]>([
|
||||||
|
// {
|
||||||
|
// orderId: 111,
|
||||||
|
// title: '消息1',
|
||||||
|
// time: '2024-08-12 12:56:35',
|
||||||
|
// type: '类型1',
|
||||||
|
// status: true
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// orderId: 222,
|
||||||
|
// title: '消息2',
|
||||||
|
// time: '2024-08-12 12:56:35',
|
||||||
|
// type: '类型2',
|
||||||
|
// status: false
|
||||||
|
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// orderId: 333,
|
||||||
|
// title: '消息3嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻',
|
||||||
|
// time: '2024-08-12 12:56:35',
|
||||||
|
// type: '类型3',
|
||||||
|
// status: false
|
||||||
|
// },
|
||||||
|
])
|
||||||
|
// 获取消息列表
|
||||||
|
const getNoticeData = () => {
|
||||||
|
get<any>({
|
||||||
|
messageApi,
|
||||||
|
url: '/api/user-msg/listpage-simple/self',
|
||||||
|
config: {
|
||||||
|
params: {
|
||||||
|
page: page,
|
||||||
|
rows: 10,
|
||||||
|
isRead: isRead ? isRead : '',
|
||||||
|
keywords: keywords ? keywords : ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onBefore() {
|
||||||
|
setIsLoading(true);
|
||||||
|
},
|
||||||
|
onSuccess({ data }) {
|
||||||
|
console.log(data);
|
||||||
|
|
||||||
|
setData(data.rows)
|
||||||
|
setTotal(data.total)
|
||||||
|
},
|
||||||
|
onFinally() {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// const data: DataType[] = [
|
||||||
|
// {
|
||||||
|
// orderId: 111,
|
||||||
|
// title: '消息1',
|
||||||
|
// time: '2024-08-12 12:56:35',
|
||||||
|
// type: '类型1',
|
||||||
|
// status: true
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// orderId: 222,
|
||||||
|
// title: '消息2',
|
||||||
|
// time: '2024-08-12 12:56:35',
|
||||||
|
// type: '类型2',
|
||||||
|
// status: false
|
||||||
|
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// orderId: 333,
|
||||||
|
// title: '消息3',
|
||||||
|
// time: '2024-08-12 12:56:35',
|
||||||
|
// type: '类型3',
|
||||||
|
// status: false
|
||||||
|
// },
|
||||||
|
// ];
|
||||||
|
// const isButtonDisabled = !data.some(item => item.status == false);
|
||||||
|
// 输入关键字搜索
|
||||||
|
const handleSearch = (value: string) => {
|
||||||
|
// console.log(value);
|
||||||
|
setKeywords(value)
|
||||||
|
}
|
||||||
|
// 当删除所有关键字时
|
||||||
|
const handleChange = (e: any) => {
|
||||||
|
// console.log(e.target.value);
|
||||||
|
if (e.target.value == '') {
|
||||||
|
// 如果删除所有发起请求重新取列表
|
||||||
|
// alert('重新获取')
|
||||||
|
setKeywords('')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 点击删除按钮
|
||||||
|
const Delete = () => {
|
||||||
|
// const deleteIds:any = ids.join('/')
|
||||||
|
del<any>({
|
||||||
|
messageApi,
|
||||||
|
url: `api/user-msg/remove/self/${ ids.join('_')}`,
|
||||||
|
onSuccess() {
|
||||||
|
messageApi.open({
|
||||||
|
type: 'success',
|
||||||
|
content: '已删除'
|
||||||
|
})
|
||||||
|
getNoticeData()
|
||||||
|
init()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//恢复无内容被选中状态
|
||||||
|
const init = () => {
|
||||||
|
setSelectedRowKeys([]);
|
||||||
|
setSelectArray([])
|
||||||
|
setIds([])
|
||||||
|
}
|
||||||
|
// 标记为已读
|
||||||
|
const Read = () => {
|
||||||
|
put<any>({
|
||||||
|
messageApi,
|
||||||
|
url: `/api/user-msg/update-read/self`,
|
||||||
|
body: {
|
||||||
|
ids: ids
|
||||||
|
},
|
||||||
|
onBefore() {
|
||||||
|
|
||||||
|
},
|
||||||
|
onSuccess(data) {
|
||||||
|
console.log(data);
|
||||||
|
getNoticeData()
|
||||||
|
init()
|
||||||
|
},
|
||||||
|
onFinally() {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 全部已读
|
||||||
|
const ReadAll = () => {
|
||||||
|
// setData(data.map(item => ({ ...item, status: true }))); //将所有false改为true
|
||||||
|
// console.log(data.map(item => item.orderId)); //所有的id数组
|
||||||
|
// console.log(data.filter(item => !item.status).map(item => item.orderId)); //未读的id数组
|
||||||
|
put<any>({
|
||||||
|
messageApi,
|
||||||
|
url: `/api/user-msg/update-read-all/self`,
|
||||||
|
body: {
|
||||||
|
|
||||||
|
},
|
||||||
|
onBefore() {
|
||||||
|
|
||||||
|
},
|
||||||
|
onSuccess(data) {
|
||||||
|
console.log(data);
|
||||||
|
getNoticeData()
|
||||||
|
init()
|
||||||
|
},
|
||||||
|
onFinally() {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 选择(多选)项目
|
||||||
|
const rowSelection = {
|
||||||
|
selectedRowKeys,
|
||||||
|
onChange: (selectedRowKeys: React.Key[], selectedRows: DataType[]) => {
|
||||||
|
console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
|
||||||
|
const selectedOrderIds = selectedRows.map(row => row.userMsgId);
|
||||||
|
// Array.isArray()
|
||||||
|
// console.log(Array.isArray(selectedOrderIds));
|
||||||
|
setSelectedRowKeys(selectedRowKeys);
|
||||||
|
setSelectArray(selectedRowKeys);
|
||||||
|
console.log(`selectedOrderIds: ${selectedOrderIds}`);
|
||||||
|
setIds(selectedOrderIds)
|
||||||
|
setSelectArray(selectedRows)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
useEffect(() => {
|
||||||
|
getNoticeData()
|
||||||
|
}, [page, isRead, keywords])
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{contextHolder}
|
||||||
|
<Spin tip="加载中..." spinning={isLoading}>
|
||||||
|
<div className='noticeSearch'>
|
||||||
|
<Select
|
||||||
|
// value={}
|
||||||
|
style={{ height: '31px', width: '70px' }}
|
||||||
|
onChange={(value: string) => {
|
||||||
|
// console.log(value);
|
||||||
|
setIsRead(value)
|
||||||
|
}}
|
||||||
|
options={[
|
||||||
|
{ value: '', label: '全部' },
|
||||||
|
{ value: '1', label: '已读' },
|
||||||
|
{ value: '0', label: '未读' },
|
||||||
|
]}
|
||||||
|
defaultValue={''}
|
||||||
|
// placeholder='选择类型'
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
<Button type="primary" disabled={selectArray.length > 0 ? false : true} onClick={() => {
|
||||||
|
Delete()
|
||||||
|
}}>删除</Button>
|
||||||
|
<Button type="primary" disabled={selectArray.length > 0 ? false : true} onClick={() => {
|
||||||
|
Read()
|
||||||
|
}} style={{ marginLeft: 10 }}>标记为已读</Button>
|
||||||
|
<Button type="primary"
|
||||||
|
// disabled={isButtonDisabled} // 根据状态设置按钮是否禁用
|
||||||
|
onClick={() => {
|
||||||
|
ReadAll()
|
||||||
|
|
||||||
|
}} style={{ marginLeft: 10 }}>全部标记为已读</Button>
|
||||||
|
<Search placeholder="输入消息标题"
|
||||||
|
// value={nowKeyword}
|
||||||
|
onSearch={handleSearch}
|
||||||
|
onChange={handleChange}
|
||||||
|
style={{
|
||||||
|
width: '200px',
|
||||||
|
height: '31px',
|
||||||
|
marginLeft: 10
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Table
|
||||||
|
rowSelection={{
|
||||||
|
...rowSelection,
|
||||||
|
}}
|
||||||
|
columns={columns}
|
||||||
|
dataSource={data}
|
||||||
|
pagination={
|
||||||
|
{
|
||||||
|
pageSize: 10,
|
||||||
|
total: total,
|
||||||
|
onChange: (currentPage) => {
|
||||||
|
setPage(currentPage);
|
||||||
|
},
|
||||||
|
showSizeChanger: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scroll={{ y: 500 }} bordered key="dataTable" rowKey="userMsgId"
|
||||||
|
/>
|
||||||
|
{/* defaultCurrent: 默认当前页数 total:数据总数 defaultPageSize:'页面显示几条' */}
|
||||||
|
{/* <div className='product-release-pagination' >
|
||||||
|
<Pagination
|
||||||
|
showSizeChanger={false}
|
||||||
|
defaultCurrent={1} total={10} defaultPageSize={10} onChange={(page) => {
|
||||||
|
console.log(page)
|
||||||
|
}} />
|
||||||
|
</div> */}
|
||||||
|
</Spin>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
6
src/components/NoticeModal/noticeModal.css
Normal file
6
src/components/NoticeModal/noticeModal.css
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
.noticeSearch{
|
||||||
|
display: flex;
|
||||||
|
/* background-color: pink; */
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
@ -3,7 +3,7 @@ import { useDispatch } from 'react-redux'
|
|||||||
import BalanceHead from '../../components/balance/BalanceHead.tsx';
|
import BalanceHead from '../../components/balance/BalanceHead.tsx';
|
||||||
import RechargeHead from '../../components/recharge/RechargeHead.tsx';
|
import RechargeHead from '../../components/recharge/RechargeHead.tsx';
|
||||||
import { Dropdown, MenuProps, message, Modal, Space, Spin, Input } from "antd";
|
import { Dropdown, MenuProps, message, Modal, Space, Spin, Input } from "antd";
|
||||||
import { DownOutlined, UserOutlined, QuestionCircleOutlined,KeyOutlined, LogoutOutlined, AccountBookOutlined, ContainerOutlined, MenuFoldOutlined, UsergroupAddOutlined } from "@ant-design/icons";
|
import { DownOutlined, UserOutlined, QuestionCircleOutlined, BellOutlined, KeyOutlined, LogoutOutlined, AccountBookOutlined, ContainerOutlined, MenuFoldOutlined, UsergroupAddOutlined } from "@ant-design/icons";
|
||||||
import { useContext, useEffect, useState } from "react";
|
import { useContext, useEffect, useState } from "react";
|
||||||
import { put, get, post } from "../../util/AjaxUtils.ts";
|
import { put, get, post } from "../../util/AjaxUtils.ts";
|
||||||
import { GlobalContext, GlobalDispatchContext, reloadUser } from "../../context/GlobalContext.ts";
|
import { GlobalContext, GlobalDispatchContext, reloadUser } from "../../context/GlobalContext.ts";
|
||||||
@ -19,11 +19,29 @@ import BelongPeople from '../../components/BelongPeople/BelongPeople.tsx'
|
|||||||
import ContactPeople from '../../components/ContactPeople/ContactPeople.tsx'
|
import ContactPeople from '../../components/ContactPeople/ContactPeople.tsx'
|
||||||
import inv from '../../static/inv.png'
|
import inv from '../../static/inv.png'
|
||||||
import MyOrder from '../../components/myOrder/MyOrder.tsx'
|
import MyOrder from '../../components/myOrder/MyOrder.tsx'
|
||||||
|
import NoticeModal from '../../components/NoticeModal/NoticeModal.tsx';
|
||||||
export default function Head() {
|
export default function Head() {
|
||||||
|
|
||||||
|
// 消息通知弹窗
|
||||||
|
const [noticeModal, setNoticeModal] = useState(false)
|
||||||
|
// 未读消息数
|
||||||
|
const [unRead, setUnRead] = useState(0)
|
||||||
|
// 获取未读消息总数
|
||||||
|
const getUnRead = () => {
|
||||||
|
get<any>({
|
||||||
|
messageApi,
|
||||||
|
url: '/api/user-msg/count-un-read/self',
|
||||||
|
onSuccess({ data }) {
|
||||||
|
console.log(data);
|
||||||
|
setUnRead(data.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 邀请码弹窗
|
// 邀请码弹窗
|
||||||
const [invitationModal, setinvitationModal] = useState(false)
|
const [invitationModal, setinvitationModal] = useState(false)
|
||||||
// 邀请码弹窗加载
|
// 邀请码弹窗加载
|
||||||
const [isLoading,setisLoading] = useState(false)
|
const [isLoading, setisLoading] = useState(false)
|
||||||
// 解除绑定邀请码弹窗
|
// 解除绑定邀请码弹窗
|
||||||
// const [relieveModal, setRelieveModal] = useState(false)
|
// const [relieveModal, setRelieveModal] = useState(false)
|
||||||
// 申请的邀请码
|
// 申请的邀请码
|
||||||
@ -271,9 +289,9 @@ export default function Head() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, [globalContext.user]);
|
}, [globalContext.user]);
|
||||||
// useEffect(()=>{
|
useEffect(()=>{
|
||||||
// getIc()
|
getUnRead()
|
||||||
// },[])
|
},[])
|
||||||
const items: MenuProps['items'] = [
|
const items: MenuProps['items'] = [
|
||||||
{
|
{
|
||||||
key: 'userinfo',
|
key: 'userinfo',
|
||||||
@ -403,6 +421,14 @@ export default function Head() {
|
|||||||
<QuestionCircleOutlined />
|
<QuestionCircleOutlined />
|
||||||
</div>
|
</div>
|
||||||
<div className='headLine'></div>
|
<div className='headLine'></div>
|
||||||
|
<div className='head-notice' onClick={() => {
|
||||||
|
setNoticeModal(true)
|
||||||
|
}}>
|
||||||
|
<BellOutlined />
|
||||||
|
<div className='noticeNum' style={{display:unRead == 0?'none':'block'}}>{unRead}</div>
|
||||||
|
</div>
|
||||||
|
<div className='headLine'></div>
|
||||||
|
|
||||||
{/*<MessageHead/>*/}
|
{/*<MessageHead/>*/}
|
||||||
<div style={{ display: 'flex', alignContent: 'center', padding: '0', cursor: 'pointer' }}>
|
<div style={{ display: 'flex', alignContent: 'center', padding: '0', cursor: 'pointer' }}>
|
||||||
<div style={{ width: '50px', height: '50px', borderRadius: '25px', marginLeft: '', marginRight: '10px' }} >
|
<div style={{ width: '50px', height: '50px', borderRadius: '25px', marginLeft: '', marginRight: '10px' }} >
|
||||||
@ -682,6 +708,20 @@ export default function Head() {
|
|||||||
}}>
|
}}>
|
||||||
<MyOrder></MyOrder>
|
<MyOrder></MyOrder>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
<Modal title="消息通知"
|
||||||
|
footer={null}
|
||||||
|
|
||||||
|
destroyOnClose
|
||||||
|
open={noticeModal}
|
||||||
|
|
||||||
|
width={1200}
|
||||||
|
onCancel={() => {
|
||||||
|
setNoticeModal(false)
|
||||||
|
getUnRead()
|
||||||
|
// setUnRead(0)
|
||||||
|
}}>
|
||||||
|
<NoticeModal></NoticeModal>
|
||||||
|
</Modal>
|
||||||
<Spin tip="正在提交..." spinning={loading} fullscreen />
|
<Spin tip="正在提交..." spinning={loading} fullscreen />
|
||||||
{contextHolder}
|
{contextHolder}
|
||||||
{modalHolder}
|
{modalHolder}
|
||||||
|
@ -286,4 +286,24 @@
|
|||||||
background-color: rgb(218, 218, 218);
|
background-color: rgb(218, 218, 218);
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
.head-notice{
|
||||||
|
color: #f78e4c;
|
||||||
|
font-size: 28px;
|
||||||
|
/* background-color: pink; */
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.noticeNum{
|
||||||
|
top: 0;
|
||||||
|
left: 15px;
|
||||||
|
position: absolute;
|
||||||
|
width: 28px;
|
||||||
|
height: 20px;
|
||||||
|
background-color: #f78e4c;
|
||||||
|
border-radius: 10px;
|
||||||
|
color: white;
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user