update
@ -10,6 +10,6 @@ VITE_APP_BASE_API = '/prod-api'
|
|||||||
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
||||||
VITE_BUILD_COMPRESS = gzip
|
VITE_BUILD_COMPRESS = gzip
|
||||||
|
|
||||||
VITE_PUBLIC_BASE_PATH = '/'
|
VITE_PUBLIC_BASE_PATH = '/ras-web'
|
||||||
|
|
||||||
VITE_APP_WS_API = ''
|
VITE_APP_WS_API = ''
|
1
path/to/src/views/screen/R_D_Environment1/index.vue
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
98
src/api/screen/micro.js
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 查询设备列表
|
||||||
|
export function listDevice(devId) {
|
||||||
|
return request({
|
||||||
|
url: '/mf/device',
|
||||||
|
method: 'get',
|
||||||
|
params: { devId }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询设备能耗排行
|
||||||
|
export function listElect(type) {
|
||||||
|
return request({
|
||||||
|
url: '/mf/elect?type=' + type,
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询设备用电监测
|
||||||
|
export function electMonitoring() {
|
||||||
|
return request({
|
||||||
|
url: '/mf/electMonitoring',
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询设备状态
|
||||||
|
export function deviceStatus() {
|
||||||
|
return request({
|
||||||
|
url: '/mf/deviceStatus',
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设备利用率
|
||||||
|
export function deviceRate() {
|
||||||
|
return request({
|
||||||
|
url: '/mf/deviceRate',
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设备保养提醒
|
||||||
|
export function deviceCheck(devId) {
|
||||||
|
return request({
|
||||||
|
url: '/mf/deviceCheck',
|
||||||
|
method: 'get',
|
||||||
|
params: { devId }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//设备报警记录
|
||||||
|
export function deviceRepair(devId) {
|
||||||
|
return request({
|
||||||
|
url: '/mf/deviceRepair',
|
||||||
|
method: 'get',
|
||||||
|
params: { devId }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//单设备运行状态
|
||||||
|
export function deviceStatusById(devId) {
|
||||||
|
return request({
|
||||||
|
url: '/mf/deviceStatusById',
|
||||||
|
method: 'get',
|
||||||
|
params: { devId }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//单设备运行状态
|
||||||
|
export function deviceStatusChart(devId) {
|
||||||
|
return request({
|
||||||
|
url: '/mf/deviceStatusChart',
|
||||||
|
method: 'get',
|
||||||
|
params: { devId }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//单设备运行状态
|
||||||
|
export function deviceRateChart(devId) {
|
||||||
|
return request({
|
||||||
|
url: '/mf/deviceRateChart',
|
||||||
|
method: 'get',
|
||||||
|
params: { devId }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//单设备用电量图表
|
||||||
|
export function deviceElectChart(devId) {
|
||||||
|
return request({
|
||||||
|
url: '/mf/deviceElectChart',
|
||||||
|
method: 'get',
|
||||||
|
params: { devId }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
BIN
src/assets/images/screen-bg.png
Normal file
After Width: | Height: | Size: 158 KiB |
BIN
src/assets/images/screen-header-bg1.png
Normal file
After Width: | Height: | Size: 40 KiB |
135
src/components/ZdScrollBoard/scrollBoard.vue
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
<!--
|
||||||
|
* @FilePath: \code\gitscreenFront\src\views\Mechanics\components\scrollBoard.vue
|
||||||
|
* @Author: 王路平
|
||||||
|
* @文件版本: V1.0.0
|
||||||
|
* @Date: 2023-06-13 08:33:37
|
||||||
|
* @Description:
|
||||||
|
*
|
||||||
|
* 版权信息 : 2023 by ${RAS}, All Rights Reserved.
|
||||||
|
-->
|
||||||
|
<template>
|
||||||
|
<div class="box">
|
||||||
|
|
||||||
|
<ZdScrollBoard ref="devList" @click="dvClick" :config="newConfig" @mouseover="dvMouseover"
|
||||||
|
@mouseout="dvmouseleave" :style="{
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
}" />
|
||||||
|
<el-tooltip v-model:visible="visible" :content="tipcontent" effect="light" placement="top" trigger="click"
|
||||||
|
popper-class="tooltip-class" virtual-triggering :virtual-ref="triggerRef" />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang='ts'>
|
||||||
|
import { getCurrentInstance, onMounted, reactive, ref, watch,computed } from "vue";
|
||||||
|
import ZdScrollBoard from "@/components/ZdScrollBoard/index.vue";
|
||||||
|
import { useRouter } from "vue-router"
|
||||||
|
|
||||||
|
const prop = defineProps({
|
||||||
|
config: Object,
|
||||||
|
data: <any>Array
|
||||||
|
})
|
||||||
|
let newConfig: any = computed(() => {
|
||||||
|
return {
|
||||||
|
...prop.config,
|
||||||
|
data: prop.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const router = useRouter()
|
||||||
|
const emit: any = defineEmits()
|
||||||
|
//弹窗文本
|
||||||
|
let tipcontent = ref(null)
|
||||||
|
//弹窗显示与隐藏
|
||||||
|
let visible = ref(false)
|
||||||
|
//存储弹窗dom
|
||||||
|
let triggerRef = ref(null)
|
||||||
|
let devList = ref(null)
|
||||||
|
/**
|
||||||
|
* @函数功能: 鼠标移入组件方法
|
||||||
|
* @param {*} value
|
||||||
|
* @出口参数:
|
||||||
|
* @函数备注:
|
||||||
|
*/
|
||||||
|
const dvMouseover = (value) => {
|
||||||
|
if (value.toElement && value.toElement.innerHTML && value.toElement.className == 'ceil') {
|
||||||
|
triggerRef.value = value.toElement
|
||||||
|
tipcontent.value = value.toElement.innerText
|
||||||
|
visible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
// watch(
|
||||||
|
// () => prop.data,
|
||||||
|
// (val) => {
|
||||||
|
|
||||||
|
// devList.value.updateRows(val)
|
||||||
|
|
||||||
|
// },
|
||||||
|
// { deep: true, immediate: false }
|
||||||
|
// );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 点击表格事件
|
||||||
|
*/
|
||||||
|
const dvClick = (value) => {
|
||||||
|
|
||||||
|
if (value.row) {
|
||||||
|
emit('dvclick', value)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @函数功能: 鼠标移出组件方法
|
||||||
|
* @出口参数:
|
||||||
|
* @函数备注:
|
||||||
|
*/
|
||||||
|
const dvmouseleave = () => {
|
||||||
|
triggerRef.value = null
|
||||||
|
tipcontent.value = null
|
||||||
|
visible.value = false
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.box {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-title {
|
||||||
|
width: 100%;
|
||||||
|
font-size: 20px;
|
||||||
|
margin: 5px 0 10px 0;
|
||||||
|
color: #fff;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-body {
|
||||||
|
width: 100%;
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.dv-scroll-board .rows .ceil) {
|
||||||
|
overflow: auto;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
text-overflow: none
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.dv-scroll-board .rows .row-item) {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style>
|
||||||
|
.el-popper.tooltip-class {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
</style>
|
@ -77,16 +77,28 @@ export const constantRoutes = [
|
|||||||
hidden: true,
|
hidden: true,
|
||||||
redirect: 'noredirect',
|
redirect: 'noredirect',
|
||||||
children: [
|
children: [
|
||||||
|
// {
|
||||||
|
// path: "/screen/R_D_Environment",
|
||||||
|
// name: "R_D_Environment",
|
||||||
|
// component: () => import("../views/screen/R_D_Environment/index.vue"),
|
||||||
|
// hidden: true
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
path: "/screen/R_D_Environment",
|
path: "/screen/R_D_Environment",
|
||||||
name: "R_D_Environment",
|
name: "R_D_Environment",
|
||||||
component: () => import("../views/screen/R_D_Environment/index.vue"),
|
component: () => import("../views/screen/R_D_Environment/index.vue"),
|
||||||
hidden: true
|
hidden: true
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: "/screen/R_D_Environment1",
|
path: "microFactory",
|
||||||
name: "R_D_Environment1",
|
name: "MicroFactory",
|
||||||
component: () => import("../views/screen/R_D_Environment1/index.vue"),
|
component: () => import("../views/screen/microFactory/index.vue"),
|
||||||
|
// meta: { title: '大屏首页', icon: 'dashboard', affix: true }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "devItem_:id",
|
||||||
|
component: () => import("../views/screen/devItem/index.vue"),
|
||||||
hidden: true
|
hidden: true
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
@ -41,7 +41,7 @@ onMounted(() => {
|
|||||||
initModel();
|
initModel();
|
||||||
|
|
||||||
viewer.scene.traverse((item: THREE.Object3D) => {
|
viewer.scene.traverse((item: THREE.Object3D) => {
|
||||||
console.log(item, '0000000000');
|
//console.log(item, '0000000000');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -58,6 +58,7 @@ const init = () => {
|
|||||||
boxHelperWrap = new BoxHelperWrap(viewer);
|
boxHelperWrap = new BoxHelperWrap(viewer);
|
||||||
|
|
||||||
viewer.emitter.on(Event.dblclick.raycaster, (list: THREE.Intersection[]) => {
|
viewer.emitter.on(Event.dblclick.raycaster, (list: THREE.Intersection[]) => {
|
||||||
|
|
||||||
onMouseClick(list);
|
onMouseClick(list);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -174,7 +175,6 @@ const initModel = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const planeAnimate = (texture: any): Animate => {
|
const planeAnimate = (texture: any): Animate => {
|
||||||
// console.log(texture, 'texture');
|
|
||||||
texture.wrapS = THREE.RepeatWrapping;
|
texture.wrapS = THREE.RepeatWrapping;
|
||||||
texture.wrapT = THREE.RepeatWrapping;
|
texture.wrapT = THREE.RepeatWrapping;
|
||||||
const animateFn = {
|
const animateFn = {
|
||||||
@ -208,7 +208,7 @@ const onMouseClick = (intersects: THREE.Intersection[]) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
findClickModel(selectedObject);
|
findClickModel(selectedObject);
|
||||||
console.log(selectedObjectName);
|
//console.log(selectedObjectName);
|
||||||
|
|
||||||
// if (!selectedObjectName || !selectedObjectName.includes('办公楼')) {
|
// if (!selectedObjectName || !selectedObjectName.includes('办公楼')) {
|
||||||
// // this.scene.remove(this.label);
|
// // this.scene.remove(this.label);
|
||||||
@ -216,7 +216,7 @@ const onMouseClick = (intersects: THREE.Intersection[]) => {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// const selectedModel = viewer.scene.getObjectByName(selectedObjectName);
|
// const selectedModel = viewer.scene.getObjectByName(selectedObjectName);
|
||||||
console.log(selectedObject, 'selectedObject');
|
//console.log(selectedObject, 'selectedObject');
|
||||||
|
|
||||||
// 点击楼房
|
// 点击楼房
|
||||||
if (selectedObject.name.includes('zuo')) {
|
if (selectedObject.name.includes('zuo')) {
|
||||||
@ -272,10 +272,9 @@ const onMouseMove = (intersects: THREE.Intersection[]) => {
|
|||||||
// };
|
// };
|
||||||
findClickModel(selectedObject);
|
findClickModel(selectedObject);
|
||||||
|
|
||||||
console.log(selectedObjectName, '--selectedObjectName---');
|
// console.log(selectedObjectName,selectedObject, '--selectedObjectName---');
|
||||||
console.log(selectedObject, '------selectedObject---------');
|
|
||||||
const rack = findParent(selectedObject, checkIsRack);
|
const rack = findParent(selectedObject, checkIsRack);
|
||||||
console.log(rack, '-------rack---------');
|
// console.log(rack, '-------rack---------');
|
||||||
if (rack) {
|
if (rack) {
|
||||||
|
|
||||||
boxHelperWrap.attach(rack);
|
boxHelperWrap.attach(rack);
|
||||||
|
@ -1,202 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div ref="threeContainer"></div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import * as THREE from 'three';
|
|
||||||
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader';
|
|
||||||
import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader';
|
|
||||||
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
|
|
||||||
import { CSS3DObject, CSS3DRenderer } from 'three/examples/jsm/Addons.js';
|
|
||||||
import { onMounted, ref } from 'vue';
|
|
||||||
|
|
||||||
const threeContainer = ref(null);
|
|
||||||
let camera, scene, renderer, model, controls, cssRenderer;
|
|
||||||
let width = 1920;
|
|
||||||
let height = 1080;
|
|
||||||
let text = ref('标注1');
|
|
||||||
const init = () => {
|
|
||||||
scene = new THREE.Scene();
|
|
||||||
// scene.background = new THREE.Color(0x100c2a);//0x100c2a
|
|
||||||
// scene.background.setAlpha(0);
|
|
||||||
camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 2000);
|
|
||||||
camera.position.set(40, 300, 200);
|
|
||||||
|
|
||||||
renderer = new THREE.WebGLRenderer({
|
|
||||||
antialias: true,
|
|
||||||
alpha: true
|
|
||||||
});
|
|
||||||
renderer.setSize(width, height);
|
|
||||||
threeContainer.value.appendChild(renderer.domElement);
|
|
||||||
|
|
||||||
cssRenderer = initLabelRenderer(threeContainer.value);
|
|
||||||
const objLoader = new OBJLoader();
|
|
||||||
let mtlLoader = new MTLLoader();
|
|
||||||
mtlLoader.load('/src/assets/obj/goats_R&D.mtl', function (materials) {
|
|
||||||
materials.preload();
|
|
||||||
objLoader.setMaterials(materials);
|
|
||||||
objLoader.load('/src/assets/obj/goats_R&D.obj', function (obj) {
|
|
||||||
var scale = 0.07 / obj.scale.x;
|
|
||||||
obj.scale.set(scale, scale, scale);
|
|
||||||
model = obj;
|
|
||||||
const box = new THREE.Box3().setFromObject(model);
|
|
||||||
const size = box.getSize(new THREE.Vector3())
|
|
||||||
// console.log(size,'-----');
|
|
||||||
obj.position.set(-size.x * 0.5, -size.y * 0.1, -size.z * 0.5);
|
|
||||||
obj.children.forEach((child) => {
|
|
||||||
const c = child;
|
|
||||||
const cm = c.material;
|
|
||||||
cm.emissive = cm.color;
|
|
||||||
cm.emissiveMap = cm.map;
|
|
||||||
});
|
|
||||||
addMarks(text.value);
|
|
||||||
scene.add(model);
|
|
||||||
animate();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
// loader.load(
|
|
||||||
// '/src/assets/obj/goats_R&D.obj',
|
|
||||||
// (obj) => {
|
|
||||||
// var scale = 0.1 / obj.scale.x;
|
|
||||||
// obj.scale.set(scale, scale, scale);
|
|
||||||
// model = obj;
|
|
||||||
// // 添加光照
|
|
||||||
// // scene.add(new THREE.AmbientLight(0x404040));
|
|
||||||
// scene.add(new THREE.DirectionalLight());
|
|
||||||
// scene.add(model);
|
|
||||||
// },
|
|
||||||
// (xhr) => {
|
|
||||||
// console.log((xhr.loaded / xhr.total * 100) + '% loaded');
|
|
||||||
// },
|
|
||||||
// (error) => {
|
|
||||||
// console.error('An error happened: ', error);
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
|
|
||||||
controls = new OrbitControls(camera, cssRenderer.domElement);
|
|
||||||
controls.enableDamping = true;
|
|
||||||
|
|
||||||
animate();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 初始化标注渲染器
|
|
||||||
const initLabelRenderer = boxElement => {
|
|
||||||
const labelRenderer = new CSS3DRenderer();
|
|
||||||
labelRenderer.setSize(width, height);
|
|
||||||
labelRenderer.domElement.style.position = 'absolute';
|
|
||||||
labelRenderer.domElement.style.top = 0;
|
|
||||||
boxElement.appendChild(labelRenderer.domElement);
|
|
||||||
return labelRenderer;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
function addMarks(text) {
|
|
||||||
//把传入的标注文字通过 canvas 修改为可以添加到场景中的 texture
|
|
||||||
const offScreenCanvas = document.createElement('canvas');
|
|
||||||
const offScreenCtx = offScreenCanvas.getContext('2d');
|
|
||||||
// 配置字体、大小、颜色等
|
|
||||||
offScreenCtx.font = '16px 黑体';
|
|
||||||
const txt = text;
|
|
||||||
const textWidth = offScreenCtx.measureText(txt).width;
|
|
||||||
const canvas = document.createElement('canvas');
|
|
||||||
const ctx = canvas.getContext('2d');
|
|
||||||
if (ctx !== null) {
|
|
||||||
// pixelRatio: 像素密度
|
|
||||||
canvas.width = (5 + textWidth + 5) * 2;
|
|
||||||
canvas.height = 18 * 2;
|
|
||||||
ctx.setTransform(2, 0, 0, 2, 0, 0);
|
|
||||||
ctx.font = '16px 黑体';
|
|
||||||
ctx.fillStyle = '#fff'; //标注背景颜色
|
|
||||||
ctx.fillRect(0, 0, 5 + textWidth + 5, 18);
|
|
||||||
ctx.fillStyle = '#000'; //标注字体颜色
|
|
||||||
ctx.fillText(txt, 5, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 将标注变成可以添加到场景中的 texture 对象
|
|
||||||
const texture = new THREE.CanvasTexture(canvas);
|
|
||||||
|
|
||||||
|
|
||||||
var geometry2 = new THREE.BufferGeometry();
|
|
||||||
var material = new THREE.LineBasicMaterial({ vertexColors: true });
|
|
||||||
var color1 = new THREE.Color(0xffffff), color2 = new THREE.Color(0xffffff);
|
|
||||||
//定义第一条线
|
|
||||||
var p3 = new THREE.Vector3(0, 50, 40);
|
|
||||||
var p4 = new THREE.Vector3(4, 23.5, 10);
|
|
||||||
const points = [];
|
|
||||||
points.push(p3);
|
|
||||||
points.push(p4);
|
|
||||||
// geometry2.vertices.push(p3);
|
|
||||||
// geometry2.vertices.push(p4);
|
|
||||||
// geometry2.colors.push(color1, color2);
|
|
||||||
geometry2.setFromPoints(points);
|
|
||||||
//把线条添加到场景中
|
|
||||||
var line2 = new THREE.Line(geometry2, material, THREE.LinePieces);
|
|
||||||
scene.add(line2);
|
|
||||||
//定义第一个标签
|
|
||||||
/**精灵图 */
|
|
||||||
// var spriteMaterial2 = new THREE.SpriteMaterial({ map: texture, color: 0xffffff });
|
|
||||||
// var sprite2 = new THREE.Sprite(spriteMaterial2);
|
|
||||||
// sprite2.position.set(0, 50, 40);
|
|
||||||
// sprite2.scale.set(15, 5, 0);
|
|
||||||
// scene.add(sprite2);
|
|
||||||
|
|
||||||
|
|
||||||
/** CSS3D */
|
|
||||||
const label = new CSS3DObject(document.createElement('div'));
|
|
||||||
label.position.set(0, 50, 40);
|
|
||||||
label.scale.set(0.5, 0.5, 0.5);
|
|
||||||
label.element.style.backgroundColor = '#fff';
|
|
||||||
label.element.innerText = text;
|
|
||||||
scene.add(label);
|
|
||||||
// 调整显示方向
|
|
||||||
// 假设我们要将HTML元素旋转90度绕Y轴,使其从正前方指向右方
|
|
||||||
label.rotation.set(-Math.PI / 4,0, 0);
|
|
||||||
|
|
||||||
//定义标记点
|
|
||||||
var radius = 0.5, segemnt = 16, rings = 16;
|
|
||||||
var sphereMaterial = new THREE.MeshLambertMaterial({ color: 0x9afc00 });
|
|
||||||
var sphere101 = new THREE.Mesh(new THREE.SphereGeometry(radius, segemnt, rings), sphereMaterial);
|
|
||||||
sphere101.position.set(4, 23.5, 10);
|
|
||||||
scene.add(sphere101);
|
|
||||||
|
|
||||||
// var group = new THREE.Object3D();
|
|
||||||
// group.add(line2);
|
|
||||||
// group.add(sphere101);
|
|
||||||
// group.add(sprite2);
|
|
||||||
// scene.add(group);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const animate = () => {
|
|
||||||
requestAnimationFrame(animate);
|
|
||||||
renderer.render(scene, camera);
|
|
||||||
cssRenderer.render(scene, camera);
|
|
||||||
controls.update();
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
init();
|
|
||||||
|
|
||||||
window.addEventListener('resize', onWindowResize);
|
|
||||||
});
|
|
||||||
|
|
||||||
const onWindowResize = () => {
|
|
||||||
camera.aspect = window.innerWidth / window.innerHeight;
|
|
||||||
camera.updateProjectionMatrix();
|
|
||||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
window.removeEventListener('resize', onWindowResize);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
#threeContainer {
|
|
||||||
width: 1920px;
|
|
||||||
height: 1080px;
|
|
||||||
/* 根据需要调整位置 */
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,147 +0,0 @@
|
|||||||
<template>
|
|
||||||
<v-chart :option="options" theme="dark" style="width: 100%;height: 100%;" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { computed } from 'vue';
|
|
||||||
const prop = defineProps({
|
|
||||||
data: {
|
|
||||||
type: Object,
|
|
||||||
default: () => {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const options = computed(() => {
|
|
||||||
return {
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'axis',
|
|
||||||
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
|
||||||
borderColor: '#00c6ff',
|
|
||||||
borderWidth: 2,
|
|
||||||
textStyle: {
|
|
||||||
color: '#fff',
|
|
||||||
fontSize: 14
|
|
||||||
},
|
|
||||||
formatter: function (params) {
|
|
||||||
let tooltipText = '';
|
|
||||||
let xAxisValue = params[0].name;
|
|
||||||
params.forEach((item) => {
|
|
||||||
tooltipText += `<div style="padding: 2px 0;"><strong>${item.seriesName}:</strong> ${item.value}</div>`;
|
|
||||||
});
|
|
||||||
return `${xAxisValue}<br>${tooltipText}`;
|
|
||||||
},
|
|
||||||
padding: 10,
|
|
||||||
extraCssText: 'border-radius: 8px; box-shadow: 0 0 15px rgba(0, 0, 0, 0.5);'
|
|
||||||
},
|
|
||||||
backgroundColor: 'transparent',
|
|
||||||
legend: {
|
|
||||||
show: true,
|
|
||||||
data: ['目标产量', '实际产量'],
|
|
||||||
textStyle: {
|
|
||||||
color: '#fff',
|
|
||||||
|
|
||||||
},
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
type: 'category',
|
|
||||||
data: ['102410', '102411', '102412', '102413', '102414', '102415', '102416', '102417'],
|
|
||||||
axisLabel: {
|
|
||||||
color: "#ffffff",
|
|
||||||
interval: 0,
|
|
||||||
},
|
|
||||||
axisLine: {
|
|
||||||
lineStyle: {
|
|
||||||
color: '#0091ea'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
axisTick: {
|
|
||||||
show: false,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
yAxis: [
|
|
||||||
{
|
|
||||||
type: 'value',
|
|
||||||
axisTick: {
|
|
||||||
show: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'value',
|
|
||||||
axisTick: {
|
|
||||||
show: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: '目标产量',
|
|
||||||
data: [150, 105, 110, 80, 120, 100, 140, 180],
|
|
||||||
yAxisIndex: 0,
|
|
||||||
type: 'bar',
|
|
||||||
barCategoryGap: '10%',
|
|
||||||
showBackground: true,
|
|
||||||
itemStyle: {
|
|
||||||
color: {
|
|
||||||
type: 'linear',
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
x2: 1,
|
|
||||||
y2: 1,
|
|
||||||
colorStops: [
|
|
||||||
{ offset: 0, color: '#5aaef3' },
|
|
||||||
{ offset: 1, color: '#1e90ff' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
borderRadius: [60, 60, 60, 60],
|
|
||||||
stroke: '#00c6ff',
|
|
||||||
lineWidth: 2
|
|
||||||
},
|
|
||||||
label: {
|
|
||||||
show: true,
|
|
||||||
position: 'top',
|
|
||||||
color: '#ffffff'
|
|
||||||
},
|
|
||||||
backgroundStyle: {
|
|
||||||
borderRadius: [60, 60, 60, 60],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '实际产量',
|
|
||||||
yAxisIndex: 1,
|
|
||||||
data: [106, 90, 25, 80, 35, 100, 140, 172],
|
|
||||||
type: 'bar',
|
|
||||||
barCategoryGap: '10%',
|
|
||||||
showBackground: true,
|
|
||||||
itemStyle: {
|
|
||||||
color: {
|
|
||||||
type: 'linear',
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
x2: 1,
|
|
||||||
y2: 1,
|
|
||||||
colorStops: [
|
|
||||||
{ offset: 0, color: '#f8efd4' },
|
|
||||||
{ offset: 1, color: '#fbdc7f' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
borderRadius: [60, 60, 60, 60],
|
|
||||||
stroke: '#ff6347',
|
|
||||||
lineWidth: 2
|
|
||||||
},
|
|
||||||
label: {
|
|
||||||
show: true,
|
|
||||||
position: 'top',
|
|
||||||
color: '#ffffff'
|
|
||||||
},
|
|
||||||
backgroundStyle: {
|
|
||||||
borderRadius: [60, 60, 60, 60],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
@ -1,64 +0,0 @@
|
|||||||
<template>
|
|
||||||
<v-chart :option="options" theme="dark" style="width: 100%;height: 100%;" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { computed } from 'vue';
|
|
||||||
const prop = defineProps({
|
|
||||||
data: {
|
|
||||||
type: Object,
|
|
||||||
default: () => {
|
|
||||||
return {
|
|
||||||
date: ['2021-10-01', '2021-10-02', '2021-10-03', '2021-10-04', '2021-10-05', '2021-10-06', '2021-10-07'],
|
|
||||||
series: [{
|
|
||||||
type: '温度',
|
|
||||||
value: [20, 22, 23, 24, 25, 26, 27]
|
|
||||||
}, {
|
|
||||||
type: '湿度',
|
|
||||||
value: [30, 32, 33, 34, 35, 36, 37]
|
|
||||||
}]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const options = computed(() => {
|
|
||||||
let seriesData = [];
|
|
||||||
prop.data.series.forEach(res => {
|
|
||||||
seriesData.push({
|
|
||||||
name: res.type,
|
|
||||||
type: 'line',
|
|
||||||
showSymbol: false,
|
|
||||||
data: prop.data.date.map((key, value) => [key, res.value[value]]),
|
|
||||||
smooth: true,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
backgroundColor: 'transparent',
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'axis',
|
|
||||||
},
|
|
||||||
|
|
||||||
grid: {
|
|
||||||
top: "15%",
|
|
||||||
left: "5%",
|
|
||||||
right: "5%",
|
|
||||||
bottom: "5%",
|
|
||||||
containLabel: true,
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
type: 'time',
|
|
||||||
splitLine: {
|
|
||||||
show: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
type: 'value',
|
|
||||||
},
|
|
||||||
series: seriesData
|
|
||||||
};
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
@ -1,201 +0,0 @@
|
|||||||
<template>
|
|
||||||
<v-chart :option="options" style="width: 100%;height: 100%;" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { computed } from 'vue';
|
|
||||||
const prop = defineProps({
|
|
||||||
value: {
|
|
||||||
type: Object,
|
|
||||||
default: () => {
|
|
||||||
return {
|
|
||||||
Humiture: [{
|
|
||||||
"devId": "eb98cb70-158f-11ee-b4df-a9653aef169c",
|
|
||||||
"name": "服装军团",
|
|
||||||
"temp": "18.2",
|
|
||||||
"humidity": "32.2",
|
|
||||||
"status": true
|
|
||||||
}],
|
|
||||||
top: { temp: 0, humidity: 0 },
|
|
||||||
bottom: { temp: 0, humidity: 0 }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const options = computed(() => {
|
|
||||||
|
|
||||||
//x轴数据
|
|
||||||
let x = [];
|
|
||||||
//y轴数据
|
|
||||||
let y = { temp: [], humidity: [] };
|
|
||||||
|
|
||||||
prop.value.Humiture.forEach((res) => {
|
|
||||||
x.push(res.name);
|
|
||||||
y.temp.push(res.temp);
|
|
||||||
y.humidity.push(res.humidity);
|
|
||||||
});
|
|
||||||
return {
|
|
||||||
tooltip: {
|
|
||||||
trigger: "axis",
|
|
||||||
axisPointer: {
|
|
||||||
type: "shadow",
|
|
||||||
},
|
|
||||||
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
// bottom: "3%",
|
|
||||||
top: '6%'
|
|
||||||
},
|
|
||||||
grid: {
|
|
||||||
top: "15%",
|
|
||||||
left: "3%",
|
|
||||||
right: "4%",
|
|
||||||
bottom: "3%",
|
|
||||||
containLabel: true,
|
|
||||||
},
|
|
||||||
color: ["#4992FF", "#7CFFB2", "#FF6E76"],
|
|
||||||
xAxis: {
|
|
||||||
type: "category",
|
|
||||||
data: x,
|
|
||||||
axisLabel: {
|
|
||||||
interval: 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
name: "温度(°C)/湿度(%RH)",
|
|
||||||
type: "value",
|
|
||||||
boundaryGap: [0, 0.01],
|
|
||||||
axisLabel: {
|
|
||||||
formatter: "{value}",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
//name: `${'温度'}(°C)(${t('messages.fanwei')}:${value.bottom.temp}°C - ${value.top.temp}°C)`,
|
|
||||||
type: "bar",
|
|
||||||
data: y.temp,
|
|
||||||
barWidth: '30%',
|
|
||||||
itemStyle: {
|
|
||||||
color: function (params) {
|
|
||||||
var index_color = params.value;
|
|
||||||
if (
|
|
||||||
index_color <= prop.value.bottom.temp ||
|
|
||||||
index_color >= prop.value.top.temp
|
|
||||||
) {
|
|
||||||
return "#FF6E76";
|
|
||||||
} else {
|
|
||||||
return "#4992FF";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
label: {
|
|
||||||
formatter: "{c} °C",
|
|
||||||
show: true,
|
|
||||||
position: "top",
|
|
||||||
textStyle: {
|
|
||||||
color: "rgb(255,255,255,0.9)",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
markLine: {
|
|
||||||
// 设置最大值和最小值
|
|
||||||
silent: true, //基线显示 隐藏
|
|
||||||
symbol: "none", // 不显示箭头和圆点
|
|
||||||
data: [
|
|
||||||
{
|
|
||||||
name: '温度',
|
|
||||||
yAxis: prop.value.bottom.temp,
|
|
||||||
label: {
|
|
||||||
formatter: `温度下限值: ${prop.value.bottom.temp} °C`,
|
|
||||||
position: "middle",
|
|
||||||
},
|
|
||||||
lineStyle: {
|
|
||||||
color: "yellow", // 这儿设置安全基线颜色
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '温度',
|
|
||||||
yAxis: prop.value.top.temp,
|
|
||||||
label: {
|
|
||||||
formatter: `温度上限值:${prop.value.top.temp} °C`,
|
|
||||||
position: "middle",
|
|
||||||
},
|
|
||||||
lineStyle: {
|
|
||||||
color: "yellow", // 这儿设置安全基线颜色
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
//name: `${t('messages.HumidityRange')}(%RH)(${t('messages.fanwei')}:${value.bottom.humidity}%RH - ${value.top.humidity}%RH)`,
|
|
||||||
name: `湿度(%RH)(范围:${prop.value.bottom.humidity}%RH - ${prop.value.top.humidity}%RH)`,
|
|
||||||
type: "bar",
|
|
||||||
data: y.humidity,
|
|
||||||
barWidth: '30%',
|
|
||||||
itemStyle: {
|
|
||||||
color: function (params) {
|
|
||||||
var index_color = params.value;
|
|
||||||
|
|
||||||
if (
|
|
||||||
index_color <= prop.value.bottom.humidity ||
|
|
||||||
index_color >= prop.value.top.humidity
|
|
||||||
) {
|
|
||||||
return "#FF6E76";
|
|
||||||
} else {
|
|
||||||
return "#7CFFB2";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
label: {
|
|
||||||
formatter: "{c} %RH",
|
|
||||||
show: true,
|
|
||||||
position: "top",
|
|
||||||
textStyle: {
|
|
||||||
color: "rgb(255,255,255,0.9)",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
markLine: {
|
|
||||||
// 设置最大值和最小值
|
|
||||||
silent: true, //基线显示 隐藏
|
|
||||||
symbol: "none", // 不显示箭头和圆点
|
|
||||||
data: [
|
|
||||||
{
|
|
||||||
name: "湿度",
|
|
||||||
yAxis: prop.value.bottom.humidity,
|
|
||||||
label: {
|
|
||||||
// formatter: `${t('messages.HumidityRange')}${t('messages.TemperatureRange_down')}:` + value.bottom.humidity + "%RH",
|
|
||||||
formatter: `湿度下限值:` + prop.value.bottom.humidity + "%RH",
|
|
||||||
|
|
||||||
position: "middle",
|
|
||||||
},
|
|
||||||
lineStyle: {
|
|
||||||
color: "red", // 这儿设置安全基线颜色
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "湿度",
|
|
||||||
yAxis: prop.value.top.humidity,
|
|
||||||
label: {
|
|
||||||
// formatter: `${t('messages.HumidityRange')}${t('messages.TemperatureRange_up')}:` + value.top.humidity + "%RH",
|
|
||||||
formatter: `湿度上限值:` + prop.value.top.humidity + "%RH",
|
|
||||||
position: "middle",
|
|
||||||
},
|
|
||||||
lineStyle: {
|
|
||||||
color: "red", // 这儿设置安全基线颜色
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '超标(温湿度未达正常值均为超标)',
|
|
||||||
type: "bar",
|
|
||||||
color: '#FF6E76'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
};
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
@ -1,52 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="item-container">
|
|
||||||
<div class="box-title" :class="[prop.pos == 'left'?'pos-l':'pos-r']">{{ prop.title }}</div>
|
|
||||||
<div class="content">
|
|
||||||
<slot></slot>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
|
|
||||||
const prop = defineProps({
|
|
||||||
title: {
|
|
||||||
type: String,
|
|
||||||
default: '标题'
|
|
||||||
},
|
|
||||||
pos: {
|
|
||||||
type: String,
|
|
||||||
default: 'left'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.item-container {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
.box-title {
|
|
||||||
width: 100%;
|
|
||||||
height: 41px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding-left: 25px;
|
|
||||||
font-size: 20px;
|
|
||||||
line-height: 40px;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
.pos-l {
|
|
||||||
// background: linear-gradient(to right, #102238 0%, transparent 100%);
|
|
||||||
background: url('/src/assets/images/box-title-l.png') no-repeat center center / 100% 100%;
|
|
||||||
}
|
|
||||||
.pos-r {
|
|
||||||
// background: linear-gradient(to left, #102238 0%, transparent 100%);
|
|
||||||
background: url('/src/assets/images/box-title-r.png') no-repeat center center / 100% 100%;
|
|
||||||
text-align: right;
|
|
||||||
padding-right: 25px;
|
|
||||||
}
|
|
||||||
.content {
|
|
||||||
width: 100%;
|
|
||||||
height: calc(100% - 41px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,62 +0,0 @@
|
|||||||
<template>
|
|
||||||
<v-chart :option="options" theme="dark" style="width: 100%;height: 100%;" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { computed } from 'vue';
|
|
||||||
const prop = defineProps({
|
|
||||||
data: {
|
|
||||||
type: Object,
|
|
||||||
default: () => {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const options = computed(() => {
|
|
||||||
return {
|
|
||||||
tooltip: {
|
|
||||||
trigger: "axis",
|
|
||||||
formatter: function (params) {
|
|
||||||
let tooltipText = '';
|
|
||||||
let xAxisValue = params[0].name; // 获取 x 轴的值
|
|
||||||
params.forEach((item) => {
|
|
||||||
tooltipText += `${item.marker}${item.seriesName}: ${item.value} kWh<br>`;
|
|
||||||
});
|
|
||||||
return `${xAxisValue}<br>${tooltipText}`;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
backgroundColor: 'transparent',
|
|
||||||
xAxis: {
|
|
||||||
type: 'category',
|
|
||||||
data: ['9:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00'],
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
type: 'value',
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: "耗电量",
|
|
||||||
data: [820, 932, 901, 934, 1290, 1330, 1320],
|
|
||||||
type: 'line',
|
|
||||||
smooth: true,
|
|
||||||
areaStyle: {
|
|
||||||
color: {
|
|
||||||
type: 'linear',
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
x2: 0,
|
|
||||||
y2: 1,
|
|
||||||
colorStops: [
|
|
||||||
{ offset: 0, color: 'rgba(0, 198, 255, 0.5)' },
|
|
||||||
{ offset: 1, color: 'rgba(0, 114, 255, 0.01)' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
@ -1,169 +0,0 @@
|
|||||||
<template>
|
|
||||||
<v-chart :option="options" theme="dark" style="width: 100%;height: 100%;" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { computed } from 'vue';
|
|
||||||
const prop = defineProps({
|
|
||||||
data: {
|
|
||||||
type: Object,
|
|
||||||
default: () => {
|
|
||||||
return {
|
|
||||||
pm25: 0,
|
|
||||||
pm10: 0,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const options = computed(() => {
|
|
||||||
return {
|
|
||||||
grid: {
|
|
||||||
// 让图表占满容器
|
|
||||||
top: "0px",
|
|
||||||
left: "0px",
|
|
||||||
right: "0px",
|
|
||||||
bottom: "0px",
|
|
||||||
},
|
|
||||||
backgroundColor: "transparent",
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
type: "gauge",
|
|
||||||
center: ["50%", "90%"],
|
|
||||||
startAngle: 190,
|
|
||||||
endAngle: -10,
|
|
||||||
radius: "50%",
|
|
||||||
min: 0,
|
|
||||||
max: 100,
|
|
||||||
splitNumber: 10,
|
|
||||||
pointer: {
|
|
||||||
icon: "path://M12.8,0.7l12,40.1H0.7L12.8,0.7z",
|
|
||||||
length: "12%",
|
|
||||||
width: 10,
|
|
||||||
offsetCenter: [0, "-40%"],
|
|
||||||
itemStyle: {
|
|
||||||
color: "inherit",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
axisLine: {
|
|
||||||
lineStyle: {
|
|
||||||
width: 8,
|
|
||||||
color: [
|
|
||||||
[0.35, "#7CFFB2"],
|
|
||||||
[0.75, "#FDDD60"],
|
|
||||||
[1, "#FF6E76"],
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
axisTick: {
|
|
||||||
distance: 0,
|
|
||||||
splitNumber: 5,
|
|
||||||
lineStyle: {
|
|
||||||
width: 2,
|
|
||||||
color: "#999",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
splitLine: {
|
|
||||||
distance: 5,
|
|
||||||
length: 8,
|
|
||||||
lineStyle: {
|
|
||||||
width: 3,
|
|
||||||
color: "#999",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
axisLabel: {
|
|
||||||
distance: 12,
|
|
||||||
color: "#999",
|
|
||||||
fontSize: 10,
|
|
||||||
},
|
|
||||||
anchor: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
detail: {
|
|
||||||
valueAnimation: true,
|
|
||||||
width: "60%",
|
|
||||||
lineHeight: 20,
|
|
||||||
borderRadius: 8,
|
|
||||||
offsetCenter: [0, "20%"],
|
|
||||||
fontSize: 15,
|
|
||||||
fontWeight: "bolder",
|
|
||||||
formatter: "{value} μg/m3",
|
|
||||||
color: "inherit",
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
// show: false,
|
|
||||||
offsetCenter: [0, "-20%"],
|
|
||||||
},
|
|
||||||
data: [
|
|
||||||
{
|
|
||||||
value: prop.data.pm25,
|
|
||||||
name: "PM2.5",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "gauge",
|
|
||||||
center: ["50%", "55%"],
|
|
||||||
startAngle: 200,
|
|
||||||
endAngle: -20,
|
|
||||||
min: 0,
|
|
||||||
max: 200,
|
|
||||||
axisLine: {
|
|
||||||
lineStyle: {
|
|
||||||
width: 10,
|
|
||||||
color: [
|
|
||||||
[0.35, "#7CFFB2"],
|
|
||||||
[0.75, "#FDDD60"],
|
|
||||||
[1, "#FF6E76"],
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
pointer: {
|
|
||||||
itemStyle: {
|
|
||||||
color: "inherit",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
axisTick: {
|
|
||||||
distance: -10,
|
|
||||||
length: 6,
|
|
||||||
lineStyle: {
|
|
||||||
color: "#fff",
|
|
||||||
width: 2,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
splitLine: {
|
|
||||||
distance: -10,
|
|
||||||
length: 10,
|
|
||||||
lineStyle: {
|
|
||||||
color: "#fff",
|
|
||||||
width: 4,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
axisLabel: {
|
|
||||||
color: "inherit",
|
|
||||||
distance: 20,
|
|
||||||
fontSize: 10,
|
|
||||||
},
|
|
||||||
detail: {
|
|
||||||
valueAnimation: true,
|
|
||||||
offsetCenter: [0, "20%"],
|
|
||||||
fontSize: 20,
|
|
||||||
formatter: "{value} μg/m3",
|
|
||||||
color: "inherit",
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
offsetCenter: [0, "-50%"],
|
|
||||||
},
|
|
||||||
data: [
|
|
||||||
{
|
|
||||||
value: prop.data.pm10,
|
|
||||||
name: "PM10",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 162 KiB |
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 162 KiB |
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 150 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
@ -1,533 +1,514 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="abs-header" ref="texstref">研发中心环境实时监测系统</div>
|
<div class="header">
|
||||||
<div class="l-box">
|
<div class="title">研发中心环境实时监测系统</div>
|
||||||
<div class="lbox1">
|
|
||||||
<ItemVue title="温湿度监测">
|
|
||||||
<Humiture />
|
|
||||||
</ItemVue>
|
|
||||||
</div>
|
|
||||||
<div class="lbox1">
|
|
||||||
<ItemVue title="粉尘监测">
|
|
||||||
<PmVue :data="dustData" />
|
|
||||||
</ItemVue>
|
|
||||||
</div>
|
|
||||||
<div class="lbox1">
|
|
||||||
<ItemVue title="智能控制系统">
|
|
||||||
<BarChart />
|
|
||||||
</ItemVue>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="ct-box">
|
|
||||||
<div class="ct-sensor">
|
|
||||||
<div class="sensor-item" v-for="item in sensor_list">
|
|
||||||
<!-- :style="{color:item.status == 'true'?'#469DE9':'gray'}" -->
|
|
||||||
<component style="width: 75px;height: 75px;margin-top: 10px;" :is="item.component" :value="item.value"
|
|
||||||
:color="checkCb(item)" :unit="item.unit" /><!-- item.status == 'true'?'#469DE9':'gray' -->
|
|
||||||
|
|
||||||
<div style="margin: 10px 0">{{ item.value + item.unit }}</div>
|
|
||||||
<div>{{ item.name }}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="ct-box">
|
||||||
|
<div class="ct-sensor">
|
||||||
|
<SensorNumLoop :sensorData="item" v-for="(item, index) in sensor_list" :key="index" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="left-content left-right" ref="leftContentRef">
|
||||||
|
<Lr1 :data="avg_temp_humi.four" />
|
||||||
|
<Lr2 :deptId="'113'" />
|
||||||
|
<Lr3 :public_list="noiseDataList.four.public_noise" :office_list="noiseDataList.four.office_noise" />
|
||||||
|
<Lr4 :data="TVOC_CH2O_floor['4f']" />
|
||||||
|
</div>
|
||||||
|
<div class="right-content left-right" ref="rightContentRef">
|
||||||
|
<Lr1 :data="avg_temp_humi.five" />
|
||||||
|
<Lr2 :deptId="'114'" />
|
||||||
|
<Lr3 :public_list="noiseDataList.five.public_noise" :office_list="noiseDataList.five.office_noise" />
|
||||||
|
<Lr4 :data="TVOC_CH2O_floor['5f']" />
|
||||||
|
</div>
|
||||||
|
<div class="bottom-content" ref="bottomContentRef">
|
||||||
|
|
||||||
</div>
|
<ZdScrollBoard ref="devList" :config="zd_config" class="zd-scroll-board" />
|
||||||
<div class="cb-box">
|
</div>
|
||||||
<div class="cbox">
|
<div class="checkboxlist">
|
||||||
<ItemVue title="甲醛监测">
|
<el-radio-group v-model="radioGroup1" :fill="'#105F88'" size="large">
|
||||||
<LineChart />
|
<el-radio-button label="四层" value="四层"></el-radio-button>
|
||||||
</ItemVue>
|
|
||||||
</div>
|
|
||||||
<div class="cbox">
|
|
||||||
<ItemVue title="TVOC监测">
|
|
||||||
<LineChart />
|
|
||||||
</ItemVue>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="r-box">
|
|
||||||
<div class="rbox-item">
|
|
||||||
<ItemVue title="公共区域噪音" pos="right">
|
|
||||||
<LineChart />
|
|
||||||
</ItemVue>
|
|
||||||
</div>
|
|
||||||
<div class="rbox-item">
|
|
||||||
<ItemVue title="办公室噪音" pos="right">
|
|
||||||
<ProgeChart :data="noiseDataList" />
|
|
||||||
</ItemVue>
|
|
||||||
</div>
|
|
||||||
<div class="rbox-item">
|
|
||||||
<ItemVue title="告警信息" pos="right">
|
|
||||||
<ZdScrollBoard ref="devList" :config="zd_config"
|
|
||||||
:style="{ width: '100%', height: '260px', 'padding-top': '10px' }" />
|
|
||||||
</ItemVue>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<el-radio-button label="五层" value="五层"></el-radio-button>
|
||||||
<!-- <Sence /> -->
|
</el-radio-group>
|
||||||
</div>
|
</div>
|
||||||
|
<Sence />
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, onMounted } from 'vue';
|
import { ref, reactive, onMounted, computed, watch } from 'vue';
|
||||||
// import ThreeBG from './component/threeBG.vue';
|
|
||||||
import Sence from './component/Sence.vue';
|
import Sence from './component/Sence.vue';
|
||||||
import ItemVue from './component/item.vue';
|
import Lr1 from './component/Lr1.vue';
|
||||||
import Humiture from './component/humiture_line.vue';
|
import Lr2 from './component/Lr2.vue';
|
||||||
import PmVue from './component/pm.vue';
|
import Lr3 from './component/Lr3.vue';
|
||||||
import LineChart from './component/lineChart.vue';
|
import Lr4 from './component/Lr4.vue';
|
||||||
import BarChart from './component/barChart.vue';
|
|
||||||
import ProgeChart from './component/proge.vue';
|
|
||||||
import SvgFenchen from './component/svgFenchen.vue';
|
|
||||||
import SvgPm25 from './component/svgPm25.vue';
|
|
||||||
import SvgPm10 from './component/svgPm10.vue';
|
|
||||||
import SvgJiaquan from './component/svgJiaquan.vue';
|
|
||||||
import SvgZaosheng from './component/svgZaosheng.vue';
|
|
||||||
import SvgTVOC from './component/svgTVOC.vue';
|
|
||||||
import SvgShidu from './component/svgShidu.vue';
|
|
||||||
import SvgWendu from './component/svgWendu.vue';
|
|
||||||
import SvgYanwu from './component/svgYanwu.vue';
|
|
||||||
import ZdScrollBoard from "@/components/ZdScrollBoard/index.vue";
|
import ZdScrollBoard from "@/components/ZdScrollBoard/index.vue";
|
||||||
import { connectWebsocket, closeWebsocket } from '@/utils/websocket';
|
import SensorNumLoop from './component/SensorNumLoop.vue';
|
||||||
import { getNoiseData, getTopData, getSensorDateHourByType } from '@/api/screen/R_D_Environment';
|
import useR_D_EnvironmentStore from '@/store/modules/r_d_environment'
|
||||||
|
import { connectWebsocket, closeWebsocket} from "@/utils/websocket";
|
||||||
|
import { getSensorByDept } from '@/api/screen/R_D_Environment';
|
||||||
|
|
||||||
let noiseDataList = ref([
|
|
||||||
{
|
let R_D_EnvironmentStore = useR_D_EnvironmentStore()
|
||||||
"devId": "48a2ec70-a60c-11ef-91f3-abd609c7e488",
|
let deltaY = ref(0)
|
||||||
"devName": "办公区7",
|
let avg_temp_humi = computed(() => {
|
||||||
"label": "noise-7",
|
return R_D_EnvironmentStore.getLayerData
|
||||||
"place": null,
|
|
||||||
"data": 10,
|
|
||||||
"status": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"devId": "48a2ec70-a60c-11ef-91f3-abd609c7e489",
|
|
||||||
"devName": "办公区6",
|
|
||||||
"label": "noise-6",
|
|
||||||
"place": null,
|
|
||||||
"data": 20,
|
|
||||||
"status": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"devId": "48a2ec70-a60c-11ef-91f3-abd609c7e490",
|
|
||||||
"devName": "办公区5",
|
|
||||||
"label": "noise-5",
|
|
||||||
"place": null,
|
|
||||||
"data": 22,
|
|
||||||
"status": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"devId": "48a2ec70-a60c-11ef-91f3-abd609c7e491",
|
|
||||||
"devName": "办公区4",
|
|
||||||
"label": "noise-4",
|
|
||||||
"place": null,
|
|
||||||
"data": 22,
|
|
||||||
"status": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"devId": "48a2ec70-a60c-11ef-91f3-abd609c7e491",
|
|
||||||
"devName": "办公区3",
|
|
||||||
"label": "noise-3",
|
|
||||||
"place": null,
|
|
||||||
"data": 21,
|
|
||||||
"status": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"devId": "48a2ec70-a60c-11ef-91f3-abd609c7e492",
|
|
||||||
"devName": "办公区2",
|
|
||||||
"label": "noise-2",
|
|
||||||
"place": null,
|
|
||||||
"data": 24,
|
|
||||||
"status": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"devId": "48a2ec70-a60c-11ef-91f3-abd609c7e493",
|
|
||||||
"devName": "办公区1",
|
|
||||||
"label": "noise-1",
|
|
||||||
"place": null,
|
|
||||||
"data": 25,
|
|
||||||
"status": 0
|
|
||||||
},
|
|
||||||
])
|
|
||||||
let sensor_list = reactive([
|
|
||||||
{
|
|
||||||
id: '',
|
|
||||||
name: '温度',
|
|
||||||
component: SvgWendu,
|
|
||||||
value: 20,
|
|
||||||
unit: '℃',
|
|
||||||
type: 'AirTemp_Reg',
|
|
||||||
limit: 40,
|
|
||||||
status: "true"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '',
|
|
||||||
name: '湿度',
|
|
||||||
component: SvgShidu,
|
|
||||||
value: 20,
|
|
||||||
unit: '%',
|
|
||||||
type: 'AirHumi_Reg',
|
|
||||||
limit: 90,
|
|
||||||
status: "true"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '',
|
|
||||||
name: '甲醛',
|
|
||||||
component: SvgJiaquan,
|
|
||||||
value: 20,
|
|
||||||
unit: 'mg/m³',
|
|
||||||
type: 'CH2O',
|
|
||||||
limit: 0.08,
|
|
||||||
status: "true"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '',
|
|
||||||
name: 'TVOC',
|
|
||||||
component: SvgTVOC,
|
|
||||||
value: 20,
|
|
||||||
unit: 'mg/m³',
|
|
||||||
type: 'TVOC',
|
|
||||||
limit: 0.5,
|
|
||||||
status: "true"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '',
|
|
||||||
name: 'PM2.5',
|
|
||||||
component: SvgPm25,
|
|
||||||
value: 20,
|
|
||||||
unit: 'mg/m³',
|
|
||||||
type: 'HIGH_PM25_Reg',
|
|
||||||
limit: 30,
|
|
||||||
status: "true"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '',
|
|
||||||
name: 'PM10',
|
|
||||||
component: SvgPm10,
|
|
||||||
value: 20,
|
|
||||||
unit: 'mg/m³',
|
|
||||||
type: 'HIGH_PM10_Reg',
|
|
||||||
limit: 30,
|
|
||||||
status: "true"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '',
|
|
||||||
name: '噪音',
|
|
||||||
component: SvgZaosheng,
|
|
||||||
value: 20,
|
|
||||||
unit: 'dB',
|
|
||||||
type: 'Noise_Reg',
|
|
||||||
limit: 85,
|
|
||||||
status: "true"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '',
|
|
||||||
name: '烟雾',
|
|
||||||
component: SvgYanwu,
|
|
||||||
value: 20,
|
|
||||||
unit: 'mg/m³',
|
|
||||||
type: 'Smoke_Reg',
|
|
||||||
limit: 100,
|
|
||||||
status: "true"
|
|
||||||
}
|
|
||||||
])
|
|
||||||
let dustData = reactive({
|
|
||||||
pm25: 0,
|
|
||||||
pm10: 0,
|
|
||||||
})
|
})
|
||||||
let texstref = ref(null)
|
let noiseDataList = computed(() => {
|
||||||
let zd_config = ref({
|
return R_D_EnvironmentStore.getNoiseData
|
||||||
header: ['报警时间', '报警内容', '报警位置'],
|
|
||||||
rowNum: 4,
|
|
||||||
data: [
|
|
||||||
['行1列1', '行1列2', '行1列3'],
|
|
||||||
['行2列1', '行2列2', '行2列3'],
|
|
||||||
['行3列1', '行3列2', '行3列3'],
|
|
||||||
['行4列1', '行4列2', '行4列3'],
|
|
||||||
['行5列1', '行5列2', '行5列3'],
|
|
||||||
['行6列1', '行6列2', '行6列3'],
|
|
||||||
['行7列1', '行7列2', '行7列3'],
|
|
||||||
['行8列1', '行8列2', '行8列3'],
|
|
||||||
['行9列1', '行9列2', '行9列3'],
|
|
||||||
['行10列1', '行10列2', '行10列3']
|
|
||||||
]
|
|
||||||
})
|
})
|
||||||
//检测是否超标
|
let TVOC_CH2O_floor = reactive({
|
||||||
function checkCb(item) {
|
'4f': {
|
||||||
if (item.status === 'false') {
|
ch2o: [],
|
||||||
return 'gray'
|
tvoc: []
|
||||||
} else if (item.value > item.limit) {
|
},
|
||||||
return '#FF0000'
|
'5f': {
|
||||||
} else {
|
ch2o: [],
|
||||||
return '#469DE9'
|
tvoc: []
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 获取各办公室噪音数据
|
|
||||||
function getNoiseDataList() {
|
|
||||||
getNoiseData().then(res => {
|
|
||||||
if (res.code === 200) {
|
|
||||||
noiseDataList.value = res.data
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
let sensor_list = computed(() => {
|
||||||
// 获取顶部数据
|
let sensorData = R_D_EnvironmentStore.sensorData
|
||||||
function getTopDataList() {
|
return [
|
||||||
getTopData(113).then(res => {
|
{
|
||||||
if (res.code === 200) {
|
|
||||||
res.data.forEach(item => {
|
|
||||||
let index = sensor_list.findIndex(sensor => sensor.type === item.type)
|
|
||||||
sensor_list[index].value = item.data
|
|
||||||
sensor_list[index].id = item.id
|
|
||||||
sensor_list[index].status = item.status
|
|
||||||
sensor_list[index].limit = item.limit
|
|
||||||
if (item.type === 'HIGH_PM25_Reg') {
|
|
||||||
dustData.pm25 = item.data
|
|
||||||
} else if (item.type === 'HIGH_PM10_Reg') {
|
|
||||||
dustData.pm10 = item.data
|
|
||||||
|
|
||||||
|
component: 'SvgWendu',
|
||||||
|
unit: '℃',
|
||||||
|
type: 'AirTemp_Reg',
|
||||||
|
limit: 40,
|
||||||
|
list: sensorData['temp_humi']?.map(sensor => {
|
||||||
|
return {
|
||||||
|
id: sensor.deviceId,
|
||||||
|
name: sensor.name,
|
||||||
|
value: sensor.temp,
|
||||||
|
status: sensor.status
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'SvgShidu',
|
||||||
|
unit: '%RH',
|
||||||
|
type: 'AirHumi_Reg',
|
||||||
|
limit: 90,
|
||||||
|
list: sensorData['temp_humi']?.map(sensor => {
|
||||||
|
return {
|
||||||
|
id: sensor.deviceId,
|
||||||
|
name: sensor.name,
|
||||||
|
value: sensor.humidity,
|
||||||
|
status: sensor.status
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'SvgJiaquan',
|
||||||
|
unit: 'mg/m³',
|
||||||
|
type: 'CH2O',
|
||||||
|
limit: 0.08,
|
||||||
|
list: sensorData['TVOC_CH2O']?.filter(sensor => sensor.type === 'CH2O').map(sensor => {
|
||||||
|
return {
|
||||||
|
id: sensor.deviceId,
|
||||||
|
name: sensor.name,
|
||||||
|
value: sensor.data,
|
||||||
|
status: sensor.status
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'SvgTVOC',
|
||||||
|
unit: 'mg/m³',
|
||||||
|
type: 'TVOC',
|
||||||
|
limit: 0.5,
|
||||||
|
list: sensorData['TVOC_CH2O']?.filter(sensor => sensor.type === 'TVOC').map(sensor => {
|
||||||
|
return {
|
||||||
|
id: sensor.deviceId,
|
||||||
|
name: sensor.name,
|
||||||
|
value: sensor.data,
|
||||||
|
status: sensor.status
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'SvgPm25',
|
||||||
|
unit: 'mg/m³',
|
||||||
|
type: 'HIGH_PM25_Reg',
|
||||||
|
limit: 30,
|
||||||
|
list: sensorData['dust']?.filter(sensor => sensor.type === 'HIGH_PM25_Reg').map(sensor => {
|
||||||
|
return {
|
||||||
|
id: sensor.deviceId,
|
||||||
|
name: sensor.name,
|
||||||
|
value: sensor.data,
|
||||||
|
status: sensor.status
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'SvgPm10',
|
||||||
|
unit: 'mg/m³',
|
||||||
|
type: 'HIGH_PM10_Reg',
|
||||||
|
limit: 30,
|
||||||
|
list: sensorData['dust']?.filter(sensor => sensor.type === 'HIGH_PM10_Reg').map(sensor => {
|
||||||
|
return {
|
||||||
|
id: sensor.deviceId,
|
||||||
|
name: sensor.name,
|
||||||
|
value: sensor.data,
|
||||||
|
status: sensor.status
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'SvgZaosheng',
|
||||||
|
unit: 'dB',
|
||||||
|
type: 'Noise_Reg',
|
||||||
|
limit: 85,
|
||||||
|
list: sensorData['noise']?.map(sensor => {
|
||||||
|
return {
|
||||||
|
id: sensor.deviceId,
|
||||||
|
name: sensor.name,
|
||||||
|
value: sensor.data,
|
||||||
|
status: sensor.status
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'SvgYanwu',
|
||||||
|
unit: 'mg/m³',
|
||||||
|
type: 'Smoke_Reg',
|
||||||
|
limit: 100,
|
||||||
|
list: sensorData['Smoke']?.map(sensor => {
|
||||||
|
return {
|
||||||
|
id: sensor.deviceId,
|
||||||
|
name: sensor.name,
|
||||||
|
value: sensor.data,
|
||||||
|
status: sensor.status
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
const radioGroup1 = ref('四层')
|
||||||
|
let zd_config = ref({
|
||||||
|
header: ['报警时间', '报警内容', '持续时长', '报警设备'],
|
||||||
|
rowNum: 2,
|
||||||
|
headerHeight: 50,
|
||||||
|
headerBGC: 'transparent',
|
||||||
|
oddRowBGC: 'transparent',
|
||||||
|
evenRowBGC: 'transparent',
|
||||||
|
columnWidth: [179, 179, 179, 179],
|
||||||
|
data: [
|
||||||
|
['行1列1', '行1列2', '行1列3', '行1列4'],
|
||||||
|
['行2列1', '行2列2', '行2列3', '行2列4'],
|
||||||
|
['行3列1', '行3列2', '行3列3', '行3列4'],
|
||||||
|
['行4列1', '行4列2', '行4列3', '行4列4'],
|
||||||
|
]
|
||||||
|
})
|
||||||
|
function reqSensorByDept() {
|
||||||
|
getSensorByDept('113,114').then(res => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
let sensorData = res.data
|
||||||
|
let temp_humi = sensorData.temp_humi
|
||||||
|
let TVOC_CH2O = sensorData.TVOC_CH2O
|
||||||
|
let temp = []
|
||||||
|
temp_humi.map(item => {
|
||||||
|
let index = temp.find(item2 => { return item2.deviceId == item.deviceId })
|
||||||
|
if (!index) {
|
||||||
|
if (item.type === 'AirHumi_Reg') {
|
||||||
|
temp.push({
|
||||||
|
deviceId: item.deviceId,
|
||||||
|
humidity: item.data,
|
||||||
|
name: item.name,
|
||||||
|
label: item.label,
|
||||||
|
temp: '',
|
||||||
|
deptId: item.deptId,
|
||||||
|
deptName: item.deptName,
|
||||||
|
status: item.status
|
||||||
|
})
|
||||||
|
|
||||||
})
|
} else if (item.type === 'AirTemp_Reg') {
|
||||||
}
|
temp.push({
|
||||||
})
|
deviceId: item.deviceId,
|
||||||
|
humidity: '',
|
||||||
|
name: item.name,
|
||||||
|
label: item.label,
|
||||||
|
temp: item.data,
|
||||||
|
deptId: item.deptId,
|
||||||
|
deptName: item.deptName,
|
||||||
|
status: item.status
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (item.type === 'AirHumi_Reg') {
|
||||||
|
index.humidity = item.data
|
||||||
|
} else if (item.type === 'AirTemp_Reg') {
|
||||||
|
index.temp = item.data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let now = +new Date()
|
||||||
|
TVOC_CH2O.map(item => {
|
||||||
|
if (item.deptId == '113') {
|
||||||
|
if (item.type === 'CH2O') {
|
||||||
|
TVOC_CH2O_floor['4f'].ch2o.push([now,item.data])
|
||||||
|
} else if (item.type === 'TVOC') {
|
||||||
|
TVOC_CH2O_floor['4f'].tvoc.push([now,item.data])
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if(item.deptId == '114') {
|
||||||
|
if (item.type === 'CH2O') {
|
||||||
|
TVOC_CH2O_floor['5f'].ch2o.push([now,item.data])
|
||||||
|
} else if (item.type === 'TVOC') {
|
||||||
|
TVOC_CH2O_floor['5f'].tvoc.push([now,item.data])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
sensorData.temp_humi = temp
|
||||||
|
R_D_EnvironmentStore.sensorData = sensorData
|
||||||
|
// noiseDataList.value = res.data
|
||||||
|
// public_noise.value = noiseDataList.value.find(item => item.devName === '公共区域')
|
||||||
|
// office_noise.value = noiseDataList.value.filter(item => item.devName !== '公共区域')
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取传感器数据
|
|
||||||
function getSensorData(type) {
|
|
||||||
let query = {
|
|
||||||
type,
|
|
||||||
deptId: '100'
|
|
||||||
}
|
|
||||||
getSensorDateHourByType(query)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//socket
|
//socket
|
||||||
function getWebsocket(val) {
|
function getWebsocket(val) {
|
||||||
try {
|
try {
|
||||||
let data = JSON.parse(val);
|
let data = JSON.parse(val);
|
||||||
|
|
||||||
if (data.type == "HUMI_TEMP") {
|
if (data.type == "HUMI_TEMP") {
|
||||||
let obj = data.msg;
|
let obj = data.msg;
|
||||||
if (obj.hasOwnProperty('temp')) {
|
if (obj.hasOwnProperty('temp')) {
|
||||||
let index = sensor_list.findIndex(sensor => sensor.type === 'AirTemp_Reg' && sensor.id === obj.temp.devId)
|
let index = sensor_list.findIndex(sensor => sensor.type === 'AirTemp_Reg' && sensor.id === obj.temp.devId)
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
sensor_list[index].value = obj.temp.value
|
sensor_list[index].value = obj.temp.value
|
||||||
sensor_list[index].status = "true"
|
sensor_list[index].status = "true"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (obj.hasOwnProperty('humi')) {
|
||||||
|
let index = sensor_list.findIndex(sensor => sensor.type === 'AirHumi_Reg' && sensor.id === obj.humi.devId)
|
||||||
|
if (index !== -1) {
|
||||||
|
sensor_list[index].value = obj.humi.value
|
||||||
|
sensor_list[index].status = "true"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (data.type == "TVOC_CH2O") {
|
||||||
|
let obj = data.msg;
|
||||||
|
if (obj.hasOwnProperty('CH2O')) {
|
||||||
|
let index = sensor_list.findIndex(sensor => sensor.type === 'CH2O' && sensor.id === obj.CH2O.devId)
|
||||||
|
if (index !== -1) {
|
||||||
|
sensor_list[index].value = obj.CH2O.value
|
||||||
|
sensor_list[index].status = "true"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (obj.hasOwnProperty('humi')) {
|
if (obj.hasOwnProperty('TVOC')) {
|
||||||
let index = sensor_list.findIndex(sensor => sensor.type === 'AirHumi_Reg' && sensor.id === obj.humi.devId)
|
let index = sensor_list.findIndex(sensor => sensor.type === 'TVOC' && sensor.id === obj.TVOC.devId)
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
sensor_list[index].value = obj.humi.value
|
sensor_list[index].value = obj.TVOC.value
|
||||||
sensor_list[index].status = "true"
|
sensor_list[index].status = "true"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
//粉尘
|
||||||
|
if (data.type == "dust") {
|
||||||
|
let obj = data.msg;
|
||||||
|
|
||||||
}
|
|
||||||
|
let index_pm25 = sensor_list.findIndex(sensor => sensor.type === 'HIGH_PM25_Reg' && sensor.id === obj.devId)
|
||||||
|
let index_pm10 = sensor_list.findIndex(sensor => sensor.type === 'HIGH_PM10_Reg' && sensor.id === obj.devId)
|
||||||
|
if (index_pm25 !== -1) {
|
||||||
|
sensor_list[index_pm25].value = obj.pm25
|
||||||
|
sensor_list[index_pm25].status = "true"
|
||||||
|
dustData.pm25 = obj.pm25
|
||||||
|
}
|
||||||
|
if (index_pm10 !== -1) {
|
||||||
|
sensor_list[index_pm10].value = obj.pm10
|
||||||
|
sensor_list[index_pm10].status = "true"
|
||||||
|
dustData.pm10 = obj.pm10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//噪音
|
||||||
|
if (data.type === "NOISE") {
|
||||||
|
let obj = data.msg;
|
||||||
|
let list_index = noiseDataList.value.findIndex(item => item.devId === obj.noise.devId)
|
||||||
|
if (list_index !== -1) {
|
||||||
|
noiseDataList.value[list_index].data = obj.noise.value
|
||||||
|
} else {
|
||||||
|
let index = sensor_list.findIndex(sensor => sensor.type === 'Noise_Reg' && sensor.id === obj.noise.devId)
|
||||||
|
if (index !== -1) {
|
||||||
|
sensor_list[index].value = obj.noise.value
|
||||||
|
sensor_list[index].status = "true"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
}
|
}
|
||||||
if (data.type == "TVOC_CH2O") {
|
|
||||||
let obj = data.msg;
|
|
||||||
if (obj.hasOwnProperty('CH2O')) {
|
|
||||||
let index = sensor_list.findIndex(sensor => sensor.type === 'CH2O' && sensor.id === obj.CH2O.devId)
|
|
||||||
if (index !== -1) {
|
|
||||||
sensor_list[index].value = obj.CH2O.value
|
|
||||||
sensor_list[index].status = "true"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if (obj.hasOwnProperty('TVOC')) {
|
|
||||||
let index = sensor_list.findIndex(sensor => sensor.type === 'TVOC' && sensor.id === obj.TVOC.devId)
|
|
||||||
if (index !== -1) {
|
|
||||||
sensor_list[index].value = obj.TVOC.value
|
|
||||||
sensor_list[index].status = "true"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//粉尘
|
|
||||||
if (data.type == "dust") {
|
|
||||||
let obj = data.msg;
|
|
||||||
|
|
||||||
|
|
||||||
let index_pm25 = sensor_list.findIndex(sensor => sensor.type === 'HIGH_PM25_Reg' && sensor.id === obj.devId)
|
|
||||||
let index_pm10 = sensor_list.findIndex(sensor => sensor.type === 'HIGH_PM10_Reg' && sensor.id === obj.devId)
|
|
||||||
if (index_pm25 !== -1) {
|
|
||||||
sensor_list[index_pm25].value = obj.pm25
|
|
||||||
sensor_list[index_pm25].status = "true"
|
|
||||||
dustData.pm25 = obj.pm25
|
|
||||||
}
|
|
||||||
if (index_pm10 !== -1) {
|
|
||||||
sensor_list[index_pm10].value = obj.pm10
|
|
||||||
sensor_list[index_pm10].status = "true"
|
|
||||||
dustData.pm10 = obj.pm10
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//噪音
|
|
||||||
if (data.type === "NOISE") {
|
|
||||||
let obj = data.msg;
|
|
||||||
let list_index = noiseDataList.value.findIndex(item => item.devId === obj.noise.devId)
|
|
||||||
if (list_index !== -1) {
|
|
||||||
noiseDataList.value[list_index].data = obj.noise.value
|
|
||||||
} else {
|
|
||||||
let index = sensor_list.findIndex(sensor => sensor.type === 'Noise_Reg' && sensor.id === obj.noise.devId)
|
|
||||||
if (index !== -1) {
|
|
||||||
sensor_list[index].value = obj.noise.value
|
|
||||||
sensor_list[index].status = "true"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.log(err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
function errWebsocket(val) {
|
function errWebsocket(val) {
|
||||||
// console.log(val);
|
// console.log(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
let deltaY = ref(0)
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getNoiseDataList()
|
reqSensorByDept()
|
||||||
getTopDataList()
|
window.addEventListener('wheel', function (event) {
|
||||||
|
deltaY.value += event.deltaY
|
||||||
|
if (deltaY.value <= -500 && deltaY.value >= -1000) {
|
||||||
|
this.document.querySelector('.ct-box').style.transform = 'translateY(-200%) translateX(-50%)'
|
||||||
|
this.document.querySelector('.left-content').style.transform = 'translateX(-100%)'
|
||||||
|
this.document.querySelector('.right-content').style.transform = 'translateX(100%)'
|
||||||
|
this.document.querySelector('.bottom-content').style.transform = 'translateY(100%)'
|
||||||
|
}
|
||||||
|
if (deltaY.value > -500 && deltaY.value < 0) {
|
||||||
|
this.document.querySelector('.ct-box').style.transform = 'translateY(0) translateX(-50%)'
|
||||||
|
this.document.querySelector('.left-content').style.transform = 'translateX(0)'
|
||||||
|
this.document.querySelector('.right-content').style.transform = 'translateX(0)'
|
||||||
|
this.document.querySelector('.bottom-content').style.transform = 'translateY(0)'
|
||||||
|
|
||||||
//监听滚动事件
|
}
|
||||||
// window.addEventListener('wheel', function (event) {
|
|
||||||
// deltaY.value += event.deltaY
|
|
||||||
// console.log(event.deltaY,deltaY.value,'event.deltaY');
|
|
||||||
// if (deltaY.value <= -500 &&deltaY.value >= -1000) {
|
|
||||||
// texstref.value.style.display = 'none'
|
|
||||||
// }
|
|
||||||
// if (deltaY.value > -500 && deltaY.value < 0) {
|
|
||||||
// texstref.value.style.display = 'block'
|
|
||||||
|
|
||||||
// }
|
// if (deltaY.value >= 0) {
|
||||||
// }, { passive: false });
|
// deltaY.value = 0
|
||||||
|
// }
|
||||||
connectWebsocket(null, null, getWebsocket, errWebsocket);
|
}, { passive: false });
|
||||||
|
connectWebsocket('','',getWebsocket, errWebsocket)
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.container {
|
.container {
|
||||||
width: 1920px;
|
width: 1920px;
|
||||||
height: 1080px;
|
height: 1080px;
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
// display: flex;
|
||||||
justify-content: center;
|
// justify-content: center;
|
||||||
align-items: center;
|
|
||||||
// background-image: url('/src/assets/images/gif-bg.gif');
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
/* 如果你不想让背景平铺 */
|
|
||||||
background-size: cover;
|
|
||||||
/* 或者其他你需要的大小设置 */
|
|
||||||
background-position: center;
|
|
||||||
|
|
||||||
.abs-header {
|
|
||||||
width: 100%;
|
|
||||||
height: 80px;
|
|
||||||
position: absolute;
|
|
||||||
top: 28px;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 36px;
|
|
||||||
font-weight: 700;
|
|
||||||
color: #00c6ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.l-box {
|
|
||||||
position: absolute;
|
|
||||||
top: 100px;
|
|
||||||
left: 0px;
|
|
||||||
width: 410px;
|
|
||||||
height: 980px;
|
|
||||||
z-index: 2;
|
|
||||||
background: linear-gradient(to left, transparent 0%, rgba(15, 32, 54, 0.8) 50%, #102238 100%);
|
|
||||||
// background: url('/src/assets/images/preview-left.png') center center / 100% 100% no-repeat;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
// background-image: url('/src/assets/images/gif-bg.gif');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
/* 如果你不想让背景平铺 */
|
||||||
|
background-size: cover;
|
||||||
|
/* 或者其他你需要的大小设置 */
|
||||||
|
background-position: center;
|
||||||
|
|
||||||
.lbox1 {
|
.header {
|
||||||
width: 100%;
|
position: absolute;
|
||||||
height: 316px;
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 72px;
|
||||||
|
background-image: url('./image/u796.png');
|
||||||
|
z-index: 2;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
width: 100%;
|
||||||
|
height: 72px;
|
||||||
|
font-size: 36px;
|
||||||
|
color: #2affff;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 60px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.ct-box {
|
.ct-box {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 100px;
|
top: 100px;
|
||||||
left: 445px;
|
left: 50%;
|
||||||
width: 1026px;
|
transform: translateX(-50%);
|
||||||
height: 180px;
|
width: 825px;
|
||||||
display: flex;
|
height: 180px;
|
||||||
z-index: 2;
|
display: flex;
|
||||||
justify-content: space-between;
|
z-index: 2;
|
||||||
|
justify-content: space-between;
|
||||||
|
transition: transform 1s;
|
||||||
|
|
||||||
.ct-sensor {
|
.ct-sensor {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
.sensor-item {
|
}
|
||||||
width: 146px;
|
}
|
||||||
height: 100%;
|
|
||||||
|
.left-content {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 557px;
|
||||||
|
height: 1080px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding-top: 72px;
|
||||||
|
background-image: url('./image/u801.png'), url('./image/u797.png');
|
||||||
|
background-position: center, 0% 78%;
|
||||||
|
background-repeat: no-repeat, no-repeat;
|
||||||
|
padding-left: 30px;
|
||||||
|
transition: transform 1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-right {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
justify-content: space-between;
|
||||||
font-size: 14px;
|
padding-bottom: 30px;
|
||||||
color: #fff;
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-content {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 557px;
|
||||||
|
height: 1080px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding-top: 72px;
|
||||||
|
background-image: url('./image/u800.png'), url('./image/u798.png');
|
||||||
|
background-position: center, 100% 78%;
|
||||||
|
background-repeat: no-repeat, no-repeat;
|
||||||
|
padding-right: 30px;
|
||||||
|
transition: transform 1s;
|
||||||
|
align-items: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-content {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 1920px;
|
||||||
|
height: 184px;
|
||||||
|
background-image: url('./image/u799.png'), url('./image/u802.png');
|
||||||
|
background-position: bottom, 50% 100%;
|
||||||
|
background-repeat: no-repeat, no-repeat;
|
||||||
|
transition: transform 1s;
|
||||||
|
|
||||||
|
.zd-scroll-board {
|
||||||
|
width: 716px;
|
||||||
|
height: 120px, ;
|
||||||
|
position: absolute;
|
||||||
|
top: 28px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
|
||||||
.sensor-icon {
|
|
||||||
width: 75px;
|
|
||||||
height: 75px;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.cb-box {
|
.checkboxlist {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0px;
|
top: 2px;
|
||||||
left: 435px;
|
right: 60px;
|
||||||
width: 1046px;
|
z-index: 999;
|
||||||
height: 316px;
|
|
||||||
display: flex;
|
|
||||||
z-index: 2;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
background: linear-gradient(to bottom, transparent 0%, rgba(15, 32, 54, 0.8) 50%, #102238 100%);
|
|
||||||
// background: url('/src/assets/images/preview-bottom.png') center center / 100% 100% no-repeat;
|
|
||||||
|
|
||||||
.cbox {
|
|
||||||
width: 48%;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
|
:deep(.el-checkbox-button__inner) {
|
||||||
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.r-box {
|
|
||||||
position: absolute;
|
|
||||||
top: 100px;
|
|
||||||
right: 0px;
|
|
||||||
width: 420px;
|
|
||||||
height: 980px;
|
|
||||||
z-index: 2;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
background: linear-gradient(to right, transparent 0%, rgba(15, 32, 54, 0.8) 50%, #102238 100%);
|
|
||||||
|
|
||||||
.rbox-item {
|
|
||||||
width: 100%;
|
|
||||||
height: 316px;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,61 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div
|
|
||||||
class="popover"
|
|
||||||
:style="{
|
|
||||||
'top': props.top + 'px',
|
|
||||||
'left': props.left + 'px',
|
|
||||||
'display': isShow ? 'inline-block' : 'none'
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<div class="popover-title">
|
|
||||||
{{ dataRef.name }}
|
|
||||||
</div>
|
|
||||||
<div class="popover-content">
|
|
||||||
{{ 'content' }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup name="Popover">
|
|
||||||
import { ref } from 'vue';
|
|
||||||
type PropsTypes = {
|
|
||||||
top: number;
|
|
||||||
left: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
const props = withDefaults(defineProps<PropsTypes>(), {
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
const isShow = ref(false);
|
|
||||||
const dataRef = ref<any>({});
|
|
||||||
|
|
||||||
const setShow = (visible: boolean, data?: any) => {
|
|
||||||
isShow.value = visible;
|
|
||||||
if (data) dataRef.value = data;
|
|
||||||
};
|
|
||||||
|
|
||||||
defineExpose({
|
|
||||||
setShow,
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.popover {
|
|
||||||
position: absolute;
|
|
||||||
background-color: rgb(29 78 216 / 0.6);
|
|
||||||
/* background-image: url('/src/assets/images/preview-bottom.png'); */
|
|
||||||
border-radius: 5px;
|
|
||||||
font-size: 0.2rem;
|
|
||||||
color: #fff;
|
|
||||||
font-size: 30px;
|
|
||||||
}
|
|
||||||
.popover-title {
|
|
||||||
padding: 12px;
|
|
||||||
border-bottom: 1px solid #fff;
|
|
||||||
}
|
|
||||||
.popover-content {
|
|
||||||
padding: 24px;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,385 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div id="three"></div>
|
|
||||||
<Popover ref="popoverRef" :top="popoverTop" :left="popoverLeft" :data="popoverData"></Popover>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup name="Sence">
|
|
||||||
/* eslint-disable */
|
|
||||||
import { ref, onMounted, type Ref } from 'vue';
|
|
||||||
import Viewer, { type Animate } from '@/modules/Viewer';
|
|
||||||
import Floors from '@/modules/Floors';
|
|
||||||
import ModelLoader from '@/modules/ModelLoder';
|
|
||||||
import * as THREE from 'three';
|
|
||||||
import gsap from 'gsap';
|
|
||||||
import Event from '@/modules/Viewer/Events';
|
|
||||||
import BoxHelperWrap from '@/modules/BoxHelperWrap';
|
|
||||||
import { checkNameIncludes, findParent } from '@/utils/threejs';
|
|
||||||
|
|
||||||
import Popover from './Popover/index.vue';
|
|
||||||
|
|
||||||
let viewer: Viewer;
|
|
||||||
let modelLoader: ModelLoader;
|
|
||||||
let boxHelperWrap: BoxHelperWrap;
|
|
||||||
|
|
||||||
const popoverRef: Ref = ref(null);
|
|
||||||
const popoverTop = ref(0);
|
|
||||||
const popoverLeft = ref(0);
|
|
||||||
const popoverData = ref<any>({});
|
|
||||||
|
|
||||||
let office: any = null;
|
|
||||||
let oldOffice: any = null;
|
|
||||||
let dataCenter: any = null;
|
|
||||||
let oldDataCenter: any = null;
|
|
||||||
let modelSelect = ['zuo0', 'zuo1', 'zuo2', 'zuo3', 'zuo4', 'zuo5'];
|
|
||||||
let modelSelectName = '';
|
|
||||||
let modelMoveName = '';
|
|
||||||
let isModelSelectName = false;
|
|
||||||
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
init();
|
|
||||||
initModel();
|
|
||||||
|
|
||||||
viewer.scene.traverse((item: THREE.Object3D) => {
|
|
||||||
//console.log(item, '0000000000');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const init = () => {
|
|
||||||
viewer = new Viewer('three',{width: 1920, height: 1080});
|
|
||||||
// viewer.addAxis();
|
|
||||||
// viewer.addStats();
|
|
||||||
viewer.initRaycaster();
|
|
||||||
|
|
||||||
modelLoader = new ModelLoader(viewer);
|
|
||||||
// const floors = new Floors(viewer);
|
|
||||||
// floors.addGird();
|
|
||||||
|
|
||||||
boxHelperWrap = new BoxHelperWrap(viewer);
|
|
||||||
|
|
||||||
viewer.emitter.on(Event.dblclick.raycaster, (list: THREE.Intersection[]) => {
|
|
||||||
console.log(list, 'list');
|
|
||||||
|
|
||||||
onMouseClick(list);
|
|
||||||
});
|
|
||||||
|
|
||||||
viewer.emitter.on(Event.mousemove.raycaster, (list: THREE.Intersection[]) => {
|
|
||||||
onMouseMove(list);
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
const initModel = () => {
|
|
||||||
// modelLoader.loadModelToScene('/models/zuo.glb', baseModel => {
|
|
||||||
// console.log(baseModel, '1111111');
|
|
||||||
|
|
||||||
// baseModel.setScalc(0.01);
|
|
||||||
// const model = baseModel.gltf.scene;
|
|
||||||
// office = baseModel;
|
|
||||||
// office.object.rotation.y = Math.PI;
|
|
||||||
// office.object.position.set(2, 0, 0);
|
|
||||||
// // model.position.set(80, 2, 90);
|
|
||||||
// office.object.children.forEach((item: any) => {
|
|
||||||
// item.name = item.name.replace('zuo', '');
|
|
||||||
// if (item.name === 'ding') {
|
|
||||||
// item.name = 6;
|
|
||||||
// }
|
|
||||||
// item.name--;
|
|
||||||
// });
|
|
||||||
// office.object.children.sort((a: { name: number; }, b: { name: number; }) => a.name - b.name).forEach((v: { name: string; }) => {
|
|
||||||
// v.name = 'zuo' + v.name;
|
|
||||||
// });
|
|
||||||
|
|
||||||
// model.name = '办公楼';
|
|
||||||
// baseModel.openCastShadow();
|
|
||||||
// oldOffice = model.clone();
|
|
||||||
|
|
||||||
// const list: THREE.Object3D<THREE.Event>[] = [];
|
|
||||||
// model.traverse(item => {
|
|
||||||
// list.push(item);
|
|
||||||
// });
|
|
||||||
// viewer.setRaycasterObjects(list);
|
|
||||||
// });
|
|
||||||
|
|
||||||
modelLoader.loadModelToScene('/models/plane.glb', baseModel => {
|
|
||||||
const model = baseModel.gltf.scene;
|
|
||||||
model.scale.set(0.01 * 3, 0.01 * 3, 0.01 * 3)
|
|
||||||
model.name = 'plane';
|
|
||||||
baseModel.openCastShadow();
|
|
||||||
|
|
||||||
const texture = (baseModel.object.children[0] as any).material.map;
|
|
||||||
// console.log(baseModel,baseModel.object.children[0], 'texture-------2222');
|
|
||||||
const fnOnj = planeAnimate(texture);
|
|
||||||
viewer.addAnimate(fnOnj);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
let objUrl = {
|
|
||||||
mtlUrl: '/obj/goats_R&D.mtl',
|
|
||||||
objUrl: '/obj/goats_R&D.obj',
|
|
||||||
}
|
|
||||||
modelLoader.ladObjModelToScene(objUrl, baseModel => {
|
|
||||||
var scale = 0.07 / baseModel.scale.x;
|
|
||||||
baseModel.scale.set(scale, scale, scale);
|
|
||||||
const box = new THREE.Box3().setFromObject(baseModel);
|
|
||||||
const size = box.getSize(new THREE.Vector3())
|
|
||||||
// // console.log(size,'-----');
|
|
||||||
baseModel.position.set(-size.x * 0.5, -size.y * 0.1+2, -size.z * 0.5);
|
|
||||||
// baseModel.children.forEach((child) => {
|
|
||||||
// const c = child;
|
|
||||||
// const cm = c.material;
|
|
||||||
// cm.emissive = cm.color;
|
|
||||||
// cm.emissiveMap = cm.map;
|
|
||||||
// });
|
|
||||||
|
|
||||||
baseModel.name = '再登研发中心';
|
|
||||||
dataCenter = baseModel;
|
|
||||||
oldDataCenter = baseModel.clone();
|
|
||||||
|
|
||||||
const rackList: any[] = [];
|
|
||||||
baseModel.traverse(item => {
|
|
||||||
|
|
||||||
if (checkIsRack(item)) {
|
|
||||||
rackList.push(item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// console.log(baseModel,rackList, 'rackList------111');
|
|
||||||
|
|
||||||
viewer.setRaycasterObjects(rackList);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// modelLoader.loadModelToScene('/models/datacenter.glb', baseModel => {
|
|
||||||
// console.log(baseModel, '1111111');
|
|
||||||
// baseModel.setScalc(0.2);
|
|
||||||
// // baseModel.object.rotation.y = Math.PI / 2;
|
|
||||||
// const model = baseModel.gltf.scene;
|
|
||||||
// model.position.set(0, 0, 0);
|
|
||||||
// model.name = '机房';
|
|
||||||
// baseModel.openCastShadow();
|
|
||||||
|
|
||||||
// dataCenter = baseModel;
|
|
||||||
// oldDataCenter = model.clone();
|
|
||||||
|
|
||||||
// const rackList: any[] = [];
|
|
||||||
// model.traverse(item => {
|
|
||||||
// if (checkIsRack(item)) {
|
|
||||||
// rackList.push(item);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// // console.log(rackList, 'rackList------');
|
|
||||||
|
|
||||||
// viewer.setRaycasterObjects(rackList);
|
|
||||||
|
|
||||||
// });
|
|
||||||
};
|
|
||||||
|
|
||||||
const planeAnimate = (texture: any): Animate => {
|
|
||||||
texture.wrapS = THREE.RepeatWrapping;
|
|
||||||
texture.wrapT = THREE.RepeatWrapping;
|
|
||||||
const animateFn = {
|
|
||||||
fun: () => {
|
|
||||||
const count = texture.repeat.y;
|
|
||||||
if (count <= 10) {
|
|
||||||
texture.repeat.x += 0.01;
|
|
||||||
texture.repeat.y += 0.02;
|
|
||||||
} else {
|
|
||||||
texture.repeat.x = 0;
|
|
||||||
texture.repeat.y = 0;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
content: viewer,
|
|
||||||
};
|
|
||||||
return animateFn;
|
|
||||||
}
|
|
||||||
|
|
||||||
const onMouseClick = (intersects: THREE.Intersection[]) => {
|
|
||||||
if (!intersects.length) return;
|
|
||||||
const selectedObject = intersects[0].object;
|
|
||||||
|
|
||||||
let selectedObjectName = '';
|
|
||||||
const findClickModel = (object: any) => {
|
|
||||||
console.log(object, 'object');
|
|
||||||
if (object.type === 'Group') {
|
|
||||||
selectedObjectName = object.name;
|
|
||||||
}
|
|
||||||
if (object.parent && object.type !== 'Scene') {
|
|
||||||
findClickModel(object.parent);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
findClickModel(selectedObject);
|
|
||||||
console.log(selectedObjectName);
|
|
||||||
|
|
||||||
// if (!selectedObjectName || !selectedObjectName.includes('办公楼')) {
|
|
||||||
// // this.scene.remove(this.label);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const selectedModel = viewer.scene.getObjectByName(selectedObjectName);
|
|
||||||
console.log(selectedObject, 'selectedObject');
|
|
||||||
|
|
||||||
// 点击楼房
|
|
||||||
if (selectedObject.name.includes('zuo')) {
|
|
||||||
|
|
||||||
selectOffice(selectedObject.parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 点击其他区域
|
|
||||||
if (!selectedObject.name.includes('zuo')) {
|
|
||||||
if (!isModelSelectName && oldOffice) {
|
|
||||||
let oldmodel = oldOffice.getObjectByName(modelMoveName);
|
|
||||||
office.object.getObjectByName(modelMoveName).traverse(function (child: { isMesh: any; material: any; name: any; }) {
|
|
||||||
if (child.isMesh) {
|
|
||||||
child.material = oldmodel.getObjectByName(child.name).material;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function checkIsRack(obj: any): boolean {
|
|
||||||
return checkNameIncludes(obj, 'Door');
|
|
||||||
}
|
|
||||||
|
|
||||||
const onMouseMove = (intersects: THREE.Intersection[]) => {
|
|
||||||
if (!intersects.length) {
|
|
||||||
popoverRef.value.setShow(false);
|
|
||||||
boxHelperWrap.setVisible(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const selectedObject = intersects[0].object || {};
|
|
||||||
|
|
||||||
|
|
||||||
let selectedObjectName = '';
|
|
||||||
const findClickModel = (object: any) => {
|
|
||||||
if (object.name.includes('Door')) {
|
|
||||||
selectedObjectName = object.name;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (object.parent) {
|
|
||||||
findClickModel(object.parent);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// const findClickModel = (object: any) => {
|
|
||||||
// if (object.name.includes('zuo')) {
|
|
||||||
// selectedObjectName = object.name;
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// if (object.parent) {
|
|
||||||
// findClickModel(object.parent);
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
findClickModel(selectedObject);
|
|
||||||
|
|
||||||
// console.log(selectedObjectName,selectedObject, '--selectedObjectName---');
|
|
||||||
const rack = findParent(selectedObject, checkIsRack);
|
|
||||||
// console.log(rack, '-------rack---------');
|
|
||||||
if (rack) {
|
|
||||||
|
|
||||||
boxHelperWrap.attach(rack);
|
|
||||||
updateRackInfo(rack.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (!selectedObjectName || !selectedObjectName.includes('办公楼')) {
|
|
||||||
// // 重置模型
|
|
||||||
// // viewer.scene.children[viewer.scene.children.findIndex(o => o.name === '办公楼')] = office.object = oldOffice.clone();
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
modelSelect.forEach((item: any) => {
|
|
||||||
if (item === selectedObject.parent?.name) {
|
|
||||||
modelMoveName = item;
|
|
||||||
if (modelSelectName === modelMoveName) return;
|
|
||||||
office.object.getObjectByName(item).traverse(function (child: { isMesh: any; material: THREE.MeshPhongMaterial; }) {
|
|
||||||
if (child.isMesh) {
|
|
||||||
child.material = new THREE.MeshPhongMaterial({
|
|
||||||
side: THREE.DoubleSide,
|
|
||||||
transparent: true,
|
|
||||||
depthTest: false,
|
|
||||||
depthWrite: true, // 无法被选择,鼠标穿透
|
|
||||||
color: 'yellow',
|
|
||||||
opacity: 0.3,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
if (!isModelSelectName && oldOffice) {
|
|
||||||
let oldmodel = oldOffice.getObjectByName(item);
|
|
||||||
office.object.getObjectByName(item).traverse(function (child: { isMesh: any; material: any; name: any; }) {
|
|
||||||
if (child.isMesh) {
|
|
||||||
child.material = oldmodel.getObjectByName(child.name).material;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
const updateRackInfo = (name: string) => {
|
|
||||||
if (name) {
|
|
||||||
popoverRef.value.setShow(true, { name });
|
|
||||||
const event = viewer.mouseEvent as MouseEvent;
|
|
||||||
popoverTop.value = event.y + 10;
|
|
||||||
popoverLeft.value = event.x + 10;
|
|
||||||
} else {
|
|
||||||
popoverRef.value.setShow(false);
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const selectOffice = (model: any) => {
|
|
||||||
modelSelectName = model.name;
|
|
||||||
let oldmodel = oldOffice.getObjectByName(modelSelectName);
|
|
||||||
let modelSelectIndex = modelSelect.findIndex(v => v === modelSelectName);
|
|
||||||
office.object.children.forEach((child: any, index: number) => {
|
|
||||||
child.children.forEach((Mesh: any) => {
|
|
||||||
if (child.name === modelSelectName) {
|
|
||||||
child.children.forEach((Mesh: { material: any; name: any; }) => {
|
|
||||||
Mesh.material = oldmodel.getObjectByName(Mesh.name).material;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Mesh.material = new THREE.MeshPhongMaterial({
|
|
||||||
// color: new THREE.Color('#123ca8'),
|
|
||||||
// transparent: true,
|
|
||||||
// opacity: 0.5,
|
|
||||||
// emissiveMap: Mesh.material.map,
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (!model.userData.position && index > modelSelectIndex) {
|
|
||||||
gsap.to(child.position, {
|
|
||||||
y: !child.userData.position ? child.position.y + 60 : child.position.y,
|
|
||||||
duration: 2,
|
|
||||||
ease: "power1.inOut",
|
|
||||||
onComplete: () => {
|
|
||||||
child.userData.position = true;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (model.userData.position && index <= modelSelectIndex) {
|
|
||||||
if (child.userData.position) {
|
|
||||||
gsap.to(child.position, {
|
|
||||||
y: oldOffice.getObjectByName(child.name).position.y,
|
|
||||||
duration: 2,
|
|
||||||
ease: "power1.inOut",
|
|
||||||
onComplete: () => {
|
|
||||||
child.userData.position = false;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
#three {
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,121 +0,0 @@
|
|||||||
<template>
|
|
||||||
<v-chart :option="options" theme="dark" style="width: 100%;height: 100%;" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { computed } from 'vue';
|
|
||||||
|
|
||||||
const prop = defineProps({
|
|
||||||
data: {
|
|
||||||
type: Object,
|
|
||||||
default: () => {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
"devId": "48a2ec70-a60c-11ef-91f3-abd609c7e488",
|
|
||||||
"devName": "噪声监测7",
|
|
||||||
"label": "noise-7",
|
|
||||||
"place": null,
|
|
||||||
"data": 0,
|
|
||||||
"status": 0
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const bodyMax = 150;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const options = computed(() => {
|
|
||||||
|
|
||||||
|
|
||||||
let xData = []
|
|
||||||
let seriesData = []
|
|
||||||
prop.data.forEach((item) => {
|
|
||||||
xData.push(item.devName);
|
|
||||||
seriesData.push(item.data);
|
|
||||||
});
|
|
||||||
const labelSetting = {
|
|
||||||
show: true,
|
|
||||||
position: 'top',
|
|
||||||
offset: [0, -20],
|
|
||||||
formatter: function (param) {
|
|
||||||
return xData[param.dataIndex] + '\r\n' + seriesData[param.dataIndex] + 'dB';
|
|
||||||
},
|
|
||||||
fontSize: 14,
|
|
||||||
fontFamily: 'Arial',
|
|
||||||
color: '#33FFFF'
|
|
||||||
};
|
|
||||||
return {
|
|
||||||
tooltip: {
|
|
||||||
},
|
|
||||||
backgroundColor: 'transparent',
|
|
||||||
xAxis: {
|
|
||||||
data: xData,
|
|
||||||
axisTick: { show: false },
|
|
||||||
axisLine: { show: false },
|
|
||||||
axisLabel: { show: false }
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
show: false,
|
|
||||||
max: bodyMax,
|
|
||||||
offset: 20,
|
|
||||||
splitLine: { show: false },
|
|
||||||
},
|
|
||||||
grid: {
|
|
||||||
top: 'center',
|
|
||||||
height: 230,
|
|
||||||
left: 0,
|
|
||||||
right: 0
|
|
||||||
},
|
|
||||||
markLine: {
|
|
||||||
z: -100
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: 'typeA',
|
|
||||||
type: 'pictorialBar',
|
|
||||||
symbolClip: true,
|
|
||||||
symbolBoundingData: bodyMax,
|
|
||||||
symbolRepeat: true, //图形是否重复
|
|
||||||
symbolSize: [25, 6], //图形元素的尺寸
|
|
||||||
itemStyle: {
|
|
||||||
color: '#33FFFF'
|
|
||||||
},
|
|
||||||
data: seriesData.map((item) => {
|
|
||||||
let dataobj = {
|
|
||||||
value: item
|
|
||||||
}
|
|
||||||
if (item > 100) {
|
|
||||||
dataobj.itemStyle = {
|
|
||||||
color: '#FF0000'
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return dataobj
|
|
||||||
}),
|
|
||||||
z: 10
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'full',
|
|
||||||
type: 'pictorialBar',
|
|
||||||
symbolBoundingData: bodyMax,
|
|
||||||
label: labelSetting,
|
|
||||||
animationDuration: 0,
|
|
||||||
symbolRepeat: true, //图形是否重复
|
|
||||||
symbolSize: [25, 6], //图形元素的尺寸
|
|
||||||
itemStyle: {
|
|
||||||
color: '#ccc'
|
|
||||||
},
|
|
||||||
data: prop.data.map(item => {
|
|
||||||
return {
|
|
||||||
value: 100,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
@ -1,37 +0,0 @@
|
|||||||
<template>
|
|
||||||
<svg t="1730769272802" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
|
||||||
p-id="1039" width="256" height="256" :fill="prop.color">
|
|
||||||
<path
|
|
||||||
d="M378.105721 356.776833a62.282417 62.282417 0 0 0-0.01338-63.076668 62.287282 62.287282 0 0 0-55.100101-30.706985c-33.842635 0.76506-60.877578 28.426402-60.867847 62.273902 0.00973 33.852366 27.053187 61.499113 60.895823 62.245928a62.275119 62.275119 0 0 0 55.085505-30.736177zM751.756435 356.776833a62.27147 62.27147 0 0 0-55.114696-93.783653c-33.842635 0.76506-60.877578 28.426402-60.867848 62.273902 0.00973 33.852366 27.058053 61.499113 60.900688 62.245928a62.275119 62.275119 0 0 0 55.081856-30.736177zM540.953941 325.271948c0-17.199853-13.940139-31.139992-31.138776-31.139993-17.194987 0-31.135127 13.940139-31.135127 31.139993 0 17.193771 13.940139 31.133911 31.135127 31.13391 17.198636 0 31.138776-13.940139 31.138776-31.13391zM323.020216 761.162508a62.279984 62.279984 0 0 0 55.085505-30.731312 62.282417 62.282417 0 0 0-0.01338-63.076667 62.267821 62.267821 0 0 0-55.100101-30.706986c-33.842635 0.76506-60.877578 28.421537-60.867847 62.273903 0.00973 33.848717 27.053187 61.495464 60.895823 62.241062zM696.675795 761.162508a62.27147 62.27147 0 0 0 55.066045-93.807979 62.267821 62.267821 0 0 0-55.100101-30.706986c-33.842635 0.76506-60.877578 28.421537-60.867848 62.273903 0.00973 33.848717 27.058053 61.495464 60.901904 62.241062zM478.680038 698.922662c0 17.194987 13.940139 31.135127 31.135127 31.135127 17.198636 0 31.138776-13.940139 31.138776-31.135127 0-17.201069-13.940139-31.141208-31.138776-31.141208-17.194987 0-31.135127 13.940139-31.135127 31.141208zM665.502963 512.093656c0 17.199853 13.945005 31.139992 31.139992 31.139992 17.199853 0 31.139992-13.940139 31.139992-31.139992 0-17.193771-13.940139-31.133911-31.139992-31.133911-17.196204 0-31.139992 13.940139-31.139992 31.133911zM291.852248 512.093656c0 17.199853 13.940139 31.139992 31.139992 31.139992 17.194987 0 31.135127-13.940139 31.135127-31.139992 0-17.193771-13.940139-31.133911-31.135127-31.133911-17.199853 0-31.139992 13.940139-31.139992 31.133911zM448.952183 512.093656c0.003649 33.852366 27.053187 61.495464 60.895822 62.245928a62.27147 62.27147 0 0 0 55.08064-30.736177 62.273903 62.273903 0 0 0-55.11348-93.78487c-33.838986 0.766276-60.872713 28.422754-60.862982 62.275119z"
|
|
||||||
p-id="1040"></path>
|
|
||||||
<path
|
|
||||||
d="M970.857819 318.763468c-25.181285-59.281778-61.204765-112.580522-107.052389-158.434228-45.863436-45.863436-99.171911-81.883267-158.441526-107.059687a491.752072 491.752072 0 0 0-193.366677-39.291708c-83.403656 0-171.837974 23.574538-249.031147 66.383817-12.851541 7.89629-13.060747 22.976113-9.240314 33.865745 4.075858 5.958707 9.962803 9.099222 17.056328 9.099222 4.884705 0 9.996859-1.525254 14.800071-4.404261l0.437872-0.261507 0.451252-0.246911c72.839996-38.846538 148.71712-58.544693 225.534452-58.544694 249.379012 0 452.256024 202.881878 452.256024 452.253591 0 249.377795-202.877012 452.259673-452.256024 452.259673-249.376579 0-452.253591-202.881878-452.253591-452.259673 0-76.807602 19.694506-152.694457 58.534963-225.516207l0.246911-0.460982 0.266372-0.441521c7.265025-12.110808 1.772165-26.726-7.739387-33.862096-2.365725-1.7673-5.702066-2.038537-7.47423-2.038537-8.798793 0-18.591312 5.578002-23.351953 13.289413-42.808063 77.198038-66.383817 165.632356-66.383818 249.02993a491.870054 491.870054 0 0 0 39.292924 193.370327c25.18615 59.280562 61.195035 112.575657 107.058471 158.437876 45.858571 45.859787 99.163397 81.873537 158.434228 107.056039a491.843295 491.843295 0 0 0 193.36911 39.292924 491.928437 491.928437 0 0 0 193.359379-39.283194c59.273264-25.18615 112.57809-61.196251 158.441526-107.059687 45.858571-45.858571 81.871104-99.16218 107.052389-158.435444 26.07649-61.365319 39.292924-126.433087 39.292925-193.367894s-13.216434-131.995277-39.294141-193.370326z"
|
|
||||||
p-id="1041" class="border"></path>
|
|
||||||
</svg>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, onMounted } from 'vue';
|
|
||||||
const prop = defineProps({
|
|
||||||
color: '#469DE9'
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
/** .border设置循环旋转动画效果 */
|
|
||||||
.border {
|
|
||||||
animation: rotate 3s linear infinite;
|
|
||||||
transform-origin: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes rotate {
|
|
||||||
0% {
|
|
||||||
transform: rotate(0deg) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
@ -1,36 +0,0 @@
|
|||||||
<template>
|
|
||||||
<svg t="1730777236728" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
|
||||||
p-id="1648" width="256" height="256" :fill="prop.color">
|
|
||||||
<path
|
|
||||||
d="M512 22.26087A488.136348 488.136348 0 0 0 165.709913 165.709913 488.136348 488.136348 0 0 0 22.26087 512a488.136348 488.136348 0 0 0 143.449043 346.290087A488.136348 488.136348 0 0 0 512 1001.73913a488.136348 488.136348 0 0 0 346.290087-143.449043A488.136348 488.136348 0 0 0 1001.73913 512a488.136348 488.136348 0 0 0-143.449043-346.290087A488.136348 488.136348 0 0 0 512 22.26087m0-22.26087c282.779826 0 512 229.220174 512 512S794.779826 1024 512 1024 0 794.779826 0 512 229.220174 0 512 0z"
|
|
||||||
p-id="1649"></path>
|
|
||||||
<path
|
|
||||||
d="M748.477217 625.775304a57.677913 57.677913 0 0 0-35.328 12.198957l-73.928347-42.674087a130.715826 130.715826 0 0 0-80.339479-165.954783v-69.565217a84.057043 84.057043 0 1 0-87.485217-5.075478v74.551652a130.715826 130.715826 0 0 0-80.339478 165.954782l-73.928348 42.674087a57.566609 57.566609 0 1 0 18.18713 23.04l68.140522-39.379478a131.027478 131.027478 0 0 0 223.187478 0l68.140522 39.379478a57.655652 57.655652 0 0 0-4.786087 23.04 58.301217 58.301217 0 1 0 58.434783-58.212174z m-247.874782-258.226087a80.740174 80.740174 0 0 0 29.184 1.424696v53.648696a124.14887 124.14887 0 0 0-29.117218 0v-55.073392z m14.558608 287.47687a102.066087 102.066087 0 1 1 102.110609-102.021565 102.066087 102.066087 0 0 1-102.110609 101.954782z"
|
|
||||||
p-id="1650" class="border"></path>
|
|
||||||
</svg>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, onMounted } from 'vue';
|
|
||||||
const prop = defineProps({
|
|
||||||
color: '#469DE9'
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
/** .border设置循环旋转动画效果 */
|
|
||||||
.border {
|
|
||||||
animation: rotate 3s linear infinite;
|
|
||||||
transform-origin: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes rotate {
|
|
||||||
0% {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,36 +0,0 @@
|
|||||||
<template>
|
|
||||||
<svg t="1731979776030" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
|
||||||
p-id="15886" width="256" height="256" :fill="prop.color">
|
|
||||||
<path
|
|
||||||
d="M507.44 955.95a438.912 438.912 0 0 1-172.62-35.08c-52.91-22.48-100.5-54.63-141.43-95.57-40.94-40.94-73.09-88.52-95.57-141.44a439.09 439.09 0 0 1-35.08-172.62c0-74.45 21.05-153.39 59.26-222.31 4.25-6.88 12.99-11.86 20.85-11.86 1.58 0 4.56 0.24 6.67 1.82 8.49 6.37 13.39 19.42 6.91 30.23l-0.24 0.39-0.22 0.41c-34.67 65.01-52.25 132.75-52.25 201.32 0 222.62 181.11 403.73 403.73 403.73s403.73-181.11 403.73-403.73c0-222.61-181.11-403.73-403.73-403.73-68.57 0-136.31 17.58-201.33 52.26l-0.4 0.22-0.39 0.23c-4.29 2.57-8.85 3.93-13.21 3.93-6.33 0-11.59-2.8-15.23-8.12-3.41-9.72-3.22-23.18 8.25-30.23C354.05 87.58 433 66.54 507.45 66.54a438.912 438.912 0 0 1 172.62 35.08c52.91 22.48 100.5 54.63 141.44 95.57 40.93 40.93 73.09 88.51 95.57 141.43 23.28 54.79 35.08 112.87 35.08 172.62s-11.8 117.84-35.08 172.62c-22.48 52.91-54.63 100.5-95.57 141.43-40.94 40.94-88.53 73.09-141.44 95.57a438.83 438.83 0 0 1-172.63 35.09z m0 0"
|
|
||||||
p-id="15887" class="border"></path>
|
|
||||||
<path
|
|
||||||
d="M327.36 460.82c0 22.16 18.05 40.64 39.71 40.64s39.73-18.57 39.73-40.64c3.62-25.85-18.05-40.61-39.73-40.61s-39.71 18.44-39.71 40.61z m377.59-94.43c-14.46 0-25.3 11.09-25.3 22.16 3.62 11.07 14.46 22.16 25.3 22.16 14.43 0 25.27-11.09 25.27-22.16s-10.84-22.16-25.27-22.16z m-110.23 18.29c21.68 0 39.73-18.56 39.73-40.61s-18.06-40.61-39.73-40.61c-21.67 0-39.73 18.57-39.73 40.61-3.6 22.09 14.46 40.54 39.73 40.54v0.07zM429.23 395.7c18.08 0 36.11-14.78 36.11-33.23 0-18.45-14.43-33.21-36.11-33.21-18.06 0-36.11 14.76-36.11 33.23s14.46 33.21 36.11 33.21z m178.99 95.33c0 18.57 14.46 33.23 36.11 33.23 18.05 0 36.11-14.78 36.11-33.23 0-18.45-14.43-33.23-36.11-33.23-17.96 0-36.11 14.76-36.11 33.23z m-89.64-3.02c18.05 0 28.89-14.87 28.89-29.54s-14.43-29.43-28.89-29.43c-18.05 0-28.89 14.64-28.89 29.43 0 14.78 14.45 29.54 28.89 29.54z m178.2 63.15c-3.88 0-7.77 0-9.7 2-77.74 55.51-147.71 15.85-149.66 13.92-145.76-91.25-242.9 5.85-242.9 5.85a10.313 10.313 0 0 0-3.88 7.94c0.47 2.98 1.81 5.75 3.88 7.96 3.9 5.96 11.6 3.97 17.5 0 1.95-3.97 81.62-81.22 209.9-1.97 1.95 1.97 33.05 19.82 77.74 19.82 29.15 0 66.07-7.91 102.99-33.7a14.953 14.953 0 0 0 1.95-17.85 10.057 10.057 0 0 0-7.82-3.97z m-383.26-185a29.21 29.21 0 0 0 20.56-8.77c5.42-5.54 8.41-13 8.33-20.75 0.19-16.14-12.73-29.39-28.87-29.59a29.227 29.227 0 0 0-28.89 29.54 29.22 29.22 0 0 0 8.3 20.77 29.22 29.22 0 0 0 20.57 8.8z m57.14 267.22h-32.77v95.15h22.49v-31.52h10.91c19.7 0 36.9-9.98 36.9-32.65 0.04-23.55-16.95-30.98-37.53-30.98z m-0.49 45.58h-9.79v-27.52h9.17c10.79 0 16.8 3.34 16.8 12.93 0 9.58-5.27 14.59-16.18 14.59z m103.92-4.48c-1.76 5.5-3.27 11.6-5.15 17.41h-0.63c-1.76-5.87-3.27-11.91-5.15-17.41l-14.81-41.1h-24.23v95.15h20.08v-32.61c-0.39-11.05-1.35-22.07-2.88-33.02h0.51l7.52 22.79 12.67 34.81h12.3l12.56-34.81 7.77-22.79h0.51a320.218 320.218 0 0 0-2.88 33.02v32.72h20.38V633.5h-24.27l-14.3 40.98z m101.23-41.1h-16.45a62.13 62.13 0 0 1-23.21 8.59v14.09h17.2v54.14h-19.82v18.45H592V710.2h-16.69v-76.82z m62.66-1.79c-19.68 0-33 16.13-33 48.9 0 32.77 13.32 49.94 33 49.94s33.14-17.15 33.14-49.94c-0.01-32.79-13.42-48.9-33.14-48.9z m0 81.23c-6.64 0-11.9-6.15-11.9-32.28 0-26.13 5.27-31.35 11.9-31.35 6.64 0 12.07 5.38 12.07 31.35 0 25.97-5.41 32.23-12.07 32.23v0.05z m0 0"
|
|
||||||
p-id="15888"></path>
|
|
||||||
</svg>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, onMounted } from 'vue';
|
|
||||||
const prop = defineProps({
|
|
||||||
color: '#469DE9'
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
/** .border设置循环旋转动画效果 */
|
|
||||||
.border {
|
|
||||||
animation: rotate 3s linear infinite;
|
|
||||||
transform-origin: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes rotate {
|
|
||||||
0% {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,36 +0,0 @@
|
|||||||
<template>
|
|
||||||
<svg t="1731979377696" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
|
||||||
p-id="4643" width="256" height="256" :fill="prop.color">
|
|
||||||
<path
|
|
||||||
d="M510.24 954.86a438.195 438.195 0 0 1-172.33-35.02c-52.82-22.44-100.33-54.54-141.2-95.41-40.87-40.87-72.97-88.37-95.41-141.2A438.195 438.195 0 0 1 66.28 510.9c0-74.33 21.01-153.14 59.16-221.94 4.24-6.87 12.97-11.84 20.81-11.84 1.58 0 4.55 0.24 6.66 1.82 8.48 6.36 13.37 19.39 6.9 30.18l-0.24 0.39-0.22 0.41c-34.62 64.9-52.17 132.53-52.17 200.98 0 222.25 180.81 403.06 403.06 403.06S913.3 733.15 913.3 510.9c0-222.24-180.81-403.06-403.06-403.06-68.46 0-136.08 17.56-201 52.18l-0.4 0.22-0.39 0.23c-4.28 2.57-8.84 3.93-13.19 3.93-6.32 0-11.57-2.8-15.2-8.11-3.4-9.71-3.22-23.14 8.24-30.18 68.8-38.15 147.61-59.16 221.94-59.16a438.16 438.16 0 0 1 172.33 35.02c52.82 22.44 100.33 54.54 141.2 95.41 40.86 40.87 72.97 88.37 95.41 141.2 23.24 54.7 35.02 112.68 35.02 172.33s-11.78 117.64-35.02 172.33c-22.44 52.82-54.54 100.33-95.41 141.2-40.87 40.87-88.38 72.97-141.2 95.41a438.362 438.362 0 0 1-172.33 35.01z m0 0"
|
|
||||||
p-id="4644" class="border"></path>
|
|
||||||
<path
|
|
||||||
d="M314.61 465.3c0 22.12 18.02 40.53 39.63 40.53 21.61 0 39.66-18.51 39.66-40.53 3.61-25.8-18.02-40.54-39.66-40.54-21.64 0.01-39.63 18.33-39.63 40.54z m376.86-94.32c-14.41-0.09-25.13 10.93-25.13 22.03 3.61 11.05 14.41 22.1 25.22 22.1 14.43 0 25.25-11.05 25.25-22.1s-10.91-22.12-25.34-22.12v0.09z m-110 18.25c21.63 0 39.66-18.53 39.66-40.54 0-22-18.02-40.54-39.66-40.54-21.63 0-39.63 18.53-39.63 40.54-3.61 22.01 14.41 40.44 39.63 40.44v0.1z m-165.15 11.05c18.02 0 36.04-14.73 36.04-33.17s-14.43-33.26-36.04-33.26c-18.02 0-36.04 14.75-36.04 33.17 0 18.41 14.41 33.17 36.04 33.17v0.09z m178.63 95.13c0 18.53 14.43 33.17 36.04 33.17 18.02 0 36.04-14.75 36.04-33.17 0-18.41-14.41-33.17-36.04-33.17-17.92-0.04-36.04 14.64-36.04 33.17z m-89.48-3.03c18.02 0 28.84-14.73 28.84-29.49 0-14.76-14.41-29.46-28.84-29.46-18.02 0-28.84 14.73-28.84 29.46s14.43 29.44 28.84 29.44v0.05z m177.87 63.05c-3.87 0-7.76 0-9.68 1.97-77.6 55.41-147.46 15.84-149.38 13.9-145.49-91.12-242.45 5.84-242.45 5.84a10.358 10.358 0 0 0-3.87 7.92c0.47 2.97 1.81 5.73 3.87 7.92 3.89 5.93 11.58 3.96 17.46 0 1.95-3.96 81.46-81.07 209.51-1.97 1.95 1.97 32.98 19.78 77.6 19.78 29.09 0 65.95-7.92 102.82-33.65a14.92 14.92 0 0 0 1.92-17.79 9.92 9.92 0 0 0-7.8-3.96v0.04zM300.8 370.73c16.1-0.18 29.01-13.37 28.84-29.46a29.16 29.16 0 0 0-28.82-29.53c-16.1 0.19-29.01 13.38-28.84 29.49a29.1 29.1 0 0 0 8.29 20.73c5.41 5.52 12.8 8.68 20.53 8.77z m27.15 266.72h-32.68v94.97h22.42v-31.45h10.89c19.66 0 36.83-9.98 36.83-32.59-0.01-23.52-16.91-30.93-37.46-30.93z m-0.51 45.59h-9.75v-27.57h9.15c10.77 0 16.77 3.31 16.77 12.9s-5.26 14.67-16.17 14.67z m103.75-4.64c-1.76 5.49-3.27 11.58-5.14 17.37h-0.6c-1.74-5.88-3.24-11.88-5.12-17.37l-14.78-41.02h-24.11v94.97h19.92v-32.41c-0.39-11.04-1.35-22.05-2.87-32.98h0.51l7.5 22.75 12.65 34.75h12.28l12.53-34.75 7.76-22.75h0.51a316.917 316.917 0 0 0-2.87 32.98v32.57h20.4v-94.97h-24.3l-14.27 40.86z m86.91 36.23c14.29-14.69 28.05-32.71 28.05-49.06 0-18.16-12.51-29.9-30.55-29.9-13.27 0-21.8 4.84-30.95 14.69l12.16 12.28c4.38-4.86 9.26-9.27 15.77-9.27 7.39 0 12.16 4.63 12.16 13.44 0 13.9-15.66 31.04-38.96 52.65v13.02h64.65v-19.16h-17.19c-5.07 0.13-10.13 0.57-15.14 1.31z m60.75-8.57c-5.8-0.36-11.23 2.86-13.69 8.12a14.157 14.157 0 0 0 2.52 15.72 14.158 14.158 0 0 0 15.55 3.42c5.39-2.16 8.92-7.39 8.9-13.21 0.18-3.66-1.15-7.24-3.68-9.9a13.39 13.39 0 0 0-9.7-4.16h0.1z m62.27-35.51c-3.31-0.06-6.6 0.59-9.64 1.92l1.37-16.21h33.19v-18.9h-52.35l-2.32 47.02 9.75 6.51c5.54-3.57 8.04-4.63 13.16-4.63 8.04 0 13.66 5.12 13.66 14.69s-5.63 14.82-14.66 14.82c-7.39 0-13.9-3.96-19.16-9.06l-10.33 14.43a44.022 44.022 0 0 0 32.57 13.18c17.9 0 33.7-12.39 33.7-33.75 0-20.57-13.29-30.02-29.07-30.02h0.13z m0 0"
|
|
||||||
p-id="4645"></path>
|
|
||||||
</svg>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, onMounted } from 'vue';
|
|
||||||
const prop = defineProps({
|
|
||||||
color: '#469DE9'
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
/** .border设置循环旋转动画效果 */
|
|
||||||
.border {
|
|
||||||
animation: rotate 3s linear infinite;
|
|
||||||
transform-origin: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes rotate {
|
|
||||||
0% {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,36 +0,0 @@
|
|||||||
<template>
|
|
||||||
<svg t="1730777853051" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
|
||||||
p-id="2254" id="mx_n_1730777853052" width="256" height="256" :fill="prop.color">
|
|
||||||
<path
|
|
||||||
d="M511.952979 1023.896979a505.462446 505.462446 0 0 1-198.72418-40.381232c-60.914463-25.881164-115.693372-62.891387-162.824501-110.022515-47.131128-47.131128-84.141351-101.902162-110.022514-162.8245a505.462446 505.462446 0 0 1-40.381233-198.72418c0-85.708713 24.227164-176.592083 68.223569-255.928957 4.891115-7.923448 14.956887-13.657316 23.998754-13.657316 1.8194 0 5.245543 0.275667 7.679287 2.095067 9.774353 7.332734 15.421582 22.352631 7.954953 34.797013l-0.275667 0.456819-0.252038 0.472571C67.412872 355.019318 47.17106 433.009363 47.17106 511.944552c0 256.283385 208.498533 464.781919 464.781919 464.781918s464.781919-208.498533 464.781919-464.781918-208.498533-464.781919-464.781919-464.781919c-78.943064 0-156.925233 20.241811-231.780554 60.166224l-0.464696 0.252039-0.448943 0.26779c-4.938372 2.961448-10.191791 4.52881-15.208925 4.52881-7.293353 0-13.342268-3.229238-17.532401-9.349039-3.922343-11.192068-3.709686-26.692412 9.498686-34.804889 79.328998-43.996404 170.212368-68.223568 255.928957-68.223568a505.430941 505.430941 0 0 1 198.72418 40.381232c60.906587 25.873288 115.693372 62.891387 162.824501 110.022515 47.123252 47.123252 84.141351 101.902162 110.022515 162.824501 26.794802 63.072539 40.381232 129.933526 40.381232 198.72418s-13.58643 135.659517-40.381232 198.72418c-25.881164 60.914463-62.891387 115.693372-110.022515 162.824501-47.131128 47.131128-101.910038 84.141351-162.824501 110.022514a505.525456 505.525456 0 0 1-198.716304 40.373356z"
|
|
||||||
p-id="2255" class="border"></path>
|
|
||||||
<path
|
|
||||||
d="M716.088103 531.012811c-23.57344-52.345167-57.480443-102.288095-93.364371-155.160967-25.014783-36.852699-50.872319-74.949835-73.587254-114.74823l-0.181153-0.322923-38.506698-78.344474a1190.187004 1190.187004 0 0 0-16.587259 32.930355c-7.758048 15.783887-15.783887 32.111232-24.227164 46.855462-23.124497 40.538756-47.942376 79.116341-71.949007 116.425858-30.945555 48.076271-62.930768 97.79079-91.820637 152.514566-28.094374 69.444378-21.454745 144.449347 18.257012 205.867886 41.641423 64.411492 113.488039 104.438295 187.508483 104.438295 1.252314 0 2.496753-0.015752 3.756944-0.039381 75.761083-1.236562 145.024309-41.239737 185.255893-107.005934 38.490946-62.930768 44.256318-138.975394 15.445211-203.410513z m-41.594166 166.19551c-30.709269 58.323196-95.538199 103.595543-157.933386 106.060791h-0.716733c-65.269996-1.559486-126.877564-41.869832-160.90271-100.137895-34.607984-59.284091-34.214175-131.359117-6.395468-188.296103 25.314079-49.493985 83.897189-140.542756 130.122555-203.953971a37.293765 37.293765 0 0 1 61.158625 0.669476c21.375983 30.638384 49.470357 71.61033 66.994882 99.94099 19.462068 31.47326 37.845099 61.198006 50.9117 81.16415l0.3308 0.535581c40.341851 69.365616 49.186814 141.818699 16.429735 204.016981zM501.745435 594.298007c-63.994053 35.198698-126.475878 15.07503-159.390481-1.016029-1.590991 36.56128 7.529639 74.524521 27.133479 108.1086 31.796184 54.463862 85.015608 86.535713 146.032461 88.000685l0.669476-0.007876c50.4155-1.992676 99.232133-29.716869 130.098926-72.413702a416.099181 416.099181 0 0 0 20.604116-37.333147c14.051125-34.584356 16.603011-71.964759 7.742296-109.778353-36.33287-8.616553-101.847028-14.633963-172.890273 24.439822z"
|
|
||||||
p-id="2256"></path>
|
|
||||||
</svg>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, onMounted } from 'vue';
|
|
||||||
const prop = defineProps({
|
|
||||||
color: '#469DE9'
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
/** .border设置循环旋转动画效果 */
|
|
||||||
.border {
|
|
||||||
animation: rotate 3s linear infinite;
|
|
||||||
transform-origin: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes rotate {
|
|
||||||
0% {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,36 +0,0 @@
|
|||||||
<template>
|
|
||||||
<svg t="1730777586016" class="icon" viewBox="0 0 1152 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
|
||||||
p-id="1965" width="256" height="256" :fill="prop.color">
|
|
||||||
<path
|
|
||||||
d="M160 512c0-32-19.2-61.44-48.64-74.24l-10.24-3.84 1.28-11.52c17.92-96 64-183.04 133.12-252.16 90.88-90.88 211.2-140.8 340.48-140.8 176.64 0 337.92 96 422.4 250.88 3.84 6.4 12.8 8.96 19.2 5.12 6.4-3.84 8.96-12.8 5.12-19.2C934.4 102.4 762.88 0 576 0c-69.12 0-135.68 14.08-198.4 39.68-61.44 25.6-115.2 62.72-162.56 110.08-47.36 47.36-83.2 102.4-108.8 162.56-15.36 35.84-25.6 72.96-32 110.08l-1.28 8.96-8.96 2.56c-38.4 7.68-64 40.96-64 78.08 0 43.52 35.84 79.36 79.36 79.36 44.8 0 80.64-35.84 80.64-79.36z m912.64-79.36c-43.52 0-79.36 35.84-79.36 79.36 0 32 19.2 61.44 48.64 74.24l10.24 3.84-2.56 11.52c-17.92 96-64 183.04-133.12 252.16-90.88 90.88-211.2 140.8-340.48 140.8-176.64 0-337.92-96-422.4-250.88-2.56-5.12-7.68-7.68-12.8-7.68-2.56 0-5.12 0-6.4 1.28-3.84 1.28-6.4 5.12-6.4 8.96-1.28 3.84-1.28 7.68 1.28 11.52C217.6 921.6 389.12 1024 576 1024c69.12 0 135.68-14.08 198.4-39.68 61.44-25.6 115.2-62.72 162.56-110.08 47.36-47.36 83.2-102.4 108.8-162.56 15.36-35.84 25.6-72.96 32-110.08l1.28-8.96 8.96-2.56c38.4-7.68 64-40.96 64-78.08 0-43.52-35.84-79.36-79.36-79.36z"
|
|
||||||
p-id="1966" class="border"></path>
|
|
||||||
<path
|
|
||||||
d="M266.24 423.68h-69.12v-21.76h162.56v21.76h-69.12V627.2h-25.6V423.68zM382.72 401.92H409.6l38.4 124.16c7.68 26.88 12.8 47.36 21.76 74.24h1.28c8.96-26.88 14.08-47.36 23.04-74.24l37.12-124.16h25.6L483.84 627.2h-29.44l-71.68-225.28zM569.6 514.56c0-71.68 39.68-115.2 94.72-115.2 56.32 0 94.72 43.52 94.72 115.2s-39.68 117.76-94.72 117.76c-55.04-1.28-94.72-46.08-94.72-117.76z m163.84 0c0-57.6-26.88-93.44-69.12-93.44-40.96 0-69.12 35.84-69.12 93.44s26.88 94.72 69.12 94.72c42.24 0 69.12-37.12 69.12-94.72zM794.88 514.56c0-71.68 42.24-116.48 98.56-116.48 26.88 0 48.64 12.8 61.44 26.88l-14.08 16.64c-11.52-12.8-26.88-21.76-46.08-21.76-43.52 0-72.96 35.84-72.96 93.44s28.16 94.72 71.68 94.72c21.76 0 38.4-8.96 53.76-25.6l14.08 15.36c-17.92 20.48-39.68 32-69.12 32-56.32 1.28-97.28-42.24-97.28-115.2z"
|
|
||||||
p-id="1967"></path>
|
|
||||||
</svg>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, onMounted } from 'vue';
|
|
||||||
const prop = defineProps({
|
|
||||||
color: '#469DE9'
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
/** .border设置循环旋转动画效果 */
|
|
||||||
.border {
|
|
||||||
animation: rotate 3s linear infinite;
|
|
||||||
transform-origin: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes rotate {
|
|
||||||
0% {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,36 +0,0 @@
|
|||||||
<template>
|
|
||||||
<svg t="1730777903037" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
|
||||||
p-id="2469" width="256" height="256" :fill="prop.color">
|
|
||||||
<path
|
|
||||||
d="M511.2 959.1c-59.7 0.1-118.7-11.9-173.6-35.3-53.2-22.6-101.1-54.9-142.3-96.1-41.2-41.2-73.5-89-96.1-142.3a441 441 0 0 1-35.3-173.6c0-74.9 21.2-154.3 59.6-223.6 4.3-6.9 13.1-11.9 21-11.9 1.6 0 4.6 0.2 6.7 1.8 8.5 6.4 13.5 19.5 6.9 30.4l-0.2 0.4-0.2 0.4c-34.9 65.4-52.6 133.5-52.6 202.5 0 223.9 182.2 406.1 406.1 406.1 223.9 0 406.1-182.2 406.1-406.1 0-223.9-182.2-406.1-406.1-406.1-69 0-137.1 17.7-202.5 52.6l-0.4 0.2-0.4 0.2c-4.3 2.6-8.9 4-13.3 4-6.4 0-11.7-2.8-15.3-8.2-3.4-9.8-3.2-23.3 8.3-30.4 69.3-38.4 148.7-59.6 223.6-59.6 59.7-0.1 118.7 11.9 173.6 35.3 53.2 22.6 101.1 54.9 142.3 96.1 41.2 41.2 73.5 89 96.1 142.3 23.4 55.1 35.3 113.5 35.3 173.6s-11.9 118.5-35.3 173.6c-22.6 53.2-54.9 101.1-96.1 142.3-41.2 41.2-89 73.5-142.3 96.1a441 441 0 0 1-173.6 35.3z m0 0"
|
|
||||||
p-id="2470" class="border"></path>
|
|
||||||
<path
|
|
||||||
d="M531.5 583.1l-6-2.7V352.8c0-9.5-12-17.6-26.2-17.6s-26.2 8-26.2 17.6v227.7l-6.1 2.7c-28.8 12.9-47.5 41.9-47.5 73.8 0 44.5 35.8 80.7 79.7 80.7 43.9 0 79.7-36.2 79.7-80.7 0.1-31.9-18.5-61-47.4-73.9z m81.7-48.4l-3.2-3.1V286.8c0-24-12.3-47.2-33.8-63.6-20.7-15.9-48-24.6-76.9-24.6-28.9 0-56.2 8.7-76.9 24.6-21.5 16.5-33.8 39.7-33.8 63.6v244.9l-3.2 3.1c-33.1 31.6-52.1 76.2-52.1 122.3 0 44.9 17.3 87.1 48.6 118.9 31.4 31.8 73 49.2 117.4 49.2 44.3 0 86-17.5 117.4-49.2 31.4-31.8 48.6-74 48.6-118.9 0-46.2-19-90.8-52.1-122.4z m-113.9 263c-76.6 0-138.9-63.1-138.9-140.7 0-42.1 18.3-81.6 50.4-108.4l4.9-4.1V286.8c0-16.5 9.6-32.6 26.3-44.1 15.7-10.8 36.1-16.8 57.4-16.8 21.3 0 41.7 5.9 57.4 16.8 16.7 11.5 26.3 27.5 26.3 44.1v257.7l4.9 4.1c32 26.9 50.4 66.4 50.4 108.4-0.2 77.5-62.5 140.7-139.1 140.7zM642 304.5h36.4c5.9 0 10.6-3.9 10.6-8.7 0-4.8-4.8-8.7-10.6-8.7H642c-5.9 0-10.6 3.9-10.6 8.7 0 4.8 4.8 8.7 10.6 8.7z m36.4 20.6H642c-5.9 0-10.6 3.9-10.6 8.7 0 4.8 4.8 8.7 10.6 8.7h36.4c5.9 0 10.6-3.9 10.6-8.7 0-4.9-4.7-8.7-10.6-8.7z m0 37.9H642c-5.9 0-10.6 3.9-10.6 8.7 0 4.8 4.8 8.7 10.6 8.7h36.4c5.9 0 10.6-3.9 10.6-8.7 0-4.8-4.7-8.7-10.6-8.7z m0 37.9H642c-5.9 0-10.6 3.9-10.6 8.7 0 4.8 4.8 8.7 10.6 8.7h36.4c5.9 0 10.6-3.9 10.6-8.7 0-4.8-4.7-8.7-10.6-8.7z m0 38H642c-5.9 0-10.6 3.9-10.6 8.7s4.8 8.7 10.6 8.7h36.4c5.9 0 10.6-3.9 10.6-8.7 0-4.9-4.7-8.7-10.6-8.7z m0 37.9H642c-5.9 0-10.6 3.9-10.6 8.7 0 4.8 4.8 8.7 10.6 8.7h36.4c5.9 0 10.6-3.9 10.6-8.7 0-4.8-4.7-8.7-10.6-8.7z m0 0"
|
|
||||||
p-id="2471"></path>
|
|
||||||
</svg>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, onMounted } from 'vue';
|
|
||||||
const prop = defineProps({
|
|
||||||
color: '#469DE9'
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
/** .border设置循环旋转动画效果 */
|
|
||||||
.border {
|
|
||||||
animation: rotate 3s linear infinite;
|
|
||||||
transform-origin: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes rotate {
|
|
||||||
0% {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,34 +0,0 @@
|
|||||||
<template>
|
|
||||||
<svg t="1730776964174" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
|
||||||
p-id="7087" width="256" height="256" :fill="prop.color">
|
|
||||||
<path
|
|
||||||
d="M631.466667 230.4l-17.066667-8.533333 17.066667-38.4 17.066666 8.533333c76.8 38.4 140.8 98.133333 179.2 174.933333l8.533334 17.066667-38.4 21.333333-8.533334-17.066666c-34.133333-68.266667-89.6-123.733333-157.866666-157.866667z m17.066666 601.6l-17.066666 8.533333-17.066667-38.4 17.066667-8.533333c68.266667-34.133333 123.733333-89.6 162.133333-157.866667l8.533333-17.066666 38.4 21.333333-8.533333 17.066667c-42.666667 76.8-106.666667 136.533333-183.466667 174.933333zM674.133333 170.666667l-17.066666-8.533334 17.066666-38.4 17.066667 8.533334c85.333333 42.666667 157.866667 110.933333 200.533333 196.266666l8.533334 17.066667-38.4 21.333333-8.533334-17.066666c-38.4-81.066667-102.4-140.8-179.2-179.2z m192 490.666666l38.4 21.333334-8.533333 17.066666c-42.666667 85.333333-115.2 153.6-200.533333 196.266667l-17.066667 8.533333-17.066667-38.4 17.066667-8.533333c76.8-38.4 140.8-98.133333 183.466667-174.933333l4.266666-21.333334zM392.533333 793.6l17.066667 8.533333-17.066667 38.4-17.066666-8.533333c-76.8-38.4-140.8-98.133333-179.2-174.933333l-12.8-17.066667 38.4-21.333333 8.533333 17.066666c38.4 68.266667 93.866667 123.733333 162.133333 157.866667z m0-610.133333l17.066667 38.4-17.066667 8.533333c-68.266667 34.133333-123.733333 89.6-162.133333 157.866667l-8.533333 17.066666-38.4-17.066666 8.533333-17.066667c42.666667-81.066667 106.666667-140.8 183.466667-179.2l17.066666-8.533333zM157.866667 366.933333l-38.4-21.333333 8.533333-17.066667c42.666667-85.333333 115.2-153.6 200.533333-196.266666l17.066667-8.533334 17.066667 38.4-12.8 8.533334c-76.8 38.4-145.066667 98.133333-183.466667 174.933333l-8.533333 21.333333z m192 490.666667l17.066666 8.533333-17.066666 38.4-17.066667-8.533333c-85.333333-42.666667-157.866667-110.933333-200.533333-196.266667l-8.533334-17.066666 38.4-21.333334 8.533334 17.066667c38.4 76.8 102.4 140.8 179.2 179.2zM512 981.333333C251.733333 981.333333 42.666667 772.266667 42.666667 512S251.733333 42.666667 512 42.666667s469.333333 213.333333 469.333333 469.333333-213.333333 469.333333-469.333333 469.333333z m0-981.333333C230.4 0 0 230.4 0 512s230.4 512 512 512 512-230.4 512-512S793.6 0 512 0z m426.666667 512c0 25.6-17.066667 42.666667-42.666667 42.666667s-42.666667-17.066667-42.666667-42.666667 17.066667-42.666667 42.666667-42.666667 42.666667 21.333333 42.666667 42.666667z m-426.666667 85.333333c-46.933333 0-85.333333-38.4-85.333333-85.333333s38.4-85.333333 85.333333-85.333333 85.333333 38.4 85.333333 85.333333-38.4 85.333333-85.333333 85.333333z m0-213.333333c-72.533333 0-128 59.733333-128 128s59.733333 128 128 128 128-59.733333 128-128-59.733333-128-128-128z m0 298.666667c-93.866667 0-170.666667-76.8-170.666667-170.666667s76.8-170.666667 170.666667-170.666667 170.666667 76.8 170.666667 170.666667-76.8 170.666667-170.666667 170.666667z m0-384c-119.466667 0-213.333333 93.866667-213.333333 213.333333s93.866667 213.333333 213.333333 213.333333 213.333333-93.866667 213.333333-213.333333-98.133333-213.333333-213.333333-213.333333z"
|
|
||||||
p-id="7088" class="border"></path>
|
|
||||||
</svg>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, onMounted } from 'vue';
|
|
||||||
const prop = defineProps({
|
|
||||||
color: '#469DE9'
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
/** .border设置循环旋转动画效果 */
|
|
||||||
.border {
|
|
||||||
animation: rotate 3s linear infinite;
|
|
||||||
transform-origin: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes rotate {
|
|
||||||
0% {
|
|
||||||
transform: rotate(0deg) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
@ -1,39 +0,0 @@
|
|||||||
<template>
|
|
||||||
<svg t="1730777460223" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
|
||||||
p-id="1806" width="256" height="256" :fill="prop.color">
|
|
||||||
<path
|
|
||||||
d="M204.8 869.171l29.491-29.491a431.923 431.923 0 0 1-33.382-31.54l-29.082 29.492q15.975 16.589 32.973 31.54z"
|
|
||||||
p-id="1807"></path>
|
|
||||||
<path
|
|
||||||
d="M512 40.96a471.04 471.04 0 0 0-367.206 765.952l29.286-28.672a430.08 430.08 0 1 1 92.16 87.04l-28.672 29.491A471.04 471.04 0 1 0 512 40.96z"
|
|
||||||
p-id="1808" class="border"></path>
|
|
||||||
<path
|
|
||||||
d="M522.24 634.88v-40.96a81.92 81.92 0 0 0 0-163.84v-40.96a122.88 122.88 0 0 1 0 245.76z m-40.96-350.003a20.48 20.48 0 0 0-4.096 0 86.835 86.835 0 0 0-67.584 24.78l-63.488 63.489H276.48a40.96 40.96 0 0 0-40.96 40.96v204.8a40.96 40.96 0 0 0 40.96 40.96h77.005l55.296 55.296a81.92 81.92 0 0 0 67.379 22.118 20.48 20.48 0 0 0 5.12 0 20.48 20.48 0 0 0 20.48-20.48V305.357a20.48 20.48 0 0 0-20.48-20.48zM460.8 697.549a40.96 40.96 0 0 1-23.142-11.264l-66.15-66.15H358.4v-1.23h-81.92v-204.8h27.648l-1.229 1.23h57.959l76.595-76.596A40.96 40.96 0 0 1 460.8 327.68v369.869z m266.24-201.933H768a20.48 20.48 0 0 1 0 40.96h-40.96a20.48 20.48 0 0 1 0-40.96z m-80.691-153.6l29.491-29.082a20.48 20.48 0 0 1 28.877 28.877l-28.877 29.082a20.48 20.48 0 0 1-28.877-28.877z m36.25 311.091l28.876 28.877a20.48 20.48 0 1 1-28.877 28.877l-28.876-28.877a20.48 20.48 0 1 1 28.876-28.877z"
|
|
||||||
p-id="1809"></path>
|
|
||||||
</svg>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, onMounted } from 'vue';
|
|
||||||
const prop = defineProps({
|
|
||||||
color: '#469DE9'
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
/** .border设置循环旋转动画效果 */
|
|
||||||
.border {
|
|
||||||
animation: rotate 3s linear infinite;
|
|
||||||
transform-origin: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes rotate {
|
|
||||||
0% {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,514 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="container">
|
|
||||||
<div class="header">
|
|
||||||
<div class="title">研发中心环境实时监测系统</div>
|
|
||||||
</div>
|
|
||||||
<div class="ct-box">
|
|
||||||
<div class="ct-sensor">
|
|
||||||
<SensorNumLoop :sensorData="item" v-for="(item, index) in sensor_list" :key="index" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="left-content left-right" ref="leftContentRef">
|
|
||||||
<Lr1 :data="avg_temp_humi.four" />
|
|
||||||
<Lr2 :deptId="'113'" />
|
|
||||||
<Lr3 :public_list="noiseDataList.four.public_noise" :office_list="noiseDataList.four.office_noise" />
|
|
||||||
<Lr4 :data="TVOC_CH2O['4f']" />
|
|
||||||
</div>
|
|
||||||
<div class="right-content left-right" ref="rightContentRef">
|
|
||||||
<Lr1 :data="avg_temp_humi.five" />
|
|
||||||
<Lr2 :deptId="'114'" />
|
|
||||||
<Lr3 :public_list="noiseDataList.five.public_noise" :office_list="noiseDataList.five.office_noise" />
|
|
||||||
<Lr4 :data="TVOC_CH2O['5f']" />
|
|
||||||
</div>
|
|
||||||
<div class="bottom-content" ref="bottomContentRef">
|
|
||||||
|
|
||||||
<ZdScrollBoard ref="devList" :config="zd_config" class="zd-scroll-board" />
|
|
||||||
</div>
|
|
||||||
<div class="checkboxlist">
|
|
||||||
<el-radio-group v-model="radioGroup1" :fill="'#105F88'" size="large">
|
|
||||||
<el-radio-button label="四层" value="四层"></el-radio-button>
|
|
||||||
|
|
||||||
<el-radio-button label="五层" value="五层"></el-radio-button>
|
|
||||||
</el-radio-group>
|
|
||||||
</div>
|
|
||||||
<!-- <Sence /> -->
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, reactive, onMounted, computed, watch } from 'vue';
|
|
||||||
import Sence from './component/Sence.vue';
|
|
||||||
import Lr1 from './component/Lr1.vue';
|
|
||||||
import Lr2 from './component/Lr2.vue';
|
|
||||||
import Lr3 from './component/Lr3.vue';
|
|
||||||
import Lr4 from './component/Lr4.vue';
|
|
||||||
import ZdScrollBoard from "@/components/ZdScrollBoard/index.vue";
|
|
||||||
import SensorNumLoop from './component/SensorNumLoop.vue';
|
|
||||||
import useR_D_EnvironmentStore from '@/store/modules/r_d_environment'
|
|
||||||
import { connectWebsocket, closeWebsocket} from "@/utils/websocket";
|
|
||||||
import { getSensorByDept } from '@/api/screen/R_D_Environment';
|
|
||||||
|
|
||||||
|
|
||||||
let R_D_EnvironmentStore = useR_D_EnvironmentStore()
|
|
||||||
let deltaY = ref(0)
|
|
||||||
let avg_temp_humi = computed(() => {
|
|
||||||
return R_D_EnvironmentStore.getLayerData
|
|
||||||
})
|
|
||||||
let noiseDataList = computed(() => {
|
|
||||||
return R_D_EnvironmentStore.getNoiseData
|
|
||||||
})
|
|
||||||
let TVOC_CH2O = reactive({
|
|
||||||
'4f': {
|
|
||||||
ch2o: [],
|
|
||||||
tvoc: []
|
|
||||||
},
|
|
||||||
'5f': {
|
|
||||||
ch2o: [],
|
|
||||||
tvoc: []
|
|
||||||
}
|
|
||||||
})
|
|
||||||
let sensor_list = computed(() => {
|
|
||||||
let sensorData = R_D_EnvironmentStore.sensorData
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
|
|
||||||
component: 'SvgWendu',
|
|
||||||
unit: '℃',
|
|
||||||
type: 'AirTemp_Reg',
|
|
||||||
limit: 40,
|
|
||||||
list: sensorData['temp_humi']?.map(sensor => {
|
|
||||||
return {
|
|
||||||
id: sensor.deviceId,
|
|
||||||
name: sensor.name,
|
|
||||||
value: sensor.temp,
|
|
||||||
status: sensor.status
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
{
|
|
||||||
component: 'SvgShidu',
|
|
||||||
unit: '%RH',
|
|
||||||
type: 'AirHumi_Reg',
|
|
||||||
limit: 90,
|
|
||||||
list: sensorData['temp_humi']?.map(sensor => {
|
|
||||||
return {
|
|
||||||
id: sensor.deviceId,
|
|
||||||
name: sensor.name,
|
|
||||||
value: sensor.humidity,
|
|
||||||
status: sensor.status
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
{
|
|
||||||
component: 'SvgJiaquan',
|
|
||||||
unit: 'mg/m³',
|
|
||||||
type: 'CH2O',
|
|
||||||
limit: 0.08,
|
|
||||||
list: sensorData['TVOC_CH2O']?.filter(sensor => sensor.type === 'CH2O').map(sensor => {
|
|
||||||
return {
|
|
||||||
id: sensor.deviceId,
|
|
||||||
name: sensor.name,
|
|
||||||
value: sensor.data,
|
|
||||||
status: sensor.status
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
{
|
|
||||||
component: 'SvgTVOC',
|
|
||||||
unit: 'mg/m³',
|
|
||||||
type: 'TVOC',
|
|
||||||
limit: 0.5,
|
|
||||||
list: sensorData['TVOC_CH2O']?.filter(sensor => sensor.type === 'TVOC').map(sensor => {
|
|
||||||
return {
|
|
||||||
id: sensor.deviceId,
|
|
||||||
name: sensor.name,
|
|
||||||
value: sensor.data,
|
|
||||||
status: sensor.status
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
{
|
|
||||||
component: 'SvgPm25',
|
|
||||||
unit: 'mg/m³',
|
|
||||||
type: 'HIGH_PM25_Reg',
|
|
||||||
limit: 30,
|
|
||||||
list: sensorData['dust']?.filter(sensor => sensor.type === 'HIGH_PM25_Reg').map(sensor => {
|
|
||||||
return {
|
|
||||||
id: sensor.deviceId,
|
|
||||||
name: sensor.name,
|
|
||||||
value: sensor.data,
|
|
||||||
status: sensor.status
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
{
|
|
||||||
component: 'SvgPm10',
|
|
||||||
unit: 'mg/m³',
|
|
||||||
type: 'HIGH_PM10_Reg',
|
|
||||||
limit: 30,
|
|
||||||
list: sensorData['dust']?.filter(sensor => sensor.type === 'HIGH_PM10_Reg').map(sensor => {
|
|
||||||
return {
|
|
||||||
id: sensor.deviceId,
|
|
||||||
name: sensor.name,
|
|
||||||
value: sensor.data,
|
|
||||||
status: sensor.status
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
{
|
|
||||||
component: 'SvgZaosheng',
|
|
||||||
unit: 'dB',
|
|
||||||
type: 'Noise_Reg',
|
|
||||||
limit: 85,
|
|
||||||
list: sensorData['noise']?.map(sensor => {
|
|
||||||
return {
|
|
||||||
id: sensor.deviceId,
|
|
||||||
name: sensor.name,
|
|
||||||
value: sensor.data,
|
|
||||||
status: sensor.status
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
{
|
|
||||||
component: 'SvgYanwu',
|
|
||||||
unit: 'mg/m³',
|
|
||||||
type: 'Smoke_Reg',
|
|
||||||
limit: 100,
|
|
||||||
list: sensorData['Smoke']?.map(sensor => {
|
|
||||||
return {
|
|
||||||
id: sensor.deviceId,
|
|
||||||
name: sensor.name,
|
|
||||||
value: sensor.data,
|
|
||||||
status: sensor.status
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
const radioGroup1 = ref('四层')
|
|
||||||
let zd_config = ref({
|
|
||||||
header: ['报警时间', '报警内容', '持续时长', '报警设备'],
|
|
||||||
rowNum: 2,
|
|
||||||
headerHeight: 50,
|
|
||||||
headerBGC: 'transparent',
|
|
||||||
oddRowBGC: 'transparent',
|
|
||||||
evenRowBGC: 'transparent',
|
|
||||||
columnWidth: [179, 179, 179, 179],
|
|
||||||
data: [
|
|
||||||
['行1列1', '行1列2', '行1列3', '行1列4'],
|
|
||||||
['行2列1', '行2列2', '行2列3', '行2列4'],
|
|
||||||
['行3列1', '行3列2', '行3列3', '行3列4'],
|
|
||||||
['行4列1', '行4列2', '行4列3', '行4列4'],
|
|
||||||
]
|
|
||||||
})
|
|
||||||
function reqSensorByDept() {
|
|
||||||
getSensorByDept('113,114').then(res => {
|
|
||||||
if (res.code === 200) {
|
|
||||||
let sensorData = res.data
|
|
||||||
let temp_humi = sensorData.temp_humi
|
|
||||||
let TVOC_CH2O = sensorData.TVOC_CH2O
|
|
||||||
let temp = []
|
|
||||||
temp_humi.map(item => {
|
|
||||||
let index = temp.find(item2 => { return item2.deviceId == item.deviceId })
|
|
||||||
if (!index) {
|
|
||||||
if (item.type === 'AirHumi_Reg') {
|
|
||||||
temp.push({
|
|
||||||
deviceId: item.deviceId,
|
|
||||||
humidity: item.data,
|
|
||||||
name: item.name,
|
|
||||||
label: item.label,
|
|
||||||
temp: '',
|
|
||||||
deptId: item.deptId,
|
|
||||||
deptName: item.deptName,
|
|
||||||
status: item.status
|
|
||||||
})
|
|
||||||
|
|
||||||
} else if (item.type === 'AirTemp_Reg') {
|
|
||||||
temp.push({
|
|
||||||
deviceId: item.deviceId,
|
|
||||||
humidity: '',
|
|
||||||
name: item.name,
|
|
||||||
label: item.label,
|
|
||||||
temp: item.data,
|
|
||||||
deptId: item.deptId,
|
|
||||||
deptName: item.deptName,
|
|
||||||
status: item.status
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (item.type === 'AirHumi_Reg') {
|
|
||||||
index.humidity = item.data
|
|
||||||
} else if (item.type === 'AirTemp_Reg') {
|
|
||||||
index.temp = item.data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
let now = +new Date()
|
|
||||||
TVOC_CH2O.map(item => {
|
|
||||||
if (item.deptId == '113') {
|
|
||||||
if (item.type === 'CH2O') {
|
|
||||||
TVOC_CH2O['4f'].ch2o.push([now,item.data])
|
|
||||||
} else if (item.type === 'TVOC') {
|
|
||||||
TVOC_CH2O['4f'].tvoc.push([now,item.data])
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if(item.deptId == '114') {
|
|
||||||
if (item.type === 'CH2O') {
|
|
||||||
TVOC_CH2O['5f'].ch2o.push([now,item.data])
|
|
||||||
} else if (item.type === 'TVOC') {
|
|
||||||
TVOC_CH2O['5f'].tvoc.push([now,item.data])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
sensorData.temp_humi = temp
|
|
||||||
R_D_EnvironmentStore.sensorData = sensorData
|
|
||||||
// noiseDataList.value = res.data
|
|
||||||
// public_noise.value = noiseDataList.value.find(item => item.devName === '公共区域')
|
|
||||||
// office_noise.value = noiseDataList.value.filter(item => item.devName !== '公共区域')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//socket
|
|
||||||
function getWebsocket(val) {
|
|
||||||
try {
|
|
||||||
let data = JSON.parse(val);
|
|
||||||
|
|
||||||
if (data.type == "HUMI_TEMP") {
|
|
||||||
let obj = data.msg;
|
|
||||||
if (obj.hasOwnProperty('temp')) {
|
|
||||||
let index = sensor_list.findIndex(sensor => sensor.type === 'AirTemp_Reg' && sensor.id === obj.temp.devId)
|
|
||||||
if (index !== -1) {
|
|
||||||
sensor_list[index].value = obj.temp.value
|
|
||||||
sensor_list[index].status = "true"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if (obj.hasOwnProperty('humi')) {
|
|
||||||
let index = sensor_list.findIndex(sensor => sensor.type === 'AirHumi_Reg' && sensor.id === obj.humi.devId)
|
|
||||||
if (index !== -1) {
|
|
||||||
sensor_list[index].value = obj.humi.value
|
|
||||||
sensor_list[index].status = "true"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (data.type == "TVOC_CH2O") {
|
|
||||||
let obj = data.msg;
|
|
||||||
if (obj.hasOwnProperty('CH2O')) {
|
|
||||||
let index = sensor_list.findIndex(sensor => sensor.type === 'CH2O' && sensor.id === obj.CH2O.devId)
|
|
||||||
if (index !== -1) {
|
|
||||||
sensor_list[index].value = obj.CH2O.value
|
|
||||||
sensor_list[index].status = "true"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if (obj.hasOwnProperty('TVOC')) {
|
|
||||||
let index = sensor_list.findIndex(sensor => sensor.type === 'TVOC' && sensor.id === obj.TVOC.devId)
|
|
||||||
if (index !== -1) {
|
|
||||||
sensor_list[index].value = obj.TVOC.value
|
|
||||||
sensor_list[index].status = "true"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//粉尘
|
|
||||||
if (data.type == "dust") {
|
|
||||||
let obj = data.msg;
|
|
||||||
|
|
||||||
|
|
||||||
let index_pm25 = sensor_list.findIndex(sensor => sensor.type === 'HIGH_PM25_Reg' && sensor.id === obj.devId)
|
|
||||||
let index_pm10 = sensor_list.findIndex(sensor => sensor.type === 'HIGH_PM10_Reg' && sensor.id === obj.devId)
|
|
||||||
if (index_pm25 !== -1) {
|
|
||||||
sensor_list[index_pm25].value = obj.pm25
|
|
||||||
sensor_list[index_pm25].status = "true"
|
|
||||||
dustData.pm25 = obj.pm25
|
|
||||||
}
|
|
||||||
if (index_pm10 !== -1) {
|
|
||||||
sensor_list[index_pm10].value = obj.pm10
|
|
||||||
sensor_list[index_pm10].status = "true"
|
|
||||||
dustData.pm10 = obj.pm10
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//噪音
|
|
||||||
if (data.type === "NOISE") {
|
|
||||||
let obj = data.msg;
|
|
||||||
let list_index = noiseDataList.value.findIndex(item => item.devId === obj.noise.devId)
|
|
||||||
if (list_index !== -1) {
|
|
||||||
noiseDataList.value[list_index].data = obj.noise.value
|
|
||||||
} else {
|
|
||||||
let index = sensor_list.findIndex(sensor => sensor.type === 'Noise_Reg' && sensor.id === obj.noise.devId)
|
|
||||||
if (index !== -1) {
|
|
||||||
sensor_list[index].value = obj.noise.value
|
|
||||||
sensor_list[index].status = "true"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.log(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function errWebsocket(val) {
|
|
||||||
// console.log(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
reqSensorByDept()
|
|
||||||
window.addEventListener('wheel', function (event) {
|
|
||||||
deltaY.value += event.deltaY
|
|
||||||
if (deltaY.value <= -500 && deltaY.value >= -1000) {
|
|
||||||
this.document.querySelector('.ct-box').style.transform = 'translateY(-200%) translateX(-50%)'
|
|
||||||
this.document.querySelector('.left-content').style.transform = 'translateX(-100%)'
|
|
||||||
this.document.querySelector('.right-content').style.transform = 'translateX(100%)'
|
|
||||||
this.document.querySelector('.bottom-content').style.transform = 'translateY(100%)'
|
|
||||||
}
|
|
||||||
if (deltaY.value > -500 && deltaY.value < 0) {
|
|
||||||
this.document.querySelector('.ct-box').style.transform = 'translateY(0) translateX(-50%)'
|
|
||||||
this.document.querySelector('.left-content').style.transform = 'translateX(0)'
|
|
||||||
this.document.querySelector('.right-content').style.transform = 'translateX(0)'
|
|
||||||
this.document.querySelector('.bottom-content').style.transform = 'translateY(0)'
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (deltaY.value >= 0) {
|
|
||||||
// deltaY.value = 0
|
|
||||||
// }
|
|
||||||
}, { passive: false });
|
|
||||||
//connectWebsocket('','',getWebsocket, errWebsocket)
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.container {
|
|
||||||
width: 1920px;
|
|
||||||
height: 1080px;
|
|
||||||
position: relative;
|
|
||||||
// display: flex;
|
|
||||||
// justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
// background-image: url('/src/assets/images/gif-bg.gif');
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
/* 如果你不想让背景平铺 */
|
|
||||||
background-size: cover;
|
|
||||||
/* 或者其他你需要的大小设置 */
|
|
||||||
background-position: center;
|
|
||||||
|
|
||||||
.header {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 72px;
|
|
||||||
background-image: url('./image/u796.png');
|
|
||||||
z-index: 2;
|
|
||||||
|
|
||||||
.title {
|
|
||||||
width: 100%;
|
|
||||||
height: 72px;
|
|
||||||
font-size: 36px;
|
|
||||||
color: #2affff;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 60px;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.ct-box {
|
|
||||||
position: absolute;
|
|
||||||
top: 100px;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
width: 825px;
|
|
||||||
height: 180px;
|
|
||||||
display: flex;
|
|
||||||
z-index: 2;
|
|
||||||
justify-content: space-between;
|
|
||||||
transition: transform 1s;
|
|
||||||
|
|
||||||
.ct-sensor {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.left-content {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 557px;
|
|
||||||
height: 1080px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding-top: 72px;
|
|
||||||
background-image: url('./image/u801.png'), url('./image/u797.png');
|
|
||||||
background-position: center, 0% 78%;
|
|
||||||
background-repeat: no-repeat, no-repeat;
|
|
||||||
padding-left: 30px;
|
|
||||||
transition: transform 1s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left-right {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding-bottom: 30px;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-content {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
width: 557px;
|
|
||||||
height: 1080px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding-top: 72px;
|
|
||||||
background-image: url('./image/u800.png'), url('./image/u798.png');
|
|
||||||
background-position: center, 100% 78%;
|
|
||||||
background-repeat: no-repeat, no-repeat;
|
|
||||||
padding-right: 30px;
|
|
||||||
transition: transform 1s;
|
|
||||||
align-items: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom-content {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 1920px;
|
|
||||||
height: 184px;
|
|
||||||
background-image: url('./image/u799.png'), url('./image/u802.png');
|
|
||||||
background-position: bottom, 50% 100%;
|
|
||||||
background-repeat: no-repeat, no-repeat;
|
|
||||||
transition: transform 1s;
|
|
||||||
|
|
||||||
.zd-scroll-board {
|
|
||||||
width: 716px;
|
|
||||||
height: 120px, ;
|
|
||||||
position: absolute;
|
|
||||||
top: 28px;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.checkboxlist {
|
|
||||||
position: absolute;
|
|
||||||
top: 2px;
|
|
||||||
right: 60px;
|
|
||||||
z-index: 999;
|
|
||||||
|
|
||||||
:deep(.el-checkbox-button__inner) {
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
65
src/views/screen/devItem/component/Progress.vue
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<template>
|
||||||
|
<div class="progress-container">
|
||||||
|
<div class="text-label">
|
||||||
|
<div class="label-left">{{ prop.mdoelValue1.date }}</div>
|
||||||
|
<div class="label-right"><i class="value">{{ prop.mdoelValue1.rate }}</i> %</div>
|
||||||
|
</div>
|
||||||
|
<div class="progress">
|
||||||
|
<el-progress :percentage="percentage" stroke-width="8" :color="checkCb(prop.mdoelValue1)" :show-text="false"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref,computed } from 'vue';
|
||||||
|
|
||||||
|
const prop = defineProps({
|
||||||
|
mdoelValue1:{
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {
|
||||||
|
date: '',
|
||||||
|
rate: 10,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
const percentage = computed(() => {
|
||||||
|
console.log(prop.mdoelValue1.data);
|
||||||
|
|
||||||
|
return prop.mdoelValue1.rate > 100 ? 100 : prop.mdoelValue1.rate;
|
||||||
|
})
|
||||||
|
|
||||||
|
//检测是否超标
|
||||||
|
function checkCb(item) {
|
||||||
|
if (item.data > 85) {
|
||||||
|
return '#FF0000'
|
||||||
|
} else {
|
||||||
|
return '#469DE9'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.progress-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
.text-label {
|
||||||
|
width: 100%;
|
||||||
|
height: 30px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #2affff;
|
||||||
|
box-sizing: border-box;
|
||||||
|
.label-right {
|
||||||
|
.value {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
42
src/views/screen/devItem/component/card.vue
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<template>
|
||||||
|
<div class="item-container">
|
||||||
|
<div class="box-title" >{{ prop.title }}</div>
|
||||||
|
<div class="content">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
|
||||||
|
const prop = defineProps({
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: '标题'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.item-container {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
.box-title {
|
||||||
|
width: 100%;
|
||||||
|
height: 53px;
|
||||||
|
background: url('../image/u17.png') no-repeat;
|
||||||
|
background-size: auto 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding-left: 32px;
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 53px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - 53px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
108
src/views/screen/devItem/component/lineChart.vue
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
<template>
|
||||||
|
<v-chart :option="options" theme="dark" style="width: 100%;height: 100%;" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue';
|
||||||
|
const prop = defineProps({
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {
|
||||||
|
xAxis: [],
|
||||||
|
series: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const options = computed(() => {
|
||||||
|
return {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
||||||
|
borderColor: '#00c6ff',
|
||||||
|
borderWidth: 2,
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: 14
|
||||||
|
},
|
||||||
|
formatter: function (params) {
|
||||||
|
let tooltipText = '';
|
||||||
|
let xAxisValue = params[0].name;
|
||||||
|
params.forEach((item) => {
|
||||||
|
tooltipText += `<div style="padding: 2px 0;"><strong>${item.seriesName}:</strong> ${item.value}%</div>`;
|
||||||
|
});
|
||||||
|
return `${xAxisValue}<br>${tooltipText}`;
|
||||||
|
},
|
||||||
|
padding: 10,
|
||||||
|
extraCssText: 'border-radius: 8px; box-shadow: 0 0 15px rgba(0, 0, 0, 0.5);'
|
||||||
|
},
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
// legend: {
|
||||||
|
// data: ['上月', '本月'],
|
||||||
|
// right: 'left',
|
||||||
|
// textStyle: {
|
||||||
|
// color: '#ffff'
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
grid: {
|
||||||
|
left: '10%',
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: prop.data.xAxis,
|
||||||
|
axisLabel: {
|
||||||
|
color: "#ffffff",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
max: 100,
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
type: 'dashed',
|
||||||
|
color: '#3c3a4a85',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
color: "#ffffff",
|
||||||
|
formatter: function (value) {
|
||||||
|
return `${value} %`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
series: [{
|
||||||
|
name: '利用率',
|
||||||
|
data: prop.data.series,
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
itemStyle: {
|
||||||
|
color: 'rgb(150 ,162 ,116)',
|
||||||
|
},
|
||||||
|
lineStyle: {
|
||||||
|
width: 2,
|
||||||
|
},
|
||||||
|
areaStyle: {
|
||||||
|
color: {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
x2: 0,
|
||||||
|
y2: 1,
|
||||||
|
colorStops: [{
|
||||||
|
offset: 0,
|
||||||
|
color: 'rgb(150 ,162 ,116 ,0.6)'
|
||||||
|
}, {
|
||||||
|
offset: 1,
|
||||||
|
color: 'rgb(150 ,162 ,116 ,0.2)'
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
70
src/views/screen/devItem/component/stackBarChart.vue
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<template>
|
||||||
|
<v-chart :option="options" theme="dark" style="width: 100%;height: 100%;" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed, ref } from 'vue';
|
||||||
|
const prop = defineProps({
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {
|
||||||
|
xAxis: [],
|
||||||
|
series: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const options = computed(() => {
|
||||||
|
return {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
axisPointer: {
|
||||||
|
// Use axis to trigger tooltip
|
||||||
|
type: 'shadow' // 'shadow' as default; can also be 'line' or 'shadow'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
legend: {},
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
grid: {
|
||||||
|
left: '3%',
|
||||||
|
right: '4%',
|
||||||
|
bottom: '3%',
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: prop.data.xAxis,
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
name: 'min',
|
||||||
|
type: 'value',
|
||||||
|
axisLabel: {
|
||||||
|
color: '#fff',
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
series: prop.data.series.map((item, index) => {
|
||||||
|
return {
|
||||||
|
name: item.name,
|
||||||
|
type: 'bar',
|
||||||
|
stack: 'total',
|
||||||
|
barWidth: '30%',
|
||||||
|
label: {
|
||||||
|
show: true
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
focus: 'series'
|
||||||
|
},
|
||||||
|
data: item.data
|
||||||
|
};
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
BIN
src/views/screen/devItem/image/center-bg.png
Normal file
After Width: | Height: | Size: 942 KiB |
BIN
src/views/screen/devItem/image/u156.png
Normal file
After Width: | Height: | Size: 642 B |
BIN
src/views/screen/devItem/image/u157.png
Normal file
After Width: | Height: | Size: 584 B |
BIN
src/views/screen/devItem/image/u158.png
Normal file
After Width: | Height: | Size: 7.5 KiB |
BIN
src/views/screen/devItem/image/u17.png
Normal file
After Width: | Height: | Size: 49 KiB |
BIN
src/views/screen/devItem/image/u83.png
Normal file
After Width: | Height: | Size: 611 B |
500
src/views/screen/devItem/index.vue
Normal file
@ -0,0 +1,500 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<div class="header">
|
||||||
|
<div class="title">微工厂设备详情</div>
|
||||||
|
<svg-icon icon-class="back" class="back_icon" @click="handleBack"/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<div class="left-plane">
|
||||||
|
<div class="lt-plane">
|
||||||
|
<div class="ltl-plane">
|
||||||
|
<Card class="ltl-item1" title="设备详情">
|
||||||
|
<div class="ltl-content">
|
||||||
|
<div class="ltl-box">
|
||||||
|
<div class="ltl-item-box">
|
||||||
|
<div class="label">名称:</div>
|
||||||
|
<div class="value">{{ deviceInfo.name }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ltl-box">
|
||||||
|
<div class="ltl-item-box">
|
||||||
|
<div class="label">编号:</div>
|
||||||
|
<div class="value">{{ deviceInfo.code }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ltl-box">
|
||||||
|
<div class="ltl-item-box">
|
||||||
|
<div class="label">负责人:</div>
|
||||||
|
<div class="value">{{ deviceInfo.director }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ltl-box">
|
||||||
|
<div class="ltl-item-box">
|
||||||
|
<div class="label">所在位置:</div>
|
||||||
|
<div class="value">{{ deviceInfo.deviceLocation }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</Card>
|
||||||
|
<Card class="ltl-item2" title="设备利用率">
|
||||||
|
<div style="width: 100%;height: 100%;display: flex;flex-direction: column;justify-content: space-around;align-items: center;">
|
||||||
|
<Progress :mdoelValue1="item" v-for="item in deviceRateChartData"></Progress>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
<div class="ltr-plane">
|
||||||
|
<div class="tip-type">
|
||||||
|
<div class="tip-type-item">
|
||||||
|
<svg-icon icon-class="run" class="el-input__icon" style="width: 26px;height: 26px;" />
|
||||||
|
<div class="tip-type-item-text">工作</div>
|
||||||
|
</div>
|
||||||
|
<div class="tip-type-item">
|
||||||
|
<svg-icon icon-class="wait" class="el-input__icon" style="width: 26px;height: 26px;" />
|
||||||
|
<div class="tip-type-item-text">待机</div>
|
||||||
|
</div>
|
||||||
|
<div class="tip-type-item">
|
||||||
|
<svg-icon icon-class="stop" class="el-input__icon" style="width: 26px;height: 26px;" />
|
||||||
|
<div class="tip-type-item-text">停机</div>
|
||||||
|
</div>
|
||||||
|
<div class="tip-type-item">
|
||||||
|
<svg-icon icon-class="repair" class="el-input__icon"
|
||||||
|
style="width: 26px;height: 26px;" />
|
||||||
|
<div class="tip-type-item-text">维修</div>
|
||||||
|
</div>
|
||||||
|
<div class="tip-type-item">
|
||||||
|
<svg-icon icon-class="alarm" class="el-input__icon" style="width: 26px;height: 26px;" />
|
||||||
|
<div class="tip-type-item-text">故障</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="c-item c-top">
|
||||||
|
<div class="item-box">当前状态:
|
||||||
|
<svg-icon v-if="devStatus.state == 0" icon-class="stop"
|
||||||
|
class="el-input__icon input-icon" />
|
||||||
|
<svg-icon v-else-if="devStatus.state == 1" icon-class="wait"
|
||||||
|
class="el-input__icon input-icon" />
|
||||||
|
<svg-icon v-else-if="devStatus.state == 2" icon-class="run"
|
||||||
|
class="el-input__icon input-icon" />
|
||||||
|
<svg-icon v-else-if="devStatus.state == 4" icon-class="alarm"
|
||||||
|
class="el-input__icon input-icon" />
|
||||||
|
</div>
|
||||||
|
<div class="item-box">运行时长:{{ devStatus.runTime }}min</div>
|
||||||
|
</div>
|
||||||
|
<div class="c-item c-center">
|
||||||
|
<div class="item-box">停机时长:{{ devStatus.stopTime }}min</div>
|
||||||
|
<el-image :src="baseUrl + deviceInfo.file"
|
||||||
|
style="height: 100%;position: relative;top: -30px;" />
|
||||||
|
<div class="item-box">工作时长:{{ devStatus.workTime }}min</div>
|
||||||
|
</div>
|
||||||
|
<div class="c-item c-bottom">
|
||||||
|
<div class="item-box">故障时长:{{ devStatus.faultTime }}min</div>
|
||||||
|
<div class="item-box">待机时长:{{ devStatus.waitTime }}min</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Card class="lb-plane" title="设备状态分析">
|
||||||
|
<StackBarChart :data="deviceStatusChartData"></StackBarChart>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="right-plane">
|
||||||
|
|
||||||
|
<Card class="right-item1" title="设备维修记录">
|
||||||
|
<el-table :data="repairData" v-if="repairData.length > 0" v-tableAutoScroll="{ delay: 15 }"
|
||||||
|
header-row-class-name="table_header" style="width: 100%;height: 100%;">
|
||||||
|
<el-table-column prop="devCode" label="编码" width="90" />
|
||||||
|
<el-table-column prop="name" label="设备名称" />
|
||||||
|
<el-table-column prop="subject" label="报警内容" />
|
||||||
|
<el-table-column prop="person" label="负责人" />
|
||||||
|
<el-table-column prop="time" label="报警时间" />
|
||||||
|
</el-table>
|
||||||
|
<el-empty v-else description="暂无记录" />
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card class="right-item2" title="设备保养记录">
|
||||||
|
<el-table :data="remindData" v-if="remindData.length > 0" v-tableAutoScroll="{ delay: 15 }"
|
||||||
|
header-row-class-name="table_header" style="width: 100%;height: 100%;">
|
||||||
|
<el-table-column prop="devCode" label="编码" width="90" />
|
||||||
|
<el-table-column prop="name" label="设备名称" />
|
||||||
|
<el-table-column prop="subject" label="保养内容" />
|
||||||
|
<el-table-column prop="person" label="负责人" />
|
||||||
|
<el-table-column prop="time" label="保养时间" />
|
||||||
|
</el-table>
|
||||||
|
<el-empty v-else description="暂无记录" />
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card class="right-item3" title="设备用电量分析">
|
||||||
|
<LineChart :data="deviceElectChartData"></LineChart>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import 'element-plus/theme-chalk/dark/css-vars.css'
|
||||||
|
import { onMounted, ref } from 'vue';
|
||||||
|
import Card from './component/card.vue';
|
||||||
|
import StackBarChart from './component/stackBarChart.vue';
|
||||||
|
import Progress from './component/Progress.vue';
|
||||||
|
import LineChart from './component/lineChart.vue';
|
||||||
|
import { useRoute,useRouter } from 'vue-router';
|
||||||
|
import { connectWebsocket, closeWebsocket} from "@/utils/websocket";
|
||||||
|
import { listDevice, deviceCheck, deviceRepair, deviceStatusById, deviceStatusChart,deviceRateChart,deviceElectChart } from '@/api/screen/micro'
|
||||||
|
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
let id = ref(0)
|
||||||
|
|
||||||
|
const baseUrl = import.meta.env.VITE_APP_BASE_API;
|
||||||
|
let deviceInfo = ref({})
|
||||||
|
//获取设备列表
|
||||||
|
function getListDevice() {
|
||||||
|
listDevice(id.value).then(res => {
|
||||||
|
deviceInfo.value = res.data
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let remindData = ref([])
|
||||||
|
//获取保养记录
|
||||||
|
const getDeviceCheck = async () => {
|
||||||
|
const res = await deviceCheck(id.value);
|
||||||
|
remindData.value = res.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
let repairData = ref([])
|
||||||
|
//获取维修记录
|
||||||
|
const getDeviceRepair = async () => {
|
||||||
|
const res = await deviceRepair(id.value);
|
||||||
|
repairData.value = res.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
let devStatus = ref({
|
||||||
|
"deviceCode": null,
|
||||||
|
"onlineTime": null,
|
||||||
|
"realTime": null,
|
||||||
|
"deviceId": null,
|
||||||
|
"workTime": null,
|
||||||
|
"runTime": null,
|
||||||
|
"waitTime": null,
|
||||||
|
"stopTime": null,
|
||||||
|
"faultTime": null,
|
||||||
|
"ts": null,
|
||||||
|
"state": null,
|
||||||
|
})
|
||||||
|
//单设备运行状态
|
||||||
|
const getDeviceStatus = async () => {
|
||||||
|
const res = await deviceStatusById(id.value);
|
||||||
|
devStatus.value = res.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
let deviceStatusChartData = reactive({
|
||||||
|
xAxis: [],
|
||||||
|
series: []
|
||||||
|
})
|
||||||
|
//设备状态图表
|
||||||
|
const getDeviceStatusChart = async () => {
|
||||||
|
const res = await deviceStatusChart(id.value);
|
||||||
|
deviceStatusChartData.xAxis = res.data.dates;
|
||||||
|
deviceStatusChartData.series.push({
|
||||||
|
name: '工作',
|
||||||
|
data: res.data.work
|
||||||
|
})
|
||||||
|
deviceStatusChartData.series.push({
|
||||||
|
name: '待机',
|
||||||
|
data: res.data.wait
|
||||||
|
})
|
||||||
|
deviceStatusChartData.series.push({
|
||||||
|
name: '停机',
|
||||||
|
data: res.data.stop
|
||||||
|
})
|
||||||
|
deviceStatusChartData.series.push({
|
||||||
|
name: '故障',
|
||||||
|
data: res.data.fault
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//设备利用率
|
||||||
|
let deviceRateChartData = ref([])
|
||||||
|
const getDeviceRateChart = async () => {
|
||||||
|
const res = await deviceRateChart(id.value);
|
||||||
|
deviceRateChartData.value = res.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
//单设备用电量图表
|
||||||
|
let deviceElectChartData = reactive({
|
||||||
|
xAxis: [],
|
||||||
|
series: []
|
||||||
|
})
|
||||||
|
function getdeviceElectChart() {
|
||||||
|
deviceElectChart(id.value).then(res => {
|
||||||
|
deviceElectChartData.xAxis = res.data.dates;
|
||||||
|
deviceElectChartData.series = res.data.elects;
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//返回
|
||||||
|
function handleBack() {
|
||||||
|
router.go(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//socket
|
||||||
|
function getWebsocket(val) {
|
||||||
|
try {
|
||||||
|
let data = JSON.parse(val);
|
||||||
|
|
||||||
|
if (data.type == "status" && data.msg.id == id.value) {
|
||||||
|
let obj = data.msg;
|
||||||
|
devStatus.state = obj.status;
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function errWebsocket(val) {
|
||||||
|
// headerref.value.HeadererrWebsocket(val)
|
||||||
|
// console.log(val);
|
||||||
|
}
|
||||||
|
onMounted(() => {
|
||||||
|
id.value = route.params.id;
|
||||||
|
getDeviceCheck();
|
||||||
|
getDeviceRepair();
|
||||||
|
getListDevice()
|
||||||
|
getDeviceStatus()
|
||||||
|
getDeviceStatusChart()
|
||||||
|
getDeviceRateChart()
|
||||||
|
getdeviceElectChart()
|
||||||
|
connectWebsocket('','',getWebsocket, errWebsocket)
|
||||||
|
});
|
||||||
|
onUnmounted(() => {
|
||||||
|
closeWebsocket()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
::v-deep(.table_header th) {
|
||||||
|
background-color: transparent !important;
|
||||||
|
color: #21dadb;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.back_icon {
|
||||||
|
position: absolute;
|
||||||
|
top: 40px;
|
||||||
|
left: 20px;
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
color: #f9f8f4;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
width: 1920px;
|
||||||
|
height: 1080px;
|
||||||
|
position: relative;
|
||||||
|
// display: flex;
|
||||||
|
// justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background-image: url('/src/assets/images/screen-bg.png');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
/* 如果你不想让背景平铺 */
|
||||||
|
background-size: cover;
|
||||||
|
/* 或者其他你需要的大小设置 */
|
||||||
|
background-position: center;
|
||||||
|
|
||||||
|
.header {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 89px;
|
||||||
|
background-image: url('/src/assets/images/screen-header-bg1.png');
|
||||||
|
background-size: 100% 100%;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
width: 100%;
|
||||||
|
height: 89px;
|
||||||
|
font-size: 36px;
|
||||||
|
color: #f9f8f4;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 89px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
width: 100%;
|
||||||
|
height: 975px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 20px 0;
|
||||||
|
|
||||||
|
.right-plane {
|
||||||
|
width: 488px;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.right-item1 {
|
||||||
|
width: 100%;
|
||||||
|
height: 280px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-item2 {
|
||||||
|
width: 100%;
|
||||||
|
height: 280px;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-item3 {
|
||||||
|
width: 100%;
|
||||||
|
height: 395px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-plane {
|
||||||
|
width: 1400px;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.lt-plane {
|
||||||
|
width: 100%;
|
||||||
|
height: 635px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.ltl-plane {
|
||||||
|
width: 488px;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.ltl-item1 {
|
||||||
|
width: 100%;
|
||||||
|
height: 260px;
|
||||||
|
|
||||||
|
.ltl-content {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
.ltl-box {
|
||||||
|
width: 48%;
|
||||||
|
height: 50%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.ltl-item-box {
|
||||||
|
height: 60px;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background-color: rgba(2, 48, 87, 0.5);
|
||||||
|
border: #2A80B8 2px solid;
|
||||||
|
padding: 0 10px;
|
||||||
|
color: #f9f8f4;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 500;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.label {
|
||||||
|
width: 50%;
|
||||||
|
text-wrap: nowrap;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.ltl-item2 {
|
||||||
|
width: 100%;
|
||||||
|
height: 360px;
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ltr-plane {
|
||||||
|
position: relative;
|
||||||
|
width: 892px;
|
||||||
|
height: 100%;
|
||||||
|
background: url('./image/center-bg.png') no-repeat;
|
||||||
|
background-size: 38% auto;
|
||||||
|
background-position: 50% 70%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.tip-type {
|
||||||
|
position: absolute;
|
||||||
|
top: -15px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: 260px;
|
||||||
|
height: 50px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 700;
|
||||||
|
|
||||||
|
.tip-type-item {
|
||||||
|
width: 33%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-top,
|
||||||
|
.c-bottom {
|
||||||
|
width: 70%;
|
||||||
|
height: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-center {
|
||||||
|
width: 85%;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.item-box {
|
||||||
|
background-color: rgba(2, 48, 87, 0.5);
|
||||||
|
border: #2A80B8 2px solid;
|
||||||
|
padding: 15px;
|
||||||
|
color: #f9f8f4;
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: 500;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.lb-plane {
|
||||||
|
width: 100%;
|
||||||
|
height: 340px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
101
src/views/screen/microFactory/component/barChart.vue
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
<template>
|
||||||
|
<v-chart :option="options" theme="dark" style="width: 100%;height: 100%;" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue';
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
const prop = defineProps({
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {
|
||||||
|
name: [],
|
||||||
|
value: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const options = computed(() => {
|
||||||
|
return {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis'
|
||||||
|
},
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
legend: {
|
||||||
|
data: ['目标产量', '实际产量'],
|
||||||
|
textStyle: {
|
||||||
|
color: "#FFF",
|
||||||
|
fontSize: 10
|
||||||
|
},
|
||||||
|
},
|
||||||
|
toolbox: {
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
calculable: true,
|
||||||
|
xAxis: [{
|
||||||
|
type: 'category',
|
||||||
|
data: ['W01', 'W02', 'W03', 'w04', 'W05', 'W06', 'W07', 'W08'],
|
||||||
|
axisLabel: {
|
||||||
|
color: '#fff'
|
||||||
|
},
|
||||||
|
},],
|
||||||
|
yAxis: [{
|
||||||
|
type: 'value',
|
||||||
|
axisLabel: {
|
||||||
|
color: '#fff'
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
series: [{
|
||||||
|
name: '目标产量',
|
||||||
|
type: 'bar',
|
||||||
|
data: [20, 15, 30, 25, 18, 35, 20, 15],
|
||||||
|
barWidth: '20%',
|
||||||
|
itemStyle: {
|
||||||
|
borderRadius: [2, 2, 0, 0],
|
||||||
|
color:
|
||||||
|
{
|
||||||
|
type: 'linear',
|
||||||
|
x: 0,
|
||||||
|
y: 1,
|
||||||
|
x2: 0,
|
||||||
|
y2: 0,
|
||||||
|
colorStops: [{
|
||||||
|
offset: 0, color: 'rgba(84,194,238,0.1)' // 0% 处的颜色
|
||||||
|
}, {
|
||||||
|
offset: 1, color: 'rgb(84,194,238)' // 100% 处的颜色
|
||||||
|
}],
|
||||||
|
global: false // 缺省为 false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
name: '实际产量',
|
||||||
|
type: 'bar',
|
||||||
|
data: [9, 15, 28, 15, 15, 25, 20, 10],
|
||||||
|
barWidth: '20%',
|
||||||
|
itemStyle: {
|
||||||
|
borderRadius: [2, 2, 0, 0],
|
||||||
|
color: {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0,
|
||||||
|
y: 1,
|
||||||
|
x2: 0,
|
||||||
|
y2: 0,
|
||||||
|
colorStops: [{
|
||||||
|
offset: 0, color: 'rgba(181,202,159,0.1)' // 0% 处的颜色
|
||||||
|
}, {
|
||||||
|
offset: 1, color: 'rgb(181,202,159)' // 100% 处的颜色
|
||||||
|
}],
|
||||||
|
global: false // 缺省为 false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
42
src/views/screen/microFactory/component/card.vue
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<template>
|
||||||
|
<div class="item-container">
|
||||||
|
<div class="box-title" >{{ prop.title }}</div>
|
||||||
|
<div class="content">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
|
||||||
|
const prop = defineProps({
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: '标题'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.item-container {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
.box-title {
|
||||||
|
width: 100%;
|
||||||
|
height: 53px;
|
||||||
|
background: url('../image/u17.png') no-repeat;
|
||||||
|
background-size: auto 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding-left: 32px;
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 53px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - 53px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
42
src/views/screen/microFactory/component/centerCard.vue
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<template>
|
||||||
|
<div class="item-container">
|
||||||
|
<div class="box-title" >{{ prop.title }}</div>
|
||||||
|
<div class="content">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
|
||||||
|
const prop = defineProps({
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: '标题'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.item-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
.box-title {
|
||||||
|
width: 100%;
|
||||||
|
height: 53px;
|
||||||
|
background: url('../image/u36.png') no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding-left: 32px;
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 53px;
|
||||||
|
text-align: center;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - 53px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
32
src/views/screen/microFactory/component/devStatus.vue
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<template>
|
||||||
|
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" version="1.1" width="20px" height="20px">
|
||||||
|
<g transform="matrix(1 0 0 1 -436 -253 )">
|
||||||
|
<path d="M 6.15 6.22 C 7.15 5.24325581395349 8.57 4.69627906976744 10 4.69627906976744 C 11.43 4.69627906976744 12.86 5.25302325581395 13.86 6.22976744186046 C 14.86 7.20651162790698 15.43 8.46651162790698 15.43 9.85348837209303 C 15.43 11.2404651162791 14.86 12.5004651162791 13.86 13.4772093023256 C 11.72 15.5674418604651 8.29 15.5674418604651 6.15 13.6139534883721 C 5.15 12.6372093023256 4.58 11.2404651162791 4.58 9.84372093023256 C 4.58 8.44697674418605 5.15 7.19674418604651 6.15 6.22 Z M 11.43 1.2093023255814 L 11.29 1.2093023255814 C 14.43 1.6293023255814 17 3.71953488372093 18.29 6.51302325581395 C 18.58 7.20651162790698 18.86 7.90976744186047 19 8.60325581395349 L 20 8.60325581395349 C 19.43 4.27627906976744 15.86 0.789302325581395 11.43 0.232558139534884 L 11.43 1.2093023255814 Z M 0 8.60325581395349 L 1 8.60325581395349 C 1.14 7.90976744186047 1.29 7.20651162790698 1.57 6.51302325581395 C 2.86 3.71953488372093 5.57 1.6293023255814 8.57 1.2093023255814 L 8.57 0.232558139534884 C 4.14 0.789302325581395 0.57 4.27627906976744 0 8.60325581395349 Z M 20 11.26 L 19 11.26 C 18.86 11.953488372093 18.71 12.6567441860465 18.43 13.3502325581395 C 17.14 16.1437209302326 14.57 18.2339534883721 11.43 18.6539534883721 L 11.43 19.6306976744186 C 15.86 19.0739534883721 19.43 15.586976744186 20 11.26 Z M 8.57 19.6306976744186 L 8.57 18.6539534883721 C 5.43 18.2339534883721 2.86 16.1437209302326 1.57 13.3502325581395 C 1.28 12.6567441860465 1.14 11.953488372093 1 11.26 L 0 11.26 C 0.57 15.586976744186 4.14 19.0739534883721 8.57 19.6306976744186 Z " fill-rule="nonzero" :fill="color" stroke="none" transform="matrix(1 0 0 1 436 253 )"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
const prop = defineProps({
|
||||||
|
color: '#aaef8a'
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
/** .border设置循环旋转动画效果 */
|
||||||
|
// .border {
|
||||||
|
// animation: rotate 3s linear infinite;
|
||||||
|
// transform-origin: center;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @keyframes rotate {
|
||||||
|
// 0% {
|
||||||
|
// transform: rotate(0deg);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 100% {
|
||||||
|
// transform: rotate(360deg);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
</style>
|
108
src/views/screen/microFactory/component/lineChart.vue
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
<template>
|
||||||
|
<v-chart :option="options" theme="dark" style="width: 100%;height: 100%;" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue';
|
||||||
|
const prop = defineProps({
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {
|
||||||
|
xAxis: [],
|
||||||
|
series: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const options = computed(() => {
|
||||||
|
return {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
||||||
|
borderColor: '#00c6ff',
|
||||||
|
borderWidth: 2,
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: 14
|
||||||
|
},
|
||||||
|
formatter: function (params) {
|
||||||
|
let tooltipText = '';
|
||||||
|
let xAxisValue = params[0].name;
|
||||||
|
params.forEach((item) => {
|
||||||
|
tooltipText += `<div style="padding: 2px 0;"><strong>${item.seriesName}:</strong> ${item.value}%</div>`;
|
||||||
|
});
|
||||||
|
return `${xAxisValue}<br>${tooltipText}`;
|
||||||
|
},
|
||||||
|
padding: 10,
|
||||||
|
extraCssText: 'border-radius: 8px; box-shadow: 0 0 15px rgba(0, 0, 0, 0.5);'
|
||||||
|
},
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
// legend: {
|
||||||
|
// data: ['上月', '本月'],
|
||||||
|
// right: 'left',
|
||||||
|
// textStyle: {
|
||||||
|
// color: '#ffff'
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
grid: {
|
||||||
|
left: '10%',
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: prop.data.xAxis,
|
||||||
|
axisLabel: {
|
||||||
|
color: "#ffffff",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
max: 100,
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
type: 'dashed',
|
||||||
|
color: '#3c3a4a85',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
color: "#ffffff",
|
||||||
|
formatter: function (value) {
|
||||||
|
return `${value} %`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
series: [{
|
||||||
|
name: '利用率',
|
||||||
|
data: prop.data.series,
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
itemStyle: {
|
||||||
|
color: 'rgb(150 ,162 ,116)',
|
||||||
|
},
|
||||||
|
lineStyle: {
|
||||||
|
width: 2,
|
||||||
|
},
|
||||||
|
areaStyle: {
|
||||||
|
color: {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
x2: 0,
|
||||||
|
y2: 1,
|
||||||
|
colorStops: [{
|
||||||
|
offset: 0,
|
||||||
|
color: 'rgb(150 ,162 ,116 ,0.6)'
|
||||||
|
}, {
|
||||||
|
offset: 1,
|
||||||
|
color: 'rgb(150 ,162 ,116 ,0.2)'
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
84
src/views/screen/microFactory/component/powerMonitoring.vue
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
<template>
|
||||||
|
<v-chart :option="options" theme="dark" style="width: 100%;height: 100%;" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed, ref } from 'vue';
|
||||||
|
const prop = defineProps({
|
||||||
|
data: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const options = computed(() => {
|
||||||
|
return {
|
||||||
|
tooltip: {
|
||||||
|
formatter: "{a} <br/>{c} {b}",
|
||||||
|
},
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
series: [{
|
||||||
|
name: "耗电量",
|
||||||
|
type: "gauge",
|
||||||
|
z: 3,
|
||||||
|
min: 0,
|
||||||
|
max: 380,
|
||||||
|
radius: "85%",
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
width: 12,
|
||||||
|
color: [[0.9, "#00b2b9"], [1, "#e60007"], ],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pointer: {
|
||||||
|
itemStyle: {
|
||||||
|
color: "auto",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
distance: 1,
|
||||||
|
length: 5,
|
||||||
|
splitNumber: 5,
|
||||||
|
lineStyle: {
|
||||||
|
color: "#464646"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
distance: -3,
|
||||||
|
length: 12,
|
||||||
|
lineStyle: {
|
||||||
|
color: "auto",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
color: "#fbffff",
|
||||||
|
distance: 10,
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: "bolder",
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
offsetCenter: ["0", "30%"],
|
||||||
|
textStyle: {
|
||||||
|
fontWeight: "bolder",
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#fbffff",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
detail: {
|
||||||
|
formatter: "{value}\n kW·h",
|
||||||
|
color: "inherit",
|
||||||
|
fontSize: 14,
|
||||||
|
textStyle: {
|
||||||
|
fontWeight: "bolder",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data: [{
|
||||||
|
value: prop.data,
|
||||||
|
}],
|
||||||
|
}, ],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
56
src/views/screen/microFactory/component/ringChart.vue
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<template>
|
||||||
|
<v-chart :option="options" theme="dark" style="width: 100%;height: 100%;" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed, ref } from 'vue';
|
||||||
|
const prop = defineProps({
|
||||||
|
data: {
|
||||||
|
type: Number,
|
||||||
|
default: 84.3
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const options = computed(() => {
|
||||||
|
return {
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
series: [{
|
||||||
|
type: 'gauge',
|
||||||
|
startAngle: 90,
|
||||||
|
endAngle: -270,
|
||||||
|
pointer: { show: false },
|
||||||
|
progress: {
|
||||||
|
show: true,
|
||||||
|
overlap: false,
|
||||||
|
roundCap: true,
|
||||||
|
clip: false,
|
||||||
|
itemStyle: {
|
||||||
|
color: '#58D9F9'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
width: 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
splitLine: { show: false },
|
||||||
|
axisTick: { show: false },
|
||||||
|
axisLabel: { show: false },
|
||||||
|
data: [{
|
||||||
|
value: prop.data,
|
||||||
|
// name: '完成率',
|
||||||
|
title: { offsetCenter: ['0%', '0%'] },
|
||||||
|
detail: {
|
||||||
|
offsetCenter: ['0%', '0%'], formatter: function (value) {
|
||||||
|
return value.toFixed(1) + '%';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
154
src/views/screen/microFactory/component/sortBarChart.vue
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
<template>
|
||||||
|
<!-- <v-chart class="chart" :option="option" theme="dark" style="width: 100%;height: 100%;" /> -->
|
||||||
|
<div ref="test1" style="width: 100%;height: 100%;"></div>
|
||||||
|
<div class="fullmask" v-show="isFull">
|
||||||
|
<div ref="fullScreen" v-bind:class="{ show: isFull, hide: !isFull }"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang='ts'>
|
||||||
|
import { ref, computed, getCurrentInstance, watch, nextTick } from "vue"
|
||||||
|
//饼图
|
||||||
|
const prop = defineProps({
|
||||||
|
data: {
|
||||||
|
default: () => {
|
||||||
|
return [
|
||||||
|
{ name: '支柱试验台', value: 120 },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
|
})
|
||||||
|
let isFull = ref(false)
|
||||||
|
const { proxy } = getCurrentInstance() as any
|
||||||
|
const test1 = ref(null)
|
||||||
|
const fullScreen = ref(null)
|
||||||
|
let charts = ref(null)
|
||||||
|
watch(() => prop.data, () => {
|
||||||
|
|
||||||
|
drawChart('test1')
|
||||||
|
}, { immediate: false, deep: true })
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function drawChart(elementId) {
|
||||||
|
|
||||||
|
let element = elementId == 'fullScreen' ? fullScreen.value : test1.value;
|
||||||
|
charts.value = proxy.$echarts.init(element, 'dark');
|
||||||
|
let sortBarChartData = prop.data.sort((a, b) => b.value - a.value)
|
||||||
|
|
||||||
|
|
||||||
|
if (elementId == 'test1') {
|
||||||
|
sortBarChartData = sortBarChartData.slice(0, 6)
|
||||||
|
}
|
||||||
|
|
||||||
|
let yAxisData = sortBarChartData.map(item => item.name)
|
||||||
|
let seriesData = sortBarChartData.map(item => item.value)
|
||||||
|
|
||||||
|
|
||||||
|
var option = {
|
||||||
|
// title: {
|
||||||
|
// text: 'Referer of a Website',
|
||||||
|
// subtext: 'Fake Data',
|
||||||
|
// left: 'center'
|
||||||
|
// },
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
// tooltip: {
|
||||||
|
// trigger: 'item'
|
||||||
|
// },
|
||||||
|
tooltip: {
|
||||||
|
},
|
||||||
|
|
||||||
|
toolbox: {
|
||||||
|
show: true,
|
||||||
|
right: "10%",
|
||||||
|
feature: {
|
||||||
|
myTool1: {
|
||||||
|
show: true,
|
||||||
|
title: isFull.value == true ? '取消全屏' : '全屏',
|
||||||
|
icon:
|
||||||
|
'path://M641.750109 384.100028l205.227128-204.519-0.704035 115.89966c-0.282433 9.611915 7.489578 18.09103 17.101493 17.808598l12.297071 0c9.611915-0.283456 17.667382-5.936199 17.808598-15.689331l0.565888-172.57752c0-0.14224 0.282433-9.187243 0.282433-9.187243 0.14224-4.804423-0.99056-9.187243-4.100388-12.297071-3.109828-3.109828-7.347339-5.086855-12.297071-4.946662l-8.763594 0.14224c-0.141216 0-0.278339 0-0.420579 0.14224L697.581696 98.166787c-9.611915 0.283456-17.667382 8.200776-17.808598 17.950837l0 12.297071c1.416256 11.44875 10.458189 18.092054 20.070104 17.808598l112.789832 0.283456-204.66124 203.814965c-9.329483 9.329483-9.329483 24.449855 0 33.778314 9.329483 9.470699 24.452925 9.470699 33.782408 0L641.750109 384.100028zM383.095141 576.889893 177.726797 780.705881l0.707105-115.338888c0.283456-9.607822-7.492648-18.086937-17.104563-17.808598l-13.001105 0c-9.611915 0.283456-17.667382 5.937223-17.808598 15.690354l-0.565888 172.718737c0 0.14224-0.282433 9.187243-0.282433 9.187243-0.14224 4.808516 0.99056 9.187243 4.096295 12.297071 3.109828 3.109828 7.351432 5.086855 12.297071 4.946662l8.762571-0.14224c0.14224 0 0.283456 0 0.425695-0.14224l171.873486 0.708128c9.607822-0.283456 17.667382-8.196683 17.808598-17.950837L344.93503 832.575226c-1.415232-11.44875-10.461259-18.092054-20.074198-17.808598L212.069977 814.483172 416.59 610.671277c9.329483-9.329483 9.329483-24.453948 0-33.782408C407.40685 567.41817 392.424624 567.41817 383.095141 576.889893L383.095141 576.889893zM894.047276 835.967486l-0.424672-172.718737c-0.283456-9.612938-8.200776-15.406898-17.809621-15.690354l-12.296047 0c-9.612938-0.278339-17.243733 8.200776-17.105586 17.808598l0.708128 115.903753L641.750109 576.889893c-9.329483-9.329483-24.452925-9.329483-33.782408 0-9.325389 9.328459-9.325389 24.452925 0 33.782408L812.490795 814.483172l-112.789832 0.283456c-9.611915-0.283456-18.515702 6.502088-20.073174 17.808598l0 12.297071c0.282433 9.611915 8.200776 17.667382 17.808598 17.950837l171.166381-0.708128c0.141216 0 0.282433 0.14224 0.424672 0.14224l8.763594 0.14224c4.803399 0.141216 9.187243-1.694595 12.296047-4.946662 3.109828-3.109828 4.238534-7.488555 4.097318-12.297071 0 0-0.14224-9.046027-0.14224-9.187243L894.047276 835.968509zM212.216309 146.506748l112.789832-0.283456c9.607822 0.283456 18.512632-6.502088 20.070104-17.808598L345.076246 116.116601c-0.283456-9.611915-8.196683-17.667382-17.808598-17.950837l-172.011632 0.708128c-0.14224 0-0.283456-0.14224-0.425695-0.14224l-8.761548-0.14224c-4.808516-0.141216-9.187243 1.694595-12.297071 4.946662-3.109828 3.109828-4.242627 7.488555-4.096295 12.297071 0 0 0.282433 9.046027 0.282433 9.187243l0.420579 172.718737c0.14224 9.608845 8.200776 15.406898 17.808598 15.686261l13.005198 0c9.611915 0.282433 17.242709-8.196683 17.10047-17.808598l-0.564865-115.334795 205.231221 203.958228c9.324366 9.329483 24.448832 9.329483 33.777291 0 9.329483-9.329483 9.329483-24.452925 0-33.782408L212.216309 146.506748 212.216309 146.506748zM212.216309 146.506748',
|
||||||
|
onclick: function () {
|
||||||
|
if (!isFull.value) {
|
||||||
|
elementId = 'fullScreen';
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
nextTick(() => {
|
||||||
|
drawChart(elementId);
|
||||||
|
});
|
||||||
|
}, 10);
|
||||||
|
|
||||||
|
isFull.value = !isFull.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
grid: {
|
||||||
|
left: '25%',
|
||||||
|
top: '10%',
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'value',
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: yAxisData,
|
||||||
|
inverse: true,
|
||||||
|
axisLabel: {
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: 13,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
data: seriesData,
|
||||||
|
type: 'bar',
|
||||||
|
realtimeSort: true,
|
||||||
|
itemStyle: {
|
||||||
|
color: (params) => {
|
||||||
|
let colorList = ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'];
|
||||||
|
return colorList[params.dataIndex % colorList.length]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: 'right',
|
||||||
|
valueAnimation: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
charts.value.setOption(option);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.fullmask {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 998;
|
||||||
|
background-color: rgba(0, 0, 0, 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.show {
|
||||||
|
position: fixed !important;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
width: 65%;
|
||||||
|
height: 95%;
|
||||||
|
z-index: 999;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background-color: rgba(18, 27, 38, 0.9137254901960784);
|
||||||
|
|
||||||
|
filter: alpha(opacity=10);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hide {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
BIN
src/views/screen/microFactory/image/u107.png
Normal file
After Width: | Height: | Size: 6.0 KiB |
BIN
src/views/screen/microFactory/image/u156.png
Normal file
After Width: | Height: | Size: 642 B |
BIN
src/views/screen/microFactory/image/u157.png
Normal file
After Width: | Height: | Size: 584 B |
BIN
src/views/screen/microFactory/image/u158.png
Normal file
After Width: | Height: | Size: 7.5 KiB |
BIN
src/views/screen/microFactory/image/u16.png
Normal file
After Width: | Height: | Size: 103 KiB |
BIN
src/views/screen/microFactory/image/u17.png
Normal file
After Width: | Height: | Size: 49 KiB |
BIN
src/views/screen/microFactory/image/u19.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
BIN
src/views/screen/microFactory/image/u26.png
Normal file
After Width: | Height: | Size: 994 B |
BIN
src/views/screen/microFactory/image/u36.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
src/views/screen/microFactory/image/u57.png
Normal file
After Width: | Height: | Size: 191 KiB |
BIN
src/views/screen/microFactory/image/u83.png
Normal file
After Width: | Height: | Size: 611 B |
731
src/views/screen/microFactory/index.vue
Normal file
@ -0,0 +1,731 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<div class="header">
|
||||||
|
<div class="title">{{ skinName }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<div class="left-panel">
|
||||||
|
<CardVue class="left-container-1" title="设备列表">
|
||||||
|
<!-- <scrollBoard ref="DvScrollBoard" :data="scrollBoardConfig_data" :config="scrollBoardConfig">
|
||||||
|
</scrollBoard> -->
|
||||||
|
<el-table :data="devList"
|
||||||
|
v-tableAutoScroll="{delay:15}"
|
||||||
|
header-row-class-name="table_header"
|
||||||
|
style="width: 100%;height: 100%;"
|
||||||
|
@row-click="handlePush2item"
|
||||||
|
>
|
||||||
|
<el-table-column prop="code" label="编码" width="90"/>
|
||||||
|
<el-table-column prop="name" label="设备名称" />
|
||||||
|
<el-table-column prop="runTime" label="运行时长" >
|
||||||
|
<template #default="{row}">
|
||||||
|
<div>{{ row.runTime }}min</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="rate" label="设备利用率" >
|
||||||
|
<template #default="{row}">
|
||||||
|
<div>{{ row.rate }}%</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="state" label="状态" >
|
||||||
|
<template #default="{row}">
|
||||||
|
<div style="width:100%;height:100%;display:flex;justify-content: space-around;align-items: center;">
|
||||||
|
<svg-icon v-if="row.state == 0" icon-class="stop" class="el-input__icon input-icon" />
|
||||||
|
<svg-icon v-else-if="row.state == 1" icon-class="wait" class="el-input__icon input-icon" />
|
||||||
|
<svg-icon v-else-if="row.state == 2" icon-class="run" class="el-input__icon input-icon" />
|
||||||
|
<svg-icon v-else-if="row.state == 4" icon-class="alarm" class="el-input__icon input-icon" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<div class="left-tip-type">
|
||||||
|
<div class="left-tip-type-item">
|
||||||
|
<svg-icon icon-class="run" class="el-input__icon" style="width: 26px;height: 26px;" />
|
||||||
|
<div class="left-tip-type-item-text">工作</div>
|
||||||
|
</div>
|
||||||
|
<div class="left-tip-type-item">
|
||||||
|
<svg-icon icon-class="wait" class="el-input__icon" style="width: 26px;height: 26px;" />
|
||||||
|
<div class="left-tip-type-item-text">待机</div>
|
||||||
|
</div>
|
||||||
|
<div class="left-tip-type-item">
|
||||||
|
<svg-icon icon-class="stop" class="el-input__icon" style="width: 26px;height: 26px;" />
|
||||||
|
<div class="left-tip-type-item-text">停机</div>
|
||||||
|
</div>
|
||||||
|
<div class="left-tip-type-item">
|
||||||
|
<svg-icon icon-class="repair" class="el-input__icon" style="width: 26px;height: 26px;" />
|
||||||
|
<div class="left-tip-type-item-text">维修</div>
|
||||||
|
</div>
|
||||||
|
<div class="left-tip-type-item">
|
||||||
|
<svg-icon icon-class="alarm" class="el-input__icon" style="width: 26px;height: 26px;" />
|
||||||
|
<div class="left-tip-type-item-text">故障</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CardVue>
|
||||||
|
|
||||||
|
<CardVue class="left-container" title="单设备耗电量排行">
|
||||||
|
|
||||||
|
<SortBarChart :data="sortBarChartData" fill="#169BD5" />
|
||||||
|
<div class="radio-ab-lb">
|
||||||
|
<el-radio-group v-model="radio_bar" @change="handleChangeBar" size="small">
|
||||||
|
<el-radio-button label="d">当天</el-radio-button>
|
||||||
|
<el-radio-button label="all">累计</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
</div>
|
||||||
|
</CardVue>
|
||||||
|
</div>
|
||||||
|
<div class="center-panel">
|
||||||
|
<div class="dev-type-overview">
|
||||||
|
<div class="status-item" v-for="item in devStatus.devTypes" :key="item.type">
|
||||||
|
<div class="value">
|
||||||
|
<div class="on-text">{{ item.work }}</div>
|
||||||
|
<div class="all-text">{{ item.total }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="label">{{ item.name }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="status-flag">
|
||||||
|
<div class="yuan green"></div>
|
||||||
|
<div class="flag-text">工作数量</div>
|
||||||
|
<div class="yuan blue"></div>
|
||||||
|
<div class="flag-text">设备总数</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="status-overview">
|
||||||
|
<div class="status-item">
|
||||||
|
<div class="item-label item-label-1">工作数量</div>
|
||||||
|
<div class="item-label item-label-2">停机数量</div>
|
||||||
|
<div class="item-label item-label-3">待机数量</div>
|
||||||
|
<div class="item-label item-label-4">设备总数</div>
|
||||||
|
</div>
|
||||||
|
<div class="status-center">
|
||||||
|
<div class="status-center-item">
|
||||||
|
<div class="item-value item-label-1">{{ devStatus.work }}台</div>
|
||||||
|
<div class="item-value item-label-2">{{ devStatus.stop }}台</div>
|
||||||
|
<div class="item-value item-label-3">{{ devStatus.wait }}台</div>
|
||||||
|
<div class="item-value item-label-4">{{ devStatus.total }}台</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="centerChart">
|
||||||
|
<div class="ring-chart">
|
||||||
|
<RingChart :data="devStatus.work/devStatus.total * 100" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<CenterCard title="用电监测" class="power-monitoring">
|
||||||
|
<div class="power-item-wrapper">
|
||||||
|
<div class="power-item" v-for="item in powerMonitoring" :key="item.label">
|
||||||
|
<div class="item-label">{{ item.label }}</div>
|
||||||
|
<div class="power-chart">
|
||||||
|
<PowerMonitoring :data="item.value" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CenterCard>
|
||||||
|
</div>
|
||||||
|
<div class="right-panel">
|
||||||
|
<CardVue class="left-container" title="设备利用率">
|
||||||
|
<LineChart :data="rateData" />
|
||||||
|
</CardVue>
|
||||||
|
<CardVue class="left-container" title="设备提醒">
|
||||||
|
<el-table :data="remindData" v-if="remindData.length > 0" v-tableAutoScroll="{delay:15}" header-row-class-name="table_header" style="width: 100%;height: 100%;">
|
||||||
|
<el-table-column prop="devCode" label="编码" width="90"/>
|
||||||
|
<el-table-column prop="name" label="设备名称" />
|
||||||
|
<el-table-column prop="subject" label="保养内容" />
|
||||||
|
<el-table-column prop="person" label="负责人" />
|
||||||
|
<el-table-column prop="time" label="保养时间" />
|
||||||
|
</el-table>
|
||||||
|
<el-empty v-else description="暂无记录" />
|
||||||
|
<!-- <div class="radio-ab-lb">
|
||||||
|
<el-radio-group v-model="radio_repair" @change="handleChangeRepair" size="small">
|
||||||
|
<el-radio-button label="b">保养</el-radio-button>
|
||||||
|
<el-radio-button label="w">维修</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
</div> -->
|
||||||
|
</CardVue>
|
||||||
|
<CardVue class="left-container" title="设备报警">
|
||||||
|
<el-table :data="repairData" v-if="repairData.length > 0" v-tableAutoScroll="{delay:15}" header-row-class-name="table_header" style="width: 100%;height: 100%;">
|
||||||
|
<el-table-column prop="devCode" label="编码" width="90"/>
|
||||||
|
<el-table-column prop="name" label="设备名称" />
|
||||||
|
<el-table-column prop="subject" label="报警内容" />
|
||||||
|
<el-table-column prop="person" label="负责人" />
|
||||||
|
<el-table-column prop="time" label="报警时间" />
|
||||||
|
</el-table>
|
||||||
|
<el-empty v-else description="暂无记录" />
|
||||||
|
</CardVue>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footer"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted, onUnmounted,getCurrentInstance } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import CardVue from './component/card.vue'
|
||||||
|
import CenterCard from './component/centerCard.vue'
|
||||||
|
import BarChart from './component/barChart.vue'
|
||||||
|
import LineChart from './component/lineChart.vue'
|
||||||
|
import RingChart from './component/ringChart.vue'
|
||||||
|
import PowerMonitoring from './component/powerMonitoring.vue'
|
||||||
|
import SortBarChart from './component/sortBarChart.vue'
|
||||||
|
import scrollBoard from "@/components/ZdScrollBoard/scrollBoard.vue";
|
||||||
|
import u83 from './image/u83.png'
|
||||||
|
import u156 from './image/u156.png'
|
||||||
|
import u157 from './image/u157.png'
|
||||||
|
import u158 from './image/u158.png'
|
||||||
|
import 'element-plus/theme-chalk/dark/css-vars.css'
|
||||||
|
import { getConfigKey } from "@/api/system/config";
|
||||||
|
import { connectWebsocket, closeWebsocket} from "@/utils/websocket";
|
||||||
|
import { listDevice, listElect, electMonitoring, deviceStatus, deviceRate,deviceCheck,deviceRepair } from '@/api/screen/micro'
|
||||||
|
|
||||||
|
let {proxy} = getCurrentInstance()
|
||||||
|
let router = useRouter()
|
||||||
|
let radio_bar = ref('d')
|
||||||
|
let radio_repair = ref('b')
|
||||||
|
let skinName = ref('');
|
||||||
|
|
||||||
|
let devStatus = reactive({
|
||||||
|
"wait": 0,
|
||||||
|
"total": 0,
|
||||||
|
"stop": 0,
|
||||||
|
"rate": 0,
|
||||||
|
"work": 0,
|
||||||
|
"devTypes": []
|
||||||
|
})
|
||||||
|
|
||||||
|
let devList = ref([])
|
||||||
|
|
||||||
|
function getConfigKeyFun(key) {
|
||||||
|
getConfigKey(key).then(res => {
|
||||||
|
skinName.value = res.msg
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function status2Img(status) {
|
||||||
|
let html = `<div style="width:100%;height:100%;display:flex;justify-content: space-around;align-items: center;">`
|
||||||
|
switch (status) {
|
||||||
|
case 0:
|
||||||
|
html += `<img src="${u157}" width="32" height="32">`
|
||||||
|
break
|
||||||
|
case 1:
|
||||||
|
html += `<img src="${u156}" width="32" height="32">`
|
||||||
|
break
|
||||||
|
case 2:
|
||||||
|
html += `<img src="${u83}" width="32" height="32">`
|
||||||
|
break
|
||||||
|
case 4:
|
||||||
|
html += `<img src="${u158}" width="32" height="32">`
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
html += `<img src="${u157}" width="32" height="32">`
|
||||||
|
break
|
||||||
|
}
|
||||||
|
html += '</div>'
|
||||||
|
return html
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取设备列表
|
||||||
|
function getListDevice() {
|
||||||
|
listDevice().then(res => {
|
||||||
|
devList.value = res.data
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let timer = new Date().getTime();
|
||||||
|
|
||||||
|
//节流
|
||||||
|
function throttle(func, wait) {
|
||||||
|
let lastTime = 0;
|
||||||
|
|
||||||
|
return function(...args) {
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
|
if (now - lastTime >= wait) {
|
||||||
|
lastTime = now;
|
||||||
|
func.apply(this, args);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let sortBarChartData = ref([])
|
||||||
|
//获取设备能耗排行
|
||||||
|
function getlistElect() {
|
||||||
|
listElect(radio_bar.value).then(res => {
|
||||||
|
sortBarChartData.value = res.data.map(item => {
|
||||||
|
return {
|
||||||
|
name: item.name,
|
||||||
|
value: item.electricity
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//切换能耗排行
|
||||||
|
function handleChangeBar() {
|
||||||
|
getlistElect()
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleChangeRepair() {
|
||||||
|
if (radio_repair.value == 'b') {
|
||||||
|
getdeviceCheck()
|
||||||
|
} else {
|
||||||
|
getdeviceRepair()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let powerMonitoring = ref([
|
||||||
|
{ label: '当天耗电量', value: 8 },
|
||||||
|
{ label: '本周耗电量', value: 60 },
|
||||||
|
{ label: '本月耗电量', value: 288 }
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
|
//获取用电监测
|
||||||
|
function getelectMonitoring() {
|
||||||
|
electMonitoring().then(res => {
|
||||||
|
powerMonitoring.value = [
|
||||||
|
{ label: '当天耗电量', value: res.data.day },
|
||||||
|
{ label: '本周耗电量', value: res.data.week },
|
||||||
|
{ label: '本月耗电量', value: res.data.month }
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let remindData = ref([])
|
||||||
|
|
||||||
|
//获取设备提醒
|
||||||
|
function getdeviceCheck() {
|
||||||
|
deviceCheck().then(res => {
|
||||||
|
remindData.value = res.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let repairData = ref([])
|
||||||
|
//获取设备维修
|
||||||
|
function getdeviceRepair() {
|
||||||
|
deviceRepair().then(res => {
|
||||||
|
repairData.value = res.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//获取设备状态
|
||||||
|
function getdeviceStatus() {
|
||||||
|
deviceStatus().then(res => {
|
||||||
|
devStatus.wait = res.data.wait
|
||||||
|
devStatus.total = res.data.total
|
||||||
|
devStatus.stop = res.data.stop
|
||||||
|
devStatus.rate = res.data.rate
|
||||||
|
devStatus.work = res.data.work
|
||||||
|
devStatus.devTypes = res.data.devTypes
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let rateData = ref()
|
||||||
|
//设备利用率
|
||||||
|
function getdeviceRate() {
|
||||||
|
deviceRate().then(res => {
|
||||||
|
rateData.value = {
|
||||||
|
xAxis: res.data.dates,
|
||||||
|
series: res.data.rate
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function handlePush2item(row) {
|
||||||
|
|
||||||
|
router.push({
|
||||||
|
path: '/screen/devItem_' + row.id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//socket
|
||||||
|
function getWebsocket(val) {
|
||||||
|
try {
|
||||||
|
let data = JSON.parse(val);
|
||||||
|
|
||||||
|
if (data.type == "status") {
|
||||||
|
let obj = data.msg;
|
||||||
|
let flag = false;
|
||||||
|
let thatTime = new Date().getTime();
|
||||||
|
devList.value.forEach(item => {
|
||||||
|
if (item.id == obj.id) {
|
||||||
|
item.state = obj.status
|
||||||
|
// item.runTime = obj.runTime
|
||||||
|
flag = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (flag && thatTime - timer > 10000) {
|
||||||
|
timer = thatTime;
|
||||||
|
getdeviceStatus()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function errWebsocket(val) {
|
||||||
|
// console.log(val);
|
||||||
|
}
|
||||||
|
onMounted(() => {
|
||||||
|
getListDevice()
|
||||||
|
getlistElect()
|
||||||
|
getelectMonitoring()
|
||||||
|
getdeviceStatus()
|
||||||
|
getdeviceRate()
|
||||||
|
getdeviceCheck()
|
||||||
|
getdeviceRepair()
|
||||||
|
getConfigKeyFun('screen.microFactory.title')
|
||||||
|
|
||||||
|
connectWebsocket('','',getWebsocket, errWebsocket)
|
||||||
|
|
||||||
|
})
|
||||||
|
onUnmounted(() => {
|
||||||
|
closeWebsocket()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
::v-deep(.table_header th) {
|
||||||
|
background-color: transparent !important;
|
||||||
|
color: #21dadb;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.input-icon {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
width: 1920px;
|
||||||
|
height: 1080px;
|
||||||
|
position: relative;
|
||||||
|
// display: flex;
|
||||||
|
// justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background-image: url('/src/assets/images/screen-bg.png');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
/* 如果你不想让背景平铺 */
|
||||||
|
background-size: cover;
|
||||||
|
/* 或者其他你需要的大小设置 */
|
||||||
|
background-position: center;
|
||||||
|
|
||||||
|
.header {
|
||||||
|
width: 100%;
|
||||||
|
height: 89px;
|
||||||
|
background-image: url('/src/assets/images/screen-header-bg1.png');
|
||||||
|
background-size: 100% 100%;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
width: 100%;
|
||||||
|
height: 89px;
|
||||||
|
font-size: 36px;
|
||||||
|
color: #f9f8f4;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 89px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
width: 100%;
|
||||||
|
height: 975px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 20px 0;
|
||||||
|
|
||||||
|
.left-panel,
|
||||||
|
.right-panel {
|
||||||
|
width: 488px;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(242, 242, 242, 0.0274509803921569);
|
||||||
|
|
||||||
|
.left-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 320px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-container-1 {
|
||||||
|
width: 100%;
|
||||||
|
height: 640px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-ab-lb {
|
||||||
|
position: absolute;
|
||||||
|
top: 23px;
|
||||||
|
right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-tip-type {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 200px;
|
||||||
|
height: 50px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 700;
|
||||||
|
|
||||||
|
.left-tip-type-item {
|
||||||
|
width: 33%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-panel {
|
||||||
|
width: 900px;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
// background-color: rgba(242, 242, 242, 0.0274509803921569);
|
||||||
|
.dev-type-overview {
|
||||||
|
width: 100%;
|
||||||
|
height: 80px;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
margin: 30px 0;
|
||||||
|
|
||||||
|
.status-item {
|
||||||
|
width: 120px;
|
||||||
|
height: 80px;
|
||||||
|
text-align: center;
|
||||||
|
color: #f9f8f4;
|
||||||
|
|
||||||
|
.value {
|
||||||
|
width: 100%;
|
||||||
|
height: 56px;
|
||||||
|
color: #21dadb;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 20px;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
width: 1px;
|
||||||
|
height: 54px;
|
||||||
|
border: #f9f8f4 solid 1px;
|
||||||
|
position: absolute;
|
||||||
|
transform: rotate(30deg);
|
||||||
|
top: 0px;
|
||||||
|
left: 61px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.on-text {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 35px;
|
||||||
|
color: #7CFFB2;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.all-text {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 60px;
|
||||||
|
color: #21dadb;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
width: 100%;
|
||||||
|
height: 24px;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-flag {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
top: -53px;
|
||||||
|
left: 15px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.yuan {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.green {
|
||||||
|
background-color: #7CFFB2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blue {
|
||||||
|
background-color: #21dadb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flag-text {
|
||||||
|
color: #f9f8f4;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
margin: 0 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-overview {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 400px;
|
||||||
|
background: url('./image/u16.png') no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 22px;
|
||||||
|
color: #f9f8f4;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.status-item {
|
||||||
|
position: relative;
|
||||||
|
width: 85%;
|
||||||
|
height: 80%;
|
||||||
|
|
||||||
|
.item-label {
|
||||||
|
position: absolute;
|
||||||
|
width: 167px;
|
||||||
|
height: 47px;
|
||||||
|
text-align: center;
|
||||||
|
background: url('./image/u19.png') no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
line-height: 47px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-label-1 {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-label-2 {
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-label-3 {
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-label-4 {
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-center {
|
||||||
|
position: absolute;
|
||||||
|
width: calc(85% - 370px);
|
||||||
|
height: calc(80% - 47px - 47px - 30px);
|
||||||
|
|
||||||
|
.item-value {
|
||||||
|
position: absolute;
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
background: url('./image/u107.png') no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
line-height: 60px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.centerChart {
|
||||||
|
position: absolute;
|
||||||
|
width: 300px;
|
||||||
|
height: 300px;
|
||||||
|
background: url('./image/u57.png') no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.ring-chart {
|
||||||
|
width: 220px;
|
||||||
|
height: 220px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.power-monitoring {
|
||||||
|
width: 100%;
|
||||||
|
height: 350px;
|
||||||
|
margin-top: 60px;
|
||||||
|
|
||||||
|
.power-item-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.power-item {
|
||||||
|
width: 280px;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.item-label {
|
||||||
|
width: 100%;
|
||||||
|
height: 47px;
|
||||||
|
background: url('./image/u19.png') no-repeat;
|
||||||
|
background-size: 167px 47px;
|
||||||
|
background-position: center;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 47px;
|
||||||
|
color: #f9f8f4;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
margin: 6px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.power-chart {
|
||||||
|
width: 247px;
|
||||||
|
height: 247px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
width: 100%;
|
||||||
|
height: 16px;
|
||||||
|
background: url('./image/u26.png') no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
@ -10,7 +10,7 @@ export default defineConfig(({ mode, command }) => {
|
|||||||
// 部署生产环境和开发环境下的URL。
|
// 部署生产环境和开发环境下的URL。
|
||||||
// 默认情况下,vite 会假设你的应用是被部署在一个域名的根路径上
|
// 默认情况下,vite 会假设你的应用是被部署在一个域名的根路径上
|
||||||
// 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
|
// 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
|
||||||
base: VITE_APP_ENV === 'production' ? '/' : '/',
|
base: VITE_APP_ENV === 'production' ? '/ras-web/' : '/',
|
||||||
plugins: createVitePlugins(env, command === 'build'),
|
plugins: createVitePlugins(env, command === 'build'),
|
||||||
resolve: {
|
resolve: {
|
||||||
// https://cn.vitejs.dev/config/#resolve-alias
|
// https://cn.vitejs.dev/config/#resolve-alias
|
||||||
@ -31,8 +31,8 @@ export default defineConfig(({ mode, command }) => {
|
|||||||
proxy: {
|
proxy: {
|
||||||
// https://cn.vitejs.dev/config/#server-proxy
|
// https://cn.vitejs.dev/config/#server-proxy
|
||||||
'/dev-api': {
|
'/dev-api': {
|
||||||
target: 'http://192.168.10.97:9015',
|
// target: 'http://192.168.10.65:9015',
|
||||||
// target: 'http://8.141.87.86:9015',
|
target: 'http://8.141.87.86:9015',
|
||||||
// target: 'http://192.168.110.90:10393/mock/5ce74738-f63f-4d21-af85-b1d132c6f6fd',
|
// target: 'http://192.168.110.90:10393/mock/5ce74738-f63f-4d21-af85-b1d132c6f6fd',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (p) => p.replace(/^\/dev-api/, '')
|
rewrite: (p) => p.replace(/^\/dev-api/, '')
|
||||||
|