工业仿真(simulation)--前端(七)--消息栏

在这篇文章中,主要讲解仿真软件的消息栏

那在我们的仿真软件中,消息栏是分为三部分的

  • 系统提示消息【包括打开某个窗口,系统出现了某个警告,错误,网络连接等等】
  • 画布操作消息【对画布的一切操作都会记录在上面,类似于一个历史操作步骤】
  • 仿真控制器【控制仿真的组件】

如图一,二,三

图一 提示消息

图二 画布操作

图三 仿真控制器

在这三个组件中,只有图二不需要和主进程进行通信,提示消息需要监听主进程发送的消息,比如说当有其他渲染进程有重要消息时,就需要通过主进程将消息传递给提示组件

其他渲染进程📢 --> 主进程 --> 👂消息组件

首先说一下提示和画布操作,这两个有异曲同工的地方

提示和画布

先看代码 message.ts

ts 复制代码
import { defineStore } from 'pinia'
import { CanvasOperateType, Message } from '@renderer/types/message'
import { generateUUID } from '@renderer/utils/utils'
import dayjs from 'dayjs'
import { nextTick } from 'vue'

export const useMessageStore = defineStore('message', {
  state: () => ({
    activeTab: 'prompt' as 'prompt' | 'canvas' | 'simControler',

    prompt: [] as Message[],
    messageContentRef: null as HTMLElement | null,
    showNewMessage: false as boolean,

    canvasOperate: [] as CanvasOperateType[],
    canvasOperateContentRef: null as HTMLElement | null
  }),
  actions: {
    //切换tab
    changeTab(tab: 'prompt' | 'canvas' | 'simControler') {
      this.activeTab = tab
    },

    //添加信息
    addPrompt(message: Message) {
      const msg = {} as Message
      //设置id
      msg.id = generateUUID()
      //获取当前时间
      msg.time = dayjs().format('HH:mm:ss')

      msg.content = message.content
      msg.source = message.source
      msg.type = message.type

      //判断当前消息内容是否和上一条消息内容一样
      if (this.prompt.length > 0 && this.prompt[this.prompt.length - 1].content === msg.content) {
        //获取上一条消息的次数,如果没有就默认为1
        const count = this.prompt[this.prompt.length - 1].count || 1
        //设置当前消息的次数
        msg.count = count + 1
        //删除上一条消息
        this.prompt.pop()
      }

      //判断消息是否超过了200条
      if (this.prompt.length > 200) {
        //删除前一百条
        this.prompt.splice(0, 100)
      }
      this.prompt.push(msg)

      if (this.activeTab !== 'prompt') {
        this.showNewMessage = true
      }

      nextTick(() => {
        //将messageContentRef滚动条滚动到最后
        if (this.messageContentRef) {
          this.messageContentRef.scrollTop = this.messageContentRef.scrollHeight
        }
      })
    },

    //添加画布操作信息
    addCanvasOperate(message: CanvasOperateType) {
      const msg = {} as CanvasOperateType
      //设置id
      msg.id = generateUUID()
      //获取当前时间
      msg.time = dayjs().format('HH:mm:ss')

      msg.content = message.content
      msg.source = message.source
      msg.otherMsg = message.otherMsg

      this.judgeCanvasOperate(msg)
      nextTick(() => {
        //将canvasOperateContentRef滚动条滚动到最后
        if (this.canvasOperateContentRef) {
          this.canvasOperateContentRef.scrollTop = this.canvasOperateContentRef.scrollHeight
        }
      })
    },

    //对画布操作进行判断
    judgeCanvasOperate(msg: CanvasOperateType) {
      //判断当前消息内容是否和上一条消息内容一样
      if (
        this.canvasOperate.length > 0 &&
        this.canvasOperate[this.canvasOperate.length - 1].content === msg.content
      ) {
        //获取上一条消息的次数,如果没有就默认为1
        const count = this.canvasOperate[this.canvasOperate.length - 1].count || 1
        //设置当前消息的次数
        msg.count = count + 1
        //删除上一条消息
        this.canvasOperate.pop()
      }

      //判断消息是否超过了200条
      if (this.canvasOperate.length > 200) {
        this.canvasOperate.splice(0, 100)
      }

      this.canvasOperate.push(msg)
    },

    //清除消息
    clearMessage() {
      if (this.activeTab === 'prompt') {
        this.prompt = []
      } else {
        this.canvasOperate = []
      }
    }
  }
})

提示的数据格式和画布操作的格式是差不多的

ts 复制代码
export interface Message {
  id?: string
  time?: string
  source?: string
  content: string
  type?: 'info' | 'warning' | 'error' | 'success'
  count?: number
}

export interface CanvasOperateType {
  id?: string
  time?: string
  source: string
  content: string
  otherMsg?: string
  count?: number
}
  • id:位移ID值,可以采用UUID形式
  • time:当前消息的时间
  • source:消息来源于哪个地方
  • content:消息内容
  • type:消息类型
  • count:当消息和上一条消息重复时,此count就会+1

那此时我们就需要考虑一下,怎么去监听主进程的消息,在我的上一篇文章,属性栏里面其实已经讲过,属性栏数据是来源于主进程的,那么同理,我们也需要写一个监听事件

ts 复制代码
  //监听主进程发送的消息数据
  window.electron.ipcRenderer.on('mainProcessMsg', (e, data): void => {
    useMessageStore().addPrompt(data)
  })

然后这个方法需要放到main.ts里面区立即执行

那么在我们的主进程中,也同样需要一个方法,这个方法起到统一接收消息,然后将消息传递给渲染进程,代码如下

ts 复制代码
import { mainWindow } from '../..'

//给渲染进程的消息框发消息
export const sendMsgToRender = (
  source: string,
  content: string,
  type?: 'info' | 'warning' | 'error' | 'success'
): void => {
  const data = {
    source,
    content,
    type
  }
  //判断mainWindow是否存在
  if (mainWindow) {
    mainWindow?.webContents?.send('mainProcessMsg', data)
  }
}

那么至此我们的消息栏已经将核心讲解完毕了,关于仿真控制器的部分,我需要留到后面和仿真引擎一起讲解

相关推荐
jacGJ8 小时前
记录学习--文件读写
java·前端·学习
毕设源码-赖学姐8 小时前
【开题答辩全过程】以 基于WEB的实验室开放式管理系统的设计与实现为例,包含答辩的问题和答案
前端
幻云20108 小时前
Python深度学习:从筑基到登仙
前端·javascript·vue.js·人工智能·python
我即将远走丶或许也能高飞10 小时前
vuex 和 pinia 的学习使用
开发语言·前端·javascript
钟离墨笺11 小时前
Go语言--2go基础-->基本数据类型
开发语言·前端·后端·golang
爱吃泡芙的小白白11 小时前
Vue 3 核心原理与实战:从响应式到企业级应用
前端·javascript·vue.js
卓怡学长11 小时前
m115乐购游戏商城系统
java·前端·数据库·spring boot·spring·游戏
老陈聊架构12 小时前
『AI辅助Skill』掌握三大AI设计Skill:前端独立完成产品设计全流程
前端·人工智能·claude·skill
Ulyanov12 小时前
从桌面到云端:构建Web三维战场指挥系统
开发语言·前端·python·tkinter·pyvista·gui开发
cypking13 小时前
二、前端Java后端对比指南
java·开发语言·前端