Переглянути джерело

报警气泡模块修改,改为可配置多列报警的模式,具体列数和每列显示条数均可由用户自行配置、新增历史报警获取出错时的窗口提醒,其他常规BUG修复。

Koishi 1 рік тому
батько
коміт
a7dbb5a536

+ 3 - 1
README.md

@@ -8,6 +8,8 @@
         - 重构页面由原来的三个报警区域改为六个报警区域,新增功能每个报警区域点击后显示弹出层以便更详尽显示报警列表信息。
     - 报警记录
         - 更换页面所用接口、调整表格所用字段。
+    - 预警查询
+        - 新增页面,用于查询自定义类的风机、升压站、逆变器报警。
     - 停机查询
         - 新增停机查询模块与接口联调。
     - 数据查询
@@ -31,4 +33,4 @@
     - 页面重构、现五个级别可以分别设置自己独立的规则并保存了,新增报警弹窗上限数量修改框,可根据自身需求动态修改弹窗弹出的上限值
 - 其他
     - 全局报警提醒
-        - 新增全局窗口提醒功能,实时监听 WS 获取报警状态并于系统右下角排列展示,其中危险等级达到要求的部分报警会以播放声音的形式告知用户。
+        - 新增全局窗口提醒功能,实时监听 WS 获取报警状态并于系统右下角多列展示,展示的列数与每列上限的条数可配置,其中危险等级达到要求的部分报警会以播放声音的形式告知用户。

+ 4 - 3
src/api/api.js

@@ -1,6 +1,6 @@
 import request from "./axios.js";
 export const baseURL = "http://10.81.3.154:6015/";
-// export const baseURL = "http://192.168.1.102:6015/";
+// export const baseURL = "http://192.168.1.101:6015/";
 import JSONBIG from "json-bigint";
 
 // 获取场站数据
@@ -190,11 +190,12 @@ export const getAdapterHistorysnap = (
 };
 
 //查询历史报警记录
-export const alarm_history = (params) => {
+export const alarm_history = (params, timeout = 2000) => {
     return request({
         url: `alarm/history/findAlarmlist`,
         params: params,
         baseURL,
+        timeout
     });
 };
 
@@ -837,7 +838,7 @@ export const saveAlartConfig = (data) => {
     });
 };
 
-export const getWtModel = (wpId) => {
+export const getWtModel = (wpId = "") => {
     return request({
         baseURL,
         method: "get",

+ 271 - 178
src/components/alarmPopupa/index.vue

@@ -1,45 +1,68 @@
 <template>
-  <div class="alarmBox" :class="alarmList?.length ? 'notEmpty' : ''">
+  <div
+    class="alarmBox"
+    :class="alarmList?.length ? 'notEmpty' : ''"
+    :style="`width: ${getAlarmBoxWidth()}px;`"
+  >
     <div
-      :class="`${index < $store.state.alarmShowNumber ? item.class + ' alarmItem animate__animated' : ''}`"
-      v-for="(item, index) in alarmList"
-      :key="index"
+      class="columnItem"
+      v-for="columnNumber in $store.state.columnNumber"
+      :key="columnNumber"
+      v-show="alarmList[(columnNumber - 1) * $store.state.alarmShowNumber]"
     >
-      <template v-if="index < $store.state.alarmShowNumber">
-        <div class="alarmTitle">{{ item.wpName }}&nbsp;{{ item.code }}</div>
-        <div class="alarmContent">
-          <div class="contentItem" @click="goToAlertDescPage(item)">
-            报警描述:
-            <span class="alertDescCursor">{{ item.description }}</span>
+      <div
+        :class="`${
+          index >= (columnNumber - 1) * $store.state.alarmShowNumber &&
+          index < columnNumber * $store.state.alarmShowNumber
+            ? item.class + ' alarmItem animate__animated'
+            : ''
+        }`"
+        v-for="(item, index) in alarmList"
+        :key="index"
+      >
+        <template
+          v-if="
+            index >= (columnNumber - 1) * $store.state.alarmShowNumber &&
+            index < columnNumber * $store.state.alarmShowNumber
+          "
+        >
+          <div class="alarmTitle">{{ item.wpName }}&nbsp;{{ item.code }}</div>
+          <div class="alarmContent">
+            <div class="contentItem" @click="goToAlertDescPage(item)">
+              报警描述:
+              <span class="alertDescCursor">{{ item.description }}</span>
+            </div>
+            <div class="contentItem">报警时间:{{ item.tsName }}</div>
           </div>
-          <div class="contentItem">报警时间: {{ item.tsName }}</div>
-        </div>
-        <div class="btnBox" :class="`lv${item.lv}BdColor`">
-          <div class="btnItem" :class="`lv${item.lv}BdColor lv${item.lv}`">
-            <el-button
-              class="comfirmBtn"
-              size="small"
-              type="text"
-              @click="comfirm(item)"
-              >确认本条</el-button
-            >
+          <div class="btnBox" :class="`lv${item.lv}BdColor`">
+            <div class="btnItem" :class="`lv${item.lv}BdColor lv${item.lv}`">
+              <el-button
+                class="comfirmBtn"
+                size="small"
+                type="text"
+                @click="comfirm(item)"
+                >确认本条</el-button
+              >
+            </div>
+            <div class="btnItem" :class="`lv${item.lv}`">
+              <el-button
+                class="comfirmBtn"
+                size="small"
+                type="text"
+                @click="comfirmAll"
+                >全部确认</el-button
+              >
+            </div>
           </div>
-          <div class="btnItem" :class="`lv${item.lv}`">
-            <el-button
-              class="comfirmBtn"
-              size="small"
-              type="text"
-              @click="comfirmAll"
-              >全部确认</el-button
-            >
-          </div>
-        </div>
-      </template>
+        </template>
+      </div>
     </div>
   </div>
 </template>
 <script>
 import { confirmAlart, getAlartConfig, alarm_history } from "@api/api.js";
+import { h } from "vue";
+import { ElNotification } from "element-plus";
 import dayJs from "dayjs";
 export default {
   data() {
@@ -51,6 +74,7 @@ export default {
       ws: null,
       timeConnect: 0,
       limitConnect: 5,
+      columnNumber: 2,
       requestAlarmHistoryParams: [
         {
           alarmType: "booststation",
@@ -89,16 +113,40 @@ export default {
           requestResult.push(this.getAlarmHistory(alarmType, deviceType));
         });
 
-        Promise.all(requestResult).then((promiseResult) => {
-          promiseResult.forEach(({ data }) => {
-            data?.ls?.forEach((ele) => {
-              this.pushALarmItem(ele);
+        Promise.all(requestResult)
+          .then((promiseResult) => {
+            promiseResult.forEach(({ data }) => {
+              data?.ls?.forEach((ele) => {
+                this.pushALarmItem(ele);
+              });
+            });
+            this.webSocketInit(
+              `ws://10.81.3.154:6014/websocket/${this.$store.state.user.userId}_${this.$store.state.user.authToken}`
+            );
+          })
+          .catch(() => {
+            requestResult.forEach((ele, index) => {
+              ele
+                .then(({ data }) => {
+                  data?.ls?.forEach((ele) => {
+                    this.pushALarmItem(ele);
+                  });
+                })
+                .catch((error) => {
+                  ElNotification({
+                    type: "error",
+                    title: "查询历史未处理报警请求出错!",
+                    dangerouslyUseHTMLString: true,
+                    message: `<div class="currentRequestErrorNotification">
+                                <p><span>主要参数:</p>
+                                <p style="color:var(--el-color-primary)"><span class="errorTitle">alarmType:</span><span class="errorDesc">"${this.requestAlarmHistoryParams[index].alarmType}"</span></p>
+                                <p style="color:var(--el-color-primary)"><span class="errorTitle">deviceType:</span><span class="errorDesc">"${this.requestAlarmHistoryParams[index].deviceType}"</span></p>
+                                <p style="color:var(--el-color-danger)"><span class="errorTitle">错误正文:</span><span class="errorDesc">${error}</span></p>
+                             </div>`,
+                  });
+                });
             });
           });
-          this.webSocketInit(
-            `ws://10.81.3.154:6014/websocket/${this.$store.state.user.userId}`
-          );
-        });
       })
       .catch(() => {
         this.BASE.showMsg({
@@ -281,21 +329,24 @@ export default {
     },
 
     getAlarmHistory(alarmType, deviceType) {
-      return alarm_history({
-        pageNum: 1,
-        pageSize: 10,
-        alarmId: "",
-        alarmType,
-        deviceType,
-        stationid: "",
-        deviceid: "",
-        modelId: "",
-        components: "",
-        description: "",
-        begin: `${dayJs().format("YYYY-MM-DD")} 00:00:00`,
-        end: dayJs().format("YYYY-MM-DD HH:mm:ss"),
-        isclose: false,
-      });
+      return alarm_history(
+        {
+          pageNum: 1,
+          pageSize: 10,
+          alarmId: "",
+          alarmType,
+          deviceType,
+          stationid: "",
+          deviceid: "",
+          modelId: "",
+          components: "",
+          description: "",
+          begin: `${dayJs().format("YYYY-MM-DD")} 00:00:00`,
+          end: dayJs().format("YYYY-MM-DD HH:mm:ss"),
+          isclose: false,
+        },
+        5000
+      );
     },
 
     webSocketInit(serveIP) {
@@ -397,6 +448,17 @@ export default {
         }) || {}
       );
     },
+
+    getAlarmBoxWidth() {
+      const baseWIdth = 240;
+      let widthStep = 1;
+      for (let i = 1; i < this.$store.state.columnNumber; i++) {
+        if (this.alarmList?.[(i + 1) * this.$store.state.columnNumber]) {
+          widthStep++;
+        }
+      }
+      return widthStep * baseWIdth;
+    },
   },
 
   watch: {
@@ -416,161 +478,167 @@ export default {
 </script>
 <style lang="scss" scoped>
 .alarmBox {
-  width: 240px;
-  height: calc(100% - 85px);
+  height: calc(100% - 180px);
   padding: 0 12px 0 30px;
   position: absolute;
   right: 0;
   bottom: 0;
   z-index: 1000;
   display: flex;
-  flex-direction: column-reverse;
-  align-items: center;
-  font-size: 12px;
-  overflow-y: scroll;
+  justify-content: flex-end;
+  align-items: flex-end;
   pointer-events: none;
-  border-radius: 8px;
-  transition: 0.2s;
 
-  .alarmItem {
-    width: 100%;
-    box-sizing: border-box;
+  .columnItem {
+    width: 240px;
+    display: flex;
+    flex-direction: column-reverse;
+    align-items: center;
+    font-size: 12px;
+    overflow-y: scroll;
     border-radius: 8px;
-    border: 1px solid #ebeef5;
-    background: #1890ff;
-    margin-bottom: 4px;
-    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
-    color: #fff;
-    pointer-events: auto;
-    cursor: pointer;
-    .alarmTitle {
-      display: flex;
-      justify-content: flex-start;
-      align-content: center;
-      width: calc(100% - 16px);
-      overflow: hidden;
-      text-overflow: ellipsis;
-      white-space: nowrap;
-      padding: 0 8px;
-      margin-top: 8px;
-    }
-
-    .alarmContent {
-      width: calc(100% - 16px);
-      display: flex;
-      justify-content: flex-start;
-      align-items: flex-start;
-      flex-wrap: wrap;
-      margin-top: 4px;
-      padding: 0 8px;
+    transition: 0.2s;
 
-      .contentItem {
-        width: 100%;
+    .alarmItem {
+      width: 100%;
+      box-sizing: border-box;
+      border-radius: 8px;
+      border: 1px solid #ebeef5;
+      background: #1890ff;
+      margin-bottom: 4px;
+      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+      color: #fff;
+      pointer-events: auto;
+      cursor: pointer;
+      .alarmTitle {
         display: flex;
         justify-content: flex-start;
-        align-items: center;
-        margin-bottom: 2px;
-        word-wrap: break-word;
-
-        .alertDescCursor {
-          cursor: pointer;
-          transition: 0.2s;
+        align-content: center;
+        width: calc(100% - 16px);
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        padding: 0 8px;
+        margin-top: 8px;
+      }
 
-          &:hover {
-            color: var(--el-color-primary);
-            text-decoration: underline;
+      .alarmContent {
+        width: calc(100% - 16px);
+        display: flex;
+        justify-content: flex-start;
+        align-items: flex-start;
+        flex-wrap: wrap;
+        margin-top: 4px;
+        padding: 0 8px;
+
+        .contentItem {
+          width: 100%;
+          display: flex;
+          justify-content: flex-start;
+          align-items: flex-start;
+          margin-bottom: 2px;
+
+          .alertDescCursor {
+            width: 160px;
+            cursor: pointer;
             transition: 0.2s;
+
+            &:hover {
+              color: var(--el-color-primary);
+              text-decoration: underline;
+              transition: 0.2s;
+            }
           }
-        }
 
-        &:last-child {
-          margin-bottom: 0;
+          &:last-child {
+            margin-bottom: 0;
+          }
         }
       }
-    }
 
-    .btnBox {
-      display: flex;
-      width: 100%;
-      justify-content: center;
-      align-items: center;
-      margin-top: 4px;
-      border-top: 1px solid red;
-
-      .btnItem {
-        width: 50%;
+      .btnBox {
         display: flex;
+        width: 100%;
         justify-content: center;
         align-items: center;
-        padding: 4px 0;
-
-        .el-button {
-          padding: 0;
-          width: 45%;
-          height: 20px;
-          min-height: 20px;
-        }
+        margin-top: 4px;
+        border-top: 1px solid red;
+
+        .btnItem {
+          width: 50%;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          padding: 4px 0;
+
+          .el-button {
+            padding: 0;
+            width: 45%;
+            height: 20px;
+            min-height: 20px;
+          }
 
-        &.lv1 .el-button,
-        &.lv2 .el-button,
-        &.lv3 .el-button {
-          color: var(--el-color-info) !important;
-        }
+          &.lv1 .el-button,
+          &.lv2 .el-button,
+          &.lv3 .el-button {
+            color: var(--el-color-info) !important;
+          }
 
-        &.lv4 .el-button {
-          color: rgb(50, 65, 87) !important;
-        }
+          &.lv4 .el-button {
+            color: rgb(50, 65, 87) !important;
+          }
 
-        &.lv5 .el-button {
-          color: #242f42;
-        }
+          &.lv5 .el-button {
+            color: #242f42;
+          }
 
-        &:first-child {
-          border-right: 1px solid red;
+          &:first-child {
+            border-right: 1px solid red;
+          }
         }
       }
-    }
-    &.lv5 {
-      background: #fef0f0;
-      border: 1px solid #242f42;
-      color: #242f42;
-    }
+      &.lv5 {
+        background: #fef0f0;
+        border: 1px solid #242f42;
+        color: #242f42;
+      }
 
-    &.lv4 {
-      background: #f0f9eb;
-      border: 1px solid rgb(50, 65, 87);
-      color: rgb(50, 65, 87);
-    }
+      &.lv4 {
+        background: #f0f9eb;
+        border: 1px solid rgb(50, 65, 87);
+        color: rgb(50, 65, 87);
+      }
 
-    &.lv1,
-    &.lv2,
-    &.lv3 {
-      background: #fdf6ec;
-      border: 1px solid var(--el-color-info);
-      color: var(--el-color-info);
-    }
+      &.lv1,
+      &.lv2,
+      &.lv3 {
+        background: #fdf6ec;
+        border: 1px solid var(--el-color-info);
+        color: var(--el-color-info);
+      }
 
-    .lv1BdColor,
-    .lv2BdColor,
-    .lv3BdColor {
-      border-color: var(--el-color-info) !important;
-    }
+      .lv1BdColor,
+      .lv2BdColor,
+      .lv3BdColor {
+        border-color: var(--el-color-info) !important;
+      }
 
-    .lv4BdColor {
-      border-color: rgb(50, 65, 87) !important;
-    }
+      .lv4BdColor {
+        border-color: rgb(50, 65, 87) !important;
+      }
 
-    .lv5BdColor {
-      border-color: #242f42 !important;
-    }
+      .lv5BdColor {
+        border-color: #242f42 !important;
+      }
 
-    &.hidden {
-      height: 0;
-      padding: 0;
-      margin-bottom: 0;
-      border: 0;
-      transition: 0.2s;
-      overflow: hidden;
+      &.hidden {
+        height: 0;
+        padding: 0;
+        margin-bottom: 0;
+        border: 0;
+        transition: 0.2s;
+        overflow: hidden;
+      }
     }
   }
 
@@ -580,9 +648,34 @@ export default {
   }
 
   &.notEmpty:hover {
-    background: rgba(0, 0, 0, 0.12);
-    box-shadow: 0 0 12px rgba(0, 0, 0, 0.12);
+    // background: rgba(0, 0, 0, 0.12);
+    // box-shadow: 0 0 12px rgba(0, 0, 0, 0.12);
     transition: 0.2s;
   }
 }
 </style>
+<style lang="scss" >
+.currentRequestErrorNotification {
+  width: 100%;
+  display: flex;
+  flex-direction: column;
+  justify-content: flex-start;
+  align-items: flex-start;
+
+  p {
+    width: 100%;
+    display: flex;
+    justify-content: flex-start;
+    align-items: center;
+    flex-wrap: wrap;
+
+    .errorTitle {
+      width: 85px;
+    }
+
+    .errorDesc {
+      width: calc(100% - 85px);
+    }
+  }
+}
+</style>

+ 170 - 48
src/pages/baseData/fan_components/ycpoint.vue

@@ -1,26 +1,68 @@
 <template>
   <div class="devicemenu">
     <el-space wrap :size="10">
-      <el-button type="primary" @click="handleEdit(state.addFormData)" :disabled="desc.code == ''">新增</el-button>
-      <el-input v-model="state.SearchVal" placeholder="筛选" style="width: 180px" size="small" />
-      <el-select v-model="state.selectModel" class="mr10" style="width: 180px"  placeholder="全部" >
-     <el-option v-for="item in state.modelList" :key="item" :value="item" :label="item"></el-option>
-    </el-select>
-    <el-select v-model="state.selectPoint" class="mr10" style="width: 100px"  placeholder="全部" >
-      <el-option key="1" label="全部" value=""></el-option>
-      <el-option key="2" label="遥测" value="AI"></el-option>
-      <el-option key="3" label="遥调" value="MI"></el-option>
-      <el-option key="4" label="计算" value="CI"></el-option>
-    </el-select>
+      <el-button
+        type="primary"
+        @click="handleEdit(state.addFormData)"
+        :disabled="desc.code == ''"
+        >新增</el-button
+      >
+      <el-input
+        v-model="state.SearchVal"
+        placeholder="筛选"
+        style="width: 180px"
+        size="small"
+      />
+      <el-select
+        v-model="state.selectModel"
+        class="mr10"
+        style="width: 180px"
+        placeholder="全部"
+      >
+        <el-option
+          v-for="item in state.modelList"
+          :key="item"
+          :value="item"
+          :label="item"
+        ></el-option>
+      </el-select>
+      <el-select
+        v-model="state.selectPoint"
+        class="mr10"
+        style="width: 100px"
+        placeholder="全部"
+      >
+        <el-option key="1" label="全部" value=""></el-option>
+        <el-option key="2" label="遥测" value="AI"></el-option>
+        <el-option key="3" label="遥调" value="MI"></el-option>
+        <el-option key="4" label="计算" value="CI"></el-option>
+      </el-select>
       <el-button type="primary" @click="search">查询</el-button>
-      <el-upload class="upload-demo" :disabled="desc.code == ''" action="/sharding/device/input" :show-file-list="false"
-        :on-success="handleSuccess" :on-progress="handleProgress" :on-error="handleError">
+      <el-upload
+        class="upload-demo"
+        :disabled="desc.code == ''"
+        action="/sharding/device/input"
+        :show-file-list="false"
+        :on-success="handleSuccess"
+        :on-progress="handleProgress"
+        :on-error="handleError"
+      >
         <el-button :disabled="desc.code == ''" type="primary">导入</el-button>
       </el-upload>
-      <el-button type="primary" @click="export2Excel" :disabled="desc.code == ''">导出</el-button>
+      <el-button
+        type="primary"
+        @click="export2Excel"
+        :disabled="desc.code == ''"
+        >导出</el-button
+      >
     </el-space>
   </div>
-  <el-table :data="state.pointTableData" stripe style="width: 100%" height="65vh">
+  <el-table
+    :data="state.pointTableData"
+    stripe
+    style="width: 100%"
+    height="65vh"
+  >
     <el-table-column type="index" width="50" />
     <el-table-column prop="metriccode" label="测点编码"></el-table-column>
     <el-table-column label="名称">
@@ -30,9 +72,21 @@
             <el-button type="text" size="small">{{ scope.row.name }}</el-button>
           </template>
           <el-table :data="scope.row.deviceModelMetrics" max-height="400px">
-            <el-table-column property="devicemodel" label="机型" align="center"></el-table-column>
-            <el-table-column property="uniformcode" label="统一编码" align="center"></el-table-column>
-            <el-table-column property="multiplier" label="倍率" align="center"></el-table-column>
+            <el-table-column
+              property="devicemodel"
+              label="机型"
+              align="center"
+            ></el-table-column>
+            <el-table-column
+              property="uniformcode"
+              label="统一编码"
+              align="center"
+            ></el-table-column>
+            <el-table-column
+              property="multiplier"
+              label="倍率"
+              align="center"
+            ></el-table-column>
           </el-table>
         </el-popover>
       </template>
@@ -45,14 +99,32 @@
     <el-table-column prop="description" label="描述"></el-table-column>
     <el-table-column label="操作" width="180" align="center">
       <template #default="scope">
-        <el-button type="text" icon="el-icon-edit" @click="handleEdit(scope.row)">编辑</el-button>
-        <el-button type="text" icon="el-icon-delete" style="color: red" @click="handleDelete(scope.row)">删除</el-button>
+        <el-button
+          type="text"
+          icon="el-icon-edit"
+          @click="handleEdit(scope.row)"
+          >编辑</el-button
+        >
+        <el-button
+          type="text"
+          icon="el-icon-delete"
+          style="color: red"
+          @click="handleDelete(scope.row)"
+          >删除</el-button
+        >
       </template>
     </el-table-column>
   </el-table>
   <div class="pagination">
-    <el-pagination background layout="total, prev, pager, next" hide-on-single-page :current-page="query.page"
-      :page-size="query.limit" :total="pageTotal" @current-change="handlePageChange"></el-pagination>
+    <el-pagination
+      background
+      layout="total, prev, pager, next"
+      hide-on-single-page
+      :current-page="query.page"
+      :page-size="query.limit"
+      :total="pageTotal"
+      @current-change="handlePageChange"
+    ></el-pagination>
   </div>
   <!-- 传感点编辑弹出框 -->
   <el-dialog v-model="editVisible" width="40%">
@@ -87,21 +159,35 @@
         </el-col>
       </el-row>
       <el-form-item label="描述">
-        <el-input v-model="editFormData.description" :rows="3" type="textarea" clearable></el-input>
+        <el-input
+          v-model="editFormData.description"
+          :rows="3"
+          type="textarea"
+          clearable
+        ></el-input>
       </el-form-item>
       <el-row :gutter="24">
         <el-col :span="12">
           <el-form-item label="数据类型">
             <el-select v-model="editFormData.categorydata" placeholder="Select">
-              <el-option v-for="item in state.categorydataoptions" :key="item" :label="item" :value="item">
+              <el-option
+                v-for="item in state.categorydataoptions"
+                :key="item"
+                :label="item"
+                :value="item"
+              >
               </el-option>
             </el-select>
           </el-form-item>
         </el-col>
         <el-col :span="12">
           <el-form-item label="结构">
-            <el-cascader v-model="editFormData.structurecode" :options="cascaderdata"
-              :props="{ checkStrictly: true, emitPath: false }" clearable />
+            <el-cascader
+              v-model="editFormData.structurecode"
+              :options="cascaderdata"
+              :props="{ checkStrictly: true, emitPath: false }"
+              clearable
+            />
           </el-form-item>
         </el-col>
       </el-row>
@@ -119,13 +205,32 @@
       </el-row>
 
       <el-form-item label="适配机型" class="deviceModelClass">
-        <el-select v-model="state.deviceModelSel" style="margin-right: 20px" placeholder="新增机型" size="mini">
-          <el-option v-for="item in state.deviceModel" :key="item.code" :label="item.code" :value="item.code">
+        <el-select
+          v-model="state.deviceModelSel"
+          style="margin-right: 20px"
+          placeholder="新增机型"
+          size="mini"
+        >
+          <el-option
+            v-for="item in state.deviceModel"
+            :key="item.code"
+            :label="item.code"
+            :value="item.code"
+          >
           </el-option>
         </el-select>
-        <el-button v-show="state.deviceModelSel != ''" size="mini" type="primary" @click="deviceModelAdd()">新增机型
+        <el-button
+          v-show="state.deviceModelSel != ''"
+          size="mini"
+          type="primary"
+          @click="deviceModelAdd()"
+          >新增机型
         </el-button>
-        <el-table :data="editFormData.deviceModelMetrics" style="width: 100%;margin-top: 10px;" max-height="200px">
+        <el-table
+          :data="editFormData.deviceModelMetrics"
+          style="width: 100%; margin-top: 10px"
+          max-height="200px"
+        >
           <el-table-column prop="devicemodel" label="机型" />
           <el-table-column label="倍率">
             <template #default="scope">
@@ -151,12 +256,18 @@
 <script setup>
 import { ref, onMounted, inject, reactive, watch } from "vue";
 import { ElMessageBox, ElMessage } from "element-plus";
-import { point, metrics, delmetrics, device_list,getStationinfo } from "/@/api/api.js";
+import {
+  point,
+  metrics,
+  delmetrics,
+  device_list,
+  getWtModel,
+} from "/@/api/api.js";
 import { outExportExcel } from "/@/utils/exportExcel"; //引入文件
 onMounted(() => {
   getPoint(desc.value);
   getDeviceModel();
-  getequipmentmodel_list()
+  getequipmentmodel_list();
 });
 let editFormData = ref({});
 let editVisible = ref(false); //传感点
@@ -179,7 +290,7 @@ let state = reactive({
   selectPoint: "",
   selectModel: "",
   modelList: [],
-  categorydataoptions: ['AI', 'DI', 'CI'],
+  categorydataoptions: ["AI", "DI", "CI"],
   addFormData: {
     categorydata: "AI",
     categoryres1: null,
@@ -195,7 +306,7 @@ let state = reactive({
     id: null,
     metriccode: "",
     name: "",
-    structurecode: "101010205",
+    structurecode: "",
     unitname: null,
     unitnamecn: null,
     deviceModelMetrics: [],
@@ -207,12 +318,20 @@ const query = reactive({
 });
 let pageTotal = ref(0);
 const search = async () => {
-  getPoint(desc.value)
-}
+  getPoint(desc.value);
+};
 // getPoint
 const getPoint = async (node) => {
-  const res = await point(node.code, query.page, query.limit, state.selectPoint, state.SearchVal, 'windturbine', state.selectModel);
-  console.warn(res);
+  const res = await point(
+    node.code,
+    query.page,
+    query.limit,
+    state.selectPoint,
+    state.SearchVal,
+    "windturbine",
+    state.selectModel
+  );
+  console.log(123123, res);
   pageTotal.value = res.total;
   state.pointTableData = res.records?.sort((a, b) => {
     return a.id - b.id;
@@ -220,16 +339,11 @@ const getPoint = async (node) => {
 };
 // 机型
 const getequipmentmodel_list = async () => {
-  const { data } = await getStationinfo('');
-    let arr = []
-    data.forEach(e => {
-      arr.push(...e.modelList)
-    });
-    state.modelList = [...new Set(arr)]
+  const { data } = await getWtModel("");
+  state.modelList = data || [];
 };
 // 测点 编辑
 const handleEdit = (row) => {
-  console.warn(row);
   if (!row.deviceModelMetrics) {
     row.deviceModelMetrics = [];
   }
@@ -270,7 +384,7 @@ const handleDelete = (row) => {
       }
       getPoint(desc.value);
     })
-    .catch(() => { });
+    .catch(() => {});
 };
 
 //deviceModelAdd 新增机型
@@ -306,14 +420,22 @@ const handleSuccess = (response, file, fileList) => {
   ElMessage.success("导入成功!");
   getPoint(desc.value);
 };
-const handleProgress = (response, file, fileList) => { };
+const handleProgress = (response, file, fileList) => {};
 const handleError = (response, file, fileList) => {
   ElMessage.success("导入失败!");
 };
 
 // 批量导出
 const export2Excel = async () => {
-  const tableData = await point(desc.value.code, 1, 99999999, state.selectPoint, state.SearchVal, 'windturbine', state.selectModel);
+  const tableData = await point(
+    desc.value.code,
+    1,
+    99999999,
+    state.selectPoint,
+    state.SearchVal,
+    "windturbine",
+    state.selectModel
+  );
   ElMessage.success(`导出成功!`);
   const tableHeader = [
     "上级结构编码",

+ 551 - 0
src/pages/customWarning/index.vue

@@ -0,0 +1,551 @@
+<template>
+  <el-card>
+    <el-space wrap>
+      <div class="search-input">
+        <span class="lable">类型:</span>
+        <el-select
+          v-model="state.typeVal"
+          clearable
+          size="mini"
+          style="width: 100px"
+          placeholder="全部"
+          popper-class="select"
+          @change="
+            () => {
+              getStationList();
+              typechange();
+            }
+          "
+        >
+          <el-option
+            v-for="item in state.typeList"
+            :key="item.value"
+            :value="item.value"
+            :label="item.label"
+          >
+          </el-option>
+        </el-select>
+      </div>
+      <div class="search-input" v-if="!isStation">
+        <span class="lable">{{
+          state.isshowwindturbineName ? "场站:" : "升压站:"
+        }}</span>
+        <el-select
+          v-model="state.stationId"
+          clearable
+          size="mini"
+          placeholder="全部"
+          popper-class="select"
+          @change="getWindturbineList"
+        >
+          <el-option
+            v-for="item in stationList"
+            :key="item.id"
+            :value="item.id"
+            :label="item.name"
+          ></el-option>
+        </el-select>
+      </div>
+      <div class="search-input" v-if="state.isshowwindturbineName">
+        <span class="lable">机组:</span>
+        <el-select
+          v-model="state.windturbineId"
+          clearable
+          size="mini"
+          placeholder="全部"
+          popper-class="select"
+        >
+          <el-option
+            v-for="item in state.windturbineList"
+            :key="item.id"
+            :value="item.id"
+            :label="item.name"
+          >
+          </el-option>
+        </el-select>
+      </div>
+      <div class="search-input" v-if="state.isshowwindturbineName">
+        <span class="lable">型号:</span>
+        <el-select
+          v-model="state.modelId"
+          clearable
+          size="mini"
+          placeholder="全部"
+          popper-class="select"
+        >
+          <el-option
+            v-for="item in modelList"
+            :key="item.id"
+            :value="item.id"
+            :label="item.name"
+          >
+          </el-option>
+        </el-select>
+      </div>
+      <div class="search-input" v-if="state.isshowwindturbineName">
+        <span class="lable">部件:</span>
+        <el-select
+          v-model="state.components"
+          clearable
+          size="mini"
+          placeholder="全部"
+          popper-class="select"
+        >
+          <el-option
+            v-for="item in componentList"
+            :key="item.id"
+            :value="item.id"
+            :label="item.name"
+          >
+          </el-option>
+        </el-select>
+      </div>
+      <div class="search-input">
+        <span class="lable">描述:</span>
+        <el-input
+          v-model="state.description"
+          style="width: 100px"
+          size="mini"
+        ></el-input>
+      </div>
+      <div class="search-input">
+        <span class="lable">日期:</span>
+        <el-date-picker
+          v-model="state.dateTime"
+          size="mini"
+          type="datetimerange"
+          range-separator="-"
+          format="YYYY-MM-DD HH:mm:ss"
+          value-format="YYYY-MM-DD HH:mm:ss"
+          start-placeholder="开始"
+          end-placeholder="结束"
+        >
+        </el-date-picker>
+      </div>
+
+      <el-button type="primary" size="mini" @click="getAlarmHistoryt"
+        >查询</el-button
+      >
+      <el-button
+        size="mini"
+        type="primary"
+        @click="export2Excel"
+        :disabled="state.tableData?.length == 0 ? true : false"
+      >
+        导出</el-button
+      >
+    </el-space>
+  </el-card>
+  <div class="table-wrapper">
+    <el-table
+      :data="state.tableData"
+      height="calc(100% - 35px - 10px)"
+      style="width: 100%"
+      border
+      stripe
+    >
+      <template v-if="state.isshowwindturbineName">
+        <el-table-column
+          v-for="item in state.tableHeader"
+          :label="item.title"
+          :prop="item.code"
+          :key="item.code"
+          :width="item.width || ''"
+          show-overflow-tooltip
+          header-align="center"
+        >
+          <template #default="scope">
+            <p :style="item.style && item.style(item)">
+              <span v-if="item.code == 'rank'">
+                {{ tableFilter(scope.row.rank) }}
+              </span>
+              <span v-else-if="item.code == 'alarmtype'">
+                {{ tableFilter(scope.row.alarmtype) }}
+              </span>
+              <span v-else-if="item.code == 'ts'">
+                {{ formatTime(scope.row.ts) }}
+              </span>
+              <span v-else>
+                {{ scope.row[item.code] }}
+              </span>
+            </p>
+          </template>
+        </el-table-column>
+      </template>
+      <template v-else>
+        <el-table-column
+          v-for="item in state.tableHeader1"
+          :label="item.title"
+          :prop="item.code"
+          :key="item.code"
+          :width="item.width || ''"
+          show-overflow-tooltip
+          header-align="center"
+        >
+          <template #default="scope">
+            <p :style="item.style && item.style(item)">
+              <span v-if="item.code == 'rank'">
+                {{ tableFilter(scope.row.rank) }}
+              </span>
+              <span v-else-if="item.code == 'alarmtype'">
+                {{ tableFilter(scope.row.alarmtype) }}
+              </span>
+              <span v-else-if="item.code == 'ts'">
+                {{ formatTime(scope.row.ts) }}
+              </span>
+              <span v-else>
+                {{ scope.row[item.code] }}
+              </span>
+            </p>
+          </template>
+        </el-table-column>
+      </template>
+    </el-table>
+    <div class="pagination-wrapper">
+      <el-pagination
+        background
+        layout="total, prev, pager, next"
+        hide-on-single-page
+        :current-page="query.page"
+        :page-size="query.limit"
+        :total="query.pageTotal"
+        @current-change="handlePageChange"
+      ></el-pagination>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { watch, reactive, nextTick, computed, onMounted, ref } from "vue";
+import { useRouter, useRoute } from "vue-router";
+import dayjs from "dayjs";
+import {
+  alarm_history,
+  new_alarm_history,
+  fetchWindturbineList,
+  fetchModel,
+  fetchRelatePartAndAlarmType,
+  getWpList,
+} from "/@/api/api.js";
+import { ElMessage } from "element-plus";
+import { initWebSocket } from "/@/websocket/indextest";
+import { outExportExcel } from "/@/utils/exportExcel"; //引入文件
+import { useStore } from "vuex";
+
+const store = useStore();
+const isStation = computed(() => store.getters.isStation);
+const route = useRoute();
+
+onMounted(() => {
+  state.dateTime = [
+    dayjs().startOf("day").format("YYYY-MM-DD HH:mm:ss"),
+    dayjs().format("YYYY-MM-DD HH:mm:ss"),
+  ];
+  state.deviceId = route.params.deviceId || "";
+  state.alarmId = route.params.alarmId || "";
+  getStationList();
+  getequipmentmodel_list();
+  getfetchRelatePart();
+});
+// 机型
+const getequipmentmodel_list = async () => {
+  const { data } = await fetchModel();
+  state.modelListAll = data;
+};
+//所属部件
+const getfetchRelatePart = async () => {
+  const { data } = await fetchRelatePartAndAlarmType();
+  state.fetchListAll = data;
+};
+
+const getColumnStyle = (columnItem) => {
+  let style = "color:";
+  if (columnItem.endts) {
+    style += "var(--el-color-success)";
+  } else {
+    style += "var(--el-color-danger)";
+  }
+  return style;
+};
+
+const state = reactive({
+  typeList: [
+    {
+      label: "升压站",
+      value: "booststation",
+    },
+    // {
+    //   label: "自定义",
+    //   value: "custom",
+    // },
+    {
+      label: "风机",
+      value: "windturbine",
+    },
+    {
+      label: "光伏",
+      value: "inverter",
+    },
+  ],
+  c: "windturbine",
+  stationId: "",
+  alarmId: "",
+  typeVal: "windturbine",
+  windturbineList: [],
+  windturbineId: "",
+  modelListAll: {},
+  fetchListAll: {},
+  modelId: "", //型号
+  components: "", //部件
+  description: "", //描述
+  dateTime: [],
+  startDate: null,
+  endDate: null,
+  tableData: [],
+  isshowwindturbineName: true,
+  tableHeader: [
+    { title: "时间", code: "ts", width: "150" },
+    { title: "场站", code: "stationname", width: "150" },
+    { title: "机组", code: "devicename", width: "150" },
+    { title: "故障编码", code: "nemCode", width: "100" },
+    { title: "故障原因", code: "faultCause" },
+    { title: "故障解决方法", code: "resolvent" },
+    { title: "报警信息", code: "description", width: "180" },
+    { title: "级别", code: "rank", width: "80" },
+    { title: "类型", code: "alarmType", width: "80" },
+    {
+      title: "状态",
+      code: "isCloseName",
+      width: "80",
+      style: getColumnStyle,
+      width: 100,
+    },
+  ],
+  tableHeader1: [
+    { title: "时间", code: "ts", width: "150" },
+    { title: "升压站", code: "stationname", width: "150" },
+    { title: "报警信息", code: "description" },
+    { title: "级别", code: "rank", width: "80" },
+    { title: "类型", code: "alarmType", width: "80" },
+    {
+      title: "状态",
+      code: "isCloseName",
+      style: getColumnStyle,
+      width: 100,
+      width: "80",
+    },
+  ],
+});
+// 场站列表/升压站列表
+const stationList = ref([]);
+
+const getStationList = async () => {
+  const { data } = await getWpList(state.typeVal);
+  stationList.value = data;
+};
+
+watch(
+  () => stationList,
+  (val, old) => {
+    val?.value?.length &&
+      nextTick(async () => {
+        state.stationId = val.value[0]?.id;
+        await getWindturbineList();
+        await getAlarmHistoryt();
+      });
+  },
+  {
+    deep: true,
+    immediate: true,
+  }
+);
+watch(
+  () => route,
+  (val, old) => {
+    state.deviceId = route.params.deviceId || "";
+    state.alarmId = route.params.alarmId || "";
+    nextTick(async () => {
+      if (route.params.deviceId && route.params.alarmId) {
+        await getAlarmHistoryt();
+      }
+    });
+  },
+  {
+    deep: true,
+    immediate: true,
+  }
+);
+//型号列表
+const modelList = computed(() => {
+  if (state.typeVal == "windturbine") {
+    if (state.stationId == "") {
+      return [];
+    } else {
+      state.modelId = state.modelListAll[state.stationId]?.[0]?.id || "";
+      return state.modelListAll[state.stationId];
+    }
+  } else {
+    return [];
+  }
+});
+//部件列表
+const componentList = computed(() => {
+  if (state.typeVal == "windturbine") {
+    if (state.stationId == "") {
+      return [];
+    } else {
+      if (state.stationId.includes("FDC")) {
+        return state.fetchListAll?.fjbj;
+      } else {
+        return state.fetchListAll?.gfbj;
+      }
+    }
+  } else {
+    return [];
+  }
+});
+//get 风机
+const getWindturbineList = async () => {
+  state.windturbineList = [];
+  state.windturbineId = "";
+  const { data } = await fetchWindturbineList(state.stationId);
+  state.windturbineList = data;
+};
+const query = reactive({
+  page: 1,
+  limit: 17,
+  pageTotal: null,
+});
+
+// 获取历史记录表
+const getAlarmHistoryt = async () => {
+  if (route.params.deviceId && route.params.alarmId) {
+    state.stationId = "";
+  }
+  let params = {
+    pageNum: query.page,
+    pageSize: query.limit,
+    alarmId: state.alarmId,
+    alarmType: "custom",
+    deviceType: state.typeVal,
+    stationid: state.stationId,
+    deviceid:
+      state.deviceId ||
+      (state.typeVal == "booststation" ? "" : state.windturbineId),
+    modelId: state.typeVal == "booststation" ? "" : state.modelId,
+    components: state.components,
+    description: state.description,
+    begin: state.dateTime[0],
+    end: state.dateTime[1],
+  };
+  const { data } = await alarm_history(params);
+  query.pageTotal = data?.total;
+  data?.ls?.forEach((ele) => {
+    ele.isCloseName = ele.endts ? "已解除" : "未解除";
+  });
+  state.tableData = data?.ls;
+};
+//报警类型变化
+const typechange = () => {
+  state.isshowwindturbineName = state.typeVal == "booststation" ? false : true;
+};
+
+// 批量导出
+const export2Excel = async () => {
+  let params = {
+    pageNum: query.page,
+    pageSize: query.pageTotal,
+    alarmType: state.typeVal,
+    stationid: state.stationId,
+    deviceid: state.typeVal == "booststation" ? "" : state.windturbineId,
+    modelId: state.modelId,
+    components: state.components,
+    description: state.description,
+    begin: state.dateTime[0],
+    end: state.dateTime[1],
+  };
+
+  if (state.dateTime[1] - state.dateTime[0] > 6 * 24 * 60 * 60 * 1000) {
+    this.$message({
+      message: "导出时间范围不能大于7天",
+      type: "warning",
+    });
+  } else {
+    let tableHeader = [];
+    let tableKey = [];
+    const { data } = await alarm_history(params);
+    if (state.isshowwindturbineName) {
+      tableHeader = state.tableHeader.map((item) => item.title);
+      tableKey = state.tableHeader.map((item) => item.code);
+    } else {
+      tableHeader = state.tableHeader1.map((item) => item.title);
+      tableKey = state.tableHeader1.map((item) => item.code);
+    }
+    const stationName = stationList.value.find((ele) => {
+      return ele.id === state.stationId;
+    }).name;
+    const fileName = `${stationName} ${state.dateTime[0]} ~ ${state.dateTime[1]} 数据表`;
+
+    outExportExcel(
+      tableHeader,
+      tableKey,
+      data.ls.map((item) => {
+        return {
+          ...item,
+          ts: formatTime(item.ts),
+          rank: tableFilter(item.rank),
+          alarmtype: tableFilter(item.alarmtype),
+        };
+      }),
+      fileName
+    );
+    ElMessage.success(`导出成功!`);
+  }
+};
+// 分页导航
+const handlePageChange = (val) => {
+  query.page = val;
+  getAlarmHistoryt();
+};
+// 时间格式化
+const formatTime = (val) => {
+  return dayjs(val).format("YYYY-MM-DD HH:mm:ss");
+};
+// 格式化
+const obj = {
+  1: "低级",
+  2: "中低级",
+  3: "中级",
+  4: "中高级",
+  5: "高级",
+  booststation: "升压站",
+  custom: "自定义",
+  windturbine: "风机",
+};
+const messageTypeObj = {
+  1: "触发",
+  3: "解除",
+};
+const tableFilter = (val) => {
+  return obj[val];
+};
+const messageTypeFilter = (val) => {
+  return messageTypeObj[val];
+};
+</script>
+
+<style scoped lang="scss">
+.table-wrapper {
+  height: calc(100% - 70px - 50px);
+  background-color: #fff;
+  margin-top: 10px;
+  padding: 20px;
+  .pagination-wrapper :deep {
+    text-align: right;
+    margin-top: 10px;
+    .el-icon {
+      width: unset;
+    }
+  }
+}
+</style>

+ 9 - 8
src/pages/stopQuery/index.vue

@@ -50,7 +50,6 @@
           <span>停机类型:</span>
           <el-select
             v-model="type"
-            clearable
             size="mini"
             style="width: 150px"
             placeholder="全部"
@@ -145,7 +144,7 @@ export default {
       wtId: "",
       wtArray: [],
       dateRange: [],
-      type: "",
+      type: "gz",
       description: "",
       pageNum: 1,
       pageSize: 15,
@@ -178,15 +177,15 @@ export default {
         },
         {
           label: "处理方式",
-          prop: " handleWay",
+          prop: "handleWay",
         },
         {
           label: "故障现象",
-          prop: " aultView",
+          prop: "faultView",
         },
         {
           label: "故障类型",
-          prop: " typeName",
+          prop: "typeName",
         },
       ],
     };
@@ -203,7 +202,7 @@ export default {
   methods: {
     async getWpList() {
       const { data } = await getWpList("windturbine");
-        this.wpId = data?.[0]?.id || "";
+      this.wpId = data?.[0]?.id || "";
       this.wpArray = data || [];
       this.getWtList();
     },
@@ -228,8 +227,10 @@ export default {
 
       data?.records?.forEach((ele) => {
         ele.stopTimeName = dayJS(ele.stopTime).format("YYYY-MM-DD HH:mm:ss");
-        ele.startTimeName = dayJS(ele.startTime).format("YYYY-MM-DD HH:mm:ss");
-        ele.typeName = ele.type === "gz" ? "故障" : "检修";
+        ele.startTimeName = ele.startTime
+          ? dayJS(ele.startTime).format("YYYY-MM-DD HH:mm:ss")
+          : "";
+        ele.typeName = ele.stopTypeId === "gz" ? "故障" : "检修";
       });
 
       this.tableData = data?.records || [];

+ 23 - 2
src/pages/systemManage/systemManage.vue

@@ -43,7 +43,19 @@
       </el-tab-pane>
     </el-tabs>
     <div class="alarmNumBox">
-      <span>右下报警弹窗数量上限:</span>
+      <span>报警气泡列数上限:</span>
+      <el-input-number
+        style="margin: 0 10px"
+        size="small"
+        v-model="columnNumber"
+        :step="1"
+        :min="columnNumberMin"
+        :max="columnNumberMax"
+      />
+      <span>列</span>
+    </div>
+    <div class="alarmNumBox">
+      <span>报警气泡每列至多显示数量:</span>
       <el-input-number
         style="margin: 0 10px"
         size="small"
@@ -66,14 +78,18 @@ export default {
     return {
       activeTab: "",
       alarmConfigArray: [],
+      columnNumber: 1,
+      columnNumberMin: 1,
+      columnNumberMax: 5,
       alarmShowNumber: 0,
       alarmMinNumber: 0,
-      alarmMaxNumber: 100,
+      alarmMaxNumber: 7,
     };
   },
 
   created() {
     this.alarmShowNumber = this.$store.state.alarmShowNumber;
+    this.columnNumber = this.$store.state.columnNumber;
     this.getConfigArray();
   },
 
@@ -128,7 +144,9 @@ export default {
         });
         this.$store.commit("changeAlarmResetFlg");
         this.$store.commit("changeAlarmShowNumber", this.alarmShowNumber);
+        this.$store.commit("changeColumnNumber", this.columnNumber);
         localStorage.setItem("alarmShowNumber", this.alarmShowNumber);
+        localStorage.setItem("columnNumber", this.columnNumber);
         this.getConfigArray();
       });
     },
@@ -138,6 +156,9 @@ export default {
     "$store.state.alarmShowNumber"(value) {
       this.alarmShowNumber = value;
     },
+    "$store.state.columnNumber"(value) {
+      this.columnNumber = value;
+    },
   },
 };
 </script>

+ 13 - 0
src/router/index.js

@@ -77,6 +77,19 @@ const routes = [
               ),
           },
           {
+            path: "/safe/customWarning/:deviceId?/:alarmId?",
+            name: "customWarning",
+            isshow: "super_admin,common",
+            meta: {
+              title: "预警查询",
+            },
+            component: () =>
+              import(
+                /* webpackChunkName: "form" */
+                "../pages/customWarning/index.vue"
+              ),
+          },
+          {
             path: "/safe/stopQuery",
             name: "stopQuery",
             isshow: "super_admin,common",

+ 7 - 0
src/store/index.js

@@ -23,6 +23,7 @@ export default createStore({
         alarmResetFlg: 1,
         replaceRouteName: ["safehistorywaring"],
         alarmShowNumber: (localStorage.getItem("alarmShowNumber") ? parseInt(localStorage.getItem("alarmShowNumber")) : 6),
+        columnNumber: (localStorage.getItem("columnNumber") ? parseInt(localStorage.getItem("columnNumber")) : 1)
     },
     mutations: {
         delTagsItem(state, data) {
@@ -137,6 +138,9 @@ export default createStore({
         changeAlarmShowNumber(state, data) {
             state.alarmShowNumber = data;
         },
+        changeColumnNumber(state, data) {
+            state.columnNumber = data;
+        },
     },
     actions: {
         actionsWarning(context, newData) {
@@ -168,6 +172,9 @@ export default createStore({
         changeAlarmShowNumber(context, newData) {
             context.commit("changeAlarmShowNumber", newData);
         },
+        changeColumnNumber(context, newData) {
+            context.commit("changeColumnNumber", newData);
+        },
     },
     modules: { user, },
     getters: getter,

+ 1 - 1
vite.config.js

@@ -31,7 +31,7 @@ export default defineConfig({
             "^/sharding": {
                 // target: 'http://wanghs.nat300.top',
                 target: "http://10.81.3.154:6015",
-                // target: "http://192.168.1.102:6015",
+                // target: "http://192.168.1.101:6015",
                 changeOrigin: true, //开启代理
                 rewrite: (path) => path.replace(/^\/sharding/, ""),
             },