JNBusiness/ruoyi-ui/src/layout/components/NavbarNotice.vue

326 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<!--1通知 2公告-->
<el-dropdown>
<span class="el-dropdown-link">
<svg-icon icon-class="message" slot="reference" />
<el-badge :value="noteTotal" v-if="noteTotal>0"></el-badge>
</span>
<el-dropdown-menu slot="dropdown">
<el-tabs v-model="activeName" @tab-click="handleClick" style="width:100%">
<el-tab-pane label="系统通知" name="first">
<el-dropdown-item v-for="(item,index) in noticeData.slice(0,5)" :key="index">
<el-link :underline="false" @click="clickNote(item)" :style="index==0?'': 'margin-top :10px'">{{item.noticeTitle}}</el-link>
<el-link :underline="false" style="color:#AAAAAA">{{parseTime(item.sendTime, '{y}-{m}-{d} {h}:{i}:{s}')}}</el-link>
</el-dropdown-item>
<el-link :underline="false" @click="moreNote('1')" style="margin-top :10px" type="primary">更多消息</el-link>
</el-tab-pane>
<el-tab-pane label="系统公告" name="second">
<el-dropdown-item v-for="(item,index) in sysLog.slice(0,5)" :key="index">
<el-link :underline="false" @click="clickNote(item)" :style="index==0?'': 'margin-top :10px'">{{item.noticeTitle}}</el-link>
<el-link :underline="false" style="color:#AAAAAA">{{parseTime(item.sendTime, '{y}-{m}-{d} {h}:{i}:{s}')}}</el-link>
</el-dropdown-item>
<el-link :underline="false" @click="moreNote('2')" style="margin-top :10px" type="primary">更多消息</el-link>
</el-tab-pane>
<el-tab-pane label="业务通知" name="third">
<el-dropdown-item v-for="(item,index) in businessData.slice(0,5)" :key="index">
<el-link :underline="false" @click="clickNote(item)" :style="index==0?'': 'margin-top :10px'">{{item.noticeTitle}}</el-link>
<el-link :underline="false" style="color:#AAAAAA">{{parseTime(item.sendTime, '{y}-{m}-{d} {h}:{i}:{s}')}}</el-link>
</el-dropdown-item>
<el-link :underline="false" @click="moreNote('3')" style="margin-top :10px" type="primary">更多消息</el-link>
</el-tab-pane>
</el-tabs>
</el-dropdown-menu>
<el-dialog :title="noteTitle" :visible.sync="noteVisible" width="780px" append-to-body>
<el-form ref="form" :model="form" label-width="80px">
<el-row>
<el-col :span="12">
<el-form-item label="标题" prop="noticeTitle">
<el-input v-model="form.noticeTitle" :disabled="true"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="类型" prop="noticeType">
<el-select v-model="form.noticeType" :disabled="true">
<el-option
v-for="dict in dict.type.sys_notice_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="内容">
<editor v-model="form.noticeContent" :min-height="192"/>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-dialog>
<el-dialog class="noteMore" :title="noteMoreTitle" :visible.sync="noteMoreVisible" width="780px" append-to-body>
<div class="block">
<el-form :model="form" ref="queryForm" size="small" :inline="true" label-width="80px">
<el-form-item label="消息时间">
<el-date-picker
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-timeline>
<el-timeline-item :timestamp="item.date" placement="top" v-for="(item,index) in noteMore" :key="index">
<el-card v-for="(item,index) in item.data" :key="index" :style="index==0?'': 'margin-top :10px'">
<h3>{{item.noticeTitle}}</h3>
<span>{{item.sendUser}} 提交于 {{parseTime(item.sendTime, '{y}-{m}-{d} {h}:{i}:{s}')}}</span>
<el-button class="mb5" size="mini" :style="item.isRead==0?'float :right;background-color :#ffba00;border-color: #ffba00;': 'float :right;background-color :#c0c4cc;border-color: #c0c4cc;'" type="info">{{item.isRead=='1'?'已读':'未读'}}</el-button>
<div style="width:100%;height:1px;margin:0px auto;padding:0px;overflow:hidden;background-color: #c0c4ccab"></div>
<el-link :underline="false" @click="clickMoreNote(item)" style="color:#46a6ff;margin-top :10px">查看详情</el-link>
</el-card>
</el-timeline-item>
</el-timeline>
</div>
</el-dialog>
</el-dropdown>
</template>
<style>
/* 弹窗设置 */
.noteMore .el-dialog__body {
padding: 10px 10px;
color: #606266;
font-size: 14px;
word-break: break-all;
overflow-y: auto; /* 自动显示垂直滚动条 */
height: 600px;
max-height: 680px; /* 设置最大高度,根据需要调整 */
}
</style>
<script>
import { navbarNoticelist, navbarNoticeMorelist } from '@/api/system/notice';
import { getNavbarNotice} from "@/api/system/notice";
export default {
name: 'NavbarNotice',
dicts: ['sys_notice_type'],
data() {
return {
activeName: 'first',
noteTotal: '',
// 公告
sysLog: [],
// 通知
noticeData: [],
// 业务消息
businessData: [],
// 消息-更多数据
noteMore: [],
websock: null,
lockReconnect: false,
//弹窗设置
noteTitle: '',
noteVisible: false,
noteMoreTitle: '',
noteMoreVisible: false,
// 表单参数
form: {},
//查询参数
queryParams:{},
// 日期范围
dateRange: [],
}
},
mounted() {
// 初始化WebSocket
//this.initWebSocket();
},
created(){
this.getList();
},
destroyed: function() { // 离开页面生命周期函数
this.websocketOnclose();
},
methods: {
/**获取消息数据*/
getList() {
this.noticeData = [];
this.sysLog = [];
navbarNoticelist(this.queryParams).then(res => {
this.noticeData = res[1]?res[1]:[];
this.sysLog = res[2]?res[2]:[];
this.businessData = res[3]?res[3]:[];
this.noteTotal = this.noticeData.length+this.sysLog.length+this.businessData.length;
})
},
handleClick(tab, event) {
},
/**获取消息详情*/
clickNote(data) {
getNavbarNotice(data.noticeId).then(response => {
this.form = response.data;
this.noteTitle = "消息详情"
this.noteVisible = true
this.getList()
});
},
/** 显示更多消息 */
moreNote(noticeType){
this.noteMore = [];
this.queryParams.noticeType = noticeType;
navbarNoticeMorelist(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
console.log(response)
this.noteMoreTitle = noticeType=='1'?"系统通知消息":noticeType=='2'?"系统公告消息":"业务通知消息";
this.noteMoreVisible = true
this.noteMore = response
});
},
/** 搜索按钮操作 */
handleQuery() {
this.moreNote(this.queryParams.noticeType)
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = [];
this.resetForm("queryForm");
this.handleQuery();
},
/**获取更多消息中详情*/
clickMoreNote(data) {
getNavbarNotice(data.noticeId).then(response => {
this.form = response.data;
this.noteTitle = "消息详情"
this.noteVisible = true
this.moreNote(data.noticeType)
this.getList()
});
},
initWebSocket() {
var userName = this.$store.state.user.name;
// WebSocket与普通的请求所用协议有所不同ws等同于httpwss等同于https
// 当前浏览器Location对象
const nowLocation = window.location;
// 协议 => http、https
const protocol = nowLocation.protocol;
// hostName => ip
const hostName = nowLocation.hostname;
// host => ip:port
const host = nowLocation.host;
// websocket api 地址
// 这个判断就是根据当前项目环境 自动确定使用 ws 还是 wss 的路由地址
//const websocket_pattern = (hostName == '域名') ? 'wss-websocket-api' : 'websocket-api';
const websocket_pattern = 'websocket-api';
// websocket 请求地址前缀
//const webSocketApiUrl = ((protocol.startsWith('https')) ? 'wss://' : 'ws://') + host + '/' + websocket_pattern;
const webSocketApiUrl = 'ws://' + host + '/' + websocket_pattern;
// 当前WebSocket的请求地址前缀,
// /websocket/template-push/ 就是我后端配置的websocket端点地址
let url = webSocketApiUrl + '/websocket/message/ruoyi/'+userName;
this.websock = new WebSocket(url)
this.websock.onopen = this.websocketOnopen
this.websock.onerror = this.websocketOnerror
this.websock.onmessage = this.websocketOnmessage
this.websock.onclose = this.websocketOnclose
console.log('WebSocket 连接地址:'+host)
},
websocketOnopen: function() {
console.log('WebSocket连接成功')
},
websocketOnerror: function(e) {
console.log('WebSocket连接发生错误第%s次', this.wsConnectErrorTime)
this.wsConnectErrorTime = this.wsConnectErrorTime + 1
if (this.wsConnectErrorTime > 5) {
console.log('WebSocket连接错误超过5次就不再重新连了')
this.lockReconnect = true
return
}
this.reconnect()
},
websocketOnmessage: function(e) {
console.log('-----接收消息-------', e.data)
this.getList();
this.$notify({
title: '消息',
type: 'warning',
duration: 5000,
dangerouslyUseHTMLString: true,
message: JSON.parse(e.data).noticeTitle
});
},
websocketOnclose: function(e) {
console.log('connection closed (' + e + ')')
if (e) {
console.log('connection closed (' + e.code + ')')
}
this.reconnect()
},
reconnect() {
var that = this
if (that.lockReconnect) return
that.lockReconnect = true
//没连接上会一直重连,设置延迟避免请求过多
setTimeout(function() {
console.info('尝试重连...')
that.initWebSocket()
that.lockReconnect = false
}, 2000)
}
}
}
</script>
<style lang="scss" scoped>
.text-overflow {
width: 160px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
margin: 2px 0;
}
::v-deep .el-badge {
top: -7px;
}
::v-deep .el-badge__content.is-dot {
position: relative;
width: 11px;
height: 11px;
}
.el-tab-pane{
width:300px
}
.el-dropdown-menu{
width:300px
}
::v-deep .el-dropdown-menu {
top: 28px;
}
::v-deep .el-tabs {
padding: 12px;
width: 188px;
}
</style>