he wei
2025-01-13 8ffb54b88e3907ea59c120d34a8cd9f486cc1151
U 提交
5个文件已修改
10个文件已添加
1256 ■■■■■ 已修改文件
package-lock.json 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/params.js 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/axios.js 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/const_digits.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/getWsUrl.js 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/toFixed.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/ycLight.vue 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/hooks/useElement.js 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/hooks/useWebSocket.js 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/styles/index.scss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/styles/light.scss 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/StateInfo.vue 355 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/index.vue 151 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/paramsContent.vue 198 ●●●●● 补丁 | 查看 | 原始文档 | 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>