| | |
| | | "axios": "^1.4.0", |
| | | "element-plus": "^2.3.6", |
| | | "jquery": "^3.7.0", |
| | | "js-md5": "^0.7.3", |
| | | "pinia": "^2.1.4", |
| | | "vue": "^3.3.4", |
| | | "vue-router": "^4.2.2" |
| | |
| | | "version": "3.7.0", |
| | | "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.0.tgz", |
| | | "integrity": "sha512-umpJ0/k8X0MvD1ds0P9SfowREz2LenHsQaxSohMZ5OMNEU2r0tf8pdeEFTHMFxWVxKNyU9rTtK3CWzUCTKJUeQ==" |
| | | }, |
| | | "node_modules/js-md5": { |
| | | "version": "0.7.3", |
| | | "resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.7.3.tgz", |
| | | "integrity": "sha512-ZC41vPSTLKGwIRjqDh8DfXoCrdQIyBgspJVPXHBGu4nZlAEvG3nf+jO9avM9RmLiGakg7vz974ms99nEV0tmTQ==" |
| | | }, |
| | | "node_modules/kolorist": { |
| | | "version": "1.8.0", |
| | |
| | | "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.0.tgz", |
| | | "integrity": "sha512-umpJ0/k8X0MvD1ds0P9SfowREz2LenHsQaxSohMZ5OMNEU2r0tf8pdeEFTHMFxWVxKNyU9rTtK3CWzUCTKJUeQ==" |
| | | }, |
| | | "js-md5": { |
| | | "version": "0.7.3", |
| | | "resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.7.3.tgz", |
| | | "integrity": "sha512-ZC41vPSTLKGwIRjqDh8DfXoCrdQIyBgspJVPXHBGu4nZlAEvG3nf+jO9avM9RmLiGakg7vz974ms99nEV0tmTQ==" |
| | | }, |
| | | "kolorist": { |
| | | "version": "1.8.0", |
| | | "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", |
| | |
| | | "axios": "^1.4.0", |
| | | "element-plus": "^2.3.6", |
| | | "jquery": "^3.7.0", |
| | | "js-md5": "^0.7.3", |
| | | "pinia": "^2.1.4", |
| | | "vue": "^3.3.4", |
| | | "vue-router": "^4.2.2" |
New file |
| | |
| | | import axios from 'axios'; |
| | | if (import.meta.env.VITE_APP_ENV === 'dev') { |
| | | // 跨域请求 |
| | | axios.defaults.baseURL = 'http://localhost:8101/envir/'; |
| | | axios.defaults.withCredentials = true; // 保持请求头 |
| | | } else { |
| | | axios.defaults.baseURL = location.protocol + '//' + location.host + '/envir/'; |
| | | } |
| | | |
| | | // 添加请求拦截器 |
| | | axios.interceptors.request.use(function (config) { |
| | | // 在发送请求之前做些什么 |
| | | return config; |
| | | }, function (error) { |
| | | // 对请求错误做些什么 |
| | | return Promise.reject(error); |
| | | }); |
| | | |
| | | // 添加响应拦截器 |
| | | axios.interceptors.response.use(function (response) { |
| | | // 对响应数据做点什么 |
| | | return response; |
| | | }, function (error) { |
| | | return Promise.reject(error); |
| | | }); |
| | | |
| | | export default axios; |
New file |
| | |
| | | export default { |
| | | cmd: { |
| | | get: 0x20, // 读取 |
| | | set: 0x22, // 设置 |
| | | |
| | | startWork: 0x30, // 启动空调工作 |
| | | stopWork: 0x32, // 停止空调工作 |
| | | |
| | | startOnDuty: 0x34, // 启动空调值班 |
| | | stopOnDuty: 0x36, // 停止空调值班 |
| | | |
| | | startDisinfect: 0x38, // 启动空调消毒 |
| | | stopDisinfect: 0x3A, // 停止空调消毒 |
| | | |
| | | startExhaustFan: 0x3C, // 启动空调排风机启动 |
| | | stopExhaustFan: 0x3E // 停止空调排风机 |
| | | } |
| | | } |
New file |
| | |
| | | import randomString from "@/assets/js/tools/randomString"; |
| | | import md5 from "js-md5"; |
| | | |
| | | function rejectReplay() { |
| | | let t = sessionStorage.getItem("serverStamp") || new Date().getTime()+""; |
| | | let rd = randomString(10); |
| | | let sign = getSign(t, rd); |
| | | return 't='+t+"&sign="+sign+"&rd="+rd; |
| | | } |
| | | |
| | | function getSign(time, randomStr) { |
| | | let usefulNum = randomStr; |
| | | //加盐方式,根据末尾的值进行不同的加密规则 |
| | | let lastChar = time.charAt(12); |
| | | let lastNum = Number(lastChar); |
| | | let reg = new RegExp(lastChar, 'g'); |
| | | switch (lastNum){ |
| | | //在第一位加字符串 rd@c3doed |
| | | case 0: usefulNum += time.replace(reg,"rd@c3dozero");break; |
| | | case 1: usefulNum += time.replace(reg,"rd@c3doenoe");break; |
| | | case 2: usefulNum += time.replace(reg,"rd@c3doktwo");break; |
| | | case 3: usefulNum += time.replace(reg,"rd@c3dolthree");break; |
| | | case 4: usefulNum += time.replace(reg,"rd@c3doexfour");break; |
| | | case 5: usefulNum += time.replace(reg,"rd@c3doedefive");break; |
| | | case 6: usefulNum += time.replace(reg,"rd@c3doedhsix");break; |
| | | case 7: usefulNum += time.replace(reg,"rd@c3doedtseven");break; |
| | | case 8: usefulNum += time.replace(reg,"rd@c3doedbeight");break; |
| | | case 9: usefulNum += time.replace(reg,"rd@c3doedrnine");break; |
| | | } |
| | | //MD5加密后 |
| | | let signNow = md5(usefulNum); |
| | | let sb = ""; |
| | | for (let i = 0; i < 10; i++) { |
| | | sb += signNow.charAt(i*2); |
| | | } |
| | | let signResult = sb+signNow; |
| | | return signResult; |
| | | } |
| | | |
| | | export default rejectReplay; |
| | |
| | | } |
| | | |
| | | const WSInit = ()=>{ |
| | | console.log(isWSOpen); |
| | | // 未被初始化初始化 |
| | | if (!isWSOpen.value) { |
| | | console.log('=====WSinit, url:', wsUri); |
| | |
| | | import FlexBox from "@/components/FlexBox.vue"; |
| | | import {DArrowRight, CaretTop} from "@element-plus/icons-vue"; |
| | | import HdwLight from "@/components/HdwLight.vue"; |
| | | import runMonitorModule from "@/views/airConditioning/js/runMonitorModule"; |
| | | const {runMonitorData} = runMonitorModule(); |
| | | import {watch} from "vue"; |
| | | |
| | | import paramsMonitorModule from "@/views/airConditioning/js/paramsMonitorModule"; |
| | | const {paramsMonitorData} = paramsMonitorModule(); |
| | | import runMonitorModule from "@/views/airConditioning/js/runMonitorModule"; |
| | | const {runMonitorData, setRunMonitorData} = runMonitorModule(); |
| | | |
| | | import airMonitorData from "@/views/airConditioning/js/airMonitorData"; |
| | | const {monitorData, airState} = airMonitorData(); |
| | | |
| | | import airControlModule from "@/views/airConditioning/js/airControlModule"; |
| | | |
| | | const { |
| | | airParam, |
| | | getParam, |
| | | } = airControlModule(); |
| | | |
| | | watch(monitorData, (data)=>{ |
| | | setRunMonitorData(data); |
| | | }); |
| | | |
| | | |
| | | </script> |
| | | |
| | | <template> |
| | |
| | | <div class="input-box-list"> |
| | | <div class="input-box-wrapper"> |
| | | <div class="input-box-container"> |
| | | <div class="input-text">加热器运行状态</div> |
| | | <div class="input-text">空调运行状态</div> |
| | | <div class="input-light"> |
| | | <hdw-light :type="0"></hdw-light> |
| | | </div> |
| | | </div> |
| | | <div class="input-box-container"> |
| | | <div class="input-text">加热器运行状态</div> |
| | | <div class="input-light"> |
| | | <hdw-light :type="0"></hdw-light> |
| | | <hdw-light :type="airState.airSysstate"></hdw-light> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="input-box-wrapper"> |
| | | <div class="input-box-container"> |
| | | <div class="input-text">加热器运行状态</div> |
| | | <div class="input-text">值班运行状态</div> |
| | | <div class="input-light"> |
| | | <hdw-light :type="0"></hdw-light> |
| | | </div> |
| | | </div> |
| | | <div class="input-box-container"> |
| | | <div class="input-text">加热器运行状态</div> |
| | | <div class="input-light"> |
| | | <hdw-light :type="0"></hdw-light> |
| | | <hdw-light :type="airState.airOnduty"></hdw-light> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="input-box-wrapper"> |
| | | <div class="input-box-container"> |
| | | <div class="input-text">加热器运行状态</div> |
| | | <div class="input-text">负压/排浊运行状态</div> |
| | | <div class="input-light"> |
| | | <hdw-light :type="0"></hdw-light> |
| | | <hdw-light :type="airState.airPressturbid"></hdw-light> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="input-box-wrapper"> |
| | | <div class="input-box-container"> |
| | | <div class="input-text">系统故障</div> |
| | | <div class="input-light"> |
| | | <hdw-light :type="airState.airSysAlm"></hdw-light> |
| | | </div> |
| | | </div> |
| | | <div class="input-box-container"> |
| | | <div class="input-text">加热器运行状态</div> |
| | | <div class="input-text">过滤告警</div> |
| | | <div class="input-light"> |
| | | <hdw-light :type="0"></hdw-light> |
| | | <hdw-light :type="airState.airFiltrationAlm"></hdw-light> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | </div> |
| | | <div class="flex-layout--body"> |
| | | <div class="move-img"> |
| | | <div class="handle-tools"> |
| | | <div class="tools-btn-list"> |
| | | <div class="tools-btn-item"> |
| | | <el-button type="primary" @click="getParam">空调参数设置</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="tools-btn-list"> |
| | | <div class="tools-btn-item"> |
| | | <el-button type="primary">启动空调值班</el-button> |
| | | </div> |
| | | <div class="tools-btn-item"> |
| | | <el-button type="warning">停止空调值班</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="tools-btn-list"> |
| | | <div class="tools-btn-item"> |
| | | <el-button type="primary">启动空调消毒</el-button> |
| | | </div> |
| | | <div class="tools-btn-item"> |
| | | <el-button type="warning">停止空调消毒</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="tools-btn-list"> |
| | | <div class="tools-btn-item"> |
| | | <el-button type="primary">启动空调排风</el-button> |
| | | </div> |
| | | <div class="tools-btn-item"> |
| | | <el-button type="warning">停止空调排风</el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <flex-box> |
| | | <template #header> |
| | | <div class="header-wrapper"> |
| | |
| | | </flex-box> |
| | | </div> |
| | | </div> |
| | | <div class="page-right"> |
| | | <div class="flex-layout--container"> |
| | | <div class="flex-layout--body"> |
| | | <div class="air-params-monitor-wrapper"> |
| | | <flex-box> |
| | | <template #header> |
| | | <div class="header-wrapper"> |
| | | <el-icon><DArrowRight /></el-icon> |
| | | <span class="title-text">空调参数监控</span> |
| | | </div> |
| | | </template> |
| | | <div class="air-params-monitor"> |
| | | <div class="input-list"> |
| | | <div class="input-item" v-for="(item, index) in paramsMonitorData" :key="'key'+index"> |
| | | <div class="input-box input-text">{{ item.label }}</div> |
| | | <div class="input-box input-content">{{ item.value }}</div> |
| | | <div class="input-box input-unit">{{ item.unit }}</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </flex-box> |
| | | </div> |
| | | </div> |
| | | <div class="flex-layout--body"> |
| | | <div class="air-warn-monitor-wrapper"> |
| | | <flex-box> |
| | | <template #header> |
| | | <div class="header-wrapper"> |
| | | <el-icon><DArrowRight /></el-icon> |
| | | <span class="title-text">空调报警监控</span> |
| | | </div> |
| | | </template> |
| | | <div class="air-warn-monitor"> |
| | | <div class="input-box-list"> |
| | | <div class="input-box-wrapper"> |
| | | <div class="input-box-container"> |
| | | <div class="input-text">加热器运行状态</div> |
| | | <div class="input-light"> |
| | | <hdw-light :type="0"></hdw-light> |
| | | </div> |
| | | </div> |
| | | <div class="input-box-container"> |
| | | <div class="input-text">加热器运行状态</div> |
| | | <div class="input-light"> |
| | | <hdw-light :type="0"></hdw-light> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </flex-box> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | padding: 4px 0; |
| | | } |
| | | .move-img { |
| | | position: relative; |
| | | height: 100%; |
| | | padding: 8px 0; |
| | | padding: 8px 8px 8px 0; |
| | | box-sizing: border-box; |
| | | } |
| | | .state-list { |
| | |
| | | |
| | | .input-list { |
| | | .input-item { |
| | | text-align: center; |
| | | text-align: left; |
| | | margin-top: 16px; |
| | | .input-box { |
| | | display: inline-block; |
| | |
| | | &.input-content { |
| | | margin-left: 8px; |
| | | margin-right: 8px; |
| | | padding: 4px; |
| | | padding: 4px 12px; |
| | | min-width: 6rem; |
| | | background-color: #2c5774; |
| | | border: 1px solid #42d4ff; |
| | |
| | | height: 100%; |
| | | padding: 4px; |
| | | } |
| | | .handle-tools { |
| | | position: absolute; |
| | | right: 24px; |
| | | top: 40px; |
| | | z-index: 1; |
| | | } |
| | | .tools-btn-list { |
| | | margin-bottom: 32px; |
| | | |
| | | .tools-btn-item { |
| | | margin-top: 12px; |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | import {ref} from "vue"; |
| | | import air from "@/assets/js/const/air"; |
| | | import {getAirParam} from "@/views/airConditioning/js/api"; |
| | | const airControlModule = ()=>{ |
| | | const cmd = air.cmd; |
| | | const airParam = ref({ |
| | | num: 0, |
| | | devId: 0, |
| | | opCmd: 0, |
| | | stHumid: 0, |
| | | stTemp: 0, |
| | | }); |
| | | |
| | | /** |
| | | * 读取放电参数 |
| | | */ |
| | | const getParam = ()=>{ |
| | | getAirParam(210000001).then(res=>{ |
| | | console.log(res); |
| | | }).catch(error=>{ |
| | | console.log(error); |
| | | }); |
| | | } |
| | | |
| | | return { |
| | | airParam, |
| | | getParam, |
| | | }; |
| | | } |
| | | export default airControlModule; |
New file |
| | |
| | | import createWs from "@/assets/js/tools/websocket/createWs"; |
| | | import regEquipType from "@/assets/js/tools/regEquipType"; |
| | | import {ref, onMounted, computed} from "vue"; |
| | | |
| | | const airMonitorData = ()=>{ |
| | | const { |
| | | SOCKET |
| | | } = createWs("homePageSocket"); |
| | | const monitorData = ref({ |
| | | airFiltrationAlm: 0, // 过滤报警 【1报警,0不报警】 |
| | | airHumid: 0, // 空调湿度 |
| | | airOnduty: 0, // 值班运行状态 【1运行,0停止】 |
| | | airPressturbid: 0, // 负压/排浊【1运行,0不运行】 |
| | | airSysAlm: 0, // 系统故障【1报警,0不报警】 |
| | | airSysstate:0, // 空调运行状态【1.运行,0停止】 |
| | | airTemp: 0, // 温度 |
| | | commCount:140745, // 通信计数 |
| | | commErrCount: 0, // 错误计数 |
| | | devId: 210000001, // 设备ID |
| | | num: 1, // 主键 |
| | | recordTime: "2023-08-24 09:16:04", // 数据更新日期 |
| | | }); |
| | | const handleOpen = ()=>{} |
| | | const handleMessage = (res)=>{ |
| | | const rs = JSON.parse(res.data); |
| | | if(rs.code === 1 && rs.data) { |
| | | const list = rs.data2; |
| | | let data = { |
| | | airFiltrationAlm: 0, // 过滤报警 【1报警,0不报警】 |
| | | airHumid: 0, // 空调湿度 |
| | | airOnduty: 0, // 值班运行状态 【1运行,0停止】 |
| | | airPressturbid: 0, // 负压/排浊【1运行,0不运行】 |
| | | airSysAlm: 0, // 系统故障【1报警,0不报警】 |
| | | airSysstate:0, // 空调运行状态【1.运行,0停止】 |
| | | airTemp: 0, // 温度 |
| | | commCount:140745, // 通信计数 |
| | | commErrCount: 0, // 错误计数 |
| | | devId: 210000001, // 设备ID |
| | | num: 1, // 主键 |
| | | recordTime: "2023-08-24 09:16:04", // 数据更新日期 |
| | | }; |
| | | for(let i=0; i<list.length;i++) { |
| | | if(regEquipType(list[i].devId, 'air')) { |
| | | data = list[i].envirAirState; |
| | | break; |
| | | } |
| | | } |
| | | // 设置空调监控数据的值 |
| | | monitorData.value = data; |
| | | } |
| | | } |
| | | const airState = computed(()=>{ |
| | | const airPressturbid = monitorData.value.airPressturbid ===1?0:-1; |
| | | const airSysstate = monitorData.value.airSysstate ===1?0:-1; |
| | | const airOnduty = monitorData.value.airOnduty ===1?0:-1; |
| | | const airFiltrationAlm = monitorData.value.airFiltrationAlm ===1?1:0; |
| | | const airSysAlm = monitorData.value.airSysAlm ===1?1:0; |
| | | return { |
| | | airPressturbid, // 负压/排浊【1运行,0不运行】 |
| | | airSysstate, // 空调运行状态【1.运行,0停止】 |
| | | airOnduty, // 值班运行状态 【1运行,0停止】 |
| | | airFiltrationAlm, // 过滤报警 【1报警,0不报警】 |
| | | airSysAlm, // 系统故障【1报警,0不报警】 |
| | | }; |
| | | }); |
| | | onMounted(()=>{ |
| | | SOCKET.value.addEventListener("open", handleOpen, false); |
| | | SOCKET.value.addEventListener("message", handleMessage, false); |
| | | }); |
| | | |
| | | return { |
| | | monitorData, |
| | | airState |
| | | }; |
| | | } |
| | | |
| | | export default airMonitorData; |
New file |
| | |
| | | import axios from "@/assets/js/axios"; |
| | | |
| | | /** |
| | | * 读取参数 |
| | | * @return {*} |
| | | */ |
| | | export const getAirParam = (devId)=>{ |
| | | return axios({ |
| | | method: "GET", |
| | | url: "/envirParam/searchAir", |
| | | params: { |
| | | devId |
| | | } |
| | | }); |
| | | }; |
| | |
| | | import {reactive} from "vue"; |
| | | |
| | | const paramsMonitorModule = ()=>{ |
| | | const paramsMonitorData = reactive([ |
| | | { |
| | | label: "温度上限", |
| | | value: "℃" |
| | | }, |
| | | { |
| | | label: "温度下限", |
| | | value: 0, |
| | | unit: "℃" |
| | | }, |
| | | { |
| | | label: "湿度上限", |
| | | value: 0, |
| | | unit: "%" |
| | | }, |
| | | { |
| | | label: "湿度下限", |
| | | value: 0, |
| | | unit: "%" |
| | | }, |
| | | { |
| | | label: "温度设定值", |
| | | value: 0, |
| | | unit: "℃" |
| | | }, |
| | | { |
| | | label: "湿度设定值", |
| | | value: 0, |
| | | unit: "%" |
| | | }, |
| | | ]); |
| | | const paramsMonitorData = reactive(); |
| | | |
| | | return {paramsMonitorData}; |
| | | }; |
| | |
| | | const runMonitorModule = ()=>{ |
| | | const runMonitorData = reactive([ |
| | | { |
| | | label: "压缩机运行时间", |
| | | value: 0, |
| | | unit: "H" |
| | | }, |
| | | { |
| | | label: "加热需求", |
| | | value: 0, |
| | | unit: "%" |
| | | }, |
| | | { |
| | | label: "制冷需求", |
| | | value: 0, |
| | | unit: "%" |
| | | }, |
| | | { |
| | | label: "除湿需求", |
| | | value: 0, |
| | | unit: "%" |
| | | }, |
| | | { |
| | | label: "回风温度", |
| | | key: "airTemp", |
| | | label: "空调温度", |
| | | value: 0, |
| | | unit: "℃" |
| | | }, |
| | | { |
| | | label: "回风湿度", |
| | | key: "airHumid", |
| | | label: "空调湿度", |
| | | value: 0, |
| | | unit: "%" |
| | | }, |
| | | { |
| | | key: "commCount", |
| | | label: "通信计数", |
| | | value: 0, |
| | | unit: " " |
| | | }, |
| | | { |
| | | key: "commErrCount", |
| | | label: "错误计数", |
| | | value: 0, |
| | | unit: " " |
| | | }, |
| | | { |
| | | key: "recordTime", |
| | | label: "记录日期", |
| | | value: 0, |
| | | unit: " " |
| | | } |
| | | ]); |
| | | |
| | | return {runMonitorData}; |
| | | // 设置空调运行参数 |
| | | const setRunMonitorData = (data)=>{ |
| | | for(let i=0; i<runMonitorData.length; i++) { |
| | | let item = runMonitorData[i]; |
| | | item.value = data[item.key]!==undefined?data[item.key]:0; |
| | | } |
| | | |
| | | } |
| | | |
| | | return {runMonitorData, setRunMonitorData}; |
| | | }; |
| | | |
| | | export default runMonitorModule; |
| | |
| | | const rs = JSON.parse(res.data); |
| | | if(rs.code === 1 && rs.data) { |
| | | const data = rs.data2; |
| | | console.log(data); |
| | | for(let i=0; i<data.length;i++) { |
| | | let iData = data[i]; |
| | | for(let j=0; j<homeInfo.length; j++) { |
| | |
| | | WindiCSS(), |
| | | ], |
| | | server: { |
| | | port: 8080, |
| | | host: '0.0.0.0' |
| | | }, |
| | | resolve: { |