From 8ffb54b88e3907ea59c120d34a8cd9f486cc1151 Mon Sep 17 00:00:00 2001 From: he wei <858544502@qq.com> Date: 星期一, 13 一月 2025 16:37:36 +0800 Subject: [PATCH] U 提交 --- src/assets/js/toFixed.js | 10 package-lock.json | 100 ++++ src/hooks/useWebSocket.js | 148 +++++++ src/views/home/paramsContent.vue | 198 +++++++++ src/components/ycLight.vue | 24 + src/assets/js/axios.js | 31 + src/api/params.js | 96 ++++ src/styles/light.scss | 49 ++ src/views/home/index.vue | 151 +++++- package.json | 1 src/assets/js/getWsUrl.js | 23 + src/assets/js/const_digits.js | 10 src/hooks/useElement.js | 59 ++ src/styles/index.scss | 1 src/views/home/StateInfo.vue | 355 ++++++++++++--- 15 files changed, 1,137 insertions(+), 119 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1139bed..083a91e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "power-test", "version": "0.0.0", "dependencies": { + "axios": "^1.7.2", "element-plus": "^2.8.8", "pinia": "^2.2.6", "vue": "^3.5.12", @@ -1940,6 +1941,23 @@ "resolved": "https://mirrors.huaweicloud.com/repository/npm/async-validator/-/async-validator-4.2.5.tgz", "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==" }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.7.8", + "resolved": "https://registry.npmmirror.com/axios/-/axios-1.7.8.tgz", + "integrity": "sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/birpc": { "version": "0.2.19", "resolved": "https://mirrors.huaweicloud.com/repository/npm/birpc/-/birpc-0.2.19.tgz", @@ -2050,6 +2068,18 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://mirrors.huaweicloud.com/repository/npm/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -2158,6 +2188,15 @@ }, "funding": { "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" } }, "node_modules/detect-libc": { @@ -2343,6 +2382,40 @@ }, "engines": { "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" } }, "node_modules/fs-extra": { @@ -2728,6 +2801,27 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/mitt": { "version": "3.0.1", "resolved": "https://mirrors.huaweicloud.com/repository/npm/mitt/-/mitt-3.0.1.tgz", @@ -2998,6 +3092,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, "node_modules/readdirp": { "version": "4.0.2", "resolved": "https://mirrors.huaweicloud.com/repository/npm/readdirp/-/readdirp-4.0.2.tgz", diff --git a/package.json b/package.json index 705f6ec..301d32c 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "element-plus": "^2.8.8", "pinia": "^2.2.6", "vue": "^3.5.12", + "axios": "^1.7.2", "vue-router": "^4.4.5" }, "devDependencies": { diff --git a/src/api/params.js b/src/api/params.js new file mode 100644 index 0000000..002e420 --- /dev/null +++ b/src/api/params.js @@ -0,0 +1,96 @@ +import axios from "@/assets/js/axios"; + +/** + * 璁剧疆鐢垫簮宸ヤ綔妯″紡:testModeSet(03-閫嗗彉骞剁綉06-PFC宸ヤ綔) + */ +export const controllTestModel = (powerId, testModeSet) => { + return axios({ + method: "GET", + url: "setParam/controllTestModel", + params: { + powerId, + testModeSet, + }, + }); +}; + +/** + * 璁剧疆LLCBuck鐢垫祦 + */ +export const controllLLCBuckCurr = (powerId, llcBuckcurrSet) => { + return axios({ + method: "GET", + url: "setParam/controllLLCBuckCurr", + params: { + powerId, + llcBuckcurrSet, + }, + }); +}; + +/** + * 璁剧疆LLCBuck鐢靛帇 + */ +export const controllLLCBuckVol = (powerId, llcBuckvolSet) => { + return axios({ + method: "GET", + url: "setParam/controllLLCBuckVol", + params: { + powerId, + llcBuckvolSet, + }, + }); +}; + +/** + * 璁剧疆PFC妯″紡VBus鐢靛帇 + */ +export const controllVBusVref = (powerId, vbusIrefSet) => { + return axios({ + method: "GET", + url: "setParam/controllVBusVref", + params: { + powerId, + vbusIrefSet, + }, + }); +}; + +/** + * 鎺у埗鐢垫簮寮�鏈� + */ +export const controllPowerOpen = (powerId) => { + return axios({ + method: "GET", + url: "setParam/controllPowerOpen", + params: { + powerId, + }, + }); +}; + +/** + * 鎺у埗鐢垫簮鍏虫満 + */ +export const controllPowerClose = (powerId) => { + return axios({ + method: "GET", + url: "setParam/controllPowerClose", + params: { + powerId, + }, + }); +}; + +/** + * 娓呴櫎鍙樻崲鍣ㄦ晠闅� + */ +export const controllClearAlm = (powerId) => { + return axios({ + method: "GET", + url: "setParam/controllClearAlm", + params: { + powerId, + }, + }); +}; \ No newline at end of file diff --git a/src/assets/js/axios.js b/src/assets/js/axios.js new file mode 100644 index 0000000..fa4fbcf --- /dev/null +++ b/src/assets/js/axios.js @@ -0,0 +1,31 @@ + +import axios from 'axios'; +if (process.env.NODE_ENV == 'development') { + // 璺ㄥ煙璇锋眰 + axios.defaults.baseURL = 'http://localhost:8101/fksf/'; + axios.defaults.withCredentials = true; // 淇濇寔璇锋眰澶� +} else { + axios.defaults.baseURL = location.protocol + '//' + location.host + '/fksf/'; +} + +let skipUrls = []; + +// 娣诲姞璇锋眰鎷︽埅鍣� +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; diff --git a/src/assets/js/const_digits.js b/src/assets/js/const_digits.js new file mode 100644 index 0000000..0f44e2e --- /dev/null +++ b/src/assets/js/const_digits.js @@ -0,0 +1,10 @@ +export default { + // 鐢靛帇淇濈暀3浣嶅皬鏁� + VOL: 3, + // 鐢垫祦淇濈暀1浣嶅皬鏁� + CURR: 1, + // 娓╁害淇濈暀1浣嶅皬鏁� + TEMP: 1, + // 棰戠巼 + FREQ: 1, +}; diff --git a/src/assets/js/getWsUrl.js b/src/assets/js/getWsUrl.js new file mode 100644 index 0000000..f8666e1 --- /dev/null +++ b/src/assets/js/getWsUrl.js @@ -0,0 +1,23 @@ +/** + * 鑾峰彇Websocket鐨勮繛鎺� + * @param action + * @returns {string} + */ +function getWsUrl(action, port) { + let _port = port ? port : 8101; + let hostname = window.location.hostname; + let wsProtocol = "ws://"; + if (window.location.protocol == "https:") { + wsProtocol = "wss://"; + } + if (process.env.NODE_ENV == "development") { + hostname = "localhost"; + } else { + _port = window.location.port; + } + // 澶勭悊绔彛涓�80 + _port = _port == 80 ? "" : ":" + _port; + return wsProtocol + hostname + _port + "/fksf/" + action; +} + +export default getWsUrl; diff --git a/src/assets/js/toFixed.js b/src/assets/js/toFixed.js new file mode 100644 index 0000000..ea6304f --- /dev/null +++ b/src/assets/js/toFixed.js @@ -0,0 +1,10 @@ +/** + * 鏁板�间繚鐣欐寚瀹氫綅鏁板皬鏁� + */ +export default function toFixed(value, bit) { + if (!value) { + return 0; + } + const num = Math.pow(10, bit); + return Math.round(value * num) / num; +} \ No newline at end of file diff --git a/src/components/ycLight.vue b/src/components/ycLight.vue new file mode 100644 index 0000000..dcfeaf6 --- /dev/null +++ b/src/components/ycLight.vue @@ -0,0 +1,24 @@ +<script setup> +import { ref } from "vue"; +const props = defineProps({ + error: { + type: Boolean, + default: false, + }, +}); +</script> + +<template> + <div class="light-wrapper"> + <div class="yc-light" :class="{ 'error-light': error }"></div> + </div> +</template> + +<style scoped lang="scss"> +.light-wrapper { + display: flex; + justify-content: center; + align-items: center; + height: 30px; +} +</style> diff --git a/src/hooks/useElement.js b/src/hooks/useElement.js new file mode 100644 index 0000000..9ff5857 --- /dev/null +++ b/src/hooks/useElement.js @@ -0,0 +1,59 @@ +import { ref, reactive } from "vue"; +import { ElMessageBox, ElMessage, ElLoading } from "element-plus"; + +export default () => { + const $message = ElMessage; + function $alert(title, fnCancel = () => {}) { + ElMessageBox.confirm(title, "绯荤粺鎻愮ず", { + confirmButtonText: "纭畾", + type: "warning", + showCancelButton: false, + center: true, + }) + .then(() => { + fnCancel(); + }) + .catch(() => { + fnCancel(); + }); + } + + function $confirm(operate, fnOk, fnCancel = () => {}) { + ElMessageBox.confirm(`璇风‘璁ゆ槸鍚�${operate}?`, "绯荤粺鎻愮ず", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning", + center: true, + }) + .then(() => { + fnOk(); + }) + .catch(() => { + fnCancel(); + }); + } + + function $loading(customOptions = {}) { + const defaultOptions = { + lock: true, + text: "Loading", + background: "rgba(0, 0, 0, 0.7)", + target: document.body, + // 鍙互娣诲姞鏇村榛樿閰嶇疆 + }; + + // 鍚堝苟榛樿閰嶇疆鍜岃嚜瀹氫箟閰嶇疆 + const options = { ...defaultOptions, ...customOptions }; + + // 璋冪敤Element UI鐨勫姞杞芥湇鍔� + const loadingInstance = ElLoading.service(options); + return loadingInstance; + // return () => { + // console.log('?', 'close', '============='); + + // loadingInstance.close(); + // }; + } + + return { $alert, $confirm, $message, $loading }; +}; diff --git a/src/hooks/useWebSocket.js b/src/hooks/useWebSocket.js new file mode 100644 index 0000000..d106f23 --- /dev/null +++ b/src/hooks/useWebSocket.js @@ -0,0 +1,148 @@ +// useWebSocket.js +import { + ref, + reactive, + onMounted, + onUnmounted, + onActivated, + onDeactivated, +} from "vue"; +import getWsUrl from "@/assets/js/getWsUrl"; + +export default function (url) { + url = getWsUrl(url); + // 閲嶈繛鏃堕棿闂撮殧 榛樿5绉� + const reConnectDelay = 5 * 1000; + + const socket = ref(null); + const isConnected = ref(false); + const message = ref(""); + let timer = null; + + const sendCallback = reactive([]); + + const connect = () => { + if (socket.value) { + socket.value.close(); + } + socket.value = new WebSocket(url); + + socket.value.onopen = () => { + isConnected.value = true; + console.log("WebSocket Connected, url: ", url); + sendCallback.forEach((v) => v()); + sendCallback.length = 0; + }; + + socket.value.onmessage = (event) => { + // 澶勭悊鎺ユ敹鍒扮殑娑堟伅 + // console.log("Received:", event.data); + // 鍙互鍦ㄨ繖閲岄�氳繃 emit 鍙戦�佹秷鎭埌缁勪欢 + message.value = event.data; + }; + + socket.value.onerror = (Event) => { + console.error("WebSocket Error:", Event, url); + WSClose(Event); + }; + + socket.value.onclose = WSClose; + + }; + + // 鍙戦�佹暟鎹� + const sendData = (data) => { + if (socket.value && socket.value.readyState === socket.value.OPEN) { + // console.log('send', data, '============='); + socket.value.send(data); + } else { + sendCallback.push(() => sendData(data)); + } + }; + + function WSClose(Event) { + isConnected.value = false; + if (socket.value) { + switch (socket.value.readyState) { + case 0: + socket.value.onopen = () => { + socket.value.close(); + console.log('閾炬帴鍏抽棴', url, 'close浜嬩欢瀵硅薄:', Event); + socket.value = null; + // 娌℃湁event瀵硅薄 鍒欎负鎵嬪姩鍏抽棴 + if (Event) { + reConnect(); + } + } + break; + case 1: + socket.value.close(); + console.log('閾炬帴鍏抽棴', url, 'close浜嬩欢瀵硅薄:', Event); + socket.value = null; + // 娌℃湁event瀵硅薄 鍒欎负鎵嬪姩鍏抽棴 + if (Event) { + reConnect(); + } + break; + case 2: + socket.value.onclose = () => { + console.log('閾炬帴鍏抽棴', url, 'close浜嬩欢瀵硅薄:', Event); + socket.value = null; + // 娌℃湁event瀵硅薄 鍒欎负鎵嬪姩鍏抽棴 + if (Event) { + reConnect(); + } + } + break; + case 3: + console.log('閾炬帴鍏抽棴', url, 'close浜嬩欢瀵硅薄:', Event); + socket.value = null; + // 娌℃湁event瀵硅薄 鍒欎负鎵嬪姩鍏抽棴 + if (Event) { + reConnect(); + } + break; + } + } + } + + // 閲嶈繛 + function reConnect() { + if (timer) { + return false; + } + timer = setTimeout(() => { + timer = null; + connect(); + }, reConnectDelay); + } + + onMounted(() => { + // console.log('socket mount', Date.now(), '============='); + console.log("on socket mount", url, "============="); + + connect(); + }); + + onActivated(() => { + if (!socket.value) { + console.log("on socket active", url, "============="); + connect(); + } + }); + + onDeactivated(() => { + if (socket.value) { + WSClose(); + } + }); + + onUnmounted(() => { + if (socket.value) { + WSClose(); + } + }); + + // 杩斿洖 socket 瀵硅薄鍜岀姸鎬� + return { socket, isConnected, message, sendData }; +} diff --git a/src/styles/index.scss b/src/styles/index.scss index 1dfcd40..9006af3 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -1,3 +1,4 @@ @use './reset'; @use './variable'; +@use './light'; @use './theme/index.scss'; diff --git a/src/styles/light.scss b/src/styles/light.scss new file mode 100644 index 0000000..6fb9fcd --- /dev/null +++ b/src/styles/light.scss @@ -0,0 +1,49 @@ +/* light */ +.yc-light { + position: relative; + display: inline-block; + width: 22px; + height: 22px; +} + +.yc-light:before { + content: ""; + display: inline-block; + position: absolute; + top: 50%; + left: 50%; + margin-top: -5px; + margin-left: -5px; + width: 10px; + height: 10px; + border-radius: 10px; + background-color: #4afd88; + box-shadow: 0 0 6px 6px #4afd8880; +} + +.yc-light.error-light:before { + background-color: #fd5b67; + animation: errorLight 1000ms infinite; + box-shadow: 0 0 6px 6px #fd586480; +} +.yc-light.gray-light:before { + background-color: #878787; + width: 12px; + height: 12px; + box-shadow: none; +} + +@keyframes errorLight { + 0% { + opacity: 1; + box-shadow: 0 0 6px 6px #fd586480; + } + 50% { + opacity: 0.3; + box-shadow: 0 0 0 0 #fd586480; + } + 100% { + opacity: 1; + box-shadow: 0 0 6px 6px #fd586480; + } +} \ No newline at end of file diff --git a/src/views/home/StateInfo.vue b/src/views/home/StateInfo.vue index cb0c339..74c6eca 100644 --- a/src/views/home/StateInfo.vue +++ b/src/views/home/StateInfo.vue @@ -1,24 +1,39 @@ -<script> +<script setup> import HdwBox from "@/components/HdwBox.vue"; +import { ref } from "vue"; +import ycLight from "@/components/ycLight.vue"; +import toFixed from "@/assets/js/toFixed.js"; +import const_digits from "@/assets/js/const_digits"; -export default { - name: "StateInfo" , - components: {HdwBox}, - data() { - return { - title: "鏍囬" - }; +const emit = defineEmits(["editParams", 'start', 'stop', 'clearAlarm']); +const { VOL, CURR, TEMP, FREQ } = const_digits; + +const props = defineProps({ + // title: { + // type: String, + // default: "鏍囬", + // }, + info: { + type: Object, + // default: () => { + // return {}; + // }, + required: true, }, -} +}); + </script> <template> - <hdw-box :title="title"> + <hdw-box :title="info.powerName"> <template #tools> - <el-button size="small" type="primary">鍚姩娴嬭瘯</el-button> + <el-button size="small" type="primary" @click="emit('clearAlarm')">娓呴櫎鏁呴殰</el-button> + <el-button size="small" type="primary" @click="emit('editParams')">淇敼鍙傛暟</el-button> + <el-button size="small" type="primary" v-if="!info.state?.powerWorkstat" @click="emit('start')">寮�鏈�</el-button> + <el-button size="small" type="primary" v-else @click="emit('stop')">鍏虫満</el-button> </template> <el-scrollbar> - <div class="state-info-title">IIC璇诲彇鏁版嵁</div> + <!-- <div class="state-info-title">IIC璇诲彇鏁版嵁</div> <div class="state-info-list-wrapper"> <el-row :gutter="0"> <el-col :span="8"> @@ -76,15 +91,17 @@ </div> </el-col> </el-row> - </div> - <div class="state-info-title adc">鍗曠墖鏈篈DC閲囨牱</div> + </div> --> + <!-- <div class="state-info-title adc">鍗曠墖鏈篈DC閲囨牱</div> --> <div class="state-info-list-wrapper"> <el-row :gutter="0"> <el-col :span="8"> <div class="state-info-item-wrapper"> <div class="state-info-label">A鐩哥數鍘�:</div> <div class="state-info-value-wrapper"> - <div class="state-info-value">0</div> + <div class="state-info-value"> + {{ toFixed(info.state?.vgridrmsVola, VOL) }} + </div> <div class="state-info-unit">V</div> </div> </div> @@ -93,7 +110,9 @@ <div class="state-info-item-wrapper"> <div class="state-info-label">B鐩哥數鍘�:</div> <div class="state-info-value-wrapper"> - <div class="state-info-value">0</div> + <div class="state-info-value"> + {{ toFixed(info.state?.vgridrmsVolb, VOL) }} + </div> <div class="state-info-unit">V</div> </div> </div> @@ -102,7 +121,9 @@ <div class="state-info-item-wrapper"> <div class="state-info-label">C鐩哥數鍘�:</div> <div class="state-info-value-wrapper"> - <div class="state-info-value">0</div> + <div class="state-info-value"> + {{ toFixed(info.state?.vgridrmsVolc, VOL) }} + </div> <div class="state-info-unit">V</div> </div> </div> @@ -111,7 +132,9 @@ <div class="state-info-item-wrapper"> <div class="state-info-label">A鐩哥數娴�:</div> <div class="state-info-value-wrapper"> - <div class="state-info-value">0</div> + <div class="state-info-value"> + {{ toFixed(info.state?.igridrmsCurra, CURR) }} + </div> <div class="state-info-unit">A</div> </div> </div> @@ -120,7 +143,9 @@ <div class="state-info-item-wrapper"> <div class="state-info-label">B鐩哥數娴�:</div> <div class="state-info-value-wrapper"> - <div class="state-info-value">0</div> + <div class="state-info-value"> + {{ toFixed(info.state?.igridrmsCurrb, CURR) }} + </div> <div class="state-info-unit">A</div> </div> </div> @@ -129,7 +154,9 @@ <div class="state-info-item-wrapper"> <div class="state-info-label">C鐩哥數娴�:</div> <div class="state-info-value-wrapper"> - <div class="state-info-value">0</div> + <div class="state-info-value"> + {{ toFixed(info.state?.igridrmsCurrc, CURR) }} + </div> <div class="state-info-unit">A</div> </div> </div> @@ -139,7 +166,7 @@ <div class="state-info-title line"></div> <div class="state-info-list-wrapper"> <el-row :gutter="0"> - <el-col :span="8"> + <!-- <el-col :span="8"> <div class="state-info-item-wrapper"> <div class="state-info-label">A鐩稿姛鐜�:</div> <div class="state-info-value-wrapper"> @@ -165,12 +192,12 @@ <div class="state-info-unit"></div> </div> </div> - </el-col> + </el-col> --> <el-col :span="8"> <div class="state-info-item-wrapper"> <div class="state-info-label">姣嶇嚎鐢靛帇:</div> <div class="state-info-value-wrapper"> - <div class="state-info-value">0</div> + <div class="state-info-value">{{ toFixed(info.state?.vbusVol, VOL) }}</div> <div class="state-info-unit">V</div> </div> </div> @@ -179,7 +206,7 @@ <div class="state-info-item-wrapper"> <div class="state-info-label">浜ゆ祦棰戠巼:</div> <div class="state-info-value-wrapper"> - <div class="state-info-value">0</div> + <div class="state-info-value">{{ toFixed(info.state?.gridFreq, FREQ) }}</div> <div class="state-info-unit">HZ</div> </div> </div> @@ -188,7 +215,9 @@ <div class="state-info-item-wrapper"> <div class="state-info-label">PCB娓╁害:</div> <div class="state-info-value-wrapper"> - <div class="state-info-value">0</div> + <div class="state-info-value"> + {{ toFixed(info.state?.degreeTemppcb, TEMP) }} + </div> <div class="state-info-unit">鈩�</div> </div> </div> @@ -197,7 +226,7 @@ <div class="state-info-item-wrapper"> <div class="state-info-label">BUS+姝g數鍘�:</div> <div class="state-info-value-wrapper"> - <div class="state-info-value">0</div> + <div class="state-info-value">{{ toFixed(info.state?.vmidVol, VOL) }}</div> <div class="state-info-unit">V</div> </div> </div> @@ -206,7 +235,9 @@ <div class="state-info-item-wrapper"> <div class="state-info-label">A鏁g儹鍣ㄦ俯搴�:</div> <div class="state-info-value-wrapper"> - <div class="state-info-value">0</div> + <div class="state-info-value"> + {{ toFixed(info.state?.degreeTempa, TEMP) }} + </div> <div class="state-info-unit">鈩�</div> </div> </div> @@ -215,7 +246,9 @@ <div class="state-info-item-wrapper"> <div class="state-info-label">B鏁g儹鍣ㄦ俯搴�:</div> <div class="state-info-value-wrapper"> - <div class="state-info-value">0</div> + <div class="state-info-value"> + {{ toFixed(info.state?.degreeTempb, TEMP) }} + </div> <div class="state-info-unit">鈩�</div> </div> </div> @@ -224,65 +257,204 @@ <div class="state-info-item-wrapper"> <div class="state-info-label">C鏁g儹鍣ㄦ俯搴�:</div> <div class="state-info-value-wrapper"> - <div class="state-info-value">0</div> + <div class="state-info-value"> + {{ toFixed(info.state?.degreeTempc, TEMP) }} + </div> <div class="state-info-unit">鈩�</div> </div> </div> </el-col> -<!-- <el-col :span="12">--> -<!-- <div class="state-info-item-wrapper">--> -<!-- <div class="state-info-label">A鐩哥數鍘嬫湁鏁堝��:</div>--> -<!-- <div class="state-info-value-wrapper">--> -<!-- <div class="state-info-value">0</div>--> -<!-- <div class="state-info-unit">V</div>--> -<!-- </div>--> -<!-- </div>--> -<!-- </el-col>--> -<!-- <el-col :span="12">--> -<!-- <div class="state-info-item-wrapper">--> -<!-- <div class="state-info-label">B鐩哥數鍘嬫湁鏁堝��:</div>--> -<!-- <div class="state-info-value-wrapper">--> -<!-- <div class="state-info-value">0</div>--> -<!-- <div class="state-info-unit">V</div>--> -<!-- </div>--> -<!-- </div>--> -<!-- </el-col>--> -<!-- <el-col :span="12">--> -<!-- <div class="state-info-item-wrapper">--> -<!-- <div class="state-info-label">C鐩哥數鍘嬫湁鏁堝��:</div>--> -<!-- <div class="state-info-value-wrapper">--> -<!-- <div class="state-info-value">0</div>--> -<!-- <div class="state-info-unit">C</div>--> -<!-- </div>--> -<!-- </div>--> -<!-- </el-col>--> -<!-- <el-col :span="12">--> -<!-- <div class="state-info-item-wrapper">--> -<!-- <div class="state-info-label large">A鐩哥數娴佹湁鏁堝��:</div>--> -<!-- <div class="state-info-value-wrapper">--> -<!-- <div class="state-info-value">0</div>--> -<!-- <div class="state-info-unit">A</div>--> -<!-- </div>--> -<!-- </div>--> -<!-- </el-col>--> -<!-- <el-col :span="12">--> -<!-- <div class="state-info-item-wrapper">--> -<!-- <div class="state-info-label large">B鐩哥數娴佹湁鏁堝��:</div>--> -<!-- <div class="state-info-value-wrapper">--> -<!-- <div class="state-info-value">0</div>--> -<!-- <div class="state-info-unit">A</div>--> -<!-- </div>--> -<!-- </div>--> -<!-- </el-col>--> -<!-- <el-col :span="12">--> -<!-- <div class="state-info-item-wrapper">--> -<!-- <div class="state-info-label">C鐩哥數娴佹湁鏁堝��:</div>--> -<!-- <div class="state-info-value-wrapper">--> -<!-- <div class="state-info-value">0</div>--> -<!-- <div class="state-info-unit">A</div>--> -<!-- </div>--> -<!-- </div>--> -<!-- </el-col>--> + <!-- <el-col :span="12">--> + <!-- <div class="state-info-item-wrapper">--> + <!-- <div class="state-info-label">A鐩哥數鍘嬫湁鏁堝��:</div>--> + <!-- <div class="state-info-value-wrapper">--> + <!-- <div class="state-info-value">0</div>--> + <!-- <div class="state-info-unit">V</div>--> + <!-- </div>--> + <!-- </div>--> + <!-- </el-col>--> + <!-- <el-col :span="12">--> + <!-- <div class="state-info-item-wrapper">--> + <!-- <div class="state-info-label">B鐩哥數鍘嬫湁鏁堝��:</div>--> + <!-- <div class="state-info-value-wrapper">--> + <!-- <div class="state-info-value">0</div>--> + <!-- <div class="state-info-unit">V</div>--> + <!-- </div>--> + <!-- </div>--> + <!-- </el-col>--> + <!-- <el-col :span="12">--> + <!-- <div class="state-info-item-wrapper">--> + <!-- <div class="state-info-label">C鐩哥數鍘嬫湁鏁堝��:</div>--> + <!-- <div class="state-info-value-wrapper">--> + <!-- <div class="state-info-value">0</div>--> + <!-- <div class="state-info-unit">C</div>--> + <!-- </div>--> + <!-- </div>--> + <!-- </el-col>--> + <!-- <el-col :span="12">--> + <!-- <div class="state-info-item-wrapper">--> + <!-- <div class="state-info-label large">A鐩哥數娴佹湁鏁堝��:</div>--> + <!-- <div class="state-info-value-wrapper">--> + <!-- <div class="state-info-value">0</div>--> + <!-- <div class="state-info-unit">A</div>--> + <!-- </div>--> + <!-- </div>--> + <!-- </el-col>--> + <!-- <el-col :span="12">--> + <!-- <div class="state-info-item-wrapper">--> + <!-- <div class="state-info-label large">B鐩哥數娴佹湁鏁堝��:</div>--> + <!-- <div class="state-info-value-wrapper">--> + <!-- <div class="state-info-value">0</div>--> + <!-- <div class="state-info-unit">A</div>--> + <!-- </div>--> + <!-- </div>--> + <!-- </el-col>--> + <!-- <el-col :span="12">--> + <!-- <div class="state-info-item-wrapper">--> + <!-- <div class="state-info-label">C鐩哥數娴佹湁鏁堝��:</div>--> + <!-- <div class="state-info-value-wrapper">--> + <!-- <div class="state-info-value">0</div>--> + <!-- <div class="state-info-unit">A</div>--> + <!-- </div>--> + <!-- </div>--> + <!-- </el-col>--> + </el-row> + </div> + <div class="state-info-title line"></div> + <div class="state-info-list-wrapper"> + <el-row :gutter="0"> + <el-col :span="8"> + <div class="state-info-item-wrapper alarm"> + <div class="label">A鐩歌繃娴�</div> + <div class="value"> + <yc-light :error="info.state?.acinOverCurra"></yc-light> + </div> + </div> + </el-col> + <el-col :span="8"> + <div class="state-info-item-wrapper alarm"> + <div class="label">B鐩歌繃娴�</div> + <div class="value"> + <yc-light :error="info.state?.acinOverCurrb"></yc-light> + </div> + </div> + </el-col> + <el-col :span="8"> + <div class="state-info-item-wrapper alarm"> + <div class="label">C鐩歌繃娴�</div> + <div class="value"> + <yc-light :error="info.state?.acinOverCurrc"></yc-light> + </div> + </div> + </el-col> + + <el-col :span="8"> + <div class="state-info-item-wrapper alarm"> + <div class="label">A鐩歌繃鍘�</div> + <div class="value"> + <yc-light :error="info.state?.vgridOverVola"></yc-light> + </div> + </div> + </el-col> + <el-col :span="8"> + <div class="state-info-item-wrapper alarm"> + <div class="label">B鐩歌繃鍘�</div> + <div class="value"> + <yc-light :error="info.state?.vgridOverVolb"></yc-light> + </div> + </div> + </el-col> + <el-col :span="8"> + <div class="state-info-item-wrapper alarm"> + <div class="label">C鐩歌繃鍘�</div> + <div class="value"> + <yc-light :error="info.state?.vgridOverVolc"></yc-light> + </div> + </div> + </el-col> + + <el-col :span="8"> + <div class="state-info-item-wrapper alarm"> + <div class="label">A鐩告瑺鍘�</div> + <div class="value"> + <yc-light :error="info.state?.vgridUnderVola"></yc-light> + </div> + </div> + </el-col> + <el-col :span="8"> + <div class="state-info-item-wrapper alarm"> + <div class="label">B鐩告瑺鍘�</div> + <div class="value"> + <yc-light :error="info.state?.vgridUnderVolb"></yc-light> + </div> + </div> + </el-col> + <el-col :span="8"> + <div class="state-info-item-wrapper alarm"> + <div class="label">C鐩告瑺鍘�</div> + <div class="value"> + <yc-light :error="info.state?.vgridUnderVolc"></yc-light> + </div> + </div> + </el-col> + <el-col :span="8"> + <div class="state-info-item-wrapper alarm"> + <div class="label">BUS杩囧帇</div> + <div class="value"> + <yc-light :error="info.state?.busOverVol"></yc-light> + </div> + </div> + </el-col> + <el-col :span="8"> + <div class="state-info-item-wrapper alarm"> + <div class="label">BUS娆犲帇</div> + <div class="value"> + <yc-light :error="info.state?.busUnderVol"></yc-light> + </div> + </div> + </el-col> + <el-col :span="8"> </el-col> + <el-col :span="12"> + <div class="state-info-item-wrapper alarm"> + <div class="label">A鏁g儹鍣ㄦ俯搴﹁繃娓�</div> + <div class="value"> + <yc-light :error="info.state?.mosaOverTemp"></yc-light> + </div> + </div> + </el-col> + <el-col :span="12"> + <div class="state-info-item-wrapper alarm"> + <div class="label">B鏁g儹鍣ㄦ俯搴﹁繃娓�</div> + <div class="value"> + <yc-light :error="info.state?.mosbOverTemp"></yc-light> + </div> + </div> + </el-col> + <el-col :span="12"> + <div class="state-info-item-wrapper alarm"> + <div class="label">C鏁g儹鍣ㄦ俯搴﹁繃娓�</div> + <div class="value"> + <yc-light :error="info.state?.moscOverTemp"></yc-light> + </div> + </div> + </el-col> + <el-col :span="12"></el-col> + <el-col :span="12"> + <div class="state-info-item-wrapper alarm"> + <div class="label">椋庢満鏁呴殰</div> + <div class="value"> + <yc-light :error="info.state?.fanAlarm"></yc-light> + </div> + </div> + </el-col> + <el-col :span="12"> + <div class="state-info-item-wrapper alarm"> + <div class="label">12V杈呭姪鐢垫簮鏁呴殰</div> + <div class="value"> + <yc-light :error="info.state?.vdc12vFault"></yc-light> + </div> + </div> + </el-col> </el-row> </div> </el-scrollbar> @@ -321,6 +493,23 @@ display: inline-block; } } + &.alarm { + display: flex; + flex-direction: row; + align-items: center; + padding: 0; + } + .label { + flex: 1; + text-align: right; + margin-right: 0.6em; + &::after { + content: ":"; + } + } + .value { + margin-right: 0.4em; + } } } .state-info-title { diff --git a/src/views/home/index.vue b/src/views/home/index.vue index b7c8db7..fd893f5 100644 --- a/src/views/home/index.vue +++ b/src/views/home/index.vue @@ -1,49 +1,128 @@ -<script> -import HdwBox from "@/components/HdwBox.vue"; +<script setup> +// import HdwBox from "@/components/HdwBox.vue"; import StateInfo from "@/views/home/StateInfo.vue"; +import ParamsContent from "@/views/home/paramsContent.vue"; +import { ref, watchEffect, onMounted, computed } from "vue"; +import useWebSocket from "@/hooks/useWebSocket.js"; +import useElement from "@/hooks/useElement.js"; +import { + controllPowerOpen, + controllPowerClose, + controllClearAlm, +} from "@/api/params"; +const { sendData, message } = useWebSocket("powerSocket"); +const { $alert, $loading, $message, $confirm } = useElement(); +const rtData = ref([]); +const paramsVisible = ref(false); +const currentIdx = ref(0); -export default { - name: "HomeView", - components: {StateInfo, HdwBox}, - data() { - return {} - }, - methods: { - - }, - mounted() { - +watchEffect(() => { + let _list = []; + if (message.value) { + const { code, data, data2 } = JSON.parse(message.value); + if (code && data) { + _list = data2; + } } + rtData.value = _list; +}); + +const title = computed(() => { + return `璁剧疆 妯″潡${currentIdx.value + 1} 鍙傛暟`; +}); + +function showParams(idx) { + currentIdx.value = idx; + paramsVisible.value = true; } +function start(idx) { + let loading = $loading(); + controllPowerOpen(rtData.value[idx].state.powerId) + .then((res) => { + let { code, data } = res.data; + loading.close(); + if (code && data) { + $message.success("鎿嶄綔鎴愬姛"); + } else { + $message.error("鎿嶄綔澶辫触"); + } + }) + .catch((err) => { + $message.error("鎿嶄綔澶辫触"); + loading.close(); + console.log(err); + }); +} +function stop(idx) { + let loading = $loading(); + controllPowerClose(rtData.value[idx].state.powerId) + .then((res) => { + let { code, data } = res.data; + loading.close(); + if (code && data) { + $message.success("鎿嶄綔鎴愬姛"); + } else { + $message.error("鎿嶄綔澶辫触"); + } + }) + .catch((err) => { + $message.error("鎿嶄綔澶辫触"); + loading.close(); + console.log(err); + }); +} +function clearAlarm(idx) { + let loading = $loading(); + controllClearAlm(rtData.value[idx].state.powerId) + .then((res) => { + let { code, data } = res.data; + loading.close(); + if (code && data) { + $message.success("鎿嶄綔鎴愬姛"); + } else { + $message.error("鎿嶄綔澶辫触"); + } + }) + .catch((err) => { + $message.error("鎿嶄綔澶辫触"); + loading.close(); + console.log(err); + }); +} + +onMounted(() => { + sendData(""); +}); </script> <template> <div class="home-view-wrapper"> - <div class="home-item"> - <state-info></state-info> - </div> - <div class="home-item"> - <state-info></state-info> - </div> - <div class="home-item"> - <state-info></state-info> - </div> - <div class="home-item"> - <state-info></state-info> - </div> - <div class="home-item"> - <state-info></state-info> - </div> - <div class="home-item"> - <state-info></state-info> - </div> - <div class="home-item"> - <state-info></state-info> - </div> - <div class="home-item"> - <state-info></state-info> + <div class="home-item" v-for="(item, idx) in 8" :key="'item_' + idx"> + <state-info + :info="rtData[idx] || {}" + @clearAlarm="clearAlarm(idx)" + @editParams="showParams(idx)" + @start="start(idx)" + @stop="stop(idx)" + ></state-info> </div> </div> + <!-- 寮圭獥 --> + <el-dialog + :title="title" + v-model="paramsVisible" + :close-on-click-modal="false" + class="dialog-center" + width="360px" + center + > + <params-content + v-model="paramsVisible" + v-if="paramsVisible" + :info="rtData[currentIdx]" + @setOk="sendData('')" + ></params-content> + </el-dialog> </template> <style scoped lang="scss"> diff --git a/src/views/home/paramsContent.vue b/src/views/home/paramsContent.vue new file mode 100644 index 0000000..b379815 --- /dev/null +++ b/src/views/home/paramsContent.vue @@ -0,0 +1,198 @@ +<script setup> +import { ref, computed, nextTick } from "vue"; +import { + controllTestModel, + controllLLCBuckCurr, + controllLLCBuckVol, + controllVBusVref, + controllPowerOpen, + controllPowerClose, +} from "@/api/params"; +import useElement from "@/hooks/useElement.js"; +const { $alert, $loading, $message, $confirm } = useElement(); + +const emit = defineEmits(["setOk"]); + +const props = defineProps({ + info: { + type: Object, + // default: () => { + // return {}; + // }, + required: true, + }, +}); +const title = ref("璁剧疆娴嬭瘯妯″紡"); +const paramsVisible = ref(false); +const inputValue = ref(); +const currentIdx = ref(0); +const input = ref(); + +const testModelab = computed(() => { + const obj = { + 3: "閫嗗彉骞剁綉", + 6: "PFC宸ヤ綔", + }; + const lab = props.info.state?.testModelab || 0; + return obj[lab] || `鏈煡 (${lab})`; +}); + +function edit(idx) { + currentIdx.value = idx; + switch (idx) { + case 0: + title.value = "璁剧疆娴嬭瘯妯″紡"; + inputValue.value = props.info.state.testModelab; + break; + case 1: + title.value = "璁剧疆VBus鐢靛帇"; + inputValue.value = props.info.state.vbusVerfVolSet; + break; + case 2: + title.value = "璁剧疆LLC Buck鐢靛帇"; + inputValue.value = props.info.state.llcBuckVolSet; + break; + case 3: + title.value = "璁剧疆LLC Buck鐢垫祦"; + inputValue.value = props.info.state.llcBuckCurrSet; + break; + default: + break; + } + paramsVisible.value = true; + + if (idx) { + setTimeout(() => { + input.value.select(); + }, 0); + } +} +function setParams() { + let setFn; + if (currentIdx.value !== 0 &&inputValue.value.trim() === '') { + $message.error("璇疯緭鍏ュ弬鏁�"); + return; + } + switch (currentIdx.value) { + case 0: + setFn = controllTestModel; + break; + case 1: + setFn = controllVBusVref; + break; + case 2: + setFn = controllLLCBuckVol; + break; + case 3: + setFn = controllLLCBuckCurr; + break; + default: + break; + } + + let loading = $loading(); + setFn(props.info.powerId, inputValue.value) + .then((res) => { + let { code, data } = res.data; + loading.close(); + if (code && data) { + console.log(data); + $message.success("璁剧疆鎴愬姛"); + emit("setOk"); + paramsVisible.value = false; + } else { + $message.error("璁剧疆澶辫触"); + } + }) + .catch((err) => { + $message.error("璁剧疆澶辫触"); + loading.close(); + console.log(err); + }); +} +</script> + +<template> + <div class="params"> + <div class="item"> + <div class="label">娴嬭瘯妯″紡</div> + <div class="value">{{ testModelab }}</div> + <el-button size="small" type="primary" @click="edit(0)">淇敼</el-button> + </div> + <!-- <div class="item"> + <div class="label">骞剁綉杈撳嚭鐢垫祦</div> + <div class="value">{{ info.state.gridIrefCurrSet }}</div> + <el-button size="small" type="primary" @click="edit">淇敼</el-button> + </div> --> + <!-- <div class="item"> + <div class="label">VBus鐢靛帇</div> + <div class="value">{{ info.state.vbusVerfVolSet }}</div> + <el-button size="small" type="primary" @click="edit(1)">淇敼</el-button> + </div> --> + <div class="item"> + <div class="label">LLC Buck鐢靛帇</div> + <div class="value">{{ info.state.llcBuckVolSet }}</div> + <el-button size="small" type="primary" @click="edit(2)">淇敼</el-button> + </div> + <div class="item"> + <div class="label">LLC Buck鐢垫祦</div> + <div class="value">{{ info.state.llcBuckCurrSet }}</div> + <el-button size="small" type="primary" @click="edit(3)">淇敼</el-button> + </div> + </div> + <!-- 寮圭獥 --> + <el-dialog + :title="title" + v-model="paramsVisible" + :close-on-click-modal="false" + class="dialog-center" + width="280px" + center + > + <el-select + v-model="inputValue" + v-if="currentIdx === 0" + placeholder="Select" + size="small" + > + <el-option :value="3" label="閫嗗彉骞剁綉"></el-option> + <el-option :value="6" label="PFC宸ヤ綔"></el-option> + </el-select> + <el-input + v-else + ref="input" + v-model="inputValue" + placeholder="Please input" + /> + <template #footer> + <span class="dialog-footer"> + <el-button @click="paramsVisible = false">鍙栨秷</el-button> + <el-button type="primary" @click="setParams">纭畾</el-button> + </span> + </template> + </el-dialog> +</template> + +<style scoped lang="scss"> +.params { + display: flex; + flex-direction: column; + .item { + display: flex; + align-items: center; + margin-bottom: 10px; + .label { + flex: 1; + margin-right: 10px; + text-align: right; + &::after { + content: ":"; + } + } + .value { + width: 8em; + margin-right: 10px; + } + } +} +</style> -- Gitblit v1.9.1