chenbaoxin 3 месяцев назад
Родитель
Сommit
a01b6f7c0b

+ 34 - 3
src/api/index.ts

@@ -135,7 +135,7 @@ export function repairHisDel(id:number) {
  * @returns 
  */
 export function recordAssessmentResult(params) {
-  return post('/healthStatusAnalysis/recordAssessmentResult',params);
+  return post('/reliabilityPrediction/recordAssessmentResult',params);
 }
 /**
  * @name 评估健康状态
@@ -144,7 +144,7 @@ export function recordAssessmentResult(params) {
  * @returns 
  */
 export function evaluateHealthStatus(params:any) {
-  return get('/operationalReliabilityPrediction/evaluateHealthStatus',{...params});
+  return get('/reliabilityPrediction/evaluateHealthStatus',{...params});
 }
 /**
  * @name 文件夹读取
@@ -208,7 +208,38 @@ export function devicesAndCategories(data:any) {
 export function measurementPoints(data:any) {
   return post('/settings/measurementPoints',data);
 }
-
+/**
+ * @name  时间范围和速率的查询和修改
+ * @param params 
+ * @returns 
+ */
+export function updateDataRangeSpeed(params:any) {
+  return put('/healthStatusAnalysis/updateDataRangeSpeed',params);
+}
+/**
+ * @name  模拟缓存
+ * @param params 
+ * @returns 
+ */
+export function mockCacheData(params:any) {
+  return post('/healthStatusAnalysis/mockCacheData',params);
+}
+/**
+ * @name  文件批量上传
+ * @param data 
+ * @returns 
+ */
+export function uploadBatch(data:any) {
+  return post('/fileManagement/uploadBatch',data);
+}
+/**
+ * @name  获取文件数量
+ * @param data 
+ * @returns 
+ */
+export function mockTotal(data:any) {
+  return get('/fileManagement/mockTotal',data);
+}
 // // 使用 http 方法获取特定的 HTTP 方法并调用
 // const deleteMethod = http("DELETE");
 // deleteMethod("/api/data")

+ 4 - 0
src/style.css

@@ -290,6 +290,10 @@ body {
   border: 1px solid rgba(0, 122, 255, 0);
   right: 0;
 }
+.el-picker-panel__footer {
+  background: rgba(2, 22, 43, 0.95);
+  border-top: 1px solid var(--el-datepicker-inner-border-color);
+}
 .popperClass{
   background: #000 !important;
 }

+ 422 - 0
src/views/ConditionClassification/components/card.vue

@@ -0,0 +1,422 @@
+<template>
+  <div class="card-all">
+    <div class="card-title">
+      <div class="card-t">{{ data.name }}</div>
+      <div class="card-c" @click="handleClick">修改</div>
+    </div>
+    <div class="paramsRunRcharts">
+      <div class="paramsRunBtn" @click="showParamsModel">选择显示参数</div>
+      <LineChart
+        :showYAxisLabels="showYAxisLabels"
+        :xAxisData="xAxisParamsData"
+        :seriesData="seriesParamsData"
+        :legendData="legendPramsData"
+        :gridTop="gridParamsTop"
+      />
+    </div>
+  </div>
+  <!-- 参数运行曲线model -->
+  <ModalComponent
+    v-model:visible="showModal"
+    customClass="custom-modal"
+    title="选择显示曲线图的参数"
+  >
+    <div class="hra">
+      <div class="hra-left">
+        <div>选择设备</div>
+        <div class="custom-time-select">
+          <el-select
+            class="hra-sel"
+            v-model="btnBigIndex"
+            @change="setCateData"
+            placeholder="选择设备"
+          >
+            <template v-slot:prefix>
+              <!-- <el-icon color="rgba(255, 255, 255, 0.75)">
+              <Filter />
+            </el-icon> -->
+            </template>
+            <el-option v-for="item in cateBigRef" :key="item" :value="item">{{
+              item
+            }}</el-option>
+          </el-select>
+        </div>
+      </div>
+      <div class="hra-right">
+        <div>选择大类(仅可选择一类)</div>
+        <div
+          :class="['btn', btnIndex == index ? 'btnCurrent' : '']"
+          @click="btnTab(index, item)"
+          v-for="(item, index) in cateSmallRef"
+          :key="item"
+        >
+          {{ item }}
+        </div>
+      </div>
+    </div>
+    <!-- 模态框内容插槽 -->
+    <div class="custom-box box-height">
+      <el-checkbox-group @change="changeAttr" v-model="checkedParams">
+        <el-checkbox
+          v-for="item in setParams"
+          :key="item"
+          :label="item"
+          :value="item"
+        ></el-checkbox>
+        <!-- 其他选项 -->
+      </el-checkbox-group>
+    </div>
+  </ModalComponent>
+</template>
+
+<script setup lang="ts">
+import moment from "moment";
+import { Warning } from "@element-plus/icons-vue";
+
+import {
+  ref,
+  onMounted,
+  onUnmounted,
+  nextTick,
+  computed,
+  watch,
+  Ref,
+  getCurrentInstance,
+  defineProps,
+  defineEmits,
+} from "vue";
+import { useRoute, useRouter } from "vue-router";
+import { ElTimeSelect, ElMessage } from "element-plus";
+import CalendarHeatmap from "@/components/CalendarHeatmap/index.vue";
+import LineChart from "@/components/LineChart/index.vue";
+import { COLUMN_MAP } from "@/utils/engine";
+import sTitle from "@/components/StructTitle/index.vue";
+import ModalComponent from "@/components/ModalComponent/index.vue";
+import WebSocketClient from "@/utils/webSocketClient";
+import { Interface } from "readline";
+import { time } from "console";
+import {
+  recordAssessmentResult,
+  healthStatusTip,
+  healthySetList,
+  measurementPoints,
+  devicesAndCategories,
+} from "@/api/index";
+const props = defineProps({
+  data: {
+    type: Object,
+    required: true,
+  },
+});
+watch(
+  () => props.data,
+  (newData, oldData) => {
+    lineParamsAllRef.value = newData;
+  },
+  { deep: true }
+);
+const emit = defineEmits(["viewDetails"]);
+
+const handleClick = () => {
+  emit("viewDetails", props.data);
+};
+onMounted(() => {
+  getcateData();
+  getPointData(btnBigIndex.value, "温度");
+});
+let cateBigRef = ref([]);
+let cateSmallRef = ref([]);
+let setParams = ref([]);
+let btnIndex = ref(0);
+let btnBigIndex = ref("右DE");
+const btnTab = (index, val) => {
+  btnIndex.value = index;
+  getPointData(btnBigIndex.value, val);
+};
+const setCateData = () => {
+  getPointData(btnBigIndex.value, cateSmallRef.value[btnIndex.value]);
+};
+
+const getcateData = async () => {
+  let data = await devicesAndCategories({});
+  cateBigRef = data.data.devices;
+  cateSmallRef.value = data.data.categories;
+};
+const getPointData = async (deviceName, categoryName) => {
+  let data = await measurementPoints({ deviceName, categoryName });
+  setParams.value = data.data.map((its) => its.pointName);
+};
+// 获取所有显示参数
+let lineParamsAllRef = ref([]);
+watch(
+  () => lineParamsAllRef.value,
+  (newdata: any) => {
+    if (lineParamsAllRef.value.length == 0) {
+      const result: Array<AnyObject> = convertToChartData(
+        newdata,
+        checkedParams.value
+      );
+      setLineparames(newdata, result);
+      return false;
+    }
+    const result: Array<AnyObject> = convertToChartData(
+      newdata,
+      checkedParams.value
+    );
+
+    setLineparames(newdata, result);
+  },
+  { deep: true }
+);
+// const setParams = ref(convertObjectToArray(COLUMN_MAP));
+const changeAttr = (valArr: string[]) => {
+  btnIndex.value == 5
+    ? (showYAxisLabels.value = false)
+    : (showYAxisLabels.value = true);
+  let val = setParams.value.filter((element) => valArr.includes(element));
+  if (val.length > 5) {
+    ElMessage({
+      message: `最多选择5个参数`,
+      type: "error",
+    });
+    checkedParams.value = val.slice(0, 5);
+  } else {
+    checkedParams.value = val;
+  }
+  //   localStorage.setItem(
+  //     "OE_checked_params",
+  //     JSON.stringify(checkedParams.value)
+  //   );
+  //   localStorage.setItem("btnIndex", btnIndex.value);
+  //   localStorage.setItem("btnBigIndex", btnBigIndex.value);
+};
+// 显示参数相关(模态框)
+const showModal = ref(false);
+let openFailIndex = 0;
+const showParamsModel = () => {
+  // 判断要是数据没请求过来的情况下 延迟500毫秒在调用下,最多三次
+  if (cateSmallRef.value.length == 0 && openFailIndex < 3) {
+    openFailIndex++;
+    setTimeout(() => {
+      showParamsModel();
+    }, 500);
+  }
+  //   let btn = localStorage.getItem("btnIndex");
+  //   let btnBig = localStorage.getItem("btnBigIndex");
+  //   if (!!btn && !!btnBig) {
+  //     btnIndex.value = btn;
+  //     btnBigIndex.value = btnBig;
+  //     getPointData(btnBigIndex.value, cateSmallRef.value[btnIndex.value]);
+  //   }
+
+  showModal.value = true;
+};
+
+const checkedParams = ref([]);
+// 设备参数全
+// 参数运行示例数据
+// 横坐标轴时间点
+let xAxisParamsData = ref([]);
+let seriesParamsData = ref([]);
+let showParamsLegend = ref(true);
+let showYAxisLabels = ref(true);
+let legendPramsData = ref([]);
+let gridParamsTop = ref(40); // 根据是否显示图例动态调整
+const invertObjectKeysAndValues = (
+  obj: Record<string, string>
+): Record<string, string> => {
+  return Object.entries(obj).reduce((acc, [key, value]) => {
+    acc[value] = key;
+    return acc;
+  }, {} as Record<string, string>);
+};
+// const inverParams = invertObjectKeysAndValues(COLUMN_MAP);
+const inverParams = COLUMN_MAP;
+// 设置默认5个数值
+// checkedParams.value = Object.values(COLUMN_MAP).slice(0, 5);
+
+/**
+ * @param dataAll 全部数据,获取数据中的time
+ * @param selectData 折线图数据,符合格式返回
+ * @description xAxisParamsData 横坐标时间点 [时间]
+ * @description seriesParamsData 折线图数据[{
+     name: "温度",
+     data: [3020, 2010, 2005, 2030, 2040, 2025, 2015, 2020, 2005, 2010],
+   }] 
+ * @description legendPramsData 图例数据["温度", "压力", "流量"]
+ */
+const setLineparames = (
+  dataAll: Array<AnyObject>,
+  selectData: Array<AnyObject>
+) => {
+  // 横坐标时间点
+  xAxisParamsData.value = dataAll.map((its) =>
+    moment(its.data._ts).format("HH:mm:ss")
+  );
+  // .slice(-30);
+  // 折线图数据
+  seriesParamsData.value = selectData.map((its) => {
+    return {
+      ...its,
+      data: its.data.slice(-30),
+    };
+  });
+  // 图例
+  legendPramsData.value = selectData.map((its) => its.name);
+};
+// 参数转化
+const convertObjectToArray = (
+  obj: Record<string, string>
+): { name: string; value: string }[] => {
+  return Object.entries(obj).map(([key, value]) => ({
+    name: key,
+    value,
+  }));
+};
+
+interface AnyObject {
+  [key: string]: any;
+}
+const convertToChartData = (
+  selectedData: AnyObject[],
+  properties: string[]
+): { name: string; data: any[] }[] => {
+  // properties.forEach(its=>{
+  //   console.log(selectedData.map((item) => item.data['right_de_rpm_sensor_fault']),its,inverParams[its]);
+
+  // })
+  // // console.log(selectedData);
+
+  // debugger
+  return properties.map((propertyName) => ({
+    name: propertyName,
+    // name: propertyName,
+    data: selectedData.map((item) => item.data[inverParams[propertyName]]),
+  }));
+};
+const formatPressure = (value: number | string) => {
+  // console.log(typeof value,'------');
+
+  // if (typeof value == 'string') {
+  //   return Number(value).toFixed(2);
+  // }
+  return value;
+};
+</script>
+
+<style scoped>
+.card-all {
+  width: 100%;
+  box-sizing: border-box;
+  height: 380px;
+  border: 1px solid rgba(56, 151, 255, 0.6);
+  background: rgba(22, 93, 255, 0.1);
+  /* padding: 10px; */
+}
+.card-title {
+  box-sizing: border-box;
+  width: 100%;
+  height: 44px;
+  line-height: 44px;
+  /* padding: 10px; */
+  display: flex;
+  padding-left: 20px;
+  padding-right: 20px;
+  justify-content: space-between;
+  border-bottom: 1px solid rgba(56, 151, 255, 0.6);
+
+  color: rgba(255, 255, 255, 0.85);
+}
+.card-c {
+  color: #3897ff;
+  cursor: pointer;
+}
+.paramsRunRcharts {
+  margin-top: 10px;
+  width: 100%;
+  height: 320px;
+  box-sizing: border-box;
+  position: relative;
+  padding: 20px;
+}
+.paramsRunBtn {
+  position: absolute;
+  z-index: 6;
+  right: 20px;
+  top: 15px;
+  width: 130px;
+  height: 30px;
+  cursor: pointer;
+  font-size: 14px;
+  color: #ffffffbf;
+  text-align: center;
+  line-height: 30px;
+  box-sizing: border-box;
+  border: 1px solid rgb(0, 122, 255);
+  border-radius: 4px;
+
+  background: rgba(0, 122, 255, 0.1);
+}
+.hra {
+  display: flex;
+  justify-content: flex-start;
+  align-items: center;
+  color: #fff;
+  margin-bottom: 10px;
+}
+.hra-left {
+  display: flex;
+  width: 190px;
+  justify-content: space-between;
+  align-items: center;
+  margin-right: 80px;
+}
+.hra-right {
+  display: flex;
+  flex: 1;
+  white-space: pre-wrap; /* Allows wrapping */
+  /* min-width: 200px; */
+
+  justify-content: flex-start;
+  align-items: center;
+}
+.hra-sel {
+  width: 120px;
+}
+.warnIcon {
+  font-size: 16px;
+  color: #999;
+  margin-left: 10px;
+  cursor: pointer;
+}
+.btn {
+  /* width: 22%; */
+  margin: 5px 5px;
+  padding: 8px 15px;
+  box-sizing: border-box;
+  background: rgba(0, 122, 255, 0.25);
+  color: rgba(255, 255, 255, 0.45);
+  text-align: center;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  border: none;
+  cursor: pointer;
+  border-radius: 4px;
+  border: 1px solid rgb(0, 122, 255);
+}
+.btn:hover {
+  color: #fff;
+}
+.btnCurrent {
+  color: #fff;
+  background: #165dff;
+}
+.btn-big {
+  width: 40%;
+}
+.btn-big:hover {
+  background-color: rgb(0, 122, 255);
+  color: #fff;
+}
+</style>

+ 25 - 14
src/views/ConditionClassification/index.vue

@@ -5,7 +5,7 @@
         <s-title titleText="工况分类展示"></s-title>
       </div>
     </div>
-    <div class="ace-sear">
+    <!-- <div class="ace-sear">
       <div class="back" @click="open">
         <svg
           width="24.000000"
@@ -75,11 +75,13 @@
           </el-input>
         </div>
       </div>
-    </div>
+    </div> -->
         <div class="records listFlex">
-
+            <div class="flex-card" v-for="item in tableData" :key="item.id">
+              <card :data="item" @viewDetails="viewDetails"></card> 
+              </div>  
         </div>
-    <div class="records">
+    <!-- <div class="records">
       <el-table
         show-overflow-tooltip
         :data="tableData"
@@ -92,12 +94,7 @@
           label="工况名称"
           align="center"
         ></el-table-column>
-        <!-- <el-table-column
-          prop="time"
-          label="上传时间"
-          align="center"
-          width="240"
-        ></el-table-column> -->
+
         <el-table-column
           prop="remark"
           label="备注"
@@ -115,7 +112,7 @@
           </template>
         </el-table-column>
       </el-table>
-    </div>
+    </div> -->
     <div class="pagination custom-page">
       <el-pagination
         background
@@ -195,6 +192,7 @@ import {
   operatingConditionDel,
   operatingConditionAdd,
 } from "@/api/index";
+import card from './components/card.vue'
 const { proxy } = getCurrentInstance()!;
 // pages
 import {
@@ -317,6 +315,21 @@ const deleteRecord = async () => {
 </script>
 
 <style scoped>
+.records {
+ display: flex;
+}
+.listFlex{
+  width: 100%;
+   display: flex;
+   justify-content: space-between;
+   flex-wrap: wrap;
+
+}
+.flex-card{
+ display: flex;
+  width: 49.5%;
+  margin-top: 20px;
+}
 .el-input__icon {
   cursor: pointer;
 }
@@ -337,9 +350,7 @@ const deleteRecord = async () => {
   align-items: center;
   margin-bottom: 20px;
 }
-.records {
-  margin-top: 20px;
-}
+
 .title {
   font-size: 24px;
   color: #fff;

+ 184 - 42
src/views/FileManagement/index.vue

@@ -6,7 +6,8 @@
       </div>
     </div>
     <div class="ace-sear">
-      <div class="back" @click="open">
+      <div class="ace-left">
+           <div class="back" @click="open">
         <svg
           width="24.000000"
           height="24.000000"
@@ -63,6 +64,70 @@
           </g>
         </svg>
         上传文件
+      </div>
+       <div class="back backBatch" @click="openBatch">
+        <svg
+          width="24.000000"
+          height="24.000000"
+          viewBox="0 0 24 24"
+          fill="none"
+          xmlns="http://www.w3.org/2000/svg"
+          xmlns:xlink="http://www.w3.org/1999/xlink"
+        >
+          <desc>Created with Pixso.</desc>
+          <defs>
+            <clipPath id="clip486_7805">
+              <rect
+                id="svg"
+                width="24.000000"
+                height="24.000000"
+                fill="white"
+                fill-opacity="0"
+              />
+            </clipPath>
+            <linearGradient
+              x1="12.000000"
+              y1="0.000000"
+              x2="12.000000"
+              y2="24.000000"
+              id="paint_linear_486_7805_0"
+              gradientUnits="userSpaceOnUse"
+            >
+              <stop offset="0.041667" stop-color="#5CFFD5" />
+              <stop offset="0.887213" stop-color="#FFFFFF" />
+            </linearGradient>
+          </defs>
+          <rect
+            id="svg"
+            width="24.000000"
+            height="24.000000"
+            fill="url(#paint_linear_486_7805_0)"
+            fill-opacity="0"
+          />
+          <g clip-path="url(#clip486_7805)">
+            <path
+              id="path"
+              d="M21.41 12.92L2.74 12.92C2.18 12.92 1.73 12.47 1.73 11.91C1.73 11.36 2.18 10.91 2.74 10.91L21.41 10.91C21.96 10.91 22.41 11.36 22.41 11.91C22.41 12.47 21.96 12.92 21.41 12.92Z"
+              fill="#50B1FF"
+              fill-opacity="1.000000"
+              fill-rule="nonzero"
+            />
+            <path
+              id="path"
+              d="M11.06 21.25L11.06 2.58C11.06 2.02 11.52 1.57 12.07 1.57C12.62 1.57 13.08 2.02 13.08 2.58L13.08 21.25C13.08 21.8 12.62 22.25 12.07 22.25C11.52 22.25 11.06 21.8 11.06 21.25Z"
+              fill="#50B1FF"
+              fill-opacity="1.000000"
+              fill-rule="nonzero"
+            />
+          </g>
+        </svg>
+        上传批量文件
+      </div>
+      <div class="mockDesc">
+        当前数据范围:{{ mockTotalText.time }},包含{{
+          mockTotalText.hours
+        }}小时的数据
+      </div>
       </div>
       <div class="search">
         <div class="custom-time-input custom-search-input search-input">
@@ -136,7 +201,7 @@
   >
     <!-- 模态框内容插槽 -->
     <div class="custom-box custom-time-input">
-      <div class="confirmText">{{delDesc}}确认删除该数据吗?</div>
+      <div class="confirmText">{{ delDesc }}确认删除该数据吗?</div>
       <div class="footer">
         <div class="btnFooter cancel" @click="delVisible = false">取消</div>
         <div class="btnFooter btnFooter-big" @click="deleteRecord(form)">
@@ -155,16 +220,13 @@
     <!-- 模态框内容插槽 -->
     <div class="custom-box modal-bot custom-time-input">
       <el-form :model="form" label-width="auto" style="max-width: 600px">
-        <el-form-item required label="数据文件管理名称">
+        <el-form-item v-if="!batchStatus" required label="数据文件管理名称">
           <el-input v-model="form.name" maxlength="20" />
         </el-form-item>
         <el-form-item v-if="!!!form.id" required label="上传文件">
-          <cTree
-            v-if="isVisible"
-            v-model="form.file"
-          ></cTree>
+          <cTree v-if="isVisible" v-model="form.file"></cTree>
         </el-form-item>
-        <el-form-item label="描述">
+        <el-form-item label="描述" v-if="!batchStatus">
           <el-input
             rows="8"
             maxlength="200"
@@ -184,7 +246,7 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed, getCurrentInstance } from "vue";
+import { ref, computed, getCurrentInstance, onMounted } from "vue";
 import { ElMessage, ElMessageBox } from "element-plus";
 import sTitle from "@/components/StructTitle/index.vue";
 import cTree from "@/components/Tree/index.vue";
@@ -203,7 +265,9 @@ import {
   fileDelBefore,
   evaluateHealthStatus,
   recordAssessmentResult,
-  readDict
+  readDict,
+  mockTotal,
+  uploadBatch,
 } from "@/api/index";
 
 const { proxy } = getCurrentInstance()!;
@@ -220,6 +284,21 @@ interface DataItem {
   remark: string;
 }
 
+const mockTotalText = ref({
+  time: "",
+  hours: "0",
+});
+const getMockTotal = () => {
+  mockTotal({}).then((res) => {
+    mockTotalText.value = {
+      time: `${res.data.start_time}-${res.data.end_time}`,
+      hours: res.data.hours,
+    };
+  });
+};
+onMounted(() => {
+  getMockTotal();
+});
 const fetchDataFunction = async (
   page: number,
   pageSize: number
@@ -265,7 +344,45 @@ interface DataItem {
   name: string;
   remark: string;
 }
+const submitDataBatch = async (data: DataItem) => {
+
+  if (data.file !== undefined && data.file.length == 0 && !!!form.value.id) {
+    ElMessage({
+      message: `请选择要上传的文件`,
+      type: "error",
+    });
+    return false;
+  }
+  try {
+    proxy.$loading.start();
+    let res = null;
+    // let dataCopy = JSON.parse(JSON.stringify({ ...data, file: [] }));
+      res = await uploadBatch({paths:form.value.file});
+  
+    if (res == true || !!res.data) {
+      ElMessage({
+        message: `操作成功`,
+        type: "success",
+      });
+      fetchData();
+      closeModal(); // 提交成功后关闭模态框
+    } else {
+      ElMessage({
+        message: res.msg,
+        type: "error",
+      });
+    }
+  } catch (err) {
+    error.value = err.message || "错误";
+  } finally {
+    proxy.$loading.stop();
+  }
+};
 const submitData = async (data: DataItem) => {
+  if (batchStatus.value==true) {
+    submitDataBatch(data)
+    return false
+  }
   if (!!!data.name) {
     ElMessage({
       message: `请填写数据文件管理名称`,
@@ -286,7 +403,7 @@ const submitData = async (data: DataItem) => {
     // }
     proxy.$loading.start();
     let res = null;
-     let dataCopy=JSON.parse(JSON.stringify({...data,file:[]}))
+    let dataCopy = JSON.parse(JSON.stringify({ ...data, file: [] }));
     let status = false;
     if (!!form.value.id) {
       res = await fileUpdate(dataCopy);
@@ -353,23 +470,23 @@ const uploadFileSubmit = async (fileId: number) => {
     const executing = [];
 
     // for (const file of files) {
-      // const formData = new FormData();
-      // formData.append("paths", files);
-      // formData.append("fileId", fileId.toString());
-      
-      const p = uploadFile({
-        paths:files,
-        "fileId":fileId.toString()
-      });
-      results.push(p);
+    // const formData = new FormData();
+    // formData.append("paths", files);
+    // formData.append("fileId", fileId.toString());
+
+    const p = uploadFile({
+      paths: files,
+      fileId: fileId.toString(),
+    });
+    results.push(p);
 
-      if (limit <= files.length) {
-        const e = p.then(() => executing.splice(executing.indexOf(e), 1));
-        executing.push(e);
-        if (executing.length >= limit) {
-          await Promise.race(executing);
-        }
+    if (limit <= files.length) {
+      const e = p.then(() => executing.splice(executing.indexOf(e), 1));
+      executing.push(e);
+      if (executing.length >= limit) {
+        await Promise.race(executing);
       }
+    }
     // }
 
     return Promise.all(results);
@@ -397,7 +514,17 @@ const { isVisible, error, openModal, closeModal } = useModal();
 const form = ref({
   file: [],
 });
-const open = () => {
+const batchStatus=ref(false)
+const openBatch= () => {
+ open(1)
+};
+const open = (val) => {
+  if (val==1) {
+    batchStatus.value=true
+  }else{
+        batchStatus.value=false
+
+  }
   form.value = {
     remark: "",
     file: [],
@@ -411,18 +538,18 @@ const onCancel = () => {
 };
 // 模态框结束
 // 可靠性预测
-const toRpc=async (row:any)=>{
-      proxy.$loading.start();
-  await recordAssessmentResult({source:2,fileId:row.id})
-      proxy.$loading.stop();
+const toRpc = async (row: any) => {
+  proxy.$loading.start();
+  await recordAssessmentResult({ source: 2, fileId: row.id });
+  proxy.$loading.stop();
   router.push({
-    path:'/OperationalReliabilityPrediction',
-    query:{
-      id:row.id,
-      name:row.name
-    }
-  })
-}
+    path: "/OperationalReliabilityPrediction",
+    query: {
+      id: row.id,
+      name: row.name,
+    },
+  });
+};
 // 删除逻辑
 let delVisible = ref(false);
 let delDesc = ref(null);
@@ -430,9 +557,9 @@ let delId = ref("");
 const delBefore = async (id: number) => {
   let res = await fileDelBefore(id);
   if (res == true || !!res.data) {
-    delDesc.value="该文件已被预测过,"
-  }else{
-    delDesc.value=''
+    delDesc.value = "该文件已被预测过,";
+  } else {
+    delDesc.value = "";
   }
   delVisible.value = true;
   delId.value = id;
@@ -456,6 +583,15 @@ const deleteRecord = async () => {
 </script>
 
 <style scoped>
+.ace-left{
+  width: 60%;
+  display: flex;
+  justify-content: flex-start;
+  align-items: center;
+}
+.mockDesc{
+  color: #fff;
+}
 .el-input__icon {
   cursor: pointer;
 }
@@ -489,8 +625,10 @@ const deleteRecord = async () => {
   justify-content: space-between;
   align-items: center;
 }
+
 .back {
-  padding-left: 20px;
+  margin: 0 15px;
+  padding:0 20px;
   width: 90px;
   height: 40px;
   display: flex;
@@ -498,6 +636,10 @@ const deleteRecord = async () => {
   align-items: center;
   color: rgb(0, 139, 250);
   cursor: pointer;
+  border: 1px solid #007AFF;
+}
+.backBatch {
+    width: 120px;
 }
 .back:hover {
   text-decoration-line: underline;

+ 84 - 17
src/views/HealthStatusAnalysis/mock.vue

@@ -14,9 +14,10 @@
         <div class="mockDiv custom-time-select">
           选择时间: &nbsp;
           <el-date-picker
+          class=" custom-time-input"
             v-model="queryParamsMock.sDate"
             style="width: 140px"
-            type="date"
+            type="datetime"
             placeholder=""
           >
           </el-date-picker>
@@ -24,22 +25,28 @@
           <el-date-picker
             v-model="queryParamsMock.eDate"
             style="width: 140px"
-            type="date"
+            type="datetime"
             placeholder=""
           >
           </el-date-picker>
           &emsp; &emsp; &emsp; &emsp; &emsp; 速度控制:&emsp;<el-input
             style="width: 80px"
-                    max="60"
-            placeholder="最大不能超过60s"
+            max="60"
+            min="1"
+          class="no-arrows"
+            placeholder=""
+             type="number"
             v-model="queryParamsMock.time"
           ></el-input
           >&nbsp;秒显示&nbsp;<el-input
             style="width: 80px"
-    
+             type="number"
+                max="60"
+            min="1"
+             class="no-arrows"
             v-model="queryParamsMock.count"
           ></el-input
-          >&nbsp;分钟数据&emsp; 
+          >&nbsp;分钟数据&emsp;
           <el-button class="btn" @click="mockStart">开始</el-button>
         </div>
         <s-title titleText="系统数据监测"></s-title>
@@ -498,21 +505,33 @@ import {
   healthySetList,
   measurementPoints,
   devicesAndCategories,
+  updateDataRangeSpeed,
+  mockCacheData
 } from "@/api/index";
 const wsMockUrl = import.meta.env.VITE_WS_MOCK_URL as string;
 const wsMockClient = new WebSocketClient(wsMockUrl);
 const queryParamsMock = ref({
-  time: null,
+  time: 1,
   eDate: null,
   sDate: null,
-  count: 0,
+  count: 1,
 });
+watch(
+  () => queryParamsMock.value.sDate,
+  (newSDate) => {
+    if (newSDate) {
+      queryParamsMock.value.eDate = moment(newSDate).add(1, 'hour').toDate();
+    }
+  }
+);
 const { proxy } = getCurrentInstance()!;
 let gridData = ref(null);
 const getHStatus = async () => {
   let result = await healthySetList({});
   gridData.value = result.data;
 };
+let lineParamsAllRef = ref([]);
+
 onMounted(() => {
   getcateData();
   getPointData(btnBigIndex.value, "温度");
@@ -532,6 +551,15 @@ onMounted(() => {
       checkedParams.value = Object.values(COLUMN_MAP).slice(0, 5);
     }
   });
+  mockCacheData({}).then((res:any)=>{
+        lineParamsAllRef.value=res.data.map((its)=>{
+          return {
+data:its
+          }
+          });
+        // debugger
+
+  })
   // 处理接收到的消息
   wsMockClient.onMessage = (data: string) => {
     try {
@@ -578,6 +606,32 @@ const mockStart = () => {
   wsMockClient.connect();
   // 向服务器发送消息
   wsMockClient.send("你好!");
+  if (queryParamsMock.value.time>60) {
+        ElMessage({
+      message: `最大不超过60s`,
+      type: "error",
+    });
+    return false
+  }
+    if (!!!queryParamsMock.value.sDate) {
+        ElMessage({
+      message: `请选择开始时间`,
+      type: "error",
+    });
+    return false
+  }
+  
+  updateDataRangeSpeed({
+    start_time: moment(queryParamsMock.value.sDate).format("YYYY-MM-DD HH:mm:ss"),
+    end_time: moment(queryParamsMock.value.eDate).format("YYYY-MM-DD HH:mm:ss"),
+    interval: queryParamsMock.value.time,
+    batch_size: Number(queryParamsMock.value.count),
+  }).then((res: any) => {
+         ElMessage({
+      message: `设置成功!`,
+      type: "success",
+    });
+  });
 };
 let cateBigRef = ref([]);
 let cateSmallRef = ref([]);
@@ -602,7 +656,6 @@ const getPointData = async (deviceName, categoryName) => {
   setParams.value = data.data.map((its) => its.pointName);
 };
 // 获取所有显示参数
-let lineParamsAllRef = ref([]);
 watch(
   () => lineParamsAllRef.value,
   (newdata: any) => {
@@ -791,6 +844,10 @@ const convertToChartData = (
     name: propertyName,
     // name: propertyName,
     data: selectedData.map((item) => item.data[inverParams[propertyName]]),
+    //   data: selectedData.map((item) => {
+    // const key = inverParams[propertyName];
+    // return key && item.data ? item.data[key] : null; 
+  // }),
   }));
 };
 const formatPressure = (value: number | string) => {
@@ -1098,14 +1155,24 @@ const healthColor = (status: string) => {
   }
 };
 </script>
+<style lang="css">
+  .no-arrows::-webkit-outer-spin-button,
+.no-arrows::-webkit-inner-spin-button {
+  -webkit-appearance: none;
+  margin: 0;
+}
 
+.no-arrows {
+  -moz-appearance: textfield; /* Firefox */
+}
+</style>
 <style scoped>
-.tools{
-    display: flex;
-    justify-content: flex-start;
+.tools {
+  display: flex;
+  justify-content: flex-start;
 }
 .arrow-button {
-    margin: 0 10px;
+  margin: 0 10px;
   display: flex;
   justify-content: center;
   align-items: center;
@@ -1141,10 +1208,10 @@ const healthColor = (status: string) => {
   transform: rotate(225deg);
   position: absolute;
 }
-  .arrow-button-left:hover::before,
-    .arrow-button-right:hover::before {
-      border-color: #0982FE; 
-    }
+.arrow-button-left:hover::before,
+.arrow-button-right:hover::before {
+  border-color: #0982fe;
+}
 .mockDiv {
   display: flex;
   justify-content: flex-start;

+ 23 - 5
src/views/MaintenanceStrategyAssistance/his.vue

@@ -62,7 +62,7 @@
       </div>
     </div>
       <div class="records">
-        <el-table border  :data="tableData" style="width: 100%" align="center" class="custom-table">
+        <el-table border v-if="routeType!=''"  :data="tableData" style="width: 100%" align="center" class="custom-table">
           <el-table-column
             prop="name"
             label="设备名称"
@@ -95,11 +95,14 @@
               <span>{{ scope.row.createTime }}</span>
             </template>
           </el-table-column>
-          <el-table-column label="操作" width="120"  align="center">
+          <el-table-column label="操作" width="160" v-if="routeType=='auto'"  align="center">
             <template v-slot="scope">
-              <el-button class="btns-warn"  link @click="delBefore(scope.row.id)"
+              <!-- <el-button class="btns-warn"  link @click="delBefore(scope.row.id)"
                 >删除</el-button
-              >
+              > -->
+                <el-button class="btns" link @click="toRpc(scope.row)"
+          >跳转至可靠性预测</el-button
+        >
             </template>
           </el-table-column>
         </el-table>
@@ -178,10 +181,23 @@ const getHealthStatusText = (status: number) => {
   }
   }
 
-
+// 可靠性预测
+const toRpc=async (row:any)=>{
+      proxy.$loading.start();
+  await recordAssessmentResult({source:2,fileId:row.id})
+      proxy.$loading.stop();
+  router.push({
+    path:'/OperationalReliabilityPrediction',
+    query:{
+      id:row.id,
+      name:row.name
+    }
+  })
+}
 import {
   repairHisList,
   repairHisDel,
+  recordAssessmentResult
 } from "@/api/index";
 const { proxy } = getCurrentInstance()!;
 // pages
@@ -220,9 +236,11 @@ const queryParams = ref({
   name: "",
 });
 // 初始化逻辑
+const routeType=ref('')
 onMounted(() => {
   const pageId = route.query.id;
   const name = route.query.name;
+  routeType.value=route.query.type;
   if (pageId) {
     queryParams.value.id = Number(pageId);
  

Разница между файлами не показана из-за своего большого размера
+ 5 - 88
src/views/MaintenanceStrategyAssistance/index.vue


Разница между файлами не показана из-за своего большого размера
+ 115 - 0
src/views/MaintenanceStrategyAssistance/index_bak.vue


+ 450 - 0
src/views/MaintenanceStrategyAssistance/offline/index.vue

@@ -0,0 +1,450 @@
+<template>
+  <div class="ace-sear">
+    <div class="custom-time-select">
+      <el-select
+        class="ace-sel"
+        v-model="queryParams.status"
+        @change="fetchData"
+        placeholder="全部"
+      >
+        <template v-slot:prefix>
+          <el-icon color="rgba(255, 255, 255, 0.75)">
+            <Filter />
+          </el-icon>
+        </template>
+        <el-option label="全部" value="null"></el-option>
+        <el-option label="有故障" value="2"></el-option>
+        <el-option label="无故障" value="1"></el-option>
+      </el-select>
+    </div>
+    <div
+      class="custom-time-input custom-search-input search-input"
+
+    >
+      <el-input placeholder="请输入预测文件名称" v-model="queryParams.name">
+        <template #suffix>
+          <el-icon
+            class="el-input__icon"
+            style="cursor: pointer"
+            @click="fetchData"
+            ><Search
+          /></el-icon>
+        </template>
+      </el-input>
+    </div>
+  </div>
+  <el-table :data="tableData" align="center" class="custom-table recordTable">
+    <el-table-column
+      prop="name"
+      label="记录名称"
+      align="center"
+    ></el-table-column>
+    <el-table-column
+      prop="name"
+      label="预测文件名称"
+      align="center"
+    ></el-table-column>
+    <!-- <el-table-column prop="sts" label="时间" width="140" align="center">
+          <template v-slot="scope">
+            <span :class="getHealthStatusClass(scope.row.sts)">
+              {{ getHealthStatusText(scope.row.sts) }}
+            </span>
+          </template>
+        </el-table-column> -->
+    <!-- <el-table-column prop="lifetime" label="时间" width="320" align="center">
+      <template v-slot="scope">
+        <span>{{ scope.row.startTime }} - {{ scope.row.endTime }}</span>
+      </template>
+    </el-table-column> -->
+    <el-table-column label="是否故障" width="110" align="center">
+      <template v-slot="scope">
+        <span :class="getHealthStatusClass(scope.row.sts)">{{
+          scope.row.sts == 2 ? "有故障" : "无故障"
+        }}</span>
+      </template>
+    </el-table-column>
+    <el-table-column label="操作" width="280" align="center">
+      <template v-slot="scope">
+        <el-button
+          class="btns"
+          link
+          @click="viewDetails(scope.row.id, scope.row.name)"
+          >详情</el-button
+        >
+          <el-button class="btns" link @click="toRpc(scope.row)"
+          >跳转至可靠性预测</el-button
+        >
+        <!--  <el-button class="btns-warn" link @click="delBefore(scope.row.id)"
+          >删除</el-button
+        > -->
+      </template>
+    </el-table-column>
+  </el-table>
+
+  <div class="pagination custom-page off-page">
+    <el-pagination
+      background
+      v-model:current-page="currentPage"
+      v-model:page-size="pageSize"
+      layout="prev, pager, next"
+      :total="totalItems"
+      hide-on-single-page
+    >
+    </el-pagination>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ElMessage } from "element-plus";
+import sTitle from "@/components/StructTitle/index.vue";
+import { Filter } from "@element-plus/icons-vue";
+import { ref, computed, getCurrentInstance } from "vue";
+
+import { repairList,recordAssessmentResult } from "@/api/index";
+const { proxy } = getCurrentInstance()!;
+// pages
+import {
+  useServerPagination,
+  PaginationResponse,
+} from "@/utils/useServerPagination";
+// 可靠性预测
+const toRpc=async (row:any)=>{
+      proxy.$loading.start();
+  await recordAssessmentResult({source:2,fileId:row.id})
+      proxy.$loading.stop();
+  router.push({
+    path:'/OperationalReliabilityPrediction',
+    query:{
+      id:row.id,
+      name:row.name
+    }
+  })
+}
+// table逻辑
+interface DataItem {
+  id: number;
+  name: string;
+  remark: string;
+}
+
+const fetchDataFunction = async (
+  page: number,
+  pageSize: number
+): Promise<PaginationResponse<DataItem>> => {
+  // 开始日期结束日期要有就都有 要不就都没有
+  if (!!queryParams.value.startTime || !!queryParams.value.endTime) {
+    if (!!queryParams.value.startTime && !!queryParams.value.endTime) {
+    } else {
+      // ElMessage({
+      //   message: `请选择开始日期和结束日期`,
+      //   type: "info",
+      // });
+      return false;
+    }
+  }
+  proxy.$loading.start();
+  const response = await repairList({
+    current: page,
+    size: 9,
+    status: "",
+    type: "2",
+    name: "",
+    startTime: "",
+    endTime: "",
+    ...queryParams.value,
+  });
+  proxy.$loading.stop();
+  return {
+    data: response.data.records,
+    total: response.data.total,
+  };
+};
+const pagination = useServerPagination<DataItem>(fetchDataFunction);
+let { tableData, currentPage, pageSize, totalItems, loading, fetchData } =
+  pagination;
+const searchClick = fetchData();
+const queryParams = ref({
+  name: "",
+  status: "null",
+});
+import { useRoute, useRouter } from "vue-router";
+const router = useRouter();
+const route = useRoute(); // 获取当前路由对象
+const activeTab = ref("1");
+const setActiveTab = (val: number) => {
+  activeTab.value = val;
+  queryParams.value = {};
+  currentPage.value = 1;
+  fetchData();
+};
+const viewDetails = (id: number) => {
+  router.push({
+    path: "/repair/MaintenanceStrategyAssistanceView",
+    query: { id, type: "auto" },
+  });
+  // ElMessage({
+  //   message: `查看详情: ${id}`,
+  //   type: "info",
+  // });
+};
+const getHealthStatusClass = (sts: number) => {
+  switch (sts) {
+    case 1:
+      return "success";
+    case 2:
+      return "dange";
+  }
+};
+</script>
+
+<style scoped>
+.off-page {
+  width: 100%;
+  display: flex;
+  justify-content: center;
+}
+.success {
+  background: linear-gradient(180deg, rgb(92, 255, 213), rgb(255, 255, 255));
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
+  text-fill-color: transparent;
+  /* font-size: 20px; */
+  font-weight: 400;
+  line-height: 30px;
+  letter-spacing: 0%;
+  text-align: left;
+}
+.dange {
+  background: linear-gradient(180deg, rgb(255, 0, 0), rgb(255, 255, 255));
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
+  text-fill-color: transparent;
+  /* font-size: 20px; */
+  font-weight: 400;
+  line-height: 30px;
+  letter-spacing: 0%;
+  text-align: left;
+}
+.maintenance-strategy-assistance {
+  color: #fff;
+}
+
+.header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+}
+
+.title {
+  font-size: 24px;
+  color: #fff;
+}
+
+.filters {
+  display: flex;
+  align-items: center;
+}
+
+.filters > * {
+  margin-right: 20px;
+}
+
+.tabs {
+  display: flex;
+  margin-bottom: 20px;
+}
+
+.tab {
+  padding: 10px 20px;
+  cursor: pointer;
+  color: #fff;
+  background: url(../../assets/img/j1.png);
+  background-size: 100% 100%;
+  width: 135px;
+  height: 36px;
+  text-align: center;
+  color: rgba(255, 255, 255, 0.45);
+  font-family: "YouSheTitleHei";
+  font-size: 24px;
+  font-weight: 400;
+  line-height: 36px;
+  letter-spacing: 0%;
+  text-align: center;
+}
+.tab1 {
+  background: url(../../assets/img/j1.png);
+  background-size: 100% 100%;
+  transform: rotate(180deg); /* 旋转180度 */
+}
+.tab1 > * {
+  transform: rotate(-180deg); /* 容器内所有子元素反向旋转180度 */
+}
+.tab1.active {
+  background: url(../../assets/img/j2.png);
+  background-size: 100% 100%;
+  transform: rotate(180deg); /* 旋转180度 */
+}
+.tab2.active {
+  background: url(../../assets/img/j2.png);
+  background-size: 100% 100%;
+}
+.tab1.active > * {
+  transform: rotate(-180deg); /* 容器内所有子元素反向旋转180度 */
+}
+.tab.active .tab-text {
+  background: linear-gradient(180deg, rgb(0, 139, 250), rgb(255, 255, 255));
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
+  text-fill-color: transparent;
+}
+
+.records {
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: flex-start;
+  margin-top: 20px;
+}
+.recordTable {
+  width: 100%;
+  height: 600px;
+  padding-top: 20px;
+  padding-left: 10px;
+  padding-right: 10px;
+  margin-top: 10px;
+  border: 1px solid #3897ff;
+  overflow-y: auto;
+}
+/* .recordTable::before {
+  content: "自动记录区";
+  line-height: 30px;
+
+  position: absolute;
+  width: 103px;
+  height: 30px;
+  left: 0px;
+  top: 0px;
+  border: 1px solid rgb(22, 93, 255);
+  border-radius: 4px;
+
+  background: rgba(56, 151, 255, 0.45);
+} */
+.setItem {
+  margin: 0 0.5%;
+  background: url(../../assets/img/3.png);
+  width: 32%;
+  height: 208px;
+  background-size: 100% 100%;
+  padding: 30px;
+  box-sizing: border-box;
+}
+.record {
+  padding: 20px;
+  border-radius: 8px;
+}
+
+.record-header {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 10px;
+  width: calc(100% - 0px);
+  height: 50px;
+
+  /* box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25),0px 4px 16px 0px rgb(0, 122, 255); */
+}
+
+.record-title {
+  font-size: 20px;
+  color: rgba(255, 255, 255, 0.75);
+  line-height: 40px;
+  border-bottom: 1px solid #2b69ac;
+  width: 100%;
+  white-space: nowrap;
+
+  overflow: hidden;
+
+  /* clip====裁剪===默认效果 */
+
+  text-overflow: ellipsis;
+}
+
+.record-time {
+  color: #ccc;
+}
+.gz {
+  display: flex;
+  justify-content: space-between;
+  align-content: center;
+  margin-top: 20px;
+}
+.gz-cont {
+  width: 160px;
+}
+.record-body {
+  font-size: 20px;
+  padding: 20px 0;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  color: rgba(255, 255, 255, 0.75);
+}
+.btn {
+  color: rgb(56, 151, 255);
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  width: 60px;
+  font-size: 18px;
+  line-height: 40px;
+  cursor: pointer;
+}
+.valid {
+  background: linear-gradient(180deg, rgb(92, 255, 213), rgb(255, 255, 255));
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
+  text-fill-color: transparent;
+  font-size: 20px;
+  font-weight: 400;
+  line-height: 30px;
+  letter-spacing: 0%;
+  text-align: left;
+}
+
+.invalid {
+  background: linear-gradient(180deg, rgb(255, 0, 0), rgb(255, 255, 255));
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
+  text-fill-color: transparent;
+  font-size: 20px;
+  font-weight: 400;
+  line-height: 30px;
+  letter-spacing: 0%;
+  text-align: left;
+}
+.ace-sear {
+  display: flex;
+  justify-content: flex-start;
+  align-items: center;
+  margin-bottom: 20px;
+}
+.ace-sel {
+  width: 120px;
+  margin-right: 20px;
+}
+.line-select {
+  margin: 0 10px;
+  width: 30px;
+  height: 2px;
+  background: rgba(131, 187, 255, 0.65);
+}
+.pagination {
+  margin-top: 20px;
+  display: flex;
+  justify-content: center;
+}
+</style>

+ 0 - 0
src/views/MaintenanceStrategyAssistance/offline/离线


+ 449 - 0
src/views/MaintenanceStrategyAssistance/record/auto.vue

@@ -0,0 +1,449 @@
+<template>
+  <div class="ace-sear">
+    <div class="custom-time-select">
+      <el-select
+        class="ace-sel"
+        v-model="queryParams.status"
+        @change="fetchData"
+        placeholder="全部"
+      >
+        <template v-slot:prefix>
+          <el-icon color="rgba(255, 255, 255, 0.75)">
+            <Filter />
+          </el-icon>
+        </template>
+        <el-option label="全部" value="null"></el-option>
+        <el-option label="有故障" value="2"></el-option>
+        <el-option label="无故障" value="1"></el-option>
+      </el-select>
+    </div>
+    <div class="custom-time-input" v-if="activeTab == 1">
+      <el-date-picker
+        v-model="queryParams.startTime"
+        type="date"
+        :value-format="'YYYY-MM-DD HH:mm:ss'"
+        @change="fetchData"
+        placeholder="开始日期"
+      ></el-date-picker>
+    </div>
+
+    <div class="line-select" v-if="activeTab == 1"></div>
+
+    <div class="custom-time-input" v-if="activeTab == 1">
+      <el-date-picker
+        v-model="queryParams.endTime"
+        type="date"
+        :value-format="'YYYY-MM-DD 23:59:59'"
+        @change="fetchData"
+        placeholder="结束日期"
+      ></el-date-picker>
+    </div>
+
+    <div
+      class="custom-time-input custom-search-input search-input"
+      v-if="activeTab == 2"
+    >
+      <el-input placeholder="请输入预测文件名称" v-model="queryParams.name">
+        <template #suffix>
+          <el-icon
+            class="el-input__icon"
+            style="cursor: pointer"
+            @click="fetchData"
+            ><Search
+          /></el-icon>
+        </template>
+      </el-input>
+    </div>
+  </div>
+  <el-table :data="tableData" align="center" class="custom-table recordTable">
+    <el-table-column
+      prop="name"
+      label="记录名称"
+      align="center"
+    ></el-table-column>
+    <!-- <el-table-column prop="sts" label="时间" width="140" align="center">
+          <template v-slot="scope">
+            <span :class="getHealthStatusClass(scope.row.sts)">
+              {{ getHealthStatusText(scope.row.sts) }}
+            </span>
+          </template>
+        </el-table-column> -->
+    <el-table-column prop="lifetime" label="时间" width="320" align="center">
+      <template v-slot="scope">
+        <span>{{ scope.row.startTime }} - {{ scope.row.endTime }}</span>
+      </template>
+    </el-table-column>
+    <el-table-column label="是否故障" width="110"  align="center">
+      <template v-slot="scope">
+        <span :class="getHealthStatusClass(scope.row.sts)">{{
+          scope.row.sts == 2 ? "有故障" : "无故障"
+        }}</span>
+      </template>
+    </el-table-column>
+    <el-table-column label="操作" width="120" align="center">
+      <template v-slot="scope">
+        <el-button
+          class="btns"
+          link
+          @click="viewDetails(scope.row.id, scope.row.name)"
+          >详情</el-button
+        >
+        <!-- <el-button class="btns" link @click="exportRecord(scope.row.name)"
+          >跳转至可靠性预测</el-button
+        >
+        <el-button class="btns-warn" link @click="delBefore(scope.row.id)"
+          >删除</el-button
+        > -->
+      </template>
+    </el-table-column>
+  </el-table>
+
+  <div class="pagination custom-page">
+    <el-pagination
+      background
+      v-model:current-page="currentPage"
+      v-model:page-size="pageSize"
+      layout="prev, pager, next"
+      :total="totalItems"
+      hide-on-single-page
+    >
+    </el-pagination>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ElMessage } from "element-plus";
+import sTitle from "@/components/StructTitle/index.vue";
+import { Filter } from "@element-plus/icons-vue";
+import { ref, computed, getCurrentInstance } from "vue";
+
+import { repairList } from "@/api/index";
+const { proxy } = getCurrentInstance()!;
+// pages
+import {
+  useServerPagination,
+  PaginationResponse,
+} from "@/utils/useServerPagination";
+// table逻辑
+interface DataItem {
+  id: number;
+  name: string;
+  remark: string;
+}
+
+const fetchDataFunction = async (
+  page: number,
+  pageSize: number
+): Promise<PaginationResponse<DataItem>> => {
+  // 开始日期结束日期要有就都有 要不就都没有
+  if (!!queryParams.value.startTime || !!queryParams.value.endTime) {
+    if (!!queryParams.value.startTime && !!queryParams.value.endTime) {
+    } else {
+      // ElMessage({
+      //   message: `请选择开始日期和结束日期`,
+      //   type: "info",
+      // });
+      return false;
+    }
+  }
+  proxy.$loading.start();
+  const response = await repairList({
+    current: page,
+    size: 9,
+    status: "",
+    type: activeTab.value == 1 ? "1" : "2",
+    name: "",
+    startTime: "",
+    endTime: "",
+    ...queryParams.value,
+  });
+  proxy.$loading.stop();
+  return {
+    data: response.data.records,
+    total: response.data.total,
+  };
+};
+const pagination = useServerPagination<DataItem>(fetchDataFunction);
+let { tableData, currentPage, pageSize, totalItems, loading, fetchData } =
+  pagination;
+const searchClick = fetchData();
+const queryParams = ref({
+  name: "",
+  status: "null",
+});
+import { useRoute, useRouter } from "vue-router";
+const router = useRouter();
+const route = useRoute(); // 获取当前路由对象
+const activeTab = ref("1");
+const setActiveTab = (val: number) => {
+  activeTab.value = val;
+  queryParams.value = {};
+  currentPage.value = 1;
+  fetchData();
+};
+const viewDetails = (id: number) => {
+  router.push({
+    path: "/repair/MaintenanceStrategyAssistanceView",
+    query: { id,type:'auto' },
+  });
+  // ElMessage({
+  //   message: `查看详情: ${id}`,
+  //   type: "info",
+  // });
+};
+const getHealthStatusClass = (sts: number) => {
+  switch (sts) {
+    case 1:
+      return "success";
+    case 2:
+      return "dange";
+  }
+};
+</script>
+
+<style scoped>
+.success {
+  background: linear-gradient(180deg, rgb(92, 255, 213), rgb(255, 255, 255));
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
+  text-fill-color: transparent;
+  /* font-size: 20px; */
+  font-weight: 400;
+  line-height: 30px;
+  letter-spacing: 0%;
+  text-align: left;
+}
+.dange {
+  background: linear-gradient(180deg, rgb(255, 0, 0), rgb(255, 255, 255));
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
+  text-fill-color: transparent;
+  /* font-size: 20px; */
+  font-weight: 400;
+  line-height: 30px;
+  letter-spacing: 0%;
+  text-align: left;
+}
+.maintenance-strategy-assistance {
+  color: #fff;
+}
+
+.header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+}
+
+.title {
+  font-size: 24px;
+  color: #fff;
+}
+
+.filters {
+  display: flex;
+  align-items: center;
+}
+
+.filters > * {
+  margin-right: 20px;
+}
+
+.tabs {
+  display: flex;
+  margin-bottom: 20px;
+}
+
+.tab {
+  padding: 10px 20px;
+  cursor: pointer;
+  color: #fff;
+  background: url(../../assets/img/j1.png);
+  background-size: 100% 100%;
+  width: 135px;
+  height: 36px;
+  text-align: center;
+  color: rgba(255, 255, 255, 0.45);
+  font-family: "YouSheTitleHei";
+  font-size: 24px;
+  font-weight: 400;
+  line-height: 36px;
+  letter-spacing: 0%;
+  text-align: center;
+}
+.tab1 {
+  background: url(../../assets/img/j1.png);
+  background-size: 100% 100%;
+  transform: rotate(180deg); /* 旋转180度 */
+}
+.tab1 > * {
+  transform: rotate(-180deg); /* 容器内所有子元素反向旋转180度 */
+}
+.tab1.active {
+  background: url(../../assets/img/j2.png);
+  background-size: 100% 100%;
+  transform: rotate(180deg); /* 旋转180度 */
+}
+.tab2.active {
+  background: url(../../assets/img/j2.png);
+  background-size: 100% 100%;
+}
+.tab1.active > * {
+  transform: rotate(-180deg); /* 容器内所有子元素反向旋转180度 */
+}
+.tab.active .tab-text {
+  background: linear-gradient(180deg, rgb(0, 139, 250), rgb(255, 255, 255));
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
+  text-fill-color: transparent;
+}
+
+.records {
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: flex-start;
+  margin-top: 20px;
+}
+.recordTable {
+  width: 100%;
+  height: 630px;
+  padding-top: 50px;
+  padding-left: 10px;
+  padding-right: 10px;
+  margin-top: 10px;
+  border: 1px solid #3897ff;
+  overflow-y: auto;
+}
+.recordTable::before {
+  content: "自动记录区";
+  line-height: 30px;
+
+  position: absolute;
+  width: 103px;
+  height: 30px;
+  left: 0px;
+  top: 0px;
+  border: 1px solid rgb(22, 93, 255);
+  border-radius: 4px;
+
+  background: rgba(56, 151, 255, 0.45);
+}
+.setItem {
+  margin: 0 0.5%;
+  background: url(../../assets/img/3.png);
+  width: 32%;
+  height: 208px;
+  background-size: 100% 100%;
+  padding: 30px;
+  box-sizing: border-box;
+}
+.record {
+  padding: 20px;
+  border-radius: 8px;
+}
+
+.record-header {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 10px;
+  width: calc(100% - 0px);
+  height: 50px;
+
+  /* box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25),0px 4px 16px 0px rgb(0, 122, 255); */
+}
+
+.record-title {
+  font-size: 20px;
+  color: rgba(255, 255, 255, 0.75);
+  line-height: 40px;
+  border-bottom: 1px solid #2b69ac;
+  width: 100%;
+  white-space: nowrap;
+
+  overflow: hidden;
+
+  /* clip====裁剪===默认效果 */
+
+  text-overflow: ellipsis;
+}
+
+.record-time {
+  color: #ccc;
+}
+.gz {
+  display: flex;
+  justify-content: space-between;
+  align-content: center;
+  margin-top: 20px;
+}
+.gz-cont {
+  width: 160px;
+}
+.record-body {
+  font-size: 20px;
+  padding: 20px 0;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  color: rgba(255, 255, 255, 0.75);
+}
+.btn {
+  color: rgb(56, 151, 255);
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  width: 60px;
+  font-size: 18px;
+  line-height: 40px;
+  cursor: pointer;
+}
+.valid {
+  background: linear-gradient(180deg, rgb(92, 255, 213), rgb(255, 255, 255));
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
+  text-fill-color: transparent;
+  font-size: 20px;
+  font-weight: 400;
+  line-height: 30px;
+  letter-spacing: 0%;
+  text-align: left;
+}
+
+.invalid {
+  background: linear-gradient(180deg, rgb(255, 0, 0), rgb(255, 255, 255));
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
+  text-fill-color: transparent;
+  font-size: 20px;
+  font-weight: 400;
+  line-height: 30px;
+  letter-spacing: 0%;
+  text-align: left;
+}
+.ace-sear {
+  display: flex;
+  justify-content: flex-start;
+  align-items: center;
+  margin-bottom: 20px;
+}
+.ace-sel {
+  width: 120px;
+  margin-right: 20px;
+}
+.line-select {
+  margin: 0 10px;
+  width: 30px;
+  height: 2px;
+  background: rgba(131, 187, 255, 0.65);
+}
+.pagination {
+  margin-top: 20px;
+  display: flex;
+  justify-content: center;
+}
+</style>

+ 462 - 0
src/views/MaintenanceStrategyAssistance/record/hand.vue

@@ -0,0 +1,462 @@
+<template>
+  <div class="ace-sear">
+    <div class="custom-time-select">
+      <el-select
+        class="ace-sel"
+        v-model="queryParams.status"
+        @change="fetchData"
+        placeholder="全部"
+      >
+        <template v-slot:prefix>
+          <el-icon color="rgba(255, 255, 255, 0.75)">
+            <Filter />
+          </el-icon>
+        </template>
+        <el-option label="全部" value="null"></el-option>
+        <el-option label="有故障" value="2"></el-option>
+        <el-option label="无故障" value="1"></el-option>
+      </el-select>
+    </div>
+    <div class="custom-time-input" v-if="activeTab == 1">
+      <el-date-picker
+        v-model="queryParams.startTime"
+        type="date"
+        :value-format="'YYYY-MM-DD HH:mm:ss'"
+        @change="fetchData"
+        placeholder="开始日期"
+      ></el-date-picker>
+    </div>
+
+    <div class="line-select" v-if="activeTab == 1"></div>
+
+    <div class="custom-time-input" v-if="activeTab == 1">
+      <el-date-picker
+        v-model="queryParams.endTime"
+        type="date"
+        :value-format="'YYYY-MM-DD 23:59:59'"
+        @change="fetchData"
+        placeholder="结束日期"
+      ></el-date-picker>
+    </div>
+
+    <div
+      class="custom-time-input custom-search-input search-input"
+      v-if="activeTab == 2"
+    >
+      <el-input placeholder="请输入预测文件名称" v-model="queryParams.name">
+        <template #suffix>
+          <el-icon
+            class="el-input__icon"
+            style="cursor: pointer"
+            @click="fetchData"
+            ><Search
+          /></el-icon>
+        </template>
+      </el-input>
+    </div>
+  </div>
+  <el-table :data="tableData" align="center" class="custom-table recordTable">
+    <el-table-column
+      prop="name"
+      label="记录名称"
+      align="center"
+    ></el-table-column>
+    <!-- <el-table-column prop="sts" label="时间" width="140" align="center">
+          <template v-slot="scope">
+            <span :class="getHealthStatusClass(scope.row.sts)">
+              {{ getHealthStatusText(scope.row.sts) }}
+            </span>
+          </template>
+        </el-table-column> -->
+    <el-table-column prop="lifetime" label="时间" width="320" align="center">
+      <template v-slot="scope">
+        <span>{{ scope.row.startTime }} - {{ scope.row.endTime }}</span>
+      </template>
+    </el-table-column>
+    <el-table-column label="是否故障" width="110" align="center">
+      <template v-slot="scope">
+        <span :class="getHealthStatusClass(scope.row.sts)">{{
+          scope.row.sts == 2 ? "有故障" : "无故障"
+        }}</span>
+      </template>
+    </el-table-column>
+    <el-table-column label="操作" width="280" align="center">
+      <template v-slot="scope">
+        <el-button
+          class="btns"
+          link
+          @click="viewDetails(scope.row.id, scope.row.name)"
+          >详情</el-button
+        >
+        <el-button class="btns" link @click="toRpc(scope.row)"
+          >跳转至可靠性预测</el-button
+        >
+        <el-button class="btns-warn" link @click="delBefore(scope.row.id)"
+          >删除</el-button
+        >
+      </template>
+    </el-table-column>
+  </el-table>
+
+  <div class="pagination custom-page">
+    <el-pagination
+      background
+      v-model:current-page="currentPage"
+      v-model:page-size="pageSize"
+      layout="prev, pager, next"
+      :total="totalItems"
+      hide-on-single-page
+    >
+    </el-pagination>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ElMessage } from "element-plus";
+import sTitle from "@/components/StructTitle/index.vue";
+import { Filter } from "@element-plus/icons-vue";
+import { ref, computed, getCurrentInstance } from "vue";
+
+import { repairList,recordAssessmentResult } from "@/api/index";
+const { proxy } = getCurrentInstance()!;
+// pages
+import {
+  useServerPagination,
+  PaginationResponse,
+} from "@/utils/useServerPagination";
+// table逻辑
+interface DataItem {
+  id: number;
+  name: string;
+  remark: string;
+}
+
+const fetchDataFunction = async (
+  page: number,
+  pageSize: number
+): Promise<PaginationResponse<DataItem>> => {
+  // 开始日期结束日期要有就都有 要不就都没有
+  if (!!queryParams.value.startTime || !!queryParams.value.endTime) {
+    if (!!queryParams.value.startTime && !!queryParams.value.endTime) {
+    } else {
+      // ElMessage({
+      //   message: `请选择开始日期和结束日期`,
+      //   type: "info",
+      // });
+      return false;
+    }
+  }
+  proxy.$loading.start();
+  const response = await repairList({
+    current: page,
+    size: 9,
+    status: "",
+    type: activeTab.value == 1 ? "1" : "2",
+    name: "",
+    startTime: "",
+    endTime: "",
+    ...queryParams.value,
+  });
+  proxy.$loading.stop();
+  return {
+    data: response.data.records,
+    total: response.data.total,
+  };
+};
+const pagination = useServerPagination<DataItem>(fetchDataFunction);
+let { tableData, currentPage, pageSize, totalItems, loading, fetchData } =
+  pagination;
+const searchClick = fetchData();
+const queryParams = ref({
+  name: "",
+  status: "null",
+});
+import { useRoute, useRouter } from "vue-router";
+const router = useRouter();
+const route = useRoute(); // 获取当前路由对象
+// 可靠性预测
+const toRpc=async (row:any)=>{
+      proxy.$loading.start();
+  await recordAssessmentResult({source:2,fileId:row.id})
+      proxy.$loading.stop();
+  router.push({
+    path:'/OperationalReliabilityPrediction',
+    query:{
+      id:row.id,
+      name:row.name
+    }
+  })
+}
+const activeTab = ref("1");
+const setActiveTab = (val: number) => {
+  activeTab.value = val;
+  queryParams.value = {};
+  currentPage.value = 1;
+  fetchData();
+};
+const viewDetails = (id: number) => {
+  router.push({
+    path: "/repair/MaintenanceStrategyAssistanceView",
+    query: { id,type:'hand' },
+  });
+  // ElMessage({
+  //   message: `查看详情: ${id}`,
+  //   type: "info",
+  // });
+};
+const getHealthStatusClass = (sts: number) => {
+  switch (sts) {
+    case 1:
+      return "success";
+    case 2:
+      return "dange";
+  }
+};
+</script>
+
+<style scoped>
+.success {
+  background: linear-gradient(180deg, rgb(92, 255, 213), rgb(255, 255, 255));
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
+  text-fill-color: transparent;
+  /* font-size: 20px; */
+  font-weight: 400;
+  line-height: 30px;
+  letter-spacing: 0%;
+  text-align: left;
+}
+.dange {
+  background: linear-gradient(180deg, rgb(255, 0, 0), rgb(255, 255, 255));
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
+  text-fill-color: transparent;
+  /* font-size: 20px; */
+  font-weight: 400;
+  line-height: 30px;
+  letter-spacing: 0%;
+  text-align: left;
+}
+.maintenance-strategy-assistance {
+  color: #fff;
+}
+
+.header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+}
+
+.title {
+  font-size: 24px;
+  color: #fff;
+}
+
+.filters {
+  display: flex;
+  align-items: center;
+}
+
+.filters > * {
+  margin-right: 20px;
+}
+
+.tabs {
+  display: flex;
+  margin-bottom: 20px;
+}
+
+.tab {
+  padding: 10px 20px;
+  cursor: pointer;
+  color: #fff;
+  background: url(../../assets/img/j1.png);
+  background-size: 100% 100%;
+  width: 135px;
+  height: 36px;
+  text-align: center;
+  color: rgba(255, 255, 255, 0.45);
+  font-family: "YouSheTitleHei";
+  font-size: 24px;
+  font-weight: 400;
+  line-height: 36px;
+  letter-spacing: 0%;
+  text-align: center;
+}
+.tab1 {
+  background: url(../../assets/img/j1.png);
+  background-size: 100% 100%;
+  transform: rotate(180deg); /* 旋转180度 */
+}
+.tab1 > * {
+  transform: rotate(-180deg); /* 容器内所有子元素反向旋转180度 */
+}
+.tab1.active {
+  background: url(../../assets/img/j2.png);
+  background-size: 100% 100%;
+  transform: rotate(180deg); /* 旋转180度 */
+}
+.tab2.active {
+  background: url(../../assets/img/j2.png);
+  background-size: 100% 100%;
+}
+.tab1.active > * {
+  transform: rotate(-180deg); /* 容器内所有子元素反向旋转180度 */
+}
+.tab.active .tab-text {
+  background: linear-gradient(180deg, rgb(0, 139, 250), rgb(255, 255, 255));
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
+  text-fill-color: transparent;
+}
+
+.records {
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: flex-start;
+  margin-top: 20px;
+}
+.recordTable {
+  width: 100%;
+  height: 630px;
+  padding-top: 50px;
+  padding-left: 10px;
+  padding-right: 10px;
+  margin-top: 10px;
+  border: 1px solid #3897ff;
+  overflow-y: auto;
+}
+.recordTable::before {
+  content: "手动记录区";
+  line-height: 30px;
+
+  position: absolute;
+  width: 103px;
+  height: 30px;
+  left: 0px;
+  top: 0px;
+  border: 1px solid rgb(22, 93, 255);
+  border-radius: 4px;
+
+  background: rgba(56, 151, 255, 0.45);
+}
+.setItem {
+  margin: 0 0.5%;
+  background: url(../../assets/img/3.png);
+  width: 32%;
+  height: 208px;
+  background-size: 100% 100%;
+  padding: 30px;
+  box-sizing: border-box;
+}
+.record {
+  padding: 20px;
+  border-radius: 8px;
+}
+
+.record-header {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 10px;
+  width: calc(100% - 0px);
+  height: 50px;
+
+  /* box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25),0px 4px 16px 0px rgb(0, 122, 255); */
+}
+
+.record-title {
+  font-size: 20px;
+  color: rgba(255, 255, 255, 0.75);
+  line-height: 40px;
+  border-bottom: 1px solid #2b69ac;
+  width: 100%;
+  white-space: nowrap;
+
+  overflow: hidden;
+
+  /* clip====裁剪===默认效果 */
+
+  text-overflow: ellipsis;
+}
+
+.record-time {
+  color: #ccc;
+}
+.gz {
+  display: flex;
+  justify-content: space-between;
+  align-content: center;
+  margin-top: 20px;
+}
+.gz-cont {
+  width: 160px;
+}
+.record-body {
+  font-size: 20px;
+  padding: 20px 0;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  color: rgba(255, 255, 255, 0.75);
+}
+.btn {
+  color: rgb(56, 151, 255);
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  width: 60px;
+  font-size: 18px;
+  line-height: 40px;
+  cursor: pointer;
+}
+.valid {
+  background: linear-gradient(180deg, rgb(92, 255, 213), rgb(255, 255, 255));
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
+  text-fill-color: transparent;
+  font-size: 20px;
+  font-weight: 400;
+  line-height: 30px;
+  letter-spacing: 0%;
+  text-align: left;
+}
+
+.invalid {
+  background: linear-gradient(180deg, rgb(255, 0, 0), rgb(255, 255, 255));
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
+  text-fill-color: transparent;
+  font-size: 20px;
+  font-weight: 400;
+  line-height: 30px;
+  letter-spacing: 0%;
+  text-align: left;
+}
+.ace-sear {
+  display: flex;
+  justify-content: flex-start;
+  align-items: center;
+  margin-bottom: 20px;
+}
+.ace-sel {
+  width: 120px;
+  margin-right: 20px;
+}
+.line-select {
+  margin: 0 10px;
+  width: 30px;
+  height: 2px;
+  background: rgba(131, 187, 255, 0.65);
+}
+.pagination {
+  margin-top: 20px;
+  display: flex;
+  justify-content: center;
+}
+</style>

+ 6 - 4
src/views/MaintenanceStrategyAssistance/view.vue

@@ -101,9 +101,9 @@
               <el-button class="btns"  link @click="exportRecord(scope.row.name)"
                 >导出记录</el-button
               >
-              <el-button class="btns-warn"  link @click="delBefore(scope.row.id)"
+              <!-- <el-button class="btns-warn"  link @click="delBefore(scope.row.id)"
                 >删除</el-button
-              >
+              > -->
             </template>
           </el-table-column>
         </el-table>
@@ -170,7 +170,7 @@ const getHealthStatusClass = (sts: number) => {
 };
 const exportRecord=(value:string)=>{
 
-     downloadFile(downloadDeviceRepair(), "设备历史维修策略.xlsx", {name:value });
+downloadFile(downloadDeviceRepair(), "设备历史维修策略.xlsx", {name:value });
 }
 // 当前健康状态:1-良好;2-一般;3-较差;4-危险
 const getHealthStatusText = (status: number) => {
@@ -230,8 +230,10 @@ const queryParams = ref({
   name: "",
 });
 // 初始化逻辑
+const routeType=ref('')
 onMounted(() => {
   const pageId = route.query.id;
+  routeType.value=route.query.type
   // const pageId = route.query.id;
   if (pageId) {
     queryParams.value.id = Number(pageId);
@@ -266,7 +268,7 @@ const back=()=>{
     router.back(-1)
 }
 const viewDetails = (id: number,name:string) => {
-  router.push({ path: "/repair/MaintenanceStrategyAssistanceViewHis", query: { id,name } });
+  router.push({ path: "/repair/MaintenanceStrategyAssistanceViewHis", query: { id,name,type:routeType.value } });
   // ElMessage({
   //   message: `查看详情: ${id}`,
   //   type: "info",

Некоторые файлы не были показаны из-за большого количества измененных файлов