| | |
| | | import { useToolboxStore } from '@/stores/toolbox' |
| | | import util from './util' |
| | | import * as echarts from 'echarts' |
| | | import exceedIcon from '@/assets/exceed.png' |
| | | import exceptionIcon from '@/assets/exception.png' |
| | | import offlineIcon from '@/assets/offline.png' |
| | | |
| | | const toolboxStore = useToolboxStore() |
| | | |
| | | var _massMarks = undefined |
| | | |
| | | // 环信码等级和对应颜色 |
| | | const ringCodeLevelColors = [ |
| | | '#52c41a', // 绿色 |
| | | '#faad14', // 黄色 |
| | | '#f5222d', // 红色 |
| | | ] |
| | | // 状态图标配置 |
| | | const statusIcons = { |
| | | exceed: exceedIcon, // 油烟浓度超标 |
| | | exception: exceptionIcon, // 供电异常 |
| | | offline: offlineIcon, // 设备或网络异常 |
| | | online: createCustomMarkerOnline(), // 在线状态 |
| | | offlineStatus: createCustomMarkerOffline(), // 离线状态 |
| | | } |
| | | |
| | | /** |
| | | * 绘制海量点标记 |
| | |
| | | * @param {number} shops[].shop.longitude 经度 |
| | | * @param {string} shops[].shop.ringCodeLevel 最新环信码等级 |
| | | * @param {string} shops[].shop.ringCodePublishTime 最新环信码发布时间 |
| | | * @param {boolean} shops[].shop.isOnline 在线状态 |
| | | * @param {number} shops[].shop.exceptionStatus 异常状态(0: 油烟浓度超标, 1: 供电异常, 2: 设备或网络异常, 3: 无异常) |
| | | * @param {Array} shops[].recentData 近1小时的监测数据 |
| | | * @param {string} shops[].recentData[].sampleTime 数据采样时间 |
| | | * @param {number} shops[].recentData[].oilSmokeConcentration 油烟浓度 |
| | |
| | | */ |
| | | function drawMassMarks(shops) { |
| | | // 配置样式 |
| | | const massMarksStyle = ringCodeLevelColors.map((color, index) => ({ |
| | | url: createCustomMarker(color), |
| | | const massMarksStyle = [ |
| | | { |
| | | url: statusIcons.exceed, |
| | | size: new AMap.Size(20, 20), |
| | | anchor: new AMap.Pixel(10, 10), |
| | | })) |
| | | }, |
| | | { |
| | | url: statusIcons.exception, |
| | | size: new AMap.Size(20, 20), |
| | | anchor: new AMap.Pixel(10, 10), |
| | | }, |
| | | { |
| | | url: statusIcons.offline, |
| | | size: new AMap.Size(20, 20), |
| | | anchor: new AMap.Pixel(10, 10), |
| | | }, |
| | | { |
| | | url: statusIcons.online, |
| | | size: new AMap.Size(32, 32), |
| | | anchor: new AMap.Pixel(10, 10), |
| | | }, |
| | | { |
| | | url: statusIcons.offlineStatus, |
| | | size: new AMap.Size(32, 32), |
| | | anchor: new AMap.Pixel(10, 10), |
| | | }, |
| | | ] |
| | | // 准备海量点数据 |
| | | const massMarksData = shops.map((shop, index) => { |
| | | // 根据环信码等级获取颜色 |
| | | const color = getColorByRingCodeLevel(shop.shop.ringCodeLevel) |
| | | // 根据异常状态和在线状态获取样式索引 |
| | | let styleIndex = 3 // 默认在线状态 |
| | | |
| | | if (shop.shop.exceptionStatus !== undefined) { |
| | | switch (shop.shop.exceptionStatus) { |
| | | case 0: // 油烟浓度超标 |
| | | styleIndex = 0 |
| | | break |
| | | case 1: // 供电异常 |
| | | styleIndex = 1 |
| | | break |
| | | case 2: // 设备或网络异常 |
| | | styleIndex = 2 |
| | | break |
| | | case 3: // 无异常,根据在线状态决定 |
| | | styleIndex = shop.shop.isOnline ? 3 : 4 |
| | | break |
| | | default: |
| | | styleIndex = shop.shop.isOnline ? 3 : 4 |
| | | } |
| | | } else { |
| | | // 没有异常状态时,根据在线状态决定 |
| | | styleIndex = shop.shop.isOnline ? 3 : 4 |
| | | } |
| | | |
| | | return { |
| | | id: index, |
| | | name: shop.shop.name, |
| | | lnglat: [shop.shop.longitude, shop.shop.latitude], |
| | | style: shop.shop.ringCodeLevel, // 样式索引,对应 massMarksStyle |
| | | style: styleIndex, // 样式索引,对应 massMarksStyle |
| | | extData: shop, // 存储完整的店铺信息 |
| | | } |
| | | }) |
| | |
| | | } |
| | | |
| | | /** |
| | | * 根据异常状态获取中文 |
| | | * @param {number} status 异常状态 |
| | | * @returns {string} 中文表示 |
| | | */ |
| | | function getExceptionStatusText(status) { |
| | | switch (status + '') { |
| | | case '0': |
| | | return '油烟浓度超标' |
| | | case '1': |
| | | return '供电异常' |
| | | case '2': |
| | | return '设备或网络异常' |
| | | case '3': |
| | | return '无异常' |
| | | default: |
| | | return '未知状态' |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 根据异常状态获取颜色 |
| | | * @param {number} status 异常状态 |
| | | * @returns {string} 颜色值 |
| | | */ |
| | | function getColorByExceptionStatus(status) { |
| | | switch (status + '') { |
| | | case '0': |
| | | return '#f5222d' // 油烟浓度超标 - 红色 |
| | | case '1': |
| | | return '#faad14' // 供电异常 - 黄色 |
| | | case '2': |
| | | return '#8c8c8c' // 设备或网络异常 - 灰色 |
| | | case '3': |
| | | return '#52c41a' // 无异常 - 绿色 |
| | | default: |
| | | return '#8c8c8c' // 灰色 |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 创建自定义标记 |
| | | * @param {string} color 标记颜色 |
| | | * @returns {string} 标记的SVG URL |
| | |
| | | } |
| | | |
| | | /** |
| | | * 创建在线状态的SVG标记(油烟监测设备形象) |
| | | * @returns {string} 标记的SVG URL |
| | | */ |
| | | function createCustomMarkerOnline() { |
| | | const svg = ` |
| | | <svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"> |
| | | <!-- 设备主体 - 圆角矩形 --> |
| | | <rect x="5" y="8" width="22" height="16" rx="3" fill="#52c41a" stroke="white" stroke-width="2"/> |
| | | |
| | | <!-- 设备顶部 - 弧形 --> |
| | | <path d="M5 8 Q16 3 27 8" stroke="white" stroke-width="2" fill="#389e0d"/> |
| | | |
| | | <!-- 设备底部 - 弧形 --> |
| | | <path d="M5 24 Q16 29 27 24" stroke="white" stroke-width="2" fill="#389e0d"/> |
| | | |
| | | <!-- 设备显示屏 --> |
| | | <rect x="8" y="11" width="16" height="10" rx="2" fill="white"/> |
| | | |
| | | <!-- 显示屏数据 --> |
| | | <path d="M11 14 L21 14" stroke="#52c41a" stroke-width="1.5"/> |
| | | <path d="M11 17 L18 17" stroke="#52c41a" stroke-width="1.5"/> |
| | | <path d="M11 20 L15 20" stroke="#52c41a" stroke-width="1.5"/> |
| | | |
| | | <!-- 设备天线 --> |
| | | <line x1="16" y1="8" x2="16" y2="3" stroke="white" stroke-width="1.5"/> |
| | | <circle cx="16" cy="3" r="1.5" fill="white"/> |
| | | |
| | | <!-- 设备指示灯 --> |
| | | <circle cx="27" cy="16" r="3" fill="#ffffff"/> |
| | | <circle cx="27" cy="16" r="1.5" fill="#52c41a"/> |
| | | |
| | | <!-- 装饰线条 --> |
| | | <line x1="5" y1="13" x2="6" y2="13" stroke="white" stroke-width="1.5"/> |
| | | <line x1="5" y1="19" x2="6" y2="19" stroke="white" stroke-width="1.5"/> |
| | | </svg> |
| | | ` |
| | | return 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(svg))) |
| | | } |
| | | |
| | | /** |
| | | * 创建离线状态的SVG标记(油烟监测设备形象) |
| | | * @returns {string} 标记的SVG URL |
| | | */ |
| | | function createCustomMarkerOffline() { |
| | | const svg = ` |
| | | <svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"> |
| | | <!-- 设备主体 - 圆角矩形 --> |
| | | <rect x="5" y="8" width="22" height="16" rx="3" fill="#8c8c8c" stroke="white" stroke-width="2"/> |
| | | |
| | | <!-- 设备顶部 - 弧形 --> |
| | | <path d="M5 8 Q16 3 27 8" stroke="white" stroke-width="2" fill="#666666"/> |
| | | |
| | | <!-- 设备底部 - 弧形 --> |
| | | <path d="M5 24 Q16 29 27 24" stroke="white" stroke-width="2" fill="#666666"/> |
| | | |
| | | <!-- 设备显示屏 --> |
| | | <rect x="8" y="11" width="16" height="10" rx="2" fill="white"/> |
| | | |
| | | <!-- 显示屏无数据 - 交叉线 --> |
| | | <line x1="11" y1="12" x2="21" y2="22" stroke="#8c8c8c" stroke-width="2"/> |
| | | <line x1="11" y1="22" x2="21" y2="12" stroke="#8c8c8c" stroke-width="2"/> |
| | | |
| | | <!-- 设备天线 --> |
| | | <line x1="16" y1="8" x2="16" y2="3" stroke="white" stroke-width="1.5"/> |
| | | <circle cx="16" cy="3" r="1.5" fill="white"/> |
| | | |
| | | <!-- 设备指示灯 --> |
| | | <circle cx="27" cy="16" r="3" fill="#ffffff"/> |
| | | <circle cx="27" cy="16" r="1.5" fill="#8c8c8c"/> |
| | | |
| | | <!-- 装饰线条 --> |
| | | <line x1="5" y1="13" x2="6" y2="13" stroke="white" stroke-width="1.5"/> |
| | | <line x1="5" y1="19" x2="6" y2="19" stroke="white" stroke-width="1.5"/> |
| | | </svg> |
| | | ` |
| | | return 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(svg))) |
| | | } |
| | | |
| | | /** |
| | | * 显示店铺信息窗口 |
| | | * @param {Object} shop 店铺对象 |
| | | */ |
| | | function showShopInfoWindow(shop) { |
| | | // 准备信息窗口内容 |
| | | // const content = ` |
| | | // <div style="padding: 10px; max-width: 300px;"> |
| | | // <h3 style="margin: 0 0 10px 0; color: #333;">${shop.shop.name}</h3> |
| | | // <div style="font-size: 14px; line-height: 1.5;"> |
| | | // <p><strong>地址:</strong>${shop.shop.address}</p> |
| | | // <p><strong>环信码等级:</strong><span style="color: ${getColorByRingCodeLevel(shop.shop.ringCodeLevel)}">${shop.shop.ringCodeLevel}</span></p> |
| | | // <p><strong>环信码发布时间:</strong>${shop.shop.ringCodePublishTime}</p> |
| | | // <h4 style="margin: 10px 0 5px 0; color: #666;">近1小时监测数据</h4> |
| | | // <div style="max-height: 150px; overflow-y: auto;"> |
| | | // ${shop.recentData |
| | | // .map( |
| | | // (item) => ` |
| | | // <div style="padding: 5px; border-bottom: 1px solid #f0f0f0;"> |
| | | // <p><strong>采样时间:</strong>${item.sampleTime}</p> |
| | | // <p><strong>油烟浓度:</strong>${item.oilSmokeConcentration} mg/m³</p> |
| | | // <p><strong>净化器电流:</strong>${item.purifierCurrent} A</p> |
| | | // <p><strong>风机电流:</strong>${item.fanCurrent} A</p> |
| | | // </div> |
| | | // `, |
| | | // ) |
| | | // .join('')} |
| | | // </div> |
| | | // </div> |
| | | // </div> |
| | | // ` |
| | | // 获取在线状态文本 |
| | | const onlineStatusText = shop.shop.isOnline ? '在线' : '离线' |
| | | // 获取异常状态文本 |
| | | const exceptionStatusText = getExceptionStatusText(shop.shop.exceptionStatus) |
| | | // 获取异常状态颜色 |
| | | const exceptionStatusColor = getColorByExceptionStatus(shop.shop.exceptionStatus) |
| | | |
| | | // 根据状态获取对应的图标 |
| | | let statusIcon = statusIcons.online // 默认在线图标 |
| | | if (shop.shop.exceptionStatus !== undefined) { |
| | | switch (shop.shop.exceptionStatus) { |
| | | case 0: |
| | | statusIcon = statusIcons.exceed |
| | | break |
| | | case 1: |
| | | statusIcon = statusIcons.exception |
| | | break |
| | | case 2: |
| | | statusIcon = statusIcons.offline |
| | | break |
| | | case 3: |
| | | statusIcon = shop.shop.isOnline ? statusIcons.online : statusIcons.offlineStatus |
| | | break |
| | | default: |
| | | statusIcon = shop.shop.isOnline ? statusIcons.online : statusIcons.offlineStatus |
| | | } |
| | | } else { |
| | | statusIcon = shop.shop.isOnline ? statusIcons.online : statusIcons.offlineStatus |
| | | } |
| | | |
| | | // 根据在线状态获取图标 |
| | | const onlineIcon = shop.shop.isOnline ? statusIcons.online : statusIcons.offlineStatus |
| | | |
| | | // 根据异常状态获取图标 |
| | | let exceptionIcon = statusIcons.online // 默认在线图标 |
| | | if (shop.shop.exceptionStatus !== undefined) { |
| | | switch (shop.shop.exceptionStatus) { |
| | | case 0: |
| | | exceptionIcon = statusIcons.exceed |
| | | break |
| | | case 1: |
| | | exceptionIcon = statusIcons.exception |
| | | break |
| | | case 2: |
| | | exceptionIcon = statusIcons.offline |
| | | break |
| | | case 3: |
| | | exceptionIcon = statusIcons.online |
| | | break |
| | | default: |
| | | exceptionIcon = statusIcons.online |
| | | } |
| | | } |
| | | |
| | | const content = ` |
| | | <div style="padding: 10px; width: 400px;"> |
| | | <h3 style="margin: 0 0 10px 0; color: #333;">${shop.shop.name}</h3> |
| | | <div style="font-size: 14px; line-height: 1.5;"> |
| | | <p><strong>地址:</strong>${shop.shop.address}</p> |
| | | <p><strong>在线状态:</strong><span style="color: ${shop.shop.isOnline ? '#52c41a' : '#8c8c8c'}">${onlineStatusText}</span> </p> |
| | | <p><strong>异常状态:</strong><span style="color: ${exceptionStatusColor}">${exceptionStatusText}</span></p> |
| | | <p><strong>环信码等级:</strong><span style="color: ${getColorByRingCodeLevel(shop.shop.ringCodeLevel)}">${getRingCodeLevelText(shop.shop.ringCodeLevel)}</span></p> |
| | | <p><strong>环信码发布时间:</strong>${shop.shop.ringCodePublishTime}</p> |
| | | <h4 style="margin: 10px 0 5px 0; color: #666;">近1小时监测数据</h4> |