返回博客列表
项目实战

船舶数字化监控系统(AMS):从0到1的数字孪生平台实战

分享在厦门三顾海事科技开发船舶自动化管理系统的完整技术方案,包括Vue3架构设计、MQTT实时通信、大数据渲染优化等核心技术实现

吴志萍
2025年1月15日
12分钟
#Vue3 #数字孪生 #MQTT #实时监控 #性能优化 #ECharts

船舶数字化监控系统(AMS):从0到1的数字孪生平台实战

🚢 项目背景

在厦门三顾海事科技担任前端开发核心成员期间,我负责开发了船舶自动化管理系统(AMS),该系统成功通过JANA船东验收并实现商业化交付。这是一个集船舶设备监控、报警管理、数据分析于一体的数字孪生平台。

项目展示地址: Digital演示版

🏗️ 技术架构设计

核心技术栈选型

// 主要技术栈
const techStack = {
  framework: "Vue3 + TypeScript + Vite",
  stateManagement: "Pinia + pinia-plugin-persistedstate",
  uiFramework: "Element Plus + TailwindCSS",
  visualization: "ECharts + Canvas + Three.js + WebGL",
  communication: "MQTT + WebSocket",
  utils: "Dayjs + Lodash + File-saver + Xlsx",
  deployment: "Docker + Jenkins"
}

系统架构设计理念

模块化架构:基于Vue3 Composition API设计模块化组件系统 状态管理:使用Pinia实现响应式状态管理和数据持久化 实时通信:MQTT协议确保设备数据实时性 性能优化:多种策略确保10万+数据点流畅渲染

💡 核心功能实现

1. 实时设备监控系统

<template>
  <div class="ship-monitoring-dashboard">
    <!-- 船舶概览 -->
    <ship-overview
      :vessel-info="vesselInfo"
      :real-time-status="realtimeStatus"
    />

    <!-- 设备监控网格 -->
    <equipment-grid
      :equipment-list="equipmentList"
      :alert-config="alertConfig"
      @equipment-select="handleEquipmentSelect"
    />

    <!-- 实时数据图表 -->
    <real-time-charts
      :chart-data="chartData"
      :time-range="timeRange"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { useMqttStore } from '@/stores/mqtt'
import { useEquipmentStore } from '@/stores/equipment'

// 船舶设备实时监控核心逻辑
const mqttStore = useMqttStore()
const equipmentStore = useEquipmentStore()

// 实时数据状态
const realtimeStatus = ref({
  mainEngine: {},
  emergencyGenerator: {},
  powerSystem: {},
  liquidLevel: {},
  airCompression: {},
  fireAlarm: {}
})

// MQTT连接和数据订阅
onMounted(async () => {
  await mqttStore.connect()

  // 订阅所有设备主题
  const topics = [
    'ship/main-engine/+',
    'ship/generator/+',
    'ship/power-system/+',
    'ship/liquid-level/+',
    'ship/air-compression/+',
    'ship/fire-alarm/+'
  ]

  topics.forEach(topic => {
    mqttStore.subscribe(topic, handleDeviceData)
  })
})

// 设备数据处理
const handleDeviceData = (topic: string, payload: any) => {
  const [_, system, deviceId] = topic.split('/')

  // 实时更新设备状态
  updateDeviceStatus(system, deviceId, payload)

  // 检查报警条件
  checkAlertConditions(system, deviceId, payload)

  // 更新图表数据
  updateChartData(system, deviceId, payload)
}
</script>

2. 大数据渲染性能优化

处理10万+实时数据点的核心挑战在于性能优化:

// 虚拟滚动优化大数据表格
import { ElTableV2 } from 'element-plus'

// 数据分片策略
const useDataPagination = (data: any[], pageSize = 100) => {
  const currentPage = ref(1)
  const totalPages = computed(() => Math.ceil(data.length / pageSize))

  const paginatedData = computed(() => {
    const start = (currentPage.value - 1) * pageSize
    const end = start + pageSize
    return data.slice(start, end)
  })

  return {
    currentPage,
    totalPages,
    paginatedData
  }
}

// 使用shallowRef减少响应式开销
const equipmentData = shallowRef<EquipmentData[]>([])

// 节流优化滚动事件
import { throttle } from 'lodash'

const handleScroll = throttle((event) => {
  // 滚动处理逻辑
  updateVisibleItems(event.target.scrollTop)
}, 100)

// 数据更新优化
const updateEquipmentData = (newData: EquipmentData[]) => {
  // 使用Object.freeze减少响应式开销
  equipmentData.value = Object.freeze(newData)
}

3. MQTT实时通信优化

// MQTT连接管理
import mqtt from 'mqtt'

export const useMqttStore = defineStore('mqtt', () => {
  const client = ref<mqtt.MqttClient | null>(null)
  const connectionStatus = ref<'disconnected' | 'connecting' | 'connected'>('disconnected')

  // 连接配置
  const connect = async () => {
    connectionStatus.value = 'connecting'

    try {
      client.value = mqtt.connect('ws://localhost:8083/mqtt', {
        keepalive: 60,
        reschedulePings: true,
        protocolId: 'MQTT',
        protocolVersion: 4,
        reconnectPeriod: 1000,
        connectTimeout: 30 * 1000,
        clean: true,
        // 心跳检测
        will: {
          topic: 'ship/status',
          payload: 'offline',
          qos: 0,
          retain: false
        }
      })

      // 连接成功处理
      client.value.on('connect', () => {
        connectionStatus.value = 'connected'
        console.log('MQTT连接成功')
      })

      // 断线重连机制
      client.value.on('close', () => {
        connectionStatus.value = 'disconnected'
        console.log('MQTT连接断开,尝试重连...')
      })

      // 消息接收处理
      client.value.on('message', (topic, message) => {
        try {
          const data = JSON.parse(message.toString())
          handleMessage(topic, data)
        } catch (error) {
          console.error('消息解析失败:', error)
        }
      })

    } catch (error) {
      connectionStatus.value = 'disconnected'
      console.error('MQTT连接失败:', error)
    }
  }

  // 消息处理和数据更新
  const handleMessage = (topic: string, data: any) => {
    // 数据验证
    if (!validateMessageData(data)) {
      return
    }

    // 实时数据更新
    updateRealtimeData(topic, data)

    // 触发告警检查
    checkAlerts(topic, data)
  }

  return {
    client,
    connectionStatus,
    connect,
    subscribe,
    publish
  }
})

4. 船舶专业仪表盘组件

<template>
  <div class="ship-dashboard">
    <div class="dashboard-grid">
      <!-- 主发电机监控 -->
      <engine-gauge
        :value="mainEngine.power"
        :max="mainEngine.maxPower"
        :unit="'kW'"
        :status="mainEngine.status"
        title="主发电机"
      />

      <!-- 液位系统 -->
      <liquid-level-gauge
        :levels="liquidLevels"
        @level-alert="handleLevelAlert"
      />

      <!-- 电力系统PMS -->
      <power-system-chart
        :power-data="powerSystemData"
        :real-time="true"
      />
    </div>
  </div>
</template>

<script setup lang="ts">
// 自定义ECharts仪表盘组件
const createEngineGauge = (value: number, max: number) => {
  return {
    series: [{
      type: 'gauge',
      startAngle: 180,
      endAngle: 0,
      min: 0,
      max: max,
      splitNumber: 8,
      axisLine: {
        lineStyle: {
          width: 6,
          color: [
            [0.25, '#7CFFB2'],
            [0.5, '#58D9F9'],
            [0.75, '#FDDD60'],
            [1, '#FF6E76']
          ]
        }
      },
      pointer: {
        icon: 'path://M12.8,0.7l12,40.1H0.7L12.8,0.7z',
        length: '12%',
        width: 20,
        offsetCenter: [0, '-60%'],
        itemStyle: {
          color: 'auto'
        }
      },
      axisTick: {
        length: 12,
        lineStyle: {
          color: 'auto',
          width: 2
        }
      },
      splitLine: {
        length: 20,
        lineStyle: {
          color: 'auto',
          width: 5
        }
      },
      title: {
        fontSize: 30
      },
      detail: {
        fontSize: 40,
        offsetCenter: [0, '-35%'],
        valueAnimation: true,
        formatter: function (value: number) {
          return Math.round(value) + ' kW'
        },
        color: 'auto'
      },
      data: [{
        value: value,
        name: '功率输出'
      }]
    }]
  }
}
</script>

🚀 性能优化成果

首屏加载优化

优化前: 首屏加载时间 8-12秒 优化后: 首屏加载时间 2-3秒

// 路由懒加载
const routes = [
  {
    path: '/dashboard',
    component: () => import('@/views/Dashboard.vue')
  },
  {
    path: '/monitoring',
    component: () => import('@/views/Monitoring.vue')
  }
]

// 组件按需加载
import { ElButton, ElTable } from 'element-plus'

// 图片压缩和WebP格式
// vite.config.ts
import { defineConfig } from 'vite'
import { createVitePlugins } from './build/vite/plugins'

export default defineConfig({
  plugins: createVitePlugins(),
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          'element-plus': ['element-plus'],
          'echarts': ['echarts'],
          'three': ['three']
        }
      }
    }
  }
})

实时数据优化效果

  • 数据处理能力: 支持1000+测点实时监控
  • 更新频率: 实现秒级数据更新
  • 系统稳定性: 24小时连续运行无卡顿
  • 内存占用: 优化前后内存使用减少40%

📊 项目成果与价值

商业价值

  • 成功交付: 通过JANA船东验收,实现商业化
  • 技术领先: 支持10+种船型监控管理
  • 用户体验: 大数据渲染性能显著提升
  • 系统稳定: 7*24小时稳定运行

技术成长

  • 🎯 架构能力: 从0到1搭建大型前端系统
  • 🎯 性能优化: 掌握大数据量前端优化技巧
  • 🎯 实时通信: 精通MQTT/WebSocket实时数据处理
  • 🎯 团队协作: 带领前端团队完成技术攻关

🔮 技术展望

这个项目让我深度理解了数字孪生实时监控系统的技术要求,为未来参与不动产数字化平台等类似项目奠定了坚实基础。

核心技能迁移价值

  • MQTT实时通信 → 不动产设备物联网
  • 大数据可视化 → 商业数据分析
  • 性能优化经验 → 移动端小程序优化
  • 数字孪生经验 → 智慧楼宇/园区管理

这篇文章总结了我在船舶数字化监控系统开发中的核心技术实践,希望能为同样面临大数据实时处理挑战的开发者提供参考。

分享这篇文章