feat: 站内信消息记录
							parent
							
								
									3d692a583d
								
							
						
					
					
						commit
						b0b986c152
					
				|  | @ -0,0 +1,59 @@ | ||||||
|  | import type { PageParam, PageResult } from '@vben/request'; | ||||||
|  | 
 | ||||||
|  | import { requestClient } from '#/api/request'; | ||||||
|  | 
 | ||||||
|  | export namespace SystemNotifyMessageApi { | ||||||
|  |   /** 站内信消息信息 */ | ||||||
|  |   export interface NotifyMessage { | ||||||
|  |     id: number; | ||||||
|  |     userId: number; | ||||||
|  |     userType: number; | ||||||
|  |     templateId: number; | ||||||
|  |     templateCode: string; | ||||||
|  |     templateNickname: string; | ||||||
|  |     templateContent: string; | ||||||
|  |     templateType: number; | ||||||
|  |     templateParams: string; | ||||||
|  |     readStatus: boolean; | ||||||
|  |     readTime: string; | ||||||
|  |     createTime: string; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** 查询站内信消息列表 */ | ||||||
|  | export function getNotifyMessagePage(params: PageParam) { | ||||||
|  |   return requestClient.get<PageResult<SystemNotifyMessageApi.NotifyMessage>>( | ||||||
|  |     '/system/notify-message/page', | ||||||
|  |     { params }, | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** 获得我的站内信分页 */ | ||||||
|  | export function getMyNotifyMessagePage(params: PageParam) { | ||||||
|  |   return requestClient.get<PageResult<SystemNotifyMessageApi.NotifyMessage>>( | ||||||
|  |     '/system/notify-message/my-page', | ||||||
|  |     { params }, | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** 批量标记已读 */ | ||||||
|  | export function updateNotifyMessageRead(ids: number[]) { | ||||||
|  |   return requestClient.put('/system/notify-message/update-read', { ids }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** 标记所有站内信为已读 */ | ||||||
|  | export function updateAllNotifyMessageRead() { | ||||||
|  |   return requestClient.put('/system/notify-message/update-all-read'); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** 获取当前用户的最新站内信列表 */ | ||||||
|  | export function getUnreadNotifyMessageList() { | ||||||
|  |   return requestClient.get<SystemNotifyMessageApi.NotifyMessage[]>( | ||||||
|  |     '/system/notify-message/get-unread-list', | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** 获得当前用户的未读站内信数量 */ | ||||||
|  | export function getUnreadNotifyMessageCount() { | ||||||
|  |   return requestClient.get<number>('/system/notify-message/get-unread-count'); | ||||||
|  | } | ||||||
|  | @ -0,0 +1,158 @@ | ||||||
|  | import type { VbenFormSchema } from '#/adapter/form'; | ||||||
|  | import type { OnActionClickFn, VxeTableGridOptions } from '#/adapter/vxe-table'; | ||||||
|  | import type { SystemNotifyMessageApi } from '#/api/system/notify/message'; | ||||||
|  | 
 | ||||||
|  | import { DICT_TYPE, getDictOptions } from '#/utils/dict'; | ||||||
|  | 
 | ||||||
|  | /** 列表的搜索表单 */ | ||||||
|  | export function useGridFormSchema(): VbenFormSchema[] { | ||||||
|  |   return [ | ||||||
|  |     { | ||||||
|  |       fieldName: 'userId', | ||||||
|  |       label: '用户编号', | ||||||
|  |       component: 'Input', | ||||||
|  |       componentProps: { | ||||||
|  |         allowClear: true, | ||||||
|  |         placeholder: '请输入用户编号', | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       fieldName: 'userType', | ||||||
|  |       label: '用户类型', | ||||||
|  |       component: 'Select', | ||||||
|  |       componentProps: { | ||||||
|  |         allowClear: true, | ||||||
|  |         options: getDictOptions(DICT_TYPE.USER_TYPE, 'number'), | ||||||
|  |         placeholder: '请选择用户类型', | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       fieldName: 'templateCode', | ||||||
|  |       label: '模板编码', | ||||||
|  |       component: 'Input', | ||||||
|  |       componentProps: { | ||||||
|  |         allowClear: true, | ||||||
|  |         placeholder: '请输入模板编码', | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       fieldName: 'templateType', | ||||||
|  |       label: '模版类型', | ||||||
|  |       component: 'Select', | ||||||
|  |       componentProps: { | ||||||
|  |         allowClear: true, | ||||||
|  |         options: getDictOptions( | ||||||
|  |           DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE, | ||||||
|  |           'number', | ||||||
|  |         ), | ||||||
|  |         placeholder: '请选择模版类型', | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       fieldName: 'createTime', | ||||||
|  |       label: '创建时间', | ||||||
|  |       component: 'RangePicker', | ||||||
|  |       componentProps: { | ||||||
|  |         allowClear: true, | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |   ]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** 列表的字段 */ | ||||||
|  | export function useGridColumns<T = SystemNotifyMessageApi.NotifyMessage>( | ||||||
|  |   onActionClick: OnActionClickFn<T>, | ||||||
|  | ): VxeTableGridOptions['columns'] { | ||||||
|  |   return [ | ||||||
|  |     { | ||||||
|  |       field: 'id', | ||||||
|  |       title: '编号', | ||||||
|  |       minWidth: 100, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'userType', | ||||||
|  |       title: '用户类型', | ||||||
|  |       minWidth: 120, | ||||||
|  |       cellRender: { | ||||||
|  |         name: 'CellDict', | ||||||
|  |         props: { type: DICT_TYPE.USER_TYPE }, | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'userId', | ||||||
|  |       title: '用户编号', | ||||||
|  |       minWidth: 100, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'templateCode', | ||||||
|  |       title: '模板编码', | ||||||
|  |       minWidth: 120, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'templateNickname', | ||||||
|  |       title: '发送人名称', | ||||||
|  |       minWidth: 180, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'templateContent', | ||||||
|  |       title: '模版内容', | ||||||
|  |       minWidth: 200, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'templateParams', | ||||||
|  |       title: '模版参数', | ||||||
|  |       minWidth: 180, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'templateType', | ||||||
|  |       title: '模版类型', | ||||||
|  |       minWidth: 120, | ||||||
|  |       cellRender: { | ||||||
|  |         name: 'CellDict', | ||||||
|  |         props: { type: DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE }, | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'readStatus', | ||||||
|  |       title: '是否已读', | ||||||
|  |       minWidth: 100, | ||||||
|  |       cellRender: { | ||||||
|  |         name: 'CellDict', | ||||||
|  |         props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING }, | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'readTime', | ||||||
|  |       title: '阅读时间', | ||||||
|  |       minWidth: 180, | ||||||
|  |       formatter: 'formatDateTime', | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'createTime', | ||||||
|  |       title: '创建时间', | ||||||
|  |       minWidth: 180, | ||||||
|  |       formatter: 'formatDateTime', | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'operation', | ||||||
|  |       title: '操作', | ||||||
|  |       minWidth: 180, | ||||||
|  |       align: 'center', | ||||||
|  |       fixed: 'right', | ||||||
|  |       cellRender: { | ||||||
|  |         attrs: { | ||||||
|  |           nameField: 'id', | ||||||
|  |           nameTitle: '站内信', | ||||||
|  |           onClick: onActionClick, | ||||||
|  |         }, | ||||||
|  |         name: 'CellOperation', | ||||||
|  |         options: [ | ||||||
|  |           { | ||||||
|  |             code: 'view', | ||||||
|  |             text: '查看', | ||||||
|  |           }, | ||||||
|  |         ], | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |   ]; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,78 @@ | ||||||
|  | <script lang="ts" setup> | ||||||
|  | import type { | ||||||
|  |   OnActionClickParams, | ||||||
|  |   VxeTableGridOptions, | ||||||
|  | } from '#/adapter/vxe-table'; | ||||||
|  | import type { SystemNotifyMessageApi } from '#/api/system/notify/message'; | ||||||
|  | 
 | ||||||
|  | import { Page, useVbenModal } from '@vben/common-ui'; | ||||||
|  | 
 | ||||||
|  | import { useVbenVxeGrid } from '#/adapter/vxe-table'; | ||||||
|  | import { getNotifyMessagePage } from '#/api/system/notify/message'; | ||||||
|  | 
 | ||||||
|  | import { useGridColumns, useGridFormSchema } from './data'; | ||||||
|  | import Detail from './modules/detail.vue'; | ||||||
|  | 
 | ||||||
|  | const [DetailModal, detailModalApi] = useVbenModal({ | ||||||
|  |   connectedComponent: Detail, | ||||||
|  |   destroyOnClose: true, | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | /** 刷新表格 */ | ||||||
|  | function onRefresh() { | ||||||
|  |   gridApi.query(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** 查看站内信详情 */ | ||||||
|  | function onView(row: SystemNotifyMessageApi.NotifyMessage) { | ||||||
|  |   detailModalApi.setData(row).open(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** 表格操作按钮的回调函数 */ | ||||||
|  | function onActionClick({ | ||||||
|  |   code, | ||||||
|  |   row, | ||||||
|  | }: OnActionClickParams<SystemNotifyMessageApi.NotifyMessage>) { | ||||||
|  |   switch (code) { | ||||||
|  |     case 'view': { | ||||||
|  |       onView(row); | ||||||
|  |       break; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const [Grid, gridApi] = useVbenVxeGrid({ | ||||||
|  |   formOptions: { | ||||||
|  |     schema: useGridFormSchema(), | ||||||
|  |   }, | ||||||
|  |   gridOptions: { | ||||||
|  |     columns: useGridColumns(onActionClick), | ||||||
|  |     height: 'auto', | ||||||
|  |     keepSource: true, | ||||||
|  |     proxyConfig: { | ||||||
|  |       ajax: { | ||||||
|  |         query: async ({ page }, formValues) => { | ||||||
|  |           return await getNotifyMessagePage({ | ||||||
|  |             pageNo: page.currentPage, | ||||||
|  |             pageSize: page.pageSize, | ||||||
|  |             ...formValues, | ||||||
|  |           }); | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |     rowConfig: { | ||||||
|  |       keyField: 'id', | ||||||
|  |     }, | ||||||
|  |     toolbarConfig: { | ||||||
|  |       refresh: { code: 'query' }, | ||||||
|  |       search: true, | ||||||
|  |     }, | ||||||
|  |   } as VxeTableGridOptions<SystemNotifyMessageApi.NotifyMessage>, | ||||||
|  | }); | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <Page auto-content-height> | ||||||
|  |     <DetailModal @success="onRefresh" /> | ||||||
|  |     <Grid table-title="站内信列表" /> | ||||||
|  |   </Page> | ||||||
|  | </template> | ||||||
|  | @ -0,0 +1,93 @@ | ||||||
|  | <script lang="ts" setup> | ||||||
|  | import type { SystemNotifyMessageApi } from '#/api/system/notify/message'; | ||||||
|  | 
 | ||||||
|  | import { ref } from 'vue'; | ||||||
|  | 
 | ||||||
|  | import { useVbenModal } from '@vben/common-ui'; | ||||||
|  | import { formatDateTime } from '@vben/utils'; | ||||||
|  | 
 | ||||||
|  | import { Descriptions, Tag } from 'ant-design-vue'; | ||||||
|  | 
 | ||||||
|  | import { DICT_TYPE, getDictLabel } from '#/utils/dict'; | ||||||
|  | 
 | ||||||
|  | const messageData = ref<SystemNotifyMessageApi.NotifyMessage>(); | ||||||
|  | 
 | ||||||
|  | const [Modal, modalApi] = useVbenModal({ | ||||||
|  |   async onOpenChange(isOpen: boolean) { | ||||||
|  |     if (!isOpen) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |     // 加载数据 | ||||||
|  |     const data = modalApi.getData<SystemNotifyMessageApi.NotifyMessage>(); | ||||||
|  |     if (!data || !data.id) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |     modalApi.lock(); | ||||||
|  |     try { | ||||||
|  |       messageData.value = data; | ||||||
|  |     } finally { | ||||||
|  |       modalApi.lock(false); | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  | }); | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <Modal title="站内信详情"> | ||||||
|  |     <Descriptions bordered :column="1" size="middle" class="mx-4"> | ||||||
|  |       <Descriptions.Item label="编号">{{ messageData?.id }}</Descriptions.Item> | ||||||
|  |       <Descriptions.Item label="用户类型"> | ||||||
|  |         <!-- TODO @芋艿: 数据字典--> | ||||||
|  |         <Tag color="processing"> | ||||||
|  |           {{ getDictLabel(DICT_TYPE.USER_TYPE, messageData?.userType) }} | ||||||
|  |         </Tag> | ||||||
|  |       </Descriptions.Item> | ||||||
|  |       <Descriptions.Item label="用户编号"> | ||||||
|  |         {{ messageData?.userId }} | ||||||
|  |       </Descriptions.Item> | ||||||
|  |       <Descriptions.Item label="模版编号"> | ||||||
|  |         {{ messageData?.templateId }} | ||||||
|  |       </Descriptions.Item> | ||||||
|  |       <Descriptions.Item label="模板编码"> | ||||||
|  |         {{ messageData?.templateCode }} | ||||||
|  |       </Descriptions.Item> | ||||||
|  |       <Descriptions.Item label="发送人名称"> | ||||||
|  |         {{ messageData?.templateNickname }} | ||||||
|  |       </Descriptions.Item> | ||||||
|  |       <Descriptions.Item label="模版内容"> | ||||||
|  |         {{ messageData?.templateContent }} | ||||||
|  |       </Descriptions.Item> | ||||||
|  |       <Descriptions.Item label="模版参数"> | ||||||
|  |         {{ messageData?.templateParams }} | ||||||
|  |       </Descriptions.Item> | ||||||
|  |       <Descriptions.Item label="模版类型"> | ||||||
|  |         <!-- TODO @芋艿: 数据字典--> | ||||||
|  |         <Tag color="processing"> | ||||||
|  |           {{ | ||||||
|  |             getDictLabel( | ||||||
|  |               DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE, | ||||||
|  |               messageData?.templateType, | ||||||
|  |             ) | ||||||
|  |           }} | ||||||
|  |         </Tag> | ||||||
|  |       </Descriptions.Item> | ||||||
|  |       <Descriptions.Item label="是否已读"> | ||||||
|  |         <!-- TODO @芋艿: 数据字典--> | ||||||
|  |         <Tag color="processing"> | ||||||
|  |           {{ | ||||||
|  |             getDictLabel( | ||||||
|  |               DICT_TYPE.INFRA_BOOLEAN_STRING, | ||||||
|  |               messageData?.readStatus, | ||||||
|  |             ) | ||||||
|  |           }} | ||||||
|  |         </Tag> | ||||||
|  |       </Descriptions.Item> | ||||||
|  |       <Descriptions.Item label="阅读时间"> | ||||||
|  |         {{ messageData?.readTime }} | ||||||
|  |       </Descriptions.Item> | ||||||
|  |       <Descriptions.Item label="创建时间"> | ||||||
|  |         {{ formatDateTime(messageData?.createTime || '') }} | ||||||
|  |       </Descriptions.Item> | ||||||
|  |     </Descriptions> | ||||||
|  |   </Modal> | ||||||
|  | </template> | ||||||
		Loading…
	
		Reference in New Issue
	
	 puhui999
						puhui999