|
|
|
|
@ -1,11 +1,6 @@
@@ -1,11 +1,6 @@
|
|
|
|
|
<!-- |
|
|
|
|
* @author: fu_li_wei |
|
|
|
|
* @since: 2025-05-12 |
|
|
|
|
* message.vue |
|
|
|
|
--> |
|
|
|
|
<template> |
|
|
|
|
<el-dropdown ref="dropdownRef" class="right-menu-message" trigger="click"> |
|
|
|
|
<el-badge :value="$store.getters.messageNum"> |
|
|
|
|
<el-badge :value="$store.getters.messageNum" :hidden="!$store.getters.messageNum"> |
|
|
|
|
<el-button size="small" icon="el-icon-bell" type="info" round plain>消息</el-button> |
|
|
|
|
</el-badge> |
|
|
|
|
<el-dropdown-menu slot="dropdown"> |
|
|
|
|
@ -14,115 +9,118 @@
@@ -14,115 +9,118 @@
|
|
|
|
|
<span>未读消息({{ $store.getters.messageNum }})</span> |
|
|
|
|
</div> |
|
|
|
|
<div class="message-body"> |
|
|
|
|
<div v-for="item in messageList" :key="item.id" class="message-content"> |
|
|
|
|
<span class="message-content-content">{{ item.content }}</span> |
|
|
|
|
<span class="message-content-date">{{ item.date }}</span> |
|
|
|
|
<div v-for="item in messageList" :key="item.id" class="message-content" @click="openMessage(item)"> |
|
|
|
|
<span class="message-content-content"> |
|
|
|
|
<span class="message-dot" /> |
|
|
|
|
{{ item.title || item.content || '消息' }} |
|
|
|
|
</span> |
|
|
|
|
<span class="message-content-date">{{ formatTime(item.createTime) }}</span> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
<el-divider></el-divider> |
|
|
|
|
<el-divider /> |
|
|
|
|
<div class="message-foot items-center"> |
|
|
|
|
<span @click="loadingMore">查看更多</span> |
|
|
|
|
<span @click="readAll">全部已读</span> |
|
|
|
|
<svg-icon icon-class="link" style="font-size: 10px;" /> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
<div v-else class="dropdown-message"> |
|
|
|
|
<el-empty :image-size="50" description="暂无消息"></el-empty> |
|
|
|
|
<el-empty :image-size="50" description="暂无未读消息" /> |
|
|
|
|
</div> |
|
|
|
|
</el-dropdown-menu> |
|
|
|
|
</el-dropdown> |
|
|
|
|
</template> |
|
|
|
|
|
|
|
|
|
<script> |
|
|
|
|
/* global MyConfig */ |
|
|
|
|
import mqtt from 'mqtt' |
|
|
|
|
// const client = mqtt.connect('ws://221.219.102.234:8083/mqtt', { |
|
|
|
|
// clientId: 'mqttjs_' + Math.random().toString(16).substr(2, 8), |
|
|
|
|
// }) |
|
|
|
|
// client.on('connect', () => { |
|
|
|
|
// console.log('Connected') |
|
|
|
|
// }) |
|
|
|
|
// client.on('error', error => { |
|
|
|
|
// console.log('Connection failed', error) |
|
|
|
|
// }) |
|
|
|
|
|
|
|
|
|
// // 订阅主题 |
|
|
|
|
// client.subscribe('sound-alarm', { qos: 0 }, (error, res) => {}) |
|
|
|
|
import { getUnreadMessageCount, listMessages, getMessageDetail, readAllMessages } from '@/api/message' |
|
|
|
|
|
|
|
|
|
export default { |
|
|
|
|
name: 'Message', |
|
|
|
|
components: {}, |
|
|
|
|
data() { |
|
|
|
|
return { |
|
|
|
|
client: null, |
|
|
|
|
messageList: [] |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
async created() { |
|
|
|
|
created() { |
|
|
|
|
this.createConnection() |
|
|
|
|
const list = await this.$store.dispatch('setMessageNum') |
|
|
|
|
this.messageList = list |
|
|
|
|
this.refresh() |
|
|
|
|
}, |
|
|
|
|
mounted() { |
|
|
|
|
// const _that = this |
|
|
|
|
// client.on('message', (topic, message) => { |
|
|
|
|
// console.log('收到消息:', topic, JSON.parse(message)); |
|
|
|
|
// switch (topic) { |
|
|
|
|
// case 'warn-zj': |
|
|
|
|
// _that.newMessage(JSON.parse(message)) |
|
|
|
|
// break; |
|
|
|
|
// } |
|
|
|
|
// this.$store.commit('setUntreated') |
|
|
|
|
// }) |
|
|
|
|
beforeDestroy() { |
|
|
|
|
if (this.client) { |
|
|
|
|
this.client.end(true) |
|
|
|
|
this.client = null |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
methods: { |
|
|
|
|
/** 链接Mqtt服务 */ |
|
|
|
|
/** 拉取未读数量与未读消息列表 */ |
|
|
|
|
async refresh() { |
|
|
|
|
try { |
|
|
|
|
const [countRes, listRes] = await Promise.all([ |
|
|
|
|
getUnreadMessageCount(), |
|
|
|
|
listMessages({ pageNum: 1, pageSize: 10 }) |
|
|
|
|
]) |
|
|
|
|
this.$store.commit('SET_MESSAGE_NUM', Number(countRes.data || 0)) |
|
|
|
|
const page = listRes.data || listRes |
|
|
|
|
const list = page.list || page.rows || [] |
|
|
|
|
this.messageList = list.filter(item => String(item.isRead) !== '1') |
|
|
|
|
} catch (error) { |
|
|
|
|
this.$store.commit('SET_MESSAGE_NUM', 0) |
|
|
|
|
this.messageList = [] |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
/** 点击消息:查看详情(即已读)并刷新 */ |
|
|
|
|
openMessage(item) { |
|
|
|
|
if (!item) return |
|
|
|
|
if (String(item.isRead) === '1') return |
|
|
|
|
getMessageDetail(item.id) |
|
|
|
|
.then(response => { |
|
|
|
|
const detail = response.data || item |
|
|
|
|
this.$alert(detail.content || '', detail.title || '消息详情', { confirmButtonText: '知道了' }) |
|
|
|
|
this.refresh() |
|
|
|
|
}) |
|
|
|
|
.catch(() => { |
|
|
|
|
this.$modal.msgError('消息详情加载失败') |
|
|
|
|
}) |
|
|
|
|
}, |
|
|
|
|
/** 全部已读 */ |
|
|
|
|
readAll() { |
|
|
|
|
readAllMessages() |
|
|
|
|
.then(() => { |
|
|
|
|
this.$modal.msgSuccess('已全部标记为已读') |
|
|
|
|
this.refresh() |
|
|
|
|
}) |
|
|
|
|
.catch(() => { |
|
|
|
|
this.$modal.msgError('操作失败,请稍后重试') |
|
|
|
|
}) |
|
|
|
|
}, |
|
|
|
|
/** 连接 MQTT,订阅当前用户消息主题 */ |
|
|
|
|
createConnection() { |
|
|
|
|
const _that = this |
|
|
|
|
const { host, port, endpoint, ...options } = MyConfig.MQTTconnection; |
|
|
|
|
// 连接 |
|
|
|
|
const { host, port, endpoint, ...options } = MyConfig.MQTTconnection |
|
|
|
|
this.client = mqtt.connect(`ws://${host}:${port}${endpoint}`, options) |
|
|
|
|
|
|
|
|
|
// 成功 |
|
|
|
|
this.client.on('connect', () => { |
|
|
|
|
/** |
|
|
|
|
* 订阅主题 |
|
|
|
|
* 订阅的主题应该和 message接受配合使用 |
|
|
|
|
*/ |
|
|
|
|
_that.client.subscribe(`sys/${_that.$store.getters.user_id}/msg`, { qos: 0 }, (error, res) => { |
|
|
|
|
_that.client.subscribe(`sys/${_that.$store.getters.user_id}/msg`, { qos: 0 }, () => { |
|
|
|
|
console.log(`订阅主题: sys/${_that.$store.getters.user_id}/msg 成功`) |
|
|
|
|
}); |
|
|
|
|
_that.client.subscribe(`test`, { qos: 0 }, (error, res) => { |
|
|
|
|
console.log(`订阅主题: test 成功`) |
|
|
|
|
}); |
|
|
|
|
_that.client.subscribe(`sys/test/msg`, { qos: 0 }, (error, res) => { |
|
|
|
|
console.log(`订阅主题: sys/test/msg 成功`) |
|
|
|
|
}); |
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
// 失败 |
|
|
|
|
this.client.on('error', error => { |
|
|
|
|
console.log('Connection failed', error) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
// 接收消息 |
|
|
|
|
this.client.on('message', (topic, message) => { |
|
|
|
|
console.log('收到消息:', topic, message.toString()) |
|
|
|
|
switch (topic) { |
|
|
|
|
case `sys/${_that.$store.getters.user_id}/msg`: |
|
|
|
|
_that.newMessage() |
|
|
|
|
break; |
|
|
|
|
if (topic === `sys/${_that.$store.getters.user_id}/msg`) { |
|
|
|
|
_that.refresh() |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
}, |
|
|
|
|
/** 跳转信息页 */ |
|
|
|
|
loadingMore() { |
|
|
|
|
setTimeout(() => { |
|
|
|
|
this.$refs.dropdownRef.hide() |
|
|
|
|
}, 300) |
|
|
|
|
}, |
|
|
|
|
/** 新的信息 */ |
|
|
|
|
async newMessage(data) { |
|
|
|
|
const list = await this.$store.dispatch('setMessageNum') |
|
|
|
|
this.messageList = list |
|
|
|
|
formatTime(value) { |
|
|
|
|
if (!value) return '' |
|
|
|
|
return String(value).replace('T', ' ').slice(5, 16) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -142,31 +140,13 @@ export default {
@@ -142,31 +140,13 @@ export default {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.right-menu-item { |
|
|
|
|
display: inline-block; |
|
|
|
|
padding: 0 8px; |
|
|
|
|
height: 100%; |
|
|
|
|
font-size: 18px; |
|
|
|
|
color: #5a5e66; |
|
|
|
|
vertical-align: text-bottom; |
|
|
|
|
|
|
|
|
|
&.hover-effect { |
|
|
|
|
cursor: pointer; |
|
|
|
|
transition: background .3s; |
|
|
|
|
|
|
|
|
|
&:hover { |
|
|
|
|
background: rgba(0, 0, 0, .025) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
::v-deep .el-badge__content { |
|
|
|
|
line-height: 15px; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.dropdown-message-more { |
|
|
|
|
width: 300px; |
|
|
|
|
|
|
|
|
|
width: 320px; |
|
|
|
|
|
|
|
|
|
.message-head { |
|
|
|
|
width: 100%; |
|
|
|
|
height: 30px; |
|
|
|
|
@ -182,10 +162,12 @@ export default {
@@ -182,10 +162,12 @@ export default {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.message-body { |
|
|
|
|
// height: 200px; |
|
|
|
|
// overflow-y: auto; |
|
|
|
|
max-height: 300px; |
|
|
|
|
overflow-y: auto; |
|
|
|
|
|
|
|
|
|
.message-content { |
|
|
|
|
padding: 6px 15px; |
|
|
|
|
padding: 8px 15px; |
|
|
|
|
cursor: pointer; |
|
|
|
|
|
|
|
|
|
&:hover { |
|
|
|
|
background-color: #fafafa; |
|
|
|
|
@ -194,12 +176,11 @@ export default {
@@ -194,12 +176,11 @@ export default {
|
|
|
|
|
.message-content-content { |
|
|
|
|
display: block; |
|
|
|
|
font-size: 13px; |
|
|
|
|
// 一行显示,超出隐藏,用省略号表示 |
|
|
|
|
white-space: nowrap; |
|
|
|
|
overflow: hidden; |
|
|
|
|
text-overflow: ellipsis; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.message-content-date { |
|
|
|
|
font-size: 12px; |
|
|
|
|
color: #999; |
|
|
|
|
@ -213,6 +194,7 @@ export default {
@@ -213,6 +194,7 @@ export default {
|
|
|
|
|
color: #1890ff; |
|
|
|
|
font-size: 12px; |
|
|
|
|
font-weight: 500; |
|
|
|
|
cursor: pointer; |
|
|
|
|
span { |
|
|
|
|
margin-right: 4px; |
|
|
|
|
} |
|
|
|
|
@ -222,20 +204,20 @@ export default {
@@ -222,20 +204,20 @@ export default {
|
|
|
|
|
margin: 10px 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.text-gray { |
|
|
|
|
font-size: 13px; |
|
|
|
|
color: #999; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.items-center { |
|
|
|
|
display: flex; |
|
|
|
|
align-items: center; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.justify-between { |
|
|
|
|
display: flex; |
|
|
|
|
justify-content: space-between; |
|
|
|
|
} |
|
|
|
|
.message-dot { |
|
|
|
|
display: inline-block; |
|
|
|
|
width: 6px; |
|
|
|
|
height: 6px; |
|
|
|
|
margin-right: 4px; |
|
|
|
|
border-radius: 50%; |
|
|
|
|
background: #d64550; |
|
|
|
|
vertical-align: middle; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.dropdown-message { |
|
|
|
|
|