From d50f2acc73dc53a334c5feeb25a7e60e3df91f81 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期一, 30 三月 2026 11:16:06 +0800
Subject: [PATCH] 酒泉 1.设备功能迁移

---
 src/views/equipmentManagement/measurementEquipment/components/formDia.vue        |   14 
 src/views/equipmentManagement/upkeep/Form/PlanModal.vue                          |  188 ++
 src/views/equipmentManagement/inspectionManagement/components/formDia.vue        |  397 ++--
 src/api/equipmentManagement/upkeep.js                                            |   17 
 src/views/equipmentManagement/ledger/Form.vue                                    |  118 -
 src/api/equipmentManagement/maintenanceTaskFile.js                               |   28 
 src/views/equipmentManagement/calibration/index.vue                              |   38 
 src/views/equipmentManagement/ledger/index.vue                                   |  176 ++
 src/components/Dialog/FileListDialog.vue                                         |  328 ++++
 src/views/equipmentManagement/upkeep/Form/ApproveModal.vue                       |  144 ++
 src/views/equipmentManagement/upkeep/index.vue                                   |  208 ++
 src/views/equipmentManagement/spareParts/index.vue                               |  149 +
 src/views/equipmentManagement/repair/Modal/MaintainModal.vue                     |  127 +
 src/views/equipmentManagement/repair/Modal/RepairModal.vue                       |  239 ++
 src/views/equipmentManagement/repair/Modal/ApproveModal.vue                      |  142 +
 src/views/equipmentManagement/defectManagement/index.vue                         |    2 
 src/views/equipmentManagement/repair/index.vue                                   |  298 ++--
 src/views/equipmentManagement/inspectionManagement/index.vue                     |  517 +++---
 src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue |   14 
 src/views/equipmentManagement/inspectionManagement/components/viewFiles.vue      |   78 
 /dev/null                                                                        |  304 ----
 src/api/equipmentManagement/repair.js                                            |   16 
 src/views/equipmentManagement/amountSummary/index.vue                            |  180 ++
 src/views/equipmentManagement/measurementEquipment/index.vue                     |   20 
 src/views/equipmentManagement/ledger/Modal.vue                                   |    2 
 src/views/equipmentManagement/upkeep/Form/formDia.vue                            |  337 ++++
 src/components/Dialog/FormDialog.vue                                             |   73 +
 src/api/equipmentManagement/calibration.js                                       |    8 
 src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue                   |  146 ++
 29 files changed, 3,062 insertions(+), 1,246 deletions(-)

diff --git a/src/api/equipmentManagement/calibration.js b/src/api/equipmentManagement/calibration.js
index b0a9844..54b99f9 100644
--- a/src/api/equipmentManagement/calibration.js
+++ b/src/api/equipmentManagement/calibration.js
@@ -24,12 +24,4 @@
     method: "post",
     data: query,
   });
-}
-// 鍒犻櫎璁板綍
-export function ledgerRecordDelete(ids) {
-  return request({
-    url: "/measuringInstrumentLedgerRecord/delete",
-    method: "delete",
-    data: ids,
-  });
 }
\ No newline at end of file
diff --git a/src/api/equipmentManagement/maintenanceTaskFile.js b/src/api/equipmentManagement/maintenanceTaskFile.js
new file mode 100644
index 0000000..8373ae3
--- /dev/null
+++ b/src/api/equipmentManagement/maintenanceTaskFile.js
@@ -0,0 +1,28 @@
+import request from "@/utils/request";
+
+// 鏌ヨ淇濆吇浠诲姟闄勪欢鍒楄〃
+export function listMaintenanceTaskFiles(query) {
+  return request({
+    url: "/maintenanceTaskFile/listPage",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鏂板淇濆吇浠诲姟闄勪欢
+export function addMaintenanceTaskFile(data) {
+  return request({
+    url: "/maintenanceTaskFile/add",
+    method: "post",
+    data,
+  });
+}
+
+// 鍒犻櫎淇濆吇浠诲姟闄勪欢
+export function delMaintenanceTaskFile(id) {
+  return request({
+    url: "/maintenanceTaskFile/del",
+    method: "delete",
+    data: Array.isArray(id) ? id : [id],
+  });
+}
diff --git a/src/api/equipmentManagement/repair.js b/src/api/equipmentManagement/repair.js
index 0233ae6..bb44f8e 100644
--- a/src/api/equipmentManagement/repair.js
+++ b/src/api/equipmentManagement/repair.js
@@ -70,3 +70,19 @@
     data,
   });
 };
+// 鏌ヨ璁惧鐨勬姤淇噾棰�-姣忔湀
+export const monthlyAmount = (query) => {
+  return request({
+    url: `/device/repair/monthlyAmount`,
+    method: "get",
+    params: query,
+  });
+};
+// 鏌ヨ璁惧鐨勬姤淇噾棰�-姣忓勾
+export const yearlyAmount = (query) => {
+  return request({
+    url: `/device/repair/yearlyAmount`,
+    method: "get",
+    params: query,
+  });
+};
diff --git a/src/api/equipmentManagement/upkeep.js b/src/api/equipmentManagement/upkeep.js
index 234d2a5..37f6e5f 100644
--- a/src/api/equipmentManagement/upkeep.js
+++ b/src/api/equipmentManagement/upkeep.js
@@ -102,3 +102,20 @@
     data: params,
   });
 };
+
+// 鏌ヨ璁惧鐨勬姤淇噾棰�-姣忔湀
+export const monthlyAmount = (query) => {
+  return request({
+    url: `/device/maintenance/monthlyAmount`,
+    method: "get",
+    params: query,
+  });
+};
+// 鏌ヨ璁惧鐨勬姤淇噾棰�-姣忓勾
+export const yearlyAmount = (query) => {
+  return request({
+    url: `/device/maintenance/yearlyAmount`,
+    method: "get",
+    params: query,
+  });
+};
diff --git a/src/components/Dialog/FileListDialog.vue b/src/components/Dialog/FileListDialog.vue
new file mode 100644
index 0000000..fc82411
--- /dev/null
+++ b/src/components/Dialog/FileListDialog.vue
@@ -0,0 +1,328 @@
+<template>
+  <el-dialog v-model="dialogVisible"
+             :title="title"
+             :width="width"
+             :before-close="handleClose">
+    <div class="file-list-toolbar"
+         v-if="showToolbar">
+      <template v-if="useBuiltInUpload">
+        <el-upload v-model:file-list="uploadFileList"
+                   class="upload-demo"
+                   :action="uploadAction"
+                   :headers="uploadHeaders"
+                   :show-file-list="false"
+                   :on-success="handleDefaultUploadSuccess"
+                   :on-error="handleDefaultUploadError">
+          <el-button v-if="showUploadButton"
+                     type="primary"
+                     size="small">
+            涓婁紶闄勪欢
+          </el-button>
+        </el-upload>
+      </template>
+      <template v-else>
+        <el-button v-if="showUploadButton"
+                   type="primary"
+                   size="small"
+                   @click="handleUpload">
+          鏂板闄勪欢
+        </el-button>
+      </template>
+    </div>
+    <el-table :data="tableData"
+              border
+              :height="tableHeight">
+      <el-table-column :label="nameColumnLabel"
+                       :prop="nameColumnProp"
+                       :min-width="nameColumnMinWidth"
+                       show-overflow-tooltip />
+      <el-table-column v-if="showActions"
+                       fixed="right"
+                       label="鎿嶄綔"
+                       :width="actionColumnWidth"
+                       align="center">
+        <template #default="scope">
+          <el-button v-if="showDownload"
+                     link
+                     type="primary"
+                     size="small"
+                     @click="handleDownload(scope.row)">
+            涓嬭浇
+          </el-button>
+          <el-button v-if="showPreview"
+                     link
+                     type="primary"
+                     size="small"
+                     @click="handlePreview(scope.row)">
+            棰勮
+          </el-button>
+          <el-button v-if="showDeleteButton"
+                     link
+                     type="danger"
+                     size="small"
+                     @click="handleDelete(scope.row, scope.$index)">
+            鍒犻櫎
+          </el-button>
+          <slot name="actions"
+                :row="scope.row"></slot>
+        </template>
+      </el-table-column>
+      <slot name="columns"></slot>
+    </el-table>
+    <pagination v-if="isShowPagination"
+                style="margin-bottom: 20px;"
+                :total="page.total"
+                :page="page.current"
+                :limit="page.size"
+                @pagination="paginationSearch"
+                @change="handleChange" />
+  </el-dialog>
+  <filePreview v-if="showPreview"
+               ref="filePreviewRef" />
+</template>
+
+<script setup>
+  import { ref, computed, getCurrentInstance } from "vue";
+  import pagination from "@/components/Pagination/index.vue";
+  import { ElMessage } from "element-plus";
+  import filePreview from "@/components/filePreview/index.vue";
+  import { getToken } from "@/utils/auth";
+
+  const props = defineProps({
+    modelValue: {
+      type: Boolean,
+      default: false,
+    },
+    title: {
+      type: String,
+      default: "闄勪欢",
+    },
+    width: {
+      type: String,
+      default: "40%",
+    },
+    tableHeight: {
+      type: String,
+      default: "40vh",
+    },
+    nameColumnLabel: {
+      type: String,
+      default: "闄勪欢鍚嶇О",
+    },
+    nameColumnProp: {
+      type: String,
+      default: "name",
+    },
+    nameColumnMinWidth: {
+      type: [String, Number],
+      default: 400,
+    },
+    actionColumnWidth: {
+      type: [String, Number],
+      default: 160,
+    },
+    showActions: {
+      type: Boolean,
+      default: true,
+    },
+    showDownload: {
+      type: Boolean,
+      default: true,
+    },
+    showPreview: {
+      type: Boolean,
+      default: true,
+    },
+    showUploadButton: {
+      type: Boolean,
+      default: false,
+    },
+    showDeleteButton: {
+      type: Boolean,
+      default: false,
+    },
+    urlField: {
+      type: String,
+      default: "url",
+    },
+    downloadMethod: {
+      type: Function,
+      default: null,
+    },
+    previewMethod: {
+      type: Function,
+      default: null,
+    },
+    uploadMethod: {
+      type: Function,
+      default: null,
+    },
+    deleteMethod: {
+      type: Function,
+      default: null,
+    },
+    rulesRegulationsManagementId: {
+      type: [String, Number],
+      default: "",
+    },
+    uploadUrl: {
+      type: String,
+      default: `${import.meta.env.VITE_APP_BASE_API}/file/upload`,
+    },
+    isShowPagination: {
+      type: Boolean,
+      default: false,
+    },
+    page: {
+      type: Object,
+      default: () => ({
+        current: 1,
+        size: 10,
+        total: 0,
+      }),
+    },
+  });
+
+  const emit = defineEmits([
+    "update:modelValue",
+    "close",
+    "download",
+    "preview",
+    "upload",
+    "delete",
+  ]);
+
+  const { proxy } = getCurrentInstance();
+  const filePreviewRef = ref(null);
+  const uploadFileList = ref([]);
+
+  const dialogVisible = computed({
+    get: () => props.modelValue,
+    set: val => emit("update:modelValue", val),
+  });
+
+  const tableData = ref([]);
+  const showToolbar = computed(() => props.showUploadButton);
+  const useBuiltInUpload = computed(() => !props.uploadMethod);
+  const uploadAction = computed(() => props.uploadUrl);
+  const uploadHeaders = computed(() => ({
+    Authorization: `Bearer ${getToken()}`,
+  }));
+
+  const handleClose = () => {
+    emit("close");
+    dialogVisible.value = false;
+  };
+
+  const handleDownload = row => {
+    if (props.downloadMethod) {
+      props.downloadMethod(row);
+    } else {
+      // 榛樿涓嬭浇鏂规硶
+      proxy.$download.name(row[props.urlField]);
+    }
+    emit("download", row);
+  };
+
+  const handlePreview = row => {
+    if (props.previewMethod) {
+      props.previewMethod(row);
+    } else {
+      // 榛樿棰勮鏂规硶
+      if (filePreviewRef.value) {
+        filePreviewRef.value.open(row[props.urlField]);
+      }
+    }
+    emit("preview", row);
+  };
+  const paginationSearch = page => {
+    props.page.current = page.page;
+    props.page.size = page.limit;
+    emit("pagination", page.page, page.limit);
+  };
+
+  const open = list => {
+    dialogVisible.value = true;
+    tableData.value = list || [];
+  };
+
+  const handleUpload = async () => {
+    if (props.uploadMethod) {
+      // 濡傛灉鎻愪緵浜嗚嚜瀹氫箟涓婁紶鏂规硶锛岀敱鐖剁粍浠惰礋璐f洿鏂板垪琛紙閫氳繃 setList锛�
+      // 杩欓噷涓嶅啀鑷姩娣诲姞锛岄伩鍏嶄笌鐖剁粍浠剁殑 setList 閲嶅
+      await props.uploadMethod();
+    }
+    emit("upload");
+  };
+
+  const handleDelete = async (row, index) => {
+    if (props.deleteMethod) {
+      const result = await props.deleteMethod(row, index);
+      if (result === false) {
+        return;
+      }
+      // 濡傛灉鎻愪緵浜� deleteMethod锛岀敱鐖剁粍浠惰礋璐e埛鏂板垪琛紝涓嶅湪杩欓噷鍒犻櫎
+    } else {
+      // 濡傛灉娌℃湁鎻愪緵 deleteMethod锛屾墠鍦ㄧ粍浠跺唴閮ㄥ垹闄�
+      removeAttachment(index);
+    }
+    emit("delete", row);
+  };
+
+  const addAttachment = item => {
+    tableData.value = [...tableData.value, item];
+  };
+
+  const handleDefaultUploadSuccess = async (res, file) => {
+    if (res?.code !== 200) {
+      ElMessage.error(res?.msg || "鏂囦欢涓婁紶澶辫触");
+      return;
+    }
+    if (!props.rulesRegulationsManagementId) {
+      ElMessage.error("缂哄皯瑙勭珷鍒跺害ID锛屾棤娉曚繚瀛橀檮浠�");
+      return;
+    }
+    const fileName = res?.data?.originalName || file?.name;
+    const fileUrl = res?.data?.tempPath || res?.data?.url;
+    const payload = {
+      fileName,
+      fileUrl,
+      rulesRegulationsManagementId: props.rulesRegulationsManagementId,
+      raw: res?.data || {},
+    };
+    emit("upload", payload);
+  };
+
+  const handleDefaultUploadError = () => {
+    ElMessage.error("鏂囦欢涓婁紶澶辫触");
+  };
+
+  const removeAttachment = index => {
+    if (index > -1 && index < tableData.value.length) {
+      const newList = [...tableData.value];
+      newList.splice(index, 1);
+      tableData.value = newList;
+    }
+  };
+
+  const setList = list => {
+    tableData.value = list || [];
+  };
+
+  defineExpose({
+    open,
+    addAttachment,
+    removeAttachment,
+    setList,
+    handleUpload,
+    handleDelete,
+  });
+</script>
+
+<style scoped>
+  .file-list-toolbar {
+    margin-bottom: 8px;
+    text-align: right;
+  }
+</style>
+
diff --git a/src/components/Dialog/FormDialog.vue b/src/components/Dialog/FormDialog.vue
new file mode 100644
index 0000000..5e21b1d
--- /dev/null
+++ b/src/components/Dialog/FormDialog.vue
@@ -0,0 +1,73 @@
+<template>
+  <el-dialog
+    v-model="dialogVisible"
+    :title="computedTitle"
+    :width="width"
+    @close="handleClose"
+  >
+    <slot></slot>
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button type="primary" @click="handleConfirm">纭</el-button>
+        <el-button @click="handleCancel">鍙栨秷</el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup>
+import { computed } from 'vue'
+
+const props = defineProps({
+  modelValue: {
+    type: Boolean,
+    default: false
+  },
+  title: {
+    type: [String, Function],
+    default: ''
+  },
+  operationType: {
+    type: String,
+    default: ''
+  },
+  width: {
+    type: String,
+    default: '70%'
+  }
+})
+
+const emit = defineEmits(['update:modelValue', 'close', 'confirm', 'cancel'])
+
+const dialogVisible = computed({
+  get: () => props.modelValue,
+  set: (val) => emit('update:modelValue', val)
+})
+
+const computedTitle = computed(() => {
+  if (typeof props.title === 'function') {
+    return props.title(props.operationType)
+  }
+  return props.title
+})
+
+const handleClose = () => {
+  emit('close')
+}
+
+const handleConfirm = () => {
+  emit('confirm')
+}
+
+const handleCancel = () => {
+  emit('cancel')
+  dialogVisible.value = false
+}
+</script>
+
+<style scoped>
+.dialog-footer {
+  text-align: center;
+}
+</style>
+
diff --git a/src/views/equipmentManagement/amountSummary/index.vue b/src/views/equipmentManagement/amountSummary/index.vue
new file mode 100644
index 0000000..9d6a8bc
--- /dev/null
+++ b/src/views/equipmentManagement/amountSummary/index.vue
@@ -0,0 +1,180 @@
+<template>
+  <div class="app-container">
+    <el-tabs v-model="activeTab">
+      <el-tab-pane label="鎶ヤ慨" name="repair">
+        <el-form :inline="true" :model="filtersRepair">
+          <el-form-item label="鏌ョ湅妯″紡">
+            <el-radio-group v-model="modeRepair" @change="buildColumnsRepair">
+              <el-radio-button :value="'month'">鎸夋湀</el-radio-button>
+              <el-radio-button :value="'year'">鎸夊勾</el-radio-button>
+            </el-radio-group>
+          </el-form-item>
+          <el-form-item v-if="modeRepair === 'month' || modeRepair === 'year'" label="骞翠唤">
+            <el-date-picker v-model="yearRepair" type="year" value-format="YYYY" format="YYYY" placeholder="璇烽�夋嫨骞翠唤" @change="refreshRepair" />
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" @click="refreshRepair">鏌ヨ</el-button>
+            <el-button @click="resetRepair">閲嶇疆</el-button>
+          </el-form-item>
+        </el-form>
+
+        <div class="table_list">
+          <PIMTable
+            rowKey="deviceId"
+            :column="columnsRepair"
+            :tableData="tableDataRepair"
+            :page="{ current: 1, size: tableDataRepair.length || 10, total: tableDataRepair.length }"
+          />
+        </div>
+      </el-tab-pane>
+
+      <el-tab-pane label="淇濆吇" name="maintain">
+        <el-form :inline="true" :model="filtersMaintain">
+          <el-form-item label="鏌ョ湅妯″紡">
+            <el-radio-group v-model="modeMaintain" @change="buildColumnsMaintain">
+              <el-radio-button :value="'month'">鎸夋湀</el-radio-button>
+              <el-radio-button :value="'year'">鎸夊勾</el-radio-button>
+            </el-radio-group>
+          </el-form-item>
+          <el-form-item v-if="modeMaintain === 'month' || modeMaintain === 'year'" label="骞翠唤">
+            <el-date-picker v-model="yearMaintain" type="year" value-format="YYYY" format="YYYY" placeholder="璇烽�夋嫨骞翠唤" @change="refreshMaintain" />
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" @click="refreshMaintain">鏌ヨ</el-button>
+            <el-button @click="resetMaintain">閲嶇疆</el-button>
+          </el-form-item>
+        </el-form>
+
+        <div class="table_list">
+          <PIMTable
+            rowKey="deviceId"
+            :column="columnsMaintain"
+            :tableData="tableDataMaintain"
+            :page="{ current: 1, size: tableDataMaintain.length || 10, total: tableDataMaintain.length }"
+          />
+        </div>
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+  </template>
+
+<script setup>
+import { ref } from "vue";
+import { monthlyAmount, yearlyAmount } from "@/api/equipmentManagement/repair";
+import { monthlyAmount as monthlyAmountMaintain, yearlyAmount as yearlyAmountMaintain } from "@/api/equipmentManagement/upkeep";
+
+defineOptions({ name: "閲戦姹囨��" });
+
+const activeTab = ref("repair");
+
+// 鎶ヤ慨
+const modeRepair = ref("month");
+const yearRepair = ref(new Date().getFullYear().toString());
+const filtersRepair = ref({});
+const columnsRepair = ref([]);
+const tableDataRepair = ref([]);
+
+const fetchRepairData = async () => {
+  try {
+    const query = { year: yearRepair.value };
+    const res = modeRepair.value === "month" ? await monthlyAmount(query) : await yearlyAmount(query);
+    const list = res?.records || res?.data || res || [];
+    tableDataRepair.value = Array.isArray(list) ? list : [];
+  } catch (e) {
+    tableDataRepair.value = [];
+  }
+};
+
+const buildColumnsRepair = async () => {
+  const base = [{ label: "璁惧鍚嶇О", align: "center", prop: "deviceName", width: 180 }];
+  if (modeRepair.value === "month") {
+    const monthCols = Array.from({ length: 12 }, (_, i) => ({
+      label: `${i + 1}鏈坄,
+      align: "center",
+      prop: `month${i + 1}`,
+    }));
+    columnsRepair.value = [
+      ...base,
+      ...monthCols,
+      { label: "鎬昏", align: "center", prop: "total" },
+    ];
+  } else {
+    columnsRepair.value = [
+      ...base,
+      { label: "閲戦", align: "center", prop: "totalRepairPrice" },
+    ];
+  }
+  await fetchRepairData();
+};
+
+const refreshRepair = async () => {
+  await buildColumnsRepair();
+};
+
+const resetRepair = () => {
+  modeRepair.value = "month";
+  yearRepair.value = new Date().getFullYear().toString();
+  refreshRepair();
+};
+
+// 淇濆吇
+const modeMaintain = ref("month");
+const yearMaintain = ref(new Date().getFullYear().toString());
+const filtersMaintain = ref({});
+const columnsMaintain = ref([]);
+const tableDataMaintain = ref([]);
+
+const fetchMaintainData = async () => {
+  try {
+    const query = { year: yearMaintain.value };
+    const res = modeMaintain.value === "month" ? await monthlyAmountMaintain(query) : await yearlyAmountMaintain(query);
+    const list = res?.records || res?.data || res || [];
+    tableDataMaintain.value = Array.isArray(list) ? list : [];
+  } catch (e) {
+    tableDataMaintain.value = [];
+  }
+};
+
+const buildColumnsMaintain = async () => {
+  const base = [{ label: "璁惧鍚嶇О", align: "center", prop: "deviceName", width: 180 }];
+  if (modeMaintain.value === "month") {
+    const monthCols = Array.from({ length: 12 }, (_, i) => ({
+      label: `${i + 1}鏈坄,
+      align: "center",
+      prop: `month${i + 1}`,
+    }));
+    columnsMaintain.value = [
+      ...base,
+      ...monthCols,
+      { label: "鎬昏", align: "center", prop: "total" },
+    ];
+  } else {
+    columnsMaintain.value = [
+      ...base,
+      { label: "閲戦", align: "center", prop: "totalRepairPrice" },
+    ];
+  }
+  await fetchMaintainData();
+};
+
+const refreshMaintain = async () => {
+  await buildColumnsMaintain();
+};
+
+const resetMaintain = () => {
+  modeMaintain.value = "month";
+  yearMaintain.value = new Date().getFullYear().toString();
+  refreshMaintain();
+};
+
+buildColumnsRepair();
+refreshRepair();
+buildColumnsMaintain();
+refreshMaintain();
+</script>
+
+<style scoped>
+.table_list {
+  margin-top: 10px;
+}
+</style>
diff --git a/src/views/equipmentManagement/calibration/index.vue b/src/views/equipmentManagement/calibration/index.vue
index 3ace389..7dfd405 100644
--- a/src/views/equipmentManagement/calibration/index.vue
+++ b/src/views/equipmentManagement/calibration/index.vue
@@ -57,10 +57,10 @@
 
 <script setup>
 import {onMounted, ref} from "vue";
-import {ElMessageBox, ElMessage} from "element-plus";
+import {ElMessageBox} from "element-plus";
 import useUserStore from "@/store/modules/user.js";
 import CalibrationDia from "@/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue";
-import {ledgerRecordListPage, ledgerRecordDelete} from "@/api/equipmentManagement/calibration.js";
+import {ledgerRecordListPage} from "@/api/equipmentManagement/calibration.js";
 const { proxy } = getCurrentInstance();
 const userStore = useUserStore()
 
@@ -134,7 +134,6 @@
 	{
 		dataType: "action",
 		label: "鎿嶄綔",
-		width: 140,
 		align: "center",
 		fixed: 'right',
 		operation: [
@@ -144,16 +143,9 @@
 				clickFun: (row) => {
 					openCalibrationDia("edit", row);
 				},
-			},
-			{
-				name: "鍒犻櫎",
-				type: "text",
-				style: {
-					color: "#F56C6C"
-				},
-				clickFun: (row) => {
-					handleDelete(row);
-				},
+				disabled: (row) => {
+					return row.userId !== userStore.id
+				}
 			},
 		],
 	},
@@ -201,26 +193,6 @@
 		calibrationDia.value?.openDialog(type, row)
 	})
 }
-
-// 鍒犻櫎璁板綍
-const handleDelete = (row) => {
-	ElMessageBox.confirm(`纭鍒犻櫎璁¢噺鍣ㄥ叿缂栧彿涓�"${row.code}"鐨勬瀹氳褰曞悧锛焋, "鍒犻櫎纭", {
-		confirmButtonText: "纭",
-		cancelButtonText: "鍙栨秷",
-		type: "warning",
-	})
-		.then(() => {
-			ledgerRecordDelete([row.id]).then(() => {
-				ElMessage.success("鍒犻櫎鎴愬姛");
-				getList();
-			}).catch(() => {
-				ElMessage.error("鍒犻櫎澶辫触");
-			});
-		})
-		.catch(() => {
-			proxy.$modal.msg("宸插彇娑堝垹闄�");
-		});
-};
 
 // 瀵煎嚭
 const handleOut = () => {
diff --git a/src/views/equipmentManagement/defectManagement/index.vue b/src/views/equipmentManagement/defectManagement/index.vue
index f35454f..139f139 100644
--- a/src/views/equipmentManagement/defectManagement/index.vue
+++ b/src/views/equipmentManagement/defectManagement/index.vue
@@ -43,7 +43,7 @@
     <el-dialog title="鐧昏璁惧缂洪櫡" v-model="showRegisterDialog" width="50%">
       <el-form :model="defectForm" :rules="defectRules" ref="defectFormRef" label-width="100px">
         <el-form-item label="璁惧鍚嶇О" prop="deviceName">
-          <el-select v-model="defectForm.deviceLedgerId" @change="setDeviceModel">
+          <el-select v-model="defectForm.deviceLedgerId" @change="setDeviceModel" filterable>
             <el-option
               v-for="(item, index) in deviceOptions"
               :key="index"
diff --git a/src/views/equipmentManagement/inspectionManagement/components/formDia.vue b/src/views/equipmentManagement/inspectionManagement/components/formDia.vue
index 82837af..87c9cee 100644
--- a/src/views/equipmentManagement/inspectionManagement/components/formDia.vue
+++ b/src/views/equipmentManagement/inspectionManagement/components/formDia.vue
@@ -1,116 +1,102 @@
 <template>
-	<div>
-		<el-dialog :title="operationType === 'add' ? '鏂板宸℃浠诲姟' : '缂栬緫宸℃浠诲姟'"
-							 v-model="dialogVisitable" width="800px" @close="cancel">
-			<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
-				<el-row>
-					<el-col :span="12">
-						<el-form-item label="璁惧鍚嶇О" prop="taskId">
-							<el-select v-model="form.taskId" @change="setDeviceModel" filterable>
-								<el-option
-									v-for="(item, index) in deviceOptions"
-									:key="index"
-									:label="item.deviceName"
-									:value="item.id"
-								></el-option>
-							</el-select>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12">
-						<el-form-item label="宸℃浜�" prop="inspector">
-							<el-select v-model="form.inspector"                 filterable
-												 default-first-option
-												 :reserve-keyword="false" placeholder="璇烽�夋嫨" multiple clearable>
-								<el-option v-for="item in userList" :label="item.nickName" :value="item.userId" :key="item.userId"/>
-							</el-select>
-						</el-form-item>
-					</el-col>
-				</el-row>
-				<el-row>
-					<el-col :span="12">
-						<el-form-item label="澶囨敞" prop="remarks">
-							<el-input v-model="form.remarks" placeholder="璇疯緭鍏ュ娉�" type="textarea" />
-						</el-form-item>
-					</el-col>
-					<el-col :span="12">
-						<el-form-item label="鐧昏鏃堕棿" prop="dateStr">
-							<el-date-picker
-								v-model="form.dateStr"
-								type="date"
-								placeholder="閫夋嫨鐧昏鏃ユ湡"
-								format="YYYY-MM-DD"
-								value-format="YYYY-MM-DD"
-								style="width: 100%"
-							/>
-						</el-form-item>
-					</el-col>
-				</el-row>
-				<el-row>
-					<el-col :span="12">
-						<el-form-item label="浠诲姟棰戠巼" prop="frequencyType">
-							<el-select v-model="form.frequencyType" placeholder="璇烽�夋嫨" clearable>
-								<el-option label="姣忔棩" value="DAILY"/>
-								<el-option label="姣忓懆" value="WEEKLY"/>
-								<el-option label="姣忔湀" value="MONTHLY"/>
-								<!-- <el-option label="瀛e害" value="QUARTERLY"/> -->
-							</el-select>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12" v-if="form.frequencyType === 'DAILY' && form.frequencyType">
-						<el-form-item label="鏃ユ湡" prop="frequencyDetail">
-							<el-time-picker v-model="form.frequencyDetail" placeholder="閫夋嫨鏃堕棿" format="HH:mm"
-															value-format="HH:mm" />
-						</el-form-item>
-					</el-col>
-					<el-col :span="12" v-if="form.frequencyType === 'WEEKLY' && form.frequencyType">
-						<el-form-item label="鏃ユ湡" prop="frequencyDetail">
-							<el-select v-model="form.week" placeholder="璇烽�夋嫨" clearable style="width: 50%">
-								<el-option label="鍛ㄤ竴" value="MON"/>
-								<el-option label="鍛ㄤ簩" value="TUE"/>
-								<el-option label="鍛ㄤ笁" value="WED"/>
-								<el-option label="鍛ㄥ洓" value="THU"/>
-								<el-option label="鍛ㄤ簲" value="FRI"/>
-								<el-option label="鍛ㄥ叚" value="SAT"/>
-								<el-option label="鍛ㄦ棩" value="SUN"/>
-							</el-select>
-							<el-time-picker v-model="form.time" placeholder="閫夋嫨鏃堕棿" format="HH:mm"
-															value-format="HH:mm"  style="width: 50%"/>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12" v-if="form.frequencyType === 'MONTHLY' && form.frequencyType">
-						<el-form-item label="鏃ユ湡" prop="frequencyDetail">
-							<el-date-picker
-								v-model="form.frequencyDetail"
-								type="datetime"
-								clearable
-								placeholder="閫夋嫨寮�濮嬫棩鏈�"
-								format="DD,HH:mm"
-								value-format="DD,HH:mm"
-							/>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12" v-if="form.frequencyType === 'QUARTERLY' && form.frequencyType">
-						<el-form-item label="鏃ユ湡" prop="frequencyDetail">
-							<el-date-picker
-								v-model="form.frequencyDetail"
-								type="datetime"
-								clearable
-								placeholder="閫夋嫨寮�濮嬫棩鏈�"
-								format="MM,DD,HH:mm"
-								value-format="MM,DD,HH:mm"
-							/>
-						</el-form-item>
-					</el-col>
-				</el-row>
-			</el-form>
-			<template #footer>
-				<div class="dialog-footer">
-					<el-button @click="cancel">鍙栨秷</el-button>
-					<el-button type="primary" @click="submitForm">淇濆瓨</el-button>
-				</div>
-			</template>
-		</el-dialog>
-	</div>
+  <div>
+    <el-dialog :title="operationType === 'add' ? '鏂板宸℃浠诲姟' : '缂栬緫宸℃浠诲姟'"
+               v-model="dialogVisitable" width="800px" @close="cancel">
+      <el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="璁惧鍚嶇О" prop="taskIds">
+              <el-select v-model="form.taskIds" @change="setDeviceModel" multiple filterable>
+                <el-option
+                  v-for="(item, index) in deviceOptions"
+                  :key="index"
+                  :label="item.deviceName"
+                  :value="item.id"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="宸℃浜�" prop="inspector">
+              <el-select v-model="form.inspector" placeholder="璇烽�夋嫨" multiple clearable>
+                <el-option v-for="item in userList" :label="item.nickName" :value="item.userId" :key="item.userId"/>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="澶囨敞" prop="remarks">
+              <el-input v-model="form.remarks" placeholder="璇疯緭鍏ュ娉�" type="textarea" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="浠诲姟棰戠巼" prop="frequencyType">
+              <el-select v-model="form.frequencyType" placeholder="璇烽�夋嫨" clearable>
+                <el-option label="姣忔棩" value="DAILY"/>
+                <el-option label="姣忓懆" value="WEEKLY"/>
+                <el-option label="姣忔湀" value="MONTHLY"/>
+                <!-- <el-option label="瀛e害" value="QUARTERLY"/> -->
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12" v-if="form.frequencyType === 'DAILY' && form.frequencyType">
+            <el-form-item label="鏃ユ湡" prop="frequencyDetail">
+              <el-time-picker v-model="form.frequencyDetail" placeholder="閫夋嫨鏃堕棿" format="HH:mm"
+                              value-format="HH:mm" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12" v-if="form.frequencyType === 'WEEKLY' && form.frequencyType">
+            <el-form-item label="鏃ユ湡" prop="frequencyDetail">
+              <el-select v-model="form.week" placeholder="璇烽�夋嫨" clearable style="width: 50%">
+                <el-option label="鍛ㄤ竴" value="MON"/>
+                <el-option label="鍛ㄤ簩" value="TUE"/>
+                <el-option label="鍛ㄤ笁" value="WED"/>
+                <el-option label="鍛ㄥ洓" value="THU"/>
+                <el-option label="鍛ㄤ簲" value="FRI"/>
+                <el-option label="鍛ㄥ叚" value="SAT"/>
+                <el-option label="鍛ㄦ棩" value="SUN"/>
+              </el-select>
+              <el-time-picker v-model="form.time" placeholder="閫夋嫨鏃堕棿" format="HH:mm"
+                              value-format="HH:mm"  style="width: 50%"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12" v-if="form.frequencyType === 'MONTHLY' && form.frequencyType">
+            <el-form-item label="鏃ユ湡" prop="frequencyDetail">
+              <el-date-picker
+                  v-model="form.frequencyDetail"
+                  type="datetime"
+                  clearable
+                  placeholder="閫夋嫨寮�濮嬫棩鏈�"
+                  format="DD,HH:mm"
+                  value-format="DD,HH:mm"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12" v-if="form.frequencyType === 'QUARTERLY' && form.frequencyType">
+            <el-form-item label="鏃ユ湡" prop="frequencyDetail">
+              <el-date-picker
+                  v-model="form.frequencyDetail"
+                  type="datetime"
+                  clearable
+                  placeholder="閫夋嫨寮�濮嬫棩鏈�"
+                  format="MM,DD,HH:mm"
+                  value-format="MM,DD,HH:mm"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">淇濆瓨</el-button>
+          <el-button @click="cancel">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
 </template>
 
 <script setup>
@@ -127,117 +113,128 @@
 const operationType = ref('add');
 const deviceOptions = ref([]);
 const data = reactive({
-	form: {
-		taskId: undefined,
-		taskName: undefined,
-		inspector: '',
-		inspectorIds: '',
-		remarks: '',
-		frequencyType: '',
-		frequencyDetail: '',
-		week: '',
-		time: '',
-		dateStr: ''
-	},
-	rules: {
-		taskId: [{ required: true, message: "璇烽�夋嫨璁惧", trigger: "change" },],
-		inspector: [{ required: true, message: "璇疯緭鍏ュ贰妫�浜�", trigger: "blur" },],
-		dateStr: [{ required: true, message: "璇烽�夋嫨鐧昏鏃堕棿", trigger: "change" }]
-	}
+  form: {
+    taskIds: [],
+    taskName: undefined,
+    inspector: '',
+    inspectorIds: '',
+    remarks: '',
+    frequencyType: '',
+    frequencyDetail: '',
+    week: '',
+    time: ''
+  },
+  rules: {
+    taskIds: [{ required: true, message: "璇烽�夋嫨璁惧", trigger: "change" },],
+    inspector: [{ required: true, message: "璇疯緭鍏ュ贰妫�浜�", trigger: "blur" },],
+  }
 })
 const { form, rules } = toRefs(data)
 const userList = ref([])
 
 const loadDeviceName = async () => {
-	const { data } = await getDeviceLedger();
-	deviceOptions.value = data;
+  const { data } = await getDeviceLedger();
+  deviceOptions.value = data;
 };
 
-const setDeviceModel = (id) => {
-	const option = deviceOptions.value.find((item) => item.id === id);
-	if (option) {
-		form.value.taskName = option.deviceName;
-	}
+const setDeviceModel = (ids) => {
+  if (!ids || ids.length === 0) {
+    form.value.taskIds = []
+    form.value.taskName = undefined
+    return
+  }
+  
+  const selectedDevices = deviceOptions.value.filter((item) => ids.includes(item.id))
+  if (selectedDevices.length > 0) {
+    form.value.taskIds = ids
+    form.value.taskName = selectedDevices.map(d => d.deviceName).join(',')
+  }
 }
 
 // 鎵撳紑寮规
 const openDialog = async (type, row) => {
-	dialogVisitable.value = true
-	operationType.value = type
-	
-	// 閲嶇疆琛ㄥ崟
-	resetForm();
-	
-	// 鍔犺浇鐢ㄦ埛鍒楄〃
-	userListNoPageByTenantId().then((res) => {
-		userList.value = res.data;
-	});
-	
-	// 鍔犺浇璁惧鍒楄〃
-	await loadDeviceName();
-	
-	if (type === 'edit' && row) {
-		form.value = {...row}
-		form.value.inspector = form.value.inspectorIds.split(',').map(Number)
-		
-		// 濡傛灉鏈夎澶嘔D锛岃嚜鍔ㄨ缃澶囦俊鎭�
-		if (form.value.taskId) {
-			setDeviceModel(form.value.taskId);
-		}
-	}
+  dialogVisitable.value = true
+  operationType.value = type
+  
+  // 閲嶇疆琛ㄥ崟
+  resetForm();
+  
+  // 鍔犺浇鐢ㄦ埛鍒楄〃
+  userListNoPageByTenantId().then((res) => {
+    userList.value = res.data;
+  });
+  
+  // 鍔犺浇璁惧鍒楄〃
+  await loadDeviceName();
+  
+  if (type === 'edit' && row) {
+    form.value = {...row}
+    form.value.inspector = form.value.inspectorIds.split(',').map(Number)
+    
+    // 濡傛灉鏈夎澶嘔D鏁扮粍锛岃浆鎹负鏁扮粍骞惰缃澶囦俊鎭�
+    if (row.taskIds) {
+      form.value.taskIds = row.taskIds.split(',').map(id => parseInt(id.trim()))
+      setDeviceModel(form.value.taskIds)
+    }
+  }
 }
 
 // 鍏抽棴瀵硅瘽妗�
 const cancel = () => {
-	resetForm()
-	dialogVisitable.value = false
-	emit('closeDia')
+  resetForm()
+  dialogVisitable.value = false
+  emit('closeDia')
 }
 
 // 閲嶇疆琛ㄥ崟鍑芥暟
 const resetForm = () => {
-	if (proxy.$refs.formRef) {
-		proxy.$refs.formRef.resetFields()
-	}
-	// 閲嶇疆琛ㄥ崟鏁版嵁纭繚璁惧淇℃伅姝g‘閲嶇疆
-	form.value = {
-		taskId: undefined,
-		taskName: undefined,
-		inspector: '',
-		inspectorIds: '',
-		remarks: '',
-		frequencyType: '',
-		frequencyDetail: '',
-		week: '',
-		time: ''
-	}
+  if (proxy.$refs.formRef) {
+    proxy.$refs.formRef.resetFields()
+  }
+  // 閲嶇疆琛ㄥ崟鏁版嵁纭繚璁惧淇℃伅姝g‘閲嶇疆
+  form.value = {
+    taskIds: [],
+    taskName: undefined,
+    inspector: '',
+    inspectorIds: '',
+    remarks: '',
+    frequencyType: '',
+    frequencyDetail: '',
+    week: '',
+    time: ''
+  }
 }
 
 // 鎻愪氦琛ㄥ崟
 const submitForm = () => {
-	proxy.$refs["formRef"].validate(async valid => {
-		if (valid) {
-			try {
-				form.value.inspectorIds = form.value.inspector.join(',')
-				delete form.value.inspector
-				
-				if (form.value.frequencyType === 'WEEKLY') {
-					let frequencyDetail = ''
-					frequencyDetail = form.value.week + ',' + form.value.time
-					form.value.frequencyDetail = frequencyDetail
-				}
-				
-				let res = await userStore.getInfo()
-				form.value.registrantId = res.user.userId
-				
-				await addOrEditTimingTask(form.value)
-				cancel()
-				proxy.$modal.msgSuccess('鎻愪氦鎴愬姛')
-			} catch (error) {
-				proxy.$modal.msgError('鎻愪氦澶辫触锛岃閲嶈瘯')
-			}
-		}
-	})
+  proxy.$refs["formRef"].validate(async valid => {
+    if (valid) {
+      try {
+        form.value.inspectorIds = form.value.inspector.join(',')
+        delete form.value.inspector
+        
+        // 澶勭悊 taskIds 鍜� taskName
+        if (form.value.taskIds && Array.isArray(form.value.taskIds)) {
+          form.value.taskIds = form.value.taskIds.join(',')
+        }
+        
+        if (form.value.frequencyType === 'WEEKLY') {
+          let frequencyDetail = ''
+          frequencyDetail = form.value.week + ',' + form.value.time
+          form.value.frequencyDetail = frequencyDetail
+        }
+        
+        let res = await userStore.getInfo()
+        form.value.registrantId = res.user.userId
+        
+        await addOrEditTimingTask(form.value)
+        cancel()
+        proxy.$modal.msgSuccess('鎻愪氦鎴愬姛')
+      } catch (error) {
+        proxy.$modal.msgError('鎻愪氦澶辫触锛岃閲嶈瘯')
+      }
+    }
+  })
 }
 defineExpose({ openDialog })
 </script>
diff --git a/src/views/equipmentManagement/inspectionManagement/components/viewFiles.vue b/src/views/equipmentManagement/inspectionManagement/components/viewFiles.vue
index f0deddb..27b4a59 100644
--- a/src/views/equipmentManagement/inspectionManagement/components/viewFiles.vue
+++ b/src/views/equipmentManagement/inspectionManagement/components/viewFiles.vue
@@ -32,7 +32,7 @@
         
         <!-- 鐢熶骇鍚� -->
         <div class="form-container">
-          <div class="title">鐢熶骇涓�</div>
+          <div class="title">鐢熶骇鍚�</div>
           
           <!-- 鍥剧墖鍒楄〃 -->
           <div style="display: flex; flex-wrap: wrap;">
@@ -59,7 +59,7 @@
         
         <!-- 鐢熶骇闂 -->
         <div class="form-container">
-          <div class="title">鐢熶骇鍚�</div>
+          <div class="title">鐢熶骇闂</div>
           
           <!-- 鍥剧墖鍒楄〃 -->
           <div style="display: flex; flex-wrap: wrap;">
@@ -100,7 +100,7 @@
         
         <!-- 瑙嗛 -->
         <div v-else-if="mediaType === 'video'" style="position: relative;">
-          <Video
+          <video
               :src="mediaList[currentMediaIndex]"
               autoplay
               controls
@@ -114,6 +114,7 @@
 <script setup>
 import { ref } from 'vue';
 import VueEasyLightbox from 'vue-easy-lightbox';
+const { proxy } = getCurrentInstance();
 
 // 鎺у埗寮圭獥鏄剧ず
 const dialogVisitable = ref(false);
@@ -133,26 +134,83 @@
 const currentMediaIndex = ref(0);
 const mediaList = ref([]); // 瀛樺偍褰撳墠瑕佹煡鐪嬬殑濯掍綋鍒楄〃锛堝惈鍥剧墖鍜岃棰戝璞★級
 const mediaType = ref('image'); // image | video
+const javaApi = proxy.javaApi;
+
+// 澶勭悊 URL锛氬皢 Windows 璺緞杞崲涓哄彲璁块棶鐨� URL
+function processFileUrl(fileUrl) {
+  if (!fileUrl) return '';
+  
+  // 濡傛灉 URL 鏄� Windows 璺緞鏍煎紡锛堝寘鍚弽鏂滄潬锛夛紝闇�瑕佽浆鎹�
+  if (fileUrl && fileUrl.indexOf('\\') > -1) {
+    // 鏌ユ壘 uploads 鍏抽敭瀛楃殑浣嶇疆锛屼粠閭i噷寮�濮嬫彁鍙栫浉瀵硅矾寰�
+    const uploadsIndex = fileUrl.toLowerCase().indexOf('uploads');
+    if (uploadsIndex > -1) {
+      // 浠� uploads 寮�濮嬫彁鍙栬矾寰勶紝骞跺皢鍙嶆枩鏉犳浛鎹负姝f枩鏉�
+      const relativePath = fileUrl.substring(uploadsIndex).replace(/\\/g, '/');
+      fileUrl = '/' + relativePath;
+    } else {
+      // 濡傛灉娌℃湁鎵惧埌 uploads锛屾彁鍙栨渶鍚庝竴涓洰褰曞拰鏂囦欢鍚�
+      const parts = fileUrl.split('\\');
+      const fileName = parts[parts.length - 1];
+      fileUrl = '/uploads/' + fileName;
+    }
+  }
+  
+  // 纭繚鎵�鏈夐潪 http 寮�澶寸殑 URL 閮芥嫾鎺� baseUrl
+  if (fileUrl && !fileUrl.startsWith('http')) {
+    // 纭繚璺緞浠� / 寮�澶�
+    if (!fileUrl.startsWith('/')) {
+      fileUrl = '/' + fileUrl;
+    }
+    // 鎷兼帴 baseUrl
+    fileUrl = javaApi + fileUrl;
+  }
+  
+  return fileUrl;
+}
 
 // 澶勭悊姣忎竴绫绘暟鎹細鍒嗙鍥剧墖鍜岃棰�
 function processItems(items) {
   const images = [];
   const videos = [];
+  
+  // 妫�鏌� items 鏄惁瀛樺湪涓斾负鏁扮粍
+  if (!items || !Array.isArray(items)) {
+    return { images, videos };
+  }
+  
   items.forEach(item => {
-    if (item.contentType?.startsWith('image/')) {
-      images.push(item.url);
-    } else if (item.contentType?.startsWith('video/')) {
-      videos.push(item.url);
+    if (!item || !item.url) return;
+    
+    // 澶勭悊鏂囦欢 URL
+    const fileUrl = processFileUrl(item.url);
+    
+    // 鏍规嵁鏂囦欢鎵╁睍鍚嶅垽鏂槸鍥剧墖杩樻槸瑙嗛
+    const urlLower = fileUrl.toLowerCase();
+    if (urlLower.match(/\.(jpg|jpeg|png|gif|bmp|webp)$/)) {
+      images.push(fileUrl);
+    } else if (urlLower.match(/\.(mp4|avi|mov|wmv|flv|mkv|webm)$/)) {
+      videos.push(fileUrl);
+    } else if (item.contentType) {
+      // 濡傛灉鏈� contentType锛屼娇鐢� contentType 鍒ゆ柇
+      if (item.contentType.startsWith('image/')) {
+        images.push(fileUrl);
+      } else if (item.contentType.startsWith('video/')) {
+        videos.push(fileUrl);
+      }
     }
   });
+  
   return { images, videos };
 }
 
 // 鎵撳紑寮圭獥骞跺姞杞芥暟鎹�
 const openDialog = async (row) => {
-  const { images: beforeImgs, videos: beforeVids } = processItems(row.beforeProduction);
-  const { images: afterImgs, videos: afterVids } = processItems(row.afterProduction);
-  const { images: issueImgs, videos: issueVids } = processItems(row.productionIssues);
+  // 浣跨敤姝g‘鐨勫瓧娈靛悕锛歝ommonFileListBefore, commonFileListAfter
+  // productionIssues 鍙兘涓嶅瓨鍦紝浣跨敤绌烘暟缁�
+  const { images: beforeImgs, videos: beforeVids } = processItems(row.commonFileListBefore || []);
+  const { images: afterImgs, videos: afterVids } = processItems(row.commonFileListAfter || []);
+  const { images: issueImgs, videos: issueVids } = processItems(row.productionIssues || []);
   
   beforeProductionImgs.value = beforeImgs;
   beforeProductionVideos.value = beforeVids;
diff --git a/src/views/equipmentManagement/inspectionManagement/index.vue b/src/views/equipmentManagement/inspectionManagement/index.vue
index 381fc69..63ff08e 100644
--- a/src/views/equipmentManagement/inspectionManagement/index.vue
+++ b/src/views/equipmentManagement/inspectionManagement/index.vue
@@ -1,78 +1,77 @@
 <template>
-	<div class="app-container">
-		<el-form :inline="true" :model="queryParams" class="search-form">
-			<el-form-item label="鎼滅储">
-				<el-input
-					v-model="queryParams.searchAll"
-					placeholder="璇疯緭鍏ュ叧閿瓧"
-					clearable
-					:style="{ width: '100%' }"
-				/>
-			</el-form-item>
-			<el-form-item>
-				<el-button type="primary" @click="handleQuery">鏌ヨ</el-button>
-				<el-button @click="resetQuery">閲嶇疆</el-button>
-			</el-form-item>
-		</el-form>
-		<el-card>
-			<div style="display: flex;flex-direction: row;justify-content: space-between;margin-bottom: 10px;">
-				<el-radio-group v-model="activeRadio" @change="radioChange">
-					<el-radio-button v-for="tab in radios"
-													 :key="tab.name"
-													 :label="tab.label"
-													 :value="tab.name"/>
-				</el-radio-group>
-				<!-- 鎿嶄綔鎸夐挳鍖� -->
-				<el-space v-if="activeRadio !== 'task'">
-					<el-button type="primary" :icon="Plus" @click="handleAdd(undefined)">鏂板缓</el-button>
-					<el-button type="danger" :icon="Delete" @click="handleDelete">鍒犻櫎</el-button>
-					<el-button @click="handleOut">瀵煎嚭</el-button>
-				</el-space>
-				<el-space v-else>
-					<el-button @click="handleOut">瀵煎嚭</el-button>
-				</el-space>
-			</div>
-			<div>
-				<div>
-					<PIMTable :table-loading="tableLoading"
-										:table-data="tableData"
-										:column="tableColumns"
-										@selection-change="handleSelectionChange"
-										:is-selection="true"
-										:border="true"
-										:table-style="{ width: '100%', height: 'calc(100vh - 23em)' }"
-										:page="{
-          current: pageNum,
-          size: pageSize,
-          total: total,
-        }"
-										@pagination="pagination"
-					>
-						<template #inspector="{ row }">
-							<div class="person-tags">
-								<!-- 璋冭瘯淇℃伅锛屼笂绾挎椂鍒犻櫎 -->
-								<!-- {{ console.log('inspector data:', row.inspector) }} -->
-								<template v-if="row.inspector && row.inspector.length > 0">
-									<el-tag
-										v-for="(person, index) in row.inspector"
-										:key="index"
-										size="small"
-										type="primary"
-										class="person-tag"
-									>
-										{{ person }}
-									</el-tag>
-								</template>
-								<span v-else class="no-data">--</span>
-							</div>
-						</template>
-					</PIMTable>
-				</div>
-			</div>
-		</el-card>
-		<form-dia ref="formDia" @closeDia="handleQuery"></form-dia>
-		<view-files ref="viewFiles"></view-files>
-	</div>
+  <div class="app-container">
+    <el-form :inline="true" :model="queryParams" class="search-form">
+      <el-form-item label="鎼滅储">
+        <el-input
+            v-model="queryParams.searchAll"
+            placeholder="璇疯緭鍏ュ叧閿瓧"
+            clearable
+            :style="{ width: '100%' }"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" @click="handleQuery">鏌ヨ</el-button>
+        <el-button @click="resetQuery">閲嶇疆</el-button>
+      </el-form-item>
+    </el-form>
+    <el-card>
+      <div style="display: flex;flex-direction: row;justify-content: space-between;margin-bottom: 10px;">
+        <el-radio-group v-model="activeRadio" @change="radioChange">
+          <el-radio-button v-for="tab in radios"
+                           :key="tab.name"
+                           :label="tab.label"
+                           :value="tab.name"/>
+        </el-radio-group>
+        <!-- 鎿嶄綔鎸夐挳鍖� -->
+        <el-space v-if="activeRadio !== 'task'">
+          <el-button type="primary" :icon="Plus" @click="handleAdd(undefined)">鏂板缓</el-button>
+          <el-button type="danger" :icon="Delete" @click="handleDelete">鍒犻櫎</el-button>
+          <el-button @click="handleOut">瀵煎嚭</el-button>
+        </el-space>
+        <el-space v-else>
+          <el-button @click="handleOut">瀵煎嚭</el-button>
+        </el-space>
+      </div>
+      <div>
+        <PIMTable :table-loading="tableLoading"
+                :table-data="tableData"
+                :column="tableColumns"
+                @selection-change="handleSelectionChange"
+                @pagination="handlePagination"
+                :is-selection="true"
+                :border="true"
+                :page="{
+                  current: pageNum,
+                  size: pageSize,
+                  total: total,
+                  layout: 'total, sizes, prev, pager, next, jumper'
+                }"
+                :table-style="{ width: '100%', height: 'calc(100vh - 23em)' }"
+        >
+          <template #inspector="{ row }">
+            <div class="person-tags">
+              <!-- 璋冭瘯淇℃伅锛屼笂绾挎椂鍒犻櫎 -->
+              <!-- {{ console.log('inspector data:', row.inspector) }} -->
+              <template v-if="row.inspector && row.inspector.length > 0">
+                <el-tag
+                  v-for="(person, index) in row.inspector"
+                  :key="index"
+                  size="small"
+                  type="primary"
+                  class="person-tag"
+                >
+                  {{ person }}
+                </el-tag>
+              </template>
+              <span v-else class="no-data">--</span>
+            </div>
+          </template>
+        </PIMTable>
+      </div>
+    </el-card>
+    <form-dia ref="formDia" @closeDia="handleQuery"></form-dia>
+    <view-files ref="viewFiles"></view-files>
+  </div>
 </template>
 
 <script setup>
@@ -81,16 +80,15 @@
 import { ElMessageBox } from "element-plus";
 
 // 缁勪欢寮曞叆
-import Pagination from "@/components/Pagination/index.vue";
 import PIMTable from "@/components/PIMTable/PIMTable.vue";
 import FormDia from "@/views/equipmentManagement/inspectionManagement/components/formDia.vue";
 import ViewFiles from "@/views/equipmentManagement/inspectionManagement/components/viewFiles.vue";
 
 // 鎺ュ彛寮曞叆
 import {
-	delTimingTask,
-	inspectionTaskList,
-	timingTaskList
+  delTimingTask,
+  inspectionTaskList,
+  timingTaskList
 } from "@/api/inspectionManagement/index.js";
 
 // 鍏ㄥ眬鍙橀噺
@@ -100,14 +98,14 @@
 
 // 鏌ヨ鍙傛暟
 const queryParams = reactive({
-	searchAll: "",
+  searchAll: "",
 });
 
 // 鍗曢�夋閰嶇疆
 const activeRadio = ref("taskManage");
 const radios = reactive([
-	{ name: "taskManage", label: "瀹氭椂浠诲姟绠$悊" },
-	{ name: "task", label: "瀹氭椂浠诲姟璁板綍" },
+  { name: "taskManage", label: "瀹氭椂浠诲姟绠$悊" },
+  { name: "task", label: "瀹氭椂浠诲姟璁板綍" },
 ]);
 
 // 琛ㄦ牸鏁版嵁
@@ -122,233 +120,244 @@
 
 // 鍒楅厤缃�
 const columns = ref([
-	{ prop: "taskName", label: "宸℃浠诲姟鍚嶇О", minWidth: 160 },
-	{ prop: "remarks", label: "澶囨敞", minWidth: 150 },
-	{ prop: "inspector", label: "鎵ц宸℃浜�", minWidth: 150, slot: "inspector" },
-	{
-		prop: "frequencyType",
-		label: "棰戞",
-		minWidth: 150,
-		formatData: (cell) => ({
-			DAILY: "姣忔棩",
-			WEEKLY: "姣忓懆",
-			MONTHLY: "姣忔湀",
-			QUARTERLY: "瀛e害"
-		}[cell] || "")
-	},
-	{
-		prop: "frequencyDetail",
-		label: "寮�濮嬫棩鏈熶笌鏃堕棿",
-		minWidth: 150,
-		formatter: (row, column, cellValue) => {
-			// 鍏堝垽鏂槸鍚︽槸瀛楃涓�
-			if (typeof cellValue !== 'string') return '';
-			let val = cellValue;
-			const replacements = {
-				MON: '鍛ㄤ竴',
-				TUE: '鍛ㄤ簩',
-				WED: '鍛ㄤ笁',
-				THU: '鍛ㄥ洓',
-				FRI: '鍛ㄤ簲',
-				SAT: '鍛ㄥ叚',
-				SUN: '鍛ㄦ棩'
-			};
-			// 浣跨敤姝e垯涓�娆℃�ф浛鎹㈡墍鏈夊尮閰嶉」
-			return val.replace(/MON|TUE|WED|THU|FRI|SAT|SUN/g, match => replacements[match]);
-		}
-	},
-	{ prop: "registrant", label: "鐧昏浜�", minWidth: 100 },
-	{ prop: "dateStr", label: "鐧昏鏃ユ湡", minWidth: 100 },
+  { prop: "taskName", label: "宸℃浠诲姟鍚嶇О", minWidth: 160 },
+  { prop: "remarks", label: "澶囨敞", minWidth: 150 },
+  { prop: "inspector", label: "鎵ц宸℃浜�", minWidth: 150, slot: "inspector" },
+  {
+    prop: "frequencyType",
+    label: "棰戞",
+    minWidth: 150,
+    formatter: (_, __, val) => ({
+      DAILY: "姣忔棩",
+      WEEKLY: "姣忓懆",
+      MONTHLY: "姣忔湀",
+      QUARTERLY: "瀛e害"
+    }[val] || "")
+  },
+  {
+    prop: "frequencyDetail",
+    label: "寮�濮嬫棩鏈熶笌鏃堕棿",
+    minWidth: 150,
+    formatter: (row, column, cellValue) => {
+      // 鍏堝垽鏂槸鍚︽槸瀛楃涓�
+      if (typeof cellValue !== 'string') return '';
+      let val = cellValue;
+      const replacements = {
+        MON: '鍛ㄤ竴',
+        TUE: '鍛ㄤ簩',
+        WED: '鍛ㄤ笁',
+        THU: '鍛ㄥ洓',
+        FRI: '鍛ㄤ簲',
+        SAT: '鍛ㄥ叚',
+        SUN: '鍛ㄦ棩'
+      };
+      // 浣跨敤姝e垯涓�娆℃�ф浛鎹㈡墍鏈夊尮閰嶉」
+      return val.replace(/MON|TUE|WED|THU|FRI|SAT|SUN/g, match => replacements[match]);
+    }
+  },
+  { prop: "registrant", label: "鐧昏浜�", minWidth: 100 },
+  { prop: "createTime", label: "鐧昏鏃ユ湡", minWidth: 100 },
 ]);
 
 // 鎿嶄綔鍒楅厤缃�
 const getOperationColumn = (operations) => {
-	if (!operations || operations.length === 0) return null;
-	
-	const operationConfig = {
-		label: "鎿嶄綔",
-		width: 130,
-		fixed: "right",
-		dataType: "action",
-		operation: operations.map(op => {
-			switch (op) {
-				case 'edit':
-					return {
-						name: "缂栬緫",
-						clickFun: handleAdd,
-						color: "#409EFF"
-					};
-				case 'viewFile':
-					return {
-						name: "鏌ョ湅闄勪欢",
-						clickFun: viewFile,
-						color: "#67C23A"
-					};
-				default:
-					return null;
-			}
-		}).filter(Boolean)
-	};
-	
-	return operationConfig;
+  if (!operations || operations.length === 0) return null;
+  
+  const operationConfig = {
+    label: "鎿嶄綔",
+    width: 130,
+    fixed: "right",
+    dataType: "action",
+    operation: operations.map(op => {
+      switch (op) {
+        case 'edit':
+          return {
+            name: "缂栬緫",
+            clickFun: handleAdd,
+            color: "#409EFF"
+          };
+        case 'viewFile':
+          return {
+            name: "鏌ョ湅闄勪欢",
+            clickFun: viewFile,
+            color: "#67C23A"
+          };
+        default:
+          return null;
+      }
+    }).filter(Boolean)
+  };
+  
+  return operationConfig;
 };
 
 onMounted(() => {
-	radioChange('taskManage');
+  radioChange('taskManage');
 });
 
 // 鍗曢�夊彉鍖�
 const radioChange = (value) => {
-	if (value === "taskManage") {
-		const operationColumn = getOperationColumn(['edit']);
-		tableColumns.value = [...columns.value, ...(operationColumn ? [operationColumn] : [])];
-		operationsArr.value = ['edit'];
-	} else if (value === "task") {
-		const operationColumn = getOperationColumn(['viewFile']);
-		tableColumns.value = [...columns.value, ...(operationColumn ? [operationColumn] : [])];
-		operationsArr.value = ['viewFile'];
-	}
-	pageNum.value = 1;
-	pageSize.value = 10;
-	getList();
+  if (value === "taskManage") {
+    const operationColumn = getOperationColumn(['edit']);
+    tableColumns.value = [...columns.value, ...(operationColumn ? [operationColumn] : [])];
+    operationsArr.value = ['edit'];
+  } else if (value === "task") {
+    const operationColumn = getOperationColumn(['viewFile']);
+    const statusColumn = {
+      prop: "status",
+      label: "浠诲姟鐘舵��",
+      minWidth: 100,
+      dataType: "tag",
+      formatType: (row) => {
+        if (row.status === '宸插贰妫�') return 'success';
+        return 'warning';
+      }
+    };
+    tableColumns.value = [...columns.value, statusColumn, ...(operationColumn ? [operationColumn] : [])];
+    operationsArr.value = ['viewFile'];
+  }
+  pageNum.value = 1;
+  pageSize.value = 10;
+  getList();
 };
 
 // 鏌ヨ鎿嶄綔
 const handleQuery = () => {
-	pageNum.value = 1;
-	pageSize.value = 10;
-	getList();
+  pageNum.value = 1;
+  pageSize.value = 10;
+  getList();
 };
-const pagination = (obj) => {
-	pageNum.value = obj.page;
-	pageSize.value = obj.limit;
+// 鍒嗛〉澶勭悊
+const handlePagination = (val) => {
+	pageNum.value = val.page;
+	pageSize.value = val.limit;
 	getList();
 };
 // 鑾峰彇鍒楄〃鏁版嵁
 const getList = () => {
-	tableLoading.value = true;
-	
-	const params = { ...queryParams, size: pageSize.value, current: pageNum.value };
-	
-	let apiCall;
-	if (activeRadio.value === "task") {
-		apiCall = inspectionTaskList(params);
-	} else {
-		apiCall = timingTaskList(params);
-	}
-	
-	apiCall.then(res => {
-		const rawData = res.data.records || [];
-		// 澶勭悊 inspector 瀛楁锛屽皢瀛楃涓茶浆鎹负鏁扮粍锛堥�傜敤浜庢墍鏈夋儏鍐碉級
-		tableData.value = rawData.map(item => {
-			const processedItem = { ...item };
-			
-			// 澶勭悊 inspector 瀛楁
-			if (processedItem.inspector) {
-				if (typeof processedItem.inspector === 'string') {
-					// 瀛楃涓叉寜閫楀彿鍒嗗壊
-					processedItem.inspector = processedItem.inspector.split(',').map(s => s.trim()).filter(s => s);
-				} else if (!Array.isArray(processedItem.inspector)) {
-					// 闈炴暟缁勮浆涓烘暟缁�
-					processedItem.inspector = [processedItem.inspector];
-				}
-			} else {
-				// 绌哄�艰涓虹┖鏁扮粍
-				processedItem.inspector = [];
-			}
-			
-			return processedItem;
-		});
-		total.value = res.data.total || 0;
-	}).finally(() => {
-		tableLoading.value = false;
-	});
+  tableLoading.value = true;
+  
+  const params = { ...queryParams, size: pageSize.value, current: pageNum.value };
+  
+  let apiCall;
+  if (activeRadio.value === "task") {
+    apiCall = inspectionTaskList(params);
+  } else {
+    apiCall = timingTaskList(params);
+  }
+  
+  apiCall.then(res => {
+    const rawData = res.data.records || [];
+    // 澶勭悊 inspector 瀛楁锛屽皢瀛楃涓茶浆鎹负鏁扮粍锛堥�傜敤浜庢墍鏈夋儏鍐碉級
+    tableData.value = rawData.map(item => {
+      const processedItem = { ...item };
+      
+      // 澶勭悊 inspector 瀛楁
+      if (processedItem.inspector) {
+        if (typeof processedItem.inspector === 'string') {
+          // 瀛楃涓叉寜閫楀彿鍒嗗壊
+          processedItem.inspector = processedItem.inspector.split(',').map(s => s.trim()).filter(s => s);
+        } else if (!Array.isArray(processedItem.inspector)) {
+          // 闈炴暟缁勮浆涓烘暟缁�
+          processedItem.inspector = [processedItem.inspector];
+        }
+      } else {
+        // 绌哄�艰涓虹┖鏁扮粍
+        processedItem.inspector = [];
+      }
+      
+      return processedItem;
+    });
+    total.value = res.data.total || 0;
+  }).finally(() => {
+    tableLoading.value = false;
+  });
 };
 
 // 閲嶇疆鏌ヨ
 const resetQuery = () => {
-	for (const key in queryParams) {
-		if (!["pageNum", "pageSize"].includes(key)) {
-			queryParams[key] = "";
-		}
-	}
-	handleQuery();
+  for (const key in queryParams) {
+    if (!["pageNum", "pageSize"].includes(key)) {
+      queryParams[key] = "";
+    }
+  }
+  handleQuery();
 };
 
 // 鏂板 / 缂栬緫
 const handleAdd = (row) => {
-	const type = row ? 'edit' : 'add';
-	nextTick(() => {
-		formDia.value?.openDialog(type, row);
-	});
+  const type = row ? 'edit' : 'add';
+  nextTick(() => {
+    formDia.value?.openDialog(type, row);
+  });
 };
 
 // 鏌ョ湅闄勪欢
 const viewFile = (row) => {
-	nextTick(() => {
-		viewFiles.value?.openDialog(row);
-	});
+  nextTick(() => {
+    viewFiles.value?.openDialog(row);
+  });
 };
 
 // 鍒犻櫎鎿嶄綔
 const handleDelete = () => {
-	if (!selectedRows.value.length) {
-		proxy.$modal.msgWarning("璇烽�夋嫨瑕佸垹闄ょ殑鏁版嵁");
-		return;
-	}
-	
-	const deleteIds = selectedRows.value.map(item => item.id);
-	
-	proxy.$modal.confirm('鏄惁纭鍒犻櫎鎵�閫夋暟鎹」锛�').then(() => {
-		return delTimingTask(deleteIds);
-	}).then(() => {
-		proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-		handleQuery();
-	}).catch(() => {});
+  if (!selectedRows.value.length) {
+    proxy.$modal.msgWarning("璇烽�夋嫨瑕佸垹闄ょ殑鏁版嵁");
+    return;
+  }
+  
+  const deleteIds = selectedRows.value.map(item => item.id);
+  
+  proxy.$modal.confirm('鏄惁纭鍒犻櫎鎵�閫夋暟鎹」锛�').then(() => {
+    return delTimingTask(deleteIds);
+  }).then(() => {
+    proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+    handleQuery();
+  }).catch(() => {});
 };
 
 // 澶氶�夊彉鏇�
 const handleSelectionChange = (selection) => {
-	selectedRows.value = selection;
+  selectedRows.value = selection;
 };
 
 // 瀵煎嚭
 const handleOut = () => {
-	ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
-		confirmButtonText: "纭",
-		cancelButtonText: "鍙栨秷",
-		type: "warning",
-	})
-		.then(() => {
-			// 鏍规嵁褰撳墠閫変腑鐨勬爣绛鹃〉璋冪敤涓嶅悓鐨勫鍑烘帴鍙�
-			if (activeRadio.value === "taskManage") {
-				// 瀹氭椂浠诲姟绠$悊
-				proxy.download("/timingTask/export", {}, "瀹氭椂浠诲姟绠$悊.xlsx");
-			} else if (activeRadio.value === "task") {
-				// 瀹氭椂浠诲姟璁板綍
-				proxy.download("/inspectionTask/export", {}, "瀹氭椂浠诲姟璁板綍.xlsx");
-			}
-		})
-		.catch(() => {
-			proxy.$modal.msg("宸插彇娑�");
-		});
+  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  })
+    .then(() => {
+      // 鏍规嵁褰撳墠閫変腑鐨勬爣绛鹃〉璋冪敤涓嶅悓鐨勫鍑烘帴鍙�
+      if (activeRadio.value === "taskManage") {
+        // 瀹氭椂浠诲姟绠$悊
+        proxy.download("/timingTask/export", {}, "瀹氭椂浠诲姟绠$悊.xlsx");
+      } else if (activeRadio.value === "task") {
+        // 瀹氭椂浠诲姟璁板綍
+        proxy.download("/inspectionTask/export", {}, "瀹氭椂浠诲姟璁板綍.xlsx");
+      }
+    })
+    .catch(() => {
+      proxy.$modal.msg("宸插彇娑�");
+    });
 };
 </script>
 
 <style scoped>
 .person-tags {
-	display: flex;
-	flex-wrap: wrap;
-	gap: 4px;
+  display: flex;
+  flex-wrap: wrap;
+  gap: 4px;
 }
 
 .person-tag {
-	margin-right: 4px;
-	margin-bottom: 2px;
+  margin-right: 4px;
+  margin-bottom: 2px;
 }
 
 .no-data {
-	color: #909399;
-	font-size: 14px;
+  color: #909399;
+  font-size: 14px;
 }
 </style>
\ No newline at end of file
diff --git a/src/views/equipmentManagement/ledger/Form.vue b/src/views/equipmentManagement/ledger/Form.vue
index d14f4ff..fe204a7 100644
--- a/src/views/equipmentManagement/ledger/Form.vue
+++ b/src/views/equipmentManagement/ledger/Form.vue
@@ -32,71 +32,29 @@
         </el-form-item>
       </el-col>
       <el-col :span="12">
-        <el-form-item label="鍚敤鎶樻棫" prop="enableDepreciation">
-          <el-switch v-model="form.enableDepreciation" :active-value="true" :inactive-value="false" />
-        </el-form-item>
-      </el-col>
-      <el-col :span="12">
         <el-form-item label="鏁伴噺" prop="number">
           <el-input-number :min="1" style="width: 100%"
             v-model="form.number"
-													 disabled
+											 disabled
             placeholder="璇疯緭鍏ユ暟閲�"
-            @change="mathNum"
           />
         </el-form-item>
       </el-col>
       <el-col :span="12">
-        <el-form-item label="鍚◣鍗曚环" prop="taxIncludingPriceUnit">
-          <el-input-number :step="0.01" :min="0" style="width: 100%"
+        <el-form-item label="璧勪骇鍘熷��" prop="taxIncludingPriceUnit">
+          <el-input-number :min="0" style="width: 100%"
+													 :precision="2"
             v-model="form.taxIncludingPriceUnit"
-            placeholder="璇疯緭鍏ュ惈绋庡崟浠�"
+            placeholder="璇疯緭鍏ヨ祫浜у師鍊�"
             maxlength="10"
-            @change="mathNum"
           />
         </el-form-item>
       </el-col>
-      <el-col :span="12">
-        <el-form-item label="鍚◣鎬讳环" prop="taxIncludingPriceTotal">
-          <el-input
-            v-model="form.taxIncludingPriceTotal"
-            placeholder="鑷姩鐢熸垚"
-            type="number"
-            disabled
-          />
-        </el-form-item>
-      </el-col>
-      <el-col :span="12">
-        <el-form-item label="绋庣巼(%)" prop="taxRate">
-          <!-- <el-input
-            v-model="form.taxRate"
-            placeholder="璇疯緭鍏ョ◣鐜�"
-            type="number"
-          >
-            <template #append> % </template>
-          </el-input> -->
-          <el-select
-            v-model="form.taxRate"
-            placeholder="璇烽�夋嫨"
-            clearable
-            @change="mathNum"
-          >
-            <el-option label="1" :value="1" />
-            <el-option label="6" :value="6" />
-            <el-option label="13" :value="13" />
-          </el-select>
-        </el-form-item>
-      </el-col>
-      <el-col :span="12">
-        <el-form-item label="涓嶅惈绋庢�讳环" prop="unTaxIncludingPriceTotal">
-          <el-input
-            v-model="form.unTaxIncludingPriceTotal"
-            placeholder="鑷姩鐢熸垚"
-            type="number"
-            disabled
-          />
-        </el-form-item>
-      </el-col>
+			<el-col :span="12">
+				<el-form-item label="鍚敤鎶樻棫" prop="enableDepreciation">
+					<el-switch v-model="form.enableDepreciation" :active-value="true" :inactive-value="false" />
+				</el-form-item>
+			</el-col>
       <!-- <el-col :span="12">
         <el-form-item label="褰曞叆浜�" prop="createUser">
           <el-input v-model="form.createUser" placeholder="璇疯緭鍏ュ綍鍏ヤ汉" />
@@ -137,11 +95,6 @@
 // import useUserStore from "@/store/modules/user";
 import { getLedgerById } from "@/api/equipmentManagement/ledger";
 import dayjs from "dayjs";
-import {
-  calculateTaxIncludeTotalPrice,
-  calculateTaxExclusiveTotalPrice,
-} from "@/utils/summarizeTable";
-import { ElMessage } from "element-plus";
 import {ref} from "vue";
 
 defineOptions({
@@ -151,13 +104,25 @@
 const operationType = ref('');
 const formRules = {
 	deviceName: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
-	deviceModel: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
-	supplierName: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
-	unit: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
-	number: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
-	taxIncludingPriceUnit: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
-	taxRate: [{ required: true, trigger: "change", message: "璇疯緭鍏�" }],
-	planRuntimeTime: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
+	deviceModel: [{ trigger: "blur", message: "璇疯緭鍏�" }],
+	supplierName: [{ trigger: "blur", message: "璇疯緭鍏�" }],
+	unit: [{ trigger: "blur", message: "璇疯緭鍏�" }],
+	taxIncludingPriceUnit: [
+		{
+			required: true,
+			trigger: "blur",
+			validator: (rule, value, callback) => {
+				if (value === undefined || value === null || value === '') {
+					callback(new Error("璇疯緭鍏ヨ祫浜у師鍊�"));
+				} else if (typeof value === 'number' && value >= 0) {
+					callback();
+				} else {
+					callback(new Error("璇疯緭鍏ユ湁鏁堢殑璧勪骇鍘熷��"));
+				}
+			}
+		}
+	],
+	planRuntimeTime: [{ trigger: "change", message: "璇烽�夋嫨" }],
 }
 
 const { form, resetForm } = useFormData({
@@ -169,10 +134,7 @@
   enableDepreciation: false, // 鏄惁鍚敤鎶樻棫
   unit: undefined, // 鍗曚綅
   number: 1, // 鏁伴噺
-  taxIncludingPriceUnit: undefined, // 鍚◣鍗曚环
-  taxIncludingPriceTotal: undefined, // 鍚◣鎬讳环
-  taxRate: undefined, // 绋庣巼
-  unTaxIncludingPriceTotal: undefined, // 涓嶅惈绋庢�讳环
+	taxIncludingPriceUnit: undefined, // 璧勪骇鍘熷��
   // createUser: useUserStore().nickName, // 褰曞叆浜�
   createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), // 褰曞叆鏃ユ湡
 	planRuntimeTime: dayjs().format("YYYY-MM-DD"), // 褰曞叆鏃ユ湡
@@ -193,29 +155,11 @@
     form.unit = data.unit;
     form.number = 1;
     form.taxIncludingPriceUnit = data.taxIncludingPriceUnit;
-    form.taxIncludingPriceTotal = data.taxIncludingPriceTotal;
-    form.taxRate = data.taxRate;
-    form.unTaxIncludingPriceTotal = data.unTaxIncludingPriceTotal;
     form.createTime = data.createTime;
   }
 };
 
-const mathNum = () => {
-  if (!form.taxIncludingPriceUnit) {
-    ElMessage.error("璇疯緭鍏ュ崟浠�");
-    return;
-  }
-  form.taxIncludingPriceTotal = calculateTaxIncludeTotalPrice(
-    form.taxIncludingPriceUnit,
-    form.number
-  );
-  if (form.taxRate) {
-    form.unTaxIncludingPriceTotal = calculateTaxExclusiveTotalPrice(
-      form.taxIncludingPriceTotal,
-      form.taxRate
-    );
-  }
-};
+
 
 // 娓呴櫎琛ㄥ崟鏍¢獙鐘舵��
 const clearValidate = () => {
diff --git a/src/views/equipmentManagement/ledger/Modal.vue b/src/views/equipmentManagement/ledger/Modal.vue
index 16166c6..0cea56c 100644
--- a/src/views/equipmentManagement/ledger/Modal.vue
+++ b/src/views/equipmentManagement/ledger/Modal.vue
@@ -1,5 +1,5 @@
 <template>
-  <el-dialog :title="modalOptions.title" v-model="visible" @close="close" draggable>
+  <el-dialog :title="modalOptions.title" v-model="visible" @close="close">
     <Form ref="formRef"></Form>
     <template #footer>
 			<el-button type="primary" @click="sendForm" :loading="loading">
diff --git a/src/views/equipmentManagement/ledger/index.vue b/src/views/equipmentManagement/ledger/index.vue
index 8cdbf32..0a2ce3c 100644
--- a/src/views/equipmentManagement/ledger/index.vue
+++ b/src/views/equipmentManagement/ledger/index.vue
@@ -55,6 +55,7 @@
         <div></div>
         <div>
           <el-button type="primary" @click="add" icon="Plus"> 鏂板 </el-button>
+          <el-button plain icon="Upload" @click="handleImport">瀵煎叆</el-button>
           <el-button @click="handleOut" icon="download">瀵煎嚭</el-button>
           <el-button
             type="danger"
@@ -82,13 +83,58 @@
       </PIMTable>
     </div>
     <Modal ref="modalRef" @success="getTableData"></Modal>
-    <el-dialog v-model="qrDialogVisible" title="浜岀淮鐮�" width="300px" draggable>
+    <el-dialog v-model="qrDialogVisible" title="浜岀淮鐮�" width="300px">
       <div style="text-align:center;">
         <img :src="qrCodeUrl" alt="浜岀淮鐮�" style="width:200px;height:200px;" />
+        <div style="margin-top:6px;font-size:14px;color:#333;">{{ qrRowData?.deviceName }}</div>
         <div style="margin:10px 0;">
           <el-button type="primary" @click="downloadQRCode">涓嬭浇浜岀淮鐮佸浘鐗�</el-button>
         </div>
       </div>
+    </el-dialog>
+    <!-- 鐢ㄦ埛瀵煎叆瀵硅瘽妗� -->
+    <el-dialog
+      :title="upload.title"
+      v-model="upload.open"
+      width="400px"
+      append-to-body
+    >
+      <el-upload
+        ref="uploadRef"
+        :limit="1"
+        accept=".xlsx, .xls"
+        :headers="upload.headers"
+        :action="upload.url + '?updateSupport=' + upload.updateSupport"
+        :disabled="upload.isUploading"
+        :before-upload="upload.beforeUpload"
+        :on-progress="upload.onProgress"
+        :on-success="upload.onSuccess"
+        :on-error="upload.onError"
+        :on-change="upload.onChange"
+        :auto-upload="false"
+        drag
+      >
+        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
+        <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
+        <template #tip>
+          <div class="el-upload__tip text-center">
+            <span>浠呭厑璁稿鍏ls銆亁lsx鏍煎紡鏂囦欢銆�</span>
+            <el-link
+              type="primary"
+              :underline="false"
+              style="font-size: 12px; vertical-align: baseline"
+              @click="importTemplate"
+              >涓嬭浇妯℃澘</el-link
+            >
+          </div>
+        </template>
+      </el-upload>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button>
+          <el-button @click="upload.open = false">鍙� 娑�</el-button>
+        </div>
+      </template>
     </el-dialog>
   </div>
 </template>
@@ -103,6 +149,7 @@
 import dayjs from "dayjs";
 import QRCode from "qrcode";
 import { ref } from "vue";
+import { getToken } from "@/utils/auth.js";
 
 defineOptions({
   name: "璁惧鍙拌处",
@@ -171,24 +218,9 @@
       prop: "number",
     },
     {
-      label: "鍚◣鍗曚环",
+      label: "璧勪骇鍘熷��",
       align: "center",
       prop: "taxIncludingPriceUnit",
-    },
-    {
-      label: "鍚◣鎬讳环",
-      align: "center",
-      prop: "taxIncludingPriceTotal",
-    },
-    {
-      label: "绋庣巼",
-      align: "center",
-      prop: "taxRate",
-    },
-    {
-      label: "涓嶅惈绋庢�讳环",
-      align: "center",
-      prop: "unTaxIncludingPriceTotal",
     },
     {
       label: "鍚敤鎶樻棫",
@@ -231,6 +263,69 @@
 		},
   ]
 );
+
+const upload = reactive({
+  // 鏄惁鏄剧ず寮瑰嚭灞傦紙瀹㈡埛瀵煎叆锛�
+  open: false,
+  // 寮瑰嚭灞傛爣棰橈紙瀹㈡埛瀵煎叆锛�
+  title: "",
+  // 鏄惁绂佺敤涓婁紶
+  isUploading: false,
+  // 璁剧疆涓婁紶鐨勮姹傚ご閮�
+  headers: { Authorization: "Bearer " + getToken() },
+  // 涓婁紶鐨勫湴鍧�
+  url: import.meta.env.VITE_APP_BASE_API + "/device/ledger/import",
+  // 鏂囦欢涓婁紶鍓嶇殑鍥炶皟
+  beforeUpload: (file) => {
+    console.log('鏂囦欢鍗冲皢涓婁紶', file);
+    // 鍙互鍦ㄦ澶勫仛鏂囦欢绫诲瀷鎴栧ぇ灏忔牎楠�
+    const isValid = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || file.name.endsWith('.xlsx') || file.name.endsWith('.xls');
+    if (!isValid) {
+      proxy.$modal.msgError("鍙兘涓婁紶 Excel 鏂囦欢");
+    }
+    return isValid;
+  },
+  // 鏂囦欢鐘舵�佹敼鍙樻椂鐨勫洖璋�
+  onChange: (file, fileList) => {
+    console.log('鏂囦欢鐘舵�佹敼鍙�', file, fileList);
+  },
+  // 鏂囦欢涓婁紶鎴愬姛鏃剁殑鍥炶皟
+  onSuccess: (response, file, fileList) => {
+    console.log('涓婁紶鎴愬姛', response, file, fileList);
+    upload.isUploading = false;
+    if(response.code === 200){
+      proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
+      upload.open = false;
+      proxy.$refs["uploadRef"].clearFiles();
+      getTableData();
+    }else if(response.code === 500){
+      proxy.$modal.msgError(response.msg);
+    }else{
+      proxy.$modal.msgWarning(response.msg);
+    }
+  },
+  // 鏂囦欢涓婁紶澶辫触鏃剁殑鍥炶皟
+  onError: (error, file, fileList) => {
+    console.error('涓婁紶澶辫触', error, file, fileList);
+    upload.isUploading = false;
+    proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
+  },
+  // 鏂囦欢涓婁紶杩涘害鍥炶皟
+  onProgress: (event, file, fileList) => {
+    console.log('涓婁紶涓�...', event.percent);
+  }
+});
+
+/** 鎻愪氦涓婁紶鏂囦欢 */
+const submitFileForm = () => {
+  upload.isUploading = true;
+  proxy.$refs["uploadRef"].submit();
+}
+
+/** 涓嬭浇妯℃澘 */
+const importTemplate = () => {
+  proxy.download("/device/ledger/downloadTemplate", {}, "璁惧鍙拌处妯℃澘.xlsx");
+}
 
 // 澶氶�夊悗鍋氫粈涔�
 const handleSelectionChange = (selectionList) => {
@@ -275,6 +370,11 @@
   }
   getTableData();
 };
+/** 瀵煎叆鎸夐挳鎿嶄綔 */
+const handleImport = () => {
+  upload.title = "璁惧鍙拌处瀵煎叆";
+  upload.open = true;
+}
 
 const handleOut = () => {
   ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
@@ -299,10 +399,44 @@
 };
 
 const downloadQRCode = () => {
-  const a = document.createElement("a");
-  a.href = qrCodeUrl.value;
-  a.download = `${qrRowData.value.deviceName || "浜岀淮鐮�"}.png`;
-  a.click();
+  const name = qrRowData.value?.deviceName || "浜岀淮鐮�";
+  const img = new Image();
+  img.src = qrCodeUrl.value;
+  img.onload = () => {
+    const padding = 10;
+    const qrSize = 200;
+    const textHeight = 24; // space for text
+    const width = qrSize + padding * 2;
+    const height = qrSize + padding * 2 + textHeight;
+    const canvas = document.createElement("canvas");
+    canvas.width = width;
+    canvas.height = height;
+    const ctx = canvas.getContext("2d");
+    // background
+    ctx.fillStyle = "#ffffff";
+    ctx.fillRect(0, 0, width, height);
+    // draw QR centered
+    ctx.drawImage(img, padding, padding, qrSize, qrSize);
+    // draw name centered below
+    ctx.fillStyle = "#333";
+    ctx.font = "14px Arial";
+    ctx.textAlign = "center";
+    ctx.textBaseline = "middle";
+    const maxTextWidth = width - padding * 2;
+    let displayName = name;
+    // ellipsis if too long
+    while (ctx.measureText(displayName).width > maxTextWidth && displayName.length > 0) {
+      displayName = displayName.slice(0, -1);
+    }
+    if (displayName !== name) displayName = displayName + "鈥�";
+    ctx.fillText(displayName, width / 2, qrSize + padding + textHeight / 2);
+
+    const dataUrl = canvas.toDataURL("image/png");
+    const a = document.createElement("a");
+    a.href = dataUrl;
+    a.download = `${name}.png`;
+    a.click();
+  };
 };
 
 onMounted(() => {
diff --git a/src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue b/src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue
index d4ac2e1..8987485 100644
--- a/src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue
+++ b/src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue
@@ -4,7 +4,6 @@
 			v-model="dialogFormVisible"
 			title="璁¢噺鍣ㄥ叿"
 			width="50%"
-			draggable
 			@close="closeDia"
 		>
 			<el-form
@@ -68,9 +67,7 @@
 							<el-select
 								v-model="form.userId"
 								placeholder="璇烽�夋嫨"
-                filterable
-                default-first-option
-                :reserve-keyword="false"
+								disabled
 								clearable
 							>
 								<el-option
@@ -132,7 +129,6 @@
 import {getToken} from "@/utils/auth.js";
 import {ledgerRecordUpdate, ledgerRecordVerifying} from "@/api/equipmentManagement/calibration.js";
 import {delLedgerFile} from "@/api/salesManagement/salesLedger.js";
-import { getCurrentDate } from "@/utils/index.js";
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
 const dialogFormVisible = ref(false);
@@ -252,6 +248,14 @@
 	dialogFormVisible.value = false;
 	emit('close')
 };
+// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
+function getCurrentDate() {
+	const today = new Date();
+	const year = today.getFullYear();
+	const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
+	const day = String(today.getDate()).padStart(2, "0");
+	return `${year}-${month}-${day}`;
+}
 defineExpose({
 	openDialog,
 });
diff --git a/src/views/equipmentManagement/measurementEquipment/components/formDia.vue b/src/views/equipmentManagement/measurementEquipment/components/formDia.vue
index 7b6097b..891316d 100644
--- a/src/views/equipmentManagement/measurementEquipment/components/formDia.vue
+++ b/src/views/equipmentManagement/measurementEquipment/components/formDia.vue
@@ -4,7 +4,6 @@
         v-model="dialogFormVisible"
         title="璁¢噺鍣ㄥ叿"
         width="50%"
-				draggable
         @close="closeDia"
     >
 			<el-form
@@ -65,9 +64,7 @@
 								v-model="form.userId"
 								placeholder="璇烽�夋嫨"
 								clearable
-                filterable
-                default-first-option
-                :reserve-keyword="false"
+								disabled
 							>
 								<el-option
 									v-for="item in userList"
@@ -127,7 +124,6 @@
 import {afterSalesServiceAdd, afterSalesServiceUpdate} from "@/api/customerService/index.js";
 import {getToken} from "@/utils/auth.js";
 import {measuringInstrumentAdd, measuringInstrumentUpdate} from "@/api/equipmentManagement/measurementEquipment.js";
-import { getCurrentDate } from "@/utils/index.js";
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
 const dialogFormVisible = ref(false);
@@ -238,6 +234,14 @@
   dialogFormVisible.value = false;
   emit('close')
 };
+// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
+function getCurrentDate() {
+	const today = new Date();
+	const year = today.getFullYear();
+	const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
+	const day = String(today.getDate()).padStart(2, "0");
+	return `${year}-${month}-${day}`;
+}
 defineExpose({
   openDialog,
 });
diff --git a/src/views/equipmentManagement/measurementEquipment/index.vue b/src/views/equipmentManagement/measurementEquipment/index.vue
index 363a85a..e983a99 100644
--- a/src/views/equipmentManagement/measurementEquipment/index.vue
+++ b/src/views/equipmentManagement/measurementEquipment/index.vue
@@ -148,13 +148,13 @@
 					openCalibrationDia("verifying", row);
 				},
 			},
-			// {
-			// 	name: "闄勪欢",
-			// 	type: "text",
-			// 	clickFun: (row) => {
-      //     openFilesFormDia(row);
-			// 	},
-			// },
+			{
+				name: "闄勪欢",
+				type: "text",
+				clickFun: (row) => {
+          openFilesFormDia(row);
+				},
+			},
 		],
 	},
 ]);
@@ -221,6 +221,12 @@
 const handleDelete = () => {
 	let ids = [];
 	if (selectedRows.value.length > 0) {
+		// 妫�鏌ユ槸鍚︽湁浠栦汉缁存姢鐨勬暟鎹�
+		const unauthorizedData = selectedRows.value.filter(item => item.userId !== userStore.id);
+		if (unauthorizedData.length > 0) {
+			proxy.$modal.msgWarning("涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�");
+			return;
+		}
 		ids = selectedRows.value.map((item) => item.id);
 	} else {
 		proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
diff --git a/src/views/equipmentManagement/repair/Form/MaintainForm.vue b/src/views/equipmentManagement/repair/Form/MaintainForm.vue
deleted file mode 100644
index 2a64d3f..0000000
--- a/src/views/equipmentManagement/repair/Form/MaintainForm.vue
+++ /dev/null
@@ -1,66 +0,0 @@
-<template>
-  <el-form :model="form" label-width="80px">
-    <el-form-item label="缁翠慨浜�">
-      <el-input v-model="form.maintenanceName" placeholder="璇疯緭鍏ョ淮淇汉" />
-    </el-form-item>
-    <el-form-item label="缁翠慨缁撴灉">
-      <el-input v-model="form.maintenanceResult" placeholder="璇疯緭鍏ョ淮淇粨鏋�" />
-    </el-form-item>
-    <el-form-item label="鎶ヤ慨鐘舵��">
-      <el-select v-model="form.status">
-        <el-option label="寰呮姤淇�" :value="0"></el-option>
-        <el-option label="瀹岀粨" :value="1"></el-option>
-        <el-option label="澶辫触" :value="2"></el-option>
-      </el-select>
-    </el-form-item>
-    <el-form-item label="缁翠慨鏃ユ湡">
-      <el-date-picker
-        v-model="form.maintenanceTime"
-        placeholder="璇烽�夋嫨缁翠慨鏃ユ湡"
-        format="YYYY-MM-DD HH:mm:ss"
-        value-format="YYYY-MM-DD HH:mm:ss"
-        type="datetime"
-        clearable
-        style="width: 100%"
-      />
-    </el-form-item>
-  </el-form>
-</template>
-
-<script setup>
-import useFormData from "@/hooks/useFormData";
-import useUserStore from "@/store/modules/user";
-import dayjs from "dayjs";
-
-defineOptions({
-  name: "璁惧缁翠慨琛ㄥ崟",
-});
-
-const userStore = useUserStore();
-const { form, resetForm } = useFormData({
-  maintenanceName: undefined, // 缁翠慨鍚嶇О
-  maintenanceResult: undefined, // 缁翠慨缁撴灉
-  maintenanceTime: undefined, // 缁翠慨鏃ユ湡
-  status: 0,
-});
-
-const setForm = (data) => {
-  form.maintenanceName = data.maintenanceName ?? userStore.nickName;
-  form.maintenanceResult = data.maintenanceResult;
-  form.maintenanceTime =
-    dayjs(data.maintenanceTime).format("YYYY-MM-DD HH:mm:ss") ??
-    dayjs().format("YYYY-MM-DD HH:mm:ss");
-};
-
-const getForm = () => {
-  return form;
-};
-
-defineExpose({
-  getForm,
-  setForm,
-  resetForm,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/repair/Form/RepairForm.vue b/src/views/equipmentManagement/repair/Form/RepairForm.vue
deleted file mode 100644
index f374172..0000000
--- a/src/views/equipmentManagement/repair/Form/RepairForm.vue
+++ /dev/null
@@ -1,180 +0,0 @@
-<template>
-  <el-form :model="form" ref="formModelRefs" :rules="rules" label-width="100px">
-    <el-row>
-      <el-col :span="12">
-        <el-form-item label="璁惧鍚嶇О" prop="deviceLedgerId">
-          <el-select v-model="form.deviceLedgerId" @change="setDeviceModel" filterable>
-            <el-option
-              v-for="(item, index) in deviceOptions"
-              :key="index"
-              :label="item.deviceName"
-              :value="item.id"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-      </el-col>
-      <el-col :span="12">
-        <el-form-item label="瑙勬牸鍨嬪彿" prop="deviceModel">
-          <el-input
-            v-model="form.deviceModel"
-            placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
-            disabled
-          />
-        </el-form-item>
-      </el-col>
-      <el-col :span="12">
-        <el-form-item label="鎶ヤ慨鏃ユ湡" prop="repairTime">
-          <el-date-picker
-            v-model="form.repairTime"
-            placeholder="璇烽�夋嫨鎶ヤ慨鏃ユ湡"
-            format="YYYY-MM-DD"
-            value-format="YYYY-MM-DD"
-            type="date"
-            clearable
-            style="width: 100%"
-          />
-        </el-form-item>
-      </el-col>
-      <el-col :span="12">
-        <el-form-item label="鎶ヤ慨浜哄憳" prop="repairName">
-          <el-input v-model="form.repairName" placeholder="璇疯緭鍏ユ姤淇汉鍛�" />
-        </el-form-item>
-      </el-col>
-    </el-row>
-    <el-row v-if="id">
-      <el-col :span="12">
-        <el-form-item label="鎶ヤ慨鐘舵��">
-          <el-select v-model="form.status" prop="status">
-            <el-option label="寰呯淮淇�" :value="0"></el-option>
-            <el-option label="瀹岀粨" :value="1"></el-option>
-            <el-option label="澶辫触" :value="2"></el-option>
-          </el-select>
-        </el-form-item>
-      </el-col>
-    </el-row>
-    <el-row>
-      <el-col :span="12">
-        <el-form-item label="鎶ヤ慨閲戦" prop="maintenancePrice">
-          <el-input-number
-              style="width: 100%"
-              :min="0"
-              v-model="form.maintenancePrice"
-              placeholder="璇疯緭鍏ヤ繚淇噾棰�"
-          />
-        </el-form-item>
-      </el-col>
-      <el-col :span="12">
-        <el-form-item label="瀹℃壒浜哄憳" prop="approverId">
-          <el-select v-model="form.approverId" placeholder="璇烽�夋嫨瀹℃壒浜哄憳" clearable>
-            <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
-          </el-select>
-        </el-form-item>
-      </el-col>
-    </el-row>
-    <el-row>
-      <el-col :span="24">
-        <el-form-item label="鏁呴殰鐜拌薄" prop="remark">
-          <el-input
-            v-model="form.remark"
-            :rows="2"
-            type="textarea"
-            placeholder="璇疯緭鍏ユ晠闅滅幇璞�"
-          />
-        </el-form-item>
-      </el-col>
-    </el-row>
-  </el-form>
-</template>
-
-<script setup>
-import {onMounted} from "vue"
-import dayjs from "dayjs";
-import useFormData from "@/hooks/useFormData";
-import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
-import useUserStore from "@/store/modules/user";
-import { userListNoPage } from "@/api/system/user.js";
-
-const { id } = defineProps(["id"])
-
-defineOptions({
-  name: "璁惧鎶ヤ慨琛ㄥ崟",
-});
-
-const userStore = useUserStore();
-const deviceOptions = ref([]);
-const formModelRefs = ref(null)
-const userList = ref(null)
-
-const loadDeviceName = async () => {
-  const { data } = await getDeviceLedger();
-  deviceOptions.value = data;
-};
-
-const rules = {
-  deviceLedgerId: [{ required: true, message: "璇烽�夋嫨璁惧鍚嶇О", trigger: "change" }],
-  repairTime: [{ required: true, message: "璇烽�夋嫨鎶ヤ慨鏃ユ湡", trigger: "change" }],
-  repairName: [{ required: true, message: "璇疯緭鍏ユ姤淇汉", trigger: "blur" }],
-  remark: [{ required: true, message: "璇疯緭鍏ユ晠闅滅幇璞�", trigger: "blur" }],
-  maintenancePrice: [{ required: true, message: "璇疯緭鍏ヤ繚淇噾棰�", trigger: "blur" }],
-  approverId:[{required: true,message: "璇烽�夋嫨瀹℃壒浜�", trigger: "change"}]
-};
-
-// 鏍¢獙琛ㄥ崟鏄惁鍚堣
-const submitForm = async () => {
-  if (!formModelRefs.value) return false;
-
-  try {
-    await formModelRefs.value.validate();
-    return true; // 琛ㄥ崟楠岃瘉閫氳繃
-  } catch (error) {
-    return false; // 琛ㄥ崟楠岃瘉澶辫触
-  }
-};
-
-const { form, resetForm } = useFormData({
-  deviceLedgerId: undefined, // 璁惧Id
-  deviceName: undefined, // 璁惧鍚嶇О
-  deviceModel: undefined, // 瑙勬牸鍨嬪彿
-  repairTime: dayjs().format("YYYY-MM-DD"), // 鎶ヤ慨鏃ユ湡锛岄粯璁ゅ綋澶�
-  repairName: userStore.nickName, // 鎶ヤ慨浜�
-  remark: undefined, // 鏁呴殰鐜拌薄
-  status: 0, // 鎶ヤ慨鐘舵��
-  maintenancePrice:0, // 淇濅慨閲戦
-});
-
-const setDeviceModel = (id) => {
-  const option = deviceOptions.value.find((item) => item.id === id);
-  form.deviceModel = option.deviceModel;
-};
-
-const getForm = () => {
-  return form;
-};
-
-const setForm = (data) => {
-  form.deviceLedgerId = data.deviceLedgerId;
-  form.deviceName = data.deviceName;
-  form.deviceModel = data.deviceModel;
-  form.repairTime = data.repairTime;
-  form.repairName = data.repairName;
-  form.remark = data.remark;
-  form.status = data.status;
-  form.maintenancePrice = data.maintenancePrice
-};
-
-onMounted(async() => {
-  // loadDeviceName();
-  let userLists = await userListNoPage();
-  userList.value = userLists.data;
-});
-
-defineExpose({
-  loadDeviceName,
-  resetForm,
-  getForm,
-  setForm,
-  submitForm
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/repair/Modal/ApproveModal.vue b/src/views/equipmentManagement/repair/Modal/ApproveModal.vue
new file mode 100644
index 0000000..74f3605
--- /dev/null
+++ b/src/views/equipmentManagement/repair/Modal/ApproveModal.vue
@@ -0,0 +1,142 @@
+<template>
+  <FormDialog
+    v-model="visible"
+    title="鎶ヤ慨瀹℃壒"
+    width="800px"
+    @confirm="handleSubmit"
+    @cancel="handleClose"
+    @close="handleClose"
+  >
+    <el-descriptions :column="2" border>
+      <el-descriptions-item label="璁惧鍚嶇О">
+        {{ detail.deviceName || "-" }}
+      </el-descriptions-item>
+      <el-descriptions-item label="瑙勬牸鍨嬪彿">
+        {{ detail.deviceModel || "-" }}
+      </el-descriptions-item>
+      <el-descriptions-item label="鎶ヤ慨鏃ユ湡">
+        {{ detail.repairTime || "-" }}
+      </el-descriptions-item>
+      <el-descriptions-item label="鎶ヤ慨浜�">
+        {{ detail.repairName || "-" }}
+      </el-descriptions-item>
+      <el-descriptions-item label="瀹℃壒浜�">
+        {{ detail.auditName || "-" }}
+      </el-descriptions-item>
+      <el-descriptions-item label="褰撳墠鐘舵��">
+        {{ statusText(detail.status) }}
+      </el-descriptions-item>
+      <el-descriptions-item label="鏁呴殰鐜拌薄" :span="2">
+        {{ detail.remark || "-" }}
+      </el-descriptions-item>
+    </el-descriptions>
+    <div style="margin-top: 16px">
+      <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
+        <el-form-item label="瀹℃壒缁撴灉" prop="decision">
+          <el-radio-group v-model="form.decision">
+            <el-radio :value="0">閫氳繃</el-radio>
+            <el-radio :value="3">涓嶉�氳繃</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="鐩戠潱浜�" prop="supervisoryName">
+          <el-input v-model="form.supervisoryName" placeholder="璇疯緭鍏ョ洃鐫d汉" clearable style="width: 100%" />
+        </el-form-item>
+      </el-form>
+    </div>
+  </FormDialog>
+</template>
+
+<script setup>
+import { nextTick, ref } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
+import { editRepair, getRepairById } from "@/api/equipmentManagement/repair";
+
+defineOptions({
+  name: "鎶ヤ慨瀹℃壒寮圭獥",
+});
+
+const emits = defineEmits(["ok"]);
+
+const visible = ref(false);
+const loading = ref(false);
+const id = ref();
+const detail = ref({});
+const formRef = ref();
+const form = ref({
+  decision: undefined, // 0 閫氳繃 3 涓嶉�氳繃
+  supervisoryName: undefined, // 鐩戠潱浜�
+});
+
+const rules = {
+  decision: [{ required: true, message: "璇烽�夋嫨瀹℃壒缁撴灉", trigger: "change" }],
+  supervisoryName: [{ required: true, message: "璇烽�夋嫨鐩戠潱浜�", trigger: "change" }],
+};
+
+const statusText = (status) => {
+  const map = {
+    0: "寰呯淮淇�",
+    1: "瀹岀粨",
+    2: "寰呭鏍�",
+    3: "瀹℃牳涓嶉�氳繃",
+  };
+  return map[status] ?? "-";
+};
+
+const loadDetail = async (repairId) => {
+  const { data } = await getRepairById(repairId);
+  detail.value = data ?? {};
+};
+
+const open = async (repairId) => {
+  id.value = repairId;
+  visible.value = true;
+  await nextTick();
+  await loadDetail(repairId);
+  form.value.decision = undefined;
+  form.value.supervisoryName = undefined;
+};
+
+const handleClose = () => {
+  visible.value = false;
+  id.value = undefined;
+  detail.value = {};
+  form.value.decision = undefined;
+  form.value.supervisoryName = undefined;
+};
+
+const updateStatus = async (status) => {
+  loading.value = true;
+  try {
+    const { code } = await editRepair({ id: id.value, status, supervisoryName: form.value.supervisoryName });
+    if (code === 200) {
+      ElMessage.success("瀹℃壒鎴愬姛");
+      emits("ok");
+      handleClose();
+    }
+  } finally {
+    loading.value = false;
+  }
+};
+
+const handleSubmit = async () => {
+  if (detail.value?.status !== 2) {
+    ElMessage.warning("浠呭緟瀹℃牳鐘舵�佸彲瀹℃壒");
+    return;
+  }
+  await formRef.value?.validate(async (valid) => {
+    if (!valid) return;
+    const isApprove = form.value.decision === 0;
+    ElMessageBox.confirm(`纭瀹℃壒${isApprove ? "閫氳繃" : "涓嶉�氳繃"}锛焋, "鎻愮ず", {
+      confirmButtonText: "纭畾",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    }).then(() => updateStatus(form.value.decision));
+  });
+};
+
+defineExpose({ open });
+</script>
+
+<style scoped></style>
+
diff --git a/src/views/equipmentManagement/repair/Modal/MaintainModal.vue b/src/views/equipmentManagement/repair/Modal/MaintainModal.vue
index a578a58..7058a5a 100644
--- a/src/views/equipmentManagement/repair/Modal/MaintainModal.vue
+++ b/src/views/equipmentManagement/repair/Modal/MaintainModal.vue
@@ -1,53 +1,116 @@
 <template>
-  <el-dialog v-model="visible" :title="modalOptions.title" direction="ltr" draggable>
-    <MaintainForm ref="maintainFormRef" />
-    <template #footer>
-			<el-button type="primary" @click="sendForm" :loading="loading">
-				{{ modalOptions.confirmText }}
-			</el-button>
-      <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
-    </template>
-  </el-dialog>
+  <FormDialog
+    v-model="visible"
+    :title="'璁惧缁翠慨'"
+    width="500px"
+    @confirm="sendForm"
+    @cancel="handleCancel"
+    @close="handleClose"
+  >
+    <el-form :model="form" :rules="rules" label-width="110px" ref="formRef">
+      <el-form-item label="缁翠慨浜�" prop="maintenanceName">
+        <el-input v-model="form.maintenanceName" placeholder="璇疯緭鍏ョ淮淇汉" />
+      </el-form-item>
+      <el-form-item label="缁翠慨缁撴灉" prop="maintenanceResult">
+        <el-input v-model="form.maintenanceResult" placeholder="璇疯緭鍏ョ淮淇粨鏋�" />
+      </el-form-item>
+			<el-form-item label="鏈缁翠慨閲戦" prop="repairPrice">
+				<el-input-number v-model="form.repairPrice" :min="0" :precision="2" style="width: 100%" />
+			</el-form-item>
+      <el-form-item label="缁翠慨鏃ユ湡" prop="maintenanceTime">
+        <el-date-picker
+          v-model="form.maintenanceTime"
+          placeholder="璇烽�夋嫨缁翠慨鏃ユ湡"
+          format="YYYY-MM-DD HH:mm:ss"
+          value-format="YYYY-MM-DD HH:mm:ss"
+          type="datetime"
+          clearable
+          style="width: 100%"
+        />
+      </el-form-item>
+    </el-form>
+  </FormDialog>
 </template>
 
 <script setup>
-import { useModal } from "@/hooks/useModal";
-import MaintainForm from "../Form/MaintainForm.vue";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
 import { addMaintain } from "@/api/equipmentManagement/repair";
+import useFormData from "@/hooks/useFormData";
+import useUserStore from "@/store/modules/user";
+import dayjs from "dayjs";
+import { ElMessage } from "element-plus";
 
 defineOptions({
   name: "缁翠慨妯℃�佹",
 });
 
-const maintainFormRef = ref();
 const emits = defineEmits(["ok"]);
 
-const {
-  id,
-  visible,
-  loading,
-  openModal,
-  modalOptions,
-  handleConfirm,
-  closeModal,
-} = useModal({ title: "璁惧缁翠慨" });
+// 淇濆瓨鎶ヤ慨璁板綍鐨刬d
+const repairId = ref();
+const visible = ref(false);
+const loading = ref(false);
+const formRef = ref();
+
+const userStore = useUserStore();
+const { form, resetForm } = useFormData({
+  maintenanceName: undefined, // 缁翠慨鍚嶇О
+  maintenanceResult: undefined, // 缁翠慨缁撴灉
+  maintenanceTime: undefined, // 缁翠慨鏃ユ湡
+	repairPrice: undefined, // 缁翠慨閲戦
+  status: 0,
+});
+
+const rules = {
+  maintenanceName: [{ required: true, message: "璇疯緭鍏ョ淮淇汉", trigger: "blur" }],
+  maintenanceResult: [{ required: true, message: "璇疯緭鍏ョ淮淇粨鏋�", trigger: "blur" }],
+  repairPrice: [{ required: true, message: "璇疯緭鍏ユ湰娆$淮淇噾棰�", trigger: "change" }],
+  maintenanceTime: [{ required: true, message: "璇烽�夋嫨缁翠慨鏃ユ湡", trigger: "change" }],
+};
+
+const setForm = (data) => {
+  form.maintenanceName = data.maintenanceName ?? userStore.nickName;
+  form.maintenanceResult = data.maintenanceResult;
+  form.maintenanceTime =
+    data.maintenanceTime 
+      ? dayjs(data.maintenanceTime).format("YYYY-MM-DD HH:mm:ss")
+      : dayjs().format("YYYY-MM-DD HH:mm:ss");
+  form.status = 2; // 缁翠慨鍚庡浐瀹氳繘鍏ュ緟瀹℃牳锛堜笉鍦ㄧ晫闈㈠睍绀猴級
+};
 
 const sendForm = async () => {
-  loading.value = true;
-  const form = await maintainFormRef.value.getForm();
-  const { code } = await addMaintain({ id: id.value, ...form });
-  if (code == 200) {
-    emits("ok");
-    maintainFormRef.value.resetForm();
-    closeModal();
-  }
-  loading.value = false;
+	await formRef.value.validate(async (valid) => {
+		if (!valid) return;
+		loading.value = true;
+		try {
+			const { code } = await addMaintain({ id: repairId.value, ...form });
+			if (code == 200) {
+				ElMessage.success("缁翠慨鎴愬姛");
+				emits("ok");
+				resetForm();
+				visible.value = false;
+			}
+		} finally {
+			loading.value = false;
+		}
+	})
+};
+
+const handleCancel = () => {
+  resetForm();
+  visible.value = false;
+};
+
+const handleClose = () => {
+  resetForm();
+  visible.value = false;
 };
 
 const open = async (id, row) => {
-  openModal(id);
+  repairId.value = id; // 淇濆瓨鎶ヤ慨璁板綍鐨刬d
+  visible.value = true;
   await nextTick();
-  maintainFormRef.value.setForm(row);
+  setForm(row);
 };
 
 defineExpose({
diff --git a/src/views/equipmentManagement/repair/Modal/RepairModal.vue b/src/views/equipmentManagement/repair/Modal/RepairModal.vue
index e89b0ac..20c9c8d 100644
--- a/src/views/equipmentManagement/repair/Modal/RepairModal.vue
+++ b/src/views/equipmentManagement/repair/Modal/RepairModal.vue
@@ -1,24 +1,113 @@
 <template>
-  <el-dialog v-model="visible" :title="modalOptions.title" @close="close" draggable>
-    <RepairForm ref="repairFormRef" :id="id" />
-    <template #footer>
-			<el-button type="primary" @click="sendForm" :loading="loading">
-				{{ modalOptions.confirmText }}
-			</el-button>
-      <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
-    </template>
-  </el-dialog>
+  <FormDialog
+    v-model="visible"
+    :title="id ? '缂栬緫璁惧鎶ヤ慨' : '鏂板璁惧鎶ヤ慨'"
+    width="800px"
+    @confirm="sendForm"
+    @cancel="handleCancel"
+    @close="handleClose"
+  >
+    <el-form :model="form" :rules="rules" label-width="100px" ref="formRef">
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="璁惧鍚嶇О">
+            <el-select v-model="form.deviceLedgerId" @change="setDeviceModel" filterable>
+              <el-option
+                v-for="(item, index) in deviceOptions"
+                :key="index"
+                :label="item.deviceName"
+                :value="item.id"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="瑙勬牸鍨嬪彿">
+            <el-input
+              v-model="form.deviceModel"
+              placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
+              disabled
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="鎶ヤ慨鏃ユ湡">
+            <el-date-picker
+              v-model="form.repairTime"
+              placeholder="璇烽�夋嫨鎶ヤ慨鏃ユ湡"
+              format="YYYY-MM-DD"
+              value-format="YYYY-MM-DD"
+              type="date"
+              clearable
+              style="width: 100%"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="鎶ヤ慨浜�">
+            <el-input v-model="form.repairName" placeholder="璇疯緭鍏ユ姤淇汉" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="瀹℃壒浜�" prop="auditName">
+            <el-select
+              v-model="form.auditName"
+              placeholder="璇烽�夋嫨瀹℃壒浜�"
+              filterable
+              clearable
+              style="width: 100%"
+            >
+              <el-option
+                v-for="user in userOptions"
+                :key="user.userId"
+                :label="user.nickName"
+                :value="user.nickName"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row v-if="id">
+        <el-col :span="12">
+          <el-form-item label="鎶ヤ慨鐘舵��">
+            <el-select v-model="form.status">
+              <el-option label="寰呯淮淇�" :value="0"></el-option>
+              <el-option label="瀹岀粨" :value="1"></el-option>
+              <el-option label="寰呭鏍�" :value="2"></el-option>
+              <el-option label="瀹℃牳涓嶉�氳繃" :value="3"></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="24">
+          <el-form-item label="鏁呴殰鐜拌薄">
+            <el-input
+              v-model="form.remark"
+              :rows="2"
+              type="textarea"
+              placeholder="璇疯緭鍏ユ晠闅滅幇璞�"
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+  </FormDialog>
 </template>
 
 <script setup>
-import { useModal } from "@/hooks/useModal";
-import RepairForm from "../Form/RepairForm.vue";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
 import {
   addRepair,
   editRepair,
   getRepairById,
 } from "@/api/equipmentManagement/repair";
 import { ElMessage } from "element-plus";
+import dayjs from "dayjs";
+import useFormData from "@/hooks/useFormData";
+import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
+import useUserStore from "@/store/modules/user";
+import { userListNoPageByTenantId } from "@/api/system/user";
 
 defineOptions({
   name: "璁惧鎶ヤ慨寮圭獥",
@@ -26,63 +115,101 @@
 
 const emits = defineEmits(["ok"]);
 
-const repairFormRef = ref();
-const {
-  id,
-  visible,
-  loading,
-  openModal,
-  modalOptions,
-  handleConfirm,
-  closeModal,
-} = useModal({ title: "璁惧鎶ヤ慨" });
+const id = ref();
+const visible = ref(false);
+const loading = ref(false);
+const formRef = ref();
+
+const userStore = useUserStore();
+const deviceOptions = ref([]);
+const userOptions = ref([]);
+
+const loadDeviceName = async () => {
+  const { data } = await getDeviceLedger();
+  deviceOptions.value = data;
+};
+
+const loadUserOptions = async () => {
+  const res = await userListNoPageByTenantId();
+  userOptions.value = res?.data ?? [];
+};
+
+const { form, resetForm } = useFormData({
+  deviceLedgerId: undefined, // 璁惧Id
+  deviceName: undefined, // 璁惧鍚嶇О
+  deviceModel: undefined, // 瑙勬牸鍨嬪彿
+  repairTime: dayjs().format("YYYY-MM-DD"), // 鎶ヤ慨鏃ユ湡锛岄粯璁ゅ綋澶�
+  repairName: userStore.nickName, // 鎶ヤ慨浜�
+  auditName: undefined, // 瀹℃壒浜�
+  remark: undefined, // 鏁呴殰鐜拌薄
+  status: 0, // 鎶ヤ慨鐘舵��
+});
+
+const rules = {
+  auditName: [
+    { required: true, message: "璇烽�夋嫨瀹℃壒浜�", trigger: "change" },
+  ],
+};
+
+const setDeviceModel = (deviceId) => {
+  const option = deviceOptions.value.find((item) => item.id === deviceId);
+  form.deviceModel = option.deviceModel;
+};
+
+const setForm = (data) => {
+  form.deviceLedgerId = data.deviceLedgerId;
+  form.deviceName = data.deviceName;
+  form.deviceModel = data.deviceModel;
+  form.repairTime = data.repairTime;
+  form.repairName = data.repairName;
+  form.auditName = data.auditName;
+  form.remark = data.remark;
+  form.status = data.status;
+};
 
 const sendForm = async () => {
-  try {
-    // 寮�濮嬪姞杞�
+  await formRef.value?.validate(async (valid) => {
+    if (!valid) return;
     loading.value = true;
-    // 鎻愪氦琛ㄥ崟骞惰幏鍙栨牎楠岀粨鏋�
-    const submitStatus = await repairFormRef.value.submitForm();
-    if (!submitStatus) {
-      // 濡傛灉琛ㄥ崟楠岃瘉澶辫触锛屽彇娑堝姞杞界姸鎬�
-      loading.value = false;
-      return;
-    }
-    // 鑾峰彇琛ㄥ崟鏁版嵁
-    const form = await repairFormRef.value.getForm();
-    // 鏍规嵁鏄惁鏈塈D鍐冲畾鏄紪杈戣繕鏄柊澧�
-    const { code } = id.value
+    try {
+      const { code } = id.value
         ? await editRepair({ id: unref(id), ...form })
         : await addRepair(form);
-    if (code === 200) {
-      ElMessage.success(`${id ? "缂栬緫" : "鏂板"}鎶ヤ慨鎴愬姛`);
-      emits("ok");
+      if (code == 200) {
+        ElMessage.success(`${id.value ? "缂栬緫" : "鏂板"}鎶ヤ慨鎴愬姛`);
+        visible.value = false;
+        emits("ok");
+      }
+    } finally {
+      loading.value = false;
     }
-  } catch (error) {
-  } finally {
-    // 鏃犺鎴愬姛杩樻槸澶辫触锛岄兘鍙栨秷鍔犺浇鐘舵��
-    loading.value = false;
-    closeModal();
-  }
+  });
+};
+
+const handleCancel = () => {
+  resetForm();
+  visible.value = false;
+};
+
+const handleClose = () => {
+  resetForm();
+  visible.value = false;
 };
 
 const openAdd = async () => {
-  openModal();
+  id.value = undefined;
+  visible.value = true;
   await nextTick();
-  await repairFormRef.value.loadDeviceName();
+  await Promise.all([loadDeviceName(), loadUserOptions()]);
 };
 
-const openEdit = async (id) => {
-  const { data } = await getRepairById(id);
-  openModal(id);
+const openEdit = async (editId) => {
+  const { data } = await getRepairById(editId);
+  id.value = editId;
+  visible.value = true;
   await nextTick();
-  await repairFormRef.value.loadDeviceName();
-  await repairFormRef.value.setForm(data);
-};
-
-const close = () => {
-  repairFormRef.value.resetForm();
-  closeModal();
+  await Promise.all([loadDeviceName(), loadUserOptions()]);
+  setForm(data);
 };
 
 defineExpose({
@@ -90,3 +217,5 @@
   openEdit,
 });
 </script>
+
+<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/repair/index.vue b/src/views/equipmentManagement/repair/index.vue
index de7f850..35391e0 100644
--- a/src/views/equipmentManagement/repair/index.vue
+++ b/src/views/equipmentManagement/repair/index.vue
@@ -7,7 +7,6 @@
             style="width: 240px"
             placeholder="璇疯緭鍏ヨ澶囧悕绉�"
             clearable
-            :prefix-icon="Search"
             @change="getTableData"
         />
       </el-form-item>
@@ -15,9 +14,8 @@
         <el-input
             v-model="filters.deviceModel"
             style="width: 240px"
-            placeholder="璇烽�夋嫨瑙勬牸鍨嬪彿"
+            placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
             clearable
-            :prefix-icon="Search"
             @change="getTableData"
         />
       </el-form-item>
@@ -27,7 +25,6 @@
             style="width: 240px"
             placeholder="璇疯緭鍏ユ晠闅滅幇璞�"
             clearable
-            :prefix-icon="Search"
             @change="getTableData"
         />
       </el-form-item>
@@ -37,7 +34,6 @@
             style="width: 240px"
             placeholder="璇疯緭鍏ョ淮淇汉"
             clearable
-            :prefix-icon="Search"
             @change="getTableData"
         />
       </el-form-item>
@@ -68,15 +64,6 @@
       <div class="actions">
         <el-text class="mx-1" size="large">璁惧鎶ヤ慨</el-text>
         <div>
-          <el-button
-            type="primary"
-            icon="Plus"
-            :disabled="multipleList.length !== 1 || multipleList[0]?.status !== 1"
-            @click="addMaintain"
-          >
-
-            鏂板缁翠慨
-          </el-button>
           <el-button type="success" icon="Van" @click="addRepair">
             鏂板鎶ヤ慨
           </el-button>
@@ -86,79 +73,94 @@
           <el-button
             type="danger"
             icon="Delete"
-            :disabled="multipleList.length <= 0"
-            @click="delRepairByIds(multipleList)"
+            :disabled="multipleList.length <= 0 || hasFinishedStatus"
+            @click="delRepairByIds(multipleList.map((item) => item.id))"
           >
             鎵归噺鍒犻櫎
           </el-button>
         </div>
       </div>
       <PIMTable
-        rowKey="id"
-        isSelection
-        :column="columns"
-        :tableData="dataList"
-        :page="{
+          rowKey="id"
+          isSelection
+          :column="columns"
+          :tableData="dataList"
+          :page="{
           current: pagination.currentPage,
           size: pagination.pageSize,
           total: pagination.total,
         }"
-        @selection-change="handleSelectionChange"
-        @pagination="changePage"
+          @selection-change="handleSelectionChange"
+          @pagination="changePage"
       >
         <template #statusRef="{ row }">
-          <el-tag v-if="row.status === 5" type="danger">缁翠慨澶辫触</el-tag>
-          <el-tag v-if="row.status === 4" type="danger">缁翠慨鎴愬姛</el-tag>
-          <el-tag v-if="row.status === 3" type="danger">缁翠慨涓�</el-tag>
-          <el-tag v-if="row.status === 2" type="danger">瀹℃牳澶辫触</el-tag>
-          <el-tag v-if="row.status === 1" type="success">瀹℃牳閫氳繃</el-tag>
-          <el-tag v-if="row.status === 0" type="warning">瀹℃牳涓�</el-tag>
+          <el-tag v-if="row.status === 0" type="warning">寰呯淮淇�</el-tag>
+          <el-tag v-else-if="row.status === 1" type="success">瀹岀粨</el-tag>
+          <el-tag v-else-if="row.status === 2" type="info">寰呭鏍�</el-tag>
+          <el-tag v-else-if="row.status === 3" type="danger">瀹℃牳涓嶉�氳繃</el-tag>
         </template>
         <template #operation="{ row }">
           <el-button
             type="primary"
-            text
-            icon="editPen"
+            link
+            :disabled="row.status === 1"
             @click="editRepair(row.id)"
-            :disabled="row.status !== 0"
           >
             缂栬緫
           </el-button>
           <el-button
-            type="danger"
-            text
-            icon="delete"
-            @click="delRepairByIds(row)"
+            type="warning"
+            link
+            :disabled="row.status !== 2"
+            @click="openApprove(row.id)"
+          >
+            瀹℃壒
+          </el-button>
+          <el-button
+            type="success"
+            link
             :disabled="row.status !== 0"
+            @click="addMaintain(row)"
+          >
+            缁翠慨
+          </el-button>
+          <el-button
+            type="danger"
+            link
+            :disabled="row.status === 1"
+            @click="delRepairByIds(row.id)"
           >
             鍒犻櫎
           </el-button>
         </template>
       </PIMTable>
     </div>
-    <RepairModal ref="repairModalRef" @ok="getTableData" />
-    <MaintainModal ref="maintainModalRef" @ok="getTableData" />
+    <RepairModal ref="repairModalRef" @ok="getTableData"/>
+    <MaintainModal ref="maintainModalRef" @ok="getTableData"/>
+    <ApproveModal ref="approveModalRef" @ok="getTableData"/>
   </div>
 </template>
 
 <script setup>
-import { usePaginationApi } from "@/hooks/usePaginationApi";
-import { getRepairPage, delRepair } from "@/api/equipmentManagement/repair";
-import { onMounted, getCurrentInstance } from "vue";
+import { onMounted, getCurrentInstance, computed } from "vue";
+import {usePaginationApi} from "@/hooks/usePaginationApi";
+import {getRepairPage, delRepair} from "@/api/equipmentManagement/repair";
 import RepairModal from "./Modal/RepairModal.vue";
-import { ElMessageBox, ElMessage } from "element-plus";
+import {ElMessageBox, ElMessage} from "element-plus";
 import dayjs from "dayjs";
 import MaintainModal from "./Modal/MaintainModal.vue";
+import ApproveModal from "./Modal/ApproveModal.vue";
 
 defineOptions({
   name: "璁惧鎶ヤ慨",
 });
 
-const { proxy } = getCurrentInstance();
+const {proxy} = getCurrentInstance();
 
 // 妯℃�佹瀹炰緥
 const repairModalRef = ref();
 const maintainModalRef = ref();
+const approveModalRef = ref();
 
 // 琛ㄦ牸澶氶�夋閫変腑椤�
 const multipleList = ref([]);
@@ -173,85 +175,87 @@
   resetFilters,
   onCurrentChange,
 } = usePaginationApi(
-  getRepairPage,
-  {
-    deviceName: undefined,
-    deviceModel: undefined,
-    remark: undefined,
-    maintenanceName: undefined,
-    repairTimeStr: undefined,
-    maintenanceTimeStr: undefined,
-  },
-  [
+    getRepairPage,
     {
-      label: "璁惧鍚嶇О",
-      align: "center",
-      prop: "deviceName",
+      deviceName: undefined,
+      deviceModel: undefined,
+      remark: undefined,
+      maintenanceName: undefined,
+      repairTimeStr: undefined,
+      maintenanceTimeStr: undefined,
     },
-    {
-      label: "瑙勬牸鍨嬪彿",
-      align: "center",
-      prop: "deviceModel",
-    },
-    {
-      label: "鎶ヤ慨鏃ユ湡",
-      align: "center",
-      prop: "repairTime",
-      formatData: (cell) => dayjs(cell).format("YYYY-MM-DD"),
-    },
-    {
-      label: "鎶ヤ慨浜�",
-      align: "center",
-      prop: "repairName",
-    },
-    {
-      label: "鏁呴殰鐜拌薄",
-      align: "center",
-      prop: "remark",
-    },
-    {
-      label: "缁翠慨浜�",
-      align: "center",
-      prop: "maintenanceName",
-    },
-    {
-      label: "缁翠慨缁撴灉",
-      align: "center",
-      prop: "maintenanceResult",
-    },
-    {
-      label: "缁翠慨鏃ユ湡",
-      align: "center",
-      prop: "maintenanceTime",
-      formatData: (cell) => (cell ? dayjs(cell).format("YYYY-MM-DD") : ""),
-    },
-    {
-      label: "鐘舵��",
-      align: "center",
-      prop: "status",
-      dataType: "slot",
-      slot: "statusRef",
-    },
-    {
-      fixed: "right",
-      label: "鎿嶄綔",
-      dataType: "slot",
-      slot: "operation",
-      align: "center",
-      width: "200px",
-    },
-  ]
+    [
+      {
+        label: "璁惧鍚嶇О",
+        align: "center",
+        prop: "deviceName",
+      },
+      {
+        label: "瑙勬牸鍨嬪彿",
+        align: "center",
+        prop: "deviceModel",
+      },
+      {
+        label: "鎶ヤ慨鏃ユ湡",
+        align: "center",
+        prop: "repairTime",
+        formatData: (cell) => dayjs(cell).format("YYYY-MM-DD"),
+      },
+      {
+        label: "鎶ヤ慨浜�",
+        align: "center",
+        prop: "repairName",
+      },
+      {
+        label: "鏁呴殰鐜拌薄",
+        align: "center",
+        prop: "remark",
+      },
+      {
+        label: "缁翠慨浜�",
+        align: "center",
+        prop: "maintenanceName",
+      },
+      {
+        label: "缁翠慨缁撴灉",
+        align: "center",
+        prop: "maintenanceResult",
+      },
+      {
+        label: "缁翠慨鏃ユ湡",
+        align: "center",
+        prop: "maintenanceTime",
+        formatData: (cell) => (cell ? dayjs(cell).format("YYYY-MM-DD") : ""),
+      },
+      { prop: "auditName", label: "瀹℃牳浜�", width: 120 },
+	{ prop: "supervisoryName", label: "鐩戠潱浜�", width: 120 },
+      {
+        label: "鐘舵��",
+        align: "center",
+        prop: "status",
+        dataType: "slot",
+        slot: "statusRef",
+      },
+      {
+        fixed: "right",
+        label: "鎿嶄綔",
+        dataType: "slot",
+        slot: "operation",
+        align: "center",
+        width: "300px",
+      },
+    ]
 );
 
 // type === 1 缁翠慨 2鎶ヤ慨闂�
-const handleDateChange = (value,type) => {
+const handleDateChange = (value, type) => {
   filters.maintenanceTimeStr = null
   filters.c = null
-  if(type === 1){
+  if (type === 1) {
     if (value) {
       filters.maintenanceTimeStr = dayjs(value).format("YYYY-MM-DD");
     }
-  }else{
+  } else {
     if (value) {
       filters.repairTimeStr = dayjs(value).format("YYYY-MM-DD");
     }
@@ -264,6 +268,11 @@
   multipleList.value = selectionList;
 };
 
+// 妫�鏌ラ�変腑鐨勮褰曚腑鏄惁鏈夊畬缁撶姸鎬佺殑
+const hasFinishedStatus = computed(() => {
+  return multipleList.value.some(item => item.status === 1)
+})
+
 // 鏂板鎶ヤ慨
 const addRepair = () => {
   repairModalRef.value.openAdd();
@@ -275,36 +284,33 @@
 };
 
 // 鏂板缁翠慨
-const addMaintain = () => {
-
-  const row = multipleList.value[0];
+const addMaintain = (row) => {
   maintainModalRef.value.open(row.id, row);
 };
 
-const changePage = ({ page, limit }) => {
-	pagination.currentPage = page;
-	pagination.pageSize = limit;
-	onCurrentChange(page);
+// 瀹℃壒
+const openApprove = (id) => {
+  approveModalRef.value.open(id);
+};
+
+const changePage = ({page, limit}) => {
+  pagination.currentPage = page;
+  pagination.pageSize = limit;
+  onCurrentChange(page);
 };
 
 // 鍗曡鍒犻櫎
 const delRepairByIds = async (ids) => {
-  let isDel = false
-  if(Array.isArray(ids)){
-    ids.forEach((item)=>{
-      if(item.status !== 0){
-        isDel = true
-      }
-    })
-  }else{
-    if(ids.status !== 0){
-      isDel = true
-    }
-  }
+  // 妫�鏌ユ槸鍚︽湁瀹岀粨鐘舵�佺殑璁板綍
+  const idsArray = Array.isArray(ids) ? ids : [ids];
+  const hasFinished = idsArray.some(id => {
+    const record = dataList.value.find(item => item.id === id);
+    return record && record.status === 1;
+  });
 
-  if(isDel){
-    ElMessage.warning("鍙兘鍒犻櫎瀹℃牳涓殑鎶ヤ慨鏁版嵁");
-    return
+  if (hasFinished) {
+    ElMessage.warning('涓嶈兘鍒犻櫎鐘舵�佷负瀹岀粨鐨勮褰�');
+    return;
   }
 
   ElMessageBox.confirm("纭鍒犻櫎鎶ヤ慨鏁版嵁, 姝ゆ搷浣滀笉鍙��?", "璀﹀憡", {
@@ -312,17 +318,10 @@
     cancelButtonText: "鍙栨秷",
     type: "warning",
   }).then(async () => {
-    let idsList = ""
-    if(Array.isArray(ids)){
-      idsList = multipleList.value.map((item) => item.id);
-      console.log(idsList)
-    }else{
-      idsList = ids.id
-    }
-    const { code } = await delRepair(idsList);
+    const {code} = await delRepair(ids);
     if (code === 200) {
       ElMessage.success("鍒犻櫎鎴愬姛");
-      await getTableData();
+      getTableData();
     }
   });
 };
@@ -334,12 +333,12 @@
     cancelButtonText: "鍙栨秷",
     type: "warning",
   })
-    .then(() => {
-      proxy.download("/device/repair/export", {}, "璁惧鎶ヤ慨.xlsx");
-    })
-    .catch(() => {
-      ElMessage.info("宸插彇娑�");
-    });
+      .then(() => {
+        proxy.download("/device/repair/export", {}, "璁惧鎶ヤ慨.xlsx");
+      })
+      .catch(() => {
+        ElMessage.info("宸插彇娑�");
+      });
 };
 
 onMounted(() => {
@@ -351,6 +350,7 @@
 .table_list {
   margin-top: unset;
 }
+
 .actions {
   display: flex;
   justify-content: space-between;
diff --git a/src/views/equipmentManagement/spareParts/index.vue b/src/views/equipmentManagement/spareParts/index.vue
index f18c84c..4a48d28 100644
--- a/src/views/equipmentManagement/spareParts/index.vue
+++ b/src/views/equipmentManagement/spareParts/index.vue
@@ -19,47 +19,21 @@
 				<el-button type="primary" @click="addCategory" >鏂板</el-button>
 			</div>
 		</div>
+
+    <PIMTable
+        rowKey="id"
+        :column="columns"
+        :tableData="renderTableData"
+        :tableLoading="loading"
+        :page="pagination"
+        :isShowPagination="true"
+        @pagination="handleSizeChange"
+    >
+      <template #status="{ row }">
+        <el-tag type="success" size="small">{{ row.status }}</el-tag>
+      </template>
+    </PIMTable>
     
-    <div class="table_list">
-      <el-table
-        v-loading="loading"
-        :data="renderTableData"
-        style="width: 100%; margin-top: 10px;"
-        border
-        row-key="id"
-      >
-      <el-table-column prop="deviceNameStr" label="璁惧鍚嶇О"  width="300"></el-table-column>
-        <el-table-column prop="name" label="澶囦欢鍚嶇О" width="200"></el-table-column>
-        <el-table-column prop="sparePartsNo" label="澶囦欢缂栧彿" width="200"></el-table-column>
-        <el-table-column prop="status" label="鐘舵��" width="100">
-          <template #default="{ row }">
-            <el-tag type="success" size="small">{{ row.status }}</el-tag>
-          </template>
-        </el-table-column>
-        <el-table-column prop="price" label="浠锋牸" width="140"></el-table-column>
-        <el-table-column prop="description" label="鎻忚堪" width="150"></el-table-column>
-        <el-table-column label="鎿嶄綔" width="150" fixed="right" align="center">
-          <template #default="{ row }">
-            <el-button
-              link
-							type="primary"
-              @click="() => editCategory(row)"
-              :disabled="loading"
-            >
-              缂栬緫
-            </el-button>
-            <el-button
-							link
-              @click="() => deleteCategory(row.id)"
-              style="color: #f56c6c;"
-              :disabled="loading"
-            >
-              鍒犻櫎
-            </el-button>
-          </template>
-        </el-table-column>
-      </el-table>
-    </div>
     <el-dialog title="鍒嗙被绠$悊" v-model="dialogVisible" width="60%">
       <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
         <el-form-item label="璁惧" prop="deviceLedgerIds">
@@ -85,6 +59,9 @@
         </el-form-item>
         <el-form-item label="澶囦欢缂栧彿" prop="sparePartsNo">
           <el-input v-model="form.sparePartsNo"></el-input>
+        </el-form-item>
+        <el-form-item label="鏁伴噺" prop="quantity">
+          <el-input type="number" v-model="form.quantity"></el-input>
         </el-form-item>
         <el-form-item label="鐘舵��" prop="status">
           <el-select v-model="form.status" placeholder="璇烽�夋嫨鐘舵��">
@@ -143,6 +120,66 @@
 const queryParams = reactive({
   name: ''
 });
+// 鍒嗛〉鍙傛暟
+const pagination = reactive({
+  current: 1,
+  size: 10,
+  total: 0
+});
+const columns = ref([
+  {
+    label: "璁惧鍚嶇О",
+    prop: "deviceNameStr",
+  },
+  {
+    label: "澶囦欢鍚嶇О",
+    prop: "name",
+  },
+  {
+    label: "澶囦欢缂栧彿",
+    prop: "sparePartsNo",
+  },
+  {
+    label: "鐘舵��",
+    prop: "status",
+    slot: "status",
+    dataType: "slot",
+  },
+  {
+    label: "浠锋牸",
+    prop: "price",
+  },
+  {
+    label: "鏁伴噺",
+    prop: "quantity",
+  },
+  {
+    label: "鎻忚堪",
+    prop: "description",
+  },
+  {
+    label: "鎿嶄綔",
+    prop: "operation",
+    width: 150,
+    fixed: 'right',
+    align: "center",
+    dataType: "action",
+    operation: [
+      {
+        name: "缂栬緫",
+        clickFun: (row) => {
+          editCategory(row)
+        },
+      },
+      {
+        name: "鍒犻櫎",
+        clickFun: (row) => {
+          deleteCategory(row.id)
+        },
+      },
+    ],
+  },
+]);
 // 琛ㄥ崟鏁版嵁
 const form = reactive({
   id:'',
@@ -161,6 +198,9 @@
   ],
   sparePartsNo: [
     { required: true, message: '璇疯緭鍏ュ浠剁紪鍙�', trigger: 'blur' }
+  ],
+  quantity:[
+    { required: true, message: '璇疯緭鍏ユ暟閲�', trigger: 'blur' }
   ],
   status: [
     { required: true, message: '璇烽�夋嫨鐘舵��', trigger: 'change' }
@@ -208,7 +248,10 @@
 const fetchListData = async () => {
   loading.value = true;
   try {
-    const params = {};
+    const params = {
+      current: pagination.current,
+      size: pagination.size
+    };
     if (queryParams.name) {
       params.name = queryParams.name;
     }
@@ -216,6 +259,7 @@
     if (res.code === 200) {
       renderTableData.value = res.data.records || [];
       categories.value = res.data.records || [];
+      pagination.total = res.data.total || 0;
     }
   } catch (error) {
 		loading.value = false;
@@ -226,12 +270,27 @@
 
 // 鏌ヨ
 const handleQuery = () => {
+  pagination.current = 1;
   fetchListData();
 }
 
 // 閲嶇疆鏌ヨ
 const resetQuery = () => {
   queryParams.name = '';
+  pagination.current = 1;
+  fetchListData();
+}
+
+// 鍒嗛〉澶у皬鏀瑰彉
+const handleSizeChange = (size) => {
+  pagination.size = size;
+  pagination.current = 1;
+  fetchListData();
+}
+
+// 褰撳墠椤垫敼鍙�
+const handleCurrentChange = (current) => {
+  pagination.current = current;
   fetchListData();
 }
 
@@ -254,6 +313,7 @@
   form.status = '';
   form.description = '';
   form.deviceLedgerIds = [];
+  form.quantity = undefined;
   form.price = null;
   operationType.value = 'add'
   dialogVisible.value = true;
@@ -366,6 +426,13 @@
   margin-top: unset;
 }
 
+.pagination-container {
+  margin-top: 20px;
+  display: flex;
+  justify-content: flex-end;
+  padding: 16px 0;
+}
+
 .el-table__header-wrapper th {
   background-color: #f5f7fa;
   font-weight: 600;
diff --git a/src/views/equipmentManagement/upkeep/Form/ApproveModal.vue b/src/views/equipmentManagement/upkeep/Form/ApproveModal.vue
new file mode 100644
index 0000000..c7a9329
--- /dev/null
+++ b/src/views/equipmentManagement/upkeep/Form/ApproveModal.vue
@@ -0,0 +1,144 @@
+<template>
+  <FormDialog
+    v-model="visible"
+    title="瀹氭椂浠诲姟瀹℃壒"
+    width="800px"
+    @confirm="handleSubmit"
+    @cancel="handleClose"
+    @close="handleClose"
+  >
+    <el-descriptions :column="2" border>
+      <el-descriptions-item label="浠诲姟鍚嶇О">
+        {{ detail.taskName || "-" }}
+      </el-descriptions-item>
+      <el-descriptions-item label="瑙勬牸鍨嬪彿">
+        {{ detail.deviceModel || "-" }}
+      </el-descriptions-item>
+      <el-descriptions-item label="棰戞">
+        {{ frequencyText(detail.frequencyType) }}
+      </el-descriptions-item>
+      <el-descriptions-item label="寮�濮嬫棩鏈熶笌鏃堕棿">
+        {{ detail.frequencyDetail || "-" }}
+      </el-descriptions-item>
+      <el-descriptions-item label="鐧昏浜�">
+        {{ detail.registrant || "-" }}
+      </el-descriptions-item>
+      <el-descriptions-item label="鐧昏鏃ユ湡">
+        {{ detail.registrationDate || "-" }}
+      </el-descriptions-item>
+      <el-descriptions-item label="褰撳墠鐘舵��">
+        {{ statusText(detail.status) }}
+      </el-descriptions-item>
+      <el-descriptions-item label="澶囨敞" :span="2">
+        {{ detail.remarks || "-" }}
+      </el-descriptions-item>
+    </el-descriptions>
+    <div style="margin-top: 16px">
+      <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
+        <el-form-item label="瀹℃壒缁撴灉" prop="decision">
+          <el-radio-group v-model="form.decision">
+            <el-radio label="瀹℃牳閫氳繃">瀹℃牳閫氳繃</el-radio>
+            <el-radio label="瀹℃牳涓嶉�氳繃">瀹℃牳涓嶉�氳繃</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="鐩戠潱浜�" prop="supervisoryName">
+          <el-input v-model="form.supervisoryName" placeholder="璇疯緭鍏ョ洃鐫d汉" clearable style="width: 100%" />
+        </el-form-item>
+      </el-form>
+    </div>
+  </FormDialog>
+</template>
+
+<script setup>
+import { nextTick, ref } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
+import { deviceMaintenanceTaskEdit } from "@/api/equipmentManagement/upkeep";
+
+defineOptions({
+  name: "瀹氭椂浠诲姟瀹℃壒寮圭獥",
+});
+
+const emits = defineEmits(["ok"]);
+
+const visible = ref(false);
+const loading = ref(false);
+const detail = ref({});
+const formRef = ref();
+const form = ref({
+  decision: undefined, // 瀹℃牳閫氳繃 / 瀹℃牳涓嶉�氳繃
+  supervisoryName: undefined, // 鐩戠潱浜�
+});
+
+const rules = {
+  decision: [{ required: true, message: "璇烽�夋嫨瀹℃壒缁撴灉", trigger: "change" }],
+  supervisoryName: [{ required: true, message: "璇烽�夋嫨鐩戠潱浜�", trigger: "change" }],
+};
+
+const statusText = (status) => status || "-";
+
+const frequencyText = (type) => {
+  const map = {
+    DAILY: "姣忔棩",
+    WEEKLY: "姣忓懆",
+    MONTHLY: "姣忔湀",
+    QUARTERLY: "瀛e害",
+  };
+  return map[type] ?? "-";
+};
+
+const open = async (row) => {
+  detail.value = { ...(row || {}) };
+  visible.value = true;
+  await nextTick();
+  form.value.decision = undefined;
+  form.value.supervisoryName = undefined;
+};
+
+const handleClose = () => {
+  visible.value = false;
+  detail.value = {};
+  form.value.decision = undefined;
+  form.value.supervisoryName = undefined;
+};
+
+const updateStatus = async (status) => {
+  loading.value = true;
+  try {
+    const payload = { ...(detail.value || {}), status, supervisoryName: form.value.supervisoryName };
+    const { code } = await deviceMaintenanceTaskEdit(payload);
+    if (code === 200) {
+      ElMessage.success("瀹℃壒鎴愬姛");
+      emits("ok");
+      handleClose();
+    }
+  } finally {
+    loading.value = false;
+  }
+};
+
+const handleSubmit = async () => {
+  if (detail.value?.status === "瀹℃牳閫氳繃") {
+    ElMessage.warning("瀹℃牳閫氳繃鍚庝笉鍙啀娆″鎵�");
+    return;
+  }
+  await formRef.value?.validate(async (valid) => {
+    if (!valid) return;
+    const isApprove = form.value.decision === "瀹℃牳閫氳繃";
+    ElMessageBox.confirm(
+      `纭瀹℃壒${isApprove ? "閫氳繃" : "涓嶉�氳繃"}锛焋,
+      "鎻愮ず",
+      {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning",
+      }
+    ).then(() => updateStatus(form.value.decision));
+  });
+};
+
+defineExpose({ open });
+</script>
+
+<style scoped></style>
+
diff --git a/src/views/equipmentManagement/upkeep/Form/MaintenanceForm.vue b/src/views/equipmentManagement/upkeep/Form/MaintenanceForm.vue
deleted file mode 100644
index 3aa0867..0000000
--- a/src/views/equipmentManagement/upkeep/Form/MaintenanceForm.vue
+++ /dev/null
@@ -1,77 +0,0 @@
-<template>
-  <el-form :model="form" label-width="100px">
-    <el-form-item label="瀹為檯淇濆吇浜�">
-      <el-input
-        v-model="form.maintenanceActuallyName"
-        placeholder="璇疯緭鍏ュ疄闄呬繚鍏讳汉"
-      ></el-input>
-    </el-form-item>
-    <el-form-item label="瀹為檯淇濆吇鏃ユ湡">
-      <el-date-picker
-        v-model="form.maintenanceActuallyTime"
-        placeholder="璇烽�夋嫨瀹為檯淇濆吇鏃ユ湡"
-        format="YYYY-MM-DD HH:mm:ss"
-        value-format="YYYY-MM-DD HH:mm:ss"
-        type="datetime"
-        clearable
-        style="width: 100%"
-      />
-    </el-form-item>
-    <el-form-item label="淇濆吇鐘舵��">
-      <el-select v-model="form.status">
-        <el-option label="寰呬繚鍏�" :value="0"></el-option>
-        <el-option label="瀹岀粨" :value="1"></el-option>
-        <el-option label="澶辫触" :value="2"></el-option>
-      </el-select>
-    </el-form-item>
-    <el-form-item label="淇濆吇缁撴灉">
-      <!-- <el-select v-model="form.maintenanceResult" placeholder="璇烽�夋嫨淇濆吇缁撴灉">
-        <el-option label="瀹屽ソ" :value="1"></el-option>
-        <el-option label="缁翠慨" :value="0"></el-option>
-      </el-select> -->
-      <el-input
-        v-model="form.maintenanceResult"
-        placeholder="璇疯緭鍏ヤ繚鍏荤粨鏋�"
-        type="text" />
-    </el-form-item>
-  </el-form>
-</template>
-
-<script setup>
-import useFormData from "@/hooks/useFormData";
-import dayjs from "dayjs";
-import useUserStore from "@/store/modules/user";
-
-defineOptions({
-  name: "淇濆吇琛ㄥ崟",
-});
-
-const userStore = useUserStore();
-const { form, resetForm } = useFormData({
-  maintenanceActuallyName: undefined, // 瀹為檯淇濆吇浜�
-  maintenanceActuallyTime: undefined, // 瀹為檯淇濆吇鏃ユ湡
-  maintenanceResult: undefined, // 淇濆吇缁撴灉
-  status: 0, // 淇濆吇鐘舵��
-});
-
-const setForm = (data) => {
-  form.maintenanceActuallyName =
-    data.maintenanceActuallyName ?? userStore.nickName;
-  form.maintenanceActuallyTime =
-    dayjs(data.maintenanceActuallyTime).format("YYYY-MM-DD HH:mm:ss") ??
-    dayjs().format("YYYY-MM-DD HH:mm:ss");
-  form.maintenanceResult = data.maintenanceResult;
-};
-
-const getForm = () => {
-  return form;
-};
-
-defineExpose({
-  getForm,
-  setForm,
-  resetForm,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue b/src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue
new file mode 100644
index 0000000..2951df7
--- /dev/null
+++ b/src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue
@@ -0,0 +1,146 @@
+<template>
+  <FormDialog
+    v-model="visible"
+    :title="'璁惧淇濆吇'"
+    width="500px"
+    @confirm="sendForm"
+    @cancel="handleCancel"
+    @close="handleClose"
+  >
+    <el-form :model="form" :rules="rules" label-width="120px" ref="formRef">
+      <el-form-item label="瀹為檯淇濆吇浜�" prop="maintenanceActuallyName">
+        <el-input
+          v-model="form.maintenanceActuallyName"
+          placeholder="璇疯緭鍏ュ疄闄呬繚鍏讳汉"
+        ></el-input>
+      </el-form-item>
+      <el-form-item label="瀹為檯淇濆吇鏃ユ湡" prop="maintenanceActuallyTime">
+        <el-date-picker
+          v-model="form.maintenanceActuallyTime"
+          placeholder="璇烽�夋嫨瀹為檯淇濆吇鏃ユ湡"
+          format="YYYY-MM-DD HH:mm:ss"
+          value-format="YYYY-MM-DD HH:mm:ss"
+          type="datetime"
+          clearable
+          style="width: 100%"
+        />
+      </el-form-item>
+      <el-form-item label="淇濆吇鐘舵��" prop="status">
+        <el-select v-model="form.status">
+          <el-option label="寰呬繚鍏�" :value="0"></el-option>
+          <el-option label="瀹岀粨" :value="1"></el-option>
+          <el-option label="澶辫触" :value="2"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="淇濆吇缁撴灉" prop="maintenanceResult">
+        <el-input
+          v-model="form.maintenanceResult"
+          placeholder="璇疯緭鍏ヤ繚鍏荤粨鏋�"
+          type="text" />
+      </el-form-item>
+			<el-form-item label="鏈淇濆吇閲戦" prop="maintenancePrice">
+				<el-input-number v-model="form.maintenancePrice" :min="0" :precision="2" style="width: 100%" />
+			</el-form-item>
+    </el-form>
+  </FormDialog>
+</template>
+
+<script setup>
+import FormDialog from "@/components/Dialog/FormDialog.vue";
+import { addMaintenance } from "@/api/equipmentManagement/upkeep";
+import useFormData from "@/hooks/useFormData";
+import dayjs from "dayjs";
+import useUserStore from "@/store/modules/user";
+import { ElMessage } from "element-plus";
+
+defineOptions({
+  name: "淇濆吇妯℃�佹",
+});
+
+const emits = defineEmits(["ok"]);
+
+// 淇濆瓨璁″垝淇濆吇璁板綍鐨刬d
+const planId = ref();
+const visible = ref(false);
+const loading = ref(false);
+const formRef = ref();
+const userStore = useUserStore();
+
+const { form, resetForm } = useFormData({
+  maintenanceActuallyName: undefined, // 瀹為檯淇濆吇浜�
+  maintenanceActuallyTime: undefined, // 瀹為檯淇濆吇鏃ユ湡
+  maintenanceResult: undefined, // 淇濆吇缁撴灉
+	maintenancePrice: undefined, // 淇濆吇閲戦
+  status: 0, // 淇濆吇鐘舵��
+});
+
+const rules = {
+  maintenanceActuallyName: [
+    { required: true, message: "璇疯緭鍏ュ疄闄呬繚鍏讳汉", trigger: "blur" },
+  ],
+  maintenanceActuallyTime: [
+    { required: true, message: "璇烽�夋嫨瀹為檯淇濆吇鏃ユ湡", trigger: "change" },
+  ],
+  maintenanceResult: [
+    { required: true, message: "璇疯緭鍏ヤ繚鍏荤粨鏋�", trigger: "blur" },
+  ],
+  maintenancePrice: [
+    { required: true, message: "璇疯緭鍏ユ湰娆′繚鍏婚噾棰�", trigger: "change" },
+  ],
+};
+
+const setForm = (data) => {
+  form.maintenanceActuallyName =
+    data.maintenanceActuallyName ?? userStore.nickName;
+  form.maintenanceActuallyTime =
+    data.maintenanceActuallyTime 
+      ? dayjs(data.maintenanceActuallyTime).format("YYYY-MM-DD HH:mm:ss")
+      : dayjs().format("YYYY-MM-DD HH:mm:ss");
+  form.maintenanceResult = data.maintenanceResult;
+  form.status = 1; // 榛樿鐘舵�佷负瀹岀粨
+};
+
+/**
+ * @desc 淇濆瓨淇濆吇
+ */
+const sendForm = async () => {
+  await formRef.value?.validate(async (valid) => {
+    if (!valid) return;
+    loading.value = true;
+    try {
+      const { code } = await addMaintenance({ id: planId.value, ...form });
+      if (code == 200) {
+        ElMessage.success("淇濆吇鎴愬姛");
+        emits("ok");
+        resetForm();
+        visible.value = false;
+      }
+    } finally {
+      loading.value = false;
+    }
+  });
+};
+
+const handleCancel = () => {
+  resetForm();
+  visible.value = false;
+};
+
+const handleClose = () => {
+  resetForm();
+  visible.value = false;
+};
+
+const open = async (id, row) => {
+  planId.value = id; // 淇濆瓨璁″垝淇濆吇璁板綍鐨刬d
+  visible.value = true;
+  await nextTick();
+  setForm(row);
+};
+
+defineExpose({
+  open,
+});
+</script>
+
+<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Form/PlanForm.vue b/src/views/equipmentManagement/upkeep/Form/PlanForm.vue
deleted file mode 100644
index 2822e2c..0000000
--- a/src/views/equipmentManagement/upkeep/Form/PlanForm.vue
+++ /dev/null
@@ -1,137 +0,0 @@
-<template>
-  <el-form :model="form" label-width="100px">
-    <el-form-item label="璁惧鍚嶇О">
-      <el-select
-        v-model="form.deviceLedgerId"
-        @change="setDeviceModel"
-        placeholder="璇烽�夋嫨璁惧"
-        filterable
-        default-first-option
-        :reserve-keyword="false"
-      >
-        <el-option
-          v-for="(item, index) in deviceOptions"
-          :key="index"
-          :label="item.deviceName"
-          :value="item.id"
-        ></el-option>
-      </el-select>
-    </el-form-item>
-    <el-form-item label="瑙勬牸鍨嬪彿">
-      <el-input
-        v-model="form.deviceModel"
-        placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
-        disabled
-      />
-    </el-form-item>
-    <el-form-item label="褰曞叆浜�">
-      <el-select
-        v-model="form.createUser"
-        placeholder="璇烽�夋嫨"
-        filterable
-        default-first-option
-        :reserve-keyword="false"
-        clearable
-      >
-        <el-option
-          v-for="item in userList"
-          :key="item.userId"
-          :label="item.nickName"
-          :value="item.userId"
-        />
-      </el-select>
-    </el-form-item>
-    <el-form-item v-if="id" label="淇濅慨鐘舵��">
-      <el-select v-model="form.status">
-        <el-option label="寰呬繚淇�" :value="0"></el-option>
-        <el-option label="瀹岀粨" :value="1"></el-option>
-        <el-option label="澶辫触" :value="2"></el-option>
-      </el-select>
-    </el-form-item>
-    <el-form-item label="璁″垝淇濆吇鏃ユ湡">
-      <el-date-picker
-        style="width: 100%"
-        v-model="form.maintenancePlanTime"
-        format="YYYY-MM-DD"
-        value-format="YYYY-MM-DD HH:mm:ss"
-        type="date"
-        placeholder="璇烽�夋嫨璁″垝淇濆吇鏃ユ湡鏃ユ湡"
-        clearable
-      />
-    </el-form-item>
-  </el-form>
-</template>
-
-<script setup>
-import useFormData from "@/hooks/useFormData";
-import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
-import { onMounted } from "vue";
-import dayjs from "dayjs";
-import { userListNoPage } from "@/api/system/user.js";
-
-defineOptions({
-  name: "璁″垝琛ㄥ崟",
-});
-
-const deviceOptions = ref([]);
-const loadDeviceName = async () => {
-  const { data } = await getDeviceLedger();
-  deviceOptions.value = data;
-};
-
-const { id } = defineProps(['id']);
-
-const { form, resetForm } = useFormData({
-  deviceLedgerId: undefined, // 璁惧Id
-  deviceName: undefined, // 璁惧鍚嶇О
-  deviceModel: undefined, // 瑙勬牸鍨嬪彿
-  maintenancePlanTime: undefined, // 璁″垝淇濆吇鏃ユ湡
-  createUser: undefined, // 褰曞叆浜�
-  status: 0, //淇濅慨鐘舵��
-});
-
-const setDeviceModel = (id) => {
-  const option = deviceOptions.value.find((item) => item.id === id);
-  form.deviceModel = option.deviceModel;
-};
-
-const getForm = () => {
-  return form;
-};
-
-/**
- * @desc 璁剧疆琛ㄥ崟鍐呭
- * @param data 璁惧淇℃伅
- */
-const setForm = (data) => {
-  form.deviceLedgerId = data.deviceLedgerId;
-  form.deviceName = data.deviceName;
-  form.deviceModel = data.deviceModel;
-  form.createUser = Number(data.createUser);
-  form.status = data.status;
-  form.maintenancePlanTime = dayjs(data.maintenancePlanTime).format(
-    "YYYY-MM-DD HH:mm:ss"
-  );
-};
-
-// 鐢ㄦ埛鍒楄〃
-const userList = ref([]);
-
-const loadForm = () => {};
-
-onMounted(() => {
-  loadDeviceName();
-  userListNoPage().then((res) => {
-    userList.value = res.data;
-  });
-});
-
-defineExpose({
-  loadForm,
-  resetForm,
-  getForm,
-  setForm,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Form/PlanModal.vue b/src/views/equipmentManagement/upkeep/Form/PlanModal.vue
new file mode 100644
index 0000000..19095b9
--- /dev/null
+++ b/src/views/equipmentManagement/upkeep/Form/PlanModal.vue
@@ -0,0 +1,188 @@
+<template>
+  <FormDialog
+    v-model="visible"
+    :title="id ? '缂栬緫璁惧淇濆吇璁″垝' : '鏂板璁惧淇濆吇璁″垝'"
+    width="500px"
+    @confirm="sendForm"
+    @cancel="handleCancel"
+    @close="handleClose"
+  >
+    <el-form :model="form" label-width="100px">
+      <el-form-item label="璁惧鍚嶇О">
+        <el-select
+          v-model="form.deviceLedgerId"
+          @change="setDeviceModel"
+          placeholder="璇烽�夋嫨璁惧"
+          filterable
+          default-first-option
+          :reserve-keyword="false"
+        >
+          <el-option
+            v-for="(item, index) in deviceOptions"
+            :key="index"
+            :label="item.deviceName"
+            :value="item.id"
+          ></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="瑙勬牸鍨嬪彿">
+        <el-input
+          v-model="form.deviceModel"
+          placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
+          disabled
+        />
+      </el-form-item>
+      <el-form-item label="褰曞叆浜�">
+        <el-select
+          v-model="form.createUser"
+          placeholder="璇烽�夋嫨"
+          filterable
+          default-first-option
+          :reserve-keyword="false"
+          clearable
+        >
+          <el-option
+            v-for="item in userList"
+            :key="item.userId"
+            :label="item.nickName"
+            :value="item.userId"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item v-if="id" label="淇濅慨鐘舵��">
+        <el-select v-model="form.status">
+          <el-option label="寰呬繚淇�" :value="0"></el-option>
+          <el-option label="瀹岀粨" :value="1"></el-option>
+          <el-option label="澶辫触" :value="2"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="璁″垝淇濆吇鏃ユ湡">
+        <el-date-picker
+          style="width: 100%"
+          v-model="form.maintenancePlanTime"
+          format="YYYY-MM-DD"
+          value-format="YYYY-MM-DD HH:mm:ss"
+          type="date"
+          placeholder="璇烽�夋嫨璁″垝淇濆吇鏃ユ湡鏃ユ湡"
+          clearable
+        />
+      </el-form-item>
+    </el-form>
+  </FormDialog>
+</template>
+
+<script setup>
+import FormDialog from "@/components/Dialog/FormDialog.vue";
+import {
+  addUpkeep,
+  editUpkeep,
+  getUpkeepById,
+} from "@/api/equipmentManagement/upkeep";
+import { ElMessage } from "element-plus";
+import useFormData from "@/hooks/useFormData";
+import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
+import { onMounted } from "vue";
+import dayjs from "dayjs";
+import { userListNoPage } from "@/api/system/user.js";
+
+defineOptions({
+  name: "璁惧淇濆吇鏂板璁″垝",
+});
+
+const emits = defineEmits(["ok"]);
+
+const id = ref();
+const visible = ref(false);
+const loading = ref(false);
+
+const deviceOptions = ref([]);
+const loadDeviceName = async () => {
+  const { data } = await getDeviceLedger();
+  deviceOptions.value = data;
+};
+
+const { form, resetForm } = useFormData({
+  deviceLedgerId: undefined, // 璁惧Id
+  deviceName: undefined, // 璁惧鍚嶇О
+  deviceModel: undefined, // 瑙勬牸鍨嬪彿
+  maintenancePlanTime: undefined, // 璁″垝淇濆吇鏃ユ湡
+  createUser: undefined, // 褰曞叆浜�
+  status: 0, //淇濅慨鐘舵��
+});
+
+const setDeviceModel = (deviceId) => {
+  const option = deviceOptions.value.find((item) => item.id === deviceId);
+  form.deviceModel = option.deviceModel;
+};
+
+/**
+ * @desc 璁剧疆琛ㄥ崟鍐呭
+ * @param data 璁惧淇℃伅
+ */
+const setForm = (data) => {
+  form.deviceLedgerId = data.deviceLedgerId;
+  form.deviceName = data.deviceName;
+  form.deviceModel = data.deviceModel;
+  form.createUser = Number(data.createUser);
+  form.status = data.status;
+  form.maintenancePlanTime = dayjs(data.maintenancePlanTime).format(
+    "YYYY-MM-DD HH:mm:ss"
+  );
+};
+
+// 鐢ㄦ埛鍒楄〃
+const userList = ref([]);
+
+onMounted(() => {
+  loadDeviceName();
+  userListNoPage().then((res) => {
+    userList.value = res.data;
+  });
+});
+
+const openEdit = async (editId) => {
+  const { data } = await getUpkeepById(editId);
+  id.value = editId;
+  visible.value = true;
+  await nextTick();
+  setForm(data);
+};
+
+const sendForm = async () => {
+  loading.value = true;
+  try {
+    const { code } = id.value
+      ? await editUpkeep({ id: unref(id), ...form })
+      : await addUpkeep(form);
+    if (code == 200) {
+      ElMessage.success(`${id.value ? "缂栬緫" : "鏂板"}璁″垝鎴愬姛`);
+      visible.value = false;
+      emits("ok");
+    }
+  } finally {
+    loading.value = false;
+  }
+};
+
+const handleCancel = () => {
+  resetForm();
+  visible.value = false;
+};
+
+const handleClose = () => {
+  resetForm();
+  visible.value = false;
+};
+
+const openModal = () => {
+  id.value = undefined;
+  visible.value = true;
+};
+
+defineExpose({
+  openModal,
+  openEdit,
+});
+</script>
+
+<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Form/formDia.vue b/src/views/equipmentManagement/upkeep/Form/formDia.vue
new file mode 100644
index 0000000..1a113cc
--- /dev/null
+++ b/src/views/equipmentManagement/upkeep/Form/formDia.vue
@@ -0,0 +1,337 @@
+<template>
+	<FormDialog
+		v-model="dialogVisitable"
+		:title="operationType === 'add' ? '鏂板淇濆吇浠诲姟' : '缂栬緫淇濆吇浠诲姟'"
+		width="800px"
+		:operation-type="operationType"
+		@confirm="submitForm"
+		@cancel="cancel"
+		@close="cancel"
+	>
+		<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
+			<el-row>
+				<el-col :span="12">
+					<el-form-item label="璁惧鍚嶇О" prop="taskIds">
+						<el-select v-model="form.taskIds" @change="setDeviceModel" multiple filterable>
+							<el-option
+								v-for="(item, index) in deviceOptions"
+								:key="index"
+								:label="item.deviceName"
+								:value="item.id"
+							></el-option>
+						</el-select>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="瑙勬牸鍨嬪彿">
+						<el-input
+							v-model="form.deviceModel"
+							placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
+							disabled
+						/>
+					</el-form-item>
+				</el-col>
+			</el-row>
+			<el-row>
+				<el-col :span="12">
+					<el-form-item label="褰曞叆浜�" prop="inspector">
+						<el-select
+							v-model="form.inspector"
+							filterable
+							default-first-option
+							:reserve-keyword="false"
+							placeholder="璇烽�夋嫨"
+							clearable
+						>
+							<el-option
+								v-for="item in userList"
+								:label="item.nickName"
+								:value="item.userId"
+								:key="item.userId"
+							/>
+						</el-select>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12">
+					<el-form-item label="鐧昏鏃堕棿" prop="registrationDate">
+						<el-date-picker
+							v-model="form.registrationDate"
+							type="date"
+							placeholder="閫夋嫨鐧昏鏃ユ湡"
+							format="YYYY-MM-DD"
+							value-format="YYYY-MM-DD"
+							style="width: 100%"
+						/>
+					</el-form-item>
+				</el-col>
+			</el-row>
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="瀹℃壒浜�" prop="auditName">
+            <el-select
+              v-model="form.auditName"
+              filterable
+              placeholder="璇烽�夋嫨瀹℃壒浜�"
+              clearable
+            >
+              <el-option
+                v-for="item in userList"
+                :key="item.userId"
+                :label="item.nickName"
+                :value="item.nickName"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+			<el-row>
+				<el-col :span="12">
+					<el-form-item label="浠诲姟棰戠巼" prop="frequencyType">
+						<el-select v-model="form.frequencyType" placeholder="璇烽�夋嫨" clearable>
+							<el-option label="姣忔棩" value="DAILY"/>
+							<el-option label="姣忓懆" value="WEEKLY"/>
+							<el-option label="姣忔湀" value="MONTHLY"/>
+							<el-option label="瀛e害" value="QUARTERLY"/>
+						</el-select>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12" v-if="form.frequencyType === 'DAILY' && form.frequencyType">
+					<el-form-item label="鏃ユ湡" prop="frequencyDetail">
+						<el-time-picker v-model="form.frequencyDetail" placeholder="閫夋嫨鏃堕棿" format="HH:mm"
+														value-format="HH:mm" />
+					</el-form-item>
+				</el-col>
+				<el-col :span="12" v-if="form.frequencyType === 'WEEKLY' && form.frequencyType">
+					<el-form-item label="鏃ユ湡" prop="frequencyDetail">
+						<el-select v-model="form.week" placeholder="璇烽�夋嫨" clearable style="width: 50%">
+							<el-option label="鍛ㄤ竴" value="MON"/>
+							<el-option label="鍛ㄤ簩" value="TUE"/>
+							<el-option label="鍛ㄤ笁" value="WED"/>
+							<el-option label="鍛ㄥ洓" value="THU"/>
+							<el-option label="鍛ㄤ簲" value="FRI"/>
+							<el-option label="鍛ㄥ叚" value="SAT"/>
+							<el-option label="鍛ㄦ棩" value="SUN"/>
+						</el-select>
+						<el-time-picker v-model="form.time" placeholder="閫夋嫨鏃堕棿" format="HH:mm"
+														value-format="HH:mm"  style="width: 50%"/>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12" v-if="form.frequencyType === 'MONTHLY' && form.frequencyType">
+					<el-form-item label="鏃ユ湡" prop="frequencyDetail">
+						<el-date-picker
+							v-model="form.frequencyDetail"
+							type="datetime"
+							clearable
+							placeholder="閫夋嫨寮�濮嬫棩鏈�"
+							format="DD,HH:mm"
+							value-format="DD,HH:mm"
+						/>
+					</el-form-item>
+				</el-col>
+				<el-col :span="12" v-if="form.frequencyType === 'QUARTERLY' && form.frequencyType">
+					<el-form-item label="鏃ユ湡" prop="frequencyDetail">
+						<el-date-picker
+							v-model="form.frequencyDetail"
+							type="datetime"
+							clearable
+							placeholder="閫夋嫨寮�濮嬫棩鏈�"
+							format="MM,DD,HH:mm"
+							value-format="MM,DD,HH:mm"
+						/>
+					</el-form-item>
+				</el-col>
+			</el-row>
+			<el-row>
+				<el-col :span="12">
+					<el-form-item label="澶囨敞" prop="remarks">
+						<el-input v-model="form.remarks" placeholder="璇疯緭鍏ュ娉�" type="textarea" />
+					</el-form-item>
+				</el-col>
+			</el-row>
+		</el-form>
+	</FormDialog>
+</template>
+
+<script setup>
+import FormDialog from "@/components/Dialog/FormDialog.vue";
+import { reactive, ref, getCurrentInstance, toRefs } from "vue";
+import {userListNoPageByTenantId} from "@/api/system/user.js";
+import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
+import { deviceMaintenanceTaskAdd, deviceMaintenanceTaskEdit } from "@/api/equipmentManagement/upkeep";
+import { getCurrentDate } from "@/utils/index.js";
+import useUserStore from "@/store/modules/user.js";
+
+const { proxy } = getCurrentInstance()
+const emit = defineEmits()
+const dialogVisitable = ref(false);
+const operationType = ref('add');
+const deviceOptions = ref([]);
+const userStore = useUserStore();
+const data = reactive({
+	form: {
+		taskIds: [],
+		taskName: undefined,
+		// 褰曞叆浜猴細鍗曢�変竴涓敤鎴� id
+		inspector: undefined,
+    auditName: undefined,
+		remarks: '',
+		frequencyType: '',
+		frequencyDetail: '',
+		week: '',
+		time: '',
+		deviceModel: undefined, // 瑙勬牸鍨嬪彿
+		registrationDate: ''
+	},
+	rules: {
+		taskIds: [{ required: true, message: "璇烽�夋嫨璁惧", trigger: "change" },],
+		inspector: [{ required: true, message: "璇烽�夋嫨褰曞叆浜�", trigger: "blur" },],
+		registrationDate: [{ required: true, message: "璇烽�夋嫨鐧昏鏃堕棿", trigger: "change" }],
+    auditName: [{ required: true, message: "璇烽�夋嫨瀹℃壒浜�", trigger: "change" }],
+	}
+})
+const { form, rules } = toRefs(data)
+const userList = ref([])
+
+const loadDeviceName = async () => {
+	const { data } = await getDeviceLedger();
+	deviceOptions.value = data;
+};
+
+// 閫夋嫨璁惧鏃讹紝鍥炲~璁惧鍚嶇О(taskName)鍜岃鏍煎瀷鍙�(deviceModel)
+const setDeviceModel = (ids) => {
+	if (!ids || ids.length === 0) {
+		form.value.taskIds = []
+		form.value.taskName = undefined
+		form.value.deviceModel = undefined
+		return
+	}
+	
+	const selectedDevices = deviceOptions.value.filter((item) => ids.includes(item.id))
+	if (selectedDevices.length > 0) {
+		form.value.taskIds = ids
+		form.value.taskName = selectedDevices.map(d => d.deviceName).join(',')
+		form.value.deviceModel = selectedDevices.map(d => d.deviceModel || '-').join(',')
+	}
+}
+
+// 鎵撳紑寮规
+const openDialog = async (type, row) => {
+	dialogVisitable.value = true
+	operationType.value = type
+	
+	// 閲嶇疆琛ㄥ崟
+	resetForm();
+	
+	// 鍔犺浇鐢ㄦ埛鍒楄〃
+	userListNoPageByTenantId().then((res) => {
+		userList.value = res.data;
+	});
+	
+	// 鍔犺浇璁惧鍒楄〃
+	await loadDeviceName();
+	
+	if (type === 'edit' && row) {
+		form.value = { ...row }
+		// 缂栬緫鏃剁敤鎺ュ彛杩斿洖鐨� registrantId 鍥炴樉褰曞叆浜�
+		if (row.registrantId) {
+			form.value.inspector = row.registrantId
+		}
+		// 濡傛灉鏈夎澶嘔D鏁扮粍锛岃浆鎹负鏁扮粍骞惰缃澶囦俊鎭�
+		if (row.taskIds) {
+			form.value.taskIds = row.taskIds.split(',').map(id => parseInt(id.trim()))
+			setDeviceModel(form.value.taskIds)
+		}
+	} else if (type === 'add') {
+		// 鏂板鏃惰缃櫥璁版棩鏈熶负褰撳ぉ
+		form.value.registrationDate = getCurrentDate();
+		// 鏂板鏃惰缃綍鍏ヤ汉涓哄綋鍓嶇櫥褰曡处鎴�
+		form.value.inspector = userStore.id;
+	}
+}
+
+// 鍏抽棴瀵硅瘽妗�
+const cancel = () => {
+	resetForm()
+	dialogVisitable.value = false
+	emit('closeDia')
+}
+
+// 閲嶇疆琛ㄥ崟鍑芥暟
+const resetForm = () => {
+	if (proxy.$refs.formRef) {
+		proxy.$refs.formRef.resetFields()
+	}
+	// 閲嶇疆琛ㄥ崟鏁版嵁纭繚璁惧淇℃伅姝g‘閲嶇疆
+	form.value = {
+		taskIds: [],
+		taskName: undefined,
+		inspector: undefined,
+		auditName: undefined,
+		remarks: '',
+		frequencyType: '',
+		frequencyDetail: '',
+		week: '',
+		time: '',
+		deviceModel: undefined,
+		registrationDate: ''
+	}
+}
+
+// 鎻愪氦琛ㄥ崟
+const submitForm = () => {
+	proxy.$refs["formRef"].validate(async valid => {
+		if (valid) {
+			try {
+				const payload = { ...form.value }
+				// 涓嶅啀鍚戝悗绔紶淇濆吇浜哄瓧娈碉紝浠呬娇鐢ㄦ帴鍙h姹傜殑 registrant / registrantId
+				// 鏍规嵁閫夋嫨鐨�"褰曞叆浜�"璁剧疆 registrant / registrantId
+				if (payload.inspector) {
+					const selectedUser = userList.value.find(
+						(u) => String(u.userId) === String(payload.inspector)
+					)
+					if (selectedUser) {
+						payload.registrantId = selectedUser.userId
+						payload.registrant = selectedUser.nickName
+					}
+				}
+				delete payload.inspector
+				delete payload.inspectorIds
+				
+				// 澶勭悊 taskIds 鍜� taskName
+				if (payload.taskIds && Array.isArray(payload.taskIds)) {
+					payload.taskIds = payload.taskIds.join(',')
+				}
+				
+				if (payload.frequencyType === 'WEEKLY') {
+					let frequencyDetail = ''
+					frequencyDetail = payload.week + ',' + payload.time
+					payload.frequencyDetail = frequencyDetail
+				}
+				
+				// 褰曞叆鏃ユ湡锛氱洿鎺ヤ娇鐢ㄨ〃鍗曢噷鐨� registrationDate 瀛楁
+				// 涓�浜涢粯璁ょ姸鎬佸瓧娈�
+				if (payload.status === undefined || payload.status === null || payload.status === '') {
+					payload.status = '寰呭鏍�' // 榛樿鐘舵�侊細寰呭鏍�
+				}
+				payload.active = true
+				payload.deleted = 0
+				
+				if (operationType.value === 'edit') {
+					await deviceMaintenanceTaskEdit(payload)
+				} else {
+					await deviceMaintenanceTaskAdd(payload)
+				}
+				cancel()
+				proxy.$modal.msgSuccess('鎻愪氦鎴愬姛')
+			} catch (error) {
+				proxy.$modal.msgError('鎻愪氦澶辫触锛岃閲嶈瘯')
+			}
+		}
+	})
+}
+defineExpose({ openDialog })
+</script>
+
+<style scoped>
+
+</style>
diff --git a/src/views/equipmentManagement/upkeep/Modal/MaintenanceModal.vue b/src/views/equipmentManagement/upkeep/Modal/MaintenanceModal.vue
deleted file mode 100644
index 0b44221..0000000
--- a/src/views/equipmentManagement/upkeep/Modal/MaintenanceModal.vue
+++ /dev/null
@@ -1,60 +0,0 @@
-<template>
-  <el-dialog v-model="visible" :title="modalOptions.title" direction="ltr" draggable>
-    <MaintenanceForm ref="maintenanceFormRef" />
-    <template #footer>
-			<el-button type="primary" @click="sendForm" :loading="loading">
-				{{ modalOptions.confirmText }}
-			</el-button>
-      <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
-    </template>
-  </el-dialog>
-</template>
-
-<script setup>
-import MaintenanceForm from "../Form/MaintenanceForm.vue";
-import { useModal } from "@/hooks/useModal";
-import { addMaintenance } from "@/api/equipmentManagement/upkeep";
-
-defineOptions({
-  name: "淇濆吇妯℃�佹",
-});
-
-const maintenanceFormRef = ref();
-const emits = defineEmits(["ok"]);
-
-const {
-  id,
-  visible,
-  loading,
-  openModal,
-  modalOptions,
-  handleConfirm,
-  closeModal,
-} = useModal({ title: "璁惧淇濆吇" });
-
-/**
- * @desc 淇濆瓨淇濆吇
- */
-const sendForm = async () => {
-  loading.value = true;
-  const form = await maintenanceFormRef.value.getForm();
-  const { code } = await addMaintenance({ id: id.value, ...form });
-  if (code == 200) {
-    emits("ok");
-    maintenanceFormRef.value.resetForm();
-    closeModal();
-  }
-  loading.value = false;
-};
-
-const open = async (id, row) => {
-  openModal(id);
-  await nextTick();
-  maintenanceFormRef.value.setForm(row);
-};
-defineExpose({
-  open,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Modal/PlanModal.vue b/src/views/equipmentManagement/upkeep/Modal/PlanModal.vue
deleted file mode 100644
index 249c9c3..0000000
--- a/src/views/equipmentManagement/upkeep/Modal/PlanModal.vue
+++ /dev/null
@@ -1,77 +0,0 @@
-<template>
-  <el-dialog
-    v-model="visible"
-    :title="modalOptions.title"
-    width="30%"
-		draggable
-    @close="close"
-  >
-    <PlanForm ref="planFormRef" :id="id"></PlanForm>
-    <template #footer>
-			<el-button type="primary" @click="sendForm" :loading="loading">
-				{{ modalOptions.confirmText }}
-			</el-button>
-      <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
-    </template>
-  </el-dialog>
-</template>
-
-<script setup>
-import { useModal } from "@/hooks/useModal";
-import PlanForm from "../Form/PlanForm";
-import {
-  addUpkeep,
-  editUpkeep,
-  getUpkeepById,
-} from "@/api/equipmentManagement/upkeep";
-import { ElMessage } from "element-plus";
-
-defineOptions({
-  name: "璁惧淇濆吇鏂板璁″垝",
-});
-
-const emits = defineEmits(["ok"]);
-const planFormRef = ref();
-const {
-  id,
-  visible,
-  loading,
-  openModal,
-  modalOptions,
-  handleConfirm,
-  closeModal,
-} = useModal({ title: "璁惧淇濆吇璁″垝" });
-
-const openEdit = async (id) => {
-  const { data } = await getUpkeepById(id);
-  openModal(id);
-  await nextTick();
-  await planFormRef.value.setForm(data);
-};
-
-const sendForm = async () => {
-  loading.value = true;
-  const form = await planFormRef.value.getForm();
-  const { code } = id.value
-    ? await editUpkeep({ id: unref(id), ...form })
-    : await addUpkeep(form);
-  if (code == 200) {
-    ElMessage.success(`${id ? "缂栬緫" : "鏂板"}璁″垝鎴愬姛`);
-    closeModal();
-    emits("ok");
-  }
-  loading.value = false;
-};
-
-const close = () => {
-  planFormRef.value.resetForm();
-  closeModal();
-};
-
-defineExpose({
-  openModal,
-  openEdit,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Modal/formDia.vue b/src/views/equipmentManagement/upkeep/Modal/formDia.vue
deleted file mode 100644
index a484d23..0000000
--- a/src/views/equipmentManagement/upkeep/Modal/formDia.vue
+++ /dev/null
@@ -1,304 +0,0 @@
-<template>
-	<div>
-		<el-dialog :title="operationType === 'add' ? '鏂板淇濆吇浠诲姟' : '缂栬緫淇濆吇浠诲姟'"
-							 v-model="dialogVisitable" width="800px" @close="cancel">
-			<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
-				<el-row>
-					<el-col :span="12">
-						<el-form-item label="璁惧鍚嶇О" prop="taskId">
-							<el-select v-model="form.taskId" @change="setDeviceModel" filterable>
-								<el-option
-									v-for="(item, index) in deviceOptions"
-									:key="index"
-									:label="item.deviceName"
-									:value="item.id"
-								></el-option>
-							</el-select>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12">
-						<el-form-item label="瑙勬牸鍨嬪彿">
-							<el-input
-								v-model="form.deviceModel"
-								placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
-								disabled
-							/>
-						</el-form-item>
-					</el-col>
-				</el-row>
-				<el-row>
-					<el-col :span="12">
-						<el-form-item label="褰曞叆浜�" prop="inspector">
-							<el-select
-								v-model="form.inspector"
-								filterable
-								default-first-option
-								:reserve-keyword="false"
-								placeholder="璇烽�夋嫨"
-								clearable
-							>
-								<el-option
-									v-for="item in userList"
-									:label="item.nickName"
-									:value="item.userId"
-									:key="item.userId"
-								/>
-							</el-select>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12">
-						<el-form-item label="鐧昏鏃堕棿" prop="registrationDate">
-							<el-date-picker
-								v-model="form.registrationDate"
-								type="date"
-								placeholder="閫夋嫨鐧昏鏃ユ湡"
-								format="YYYY-MM-DD"
-								value-format="YYYY-MM-DD"
-								style="width: 100%"
-							/>
-						</el-form-item>
-					</el-col>
-				</el-row>
-				<el-row>
-					<el-col :span="12">
-						<el-form-item label="浠诲姟棰戠巼" prop="frequencyType">
-							<el-select v-model="form.frequencyType" placeholder="璇烽�夋嫨" clearable>
-								<el-option label="姣忔棩" value="DAILY"/>
-								<el-option label="姣忓懆" value="WEEKLY"/>
-								<el-option label="姣忔湀" value="MONTHLY"/>
-								<el-option label="瀛e害" value="QUARTERLY"/>
-							</el-select>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12" v-if="form.frequencyType === 'DAILY' && form.frequencyType">
-						<el-form-item label="鏃ユ湡" prop="frequencyDetail">
-							<el-time-picker v-model="form.frequencyDetail" placeholder="閫夋嫨鏃堕棿" format="HH:mm"
-															value-format="HH:mm" />
-						</el-form-item>
-					</el-col>
-					<el-col :span="12" v-if="form.frequencyType === 'WEEKLY' && form.frequencyType">
-						<el-form-item label="鏃ユ湡" prop="frequencyDetail">
-							<el-select v-model="form.week" placeholder="璇烽�夋嫨" clearable style="width: 50%">
-								<el-option label="鍛ㄤ竴" value="MON"/>
-								<el-option label="鍛ㄤ簩" value="TUE"/>
-								<el-option label="鍛ㄤ笁" value="WED"/>
-								<el-option label="鍛ㄥ洓" value="THU"/>
-								<el-option label="鍛ㄤ簲" value="FRI"/>
-								<el-option label="鍛ㄥ叚" value="SAT"/>
-								<el-option label="鍛ㄦ棩" value="SUN"/>
-							</el-select>
-							<el-time-picker v-model="form.time" placeholder="閫夋嫨鏃堕棿" format="HH:mm"
-															value-format="HH:mm"  style="width: 50%"/>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12" v-if="form.frequencyType === 'MONTHLY' && form.frequencyType">
-						<el-form-item label="鏃ユ湡" prop="frequencyDetail">
-							<el-date-picker
-								v-model="form.frequencyDetail"
-								type="datetime"
-								clearable
-								placeholder="閫夋嫨寮�濮嬫棩鏈�"
-								format="DD,HH:mm"
-								value-format="DD,HH:mm"
-							/>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12" v-if="form.frequencyType === 'QUARTERLY' && form.frequencyType">
-						<el-form-item label="鏃ユ湡" prop="frequencyDetail">
-							<el-date-picker
-								v-model="form.frequencyDetail"
-								type="datetime"
-								clearable
-								placeholder="閫夋嫨寮�濮嬫棩鏈�"
-								format="MM,DD,HH:mm"
-								value-format="MM,DD,HH:mm"
-							/>
-						</el-form-item>
-					</el-col>
-				</el-row>
-				<el-row>
-					<el-col :span="12">
-						<el-form-item label="澶囨敞" prop="remarks">
-							<el-input v-model="form.remarks" placeholder="璇疯緭鍏ュ娉�" type="textarea" />
-						</el-form-item>
-					</el-col>
-				</el-row>
-			</el-form>
-			<template #footer>
-				<div class="dialog-footer">
-					<el-button type="primary" @click="submitForm">淇濆瓨</el-button>
-					<el-button @click="cancel">鍙栨秷</el-button>
-				</div>
-			</template>
-		</el-dialog>
-	</div>
-</template>
-
-<script setup>
-import { reactive, ref, getCurrentInstance, toRefs } from "vue";
-import {userListNoPageByTenantId} from "@/api/system/user.js";
-import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
-import { deviceMaintenanceTaskAdd, deviceMaintenanceTaskEdit } from "@/api/equipmentManagement/upkeep";
-import { getCurrentDate } from "@/utils/index.js";
-import useUserStore from "@/store/modules/user.js";
-
-const { proxy } = getCurrentInstance()
-const emit = defineEmits()
-const dialogVisitable = ref(false);
-const operationType = ref('add');
-const deviceOptions = ref([]);
-const userStore = useUserStore();
-const data = reactive({
-	form: {
-		taskId: undefined,
-		taskName: undefined,
-		// 褰曞叆浜猴細鍗曢�変竴涓敤鎴� id
-		inspector: undefined,
-		remarks: '',
-		frequencyType: '',
-		frequencyDetail: '',
-		week: '',
-		time: '',
-		deviceModel: undefined, // 瑙勬牸鍨嬪彿
-		registrationDate: ''
-	},
-	rules: {
-		taskId: [{ required: true, message: "璇烽�夋嫨璁惧", trigger: "change" },],
-		inspector: [{ required: true, message: "璇烽�夋嫨褰曞叆浜�", trigger: "blur" },],
-		registrationDate: [{ required: true, message: "璇烽�夋嫨鐧昏鏃堕棿", trigger: "change" }]
-	}
-})
-const { form, rules } = toRefs(data)
-const userList = ref([])
-
-const loadDeviceName = async () => {
-	const { data } = await getDeviceLedger();
-	deviceOptions.value = data;
-};
-
-// 閫夋嫨璁惧鏃讹紝鍥炲~璁惧鍚嶇О(taskName)鍜岃鏍煎瀷鍙�(deviceModel)
-const setDeviceModel = (id) => {
-	const option = deviceOptions.value.find((item) => item.id === id);
-	if (option) {
-		form.value.taskId = option.id;
-		form.value.taskName = option.deviceName;
-		form.value.deviceModel = option.deviceModel;
-	}
-}
-
-// 鎵撳紑寮规
-const openDialog = async (type, row) => {
-	dialogVisitable.value = true
-	operationType.value = type
-	
-	// 閲嶇疆琛ㄥ崟
-	resetForm();
-	
-	// 鍔犺浇鐢ㄦ埛鍒楄〃
-	userListNoPageByTenantId().then((res) => {
-		userList.value = res.data;
-	});
-	
-	// 鍔犺浇璁惧鍒楄〃
-	await loadDeviceName();
-	
-	if (type === 'edit' && row) {
-		form.value = { ...row }
-		// 缂栬緫鏃剁敤鎺ュ彛杩斿洖鐨� registrantId 鍥炴樉褰曞叆浜�
-		if (row.registrantId) {
-			form.value.inspector = row.registrantId
-		}
-
-		// 濡傛灉鏈夎澶嘔D锛岃嚜鍔ㄨ缃澶囦俊鎭�
-		if (form.value.taskId) {
-			setDeviceModel(form.value.taskId);
-		}
-	} else if (type === 'add') {
-		// 鏂板鏃惰缃櫥璁版棩鏈熶负褰撳ぉ
-		form.value.registrationDate = getCurrentDate();
-		// 鏂板鏃惰缃綍鍏ヤ汉涓哄綋鍓嶇櫥褰曡处鎴�
-		form.value.inspector = userStore.id;
-	}
-}
-
-// 鍏抽棴瀵硅瘽妗�
-const cancel = () => {
-	resetForm()
-	dialogVisitable.value = false
-	emit('closeDia')
-}
-
-// 閲嶇疆琛ㄥ崟鍑芥暟
-const resetForm = () => {
-	if (proxy.$refs.formRef) {
-		proxy.$refs.formRef.resetFields()
-	}
-	// 閲嶇疆琛ㄥ崟鏁版嵁纭繚璁惧淇℃伅姝g‘閲嶇疆
-	form.value = {
-		taskId: undefined,
-		taskName: undefined,
-		inspector: undefined,
-		inspector: undefined,
-		remarks: '',
-		frequencyType: '',
-		frequencyDetail: '',
-		week: '',
-		time: '',
-		deviceModel: undefined,
-		registrationDate: ''
-	}
-}
-
-// 鎻愪氦琛ㄥ崟
-const submitForm = () => {
-	proxy.$refs["formRef"].validate(async valid => {
-		if (valid) {
-			try {
-				const payload = { ...form.value }
-				// 涓嶅啀鍚戝悗绔紶淇濆吇浜哄瓧娈碉紝浠呬娇鐢ㄦ帴鍙h姹傜殑 registrant / registrantId
-				// 鏍规嵁閫夋嫨鐨勨�滃綍鍏ヤ汉鈥濊缃� registrant / registrantId
-				if (payload.inspector) {
-					const selectedUser = userList.value.find(
-						(u) => String(u.userId) === String(payload.inspector)
-					)
-					if (selectedUser) {
-						payload.registrantId = selectedUser.userId
-						payload.registrant = selectedUser.nickName
-					}
-				}
-				delete payload.inspector
-				delete payload.inspectorIds
-				
-				if (payload.frequencyType === 'WEEKLY') {
-					let frequencyDetail = ''
-					frequencyDetail = payload.week + ',' + payload.time
-					payload.frequencyDetail = frequencyDetail
-				}
-				
-				// 褰曞叆鏃ユ湡锛氱洿鎺ヤ娇鐢ㄨ〃鍗曢噷鐨� registrationDate 瀛楁
-				// 涓�浜涢粯璁ょ姸鎬佸瓧娈�
-				if (payload.status === undefined || payload.status === null || payload.status === '') {
-					payload.status = '0' // 榛樿鐘舵�侊紝鍙寜瀹為檯鏋氫妇璋冩暣
-				}
-				payload.active = true
-				payload.deleted = 0
-				
-				if (operationType.value === 'edit') {
-					await deviceMaintenanceTaskEdit(payload)
-				} else {
-					await deviceMaintenanceTaskAdd(payload)
-				}
-				cancel()
-				proxy.$modal.msgSuccess('鎻愪氦鎴愬姛')
-			} catch (error) {
-				proxy.$modal.msgError('鎻愪氦澶辫触锛岃閲嶈瘯')
-			}
-		}
-	})
-}
-defineExpose({ openDialog })
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/equipmentManagement/upkeep/index.vue b/src/views/equipmentManagement/upkeep/index.vue
index 9b13b47..c51395f 100644
--- a/src/views/equipmentManagement/upkeep/index.vue
+++ b/src/views/equipmentManagement/upkeep/index.vue
@@ -17,8 +17,9 @@
             </el-form-item>
             <el-form-item label="浠诲姟鐘舵��">
               <el-select v-model="scheduledFilters.status" placeholder="璇烽�夋嫨浠诲姟鐘舵��" clearable style="width: 200px">
-                <el-option label="鍚敤" value="1" />
-                <el-option label="鍋滅敤" value="0" />
+                <el-option label="寰呭鏍�" value="寰呭鏍�" />
+                <el-option label="瀹℃牳閫氳繃" value="瀹℃牳閫氳繃" />
+                <el-option label="瀹℃牳涓嶉�氳繃" value="瀹℃牳涓嶉�氳繃" />
               </el-select>
             </el-form-item>
             <el-form-item>
@@ -58,22 +59,30 @@
             @pagination="changeScheduledPage"
           >
             <template #statusRef="{ row }">
-              <el-tag v-if="row.status === 1" type="success">鍚敤</el-tag>
-              <el-tag v-if="row.status === 0" type="danger">鍋滅敤</el-tag>
+              <el-tag v-if="row.status === '寰呭鏍�'" type="warning">寰呭鏍�</el-tag>
+              <el-tag v-else-if="row.status === '瀹℃牳閫氳繃'" type="success">瀹℃牳閫氳繃</el-tag>
+              <el-tag v-else-if="row.status === '瀹℃牳涓嶉�氳繃'" type="danger">瀹℃牳涓嶉�氳繃</el-tag>
+              <span v-else>{{ row.status }}</span>
             </template>
             <template #operation="{ row }">
               <el-button
                 type="primary"
-                text
-                icon="editPen"
+                link
                 @click="editScheduledTask(row)"
               >
                 缂栬緫
               </el-button>
               <el-button
+                type="warning"
+                link
+                :disabled="row.status === '瀹℃牳閫氳繃'"
+                @click="openScheduledApprove(row)"
+              >
+                瀹℃壒
+              </el-button>
+              <el-button
                 type="danger"
-                text
-                icon="delete"
+                link
                 @click="delScheduledTaskByIds(row.id)"
               >
                 鍒犻櫎
@@ -135,24 +144,13 @@
           <div class="actions">
             <el-text class="mx-1" size="large">浠诲姟璁板綍</el-text>
             <div>
-              <el-button
-                type="primary"
-                icon="Plus"
-                :disabled="multipleList.length !== 1"
-                @click="addMaintain"
-              >
-                鏂板淇濆吇
-              </el-button>
-              <el-button type="success" icon="Van" @click="addPlan">
-                鏂板璁″垝
-              </el-button>
               <el-button @click="handleOut">
                 瀵煎嚭
               </el-button>
               <el-button
                 type="danger"
                 icon="Delete"
-                :disabled="multipleList.length <= 0"
+                :disabled="multipleList.length <= 0 || hasFinishedStatus"
                 @click="delRepairByIds(multipleList.map((item) => item.id))"
               >
                 鎵归噺鍒犻櫎
@@ -181,21 +179,44 @@
           <el-tag v-if="row.status === 0" type="warning">寰呬繚鍏�</el-tag>
         </template>
         <template #operation="{ row }">
+          <!-- 杩欎釜鍔熻兘璺熸柊澧炰繚鍏诲姛鑳戒竴妯′竴鏍凤紝鏈夊暐鎰忎箟锛� -->
+          <!-- <el-button
+              type="primary"
+              text
+              @click="addMaintain(row)"
+          >
+            鏂板淇濆吇
+          </el-button> -->
           <el-button
             type="primary"
-            text
-            icon="editPen"
+            link
+            :disabled="row.status === 1"
             @click="editPlan(row.id)"
           >
             缂栬緫
           </el-button>
           <el-button
+            type="success"
+            link
+            :disabled="row.status === 1"
+            @click="addMaintain(row)"
+          >
+            淇濆吇
+          </el-button>
+          <el-button
             type="danger"
-            text
-            icon="delete"
+            link
+            :disabled="row.status === 1"
             @click="delRepairByIds(row.id)"
           >
             鍒犻櫎
+          </el-button>
+          <el-button
+            type="primary"
+            link
+            @click="openFileDialog(row)"
+          >
+            闄勪欢
           </el-button>
         </template>
       </PIMTable>
@@ -203,24 +224,41 @@
       </el-tab-pane>
     </el-tabs>
     <PlanModal ref="planModalRef" @ok="getTableData" />
-        <MaintenanceModal ref="maintainModalRef" @ok="getTableData" />
-        <FormDia ref="formDiaRef" @closeDia="getScheduledTableData" />
+    <MaintenanceModal ref="maintainModalRef" @ok="getTableData" />
+    <FormDia ref="formDiaRef" @closeDia="getScheduledTableData" />
+    <ApproveModal ref="approveModalRef" @ok="getScheduledTableData" />
+    <FileListDialog 
+      ref="fileListDialogRef"
+      v-model="fileDialogVisible"
+      :show-upload-button="true"
+      :show-delete-button="true"
+      :delete-method="handleAttachmentDelete"
+      :name-column-label="'闄勪欢鍚嶇О'"
+      :rulesRegulationsManagementId="currentMaintenanceTaskId"
+      @upload="handleAttachmentUpload" />
   </div>
 </template>
 
 <script setup>
-import { ref, onMounted, reactive, getCurrentInstance, nextTick } from 'vue'
+import { ref, onMounted, reactive, getCurrentInstance, nextTick, computed } from 'vue'
 import { Search } from '@element-plus/icons-vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
-import PlanModal from './Modal/PlanModal.vue'
-import MaintenanceModal from './Modal/MaintenanceModal.vue'
-import FormDia from './Modal/formDia.vue'
+import PlanModal from './Form/PlanModal.vue'
+import MaintenanceModal from './Form/MaintenanceModal.vue'
+import FormDia from './Form/formDia.vue'
+import ApproveModal from './Form/ApproveModal.vue'
+import FileListDialog from '@/components/Dialog/FileListDialog.vue'
 import {
   getUpkeepPage,
   delUpkeep,
   deviceMaintenanceTaskList,
   deviceMaintenanceTaskDel,
 } from '@/api/equipmentManagement/upkeep'
+import {
+  listMaintenanceTaskFiles,
+  addMaintenanceTaskFile,
+  delMaintenanceTaskFile,
+} from '@/api/equipmentManagement/maintenanceTaskFile'
 import dayjs from 'dayjs'
 
 const { proxy } = getCurrentInstance()
@@ -234,6 +272,12 @@
 const maintainModalRef = ref()
 // 瀹氭椂浠诲姟寮圭獥鎺у埗鍣�
 const formDiaRef = ref()
+// 淇濆吇瀹℃壒寮圭獥
+const approveModalRef = ref()
+// 闄勪欢寮圭獥
+const fileListDialogRef = ref(null)
+const fileDialogVisible = ref(false)
+const currentMaintenanceTaskId = ref(null)
 
 // 浠诲姟璁板綍tab锛堝師璁惧淇濆吇椤甸潰锛夌浉鍏冲彉閲�
 const filters = reactive({
@@ -307,6 +351,15 @@
 	},
 	{ prop: "registrant", label: "鐧昏浜�", minWidth: 100 },
 	{ prop: "registrationDate", label: "鐧昏鏃ユ湡", minWidth: 100 },
+	{ prop: "auditName", label: "瀹℃牳浜�", width: 120 },
+	{ prop: "supervisoryName", label: "鐩戠潱浜�", width: 120 },
+  {
+    label: "鐘舵��",
+    align: "center",
+    prop: "status",
+    dataType: "slot",
+    slot: "statusRef",
+  },
 	{
 		fixed: "right",
 		label: "鎿嶄綔",
@@ -379,7 +432,7 @@
 		dataType: "slot",
 		slot: "operation",
 		align: "center",
-		width: "200px",
+		width: "350px",
 	},
 ])
 
@@ -494,15 +547,24 @@
   multipleList.value = selection
 }
 
+// 妫�鏌ラ�変腑鐨勮褰曚腑鏄惁鏈夊畬缁撶姸鎬佺殑
+const hasFinishedStatus = computed(() => {
+  return multipleList.value.some(item => item.status === 1)
+})
+
 const changePage = (page) => {
   pagination.value.currentPage = page.page
   pagination.value.pageSize = page.limit
   getTableData()
 }
 
-const addMaintain = () => {
-  const row = multipleList.value[0]
+const addMaintain = (row) => {
   maintainModalRef.value.open(row.id, row)
+}
+
+// 瀹氭椂浠诲姟瀹℃壒
+const openScheduledApprove = (row) => {
+  approveModalRef.value.open(row)
 }
 
 const addPlan = () => {
@@ -514,6 +576,13 @@
 }
 
 const delRepairByIds = async (ids) => {
+  // 妫�鏌ユ槸鍚︽湁瀹岀粨鐘舵�佺殑璁板綍
+  const hasFinished = multipleList.value.some(item => item.status === 1)
+  if (hasFinished) {
+    ElMessage.warning('涓嶈兘鍒犻櫎鐘舵�佷负瀹岀粨鐨勮褰�')
+    return
+  }
+  
   try {
     await ElMessageBox.confirm('纭鍒犻櫎淇濆吇鏁版嵁, 姝ゆ搷浣滀笉鍙��?', '璀﹀憡', {
       confirmButtonText: '纭畾',
@@ -554,6 +623,79 @@
   getTableData()
 }
 
+// 闄勪欢鐩稿叧鏂规硶
+// 鏌ヨ闄勪欢鍒楄〃
+const fetchMaintenanceTaskFiles = async (deviceMaintenanceId) => {
+  try {
+    const params = {
+      current: 1,
+      size: 100,
+      deviceMaintenanceId,
+      rulesRegulationsManagementId:deviceMaintenanceId
+    }
+    const res = await listMaintenanceTaskFiles(params)
+    const records = res?.data?.records || []
+    const mapped = records.map(item => ({
+      id: item.id,
+      name: item.fileName || item.name,
+      url: item.fileUrl || item.url,
+      raw: item,
+    }))
+    fileListDialogRef.value?.setList(mapped)
+  } catch (error) {
+    ElMessage.error('鑾峰彇闄勪欢鍒楄〃澶辫触')
+  }
+}
+
+// 鎵撳紑闄勪欢寮圭獥
+const openFileDialog = async (row) => {
+  currentMaintenanceTaskId.value = row.id
+  fileDialogVisible.value = true
+  await fetchMaintenanceTaskFiles(row.id)
+}
+
+// 鍒锋柊闄勪欢鍒楄〃
+const refreshFileList = async () => {
+  if (!currentMaintenanceTaskId.value) return
+  await fetchMaintenanceTaskFiles(currentMaintenanceTaskId.value)
+}
+
+// 涓婁紶闄勪欢
+const handleAttachmentUpload = async (filePayload) => {
+  if (!currentMaintenanceTaskId.value) return
+  try {
+    const payload = {
+      name: filePayload?.fileName || filePayload?.name,
+      url: filePayload?.fileUrl || filePayload?.url,
+      deviceMaintenanceId: currentMaintenanceTaskId.value,
+    }
+    await addMaintenanceTaskFile(payload)
+    ElMessage.success('鏂囦欢涓婁紶鎴愬姛')
+    await refreshFileList()
+  } catch (error) {
+    ElMessage.error('鏂囦欢涓婁紶澶辫触')
+  }
+}
+
+// 鍒犻櫎闄勪欢
+const handleAttachmentDelete = async (row) => {
+  if (!row?.id) return false
+  try {
+    await ElMessageBox.confirm('纭鍒犻櫎璇ラ檮浠讹紵', '鎻愮ず', { type: 'warning' })
+  } catch {
+    return false
+  }
+  try {
+    await delMaintenanceTaskFile(row.id)
+    ElMessage.success('鍒犻櫎鎴愬姛')
+    await refreshFileList()
+    return true
+  } catch (error) {
+    ElMessage.error('鍒犻櫎澶辫触')
+    return false
+  }
+}
+
 onMounted(() => {
   // 鏍规嵁榛樿婵�娲荤殑 Tab 璋冪敤瀵瑰簲鐨勬煡璇㈡帴鍙�
   if (activeTab.value === 'scheduled') {

--
Gitblit v1.9.3