From 3ee27be7fadb2fd30bd42991ef810014f1e91a19 Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期二, 11 八月 2026 18:34:13 +0800
Subject: [PATCH] fix: 发货审批的发货日期字段错误

---
 src/views/procurementManagement/procurementLedger/index.vue | 1070 ++++++++++++++++++++++-------------------------------------
 1 files changed, 401 insertions(+), 669 deletions(-)

diff --git a/src/views/procurementManagement/procurementLedger/index.vue b/src/views/procurementManagement/procurementLedger/index.vue
index 0543286..aa2ac98 100644
--- a/src/views/procurementManagement/procurementLedger/index.vue
+++ b/src/views/procurementManagement/procurementLedger/index.vue
@@ -2,381 +2,202 @@
   <div class="app-container">
     <div class="search_form">
       <div>
-        <el-form :model="searchForm"
-                 :inline="true">
+        <el-form :model="searchForm" :inline="true">
           <el-form-item label="渚涘簲鍟嗗悕绉帮細">
-            <el-input v-model="searchForm.supplierName"
-                      placeholder="璇疯緭鍏�"
-                      clearable
-                      prefix-icon="Search"
-                      @change="handleQuery" />
+            <el-input v-model="searchForm.supplierName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
+              @change="handleQuery" />
           </el-form-item>
           <el-form-item label="閲囪喘鍚堝悓鍙凤細">
-            <el-input v-model="searchForm.purchaseContractNumber"
-                      style="width: 240px"
-                      placeholder="璇疯緭鍏�"
-                      @change="handleQuery"
-                      clearable
-                      :prefix-icon="Search" />
+            <el-input v-model="searchForm.purchaseContractNumber" style="width: 240px" placeholder="璇疯緭鍏�"
+              @change="handleQuery" 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-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="璇疯緭鍏�"
-                      clearable
-                      prefix-icon="Search"
-                      @change="handleQuery" />
+            <el-input v-model="searchForm.projectName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
+              @change="handleQuery" />
           </el-form-item>
           <el-form-item label="褰曞叆鏃ユ湡锛�">
-            <el-date-picker v-model="searchForm.entryDate"
-                            value-format="YYYY-MM-DD"
-                            format="YYYY-MM-DD"
-                            type="daterange"
-                            placeholder="璇烽�夋嫨"
-                            clearable
-                            @change="changeDaterange" />
+            <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
+              type="daterange" placeholder="璇烽�夋嫨" 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"> 鎼滅储 </el-button>
+            <el-button type="primary" @click="handleQuery"> 鎼滅储
+            </el-button>
           </el-form-item>
         </el-form>
       </div>
     </div>
     <div class="table_list">
       <div style="display: flex;justify-content: flex-end;margin-bottom: 20px;">
-        <el-button type="primary"
-                   @click="openForm('add')">鏂板鍙拌处</el-button>
+        <el-button type="success" plain @click="handleBatchGenerate">鎵归噺鐢熸垚鏁版嵁</el-button>
+        <el-button type="primary" @click="openForm('add')">鏂板鍙拌处</el-button>
         <el-button type="primary" plain @click="handleImport">瀵煎叆</el-button>
         <el-button @click="handleOut">瀵煎嚭</el-button>
-        <el-button type="danger"
-                   plain
-                   @click="handleDelete">鍒犻櫎</el-button>
+        <el-button type="danger" plain @click="handleDelete">鍒犻櫎
+        </el-button>
       </div>
-      <el-table :data="tableData"
-                border
-                v-loading="tableLoading"
-                @selection-change="handleSelectionChange"
-                :expand-row-keys="expandedRowKeys"
-                :row-key="(row) => row.id"
-                show-summary
-                :summary-method="summarizeMainTable"
-                @expand-change="expandChange"
-                height="calc(100vh - 21.5em)">
-        <el-table-column align="center"
-                         type="selection"
-                         width="55" />
+      <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange"
+        :expand-row-keys="expandedRowKeys" :row-key="(row) => row.id" show-summary :summary-method="summarizeMainTable"
+        @expand-change="expandChange" height="calc(100vh - 21.5em)">
+        <el-table-column align="center" type="selection" width="55" />
         <el-table-column type="expand">
           <template #default="props">
-            <el-table :data="props.row.children"
-                      border
-                      show-summary
-                      :summary-method="summarizeChildrenTable">
-              <el-table-column align="center"
-                               label="搴忓彿"
-                               type="index"
-                               width="60" />
-              <el-table-column label="浜у搧澶х被"
-                               prop="productCategory" />
-              <el-table-column label="瑙勬牸鍨嬪彿"
-                               prop="specificationModel" />
-              <el-table-column label="鍗曚綅"
-                               prop="unit" />
-              <el-table-column label="鏁伴噺"
-                               prop="quantity" />
-              <el-table-column label="鍙敤鏁伴噺"
-                               prop="availableQuality" />
-              <el-table-column label="閫�璐ф暟閲�"
-                               prop="returnQuality" />
-                               
-              <el-table-column label="绋庣巼(%)"
-                               prop="taxRate" />
-              <el-table-column label="鍚◣鍗曚环(鍏�)"
-                               prop="taxInclusiveUnitPrice"
-                               :formatter="formattedNumber" />
-              <el-table-column label="鍚◣鎬讳环(鍏�)"
-                               prop="taxInclusiveTotalPrice"
-                               :formatter="formattedNumber" />
-              <el-table-column label="涓嶅惈绋庢�讳环(鍏�)"
-                               prop="taxExclusiveTotalPrice"
-                               :formatter="formattedNumber" />
+            <el-table :data="props.row.children" border show-summary :summary-method="summarizeChildrenTable">
+              <el-table-column align="center" label="搴忓彿" type="index" width="60" />
+              <el-table-column label="浜у搧澶х被" prop="productCategory" />
+              <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
+              <el-table-column label="鍗曚綅" prop="unit" />
+              <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" />
+              <el-table-column label="鍙敤鏁伴噺" prop="availableQuality" />
+              <el-table-column label="閫�璐ф暟閲�" prop="returnQuantity" />
+              <el-table-column label="绋庣巼(%)" prop="taxRate" />
+              <el-table-column label="鍚◣鍗曚环(鍏�)" prop="taxInclusiveUnitPrice" :formatter="formattedNumber" />
+              <el-table-column label="鍚◣鎬讳环(鍏�)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" />
+              <el-table-column label="涓嶅惈绋庢�讳环(鍏�)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" />
             </el-table>
           </template>
         </el-table-column>
-        <el-table-column align="center"
-                         label="搴忓彿"
-                         type="index"
-                         width="60" />
-        <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="supplierName"
-                          width="160"
-                         show-overflow-tooltip />
-        <el-table-column label="椤圭洰鍚嶇О"
-                         prop="projectName"
-                         width="320"
-                         show-overflow-tooltip />
-        <el-table-column label="瀹℃壒鐘舵��"
-                         prop="approvalStatus"
-                         width="100"
-                         show-overflow-tooltip>
+        <el-table-column align="center" label="搴忓彿" type="index" width="60" />
+        <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="supplierName" width="160" show-overflow-tooltip />
+        <el-table-column label="椤圭洰鍚嶇О" prop="projectName" width="320" show-overflow-tooltip />
+        <el-table-column label="瀹℃壒鐘舵��" prop="approvalStatus" width="100" show-overflow-tooltip>
           <template #default="scope">
-            <el-tag 
-              :type="getApprovalStatusType(scope.row.approvalStatus)"
-              size="small">
+            <el-tag :type="getApprovalStatusType(scope.row.approvalStatus)" size="small">
               {{ approvalStatusText[scope.row.approvalStatus] || '鏈煡鐘舵��' }}
             </el-tag>
           </template>
         </el-table-column>
-        <el-table-column label="绛捐鏃ユ湡"
-                         prop="executionDate"
-                         width="100"
-                         show-overflow-tooltip />
-        <el-table-column label="浠樻鏂瑰紡"
-                         width="100"
-                         prop="paymentMethod"
-                         show-overflow-tooltip />
-        <el-table-column label="鍚堝悓閲戦(鍏�)"
-                         prop="contractAmount"
+        <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 || '--' }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="绛捐鏃ユ湡" prop="executionDate" width="100" show-overflow-tooltip />
+        <el-table-column label="浠樻鏂瑰紡" width="100" prop="paymentMethod" show-overflow-tooltip />
+        <el-table-column label="鍚堝悓閲戦(鍏�)" prop="contractAmount" width="200" show-overflow-tooltip
+          :formatter="formattedNumber" />
+        <!-- <el-table-column label="瀹為檯鍚堝悓閲戦(鍏�)"
+                         prop="netContractAmount"
                          width="200"
                          show-overflow-tooltip
-                         :formatter="formattedNumber" />
-        <el-table-column label="褰曞叆浜�"
-                         prop="recorderName"
-                         width="120"
-                         show-overflow-tooltip />
-        <el-table-column label="褰曞叆鏃ユ湡"
-                         prop="entryDate"
-                         width="100"
-                         show-overflow-tooltip />
-        <el-table-column label="澶囨敞"
-                         prop="remarks"
-                         width="200"
-                         show-overflow-tooltip />
-        <el-table-column fixed="right"
-                         label="鎿嶄綔"
-                         width="120"
-                         align="center">
+                         :formatter="formattedNumber" /> -->
+        <el-table-column label="褰曞叆浜�" prop="recorderName" width="120" show-overflow-tooltip />
+        <el-table-column label="褰曞叆鏃ユ湡" prop="entryDate" width="100" show-overflow-tooltip />
+        <el-table-column label="澶囨敞" prop="remarks" width="200" show-overflow-tooltip />
+        <el-table-column fixed="right" label="鎿嶄綔" width="120" align="center">
           <template #default="scope">
-            <el-button link
-                       type="primary"
-                       @click="openForm('edit', scope.row)"
-                       :disabled="scope.row.approvalStatus !== 1 && scope.row.approvalStatus !== 4">缂栬緫</el-button>
-            <el-button link
-                       type="primary"
-                       @click="downLoadFile(scope.row)">闄勪欢</el-button>
+            <el-button link type="primary" @click="openForm('edit', scope.row)"
+              :disabled="scope.row.stockInStatus === '瀹屽叏鍏ュ簱'">缂栬緫
+            </el-button>
+            <el-button link type="primary" @click="openFileDialog(scope.row)">闄勪欢</el-button>
           </template>
         </el-table-column>
       </el-table>
-      <pagination v-show="total > 0"
-                  :total="total"
-                  layout="total, sizes, prev, pager, next, jumper"
-                  :page="page.current"
-                  :limit="page.size"
-                  @pagination="paginationChange" />
+      <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper"
+        :page="page.current" :limit="page.size" @pagination="paginationChange" />
     </div>
-    <FormDialog v-model="dialogFormVisible"
-               :title="operationType === 'add' ? '鏂板閲囪喘鍙拌处椤甸潰' : '缂栬緫閲囪喘鍙拌处椤甸潰'"
-               :width="'70%'"
-               :operation-type="operationType"
-               @close="closeDia"
-               @confirm="submitForm"
-               @cancel="closeDia">
-      <el-form :model="form"
-               label-width="140px"
-               label-position="top"
-               :rules="rules"
-               ref="formRef">
+    <FormDialog v-model="dialogFormVisible" :title="operationType === 'add' ? '鏂板閲囪喘鍙拌处椤甸潰' : '缂栬緫閲囪喘鍙拌处椤甸潰'" :width="'70%'"
+      :operation-type="operationType" @close="closeDia" @confirm="submitForm" @cancel="closeDia">
+      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="閲囪喘鍚堝悓鍙凤細"
-                          prop="purchaseContractNumber">
-              <el-input v-model="form.purchaseContractNumber"
-                        placeholder="璇疯緭鍏�"
-                        clearable />
+            <el-form-item label="閲囪喘鍚堝悓鍙凤細" prop="purchaseContractNumber">
+              <el-input v-model="form.purchaseContractNumber" placeholder="璇疯緭鍏�" 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-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">
-            <el-form-item label="渚涘簲鍟嗗悕绉帮細"
-                          prop="supplierId">
-              <el-select v-model="form.supplierId"
-                         placeholder="璇烽�夋嫨"
-                         filterable
-                         clearable>
-                <el-option v-for="item in supplierList"
-                           :key="item.id"
-                           :label="item.supplierName"
-													 :value="item.id" >{{item.supplierName + '---' + item.supplierType}}</el-option>
+            <el-form-item label="渚涘簲鍟嗗悕绉帮細" prop="supplierId">
+              <el-select v-model="form.supplierId" placeholder="璇烽�夋嫨" filterable clearable>
+                <el-option v-for="item in supplierList" :key="item.id" :label="item.supplierName" :value="item.id">{{
+                  item.supplierName + '---' + item.supplierType }}
+                </el-option>
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="椤圭洰鍚嶇О"
-                          prop="projectName">
-              <el-input v-model="form.projectName"
-                        placeholder="璇疯緭鍏�"
-                        clearable />
+            <el-form-item label="椤圭洰鍚嶇О" prop="projectName">
+              <el-input v-model="form.projectName" placeholder="璇疯緭鍏�" clearable />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
             <el-form-item label="浠樻鏂瑰紡">
-              <el-input v-model="form.paymentMethod"
-                        placeholder="璇疯緭鍏�"
-                        clearable />
+              <el-input v-model="form.paymentMethod" placeholder="璇疯緭鍏�" clearable />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="绛捐鏃ユ湡锛�"
-                          prop="executionDate">
-              <el-date-picker style="width: 100%"
-                              v-model="form.executionDate"
-                              value-format="YYYY-MM-DD"
-                              format="YYYY-MM-DD"
-                              type="date"
-                              placeholder="璇烽�夋嫨"
-                              clearable />
+            <el-form-item label="绛捐鏃ユ湡锛�" prop="executionDate">
+              <el-date-picker style="width: 100%" v-model="form.executionDate" value-format="YYYY-MM-DD"
+                format="YYYY-MM-DD" type="date" placeholder="璇烽�夋嫨" clearable />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="褰曞叆浜猴細"
-                          prop="recorderId">
-              <el-select v-model="form.recorderId"
-                         placeholder="璇烽�夋嫨"
-                         clearable
-                         filterable>
-                <el-option v-for="item in userList"
-                           :key="item.userId"
-                           :label="item.nickName"
-                           :value="item.userId" />
+            <el-form-item label="褰曞叆浜猴細" prop="recorderId">
+              <el-select v-model="form.recorderId" placeholder="璇烽�夋嫨" clearable filterable>
+                <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="褰曞叆鏃ユ湡锛�"
-                          prop="entryDate">
-              <el-date-picker style="width: 100%"
-                              v-model="form.entryDate"
-                              value-format="YYYY-MM-DD"
-                              format="YYYY-MM-DD"
-                              type="date"
-                              placeholder="璇烽�夋嫨"
-                              clearable />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="24">
-            <el-form-item>
-              <template #label>
-                <div style="display: flex; align-items: center; justify-content: space-between; width: 100%;">
-                  <span>瀹℃壒浜洪�夋嫨锛�</span>
-                  <el-button type="primary" size="small" @click="addApproverNode" icon="Plus">鏂板鑺傜偣</el-button>
-                </div>
-              </template>
-              <div class="approver-nodes-container">
-                <div
-                  v-for="(node, index) in approverNodes"
-                  :key="node.id"
-                  class="approver-node-item"
-                >
-                  <div class="approver-node-header">
-                    <span class="approver-node-label">瀹℃壒鑺傜偣 {{ index + 1 }}</span>
-                    <el-button
-                      v-if="approverNodes.length > 1"
-                      type="danger"
-                      size="small"
-                      text
-                      @click="removeApproverNode(index)"
-                      icon="Delete"
-                    >鍒犻櫎</el-button>
-                  </div>
-                  <el-select
-                    v-model="node.userId"
-                    placeholder="璇烽�夋嫨瀹℃壒浜�"
-                    filterable
-                    style="width: 100%;"
-                  >
-                    <el-option
-                      v-for="user in userList"
-                      :key="user.userId"
-                      :label="user.nickName"
-                      :value="user.userId"
-                    />
-                  </el-select>
-                </div>
-              </div>
+            <el-form-item label="褰曞叆鏃ユ湡锛�" prop="entryDate">
+              <el-date-picker style="width: 100%" v-model="form.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
+                type="date" placeholder="璇烽�夋嫨" clearable />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row>
-          <el-form-item label="浜у搧淇℃伅锛�"
-                        prop="entryDate">
-            <el-button type="primary"
-                       @click="openProductForm('add')">娣诲姞</el-button>
-            <el-button plain
-                       type="danger"
-                       @click="deleteProduct">鍒犻櫎</el-button>
+          <el-form-item label="浜у搧淇℃伅锛�" prop="entryDate">
+            <el-button type="primary" @click="openProductForm('add')">娣诲姞
+            </el-button>
+            <el-button plain type="danger" @click="deleteProduct">鍒犻櫎
+            </el-button>
           </el-form-item>
-          <div class="select-button-group"
-               style="width: 500px; margin: 20px 0;"
-               v-if="operationType === 'add'">
-            <el-select filterable
-                       allow-create
-                       :reserve-keyword="true"
-                       :default-first-option="false"
-                       clearable
-                       v-model="templateName"
-                       :input-value="filterInputValue"
-                       @filter-change="onTemplateFilterChange"
-                       @change="onTemplateChange"
-                       @focus="getTemplateList"
-                       style="width: 500px;"
-                       placeholder="璇烽�夋嫨妯$増鎴栬�呰緭鍏ユ柊鐨勬ā鐗堝悕绉板悗閫夋嫨"
-                       class="no-arrow-select">
-              <el-option v-for="item in templateList"
-                         :key="item.id || item.value"
-                         :label="item.templateName"
-                         :value="item.templateName">
+          <div class="select-button-group" style="width: 500px; margin: 20px 0;" v-if="operationType === 'add'">
+            <el-select filterable allow-create :reserve-keyword="true" :default-first-option="false" clearable
+              v-model="templateName" :input-value="filterInputValue" @filter-change="onTemplateFilterChange"
+              @change="onTemplateChange" @focus="getTemplateList" style="width: 500px;" placeholder="璇烽�夋嫨妯$増鎴栬�呰緭鍏ユ柊鐨勬ā鐗堝悕绉板悗閫夋嫨"
+              class="no-arrow-select">
+              <el-option v-for="item in templateList" :key="item.id || item.value" :label="item.templateName"
+                :value="item.templateName">
                 <div style="display: flex; justify-content: space-between; align-items: center;">
                   <span>{{ item.templateName }}</span>
-                  <el-icon 
-                    v-if="item.id"
-                    class="delete-icon"
-                    @click.stop="handleDeleteTemplate(item)"
+                  <el-icon v-if="item.id" class="delete-icon" @click.stop="handleDeleteTemplate(item)"
                     style="cursor: pointer; color: #f56c6c; font-size: 14px; margin-left: 8px;">
                     <Delete />
                   </el-icon>
@@ -384,137 +205,70 @@
               </el-option>
             </el-select>
             <!-- 鎸夐挳锛氫笌 Select 楂樺害鍖归厤锛屽幓鎺夊乏渚ц竟妗嗭紝鏃犵紳琛旀帴 -->
-            <el-button size="small"
-                       style="height: 32px;margin-left: 8px;"
-                       @click="handleButtonClick"
-                       :disabled="!templateName || templateName.trim() === '' || (!currentTemplateId && isTemplateNameDuplicate)">
+            <el-button size="small" style="height: 32px;margin-left: 8px;" @click="handleButtonClick"
+              :disabled="!templateName || templateName.trim() === '' || (!currentTemplateId && isTemplateNameDuplicate)">
               淇濆瓨
             </el-button>
           </div>
         </el-row>
-        <el-table :data="productData"
-                  border
-                  @selection-change="productSelected"
-                  show-summary
-                  :summary-method="summarizeProTable">
-          <el-table-column align="center"
-                           type="selection"
-                           width="55" />
-          <el-table-column align="center"
-                           label="搴忓彿"
-                           type="index"
-                           width="60" />
-          <el-table-column label="浜у搧澶х被"
-                           prop="productCategory" />
-          <el-table-column label="瑙勬牸鍨嬪彿"
-                           prop="specificationModel" />
-          <el-table-column label="鍗曚綅"
-                           prop="unit"
-                           width="70" />
-          <el-table-column label="鏁伴噺"
-                           prop="quantity"
-                           width="70" />
-          <el-table-column label="搴撳瓨棰勮鏁伴噺"
-                           prop="warnNum"
-                           width="120"
-                           show-overflow-tooltip />
-          <el-table-column label="绋庣巼(%)"
-                           prop="taxRate"
-                           width="80" />
-          <el-table-column label="鍚◣鍗曚环(鍏�)"
-                           prop="taxInclusiveUnitPrice"
-                           :formatter="formattedNumber"
-                           width="150" />
-          <el-table-column label="鍚◣鎬讳环(鍏�)"
-                           prop="taxInclusiveTotalPrice"
-                           :formatter="formattedNumber"
-                           width="150" />
-          <el-table-column label="涓嶅惈绋庢�讳环(鍏�)"
-                           prop="taxExclusiveTotalPrice"
-                           :formatter="formattedNumber"
-                           width="150" />
-          <el-table-column label="鏄惁璐ㄦ"
-                           prop="isChecked"
-                           width="150">
+        <el-table :data="productData" border @selection-change="productSelected" show-summary
+          :summary-method="summarizeProTable">
+          <el-table-column align="center" type="selection" width="55" />
+          <el-table-column align="center" label="搴忓彿" type="index" width="60" />
+          <el-table-column label="浜у搧澶х被" prop="productCategory" />
+          <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
+          <el-table-column label="鍗曚綅" prop="unit" width="70" />
+          <el-table-column label="鏁伴噺" prop="quantity" width="70" />
+          <el-table-column label="搴撳瓨棰勮鏁伴噺" prop="warnNum" width="120" show-overflow-tooltip />
+          <el-table-column label="绋庣巼(%)" prop="taxRate" width="80" />
+          <el-table-column label="鍚◣鍗曚环(鍏�)" prop="taxInclusiveUnitPrice" :formatter="formattedNumber" width="150" />
+          <el-table-column label="鍚◣鎬讳环(鍏�)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" width="150" />
+          <el-table-column label="涓嶅惈绋庢�讳环(鍏�)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" width="150" />
+          <el-table-column label="鏄惁璐ㄦ" prop="isChecked" width="150">
             <template #default="scope">
               <el-tag :type="scope.row.isChecked ? 'success' : 'info'">
                 {{ scope.row.isChecked ? '鏄�' : '鍚�' }}
               </el-tag>
             </template>
           </el-table-column>
-          <el-table-column fixed="right"
-                           label="鎿嶄綔"
-                           min-width="60"
-                           align="center">
+          <el-table-column label="鍏ュ簱瀹℃牳鐘舵��" prop="stockInApprovalStatus" width="120">
             <template #default="scope">
-              <el-button link
-                         type="primary"
-                         @click="openProductForm('edit', scope.row, scope.$index)">缂栬緫</el-button>
+              <el-tag :type="getStockInApprovalStatusType(scope.row.stockInApprovalStatus)" size="small">
+                {{ scope.row.stockInApprovalStatus || '--' }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column fixed="right" label="鎿嶄綔" min-width="60" align="center">
+            <template #default="scope">
+              <el-button link type="primary" @click="openProductForm('edit', scope.row, scope.$index)"
+                :disabled="scope.row.stockInApprovalStatus === '瀹屽叏鍏ュ簱'">缂栬緫
+              </el-button>
             </template>
           </el-table-column>
         </el-table>
         <el-row :gutter="30">
           <el-col :span="24">
-            <el-form-item label="澶囨敞路锛�"
-                          prop="remarks">
-              <el-input v-model="form.remarks"
-                        placeholder="璇疯緭鍏�"
-                        clearable
-                        type="textarea"
-                        :rows="2" />
+            <el-form-item label="澶囨敞路锛�" prop="remarks">
+              <el-input v-model="form.remarks" placeholder="璇疯緭鍏�" clearable type="textarea" :rows="2" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="24">
-            <el-form-item label="闄勪欢鏉愭枡锛�"
-                          prop="purchaseLedgerFiles">
-              <el-upload v-model:file-list="fileList"
-                         :action="upload.url"
-                         multiple
-                         ref="fileUpload"
-                         auto-upload
-                         :headers="upload.headers"
-                         :before-upload="handleBeforeUpload"
-                         :on-error="handleUploadError"
-                         :on-success="handleUploadSuccess"
-                         :on-remove="handleRemove">
-                <el-button type="primary">涓婁紶</el-button>
-                <template #tip>
-                  <div class="el-upload__tip">
-                    鏂囦欢鏍煎紡鏀寔
-                    doc锛宒ocx锛寈ls锛寈lsx锛宲pt锛宲ptx锛宲df锛宼xt锛寈ml锛宩pg锛宩peg锛宲ng锛実if锛宐mp锛宺ar锛寊ip锛�7z
-                  </div>
-                </template>
-              </el-upload>
+            <el-form-item label="闄勪欢鏉愭枡锛�" prop="purchaseLedgerFiles">
+              <FileUpload v-model:file-list="fileList" />
             </el-form-item>
           </el-col>
         </el-row>
       </el-form>
     </FormDialog>
     <!-- 瀵煎叆寮圭獥 -->
-    <FormDialog
-      v-model="importUpload.open"
-      :title="importUpload.title"
-      :width="'600px'"
-      @close="importUpload.open = false"
-      @confirm="submitImportFile"
-      @cancel="importUpload.open = false"
-    >
-      <el-upload
-        ref="importUploadRef"
-        :limit="1"
-        accept=".xlsx,.xls"
-        :action="importUpload.url"
-        :headers="importUpload.headers"
-        :before-upload="importUpload.beforeUpload"
-        :on-success="importUpload.onSuccess"
-        :on-error="importUpload.onError"
-        :on-progress="importUpload.onProgress"
-        :on-change="importUpload.onChange"
-        :auto-upload="false"
-        drag
-      >
+    <FormDialog v-model="importUpload.open" :title="importUpload.title" :width="'600px'"
+      @close="importUpload.open = false" @confirm="submitImportFile" @cancel="importUpload.open = false">
+      <el-upload ref="importUploadRef" :limit="1" accept=".xlsx,.xls" :action="importUpload.url"
+        :headers="importUpload.headers" :before-upload="importUpload.beforeUpload" :on-success="importUpload.onSuccess"
+        :on-error="importUpload.onError" :on-progress="importUpload.onProgress" :on-change="importUpload.onChange"
+        :auto-upload="false" drag>
         <i class="el-icon-upload"></i>
         <div class="el-upload__text">
           灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em>
@@ -527,180 +281,106 @@
         </template>
       </el-upload>
     </FormDialog>
-    <FormDialog v-model="productFormVisible"
-               :title="productOperationType === 'add' ? '鏂板浜у搧' : '缂栬緫浜у搧'"
-               :width="'40%'"
-               :operation-type="productOperationType"
-               @close="closeProductDia"
-               @confirm="submitProduct"
-               @cancel="closeProductDia">
-      <el-form :model="productForm"
-               label-width="140px"
-               label-position="top"
-               :rules="productRules"
-               ref="productFormRef">
+    <FormDialog v-model="productFormVisible" :title="productOperationType === 'add' ? '鏂板浜у搧' : '缂栬緫浜у搧'" :width="'40%'"
+      :operation-type="productOperationType" @close="closeProductDia" @confirm="submitProduct"
+      @cancel="closeProductDia">
+      <el-form :model="productForm" label-width="140px" label-position="top" :rules="productRules" ref="productFormRef">
         <el-row :gutter="30">
           <el-col :span="24">
-            <el-form-item label="浜у搧澶х被锛�"
-                          prop="productId">
-              <el-tree-select v-model="productForm.productId"
-                              placeholder="璇烽�夋嫨"
-                              clearable
-                              filterable
-                              check-strictly
-                              @change="getModels"
-                              :data="productOptions"
-                              :render-after-expand="false"
-                              style="width: 100%" />
+            <el-form-item label="浜у搧澶х被锛�" prop="productId">
+              <el-tree-select v-model="productForm.productId" placeholder="璇烽�夋嫨" clearable filterable check-strictly
+                @change="getModels" :data="productOptions" :render-after-expand="false" style="width: 100%" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="24">
-            <el-form-item label="瑙勬牸鍨嬪彿锛�"
-                          prop="productModelId">
-              <el-select v-model="productForm.productModelId"
-                         placeholder="璇烽�夋嫨"
-                         filterable
-                         clearable
-                         @change="getProductModel">
-                <el-option v-for="item in modelOptions"
-                           :key="item.id"
-                           :label="item.model"
-                           :value="item.id" />
+            <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="productModelId">
+              <el-select v-model="productForm.productModelId" placeholder="璇烽�夋嫨" filterable clearable
+                @change="getProductModel">
+                <el-option v-for="item in modelOptions" :key="item.id" :label="item.model" :value="item.id" />
               </el-select>
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="鍗曚綅锛�"
-                          prop="unit">
-              <el-input v-model="productForm.unit"
-                        placeholder="璇疯緭鍏�"
-                        clearable />
+            <el-form-item label="鍗曚綅锛�" prop="unit">
+              <el-input v-model="productForm.unit" placeholder="璇疯緭鍏�" clearable />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="绋庣巼(%)锛�"
-                          prop="taxRate">
-              <el-select v-model="productForm.taxRate"
-                         placeholder="璇烽�夋嫨"
-                         clearable
-                         @change="mathNum">
-                <el-option label="1"
-                           value="1" />
-                <el-option label="6"
-                           value="6" />
-                <el-option label="13"
-                           value="13" />
+            <el-form-item label="绋庣巼(%)锛�" prop="taxRate">
+              <el-select v-model="productForm.taxRate" placeholder="璇烽�夋嫨" clearable @change="mathNum">
+                <el-option v-for="dict in tax_rate" :key="dict.value" :label="dict.label" :value="dict.value" />
               </el-select>
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="鍚◣鍗曚环(鍏�)锛�"
-                          prop="taxInclusiveUnitPrice">
-              <el-input-number v-model="productForm.taxInclusiveUnitPrice"
-                               :precision="2"
-                               :step="0.1"
-                               :min="0"
-                               clearable
-                               style="width: 100%"
-                               @change="mathNum" />
+            <el-form-item label="鍚◣鍗曚环(鍏�)锛�" prop="taxInclusiveUnitPrice">
+              <el-input-number v-model="productForm.taxInclusiveUnitPrice" :precision="2" :step="0.1" :min="0" clearable
+                style="width: 100%" @change="mathNum" />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <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="璇疯緭鍏�"
-                               @change="mathNum" />
+            <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="璇疯緭鍏�" @change="mathNum" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="鍚◣鎬讳环(鍏�)锛�"
-                          prop="taxInclusiveTotalPrice">
-              <el-input-number v-model="productForm.taxInclusiveTotalPrice"
-                               :precision="2"
-                               :step="0.1"
-                               :min="0"
-                               clearable
-                               style="width: 100%"
-                               @change="reverseMathNum('taxInclusiveTotalPrice')" />
+            <el-form-item label="鍚◣鎬讳环(鍏�)锛�" prop="taxInclusiveTotalPrice">
+              <el-input-number v-model="productForm.taxInclusiveTotalPrice" :precision="2" :step="0.1" :min="0"
+                clearable style="width: 100%" @change="reverseMathNum('taxInclusiveTotalPrice')" />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="涓嶅惈绋庢�讳环(鍏�)锛�"
-                          prop="taxExclusiveTotalPrice">
-              <el-input-number v-model="productForm.taxExclusiveTotalPrice"
-                               :precision="2"
-                               :step="0.1"
-                               :min="0"
-                               clearable
-                               style="width: 100%"
-                               @change="reverseMathNum('taxExclusiveTotalPrice')" />
+            <el-form-item label="涓嶅惈绋庢�讳环(鍏�)锛�" prop="taxExclusiveTotalPrice">
+              <el-input-number v-model="productForm.taxExclusiveTotalPrice" :precision="2" :step="0.1" :min="0"
+                clearable style="width: 100%" @change="reverseMathNum('taxExclusiveTotalPrice')" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="鍙戠エ绫诲瀷锛�"
-                          prop="invoiceType">
-              <el-select v-model="productForm.invoiceType"
-                         placeholder="璇烽�夋嫨"
-                         clearable>
-                <el-option label="澧炴櫘绁�"
-                           value="澧炴櫘绁�" />
-                <el-option label="澧炰笓绁�"
-                           value="澧炰笓绁�" />
+            <el-form-item label="鍙戠エ绫诲瀷锛�" prop="invoiceType">
+              <el-select v-model="productForm.invoiceType" placeholder="璇烽�夋嫨" clearable>
+                <el-option label="澧炴櫘绁�" value="澧炴櫘绁�" />
+                <el-option label="澧炰笓绁�" value="澧炰笓绁�" />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="搴撳瓨棰勮鏁伴噺锛�"
-                          prop="warnNum">
-              <el-input-number v-model="productForm.warnNum"
-                               :precision="2"
-                               :step="0.1"
-                               :min="0"
-                               clearable
-                               style="width: 100%" />
+            <el-form-item label="搴撳瓨棰勮鏁伴噺锛�" prop="warnNum">
+              <el-input-number v-model="productForm.warnNum" :precision="2" :step="0.1" :min="0" clearable
+                style="width: 100%" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="鏄惁璐ㄦ锛�"
-                          prop="isChecked">
+            <el-form-item label="鏄惁璐ㄦ锛�" prop="isChecked">
               <el-radio-group v-model="productForm.isChecked">
-                <el-radio label="鏄�"
-                          :value="true" />
-                <el-radio label="鍚�"
-                          :value="false" />
+                <el-radio label="鏄�" :value="true" />
+                <el-radio label="鍚�" :value="false" />
               </el-radio-group>
             </el-form-item>
           </el-col>
         </el-row>
       </el-form>
     </FormDialog>
-    <FileListDialog 
-      ref="fileListRef" 
-      v-model="fileListDialogVisible"
-      title="闄勪欢鍒楄〃"
-    />
+    <FileList v-if="fileListDialogVisible" v-model:visible="fileListDialogVisible" record-type="purchase_ledger"
+      :record-id="recordId" />
   </div>
 </template>
 
 <script setup>
+  import FormDialog from "@/components/Dialog/FormDialog.vue";
+  import FileListDialog from "@/components/Dialog/FileListDialog.vue";
   import { getToken } from "@/utils/auth";
   import pagination from "@/components/PIMTable/Pagination.vue";
   import {
@@ -714,10 +394,7 @@
   import { Search, Delete } from "@element-plus/icons-vue";
   import { ElMessageBox, ElMessage } from "element-plus";
   import { userListNoPage } from "@/api/system/user.js";
-  import FormDialog from '@/components/Dialog/FormDialog.vue';
-  import FileListDialog from '@/components/Dialog/FileListDialog.vue';
   import {
-    getSalesLedgerWithProducts,
     addOrUpdateSalesLedgerProduct,
     delProduct,
     delLedgerFile,
@@ -736,10 +413,15 @@
     getOptions,
     getPurchaseTemplateList,
     delPurchaseTemplate,
+    batchGeneratePurchaseInboundSteps,
   } from "@/api/procurementManagement/procurementLedger.js";
   import useFormData from "@/hooks/useFormData.js";
+  const FileList = defineAsyncComponent(() =>
+    import("@/components/Dialog/FileList.vue")
+  );
 
   const { proxy } = getCurrentInstance();
+  const { tax_rate } = proxy.useDict("tax_rate");
   const tableData = ref([]);
   const productData = ref([]);
   const selectedRows = ref([]);
@@ -750,6 +432,8 @@
   const salesContractList = ref([]);
   const supplierList = ref([]);
   const tableLoading = ref(false);
+  const recordId = ref();
+  const fileListDialogVisible = ref(false);
   const page = reactive({
     current: 1,
     size: 100,
@@ -759,18 +443,9 @@
   import useUserStore from "@/store/modules/user";
   import { modelList, productTreeList } from "@/api/basicData/product.js";
   import dayjs from "dayjs";
+  import FileUpload from "@/components/AttachmentUpload/file/index.vue";
 
   const userStore = useUserStore();
-
-  // 瀹℃壒浜鸿妭鐐癸紙浠块攢鍞彴璐﹀彂璐у鎵逛汉锛�
-  const approverNodes = ref([{ id: 1, userId: null }]);
-  let nextApproverId = 2;
-  const addApproverNode = () => {
-    approverNodes.value.push({ id: nextApproverId++, userId: null });
-  };
-  const removeApproverNode = (index) => {
-    approverNodes.value.splice(index, 1);
-  };
 
   // 璁㈠崟瀹℃壒鐘舵�佹樉绀烘枃鏈�
   const approvalStatusText = {
@@ -781,12 +456,32 @@
   };
 
   // 鑾峰彇瀹℃壒鐘舵�佹爣绛剧被鍨�
-  const getApprovalStatusType = (status) => {
+  const getApprovalStatusType = status => {
     const typeMap = {
-      1: "info",      // 寰呭鏍� - 鐏拌壊
-      2: "warning",   // 瀹℃壒涓� - 姗欒壊
-      3: "success",   // 瀹℃壒閫氳繃 - 缁胯壊
-      4: "danger",    // 瀹℃壒澶辫触 - 绾㈣壊
+      1: "info", // 寰呭鏍� - 鐏拌壊
+      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", // 瀹屽叏鍏ュ簱 - 缁胯壊
     };
     return typeMap[status] || "";
   };
@@ -868,7 +563,8 @@
         form.value.paymentMethod = matchedTemplate.paymentMethod;
       }
       // 妯℃澘鏁版嵁涓殑浜у搧瀛楁鏄� productList锛岄渶瑕佽浆鎹负 productData
-      productData.value = matchedTemplate.productList || matchedTemplate.productData || [];
+      productData.value =
+        matchedTemplate.productList || matchedTemplate.productData || [];
     } else {
       // 鏈尮閰嶅埌宸叉湁妯℃澘锛岃涓烘柊妯℃澘
       currentTemplateId.value = null;
@@ -916,14 +612,11 @@
       supplierId: "",
       paymentMethod: "",
       executionDate: "",
-      isChecked: true,
+      isChecked: false,
     },
     rules: {
       purchaseContractNumber: [
-        { required: true, message: "璇疯緭鍏�", trigger: "blur" },
-      ],
-      approverId: [
-        { required: true, message: "璇烽�夋嫨瀹℃壒浜�", trigger: "change" },
+        { required: false, message: "璇疯緭鍏�", trigger: "blur" },
       ],
       projectName: [
         { required: true, message: "璇疯緭鍏ラ」鐩悕绉�", trigger: "blur" },
@@ -934,16 +627,7 @@
     },
   });
   const { form, rules } = toRefs(data);
-  const { form: searchForm } = useFormData({
-    ...data.searchForm,
-    // 璁剧疆褰曞叆鏃ユ湡鑼冨洿涓哄綋澶�
-    entryDate: [
-      dayjs().startOf("day").format("YYYY-MM-DD"),
-      dayjs().endOf("day").format("YYYY-MM-DD"),
-    ],
-    entryDateStart: dayjs().startOf("day").format("YYYY-MM-DD"),
-    entryDateEnd: dayjs().endOf("day").format("YYYY-MM-DD"),
-  });
+  const { form: searchForm } = useFormData(data.searchForm);
 
   // 浜у搧琛ㄥ崟寮规鏁版嵁
   const productFormVisible = ref(false);
@@ -964,7 +648,7 @@
       taxExclusiveTotalPrice: "",
       invoiceType: "",
       warnNum: "",
-      isChecked: true,
+      isChecked: false,
     },
     productRules: {
       productId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
@@ -1002,7 +686,7 @@
     url: import.meta.env.VITE_APP_BASE_API + "/purchase/ledger/import",
     headers: { Authorization: "Bearer " + getToken() },
     isUploading: false,
-    beforeUpload: (file) => {
+    beforeUpload: file => {
       const isExcel = file.name.endsWith(".xlsx") || file.name.endsWith(".xls");
       const isLt10M = file.size / 1024 / 1024 < 10;
       if (!isExcel) {
@@ -1051,7 +735,11 @@
 
   // 涓嬭浇瀵煎叆妯℃澘锛堝鍚庣璺緞涓嶅悓锛屽彲鍦ㄦ澶勮皟鏁达級
   const downloadTemplate = () => {
-    proxy.download("/purchase/ledger/exportTemplate", {}, "閲囪喘鍙拌处瀵煎叆妯℃澘.xlsx");
+    proxy.download(
+      "/purchase/ledger/exportTemplate",
+      {},
+      "閲囪喘鍙拌处瀵煎叆妯℃澘.xlsx"
+    );
   };
 
   const submitImportFile = () => {
@@ -1116,29 +804,27 @@
     // 妫�鏌ユ槸鍚︽湁浜у搧鏁版嵁
     if (!productData.value || productData.value.length === 0) {
       ElMessage({
-        message: '璇峰厛娣诲姞浜у搧淇℃伅',
-        type: 'warning',
+        message: "璇峰厛娣诲姞浜у搧淇℃伅",
+        type: "warning",
       });
       return;
     }
 
     try {
-      // 鑾峰彇瀹℃壒浜篒D瀛楃涓�
-      const approveUserIds = approverNodes.value
-        .filter(node => node.userId)
-        .map(node => node.userId)
-        .join(",");
-      
       let params = {
         productData: proxy.HaveJson(productData.value),
         supplierId: form.value.supplierId,
         paymentMethod: form.value.paymentMethod,
         recorderId: form.value.recorderId,
         projectName: form.value.projectName,
-        approveUserIds: approveUserIds,
         templateName: templateName.value.trim(),
       };
-      console.log("template params ===>", params, "currentTemplateId:", currentTemplateId.value);
+      console.log(
+        "template params ===>",
+        params,
+        "currentTemplateId:",
+        currentTemplateId.value
+      );
 
       // 濡傛灉 currentTemplateId 鏈夊�硷紝璇存槑褰撳墠鏄�滅紪杈戝凡鏈夋ā鏉库�� 鈫� 璋冪敤鏇存柊鎺ュ彛
       // 鍚﹀垯涓衡�滄柊寤烘ā鏉库�� 鈫� 璋冪敤鏂板鎺ュ彛
@@ -1258,7 +944,7 @@
   };
   // 涓昏〃鍚堣鏂规硶
   const summarizeMainTable = param => {
-    return proxy.summarizeTable(param, ["contractAmount"]);
+    return proxy.summarizeTable(param, ["contractAmount", "netContractAmount"]);
   };
   // 瀛愯〃鍚堣鏂规硶
   const summarizeProTable = param => {
@@ -1270,15 +956,18 @@
   };
   // 鎵撳紑寮规
   const openForm = async (type, row) => {
-    // 缂栬緫鏃舵鏌ュ鏍哥姸鎬侊紝鍙湁寰呭鏍�(1)鍜屽鎵瑰け璐�(4)鎵嶈兘缂栬緫
+    // 缂栬緫鏃舵鏌ュ叆搴撶姸鎬侊紝瀹屽叏鍏ュ簱鏃朵笉鑳界紪杈�
     if (type === "edit" && row) {
-      if (row.approvalStatus !== 1 && row.approvalStatus !== 4) {
-        proxy.$modal.msgWarning("鍙湁寰呭鏍稿拰瀹℃壒澶辫触鐘舵�佺殑璁板綍鎵嶈兘缂栬緫");
+      if (row.stockInStatus === "瀹屽叏鍏ュ簱") {
+        proxy.$modal.msgWarning("瀹屽叏鍏ュ簱鐘舵�佺殑璁板綍涓嶈兘缂栬緫");
         return;
       }
     }
-    
+
     await getTemplateList();
+    await userListNoPage().then(res => {
+      userList.value = res.data;
+    });
     operationType.value = type;
     form.value = {};
     productData.value = [];
@@ -1286,56 +975,34 @@
     templateName.value = "";
     filterInputValue.value = "";
     isTemplateNameDuplicate.value = false;
-    // 閲嶇疆瀹℃壒浜鸿妭鐐癸紙榛樿涓�涓┖鑺傜偣锛�
-    approverNodes.value = [{ id: 1, userId: null }];
-    nextApproverId = 2;
     try {
       // 骞惰鍔犺浇鍩虹鏁版嵁
-      const [userRes, salesRes, supplierRes] = await Promise.all([
-        userListNoPage(),
+      const [salesRes, supplierRes] = await Promise.all([
         getSalesNo(),
         getOptions(),
       ]);
 
-      userList.value = userRes.data || [];
       salesContractList.value = salesRes || [];
       // 渚涘簲鍟嗚繃婊ゅ嚭isWhite=0 鐨勬暟鎹�
       supplierList.value = (supplierRes.data || []).filter(
         item => item.isWhite === 0
       );
 
-      // 璁剧疆榛樿鍊�
-      form.value.recorderId = userStore.id;
       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 || [];
-          fileList.value = purchaseRes.salesLedgerFiles || [];
-          // 濡傛灉缂栬緫鏃舵湁瀹℃壒浜猴紝瑙f瀽瀹℃壒浜篒D瀛楃涓插苟璁剧疆鍒拌妭鐐逛腑
-          if (purchaseRes.approveUserIds) {
-            const approverIds = purchaseRes.approveUserIds.split(",");
-            approverNodes.value = approverIds.map((id, index) => ({
-              id: index + 1,
-              userId: Number(id)
-            }));
-            nextApproverId = approverIds.length + 1;
-          }
+          form.value = { ...purchaseRes, stockInStatus: row.stockInStatus };
+          fileList.value = purchaseRes.storageBlobVOS || [];
+          // 浣跨敤 productList 鎺ュ彛鑾峰彇浜у搧鍒楄〃锛屼互鑾峰彇鍏ュ簱瀹℃牳鐘舵��
+          const productRes = await productList({
+            salesLedgerId: row.id,
+            type: 2,
+          });
+          productData.value = productRes.data || [];
         } catch (error) {
           console.error("鍔犺浇閲囪喘鍙拌处鏁版嵁澶辫触:", error);
           proxy.$modal.msgError("鍔犺浇鏁版嵁澶辫触");
@@ -1353,6 +1020,7 @@
       proxy.$modal.msgError("鍔犺浇鍩虹鏁版嵁澶辫触");
     }
   };
+
   // 涓婁紶鍓嶆牎妫�
   function handleBeforeUpload(file) {
     // 鏍℃鏂囦欢澶у皬
@@ -1363,11 +1031,13 @@
     proxy.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��...");
     return true;
   }
+
   // 涓婁紶澶辫触
   function handleUploadError(err) {
     proxy.$modal.msgError("涓婁紶鏂囦欢澶辫触");
     proxy.$modal.closeLoading();
   }
+
   // 涓婁紶鎴愬姛鍥炶皟
   function handleUploadSuccess(res, file, uploadFiles) {
     proxy.$modal.closeLoading();
@@ -1379,6 +1049,7 @@
       proxy.$refs.fileUpload.handleRemove(file);
     }
   }
+
   // 绉婚櫎鏂囦欢
   async function handleRemove(file) {
     if (!file?.id) {
@@ -1400,18 +1071,11 @@
       }
     }
   }
+
   // 鎻愪氦琛ㄥ崟
   const submitForm = () => {
-    proxy.$refs["formRef"].validate(valid => {
+    proxy.$refs["formRef"].validate(async valid => {
       if (valid) {
-        // 瀹℃壒浜哄繀濉牎楠岋紙鎵�鏈夎妭鐐归兘瑕侀�変汉锛�
-        const hasEmptyApprover = approverNodes.value.some(node => !node.userId);
-        if (hasEmptyApprover) {
-          proxy.$modal.msgError("璇蜂负鎵�鏈夊鎵硅妭鐐归�夋嫨瀹℃壒浜猴紒");
-          return;
-        }
-        const approveUserIds = approverNodes.value.map(node => node.userId).join(",");
-        
         if (productData.value.length > 0) {
           // 鏂板鏃讹紝闇�瑕佷粠姣忎釜浜у搧瀵硅薄涓垹闄� id 瀛楁
           let processedProductData = productData.value;
@@ -1426,13 +1090,8 @@
           proxy.$modal.msgWarning("璇锋坊鍔犱骇鍝佷俊鎭�");
           return;
         }
-        let tempFileIds = [];
-        if (fileList.value.length > 0) {
-          tempFileIds = fileList.value.map(item => item.tempId);
-        }
-        form.value.tempFileIds = tempFileIds;
+        form.value.storageBlobDTOS = fileList.value;
         form.value.type = 2;
-        form.value.approveUserIds = approveUserIds;
 
         // 濡傛灉salesLedgerId涓虹┖锛屽垯涓嶄紶閫抯alesContractNo
         if (!form.value.salesLedgerId) {
@@ -1443,6 +1102,20 @@
         const submitData = { ...form.value };
         if (operationType.value === "add") {
           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 => {
@@ -1456,29 +1129,36 @@
   // 鍏抽棴寮规
   const closeDia = () => {
     proxy.resetForm("formRef");
-    // 閲嶇疆瀹℃壒浜鸿妭鐐癸紙榛樿涓�涓┖鑺傜偣锛�
-    approverNodes.value = [{ id: 1, userId: null }];
-    nextApproverId = 2;
     dialogFormVisible.value = false;
   };
   // 鎵撳紑浜у搧寮规
   const openProductForm = async (type, row, index) => {
+    // 缂栬緫鏃舵鏌ヤ骇鍝佸叆搴撳鏍哥姸鎬侊紝瀹屽叏鍏ュ簱鏃朵笉鑳界紪杈�
+    if (type === "edit" && row && row.stockInApprovalStatus === "瀹屽叏鍏ュ簱") {
+      proxy.$modal.msgWarning("瀹屽叏鍏ュ簱鐘舵�佺殑浜у搧涓嶈兘缂栬緫");
+      return;
+    }
+
     productOperationType.value = type;
     productOperationIndex.value = index;
     productForm.value = {};
     proxy.resetForm("productFormRef");
     productFormVisible.value = true;
-    
+
     // 鍏堣幏鍙栦骇鍝侀�夐」锛岀‘淇濇暟鎹姞杞藉畬鎴�
     await getProductOptions();
-    
+
     // 绛夊緟 DOM 鏇存柊
     await nextTick();
-    
+
+    if (type === "add") {
+      productForm.value.isChecked = false;
+    }
+
     if (type === "edit") {
       // 澶嶅埗琛屾暟鎹�
       productForm.value = { ...row };
-      
+
       // 濡傛灉鏄粠妯℃澘鍔犺浇鐨勬暟鎹紝鍙兘娌℃湁 productId 鍜� productModelId
       // 闇�瑕佹牴鎹� productCategory 鍜� specificationModel 鏉ユ煡鎵惧搴旂殑 ID
       if (!productForm.value.productId && productForm.value.productCategory) {
@@ -1489,25 +1169,34 @@
               return nodes[i].value;
             }
             if (nodes[i].children && nodes[i].children.length > 0) {
-              const found = findProductIdByCategory(nodes[i].children, categoryName);
+              const found = findProductIdByCategory(
+                nodes[i].children,
+                categoryName
+              );
               if (found) return found;
             }
           }
           return null;
         };
-        
-        const productId = findProductIdByCategory(productOptions.value, productForm.value.productCategory);
+
+        const productId = findProductIdByCategory(
+          productOptions.value,
+          productForm.value.productCategory
+        );
         if (productId) {
           productForm.value.productId = productId;
           // 鑾峰彇鍨嬪彿鍒楄〃骞剁瓑寰呭畬鎴�
           const modelRes = await modelList({ id: productId });
           modelOptions.value = modelRes;
-          
+
           // 绛夊緟 DOM 鏇存柊
           await nextTick();
-          
+
           // 鏍规嵁 specificationModel 鏌ユ壘 productModelId
-          if (productForm.value.specificationModel && modelOptions.value.length > 0) {
+          if (
+            productForm.value.specificationModel &&
+            modelOptions.value.length > 0
+          ) {
             const modelItem = modelOptions.value.find(
               item => item.model === productForm.value.specificationModel
             );
@@ -1521,15 +1210,15 @@
       } else if (productForm.value.productId) {
         // 濡傛灉鏈� productId锛屾甯稿姞杞藉瀷鍙峰垪琛�
         await getModels(productForm.value.productId);
-        
+
         // 绛夊緟 DOM 鏇存柊
         await nextTick();
-        
+
         if (productForm.value.productModelId) {
           getProductModel(productForm.value.productModelId);
         }
       }
-      
+
       // 鏈�鍚庡啀绛夊緟涓�娆� DOM 鏇存柊锛岀‘淇濇墍鏈夋暟鎹兘宸茶缃�
       await nextTick();
     }
@@ -1578,6 +1267,7 @@
     }
     return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
   };
+
   function convertIdToValue(data) {
     return data.map(item => {
       const { id, children, ...rest } = item;
@@ -1592,6 +1282,7 @@
       return newItem;
     });
   }
+
   // 鎻愪氦浜у搧琛ㄥ崟
   const submitProduct = () => {
     proxy.$refs["productFormRef"].validate(valid => {
@@ -1618,8 +1309,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 || [];
       });
     });
   };
@@ -1629,15 +1321,19 @@
       proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
       return;
     }
+    // 妫�鏌ラ�変腑鐨勪骇鍝佷腑鏄惁鏈夊畬鍏ㄥ叆搴撶殑
+    const hasFullyStocked = productSelectedRows.value.some(
+      row => row.stockInApprovalStatus === "瀹屽叏鍏ュ簱"
+    );
+    if (hasFullyStocked) {
+      proxy.$modal.msgWarning("閫変腑鐨勪骇鍝佷腑鍖呭惈瀹屽叏鍏ュ簱鐨勪骇鍝侊紝鏃犳硶鍒犻櫎");
+      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) {
@@ -1652,11 +1348,10 @@
           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 || [];
+            });
           });
         })
         .catch(() => {
@@ -1687,7 +1382,9 @@
   const handleDelete = () => {
     let ids = [];
     if (selectedRows.value.length > 0) {
-      ids = selectedRows.value.filter(item => item.salesLedgerId === null).map(item => item.id);
+      ids = selectedRows.value
+        .filter(item => item.salesLedgerId === null)
+        .map(item => item.id);
     } else {
       proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
       return;
@@ -1707,6 +1404,38 @@
         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("宸插彇娑�");
+      });
+  };
+
   // 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
   function getCurrentDate() {
     const today = new Date();
@@ -1715,6 +1444,7 @@
     const day = String(today.getDate()).padStart(2, "0");
     return `${year}-${month}-${day}`;
   }
+
   const mathNum = () => {
     if (!productForm.value.taxRate) {
       proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
@@ -1843,15 +1573,7 @@
       contractNo: form.value.salesLedgerId,
     });
     if (code == 200) {
-      productData.value = data;
-    }
-  };
-
-  const fileListRef = ref(null);
-  const fileListDialogVisible = ref(false);
-  const downLoadFile = row => {
-    if (fileListRef.value) {
-      fileListRef.value.open(row.salesLedgerFiles);
+      productData.value = data || [];
     }
   };
 
@@ -1863,13 +1585,19 @@
     }
   };
 
+  // 鎵撳紑闄勪欢寮规
+  const openFileDialog = async row => {
+    recordId.value = row.id;
+    fileListDialogVisible.value = true;
+  };
+
   // 鍒犻櫎妯℃澘
-  const handleDeleteTemplate = async (item) => {
+  const handleDeleteTemplate = async item => {
     if (!item.id) {
       proxy.$modal.msgWarning("鏃犳硶鍒犻櫎璇ユā鏉�");
       return;
     }
-    
+
     try {
       await ElMessageBox.confirm(
         `纭畾瑕佸垹闄ゆā鏉�"${item.templateName}"鍚楋紵`,
@@ -1880,7 +1608,7 @@
           type: "warning",
         }
       );
-      
+
       const res = await delPurchaseTemplate([item.id]);
       if (res && res.code === 200) {
         ElMessage({
@@ -1922,18 +1650,21 @@
     opacity: 0.6;
     background-color: #f5f7fa;
   }
+
   .el-row {
     justify-content: space-between;
     align-items: center;
   }
+
   .no-arrow-select {
     --el-select-suffix-icon-color: transparent; /* 闅愯棌榛樿涓嬫媺绠ご */
   }
+
   .select-button-group {
     display: flex;
     align-items: center;
   }
-  
+
   // 瀹℃壒浜鸿妭鐐瑰鍣ㄦ牱寮�
   .approver-nodes-container {
     display: flex;
@@ -1944,7 +1675,7 @@
     border-radius: 4px;
     border: 1px solid #e4e7ed;
   }
-  
+
   .approver-node-item {
     flex: 0 0 calc(33.333% - 12px);
     min-width: 200px;
@@ -1953,41 +1684,42 @@
     border-radius: 4px;
     border: 1px solid #dcdfe6;
     transition: all 0.3s;
-    
+
     &:hover {
       border-color: #409eff;
       box-shadow: 0 2px 8px rgba(64, 158, 255, 0.1);
     }
   }
-  
+
   .approver-node-header {
     display: flex;
     justify-content: space-between;
     align-items: center;
     margin-bottom: 8px;
   }
-  
+
   .approver-node-label {
     font-size: 13px;
     font-weight: 500;
     color: #606266;
   }
-  
+
   @media (max-width: 1200px) {
     .approver-node-item {
       flex: 0 0 calc(50% - 8px);
     }
   }
-  
+
   @media (max-width: 768px) {
     .approver-node-item {
       flex: 0 0 100%;
     }
   }
-  
+
   // 鍒犻櫎鍥炬爣鏍峰紡
   .delete-icon {
     transition: all 0.3s;
+
     &:hover {
       color: #f56c6c !important;
       transform: scale(1.2);

--
Gitblit v1.9.3