一、实现效果:网页端或者移动端进行了审核操作,在电脑右下角提示用户查看。
1、当有弹框提示的情况时,会弹出如下提示,点击查看自动跳转到当前地址,点击关闭则关闭当前提示窗口;

2、当有两条及其以上的消息要审核时,弹框的内容会变成如下展示:

二、实现思路:
1、在主进程main.js中创建弹框,并确定弹框的位置;
2、编写弹框内容和样式;
3、在登录成功后使用webSoket实时监听消息;
4、主进程收到消息后触发提示弹框展示;
三、代码实现:
1、主进程main.js中:
- // main.js
-
- // 监听
- ipcMain.on('remindWindow:close', () => {
- remindWindow.close()
- })
-
- // 判断在弹框关闭前一共收到几次消息
- let num = 1
- ipcMain.on('open-remind', (event, task, twrUrl) => {
- if (remindWindow) {
- num++
- remindWindow.webContents.send('show-remind', task, twrUrl, num)
- } else {
- num = 1
- createRemindWindow(task, twrUrl)
- }
- })
-
- // 创建提示弹出窗
- const iconPath = path.join(__dirname, './src/img/icon.png')
- function createRemindWindow(task, twrUrl) {
- if (remindWindow) remindWindow.close()
- remindWindow = new BrowserWindow({
- height: 180,
- width: 300,
- resizable: false,
- frame: false,
- icon: iconPath,
- show: false,
- webPreferences: {
- nodeIntegration: true,
- contextIsolation: false, //关闭上下文隔离的
- // preload: path.join(__dirname, './preload.js')
- },
- })
-
- // 打开控制台
- // remindWindow.webContents.openDevTools()
- remindWindow.removeMenu()
- // 右下角弹出
- const size = screen.getPrimaryDisplay().workAreaSize
- const { y } = tray.getBounds()
- const { height, width } = remindWindow.getBounds()
- const yPosition = y - height
-
- remindWindow.setBounds({
- x: size.width - width,
- y: yPosition,
- height,
- width,
- })
- remindWindow.setAlwaysOnTop(true)
- remindWindow.loadURL(`file://${__dirname}/src/remind.html`)
- remindWindow.show()
- // 发消息
- remindWindow.webContents.send('show-remind', task, twrUrl)
- remindWindow.on('closed', () => {
- remindWindow = null
- })
- }
2、登录成功后获取实时信息弹框提示;
- // login.js
-
- // 获取登录
- async function getLogin({ account, password }) {
-
- // do something
-
- if (response.ok) {
- // 登录成功后触发webSoket
- initWebSocket()
- }
- }
-
- const heartbeatInterval = 30000 // 心跳检测间隔,单位:毫秒
- const reconnectInterval = 3000 // 重连间隔,单位:毫秒
- let socket = null
- let isReconnecting = false
- // 心跳检测
- function startHeartbeat() {
- setInterval(() => {
- if (socket && socket.readyState === WebSocket.OPEN) {
- // 发送心跳消息到服务器
- socket.send('heartbeat')
- }
- }, heartbeatInterval)
- }
-
- // 获取实时信息弹框提示
- function initWebSocket() {
- const socUrl = 'ws://xxx/xxx'
- socket = new WebSocket(socUrl)
- // 监听连接事件
- socket.onopen = () => {
- console.log('WebSocket连接已建立')
- // 启动心跳检测
- startHeartbeat()
- }
- // 监听消息事件
- socket.onmessage = event => {
- console.log('收到数据:', event)
- // 启动心跳检测
- startHeartbeat()
- if (event.data === 'HeartBeatResp') {
- // 心跳响应消息不做处理
- return
- }
- const socketData = JSON.parse(event.data)
- // 收到消息后发消息给主进程 socketData:提示信息 | twrUrl.value:跳转地址
- if (socketData) {
- ipcRenderer.send('open-remind', socketData, twrUrl.value)
- }
- }
-
- // 监听关闭事件
- socket.onclose = event => {
- console.log(`websocket连接关闭 code: ${event.code}, reason: ${event.reason}, wasClean: ${event.wasClean}`)
- reconnectWebSocket()
- }
-
- // 监听错误事件
- socket.onerror = event => {
- console.log('websocket连接错误')
- reconnectWebSocket()
- }
- }
- // websocket重连
- function reconnectWebSocket() {
- if (!isReconnecting) {
- // 连接断开时,触发重连
- isReconnecting = true
- setTimeout(() => {
- initWebSocket()
- isReconnecting = false
- }, reconnectInterval)
- }
- }
3、在src文件夹下新建remind.html实现提示弹框具体内容;
- DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8" />
- <meta http-equiv="X-UA-Compatible" content="IE=edge" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <title>Documenttitle>
- <style>
- * {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
- }
- .custom-toolbar {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 10px;
- font-weight: bold;
- background-color: rgb(236, 233, 233);
- }
- .custom-toolbar .close-button {
- cursor: pointer;
- font-size: 20px;
- position: relative;
- bottom: 1px;
- }
- .custom-toolbar .title-text {
- font-size: 16px;
- }
- .custom-toolbar .title-text > img {
- width: 16px;
- height: 16px;
- position: relative;
- top: 2px;
- }
- .reminder {
- text-align: left;
- font-size: 14px;
- height: 100px;
- padding: 10px;
- padding-top: 0;
- line-height: 24px;
- /* letter-spacing: 1.2px; */
- overflow: auto;
- }
- .close,
- .detail-button {
- position: absolute;
- font-size: 14px;
- color: dodgerblue;
- bottom: 10px;
- cursor: pointer;
- z-index: 1;
- }
- .close {
- right: 10px;
- }
- .detail-button {
- right: 50px;
- }
- .num {
- color: dodgerblue;
- font-weight: bold;
- }
- style>
- head>
- <body>
- <div class="custom-toolbar">
- <div class="title-text">
- <img src="./img/icon.png" alt="" />
- xxx小助手
- div>
- <div class="close-button">×div>
- div>
- <span class="detail-button">查看span>
- <span class="close-button close">关闭span>
- <div class="reminder">div>
- body>
- <script>
- const electron = require('electron')
- const { ipcRenderer } = electron
- const { shell } = require('electron/common')
- const reminder = document.querySelector('.reminder')
- const closeBtns = document.querySelectorAll('.close-button')
- const detailBtn = document.querySelector('.detail-button')
- let socketData
- let url
- ipcRenderer.on('show-remind', (event, task, twrUrl, num) => {
- socketData = task
- url = twrUrl
- if (num) {
- reminder.innerHTML = `您有${num}条信息需要处理,请及时登录xxx系统操作。`
- } else {
- reminder.innerHTML = `${socketData.msgContent}`
- }
-
- })
- // 关闭
- closeBtns.forEach(i => {
- i.addEventListener('click', () => {
- ipcRenderer.send('remindWindow:close')
- })
- })
- // 查看-点击自动跳转到默认浏览器
- detailBtn.addEventListener('click', () => {
- shell.openExternal(`http://${url}/xxx/#/xxx`)
- })
- script>
- html>
4、综上所述,即可完成桌面提示功能。