From 0c4bdf3dca76f9b8c348f2f7e48f9a6319dee4e1 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期五, 17 四月 2026 17:09:22 +0800
Subject: [PATCH] 进销存升级 1.销售台账不能删除和编辑别人维护的数据 2.产品维护固定产品大类为:成品、半成品、原材料。

---
 src/views/salesManagement/salesQuotation/index.vue |  145 +++++++++++++++++++++++++++---------------------
 1 files changed, 82 insertions(+), 63 deletions(-)

diff --git a/src/views/salesManagement/salesQuotation/index.vue b/src/views/salesManagement/salesQuotation/index.vue
index d6f6c80..01174d7 100644
--- a/src/views/salesManagement/salesQuotation/index.vue
+++ b/src/views/salesManagement/salesQuotation/index.vue
@@ -70,8 +70,8 @@
         </el-table-column>
         <el-table-column label="鎿嶄綔" width="200" fixed="right" align="center">
           <template #default="scope">
-            <el-button link type="primary" @click="handleView(scope.row)">鏌ョ湅</el-button>
             <el-button link type="primary" @click="handleEdit(scope.row)" :disabled="!['寰呭鎵�','鎷掔粷'].includes(scope.row.status)">缂栬緫</el-button>
+            <el-button link type="primary" @click="handleView(scope.row)" style="color: #67C23A">鏌ョ湅</el-button>
             <el-button link type="danger" @click="handleDelete(scope.row)">鍒犻櫎</el-button>
           </template>
         </el-table-column>
@@ -103,18 +103,14 @@
             <el-row :gutter="24">
               <el-col :span="12">
                 <el-form-item label="瀹㈡埛鍚嶇О" prop="customer">
-                  <el-select v-model="form.customer" placeholder="璇烽�夋嫨瀹㈡埛" style="width: 100%" @change="handleCustomerChange" clearable>
-                    <el-option v-for="item in customerOption" :key="item.id" :label="item.customerName" :value="item.customerName">
-                      {{
-                        item.customerName + "鈥斺��" + item.taxpayerIdentificationNumber
-                      }}
-                    </el-option>
+                  <el-select v-model="form.customer" placeholder="璇烽�夋嫨瀹㈡埛" style="width: 100%" clearable filterable>
+                    <el-option v-for="item in customerOption" :key="item.id" :label="item.customerName" :value="item.id"></el-option>
                   </el-select>
                 </el-form-item>
               </el-col>
               <el-col :span="12">
                 <el-form-item label="涓氬姟鍛�" prop="salesperson">
-                  <el-select v-model="form.salesperson" placeholder="璇烽�夋嫨涓氬姟鍛�" style="width: 100%" clearable>
+                  <el-select v-model="form.salesperson" placeholder="璇烽�夋嫨涓氬姟鍛�" style="width: 100%" clearable filterable>
                     <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName"
                       :value="item.nickName" />
                   </el-select>
@@ -190,6 +186,7 @@
                         v-model="node.userId"
                         placeholder="閫夋嫨浜哄憳"
                         class="approver-select"
+												filterable
                         clearable
                       >
                         <el-option
@@ -231,43 +228,52 @@
             <el-table :data="form.products" border style="width: 100%" class="product-table" v-if="form.products.length > 0">
             <el-table-column prop="product" label="浜у搧鍚嶇О" width="200">
               <template #default="scope">
-								<el-tree-select
-									v-model="scope.row.productId"
-									placeholder="璇烽�夋嫨"
-									clearable
-									check-strictly
-									@change="getModels($event, scope.row)"
-									:data="productOptions"
-									:render-after-expand="false"
-									style="width: 100%"
-								/>
+                <el-form-item :prop="`products.${scope.$index}.productId`" class="product-table-form-item">
+                  <el-tree-select
+                    v-model="scope.row.productId"
+                    placeholder="璇烽�夋嫨"
+                    clearable
+                    check-strictly
+                    @change="getModels($event, scope.row)"
+                    :data="productOptions"
+                    :render-after-expand="false"
+                    style="width: 100%"
+                  />
+                </el-form-item>
               </template>
             </el-table-column>
-            <el-table-column prop="specification" label="瑙勬牸鍨嬪彿" width="150">
+            <el-table-column prop="specification" label="瑙勬牸鍨嬪彿" width="200">
               <template #default="scope">
-								<el-select
-									v-model="scope.row.specificationId"
-									placeholder="璇烽�夋嫨"
-									clearable
-									@change="getProductModel($event, scope.row)"
-								>
-									<el-option
-										v-for="item in scope.row.modelOptions || []"
-										:key="item.id"
-										:label="item.model"
-										:value="item.id"
-									/>
-								</el-select>
+                <el-form-item :prop="`products.${scope.$index}.specificationId`" class="product-table-form-item">
+                  <el-select
+                    v-model="scope.row.specificationId"
+                    placeholder="璇烽�夋嫨"
+                    clearable
+                    @change="getProductModel($event, scope.row)"
+                    style="width: 100%"
+                  >
+                    <el-option
+                      v-for="item in scope.row.modelOptions || []"
+                      :key="item.id"
+                      :label="item.model"
+                      :value="item.id"
+                    />
+                  </el-select>
+                </el-form-item>
               </template>
             </el-table-column>
             <el-table-column prop="unit" label="鍗曚綅">
               <template #default="scope">
-                <el-input v-model="scope.row.unit" placeholder="鍗曚綅" />
+                <el-form-item :prop="`products.${scope.$index}.unit`" class="product-table-form-item">
+                  <el-input v-model="scope.row.unit" placeholder="鍗曚綅" clearable/>
+                </el-form-item>
               </template>
             </el-table-column>
             <el-table-column prop="unitPrice" label="鍗曚环">
               <template #default="scope">
-                <el-input-number v-model="scope.row.unitPrice" :min="0" :precision="2" style="width: 100%" />
+                <el-form-item :prop="`products.${scope.$index}.unitPrice`" class="product-table-form-item">
+                  <el-input-number v-model="scope.row.unitPrice" :min="0" :precision="2" style="width: 100%" />
+                </el-form-item>
               </template>
             </el-table-column>
             <el-table-column label="鎿嶄綔" width="80" align="center">
@@ -354,6 +360,7 @@
 import {userListNoPage} from "@/api/system/user.js";
 import {customerList} from "@/api/salesManagement/salesLedger.js";
 import {modelList, productTreeList} from "@/api/basicData/product.js";
+import {listCustomerPrivatePool} from "@/api/basicData/customerFile.js";
 
 // 鍝嶅簲寮忔暟鎹�
 const loading = ref(false)
@@ -393,13 +400,30 @@
   totalAmount: 0
 })
 
-const rules = {
+const baseRules = {
   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 productRowRules = {
+  productId: [{ required: true, message: '璇烽�夋嫨浜у搧鍚嶇О', trigger: 'change' }],
+  specificationId: [{ required: true, message: '璇烽�夋嫨瑙勬牸鍨嬪彿', trigger: 'change' }],
+  unit: [{ required: true, message: '璇峰~鍐欏崟浣�', trigger: 'blur' }],
+  unitPrice: [{ required: true, message: '璇峰~鍐欏崟浠�', trigger: 'change' }]
+}
+const rules = computed(() => {
+  const r = { ...baseRules }
+  ;(form.products || []).forEach((_, i) => {
+    r[`products.${i}.productId`] = productRowRules.productId
+    r[`products.${i}.specificationId`] = productRowRules.specificationId
+    r[`products.${i}.unit`] = productRowRules.unit
+    r[`products.${i}.unitPrice`] = productRowRules.unitPrice
+  })
+  return r
+})
 const userList = ref([]);
 const customerOption = ref([]);
 
@@ -427,15 +451,6 @@
 // 璁$畻灞炴��
 const filteredList = computed(() => {
   let list = quotationList.value
-  if (searchForm.quotationNo) {
-    list = list.filter(item => item.quotationNo.includes(searchForm.quotationNo))
-  }
-  if (searchForm.customer) {
-    list = list.filter(item => item.customer === searchForm.customer)
-  }
-  if (searchForm.status) {
-    list = list.filter(item => item.status === searchForm.status)
-  }
   return list
 })
 
@@ -454,6 +469,9 @@
   searchForm.quotationNo = ''
   searchForm.customer = ''
   searchForm.status = ''
+  // 閲嶇疆鍒扮涓�椤靛苟閲嶆柊鏌ヨ
+  pagination.currentPage = 1
+  handleSearch()
 }
 
 const handleAdd = async () => {
@@ -472,13 +490,8 @@
     userName: item.userName || ''
   }));
 	getProductOptions();
-	customerList().then((res) => {
-		// 鍙鍒堕渶瑕佺殑瀛楁锛岄伩鍏嶅皢缁勪欢寮曠敤鏀惧叆鍝嶅簲寮忓璞�
-		customerOption.value = (Array.isArray(res) ? res : []).map(item => ({
-      id: item.id,
-      customerName: item.customerName || '',
-      taxpayerIdentificationNumber: item.taxpayerIdentificationNumber || ''
-    }))
+	listCustomerPrivatePool({current: -1,size:-1}).then((res) => {
+		customerOption.value = res.data.records;
 	});
 }
 const getProductOptions = () => {
@@ -763,10 +776,6 @@
   form.totalAmount = form.subtotal + form.freight + form.otherFee - form.discountAmount
 }
 
-const handleCustomerChange = () => {
-  // 鍙互鏍规嵁瀹㈡埛淇℃伅鑷姩濉厖涓�浜涢粯璁ゅ��
-}
-
 const handleSubmit = () => {
   formRef.value.validate((valid) => {
     if (valid) {
@@ -774,7 +783,7 @@
         ElMessage.warning('璇疯嚦灏戞坊鍔犱竴涓骇鍝�')
         return
       }
-      
+
       // 瀹℃壒浜哄繀濉牎楠�
       const hasEmptyApprover = approverNodes.value.some(node => !node.userId)
       if (hasEmptyApprover) {
@@ -822,10 +831,14 @@
 const handleCurrentChange = (val) => {
   pagination.currentPage = val.page
   pagination.pageSize = val.limit
+  // 鍒嗛〉鍙樺寲鏃堕噸鏂版煡璇㈠垪琛�
+  handleSearch()
 }
 const handleSearch = ()=>{
   const params = {
-    ...pagination,
+    // 鍚庣鍒嗛〉鍙傛暟锛歝urrent / size
+    current: pagination.currentPage,
+    size: pagination.pageSize,
     ...searchForm
   }
   getQuotationList(params).then(res=>{
@@ -865,12 +878,7 @@
     }
   })
 	customerList().then((res) => {
-		// 鍙鍒堕渶瑕佺殑瀛楁锛岄伩鍏嶅皢缁勪欢寮曠敤鏀惧叆鍝嶅簲寮忓璞�
-		customerOption.value = (Array.isArray(res) ? res : []).map(item => ({
-      id: item.id,
-      customerName: item.customerName || '',
-      taxpayerIdentificationNumber: item.taxpayerIdentificationNumber || ''
-    }))
+		customerOption.value = res;
 	});
 }
 
@@ -956,6 +964,17 @@
   padding: 8px 0;
 }
 
+.product-table-form-item {
+  margin-bottom: 0;
+  :deep(.el-form-item__content) {
+    margin-left: 0 !important;
+  }
+  :deep(.el-form-item__label) {
+    width: auto;
+    min-width: auto;
+  }
+}
+
 .approver-nodes-container {
   display: flex;
   flex-wrap: wrap;

--
Gitblit v1.9.3