246 lines
7.0 KiB
Vue
246 lines
7.0 KiB
Vue
|
|
<template>
|
|||
|
|
<div>
|
|||
|
|
<el-popover placement="bottom" trigger="click" width="400px" popper-class="el-popover-pupop-user-news">
|
|||
|
|
<template #reference>
|
|||
|
|
<el-badge :show-zero="false" :value="allDotNum" style="line-height: 18px">
|
|||
|
|
<el-icon><bell /></el-icon>
|
|||
|
|
</el-badge>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<el-tabs v-model="noticeType">
|
|||
|
|
<el-tab-pane name="0">
|
|||
|
|
<template #label>
|
|||
|
|
<el-badge :show-zero="false" :value="dotNumInfo.noticeNum"> 通知 </el-badge>
|
|||
|
|
</template>
|
|||
|
|
<div class="content-box">
|
|||
|
|
<el-scrollbar>
|
|||
|
|
<div class="content-box-item" v-for="item in noticeList">
|
|||
|
|
<div class="left">
|
|||
|
|
<svg-icon name="gonggao" color="#fff" size="16"></svg-icon>
|
|||
|
|
</div>
|
|||
|
|
<div class="content" @click="handleDetails(item, 0)">
|
|||
|
|
<div class="title">
|
|||
|
|
{{ item.noticeTitle }}
|
|||
|
|
</div>
|
|||
|
|
<div class="content-box-time">{{ dayjs(item.create_time).format('YYYY-MM-DD') }}</div>
|
|||
|
|
</div>
|
|||
|
|
<!-- <div v-if="!readList.includes(item.noticeId)">
|
|||
|
|
<el-button text @click="handleReadNotice(item)">已读</el-button>
|
|||
|
|
</div> -->
|
|||
|
|
</div>
|
|||
|
|
</el-scrollbar>
|
|||
|
|
<el-empty v-if="noticeList.length <= 0" :image-size="60"></el-empty>
|
|||
|
|
</div>
|
|||
|
|
<div class="foot-box">
|
|||
|
|
<div class="read" @click="onAllReadClick" v-show="dotNumInfo.noticeNum > 0">标记当前页已读</div>
|
|||
|
|
<div class="goNotice" @click="handleToNotice" v-if="settings.noticeUrl">前往通知中心</div>
|
|||
|
|
</div>
|
|||
|
|
</el-tab-pane>
|
|||
|
|
|
|||
|
|
<el-tab-pane name="1">
|
|||
|
|
<template #label>
|
|||
|
|
<el-badge :show-zero="false" :value="dotNumInfo.chatNum"> 私信 </el-badge>
|
|||
|
|
</template>
|
|||
|
|
<div class="content-box">
|
|||
|
|
<el-scrollbar>
|
|||
|
|
<div class="content-box-item" v-for="item in chatList" @click="handleDetails(item, 1)">
|
|||
|
|
<el-avatar :src="item.fromUser.avatar"></el-avatar>
|
|||
|
|
<div class="content">
|
|||
|
|
<div class="title">
|
|||
|
|
<span class="name">{{ item.fromUser.nickName }}</span>
|
|||
|
|
回复:{{ item.message }}
|
|||
|
|
</div>
|
|||
|
|
<div class="content-box-time">{{ formatTime(item.chatTime) }}</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<el-empty v-if="chatList.length <= 0" :image-size="60"></el-empty>
|
|||
|
|
</el-scrollbar>
|
|||
|
|
</div>
|
|||
|
|
<div class="foot-box">
|
|||
|
|
<div class="read" @click="onAllReadClick" v-if="dotNumInfo.chatNum > 0">标记当前页已读</div>
|
|||
|
|
</div>
|
|||
|
|
</el-tab-pane>
|
|||
|
|
<el-tab-pane name="2">
|
|||
|
|
<template #label>
|
|||
|
|
<el-badge :show-zero="false" :value="dotNumInfo.sysMsgNum"> 系统 </el-badge>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<div class="content-box">
|
|||
|
|
<el-scrollbar>
|
|||
|
|
<div class="content-box-item" v-for="item in sysList">
|
|||
|
|
<div class="left">
|
|||
|
|
<svg-icon name="gonggao" color="#fff" size="16"></svg-icon>
|
|||
|
|
</div>
|
|||
|
|
<div class="content">
|
|||
|
|
<div class="title">
|
|||
|
|
{{ item.content }}
|
|||
|
|
</div>
|
|||
|
|
<div class="content-box-time">{{ formatTime(dayjs(item.addTime).valueOf()) }}</div>
|
|||
|
|
</div>
|
|||
|
|
<div v-if="item.isRead == 0">
|
|||
|
|
<el-button text @click="handleRead(item)">已读</el-button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<el-empty v-if="sysList.length <= 0" :image-size="60"></el-empty>
|
|||
|
|
</el-scrollbar>
|
|||
|
|
</div>
|
|||
|
|
<div class="foot-box">
|
|||
|
|
<div class="read" @click="onAllReadClick" v-if="dotNumInfo.sysMsgNum > 0">标记当前页已读</div>
|
|||
|
|
</div>
|
|||
|
|
</el-tab-pane>
|
|||
|
|
</el-tabs>
|
|||
|
|
</el-popover>
|
|||
|
|
<noticeInfo ref="noticeInfoRef"></noticeInfo>
|
|||
|
|
</div>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script setup name="noticeIndex">
|
|||
|
|
import { listMySysUserMsg, readSysUserMsg } from '@/api/system/sysusermsg'
|
|||
|
|
import noticeInfo from './noticeInfo.vue'
|
|||
|
|
import useSocketStore from '@/store/modules/socket'
|
|||
|
|
import useUserStore from '@/store/modules/user'
|
|||
|
|
import { dayjs } from 'element-plus'
|
|||
|
|
import { formatTime } from '@/utils/index'
|
|||
|
|
import settings from '@/settings'
|
|||
|
|
const { proxy } = getCurrentInstance()
|
|||
|
|
const socketStore = useSocketStore()
|
|||
|
|
const noticeType = ref('0')
|
|||
|
|
|
|||
|
|
const noticeList = computed(() => {
|
|||
|
|
return socketStore.noticeList
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
const allDotNum = computed(() => {
|
|||
|
|
return socketStore.getAllDotNum
|
|||
|
|
})
|
|||
|
|
const chatList = computed(() => {
|
|||
|
|
return socketStore.getSessionList(useUserStore().userId)
|
|||
|
|
})
|
|||
|
|
/**
|
|||
|
|
* 小红点信息
|
|||
|
|
*/
|
|||
|
|
const dotNumInfo = computed(() => {
|
|||
|
|
return socketStore.getMsgNum
|
|||
|
|
})
|
|||
|
|
const noticeInfoRef = ref()
|
|||
|
|
/**
|
|||
|
|
* 查看公告详情
|
|||
|
|
* @param {*} item
|
|||
|
|
* @param {*} type
|
|||
|
|
*/
|
|||
|
|
function handleDetails(item, type) {
|
|||
|
|
var info = {}
|
|||
|
|
if (type == 0) {
|
|||
|
|
info = { type, ...item, title: item.noticeTitle }
|
|||
|
|
} else if (type == 1) {
|
|||
|
|
info = { type, title: item.fromUser.nickName, userId: item.userId }
|
|||
|
|
}
|
|||
|
|
proxy.$refs['noticeInfoRef'].handleOpen(type, info)
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* 已读消息
|
|||
|
|
* @param {*} item
|
|||
|
|
*/
|
|||
|
|
function handleRead(item) {
|
|||
|
|
readSysUserMsg(item.msgId, 1).then(() => {
|
|||
|
|
init()
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
// 全部已读点击
|
|||
|
|
function onAllReadClick() {
|
|||
|
|
if (noticeType.value == 2) {
|
|||
|
|
readSysUserMsg(0, 1).then(() => {
|
|||
|
|
init()
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
useSocketStore().readAll(noticeType.value)
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* 已读通知
|
|||
|
|
*/
|
|||
|
|
function handleReadNotice(item) {
|
|||
|
|
useSocketStore().readPromptNotice(item.noticeId)
|
|||
|
|
}
|
|||
|
|
// 前往通知中心点击
|
|||
|
|
function handleToNotice() {
|
|||
|
|
window.open(settings.noticeUrl)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const sysList = ref([])
|
|||
|
|
function init() {
|
|||
|
|
listMySysUserMsg({ isRead: 0, msgType: 1 }).then((res) => {
|
|||
|
|
const { result, totalNum } = res.data
|
|||
|
|
sysList.value = result
|
|||
|
|
|
|||
|
|
socketStore.setSysMsgNum(totalNum)
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
init()
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style lang="scss" scoped>
|
|||
|
|
.content-box {
|
|||
|
|
font-size: 13px;
|
|||
|
|
height: 200px;
|
|||
|
|
overflow: hidden;
|
|||
|
|
|
|||
|
|
.content-box-item {
|
|||
|
|
margin-bottom: 10px;
|
|||
|
|
margin-right: 10px;
|
|||
|
|
display: flex;
|
|||
|
|
cursor: pointer;
|
|||
|
|
|
|||
|
|
.left {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
border-radius: 50%;
|
|||
|
|
width: 30px;
|
|||
|
|
height: 30px;
|
|||
|
|
justify-content: center;
|
|||
|
|
background: linear-gradient(23deg, rgba(110, 227, 225, 0.18) 0%, #00d9f5 100%);
|
|||
|
|
}
|
|||
|
|
&:hover {
|
|||
|
|
color: var(--el-color-primary);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.content {
|
|||
|
|
margin-left: 8px;
|
|||
|
|
word-wrap: break-word;
|
|||
|
|
word-break: break-all;
|
|||
|
|
position: relative;
|
|||
|
|
flex: 1;
|
|||
|
|
|
|||
|
|
.name {
|
|||
|
|
color: var(--el-color-primary);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.content-box-time {
|
|||
|
|
margin-top: 3px;
|
|||
|
|
color: #ccc;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
.foot-box {
|
|||
|
|
color: var(--el-color-primary);
|
|||
|
|
font-size: 13px;
|
|||
|
|
cursor: pointer;
|
|||
|
|
height: 25px;
|
|||
|
|
line-height: 25px;
|
|||
|
|
border-top: 1px solid #eee;
|
|||
|
|
|
|||
|
|
.read {
|
|||
|
|
top: 7px;
|
|||
|
|
right: 0;
|
|||
|
|
color: var(--el-color-primary);
|
|||
|
|
cursor: pointer;
|
|||
|
|
z-index: 2;
|
|||
|
|
font-size: 12px;
|
|||
|
|
float: left;
|
|||
|
|
}
|
|||
|
|
.goNotice {
|
|||
|
|
float: right;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
</style>
|