'123'
This commit is contained in:
parent
b3a429204f
commit
00cd608378
|
@ -9,6 +9,7 @@ import com.ruoyi.framework.websocket.OneToManyWebSocket;
|
|||
import com.ruoyi.framework.websocket.WebSocketServer;
|
||||
import com.ruoyi.framework.websocket.WebSocketUsers;
|
||||
import com.ruoyi.system.domain.SysNoticeUser;
|
||||
import org.checkerframework.checker.units.qual.A;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
@ -77,26 +78,9 @@ public class SysNoticeController extends BaseController
|
|||
{
|
||||
notice.setCreateBy(getUsername());
|
||||
noticeService.insertNotice(notice);
|
||||
|
||||
List<SysNoticeUser> sysNoticeUsers = new ArrayList<SysNoticeUser>();
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put(WebsocketConst.MSG_ID, notice.getNoticeId());
|
||||
obj.put(WebsocketConst.MSG_TITLE, notice.getNoticeTitle());
|
||||
obj.put(WebsocketConst.MSG_CONTENT, notice.getNoticeContent());
|
||||
if(!"3".equals(notice.getNoticeType())){//系统通知 或 通知公告
|
||||
oneToManyWebSocket.sendMessage(obj.toString());
|
||||
|
||||
SysNoticeUser sysNoticeUser = null;
|
||||
Map<String, Session> users = oneToManyWebSocket.getUsers();
|
||||
for(String userId:users.keySet()){
|
||||
sysNoticeUser = new SysNoticeUser();
|
||||
sysNoticeUser.setNoticeId(notice.getNoticeId());
|
||||
sysNoticeUser.setUserId(Long.valueOf(userId));
|
||||
sysNoticeUsers.add(sysNoticeUser);
|
||||
}
|
||||
noticeService.insertNoticeUserBatch(sysNoticeUsers);
|
||||
}
|
||||
|
||||
//推送消息插入中间表
|
||||
Long userId = getLoginUser().getUserId();//当前登陆者
|
||||
insertNoticeUser(userId,notice,noticeService,oneToManyWebSocket,null);
|
||||
return success();
|
||||
}
|
||||
|
||||
|
@ -140,4 +124,65 @@ public class SysNoticeController extends BaseController
|
|||
}
|
||||
return groupedByNoticeType;
|
||||
}
|
||||
|
||||
/**
|
||||
* 导航面板 消息通知 获取详细信息
|
||||
*/
|
||||
@GetMapping(value = "navbarNotice/{noticeId}")
|
||||
public AjaxResult getNavbarNoticeInfo(@PathVariable Long noticeId)
|
||||
{
|
||||
return success(noticeService.selectNoticeById(noticeId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 推送消息插入中间表
|
||||
* @param userId 发送对象排除自身
|
||||
* @param notice 发送信息对象
|
||||
* @param noticeService 接口
|
||||
* @param oneToManyWebSocket WebSocket服务
|
||||
*/
|
||||
public static void insertNoticeUser(Long userId,SysNotice notice,ISysNoticeService noticeService,OneToManyWebSocket oneToManyWebSocket,List<String> userIds){
|
||||
List<SysNoticeUser> sysNoticeUsers = new ArrayList<SysNoticeUser>();
|
||||
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put(WebsocketConst.MSG_ID, notice.getNoticeId());
|
||||
obj.put(WebsocketConst.MSG_TITLE, notice.getNoticeTitle());
|
||||
obj.put(WebsocketConst.MSG_CONTENT, notice.getNoticeContent());
|
||||
|
||||
if(!"3".equals(notice.getNoticeType())){//系统通知 或 通知公告
|
||||
oneToManyWebSocket.sendMessage(obj.toString(),String.valueOf(userId));
|
||||
|
||||
SysNoticeUser sysNoticeUser = null;
|
||||
Map<String, Session> users = oneToManyWebSocket.getUsers();//获取在线用户
|
||||
for(String userid:users.keySet()){
|
||||
if(!userid.equals(String.valueOf(userId))){
|
||||
sysNoticeUser = new SysNoticeUser();
|
||||
sysNoticeUser.setNoticeId(notice.getNoticeId());
|
||||
sysNoticeUser.setUserId(Long.valueOf(userid));
|
||||
sysNoticeUsers.add(sysNoticeUser);
|
||||
}
|
||||
}
|
||||
if(!sysNoticeUsers.isEmpty()){
|
||||
noticeService.insertNoticeUserBatch(sysNoticeUsers);
|
||||
}
|
||||
}else{
|
||||
if(userIds!=null&&userIds.size()>0){
|
||||
oneToManyWebSocket.sendMessageByUserIds(obj.toString(),userIds);
|
||||
|
||||
SysNoticeUser sysNoticeUser = null;
|
||||
Map<String, Session> users = oneToManyWebSocket.getUsers();//获取在线用户
|
||||
for(String userid:users.keySet()){
|
||||
if(userIds.contains(userid)){
|
||||
sysNoticeUser = new SysNoticeUser();
|
||||
sysNoticeUser.setNoticeId(notice.getNoticeId());
|
||||
sysNoticeUser.setUserId(Long.valueOf(userid));
|
||||
sysNoticeUsers.add(sysNoticeUser);
|
||||
}
|
||||
}
|
||||
if(!sysNoticeUsers.isEmpty()){
|
||||
noticeService.insertNoticeUserBatch(sysNoticeUsers);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,29 +90,30 @@ public class OneToManyWebSocket {
|
|||
|
||||
/**
|
||||
* 群发消息
|
||||
*
|
||||
* @param message
|
||||
* @param userId
|
||||
*/
|
||||
public static void sendMessage(String message) {
|
||||
public static void sendMessage(String message,String userId) {
|
||||
for (Map.Entry<String, Session> sessionEntry : clients.entrySet()) {
|
||||
Session toSession = sessionEntry.getValue();
|
||||
String suid = sessionEntry.getKey();
|
||||
// 排除掉自己
|
||||
//if (!fromSession.getId().equals(toSession.getId())) {
|
||||
LOGGER.info("服务端给客户端[{}]发送消息{}", toSession.getId(), message);
|
||||
toSession.getAsyncRemote().sendText(message);
|
||||
//}
|
||||
if (!suid.equals(userId)) {
|
||||
LOGGER.info("服务端给客户端[{}]发送消息{}", toSession.getId(), message);
|
||||
toSession.getAsyncRemote().sendText(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 群发消息
|
||||
*
|
||||
* @param message
|
||||
* 消息内容
|
||||
* @param userIds
|
||||
*/
|
||||
public static void sendMessage(String message, List<String> ids) {
|
||||
|
||||
for (String id : ids) {
|
||||
public static void sendMessageByUserIds(String message, List<String> userIds) {
|
||||
|
||||
for (String id : userIds) {
|
||||
Session session = clients.get(id);
|
||||
if(session!=null){
|
||||
LOGGER.info("服务端给客户端[{}]发送消息{}", session.getId(), message);
|
||||
|
|
|
@ -12,7 +12,7 @@ import java.nio.charset.StandardCharsets;
|
|||
|
||||
/**
|
||||
* 通知公告表 sys_notice
|
||||
*
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class SysNotice extends BaseEntity
|
||||
|
@ -35,6 +35,9 @@ public class SysNotice extends BaseEntity
|
|||
/** 公告状态(0正常 1关闭) */
|
||||
private String status;
|
||||
|
||||
/** 公告是否已读(0未读 1已读) */
|
||||
private String isRead;
|
||||
|
||||
public Long getNoticeId()
|
||||
{
|
||||
return noticeId;
|
||||
|
@ -94,6 +97,10 @@ public class SysNotice extends BaseEntity
|
|||
return status;
|
||||
}
|
||||
|
||||
public String getIsRead() { return isRead; }
|
||||
|
||||
public void setIsRead(String isRead) { this.isRead = isRead; }
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
|
|
|
@ -92,14 +92,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
inner join sys_user_notice b on a.notice_id = b.noticeId
|
||||
<where>
|
||||
and b.userId = #{userId}
|
||||
and CONVERT(date, create_time) = CONVERT(date, GETDATE())
|
||||
and CONVERT(date, a.create_time) = CONVERT(date, GETDATE())
|
||||
and a.status = '0' and a.isRead = '0'
|
||||
</where>
|
||||
order by create_time desc
|
||||
</select>
|
||||
|
||||
<insert id="insertNoticeUserBatch" parameterType="java.util.List">
|
||||
insert into sys_user_notice
|
||||
(noticeId,userId)
|
||||
<insert id="insertNoticeUserBatch">
|
||||
insert into sys_user_notice(noticeId,userId)
|
||||
values
|
||||
<foreach collection="list" item="item" index="index" separator=",">
|
||||
(
|
||||
|
|
|
@ -7,5 +7,9 @@ ENV = 'development'
|
|||
# 江南业务系统/开发环境
|
||||
VUE_APP_BASE_API = '/dev-api'
|
||||
|
||||
# 江南业务系统-WebSocket/开发环境
|
||||
VUE_APP_WEBSOCKET_API = '/websocket-api'
|
||||
VUE_APP_WSS_WEBSOCKET_API = '/wss-websocket-api'
|
||||
|
||||
# 路由懒加载
|
||||
VUE_CLI_BABEL_TRANSPILE_MODULES = true
|
||||
|
|
|
@ -6,3 +6,7 @@ ENV = 'production'
|
|||
|
||||
# 江南业务系统/生产环境
|
||||
VUE_APP_BASE_API = '/prod-api'
|
||||
|
||||
# 江南业务系统-WebSocket/开发环境
|
||||
VUE_APP_WEBSOCKET_API = '/websocket-api'
|
||||
VUE_APP_WSS_WEBSOCKET_API = '/wss-websocket-api'
|
||||
|
|
|
@ -51,3 +51,12 @@ export function navbarNoticelist(query) {
|
|||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 导航面板 消息通知 获取详细信息
|
||||
export function getNavbarNotice(noticeId) {
|
||||
return request({
|
||||
url: '/system/notice/navbarNotice/' + noticeId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<el-dropdown>
|
||||
<span class="el-dropdown-link">
|
||||
<svg-icon icon-class="message" slot="reference" />
|
||||
<el-badge :value="noteTotal"></el-badge>
|
||||
<el-badge :value="noteTotal" v-if="noteTotal>0"></el-badge>
|
||||
</span>
|
||||
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
|
@ -12,31 +12,70 @@
|
|||
<el-dropdown-item v-for="(item,index) in noticeData" :key="index">
|
||||
<el-link :underline="false" @click="clickNote(item)" :style="index==0?'': 'margin-top :15px'">{{item.noticeTitle}}</el-link>
|
||||
</el-dropdown-item>
|
||||
<!--
|
||||
<el-link :underline="false" style="margin-top :15px" v-if="noticeData.length>5" type="primary">更多消息</el-link>
|
||||
-->
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="系统公告" name="second">
|
||||
<el-dropdown-item v-for="(item,index) in sysLog" :key="index">
|
||||
<el-link :underline="false" @click="clickNote(item)" :style="index==0?'': 'margin-top :15px'">{{item.noticeTitle}}</el-link>
|
||||
</el-dropdown-item>
|
||||
<!--
|
||||
<el-link v-if="sysLog.length>5" type="primary">更多消息</el-link>
|
||||
-->
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="业务通知" name="third">
|
||||
<el-dropdown-item v-for="(item,index) in businessData" :key="index">
|
||||
<el-link :underline="false" @click="clickNote(item)" :style="index==0?'': 'margin-top :15px'">{{item.noticeTitle}}</el-link>
|
||||
</el-dropdown-item>
|
||||
<!--
|
||||
<el-link :underline="false" style="margin-top :15px" v-if="noticeData.length>5" type="primary">更多消息</el-link>
|
||||
-->
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-dropdown-menu>
|
||||
<!--<mode-dialog :visible="noteVisible" :noteType="noteType" :noticeId="noticeId" @close="closeMode"></mode-dialog>-->
|
||||
<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-dropdown>
|
||||
</template>
|
||||
<script>
|
||||
import { navbarNoticelist } from '@/api/system/notice';
|
||||
/*
|
||||
import ModeDialog from '@/components/ModeDialog'
|
||||
*/
|
||||
import { getNavbarNotice} from "@/api/system/notice";
|
||||
|
||||
/*
|
||||
import ModeDialog from '@/components/ModeDialog'
|
||||
*/
|
||||
import { Notification } from 'element-ui';
|
||||
|
||||
export default {
|
||||
name: 'NavbarNotice',
|
||||
/*
|
||||
components: { ModeDialog },
|
||||
*/
|
||||
dicts: ['sys_notice_type'],
|
||||
data() {
|
||||
return {
|
||||
activeName: 'first',
|
||||
|
@ -45,18 +84,25 @@
|
|||
sysLog: [],
|
||||
// 通知
|
||||
noticeData: [],
|
||||
// 业务消息
|
||||
businessData: [],
|
||||
websock: null,
|
||||
lockReconnect: false,
|
||||
heartCheck: null,
|
||||
|
||||
//弹窗设置
|
||||
noteTitle: '',
|
||||
noteVisible: false,
|
||||
noteType: 0,
|
||||
noticeId: 0
|
||||
// 表单参数
|
||||
form: {},
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// 初始化WebSocket
|
||||
this.initWebSocket();
|
||||
},
|
||||
created(){
|
||||
this.getList();
|
||||
},
|
||||
destroyed: function() { // 离开页面生命周期函数
|
||||
this.websocketOnclose();
|
||||
},
|
||||
|
@ -71,24 +117,42 @@
|
|||
var sysLog = res[2]?res[2]:[];
|
||||
this.sysLog = sysLog.slice(0,5);
|
||||
|
||||
this.noteTotal = this.noticeData.length+this.sysLog.length;
|
||||
var businessData = res[3]?res[3]:[];
|
||||
this.businessData = businessData.slice(0,5);
|
||||
|
||||
this.noteTotal = this.noticeData.length+this.sysLog.length+this.businessData.length;
|
||||
})
|
||||
},
|
||||
handleClick(tab, event) {
|
||||
},
|
||||
clickNote(data) {
|
||||
this.noteVisible = true
|
||||
this.noticeId = data.noticeId
|
||||
this.noteType = data.noticeType == '1' ? 0 : 1
|
||||
},
|
||||
closeMode() {
|
||||
this.getList()
|
||||
this.noteVisible = false
|
||||
getNavbarNotice(data.noticeId).then(response => {
|
||||
this.form = response.data;
|
||||
this.noteTitle = "消息详情"
|
||||
this.noteVisible = true
|
||||
});
|
||||
},
|
||||
initWebSocket() {
|
||||
var userId = this.$store.state.user.id;
|
||||
// WebSocket与普通的请求所用协议有所不同,ws等同于http,wss等同于https
|
||||
var url = 'ws://localhost:3334/websocket/message/'+userId;
|
||||
// 当前浏览器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/'+userId;
|
||||
this.websock = new WebSocket(url)
|
||||
this.websock.onopen = this.websocketOnopen
|
||||
this.websock.onerror = this.websocketOnerror
|
||||
|
@ -113,6 +177,8 @@
|
|||
this.getList();
|
||||
Notification({
|
||||
title: '消息',
|
||||
duration: 3000,
|
||||
dangerouslyUseHTMLString: true,
|
||||
message: JSON.parse(e.data).noticeTitle
|
||||
})
|
||||
},
|
||||
|
@ -162,7 +228,7 @@
|
|||
width:300px
|
||||
}
|
||||
.el-dropdown-menu{
|
||||
width:250px
|
||||
width:300px
|
||||
}
|
||||
::v-deep .el-dropdown-menu {
|
||||
top: 28px;
|
||||
|
|
|
@ -40,7 +40,15 @@ module.exports = {
|
|||
pathRewrite: {
|
||||
['^' + process.env.VUE_APP_BASE_API]: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
[process.env.VUE_APP_WEBSOCKET_API]: {
|
||||
target: `http://localhost:3334`,
|
||||
changeOrigin: true,
|
||||
ws: true,
|
||||
pathRewrite: {
|
||||
['^' + process.env.VUE_APP_WEBSOCKET_API]: ''
|
||||
}
|
||||
},
|
||||
},
|
||||
disableHostCheck: true
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue