package-lock.json | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
package.json | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/api/params.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/assets/js/axios.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/assets/js/const_digits.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/assets/js/getWsUrl.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/assets/js/toFixed.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components/ycLight.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/hooks/useElement.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/hooks/useWebSocket.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/styles/index.scss | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/styles/light.scss | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/home/StateInfo.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/home/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/home/paramsContent.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
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", 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": { src/api/params.js
New file @@ -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, }, }); }; src/assets/js/axios.js
New file @@ -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; src/assets/js/const_digits.js
New file @@ -0,0 +1,10 @@ export default { // 电压保留3位小数 VOL: 3, // 电流保留1位小数 CURR: 1, // 温度保留1位小数 TEMP: 1, // 频率 FREQ: 1, }; src/assets/js/getWsUrl.js
New file @@ -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; src/assets/js/toFixed.js
New file @@ -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; } src/components/ycLight.vue
New file @@ -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> src/hooks/useElement.js
New file @@ -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 }; }; src/hooks/useWebSocket.js
New file @@ -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 }; } src/styles/index.scss
@@ -1,3 +1,4 @@ @use './reset'; @use './variable'; @use './light'; @use './theme/index.scss'; src/styles/light.scss
New file @@ -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; } } 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">单片机ADC采样</div> </div> --> <!-- <div class="state-info-title adc">单片机ADC采样</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+正电压:</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散热器温度:</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散热器温度:</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散热器温度:</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散热器温度过温</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散热器温度过温</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散热器温度过温</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 { 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"> src/views/home/paramsContent.vue
New file @@ -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>