he wei
2025-06-03 a10f3b82e33756ed0cd62a0cbe83bab8674df16f
src/views/realtime/index.vue
@@ -1,23 +1,62 @@
<script setup>
import { ref, reactive } from "vue";
<script setup name="realtime">
import { ref, reactive, watch, onMounted } from "vue";
import tabPower from "./tabs/power.vue";
import tabSystem from "./tabs/system.vue";
import tabVol from './tabs/vol.vue';
import siteList from "@/components/siteList/index.vue";
import  getQueryString  from "@/utils/getQueryString";
import formatSeconds from '@/utils/formatSeconds';
import { useRoute, useRouter } from "vue-router";
import useWebsocket from "@/hooks/useWebsocket";
const route = useRoute();
const router = useRouter();
const { message, sendData } = useWebsocket('real');
const curStationId = ref(
  getQueryString("stationId") || ''
);
const curPowerId = ref(
  getQueryString("powerId") || ''
);
const curBattgroupId = ref(
  getQueryString("battgroupId") || ''
);
const curDevId = ref(
  getQueryString("devId") || ''
);
const rtData = reactive({
  system: {},
  power: {},
  vol: {},
  res: {},
  tmp: {},
  threeD: {},
  self: {},
  manage: {},
});
const statusList = reactive([
   { label: '系统状态', value: '充电' },
   { label: '设备状态', value: '正常' },
   { label: '电源状态', value: '正常' },
   { label: '电池状态', value: '正常' },
   { label: '母线电压', value: 60 },
   { label: '在线电压', value: 60 },
   { label: '组端电压', value: 60 },
   { label: '电池电流', value: 60 },
   { label: '测试时长', value: 60 },
   { label: '测试容量', value: 60 },
   { label: '预估剩余容量', value: 60 },
   { label: '预估剩余续航', value: 60 },
   { label: '告警', value: '无' },
   { label: '更新日期', value: '2022-01-01' },
   { label: '系统状态', prop: 'systemState', unit: '' },
   { label: '设备状态', prop: 'devState', unit: '' },
   { label: '电源状态', prop: 'pwrState', unit: '' },
   { label: '电池状态', prop: 'battState', unit: '' },
   { label: '母线电压', prop: 'vbusVol', unit: 'V' },
   { label: '在线电压', prop: 'onlineVol', unit: 'V' },
   { label: '组端电压', prop: 'captestGroupvol', unit: 'V' },
   { label: '电池电流', prop: 'captestCurr', unit: 'A' },
   { label: '测试时长', prop: 'captestTimelong', unit: '' },
   { label: '测试容量', prop: 'captestCap', unit: 'Ah' },
   { label: '预估剩余容量', prop: 'restCap', unit: 'Ah' },
   { label: '预估剩余续航', prop: 'restTime', unit: '' },
   { label: '告警', prop: 'allALmNum', unit: '' },
   { label: '更新日期', prop: 'recordtime', unit: '' },
]);
const tabs = ref([
@@ -25,10 +64,13 @@
   { label: '电源', name: 'power' },
   { label: '电压', name: 'vol' },
   { label: '内阻', name: 'res' },
   { label: '温度', name: 'temp' },
   { label: '3D', name: '3d' },
   { label: '温度', name: 'tmp' },
   { label: '3D', name: '3D' },
   { label: '自愈能力', name: 'self' },
   { label: '管理信息', name: 'manage' },
]);
const btns = ref([
   { label: '电源告警参数设置', name: 'powerAlarmSet' },
   { label: '电池告警参数设置', name: 'battAlarmSet' },
   { label: '图片', name: 'img' },
@@ -39,56 +81,139 @@
const acTab = ref(tabs.value[0].name);
const fullName = ref('湖北省-武汉市-武昌区-武昌机房-电池组1');
const topData = ref({});
function sendMessage() {
  let params = {
    stationId: curStationId.value || 0,
    powerId: curPowerId.value || 0,
    devId: curDevId.value || 0,
    battgroupId: curBattgroupId.value || 0,
    // system, power, vol, res, tmp, 3D, self, manage
    pageType: acTab.value
  };
  sendData(JSON.stringify(params));
}
function tabClick(item) {
   acTab.value = item.name;
  sendMessage();
}
function btnClick(item) {
  console.log('item', item, '=============');
}
function leafClick(item) {
  // console.log('item', item, '=============');
  curStationId.value = item.stationId;
  curPowerId.value = item.powerId;
  curBattgroupId.value = item.battgroupId || 0;
  curDevId.value = item.devId || 0;
  sendMessage();
  // if (getQueryString("stationId")) {
  //   router.push({
  //     path: route.path,
  //     query: {
  //       stationId: item.stationId,
  //       powerId: item.powerId,
  //       battgroupId: item.battgroupId || undefined,
  //       devId: item.devId || undefined
  //     }
  //   })
  // }
  // fullName.value = item.fullName;
}
watch(
  () => message.value,
  (n) => {
    if (n) {
      let {data2: { topRes, realRes}} = JSON.parse(n);
      let data = {};
      if (topRes.code && topRes.data) {
        data = topRes.data2;
        fullName.value = `${data.fullName} ${data.powerName} ${data.devName} ${data.battGroupName}`;
      }
      topData.value = data;
      if (realRes.code && realRes.data) {
        // rtData.
        rtData['system'] = realRes.data2;
      }
    }
  }
)
onMounted(() => {
  sendMessage();
});
</script>
<template>
  <div class="page-contain">
    <div class="page-header">
      <div class="p-title">{{ fullName }}</div>
      <div class="status-bar">
        <div
          :class="['status-item',]"
          v-for="(item, index) in statusList"
          :key="'status_' + index"
        >
          <div class="item-value">{{ item.value }}</div>
          <div class="item-name">{{ item.label }}</div>
    <site-list @leaf-click="leafClick"></site-list>
    <div class="page-inner">
      <div class="page-header">
        <div class="p-title">{{ fullName }}</div>
        <div class="status-bar">
          <div
            :class="['status-item',]"
            v-for="(item, index) in statusList"
            :key="'status_' + index"
          >
            <div class="item-value" v-if="item.prop == 'captestTimelong' || item.prop == 'restTime'">{{ topData[item.prop] ? formatSeconds(topData[item.prop]) : '--' }}</div>
            <div class="item-value time" v-else-if="item.prop == 'recordtime'">{{ topData[item.prop] || '--' }}</div>
            <div class="item-value" v-else>{{ topData[item.prop] || '--' }}{{ item.unit }}</div>
            <div class="item-name">{{ item.label }}</div>
          </div>
        </div>
        <div class="p-tabs">
          <div
            :class="['tab-item', {'active': item.name == acTab}]"
            v-for="(item, index) in tabs"
            :key="'tab_' + index"
            @click="tabClick(item)"
          >
            {{ item.label }}
          </div>
          <div
            class="btn-item tab-item"
            v-for="(item, index) in btns"
            :key="'btn_' + index"
            @click="btnClick(item)"
          >
            {{ item.label }}
          </div>
        </div>
      </div>
      <div class="p-tabs">
        <div
          :class="['tab-item', {'active': item.name == acTab}]"
          v-for="(item, index) in tabs"
          :key="'tab_' + index"
          @click="tabClick(item)"
        >
          {{ item.label }}
      <div class="page-main">
        <div class="tab-contain" v-if="acTab == 'system'">
          <tab-system :data="rtData['system']"></tab-system>
        </div>
        <div class="tab-contain" v-if="acTab == 'power'">
          <tab-power></tab-power>
        </div>
        <div class="tab-contain" v-if="acTab == 'vol'">
          <tab-vol></tab-vol>
        </div>
        <div class="tab-contain" v-if="acTab == 'res'">3</div>
        <div class="tab-contain" v-if="acTab == 'tmp'">4</div>
        <div class="tab-contain" v-if="acTab == '3D'">5</div>
        <div class="tab-contain" v-if="acTab == 'self'">6</div>
        <div class="tab-contain" v-if="acTab == 'manage'">7</div>
        <!-- <div class="tab-contain" v-if="acTab == 'powerAlarmSet'">8</div>
        <div class="tab-contain" v-if="acTab == 'battAlarmSet'">9</div>
        <div class="tab-contain" v-if="acTab == 'img'">10</div>
        <div class="tab-contain" v-if="acTab == 'history'">11</div>
        <div class="tab-contain" v-if="acTab == 'hisRt'">12</div> -->
      </div>
    </div>
    <div class="page-main">
      <div class="tab-contain" v-if="acTab == 'system'">
        <tab-system></tab-system>
      </div>
      <div class="tab-contain" v-if="acTab == 'power'">
        <tab-power></tab-power>
      </div>
      <div class="tab-contain" v-if="acTab == 'vol'">2</div>
      <div class="tab-contain" v-if="acTab == 'res'">3</div>
      <div class="tab-contain" v-if="acTab == 'temp'">4</div>
      <div class="tab-contain" v-if="acTab == '3d'">5</div>
      <div class="tab-contain" v-if="acTab == 'self'">6</div>
      <div class="tab-contain" v-if="acTab == 'manage'">7</div>
      <div class="tab-contain" v-if="acTab == 'powerAlarmSet'">8</div>
      <div class="tab-contain" v-if="acTab == 'battAlarmSet'">9</div>
      <div class="tab-contain" v-if="acTab == 'img'">10</div>
      <div class="tab-contain" v-if="acTab == 'history'">11</div>
      <div class="tab-contain" v-if="acTab == 'hisRt'">12</div>
    </div>
  </div>
</template>
@@ -96,7 +221,15 @@
<style scoped lang="less">
.page-contain {
  display: flex;
  flex-direction: column;
  padding: 8px 8px 8px 0;
  margin-left: 8px;
  overflow: hidden;
  .page-inner {
    display: flex;
    flex-direction: column;
    flex: 1;
    margin-left: 8px;
  }
  .page-header {
    // border: 1px solid #0ff;
@@ -125,7 +258,7 @@
        color: #50c7f1;
        // border: 1px solid #0F6B79;
        border-radius: 6px;
        margin: 4px 6px;
        margin: 4px 2px;
        display: flex;
        flex-direction: column;
        justify-content: center;
@@ -140,6 +273,10 @@
          margin-bottom: 6px;
          color: #ff0;
          font-size: 20px;
          &.time {
            white-space: nowrap;
            font-size: 12px;
          }
        }
        .item-name {
@@ -171,6 +308,10 @@
          background: #47CAFE;
          color: #03216e;
        }
        &.btn-item {
          background: #076fe8;
          // border-radius: 6px;
        }
      }
    }
  }