feat: 新增消息中心

This commit is contained in:
2024-05-19 22:58:47 +08:00
parent 00da9acdd0
commit fdd4b9a4df
6 changed files with 189 additions and 1 deletions

View File

@@ -8,3 +8,4 @@ export * from './file'
export * from './storage'
export * from './option'
export * from './user-center'
export * from './message'

View File

@@ -0,0 +1,19 @@
import type * as System from './type'
import http from '@/utils/http'
const BASE_URL = '/system/message'
/** @desc 查询消息列表 */
export function listMessage(query: System.MessagePageQuery) {
return http.get<PageRes<System.MessageResp[]>>(`${BASE_URL}`, query)
}
/** @desc 删除消息 */
export function deleteMessage(ids: string | Array<string>) {
return http.del(`${BASE_URL}/${ids}`)
}
/** @desc 标记已读 */
export function readMessage(ids: string | Array<string>) {
return http.patch(`${BASE_URL}/read`, ids)
}

View File

@@ -297,3 +297,25 @@ export interface BindSocialAccountRes {
source: string
description: string
}
/** 系统消息类型 */
export interface MessageResp {
id: string
title: string
content: string
type: number
isRead: boolean
readTime: string
createUserString: string
createTime: string
}
export interface MessageQuery {
title?: string
type?: number
isRead?: boolean
sort: Array<string>
}
export interface MessagePageQuery extends MessageQuery, PageQuery {
}

View File

@@ -1,5 +1,5 @@
import type * as System from './type'
import http from '@/utils/http'
import type * as System from '@/apis/system/type'
const BASE_URL = '/system/user'

View File

@@ -63,6 +63,12 @@ export const constantRoutes: RouteRecordRaw[] = [
name: 'SettingProfile',
component: () => import('@/views/setting/profile/index.vue'),
meta: { title: '个人中心', showInTabs: false }
},
{
path: '/setting/message',
name: 'SettingMessage',
component: () => import('@/views/setting/message/index.vue'),
meta: { title: '消息中心', showInTabs: false }
}
]
}

View File

@@ -0,0 +1,140 @@
<template>
<div class="table-page">
<GiTable
row-key="id"
title="消息中心"
:data="dataList"
:columns="columns"
:loading="loading"
:scroll="{ x: '100%', y: '100%', minWidth: 1000 }"
:pagination="pagination"
:disabled-tools="['size', 'setting']"
:disabled-column-keys="['name']"
:row-selection="{ type: 'checkbox', showCheckedAll: true }"
:selected-keys="selectedKeys"
@select-all="selectAll"
@select="select"
@refresh="search"
>
<template #custom-left>
<a-input v-model="queryForm.title" placeholder="请输入标题" allow-clear @change="search">
<template #prefix><icon-search /></template>
</a-input>
<a-select
v-model="queryForm.isRead"
placeholder="请选择状态"
allow-clear
style="width: 150px"
@change="search"
>
<a-option :value="false">未读</a-option>
<a-option :value="true">已读</a-option>
</a-select>
<a-button @click="reset">重置</a-button>
</template>
<template #custom-right>
<a-button type="primary" status="danger" :disabled="!selectedKeys.length" @click="onDelete">
<template #icon><icon-delete /></template>
<span>删除</span>
</a-button>
<a-button type="primary" :disabled="!selectedKeys.length" @click="onRead">
<span>标记为已读</span>
</a-button>
<a-button type="primary" :disabled="selectedKeys.length" @click="onReadAll">全部已读</a-button>
</template>
<template #title="{ record }">
<a-tooltip :content="record.content"><span>{{ record.title }}</span></a-tooltip>
</template>
<template #isRead="{ record }">
<a-tag v-if="record.isRead">已读</a-tag>
<a-tag v-else color="arcoblue">未读</a-tag>
</template>
<template #type="{ record }">
<GiCellTag :value="record.type" :dict="message_type" />
</template>
</GiTable>
</div>
</template>
<script setup lang="ts">
import { Message, Modal } from '@arco-design/web-vue'
import { type MessageQuery, deleteMessage, listMessage, readMessage } from '@/apis'
import type { TableInstanceColumns } from '@/components/GiTable/type'
import { useTable } from '@/hooks'
import { useDict } from '@/hooks/app'
defineOptions({ name: 'SystemMessage' })
const { message_type } = useDict('message_type')
const queryForm = reactive<MessageQuery>({
sort: ['createTime,desc']
})
const {
tableData: dataList,
loading,
pagination,
selectedKeys,
select,
selectAll,
search,
handleDelete
} = useTable((page) => listMessage({ ...queryForm, ...page }), { immediate: true })
const columns: TableInstanceColumns[] = [
{
title: '序号',
width: 66,
align: 'center',
render: ({ rowIndex }) => h('span', {}, rowIndex + 1 + (pagination.current - 1) * pagination.pageSize)
},
{ title: '标题', dataIndex: 'title', slotName: 'title', ellipsis: true, tooltip: true },
{ title: '状态', dataIndex: 'isRead', slotName: 'isRead', align: 'center', width: 80 },
{ title: '时间', dataIndex: 'createTime', width: 180 },
{ title: '类型', dataIndex: 'type', slotName: 'type', width: 180, ellipsis: true, tooltip: true }
]
// 重置
const reset = () => {
queryForm.title = undefined
queryForm.type = undefined
queryForm.isRead = undefined
search()
}
// 删除
const onDelete = () => {
if (!selectedKeys.value.length) {
return Message.warning('请选择数据')
}
return handleDelete(() => deleteMessage(selectedKeys.value), { showModal: false })
}
// 标记为已读
const onRead = async () => {
if (!selectedKeys.value.length) {
return Message.warning('请选择数据')
}
await readMessage(selectedKeys.value)
Message.success('操作成功')
search()
}
// 全部已读
const onReadAll = async () => {
Modal.warning({
title: '全部已读',
content: '确定要标记全部消息为已读吗?',
hideCancel: false,
maskClosable: false,
onOk: async () => {
await readMessage([])
Message.success('操作成功')
search()
}
})
}
</script>
<style lang="scss" scoped></style>