feat: 重构公告及消息,公告支持系统消息推送提醒、定时发布、置顶、记录读取状态

This commit is contained in:
2025-05-20 22:37:06 +08:00
parent feef35f541
commit abf3f13041
19 changed files with 316 additions and 151 deletions

View File

@@ -7,7 +7,7 @@
:loading="loading"
:scroll="{ x: '100%', y: '100%', minWidth: 800 }"
:pagination="pagination"
:disabled-tools="['size', 'setting']"
:disabled-tools="['size', 'setting', 'fullscreen']"
:row-selection="{ type: 'checkbox', showCheckedAll: true }"
@select="select"
@select-all="selectAll"
@@ -15,6 +15,15 @@
>
<template #toolbar-left>
<a-input-search v-model="queryForm.title" placeholder="搜索标题" allow-clear @search="search" />
<a-select
v-model="queryForm.type"
placeholder="请选择类型"
allow-clear
style="width: 150px"
:options="message_type_enum"
@change="search"
>
</a-select>
<a-select
v-model="queryForm.isRead"
placeholder="请选择状态"
@@ -36,7 +45,7 @@
删除
</a-button>
<a-button type="primary" :disabled="!selectedKeys.length" :title="!selectedKeys.length ? '请选择' : ''" @click="onRead">
标记已读
标记已读
</a-button>
<a-button type="primary" :disabled="selectedKeys.length > 0" :title="!selectedKeys.length ? '请选择' : ''" @click="onReadAll">
全部已读
@@ -45,14 +54,14 @@
<template #title="{ record }">
<a-tooltip :content="record.content"><span>{{ record.title }}</span></a-tooltip>
</template>
<template #type="{ record }">
<GiCellTag :value="record.type" :dict="message_type_enum" />
</template>
<template #isRead="{ record }">
<a-tag :color="record.isRead ? '' : 'arcoblue'">
{{ record.isRead ? '已读' : '未读' }}
</a-tag>
</template>
<template #type="{ record }">
<GiCellTag :value="record.type" :dict="message_type" />
</template>
</GiTable>
</template>
@@ -66,7 +75,7 @@ import mittBus from '@/utils/mitt'
defineOptions({ name: 'SystemMessage' })
const { message_type } = useDict('message_type')
const { message_type_enum } = useDict('message_type_enum')
const queryForm = reactive<MessageQuery>({
sort: ['createTime,desc'],
@@ -94,9 +103,9 @@ const columns: TableInstance['columns'] = [
render: ({ rowIndex }) => h('span', {}, rowIndex + 1 + (pagination.current - 1) * pagination.pageSize),
},
{ title: '标题', dataIndex: 'title', slotName: 'title', minWidth: 100, ellipsis: true, tooltip: true },
{ title: '类型', dataIndex: 'type', slotName: 'type', width: 180, ellipsis: true, tooltip: true },
{ title: '状态', dataIndex: 'isRead', slotName: 'isRead', minWidth: 100, align: 'center' },
{ title: '时间', dataIndex: 'createTime', width: 180 },
{ title: '类型', dataIndex: 'type', slotName: 'type', width: 180, ellipsis: true, tooltip: true },
]
// 重置

View File

@@ -25,7 +25,7 @@
</a-button>
</template>
<template #title="{ record }">
<a-link @click="onDetail(record)">
<a-link @click="onView(record)">
<a-typography-paragraph
class="link-text"
:ellipsis="{
@@ -41,6 +41,11 @@
<template #type="{ record }">
<GiCellTag :value="record.type" :dict="notice_type" />
</template>
<template #isRead="{ record }">
<a-tag :color="record.isRead ? '' : 'arcoblue'">
{{ record.isRead ? '已读' : '未读' }}
</a-tag>
</template>
</GiTable>
</template>
@@ -72,10 +77,11 @@ const columns: TableInstance['columns'] = [
align: 'center',
render: ({ rowIndex }) => h('span', {}, rowIndex + 1 + (pagination.current - 1) * pagination.pageSize),
},
{ title: '标题', dataIndex: 'title', slotName: 'title', ellipsis: true, tooltip: true },
{ title: '类', dataIndex: 'type', slotName: 'type', align: 'center' },
{ title: '公告标题', dataIndex: 'title', slotName: 'title', ellipsis: true, tooltip: true },
{ title: '类', dataIndex: 'type', slotName: 'type', align: 'center' },
{ title: '状态', dataIndex: 'isRead', slotName: 'isRead', align: 'center' },
{ title: '发布人', dataIndex: 'createUserString', ellipsis: true, tooltip: true },
{ title: '发布时间', dataIndex: 'createTime', width: 180 },
{ title: '发布时间', dataIndex: 'publishTime', width: 180 },
]
// 重置
@@ -86,8 +92,8 @@ const reset = () => {
}
const router = useRouter()
// 详情
const onDetail = (record: NoticeResp) => {
// 查看
const onView = (record: NoticeResp) => {
router.push({ path: '/user/notice', query: { id: record.id } })
}
</script>

View File

@@ -29,7 +29,10 @@ import { useRoute, useRouter } from 'vue-router'
import MyMessage from './components/MyMessage.vue'
import MyNotice from './components/MyNotice.vue'
import { useDevice } from '@/hooks'
import { type MessageResp, type NoticeResp, listMessage, listNotice } from '@/apis'
import {
getUnreadMessageCount,
getUnreadNoticeCount,
} from '@/apis'
import mittBus from '@/utils/mitt'
defineOptions({ name: 'UserMessage' })
@@ -51,35 +54,22 @@ const TabPaneTitle = defineComponent({
const { isDesktop } = useDevice()
const messageList = ref<MessageResp[]>()
const noticeList = ref<NoticeResp[]>()
const unreadMessageCount = ref(0)
const unreadNoticeCount = ref(0)
const tabItems = computed(() => [
{ key: 'msg', title: '我的消息', count: messageList.value?.length ?? 0 },
{ key: 'notice', title: '我的公告' },
{ key: 'msg', title: '我的消息', count: unreadMessageCount },
{ key: 'notice', title: '我的公告', count: unreadNoticeCount },
])
const messageQueryParam = reactive({
isRead: false,
sort: ['createTime,desc'],
page: 1,
size: 5,
})
const noticeQueryParam = reactive({
sort: ['createTime,desc'],
page: 1,
size: 5,
})
const getMessageData = async () => {
const { data } = await listMessage(messageQueryParam)
messageList.value = data.list.filter((item) => !item.isRead)
const { data } = await getUnreadMessageCount()
unreadMessageCount.value = data.total
}
const getNoticeData = async () => {
const { data } = await listNotice(noticeQueryParam)
noticeList.value = data.list
const { data } = await getUnreadNoticeCount()
unreadNoticeCount.value = data.total
}
onMounted(() => {