Explorar el Código

水锤防护系统

xiaohaizhao hace 6 meses
padre
commit
becbc7f8c8

BIN
src/assets/controlPanel/icon/水锤防护.png


+ 39 - 23
src/router/index.js

@@ -1,69 +1,85 @@
-import { createRouter, createWebHashHistory } from 'vue-router'
+import {
+  createRouter,
+  createWebHashHistory
+} from 'vue-router'
 import modelNormal from './modelNormal.js'
 import controlPanle from './controlPanle.js'
 import IOT from "./IOT";
 
-import { useRouteTabsStore } from '@/stores/modules/Htabs'
-import { useAuthStore } from '@/stores/modules/auth'
+import {
+  useRouteTabsStore
+} from '@/stores/modules/Htabs'
+import {
+  useAuthStore
+} from '@/stores/modules/auth'
 
 
 
-const routes = [
-  {
+const routes = [{
     path: '/',
     name: 'login',
-    component: ()=>import(/* webpackChunkName: "about" */ '@/views/login/login.vue')
+    component: () => import( /* webpackChunkName: "about" */ '@/views/login/login.vue')
   },
   {
     path: '/home',
     name: 'home',
-    redirect:'/controlPanel',
-    component: ()=>import(/* webpackChunkName: "about" */ '@/components/layout/index.vue'),
-    children:[]
+    redirect: '/controlPanel',
+    component: () => import( /* webpackChunkName: "about" */ '@/components/layout/index.vue'),
+    children: []
   },
   {
     path: '/controlPanel',
     name: 'controlPanel',
-    component: ()=>import(/* webpackChunkName: "about" */ '@/views/controlPanel/index.vue'),
+    component: () => import( /* webpackChunkName: "about" */ '@/views/controlPanel/index.vue'),
   },
   {
     path: '/pressureControl',
     name: 'pressureControl',
     meta: {
-        title: '仪表盘',
-        name: 'pressureControl',
-        keepAlive:true
+      title: '仪表盘',
+      name: 'pressureControl',
+      keepAlive: true
     },
-    component: ()=>import(/* webpackChunkName: "about" */ '@/system/IOT/pressureControl/index.vue'),
+    component: () => import( /* webpackChunkName: "about" */ '@/system/IOT/pressureControl/index.vue'),
   },
   {
     path: '/positionControl',
     name: 'positionControl',
     meta: {
-        title: '仪表盘',
-        name: 'positionControl',
-        keepAlive:true
+      title: '仪表盘',
+      name: 'positionControl',
+      keepAlive: true
+    },
+    component: () => import( /* webpackChunkName: "about" */ '@/system/IOT/positionControl/index.vue'),
+  },
+  {
+    path: '/waterhammerControl',
+    name: 'waterhammerControl',
+    meta: {
+      title: '仪表盘',
+      name: 'waterhammerControl',
+      keepAlive: true
     },
-    component: ()=>import(/* webpackChunkName: "about" */ '@/system/IOT/positionControl/index.vue'),
+    component: () => import( /* webpackChunkName: "about" */ '@/system/IOT/waterhammerControl/index.vue'),
   },
   {
     path: '/404',
     name: '404',
-    component: ()=>import(/* webpackChunkName: "about" */ '@/views/404.vue'),
+    component: () => import( /* webpackChunkName: "about" */ '@/views/404.vue'),
   },
   {
     path: "/:catchAll(.*)",
     redirect: "/404"
   },
 ]
-routes[1].children = [...routes[1].children,...modelNormal,...IOT,...controlPanle]
+routes[1].children = [...routes[1].children, ...modelNormal, ...IOT, ...controlPanle]
 const router = createRouter({
   history: createWebHashHistory(),
   routes
 })
 
-router.beforeEach((to,from,next)=>{
-  let rs = useRouteTabsStore().historyRoutes.some(item=>item.name == from.name)
+router.beforeEach((to, from, next) => {
+  let rs = useRouteTabsStore().historyRoutes.some(item => item.name == from.name)
   if (to.path != '/controlPanel') useRouteTabsStore().saveRoute(to)
   useAuthStore().appData(to.meta.name)
   useRouteTabsStore().activeKey = to.name
@@ -72,4 +88,4 @@ router.beforeEach((to,from,next)=>{
 
 
 
-export default router
+export default router

+ 1293 - 0
src/system/IOT/waterhammerControl/index.vue

@@ -0,0 +1,1293 @@
+<template>
+  <div class="control">
+    <div class="bg_header">
+      <img src="@/assets/controlPanel/icon/水锤防护.png" alt="" />
+      <div class="header-handle">
+        <div><weather /></div>
+        <div>
+          <a-dropdown
+            class="dropdown-link"
+            overlayClassName="site-custom__classname"
+          >
+            <a class="ant-dropdown-link" @click.prevent>
+              <div class="siteinfo1">
+                <span style="margin-right: 25rem"
+                  ><EnvironmentOutlined />{{ nowAccount.sitename }}</span
+                >
+                <span style="margin-right: 10rem">{{ nowAccount.name }}</span>
+                <DownOutlined />
+              </div>
+            </a>
+            <template #overlay>
+              <a-menu>
+                <a-menu-item v-for="item in accountList" :key="item.index">
+                  <a @click="accountItemClick(item, false)">{{
+                    item.sitename + "-" + item.name
+                  }}</a>
+                </a-menu-item>
+                <a-menu-divider />
+                <a-menu-item>
+                  <LogoutOutlined />
+                  <a class="color-red" @click="loginOut">&nbsp;退出登录</a>
+                </a-menu-item>
+              </a-menu>
+            </template>
+          </a-dropdown>
+          <a-button
+            type="primary"
+            size="small"
+            @click="router.push('/controlPanel')"
+            style="position: absolute; right: 20rem; bottom: 0"
+            >退出</a-button
+          >
+        </div>
+      </div>
+    </div>
+    <div class="control_content">
+      <div class="control_content-left">
+        <ContentBox>
+          <div class="header">
+            <span>告警记录</span>
+            <a-button
+              type="primary"
+              size="small"
+              @click="goPage('/warningHistory')"
+              >进入</a-button
+            >
+          </div>
+          <div class="history-statistice">
+            <div>
+              <div class="history-item">
+                <span class="normal-title">今日告警量</span>
+                <span>{{ data.dataAll.today_total }}</span>
+              </div>
+              <div class="history-item">
+                <span class="normal-title">未处理</span>
+                <span>{{ data.dataAll.today_undeal }}</span>
+              </div>
+              <div class="history-item">
+                <span class="normal-title">已处理</span>
+                <span>{{ data.dataAll.today_deal }}</span>
+              </div>
+            </div>
+          </div>
+          <div class="history-wrapper" v-load-directive="warningLoad">
+            <div
+              :class="[{ move: warningMove }, { 'history-list': true }]"
+              @mouseenter="warningClose"
+              @mouseleave="warningScrollUp"
+              v-if="data.warningHistory.length"
+            >
+              <div
+                class="history-item"
+                v-for="(item, index) in data.warningHistory"
+                :key="index"
+              >
+                <a-tooltip>
+                  <template #title>
+                    <span>{{ item.devicename }}</span>
+                  </template>
+                  <span>{{ item.devicename }}</span>
+                </a-tooltip>
+                <a-tooltip>
+                  <template #title>
+                    <span>{{ item.eventname }}</span>
+                  </template>
+                  <span>{{ item.eventname }}</span>
+                </a-tooltip>
+                <span
+                  :style="{
+                    color: baseSet.styleObj(
+                      eventlevelList.filter(
+                        (v) => v.value == item.lasteventlevel
+                      )[0]
+                        ? eventlevelList.filter(
+                            (v) => v.value == item.lasteventlevel
+                          )[0].remarks
+                        : ''
+                    ).color,
+                  }"
+                  >{{
+                    eventlevelList.filter(
+                      (v) => v.value == item.lasteventlevel
+                    )[0]
+                      ? eventlevelList.filter(
+                          (v) => v.value == item.lasteventlevel
+                        )[0].remarks
+                      : ""
+                  }}</span
+                >
+                <span>{{ item.lasteventtime }}</span>
+              </div>
+            </div>
+            <a-empty :image="simpleImage" v-else>
+              <template #description>
+                <span style="color: #ffffff">暂无数据</span>
+              </template>
+            </a-empty>
+          </div>
+        </ContentBox>
+        <ContentBox>
+          <div class="header">
+            <span>本周告警统计</span>
+            <a-button
+              type="primary"
+              size="small"
+              @click="goPage('/warningControl', 'waterhammersystem')"
+              >进入</a-button
+            >
+          </div>
+          <div class="history-statistice">
+            <div>
+              <div class="history-item">
+                <span class="normal-title">本周告警量</span>
+                <span>{{ data.dataAll.week_total }}</span>
+              </div>
+              <div class="history-item">
+                <span class="normal-title">紧急</span>
+                <span>{{ data.dataAll.week_emergent }}</span>
+              </div>
+              <div class="history-item">
+                <span class="normal-title">重要</span>
+                <span>{{ data.dataAll.week_important }}</span>
+              </div>
+            </div>
+          </div>
+          <div class="map" ref="map"></div>
+        </ContentBox>
+      </div>
+      <div class="control_content-center">
+        <ContentBox>
+          <div class="header">
+            <span>设备监控</span>
+            <a-button
+              type="primary"
+              size="small"
+              @click="goPage('/equipmentManage')"
+              >进入</a-button
+            >
+          </div>
+          <div class="device-statistice">
+            <div class="device-item">
+              <div class="left">
+                <span>设备数</span>
+                <span>{{ data.dataAll.device_total }}</span>
+              </div>
+              <div class="right">
+                <img src="@/assets/controlPanel/icon/设备数.png" alt="" />
+              </div>
+            </div>
+            <div class="device-item">
+              <div class="left">
+                <span>在线数</span>
+                <span>{{ data.dataAll.device_online }}</span>
+              </div>
+              <div class="right">
+                <img src="@/assets/controlPanel/icon/在线数.png" alt="" />
+              </div>
+            </div>
+            <div class="device-item">
+              <div class="left">
+                <span>异常数</span>
+                <span>{{ data.dataAll.device_abnormal }}</span>
+              </div>
+              <div class="right">
+                <img src="@/assets/controlPanel/icon/异常数.png" alt="" />
+              </div>
+            </div>
+          </div>
+          <devices systemname='waterhammersystem' />
+        </ContentBox>
+      </div>
+      <div class="control_content-right">
+        <ContentBox>
+          <div class="header">
+            <span>待接收的命令</span>
+          </div>
+          <div class="info-wrapper" v-load-directive="cmdLoad">
+            <div class="info-list" v-if="data.cmdList.length">
+              <template v-for="item in data.cmdList">
+                <div
+                  class="info-item"
+                  v-for="(item2, index) in item.content"
+                  :key="index"
+                >
+                  <a-tooltip>
+                    <template #title>
+                      <span>{{ item.createdate }}</span>
+                    </template>
+                    <span>{{ item.createdate }}</span>
+                  </a-tooltip>
+                  <a-tooltip>
+                    <template #title>
+                      <span>{{ item.devicename }}</span>
+                    </template>
+                    <span>{{ item.devicename }}</span>
+                  </a-tooltip>
+                  <a-tooltip>
+                    <template #title>
+                      <span>{{ item2.title }}:{{ item2.value }}</span>
+                    </template>
+                    <span>{{ item2.title }}:{{ item2.value }}</span>
+                  </a-tooltip>
+                </div>
+              </template>
+            </div>
+            <a-empty :image="simpleImage" v-else>
+              <template #description>
+                <span style="color: #ffffff">暂无数据</span>
+              </template>
+            </a-empty>
+          </div>
+        </ContentBox>
+        <ContentBox>
+          <div class="header">
+            <span>操作记录</span>
+          </div>
+          <div class="handle-wrapper" v-load-directive="handleLoad">
+            <div
+              :class="[{ move: move }, { 'handle-list': true }]"
+              @mouseenter="close"
+              @mouseleave="scrollUp"
+              v-if="data.handleHistory.length"
+            >
+              <div
+                class="info-item"
+                v-for="(item, index) in data.handleHistory"
+                :key="index"
+              >
+                <a-tooltip>
+                  <template #title>
+                    <span>{{ item.createdate }}</span>
+                  </template>
+                  <span>{{ item.createdate }}</span>
+                </a-tooltip>
+                <a-tooltip>
+                  <template #title>
+                    <span>{{ item.devicename }}</span>
+                  </template>
+                  <span>{{ item.devicename }}</span>
+                </a-tooltip>
+                <a-tooltip>
+                  <template #title>
+                    <span>{{ item.title }}:{{ item.value }}</span>
+                  </template>
+                  <span>{{ item.title }}:{{ item.value }}</span>
+                </a-tooltip>
+              </div>
+            </div>
+            <a-empty :image="simpleImage" v-else>
+              <template #description>
+                <span style="color: #ffffff">暂无数据</span>
+              </template>
+            </a-empty>
+          </div>
+        </ContentBox>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import weather from "@/components/weather/index.vue";
+import devices from "../pressureControl/modules/devices.vue"
+import { Empty, Modal } from "ant-design-vue";
+import {
+  EnvironmentOutlined,
+  DownOutlined,
+  ExclamationCircleOutlined,
+} from "@ant-design/icons-vue";
+const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE;
+import baseSet from "../warningControl/baseSet.js";
+import ContentBox from "../pressureControl/modules/Box.vue";
+import { Line } from "@antv/g2plot";
+import {
+  ref,
+  defineProps,
+  defineEmits,
+  onMounted,
+  onUnmounted,
+  onBeforeMount,
+  onDeactivated,
+  watch,
+  createVNode,
+} from "vue";
+import Api from "@/api/api";
+import utils from "@/utils/utils";
+import { onBeforeRouteUpdate, useRouter } from "vue-router";
+import { useRouteTabsStore } from "@/stores/modules/Htabs";
+import { useAuthStore } from "@/stores/modules/auth";
+import { storeToRefs } from "pinia";
+const store = useAuthStore();
+let { system, mods, actSystem, openKeys, app, accountList, nowAccount } =
+  storeToRefs(store);
+
+const rotTabs = useRouteTabsStore();
+let { historyRoutes } = storeToRefs(rotTabs);
+const emit = defineEmits([]);
+const router = useRouter();
+let map = ref();
+let line = ref();
+let eventlevelList = ref([]);
+let loading = ref(false);
+
+let timer = ref();
+let move = ref(false);
+
+const accountItemClick = (account, bool) => {
+  store.defaultAccount(account, () => {
+    store.reloadPage();
+    setTimeout(() => {
+      getBaseInfo();
+      historyDataFun();
+      isRefresh.value = true;
+    }, 1500);
+    // historyRoutes.value = []
+  });
+  if (!bool) {
+    if (router.currentRoute.value.meta.isDetail) {
+      router.go(-1);
+    }
+  } else {
+    router.go(0);
+  }
+};
+
+const loginOut = () => {
+  Modal.confirm({
+    title: "注意",
+    icon: createVNode(ExclamationCircleOutlined),
+    content: "确定登出当前账号吗?",
+    okText: "确认",
+    cancelText: "取消",
+    onOk() {
+      historyRoutes.value = [];
+      Api.loginout({});
+      router.push({ path: "/" });
+    },
+  });
+};
+
+let goPage = (path, name) => {
+  if (name) {
+    router.push({ path: path, query: { systemname: name } });
+  } else {
+    router.push(path);
+  }
+  setTimeout(() => {
+    console.log(system.value, app.value);
+    let result;
+    system.value.forEach((item) => {
+      item.modules.forEach((item2) => {
+        if (item2.systemmoduleid == app.value.systemmoduleid) {
+          result = item;
+        }
+      });
+    });
+    actSystem.value = result;
+    store.modulesData(result);
+    openKeys.value.push(result.modules[0].apps[0].systemmoduleid);
+  });
+};
+
+let calcSizeFun = () => {
+  let baseSize = 1920;
+  console.log(document.body.clientWidth);
+  document.querySelector("html").style.fontSize = `${100 / baseSize}vw`;
+};
+
+let scrollUp = () => {
+  timer.value = setInterval(() => {
+    let wrapper = document.querySelector(".handle-wrapper").clientHeight;
+    let list = document.querySelector(".handle-list").clientHeight;
+    if (list < wrapper) return;
+    move.value = true;
+    setTimeout(() => {
+      data.value.handleHistory.push(data.value.handleHistory.shift());
+      move.value = false;
+    }, 500);
+  }, 2000);
+};
+
+let close = () => {
+  clearInterval(timer.value);
+};
+
+let warningMove = ref(false);
+let timer2 = ref();
+let warningScrollUp = () => {
+  timer2.value = setInterval(() => {
+    let wrapper = document.querySelector(".history-wrapper").clientHeight;
+    let list = document.querySelector(".history-list").clientHeight;
+    if (list < wrapper) return;
+    warningMove.value = true;
+    setTimeout(() => {
+      data.value.warningHistory.push(data.value.warningHistory.shift());
+      warningMove.value = false;
+    }, 500);
+  }, 2000);
+};
+
+let warningClose = () => {
+  clearInterval(timer2.value);
+};
+
+/* 数据变量 */
+let data = ref({
+  dataAll: {},
+  warningMapData: [],
+  warningHistory: [],
+  deviceList: [],
+  handleHistory: [],
+  cmdList: [],
+});
+
+let warningParam = ref({
+  id: 20230914133102,
+  content: {
+    systemname: "waterhammersystem",
+    pageNumber: 1,
+    pageSize: 30,
+  },
+});
+
+
+let cmdParam = ref({
+  id: 20230914133402,
+  content: {
+    systemname: "waterhammersystem",
+    pageNumber: 1,
+    pageSize: 10,
+  },
+});
+
+let handleParam = ref({
+  id: 20230914133502,
+  content: {
+    systemname: "waterhammersystem",
+    pageNumber: 1,
+    pageSize: 30,
+  },
+});
+
+let listData = async () => {
+  let res = await Api.requested({
+    id: 20230914133002,
+    content: { systemname: "waterhammersystem" },
+  });
+  data.value.dataAll = res.data;
+  console.log(data.value.dataAll, "数据统计");
+
+  let res3 = await Api.requested({
+    id: 20230914133202,
+    content: { systemname: "waterhammersystem" },
+  });
+  data.value.warningMapData = res3.data;
+  data.value.warningMapData.forEach((item) => (item.次数 = item.count));
+  line.value.changeData(data.value.warningMapData);
+  console.log(data.value.warningMapData, "告警统计");
+};
+
+let deviceClick = (data) => {
+  router.push({
+    path: "/" + (data.dashboardpath || "baseDevice"),
+    query: {
+      id: data.w_deviceid,
+    },
+  });
+};
+
+let warningTotalPage = ref(0);
+let warningLoad = () => {
+  console.log("触发");
+  if (
+    warningParam.value.content.pageNumber == warningTotalPage.value ||
+    loading.value == true
+  )
+    return;
+  warningParam.value.content.pageNumber += 1;
+  console.log(warningParam.value);
+  getwarningData();
+};
+
+let getwarningData = async () => {
+  loading.value = true;
+  let res = await Api.requested(warningParam.value);
+  data.value.warningHistory =
+    warningParam.value.content.pageNumber == 1
+      ? res.data
+      : data.value.warningHistory.concat(res.data);
+  data.value.warningHistory.forEach((item) => {
+    item.lasteventtime = item.lasteventtime.slice(5, item.lasteventtime.length);
+  });
+  warningTotalPage.value = res.pageTotal;
+  setTimeout(() => {
+    loading.value = false;
+  }, 1500);
+  console.log(data.value.warningHistory, "告警记录");
+};
+
+let cmdTotalPage = ref(0);
+let cmdLoad = () => {
+  if (
+    cmdParam.value.content.pageNumber == cmdTotalPage.value ||
+    loading.value == true
+  )
+    return;
+  cmdParam.value.content.pageNumber += 1;
+  console.log(cmdParam.value);
+  getCmdData();
+};
+
+let getCmdData = async () => {
+  loading.value = true;
+  let res = await Api.requested(cmdParam.value);
+  data.value.cmdList =
+    cmdParam.value.content.pageNumber == 1
+      ? res.data
+      : data.value.cmdList.concat(res.data);
+  data.value.cmdList.forEach((item) => {
+    item.createdate = item.createdate.slice(5, item.createdate.length);
+  });
+  cmdTotalPage.value = res.pageTotal;
+  setTimeout(() => {
+    loading.value = false;
+  }, 1500);
+  console.log(data.value.cmdList, "cmd列表");
+};
+
+let handleTotalPage = ref(0);
+let handleLoad = () => {
+  if (
+    handleParam.value.content.pageNumber == handleTotalPage.value ||
+    loading.value == true
+  )
+    return;
+  handleParam.value.content.pageNumber += 1;
+  console.log(handleParam.value);
+  getHanleData();
+};
+
+let getHanleData = async () => {
+  loading.value = true;
+  let res = await Api.requested(handleParam.value);
+  // data.value.handleHistory = handleParam.value.content.pageNumber == 1 ? res.data : data.value.handleHistory.concat(res.data)
+  res.data.forEach((item) => {
+    item.content.forEach((item2) => {
+      data.value.handleHistory.push({
+        devicename: item.devicename,
+        createdate: item.createdate.slice(5, item.createdate.length),
+        title: item2.title,
+        value: item2.value,
+      });
+    });
+  });
+  handleTotalPage.value = res.pageTotal;
+  setTimeout(() => {
+    loading.value = false;
+  }, 1000);
+  console.log(data.value.handleHistory, "操作记录");
+};
+
+let initChart = () => {
+  line.value = new Line(map.value, {
+    data: data.value.warningMapData,
+    xField: "date",
+    yField: "次数",
+    yAxis: {
+      label: {
+        style: {
+          fill: "#ffffff",
+        },
+      },
+    },
+    xAxis: {
+      label: {
+        style: {
+          fill: "#ffffff",
+        },
+      },
+    },
+    color: ["#16FFF6", "rgba(255, 164, 6)"],
+    legend: {
+      position: "bottom",
+      itemName: {
+        style: {
+          fill: "#ffffff",
+        },
+      },
+    },
+    tooltip: {
+      // formatter:(v) => {
+      //   return {name:v.paramname,value:v.value + chartData.value.find(item => item.paramname == v.paramname).unit}
+      // }
+    },
+    area: {
+      style: {
+        fillOpacity: 0.15,
+      },
+    },
+    // @TODO 后续会换一种动画方式
+    animation: {
+      appear: {
+        animation: "path-in",
+        duration: 3000,
+      },
+    },
+  });
+  line.value.render();
+};
+
+let vLoadDirective = {
+  mounted(el, binding) {
+    let tableWarp = el;
+    function handleFun(e) {
+      if (
+        tableWarp.scrollTop + tableWarp.clientHeight >=
+        tableWarp.scrollHeight
+      ) {
+        binding.value();
+      }
+    }
+    tableWarp.addEventListener("scroll", handleFun);
+    el.tableWarp = tableWarp;
+    el.handleFun = handleFun;
+  },
+  unmounted(el) {
+    el.tableWarp.removeEventListener("scroll", el.handleFun);
+  },
+};
+
+onMounted(async () => {
+  calcSizeFun();
+  initChart();
+  listData();
+  getCmdData();
+  getDeviceData();
+  getHanleData();
+  getwarningData();
+  scrollUp();
+  warningScrollUp();
+  const res = await Api.optionstype("eventlevel");
+  eventlevelList.value = res.data;
+  console.log("警告等级", eventlevelList.value);
+  console.log(router.currentRoute.value.path);
+});
+
+router.beforeEach((to, from, next) => {
+  clearInterval(timer2.value);
+  clearInterval(timer.value);
+  next();
+});
+</script>
+
+<style>
+.site-custom__classname .ant-dropdown-menu {
+  background: rgba(5, 54, 178, 0.7) !important;
+  color: #ffffff !important;
+  padding: 0 !important;
+}
+.site-custom__classname .ant-dropdown-menu-item {
+  color: #ffffff !important;
+}
+.site-custom__classname .ant-dropdown-menu-item:hover {
+  background: rgba(5, 54, 178, 0.1) !important;
+}
+</style>
+<style scoped>
+.header-handle {
+  padding: 0 40rem;
+  transform: translateY(-20rem);
+  display: flex;
+  justify-content: space-between;
+}
+.weather-panel {
+  font-size: 14rem;
+  font-weight: bold;
+}
+.ant-btn-primary {
+  background: rgb(20, 49, 125) !important;
+  border-color: rgb(20, 49, 125) !important;
+}
+/deep/.weather-panel .white {
+  display: none;
+}
+/deep/.weather-panel span:nth-child(2) {
+  margin-right: 15rem;
+}
+/deep/.weather-panel span:nth-child(3) {
+  margin-right: 3rem;
+}
+/deep/.weather-panel span:nth-child(4) {
+}
+/deep/.weather-panel span:last-child {
+}
+.siteinfo1 {
+  color: #ffffff !important;
+  font-size: 14rem;
+  font-weight: bold;
+  z-index: 999999;
+  margin-right: 40rem;
+}
+.normal-title {
+  font-size: 16rem;
+  color: #ffffff;
+}
+.header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  font-size: 14rem;
+  font-weight: bold;
+  margin-bottom: 20rem;
+}
+* {
+  box-sizing: border-box;
+}
+.control {
+  width: 100%;
+  height: 100vh;
+  background: #02004d;
+  color: #ffffff;
+  --color1: #16fff6;
+  --color2: rgba(255, 164, 6);
+  overflow: hidden;
+}
+.control .bg_header {
+  position: relative;
+}
+.control .bg_header img {
+  width: 100%;
+}
+
+.control .control_content {
+  width: 100%;
+  height: calc(100vh - 110rem);
+  margin-top: 10rem;
+  padding: 0 10rem 10rem 10rem;
+  display: flex;
+}
+.control .control_content .control_content-left {
+  flex: 1;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  overflow: hidden;
+}
+.control .control_content .control_content-left .content_box {
+  height: 50%;
+}
+.control .control_content .control_content-left .content_box:first-child {
+  margin-bottom: 15rem;
+}
+.control .control_content .control_content-left .history-statistice {
+  display: flex;
+}
+.control .control_content .control_content-left .history-statistice > div {
+  margin: 0 auto;
+  display: flex;
+}
+.control
+  .control_content
+  .control_content-left
+  .history-statistice
+  .history-item {
+  display: flex;
+  flex-direction: column;
+  text-align: center;
+  margin-right: 20rem;
+}
+
+.control
+  .control_content
+  .control_content-left
+  .history-statistice
+  .history-item
+  span:last-child {
+  color: var(--color2);
+  font-size: 16rem;
+  font-weight: bold;
+}
+.control .control_content .control_content-left .history-wrapper {
+  height: calc(100% - 110rem);
+  overflow-y: scroll;
+  margin-top: 15rem;
+  padding-bottom: 15rem;
+}
+::-webkit-scrollbar {
+  display: none;
+}
+.control .control_content .control_content-left .history-wrapper .history-item {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 10rem;
+  cursor: pointer;
+}
+.control
+  .control_content
+  .control_content-left
+  .history-wrapper
+  .history-item:last-child {
+  margin: 0;
+}
+.control
+  .control_content
+  .control_content-left
+  .history-wrapper
+  .history-item:hover {
+  background: rgba(255, 255, 255, 0.4);
+}
+
+.control
+  .control_content
+  .control_content-left
+  .history-wrapper
+  .history-item
+  span {
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.control
+  .control_content
+  .control_content-left
+  .history-wrapper
+  .history-item
+  span:nth-child(1) {
+  flex: 1;
+}
+.control
+  .control_content
+  .control_content-left
+  .history-wrapper
+  .history-item
+  span:nth-child(2) {
+  flex: 1;
+}
+.control
+  .control_content
+  .control_content-left
+  .history-wrapper
+  .history-item
+  span:nth-child(3) {
+  flex: 0.5;
+}
+.control
+  .control_content
+  .control_content-left
+  .history-wrapper
+  .history-item
+  span:nth-child(4) {
+  flex: 1;
+}
+.control .control_content .control_content-left .map {
+  height: calc(100% - 120rem);
+}
+.control .control_content .control_content-center {
+  flex: 1.5;
+  height: 100%;
+  min-width: 565rem;
+}
+.control .control_content .control_content-center .device-statistice {
+  display: flex;
+  justify-content: space-between;
+  margin: 15rem;
+}
+.control
+  .control_content
+  .control_content-center
+  .device-statistice
+  .device-item {
+  display: flex;
+  flex: 1;
+  justify-content: space-between;
+  border: 1rem solid var(--color1);
+  margin-right: 20rem;
+  padding: 10rem 20rem;
+  color: var(--color1);
+}
+.siteinfo {
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 100%;
+}
+.siteinfo .siteinfo-wrapper {
+  display: flex;
+  align-items: center;
+  align-self: flex-start;
+  width: 100%;
+  background: #40a9ff;
+}
+.siteinfo span {
+  margin-left: 10px;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  overflow: hidden;
+  font-size: 14rem;
+}
+.control
+  .control_content
+  .control_content-center
+  .device-statistice
+  .device-item:last-child {
+  margin: 0;
+}
+.control
+  .control_content
+  .control_content-center
+  .device-statistice
+  .device-item
+  .left {
+  display: flex;
+  justify-content: space-between;
+  flex-direction: column;
+}
+.control
+  .control_content
+  .control_content-center
+  .device-statistice
+  .device-item
+  .left
+  span:last-child {
+  color: var(--color2);
+  font-size: 16rem;
+  font-weight: bold;
+}
+.control
+  .control_content
+  .control_content-center
+  .device-statistice
+  .device-item
+  .right {
+  width: 50rem;
+  height: 50rem;
+  display: flex;
+  align-items: center;
+}
+.control
+  .control_content
+  .control_content-center
+  .device-statistice
+  .device-item
+  .right
+  img {
+  width: 100%;
+  margin-bottom: 0 !important;
+}
+.control .control_content .control_content-center .device-wrapper {
+  overflow-y: scroll;
+  height: calc(100% - 180rem);
+  margin-top: 40rem;
+}
+.control .control_content .control_content-center .device-wrapper .device-list {
+  display: flex;
+  flex-wrap: wrap;
+}
+.control
+  .control_content
+  .control_content-center
+  .device-wrapper
+  .device-list
+  .used {
+  display: inline-block;
+  width: 10rem;
+  height: 10rem;
+  border-radius: 10rem;
+  background: var(--icon);
+  margin-right: 10rem;
+}
+.control
+  .control_content
+  .control_content-center
+  .device-wrapper
+  .device-list
+  .device-title {
+  display: flex;
+  align-items: center;
+  height: 44rem;
+  font-size: 14rem;
+}
+.control
+  .control_content
+  .control_content-center
+  .device-wrapper
+  .device-list
+  .device-title,
+img,
+.status {
+  margin-bottom: 10rem;
+  font-size: 14rem;
+}
+.control
+  .control_content
+  .control_content-center
+  .device-wrapper
+  .device-list
+  .device-title
+  span {
+  display: inline-block;
+  width: 140rem;
+  text-overflow: ellipsis;
+  overflow: hidden;
+  display: -webkit-box;
+  -webkit-line-clamp: 2;
+  -webkit-box-orient: vertical;
+  word-break: break-all;
+}
+.control
+  .control_content
+  .control_content-center
+  .device-wrapper
+  .device-list
+  .content_box {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  align-content: center;
+  padding: 0 25rem;
+  margin-bottom: 15rem;
+  cursor: pointer;
+}
+.control
+  .control_content
+  .control_content-center
+  .device-wrapper
+  .device-list
+  .content_box:hover {
+  --color: red !important;
+}
+.control
+  .control_content
+  .control_content-center
+  .device-wrapper
+  .device-list
+  .content_box:hover
+  img {
+  transition: all 0.2s;
+  transform: scale(1.2);
+}
+.control
+  .control_content
+  .control_content-center
+  .device-wrapper
+  .device-list
+  .i {
+  width: 20rem;
+  height: 20rem;
+  border-radius: 20rem;
+  background: red;
+}
+.control
+  .control_content
+  .control_content-center
+  .device-wrapper
+  .device-list
+  img {
+  width: 100%;
+  max-height: 70rem;
+}
+.control
+  .control_content
+  .control_content-center
+  .device-wrapper
+  .device-list
+  .status {
+  color: var(--color2);
+}
+.control .control_content .control_content-center .content_box {
+  height: 100%;
+  margin: 0 18rem;
+  width: auto !important;
+  flex: 1;
+}
+.control .control_content .control_content-center .device-list .content_box {
+  flex: 1 !important;
+  max-width: 212rem;
+}
+.control .control_content .control_content-right {
+  flex: 1;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  overflow: hidden;
+}
+.control .control_content .control_content-right .content_box:first-child {
+  margin-bottom: 15rem;
+  height: 35%;
+}
+.control .control_content .control_content-right .content_box:last-child {
+  height: 65%;
+}
+.control .control_content .control_content-right .info-wrapper {
+  height: calc(100% - 30rem);
+  overflow-y: scroll;
+}
+.control .control_content .control_content-right .info-wrapper .info-list {
+}
+.control
+  .control_content
+  .control_content-right
+  .info-wrapper
+  .info-list
+  .info-item {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 10rem;
+  cursor: pointer;
+}
+.control
+  .control_content
+  .control_content-right
+  .info-wrapper
+  .info-list
+  .info-item:hover {
+  background: rgba(255, 255, 255, 0.4);
+}
+.control
+  .control_content
+  .control_content-right
+  .info-wrapper
+  .info-list
+  .info-item
+  span {
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+.control
+  .control_content
+  .control_content-right
+  .info-wrapper
+  .info-list
+  .info-item
+  span:nth-child(1) {
+  flex: 1;
+}
+.control
+  .control_content
+  .control_content-right
+  .info-wrapper
+  .info-list
+  .info-item
+  span:nth-child(2) {
+  flex: 1;
+}
+.control
+  .control_content
+  .control_content-right
+  .info-wrapper
+  .info-list
+  .info-item
+  span:nth-child(3) {
+  flex: 2;
+}
+.control
+  .control_content
+  .control_content-right
+  .info-wrapper
+  .info-list
+  .info-item
+  span:nth-child(1) {
+  color: var(--color1);
+}
+.control
+  .control_content
+  .control_content-right
+  .info-wrapper
+  .info-list
+  .info-item
+  span:nth-child(2) {
+  color: var(--color2);
+}
+
+.control .control_content .control_content-right .handle-wrapper {
+  height: calc(100% - 30rem);
+  overflow-y: scroll;
+}
+.control .control_content .control_content-right .handle-wrapper .handle-list {
+}
+.control
+  .control_content
+  .control_content-right
+  .handle-wrapper
+  .handle-list
+  .info-item {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 10rem;
+  cursor: pointer;
+}
+.control
+  .control_content
+  .control_content-right
+  .handle-wrapper
+  .handle-list
+  .info-item:hover {
+  background: rgba(255, 255, 255, 0.4);
+}
+.control
+  .control_content
+  .control_content-right
+  .handle-wrapper
+  .handle-list
+  .info-item
+  span {
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+.control
+  .control_content
+  .control_content-right
+  .handle-wrapper
+  .handle-list
+  .info-item
+  span:nth-child(1) {
+  flex: 1;
+}
+.control
+  .control_content
+  .control_content-right
+  .handle-wrapper
+  .handle-list
+  .info-item
+  span:nth-child(2) {
+  flex: 1;
+}
+.control
+  .control_content
+  .control_content-right
+  .handle-wrapper
+  .handle-list
+  .info-item
+  span:nth-child(3) {
+  flex: 2;
+}
+.control
+  .control_content
+  .control_content-right
+  .handle-wrapper
+  .handle-list
+  .info-item
+  span:nth-child(1) {
+  color: var(--color1);
+}
+.control
+  .control_content
+  .control_content-right
+  .handle-wrapper
+  .handle-list
+  .info-item
+  span:nth-child(2) {
+  color: var(--color2);
+}
+.content_box {
+  padding: 10rem 15rem;
+}
+.move {
+  margin-top: -30rem;
+  transition: all 0.5s ease-in-out;
+}
+</style>

+ 1 - 1
src/views/controlPanel/index.vue

@@ -102,7 +102,7 @@
               <img src="@/assets/controlPanel/icon/标题分割线.png" alt="" style="margin-top: 20rem;width: 50rem;">
             </div>
             <div class="system_box">
-              <div class="item" @click="itemClick('')">
+              <div class="item" @click="itemClick('waterhammerprotection')">
                 <p>水锤防护<br/>系统</p>
                 <img src="@/assets/controlPanel/icon/水锤防护系统.png" alt="">
               </div>

+ 4 - 4
vite.config.js

@@ -12,15 +12,15 @@ export default defineConfig({
   },
   define: {
     'process.env': {
-      'BASE_API':"http://60.204.153.188"
-      // 'BASE_API':"http://61.164.207.46:8100/"
+      // 'BASE_API':"http://60.204.153.188"
+      'BASE_API':"http://61.164.207.46:8100/"
     }
   },
   server: {
     proxy: {
       "/api": {
-        target: "http://60.204.153.188/",
-        // target: "http://61.164.207.46:8100/",
+        // target: "http://60.204.153.188/",
+        target: "http://61.164.207.46:8100/",
         ws: true,
         changeOrigin: true,
         rewrite: (path) => path.replace(/^\/api/, ""),