From 36c8ae70cae3de90e642b080553abe70d3345c74 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期一, 27 四月 2026 13:20:16 +0800
Subject: [PATCH] 天津宝东app 1.部署修改 2.按照web端逻辑修改销售报价和客户档案的逻辑

---
 src/pages/basicData/customerFile/edit.vue        |   80 ---
 src/api/salesManagement/salesQuotationProduct.js |   48 ++
 src/pages/works.vue                              |  170 +++----
 src/api/basicData/customerFile.js                |   94 +++
 src/pages/basicData/customerFile/detail.vue      |   38 -
 src/utils/versionUpgrade.js                      |    2 
 src/config.js                                    |    4 
 src/manifest.json                                |    4 
 src/pages/basicData/customerFile/index.vue       |   19 
 src/pages/sales/salesQuotation/detail.vue        |  176 +++----
 src/pages/sales/salesQuotation/edit.vue          |  551 ++++++++---------------
 src/pages/sales/salesQuotation/index.vue         |  170 +++----
 12 files changed, 576 insertions(+), 780 deletions(-)

diff --git a/src/api/basicData/customerFile.js b/src/api/basicData/customerFile.js
index 409161a..7b6d7c6 100644
--- a/src/api/basicData/customerFile.js
+++ b/src/api/basicData/customerFile.js
@@ -1,7 +1,5 @@
-// 瀹㈡埛妗f椤甸潰鎺ュ彛
 import request from '@/utils/request'
 
-// 鍒嗛〉鏌ヨ
 export function listCustomer(query) {
     return request({
         url: '/basic/customer/list',
@@ -9,14 +7,76 @@
         params: query
     })
 }
-// 鏌ヨ瀹㈡埛妗f璇︾粏
+
+// 瀹㈡埛妗f绉佹捣鏌ヨ
+export function listCustomerPrivatePool(query) {
+    return request({
+        url: '/customerPrivatePool/listPage',
+        method: 'get',
+        params: query
+    })
+}
+
+export function addCustomerPrivatePool(data) {
+    return request({
+        url: '/customerPrivatePool/add',
+        method: 'post',
+        data: data
+    })
+}
+
+export function addCustomerPrivate(data) {
+    return request({
+        url: '/customerPrivate/add',
+        method: 'post',
+        data: data
+    })
+}
+
+export function delCustomerPrivate(ids) {
+    return request({
+        url: '/customerPrivate/delete',
+        method: 'delete',
+        data: ids
+    })
+}
+
+export function delCustomerPrivatePool(id) {
+    return request({
+        url: '/customerPrivatePool/delete/' + id,
+        method: 'delete',
+    })
+}
+
+export function shareCustomer(data) {
+    return request({
+        url: '/customerPrivatePool/together',
+        method: 'post',
+        data: data
+    })
+}
+
 export function getCustomer(id) {
     return request({
         url: '/basic/customer/' + id,
         method: 'get'
     })
 }
-// 鏂板瀹㈡埛妗f
+
+export function getCustomerPrivatePoolById(id) {
+    return request({
+        url: '/customerPrivatePool/getbyId/' + id,
+        method: 'get'
+    })
+}
+
+export function getCustomerPrivatePoolInfo(id) {
+    return request({
+        url: '/customerPrivatePool/info/' + id,
+        method: 'get'
+    })
+}
+
 export function addCustomer(data) {
     return request({
         url: '/basic/customer/addCustomer',
@@ -24,7 +84,7 @@
         data: data
     })
 }
-// 淇敼瀹㈡埛妗f
+
 export function updateCustomer(data) {
     return request({
         url: '/basic/customer/updateCustomer',
@@ -32,7 +92,15 @@
         data: data
     })
 }
-// 瀵煎嚭瀹㈡埛妗f
+
+export function updateCustomerPrivatePool(data) {
+    return request({
+        url: '/customerPrivatePool/update',
+        method: 'put',
+        data: data
+    })
+}
+
 export function exportCustomer(query) {
     return request({
         url: '/basic/customer/export',
@@ -41,7 +109,7 @@
         responseType: 'blob'
     })
 }
-// 鍒犻櫎瀹㈡埛妗f
+
 export function delCustomer(ids) {
     return request({
         url: '/basic/customer/delCustomer',
@@ -50,8 +118,6 @@
     })
 }
 
-
-// 鏂板瀹㈡埛璺熻繘
 export function addCustomerFollow(data) {
     return request({
         url: '/basic/customer-follow/add',
@@ -60,7 +126,6 @@
     })
 }
 
-// 淇敼瀹㈡埛璺熻繘
 export function updateCustomerFollow(data) {
     return request({
         url: '/basic/customer-follow/edit',
@@ -68,15 +133,14 @@
         data: data,
     })
 }
-// 鍒犻櫎瀹㈡埛璺熻繘
+
 export function delCustomerFollow(id) {
     return request({
-        url: '/basic/customer-follow/'+id,
+        url: '/basic/customer-follow/' + id,
         method: 'delete',
     })
 }
 
-// 鍥炶鎻愰啋-鏂板/鏇存柊
 export function addReturnVisit(data) {
     return request({
         url: '/basic/customer-follow/return-visit',
@@ -84,10 +148,10 @@
         data: data
     })
 }
-// 鑾峰彇鍥炶鎻愰啋璇︽儏
+
 export function getReturnVisit(id) {
     return request({
         url: '/basic/customer-follow/return-visit/' + id,
         method: 'get'
     })
-}
\ No newline at end of file
+}
diff --git a/src/api/salesManagement/salesQuotationProduct.js b/src/api/salesManagement/salesQuotationProduct.js
new file mode 100644
index 0000000..99d60e0
--- /dev/null
+++ b/src/api/salesManagement/salesQuotationProduct.js
@@ -0,0 +1,48 @@
+import request from "@/utils/request";
+
+export function quotationProductListPage(query) {
+  return request({
+    url: "/sales/quotationProduct/listPage",
+    method: "get",
+    params: query,
+  });
+}
+
+export function quotationProductList(query) {
+  return request({
+    url: "/sales/quotationProduct/list",
+    method: "get",
+    params: query,
+  });
+}
+
+export function getQuotationProductInfo(id) {
+  return request({
+    url: `/sales/quotationProduct/${id}`,
+    method: "get",
+  });
+}
+
+export function addOrUpdateQuotationProduct(data) {
+  return request({
+    url: "/sales/quotationProduct/addOrUpdate",
+    method: "post",
+    data,
+  });
+}
+
+export function editQuotationProduct(data) {
+  return request({
+    url: "/sales/quotationProduct/edit",
+    method: "post",
+    data,
+  });
+}
+
+export function deleteQuotationProduct(ids) {
+  return request({
+    url: "/sales/quotationProduct/delete",
+    method: "delete",
+    data: ids,
+  });
+}
diff --git a/src/config.js b/src/config.js
index 42a7174..6d6c424 100644
--- a/src/config.js
+++ b/src/config.js
@@ -1,7 +1,7 @@
 // 搴旂敤鍏ㄥ眬閰嶇疆
 const config = {
-  baseUrl: "http://1.15.17.182:9003",
-  fileUrl: "http://1.15.17.182:9002",
+  baseUrl: "http://1.15.17.182:9046",
+  fileUrl: "http://1.15.17.182:9047",
   // 搴旂敤淇℃伅
   appInfo: {
     // 搴旂敤鍚嶇О
diff --git a/src/manifest.json b/src/manifest.json
index 3934c37..9f1214f 100644
--- a/src/manifest.json
+++ b/src/manifest.json
@@ -1,6 +1,6 @@
 {
-    "name" : "淇℃伅绠$悊",
-    "appid" : "__UNI__099A590",
+    "name" : "澶╂触瀹濅笢",
+    "appid" : "__UNI__FDF4041",
     "description" : "",
     "versionName" : "1.1.5",
     "versionCode" : 100,
diff --git a/src/pages/basicData/customerFile/detail.vue b/src/pages/basicData/customerFile/detail.vue
index 37fa67a..309a970 100644
--- a/src/pages/basicData/customerFile/detail.vue
+++ b/src/pages/basicData/customerFile/detail.vue
@@ -15,28 +15,12 @@
             <text class="info-value">{{ detailData.customerType || "-" }}</text>
           </view>
           <view class="info-item">
-            <text class="info-label">绾崇◣浜鸿瘑鍒彿</text>
-            <text class="info-value">{{ detailData.taxpayerIdentificationNumber || "-" }}</text>
-          </view>
-          <view class="info-item">
             <text class="info-label">鍏徃鍦板潃</text>
             <text class="info-value">{{ detailData.companyAddress || "-" }}</text>
           </view>
           <view class="info-item">
             <text class="info-label">鍏徃鐢佃瘽</text>
             <text class="info-value">{{ detailData.companyPhone || "-" }}</text>
-          </view>
-          <view class="info-item">
-            <text class="info-label">娉曚汉</text>
-            <text class="info-value">{{ detailData.corporation || "-" }}</text>
-          </view>
-          <view class="info-item">
-            <text class="info-label">浠g悊浜�</text>
-            <text class="info-value">{{ detailData.agent || "-" }}</text>
-          </view>
-          <view class="info-item">
-            <text class="info-label">浼犵湡</text>
-            <text class="info-value">{{ detailData.fax || "-" }}</text>
           </view>
         </view>
       </view>
@@ -52,27 +36,9 @@
             <text class="info-label">鑱旂郴鐢佃瘽</text>
             <text class="info-value">{{ detailData.contactPhone || "-" }}</text>
           </view>
-        </view>
-      </view>
-
-      <view class="section">
-        <view class="section-title">閾惰淇℃伅</view>
-        <view class="info-list">
           <view class="info-item">
-            <text class="info-label">閾惰鍩烘湰鎴�</text>
-            <text class="info-value">{{ detailData.basicBankAccount || "-" }}</text>
-          </view>
-          <view class="info-item">
-            <text class="info-label">閾惰璐﹀彿</text>
-            <text class="info-value">{{ detailData.bankAccount || "-" }}</text>
-          </view>
-          <view class="info-item">
-            <text class="info-label">寮�鎴烽摱琛�</text>
-            <text class="info-value">{{ detailData.bankName || "-" }}</text>
-          </view>
-          <view class="info-item">
-            <text class="info-label">寮�鎴疯鍙�</text>
-            <text class="info-value">{{ detailData.bankCode || "-" }}</text>
+            <text class="info-label">鑱旂郴浜哄矖浣�</text>
+            <text class="info-value">{{ detailData.contactPosition || "-" }}</text>
           </view>
         </view>
       </view>
diff --git a/src/pages/basicData/customerFile/edit.vue b/src/pages/basicData/customerFile/edit.vue
index c10973e..516ef2b 100644
--- a/src/pages/basicData/customerFile/edit.vue
+++ b/src/pages/basicData/customerFile/edit.vue
@@ -19,7 +19,7 @@
               clearable
             />
           </up-form-item>
-          <up-form-item label="瀹㈡埛鍒嗙被" prop="customerType" required>
+          <up-form-item label="瀹㈡埛鍒嗙被" prop="customerType">
             <up-input
               v-model="customerTypeText"
               placeholder="璇烽�夋嫨瀹㈡埛鍒嗙被"
@@ -30,48 +30,17 @@
               <up-icon name="arrow-right" @click="showCustomerTypeSheet = true"></up-icon>
             </template>
           </up-form-item>
-          <up-form-item
-            label="绾崇◣浜鸿瘑鍒彿"
-            prop="taxpayerIdentificationNumber"
-          >
-            <up-input
-              v-model="form.taxpayerIdentificationNumber"
-              placeholder="璇疯緭鍏ョ撼绋庝汉璇嗗埆鍙�"
-              clearable
-            />
-          </up-form-item>
-          <up-form-item label="鍏徃鍦板潃" prop="companyAddress">
+          <up-form-item label="鍏徃鍦板潃" prop="companyAddress" required>
             <up-input
               v-model="form.companyAddress"
               placeholder="璇疯緭鍏ュ叕鍙稿湴鍧�"
               clearable
             />
           </up-form-item>
-          <up-form-item label="鍏徃鐢佃瘽" prop="companyPhone">
+          <up-form-item label="鍏徃鐢佃瘽" prop="companyPhone" required>
             <up-input
               v-model="form.companyPhone"
               placeholder="璇疯緭鍏ュ叕鍙哥數璇�"
-              clearable
-            />
-          </up-form-item>
-          <up-form-item label="娉曚汉" prop="corporation">
-            <up-input
-              v-model="form.corporation"
-              placeholder="璇疯緭鍏ユ硶浜�"
-              clearable
-            />
-          </up-form-item>
-          <up-form-item label="浠g悊浜�" prop="agent">
-            <up-input
-              v-model="form.agent"
-              placeholder="璇疯緭鍏ヤ唬鐞嗕汉"
-              clearable
-            />
-          </up-form-item>
-          <up-form-item label="浼犵湡" prop="fax">
-            <up-input
-              v-model="form.fax"
-              placeholder="璇疯緭鍏ヤ紶鐪�"
               clearable
             />
           </up-form-item>
@@ -92,34 +61,10 @@
               clearable
             />
           </up-form-item>
-        </u-cell-group>
-
-        <u-cell-group title="閾惰淇℃伅" class="form-section">
-          <up-form-item label="閾惰鍩烘湰鎴�" prop="basicBankAccount">
+          <up-form-item label="鑱旂郴浜哄矖浣�" prop="contactPosition">
             <up-input
-              v-model="form.basicBankAccount"
-              placeholder="璇疯緭鍏ラ摱琛屽熀鏈埛"
-              clearable
-            />
-          </up-form-item>
-          <up-form-item label="閾惰璐﹀彿" prop="bankAccount">
-            <up-input
-              v-model="form.bankAccount"
-              placeholder="璇疯緭鍏ラ摱琛岃处鍙�"
-              clearable
-            />
-          </up-form-item>
-          <up-form-item label="寮�鎴烽摱琛�" prop="bankName">
-            <up-input
-              v-model="form.bankName"
-              placeholder="璇疯緭鍏ュ紑鎴烽摱琛�"
-              clearable
-            />
-          </up-form-item>
-          <up-form-item label="寮�鎴疯鍙�" prop="bankCode">
-            <up-input
-              v-model="form.bankCode"
-              placeholder="璇疯緭鍏ュ紑鎴疯鍙�"
+              v-model="form.contactPosition"
+              placeholder="璇疯緭鍏ヨ仈绯讳汉宀椾綅"
               clearable
             />
           </up-form-item>
@@ -178,30 +123,25 @@
   const form = ref({
     customerName: "",
     customerType: "",
-    taxpayerIdentificationNumber: "",
     companyAddress: "",
     companyPhone: "",
-    corporation: "",
-    agent: "",
-    fax: "",
     contactPerson: "",
     contactPhone: "",
-    basicBankAccount: "",
-    bankAccount: "",
-    bankName: "",
-    bankCode: "",
+    contactPosition: "",
     maintainer: "",
     maintenanceTime: "",
   });
 
   const rules = {
     customerName: [{ required: true, message: "璇疯緭鍏ュ鎴峰悕绉�", trigger: "blur" }],
-    customerType: [{ required: true, message: "璇烽�夋嫨瀹㈡埛鍒嗙被", trigger: "change" }],
+    companyAddress: [{ required: true, message: "璇疯緭鍏ュ叕鍙稿湴鍧�", trigger: "blur" }],
+    companyPhone: [{ required: true, message: "璇疯緭鍏ュ叕鍙哥數璇�", trigger: "blur" }],
   };
 
   const customerTypeActions = [
     { name: "闆跺敭瀹㈡埛", value: "闆跺敭瀹㈡埛" },
     { name: "缁忛攢鍟嗗鎴�", value: "缁忛攢鍟嗗鎴�" },
+    { name: "杩為攣搴�", value: "杩為攣搴�" },
   ];
 
   const pageTitle = computed(() =>
diff --git a/src/pages/basicData/customerFile/index.vue b/src/pages/basicData/customerFile/index.vue
index 1d6fb9d..96ff6fb 100644
--- a/src/pages/basicData/customerFile/index.vue
+++ b/src/pages/basicData/customerFile/index.vue
@@ -23,7 +23,7 @@
       <up-tabs
         v-model="tabValue"
         :list="tabList"
-        itemStyle="width: 33.33%;height: 80rpx;"
+        itemStyle="width: 25%;height: 80rpx;"
         @change="onTabChange"
       />
     </view>
@@ -44,10 +44,6 @@
 
         <view class="item-details">
           <view class="detail-row">
-            <text class="detail-label">绾崇◣浜鸿瘑鍒彿</text>
-            <text class="detail-value">{{ item.taxpayerIdentificationNumber || "-" }}</text>
-          </view>
-          <view class="detail-row">
             <text class="detail-label">鍏徃鐢佃瘽</text>
             <text class="detail-value">{{ item.companyPhone || "-" }}</text>
           </view>
@@ -56,12 +52,16 @@
             <text class="detail-value">{{ item.companyAddress || "-" }}</text>
           </view>
           <view class="detail-row">
-            <text class="detail-label">娉曚汉</text>
-            <text class="detail-value">{{ item.corporation || "-" }}</text>
+            <text class="detail-label">鑱旂郴浜�</text>
+            <text class="detail-value">{{ item.contactPerson || "-" }}</text>
           </view>
           <view class="detail-row">
-            <text class="detail-label">浠g悊浜�</text>
-            <text class="detail-value">{{ item.agent || "-" }}</text>
+            <text class="detail-label">鑱旂郴鐢佃瘽</text>
+            <text class="detail-value">{{ item.contactPhone || "-" }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="detail-label">鑱旂郴浜哄矖浣�</text>
+            <text class="detail-value">{{ item.contactPosition || "-" }}</text>
           </view>
           <view class="detail-row">
             <text class="detail-label">缁存姢浜�</text>
@@ -106,6 +106,7 @@
     { name: "鍏ㄩ儴瀹㈡埛", value: "" },
     { name: "闆跺敭瀹㈡埛", value: "闆跺敭瀹㈡埛" },
     { name: "缁忛攢鍟嗗鎴�", value: "缁忛攢鍟嗗鎴�" },
+    { name: "杩為攣搴�", value: "杩為攣搴�" },
   ]);
   const tabValue = ref(0);
 
diff --git a/src/pages/sales/salesQuotation/detail.vue b/src/pages/sales/salesQuotation/detail.vue
index a273974..0eb5bf0 100644
--- a/src/pages/sales/salesQuotation/detail.vue
+++ b/src/pages/sales/salesQuotation/detail.vue
@@ -6,142 +6,109 @@
       <view class="section">
         <view class="section-title">鍩虹淇℃伅</view>
         <view class="info-list">
-          <view class="info-item">
-            <text class="info-label">鎶ヤ环鍗曞彿</text>
-            <text class="info-value">{{ detailData.quotationNo || "-" }}</text>
-          </view>
-          <view class="info-item">
-            <text class="info-label">瀹㈡埛鍚嶇О</text>
-            <text class="info-value">{{ detailData.customer || "-" }}</text>
-          </view>
-          <view class="info-item">
-            <text class="info-label">涓氬姟鍛�</text>
-            <text class="info-value">{{ detailData.salesperson || "-" }}</text>
-          </view>
-          <view class="info-item">
-            <text class="info-label">鎶ヤ环鏃ユ湡</text>
-            <text class="info-value">{{ detailData.quotationDate || "-" }}</text>
-          </view>
-          <view class="info-item">
-            <text class="info-label">鏈夋晥鏈熻嚦</text>
-            <text class="info-value">{{ detailData.validDate || "-" }}</text>
-          </view>
-          <view class="info-item">
-            <text class="info-label">浠樻鏂瑰紡</text>
-            <text class="info-value">{{ detailData.paymentMethod || "-" }}</text>
-          </view>
-          <view class="info-item">
-            <text class="info-label">瀹℃壒鐘舵��</text>
-            <text class="info-value">{{ detailData.status || "-" }}</text>
-          </view>
-          <view class="info-item">
-            <text class="info-label">鎶ヤ环鎬婚</text>
-            <text class="info-value highlight">{{ formatAmount(detailData.totalAmount) }}</text>
-          </view>
-          <view class="info-item">
-            <text class="info-label">澶囨敞</text>
-            <text class="info-value">{{ detailData.remark || "-" }}</text>
-          </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 class="info-item"><text class="info-label">鎶ヤ环鍗曞彿</text><text class="info-value">{{ detailData.quotationNo || "-" }}</text></view>
+          <view class="info-item"><text class="info-label">瀹㈡埛</text><text class="info-value">{{ detailData.customer || "-" }}</text></view>
+          <view class="info-item"><text class="info-label">涓氬姟鍛�</text><text class="info-value">{{ detailData.salesperson || "-" }}</text></view>
+          <view class="info-item"><text class="info-label">鎶ヤ环鏃ユ湡</text><text class="info-value">{{ detailData.quotationDate || "-" }}</text></view>
+          <view class="info-item"><text class="info-label">鏈夋晥鏈熻嚦</text><text class="info-value">{{ detailData.validDate || "-" }}</text></view>
+          <view class="info-item"><text class="info-label">浠樻鏂瑰紡</text><text class="info-value">{{ detailData.paymentMethod || "-" }}</text></view>
+          <view class="info-item"><text class="info-label">鎬婚</text><text class="info-value highlight">{{ formatAmount(totalAmount) }}</text></view>
+          <view class="info-item"><text class="info-label">澶囨敞</text><text class="info-value">{{ detailData.remark || "-" }}</text></view>
         </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="products.length" class="product-list">
+          <view v-for="(item, index) in products" :key="index" class="product-card">
             <view class="product-head">浜у搧 {{ index + 1 }}</view>
-            <view class="info-item">
-              <text class="info-label">浜у搧鍚嶇О</text>
-              <text class="info-value">{{ item.product || item.productName || "-" }}</text>
-            </view>
-            <view class="info-item">
-              <text class="info-label">瑙勬牸鍨嬪彿</text>
-              <text class="info-value">{{ item.specification || "-" }}</text>
-            </view>
-            <view class="info-item">
-              <text class="info-label">鍗曚綅</text>
-              <text class="info-value">{{ item.unit || "-" }}</text>
-            </view>
-            <view class="info-item">
-              <text class="info-label">鏁伴噺</text>
-              <text class="info-value">{{ item.quantity || "-" }}</text>
-            </view>
-            <view class="info-item">
-              <text class="info-label">鍗曚环</text>
-              <text class="info-value">{{ formatAmount(item.unitPrice) }}</text>
-            </view>
-            <view class="info-item">
-              <text class="info-label">閲戦</text>
-              <text class="info-value highlight">{{ formatAmount(item.amount) }}</text>
-            </view>
+            <view class="info-item"><text class="info-label">浜у搧</text><text class="info-value">{{ item.product || item.productName || "-" }}</text></view>
+            <view class="info-item"><text class="info-label">瑙勬牸</text><text class="info-value">{{ item.specification || "-" }}</text></view>
+            <view class="info-item"><text class="info-label">鍗曚綅</text><text class="info-value">{{ item.unit || "-" }}</text></view>
+            <view class="info-item"><text class="info-label">绾稿紶</text><text class="info-value">{{ item.paper || "-" }}</text></view>
+            <view class="info-item"><text class="info-label">瀹氶噺</text><text class="info-value">{{ item.paperWeight || "-" }}</text></view>
+            <view class="info-item"><text class="info-label">鏁伴噺</text><text class="info-value">{{ Number(item.quantity || 0) }}</text></view>
+            <view class="info-item"><text class="info-label">鍗曚环</text><text class="info-value">{{ formatAmount(item.unitPrice) }}</text></view>
+            <view class="info-item"><text class="info-label">鍗扮増璐�</text><text class="info-value">{{ formatAmount(item.printingFee) }}</text></view>
+            <view class="info-item"><text class="info-label">鍒�鐗堣垂</text><text class="info-value">{{ formatAmount(item.dieCuttingFee) }}</text></view>
+            <view class="info-item"><text class="info-label">纾ㄥ叿璐�</text><text class="info-value">{{ formatAmount(item.grindingFee) }}</text></view>
+            <view class="info-item"><text class="info-label">閲戦</text><text class="info-value highlight">{{ formatAmount(item.amount) }}</text></view>
           </view>
         </view>
-        <view v-else class="empty-box">
-          <text>鏆傛棤浜у搧鏄庣粏</text>
-        </view>
+        <view v-else class="empty-box"><text>鏆傛棤浜у搧鏄庣粏</text></view>
       </view>
     </view>
 
-    <FooterButtons cancelText="杩斿洖" confirmText="缂栬緫" @cancel="goBack" @confirm="goEdit" />
+    <view class="detail-footer">
+      <up-button type="primary" @click="goBack">杩斿洖</up-button>
+    </view>
   </view>
 </template>
 
 <script setup>
   import { computed, ref } from "vue";
   import { onLoad, onShow } from "@dcloudio/uni-app";
-  import FooterButtons from "@/components/FooterButtons.vue";
   import PageHeader from "@/components/PageHeader.vue";
+  import { getQuotationDetail } from "@/api/salesManagement/salesQuotation";
 
   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 products = computed(() => {
+    const rows = detailData.value?.products;
+    if (Array.isArray(rows) && rows.length) return rows;
+    if (detailData.value?.product || detailData.value?.productName) return [detailData.value];
+    return [];
   });
 
-  const goBack = () => {
-    uni.navigateBack();
-  };
+  const totalAmount = computed(() => {
+    const backendTotal = Number(detailData.value?.totalAmount || 0);
+    if (backendTotal > 0) return backendTotal;
+    return Number(
+      products.value
+        .reduce((sum, item) => {
+          const unitPrice = Number(item?.unitPrice || 0);
+          const printingFee = Number(item?.printingFee || 0);
+          const dieCuttingFee = Number(item?.dieCuttingFee || 0);
+          const grindingFee = Number(item?.grindingFee || 0);
+          return sum + unitPrice + printingFee + dieCuttingFee + grindingFee;
+        }, 0)
+        .toFixed(2)
+    );
+  });
 
-  const goEdit = () => {
-    if (!quotationId.value) return;
-    uni.navigateTo({ url: `/pages/sales/salesQuotation/edit?id=${quotationId.value}` });
-  };
-
+  const goBack = () => uni.navigateBack();
   const formatAmount = amount => `楼${Number(amount || 0).toFixed(2)}`;
 
   const loadDetailFromStorage = () => {
     const cachedData = uni.getStorageSync("salesQuotationDetail");
-    detailData.value = cachedData || {};
+    if (cachedData && typeof cachedData === "object") detailData.value = cachedData;
+  };
+
+  const loadDetailFromApi = () => {
+    if (!quotationId.value) return Promise.resolve();
+    uni.showLoading({ title: "鍔犺浇涓�...", mask: true });
+    return getQuotationDetail({ id: quotationId.value })
+      .then(res => {
+        detailData.value = res?.data || detailData.value || {};
+      })
+      .catch(() => {
+        uni.showToast({ title: "鍔犺浇璇︽儏澶辫触", icon: "error" });
+      })
+      .finally(() => {
+        uni.hideLoading();
+      });
   };
 
   onLoad(options => {
-    if (options?.id) {
-      quotationId.value = options.id;
-    }
+    if (options?.id) quotationId.value = options.id;
     loadDetailFromStorage();
+    loadDetailFromApi();
   });
 
   onShow(() => {
     loadDetailFromStorage();
+    loadDetailFromApi();
   });
 </script>
 
@@ -232,4 +199,15 @@
     color: #22324d;
     border-bottom: 1px solid #eef2f7;
   }
+
+  .detail-footer {
+    position: fixed;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
+    background: #fff;
+    box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.05);
+    z-index: 10;
+  }
 </style>
diff --git a/src/pages/sales/salesQuotation/edit.vue b/src/pages/sales/salesQuotation/edit.vue
index 940a8d9..80561e5 100644
--- a/src/pages/sales/salesQuotation/edit.vue
+++ b/src/pages/sales/salesQuotation/edit.vue
@@ -3,246 +3,122 @@
     <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" />
-            <template #right>
-              <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"
-            />
-            <template #right>
-              <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"
-            />
-            <template #right>
-              <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"
-            />
-            <template #right>
-              <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>
-          <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">
-          <view class="section-tools">
-            <up-button type="primary" size="small" text="鏂板鑺傜偣" @click="addApproverNode" />
-          </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>
-
+      <up-form ref="formRef" :model="form" label-width="110" input-align="right" error-message-align="right">
         <u-cell-group title="浜у搧淇℃伅" class="form-section">
           <view class="section-tools">
-            <up-button type="primary" size="small" text="鏂板浜у搧" @click="addProduct" />
+            <up-button type="primary" size="small" text="鏂板浜у搧" :disabled="isEditMode" @click="addProduct" />
           </view>
-          <view v-if="form.products.length === 0" class="empty-text">
-            <text>鏆傛棤浜у搧锛岃鍏堟坊鍔犱骇鍝�</text>
-          </view>
+          <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-for="(product, index) in form.products" :key="product.uid || index" 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>
               </view>
               <up-divider></up-divider>
               <view class="product-body">
-                <up-form-item label="浜у搧鍚嶇О">
-                  <up-input
-                    v-model="product.product"
-                    placeholder="璇烽�夋嫨浜у搧"
-                    readonly
-                    @click="openProductPicker(index)"
-                  />
-                  <template #right>
-                    <up-icon name="arrow-right" @click="openProductPicker(index)"></up-icon>
-                  </template>
+                <up-form-item label="浜у搧">
+                  <up-input v-model="product.product" placeholder="璇烽�夋嫨浜у搧" readonly @click="openProductPicker(index)" />
+                  <template #right><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)"
-                  />
-                  <template #right>
-                    <up-icon name="arrow-right" @click="openModelPicker(index)"></up-icon>
-                  </template>
+                <up-form-item label="瑙勬牸">
+                  <up-input v-model="product.specification" placeholder="璇烽�夋嫨瑙勬牸" readonly @click="openModelPicker(index)" />
+                  <template #right><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-form-item>
+                <up-form-item label="鍗曚綅"><up-input v-model="product.unit" placeholder="璇疯緭鍏ュ崟浣�" clearable /></up-form-item>
+                <up-form-item label="绾稿紶"><up-input v-model="product.paper" placeholder="璇疯緭鍏ョ焊寮�" clearable /></up-form-item>
+                <up-form-item label="瀹氶噺"><up-input v-model="product.paperWeight" 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 v-model="product.printingFee" type="number" placeholder="璇疯緭鍏ュ嵃鐗堣垂" clearable @blur="syncTotalAmount" />
+                </up-form-item>
+                <up-form-item label="鍒�鐗堣垂">
+                  <up-input v-model="product.dieCuttingFee" type="number" placeholder="璇疯緭鍏ュ垁鐗堣垂" clearable @blur="syncTotalAmount" />
+                </up-form-item>
+                <up-form-item label="纾ㄥ叿璐�">
+                  <up-input v-model="product.grindingFee" type="number" placeholder="璇疯緭鍏ョ(鍏疯垂" clearable @blur="syncTotalAmount" />
                 </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-textarea v-model="form.remark" placeholder="璇疯緭鍏ュ娉紙閫夊~锛�" auto-height />
+          </up-form-item>
+        </u-cell-group>
+
+        <u-cell-group title="姹囨��" class="form-section">
           <up-form-item label="鎶ヤ环鎬婚">
             <up-input :model-value="formatAmount(totalAmount)" disabled placeholder="鑷姩姹囨��" />
           </up-form-item>
+          <view class="summary-tip">鎬婚瑙勫垯锛氬崟浠� + 鍗扮増璐� + 鍒�鐗堣垂 + 纾ㄥ叿璐癸紙鎸変骇鍝侀�愯姹傚拰锛�</view>
         </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" />
+    <up-action-sheet :show="showModelSheet" title="閫夋嫨瑙勬牸" :actions="modelActions" @select="onSelectModel" @close="showModelSheet = false" />
   </view>
 </template>
 
 <script setup>
-  import { computed, onMounted, onUnmounted, ref } from "vue";
+  import { computed, onMounted, ref } from "vue";
   import { onLoad } from "@dcloudio/uni-app";
   import FooterButtons from "@/components/FooterButtons.vue";
   import PageHeader from "@/components/PageHeader.vue";
-  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 { addOrUpdateQuotationProduct, editQuotationProduct } from "@/api/salesManagement/salesQuotationProduct";
 
   const formRef = ref();
   const loading = ref(false);
   const quotationId = ref("");
-  const showCustomerSheet = ref(false);
-  const showSalespersonSheet = ref(false);
   const showProductSheet = ref(false);
   const showModelSheet = ref(false);
-  const showQuotationDatePicker = ref(false);
-  const showValidDatePicker = ref(false);
-  const quotationDateValue = ref(Date.now());
-  const validDateValue = ref(Date.now());
   const currentProductIndex = ref(-1);
-  const customerList = ref([]);
-  const salespersonList = ref([]);
   const productList = ref([]);
   const modelActions = ref([]);
 
   let uidSeed = 1;
-  let nextApproverId = 2;
-
   const form = ref({
     id: undefined,
-    quotationNo: "",
-    customer: "",
-    salesperson: "",
-    quotationDate: "",
-    validDate: "",
-    paymentMethod: "",
-    status: "寰呭鎵�",
     remark: "",
-    approveUserIds: "",
     products: [],
     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" }],
-    validDate: [{ required: true, message: "璇烽�夋嫨鏈夋晥鏈�", trigger: "change" }],
-    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))
-  );
-  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 isEditMode = computed(() => Boolean(quotationId.value));
   const productActions = computed(() => productList.value.map(item => ({ name: item.label, value: item.value, label: item.label })));
+  const totalAmount = computed(() => calcTotalAmountFromProducts(form.value.products));
 
   const createEmptyProduct = () => ({
     uid: `p_${uidSeed++}`,
+    id: "",
+    salesQuotationId: "",
     productId: "",
     product: "",
     specificationId: "",
     specification: "",
     unit: "",
+    paper: "",
+    paperWeight: "",
     quantity: 1,
     unitPrice: 0,
+    printingFee: 0,
+    dieCuttingFee: 0,
+    grindingFee: 0,
     amount: 0,
     modelOptions: [],
   });
@@ -251,37 +127,56 @@
     const result = [];
     const walk = list => {
       (list || []).forEach(item => {
-        if (item.children && item.children.length) {
-          walk(item.children);
-        } else {
-          result.push({ label: item.label || item.productName || "", value: item.id || item.value });
-        }
+        if (item.children && item.children.length) walk(item.children);
+        else result.push({ label: item.label || item.productName || "", value: item.id || item.value });
       });
     };
     walk(nodes);
     return result;
   };
 
+  const findProductIdByLabel = label => {
+    if (!label) return "";
+    const hit = (productList.value || []).find(item => item.label === label);
+    return hit?.value || "";
+  };
+
   const formatAmount = amount => `楼${Number(amount || 0).toFixed(2)}`;
   const goBack = () => uni.navigateBack();
 
-  const calculateAmount = product => {
-    product.amount = Number((Number(product.quantity || 0) * Number(product.unitPrice || 0)).toFixed(2));
+  const calcTotalAmountFromProducts = products =>
+    Number(
+      (products || [])
+        .reduce((sum, item) => {
+          const unitPrice = Number(item?.unitPrice || 0);
+          const printingFee = Number(item?.printingFee || 0);
+          const dieCuttingFee = Number(item?.dieCuttingFee || 0);
+          const grindingFee = Number(item?.grindingFee || 0);
+          return sum + unitPrice + printingFee + dieCuttingFee + grindingFee;
+        }, 0)
+        .toFixed(2)
+    );
+
+  const syncTotalAmount = () => {
     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 calculateAmount = product => {
+    product.amount = Number((Number(product.quantity || 0) * Number(product.unitPrice || 0)).toFixed(2));
+    syncTotalAmount();
   };
-  const addProduct = () => form.value.products.push(createEmptyProduct());
+
+  const addProduct = () => {
+    if (isEditMode.value) {
+      uni.showToast({ title: "缂栬緫妯″紡涓嬩笉鍏佽鏂板浜у搧", icon: "none" });
+      return;
+    }
+    form.value.products.push(createEmptyProduct());
+  };
+
   const removeProduct = index => {
     form.value.products.splice(index, 1);
-    form.value.totalAmount = totalAmount.value;
+    syncTotalAmount();
   };
 
   const fetchModelOptions = async (productId, product) => {
@@ -293,6 +188,7 @@
     currentProductIndex.value = index;
     showProductSheet.value = true;
   };
+
   const openModelPicker = index => {
     currentProductIndex.value = index;
     const current = form.value.products[index];
@@ -302,27 +198,12 @@
     }
     modelActions.value = (current.modelOptions || []).map(item => ({ name: item.model, value: item.id, unit: item.unit }));
     if (!modelActions.value.length) {
-      uni.showToast({ title: "鏆傛棤瑙勬牸鍨嬪彿", icon: "none" });
+      uni.showToast({ title: "鏆傛棤瑙勬牸鏁版嵁", icon: "none" });
       return;
     }
     showModelSheet.value = true;
   };
 
-  const onSelectCustomer = action => {
-    form.value.customer = action.value;
-    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;
@@ -335,6 +216,7 @@
     showProductSheet.value = false;
     fetchModelOptions(action.value, current);
   };
+
   const onSelectModel = action => {
     const current = form.value.products[currentProductIndex.value];
     if (!current) return;
@@ -343,81 +225,70 @@
     current.unit = action.unit || current.unit;
     showModelSheet.value = false;
   };
-  const onQuotationDateConfirm = e => {
-    form.value.quotationDate = formatDateToYMD(e.value);
-    showQuotationDatePicker.value = false;
-  };
-  const onValidDateConfirm = e => {
-    form.value.validDate = formatDateToYMD(e.value);
-    showValidDatePicker.value = false;
-  };
 
-  const fetchBaseOptions = async () => {
-      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 : [];
+  const fetchProductOptions = async () => {
+    const productTree = await productTreeList().catch(() => []);
     productList.value = flattenProductTree(Array.isArray(productTree) ? productTree : productTree?.data || []);
   };
 
   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 row = {
+          uid: `p_${uidSeed++}`,
+          id: item.id || "",
+          salesQuotationId: item.salesQuotationId || "",
+          productId: item.productId || "",
+          product: item.product || item.productName || "",
+          specificationId: item.specificationId || "",
+          specification: item.specification || "",
+          unit: item.unit || "",
+          paper: item.paper || "",
+          paperWeight: item.paperWeight || "",
+          quantity: Number(item.quantity || 1),
+          unitPrice: Number(item.unitPrice || 0),
+          printingFee: Number(item.printingFee || 0),
+          dieCuttingFee: Number(item.dieCuttingFee || 0),
+          grindingFee: Number(item.grindingFee || 0),
+          amount: Number(item.amount || Number(item.quantity || 0) * Number(item.unitPrice || 0)),
+          modelOptions: [],
+        };
+        if (row.productId) {
+          await fetchModelOptions(row.productId, row);
+          if (!row.specificationId && row.specification) {
+            const matchedModel = (row.modelOptions || []).find(model => model.model === row.specification);
+            if (matchedModel) {
+              row.specificationId = matchedModel.id;
+              if (!row.unit) row.unit = matchedModel.unit || "";
+            }
+          }
+        }
+        return row;
+      })
+    );
     form.value.products = normalized;
   };
 
-  const loadDetail = async () => {
+  const loadEditFromStorage = async () => {
     if (!quotationId.value) return;
-    uni.showLoading({ title: "鍔犺浇涓�...", mask: true });
-    try {
-      const res = await getQuotationDetail({ id: quotationId.value });
-      const data = res?.data || {};
-      form.value = {
-        ...form.value,
-        id: data.id,
-        quotationNo: data.quotationNo || "",
-        customer: data.customer || "",
-        salesperson: data.salesperson || "",
-        quotationDate: data.quotationDate || "",
-        validDate: data.validDate || "",
-        paymentMethod: data.paymentMethod || "",
-        status: data.status || "寰呭鎵�",
-        remark: data.remark || "",
-      };
-      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();
-    }
+    const cached = uni.getStorageSync("salesQuotationEdit");
+    if (!cached || typeof cached !== "object") return;
+    if (cached.id && String(cached.id) !== String(quotationId.value)) return;
+
+    const data = cached;
+    form.value = {
+      ...form.value,
+      id: data.id || form.value.id,
+      remark: data.remark || "",
+    };
+
+    const rows = Array.isArray(data.products) && data.products.length ? data.products : [data];
+    const normalizedRows = rows.map(item => ({
+      ...item,
+      productId: item.productId || findProductIdByLabel(item.product || item.productName || ""),
+    }));
+    await normalizeProductRows(normalizedRows);
+    syncTotalAmount();
   };
 
   const validateProducts = () => {
@@ -425,42 +296,64 @@
       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.specificationId || !item.unit || !Number(item.unitPrice || 0));
     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;
+
+  const buildProductPayload = item => {
+    const quantity = Number(item?.quantity || 0);
+    const unitPrice = Number(item?.unitPrice || 0);
+    const printingFee = Number(item?.printingFee || 0);
+    const dieCuttingFee = Number(item?.dieCuttingFee || 0);
+    const grindingFee = Number(item?.grindingFee || 0);
+    return {
+      id: item?.id || undefined,
+      salesQuotationId: item?.salesQuotationId || null,
+      product: item?.product || "",
+      specification: item?.specification || "",
+      unit: item?.unit || "",
+      paper: item?.paper || "",
+      paperWeight: item?.paperWeight || "",
+      unitPrice,
+      printingFee,
+      dieCuttingFee,
+      grindingFee,
+      quantity,
+      amount: Number(item?.amount ?? quantity * unitPrice),
+      remark: form.value.remark || "",
+    };
   };
 
   const handleSubmit = async () => {
-    const valid = await formRef.value.validate().catch(() => false);
-    if (!valid || !validateApprovers() || !validateProducts()) return;
+    if (!validateProducts()) return;
+
     loading.value = true;
-    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,
-        quantity: Number(item.quantity || 0),
-        unit: item.unit,
-        unitPrice: Number(item.unitPrice || 0),
-        amount: Number(item.amount || 0),
-      })),
-    };
-    const action = quotationId.value ? updateQuotation : addQuotation;
-    action(payload)
+    if (quotationId.value) {
+      const editingItem = form.value.products[0] || {};
+      const payload = buildProductPayload({
+        ...editingItem,
+        id: editingItem.id || quotationId.value,
+      });
+      editQuotationProduct(payload)
+        .then(() => {
+          uni.showToast({ title: "淇濆瓨鎴愬姛", icon: "success" });
+          setTimeout(() => uni.navigateBack(), 300);
+        })
+        .catch(() => {
+          uni.showToast({ title: "淇濆瓨澶辫触", icon: "error" });
+        })
+        .finally(() => {
+          loading.value = false;
+        });
+      return;
+    }
+
+    const payloadList = form.value.products.map(item => buildProductPayload(item));
+    addOrUpdateQuotationProduct(payloadList)
       .then(() => {
         uni.showToast({ title: "淇濆瓨鎴愬姛", icon: "success" });
         setTimeout(() => uni.navigateBack(), 300);
@@ -478,60 +371,21 @@
       quotationId.value = options.id;
       form.value.id = options.id;
     } else {
-      const today = formatDateToYMD(Date.now());
-      form.value.quotationDate = today;
-      form.value.validDate = today;
+      form.value.products = [];
     }
   });
 
   onMounted(async () => {
-    await fetchBaseOptions();
-    uni.$on("selectContact", onSelectApprover);
-    if (quotationId.value) {
-      await loadDetail();
-    }
-  });
-
-  onUnmounted(() => {
-    uni.$off("selectContact", onSelectApprover);
-    uni.removeStorageSync("stepIndex");
+    await fetchProductOptions();
+    if (quotationId.value) await loadEditFromStorage();
   });
 </script>
 
 <style scoped lang="scss">
   @import "@/static/scss/form-common.scss";
 
-  .account-detail {
-    min-height: 100vh;
-    background: #f8f9fa;
-    padding-bottom: 100px;
-  }
-
   .form-container {
     padding: 12px 12px 0;
-  }
-
-  .hero-card {
-    margin-bottom: 12px;
-    padding: 18px 18px 16px;
-    border-radius: 16px;
-    background: linear-gradient(135deg, #eef6ff 0%, #ffffff 100%);
-    box-shadow: 0 6px 18px rgba(41, 121, 255, 0.08);
-  }
-
-  .hero-title {
-    display: block;
-    font-size: 18px;
-    font-weight: 600;
-    color: #1f2d3d;
-    margin-bottom: 6px;
-  }
-
-  .hero-desc {
-    display: block;
-    font-size: 13px;
-    line-height: 1.6;
-    color: #7a8599;
   }
 
   .form-section {
@@ -547,7 +401,6 @@
     padding: 12px 12px 0;
   }
 
-  .node-list,
   .product-list {
     padding: 12px;
     display: flex;
@@ -555,31 +408,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;
@@ -603,6 +437,13 @@
     font-size: 14px;
   }
 
+  .summary-tip {
+    padding: 0 24rpx 24rpx;
+    color: #909399;
+    font-size: 12px;
+    line-height: 1.6;
+  }
+
   :deep(.u-cell-group__title) {
     padding: 14px 18px 10px !important;
     font-size: 15px !important;
diff --git a/src/pages/sales/salesQuotation/index.vue b/src/pages/sales/salesQuotation/index.vue
index a6a5103..e9f6be3 100644
--- a/src/pages/sales/salesQuotation/index.vue
+++ b/src/pages/sales/salesQuotation/index.vue
@@ -7,25 +7,16 @@
         <view class="search-input">
           <up-input
             class="search-text"
-            v-model="quotationNo"
-            placeholder="璇疯緭鍏ユ姤浠峰崟鍙锋悳绱�"
+            v-model="searchForm.product"
+            placeholder="璇疯緭鍏ヤ骇鍝佸悕绉版悳绱�"
             clearable
-            @change="getList"
+            @change="getList(true)"
           />
         </view>
-        <view class="filter-button" @click="getList">
+        <view class="filter-button" @click="getList(true)">
           <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"
-      />
     </view>
 
     <view v-if="quotationList.length > 0" class="ledger-list">
@@ -35,37 +26,44 @@
             <view class="document-icon">
               <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
             </view>
-            <text class="item-id">{{ item.quotationNo || "-" }}</text>
+            <text class="item-id">{{ item.product || "-" }}</text>
           </view>
-          <text class="item-index">{{ item.status || "-" }}</text>
         </view>
 
         <up-divider></up-divider>
 
         <view class="item-details">
           <view class="detail-row">
-            <text class="detail-label">瀹㈡埛鍚嶇О</text>
-            <text class="detail-value">{{ item.customer || "-" }}</text>
+            <text class="detail-label">瑙勬牸</text>
+            <text class="detail-value">{{ item.specification || "-" }}</text>
           </view>
           <view class="detail-row">
-            <text class="detail-label">涓氬姟鍛�</text>
-            <text class="detail-value">{{ item.salesperson || "-" }}</text>
+            <text class="detail-label">绾稿紶</text>
+            <text class="detail-value">{{ item.paper || "-" }}</text>
           </view>
           <view class="detail-row">
-            <text class="detail-label">鎶ヤ环鏃ユ湡</text>
-            <text class="detail-value">{{ item.quotationDate || "-" }}</text>
+            <text class="detail-label">瀹氶噺</text>
+            <text class="detail-value">{{ item.paperWeight || "-" }}</text>
           </view>
           <view class="detail-row">
-            <text class="detail-label">鏈夋晥鏈熻嚦</text>
-            <text class="detail-value">{{ item.validDate || "-" }}</text>
+            <text class="detail-label">鍗曚环</text>
+            <text class="detail-value">{{ formatAmount(item.unitPrice) }}</text>
           </view>
           <view class="detail-row">
-            <text class="detail-label">浠樻鏂瑰紡</text>
-            <text class="detail-value">{{ item.paymentMethod || "-" }}</text>
+            <text class="detail-label">鍗扮増璐�</text>
+            <text class="detail-value">{{ formatAmount(item.printingFee) }}</text>
           </view>
           <view class="detail-row">
-            <text class="detail-label">鎶ヤ环閲戦</text>
-            <text class="detail-value highlight">{{ formatAmount(item.totalAmount) }}</text>
+            <text class="detail-label">鍒�鐗堣垂</text>
+            <text class="detail-value">{{ formatAmount(item.dieCuttingFee) }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="detail-label">纾ㄥ叿璐�</text>
+            <text class="detail-value">{{ formatAmount(item.grindingFee) }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="detail-label">鏁伴噺</text>
+            <text class="detail-value">{{ Number(item.quantity || 0) }}</text>
           </view>
           <view class="detail-row">
             <text class="detail-label">澶囨敞</text>
@@ -74,25 +72,15 @@
         </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" type="primary" @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>
+          <up-button class="action-btn" size="small" type="error" plain @click="handleDelete(item)">鍒犻櫎</up-button>
         </view>
       </view>
     </view>
 
     <view v-else class="no-data">
-      <text>鏆傛棤閿�鍞姤浠锋暟鎹�</text>
+      <text>鏆傛棤鏁版嵁</text>
     </view>
 
     <view class="fab-button" @click="goAdd">
@@ -105,70 +93,73 @@
   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 } from "@/api/salesManagement/salesQuotation";
+  import { quotationProductListPage } from "@/api/salesManagement/salesQuotationProduct";
 
-  const quotationNo = ref("");
+  const searchForm = reactive({ product: "" });
   const quotationList = ref([]);
-
-  const tabList = reactive([
-    { name: "鍏ㄩ儴", value: "" },
-    { name: "寰呭鎵�", value: "寰呭鎵�" },
-    { name: "瀹℃牳涓�", value: "瀹℃牳涓�" },
-    { name: "閫氳繃", value: "閫氳繃" },
-    { name: "鎷掔粷", value: "鎷掔粷" },
-  ]);
-  const tabValue = ref(0);
-
-  const page = {
-    current: -1,
-    size: -1,
-  };
-
-  const goBack = () => {
-    uni.navigateBack();
-  };
-
-  const goAdd = () => {
-    uni.navigateTo({ url: "/pages/sales/salesQuotation/edit" });
-  };
-
+  const goBack = () => uni.navigateBack();
+  const goAdd = () => uni.navigateTo({ url: "/pages/sales/salesQuotation/edit" });
   const goEdit = item => {
-    if (!canEdit(item)) return;
+    const source = item?.__raw || item || {};
+    uni.setStorageSync("salesQuotationEdit", source);
     uni.navigateTo({ url: `/pages/sales/salesQuotation/edit?id=${item.id}` });
   };
-
   const goDetail = item => {
     uni.setStorageSync("salesQuotationDetail", item || {});
     uni.navigateTo({ url: `/pages/sales/salesQuotation/detail?id=${item.id}` });
   };
 
-  const canEdit = item => ["寰呭鎵�", "鎷掔粷"].includes(item?.status);
+  const formatAmount = amount => `楼${Number(amount || 0).toFixed(2)}`;
 
-  const onTabChange = val => {
-    tabValue.value = val.index;
-    getList();
-  };
+  const calcTotalAmountFromProducts = products =>
+    Number(
+      (products || [])
+        .reduce((sum, product) => {
+          const unitPrice = Number(product?.unitPrice || 0);
+          const printingFee = Number(product?.printingFee || 0);
+          const dieCuttingFee = Number(product?.dieCuttingFee || 0);
+          const grindingFee = Number(product?.grindingFee || 0);
+          return sum + unitPrice + printingFee + dieCuttingFee + grindingFee;
+        }, 0)
+        .toFixed(2)
+    );
 
-  const getCurrentStatus = () => {
-    const currentTab = tabList[tabValue.value];
-    return currentTab?.value || "";
-  };
-
-  const formatAmount = amount => {
-    const num = Number(amount || 0);
-    return `楼${num.toFixed(2)}`;
+  const normalizeQuotation = row => {
+    const sourceProducts = Array.isArray(row?.products) && row.products.length ? row.products : [row];
+    const first = sourceProducts[0] || {};
+    return {
+      ...row,
+      __raw: row,
+      customer: row?.customer || row?.customerName || first?.customer || first?.customerName || "",
+      salesperson: row?.salesperson || row?.salesman || row?.salesPerson || first?.salesperson || "",
+      quotationDate: row?.quotationDate || row?.quoteDate || first?.quotationDate || "",
+      validDate: row?.validDate || row?.expireDate || first?.validDate || "",
+      paymentMethod: row?.paymentMethod || row?.paymentType || first?.paymentMethod || "",
+      product: first.product || first.productName || row?.product || "",
+      specification: first.specification || row?.specification || "",
+      paper: first.paper || row?.paper || "",
+      paperWeight: first.paperWeight || row?.paperWeight || "",
+      unitPrice: Number(first.unitPrice || row?.unitPrice || 0),
+      printingFee: Number(first.printingFee || row?.printingFee || 0),
+      dieCuttingFee: Number(first.dieCuttingFee || row?.dieCuttingFee || 0),
+      grindingFee: Number(first.grindingFee || row?.grindingFee || 0),
+      quantity: Number(first.quantity || row?.quantity || 0),
+      quotationNo: row?.quotationNo || first?.quotationNo || "",
+      totalAmount: Number(row?.totalAmount || calcTotalAmountFromProducts(sourceProducts)),
+    };
   };
 
   const getList = () => {
     uni.showLoading({ title: "鍔犺浇涓�...", mask: true });
-    getQuotationList({
-      ...page,
-      quotationNo: quotationNo.value,
-      status: getCurrentStatus(),
+    quotationProductListPage({
+      current: -1,
+      size: -1,
+      product: String(searchForm.product || "").trim(),
     })
       .then(res => {
         const records = res?.data?.records || res?.records || [];
-        quotationList.value = Array.isArray(records) ? records : [];
+        quotationList.value = Array.isArray(records) ? records.map(normalizeQuotation) : [];
       })
       .catch(() => {
         uni.showToast({ title: "鏌ヨ澶辫触", icon: "error" });
@@ -182,11 +173,11 @@
     if (!item?.id) return;
     uni.showModal({
       title: "鍒犻櫎纭",
-      content: "纭鍒犻櫎璇ユ姤浠峰崟鍚楋紵",
+      content: "纭鍒犻櫎璇ユ姤浠峰悧锛�",
       success: res => {
         if (!res.confirm) return;
         uni.showLoading({ title: "澶勭悊涓�...", mask: true });
-        deleteQuotation(item.id)
+        deleteQuotation([item.id])
           .then(() => {
             uni.showToast({ title: "鍒犻櫎鎴愬姛", icon: "success" });
             getList();
@@ -208,11 +199,6 @@
 
 <style scoped lang="scss">
   @import "@/styles/sales-common.scss";
-
-  .tabs-section {
-    background: #ffffff;
-    padding: 0 12px 8px 12px;
-  }
 
   .item-index {
     max-width: 180rpx;
diff --git a/src/pages/works.vue b/src/pages/works.vue
index 8d37e74..360fc0e 100644
--- a/src/pages/works.vue
+++ b/src/pages/works.vue
@@ -89,27 +89,27 @@
       </view>
     </view>
     <!-- 浜哄姏璧勬簮妯″潡 -->
-    <view class="common-module collaboration-module"
-          v-if="hasHumanResourcesItems">
-      <view class="module-header">
-        <view class="module-title-container">
-          <text class="module-title">浜哄姏璧勬簮</text>
-        </view>
-      </view>
-      <view class="module-content">
-        <up-grid :border="false"
-                 col="4">
-          <up-grid-item v-for="(item, index) in humanResourcesItems"
-                        :key="index"
-                        @click="handleCommonItemClick(item)">
-            <view class="icon-container">
-              <image :src="item.icon" class="item-icon"></image>
-            </view>
-            <text class="item-label">{{item.label}}</text>
-          </up-grid-item>
-        </up-grid>
-      </view>
-    </view>
+<!--    <view class="common-module collaboration-module"-->
+<!--          v-if="hasHumanResourcesItems">-->
+<!--      <view class="module-header">-->
+<!--        <view class="module-title-container">-->
+<!--          <text class="module-title">浜哄姏璧勬簮</text>-->
+<!--        </view>-->
+<!--      </view>-->
+<!--      <view class="module-content">-->
+<!--        <up-grid :border="false"-->
+<!--                 col="4">-->
+<!--          <up-grid-item v-for="(item, index) in humanResourcesItems"-->
+<!--                        :key="index"-->
+<!--                        @click="handleCommonItemClick(item)">-->
+<!--            <view class="icon-container">-->
+<!--              <image :src="item.icon" class="item-icon"></image>-->
+<!--            </view>-->
+<!--            <text class="item-label">{{item.label}}</text>-->
+<!--          </up-grid-item>-->
+<!--        </up-grid>-->
+<!--      </view>-->
+<!--    </view>-->
     <!-- 鐢熶骇绠℃帶妯″潡 -->
     <view class="common-module equipment-module"
           v-if="hasProductionItems">
@@ -154,50 +154,28 @@
         </up-grid>
       </view>
     </view>
-    <!-- 妗f绠$悊妯″潡 -->
-    <view class="common-module archive-module"
-          v-if="hasArchiveManagementItems">
-      <view class="module-header">
-        <view class="module-title-container">
-          <text class="module-title">妗f绠$悊</text>
-        </view>
-      </view>
-      <view class="module-content">
-        <up-grid :border="false"
-                 col="4">
-          <up-grid-item v-for="(item, index) in archiveManagementItems"
-                        :key="index"
-                        @click="handleCommonItemClick(item)">
-            <view class="icon-container">
-              <image :src="item.icon" class="item-icon"></image>
-            </view>
-            <text class="item-label">{{item.label}}</text>
-          </up-grid-item>
-        </up-grid>
-      </view>
-    </view>
     <!-- 鍞悗鏈嶅姟妯″潡 -->
-    <view class="common-module after-sales-module"
-          v-if="hasAfterSalesServiceItems">
-      <view class="module-header">
-        <view class="module-title-container">
-          <text class="module-title">鍞悗鏈嶅姟</text>
-        </view>
-      </view>
-      <view class="module-content">
-        <up-grid :border="false"
-                 col="4">
-          <up-grid-item v-for="(item, index) in afterSalesServiceItems"
-                        :key="index"
-                        @click="handleCommonItemClick(item)">
-            <view class="icon-container">
-              <image :src="item.icon" class="item-icon"></image>
-            </view>
-            <text class="item-label">{{item.label}}</text>
-          </up-grid-item>
-        </up-grid>
-      </view>
-    </view>
+<!--    <view class="common-module after-sales-module"-->
+<!--          v-if="hasAfterSalesServiceItems">-->
+<!--      <view class="module-header">-->
+<!--        <view class="module-title-container">-->
+<!--          <text class="module-title">鍞悗鏈嶅姟</text>-->
+<!--        </view>-->
+<!--      </view>-->
+<!--      <view class="module-content">-->
+<!--        <up-grid :border="false"-->
+<!--                 col="4">-->
+<!--          <up-grid-item v-for="(item, index) in afterSalesServiceItems"-->
+<!--                        :key="index"-->
+<!--                        @click="handleCommonItemClick(item)">-->
+<!--            <view class="icon-container">-->
+<!--              <image :src="item.icon" class="item-icon"></image>-->
+<!--            </view>-->
+<!--            <text class="item-label">{{item.label}}</text>-->
+<!--          </up-grid-item>-->
+<!--        </up-grid>-->
+<!--      </view>-->
+<!--    </view>-->
     <!-- 璐ㄩ噺绠$悊妯″潡 -->
     <view class="common-module collaboration-module"
           v-if="hasQualityItems">
@@ -243,27 +221,27 @@
       </view>
     </view>
     <!-- 瀹夊叏鐢熶骇妯″潡 -->
-    <view class="common-module collaboration-module"
-          v-if="hasSafetyItems">
-      <view class="module-header">
-        <view class="module-title-container">
-          <text class="module-title">瀹夊叏鐢熶骇</text>
-        </view>
-      </view>
-      <view class="module-content">
-        <up-grid :border="false"
-                 col="4">
-          <up-grid-item v-for="(item, index) in safetyItems"
-                        :key="index"
-                        @click="handleCommonItemClick(item)">
-            <view class="icon-container">
-              <image :src="item.icon" class="item-icon"></image>
-            </view>
-            <text class="item-label">{{item.label}}</text>
-          </up-grid-item>
-        </up-grid>
-      </view>
-    </view>
+<!--    <view class="common-module collaboration-module"-->
+<!--          v-if="hasSafetyItems">-->
+<!--      <view class="module-header">-->
+<!--        <view class="module-title-container">-->
+<!--          <text class="module-title">瀹夊叏鐢熶骇</text>-->
+<!--        </view>-->
+<!--      </view>-->
+<!--      <view class="module-content">-->
+<!--        <up-grid :border="false"-->
+<!--                 col="4">-->
+<!--          <up-grid-item v-for="(item, index) in safetyItems"-->
+<!--                        :key="index"-->
+<!--                        @click="handleCommonItemClick(item)">-->
+<!--            <view class="icon-container">-->
+<!--              <image :src="item.icon" class="item-icon"></image>-->
+<!--            </view>-->
+<!--            <text class="item-label">{{item.label}}</text>-->
+<!--          </up-grid-item>-->
+<!--        </up-grid>-->
+<!--      </view>-->
+<!--    </view>-->
 
     <DownloadProgressMask />
   </view>
@@ -307,7 +285,7 @@
   const marketingItems = reactive([
     {
       icon: "/static/images/icon/kehudangan.svg",
-      label: "瀹㈡埛妗f",
+      label: "瀹㈡埛妗f(绉佹捣)",
     },
     {
       icon: "/static/images/icon/xiaoshoubaojia.svg",
@@ -332,6 +310,10 @@
     {
       icon: "/static/images/icon/gongyingshangwanglai.svg",
       label: "渚涘簲鍟嗗線鏉�",
+    },
+    {
+      icon: "/static/images/icon/gongyingshangdangan.svg",
+      label: "渚涘簲鍟嗘。妗�",
     },
     {
       icon: "/static/images/icon/caigouguanli.svg",
@@ -384,14 +366,6 @@
     {
       icon: "/static/images/icon/jiekuanguanli.svg",
       label: "鍊熸绠$悊",
-    },
-  ]);
-
-  // 妗f绠$悊鍔熻兘鏁版嵁
-  const archiveManagementItems = reactive([
-    {
-      icon: "/static/images/icon/gongyingshangdangan.svg",
-      label: "渚涘簲鍟嗘。妗�",
     },
   ]);
 
@@ -565,7 +539,7 @@
   const handleCommonItemClick = item => {
     // 鏍规嵁涓嶅悓鐨勫姛鑳介」杩涜璺宠浆
     switch (item.label) {
-      case "瀹㈡埛妗f":
+      case "瀹㈡埛妗f(绉佹捣)":
         uni.navigateTo({
           url: "/pages/basicData/customerFile/index",
         });
@@ -1110,8 +1084,8 @@
 
     // 瀹氫箟鑿滃崟閰嶇疆鏄犲皠
     const menuMapping = {
+      purchase: { target: purchaseItems, specialMapping: { "渚涘簲鍟嗘。妗�": "渚涘簲鍟嗙鐞�" } },
       collaboration: { target: collaborationItems, specialMapping: { "瑙勭珷鍒跺害": "瑙勭珷鍒跺害绠$悊" } },
-      archiveManagement: { target: archiveManagementItems, specialMapping: { "渚涘簲鍟嗘。妗�": "渚涘簲鍟嗙鐞�" } },
     };
     console.log(allowedMenuTitles)
     // 閫氱敤杩囨护鍑芥暟
@@ -1128,9 +1102,8 @@
 
     // 杩囨护鍚勪釜妯″潡
     filterArray(marketingItems);
-    filterArray(purchaseItems);
+    filterArray(purchaseItems, menuMapping.purchase.specialMapping);
     filterArray(financeManagementItems);
-    filterArray(archiveManagementItems, menuMapping.archiveManagement.specialMapping);
     filterArray(collaborationItems, menuMapping.collaboration.specialMapping);
     filterArray(safetyItems);
     filterArray(humanResourcesItems);
@@ -1144,7 +1117,6 @@
   const hasMarketingItems = computed(() => marketingItems.length > 0);
   const hasPurchaseItems = computed(() => purchaseItems.length > 0);
   const hasFinanceManagementItems = computed(() => financeManagementItems.length > 0);
-  const hasArchiveManagementItems = computed(() => archiveManagementItems.length > 0);
   const hasAfterSalesServiceItems = computed(() => afterSalesServiceItems.length > 0);
   const hasCollaborationItems = computed(() => collaborationItems.length > 0);
   const hasSafetyItems = computed(() => safetyItems.length > 0);
diff --git a/src/utils/versionUpgrade.js b/src/utils/versionUpgrade.js
index e0c818a..680b794 100644
--- a/src/utils/versionUpgrade.js
+++ b/src/utils/versionUpgrade.js
@@ -272,7 +272,7 @@
     lastVersionCheckAt = now;
     console.log(`${logPrefix} 瑙﹀彂鐗堟湰妫�鏌ワ紝鏉ユ簮=${from}`);
     const currentVersion = await getCurrentVersion(logPrefix);
-    await checkAppVersionUpgrade(logPrefix, currentVersion);
+    // await checkAppVersionUpgrade(logPrefix, currentVersion);
   };
 
   return { triggerVersionCheck };

--
Gitblit v1.9.3