feat(notify): 添加消息记录管理功能
- 新增 NotifyMessageRecordList 组件实现消息记录列表功能 - 在 NotificationMessage 组件中更新路由跳转至新的消息记录页面 - 添加消息记录相关国际化配置项 - 创建独立的消息记录页面组件 - 更新 BoxProductList 组件中的 actionRef 引用管理 - 优化消息记录列表的搜索和筛选功能 - 实现消息点击自动标记已读功能 - 添加消息记录的详细信息查看功能
This commit is contained in:
parent
f183da70ee
commit
33b46abc27
@ -210,6 +210,7 @@ export default function BoxProductList(props: IBoxProductListProps) {
|
|||||||
>[];
|
>[];
|
||||||
|
|
||||||
const actionRef = useRef<ActionType>();
|
const actionRef = useRef<ActionType>();
|
||||||
|
const actionBrandRef = useRef<ActionType>();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BizContainer<
|
<BizContainer<
|
||||||
@ -263,6 +264,7 @@ export default function BoxProductList(props: IBoxProductListProps) {
|
|||||||
status
|
status
|
||||||
drag={{
|
drag={{
|
||||||
fieldProps: {
|
fieldProps: {
|
||||||
|
actionRef: actionRef,
|
||||||
tableRender: (_, defaultDom) => (
|
tableRender: (_, defaultDom) => (
|
||||||
<RouteContext.Consumer>
|
<RouteContext.Consumer>
|
||||||
{(value: RouteContextType) => {
|
{(value: RouteContextType) => {
|
||||||
@ -296,12 +298,12 @@ export default function BoxProductList(props: IBoxProductListProps) {
|
|||||||
ghost={true}
|
ghost={true}
|
||||||
search={false}
|
search={false}
|
||||||
onValueChange={() => {
|
onValueChange={() => {
|
||||||
actionRef.current?.reload();
|
actionBrandRef.current?.reload();
|
||||||
}}
|
}}
|
||||||
/>,
|
/>,
|
||||||
],
|
],
|
||||||
}}
|
}}
|
||||||
actionRef={actionRef}
|
actionRef={actionBrandRef}
|
||||||
ghost={true}
|
ghost={true}
|
||||||
params={boxBrandParams}
|
params={boxBrandParams}
|
||||||
grid={{ column: 1 }}
|
grid={{ column: 1 }}
|
||||||
@ -378,7 +380,7 @@ export default function BoxProductList(props: IBoxProductListProps) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
actionRef.current?.reload();
|
actionBrandRef.current?.reload();
|
||||||
}}
|
}}
|
||||||
checkedChildren={intl.formatMessage({
|
checkedChildren={intl.formatMessage({
|
||||||
id:
|
id:
|
||||||
@ -402,6 +404,10 @@ export default function BoxProductList(props: IBoxProductListProps) {
|
|||||||
ghost={true}
|
ghost={true}
|
||||||
search={false}
|
search={false}
|
||||||
brandId={item.brandId}
|
brandId={item.brandId}
|
||||||
|
onValueChange={() => {
|
||||||
|
actionBrandRef.current?.reload();
|
||||||
|
actionRef.current?.reload();
|
||||||
|
}}
|
||||||
trigger={() => {
|
trigger={() => {
|
||||||
return <Button type="link">编辑</Button>;
|
return <Button type="link">编辑</Button>;
|
||||||
}}
|
}}
|
||||||
@ -412,6 +418,10 @@ export default function BoxProductList(props: IBoxProductListProps) {
|
|||||||
ghost={true}
|
ghost={true}
|
||||||
search={false}
|
search={false}
|
||||||
brandId={item.brandId}
|
brandId={item.brandId}
|
||||||
|
onValueChange={() => {
|
||||||
|
actionBrandRef.current?.reload();
|
||||||
|
actionRef.current?.reload();
|
||||||
|
}}
|
||||||
trigger={() => {
|
trigger={() => {
|
||||||
return <Button type="link">删除</Button>;
|
return <Button type="link">删除</Button>;
|
||||||
}}
|
}}
|
||||||
@ -442,6 +452,9 @@ export default function BoxProductList(props: IBoxProductListProps) {
|
|||||||
mode={'create'}
|
mode={'create'}
|
||||||
ghost={true}
|
ghost={true}
|
||||||
search={false}
|
search={false}
|
||||||
|
onValueChange={() => {
|
||||||
|
actionBrandRef.current?.reload();
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</ProCard>
|
</ProCard>
|
||||||
|
|||||||
@ -80,13 +80,13 @@ const NotificationMessage: React.FC<NotificationMessageProps> = ({
|
|||||||
markAsRead(item.messageReceiverId);
|
markAsRead(item.messageReceiverId);
|
||||||
}
|
}
|
||||||
// 可以跳转到消息详情页面
|
// 可以跳转到消息详情页面
|
||||||
// history.push(`/message/detail/${item.messageReceiverId}`);
|
// history.push(`/operation/settings/notify/message-record`);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 查看更多消息
|
// 查看更多消息
|
||||||
const handleViewMore = () => {
|
const handleViewMore = () => {
|
||||||
setDropdownOpen(false);
|
setDropdownOpen(false);
|
||||||
history.push('/message');
|
history.push('/operation/settings/notify/message-record');
|
||||||
};
|
};
|
||||||
|
|
||||||
// 下拉菜单内容
|
// 下拉菜单内容
|
||||||
|
|||||||
@ -0,0 +1,163 @@
|
|||||||
|
import { BizContainer, BizValueType, ModeType } from '@/components';
|
||||||
|
import { business } from '@/services';
|
||||||
|
import { useIntl } from '@@/exports';
|
||||||
|
import { ActionType, ProColumns } from '@ant-design/pro-components';
|
||||||
|
import { ProDescriptionsItemProps } from '@ant-design/pro-descriptions';
|
||||||
|
import { Tag } from 'antd';
|
||||||
|
import React, { useRef } from 'react';
|
||||||
|
|
||||||
|
interface INotifyMessageRecordListProps {
|
||||||
|
ghost?: boolean;
|
||||||
|
search?: boolean;
|
||||||
|
onValueChange?: () => void;
|
||||||
|
mode?: ModeType;
|
||||||
|
trigger?: () => React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function NotifyMessageRecordList(
|
||||||
|
props: INotifyMessageRecordListProps,
|
||||||
|
) {
|
||||||
|
const {
|
||||||
|
ghost = false,
|
||||||
|
search = true,
|
||||||
|
mode = 'page',
|
||||||
|
trigger,
|
||||||
|
onValueChange,
|
||||||
|
} = props;
|
||||||
|
const intl = useIntl();
|
||||||
|
const intlPrefix = 'notifyMessageRecord';
|
||||||
|
const actionRef = useRef<ActionType>();
|
||||||
|
|
||||||
|
// 是否已读状态映射
|
||||||
|
const isReadMap: Record<string, { text: string; color: string }> = {
|
||||||
|
false: {
|
||||||
|
text: intl.formatMessage({ id: intlPrefix + '.status.unread' }),
|
||||||
|
color: 'red',
|
||||||
|
},
|
||||||
|
true: {
|
||||||
|
text: intl.formatMessage({ id: intlPrefix + '.status.read' }),
|
||||||
|
color: 'default',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const columns: ProColumns<BusinessAPI.MessageReceiverVO, BizValueType>[] = [
|
||||||
|
{
|
||||||
|
title: intl.formatMessage({ id: intlPrefix + '.column.title' }),
|
||||||
|
dataIndex: ['messageVO', 'title'],
|
||||||
|
key: 'messageId',
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: intl.formatMessage({ id: intlPrefix + '.column.content' }),
|
||||||
|
dataIndex: ['messageVO', 'content'],
|
||||||
|
key: 'content',
|
||||||
|
ellipsis: true,
|
||||||
|
hideInTable: true, // 内容较长,在表格中隐藏,只在详情中显示
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: intl.formatMessage({ id: intlPrefix + '.column.isRead' }),
|
||||||
|
dataIndex: 'isRead',
|
||||||
|
key: 'isRead',
|
||||||
|
valueType: 'select',
|
||||||
|
valueEnum: {
|
||||||
|
true: {
|
||||||
|
text: isReadMap.true.text,
|
||||||
|
status: 'Default',
|
||||||
|
},
|
||||||
|
false: {
|
||||||
|
text: isReadMap.false.text,
|
||||||
|
status: 'Error',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
render: (_, record) => {
|
||||||
|
const isRead = record.isRead ? 'true' : 'false';
|
||||||
|
const isReadInfo = isReadMap[isRead];
|
||||||
|
return <Tag color={isReadInfo.color}>{isReadInfo.text}</Tag>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: intl.formatMessage({ id: intlPrefix + '.column.readAt' }),
|
||||||
|
dataIndex: 'readAt',
|
||||||
|
key: 'readAt',
|
||||||
|
valueType: 'dateTime',
|
||||||
|
search: false,
|
||||||
|
hideInTable: true, // 已读时间通常不显示在列表中
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: intl.formatMessage({ id: intlPrefix + '.column.createdAt' }),
|
||||||
|
dataIndex: 'createdAt',
|
||||||
|
key: 'createdAt',
|
||||||
|
valueType: 'dateTime',
|
||||||
|
search: false,
|
||||||
|
sorter: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const detailColumns: ProDescriptionsItemProps<
|
||||||
|
BusinessAPI.MessageReceiverVO,
|
||||||
|
BizValueType
|
||||||
|
>[] = columns as ProDescriptionsItemProps<
|
||||||
|
BusinessAPI.MessageReceiverVO,
|
||||||
|
BizValueType
|
||||||
|
>[];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BizContainer<
|
||||||
|
typeof business.messageReceiver,
|
||||||
|
BusinessAPI.MessageReceiverVO,
|
||||||
|
BusinessAPI.MessageReceiverPageQry
|
||||||
|
>
|
||||||
|
rowKey={'messageReceiverId'}
|
||||||
|
permission={'operation-notify-message-record'}
|
||||||
|
func={business.messageReceiver}
|
||||||
|
method={'messageReceiver'}
|
||||||
|
methodUpper={'MessageReceiver'}
|
||||||
|
intlPrefix={intlPrefix}
|
||||||
|
modeType={mode}
|
||||||
|
onValueChange={onValueChange}
|
||||||
|
container={{ ghost }}
|
||||||
|
actionRef={actionRef}
|
||||||
|
status={false}
|
||||||
|
page={{
|
||||||
|
fieldProps: {
|
||||||
|
bordered: true,
|
||||||
|
ghost,
|
||||||
|
// @ts-ignore
|
||||||
|
search,
|
||||||
|
pagination: {
|
||||||
|
defaultPageSize: 20,
|
||||||
|
showSizeChanger: true,
|
||||||
|
showQuickJumper: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
columns,
|
||||||
|
options: () => [],
|
||||||
|
// 自定义行点击事件,点击消息自动标记已读
|
||||||
|
onRow: (record: any) => ({
|
||||||
|
onClick: async () => {
|
||||||
|
// 如果未读,标记为已读
|
||||||
|
if (!record.isRead) {
|
||||||
|
try {
|
||||||
|
await business.messageReceiver.markReadMessageReceiver({
|
||||||
|
messageReceiverId: record.messageReceiverId,
|
||||||
|
});
|
||||||
|
actionRef.current?.reload();
|
||||||
|
onValueChange?.();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('标记已读失败:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}}
|
||||||
|
create={false}
|
||||||
|
update={false}
|
||||||
|
destroy={false}
|
||||||
|
detail={{
|
||||||
|
formType: 'drawer',
|
||||||
|
columns: detailColumns,
|
||||||
|
trigger,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -27,9 +27,6 @@ const variables = [
|
|||||||
'车次号',
|
'车次号',
|
||||||
'车牌号',
|
'车牌号',
|
||||||
'目的地',
|
'目的地',
|
||||||
'利润金额',
|
|
||||||
'瓜农姓名',
|
|
||||||
'瓜农货款',
|
|
||||||
'录入员姓名',
|
'录入员姓名',
|
||||||
'录入员提审时间',
|
'录入员提审时间',
|
||||||
// 采购单审核
|
// 采购单审核
|
||||||
|
|||||||
@ -1,2 +1,3 @@
|
|||||||
export { default as NotificationMessage } from './NotificationMessage';
|
export { default as NotificationMessage } from './NotificationMessage';
|
||||||
|
export { default as NotifyMessageRecordList } from './NotifyMessageRecordList';
|
||||||
export { default as NotifyMessageTemplateList } from './NotifyMessageTemplateList';
|
export { default as NotifyMessageTemplateList } from './NotifyMessageTemplateList';
|
||||||
|
|||||||
@ -3435,4 +3435,24 @@ export default {
|
|||||||
markReadSuccess: '标记已读成功',
|
markReadSuccess: '标记已读成功',
|
||||||
markReadFailed: '标记已读失败',
|
markReadFailed: '标记已读失败',
|
||||||
},
|
},
|
||||||
|
notifyMessageRecord: {
|
||||||
|
column: {
|
||||||
|
title: '消息标题',
|
||||||
|
content: '消息内容',
|
||||||
|
isRead: '阅读状态',
|
||||||
|
readAt: '已读时间',
|
||||||
|
createdAt: '接收时间',
|
||||||
|
option: '操作',
|
||||||
|
},
|
||||||
|
status: {
|
||||||
|
read: '已读',
|
||||||
|
unread: '未读',
|
||||||
|
},
|
||||||
|
modal: {
|
||||||
|
view: {
|
||||||
|
title: '查看消息详情',
|
||||||
|
button: '详情',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
5
packages/app-operation/src/pages/NotifyMessageRecord.tsx
Normal file
5
packages/app-operation/src/pages/NotifyMessageRecord.tsx
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { NotifyMessageRecordList } from '@/components';
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return <NotifyMessageRecordList />;
|
||||||
|
}
|
||||||
@ -259,6 +259,7 @@ declare namespace BusinessAPI {
|
|||||||
status?: boolean;
|
status?: boolean;
|
||||||
/** 纸箱品牌ID */
|
/** 纸箱品牌ID */
|
||||||
brandId?: string;
|
brandId?: string;
|
||||||
|
title?: string;
|
||||||
/** 品牌类型:1_我方纸箱;2_瓜农纸箱;3_第三方纸箱;4_礼盒; */
|
/** 品牌类型:1_我方纸箱;2_瓜农纸箱;3_第三方纸箱;4_礼盒; */
|
||||||
type?: 'OUR_BOX' | 'FARMER_BOX' | 'THIRD_PARTY_BOX' | 'GIFT_BOX';
|
type?: 'OUR_BOX' | 'FARMER_BOX' | 'THIRD_PARTY_BOX' | 'GIFT_BOX';
|
||||||
offset?: number;
|
offset?: number;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user