1.太极开发者软件的智慧管廊案例界面截图
2.笔者自行接入新大陆云平台数据修改后的界面
3.主要修改了以下地方:
- 开场动画:路径:E:\数字孪生\taichi\智慧管廊\Code\src\Views\home\IntegratedSupervision\index.vue
- 案例代码:
import { addAdministrativeRegion } from './administrativeRegion'
import { getLayer, getBorder, getLine1, getLine2, getPoint } from '@/api/integratedSupervision'
// 添加行政区划图层
const addTopLayer = () => {
const polygonArr: any = []
getLayer().then((data: any) => {
data.features.forEach((item: any, index: number) => {
item.geometry.coordinates.forEach((coordinates: any) => {
coordinates[0].forEach((item: Array<number>) => {
item[2] = 1000
})
const top = {
id: 'top_polygon_' + index, //polygon唯一标识id
coordinates: coordinates[0], //构成polygon的坐标点数组
height: 50, //3D多边形的高度
material: '/JC_CustomAssets/MaterialLibrary/Exhibition/大理石/MI_BlueMarble01.MI_BlueMarble01', //自定义材质路径
vectorParameters: [{ name: '颜色', value: [0.075, 0.373, 0.537] }], //材质数组类型参数
scalarParameters: [
{ name: 'U缩放', value: 0.001 },
{ name: 'V缩放', value: 0.001 },
{ name: '饱和度', value: 1 },
{ name: '高光', value: 0.1 },
{ name: '亮度', value: 0.5 }
], //材质数值类型参数
generateTop: true, //是否生成顶面
generateSide: true, //是否生成侧面
generateBottom: true //是否生成底面
}
polygonArr.push(top)
const borderCoord = JSON.parse(JSON.stringify(item.geometry.coordinates[0][0]))
borderCoord.forEach((item: Array<number>) => {
item[2] = 1050
})
const border = {
id: 'top_border_' + index, //polygon唯一标识id
coordinates: borderCoord, //构成polygon的坐标点数组
color: '#77e3f7',
style: 3,
intensity: 1,
height: 200 //3D多边形的高度
}
polygonArr.push(border)
})
})
//批量添加polygon
__g.polygon3d.add(polygonArr, null)
})
}
/**
* 添加底部装饰图层
*/
const addBottomLayer = () => {
const polygonArr: Array<any> = []
getBorder().then((data: any) => {
data.features.forEach((item: any, index: number) => {
const coordinate1 = JSON.parse(JSON.stringify(item.geometry.coordinates[0][0]))
// 最底层蓝色-起始高度0,高度80
coordinate1.forEach((item: Array<number>) => {
item[2] = 0
})
const bottom1 = {
id: 'bottom1_' + index, //polygon唯一标识id
coordinates: coordinate1, //构成polygon的坐标点数组
color: '#122e36',
style: 2,
intensity: 1,
height: 500 //3D多边形的高度
}
polygonArr.push(bottom1)
const coordinate2 = JSON.parse(JSON.stringify(item.geometry.coordinates[0][0]))
// 2层灰色-起始高度60,高度160
coordinate2.forEach((item: Array<number>) => {
item[2] = 200
})
const bottom2 = {
id: 'bottom2_' + index, //polygon唯一标识id
coordinates: coordinate2, //构成polygon的坐标点数组
color: [0.2, 0.2, 0.2, 1],
style: 2,
height: 600 //3D多边形的高度
}
polygonArr.push(bottom2)
// 3层蓝绿色-起始高度120,高度100
const coordinate3 = JSON.parse(JSON.stringify(item.geometry.coordinates[0][0]))
coordinate3.forEach((item: Array<number>) => {
item[2] = 400
})
const bottom3 = {
id: 'bottom3_' + index, //polygon唯一标识id
coordinates: coordinate3, //构成polygon的坐标点数组
color: '#1d8eae',
style: 4,
height: 750 //3D多边形的高度
}
polygonArr.push(bottom3)
})
//批量添加polygon
__g.polygon3d.add(polygonArr, null)
})
}
// 添加管廊线路
const addLine = () => {
getLine1().then((data: any) => {
const polylineArr: Array<any> = []
data.features.forEach((item: any, index: number) => {
item.geometry.coordinates[0].map((item: Array<number>) => {
item[2] = 800
})
const oPolyline = {
id: 'polyLine1_' + index, //折线唯一标识id
coordinates: item.geometry.coordinates[0], //构成折线的坐标点数组
range: [1, 1000000], //可视范围:[近裁距离, 远裁距离],取值范围: [任意负值, 任意正值]
color: '#ff5959', //折线颜色
style: 0, //折线样式 参考样式枚举:PolylineStyle
thickness: 400, //折线宽度
intensity: 1, //亮度
flowRate: 0.1, //流速
tiling: 0.2, //材质贴图平铺比例
shape: 1, //折线类型 0:直线, 1:曲线
depthTest: false //是否做深度检测
}
polylineArr.push(oPolyline)
})
__g.polyline.add(polylineArr, null)
})
getLine2().then((data: any) => {
const polylineArr: Array<any> = []
data.features.forEach((item: any, index: number) => {
item.geometry.coordinates[0].map((item: Array<number>) => {
item[2] = 800
})
const oPolyline = {
id: 'polyLine2_' + index, //折线唯一标识id
coordinates: item.geometry.coordinates[0], //构成折线的坐标点数组
range: [1, 1000000], //可视范围:[近裁距离, 远裁距离],取值范围: [任意负值, 任意正值]
color: index % 2 ? '#ffa92e' : '#3a8fff', //折线颜色
style: 0, //折线样式 参考样式枚举:PolylineStyle
thickness: 400, //折线宽度
intensity: 1, //亮度
flowRate: 0.1, //流速
tiling: 0.2, //材质贴图平铺比例
shape: 1, //折线类型 0:直线, 1:曲线
depthTest: false //是否做深度检测
}
polylineArr.push(oPolyline)
})
__g.polyline.add(polylineArr, null)
})
}
// 添加监控中心点位
// const addPoint = () => {
// getPoint().then((data: any) => {
// const os: Array<any> = []
// data.features.forEach((item: any, index: number) => {
// item.geometry.coordinates[2] = 1050
// const o = {
// id: 'm1_' + index,
// pointName: index == 0 ? 'Point_R_4' : 'Point_B_6', //3D标注展示的特效名称
// text: index == 0 ? '总监控中心' : '分监控中心', //3D标注显示文字
// textSize: 100, //3D标注显示文字大小
// textColor: index == 0 ? [0.8, 0.2, 0.2, 1] : [1, 1, 1, 1], //3D标注显示文字颜色
// textOutlineSize: 5, //3D标注显示文字轮廓大小
// textOutlineColor: [0, 0, 0, 1], // 3D标注显示文字轮廓颜色
// textFixed: false, // 3D标注显示文字是否固定文本朝向
// textVisible: true, //3D标注显示文字是否显示文本
// textLocation: index == 0 ? [0, 0, 3500] : [0, 0, 2500], // 文字位置
// textRotation: [0, 90, 0], // 文字旋转
// pointVisible: true, //3D标注是否显示
// pointScale: index == 0 ? 600 : 400, //3D标注整体缩放比例
// coordinate: item.geometry.coordinates, //3D标注的坐标位置 注意:若坐标Z设置高度为0时 autoHeight=true则会显示在物体上方
// coordinateType: 0, //坐标系类型
// range: [1, 1000000], //3D标注的可视距离范围:[min,max],单位:米
// autoHeight: false //自动判断下方是否有物体,设置正确高度,默认值:false
// }
// os.push(o)
// })
// __g.marker3d.add(os, null)
// })
// }
const addAdministrativeRegion = () => {
addTopLayer()
addBottomLayer()
addLine()
// addPoint()
}
export {
addAdministrativeRegion
}
// 代码中注释掉的是便是原案例监控点样式的代码
- 修改代码
import { AnimationType, playInitAnimation } from '@/utils/animation'
/*
* @Author: Janio 2207597040@qq.com
* @Date: 2023-10-12 19:18:35
* @LastEditors: Janio 2207597040@qq.com
* @LastEditTime: 2023-10-12 19:22:57
* @FilePath: \20230515_CGSY_FREEDO_DTSWEEKLY_ZHGC\src\utils\animation.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
let animationList: any = null
/**
* 播放初始化导览
*/
let AnimationList: any = []
export const playInitAnimation = async (type = AnimationType.Initialization) => {
const nameArr = ['管廊漫游1', '管廊漫游2', '综合舱']
if (!AnimationList.length) {
const res: any = await __g.camera.getAnimationList()
AnimationList = res.data
const obj = AnimationList.filter((item: any) => item.name == nameArr[type])
await __g.camera.playAnimation(obj[0].id)
} else {
const obj = AnimationList.filter((item: any) => item.name == nameArr[type])
await __g.camera.playAnimation(obj[0].id)
}
}
/**
* 导览名字枚举
*/
export enum AnimationType {
/**
* 城市孪生 初始化
*/
Initialization = 4,
//精加工产线
Roam1 = 0,
Roam2 = 1,
CompositeTank = 2
}
- 数据的接入与显示
import axios from "@/http/HTTP";
export function getWenDu(){
return axios.get("/myapi/devices/1155318/sensors/z_temp",{
headers:{
AccessToken: "070427928080F1C98F91F626C262E30CF67D73B616CFA47E9E23C143E1F9021C8D795302CEC565DF4D1CA81BE1C8E9557D83C4FBAADB406166FAE1AFB60D9DE1F7DB252BEA073D8010BFA85ED29183842266BD07D6CFFB50B8BD4D52C2CE9812BDC7086D723DB063E9C15F34FFD5A5953562E2B2914C52BE1FF61CEECF598F2544E43BE7E8B83C3F221E9C7BD2D5E2A6D1289738C8CAC138AE5175A3397432C581CA61BC5E541CEA6C1C35DBEEBA6AE0C08A42BA0888A99167E691F7E6A275856AE3B0D4E3CC6023BD7556D38F8CE41F9C7C8BD8C11C4E6FE19538868E260FD3"
}
});
/*
* @Author: your name
* @Date: 2021-12-01 15:52:58
* @LastEditTime: 2021-12-01 15:55:51
* @LastEditors: Please set LastEditors
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
* @FilePath: \vue3_ts_init\src\plugins\HTTP.ts
*/
import axios from "axios";
import { getToken } from "@/http/auth";
// create an axios instance
const request = axios.create({
timeout: 60000,
});
const TOKEN = getToken(); // 获取token
// 请求拦截器
request.interceptors.request.use(
(config: any) => {
if (TOKEN) {
config.headers["Authorization"] = TOKEN;
}
return config;
},
(error) => {
// do something with request error
console.log(error);
return Promise.reject(error);
}
);
// 响应拦截器
request.interceptors.response.use(
(response) => {
return response.data;
},
(error) => {
console.log(error);
const data = error.response.data;
const status = error.response.status;
// 对不同状态码进行管理
if (status === 401) {
console.log("登录已过期");
} else if (status === 500) {
console.log("服务器错误");
} else {
console.log("请求错误状态码:", status);
}
return Promise.reject(data.error);
}
);
export default request;
<!--
* @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
* @Date: 2024-12-26 19:14:33
* @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
* @LastEditTime: 2024-12-29 17:34:08
* @FilePath: \Code\src\App.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
<router-view/>
</template>
<script lang="ts" setup>
import {onMounted} from "vue";
import {getBattery, getCO, getFan, getfire, getled, getMethane, getshidu, getVoltage, getwater, getWaterimmersion, getWenDu} from "@/api/demoAPI"
onMounted(async function() {
const data = await getWenDu();
console.log("温度",data);
});
onMounted(async function() {
const data = await getshidu();
console.log("湿度",data);
});
onMounted(async function() {
const data = await getCO();
console.log("一氧化碳",data);
});
onMounted(async function() {
const data = await getVoltage();
console.log("电压值",data);
});
onMounted(async function() {
const data = await getBattery();
console.log("电量",data);
});
onMounted(async function() {
const data = await getMethane();
console.log("甲烷",data);
});
onMounted(async function() {
const data = await getwater();
console.log("水流",data);
});
onMounted(async function() {
const data = await getWaterimmersion();
console.log("水浸",data);
});
onMounted(async function() {
const data = await getfire();
console.log("火焰",data);
});
onMounted(async function() {
const data = await getFan();
console.log("风扇",data);
});
onMounted(async function() {
const data = await getled();
console.log("报警灯",data);
});
</script>
<style lang="scss" scoped>
</style>
上面的代码原理简化例子:
import axios from 'axios'
import { onMounted,ref } from 'vue'
export function getWenDu(){
return axios.get('url',{
headers:{
AccessToken:''
}
})
}
const getWenDu_Value = ref("无法找到温度值!");
onMounted(async()=>{
const data = getWenDu();
const {Unit,Value} = data.ResultObj;
getWenDu_Value.value = Value+Unit
})
代码解释:
import axios from 'axios'
:导入 Axios 库。Axios 是一个基于 Promise 的 HTTP 客户端,用于浏览器和 node.js,常用于发送 HTTP 请求。import { onMounted, ref } from 'vue'
:从 Vue 3 中导入onMounted
和ref
函数。onMounted
是一个生命周期钩子,用于在组件挂载后执行代码;ref
用于创建响应式引用,通常用于存储组件的响应式数据.export function getWenDu()
:定义并导出一个名为getWenDu
的函数。这个函数将用于发送 HTTP GET 请求以获取温度数据。return axios.get('url',{ headers: { AccessToken: '' } })
:在getWenDu
函数中,使用 Axios 发送一个 GET 请求到'url'
(这里需要替换为实际的 API URL)。请求的头部包含一个名为AccessToken
的字段,用于身份验证(实际使用时需要填入有效的访问令牌).const getWenDu_Value = ref("无法找到温度值!")
:创建一个名为getWenDu_Value
的响应式引用,并初始化为字符串"无法找到温度值!"
。这个变量将用于存储并显示获取到的温度值.onMounted(async()=>{...})
:在组件挂载后执行一个异步函数。这个函数将调用getWenDu
函数获取温度数据,并更新getWenDu_Value
的值.const data = getWenDu();
:调用getWenDu
函数并将其返回值(一个 Promise)赋值给变量data
。注意,这里应该使用await
关键字来等待 Promise 解析,否则data
将是一个未解析的 Promise 对象,而不是实际的请求结果.const {Unit,Value} = data.ResultObj;
:从data.ResultObj
中解构出Unit
和Value
。这里假定 API 返回的数据结构中包含一个名为ResultObj
的对象,该对象有Unit
和Value
两个属性,分别表示温度的单位和值。然而,由于上一步没有使用await
,这行代码实际上无法正确执行,因为data
并不是一个包含ResultObj
的对象.getWenDu_Value.value = Value+Unit
:将获取到的温度值和单位拼接成一个字符串,并更新getWenDu_Value
的值,以便在页面上显示
- 同源策略代理服务器代码
const path = require('path')
//数字孪生智慧xx管理平台
const { TITLE } = require('./public/aircity/Config')
const title = TITLE || '管廊综合管理系统'
module.exports = {
publicPath: '/',
devServer: {
// 配置服务器
open: false,
// 项目运行时候的端口号
port: 8090,
// https: false,
disableHostCheck: true,
overlay: {
warnings: true,
errors: true
},
proxy: {
'/api': {
target: 'http://127.0.0.1:8084/',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
},
//自己填写的代理服务器部分
'/myapi':{
target: 'http://api.nlecloud.com/',
changeOrigin: true,
pathRewrite: {
'^/myapi': ''
}
}
}
},
css: {
sourceMap: true, // 开启 CSS source maps
loaderOptions: {
sass: {
// prependData: "@import '@/styles/common.scss';"
additionalData: "@import '@/styles/common.scss';"
}
}
},
chainWebpack: config => {
config.plugin('html').tap(args => {
args[0].title = title
return args
})
if (process.env.NODE_ENV === 'production') {
//生产包取消console debugger打印
config.optimization.minimizer('terser').tap(args => {
args[0].terserOptions.compress.drop_console = true
args[0].terserOptions.compress.drop_debugger = true
args[0].terserOptions.compress.pure_funcs = ['console.log']
args[0].terserOptions.output = {
comments: false
}
return args
})
}
// 分析打包大小
if (process.env.npm_config_report) {
config.plugin('webpack-bundle-analyzer').use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin).end()
}
},
configureWebpack: {
resolve: {
// extensions: ['.js', '.vue', '.json', '.ts', '.tsx'] // 加入ts 和 tsx
extensions: ['.js', '.vue', '.json', '.ts', '.tsx'], // 加入ts 和 tsx
alias: {
'@': path.resolve(__dirname, 'src')
}
}
}
}
- 界面修改代码
<!--
* @Author: your name
* @Date: 2022-04-11 14:35:02
* @LastEditTime: 2024-12-30 12:11:31
* @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
* @FilePath: \FdInit\src\Views\home\EquipmentManagement\index.vue
-->
<!-- Equipment management 设备管理 -->
<template>
<Left_box>
<FirstTitle>管廊数据总览</FirstTitle>
<SecondTitle>管廊环境数据</SecondTitle>
<div class="index-list">
<div class="item">
<div class="icon">
<img src="@/assets/images/icon/温度.png" alt="" />
</div>
<div class="right">
<div class="label">温度</div>
<div class="count" style="color: #2d98ff">
{{wendu}}
<span>°</span>
</div>
</div>
</div>
<div class="item">
<div class="icon">
<img src="@/assets/images/icon/相对湿度.png" alt="" />
</div>
<div class="right">
<div class="label">湿度</div>
<div class="count" style="color: #ff6c83">
{{shidu}}
<span>%RH</span>
</div>
</div>
</div>
<div class="item">
<div class="icon">
<img src="@/assets/images/icon/甲烷.png" alt="" />
</div>
<div class="right">
<div class="label">甲烷</div>
<div class="count" style="color: #ff9433">
{{CH4}}
<span>ppm</span>
</div>
</div>
</div>
<div class="item">
<div class="icon">
<img src="@/assets/images/icon/一氧化碳.png" alt="" />
</div>
<div class="right">
<div class="label">一氧化碳</div>
<div class="count" style="color: #00ffff">
{{co}}
<span>ppm</span>
</div>
</div>
</div>
</div>
<!-- <SecondTitle>管廊环境数据</SecondTitle> -->
<div class="index-list">
<div class="item">
<div class="icon">
<img src="@/assets/images/icon/给水流量.png" alt="" />
</div>
<div class="right">
<div class="label">水流量</div>
<div class="count" style="color: #2d98ff">
{{getwater_one}}
<span>s</span>
</div>
</div>
</div>
<div class="item">
<div class="icon">
<img src="@/assets/images/icon/电流.png" alt="" />
</div>
<div class="right">
<div class="label">水浸</div>
<div class="count" style="color: #ff6c83">
{{ getWaterimmersion_one }}
<span></span>
</div>
</div>
</div>
<div class="item">
<div class="icon">
<img src="@/assets/images/icon/电压.png" alt="" />
</div>
<div class="right">
<div class="label">电压</div>
<div class="count" style="color: #ff9433">
{{getVoltage_one}}
<span>v</span>
</div>
</div>
</div>
<div class="item">
<div class="icon">
<img src="@/assets/images/icon/火警.png" alt="" />
</div>
<div class="right">
<div class="label">火焰</div>
<div class="count" style="color: #00ffff">
{{ getBattery_one }}
<span></span>
</div>
</div>
</div>
</div>
<!-- <SecondTitle>管廊环境数据</SecondTitle>
<LineChart /> -->
<SecondTitle>管廊数据图像</SecondTitle>
<!-- <LineEchart></LineEchart> -->
<!-- <PieEchart></PieEchart> -->
<!-- <RankChart /> -->
<ColumnarEchart></ColumnarEchart>
<chars></chars>
<!-- <LineEchart></LineEchart> -->
<!-- <ColumnarEchart></ColumnarEchart> -->
<!-- <chars></chars>
<chars12></chars12> -->
</Left_box>
<Right_box>
<FirstTitle>管线概况</FirstTitle>
<SecondTitle>设备状态</SecondTitle>
<div class="index-list">
<div class="item">
<div class="icon">
<img src="@/assets/images/icon/排风扇.png" alt="" />
</div>
<div class="right">
<div class="label">排风扇</div>
<div class="count" style="color: #2d98ff">
{{fan}}
<span></span>
</div>
</div>
</div>
<div class="item">
<div class="icon">
<img src="@/assets/images/icon/报警.png" alt="" />
</div>
<div class="right">
<div class="label">警示灯</div>
<div class="count" style="color: #ff6c83">
{{baojing}}
<span></span>
</div>
</div>
</div>
<div class="item">
<div class="icon">
<img src="@/assets/images/icon/甲烷.png" alt="" />
</div>
<div class="right">
<div class="label">甲烷</div>
<div class="count" style="color: #ff9433">
{{CH4}}
<span></span>
</div>
</div>
</div>
<div class="item">
<div class="icon">
<img src="@/assets/images/icon/一氧化碳.png" alt="" />
</div>
<div class="right">
<div class="label">一氧化碳</div>
<div class="count" style="color: #00ffff">
{{co}}
<span></span>
</div>
</div>
</div>
</div>
<FirstTitle>监控中心统计</FirstTitle>
<div class="index-list">
<div class="item">
<div class="icon">
<img src="@/assets/images/icon/shanshuo.png" alt="" />
</div>
<div class="right">
<div class="label">总监控中心</div>
<div class="count" style="color: #ff9433">
1
<span>个</span>
</div>
</div>
</div>
<div class="item">
<div class="icon">
<img src="@/assets/images/icon/shiwujiaoxing.png" alt="" />
</div>
<div class="right">
<div class="label">分监控中心</div>
<div class="count" style="color: #00ffff">
7
<span>个</span>
</div>
</div>
</div>
<div class="item">
<div class="icon">
<img src="@/assets/images/icon/guanxianchangdu.png" alt="" />
</div>
<div class="right">
<div class="label">热力管廊分区</div>
<div class="count" style="color: #2d98ff">
13
<span>个</span>
</div>
</div>
</div>
<div class="item">
<div class="icon">
<img src="@/assets/images/icon/guandao.png" alt="" />
</div>
<div class="right">
<div class="label">电力管廊分区</div>
<div class="count" style="color: #ff6c83">
16
<span>个</span>
</div>
</div>
</div>
</div>
<FirstTitle>设备总体架构</FirstTitle>
<div class="guihua">
<!-- <img src="@/assets/images/guihua.jpg" alt="" /> -->
<img src="@/assets/images/icon/one.jpg" alt="" />
<!-- <video src="rtsp://admin:iot789789789@192.168.1.200:554/stream2" typeof="video/rtsp"></video> -->
</div>
</Right_box>
</template>
<script lang="ts" setup>
import { onMounted,ref } from 'vue'
import { getBattery, getCO, getFan, getfire, getled, getMethane, getshidu, getVoltage, getwater, getWaterimmersion, getWenDu } from '@/api/demoAPI'
const wendu = ref("温度未找到!");
const shidu = ref("湿度未找到!");
const CH4 = ref("甲烷未找到!");
const co = ref("一氧化碳未找到!");
const getwater_one = ref("水流量未找到");
const getBattery_one = ref("TVOS未找到");
const getWaterimmersion_one = ref("电量未找到");
const getVoltage_one = ref("电压未找到");
const fan = ref("设备故障");
const baojing = ref("设备故障");
let intervalId = null;
let intervalId1 = null;
let intervalId2 = null;
let intervalId3 = null;
let intervalId4 = null;
let intervalId5 = null;
let intervalId6 = null;
let intervalId7 = null;
let intervalId8 = null;
let intervalId9 = null;
const one = async()=>
{
try {
const data = await getWenDu();
const {Value} = data.ResultObj; // 将响应数据赋值给响应式变量
wendu.value = Value;
} catch (error) {
console.error(error);
}
}
onMounted(async () => {
intervalId = setInterval(one, 0);
one();
});
const two = async()=>
{
try {
const data1 = await getshidu();
const {Value} = data1.ResultObj; // 将响应数据赋值给响应式变量
shidu.value = Value;
} catch (error) {
console.error(error);
}
}
onMounted(async () => {
intervalId1 = setInterval(two, 0);
three();
});
const three = async()=>
{
try {
const data2 = await getMethane();
const {Value} = data2.ResultObj; // 将响应数据赋值给响应式变量
CH4.value = Value;
} catch (error) {
console.error(error);
}
}
onMounted(async () => {
intervalId2 = setInterval(three, 0);
three();
});
const four = async()=>
{
try {
const data3 = await getCO();
const {Value} = data3.ResultObj; // 将响应数据赋值给响应式变量
co.value = Value;
} catch (error) {
console.error(error);
}
}
onMounted(async () => {
intervalId3 = setInterval(four, 0);
four();
});
const five = async()=>
{
try {
const data4 = await getCO();
const {Value} = data4.ResultObj; // 将响应数据赋值给响应式变量
getwater_one.value = Value;
} catch (error) {
console.error(error);
}
}
onMounted(async () => {
intervalId4 = setInterval(five, 0);
five();
});
const six = async()=>
{
try {
const data4 = await getWaterimmersion();
const {Value} = data4.ResultObj; // 将响应数据赋值给响应式变量
getWaterimmersion_one.value = Value;
} catch (error) {
console.error(error);
}
}
onMounted(async () => {
intervalId5 = setInterval(six, 0);
six();
});
const seven = async()=>
{
try {
const data4 = await getVoltage();
const {Value} = data4.ResultObj; // 将响应数据赋值给响应式变量
getVoltage_one.value =Value;
} catch (error) {
console.error(error);
}
}
onMounted(async () => {
intervalId6 = setInterval(seven, 0);
seven();
});
const eight = async()=>
{
try {
const data4 = await getfire();
const {Value} = data4.ResultObj; // 将响应数据赋值给响应式变量
getBattery_one.value = Value;
} catch (error) {
console.error(error);
}
}
onMounted(async () => {
intervalId7 = setInterval(eight, 0);
eight();
});
const nine = async()=>
{
try {
const data4 = await getFan();
const {Value} = data4.ResultObj; // 将响应数据赋值给响应式变量
if(Value==1)
{
fan.value = "排风扇启动"
}
else{
fan.value = "排风扇关闭"
}
} catch (error) {
console.error(error);
}
}
onMounted(async () => {
intervalId8 = setInterval(nine, 0);
nine();
});
const ten = async()=>
{
try {
const data4 = await getled();
const {Value} = data4.ResultObj; // 将响应数据赋值给响应式变量
if(Value==1)
{
baojing.value = "报警"
}
else{
baojing.value = "正常"
}
} catch (error) {
console.error(error);
}
}
onMounted(async () => {
intervalId9 = setInterval(ten, 0);
ten();
});
import Left_box from '@/components/left_box.vue'
import Right_box from '@/components/right_box.vue'
//import RanderChart from '../monitoringPanel/RanderChart.vue'
import ColumnarEchart from '../../EnvironmentalMonitoring/cpnsEquipment/ColumnarEchart.vue'
import chars from '../../EnvironmentalMonitoring/cpnsEquipment/chars.vue';
//import chars from '../../EnvironmentalMonitoring/cpnsEquipment/chars.vue';
//import chars12 from '../../EnvironmentalMonitoring/cpnsEquipment/chars.vue'
import PieEchart from '../../PipeGalleryOverview/cpnsCabin/PieEchart.vue'
import LineEchart from '../../PipeGalleryOverview/cpnsCabin/LineEchart.vue'
import LineChart from './LineChart.vue'
import RankChart from './RankChart.vue'
import PieChart from './PieChart.vue'
</script>
<style lang="scss" scoped>
.index-list {
display: flex;
flex-wrap: wrap;
.item {
display: flex;
align-items: center;
width: 50%;
@include MarginBottom(10);
padding: 5px 5px;
.icon {
width: 40px;
height: 40px;
margin-right: 5px;
img {
width: 100%;
height: 100%;
}
}
.label {
@include MarginBottom(10);
}
.count {
font-family: HuXiaoBo-NanShen;
span {
font-family: Oppo;
color: #aaa;
@include FontSize(14);
}
}
}
}
.guihua {
@include Width(400);
padding: 10px;
img {
width: 100%;
}
}
</style>
- 图表的修改代码
<!--
* @Author: your name
* @Date: 2022-02-26 17:41:48
* @LastEditTime: 2024-12-30 09:20:58
* @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
* @FilePath: \DTSWeekly_zhyq\src\Views\home\First\left\two.vue
-->
<!-- two -->
<template>
<V3Echarts :height="200" :options="option" :top="10" container="container3" />
</template>
<script lang="ts" setup>
const xData = ['温度', '湿度', '甲烷', '一氧化碳']
import * as echarts from 'echarts'
import V3Echarts from '@/components/V3Echarts/index.vue'
import { onMounted,ref } from 'vue'
import { getBattery, getCO, getFan, getled, getMethane, getshidu, getVoltage, getwater, getWaterimmersion, getWenDu } from '@/api/demoAPI'
import { values } from 'lodash'
const wendu = ref("温度未找到!");
const shidu = ref("湿度未找到!");
const CH4 = ref("甲烷未找到!");
const co = ref("一氧化碳未找到!");
const getwater_one = ref("水流量未找到");
const getBattery_one = ref("TVOS未找到");
const getWaterimmersion_one = ref("电量未找到");
const getVoltage_one = ref("电压未找到");
let intervalId = null;
let intervalId1 = null;
let intervalId2 = null;
let intervalId3 = null;
let intervalId4 = null;
let intervalId5 = null;
let intervalId6 = null;
let intervalId7 = null;
const ydata = ref([
[], // 温度数据
[], // 湿度数据
[], // 甲烷数据
[], // 一氧化碳数据
]);
const one = async()=>
{
try {
const data = await getWenDu();
const {Value} = data.ResultObj; // 将响应数据赋值给响应式变量
wendu.value = Value;
ydata.value[0] = Value;
} catch (error) {
console.error(error);
}
}
onMounted(async () => {
intervalId = setInterval(one, 0);
one();
});
const two = async()=>
{
try {
const data1 = await getshidu();
const {Value} = data1.ResultObj; // 将响应数据赋值给响应式变量
ydata.value[1] = Value;
shidu.value = Value;
} catch (error) {
console.error(error);
}
}
onMounted(async () => {
intervalId1 = setInterval(two, 0);
three();
});
const three = async()=>
{
try {
const data2 = await getMethane();
const {Value} = data2.ResultObj; // 将响应数据赋值给响应式变量
ydata.value[2] = Value;
CH4.value = Value;
} catch (error) {
console.error(error);
}
}
onMounted(async () => {
intervalId2 = setInterval(three, 0);
three();
});
const four = async()=>
{
try {
const data3 = await getCO();
const {Value} = data3.ResultObj; // 将响应数据赋值给响应式变量
ydata.value[3] = Value;
// console.log("一氧化碳"+ydata.value[3]);
co.value = Value;
} catch (error) {
console.error(error);
}
}
onMounted(async () => {
intervalId3 = setInterval(four, 0);
four();
});
const five = async()=>
{
try {
const data4 = await getCO();
const {Value} = data4.ResultObj; // 将响应数据赋值给响应式变量
getwater_one.value = Value;
} catch (error) {
console.error(error);
}
}
onMounted(async () => {
intervalId4 = setInterval(five, 0);
five();
});
const six = async()=>
{
try {
const data4 = await getWaterimmersion();
const {Value} = data4.ResultObj; // 将响应数据赋值给响应式变量
getWaterimmersion_one.value = Value;
} catch (error) {
console.error(error);
}
}
onMounted(async () => {
intervalId5 = setInterval(six, 0);
six();
});
const seven = async()=>
{
try {
const data4 = await getVoltage();
const {Value} = data4.ResultObj; // 将响应数据赋值给响应式变量
getVoltage_one.value =Value;
} catch (error) {
console.error(error);
}
}
onMounted(async () => {
intervalId6 = setInterval(seven, 0);
seven();
});
const eight = async()=>
{
try {
const data4 = await getBattery();
const {Value} = data4.ResultObj; // 将响应数据赋值给响应式变量
getBattery_one.value = Value;
} catch (error) {
console.error(error);
}
}
onMounted(async () => {
intervalId7 = setInterval(eight, 0);
eight();
});
const option = {
grid: {
top: '25%',
left: '-5%',
bottom: '5%',
right: '5%',
containLabel: true
},
tooltip: {
show: true
},
animation: false,
xAxis: [
{
type: 'category',
data: xData,
axisTick: {
alignWithLabel: true
},
nameTextStyle: {
color: '#82b0ec'
},
axisLine: {
show: false,
lineStyle: {
color: '#82b0ec'
}
},
axisLabel: {
show: true,
color: '#00c7ff',
margin: 30
}
}
],
yAxis: [
{
show: false,
type: 'value',
axisLabel: {
color: '#fff'
},
splitLine: {
lineStyle: {
color: '#0c2c5a'
}
},
axisLine: {
show: false
}
}
],
series: [
{
name: '',
type: 'pictorialBar',
symbolSize: [40, 10],
symbolOffset: [0, -6],
symbolPosition: 'end',
z: 12,
// "barWidth": "0",
label: {
show: true,
position: 'top',
// "formatter": "{c}%"
fontSize: 15,
fontWeight: 'bold',
color: '#34DCFF'
},
color: '#2DB1EF',
data: ydata.value
},
{
name: '',
type: 'pictorialBar',
symbolSize: [40, 10],
symbolOffset: [0, 7],
// "barWidth": "20",
z: 12,
color: '#2DB1EF',
data: ydata.value
},
{
name: '',
type: 'pictorialBar',
symbolSize: [50, 15],
symbolOffset: [0, 12],
z: 10,
itemStyle: {
color: 'transparent',
borderColor: '#2EA9E5',
borderType: 'solid',
borderWidth: 1
},
data: ydata.value
},
{
name: '',
type: 'pictorialBar',
symbolSize: [70, 20],
symbolOffset: [0, 18],
z: 10,
itemStyle: {
color: 'transparent',
borderColor: '#19465D',
borderType: 'solid',
borderWidth: 2
},
data: ydata.value
},
{
type: 'bar',
//silent: true,
barWidth: '40',
barGap: '10%', // Make series be overlap
barCateGoryGap: '10%',
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 0.7, [
{
offset: 0,
color: '#38B2E6'
},
{
offset: 1,
color: '#0B3147'
}
]),
opacity: 0.8
},
data: ydata.value
}
]
}
</script>
<style lang="scss" scoped></style>
我的代码缺点:定时器数量太多且定时太快,新大陆的参数底线为3s,容易拖死网关与资源占用过大,建议加入定时器销毁与需要定时时间减少定时器数量。
太极平台使用注意点:
- 电脑系统重启或关机重启后需要重新微信登陆
- 平台的免费使用时间可在许可证web界面查看
- 因为官方开放的源码底层规定了需要通过websocket协议连接上服务器使用cloud服务所以当你未启动taichi软件的服务时会出现如下情况:
- 如果用于比赛的话请先确定比赛是否可以使用外网
后话关于taichi软件的登陆问题笔者曾尝试逆向解析软件代码修改登陆token的保存代码与修改底层代码逻辑由于时间与各种因素最终放弃了。引用林纳斯·托瓦兹大佬的一句话"开源社区的凝聚力在于共同的目标和价值观"。在此提醒:开源不等于拥有一切,请遵守约定好的开源协议与尊重开源作者的劳动成果,再次感谢飞渡科技的太极开发者平台。以及我对曾经尝试逆向解析软件代码的行为向各位官方大佬郑重道歉。
结语:朝乾夕惕,功不唐捐,玉汝于成