Kaynağa Gözat

特征值+合并

rui.jiang 2 ay önce
ebeveyn
işleme
2a1f241fb9

+ 7 - 0
README.md

@@ -39,3 +39,10 @@
 个人工作台(自由托动、定制化)分析辅助工具
 各种变量对比分析、拖动轮播
 分析事件中的 loading 状态数据没请求到的
+
+1. 点击下载 pdf 按钮 请求后端生成图表图片后上传到 minio 上,(分批次请求上传接口)
+   nodejs 生成图表会占用服务器内存和 cpu ,使用分片处理避免服务器压力过大导致崩溃(不完全保证能解决这个问题)
+2. 给出上传完毕信号后,调用下载 pdf 的方法,生成报告
+   问题:
+   1. 目前手动通过模版生成报告,nodejs 开发时间问题
+   2. 自动生成报告算法计算相应的风场风机后提供计算值和文字,这样算法直接获取 minio 图片直接生成文字更便利

+ 1 - 26
src/App.vue

@@ -20,15 +20,6 @@ export default {
 };
 </script>
 <style lang="scss">
-// ::v-deep body .el-menu--horizontal .el-menu .el-menu-item {
-//   color: #000 !important;
-//   background-color: #fff !important;
-// }
-// ::v-deep body .el-menu--horizontal .el-menu .el-submenu__title {
-//   color: #000 !important;
-//   background-color: #fff !important;
-// }
-
 body {
   width: 100%;
   height: 100%;
@@ -36,12 +27,7 @@ body {
 ::v-deep .vue-recycle-scroller__item-wrapper::-webkit-scrollbar {
   display: block !important;
 }
-// ::-webkit-scrollbar {
-//   display: none;
-// }
-// ::-webkit-scrollbar {
-//   display: none;
-// }
+
 .fade-enter-active,
 .fade-leave-active {
   transition: opacity 0.5s ease;
@@ -56,14 +42,3 @@ body {
   display: none;
 }
 </style>
-<style>
-/* ::v-deep .el-color-dropdown .el-color-dropdown__main-wrapper {
-  display: none !important;
-}
-.el-color-svpanel {
-  display: none !important;
-}
-.el-color-hue-slider {
-  display: none !important;
-} */
-</style>

+ 33 - 1
src/api/performance.js

@@ -1,12 +1,36 @@
 /*
  * @Author: your name
  * @Date: 2024-06-03 09:29:50
- * @LastEditTime: 2025-02-12 17:32:36
+ * @LastEditTime: 2025-04-02 14:39:07
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/api/performance。.js
  */
 import request from "@/utils/request";
+//编辑自动分析
+export function configEdit(data) {
+  return request({
+    url: "/energy-manage-service/autoAnalysis/configEdit",
+    method: "post",
+    data,
+  });
+}
+//创建自动分析
+export function configSave(data) {
+  return request({
+    url: "/energy-manage-service/autoAnalysis/configSave",
+    method: "post",
+    data,
+  });
+}
+//自动分析关停分析
+export function onOff(data) {
+  return request({
+    url: "/energy-manage-service/autoAnalysis/onOff",
+    method: "post",
+    data,
+  });
+}
 //插队接口
 export function editPriority(data) {
   return request({
@@ -305,3 +329,11 @@ export function analysisResultList(data) {
     params: data,
   });
 }
+//查询自动分析列表
+export function autoAnalysisConfigList(data) {
+  return request({
+    url: "/energy-manage-service/autoAnalysis/configList",
+    method: "get",
+    params: data,
+  });
+}

+ 0 - 1
src/directives/permission.js

@@ -8,7 +8,6 @@ export default {
 
     if (value && value instanceof Array && value.length > 0) {
       const permissionFlag = value;
-      console.log(permissions, "permissions");
       const hasPermissions = permissions.some((permission) => {
         return (
           all_permission === permission || permissionFlag.includes(permission)

+ 0 - 2
src/main.js

@@ -82,7 +82,6 @@ Vue.prototype.$formatDateTWO = function (timestamp) {
   return `${year}-${month}-${day} ${hours}:${minutes}`;
 };
 
-
 // man.js
 
 // 注册 convertDMSToDecimal 方法
@@ -102,7 +101,6 @@ Vue.prototype.$convertDMSToDecimal = function (dms) {
   return null; // 如果格式不正确,返回null
 };
 
-
 // 路由导航守卫
 router.beforeEach((to, from, next) => {
   if (from.path === "/home/performance/customAnalysis") {

+ 3 - 5
src/views/home/Index.vue

@@ -52,7 +52,7 @@ export default {
     return {
       // history: ["11", "22", "33"],
       loading: false,
-      isShowHd: false,
+      isShowHd: true,
     };
   },
   mounted() {},
@@ -91,8 +91,8 @@ export default {
     display: flex;
     justify-content: space-between;
     align-items: center;
-    background: url("../../assets/headerBorder.png") center center;
-    background-size: contain;
+    background: url("../../assets/headerBorder.png");
+    background-size: 6%, 100%;
     background-repeat: repeat-x; /* 水平方向重复 */
   }
   .menuBox {
@@ -101,8 +101,6 @@ export default {
     align-items: center;
     justify-content: center;
     display: flex;
-    // background: url("../../assets/headerBorder.png") no-repeat center center;
-    // background-size: 100% 100%; /* 强行拉伸,可能会导致图片变形 */
   }
   .headerRight {
   }

+ 79 - 179
src/views/home/components/MenuHD.vue

@@ -1,5 +1,4 @@
 <template>
-  <!-- <el-aside :width="!isCollapse ? '250px' : '100px'" class="asideBox"> -->
   <el-menu
     collapse-transition
     ref="menu"
@@ -12,24 +11,39 @@
     :default-active="defaultActive"
     :default-openeds="openMenus"
   >
-    <!-- background-color="#eff1f300" text-color="#fff" -->
     <template v-for="(item, indexMenu) in routerList">
       <!-- 判断是否是中间位置 -->
-      <el-menu-item v-if="indexMenu === Math.floor(routerList.length / 2) + 1">
-        <span class="headerText">风电机组健康度诊断平台</span>
+      <el-menu-item
+        class="hdMenuTitle"
+        v-if="indexMenu === Math.floor(routerList.length / 2) + 1"
+      >
+        <div class="titles">
+          <span class="headerText">风电机组健康度诊断平台</span>
+        </div>
       </el-menu-item>
       <el-submenu
+        class="menuParentItem"
+        :style="{
+          transform:
+            indexMenu < Math.floor(routerList.length / 2) + 1
+              ? 'scaleX(-1)'
+              : 'scaleX(1)',
+        }"
         v-if="
           item.children && item.children.length && item.meta?.hidden === false
         "
         :index="item.path"
       >
         <template slot="title">
-          <!-- <i v-if="isElPrefix(item.iconName)" class="el-icon-menu"></i>
-          <i v-else class="svnIcon">
-            <svg-icon :icon-class="item.iconName" />
-          </i> -->
-          <span>{{ item.name }}</span>
+          <span
+            :style="{
+              transform:
+                indexMenu < Math.floor(routerList.length / 2) + 1
+                  ? 'scaleX(-1)'
+                  : 'scaleX(1)',
+            }"
+            >{{ item.name }}</span
+          >
         </template>
         <el-menu-item
           v-for="child in item.children"
@@ -38,56 +52,35 @@
           :index="`${child.path}?id=${child.id}`"
           @click="handleChangeMenuUrl(child, `${child.path}?id=${child.id}`)"
         >
-          <!-- <i v-if="isElPrefix(child.iconName)" class="el-icon-menu"></i>
-          <i v-else class="svnIcon">
-            <svg-icon :icon-class="child.iconName" />
-          </i> -->
           <span>{{ child.name }}</span>
         </el-menu-item>
       </el-submenu>
       <el-menu-item
+        class="menuParentItem"
+        :style="{
+          transform:
+            indexMenu < Math.floor(routerList.length / 2) + 1
+              ? 'scaleX(-1)'
+              : 'scaleX(1)',
+          color: '#fff',
+        }"
         v-else-if="item.meta?.hidden === false"
         :key="item.id"
         :index="`${item.path}?id=${item.id}`"
         @click="handleChangeMenuUrl(item, `${item.path}?id=${item.id}`)"
       >
-        <!-- <i v-if="isElPrefix(item.iconName)" class="el-icon-menu"></i>
-        <i v-else-if="item.iconName" class="svnIcon">
-          <svg-icon :icon-class="item.iconName" />
-        </i>
-        <i class="svnIcon" v-else-if="item.path === '/home/laserRangeFinder'">
-          <svg-icon
-            style="width: 22px; height: 22px"
-            icon-class="laserRangeFinder"
-          />
-        </i> -->
-        <span>{{ item.name }}</span>
+        <span
+          :style="{
+            transform:
+              indexMenu < Math.floor(routerList.length / 2) + 1
+                ? 'scaleX(-1)'
+                : 'scaleX(1)',
+          }"
+          >{{ item.name }}</span
+        >
       </el-menu-item>
     </template>
   </el-menu>
-
-  <!-- <div class="foldBox flexCenter">
-      <span
-        v-show="isCollapse"
-        class="el-icon-s-unfold icon"
-        @click.stop="isCollapse = false"
-        >展开</span
-      >
-      <el-switch
-        v-show="!isCollapse"
-        :value="isExpanded"
-        @change="toggleAllMenus"
-      >
-        :inactive-text="isExpanded ? '收起全部菜单' : '展开全部菜单'"
-      </el-switch>
-      <span
-        v-show="!isCollapse"
-        class="el-icon-s-fold icon"
-        @click.stop="isCollapse = true"
-        >收起</span
-      >
-    </div> -->
-  <!-- </el-aside> -->
 </template>
 
 <script>
@@ -116,17 +109,6 @@ export default {
           meta: {
             hidden: false,
           },
-          // children: [
-          //   {
-          //     id: 11,
-          //     iconName: "",
-          //     meta: {
-          //       hidden: false,
-          //     },
-          //     path: "electronic-map",
-          //     name: "电子地图",
-          //   },
-          // ],
         },
       ],
     };
@@ -258,25 +240,59 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-.el-menu-vertical-demo {
-  // overflow-x: scroll;
+::v-deep.menuParentItem .el-submenu__title,
+::v-deep.menuParentItem .el-submenu__title:hover {
+  background: #eff1f300 !important;
+  color: #fff !important;
+}
+:v-deep.menuParentItem .el-submenu__title:hover {
+  color: #eee !important;
+}
+::v-deep .menuParentItem,
+::v-deep .menuParentItem:hover {
+  background-image: url("../../../assets/head-tab.png") !important;
+  background-repeat: no-repeat !important;
+  background-position: center !important;
+  background-size: 100%, 100% !important;
+  height: 60px !important;
+  width: 140px !important;
+  display: flex !important;
+  align-items: center !important;
+  justify-content: center !important;
+  background-color: #eff1f300 !important;
 }
 ::v-deep.el-menu {
   background-color: #eff1f300 !important;
 }
+::v-deep.hdMenuTitle,
+::v-deep.hdMenuTitle:hover {
+  background-color: #1b3b7f !important;
+  padding: 0px !important;
+}
+
+::v-deep.titles,
+::v-deep.titles:hover {
+  width: 100% !important;
+  background-image: url("../../../assets/headerBorder.png") !important;
+  background-size: 35%, 100% !important;
+  background-repeat: repeat-x !important;
+  padding: 0px !important;
+}
 ::v-deep.headerText {
   pointer-events: none;
   background-image: url("../../../assets/headerText.png") !important;
   background-size: 100% 100%;
   color: #fff;
-  font-size: 16px;
+  font-size: 18px;
   font-weight: 600;
   text-align: center;
   display: block;
   width: 100%;
-  height: 85%;
+  height: 45px;
   padding: 0px 30px;
-  // width: 200px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
 }
 
 ::v-deep.mt-3 {
@@ -288,122 +304,6 @@ export default {
   font-size: 0px;
 }
 
-// .asideBox {
-//   height: 100vh;
-//   overflow-y: scroll;
-//   position: relative;
-//   padding-bottom: 40px;
-//   padding-top: 16px;
-//   box-sizing: border-box;
-//   display: flex;
-//   align-items: flex-start;
-//   justify-content: flex-start;
-//   flex-direction: column;
-//   border-right: 1px solid #d8d8d8;
-//   position: relative;
-
-//   .homeBox {
-//     width: 100%;
-//     padding: 0 20px;
-//     display: flex;
-//     flex-direction: column;
-//     align-items: flex-start;
-//     justify-content: flex-start;
-//     box-sizing: border-box;
-
-//     .logoItem {
-//       display: flex;
-//       width: 100%;
-//       cursor: pointer;
-//       box-sizing: border-box;
-
-//       span {
-//         line-height: 50px;
-//         margin: 0 auto;
-//       }
-
-//       .logoImg {
-//         img {
-//           height: 100%;
-//           width: inherit;
-//         }
-
-//         width: 50px;
-//         height: 50px;
-//       }
-//     }
-
-//     .search {
-//       display: flex;
-//       width: 100%;
-//       align-items: center;
-//       justify-content: center;
-
-//       .el-icon-search {
-//         margin-top: 28px;
-//       }
-
-//       .el-input {
-//         width: inherit;
-//       }
-//     }
-
-//     .frame {
-//       display: flex;
-//       justify-content: space-between;
-//       align-items: center;
-//       color: #666;
-//       width: 100%;
-//       margin-top: 20px;
-//       margin-bottom: 10px;
-//       cursor: pointer;
-
-//       .homeIndex {
-//         display: flex;
-//         justify-content: center;
-//         align-items: center;
-//         font-size: 18px;
-
-//         .home_active {
-//           margin-right: 2px;
-//         }
-
-//         p {
-//           color: #666;
-//           font-size: 18px;
-//         }
-//       }
-
-//       &:hover {
-//         p {
-//           color: #19436d;
-//         }
-
-//         transition: width 0.5s ease, transform 0.5s ease;
-//         transform-origin: left;
-//       }
-
-//       .left {
-//         left: 50%;
-//         transform: scaleX(0);
-//       }
-
-//       .right {
-//         left: 0;
-//         transform: scaleX(0);
-//       }
-//     }
-//   }
-
-//   .el-menu {
-//     margin-bottom: 10px;
-//     border: none;
-//     overflow-y: auto;
-//     width: 100% !important;
-//     height: 100%;
-//   }
-// }
-
 .flexCenter {
   display: flex;
   align-items: center !important;

+ 20 - 16
src/views/performance/assetssMag.vue

@@ -173,24 +173,24 @@
         >
         </el-table-column>
 
-        <!-- <el-table-column
-          prop="errState"
+        <el-table-column
+          prop="onOffCall"
           align="center"
-          label="异常状态"
-          min-width="120"
+          label="是否开启自动分析"
+          min-width="140"
         >
           <template slot-scope="scope">
             <span>
               {{
-                scope.row.errState == 0 && scope.row.analysisState !== -1
-                  ? "未异常"
-                  : scope.row.errState === 1
-                  ? "异常"
+                scope.row.onOffCall == 0
+                  ? "不开启"
+                  : scope.row.onOffCall === 1
+                  ? "开启"
                   : "/"
               }}</span
             >
           </template>
-        </el-table-column> -->
+        </el-table-column>
         <el-table-column
           prop="roleName"
           align="center"
@@ -367,7 +367,7 @@
       :rowInfo="rowInfo"
       @confirm="handleConfirm"
       :errorInfo="errorInfo"
-      @getTableList="getTableList"
+      @getTableList="fetchData"
     >
       <div slot="tableEl">
         <el-empty description="暂无数据"></el-empty>
@@ -539,9 +539,13 @@ export default {
   methods: {
     //自动分析列表页面跳转
     handleAutoAsstessList() {
-      this.$router.push({
-        path: "/home/performance/autoAssetss",
-      });
+      window.open(
+        this.$router.resolve({ path: "/home/performance/autoAssetss" }).href,
+        "_blank"
+      );
+      // this.$router.push({
+      //   path: "/home/performance/autoAssetss",
+      // });
     },
     // 创建分析时请求
     async addRuleFormSubmit() {
@@ -557,7 +561,7 @@ export default {
               this.addDialogVisible = false;
               this.loading = false;
               this.isPolling = false;
-              await this.getTableList();
+              await this.fetchData();
               this.$router.push({
                 path: "/home/performance/editAssets",
                 query: {
@@ -616,7 +620,7 @@ export default {
         form.append("onOffCall", row.onOffCall === 0 ? 1 : 0);
         const res = await onOffAutoAnalysis(form);
         if (res.code === 200) {
-          this.getTableList();
+          this.fetchData();
           this.$message({
             type: "success",
             message: `${row.onOffCall === 0 ? "开启" : "关闭"}成功`,
@@ -707,7 +711,7 @@ export default {
     // 页码变化时才触发查询
     handleCurrentChange(val) {
       this.formInline.pageNum = val;
-      this.getTableList();
+      this.fetchData();
     },
     // 修改 getTableList 方法,避免重复请求
     async getTableList() {

+ 244 - 439
src/views/performance/autoAssetss.vue

@@ -1,11 +1,3 @@
-<!--
- * @Author: your name
- * @Date: 2025-03-27 10:01:43
- * @LastEditTime: 2025-03-27 10:30:09
- * @LastEditors: bogon
- * @Description: In User Settings Edit
- * @FilePath: /performance-test/src/views/performance/autoAssetss.vue
--->
 <template>
   <div class="global-variable">
     <div class="condition">
@@ -14,15 +6,7 @@
         ref="ruleForm"
         :model="formInline"
         class="demo-form-inline"
-        :rules="rules"
       >
-        <el-form-item label="分析主题:" prop="analysisName">
-          <el-input
-            size="small"
-            v-model="formInline.analysisName"
-            placeholder="请输入分析主题"
-          ></el-input>
-        </el-form-item>
         <el-form-item label="风场名称:" prop="fieldName">
           <el-input
             size="small"
@@ -30,10 +14,10 @@
             placeholder="请输入风场名称"
           ></el-input>
         </el-form-item>
-        <el-form-item label="分析状态:" prop="analysisState">
+        <el-form-item label="分析状态:" prop="startupState">
           <el-select
             size="small"
-            v-model="formInline.analysisState"
+            v-model="formInline.startupState"
             placeholder="请选择分析状态"
           >
             <el-option
@@ -50,10 +34,14 @@
             >查询</el-button
           >
           <el-button @click="reset('ruleForm')" size="small">重置</el-button>
-        </el-form-item>
-
-        <el-form-item class="right-align">
-          <el-button @click="examine" size="small">查看导入数据</el-button>
+          <el-button
+            @click="
+              addDialogVisible = true;
+              title = '创建';
+            "
+            size="small"
+            >创建自动分析配置</el-button
+          >
         </el-form-item>
       </el-form>
     </div>
@@ -66,202 +54,46 @@
       >
         <el-table-column
           align="center"
-          label="分析主题"
-          prop="analysisName"
-          min-width="200"
-          fixed
-        >
-          <template slot-scope="scope">
-            <el-tooltip
-              class="item"
-              effect="dark"
-              :content="scope.row.sketch || '暂无分析简述'"
-              placement="top"
-            >
-              <span>{{ scope.row.analysisName }}</span>
-            </el-tooltip>
-          </template>
-        </el-table-column>
-        <el-table-column
-          align="center"
           prop="fieldName"
           label="风场名称"
           min-width="200"
         >
         </el-table-column>
-
         <el-table-column
-          prop="loginName"
           align="center"
-          label="分析状态"
-          min-width="150"
-        >
-          <template slot-scope="scope">
-            <span v-if="scope.row.analysisState == -1">未关联</span>
-            <span
-              v-else-if="
-                scope.row.analysisState == 20 && scope.row.errState == 0
-              "
-              style="color: #f90"
-              >分析中</span
-            >
-            <span
-              v-else-if="
-                scope.row.errState == 1 && scope.row.analysisState == 30
-              "
-              style="color: #f00"
-              >分析异常</span
-            >
-
-            <span
-              v-else-if="scope.row.analysisState == 30"
-              style="color: #4caf50"
-              >分析完成</span
-            >
-            <span
-              v-else-if="scope.row.analysisState == 10"
-              style="color: #4caf50"
-              >排队中</span
-            >
-            <span v-else>/</span>
-          </template>
-        </el-table-column>
-        <el-table-column
-          prop="loginName"
-          align="center"
-          label="进度"
-          min-width="150"
-        >
-          <template slot-scope="scope">
-            <el-progress
-              v-if="scope.row.analysisState == 20"
-              :text-inside="true"
-              :stroke-width="20"
-              :percentage="scope.row.analysisProgress"
-              :class="{
-                'indeterminate-progress': scope.row.analysisProgress < 100,
-                'animated-progress': true,
-              }"
-            ></el-progress>
-            <span v-else>/</span>
-          </template>
-        </el-table-column>
-        <el-table-column
-          align="center"
-          label="优先执行"
-          prop="orderNum"
+          label="启停状态"
+          prop="startupState"
           min-width="200"
         >
           <template slot-scope="scope">
-            <span> {{ scope.row.orderNum }}</span>
+            <span> {{ scope.row.startupState == "1" ? "启动" : "关停" }}</span>
           </template>
         </el-table-column>
-
         <el-table-column
           align="center"
-          label="数据类型名称"
-          prop="dataTypeName"
+          label="间隔天数"
+          prop="intervalDays"
           min-width="200"
         >
         </el-table-column>
         <el-table-column
-          prop="roleName"
+          prop="startTime"
           align="center"
-          label="异常信息"
-          min-width="120"
-        >
-          <template slot-scope="scope">
-            <el-button
-              v-if="scope.row.errState == 1"
-              @click="abnormalDialog(scope.row, '异常详情')"
-              type="text"
-              size="small"
-              >异常详情</el-button
-            >
-            <span v-else>/</span>
-          </template>
-        </el-table-column>
-        <el-table-column
-          prop="roleName"
-          align="center"
-          label="分析记录"
-          min-width="120"
-        >
-          <template slot-scope="scope">
-            <!-- 分析完成 -->
-            <el-button
-              v-if="scope.row.analysisState == 30 && scope.row.errState !== 1"
-              @click="handleAssetssDetail(scope.row, '1')"
-              type="text"
-              size="small"
-              >分析详情</el-button
-            >
-            <!-- 分析中 -->
-            <el-button
-              v-else-if="
-                scope.row.analysisState == 20 && scope.row.errState == 0
-              "
-              @click="handleAssetssDetail(scope.row, '0')"
-              type="text"
-              size="small"
-              >分析详情</el-button
-            >
-
-            <span v-else>/</span>
-          </template>
-        </el-table-column>
-        <el-table-column
-          prop="reportVos"
-          align="center"
-          label="报告"
-          min-width="120"
+          label="起始日期"
+          min-width="230"
         >
-          <template slot-scope="scope">
-            <el-dropdown v-if="scope.row.reportVos.length > 0" trigger="click">
-              <el-button type="text" size="small" class="el-dropdown-link">
-                查看报告
-              </el-button>
-              <el-dropdown-menu slot="dropdown">
-                <el-dropdown-item
-                  v-for="val in scope.row.reportVos"
-                  class="reportItemVal"
-                >
-                  <div class="reportLeft">
-                    <span>{{ val.reportName }}</span>
-                  </div>
-                  <div class="reportRight">
-                    <el-button
-                      type="text"
-                      size="small"
-                      @click="detailReportAssetss(val)"
-                    >
-                      查看
-                    </el-button>
-                    <el-button
-                      type="text"
-                      size="small"
-                      @click="downLoadeAssetss(val)"
-                    >
-                      下载
-                    </el-button>
-                  </div>
-                </el-dropdown-item>
-              </el-dropdown-menu>
-            </el-dropdown>
-            <span v-else>/</span>
-          </template>
         </el-table-column>
         <el-table-column
-          prop="dataStartTime"
+          prop="createTime"
           align="center"
-          label="开始时间"
+          label="创建时间"
           min-width="230"
         >
         </el-table-column>
         <el-table-column
-          prop="dataEndTime"
+          prop="updateTime"
           align="center"
-          label="结束时间"
+          label="更新时间"
           min-width="230"
         >
         </el-table-column>
@@ -274,40 +106,21 @@
         >
           <template slot-scope="scope">
             <el-button
-              @click="abnormalDialog(scope.row, '上传报告')"
-              type="text"
-              size="small"
-              >上传报告</el-button
-            >
-            <el-button
-              @click="handleAssetss(scope.row)"
-              type="text"
-              :disabled="
-                (scope.row.analysisState == 20 && scope.row.errState == 0) ||
-                scope.row.analysisState == 10
-              "
-              size="small"
-              >分析</el-button
-            >
-            <el-button
-              @click="abnormalDialog(scope.row, '机组异常记录')"
-              type="text"
-              size="small"
-              >机组异常记录</el-button
-            >
-            <el-button
-              v-if="scope.row.analysisState == 10"
+              v-if="scope.row.startupState == 0"
               @click="insertQueue(scope.row, 1)"
               type="text"
               size="small"
-              >插队</el-button
+              >启动</el-button
             >
             <el-button
-              v-if="scope.row.analysisState == 10"
+              v-if="scope.row.startupState == 1"
               @click="insertQueue(scope.row, 0)"
               type="text"
               size="small"
-              >取消插队</el-button
+              >关停</el-button
+            >
+            <el-button @click="editDialog(scope.row)" type="text" size="small"
+              >修改</el-button
             >
           </template>
         </el-table-column>
@@ -323,18 +136,71 @@
         </el-pagination>
       </div>
     </div>
+    <el-dialog
+      :title="title + '自动分析'"
+      :visible.sync="addDialogVisible"
+      width="30%"
+      class="dialogForm"
+      :before-close="handleClose"
+    >
+      <el-form
+        :label-position="labelPosition"
+        label-width="80px"
+        ref="formLabelAlign"
+        :rules="rules"
+        :model="formLabelAlign"
+      >
+        <el-form-item label="分析风场" prop="fieldCode">
+          <el-select
+            size="small"
+            v-model="formLabelAlign.fieldCode"
+            @change="handleTimeChange"
+            placeholder="请选择分析风场"
+          >
+            <el-option
+              :label="item.fieldName"
+              v-for="item in fieldCodeList"
+              :value="item.codeNumber"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="间隔天数" prop="intervalDays">
+          <el-input-number
+            size="small"
+            v-model="formLabelAlign.intervalDays"
+            min="1"
+            controls-position="right"
+          ></el-input-number>
+        </el-form-item>
+        <el-form-item label="起始日期" prop="startTime">
+          <el-date-picker
+            value-format="yyyy-MM-dd"
+            size="small"
+            v-model="formLabelAlign.startTime"
+            type="date"
+            placeholder="选择日期"
+            :picker-options="pickerOptions"
+          >
+          </el-date-picker>
+        </el-form-item>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="cancel">取 消</el-button>
+        <el-button type="primary" @click="addDialogSubmit">确 定</el-button>
+      </span>
+    </el-dialog>
   </div>
 </template>
 
 <script>
+import axios from "axios";
 import MyDialog from "./components/dialogCom.vue";
-import { downloadPDF } from "@/utils/common";
 import {
-  onOffAutoAnalysis,
-  analysisResultList,
-  addAnalysisResult,
+  autoAnalysisConfigList,
+  onOff,
   queryCodeNum,
-  editPriority,
+  configSave,
+  configEdit,
 } from "@/api/performance";
 export default {
   components: {
@@ -342,124 +208,168 @@ export default {
   },
   data() {
     return {
+      title: "",
+      editId: "",
+      fieldCodeList: [],
       addDialogVisible: false,
       loading: false, //数据加载中
       errorInfo: "",
       options: [
         {
-          value: "-1",
-          label: "未关联",
-        },
-        {
-          value: "10",
-          label: "排队中",
+          value: "0",
+          label: "关停",
         },
         {
-          value: "20",
-          label: "分析中",
-        },
-        {
-          value: "30",
-          label: "已分析",
+          value: "1",
+          label: "启动",
         },
       ],
-
-      rules: {
-        fieldName: { trigger: "blur" },
-      },
       formInline: {
         fieldName: undefined,
         pageNum: 1,
         pageSize: 10,
         totalSize: 0,
-        analysisName: undefined,
-        analysisState: undefined,
+        startupState: undefined,
+      },
+      labelPosition: "right",
+      formLabelAlign: {
+        fieldCode: "",
+        intervalDays: null,
+        startTime: null,
+      },
+      rules: {
+        intervalDays: [
+          { required: true, message: "请输入间隔天数", trigger: "blur" },
+        ],
+        fieldCode: [
+          { required: true, message: "请选择分析风场", trigger: "change" },
+        ],
+        startTime: [
+          {
+            type: "string", // Vue 可能传递字符串,所以用 string
+            required: true,
+            message: "请选择自动分析起始日期",
+            trigger: "change",
+          },
+        ],
       },
       tableData: [],
       rowInfo: {},
       title: "",
+      restrictTime: null,
+      disableAllDates: false, // 是否禁用所有日期
     };
   },
+  computed: {
+    pickerOptions() {
+      return {
+        disabledDate: (time) => {
+          if (this.disableAllDates) {
+            return true; // 禁用所有日期
+          }
+          if (!this.restrictTime) {
+            return false; // 还没获取数据时,不限制
+          }
+          const restrictTimestamp = new Date(this.restrictTime).setHours(
+            0,
+            0,
+            0,
+            0
+          );
+          const currentTimestamp = time.setHours(0, 0, 0, 0);
+          return currentTimestamp < restrictTimestamp; // 允许选择 restrictTime 当天
+        },
+      };
+    },
+  },
 
   methods: {
+    editDialog(row) {
+      this.title = "编辑";
+      this.formLabelAlign = { ...row };
+      this.addDialogVisible = true;
+    },
+    async addDialogSubmit() {
+      this.$refs.formLabelAlign.validate(async (valid) => {
+        if (!valid) return;
+        try {
+          const apiMethod = this.title === "编辑" ? configEdit : configSave;
+          const res = await apiMethod(this.formLabelAlign);
+          if (res.code === 200) {
+            this.$message.success("保存成功");
+            await this.getTableList();
+            this.resetFormLabelAlign();
+            this.addDialogVisible = false;
+          } else {
+            this.$message.error(res.msg);
+          }
+        } catch (error) {}
+      });
+    },
     //获取风场列表
-
+    async getQueryCodeNumList() {
+      this.loading = true;
+      try {
+        const result = await queryCodeNum();
+        this.fieldCodeList = result.data.fieldCodeList;
+        this.loading = false;
+      } catch (error) {
+        console.error(error);
+        this.loading = false;
+      }
+    },
     //插队接口
     async insertQueue(row, index) {
-      this.$confirm(`确认插队?`, "提示", {
-        confirmButtonText: "确定",
-        cancelButtonText: "取消",
-        type: "warning",
-      })
+      this.$confirm(
+        `确认${row.startupState == "0" ? "启动" : "关停"}?`,
+        "提示",
+        {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning",
+        }
+      )
         .then(async () => {
-          const formData = new FormData();
-          formData.append("batchCode", row.batchCode);
-          formData.append("priority", index);
-          const result = await editPriority(formData);
-          console.log(result, "插队结果");
+          const formData = {
+            configUniqueId: row.configUniqueId,
+            fieldCode: row.fieldCode,
+            startupState: index,
+          };
+          const result = await onOff(formData);
           if (result.code === 200) {
             this.$message({
               type: "success",
-              message: "插队成功",
+              message: "成功",
             });
-            await this.fetchData();
+            await this.getTableList();
           }
         })
         .catch(() => {});
     },
-    //分析
-    handleAssetss(row) {
-      this.$router.push({
-        path: "/home/performance/editAssets",
-        query: {
-          batchCode: row.batchCode,
-          analysisTypeCode: row.analysisTypeCode,
-          fieldEngineCode: row.fieldCode,
-          fieldName: row.fieldName,
-          analysisName: row.analysisName,
-        },
-      });
-    },
-    //分析详情
-    handleAssetssDetail(row, state) {
-      const navigateToDetails = () => {
-        this.$router.push({
-          path: "/home/performance/overview",
-          query: {
-            batchCode: row.batchCode,
-            // analysisTypeCode: row.analysisTypeCode,
-            fieldCode: row.fieldCode,
-          },
-        });
-      };
-      if (state === "0") {
-        // 分析状态为分析中
-        this.$confirm(
-          "当前查看的分析记录为历史分析结果,最新分析记录还未分析完成不展示!"
-        )
-          .then(() => {
-            navigateToDetails();
-          })
-          .catch(() => {});
-      } else {
-        navigateToDetails();
-      }
-    },
-    abnormalDialog(row, title) {
-      if (title === "异常详情") {
-        this.errorInfo = row.errInfo;
-        this.rowInfo = {};
-      } else if (title === "机组异常记录") {
-        this.errorInfo = "";
-        this.rowInfo = { ...row };
-      } else if (title === "上传报告") {
-        this.errorInfo = "";
-        this.rowInfo = {};
-        this.rowInfo.batchCode = row.batchCode;
-      }
-      this.title = title;
-    },
+    //时间范围
+    async handleTimeChange() {
+      try {
+        const params = {
+          windFarmCode: this.formLabelAlign.fieldCode,
+        };
+        const res = await axios.get(
+          "/ETLapi/windFarmDayCount/pltAutoAnalysisTime",
+          { params }
+        );
 
+        if (res.data.code === 200) {
+          this.restrictTime = res.data?.datas?.startTime
+            ? new Date(res.data.datas.startTime)
+            : null;
+          this.disableAllDates = false;
+        } else if (res.data.code === 500) {
+          this.disableAllDates = true;
+          this.$message.warning("数据错误,无法选择日期");
+        } else {
+          this.$message.warning(res.data.message);
+        }
+      } catch (error) {}
+    },
     // 页码变化时才触发查询
     handleCurrentChange(val) {
       this.formInline.pageNum = val;
@@ -473,19 +383,12 @@ export default {
       this.loading = true;
       try {
         const params = { ...this.formInline, totalSize: undefined };
+        const result = await autoAnalysisConfigList(params);
 
-        // 传递条件参数
-        if (this.formInline.analysisState !== undefined) {
-          params.analysisState = this.formInline.analysisState;
-        }
-        if (this.formInline.errState !== undefined) {
-          params.errState = this.formInline.errState;
-        }
+        // 确保 list 不是 undefined
+        this.tableData = result.data?.list || [];
 
-        const result = await analysisResultList(params);
-        this.tableData = result.data.list;
-        console.log(this.tableData, "result this.tableData");
-        this.formInline.totalSize = result.data.totalSize;
+        this.formInline.totalSize = result.data?.totalSize || 0; // 确保 totalSize 不是 undefined
       } catch (error) {
         this.$message({
           type: "error",
@@ -498,42 +401,39 @@ export default {
     rowStyle() {
       return "text-align:center";
     },
+    cancel() {
+      this.resetFormLabelAlign();
+      this.addDialogVisible = false;
+    },
     // 查询
     onSubmit() {
-      this.fetchData();
+      this.getTableList();
     },
     // 重置
     reset(formName) {
       this.$refs[formName].resetFields();
       this.formInline.fieldName = "";
-      this.formInline.analysisName = "";
-      this.formInline.analysisState = "";
-      this.formInline.errState = "";
-      this.fetchData();
+      this.formInline.startupState = null;
+      this.getTableList();
     },
-    // fetchData 方法在轮询中调用
-    async fetchData() {
-      try {
-        const result = await analysisResultList({
-          ...this.formInline,
-          totalSize: undefined,
-        });
-        this.tableData = result.data.list;
-        this.formInline.totalSize = result.data.totalSize;
-      } catch (error) {
-        this.$message({
-          type: "error",
-          message: "请检查是否连接网络",
-        });
-      }
+    resetFormLabelAlign() {
+      this.formLabelAlign = {
+        fieldCode: "",
+        intervalDays: "",
+        startTime: "",
+      };
     },
-    examine() {
-      const targetUrl = this.$router.resolve({ name: "transition" }).href;
-      window.open(targetUrl, "_blank");
+    handleClose(done) {
+      this.$confirm("确认关闭?")
+        .then((_) => {
+          done();
+        })
+        .catch((_) => {});
     },
   },
   mounted() {
     this.getTableList();
+    this.getQueryCodeNumList();
   },
 };
 </script>
@@ -547,108 +447,13 @@ export default {
     background-position: 1.25em 1.25em;
   }
 }
-.general {
-  display: flex;
-  flex-wrap: wrap;
-
-  .condition {
-    width: 50%;
-    display: flex;
-
-    p {
-      width: 100px;
-      text-align: right;
-      line-height: 40px;
-    }
-
-    span {
-      line-height: 40px;
-
-      padding-left: 20px;
-    }
-
-    .el-select {
-      width: 100%;
-      margin-bottom: 20px;
-    }
-
-    .el-input {
-      margin-bottom: 20px;
-    }
-  }
-}
-
-.attachment {
-  display: flex;
-  padding-top: 10px;
-
-  p {
-    margin-right: 20px;
-    color: #409eff;
-  }
-}
-.add-ruleForm {
-  .el-select {
-    width: 100%;
-  }
-}
-.addition {
-  display: flex;
-  justify-content: flex-end;
-  margin-bottom: 10px;
-}
-.demo-ruleForm {
-  .el-form-item {
-    margin-bottom: 25px;
-  }
-}
-::v-deep .animated-progress .el-progress-bar__outer {
-  height: 15px; /* Adjust height as needed */
-  background-color: rgb(235, 238, 245);
-  background-image: linear-gradient(
-    45deg,
-    rgba(0, 0, 0, 0.1) 25%,
-    transparent 25%,
-    transparent 50%,
-    rgba(0, 0, 0, 0.1) 50%,
-    rgba(0, 0, 0, 0.1) 75%,
-    transparent 75%,
-    transparent
-  );
-  background-size: 1.25em 1.25em;
-  animation: striped-flow 3s linear infinite;
+.dialogForm .el-input-number--small {
+  width: 220px;
 }
-.reportItemVal {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  .reportLeft {
-    margin-right: 50px;
-  }
+.dialogForm .el-select--small {
+  width: 220px;
 }
-::v-deep .pdfDialog .el-dialog {
-  height: 100vh;
-  display: flex;
-  flex-direction: column;
-  margin: 0 auto !important;
-  .el-dialog__body {
-    // height: 100% !important;
-    flex: 1;
-    background: #fff;
-    .pdf-container {
-      display: flex;
-      justify-content: center;
-      align-items: center;
-      height: 100% !important;
-    }
-  }
-}
-
-canvas {
-  border: 1px solid #dcdfe6;
-}
-
-.right-align {
-  white-space: nowrap;
+.dialogForm .el-form-item {
+  margin-bottom: 20px;
 }
 </style>

+ 2 - 1
vue.config.js

@@ -89,7 +89,8 @@ module.exports = {
         // target: "http://192.168.5.11:8001", // WZLapi 目标地址
         // target: "http://106.120.102.238:18080/ImportDataDev", //导数工具
         // target: "http://106.120.102.238:18080/WindTransDev", //WTL外网目标地址
-        target: "http://106.120.102.238:28999/transDataWeb", //WTL演示环境
+        // target: "http://106.120.102.238:28999/transDataWeb", //WTL演示环境
+        target: "http://192.168.50.235:8999/transDataWeb", //WTL演示环境
         changeOrigin: true,
         pathRewrite: {
           "^/ETLapi": "", // 去掉 /WZLapi 前缀