From a6dfc8e7c0ba4fa8ccd238f3469ff7fe803ef476 Mon Sep 17 00:00:00 2001
From: yuan <123@>
Date: 星期六, 23 五月 2026 14:14:19 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_pro_河南鹤壁' into dev_pro_河南鹤壁

---
 src/views/procurementManagement/procurementLedger/index.vue           | 3159 ++++++++++++++++++++-----------------------
 src/views/customerService/feedbackRegistration/components/formDia.vue |    4 
 src/views/customerService/feedbackRegistration/index.vue              |  825 +++++-----
 src/views/procurementManagement/procurementLedger/detail.vue          |  248 +++
 src/views/equipmentManagement/inspectionManagement/index.vue          |   67 
 5 files changed, 2,148 insertions(+), 2,155 deletions(-)

diff --git a/src/views/customerService/feedbackRegistration/components/formDia.vue b/src/views/customerService/feedbackRegistration/components/formDia.vue
index 790ddbe..fd3091e 100644
--- a/src/views/customerService/feedbackRegistration/components/formDia.vue
+++ b/src/views/customerService/feedbackRegistration/components/formDia.vue
@@ -63,10 +63,10 @@
               </el-form-item>
             </el-col>
             <el-col :span="4">
-              <el-form-item label="闂鎻忚堪锛�"
+              <el-form-item label="瀹㈡埛璇夋眰锛�"
                             prop="proDesc">
                 <el-input v-model="form.proDesc"
-                          placeholder="璇疯緭鍏ラ棶棰樻弿杩�" />
+                          placeholder="璇疯緭鍏ュ鎴疯瘔姹�" />
               </el-form-item>
             </el-col>
           </el-row>
diff --git a/src/views/customerService/feedbackRegistration/index.vue b/src/views/customerService/feedbackRegistration/index.vue
index 40d99be..4fd469b 100644
--- a/src/views/customerService/feedbackRegistration/index.vue
+++ b/src/views/customerService/feedbackRegistration/index.vue
@@ -1,13 +1,13 @@
 <template>
   <div class="app-container">
     <div class="workorder-stats">
-      <div
-          v-for="(item, index) in statsList"
-          :key="index"
-          class="stat-card"
-      >
-        <div class="stat-icon" :style="{ backgroundColor: item.bgColor }">
-          <el-icon :color="item.color" :size="20">
+      <div v-for="(item, index) in statsList"
+           :key="index"
+           class="stat-card">
+        <div class="stat-icon"
+             :style="{ backgroundColor: item.bgColor }">
+          <el-icon :color="item.color"
+                   :size="20">
             <component :is="item.icon" />
           </el-icon>
         </div>
@@ -18,84 +18,64 @@
       </div>
     </div>
     <div class="search-wrapper">
-      <el-form
-          :model="searchForm"
-          class="demo-form-inline"
-      >
+      <el-form :model="searchForm"
+               class="demo-form-inline">
         <el-row :gutter="20">
           <el-col :span="4">
             <el-form-item>
-              <el-input
-                  v-model="searchForm.afterSalesServiceNo"
-                  placeholder="璇疯緭鍏ュ伐鍗曠紪鍙�"
-                  clearable
-              />
+              <el-input v-model="searchForm.afterSalesServiceNo"
+                        placeholder="璇疯緭鍏ュ伐鍗曠紪鍙�"
+                        clearable />
             </el-form-item>
           </el-col>
           <el-col :span="4">
             <el-form-item>
-              <el-select
-                  v-model="searchForm.status"
-                  placeholder="璇烽�夋嫨宸ュ崟鐘舵��"
-                  clearable
-              >
-                <el-option
-                    v-for="dict in workOrderStatusOptions"
-                    :key="dict.value"
-                    :label="dict.label"
-                    :value="dict.value"
-                />
+              <el-select v-model="searchForm.status"
+                         placeholder="璇烽�夋嫨宸ュ崟鐘舵��"
+                         clearable>
+                <el-option v-for="dict in workOrderStatusOptions"
+                           :key="dict.value"
+                           :label="dict.label"
+                           :value="dict.value" />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="4">
             <el-form-item>
-              <el-select
-                  v-model="searchForm.urgency"
-                  placeholder="璇烽�夋嫨绱ф�ョ▼搴�"
-                  clearable
-              >
-                <el-option
-                    v-for="dict in degreeOfUrgencyOptions"
-                    :key="dict.value"
-                    :label="dict.label"
-                    :value="dict.value"
-                />
+              <el-select v-model="searchForm.urgency"
+                         placeholder="璇烽�夋嫨绱ф�ョ▼搴�"
+                         clearable>
+                <el-option v-for="dict in degreeOfUrgencyOptions"
+                           :key="dict.value"
+                           :label="dict.label"
+                           :value="dict.value" />
               </el-select>
             </el-form-item>
           </el-col>
-           <el-col :span="4">
+          <el-col :span="4">
             <el-form-item>
-              <el-select
-                  v-model="searchForm.serviceType"
-                  placeholder="璇烽�夋嫨鍞悗绫诲瀷"
-                  clearable
-              >
-                <el-option
-                    v-for="dict in classificationOptions"
-                    :key="dict.value"
-                    :label="dict.label"
-                    :value="dict.value"
-                />
+              <el-select v-model="searchForm.serviceType"
+                         placeholder="璇烽�夋嫨鍞悗绫诲瀷"
+                         clearable>
+                <el-option v-for="dict in classificationOptions"
+                           :key="dict.value"
+                           :label="dict.label"
+                           :value="dict.value" />
               </el-select>
             </el-form-item>
           </el-col>
-            <el-col :span="4">
-              <el-form-item>
-                <el-input
-                    v-model="searchForm.orderNo"
-                    placeholder="璇疯緭鍏ラ攢鍞崟鍙�"
-                    clearable
-                />
-              </el-form-item>
-            </el-col>
-          
-          
-
+          <el-col :span="4">
+            <el-form-item>
+              <el-input v-model="searchForm.orderNo"
+                        placeholder="璇疯緭鍏ラ攢鍞崟鍙�"
+                        clearable />
+            </el-form-item>
+          </el-col>
           <!-- 鎸夐挳 -->
           <el-col :span="4">
             <el-form-item>
-              <el-button type="primary" @click="handleQuery">
+              <el-button type="primary"
+                         @click="handleQuery">
                 鎼滅储
               </el-button>
               <el-button @click="handleReset">
@@ -107,310 +87,340 @@
       </el-form>
     </div>
     <div class="table_list">
-      <div class="table_header" style="display: flex; justify-content: space-between; align-items: center;">
+      <div class="table_header"
+           style="display: flex; justify-content: space-between; align-items: center;">
         <div>
-          <el-button type="primary" @click="openForm('add')">鏂板鍞悗鍗�</el-button>
+          <el-button type="primary"
+                     @click="openForm('add')">鏂板鍞悗鍗�</el-button>
         </div>
         <div>
           <el-button @click="handleOut">瀵煎嚭</el-button>
-          <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
+          <el-button type="danger"
+                     plain
+                     @click="handleDelete">鍒犻櫎</el-button>
         </div>
       </div>
-      <PIMTable
-          rowKey="id"
-          :column="tableColumn"
-          :tableData="tableData"
-          :page="page"
-          :height="tableHeight"
-          :isSelection="true"
-          @selection-change="handleSelectionChange"
-          :tableLoading="tableLoading"
-          @pagination="pagination"
-      ></PIMTable>
+      <PIMTable rowKey="id"
+                :column="tableColumn"
+                :tableData="tableData"
+                :page="page"
+                :height="tableHeight"
+                :isSelection="true"
+                @selection-change="handleSelectionChange"
+                :tableLoading="tableLoading"
+                @pagination="pagination"></PIMTable>
     </div>
-    <form-dia ref="formDia" @close="handleQuery"></form-dia>
+    <form-dia ref="formDia"
+              @close="handleQuery"></form-dia>
   </div>
 </template>
 
 <script setup>
-import {onMounted, reactive, ref, toRefs, computed, getCurrentInstance, nextTick} from "vue";
-import FormDia from "@/views/customerService/feedbackRegistration/components/formDia.vue";
-import {ElMessageBox} from "element-plus";
-import {afterSalesServiceDelete, afterSalesServiceListPage, getSalesLedgerDetail} from "@/api/customerService/index.js";
-import useUserStore from "@/store/modules/user.js";
-const { proxy } = getCurrentInstance();
-const userStore = useUserStore()
-import { Document, FolderOpened, UserFilled } from "@element-plus/icons-vue"
-import { markRaw } from 'vue'
+  import {
+    onMounted,
+    reactive,
+    ref,
+    toRefs,
+    computed,
+    getCurrentInstance,
+    nextTick,
+  } from "vue";
+  import FormDia from "@/views/customerService/feedbackRegistration/components/formDia.vue";
+  import { ElMessageBox } from "element-plus";
+  import {
+    afterSalesServiceDelete,
+    afterSalesServiceListPage,
+    getSalesLedgerDetail,
+  } from "@/api/customerService/index.js";
+  import useUserStore from "@/store/modules/user.js";
+  const { proxy } = getCurrentInstance();
+  const userStore = useUserStore();
+  import { Document, FolderOpened, UserFilled } from "@element-plus/icons-vue";
+  import { markRaw } from "vue";
 
-const statsList = ref([
-  {
-    icon: markRaw(Document),
-    count: 0,
-    label: '鍏ㄩ儴宸ュ崟',
-    color: '#4080ff',
-    bgColor: '#eaf2ff'
-  },
-  {
-    icon: markRaw(FolderOpened),
-    count: 0,
-    label: '宸插鐞�',
-    color: '#ff9a2e',
-    bgColor: '#fff5e6'
-  },
-  {
-    icon: markRaw(UserFilled),
-    count: 0,
-    label: '宸插畬鎴�',
-    color: '#00b42a',
-    bgColor: '#e6f7ed'
-  },
-])
-
-const data = reactive({
-  searchForm : {
-    customerName: "",
-    status: "",
-    urgency: "",
-    serviceType: "",
-    reviewStatus: "",
-    orderNo: "",
-  }
-});
-const { searchForm } = toRefs(data);
-
-const tableColumn = ref([
-  {
-    label: "宸ュ崟缂栧彿",
-    prop:"afterSalesServiceNo",
-    width: 150,
-    align: "center"
-  },
-  {
-    label: "閿�鍞崟鍙�",
-    prop:"salesContractNo",
-    width: 150,
-    align: "center"
-  },
-  {
-    label: "澶勭悊鐘舵��",
-    prop: "status",
-    dataType: "tag",
-    
-    formatData: (params) => {
-      if (params) {
-        let part = String(params)
-        const item = workOrderStatusOptions.value.find(item => item.value === part);
-        return item?.label || params; 
-      }
-      return null;
+  const statsList = ref([
+    {
+      icon: markRaw(Document),
+      count: 0,
+      label: "鍏ㄩ儴宸ュ崟",
+      color: "#4080ff",
+      bgColor: "#eaf2ff",
     },
-    formatType: (params) => {
-      if (params === 1) {
-        return "danger";
-      } else if (params === 2) {
-        return "success";
-      } else {
+    {
+      icon: markRaw(FolderOpened),
+      count: 0,
+      label: "宸插鐞�",
+      color: "#ff9a2e",
+      bgColor: "#fff5e6",
+    },
+    {
+      icon: markRaw(UserFilled),
+      count: 0,
+      label: "宸插畬鎴�",
+      color: "#00b42a",
+      bgColor: "#e6f7ed",
+    },
+  ]);
+
+  const data = reactive({
+    searchForm: {
+      customerName: "",
+      status: "",
+      urgency: "",
+      serviceType: "",
+      reviewStatus: "",
+      orderNo: "",
+    },
+  });
+  const { searchForm } = toRefs(data);
+
+  const tableColumn = ref([
+    {
+      label: "宸ュ崟缂栧彿",
+      prop: "afterSalesServiceNo",
+      width: 150,
+      align: "center",
+    },
+    {
+      label: "閿�鍞崟鍙�",
+      prop: "salesContractNo",
+      width: 150,
+      align: "center",
+    },
+    {
+      label: "澶勭悊鐘舵��",
+      prop: "status",
+      dataType: "tag",
+
+      formatData: params => {
+        if (params) {
+          let part = String(params);
+          const item = workOrderStatusOptions.value.find(
+            item => item.value === part
+          );
+          return item?.label || params;
+        }
         return null;
-      }
-    },
-    align: "center"
-  },
-  {
-    label: "鍙嶉鏃ユ湡",
-    prop: "feedbackDate",
-    width: 150,
-    align: "center"
-  },
-  {
-    label: "鐧昏浜�",
-    prop: "checkNickName",
-    align: "center"
-  },
-  {
-    label: "绱ф�ョ▼搴�",
-    prop: "urgency",
-    // 鏍规嵁degreeOfUrgencyOptions瀛楀吀鍘昏嚜鍔ㄥ尮閰�
-    formatData: (params) => {
-      if (params) {
-        const item = degreeOfUrgencyOptions.value.find(item => item.value === params);
-        return item?.label || params;
-      }
-      return null;
-    },
-    align: "center"
-  },
-  {
-    label: "鍞悗绫诲瀷",
-    prop: "serviceType",
-    // 鏍规嵁classificationOptions瀛楀吀鍘昏嚜鍔ㄥ尮閰�
-    formatData: (params) => {
-      if (params) {
-        const item = classificationOptions.value.find(item => item.value === params);
-        return item?.label || params;
-      }
-      return null;
-    },
-    align: "center"
-  },
-  {
-    label: "闂鎻忚堪",
-    prop: "proDesc",
-    width:300,
-  },
-  {
-    label: "鍏宠仈閮ㄩ棬",
-    prop: "deptName",
-    width: 200,
-    align: "center"
-  },
-  {
-    dataType: "action",
-    label: "鎿嶄綔",
-    fixed: 'right',
-    operation: [
-      {
-        name: "缂栬緫",
-        type: "text",
-        clickFun: (row) => {
-          console.log(row)
-          openForm("edit", row);
-        },
-        disabled: (row) => {
-          return row.status !== 1
+      },
+      formatType: params => {
+        if (params === 1) {
+          return "danger";
+        } else if (params === 2) {
+          return "success";
+        } else {
+          return null;
         }
       },
-    ],
-    align: "center"
-  },
-]);
-const tableData = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
-  current: 1,
-  size: 100,
-  total: 0,
-});
-const selectedRows = ref([]);
-const tableHeight = computed(() => "calc(100% -80px)");
-
-const handleReset = () => {
-  Object.keys(searchForm.value).forEach(key => {
-    searchForm.value[key] = ""
-  })
-  page.current = 1;
-  getList();
-}
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
-  selectedRows.value = selection;
-};
-const formDia = ref()
-
-// 瀛楀吀鑾峰彇
-/* 
-post_sale_waiting_list 鏂板鐨勫敭鍚庡垎绫�
-degree_of_urgency 鏂板鐨勭揣鎬ョ▼搴�
-work_order_status 涓婚〉鐨勫伐鍗曠姸鎬�
-review_status 棣栭〉鐨勫鏍哥姸鎬�
-*/
-const { post_sale_waiting_list, degree_of_urgency, work_order_status, review_status } = proxy.useDict(
-  "post_sale_waiting_list",
-  "degree_of_urgency",
-  "work_order_status",
-  "review_status"
-);
-
-const classificationOptions = computed(() => post_sale_waiting_list?.value || []);
-const degreeOfUrgencyOptions = computed(() => degree_of_urgency?.value || []);
-const workOrderStatusOptions = computed(() => work_order_status?.value || []);
-
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
-  page.current = 1;
-  getList();
-};
-const pagination = (obj) => {
-  page.current = obj.page;
-  page.size = obj.limit;
-  getList();
-};
-const getList = () => {
-  tableLoading.value = true;
-  getSalesLedgerDetails()
-  afterSalesServiceListPage({ ...searchForm.value, ...page }).then((res) => {
-    tableLoading.value = false;
-    tableData.value = res.data.records;
-    page.total = res.data.total;
+      align: "center",
+    },
+    {
+      label: "鍙嶉鏃ユ湡",
+      prop: "feedbackDate",
+      width: 150,
+      align: "center",
+    },
+    {
+      label: "鐧昏浜�",
+      prop: "checkNickName",
+      align: "center",
+    },
+    {
+      label: "绱ф�ョ▼搴�",
+      prop: "urgency",
+      // 鏍规嵁degreeOfUrgencyOptions瀛楀吀鍘昏嚜鍔ㄥ尮閰�
+      formatData: params => {
+        if (params) {
+          const item = degreeOfUrgencyOptions.value.find(
+            item => item.value === params
+          );
+          return item?.label || params;
+        }
+        return null;
+      },
+      align: "center",
+    },
+    {
+      label: "鍞悗绫诲瀷",
+      prop: "serviceType",
+      // 鏍规嵁classificationOptions瀛楀吀鍘昏嚜鍔ㄥ尮閰�
+      formatData: params => {
+        if (params) {
+          const item = classificationOptions.value.find(
+            item => item.value === params
+          );
+          return item?.label || params;
+        }
+        return null;
+      },
+      align: "center",
+    },
+    {
+      label: "瀹㈡埛璇夋眰",
+      prop: "proDesc",
+      width: 300,
+    },
+    {
+      label: "鍏宠仈閮ㄩ棬",
+      prop: "deptName",
+      width: 200,
+      align: "center",
+    },
+    {
+      dataType: "action",
+      label: "鎿嶄綔",
+      fixed: "right",
+      operation: [
+        {
+          name: "缂栬緫",
+          type: "text",
+          clickFun: row => {
+            console.log(row);
+            openForm("edit", row);
+          },
+          disabled: row => {
+            return row.status !== 1;
+          },
+        },
+      ],
+      align: "center",
+    },
+  ]);
+  const tableData = ref([]);
+  const tableLoading = ref(false);
+  const page = reactive({
+    current: 1,
+    size: 100,
+    total: 0,
   });
-};
+  const selectedRows = ref([]);
+  const tableHeight = computed(() => "calc(100% -80px)");
 
-// 鎵撳紑寮规
-const openForm = (type, row) => {
-  nextTick(() => {
-    formDia.value?.openDialog(type, row)
-  })
-};
+  const handleReset = () => {
+    Object.keys(searchForm.value).forEach(key => {
+      searchForm.value[key] = "";
+    });
+    page.current = 1;
+    getList();
+  };
+  // 琛ㄦ牸閫夋嫨鏁版嵁
+  const handleSelectionChange = selection => {
+    selectedRows.value = selection;
+  };
+  const formDia = ref();
 
-function handleDelete() {
-  let ids = [];
-  if (selectedRows.value.length > 0) {
-    // 妫�鏌ユ槸鍚︽湁浠栦汉缁存姢鐨勬暟鎹�
-    const unauthorizedData = selectedRows.value.filter(item => item.checkUserId !== userStore.id);
-    if (unauthorizedData.length > 0) {
-      proxy.$modal.msgWarning("涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�");
+  // 瀛楀吀鑾峰彇
+  /* 
+  post_sale_waiting_list 鏂板鐨勫敭鍚庡垎绫�
+  degree_of_urgency 鏂板鐨勭揣鎬ョ▼搴�
+  work_order_status 涓婚〉鐨勫伐鍗曠姸鎬�
+  review_status 棣栭〉鐨勫鏍哥姸鎬�
+  */
+  const {
+    post_sale_waiting_list,
+    degree_of_urgency,
+    work_order_status,
+    review_status,
+  } = proxy.useDict(
+    "post_sale_waiting_list",
+    "degree_of_urgency",
+    "work_order_status",
+    "review_status"
+  );
+
+  const classificationOptions = computed(
+    () => post_sale_waiting_list?.value || []
+  );
+  const degreeOfUrgencyOptions = computed(() => degree_of_urgency?.value || []);
+  const workOrderStatusOptions = computed(() => work_order_status?.value || []);
+
+  // 鏌ヨ鍒楄〃
+  /** 鎼滅储鎸夐挳鎿嶄綔 */
+  const handleQuery = () => {
+    page.current = 1;
+    getList();
+  };
+  const pagination = obj => {
+    page.current = obj.page;
+    page.size = obj.limit;
+    getList();
+  };
+  const getList = () => {
+    tableLoading.value = true;
+    getSalesLedgerDetails();
+    afterSalesServiceListPage({ ...searchForm.value, ...page }).then(res => {
+      tableLoading.value = false;
+      tableData.value = res.data.records;
+      page.total = res.data.total;
+    });
+  };
+
+  // 鎵撳紑寮规
+  const openForm = (type, row) => {
+    nextTick(() => {
+      formDia.value?.openDialog(type, row);
+    });
+  };
+
+  function handleDelete() {
+    let ids = [];
+    if (selectedRows.value.length > 0) {
+      // 妫�鏌ユ槸鍚︽湁浠栦汉缁存姢鐨勬暟鎹�
+      const unauthorizedData = selectedRows.value.filter(
+        item => item.checkUserId !== userStore.id
+      );
+      if (unauthorizedData.length > 0) {
+        proxy.$modal.msgWarning("涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�");
+        return;
+      }
+      ids = selectedRows.value.map(item => item.id);
+    } else {
+      proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
       return;
     }
-    ids = selectedRows.value.map((item) => item.id);
-  } else {
-    proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
-    return;
-  }
-  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
-    confirmButtonText: "纭",
-    cancelButtonText: "鍙栨秷",
-    type: "warning",
-  })
+    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
       .then(() => {
         tableLoading.value = true;
         afterSalesServiceDelete(ids)
-            .then(() => {
-              proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-              getList();
-            })
-            .finally(() => {
-              tableLoading.value = false;
-            });
+          .then(() => {
+            proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+            getList();
+          })
+          .finally(() => {
+            tableLoading.value = false;
+          });
       })
       .catch(() => {
         proxy.$modal.msg("宸插彇娑�");
       });
-};
+  }
 
-// 瀵煎嚭
-const handleOut = () => {
-  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
-    confirmButtonText: "纭",
-    cancelButtonText: "鍙栨秷",
-    type: "warning",
-  })
+  // 瀵煎嚭
+  const handleOut = () => {
+    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
       .then(() => {
         proxy.download("/afterSalesService/export", {}, "鍙嶉鐧昏.xlsx");
       })
       .catch(() => {
         proxy.$modal.msg("宸插彇娑�");
       });
-};
+  };
 
-const getStatsCountByStatus = (list, status) => {
-  if (!Array.isArray(list)) return 0;
-  return list.find((item) => item?.status === status)?.count || 0;
-};
+  const getStatsCountByStatus = (list, status) => {
+    if (!Array.isArray(list)) return 0;
+    return list.find(item => item?.status === status)?.count || 0;
+  };
 
   // 鑾峰彇缁熻鏁版嵁骞跺埛鏂伴《閮ㄥ崱鐗�
   const getSalesLedgerDetails = () => {
-    getSalesLedgerDetail({}).then((res) => {
+    getSalesLedgerDetail({}).then(res => {
       if (res.code === 200) {
         const statsData = Array.isArray(res.data) ? res.data : [];
         statsList.value[0].count = getStatsCountByStatus(statsData, 3);
@@ -418,99 +428,96 @@
         statsList.value[2].count = getStatsCountByStatus(statsData, 1);
       }
     });
-  }
+  };
 
-
-
-onMounted(() => {
-  getList();
-  
-});
+  onMounted(() => {
+    getList();
+  });
 </script>
 
 <style scoped lang="scss">
-.search-wrapper {
-  background: white;
-  padding: 1rem 1rem 0 1rem;
-  border: 8px;
-  border-radius: 16px;
-}
+  .search-wrapper {
+    background: white;
+    padding: 1rem 1rem 0 1rem;
+    border: 8px;
+    border-radius: 16px;
+  }
 
-.expand-btn {
-  width: 100%;
-  padding: 20px; /* 涓婁笅宸﹀彸鍚�20px锛岀偣鍑昏繖涓寖鍥撮兘鑳借Е鍙戜簨浠� */
-  cursor: pointer; /* 榧犳爣鎮诞鏄剧ず鎵嬪瀷锛屾彁鍗囦綋楠� */
-  text-align: center;
-}
+  .expand-btn {
+    width: 100%;
+    padding: 20px; /* 涓婁笅宸﹀彸鍚�20px锛岀偣鍑昏繖涓寖鍥撮兘鑳借Е鍙戜簨浠� */
+    cursor: pointer; /* 榧犳爣鎮诞鏄剧ず鎵嬪瀷锛屾彁鍗囦綋楠� */
+    text-align: center;
+  }
 
-.workorder-stats {
-  display: flex;
-  gap: 16px;
-  padding-bottom:1rem;
-  border-radius: 8px;
-}
+  .workorder-stats {
+    display: flex;
+    gap: 16px;
+    padding-bottom: 1rem;
+    border-radius: 8px;
+  }
 
-.stat-card {
-  flex: 1;
-  display: flex;
-  align-items: center;
-  gap: 12px;
-  padding: 20px;
-  background-color: #fff;
-  border-radius: 8px;
-  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.06);
-}
+  .stat-card {
+    flex: 1;
+    display: flex;
+    align-items: center;
+    gap: 12px;
+    padding: 20px;
+    background-color: #fff;
+    border-radius: 8px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.06);
+  }
 
-.stat-icon {
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  width: 48px;
-  height: 48px;
-  border-radius: 8px;
-}
+  .stat-icon {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    width: 48px;
+    height: 48px;
+    border-radius: 8px;
+  }
 
-.stat-info {
-  display: flex;
-  flex-direction: column;
-  gap: 4px;
-}
+  .stat-info {
+    display: flex;
+    flex-direction: column;
+    gap: 4px;
+  }
 
-.stat-number {
-  font-size: 24px;
-  font-weight: 600;
-  color: #303133;
-  line-height: 1;
-}
+  .stat-number {
+    font-size: 24px;
+    font-weight: 600;
+    color: #303133;
+    line-height: 1;
+  }
 
-.stat-label {
-  font-size: 14px;
-  color: #909399;
-  line-height: 1;
-}
-.table_header{
-  padding-bottom: 10px;
-}
+  .stat-label {
+    font-size: 14px;
+    color: #909399;
+    line-height: 1;
+  }
+  .table_header {
+    padding-bottom: 10px;
+  }
 
-.table_list {
-  height: calc(100vh - 380px);
-  background: #fff;
-  margin-top: 20px;
-  display: flex;
-  flex-direction: column;
-}
+  .table_list {
+    height: calc(100vh - 380px);
+    background: #fff;
+    margin-top: 20px;
+    display: flex;
+    flex-direction: column;
+  }
 
-:deep(.table_list .pagination-container) {
-  display: flex;
-  justify-content: flex-end;
-  align-items: center;
-  margin-top: auto;
-  padding: 12px 0 0;
-}
+  :deep(.table_list .pagination-container) {
+    display: flex;
+    justify-content: flex-end;
+    align-items: center;
+    margin-top: auto;
+    padding: 12px 0 0;
+  }
 
-:deep(.table_list .el-pagination) {
-  flex-wrap: nowrap;
-  justify-content: flex-end;
-  width: 100%;
-}
+  :deep(.table_list .el-pagination) {
+    flex-wrap: nowrap;
+    justify-content: flex-end;
+    width: 100%;
+  }
 </style>
diff --git a/src/views/equipmentManagement/inspectionManagement/index.vue b/src/views/equipmentManagement/inspectionManagement/index.vue
index c863719..8c0d52c 100644
--- a/src/views/equipmentManagement/inspectionManagement/index.vue
+++ b/src/views/equipmentManagement/inspectionManagement/index.vue
@@ -52,7 +52,8 @@
                   total: total,
                   layout: 'total, sizes, prev, pager, next, jumper'
                 }"
-                  :table-style="{ width: '100%', height: 'calc(100vh - 23em)' }">
+                  height="calc(100vh - 23em)"
+                  :table-style="{ width: '100%' }">
           <template #inspector="{ row }">
             <div class="person-tags">
               <!-- 璋冭瘯淇℃伅锛屼笂绾挎椂鍒犻櫎 -->
@@ -121,8 +122,8 @@
   // 鍗曢�夋閰嶇疆
   const activeRadio = ref("taskManage");
   const radios = reactive([
-    { name: "taskManage", label: "瀹氭椂浠诲姟绠$悊" },
-    { name: "task", label: "瀹氭椂浠诲姟璁板綍" },
+    { name: "taskManage", label: "宸℃浠诲姟" },
+    { name: "task", label: "宸℃璁板綍" },
   ]);
 
   // 琛ㄦ牸鏁版嵁
@@ -137,10 +138,10 @@
 
   // 鍒楅厤缃�
   const columns = ref([
-    { prop: "taskName", label: "宸℃浠诲姟鍚嶇О", minWidth: 160 },
-    { prop: "inspectionProject", label: "宸℃椤圭洰", minWidth: 150 },
-    { prop: "remarks", label: "澶囨敞", minWidth: 150 },
-    { prop: "inspector", label: "鎵ц宸℃浜�", minWidth: 150, slot: "inspector" },
+    { prop: "taskName", label: "宸℃浠诲姟鍚嶇О", minWidth: 200 },
+    { prop: "inspectionProject", label: "宸℃椤圭洰", minWidth: 180 },
+    { prop: "remarks", label: "澶囨敞", minWidth: 180 },
+    { prop: "inspector", label: "鎵ц宸℃浜�", minWidth: 180, slot: "inspector" },
     {
       prop: "isEnabled",
       label: "鏄惁鍚敤",
@@ -151,13 +152,7 @@
     {
       prop: "frequencyType",
       label: "棰戞",
-      minWidth: 150,
-      // formatter: (_, __, val) => ({
-      //   DAILY: "姣忔棩",
-      //   WEEKLY: "姣忓懆",
-      //   MONTHLY: "姣忔湀",
-      //   QUARTERLY: "瀛e害"
-      // }[val] || "")
+      minWidth: 120,
       formatData: params => {
         return params === "DAILY"
           ? "姣忔棩"
@@ -173,7 +168,7 @@
     {
       prop: "frequencyDetail",
       label: "寮�濮嬫棩鏈熶笌鏃堕棿",
-      minWidth: 150,
+      minWidth: 200,
       formatter: (row, column, cellValue) => {
         // 鍏堝垽鏂槸鍚︽槸瀛楃涓�
         if (typeof cellValue !== "string") return "";
@@ -194,11 +189,11 @@
         );
       },
     },
-    { prop: "registrant", label: "鐧昏浜�", minWidth: 100 },
+    { prop: "registrant", label: "鐧昏浜�", minWidth: 120 },
     {
       prop: "createTime",
       label: "鐧昏鏃ユ湡",
-      minWidth: 100,
+      minWidth: 180,
       formatData: cell => {
         if (!cell) return "-";
         try {
@@ -208,19 +203,19 @@
         }
       },
     },
-    {
-      prop: "inspectionResult",
-      label: "宸℃缁撴灉",
-      minWidth: 100,
-      dataType: "tag",
-      formatData: val => {
-        return val == 1 ? "姝e父" : "寮傚父";
-      },
-      formatType: val => {
-        return val == 1 ? "success" : "danger";
-      },
-    },
-    { prop: "abnormalDescription", label: "寮傚父鎻忚堪", minWidth: 100 },
+    // {
+    //   prop: "inspectionResult",
+    //   label: "宸℃缁撴灉",
+    //   minWidth: 100,
+    //   dataType: "tag",
+    //   formatData: val => {
+    //     return val == 1 ? "姝e父" : "寮傚父";
+    //   },
+    //   formatType: val => {
+    //     return val == 1 ? "success" : "danger";
+    //   },
+    // },
+    { prop: "abnormalDescription", label: "寮傚父鎻忚堪", minWidth: 150 },
   ]);
 
   // 鎿嶄綔鍒楅厤缃�
@@ -231,7 +226,7 @@
       label: "鎿嶄綔",
       width: operations.length > 1 ? 180 : 130,
       fixed: "right",
-			align: 'center',
+      align: "center",
       dataType: "action",
       operation: operations
         .map(op => {
@@ -279,7 +274,7 @@
       operationsArr.value = ["edit"];
     } else if (value === "task") {
       const operationColumn = getOperationColumn(["upload", "viewFile"]);
-      // 瀹氭椂浠诲姟璁板綍涓嶅睍绀�"鏄惁鍚敤"鍒�
+      // 宸℃璁板綍涓嶅睍绀�"鏄惁鍚敤"鍒�
       const taskColumns = columns.value.filter(col => col.prop !== "isEnabled");
       tableColumns.value = [
         ...taskColumns,
@@ -422,11 +417,11 @@
       .then(() => {
         // 鏍规嵁褰撳墠閫変腑鐨勬爣绛鹃〉璋冪敤涓嶅悓鐨勫鍑烘帴鍙�
         if (activeRadio.value === "taskManage") {
-          // 瀹氭椂浠诲姟绠$悊
-          proxy.download("/timingTask/export", {}, "瀹氭椂浠诲姟绠$悊.xlsx");
+          // 宸℃浠诲姟
+          proxy.download("/timingTask/export", {}, "宸℃浠诲姟.xlsx");
         } else if (activeRadio.value === "task") {
-          // 瀹氭椂浠诲姟璁板綍
-          proxy.download("/inspectionTask/export", {}, "瀹氭椂浠诲姟璁板綍.xlsx");
+          // 宸℃璁板綍
+          proxy.download("/inspectionTask/export", {}, "宸℃璁板綍.xlsx");
         }
       })
       .catch(() => {
diff --git a/src/views/procurementManagement/procurementLedger/detail.vue b/src/views/procurementManagement/procurementLedger/detail.vue
new file mode 100644
index 0000000..c1dd275
--- /dev/null
+++ b/src/views/procurementManagement/procurementLedger/detail.vue
@@ -0,0 +1,248 @@
+<template>
+  <FormDialog v-model="visible" title="閲囪喘鍙拌处璇︽儏" width="70%" operation-type="detail" @close="handleClose">
+    <el-form :model="form" label-width="140px" label-position="top">
+      <el-row :gutter="30">
+        <el-col :span="12">
+          <el-form-item label="閲囪喘鍚堝悓鍙凤細">
+            <span class="readonly-text">{{ form.purchaseContractNumber || '--' }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="閿�鍞悎鍚屽彿锛�">
+            <span class="readonly-text">{{ form.salesContractNo || '--' }}</span>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="30">
+        <el-col :span="12">
+          <el-form-item label="渚涘簲鍟嗗悕绉帮細">
+            <span class="readonly-text">{{ form.supplierName || '--' }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="椤圭洰鍚嶇О锛�">
+            <span class="readonly-text">{{ form.projectName || '--' }}</span>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="30">
+        <el-col :span="12">
+          <el-form-item label="浠樻鏂瑰紡锛�">
+            <span class="readonly-text">{{ form.paymentMethod || '--' }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="绛捐鏃ユ湡锛�">
+            <span class="readonly-text">{{ form.executionDate || '--' }}</span>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="30">
+        <el-col :span="12">
+          <el-form-item label="褰曞叆浜猴細">
+            <span class="readonly-text">{{ form.recorderName || '--' }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="褰曞叆鏃ユ湡锛�">
+            <span class="readonly-text">{{ form.entryDate || '--' }}</span>
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <div style="font-weight: bold; margin: 10px 0; color: #f56c6c">
+        * 浜у搧淇℃伅锛�
+      </div>
+      <el-table :data="productData" border>
+        <el-table-column type="index" label="搴忓彿" width="60" align="center" />
+        <el-table-column label="浜у搧澶х被" prop="productCategory" />
+        <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
+        <el-table-column label="鍗曚綅" prop="unit" />
+        <el-table-column label="鏁伴噺" prop="quantity" />
+        <el-table-column label="搴撳瓨棰勭暀鏁伴噺" prop="stockReservedQuantity" />
+        <el-table-column label="绋庣巼(%)" prop="taxRate" />
+        <el-table-column label="鍚◣鍗曚环(鍏�)" prop="taxInclusiveUnitPrice" :formatter="formattedNumber" width="150" />
+        <el-table-column label="鍚◣鎬讳环(鍏�)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" width="150" />
+        <el-table-column label="涓嶅惈绋庢�讳环(鍏�)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" width="150" />
+        <template #append>
+          <div class="summary-row" v-if="productData.length > 0">
+            <div class="summary-label">鍚堣</div>
+            <div class="summary-value" style="width: 150px">
+              {{ formattedNumber(null, null, sumTaxInclusiveUnitPrice) }}
+            </div>
+            <div class="summary-value" style="width: 150px">
+              {{ formattedNumber(null, null, sumTaxInclusiveTotalPrice) }}
+            </div>
+            <div class="summary-value" style="width: 150px">
+              {{ formattedNumber(null, null, sumTaxExclusiveTotalPrice) }}
+            </div>
+          </div>
+        </template>
+      </el-table>
+
+      <el-row :gutter="30" style="margin-top: 20px;">
+        <el-col :span="24">
+          <el-form-item label="澶囨敞锛�">
+            <div class="readonly-text-area">{{ form.remarks || '--' }}</div>
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row :gutter="30">
+        <el-col :span="24">
+          <el-form-item label="闄勪欢鏉愭枡锛�">
+            <div class="table-container" style="width: 100%;">
+              <el-table :data="fileList" border class="attachment-table" style="width: 100%;"
+                :height="fileList.length > 0 ? 'auto' : '120px'">
+                <el-table-column label="闄勪欢鍚嶇О" prop="originalFilename" show-overflow-tooltip min-width="200">
+                  <template #default="scope">
+                    {{ scope.row.name || scope.row.originalFilename || ('闄勪欢' + (scope.$index + 1)) }}
+                  </template>
+                </el-table-column>
+                <el-table-column fixed="right" label="鎿嶄綔" :width="150" align="center">
+                  <template #default="scope">
+                    <el-button link type="primary" size="small" class="download-link"
+                      @click="previewFile(scope.row.previewURL || scope.row.url)">
+                      棰勮
+                    </el-button>
+                    <el-button link type="primary" size="small" class="download-link"
+                      @click="downloadFile(scope.row.downloadURL || scope.row.url)">
+                      涓嬭浇
+                    </el-button>
+                  </template>
+                </el-table-column>
+              </el-table>
+            </div>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+  </FormDialog>
+  <filePreview ref="filePreviewRef" />
+</template>
+
+<script setup>
+import { ref, computed } from 'vue'
+import { ElMessage } from 'element-plus'
+import FormDialog from "@/components/Dialog/FormDialog.vue"
+import filePreview from '@/components/filePreview/index.vue'
+import { getPurchaseById } from "@/api/procurementManagement/procurementLedger"
+
+const visible = ref(false)
+const form = ref({})
+const productData = ref([])
+const fileList = ref([])
+const filePreviewRef = ref()
+
+const open = (id) => {
+  visible.value = true
+  getPurchaseById({ id: id, type: 2 }).then(res => {
+    form.value = res.data ? res.data : res || {}
+    productData.value = form.value.purchaseLedgerProductList || form.value.productData || []
+    fileList.value = form.value.storageBlobVOS || []
+  })
+}
+
+// 鏆撮湶 open 鏂规硶缁欑埗缁勪欢璋冪敤
+defineExpose({
+  open
+})
+
+const handleClose = () => {
+  visible.value = false
+  form.value = {}
+  productData.value = []
+  fileList.value = []
+}
+
+const formattedNumber = (row, column, cellValue) => {
+  if (cellValue != null && !isNaN(cellValue)) {
+    return Number(cellValue).toFixed(2)
+  }
+  return cellValue
+}
+
+const sumTaxInclusiveUnitPrice = computed(() => {
+  return productData.value.reduce((sum, item) => {
+    return sum + (Number(item.taxInclusiveUnitPrice) || 0)
+  }, 0)
+})
+
+const sumTaxInclusiveTotalPrice = computed(() => {
+  return productData.value.reduce((sum, item) => {
+    return sum + (Number(item.taxInclusiveTotalPrice) || 0)
+  }, 0)
+})
+
+const sumTaxExclusiveTotalPrice = computed(() => {
+  return productData.value.reduce((sum, item) => {
+    return sum + (Number(item.taxExclusiveTotalPrice) || 0)
+  }, 0)
+})
+
+const previewFile = (url) => {
+  if (url) {
+    filePreviewRef.value.open(url)
+  } else {
+    ElMessage.warning('鏂囦欢鍦板潃鏃犳晥锛屾棤娉曢瑙�')
+  }
+}
+
+const downloadFile = (url) => {
+  window.open(url, "_blank")
+}
+</script>
+
+<style scoped>
+.readonly-text {
+  width: 100%;
+  padding: 0 12px;
+  background-color: #f5f7fa;
+  color: #606266;
+  border-radius: 4px;
+  border: 1px solid #e4e7ed;
+  box-sizing: border-box;
+  min-height: 32px;
+  line-height: 32px;
+  display: inline-block;
+}
+
+.readonly-text-area {
+  width: 100%;
+  padding: 8px 12px;
+  background-color: #f5f7fa;
+  color: #606266;
+  border-radius: 4px;
+  border: 1px solid #e4e7ed;
+  box-sizing: border-box;
+  min-height: 64px;
+  line-height: 1.5;
+  white-space: pre-wrap;
+  word-break: break-all;
+}
+
+.summary-row {
+  display: flex;
+  background-color: #f5f7fa;
+  font-weight: bold;
+  border-top: 1px solid #ebeef5;
+}
+
+.summary-label {
+  flex: 1;
+  text-align: right;
+  padding: 12px;
+  color: #606266;
+}
+
+.summary-value {
+  padding: 12px;
+  color: #606266;
+  border-left: 1px solid #ebeef5;
+}
+
+.table-container {
+  overflow-y: auto;
+  box-sizing: border-box;
+}
+</style>
diff --git a/src/views/procurementManagement/procurementLedger/index.vue b/src/views/procurementManagement/procurementLedger/index.vue
index dad6a26..e4328aa 100644
--- a/src/views/procurementManagement/procurementLedger/index.vue
+++ b/src/views/procurementManagement/procurementLedger/index.vue
@@ -2,63 +2,37 @@
   <div class="app-container">
     <div class="search_form">
       <div>
-        <el-form :model="searchForm"
-                 :inline="true">
+        <el-form :model="searchForm" :inline="true">
           <el-form-item label="渚涘簲鍟嗗悕绉帮細">
-            <el-input v-model="searchForm.supplierName"
-                      placeholder="璇疯緭鍏�"
-                      clearable
-                      prefix-icon="Search"
-                      @change="handleQuery" />
+            <el-input v-model="searchForm.supplierName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
+              @change="handleQuery" />
           </el-form-item>
           <el-form-item label="閲囪喘鍚堝悓鍙凤細">
-            <el-input v-model="searchForm.purchaseContractNumber"
-                      style="width: 240px"
-                      placeholder="璇疯緭鍏�"
-                      @change="handleQuery"
-                      clearable
-                      :prefix-icon="Search" />
+            <el-input v-model="searchForm.purchaseContractNumber" style="width: 240px" placeholder="璇疯緭鍏�"
+              @change="handleQuery" clearable :prefix-icon="Search" />
           </el-form-item>
           <el-form-item label="閿�鍞悎鍚屽彿锛�">
-            <el-input v-model="searchForm.salesContractNo"
-                      placeholder="璇疯緭鍏�"
-                      clearable
-                      prefix-icon="Search"
-                      @change="handleQuery" />
+            <el-input v-model="searchForm.salesContractNo" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
+              @change="handleQuery" />
           </el-form-item>
           <el-form-item label="椤圭洰鍚嶇О锛�">
-            <el-input v-model="searchForm.projectName"
-                      placeholder="璇疯緭鍏�"
-                      clearable
-                      prefix-icon="Search"
-                      @change="handleQuery" />
+            <el-input v-model="searchForm.projectName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
+              @change="handleQuery" />
           </el-form-item>
           <el-form-item label="褰曞叆鏃ユ湡锛�">
-            <el-date-picker v-model="searchForm.entryDate"
-                            value-format="YYYY-MM-DD"
-                            format="YYYY-MM-DD"
-                            type="daterange"
-                            placeholder="璇烽�夋嫨"
-                            clearable
-                            @change="changeDaterange" />
+            <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
+              type="daterange" placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
           </el-form-item>
           <el-form-item label="鍏ュ簱鐘舵�侊細">
-            <el-select v-model="searchForm.stockInStatus"
-                       placeholder="璇烽�夋嫨"
-                       clearable
-                       style="width: 240px"
-                       @change="handleQuery">
-              <el-option label="寰呭叆搴�"
-                         value="寰呭叆搴�" />
-              <el-option label="鍏ュ簱涓�"
-                         value="鍏ュ簱涓�" />
-              <el-option label="瀹屽叏鍏ュ簱"
-                         value="瀹屽叏鍏ュ簱" />
+            <el-select v-model="searchForm.stockInStatus" placeholder="璇烽�夋嫨" clearable style="width: 240px"
+              @change="handleQuery">
+              <el-option label="寰呭叆搴�" value="寰呭叆搴�" />
+              <el-option label="鍏ュ簱涓�" value="鍏ュ簱涓�" />
+              <el-option label="瀹屽叏鍏ュ簱" value="瀹屽叏鍏ュ簱" />
             </el-select>
           </el-form-item>
           <el-form-item>
-            <el-button type="primary"
-                       @click="handleQuery"> 鎼滅储
+            <el-button type="primary" @click="handleQuery"> 鎼滅储
             </el-button>
           </el-form-item>
         </el-form>
@@ -66,417 +40,212 @@
     </div>
     <div class="table_list">
       <div style="display: flex;justify-content: flex-end;margin-bottom: 20px;">
-        <el-button type="primary"
-                   @click="openForm('add')">鏂板鍙拌处</el-button>
-        <el-button type="primary"
-                   plain
-                   @click="handleImport">瀵煎叆</el-button>
+        <el-button type="primary" @click="openForm('add')">鏂板鍙拌处</el-button>
+        <el-button type="primary" plain @click="handleImport">瀵煎叆</el-button>
         <el-button @click="handleOut">瀵煎嚭</el-button>
-        <el-button type="danger"
-                   plain
-                   @click="handleDelete">鍒犻櫎
+        <el-button type="danger" plain @click="handleDelete">鍒犻櫎
         </el-button>
       </div>
-      <el-table :data="tableData"
-                border
-                v-loading="tableLoading"
-                @selection-change="handleSelectionChange"
-                :expand-row-keys="expandedRowKeys"
-                :row-key="(row) => row.id"
-                show-summary
-                :summary-method="summarizeMainTable"
-                @expand-change="expandChange"
-                height="calc(100vh - 21.5em)">
-        <el-table-column align="center"
-                         type="selection"
-                         width="55" />
+      <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange"
+        :expand-row-keys="expandedRowKeys" :row-key="(row) => row.id" show-summary :summary-method="summarizeMainTable"
+        @expand-change="expandChange" height="calc(100vh - 21.5em)">
+        <el-table-column align="center" type="selection" width="55" />
         <el-table-column type="expand">
           <template #default="props">
-            <el-table :data="props.row.children"
-                      border
-                      show-summary
-                      :summary-method="summarizeChildrenTable">
-              <el-table-column align="center"
-                               label="搴忓彿"
-                               type="index"
-                               width="60" />
-              <el-table-column label="浜у搧澶х被"
-                               prop="productCategory" />
-              <el-table-column label="瑙勬牸鍨嬪彿"
-                               prop="specificationModel" />
-              <el-table-column label="鍗曚綅"
-                               prop="unit" />
-                               <el-table-column label="鍏ュ簱瀹℃牳鐘舵��"
-                               prop="stockInApprovalStatus"
-                               width="120">
+            <el-table :data="props.row.children" border show-summary :summary-method="summarizeChildrenTable">
+              <el-table-column align="center" label="搴忓彿" type="index" width="60" />
+              <el-table-column label="浜у搧澶х被" prop="productCategory" />
+              <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
+              <el-table-column label="鍗曚綅" prop="unit" />
+              <el-table-column label="鍏ュ簱瀹℃牳鐘舵��" prop="stockInApprovalStatus" width="120">
                 <template #default="scope">
-                  <el-tag :type="getStockInApprovalStatusType(scope.row.stockInApprovalStatus)"
-                          size="small">
+                  <el-tag :type="getStockInApprovalStatusType(scope.row.stockInApprovalStatus)" size="small">
                     {{ scope.row.stockInApprovalStatus || '--' }}
                   </el-tag>
                 </template>
               </el-table-column>
-              <el-table-column label="鏁伴噺"
-                               prop="quantity" />
-              <el-table-column label="鍙敤鏁伴噺"
-                               prop="availableQuality" />
-              <el-table-column label="閫�璐ф暟閲�"
-                               prop="returnQuality" />
-              <el-table-column label="绋庣巼(%)"
-                               prop="taxRate" />
-              <el-table-column label="鍚◣鍗曚环(鍏�)"
-                               prop="taxInclusiveUnitPrice"
-                               :formatter="formattedNumber" />
-              <el-table-column label="鍚◣鎬讳环(鍏�)"
-                               prop="taxInclusiveTotalPrice"
-                               :formatter="formattedNumber" />
-              <el-table-column label="涓嶅惈绋庢�讳环(鍏�)"
-                               prop="taxExclusiveTotalPrice"
-                               :formatter="formattedNumber" />
+              <el-table-column label="鏁伴噺" prop="quantity" />
+              <el-table-column label="鍙敤鏁伴噺" prop="availableQuality" />
+              <el-table-column label="閫�璐ф暟閲�" prop="returnQuality" />
+              <el-table-column label="绋庣巼(%)" prop="taxRate" />
+              <el-table-column label="鍚◣鍗曚环(鍏�)" prop="taxInclusiveUnitPrice" :formatter="formattedNumber" />
+              <el-table-column label="鍚◣鎬讳环(鍏�)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" />
+              <el-table-column label="涓嶅惈绋庢�讳环(鍏�)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" />
             </el-table>
           </template>
         </el-table-column>
-        <el-table-column align="center"
-                         label="搴忓彿"
-                         type="index"
-                         width="60" />
-        <el-table-column label="閲囪喘鍚堝悓鍙�"
-                         prop="purchaseContractNumber"
-                         width="160"
-                         show-overflow-tooltip />
-        <el-table-column label="閿�鍞悎鍚屽彿"
-                         prop="salesContractNo"
-                         width="160"
-                         show-overflow-tooltip />
-        <el-table-column label="渚涘簲鍟嗗悕绉�"
-                         prop="supplierName"
-                         width="160"
-                         show-overflow-tooltip />
-        <el-table-column label="椤圭洰鍚嶇О"
-                         prop="projectName"
-                         width="320"
-                         show-overflow-tooltip />
-        <el-table-column label="瀹℃壒鐘舵��"
-                         prop="approvalStatus"
-                         width="100"
-                         show-overflow-tooltip>
+        <el-table-column align="center" label="搴忓彿" type="index" width="60" />
+        <el-table-column label="閲囪喘鍚堝悓鍙�" prop="purchaseContractNumber" width="160" show-overflow-tooltip />
+        <el-table-column label="閿�鍞悎鍚屽彿" prop="salesContractNo" width="160" show-overflow-tooltip />
+        <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" width="160" show-overflow-tooltip />
+        <el-table-column label="椤圭洰鍚嶇О" prop="projectName" width="320" show-overflow-tooltip />
+        <el-table-column label="瀹℃壒鐘舵��" prop="approvalStatus" width="100" show-overflow-tooltip>
           <template #default="scope">
-            <el-tag :type="getApprovalStatusType(scope.row.approvalStatus)"
-                    size="small">
+            <el-tag :type="getApprovalStatusType(scope.row.approvalStatus)" size="small">
               {{ approvalStatusText[scope.row.approvalStatus] || '鏈煡鐘舵��' }}
             </el-tag>
           </template>
         </el-table-column>
-        <el-table-column label="鍏ュ簱鐘舵��"
-                         prop="stockInStatus"
-                         width="100"
-                         show-overflow-tooltip>
+        <el-table-column label="鍏ュ簱鐘舵��" prop="stockInStatus" width="100" show-overflow-tooltip>
           <template #default="scope">
-            <el-tag :type="getStockInStatusType(scope.row.stockInStatus)"
-                    size="small">
+            <el-tag :type="getStockInStatusType(scope.row.stockInStatus)" size="small">
               {{ scope.row.stockInStatus || '--' }}
             </el-tag>
           </template>
         </el-table-column>
-        <el-table-column label="绛捐鏃ユ湡"
-                         prop="executionDate"
-                         width="100"
-                         show-overflow-tooltip />
-        <el-table-column label="浠樻鏂瑰紡"
-                         width="100"
-                         prop="paymentMethod"
-                         show-overflow-tooltip />
-        <el-table-column label="鍚堝悓閲戦(鍏�)"
-                         prop="contractAmount"
-                         width="200"
-                         show-overflow-tooltip
-                         :formatter="formattedNumber" />
-        <el-table-column label="褰曞叆浜�"
-                         prop="recorderName"
-                         width="120"
-                         show-overflow-tooltip />
-        <el-table-column label="褰曞叆鏃ユ湡"
-                         prop="entryDate"
-                         width="100"
-                         show-overflow-tooltip />
-        <el-table-column label="澶囨敞"
-                         prop="remarks"
-                         width="200"
-                         show-overflow-tooltip />
-        <el-table-column fixed="right"
-                         label="鎿嶄綔"
-                         width="120"
-                         align="center">
+        <el-table-column label="绛捐鏃ユ湡" prop="executionDate" width="100" show-overflow-tooltip />
+        <el-table-column label="浠樻鏂瑰紡" width="100" prop="paymentMethod" show-overflow-tooltip />
+        <el-table-column label="鍚堝悓閲戦(鍏�)" prop="contractAmount" width="200" show-overflow-tooltip
+          :formatter="formattedNumber" />
+        <el-table-column label="褰曞叆浜�" prop="recorderName" width="120" show-overflow-tooltip />
+        <el-table-column label="褰曞叆鏃ユ湡" prop="entryDate" width="100" show-overflow-tooltip />
+        <el-table-column label="澶囨敞" prop="remarks" width="200" show-overflow-tooltip />
+        <el-table-column fixed="right" label="鎿嶄綔" width="180" align="center">
           <template #default="scope">
-            <el-button link
-                       type="primary"
-                       @click="openForm('edit', scope.row)"
-                       :disabled="scope.row.stockInStatus === '瀹屽叏鍏ュ簱'">缂栬緫
+            <el-button link type="primary" @click="openForm('detail', scope.row)">璇︽儏
             </el-button>
-            <el-button link
-                       type="primary"
-                       @click="openFileDialog(scope.row)">闄勪欢</el-button>
+            <el-button link type="primary" @click="openForm('edit', scope.row)"
+              :disabled="scope.row.stockInStatus === '瀹屽叏鍏ュ簱'">缂栬緫
+            </el-button>
+            <el-button link type="primary" @click="openFileDialog(scope.row)">闄勪欢</el-button>
           </template>
         </el-table-column>
       </el-table>
-      <pagination v-show="total > 0"
-                  :total="total"
-                  layout="total, sizes, prev, pager, next, jumper"
-                  :page="page.current"
-                  :limit="page.size"
-                  @pagination="paginationChange" />
+      <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper"
+        :page="page.current" :limit="page.size" @pagination="paginationChange" />
     </div>
     <FormDialog v-model="dialogFormVisible"
-                :title="operationType === 'add' ? '鏂板閲囪喘鍙拌处椤甸潰' : '缂栬緫閲囪喘鍙拌处椤甸潰'"
-                :width="'70%'"
-                :operation-type="operationType"
-                @close="closeDia"
-                @confirm="submitForm"
-                @cancel="closeDia">
-      <el-form :model="form"
-               label-width="140px"
-               label-position="top"
-               :rules="rules"
-               ref="formRef">
+      :title="operationType === 'add' ? '鏂板閲囪喘鍙拌处椤甸潰' : operationType === 'edit' ? '缂栬緫閲囪喘鍙拌处椤甸潰' : '閲囪喘鍙拌处璇︽儏'" :width="'70%'"
+      :operation-type="operationType" @close="closeDia" @confirm="submitForm" @cancel="closeDia">
+      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="閲囪喘鍚堝悓鍙凤細"
-                          prop="purchaseContractNumber">
-              <el-input v-model="form.purchaseContractNumber"
-                        placeholder="璇疯緭鍏�"
-                        clearable />
+            <el-form-item label="閲囪喘鍚堝悓鍙凤細" prop="purchaseContractNumber">
+              <el-input v-model="form.purchaseContractNumber" placeholder="璇疯緭鍏�" clearable />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="閿�鍞悎鍚屽彿锛�"
-                          prop="salesLedgerId">
-              <el-select v-model="form.salesLedgerId"
-                         placeholder="璇烽�夋嫨"
-                         filterable
-                         clearable
-                         @change="salesLedgerChange">
-                <el-option v-for="item in salesContractList"
-                           :key="item.id"
-                           :label="item.salesContractNo"
-                           :value="item.id" />
+            <el-form-item label="閿�鍞悎鍚屽彿锛�" prop="salesLedgerId">
+              <el-select v-model="form.salesLedgerId" placeholder="璇烽�夋嫨" filterable clearable @change="salesLedgerChange">
+                <el-option v-for="item in salesContractList" :key="item.id" :label="item.salesContractNo" :value="item.id" />
               </el-select>
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="渚涘簲鍟嗗悕绉帮細"
-                          prop="supplierId">
-              <el-select v-model="form.supplierId"
-                         placeholder="璇烽�夋嫨"
-                         filterable
-                         clearable>
-                <el-option v-for="item in supplierList"
-                           :key="item.id"
-                           :label="item.supplierName"
-                           :value="item.id">{{ item.supplierName + '---' + item.supplierType }}
-                </el-option>
+            <el-form-item label="渚涘簲鍟嗗悕绉帮細" prop="supplierId">
+              <el-select v-model="form.supplierId" placeholder="璇烽�夋嫨" filterable clearable>
+                <el-option v-for="item in supplierList" :key="item.id" :label="item.supplierName" :value="item.id">{{ item.supplierName + '---' + item.supplierType }}</el-option>
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="椤圭洰鍚嶇О"
-                          prop="projectName">
-              <el-input v-model="form.projectName"
-                        placeholder="璇疯緭鍏�"
-                        clearable />
+            <el-form-item label="椤圭洰鍚嶇О" prop="projectName">
+              <el-input v-model="form.projectName" placeholder="璇疯緭鍏�" clearable />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
             <el-form-item label="浠樻鏂瑰紡">
-              <el-input v-model="form.paymentMethod"
-                        placeholder="璇疯緭鍏�"
-                        clearable />
+              <el-input v-model="form.paymentMethod" placeholder="璇疯緭鍏�" clearable />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="绛捐鏃ユ湡锛�"
-                          prop="executionDate">
-              <el-date-picker style="width: 100%"
-                              v-model="form.executionDate"
-                              value-format="YYYY-MM-DD"
-                              format="YYYY-MM-DD"
-                              type="date"
-                              placeholder="璇烽�夋嫨"
-                              clearable />
+            <el-form-item label="绛捐鏃ユ湡锛�" prop="executionDate">
+              <el-date-picker style="width: 100%" v-model="form.executionDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="date" placeholder="璇烽�夋嫨" clearable />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="褰曞叆浜猴細"
-                          prop="recorderId">
-              <el-select v-model="form.recorderId"
-                         placeholder="璇烽�夋嫨"
-                         clearable
-                         filterable>
-                <el-option v-for="item in userList"
-                           :key="item.userId"
-                           :label="item.nickName"
-                           :value="item.userId" />
+            <el-form-item label="褰曞叆浜猴細" prop="recorderId">
+              <el-select v-model="form.recorderId" placeholder="璇烽�夋嫨" clearable filterable>
+                <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="褰曞叆鏃ユ湡锛�"
-                          prop="entryDate">
-              <el-date-picker style="width: 100%"
-                              v-model="form.entryDate"
-                              value-format="YYYY-MM-DD"
-                              format="YYYY-MM-DD"
-                              type="date"
-                              placeholder="璇烽�夋嫨"
-                              clearable />
+            <el-form-item label="褰曞叆鏃ユ湡锛�" prop="entryDate">
+              <el-date-picker style="width: 100%" v-model="form.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="date" placeholder="璇烽�夋嫨" clearable />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row>
-          <el-form-item label="浜у搧淇℃伅锛�"
-                        prop="entryDate">
-            <el-button type="primary"
-                       @click="openProductForm('add')">娣诲姞
-            </el-button>
-            <el-button plain
-                       type="danger"
-                       @click="deleteProduct">鍒犻櫎
-            </el-button>
+          <el-form-item label="浜у搧淇℃伅锛�" prop="entryDate">
+            <el-button type="primary" @click="openProductForm('add')">娣诲姞</el-button>
+            <el-button plain type="danger" @click="deleteProduct">鍒犻櫎</el-button>
           </el-form-item>
-          <div class="select-button-group"
-               style="width: 500px; margin: 20px 0;"
-               v-if="operationType === 'add'">
-            <el-select filterable
-                       allow-create
-                       :reserve-keyword="true"
-                       :default-first-option="false"
-                       clearable
-                       v-model="templateName"
-                       :input-value="filterInputValue"
-                       @filter-change="onTemplateFilterChange"
-                       @change="onTemplateChange"
-                       @focus="getTemplateList"
-                       style="width: 500px;"
-                       placeholder="璇烽�夋嫨妯$増鎴栬�呰緭鍏ユ柊鐨勬ā鐗堝悕绉板悗閫夋嫨"
-                       class="no-arrow-select">
-              <el-option v-for="item in templateList"
-                         :key="item.id || item.value"
-                         :label="item.templateName"
-                         :value="item.templateName">
+          <div class="select-button-group" style="width: 500px; margin: 20px 0;" v-if="operationType === 'add'">
+            <el-select filterable allow-create :reserve-keyword="true" :default-first-option="false" clearable
+              v-model="templateName" :input-value="filterInputValue" @filter-change="onTemplateFilterChange"
+              @change="onTemplateChange" @focus="getTemplateList" style="width: 500px;" placeholder="璇烽�夋嫨妯$増鎴栬�呰緭鍏ユ柊鐨勬ā鐗堝悕绉板悗閫夋嫨"
+              class="no-arrow-select">
+              <el-option v-for="item in templateList" :key="item.id || item.value" :label="item.templateName"
+                :value="item.templateName">
                 <div style="display: flex; justify-content: space-between; align-items: center;">
                   <span>{{ item.templateName }}</span>
-                  <el-icon v-if="item.id"
-                           class="delete-icon"
-                           @click.stop="handleDeleteTemplate(item)"
-                           style="cursor: pointer; color: #f56c6c; font-size: 14px; margin-left: 8px;">
+                  <el-icon v-if="item.id" class="delete-icon" @click.stop="handleDeleteTemplate(item)"
+                    style="cursor: pointer; color: #f56c6c; font-size: 14px; margin-left: 8px;">
                     <Delete />
                   </el-icon>
                 </div>
               </el-option>
             </el-select>
             <!-- 鎸夐挳锛氫笌 Select 楂樺害鍖归厤锛屽幓鎺夊乏渚ц竟妗嗭紝鏃犵紳琛旀帴 -->
-            <el-button size="small"
-                       style="height: 32px;margin-left: 8px;"
-                       @click="handleButtonClick"
-                       :disabled="!templateName || templateName.trim() === '' || (!currentTemplateId && isTemplateNameDuplicate)">
+            <el-button size="small" style="height: 32px;margin-left: 8px;" @click="handleButtonClick"
+              :disabled="!templateName || templateName.trim() === '' || (!currentTemplateId && isTemplateNameDuplicate)">
               淇濆瓨
             </el-button>
           </div>
         </el-row>
-        <el-table :data="productData"
-                  border
-                  @selection-change="productSelected"
-                  show-summary
-                  :summary-method="summarizeProTable">
-          <el-table-column align="center"
-                           type="selection"
-                           width="55" />
-          <el-table-column align="center"
-                           label="搴忓彿"
-                           type="index"
-                           width="60" />
-          <el-table-column label="浜у搧澶х被"
-                           prop="productCategory" />
-          <el-table-column label="瑙勬牸鍨嬪彿"
-                           prop="specificationModel" />
-          <el-table-column label="鍗曚綅"
-                           prop="unit"
-                           width="70" />
-          <el-table-column label="鏁伴噺"
-                           prop="quantity"
-                           width="70" />
-          <el-table-column label="搴撳瓨棰勮鏁伴噺"
-                           prop="warnNum"
-                           width="120"
-                           show-overflow-tooltip />
-          <el-table-column label="绋庣巼(%)"
-                           prop="taxRate"
-                           width="80" />
-          <el-table-column label="鍚◣鍗曚环(鍏�)"
-                           prop="taxInclusiveUnitPrice"
-                           :formatter="formattedNumber"
-                           width="150" />
-          <el-table-column label="鍚◣鎬讳环(鍏�)"
-                           prop="taxInclusiveTotalPrice"
-                           :formatter="formattedNumber"
-                           width="150" />
-          <el-table-column label="涓嶅惈绋庢�讳环(鍏�)"
-                           prop="taxExclusiveTotalPrice"
-                           :formatter="formattedNumber"
-                           width="150" />
-          <el-table-column label="鏄惁璐ㄦ"
-                           prop="isChecked"
-                           width="150">
+        <el-table :data="productData" border @selection-change="productSelected" show-summary
+          :summary-method="summarizeProTable">
+          <el-table-column align="center" type="selection" width="55" />
+          <el-table-column align="center" label="搴忓彿" type="index" width="60" />
+          <el-table-column label="浜у搧澶х被" prop="productCategory" />
+          <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
+          <el-table-column label="鍗曚綅" prop="unit" width="70" />
+          <el-table-column label="鏁伴噺" prop="quantity" width="70" />
+          <el-table-column label="搴撳瓨棰勮鏁伴噺" prop="warnNum" width="120" show-overflow-tooltip />
+          <el-table-column label="绋庣巼(%)" prop="taxRate" width="80" />
+          <el-table-column label="鍚◣鍗曚环(鍏�)" prop="taxInclusiveUnitPrice" :formatter="formattedNumber" width="150" />
+          <el-table-column label="鍚◣鎬讳环(鍏�)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" width="150" />
+          <el-table-column label="涓嶅惈绋庢�讳环(鍏�)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" width="150" />
+          <el-table-column label="鏄惁璐ㄦ" prop="isChecked" width="150">
             <template #default="scope">
               <el-tag :type="scope.row.isChecked ? 'success' : 'info'">
                 {{ scope.row.isChecked ? '鏄�' : '鍚�' }}
               </el-tag>
             </template>
           </el-table-column>
-          <el-table-column label="鍏ュ簱瀹℃牳鐘舵��"
-                           prop="stockInApprovalStatus"
-                           width="120">
+          <el-table-column label="鍏ュ簱瀹℃牳鐘舵��" prop="stockInApprovalStatus" width="120">
             <template #default="scope">
-              <el-tag :type="getStockInApprovalStatusType(scope.row.stockInApprovalStatus)"
-                      size="small">
+              <el-tag :type="getStockInApprovalStatusType(scope.row.stockInApprovalStatus)" size="small">
                 {{ scope.row.stockInApprovalStatus || '--' }}
               </el-tag>
             </template>
           </el-table-column>
-          <el-table-column fixed="right"
-                           label="鎿嶄綔"
-                           min-width="60"
-                           align="center">
+          <el-table-column fixed="right" label="鎿嶄綔" min-width="60" align="center">
             <template #default="scope">
-              <el-button link
-                         type="primary"
-                         @click="openProductForm('edit', scope.row, scope.$index)"
-                         :disabled="scope.row.stockInApprovalStatus === '瀹屽叏鍏ュ簱'">缂栬緫
+              <el-button link type="primary"
+                @click="openProductForm('edit', scope.row, scope.$index)"
+                :disabled="scope.row.stockInApprovalStatus === '瀹屽叏鍏ュ簱'">缂栬緫
               </el-button>
             </template>
           </el-table-column>
         </el-table>
         <el-row :gutter="30">
           <el-col :span="24">
-            <el-form-item label="澶囨敞路锛�"
-                          prop="remarks">
-              <el-input v-model="form.remarks"
-                        placeholder="璇疯緭鍏�"
-                        clearable
-                        type="textarea"
-                        :rows="2" />
+            <el-form-item label="澶囨敞路锛�" prop="remarks">
+              <el-input v-model="form.remarks" placeholder="璇疯緭鍏�" clearable type="textarea" :rows="2" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="24">
-            <el-form-item label="闄勪欢鏉愭枡锛�"
-                          prop="purchaseLedgerFiles">
+            <el-form-item label="闄勪欢鏉愭枡锛�" prop="purchaseLedgerFiles">
               <FileUpload v-model:file-list="fileList" />
             </el-form-item>
           </el-col>
@@ -484,24 +253,12 @@
       </el-form>
     </FormDialog>
     <!-- 瀵煎叆寮圭獥 -->
-    <FormDialog v-model="importUpload.open"
-                :title="importUpload.title"
-                :width="'600px'"
-                @close="importUpload.open = false"
-                @confirm="submitImportFile"
-                @cancel="importUpload.open = false">
-      <el-upload ref="importUploadRef"
-                 :limit="1"
-                 accept=".xlsx,.xls"
-                 :action="importUpload.url"
-                 :headers="importUpload.headers"
-                 :before-upload="importUpload.beforeUpload"
-                 :on-success="importUpload.onSuccess"
-                 :on-error="importUpload.onError"
-                 :on-progress="importUpload.onProgress"
-                 :on-change="importUpload.onChange"
-                 :auto-upload="false"
-                 drag>
+    <FormDialog v-model="importUpload.open" :title="importUpload.title" :width="'600px'"
+      @close="importUpload.open = false" @confirm="submitImportFile" @cancel="importUpload.open = false">
+      <el-upload ref="importUploadRef" :limit="1" accept=".xlsx,.xls" :action="importUpload.url"
+        :headers="importUpload.headers" :before-upload="importUpload.beforeUpload" :on-success="importUpload.onSuccess"
+        :on-error="importUpload.onError" :on-progress="importUpload.onProgress" :on-change="importUpload.onChange"
+        :auto-upload="false" drag>
         <i class="el-icon-upload"></i>
         <div class="el-upload__text">
           灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em>
@@ -509,1499 +266,1485 @@
         <template #tip>
           <div class="el-upload__tip">
             浠呮敮鎸� xls/xlsx锛屽ぇ灏忎笉瓒呰繃 10MB銆�
-            <el-button link
-                       type="primary"
-                       @click="downloadTemplate">涓嬭浇瀵煎叆妯℃澘</el-button>
+            <el-button link type="primary" @click="downloadTemplate">涓嬭浇瀵煎叆妯℃澘</el-button>
           </div>
         </template>
       </el-upload>
     </FormDialog>
-    <FormDialog v-model="productFormVisible"
-                :title="productOperationType === 'add' ? '鏂板浜у搧' : '缂栬緫浜у搧'"
-                :width="'40%'"
-                :operation-type="productOperationType"
-                @close="closeProductDia"
-                @confirm="submitProduct"
-                @cancel="closeProductDia">
-      <el-form :model="productForm"
-               label-width="140px"
-               label-position="top"
-               :rules="productRules"
-               ref="productFormRef">
+    <FormDialog v-model="productFormVisible" :title="productOperationType === 'add' ? '鏂板浜у搧' : '缂栬緫浜у搧'" :width="'40%'"
+      :operation-type="productOperationType" @close="closeProductDia" @confirm="submitProduct"
+      @cancel="closeProductDia">
+      <el-form :model="productForm" label-width="140px" label-position="top" :rules="productRules" ref="productFormRef">
         <el-row :gutter="30">
           <el-col :span="24">
-            <el-form-item label="浜у搧澶х被锛�"
-                          prop="productId">
-              <el-tree-select v-model="productForm.productId"
-                              placeholder="璇烽�夋嫨"
-                              clearable
-                              filterable
-                              check-strictly
-                              @change="getModels"
-                              :data="productOptions"
-                              :render-after-expand="false"
-                              style="width: 100%" />
+            <el-form-item label="浜у搧澶х被锛�" prop="productId">
+              <el-tree-select v-model="productForm.productId" placeholder="璇烽�夋嫨" clearable filterable check-strictly
+                @change="getModels" :data="productOptions" :render-after-expand="false" style="width: 100%" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="24">
-            <el-form-item label="瑙勬牸鍨嬪彿锛�"
-                          prop="productModelId">
-              <el-select v-model="productForm.productModelId"
-                         placeholder="璇烽�夋嫨"
-                         filterable
-                         clearable
-                         @change="getProductModel">
-                <el-option v-for="item in modelOptions"
-                           :key="item.id"
-                           :label="item.model"
-                           :value="item.id" />
+            <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="productModelId">
+              <el-select v-model="productForm.productModelId" placeholder="璇烽�夋嫨" filterable clearable
+                @change="getProductModel">
+                <el-option v-for="item in modelOptions" :key="item.id" :label="item.model" :value="item.id" />
               </el-select>
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="鍗曚綅锛�"
-                          prop="unit">
-              <el-input v-model="productForm.unit"
-                        placeholder="璇疯緭鍏�"
-                        clearable />
+            <el-form-item label="鍗曚綅锛�" prop="unit">
+              <el-input v-model="productForm.unit" placeholder="璇疯緭鍏�" clearable />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="绋庣巼(%)锛�"
-                          prop="taxRate">
-              <el-select v-model="productForm.taxRate"
-                         placeholder="璇烽�夋嫨"
-                         clearable
-                         @change="mathNum">
-                <el-option v-for="dict in tax_rate"
-                           :key="dict.value"
-                           :label="dict.label"
-                           :value="dict.value" />
+            <el-form-item label="绋庣巼(%)锛�" prop="taxRate">
+              <el-select v-model="productForm.taxRate" placeholder="璇烽�夋嫨" clearable @change="mathNum">
+                <el-option v-for="dict in tax_rate" :key="dict.value" :label="dict.label" :value="dict.value" />
               </el-select>
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="鍚◣鍗曚环(鍏�)锛�"
-                          prop="taxInclusiveUnitPrice">
-              <el-input-number v-model="productForm.taxInclusiveUnitPrice"
-                               :precision="2"
-                               :step="0.1"
-                               :min="0"
-                               clearable
-                               style="width: 100%"
-                               @change="mathNum" />
+            <el-form-item label="鍚◣鍗曚环(鍏�)锛�" prop="taxInclusiveUnitPrice">
+              <el-input-number v-model="productForm.taxInclusiveUnitPrice" :precision="2" :step="0.1" :min="0" clearable
+                style="width: 100%" @change="mathNum" />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="鏁伴噺锛�"
-                          prop="quantity">
-              <el-input-number :step="0.1"
-                               clearable
-                               :precision="2"
-                               :min="0"
-                               style="width: 100%"
-                               v-model="productForm.quantity"
-                               placeholder="璇疯緭鍏�"
-                               @change="mathNum" />
+            <el-form-item label="鏁伴噺锛�" prop="quantity">
+              <el-input-number :step="0.1" clearable :precision="2" :min="0" style="width: 100%"
+                v-model="productForm.quantity" placeholder="璇疯緭鍏�" @change="mathNum" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="鍚◣鎬讳环(鍏�)锛�"
-                          prop="taxInclusiveTotalPrice">
-              <el-input-number v-model="productForm.taxInclusiveTotalPrice"
-                               :precision="2"
-                               :step="0.1"
-                               :min="0"
-                               clearable
-                               style="width: 100%"
-                               @change="reverseMathNum('taxInclusiveTotalPrice')" />
+            <el-form-item label="鍚◣鎬讳环(鍏�)锛�" prop="taxInclusiveTotalPrice">
+              <el-input-number v-model="productForm.taxInclusiveTotalPrice" :precision="2" :step="0.1" :min="0"
+                clearable style="width: 100%" @change="reverseMathNum('taxInclusiveTotalPrice')" />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="涓嶅惈绋庢�讳环(鍏�)锛�"
-                          prop="taxExclusiveTotalPrice">
-              <el-input-number v-model="productForm.taxExclusiveTotalPrice"
-                               :precision="2"
-                               :step="0.1"
-                               :min="0"
-                               clearable
-                               style="width: 100%"
-                               @change="reverseMathNum('taxExclusiveTotalPrice')" />
+            <el-form-item label="涓嶅惈绋庢�讳环(鍏�)锛�" prop="taxExclusiveTotalPrice">
+              <el-input-number v-model="productForm.taxExclusiveTotalPrice" :precision="2" :step="0.1" :min="0"
+                clearable style="width: 100%" @change="reverseMathNum('taxExclusiveTotalPrice')" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="鍙戠エ绫诲瀷锛�"
-                          prop="invoiceType">
-              <el-select v-model="productForm.invoiceType"
-                         placeholder="璇烽�夋嫨"
-                         clearable>
-                <el-option label="澧炴櫘绁�"
-                           value="澧炴櫘绁�" />
-                <el-option label="澧炰笓绁�"
-                           value="澧炰笓绁�" />
+            <el-form-item label="鍙戠エ绫诲瀷锛�" prop="invoiceType">
+              <el-select v-model="productForm.invoiceType" placeholder="璇烽�夋嫨" clearable>
+                <el-option label="澧炴櫘绁�" value="澧炴櫘绁�" />
+                <el-option label="澧炰笓绁�" value="澧炰笓绁�" />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="搴撳瓨棰勮鏁伴噺锛�"
-                          prop="warnNum">
-              <el-input-number v-model="productForm.warnNum"
-                               :precision="2"
-                               :step="0.1"
-                               :min="0"
-                               clearable
-                               style="width: 100%" />
+            <el-form-item label="搴撳瓨棰勮鏁伴噺锛�" prop="warnNum">
+              <el-input-number v-model="productForm.warnNum" :precision="2" :step="0.1" :min="0" clearable
+                style="width: 100%" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="鏄惁璐ㄦ锛�"
-                          prop="isChecked">
+            <el-form-item label="鏄惁璐ㄦ锛�" prop="isChecked">
               <el-radio-group v-model="productForm.isChecked">
-                <el-radio label="鏄�"
-                          :value="true" />
-                <el-radio label="鍚�"
-                          :value="false" />
+                <el-radio label="鏄�" :value="true" />
+                <el-radio label="鍚�" :value="false" />
               </el-radio-group>
             </el-form-item>
           </el-col>
         </el-row>
       </el-form>
     </FormDialog>
-    <FileList v-if="fileListDialogVisible"
-              v-model:visible="fileListDialogVisible"
-              record-type="purchase_ledger"
-              :record-id="recordId" />
+    <FileList v-if="fileListDialogVisible" v-model:visible="fileListDialogVisible" record-type="purchase_ledger"
+      :record-id="recordId" />
+    <Detail ref="detailRef" />
   </div>
 </template>
 
 <script setup>
-  import FormDialog from "@/components/Dialog/FormDialog.vue";
-  import FileListDialog from "@/components/Dialog/FileListDialog.vue";
-  import { getToken } from "@/utils/auth";
-  import pagination from "@/components/PIMTable/Pagination.vue";
-  import {
-    ref,
-    onMounted,
-    reactive,
-    toRefs,
-    getCurrentInstance,
-    nextTick,
-  } from "vue";
-  import { Search, Delete } from "@element-plus/icons-vue";
-  import { ElMessageBox, ElMessage } from "element-plus";
-  import { userListNoPage } from "@/api/system/user.js";
-  import {
-    addOrUpdateSalesLedgerProduct,
-    delProduct,
-    delLedgerFile,
-    getProductInfoByContractNo,
-  } from "@/api/salesManagement/salesLedger.js";
-  import {
-    addOrEditPurchase,
-    addPurchaseTemplate,
-    updatePurchaseTemplate,
-    createPurchaseNo,
-    delPurchase,
-    getSalesNo,
-    purchaseListPage,
-    productList,
-    getPurchaseById,
-    getOptions,
-    getPurchaseTemplateList,
-    delPurchaseTemplate,
-  } from "@/api/procurementManagement/procurementLedger.js";
-  import useFormData from "@/hooks/useFormData.js";
-  const FileList = defineAsyncComponent(() =>
-    import("@/components/Dialog/FileList.vue")
+import FormDialog from "@/components/Dialog/FormDialog.vue";
+import FileListDialog from "@/components/Dialog/FileListDialog.vue";
+import Detail from "./detail.vue";
+import { getToken } from "@/utils/auth";
+import pagination from "@/components/PIMTable/Pagination.vue";
+import {
+  ref,
+  onMounted,
+  reactive,
+  toRefs,
+  getCurrentInstance,
+  nextTick,
+} from "vue";
+import { Search, Delete } from "@element-plus/icons-vue";
+import { ElMessageBox, ElMessage } from "element-plus";
+import { userListNoPage } from "@/api/system/user.js";
+import {
+  addOrUpdateSalesLedgerProduct,
+  delProduct,
+  delLedgerFile,
+  getProductInfoByContractNo,
+} from "@/api/salesManagement/salesLedger.js";
+import {
+  addOrEditPurchase,
+  addPurchaseTemplate,
+  updatePurchaseTemplate,
+  createPurchaseNo,
+  delPurchase,
+  getSalesNo,
+  purchaseListPage,
+  productList,
+  getPurchaseById,
+  getOptions,
+  getPurchaseTemplateList,
+  delPurchaseTemplate,
+} from "@/api/procurementManagement/procurementLedger.js";
+import useFormData from "@/hooks/useFormData.js";
+const FileList = defineAsyncComponent(() =>
+  import("@/components/Dialog/FileList.vue")
+);
+
+const detailRef = ref(null);
+
+const { proxy } = getCurrentInstance();
+const { tax_rate } = proxy.useDict("tax_rate");
+const tableData = ref([]);
+const productData = ref([]);
+const selectedRows = ref([]);
+const productSelectedRows = ref([]);
+const modelOptions = ref([]);
+const userList = ref([]);
+const productOptions = ref([]);
+const salesContractList = ref([]);
+const supplierList = ref([]);
+const tableLoading = ref(false);
+const recordId = ref();
+const fileListDialogVisible = ref(false);
+const page = reactive({
+  current: 1,
+  size: 100,
+});
+const total = ref(0);
+const fileList = ref([]);
+import useUserStore from "@/store/modules/user";
+import { modelList, productTreeList } from "@/api/basicData/product.js";
+import dayjs from "dayjs";
+import FileUpload from "@/components/AttachmentUpload/file/index.vue";
+
+const userStore = useUserStore();
+
+// 璁㈠崟瀹℃壒鐘舵�佹樉绀烘枃鏈�
+const approvalStatusText = {
+  1: "寰呭鏍�",
+  2: "瀹℃壒涓�",
+  3: "瀹℃壒閫氳繃",
+  4: "瀹℃壒澶辫触",
+};
+
+// 鑾峰彇瀹℃壒鐘舵�佹爣绛剧被鍨�
+const getApprovalStatusType = status => {
+  const typeMap = {
+    1: "info", // 寰呭鏍� - 鐏拌壊
+    2: "warning", // 瀹℃壒涓� - 姗欒壊
+    3: "success", // 瀹℃壒閫氳繃 - 缁胯壊
+    4: "danger", // 瀹℃壒澶辫触 - 绾㈣壊
+  };
+  return typeMap[status] || "";
+};
+
+// 鑾峰彇鍏ュ簱鐘舵�佹爣绛剧被鍨�
+const getStockInStatusType = status => {
+  const typeMap = {
+    "寰呭叆搴�": "info", // 寰呭叆搴� - 鐏拌壊
+    "鍏ュ簱涓�": "warning", // 鍏ュ簱涓� - 姗欒壊
+    "瀹屽叏鍏ュ簱": "success", // 瀹屽叏鍏ュ簱 - 缁胯壊
+  };
+  return typeMap[status] || "";
+};
+
+// 鑾峰彇鍏ュ簱瀹℃牳鐘舵�佹爣绛剧被鍨�
+const getStockInApprovalStatusType = status => {
+  const typeMap = {
+    "寰呭叆搴�": "info", // 寰呭叆搴� - 鐏拌壊
+    "鍏ュ簱涓�": "warning", // 鍏ュ簱涓� - 姗欒壊
+    "瀹屽叏鍏ュ簱": "success", // 瀹屽叏鍏ュ簱 - 缁胯壊
+  };
+  return typeMap[status] || "";
+};
+
+const templateName = ref("");
+const filterInputValue = ref("");
+const templateList = ref([]);
+const isTemplateNameDuplicate = ref(false); // 鏍囪妯℃澘鍚嶇О鏄惁閲嶅
+// 褰撳墠閫変腑鐨勬ā鏉縄D锛堢敤浜庡尯鍒嗘柊澧炴ā鏉胯繕鏄洿鏂版ā鏉匡級
+const currentTemplateId = ref(null);
+
+// 妫�鏌ユā鏉垮悕绉版槸鍚﹂噸澶�
+const checkTemplateNameDuplicate = name => {
+  if (!name || name.trim() === "") {
+    isTemplateNameDuplicate.value = false;
+    return false;
+  }
+  const isDuplicate = templateList.value.some(
+    item => item.templateName === name.trim()
   );
+  isTemplateNameDuplicate.value = isDuplicate;
+  return isDuplicate;
+};
 
-  const { proxy } = getCurrentInstance();
-  const { tax_rate } = proxy.useDict("tax_rate");
-  const tableData = ref([]);
-  const productData = ref([]);
-  const selectedRows = ref([]);
-  const productSelectedRows = ref([]);
-  const modelOptions = ref([]);
-  const userList = ref([]);
-  const productOptions = ref([]);
-  const salesContractList = ref([]);
-  const supplierList = ref([]);
-  const tableLoading = ref(false);
-  const recordId = ref();
-  const fileListDialogVisible = ref(false);
-  const page = reactive({
-    current: 1,
-    size: 100,
-  });
-  const total = ref(0);
-  const fileList = ref([]);
-  import useUserStore from "@/store/modules/user";
-  import { modelList, productTreeList } from "@/api/basicData/product.js";
-  import dayjs from "dayjs";
-  import FileUpload from "@/components/AttachmentUpload/file/index.vue";
+// 鍒ゆ柇鏂囦欢鏄惁涓哄浘鐗�
+const isImage = (filename) => {
+  if (!filename) return false;
+  const ext = filename.substring(filename.lastIndexOf('.')).toLowerCase();
+  return ['.png', '.jpg', '.jpeg', '.gif', '.webp', '.bmp'].includes(ext);
+};
 
-  const userStore = useUserStore();
-
-  // 璁㈠崟瀹℃壒鐘舵�佹樉绀烘枃鏈�
-  const approvalStatusText = {
-    1: "寰呭鏍�",
-    2: "瀹℃壒涓�",
-    3: "瀹℃壒閫氳繃",
-    4: "瀹℃壒澶辫触",
-  };
-
-  // 鑾峰彇瀹℃壒鐘舵�佹爣绛剧被鍨�
-  const getApprovalStatusType = status => {
-    const typeMap = {
-      1: "info", // 寰呭鏍� - 鐏拌壊
-      2: "warning", // 瀹℃壒涓� - 姗欒壊
-      3: "success", // 瀹℃壒閫氳繃 - 缁胯壊
-      4: "danger", // 瀹℃壒澶辫触 - 绾㈣壊
-    };
-    return typeMap[status] || "";
-  };
-
-  // 鑾峰彇鍏ュ簱鐘舵�佹爣绛剧被鍨�
-  const getStockInStatusType = status => {
-    const typeMap = {
-      "寰呭叆搴�": "info", // 寰呭叆搴� - 鐏拌壊
-      "鍏ュ簱涓�": "warning", // 鍏ュ簱涓� - 姗欒壊
-      "瀹屽叏鍏ュ簱": "success", // 瀹屽叏鍏ュ簱 - 缁胯壊
-    };
-    return typeMap[status] || "";
-  };
-
-  // 鑾峰彇鍏ュ簱瀹℃牳鐘舵�佹爣绛剧被鍨�
-  const getStockInApprovalStatusType = status => {
-    const typeMap = {
-      "寰呭叆搴�": "info", // 寰呭叆搴� - 鐏拌壊
-      "鍏ュ簱涓�": "warning", // 鍏ュ簱涓� - 姗欒壊
-      "瀹屽叏鍏ュ簱": "success", // 瀹屽叏鍏ュ簱 - 缁胯壊
-    };
-    return typeMap[status] || "";
-  };
-
-  const templateName = ref("");
-  const filterInputValue = ref("");
-  const templateList = ref([]);
-  const isTemplateNameDuplicate = ref(false); // 鏍囪妯℃澘鍚嶇О鏄惁閲嶅
-  // 褰撳墠閫変腑鐨勬ā鏉縄D锛堢敤浜庡尯鍒嗘柊澧炴ā鏉胯繕鏄洿鏂版ā鏉匡級
-  const currentTemplateId = ref(null);
-
-  // 妫�鏌ユā鏉垮悕绉版槸鍚﹂噸澶�
-  const checkTemplateNameDuplicate = name => {
-    if (!name || name.trim() === "") {
-      isTemplateNameDuplicate.value = false;
-      return false;
-    }
-    const isDuplicate = templateList.value.some(
-      item => item.templateName === name.trim()
-    );
-    isTemplateNameDuplicate.value = isDuplicate;
-    return isDuplicate;
-  };
-
-  // 闃叉姈瀹氭椂鍣�
-  let duplicateCheckTimer = null;
-  const onTemplateFilterChange = val => {
-    filterInputValue.value = val ?? "";
-    // 娓呴櫎涔嬪墠鐨勫畾鏃跺櫒
-    if (duplicateCheckTimer) {
-      clearTimeout(duplicateCheckTimer);
-    }
-    // 瀹炴椂妫�鏌ユā鏉垮悕绉版槸鍚﹂噸澶嶏紙闃叉姈澶勭悊锛岄伩鍏嶉绻佹彁绀猴級
-    if (val && val.trim()) {
-      duplicateCheckTimer = setTimeout(() => {
-        const isDuplicate = checkTemplateNameDuplicate(val);
-        if (isDuplicate) {
-          ElMessage({
-            message: "妯℃澘鍚嶇О宸插瓨鍦紝璇锋洿鎹㈡ā鏉垮悕绉�",
-            type: "warning",
-            duration: 2000,
-          });
-        }
-      }, 300); // 300ms 闃叉姈
-    } else {
-      isTemplateNameDuplicate.value = false;
-    }
-  };
-
-  // allow-create 鏃讹紝杈撳叆涓嶅瓨鍦ㄧ殑鍐呭浼氫綔涓� string 鍊艰繑鍥烇紱杩欓噷鍚屾鍥炶緭鍏ユ浠ョ‘淇濇枃瀛椾笉涓�
-  const onTemplateChange = async val => {
-    if (typeof val === "string") {
-      filterInputValue.value = val;
-      // 閫夋嫨鎴栬緭鍏ユ椂妫�鏌ラ噸澶�
-      checkTemplateNameDuplicate(val);
-    }
-
-    // 杩囨护鏁版嵁锛屾煡鎵惧尮閰嶇殑妯℃澘
-    const matchedTemplate = templateList.value.find(
-      item => item.templateName === val
-    );
-
-    if (matchedTemplate?.id) {
-      // 璁板綍褰撳墠閫変腑鐨勬ā鏉縄D锛屽悗缁繚瀛樻椂杩涜鏇存柊鎿嶄綔
-      currentTemplateId.value = matchedTemplate.id;
-      // 閫変腑宸叉湁妯℃澘鏃讹紝涓嶅簲瑙嗕负鈥滄ā鏉垮悕绉伴噸澶嶅鑷翠笉鍙繚瀛樷��
-      isTemplateNameDuplicate.value = false;
-      // 濡傛灉鎵惧埌妯℃澘锛屽彧璧嬪�间緵搴斿晢銆侀」鐩悕绉般�佷粯娆炬柟寮忓拰浜у搧淇℃伅
-      if (matchedTemplate.supplierId) {
-        form.value.supplierId = matchedTemplate.supplierId;
-      }
-      if (matchedTemplate.supplierName) {
-        form.value.supplierName = matchedTemplate.supplierName;
-      }
-      if (matchedTemplate.projectName) {
-        form.value.projectName = matchedTemplate.projectName;
-      }
-      if (matchedTemplate.paymentMethod) {
-        form.value.paymentMethod = matchedTemplate.paymentMethod;
-      }
-      // 妯℃澘鏁版嵁涓殑浜у搧瀛楁鏄� productList锛岄渶瑕佽浆鎹负 productData
-      productData.value =
-        matchedTemplate.productList || matchedTemplate.productData || [];
-    } else {
-      // 鏈尮閰嶅埌宸叉湁妯℃澘锛岃涓烘柊妯℃澘
-      currentTemplateId.value = null;
-      // 濡傛灉娌℃湁鎵惧埌妯℃澘锛岄噸缃〃鍗曪紙淇濇寔褰撳墠琛ㄥ崟鐘舵�侊級
-      const currentFormData = { ...form.value };
-      const currentProductData = [...productData.value];
-
-      // 濡傛灉瀵硅瘽妗嗘湭鎵撳紑锛屽厛鎵撳紑
-      if (!dialogFormVisible.value) {
-        operationType.value = "add";
-        dialogFormVisible.value = true;
-      }
-
-      // 绛夊緟涓嬩竴涓� tick 鍚庢仮澶嶆暟鎹�
-      await nextTick();
-      form.value = {
-        ...form.value,
-        ...currentFormData,
-      };
-      productData.value = currentProductData;
-    }
-  };
-
-  // 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-  const operationType = ref("");
-  const dialogFormVisible = ref(false);
-  const data = reactive({
-    searchForm: {
-      supplierName: "", // 渚涘簲鍟嗗悕绉�
-      purchaseContractNumber: "", // 閲囪喘鍚堝悓缂栧彿
-      salesContractNo: "", // 閿�鍞悎鍚岀紪鍙�
-      projectName: "", // 椤圭洰鍚嶇О
-      entryDate: null, // 褰曞叆鏃ユ湡
-      entryDateStart: undefined,
-      entryDateEnd: undefined,
-    },
-    form: {
-      purchaseContractNumber: "",
-      salesLedgerId: "",
-      projectName: "",
-      recorderId: "",
-      entryDate: "",
-      productData: [],
-      supplierName: "",
-      supplierId: "",
-      paymentMethod: "",
-      executionDate: "",
-      isChecked: false,
-    },
-    rules: {
-      purchaseContractNumber: [
-        { required: true, message: "璇疯緭鍏�", trigger: "blur" },
-      ],
-      projectName: [
-        { required: true, message: "璇疯緭鍏ラ」鐩悕绉�", trigger: "blur" },
-      ],
-      supplierId: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-      entryDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-      executionDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    },
-  });
-  const { form, rules } = toRefs(data);
-  const { form: searchForm } = useFormData({
-    ...data.searchForm,
-    // 璁剧疆褰曞叆鏃ユ湡鑼冨洿涓哄綋澶�
-    entryDate: [
-      dayjs().startOf("day").format("YYYY-MM-DD"),
-      dayjs().endOf("day").format("YYYY-MM-DD"),
-    ],
-    entryDateStart: dayjs().startOf("day").format("YYYY-MM-DD"),
-    entryDateEnd: dayjs().endOf("day").format("YYYY-MM-DD"),
-  });
-
-  // 浜у搧琛ㄥ崟寮规鏁版嵁
-  const productFormVisible = ref(false);
-  const productOperationType = ref("");
-  const productOperationIndex = ref("");
-  const currentId = ref("");
-  const productFormData = reactive({
-    productForm: {
-      productId: "",
-      productCategory: "",
-      productModelId: "",
-      specificationModel: "",
-      unit: "",
-      quantity: "",
-      taxInclusiveUnitPrice: "",
-      taxRate: "",
-      taxInclusiveTotalPrice: "",
-      taxExclusiveTotalPrice: "",
-      invoiceType: "",
-      warnNum: "",
-      isChecked: false,
-    },
-    productRules: {
-      productId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-      productModelId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-      unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-      quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-      taxInclusiveUnitPrice: [
-        { required: true, message: "璇疯緭鍏�", trigger: "blur" },
-      ],
-      taxRate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-      warnNum: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-      taxInclusiveTotalPrice: [
-        { required: true, message: "璇疯緭鍏�", trigger: "blur" },
-      ],
-      taxExclusiveTotalPrice: [
-        { required: true, message: "璇疯緭鍏�", trigger: "blur" },
-      ],
-      invoiceType: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-      isChecked: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    },
-  });
-  const { productForm, productRules } = toRefs(productFormData);
-  const upload = reactive({
-    // 涓婁紶鐨勫湴鍧�
-    url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
-    // 璁剧疆涓婁紶鐨勮姹傚ご閮�
-    headers: { Authorization: "Bearer " + getToken() },
-  });
-
-  // 瀵煎叆鐩稿叧
-  const importUploadRef = ref(null);
-  const importUpload = reactive({
-    title: "瀵煎叆閲囪喘鍙拌处",
-    open: false,
-    url: import.meta.env.VITE_APP_BASE_API + "/purchase/ledger/import",
-    headers: { Authorization: "Bearer " + getToken() },
-    isUploading: false,
-    beforeUpload: file => {
-      const isExcel = file.name.endsWith(".xlsx") || file.name.endsWith(".xls");
-      const isLt10M = file.size / 1024 / 1024 < 10;
-      if (!isExcel) {
-        proxy.$modal.msgError("涓婁紶鏂囦欢鍙兘鏄� xlsx/xls 鏍煎紡!");
-        return false;
-      }
-      if (!isLt10M) {
-        proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃 10MB!");
-        return false;
-      }
-      return true;
-    },
-    onChange: (file, fileList) => {
-      // noop
-    },
-    onProgress: (event, file, fileList) => {
-      // noop
-    },
-    onSuccess: (response, file, fileList) => {
-      importUpload.isUploading = false;
-      if (response?.code === 200) {
-        proxy.$modal.msgSuccess("瀵煎叆鎴愬姛");
-        importUpload.open = false;
-        if (importUploadRef.value) {
-          importUploadRef.value.clearFiles?.();
-        }
-        getList();
-      } else {
-        proxy.$modal.msgError(response?.msg || "瀵煎叆澶辫触");
-      }
-    },
-    onError: () => {
-      importUpload.isUploading = false;
-      proxy.$modal.msgError("瀵煎叆澶辫触锛岃閲嶈瘯");
-    },
-  });
-
-  const handleImport = () => {
-    importUpload.title = "瀵煎叆閲囪喘鍙拌处";
-    importUpload.open = true;
-    importUpload.isUploading = false;
-    if (importUploadRef.value) {
-      importUploadRef.value.clearFiles?.();
-    }
-  };
-
-  // 涓嬭浇瀵煎叆妯℃澘锛堝鍚庣璺緞涓嶅悓锛屽彲鍦ㄦ澶勮皟鏁达級
-  const downloadTemplate = () => {
-    proxy.download(
-      "/purchase/ledger/exportTemplate",
-      {},
-      "閲囪喘鍙拌处瀵煎叆妯℃澘.xlsx"
-    );
-  };
-
-  const submitImportFile = () => {
-    importUpload.isUploading = true;
-    proxy.$refs["importUploadRef"]?.submit?.();
-  };
-
-  const changeDaterange = value => {
-    if (value) {
-      searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
-      searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
-    } else {
-      searchForm.entryDateStart = undefined;
-      searchForm.entryDateEnd = undefined;
-    }
-    handleQuery();
-  };
-
-  const formattedNumber = (row, column, cellValue) => {
-    return parseFloat(cellValue).toFixed(2);
-  };
-  // 鏌ヨ鍒楄〃
-  /** 鎼滅储鎸夐挳鎿嶄綔 */
-  const handleQuery = () => {
-    page.current = 1;
-    getList();
-  };
-
-  // 淇濆瓨妯℃澘
-  const handleButtonClick = async () => {
-    // 妫�鏌ユā鏉垮悕绉版槸鍚︿负绌�
-    if (!templateName.value || templateName.value.trim() === "") {
-      ElMessage({
-        message: "璇疯緭鍏ユā鏉垮悕绉�",
-        type: "warning",
-      });
-      return;
-    }
-
-    // 濡傛灉鏄�滄柊澧炴ā鏉库�濓紙娌℃湁閫変腑宸叉湁妯℃澘锛夛紝鎵嶉渶瑕佸仛閲嶅悕鏍¢獙锛�
-    // 鑻ユ槸閫変腑宸叉湁妯℃澘鍚庝慨鏀癸紝鍒欏厑璁镐娇鐢ㄥ師鍚嶇О锛堣涓烘洿鏂帮級
-    if (!currentTemplateId.value) {
-      const isDuplicate = checkTemplateNameDuplicate(templateName.value);
+// 闃叉姈瀹氭椂鍣�
+let duplicateCheckTimer = null;
+const onTemplateFilterChange = val => {
+  filterInputValue.value = val ?? "";
+  // 娓呴櫎涔嬪墠鐨勫畾鏃跺櫒
+  if (duplicateCheckTimer) {
+    clearTimeout(duplicateCheckTimer);
+  }
+  // 瀹炴椂妫�鏌ユā鏉垮悕绉版槸鍚﹂噸澶嶏紙闃叉姈澶勭悊锛岄伩鍏嶉绻佹彁绀猴級
+  if (val && val.trim()) {
+    duplicateCheckTimer = setTimeout(() => {
+      const isDuplicate = checkTemplateNameDuplicate(val);
       if (isDuplicate) {
         ElMessage({
           message: "妯℃澘鍚嶇О宸插瓨鍦紝璇锋洿鎹㈡ā鏉垮悕绉�",
           type: "warning",
+          duration: 2000,
         });
-        return;
       }
+    }, 300); // 300ms 闃叉姈
+  } else {
+    isTemplateNameDuplicate.value = false;
+  }
+};
+
+// allow-create 鏃讹紝杈撳叆涓嶅瓨鍦ㄧ殑鍐呭浼氫綔涓� string 鍊艰繑鍥烇紱杩欓噷鍚屾鍥炶緭鍏ユ浠ョ‘淇濇枃瀛椾笉涓�
+const onTemplateChange = async val => {
+  if (typeof val === "string") {
+    filterInputValue.value = val;
+    // 閫夋嫨鎴栬緭鍏ユ椂妫�鏌ラ噸澶�
+    checkTemplateNameDuplicate(val);
+  }
+
+  // 杩囨护鏁版嵁锛屾煡鎵惧尮閰嶇殑妯℃澘
+  const matchedTemplate = templateList.value.find(
+    item => item.templateName === val
+  );
+
+  if (matchedTemplate?.id) {
+    // 璁板綍褰撳墠閫変腑鐨勬ā鏉縄D锛屽悗缁繚瀛樻椂杩涜鏇存柊鎿嶄綔
+    currentTemplateId.value = matchedTemplate.id;
+    // 閫変腑宸叉湁妯℃澘鏃讹紝涓嶅簲瑙嗕负鈥滄ā鏉垮悕绉伴噸澶嶅鑷翠笉鍙繚瀛樷��
+    isTemplateNameDuplicate.value = false;
+    // 濡傛灉鎵惧埌妯℃澘锛屽彧璧嬪�间緵搴斿晢銆侀」鐩悕绉般�佷粯娆炬柟寮忓拰浜у搧淇℃伅
+    if (matchedTemplate.supplierId) {
+      form.value.supplierId = matchedTemplate.supplierId;
+    }
+    if (matchedTemplate.supplierName) {
+      form.value.supplierName = matchedTemplate.supplierName;
+    }
+    if (matchedTemplate.projectName) {
+      form.value.projectName = matchedTemplate.projectName;
+    }
+    if (matchedTemplate.paymentMethod) {
+      form.value.paymentMethod = matchedTemplate.paymentMethod;
+    }
+    // 妯℃澘鏁版嵁涓殑浜у搧瀛楁鏄� productList锛岄渶瑕佽浆鎹负 productData
+    productData.value =
+      matchedTemplate.productList || matchedTemplate.productData || [];
+  } else {
+    // 鏈尮閰嶅埌宸叉湁妯℃澘锛岃涓烘柊妯℃澘
+    currentTemplateId.value = null;
+    // 濡傛灉娌℃湁鎵惧埌妯℃澘锛岄噸缃〃鍗曪紙淇濇寔褰撳墠琛ㄥ崟鐘舵�侊級
+    const currentFormData = { ...form.value };
+    const currentProductData = [...productData.value];
+
+    // 濡傛灉瀵硅瘽妗嗘湭鎵撳紑锛屽厛鎵撳紑
+    if (!dialogFormVisible.value) {
+      operationType.value = "add";
+      dialogFormVisible.value = true;
     }
 
-    // 妫�鏌ヤ緵搴斿晢鏄惁閫夋嫨
-    if (!form.value.supplierId) {
+    // 绛夊緟涓嬩竴涓� tick 鍚庢仮澶嶆暟鎹�
+    await nextTick();
+    form.value = {
+      ...form.value,
+      ...currentFormData,
+    };
+    productData.value = currentProductData;
+  }
+};
+
+// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
+const operationType = ref("");
+const dialogFormVisible = ref(false);
+const data = reactive({
+  searchForm: {
+    supplierName: "", // 渚涘簲鍟嗗悕绉�
+    purchaseContractNumber: "", // 閲囪喘鍚堝悓缂栧彿
+    salesContractNo: "", // 閿�鍞悎鍚岀紪鍙�
+    projectName: "", // 椤圭洰鍚嶇О
+    entryDate: null, // 褰曞叆鏃ユ湡
+    entryDateStart: undefined,
+    entryDateEnd: undefined,
+  },
+  form: {
+    purchaseContractNumber: "",
+    salesLedgerId: "",
+    projectName: "",
+    recorderId: "",
+    entryDate: "",
+    productData: [],
+    supplierName: "",
+    supplierId: "",
+    paymentMethod: "",
+    executionDate: "",
+    isChecked: false,
+  },
+  rules: {
+    purchaseContractNumber: [
+      { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+    ],
+    projectName: [
+      { required: true, message: "璇疯緭鍏ラ」鐩悕绉�", trigger: "blur" },
+    ],
+    supplierId: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    entryDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+    executionDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+  },
+});
+const { form, rules } = toRefs(data);
+const { form: searchForm } = useFormData({
+  ...data.searchForm,
+  // 璁剧疆褰曞叆鏃ユ湡鑼冨洿涓哄綋澶�
+  entryDate: [
+    dayjs().startOf("day").format("YYYY-MM-DD"),
+    dayjs().endOf("day").format("YYYY-MM-DD"),
+  ],
+  entryDateStart: dayjs().startOf("day").format("YYYY-MM-DD"),
+  entryDateEnd: dayjs().endOf("day").format("YYYY-MM-DD"),
+});
+
+// 浜у搧琛ㄥ崟寮规鏁版嵁
+const productFormVisible = ref(false);
+const productOperationType = ref("");
+const productOperationIndex = ref("");
+const currentId = ref("");
+const productFormData = reactive({
+  productForm: {
+    productId: "",
+    productCategory: "",
+    productModelId: "",
+    specificationModel: "",
+    unit: "",
+    quantity: "",
+    taxInclusiveUnitPrice: "",
+    taxRate: "",
+    taxInclusiveTotalPrice: "",
+    taxExclusiveTotalPrice: "",
+    invoiceType: "",
+    warnNum: "",
+    isChecked: false,
+  },
+  productRules: {
+    productId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+    productModelId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+    unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    taxInclusiveUnitPrice: [
+      { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+    ],
+    taxRate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+    warnNum: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+    taxInclusiveTotalPrice: [
+      { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+    ],
+    taxExclusiveTotalPrice: [
+      { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+    ],
+    invoiceType: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+    isChecked: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+  },
+});
+const { productForm, productRules } = toRefs(productFormData);
+const upload = reactive({
+  // 涓婁紶鐨勫湴鍧�
+  url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
+  // 璁剧疆涓婁紶鐨勮姹傚ご閮�
+  headers: { Authorization: "Bearer " + getToken() },
+});
+
+// 瀵煎叆鐩稿叧
+const importUploadRef = ref(null);
+const importUpload = reactive({
+  title: "瀵煎叆閲囪喘鍙拌处",
+  open: false,
+  url: import.meta.env.VITE_APP_BASE_API + "/purchase/ledger/import",
+  headers: { Authorization: "Bearer " + getToken() },
+  isUploading: false,
+  beforeUpload: file => {
+    const isExcel = file.name.endsWith(".xlsx") || file.name.endsWith(".xls");
+    const isLt10M = file.size / 1024 / 1024 < 10;
+    if (!isExcel) {
+      proxy.$modal.msgError("涓婁紶鏂囦欢鍙兘鏄� xlsx/xls 鏍煎紡!");
+      return false;
+    }
+    if (!isLt10M) {
+      proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃 10MB!");
+      return false;
+    }
+    return true;
+  },
+  onChange: (file, fileList) => {
+    // noop
+  },
+  onProgress: (event, file, fileList) => {
+    // noop
+  },
+  onSuccess: (response, file, fileList) => {
+    importUpload.isUploading = false;
+    if (response?.code === 200) {
+      proxy.$modal.msgSuccess("瀵煎叆鎴愬姛");
+      importUpload.open = false;
+      if (importUploadRef.value) {
+        importUploadRef.value.clearFiles?.();
+      }
+      getList();
+    } else {
+      proxy.$modal.msgError(response?.msg || "瀵煎叆澶辫触");
+    }
+  },
+  onError: () => {
+    importUpload.isUploading = false;
+    proxy.$modal.msgError("瀵煎叆澶辫触锛岃閲嶈瘯");
+  },
+});
+
+const handleImport = () => {
+  importUpload.title = "瀵煎叆閲囪喘鍙拌处";
+  importUpload.open = true;
+  importUpload.isUploading = false;
+  if (importUploadRef.value) {
+    importUploadRef.value.clearFiles?.();
+  }
+};
+
+// 涓嬭浇瀵煎叆妯℃澘锛堝鍚庣璺緞涓嶅悓锛屽彲鍦ㄦ澶勮皟鏁达級
+const downloadTemplate = () => {
+  proxy.download(
+    "/purchase/ledger/exportTemplate",
+    {},
+    "閲囪喘鍙拌处瀵煎叆妯℃澘.xlsx"
+  );
+};
+
+const submitImportFile = () => {
+  importUpload.isUploading = true;
+  proxy.$refs["importUploadRef"]?.submit?.();
+};
+
+const changeDaterange = value => {
+  if (value) {
+    searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
+    searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
+  } else {
+    searchForm.entryDateStart = undefined;
+    searchForm.entryDateEnd = undefined;
+  }
+  handleQuery();
+};
+
+const formattedNumber = (row, column, cellValue) => {
+  return parseFloat(cellValue).toFixed(2);
+};
+// 鏌ヨ鍒楄〃
+/** 鎼滅储鎸夐挳鎿嶄綔 */
+const handleQuery = () => {
+  page.current = 1;
+  getList();
+};
+
+// 淇濆瓨妯℃澘
+const handleButtonClick = async () => {
+  // 妫�鏌ユā鏉垮悕绉版槸鍚︿负绌�
+  if (!templateName.value || templateName.value.trim() === "") {
+    ElMessage({
+      message: "璇疯緭鍏ユā鏉垮悕绉�",
+      type: "warning",
+    });
+    return;
+  }
+
+  // 濡傛灉鏄�滄柊澧炴ā鏉库�濓紙娌℃湁閫変腑宸叉湁妯℃澘锛夛紝鎵嶉渶瑕佸仛閲嶅悕鏍¢獙锛�
+  // 鑻ユ槸閫変腑宸叉湁妯℃澘鍚庝慨鏀癸紝鍒欏厑璁镐娇鐢ㄥ師鍚嶇О锛堣涓烘洿鏂帮級
+  if (!currentTemplateId.value) {
+    const isDuplicate = checkTemplateNameDuplicate(templateName.value);
+    if (isDuplicate) {
       ElMessage({
-        message: "璇峰厛閫夋嫨渚涘簲鍟�",
+        message: "妯℃澘鍚嶇О宸插瓨鍦紝璇锋洿鎹㈡ā鏉垮悕绉�",
         type: "warning",
       });
       return;
     }
+  }
 
-    // 妫�鏌ユ槸鍚︽湁浜у搧鏁版嵁
-    if (!productData.value || productData.value.length === 0) {
-      ElMessage({
-        message: "璇峰厛娣诲姞浜у搧淇℃伅",
-        type: "warning",
+  // 妫�鏌ヤ緵搴斿晢鏄惁閫夋嫨
+  if (!form.value.supplierId) {
+    ElMessage({
+      message: "璇峰厛閫夋嫨渚涘簲鍟�",
+      type: "warning",
+    });
+    return;
+  }
+
+  // 妫�鏌ユ槸鍚︽湁浜у搧鏁版嵁
+  if (!productData.value || productData.value.length === 0) {
+    ElMessage({
+      message: "璇峰厛娣诲姞浜у搧淇℃伅",
+      type: "warning",
+    });
+    return;
+  }
+
+  try {
+    let params = {
+      productData: proxy.HaveJson(productData.value),
+      supplierId: form.value.supplierId,
+      paymentMethod: form.value.paymentMethod,
+      recorderId: form.value.recorderId,
+      projectName: form.value.projectName,
+      templateName: templateName.value.trim(),
+    };
+    console.log(
+      "template params ===>",
+      params,
+      "currentTemplateId:",
+      currentTemplateId.value
+    );
+
+    // 濡傛灉 currentTemplateId 鏈夊�硷紝璇存槑褰撳墠鏄�滅紪杈戝凡鏈夋ā鏉库�� 鈫� 璋冪敤鏇存柊鎺ュ彛
+    // 鍚﹀垯涓衡�滄柊寤烘ā鏉库�� 鈫� 璋冪敤鏂板鎺ュ彛
+    let res;
+    if (currentTemplateId.value) {
+      res = await updatePurchaseTemplate({
+        id: currentTemplateId.value,
+        ...params,
       });
-      return;
+    } else {
+      res = await addPurchaseTemplate(params);
     }
 
-    try {
-      let params = {
-        productData: proxy.HaveJson(productData.value),
-        supplierId: form.value.supplierId,
-        paymentMethod: form.value.paymentMethod,
-        recorderId: form.value.recorderId,
-        projectName: form.value.projectName,
-        templateName: templateName.value.trim(),
-      };
-      console.log(
-        "template params ===>",
-        params,
-        "currentTemplateId:",
-        currentTemplateId.value
-      );
-
-      // 濡傛灉 currentTemplateId 鏈夊�硷紝璇存槑褰撳墠鏄�滅紪杈戝凡鏈夋ā鏉库�� 鈫� 璋冪敤鏇存柊鎺ュ彛
-      // 鍚﹀垯涓衡�滄柊寤烘ā鏉库�� 鈫� 璋冪敤鏂板鎺ュ彛
-      let res;
-      if (currentTemplateId.value) {
-        res = await updatePurchaseTemplate({
-          id: currentTemplateId.value,
-          ...params,
-        });
-      } else {
-        res = await addPurchaseTemplate(params);
-      }
-
-      if (res && res.code === 200) {
-        ElMessage({
-          message: currentTemplateId.value ? "妯℃澘鏇存柊鎴愬姛" : "妯℃澘淇濆瓨鎴愬姛",
-          type: "success",
-        });
-        // 淇濆瓨鎴愬姛鍚庨噸鏂拌幏鍙栨ā鏉垮垪琛�
-        await getTemplateList();
-        // 娓呯┖妯℃澘鍚嶇О杈撳叆
-        templateName.value = "";
-        filterInputValue.value = "";
-        isTemplateNameDuplicate.value = false;
-        // 淇濆瓨/鏇存柊瀹屾垚鍚庯紝閲嶇疆褰撳墠妯℃澘ID
-        currentTemplateId.value = null;
-      } else {
-        ElMessage({
-          message: res?.msg || "妯℃澘淇濆瓨澶辫触",
-          type: "error",
-        });
-      }
-    } catch (error) {
-      console.error("淇濆瓨妯℃澘澶辫触:", error);
+    if (res && res.code === 200) {
       ElMessage({
-        message: "妯℃澘淇濆瓨澶辫触锛岃绋嶅悗閲嶈瘯",
+        message: currentTemplateId.value ? "妯℃澘鏇存柊鎴愬姛" : "妯℃澘淇濆瓨鎴愬姛",
+        type: "success",
+      });
+      // 淇濆瓨鎴愬姛鍚庨噸鏂拌幏鍙栨ā鏉垮垪琛�
+      await getTemplateList();
+      // 娓呯┖妯℃澘鍚嶇О杈撳叆
+      templateName.value = "";
+      filterInputValue.value = "";
+      isTemplateNameDuplicate.value = false;
+      // 淇濆瓨/鏇存柊瀹屾垚鍚庯紝閲嶇疆褰撳墠妯℃澘ID
+      currentTemplateId.value = null;
+    } else {
+      ElMessage({
+        message: res?.msg || "妯℃澘淇濆瓨澶辫触",
         type: "error",
       });
     }
-  };
-  // 瀛愯〃鍚堣鏂规硶
-  const summarizeChildrenTable = param => {
-    return proxy.summarizeTable(
-      param,
-      [
-        "taxInclusiveUnitPrice",
-        "taxInclusiveTotalPrice",
-        "taxExclusiveTotalPrice",
-        "ticketsNum",
-        "ticketsAmount",
-        "futureTickets",
-        "futureTicketsAmount",
-      ],
-      {
-        ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
-        futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
-      }
-    );
-  };
-  const paginationChange = obj => {
-    page.current = obj.page;
-    page.size = obj.limit;
-    getList();
-  };
-  const getList = () => {
-    tableLoading.value = true;
-    const { entryDate, ...rest } = searchForm;
-    purchaseListPage({ ...rest, ...page })
-      .then(res => {
-        tableLoading.value = false;
-        // tableData.value = res.data.records;
-        tableData.value = res.data.records.map(record => ({
-          ...record,
-        }));
-        // 鍒濆鍖栧瓙鏁版嵁鏁扮粍
-        tableData.value.forEach(item => {
-          item.children = [];
-        });
-        total.value = res.data.total;
-        expandedRowKeys.value = [];
-      })
-      .catch(() => {
-        tableLoading.value = false;
-      });
-  };
-  // 琛ㄦ牸閫夋嫨鏁版嵁
-  const handleSelectionChange = selection => {
-    selectedRows.value = selection;
-  };
-  const productSelected = selectedRows => {
-    productSelectedRows.value = selectedRows;
-  };
-  const expandedRowKeys = ref([]);
-  // 灞曞紑琛�
-  const expandChange = async (row, expandedRows) => {
-    if (expandedRows.length > 0) {
-      expandedRowKeys.value = [];
-      try {
-        const res = await productList({ salesLedgerId: row.id, type: 2 });
-        const index = tableData.value.findIndex(item => item.id === row.id);
-        if (index > -1) {
-          tableData.value[index].children = res.data || [];
-          expandedRowKeys.value.push(row.id);
-        }
-      } catch (error) {
-        console.error("鍔犺浇浜у搧鍒楄〃澶辫触:", error);
-        proxy.$modal.msgError("鍔犺浇浜у搧鍒楄〃澶辫触");
-        // 灞曞紑澶辫触鏃讹紝绉婚櫎灞曞紑鐘舵��
-        const index = expandedRows.findIndex(item => item.id === row.id);
-        if (index > -1) {
-          expandedRows.splice(index, 1);
-        }
-      }
-    } else {
-      expandedRowKeys.value = [];
-    }
-  };
-  // 涓昏〃鍚堣鏂规硶
-  const summarizeMainTable = param => {
-    return proxy.summarizeTable(param, ["contractAmount"]);
-  };
-  // 瀛愯〃鍚堣鏂规硶
-  const summarizeProTable = param => {
-    return proxy.summarizeTable(param, [
+  } catch (error) {
+    console.error("淇濆瓨妯℃澘澶辫触:", error);
+    ElMessage({
+      message: "妯℃澘淇濆瓨澶辫触锛岃绋嶅悗閲嶈瘯",
+      type: "error",
+    });
+  }
+};
+// 瀛愯〃鍚堣鏂规硶
+const summarizeChildrenTable = param => {
+  return proxy.summarizeTable(
+    param,
+    [
       "taxInclusiveUnitPrice",
       "taxInclusiveTotalPrice",
       "taxExclusiveTotalPrice",
+      "ticketsNum",
+      "ticketsAmount",
+      "futureTickets",
+      "futureTicketsAmount",
+    ],
+    {
+      ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
+      futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
+    }
+  );
+};
+const paginationChange = obj => {
+  page.current = obj.page;
+  page.size = obj.limit;
+  getList();
+};
+const getList = () => {
+  tableLoading.value = true;
+  const { entryDate, ...rest } = searchForm;
+  purchaseListPage({ ...rest, ...page })
+    .then(res => {
+      tableLoading.value = false;
+      // tableData.value = res.data.records;
+      tableData.value = res.data.records.map(record => ({
+        ...record,
+      }));
+      // 鍒濆鍖栧瓙鏁版嵁鏁扮粍
+      tableData.value.forEach(item => {
+        item.children = [];
+      });
+      total.value = res.data.total;
+      expandedRowKeys.value = [];
+    })
+    .catch(() => {
+      tableLoading.value = false;
+    });
+};
+// 琛ㄦ牸閫夋嫨鏁版嵁
+const handleSelectionChange = selection => {
+  selectedRows.value = selection;
+};
+const productSelected = selectedRows => {
+  productSelectedRows.value = selectedRows;
+};
+const expandedRowKeys = ref([]);
+// 灞曞紑琛�
+const expandChange = async (row, expandedRows) => {
+  if (expandedRows.length > 0) {
+    expandedRowKeys.value = [];
+    try {
+      const res = await productList({ salesLedgerId: row.id, type: 2 });
+      const index = tableData.value.findIndex(item => item.id === row.id);
+      if (index > -1) {
+        tableData.value[index].children = res.data || [];
+        expandedRowKeys.value.push(row.id);
+      }
+    } catch (error) {
+      console.error("鍔犺浇浜у搧鍒楄〃澶辫触:", error);
+      proxy.$modal.msgError("鍔犺浇浜у搧鍒楄〃澶辫触");
+      // 灞曞紑澶辫触鏃讹紝绉婚櫎灞曞紑鐘舵��
+      const index = expandedRows.findIndex(item => item.id === row.id);
+      if (index > -1) {
+        expandedRows.splice(index, 1);
+      }
+    }
+  } else {
+    expandedRowKeys.value = [];
+  }
+};
+// 涓昏〃鍚堣鏂规硶
+const summarizeMainTable = param => {
+  return proxy.summarizeTable(param, ["contractAmount"]);
+};
+// 瀛愯〃鍚堣鏂规硶
+const summarizeProTable = param => {
+  return proxy.summarizeTable(param, [
+    "taxInclusiveUnitPrice",
+    "taxInclusiveTotalPrice",
+    "taxExclusiveTotalPrice",
+  ]);
+};
+// 鎵撳紑寮规
+const openForm = async (type, row) => {
+  if (type === 'detail') {
+    detailRef.value.open(row.id);
+    return;
+  }
+  // 缂栬緫鏃舵鏌ュ叆搴撶姸鎬侊紝瀹屽叏鍏ュ簱鏃朵笉鑳界紪杈�
+  if (type === "edit" && row) {
+    if (row.stockInStatus === '瀹屽叏鍏ュ簱') {
+      proxy.$modal.msgWarning("瀹屽叏鍏ュ簱鐘舵�佺殑璁板綍涓嶈兘缂栬緫");
+      return;
+    }
+  }
+
+  await getTemplateList();
+  await userListNoPage().then(res => {
+    userList.value = res.data;
+  });
+  operationType.value = type;
+  form.value = {};
+  productData.value = [];
+  fileList.value = [];
+  templateName.value = "";
+  filterInputValue.value = "";
+  isTemplateNameDuplicate.value = false;
+  try {
+    // 骞惰鍔犺浇鍩虹鏁版嵁
+    const [salesRes, supplierRes] = await Promise.all([
+      getSalesNo(),
+      getOptions(),
     ]);
-  };
-  // 鎵撳紑寮规
-  const openForm = async (type, row) => {
-    // 缂栬緫鏃舵鏌ュ叆搴撶姸鎬侊紝瀹屽叏鍏ュ簱鏃朵笉鑳界紪杈�
-    if (type === "edit" && row) {
-      if (row.stockInStatus === '瀹屽叏鍏ュ簱') {
-        proxy.$modal.msgWarning("瀹屽叏鍏ュ簱鐘舵�佺殑璁板綍涓嶈兘缂栬緫");
+
+    salesContractList.value = salesRes || [];
+    // 渚涘簲鍟嗚繃婊ゅ嚭isWhite=0 鐨勬暟鎹�
+    supplierList.value = (supplierRes.data || []).filter(
+      item => item.isWhite === 0
+    );
+
+    form.value.entryDate = getCurrentDate();
+
+    if (type === "add") {
+      // 鏂板鏃剁敓鎴愰噰璐悎鍚屽彿
+      try {
+        const purchaseNoRes = await createPurchaseNo();
+        if (purchaseNoRes?.data) {
+          form.value.purchaseContractNumber = purchaseNoRes.data;
+        }
+      } catch (error) {
+        console.error("鐢熸垚閲囪喘鍚堝悓鍙峰け璐�:", error);
+        proxy.$modal.msgWarning("鐢熸垚閲囪喘鍚堝悓鍙峰け璐�");
+      }
+    } else if (type === "edit" && row?.id) {
+      // 缂栬緫鏃跺姞杞芥暟鎹�
+      currentId.value = row.id;
+      try {
+        const purchaseRes = await getPurchaseById({ id: row.id, type: 2 });
+        form.value = { ...purchaseRes, stockInStatus: row.stockInStatus };
+        fileList.value = purchaseRes.storageBlobVOS || [];
+        // 浣跨敤 productList 鎺ュ彛鑾峰彇浜у搧鍒楄〃锛屼互鑾峰彇鍏ュ簱瀹℃牳鐘舵��
+        const productRes = await productList({ salesLedgerId: row.id, type: 2 });
+        productData.value = productRes.data || [];
+      } catch (error) {
+        console.error("鍔犺浇閲囪喘鍙拌处鏁版嵁澶辫触:", error);
+        proxy.$modal.msgError("鍔犺浇鏁版嵁澶辫触");
         return;
       }
     }
 
-    await getTemplateList();
-    await userListNoPage().then(res => {
-      userList.value = res.data;
-    });
-    operationType.value = type;
-    form.value = {};
-    productData.value = [];
-    fileList.value = [];
-    templateName.value = "";
-    filterInputValue.value = "";
-    isTemplateNameDuplicate.value = false;
+    if (form.value.salesLedgerId == -1) {
+      form.value.salesLedgerId = null;
+    }
+    console.log(form.value, "form.value===========");
+    dialogFormVisible.value = true;
+  } catch (error) {
+    console.error("鎵撳紑琛ㄥ崟澶辫触:", error);
+    proxy.$modal.msgError("鍔犺浇鍩虹鏁版嵁澶辫触");
+  }
+};
+
+// 涓婁紶鍓嶆牎妫�
+function handleBeforeUpload(file) {
+  // 鏍℃鏂囦欢澶у皬
+  if (file.size > 1024 * 1024 * 10) {
+    proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃10MB!");
+    return false;
+  }
+  proxy.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��...");
+  return true;
+}
+
+// 涓婁紶澶辫触
+function handleUploadError(err) {
+  proxy.$modal.msgError("涓婁紶鏂囦欢澶辫触");
+  proxy.$modal.closeLoading();
+}
+
+// 涓婁紶鎴愬姛鍥炶皟
+function handleUploadSuccess(res, file, uploadFiles) {
+  proxy.$modal.closeLoading();
+  if (res.code === 200) {
+    file.tempId = res.data.tempId;
+    proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
+  } else {
+    proxy.$modal.msgError(res.msg);
+    proxy.$refs.fileUpload.handleRemove(file);
+  }
+}
+
+// 绉婚櫎鏂囦欢
+async function handleRemove(file) {
+  if (!file?.id) {
+    return;
+  }
+  console.log("handleRemove", file.id);
+  if (file.size > 1024 * 1024 * 10) {
+    // 浠呭墠绔竻鐞嗭紝涓嶈皟鐢ㄥ垹闄ゆ帴鍙e拰鎻愮ず
+    return;
+  }
+
+  if (operationType.value === "edit" && file.id) {
     try {
-      // 骞惰鍔犺浇鍩虹鏁版嵁
-      const [salesRes, supplierRes] = await Promise.all([
-        getSalesNo(),
-        getOptions(),
-      ]);
-
-      salesContractList.value = salesRes || [];
-      // 渚涘簲鍟嗚繃婊ゅ嚭isWhite=0 鐨勬暟鎹�
-      supplierList.value = (supplierRes.data || []).filter(
-        item => item.isWhite === 0
-      );
-
-      form.value.entryDate = getCurrentDate();
-
-      if (type === "add") {
-        // 鏂板鏃剁敓鎴愰噰璐悎鍚屽彿
-        try {
-          const purchaseNoRes = await createPurchaseNo();
-          if (purchaseNoRes?.data) {
-            form.value.purchaseContractNumber = purchaseNoRes.data;
-          }
-        } catch (error) {
-          console.error("鐢熸垚閲囪喘鍚堝悓鍙峰け璐�:", error);
-          proxy.$modal.msgWarning("鐢熸垚閲囪喘鍚堝悓鍙峰け璐�");
-        }
-      } else if (type === "edit" && row?.id) {
-        // 缂栬緫鏃跺姞杞芥暟鎹�
-        currentId.value = row.id;
-        try {
-          const purchaseRes = await getPurchaseById({ id: row.id, type: 2 });
-          form.value = { ...purchaseRes, stockInStatus: row.stockInStatus };
-          fileList.value = purchaseRes.storageBlobVOS || [];
-          // 浣跨敤 productList 鎺ュ彛鑾峰彇浜у搧鍒楄〃锛屼互鑾峰彇鍏ュ簱瀹℃牳鐘舵��
-          const productRes = await productList({ salesLedgerId: row.id, type: 2 });
-          productData.value = productRes.data || [];
-        } catch (error) {
-          console.error("鍔犺浇閲囪喘鍙拌处鏁版嵁澶辫触:", error);
-          proxy.$modal.msgError("鍔犺浇鏁版嵁澶辫触");
-          return;
-        }
-      }
-
-      if (form.value.salesLedgerId == -1) {
-        form.value.salesLedgerId = null;
-      }
-      console.log(form.value, "form.value===========");
-      dialogFormVisible.value = true;
+      await delLedgerFile([file.id]);
+      proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
     } catch (error) {
-      console.error("鎵撳紑琛ㄥ崟澶辫触:", error);
-      proxy.$modal.msgError("鍔犺浇鍩虹鏁版嵁澶辫触");
-    }
-  };
-
-  // 涓婁紶鍓嶆牎妫�
-  function handleBeforeUpload(file) {
-    // 鏍℃鏂囦欢澶у皬
-    if (file.size > 1024 * 1024 * 10) {
-      proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃10MB!");
-      return false;
-    }
-    proxy.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��...");
-    return true;
-  }
-
-  // 涓婁紶澶辫触
-  function handleUploadError(err) {
-    proxy.$modal.msgError("涓婁紶鏂囦欢澶辫触");
-    proxy.$modal.closeLoading();
-  }
-
-  // 涓婁紶鎴愬姛鍥炶皟
-  function handleUploadSuccess(res, file, uploadFiles) {
-    proxy.$modal.closeLoading();
-    if (res.code === 200) {
-      file.tempId = res.data.tempId;
-      proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
-    } else {
-      proxy.$modal.msgError(res.msg);
-      proxy.$refs.fileUpload.handleRemove(file);
+      console.error("鍒犻櫎鏂囦欢澶辫触:", error);
+      proxy.$modal.msgError("鍒犻櫎鏂囦欢澶辫触");
     }
   }
+}
 
-  // 绉婚櫎鏂囦欢
-  async function handleRemove(file) {
-    if (!file?.id) {
-      return;
-    }
-    console.log("handleRemove", file.id);
-    if (file.size > 1024 * 1024 * 10) {
-      // 浠呭墠绔竻鐞嗭紝涓嶈皟鐢ㄥ垹闄ゆ帴鍙e拰鎻愮ず
-      return;
-    }
-
-    if (operationType.value === "edit" && file.id) {
-      try {
-        await delLedgerFile([file.id]);
-        proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-      } catch (error) {
-        console.error("鍒犻櫎鏂囦欢澶辫触:", error);
-        proxy.$modal.msgError("鍒犻櫎鏂囦欢澶辫触");
-      }
-    }
-  }
-
-  // 鎻愪氦琛ㄥ崟
-  const submitForm = () => {
-    proxy.$refs["formRef"].validate(valid => {
-      if (valid) {
-        if (productData.value.length > 0) {
-          // 鏂板鏃讹紝闇�瑕佷粠姣忎釜浜у搧瀵硅薄涓垹闄� id 瀛楁
-          let processedProductData = productData.value;
-          if (operationType.value === "add") {
-            processedProductData = productData.value.map(product => {
-              const { id, ...rest } = product;
-              return rest;
-            });
-          }
-          form.value.productData = proxy.HaveJson(processedProductData);
-        } else {
-          proxy.$modal.msgWarning("璇锋坊鍔犱骇鍝佷俊鎭�");
-          return;
-        }
-        form.value.storageBlobDTOS = fileList.value;
-        form.value.type = 2;
-
-        // 濡傛灉salesLedgerId涓虹┖锛屽垯涓嶄紶閫抯alesContractNo
-        if (!form.value.salesLedgerId) {
-          form.value.salesContractNo = "";
-        }
-
-        // 鏂板鏃朵笉浼犻�抜d
-        const submitData = { ...form.value };
+// 鎻愪氦琛ㄥ崟
+const submitForm = () => {
+  proxy.$refs["formRef"].validate(valid => {
+    if (valid) {
+      if (productData.value.length > 0) {
+        // 鏂板鏃讹紝闇�瑕佷粠姣忎釜浜у搧瀵硅薄涓垹闄� id 瀛楁
+        let processedProductData = productData.value;
         if (operationType.value === "add") {
-          delete submitData.id;
+          processedProductData = productData.value.map(product => {
+            const { id, ...rest } = product;
+            return rest;
+          });
         }
-
-        addOrEditPurchase(submitData).then(res => {
-          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-          closeDia();
-          getList();
-        });
+        form.value.productData = proxy.HaveJson(processedProductData);
+      } else {
+        proxy.$modal.msgWarning("璇锋坊鍔犱骇鍝佷俊鎭�");
+        return;
       }
-    });
-  };
-  // 鍏抽棴寮规
-  const closeDia = () => {
-    proxy.resetForm("formRef");
-    dialogFormVisible.value = false;
-  };
-  // 鎵撳紑浜у搧寮规
-  const openProductForm = async (type, row, index) => {
-    // 缂栬緫鏃舵鏌ヤ骇鍝佸叆搴撳鏍哥姸鎬侊紝瀹屽叏鍏ュ簱鏃朵笉鑳界紪杈�
-    if (type === "edit" && row && row.stockInApprovalStatus === '瀹屽叏鍏ュ簱') {
-      proxy.$modal.msgWarning("瀹屽叏鍏ュ簱鐘舵�佺殑浜у搧涓嶈兘缂栬緫");
-      return;
+      form.value.storageBlobDTOS = fileList.value;
+      form.value.type = 2;
+
+      // 濡傛灉salesLedgerId涓虹┖锛屽垯涓嶄紶閫抯alesContractNo
+      if (!form.value.salesLedgerId) {
+        form.value.salesContractNo = "";
+      }
+
+      // 鏂板鏃朵笉浼犻�抜d
+      const submitData = { ...form.value };
+      if (operationType.value === "add") {
+        delete submitData.id;
+      }
+
+      addOrEditPurchase(submitData).then(res => {
+        proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+        closeDia();
+        getList();
+      });
     }
+  });
+};
+// 鍏抽棴寮规
+const closeDia = () => {
+  proxy.resetForm("formRef");
+  dialogFormVisible.value = false;
+};
+// 鎵撳紑浜у搧寮规
+const openProductForm = async (type, row, index) => {
+  // 缂栬緫鏃舵鏌ヤ骇鍝佸叆搴撳鏍哥姸鎬侊紝瀹屽叏鍏ュ簱鏃朵笉鑳界紪杈�
+  if (type === "edit" && row && row.stockInApprovalStatus === '瀹屽叏鍏ュ簱') {
+    proxy.$modal.msgWarning("瀹屽叏鍏ュ簱鐘舵�佺殑浜у搧涓嶈兘缂栬緫");
+    return;
+  }
 
-    productOperationType.value = type;
-    productOperationIndex.value = index;
-    productForm.value = {};
-    proxy.resetForm("productFormRef");
-    productFormVisible.value = true;
+  productOperationType.value = type;
+  productOperationIndex.value = index;
+  productForm.value = {};
+  proxy.resetForm("productFormRef");
+  productFormVisible.value = true;
 
-    // 鍏堣幏鍙栦骇鍝侀�夐」锛岀‘淇濇暟鎹姞杞藉畬鎴�
-    await getProductOptions();
+  // 鍏堣幏鍙栦骇鍝侀�夐」锛岀‘淇濇暟鎹姞杞藉畬鎴�
+  await getProductOptions();
 
-    // 绛夊緟 DOM 鏇存柊
-    await nextTick();
+  // 绛夊緟 DOM 鏇存柊
+  await nextTick();
 
-    if (type === "add") {
-      productForm.value.isChecked = false;
-    }
+  if (type === "add") {
+    productForm.value.isChecked = false;
+  }
 
-    if (type === "edit") {
-      // 澶嶅埗琛屾暟鎹�
-      productForm.value = { ...row };
+  if (type === "edit") {
+    // 澶嶅埗琛屾暟鎹�
+    productForm.value = { ...row };
 
-      // 濡傛灉鏄粠妯℃澘鍔犺浇鐨勬暟鎹紝鍙兘娌℃湁 productId 鍜� productModelId
-      // 闇�瑕佹牴鎹� productCategory 鍜� specificationModel 鏉ユ煡鎵惧搴旂殑 ID
-      if (!productForm.value.productId && productForm.value.productCategory) {
-        // 鏍规嵁 productCategory 鏌ユ壘 productId
-        const findProductIdByCategory = (nodes, categoryName) => {
-          for (let i = 0; i < nodes.length; i++) {
-            if (nodes[i].label === categoryName) {
-              return nodes[i].value;
-            }
-            if (nodes[i].children && nodes[i].children.length > 0) {
-              const found = findProductIdByCategory(
-                nodes[i].children,
-                categoryName
-              );
-              if (found) return found;
-            }
+    // 濡傛灉鏄粠妯℃澘鍔犺浇鐨勬暟鎹紝鍙兘娌℃湁 productId 鍜� productModelId
+    // 闇�瑕佹牴鎹� productCategory 鍜� specificationModel 鏉ユ煡鎵惧搴旂殑 ID
+    if (!productForm.value.productId && productForm.value.productCategory) {
+      // 鏍规嵁 productCategory 鏌ユ壘 productId
+      const findProductIdByCategory = (nodes, categoryName) => {
+        for (let i = 0; i < nodes.length; i++) {
+          if (nodes[i].label === categoryName) {
+            return nodes[i].value;
           }
-          return null;
-        };
-
-        const productId = findProductIdByCategory(
-          productOptions.value,
-          productForm.value.productCategory
-        );
-        if (productId) {
-          productForm.value.productId = productId;
-          // 鑾峰彇鍨嬪彿鍒楄〃骞剁瓑寰呭畬鎴�
-          const modelRes = await modelList({ id: productId });
-          modelOptions.value = modelRes;
-
-          // 绛夊緟 DOM 鏇存柊
-          await nextTick();
-
-          // 鏍规嵁 specificationModel 鏌ユ壘 productModelId
-          if (
-            productForm.value.specificationModel &&
-            modelOptions.value.length > 0
-          ) {
-            const modelItem = modelOptions.value.find(
-              item => item.model === productForm.value.specificationModel
+          if (nodes[i].children && nodes[i].children.length > 0) {
+            const found = findProductIdByCategory(
+              nodes[i].children,
+              categoryName
             );
-            if (modelItem) {
-              productForm.value.productModelId = modelItem.id;
-              // 璁剧疆瑙勬牸鍨嬪彿鍜屽崟浣�
-              getProductModel(modelItem.id);
-            }
+            if (found) return found;
           }
         }
-      } else if (productForm.value.productId) {
-        // 濡傛灉鏈� productId锛屾甯稿姞杞藉瀷鍙峰垪琛�
-        await getModels(productForm.value.productId);
+        return null;
+      };
+
+      const productId = findProductIdByCategory(
+        productOptions.value,
+        productForm.value.productCategory
+      );
+      if (productId) {
+        productForm.value.productId = productId;
+        // 鑾峰彇鍨嬪彿鍒楄〃骞剁瓑寰呭畬鎴�
+        const modelRes = await modelList({ id: productId });
+        modelOptions.value = modelRes;
 
         // 绛夊緟 DOM 鏇存柊
         await nextTick();
 
-        if (productForm.value.productModelId) {
-          getProductModel(productForm.value.productModelId);
+        // 鏍规嵁 specificationModel 鏌ユ壘 productModelId
+        if (
+          productForm.value.specificationModel &&
+          modelOptions.value.length > 0
+        ) {
+          const modelItem = modelOptions.value.find(
+            item => item.model === productForm.value.specificationModel
+          );
+          if (modelItem) {
+            productForm.value.productModelId = modelItem.id;
+            // 璁剧疆瑙勬牸鍨嬪彿鍜屽崟浣�
+            getProductModel(modelItem.id);
+          }
         }
       }
+    } else if (productForm.value.productId) {
+      // 濡傛灉鏈� productId锛屾甯稿姞杞藉瀷鍙峰垪琛�
+      await getModels(productForm.value.productId);
 
-      // 鏈�鍚庡啀绛夊緟涓�娆� DOM 鏇存柊锛岀‘淇濇墍鏈夋暟鎹兘宸茶缃�
+      // 绛夊緟 DOM 鏇存柊
       await nextTick();
+
+      if (productForm.value.productModelId) {
+        getProductModel(productForm.value.productModelId);
+      }
     }
-  };
-  const getProductOptions = () => {
-    return productTreeList().then(res => {
-      productOptions.value = convertIdToValue(res);
+
+    // 鏈�鍚庡啀绛夊緟涓�娆� DOM 鏇存柊锛岀‘淇濇墍鏈夋暟鎹兘宸茶缃�
+    await nextTick();
+  }
+};
+const getProductOptions = () => {
+  return productTreeList().then(res => {
+    productOptions.value = convertIdToValue(res);
+    return res;
+  });
+};
+const getModels = value => {
+  if (value) {
+    productForm.value.productCategory =
+      findNodeById(productOptions.value, value) || "";
+    return modelList({ id: value }).then(res => {
+      modelOptions.value = res;
       return res;
     });
-  };
-  const getModels = value => {
-    if (value) {
-      productForm.value.productCategory =
-        findNodeById(productOptions.value, value) || "";
-      return modelList({ id: value }).then(res => {
-        modelOptions.value = res;
-        return res;
-      });
-    } else {
-      productForm.value.productCategory = "";
-      modelOptions.value = [];
-      return Promise.resolve([]);
+  } else {
+    productForm.value.productCategory = "";
+    modelOptions.value = [];
+    return Promise.resolve([]);
+  }
+};
+const getProductModel = value => {
+  const index = modelOptions.value.findIndex(item => item.id === value);
+  if (index !== -1) {
+    productForm.value.specificationModel = modelOptions.value[index].model;
+    productForm.value.unit = modelOptions.value[index].unit;
+  } else {
+    productForm.value.specificationModel = null;
+    productForm.value.unit = null;
+  }
+};
+const findNodeById = (nodes, productId) => {
+  for (let i = 0; i < nodes.length; i++) {
+    if (nodes[i].value === productId) {
+      return nodes[i].label; // 鎵惧埌鑺傜偣锛岃繑鍥炶鑺傜偣鐨刲abel
     }
-  };
-  const getProductModel = value => {
-    const index = modelOptions.value.findIndex(item => item.id === value);
-    if (index !== -1) {
-      productForm.value.specificationModel = modelOptions.value[index].model;
-      productForm.value.unit = modelOptions.value[index].unit;
-    } else {
-      productForm.value.specificationModel = null;
-      productForm.value.unit = null;
-    }
-  };
-  const findNodeById = (nodes, productId) => {
-    for (let i = 0; i < nodes.length; i++) {
-      if (nodes[i].value === productId) {
-        return nodes[i].label; // 鎵惧埌鑺傜偣锛岃繑鍥炶鑺傜偣鐨刲abel
+    if (nodes[i].children && nodes[i].children.length > 0) {
+      const foundNode = findNodeById(nodes[i].children, productId);
+      if (foundNode) {
+        return foundNode; // 鍦ㄥ瓙鑺傜偣涓壘鍒帮紝鐩存帴杩斿洖锛堝凡缁忔槸label瀛楃涓诧級
       }
-      if (nodes[i].children && nodes[i].children.length > 0) {
-        const foundNode = findNodeById(nodes[i].children, productId);
-        if (foundNode) {
-          return foundNode; // 鍦ㄥ瓙鑺傜偣涓壘鍒帮紝鐩存帴杩斿洖锛堝凡缁忔槸label瀛楃涓诧級
+    }
+  }
+  return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
+};
+
+function convertIdToValue(data) {
+  return data.map(item => {
+    const { id, children, ...rest } = item;
+    const newItem = {
+      ...rest,
+      value: id, // 灏� id 鏀逛负 value
+    };
+    if (children && children.length > 0) {
+      newItem.children = convertIdToValue(children);
+    }
+
+    return newItem;
+  });
+}
+
+// 鎻愪氦浜у搧琛ㄥ崟
+const submitProduct = () => {
+  proxy.$refs["productFormRef"].validate(valid => {
+    if (valid) {
+      if (operationType.value === "edit") {
+        submitProductEdit();
+      } else {
+        if (productOperationType.value === "add") {
+          productData.value.push({ ...productForm.value });
+          console.log("productData.value---", productData.value);
+        } else {
+          productData.value[productOperationIndex.value] = {
+            ...productForm.value,
+          };
         }
+        closeProductDia();
       }
     }
-    return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
-  };
-
-  function convertIdToValue(data) {
-    return data.map(item => {
-      const { id, children, ...rest } = item;
-      const newItem = {
-        ...rest,
-        value: id, // 灏� id 鏀逛负 value
-      };
-      if (children && children.length > 0) {
-        newItem.children = convertIdToValue(children);
-      }
-
-      return newItem;
+  });
+};
+const submitProductEdit = () => {
+  productForm.value.salesLedgerId = currentId.value;
+  productForm.value.type = 2;
+  addOrUpdateSalesLedgerProduct(productForm.value).then(res => {
+    proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+    closeProductDia();
+    // 浣跨敤 productList 鎺ュ彛鍒锋柊浜у搧鍒楄〃锛屼互鑾峰彇鍏ュ簱瀹℃牳鐘舵��
+    productList({ salesLedgerId: currentId.value, type: 2 }).then(res => {
+      productData.value = res.data || [];
     });
+  });
+};
+// 鍒犻櫎浜у搧
+const deleteProduct = () => {
+  if (productSelectedRows.value.length === 0) {
+    proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+    return;
+  }
+  // 妫�鏌ラ�変腑鐨勪骇鍝佷腑鏄惁鏈夊畬鍏ㄥ叆搴撶殑
+  const hasFullyStocked = productSelectedRows.value.some(
+    row => row.stockInApprovalStatus === '瀹屽叏鍏ュ簱'
+  );
+  if (hasFullyStocked) {
+    proxy.$modal.msgWarning("閫変腑鐨勪骇鍝佷腑鍖呭惈瀹屽叏鍏ュ簱鐨勪骇鍝侊紝鏃犳硶鍒犻櫎");
+    return;
+  }
+  if (operationType.value === "add") {
+    productData.value = productData.value.filter(
+      item => !productSelectedRows.value.includes(item)
+    );
+    productSelectedRows.value = [];
+  } else {
+    let ids = [];
+    if (productSelectedRows.value.length > 0) {
+      ids = productSelectedRows.value.map(item => item.id);
+    }
+    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
+      .then(() => {
+        delProduct(ids).then(res => {
+          proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+          closeProductDia();
+          // 浣跨敤 productList 鎺ュ彛鍒锋柊浜у搧鍒楄〃锛屼互鑾峰彇鍏ュ簱瀹℃牳鐘舵��
+          productList({ salesLedgerId: currentId.value, type: 2 }).then(res => {
+            productData.value = res.data || [];
+          });
+        });
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+  }
+};
+// 鍏抽棴浜у搧寮规
+const closeProductDia = () => {
+  proxy.resetForm("productFormRef");
+  productFormVisible.value = false;
+};
+// 瀵煎嚭
+const handleOut = () => {
+  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  })
+    .then(() => {
+      proxy.download("/purchase/ledger/export", {}, "閲囪喘鍙拌处.xlsx");
+    })
+    .catch(() => {
+      proxy.$modal.msg("宸插彇娑�");
+    });
+};
+// 鍒犻櫎
+const handleDelete = () => {
+  let ids = [];
+  if (selectedRows.value.length > 0) {
+    ids = selectedRows.value
+      .filter(item => item.salesLedgerId === null)
+      .map(item => item.id);
+  } else {
+    proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+    return;
+  }
+  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  })
+    .then(() => {
+      delPurchase(ids).then(res => {
+        proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+        getList();
+      });
+    })
+    .catch(() => {
+      proxy.$modal.msg("宸插彇娑�");
+    });
+};
+
+// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� 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}`;
+}
+
+const mathNum = () => {
+  if (!productForm.value.taxRate) {
+    proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
+    return;
+  }
+  if (!productForm.value.taxInclusiveUnitPrice) {
+    return;
+  }
+  if (!productForm.value.quantity) {
+    return;
+  }
+  // 鍚◣鎬讳环璁$畻
+  productForm.value.taxInclusiveTotalPrice =
+    proxy.calculateTaxIncludeTotalPrice(
+      productForm.value.taxInclusiveUnitPrice,
+      productForm.value.quantity
+    );
+  if (productForm.value.taxRate) {
+    // 涓嶅惈绋庢�讳环璁$畻
+    productForm.value.taxExclusiveTotalPrice =
+      proxy.calculateTaxExclusiveTotalPrice(
+        productForm.value.taxInclusiveTotalPrice,
+        productForm.value.taxRate
+      );
+  }
+};
+const reverseMathNum = field => {
+  if (!productForm.value.taxRate) {
+    proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
+    return;
+  }
+  const taxRate = Number(productForm.value.taxRate);
+  if (!taxRate) return;
+
+  // 纭繚杈撳叆鍊间笉涓鸿礋鏁�
+  if (
+    field === "taxInclusiveTotalPrice" ||
+    field === "taxExclusiveTotalPrice"
+  ) {
+    const value = Number(productForm.value[field]);
+    if (value < 0) {
+      productForm.value[field] = "0";
+      proxy.$modal.msgWarning("鍊间笉鑳藉皬浜�0");
+      return;
+    }
   }
 
-  // 鎻愪氦浜у搧琛ㄥ崟
-  const submitProduct = () => {
-    proxy.$refs["productFormRef"].validate(valid => {
-      if (valid) {
-        if (operationType.value === "edit") {
-          submitProductEdit();
-        } else {
-          if (productOperationType.value === "add") {
-            productData.value.push({ ...productForm.value });
-            console.log("productData.value---", productData.value);
-          } else {
-            productData.value[productOperationIndex.value] = {
-              ...productForm.value,
-            };
-          }
-          closeProductDia();
-        }
+  if (field === "taxInclusiveTotalPrice") {
+    // 宸茬煡鍚◣鎬讳环鍜屾暟閲忥紝鍙嶇畻鍚◣鍗曚环
+    if (productForm.value.quantity) {
+      productForm.value.taxInclusiveUnitPrice = (
+        Number(productForm.value.taxInclusiveTotalPrice) /
+        Number(productForm.value.quantity)
+      ).toFixed(2);
+      // 纭繚缁撴灉涓嶄负璐熸暟
+      if (Number(productForm.value.taxInclusiveUnitPrice) < 0) {
+        productForm.value.taxInclusiveUnitPrice = "0";
       }
-    });
-  };
-  const submitProductEdit = () => {
-    productForm.value.salesLedgerId = currentId.value;
-    productForm.value.type = 2;
-    addOrUpdateSalesLedgerProduct(productForm.value).then(res => {
-      proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-      closeProductDia();
-      // 浣跨敤 productList 鎺ュ彛鍒锋柊浜у搧鍒楄〃锛屼互鑾峰彇鍏ュ簱瀹℃牳鐘舵��
-      productList({ salesLedgerId: currentId.value, type: 2 }).then(res => {
-        productData.value = res.data || [];
-      });
-    });
-  };
-  // 鍒犻櫎浜у搧
-  const deleteProduct = () => {
-    if (productSelectedRows.value.length === 0) {
-      proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
-      return;
     }
-    // 妫�鏌ラ�変腑鐨勪骇鍝佷腑鏄惁鏈夊畬鍏ㄥ叆搴撶殑
-    const hasFullyStocked = productSelectedRows.value.some(
-      row => row.stockInApprovalStatus === '瀹屽叏鍏ュ簱'
-    );
-    if (hasFullyStocked) {
-      proxy.$modal.msgWarning("閫変腑鐨勪骇鍝佷腑鍖呭惈瀹屽叏鍏ュ簱鐨勪骇鍝侊紝鏃犳硶鍒犻櫎");
-      return;
-    }
-    if (operationType.value === "add") {
-      productData.value = productData.value.filter(
-        item => !productSelectedRows.value.includes(item)
-      );
-      productSelectedRows.value = [];
-    } else {
-      let ids = [];
-      if (productSelectedRows.value.length > 0) {
-        ids = productSelectedRows.value.map(item => item.id);
+    // 宸茬煡鍚◣鎬讳环鍜屽惈绋庡崟浠凤紝鍙嶇畻鏁伴噺
+    else if (productForm.value.taxInclusiveUnitPrice) {
+      productForm.value.quantity = (
+        Number(productForm.value.taxInclusiveTotalPrice) /
+        Number(productForm.value.taxInclusiveUnitPrice)
+      ).toFixed(2);
+      // 纭繚缁撴灉涓嶄负璐熸暟
+      if (Number(productForm.value.quantity) < 0) {
+        productForm.value.quantity = "0";
       }
-      ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
-        confirmButtonText: "纭",
+    }
+    // 鍙嶇畻涓嶅惈绋庢�讳环
+    productForm.value.taxExclusiveTotalPrice = (
+      Number(productForm.value.taxInclusiveTotalPrice) /
+      (1 + taxRate / 100)
+    ).toFixed(2);
+    // 纭繚缁撴灉涓嶄负璐熸暟
+    if (Number(productForm.value.taxExclusiveTotalPrice) < 0) {
+      productForm.value.taxExclusiveTotalPrice = "0";
+    }
+  } else if (field === "taxExclusiveTotalPrice") {
+    // 鍙嶇畻鍚◣鎬讳环
+    productForm.value.taxInclusiveTotalPrice = (
+      Number(productForm.value.taxExclusiveTotalPrice) *
+      (1 + taxRate / 100)
+    ).toFixed(2);
+    // 纭繚缁撴灉涓嶄负璐熸暟
+    if (Number(productForm.value.taxInclusiveTotalPrice) < 0) {
+      productForm.value.taxInclusiveTotalPrice = "0";
+    }
+    // 宸茬煡鏁伴噺锛屽弽绠楀惈绋庡崟浠�
+    if (productForm.value.quantity) {
+      productForm.value.taxInclusiveUnitPrice = (
+        Number(productForm.value.taxInclusiveTotalPrice) /
+        Number(productForm.value.quantity)
+      ).toFixed(2);
+      // 纭繚缁撴灉涓嶄负璐熸暟
+      if (Number(productForm.value.taxInclusiveUnitPrice) < 0) {
+        productForm.value.taxInclusiveUnitPrice = "0";
+      }
+    }
+    // 宸茬煡鍚◣鍗曚环锛屽弽绠楁暟閲�
+    else if (productForm.value.taxInclusiveUnitPrice) {
+      productForm.value.quantity = (
+        Number(productForm.value.taxInclusiveTotalPrice) /
+        Number(productForm.value.taxInclusiveUnitPrice)
+      ).toFixed(2);
+      // 纭繚缁撴灉涓嶄负璐熸暟
+      if (Number(productForm.value.quantity) < 0) {
+        productForm.value.quantity = "0";
+      }
+    }
+  }
+};
+// 閿�鍞悎鍚岄�夋嫨鏀瑰彉鏂规硶
+const salesLedgerChange = async row => {
+  console.log("row", row);
+  var index = salesContractList.value.findIndex(item => item.id == row);
+  console.log("index", index);
+  if (index > -1) {
+    await querygProductInfoByContractNo();
+  }
+};
+
+const querygProductInfoByContractNo = async () => {
+  const { code, data } = await getProductInfoByContractNo({
+    contractNo: form.value.salesLedgerId,
+  });
+  if (code == 200) {
+    productData.value = data;
+  }
+};
+
+// 鑾峰彇妯℃澘淇℃伅
+const getTemplateList = async () => {
+  let res = await getPurchaseTemplateList();
+  if (res && res.code === 200 && Array.isArray(res.data)) {
+    templateList.value = res.data;
+  }
+};
+
+// 鎵撳紑闄勪欢寮规
+const openFileDialog = async row => {
+  recordId.value = row.id;
+  fileListDialogVisible.value = true;
+};
+
+// 鍒犻櫎妯℃澘
+const handleDeleteTemplate = async item => {
+  if (!item.id) {
+    proxy.$modal.msgWarning("鏃犳硶鍒犻櫎璇ユā鏉�");
+    return;
+  }
+
+  try {
+    await ElMessageBox.confirm(
+      `纭畾瑕佸垹闄ゆā鏉�"${item.templateName}"鍚楋紵`,
+      "鍒犻櫎纭",
+      {
+        confirmButtonText: "纭畾",
         cancelButtonText: "鍙栨秷",
         type: "warning",
-      })
-        .then(() => {
-          delProduct(ids).then(res => {
-            proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-            closeProductDia();
-            // 浣跨敤 productList 鎺ュ彛鍒锋柊浜у搧鍒楄〃锛屼互鑾峰彇鍏ュ簱瀹℃牳鐘舵��
-            productList({ salesLedgerId: currentId.value, type: 2 }).then(res => {
-              productData.value = res.data || [];
-            });
-          });
-        })
-        .catch(() => {
-          proxy.$modal.msg("宸插彇娑�");
-        });
-    }
-  };
-  // 鍏抽棴浜у搧寮规
-  const closeProductDia = () => {
-    proxy.resetForm("productFormRef");
-    productFormVisible.value = false;
-  };
-  // 瀵煎嚭
-  const handleOut = () => {
-    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
-      confirmButtonText: "纭",
-      cancelButtonText: "鍙栨秷",
-      type: "warning",
-    })
-      .then(() => {
-        proxy.download("/purchase/ledger/export", {}, "閲囪喘鍙拌处.xlsx");
-      })
-      .catch(() => {
-        proxy.$modal.msg("宸插彇娑�");
+      }
+    );
+
+    const res = await delPurchaseTemplate([item.id]);
+    if (res && res.code === 200) {
+      ElMessage({
+        message: "鍒犻櫎鎴愬姛",
+        type: "success",
       });
-  };
-  // 鍒犻櫎
-  const handleDelete = () => {
-    let ids = [];
-    if (selectedRows.value.length > 0) {
-      ids = selectedRows.value
-        .filter(item => item.salesLedgerId === null)
-        .map(item => item.id);
+      // 濡傛灉鍒犻櫎鐨勬槸褰撳墠閫変腑鐨勬ā鏉匡紝娓呯┖閫夋嫨
+      if (templateName.value === item.templateName) {
+        templateName.value = "";
+        filterInputValue.value = "";
+      }
+      // 閲嶆柊鑾峰彇妯℃澘鍒楄〃
+      await getTemplateList();
     } else {
-      proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
-      return;
-    }
-    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎", {
-      confirmButtonText: "纭",
-      cancelButtonText: "鍙栨秷",
-      type: "warning",
-    })
-      .then(() => {
-        delPurchase(ids).then(res => {
-          proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-          getList();
-        });
-      })
-      .catch(() => {
-        proxy.$modal.msg("宸插彇娑�");
+      ElMessage({
+        message: res?.msg || "鍒犻櫎澶辫触",
+        type: "error",
       });
-  };
-
-  // 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� 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}`;
+    }
+  } catch (error) {
+    if (error !== "cancel") {
+      console.error("鍒犻櫎妯℃澘澶辫触:", error);
+      ElMessage({
+        message: "鍒犻櫎澶辫触锛岃绋嶅悗閲嶈瘯",
+        type: "error",
+      });
+    }
   }
+};
 
-  const mathNum = () => {
-    if (!productForm.value.taxRate) {
-      proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
-      return;
-    }
-    if (!productForm.value.taxInclusiveUnitPrice) {
-      return;
-    }
-    if (!productForm.value.quantity) {
-      return;
-    }
-    // 鍚◣鎬讳环璁$畻
-    productForm.value.taxInclusiveTotalPrice =
-      proxy.calculateTaxIncludeTotalPrice(
-        productForm.value.taxInclusiveUnitPrice,
-        productForm.value.quantity
-      );
-    if (productForm.value.taxRate) {
-      // 涓嶅惈绋庢�讳环璁$畻
-      productForm.value.taxExclusiveTotalPrice =
-        proxy.calculateTaxExclusiveTotalPrice(
-          productForm.value.taxInclusiveTotalPrice,
-          productForm.value.taxRate
-        );
-    }
-  };
-  const reverseMathNum = field => {
-    if (!productForm.value.taxRate) {
-      proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
-      return;
-    }
-    const taxRate = Number(productForm.value.taxRate);
-    if (!taxRate) return;
-
-    // 纭繚杈撳叆鍊间笉涓鸿礋鏁�
-    if (
-      field === "taxInclusiveTotalPrice" ||
-      field === "taxExclusiveTotalPrice"
-    ) {
-      const value = Number(productForm.value[field]);
-      if (value < 0) {
-        productForm.value[field] = "0";
-        proxy.$modal.msgWarning("鍊间笉鑳藉皬浜�0");
-        return;
-      }
-    }
-
-    if (field === "taxInclusiveTotalPrice") {
-      // 宸茬煡鍚◣鎬讳环鍜屾暟閲忥紝鍙嶇畻鍚◣鍗曚环
-      if (productForm.value.quantity) {
-        productForm.value.taxInclusiveUnitPrice = (
-          Number(productForm.value.taxInclusiveTotalPrice) /
-          Number(productForm.value.quantity)
-        ).toFixed(2);
-        // 纭繚缁撴灉涓嶄负璐熸暟
-        if (Number(productForm.value.taxInclusiveUnitPrice) < 0) {
-          productForm.value.taxInclusiveUnitPrice = "0";
-        }
-      }
-      // 宸茬煡鍚◣鎬讳环鍜屽惈绋庡崟浠凤紝鍙嶇畻鏁伴噺
-      else if (productForm.value.taxInclusiveUnitPrice) {
-        productForm.value.quantity = (
-          Number(productForm.value.taxInclusiveTotalPrice) /
-          Number(productForm.value.taxInclusiveUnitPrice)
-        ).toFixed(2);
-        // 纭繚缁撴灉涓嶄负璐熸暟
-        if (Number(productForm.value.quantity) < 0) {
-          productForm.value.quantity = "0";
-        }
-      }
-      // 鍙嶇畻涓嶅惈绋庢�讳环
-      productForm.value.taxExclusiveTotalPrice = (
-        Number(productForm.value.taxInclusiveTotalPrice) /
-        (1 + taxRate / 100)
-      ).toFixed(2);
-      // 纭繚缁撴灉涓嶄负璐熸暟
-      if (Number(productForm.value.taxExclusiveTotalPrice) < 0) {
-        productForm.value.taxExclusiveTotalPrice = "0";
-      }
-    } else if (field === "taxExclusiveTotalPrice") {
-      // 鍙嶇畻鍚◣鎬讳环
-      productForm.value.taxInclusiveTotalPrice = (
-        Number(productForm.value.taxExclusiveTotalPrice) *
-        (1 + taxRate / 100)
-      ).toFixed(2);
-      // 纭繚缁撴灉涓嶄负璐熸暟
-      if (Number(productForm.value.taxInclusiveTotalPrice) < 0) {
-        productForm.value.taxInclusiveTotalPrice = "0";
-      }
-      // 宸茬煡鏁伴噺锛屽弽绠楀惈绋庡崟浠�
-      if (productForm.value.quantity) {
-        productForm.value.taxInclusiveUnitPrice = (
-          Number(productForm.value.taxInclusiveTotalPrice) /
-          Number(productForm.value.quantity)
-        ).toFixed(2);
-        // 纭繚缁撴灉涓嶄负璐熸暟
-        if (Number(productForm.value.taxInclusiveUnitPrice) < 0) {
-          productForm.value.taxInclusiveUnitPrice = "0";
-        }
-      }
-      // 宸茬煡鍚◣鍗曚环锛屽弽绠楁暟閲�
-      else if (productForm.value.taxInclusiveUnitPrice) {
-        productForm.value.quantity = (
-          Number(productForm.value.taxInclusiveTotalPrice) /
-          Number(productForm.value.taxInclusiveUnitPrice)
-        ).toFixed(2);
-        // 纭繚缁撴灉涓嶄负璐熸暟
-        if (Number(productForm.value.quantity) < 0) {
-          productForm.value.quantity = "0";
-        }
-      }
-    }
-  };
-  // 閿�鍞悎鍚岄�夋嫨鏀瑰彉鏂规硶
-  const salesLedgerChange = async row => {
-    console.log("row", row);
-    var index = salesContractList.value.findIndex(item => item.id == row);
-    console.log("index", index);
-    if (index > -1) {
-      await querygProductInfoByContractNo();
-    }
-  };
-
-  const querygProductInfoByContractNo = async () => {
-    const { code, data } = await getProductInfoByContractNo({
-      contractNo: form.value.salesLedgerId,
-    });
-    if (code == 200) {
-      productData.value = data;
-    }
-  };
-
-  // 鑾峰彇妯℃澘淇℃伅
-  const getTemplateList = async () => {
-    let res = await getPurchaseTemplateList();
-    if (res && res.code === 200 && Array.isArray(res.data)) {
-      templateList.value = res.data;
-    }
-  };
-
-  // 鎵撳紑闄勪欢寮规
-  const openFileDialog = async row => {
-    recordId.value = row.id;
-    fileListDialogVisible.value = true;
-  };
-
-  // 鍒犻櫎妯℃澘
-  const handleDeleteTemplate = async item => {
-    if (!item.id) {
-      proxy.$modal.msgWarning("鏃犳硶鍒犻櫎璇ユā鏉�");
-      return;
-    }
-
-    try {
-      await ElMessageBox.confirm(
-        `纭畾瑕佸垹闄ゆā鏉�"${item.templateName}"鍚楋紵`,
-        "鍒犻櫎纭",
-        {
-          confirmButtonText: "纭畾",
-          cancelButtonText: "鍙栨秷",
-          type: "warning",
-        }
-      );
-
-      const res = await delPurchaseTemplate([item.id]);
-      if (res && res.code === 200) {
-        ElMessage({
-          message: "鍒犻櫎鎴愬姛",
-          type: "success",
-        });
-        // 濡傛灉鍒犻櫎鐨勬槸褰撳墠閫変腑鐨勬ā鏉匡紝娓呯┖閫夋嫨
-        if (templateName.value === item.templateName) {
-          templateName.value = "";
-          filterInputValue.value = "";
-        }
-        // 閲嶆柊鑾峰彇妯℃澘鍒楄〃
-        await getTemplateList();
-      } else {
-        ElMessage({
-          message: res?.msg || "鍒犻櫎澶辫触",
-          type: "error",
-        });
-      }
-    } catch (error) {
-      if (error !== "cancel") {
-        console.error("鍒犻櫎妯℃澘澶辫触:", error);
-        ElMessage({
-          message: "鍒犻櫎澶辫触锛岃绋嶅悗閲嶈瘯",
-          type: "error",
-        });
-      }
-    }
-  };
-
-  onMounted(() => {
-    getList();
-    getTemplateList();
-  });
+onMounted(() => {
+  getList();
+  getTemplateList();
+});
 </script>
 
 <style scoped lang="scss">
-  .invalid-row {
-    opacity: 0.6;
-    background-color: #f5f7fa;
-  }
+.invalid-row {
+  opacity: 0.6;
+  background-color: #f5f7fa;
+}
 
-  .el-row {
-    justify-content: space-between;
-    align-items: center;
-  }
+.el-row {
+  justify-content: space-between;
+  align-items: center;
+}
 
-  .no-arrow-select {
-    --el-select-suffix-icon-color: transparent; /* 闅愯棌榛樿涓嬫媺绠ご */
-  }
+.no-arrow-select {
+  --el-select-suffix-icon-color: transparent;
+  /* 闅愯棌榛樿涓嬫媺绠ご */
+}
 
-  .select-button-group {
-    display: flex;
-    align-items: center;
-  }
+.readonly-text {
+  display: inline-block;
+  width: 100%;
+  padding: 0 15px;
+  height: 32px;
+  line-height: 32px;
+  background-color: var(--el-fill-color-light);
+  border-radius: var(--el-border-radius-base);
+  color: var(--el-text-color-regular);
+  font-size: var(--el-font-size-base);
+  box-sizing: border-box;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
 
-  // 瀹℃壒浜鸿妭鐐瑰鍣ㄦ牱寮�
-  .approver-nodes-container {
-    display: flex;
-    flex-wrap: wrap;
-    gap: 16px;
-    padding: 16px;
-    background-color: #f8f9fa;
-    border-radius: 4px;
-    border: 1px solid #e4e7ed;
-  }
+.readonly-text-area {
+  width: 100%;
+  min-height: 52px;
+  padding: 5px 15px;
+  background-color: var(--el-fill-color-light);
+  border-radius: var(--el-border-radius-base);
+  color: var(--el-text-color-regular);
+  font-size: var(--el-font-size-base);
+  box-sizing: border-box;
+  white-space: pre-wrap;
+  word-break: break-all;
+}
 
+.detail-file-list {
+  width: 100%;
+  padding: 10px 15px;
+  background-color: var(--el-fill-color-light);
+  border-radius: var(--el-border-radius-base);
+}
+
+.detail-file-item {
+  line-height: 24px;
+  margin-bottom: 5px;
+}
+
+.detail-file-item:last-child {
+  margin-bottom: 0;
+}
+
+.select-button-group {
+  display: flex;
+  align-items: center;
+}
+
+// 瀹℃壒浜鸿妭鐐瑰鍣ㄦ牱寮�
+.approver-nodes-container {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 16px;
+  padding: 16px;
+  background-color: #f8f9fa;
+  border-radius: 4px;
+  border: 1px solid #e4e7ed;
+}
+
+.approver-node-item {
+  flex: 0 0 calc(33.333% - 12px);
+  min-width: 200px;
+  padding: 12px;
+  background-color: #fff;
+  border-radius: 4px;
+  border: 1px solid #dcdfe6;
+  transition: all 0.3s;
+
+  &:hover {
+    border-color: #409eff;
+    box-shadow: 0 2px 8px rgba(64, 158, 255, 0.1);
+  }
+}
+
+.approver-node-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 8px;
+}
+
+.approver-node-label {
+  font-size: 13px;
+  font-weight: 500;
+  color: #606266;
+}
+
+@media (max-width: 1200px) {
   .approver-node-item {
-    flex: 0 0 calc(33.333% - 12px);
-    min-width: 200px;
-    padding: 12px;
-    background-color: #fff;
-    border-radius: 4px;
-    border: 1px solid #dcdfe6;
-    transition: all 0.3s;
-
-    &:hover {
-      border-color: #409eff;
-      box-shadow: 0 2px 8px rgba(64, 158, 255, 0.1);
-    }
+    flex: 0 0 calc(50% - 8px);
   }
+}
 
-  .approver-node-header {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    margin-bottom: 8px;
+@media (max-width: 768px) {
+  .approver-node-item {
+    flex: 0 0 100%;
   }
+}
 
-  .approver-node-label {
-    font-size: 13px;
-    font-weight: 500;
-    color: #606266;
+// 鍒犻櫎鍥炬爣鏍峰紡
+.delete-icon {
+  transition: all 0.3s;
+
+  &:hover {
+    color: #f56c6c !important;
+    transform: scale(1.2);
   }
-
-  @media (max-width: 1200px) {
-    .approver-node-item {
-      flex: 0 0 calc(50% - 8px);
-    }
-  }
-
-  @media (max-width: 768px) {
-    .approver-node-item {
-      flex: 0 0 100%;
-    }
-  }
-
-  // 鍒犻櫎鍥炬爣鏍峰紡
-  .delete-icon {
-    transition: all 0.3s;
-
-    &:hover {
-      color: #f56c6c !important;
-      transform: scale(1.2);
-    }
-  }
+}
 </style>

--
Gitblit v1.9.3