新增通知中心
This commit is contained in:
parent
cd7251091b
commit
61d52e1571
50
src/components/Notice/noticeDialog/index.vue
Normal file
50
src/components/Notice/noticeDialog/index.vue
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<Editor
|
||||||
|
style="height: 600px; overflow-y: hidden"
|
||||||
|
v-model="valueHtml"
|
||||||
|
:defaultConfig="editorConfig"
|
||||||
|
mode="default"
|
||||||
|
@onCreated="handleCreated"
|
||||||
|
@onChange="handleChange" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import '@wangeditor/editor/dist/css/style.css' // 引入 css
|
||||||
|
import { Editor } from '@wangeditor/editor-for-vue'
|
||||||
|
interface props {
|
||||||
|
modelValue: string
|
||||||
|
}
|
||||||
|
const props = defineProps<props>()
|
||||||
|
const emit = defineEmits()
|
||||||
|
const valueHtml = ref(props.modelValue)
|
||||||
|
const editorRef = shallowRef()
|
||||||
|
const editorConfig = {
|
||||||
|
readOnly: true
|
||||||
|
}
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
const editor = editorRef.value
|
||||||
|
if (editor == null) return
|
||||||
|
editor.destroy()
|
||||||
|
})
|
||||||
|
const handleCreated = (editor) => {
|
||||||
|
editorRef.value = editor
|
||||||
|
}
|
||||||
|
const handleChange = (editor) => {
|
||||||
|
emit('update:modelValue', editor.getHtml())
|
||||||
|
}
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(value) => {
|
||||||
|
const editor = editorRef.value
|
||||||
|
if (value == undefined) {
|
||||||
|
editor.clear()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
valueHtml.value = value
|
||||||
|
}
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
||||||
@ -91,6 +91,20 @@ export const constantRoutes = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/notice',
|
||||||
|
component: Layout,
|
||||||
|
hidden: true,
|
||||||
|
redirect: 'noredirect',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'title',
|
||||||
|
name: 'Title',
|
||||||
|
component: () => import('@/views/noticecenter/index'),
|
||||||
|
meta: { title: '通知中心', icon: 'Bell' }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
// 不用可删掉
|
// 不用可删掉
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
|
|||||||
155
src/views/noticecenter/index.vue
Normal file
155
src/views/noticecenter/index.vue
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app-container" style="position: absolute; left: 10px; right: 10px">
|
||||||
|
<el-tabs v-model="activeTab">
|
||||||
|
<el-tab-pane name="notice">
|
||||||
|
<template #label>
|
||||||
|
<el-badge :value="unreadNoticeList.length" style="line-height: 18px" :hidden="unreadNoticeList.length === 0"> 通知公告 </el-badge>
|
||||||
|
</template>
|
||||||
|
<el-divider />
|
||||||
|
<el-empty :image-size="150" description="暂无通知公告" v-if="noticeList.length === 0" />
|
||||||
|
<el-table :data="noticeList" height="600" :show-header="false" v-else>
|
||||||
|
<el-table-column prop="noticeTitle" label="标题">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-link :type="row.isRead ? 'primary' : 'danger'" @click="viewNoticeDetail(row.noticeId, row.isRead, row.noticeContent)">{{
|
||||||
|
row.noticeTitle
|
||||||
|
}}</el-link>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="create_time" label="时间" width="180">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ formatDate(row.create_time) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane name="aimMsg">
|
||||||
|
<template #label>
|
||||||
|
<el-badge :value="unreadAimList.length" style="line-height: 18px" :hidden="unreadAimList.length === 0"> 业务信息 </el-badge>
|
||||||
|
</template>
|
||||||
|
<el-divider />
|
||||||
|
<el-empty :image-size="150" description="暂无业务信息" v-if="aimList.length === 0" />
|
||||||
|
<el-table :data="aimList" height="600" :show-header="false" v-else>
|
||||||
|
<el-table-column prop="noticeTitle" label="标题">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-link :type="row.isRead ? 'primary' : 'danger'" @click="viewAimMsgDetail(row.noticeId, row.isRead, row.noticeContent)">{{
|
||||||
|
row.noticeTitle
|
||||||
|
}}</el-link>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="create_time" label="时间" width="180">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ formatDate(row.create_time) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
<el-popconfirm title="是否确定把全部内容消息设为已读?" :width="300" @confirm="onAllReadClick">
|
||||||
|
<template #reference>
|
||||||
|
<el-button type="primary" link class="left-top-button">全部标为已读</el-button>
|
||||||
|
</template>
|
||||||
|
</el-popconfirm>
|
||||||
|
<el-dialog v-model="noticeDialogOpen" title="查看通知详情" draggable :close-on-click-modal="false">
|
||||||
|
<noticeDialog v-model="form.noticeContent" />
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import useSocketStore from '@/store/modules/socket'
|
||||||
|
import signalR from '@/utils/signalR'
|
||||||
|
import noticeDialog from '@/components/Notice/noticeDialog/index.vue'
|
||||||
|
import { ElTable } from 'element-plus'
|
||||||
|
|
||||||
|
const activeTab = ref('notice')
|
||||||
|
const readNoticeList = computed(() => {
|
||||||
|
return useSocketStore().readNoticeList
|
||||||
|
})
|
||||||
|
const unreadNoticeList = computed(() => {
|
||||||
|
return useSocketStore().unreadNoticeList
|
||||||
|
})
|
||||||
|
const noticeList = computed(() => {
|
||||||
|
return readNoticeList.value
|
||||||
|
.map((item: any) => ({
|
||||||
|
...item,
|
||||||
|
isRead: true
|
||||||
|
}))
|
||||||
|
.concat(unreadNoticeList.value.map((item: any) => ({ ...item, isRead: false })))
|
||||||
|
})
|
||||||
|
|
||||||
|
const readAimList = computed(() => {
|
||||||
|
return useSocketStore().readAimList
|
||||||
|
})
|
||||||
|
const unreadAimList = computed(() => {
|
||||||
|
return useSocketStore().unreadAimList
|
||||||
|
})
|
||||||
|
const aimList = computed(() => {
|
||||||
|
return readAimList.value
|
||||||
|
.map((item: any) => ({
|
||||||
|
...item,
|
||||||
|
isRead: true
|
||||||
|
}))
|
||||||
|
.concat(unreadAimList.value.map((item: any) => ({ ...item, isRead: false })))
|
||||||
|
})
|
||||||
|
const form = ref({
|
||||||
|
noticeContent: ''
|
||||||
|
})
|
||||||
|
const noticeDialogOpen = ref(false)
|
||||||
|
const viewNoticeDetail = (noticeId, isRead, noticeContent) => {
|
||||||
|
if (!isRead) signalR.ReadNotice(noticeId)
|
||||||
|
noticeDialogOpen.value = true
|
||||||
|
form.value.noticeContent = noticeContent
|
||||||
|
}
|
||||||
|
const viewAimMsgDetail = (noticeId, isRead, noticeContent) => {
|
||||||
|
if (!isRead) signalR.ReadAimMsg(noticeId)
|
||||||
|
noticeDialogOpen.value = true
|
||||||
|
form.value.noticeContent = noticeContent
|
||||||
|
}
|
||||||
|
function onAllReadClick() {
|
||||||
|
if (activeTab.value === 'notice') {
|
||||||
|
signalR.AllReadNotice()
|
||||||
|
} else {
|
||||||
|
signalR.AllReadAimMsg()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const formatDate = (dateTime) => {
|
||||||
|
const dateObj = new Date(dateTime)
|
||||||
|
const options: any = {
|
||||||
|
year: 'numeric',
|
||||||
|
month: 'short',
|
||||||
|
day: 'numeric'
|
||||||
|
// hour: '2-digit',
|
||||||
|
// minute: '2-digit',
|
||||||
|
// second: '2-digit'
|
||||||
|
}
|
||||||
|
return dateObj.toLocaleDateString('zh-CN', options)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.content-box {
|
||||||
|
font-size: 13px;
|
||||||
|
|
||||||
|
.content-box-item {
|
||||||
|
//padding-top: 12px;
|
||||||
|
&:last-of-type {
|
||||||
|
padding-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-box-msg {
|
||||||
|
color: #999999;
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-box-time {
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.left-top-button {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
x
Reference in New Issue
Block a user