소스 검색

更改主题、健康、振动、分析概览叶尖速比cp散点功率展示

liujiejie 2 달 전
부모
커밋
c57f9ff5ae
53개의 변경된 파일5724개의 추가작업 그리고 3253개의 파일을 삭제
  1. 1 1
      .env.dev
  2. 100 85
      downLoadServer/src/server/utils/chartsCom/TwoDMarkersChart.js
  3. 1 1
      src/components/HeaderCom.vue
  4. 24 26
      src/components/map/index.vue
  5. 1 1
      src/store/themes.js
  6. 7 3
      src/styles/base.css
  7. 3 3
      src/styles/global.scss
  8. 476 3
      src/styles/legacy-theme.scss
  9. 238 19
      src/styles/tech-theme.scss
  10. 2 1
      src/themes/blue.scss
  11. 2 2
      src/themes/dark.scss
  12. 6 5
      src/themes/green.scss
  13. 2 1
      src/themes/light.scss
  14. 40 0
      src/themes/tech-blue.scss
  15. 195 109
      src/views/admin/cockpitManage/Index.vue
  16. 0 1601
      src/views/admin/cockpitManage/cockpit-dashboard.scss
  17. 0 235
      src/views/admin/cockpitManage/component/CockpitAbnormalPanel.vue
  18. 0 206
      src/views/admin/cockpitManage/component/CockpitHealthPanel.vue
  19. 0 65
      src/views/admin/cockpitManage/component/CockpitHealthTable.vue
  20. 0 96
      src/views/admin/cockpitManage/component/CockpitTechTabs.vue
  21. 0 23
      src/views/admin/cockpitManage/component/cockpitHealthData.js
  22. 0 6
      src/views/admin/cockpitManage/component/cockpitTableMetrics.js
  23. 114 244
      src/views/admin/cockpitManage/component/leftdata.vue
  24. 169 208
      src/views/admin/cockpitManage/component/rightdata.vue
  25. 34 80
      src/views/admin/cockpitManage/component/tabroll.vue
  26. 6 5
      src/views/health/components/malfunction/bearing.vue
  27. 6 5
      src/views/health/components/malfunction/dissymmetry.vue
  28. 6 5
      src/views/health/components/malfunction/gear.vue
  29. 6 5
      src/views/health/components/malfunction/loose.vue
  30. 6 5
      src/views/health/components/malfunction/misalignment.vue
  31. 114 0
      src/views/health/components/malfunctionOld/Eecharts.vue
  32. 483 0
      src/views/health/components/malfunctionOld/bearing.vue
  33. 146 0
      src/views/health/components/malfunctionOld/bing.vue
  34. 154 0
      src/views/health/components/malfunctionOld/bingTwo.vue
  35. 432 0
      src/views/health/components/malfunctionOld/dissymmetry.vue
  36. 475 0
      src/views/health/components/malfunctionOld/gear.vue
  37. 431 0
      src/views/health/components/malfunctionOld/loose.vue
  38. 431 0
      src/views/health/components/malfunctionOld/misalignment.vue
  39. 423 0
      src/views/health/components/malfunctionOld/temperature.vue
  40. 277 0
      src/views/health/components/malfunctionOld/zhexian.vue
  41. 737 93
      src/views/health/index.vue
  42. 7 7
      src/views/health/malfunction.vue
  43. 7 7
      src/views/health/malfunctionOld.vue
  44. 10 10
      src/views/ledger/maintain.vue
  45. 34 5
      src/views/login/Index.vue
  46. 1 0
      src/views/overview/components/tsr_cp_power_scatter/index.vue
  47. 2 2
      src/views/performance/assetssMag.vue
  48. 0 1
      src/views/performance/components/analysisEvent.vue
  49. 66 42
      src/views/performance/components/chartsCom/TwoDMarkersChart.vue
  50. 1 1
      src/views/performance/editAssets.vue
  51. 39 27
      src/views/transition/index.vue
  52. 1 1
      src/views/windResourceWake/data/mockData.js
  53. 8 8
      vue.config.js

+ 1 - 1
.env.dev

@@ -7,7 +7,7 @@
  # @FilePath: /performance-test/.env.dev
 #这里需要在router/index.js 文件中进行判断cockpitComponent;
 #VUE_APP_HOME_COM="../views/admin/cockpitManage/Index.vue"
-VUE_APP_THEM="tech-blue"
+VUE_APP_THEM="green"
 VUE_APP_ISSHOWHD='default'
 VUE_APP_Helath='dev'
 VUE_APP_TITLE='机组功率曲线异常检测数据分析系统'

+ 100 - 85
downLoadServer/src/server/utils/chartsCom/TwoDMarkersChart.js

@@ -1,42 +1,66 @@
 import { renderChart } from "../chartService/index.js";
 import { colorSchemes } from "../colors.js";
 
-const MAX_COLORBAR_CATEGORIES = Number.parseInt(
-  process.env.CHART_MAX_COLORBAR_CATEGORIES || "50",
-  10,
-);
+const isArray = (val) => Array.isArray(val);
+const isString = (val) => typeof val === "string";
 
-const buildColorConfig = (rawColorData) => {
-  const seen = new Map();
-  let allNumeric = true;
-
-  for (const value of rawColorData) {
-    const numericValue = Number(value);
-    if (!Number.isFinite(numericValue)) allNumeric = false;
-
-    if (seen.size <= MAX_COLORBAR_CATEGORIES && !seen.has(value)) {
-      seen.set(value, seen.size + 1);
-    }
+const getUniformPointColor = (colors) => {
+  if (!Array.isArray(colors) || colors.length === 0) {
+    return "#407DB3";
   }
+  const midIndex = Math.floor(colors.length - 2);
+  return colors[midIndex] || colors[0] || "#407DB3";
+};
 
-  // 连续数值或分类过多时,直接使用连续色条;避免为海量唯一值生成 ticktext/tickvals/mapping。
-  if (allNumeric || seen.size > MAX_COLORBAR_CATEGORIES) {
-    return {
-      colorValues: rawColorData.map((value) => Number(value)),
-      colorbar: undefined,
-      customdata: undefined,
-    };
+const buildColorscale = (colors) => {
+  const safePick = (i) => colors[i] || colors[0] || "#1B2973";
+  const colorStops = [safePick(0), safePick(4), safePick(8), safePick(12)];
+  const colorscale = colorStops.map((color, index) => [
+    index / (colorStops.length - 1),
+    color,
+  ]);
+  if (colorscale.length < 2) {
+    colorscale.push([1, colorStops[colorStops.length - 1] || "#1B2973"]);
   }
+  return colorscale;
+};
 
-  const ticktext = [...seen.keys()];
-  return {
-    colorValues: rawColorData.map((value) => seen.get(value)),
-    colorbar: {
-      tickvals: ticktext.map((_, i) => i + 1),
-      ticktext,
-    },
-    customdata: rawColorData,
-  };
+const buildColorValues = (chartDataset, xData, yData) => {
+  const uniqueTimeLabels =
+    chartDataset.colorbar?.length === xData.length
+      ? [...new Set(chartDataset.colorbar)]
+      : [...new Set(yData)];
+  const timeMapping = uniqueTimeLabels.reduce((acc, curr, index) => {
+    acc[curr] = index + 1;
+    return acc;
+  }, {});
+  const colorValues =
+    chartDataset.colorbar?.length === xData.length
+      ? chartDataset.colorbar.map((value) => timeMapping[value])
+      : yData.map((value) => timeMapping[value]);
+  const maxValue = Math.max(...uniqueTimeLabels);
+  return { colorValues, maxValue };
+};
+
+const buildHoverTemplate = (chartData, chartDataset) => {
+  if (chartDataset.colorbar && isArray(chartDataset.colorbar)) {
+    return (
+      `${chartData.xaixs}: %{x}<br>` +
+      `${chartData.yaixs}: %{y}<br>` +
+      `${chartDataset.colorbartitle}:%{customdata}<extra></extra>`
+    );
+  }
+  if (chartDataset.colorbar && isString(chartDataset.colorbar)) {
+    return (
+      `${chartData.xaixs}: %{x}<br>` +
+      `${chartData.yaixs}: %{y}<br>` +
+      `${chartDataset.colorbartitle}:${chartDataset.colorbar}<extra></extra>`
+    );
+  }
+  return (
+    `${chartData.xaixs}: %{x}<br>` +
+    `${chartData.yaixs}: %{y}<extra></extra>`
+  );
 };
 
 export const generateTwoDMarkersChart = async (
@@ -51,66 +75,59 @@ export const generateTwoDMarkersChart = async (
     }
 
     const { xData, yData, title, engineName } = chartDataset;
-
-    // ✅ 1. color 数据源(统一逻辑)
-    const rawColorData =
-      chartDataset.colorbar?.length === xData.length
-        ? chartDataset.colorbar
-        : yData;
-
-    // ✅ 2. 颜色渐变(安全版)
     const colors = colorSchemes?.[0]?.colors || [];
+    const uniformColor =
+      data.analysisTypeCode === "tsr_cp_power_scatter" ||
+      data.analysisTypeCode === "叶尖速比-风能利用系数-功率散点" ||
+      objectName?.includes("/tsr_cp_power_scatter/");
+    const uniformPointColor = getUniformPointColor(colors);
+    const pointSize = 5;
+
+    let marker = {
+      size: new Array(xData.length).fill(pointSize),
+    };
 
-    const safePick = (i) => colors[i] || colors[0] || "#1B2973";
-
-    const colorStops = [safePick(0), safePick(4), safePick(8), safePick(12)];
-
-    const colorscale = colorStops.map((c, i) => [
-      i / (colorStops.length - 1),
-      c,
-    ]);
-
-    if (colorscale.length < 2) {
-      colorscale.push([1, safePick(0)]);
+    if (uniformColor) {
+      marker.color = uniformPointColor;
+    } else {
+      const { colorValues, maxValue } = buildColorValues(
+        chartDataset,
+        xData,
+        yData,
+      );
+      marker.color = colorValues;
+      marker.colorscale = buildColorscale(colors);
+
+      if (chartDataset.colorbartitle === "密度") {
+        marker.cmin = 0;
+        marker.cmax = maxValue;
+      } else if (chartDataset.colorbartitle === "百分比(%)") {
+        marker.cmin = 0;
+        marker.cmax = 100;
+      }
     }
 
-    // ✅ 3. 映射颜色值:小分类使用离散刻度,大数据/连续值使用连续色条
-    const colorConfig = buildColorConfig(rawColorData);
-
-    // ⚠️ 性能优化(点很多时很关键🔥)
-    const pointCount = xData.length;
-    const markerSize = pointCount > 5000 ? 3 : 6;
-
-    // ✅ 5. trace
     const trace = {
       x: xData,
       y: yData,
       type: "scattergl",
       mode: "markers",
-      name: engineName || "散点图",
-      marker: {
-        color: colorConfig.colorValues,
-        colorscale,
-        size: markerSize,
-        colorbar: {
-          title: { text: chartDataset.colorbartitle || "分类" },
-          ...colorConfig.colorbar,
-        },
-      },
-      customdata: colorConfig.customdata,
-      hovertemplate:
-        `${data.xaixs}: %{x}<br>` +
-        `${data.yaixs}: %{y}<br>` +
-        (colorConfig.customdata
-          ? `分类: %{customdata}<extra></extra>`
-          : `<extra></extra>`),
+      text: engineName,
+      marker,
+      hovertemplate: buildHoverTemplate(data, chartDataset),
     };
 
-    // ✅ 6. layout(简化+统一风格)
+    if (chartDataset.colorbar && isArray(chartDataset.colorbar)) {
+      trace.customdata = chartDataset.colorbar || chartDataset.color;
+    }
+
     const layout = {
       title: {
         text: title || "2D散点图",
-        font: { size: 16 },
+        font: {
+          size: 16,
+          weight: "bold",
+        },
       },
       xaxis: {
         title: data.xaixs,
@@ -118,9 +135,6 @@ export const generateTwoDMarkersChart = async (
         tickcolor: "rgb(255,255,255)",
         backgroundcolor: "#e5ecf6",
         showbackground: true,
-        showline: true, // ✅ 显示 X 轴轴线
-        zeroline: false,
-        linecolor: "#ffffff", // ✅ X 轴轴线颜色设为白色
       },
       yaxis: {
         title: data.yaixs,
@@ -128,16 +142,17 @@ export const generateTwoDMarkersChart = async (
         tickcolor: "rgb(255,255,255)",
         backgroundcolor: "#e5ecf6",
         showbackground: true,
-        showline: true, // ✅ 显示 X 轴轴线
-        zeroline: false,
-        linecolor: "#ffffff", // ✅ X 轴轴线颜色设为白色
       },
       showlegend: false,
       plot_bgcolor: "#e5ecf6",
-      paper_bgcolor: "#e5ecf6",
+      gridcolor: "#fff",
     };
 
-    // ✅ 7. 渲染
+    if (data.xaixs === "时间") {
+      layout.xaxis.type = "date";
+      layout.xaxis.tickformat = "%Y-%m-%d";
+    }
+
     const url = await renderChart({
       traces: [trace],
       layout,

+ 1 - 1
src/components/HeaderCom.vue

@@ -116,7 +116,7 @@ export default {
       currentDate: "",
       currentTheme: this.$store.state.themes.theme,
       colorData: [
-        { lable: "科技蓝", value: "tech-blue", color: "#1890ff" },
+        // { lable: "科技蓝", value: "tech-blue", color: "#1890ff" },
         { lable: "黄色", value: "light", color: "#82780ccf" },
         { lable: "深色", value: "dark", color: "#607d8b" },
         { lable: "绿色", value: "green", color: "#008080" },

+ 24 - 26
src/components/map/index.vue

@@ -592,48 +592,46 @@ export default {
   height: 100%;
 }
 
-.hover-info {
-  position: absolute;
-  color: white;
-  padding: 0;
-  z-index: 100;
-  h3 {
-    background-color: var(--header-bg);
-    width: 240px;
-    padding: 5px 10px;
-    font-size: 16px;
-  }
-  div {
-    background-color: var(--content-bg);
-    width: 240px;
-    font-size: 12px;
-    p {
-      padding: 5px 10px;
-      display: flex;
-      justify-content: space-between;
-    }
-  }
-}
-
+.hover-info,
 .hover-fengji {
   position: absolute;
-  color: white;
   padding: 0;
   z-index: 100;
+  border-radius: 4px;
+  overflow: hidden;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
+
   h3 {
-    background-color: var(--header-bg);
+    margin: 0;
+    background-color: var(
+      --map-hover-header-bg,
+      var(--primary-color, #008080)
+    );
+    color: var(--map-hover-header-text, #ffffff);
     width: 240px;
     padding: 5px 10px;
     font-size: 16px;
   }
+
   div {
-    background-color: var(--content-bg);
+    background-color: var(--map-hover-body-bg, #ffffff);
+    color: var(--map-hover-text, #606266);
     width: 240px;
     font-size: 12px;
+
     p {
+      margin: 0;
       padding: 5px 10px;
       display: flex;
       justify-content: space-between;
+
+      span:first-child {
+        color: var(--map-hover-label-text, #909399);
+      }
+
+      span:last-child {
+        color: var(--map-hover-text, #303133);
+      }
     }
   }
 }

+ 1 - 1
src/store/themes.js

@@ -12,7 +12,7 @@ import { colorSchemes } from "@/views/overview/js/colors";
 export default {
   namespaced: true,
   state: {
-    theme: localStorage.getItem("theme") || process.env.VUE_APP_THEM, //华电默认主题色
+    theme: localStorage.getItem("theme") || process.env.VUE_APP_THEM || "green",
     themeColor: [...colorSchemes[0].colors],
   },
   mutations: {

+ 7 - 3
src/styles/base.css

@@ -129,9 +129,13 @@ small {
   font-size: 80%;
 }
 
-input:-webkit-autofill {
-  -webkit-box-shadow: 0 0 0 1000px #000c17 inset !important;
-  -webkit-text-fill-color: #52c8f2 !important;
+input:-webkit-autofill,
+input:-webkit-autofill:hover,
+input:-webkit-autofill:focus,
+input:-webkit-autofill:active {
+  -webkit-box-shadow: 0 0 0 1000px #ffffff inset !important;
+  -webkit-text-fill-color: #606266 !important;
+  caret-color: #606266;
 }
 
 sub,

+ 3 - 3
src/styles/global.scss

@@ -32,7 +32,7 @@
 .el-button--text,
 .el-button--text:hover,
 .el-button--text:focus {
-  color: var(--table-cell-text, var(--text-cyan, #b7dff5)) !important;
+  color: var(--primary-color) !important;
   background: transparent !important;
   border: none !important;
   box-shadow: none !important;
@@ -74,8 +74,8 @@
 }
 
 .el-tag:not(.el-tag--warning):not(.el-tag--danger):not(.el-tag--info) {
-  background-color: #00808036 !important;
-  border-color: #00808042 !important;
+  background-color: var(--bgopacity-color) !important;
+  border-color: var(--bgopacity-color) !important;
   color: var(--primary-color) !important;
 }
 .el-tag {

+ 476 - 3
src/styles/legacy-theme.scss

@@ -70,6 +70,53 @@ html:not([data-theme="tech-blue"]) {
     color: #ffffff !important;
   }
 
+  .el-button--text,
+  .el-button--text:hover,
+  .el-button--text:focus {
+    color: var(--primary-color, #82780c) !important;
+    background: transparent !important;
+    border: none !important;
+    box-shadow: none !important;
+  }
+
+  .el-table .cell .el-button--text,
+  .el-table .el-button--text {
+    color: var(--primary-color, #82780c) !important;
+
+    &:hover,
+    &:focus {
+      color: var(--primary-color, #82780c) !important;
+      opacity: 0.85;
+      background: transparent !important;
+    }
+
+    &.is-disabled,
+    &.is-disabled:hover,
+    &.is-disabled:focus {
+      color: #c0c4cc !important;
+    }
+  }
+
+  .el-menu-item.is-active,
+  .el-menu-item.is-active i,
+  .el-menu-item.is-active span,
+  .el-submenu .el-menu-item.is-active,
+  .el-submenu .el-menu-item.is-active i,
+  .el-submenu .el-menu-item.is-active span {
+    color: var(--primary-color, #82780c) !important;
+    background-color: transparent !important;
+  }
+
+  .el-submenu.is-active > .el-submenu__title,
+  .el-submenu.is-active > .el-submenu__title i,
+  .el-submenu.is-active > .el-submenu__title span {
+    color: var(--primary-color, #82780c) !important;
+  }
+
+  .theme-status-success {
+    color: var(--success-color, var(--primary-color, #82780c)) !important;
+  }
+
   .el-button--primary:hover,
   .el-button--primary:focus {
     opacity: 0.9;
@@ -275,6 +322,7 @@ html:not([data-theme="tech-blue"]) {
   }
 
   /* 分析事件页(editAssets / analysisEvent) */
+  .edit-assets-page,
   .analysis-event-page {
     color: #303133;
 
@@ -286,8 +334,14 @@ html:not([data-theme="tech-blue"]) {
       color: #303133 !important;
     }
 
+    .el-collapse {
+      border: 1px solid #ebeef5 !important;
+      border-radius: 4px;
+      overflow: hidden;
+    }
+
     .el-collapse-item__header {
-      background: var(--table-header-bg, #9c9a3f) !important;
+      background: var(--primary-color, #82780c) !important;
       color: #ffffff !important;
       border-color: #ebeef5 !important;
     }
@@ -299,6 +353,22 @@ html:not([data-theme="tech-blue"]) {
 
     .el-collapse-item__content {
       color: #303133 !important;
+      background: #ffffff !important;
+    }
+
+    .searchFrom {
+      .el-button--default {
+        background: #ffffff !important;
+        border-color: var(--primary-color, #82780c) !important;
+        color: var(--primary-color, #82780c) !important;
+
+        &:hover,
+        &:focus {
+          background: var(--bgopacity-color, rgba(0, 0, 0, 0.04)) !important;
+          border-color: var(--primary-color, #82780c) !important;
+          color: var(--primary-color, #82780c) !important;
+        }
+      }
     }
 
     .setting {
@@ -308,17 +378,388 @@ html:not([data-theme="tech-blue"]) {
     .box-card {
       border-color: #ebeef5 !important;
       background: #ffffff !important;
+      box-shadow: none !important;
     }
 
     .filedView {
-      background: var(--table-header-bg, #9c9a3f) !important;
-      color: #ffffff !important;
+      background: #ffffff !important;
+      color: #303133 !important;
+      border-bottom: 1px solid #ebeef5 !important;
     }
 
     .box-card .el-card__body {
       background: #ffffff !important;
       color: #303133 !important;
     }
+
+    .el-input__inner,
+    .el-textarea__inner,
+    .el-select .el-input__inner,
+    .el-date-editor .el-input__inner,
+    .el-range-editor.el-input__inner {
+      background-color: #ffffff !important;
+      border-color: #dcdfe6 !important;
+      color: #606266 !important;
+    }
+
+    .el-checkbox__label {
+      color: #606266 !important;
+    }
+  }
+
+  .edit-assets-page {
+    > .el-row .el-button--text {
+      color: var(--primary-color, #82780c) !important;
+      padding-left: 0;
+      font-weight: 500;
+    }
+  }
+
+  /* 登录页 */
+  .background-image {
+    .border {
+      background: #ffffff !important;
+      border-color: #ebeef5 !important;
+      box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1) !important;
+
+      .leftLogin h1 {
+        color: var(--primary-color, #008080) !important;
+      }
+
+      .leftLogin .el-divider--horizontal {
+        background: var(--primary-color, #008080) !important;
+      }
+
+      .el-input__inner {
+        background-color: #ffffff !important;
+        border-color: #dcdfe6 !important;
+        color: #606266 !important;
+      }
+
+      .el-input__inner::placeholder {
+        color: #c0c4cc !important;
+      }
+
+      .el-input__inner:focus {
+        border-color: var(--primary-color, #008080) !important;
+      }
+
+      .el-button--primary {
+        background-color: var(--primary-color, #008080) !important;
+        border-color: var(--primary-color, #008080) !important;
+        color: #ffffff !important;
+      }
+    }
+  }
+
+  /* 故障诊断页(malfunction) */
+  .malfunction-page {
+    .searchbox {
+      color: #303133;
+
+      p {
+        color: #606266;
+      }
+    }
+
+    .el-tabs__item {
+      color: #606266 !important;
+    }
+
+    .el-tabs__item.is-active {
+      color: var(--primary-color, #82780c) !important;
+    }
+
+    .el-tabs__item:hover {
+      color: var(--primary-color, #82780c) !important;
+    }
+
+    .el-tabs__active-bar {
+      background-color: var(--primary-color, #82780c) !important;
+    }
+
+    .el-tabs__nav-wrap::after {
+      background-color: #ebeef5 !important;
+    }
+
+    .gear-container {
+      .gear-header {
+        background: #f5f7fa !important;
+        border: none !important;
+        box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1) !important;
+
+        .title {
+          color: #303133 !important;
+        }
+
+        .sub-title {
+          color: #909399 !important;
+        }
+
+        .stat-content {
+          .label {
+            color: #303133 !important;
+          }
+
+          .count {
+            color: #303133 !important;
+          }
+
+          .ratio {
+            color: #909399 !important;
+          }
+        }
+
+        .header-divider.el-divider--vertical {
+          background-color: #dcdfe6 !important;
+        }
+
+        .stat-item.is-normal .icon-wrap {
+          background: var(--primary-color, #82780c) !important;
+        }
+      }
+
+      h4 {
+        color: #303133 !important;
+      }
+
+      .monitor-panel {
+        background: transparent !important;
+        border: none !important;
+        box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1) !important;
+      }
+
+      .monitor-empty {
+        background: #ffffff !important;
+        border: none !important;
+      }
+
+      .monitor-item {
+        background: #ffffff !important;
+        border-color: #e4e7ed !important;
+
+        &.is-active {
+          background: #f0f5f7 !important;
+        }
+
+        &.is-active::before {
+          background: var(--primary-color, #82780c) !important;
+        }
+      }
+
+      .item-main {
+        .item-name {
+          color: #1f2d3d !important;
+        }
+
+        .item-line {
+          color: #6b7280 !important;
+        }
+      }
+
+      .bottomBox {
+        background: #ffffff !important;
+        border: none !important;
+        box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1) !important;
+      }
+
+      .status-legend {
+        color: #909399 !important;
+
+        .legend-label {
+          color: #606266 !important;
+        }
+
+        .legend-item.is-normal {
+          color: var(--primary-color, #82780c) !important;
+        }
+      }
+
+      .index-badge.is-success {
+        background: var(--primary-color, #82780c) !important;
+      }
+
+      .mpoint-chart-item {
+        background: #ffffff !important;
+        border-color: #f0f0f0 !important;
+      }
+
+      .mpoint-chart-title {
+        color: #303133 !important;
+      }
+
+      .el-carousel__indicator.is-active .el-carousel__button,
+      .el-carousel__indicator:hover .el-carousel__button {
+        background-color: var(--primary-color, #82780c) !important;
+      }
+    }
+  }
+
+  /* 导入数据页(transition) */
+  .transition-page {
+    --transition-page-bg: #ffffff;
+    --transition-page-text: #303133;
+    --transition-collapse-header-bg: var(--primary-color, #008080);
+    --transition-collapse-header-text: #ffffff;
+    --transition-collapse-body-bg: #ffffff;
+    --transition-label-color: #606266;
+    --transition-border-color: #ebeef5;
+    --transition-badge-border: var(--primary-color, #008080);
+    --transition-badge-bg: rgba(0, 128, 128, 0.08);
+    --transition-badge-bg-hover: rgba(0, 128, 128, 0.15);
+    --transition-badge-accent: var(--primary-color, #008080);
+    --transition-card-bg: #ffffff;
+    --transition-card-hover-bg: rgba(0, 128, 128, 0.08);
+    --transition-scrollbar-track: #f5f7fa;
+    --transition-scrollbar-thumb: #dcdfe6;
+    --transition-scrollbar-thumb-hover: #c0c4cc;
+
+    background: #ffffff !important;
+    color: #303133 !important;
+
+    .transition-collapse {
+      border-color: #ebeef5 !important;
+
+      .el-collapse-item__header {
+        background: var(--primary-color, #008080) !important;
+        color: #ffffff !important;
+        border-bottom-color: #ebeef5 !important;
+      }
+
+      .el-collapse-item__wrap,
+      .el-collapse-item__content {
+        background: #ffffff !important;
+        color: #303133 !important;
+      }
+    }
+
+    .condition-label {
+      color: #606266 !important;
+    }
+
+    .condition {
+      border-bottom-color: #ebeef5 !important;
+    }
+
+    .CPC {
+      color: #303133 !important;
+      border-color: var(--primary-color, #008080) !important;
+      background: rgba(0, 128, 128, 0.08) !important;
+
+      span {
+        color: var(--primary-color, #008080) !important;
+      }
+    }
+
+    .incoming-desc {
+      .el-descriptions__title,
+      .el-descriptions__content {
+        color: #303133 !important;
+      }
+
+      .el-descriptions__label {
+        color: #606266 !important;
+      }
+
+      .el-descriptions-item__cell {
+        background: #ffffff !important;
+        border-color: #ebeef5 !important;
+      }
+    }
+
+    .demo-table-expand label {
+      color: #606266 !important;
+    }
+
+    .el-button--text {
+      color: var(--primary-color, #008080) !important;
+    }
+
+    .condition-actions .el-button--default {
+      background: #ffffff !important;
+      border-color: #dcdfe6 !important;
+      color: #606266 !important;
+    }
+
+    .card {
+      background: #ffffff !important;
+      border-color: #ebeef5 !important;
+      color: #303133 !important;
+    }
+
+    .scrollable-list {
+      color: #303133 !important;
+    }
+  }
+
+  .transition-drawer,
+  .transition-dialog {
+    .el-drawer__title,
+    .el-dialog__title {
+      color: #303133 !important;
+    }
+
+    .el-drawer__body,
+    .el-dialog__body {
+      color: #303133 !important;
+      background: #ffffff !important;
+    }
+
+    .el-form-item__label {
+      color: #606266 !important;
+    }
+  }
+
+  /* 健康评估页 */
+  .health-assess-page {
+    --health-card-border: var(--primary-color, #008080);
+    --health-title-color: var(--primary-color, #008080);
+    --health-sub-label-color: var(--primary-color, #008080);
+    --health-sub-score-color: var(--primary-color, #008080);
+
+    .searchbox {
+      color: #303133;
+
+      p {
+        color: #606266;
+      }
+    }
+
+    .basics {
+      background: #ffffff !important;
+      border-color: var(--health-card-border) !important;
+
+      .title {
+        border-bottom-color: var(--health-card-border) !important;
+
+        h4 {
+          color: var(--health-title-color) !important;
+        }
+
+        .mill {
+          color: #606266 !important;
+        }
+      }
+
+      .health li span:first-child,
+      .health li span:last-child {
+        color: var(--health-sub-score-color) !important;
+      }
+    }
+
+    .health-legend {
+      background: #ffffff !important;
+      border-color: #ebeef5 !important;
+      box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.08) !important;
+
+      .legend-title {
+        color: #303133 !important;
+      }
+
+      .legend-advice {
+        color: #606266 !important;
+      }
+    }
   }
 
   .analysis-event-drawer {
@@ -469,3 +910,35 @@ html:not([data-theme="tech-blue"]) {
     }
   }
 }
+
+/* 登录页:全主题统一浅色输入框(覆盖 tech-theme 全局深色 input) */
+.background-image .border {
+  .el-input__inner {
+    background-color: var(--login-input-bg, #ffffff) !important;
+    border-color: var(--login-input-border, #dcdfe6) !important;
+    color: var(--login-input-text, #606266) !important;
+  }
+
+  .el-input__inner::placeholder {
+    color: #c0c4cc !important;
+  }
+
+  .el-input__inner:focus {
+    border-color: var(--login-title-color, var(--primary-color, #008080)) !important;
+  }
+
+  input:-webkit-autofill,
+  input:-webkit-autofill:hover,
+  input:-webkit-autofill:focus,
+  input:-webkit-autofill:active {
+    -webkit-box-shadow: 0 0 0 1000px var(--login-input-bg, #ffffff) inset !important;
+    -webkit-text-fill-color: var(--login-input-text, #606266) !important;
+    caret-color: var(--login-input-text, #606266) !important;
+  }
+
+  .el-button--primary {
+    background-color: var(--login-title-color, var(--primary-color, #008080)) !important;
+    border-color: var(--login-title-color, var(--primary-color, #008080)) !important;
+    color: #ffffff !important;
+  }
+}

+ 238 - 19
src/styles/tech-theme.scss

@@ -1414,7 +1414,8 @@ a {
   }
 }
 
-/* ========== 自定义分析 / 图表配置页 ========== */
+/* ========== 自定义分析 / 图表配置页(仅科技蓝) ========== */
+html[data-theme="tech-blue"] {
 .custom-analysis-page,
 .drag-chart-page,
 .analysis-event-page,
@@ -1493,7 +1494,13 @@ a {
   }
 }
 
-/* ========== Checkbox / Radio ========== */
+.analysis-event-drawer {
+  .drawer-section-title {
+    color: #ffffff;
+  }
+}
+
+/* ========== Checkbox / Radio(仅科技蓝) ========== */
 .el-checkbox {
   color: #ffffff !important;
 }
@@ -1519,38 +1526,99 @@ a {
 .el-radio__input.is-checked + .el-radio__label {
   color: #ffffff !important;
 }
+}
 
-.analysis-event-drawer {
-  .drawer-section-title {
-    color: #ffffff;
+
+html[data-theme="tech-blue"] {
+  .transition-page {
+    .transition-collapse .el-collapse-item__header {
+      background: var(--transition-collapse-header-bg) !important;
+    }
+
+    .CPC {
+      color: #ffffff !important;
+
+      span {
+        color: var(--transition-badge-accent) !important;
+      }
+    }
+
+    .incoming-desc {
+      .el-descriptions__title,
+      .el-descriptions__content {
+        color: #ffffff !important;
+      }
+
+      .el-descriptions__label {
+        color: #b7dff5 !important;
+      }
+    }
+
+    .demo-table-expand label {
+      color: #b7dff5 !important;
+    }
+  }
+
+  .transition-drawer,
+  .transition-dialog {
+    .el-drawer__header > :first-child,
+    .el-dialog__title {
+      color: #ffffff !important;
+    }
+
+    .scrollable-list {
+      color: #ffffff;
+
+      li span {
+        color: #ffffff;
+      }
+    }
+
+    .scrollable-list::-webkit-scrollbar-track {
+      background: rgba(0, 16, 32, 0.6);
+    }
+
+    .scrollable-list::-webkit-scrollbar-thumb {
+      background: rgba(0, 170, 255, 0.35);
+    }
+
+    .scrollable-list::-webkit-scrollbar-thumb:hover {
+      background: rgba(0, 170, 255, 0.55);
+    }
   }
 }
 
-.transition-drawer,
-.transition-dialog {
-  .scrollable-list {
+/* ========== 故障诊断页 malfunction(仅科技蓝) ========== */
+html[data-theme="tech-blue"] {
+.malfunction-page {
+  .searchbox {
     color: #ffffff;
 
-    li span {
-      color: #ffffff;
+    p {
+      color: #b7dff5;
     }
   }
 
-  .scrollable-list::-webkit-scrollbar-track {
-    background: rgba(0, 16, 32, 0.6);
+  .el-tabs__item {
+    color: rgba(183, 223, 245, 0.75) !important;
+  }
+
+  .el-tabs__item.is-active {
+    color: #ffffff !important;
   }
 
-  .scrollable-list::-webkit-scrollbar-thumb {
-    background: rgba(0, 170, 255, 0.35);
+  .el-tabs__item:hover {
+    color: #ffffff !important;
   }
 
-  .scrollable-list::-webkit-scrollbar-thumb:hover {
-    background: rgba(0, 170, 255, 0.55);
+  .el-tabs__active-bar {
+    background-color: #00aaff !important;
+  }
+
+  .el-tabs__nav-wrap::after {
+    background-color: rgba(0, 170, 255, 0.25) !important;
   }
-}
 
-/* ========== 故障诊断页 malfunction ========== */
-.malfunction-page {
   .gear-container {
     .gear-header {
       background: rgba(0, 16, 32, 0.85) !important;
@@ -1659,4 +1727,155 @@ a {
   }
 }
 
+/* ========== 健康评估页(仅科技蓝) ========== */
+.health-assess-page {
+  --health-card-border: rgba(0, 170, 255, 0.45);
+  --health-title-color: #52c8f2;
+  --health-sub-label-color: #b7dff5;
+  --health-sub-score-color: #00aaff;
+
+  .searchbox {
+    color: #ffffff;
+
+    p {
+      color: #b7dff5;
+    }
+  }
+
+  .basics {
+    background: rgba(0, 16, 32, 0.85) !important;
+    border-color: var(--health-card-border) !important;
+
+    .title {
+      border-bottom-color: var(--health-card-border) !important;
+
+      h4 {
+        color: var(--health-title-color) !important;
+      }
+
+      .mill {
+        color: rgba(183, 223, 245, 0.75) !important;
+      }
+    }
+
+    .health li span:first-child {
+      color: var(--health-sub-label-color) !important;
+    }
+
+    .health li span:last-child {
+      color: var(--health-sub-score-color) !important;
+    }
+  }
+
+  .health-legend {
+    background: rgba(0, 16, 32, 0.85) !important;
+    border-color: var(--panel-border) !important;
+    box-shadow: none !important;
+
+    .legend-title {
+      color: #ffffff !important;
+    }
+
+    .legend-advice {
+      color: #b7dff5 !important;
+    }
+
+    .legend-item + .legend-item::before {
+      background: rgba(0, 170, 255, 0.25) !important;
+    }
+  }
+}
+}
+
+/* 科技蓝业务页:浏览器自动填充与深色 input 一致 */
+html[data-theme="tech-blue"] {
+  input:-webkit-autofill,
+  input:-webkit-autofill:hover,
+  input:-webkit-autofill:focus,
+  input:-webkit-autofill:active {
+    -webkit-box-shadow: 0 0 0 1000px var(--input-bg, #000c17) inset !important;
+    -webkit-text-fill-color: var(--text-cyan, #b7dff5) !important;
+    caret-color: var(--text-cyan, #b7dff5);
+  }
+}
+
+/* ========== 登录页(仅科技蓝) ========== */
+html[data-theme="tech-blue"] {
+  .background-image .border {
+    background: var(--login-panel-bg, #ffffff) !important;
+    border-color: var(--login-panel-border, #ebeef5) !important;
+    box-shadow: var(--login-panel-shadow, 0 2px 12px rgba(0, 0, 0, 0.1)) !important;
+
+    .leftLogin h1 {
+      color: var(--login-title-color, var(--primary-color, #008080)) !important;
+    }
+
+    .leftLogin .el-divider--horizontal {
+      background: var(--login-title-color, var(--primary-color, #008080)) !important;
+    }
+
+    .el-input__inner {
+      background-color: var(--login-input-bg, #ffffff) !important;
+      border-color: var(--login-input-border, #dcdfe6) !important;
+      color: var(--login-input-text, #606266) !important;
+    }
+
+    .el-input__inner::placeholder {
+      color: #c0c4cc !important;
+    }
+
+    .el-input__inner:focus {
+      border-color: var(--login-title-color, var(--primary-color, #008080)) !important;
+    }
+
+    input:-webkit-autofill,
+    input:-webkit-autofill:hover,
+    input:-webkit-autofill:focus,
+    input:-webkit-autofill:active {
+      -webkit-box-shadow: 0 0 0 1000px var(--login-input-bg, #ffffff) inset !important;
+      -webkit-text-fill-color: var(--login-input-text, #606266) !important;
+      caret-color: var(--login-input-text, #606266) !important;
+    }
+
+    .el-button--primary {
+      background-color: var(--login-title-color, var(--primary-color, #008080)) !important;
+      border-color: var(--login-title-color, var(--primary-color, #008080)) !important;
+      color: #ffffff !important;
+    }
+  }
+}
+
+/* ========== 首页驾驶舱 map-ditu(仅科技蓝) ========== */
+html[data-theme="tech-blue"] {
+  .map-ditu {
+    #Tabtab.el-table,
+    #Tabtab {
+      background-color: transparent !important;
+      color: var(--text-cyan, #b7dff5) !important;
+    }
+
+    #Tabtab .el-table__body td.el-table__cell {
+      background-color: var(--cockpit-table-row-bg) !important;
+      color: var(--text-cyan, #b7dff5) !important;
+      border-bottom-color: var(--table-border) !important;
+    }
+
+    #Tabtab .el-table__body tr:nth-child(even) td.el-table__cell {
+      background-color: var(--cockpit-table-row-alt-bg) !important;
+    }
+
+    .ledata .el-input__inner {
+      background-color: var(--input-bg) !important;
+      border-color: var(--input-border) !important;
+      color: var(--text-cyan) !important;
+    }
+
+    .backbone .el-date-editor .el-input__inner {
+      background-color: var(--input-bg) !important;
+      border-color: var(--input-border) !important;
+      color: var(--text-cyan) !important;
+    }
+  }
+}
+
 }

+ 2 - 1
src/themes/blue.scss

@@ -14,7 +14,8 @@ $bgopacity-color: rgba(0, 187, 212, 0.145);
   --panel-bg: #ffffff;
   --input-bg: #ffffff;
   --input-border: #dcdfe6;
-  --table-header-bg: #2f5aa0;
+  --table-header-bg: #{$primary-color};
+  --success-color: #{$primary-color};
   --table-header-text: #ffffff;
   --table-row-bg: #ffffff;
   --table-cell-text: #606266;

+ 2 - 2
src/themes/dark.scss

@@ -14,9 +14,9 @@ $bgopacity-color: #607d8b31;
   --panel-bg: #ffffff;
   --input-bg: #ffffff;
   --input-border: #dcdfe6;
-  --table-header-bg: #607d8b;
+  --table-header-bg: #{$primary-color};
   --table-header-text: #ffffff;
   --table-row-bg: #ffffff;
   --table-cell-text: #606266;
-  --primary-color: #607d8b;
+  --success-color: #{$primary-color};
 }

+ 6 - 5
src/themes/green.scss

@@ -1,7 +1,8 @@
-$primary-color: #090a0f;
-$background-color: #090a0f;
+$primary-color: #008080;
+$background-color: #008080;
 $text-color: #ffffff;
-$bgopacity-color: #00968730;
+$bgopacity-color: rgba(0, 128, 128, 0.12);
+
 :root {
   --primary-color: #{$primary-color};
   --background-color: #{$background-color};
@@ -14,9 +15,9 @@ $bgopacity-color: #00968730;
   --panel-bg: #ffffff;
   --input-bg: #ffffff;
   --input-border: #dcdfe6;
-  --table-header-bg: #2f8f62;
+  --table-header-bg: #{$primary-color};
   --table-header-text: #ffffff;
   --table-row-bg: #ffffff;
   --table-cell-text: #606266;
-  --primary-color: #008080;
+  --success-color: #{$primary-color};
 }

+ 2 - 1
src/themes/light.scss

@@ -15,7 +15,8 @@ $bgopacity-color: #82780c27;
   --panel-bg: #ffffff;
   --input-bg: #ffffff;
   --input-border: #dcdfe6;
-  --table-header-bg: #9c9a3f;
+  --table-header-bg: #{$primary-color};
+  --success-color: #{$primary-color};
   --table-header-text: #ffffff;
   --table-row-bg: #ffffff;
   --table-cell-text: #606266;

+ 40 - 0
src/themes/tech-blue.scss

@@ -74,4 +74,44 @@ $bgopacity-color: rgba(0, 170, 255, 0.12);
   --drag-chart-tab-active-text: #ffffff;
   --drag-chart-divider: rgba(0, 170, 255, 0.25);
   --drag-chart-tree-hover: rgba(24, 144, 255, 0.12);
+  /* 首页驾驶舱地图浮层 */
+  --cockpit-panel-bg: rgba(0, 21, 41, 0.88);
+  --cockpit-panel-inner-bg: rgba(0, 42, 92, 0.82);
+  --cockpit-panel-inner-light: rgba(0, 42, 92, 0.62);
+  --cockpit-table-header-bg: #001a33;
+  --cockpit-table-track-bg: #000c17;
+  --cockpit-table-row-bg: rgba(0, 26, 51, 0.72);
+  --cockpit-table-row-alt-bg: rgba(0, 16, 32, 0.85);
+  --cockpit-accent-color: #00aaff;
+  /* 地图悬停信息框 */
+  --map-hover-header-bg: #001529;
+  --map-hover-header-text: #ffffff;
+  --map-hover-body-bg: rgba(0, 21, 41, 0.95);
+  --map-hover-text: #b7dff5;
+  --map-hover-label-text: rgba(183, 223, 245, 0.75);
+  /* 登录页:保持白卡片 + 浅色输入框,与业务浅色主题一致 */
+  --login-panel-bg: #ffffff;
+  --login-panel-border: #ebeef5;
+  --login-panel-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
+  --login-title-color: #008080;
+  --login-input-bg: #ffffff;
+  --login-input-border: #dcdfe6;
+  --login-input-text: #606266;
+  /* 导入数据页 */
+  --transition-page-bg: #000c17;
+  --transition-page-text: #ffffff;
+  --transition-collapse-header-bg: linear-gradient(90deg, #001529 0%, #002a5c 100%);
+  --transition-collapse-header-text: #ffffff;
+  --transition-collapse-body-bg: transparent;
+  --transition-label-color: #b7dff5;
+  --transition-border-color: rgba(0, 170, 255, 0.35);
+  --transition-badge-border: rgba(0, 170, 255, 0.45);
+  --transition-badge-bg: rgba(0, 170, 255, 0.12);
+  --transition-badge-bg-hover: rgba(0, 170, 255, 0.22);
+  --transition-badge-accent: #00aaff;
+  --transition-card-bg: rgba(0, 16, 32, 0.6);
+  --transition-card-hover-bg: rgba(0, 170, 255, 0.25);
+  --transition-scrollbar-track: rgba(0, 16, 32, 0.6);
+  --transition-scrollbar-thumb: rgba(0, 170, 255, 0.35);
+  --transition-scrollbar-thumb-hover: rgba(0, 170, 255, 0.55);
 }

+ 195 - 109
src/views/admin/cockpitManage/Index.vue

@@ -1,89 +1,75 @@
 <template>
-  <div class="cockpit-dashboard-page map-ditu">
-    <Tmap
-      ref="map"
-      class="cockpit-dashboard__map"
-      :maplist="maplist"
-      @feature-click="featureClick"
-    />
-
-    <div class="cockpit-dashboard__overlay">
-      <!-- 左侧:统计面板始终显示;其余面板由 switch 控制 -->
-      <aside class="cockpit-dashboard__left">
-        <section
-          class="cockpit-panel cockpit-panel--stats cockpit-panel--compact"
+  <div class="map-ditu">
+    <Tmap ref="map" :maplist="maplist" @feature-click="featureClick"></Tmap>
+    <div class="statistics">
+      <div class="ledata">
+        <selecttree
+          placeholder="请选择所属公司"
+          :list="parentOpt"
+          type="1"
+          v-model="companyCode"
+          @change="parentChange"
+          :defaultParentProps="{
+            children: 'children',
+            label: 'companyName',
+            value: 'codeNumber',
+          }"
         >
-          <selecttree
-            placeholder="请选择所属公司"
-            :list="parentOpt"
-            type="1"
-            v-model="companyCode"
-            @change="parentChange"
-            :defaultParentProps="{
-              children: 'children',
-              label: 'companyName',
-              value: 'codeNumber',
-            }"
-          />
-          <p class="cockpit-stats__row">
-            <span class="SpText">已接入风场数:</span>
-            <span>{{ totalList?.fieldSumNumber || 0 }} 座</span>
-          </p>
-          <p class="cockpit-stats__row">
-            <span class="SpText">已接入风机数:</span>
-            <span>{{ totalList?.engineGroupNumber || 0 }} 台</span>
-          </p>
-
-          <div class="cockpit-stats__switch">
-            <el-switch
-              v-model="value1"
-              active-text="显示"
-              inactive-text="隐藏"
-              @change="handleSwitchChange"
-            />
-          </div>
-        </section>
-
-        <template v-if="ShowRi">
-          <section class="cockpit-panel cockpit-panel--analysis-history">
-            <Rightdata
-              panel="analysis-history"
-              :maplistArr="maplistArr"
-              :defaultdata="defaultdata"
-            />
-          </section>
-
-          <section
-            class="cockpit-panel cockpit-panel--task cockpit-panel--compact"
-            v-hasPermi="['home:performance:performanceData']"
-          >
-            <Leftdata panel="task" />
-          </section>
-        </template>
-      </aside>
-
-      <div v-show="ShowRi" class="cockpit-dashboard__center-spacer" />
+        </selecttree>
 
-      <!-- 右侧:健康 / 健康数据与业务 Tab -->
-      <aside
-        v-show="ShowRi"
-        class="cockpit-dashboard__right"
-        v-hasPermi="['home:performance:performanceData']"
-      >
-        <section class="cockpit-panel cockpit-panel--health">
-          <CockpitHealthPanel
-            :maplistArr="maplistArr"
-            :defaultdata="defaultdata"
-          />
-        </section>
-
-        <section class="cockpit-panel cockpit-panel--inbound">
-          <Leftdata panel="inbound" />
-        </section>
-      </aside>
+        <p>
+          <span class="SpText">已接入风场数:</span>
+          {{ totalList?.fieldSumNumber ? totalList.fieldSumNumber : 0 }}
+          座
+        </p>
+        <!-- <p>
+          <span class="SpText">已完成分析风场:</span>
+          {{
+            totalList?.analysisFinishNumber ? totalList.analysisFinishNumber : 0
+          }}
+          个
+        </p> -->
+        <!-- <p>
+          <span class="SpText">未完成分析风场:</span>
+          {{
+            totalList?.analysisUnFinishedNumber
+              ? totalList.analysisUnFinishedNumber
+              : 0
+          }}
+          个
+        </p> -->
+        <p>
+          <span class="SpText">已接入风机数:</span>
+          {{ totalList?.engineGroupNumber ? totalList.engineGroupNumber : 0 }}
+          台
+        </p>
+        <!-- <p>
+          <span class="SpText">风场状态:</span>
+          <span class="red"></span>
+          <span class="yellow"></span>
+          <span class="green"></span>
+        </p> -->
+        <el-switch
+          v-model="value1"
+          active-text="显示"
+          inactive-text="隐藏"
+          @change="handleSwitchChange"
+        >
+        </el-switch>
+      </div>
+      <leftdata v-show="ShowRi" class="task"></leftdata>
     </div>
 
-    <router-view />
+    <Rightdata
+      v-show="ShowRi"
+      v-hasPermi="['home:performance:performanceData']"
+      ref="childRef"
+      :maplistArr="maplistArr"
+      :defaultdata="defaultdata"
+      class="ridata"
+    >
+    </Rightdata>
+    <router-view></router-view>
   </div>
 </template>
 
@@ -96,7 +82,6 @@ import {
 import Tmap from "@/components/map";
 import Rightdata from "./component/rightdata.vue";
 import Leftdata from "./component/leftdata.vue";
-import CockpitHealthPanel from "./component/CockpitHealthPanel.vue";
 
 export default {
   name: "Index",
@@ -105,12 +90,15 @@ export default {
     Rightdata,
     selecttree,
     Leftdata,
-    CockpitHealthPanel,
   },
   data() {
     return {
       ShowRi: true,
+      treeval: "",
       value1: true,
+      treeval: "", // 绑定的输入框值
+      showTree: false, // 控制树列表显示
+      treeData: [],
       maplist: [],
       maplistArr: {},
       totalList: [],
@@ -124,30 +112,34 @@ export default {
     this.GETtotal();
   },
   mounted() {
-    this.restoreMapMarkers();
-  },
-  activated() {
-    this.restoreMapMarkers();
+    //模拟地图上的点位
+    const data = this.maplist;
+    // data.forEach((element) => {
+    //   console.log(element);
+    //   // this.$refs.map.addMarker({ point: [116.40740,39.90420], val: "1" });
+    // });
   },
   methods: {
-    restoreMapMarkers() {
-      if (!this.maplistArr || !Object.keys(this.maplistArr).length) return;
-      this.$nextTick(() => {
-        this.parentChange(this.maplistArr);
-      });
-    },
+    // 获取总数
     GETtotal() {
       getCompanyFieldNumberVo().then((res) => {
         this.totalList = res.data;
       });
     },
+    // 获取企业数
     async GETtree() {
       const res = await getSysOrganizationAuthTreeByRoleId();
-      const processedData = this.processTreeData(res.data);
+      const treedata = res.data;
+      const processedData = this.processTreeData(treedata);
       this.parentOpt = processedData;
       this.defaultdata = res.data[0];
       this.parentChange(this.defaultdata);
+      // const firstLayer = this.findFirstFieldLayer(processedData);
+      // if (firstLayer) {
+      //   this.parentChange(  this.defaultdata);
+      // }
     },
+    //过滤数据
     processTreeData(treeData) {
       const processedData = [];
       function processNode(node) {
@@ -155,7 +147,9 @@ export default {
           node.companyName = node.fieldName;
         }
         if (node.children && node.children.length > 0) {
-          node.children.forEach((child) => processNode(child));
+          node.children.forEach((child) => {
+            processNode(child);
+          });
         }
       }
       treeData.forEach((root) => {
@@ -164,52 +158,73 @@ export default {
       });
       return processedData;
     },
+    handleTreeData() {
+      this.treeData = this.processTreeData(this.treeData);
+    },
     parseCoordinates(input) {
       if (input && typeof input === "string") {
         return input.split(",").map(Number);
       }
+      // debugger;
       return [];
     },
     parentChange(data) {
+      //data为当前选中对象
+      this.$refs.map.clearMarkers();
       this.maplist = data;
       this.maplistArr = data;
-      const mapRef = this.$refs.map;
-      if (!mapRef || typeof mapRef.clearMarkers !== "function") {
-        return;
-      }
-      mapRef.clearMarkers();
       if (data.codeType === "field") {
         if (this.parseCoordinates(data.longitudeAndLatitudeString).length > 0) {
-          mapRef.addMarker({
+          this.$refs.map.addMarker({
             point: this.parseCoordinates(data.longitudeAndLatitudeString),
             val: data.analysisState,
             ...data,
           });
           return;
         }
-        mapRef.clearMarkers();
+        this.$refs.map.clearMarkers();
       } else {
-        (data.children || []).forEach((element) => {
+        const dataMapList = data.children;
+        dataMapList.forEach((element) => {
           if (
             this.parseCoordinates(element.longitudeAndLatitudeString).length >
               0 &&
             element.codeType === "field"
           ) {
-            mapRef.addMarker({
+            this.$refs.map.addMarker({
               point: this.parseCoordinates(element.longitudeAndLatitudeString),
               val: element.analysisState,
               ...element,
             });
+            return;
           }
+          this.$refs.map.clearMarkers();
         });
       }
     },
+    findFirstFieldLayer(data) {
+      for (const item of data) {
+        if (item.codeType === "field") {
+          return item;
+        }
+        if (item.children && item.children.length > 0) {
+          const childResult = this.findFirstFieldLayer(item.children);
+          if (childResult) {
+            return childResult;
+          }
+        }
+      }
+      return null;
+    },
     featureClick(data) {
       const val = data.val;
       if (val === "-1" || val === -1 || val === 10) {
         this.$message.error("当前风场未完成分析");
       } else if (val === "0" || val === 0) {
-        this.$message({ message: "当前风场正在分析中", type: "warning" });
+        this.$message({
+          message: "当前风场正在分析中",
+          type: "warning",
+        });
       } else if (val === "1" || val === 1 || val === "30" || val === 30) {
         this.$router.push({
           path: "cockpitManage/electronic-map",
@@ -220,13 +235,84 @@ export default {
         });
       }
     },
-    handleSwitchChange(val) {
-      this.ShowRi = val;
+    handleSwitchChange() {
+      this.ShowRi = !this.ShowRi;
     },
   },
 };
 </script>
 
-<style lang="scss">
-@import "./cockpit-dashboard.scss";
+<style lang="scss" scoped>
+.map-ditu {
+  //  min-width: 86.9vw;
+  //  max-width: 94.9vw;
+  height: calc(100vh - 60px);
+  // height: 100vh;
+  position: relative;
+}
+
+.statistics {
+  position: absolute;
+  top: 20px; /* 距离页面顶部20px */
+  left: 60px;
+  display: grid;
+  grid-template-rows: auto auto; /* 为 ledata 和 task 分配行 */
+  grid-gap: 20px; /* 在 ledata 和 task 之间设置间距 */
+
+  .ledata {
+    font-size: 14px;
+    width: 300px;
+    background: var(--cockpit-panel-bg, rgba(0, 128, 128, 0.8));
+    padding: 10px;
+    color: #fff;
+    border-radius: 5px;
+    p {
+      line-height: 24px;
+
+      .SpText {
+        display: inline-block;
+        width: 120px;
+        text-align: right;
+      }
+
+      .red,
+      .yellow,
+      .green {
+        display: inline-block;
+        width: 30px;
+        height: 12px;
+        margin-right: 5px;
+      }
+
+      .red {
+        background-color: #e16757;
+      }
+
+      .yellow {
+        background-color: #eecb5f;
+      }
+
+      .green {
+        background-color: #7ecf51;
+      }
+    }
+  }
+
+  .task {
+    // background: #f4f4f4;
+    // padding: 10px;
+    color: #333;
+    border-radius: 5px;
+  }
+}
+
+.ridata {
+  position: absolute;
+  top: 20px;
+  right: 20px;
+}
+
+::v-deep .el-switch__label.is-active {
+  color: #fff;
+}
 </style>

+ 0 - 1601
src/views/admin/cockpitManage/cockpit-dashboard.scss

@@ -1,1601 +0,0 @@
-/* 驾驶舱:布局 + 主题(全局,勿 scoped,以便作用于子组件) */
-.cockpit-dashboard-page {
-  --cockpit-th-height: 32px;
-  --cockpit-tr-height: 40px;
-  --cockpit-td-padding-x: 8px;
-  --cockpit-table-stripe-odd: #1a2a4f;
-  --cockpit-table-stripe-even: #0f1f3d;
-  --cockpit-table-visible-rows: 4;
-  --cockpit-table-body-h: calc(
-    var(--cockpit-tr-height) * var(--cockpit-table-visible-rows)
-  );
-  --cockpit-table-block-h: calc(
-    var(--cockpit-th-height) + var(--cockpit-table-body-h)
-  );
-  /* 健康 Tab:环图 + 表格标题 + 4 行表,避免固定过高留白 */
-  --cockpit-health-chart-h: 150px;
-  --cockpit-health-abnormal-kpi-h: 76px;
-  --cockpit-health-abnormal-pane-h: calc(
-    32px + var(--cockpit-health-abnormal-kpi-h) + 12px + 34px +
-      var(--cockpit-table-block-h)
-  );
-  --cockpit-health-pane-h: max(
-    calc(
-      32px + var(--cockpit-health-chart-h) + 8px + 30px +
-        var(--cockpit-table-block-h)
-    ),
-    var(--cockpit-health-abnormal-pane-h)
-  );
-  /* 入库 Tab:副标题 + 表头 + 4 行表(缩小底部冗余预留) */
-  --cockpit-inbound-pane-h: calc(32px + var(--cockpit-table-block-h));
-
-  position: relative;
-  width: 100%;
-  height: calc(100vh - 60px);
-  overflow: hidden;
-  background: var(--cockpit-page-bg, #f0f2f5);
-  box-sizing: border-box;
-
-  *,
-  *::before,
-  *::after {
-    box-sizing: border-box;
-  }
-
-  .cockpit-dashboard__map {
-    position: absolute;
-    inset: 0;
-    z-index: 0;
-  }
-
-  .cockpit-dashboard__overlay {
-    position: relative;
-    z-index: 2;
-    display: flex;
-    align-items: flex-start;
-    justify-content: space-between;
-    height: 100%;
-    padding: 10px 12px;
-    gap: 10px;
-    pointer-events: none;
-  }
-
-  .cockpit-dashboard__left,
-  .cockpit-dashboard__right {
-    flex: 0 0 308px;
-    width: 308px;
-    max-height: 100%;
-    overflow-x: hidden;
-    overflow-y: auto;
-    display: flex;
-    flex-direction: column;
-    gap: 10px;
-    pointer-events: auto;
-    scrollbar-width: thin;
-    scrollbar-color: rgba(0, 140, 200, 0.45) transparent;
-  }
-
-  .cockpit-dashboard__left::-webkit-scrollbar,
-  .cockpit-dashboard__right::-webkit-scrollbar {
-    width: 4px;
-  }
-
-  .cockpit-dashboard__left::-webkit-scrollbar-thumb,
-  .cockpit-dashboard__right::-webkit-scrollbar-thumb {
-    border-radius: 4px;
-    background: rgba(0, 150, 220, 0.45);
-  }
-
-  .cockpit-dashboard__center-spacer {
-    flex: 1 1 auto;
-    min-width: 0;
-    pointer-events: none;
-  }
-
-  /* —— 统一面板容器 —— */
-  .cockpit-panel {
-    flex-shrink: 0;
-    border-radius: var(--cockpit-panel-radius, 8px);
-    padding: 10px 12px 12px;
-    background: var(--cockpit-panel-bg, #ffffff);
-    border: 1px solid var(--cockpit-panel-border, #ebeef5);
-    color: var(--cockpit-panel-text, #303133);
-    box-shadow: var(--cockpit-panel-shadow, 0 2px 8px rgba(0, 0, 0, 0.06));
-
-    &::after {
-      display: none !important;
-      content: none !important;
-    }
-  }
-
-  .cockpit-panel--compact {
-    padding: 10px 12px;
-  }
-
-  /* 面板内标题(含子组件 h3) */
-  .cockpit-panel__title,
-  .cockpit-panel h3,
-  .cockpit-panel .backbone h3,
-  .cockpit-panel .BOXYI > h3,
-  .cockpit-panel .centeredh3 {
-    margin: 0 0 10px;
-    padding: 0 0 8px;
-    font-size: 14px;
-    font-weight: 600;
-    line-height: 1.4;
-    color: var(--cockpit-panel-title, #303133);
-    border-bottom: 1px solid var(--cockpit-panel-divider, #ebeef5);
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-    width: 100%;
-  }
-
-  .cockpit-panel .centeredh3 span {
-    font-size: 12px;
-    font-weight: 400;
-    color: var(--cockpit-accent, var(--primary-color, #82780c));
-  }
-
-  .cockpit-panel--stats {
-    .cockpit-stats__row {
-      display: flex;
-      align-items: center;
-      justify-content: space-between;
-      font-size: 13px;
-      line-height: 28px;
-      color: var(--cockpit-panel-text, #303133);
-
-      .SpText {
-        color: var(--cockpit-panel-muted, #909399);
-      }
-    }
-
-    .cockpit-stats__switch {
-      margin-top: 6px;
-      display: flex;
-      justify-content: flex-end;
-    }
-
-    .el-select,
-    .el-input__inner {
-      width: 100%;
-    }
-  }
-
-  /* 子组件根:透明,由面板承载外观 */
-  .cockpit-panel .backbone,
-  .cockpit-panel .BOXYI,
-  .cockpit-panel .BOX {
-    width: 100% !important;
-    background: transparent !important;
-    padding: 0 !important;
-    margin: 0 !important;
-    border: none !important;
-    border-radius: 0 !important;
-    color: inherit !important;
-    box-shadow: none !important;
-  }
-
-  .cockpit-panel--data-tabs .cockpit-inbound-wrap {
-    margin-top: 12px;
-    padding-top: 12px;
-    border-top: 1px solid var(--cockpit-panel-divider, #ebeef5);
-  }
-
-  /* 表头条(与 el-table thead 同高) */
-  .cockpit-panel .titleJQ,
-  .cockpit-panel .titleYC,
-  .cockpit-panel .cockpit-inbound-table-head {
-    margin: 0 0 6px;
-    padding: 0 8px;
-    min-height: var(--cockpit-th-height);
-    height: var(--cockpit-th-height);
-    line-height: var(--cockpit-th-height);
-    font-size: 12px;
-    border-radius: 2px;
-    background: var(--cockpit-table-header-bg, #f5f7fa) !important;
-    color: var(--cockpit-panel-muted, #909399) !important;
-    box-sizing: border-box;
-  }
-
-  .cockpit-panel .cockpit-inbound-table-head {
-    line-height: normal;
-    display: grid;
-    align-items: center;
-  }
-
-  /* el-table 表头:含 has-gutter 时高度一致 */
-  .cockpit-panel .el-table thead th.el-table__cell,
-  .cockpit-panel .el-table thead.has-gutter th.el-table__cell,
-  .cockpit-panel .el-table thead th.gutter,
-  .cockpit-panel .el-table thead.has-gutter th.gutter {
-    height: var(--cockpit-th-height) !important;
-    padding: 0 4px !important;
-    box-sizing: border-box;
-  }
-
-  .cockpit-panel .el-table thead.has-gutter tr {
-    height: var(--cockpit-th-height) !important;
-  }
-
-  .cockpit-panel .el-table thead th.gutter,
-  .cockpit-panel .el-table thead.has-gutter th.gutter {
-    display: table-cell !important;
-    width: 6px !important;
-    padding: 0 !important;
-    vertical-align: middle;
-  }
-
-  .cockpit-panel .el-table thead th .cell {
-    line-height: var(--cockpit-th-height);
-    height: var(--cockpit-th-height);
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    padding: 0 4px;
-    box-sizing: border-box;
-  }
-
-  .cockpit-panel .el-table thead th.is-left .cell,
-  .cockpit-panel .el-table thead th.cockpit-health-col-name .cell {
-    justify-content: flex-start;
-  }
-
-  /* 表体:固定 4 行高度,两表一致 */
-  .cockpit-panel .cockpit-table-block .el-table__body-wrapper {
-    max-height: var(--cockpit-table-body-h) !important;
-    min-height: var(--cockpit-table-body-h) !important;
-    height: var(--cockpit-table-body-h) !important;
-    overflow-y: auto !important;
-  }
-
-  /* 自动滚动列表:隐藏滚动条,保留 programmatic scroll */
-  .cockpit-panel .cockpit-table-block .el-table__body-wrapper,
-  .cockpit-panel #Tabtab .el-table__body-wrapper,
-  .cockpit-panel .cockpit-unified-table .el-table__body-wrapper {
-    scrollbar-width: none !important;
-    -ms-overflow-style: none !important;
-  }
-
-  .cockpit-panel
-    .cockpit-table-block
-    .el-table__body-wrapper::-webkit-scrollbar,
-  .cockpit-panel #Tabtab .el-table__body-wrapper::-webkit-scrollbar,
-  .cockpit-panel
-    .cockpit-unified-table
-    .el-table__body-wrapper::-webkit-scrollbar {
-    width: 0 !important;
-    height: 0 !important;
-    display: none !important;
-  }
-
-  .cockpit-panel .cockpit-table-block {
-    min-height: var(--cockpit-table-block-h);
-  }
-
-  .cockpit-panel .cockpit-table-block > .titleYC,
-  .cockpit-panel .cockpit-table-block > .cockpit-inbound-table-head {
-    margin-bottom: 0 !important;
-  }
-
-  .cockpit-panel .cockpit-table-block .cockpit-tabroll-table {
-    flex: 1;
-    min-height: 0;
-  }
-
-  .cockpit-panel .cockpit-table-block .el-table__body tr {
-    height: var(--cockpit-tr-height) !important;
-  }
-
-  .cockpit-panel .cockpit-table-block .el-table__body td.el-table__cell {
-    height: var(--cockpit-tr-height) !important;
-    padding: 0 !important;
-    box-sizing: border-box;
-    border-bottom: none !important;
-  }
-
-  .cockpit-inbound-table-wrap.cockpit-table-block {
-    display: flex;
-    flex-direction: column;
-  }
-
-  .cockpit-panel .cockpit-table-block .el-table__body td.el-table__cell .cell {
-    line-height: var(--cockpit-tr-height);
-    height: var(--cockpit-tr-height);
-    display: flex;
-    align-items: center;
-    padding: 0 var(--cockpit-td-padding-x) !important;
-    box-sizing: border-box;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    white-space: nowrap;
-  }
-
-  /* 滚动列表表格 */
-  .cockpit-panel #Tabtab.el-table,
-  .cockpit-panel #Tabtab .el-table__cell {
-    background: transparent !important;
-    color: var(--cockpit-panel-text, #606266) !important;
-    font-size: 12px;
-    border-color: var(--cockpit-panel-divider, #ebeef5) !important;
-  }
-
-  .cockpit-panel #Tabtab th.el-table__cell {
-    background: var(--cockpit-table-header-bg, #f5f7fa) !important;
-    color: var(--cockpit-panel-muted, #909399) !important;
-  }
-
-  .cockpit-panel #Tabtab .el-table__row:nth-child(2n) td {
-    background: var(--cockpit-table-stripe, #fafafa) !important;
-  }
-
-  .cockpit-panel .cockpit-analysis-chart {
-    width: 100%;
-    height: 160px;
-  }
-
-  .cockpit-panel--analysis-history .cockpit-analysis-chart {
-    height: 132px;
-    margin-top: 4px;
-  }
-
-  .cockpit-panel--analysis-history .cockpit-history-block {
-    margin-top: 10px;
-    padding-top: 10px;
-    border-top: 1px solid var(--cockpit-panel-divider, #ebeef5);
-  }
-
-  .cockpit-panel--analysis-history .cockpit-section-title {
-    margin-bottom: 8px;
-  }
-
-  .cockpit-scroll-table {
-    border-radius: 2px;
-    overflow: hidden;
-  }
-
-  /* 统一列表表(历史 / 健康 / 入库 / 异常) */
-  .cockpit-unified-table {
-    background: transparent;
-  }
-
-  .cockpit-unified-table-head {
-    display: grid !important;
-    align-items: center;
-    margin: 0 !important;
-    padding: 0 var(--cockpit-td-padding-x) !important;
-    min-height: var(--cockpit-th-height);
-    height: var(--cockpit-th-height);
-    line-height: var(--cockpit-th-height);
-    font-size: 12px;
-    font-weight: 500;
-    border: none !important;
-    border-radius: 0;
-    box-sizing: border-box;
-
-    span {
-      margin: 0 !important;
-      padding: 0;
-      text-align: center;
-      overflow: hidden;
-      text-overflow: ellipsis;
-      white-space: nowrap;
-    }
-
-    span:first-child {
-      text-align: left !important;
-    }
-
-    &--history {
-      grid-template-columns: 28% 38% 34%;
-    }
-
-    &--health {
-      grid-template-columns: 38% 15% 15% 15% 17%;
-    }
-
-    &--inbound-import {
-      grid-template-columns: 42% 58%;
-    }
-
-    &--inbound-two,
-    &--abnormal-two {
-      grid-template-columns: 50% 50%;
-    }
-  }
-
-  .cockpit-unified-table-head--inbound-import .cockpit-inbound-col-data {
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-    gap: 8px;
-    padding-right: 0;
-  }
-
-  .cockpit-unified-table .cockpit-tabroll-table,
-  .cockpit-unified-table #Tabtab {
-    width: 100% !important;
-  }
-
-  .cockpit-unified-table #Tabtab.el-table,
-  .cockpit-unified-table #Tabtab::before {
-    background: transparent !important;
-  }
-
-  .cockpit-unified-table #Tabtab .el-table__body,
-  .cockpit-unified-table #Tabtab .el-table__body-wrapper table {
-    width: 100% !important;
-    table-layout: fixed !important;
-  }
-
-  .cockpit-unified-table #Tabtab .el-table__body td.el-table__cell {
-    border: none !important;
-    color: #ffffff;
-    vertical-align: middle;
-  }
-
-  .cockpit-unified-table
-    #Tabtab
-    .el-table__body
-    tr:nth-child(odd)
-    td.el-table__cell {
-    background: var(--cockpit-table-stripe-odd) !important;
-    color: #ffffff !important;
-  }
-
-  .cockpit-unified-table
-    #Tabtab
-    .el-table__body
-    tr:nth-child(even)
-    td.el-table__cell {
-    background: var(--cockpit-table-stripe-even) !important;
-    color: #ffffff !important;
-  }
-
-  .cockpit-unified-table #Tabtab .el-table__body tr:hover > td.el-table__cell {
-    background: #182544 !important; /* 稍微加深的蓝色 */
-    color: rgba(255, 255, 255, 0.9) !important;
-  }
-
-  .cockpit-unified-table #Tabtab .el-table__body td.el-table__cell .cell {
-    display: flex !important;
-    align-items: center !important;
-    width: 100%;
-    box-sizing: border-box;
-  }
-
-  /* 表体除第一列外居中 */
-  .cockpit-unified-table
-    #Tabtab
-    .el-table__body
-    tr
-    td.el-table__cell:not(:first-child)
-    .cell {
-    justify-content: center !important;
-    text-align: center !important;
-  }
-
-  .cockpit-unified-table
-    #Tabtab
-    .el-table__body
-    tr
-    td.el-table__cell:nth-child(n + 2)
-    .cell {
-    justify-content: center !important;
-    text-align: center !important;
-  }
-
-  /* 第一列数据强制左对齐 */
-  .cockpit-unified-table
-    #Tabtab
-    .el-table__body
-    td.el-table__cell:first-child
-    .cell,
-  .cockpit-unified-table #Tabtab .el-table__body tr td:first-child .cell {
-    justify-content: flex-start !important;
-    text-align: left !important;
-  }
-
-  /* 表头与表体列宽对齐 */
-  .cockpit-unified-table--history #Tabtab colgroup col:nth-child(1) {
-    width: 28% !important;
-  }
-
-  .cockpit-unified-table--history #Tabtab colgroup col:nth-child(2) {
-    width: 38% !important;
-  }
-
-  .cockpit-unified-table--history #Tabtab colgroup col:nth-child(3) {
-    width: 34% !important;
-  }
-
-  .cockpit-unified-table--health #Tabtab colgroup col:nth-child(1) {
-    width: 38% !important;
-  }
-
-  .cockpit-unified-table--health #Tabtab colgroup col:nth-child(2),
-  .cockpit-unified-table--health #Tabtab colgroup col:nth-child(3),
-  .cockpit-unified-table--health #Tabtab colgroup col:nth-child(4) {
-    width: 15% !important;
-  }
-
-  .cockpit-unified-table--health #Tabtab colgroup col:nth-child(5) {
-    width: 17% !important;
-  }
-
-  .cockpit-unified-table--inbound-import #Tabtab colgroup col:nth-child(1) {
-    width: 42% !important;
-  }
-
-  .cockpit-unified-table--inbound-import #Tabtab colgroup col:nth-child(2) {
-    width: 58% !important;
-  }
-
-  .cockpit-unified-table--inbound-two #Tabtab colgroup col:nth-child(1),
-  .cockpit-unified-table--abnormal-two #Tabtab colgroup col:nth-child(1) {
-    width: 50% !important;
-  }
-
-  .cockpit-unified-table--inbound-two #Tabtab colgroup col:nth-child(2),
-  .cockpit-unified-table--abnormal-two #Tabtab colgroup col:nth-child(2) {
-    width: 50% !important;
-  }
-
-  .cockpit-section-title {
-    margin: 0 0 8px;
-    padding: 0;
-    border-bottom: none;
-    font-size: 14px;
-    font-weight: 600;
-    line-height: 1.4;
-  }
-
-  .cockpit-panel--stats .cockpit-stats__row {
-    line-height: 26px;
-  }
-
-  .cockpit-panel--stats .cockpit-stats__switch {
-    margin-top: 4px;
-  }
-
-  /* 任务统计数字块 */
-  .cockpit-panel .BOXsan {
-    width: 100%;
-    display: flex;
-    justify-content: space-between;
-    gap: 8px;
-  }
-
-  .cockpit-panel .YC01,
-  .cockpit-panel .YC02,
-  .cockpit-panel .YC03 {
-    flex: 1;
-    min-width: 0;
-  }
-
-  /* Tab 统一样式 */
-  .cockpit-panel .el-tabs__header {
-    margin: 0 0 10px;
-  }
-
-  .cockpit-panel .el-tabs__nav-wrap::after {
-    background-color: var(--cockpit-panel-divider, #ebeef5);
-  }
-
-  .cockpit-panel .el-tabs__item {
-    height: 32px;
-    line-height: 32px;
-    font-size: 13px;
-    color: var(--cockpit-panel-muted, #909399);
-    padding: 0 14px;
-  }
-
-  .cockpit-panel .el-tabs__item.is-active {
-    color: var(--cockpit-accent, var(--primary-color, #82780c));
-    font-weight: 600;
-  }
-
-  .cockpit-panel .el-tabs__active-bar {
-    background-color: var(--cockpit-accent, var(--primary-color, #82780c));
-  }
-
-  /* 表单控件 */
-  .cockpit-panel .el-input__inner,
-  .cockpit-panel .el-range-editor.el-input__inner,
-  .cockpit-panel .el-range-input {
-    background-color: var(--cockpit-input-bg, #ffffff) !important;
-    border-color: var(--cockpit-input-border, #dcdfe6) !important;
-    color: var(--cockpit-panel-text, #606266) !important;
-  }
-
-  .cockpit-panel .el-date-editor .el-range-separator {
-    color: var(--cockpit-panel-muted, #909399) !important;
-  }
-
-  .cockpit-panel .el-switch__label {
-    color: var(--cockpit-panel-muted, #909399);
-  }
-
-  .cockpit-panel .el-switch__label.is-active {
-    color: var(--cockpit-accent, var(--primary-color, #82780c)) !important;
-  }
-
-  .cockpit-panel--health .cockpit-health-table__head {
-    border-bottom: none;
-    margin-bottom: 8px;
-    padding-bottom: 0;
-  }
-
-  .cockpit-inbound-panel {
-    width: 100%;
-  }
-
-  .cockpit-inbound-body {
-    position: relative;
-    height: var(--cockpit-inbound-pane-h);
-    min-height: var(--cockpit-inbound-pane-h);
-    overflow: hidden;
-  }
-
-  .cockpit-inbound-pane {
-    position: absolute;
-    inset: 0;
-    overflow: hidden;
-    display: flex;
-    flex-direction: column;
-  }
-
-  .cockpit-panel--inbound .cockpit-inbound-pane-header {
-    margin: 2px 0 6px;
-  }
-
-  .cockpit-panel--inbound .cockpit-inbound-subtitle {
-    margin: 0;
-  }
-
-  .cockpit-inbound-pane .cockpit-inbound-table-wrap {
-    flex: 1;
-    min-height: 0;
-    display: flex;
-    flex-direction: column;
-  }
-
-  .cockpit-inbound-pane .cockpit-tabroll-table {
-    flex: 1;
-    min-height: 0;
-  }
-  .cockpit-inbound-pane-header {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    .cockpit-inbound-col-data {
-      font-size: 12px;
-      color: var(--cockpit-panel-muted, #909399);
-      cursor: pointer;
-      &:hover {
-        color: var(--cockpit-accent, #2979ff) !important;
-      }
-    }
-  }
-
-  .cockpit-inbound-subtitle {
-    margin: 8px 0 10px;
-    font-size: 14px;
-    font-weight: 600;
-    line-height: 1.3;
-    color: var(--cockpit-panel-title, #303133);
-  }
-
-  .cockpit-inbound-table-wrap {
-    border-radius: 6px;
-    overflow: hidden;
-  }
-
-  .cockpit-inbound-table-head {
-    display: grid !important;
-    align-items: center;
-    margin: 0 !important;
-    padding: 0 10px !important;
-    min-height: var(--cockpit-th-height);
-    height: var(--cockpit-th-height);
-    line-height: normal;
-    width: 100%;
-    box-sizing: border-box;
-
-    span {
-      margin: 0 !important;
-      font-size: 12px;
-    }
-
-    &--import {
-      grid-template-columns: 42% 58%;
-    }
-
-    .cockpit-inbound-col-name {
-      text-align: left;
-      white-space: nowrap;
-      overflow: hidden;
-      text-overflow: ellipsis;
-    }
-
-    .cockpit-inbound-col-data {
-      display: flex;
-      align-items: center;
-      justify-content: space-between;
-      gap: 8px;
-      padding-left: 6px;
-      box-sizing: border-box;
-
-      > span:first-child {
-        flex: 1;
-        text-align: right;
-        white-space: nowrap;
-        overflow: hidden;
-        text-overflow: ellipsis;
-      }
-    }
-
-    &--two {
-      grid-template-columns: 42% 58%;
-    }
-
-    .cockpit-inbound-col-extra {
-      text-align: right;
-      padding-right: 4px;
-    }
-  }
-
-  .cockpit-inbound-more-link {
-    flex-shrink: 0;
-    color: var(--cockpit-accent, #2979ff) !important;
-    cursor: pointer;
-    text-align: right !important;
-  }
-
-  .cockpit-inbound-table-wrap .tabroll-wrap,
-  .cockpit-inbound-table-wrap #Tabtab,
-  .cockpit-inbound-table-wrap #Tabtab .el-table__body,
-  .cockpit-inbound-table-wrap #Tabtab .el-table__body-wrapper,
-  .cockpit-inbound-table-wrap #Tabtab table {
-    width: 100% !important;
-  }
-
-  .cockpit-inbound-table-wrap #Tabtab table {
-    table-layout: fixed !important;
-  }
-
-  .cockpit-inbound-table-wrap #Tabtab colgroup col:first-child {
-    width: 42% !important;
-  }
-
-  .cockpit-inbound-table-wrap #Tabtab colgroup col:last-child {
-    width: 58% !important;
-  }
-
-  .cockpit-panel--inbound .centeredh3 {
-    display: none;
-  }
-
-  .cockpit-health-table .el-table th.el-table__cell {
-    background: var(--cockpit-table-header-bg, #f5f7fa) !important;
-    color: var(--cockpit-panel-muted, #909399) !important;
-    font-size: 12px;
-  }
-
-  .cockpit-health-table .el-table td.el-table__cell {
-    background: transparent !important;
-    color: var(--cockpit-panel-text, #606266) !important;
-    font-size: 12px;
-  }
-}
-
-/* —— 科技蓝大屏(参考设计稿) —— */
-html[data-theme="tech-blue"] .cockpit-dashboard-page {
-  --cockpit-page-bg: #020a16;
-  --cockpit-panel-border: rgba(0, 90, 140, 0.72);
-  --cockpit-panel-divider: rgba(0, 120, 200, 0.22);
-  --cockpit-panel-text: #c8e8f8;
-  --cockpit-panel-title: #ffffff;
-  --cockpit-panel-muted: rgba(168, 210, 235, 0.72);
-  --cockpit-panel-radius: 8px;
-  --cockpit-table-header-bg: rgba(0, 36, 64, 0.92);
-  --cockpit-table-row-bg: rgba(0, 18, 36, 0.55);
-  --cockpit-table-row-bg-alt: rgba(0, 24, 46, 0.72);
-  --cockpit-input-bg: rgba(0, 16, 32, 0.92);
-  --cockpit-input-border: rgba(0, 140, 210, 0.45);
-  --cockpit-accent: #00c8ff;
-  --cockpit-status-ok: #7ecf51;
-  --cockpit-status-warn: #eecb5f;
-  --cockpit-status-danger: #e16757;
-  --cockpit-kpi-cyan: #5ce1ff;
-
-  background-color: #020a16;
-  background-image: radial-gradient(
-      ellipse 80% 55% at 50% 38%,
-      rgba(12, 40, 88, 0.45) 0%,
-      transparent 68%
-    ),
-    linear-gradient(rgba(255, 255, 255, 0.025) 1px, transparent 1px),
-    linear-gradient(90deg, rgba(255, 255, 255, 0.025) 1px, transparent 1px);
-  background-size: 100% 100%, 24px 24px, 24px 24px;
-
-  .cockpit-dashboard__map {
-    filter: saturate(1.12) contrast(1.08) brightness(0.9);
-  }
-
-  .cockpit-dashboard__map::before {
-    content: "";
-    position: absolute;
-    inset: 0;
-    pointer-events: none;
-    z-index: 1;
-    background: radial-gradient(
-        ellipse 70% 48% at 50% 45%,
-        rgba(20, 86, 165, 0.12) 0%,
-        rgba(0, 0, 0, 0) 74%
-      ),
-      linear-gradient(
-        180deg,
-        rgba(0, 8, 20, 0.26) 0%,
-        rgba(0, 8, 20, 0) 18%,
-        rgba(0, 8, 20, 0) 82%,
-        rgba(0, 8, 20, 0.24) 100%
-      );
-  }
-
-  .cockpit-dashboard__map::after {
-    content: "";
-    position: absolute;
-    inset: 0;
-    pointer-events: none;
-    z-index: 1;
-    background-image: repeating-linear-gradient(
-      to bottom,
-      rgba(0, 235, 255, 0.04) 0,
-      rgba(0, 235, 255, 0.04) 1px,
-      transparent 1px,
-      transparent 4px
-    );
-    opacity: 0.45;
-  }
-
-  .cockpit-dashboard__left,
-  .cockpit-dashboard__right {
-    scrollbar-width: none;
-    -ms-overflow-style: none;
-
-    &::-webkit-scrollbar {
-      display: none;
-    }
-  }
-
-  .cockpit-panel {
-    position: relative;
-    overflow: hidden;
-    background: linear-gradient(
-      180deg,
-      rgba(6, 22, 45, 0.97) 0%,
-      rgba(4, 16, 32, 0.98) 52%,
-      rgba(2, 10, 22, 0.99) 100%
-    ) !important;
-    border: 1px solid var(--cockpit-panel-border) !important;
-    border-radius: var(--cockpit-panel-radius) !important;
-    box-shadow: inset 0 0 28px rgba(0, 130, 220, 0.1),
-      inset 0 1px 0 rgba(0, 210, 255, 0.12), 0 6px 28px rgba(0, 0, 0, 0.42) !important;
-    backdrop-filter: blur(12px);
-
-    &::before {
-      content: "";
-      position: absolute;
-      top: 0;
-      left: 6%;
-      right: 6%;
-      height: 1px;
-      background: linear-gradient(
-        90deg,
-        transparent,
-        rgba(0, 242, 255, 0.65),
-        transparent
-      );
-      pointer-events: none;
-      z-index: 1;
-    }
-
-    &::after {
-      content: "";
-      position: absolute;
-      inset: 0;
-      pointer-events: none;
-      border-radius: inherit;
-      box-shadow: inset 0 0 0 1px rgba(0, 186, 255, 0.18),
-        inset 0 0 24px rgba(0, 122, 210, 0.14);
-      z-index: 1;
-    }
-  }
-
-  /* section 盒子内部科技填充纹理 */
-  .cockpit-panel > * {
-    position: relative;
-    z-index: 2;
-  }
-
-  .cockpit-panel::before,
-  .cockpit-panel::after {
-    border-radius: inherit;
-  }
-
-  .cockpit-panel {
-    background-image: linear-gradient(
-        115deg,
-        rgba(0, 170, 255, 0.09) 0%,
-        rgba(0, 170, 255, 0) 34%
-      ),
-      linear-gradient(
-        180deg,
-        rgba(0, 255, 255, 0.05) 0%,
-        rgba(0, 255, 255, 0) 24%
-      ),
-      repeating-linear-gradient(
-        90deg,
-        rgba(0, 210, 255, 0.035) 0,
-        rgba(0, 210, 255, 0.035) 1px,
-        transparent 1px,
-        transparent 18px
-      ),
-      repeating-linear-gradient(
-        0deg,
-        rgba(0, 170, 220, 0.028) 0,
-        rgba(0, 170, 220, 0.028) 1px,
-        transparent 1px,
-        transparent 18px
-      ),
-      linear-gradient(
-        180deg,
-        rgba(6, 22, 45, 0.97) 0%,
-        rgba(4, 16, 32, 0.98) 52%,
-        rgba(2, 10, 22, 0.99) 100%
-      ) !important;
-    background-blend-mode: screen, screen, normal, normal, normal;
-  }
-
-  .cockpit-panel__title,
-  .cockpit-panel h3,
-  .cockpit-panel .backbone h3,
-  .cockpit-panel .BOXYI > h3,
-  .cockpit-panel .centeredh3 {
-    color: #ffffff;
-    font-size: 14px;
-    font-weight: 600;
-    letter-spacing: 0.02em;
-    border-bottom: 1px solid var(--cockpit-panel-divider);
-    padding: 0 0 8px;
-    margin-bottom: 10px;
-  }
-
-  .cockpit-panel .centeredh3 span {
-    color: #5ec8ff;
-    text-shadow: 0 0 10px rgba(86, 200, 255, 0.32);
-  }
-
-  .cockpit-panel__title,
-  .cockpit-panel h3,
-  .cockpit-panel .backbone h3,
-  .cockpit-panel .BOXYI > h3,
-  .cockpit-panel .centeredh3 {
-    text-shadow: 0 0 10px rgba(0, 170, 255, 0.28);
-  }
-
-  .cockpit-panel:not(.cockpit-panel--health):not(.cockpit-panel--inbound)
-    .el-tabs__item.is-active {
-    color: #00d4ff !important;
-  }
-
-  .cockpit-panel .el-tabs__active-bar {
-    background-color: #00aaff !important;
-  }
-
-  /* 统一列表表(科技蓝) */
-  .cockpit-unified-table-head {
-    background: linear-gradient(
-      180deg,
-      rgba(0, 36, 72, 0.72) 0%,
-      rgba(0, 24, 44, 0.58) 100%
-    ) !important;
-    color: #ffffff !important;
-    box-shadow: inset 0 -1px 0 rgba(0, 190, 255, 0.22);
-
-    span {
-      color: #ffffff !important;
-      font-weight: 400;
-      text-shadow: 0 0 8px rgba(0, 168, 255, 0.22);
-    }
-  }
-
-  .cockpit-unified-table #Tabtab .el-table__empty-text {
-    color: rgba(200, 228, 245, 0.65) !important;
-  }
-
-  .cockpit-panel .cockpit-section-title {
-    color: #ffffff;
-    text-shadow: none;
-  }
-
-  /* 接入统计 */
-  .cockpit-panel--stats {
-    .cockpit-stats__row {
-      color: var(--cockpit-panel-text);
-      font-size: 13px;
-
-      .SpText {
-        color: var(--cockpit-panel-muted);
-      }
-
-      > span:last-child {
-        color: #fff;
-        font-weight: 500;
-      }
-    }
-
-    .cockpit-stats__legend {
-      display: flex;
-      gap: 5px;
-      margin: 8px 0 6px;
-      height: 5px;
-    }
-
-    .cockpit-stats__legend-seg {
-      flex: 1;
-      border-radius: 2px;
-      opacity: 0.92;
-
-      &--ok {
-        background: var(--cockpit-status-ok);
-        box-shadow: 0 0 8px rgba(126, 207, 81, 0.45);
-      }
-
-      &--warn {
-        background: var(--cockpit-status-warn);
-        box-shadow: 0 0 8px rgba(238, 203, 95, 0.4);
-      }
-
-      &--danger {
-        background: var(--cockpit-status-danger);
-        box-shadow: 0 0 8px rgba(225, 103, 87, 0.4);
-      }
-    }
-
-    .el-select .el-input__inner {
-      height: 34px;
-      line-height: 34px;
-      font-weight: 600;
-      color: #fff !important;
-      background: var(--cockpit-input-bg) !important;
-      border-color: var(--cockpit-input-border) !important;
-      box-shadow: inset 0 0 0 1px rgba(0, 150, 220, 0.18),
-        0 0 12px rgba(0, 122, 210, 0.08);
-    }
-
-    .el-switch__label {
-      color: var(--cockpit-panel-muted);
-      font-size: 12px;
-
-      &.is-active {
-        color: var(--cockpit-kpi-cyan) !important;
-      }
-    }
-
-    .el-switch__core {
-      background: rgba(0, 35, 60, 0.95);
-      border-color: rgba(0, 150, 220, 0.5);
-    }
-
-    .el-switch.is-checked .el-switch__core {
-      border-color: var(--cockpit-accent);
-      background-color: rgba(0, 120, 200, 0.85);
-      box-shadow: 0 0 14px rgba(0, 190, 255, 0.35);
-    }
-  }
-
-  /* 分析 + 历史 */
-  .cockpit-panel--analysis-history {
-    .cockpit-analysis-chart {
-      height: 128px;
-    }
-
-    .cockpit-history-block {
-      border-top-color: var(--cockpit-panel-divider);
-    }
-
-    .el-date-editor.el-input__inner {
-      width: 100%;
-      max-width: none;
-      height: 30px;
-      font-size: 11px;
-      color: var(--cockpit-panel-text) !important;
-      background: var(--cockpit-input-bg) !important;
-      border-color: var(--cockpit-input-border) !important;
-    }
-
-    .el-range-separator,
-    .el-range-input {
-      color: var(--cockpit-panel-muted) !important;
-    }
-
-    .el-input__icon {
-      color: var(--cockpit-kpi-cyan) !important;
-    }
-  }
-
-  /* 任务统计 KPI(L 角描边) */
-  .cockpit-panel .cockpit-task-kpi {
-    gap: 8px;
-    margin-top: 2px;
-  }
-
-  .cockpit-panel .cockpit-task-kpi .YC02,
-  .cockpit-panel .cockpit-task-kpi .YC03 {
-    background-image: none !important;
-    width: auto !important;
-    flex: 1;
-    min-width: 0;
-    min-height: 76px;
-    margin-top: 0 !important;
-    display: flex;
-    flex-direction: column;
-    align-items: center;
-    justify-content: center;
-    gap: 6px;
-    cursor: pointer;
-    position: relative;
-    background: rgba(0, 22, 42, 0.65) !important;
-    border: none !important;
-    border-radius: 2px;
-    box-shadow: inset 0 0 0 1px rgba(0, 122, 200, 0.55),
-      inset 0 0 16px rgba(0, 72, 120, 0.3);
-    transition: box-shadow 0.2s;
-
-    &::before,
-    &::after {
-      content: "";
-      position: absolute;
-      width: 10px;
-      height: 10px;
-      border-color: rgba(0, 210, 255, 0.8);
-      border-style: solid;
-      pointer-events: none;
-    }
-
-    &::before {
-      top: 0;
-      left: 0;
-      border-width: 1px 0 0 1px;
-    }
-
-    &::after {
-      bottom: 0;
-      right: 0;
-      border-width: 0 1px 1px 0;
-    }
-
-    &:hover {
-      box-shadow: inset 0 0 0 1px rgba(0, 200, 255, 0.5),
-        0 0 14px rgba(0, 160, 255, 0.18);
-    }
-
-    strong {
-      font-size: 26px;
-      line-height: 1;
-      color: var(--cockpit-kpi-cyan);
-      text-shadow: 0 0 12px rgba(0, 200, 255, 0.35);
-    }
-
-    span {
-      font-size: 12px;
-      color: var(--cockpit-panel-muted);
-    }
-
-    .texyellow {
-      color: var(--cockpit-status-warn) !important;
-      text-shadow: 0 0 10px rgba(238, 203, 95, 0.35);
-    }
-
-    .textred {
-      color: var(--cockpit-status-danger) !important;
-      text-shadow: 0 0 10px rgba(225, 103, 87, 0.35);
-    }
-  }
-
-  .cockpit-panel .YC01 strong,
-  .cockpit-panel .YC02 strong {
-    color: #4bffff;
-  }
-
-  .cockpit-panel .YC02 span,
-  .cockpit-panel .YC01 span {
-    color: rgba(183, 223, 245, 0.85);
-  }
-
-  .cockpit-panel--health,
-  .cockpit-panel--inbound {
-    overflow: visible;
-  }
-
-  /* 自定义科技蓝 Tab(CockpitTechTabs) */
-  .cockpit-tech-tabs {
-    margin-bottom: 10px;
-  }
-
-  .cockpit-tech-tabs__track {
-    display: flex;
-    align-items: flex-end;
-    gap: 0;
-    min-height: 42px;
-    padding: 5px 10px 0;
-    background: rgba(0, 4, 12, 0.98);
-    border: 1px solid rgba(0, 95, 165, 0.45);
-    border-radius: 22px;
-    box-shadow: inset 0 1px 0 rgba(0, 70, 120, 0.2),
-      inset 0 -12px 20px rgba(0, 0, 0, 0.4);
-    position: relative;
-    overflow: hidden;
-  }
-
-  .cockpit-tech-tabs__list {
-    flex: 1;
-    display: flex;
-    align-items: flex-end;
-    min-width: 0;
-    min-height: 36px;
-    position: relative;
-    z-index: 1;
-  }
-
-  .cockpit-tech-tabs__item {
-    flex: 1;
-    min-width: 72px;
-    height: 34px;
-    margin: 0;
-    padding: 0 4px;
-    border: none;
-    background: transparent;
-    cursor: pointer;
-    position: relative;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    outline: none;
-
-    .cockpit-tech-tabs__label {
-      position: relative;
-      z-index: 3;
-      font-size: 13px;
-      line-height: 1;
-      color: rgba(170, 205, 230, 0.72);
-      transition: color 0.2s;
-      pointer-events: none;
-      user-select: none;
-    }
-
-    &:hover:not(.is-active) .cockpit-tech-tabs__label {
-      color: rgba(210, 235, 255, 0.95);
-    }
-
-    &.is-active {
-      flex: 1.12;
-      height: 36px;
-      margin-bottom: -1px;
-
-      .cockpit-tech-tabs__label {
-        color: #ffffff;
-        font-weight: 600;
-        text-shadow: 0 0 10px rgba(0, 220, 255, 0.35);
-      }
-    }
-  }
-
-  .cockpit-tech-tabs__shape {
-    position: absolute;
-    left: 4%;
-    right: 4%;
-    bottom: 0;
-    top: 0;
-    width: 92%;
-    height: 100%;
-    z-index: 1;
-    pointer-events: none;
-    filter: drop-shadow(0 2px 10px rgba(0, 160, 255, 0.55));
-  }
-
-  .cockpit-tech-tabs__baseline {
-    position: absolute;
-    left: 10px;
-    right: 10px;
-    bottom: 0;
-    height: 2px;
-    z-index: 0;
-    background: linear-gradient(
-      90deg,
-      #00f0ff 0%,
-      rgba(0, 190, 255, 0.85) 28%,
-      rgba(0, 140, 220, 0.5) 70%,
-      rgba(0, 90, 160, 0.25) 100%
-    );
-    box-shadow: 0 0 12px rgba(0, 230, 255, 0.75), 0 0 4px rgba(0, 255, 255, 0.5);
-  }
-
-  .cockpit-tech-tabs__extra {
-    flex-shrink: 0;
-    display: flex;
-    align-items: center;
-    gap: 8px;
-    padding: 0 4px 8px 8px;
-    position: relative;
-    z-index: 2;
-  }
-
-  .cockpit-tech-tabs__bolt {
-    display: none !important;
-  }
-
-  .cockpit-tech-tabs__chevron {
-    font-size: 14px;
-    color: #5ec8ff;
-    cursor: pointer;
-    text-shadow: 0 0 8px rgba(0, 200, 255, 0.6);
-
-    &:hover {
-      color: #9ef8ff;
-    }
-  }
-
-  /* 右侧统一 Tab:贴顶左对齐(健康 / 入库,图二) */
-  .cockpit-panel--health .cockpit-tech-tabs,
-  .cockpit-panel--inbound .cockpit-tech-tabs,
-  .cockpit-tech-tabs--panel {
-    margin-bottom: 6px;
-  }
-
-  .cockpit-panel--health .cockpit-tech-tabs--panel,
-  .cockpit-panel--inbound .cockpit-tech-tabs--panel,
-  .cockpit-tech-tabs--panel {
-    .cockpit-tech-tabs__track {
-      position: relative;
-      min-height: 36px;
-      padding: 0 28px 0 0;
-      background: transparent;
-      border: none;
-      border-radius: 0;
-      box-shadow: none;
-      overflow: visible;
-    }
-
-    .cockpit-tech-tabs__list {
-      flex: 1;
-      justify-content: flex-start;
-      gap: 6px;
-      min-height: 34px;
-    }
-
-    .cockpit-tech-tabs__item {
-      flex: 0 0 auto;
-      min-width: 64px;
-      height: 32px;
-      padding: 0 20px;
-
-      &.is-active {
-        flex: 0 0 auto;
-        height: 34px;
-        margin-bottom: 0;
-
-        &::after {
-          content: "";
-          position: absolute;
-          left: 8%;
-          right: 8%;
-          bottom: 0;
-          height: 2px;
-          background: #00f0ff;
-          box-shadow: 0 0 10px rgba(0, 240, 255, 0.85);
-          z-index: 4;
-          pointer-events: none;
-        }
-      }
-
-      &:not(.is-active) .cockpit-tech-tabs__label {
-        color: rgba(183, 223, 245, 0.5);
-        font-weight: 400;
-      }
-    }
-
-    .cockpit-tech-tabs__shape {
-      left: 0;
-      right: 0;
-      width: 100%;
-      filter: drop-shadow(0 2px 12px rgba(0, 170, 255, 0.5));
-    }
-
-    .cockpit-tech-tabs__baseline {
-      display: none;
-    }
-
-    .cockpit-tech-tabs__extra {
-      flex-shrink: 0;
-      margin-left: auto;
-      padding: 0 0 8px 8px;
-      position: static;
-      transform: none;
-    }
-  }
-
-  /* 入库表格:图二深色圆角容器 + 轻斑马纹 */
-  .cockpit-panel--inbound .cockpit-inbound-table-wrap {
-    border: 1px solid rgba(0, 110, 190, 0.4);
-    background: rgba(0, 16, 32, 0.75);
-    box-shadow: inset 0 0 16px rgba(0, 40, 80, 0.25);
-  }
-
-  .cockpit-panel--inbound .cockpit-inbound-more-link {
-    color: rgba(126, 212, 255, 0.95) !important;
-    cursor: pointer;
-  }
-
-  .cockpit-panel--health .cockpit-health-panel__tab-body {
-    height: var(--cockpit-health-pane-h);
-    min-height: var(--cockpit-health-pane-h);
-  }
-
-  .cockpit-panel--health .cockpit-health-panel__pane--abnormal {
-    justify-content: flex-start;
-  }
-
-  .cockpit-panel--health
-    .cockpit-health-panel__pane--abnormal
-    .cockpit-abnormal-panel {
-    height: auto;
-    flex: 0 0 auto;
-  }
-
-  .cockpit-panel--health .cockpit-abnormal-panel__subtitle,
-  .cockpit-panel--health .cockpit-abnormal-table__section-head {
-    color: #ffffff;
-    text-shadow: 0 0 8px rgba(0, 170, 255, 0.2);
-  }
-
-  .cockpit-panel--health .cockpit-abnormal-table__section-head {
-    background: rgba(0, 52, 96, 0.85);
-    border: 1px solid rgba(0, 120, 200, 0.35);
-  }
-
-  .cockpit-panel--health .cockpit-abnormal-kpi__card {
-    --cockpit-abnormal-kpi-bg: rgba(0, 28, 52, 0.75);
-    --cockpit-abnormal-kpi-corner: rgba(0, 210, 255, 0.85);
-  }
-
-  .cockpit-panel--health .cockpit-abnormal-kpi__value {
-    color: #5ce1ff;
-    text-shadow: 0 0 12px rgba(0, 200, 255, 0.35);
-  }
-
-  .cockpit-panel--health .cockpit-abnormal-kpi__label {
-    color: rgba(190, 215, 235, 0.88);
-  }
-
-  .cockpit-health-panel__subtitle,
-  .cockpit-inbound-subtitle {
-    color: #ffffff;
-    font-size: 14px;
-    text-shadow: 0 0 8px rgba(0, 170, 255, 0.2);
-  }
-
-  .cockpit-panel--health,
-  .cockpit-panel--inbound {
-    padding-top: 8px;
-  }
-
-  .cockpit-panel--health .cockpit-health-panel__subtitle {
-    margin-top: 4px;
-    padding-right: 4px;
-    border-bottom: none;
-  }
-
-  .cockpit-panel--inbound .cockpit-inbound-subtitle {
-    margin: 6px 0 8px;
-    border-bottom: none;
-  }
-}
-
-/* —— 非科技蓝:浅色统一 —— */
-html:not([data-theme="tech-blue"]) .cockpit-dashboard-page {
-  --cockpit-page-bg: #eef1f6;
-  --cockpit-panel-bg: #ffffff;
-  --cockpit-panel-border: #e4e7ed;
-  --cockpit-panel-divider: #ebeef5;
-  --cockpit-panel-text: #303133;
-  --cockpit-panel-title: #303133;
-  --cockpit-panel-muted: #909399;
-  --cockpit-panel-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
-  --cockpit-panel-radius: 8px;
-  --cockpit-table-header-bg: #f5f7fa;
-  --cockpit-table-stripe: #fafafa;
-  --cockpit-input-bg: #ffffff;
-  --cockpit-input-border: #dcdfe6;
-  --cockpit-accent: var(--primary-color, #82780c);
-
-  .cockpit-stats__legend {
-    display: none;
-  }
-
-  .cockpit-panel__title,
-  .cockpit-panel h3 {
-    border-bottom-color: #ebeef5;
-  }
-
-  .cockpit-tech-tabs__track {
-    background: #f0f2f5;
-    border: 1px solid #dcdfe6;
-    border-radius: 8px;
-    box-shadow: none;
-    padding: 4px;
-    min-height: 36px;
-  }
-
-  .cockpit-tech-tabs__baseline,
-  .cockpit-tech-tabs__shape {
-    display: none;
-  }
-
-  .cockpit-tech-tabs__bolt {
-    display: none !important;
-  }
-
-  .cockpit-tech-tabs__item {
-    height: 32px;
-    border-radius: 4px;
-
-    .cockpit-tech-tabs__label {
-      color: #909399;
-    }
-
-    &.is-active {
-      background: #ffffff;
-      box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
-
-      .cockpit-tech-tabs__label {
-        color: var(--primary-color, #82780c);
-        font-weight: 600;
-        text-shadow: none;
-      }
-    }
-  }
-
-  .cockpit-tech-tabs__chevron {
-    color: var(--primary-color, #82780c);
-    text-shadow: none;
-  }
-
-  .cockpit-panel .cockpit-task-kpi .YC02,
-  .cockpit-panel .cockpit-task-kpi .YC03 {
-    background-image: none !important;
-    width: auto !important;
-    flex: 1;
-    min-height: 64px;
-    margin-top: 0 !important;
-    border: 1px solid #e4e7ed;
-    border-radius: 6px;
-    background: #f8fafc !important;
-  }
-
-  .cockpit-unified-table-head {
-    background: var(--cockpit-table-header-bg) !important;
-    color: var(--cockpit-panel-title) !important;
-
-    span {
-      color: var(--cockpit-panel-muted) !important;
-    }
-  }
-
-  .cockpit-unified-table #Tabtab .el-table__body tr:hover > td.el-table__cell {
-    background: var(--cockpit-table-stripe) !important;
-  }
-}

+ 0 - 235
src/views/admin/cockpitManage/component/CockpitAbnormalPanel.vue

@@ -1,235 +0,0 @@
-<template>
-  <div class="cockpit-abnormal-panel">
-    <div class="cockpit-abnormal-panel__subtitle">异常设备概览</div>
-
-    <div class="cockpit-abnormal-kpi">
-      <div class="cockpit-abnormal-kpi__card">
-        <span class="cockpit-abnormal-kpi__corner is-tl" aria-hidden="true" />
-        <span class="cockpit-abnormal-kpi__corner is-tr" aria-hidden="true" />
-        <span class="cockpit-abnormal-kpi__corner is-bl" aria-hidden="true" />
-        <span class="cockpit-abnormal-kpi__corner is-br" aria-hidden="true" />
-        <strong class="cockpit-abnormal-kpi__value">{{ normalTotal }}</strong>
-        <span class="cockpit-abnormal-kpi__label">正常总数</span>
-      </div>
-      <div
-        class="cockpit-abnormal-kpi__card cockpit-abnormal-kpi__card--danger"
-      >
-        <span class="cockpit-abnormal-kpi__corner is-tl" aria-hidden="true" />
-        <span class="cockpit-abnormal-kpi__corner is-tr" aria-hidden="true" />
-        <span class="cockpit-abnormal-kpi__corner is-bl" aria-hidden="true" />
-        <span class="cockpit-abnormal-kpi__corner is-br" aria-hidden="true" />
-        <strong class="cockpit-abnormal-kpi__value">{{ abnormalTotal }}</strong>
-        <span class="cockpit-abnormal-kpi__label">异常总数</span>
-      </div>
-    </div>
-
-    <div class="cockpit-abnormal-table">
-      <div class="cockpit-abnormal-table__section-head">异常数据信息</div>
-      <div
-        class="cockpit-abnormal-table-wrap cockpit-table-block cockpit-unified-table cockpit-unified-table--abnormal-two"
-      >
-        <p
-          class="titleYC cockpit-unified-table-head cockpit-unified-table-head--abnormal-two"
-        >
-          <span class="cockpit-inbound-col-name">风场名称</span>
-          <span class="cockpit-inbound-col-extra">异常风机数</span>
-        </p>
-        <Tabroll
-          :table-data="tableData"
-          :shujuloading="loading"
-          :columns="tableColumns"
-          :column-widths="columnWidths"
-          :max-height="tableBodyHeight"
-        />
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import { queryStatistics } from "@/api/ledger.js";
-import Tabroll from "./tabroll.vue";
-import { COCKPIT_TABLE_BODY_HEIGHT } from "./cockpitTableMetrics";
-
-export default {
-  name: "CockpitAbnormalPanel",
-  components: { Tabroll },
-  props: {
-    maplistArr: { type: Object, default: () => ({}) },
-    defaultdata: { type: Object, default: () => ({}) },
-  },
-  data() {
-    return {
-      loading: false,
-      equipment: {},
-      tableData: [],
-      tableColumns: [{ prop: "fieldName" }, { prop: "errCount" }],
-      columnWidths: {
-        fieldName: "50%",
-        errCount: "50%",
-      },
-      tableBodyHeight: COCKPIT_TABLE_BODY_HEIGHT,
-    };
-  },
-  computed: {
-    abnormalTotal() {
-      const e = this.equipment;
-      return e.errDeviceCount ?? e.errCounrt ?? e.errCount ?? 0;
-    },
-    normalTotal() {
-      const e = this.equipment;
-      if (e.normalCount != null) return e.normalCount;
-      if (e.engineNormalCount != null) return e.engineNormalCount;
-      if (e.totalCount != null && this.abnormalTotal != null) {
-        return Math.max(0, Number(e.totalCount) - Number(this.abnormalTotal));
-      }
-      return 0;
-    },
-  },
-  watch: {
-    maplistArr: {
-      handler(val) {
-        if (val && Object.keys(val).length > 0) {
-          this.fetchStatistics();
-        }
-      },
-      immediate: true,
-      deep: true,
-    },
-  },
-  methods: {
-    fetchStatistics() {
-      if (!this.maplistArr?.codeNumber) return;
-      this.loading = true;
-      const end = new Date();
-      const start = new Date();
-      start.setMonth(start.getMonth() - 6);
-      queryStatistics({
-        codeNumber: this.maplistArr.codeNumber,
-        codeType: this.maplistArr.codeType,
-        startTime: this.$formatDate(start),
-        endTime: this.$formatDate(end),
-      })
-        .then((res) => {
-          const data = res.data || {};
-          this.equipment = data;
-          this.tableData = (data.errList || []).map((row) => ({
-            fieldName: row.fieldName ?? row.windFarmName ?? "—",
-            errCount:
-              row.errCount ??
-              row.abnormalEngineCount ??
-              row.engineErrCount ??
-              0,
-          }));
-        })
-        .finally(() => {
-          this.loading = false;
-        });
-    },
-  },
-};
-</script>
-
-<style lang="scss" scoped>
-.cockpit-abnormal-panel {
-  display: flex;
-  flex-direction: column;
-  width: 100%;
-}
-
-.cockpit-abnormal-panel__subtitle {
-  flex-shrink: 0;
-  margin: 4px 0 10px;
-  font-size: 14px;
-  font-weight: 600;
-  color: var(--cockpit-panel-title, #303133);
-}
-
-.cockpit-abnormal-kpi {
-  flex-shrink: 0;
-  display: grid;
-  grid-template-columns: 1fr 1fr;
-  gap: 10px;
-  margin-bottom: 12px;
-}
-
-.cockpit-abnormal-kpi__card {
-  position: relative;
-  min-height: 76px;
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  justify-content: center;
-  gap: 4px;
-  background: var(--cockpit-abnormal-kpi-bg, rgba(0, 36, 64, 0.45));
-}
-
-.cockpit-abnormal-kpi__corner {
-  position: absolute;
-  width: 10px;
-  height: 10px;
-  border-color: var(--cockpit-abnormal-kpi-corner, rgba(0, 200, 255, 0.75));
-  border-style: solid;
-  pointer-events: none;
-
-  &.is-tl {
-    top: 0;
-    left: 0;
-    border-width: 1px 0 0 1px;
-  }
-
-  &.is-tr {
-    top: 0;
-    right: 0;
-    border-width: 1px 1px 0 0;
-  }
-
-  &.is-bl {
-    bottom: 0;
-    left: 0;
-    border-width: 0 0 1px 1px;
-  }
-
-  &.is-br {
-    bottom: 0;
-    right: 0;
-    border-width: 0 1px 1px 0;
-  }
-}
-
-.cockpit-abnormal-kpi__value {
-  font-size: 28px;
-  font-weight: 600;
-  line-height: 1.1;
-  color: var(--cockpit-abnormal-kpi-value, #4bffff);
-}
-
-.cockpit-abnormal-kpi__card--danger .cockpit-abnormal-kpi__value {
-  color: #ff4d4f;
-}
-
-.cockpit-abnormal-kpi__label {
-  font-size: 12px;
-  color: var(--cockpit-panel-muted, #909399);
-}
-
-.cockpit-abnormal-table {
-  flex: 0 0 auto;
-  min-height: 0;
-}
-
-.cockpit-abnormal-table__section-head {
-  margin-bottom: 8px;
-  padding: 6px 10px;
-  font-size: 14px;
-  font-weight: 600;
-  color: var(--cockpit-panel-title, #303133);
-  background: var(--cockpit-abnormal-section-head-bg, rgba(0, 52, 96, 0.35));
-  border-radius: 2px;
-}
-
-.cockpit-abnormal-table-wrap {
-  border-radius: 4px;
-  overflow: hidden;
-}
-</style>

+ 0 - 206
src/views/admin/cockpitManage/component/CockpitHealthPanel.vue

@@ -1,206 +0,0 @@
-<template>
-  <div class="cockpit-health-panel">
-    <CockpitTechTabs v-model="activeTab" :tabs="healthTabs" variant="panel" />
-
-    <div class="cockpit-health-panel__tab-body">
-      <div
-        v-show="activeTab === 'healthy'"
-        class="cockpit-health-panel__pane cockpit-health-panel__pane--healthy"
-      >
-        <div class="cockpit-health-panel__subtitle">综合健康评分</div>
-        <div class="cockpit-health-panel__body">
-          <ul class="cockpit-health-panel__legend">
-            <li
-              v-for="item in legendItems"
-              :key="item.name"
-              class="cockpit-health-panel__legend-item"
-            >
-              <i :style="{ background: item.color }"></i>
-              <span>{{ item.name }}</span>
-            </li>
-          </ul>
-          <div ref="chartRef" class="cockpit-health-panel__chart"></div>
-        </div>
-        <CockpitHealthTable
-          ref="healthTable"
-          class="cockpit-health-panel__table"
-        />
-      </div>
-
-      <div
-        v-show="activeTab === 'abnormal'"
-        class="cockpit-health-panel__pane cockpit-health-panel__pane--abnormal"
-      >
-        <CockpitAbnormalPanel
-          :maplistArr="maplistArr"
-          :defaultdata="defaultdata"
-        />
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import * as echarts from "echarts";
-import { healthScoreDistribution } from "./cockpitHealthData";
-import CockpitTechTabs from "./CockpitTechTabs.vue";
-import CockpitHealthTable from "./CockpitHealthTable.vue";
-import CockpitAbnormalPanel from "./CockpitAbnormalPanel.vue";
-
-export default {
-  name: "CockpitHealthPanel",
-  components: { CockpitTechTabs, CockpitHealthTable, CockpitAbnormalPanel },
-  props: {
-    maplistArr: { type: Object, default: () => ({}) },
-    defaultdata: { type: Object, default: () => ({}) },
-  },
-  data() {
-    return {
-      activeTab: "healthy",
-      healthTabs: [
-        { label: "健康", value: "healthy" },
-        { label: "异常", value: "abnormal" },
-      ],
-      chart: null,
-      legendItems: [
-        { name: "优", color: "#7ECF51" },
-        { name: "良", color: "#2979ff" },
-        { name: "中", color: "#EECB5F" },
-        { name: "差", color: "#E16757" },
-      ],
-    };
-  },
-  mounted() {
-    this.$nextTick(() => this.initChart());
-    window.addEventListener("resize", this.handleResize);
-  },
-  watch: {
-    activeTab(val) {
-      if (val === "healthy") {
-        this.$nextTick(() => {
-          if (this.chart) {
-            this.chart.resize();
-          } else {
-            this.initChart();
-          }
-        });
-      }
-    },
-  },
-  beforeDestroy() {
-    window.removeEventListener("resize", this.handleResize);
-    if (this.chart) {
-      this.chart.dispose();
-      this.chart = null;
-    }
-  },
-  methods: {
-    initChart() {
-      if (!this.$refs.chartRef) return;
-      const textColor =
-        getComputedStyle(document.documentElement)
-          .getPropertyValue("--cockpit-panel-muted")
-          .trim() || "#909399";
-      this.chart = echarts.init(this.$refs.chartRef);
-      this.chart.setOption({
-        tooltip: {
-          trigger: "item",
-          formatter: "{b}: {c} ({d}%)",
-        },
-        series: [
-          {
-            type: "pie",
-            radius: ["48%", "78%"],
-            center: ["50%", "50%"],
-            avoidLabelOverlap: true,
-            label: {
-              show: true,
-              formatter: "{b}\n{d}%",
-              color: textColor,
-              fontSize: 11,
-            },
-            labelLine: {
-              show: true,
-              length: 8,
-              length2: 6,
-              lineStyle: { color: "rgba(183, 223, 245, 0.45)" },
-            },
-            data: healthScoreDistribution,
-          },
-        ],
-      });
-    },
-    handleResize() {
-      if (this.chart) this.chart.resize();
-    },
-  },
-};
-</script>
-
-<style lang="scss" scoped>
-.cockpit-health-panel__subtitle {
-  margin: 4px 0 10px;
-  font-size: 13px;
-  font-weight: 600;
-  color: var(--cockpit-panel-title, #303133);
-}
-
-.cockpit-health-panel__tab-body {
-  position: relative;
-  height: var(--cockpit-health-pane-h);
-  min-height: var(--cockpit-health-pane-h);
-  overflow: hidden;
-}
-
-.cockpit-health-panel__pane {
-  position: absolute;
-  inset: 0;
-  overflow: hidden;
-  display: flex;
-  flex-direction: column;
-  justify-content: flex-start;
-}
-
-.cockpit-health-panel__body {
-  display: flex;
-  align-items: center;
-  gap: 8px;
-  flex-shrink: 0;
-  height: var(--cockpit-health-chart-h, 150px);
-  min-height: var(--cockpit-health-chart-h, 150px);
-}
-
-.cockpit-health-panel__legend {
-  flex: 0 0 52px;
-  margin: 0;
-  padding: 0;
-  list-style: none;
-}
-
-.cockpit-health-panel__legend-item {
-  display: flex;
-  align-items: center;
-  gap: 6px;
-  margin-bottom: 10px;
-  font-size: 12px;
-  color: var(--cockpit-panel-muted, #909399);
-
-  i {
-    flex-shrink: 0;
-    width: 10px;
-    height: 10px;
-    border-radius: 1px;
-  }
-}
-
-.cockpit-health-panel__chart {
-  flex: 1;
-  min-width: 0;
-  height: var(--cockpit-health-chart-h, 150px);
-}
-
-.cockpit-health-panel__table {
-  flex: 0 0 auto;
-  margin-top: 8px;
-}
-</style>

+ 0 - 65
src/views/admin/cockpitManage/component/CockpitHealthTable.vue

@@ -1,65 +0,0 @@
-<template>
-  <div class="cockpit-health-table">
-    <h3 class="cockpit-section-title">健康数据信息</h3>
-    <div
-      class="cockpit-scroll-table cockpit-table-block cockpit-unified-table cockpit-unified-table--health"
-    >
-      <p
-        class="titleYC cockpit-unified-table-head cockpit-unified-table-head--health"
-      >
-        <span>风场名称</span>
-        <span>优</span>
-        <span>良</span>
-        <span>中</span>
-        <span>差</span>
-      </p>
-      <Tabroll
-        :table-data="tableData"
-        :columns="columns"
-        :column-widths="columnWidths"
-        :max-height="bodyHeight"
-      />
-    </div>
-  </div>
-</template>
-
-<script>
-import { healthTableColumns, healthTableData } from "./cockpitHealthData";
-import { COCKPIT_TABLE_BODY_HEIGHT } from "./cockpitTableMetrics";
-import Tabroll from "./tabroll.vue";
-
-export default {
-  name: "CockpitHealthTable",
-  components: { Tabroll },
-  props: {
-    bodyHeight: { type: Number, default: COCKPIT_TABLE_BODY_HEIGHT },
-  },
-  data() {
-    return {
-      columns: healthTableColumns.map(({ prop }) => ({ prop })),
-      columnWidths: {
-        fieldName: "38%",
-        excellent: "15%",
-        good: "15%",
-        medium: "16%",
-        poor: "16%",
-      },
-      tableData: healthTableData,
-    };
-  },
-};
-</script>
-
-<style lang="scss" scoped>
-.cockpit-health-table {
-  width: 100%;
-}
-
-.cockpit-health-table .cockpit-section-title {
-  margin: 0 0 8px;
-  padding: 0;
-  border-bottom: none;
-  font-size: 14px;
-  font-weight: 600;
-}
-</style>

+ 0 - 96
src/views/admin/cockpitManage/component/CockpitTechTabs.vue

@@ -1,96 +0,0 @@
-<template>
-  <div class="cockpit-tech-tabs" :class="`cockpit-tech-tabs--${variant}`">
-    <div class="cockpit-tech-tabs__track">
-      <div class="cockpit-tech-tabs__list" role="tablist">
-        <button
-          v-for="tab in tabs"
-          :key="tab.value"
-          type="button"
-          role="tab"
-          class="cockpit-tech-tabs__item"
-          :class="{ 'is-active': value === tab.value }"
-          :aria-selected="value === tab.value"
-          @click="onSelect(tab.value)"
-        >
-          <svg
-            v-if="value === tab.value"
-            class="cockpit-tech-tabs__shape"
-            viewBox="0 0 160 40"
-            preserveAspectRatio="none"
-            aria-hidden="true"
-          >
-            <defs>
-              <linearGradient :id="gradId" x1="0%" y1="0%" x2="0%" y2="100%">
-                <stop offset="0%" stop-color="#4dd4ff" />
-                <stop offset="38%" stop-color="#1a9ee8" />
-                <stop offset="100%" stop-color="#0a4d8c" />
-              </linearGradient>
-              <linearGradient :id="strokeId" x1="0%" y1="0%" x2="100%" y2="0%">
-                <stop offset="0%" stop-color="rgba(100, 230, 255, 0.15)" />
-                <stop offset="25%" stop-color="#9ef8ff" />
-                <stop offset="75%" stop-color="#9ef8ff" />
-                <stop offset="100%" stop-color="rgba(100, 230, 255, 0.15)" />
-              </linearGradient>
-            </defs>
-            <path
-              class="cockpit-tech-tabs__shape-fill"
-              :fill="`url(#${gradId})`"
-              d="M14 3 L146 3 Q152 3 155 9 L160 40 L0 40 L5 9 Q8 3 14 3 Z"
-            />
-            <path
-              class="cockpit-tech-tabs__shape-stroke"
-              fill="none"
-              :stroke="`url(#${strokeId})`"
-              stroke-width="1.2"
-              d="M14 3 L146 3 Q152 3 155 9 L160 40 L0 40 L5 9 Q8 3 14 3 Z"
-            />
-          </svg>
-          <span class="cockpit-tech-tabs__label">{{ tab.label }}</span>
-        </button>
-      </div>
-      <!-- <div v-if="$slots.extra" class="cockpit-tech-tabs__extra">
-        <slot name="extra" />
-      </div> -->
-      <div class="cockpit-tech-tabs__baseline" aria-hidden="true" />
-    </div>
-  </div>
-</template>
-
-<script>
-export default {
-  name: "CockpitTechTabs",
-  model: {
-    prop: "value",
-    event: "input",
-  },
-  props: {
-    value: { type: String, required: true },
-    tabs: {
-      type: Array,
-      required: true,
-      // [{ label: '入库', value: 'import' }]
-    },
-    /** pill:胶囊底托(健康等);panel:贴面板顶左对齐(入库/接入,图二) */
-    variant: {
-      type: String,
-      default: "pill",
-      validator: (v) => ["pill", "panel"].includes(v),
-    },
-  },
-  computed: {
-    gradId() {
-      return `cockpit-tab-grad-${this._uid}`;
-    },
-    strokeId() {
-      return `cockpit-tab-stroke-${this._uid}`;
-    },
-  },
-  methods: {
-    onSelect(val) {
-      if (val !== this.value) {
-        this.$emit("input", val);
-      }
-    },
-  },
-};
-</script>

+ 0 - 23
src/views/admin/cockpitManage/component/cockpitHealthData.js

@@ -1,23 +0,0 @@
-/** 驾驶舱健康展示 mock(布局占位,不影响原有业务接口) */
-export const healthScoreDistribution = [
-  { value: 40, name: "优", itemStyle: { color: "#7ECF51" } },
-  { value: 10, name: "良", itemStyle: { color: "#2979ff" } },
-  { value: 45, name: "中", itemStyle: { color: "#EECB5F" } },
-  { value: 5, name: "差", itemStyle: { color: "#E16757" } },
-];
-
-export const healthTableColumns = [
-  { prop: "fieldName", label: "风场名称", minWidth: 108 },
-  { prop: "excellent", label: "优", width: 40 },
-  { prop: "good", label: "良", width: 40 },
-  { prop: "medium", label: "中", width: 40 },
-  { prop: "poor", label: "差", width: 40 },
-];
-
-export const healthTableData = [
-  { fieldName: "马宗山风电场", excellent: 3, good: 10, medium: 10, poor: 9 },
-  { fieldName: "桥西第一风电场", excellent: 5, good: 8, medium: 6, poor: 2 },
-  { fieldName: "桥西第二风电场", excellent: 4, good: 9, medium: 7, poor: 3 },
-  { fieldName: "王团风电场", excellent: 6, good: 7, medium: 5, poor: 1 },
-  { fieldName: "示范风电场", excellent: 50, good: 200, medium: 100, poor: 100 },
-];

+ 0 - 6
src/views/admin/cockpitManage/component/cockpitTableMetrics.js

@@ -1,6 +0,0 @@
-/** 驾驶舱列表表格统一尺寸(与 cockpit-dashboard.scss 变量保持一致) */
-export const COCKPIT_TR_HEIGHT = 40;
-export const COCKPIT_TABLE_VISIBLE_ROWS = 4;
-export const COCKPIT_TH_HEIGHT = 32;
-export const COCKPIT_TABLE_BODY_HEIGHT =
-  COCKPIT_TR_HEIGHT * COCKPIT_TABLE_VISIBLE_ROWS;

+ 114 - 244
src/views/admin/cockpitManage/component/leftdata.vue

@@ -1,14 +1,12 @@
 <template>
-  <div class="backbone" :class="{ 'backbone--flat': panel !== 'all' }">
-    <div
-      v-if="showTaskBlock"
-      class="BOXYI"
-      v-hasPermi="['home:performance:performanceData']"
-    >
+  <div class="backbone">
+    <div class="BOXYI" v-hasPermi="['home:performance:performanceData']">
       <h3>任务统计</h3>
-      <div class="BOXsan cockpit-task-kpi">
+      <div class="BOXsan">
         <div class="YC02" @click="getwgl">
-          <strong> {{ onrelevance ? onrelevance : 0 }}</strong>
+          <strong class="texyellow">
+            {{ onrelevance ? onrelevance : 0 }}</strong
+          >
           <span>待分析</span>
         </div>
         <div class="YC02" @click="getwfx">
@@ -17,9 +15,7 @@
         </div>
 
         <div class="YC03" @click="getpd">
-          <strong class="texyellow">
-            {{ queueNumber ? queueNumber : 0 }}</strong
-          >
+          <strong class="textred"> {{ queueNumber ? queueNumber : 0 }}</strong>
           <span>排队中</span>
         </div>
       </div>
@@ -100,130 +96,46 @@
         </div>
       </el-dialog>
     </div>
-    <template v-if="showInboundBlock">
-      <div v-if="panel === 'inbound'" class="cockpit-inbound-panel">
-        <CockpitTechTabs
-          v-model="inboundTab"
-          :tabs="inboundTabs"
-          variant="panel"
-        >
-          <template #extra>
-            <i
-              class="el-icon-arrow-right cockpit-tech-tabs__chevron"
-              title="更多"
-              @click="onInboundChevronClick"
-            />
-          </template>
-        </CockpitTechTabs>
-
-        <div class="cockpit-inbound-body">
-          <div v-show="inboundTab === 'import'" class="cockpit-inbound-pane">
-            <div class="cockpit-inbound-pane-header">
-              <div
-                class="cockpit-inbound-subtitle"
-                v-hasPermi="['home:offlinedata']"
-              >
-                入库数据
-              </div>
-              <span class="cockpit-inbound-col-data">
-                <span class="cockpit-inbound-more-link" @click="more"
-                  >更多</span
-                >
-              </span>
-            </div>
-
-            <div
-              class="cockpit-inbound-table-wrap cockpit-table-block cockpit-unified-table cockpit-unified-table--inbound-import BOX BOX--flat"
-              v-hasPermi="['home:offlinedata']"
-            >
-              <p
-                class="titleYC cockpit-unified-table-head cockpit-unified-table-head--inbound-import"
-              >
-                <span class="cockpit-inbound-col-name">风场名称</span>
-                <span class="cockpit-inbound-col-extra"> 入库时间 </span>
-              </p>
-              <tabroll
-                :table-data="tableData"
-                :shujuloading="shujuloading"
-                :columns="inboundImportColumns"
-                :column-widths="inboundImportColumnWidths"
-                :max-height="140"
-              />
-            </div>
-          </div>
-
-          <div v-show="inboundTab === 'access'" class="cockpit-inbound-pane">
-            <div
-              class="cockpit-inbound-subtitle"
-              v-hasPermi="['home:onlinData']"
-            >
-              接入数据
-            </div>
-            <div
-              class="cockpit-inbound-table-wrap cockpit-table-block cockpit-unified-table cockpit-unified-table--inbound-two BOX BOX--flat"
-              v-hasPermi="['home:onlinData']"
-            >
-              <p
-                class="titleYC cockpit-unified-table-head cockpit-unified-table-head--inbound-two"
-              >
-                <span class="cockpit-inbound-col-name">风场名称</span>
-                <span class="cockpit-inbound-col-extra">采集状态</span>
-              </p>
-              <tabroll
-                :table-data="hometopdata"
-                :hometoploading="hometoploading"
-                :columns="hometopColumns"
-                :column-widths="hometopcolumnWidths"
-                :max-height="cockpitTableBodyHeight"
-              />
-            </div>
-          </div>
-        </div>
+    <!-- 入库信息 -->
+    <!-- 离线 -->
+    <div class="BOX" v-hasPermi="['home:offlinedata']">
+      <h3 class="centeredh3">
+        入库数据
+        <span>
+          <span style="cursor: pointer" @click="importdata">导入数据</span>
+          <span style="cursor: pointer" @click="more">更多</span>
+        </span>
+      </h3>
+      <div>
+        <p class="titleYC"><span>风场名称</span><span>入库时间</span></p>
+        <tabroll
+          :table-data="tableData"
+          :shujuloading="shujuloading"
+          :columns="YCtableColumns"
+          :column-widths="YCcolumnWidths"
+          :max-height="140"
+        ></tabroll>
       </div>
-
-      <template v-else>
-        <!-- 入库信息 -->
-        <!-- 离线 -->
-        <div class="BOX" v-hasPermi="['home:offlinedata']">
-          <h3 class="centeredh3">
-            入库数据
-            <span>
-              <span style="cursor: pointer" @click="importdata">导入数据</span>
-              <span style="cursor: pointer" @click="more">更多</span>
-            </span>
-          </h3>
-          <div>
-            <p class="titleYC"><span>风场名称</span><span>入库时间</span></p>
-            <tabroll
-              :table-data="tableData"
-              :shujuloading="shujuloading"
-              :columns="YCtableColumns"
-              :column-widths="YCcolumnWidths"
-              :max-height="140"
-            ></tabroll>
-          </div>
-        </div>
-        <!-- 在线 -->
-        <div class="BOX" v-hasPermi="['home:onlinData']">
-          <h3 class="centeredh3">
-            接入数据
-            <span>
-              <span style="cursor: pointer" @click="onlinedata">更多</span>
-            </span>
-          </h3>
-          <div>
-            <p class="titleYC"><span>风场名称</span><span>采集状态</span></p>
-            <tabroll
-              :table-data="hometopdata"
-              :hometoploading="hometoploading"
-              :columns="hometopColumns"
-              :column-widths="hometopcolumnWidths"
-              :max-height="140"
-            ></tabroll>
-          </div>
-        </div>
-      </template>
-    </template>
+    </div>
+    <!-- 在线 -->
+    <div class="BOX" v-hasPermi="['home:onlinData']">
+      <h3 class="centeredh3">
+        接入数据
+        <span>
+          <span style="cursor: pointer" @click="onlinedata">更多</span>
+        </span>
+      </h3>
+      <div>
+        <p class="titleYC"><span>风场名称</span><span>采集状态</span></p>
+        <tabroll
+          :table-data="hometopdata"
+          :hometoploading="hometoploading"
+          :columns="hometopColumns"
+          :column-widths="hometopcolumnWidths"
+          :max-height="140"
+        ></tabroll>
+      </div>
+    </div>
     <el-dialog
       title="实时数据采集统计"
       :visible.sync="lineShow"
@@ -392,58 +304,22 @@ import {
 } from "@/api/ledger.js";
 import axios from "axios";
 import Tabroll from "./tabroll.vue";
-import CockpitTechTabs from "./CockpitTechTabs.vue";
-import { COCKPIT_TABLE_BODY_HEIGHT } from "./cockpitTableMetrics";
-
 export default {
-  props: {
-    /** task | inbound | all */
-    panel: { type: String, default: "all" },
-  },
+  // props: {
+  //   maplistArr: {
+  //     type: Object,
+  //     default: () => ({}),
+  //   },
+  //   defaultdata: {
+  //     type: Object,
+  //     default: () => ({}),
+  //   },
+  // },
   components: {
     Tabroll,
-    CockpitTechTabs,
-  },
-  computed: {
-    showTaskBlock() {
-      return this.panel === "all" || this.panel === "task";
-    },
-    showInboundBlock() {
-      return this.panel === "all" || this.panel === "inbound";
-    },
-    shouldPollInbound() {
-      return this.panel === "inbound" || this.panel === "all";
-    },
-    filteredWindList() {
-      return this.searchvalue
-        ? this.windList.filter((item) =>
-            item.windFarmName.includes(this.searchvalue),
-          )
-        : this.windList;
-    },
-    inboundImportColumns() {
-      return [
-        { prop: "windFarmName", label: "风场名称" },
-        { prop: "createTime", label: "导入数据" },
-      ];
-    },
-    inboundImportColumnWidths() {
-      return {
-        windFarmName: "42%",
-        createTime: "auto",
-      };
-    },
-    inboundTabs() {
-      return [
-        { label: "入库", value: "import" },
-        { label: "接入", value: "access" },
-      ];
-    },
   },
   data() {
     return {
-      cockpitTableBodyHeight: COCKPIT_TABLE_BODY_HEIGHT,
-      inboundTab: "import",
       onrelevance: "",
       abnormal: "",
       queueNumber: "",
@@ -522,8 +398,8 @@ export default {
         },
       ],
       hometopcolumnWidths: {
-        windFarmName: "42%",
-        canAnalysis: "auto",
+        windFarmName: 130,
+        canAnalysis: 150,
       },
       ListtableData: [],
       startDate: "",
@@ -534,22 +410,27 @@ export default {
     };
   },
   created() {
-    if (this.showTaskBlock) {
-      this.getbacklog();
-    }
-    if (this.showInboundBlock) {
-      this.ruku();
-    }
+    this.getbacklog();
+    this.ruku();
+    // this.hometop();
+  },
+  computed: {
+    filteredWindList() {
+      return this.searchvalue
+        ? this.windList.filter((item) =>
+            item.windFarmName.includes(this.searchvalue),
+          )
+        : this.windList;
+    },
   },
+
+  // 在线版本 离线需要注释
   mounted() {
-    if (this.shouldPollInbound) {
-      this.startPolling();
-    }
+    this.startPolling();
   },
+  // 在线版本 离线需要注释
   beforeDestroy() {
-    if (this.shouldPollInbound) {
-      this.stopPolling();
-    }
+    this.stopPolling();
   },
   methods: {
     getbacklog() {
@@ -679,13 +560,6 @@ export default {
           console.error("Error fetching data:", error);
         });
     },
-    onInboundChevronClick() {
-      if (this.inboundTab === "import") {
-        this.more();
-      } else {
-        this.onlinedata();
-      }
-    },
     importdata() {
       window.open(this.$router.resolve({ path: "/transition" }).href, "_blank");
     },
@@ -796,28 +670,22 @@ export default {
 
 <style lang="scss" scoped>
 .backbone {
-  width: 100%;
-  color: inherit;
-  border-radius: 0;
-}
-
-.backbone--flat .BOXYI,
-.backbone--flat .BOX {
-  background: transparent !important;
-  padding-left: 0 !important;
-  padding-right: 0 !important;
-  margin-bottom: 0 !important;
-  color: inherit !important;
+  width: 300px;
+  color: #fff;
+  border-radius: 5px;
+  //   padding: 20px;
 }
 
 .BOXYI {
-  background: transparent;
+  background: var(--cockpit-panel-inner-bg, rgba(0, 79, 95, 0.8));
   display: flex;
   flex-wrap: wrap;
-  padding: 0;
-  color: inherit;
-  border-radius: 0;
-  margin-bottom: 0;
+  padding-left: 10px;
+  padding-right: 10px;
+  padding-bottom: 15px;
+  color: #fff;
+  border-radius: 5px;
+  margin-bottom: 10px;
 
   .BOXsan {
     width: 100%;
@@ -838,7 +706,7 @@ export default {
       strong {
         display: block;
         font-size: 26px;
-        color: #4bffff;
+        color: var(--cockpit-accent-color, #4bffff);
       }
 
       span {
@@ -870,7 +738,7 @@ export default {
       strong {
         display: block;
         font-size: 26px;
-        color: #4bffff;
+        color: var(--cockpit-accent-color, #4bffff);
       }
 
       span {
@@ -902,7 +770,7 @@ export default {
       strong {
         display: block;
         font-size: 26px;
-        color: #4bffff;
+        color: var(--cockpit-accent-color, #4bffff);
       }
 
       span {
@@ -919,22 +787,24 @@ export default {
 }
 
 .BOX {
-  background: transparent;
+  background: var(--cockpit-panel-inner-bg, rgba(0, 79, 95, 0.8));
   display: flex;
-  padding-left: 0;
+  padding-left: 10px;
   flex-wrap: wrap;
-  padding-bottom: 8px;
-  color: inherit;
-  border-radius: 0;
-  margin-bottom: 0;
+  padding-bottom: 15px;
+  color: #fff;
+  border-radius: 5px;
+  margin-bottom: 10px;
+
+  h3 {
+    margin-top: 5px;
+  }
 
   .centeredh3 {
     width: 100%;
     display: flex;
     justify-content: space-between;
     margin-bottom: 5px;
-    border-bottom: none;
-    padding-bottom: 0;
 
     span {
       font-size: 12px;
@@ -947,31 +817,31 @@ export default {
   font-size: 12px;
 }
 
-.cockpit-inbound-panel ::v-deep .el-table__body .el-table__cell {
-  padding: 0 !important;
+::v-deep.el-table__cell {
+  padding: 2px 0 !important;
 }
 
-.cockpit-inbound-panel ::v-deep .el-table__body .el-table__cell .cell {
-  padding-top: 0 !important;
-  padding-bottom: 0 !important;
-  padding-left: var(--cockpit-td-padding-x, 8px) !important;
-  padding-right: var(--cockpit-td-padding-x, 8px) !important;
+::v-deep.el-table .el-table__cell {
+  padding: 2px 0 !important;
 }
 
 ::v-deep.el-table--scrollable-y .el-table__body-wrapper {
   overflow-y: clip !important;
 }
 
-.titleYC:not(.cockpit-unified-table-head) span:nth-child(1) {
-  margin: 0 70px 0 10px;
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
+.titleYC {
+  font-size: 14px;
+  background: var(--cockpit-table-header-bg, #214e5d);
+  padding: 5px 0;
+
+  span:nth-child(1) {
+    margin: 0 70px 0 10px;
+  }
 }
 
 .titleJQ {
   font-size: 14px;
-  background: #214e5d;
+  background: var(--cockpit-table-header-bg, #214e5d);
   padding: 5px 0;
 
   span:nth-child(1) {
@@ -998,7 +868,7 @@ export default {
 
 /* 滚动条样式 */
 ::v-deep .el-table__body-wrapper::-webkit-scrollbar-track {
-  background-color: #004f5f;
+  background-color: var(--cockpit-table-track-bg, #004f5f);
 }
 
 ::v-deep .el-table__body-wrapper::-webkit-scrollbar {
@@ -1027,7 +897,7 @@ export default {
 
 /* 滚动条样式 */
 ::v-deep .el-table__body-wrapper::-webkit-scrollbar-track {
-  background-color: #004f5f;
+  background-color: var(--cockpit-table-track-bg, #004f5f);
 }
 
 ::v-deep .el-table__body-wrapper::-webkit-scrollbar {

+ 169 - 208
src/views/admin/cockpitManage/component/rightdata.vue

@@ -1,6 +1,6 @@
 <template>
-  <div class="backbone" :class="{ 'backbone--flat': panel !== 'all' }">
-    <div v-if="showAnalysis">
+  <div class="backbone">
+    <div>
       <h3>风场分析完成率</h3>
       <el-date-picker
         size="mini"
@@ -11,60 +11,60 @@
         start-placeholder="开始日期"
         end-placeholder="结束日期"
         @change="onDateChange"
-      />
-      <div ref="chartRef" class="cockpit-analysis-chart"></div>
-    </div>
-
-    <div v-if="showHistory" class="cockpit-history-block">
-      <h3 class="cockpit-section-title">历史操作记录</h3>
-      <div
-        class="cockpit-scroll-table cockpit-table-block cockpit-unified-table cockpit-unified-table--history"
       >
-        <p
-          class="titleJQ cockpit-unified-table-head cockpit-unified-table-head--history"
-        >
-          <span>名字</span><span>日期</span><span>操作记录</span>
-        </p>
-        <Tabroll
-          :table-data="tableData"
-          :shujuloading="shujuloading"
-          :columns="tableColumns"
-          :max-height="tableBodyHeight"
-          :column-widths="historyColumnWidths"
-        />
-      </div>
+      </el-date-picker>
+      <div id="main" style="width: 260px; height: 160px"></div>
     </div>
 
-    <div v-if="showEquipment">
+    <div>
+      <h3 style="margin-bottom: 8px">历史操作记录</h3>
+      <p class="titleJQ">
+        <span>名字</span><span>日期</span><span>操作记录</span>
+      </p>
+      <Tabroll
+        :table-data="tableData"
+        :shujuloading="shujuloading"
+        :columns="tableColumns"
+        :max-height="120"
+        :column-widths="columnWidths"
+      ></Tabroll>
+    </div>
+    <div>
       <h3>风机异常概览</h3>
       <div class="BOX">
         <div style="display: flex">
           <div class="YC01">
-            <strong>{{
-              equipment?.errCounrt ? equipment.errCounrt : 0
-            }}</strong>
+            <strong>
+              {{ equipment?.errCounrt ? equipment.errCounrt : 0 }}</strong
+            >
             <span>异常总数</span>
           </div>
           <div class="YC02">
-            <strong>{{
-              equipment?.errCountInCurrentMonth
-                ? equipment.errCountInCurrentMonth
-                : 0
-            }}</strong>
+            <strong>
+              {{
+                equipment?.errCountInCurrentMonth
+                  ? equipment.errCountInCurrentMonth
+                  : 0
+              }}</strong
+            >
             <span>本月异常</span>
           </div>
         </div>
         <div style="display: flex">
           <div class="YC02">
-            <strong class="textred">{{
-              equipment?.errCountNotDeal ? equipment.errCountNotDeal : 0
-            }}</strong>
+            <strong class="textred">
+              {{
+                equipment?.errCountNotDeal ? equipment.errCountNotDeal : 0
+              }}</strong
+            >
             <span>未处理异常</span>
           </div>
           <div class="YC02">
-            <strong class="texyellow">{{
-              equipment?.errDeviceCount ? equipment.errDeviceCount : 0
-            }}</strong>
+            <strong class="texyellow">
+              {{
+                equipment?.errDeviceCount ? equipment.errDeviceCount : 0
+              }}</strong
+            >
             <span>异常设备数</span>
           </div>
           <div class="YC03"></div>
@@ -72,15 +72,8 @@
       </div>
     </div>
 
-    <div
-      v-if="showEquipmentTable"
-      class="cockpit-equipment-table-block"
-      :class="{
-        'cockpit-equipment-table-block--stacked':
-          panel === 'equipment-abnormal',
-      }"
-    >
-      <h3 class="cockpit-section-title">异常数据信息</h3>
+    <div>
+      <h3 style="margin: 8px 0">异常数据信息</h3>
       <p class="titleYC"><span>风场名称</span><span>风机信息</span></p>
       <Tabroll
         :table-data="YCtableData"
@@ -88,7 +81,7 @@
         :columns="YCtableColumns"
         :column-widths="YCcolumnWidths"
         :max-height="120"
-      />
+      ></Tabroll>
     </div>
   </div>
 </template>
@@ -97,36 +90,54 @@
 import { queryStatistics, queryOptionRecords } from "@/api/ledger.js";
 import * as echarts from "echarts";
 import Tabroll from "./tabroll.vue";
-import { COCKPIT_TABLE_BODY_HEIGHT } from "./cockpitTableMetrics";
 
 export default {
   props: {
-    maplistArr: { type: Object, default: () => ({}) },
-    defaultdata: { type: Object, default: () => ({}) },
-    /** analysis | history | analysis-history | equipment | equipment-table | equipment-abnormal | all */
-    panel: { type: String, default: "all" },
+    maplistArr: {
+      type: Object,
+      default: () => ({}),
+    },
+    defaultdata: {
+      type: Object,
+      default: () => ({}),
+    },
+  },
+
+  watch: {
+    maplistArr: {
+      handler(newVal) {
+        if (Object.keys(newVal).length > 0) {
+          // 检查maplistArr是否有值
+          this.getStatistics();
+          this.getOptionRecords();
+        }
+      },
+      immediate: true, // 立即执行一次handler
+      deep: true, // 深度监听对象内部变化
+    },
+  },
+  components: {
+    Tabroll,
   },
-  components: { Tabroll },
   data() {
     return {
       myChart: null,
       YCtableData: [],
       shujuloading: false,
       YCtableColumns: [{ prop: "fieldName" }, { prop: "engineName" }],
-      YCcolumnWidths: { fieldName: 120 },
+      YCcolumnWidths: {
+        fieldName: 120,
+      },
       tableData: [],
       tableColumns: [
         { prop: "optionByName" },
         { prop: "createTime" },
         { prop: "optionContent" },
       ],
-      columnWidths: { optionByName: 60, createTime: 100 },
-      historyColumnWidths: {
-        optionByName: "28%",
-        createTime: "38%",
-        optionContent: "34%",
+      columnWidths: {
+        optionByName: 60,
+        createTime: 100,
       },
-      tableBodyHeight: COCKPIT_TABLE_BODY_HEIGHT,
       equipment: {
         analysisedCount: 0,
         analysisingCount: 0,
@@ -137,108 +148,50 @@ export default {
       endTime: "",
     };
   },
-  computed: {
-    showAnalysis() {
-      return (
-        this.panel === "all" ||
-        this.panel === "analysis" ||
-        this.panel === "analysis-history"
-      );
-    },
-    showHistory() {
-      return (
-        this.panel === "all" ||
-        this.panel === "history" ||
-        this.panel === "analysis-history"
-      );
-    },
-    showEquipment() {
-      return (
-        this.panel === "all" ||
-        this.panel === "equipment" ||
-        this.panel === "equipment-abnormal"
-      );
-    },
-    showEquipmentTable() {
-      return (
-        this.panel === "all" ||
-        this.panel === "equipment-table" ||
-        this.panel === "equipment-abnormal"
-      );
-    },
-  },
-  watch: {
-    maplistArr: {
-      handler(newVal) {
-        if (!newVal?.codeNumber) return;
-        if (
-          this.showAnalysis ||
-          this.showEquipment ||
-          this.showEquipmentTable
-        ) {
-          this.getStatistics();
-        }
-        if (this.showHistory) {
-          this.getOptionRecords();
-        }
-      },
-      immediate: true,
-      deep: true,
-    },
-  },
+  created() {},
   mounted() {
-    if (this.showAnalysis) {
-      const currentTime = new Date();
-      const halfYearAgo = new Date();
-      halfYearAgo.setMonth(currentTime.getMonth() - 6);
-      this.value1 = [halfYearAgo, currentTime];
-      this.startTime = this.$formatDate(halfYearAgo);
-      this.endTime = this.$formatDate(currentTime);
-      this.$nextTick(() => this.initChart());
-    }
-  },
-  beforeDestroy() {
-    if (this.myChart) {
-      this.myChart.dispose();
-      this.myChart = null;
-    }
+    this.initChart();
+    const currentTime = new Date();
+    const halfYearAgo = new Date();
+    halfYearAgo.setMonth(currentTime.getMonth() - 6);
+    this.value1 = [halfYearAgo, currentTime];
+    // 同时更新 startTime 和 endTime
+    this.startTime = this.$formatDate(halfYearAgo);
+    this.endTime = this.$formatDate(currentTime);
   },
   methods: {
     initChart() {
-      if (!this.$refs.chartRef) return;
-      this.myChart = echarts.init(this.$refs.chartRef);
+      var chartDom = document.getElementById("main");
+      this.myChart = echarts.init(chartDom);
       this.updateChart();
     },
     updateChart() {
-      if (!this.myChart) return;
-      this.myChart.setOption({
+      var option = {
         tooltip: {
           trigger: "item",
-          formatter(params) {
-            const percent = params.percent.toFixed(2) + "%";
+          formatter: function (params) {
+            var percent = params.percent.toFixed(2) + "%";
             return `${params.name}: ${params.value} (${percent})`;
           },
         },
         legend: {
           orient: "vertical",
-          left: 4,
-          top: "middle",
-          itemWidth: 10,
-          itemHeight: 10,
-          itemGap: 10,
-          textStyle: {
-            color: "rgba(183, 223, 245, 0.85)",
-            fontSize: 11,
-          },
+          left: "left",
+          top: "30%",
         },
         series: [
           {
             type: "pie",
-            radius: ["42%", "72%"],
+            radius: ["40%", "80%"],
             avoidLabelOverlap: false,
-            label: { show: false, position: "center" },
-            labelLine: { show: false },
-            center: ["62%", "50%"],
+            label: {
+              show: false,
+              position: "center",
+            },
+            labelLine: {
+              show: false,
+            },
+            center: ["60%", "50%"],
             data: [
               {
                 value: this.equipment.analysisedCount,
@@ -258,51 +211,41 @@ export default {
             ],
           },
         ],
-      });
+      };
+      this.myChart.setOption(option);
     },
+
     getStatistics() {
-      if (!this.maplistArr?.codeNumber) return;
       const startTime =
         this.startTime ||
         this.$formatDate(
-          new Date(new Date().setMonth(new Date().getMonth() - 6)),
-        );
-      const endTime = this.endTime || this.$formatDate(new Date());
-      queryStatistics({
+          new Date(new Date().setMonth(new Date().getMonth() - 6))
+        ); // 半年前的时间
+      const endTime = this.endTime || this.$formatDate(new Date()); // 当前时间
+      // halfYearAgo.setMonth(currentTime.getMonth() - 6)
+
+      let DataObject = {
         codeNumber: this.maplistArr.codeNumber,
         codeType: this.maplistArr.codeType,
-        startTime,
-        endTime,
-      }).then((res) => {
-        const data = res.data || {};
-        this.YCtableData = data.errList || [];
-        this.equipment = data;
-        this.$nextTick(() => {
-          if (this.showAnalysis) {
-            if (!this.myChart && this.$refs.chartRef) {
-              this.initChart();
-            } else {
-              this.updateChart();
-            }
-          }
-        });
+        startTime: startTime,
+        endTime: endTime,
+      };
+      queryStatistics(DataObject).then((res) => {
+        this.YCtableData = res.data.errList || [];
+        this.equipment = res.data || {};
+        this.updateChart(); // Update chart after data is received
       });
     },
     getOptionRecords() {
-      if (!this.maplistArr?.codeNumber) return;
-      this.shujuloading = true;
-      queryOptionRecords({
+      let DataObject = {
         codeNumber: this.maplistArr.codeNumber,
         codeType: this.maplistArr.codeType,
-      })
-        .then((res) => {
-          const list = res.data;
-          this.tableData = Array.isArray(list) ? list : list?.list || [];
-        })
-        .finally(() => {
-          this.shujuloading = false;
-        });
+      };
+      queryOptionRecords(DataObject).then((res) => {
+        this.tableData = res.data || [];
+      });
     },
+
     onDateChange(date) {
       if (Array.isArray(date)) {
         this.startTime = this.$formatDate(date[0]);
@@ -322,29 +265,21 @@ export default {
 
 <style lang="scss" scoped>
 .backbone {
-  width: 100%;
-  color: inherit;
-  background: transparent;
-  padding: 0;
-  border-radius: 0;
-}
-
-.backbone--flat .BOX {
-  background: transparent;
-  padding-left: 0;
-}
-
-.cockpit-analysis-chart {
-  width: 100%;
-  height: 160px;
+  width: 300px;
+  color: #fff;
+  background: var(--cockpit-panel-bg, rgba(0, 128, 128, 0.8));
+  // height: 100%;
+  // height: 95%;
+  border-radius: 5px;
+  padding: 20px;
 }
 
 .BOX {
-  background: transparent;
+  background: var(--cockpit-panel-inner-light, rgba(0, 79, 95, 0.6));
   display: flex;
-  padding-left: 0;
+  padding-left: 10px;
   flex-wrap: wrap;
-  padding-bottom: 8px;
+  padding-bottom: 15px;
 }
 
 .YC01 {
@@ -355,13 +290,13 @@ export default {
   background-repeat: no-repeat;
   background-position: center;
   margin-right: 15px;
-  margin-top: 8px;
+  margin-top: 15px;
   text-align: center;
 
   strong {
     display: block;
     font-size: 26px;
-    color: #4bffff;
+    color: var(--cockpit-accent-color, #4bffff);
   }
 
   span {
@@ -378,7 +313,7 @@ export default {
   background-repeat: no-repeat;
   background-position: center;
   margin-right: 15px;
-  margin-top: 8px;
+  margin-top: 15px;
   text-align: center;
 
   .textred {
@@ -392,7 +327,7 @@ export default {
   strong {
     display: block;
     font-size: 26px;
-    color: #4bffff;
+    color: var(--cockpit-accent-color, #4bffff);
   }
 
   span {
@@ -406,21 +341,47 @@ export default {
   height: 60px;
 }
 
-.titleYC span:nth-child(1) {
-  margin: 0 70px 0 10px;
+.Tabtab {
+  font-size: 12px;
+}
+
+::v-deep.el-table__cell {
+  padding: 2px 0 !important;
+}
+
+::v-deep.el-table .el-table__cell {
+  padding: 2px 0 !important;
 }
 
-.titleJQ:not(.cockpit-history-table-head) span:nth-child(1) {
-  margin: 0 15px 0 10px;
+::v-deep.el-table--scrollable-y .el-table__body-wrapper {
+  overflow-y: clip !important;
 }
 
-.titleJQ:not(.cockpit-history-table-head) span:nth-child(2) {
-  margin: 0 45px 0 30px;
+.titleYC {
+  font-size: 14px;
+  background: var(--cockpit-table-header-bg, #214e5d);
+  padding: 5px 0;
+
+  span:nth-child(1) {
+    margin: 0 70px 0 10px;
+  }
 }
 
-::v-deep .el-date-editor--datetimerange.el-input,
-::v-deep .el-date-editor--datetimerange.el-input__inner {
-  width: 100%;
-  max-width: 260px;
+.titleJQ {
+  font-size: 14px;
+  background: var(--cockpit-table-header-bg, #214e5d);
+  padding: 5px 0;
+
+  span:nth-child(1) {
+    margin: 0 15px 0 10px;
+  }
+
+  span:nth-child(2) {
+    margin: 0 45px 0 30px;
+  }
+}
+.el-date-editor--datetimerange.el-input,
+.el-date-editor--datetimerange.el-input__inner {
+  width: 250px;
 }
 </style>

+ 34 - 80
src/views/admin/cockpitManage/component/tabroll.vue

@@ -1,16 +1,16 @@
 <template>
-  <div class="tabroll-wrap cockpit-tabroll-table">
+  <div>
     <el-table
-      :show-header="false"
+    :show-header="false"
       v-loading="shujuloading"
       :data="tableData"
       :max-height="maxHeight"
       ref="shujuscroll_Table"
       strip
-      style="width: 100%"
       @mouseenter.native="shujuautoScroll(true)"
       @mouseleave.native="shujuautoScroll(false)"
       id="Tabtab"
+      :header-cell-style="{ backgroundColor: 'red' }"
     >
       <el-table-column
         v-for="(column, index) in columns"
@@ -18,16 +18,13 @@
         :prop="column.prop"
         :label="column.label"
         show-overflow-tooltip
-        :width="getColumnWidth(column.prop)"
-        :min-width="getColumnMinWidth(column.prop)"
-      />
+        :width="getColumnWidth(column.prop)" 
+      ></el-table-column>
     </el-table>
   </div>
 </template>
 
 <script>
-import { COCKPIT_TABLE_BODY_HEIGHT } from "./cockpitTableMetrics";
-
 export default {
   props: {
     tableData: {
@@ -48,7 +45,7 @@ export default {
     },
     maxHeight: {
       type: Number,
-      default: COCKPIT_TABLE_BODY_HEIGHT,
+      default: 150,
     },
     columnWidths: {
       type: Object,
@@ -60,60 +57,32 @@ export default {
     },
   },
   mounted() {
-    this.$nextTick(() => this.shujuautoScroll());
-  },
-  watch: {
-    tableData() {
-      this.$nextTick(() => {
-        this.shujuautoScroll(true);
-        this.shujuautoScroll();
-      });
-    },
+    this.shujuautoScroll();
   },
   beforeDestroy() {
     this.shujuautoScroll(true);
   },
   methods: {
     shujuautoScroll(stop) {
+      const table = this.$refs.shujuscroll_Table;
+      const divData = table.$refs.bodyWrapper;
       if (stop) {
         window.clearInterval(this.scrolltimer);
-        this.scrolltimer = null;
-        return;
-      }
-      const table = this.$refs.shujuscroll_Table;
-      const divData = table && table.$refs.bodyWrapper;
-      if (!divData || !this.tableData || this.tableData.length === 0) {
-        return;
-      }
-      if (divData.scrollHeight <= divData.clientHeight) {
-        return;
+      } else {
+        this.scrolltimer = window.setInterval(() => {
+          divData.scrollTop += 1;
+          if (
+            divData.clientHeight + divData.scrollTop ==
+            divData.scrollHeight
+          ) {
+            divData.scrollTop = 0;
+          }
+        }, 150);
       }
-      window.clearInterval(this.scrolltimer);
-      this.scrolltimer = window.setInterval(() => {
-        divData.scrollTop += 1;
-        if (
-          divData.clientHeight + divData.scrollTop >=
-          divData.scrollHeight
-        ) {
-          divData.scrollTop = 0;
-        }
-      }, 150);
     },
     getColumnWidth(prop) {
-      const w =
-        this.columnWidths[prop] ?? this.YCcolumnWidths[prop];
-      if (w == null || w === "auto") return undefined;
-      if (typeof w === "string" && w.endsWith("%")) return undefined;
-      if (typeof w === "string") return w;
-      return `${w}px`;
-    },
-    getColumnMinWidth(prop) {
-      const w =
-        this.columnWidths[prop] ?? this.YCcolumnWidths[prop];
-      if (typeof w === "string" && w.endsWith("%")) {
-        return w;
-      }
-      return undefined;
+      return this.columnWidths[prop] + 'px'; // 根据传入的属性(prop)获取对应的列宽度
+      return this.YCcolumnWidths[prop] + 'px'; // 根据传入的属性(prop)获取对应的列宽度
     },
     tableRowClassName({ row, rowIndex }) {
       if (rowIndex % 2 === 1) {
@@ -127,30 +96,12 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-.tabroll-wrap {
-  width: 100%;
-}
-
 #Tabtab {
-  width: 100% !important;
   font-size: 12px;
 }
 
-::v-deep #Tabtab .el-table__body,
-::v-deep #Tabtab .el-table__body-wrapper table {
-  width: 100% !important;
-  table-layout: fixed;
-}
-
-::v-deep .cockpit-tabroll-table .el-table__body .el-table__cell {
-  padding: 0 !important;
-}
-
-::v-deep .cockpit-tabroll-table .el-table__body .el-table__cell .cell {
-  padding-top: 0 !important;
-  padding-bottom: 0 !important;
-  padding-left: var(--cockpit-td-padding-x, 8px) !important;
-  padding-right: var(--cockpit-td-padding-x, 8px) !important;
+::v-deep.el-table .el-table__cell {
+  padding: 2px 0 !important;
 }
 
 /* 去掉最下面的那一条线 */
@@ -158,15 +109,18 @@ export default {
   height: 0px;
 }
 
-/* 自动滚动:隐藏滚动条 */
-::v-deep .cockpit-tabroll-table .el-table__body-wrapper {
-  scrollbar-width: none;
-  -ms-overflow-style: none;
+/* 滚动条样式 */
+::v-deep .el-table__body-wrapper::-webkit-scrollbar-track {
+  background-color: var(--cockpit-table-track-bg, #004f5f);
+}
+
+::v-deep .el-table__body-wrapper::-webkit-scrollbar {
+  width: 0px;
+  opacity: 0.5;
 }
 
-::v-deep .cockpit-tabroll-table .el-table__body-wrapper::-webkit-scrollbar {
-  width: 0 !important;
-  height: 0 !important;
-  display: none !important;
+::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb {
+  border-radius: 15px;
+  // background-color: rgba(0, 79, 95, 0.75);
 }
 </style>

+ 6 - 5
src/views/health/components/malfunction/bearing.vue

@@ -576,7 +576,7 @@ export default {
         }
       }
       &.is-normal .icon-wrap {
-        background: #008080;
+        background: var(--primary-color, #008080);
       }
       &.is-warning .icon-wrap {
         background: #e6a23c;
@@ -672,7 +672,7 @@ h4 {
       justify-content: center;
       flex-shrink: 0;
       &.is-success {
-        background: #008080;
+        background: var(--primary-color, #008080);
       }
       &.is-warning {
         background: #e6a23c;
@@ -812,7 +812,7 @@ h4 {
       background: currentColor;
     }
     &.is-normal {
-      color: #008080;
+      color: var(--primary-color, #008080);
     }
     &.is-warning {
       color: #e6a23c;
@@ -828,10 +828,11 @@ h4 {
   opacity: 1;
 }
 ::v-deep .el-carousel__indicator.is-active .el-carousel__button {
-  background-color: #24a166;
+  background-color: var(--primary-color, #008080);
 }
 ::v-deep .el-carousel__indicator:hover .el-carousel__button {
-  background-color: #24a166aa;
+  background-color: var(--primary-color, #008080);
+  opacity: 0.75;
 }
 ::v-deep .el-carousel__indicators--horizontal {
   bottom: -10px !important;

+ 6 - 5
src/views/health/components/malfunction/dissymmetry.vue

@@ -584,7 +584,7 @@ export default {
         }
       }
       &.is-normal .icon-wrap {
-        background: #008080;
+        background: var(--primary-color, #008080);
       }
       &.is-warning .icon-wrap {
         background: #e6a23c;
@@ -680,7 +680,7 @@ h4 {
       justify-content: center;
       flex-shrink: 0;
       &.is-success {
-        background: #008080;
+        background: var(--primary-color, #008080);
       }
       &.is-warning {
         background: #e6a23c;
@@ -820,7 +820,7 @@ h4 {
       background: currentColor;
     }
     &.is-normal {
-      color: #008080;
+      color: var(--primary-color, #008080);
     }
     &.is-warning {
       color: #e6a23c;
@@ -836,10 +836,11 @@ h4 {
   opacity: 1;
 }
 ::v-deep .el-carousel__indicator.is-active .el-carousel__button {
-  background-color: #24a166;
+  background-color: var(--primary-color, #008080);
 }
 ::v-deep .el-carousel__indicator:hover .el-carousel__button {
-  background-color: #24a166aa;
+  background-color: var(--primary-color, #008080);
+  opacity: 0.75;
 }
 ::v-deep .el-carousel__indicators--horizontal {
   bottom: -10px !important;

+ 6 - 5
src/views/health/components/malfunction/gear.vue

@@ -602,7 +602,7 @@ export default {
         }
       }
       &.is-normal .icon-wrap {
-        background: #008080;
+        background: var(--primary-color, #008080);
       }
       &.is-warning .icon-wrap {
         background: #e6a23c;
@@ -794,7 +794,7 @@ h4 {
       justify-content: center;
       flex-shrink: 0;
       &.is-success {
-        background: #008080;
+        background: var(--primary-color, #008080);
       }
       &.is-warning {
         background: #e6a23c;
@@ -994,7 +994,7 @@ h4 {
       background: currentColor;
     }
     &.is-normal {
-      color: #008080;
+      color: var(--primary-color, #008080);
     }
     &.is-warning {
       color: #e6a23c;
@@ -1011,10 +1011,11 @@ h4 {
   opacity: 1; /* Element UI 默认会用 opacity 控制,这里统一用背景色 */
 }
 ::v-deep .el-carousel__indicator.is-active .el-carousel__button {
-  background-color: #24a166; /* 激活:主色蓝(可改) */
+  background-color: var(--primary-color, #008080);
 }
 ::v-deep .el-carousel__indicator:hover .el-carousel__button {
-  background-color: #24a166aa; /* hover */
+  background-color: var(--primary-color, #008080);
+  opacity: 0.75;
 }
 ::v-deep .el-carousel__indicators--horizontal {
   bottom: -10px !important;

+ 6 - 5
src/views/health/components/malfunction/loose.vue

@@ -573,7 +573,7 @@ export default {
         }
       }
       &.is-normal .icon-wrap {
-        background: #008080;
+        background: var(--primary-color, #008080);
       }
       &.is-warning .icon-wrap {
         background: #e6a23c;
@@ -669,7 +669,7 @@ h4 {
       justify-content: center;
       flex-shrink: 0;
       &.is-success {
-        background: #008080;
+        background: var(--primary-color, #008080);
       }
       &.is-warning {
         background: #e6a23c;
@@ -809,7 +809,7 @@ h4 {
       background: currentColor;
     }
     &.is-normal {
-      color: #008080;
+      color: var(--primary-color, #008080);
     }
     &.is-warning {
       color: #e6a23c;
@@ -825,10 +825,11 @@ h4 {
   opacity: 1;
 }
 ::v-deep .el-carousel__indicator.is-active .el-carousel__button {
-  background-color: #24a166;
+  background-color: var(--primary-color, #008080);
 }
 ::v-deep .el-carousel__indicator:hover .el-carousel__button {
-  background-color: #24a166aa;
+  background-color: var(--primary-color, #008080);
+  opacity: 0.75;
 }
 ::v-deep .el-carousel__indicators--horizontal {
   bottom: -10px !important;

+ 6 - 5
src/views/health/components/malfunction/misalignment.vue

@@ -573,7 +573,7 @@ export default {
         }
       }
       &.is-normal .icon-wrap {
-        background: #008080;
+        background: var(--primary-color, #008080);
       }
       &.is-warning .icon-wrap {
         background: #e6a23c;
@@ -669,7 +669,7 @@ h4 {
       justify-content: center;
       flex-shrink: 0;
       &.is-success {
-        background: #008080;
+        background: var(--primary-color, #008080);
       }
       &.is-warning {
         background: #e6a23c;
@@ -809,7 +809,7 @@ h4 {
       background: currentColor;
     }
     &.is-normal {
-      color: #008080;
+      color: var(--primary-color, #008080);
     }
     &.is-warning {
       color: #e6a23c;
@@ -825,10 +825,11 @@ h4 {
   opacity: 1;
 }
 ::v-deep .el-carousel__indicator.is-active .el-carousel__button {
-  background-color: #24a166;
+  background-color: var(--primary-color, #008080);
 }
 ::v-deep .el-carousel__indicator:hover .el-carousel__button {
-  background-color: #24a166aa;
+  background-color: var(--primary-color, #008080);
+  opacity: 0.75;
 }
 ::v-deep .el-carousel__indicators--horizontal {
   bottom: -10px !important;

+ 114 - 0
src/views/health/components/malfunctionOld/Eecharts.vue

@@ -0,0 +1,114 @@
+<template>
+  <div ref="chartDom" style="width: 100%; height: 100%"></div>
+</template>
+
+<script>
+import * as echarts from "echarts";
+
+export default {
+  name: "LineChart",
+  props: {
+    xData: {
+      type: Array,
+      required: true,
+    },
+    yData: {
+      type: Array, // 二维数组
+      required: true,
+    },
+    yNames: {
+      type: Array,
+      required: true, // 只取第一个元素
+    },
+    yAxisName: {
+      type: String,
+      default: "",
+    },
+  },
+  data() {
+    return {
+      myChart: null,
+    };
+  },
+  mounted() {
+    this.initChart();
+  },
+  watch: {
+    xData: {
+      handler: "initChart",
+      deep: true,
+      immediate: true,
+    },
+    yData: {
+      handler: "initChart",
+      deep: true,
+      immediate: true,
+    },
+    yNames: {
+      handler: "initChart",
+      immediate: true,
+    },
+    yAxisName: {
+      handler: "initChart",
+      immediate: true,
+    },
+  },
+
+  methods: {
+    initChart() {
+      if (!this.$refs.chartDom) return;
+
+      if (!this.myChart) {
+        this.myChart = echarts.init(this.$refs.chartDom);
+      }
+
+      const colors = ["#02aae9", "#5470C6", "#3CB9B9", "#9966CC"]; // 颜色列表可以根据需要扩展
+
+      const series = this.yData.map((data, index) => ({
+        name: this.yNames[index] || `系列${index + 1}`,
+        type: "line",
+        data: data,
+        lineStyle: {
+          color: colors[index % colors.length],
+        },
+        itemStyle: {
+          color: colors[index % colors.length],
+        },
+      }));
+
+      const option = {
+        tooltip: {
+          trigger: "axis",
+        },
+        legend: {
+          data: this.yNames.slice(0, series.length),
+          top: 10,
+        },
+        grid: {
+          top: 40,
+          bottom: 0,
+          left: 40,
+          right: 20,
+          containLabel: true,
+        },
+        xAxis: {
+          type: "category",
+          data: this.xData,
+        },
+        yAxis: {
+          type: "value",
+          name: this.yAxisName,
+        },
+        series: series,
+        color: colors,
+      };
+
+      this.myChart.clear(); // ✅ 清除旧配置
+      this.myChart.setOption(option);
+    },
+  },
+};
+</script>
+
+<style scoped>
+</style>

+ 483 - 0
src/views/health/components/malfunctionOld/bearing.vue

@@ -0,0 +1,483 @@
+<template>
+  <div>
+    <div class="TopBox">
+      <div class="rightdiv">
+        <el-table
+          ref="multipleTable"
+          :data="tableData"
+          tooltip-effect="dark"
+          style="width: 100%"
+          height="250"
+        >
+          <!-- <el-table-column fixed type="selection" width="55"> </el-table-column> -->
+          <el-table-column
+            prop="timeStamp"
+            label="时间"
+            align="center"
+            width="150"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="samplingFrequency"
+            label="采样频率(Hz)"
+            align="center"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="rotationalSpeed"
+            label="转速(rpm)"
+            align="center"
+          >
+          </el-table-column>
+        </el-table>
+        <div class="fenye">
+          <p><span>状态码说明:</span>0正常,1报警,2危险,-1未定义</p>
+
+          <el-pagination
+            @current-change="handleCurrentChange"
+            :current-page="currentPage"
+            layout="total, prev, pager, next"
+            :total="totalCount"
+            :page-size="10"
+            small
+          ></el-pagination>
+        </div>
+      </div>
+      <div class="leftdiv">
+        <div class="stateBox">
+          <h4>轴承状态</h4>
+          <div class="state">
+            <p :style="{ backgroundColor: bearingStateColors.innerRing }">
+              轴承内圈状态
+            </p>
+            <p :style="{ backgroundColor: bearingStateColors.outerRing }">
+              轴承外圈状态
+            </p>
+            <p :style="{ backgroundColor: bearingStateColors.rollingElement }">
+              轴承滚动体状态
+            </p>
+            <p :style="{ backgroundColor: bearingStateColors.cage }">
+              轴承保持架状态
+            </p>
+          </div>
+          <el-button
+            type="primary"
+            size="small"
+            @click="automaticDiagnosis"
+            class="btn-auto"
+            :loading="loading"
+            >诊断</el-button
+          >
+        </div>
+
+        <div class="Btn">
+          <div style="height: 200px">
+            <bingTwo :statistics="statistics"> </bingTwo>
+          </div>
+
+          <div class="minp">
+            <p class="PText">
+              <span><i class="color1"></i>正常</span
+              ><span><i class="color2"></i>报警</span
+              ><span><i class="color3"></i>危险</span>
+            </p>
+
+            <h4>诊断步骤:</h4>
+            <p>1、选择振动测点与起止时间,点击“查询”;</p>
+            <!-- <p>2、对轴承“参数设置”输入相关信息;</p> -->
+            <p>2、点击“诊断”输出最终轴承状态结果。</p>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="bottomBox">
+      <div class="BtLeft">
+        <h4>轴承状态趋势图</h4>
+        <el-empty
+          v-if="this.xData.length === 0 || this.yData.length === 0"
+          description="暂无数据"
+          style="padding: 46px 0"
+        ></el-empty>
+        <Eecharts
+          v-else
+          style="height: 300px"
+          :xData="xData"
+          :yData="yData"
+          :yNames="[
+            '轴承内圈状态',
+            '轴承外圈状态',
+            '轴承滚动体状态',
+            '轴承保持架状态',
+          ]"
+          yAxisName="轴承故障状态"
+        ></Eecharts>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from "axios";
+import Eecharts from "./Eecharts.vue";
+import bingTwo from "./bingTwo.vue";
+import { cacheEntryPossiblyAdded } from "plotly.js-dist";
+export default {
+  components: { Eecharts, bingTwo },
+  props: {
+    codedata: {
+      type: Array,
+      default: () => [],
+    },
+    totalCount: {
+      type: Number,
+      default: 0,
+    },
+    totalPage: {
+      type: Number,
+      default: 0,
+    },
+    fieldCode: {
+      type: String,
+      default: "",
+    },
+    windTurbineNumber: {
+      type: String,
+      default: "",
+    },
+  },
+  data() {
+    return {
+      tableData: [],
+      // 添加新的数据属性用于绑定输入框的值
+      transmissionRatio: "",
+      bearingPitchDiameter: "",
+      rollingElementDiameter: "",
+      rollingElementCount: "",
+      contactAngle: "",
+      vibrationSpeedAlarmThreshold: "",
+      vibrationSpeedDangerThreshold: "",
+      envelopeTotalAlarmThreshold: "",
+      envelopeTotalDangerThreshold: "",
+      // 分页
+      currentPage: 1,
+      total: 1,
+      xData: [],
+      yData: [],
+      // 颜色判断
+      bearingStateColors: {
+        innerRing: "#80808057",
+        outerRing: "#80808057",
+        rollingElement: "#80808057",
+        cage: "#80808057",
+      },
+      hasError: false, // 标志是否已经显示过错误提示
+      result: {},
+      dialogVisible: false,
+      loading: false, // 控制加载状态
+      statistics: {},
+    };
+  },
+  created() {},
+  watch: {
+    codedata: {
+      handler(newVal) {
+        this.tableData = newVal;
+      },
+      immediate: true, // 组件创建时立刻执行一次
+      deep: true, // 如果 codedata 是复杂对象,建议加上
+    },
+  },
+
+  methods: {
+    toggleSelection(rows) {
+      if (rows) {
+        rows.forEach((row) => {
+          this.$refs.multipleTable.toggleRowSelection(row);
+        });
+      } else {
+        this.$refs.multipleTable.clearSelection();
+      }
+    },
+    handleSelectionChange(val) {
+      this.multipleSelection = val;
+    },
+    handleCurrentChange(val) {
+      console.log(`当前页: ${val}`);
+      setTimeout(() => {
+        this.automaticDiagnosis();
+      }, 500);
+      this.currentPage = val; // 子组件内部更新当前页
+      this.$emit("updatePage", this.currentPage); // 通知父组件,把当前页传出去
+    },
+
+    automaticDiagnosis() {
+      if (this.tableData.length === 0) {
+        this.$message.warning("当前没有数据,无法进行诊断");
+        this.loading = false; // 确保关闭 loading 状态
+        return; // 直接返回,不发请求
+      }
+      this.loading = true;
+      const ids = this.tableData
+        .map((item) => item.id)
+        .filter((id) => id !== undefined);
+
+      const params = {
+        windCode: this.fieldCode,
+        engine_code: this.windTurbineNumber,
+        autodiagType: "Bearing",
+        ids,
+      };
+
+      const autodiagType = params.autodiagType || "Bearing";
+
+      const loadingInstance = this.$loading({
+        lock: true,
+        text: "自动诊断中...",
+        spinner: "el-icon-loading",
+        background: "rgba(0, 0, 0, 0.7)",
+      });
+
+      axios
+        .post(`/AnalysisMulti/autodiag/${autodiagType}`, params)
+        .then((res) => {
+          if (res.data.code === 405) {
+            this.$message.warning(
+              res.data.message || "当前采集频率不适合进行诊断分析"
+            );
+            return; // 终止后续数据处理逻辑
+          }
+
+          const result = res.data.results;
+          this.statistics = res.data.statistics || {};
+          // x轴数据,时间戳
+          this.xData = this.tableData.map((item) => item.timeStamp);
+          // y轴数据,状态码二维数组
+          this.yData = [
+            result.BPFI?.status_codes || [],
+            result.BPFO?.status_codes || [],
+            result.BSF?.status_codes || [],
+            result.FTF?.status_codes || [],
+          ];
+
+          // 根据 max_status 设置颜色的函数
+          const setColor = (status) => {
+            switch (status) {
+              case 0:
+                return "#8ae359";
+              case 1:
+                return "#eecb5f";
+              case 2:
+                return "#f7715f";
+              default:
+                return "#80808057";
+            }
+          };
+
+          this.bearingStateColors.innerRing = setColor(
+            result.BPFI?.max_status || 0
+          );
+          this.bearingStateColors.outerRing = setColor(
+            result.BPFO?.max_status || 0
+          );
+          this.bearingStateColors.rollingElement = setColor(
+            result.BSF?.max_status || 0
+          );
+          this.bearingStateColors.cage = setColor(result.FTF?.max_status || 0);
+        })
+        .catch((err) => {
+          console.error("诊断失败:", err);
+        })
+        .finally(() => {
+          loadingInstance.close();
+          this.loading = false;
+        });
+    },
+
+    reset() {
+      // 重置状态
+      this.xData = [];
+      this.yData = [];
+      this.statistics = {};
+      this.bearingStateColors = {
+        innerRing: "#80808057",
+        outerRing: "#80808057",
+        rollingElement: "#80808057",
+        cage: "#80808057",
+      };
+      this.tableData = [];
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+h4 {
+  margin-bottom: 5px;
+  font-weight: 600;
+}
+
+.TopBox {
+  height: 280px;
+  display: flex;
+  justify-content: space-around;
+
+  .leftdiv {
+    width: 50%;
+    display: flex;
+    justify-content: space-around;
+
+    .stateBox {
+      .state {
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+        /* 整体居中 */
+        align-items: center;
+        height: 200px;
+        gap: 20px;
+
+        /* 控制间距 */
+        p {
+          width: 150px;
+          height: 40px;
+          background: rgb(227, 227, 227);
+          color: rgb(50, 50, 50);
+          text-align: center;
+          align-content: center;
+          font-weight: 600;
+        }
+      }
+
+      .btn-auto {
+        margin-top: 10px;
+        width: 100%;
+      }
+    }
+
+    .Btn {
+      width: 50%;
+      display: flex;
+      flex-direction: column;
+      /* 垂直排列 */
+      justify-content: space-between;
+      /* 顶部和底部对齐 */
+      min-height: 100px;
+      /* 确保容器有足够高度 */
+      margin: 10px 0;
+
+      .PText {
+        display: flex;
+        justify-content: space-around;
+
+        span {
+          display: flex;
+          align-items: center;
+
+          i {
+            width: 30px;
+            height: 15px;
+            margin-right: 5px;
+          }
+
+          .color1 {
+            background-color: #8ae359;
+          }
+
+          .color2 {
+            background-color: #eecb5f;
+          }
+
+          .color3 {
+            background-color: #f7715f;
+          }
+        }
+      }
+
+      margin: 10px 0;
+
+      .minp {
+        font-size: 12px;
+        margin-top: auto;
+        /* 自动推到最底部 */
+      }
+    }
+  }
+
+  .rightdiv {
+    width: 50%;
+
+    .fenye {
+      display: flex;
+      justify-content: space-between;
+      margin: 5px 0;
+      font-size: 11px;
+      line-height: 30px;
+
+      span {
+        font-weight: 600;
+      }
+    }
+  }
+}
+
+.bottomBox {
+  display: flex;
+  justify-content: space-around;
+  margin-top: 10px;
+
+  .BtLeft {
+    border: 1px solid rgb(231, 231, 231);
+    width: 100%;
+    padding: 10px;
+  }
+
+  .BtRight {
+    border: 1px solid rgb(231, 231, 231);
+    padding: 10px;
+
+    .BtRightDiv {
+      padding: 0 10px;
+
+      h4 {
+        font-size: 14px;
+      }
+
+      .BtRightP {
+        line-height: 30px;
+        font-size: 12px;
+        display: flex;
+        margin-bottom: 5px;
+        width: 50%;
+
+        span {
+          margin-left: 10px;
+
+          .el-input {
+            width: 100px;
+          }
+        }
+
+        .label-text {
+          width: 140px;
+        }
+      }
+
+      .canshu {
+        display: flex;
+        flex-wrap: wrap;
+        justify-content: space-between;
+      }
+    }
+  }
+
+  .dialog-footer {
+    margin-top: 20px;
+    text-align: right;
+  }
+}
+
+::v-deep .el-table__cell {
+  padding: 2px 0;
+  font-size: 12px;
+}
+</style>

+ 146 - 0
src/views/health/components/malfunctionOld/bing.vue

@@ -0,0 +1,146 @@
+<template>
+  <div ref="chartDom" style="width: 100%; height: 100%"></div>
+</template>
+
+<script>
+import * as echarts from "echarts";
+
+export default {
+  name: "EChartsComponent",
+
+  props: {
+    result: {
+      type: Object,
+      default: () => ({
+        normal: 0,
+        danger: 0,
+      }),
+    },
+  },
+
+  data() {
+    return {
+      myChart: null,
+    };
+  },
+
+  mounted() {
+    console.log(this.result, "this.result");
+
+    this.initChart(); // 初始化图表
+  },
+
+  watch: {
+    // 监听 result 的变化
+    result(newValue) {
+      console.log("result changed", newValue);
+      this.updateChart(newValue); // 更新图表
+    },
+  },
+
+  methods: {
+    initChart() {
+      const chartDom = this.$refs.chartDom;
+      this.myChart = echarts.init(chartDom);
+
+      const option = {
+        title: {
+          text: "状态统计图",
+          left: "center",
+          textStyle: {
+            fontSize: 14, // 设置字体大小
+            fontWeight: "600", // 可选,设置字体粗细
+            color: "#333", // 可选,设置字体颜色
+          },
+        },
+        tooltip: {
+          trigger: "item",
+          formatter: "{b}: {c} 次 ({d}%)", // 显示次数和百分比
+        },
+
+        series: [
+          {
+            name: "状态次数",
+            type: "pie",
+            radius: ["40%", "60%"], // 设置内外半径来形成圆环
+            data: [
+              { value: 0, name: "正常", itemStyle: { color: "#8AE359" } },
+              { value: 0, name: "危险", itemStyle: { color: "#EECB5F" } },
+            ],
+            emphasis: {
+              itemStyle: {
+                shadowBlur: 10,
+                shadowOffsetX: 0,
+                shadowColor: "rgba(0, 0, 0, 0.5)",
+              },
+            },
+            label: {
+              // formatter: "{b}: {c} 次", // 在图表中显示次数
+            },
+          },
+        ],
+      };
+
+      this.myChart.setOption(option);
+    },
+
+    // 更新图表方法
+    updateChart(newResult) {
+      console.log(newResult, "111111111111111111");
+
+      const option = {
+        title: {
+          text: "状态统计图",
+          left: "center",
+          textStyle: {
+            fontSize: 14, // 设置字体大小
+            fontWeight: "600", // 可选,设置字体粗细
+            color: "#333", // 可选,设置字体颜色
+          },
+        },
+        tooltip: {
+          trigger: "item",
+          // formatter: "{b}: {c} 次 ({d}%)", // 显示次数和百分比
+        },
+
+        series: [
+          {
+            name: "状态次数",
+            type: "pie",
+            radius: ["40%", "60%"], // 设置内外半径来形成圆环
+            data: [
+              {
+                value: this.result.normal || 0,
+                name: "正常",
+                itemStyle: { color: "#8AE359" },
+              },
+              {
+                value: this.result.danger || 0,
+                name: "危险",
+                itemStyle: { color: "#EECB5F" },
+              },
+            ],
+            emphasis: {
+              itemStyle: {
+                shadowBlur: 10,
+                shadowOffsetX: 0,
+                shadowColor: "rgba(0, 0, 0, 0.5)",
+              },
+            },
+            label: {
+              // formatter: "{b}: {c} 次", // 在图表中显示次数
+            },
+          },
+        ],
+      };
+
+      // 更新图表
+      this.myChart.setOption(option);
+    },
+  },
+};
+</script>
+
+<style scoped>
+/* 可根据需求添加样式 */
+</style>

+ 154 - 0
src/views/health/components/malfunctionOld/bingTwo.vue

@@ -0,0 +1,154 @@
+<template>
+  <div ref="chartDom" style="width: 100%; height: 100%"></div>
+</template>
+
+<script>
+import * as echarts from "echarts";
+
+export default {
+  name: "EChartsComponent",
+
+  props: {
+    statistics: {
+      type: Object,
+      default: () => ({
+        normal: 0,
+        danger: 0,
+      }),
+    },
+  },
+
+  data() {
+    return {
+      myChart: null,
+    };
+  },
+
+  mounted() {
+    console.log(this.statistics, "this.statistics");
+
+    this.initChart(); // 初始化图表
+  },
+
+  watch: {
+    // 监听 statistics 的变化
+    statistics(newValue) {
+      console.log("statistics changed", newValue);
+      this.updateChart(newValue); // 更新图表
+    },
+  },
+
+  methods: {
+    initChart() {
+      const chartDom = this.$refs.chartDom;
+      this.myChart = echarts.init(chartDom);
+
+      const option = {
+        title: {
+          text: "状态统计图",
+          left: "center",
+          textStyle: {
+            fontSize: 14, // 设置字体大小
+            fontWeight: "600", // 可选,设置字体粗细
+            color: "#333", // 可选,设置字体颜色
+          },
+        },
+        tooltip: {
+          trigger: "item",
+          formatter: "{b}: {c} 次 ({d}%)", // 显示次数和百分比
+        },
+
+        series: [
+          {
+            name: "状态次数",
+            type: "pie",
+            radius: ["40%", "60%"], // 设置内外半径来形成圆环
+            data: [
+              { value: 0, name: "正常", itemStyle: { color: "#8AE359" } },
+              { value: 0, name: "报警", itemStyle: { color: "#EECB5F" } },
+              { value: 0, name: "危险", itemStyle: { color: "#f7715f " } },
+            ],
+            emphasis: {
+              itemStyle: {
+                shadowBlur: 10,
+                shadowOffsetX: 0,
+                shadowColor: "rgba(0, 0, 0, 0.5)",
+              },
+            },
+            label: {
+              // formatter: "{b}: {c} 次", // 在图表中显示次数
+            },
+          },
+        ],
+      };
+
+      this.myChart.setOption(option);
+    },
+
+    // 更新图表方法
+    updateChart(newResult) {
+      console.log(newResult, "111111111111111111");
+
+      const option = {
+        title: {
+          text: "状态统计图",
+          left: "center",
+          textStyle: {
+            fontSize: 14, // 设置字体大小
+            fontWeight: "600", // 可选,设置字体粗细
+            color: "#333", // 可选,设置字体颜色
+          },
+        },
+        tooltip: {
+          trigger: "item",
+          // formatter: "{b}: {c} 次 ({d}%)", // 显示次数和百分比
+        },
+
+        series: [
+          {
+            name: "状态次数",
+            type: "pie",
+            radius: ["40%", "60%"], // 设置内外半径来形成圆环
+            data: [
+              {
+                value: this.statistics.count_0 || 0,
+                name: "正常",
+                itemStyle: { color: "#8AE359" },
+              },
+              {
+                value: this.statistics.count_1 || 0,
+                name: "报警",
+                itemStyle: { color: " #EECB5F" },
+              },
+              {
+          
+
+                value: this.statistics.count_2 || 0,
+                name: "危险",
+                itemStyle: { color: " #f7715f " },
+              },
+            ],
+            emphasis: {
+              itemStyle: {
+                shadowBlur: 10,
+                shadowOffsetX: 0,
+                shadowColor: "rgba(0, 0, 0, 0.5)",
+              },
+            },
+            label: {
+              // formatter: "{b}: {c} 次", // 在图表中显示次数
+            },
+          },
+        ],
+      };
+
+      // 更新图表
+      this.myChart.setOption(option);
+    },
+  },
+};
+</script>
+
+<style scoped>
+/* 可根据需求添加样式 */
+</style>

+ 432 - 0
src/views/health/components/malfunctionOld/dissymmetry.vue

@@ -0,0 +1,432 @@
+<template>
+  <div>
+    <div class="TopBox">
+      <div class="rightdiv">
+        <el-table
+          ref="multipleTable"
+          :data="tableData"
+          tooltip-effect="dark"
+          style="width: 100%"
+          height="250"
+        >
+          <!-- <el-table-column fixed type="selection" width="55"> </el-table-column> -->
+          <el-table-column
+            prop="timeStamp"
+            label="时间"
+            align="center"
+            width="150"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="samplingFrequency"
+            label="采样频率(Hz)"
+            align="center"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="rotationalSpeed"
+            label="转速(rpm)"
+            align="center"
+          >
+          </el-table-column>
+        </el-table>
+        <div class="fenye">
+          <p><span>状态码说明:</span>0正常,1报警,2危险,-1未定义</p>
+
+          <el-pagination
+            small
+            @current-change="handleCurrentChange"
+            :current-page="currentPage"
+            layout="total, prev, pager, next"
+            :total="totalCount"
+            :page-size="10"
+          ></el-pagination>
+        </div>
+      </div>
+
+      <div class="leftdiv">
+        <div class="stateBox">
+          <h4>不对中状态</h4>
+          <div class="state">
+            <p :style="{ backgroundColor: bearingStateColors.innerRing }">
+              不对中
+            </p>
+          </div>
+          <el-button
+            type="primary"
+            size="small"
+            @click="automaticDiagnosis"
+            class="btn-auto"
+            :loading="loading"
+            >诊断</el-button
+          >
+        </div>
+
+        <div class="Btn">
+          <div style="height: 200px">
+            <bingTwo :statistics="statistics"> </bingTwo>
+          </div>
+
+          <div class="minp">
+            <p class="PText">
+              <span><i class="color1"></i>正常</span
+              ><span><i class="color2"></i>报警</span
+              ><span><i class="color3"></i>危险</span>
+            </p>
+
+            <h4>诊断步骤:</h4>
+            <p>1、选择振动测点与起止时间,点击“查询;</p>
+            <p>2、点击“诊断”输出不对中状态结果。</p>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="bottomBox">
+      <div class="BtLeft">
+        <h4>不对中故障状态趋势图</h4>
+        <el-empty
+          v-if="this.xData.length === 0 || this.yData.length === 0"
+          description="暂无数据"
+          style="padding: 48px 0"
+        ></el-empty>
+        <Eecharts
+          v-else
+          style="height: 310px"
+          :xData="xData"
+          :yData="[yData]"
+          :yNames="['不对中故障']"
+          yAxisName="不对中故障状态"
+        ></Eecharts>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from "axios";
+import Eecharts from "./Eecharts.vue";
+import bingTwo from "./bingTwo.vue";
+import { cacheEntryPossiblyAdded, log10, promisify } from "plotly.js-dist";
+export default {
+  components: { Eecharts, bingTwo },
+  props: {
+    codedata: {
+      type: Array,
+      default: () => [],
+    },
+    totalCount: {
+      type: Number,
+      default: 0,
+    },
+    totalPage: {
+      type: Number,
+      default: 0,
+    },
+    fieldCode: {
+      type: String,
+      default: "",
+    },
+    windTurbineNumber: {
+      type: String,
+      default: "",
+    },
+  },
+  data() {
+    return {
+      tableData: [],
+      // 添加新的数据属性用于绑定输入框的值
+      transmissionRatio: "",
+      bearingPitchDiameter: "",
+      rollingElementDiameter: "",
+      rollingElementCount: "",
+      contactAngle: "",
+      vibrationSpeedAlarmThreshold: "",
+      vibrationSpeedDangerThreshold: "",
+      envelopeTotalAlarmThreshold: "",
+      envelopeTotalDangerThreshold: "",
+      // 分页
+
+      currentPage: 1,
+      total: 1,
+
+      xData: [],
+      yData: [],
+      // 颜色判断
+      bearingStateColors: {
+        innerRing: "#80808057",
+        outerRing: "#80808057",
+        rollingElement: "#80808057",
+        cage: "#80808057",
+      },
+      hasError: false, // 标志是否已经显示过错误提示
+      statistics: {},
+      dialogVisible: false,
+      results: [],
+      loading: false, // 控制加载状态
+    };
+  },
+  created() {},
+  watch: {
+    codedata: {
+      handler(newVal) {
+        this.tableData = newVal;
+      },
+      immediate: true, // 组件创建时立刻执行一次
+      deep: true, // 如果 codedata 是复杂对象,建议加上
+    },
+  },
+
+  methods: {
+    toggleSelection(rows) {
+      if (rows) {
+        rows.forEach((row) => {
+          this.$refs.multipleTable.toggleRowSelection(row);
+        });
+      } else {
+        this.$refs.multipleTable.clearSelection();
+      }
+    },
+    handleSelectionChange(val) {
+      this.multipleSelection = val;
+    },
+    handleCurrentChange(val) {
+      console.log(`当前页: ${val}`);
+      setTimeout(() => {
+        this.automaticDiagnosis();
+      }, 500);
+
+      this.currentPage = val; // 子组件内部更新当前页
+      this.$emit("updatePage", this.currentPage); // 通知父组件,把当前页传出去
+    },
+    automaticDiagnosis() {
+      if (this.tableData.length === 0) {
+        this.$message.warning("当前没有数据,无法进行诊断");
+        this.loading = false; // 确保关闭 loading 状态
+        return; // 直接返回,不发请求
+      }
+
+      this.loading = true;
+      const ids = this.tableData
+        .map((item) => item.id)
+        .filter((id) => id !== undefined);
+      const params = {
+        windCode: this.fieldCode,
+        engine_code: this.windTurbineNumber,
+        autodiagType: "Misalignment",
+        ids: ids,
+      };
+      const autodiagType = params.autodiagType || "Misalignment";
+
+      const loadingInstance = this.$loading({
+        lock: true,
+        text: "自动诊断中...",
+        spinner: "el-icon-loading",
+        background: "rgba(0, 0, 0, 0.7)",
+      });
+
+      axios
+        .post(`/AnalysisMulti/autodiag/${autodiagType}`, params)
+        .then((res) => {
+          if (res.data.code === 405) {
+            this.$message.warning({
+              message: "当前采集频率不适合进行诊断分析",
+              duration: 2000,
+            });
+            return; // 停止继续处理数据
+          }
+          this.statistics = res.data.statistics;
+          this.$set(this, "yData", [...res.data.results]);
+          this.$set(
+            this,
+            "xData",
+            this.tableData.map((item) => item.timeStamp)
+          );
+          console.log(this.yData, "yData11");
+          console.log(this.xData, "xData22");
+
+          const maxStatus = res.data.statistics.max_status;
+          if (maxStatus === 0) {
+            this.bearingStateColors.innerRing = "#8ae359";
+          } else if (maxStatus === 1) {
+            this.bearingStateColors.innerRing = "#eecb5f";
+          } else if (maxStatus === 2) {
+            this.bearingStateColors.innerRing = "#f7715f";
+          } else {
+            this.bearingStateColors.innerRing = "#80808057";
+          }
+
+          this.$message.success({
+            message: "诊断完成",
+            duration: 1000, // 1秒后自动关闭
+          });
+        })
+        .catch((error) => {
+          console.error("自动诊断失败:", error);
+          this.bearingStateColors.innerRing = "#80808057";
+          this.$message.error({
+            message: "诊断失败",
+            duration: 1000, // 1秒后自动关闭
+          });
+        })
+        .finally(() => {
+          loadingInstance.close();
+          this.loading = false;
+        });
+    },
+
+    reset() {
+      this.tableData = [];
+      this.xData = [];
+      this.yData = [];
+      this.statistics = {};
+      this.bearingStateColors = {
+        innerRing: "#80808057",
+        outerRing: "#80808057",
+        rollingElement: "#80808057",
+        cage: "#80808057",
+      };
+      this.currentPage = 1;
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+h4 {
+  margin-bottom: 5px;
+  font-weight: 600;
+}
+.TopBox {
+  height: 280px;
+  display: flex;
+  justify-content: space-around;
+  .leftdiv {
+    width: 50%;
+    display: flex;
+    justify-content: space-around;
+    .stateBox {
+      .state {
+        display: flex;
+        flex-direction: column;
+        justify-content: center; /* 整体居中 */
+        align-items: center;
+        height: 200px;
+        gap: 20px; /* 控制间距 */
+        p {
+          width: 150px;
+          height: 40px;
+          background: rgb(227, 227, 227);
+          color: rgb(50, 50, 50);
+          text-align: center;
+          align-content: center;
+          font-weight: 600;
+        }
+      }
+      .btn-auto {
+        margin-top: 10px;
+        width: 100%;
+      }
+    }
+    .Btn {
+      width: 50%;
+      display: flex;
+      flex-direction: column; /* 垂直排列 */
+      justify-content: space-between; /* 顶部和底部对齐 */
+      min-height: 100px; /* 确保容器有足够高度 */
+      margin: 10px 0;
+      .PText {
+        display: flex;
+        justify-content: space-around;
+
+        span {
+          display: flex;
+          align-items: center;
+          i {
+            width: 30px;
+            height: 15px;
+            margin-right: 5px;
+          }
+          .color1 {
+            background-color: #8ae359;
+          }
+          .color2 {
+            background-color: #eecb5f;
+          }
+          .color3 {
+            background-color: #f7715f;
+          }
+        }
+      }
+      margin: 10px 0;
+      .minp {
+        font-size: 12px;
+        margin-top: auto; /* 自动推到最底部 */
+      }
+    }
+  }
+  .rightdiv {
+    width: 50%;
+    .fenye {
+      display: flex;
+      justify-content: space-between;
+      margin: 5px 0;
+      font-size: 11px;
+      line-height: 30px;
+      span {
+        font-weight: 600;
+      }
+    }
+  }
+}
+
+.bottomBox {
+  display: flex;
+  justify-content: space-around;
+  margin-top: 10px;
+  .BtLeft {
+    border: 1px solid rgb(231, 231, 231);
+    width: 100%;
+    padding: 10px;
+  }
+  .BtRight {
+    // width: 49%;
+    border: 1px solid rgb(231, 231, 231);
+    padding: 10px;
+    .BtRightDiv {
+      padding: 0 10px;
+      h4 {
+        font-size: 14px;
+      }
+      .BtRightP {
+        line-height: 30px;
+        font-size: 12px;
+        display: flex;
+        margin-bottom: 5px;
+        width: 50%;
+        span {
+          margin-left: 10px;
+          .el-input {
+            width: 100px;
+          }
+        }
+        .label-text {
+          width: 140px;
+        }
+      }
+      .canshu {
+        display: flex;
+        flex-wrap: wrap;
+        justify-content: space-between;
+      }
+    }
+  }
+  .dialog-footer {
+    margin-top: 20px;
+    text-align: right;
+  }
+}
+::v-deep .el-table__cell {
+  padding: 2px 0;
+  font-size: 12px;
+}
+</style>

+ 475 - 0
src/views/health/components/malfunctionOld/gear.vue

@@ -0,0 +1,475 @@
+<template>
+  <div>
+    <div class="TopBox">
+      <div class="rightdiv">
+        <el-table
+          ref="multipleTable"
+          :data="tableData"
+          tooltip-effect="dark"
+          style="width: 100%"
+          height="250"
+        >
+          <!-- <el-table-column fixed type="selection" width="55"> </el-table-column> -->
+          <el-table-column
+            prop="timeStamp"
+            label="时间"
+            align="center"
+            width="150"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="samplingFrequency"
+            label="采样频率(Hz)"
+            align="center"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="rotationalSpeed"
+            label="转速(rpm)"
+            align="center"
+          >
+          </el-table-column>
+        </el-table>
+        <div class="fenye">
+          <p><span>状态码说明:</span>0正常,1报警,2危险,-1未定义</p>
+
+          <el-pagination
+            @current-change="handleCurrentChange"
+            :current-page="currentPage"
+            layout="total, prev, pager, next"
+            :total="totalCount"
+            :page-size="10"
+            small
+          ></el-pagination>
+        </div>
+      </div>
+      <div class="leftdiv">
+        <div class="stateBox">
+          <h4>齿轮状态</h4>
+          <div class="state">
+            <p :style="{ backgroundColor: bearingStateColors.innerRing }">
+              齿轮磨损
+            </p>
+            <p :style="{ backgroundColor: bearingStateColors.outerRing }">
+              齿轮断齿
+            </p>
+          </div>
+          <el-button
+            type="primary"
+            size="small"
+            @click="automaticDiagnosis"
+            class="btn-auto"
+            :loading="loading"
+            >诊断</el-button
+          >
+        </div>
+
+        <div class="Btn">
+          <div style="height: 200px">
+            <bingTwo :statistics="statistics"> </bingTwo>
+          </div>
+
+          <div class="minp">
+            <p class="PText">
+              <span><i class="color1"></i>正常</span
+              ><span><i class="color2"></i>报警</span
+              ><span><i class="color3"></i>危险</span>
+            </p>
+
+            <h4>诊断步骤:</h4>
+            <p>1、选择振动测点与起止时间,点击“查询”;</p>
+            <!-- <p>2、对齿轮“参数设置”输入相关信息;</p> -->
+            <p>2、点击“诊断”输出最终齿轮状态结果。</p>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="bottomBox">
+      <div class="BtLeft">
+        <h4>齿轮状态趋势图</h4>
+        <el-empty
+          v-if="this.xData.length === 0 || this.yData.length === 0"
+          description="暂无数据"
+          style="padding: 46px 0"
+        ></el-empty>
+        <Eecharts
+          v-else
+          style="height: 300px"
+          :xData="xData"
+          :yData="yData"
+          :yNames="['齿轮磨损', '齿轮断齿']"
+          yAxisName="齿轮故障状态"
+        ></Eecharts>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from "axios";
+import Eecharts from "./Eecharts.vue";
+import bingTwo from "./bingTwo.vue";
+import { cacheEntryPossiblyAdded } from "plotly.js-dist";
+export default {
+  components: { Eecharts, bingTwo },
+  props: {
+    codedata: {
+      type: Array,
+      default: () => [],
+    },
+    totalCount: {
+      type: Number,
+      default: 0,
+    },
+    totalPage: {
+      type: Number,
+      default: 0,
+    },
+    fieldCode: {
+      type: String,
+      default: "",
+    },
+    windTurbineNumber: {
+      type: String,
+      default: "",
+    },
+  },
+  data() {
+    return {
+      tableData: [],
+      // 添加新的数据属性用于绑定输入框的值
+      transmissionRatio: "",
+      bearingPitchDiameter: "",
+      rollingElementDiameter: "",
+      rollingElementCount: "",
+      contactAngle: "",
+      vibrationSpeedAlarmThreshold: "",
+      vibrationSpeedDangerThreshold: "",
+      envelopeTotalAlarmThreshold: "",
+      envelopeTotalDangerThreshold: "",
+      // 分页
+
+      currentPage: 1,
+      total: 1,
+
+      xData: [],
+      yData: [],
+      // 颜色判断
+      bearingStateColors: {
+        innerRing: "#80808057",
+        outerRing: "#80808057",
+        rollingElement: "#80808057",
+        cage: "#80808057",
+      },
+      hasError: false, // 标志是否已经显示过错误提示
+      result: {},
+      dialogVisible: false,
+      loading: false, // 控制加载状态
+      statistics: {},
+    };
+  },
+  created() {},
+  watch: {
+    codedata: {
+      handler(newVal) {
+        this.tableData = newVal;
+      },
+      immediate: true, // 组件创建时立刻执行一次
+      deep: true, // 如果 codedata 是复杂对象,建议加上
+    },
+  },
+
+  methods: {
+    toggleSelection(rows) {
+      if (rows) {
+        rows.forEach((row) => {
+          this.$refs.multipleTable.toggleRowSelection(row);
+        });
+      } else {
+        this.$refs.multipleTable.clearSelection();
+      }
+    },
+    handleSelectionChange(val) {
+      this.multipleSelection = val;
+    },
+    handleCurrentChange(val) {
+      console.log(`当前页: ${val}`);
+      setTimeout(() => {
+        this.automaticDiagnosis();
+      }, 500);
+      this.currentPage = val; // 子组件内部更新当前页
+      this.$emit("updatePage", this.currentPage); // 通知父组件,把当前页传出去
+    },
+
+    automaticDiagnosis() {
+      if (this.tableData.length === 0) {
+        this.$message.warning("当前没有数据,无法进行诊断");
+        this.loading = false; // 确保关闭 loading 状态
+        return; // 直接返回,不发请求
+      }
+      this.loading = true;
+      const ids = this.tableData
+        .map((item) => item.id)
+        .filter((id) => id !== undefined);
+
+      const params = {
+        windCode: this.fieldCode,
+        engine_code: this.windTurbineNumber,
+        autodiagType: "Gear",
+        ids,
+      };
+
+      const autodiagType = params.autodiagType || "Gear";
+
+      const loadingInstance = this.$loading({
+        lock: true,
+        text: "自动诊断中...",
+        spinner: "el-icon-loading",
+        background: "rgba(0, 0, 0, 0.7)",
+      });
+
+      axios
+        .post(`/AnalysisMulti/autodiag/${autodiagType}`, params)
+        .then((res) => {
+          if (res.data.code === 400) {
+            this.$message({
+              message: "当前测点无法进行齿轮箱诊断",
+              type: "warning",
+            });
+          } else if (res.data.code === 405) {
+            this.$message({
+              message: "当前采集频率不适合进行诊断分析",
+              type: "warning",
+            });
+          } else {
+            const result = res.data.results || {};
+            this.statistics = res.data.statistics || {};
+            // x轴数据,时间戳
+            this.xData = this.tableData.map((item) => item.timeStamp);
+            // y轴数据,状态码二维数组
+            this.yData = [
+              result.crack?.status_codes || [],
+              result.wear?.status_codes || [],
+            ];
+            // 设置颜色函数(根据 max_status)
+            const setColor = (status) => {
+              switch (status) {
+                case 0:
+                  return "#8ae359"; // 正常
+                case 1:
+                  return "#eecb5f"; // 报警
+                case 2:
+                  return "#f7715f"; // 危险
+                default:
+                  return "#80808057"; // 未知或缺失
+              }
+            };
+
+            // 根据 max_status 设置颜色
+            this.bearingStateColors.innerRing = setColor(
+              result.crack?.max_status ?? -1
+            );
+            this.bearingStateColors.outerRing = setColor(
+              result.wear?.max_status ?? -1
+            );
+          }
+        })
+
+        .catch((err) => {
+          console.error("诊断失败:", err);
+        })
+        .finally(() => {
+          loadingInstance.close();
+          this.loading = false;
+        });
+    },
+
+    reset() {
+      this.tableData = [];
+      this.xData = [];
+      this.yData = [];
+      this.statistics = {};
+      this.result = {};
+      this.currentPage = 1;
+      this.bearingStateColors = {
+        innerRing: "#80808057",
+        outerRing: "#80808057",
+        rollingElement: "#80808057",
+        cage: "#80808057",
+      };
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+h4 {
+  margin-bottom: 5px;
+  font-weight: 600;
+}
+
+.TopBox {
+  height: 280px;
+  display: flex;
+  justify-content: space-around;
+
+  .leftdiv {
+    width: 50%;
+    display: flex;
+    justify-content: space-around;
+
+    .stateBox {
+      .state {
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+        /* 整体居中 */
+        align-items: center;
+        height: 200px;
+        gap: 20px;
+
+        /* 控制间距 */
+        p {
+          width: 150px;
+          height: 40px;
+          background: rgb(227, 227, 227);
+          color: rgb(50, 50, 50);
+          text-align: center;
+          align-content: center;
+          font-weight: 600;
+        }
+      }
+
+      .btn-auto {
+        margin-top: 10px;
+        width: 100%;
+      }
+    }
+
+    .Btn {
+      width: 50%;
+      display: flex;
+      flex-direction: column;
+      /* 垂直排列 */
+      justify-content: space-between;
+      /* 顶部和底部对齐 */
+      min-height: 100px;
+      /* 确保容器有足够高度 */
+      margin: 10px 0;
+
+      .PText {
+        display: flex;
+        justify-content: space-around;
+
+        span {
+          display: flex;
+          align-items: center;
+
+          i {
+            width: 30px;
+            height: 15px;
+            margin-right: 5px;
+          }
+
+          .color1 {
+            background-color: #8ae359;
+          }
+
+          .color2 {
+            background-color: #eecb5f;
+          }
+
+          .color3 {
+            background-color: #f7715f;
+          }
+        }
+      }
+
+      margin: 10px 0;
+
+      .minp {
+        font-size: 12px;
+        margin-top: auto;
+        /* 自动推到最底部 */
+      }
+    }
+  }
+
+  .rightdiv {
+    width: 50%;
+
+    .fenye {
+      display: flex;
+      justify-content: space-between;
+      margin: 5px 0;
+      font-size: 11px;
+      line-height: 30px;
+
+      span {
+        font-weight: 600;
+      }
+    }
+  }
+}
+
+.bottomBox {
+  display: flex;
+  justify-content: space-around;
+  margin-top: 10px;
+
+  .BtLeft {
+    border: 1px solid rgb(231, 231, 231);
+    width: 100%;
+    padding: 10px;
+  }
+
+  .BtRight {
+    border: 1px solid rgb(231, 231, 231);
+    padding: 10px;
+
+    .BtRightDiv {
+      padding: 0 10px;
+
+      h4 {
+        font-size: 14px;
+      }
+
+      .BtRightP {
+        line-height: 30px;
+        font-size: 12px;
+        display: flex;
+        margin-bottom: 5px;
+        width: 50%;
+
+        span {
+          margin-left: 10px;
+
+          .el-input {
+            width: 100px;
+          }
+        }
+
+        .label-text {
+          width: 140px;
+        }
+      }
+
+      .canshu {
+        display: flex;
+        flex-wrap: wrap;
+        justify-content: space-between;
+      }
+    }
+  }
+
+  .dialog-footer {
+    margin-top: 20px;
+    text-align: right;
+  }
+}
+
+::v-deep .el-table__cell {
+  padding: 2px 0;
+  font-size: 12px;
+}
+</style>

+ 431 - 0
src/views/health/components/malfunctionOld/loose.vue

@@ -0,0 +1,431 @@
+<template>
+  <div>
+    <div class="TopBox">
+      <div class="rightdiv">
+        <el-table
+          ref="multipleTable"
+          :data="tableData"
+          tooltip-effect="dark"
+          style="width: 100%"
+          height="250"
+        >
+          <!-- <el-table-column fixed type="selection" width="55"> </el-table-column> -->
+          <el-table-column
+            prop="timeStamp"
+            label="时间"
+            align="center"
+            width="150"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="samplingFrequency"
+            label="采样频率(Hz)"
+            align="center"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="rotationalSpeed"
+            label="转速(rpm)"
+            align="center"
+          >
+          </el-table-column>
+        </el-table>
+        <div class="fenye">
+          <p><span>状态码说明:</span>0正常,1报警,2危险,-1未定义</p>
+
+          <el-pagination
+            small
+            @current-change="handleCurrentChange"
+            :current-page="currentPage"
+            layout="total, prev, pager, next"
+            :total="totalCount"
+            :page-size="10"
+          ></el-pagination>
+        </div>
+      </div>
+
+      <div class="leftdiv">
+        <div class="stateBox">
+          <h4>松动状态</h4>
+          <div class="state">
+            <p :style="{ backgroundColor: bearingStateColors.innerRing }">
+              松动
+            </p>
+          </div>
+          <el-button
+            type="primary"
+            size="small"
+            @click="automaticDiagnosis"
+            class="btn-auto"
+            :loading="loading"
+            >诊断</el-button
+          >
+        </div>
+
+        <div class="Btn">
+          <div style="height: 200px">
+            <bingTwo :statistics="statistics"> </bingTwo>
+          </div>
+
+          <div class="minp">
+            <p class="PText">
+              <span><i class="color1"></i>正常</span
+              ><span><i class="color2"></i>报警</span
+              ><span><i class="color3"></i>危险</span>
+            </p>
+
+            <h4>诊断步骤:</h4>
+            <p>1、选择振动测点与起止时间,点击“查询;</p>
+            <p>2、点击“诊断”输出松动状态结果。</p>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="bottomBox">
+      <div class="BtLeft">
+        <h4>松动故障状态趋势图</h4>
+        <el-empty
+          v-if="this.xData.length === 0 || this.yData.length === 0"
+          description="暂无数据"
+          style="padding: 48px 0"
+        ></el-empty>
+        <Eecharts
+          v-else
+          style="height: 310px"
+          :xData="xData"
+          :yData="[yData]"
+          :yNames="['松动故障']"
+          yAxisName="松动故障状态"
+        ></Eecharts>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from "axios";
+import Eecharts from "./Eecharts.vue";
+import bingTwo from "./bingTwo.vue";
+import { cacheEntryPossiblyAdded, log10, promisify } from "plotly.js-dist";
+export default {
+  components: { Eecharts, bingTwo },
+  props: {
+    codedata: {
+      type: Array,
+      default: () => [],
+    },
+    totalCount: {
+      type: Number,
+      default: 0,
+    },
+    totalPage: {
+      type: Number,
+      default: 0,
+    },
+    fieldCode: {
+      type: String,
+      default: "",
+    },
+    windTurbineNumber: {
+      type: String,
+      default: "",
+    },
+  },
+  data() {
+    return {
+      tableData: [],
+      // 添加新的数据属性用于绑定输入框的值
+      transmissionRatio: "",
+      bearingPitchDiameter: "",
+      rollingElementDiameter: "",
+      rollingElementCount: "",
+      contactAngle: "",
+      vibrationSpeedAlarmThreshold: "",
+      vibrationSpeedDangerThreshold: "",
+      envelopeTotalAlarmThreshold: "",
+      envelopeTotalDangerThreshold: "",
+      // 分页
+
+      currentPage: 1,
+      total: 1,
+
+      xData: [],
+      yData: [],
+      // 颜色判断
+      bearingStateColors: {
+        innerRing: "#80808057",
+        outerRing: "#80808057",
+        rollingElement: "#80808057",
+        cage: "#80808057",
+      },
+      hasError: false, // 标志是否已经显示过错误提示
+      statistics: {},
+      dialogVisible: false,
+      results: [],
+      loading: false, // 控制加载状态
+    };
+  },
+  created() {},
+  watch: {
+    codedata: {
+      handler(newVal) {
+        this.tableData = newVal;
+      },
+      immediate: true, // 组件创建时立刻执行一次
+      deep: true, // 如果 codedata 是复杂对象,建议加上
+    },
+  },
+
+  methods: {
+    toggleSelection(rows) {
+      if (rows) {
+        rows.forEach((row) => {
+          this.$refs.multipleTable.toggleRowSelection(row);
+        });
+      } else {
+        this.$refs.multipleTable.clearSelection();
+      }
+    },
+    handleSelectionChange(val) {
+      this.multipleSelection = val;
+    },
+    handleCurrentChange(val) {
+      console.log(`当前页: ${val}`);
+      setTimeout(() => {
+        this.automaticDiagnosis();
+      }, 500);
+
+      this.currentPage = val; // 子组件内部更新当前页
+      this.$emit("updatePage", this.currentPage); // 通知父组件,把当前页传出去
+    },
+    automaticDiagnosis() {
+      if (this.tableData.length === 0) {
+        this.$message.warning("当前没有数据,无法进行诊断");
+        this.loading = false; // 确保关闭 loading 状态
+        return; // 直接返回,不发请求
+      }
+      this.loading = true;
+      const ids = this.tableData
+        .map((item) => item.id)
+        .filter((id) => id !== undefined);
+      const params = {
+        windCode: this.fieldCode,
+        engine_code: this.windTurbineNumber,
+        autodiagType: "Looseness",
+        ids: ids,
+      };
+      const autodiagType = params.autodiagType || "Looseness";
+
+      const loadingInstance = this.$loading({
+        lock: true,
+        text: "自动诊断中...",
+        spinner: "el-icon-loading",
+        background: "rgba(0, 0, 0, 0.7)",
+      });
+
+      axios
+        .post(`/AnalysisMulti/autodiag/${autodiagType}`, params)
+        .then((res) => {
+          if (res.data.code === 405) {
+            this.$message.warning(
+              res.data.message || "当前采集频率不适合进行诊断分析"
+            );
+            return; // 终止后续数据处理逻辑
+          }
+
+          this.statistics = res.data.statistics;
+          this.$set(this, "yData", [...res.data.results]);
+          this.$set(
+            this,
+            "xData",
+            this.tableData.map((item) => item.timeStamp)
+          );
+          console.log(this.yData, "yData11");
+          console.log(this.xData, "xData22");
+
+          const maxStatus = res.data.statistics.max_status;
+          if (maxStatus === 0) {
+            this.bearingStateColors.innerRing = "#8ae359";
+          } else if (maxStatus === 1) {
+            this.bearingStateColors.innerRing = "#eecb5f";
+          } else if (maxStatus === 2) {
+            this.bearingStateColors.innerRing = "#f7715f";
+          } else {
+            this.bearingStateColors.innerRing = "#80808057";
+          }
+
+          this.$message.success({
+            message: "诊断完成",
+            duration: 1000, // 1秒后自动关闭
+          });
+        })
+        .catch((error) => {
+          console.error("自动诊断失败:", error);
+          this.bearingStateColors.innerRing = "#80808057";
+          this.$message.error({
+            message: "诊断失败",
+            duration: 1000, // 1秒后自动关闭
+          });
+        })
+        .finally(() => {
+          loadingInstance.close();
+          this.loading = false;
+        });
+    },
+
+    reset() {
+      // 重置状态
+      this.xData = [];
+      this.yData = [];
+      this.statistics = {};
+      this.bearingStateColors = {
+        innerRing: "#80808057",
+        outerRing: "#80808057",
+        rollingElement: "#80808057",
+        cage: "#80808057",
+      };
+      this.tableData = [];
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+h4 {
+  margin-bottom: 5px;
+  font-weight: 600;
+}
+.TopBox {
+  height: 280px;
+  display: flex;
+  justify-content: space-around;
+  .leftdiv {
+    width: 50%;
+    display: flex;
+    justify-content: space-around;
+    .stateBox {
+      .state {
+        display: flex;
+        flex-direction: column;
+        justify-content: center; /* 整体居中 */
+        align-items: center;
+        height: 200px;
+        gap: 20px; /* 控制间距 */
+        p {
+          width: 150px;
+          height: 40px;
+          background: rgb(227, 227, 227);
+          color: rgb(50, 50, 50);
+          text-align: center;
+          align-content: center;
+          font-weight: 600;
+        }
+      }
+      .btn-auto {
+        margin-top: 10px;
+        width: 100%;
+      }
+    }
+    .Btn {
+      width: 50%;
+      display: flex;
+      flex-direction: column; /* 垂直排列 */
+      justify-content: space-between; /* 顶部和底部对齐 */
+      min-height: 100px; /* 确保容器有足够高度 */
+      margin: 10px 0;
+      .PText {
+        display: flex;
+        justify-content: space-around;
+
+        span {
+          display: flex;
+          align-items: center;
+          i {
+            width: 30px;
+            height: 15px;
+            margin-right: 5px;
+          }
+          .color1 {
+            background-color: #8ae359;
+          }
+          .color2 {
+            background-color: #eecb5f;
+          }
+          .color3 {
+            background-color: #f7715f;
+          }
+        }
+      }
+      margin: 10px 0;
+      .minp {
+        font-size: 12px;
+        margin-top: auto; /* 自动推到最底部 */
+      }
+    }
+  }
+  .rightdiv {
+    width: 50%;
+    .fenye {
+      display: flex;
+      justify-content: space-between;
+      margin: 5px 0;
+      font-size: 11px;
+      line-height: 30px;
+      span {
+        font-weight: 600;
+      }
+    }
+  }
+}
+
+.bottomBox {
+  display: flex;
+  justify-content: space-around;
+  margin-top: 10px;
+  .BtLeft {
+    border: 1px solid rgb(231, 231, 231);
+    width: 100%;
+    padding: 10px;
+  }
+  .BtRight {
+    // width: 49%;
+    border: 1px solid rgb(231, 231, 231);
+    padding: 10px;
+    .BtRightDiv {
+      padding: 0 10px;
+      h4 {
+        font-size: 14px;
+      }
+      .BtRightP {
+        line-height: 30px;
+        font-size: 12px;
+        display: flex;
+        margin-bottom: 5px;
+        width: 50%;
+        span {
+          margin-left: 10px;
+          .el-input {
+            width: 100px;
+          }
+        }
+        .label-text {
+          width: 140px;
+        }
+      }
+      .canshu {
+        display: flex;
+        flex-wrap: wrap;
+        justify-content: space-between;
+      }
+    }
+  }
+  .dialog-footer {
+    margin-top: 20px;
+    text-align: right;
+  }
+}
+::v-deep .el-table__cell {
+  padding: 2px 0;
+  font-size: 12px;
+}
+</style>

+ 431 - 0
src/views/health/components/malfunctionOld/misalignment.vue

@@ -0,0 +1,431 @@
+<template>
+  <div>
+    <div class="TopBox">
+      <div class="rightdiv">
+        <el-table
+          ref="multipleTable"
+          :data="tableData"
+          tooltip-effect="dark"
+          style="width: 100%"
+          height="250"
+        >
+          <!-- <el-table-column fixed type="selection" width="55"> </el-table-column> -->
+          <el-table-column
+            prop="timeStamp"
+            label="时间"
+            align="center"
+            width="150"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="samplingFrequency"
+            label="采样频率(Hz)"
+            align="center"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="rotationalSpeed"
+            label="转速(rpm)"
+            align="center"
+          >
+          </el-table-column>
+        </el-table>
+        <div class="fenye">
+          <p><span>状态码说明:</span>0正常,1报警,2危险,-1未定义</p>
+
+          <el-pagination
+            small
+            @current-change="handleCurrentChange"
+            :current-page="currentPage"
+            layout="total, prev, pager, next"
+            :total="totalCount"
+            :page-size="10"
+          ></el-pagination>
+        </div>
+      </div>
+
+      <div class="leftdiv">
+        <div class="stateBox">
+          <h4>不平衡状态</h4>
+          <div class="state">
+            <p :style="{ backgroundColor: bearingStateColors.innerRing }">
+              不平衡
+            </p>
+          </div>
+          <el-button
+            type="primary"
+            size="small"
+            @click="automaticDiagnosis"
+            class="btn-auto"
+            :loading="loading"
+            >诊断</el-button
+          >
+        </div>
+
+        <div class="Btn">
+          <div style="height: 200px">
+            <bingTwo :statistics="statistics"> </bingTwo>
+          </div>
+
+          <div class="minp">
+            <p class="PText">
+              <span><i class="color1"></i>正常</span
+              ><span><i class="color2"></i>报警</span
+              ><span><i class="color3"></i>危险</span>
+            </p>
+
+            <h4>诊断步骤:</h4>
+            <p>1、选择振动测点与起止时间,点击“查询;</p>
+            <p>2、点击“诊断”输出不平衡状态结果。</p>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="bottomBox">
+      <div class="BtLeft">
+        <h4>不平衡故障状态趋势图</h4>
+        <el-empty
+          v-if="this.xData.length === 0 || this.yData.length === 0"
+          description="暂无数据"
+          style="padding: 48px 0"
+        ></el-empty>
+        <Eecharts
+          v-else
+          style="height: 310px"
+          :xData="xData"
+          :yData="[yData]"
+          :yNames="['不平衡故障']"
+          yAxisName="不平衡故障状态"
+        ></Eecharts>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from "axios";
+import Eecharts from "./Eecharts.vue";
+import bingTwo from "./bingTwo.vue";
+import { cacheEntryPossiblyAdded, log10, promisify } from "plotly.js-dist";
+export default {
+  components: { Eecharts, bingTwo },
+  props: {
+    codedata: {
+      type: Array,
+      default: () => [],
+    },
+    totalCount: {
+      type: Number,
+      default: 0,
+    },
+    totalPage: {
+      type: Number,
+      default: 0,
+    },
+    fieldCode: {
+      type: String,
+      default: "",
+    },
+    windTurbineNumber: {
+      type: String,
+      default: "",
+    },
+  },
+  data() {
+    return {
+      tableData: [],
+      // 添加新的数据属性用于绑定输入框的值
+      transmissionRatio: "",
+      bearingPitchDiameter: "",
+      rollingElementDiameter: "",
+      rollingElementCount: "",
+      contactAngle: "",
+      vibrationSpeedAlarmThreshold: "",
+      vibrationSpeedDangerThreshold: "",
+      envelopeTotalAlarmThreshold: "",
+      envelopeTotalDangerThreshold: "",
+      // 分页
+
+      currentPage: 1,
+      total: 1,
+
+      xData: [],
+      yData: [],
+      // 颜色判断
+      bearingStateColors: {
+        innerRing: "#80808057",
+        outerRing: "#80808057",
+        rollingElement: "#80808057",
+        cage: "#80808057",
+      },
+      hasError: false, // 标志是否已经显示过错误提示
+      statistics: {},
+      dialogVisible: false,
+      results: [],
+      loading: false, // 控制加载状态
+    };
+  },
+  created() {},
+  watch: {
+    codedata: {
+      handler(newVal) {
+        this.tableData = newVal;
+      },
+      immediate: true, // 组件创建时立刻执行一次
+      deep: true, // 如果 codedata 是复杂对象,建议加上
+    },
+  },
+
+  methods: {
+    toggleSelection(rows) {
+      if (rows) {
+        rows.forEach((row) => {
+          this.$refs.multipleTable.toggleRowSelection(row);
+        });
+      } else {
+        this.$refs.multipleTable.clearSelection();
+      }
+    },
+    handleSelectionChange(val) {
+      this.multipleSelection = val;
+    },
+    handleCurrentChange(val) {
+      console.log(`当前页: ${val}`);
+      setTimeout(() => {
+        this.automaticDiagnosis();
+      }, 500);
+
+      this.currentPage = val; // 子组件内部更新当前页
+      this.$emit("updatePage", this.currentPage); // 通知父组件,把当前页传出去
+    },
+    automaticDiagnosis() {
+      if (this.tableData.length === 0) {
+        this.$message.warning("当前没有数据,无法进行诊断");
+        this.loading = false; // 确保关闭 loading 状态
+        return; // 直接返回,不发请求
+      }
+      this.loading = true;
+      const ids = this.tableData
+        .map((item) => item.id)
+        .filter((id) => id !== undefined);
+      const params = {
+        windCode: this.fieldCode,
+        engine_code: this.windTurbineNumber,
+        autodiagType: "Unbalance",
+        ids: ids,
+      };
+      const autodiagType = params.autodiagType || "Unbalance";
+
+      const loadingInstance = this.$loading({
+        lock: true,
+        text: "自动诊断中...",
+        spinner: "el-icon-loading",
+        background: "rgba(0, 0, 0, 0.7)",
+      });
+
+      axios
+        .post(`/AnalysisMulti/autodiag/${autodiagType}`, params)
+        .then((res) => {
+          if (res.data.code === 405) {
+            this.$message.warning({
+              message: "当前采集频率不适合进行诊断分析",
+              duration: 2000,
+            });
+            return; // 停止继续处理数据
+          }
+
+          this.statistics = res.data.statistics;
+          this.$set(this, "yData", [...res.data.results]);
+          this.$set(
+            this,
+            "xData",
+            this.tableData.map((item) => item.timeStamp)
+          );
+          console.log(this.yData, "yData11");
+          console.log(this.xData, "xData22");
+
+          const maxStatus = res.data.statistics.max_status;
+          if (maxStatus === 0) {
+            this.bearingStateColors.innerRing = "#8ae359";
+          } else if (maxStatus === 1) {
+            this.bearingStateColors.innerRing = "#eecb5f";
+          } else if (maxStatus === 2) {
+            this.bearingStateColors.innerRing = "#f7715f";
+          } else {
+            this.bearingStateColors.innerRing = "#80808057";
+          }
+
+          this.$message.success({
+            message: "诊断完成",
+            duration: 1000, // 1秒后自动关闭
+          });
+        })
+        .catch((error) => {
+          console.error("自动诊断失败:", error);
+          this.bearingStateColors.innerRing = "#80808057";
+          this.$message.error({
+            message: "诊断失败",
+            duration: 1000, // 1秒后自动关闭
+          });
+        })
+        .finally(() => {
+          loadingInstance.close();
+          this.loading = false;
+        });
+    },
+    reset() {
+      // 重置状态
+      this.xData = [];
+      this.yData = [];
+      this.statistics = {};
+      this.bearingStateColors = {
+        innerRing: "#80808057",
+        outerRing: "#80808057",
+        rollingElement: "#80808057",
+        cage: "#80808057",
+      };
+      this.tableData = [];
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+h4 {
+  margin-bottom: 5px;
+  font-weight: 600;
+}
+.TopBox {
+  height: 280px;
+  display: flex;
+  justify-content: space-around;
+  .leftdiv {
+    width: 50%;
+    display: flex;
+    justify-content: space-around;
+    .stateBox {
+      .state {
+        display: flex;
+        flex-direction: column;
+        justify-content: center; /* 整体居中 */
+        align-items: center;
+        height: 200px;
+        gap: 20px; /* 控制间距 */
+        p {
+          width: 150px;
+          height: 40px;
+          background: rgb(227, 227, 227);
+          color: rgb(50, 50, 50);
+          text-align: center;
+          align-content: center;
+          font-weight: 600;
+        }
+      }
+      .btn-auto {
+        margin-top: 10px;
+        width: 100%;
+      }
+    }
+    .Btn {
+      width: 50%;
+      display: flex;
+      flex-direction: column; /* 垂直排列 */
+      justify-content: space-between; /* 顶部和底部对齐 */
+      min-height: 100px; /* 确保容器有足够高度 */
+      margin: 10px 0;
+      .PText {
+        display: flex;
+        justify-content: space-around;
+
+        span {
+          display: flex;
+          align-items: center;
+          i {
+            width: 30px;
+            height: 15px;
+            margin-right: 5px;
+          }
+          .color1 {
+            background-color: #8ae359;
+          }
+          .color2 {
+            background-color: #eecb5f;
+          }
+          .color3 {
+            background-color: #f7715f;
+          }
+        }
+      }
+      margin: 10px 0;
+      .minp {
+        font-size: 12px;
+        margin-top: auto; /* 自动推到最底部 */
+      }
+    }
+  }
+  .rightdiv {
+    width: 50%;
+    .fenye {
+      display: flex;
+      justify-content: space-between;
+      margin: 5px 0;
+      font-size: 11px;
+      line-height: 30px;
+      span {
+        font-weight: 600;
+      }
+    }
+  }
+}
+
+.bottomBox {
+  display: flex;
+  justify-content: space-around;
+  margin-top: 10px;
+  .BtLeft {
+    border: 1px solid rgb(231, 231, 231);
+    width: 100%;
+    padding: 10px;
+  }
+  .BtRight {
+    // width: 49%;
+    border: 1px solid rgb(231, 231, 231);
+    padding: 10px;
+    .BtRightDiv {
+      padding: 0 10px;
+      h4 {
+        font-size: 14px;
+      }
+      .BtRightP {
+        line-height: 30px;
+        font-size: 12px;
+        display: flex;
+        margin-bottom: 5px;
+        width: 50%;
+        span {
+          margin-left: 10px;
+          .el-input {
+            width: 100px;
+          }
+        }
+        .label-text {
+          width: 140px;
+        }
+      }
+      .canshu {
+        display: flex;
+        flex-wrap: wrap;
+        justify-content: space-between;
+      }
+    }
+  }
+  .dialog-footer {
+    margin-top: 20px;
+    text-align: right;
+  }
+}
+::v-deep .el-table__cell {
+  padding: 2px 0;
+  font-size: 12px;
+}
+</style>

+ 423 - 0
src/views/health/components/malfunctionOld/temperature.vue

@@ -0,0 +1,423 @@
+<template>
+  <div class="MAXdiv">
+    <div class="TopBox">
+      <div class="rightdiv">
+        <el-table
+          ref="multipleTable"
+          :data="tableData"
+          tooltip-effect="dark"
+          style="width: 100%"
+          height="250"
+        >
+          <el-table-column prop="time_stamp" label="时间" align="center" />
+          <el-table-column
+            prop="temp_channel"
+            label="部件名称"
+            align="center"
+          />
+
+          <!-- 自定义状态列样式 -->
+          <el-table-column prop="status" label="温度状态" align="center">
+            <template #default="{ row }">
+              <span :class="{ 'warning-text': row.status !== '正常' }">
+                {{ row.status }}
+              </span>
+            </template>
+          </el-table-column>
+        </el-table>
+
+        <div class="fenye">
+          <p>特征值越接近1表示危险</p>
+          <el-pagination
+            @current-change="handleCurrentChange"
+            :current-page="currentPage"
+            layout="total, prev, pager, next"
+            :total="totalCount"
+            :page-size="500"
+          />
+        </div>
+      </div>
+
+      <div class="leftdiv">
+        <div class="stateBox">
+          <h4>温度状态</h4>
+          <div class="state">
+            <p :style="{ backgroundColor: getStatusColor('主轴承温度') }">
+              主轴承温度
+            </p>
+            <p :style="{ backgroundColor: getStatusColor('齿轮箱油温') }">
+              齿轮箱油温
+            </p>
+            <p
+              :style="{
+                backgroundColor: getStatusColor('发电机驱动端轴承温度'),
+              }"
+            >
+              发电机驱动端轴承温度
+            </p>
+            <p
+              :style="{
+                backgroundColor: getStatusColor('发电机非驱动端轴承温度'),
+              }"
+            >
+              发电机非驱动端轴承温度
+            </p>
+          </div>
+        </div>
+
+        <div class="Btn">
+          <div style="height: 200px">
+            <bing :result="result" />
+          </div>
+          <div class="minp">
+            <p class="PText">
+              <span><i class="color1"></i>正常</span>
+              <span><i class="color2"></i>危险</span>
+            </p>
+            <h4>诊断步骤:</h4>
+            <p>1、选择风场风机与起止时间,点击“查询”;</p>
+            <p>2、点击“查询”输出最终温度状态结果。</p>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <div class="bottomBox">
+      <div class="tu" v-for="(item, index) in chartList" :key="index">
+        <el-empty v-if="!hasData(item.data)" description="暂无数据" />
+        <zhexian
+          v-else
+          :title="item.title"
+          :lineType="item.lineType"
+          :lineColor="item.lineColor"
+          :chartData="item.data"
+          :fieldCode="fieldCode"
+          :windTurbineNumber="windTurbineNumber"
+            :bearingKey="item.bearingKey"
+          
+        />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import Eecharts from "./Eecharts.vue";
+import bing from "./bing.vue";
+import Zhexian from "./zhexian.vue";
+
+export default {
+  components: { Eecharts, bing, Zhexian },
+  props: {
+    echartsdata: {
+      type: Object,
+      default: () => ({
+        main_bearing: [],
+        generator_drive_end: [],
+        gearbox_oil: [],
+        generator_nondrive_end: [],
+      }),
+    },
+    codedata: {
+      type: Array,
+      default: () => [],
+    },
+    totalCount: {
+      type: Number,
+      default: 0,
+    },
+    totalPage: {
+      type: Number,
+      default: 0,
+    },
+    fieldCode: {
+      type: String,
+      default: "",
+    },
+    windTurbineNumber: {
+      type: String,
+      default: "",
+    },
+  },
+  data() {
+    return {
+      tableData: [],
+      currentPage: 1,
+      total: 1,
+      result: {},
+      bearingStateColors: {
+        innerRing: "#80808057",
+        outerRing: "#80808057",
+        rollingElement: "#80808057",
+        cage: "#80808057",
+      },
+    };
+  },
+  computed: {
+    chartList() {
+      const list = [
+        {
+          title: "主轴承温度趋势图",
+          data: this.echartsdata.main_bearing,
+          lineType: "line",
+          lineColor: "#02aae9",
+          bearingKey: "innerRing",
+        },
+        {
+          title: "发电机驱动端轴承温度趋势图",
+          data: this.echartsdata.generator_drive_end,
+          bearingKey: "rollingElement",
+        },
+        {
+          title: "齿轮箱油温趋势图",
+          data: this.echartsdata.gearbox_oil,
+          lineType: "line",
+          lineColor: "#02aae9",
+          bearingKey: "outerRing",
+        },
+        {
+          title: "发电机非驱动端轴承温度趋势图",
+          data: this.echartsdata.generator_nondrive_end,
+          bearingKey: "cage",
+        },
+      ];
+
+      const sortedList = list.slice().sort((a, b) => {
+        return this.hasData(b.data) - this.hasData(a.data);
+      });
+
+      console.log(
+        "排序后的图表列表:",
+        sortedList.map((i) => ({
+          title: i.title,
+          hasData: this.hasData(i.data),
+        }))
+      );
+
+      return sortedList;
+    },
+  },
+  watch: {
+    codedata: {
+      handler(newVal) {
+        this.tableData = newVal;
+        this.updateBearingStateColors();
+        this.updateStatusCount(); // 统计调用
+      },
+      immediate: true,
+      deep: true,
+    },
+  },
+  methods: {
+    updateBearingStateColors() {
+      // 四个温度类型对应状态颜色key
+      const statusMap = {
+        主轴承温度: "innerRing",
+        齿轮箱油温: "outerRing",
+        发电机驱动端轴承温度: "rollingElement", // 改成“驱动端”对应数据字段
+        发电机非驱动端轴承温度: "cage", // 改成“非驱动端”对应数据字段
+      };
+
+      // 颜色映射,正常绿,异常黄,无数据灰
+      const colorMap = {
+        normal: "#8ae359",
+        danger: "#eecb5f",
+        unknown: "#80808057",
+      };
+
+      const updatedColors = {};
+
+      // 遍历四个温度类型,分别判断它们对应的tableData是否有异常或报警
+      for (const [label, key] of Object.entries(statusMap)) {
+        const items = this.tableData.filter(
+          (item) => item.temp_channel === label
+        );
+        if (items.length === 0) {
+          updatedColors[key] = colorMap.unknown; // 无数据,灰色
+        } else {
+          const hasDanger = items.some(
+            (item) => item.status === "异常" || item.status === "危险"
+          );
+          updatedColors[key] = hasDanger ? colorMap.danger : colorMap.normal;
+        }
+      }
+
+      // 合并更新状态颜色对象
+      this.bearingStateColors = {
+        ...this.bearingStateColors,
+        ...updatedColors,
+      };
+    },
+    updateStatusCount() {
+      let normalCount = 0;
+      let dangerCount = 0;
+
+      this.tableData.forEach((item) => {
+        if (item.status === "正常") {
+          normalCount++;
+        } else if (
+          item.status === "异常" ||
+          item.status === "危险" ||
+          item.status === "报警"
+        ) {
+          dangerCount++;
+        }
+      });
+
+      this.result = {
+        normal: normalCount,
+        danger: dangerCount,
+      };
+    },
+
+    getStatusColor(tempName) {
+      const map = {
+        主轴承温度: "innerRing",
+        齿轮箱油温: "outerRing",
+        发电机驱动端轴承温度: "rollingElement",
+        发电机非驱动端轴承温度: "cage",
+      };
+      // 根据tempName返回对应颜色
+      return this.bearingStateColors[map[tempName]] || "#80808057";
+    },
+
+    hasData(data) {
+      if (!data) return false;
+
+      if (
+        typeof data === "object" &&
+        Array.isArray(data.timestamps) &&
+        Array.isArray(data.values)
+      ) {
+        return data.timestamps.length > 0 || data.values.length > 0;
+      }
+
+      return false;
+    },
+
+    handleCurrentChange(val) {
+      this.currentPage = val;
+      this.$emit("updatePage", this.currentPage);
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+h4 {
+  margin-bottom: 5px;
+  font-weight: 600;
+}
+.TopBox {
+  height: 280px;
+  display: flex;
+  justify-content: space-around;
+  .leftdiv {
+    width: 50%;
+    display: flex;
+    justify-content: space-around;
+    .stateBox {
+      .state {
+        display: flex;
+        flex-direction: column;
+        justify-content: center; /* 整体居中 */
+        align-items: center;
+        height: 200px;
+        gap: 20px; /* 控制间距 */
+        p {
+          width: 200px;
+          height: 40px;
+          background: rgb(227, 227, 227);
+          color: rgb(50, 50, 50);
+          text-align: center;
+          align-content: center;
+          font-weight: 600;
+        }
+      }
+      .btn-auto {
+        margin-top: 10px;
+        width: 100%;
+      }
+    }
+    .Btn {
+      width: 50%;
+      display: flex;
+      flex-direction: column; /* 垂直排列 */
+      justify-content: space-between; /* 顶部和底部对齐 */
+      min-height: 100px; /* 确保容器有足够高度 */
+      margin: 10px 0;
+      .PText {
+        display: flex;
+        justify-content: space-around;
+
+        span {
+          display: flex;
+          align-items: center;
+          i {
+            width: 30px;
+            height: 15px;
+            margin-right: 5px;
+          }
+          .color1 {
+            background-color: #8ae359;
+          }
+          .color2 {
+            background-color: #eecb5f;
+          }
+          .color3 {
+            background-color: #f7715f;
+          }
+        }
+      }
+      margin: 10px 0;
+      .minp {
+        font-size: 12px;
+        margin-top: auto; /* 自动推到最底部 */
+      }
+    }
+  }
+  .rightdiv {
+    width: 50%;
+    .fenye {
+      display: flex;
+      //justify-content: center;
+      justify-content: space-between;
+      margin: 5px 0;
+      font-size: 12px;
+      line-height: 30px;
+      span {
+        font-weight: 600;
+      }
+    }
+  }
+}
+
+.bottomBox {
+  margin-top: 20px;
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: space-around;
+
+  border: 1px solid rgb(231, 231, 231);
+  padding: 10px;
+  .tu {
+    width: 49%;
+    height: 350px;
+  }
+}
+::v-deep .el-table__cell {
+  padding: 2px 0;
+  font-size: 12px;
+}
+
+.MAXdiv {
+  overflow: hidden;
+  overflow-y: auto;
+  height: 70vh;
+}
+
+.warning-text {
+  color: #e6a23c; /* Element UI的warning颜色 */
+  font-weight: bold;
+}
+</style>

+ 277 - 0
src/views/health/components/malfunctionOld/zhexian.vue

@@ -0,0 +1,277 @@
+<template>
+  <div>
+    <div ref="chartRef" style="width: 100%; height: 320px"></div>
+    <el-dialog
+      title="机组运行数据"
+      :visible.sync="dialogVisible"
+      width="50%"
+      v-dialogDrag
+      :modal="false"
+      ref="myDialog"
+      @open="resetDialogPosition"
+      @closed="resetDialogPosition"
+    >
+      <div style="overflow-x: auto">
+        <el-table
+          :data="records"
+          height="400"
+          border
+          style="min-width: max-content"
+          :fit="false"
+        >
+          <el-table-column
+            v-for="(col, index) in columns"
+            :key="index"
+            :prop="col"
+            :label="col"
+            :width="col === '时间' ? 150 : getTextWidth(col) + 40"
+            :label-class-name="'nowrap-header'"
+            :class-name="'nowrap-cell'"
+            align="center"
+            :show-overflow-tooltip="false"
+            :resizable="true"
+          />
+        </el-table>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import * as echarts from "echarts";
+import axios from "axios";
+
+export default {
+  name: "LargeAreaChart",
+  props: {
+    title: {
+      type: String,
+      default: "Large Area Chart",
+    },
+    lineType: {
+      type: String,
+      default: "line", // 可选:line, bar 等
+    },
+    lineColor: {
+      type: String,
+      default: "#5470C6", // 默认 ECharts 主色
+    },
+    chartData: {
+      type: Object,
+      default: () => ({
+        timestamps: [],
+        values: [],
+      }),
+    },
+    fieldCode: {
+      // 新增 fieldCode 属性
+      type: String,
+      default: "",
+    },
+    windTurbineNumber: {
+      // 新增 windTurbineNumber 属性
+      type: String,
+      default: "",
+    },
+    bearingKey: {
+      type: String,
+      default: "",
+    },
+  },
+  data() {
+    return {
+      myChart: null,
+      dialogVisible: false,
+
+      records: [],
+    };
+  },
+  computed: {
+    columns() {
+      // 如果 records 为空则返回空数组
+      return this.records.length > 0 ? Object.keys(this.records[0]) : [];
+    },
+  },
+  watch: {
+    chartData: {
+      deep: true,
+      handler() {
+        this.updateChart();
+      },
+    },
+  },
+  mounted() {
+    this.initChart();
+  },
+  beforeUnmount() {
+    if (this.myChart) {
+      this.myChart.dispose();
+    }
+  },
+  methods: {
+    resetDialogPosition() {
+      this.$nextTick(() => {
+        const dialogEl = this.$refs.myDialog?.$el?.querySelector(".el-dialog");
+        if (dialogEl) {
+          // 清除拖拽遗留位置样式,恢复居中
+          dialogEl.style.left = "0px";
+          dialogEl.style.top = "150px";
+          dialogEl.style.transform = "0px";
+        }
+      });
+    },
+
+    initChart() {
+      this.myChart = echarts.init(this.$refs.chartRef);
+      this.updateChart();
+
+      this.myChart.getZr().on("click", (params) => {
+        const pointInPixel = [params.offsetX, params.offsetY];
+        const pointInGrid = this.myChart.convertFromPixel(
+          { xAxisIndex: 0, yAxisIndex: 0 },
+          pointInPixel
+        );
+        const clickedTime = pointInGrid[0];
+
+        if (!this.chartData.timestamps.length) return;
+
+        // 找最接近点击时间的索引
+        let minDiff = Infinity;
+        let closestIndex = -1;
+        for (let i = 0; i < this.chartData.timestamps.length; i++) {
+          const time = new Date(this.chartData.timestamps[i]).getTime();
+          const diff = Math.abs(time - clickedTime);
+          if (diff < minDiff) {
+            minDiff = diff;
+            closestIndex = i;
+          }
+        }
+
+        if (closestIndex !== -1) {
+          const value = this.chartData.values[closestIndex];
+          const time = this.chartData.timestamps[closestIndex];
+          this.myChart.setOption({
+            series: [
+              {
+                markLine: {
+                  symbol: "none",
+                  lineStyle: {
+                    type: "dashed",
+                    color: "#FF0000",
+                  },
+                  data: [
+                    {
+                      xAxis: time,
+                    },
+                  ],
+                },
+              },
+            ],
+          });
+          if (value === 1) {
+            const params = {
+              windCode: this.fieldCode,
+              windTurbineNumber: this.windTurbineNumber,
+              timestamp: time,
+            };
+            axios
+              .post("/AnalysisMulti/temperature/dataquery", params)
+              .then((res) => {
+                this.records = res.data.data.records;
+                this.dialogVisible = !this.dialogVisible;
+              })
+              .catch((error) => {
+                this.$message.error("数据异常");
+              });
+          }
+        }
+      });
+    },
+
+    updateChart() {
+      if (!this.myChart || !this.chartData.timestamps.length) return;
+
+      const data = this.chartData.timestamps.map((t, i) => [
+        t,
+        this.chartData.values[i],
+      ]);
+
+      const option = {
+        tooltip: {
+          trigger: "axis",
+          position: (pt) => [pt[0], "10%"],
+        },
+        title: {
+          left: "center",
+          text: this.title,
+        },
+        toolbox: {
+          feature: {
+            dataZoom: { yAxisIndex: "none" },
+            restore: {},
+            saveAsImage: {},
+          },
+        },
+        xAxis: {
+          type: "time",
+          boundaryGap: false,
+          axisLabel: {
+            formatter: (value) => {
+              const date = new Date(value);
+              const m = String(date.getMonth() + 1).padStart(2, "0");
+              const d = String(date.getDate()).padStart(2, "0");
+              return `${m}-${d} `;
+            },
+            rotate: 0, // 倾斜以防止重叠
+            hideOverlap: true,
+          },
+        },
+        yAxis: {
+          type: "value",
+          max: 1, // 👈 固定最大值
+          boundaryGap: [0, "100%"],
+        },
+        dataZoom: [
+          { type: "inside", start: 0, end: 20 },
+          { start: 0, end: 20 },
+        ],
+        series: [
+          {
+            name: "特征值",
+            type: this.lineType,
+            smooth: true,
+            symbol: "none",
+            areaStyle: this.lineType === "line" ? {} : undefined,
+            itemStyle: { color: this.lineColor },
+            lineStyle: { color: this.lineColor },
+            data,
+          },
+        ],
+      };
+
+      this.myChart.setOption(option);
+    },
+
+    getTextWidth(text) {
+      const span = document.createElement("span");
+      span.style.visibility = "hidden";
+      span.style.position = "fixed";
+      span.style.whiteSpace = "nowrap";
+      span.innerText = text;
+      document.body.appendChild(span);
+      const width = span.offsetWidth;
+      document.body.removeChild(span);
+      return width;
+    },
+  },
+};
+</script>
+
+<style scoped>
+.nowrap-header {
+  white-space: nowrap !important;
+}
+.nowrap-cell .cell {
+  white-space: nowrap !important;
+}
+</style>

+ 737 - 93
src/views/health/index.vue

@@ -1,141 +1,785 @@
 <template>
-  <div class="health-dashboard-page">
-    <HealthHeader v-model="companyCode" @change="handleFarmChange" />
-
-    <div class="health-page__body">
-      <main class="dashboard-main">
-        <div class="dashboard-top-row">
-          <HealthScorePanel
-            :distribution="scoreDistribution"
-            :summary="scoreSummary"
-            :total-score="totalScore"
-          />
-
-          <HealthSubsystemPanel :chart-data="subsystemData" />
-
-          <HealthRankingPanel
-            :healthy-list="healthyRankList"
-            :risk-list="riskRankList"
-          />
+  <div class="global-variable health-assess-page">
+    <div class="searchbox">
+      <p>
+        单位:
+        <selecttree
+          size="small"
+          style="width: 180px"
+          placeholder="请选择所属公司"
+          :list="parentOpt"
+          type="1"
+          v-model="companyCode"
+          :defaultParentProps="{
+            children: 'children',
+            label: 'companyName',
+            value: 'codeNumber',
+          }"
+        />
+      </p>
+
+      <p>
+        时间:
+        <el-date-picker
+          v-model="timevalue"
+          size="small"
+          type="month"
+          placeholder="选择月"
+          :picker-options="monthPickerOptions"
+        />
+      </p>
+
+      <el-button type="primary" size="small" @click="conditions">
+        查询
+      </el-button>
+    </div>
+
+    <div class="kuang">
+      <!-- 加载中动画 -->
+      <div v-if="loading" class="loader-wrapper">
+        <div class="loader"></div>
+      </div>
+
+      <!-- 空状态 -->
+      <el-empty
+        class="Anempty"
+        v-if="!loading && ListData.length === 0"
+        :image-size="200"
+      />
+
+      <!-- 主体内容 -->
+      <div class="main-body" v-if="!loading && ListData.length > 0">
+        <div
+          class="basics"
+          v-for="(item, index) in ListData"
+          :key="item + index"
+        >
+          <div class="title">
+            <span>
+              <SvgIcons
+                name="WindPower3"
+                class="WindPower3"
+                width="26"
+                height="26"
+              />
+            </span>
+            <h4>风机:{{ item.wind_turbine_name }}</h4>
+            <span class="mill">{{ millTypeMap[item.mill_type] || "-" }}</span>
+          </div>
+
+          <div class="content">
+            <div class="summary" style="color: #28a745">
+              <span :style="{ color: getHealthColor(item.total_health_score) }">
+                {{
+                  item.total_health_score < 0
+                    ? "-"
+                    : Math.floor(item.total_health_score)
+                }}
+              </span>
+              <span :style="{ color: getHealthColor(item.total_health_score) }">
+                {{ getHealthLabel(item.total_health_score) }}
+              </span>
+            </div>
+
+            <ul class="health">
+              <li>
+                <span>发电机组</span>
+                <span :class="'health-' + item.val">
+                  {{
+                    item.subsystems.generator.health_score >= 0
+                      ? String(
+                          Math.floor(item.subsystems.generator.health_score),
+                        ).slice(0, 3)
+                      : "-"
+                  }}
+                </span>
+              </li>
+
+              <li v-if="item.subsystems.drive_train">
+                <span>传动系统</span>
+                <span :class="'health-' + item.val">
+                  {{
+                    item.subsystems.drive_train.health_score >= 0
+                      ? String(
+                          Math.floor(item.subsystems.drive_train.health_score),
+                        ).slice(0, 3)
+                      : "-"
+                  }}
+                </span>
+              </li>
+
+              <li>
+                <span>机舱系统</span>
+                <span :class="'health-' + item.val">
+                  {{
+                    item.subsystems.nacelle.health_score >= 0
+                      ? String(
+                          Math.floor(item.subsystems.nacelle.health_score),
+                        ).slice(0, 3)
+                      : "-"
+                  }}
+                </span>
+              </li>
+
+              <li>
+                <span>电网环境</span>
+                <span :class="'health-' + item.val">
+                  {{
+                    item.subsystems.grid.health_score >= 0
+                      ? String(
+                          Math.floor(item.subsystems.grid.health_score),
+                        ).slice(0, 3)
+                      : "-"
+                  }}
+                </span>
+              </li>
+            </ul>
+          </div>
+
+          <!-- 健康评估建议(通用展示) -->
+          <!-- <div class="advice-box">
+            <div class="advice-head">
+              <span class="advice-title">健康评估建议</span>
+              <span
+                class="advice-badge"
+                :class="`is-${getHealthLevelKey(item.total_health_score)}`"
+              >
+                {{ getHealthLabel(item.total_health_score) }}
+              </span>
+            </div>
+            <p class="advice-text">
+              {{ getHealthAdvice(item.total_health_score) }}
+            </p>
+          </div> -->
         </div>
+      </div>
+    </div>
 
-        <section class="health-unit-grid">
-          <HealthUnitCard
-            v-for="unit in unitCards"
-            :key="unit.name"
-            :unit="unit"
-          />
-        </section>
-      </main>
+    <!-- 健康度说明(卡片版) -->
+    <div class="health-legend">
+      <div class="legend-head">
+        <span class="legend-title">健康度说明</span>
+      </div>
+      <div class="legend-body">
+        <div class="legend-item is-good">
+          <div class="legend-icon" aria-hidden="true">
+            <svg viewBox="0 0 24 24" class="legend-icon-svg">
+              <path
+                class="shield"
+                d="M12 2.5 19 6.2v6.4c0 5.2-3.6 9.8-7 10.9-3.4-1.1-7-5.7-7-10.9V6.2L12 2.5Z"
+              />
+              <path class="mark" d="M8.2 12.2l2.3 2.3 5.3-5.3" />
+            </svg>
+          </div>
+          <div class="legend-content">
+            <p class="legend-range">100–85分(健康)</p>
+            <p class="legend-advice">
+              建议:按计划进行常规巡检与维护,保持当前运行状态,无需额外检修。
+            </p>
+          </div>
+        </div>
+        <div class="legend-item is-subhealthy">
+          <div class="legend-icon" aria-hidden="true">
+            <svg viewBox="0 0 24 24" class="legend-icon-svg">
+              <path
+                class="shield"
+                d="M12 2.5 19 6.2v6.4c0 5.2-3.6 9.8-7 10.9-3.4-1.1-7-5.7-7-10.9V6.2L12 2.5Z"
+              />
+              <path class="mark" d="M12 7.6v6.2" />
+              <path class="mark" d="M12 16.9h.01" />
+            </svg>
+          </div>
+          <div class="legend-content">
+            <p class="legend-range">84–70分(亚健康)</p>
+            <p class="legend-advice">
+              建议:加强状态监测,缩短巡检周期,排查潜在隐患,可安排预防性维护。
+            </p>
+          </div>
+        </div>
+        <div class="legend-item is-normal">
+          <div class="legend-icon" aria-hidden="true">
+            <svg viewBox="0 0 24 24" class="legend-icon-svg">
+              <path
+                class="shield"
+                d="M12 2.5 19 6.2v6.4c0 5.2-3.6 9.8-7 10.9-3.4-1.1-7-5.7-7-10.9V6.2L12 2.5Z"
+              />
+              <path class="mark" d="M12 7.6v6.2" />
+              <path class="mark" d="M12 16.9h.01" />
+            </svg>
+          </div>
+          <div class="legend-content">
+            <p class="legend-range">69–55分(一般)</p>
+            <p class="legend-advice">
+              建议:开展专项检测与故障诊断,制定针对性检修计划,及时处理发现的问题,避免状态进一步恶化。
+            </p>
+          </div>
+        </div>
+        <div class="legend-item is-fault">
+          <div class="legend-icon" aria-hidden="true">
+            <svg viewBox="0 0 24 24" class="legend-icon-svg">
+              <path
+                class="shield"
+                d="M12 2.5 19 6.2v6.4c0 5.2-3.6 9.8-7 10.9-3.4-1.1-7-5.7-7-10.9V6.2L12 2.5Z"
+              />
+              <path class="mark" d="M9 9l6 6" />
+              <path class="mark" d="M15 9l-6 6" />
+            </svg>
+          </div>
+          <div class="legend-content">
+            <p class="legend-range">55分以下(故障)</p>
+            <p class="legend-advice">
+              建议:立即停机或安排紧急检修,进行全面故障排查与修复,必要时更换关键部件,确保设备恢复正常运行能力。
+            </p>
+          </div>
+        </div>
+      </div>
     </div>
   </div>
 </template>
 
 <script>
-import HealthHeader from "./components/health/HealthHeader.vue";
-import HealthScorePanel from "./components/health/HealthScorePanel.vue";
-import HealthSubsystemPanel from "./components/health/HealthSubsystemPanel.vue";
-import HealthRankingPanel from "./components/health/HealthRankingPanel.vue";
-import HealthUnitCard from "./components/health/HealthUnitCard.vue";
-import {
-  healthyRankList,
-  riskRankList,
-  scoreDistribution,
-  scoreSummary,
-  subsystemData,
-  unitCards,
-} from "./components/health/dashboardData";
+import { getSysOrganizationAuthTreeByRoleId } from "@/api/ledger.js";
+import selecttree from "../../components/selecttree.vue";
+import axios from "axios";
 
 export default {
-  name: "HealthDashboard",
   components: {
-    HealthHeader,
-    HealthScorePanel,
-    HealthSubsystemPanel,
-    HealthRankingPanel,
-    HealthUnitCard,
+    selecttree,
   },
   data() {
     return {
+      parentOpt: [],
       companyCode: "",
-      totalScore: 92,
-      scoreDistribution,
-      scoreSummary,
-      subsystemData,
-      healthyRankList,
-      riskRankList,
-      unitCards,
+      ListData: [],
+      loading: false, // ✅ 加载状态.
+      // demo演示
+      timevalue: new Date(2024, 6), // 7 月是 6,因为月份从 0 开始
     };
   },
-  mounted() {
-    this.$nextTick(() => {
-      window.dispatchEvent(new Event("resize"));
-    });
+  computed: {
+    millTypeMap() {
+      return {
+        dfig: "双馈",
+        direct: "直驱",
+        semi: "半直驱",
+      };
+    },
+
+    monthPickerOptions() {
+      return {
+        disabledDate: (time) => {
+          const code = this.companyCode;
+          const date = time;
+
+          if (code === "WOF046400029") {
+            const start = new Date("2023-10-01");
+            const end = new Date("2024-10-30");
+            return date < start || date > end;
+          } else if (code === "WOF091200030") {
+            const start = new Date("2023-01-01");
+            const end = new Date("2024-11-30");
+            return date < start || date > end;
+          } else if (code === "WOF093400005") {
+            const start = new Date("2023-12-01");
+            const end = new Date("2024-05-30");
+            return date < start || date > end;
+          } else {
+            // 其他公司不限制时间选择
+            return false;
+          }
+        },
+      };
+    },
+  },
+  created() {
+    this.GETtree();
   },
   methods: {
-    handleFarmChange(data) {
-      if (!data || !data.codeNumber) return;
-      // TODO: 切换风场/组织后刷新仪表盘数据
-      console.log("当前选中:", data.companyName || data.fieldName, data);
+    async GETtree() {
+      const res = await getSysOrganizationAuthTreeByRoleId();
+      const treedata = res.data;
+      const processedData = this.processTreeData(treedata);
+      this.parentOpt = processedData;
+      this.defaultdata = res.data[0];
+      // demo演示
+      this.$nextTick(() => {
+        this.companyCode = "WOF046400029";
+      });
+    },
+
+    processTreeData(treeData) {
+      const processedData = [];
+      function processNode(node) {
+        if (node.codeType === "field") {
+          node.companyName = node.fieldName;
+        }
+        if (node.children && node.children.length > 0) {
+          node.children.forEach((child) => {
+            processNode(child);
+          });
+        }
+      }
+      treeData.forEach((root) => {
+        processNode(root);
+        processedData.push(root);
+      });
+      return processedData;
+    },
+
+    getHealthLabel(val) {
+      if (!Number.isFinite(val) || val < 0) return "无数据";
+      if (val >= 85) return "健康";
+      if (val >= 70) return "亚健康";
+      if (val >= 55) return "一般";
+      return "故障";
+    },
+
+    getHealthLevelKey(val) {
+      if (!Number.isFinite(val) || val < 0) return "nodata";
+      if (val >= 85) return "good";
+      if (val >= 70) return "subhealthy";
+      if (val >= 55) return "normal";
+      return "fault";
+    },
+
+    getHealthAdvice(val) {
+      if (!Number.isFinite(val) || val < 0) return "暂无健康评估数据。";
+      if (val >= 85) {
+        return "按计划进行常规巡检与维护,保持当前运行状态,无需额外检修。";
+      }
+      if (val >= 70) {
+        return "加强状态监测,缩短巡检周期,排查潜在隐患,可安排预防性维护。";
+      }
+      if (val >= 55) {
+        return "开展专项检测与故障诊断,制定针对性检修计划,及时处理发现的问题,避免状态进一步恶化。";
+      }
+      return "立即停机或安排紧急检修,进行全面故障排查与修复,必要时更换关键部件,确保设备恢复正常运行能力。";
+    },
+
+    getHealthColor(val) {
+      if (!Number.isFinite(val) || val < 0) return "#6c757d"; // 灰色
+      if (val >= 85) return "#28a745"; // 绿色
+      if (val >= 70) return "#ffc107"; // 黄色
+      if (val >= 55) return "#fd7e14"; // 橙色
+      return "#dc3545"; // 红色
+    },
+
+    conditions() {
+      const fullStr = this.$formatDateTWO(this.timevalue);
+      const datePart = typeof fullStr === "string" ? fullStr.slice(0, 7) : "";
+      const parms = {
+        windcode: this.companyCode,
+        month: datePart,
+      };
+
+      this.loading = true; // ✅ 显示 loading
+      const start = performance.now(); // ⏱️ 请求开始时间
+
+      axios
+        .post(`/AnalysisMulti/health_assess`, parms)
+        .then((res) => {
+          this.ListData = res.data;
+          const end = performance.now(); // ⏱️ 请求结束时间
+          const duration = ((end - start) / 1000).toFixed(2);
+          console.log(`接口请求耗时:${duration} 秒`);
+        })
+        .catch((error) => {
+          console.error("Error fetching data:", error);
+          const end = performance.now(); // ⏱️ 请求结束时间
+          const duration = ((end - start) / 1000).toFixed(2);
+          console.log(`接口请求耗时:${duration} 秒`);
+        })
+        .finally(() => {
+          this.loading = false; // ✅ 隐藏 loading
+        });
     },
   },
 };
 </script>
 
-<style lang="scss">
-@import "./components/health/health-dashboard.scss";
+<style lang="scss" scoped>
+.searchbox {
+  display: flex;
+  align-items: center;
+  margin: 0 0 20px 0;
 
-.health-dashboard-page {
-  .dashboard-top-row {
-    display: grid;
-    grid-template-columns: 1fr;
-    gap: 24px;
-    min-width: 0;
+  p {
+    margin-right: 10px;
+    color: #606266;
   }
 
-  @media (min-width: 900px) {
-    .dashboard-top-row {
-      grid-template-columns: repeat(2, minmax(0, 1fr));
-    }
+  .el-select {
+    width: 180px;
+  }
+}
+
+.el-input__inner {
+  width: 340px;
+}
+
+.main-body {
+  margin: 0 auto;
+  display: grid;
+  grid-template-columns: repeat(auto-fill, 260px); /* 严格保持300px宽度 */
+  justify-content: space-evenly; /* 均匀分布 */
+  gap: 10px;
+
+  // height: min-content;
+  // max-height: 700px;
+  overflow: hidden;
+  overflow-y: auto;
+  .basics {
+    width: 260px;
+    display: flex;
+    flex-direction: column;
+    margin-bottom: 20px;
+    background: #ffffff;
+    border: 1px solid var(--health-card-border, var(--primary-color, #008080));
+    border-radius: 4px;
+    overflow: hidden;
+
+    .title {
+      padding: 8px 10px;
+      width: 100%;
+      border-bottom: 1px solid var(--health-card-border, var(--primary-color, #008080));
+      text-align: left;
+      display: flex;
+      align-items: center;
+
+      span {
+        display: inline-block;
+        margin-right: 6px;
 
-    .dashboard-top-row > :last-child {
-      grid-column: span 2;
+        svg {
+          display: block;
+        }
+      }
+
+      h4 {
+        flex: 1;
+        min-width: 0;
+        color: var(--health-title-color, var(--primary-color, #008080));
+        font-size: 1.1em;
+        font-weight: 600;
+        margin: 0;
+      }
+
+      .mill {
+        flex-shrink: 0;
+        font-size: 12px;
+        color: #606266;
+      }
     }
-  }
 
-  @media (min-width: 1280px) {
-    .dashboard-top-row {
-      grid-template-columns: repeat(3, minmax(0, 1fr));
+    .content {
+      display: flex;
+      width: 100%;
+      gap: 20px;
+      padding: 12px 10px;
+
+      .summary {
+        width: 70px;
+        display: flex;
+        flex-direction: column; // 垂直排列
+        align-items: center; // 居中对齐
+        justify-content: center;
+        font-weight: bold;
+        padding-left: 26px;
+        span {
+          display: block;
+          text-align: center;
+          line-height: 1.3;
+          &:first-child {
+            font-size: 1.6em; // 更大的字体
+            margin-bottom: 4px;
+          }
+          &:last-child {
+            font-size: 0.8em; // 稍小一点
+          }
+        }
+      }
+
+      .health {
+        flex: 1;
+        display: flex;
+        flex-wrap: wrap;
+        gap: 6px;
+        list-style: none;
+        padding: 0;
+        margin: 0;
+
+        li {
+          display: flex;
+          flex-direction: column;
+          align-items: center;
+          justify-content: center;
+          padding: 6px;
+          min-width: 60px;
+          font-size: 0.8em;
+
+          span {
+            display: block;
+            text-align: center;
+            line-height: 1.3;
+
+            &:first-child {
+              font-size: 0.9em;
+              font-weight: 600;
+              margin-bottom: 2px;
+              color: var(--health-sub-label-color, var(--primary-color, #008080));
+            }
+
+            &:last-child {
+              color: var(--health-sub-score-color, var(--primary-color, #008080));
+              font-weight: 600;
+            }
+          }
+        }
+      }
     }
 
-    .dashboard-top-row > :last-child {
-      grid-column: auto;
+    .advice-box {
+      margin-top: 10px;
+      padding: 10px 10px;
+      border-top: 1px solid var(--health-card-border, var(--primary-color, #008080));
+      background: #fff;
+
+      .advice-head {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        gap: 8px;
+        margin-bottom: 6px;
+      }
+      .advice-title {
+        font-size: 12px;
+        font-weight: 700;
+        color: #303133;
+      }
+      .advice-badge {
+        font-size: 12px;
+        font-weight: 700;
+        padding: 2px 8px;
+        border-radius: 999px;
+        &.is-good {
+          color: #1f7a3a;
+          background: #e7f6ee;
+        }
+        &.is-subhealthy {
+          color: #8a6d00;
+          background: #fff6e5;
+        }
+        &.is-normal {
+          color: #9a4d00;
+          background: #fff0e6;
+        }
+        &.is-fault {
+          color: #b42318;
+          background: #ffebee;
+        }
+        &.is-nodata {
+          color: #606266;
+          background: #f4f4f5;
+        }
+      }
+      .advice-text {
+        margin: 0;
+        font-size: 12px;
+        line-height: 1.45;
+        color: #606266;
+        word-break: break-all;
+      }
     }
   }
+}
+.jia {
+  color: var(--primary-color, #008080);
+}
+.kuang {
+  min-height: 79vh;
+  height: 680px;
+  position: relative;
+  overflow: hidden;
+  overflow-y: auto;
+  .Anempty {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+  }
+}
+
+.health-legend {
+  margin-top: 14px;
+  border-radius: 14px;
+  background: #fff;
+  box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.08);
+  border: 1px solid rgba(228, 231, 237, 0.8);
+  overflow: hidden;
+
+  .legend-head {
+    padding: 12px 14px 0;
+  }
+  .legend-title {
+    font-size: 14px;
+    font-weight: 800;
+    color: #303133;
+  }
 
-  .health-unit-grid {
+  .legend-body {
     display: grid;
-    grid-template-columns: repeat(1, minmax(0, 1fr));
-    gap: 16px;
+    grid-template-columns: repeat(4, minmax(0, 1fr));
+    gap: 0;
+    padding: 10px 10px 12px;
+  }
+
+  .legend-item {
+    display: flex;
+    align-items: flex-start;
+    gap: 10px;
+    padding: 10px 12px;
+    position: relative;
+    min-height: 88px;
+  }
+  .legend-item + .legend-item::before {
+    content: "";
+    position: absolute;
+    left: 0;
+    top: 16px;
+    bottom: 16px;
+    width: 1px;
+    background: rgba(220, 223, 230, 0.7);
+  }
+
+  .legend-icon {
+    width: 34px;
+    height: 34px;
+    flex: 0 0 auto;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    color: currentColor;
+  }
+  .legend-icon-svg {
+    width: 22px;
+    height: 22px;
+  }
+  .legend-icon-svg .shield {
+    fill: none;
+    stroke: currentColor;
+    stroke-width: 1.8;
+    stroke-linejoin: round;
+  }
+  .legend-icon-svg .mark {
+    fill: none;
+    stroke: currentColor;
+    stroke-width: 2.2;
+    stroke-linecap: round;
+    stroke-linejoin: round;
+  }
+  .legend-content {
+    flex: 1;
     min-width: 0;
   }
+  .legend-range {
+    margin: 0 0 6px;
+    font-size: 13px;
+    font-weight: 800;
+    line-height: 1.2;
+  }
+  .legend-advice {
+    margin: 0;
+    font-size: 12px;
+    line-height: 1.45;
+    color: #606266;
+    word-break: break-all;
+  }
 
-  @media (min-width: 768px) {
-    .health-unit-grid {
-      grid-template-columns: repeat(2, minmax(0, 1fr));
+  .legend-item.is-good {
+    color: #28a745;
+    .legend-range {
+      color: inherit;
     }
   }
-
-  @media (min-width: 1024px) {
-    .health-unit-grid {
-      grid-template-columns: repeat(3, minmax(0, 1fr));
+  .legend-item.is-subhealthy {
+    color: #ffc107;
+    .legend-range {
+      color: inherit;
+    }
+  }
+  .legend-item.is-normal {
+    color: #fd7e14;
+    .legend-range {
+      color: inherit;
     }
   }
+  .legend-item.is-fault {
+    color: #dc3545;
+    .legend-range {
+      color: inherit;
+    }
+  }
+}
 
-  @media (min-width: 1280px) {
-    .health-unit-grid {
-      grid-template-columns: repeat(5, minmax(0, 1fr));
+@media (max-width: 768px) {
+  .health-legend {
+    .legend-body {
+      grid-template-columns: 1fr;
     }
+    .legend-item + .legend-item::before {
+      display: none;
+    }
+    .legend-item {
+      border-top: 1px solid rgba(220, 223, 230, 0.7);
+    }
+    .legend-item:first-child {
+      border-top: 0;
+    }
+  }
+}
+
+// 动画
+/* ✅ loading 包裹容器 */
+.loader-wrapper {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 100%; /* 可根据页面需要调整高度 */
+}
+
+/* ✅ loading 样式动画 */
+
+.loader {
+  width: 50px;
+  --b: 8px;
+  aspect-ratio: 1;
+  border-radius: 50%;
+  padding: 1px;
+  background: conic-gradient(#0000 10%, var(--primary-color, #008080)) content-box;
+
+  -webkit-mask: repeating-conic-gradient(
+      #0000 0deg,
+      #000 1deg 20deg,
+      #0000 21deg 36deg
+    ),
+    radial-gradient(
+      farthest-side,
+      #0000 calc(100% - var(--b) - 1px),
+      #000 calc(100% - var(--b))
+    );
+  mask: repeating-conic-gradient(#0000 0deg, #000 1deg 20deg, #0000 21deg 36deg),
+    radial-gradient(
+      farthest-side,
+      #0000 calc(100% - var(--b) - 1px),
+      #000 calc(100% - var(--b))
+    );
+  -webkit-mask-composite: destination-in;
+  mask-composite: intersect;
+  animation: l4 1s infinite steps(10);
+}
+@keyframes l4 {
+  to {
+    transform: rotate(1turn);
   }
 }
 </style>

+ 7 - 7
src/views/health/malfunction.vue

@@ -484,7 +484,7 @@ export default {
   margin-bottom: 8px;
   align-items: center;
   flex-wrap: wrap;
-  color: #ffffff;
+  color: #303133;
 
   p {
     margin-right: 10px;
@@ -492,7 +492,7 @@ export default {
     margin-top: 8px;
     display: flex;
     align-items: center;
-    color: #b7dff5;
+    color: #606266;
 
     .el-select,
     .el-date-picker {
@@ -525,23 +525,23 @@ export default {
 }
 
 ::v-deep .el-tabs__item {
-  color: rgba(183, 223, 245, 0.75) !important;
+  color: #606266 !important;
 }
 
 ::v-deep .el-tabs__item.is-active {
-  color: #ffffff !important;
+  color: var(--primary-color) !important;
 }
 
 ::v-deep .el-tabs__item:hover {
-  color: #ffffff !important;
+  color: var(--primary-color) !important;
 }
 
 ::v-deep .el-tabs__active-bar {
-  background-color: #00aaff !important;
+  background-color: var(--primary-color) !important;
 }
 
 ::v-deep .el-tabs__nav-wrap::after {
-  background-color: rgba(0, 170, 255, 0.25) !important;
+  background-color: #ebeef5 !important;
 }
 
 /* 放在你的组件 <style scoped> 或全局样式里 */

+ 7 - 7
src/views/health/malfunctionOld.vue

@@ -134,12 +134,12 @@ import {
   queryDetectionDic,
 } from "@/api/ledger.js";
 import selecttree from "../../components/selecttree.vue";
-import Bearing from "./components/malfunction/bearing.vue";
-import Dissymmetry from "./components/malfunction/dissymmetry.vue";
-import Gear from "./components/malfunction/gear.vue";
-import Loose from "./components/malfunction/loose.vue";
-import Misalignment from "./components/malfunction/misalignment.vue";
-import Temperature from "./components/malfunction/temperature.vue";
+import Bearing from "./components/malfunctionOld/bearing.vue";
+import Dissymmetry from "./components/malfunctionOld/dissymmetry.vue";
+import Gear from "./components/malfunctionOld/gear.vue";
+import Loose from "./components/malfunctionOld/loose.vue";
+import Misalignment from "./components/malfunctionOld/misalignment.vue";
+import Temperature from "./components/malfunctionOld/temperature.vue";
 import axios from "axios";
 
 export default {
@@ -350,7 +350,7 @@ export default {
         .then((res) => {
           condition.frequencyoptions = (res.data.datas || [])
             .map((item) => Number(item))
-            .filter((num) => num >= 2000)
+            .filter((num) => num >= 12800)
             .map((num) => num.toString());
         });
 

+ 10 - 10
src/views/ledger/maintain.vue

@@ -482,7 +482,7 @@ export default {
           confirmButtonText: "确定",
           cancelButtonText: "取消",
           type: "warning",
-        }
+        },
       )
         .then(() => {
           // Proceed with deletion after confirmation
@@ -493,7 +493,7 @@ export default {
           delUnitDict(params).then((res) => {
             if (res.status === true) {
               this.tableData = this.tableData.filter(
-                (item) => item.id !== row.id
+                (item) => item.id !== row.id,
               );
               this.GETquery();
               this.$message({
@@ -546,7 +546,7 @@ export default {
       };
       delUnitDictProperty(params).then((res) => {
         this.nothaveData = this.nothaveData.filter(
-          (item) => item.id !== row.id
+          (item) => item.id !== row.id,
         );
       });
     },
@@ -648,11 +648,11 @@ export default {
           this.parameterVisible = false;
           this.$message({
             type: "success",
-          showClose: true,
-          message: '提交成功'
-        });
+            showClose: true,
+            message: "提交成功",
+          });
           this.fetchData();
-          this.drawer=true
+          this.drawer = true;
         })
         .catch(() => {
           this.$message.error("提交失败");
@@ -749,7 +749,7 @@ export default {
                 message: "删除成功!",
               });
               this.relevanceData = this.relevanceData.filter(
-                (item) => item.id !== row.id
+                (item) => item.id !== row.id,
               );
             } else {
               this.$message({
@@ -830,7 +830,7 @@ export default {
     display: flex;
 
     p {
-      width: 80px;
+      width: 100px;
       line-height: 32px;
     }
 
@@ -889,4 +889,4 @@ export default {
     margin-left: 10px;
   }
 }
-</style>
+</style>

+ 34 - 5
src/views/login/Index.vue

@@ -140,10 +140,10 @@ export default {
   transform: translate(-50%, -50%);
   padding: 0 50px;
   width: 450px;
-  background: var(--panel-bg, #000c17);
-  border: 1px solid var(--panel-border, rgba(0, 170, 255, 0.45));
+  background: var(--login-panel-bg, var(--panel-bg, #ffffff));
+  border: 1px solid var(--login-panel-border, #ebeef5);
   border-radius: 4px;
-  box-shadow: var(--panel-glow, 0 0 20px rgba(0, 120, 255, 0.2));
+  box-shadow: var(--login-panel-shadow, 0 2px 12px rgba(0, 0, 0, 0.1));
   margin: auto;
 
   .leftLogin {
@@ -155,14 +155,14 @@ export default {
       line-height: 50px;
       font-size: 20px;
       font-weight: 600;
-      color: var(--text-cyan, #52c8f2);
+      color: var(--login-title-color, var(--primary-color, #008080));
       margin-top: 20px;
     }
 
     .el-divider--horizontal {
       margin: 10px 0;
       height: 2px;
-      background: var(--primary-color, #1890ff);
+      background: var(--login-title-color, var(--primary-color, #008080));
     }
 
     .loginText {
@@ -210,6 +210,35 @@ export default {
         margin-bottom: 10px;
       }
     }
+
+    ::v-deep .el-input__inner {
+      background-color: var(--login-input-bg, #ffffff) !important;
+      border-color: var(--login-input-border, #dcdfe6) !important;
+      color: var(--login-input-text, #606266) !important;
+    }
+
+    ::v-deep .el-input__inner::placeholder {
+      color: #c0c4cc !important;
+    }
+
+    ::v-deep .el-input__inner:focus {
+      border-color: var(--login-title-color, var(--primary-color, #008080)) !important;
+    }
+
+    ::v-deep input:-webkit-autofill,
+    ::v-deep input:-webkit-autofill:hover,
+    ::v-deep input:-webkit-autofill:focus,
+    ::v-deep input:-webkit-autofill:active {
+      -webkit-box-shadow: 0 0 0 1000px var(--login-input-bg, #ffffff) inset !important;
+      -webkit-text-fill-color: var(--login-input-text, #606266) !important;
+      caret-color: var(--login-input-text, #606266) !important;
+    }
+
+    ::v-deep .el-button--primary {
+      background-color: var(--login-title-color, var(--primary-color, #008080)) !important;
+      border-color: var(--login-title-color, var(--primary-color, #008080)) !important;
+      color: #ffffff !important;
+    }
   }
 
   .rightImg {

+ 1 - 0
src/views/overview/components/tsr_cp_power_scatter/index.vue

@@ -45,6 +45,7 @@
           :index="`${new Date().getTime()}` + index"
           :ref="item.fieldEngineCode"
           :fileAddr="item.fileAddr"
+          :uniformColor="true"
         >
         </TwoDMarkersChart>
       </VirtualList>

+ 2 - 2
src/views/performance/assetssMag.vue

@@ -133,12 +133,12 @@
 
             <span
               v-else-if="scope.row.analysisState == 30"
-              style="color: #4caf50"
+              class="theme-status-success"
               >分析完成</span
             >
             <span
               v-else-if="scope.row.analysisState == 10"
-              style="color: #4caf50"
+              class="theme-status-success"
               >排队中</span
             >
             <span v-else>/</span>

+ 0 - 1
src/views/performance/components/analysisEvent.vue

@@ -842,7 +842,6 @@ export default {
   width: 100%;
   font-size: 14px;
   height: 100%;
-  background: transparent !important;
   box-shadow: none !important;
   border: 1px solid #ebeef5;
 

+ 66 - 42
src/views/performance/components/chartsCom/TwoDMarkersChart.vue

@@ -81,6 +81,11 @@ export default {
       default: () => [],
       type: Array,
     },
+    // 为 true 时所有散点使用统一颜色,不按 colorbar/yData 区分
+    uniformColor: {
+      default: false,
+      type: Boolean,
+    },
   },
   data() {
     return {
@@ -132,6 +137,13 @@ export default {
     });
   },
   methods: {
+    getUniformPointColor() {
+      if (!Array.isArray(this.color1) || this.color1.length === 0) {
+        return this.color1 || "#407DB3";
+      }
+      const midIndex = Math.floor(this.color1.length - 2);
+      return this.color1[midIndex];
+    },
     // 根据配色方案设置每个选项的样式
     getOptionStyle(scheme) {
       return {
@@ -188,46 +200,56 @@ export default {
       let trace = {};
 
       if (this.chartType === "scatter") {
-        // 如果有 colorbar 数据
-        const uniqueTimeLabels =
-          data.colorbar && data.colorbar.length === data.xData.length
-            ? [...new Set(data.colorbar)] // 从 colorbar 中提取唯一的标签
-            : [...new Set(data.yData)]; // 如果没有 colorbar,使用 data.color
-        const ticktext = uniqueTimeLabels.map((dateStr) => dateStr.toFixed(1)); // 格式化为标签
-        const tickvals = uniqueTimeLabels.map((label, index) => index + 1); // 设置 tick 值
-        const timeMapping = uniqueTimeLabels.reduce((acc, curr, index) => {
-          acc[curr] = index + 1;
-          return acc;
-        }, {});
-        // 获取 colorbar 的最小值和最大值来计算比例值
-        const minValue = Math.min(...new Set(uniqueTimeLabels));
-        const maxValue = Math.max(...new Set(uniqueTimeLabels));
-        const colorStops = [
-          this.color1[0],
-          this.color1[4],
-          this.color1[8],
-          this.color1[12],
-        ];
-        // 计算渐变比例
-        const colors = colorStops.map((color, index) => {
-          const proportion = index / (colorStops.length - 1); // 计算比例值 (0, 1/3, 2/3, 1)
-          return [proportion, color]; // 创建比例-颜色映射
-        });
-        // 确保 colors 至少有 2 种颜色,否则使用默认颜色
-        if (colors.length < 2) {
-          colors.push([1, colorStops[colorStops.length - 1] || "#1B2973"]);
-        }
-
-        // 计算颜色值映射
+        const uniformPointColor = this.getUniformPointColor();
         let colorValues = [];
-        if (data.colorbar && data.colorbar.length === data.xData.length) {
-          colorValues = data.colorbar.map((date) => timeMapping[date]);
-        } else {
-          colorValues = data.yData.map((date) => timeMapping[date]);
+        let colors = [];
+        let maxValue = 0;
+
+        if (!this.uniformColor) {
+          // 如果有 colorbar 数据
+          const uniqueTimeLabels =
+            data.colorbar && data.colorbar.length === data.xData.length
+              ? [...new Set(data.colorbar)] // 从 colorbar 中提取唯一的标签
+              : [...new Set(data.yData)]; // 如果没有 colorbar,使用 data.color
+          const ticktext = uniqueTimeLabels.map((dateStr) =>
+            dateStr.toFixed(1),
+          ); // 格式化为标签
+          const tickvals = uniqueTimeLabels.map((label, index) => index + 1); // 设置 tick 值
+          const timeMapping = uniqueTimeLabels.reduce((acc, curr, index) => {
+            acc[curr] = index + 1;
+            return acc;
+          }, {});
+          // 获取 colorbar 的最小值和最大值来计算比例值
+          const minValue = Math.min(...new Set(uniqueTimeLabels));
+          maxValue = Math.max(...new Set(uniqueTimeLabels));
+          const colorStops = [
+            this.color1[0],
+            this.color1[4],
+            this.color1[8],
+            this.color1[12],
+          ];
+          // 计算渐变比例
+          colors = colorStops.map((color, index) => {
+            const proportion = index / (colorStops.length - 1); // 计算比例值 (0, 1/3, 2/3, 1)
+            return [proportion, color]; // 创建比例-颜色映射
+          });
+          // 确保 colors 至少有 2 种颜色,否则使用默认颜色
+          if (colors.length < 2) {
+            colors.push([1, colorStops[colorStops.length - 1] || "#1B2973"]);
+          }
+
+          // 计算颜色值映射
+          if (data.colorbar && data.colorbar.length === data.xData.length) {
+            colorValues = data.colorbar.map((date) => timeMapping[date]);
+          } else {
+            colorValues = data.yData.map((date) => timeMapping[date]);
+          }
         }
+
         // 保存原始颜色和大小
-        // this.originalColors = [...data.yData];
-        this.originalColors = [...colorValues];
+        this.originalColors = this.uniformColor
+          ? new Array(data.xData.length).fill(uniformPointColor)
+          : [...colorValues];
         this.originalSizes = new Array(data.xData.length).fill(6); // 初始点大小
 
         // 绘制 2D 散点图
@@ -238,8 +260,10 @@ export default {
           type: "scattergl", // 使用 scattergl 提高性能
           text: data.engineName, // 提示文本
           marker: {
-            color: colorValues, // 根据 colorbar 映射的数字设置颜色
-            colorscale: this.color1
+            color: this.uniformColor ? uniformPointColor : colorValues, // 根据 colorbar 映射的数字设置颜色
+            colorscale: this.uniformColor
+              ? undefined
+              : this.color1
               ? colors // 如果有 color1 使用自定义颜色比例
               : [
                   [0, "#F9FDD2"],
@@ -257,10 +281,10 @@ export default {
             size: new Array(data.xData.length).fill(this.pointSize), // 点的大小
           },
         };
-        if (data.colorbartitle === "密度") {
+        if (!this.uniformColor && data.colorbartitle === "密度") {
           trace.marker.cmin = 0;
           trace.marker.cmax = maxValue;
-        } else if (data.colorbartitle === "百分比(%)") {
+        } else if (!this.uniformColor && data.colorbartitle === "百分比(%)") {
           trace.marker.cmin = 0;
           trace.marker.cmax = 100;
         }
@@ -406,7 +430,7 @@ export default {
           this.$refs[`plotlyChart-${this.index}`],
           [trace],
           layout,
-          config
+          config,
         ).then(() => {
           // 确保在图表加载完成后设置工具栏按钮
           const plotElement = this.$refs[`plotlyChart-${this.index}`];

+ 1 - 1
src/views/performance/editAssets.vue

@@ -7,7 +7,7 @@
  * @FilePath: /performance-test/src/views/performance/editAssets.vue
 -->
 <template>
-  <div class="global-variable">
+  <div class="global-variable edit-assets-page">
     <el-row type="flex" justify="space-between">
       <el-col :span="8">
         <el-button

+ 39 - 27
src/views/transition/index.vue

@@ -575,12 +575,14 @@ export default {
   min-height: calc(100vh - 120px);
   width: 100%;
   padding: 12px 16px;
-  background: var(--panel-bg, #000c17);
-  color: #ffffff;
+  background: var(--transition-page-bg, var(--panel-bg, #ffffff));
+  color: var(--transition-page-text, #303133);
   box-sizing: border-box;
 
   ::v-deep .transition-collapse {
-    border-color: var(--panel-border, rgba(0, 170, 255, 0.35)) !important;
+    border: 1px solid var(--transition-border-color, #ebeef5) !important;
+    border-radius: 4px;
+    overflow: hidden;
 
     .el-collapse-item__header {
       height: 40px;
@@ -588,19 +590,20 @@ export default {
       padding: 0 12px;
       font-weight: 600;
       font-size: 15px;
-      background: linear-gradient(90deg, #001529 0%, #002a5c 100%) !important;
-      color: #ffffff !important;
-      border-bottom-color: var(--panel-border, rgba(0, 170, 255, 0.35)) !important;
+      background: var(--transition-collapse-header-bg, var(--primary-color, #008080)) !important;
+      color: var(--transition-collapse-header-text, #ffffff) !important;
+      border-bottom-color: var(--transition-border-color, #ebeef5) !important;
     }
 
     .el-collapse-item__wrap {
-      background: transparent !important;
-      border-bottom-color: var(--panel-border, rgba(0, 170, 255, 0.35)) !important;
+      background: var(--transition-collapse-body-bg, #ffffff) !important;
+      border-bottom-color: var(--transition-border-color, #ebeef5) !important;
     }
 
     .el-collapse-item__content {
       padding: 10px 12px 6px;
-      color: #ffffff;
+      color: var(--transition-page-text, #303133);
+      background: var(--transition-collapse-body-bg, #ffffff);
     }
   }
 
@@ -613,6 +616,15 @@ export default {
 
     ::v-deep .el-descriptions__title {
       font-size: 14px;
+      color: var(--transition-page-text, #303133);
+    }
+
+    ::v-deep .el-descriptions__label {
+      color: #606266;
+    }
+
+    ::v-deep .el-descriptions__content {
+      color: var(--transition-page-text, #303133);
     }
 
     ::v-deep .el-descriptions-item__cell {
@@ -627,7 +639,7 @@ export default {
     gap: 12px 16px;
     padding: 10px 0 8px;
     margin-top: 4px;
-    border-bottom: 1px solid var(--panel-border, rgba(0, 170, 255, 0.25));
+    border-bottom: 1px solid var(--transition-border-color, #ebeef5);
   }
 
   .condition-item {
@@ -637,7 +649,7 @@ export default {
   }
 
   .condition-label {
-    color: var(--text-cyan, #b7dff5);
+    color: var(--transition-label-color, #606266);
     white-space: nowrap;
     font-size: 14px;
   }
@@ -655,24 +667,24 @@ export default {
 }
 
 .CPC {
-  border: 1px solid rgba(0, 170, 255, 0.45);
-  background: rgba(0, 170, 255, 0.12);
+  border: 1px solid var(--transition-badge-border, var(--primary-color, #008080));
+  background: var(--transition-badge-bg, rgba(0, 128, 128, 0.08));
   display: inline-block;
   padding: 6px 12px;
   margin: 0 0 4px;
-  color: #ffffff;
+  color: var(--transition-page-text, #303133);
   border-radius: 4px;
   cursor: pointer;
   font-size: 14px;
   line-height: 1.4;
 
   span {
-    color: #00aaff;
+    color: var(--transition-badge-accent, var(--primary-color, #008080));
     font-weight: 600;
   }
 
   &:hover {
-    background: rgba(0, 170, 255, 0.22);
+    background: var(--transition-badge-bg-hover, rgba(0, 128, 128, 0.15));
   }
 }
 
@@ -682,7 +694,7 @@ export default {
 
 .demo-table-expand label {
   width: 90px;
-  color: var(--text-cyan, #b7dff5);
+  color: var(--transition-label-color, #606266);
 }
 
 .demo-table-expand .el-form-item {
@@ -700,9 +712,9 @@ export default {
   margin: 8px 16px;
   border-radius: 4px;
   padding: 12px 16px;
-  border: 1px solid var(--panel-border, rgba(0, 170, 255, 0.35));
-  background: rgba(0, 16, 32, 0.6);
-  color: #ffffff;
+  border: 1px solid var(--transition-border-color, #ebeef5);
+  background: var(--transition-card-bg, #ffffff);
+  color: var(--transition-page-text, #303133);
   box-shadow: none;
 
   p {
@@ -722,8 +734,8 @@ export default {
     }
 
     li:hover {
-      background: rgba(0, 170, 255, 0.25);
-      color: #ffffff;
+      background: var(--transition-card-hover-bg, rgba(0, 128, 128, 0.08));
+      color: var(--transition-page-text, #303133);
       cursor: pointer;
     }
 
@@ -808,7 +820,7 @@ export default {
 .scrollable-list {
   height: 400px;
   overflow-y: auto;
-  color: #ffffff;
+  color: var(--transition-page-text, #303133);
   padding: 0;
   margin: 0;
   list-style: none;
@@ -819,24 +831,24 @@ export default {
 }
 
 .scrollable-list::-webkit-scrollbar-track {
-  background: rgba(0, 16, 32, 0.6);
+  background: var(--transition-scrollbar-track, #f5f7fa);
   border-radius: 4px;
 }
 
 .scrollable-list::-webkit-scrollbar-thumb {
-  background: rgba(0, 170, 255, 0.35);
+  background: var(--transition-scrollbar-thumb, #dcdfe6);
   border-radius: 4px;
 }
 
 .scrollable-list::-webkit-scrollbar-thumb:hover {
-  background: rgba(0, 170, 255, 0.55);
+  background: var(--transition-scrollbar-thumb-hover, #c0c4cc);
 }
 
 ::v-deep .transition-drawer .el-drawer__header > :first-child,
 ::v-deep .transition-dialog .el-dialog__title {
   font-size: 16px;
   font-weight: 600;
-  color: #ffffff;
+  color: var(--transition-page-text, #303133);
 }
 
 .demo-table-expand {

+ 1 - 1
src/views/windResourceWake/data/mockData.js

@@ -10,7 +10,7 @@ export const turbineNames = [
   "JH11",
 ];
 
-const wakeTableImage = require("../images/image(3).png");
+const wakeTableImage = require("../../../assets/logo.png");
 
 export const tableData = [
   {

+ 8 - 8
vue.config.js

@@ -71,14 +71,14 @@ module.exports = {
           "^/api": "", // 去掉 /api 前缀
         },
       },
-      //大唐健康评估-异常检测-风机尾流
-      "/healthApi": {
-        target: process.env.VUE_APP_healthAPIPROXY,
-        changeOrigin: true,
-        pathRewrite: {
-          "^/healthApi": "", // 去掉 /healthApi 前缀
-        },
-      },
+      // //大唐健康评估-异常检测-风机尾流
+      // "/healthApi": {
+      //   target: process.env.VUE_APP_healthAPIPROXY,
+      //   changeOrigin: true,
+      //   pathRewrite: {
+      //     "^/healthApi": "", // 去掉 /healthApi 前缀
+      //   },
+      // },
       // 未知量  //振动、激光测距仪
       "/WZLapi": {
         target: process.env.VUE_APP_WZLAPIPROXY,