From 4039f4dce566ffddf444bed260906acdff0b164f Mon Sep 17 00:00:00 2001
From: yyb <995253665@qq.com>
Date: 星期六, 16 五月 2026 15:58:08 +0800
Subject: [PATCH] Merge branch 'dev_NEW_pro' into dev_NEW_pro_鹤壁

---
 src/pages/equipmentManagement/upkeep/index.vue                   |    2 
 src/pages/sales/salesAccount/goOut.vue                           |  976 +++------
 src/api/procurementManagement/procurementLedger.js               |   10 
 src/pages/productionManagement/processRoute/items.vue            |   10 
 src/pages/qualityManagement/finalInspection/add.vue              |   15 
 src/pages/qualityManagement/materialInspection/add.vue           |   30 
 src/api/inventoryManagement/stockInventory.js                    |  101 
 src/pages/procurementManagement/procurementLedger/detail.vue     |   52 
 src/api/collaborativeApproval/approvalProcess.js                 |   89 
 src/pages/productionManagement/productionTraceability/index.vue  |  159 +
 src/pages/qualityManagement/processInspection/index.vue          |   19 
 src/pages/productionManagement/productionAccounting/index.vue    |   22 
 src/pages/equipmentManagement/repair/add.vue                     |   47 
 src/pages/qualityManagement/materialInspection/detail.vue        |    3 
 src/pages/sales/salesQuotation/detail.vue                        |   54 
 src/components/CommonUpload.vue                                  |  164 +
 src/pages/qualityManagement/processInspection/add.vue            |   29 
 src/pages/qualityManagement/finalInspection/detail.vue           |    3 
 src/pages/cooperativeOffice/collaborativeApproval/approve.vue    |  812 ++++----
 src/pages/cooperativeOffice/collaborativeApproval/index.vue      |   24 
 src/pages/qualityManagement/finalInspection/index.vue            |   19 
 src/pages/equipmentManagement/upkeep/add.vue                     |  778 ++++---
 src/pages/cooperativeOffice/collaborativeApproval/detail.vue     | 1113 ++++------
 src/pages/inventoryManagement/stockManagement/index.vue          |  133 
 src/pages/sales/salesQuotation/index.vue                         |  118 
 /dev/null                                                        |  134 -
 src/pages/qualityManagement/processInspection/detail.vue         |    5 
 src/pages/productionManagement/productionReport/index.vue        |   56 
 src/pages/equipmentManagement/repair/index.vue                   |    6 
 src/pages/productionManagement/productionOrder/pickingDetail.vue |    2 
 src/pages/productionManagement/productionReporting/ledger.vue    |   26 
 src/pages/qualityManagement/materialInspection/index.vue         |   19 
 src/pages/sales/salesQuotation/edit.vue                          |  547 +++--
 src/pages/inventoryManagement/stockManagement/Record.vue         |  292 ++
 34 files changed, 3,077 insertions(+), 2,792 deletions(-)

diff --git a/src/api/collaborativeApproval/approvalProcess.js b/src/api/collaborativeApproval/approvalProcess.js
index 47cf3ec..0d2b129 100644
--- a/src/api/collaborativeApproval/approvalProcess.js
+++ b/src/api/collaborativeApproval/approvalProcess.js
@@ -2,63 +2,72 @@
 import request from "@/utils/request";
 
 export function approveProcessListPage(query) {
-    return request({
-        url: '/approveProcess/list',
-        method: 'get',
-        params: query,
-    })
+  return request({
+    url: "/approveProcess/list",
+    method: "get",
+    params: query,
+  });
 }
 export function getDept(query) {
-    return request({
-        url: '/approveProcess/getDept',
-        method: 'get',
-        params: query,
-    })
+  return request({
+    url: "/approveProcess/getDept",
+    method: "get",
+    params: query,
+  });
 }
 export function approveProcessGetInfo(query) {
-    return request({
-        url: '/approveProcess/get',
-        method: 'get',
-        params: query,
-    })
+  return request({
+    url: "/approveProcess/get",
+    method: "get",
+    params: query,
+  });
 }
 // 鏂板瀹℃壒娴佺▼
 export function approveProcessAdd(query) {
-    return request({
-        url: '/approveProcess/add',
-        method: 'post',
-        data: query,
-    })
+  return request({
+    url: "/approveProcess/add",
+    method: "post",
+    data: query,
+  });
 }
 
 // 淇敼瀹℃壒娴佺▼
 export function approveProcessUpdate(query) {
-    return request({
-        url: '/approveProcess/update',
-        method: 'post',
-        data: query,
-    })
+  return request({
+    url: "/approveProcess/update",
+    method: "post",
+    data: query,
+  });
 }
 // 鎻愪氦瀹℃壒
 export function updateApproveNode(query) {
-    return request({
-        url: '/approveNode/updateApproveNode',
-        method: 'post',
-        data: query,
-    })
+  return request({
+    url: "/approveNode/updateApproveNode",
+    method: "post",
+    data: query,
+  });
 }
 // 鍒犻櫎瀹℃壒娴佺▼
 export function approveProcessDelete(query) {
-    return request({
-        url: '/approveProcess/deleteIds',
-        method: 'delete',
-        data: query,
-    })
+  return request({
+    url: "/approveProcess/deleteIds",
+    method: "delete",
+    data: query,
+  });
 }
 // 鏌ヨ瀹℃壒娴佺▼
 export function approveProcessDetails(query) {
-    return request({
-        url: '/approveNode/details/' + query,
-        method: 'get',
-    })
-}
\ No newline at end of file
+  return request({
+    url: "/approveNode/details/" + query,
+    method: "get",
+  });
+}
+
+// 瀹℃壒璇︽儏
+export function getDeliveryDetailByShippingNo(query) {
+  return request({
+    url: "/shippingInfo/getDateilByShippingNo",
+    method: "get",
+    params: query,
+  });
+}
diff --git a/src/api/inventoryManagement/stockInventory.js b/src/api/inventoryManagement/stockInventory.js
index dfa5f46..328657c 100644
--- a/src/api/inventoryManagement/stockInventory.js
+++ b/src/api/inventoryManagement/stockInventory.js
@@ -1,61 +1,78 @@
 import request from "@/utils/request";
 // 鍒嗛〉鏌ヨ搴撳瓨璁板綍鍒楄〃
-export const getStockInventoryListPage = (params) => {
-    return request({
-        url: "/stockInventory/pagestockInventory",
-        method: "get",
-        params,
-    });
+export const getStockInventoryListPage = params => {
+  return request({
+    url: "/stockInventory/pagestockInventory",
+    method: "get",
+    params,
+  });
+};
+
+// 鍒嗛〉鏌ヨ鑱斿悎搴撳瓨璁板綍鍒楄〃锛堝寘鍚晢鍝佷俊鎭級
+export const getStockInventoryListPageCombined = params => {
+  return request({
+    url: "/stockInventory/pageListCombinedStockInventory",
+    method: "get",
+    params,
+  });
 };
 
 // 鍒涘缓搴撳瓨璁板綍
-export const createStockInventory = (params) => {
-    return request({
-        url: "/stockInventory/addstockInventory",
-        method: "post",
-        data: params,
-    });
+export const createStockInventory = params => {
+  return request({
+    url: "/stockInventory/addstockInventory",
+    method: "post",
+    data: params,
+  });
 };
 
 // 鍑忓皯搴撳瓨璁板綍
-export const subtractStockInventory = (params) => {
-    return request({
-        url: "/stockInventory/subtractStockInventory",
-        method: "post",
-        data: params,
-    });
+export const subtractStockInventory = params => {
+  return request({
+    url: "/stockInventory/subtractStockInventory",
+    method: "post",
+    data: params,
+  });
 };
 
-export const getStockInventoryReportList = (params) => {
-    return request({
-        url: "/stockInventory/stockInventoryPage",
-        method: "get",
-        params,
-    });
+export const getStockInventoryReportList = params => {
+  return request({
+    url: "/stockInventory/stockInventoryPage",
+    method: "get",
+    params,
+  });
 };
 
-export const getStockInventoryInAndOutReportList = (params) => {
-    return request({
-        url: "/stockInventory/stockInAndOutRecord",
-        method: "get",
-        params,
-    });
+export const getStockInventoryInAndOutReportList = params => {
+  return request({
+    url: "/stockInventory/stockInAndOutRecord",
+    method: "get",
+    params,
+  });
 };
 
 // 鍐荤粨搴撳瓨璁板綍
-export const frozenStockInventory = (params) => {
-    return request({
-        url: "/stockInventory/frozenStock",
-        method: "post",
-        data: params,
-    });
+export const frozenStockInventory = params => {
+  return request({
+    url: "/stockInventory/frozenStock",
+    method: "post",
+    data: params,
+  });
 };
 
 // 瑙e喕搴撳瓨璁板綍
-export const thawStockInventory = (params) => {
-    return request({
-        url: "/stockInventory/thawStock",
-        method: "post",
-        data: params,
-    });
+export const thawStockInventory = params => {
+  return request({
+    url: "/stockInventory/thawStock",
+    method: "post",
+    data: params,
+  });
+};
+
+export const getStockInventoryByModelId = productModelId => {
+  return request({
+    url: "/stockInventory/getByModelId",
+    method: "get",
+    params: { productModelId },
+  });
 };
diff --git a/src/api/procurementManagement/procurementLedger.js b/src/api/procurementManagement/procurementLedger.js
index 0a05d2e..5c0bb83 100644
--- a/src/api/procurementManagement/procurementLedger.js
+++ b/src/api/procurementManagement/procurementLedger.js
@@ -72,6 +72,16 @@
     method: "get",
   });
 }
+
+// 鏌ヨ閲囪喘璇︽儏
+export function getPurchaseByCode(query) {
+  return request({
+    url: "/purchase/ledger/getPurchaseByCode",
+    method: "get",
+    params: query,
+  });
+}
+
 export function approveProcessGetInfo(query) {
     return request({
         url: '/approveProcess/get',
diff --git a/src/components/CommonUpload.vue b/src/components/CommonUpload.vue
new file mode 100644
index 0000000..8910206
--- /dev/null
+++ b/src/components/CommonUpload.vue
@@ -0,0 +1,164 @@
+<template>
+  <view class="common-upload">
+    <u-upload
+      :fileList="internalFileList"
+      @afterRead="afterRead"
+      @delete="deleteFile"
+      :name="name"
+      :multiple="multiple"
+      :maxCount="maxCount"
+      :accept="accept"
+      :disabled="disabled"
+    ></u-upload>
+  </view>
+</template>
+
+<script setup>
+import { ref, watch, onMounted } from 'vue';
+import { getToken } from "@/utils/auth";
+import config from "@/config";
+
+const props = defineProps({
+  // 鐖剁粍浠朵紶鍏ョ殑鏂囦欢鍒楄〃锛堝搴斿悗绔瓨鍌ㄧ殑瀵硅薄鍒楄〃锛�
+  modelValue: {
+    type: Array,
+    default: () => []
+  },
+  // 鏈�澶т笂浼犳暟閲�
+  maxCount: {
+    type: Number,
+    default: 9
+  },
+  // 鏄惁鏀寔澶氶��
+  multiple: {
+    type: Boolean,
+    default: true
+  },
+  // 鎺ュ彈鐨勬枃浠剁被鍨�
+  accept: {
+    type: String,
+    default: 'image'
+  },
+  // 涓婁紶鎺ュ彛瀵瑰簲鐨勫弬鏁板悕
+  name: {
+    type: String,
+    default: 'file'
+  },
+  // 鏄惁绂佺敤
+  disabled: {
+    type: Boolean,
+    default: false
+  }
+});
+
+const emit = defineEmits(['update:modelValue']);
+
+// 鐢ㄤ簬 u-upload 鏄剧ず鐨勫唴閮ㄥ垪琛�
+const internalFileList = ref([]);
+
+// 鐩戝惉澶栭儴 modelValue 鍙樺寲锛屽悓姝ュ埌鍐呴儴鏄剧ず鍒楄〃
+watch(() => props.modelValue, (newVal) => {
+  if (newVal) {
+    internalFileList.value = newVal.map(item => ({
+      ...item,
+      url: item.url || item.previewURL,
+      status: 'success',
+      message: ''
+    }));
+  }
+}, { immediate: true, deep: true });
+
+const showToast = (message) => {
+  uni.showToast({
+    title: message,
+    icon: "none",
+  });
+};
+
+// 涓婁紶閫昏緫
+const uploadFilePromise = (url) => {
+  return new Promise((resolve, reject) => {
+    uni.uploadFile({
+      url: config.baseUrl + "/common/upload",
+      filePath: url,
+      name: "files", // 娉ㄦ剰锛氳繖閲屾牴鎹師浠g爜鏄� "files"
+      header: {
+        Authorization: "Bearer " + getToken(),
+      },
+      success: (res) => {
+        try {
+          const data = JSON.parse(res.data);
+          if (data.code === 200) {
+            // 濡傛灉杩斿洖鐨勬槸鏁扮粍锛屽彇绗竴涓厓绱�
+            const resultData = Array.isArray(data.data) ? data.data[0] : data.data;
+
+            // 澶勭悊 url 璧嬪��
+            if (!resultData.url && resultData.previewURL) {
+              resultData.url = resultData.previewURL;
+            }
+            // 鍏煎鍘熶唬鐮佷腑鐨� name 璧嬪��
+            if (!resultData.name && resultData.originalFilename) {
+              resultData.name = resultData.originalFilename;
+            }
+
+            resolve(resultData);
+          } else {
+            reject(data.msg || "涓婁紶澶辫触");
+          }
+        } catch (e) {
+          reject("瑙f瀽鍝嶅簲澶辫触");
+        }
+      },
+      fail: (err) => {
+        reject(err);
+      },
+    });
+  });
+};
+
+// 涓婁紶鍚庣殑澶勭悊
+const afterRead = async (event) => {
+  let lists = [].concat(event.file);
+  let currentModelValue = [...props.modelValue];
+  
+  // 鍏堝湪鍐呴儴鍒楄〃涓坊鍔犲崰浣嶏紙涓婁紶涓姸鎬侊級
+  lists.forEach(item => {
+    internalFileList.value.push({
+      ...item,
+      status: 'uploading',
+      message: '涓婁紶涓�'
+    });
+  });
+
+  for (let i = 0; i < lists.length; i++) {
+    try {
+      const result = await uploadFilePromise(lists[i].url);
+      
+      // 鏇存柊 modelValue
+      currentModelValue.push(result);
+      emit('update:modelValue', currentModelValue);
+      
+    } catch (e) {
+      // 濡傛灉涓婁紶澶辫触锛屼粠鍐呴儴鍒楄〃涓Щ闄ゅ垰鎵嶆坊鍔犵殑椤�
+      const errorIndex = internalFileList.value.findIndex(item => item.status === 'uploading');
+      if (errorIndex > -1) {
+        internalFileList.value.splice(errorIndex, 1);
+      }
+      showToast(typeof e === "string" ? e : "涓婁紶澶辫触");
+    }
+  }
+};
+
+// 鍒犻櫎澶勭悊
+const deleteFile = (event) => {
+  const newList = [...props.modelValue];
+  newList.splice(event.index, 1);
+  emit('update:modelValue', newList);
+};
+</script>
+
+<style scoped lang="scss">
+.common-upload {
+  width: 100%;
+}
+</style>
diff --git a/src/pages/cooperativeOffice/collaborativeApproval/approve.vue b/src/pages/cooperativeOffice/collaborativeApproval/approve.vue
index aaad83e..b3c8687 100644
--- a/src/pages/cooperativeOffice/collaborativeApproval/approve.vue
+++ b/src/pages/cooperativeOffice/collaborativeApproval/approve.vue
@@ -1,8 +1,7 @@
 <template>
   <view class="approve-page">
-
-    <PageHeader title="瀹℃牳" @back="goBack" />
-
+    <PageHeader title="瀹℃牳"
+                @back="goBack" />
     <!-- 鐢宠淇℃伅 -->
     <view class="application-info">
       <view class="info-header">
@@ -25,7 +24,6 @@
           <text class="info-label">鐢宠鏃ユ湡</text>
           <text class="info-value">{{ approvalData.approveTime }}</text>
         </view>
-        
         <!-- approveType=2 璇峰亣鐩稿叧瀛楁 -->
         <template v-if="approvalData.approveType === 2">
           <view class="info-row">
@@ -37,462 +35,472 @@
             <text class="info-value">{{ approvalData.endDate || '-' }}</text>
           </view>
         </template>
-        
         <!-- approveType=3 鍑哄樊鐩稿叧瀛楁 -->
-        <view v-if="approvalData.approveType === 3" class="info-row">
+        <view v-if="approvalData.approveType === 3"
+              class="info-row">
           <text class="info-label">鍑哄樊鍦扮偣</text>
           <text class="info-value">{{ approvalData.location || '-' }}</text>
         </view>
-        
         <!-- approveType=4 鎶ラ攢鐩稿叧瀛楁 -->
-        <view v-if="approvalData.approveType === 4" class="info-row">
+        <view v-if="approvalData.approveType === 4"
+              class="info-row">
           <text class="info-label">鎶ラ攢閲戦</text>
           <text class="info-value">{{ approvalData.price ? `楼${approvalData.price}` : '-' }}</text>
         </view>
       </view>
     </view>
-
     <!-- 瀹℃壒娴佺▼ -->
     <view class="approval-process">
       <view class="process-header">
         <text class="process-title">瀹℃壒娴佺▼</text>
       </view>
-      
       <view class="process-steps">
-        <view 
-          v-for="(step, index) in approvalSteps" 
-          :key="index" 
-          class="process-step"
-          :class="{
+        <view v-for="(step, index) in approvalSteps"
+              :key="index"
+              class="process-step"
+              :class="{
             'completed': step.status === 'completed',
             'current': step.status === 'current',
             'pending': step.status === 'pending',
             'rejected': step.status === 'rejected'
-          }"
-        >
+          }">
           <view class="step-indicator">
             <view class="step-dot">
-              <text v-if="step.status === 'completed'" class="step-icon">鉁�</text>
-              <text v-else-if="step.status === 'rejected'" class="step-icon">鉁�</text>
-              <text v-else class="step-number">{{ index + 1 }}</text>
+              <text v-if="step.status === 'completed'"
+                    class="step-icon">鉁�</text>
+              <text v-else-if="step.status === 'rejected'"
+                    class="step-icon">鉁�</text>
+              <text v-else
+                    class="step-number">{{ index + 1 }}</text>
             </view>
-            <view v-if="index < approvalSteps.length - 1" class="step-line"></view>
+            <view v-if="index < approvalSteps.length - 1"
+                  class="step-line"></view>
           </view>
-          
           <view class="step-content">
             <view class="step-info">
               <text class="step-title">{{ step.title }}</text>
               <text class="step-approver">{{ step.approverName }}</text>
-              <text v-if="step.approveTime" class="step-time">{{ step.approveTime }}</text>
+              <text v-if="step.approveTime"
+                    class="step-time">{{ step.approveTime }}</text>
             </view>
-            
-            <view v-if="step.opinion" class="step-opinion">
+            <view v-if="step.opinion"
+                  class="step-opinion">
               <text class="opinion-label">瀹℃壒鎰忚锛�</text>
               <text class="opinion-content">{{ step.opinion }}</text>
             </view>
             <!-- 绛惧悕灞曠ず -->
-            <view v-if="step.urlTem" class="step-opinion" style="margin-top:8px;">
+            <view v-if="step.urlTem"
+                  class="step-opinion"
+                  style="margin-top:8px;">
               <text class="opinion-label">绛惧悕锛�</text>
-              <image :src="step.urlTem" mode="widthFix" style="width:180px;border-radius:6px;border:1px solid #eee;" />
+              <image :src="step.urlTem"
+                     mode="widthFix"
+                     style="width:180px;border-radius:6px;border:1px solid #eee;" />
             </view>
           </view>
         </view>
       </view>
     </view>
-
     <!-- 瀹℃牳鎰忚杈撳叆 -->
-    <view v-if="canApprove" class="approval-input">
+    <view v-if="canApprove"
+          class="approval-input">
       <view class="input-header">
         <text class="input-title">瀹℃牳鎰忚</text>
       </view>
-      
       <view class="input-content">
-        <u-textarea
-          v-model="approvalOpinion"
-          rows="4"
-          placeholder="璇疯緭鍏ュ鏍告剰瑙�"
-          maxlength="200"
-          count
-        />
+        <u-textarea v-model="approvalOpinion"
+                    rows="4"
+                    placeholder="璇疯緭鍏ュ鏍告剰瑙�"
+                    maxlength="200"
+                    count />
       </view>
     </view>
-
     <!-- 搴曢儴鎿嶄綔鎸夐挳 -->
-    <view v-if="canApprove" class="footer-actions">
-      <u-button class="reject-btn" @click="handleReject">椹冲洖</u-button>
-      <u-button class="approve-btn" @click="handleApprove">閫氳繃</u-button>
+    <view v-if="canApprove"
+          class="footer-actions">
+      <u-button class="reject-btn"
+                @click="handleReject">椹冲洖</u-button>
+      <u-button class="approve-btn"
+                @click="handleApprove">閫氳繃</u-button>
     </view>
   </view>
 </template>
 
 <script setup>
-import { ref, onMounted, computed } from 'vue'
-import { approveProcessGetInfo, approveProcessDetails, updateApproveNode } from '@/api/collaborativeApproval/approvalProcess'
-import useUserStore from '@/store/modules/user'
-const showToast = (message) => {
-	uni.showToast({
-		title: message,
-		icon: 'none'
-	})
-}
-import PageHeader from "@/components/PageHeader.vue";
+  import { ref, onMounted, computed } from "vue";
+  import {
+    approveProcessGetInfo,
+    approveProcessDetails,
+    updateApproveNode,
+  } from "@/api/collaborativeApproval/approvalProcess";
+  import useUserStore from "@/store/modules/user";
+  const showToast = message => {
+    uni.showToast({
+      title: message,
+      icon: "none",
+    });
+  };
+  import PageHeader from "@/components/PageHeader.vue";
 
-const userStore = useUserStore()
-const approvalData = ref({})
-const approvalSteps = ref([])
-const approvalOpinion = ref('')
-const approveId = ref('')
+  const userStore = useUserStore();
+  const approvalData = ref({});
+  const approvalSteps = ref([]);
+  const approvalOpinion = ref("");
+  const approveId = ref("");
 
-// 浠庤鎯呮帴鍙e瓧娈靛榻� canApprove锛氫粎褰撴湁 isShen 鐨勮妭鐐规椂鍙鎵�
-const canApprove = computed(() => {
-  return approvalSteps.value.some(step => step.isShen === true)
-})
+  // 浠庤鎯呮帴鍙e瓧娈靛榻� canApprove锛氫粎褰撴湁 isShen 鐨勮妭鐐规椂鍙鎵�
+  const canApprove = computed(() => {
+    return approvalSteps.value.some(step => step.isShen === true);
+  });
 
-onMounted(() => {
-  approveId.value = uni.getStorageSync('approveId')
-  if (approveId.value) {
-    loadApprovalData()
-  }
-})
-
-const loadApprovalData = () => {
-  // 鍩烘湰鐢宠淇℃伅
-  approveProcessGetInfo({ id: approveId.value }).then(res => {
-    approvalData.value = res.data || {}
-  })
-  // 瀹℃壒鑺傜偣璇︽儏
-  approveProcessDetails(approveId.value).then(res => {
-    const list = Array.isArray(res.data) ? res.data : []
-    // 淇濆瓨鍘熷鑺傜偣鏁版嵁渚涙彁浜や娇鐢�
-    activities.value = list
-
-    approvalSteps.value = list.map((it, idx) => {
-      // 鑺傜偣鐘舵�佹槧灏勶細1=閫氳繃锛�2=涓嶉�氳繃锛屽惁鍒欑湅鏄惁褰撳墠(isShen)锛屽啀榛樿涓哄緟澶勭悊
-      let status = 'pending'
-      if (it.approveNodeStatus === 1) status = 'completed'
-      else if (it.approveNodeStatus === 2) status = 'rejected'
-      else if (it.isShen) status = 'current'
-      return {
-        title: `绗�${idx + 1}姝ュ鎵筦,
-        approverName: it.approveNodeUser || '鏈煡鐢ㄦ埛',
-        status,
-        approveTime: it.approveTime || null,
-        opinion: it.approveNodeReason || '',
-        urlTem: it.urlTem || '',
-        isShen: !!it.isShen
-      }
-    })
-  })
-}
-
-const goBack = () => {
-  uni.removeStorageSync('approveId');
-  uni.navigateBack()
-}
-
-const submitForm = (status) => {
-  // 鍙�夛細鏍¢獙瀹℃牳鎰忚
-  if (!approvalOpinion.value?.trim()) {
-    showToast('璇疯緭鍏ュ鏍告剰瑙�')
-    return
-  }
-  // 鎵惧埌褰撳墠鍙鎵硅妭鐐�
-  const filteredActivities = activities.value.filter(activity => activity.isShen)
-  if (!filteredActivities.length) {
-    showToast('褰撳墠鏃犲彲瀹℃壒鑺傜偣')
-    return
-  }
-  // 鍐欏叆鐘舵�佸拰鎰忚
-  filteredActivities[0].approveNodeStatus = status
-  filteredActivities[0].approveNodeReason = approvalOpinion.value || ''
-  // 璁$畻鏄惁涓烘渶鍚庝竴姝�
-  const isLast = activities.value.findIndex(a => a.isShen) === activities.value.length - 1
-  // 璋冪敤鍚庣
-  updateApproveNode({ ...filteredActivities[0], isLast }).then(() => {
-    const msg = status === 1 ? '瀹℃壒閫氳繃' : '瀹℃壒宸查┏鍥�'
-    showToast(msg)
-    // 鎻愮ず鍚庤繑鍥炰笂涓�涓〉闈�
-    setTimeout(() => {
-      goBack() // 鍐呴儴鏄� uni.navigateBack()
-    }, 800)
-  })
-}
-
-const handleApprove = () => {
-  uni.showModal({
-    title: '纭鎿嶄綔',
-    content: '纭畾瑕侀�氳繃姝ゅ鎵瑰悧锛�',
-    success: (res) => {
-      if (res.confirm) submitForm(1)
+  onMounted(() => {
+    approveId.value = uni.getStorageSync("approveId");
+    if (approveId.value) {
+      loadApprovalData();
     }
-  })
-}
+  });
 
-const handleReject = () => {
-  uni.showModal({
-    title: '纭鎿嶄綔',
-    content: '纭畾瑕侀┏鍥炴瀹℃壒鍚楋紵',
-    success: (res) => {
-      if (res.confirm) submitForm(2)
+  const loadApprovalData = () => {
+    // 鍩烘湰鐢宠淇℃伅
+    approveProcessGetInfo({ id: approveId.value }).then(res => {
+      approvalData.value = res.data || {};
+    });
+    // 瀹℃壒鑺傜偣璇︽儏
+    approveProcessDetails(approveId.value).then(res => {
+      const list = Array.isArray(res.data) ? res.data : [];
+      // 淇濆瓨鍘熷鑺傜偣鏁版嵁渚涙彁浜や娇鐢�
+      activities.value = list;
+
+      approvalSteps.value = list.map((it, idx) => {
+        // 鑺傜偣鐘舵�佹槧灏勶細1=閫氳繃锛�2=涓嶉�氳繃锛屽惁鍒欑湅鏄惁褰撳墠(isShen)锛屽啀榛樿涓哄緟澶勭悊
+        let status = "pending";
+        if (it.approveNodeStatus === 1) status = "completed";
+        else if (it.approveNodeStatus === 2) status = "rejected";
+        else if (it.isShen) status = "current";
+        return {
+          title: `绗�${idx + 1}姝ュ鎵筦,
+          approverName: it.approveNodeUser || "鏈煡鐢ㄦ埛",
+          status,
+          approveTime: it.approveTime || null,
+          opinion: it.approveNodeReason || "",
+          urlTem: it.urlTem || "",
+          isShen: !!it.isShen,
+        };
+      });
+    });
+  };
+
+  const goBack = () => {
+    uni.removeStorageSync("approveId");
+    uni.navigateBack();
+  };
+
+  const submitForm = status => {
+    // 鍙�夛細鏍¢獙瀹℃牳鎰忚
+    if (!approvalOpinion.value?.trim()) {
+      showToast("璇疯緭鍏ュ鏍告剰瑙�");
+      return;
     }
-  })
-}
-// 鍘熷鑺傜偣鏁版嵁锛堢敤浜庢彁浜ら�昏緫锛�
-const activities = ref([])
+    // 鎵惧埌褰撳墠鍙鎵硅妭鐐�
+    const filteredActivities = activities.value.filter(
+      activity => activity.isShen
+    );
+    if (!filteredActivities.length) {
+      showToast("褰撳墠鏃犲彲瀹℃壒鑺傜偣");
+      return;
+    }
+    // 鍐欏叆鐘舵�佸拰鎰忚
+    filteredActivities[0].approveNodeStatus = status;
+    filteredActivities[0].approveNodeReason = approvalOpinion.value || "";
+    // 璁$畻鏄惁涓烘渶鍚庝竴姝�
+    const isLast =
+      activities.value.findIndex(a => a.isShen) === activities.value.length - 1;
+    // 璋冪敤鍚庣
+    updateApproveNode({ ...filteredActivities[0], isLast }).then(() => {
+      const msg = status === 1 ? "瀹℃壒閫氳繃" : "瀹℃壒宸查┏鍥�";
+      showToast(msg);
+      // 鎻愮ず鍚庤繑鍥炰笂涓�涓〉闈�
+      setTimeout(() => {
+        goBack(); // 鍐呴儴鏄� uni.navigateBack()
+      }, 800);
+    });
+  };
+
+  const handleApprove = () => {
+    uni.showModal({
+      title: "纭鎿嶄綔",
+      content: "纭畾瑕侀�氳繃姝ゅ鎵瑰悧锛�",
+      success: res => {
+        if (res.confirm) submitForm(1);
+      },
+    });
+  };
+
+  const handleReject = () => {
+    uni.showModal({
+      title: "纭鎿嶄綔",
+      content: "纭畾瑕侀┏鍥炴瀹℃壒鍚楋紵",
+      success: res => {
+        if (res.confirm) submitForm(2);
+      },
+    });
+  };
+  // 鍘熷鑺傜偣鏁版嵁锛堢敤浜庢彁浜ら�昏緫锛�
+  const activities = ref([]);
 </script>
 
 <style scoped lang="scss">
-.approve-page {
-  min-height: 100vh;
-  background: #f8f9fa;
-  padding-bottom: 80px;
-}
-
-.header {
-  display: flex;
-  align-items: center;
-  background: #fff;
-  padding: 16px 20px;
-  border-bottom: 1px solid #f0f0f0;
-  position: sticky;
-  top: 0;
-  z-index: 100;
-}
-
-.title {
-  flex: 1;
-  text-align: center;
-  font-size: 18px;
-  font-weight: 600;
-  color: #333;
-}
-
-.application-info {
-  background: #fff;
-  margin: 16px;
-  border-radius: 12px;
-  overflow: hidden;
-}
-
-.info-header {
-  padding: 16px;
-  border-bottom: 1px solid #f0f0f0;
-  background: #f8f9fa;
-}
-
-.info-title {
-  font-size: 16px;
-  font-weight: 600;
-  color: #333;
-}
-
-.info-content {
-  padding: 16px;
-}
-
-.info-row {
-  display: flex;
-  align-items: center;
-  margin-bottom: 12px;
-  
-  &:last-child {
-    margin-bottom: 0;
+  .approve-page {
+    min-height: 100vh;
+    background: #f8f9fa;
+    padding-bottom: 80px;
   }
-}
 
-.info-label {
-  font-size: 14px;
-  color: #666;
-  width: 80px;
-  flex-shrink: 0;
-}
+  .header {
+    display: flex;
+    align-items: center;
+    background: #fff;
+    padding: 16px 20px;
+    border-bottom: 1px solid #f0f0f0;
+    position: sticky;
+    top: 0;
+    z-index: 100;
+  }
 
-.info-value {
-  font-size: 14px;
-  color: #333;
-  flex: 1;
-}
+  .title {
+    flex: 1;
+    text-align: center;
+    font-size: 18px;
+    font-weight: 600;
+    color: #333;
+  }
 
-.approval-process {
-  background: #fff;
-  margin: 16px;
-  border-radius: 12px;
-  overflow: hidden;
-}
+  .application-info {
+    background: #fff;
+    margin: 16px;
+    border-radius: 12px;
+    overflow: hidden;
+  }
 
-.process-header {
-  padding: 16px;
-  border-bottom: 1px solid #f0f0f0;
-  background: #f8f9fa;
-}
+  .info-header {
+    padding: 16px;
+    border-bottom: 1px solid #f0f0f0;
+    background: #f8f9fa;
+  }
 
-.process-title {
-  font-size: 16px;
-  font-weight: 600;
-  color: #333;
-}
+  .info-title {
+    font-size: 16px;
+    font-weight: 600;
+    color: #333;
+  }
 
-.process-steps {
-  padding: 20px;
-}
+  .info-content {
+    padding: 16px;
+  }
 
-.process-step {
-  display: flex;
-  position: relative;
-  margin-bottom: 24px;
-  
-  &:last-child {
-    margin-bottom: 0;
-    
-    .step-line {
-      display: none;
+  .info-row {
+    display: flex;
+    align-items: center;
+    margin-bottom: 12px;
+
+    &:last-child {
+      margin-bottom: 0;
     }
   }
-}
 
-.step-indicator {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  margin-right: 16px;
-}
+  .info-label {
+    font-size: 14px;
+    color: #666;
+    width: 80px;
+    flex-shrink: 0;
+  }
 
-.step-dot {
-  width: 32px;
-  height: 32px;
-  border-radius: 50%;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  font-size: 14px;
-  font-weight: 600;
-  position: relative;
-  z-index: 2;
-}
+  .info-value {
+    font-size: 14px;
+    color: #333;
+    flex: 1;
+  }
 
-.process-step.completed .step-dot {
-  background: #52c41a;
-  color: #fff;
-}
+  .approval-process {
+    background: #fff;
+    margin: 16px;
+    border-radius: 12px;
+    overflow: hidden;
+  }
 
-.process-step.current .step-dot {
-  background: #1890ff;
-  color: #fff;
-  animation: pulse 2s infinite;
-}
+  .process-header {
+    padding: 16px;
+    border-bottom: 1px solid #f0f0f0;
+    background: #f8f9fa;
+  }
 
-.process-step.pending .step-dot {
-  background: #d9d9d9;
-  color: #999;
-}
+  .process-title {
+    font-size: 16px;
+    font-weight: 600;
+    color: #333;
+  }
 
-.step-line {
-  width: 2px;
-  height: 40px;
-  background: #d9d9d9;
-  margin-top: 8px;
-}
+  .process-steps {
+    padding: 20px;
+  }
 
-.process-step.completed .step-line {
-  background: #52c41a;
-}
+  .process-step {
+    display: flex;
+    position: relative;
+    margin-bottom: 24px;
 
-.process-step.rejected .step-dot {
-  background: #ff4d4f;
-  color: #fff;
-}
-.process-step.rejected .step-line {
-  background: #ff4d4f;
-}
+    &:last-child {
+      margin-bottom: 0;
 
-.step-content {
-  flex: 1;
-  padding-top: 4px;
-}
+      .step-line {
+        display: none;
+      }
+    }
+  }
 
-.step-info {
-  margin-bottom: 8px;
-}
+  .step-indicator {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    margin-right: 16px;
+  }
 
-.step-title {
-  font-size: 16px;
-  font-weight: 600;
-  color: #333;
-  display: block;
-  margin-bottom: 4px;
-}
+  .step-dot {
+    width: 32px;
+    height: 32px;
+    border-radius: 50%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-size: 14px;
+    font-weight: 600;
+    position: relative;
+    z-index: 2;
+  }
 
-.step-approver {
-  font-size: 14px;
-  color: #666;
-  display: block;
-  margin-bottom: 4px;
-}
+  .process-step.completed .step-dot {
+    background: #52c41a;
+    color: #fff;
+  }
 
-.step-time {
-  font-size: 12px;
-  color: #999;
-  display: block;
-}
+  .process-step.current .step-dot {
+    background: #1890ff;
+    color: #fff;
+    animation: pulse 2s infinite;
+  }
 
-.step-opinion {
-  background: #f8f9fa;
-  padding: 12px;
-  border-radius: 8px;
-  border-left: 4px solid #52c41a;
-}
+  .process-step.pending .step-dot {
+    background: #d9d9d9;
+    color: #999;
+  }
 
-.opinion-label {
-  font-size: 12px;
-  color: #666;
-  display: block;
-  margin-bottom: 4px;
-}
+  .step-line {
+    width: 2px;
+    height: 40px;
+    background: #d9d9d9;
+    margin-top: 8px;
+  }
 
-.opinion-content {
-  font-size: 14px;
-  color: #333;
-  line-height: 1.5;
-}
+  .process-step.completed .step-line {
+    background: #52c41a;
+  }
 
-.approval-input {
-  background: #fff;
-  margin: 16px;
-  border-radius: 12px;
-  overflow: hidden;
-}
+  .process-step.rejected .step-dot {
+    background: #ff4d4f;
+    color: #fff;
+  }
+  .process-step.rejected .step-line {
+    background: #ff4d4f;
+  }
 
-.input-header {
-  padding: 16px;
-  border-bottom: 1px solid #f0f0f0;
-  background: #f8f9fa;
-}
+  .step-content {
+    flex: 1;
+    padding-top: 4px;
+  }
 
-.input-title {
-  font-size: 16px;
-  font-weight: 600;
-  color: #333;
-}
+  .step-info {
+    margin-bottom: 8px;
+  }
 
-.input-content {
-  padding: 16px;
-}
+  .step-title {
+    font-size: 16px;
+    font-weight: 600;
+    color: #333;
+    display: block;
+    margin-bottom: 4px;
+  }
 
-.footer-actions {
-  position: fixed;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  background: #fff;
-  display: flex;
-  justify-content: space-around;
-  align-items: center;
-  padding: 16px;
-  box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.1);
-  z-index: 1000;
-}
+  .step-approver {
+    font-size: 14px;
+    color: #666;
+    display: block;
+    margin-bottom: 4px;
+  }
 
-.reject-btn {
+  .step-time {
+    font-size: 12px;
+    color: #999;
+    display: block;
+  }
+
+  .step-opinion {
+    background: #f8f9fa;
+    padding: 12px;
+    border-radius: 8px;
+    border-left: 4px solid #52c41a;
+  }
+
+  .opinion-label {
+    font-size: 12px;
+    color: #666;
+    display: block;
+    margin-bottom: 4px;
+  }
+
+  .opinion-content {
+    font-size: 14px;
+    color: #333;
+    line-height: 1.5;
+  }
+
+  .approval-input {
+    background: #fff;
+    margin: 16px;
+    border-radius: 12px;
+    overflow: hidden;
+  }
+
+  .input-header {
+    padding: 16px;
+    border-bottom: 1px solid #f0f0f0;
+    background: #f8f9fa;
+  }
+
+  .input-title {
+    font-size: 16px;
+    font-weight: 600;
+    color: #333;
+  }
+
+  .input-content {
+    padding: 16px;
+  }
+
+  .footer-actions {
+    position: fixed;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background: #fff;
+    display: flex;
+    justify-content: space-around;
+    align-items: center;
+    padding: 16px;
+    box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.1);
+    z-index: 1000;
+  }
+
+  .reject-btn {
     width: 120px;
     background: #ff4d4f;
     color: #fff;
@@ -503,47 +511,47 @@
     background: #52c41a;
     color: #fff;
   }
-  
+
   /* 閫傞厤u-button鏍峰紡 */
   :deep(.u-button) {
     border-radius: 6px;
   }
 
-@keyframes pulse {
-  0% {
-    box-shadow: 0 0 0 0 rgba(24, 144, 255, 0.7);
+  @keyframes pulse {
+    0% {
+      box-shadow: 0 0 0 0 rgba(24, 144, 255, 0.7);
+    }
+    70% {
+      box-shadow: 0 0 0 10px rgba(24, 144, 255, 0);
+    }
+    100% {
+      box-shadow: 0 0 0 0 rgba(24, 144, 255, 0);
+    }
   }
-  70% {
-    box-shadow: 0 0 0 10px rgba(24, 144, 255, 0);
+  .signature-section {
+    background: #fff;
+    padding: 12px 16px 16px;
+    border-top: 1px solid #f0f0f0;
   }
-  100% {
-    box-shadow: 0 0 0 0 rgba(24, 144, 255, 0);
+  .signature-header {
+    margin-bottom: 8px;
   }
-}
-.signature-section {
-  background: #fff;
-  padding: 12px 16px 16px;
-  border-top: 1px solid #f0f0f0;
-}
-.signature-header {
-  margin-bottom: 8px;
-}
-.signature-title {
-  font-size: 14px;
-  font-weight: 600;
-  color: #333;
-}
-.signature-box {
-  width: 100%;
-  height: 180px;
-  background: #fff;
-  border: 1px dashed #d9d9d9;
-  border-radius: 8px;
-  overflow: hidden;
-}
-.signature-actions {
-  margin-top: 8px;
-  display: flex;
-  justify-content: flex-end;
-}
+  .signature-title {
+    font-size: 14px;
+    font-weight: 600;
+    color: #333;
+  }
+  .signature-box {
+    width: 100%;
+    height: 180px;
+    background: #fff;
+    border: 1px dashed #d9d9d9;
+    border-radius: 8px;
+    overflow: hidden;
+  }
+  .signature-actions {
+    margin-top: 8px;
+    display: flex;
+    justify-content: flex-end;
+  }
 </style>
\ No newline at end of file
diff --git a/src/pages/cooperativeOffice/collaborativeApproval/detail.vue b/src/pages/cooperativeOffice/collaborativeApproval/detail.vue
index 04a4c18..16f9923 100644
--- a/src/pages/cooperativeOffice/collaborativeApproval/detail.vue
+++ b/src/pages/cooperativeOffice/collaborativeApproval/detail.vue
@@ -1,6 +1,6 @@
 <template>
   <view class="account-detail">
-    <PageHeader title="瀹℃壒娴佺▼"
+    <PageHeader :title="operationType === 'detail' ? '璇︽儏' : '瀹℃壒娴佺▼'"
                 @back="goBack" />
     <!-- 琛ㄥ崟鍖哄煙 -->
     <u-form ref="formRef"
@@ -8,38 +8,39 @@
             :rules="rules"
             :model="form"
             label-width="140rpx">
-      <u-form-item prop="approveReason"
-                   label="娴佺▼缂栧彿">
-        <u-input v-model="form.approveId"
-                 disabled
-                 placeholder="鑷姩缂栧彿" />
-      </u-form-item>
-      <u-form-item prop="approveReason"
-                   :label="approveType === 5 ? '閲囪喘浜嬬敱' : '鐢宠浜嬬敱'"
-                   required>
-        <u-input v-model="form.approveReason"
-                 type="textarea"
-                 rows="2"
-                 auto-height
-                 maxlength="200"
-                 :placeholder="approveType === 5 ? '璇疯緭鍏ラ噰璐簨鐢�' : '璇疯緭鍏ョ敵璇蜂簨鐢�'"
-                 show-word-limit />
-      </u-form-item>
-      <u-form-item prop="approveDeptName"
-                   label="鐢宠閮ㄩ棬"
-                   required>
-        <!-- <u-input v-model="form.approveDeptName"
+      <template v-if="operationType !== 'detail'">
+        <u-form-item prop="approveReason"
+                     label="娴佺▼缂栧彿">
+          <u-input v-model="form.approveId"
+                   disabled
+                   placeholder="鑷姩缂栧彿" />
+        </u-form-item>
+        <u-form-item prop="approveReason"
+                     :label="approveType === 5 ? '閲囪喘浜嬬敱' : '鐢宠浜嬬敱'"
+                     required>
+          <u-input v-model="form.approveReason"
+                   type="textarea"
+                   rows="2"
+                   auto-height
+                   maxlength="200"
+                   :placeholder="approveType === 5 ? '璇疯緭鍏ラ噰璐簨鐢�' : '璇疯緭鍏ョ敵璇蜂簨鐢�'"
+                   show-word-limit />
+        </u-form-item>
+        <u-form-item prop="approveDeptName"
+                     label="鐢宠閮ㄩ棬"
+                     required>
+          <!-- <u-input v-model="form.approveDeptName"
                  placeholder="璇烽�夋嫨鐢宠閮ㄩ棬" /> -->
-        <u-input v-model="form.approveDeptName"
-                 readonly
-                 placeholder="璇烽�夋嫨鐢宠閮ㄩ棬"
-                 @click="showPicker = true" />
-        <template #right>
-          <up-icon name="arrow-right"
-                   @click="showPicker = true"></up-icon>
-        </template>
-      </u-form-item>
-      <u-form-item prop="approveUser"
+          <u-input v-model="form.approveDeptName"
+                   readonly
+                   placeholder="璇烽�夋嫨鐢宠閮ㄩ棬"
+                   @click="showPicker = true" />
+          <template #right>
+            <up-icon name="arrow-right"
+                     @click="showPicker = true"></up-icon>
+          </template>
+        </u-form-item>
+        <!-- <u-form-item prop="approveUser"
                    label="鐢宠浜�"
                    required>
         <u-input v-model="form.approveUserName"
@@ -57,141 +58,277 @@
           <up-icon name="arrow-right"
                    @click="showDatePicker"></up-icon>
         </template>
-      </u-form-item>
-      <!-- approveType=2 璇峰亣鐩稿叧瀛楁 -->
-      <template v-if="approveType === 2">
-        <u-form-item prop="startDate"
-                     label="寮�濮嬫椂闂�"
+      </u-form-item> -->
+        <!-- approveType=2 璇峰亣鐩稿叧瀛楁 -->
+        <template v-if="approveType === 2">
+          <u-form-item prop="startDate"
+                       label="寮�濮嬫椂闂�"
+                       required>
+            <u-input v-model="form.startDate"
+                     readonly
+                     placeholder="璇峰亣寮�濮嬫椂闂�"
+                     @click="showStartDatePicker" />
+            <template #right>
+              <up-icon name="arrow-right"
+                       @click="showStartDatePicker"></up-icon>
+            </template>
+          </u-form-item>
+          <u-form-item prop="endDate"
+                       label="缁撴潫鏃堕棿"
+                       required>
+            <u-input v-model="form.endDate"
+                     readonly
+                     placeholder="璇峰亣缁撴潫鏃堕棿"
+                     @click="showEndDatePicker" />
+            <template #right>
+              <up-icon name="arrow-right"
+                       @click="showEndDatePicker"></up-icon>
+            </template>
+          </u-form-item>
+        </template>
+        <!-- approveType=3 鍑哄樊鐩稿叧瀛楁 -->
+        <u-form-item v-if="approveType === 3"
+                     prop="location"
+                     label="鍑哄樊鍦扮偣"
                      required>
-          <u-input v-model="form.startDate"
-                   readonly
-                   placeholder="璇峰亣寮�濮嬫椂闂�"
-                   @click="showStartDatePicker" />
-          <template #right>
-            <up-icon name="arrow-right"
-                     @click="showStartDatePicker"></up-icon>
-          </template>
+          <u-input v-model="form.location"
+                   placeholder="璇疯緭鍏ュ嚭宸湴鐐�"
+                   clearable />
         </u-form-item>
-        <u-form-item prop="endDate"
-                     label="缁撴潫鏃堕棿"
+        <!-- approveType=4 鎶ラ攢鐩稿叧瀛楁 -->
+        <u-form-item v-if="approveType === 4"
+                     prop="price"
+                     label="鎶ラ攢閲戦"
                      required>
-          <u-input v-model="form.endDate"
-                   readonly
-                   placeholder="璇峰亣缁撴潫鏃堕棿"
-                   @click="showEndDatePicker" />
-          <template #right>
-            <up-icon name="arrow-right"
-                     @click="showEndDatePicker"></up-icon>
-          </template>
+          <u-input v-model="form.price"
+                   type="number"
+                   placeholder="璇疯緭鍏ユ姤閿�閲戦"
+                   clearable />
         </u-form-item>
       </template>
-      <!-- approveType=3 鍑哄樊鐩稿叧瀛楁 -->
-      <u-form-item v-if="approveType === 3"
-                   prop="location"
-                   label="鍑哄樊鍦扮偣"
-                   required>
-        <u-input v-model="form.location"
-                 placeholder="璇疯緭鍏ュ嚭宸湴鐐�"
-                 clearable />
-      </u-form-item>
-      <!-- approveType=4 鎶ラ攢鐩稿叧瀛楁 -->
-      <u-form-item v-if="approveType === 4"
-                   prop="price"
-                   label="鎶ラ攢閲戦"
-                   required>
-        <u-input v-model="form.price"
-                 type="number"
-                 placeholder="璇疯緭鍏ユ姤閿�閲戦"
-                 clearable />
+      <!-- 鎶ヤ环瀹℃壒璇︽儏 -->
+      <view v-if="isQuotationApproval"
+            style="margin: 20rpx 0;">
+        <u-divider text="鎶ヤ环璇︽儏"
+                   text-size="28rpx"
+                   color="#2979ff"></u-divider>
+        <u-skeleton :loading="quotationLoading"
+                    rows="3"
+                    animated>
+          <view v-if="!currentQuotation || !currentQuotation.quotationNo"
+                style="padding: 40rpx; text-align: center; color: #999;">
+            鏈煡璇㈠埌瀵瑰簲鎶ヤ环璇︽儏
+          </view>
+          <view v-else>
+            <u-cell-group :border="false">
+              <u-cell title="鎶ヤ环鍗曞彿"
+                      :value="currentQuotation.quotationNo"></u-cell>
+              <u-cell title="瀹㈡埛鍚嶇О"
+                      :value="currentQuotation.customer"></u-cell>
+              <u-cell title="涓氬姟鍛�"
+                      :value="currentQuotation.salesperson"></u-cell>
+              <u-cell title="鎶ヤ环鏃ユ湡"
+                      :value="currentQuotation.quotationDate"></u-cell>
+              <u-cell title="鏈夋晥鏈熻嚦"
+                      :value="currentQuotation.validDate"></u-cell>
+              <u-cell title="浠樻鏂瑰紡"
+                      :value="currentQuotation.paymentMethod"></u-cell>
+              <u-cell title="鎶ヤ环鎬婚">
+                <template #value>
+                  <text style="font-size: 32rpx; color: #e6a23c; font-weight: bold;">
+                    楼{{ Number(currentQuotation.totalAmount ?? 0).toFixed(2) }}
+                  </text>
+                </template>
+              </u-cell>
+            </u-cell-group>
+            <view style="margin-top: 20rpx; padding: 0 30rpx;">
+              <view style="font-size: 28rpx; font-weight: bold; margin-bottom: 10rpx;">浜у搧鏄庣粏</view>
+              <view v-for="(item, index) in (currentQuotation.products || [])"
+                    :key="index"
+                    style="background: #f8f8f8; border-radius: 8rpx; padding: 20rpx; margin-bottom: 10rpx;">
+                <view style="display: flex; justify-content: space-between;">
+                  <text style="font-weight: bold;">{{ item.product }}</text>
+                  <text style="color: #e6a23c;">楼{{ Number(item.unitPrice ?? 0).toFixed(2) }}</text>
+                </view>
+                <view style="font-size: 24rpx; color: #666; margin-top: 10rpx;">
+                  瑙勬牸: {{ item.specification }} | 鍗曚綅: {{ item.unit }}
+                </view>
+              </view>
+            </view>
+            <view v-if="currentQuotation.remark"
+                  style="margin-top: 20rpx; padding: 0 30rpx;">
+              <view style="font-size: 28rpx; font-weight: bold;">澶囨敞</view>
+              <view style="font-size: 26rpx; color: #666; margin-top: 10rpx;">{{ currentQuotation.remark }}</view>
+            </view>
+          </view>
+        </u-skeleton>
+      </view>
+      <!-- 閲囪喘瀹℃壒璇︽儏 -->
+      <view v-if="isPurchaseApproval"
+            style="margin: 20rpx 0;">
+        <u-divider text="閲囪喘璇︽儏"
+                   text-size="28rpx"
+                   color="#2979ff"></u-divider>
+        <u-skeleton :loading="purchaseLoading"
+                    rows="3"
+                    animated>
+          <view v-if="!currentPurchase || !currentPurchase.purchaseContractNumber"
+                style="padding: 40rpx; text-align: center; color: #999;">
+            鏈煡璇㈠埌瀵瑰簲閲囪喘璇︽儏
+          </view>
+          <view v-else>
+            <u-cell-group :border="false">
+              <u-cell title="閲囪喘鍚堝悓鍙�"
+                      :value="currentPurchase.purchaseContractNumber"></u-cell>
+              <u-cell title="渚涘簲鍟嗗悕绉�"
+                      :value="currentPurchase.supplierName"></u-cell>
+              <u-cell title="椤圭洰鍚嶇О"
+                      :value="currentPurchase.projectName"></u-cell>
+              <u-cell title="閿�鍞悎鍚屽彿"
+                      :value="currentPurchase.salesContractNo"></u-cell>
+              <u-cell title="绛捐鏃ユ湡"
+                      :value="currentPurchase.executionDate"></u-cell>
+              <u-cell title="褰曞叆鏃ユ湡"
+                      :value="currentPurchase.entryDate"></u-cell>
+              <u-cell title="浠樻鏂瑰紡"
+                      :value="currentPurchase.paymentMethod"></u-cell>
+              <u-cell title="鍚堝悓閲戦">
+                <template #value>
+                  <text style="font-size: 32rpx; color: #e6a23c; font-weight: bold;">
+                    楼{{ Number(currentPurchase.contractAmount ?? 0).toFixed(2) }}
+                  </text>
+                </template>
+              </u-cell>
+            </u-cell-group>
+            <view style="margin-top: 20rpx; padding: 0 30rpx;">
+              <view style="font-size: 28rpx; font-weight: bold; margin-bottom: 10rpx;">浜у搧鏄庣粏</view>
+              <view v-for="(item, index) in (currentPurchase.productData || [])"
+                    :key="index"
+                    style="background: #f8f8f8; border-radius: 8rpx; padding: 20rpx; margin-bottom: 10rpx;">
+                <view style="display: flex; justify-content: space-between;">
+                  <text style="font-weight: bold;">{{ item.productCategory }}</text>
+                  <text style="color: #e6a23c;">楼{{ Number(item.taxInclusiveTotalPrice ?? 0).toFixed(2) }}</text>
+                </view>
+                <view style="font-size: 24rpx; color: #666; margin-top: 10rpx;">
+                  瑙勬牸: {{ item.specificationModel }} | 鏁伴噺: {{ item.quantity }} {{ item.unit }}
+                </view>
+                <view style="font-size: 24rpx; color: #999; margin-top: 4rpx;">
+                  鍚◣鍗曚环: 楼{{ Number(item.taxInclusiveUnitPrice ?? 0).toFixed(2) }}
+                </view>
+              </view>
+            </view>
+          </view>
+        </u-skeleton>
+      </view>
+      <!-- 鍙戣揣瀹℃壒璇︽儏 -->
+      <view v-if="isDeliveryApproval"
+            style="margin: 20rpx 0;">
+        <u-divider text="鍙戣揣璇︽儏"
+                   text-size="28rpx"
+                   color="#2979ff"></u-divider>
+        <u-skeleton :loading="deliveryLoading"
+                    rows="3"
+                    animated>
+          <view v-if="!currentDelivery || !currentDelivery.shippingInfo"
+                style="padding: 40rpx; text-align: center; color: #999;">
+            鏈煡璇㈠埌瀵瑰簲鍙戣揣璇︽儏
+          </view>
+          <view v-else>
+            <u-cell-group :border="false">
+              <u-cell title="閿�鍞鍗�"
+                      :value="currentDelivery.shippingInfo.salesContractNo || '--'"></u-cell>
+              <u-cell title="鍙戣揣璁㈠崟鍙�"
+                      :value="currentDelivery.shippingInfo.shippingNo || '--'"></u-cell>
+              <u-cell title="瀹㈡埛鍚嶇О"
+                      :value="currentDelivery.shippingInfo.customerName || '--'"></u-cell>
+              <u-cell title="鍙戣揣绫诲瀷"
+                      :value="currentDelivery.shippingInfo.type || '--'"></u-cell>
+              <u-cell title="鍙戣揣鏃ユ湡"
+                      :value="currentDelivery.shippingInfo.shippingDate || '--'"></u-cell>
+              <u-cell title="瀹℃牳鐘舵��"
+                      :value="currentDelivery.shippingInfo.status || '--'"></u-cell>
+              <u-cell title="鍙戣揣杞︾墝鍙�"
+                      :value="currentDelivery.shippingInfo.shippingCarNumber || '--'"></u-cell>
+              <u-cell title="蹇�掑叕鍙�"
+                      :value="currentDelivery.shippingInfo.expressCompany || '--'"></u-cell>
+              <u-cell title="蹇�掑崟鍙�"
+                      :value="currentDelivery.shippingInfo.expressNumber || '--'"></u-cell>
+            </u-cell-group>
+            <view style="margin-top: 20rpx; padding: 0 30rpx;">
+              <view style="font-size: 28rpx; font-weight: bold; margin-bottom: 10rpx;">浜у搧鏄庣粏</view>
+              <view v-for="(item, index) in deliveryProductList"
+                    :key="index"
+                    style="background: #f8f8f8; border-radius: 8rpx; padding: 20rpx; margin-bottom: 10rpx;">
+                <view style="display: flex; justify-content: space-between;">
+                  <text style="font-weight: bold;">{{ item.productName }}</text>
+                  <text style="color: #2979ff;">鏁伴噺: {{ item.deliveryQuantity }}</text>
+                </view>
+                <view style="font-size: 24rpx; color: #666; margin-top: 10rpx;">
+                  瑙勬牸: {{ item.specificationModel }}
+                </view>
+                <view v-if="item.batchNo"
+                      style="font-size: 24rpx; color: #999; margin-top: 4rpx;">
+                  鎵瑰彿: {{ item.batchNo }}
+                </view>
+              </view>
+            </view>
+            <view v-if="currentDelivery.shippingInfo.storageBlobVOs && currentDelivery.shippingInfo.storageBlobVOs.length"
+                  style="margin-top: 20rpx; padding: 0 30rpx;">
+              <view style="font-size: 28rpx; font-weight: bold; margin-bottom: 10rpx;">鍙戣揣鍥剧墖</view>
+              <CommonUpload :model-value="currentDelivery.shippingInfo.storageBlobVOs"
+                            disabled />
+            </view>
+          </view>
+        </u-skeleton>
+      </view>
+      <u-form-item v-if="operationType !== 'detail'"
+                   label="鍥剧墖闄勪欢"
+                   prop="storageBlobDTOS"
+                   border-bottom>
+        <CommonUpload v-model="form.storageBlobDTOS" />
       </u-form-item>
     </u-form>
     <!-- 閫夋嫨鍣ㄥ脊绐� -->
-    <up-action-sheet :show="showPicker"
-                     :actions="productOptions"
-                     title="閫夋嫨閮ㄩ棬"
-                     @select="onConfirm"
-                     @close="showPicker = false" />
-    <!-- 鏃ユ湡閫夋嫨鍣� -->
-    <up-popup :show="showDate"
-              mode="bottom"
-              @close="showDate = false">
-      <up-datetime-picker :show="true"
-                          v-model="currentDate"
-                          @confirm="onDateConfirm"
-                          @cancel="showDate = false"
-                          mode="date" />
-    </up-popup>
-    <!-- 璇峰亣寮�濮嬫椂闂撮�夋嫨鍣� -->
-    <up-popup :show="showStartDate"
-              mode="bottom"
-              @close="showStartDate = false">
-      <up-datetime-picker :show="true"
-                          v-model="startDateValue"
-                          @confirm="onStartDateConfirm"
-                          @cancel="showStartDate = false"
-                          mode="date" />
-    </up-popup>
-    <!-- 璇峰亣缁撴潫鏃堕棿閫夋嫨鍣� -->
-    <up-popup :show="showEndDate"
-              mode="bottom"
-              @close="showEndDate = false">
-      <up-datetime-picker :show="true"
-                          v-model="endDateValue"
-                          @confirm="onEndDateConfirm"
-                          @cancel="showEndDate = false"
-                          mode="date" />
-    </up-popup>
-    <!-- 瀹℃牳娴佺▼鍖哄煙 -->
-    <view class="approval-process">
-      <view class="approval-header">
-        <text class="approval-title">瀹℃牳娴佺▼</text>
-        <text class="approval-desc">姣忎釜姝ラ鍙兘閫夋嫨涓�涓鎵逛汉</text>
-      </view>
-      <view class="approval-steps">
-        <view v-for="(step, stepIndex) in approverNodes"
-              :key="stepIndex"
-              class="approval-step">
-          <view class="step-dot"></view>
-          <view class="step-title">
-            <text>瀹℃壒浜�</text>
-          </view>
-          <view class="approver-container">
-            <view v-if="step.nickName"
-                  class="approver-item">
-              <view class="approver-avatar">
-                <text class="avatar-text">{{ step.nickName.charAt(0) }}</text>
-                <view class="status-dot"></view>
-              </view>
-              <view class="approver-info">
-                <text class="approver-name">{{ step.nickName }}</text>
-              </view>
-              <view class="delete-approver-btn"
-                    @click="removeApprover(stepIndex)">脳</view>
-            </view>
-            <view v-else
-                  class="add-approver-btn"
-                  @click="addApprover(stepIndex)">
-              <view class="add-circle">+</view>
-              <text class="add-label">閫夋嫨瀹℃壒浜�</text>
-            </view>
-          </view>
-          <view class="step-line"
-                v-if="stepIndex < approverNodes.length - 1"></view>
-          <view class="delete-step-btn"
-                v-if="approverNodes.length > 1"
-                @click="removeApprovalStep(stepIndex)">鍒犻櫎鑺傜偣</view>
-        </view>
-      </view>
-      <view class="add-step-btn">
-        <u-button icon="plus"
-                  plain
-                  type="primary"
-                  style="width: 100%"
-                  @click="addApprovalStep">鏂板鑺傜偣</u-button>
-      </view>
-    </view>
+    <template v-if="operationType !== 'detail'">
+      <up-action-sheet :show="showPicker"
+                       :actions="productOptions"
+                       title="閫夋嫨閮ㄩ棬"
+                       @select="onConfirm"
+                       @close="showPicker = false" />
+      <!-- 鏃ユ湡閫夋嫨鍣� -->
+      <up-popup :show="showDate"
+                mode="bottom"
+                @close="showDate = false">
+        <up-datetime-picker :show="true"
+                            v-model="currentDate"
+                            @confirm="onDateConfirm"
+                            @cancel="showDate = false"
+                            mode="date" />
+      </up-popup>
+      <!-- 璇峰亣寮�濮嬫椂闂撮�夋嫨鍣� -->
+      <up-popup :show="showStartDate"
+                mode="bottom"
+                @close="showStartDate = false">
+        <up-datetime-picker :show="true"
+                            v-model="startDateValue"
+                            @confirm="onStartDateConfirm"
+                            @cancel="showStartDate = false"
+                            mode="date" />
+      </up-popup>
+      <!-- 璇峰亣缁撴潫鏃堕棿閫夋嫨鍣� -->
+      <up-popup :show="showEndDate"
+                mode="bottom"
+                @close="showEndDate = false">
+        <up-datetime-picker :show="true"
+                            v-model="endDateValue"
+                            @confirm="onEndDateConfirm"
+                            @cancel="showEndDate = false"
+                            mode="date" />
+      </up-popup>
+    </template>
     <!-- 搴曢儴鎸夐挳 -->
-    <view class="footer-btns">
+    <view class="footer-btns"
+          v-if="operationType !== 'detail'">
       <u-button class="cancel-btn"
                 @click="goBack">鍙栨秷</u-button>
       <u-button class="save-btn"
@@ -201,8 +338,17 @@
 </template>
 
 <script setup>
-  import { ref, onMounted, onUnmounted, reactive, toRefs } from "vue";
+  import {
+    ref,
+    onMounted,
+    onUnmounted,
+    reactive,
+    toRefs,
+    computed,
+    watch,
+  } from "vue";
   import PageHeader from "@/components/PageHeader.vue";
+  import CommonUpload from "@/components/CommonUpload.vue";
   import useUserStore from "@/store/modules/user";
   import { formatDateToYMD } from "@/utils/ruoyi";
   import {
@@ -210,14 +356,16 @@
     approveProcessGetInfo,
     approveProcessAdd,
     approveProcessUpdate,
+    getDeliveryDetailByShippingNo,
   } from "@/api/collaborativeApproval/approvalProcess";
+  import { getQuotationList } from "@/api/salesManagement/salesQuotation";
+  import { getPurchaseByCode } from "@/api/procurementManagement/procurementLedger";
   const showToast = message => {
     uni.showToast({
       title: message,
       icon: "none",
     });
   };
-  import { userListNoPageByTenantId } from "@/api/system/user";
 
   const data = reactive({
     form: {
@@ -229,8 +377,7 @@
       approveDeptId: "",
       approveReason: "",
       checkResult: "",
-      tempFileIds: [],
-      approverList: [], // 鏂板瀛楁锛屽瓨鍌ㄦ墍鏈夎妭鐐圭殑瀹℃壒浜篿d
+      storageBlobDTOS: [],
       startDate: "",
       endDate: "",
       location: "",
@@ -258,8 +405,6 @@
   const productOptions = ref([]);
   const operationType = ref("");
   const currentApproveStatus = ref("");
-  const approverNodes = ref([]);
-  const userList = ref([]);
   const formRef = ref(null);
   const message = ref("");
   const showDate = ref(false);
@@ -270,6 +415,19 @@
   const endDateValue = ref(Date.now());
   const userStore = useUserStore();
   const approveType = ref(0);
+  const isInitialLoading = ref(false);
+
+  const quotationLoading = ref(false);
+  const currentQuotation = ref({});
+  const purchaseLoading = ref(false);
+  const currentPurchase = ref({});
+  const deliveryLoading = ref(false);
+  const currentDelivery = ref({});
+  const deliveryProductList = ref([]);
+
+  const isQuotationApproval = computed(() => Number(approveType.value) === 6);
+  const isPurchaseApproval = computed(() => Number(approveType.value) === 5);
+  const isDeliveryApproval = computed(() => Number(approveType.value) === 7);
 
   const getProductOptions = () => {
     getDept().then(res => {
@@ -279,20 +437,133 @@
       }));
     });
   };
-  const fileList = ref([]);
-  let nextApproverId = 2;
   const getCurrentinfo = () => {
     userStore.getInfo().then(res => {
       form.value.approveDeptId = res.user.tenantId;
       console.log(res.user.tenantId, "res.user.tenantId");
     });
   };
+
+  // 鏄剧ず鏃ユ湡閫夋嫨鍣�
+  const showDatePicker = () => {
+    showDate.value = true;
+  };
+
+  // 纭鏃ユ湡閫夋嫨
+  const onDateConfirm = e => {
+    form.value.approveTime = formatDateToYMD(e.value);
+    currentDate.value = formatDateToYMD(e.value);
+    showDate.value = false;
+  };
+
+  // 鏄剧ず璇峰亣寮�濮嬫椂闂撮�夋嫨鍣�
+  const showStartDatePicker = () => {
+    showStartDate.value = true;
+  };
+
+  // 纭璇峰亣寮�濮嬫椂闂撮�夋嫨
+  const onStartDateConfirm = e => {
+    form.value.startDate = formatDateToYMD(e.value);
+    showStartDate.value = false;
+  };
+
+  const showEndDatePicker = () => {
+    showEndDate.value = true;
+  };
+
+  // 纭璇峰亣缁撴潫鏃堕棿閫夋嫨
+  const onEndDateConfirm = e => {
+    form.value.endDate = formatDateToYMD(e.value);
+    showEndDate.value = false;
+  };
+
+  const fetchDetailData = async row => {
+    // 鎶ヤ环瀹℃壒
+    if (isQuotationApproval.value) {
+      const quotationNo = row?.approveReason;
+      if (quotationNo) {
+        quotationLoading.value = true;
+        getQuotationList({ quotationNo })
+          .then(res => {
+            const records = res?.data?.records || [];
+            currentQuotation.value = records[0] || {};
+          })
+          .finally(() => {
+            quotationLoading.value = false;
+          });
+      }
+    }
+
+    // 閲囪喘瀹℃壒
+    if (isPurchaseApproval.value) {
+      const purchaseContractNumber = row?.approveReason;
+      if (purchaseContractNumber) {
+        purchaseLoading.value = true;
+        getPurchaseByCode({ purchaseContractNumber })
+          .then(res => {
+            currentPurchase.value = res;
+          })
+          .catch(err => {
+            console.error("鏌ヨ閲囪喘璇︽儏澶辫触:", err);
+          })
+          .finally(() => {
+            purchaseLoading.value = false;
+          });
+      }
+    }
+
+    // 鍙戣揣瀹℃壒
+    if (isDeliveryApproval.value) {
+      const deliveryNo = row?.approveReason;
+      if (deliveryNo) {
+        deliveryLoading.value = true;
+        currentDelivery.value = {};
+        deliveryProductList.value = [];
+        getDeliveryDetailByShippingNo({ shippingNo: deliveryNo })
+          .then(res => {
+            const detailData = res?.data || res || {};
+            currentDelivery.value = detailData;
+            deliveryProductList.value =
+              detailData.shippingProductDetailDtoList || [];
+          })
+          .catch(err => {
+            console.error("鏌ヨ鍙戣揣璇︽儏澶辫触:", err);
+          })
+          .finally(() => {
+            deliveryLoading.value = false;
+          });
+      }
+    }
+  };
+
+  // 鐩戝惉瀹℃壒浜嬬敱鍙樺寲锛屽鏋滄槸鐗瑰畾瀹℃壒绫诲瀷鍒欏皾璇曡幏鍙栬鎯�
+  watch(
+    () => form.value.approveReason,
+    newVal => {
+      if (isInitialLoading.value) return;
+      if (
+        newVal &&
+        (isQuotationApproval.value ||
+          isPurchaseApproval.value ||
+          isDeliveryApproval.value)
+      ) {
+        // 寤惰繜涓�浼氬啀璇锋眰锛岄伩鍏嶈緭鍏ヨ繃绋嬩腑棰戠箒瑙﹀彂
+        debounceFetchDetail();
+      }
+    }
+  );
+
+  let timer = null;
+  const debounceFetchDetail = () => {
+    if (timer) clearTimeout(timer);
+    timer = setTimeout(() => {
+      fetchDetailData(form.value);
+    }, 800);
+  };
+
   onMounted(async () => {
     try {
       getProductOptions();
-      userListNoPageByTenantId().then(res => {
-        userList.value = res.data;
-      });
       form.value.approveUser = userStore.id;
       form.value.approveUserName = userStore.nickName;
       form.value.approveTime = getCurrentDate();
@@ -302,57 +573,39 @@
       approveType.value = uni.getStorageSync("approveType") || 0;
 
       // 濡傛灉鏄紪杈戞ā寮忥紝浠庢湰鍦板瓨鍌ㄨ幏鍙栨暟鎹�
-      if (operationType.value === "edit") {
+      if (operationType.value === "edit" || operationType.value === "detail") {
         const storedData = uni.getStorageSync("invoiceLedgerEditRow");
         if (storedData) {
           const row = JSON.parse(storedData);
-          fileList.value = row.commonFileList || [];
-          form.value.tempFileIds = fileList.value.map(file => file.id);
           currentApproveStatus.value = row.approveStatus;
 
-          approveProcessGetInfo({ id: row.approveId, approveReason: "1" }).then(
-            res => {
+          isInitialLoading.value = true;
+          approveProcessGetInfo({ id: row.approveId, approveReason: "1" })
+            .then(res => {
               form.value = { ...res.data };
-              // 鍙嶆樉瀹℃壒浜�
-              if (res.data && res.data.approveUserIds) {
-                const userIds = res.data.approveUserIds.split(",");
-                approverNodes.value = userIds.map((userId, idx) => {
-                  const userIdNum = parseInt(userId.trim());
-                  // 浠巙serList涓壘鍒板搴旂殑鐢ㄦ埛淇℃伅
-                  const userInfo = userList.value.find(
-                    user => user.userId === userIdNum
-                  );
-                  return {
-                    id: idx + 1,
-                    userId: userIdNum,
-                    nickName: userInfo ? userInfo.nickName : null,
-                  };
-                });
-                nextApproverId = userIds.length + 1;
-              } else {
-                // 鏂板妯″紡锛屽垵濮嬪寲涓�涓┖鐨勫鎵硅妭鐐�
-                approverNodes.value = [{ id: 1, userId: null, nickName: null }];
-                nextApproverId = 2;
+              // 璁剧疆鍥剧墖鍒楄〃鏄剧ず
+              const fileData =
+                res.data.storageBlobVOS || res.data.commonFileList || [];
+              if (fileData.length > 0) {
+                form.value.storageBlobDTOS = fileData;
               }
-            }
-          );
+              // 鑾峰彇棰濆璇︽儏
+              fetchDetailData(res.data);
+            })
+            .finally(() => {
+              // 寤惰繜涓�浼氶噸缃紝纭繚 watch 涓嶄細琚Е鍙�
+              setTimeout(() => {
+                isInitialLoading.value = false;
+              }, 100);
+            });
         }
-      } else {
-        // 鏂板妯″紡锛屽垵濮嬪寲涓�涓┖鐨勫鎵硅妭鐐�
-        approverNodes.value = [{ id: 1, userId: null }];
       }
-
-      // 鐩戝惉鑱旂郴浜洪�夋嫨浜嬩欢
-      uni.$on("selectContact", handleSelectContact);
     } catch (error) {
-      console.error("鑾峰彇閮ㄩ棬鏁版嵁澶辫触:", error);
+      console.error("鑾峰彇鏁版嵁澶辫触:", error);
     }
   });
 
-  onUnmounted(() => {
-    // 绉婚櫎浜嬩欢鐩戝惉
-    uni.$off("selectContact", handleSelectContact);
-  });
+  onUnmounted(() => {});
 
   const onConfirm = item => {
     // 璁剧疆閫変腑鐨勯儴闂�
@@ -375,13 +628,6 @@
   };
 
   const submitForm = () => {
-    // 妫�鏌ユ瘡涓鎵规楠ゆ槸鍚﹂兘鏈夊鎵逛汉
-    const hasEmptyStep = approverNodes.value.some(step => !step.nickName);
-    if (hasEmptyStep) {
-      showToast("璇蜂负姣忎釜瀹℃壒姝ラ閫夋嫨瀹℃壒浜�");
-      return;
-    }
-
     // 鎵嬪姩妫�鏌ュ繀濉瓧娈碉紝闃叉鍥犳暟鎹被鍨嬮棶棰樺鑷寸殑鏍¢獙澶辫触
     if (!form.value.approveReason || !form.value.approveReason.trim()) {
       showToast("璇疯緭鍏ョ敵璇蜂簨鐢�");
@@ -406,26 +652,8 @@
       .then(valid => {
         if (valid) {
           // 琛ㄥ崟鏍¢獙閫氳繃锛屽彲浠ユ彁浜ゆ暟鎹�
-          // 鏀堕泦鎵�鏈夎妭鐐圭殑瀹℃壒浜篿d
-          console.log("approverNodes---", approverNodes.value);
-          form.value.approveUserIds = approverNodes.value
-            .map(node => node.userId)
-            .join(",");
           form.value.approveType = approveType.value;
           form.value.approveDeptId = Number(form.value.approveDeptId);
-          // const submitForm = {
-          //   approveDeptId: form.value.approveDeptId,
-          //   approveDeptName: form.value.approveDeptName,
-          //   approveReason: form.value.approveReason,
-          //   approveTime: form.value.approveTime,
-          //   approveType: form.value.approveType,
-          //   approveUser: form.value.approveUser,
-          //   approveUserIds: form.value.approveUserIds,
-          //   endDate: form.value.endDate,
-          //   startDate: form.value.startDate,
-          // };
-          // console.log("form.value---", form.value);
-          // console.log("submitForm", submitForm);
 
           if (operationType.value === "add" || currentApproveStatus.value == 3) {
             approveProcessAdd(form.value).then(res => {
@@ -461,77 +689,6 @@
       });
   };
 
-  // 澶勭悊鑱旂郴浜洪�夋嫨缁撴灉
-  const handleSelectContact = data => {
-    const { stepIndex, contact } = data;
-    // 灏嗛�変腑鐨勮仈绯讳汉璁剧疆涓哄搴斿鎵规楠ょ殑瀹℃壒浜�
-    approverNodes.value[stepIndex].userId = contact.userId;
-    approverNodes.value[stepIndex].nickName = contact.nickName;
-  };
-
-  const addApprover = stepIndex => {
-    // 璺宠浆鍒拌仈绯讳汉閫夋嫨椤甸潰
-    uni.setStorageSync("stepIndex", stepIndex);
-    uni.navigateTo({
-      url: "/pages/cooperativeOffice/collaborativeApproval/contactSelect",
-    });
-  };
-
-  const addApprovalStep = () => {
-    // 娣诲姞鏂扮殑瀹℃壒姝ラ
-    approverNodes.value.push({ userId: null, nickName: null });
-  };
-
-  const removeApprover = stepIndex => {
-    // 绉婚櫎瀹℃壒浜�
-    approverNodes.value[stepIndex].userId = null;
-    approverNodes.value[stepIndex].nickName = null;
-  };
-
-  const removeApprovalStep = stepIndex => {
-    // 纭繚鑷冲皯淇濈暀涓�涓鎵规楠�
-    if (approverNodes.value.length > 1) {
-      approverNodes.value.splice(stepIndex, 1);
-    } else {
-      uni.showToast({
-        title: "鑷冲皯闇�瑕佷竴涓鎵规楠�",
-        icon: "none",
-      });
-    }
-  };
-  // 鏄剧ず鏃ユ湡閫夋嫨鍣�
-  const showDatePicker = () => {
-    showDate.value = true;
-  };
-
-  // 纭鏃ユ湡閫夋嫨
-  const onDateConfirm = e => {
-    form.value.approveTime = formatDateToYMD(e.value);
-    currentDate.value = formatDateToYMD(e.value);
-    showDate.value = false;
-  };
-
-  // 鏄剧ず璇峰亣寮�濮嬫椂闂撮�夋嫨鍣�
-  const showStartDatePicker = () => {
-    showStartDate.value = true;
-  };
-
-  // 纭璇峰亣寮�濮嬫椂闂撮�夋嫨
-  const onStartDateConfirm = e => {
-    form.value.startDate = formatDateToYMD(e.value);
-    showStartDate.value = false;
-  };
-
-  const showEndDatePicker = () => {
-    showEndDate.value = true;
-  };
-
-  // 纭璇峰亣缁撴潫鏃堕棿閫夋嫨
-  const onEndDateConfirm = e => {
-    form.value.endDate = formatDateToYMD(e.value);
-    showEndDate.value = false;
-  };
-
   // 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
   function getCurrentDate() {
     const today = new Date();
@@ -544,238 +701,8 @@
 
 <style scoped lang="scss">
   @import "@/static/scss/form-common.scss";
-
-  .approval-process {
-    background: #fff;
-    margin: 16px;
-    border-radius: 16px;
-    padding: 16px;
-    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
-  }
-
-  .approval-header {
-    margin-bottom: 16px;
-  }
-
-  .approval-title {
-    font-size: 16px;
-    font-weight: 600;
-    color: #333;
-    display: block;
-    margin-bottom: 4px;
-  }
-
-  .approval-desc {
-    font-size: 12px;
-    color: #999;
-  }
-
-  /* 鏍峰紡澧炲己涓衡�滅畝娲佸皬鍦嗗湀椋庢牸鈥� */
-  .approval-steps {
-    padding-left: 22px;
-    position: relative;
-
-    &::before {
-      content: "";
-      position: absolute;
-      left: 11px;
-      top: 40px;
-      bottom: 40px;
-      width: 2px;
-      background: linear-gradient(
-        to bottom,
-        #e6f7ff 0%,
-        #bae7ff 50%,
-        #91d5ff 100%
-      );
-      border-radius: 1px;
-    }
-  }
-
-  .approval-step {
-    position: relative;
-    margin-bottom: 24px;
-
-    &::before {
-      content: "";
-      position: absolute;
-      left: -18px;
-      top: 14px; // 浠� 8px 璋冩暣涓� 14px锛屼笌鏂囧瓧涓績瀵归綈
-      width: 12px;
-      height: 12px;
-      background: #fff;
-      border: 3px solid #006cfb;
-      border-radius: 50%;
-      z-index: 2;
-      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
-    }
-  }
-
-  .step-title {
-    top: 12px;
-    margin-bottom: 12px;
-    position: relative;
-    margin-left: 6px;
-  }
-
-  .step-title text {
-    font-size: 14px;
-    color: #666;
-    background: #f0f0f0;
-    padding: 4px 12px;
-    border-radius: 12px;
-    position: relative;
-    line-height: 1.4; // 纭繚鏂囧瓧琛岄珮涓�鑷�
-  }
-
-  .approver-item {
-    display: flex;
-    align-items: center;
-    background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
-    border-radius: 16px;
-    padding: 16px;
-    gap: 12px;
-    position: relative;
-    border: 1px solid #e6f7ff;
-    box-shadow: 0 4px 12px rgba(0, 108, 251, 0.08);
-    transition: all 0.3s ease;
-  }
-
-  .approver-avatar {
-    width: 48px;
-    height: 48px;
-    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-    border-radius: 50%;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    position: relative;
-    box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
-  }
-
-  .avatar-text {
-    color: #fff;
-    font-size: 18px;
-    font-weight: 600;
-    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
-  }
-
-  .approver-info {
-    flex: 1;
-    position: relative;
-  }
-
-  .approver-name {
-    display: block;
-    font-size: 16px;
-    color: #333;
-    font-weight: 500;
-    position: relative;
-  }
-
-  .approver-dept {
-    font-size: 12px;
-    color: #999;
-    background: rgba(0, 108, 251, 0.05);
-    padding: 2px 8px;
-    border-radius: 8px;
-    display: inline-block;
-    position: relative;
-
-    &::before {
-      content: "";
-      position: absolute;
-      left: 4px;
-      top: 50%;
-      transform: translateY(-50%);
-      width: 2px;
-      height: 2px;
-      background: #006cfb;
-      border-radius: 50%;
-    }
-  }
-
-  .delete-approver-btn {
-    font-size: 16px;
-    color: #ff4d4f;
-    background: linear-gradient(
-      135deg,
-      rgba(255, 77, 79, 0.1) 0%,
-      rgba(255, 77, 79, 0.05) 100%
-    );
-    width: 28px;
-    height: 28px;
-    border-radius: 50%;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    transition: all 0.3s ease;
-    position: relative;
-  }
-
-  .add-approver-btn {
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    background: linear-gradient(135deg, #f0f8ff 0%, #e6f7ff 100%);
-    border: 2px dashed #006cfb;
-    border-radius: 16px;
-    padding: 20px;
-    color: #006cfb;
-    font-size: 14px;
-    position: relative;
-    transition: all 0.3s ease;
-
-    &::before {
-      content: "";
-      position: absolute;
-      left: 50%;
-      top: 50%;
-      transform: translate(-50%, -50%);
-      width: 32px;
-      height: 32px;
-      border: 2px solid #006cfb;
-      border-radius: 50%;
-      opacity: 0;
-      transition: all 0.3s ease;
-    }
-  }
-
-  .delete-step-btn {
-    color: #ff4d4f;
-    font-size: 12px;
-    background: linear-gradient(
-      135deg,
-      rgba(255, 77, 79, 0.1) 0%,
-      rgba(255, 77, 79, 0.05) 100%
-    );
-    padding: 6px 12px;
-    border-radius: 12px;
-    display: inline-block;
-    position: relative;
-    transition: all 0.3s ease;
-
-    &::before {
-      content: "";
-      position: absolute;
-      left: 6px;
-      top: 50%;
-      transform: translateY(-50%);
-      width: 4px;
-      height: 4px;
-      background: #ff4d4f;
-      border-radius: 50%;
-    }
-  }
-
-  .step-line {
-    display: none; // 闅愯棌鍘熸潵鐨勭嚎鏉★紝浣跨敤浼厓绱犱唬鏇�
-  }
-
-  .add-step-btn {
-    display: flex;
-    align-items: center;
-    justify-content: center;
+  .account-detail {
+    background-color: #fff;
   }
   .footer-btns {
     position: fixed;
@@ -809,121 +736,5 @@
     background: linear-gradient(140deg, #00baff 0%, #006cfb 100%);
     box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
     border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
-  }
-
-  // 鍔ㄧ敾瀹氫箟
-  @keyframes pulse {
-    0% {
-      transform: scale(1);
-      opacity: 1;
-    }
-    50% {
-      transform: scale(1.2);
-      opacity: 0.7;
-    }
-    100% {
-      transform: scale(1);
-      opacity: 1;
-    }
-  }
-
-  @keyframes rotate {
-    0% {
-      transform: rotate(0deg);
-    }
-    100% {
-      transform: rotate(360deg);
-    }
-  }
-
-  @keyframes ripple {
-    0% {
-      transform: translate(-50%, -50%) scale(0.8);
-      opacity: 1;
-    }
-    100% {
-      transform: translate(-50%, -50%) scale(1.6);
-      opacity: 0;
-    }
-  }
-
-  /* 濡傛灉宸叉湁 .step-line锛岃繖閲屾洿绮惧噯瀹氫綅鍒板乏渚т笌灏忓渾鐐瑰榻� */
-  .step-line {
-    position: absolute;
-    left: 4px;
-    top: 48px;
-    width: 2px;
-    height: calc(100% - 48px);
-    background: #e5e7eb;
-  }
-
-  .approver-container {
-    display: flex;
-    align-items: center;
-    background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
-    border-radius: 16px;
-    gap: 12px;
-    padding: 10px 0;
-    background: transparent;
-    border: none;
-    box-shadow: none;
-  }
-
-  .approver-item {
-    display: flex;
-    align-items: center;
-    gap: 12px;
-    padding: 8px 10px;
-    background: transparent;
-    border: none;
-    box-shadow: none;
-    border-radius: 0;
-  }
-
-  .approver-avatar {
-    position: relative;
-    width: 40px;
-    height: 40px;
-    border-radius: 50%;
-    background: #f3f4f6;
-    border: 2px solid #e5e7eb;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    animation: none; /* 绂佺敤鏃嬭浆绛夊姩鐢伙紝鍥炲綊绠�娲� */
-  }
-
-  .avatar-text {
-    font-size: 14px;
-    color: #374151;
-    font-weight: 600;
-  }
-
-  .add-approver-btn {
-    display: flex;
-    align-items: center;
-    gap: 8px;
-    background: transparent;
-    border: none;
-    box-shadow: none;
-    padding: 0;
-  }
-
-  .add-approver-btn .add-circle {
-    width: 40px;
-    height: 40px;
-    border: 2px dashed #a0aec0;
-    border-radius: 50%;
-    color: #6b7280;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    font-size: 22px;
-    line-height: 1;
-  }
-
-  .add-approver-btn .add-label {
-    color: #3b82f6;
-    font-size: 14px;
   }
 </style>
\ No newline at end of file
diff --git a/src/pages/cooperativeOffice/collaborativeApproval/index.vue b/src/pages/cooperativeOffice/collaborativeApproval/index.vue
index 3c374ef..910cdc3 100644
--- a/src/pages/cooperativeOffice/collaborativeApproval/index.vue
+++ b/src/pages/cooperativeOffice/collaborativeApproval/index.vue
@@ -97,13 +97,20 @@
               </view>
               <view class="detail-row">
                 <view class="actions">
-                  <!-- <u-button type="primary"
+                  <u-button type="primary"
                             size="small"
                             class="action-btn edit"
-                            :disabled="item.approveStatus == 2 || item.approveStatus == 1 || item.approveStatus == 4 || item.approveStatus == 8"
+                            v-if="!(item.approveStatus == 2 || item.approveStatus == 1 || item.approveStatus == 4 || item.approveStatus == 8 || item.approveType == 5 || item.approveType == 6 || item.approveType == 7)"
                             @click="handleItemClick(item)">
                     缂栬緫
-                  </u-button> -->
+                  </u-button>
+                  <u-button type="info"
+                            v-if="item.approveType == 5 || item.approveType == 6 || item.approveType == 7"
+                            size="small"
+                            class="action-btn detail"
+                            @click="handleDetailClick(item)">
+                    璇︽儏
+                  </u-button>
                   <u-button type="success"
                             size="small"
                             class="action-btn approve"
@@ -262,6 +269,17 @@
     });
   };
 
+  // 鏌ョ湅璇︽儏
+  const handleDetailClick = item => {
+    uni.setStorageSync("invoiceLedgerEditRow", JSON.stringify(item));
+    uni.setStorageSync("operationType", "detail");
+    uni.setStorageSync("approveId", item.approveId);
+    uni.setStorageSync("approveType", props.approveType);
+    uni.navigateTo({
+      url: "/pages/cooperativeOffice/collaborativeApproval/detail",
+    });
+  };
+
   // 娣诲姞鏂拌褰�
   const handleAdd = () => {
     uni.setStorageSync("operationType", "add");
diff --git a/src/pages/equipmentManagement/repair/add.vue b/src/pages/equipmentManagement/repair/add.vue
index e931494..73c4eba 100644
--- a/src/pages/equipmentManagement/repair/add.vue
+++ b/src/pages/equipmentManagement/repair/add.vue
@@ -77,9 +77,9 @@
                    clearable />
         </u-form-item>
         <u-form-item label="缁翠慨椤圭洰"
-                     prop="maintenanceProject"
+                     prop="machineryCategory"
                      border-bottom>
-          <u-input v-model="form.maintenanceProject"
+          <u-input v-model="form.machineryCategory"
                    placeholder="璇疯緭鍏ョ淮淇」鐩�"
                    clearable />
         </u-form-item>
@@ -93,6 +93,11 @@
                       clearable
                       count
                       maxlength="200" />
+        </u-form-item>
+        <u-form-item label="鍥剧墖闄勪欢"
+                     prop="storageBlobDTOs"
+                     border-bottom>
+          <CommonUpload v-model="form.storageBlobDTOs" />
         </u-form-item>
       </u-cell-group>
       <!-- 鎻愪氦鎸夐挳 -->
@@ -122,8 +127,9 @@
 
 <script setup>
   import { ref, computed, onMounted, onUnmounted } from "vue";
-  import { onShow } from "@dcloudio/uni-app";
+  import { onShow, onLoad } from "@dcloudio/uni-app";
   import PageHeader from "@/components/PageHeader.vue";
+  import CommonUpload from "@/components/CommonUpload.vue";
   import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
   import {
     addRepair,
@@ -146,10 +152,18 @@
   // 琛ㄥ崟寮曠敤
   const formRef = ref(null);
   const operationType = ref("add");
+  const repairId = ref("");
   const loading = ref(false);
   const showDevice = ref(false);
   const showDate = ref(false);
   const pickerDateValue = ref(Date.now());
+
+  onLoad(options => {
+    if (options.id) {
+      repairId.value = options.id;
+    }
+    getPageParams();
+  });
 
   // 璁惧閫夐」
   const deviceOptions = ref([]);
@@ -184,8 +198,9 @@
     repairTime: dayjs().format("YYYY-MM-DD"), // 鎶ヤ慨鏃ユ湡
     repairName: undefined, // 鎶ヤ慨浜�
     maintenanceName: undefined, // 缁翠慨浜�
-    maintenanceProject: undefined, // 缁翠慨椤圭洰
+    machineryCategory: undefined, // 缁翠慨椤圭洰
     remark: undefined, // 鏁呴殰鐜拌薄
+    storageBlobDTOs: [], // 鍥剧墖闄勪欢
   });
 
   // 鎶ヤ慨鐘舵�侀�夐」
@@ -238,8 +253,9 @@
           form.value.repairTime = dayjs(data.repairTime).format("YYYY-MM-DD");
           form.value.repairName = data.repairName;
           form.value.maintenanceName = data.maintenanceName;
-          form.value.maintenanceProject = data.maintenanceProject;
+          form.value.machineryCategory = data.machineryCategory;
           form.value.remark = data.remark;
+          form.value.storageBlobDTOs = data.storageBlobVOs || [];
           repairStatusText.value =
             repairStatusOptions.value.find(item => item.value == data.status)
               ?.name || "";
@@ -346,14 +362,12 @@
   };
 
   onShow(() => {
-    // 椤甸潰鏄剧ず鏃惰幏鍙栧弬鏁�
-    getPageParams();
+    // 椤甸潰鏄剧ず鏃堕�昏緫
   });
 
   onMounted(() => {
-    // 椤甸潰鍔犺浇鏃惰幏鍙栬澶囧垪琛ㄥ拰鍙傛暟
+    // 椤甸潰鍔犺浇鏃惰幏鍙栬澶囧垪琛�
     loadDeviceName();
-    getPageParams();
   });
 
   // 缁勪欢鍗歌浇鏃舵竻鐞嗗畾鏃跺櫒
@@ -393,7 +407,6 @@
 
       // 鍑嗗鎻愪氦鏁版嵁
       const submitData = { ...form.value };
-
       const { code } = id
         ? await editRepair({ id: id, ...submitData })
         : await addRepair(submitData);
@@ -414,21 +427,15 @@
 
   // 杩斿洖涓婁竴椤�
   const goBack = () => {
-    uni.removeStorageSync("repairId");
     uni.navigateBack();
   };
 
   // 鑾峰彇椤甸潰鍙傛暟
   const getPageParams = () => {
-    // 浣跨敤uni.getStorageSync鑾峰彇id
-    const id = uni.getStorageSync("repairId");
-
     // 鏍规嵁鏄惁鏈塱d鍙傛暟鏉ュ垽鏂槸鏂板杩樻槸缂栬緫
-    if (id) {
+    if (repairId.value) {
       // 缂栬緫妯″紡锛岃幏鍙栬鎯�
-      loadForm(id);
-      // 鍙�夛細鑾峰彇鍚庢竻闄ゅ瓨鍌ㄧ殑id锛岄伩鍏嶅奖鍝嶅悗缁搷浣�
-      uni.removeStorageSync("repairId");
+      loadForm(repairId.value);
     } else {
       // 鏂板妯″紡
       loadForm();
@@ -437,9 +444,7 @@
 
   // 鑾峰彇椤甸潰ID
   const getPageId = () => {
-    // 浣跨敤uni.getStorageSync鑾峰彇id
-    const id = uni.getStorageSync("repairId");
-    return id;
+    return repairId.value;
   };
 </script>
 
diff --git a/src/pages/equipmentManagement/repair/index.vue b/src/pages/equipmentManagement/repair/index.vue
index 5543e43..8c41ab1 100644
--- a/src/pages/equipmentManagement/repair/index.vue
+++ b/src/pages/equipmentManagement/repair/index.vue
@@ -63,7 +63,7 @@
             </view>
             <view class="detail-row">
               <text class="detail-label">缁翠慨椤圭洰</text>
-              <text class="detail-value">{{ item.maintenanceProject || '-' }}</text>
+              <text class="detail-value">{{ item.machineryCategory || '-' }}</text>
             </view>
             <view class="detail-row">
               <text class="detail-label">鏁呴殰鐜拌薄</text>
@@ -212,9 +212,9 @@
   const edit = id => {
     if (!id) return;
     // 浣跨敤uni.setStorageSync瀛樺偍id
-    uni.setStorageSync("repairId", id);
+    // uni.setStorageSync("repairId", id);
     uni.navigateTo({
-      url: "/pages/equipmentManagement/repair/add",
+      url: "/pages/equipmentManagement/repair/add?id=" + id,
     });
   };
 
diff --git a/src/pages/equipmentManagement/upkeep/add.vue b/src/pages/equipmentManagement/upkeep/add.vue
index 2b5d3da..5173510 100644
--- a/src/pages/equipmentManagement/upkeep/add.vue
+++ b/src/pages/equipmentManagement/upkeep/add.vue
@@ -1,413 +1,435 @@
 <template>
-	<view class="upkeep-add">
-		<!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
-		<PageHeader :title="operationType === 'edit' ? '缂栬緫淇濆吇璁″垝' : '鏂板淇濆吇璁″垝'" @back="goBack" />
-		
-		<!-- 琛ㄥ崟鍐呭 -->
-		<u-form ref="formRef" :model="form" :rules="formRules" label-width="110px">
-			<!-- 鍩烘湰淇℃伅 -->
-			<u-form-item label="璁惧鍚嶇О" prop="deviceNameText" required border-bottom>
-				<u-input
-					v-model="form.deviceNameText"
-					placeholder="璇烽�夋嫨璁惧鍚嶇О"
-					readonly
-					@click="showDevicePicker"
-					clearable
-				/>
-				<template #right>
-					<u-icon name="scan" @click="startScan" class="scan-icon" />
-				</template>
-			</u-form-item>
-			
-			<u-form-item label="瑙勬牸鍨嬪彿" prop="deviceModel" border-bottom>
-				<u-input
-					v-model="form.deviceModel"
-					placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
-					readonly
-					clearable
-				/>
-			</u-form-item>
-			
-			<u-form-item label="璁″垝淇濆吇鏃ユ湡" prop="maintenancePlanTime" required border-bottom>
-				<u-input
-					v-model="form.maintenancePlanTime"
-					placeholder="璇烽�夋嫨璁″垝淇濆吇鏃ユ湡"
-					readonly
-					@click="showDatePicker"
-					clearable
-				/>
-				<template #right>
-					<u-icon name="arrow-right" @click="showDatePicker" />
-				</template>
-			</u-form-item>
-			
-			<u-form-item label="淇濆吇浜�" prop="maintenancePerson" border-bottom>
-				<u-input
-					v-model="form.maintenancePerson"
-					placeholder="璇疯緭鍏ヤ繚鍏讳汉"
-					clearable
-				/>
-			</u-form-item>
-			
-			<u-form-item label="淇濆吇椤圭洰" prop="maintenanceProject" border-bottom>
-				<u-input
-					v-model="form.maintenanceProject"
-					placeholder="璇疯緭鍏ヤ繚鍏婚」鐩�"
-					clearable
-				/>
-			</u-form-item>
-			
-			<!-- 鎻愪氦鎸夐挳 -->
-			<view class="footer-btns">
-				<u-button class="cancel-btn" @click="goBack">鍙栨秷</u-button>
-				<u-button class="save-btn" @click="sendForm" :loading="loading">淇濆瓨</u-button>
-			</view>
-		</u-form>
-
-		<!-- 璁惧閫夋嫨鍣� -->
-		<up-action-sheet
-			:show="showDevice"
-			:actions="deviceActions"
-			title="閫夋嫨璁惧"
-			@select="onDeviceConfirm"
-			@close="showDevice = false"
-		/>
-<up-datetime-picker
-			:show="showDate"
-			v-model="pickerDateValue"
-			@confirm="onDateConfirm"
-			@cancel="showDate = false"
-			mode="date"
-		/>
-	
-	</view>
+  <view class="upkeep-add">
+    <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+    <PageHeader :title="operationType === 'edit' ? '缂栬緫淇濆吇璁″垝' : '鏂板淇濆吇璁″垝'"
+                @back="goBack" />
+    <!-- 琛ㄥ崟鍐呭 -->
+    <u-form ref="formRef"
+            :model="form"
+            :rules="formRules"
+            label-width="110px">
+      <!-- 鍩烘湰淇℃伅 -->
+      <u-form-item label="璁惧鍚嶇О"
+                   prop="deviceNameText"
+                   required
+                   border-bottom>
+        <u-input v-model="form.deviceNameText"
+                 placeholder="璇烽�夋嫨璁惧鍚嶇О"
+                 readonly
+                 @click="showDevicePicker"
+                 clearable />
+        <template #right>
+          <u-icon name="scan"
+                  @click="startScan"
+                  class="scan-icon" />
+        </template>
+      </u-form-item>
+      <u-form-item label="瑙勬牸鍨嬪彿"
+                   prop="deviceModel"
+                   border-bottom>
+        <u-input v-model="form.deviceModel"
+                 placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
+                 readonly
+                 clearable />
+      </u-form-item>
+      <u-form-item label="璁″垝淇濆吇鏃ユ湡"
+                   prop="maintenancePlanTime"
+                   required
+                   border-bottom>
+        <u-input v-model="form.maintenancePlanTime"
+                 placeholder="璇烽�夋嫨璁″垝淇濆吇鏃ユ湡"
+                 readonly
+                 @click="showDatePicker"
+                 clearable />
+        <template #right>
+          <u-icon name="arrow-right"
+                  @click="showDatePicker" />
+        </template>
+      </u-form-item>
+      <u-form-item label="淇濆吇浜�"
+                   prop="maintenancePerson"
+                   border-bottom>
+        <u-input v-model="form.maintenancePerson"
+                 placeholder="璇疯緭鍏ヤ繚鍏讳汉"
+                 clearable />
+      </u-form-item>
+      <u-form-item label="淇濆吇椤圭洰"
+                   prop="machineryCategory"
+                   border-bottom>
+        <u-input v-model="form.machineryCategory"
+                 placeholder="璇疯緭鍏ヤ繚鍏婚」鐩�"
+                 clearable />
+      </u-form-item>
+      <!-- 鎻愪氦鎸夐挳 -->
+      <view class="footer-btns">
+        <u-button class="cancel-btn"
+                  @click="goBack">鍙栨秷</u-button>
+        <u-button class="save-btn"
+                  @click="sendForm"
+                  :loading="loading">淇濆瓨</u-button>
+      </view>
+    </u-form>
+    <!-- 璁惧閫夋嫨鍣� -->
+    <up-action-sheet :show="showDevice"
+                     :actions="deviceActions"
+                     title="閫夋嫨璁惧"
+                     @select="onDeviceConfirm"
+                     @close="showDevice = false" />
+    <up-datetime-picker :show="showDate"
+                        v-model="pickerDateValue"
+                        @confirm="onDateConfirm"
+                        @cancel="showDate = false"
+                        mode="date" />
+  </view>
 </template>
 
 <script setup>
-import { ref, computed, onMounted, onUnmounted } from 'vue';
-import { onShow } from '@dcloudio/uni-app';
-import PageHeader from '@/components/PageHeader.vue';
-import { getDeviceLedger } from '@/api/equipmentManagement/ledger';
-import { addUpkeep, editUpkeep, getUpkeepById } from '@/api/equipmentManagement/upkeep';
-import dayjs from "dayjs";
-import { formatDateToYMD } from '@/utils/ruoyi';
+  import { ref, computed, onMounted, onUnmounted } from "vue";
+  import { onShow } from "@dcloudio/uni-app";
+  import PageHeader from "@/components/PageHeader.vue";
+  import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
+  import {
+    addUpkeep,
+    editUpkeep,
+    getUpkeepById,
+  } from "@/api/equipmentManagement/upkeep";
+  import dayjs from "dayjs";
+  import { formatDateToYMD } from "@/utils/ruoyi";
 
-defineOptions({
-	name: "璁惧淇濆吇璁″垝琛ㄥ崟",
-});
-const showToast = (message) => {
-  uni.showToast({
-    title: message,
-    icon: 'none'
-  })
-}
+  defineOptions({
+    name: "璁惧淇濆吇璁″垝琛ㄥ崟",
+  });
+  const showToast = message => {
+    uni.showToast({
+      title: message,
+      icon: "none",
+    });
+  };
 
-// 琛ㄥ崟寮曠敤
-const formRef = ref(null);
-const operationType = ref('add');
-const loading = ref(false);
-const showDevice = ref(false);
-const showDate = ref(false);
-const pickerDateValue = ref(Date.now());
-const currentDate = ref([new Date().getFullYear(), new Date().getMonth() + 1, new Date().getDate()]);
+  // 琛ㄥ崟寮曠敤
+  const formRef = ref(null);
+  const operationType = ref("add");
+  const loading = ref(false);
+  const showDevice = ref(false);
+  const showDate = ref(false);
+  const pickerDateValue = ref(Date.now());
+  const currentDate = ref([
+    new Date().getFullYear(),
+    new Date().getMonth() + 1,
+    new Date().getDate(),
+  ]);
 
-// 璁惧閫夐」
-const deviceOptions = ref([]);
-const deviceNameText = ref('');
-// 杞崲涓� action-sheet 闇�瑕佺殑鏍煎紡
-const deviceActions = computed(() => {
-	return deviceOptions.value.map(item => ({
-		text: item.deviceName,
-		value: item.id,
-		data: item
-	}));
-});
+  // 璁惧閫夐」
+  const deviceOptions = ref([]);
+  const deviceNameText = ref("");
+  // 杞崲涓� action-sheet 闇�瑕佺殑鏍煎紡
+  const deviceActions = computed(() => {
+    return deviceOptions.value.map(item => ({
+      text: item.deviceName,
+      value: item.id,
+      data: item,
+    }));
+  });
 
-// 鎵爜鐩稿叧鐘舵��
-const isScanning = ref(false);
-const scanTimer = ref(null);
+  // 鎵爜鐩稿叧鐘舵��
+  const isScanning = ref(false);
+  const scanTimer = ref(null);
 
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const formRules = {
-	deviceLedgerId: [{ required: true, trigger: "change", message: "璇烽�夋嫨璁惧鍚嶇О" }],
-	maintenancePlanTime: [{ required: true, trigger: "change", message: "璇烽�夋嫨璁″垝淇濆吇鏃ユ湡" }],
-};
+  // 琛ㄥ崟楠岃瘉瑙勫垯
+  const formRules = {
+    deviceLedgerId: [
+      { required: true, trigger: "change", message: "璇烽�夋嫨璁惧鍚嶇О" },
+    ],
+    maintenancePlanTime: [
+      { required: true, trigger: "change", message: "璇烽�夋嫨璁″垝淇濆吇鏃ユ湡" },
+    ],
+  };
 
-// 浣跨敤 ref 澹版槑琛ㄥ崟鏁版嵁
-const form = ref({
-	deviceLedgerId: undefined, // 璁惧ID
-	deviceModel: undefined, // 瑙勬牸鍨嬪彿
-	maintenancePlanTime: dayjs().format("YYYY-MM-DD"), // 璁″垝淇濆吇鏃ユ湡
-	maintenancePerson: undefined, // 淇濆吇浜�
-	maintenanceProject: undefined, // 淇濆吇椤圭洰
-});
+  // 浣跨敤 ref 澹版槑琛ㄥ崟鏁版嵁
+  const form = ref({
+    deviceLedgerId: undefined, // 璁惧ID
+    deviceModel: undefined, // 瑙勬牸鍨嬪彿
+    maintenancePlanTime: dayjs().format("YYYY-MM-DD"), // 璁″垝淇濆吇鏃ユ湡
+    maintenancePerson: undefined, // 淇濆吇浜�
+    machineryCategory: undefined, // 淇濆吇椤圭洰
+  });
 
-// 鍔犺浇璁惧鍒楄〃
-const loadDeviceName = async () => {
-	try {
-		const { data } = await getDeviceLedger();
-		deviceOptions.value = data || [];
-	} catch (e) {
-		showToast('鑾峰彇璁惧鍒楄〃澶辫触');
-	}
-};
+  // 鍔犺浇璁惧鍒楄〃
+  const loadDeviceName = async () => {
+    try {
+      const { data } = await getDeviceLedger();
+      deviceOptions.value = data || [];
+    } catch (e) {
+      showToast("鑾峰彇璁惧鍒楄〃澶辫触");
+    }
+  };
 
-// 鍔犺浇琛ㄥ崟鏁版嵁锛堢紪杈戞ā寮忥級
-const loadForm = async (id) => {
-	if (id) {
-		operationType.value = 'edit';
-		try {
-			const { code, data } = await getUpkeepById(id);
-			if (code == 200) {
-				form.value.deviceLedgerId = data.deviceLedgerId;
-			form.value.deviceModel = data.deviceModel;
-			form.value.maintenancePlanTime = dayjs(data.maintenancePlanTime).format("YYYY-MM-DD");
-			form.value.maintenancePerson = data.maintenancePerson;
-			form.value.maintenanceProject = data.maintenanceProject;
-			// 璁剧疆璁惧鍚嶇О鏄剧ず
-			const device = deviceOptions.value.find(item => item.id === data.deviceLedgerId);
-			if (device) {
-				form.value.deviceNameText = device.deviceName;
-			}
-			}
-		} catch (e) {
-			showToast('鑾峰彇璇︽儏澶辫触');
-		}
-	} else {
-		// 鏂板妯″紡
-		operationType.value = 'add';
-	}
-};
+  // 鍔犺浇琛ㄥ崟鏁版嵁锛堢紪杈戞ā寮忥級
+  const loadForm = async id => {
+    if (id) {
+      operationType.value = "edit";
+      try {
+        const { code, data } = await getUpkeepById(id);
+        if (code == 200) {
+          form.value.deviceLedgerId = data.deviceLedgerId;
+          form.value.deviceModel = data.deviceModel;
+          form.value.maintenancePlanTime = dayjs(data.maintenancePlanTime).format(
+            "YYYY-MM-DD"
+          );
+          form.value.maintenancePerson = data.maintenancePerson;
+          form.value.machineryCategory = data.machineryCategory;
+          // 璁剧疆璁惧鍚嶇О鏄剧ず
+          const device = deviceOptions.value.find(
+            item => item.id === data.deviceLedgerId
+          );
+          if (device) {
+            form.value.deviceNameText = device.deviceName;
+          }
+        }
+      } catch (e) {
+        showToast("鑾峰彇璇︽儏澶辫触");
+      }
+    } else {
+      // 鏂板妯″紡
+      operationType.value = "add";
+    }
+  };
 
-// 鎵弿浜岀淮鐮佸姛鑳�
-const startScan = () => {
-	if (isScanning.value) {
-		showToast('姝e湪鎵弿涓紝璇风◢鍊�...');
-		return;
-	}
-	
-	// 璋冪敤uni-app鐨勬壂鐮丄PI
-	uni.scanCode({
-		scanType: ['qrCode', 'barCode'],
-		success: (res) => {
-			handleScanResult(res.result);
-		},
-		fail: (err) => {
-			console.error('鎵爜澶辫触:', err);
-			showToast('鎵爜澶辫触锛岃閲嶈瘯');
-		}
-	});
-};
+  // 鎵弿浜岀淮鐮佸姛鑳�
+  const startScan = () => {
+    if (isScanning.value) {
+      showToast("姝e湪鎵弿涓紝璇风◢鍊�...");
+      return;
+    }
 
-// 澶勭悊鎵爜缁撴灉
-const handleScanResult = (scanResult) => {
-	if (!scanResult) {
-		showToast('鎵爜缁撴灉涓虹┖');
-		return;
-	}
-	
-	isScanning.value = true;
-	showToast('鎵爜鎴愬姛');
-	
-	// 3绉掑悗澶勭悊鎵爜缁撴灉
-	scanTimer.value = setTimeout(() => {
-		processScanResult(scanResult);
-		isScanning.value = false;
-	}, 1000);
-};
-function getDeviceIdByRegExp(url) {
-	// 鍖归厤deviceId=鍚庨潰鐨勬暟瀛�
-	const reg = /deviceId=(\d+)/;
-	const match = url.match(reg);
-	// 濡傛灉鍖归厤鍒扮粨鏋滐紝杩斿洖鏁板瓧绫诲瀷锛屽惁鍒欒繑鍥瀗ull
-	return match ? Number(match[1]) : null;
-}
-// 澶勭悊鎵爜缁撴灉骞跺尮閰嶈澶�
-const processScanResult = (scanResult) => {
-	const deviceId = getDeviceIdByRegExp(scanResult);
-	const matchedDevice = deviceOptions.value.find(item => item.id == deviceId);
-	
-	if (matchedDevice) {
-		// 鎵惧埌鍖归厤鐨勮澶囷紝鑷姩濉厖
-		form.value.deviceLedgerId = matchedDevice.id;
-		form.value.deviceNameText = matchedDevice.deviceName;
-		form.value.deviceModel = matchedDevice.deviceModel;
-		showToast('璁惧淇℃伅宸茶嚜鍔ㄥ~鍏�');
-	} else {
-		// 鏈壘鍒板尮閰嶇殑璁惧
-		showToast('鏈壘鍒板尮閰嶇殑璁惧锛岃鎵嬪姩閫夋嫨');
-	}
-};
+    // 璋冪敤uni-app鐨勬壂鐮丄PI
+    uni.scanCode({
+      scanType: ["qrCode", "barCode"],
+      success: res => {
+        handleScanResult(res.result);
+      },
+      fail: err => {
+        console.error("鎵爜澶辫触:", err);
+        showToast("鎵爜澶辫触锛岃閲嶈瘯");
+      },
+    });
+  };
 
-// 鏄剧ず璁惧閫夋嫨鍣�
-const showDevicePicker = () => {
-	showDevice.value = true;
-};
+  // 澶勭悊鎵爜缁撴灉
+  const handleScanResult = scanResult => {
+    if (!scanResult) {
+      showToast("鎵爜缁撴灉涓虹┖");
+      return;
+    }
 
-// 纭璁惧閫夋嫨
-const onDeviceConfirm = (selected) => {
-	// selected 杩斿洖鐨勬槸閫変腑椤�
-	form.value.deviceLedgerId = selected.value;
-		form.value.deviceNameText = selected.name;
-	const selectedDevice = deviceOptions.value.find(item => item.id === selected.value);
-	if (selectedDevice) {
-		form.value.deviceModel = selectedDevice.deviceModel;
-	}
-	showDevice.value = false;
-};
+    isScanning.value = true;
+    showToast("鎵爜鎴愬姛");
 
-// 鏄剧ず鏃ユ湡閫夋嫨鍣�
-const showDatePicker = () => {
-	showDate.value = true;
-};
+    // 3绉掑悗澶勭悊鎵爜缁撴灉
+    scanTimer.value = setTimeout(() => {
+      processScanResult(scanResult);
+      isScanning.value = false;
+    }, 1000);
+  };
+  function getDeviceIdByRegExp(url) {
+    // 鍖归厤deviceId=鍚庨潰鐨勬暟瀛�
+    const reg = /deviceId=(\d+)/;
+    const match = url.match(reg);
+    // 濡傛灉鍖归厤鍒扮粨鏋滐紝杩斿洖鏁板瓧绫诲瀷锛屽惁鍒欒繑鍥瀗ull
+    return match ? Number(match[1]) : null;
+  }
+  // 澶勭悊鎵爜缁撴灉骞跺尮閰嶈澶�
+  const processScanResult = scanResult => {
+    const deviceId = getDeviceIdByRegExp(scanResult);
+    const matchedDevice = deviceOptions.value.find(item => item.id == deviceId);
 
-// 纭鏃ユ湡閫夋嫨
-const onDateConfirm = (e) => {
-	form.value.maintenancePlanTime = formatDateToYMD(e.value);
-	showDate.value = false;
-};
+    if (matchedDevice) {
+      // 鎵惧埌鍖归厤鐨勮澶囷紝鑷姩濉厖
+      form.value.deviceLedgerId = matchedDevice.id;
+      form.value.deviceNameText = matchedDevice.deviceName;
+      form.value.deviceModel = matchedDevice.deviceModel;
+      showToast("璁惧淇℃伅宸茶嚜鍔ㄥ~鍏�");
+    } else {
+      // 鏈壘鍒板尮閰嶇殑璁惧
+      showToast("鏈壘鍒板尮閰嶇殑璁惧锛岃鎵嬪姩閫夋嫨");
+    }
+  };
 
-onShow(() => {
-	// 椤甸潰鏄剧ず鏃惰幏鍙栧弬鏁�
-	getPageParams();
-});
+  // 鏄剧ず璁惧閫夋嫨鍣�
+  const showDevicePicker = () => {
+    showDevice.value = true;
+  };
 
-onMounted(() => {
-	// 椤甸潰鍔犺浇鏃惰幏鍙栬澶囧垪琛ㄥ拰鍙傛暟
-	loadDeviceName();
-	getPageParams();
-});
+  // 纭璁惧閫夋嫨
+  const onDeviceConfirm = selected => {
+    // selected 杩斿洖鐨勬槸閫変腑椤�
+    form.value.deviceLedgerId = selected.value;
+    form.value.deviceNameText = selected.name;
+    const selectedDevice = deviceOptions.value.find(
+      item => item.id === selected.value
+    );
+    if (selectedDevice) {
+      form.value.deviceModel = selectedDevice.deviceModel;
+    }
+    showDevice.value = false;
+  };
 
-// 缁勪欢鍗歌浇鏃舵竻鐞嗗畾鏃跺櫒
-onUnmounted(() => {
-	if (scanTimer.value) {
-		clearTimeout(scanTimer.value);
-	}
-});
+  // 鏄剧ず鏃ユ湡閫夋嫨鍣�
+  const showDatePicker = () => {
+    showDate.value = true;
+  };
 
-// 鎻愪氦琛ㄥ崟
-const sendForm = async () => {
-	try {
-		// 鎵嬪姩楠岃瘉琛ㄥ崟
-		const valid = await formRef.value.validate();
-		if (!valid) return;
-		
-		loading.value = true;
-		const id = getPageId();
-		
-		// 鍑嗗鎻愪氦鏁版嵁
-		const submitData = { ...form.value };
-		// 纭繚鏃ユ湡鏍煎紡姝g‘
-		if (submitData.maintenancePlanTime && !submitData.maintenancePlanTime.includes(':')) {
-			submitData.maintenancePlanTime = submitData.maintenancePlanTime + ' 00:00:00';
-		}
-		
-		const { code } = id
-			? await editUpkeep({ id: id, ...submitData })
-			: await addUpkeep(submitData);
-		
-		if (code == 200) {
-			showToast(`${id ? "缂栬緫" : "鏂板"}璁″垝鎴愬姛`);
-			setTimeout(() => {
-				uni.navigateBack();
-			}, 1500);
-		} else {
-			loading.value = false;
-		}
-	} catch (e) {
-		loading.value = false;
-		showToast('琛ㄥ崟楠岃瘉澶辫触');
-	}
-};
+  // 纭鏃ユ湡閫夋嫨
+  const onDateConfirm = e => {
+    form.value.maintenancePlanTime = formatDateToYMD(e.value);
+    showDate.value = false;
+  };
 
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
-	// 娓呴櫎瀛樺偍鐨刬d
-	uni.removeStorageSync('repairId');
-	uni.navigateBack();
-};
+  onShow(() => {
+    // 椤甸潰鏄剧ず鏃惰幏鍙栧弬鏁�
+    getPageParams();
+  });
 
-// 鑾峰彇椤甸潰鍙傛暟
-const getPageParams = () => {
-	// 浠庢湰鍦板瓨鍌ㄨ幏鍙杋d
-	const id = uni.getStorageSync('repairId');
-	
-	// 鏍规嵁鏄惁鏈塱d鍙傛暟鏉ュ垽鏂槸鏂板杩樻槸缂栬緫
-	if (id) {
-		// 缂栬緫妯″紡锛岃幏鍙栬鎯�
-		loadForm(id);
-	} else {
-		// 鏂板妯″紡
-		loadForm();
-	}
-};
+  onMounted(() => {
+    // 椤甸潰鍔犺浇鏃惰幏鍙栬澶囧垪琛ㄥ拰鍙傛暟
+    loadDeviceName();
+    getPageParams();
+  });
 
-// 鑾峰彇椤甸潰ID
-const getPageId = () => {
-	// 浠庢湰鍦板瓨鍌ㄨ幏鍙杋d
-	return uni.getStorageSync('repairId');
-};
+  // 缁勪欢鍗歌浇鏃舵竻鐞嗗畾鏃跺櫒
+  onUnmounted(() => {
+    if (scanTimer.value) {
+      clearTimeout(scanTimer.value);
+    }
+  });
+
+  // 鎻愪氦琛ㄥ崟
+  const sendForm = async () => {
+    try {
+      // 鎵嬪姩楠岃瘉琛ㄥ崟
+      const valid = await formRef.value.validate();
+      if (!valid) return;
+
+      loading.value = true;
+      const id = getPageId();
+
+      // 鍑嗗鎻愪氦鏁版嵁
+      const submitData = { ...form.value };
+      // 纭繚鏃ユ湡鏍煎紡姝g‘
+      if (
+        submitData.maintenancePlanTime &&
+        !submitData.maintenancePlanTime.includes(":")
+      ) {
+        submitData.maintenancePlanTime =
+          submitData.maintenancePlanTime + " 00:00:00";
+      }
+
+      const { code } = id
+        ? await editUpkeep({ id: id, ...submitData })
+        : await addUpkeep(submitData);
+
+      if (code == 200) {
+        showToast(`${id ? "缂栬緫" : "鏂板"}璁″垝鎴愬姛`);
+        setTimeout(() => {
+          uni.navigateBack();
+        }, 1500);
+      } else {
+        loading.value = false;
+      }
+    } catch (e) {
+      loading.value = false;
+      showToast("琛ㄥ崟楠岃瘉澶辫触");
+    }
+  };
+
+  // 杩斿洖涓婁竴椤�
+  const goBack = () => {
+    // 娓呴櫎瀛樺偍鐨刬d
+    uni.removeStorageSync("repairId");
+    uni.navigateBack();
+  };
+
+  // 鑾峰彇椤甸潰鍙傛暟
+  const getPageParams = () => {
+    // 浠庢湰鍦板瓨鍌ㄨ幏鍙杋d
+    const id = uni.getStorageSync("repairId");
+
+    // 鏍规嵁鏄惁鏈塱d鍙傛暟鏉ュ垽鏂槸鏂板杩樻槸缂栬緫
+    if (id) {
+      // 缂栬緫妯″紡锛岃幏鍙栬鎯�
+      loadForm(id);
+    } else {
+      // 鏂板妯″紡
+      loadForm();
+    }
+  };
+
+  // 鑾峰彇椤甸潰ID
+  const getPageId = () => {
+    // 浠庢湰鍦板瓨鍌ㄨ幏鍙杋d
+    return uni.getStorageSync("repairId");
+  };
 </script>
 
 <style scoped lang="scss">
-@import '@/static/scss/form-common.scss';
-.upkeep-add {
-	min-height: 100vh;
-	background: #f8f9fa;
-	padding-bottom: 5rem;
-}
+  @import "@/static/scss/form-common.scss";
+  .upkeep-add {
+    min-height: 100vh;
+    background: #f8f9fa;
+    padding-bottom: 5rem;
+  }
 
-.footer-btns {
-	position: fixed;
-	left: 0;
-	right: 0;
-	bottom: 0;
-	background: #fff;
-	display: flex;
-	justify-content: space-around;
-	align-items: center;
-	padding: 0.75rem 0;
-	box-shadow: 0 -0.125rem 0.5rem rgba(0,0,0,0.05);
-	z-index: 1000;
-}
+  .footer-btns {
+    position: fixed;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background: #fff;
+    display: flex;
+    justify-content: space-around;
+    align-items: center;
+    padding: 0.75rem 0;
+    box-shadow: 0 -0.125rem 0.5rem rgba(0, 0, 0, 0.05);
+    z-index: 1000;
+  }
 
-.cancel-btn {
-	font-weight: 400;
-	font-size: 1rem;
-	color: #FFFFFF;
-	width: 6.375rem;
-	background: #C7C9CC;
-	box-shadow: 0 0.25rem 0.625rem 0 rgba(3,88,185,0.2);
-	border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
-}
+  .cancel-btn {
+    font-weight: 400;
+    font-size: 1rem;
+    color: #ffffff;
+    width: 6.375rem;
+    background: #c7c9cc;
+    box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
+    border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+  }
 
-.save-btn {
-	font-weight: 400;
-	font-size: 1rem;
-	color: #FFFFFF;
-	width: 14rem;
-	background: linear-gradient( 140deg, #00BAFF 0%, #006CFB 100%);
-	box-shadow: 0 0.25rem 0.625rem 0 rgba(3,88,185,0.2);
-	border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
-}
+  .save-btn {
+    font-weight: 400;
+    font-size: 1rem;
+    color: #ffffff;
+    width: 14rem;
+    background: linear-gradient(140deg, #00baff 0%, #006cfb 100%);
+    box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
+    border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+  }
 
-// 鍝嶅簲寮忚皟鏁�
-@media (max-width: 768px) {
-	.submit-section {
-		padding: 12px;
-	}
-}
+  // 鍝嶅簲寮忚皟鏁�
+  @media (max-width: 768px) {
+    .submit-section {
+      padding: 12px;
+    }
+  }
 
-.tip-text { 
-	padding: 4px 16px 0 16px; 
-	font-size: 12px; 
-	color: #888; 
-}
+  .tip-text {
+    padding: 4px 16px 0 16px;
+    font-size: 12px;
+    color: #888;
+  }
 
-.scan-icon {
-	color: #1989fa;
-	font-size: 18px;
-	margin-left: 8px;
-	cursor: pointer;
-}
+  .scan-icon {
+    color: #1989fa;
+    font-size: 18px;
+    margin-left: 8px;
+    cursor: pointer;
+  }
 </style>
\ No newline at end of file
diff --git a/src/pages/equipmentManagement/upkeep/index.vue b/src/pages/equipmentManagement/upkeep/index.vue
index 8646554..a9ecd0c 100644
--- a/src/pages/equipmentManagement/upkeep/index.vue
+++ b/src/pages/equipmentManagement/upkeep/index.vue
@@ -68,7 +68,7 @@
             </view>
             <view class="detail-row">
               <text class="detail-label">淇濆吇椤圭洰</text>
-              <text class="detail-value">{{ item.maintenanceProject || '-' }}</text>
+              <text class="detail-value">{{ item.machineryCategory || '-' }}</text>
             </view>
             <view class="detail-row">
               <text class="detail-label">瀹為檯淇濆吇浜�</text>
diff --git a/src/pages/inventoryManagement/stockManagement/Qualified.vue b/src/pages/inventoryManagement/stockManagement/Qualified.vue
deleted file mode 100644
index 12b9060..0000000
--- a/src/pages/inventoryManagement/stockManagement/Qualified.vue
+++ /dev/null
@@ -1,151 +0,0 @@
-<template>
-  <view class="qualified-record-container">
-    <view class="search-section">
-      <view class="search-bar">
-        <view class="search-input">
-          <up-input
-            class="search-text"
-            placeholder="璇疯緭鍏ヤ骇鍝佸ぇ绫�"
-            v-model="searchForm.productName"
-            @confirm="handleQuery"
-            clearable
-          />
-        </view>
-        <view class="filter-button" @click="handleQuery">
-          <up-icon name="search" size="24" color="#999"></up-icon>
-        </view>
-      </view>
-    </view>
-
-    <scroll-view scroll-y class="ledger-list" v-if="tableData.length > 0" @scrolltolower="loadMore">
-      <view v-for="item in tableData" :key="item.id" class="ledger-item" :class="{ 'low-stock': isLowStock(item) }">
-        <view class="item-header">
-          <view class="item-left">
-            <view class="document-icon">
-              <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
-            </view>
-            <text class="item-id">{{ item.productName }}</text>
-          </view>
-          <view class="item-right">
-            <text class="item-tag tag-type">鍚堟牸搴撳瓨</text>
-          </view>
-        </view>
-        
-        <up-divider></up-divider>
-
-        <view class="item-details">
-          <view class="detail-row">
-            <text class="detail-label">瑙勬牸鍨嬪彿</text>
-            <text class="detail-value">{{ item.model }}</text>
-          </view>
-          <view class="detail-row">
-            <text class="detail-label">搴撳瓨鏁伴噺</text>
-            <text class="detail-value">{{ item.qualitity }} {{ item.unit }}</text>
-          </view>
-          <view class="detail-row">
-            <text class="detail-label">閿佸畾/鍐荤粨</text>
-            <text class="detail-value">{{ item.lockedQuantity }} {{ item.unit }}</text>
-          </view>
-          <view class="detail-row">
-            <text class="detail-label">鍙敤搴撳瓨</text>
-            <text class="detail-value" style="color: #2979ff; font-weight: bold;">{{ item.unLockedQuantity }} {{ item.unit }}</text>
-          </view>
-          <view class="detail-row">
-            <text class="detail-label">搴撳瓨棰勮</text>
-            <text class="detail-value">{{ item.warnNum }}</text>
-          </view>
-          <view class="detail-row">
-            <text class="detail-label">鏇存柊鏃堕棿</text>
-            <text class="detail-value">{{ item.updateTime }}</text>
-          </view>
-        </view>
-      </view>
-      <up-loadmore :status="loadStatus" />
-    </scroll-view>
-    <view v-else-if="!loading" class="no-data">
-      <up-empty mode="data" text="鏆傛棤搴撳瓨鏁版嵁"></up-empty>
-    </view>
-  </view>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted } from 'vue';
-import { getStockInventoryListPage } from "@/api/inventoryManagement/stockInventory.js";
-
-const tableData = ref([]);
-const loading = ref(false);
-const loadStatus = ref('loadmore');
-const page = reactive({ current: 1, size: 10 });
-const total = ref(0);
-const searchForm = reactive({ productName: '' });
-
-const handleQuery = () => {
-  page.current = 1;
-  tableData.value = [];
-  getList();
-};
-
-const getList = () => {
-  if (loading.value) return;
-  loading.value = true;
-  loadStatus.value = 'loading';
-  getStockInventoryListPage({ ...searchForm, ...page, type: 'qualified' }).then(res => {
-    loading.value = false;
-    const records = res.data.records || [];
-    tableData.value = page.current === 1 ? records : [...tableData.value, ...records];
-    total.value = res.data.total;
-    loadStatus.value = tableData.value.length >= total.value ? 'nomore' : 'loadmore';
-  }).catch(() => {
-    loading.value = false;
-    loadStatus.value = 'loadmore';
-  });
-};
-
-const loadMore = () => {
-  if (loadStatus.value === 'nomore' || loading.value) return;
-  page.current++;
-  getList();
-};
-
-const isLowStock = (row) => {
-  const stock = Number(row?.unLockedQuantity ?? 0);
-  const warn = Number(row?.warnNum ?? 0);
-  return Number.isFinite(stock) && Number.isFinite(warn) && stock < warn;
-};
-
-onMounted(() => {
-  getList();
-});
-</script>
-
-<style scoped lang="scss">
-@import '@/styles/sales-common.scss';
-
-.qualified-record-container {
-  height: 100%;
-  display: flex;
-  flex-direction: column;
-}
-
-.tag-type {
-  background-color: #e3f2fd;
-  color: #2196f3;
-  padding: 2px 8px;
-  border-radius: 4px;
-  font-size: 12px;
-}
-
-.ledger-list {
-  flex: 1;
-  overflow-y: auto;
-}
-
-.low-stock {
-  background-color: #fde2e2;
-  color: #c45656;
-}
-
-.no-data {
-  padding-top: 100px;
-}
-</style>
diff --git a/src/pages/inventoryManagement/stockManagement/Record.vue b/src/pages/inventoryManagement/stockManagement/Record.vue
new file mode 100644
index 0000000..e4542a8
--- /dev/null
+++ b/src/pages/inventoryManagement/stockManagement/Record.vue
@@ -0,0 +1,292 @@
+<template>
+  <view class="record-container">
+    <view class="search-section">
+      <view class="search-bar">
+        <view class="search-input">
+          <up-input
+            class="search-text"
+            placeholder="璇疯緭鍏ヤ骇鍝佸ぇ绫�"
+            v-model="searchForm.productName"
+            @confirm="handleQuery"
+            clearable
+          />
+        </view>
+        <view class="filter-button" @click="handleQuery">
+          <up-icon name="search" size="24" color="#999"></up-icon>
+        </view>
+      </view>
+    </view>
+
+    <scroll-view scroll-y class="ledger-list" v-if="tableData.length > 0" @scrolltolower="loadMore">
+      <view v-for="item in tableData" :key="item.id" class="ledger-item">
+        <view class="item-header">
+          <view class="item-left">
+            <view class="document-icon">
+              <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
+            </view>
+            <text class="item-id">{{ item.productName }}</text>
+          </view>
+        </view>
+        
+        <up-divider></up-divider>
+
+        <view class="item-details">
+          <view class="detail-row">
+            <text class="detail-label">瑙勬牸鍨嬪彿</text>
+            <text class="detail-value">{{ item.model }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="detail-label">鍗曚綅</text>
+            <text class="detail-value">{{ item.unit }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="detail-label">鎵瑰彿</text>
+            <text class="detail-value">{{ item.batchNo }}</text>
+          </view>
+          
+          <view class="quantity-section">
+            <view class="quantity-box qualified">
+              <text class="q-label">鍚堟牸搴撳瓨</text>
+              <text class="q-value">{{ item.qualifiedQuantity }}</text>
+            </view>
+            <view class="quantity-box unqualified">
+              <text class="q-label">涓嶅悎鏍煎簱瀛�</text>
+              <text class="q-value">{{ item.unQualifiedQuantity }}</text>
+            </view>
+          </view>
+
+          <view class="quantity-section">
+            <view class="quantity-box locked">
+              <text class="q-label">鍚堟牸鍐荤粨</text>
+              <text class="q-value">{{ item.qualifiedLockedQuantity }}</text>
+            </view>
+            <view class="quantity-box locked">
+              <text class="q-label">涓嶅悎鏍煎喕缁�</text>
+              <text class="q-value">{{ item.unQualifiedLockedQuantity }}</text>
+            </view>
+          </view>
+
+          <view class="detail-row">
+            <text class="detail-label">搴撳瓨棰勮</text>
+            <text class="detail-value">{{ item.warnNum }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="detail-label">澶囨敞</text>
+            <text class="detail-value">{{ item.remark || '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="detail-label">鏇存柊鏃堕棿</text>
+            <text class="detail-value">{{ item.updateTime }}</text>
+          </view>
+        </view>
+      </view>
+      <up-loadmore :status="loadStatus" />
+    </scroll-view>
+    <view v-else-if="!loading" class="no-data">
+      <up-empty mode="data" text="鏆傛棤搴撳瓨鏁版嵁"></up-empty>
+    </view>
+  </view>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from 'vue';
+import { getStockInventoryListPageCombined } from "@/api/inventoryManagement/stockInventory.js";
+
+const props = defineProps({
+  productId: {
+    type: Number,
+    required: true
+  }
+});
+
+const tableData = ref([]);
+const loading = ref(false);
+const loadStatus = ref('loadmore');
+const page = reactive({ current: 1, size: 10 });
+const total = ref(0);
+const searchForm = reactive({ 
+  productName: '',
+  topParentProductId: props.productId
+});
+
+const handleQuery = () => {
+  page.current = 1;
+  tableData.value = [];
+  getList();
+};
+
+const getList = () => {
+  if (loading.value) return;
+  loading.value = true;
+  loadStatus.value = 'loading';
+  
+  getStockInventoryListPageCombined({ 
+    ...searchForm, 
+    current: page.current,
+    size: page.size
+  }).then(res => {
+    loading.value = false;
+    const records = res.data.records || [];
+    tableData.value = page.current === 1 ? records : [...tableData.value, ...records];
+    total.value = res.data.total;
+    loadStatus.value = tableData.value.length >= total.value ? 'nomore' : 'loadmore';
+  }).catch(() => {
+    loading.value = false;
+    loadStatus.value = 'loadmore';
+  });
+};
+
+const loadMore = () => {
+  if (loadStatus.value === 'loadmore') {
+    page.current++;
+    getList();
+  }
+};
+
+onMounted(() => {
+  getList();
+});
+</script>
+
+<style scoped lang="scss">
+.record-container {
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  background-color: #f5f7fa;
+}
+
+.search-section {
+  padding: 20rpx;
+  background-color: #ffffff;
+  position: sticky;
+  top: 0;
+  z-index: 10;
+}
+
+.search-bar {
+  display: flex;
+  align-items: center;
+  background-color: #f2f2f2;
+  border-radius: 40rpx;
+  padding: 0 30rpx;
+  height: 80rpx;
+}
+
+.search-input {
+  flex: 1;
+}
+
+.search-text {
+  font-size: 28rpx;
+}
+
+.filter-button {
+  padding-left: 20rpx;
+}
+
+.ledger-list {
+  flex: 1;
+  padding: 20rpx;
+  box-sizing: border-box;
+}
+
+.ledger-item {
+  background-color: #ffffff;
+  border-radius: 16rpx;
+  padding: 30rpx;
+  margin-bottom: 20rpx;
+  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
+}
+
+.item-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20rpx;
+}
+
+.item-left {
+  display: flex;
+  align-items: center;
+}
+
+.document-icon {
+  width: 40rpx;
+  height: 40rpx;
+  background: linear-gradient(135deg, #2979ff, #1565c0);
+  border-radius: 8rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-right: 16rpx;
+}
+
+.item-id {
+  font-size: 30rpx;
+  font-weight: bold;
+  color: #303133;
+}
+
+.item-details {
+  .detail-row {
+    display: flex;
+    justify-content: space-between;
+    margin-bottom: 16rpx;
+    font-size: 26rpx;
+
+    .detail-label {
+      color: #909399;
+    }
+
+    .detail-value {
+      color: #303133;
+      font-weight: 500;
+    }
+  }
+}
+
+.quantity-section {
+  display: flex;
+  gap: 20rpx;
+  margin: 20rpx 0;
+  
+  .quantity-box {
+    flex: 1;
+    padding: 16rpx;
+    border-radius: 8rpx;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    
+    .q-label {
+      font-size: 22rpx;
+      margin-bottom: 8rpx;
+    }
+    
+    .q-value {
+      font-size: 32rpx;
+      font-weight: bold;
+    }
+    
+    &.qualified {
+      background-color: #ecf5ff;
+      color: #409eff;
+    }
+    
+    &.unqualified {
+      background-color: #fef0f0;
+      color: #f56c6c;
+    }
+    
+    &.locked {
+      background-color: #f4f4f5;
+      color: #909399;
+    }
+  }
+}
+
+.no-data {
+  padding-top: 200rpx;
+}
+</style>
diff --git a/src/pages/inventoryManagement/stockManagement/Unqualified.vue b/src/pages/inventoryManagement/stockManagement/Unqualified.vue
deleted file mode 100644
index 48dafc4..0000000
--- a/src/pages/inventoryManagement/stockManagement/Unqualified.vue
+++ /dev/null
@@ -1,134 +0,0 @@
-<template>
-  <view class="unqualified-record-container">
-    <view class="search-section">
-      <view class="search-bar">
-        <view class="search-input">
-          <up-input
-            class="search-text"
-            placeholder="璇疯緭鍏ヤ骇鍝佸ぇ绫�"
-            v-model="searchForm.productName"
-            @confirm="handleQuery"
-            clearable
-          />
-        </view>
-        <view class="filter-button" @click="handleQuery">
-          <up-icon name="search" size="24" color="#999"></up-icon>
-        </view>
-      </view>
-    </view>
-
-    <scroll-view scroll-y class="ledger-list" v-if="tableData.length > 0" @scrolltolower="loadMore">
-      <view v-for="item in tableData" :key="item.id" class="ledger-item">
-        <view class="item-header">
-          <view class="item-left">
-            <view class="document-icon">
-              <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
-            </view>
-            <text class="item-id">{{ item.productName }}</text>
-          </view>
-          <view class="item-right">
-            <text class="item-tag tag-type" style="background-color: #fde2e2; color: #f56c6c;">涓嶅悎鏍煎簱瀛�</text>
-          </view>
-        </view>
-        
-        <up-divider></up-divider>
-
-        <view class="item-details">
-          <view class="detail-row">
-            <text class="detail-label">瑙勬牸鍨嬪彿</text>
-            <text class="detail-value">{{ item.model }}</text>
-          </view>
-          <view class="detail-row">
-            <text class="detail-label">搴撳瓨鏁伴噺</text>
-            <text class="detail-value">{{ item.qualitity }} {{ item.unit }}</text>
-          </view>
-          <view class="detail-row">
-            <text class="detail-label">閿佸畾/鍐荤粨</text>
-            <text class="detail-value">{{ item.lockedQuantity }} {{ item.unit }}</text>
-          </view>
-          <view class="detail-row">
-            <text class="detail-label">鍙敤搴撳瓨</text>
-            <text class="detail-value" style="color: #f56c6c; font-weight: bold;">{{ item.unLockedQuantity }} {{ item.unit }}</text>
-          </view>
-          <view class="detail-row">
-            <text class="detail-label">鏇存柊鏃堕棿</text>
-            <text class="detail-value">{{ item.updateTime }}</text>
-          </view>
-        </view>
-      </view>
-      <up-loadmore :status="loadStatus" />
-    </scroll-view>
-    <view v-else-if="!loading" class="no-data">
-      <up-empty mode="data" text="鏆傛棤涓嶅悎鏍煎簱瀛樻暟鎹�"></up-empty>
-    </view>
-  </view>
-</template>
-
-<script setup>
-import { ref, reactive, onMounted } from 'vue';
-import { getStockUninventoryListPage } from "@/api/inventoryManagement/stockUninventory.js";
-
-const tableData = ref([]);
-const loading = ref(false);
-const loadStatus = ref('loadmore');
-const page = reactive({ current: 1, size: 10 });
-const total = ref(0);
-const searchForm = reactive({ productName: '' });
-
-const handleQuery = () => {
-  page.current = 1;
-  tableData.value = [];
-  getList();
-};
-
-const getList = () => {
-  if (loading.value) return;
-  loading.value = true;
-  loadStatus.value = 'loading';
-  getStockUninventoryListPage({ ...searchForm, ...page, type: 'unqualified' }).then(res => {
-    loading.value = false;
-    const records = res.data.records || [];
-    tableData.value = page.current === 1 ? records : [...tableData.value, ...records];
-    total.value = res.data.total;
-    loadStatus.value = tableData.value.length >= total.value ? 'nomore' : 'loadmore';
-  }).catch(() => {
-    loading.value = false;
-    loadStatus.value = 'loadmore';
-  });
-};
-
-const loadMore = () => {
-  if (loadStatus.value === 'nomore' || loading.value) return;
-  page.current++;
-  getList();
-};
-
-onMounted(() => {
-  getList();
-});
-</script>
-
-<style scoped lang="scss">
-@import '@/styles/sales-common.scss';
-
-.unqualified-record-container {
-  height: 100%;
-  display: flex;
-  flex-direction: column;
-}
-
-.tag-type {
-  padding: 2px 8px;
-  border-radius: 4px;
-  font-size: 12px;
-}
-
-.ledger-list {
-  flex: 1;
-  overflow-y: auto;
-}
-
-.no-data {
-  padding-top: 100px;
-}
-</style>
diff --git a/src/pages/inventoryManagement/stockManagement/index.vue b/src/pages/inventoryManagement/stockManagement/index.vue
index 98ebf44..45d27ad 100644
--- a/src/pages/inventoryManagement/stockManagement/index.vue
+++ b/src/pages/inventoryManagement/stockManagement/index.vue
@@ -1,57 +1,104 @@
 <template>
   <view class="app-container">
-    <PageHeader title="搴撳瓨绠$悊" @back="goBack" />
-    <up-tabs :list="tabs" @click="handleTabClick" :current="activeTab"/>
-    <swiper class="swiper-box" :current="activeTab" @change="handleSwiperChange">
-      <swiper-item class="swiper-item">
-        <qualified-record />
-      </swiper-item>
-      <swiper-item class="swiper-item">
-        <unqualified-record />
-      </swiper-item>
-    </swiper>
+    <PageHeader title="搴撳瓨绠$悊"
+                @back="goBack" />
+    <view v-if="loading"
+          class="loading-state">
+      <up-loading-icon text="鍔犺浇涓�..."></up-loading-icon>
+    </view>
+    <template v-else>
+      <up-tabs :list="tabs"
+               @click="handleTabClick"
+               :current="activeTab" />
+      <swiper class="swiper-box"
+              :current="activeTab"
+              @change="handleSwiperChange">
+        <swiper-item class="swiper-item"
+                     v-for="tab in products"
+                     :key="tab.id">
+          <record :product-id="tab.id"
+                  v-if="activeTab === products.indexOf(tab) || initializedTabs.includes(tab.id)" />
+        </swiper-item>
+      </swiper>
+    </template>
   </view>
 </template>
 
 <script setup>
-import { ref } from 'vue';
-import PageHeader from "@/components/PageHeader.vue";
-import QualifiedRecord from "./Qualified.vue";
-import UnqualifiedRecord from "./Unqualified.vue";
+  import { ref, onMounted } from "vue";
+  import PageHeader from "@/components/PageHeader.vue";
+  import Record from "./Record.vue";
+  import { productTreeList } from "@/api/basicData/product.js";
 
-const activeTab = ref(0);
-const tabs = ref([
-  { name: '鍚堟牸搴撳瓨' },
-  { name: '涓嶅悎鏍煎簱瀛�' }
-]);
+  const activeTab = ref(0);
+  const tabs = ref([]);
+  const products = ref([]);
+  const loading = ref(false);
+  const initializedTabs = ref([]);
 
-const handleTabClick = (item) => {
-  activeTab.value = item.index;
-};
+  const handleTabClick = item => {
+    activeTab.value = item.index;
+    if (!initializedTabs.value.includes(products.value[item.index].id)) {
+      initializedTabs.value.push(products.value[item.index].id);
+    }
+  };
 
-const handleSwiperChange = (e) => {
-  activeTab.value = e.detail.current;
-};
+  const handleSwiperChange = e => {
+    const index = e.detail.current;
+    activeTab.value = index;
+    if (!initializedTabs.value.includes(products.value[index].id)) {
+      initializedTabs.value.push(products.value[index].id);
+    }
+  };
 
-const goBack = () => {
-  uni.navigateBack();
-};
+  const fetchProducts = async () => {
+    loading.value = true;
+    try {
+      const res = await productTreeList();
+      // 杩囨护鏍硅妭鐐逛骇鍝�
+      products.value = res
+        .filter(item => item.parentId === null)
+        .map(({ id, productName }) => ({ id, productName }));
+      tabs.value = products.value.map(p => ({ name: p.productName }));
+
+      if (products.value.length > 0) {
+        activeTab.value = 0;
+        initializedTabs.value = [products.value[0].id];
+      }
+    } finally {
+      loading.value = false;
+    }
+  };
+
+  const goBack = () => {
+    uni.navigateBack();
+  };
+
+  onMounted(() => {
+    fetchProducts();
+  });
 </script>
 
 <style scoped lang="scss">
-.app-container {
-  display: flex;
-  flex-direction: column;
-  height: 100vh;
-  background-color: #f8f9fa;
-}
-.swiper-box {
-  flex: 1;
-}
-.swiper-item {
-  height: 100%;
-}
-:deep(.up-tabs) {
-  background-color: #fff;
-}
+  .app-container {
+    display: flex;
+    flex-direction: column;
+    height: 100vh;
+    background-color: #f8f9fa;
+  }
+  .loading-state {
+    flex: 1;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+  .swiper-box {
+    flex: 1;
+  }
+  .swiper-item {
+    height: 100%;
+  }
+  :deep(.up-tabs) {
+    background-color: #fff;
+  }
 </style>
diff --git a/src/pages/procurementManagement/procurementLedger/detail.vue b/src/pages/procurementManagement/procurementLedger/detail.vue
index d7693cc..397d863 100644
--- a/src/pages/procurementManagement/procurementLedger/detail.vue
+++ b/src/pages/procurementManagement/procurementLedger/detail.vue
@@ -31,8 +31,7 @@
       </up-form-item>
       <up-form-item label="渚涘簲鍟嗗悕绉�"
                     prop="supplierName"
-                    required
-                    >
+                    required>
         <up-input v-model="form.supplierName"
                   readonly
                   :disabled="isReadOnly"
@@ -82,55 +81,6 @@
                   placeholder="璇疯緭鍏�"
                   disabled />
       </up-form-item>
-      <view class="approval-process">
-        <view class="approval-header">
-          <text class="approval-title">瀹℃牳娴佺▼</text>
-          <text class="approval-desc">姣忎釜姝ラ鍙兘閫夋嫨涓�涓鎵逛汉</text>
-        </view>
-        <view class="approval-steps">
-          <view v-for="(step, stepIndex) in approverNodes"
-                :key="stepIndex"
-                class="approval-step">
-            <view class="step-dot"></view>
-            <view class="step-title">
-              <text>瀹℃壒浜�</text>
-            </view>
-            <view class="approver-container">
-              <view v-if="step.nickName"
-                    class="approver-item">
-                <view class="approver-avatar">
-                  <text class="avatar-text">{{ step.nickName.charAt(0) }}</text>
-                  <view class="status-dot"></view>
-                </view>
-                <view class="approver-info">
-                  <text class="approver-name">{{ step.nickName }}</text>
-                </view>
-                <view class="delete-approver-btn"
-                      v-if="!isReadOnly"
-                      @click="removeApprover(stepIndex)">脳</view>
-              </view>
-              <view v-else-if="!isReadOnly"
-                    class="add-approver-btn"
-                    @click="addApprover(stepIndex)">
-                <view class="add-circle">+</view>
-                <text class="add-label">閫夋嫨瀹℃壒浜�</text>
-              </view>
-            </view>
-            <view class="step-line"
-                  v-if="stepIndex < approverNodes.length - 1"></view>
-            <view class="delete-step-btn"
-                  v-if="approverNodes.length > 1 && !isReadOnly"
-                  @click="removeApprovalStep(stepIndex)">鍒犻櫎鑺傜偣</view>
-          </view>
-        </view>
-        <view class="add-step-btn" v-if="!isReadOnly">
-          <u-button icon="plus"
-                    plain
-                    type="primary"
-                    style="width: 100%"
-                    @click="addApprovalStep">鏂板鑺傜偣</u-button>
-        </view>
-      </view>
       <up-popup :show="showTimePicker"
                 mode="bottom"
                 @close="showTimePicker = false">
diff --git a/src/pages/productionManagement/processRoute/items.vue b/src/pages/productionManagement/processRoute/items.vue
index d555526..9c2b266 100644
--- a/src/pages/productionManagement/processRoute/items.vue
+++ b/src/pages/productionManagement/processRoute/items.vue
@@ -63,6 +63,16 @@
                       type="success"
                       size="mini"
                       plain />
+              <up-tag v-if="item.type==0"
+                      text="璁℃椂"
+                      type="info"
+                      size="mini"
+                      plain />
+              <up-tag v-else
+                      text="璁′欢"
+                      type="warning"
+                      size="mini"
+                      plain />
             </view>
           </view>
           <view class="card-footer"
diff --git a/src/pages/productionManagement/productionAccounting/index.vue b/src/pages/productionManagement/productionAccounting/index.vue
index b20b407..87ec382 100644
--- a/src/pages/productionManagement/productionAccounting/index.vue
+++ b/src/pages/productionManagement/productionAccounting/index.vue
@@ -2,7 +2,6 @@
   <view class="production-accounting">
     <PageHeader title="鐢熶骇鏍哥畻"
                 @back="goBack" />
-
     <!-- 绛涢�夊尯鍩� -->
     <view class="filter-section">
       <view class="date-type-selector">
@@ -13,7 +12,6 @@
                  lineWidth="30"
                  lineHeight="3" />
       </view>
-
       <view class="date-picker-bar"
             @click="showDatePicker = true">
         <view class="date-display">
@@ -27,7 +25,6 @@
                  color="#999"></up-icon>
       </view>
     </view>
-
     <!-- 姹囨�诲垪琛� -->
     <view class="summary-section"
           v-if="!showDetail">
@@ -80,7 +77,6 @@
                   text="鏆傛棤姹囨�绘暟鎹�" />
       </view>
     </view>
-
     <!-- 鏄庣粏鍒楄〃 (鐐瑰嚮姹囨�昏鍚庢樉绀�) -->
     <view class="detail-section"
           v-else>
@@ -91,7 +87,6 @@
                  color="#2979ff"></up-icon>
         <text class="back-text">杩斿洖姹囨�� ({{ currentUserName }})</text>
       </view>
-
       <view class="ledger-list"
             v-if="detailList.length > 0">
         <view v-for="(item, index) in detailList"
@@ -113,6 +108,14 @@
           <up-divider></up-divider>
           <view class="item-details">
             <view class="detail-row">
+              <text class="detail-label">鐢熶骇鏃ユ湡</text>
+              <text class="detail-value">{{ item.schedulingDate || '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">鐢熶骇浜�</text>
+              <text class="detail-value">{{ item.schedulingUserName || '-' }}</text>
+            </view>
+            <view class="detail-row">
               <text class="detail-label">瑙勬牸鍨嬪彿</text>
               <text class="detail-value">{{ item.productModelName }}</text>
             </view>
@@ -123,6 +126,10 @@
             <view class="detail-row">
               <text class="detail-label">鐢熶骇鏁伴噺</text>
               <text class="detail-value">{{ item.quantity }} {{ item.unit }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">宸ユ椂(h)</text>
+              <text class="detail-value">{{ item.workHour || 0 }}</text>
             </view>
             <view class="detail-row">
               <text class="detail-label">宸ユ椂瀹氶</text>
@@ -143,7 +150,6 @@
                   text="鏆傛棤鏄庣粏鏁版嵁" />
       </view>
     </view>
-
     <!-- 鏃ユ湡閫夋嫨鍣� -->
     <up-datetime-picker :show="showDatePicker"
                         v-model="pickerValue"
@@ -281,7 +287,9 @@
     salesLedgerProductionAccountingListProductionDetails(params)
       .then(res => {
         const records = res.data.records || [];
-        detailList.value = isLoadMore ? [...detailList.value, ...records] : records;
+        detailList.value = isLoadMore
+          ? [...detailList.value, ...records]
+          : records;
         page1.total = res.data.total || 0;
 
         if (detailList.value.length >= page1.total) {
diff --git a/src/pages/productionManagement/productionOrder/pickingDetail.vue b/src/pages/productionManagement/productionOrder/pickingDetail.vue
index 9ed5f61..7aad62d 100644
--- a/src/pages/productionManagement/productionOrder/pickingDetail.vue
+++ b/src/pages/productionManagement/productionOrder/pickingDetail.vue
@@ -1,6 +1,6 @@
 <template>
   <view class="picking-detail">
-    <PageHeader :title="棰嗘枡璇︽儏"
+    <PageHeader title="棰嗘枡璇︽儏"
                 @back="goBack" />
     <scroll-view scroll-y
                  class="detail-list"
diff --git a/src/pages/productionManagement/productionReport/index.vue b/src/pages/productionManagement/productionReport/index.vue
index f5e5b4f..4687c62 100644
--- a/src/pages/productionManagement/productionReport/index.vue
+++ b/src/pages/productionManagement/productionReport/index.vue
@@ -40,6 +40,15 @@
                    @click="openProducerPicker"
                    suffix-icon="arrow-down" />
         </u-form-item>
+        <!-- 宸ユ椂 -->
+        <u-form-item label="宸ユ椂"
+                     v-if="form.type == 0"
+                     prop="workHour">
+          <u-input v-model="form.workHour"
+                   placeholder="璇疯緭鍏ュ伐鏃�"
+                   type="number" />
+          <text class="param-unit">h</text>
+        </u-form-item>
       </view>
       <!-- 鍔ㄦ�佸弬鏁板尯鍩� -->
       <view class="form-section"
@@ -135,7 +144,10 @@
   import { addProductMain } from "@/api/productionManagement/productionReporting";
   import { getInfo } from "@/api/login";
   import { userListNoPageByTenantId } from "@/api/system/user";
-  import { findProcessParamListOrder } from "@/api/productionManagement/productProcessRoute.js";
+  import {
+    findProcessParamListOrder,
+    listMaterialPickingDetail,
+  } from "@/api/productionManagement/productionOrder.js";
   import { getDicts } from "@/api/system/dict/data";
   import { formatDateToYMD, parseTime } from "@/utils/ruoyi";
 
@@ -147,13 +159,13 @@
     scrapQty: "",
     userName: "",
     workOrderId: "",
-    productProcessRouteItemId: "",
     userId: "",
     schedulingUserId: "",
     reportWork: "",
-    productMainId: null,
     productionOrderRoutingOperationId: "",
     productionOrderId: "",
+    workHour: 0,
+    type: null,
     paramGroups: {},
   });
 
@@ -344,12 +356,11 @@
       userId: form.value.userId,
       userName: form.value.userName,
       productionOperationTaskId: form.value.workOrderId,
-      productProcessRouteItemId: form.value.productProcessRouteItemId,
       reportWork: form.value.reportWork,
-      productMainId: form.value.productMainId,
       productionOrderRoutingOperationId:
         form.value.productionOrderRoutingOperationId,
       productionOrderId: form.value.productionOrderId,
+      workHour: form.value.workHour,
       productionOperationParamList: productionOperationParamList,
     };
 
@@ -374,7 +385,7 @@
       });
   };
 
-  onLoad(options => {
+  onLoad(async options => {
     console.log(options, "options");
     if (!options.orderRow) {
       console.log("浠庨椤佃烦杞紝鏃犺鍗曟暟鎹�");
@@ -389,16 +400,43 @@
       const orderRow = JSON.parse(decodeURIComponent(options.orderRow));
       console.log("鏋勯�犵殑orderRow:", orderRow);
 
+      // 鍙傜収 PC 绔�昏緫锛氭湭棰嗘枡鏃犳硶鎶ュ伐
+      if (orderRow.productionOrderId) {
+        try {
+          const res = await listMaterialPickingDetail(orderRow.productionOrderId);
+          const records = Array.isArray(res.data)
+            ? res.data
+            : res.data?.records || [];
+          if (res.code === 200 && records.length === 0) {
+            uni.showModal({
+              title: "鎻愮ず",
+              content: "鏈鏂欐棤娉曟姤宸�",
+              showCancel: false,
+              success: () => {
+                goBack();
+              },
+            });
+            return;
+          }
+        } catch (error) {
+          console.error("鏌ヨ棰嗘枡璇︽儏澶辫触:", error);
+        }
+      }
+
       form.value.planQuantity =
         orderRow.planQuantity != null ? String(orderRow.planQuantity) : "";
-      form.value.productProcessRouteItemId =
-        orderRow.productProcessRouteItemId || "";
       form.value.workOrderId = orderRow.id || "";
       form.value.reportWork = orderRow.reportWork || "";
-      form.value.productMainId = orderRow.productMainId || null;
       form.value.productionOrderRoutingOperationId =
         orderRow.productionOrderRoutingOperationId || "";
       form.value.productionOrderId = orderRow.productionOrderId || "";
+      form.value.type = orderRow.type;
+
+      if (orderRow.type == 0) {
+        form.value.workHour = orderRow.workHour || 0;
+      } else {
+        form.value.workHour = 0;
+      }
 
       getInfo().then(res => {
         form.value.userId = res.user.userId;
diff --git a/src/pages/productionManagement/productionReporting/ledger.vue b/src/pages/productionManagement/productionReporting/ledger.vue
index b71a9a3..fb5d1dd 100644
--- a/src/pages/productionManagement/productionReporting/ledger.vue
+++ b/src/pages/productionManagement/productionReporting/ledger.vue
@@ -49,6 +49,10 @@
                 <text class="detail-value highlight">{{ item.nickName || '-' }}</text>
               </view>
               <view class="detail-row">
+                <text class="detail-label">宸ユ椂(h)</text>
+                <text class="detail-value">{{ item.workHour || 0 }}</text>
+              </view>
+              <view class="detail-row">
                 <text class="detail-label">鎵�灞炲伐搴�</text>
                 <view class="detail-value">
                   <up-tag :text="item.process || '-'"
@@ -60,6 +64,10 @@
               <view class="detail-row">
                 <text class="detail-label">宸ュ崟缂栧彿</text>
                 <text class="detail-value">{{ item.workOrderNo || '-' }}</text>
+              </view>
+              <view class="detail-row">
+                <text class="detail-label">閿�鍞悎鍚屽彿</text>
+                <text class="detail-value">{{ item.salesContractNo || '-' }}</text>
               </view>
               <view class="detail-row">
                 <text class="detail-label">浜у搧鍚嶇О</text>
@@ -91,11 +99,11 @@
                              plain
                              text="鍙傛暟璇︽儏"
                              @click="handleShowParams(item)"></up-button>
-                  <up-button type="error"
+                  <!-- <up-button type="error"
                              size="small"
                              plain
                              text="鍒犻櫎"
-                             @click="handleDelete(item)"></up-button>
+                             @click="handleDelete(item)"></up-button> -->
                 </view>
               </view>
             </view>
@@ -120,16 +128,20 @@
                 :key="idx"
                 class="detail-item">
             <view class="detail-row">
-              <text class="detail-label">鎶曞叆浜у搧</text>
-              <text class="detail-value font-bold">{{ input.productName }}</text>
+              <text class="detail-label">鎶ュ伐鍗曞彿</text>
+              <text class="detail-value">{{ input.productNo || '-' }}</text>
             </view>
             <view class="detail-row">
-              <text class="detail-label">瑙勬牸鍨嬪彿</text>
-              <text class="detail-value">{{ input.model }}</text>
+              <text class="detail-label">鎶曞叆浜у搧鍚嶇О</text>
+              <text class="detail-value font-bold">{{ input.productName || '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">鎶曞叆浜у搧鍨嬪彿</text>
+              <text class="detail-value">{{ input.model || '-' }}</text>
             </view>
             <view class="detail-row">
               <text class="detail-label">鎶曞叆鏁伴噺</text>
-              <text class="detail-value highlight">{{ input.quantity }} {{ input.unit }}</text>
+              <text class="detail-value highlight">{{ input.quantity || 0 }} {{ input.unit || '' }}</text>
             </view>
             <up-divider></up-divider>
           </view>
diff --git a/src/pages/productionManagement/productionTraceability/index.vue b/src/pages/productionManagement/productionTraceability/index.vue
index b761cb6..d187543 100644
--- a/src/pages/productionManagement/productionTraceability/index.vue
+++ b/src/pages/productionManagement/productionTraceability/index.vue
@@ -25,45 +25,45 @@
       <!-- 鍩虹淇℃伅 -->
       <view class="info-card">
         <view class="card-title">鍩虹淇℃伅</view>
-        <view class="info-grid">
-          <view class="info-item">
-            <text class="label">鐢熶骇璁㈠崟鍙�</text>
-            <text class="value">{{ rowData.productionOrderDto.npsNo || '-' }}</text>
+        <view class="base-info">
+          <view class="info-row">
+            <text class="label">鐢熶骇璁㈠崟鍙凤細</text>
+            <text class="value">{{ rowData.productionOrderDto?.npsNo || '-' }}</text>
           </view>
-          <view class="info-item">
-            <text class="label">浜у搧鍚嶇О</text>
-            <text class="value">{{ rowData.productionOrderDto.productName || '-' }}</text>
+          <view class="info-row">
+            <text class="label">浜у搧鍚嶇О锛�</text>
+            <text class="value">{{ rowData.productionOrderDto?.productName || '-' }}</text>
           </view>
-          <view class="info-item">
-            <text class="label">浜у搧瑙勬牸</text>
-            <text class="value">{{ rowData.productionOrderDto.model || '-' }}</text>
+          <view class="info-row">
+            <text class="label">瑙勬牸鍨嬪彿锛�</text>
+            <text class="value">{{ rowData.productionOrderDto?.model || '-' }}</text>
           </view>
-          <view class="info-item">
-            <text class="label">璁″垝鏁伴噺</text>
-            <text class="value">{{ rowData.productionOrderDto.quantity || 0 }} {{ rowData.productionOrderDto.unit || '' }}</text>
+          <view class="info-row">
+            <text class="label">璁″垝鏁伴噺锛�</text>
+            <text class="value">{{ rowData.productionOrderDto?.quantity || 0 }} {{ rowData.productionOrderDto?.unit }}</text>
           </view>
-          <view class="info-item">
-            <text class="label">褰撳墠鐘舵��</text>
-            <up-tag :text="getStatusText(rowData.productionOrderDto.status)"
-                    style="width:100rpx"
-                    :type="getStatusType(rowData.productionOrderDto.status)"
-                    size="mini" />
+          <view class="info-row">
+            <text class="label">褰撳墠鐘舵�侊細</text>
+            <view class="value">
+              <up-tag :text="getStatusText(rowData.productionOrderDto?.status)"
+                      :type="getStatusType(rowData.productionOrderDto?.status)"
+                      size="mini" />
+            </view>
           </view>
-          <view class="info-item">
-            <text class="label">瀹㈡埛鍚嶇О</text>
-            <text class="value">{{ rowData.productionOrderDto.customerName || '-' }}</text>
+          <view class="info-row">
+            <text class="label">瀹㈡埛鍚嶇О锛�</text>
+            <text class="value">{{ rowData.productionOrderDto?.customerName || '-' }}</text>
           </view>
-          <view class="info-item">
-            <text class="label">寮�濮嬫棩鏈�</text>
-            <text class="value">{{ formatDate(rowData.productionOrderDto.startTime) }}</text>
+          <view class="info-row">
+            <text class="label">寮�濮嬫棩鏈燂細</text>
+            <text class="value">{{ formatDate(rowData.productionOrderDto?.startTime) }}</text>
           </view>
-          <view class="info-item full-width">
-            <text class="label">瀹屾垚杩涘害</text>
-            <view class="progress-container">
-              <up-line-progress :percentage="formatProgress(rowData.productionOrderDto.completionStatus)"
-                                :activeColor="progressColor(rowData.productionOrderDto.completionStatus)"
-                                height="8"></up-line-progress>
-              <text class="progress-text">{{ formatProgress(rowData.productionOrderDto.completionStatus) }}%</text>
+          <view class="info-row">
+            <text class="label">瀹屾垚杩涘害锛�</text>
+            <view class="value progress-box">
+              <up-line-progress :percentage="formatProgress(rowData.productionOrderDto?.completionStatus)"
+                                :activeColor="progressColor(formatProgress(rowData.productionOrderDto?.completionStatus))"
+                                :showText="true" />
             </view>
           </view>
         </view>
@@ -86,8 +86,16 @@
               <text class="value">{{ item.workOrder.productName }} / {{ item.workOrder.model }}</text>
             </view>
             <view class="content-row">
+              <text class="label">褰撳墠宸ュ簭锛�</text>
+              <text class="value">{{ item.workOrder.operationName || '-' }}</text>
+            </view>
+            <view class="content-row">
               <text class="label">闇�姹�/瀹屾垚锛�</text>
               <text class="value">{{ item.workOrder.planQuantity }} / {{ item.workOrder.completeQuantity }}</text>
+            </view>
+            <view class="content-row">
+              <text class="label">鎶ュ簾鏁伴噺锛�</text>
+              <text class="value error-text">{{ item.workOrder.scrapQty || 0 }}</text>
             </view>
           </view>
           <view class="card-footer">
@@ -183,6 +191,9 @@
                 class="detail-item">
             <view class="item-main">
               <view class="item-row"><text class="label">鎶ュ伐鍗曞彿锛�</text><text class="value">{{ report.productNo }}</text></view>
+              <view class="item-row"><text class="label">浜у嚭鏁伴噺锛�</text><text class="value">{{ report.quantity || 0 }}</text></view>
+              <view class="item-row"><text class="label">鎶ュ簾鏁伴噺锛�</text><text class="value error-text">{{ report.scrapQty || 0 }}</text></view>
+              <view class="item-row"><text class="label">宸ユ椂(h)锛�</text><text class="value">{{ report.workHour || 0 }}</text></view>
               <view class="item-row"><text class="label">鍒涘缓浜猴細</text><text class="value">{{ report.userName }}</text></view>
               <view class="item-row"><text class="label">鍒涘缓鏃堕棿锛�</text><text class="value">{{ formatDate(report.createTime, '{y}-{m}-{d} {h}:{i}') }}</text></view>
             </view>
@@ -215,11 +226,14 @@
           <view class="input-list-popup">
             <view v-for="(item, idx) in inputListData"
                   :key="idx"
-                  class="input-item">
-              <view class="input-row"><text class="label">鐗╂枡鍚嶇О锛�</text><text class="value">{{ item.materialName }}</text></view>
-              <view class="input-row"><text class="label">瑙勬牸鍨嬪彿锛�</text><text class="value">{{ item.model }}</text></view>
-              <view class="input-row"><text class="label">鎶曞叆鏁伴噺锛�</text><text class="value">{{ item.quantity }} {{ item.unit }}</text></view>
-              <view class="input-row"><text class="label">鎵规鍙凤細</text><text class="value">{{ item.batchNo }}</text></view>
+                  class="quality-record">
+              <view class="record-title">鎶曞叆璁板綍 {{ idx + 1 }}</view>
+              <view class="info-grid">
+                <view class="info-item"><text class="label">鎶ュ伐鍗曞彿</text><text class="value">{{ item.productNo || '-' }}</text></view>
+                <view class="info-item"><text class="label">鎶曞叆鏁伴噺</text><text class="value">{{ item.quantity || 0 }} {{ item.unit || '' }}</text></view>
+                <view class="info-item full-width"><text class="label">鎶曞叆浜у搧鍚嶇О</text><text class="value">{{ item.productName || '-' }}</text></view>
+                <view class="info-item full-width"><text class="label">鎶曞叆浜у搧鍨嬪彿</text><text class="value">{{ item.model || '-' }}</text></view>
+              </view>
             </view>
             <view v-if="!inputListData || inputListData.length === 0"
                   class="no-data-minor">{{ inputLoading ? '鍔犺浇涓�...' : '鏆傛棤鎶曞叆璁板綍' }}</view>
@@ -253,18 +267,26 @@
                         size="mini" /></view>
               <view class="info-item"><text class="label">妫�楠屽憳</text><text class="value">{{ record.userName }}</text></view>
               <view class="info-item"><text class="label">鏁伴噺</text><text class="value">{{ record.quantity }} {{ record.unit }}</text></view>
+              <view class="info-item"><text class="label">鎶ュ伐鍗曞彿</text><text class="value">{{ record.reportNo || '-' }}</text></view>
+              <view class="info-item"><text class="label">浜у搧鍚嶇О</text><text class="value">{{ record.productName || '-' }}</text></view>
+              <view class="info-item"><text class="label">瑙勬牸鍨嬪彿</text><text class="value">{{ record.model || '-' }}</text></view>
+              <view class="info-item"><text class="label">妫�娴嬪崟浣�</text><text class="value">{{ record.checkCompany || '-' }}</text></view>
             </view>
             <view class="params-table">
               <view class="table-header">
                 <text class="col">鎸囨爣</text>
+                <text class="col">鍗曚綅</text>
                 <text class="col">鏍囧噯鍊�</text>
+                <text class="col">鍐呮帶鍊�</text>
                 <text class="col">瀹為檯鍊�</text>
               </view>
               <view v-for="(param, pIdx) in record.inspectParamList"
                     :key="pIdx"
                     class="table-row">
                 <text class="col">{{ param.parameterItem }}</text>
+                <text class="col">{{ param.unit || '-' }}</text>
                 <text class="col">{{ param.standardValue }}</text>
+                <text class="col">{{ param.controlValue || '-' }}</text>
                 <text class="col"
                       :class="{ 'error-text': param.testValue != param.standardValue }">{{ param.testValue }}</text>
               </view>
@@ -440,6 +462,7 @@
       workOrder: row.workOrder || {},
       reports: (row.reportList || []).map(r => ({
         ...r.reportMain,
+        ...(r.reportOutputList ? r.reportOutputList[0] : {}),
         id: r.reportMain.id,
         productionOperationParamList: r.reportParamList || [],
       })),
@@ -471,6 +494,8 @@
     qualityRecords.value = inspects.map(i => ({
       ...i.inspect,
       reportNo: i.reportNo,
+      productName: row.workOrder?.productName || "-",
+      model: row.workOrder?.model || "-",
       userName: i.reportMain?.userName || "-",
       inspectParamList: i.inspectParamList || [],
     }));
@@ -708,6 +733,66 @@
     }
   }
 
+  .base-info {
+    background: #fff;
+    padding: 24rpx;
+    border-radius: 16rpx;
+    margin-bottom: 30rpx;
+
+    .info-row {
+      margin-bottom: 16rpx;
+      font-size: 28rpx;
+      display: flex;
+      align-items: center;
+
+      &:last-child {
+        margin-bottom: 0;
+      }
+
+      .label {
+        color: #999;
+        min-width: 180rpx;
+      }
+      .value {
+        color: #333;
+        flex: 1;
+        font-weight: 500;
+
+        &.progress-box {
+          flex: 1;
+        }
+      }
+    }
+  }
+
+  .info-grid {
+    display: flex;
+    flex-wrap: wrap;
+    padding: 10rpx 0;
+
+    .info-item {
+      width: 50%;
+      margin-bottom: 20rpx;
+      display: flex;
+      flex-direction: column;
+
+      &.full-width {
+        width: 100%;
+      }
+
+      .label {
+        font-size: 24rpx;
+        color: #999;
+        margin-bottom: 4rpx;
+      }
+      .value {
+        font-size: 28rpx;
+        color: #333;
+        font-weight: 500;
+      }
+    }
+  }
+
   .popup-content {
     background: #fff;
     padding: 30rpx;
diff --git a/src/pages/qualityManagement/finalInspection/add.vue b/src/pages/qualityManagement/finalInspection/add.vue
index 9b605c7..94321dd 100644
--- a/src/pages/qualityManagement/finalInspection/add.vue
+++ b/src/pages/qualityManagement/finalInspection/add.vue
@@ -51,6 +51,7 @@
       </up-form-item>
       <up-form-item label="鎸囨爣閫夋嫨"
                     prop="testStandardId"
+                    required
                     border-bottom>
         <up-input v-model="testStandardDisplay"
                   placeholder="璇烽�夋嫨鎸囨爣"
@@ -442,7 +443,7 @@
       { required: true, message: "璇烽�夋嫨浜у搧鍨嬪彿", trigger: "change" },
     ],
     testStandardId: [
-      { required: false, message: "璇烽�夋嫨鎸囨爣", trigger: "change" },
+      { required: true, message: "璇烽�夋嫨鎸囨爣", trigger: "change" },
     ],
     unit: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
     quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
@@ -602,9 +603,9 @@
 
   // 鑾峰彇宸ュ簭鍒楄〃
   const getprocessList = () => {
-    list().then(res => {
-      processList.value = res.data;
-    });
+    // list().then(res => {
+    //   processList.value = res.data;
+    // });
   };
 
   // 鑾峰彇浜у搧閫夐」
@@ -691,6 +692,10 @@
         showToast("璇烽�夋嫨浜у搧");
         return;
       }
+      if (!form.value.testStandardId) {
+        showToast("璇烽�夋嫨鎸囨爣");
+        return;
+      }
       if (!form.value.checkResult) {
         showToast("璇烽�夋嫨妫�娴嬬粨鏋�");
         return;
@@ -699,7 +704,7 @@
       loading.value = true;
 
       form.value.inspectType = 2;
-      if (isEdit.value) {
+      if (!isEdit.value) {
         tableData.value.forEach(item => {
           delete item.id;
         });
diff --git a/src/pages/qualityManagement/finalInspection/detail.vue b/src/pages/qualityManagement/finalInspection/detail.vue
index 0e5bba6..d274a28 100644
--- a/src/pages/qualityManagement/finalInspection/detail.vue
+++ b/src/pages/qualityManagement/finalInspection/detail.vue
@@ -15,7 +15,8 @@
           </view>
           <text class="header-title">{{ detailData.productName || '-' }}</text>
           <view class="status-tags">
-            <u-tag :type="getTagType(detailData.checkResult)"
+            <u-tag v-if="detailData.checkResult"
+                   :type="getTagType(detailData.checkResult)"
                    size="small"
                    class="status-tag">
               {{ detailData.checkResult || '-' }}
diff --git a/src/pages/qualityManagement/finalInspection/index.vue b/src/pages/qualityManagement/finalInspection/index.vue
index 180d08d..0e860ff 100644
--- a/src/pages/qualityManagement/finalInspection/index.vue
+++ b/src/pages/qualityManagement/finalInspection/index.vue
@@ -76,7 +76,8 @@
               </view>
             </view>
             <view class="status-tags">
-              <u-tag :type="getTagType(item.checkResult)"
+              <u-tag v-if="item.checkResult"
+                     :type="getTagType(item.checkResult)"
                      size="mini"
                      class="status-tag">
                 {{ item.checkResult }}
@@ -117,29 +118,29 @@
           </view>
           <!-- 鎿嶄綔鎸夐挳 -->
           <view class="action-buttons">
-            <!-- <u-button type="primary"
+            <u-button type="primary"
                       size="small"
                       class="action-btn"
                       :disabled="item.inspectState"
                       @click.stop="startInspection(item)">
               缂栬緫
-            </u-button> -->
+            </u-button>
             <u-button type="info"
                       size="small"
                       class="action-btn"
                       @click.stop="viewDetail(item)">
               璇︽儏
             </u-button>
-            <!-- <u-button type="success"
+            <u-button type="success"
                       size="small"
                       class="action-btn"
                       :disabled="item.inspectState"
                       @click.stop="submitInspection(item)">
               鎻愪氦
-            </u-button> -->
+            </u-button>
           </view>
           <view class="action-buttons">
-            <!-- <u-button type="info"
+            <u-button type="info"
                       size="small"
                       class="action-btn"
                       @click.stop="viewFileList(item)">
@@ -151,7 +152,7 @@
                       :disabled="item.inspectState || item.checkName !== ''"
                       @click.stop="assignInspector(item)">
               鍒嗛厤妫�楠屽憳
-            </u-button> -->
+            </u-button>
           </view>
         </view>
       </view>
@@ -163,12 +164,12 @@
     </view>
     <!-- 鍒嗛〉缁勪欢 -->
     <!-- 娴姩鏂板鎸夐挳 -->
-    <!-- <view class="fab-button"
+    <view class="fab-button"
           @click="addInspection">
       <up-icon name="plus"
                size="24"
                color="#ffffff"></up-icon>
-    </view> -->
+    </view>
     <!-- 鏃ユ湡閫夋嫨鍣� -->
     <up-popup v-model:show="showDate"
               mode="date"
diff --git a/src/pages/qualityManagement/materialInspection/add.vue b/src/pages/qualityManagement/materialInspection/add.vue
index 63a94ef..e04391f 100644
--- a/src/pages/qualityManagement/materialInspection/add.vue
+++ b/src/pages/qualityManagement/materialInspection/add.vue
@@ -51,6 +51,7 @@
       </up-form-item>
       <up-form-item label="鎸囨爣閫夋嫨"
                     prop="testStandardId"
+                    required
                     border-bottom>
         <up-input v-model="testStandardDisplay"
                   placeholder="璇烽�夋嫨鎸囨爣"
@@ -114,9 +115,10 @@
                     border-bottom>
         <up-input v-model="form.checkTime"
                   placeholder="璇烽�夋嫨妫�娴嬫棩鏈�"
-                  readonly />
+                  readonly
+                  @click="showDatePicker" />
         <!-- <template #right>
-          <up-icon name="calendar"
+          <up-icon name="arrow-right"
                    @click="showDatePicker"></up-icon>
         </template> -->
       </up-form-item>
@@ -191,11 +193,15 @@
       </up-button>
     </view>
     <!-- 鏃ユ湡閫夋嫨鍣� -->
-    <up-popup v-model:show="showDate"
-              mode="date"
-              :start-year="2020"
-              :end-year="2030"
-              @confirm="confirmDate" />
+    <up-popup :show="showDate"
+              mode="bottom"
+              @close="showDate = false">
+      <up-datetime-picker :show="true"
+                          v-model="pickerValue"
+                          @confirm="confirmDate"
+                          @cancel="showDate = false"
+                          mode="date" />
+    </up-popup>
     <!-- 渚涘簲鍟嗛�夋嫨 -->
     <up-action-sheet :show="showSupplierSheet"
                      :actions="supplierOptions"
@@ -337,6 +343,7 @@
   const loading = ref(false);
   // 鏃ユ湡閫夋嫨鍣�
   const showDate = ref(false);
+  const pickerValue = ref(Date.now());
   // 渚涘簲鍟嗛�夋嫨
   const showSupplierSheet = ref(false);
   // 浜у搧閫夋嫨
@@ -448,7 +455,7 @@
       { required: true, message: "璇烽�夋嫨浜у搧鍨嬪彿", trigger: "change" },
     ],
     testStandardId: [
-      { required: false, message: "璇烽�夋嫨鎸囨爣", trigger: "change" },
+      { required: true, message: "璇烽�夋嫨鎸囨爣", trigger: "change" },
     ],
     unit: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
     quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
@@ -483,6 +490,7 @@
   // 纭鏃ユ湡閫夋嫨
   const confirmDate = e => {
     form.value.checkTime = dayjs(e.value).format("YYYY-MM-DD");
+    showDate.value = false;
   };
 
   // 閫夋嫨渚涘簲鍟�
@@ -697,6 +705,10 @@
         showToast("璇烽�夋嫨浜у搧");
         return;
       }
+      if (!form.value.testStandardId) {
+        showToast("璇烽�夋嫨鎸囨爣");
+        return;
+      }
       if (!form.value.checkResult) {
         showToast("璇烽�夋嫨妫�娴嬬粨鏋�");
         return;
@@ -705,7 +717,7 @@
       loading.value = true;
 
       form.value.inspectType = 0;
-      if (isEdit.value) {
+      if (!isEdit.value) {
         tableData.value.forEach(item => {
           delete item.id;
         });
diff --git a/src/pages/qualityManagement/materialInspection/detail.vue b/src/pages/qualityManagement/materialInspection/detail.vue
index e45b9c0..12ff7a3 100644
--- a/src/pages/qualityManagement/materialInspection/detail.vue
+++ b/src/pages/qualityManagement/materialInspection/detail.vue
@@ -15,7 +15,8 @@
           </view>
           <text class="header-title">{{ detailData.productName || '-' }}</text>
           <view class="status-tags">
-            <u-tag :type="getTagType(detailData.checkResult)"
+            <u-tag v-if="detailData.checkResult"
+                   :type="getTagType(detailData.checkResult)"
                    size="small"
                    class="status-tag">
               {{ detailData.checkResult || '-' }}
diff --git a/src/pages/qualityManagement/materialInspection/index.vue b/src/pages/qualityManagement/materialInspection/index.vue
index 83ab257..eb4a140 100644
--- a/src/pages/qualityManagement/materialInspection/index.vue
+++ b/src/pages/qualityManagement/materialInspection/index.vue
@@ -76,7 +76,8 @@
               </view>
             </view>
             <view class="status-tags">
-              <u-tag :type="getTagType(item.checkResult)"
+              <u-tag v-if="item.checkResult"
+                     :type="getTagType(item.checkResult)"
                      size="mini"
                      class="status-tag">
                 {{ item.checkResult }}
@@ -117,29 +118,29 @@
           </view>
           <!-- 鎿嶄綔鎸夐挳 -->
           <view class="action-buttons">
-            <!-- <u-button type="primary"
+            <u-button type="primary"
                       size="small"
                       class="action-btn"
                       :disabled="item.inspectState"
                       @click.stop="startInspection(item)">
               缂栬緫
-            </u-button> -->
+            </u-button>
             <u-button type="info"
                       size="small"
                       class="action-btn"
                       @click.stop="viewDetail(item)">
               璇︽儏
             </u-button>
-            <!-- <u-button type="success"
+            <u-button type="success"
                       size="small"
                       class="action-btn"
                       :disabled="item.inspectState"
                       @click.stop="submitInspection(item)">
               鎻愪氦
-            </u-button> -->
+            </u-button>
           </view>
           <view class="action-buttons">
-            <!-- <u-button type="info"
+            <u-button type="info"
                       size="small"
                       class="action-btn"
                       @click.stop="viewFileList(item)">
@@ -151,7 +152,7 @@
                       :disabled="item.inspectState || item.checkName !== ''"
                       @click.stop="assignInspector(item)">
               鍒嗛厤妫�楠屽憳
-            </u-button> -->
+            </u-button>
           </view>
         </view>
       </view>
@@ -163,12 +164,12 @@
     </view>
     <!-- 鍒嗛〉缁勪欢 -->
     <!-- 娴姩鏂板鎸夐挳 -->
-    <!-- <view class="fab-button"
+    <view class="fab-button"
           @click="addInspection">
       <up-icon name="plus"
                size="24"
                color="#ffffff"></up-icon>
-    </view> -->
+    </view>
     <!-- 鏃ユ湡閫夋嫨鍣� -->
     <up-popup v-model:show="showDate"
               mode="date"
diff --git a/src/pages/qualityManagement/processInspection/add.vue b/src/pages/qualityManagement/processInspection/add.vue
index f146fe1..2f6a6d0 100644
--- a/src/pages/qualityManagement/processInspection/add.vue
+++ b/src/pages/qualityManagement/processInspection/add.vue
@@ -51,6 +51,7 @@
       </up-form-item>
       <up-form-item label="鎸囨爣閫夋嫨"
                     prop="testStandardId"
+                    required
                     border-bottom>
         <up-input v-model="testStandardDisplay"
                   placeholder="璇烽�夋嫨鎸囨爣"
@@ -184,11 +185,15 @@
       </up-button>
     </view>
     <!-- 鏃ユ湡閫夋嫨鍣� -->
-    <up-popup v-model:show="showDate"
-              mode="date"
-              :start-year="2020"
-              :end-year="2030"
-              @confirm="confirmDate" />
+    <up-popup :show="showDate"
+              mode="bottom"
+              @close="showDate = false">
+      <up-datetime-picker :show="true"
+                          v-model="pickerValue"
+                          @confirm="confirmDate"
+                          @cancel="showDate = false"
+                          mode="date" />
+    </up-popup>
     <!-- 宸ュ簭閫夋嫨 -->
     <up-action-sheet :show="showprocessSheet"
                      :actions="processOptions"
@@ -313,8 +318,8 @@
     qualityInspectParamInfo,
     qualityInspectDetailByProductId,
     getQualityTestStandardParamByTestStandardId,
-    list,
   } from "@/api/qualityManagement/materialInspection.js";
+  import { getProcessList } from "@/api/productionManagement/processManagement.js";
   import { userListNoPage } from "@/api/system/user.js";
 
   // 鏄剧ず鎻愮ず淇℃伅
@@ -442,7 +447,7 @@
       { required: true, message: "璇烽�夋嫨浜у搧鍨嬪彿", trigger: "change" },
     ],
     testStandardId: [
-      { required: false, message: "璇烽�夋嫨鎸囨爣", trigger: "change" },
+      { required: true, message: "璇烽�夋嫨鎸囨爣", trigger: "change" },
     ],
     unit: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
     quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
@@ -602,8 +607,8 @@
 
   // 鑾峰彇宸ュ簭鍒楄〃
   const getprocessList = () => {
-    list().then(res => {
-      processList.value = res.data;
+    getProcessList({ size: -1, current: -1 }).then(res => {
+      processList.value = res.data?.records || res.data || [];
     });
   };
 
@@ -691,6 +696,10 @@
         showToast("璇烽�夋嫨浜у搧");
         return;
       }
+      if (!form.value.testStandardId) {
+        showToast("璇烽�夋嫨鎸囨爣");
+        return;
+      }
       if (!form.value.checkResult) {
         showToast("璇烽�夋嫨妫�娴嬬粨鏋�");
         return;
@@ -699,7 +708,7 @@
       loading.value = true;
 
       form.value.inspectType = 1;
-      if (isEdit.value) {
+      if (!isEdit.value) {
         tableData.value.forEach(item => {
           delete item.id;
         });
diff --git a/src/pages/qualityManagement/processInspection/detail.vue b/src/pages/qualityManagement/processInspection/detail.vue
index 721bb2a..798aeee 100644
--- a/src/pages/qualityManagement/processInspection/detail.vue
+++ b/src/pages/qualityManagement/processInspection/detail.vue
@@ -15,10 +15,11 @@
           </view>
           <text class="header-title">{{ detailData.productName || '-' }}</text>
           <view class="status-tags">
-            <u-tag :type="getTagType(detailData.checkResult)"
+            <u-tag v-if="detailData.checkResult"
+                   :type="getTagType(detailData.checkResult)"
                    size="small"
                    class="status-tag">
-              {{ detailData.checkResult || '-' }}
+              {{ detailData.checkResult }}
             </u-tag>
             <u-tag :type="getStateTagType(detailData.inspectState)"
                    size="small"
diff --git a/src/pages/qualityManagement/processInspection/index.vue b/src/pages/qualityManagement/processInspection/index.vue
index 14e66ef..40358ef 100644
--- a/src/pages/qualityManagement/processInspection/index.vue
+++ b/src/pages/qualityManagement/processInspection/index.vue
@@ -76,7 +76,8 @@
               </view>
             </view>
             <view class="status-tags">
-              <u-tag :type="getTagType(item.checkResult)"
+              <u-tag v-if="item.checkResult"
+                     :type="getTagType(item.checkResult)"
                      size="mini"
                      class="status-tag">
                 {{ item.checkResult }}
@@ -117,29 +118,29 @@
           </view>
           <!-- 鎿嶄綔鎸夐挳 -->
           <view class="action-buttons">
-            <!-- <u-button type="primary"
+            <u-button type="primary"
                       size="small"
                       class="action-btn"
                       :disabled="item.inspectState"
                       @click.stop="startInspection(item)">
               缂栬緫
-            </u-button> -->
+            </u-button>
             <u-button type="info"
                       size="small"
                       class="action-btn"
                       @click.stop="viewDetail(item)">
               璇︽儏
             </u-button>
-            <!-- <u-button type="success"
+            <u-button type="success"
                       size="small"
                       class="action-btn"
                       :disabled="item.inspectState"
                       @click.stop="submitInspection(item)">
               鎻愪氦
-            </u-button> -->
+            </u-button>
           </view>
           <view class="action-buttons">
-            <!-- <u-button type="info"
+            <u-button type="info"
                       size="small"
                       class="action-btn"
                       @click.stop="viewFileList(item)">
@@ -151,7 +152,7 @@
                       :disabled="item.inspectState || item.checkName !== ''"
                       @click.stop="assignInspector(item)">
               鍒嗛厤妫�楠屽憳
-            </u-button> -->
+            </u-button>
           </view>
         </view>
       </view>
@@ -163,12 +164,12 @@
     </view>
     <!-- 鍒嗛〉缁勪欢 -->
     <!-- 娴姩鏂板鎸夐挳 -->
-    <!-- <view class="fab-button"
+    <view class="fab-button"
           @click="addInspection">
       <up-icon name="plus"
                size="24"
                color="#ffffff"></up-icon>
-    </view> -->
+    </view>
     <!-- 鏃ユ湡閫夋嫨鍣� -->
     <up-popup v-model:show="showDate"
               mode="date"
diff --git a/src/pages/sales/salesAccount/goOut.vue b/src/pages/sales/salesAccount/goOut.vue
index 9980e5f..42321c9 100644
--- a/src/pages/sales/salesAccount/goOut.vue
+++ b/src/pages/sales/salesAccount/goOut.vue
@@ -1,657 +1,451 @@
 <template>
-  <view class="account-detail">
+  <view class="shipment-page">
     <PageHeader title="鍙戣揣"
                 @back="goBack" />
-    <!-- 琛ㄥ崟鍖哄煙 -->
-    <u-form ref="formRef"
-            @submit="submitForm"
-            :rules="rules"
-            :model="form"
-            label-width="140rpx">
-      <u-form-item prop="typeValue"
-                   label="鍙戣揣绫诲瀷"
-                   required>
-        <u-input v-model="typeValue"
-                 readonly
-                 placeholder="璇烽�夋嫨鍙戣揣鏂瑰紡"
-                 @click="showPicker = true" />
-        <template #right>
-          <up-icon name="arrow-right"
-                   @click="showPicker = true"></up-icon>
-        </template>
-      </u-form-item>
-    </u-form>
-    <!-- 閫夋嫨鍣ㄥ脊绐� -->
-    <up-action-sheet :show="showPicker"
-                     :actions="productOptions"
-                     title="鍙戣揣鏂瑰紡"
-                     @select="onConfirm"
-                     @close="showPicker = false" />
-    <!-- 瀹℃牳娴佺▼鍖哄煙 -->
-    <view class="approval-process">
-      <view class="approval-header">
-        <text class="approval-title">瀹℃牳娴佺▼</text>
-        <text class="approval-desc">姣忎釜姝ラ鍙兘閫夋嫨涓�涓鎵逛汉</text>
-      </view>
-      <view class="approval-steps">
-        <view v-for="(step, stepIndex) in approverNodes"
-              :key="stepIndex"
-              class="approval-step">
-          <view class="step-dot"></view>
-          <view class="step-title">
-            <text>瀹℃壒浜�</text>
+    <view class="form-container">
+      <up-form ref="formRef"
+               :model="form"
+               :rules="rules"
+               label-width="100"
+               input-align="right"
+               error-message-align="right">
+        <!-- 鍩烘湰淇℃伅 -->
+        <u-cell-group title="鍩烘湰淇℃伅"
+                      class="form-section">
+          <up-form-item label="鍙戣揣鏂瑰紡"
+                        prop="type"
+                        required>
+            <up-input v-model="form.type"
+                      readonly
+                      placeholder="璇烽�夋嫨鍙戣揣鏂瑰紡"
+                      @click="showTypePicker = true" />
+            <template #right>
+              <up-icon name="arrow-right"
+                       @click="showTypePicker = true"></up-icon>
+            </template>
+          </up-form-item>
+          <block v-if="form.type === '璐ц溅'">
+            <up-form-item label="鍙戣揣杞︾墝"
+                          prop="shippingCarNumber"
+                          required>
+              <up-input v-model="form.shippingCarNumber"
+                        placeholder="璇疯緭鍏ュ彂璐ц溅鐗屽彿"
+                        clearable />
+            </up-form-item>
+          </block>
+          <block v-if="form.type === '蹇��'">
+            <up-form-item label="蹇�掑叕鍙�"
+                          prop="expressCompany"
+                          required>
+              <up-input v-model="form.expressCompany"
+                        placeholder="璇疯緭鍏ュ揩閫掑叕鍙�"
+                        clearable />
+            </up-form-item>
+            <up-form-item label="蹇�掑崟鍙�"
+                          prop="expressNumber"
+                          required>
+              <up-input v-model="form.expressNumber"
+                        placeholder="璇疯緭鍏ュ揩閫掑崟鍙�"
+                        clearable />
+            </up-form-item>
+          </block>
+        </u-cell-group>
+        <!-- 鎵规閫夋嫨 -->
+        <u-cell-group title="鎵规閫夋嫨"
+                      class="form-section">
+          <view class="section-header-info">
+            <text class="subtitle">寰呭彂璐ф暟閲�: {{ goOutData.noQuantity || 0 }}</text>
           </view>
-          <view class="approver-container">
-            <view v-if="step.nickName"
-                  class="approver-item">
-              <view class="approver-avatar">
-                <text class="avatar-text">{{ step.nickName.charAt(0) }}</text>
-                <view class="status-dot"></view>
+          <view v-if="batchList.length === 0"
+                class="empty-text">
+            <text>鏆傛棤鍙敤搴撳瓨鎵规</text>
+          </view>
+          <view v-else
+                class="batch-list">
+            <view v-for="(item, index) in batchList"
+                  :key="index"
+                  class="batch-card">
+              <view class="batch-header">
+                <text class="batch-no">鎵瑰彿: {{ item.batchNo }}</text>
+                <text class="batch-qty">搴撳瓨: {{ getAvailableQty(item) }}</text>
               </view>
-              <view class="approver-info">
-                <text class="approver-name">{{ step.nickName }}</text>
+              <up-divider></up-divider>
+              <view class="batch-body">
+                <up-form-item label="鍙戣揣鏁伴噺">
+                  <up-input v-model="item.deliveryQuantity"
+                            type="digit"
+                            placeholder="0.00"
+                            input-align="right"
+                            @blur="onBatchQtyChange(item)" />
+                </up-form-item>
               </view>
-              <view class="delete-approver-btn"
-                    @click="removeApprover(stepIndex)">脳</view>
-            </view>
-            <view v-else
-                  class="add-approver-btn"
-                  @click="addApprover(stepIndex)">
-              <view class="add-circle">+</view>
-              <text class="add-label">閫夋嫨瀹℃壒浜�</text>
             </view>
           </view>
-          <view class="step-line"
-                v-if="stepIndex < approverNodes.length - 1"></view>
-          <view class="delete-step-btn"
-                v-if="approverNodes.length > 1"
-                @click="removeApprovalStep(stepIndex)">鍒犻櫎鑺傜偣</view>
-        </view>
-      </view>
-      <view class="add-step-btn">
-        <u-button icon="plus"
-                  plain
-                  type="primary"
-                  style="width: 100%"
-                  @click="addApprovalStep">鏂板鑺傜偣</u-button>
-      </view>
+        </u-cell-group>
+        <!-- 鍙戣揣鍥剧墖 -->
+        <u-cell-group title="鍙戣揣鍥剧墖"
+                      class="form-section">
+          <view class="upload-container">
+            <up-upload :fileList="fileList"
+                       @afterRead="afterRead"
+                       @delete="deleteFile"
+                       multiple
+                       :maxCount="9"
+                       width="160rpx"
+                       height="160rpx" />
+          </view>
+        </u-cell-group>
+      </up-form>
     </view>
     <!-- 搴曢儴鎸夐挳 -->
-    <view class="footer-btns">
-      <u-button class="cancel-btn"
-                @click="goBack">鍙栨秷</u-button>
-      <u-button class="save-btn"
-                @click="submitForm">鍙戣揣</u-button>
-    </view>
+    <FooterButtons confirmText="纭鍙戣揣"
+                   @cancel="goBack"
+                   @confirm="submitForm" />
+    <!-- 鍙戣揣鏂瑰紡閫夋嫨鍣� -->
+    <up-action-sheet :show="showTypePicker"
+                     :actions="typeActions"
+                     title="鍙戣揣鏂瑰紡"
+                     @select="onTypeSelect"
+                     @close="showTypePicker = false" />
   </view>
 </template>
 
 <script setup>
-  import { ref, onMounted, onUnmounted, reactive, toRefs } from "vue";
+  import config from "@/config";
+  import { ref, onMounted, reactive } from "vue";
   import PageHeader from "@/components/PageHeader.vue";
+  import FooterButtons from "@/components/FooterButtons.vue";
   import { addShippingInfo } from "@/api/salesManagement/salesLedger";
-  const showToast = message => {
-    uni.showToast({
-      title: message,
-      icon: "none",
-    });
-  };
-  import { userListNoPageByTenantId } from "@/api/system/user";
+  import { getStockInventoryByModelId } from "@/api/inventoryManagement/stockInventory";
+  import { getToken } from "@/utils/auth";
 
-  const data = reactive({
-    form: {
-      approveTime: "",
-      approveId: "",
-      approveUser: "",
-      approveUserName: "",
-      approveDeptName: "",
-      approveDeptId: "",
-      approveReason: "",
-      checkResult: "",
-      tempFileIds: [],
-      approverList: [], // 鏂板瀛楁锛屽瓨鍌ㄦ墍鏈夎妭鐐圭殑瀹℃壒浜篿d
-      startDate: "",
-      endDate: "",
-      location: "",
-      price: "",
-    },
-    rules: {
-      typeValue: [{ required: false, message: "璇烽�夋嫨", trigger: "change" }],
-    },
-  });
-  const { form, rules } = toRefs(data);
-  const showPicker = ref(false);
-  const productOptions = ref([
-    {
-      value: "璐ц溅",
-      name: "璐ц溅",
-    },
-    {
-      value: "蹇��",
-      name: "蹇��",
-    },
-  ]);
-  const operationType = ref("");
-  const currentApproveStatus = ref("");
-  const approverNodes = ref([]);
-  const userList = ref([]);
-  const formRef = ref(null);
-  const approveType = ref(0);
   const goOutData = ref({});
+  const batchList = ref([]);
+  const fileList = ref([]);
+  const showTypePicker = ref(false);
+  const typeActions = [
+    { name: "璐ц溅", value: "璐ц溅" },
+    { name: "蹇��", value: "蹇��" },
+  ];
+
+  const form = reactive({
+    type: "璐ц溅",
+    shippingCarNumber: "",
+    expressCompany: "",
+    expressNumber: "",
+  });
+
+  const rules = {
+    type: [{ required: true, message: "璇烽�夋嫨鍙戣揣鏂瑰紡", trigger: "change" }],
+    shippingCarNumber: [
+      {
+        required: true,
+        validator: (rule, value, callback) => {
+          if (form.type === "璐ц溅" && !value) {
+            return false;
+          }
+          return true;
+        },
+        message: "璇疯緭鍏ヨ溅鐗屽彿",
+        trigger: "blur",
+      },
+    ],
+    expressCompany: [
+      {
+        required: true,
+        validator: (rule, value, callback) => {
+          if (form.type === "蹇��" && !value) {
+            return false;
+          }
+          return true;
+        },
+        message: "璇疯緭鍏ュ揩閫掑叕鍙�",
+        trigger: "blur",
+      },
+    ],
+    expressNumber: [
+      {
+        required: true,
+        validator: (rule, value, callback) => {
+          if (form.type === "蹇��" && !value) {
+            return false;
+          }
+          return true;
+        },
+        message: "璇疯緭鍏ュ揩閫掑崟鍙�",
+        trigger: "blur",
+      },
+    ],
+  };
+
+  const formRef = ref(null);
+
   onMounted(async () => {
-    try {
-      userListNoPageByTenantId().then(res => {
-        userList.value = res.data;
-      });
-      // 浠庢湰鍦板瓨鍌ㄨ幏鍙栧彂璐ц鎯�
-      goOutData.value = JSON.parse(uni.getStorageSync("goOutData"));
-      console.log(goOutData.value, "goOutData.value");
-
-      // 鍒濆鍖栧鎵规祦绋嬭妭鐐癸紝榛樿涓�涓妭鐐�
-      approverNodes.value = [{ id: 1, userId: null }];
-
-      // 鐩戝惉鑱旂郴浜洪�夋嫨浜嬩欢
-      uni.$on("selectContact", handleSelectContact);
-    } catch (error) {
-      console.error("鑾峰彇澶辫触:", error);
+    const storedData = uni.getStorageSync("goOutData");
+    goOutData.value = JSON.parse(storedData || "{}");
+    if (goOutData.value.productModelId) {
+      loadBatches(goOutData.value.productModelId);
     }
   });
 
-  onUnmounted(() => {
-    // 绉婚櫎浜嬩欢鐩戝惉
-    uni.$off("selectContact", handleSelectContact);
-  });
-  const typeValue = ref("璐ц溅");
-  const onConfirm = item => {
-    // 璁剧疆閫変腑鐨勯儴闂�
-    typeValue.value = item.name;
-    showPicker.value = false;
+  const loadBatches = async modelId => {
+    if (!modelId) return;
+    try {
+      const res = await getStockInventoryByModelId(modelId);
+      const rawList = Array.isArray(res?.data)
+        ? res.data
+        : res?.data?.records || res?.data?.rows || res || [];
+      const seenIds = new Set();
+      batchList.value = rawList
+        .filter(item => {
+          if (!item?.id || !item?.batchNo || seenIds.has(item.id)) {
+            return false;
+          }
+          seenIds.add(item.id);
+          return true;
+        })
+        .map(item => ({
+          ...item,
+          deliveryQuantity: "",
+        }));
+    } catch (e) {
+      console.error("鍔犺浇鎵规澶辫触", e);
+    }
   };
 
-  const goBack = () => {
-    // 娓呴櫎鏈湴瀛樺偍鐨勬暟鎹�
-    uni.removeStorageSync("operationType");
-    uni.removeStorageSync("invoiceLedgerEditRow");
-    uni.removeStorageSync("approveType");
-    uni.navigateBack();
+  const getAvailableQty = item => {
+    const quantity =
+      item?.qualitity ??
+      item?.quantity ??
+      item?.unLockedQuantity ??
+      item?.qualifiedUnLockedQuantity ??
+      item?.qualifiedQuantity ??
+      item?.stockQuantity;
+    return quantity ?? 0;
   };
 
-  const submitForm = () => {
-    // 妫�鏌ユ瘡涓鎵规楠ゆ槸鍚﹂兘鏈夊鎵逛汉
-    const hasEmptyStep = approverNodes.value.some(step => !step.nickName);
-    if (hasEmptyStep) {
-      showToast("璇蜂负姣忎釜瀹℃壒姝ラ閫夋嫨瀹℃壒浜�");
+  const onBatchQtyChange = item => {
+    const val = parseFloat(item.deliveryQuantity);
+    if (isNaN(val) || val <= 0) {
+      item.deliveryQuantity = "";
       return;
     }
-    formRef.value
-      .validate()
-      .then(valid => {
-        if (valid) {
-          // 琛ㄥ崟鏍¢獙閫氳繃锛屽彲浠ユ彁浜ゆ暟鎹�
-          // 鏀堕泦鎵�鏈夎妭鐐圭殑瀹℃壒浜篿d
-          console.log("approverNodes---", approverNodes.value);
-          const approveUserIds = approverNodes.value
-            .map(node => node.userId)
-            .join(",");
-          const params = {
-            salesLedgerId: goOutData.value.salesLedgerId,
-            salesLedgerProductId: goOutData.value.id,
-            type: typeValue.value,
-            approveUserIds,
-          };
-          console.log(params, "params");
 
-          addShippingInfo(params).then(res => {
-            showToast("鍙戣揣鎴愬姛");
-            setTimeout(() => {
-              goBack();
-            }, 500);
-          });
-        }
-      })
-      .catch(error => {
-        console.error("琛ㄥ崟鏍¢獙澶辫触:", error);
-        // 灏濊瘯鑾峰彇鍏蜂綋鐨勯敊璇瓧娈�
-        if (error && error.errors) {
-          const firstError = error.errors[0];
-          if (firstError) {
-            uni.showToast({
-              title: firstError.message || "琛ㄥ崟鏍¢獙澶辫触锛岃妫�鏌ュ繀濉」",
-              icon: "none",
-            });
-            return;
+    const available = getAvailableQty(item);
+    if (val > available) {
+      uni.showToast({ title: "涓嶈兘瓒呰繃搴撳瓨鏁伴噺", icon: "none" });
+      item.deliveryQuantity = available.toString();
+    }
+
+    const totalToShip = Number(goOutData.value.noQuantity || 0);
+    const otherBatchesTotal = batchList.value.reduce((sum, b) => {
+      if (b.id === item.id) return sum;
+      return sum + Number(b.deliveryQuantity || 0);
+    }, 0);
+
+    if (val + otherBatchesTotal > totalToShip) {
+      uni.showToast({ title: "鎬绘暟涓嶈兘瓒呰繃寰呭彂璐ф暟閲�", icon: "none" });
+      item.deliveryQuantity = (totalToShip - otherBatchesTotal).toString();
+    }
+  };
+
+  const onTypeSelect = item => {
+    form.type = item.name;
+    showTypePicker.value = false;
+  };
+
+  const afterRead = async event => {
+    const { file } = event;
+    const lists = [].concat(file);
+    const token = getToken();
+
+    for (let i = 0; i < lists.length; i++) {
+      const item = lists[i];
+      const uploadIndex = fileList.value.length;
+      fileList.value.push({
+        ...item,
+        status: "uploading",
+        message: "涓婁紶涓�",
+      });
+
+      uni.uploadFile({
+        url: config.baseUrl + "/common/upload",
+        filePath: item.url,
+        name: "files",
+        header: {
+          Authorization: "Bearer " + token,
+        },
+        success: res => {
+          try {
+            const data = JSON.parse(res.data);
+            if (data.code === 200) {
+              const fileData = Array.isArray(data.data)
+                ? data.data[0]
+                : data.data || data;
+              fileList.value[uploadIndex].status = "success";
+              fileList.value[uploadIndex].message = "";
+              fileList.value[uploadIndex].url = fileData.url;
+              fileList.value[uploadIndex].storageBlobDTO = fileData;
+            } else {
+              fileList.value[uploadIndex].status = "failed";
+              fileList.value[uploadIndex].message = data.msg || "涓婁紶澶辫触";
+            }
+          } catch (e) {
+            fileList.value[uploadIndex].status = "failed";
+            fileList.value[uploadIndex].message = "瑙f瀽澶辫触";
           }
-        }
-        // 鏄剧ず閫氱敤閿欒淇℃伅
-        uni.showToast({
-          title: "琛ㄥ崟鏍¢獙澶辫触锛岃妫�鏌ュ繀濉」",
-          icon: "none",
-        });
+        },
+        fail: () => {
+          fileList.value[uploadIndex].status = "failed";
+          fileList.value[uploadIndex].message = "缃戠粶寮傚父";
+        },
       });
+    }
   };
 
-  // 澶勭悊鑱旂郴浜洪�夋嫨缁撴灉
-  const handleSelectContact = data => {
-    const { stepIndex, contact } = data;
-    // 灏嗛�変腑鐨勮仈绯讳汉璁剧疆涓哄搴斿鎵规楠ょ殑瀹℃壒浜�
-    approverNodes.value[stepIndex].userId = contact.userId;
-    approverNodes.value[stepIndex].nickName = contact.nickName;
+  const deleteFile = event => {
+    fileList.value.splice(event.index, 1);
   };
 
-  const addApprover = stepIndex => {
-    // 璺宠浆鍒拌仈绯讳汉閫夋嫨椤甸潰
-    uni.setStorageSync("stepIndex", stepIndex);
-    uni.navigateTo({
-      url: "/pages/cooperativeOffice/collaborativeApproval/contactSelect",
-    });
-  };
+  const goBack = () => uni.navigateBack();
 
-  const addApprovalStep = () => {
-    // 娣诲姞鏂扮殑瀹℃壒姝ラ
-    approverNodes.value.push({ userId: null, nickName: null });
-  };
+  const submitForm = async () => {
+    const valid = await formRef.value.validate().catch(() => false);
+    if (!valid) return;
 
-  const removeApprover = stepIndex => {
-    // 绉婚櫎瀹℃壒浜�
-    approverNodes.value[stepIndex].userId = null;
-    approverNodes.value[stepIndex].nickName = null;
-  };
+    const selectedBatches = batchList.value.filter(
+      b => parseFloat(b.deliveryQuantity) > 0
+    );
+    if (selectedBatches.length === 0) {
+      uni.showToast({ title: "璇疯嚦灏戝~鍐欎竴涓壒娆$殑鍙戣揣鏁伴噺", icon: "none" });
+      return;
+    }
 
-  const removeApprovalStep = stepIndex => {
-    // 纭繚鑷冲皯淇濈暀涓�涓鎵规楠�
-    if (approverNodes.value.length > 1) {
-      approverNodes.value.splice(stepIndex, 1);
-    } else {
-      uni.showToast({
-        title: "鑷冲皯闇�瑕佷竴涓鎵规楠�",
-        icon: "none",
-      });
+    // Check if any file is still uploading
+    if (fileList.value.some(f => f.status === "uploading")) {
+      uni.showToast({ title: "璇风瓑寰呭浘鐗囦笂浼犲畬鎴�", icon: "none" });
+      return;
+    }
+
+    const payload = {
+      salesLedgerId: goOutData.value.salesLedgerId,
+      salesLedgerProductId: goOutData.value.id,
+      type: form.type,
+      shippingCarNumber: form.type === "璐ц溅" ? form.shippingCarNumber : "",
+      expressCompany: form.type === "蹇��" ? form.expressCompany : "",
+      expressNumber: form.type === "蹇��" ? form.expressNumber : "",
+      storageBlobDTOs: fileList.value
+        .filter(f => f.status === "success")
+        .map(f => f.storageBlobDTO),
+      batchNo: selectedBatches.map(b => b.id),
+      batchNoDetailList: selectedBatches.map(b => ({
+        stockInventoryId: b.id,
+        batchNo: b.batchNo,
+        quantity: parseFloat(b.deliveryQuantity),
+        productModelId: goOutData.value.productModelId,
+      })),
+    };
+
+    try {
+      uni.showLoading({ title: "鎻愪氦涓�..." });
+      const res = await addShippingInfo(payload);
+      uni.hideLoading();
+      uni.showToast({ title: "鍙戣揣鎴愬姛" });
+      setTimeout(() => goBack(), 500);
+    } catch (e) {
+      uni.hideLoading();
+      uni.showToast({ title: "鍙戣揣澶辫触", icon: "none" });
     }
   };
 </script>
 
 <style scoped lang="scss">
   @import "@/static/scss/form-common.scss";
-
-  .approval-process {
-    background: #fff;
-    margin: 16px;
-    border-radius: 16px;
-    padding: 16px;
-    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
+  .shipment-page {
+    min-height: 100vh;
+    background: #f8f9fa;
+    padding-bottom: 100px;
   }
 
-  .approval-header {
-    margin-bottom: 16px;
+  .form-container {
+    padding: 12px 12px 0;
   }
 
-  .approval-title {
-    font-size: 16px;
-    font-weight: 600;
-    color: #333;
-    display: block;
-    margin-bottom: 4px;
-  }
-
-  .approval-desc {
-    font-size: 12px;
-    color: #999;
-  }
-
-  /* 鏍峰紡澧炲己涓衡�滅畝娲佸皬鍦嗗湀椋庢牸鈥� */
-  .approval-steps {
-    padding-left: 22px;
-    position: relative;
-
-    &::before {
-      content: "";
-      position: absolute;
-      left: 11px;
-      top: 40px;
-      bottom: 40px;
-      width: 2px;
-      background: linear-gradient(
-        to bottom,
-        #e6f7ff 0%,
-        #bae7ff 50%,
-        #91d5ff 100%
-      );
-      border-radius: 1px;
-    }
-  }
-
-  .approval-step {
-    position: relative;
-    margin-bottom: 24px;
-
-    &::before {
-      content: "";
-      position: absolute;
-      left: -18px;
-      top: 14px; // 浠� 8px 璋冩暣涓� 14px锛屼笌鏂囧瓧涓績瀵归綈
-      width: 12px;
-      height: 12px;
-      background: #fff;
-      border: 3px solid #006cfb;
-      border-radius: 50%;
-      z-index: 2;
-      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
-    }
-  }
-
-  .step-title {
-    top: 12px;
+  .form-section {
     margin-bottom: 12px;
-    position: relative;
-    margin-left: 6px;
-  }
-
-  .step-title text {
-    font-size: 14px;
-    color: #666;
-    background: #f0f0f0;
-    padding: 4px 12px;
     border-radius: 12px;
-    position: relative;
-    line-height: 1.4; // 纭繚鏂囧瓧琛岄珮涓�鑷�
+    overflow: hidden;
+    box-shadow: 0 2px 10px rgba(15, 35, 95, 0.05);
   }
 
-  .approver-item {
+  .section-header-info {
+    padding: 10px 18px;
+    background: #f8fbff;
     display: flex;
-    align-items: center;
-    background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
-    border-radius: 16px;
-    padding: 16px;
+    justify-content: flex-end;
+
+    .subtitle {
+      font-size: 13px;
+      color: #7a8599;
+    }
+  }
+
+  .batch-list {
+    padding: 12px;
+    display: flex;
+    flex-direction: column;
     gap: 12px;
-    position: relative;
-    border: 1px solid #e6f7ff;
-    box-shadow: 0 4px 12px rgba(0, 108, 251, 0.08);
-    transition: all 0.3s ease;
   }
 
-  .approver-avatar {
-    width: 48px;
-    height: 48px;
-    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-    border-radius: 50%;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    position: relative;
-    box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
-  }
-
-  .avatar-text {
-    color: #fff;
-    font-size: 18px;
-    font-weight: 600;
-    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
-  }
-
-  .approver-info {
-    flex: 1;
-    position: relative;
-  }
-
-  .approver-name {
-    display: block;
-    font-size: 16px;
-    color: #333;
-    font-weight: 500;
-    position: relative;
-  }
-
-  .approver-dept {
-    font-size: 12px;
-    color: #999;
-    background: rgba(0, 108, 251, 0.05);
-    padding: 2px 8px;
-    border-radius: 8px;
-    display: inline-block;
-    position: relative;
-
-    &::before {
-      content: "";
-      position: absolute;
-      left: 4px;
-      top: 50%;
-      transform: translateY(-50%);
-      width: 2px;
-      height: 2px;
-      background: #006cfb;
-      border-radius: 50%;
-    }
-  }
-
-  .delete-approver-btn {
-    font-size: 16px;
-    color: #ff4d4f;
-    background: linear-gradient(
-      135deg,
-      rgba(255, 77, 79, 0.1) 0%,
-      rgba(255, 77, 79, 0.05) 100%
-    );
-    width: 28px;
-    height: 28px;
-    border-radius: 50%;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    transition: all 0.3s ease;
-    position: relative;
-  }
-
-  .add-approver-btn {
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    background: linear-gradient(135deg, #f0f8ff 0%, #e6f7ff 100%);
-    border: 2px dashed #006cfb;
-    border-radius: 16px;
-    padding: 20px;
-    color: #006cfb;
-    font-size: 14px;
-    position: relative;
-    transition: all 0.3s ease;
-
-    &::before {
-      content: "";
-      position: absolute;
-      left: 50%;
-      top: 50%;
-      transform: translate(-50%, -50%);
-      width: 32px;
-      height: 32px;
-      border: 2px solid #006cfb;
-      border-radius: 50%;
-      opacity: 0;
-      transition: all 0.3s ease;
-    }
-  }
-
-  .delete-step-btn {
-    color: #ff4d4f;
-    font-size: 12px;
-    background: linear-gradient(
-      135deg,
-      rgba(255, 77, 79, 0.1) 0%,
-      rgba(255, 77, 79, 0.05) 100%
-    );
-    padding: 6px 12px;
-    border-radius: 12px;
-    display: inline-block;
-    position: relative;
-    transition: all 0.3s ease;
-
-    &::before {
-      content: "";
-      position: absolute;
-      left: 6px;
-      top: 50%;
-      transform: translateY(-50%);
-      width: 4px;
-      height: 4px;
-      background: #ff4d4f;
-      border-radius: 50%;
-    }
-  }
-
-  .step-line {
-    display: none; // 闅愯棌鍘熸潵鐨勭嚎鏉★紝浣跨敤浼厓绱犱唬鏇�
-  }
-
-  .add-step-btn {
-    display: flex;
-    align-items: center;
-    justify-content: center;
-  }
-  .footer-btns {
-    position: fixed;
-    left: 0;
-    right: 0;
-    bottom: 0;
+  .batch-card {
     background: #fff;
+    border-radius: 12px;
+    padding: 0 12px 12px;
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+    border: 1px solid #f0f3f7;
+  }
+
+  .batch-header {
+    padding: 12px 0;
     display: flex;
-    justify-content: space-around;
+    justify-content: space-between;
     align-items: center;
-    padding: 0.75rem 0;
-    box-shadow: 0 -0.125rem 0.5rem rgba(0, 0, 0, 0.05);
-    z-index: 1000;
-  }
 
-  .cancel-btn {
-    font-weight: 400;
-    font-size: 1rem;
-    color: #ffffff;
-    width: 6.375rem;
-    background: #c7c9cc;
-    box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
-    border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
-  }
-
-  .save-btn {
-    font-weight: 400;
-    font-size: 1rem;
-    color: #ffffff;
-    width: 14rem;
-    background: linear-gradient(140deg, #00baff 0%, #006cfb 100%);
-    box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
-    border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
-  }
-
-  // 鍔ㄧ敾瀹氫箟
-  @keyframes pulse {
-    0% {
-      transform: scale(1);
-      opacity: 1;
+    .batch-no {
+      font-size: 14px;
+      font-weight: 600;
+      color: #22324d;
     }
-    50% {
-      transform: scale(1.2);
-      opacity: 0.7;
-    }
-    100% {
-      transform: scale(1);
-      opacity: 1;
+
+    .batch-qty {
+      font-size: 13px;
+      color: #2979ff;
+      background: #eef6ff;
+      padding: 2px 8px;
+      border-radius: 4px;
     }
   }
 
-  @keyframes rotate {
-    0% {
-      transform: rotate(0deg);
-    }
-    100% {
-      transform: rotate(360deg);
-    }
-  }
-
-  @keyframes ripple {
-    0% {
-      transform: translate(-50%, -50%) scale(0.8);
-      opacity: 1;
-    }
-    100% {
-      transform: translate(-50%, -50%) scale(1.6);
-      opacity: 0;
-    }
-  }
-
-  /* 濡傛灉宸叉湁 .step-line锛岃繖閲屾洿绮惧噯瀹氫綅鍒板乏渚т笌灏忓渾鐐瑰榻� */
-  .step-line {
-    position: absolute;
-    left: 4px;
-    top: 48px;
-    width: 2px;
-    height: calc(100% - 48px);
-    background: #e5e7eb;
-  }
-
-  .approver-container {
-    display: flex;
-    align-items: center;
-    background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
-    border-radius: 16px;
-    gap: 12px;
-    padding: 10px 0;
-    background: transparent;
-    border: none;
-    box-shadow: none;
-  }
-
-  .approver-item {
-    display: flex;
-    align-items: center;
-    gap: 12px;
-    padding: 8px 10px;
-    background: transparent;
-    border: none;
-    box-shadow: none;
-    border-radius: 0;
-  }
-
-  .approver-avatar {
-    position: relative;
-    width: 40px;
-    height: 40px;
-    border-radius: 50%;
-    background: #f3f4f6;
-    border: 2px solid #e5e7eb;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    animation: none; /* 绂佺敤鏃嬭浆绛夊姩鐢伙紝鍥炲綊绠�娲� */
-  }
-
-  .avatar-text {
-    font-size: 14px;
-    color: #374151;
-    font-weight: 600;
-  }
-
-  .add-approver-btn {
-    display: flex;
-    align-items: center;
-    gap: 8px;
-    background: transparent;
-    border: none;
-    box-shadow: none;
-    padding: 0;
-  }
-
-  .add-approver-btn .add-circle {
-    width: 40px;
-    height: 40px;
-    border: 2px dashed #a0aec0;
-    border-radius: 50%;
-    color: #6b7280;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    font-size: 22px;
-    line-height: 1;
-  }
-
-  .add-approver-btn .add-label {
-    color: #3b82f6;
+  .empty-text {
+    padding: 30px 12px;
+    text-align: center;
+    color: #999;
     font-size: 14px;
   }
-</style>
\ No newline at end of file
+
+  .upload-container {
+    padding: 12px 18px;
+  }
+
+  :deep(.u-cell-group__title) {
+    padding: 14px 18px 10px !important;
+    font-size: 15px !important;
+    font-weight: 600 !important;
+    color: #22324d !important;
+    background: #f8fbff !important;
+  }
+
+  :deep(.u-form-item) {
+    padding: 0 18px !important;
+  }
+</style>
diff --git a/src/pages/sales/salesQuotation/detail.vue b/src/pages/sales/salesQuotation/detail.vue
index a273974..45c3fd6 100644
--- a/src/pages/sales/salesQuotation/detail.vue
+++ b/src/pages/sales/salesQuotation/detail.vue
@@ -1,7 +1,7 @@
 <template>
   <view class="customer-detail-page">
-    <PageHeader title="鎶ヤ环璇︽儏" @back="goBack" />
-
+    <PageHeader title="鎶ヤ环璇︽儏"
+                @back="goBack" />
     <view class="detail-content">
       <view class="section">
         <view class="section-title">鍩虹淇℃伅</view>
@@ -44,24 +44,13 @@
           </view>
         </view>
       </view>
-
-      <view class="section">
-        <view class="section-title">瀹℃壒鑺傜偣</view>
-        <view v-if="approverNames.length" class="info-list">
-          <view v-for="(name, index) in approverNames" :key="index" class="info-item">
-            <text class="info-label">瀹℃壒鑺傜偣 {{ index + 1 }}</text>
-            <text class="info-value">{{ name }}</text>
-          </view>
-        </view>
-        <view v-else class="empty-box">
-          <text>鏆傛棤瀹℃壒鑺傜偣</text>
-        </view>
-      </view>
-
       <view class="section">
         <view class="section-title">浜у搧鏄庣粏</view>
-        <view v-if="detailData.products && detailData.products.length > 0" class="product-list">
-          <view v-for="(item, index) in detailData.products" :key="index" class="product-card">
+        <view v-if="detailData.products && detailData.products.length > 0"
+              class="product-list">
+          <view v-for="(item, index) in detailData.products"
+                :key="index"
+                class="product-card">
             <view class="product-head">浜у搧 {{ index + 1 }}</view>
             <view class="info-item">
               <text class="info-label">浜у搧鍚嶇О</text>
@@ -89,13 +78,16 @@
             </view>
           </view>
         </view>
-        <view v-else class="empty-box">
+        <view v-else
+              class="empty-box">
           <text>鏆傛棤浜у搧鏄庣粏</text>
         </view>
       </view>
     </view>
-
-    <FooterButtons cancelText="杩斿洖" confirmText="缂栬緫" @cancel="goBack" @confirm="goEdit" />
+    <FooterButtons cancelText="杩斿洖"
+                   confirmText="缂栬緫"
+                   @cancel="goBack"
+                   @confirm="goEdit" />
   </view>
 </template>
 
@@ -108,29 +100,27 @@
   const quotationId = ref("");
   const detailData = ref({});
 
-  const approverNames = computed(() => {
-    const approverText = detailData.value.approveUserNames || detailData.value.approverNames || detailData.value.approveUserIds || "";
-    if (Array.isArray(approverText)) return approverText.filter(Boolean);
-    return String(approverText)
-      .split(",")
-      .map(item => item.trim())
-      .filter(Boolean);
-  });
-
   const goBack = () => {
     uni.navigateBack();
   };
 
   const goEdit = () => {
     if (!quotationId.value) return;
-    uni.navigateTo({ url: `/pages/sales/salesQuotation/edit?id=${quotationId.value}` });
+    uni.navigateTo({
+      url: `/pages/sales/salesQuotation/edit?id=${quotationId.value}`,
+    });
   };
 
   const formatAmount = amount => `楼${Number(amount || 0).toFixed(2)}`;
 
   const loadDetailFromStorage = () => {
     const cachedData = uni.getStorageSync("salesQuotationDetail");
-    detailData.value = cachedData || {};
+    if (cachedData && (cachedData.id === quotationId.value || cachedData.id === Number(quotationId.value))) {
+      detailData.value = cachedData;
+    } else {
+      detailData.value = cachedData || {};
+      console.warn("鏈壘鍒板搴旂殑鎶ヤ环鍗曠紦瀛樻暟鎹�");
+    }
   };
 
   onLoad(options => {
diff --git a/src/pages/sales/salesQuotation/edit.vue b/src/pages/sales/salesQuotation/edit.vue
index 940a8d9..bfcb930 100644
--- a/src/pages/sales/salesQuotation/edit.vue
+++ b/src/pages/sales/salesQuotation/edit.vue
@@ -1,173 +1,196 @@
 <template>
   <view class="account-detail">
-    <PageHeader :title="pageTitle" @back="goBack" />
-
+    <PageHeader :title="pageTitle"
+                @back="goBack" />
     <view class="form-container">
-      <up-form
-        ref="formRef"
-        :model="form"
-        :rules="rules"
-        label-width="110"
-        input-align="right"
-        error-message-align="right"
-      >
-        <u-cell-group title="鍩虹淇℃伅" class="form-section">
-          <up-form-item label="瀹㈡埛鍚嶇О" prop="customer" required>
-            <up-input v-model="form.customer" placeholder="璇烽�夋嫨瀹㈡埛" readonly @click="showCustomerSheet = true" />
+      <up-form ref="formRef"
+               :model="form"
+               :rules="rules"
+               label-width="110"
+               input-align="right"
+               error-message-align="right">
+        <u-cell-group title="鍩虹淇℃伅"
+                      class="form-section">
+          <up-form-item label="瀹㈡埛鍚嶇О"
+                        prop="customer"
+                        required>
+            <up-input v-model="form.customer"
+                      placeholder="璇烽�夋嫨瀹㈡埛"
+                      readonly
+                      @click="showCustomerSheet = true" />
             <template #right>
-              <up-icon name="arrow-right" @click="showCustomerSheet = true"></up-icon>
+              <up-icon name="arrow-right"
+                       @click="showCustomerSheet = true"></up-icon>
             </template>
           </up-form-item>
-          <up-form-item label="涓氬姟鍛�" prop="salesperson" required>
-            <up-input
-              v-model="form.salesperson"
-              placeholder="璇烽�夋嫨涓氬姟鍛�"
-              readonly
-              @click="showSalespersonSheet = true"
-            />
+          <up-form-item label="涓氬姟鍛�"
+                        prop="salesperson"
+                        required>
+            <up-input v-model="form.salesperson"
+                      placeholder="璇烽�夋嫨涓氬姟鍛�"
+                      readonly
+                      @click="showSalespersonSheet = true" />
             <template #right>
-              <up-icon name="arrow-right" @click="showSalespersonSheet = true"></up-icon>
+              <up-icon name="arrow-right"
+                       @click="showSalespersonSheet = true"></up-icon>
             </template>
           </up-form-item>
-          <up-form-item label="鎶ヤ环鏃ユ湡" prop="quotationDate" required>
-            <up-input
-              v-model="form.quotationDate"
-              placeholder="璇烽�夋嫨鎶ヤ环鏃ユ湡"
-              readonly
-              @click="showQuotationDatePicker = true"
-            />
+          <up-form-item label="鎶ヤ环鏃ユ湡"
+                        prop="quotationDate"
+                        required>
+            <up-input v-model="form.quotationDate"
+                      placeholder="璇烽�夋嫨鎶ヤ环鏃ユ湡"
+                      readonly
+                      @click="showQuotationDatePicker = true" />
             <template #right>
-              <up-icon name="arrow-right" @click="showQuotationDatePicker = true"></up-icon>
+              <up-icon name="arrow-right"
+                       @click="showQuotationDatePicker = true"></up-icon>
             </template>
           </up-form-item>
-          <up-form-item label="鏈夋晥鏈熻嚦" prop="validDate" required>
-            <up-input
-              v-model="form.validDate"
-              placeholder="璇烽�夋嫨鏈夋晥鏈�"
-              readonly
-              @click="showValidDatePicker = true"
-            />
+          <up-form-item label="鏈夋晥鏈熻嚦"
+                        prop="validDate"
+                        required>
+            <up-input v-model="form.validDate"
+                      placeholder="璇烽�夋嫨鏈夋晥鏈�"
+                      readonly
+                      @click="showValidDatePicker = true" />
             <template #right>
-              <up-icon name="arrow-right" @click="showValidDatePicker = true"></up-icon>
+              <up-icon name="arrow-right"
+                       @click="showValidDatePicker = true"></up-icon>
             </template>
           </up-form-item>
-          <up-form-item label="浠樻鏂瑰紡" prop="paymentMethod" required>
-            <up-input v-model="form.paymentMethod" placeholder="璇疯緭鍏ヤ粯娆炬柟寮�" clearable />
+          <up-form-item label="浠樻鏂瑰紡"
+                        prop="paymentMethod"
+                        required>
+            <up-input v-model="form.paymentMethod"
+                      placeholder="璇疯緭鍏ヤ粯娆炬柟寮�"
+                      clearable />
           </up-form-item>
-          <up-form-item label="澶囨敞" prop="remark">
-            <up-textarea v-model="form.remark" placeholder="璇疯緭鍏ュ娉�" auto-height />
+          <up-form-item label="澶囨敞"
+                        prop="remark">
+            <up-textarea v-model="form.remark"
+                         placeholder="璇疯緭鍏ュ娉�"
+                         auto-height />
           </up-form-item>
         </u-cell-group>
-
-        <u-cell-group title="瀹℃壒鑺傜偣" class="form-section">
+        <u-cell-group title="浜у搧淇℃伅"
+                      class="form-section">
           <view class="section-tools">
-            <up-button type="primary" size="small" text="鏂板鑺傜偣" @click="addApproverNode" />
+            <up-button type="primary"
+                       size="small"
+                       text="鏂板浜у搧"
+                       @click="addProduct" />
           </view>
-          <view v-if="salespersonList.length === 0" class="empty-text">
-            <text>鏆傛棤鍙�夊鎵逛汉锛岃妫�鏌ョ敤鎴锋暟鎹�</text>
-          </view>
-          <view class="node-list">
-            <view v-for="(node, index) in approverNodes" :key="node.id" class="node-card">
-              <view class="node-top">
-                <text class="node-title">瀹℃壒鑺傜偣 {{ index + 1 }}</text>
-                <up-icon
-                  v-if="approverNodes.length > 1"
-                  name="trash"
-                  color="#ee0a24"
-                  size="18"
-                  @click="removeApproverNode(index)"
-                ></up-icon>
-              </view>
-              <view class="picker-field" @click="openApproverPicker(index)">
-                <up-input :model-value="node.nickName || ''" placeholder="璇烽�夋嫨瀹℃壒浜�" readonly disabled />
-                <up-icon name="arrow-right" color="#909399" size="16"></up-icon>
-              </view>
-            </view>
-          </view>
-        </u-cell-group>
-
-        <u-cell-group title="浜у搧淇℃伅" class="form-section">
-          <view class="section-tools">
-            <up-button type="primary" size="small" text="鏂板浜у搧" @click="addProduct" />
-          </view>
-          <view v-if="form.products.length === 0" class="empty-text">
+          <view v-if="form.products.length === 0"
+                class="empty-text">
             <text>鏆傛棤浜у搧锛岃鍏堟坊鍔犱骇鍝�</text>
           </view>
-          <view v-else class="product-list">
-            <view v-for="(product, index) in form.products" :key="product.uid" class="product-card">
+          <view v-else
+                class="product-list">
+            <view v-for="(product, index) in form.products"
+                  :key="product.uid"
+                  class="product-card">
               <view class="product-header">
                 <text class="product-title">浜у搧 {{ index + 1 }}</text>
-                <up-icon name="trash" color="#ee0a24" size="18" @click="removeProduct(index)"></up-icon>
+                <up-icon name="trash"
+                         color="#ee0a24"
+                         size="18"
+                         @click="removeProduct(index)"></up-icon>
               </view>
               <up-divider></up-divider>
               <view class="product-body">
                 <up-form-item label="浜у搧鍚嶇О">
-                  <up-input
-                    v-model="product.product"
-                    placeholder="璇烽�夋嫨浜у搧"
-                    readonly
-                    @click="openProductPicker(index)"
-                  />
+                  <up-input v-model="product.product"
+                            placeholder="璇烽�夋嫨浜у搧"
+                            readonly
+                            @click="openProductPicker(index)" />
                   <template #right>
-                    <up-icon name="arrow-right" @click="openProductPicker(index)"></up-icon>
+                    <up-icon name="arrow-right"
+                             @click="openProductPicker(index)"></up-icon>
                   </template>
                 </up-form-item>
                 <up-form-item label="瑙勬牸鍨嬪彿">
-                  <up-input
-                    v-model="product.specification"
-                    placeholder="璇烽�夋嫨瑙勬牸鍨嬪彿"
-                    readonly
-                    @click="openModelPicker(index)"
-                  />
+                  <up-input v-model="product.ProductModel"
+                            placeholder="璇烽�夋嫨瑙勬牸鍨嬪彿"
+                            readonly
+                            @click="openModelPicker(index)" />
                   <template #right>
-                    <up-icon name="arrow-right" @click="openModelPicker(index)"></up-icon>
+                    <up-icon name="arrow-right"
+                             @click="openModelPicker(index)"></up-icon>
                   </template>
                 </up-form-item>
                 <up-form-item label="鍗曚綅">
-                  <up-input v-model="product.unit" placeholder="璇疯緭鍏ュ崟浣�" clearable />
+                  <up-input v-model="product.unit"
+                            placeholder="璇疯緭鍏ュ崟浣�"
+                            clearable />
                 </up-form-item>
                 <up-form-item label="鏁伴噺">
-                  <up-input
-                    v-model="product.quantity"
-                    type="number"
-                    placeholder="璇疯緭鍏ユ暟閲�"
-                    clearable
-                    @blur="calculateAmount(product)"
-                  />
+                  <up-input v-model="product.quantity"
+                            type="number"
+                            placeholder="璇疯緭鍏ユ暟閲�"
+                            clearable
+                            @blur="calculateAmount(product)" />
                 </up-form-item>
                 <up-form-item label="鍗曚环">
-                  <up-input
-                    v-model="product.unitPrice"
-                    type="number"
-                    placeholder="璇疯緭鍏ュ崟浠�"
-                    clearable
-                    @blur="calculateAmount(product)"
-                  />
+                  <up-input v-model="product.unitPrice"
+                            type="number"
+                            placeholder="璇疯緭鍏ュ崟浠�"
+                            clearable
+                            @blur="calculateAmount(product)" />
                 </up-form-item>
                 <up-form-item label="閲戦">
-                  <up-input :model-value="formatAmount(product.amount)" disabled placeholder="鑷姩璁$畻" />
+                  <up-input :model-value="formatAmount(product.amount)"
+                            disabled
+                            placeholder="鑷姩璁$畻" />
                 </up-form-item>
               </view>
             </view>
           </view>
         </u-cell-group>
-
-        <u-cell-group title="姹囨�讳俊鎭�" class="form-section">
+        <u-cell-group title="姹囨�讳俊鎭�"
+                      class="form-section">
           <up-form-item label="鎶ヤ环鎬婚">
-            <up-input :model-value="formatAmount(totalAmount)" disabled placeholder="鑷姩姹囨��" />
+            <up-input :model-value="formatAmount(totalAmount)"
+                      disabled
+                      placeholder="鑷姩姹囨��" />
           </up-form-item>
         </u-cell-group>
       </up-form>
     </view>
-
-    <FooterButtons :loading="loading" confirmText="淇濆瓨" @cancel="goBack" @confirm="handleSubmit" />
-
-    <up-action-sheet :show="showCustomerSheet" title="閫夋嫨瀹㈡埛" :actions="customerActions" @select="onSelectCustomer" @close="showCustomerSheet = false" />
-    <up-action-sheet :show="showSalespersonSheet" title="閫夋嫨涓氬姟鍛�" :actions="salespersonActions" @select="onSelectSalesperson" @close="showSalespersonSheet = false" />
-    <up-action-sheet :show="showProductSheet" title="閫夋嫨浜у搧" :actions="productActions" @select="onSelectProduct" @close="showProductSheet = false" />
-    <up-action-sheet :show="showModelSheet" title="閫夋嫨瑙勬牸鍨嬪彿" :actions="modelActions" @select="onSelectModel" @close="showModelSheet = false" />
-    <up-datetime-picker :show="showQuotationDatePicker" v-model="quotationDateValue" mode="date" @confirm="onQuotationDateConfirm" @cancel="showQuotationDatePicker = false" />
-    <up-datetime-picker :show="showValidDatePicker" v-model="validDateValue" mode="date" @confirm="onValidDateConfirm" @cancel="showValidDatePicker = false" />
+    <FooterButtons :loading="loading"
+                   confirmText="淇濆瓨"
+                   @cancel="goBack"
+                   @confirm="handleSubmit" />
+    <up-action-sheet :show="showCustomerSheet"
+                     title="閫夋嫨瀹㈡埛"
+                     :actions="customerActions"
+                     @select="onSelectCustomer"
+                     @close="showCustomerSheet = false" />
+    <up-action-sheet :show="showSalespersonSheet"
+                     title="閫夋嫨涓氬姟鍛�"
+                     :actions="salespersonActions"
+                     @select="onSelectSalesperson"
+                     @close="showSalespersonSheet = false" />
+    <up-action-sheet :show="showProductSheet"
+                     title="閫夋嫨浜у搧"
+                     :actions="productActions"
+                     @select="onSelectProduct"
+                     @close="showProductSheet = false" />
+    <up-action-sheet :show="showModelSheet"
+                     title="閫夋嫨瑙勬牸鍨嬪彿"
+                     :actions="modelActions"
+                     @select="onSelectModel"
+                     @close="showModelSheet = false" />
+    <up-datetime-picker :show="showQuotationDatePicker"
+                        v-model="quotationDateValue"
+                        mode="date"
+                        @confirm="onQuotationDateConfirm"
+                        @cancel="showQuotationDatePicker = false" />
+    <up-datetime-picker :show="showValidDatePicker"
+                        v-model="validDateValue"
+                        mode="date"
+                        @confirm="onValidDateConfirm"
+                        @cancel="showValidDatePicker = false" />
   </view>
 </template>
 
@@ -179,7 +202,11 @@
   import { formatDateToYMD } from "@/utils/ruoyi";
   import { modelList, productTreeList } from "@/api/basicData/product";
   import { userListNoPageByTenantId } from "@/api/system/user";
-  import { addQuotation, getCustomerList, getQuotationDetail, updateQuotation } from "@/api/salesManagement/salesQuotation";
+  import {
+    addQuotation,
+    getCustomerList,
+    updateQuotation,
+  } from "@/api/salesManagement/salesQuotation";
 
   const formRef = ref();
   const loading = ref(false);
@@ -199,47 +226,73 @@
   const modelActions = ref([]);
 
   let uidSeed = 1;
-  let nextApproverId = 2;
 
   const form = ref({
     id: undefined,
     quotationNo: "",
+    customerId: undefined,
     customer: "",
     salesperson: "",
     quotationDate: "",
     validDate: "",
     paymentMethod: "",
-    status: "寰呭鎵�",
+    status: "鑽夌",
     remark: "",
-    approveUserIds: "",
     products: [],
+    subtotal: 0,
+    freight: 0,
+    otherFee: 0,
+    discountRate: 0,
+    discountAmount: 0,
     totalAmount: 0,
   });
-
-  const approverNodes = ref([{ id: 1, userId: "", nickName: "" }]);
 
   const rules = {
     customer: [{ required: true, message: "璇烽�夋嫨瀹㈡埛", trigger: "change" }],
     salesperson: [{ required: true, message: "璇烽�夋嫨涓氬姟鍛�", trigger: "change" }],
-    quotationDate: [{ required: true, message: "璇烽�夋嫨鎶ヤ环鏃ユ湡", trigger: "change" }],
+    quotationDate: [
+      { required: true, message: "璇烽�夋嫨鎶ヤ环鏃ユ湡", trigger: "change" },
+    ],
     validDate: [{ required: true, message: "璇烽�夋嫨鏈夋晥鏈�", trigger: "change" }],
-    paymentMethod: [{ required: true, message: "璇疯緭鍏ヤ粯娆炬柟寮�", trigger: "blur" }],
+    paymentMethod: [
+      { required: true, message: "璇疯緭鍏ヤ粯娆炬柟寮�", trigger: "blur" },
+    ],
   };
 
   const pageTitle = computed(() => (quotationId.value ? "缂栬緫鎶ヤ环" : "鏂板鎶ヤ环"));
   const totalAmount = computed(() =>
-    Number((form.value.products || []).reduce((sum, item) => sum + Number(item.amount || 0), 0).toFixed(2))
+    Number(
+      (form.value.products || [])
+        .reduce((sum, item) => sum + Number(item.amount || 0), 0)
+        .toFixed(2)
+    )
   );
-  const customerActions = computed(() => customerList.value.map(item => ({ name: item.customerName, value: item.customerName })));
-  const salespersonActions = computed(() => salespersonList.value.map(item => ({ name: item.nickName, value: item.nickName })));
-  const productActions = computed(() => productList.value.map(item => ({ name: item.label, value: item.value, label: item.label })));
+  const customerActions = computed(() =>
+    customerList.value.map(item => ({
+      name: item.customerName,
+      value: item.id,
+    }))
+  );
+  const salespersonActions = computed(() =>
+    salespersonList.value.map(item => ({
+      name: item.nickName,
+      value: item.nickName,
+    }))
+  );
+  const productActions = computed(() =>
+    productList.value.map(item => ({
+      name: item.label,
+      value: item.value,
+      label: item.label,
+    }))
+  );
 
   const createEmptyProduct = () => ({
     uid: `p_${uidSeed++}`,
     productId: "",
     product: "",
-    specificationId: "",
-    specification: "",
+    productModelId: "",
+    ProductModel: "",
     unit: "",
     quantity: 1,
     unitPrice: 0,
@@ -254,7 +307,10 @@
         if (item.children && item.children.length) {
           walk(item.children);
         } else {
-          result.push({ label: item.label || item.productName || "", value: item.id || item.value });
+          result.push({
+            label: item.label || item.productName || "",
+            value: item.id || item.value,
+          });
         }
       });
     };
@@ -266,18 +322,12 @@
   const goBack = () => uni.navigateBack();
 
   const calculateAmount = product => {
-    product.amount = Number((Number(product.quantity || 0) * Number(product.unitPrice || 0)).toFixed(2));
+    product.amount = Number(
+      (Number(product.quantity || 0) * Number(product.unitPrice || 0)).toFixed(2)
+    );
     form.value.totalAmount = totalAmount.value;
   };
 
-  const addApproverNode = () => approverNodes.value.push({ id: nextApproverId++, userId: "", nickName: "" });
-  const removeApproverNode = index => approverNodes.value.splice(index, 1);
-  const openApproverPicker = index => {
-    uni.setStorageSync("stepIndex", index);
-    uni.navigateTo({
-      url: "/pages/cooperativeOffice/collaborativeApproval/contactSelect",
-    });
-  };
   const addProduct = () => form.value.products.push(createEmptyProduct());
   const removeProduct = index => {
     form.value.products.splice(index, 1);
@@ -285,8 +335,14 @@
   };
 
   const fetchModelOptions = async (productId, product) => {
-    const rows = await modelList({ id: productId }).catch(() => []);
-    product.modelOptions = Array.isArray(rows) ? rows : [];
+    try {
+      const res = await modelList({ id: productId });
+      const rows = res?.data?.records || res?.data || res?.records || res || [];
+      product.modelOptions = Array.isArray(rows) ? rows : [];
+    } catch (error) {
+      console.error("鑾峰彇瑙勬牸鍨嬪彿澶辫触:", error);
+      product.modelOptions = [];
+    }
   };
 
   const openProductPicker = index => {
@@ -300,7 +356,11 @@
       uni.showToast({ title: "璇峰厛閫夋嫨浜у搧", icon: "none" });
       return;
     }
-    modelActions.value = (current.modelOptions || []).map(item => ({ name: item.model, value: item.id, unit: item.unit }));
+    modelActions.value = (current.modelOptions || []).map(item => ({
+      name: item.model || item.specification,
+      value: item.id,
+      unit: item.unit,
+    }));
     if (!modelActions.value.length) {
       uni.showToast({ title: "鏆傛棤瑙勬牸鍨嬪彿", icon: "none" });
       return;
@@ -309,27 +369,21 @@
   };
 
   const onSelectCustomer = action => {
-    form.value.customer = action.value;
+    form.value.customerId = action.value;
+    form.value.customer = action.name;
     showCustomerSheet.value = false;
   };
   const onSelectSalesperson = action => {
     form.value.salesperson = action.value;
     showSalespersonSheet.value = false;
   };
-  const onSelectApprover = data => {
-    const { stepIndex, contact } = data || {};
-    if (stepIndex === undefined || !contact) return;
-    if (!approverNodes.value[stepIndex]) return;
-    approverNodes.value[stepIndex].userId = contact.userId;
-    approverNodes.value[stepIndex].nickName = contact.nickName;
-  };
   const onSelectProduct = action => {
     const current = form.value.products[currentProductIndex.value];
     if (!current) return;
     current.productId = action.value;
     current.product = action.label;
-    current.specificationId = "";
-    current.specification = "";
+    current.productModelId = "";
+    current.ProductModel = "";
     current.unit = "";
     current.modelOptions = [];
     showProductSheet.value = false;
@@ -338,8 +392,8 @@
   const onSelectModel = action => {
     const current = form.value.products[currentProductIndex.value];
     if (!current) return;
-    current.specificationId = action.value;
-    current.specification = action.name;
+    current.productModelId = action.value;
+    current.ProductModel = action.name;
     current.unit = action.unit || current.unit;
     showModelSheet.value = false;
   };
@@ -353,70 +407,114 @@
   };
 
   const fetchBaseOptions = async () => {
-      const [customers, users, productTree] = await Promise.all([
-        getCustomerList({ current: -1, size: -1 }).catch(() => ({})),
-        userListNoPageByTenantId().catch(() => ({})),
-        productTreeList().catch(() => []),
-      ]);
+    const [customers, users, productTree] = await Promise.all([
+      getCustomerList({ current: -1, size: -1 }).catch(() => ({})),
+      userListNoPageByTenantId().catch(() => ({})),
+      productTreeList().catch(() => []),
+    ]);
     customerList.value = customers?.data?.records || customers?.records || [];
     const userRows = users?.data || [];
     salespersonList.value = Array.isArray(userRows) ? userRows : [];
-    productList.value = flattenProductTree(Array.isArray(productTree) ? productTree : productTree?.data || []);
+    productList.value = flattenProductTree(
+      Array.isArray(productTree) ? productTree : productTree?.data || []
+    );
+  };
+
+  // 鏍规嵁鍚嶇О鍙嶆煡鑺傜偣 id锛屼究浜庝粎瀛樺悕绉版椂鐨勫弽鏄�
+  const findNodeIdByLabel = (nodes, label) => {
+    if (!label) return null;
+    for (let i = 0; i < nodes.length; i++) {
+      const node = nodes[i];
+      if (node.label === label) return node.value;
+      if (node.children && node.children.length > 0) {
+        const found = findNodeIdByLabel(node.children, label);
+        if (found !== null && found !== undefined) return found;
+      }
+    }
+    return null;
   };
 
   const normalizeProductRows = async rows => {
-    const normalized = await Promise.all((Array.isArray(rows) ? rows : []).map(async item => {
-      const row = {
-        uid: `p_${uidSeed++}`,
-        productId: item.productId || "",
-        product: item.product || item.productName || "",
-        specificationId: item.specificationId || "",
-        specification: item.specification || "",
-        unit: item.unit || "",
-        quantity: Number(item.quantity || 1),
-        unitPrice: Number(item.unitPrice || 0),
-        amount: Number(item.amount || 0),
-        modelOptions: [],
-      };
-      if (row.productId) await fetchModelOptions(row.productId, row);
-      return row;
-    }));
+    const normalized = await Promise.all(
+      (Array.isArray(rows) ? rows : []).map(async item => {
+        const productName = item.product || item.productName || "";
+        // 浼樺厛鐢� productId锛涘鏋滃彧鏈夊悕绉帮紝灏濊瘯鍙嶆煡 id 浠ヤ究閫夋嫨鍣ㄥ弽鏄�
+        let resolvedProductId =
+          item.productId ||
+          findNodeIdByLabel(productList.value, productName) ||
+          "";
+
+        const row = {
+          uid: `p_${uidSeed++}`,
+          productId: resolvedProductId,
+          product: productName,
+          productModelId: item.productModelId || "",
+          ProductModel: item.ProductModel || item.specification || "",
+          unit: item.unit || "",
+          quantity: Number(item.quantity || 1),
+          unitPrice: Number(item.unitPrice || 0),
+          amount: Number(item.amount || 0),
+          modelOptions: [],
+        };
+
+        if (row.productId) {
+          await fetchModelOptions(row.productId, row);
+          // 濡傛灉娌℃湁 productModelId 浣嗘湁 ProductModel 鍚嶇О锛屽皾璇曚粠 modelOptions 涓尮閰� ID
+          if (!row.productModelId && row.ProductModel) {
+            const foundModel = row.modelOptions.find(
+              m =>
+                m.model === row.ProductModel ||
+                m.specification === row.ProductModel
+            );
+            if (foundModel) {
+              row.productModelId = foundModel.id;
+              // 缁熶竴浣跨敤 modelOptions 涓殑瀛楁
+              row.ProductModel =
+                foundModel.model || foundModel.specification || row.ProductModel;
+              row.unit = foundModel.unit || row.unit;
+            }
+          }
+        }
+        return row;
+      })
+    );
     form.value.products = normalized;
   };
 
   const loadDetail = async () => {
     if (!quotationId.value) return;
-    uni.showLoading({ title: "鍔犺浇涓�...", mask: true });
-    try {
-      const res = await getQuotationDetail({ id: quotationId.value });
-      const data = res?.data || {};
+
+    // 鐩存帴浠庢湰鍦板瓨鍌ㄨ幏鍙栨暟鎹紝涓嶅啀璋冪敤璇︽儏鎺ュ彛
+    const cachedData = uni.getStorageSync("salesQuotationDetail");
+    if (
+      cachedData &&
+      (cachedData.id === quotationId.value ||
+        cachedData.id === Number(quotationId.value))
+    ) {
+      const data = cachedData;
       form.value = {
         ...form.value,
         id: data.id,
         quotationNo: data.quotationNo || "",
+        customerId: data.customerId,
         customer: data.customer || "",
         salesperson: data.salesperson || "",
         quotationDate: data.quotationDate || "",
         validDate: data.validDate || "",
         paymentMethod: data.paymentMethod || "",
-        status: data.status || "寰呭鎵�",
+        status: data.status || "鑽夌",
         remark: data.remark || "",
+        subtotal: data.subtotal || 0,
+        freight: data.freight || 0,
+        otherFee: data.otherFee || 0,
+        discountRate: data.discountRate || 0,
+        discountAmount: data.discountAmount || 0,
+        totalAmount: data.totalAmount || 0,
       };
       await normalizeProductRows(data.products || []);
-      if (data.approveUserIds) {
-        const ids = String(data.approveUserIds).split(",").map(item => item.trim()).filter(Boolean);
-        approverNodes.value = ids.map((userId, index) => ({
-          id: index + 1,
-          userId,
-          nickName: salespersonList.value.find(item => String(item.userId) === String(userId))?.nickName || "",
-        }));
-        nextApproverId = approverNodes.value.length + 1;
-      }
       form.value.totalAmount = totalAmount.value;
-    } catch {
-      uni.showToast({ title: "鑾峰彇璇︽儏澶辫触", icon: "error" });
-    } finally {
-      uni.hideLoading();
+    } else {
+      console.warn("鏈壘鍒扮紦瀛樼殑鎶ヤ环鍗曡鎯呮暟鎹�");
     }
   };
 
@@ -425,16 +523,16 @@
       uni.showToast({ title: "璇疯嚦灏戞坊鍔犱竴涓骇鍝�", icon: "none" });
       return false;
     }
-    const invalid = form.value.products.some(item => !item.productId || !item.specificationId || !item.unit || !Number(item.quantity) || !Number(item.unitPrice));
+    const invalid = form.value.products.some(
+      item =>
+        !item.productId ||
+        !item.productModelId ||
+        !item.unit ||
+        !Number(item.quantity) ||
+        !Number(item.unitPrice)
+    );
     if (invalid) {
       uni.showToast({ title: "璇峰畬鍠勪骇鍝佷俊鎭�", icon: "none" });
-      return false;
-    }
-    return true;
-  };
-  const validateApprovers = () => {
-    if (approverNodes.value.some(item => !item.userId)) {
-      uni.showToast({ title: "璇烽�夋嫨瀹℃壒浜�", icon: "none" });
       return false;
     }
     return true;
@@ -442,17 +540,20 @@
 
   const handleSubmit = async () => {
     const valid = await formRef.value.validate().catch(() => false);
-    if (!valid || !validateApprovers() || !validateProducts()) return;
+    if (!valid || !validateProducts()) return;
     loading.value = true;
+
+    // 鍚屾鏈�鏂扮殑鎬婚
+    form.value.totalAmount = totalAmount.value;
+    form.value.subtotal = totalAmount.value;
+
     const payload = {
       ...form.value,
-      approveUserIds: approverNodes.value.map(item => item.userId).join(","),
-      totalAmount: totalAmount.value,
       products: form.value.products.map(item => ({
         productId: item.productId,
         product: item.product,
-        specificationId: item.specificationId,
-        specification: item.specification,
+        productModelId: item.productModelId,
+        ProductModel: item.ProductModel,
         quantity: Number(item.quantity || 0),
         unit: item.unit,
         unitPrice: Number(item.unitPrice || 0),
@@ -486,16 +587,12 @@
 
   onMounted(async () => {
     await fetchBaseOptions();
-    uni.$on("selectContact", onSelectApprover);
     if (quotationId.value) {
       await loadDetail();
     }
   });
 
-  onUnmounted(() => {
-    uni.$off("selectContact", onSelectApprover);
-    uni.removeStorageSync("stepIndex");
-  });
+  onUnmounted(() => {});
 </script>
 
 <style scoped lang="scss">
@@ -547,7 +644,6 @@
     padding: 12px 12px 0;
   }
 
-  .node-list,
   .product-list {
     padding: 12px;
     display: flex;
@@ -555,31 +651,12 @@
     gap: 12px;
   }
 
-  .node-card {
-    background: #f8fbff;
-    border-radius: 12px;
-    padding: 12px;
-    border: 1px solid #e6eef8;
-  }
-
-  .picker-field {
-    display: flex;
-    align-items: center;
-    gap: 8px;
-  }
-
-  .picker-field :deep(.u-input) {
-    flex: 1;
-  }
-
-  .node-top,
   .product-header {
     display: flex;
     align-items: center;
     justify-content: space-between;
   }
 
-  .node-title,
   .product-title {
     font-size: 14px;
     font-weight: 600;
diff --git a/src/pages/sales/salesQuotation/index.vue b/src/pages/sales/salesQuotation/index.vue
index a6a5103..4ecf910 100644
--- a/src/pages/sales/salesQuotation/index.vue
+++ b/src/pages/sales/salesQuotation/index.vue
@@ -1,47 +1,50 @@
 <template>
   <view class="sales-account">
-    <PageHeader title="閿�鍞姤浠�" @back="goBack" />
-
+    <PageHeader title="閿�鍞姤浠�"
+                @back="goBack" />
     <view class="search-section">
       <view class="search-bar">
         <view class="search-input">
-          <up-input
-            class="search-text"
-            v-model="quotationNo"
-            placeholder="璇疯緭鍏ユ姤浠峰崟鍙锋悳绱�"
-            clearable
-            @change="getList"
-          />
+          <up-input class="search-text"
+                    v-model="quotationNo"
+                    placeholder="璇疯緭鍏ユ姤浠峰崟鍙锋悳绱�"
+                    clearable
+                    @change="getList" />
         </view>
-        <view class="filter-button" @click="getList">
-          <up-icon name="search" size="24" color="#999"></up-icon>
+        <view class="filter-button"
+              @click="getList">
+          <up-icon name="search"
+                   size="24"
+                   color="#999"></up-icon>
         </view>
       </view>
     </view>
-
     <view class="tabs-section">
-      <up-tabs
-        v-model="tabValue"
-        :list="tabList"
-        itemStyle="width: 20%;height: 80rpx;"
-        @change="onTabChange"
-      />
+      <up-tabs v-model="tabValue"
+               :list="tabList"
+               itemStyle="width: 20%;height: 80rpx;"
+               @change="onTabChange" />
     </view>
-
-    <view v-if="quotationList.length > 0" class="ledger-list">
-      <view v-for="item in quotationList" :key="item.id" class="ledger-item">
+    <view v-if="quotationList.length > 0"
+          class="ledger-list">
+      <view v-for="item in quotationList"
+            :key="item.id"
+            class="ledger-item">
         <view class="item-header">
           <view class="item-left">
             <view class="document-icon">
-              <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
+              <up-icon name="file-text"
+                       size="16"
+                       color="#ffffff"></up-icon>
             </view>
             <text class="item-id">{{ item.quotationNo || "-" }}</text>
           </view>
-          <text class="item-index">{{ item.status || "-" }}</text>
+          <up-tag :text="item.status || '寰呭鎵�'"
+                  :type="getStatusType(item.status)"
+                  size="mini"
+                  shape="circle" />
         </view>
-
         <up-divider></up-divider>
-
         <view class="item-details">
           <view class="detail-row">
             <text class="detail-label">瀹㈡埛鍚嶇О</text>
@@ -60,43 +63,45 @@
             <text class="detail-value">{{ item.validDate || "-" }}</text>
           </view>
           <view class="detail-row">
-            <text class="detail-label">浠樻鏂瑰紡</text>
-            <text class="detail-value">{{ item.paymentMethod || "-" }}</text>
-          </view>
-          <view class="detail-row">
             <text class="detail-label">鎶ヤ环閲戦</text>
             <text class="detail-value highlight">{{ formatAmount(item.totalAmount) }}</text>
           </view>
-          <view class="detail-row">
+          <view class="detail-row"
+                v-if="item.remark">
             <text class="detail-label">澶囨敞</text>
-            <text class="detail-value">{{ item.remark || "-" }}</text>
+            <text class="detail-value">{{ item.remark }}</text>
           </view>
         </view>
-
         <view class="action-buttons">
-					<up-button
-						class="action-btn"
-		        size="small"
-		        type="primary"
-		        :disabled="!canEdit(item)"
-		        @click="goEdit(item)"
-					>
-						缂栬緫
-					</up-button>
-          <up-button class="action-btn" size="small" @click="goDetail(item)">璇︽儏</up-button>
-          <up-button class="action-btn" size="small" type="error" plain @click="handleDelete(item)">
+          <up-button class="action-btn"
+                     size="small"
+                     type="primary"
+                     :disabled="!canEdit(item)"
+                     @click="goEdit(item)">
+            缂栬緫
+          </up-button>
+          <up-button class="action-btn"
+                     size="small"
+                     @click="goDetail(item)">璇︽儏</up-button>
+          <up-button class="action-btn"
+                     size="small"
+                     type="error"
+                     plain
+                     @click="handleDelete(item)">
             鍒犻櫎
           </up-button>
         </view>
       </view>
     </view>
-
-    <view v-else class="no-data">
+    <view v-else
+          class="no-data">
       <text>鏆傛棤閿�鍞姤浠锋暟鎹�</text>
     </view>
-
-    <view class="fab-button" @click="goAdd">
-      <up-icon name="plus" size="28" color="#ffffff"></up-icon>
+    <view class="fab-button"
+          @click="goAdd">
+      <up-icon name="plus"
+               size="28"
+               color="#ffffff"></up-icon>
     </view>
   </view>
 </template>
@@ -105,7 +110,10 @@
   import { reactive, ref } from "vue";
   import { onShow } from "@dcloudio/uni-app";
   import PageHeader from "@/components/PageHeader.vue";
-  import { deleteQuotation, getQuotationList } from "@/api/salesManagement/salesQuotation";
+  import {
+    deleteQuotation,
+    getQuotationList,
+  } from "@/api/salesManagement/salesQuotation";
 
   const quotationNo = ref("");
   const quotationList = ref([]);
@@ -129,11 +137,13 @@
   };
 
   const goAdd = () => {
+    uni.removeStorageSync("salesQuotationDetail");
     uni.navigateTo({ url: "/pages/sales/salesQuotation/edit" });
   };
 
   const goEdit = item => {
     if (!canEdit(item)) return;
+    uni.setStorageSync("salesQuotationDetail", item || {});
     uni.navigateTo({ url: `/pages/sales/salesQuotation/edit?id=${item.id}` });
   };
 
@@ -159,6 +169,16 @@
     return `楼${num.toFixed(2)}`;
   };
 
+  const getStatusType = status => {
+    const statusMap = {
+      寰呭鎵�: "info",
+      瀹℃牳涓�: "primary",
+      閫氳繃: "success",
+      鎷掔粷: "danger",
+    };
+    return statusMap[status] || "info";
+  };
+
   const getList = () => {
     uni.showLoading({ title: "鍔犺浇涓�...", mask: true });
     getQuotationList({

--
Gitblit v1.9.3