站内信消息通知

This commit is contained in:
xixi 2024-08-13 18:06:34 +08:00
parent a635255bad
commit 1383c70817
4 changed files with 433 additions and 6 deletions

View 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>
)
}

View File

@ -0,0 +1,6 @@
.noticeSearch{
display: flex;
/* background-color: pink; */
justify-content: space-between;
margin-bottom: 10px;
}

View File

@ -3,7 +3,7 @@ import { useDispatch } from 'react-redux'
import BalanceHead from '../../components/balance/BalanceHead.tsx';
import RechargeHead from '../../components/recharge/RechargeHead.tsx';
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 { put, get, post } from "../../util/AjaxUtils.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 inv from '../../static/inv.png'
import MyOrder from '../../components/myOrder/MyOrder.tsx'
import NoticeModal from '../../components/NoticeModal/NoticeModal.tsx';
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 [isLoading,setisLoading] = useState(false)
const [isLoading, setisLoading] = useState(false)
// 解除绑定邀请码弹窗
// const [relieveModal, setRelieveModal] = useState(false)
// 申请的邀请码
@ -271,9 +289,9 @@ export default function Head() {
}
});
}, [globalContext.user]);
// useEffect(()=>{
// getIc()
// },[])
useEffect(()=>{
getUnRead()
},[])
const items: MenuProps['items'] = [
{
key: 'userinfo',
@ -403,6 +421,14 @@ export default function Head() {
<QuestionCircleOutlined />
</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/>*/}
<div style={{ display: 'flex', alignContent: 'center', padding: '0', cursor: 'pointer' }}>
<div style={{ width: '50px', height: '50px', borderRadius: '25px', marginLeft: '', marginRight: '10px' }} >
@ -682,6 +708,20 @@ export default function Head() {
}}>
<MyOrder></MyOrder>
</Modal>
<Modal title="消息通知"
footer={null}
destroyOnClose
open={noticeModal}
width={1200}
onCancel={() => {
setNoticeModal(false)
getUnRead()
// setUnRead(0)
}}>
<NoticeModal></NoticeModal>
</Modal>
<Spin tip="正在提交..." spinning={loading} fullscreen />
{contextHolder}
{modalHolder}

View File

@ -286,4 +286,24 @@
background-color: rgb(218, 218, 218);
margin-left: 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;
}