From ca56bf22820d13898e64ca683cc03927dfc4459d Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期四, 06 八月 2026 10:24:37 +0800
Subject: [PATCH] 新疆_马铃薯 1.原材料和过程检验的检测公司赋默认值

---
 src/views/procurementManagement/procurementLedger/index.vue |  748 +++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 648 insertions(+), 100 deletions(-)

diff --git a/src/views/procurementManagement/procurementLedger/index.vue b/src/views/procurementManagement/procurementLedger/index.vue
index adf7b6e..47ec1e4 100644
--- a/src/views/procurementManagement/procurementLedger/index.vue
+++ b/src/views/procurementManagement/procurementLedger/index.vue
@@ -4,6 +4,14 @@
       <div>
         <el-form :model="searchForm"
                  :inline="true">
+          <el-form-item label="鎬诲悎鍚屽彿锛�">
+            <el-input v-model="searchForm.masterContractNo"
+                      style="width: 240px"
+                      placeholder="璇疯緭鍏�"
+                      @change="handleQuery"
+                      clearable
+                      :prefix-icon="Search" />
+          </el-form-item>
           <el-form-item label="渚涘簲鍟嗗悕绉帮細">
             <el-input v-model="searchForm.supplierName"
                       placeholder="璇疯緭鍏�"
@@ -19,13 +27,13 @@
                       clearable
                       :prefix-icon="Search" />
           </el-form-item>
-          <el-form-item label="閿�鍞悎鍚屽彿锛�">
-            <el-input v-model="searchForm.salesContractNo"
-                      placeholder="璇疯緭鍏�"
-                      clearable
-                      prefix-icon="Search"
-                      @change="handleQuery" />
-          </el-form-item>
+<!--          <el-form-item label="璁㈠崟鍙凤細">-->
+<!--            <el-input v-model="searchForm.salesContractNo"-->
+<!--                      placeholder="璇疯緭鍏�"-->
+<!--                      clearable-->
+<!--                      prefix-icon="Search"-->
+<!--                      @change="handleQuery" />-->
+<!--          </el-form-item>-->
           <el-form-item label="椤圭洰鍚嶇О锛�">
             <el-input v-model="searchForm.projectName"
                       placeholder="璇疯緭鍏�"
@@ -42,6 +50,20 @@
                             clearable
                             @change="changeDaterange" />
           </el-form-item>
+          <el-form-item label="鍏ュ簱鐘舵�侊細">
+            <el-select v-model="searchForm.stockInStatus"
+                       placeholder="璇烽�夋嫨"
+                       clearable
+                       style="width: 240px"
+                       @change="handleQuery">
+              <el-option label="寰呭叆搴�"
+                         value="寰呭叆搴�" />
+              <el-option label="鍏ュ簱涓�"
+                         value="鍏ュ簱涓�" />
+              <el-option label="瀹屽叏鍏ュ簱"
+                         value="瀹屽叏鍏ュ簱" />
+            </el-select>
+          </el-form-item>
           <el-form-item>
             <el-button type="primary"
                        @click="handleQuery"> 鎼滅储
@@ -52,6 +74,9 @@
     </div>
     <div class="table_list">
       <div style="display: flex;justify-content: flex-end;margin-bottom: 20px;">
+<!--        <el-button type="success"-->
+<!--                   plain-->
+<!--                   @click="handleBatchGenerate">鎵归噺鐢熸垚鏁版嵁</el-button>-->
         <el-button type="primary"
                    @click="openForm('add')">鏂板鍙拌处</el-button>
         <el-button type="primary"
@@ -60,7 +85,7 @@
         <el-button @click="handleOut">瀵煎嚭</el-button>
         <el-button type="danger"
                    plain
-                   @click="handleDelete">鍒犻櫎
+                   @click="handleDelete" v-hasPermi="['procurementManagement:procurementLedger:remove']">鍒犻櫎
         </el-button>
       </div>
       <el-table :data="tableData"
@@ -86,29 +111,97 @@
                                label="搴忓彿"
                                type="index"
                                width="60" />
+              <el-table-column label="绫诲瀷"
+                               prop="productType"
+                               width="100">
+                <template #default="scope">
+                  <el-tag :type="scope.row.productType === 2 ? 'warning' : 'success'" size="small">
+                    {{ scope.row.productType === 2 ? '璁惧澶囦欢' : '浜у搧' }}
+                  </el-tag>
+                </template>
+              </el-table-column>
               <el-table-column label="浜у搧澶х被"
                                prop="productCategory" />
               <el-table-column label="瑙勬牸鍨嬪彿"
-                               prop="specificationModel" />
+                               prop="specificationModel"
+                               width="120">
+                <template #default="scope">
+                  <span v-if="scope.row.productType === 2">/</span>
+                  <span v-else>{{ scope.row.specificationModel || '--' }}</span>
+                </template>
+              </el-table-column>
               <el-table-column label="鍗曚綅"
-                               prop="unit" />
+                               prop="unit"
+                               width="100">
+                <template #default="scope">
+                  <span v-if="scope.row.productType === 2">--</span>
+                  <span v-else>{{ scope.row.unit || '--' }}</span>
+                </template>
+              </el-table-column>
+              <el-table-column label="鍏ュ簱瀹℃牳鐘舵��"
+                               prop="stockInApprovalStatus"
+                               width="120">
+                <template #default="scope">
+                  <el-tag :type="getStockInApprovalStatusType(scope.row.stockInApprovalStatus)"
+                          size="small">
+                    {{ scope.row.stockInApprovalStatus || '--' }}
+                  </el-tag>
+                </template>
+              </el-table-column>
               <el-table-column label="鏁伴噺"
-                               prop="quantity" />
+                               prop="quantity"
+                               width="100" />
               <el-table-column label="鍙敤鏁伴噺"
-                               prop="availableQuality" />
+                               prop="availableQuality"
+                               width="100">
+                <template #default="scope">
+                  <span v-if="scope.row.productType === 2">--</span>
+                  <span v-else>{{ scope.row.availableQuality }}</span>
+                </template>
+              </el-table-column>
               <el-table-column label="閫�璐ф暟閲�"
-                               prop="returnQuality" />
+                               prop="returnQuality"
+                               width="100">
+                <template #default="scope">
+                  <span v-if="scope.row.productType === 2">--</span>
+                  <span v-else>{{ scope.row.returnQuality }}</span>
+                </template>
+              </el-table-column>
               <el-table-column label="绋庣巼(%)"
-                               prop="taxRate" />
+                               prop="taxRate"
+                               width="100">
+                <template #default="scope">
+                  <span v-if="scope.row.productType === 2">--</span>
+                  <span v-else>{{ scope.row.taxRate }}</span>
+                </template>
+              </el-table-column>
               <el-table-column label="鍚◣鍗曚环(鍏�)"
                                prop="taxInclusiveUnitPrice"
-                               :formatter="formattedNumber" />
+                               :formatter="formattedNumber"
+                               width="130">
+                <template #default="scope">
+                  <span v-if="scope.row.productType === 2">--</span>
+                  <span v-else>{{ formattedNumber(null, null, scope.row.taxInclusiveUnitPrice) }}</span>
+                </template>
+              </el-table-column>
               <el-table-column label="鍚◣鎬讳环(鍏�)"
                                prop="taxInclusiveTotalPrice"
-                               :formatter="formattedNumber" />
+                               :formatter="formattedNumber"
+                               width="130">
+                <template #default="scope">
+                  <span v-if="scope.row.productType === 2">--</span>
+                  <span v-else>{{ formattedNumber(null, null, scope.row.taxInclusiveTotalPrice) }}</span>
+                </template>
+              </el-table-column>
               <el-table-column label="涓嶅惈绋庢�讳环(鍏�)"
                                prop="taxExclusiveTotalPrice"
-                               :formatter="formattedNumber" />
+                               :formatter="formattedNumber"
+                               width="140">
+                <template #default="scope">
+                  <span v-if="scope.row.productType === 2">--</span>
+                  <span v-else>{{ formattedNumber(null, null, scope.row.taxExclusiveTotalPrice) }}</span>
+                </template>
+              </el-table-column>
             </el-table>
           </template>
         </el-table-column>
@@ -116,14 +209,18 @@
                          label="搴忓彿"
                          type="index"
                          width="60" />
+        <el-table-column label="鎬诲悎鍚屽彿"
+                         prop="masterContractNo"
+                         width="150"
+                         show-overflow-tooltip />
         <el-table-column label="閲囪喘鍚堝悓鍙�"
                          prop="purchaseContractNumber"
                          width="160"
                          show-overflow-tooltip />
-        <el-table-column label="閿�鍞悎鍚屽彿"
-                         prop="salesContractNo"
-                         width="160"
-                         show-overflow-tooltip />
+<!--        <el-table-column label="璁㈠崟鍙�"-->
+<!--                         prop="salesContractNo"-->
+<!--                         width="160"-->
+<!--                         show-overflow-tooltip />-->
         <el-table-column label="渚涘簲鍟嗗悕绉�"
                          prop="supplierName"
                          width="160"
@@ -143,6 +240,17 @@
             </el-tag>
           </template>
         </el-table-column>
+<!--        <el-table-column label="鍏ュ簱鐘舵��"-->
+<!--                         prop="stockInStatus"-->
+<!--                         width="100"-->
+<!--                         show-overflow-tooltip>-->
+<!--          <template #default="scope">-->
+<!--            <el-tag :type="getStockInStatusType(scope.row.stockInStatus)"-->
+<!--                    size="small">-->
+<!--              {{ scope.row.stockInStatus || '&#45;&#45;' }}-->
+<!--            </el-tag>-->
+<!--          </template>-->
+<!--        </el-table-column>-->
         <el-table-column label="绛捐鏃ユ湡"
                          prop="executionDate"
                          width="100"
@@ -170,17 +278,21 @@
                          show-overflow-tooltip />
         <el-table-column fixed="right"
                          label="鎿嶄綔"
-                         width="120"
+                         width="200"
                          align="center">
           <template #default="scope">
             <el-button link
                        type="primary"
-                       @click="openForm('edit', scope.row)"
-                       :disabled="scope.row.approvalStatus !== 1 && scope.row.approvalStatus !== 4">缂栬緫
+                       @click="openForm('edit', scope.row)">缂栬緫
             </el-button>
             <el-button link
                        type="primary"
                        @click="openFileDialog(scope.row)">闄勪欢</el-button>
+            <el-button link
+                       type="primary"
+                       v-if="scope.row.masterContractNo"
+                       @click="openContractFileDialog(scope.row)">鎬诲悎鍚岄檮浠�
+            </el-button>
           </template>
         </el-table-column>
       </el-table>
@@ -212,21 +324,21 @@
                         clearable />
             </el-form-item>
           </el-col>
-          <el-col :span="12">
-            <el-form-item label="閿�鍞悎鍚屽彿锛�"
-                          prop="salesLedgerId">
-              <el-select v-model="form.salesLedgerId"
-                         placeholder="璇烽�夋嫨"
-                         filterable
-                         clearable
-                         @change="salesLedgerChange">
-                <el-option v-for="item in salesContractList"
-                           :key="item.id"
-                           :label="item.salesContractNo"
-                           :value="item.id" />
-              </el-select>
-            </el-form-item>
-          </el-col>
+<!--          <el-col :span="12">-->
+<!--            <el-form-item label="璁㈠崟鍙凤細"-->
+<!--                          prop="salesLedgerId">-->
+<!--              <el-select v-model="form.salesLedgerId"-->
+<!--                         placeholder="璇烽�夋嫨"-->
+<!--                         filterable-->
+<!--                         clearable-->
+<!--                         @change="salesLedgerChange">-->
+<!--                <el-option v-for="item in salesContractList"-->
+<!--                           :key="item.id"-->
+<!--                           :label="item.salesContractNo"-->
+<!--                           :value="item.id" />-->
+<!--              </el-select>-->
+<!--            </el-form-item>-->
+<!--          </el-col>-->
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
@@ -235,7 +347,8 @@
               <el-select v-model="form.supplierId"
                          placeholder="璇烽�夋嫨"
                          filterable
-                         clearable>
+                         clearable
+                         @change="handleSupplierChange">
                 <el-option v-for="item in supplierList"
                            :key="item.id"
                            :label="item.supplierName"
@@ -244,6 +357,22 @@
               </el-select>
             </el-form-item>
           </el-col>
+          <el-col :span="12">
+            <el-form-item label="鎬诲悎鍚屽彿锛�">
+              <el-select v-model="form.masterContractNo"
+                         placeholder="璇峰厛閫夋嫨渚涘簲鍟�"
+                         filterable
+                         clearable
+                         :disabled="!form.supplierId">
+                <el-option v-for="item in contractList"
+                           :key="item.id"
+                           :label="item.masterContractNo"
+                           :value="item.masterContractNo" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
           <el-col :span="12">
             <el-form-item label="椤圭洰鍚嶇О"
                           prop="projectName">
@@ -256,9 +385,16 @@
         <el-row :gutter="30">
           <el-col :span="12">
             <el-form-item label="浠樻鏂瑰紡">
-              <el-input v-model="form.paymentMethod"
-                        placeholder="璇疯緭鍏�"
-                        clearable />
+              <el-select v-model="form.paymentMethod"
+                         placeholder="璇烽�夋嫨"
+                         clearable
+                         style="width: 100%">
+                <el-option label="鐜伴噾" value="鐜伴噾" />
+                <el-option label="鐢垫眹" value="鐢垫眹" />
+                <el-option label="寰俊" value="寰俊" />
+                <el-option label="鏀粯瀹�" value="鏀粯瀹�" />
+                <el-option label="鏀エ" value="鏀エ" />
+              </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="12">
@@ -306,10 +442,12 @@
           <el-form-item label="浜у搧淇℃伅锛�"
                         prop="entryDate">
             <el-button type="primary"
+                       v-if="form.approvalStatus !== 3"
                        @click="openProductForm('add')">娣诲姞
             </el-button>
             <el-button plain
                        type="danger"
+                       v-if="form.approvalStatus !== 3"
                        @click="deleteProduct">鍒犻櫎
             </el-button>
           </el-form-item>
@@ -365,41 +503,126 @@
                            label="搴忓彿"
                            type="index"
                            width="60" />
+          <el-table-column label="绫诲瀷"
+                           prop="productType"
+                           width="100">
+            <template #default="scope">
+              <el-tag :type="scope.row.productType === 2 ? 'warning' : 'success'" size="small">
+                {{ scope.row.productType === 2 ? '璁惧澶囦欢' : '浜у搧' }}
+              </el-tag>
+            </template>
+          </el-table-column>
           <el-table-column label="浜у搧澶х被"
                            prop="productCategory" />
           <el-table-column label="瑙勬牸鍨嬪彿"
-                           prop="specificationModel" />
+                           prop="specificationModel"
+                           width="120">
+            <template #default="scope">
+              <span v-if="scope.row.productType === 2">/</span>
+              <span v-else>{{ scope.row.specificationModel || '--' }}</span>
+            </template>
+          </el-table-column>
           <el-table-column label="鍗曚綅"
                            prop="unit"
-                           width="70" />
+                           width="70">
+            <template #default="scope">
+              <span v-if="scope.row.productType === 2">--</span>
+              <span v-else>{{ scope.row.unit || '--' }}</span>
+            </template>
+          </el-table-column>
           <el-table-column label="鏁伴噺"
                            prop="quantity"
                            width="70" />
           <el-table-column label="搴撳瓨棰勮鏁伴噺"
                            prop="warnNum"
                            width="120"
-                           show-overflow-tooltip />
+                           show-overflow-tooltip>
+            <template #default="scope">
+              <span v-if="scope.row.productType === 2">--</span>
+              <span v-else>{{ scope.row.warnNum }}</span>
+            </template>
+          </el-table-column>
           <el-table-column label="绋庣巼(%)"
                            prop="taxRate"
-                           width="80" />
+                           width="80">
+            <template #default="scope">
+              <span v-if="scope.row.productType === 2">--</span>
+              <span v-else>{{ scope.row.taxRate }}</span>
+            </template>
+          </el-table-column>
           <el-table-column label="鍚◣鍗曚环(鍏�)"
                            prop="taxInclusiveUnitPrice"
                            :formatter="formattedNumber"
-                           width="150" />
+                           width="130">
+            <template #default="scope">
+              <span v-if="scope.row.productType === 2">--</span>
+              <span v-else>{{ formattedNumber(null, null, scope.row.taxInclusiveUnitPrice) }}</span>
+            </template>
+          </el-table-column>
           <el-table-column label="鍚◣鎬讳环(鍏�)"
                            prop="taxInclusiveTotalPrice"
                            :formatter="formattedNumber"
-                           width="150" />
+                           width="130">
+            <template #default="scope">
+              <span v-if="scope.row.productType === 2">--</span>
+              <span v-else>{{ formattedNumber(null, null, scope.row.taxInclusiveTotalPrice) }}</span>
+            </template>
+          </el-table-column>
           <el-table-column label="涓嶅惈绋庢�讳环(鍏�)"
                            prop="taxExclusiveTotalPrice"
                            :formatter="formattedNumber"
-                           width="150" />
+                           width="140">
+            <template #default="scope">
+              <span v-if="scope.row.productType === 2">--</span>
+              <span v-else>{{ formattedNumber(null, null, scope.row.taxExclusiveTotalPrice) }}</span>
+            </template>
+          </el-table-column>
           <el-table-column label="鏄惁璐ㄦ"
                            prop="isChecked"
+                           width="100">
+            <template #default="scope">
+              <span v-if="scope.row.productType === 2">--</span>
+              <el-tag v-else :type="scope.row.isChecked ? 'success' : 'info'">
+                {{ scope.row.isChecked ? '鏄�' : '鍚�' }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column label="閫夋嫨璁惧"
+                           prop="deviceId"
                            width="150">
             <template #default="scope">
-              <el-tag :type="scope.row.isChecked ? 'success' : 'info'">
-                {{ scope.row.isChecked ? '鏄�' : '鍚�' }}
+              <span v-if="scope.row.productType === 2">--</span>
+              <el-select v-else
+                         v-model="scope.row.deviceId"
+                         placeholder="璇烽�夋嫨璁惧"
+                         filterable
+                         clearable
+                         @change="handleDeviceChange(scope.row, scope.$index)">
+                <el-option v-for="device in iotDeviceList"
+                           :key="device.id"
+                           :label="device.deviceName"
+                           :value="device.id" />
+              </el-select>
+            </template>
+          </el-table-column>
+          <el-table-column label="搴撲綅"
+                           prop="storageLocation"
+                           width="120">
+            <template #default="scope">
+              <span v-if="scope.row.productType === 2">--</span>
+              <el-input v-else
+                        v-model="scope.row.storageLocation"
+                        placeholder="鑷姩鑾峰彇"
+                        disabled />
+            </template>
+          </el-table-column>
+          <el-table-column label="鍏ュ簱瀹℃牳鐘舵��"
+                           prop="stockInApprovalStatus"
+                           width="120">
+            <template #default="scope">
+              <el-tag :type="getStockInApprovalStatusType(scope.row.stockInApprovalStatus)"
+                      size="small">
+                {{ scope.row.stockInApprovalStatus || '--' }}
               </el-tag>
             </template>
           </el-table-column>
@@ -410,7 +633,8 @@
             <template #default="scope">
               <el-button link
                          type="primary"
-                         @click="openProductForm('edit', scope.row, scope.$index)">缂栬緫
+                         @click="openProductForm('edit', scope.row, scope.$index)"
+                         :disabled="form.approvalStatus === 3">缂栬緫
               </el-button>
             </template>
           </el-table-column>
@@ -484,9 +708,21 @@
                ref="productFormRef">
         <el-row :gutter="30">
           <el-col :span="24">
+            <el-form-item label="绫诲瀷锛�"
+                          prop="productType">
+              <el-radio-group v-model="productForm.productType" @change="handleProductTypeChange">
+                <el-radio :label="1">浜у搧</el-radio>
+                <el-radio :label="2">璁惧澶囦欢</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="24">
             <el-form-item label="浜у搧澶х被锛�"
                           prop="productId">
-              <el-tree-select v-model="productForm.productId"
+              <el-tree-select v-if="productForm.productType !== 2"
+                              v-model="productForm.productId"
                               placeholder="璇烽�夋嫨"
                               clearable
                               filterable
@@ -495,10 +731,22 @@
                               :data="productOptions"
                               :render-after-expand="false"
                               style="width: 100%" />
+              <el-select v-else
+                         v-model="productForm.productId"
+                         placeholder="璇烽�夋嫨璁惧澶囦欢"
+                         filterable
+                         clearable
+                         @change="handleSparePartsChange"
+                         style="width: 100%">
+                <el-option v-for="item in sparePartsOptions"
+                           :key="item.id"
+                           :label="item.name"
+                           :value="item.id" />
+              </el-select>
             </el-form-item>
           </el-col>
         </el-row>
-        <el-row :gutter="30">
+        <el-row :gutter="30" v-if="productForm.productType !== 2">
           <el-col :span="24">
             <el-form-item label="瑙勬牸鍨嬪彿锛�"
                           prop="productModelId">
@@ -515,7 +763,7 @@
             </el-form-item>
           </el-col>
         </el-row>
-        <el-row :gutter="30">
+        <el-row :gutter="30" v-if="productForm.productType !== 2">
           <el-col :span="12">
             <el-form-item label="鍗曚綅锛�"
                           prop="unit">
@@ -539,7 +787,7 @@
             </el-form-item>
           </el-col>
         </el-row>
-        <el-row :gutter="30">
+        <el-row :gutter="30" v-if="productForm.productType !== 2">
           <el-col :span="12">
             <el-form-item label="鍚◣鍗曚环(鍏�)锛�"
                           prop="taxInclusiveUnitPrice">
@@ -566,7 +814,21 @@
             </el-form-item>
           </el-col>
         </el-row>
-        <el-row :gutter="30">
+        <el-row :gutter="30" v-if="productForm.productType === 2">
+          <el-col :span="24">
+            <el-form-item label="鏁伴噺锛�"
+                          prop="quantity">
+              <el-input-number :step="0.1"
+                               clearable
+                               :precision="2"
+                               :min="0"
+                               style="width: 100%"
+                               v-model="productForm.quantity"
+                               placeholder="璇疯緭鍏�" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30" v-if="productForm.productType !== 2">
           <el-col :span="12">
             <el-form-item label="鍚◣鎬讳环(鍏�)锛�"
                           prop="taxInclusiveTotalPrice">
@@ -606,7 +868,7 @@
               </el-select>
             </el-form-item>
           </el-col>
-          <el-col :span="12">
+          <el-col :span="12" v-if="productForm.productType !== 2">
             <el-form-item label="搴撳瓨棰勮鏁伴噺锛�"
                           prop="warnNum">
               <el-input-number v-model="productForm.warnNum"
@@ -618,7 +880,33 @@
             </el-form-item>
           </el-col>
         </el-row>
-        <el-row :gutter="30">
+        <el-row :gutter="30" v-if="productForm.productType !== 2">
+          <el-col :span="12">
+            <el-form-item label="閫夋嫨璁惧锛�"
+                          prop="deviceId">
+              <el-select v-model="productForm.deviceId"
+                         placeholder="璇烽�夋嫨璁惧"
+                         filterable
+                         clearable
+                         style="width: 100%"
+                         @change="handleProductDeviceChange">
+                <el-option v-for="device in iotDeviceList"
+                           :key="device.id"
+                           :label="device.deviceName"
+                           :value="device.id" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="搴撲綅锛�"
+                          prop="storageLocation">
+              <el-input v-model="productForm.storageLocation"
+                        placeholder="閫夋嫨璁惧鍚庤嚜鍔ㄨ幏鍙�"
+                        disabled />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30" v-if="productForm.productType !== 2">
           <el-col :span="12">
             <el-form-item label="鏄惁璐ㄦ锛�"
                           prop="isChecked">
@@ -637,6 +925,28 @@
               v-model:visible="fileListDialogVisible"
               record-type="purchase_ledger"
               :record-id="recordId" />
+    <!-- 鎬诲悎鍚岄檮浠跺脊绐� -->
+    <el-dialog
+      v-model="contractFileDialogVisible"
+      title="鎬诲悎鍚岄檮浠�"
+      width="700px"
+      :close-on-click-modal="false">
+      <el-table :data="contractFileList" border v-if="contractFileList.length">
+        <el-table-column prop="name" label="鏂囦欢鍚嶇О" show-overflow-tooltip />
+        <el-table-column prop="byteSize" label="鏂囦欢澶у皬" width="120">
+          <template #default="{ row }">
+            {{ formatFileSize(row.byteSize) }}
+          </template>
+        </el-table-column>
+        <el-table-column label="鎿嶄綔" width="150">
+          <template #default="{ row }">
+            <el-link type="primary" :href="row.previewURL" target="_blank">棰勮</el-link>
+            <el-link type="primary" :href="row.downloadURL" style="margin-left: 10px">涓嬭浇</el-link>
+          </template>
+        </el-table-column>
+      </el-table>
+      <el-empty v-else description="鏆傛棤闄勪欢" />
+    </el-dialog>
   </div>
 </template>
 
@@ -675,6 +985,7 @@
     getOptions,
     getPurchaseTemplateList,
     delPurchaseTemplate,
+    batchGeneratePurchaseInboundSteps,
   } from "@/api/procurementManagement/procurementLedger.js";
   import useFormData from "@/hooks/useFormData.js";
   const FileList = defineAsyncComponent(() =>
@@ -690,8 +1001,13 @@
   const modelOptions = ref([]);
   const userList = ref([]);
   const productOptions = ref([]);
+  const sparePartsOptions = ref([]);
   const salesContractList = ref([]);
   const supplierList = ref([]);
+  const contractList = ref([]); // 渚涘簲鍟嗗悎鍚屽垪琛�
+  const iotDeviceList = ref([]); // IoT璁惧鍒楄〃
+  const contractFileDialogVisible = ref(false);
+  const contractFileList = ref([]);
   const tableLoading = ref(false);
   const recordId = ref();
   const fileListDialogVisible = ref(false);
@@ -703,6 +1019,9 @@
   const fileList = ref([]);
   import useUserStore from "@/store/modules/user";
   import { modelList, productTreeList } from "@/api/basicData/product.js";
+  import { getSparePartsList } from "@/api/equipmentManagement/spareParts.js";
+  import { getSupplierContractList, getSupplierContractFilesByNo } from "@/api/basicData/supplierContract.js";
+  import { getIotDeviceList as getIotDeviceListApi } from "@/api/equipmentManagement/ledger.js";
   import dayjs from "dayjs";
   import FileUpload from "@/components/AttachmentUpload/file/index.vue";
 
@@ -723,6 +1042,27 @@
       2: "warning", // 瀹℃壒涓� - 姗欒壊
       3: "success", // 瀹℃壒閫氳繃 - 缁胯壊
       4: "danger", // 瀹℃壒澶辫触 - 绾㈣壊
+    };
+    return typeMap[status] || "";
+  };
+
+  // 鑾峰彇鍏ュ簱鐘舵�佹爣绛剧被鍨�
+  const getStockInStatusType = status => {
+    const typeMap = {
+      寰呭叆搴�: "info", // 寰呭叆搴� - 鐏拌壊
+      鍏ュ簱涓�: "warning", // 鍏ュ簱涓� - 姗欒壊
+      瀹屽叏鍏ュ簱: "success", // 瀹屽叏鍏ュ簱 - 缁胯壊
+    };
+    return typeMap[status] || "";
+  };
+
+  // 鑾峰彇鍏ュ簱瀹℃牳鐘舵�佹爣绛剧被鍨�
+  const getStockInApprovalStatusType = status => {
+    const typeMap = {
+      寰呭叆搴�: "info", // 寰呭叆搴� - 鐏拌壊
+      鍏ュ簱涓�: "warning", // 鍏ュ簱涓� - 姗欒壊
+      瀹屽叏鍏ュ簱: "success", // 瀹屽叏鍏ュ簱 - 缁胯壊
+      宸查┏鍥�: "danger", // 宸查┏鍥� - 绾㈣壊
     };
     return typeMap[status] || "";
   };
@@ -837,6 +1177,7 @@
       supplierName: "", // 渚涘簲鍟嗗悕绉�
       purchaseContractNumber: "", // 閲囪喘鍚堝悓缂栧彿
       salesContractNo: "", // 閿�鍞悎鍚岀紪鍙�
+      masterContractNo: "", // 鎬诲悎鍚屽彿
       projectName: "", // 椤圭洰鍚嶇О
       entryDate: null, // 褰曞叆鏃ユ湡
       entryDateStart: undefined,
@@ -846,6 +1187,7 @@
       purchaseContractNumber: "",
       salesLedgerId: "",
       projectName: "",
+      masterContractNo: "",
       recorderId: "",
       entryDate: "",
       productData: [],
@@ -857,7 +1199,7 @@
     },
     rules: {
       purchaseContractNumber: [
-        { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+        { required: false, message: "璇疯緭鍏�", trigger: "blur" },
       ],
       projectName: [
         { required: true, message: "璇疯緭鍏ラ」鐩悕绉�", trigger: "blur" },
@@ -886,6 +1228,7 @@
   const currentId = ref("");
   const productFormData = reactive({
     productForm: {
+      productType: 1,
       productId: "",
       productCategory: "",
       productModelId: "",
@@ -899,6 +1242,8 @@
       invoiceType: "",
       warnNum: "",
       isChecked: false,
+      deviceId: "",
+      storageLocation: "",
     },
     productRules: {
       productId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
@@ -917,10 +1262,27 @@
         { required: true, message: "璇疯緭鍏�", trigger: "blur" },
       ],
       invoiceType: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-      isChecked: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+      // isChecked 榛樿浼犲惁锛屼笉闇�瑕侀獙璇�
     },
   });
-  const { productForm, productRules } = toRefs(productFormData);
+  const { productForm } = toRefs(productFormData);
+  
+  // 鍔ㄦ�佽绠楅獙璇佽鍒�
+  const productRules = computed(() => {
+    const isSpareParts = productForm.value.productType === 2;
+    return {
+      productId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+      productModelId: isSpareParts ? [] : [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+      unit: isSpareParts ? [] : [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      taxInclusiveUnitPrice: isSpareParts ? [] : [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      taxRate: isSpareParts ? [] : [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+      warnNum: isSpareParts ? [] : [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+      taxInclusiveTotalPrice: isSpareParts ? [] : [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      taxExclusiveTotalPrice: isSpareParts ? [] : [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      invoiceType: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+    };
+  });
   const upload = reactive({
     // 涓婁紶鐨勫湴鍧�
     url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
@@ -1206,13 +1568,6 @@
   };
   // 鎵撳紑寮规
   const openForm = async (type, row) => {
-    // 缂栬緫鏃舵鏌ュ鏍哥姸鎬侊紝鍙湁寰呭鏍�(1)鍜屽鎵瑰け璐�(4)鎵嶈兘缂栬緫
-    if (type === "edit" && row) {
-      if (row.approvalStatus !== 1 && row.approvalStatus !== 4) {
-        proxy.$modal.msgWarning("鍙湁寰呭鏍稿拰瀹℃壒澶辫触鐘舵�佺殑璁板綍鎵嶈兘缂栬緫");
-        return;
-      }
-    }
 
     await getTemplateList();
     await userListNoPage().then(res => {
@@ -1240,25 +1595,30 @@
 
       form.value.entryDate = getCurrentDate();
 
-      if (type === "add") {
-        // 鏂板鏃剁敓鎴愰噰璐悎鍚屽彿
-        try {
-          const purchaseNoRes = await createPurchaseNo();
-          if (purchaseNoRes?.data) {
-            form.value.purchaseContractNumber = purchaseNoRes.data;
-          }
-        } catch (error) {
-          console.error("鐢熸垚閲囪喘鍚堝悓鍙峰け璐�:", error);
-          proxy.$modal.msgWarning("鐢熸垚閲囪喘鍚堝悓鍙峰け璐�");
-        }
-      } else if (type === "edit" && row?.id) {
+      if (type === "edit" && row?.id) {
         // 缂栬緫鏃跺姞杞芥暟鎹�
         currentId.value = row.id;
         try {
           const purchaseRes = await getPurchaseById({ id: row.id, type: 2 });
-          form.value = { ...purchaseRes };
-          productData.value = purchaseRes.productData || [];
+          form.value = { ...purchaseRes, stockInStatus: row.stockInStatus };
           fileList.value = purchaseRes.storageBlobVOS || [];
+          // 浣跨敤 productList 鎺ュ彛鑾峰彇浜у搧鍒楄〃锛屼互鑾峰彇鍏ュ簱瀹℃牳鐘舵��
+          const productRes = await productList({
+            salesLedgerId: row.id,
+            type: 2,
+          });
+          productData.value = productRes.data || [];
+          // 缂栬緫鏃跺姞杞戒緵搴斿晢鐨勫悎鍚屽垪琛ㄤ互渚垮洖鏄炬�诲悎鍚屽彿
+          if (purchaseRes.supplierId) {
+            try {
+              const contractRes = await getSupplierContractList(purchaseRes.supplierId);
+              if (contractRes.code === 200) {
+                contractList.value = contractRes.data || [];
+              }
+            } catch (error) {
+              console.error('鑾峰彇渚涘簲鍟嗗悎鍚屽垪琛ㄥけ璐�:', error);
+            }
+          }
         } catch (error) {
           console.error("鍔犺浇閲囪喘鍙拌处鏁版嵁澶辫触:", error);
           proxy.$modal.msgError("鍔犺浇鏁版嵁澶辫触");
@@ -1330,7 +1690,7 @@
 
   // 鎻愪氦琛ㄥ崟
   const submitForm = () => {
-    proxy.$refs["formRef"].validate(valid => {
+    proxy.$refs["formRef"].validate(async valid => {
       if (valid) {
         if (productData.value.length > 0) {
           // 鏂板鏃讹紝闇�瑕佷粠姣忎釜浜у搧瀵硅薄涓垹闄� id 瀛楁
@@ -1360,6 +1720,20 @@
           delete submitData.id;
         }
 
+        // 濡傛灉閲囪喘鍚堝悓鍙蜂负绌猴紝鍒欐牴鎹綍鍏ユ棩鏈熻嚜鍔ㄧ敓鎴�
+        if (!submitData.purchaseContractNumber) {
+          try {
+            const purchaseNoRes = await createPurchaseNo(submitData.entryDate);
+            if (purchaseNoRes?.data) {
+              submitData.purchaseContractNumber = purchaseNoRes.data;
+            }
+          } catch (error) {
+            console.error("鐢熸垚閲囪喘鍚堝悓鍙峰け璐�:", error);
+            proxy.$modal.msgWarning("鐢熸垚閲囪喘鍚堝悓鍙峰け璐�");
+            return;
+          }
+        }
+
         addOrEditPurchase(submitData).then(res => {
           proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
           closeDia();
@@ -1375,6 +1749,12 @@
   };
   // 鎵撳紑浜у搧寮规
   const openProductForm = async (type, row, index) => {
+    // 瀹℃壒閫氳繃鏃朵笉鑳界紪杈戜骇鍝佷俊鎭�
+    if (type === "edit" && form.value.approvalStatus === 3) {
+      proxy.$modal.msgWarning("瀹℃壒閫氳繃鐨勮褰曚笉鑳界紪杈戜骇鍝佷俊鎭�");
+      return;
+    }
+
     productOperationType.value = type;
     productOperationIndex.value = index;
     productForm.value = {};
@@ -1388,16 +1768,27 @@
     await nextTick();
 
     if (type === "add") {
-      productForm.value.isChecked = false;
+      productForm.value.isChecked = false; // 鏄惁璐ㄦ榛樿浼犲惁
+      productForm.value.productType = "product";
     }
 
     if (type === "edit") {
       // 澶嶅埗琛屾暟鎹�
       productForm.value = { ...row };
 
+      // 濡傛灉娌℃湁 productType锛岄粯璁や负 product (1)
+      if (!productForm.value.productType) {
+        productForm.value.productType = 1;
+      }
+
+      // 濡傛灉鏄澶囧浠剁被鍨嬶紝鍔犺浇璁惧澶囦欢鍒楄〃
+      if (productForm.value.productType === 2) {
+        await getSparePartsOptions();
+      }
+
       // 濡傛灉鏄粠妯℃澘鍔犺浇鐨勬暟鎹紝鍙兘娌℃湁 productId 鍜� productModelId
       // 闇�瑕佹牴鎹� productCategory 鍜� specificationModel 鏉ユ煡鎵惧搴旂殑 ID
-      if (!productForm.value.productId && productForm.value.productCategory) {
+      if (!productForm.value.productId && productForm.value.productCategory && productForm.value.productType !== 2) {
         // 鏍规嵁 productCategory 鏌ユ壘 productId
         const findProductIdByCategory = (nodes, categoryName) => {
           for (let i = 0; i < nodes.length; i++) {
@@ -1465,6 +1856,45 @@
       return res;
     });
   };
+
+  // 鑾峰彇璁惧澶囦欢鍒楄〃
+  const getSparePartsOptions = () => {
+    return getSparePartsList({ current: -1, size: -1 }).then(res => {
+      if (res.data && Array.isArray(res.data.rows)) {
+        sparePartsOptions.value = res.data.rows;
+      } else if (res.data && Array.isArray(res.data.records)) {
+        sparePartsOptions.value = res.data.records;
+      } else {
+        sparePartsOptions.value = [];
+      }
+      return res;
+    });
+  };
+
+  // 澶勭悊绫诲瀷鍙樺寲
+  const handleProductTypeChange = (type) => {
+    productForm.value.productId = "";
+    productForm.value.productCategory = "";
+    productForm.value.productModelId = "";
+    productForm.value.specificationModel = "";
+    modelOptions.value = [];
+    
+    if (type === 2) {
+      getSparePartsOptions();
+    }
+  };
+
+  // 澶勭悊璁惧澶囦欢閫夋嫨
+  const handleSparePartsChange = (value) => {
+    const selectedSparePart = sparePartsOptions.value.find(item => item.id === value);
+    if (selectedSparePart) {
+      productForm.value.productCategory = selectedSparePart.name;
+      productForm.value.specificationModel = "/";
+    } else {
+      productForm.value.productCategory = "";
+      productForm.value.specificationModel = "";
+    }
+  };
   const getModels = value => {
     if (value) {
       productForm.value.productCategory =
@@ -1521,6 +1951,19 @@
 
   // 鎻愪氦浜у搧琛ㄥ崟
   const submitProduct = () => {
+    // 濡傛灉鏄澶囧浠讹紝鍏堣缃粯璁ゅ�硷紝鍐嶉獙璇�
+    if (productForm.value.productType === 2) {
+      productForm.value.specificationModel = "/";
+      productForm.value.productModelId = null;
+      productForm.value.unit = "";
+      productForm.value.taxRate = "";
+      productForm.value.taxInclusiveUnitPrice = 0;
+      productForm.value.taxInclusiveTotalPrice = 0;
+      productForm.value.taxExclusiveTotalPrice = 0;
+      productForm.value.warnNum = 0;
+      productForm.value.isChecked = false; // 鏄惁璐ㄦ榛樿浼犲惁
+    }
+    
     proxy.$refs["productFormRef"].validate(valid => {
       if (valid) {
         if (operationType.value === "edit") {
@@ -1545,8 +1988,9 @@
     addOrUpdateSalesLedgerProduct(productForm.value).then(res => {
       proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
       closeProductDia();
-      getPurchaseById({ id: currentId.value, type: 2 }).then(res => {
-        productData.value = res.productData;
+      // 浣跨敤 productList 鎺ュ彛鍒锋柊浜у搧鍒楄〃锛屼互鑾峰彇鍏ュ簱瀹℃牳鐘舵��
+      productList({ salesLedgerId: currentId.value, type: 2 }).then(res => {
+        productData.value = res.data || [];
       });
     });
   };
@@ -1557,14 +2001,10 @@
       return;
     }
     if (operationType.value === "add") {
-      productSelectedRows.value.forEach(selectedRow => {
-        const index = productData.value.findIndex(
-          product => product.id === selectedRow.id
-        );
-        if (index !== -1) {
-          productData.value.splice(index, 1);
-        }
-      });
+      productData.value = productData.value.filter(
+        item => !productSelectedRows.value.includes(item)
+      );
+      productSelectedRows.value = [];
     } else {
       let ids = [];
       if (productSelectedRows.value.length > 0) {
@@ -1579,8 +2019,9 @@
           delProduct(ids).then(res => {
             proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
             closeProductDia();
-            getPurchaseById({ id: currentId.value, type: 2 }).then(res => {
-              productData.value = res.productData;
+            // 浣跨敤 productList 鎺ュ彛鍒锋柊浜у搧鍒楄〃锛屼互鑾峰彇鍏ュ簱瀹℃牳鐘舵��
+            productList({ salesLedgerId: currentId.value, type: 2 }).then(res => {
+              productData.value = res.data || [];
             });
           });
         })
@@ -1629,6 +2070,37 @@
           proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
           getList();
         });
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+  };
+
+  const handleBatchGenerate = async () => {
+    if (selectedRows.value.length === 0) {
+      proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+      return;
+    }
+    const ids = selectedRows.value.map((item) => item.id);
+    
+    ElMessageBox.confirm("纭鎵归噺鐢熸垚鏁版嵁锛�", "鎵归噺鐢熸垚", {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "info",
+    })
+      .then(() => {
+        proxy.$modal.loading("姝e湪鎵归噺鐢熸垚鏁版嵁锛岃绋嶅��...");
+        batchGeneratePurchaseInboundSteps({ ids })
+          .then((res) => {
+            proxy.$modal.msgSuccess("鎵归噺鐢熸垚鎴愬姛");
+            getList();
+          })
+          .catch(() => {
+            proxy.$modal.msgError("鎵归噺鐢熸垚澶辫触");
+          })
+          .finally(() => {
+            proxy.$modal.closeLoading();
+          });
       })
       .catch(() => {
         proxy.$modal.msg("宸插彇娑�");
@@ -1772,7 +2244,7 @@
       contractNo: form.value.salesLedgerId,
     });
     if (code == 200) {
-      productData.value = data;
+      productData.value = data || [];
     }
   };
 
@@ -1838,9 +2310,85 @@
     }
   };
 
+  // 渚涘簲鍟嗛�夋嫨鍙樺寲鏃讹紝鍔犺浇璇ヤ緵搴斿晢鐨勫悎鍚屽垪琛�
+  const handleSupplierChange = async (supplierId) => {
+    form.value.masterContractNo = '';
+    contractList.value = [];
+    if (!supplierId) return;
+
+    try {
+      const res = await getSupplierContractList(supplierId);
+      if (res.code === 200) {
+        contractList.value = res.data || [];
+      }
+    } catch (error) {
+      console.error('鑾峰彇渚涘簲鍟嗗悎鍚屽垪琛ㄥけ璐�:', error);
+    }
+  };
+
+  // 鏌ョ湅鎬诲悎鍚岄檮浠�
+  const openContractFileDialog = async (row) => {
+    if (!row.masterContractNo) {
+      proxy.$modal.msgWarning('璇ヨ褰曟病鏈夋�诲悎鍚屽彿');
+      return;
+    }
+    try {
+      const res = await getSupplierContractFilesByNo(row.masterContractNo);
+      if (res.code === 200) {
+        contractFileList.value = res.data || [];
+        contractFileDialogVisible.value = true;
+      }
+    } catch (error) {
+      console.error('鑾峰彇鍚堝悓闄勪欢澶辫触:', error);
+    }
+  };
+
+  // 鑾峰彇IoT璁惧鍒楄〃
+  // 鑾峰彇IoT璁惧鍒楄〃
+  const getIotDeviceList = async () => {
+    try {
+      const res = await getIotDeviceListApi();
+      if (res.data) {
+        iotDeviceList.value = res.data;
+      }
+    } catch (error) {
+      console.error("鑾峰彇IoT璁惧鍒楄〃澶辫触:", error);
+    }
+  };
+
+  // 璁惧閫夋嫨鍙樻洿鏃讹紝鑷姩濉厖搴撲綅
+  const handleDeviceChange = (row, index) => {
+    const device = iotDeviceList.value.find(d => d.id === row.deviceId);
+    if (device) {
+      row.storageLocation = device.storageLocation || '';
+    } else {
+      row.storageLocation = '';
+    }
+  };
+
+  // 浜у搧寮圭獥涓澶囬�夋嫨鍙樻洿鏃讹紝鑷姩濉厖搴撲綅
+  const handleProductDeviceChange = (deviceId) => {
+    const device = iotDeviceList.value.find(d => d.id === deviceId);
+    if (device) {
+      productForm.value.storageLocation = device.storageLocation || '';
+    } else {
+      productForm.value.storageLocation = '';
+    }
+  };
+
+  // 鏍煎紡鍖栨枃浠跺ぇ灏�
+  const formatFileSize = (bytes) => {
+    if (!bytes) return '0 B';
+    const k = 1024;
+    const sizes = ['B', 'KB', 'MB', 'GB'];
+    const i = Math.floor(Math.log(bytes) / Math.log(k));
+    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
+  };
+
   onMounted(() => {
     getList();
     getTemplateList();
+    getIotDeviceList();
   });
 </script>
 

--
Gitblit v1.9.3