svg
ali
2025-02-10 d22576ed1352cf5b9046a13ff1be12fb9b15cf2c
svg
已添加7个文件
已删除1个文件
已修改5个文件
1659 ■■■■■ 文件已修改
zhitan-vue/index.html 385 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/package.json 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/public/logo.png 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/api/svg/equipmentfile.js 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/images/login-background.jpg 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/components/FileUpload/index.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/login copy.vue 293 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/login.vue 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/svg/components/configure.vue 204 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/svg/components/configureView.vue 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/svg/equipmentfile/chartView.vue 314 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/svg/equipmentfile/index.vue 243 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/index.html
@@ -1,215 +1,214 @@
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="renderer" content="webkit">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
  <link rel="icon" href="/favicon.ico">
  <title>管理系统</title>
  <!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
  <style>
    html,
    body,
    #app {
      height: 100%;
      margin: 0px;
      padding: 0px;
    }
    .chromeframe {
      margin: 0.2em 0;
      background: #ccc;
      color: #000;
      padding: 0.2em 0;
    }
    #loader-wrapper {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      z-index: 999999;
    }
    #loader {
      display: block;
      position: relative;
      left: 50%;
      top: 50%;
      width: 150px;
      height: 150px;
      margin: -75px 0 0 -75px;
      border-radius: 50%;
      border: 3px solid transparent;
      border-top-color: #FFF;
      -webkit-animation: spin 2s linear infinite;
      -ms-animation: spin 2s linear infinite;
      -moz-animation: spin 2s linear infinite;
      -o-animation: spin 2s linear infinite;
      animation: spin 2s linear infinite;
      z-index: 1001;
    }
    #loader:before {
      content: "";
      position: absolute;
      top: 5px;
      left: 5px;
      right: 5px;
      bottom: 5px;
      border-radius: 50%;
      border: 3px solid transparent;
      border-top-color: #FFF;
      -webkit-animation: spin 3s linear infinite;
      -moz-animation: spin 3s linear infinite;
      -o-animation: spin 3s linear infinite;
      -ms-animation: spin 3s linear infinite;
      animation: spin 3s linear infinite;
    }
    #loader:after {
      content: "";
      position: absolute;
      top: 15px;
      left: 15px;
      right: 15px;
      bottom: 15px;
      border-radius: 50%;
      border: 3px solid transparent;
      border-top-color: #FFF;
      -moz-animation: spin 1.5s linear infinite;
      -o-animation: spin 1.5s linear infinite;
      -ms-animation: spin 1.5s linear infinite;
      -webkit-animation: spin 1.5s linear infinite;
      animation: spin 1.5s linear infinite;
    }
    @-webkit-keyframes spin {
      0% {
        -webkit-transform: rotate(0deg);
        -ms-transform: rotate(0deg);
        transform: rotate(0deg);
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="renderer" content="webkit" />
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
    <link rel="icon" href="/logo.png" />
    <title>管理系统</title>
    <!--[if lt IE 11
      ]><script>
        window.location.href = "/html/ie.html"
      </script><!
    [endif]-->
    <style>
      html,
      body,
      #app {
        height: 100%;
        margin: 0px;
        padding: 0px;
      }
      100% {
        -webkit-transform: rotate(360deg);
        -ms-transform: rotate(360deg);
        transform: rotate(360deg);
      }
    }
    @keyframes spin {
      0% {
        -webkit-transform: rotate(0deg);
        -ms-transform: rotate(0deg);
        transform: rotate(0deg);
      .chromeframe {
        margin: 0.2em 0;
        background: #ccc;
        color: #000;
        padding: 0.2em 0;
      }
      100% {
        -webkit-transform: rotate(360deg);
        -ms-transform: rotate(360deg);
        transform: rotate(360deg);
      #loader-wrapper {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index: 999999;
      }
    }
      #loader {
        display: block;
        position: relative;
        left: 50%;
        top: 50%;
        width: 150px;
        height: 150px;
        margin: -75px 0 0 -75px;
        border-radius: 50%;
        border: 3px solid transparent;
        border-top-color: #fff;
        -webkit-animation: spin 2s linear infinite;
        -ms-animation: spin 2s linear infinite;
        -moz-animation: spin 2s linear infinite;
        -o-animation: spin 2s linear infinite;
        animation: spin 2s linear infinite;
        z-index: 1001;
      }
    #loader-wrapper .loader-section {
      position: fixed;
      top: 0;
      width: 51%;
      height: 100%;
      background: #7171C6;
      z-index: 1000;
      -webkit-transform: translateX(0);
      -ms-transform: translateX(0);
      transform: translateX(0);
    }
      #loader:before {
        content: "";
        position: absolute;
        top: 5px;
        left: 5px;
        right: 5px;
        bottom: 5px;
        border-radius: 50%;
        border: 3px solid transparent;
        border-top-color: #fff;
        -webkit-animation: spin 3s linear infinite;
        -moz-animation: spin 3s linear infinite;
        -o-animation: spin 3s linear infinite;
        -ms-animation: spin 3s linear infinite;
        animation: spin 3s linear infinite;
      }
    #loader-wrapper .loader-section.section-left {
      left: 0;
    }
      #loader:after {
        content: "";
        position: absolute;
        top: 15px;
        left: 15px;
        right: 15px;
        bottom: 15px;
        border-radius: 50%;
        border: 3px solid transparent;
        border-top-color: #fff;
        -moz-animation: spin 1.5s linear infinite;
        -o-animation: spin 1.5s linear infinite;
        -ms-animation: spin 1.5s linear infinite;
        -webkit-animation: spin 1.5s linear infinite;
        animation: spin 1.5s linear infinite;
      }
    #loader-wrapper .loader-section.section-right {
      right: 0;
    }
      @-webkit-keyframes spin {
        0% {
          -webkit-transform: rotate(0deg);
          -ms-transform: rotate(0deg);
          transform: rotate(0deg);
        }
        100% {
          -webkit-transform: rotate(360deg);
          -ms-transform: rotate(360deg);
          transform: rotate(360deg);
        }
      }
    .loaded #loader-wrapper .loader-section.section-left {
      -webkit-transform: translateX(-100%);
      -ms-transform: translateX(-100%);
      transform: translateX(-100%);
      -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
      transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
    }
      @keyframes spin {
        0% {
          -webkit-transform: rotate(0deg);
          -ms-transform: rotate(0deg);
          transform: rotate(0deg);
        }
    .loaded #loader-wrapper .loader-section.section-right {
      -webkit-transform: translateX(100%);
      -ms-transform: translateX(100%);
      transform: translateX(100%);
      -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
      transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
    }
        100% {
          -webkit-transform: rotate(360deg);
          -ms-transform: rotate(360deg);
          transform: rotate(360deg);
        }
      }
    .loaded #loader {
      opacity: 0;
      -webkit-transition: all 0.3s ease-out;
      transition: all 0.3s ease-out;
    }
      #loader-wrapper .loader-section {
        position: fixed;
        top: 0;
        width: 51%;
        height: 100%;
        background: #7171c6;
        z-index: 1000;
        -webkit-transform: translateX(0);
        -ms-transform: translateX(0);
        transform: translateX(0);
      }
    .loaded #loader-wrapper {
      visibility: hidden;
      -webkit-transform: translateY(-100%);
      -ms-transform: translateY(-100%);
      transform: translateY(-100%);
      -webkit-transition: all 0.3s 1s ease-out;
      transition: all 0.3s 1s ease-out;
    }
      #loader-wrapper .loader-section.section-left {
        left: 0;
      }
    .no-js #loader-wrapper {
      display: none;
    }
      #loader-wrapper .loader-section.section-right {
        right: 0;
      }
    .no-js h1 {
      color: #222222;
    }
      .loaded #loader-wrapper .loader-section.section-left {
        -webkit-transform: translateX(-100%);
        -ms-transform: translateX(-100%);
        transform: translateX(-100%);
        -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
        transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
      }
    #loader-wrapper .load_title {
      font-family: 'Open Sans';
      color: #FFF;
      font-size: 19px;
      width: 100%;
      text-align: center;
      z-index: 9999999999999;
      position: absolute;
      top: 60%;
      opacity: 1;
      line-height: 30px;
    }
      .loaded #loader-wrapper .loader-section.section-right {
        -webkit-transform: translateX(100%);
        -ms-transform: translateX(100%);
        transform: translateX(100%);
        -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
        transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
      }
    #loader-wrapper .load_title span {
      font-weight: normal;
      font-style: italic;
      font-size: 13px;
      color: #FFF;
      opacity: 0.5;
    }
  </style>
</head>
      .loaded #loader {
        opacity: 0;
        -webkit-transition: all 0.3s ease-out;
        transition: all 0.3s ease-out;
      }
<body>
  <div id="app">
    <div id="loader-wrapper">
      <div id="loader"></div>
      <div class="loader-section section-left"></div>
      <div class="loader-section section-right"></div>
      <div class="load_title">正在加载,请耐心等待</div>
      .loaded #loader-wrapper {
        visibility: hidden;
        -webkit-transform: translateY(-100%);
        -ms-transform: translateY(-100%);
        transform: translateY(-100%);
        -webkit-transition: all 0.3s 1s ease-out;
        transition: all 0.3s 1s ease-out;
      }
      .no-js #loader-wrapper {
        display: none;
      }
      .no-js h1 {
        color: #222222;
      }
      #loader-wrapper .load_title {
        font-family: "Open Sans";
        color: #fff;
        font-size: 19px;
        width: 100%;
        text-align: center;
        z-index: 9999999999999;
        position: absolute;
        top: 60%;
        opacity: 1;
        line-height: 30px;
      }
      #loader-wrapper .load_title span {
        font-weight: normal;
        font-style: italic;
        font-size: 13px;
        color: #fff;
        opacity: 0.5;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <div id="loader-wrapper">
        <div id="loader"></div>
        <div class="loader-section section-left"></div>
        <div class="loader-section section-right"></div>
        <div class="load_title">正在加载,请耐心等待</div>
      </div>
    </div>
  </div>
  <script type="module" src="/src/main.js"></script>
</body>
</html>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>
zhitan-vue/package.json
@@ -7,7 +7,7 @@
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build:prod": "vite build",
    "build": "vite build",
    "build:stage": "vite build --mode staging",
    "preview": "vite preview"
  },
zhitan-vue/public/logo.png
zhitan-vue/src/api/svg/equipmentfile.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
import request from "@/utils/request"
// ä¿®æ”¹ç»„态图
export function updateEquipmentfile(data) {
  return request({
    url: "/basicSetup/equipmentfile",
    method: "put",
    data: data,
  })
}
export function getAllCollectTag(data) {
  return request({
    url: "/basicsetting/energyindex/filter",
    method: "get",
    params: data,
  })
}
export function saveSettingApi(nodeId, data) {
  return request({
    url: "/basicSetup/equipmentfile/setting/" + nodeId,
    method: "put",
    data: data,
  })
}
export function getConfigure(nodeId) {
  return request({
    url: "/basicSetup/equipmentfile/configure/" + nodeId,
    method: "get",
  })
}
export function getLiveData(tagCodes) {
  return request({
    url: "/rtdb/retrieve/" + tagCodes,
    method: "get",
  })
}
zhitan-vue/src/assets/images/login-background.jpg
zhitan-vue/src/components/FileUpload/index.vue
@@ -13,9 +13,14 @@
      :headers="headers"
      class="upload-file-uploader"
      ref="fileUpload"
      :drag="draggable"
    >
      <!-- ä¸Šä¼ æŒ‰é’® -->
      <el-button type="primary">选取文件</el-button>
      <el-button v-if="!draggable" type="primary">选取文件</el-button>
      <div v-else>
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
      </div>
    </el-upload>
    <!-- ä¸Šä¼ æç¤º -->
    <div class="el-upload__tip" v-if="showTip">
@@ -66,6 +71,11 @@
    type: Boolean,
    default: true,
  },
  // æ˜¯å¦æ‹–拽上传
  draggable: {
    type: Boolean,
    default: false,
  },
})
const { proxy } = getCurrentInstance()
zhitan-vue/src/views/index.vue
@@ -379,7 +379,7 @@
            right: "5%",
            itemWidth: 14,
            itemHeight: 14,
            itemGap: 60,
            itemGap: 16,
            textStyle: {
              align: "left",
              verticalAlign: "middle",
@@ -777,7 +777,7 @@
            right: "10%",
            itemWidth: 14,
            itemHeight: 14,
            itemGap: 50,
            itemGap: 16,
            textStyle: {
              align: "left",
              verticalAlign: "middle",
zhitan-vue/src/views/login copy.vue
ÎļþÒÑɾ³ý
zhitan-vue/src/views/login.vue
@@ -11,8 +11,8 @@
    <div class="middle-view">
      <div class="left-wrapper">
        <div class="login-font">{{ systemInfo.systemName || "" }}</div>
        <img src="@/assets/images/font01.png" alt="" style="width: 406px" />
        <img src="@/assets/images/img_logo.png" alt="" style="width: 200px; margin-top: 20px" />
        <img src="@/assets/images/font01.png" alt="" style="width: 380px" />
        <img src="@/assets/images/img_logo.png" alt="" style="width: 180px; margin-top: 20px" />
      </div>
      <div class="right-wrapper">
        <div class="header">
@@ -44,7 +44,7 @@
              size="large"
              auto-complete="off"
              placeholder="验证码"
              style="width: 266px"
              style="width: 230px"
              @keyup.enter="handleLogin"
            >
              <!-- <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template> -->
@@ -202,7 +202,7 @@
  display: flex;
  align-items: center;
  height: 100%;
  background-image: url("@/assets/images/login-background.png");
  background-image: url("@/assets/images/login-background.jpg");
  background-repeat: no-repeat;
  background-size: cover;
  flex-direction: column;
@@ -223,31 +223,31 @@
    flex-direction: column;
  }
  .login-font {
    font-size: 34px;
    font-size: 32px;
    font-weight: 700;
    color: #d5f8ff;
    margin-bottom: 12px;
    margin-bottom: 10px;
  }
}
.right-wrapper {
  border-radius: 23px;
  background: #ffffff;
  width: 480px;
  width: 410px;
  position: relative;
  .header {
    height: 70px;
    line-height: 70px;
    height: 56px;
    line-height: 56px;
    border-bottom: 1px solid #f1f1f1;
    color: #3b3b3b;
    font-size: 22px;
    font-size: 18px;
    margin-bottom: 22px;
    span {
      display: inline-block;
      height: 70px;
      line-height: 70px;
      border-bottom: 6px solid #3a83fc;
      margin-left: 50px;
      height: 56px;
      line-height: 62px;
      border-bottom: 4px solid #3a83fc;
      margin-left: 32px;
    }
  }
}
@@ -277,14 +277,14 @@
}
.login-form {
  padding: 0 50px 30px;
  padding: 0 32px 20px;
  .submit-btn {
    width: 382px;
    height: 54px;
    width: 360px;
    height: 44px;
    background: #3a83fc;
    border-radius: 3px;
    font-size: 20px;
    font-size: 18px;
    box-shadow: 1px 2px 5px #3a83fc;
    border: none;
    border-radius: 6px;
@@ -342,7 +342,7 @@
  text-align: center;
  color: #fff;
  font-family: Arial;
  font-size: 16px;
  font-size: 14px;
  letter-spacing: 1px;
}
</style>
zhitan-vue/src/views/svg/components/configure.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,204 @@
<template>
  <div>
    <div slot="header" class="clearfix">
      <el-button
        style="float: right; padding: 8px; margin-left: 8px"
        type="text"
        icon="el-icon-setting"
        @click="saveSetting"
      >
        ä¿å­˜é…ç½®
      </el-button>
      <el-button
        style="float: right; padding: 8px; margin-left: 8px"
        type="text"
        icon="el-icon-setting"
        @click="reset()"
      >
        é‡æ–°é€‰æ‹©åº•图
      </el-button>
    </div>
    <el-row>
      <el-col :span="18">
        <!-- v-if="filePath === '空节点'" -->
        <div style="text-align: center; margin-left: 12px" v-if="filePath === '空节点'">
          <FileUpload
            :modelValue="fileList"
            @update:modelValue="fileUploadChange"
            :isShowTip="false"
            :limit="1"
            :fileSize="20"
            :fileType="[]"
            :draggable="true"
          />
        </div>
        <div id="svgHtml" v-if="filePath !== '空节点'">
          <div v-html="svgHtml" />
        </div>
      </el-col>
      <el-col :span="6" style="height: calc(100vh - 165px); overflow: auto">
        <el-table :data="tags" border>
          <el-table-column label="参数" align="center" prop="param" />
          <el-table-column label="采集点" align="center" prop="tag">
            <template #default="scope">
              <el-autocomplete
                popper-class="my-autocomplete"
                v-model="scope.row['tag']"
                :fetch-suggestions="querySearch"
                placeholder="请输入指标编码"
                placement="bottom-end"
              >
                <template #default="{ item }">
                  <div class="">{{ item.value }}</div>
                  <span class="" style="color: #409eff; display: block">{{ item.name }}</span>
                </template>
              </el-autocomplete>
            </template>
          </el-table-column>
        </el-table>
      </el-col>
    </el-row>
  </div>
</template>
<script setup>
import { getAllCollectTag, getConfigure, saveSettingApi, updateEquipmentfile } from "@/api/svg/equipmentfile"
const { proxy } = getCurrentInstance()
let props = defineProps(["types"])
const emit = defineEmits(["getList"])
const currentNode = ref({})
const filePath = ref("空节点")
const svgHtml = ref("")
const form = ref({
  nodeId: "",
  fileName: "",
  svgType: "",
})
const tags = ref([])
const fileList = ref([])
function changeModelNode(modelNode) {
  currentNode.value = modelNode
  filePath.value = "空节点"
  getConfigure(modelNode.id).then((response) => {
    tags.value = []
    svgHtml.value = ""
    if (response.code === 200) {
      if (response.data) {
        filePath.value = response.data.filePath
        tags.value = response.data.infoList
        getSvg()
      }
    } else {
      proxy.$modal.msgError(response.msg)
    }
  })
}
// åˆå§‹åŒ–svg
function getSvg() {
  /* åˆ›å»ºxhr对象 */
  const xhr = new XMLHttpRequest()
  xhr.open("GET", filePath.value, true)
  xhr.send()
  /* ç›‘听xhr对象 */
  xhr.addEventListener("load", () => {
    svgHtml.value = xhr.responseText
    let values = xhr.responseXML.getElementsByTagName("text")
    let tagTemps = []
    for (let i = 0; i < values.length; i++) {
      if (values[i].getAttribute("id") != undefined)
        tagTemps.push({
          param: values[i].textContent,
          tag: "",
          tagType: "COLLECT",
        })
    }
    console.log(tags.value.length, tagTemps.length)
    if (tags.value.length === 0 || tags.value.length != tagTemps.length) {
      tags.value = []
      tags.value = tagTemps
      console.log("222", tags.value.length, tagTemps.length)
    }
  })
}
//上传成功后
function fileUploadChange(val) {
  if (val.length) {
    // this.$refs.upload.clearFiles()
    form.value.nodeId = currentNode.value.id
    form.value.filePath = val[0].fullUrl
    form.value.svgType = "COLLECT"
    updateEquipmentfile(form.value).then((result) => {
      if (result.code === 200) {
        filePath.value = response.msg
        tags.value = []
        getSvg()
      } else {
        proxy.$modal.msgError(result.msg)
      }
    })
  } else {
    proxy.$modal.msgError(response.msg)
  }
}
function querySearch(queryString, cb) {
  if (queryString) {
    getAllCollectTag({
      codeOrName: queryString,
      indexType: "COLLECT",
    }).then((response) => {
      // è°ƒç”¨ callback è¿”回建议列表的数据
      let result = response.data
      let values = []
      result.forEach((item) => {
        values.push({
          value: item.code,
          name: item.name,
        })
      })
      cb(values)
    })
  }
}
function saveSetting() {
  saveSettingApi(currentNode.value.id, tags.value).then((response) => {
    if (response.code === 200) {
      proxy.$modal.msgSuccess(response.msg)
    } else {
      proxy.$modal.msgError(response.msg)
    }
  })
}
function reset() {
  filePath.value = "空节点"
}
defineExpose({ changeModelNode })
</script>
<style lang="scss" scoped>
.el-autocomplete {
  width: 100%;
}
.my-autocomplete li {
  line-height: normal;
  padding: 7px;
}
.my-autocomplete li .name {
  text-overflow: ellipsis;
  overflow: hidden;
}
.my-autocomplete li .addr {
  font-size: 12px;
  color: #b4b4b4;
}
.my-autocomplete li .highlighted .addr {
  color: #ddd;
}
</style>
zhitan-vue/src/views/svg/components/configureView.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,124 @@
<template>
  <div>
    <div v-if="filePath" v-html="svgHtml" />
    <div v-else>暂未上传</div>
  </div>
</template>
<script setup>
import { getConfigure, getLiveData } from "@/api/svg/equipmentfile"
import { onMounted } from "vue"
const { proxy } = getCurrentInstance()
let props = defineProps(["nodeId"])
const emit = defineEmits(["getList"])
const currentNode = ref({})
const filePath = ref("")
const svgHtml = ref("")
const form = ref({
  nodeId: "",
  fileName: "",
  svgType: "",
})
const tags = ref([])
const tagCodes = ref([])
const valueItems = ref(null)
const timer = ref(null)
function show(nodeId) {
  console.log(nodeId)
  tagCodes.value = []
  filePath.value = ""
  getConfigure(nodeId).then((response) => {
    tags.value = []
    svgHtml.value = ""
    if (response.code === 200) {
      if (response.data) {
        filePath.value = response.data.filePath
        tags.value = response.data.infoList
        getSvg()
        refresh()
      }
    } else {
      proxy.$modal.msgError(response.msg)
    }
  })
}
function refresh() {
  if (tagCodes.value.length === 0) {
    return
  }
  getLiveData(tagCodes.value).then((response) => {
    if (response.code === 200) {
      if (response.data) {
        response.data.forEach((tagValue) => {
          let value = ""
          if (tagValue.value) {
            value = parseFloat(tagValue.value).toFixed(2)
          } else {
            value = "0"
          }
          let el = document.getElementById(tagValue.tagCode)
          if (el) {
            el.textContent = value
          }
        })
        //这块是单独加的 ç”¨æ¥å¤„理 æ²¡æœ‰æŒ‡æ ‡æˆ–者指标没有结果的 éƒ½è®¾ç½®0
        let allText = document.getElementsByTagName("text")
        for (let i = 0; i < allText.length; i++) {
          // console.log(i + "textContent=" + allText[i].textContent);
          if (allText[i].textContent == null || allText[i].textContent == "") {
            allText[i].textContent = "0"
          }
        }
      }
    }
  })
}
function refreshData() {
  timer.value = setInterval(() => {
    refresh()
  }, 3000)
}
onMounted(() => {
  refreshData()
})
onBeforeUnmount(() => {
  clearInterval(timer.value)
})
// åˆå§‹åŒ–svg
function getSvg() {
  /* åˆ›å»ºxhr对象 */
  const xhr = new XMLHttpRequest()
  xhr.open("GET", filePath.value, true)
  xhr.send()
  /* ç›‘听xhr对象 */
  xhr.addEventListener("load", () => {
    const resXML = xhr.responseXML
    let svgDom = resXML.documentElement.cloneNode(true)
    let values = svgDom.getElementsByTagName("text")
    for (let i = 0; i < values.length; i++) {
      let tag = tags.value.filter((f) => f.param === values[i].textContent)
      if (tag && tag.length > 0) {
        let tagCode = tag[0].tag
        values[i].textContent = ""
        if (tagCode) {
          values[i].setAttribute("id", tagCode)
          tagCodes.value.push(tagCode)
        }
      }
    }
    let oSerializer = new XMLSerializer()
    svgHtml.value = oSerializer.serializeToString(svgDom)
  })
}
defineExpose({ show })
</script>
<style lang="scss" scoped></style>
zhitan-vue/src/views/svg/equipmentfile/chartView.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,314 @@
<template>
  <div class="page">
    <div class="page-container">
      <div class="page-container-left">
        <LeftTree ref="leftTreeRef" @handleNodeClick="handleNodeClick" />
      </div>
      <div class="page-container-right">
        <BaseCard :title="queryParams.nodeName">
          <ConfigureChartView ref="ConfigureChartViewRef" />
        </BaseCard>
      </div>
    </div>
  </div>
</template>
<script setup name="energy-real-time-monitor">
import ConfigureChartView from "../components/configureView.vue"
import { listEnergyRealTimeMonitor } from "@/api/realTimeMonitor/realTimeMonitor"
import { getConfigure } from "@/api/svg/equipmentfile"
const { proxy } = getCurrentInstance()
import { useRoute } from "vue-router"
import useSettingsStore from "@/store/modules/settings"
const settingsStore = useSettingsStore()
watch(
  () => settingsStore.sideTheme,
  (val) => {
    // getList()
  }
)
const loading = ref(false)
const data = reactive({
  queryParams: {
    nodeId: null,
    nodeName: null,
    energyType: null,
  },
  query: { ...useRoute().query },
})
const { queryParams, query } = toRefs(data)
const ConfigureChartViewRef = ref()
/** èŠ‚ç‚¹å•å‡»äº‹ä»¶ */
function handleNodeClick(data) {
  queryParams.value.nodeId = data.id
  queryParams.value.nodeName = data.label
  if (!data.id) {
    return
  }
  getConfigure(data.id).then((response) => {
    if (response.code === 200) {
      let tagCodes = []
      if (response.data) {
        response.data.infoList.forEach((tag) => {
          tagCodes.push(tag.tag)
        })
      } else {
        tagCodes = []
      }
      ConfigureChartViewRef.value.show(data.id)
    } else {
      proxy.$modal.msgError(response.msg)
    }
  })
}
</script>
<style scoped lang="scss">
@import "@/assets/styles/page.scss";
.themeDark {
  .card-box {
    margin: 0 18px;
    padding: 10px 18px;
    box-shadow: 0px 4px 10px 0px rgba(0, 0, 0, 0.12);
    border-radius: 8px 8px 8px 8px;
    border: 1px solid #22408c;
    margin-bottom: 20px;
    &-title {
      // margin: 10px 0 10px;
      color: rgba(255, 255, 255, 0.8);
      text-align: left;
      font-weight: bold;
      font-family: OPPOSans, OPPOSans;
      font-weight: 500;
      font-size: 16px;
      font-style: normal;
      text-transform: none;
    }
    &-ul {
      display: flex;
      flex-wrap: wrap;
    }
    &-li {
      width: 18%;
      margin: 1%;
      border-radius: 5px;
      border: 1px solid #22408c;
      margin-bottom: 5px;
      background: #1a235d;
      box-shadow: 0px 4px 10px 0px rgba(0, 0, 0, 0.12);
      border-radius: 8px 8px 8px 8px;
      padding: 0 10px;
      .title {
        font-size: 14px;
        color: rgba(255, 255, 255, 0.8);
        font-family: OPPOSans, OPPOSans;
        font-weight: 500;
        font-size: 16px;
        line-height: 19px;
        text-align: left;
        font-style: normal;
        text-transform: none;
      }
      .num {
        font-size: 22px;
        color: #36d3ff;
        font-family: OPPOSans, OPPOSans;
        font-weight: 800;
        font-size: 32px;
        text-align: left;
        font-style: normal;
        text-transform: none;
      }
      .time {
        color: rgba(255, 253, 253, 0.7);
        font-family: Poppins, Poppins;
        font-weight: 400;
        text-align: left;
        font-style: normal;
        text-transform: none;
      }
    }
    dd {
      padding: 0;
      margin-left: 5px;
      margin-bottom: 10px;
    }
  }
  .hamburger {
    display: inline-block;
    vertical-align: middle;
    width: 20px;
    height: 20px;
  }
  .hamburger.is-active {
    transform: rotate(180deg);
  }
  .item-box {
    display: flex;
    justify-items: center;
    align-items: center;
    flex-wrap: wrap;
    margin: 10px 18px;
    .item-tag {
      // width: 13%;
      text-align: center;
      margin: 5px 8px;
      border-radius: 8px;
      padding: 7px 10px;
      font-family: OPPOSans, OPPOSans;
      font-weight: 500;
      font-size: 16px;
      color: #ffffff;
    }
  }
}
.themeLight {
  .card-box {
    margin: 0 18px;
    padding: 10px 18px;
    box-shadow: 0px 4px 10px 0px rgba(0, 0, 0, 0.12);
    border-radius: 8px 8px 8px 8px;
    margin-bottom: 20px;
    &-title {
      // margin: 10px 0 10px;
      text-align: left;
      font-weight: bold;
      font-family: OPPOSans, OPPOSans;
      font-weight: 500;
      font-size: 16px;
      font-style: normal;
      text-transform: none;
    }
    &-ul {
      display: flex;
      flex-wrap: wrap;
    }
    &-li {
      width: 240px;
      margin-right: 10px;
      margin-top: 16px;
      border-radius: 5px;
      border: 1px solid #ebebeb;
      margin-bottom: 5px;
      background: #fff;
      // box-shadow: 0px 4px 10px 0px rgba(0, 0, 0, 0.12);
      border-radius: 8px 8px 8px 8px;
      padding: 0 10px;
      .title {
        font-size: 14px;
        color: #676767;
        font-family: OPPOSans, OPPOSans;
        font-weight: 500;
        font-size: 16px;
        line-height: 19px;
        text-align: left;
        font-style: normal;
        text-transform: none;
      }
      .num {
        font-size: 22px;
        color: #3271eb;
        font-family: OPPOSans, OPPOSans;
        font-weight: 800;
        font-size: 32px;
        text-align: left;
        font-style: normal;
        text-transform: none;
      }
      .time {
        color: #676767;
        font-family: Poppins, Poppins;
        font-weight: 400;
        text-align: left;
        font-style: normal;
        text-transform: none;
      }
    }
    dd {
      padding: 0;
      margin-left: 5px;
      margin-bottom: 10px;
    }
  }
  .hamburger {
    display: inline-block;
    vertical-align: middle;
    width: 20px;
    height: 20px;
  }
  .hamburger.is-active {
    transform: rotate(180deg);
  }
  .item-box {
    display: flex;
    justify-items: center;
    align-items: center;
    flex-wrap: wrap;
    margin: 10px 18px;
    .item-tag {
      // width: 13%;
      text-align: center;
      margin: 5px 8px;
      border-radius: 8px;
      padding: 7px 3px;
      font-family: OPPOSans, OPPOSans;
      font-weight: 500;
      font-size: 16px;
      color: #ffffff;
    }
  }
}
.scrollbar-flex-content {
  display: flex;
  margin: 10px 18px;
}
.scrollbar-demo-item {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  // width: 100px;
  // height: 50px;
  // margin: 10px;
  text-align: center;
  border-radius: 4px;
  background: var(--el-color-danger-light-9);
  color: var(--el-color-danger);
}
.item-tag {
  // width: 13%;
  text-align: center;
  margin: 5px 8px;
  border-radius: 8px;
  padding: 7px 10px;
  font-family: OPPOSans, OPPOSans;
  font-weight: 500;
  font-size: 16px;
  color: #ffffff;
  cursor: pointer;
}
</style>
zhitan-vue/src/views/svg/equipmentfile/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,243 @@
<template>
  <div class="page">
    <div class="page-container">
      <div class="page-container-left">
        <div class="tree page-box">
          <div class="select-box mb20">
            æ•°æ®æ¨¡åž‹ï¼š
            <el-select
              style="width: 180px"
              v-model="modelData"
              placeholder="请选择模型"
              filterable
              @change="changeModel"
            >
              <el-option
                v-for="model in modelInfoOptions"
                :key="model.modelCode"
                :label="model.modelName"
                :value="model.modelCode"
              />
            </el-select>
          </div>
          <div class="tree-box" v-loading="treeLoading">
            <el-tree
              ref="treeRef"
              :props="defaultProps"
              :data="treeData"
              node-key="id"
              highlight-current
              :filter-node-method="filterNode"
              :default-expanded-keys="treeExpandData"
              :expand-on-click-node="false"
              @node-click="changeNode"
              accordion
            >
              <template #default="{ node, data }">
                <span>
                  <el-tooltip
                    v-if="node.label.length > 16"
                    class="item"
                    effect="dark"
                    :content="node.label"
                    placement="top-end"
                  >
                    <span>{{ node.label.slice(0, 16) + "..." }}</span>
                  </el-tooltip>
                  <span v-else id="b">{{ node.label }}</span>
                </span>
              </template>
            </el-tree>
          </div>
        </div>
      </div>
      <div class="page-container-right">
        <BaseCard :title="currentNode ? currentNode.label + '--节点配置' : '暂无节点配置'">
          <div class="content-box">
            <ConfigureView ref="configureViewRef" />
          </div>
        </BaseCard>
      </div>
    </div>
  </div>
</template>
<script setup>
import { listModel } from "@/api/modelConfiguration/businessModel"
import { treeList } from "@/api/modelConfiguration/indexWarehouse"
import ConfigureView from "../components/configure.vue"
import { nextTick } from "vue"
import { useRoute } from "vue-router"
let { proxy } = getCurrentInstance()
let treeLoading = ref(true)
let modelData = ref(null)
let modelInfoOptions = ref([]) //下拉列表
const configureViewRef = ref()
//获取下拉列表
function searchList(flag) {
  listModel({ isShow: 1 }).then((response) => {
    modelInfoOptions.value = response.data
    if (flag) {
      if (modelInfoOptions.value.length > 0) {
        if (proxy.$route.query.modelCode) {
          modelData.value = proxy.$route.query.modelCode
        } else {
          modelData.value = modelInfoOptions.value[0].modelCode
        }
        getTreeList(modelData.value)
      }
    }
  })
}
searchList(true)
//下拉选中触发树列表
function changeModel(item) {
  // console.log('changeModel', item)
  getTreeList(item)
}
let treeRef = ref(null)
let treeData = ref([])
const defaultProps = ref({
  children: "children",
  label: "label",
})
//检索树
let filterText = ref("")
const filterNode = (value, data) => {
  if (!value) return true
  return data.label.includes(value)
}
watch(filterText, (val) => {
  // æ£€æŸ¥treeRef.value是否是一个有效的ElTree实例
  if (treeRef.value && typeof treeRef.value.filter === "function") {
    // è°ƒç”¨filter方法
    treeRef.value.filter(val)
  } else {
    // treeRef.value无效,处理错误
    console.error("error")
  }
})
let currentNode = ref(null)
let treeExpandData = ref([])
let isFirstLeafNode = ref(false)
let deviceConfigRef = ref(null)
let collectIndicatorsRef = ref(null)
let statisticalIndicatorsRef = ref(null)
//获取树列表
function getTreeList(modelCode) {
  treeLoading.value = true
  treeList({ modelCode }).then((res) => {
    treeLoading.value = false
    let { data } = res
    treeData.value = data
    let chooseNode = null
    if (data.length > 0) {
      if (data[0].children && data[0].children.length !== 0 && isFirstLeafNode.value) {
        if (data[0].children[0].children && data[0].children[0].children.length !== 0) {
          chooseNode = data[0].children[0].children[0]
        } else {
          chooseNode = data[0].children[0]
        }
      } else {
        chooseNode = data[0]
      }
      currentNode.value = chooseNode
      changeNode(currentNode.value)
      treeExpandData.value.push(chooseNode.id)
      nextTick(() => {
        treeRef.value.setCurrentKey(chooseNode.id)
      })
    }
  })
}
//树点击
function changeNode(data, node, ev) {
  console.log("树点击", data)
  currentNode.value = data
  configureViewRef.value.changeModelNode(data)
}
</script>
<style lang="scss" scoped>
@import "@/assets/styles/page.scss";
.page-box {
  height: calc(100vh - 145px);
  padding-top: 12px;
  .tree-box {
    height: calc(100% - 70px);
    overflow-y: auto !important;
  }
  .select-box {
    display: flex;
    align-items: center;
    color: #3371eb;
    margin-left: 10px;
    :deep .el-icon {
      color: #fff;
      margin: 0 10px 0 15px;
      font-size: 14px;
    }
  }
  .node-opt {
    flex: 1;
    text-align: right;
    margin-right: 5px;
    :deep .el-icon {
      color: #fff;
      margin-right: 5px;
    }
  }
}
:deep .el-tabs__nav-wrap:after {
  background: transparent;
}
:deep .el-tabs__item {
  color: #fff;
  font-size: 20px;
  padding: 0 20px;
  &.is-active,
  &:hover {
    color: #999 !important;
  }
}
.tab-box {
  display: flex;
  align-items: center;
  color: #fff;
  border-bottom: 1px solid #3371eb;
  margin-right: 20px;
  .tab-li {
    cursor: pointer;
    border: 1px solid #3371eb;
    padding: 10px 25px;
    border-radius: 5px 5px 0 0;
  }
  .is-tab {
    background: #3371eb;
  }
}
.content-box {
  height: calc(100vh - 206px) !important;
}
</style>