From 4a811fb2cd4ee4e1cbfe284bfd1fe3a7d16204ce Mon Sep 17 00:00:00 2001
From: yuan <123@>
Date: 星期四, 02 四月 2026 17:35:48 +0800
Subject: [PATCH] fix: 终检表单优化检验用粉剂/液情况字段

---
 src/views/salesManagement/salesQuotation/index.vue |  303 ++++++++++++--------------------------------------
 1 files changed, 73 insertions(+), 230 deletions(-)

diff --git a/src/views/salesManagement/salesQuotation/index.vue b/src/views/salesManagement/salesQuotation/index.vue
index d6f6c80..9718a11 100644
--- a/src/views/salesManagement/salesQuotation/index.vue
+++ b/src/views/salesManagement/salesQuotation/index.vue
@@ -56,13 +56,6 @@
         <el-table-column prop="salesperson" label="涓氬姟鍛�" width="100" />
         <el-table-column prop="quotationDate" label="鎶ヤ环鏃ユ湡" width="120" />
         <el-table-column prop="validDate" label="鏈夋晥鏈熻嚦" width="120" />
-        <el-table-column prop="status" label="瀹℃壒鐘舵��" width="120" align="center">
-          <template #default="{ row }">
-            <el-tag :type="getStatusType(row.status)" disable-transitions>
-              {{ row.status || '--' }}
-            </el-tag>
-          </template>
-        </el-table-column>
         <el-table-column prop="totalAmount" label="鎶ヤ环閲戦" width="120">
           <template #default="scope">
             楼{{ scope.row.totalAmount.toFixed(2) }}
@@ -71,7 +64,7 @@
         <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="handleEdit(scope.row)">缂栬緫</el-button>
             <el-button link type="danger" @click="handleDelete(scope.row)">鍒犻櫎</el-button>
           </template>
         </el-table-column>
@@ -149,69 +142,13 @@
                 </el-form-item>
               </el-col>
             </el-row>
-            <el-row :gutter="24">
+            <!-- <el-row :gutter="24">
               <el-col :span="12">
                 <el-form-item label="浠樻鏂瑰紡" prop="paymentMethod">
                   <el-input v-model="form.paymentMethod" placeholder="璇疯緭鍏ヤ粯娆炬柟寮�" clearable />
                 </el-form-item>
               </el-col>
-            </el-row>
-          </div>
-        </el-card>
-
-        <!-- 瀹℃壒浜轰俊鎭� -->
-        <el-card class="form-card" shadow="hover">
-          <template #header>
-            <div class="card-header-wrapper">
-              <el-icon class="card-icon"><UserFilled /></el-icon>
-              <span class="card-title">瀹℃壒浜洪�夋嫨</span>
-              <el-button type="primary" size="small" @click="addApproverNode" class="header-btn">
-                <el-icon><Plus /></el-icon>
-                鏂板鑺傜偣
-              </el-button>
-            </div>
-          </template>
-          <div class="form-content">
-            <el-row>
-              <el-col :span="24">
-                <el-form-item>
-                  <div class="approver-nodes-container">
-                    <div
-                      v-for="(node, index) in approverNodes"
-                      :key="node.id"
-                      class="approver-node-item"
-                    >
-                      <div class="approver-node-label">
-                        <span class="node-step">{{ index + 1 }}</span>
-                        <span class="node-text">瀹℃壒浜�</span>
-                        <el-icon class="arrow-icon"><ArrowRight /></el-icon>
-                      </div>
-                      <el-select
-                        v-model="node.userId"
-                        placeholder="閫夋嫨浜哄憳"
-                        class="approver-select"
-                        clearable
-                      >
-                        <el-option
-                          v-for="user in userList"
-                          :key="user.userId"
-                          :label="user.nickName"
-                          :value="user.userId"
-                        />
-                      </el-select>
-                      <el-button
-                        type="danger"
-                        size="small"
-                        :icon="Delete"
-                        @click="removeApproverNode(index)"
-                        v-if="approverNodes.length > 1"
-                        class="remove-btn"
-                      >鍒犻櫎</el-button>
-                    </div>
-                  </div>
-                </el-form-item>
-              </el-col>
-            </el-row>
+            </el-row> -->
           </div>
         </el-card>
 
@@ -231,43 +168,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">
@@ -347,7 +293,7 @@
 <script setup>
 import { ref, reactive, computed, onMounted, markRaw, shallowRef } from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
-import { Search, Document, UserFilled, Box, EditPen, Plus, ArrowRight, Delete } from '@element-plus/icons-vue'
+import { Search, Document, Box, EditPen, Plus } from '@element-plus/icons-vue'
 import Pagination from '@/components/PIMTable/Pagination.vue'
 import FormDialog from '@/components/Dialog/FormDialog.vue'
 import {getQuotationList,addQuotation,updateQuotation,deleteQuotation} from '@/api/salesManagement/salesQuotation.js'
@@ -393,76 +339,58 @@
   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([]);
-
-// 瀹℃壒浜鸿妭鐐圭浉鍏�
-const approverNodes = ref([
-  { id: 1, userId: null }
-])
-let nextApproverId = 2
 
 const isEdit = ref(false)
 const editId = ref(null)
 const currentQuotation = ref({})
 const formRef = ref()
 
-// 娣诲姞瀹℃壒浜鸿妭鐐�
-function addApproverNode() {
-  approverNodes.value.push({ id: nextApproverId++, userId: null })
-}
-
-// 鍒犻櫎瀹℃壒浜鸿妭鐐�
-function removeApproverNode(index) {
-  approverNodes.value.splice(index, 1)
-}
-
 // 璁$畻灞炴��
 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
 })
 
 // 鏂规硶
-const getStatusType = (status) => {
-  const statusMap = {
-    '寰呭鎵�': 'info',
-    '瀹℃牳涓�': 'primary',
-    '閫氳繃': 'success',
-    '鎷掔粷': 'danger'
-  }
-  return statusMap[status] || 'info'
-}
-
 const resetSearch = () => {
   searchForm.quotationNo = ''
   searchForm.customer = ''
   searchForm.status = ''
+  // 閲嶇疆鍒扮涓�椤靛苟閲嶆柊鏌ヨ
+  pagination.currentPage = 1
+  handleSearch()
 }
 
 const handleAdd = async () => {
   dialogTitle.value = '鏂板鎶ヤ环'
   isEdit.value = false
   resetForm()
-  // 閲嶇疆瀹℃壒浜鸿妭鐐�
-  approverNodes.value = [{ id: 1, userId: null }]
-  nextApproverId = 2
   dialogVisible.value = true
 	let userLists = await userListNoPage();
 	// 鍙鍒堕渶瑕佺殑瀛楁锛岄伩鍏嶅皢缁勪欢寮曠敤鏀惧叆鍝嶅簲寮忓璞�
@@ -664,19 +592,6 @@
   form.discountAmount = row.discountAmount || 0
   form.totalAmount = row.totalAmount || 0
   
-  // 鍙嶆樉瀹℃壒浜�
-  if (row.approveUserIds) {
-    const userIds = row.approveUserIds.split(',')
-    approverNodes.value = userIds.map((userId, idx) => ({
-      id: idx + 1,
-      userId: parseInt(userId.trim())
-    }))
-    nextApproverId = userIds.length + 1
-  } else {
-    approverNodes.value = [{ id: 1, userId: null }]
-    nextApproverId = 2
-  }
-  
   // 鍔犺浇鐢ㄦ埛鍒楄〃
   let userLists = await userListNoPage();
   userList.value = (userLists.data || []).map(item => ({
@@ -774,17 +689,7 @@
         ElMessage.warning('璇疯嚦灏戞坊鍔犱竴涓骇鍝�')
         return
       }
-      
-      // 瀹℃壒浜哄繀濉牎楠�
-      const hasEmptyApprover = approverNodes.value.some(node => !node.userId)
-      if (hasEmptyApprover) {
-        ElMessage.error('璇蜂负鎵�鏈夊鎵硅妭鐐归�夋嫨瀹℃壒浜猴紒')
-        return
-      }
-      
-      // 鏀堕泦鎵�鏈夎妭鐐圭殑瀹℃壒浜篿d
-      form.approveUserIds = approverNodes.value.map(node => node.userId).join(',')
-      
+
       // 璁$畻鎵�鏈変骇鍝佺殑鍗曚环鎬诲拰
       form.totalAmount = form.products.reduce((sum, product) => {
         const price = Number(product.unitPrice) || 0
@@ -822,10 +727,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=>{
@@ -841,8 +750,6 @@
         validDate: item.validDate || '',
         paymentMethod: item.paymentMethod || '',
         status: item.status || '鑽夌',
-        // 瀹℃壒浜猴紙鐢ㄤ簬缂栬緫鏃跺弽鏄撅級
-        approveUserIds: item.approveUserIds || '',
         remark: item.remark || '',
         products: item.products ? item.products.map(product => ({
           productId: product.productId || '',
@@ -956,69 +863,15 @@
   padding: 8px 0;
 }
 
-.approver-nodes-container {
-  display: flex;
-  flex-wrap: wrap;
-  gap: 24px;
-  padding: 12px 0;
-}
-
-.approver-node-item {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  gap: 12px;
-  padding: 16px;
-  background: #f8f9fa;
-  border-radius: 8px;
-  border: 1px solid #e4e7ed;
-  transition: all 0.3s ease;
-  min-width: 180px;
-  
-  &:hover {
-    border-color: #409eff;
-    background: #f0f7ff;
-    box-shadow: 0 2px 8px rgba(64, 158, 255, 0.1);
+.product-table-form-item {
+  margin-bottom: 0;
+  :deep(.el-form-item__content) {
+    margin-left: 0 !important;
   }
-}
-
-.approver-node-label {
-  display: flex;
-  align-items: center;
-  gap: 8px;
-  font-size: 14px;
-  color: #606266;
-  
-  .node-step {
-    display: inline-flex;
-    align-items: center;
-    justify-content: center;
-    width: 24px;
-    height: 24px;
-    background: #409eff;
-    color: #fff;
-    border-radius: 50%;
-    font-size: 12px;
-    font-weight: 600;
+  :deep(.el-form-item__label) {
+    width: auto;
+    min-width: auto;
   }
-  
-  .node-text {
-    font-weight: 500;
-  }
-  
-  .arrow-icon {
-    color: #909399;
-    font-size: 14px;
-  }
-}
-
-.approver-select {
-  width: 100%;
-  min-width: 150px;
-}
-
-.remove-btn {
-  margin-top: 4px;
 }
 
 .product-table {
@@ -1047,14 +900,4 @@
   text-align: right;
 }
 
-// 鍝嶅簲寮忎紭鍖�
-@media (max-width: 1200px) {
-  .approver-nodes-container {
-    gap: 16px;
-  }
-  
-  .approver-node-item {
-    min-width: 160px;
-  }
-}
 </style>

--
Gitblit v1.9.3