From 60a702a3dbcbe6e16a26faab49e66d710d1f8656 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期五, 28 十一月 2025 14:57:36 +0800
Subject: [PATCH] 湟水峡-销售台账/采购台账,有可能同一个公司不同单子,但是开票登记的时候会一起,一对多或者多对一

---
 src/views/procurementManagement/invoiceEntry/components/Modal.vue |  391 ++++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 295 insertions(+), 96 deletions(-)

diff --git a/src/views/procurementManagement/invoiceEntry/components/Modal.vue b/src/views/procurementManagement/invoiceEntry/components/Modal.vue
index 2e0f3f3..7960668 100644
--- a/src/views/procurementManagement/invoiceEntry/components/Modal.vue
+++ b/src/views/procurementManagement/invoiceEntry/components/Modal.vue
@@ -10,17 +10,7 @@
       <el-row :gutter="30">
         <el-col :span="12">
           <el-form-item label="閲囪喘鍚堝悓鍙凤細" prop="purchaseLedgerNo">
-            <el-input v-model="form.purchaseLedgerNo" disabled />
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="閿�鍞悎鍚屽彿锛�" prop="salesContractNo">
-            <el-input
-              v-model="form.salesContractNo"
-              placeholder="鑷姩濉厖"
-              clearable
-              disabled
-            />
+            <el-input v-model="form.purchaseLedgerNo" disabled placeholder="澶氬悎鍚屾壒閲忓鐞嗭紙鍏蜂綋鍚堝悓鍙疯浜у搧鍒楄〃锛�" />
           </el-form-item>
         </el-col>
         <el-col :span="12">
@@ -54,14 +44,10 @@
         </el-col>
         <el-col :span="12">
           <el-form-item label="鍙戠エ閲戦(鍏�)锛�" prop="invoiceAmount">
-            <el-input
-              type="number"
-              :step="0.01"
-              :min="0"
+            <el-input-number :step="0.01" :min="0" style="width: 100%"
               v-model="form.invoiceAmount"
-              placeholder="鑷姩濉厖"
+              placeholder="璇疯緭鍏ュ彂绁ㄩ噾棰�"
               clearable
-              :disabled="true"
             />
           </el-form-item>
         </el-col>
@@ -81,6 +67,20 @@
               style="width: 100%"
               v-model="form.entryDate"
               type="date"
+              value-format="YYYY-MM-DD"
+              format="YYYY-MM-DD"
+              clearable
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="褰曞叆鏃ユ湡锛�" prop="enterDate">
+            <el-date-picker
+              style="width: 100%"
+              v-model="form.enterDate"
+              type="date"
+              value-format="YYYY-MM-DD"
+              format="YYYY-MM-DD"
               clearable
             />
           </el-form-item>
@@ -101,49 +101,77 @@
             />
           </el-form-item>
         </el-col>
+      
       </el-row>
-      <el-form-item label="浜у搧淇℃伅锛�" prop="entryDate"> </el-form-item>
-      <PIMTable
-        rowKey="id"
-        :column="columns"
-        :tableData="form.productData"
-        height="auto"
+      <el-form-item label="浜у搧淇℃伅锛�"> </el-form-item>
+      <el-table
+        :data="form.productData"
+        border
+        show-summary
+        :summary-method="summarizeChildrenTable"
       >
-        <template #ticketsNumRef="{ row }">
-          <el-input-number
-            v-model="row.ticketsNum"
-            placeholder="璇烽�夋嫨"
-            :min="0"
-            :step="0.1"
-            clearable
-            style="width: 100%"
-            @change="invoiceNumBlur(row)"
-          />
-        </template>
-        <template #ticketsAmountRef="{ row }">
-          <el-input-number
-            v-model="row.ticketsAmount"
-            placeholder="璇烽�夋嫨"
-            :min="0"
-            :step="0.1"
-            clearable
-            style="width: 100%"
-            @change="invoiceAmountBlur(row)"
-          />
-        </template>
-      </PIMTable>
+        <el-table-column align="center" label="搴忓彿" type="index" width="60" />
+        <el-table-column label="鎵�灞炲悎鍚�" prop="purchaseLedgerNo" width="200">
+          <template #default="{ row }">
+            <el-tag type="primary">{{ row.purchaseLedgerNo }}</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="浜у搧澶х被" prop="productCategory" />
+        <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" width="150" />
+        <el-table-column label="鍗曚綅" prop="unit" width="70" />
+        <el-table-column label="鏁伴噺" prop="quantity" width="70" />
+        <el-table-column label="绋庣巼(%)" prop="taxRate" width="80" />
+        <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-column label="鏈寮�绁ㄦ暟" prop="ticketsNum" width="180">
+          <template #default="scope">
+            <el-input-number :step="0.1" :min="0" style="width: 100%"
+              :precision="2"
+              v-model="scope.row.ticketsNum"
+              @change="invoiceNumBlur(scope.row)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="鏈寮�绁ㄩ噾棰�(鍏�)"
+          prop="ticketsAmount"
+          width="180"
+        >
+          <template #default="scope">
+            <el-input-number :step="0.01" :min="0" style="width: 100%"
+              :precision="2"
+              v-model="scope.row.ticketsAmount"
+              @change="invoiceAmountBlur(scope.row)"
+            />
+          </template>
+        </el-table-column>
+      </el-table>
     </el-form>
     <template #footer>
-      <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
-      <el-button type="primary" :loading="modalLoading" @click="submitForm">
-        {{ modalOptions.confirmText }}
-      </el-button>
+			<el-button type="primary" :loading="modalLoading" @click="submitForm">
+				纭
+			</el-button>
+      <el-button @click="closeModal">鍙栨秷</el-button>
     </template>
   </el-dialog>
 </template>
 
 <script setup>
 import { ref, getCurrentInstance } from "vue";
+import { defineEmits } from 'vue';
 import { useModal } from "@/hooks/useModal";
 import useFormData from "@/hooks/useFormData";
 import FileUpload from "@/components/Upload/FileUpload.vue";
@@ -155,6 +183,7 @@
 import { getPurchaseById } from "@/api/procurementManagement/procurementLedger.js";
 import { getToken } from "@/utils/auth";
 import useUserStore from "@/store/modules/user";
+import dayjs from "dayjs";
 
 defineOptions({
   name: "鏉ョエ鐧昏妯℃�佹",
@@ -175,9 +204,12 @@
   issUer: userStore.nickName, // 褰曞叆浜�
   entryDate: undefined, // 寮�绁ㄦ棩鏈�
   salesContractNoId: undefined, // 寮�绁ㄦ棩鏈�
+  enterDate: dayjs().format("YYYY-MM-DD"),
   productData: [], // 琛ㄦ牸
   tempFileIds: [], // 鏂囦欢
 });
+
+const selectedContracts = ref([]); // 瀛樺偍閫変腑鐨勫悎鍚屾暟鎹�
 
 const rules = ref({
   invoiceNumber: [
@@ -187,6 +219,8 @@
   invoiceAmount: [
     { required: true, message: "璇疯緭鍏ュ彂绁ㄩ噾棰�", trigger: "blur" },
   ],
+  entryDate: [{ required: true, message: "璇烽�夋嫨寮�绁ㄦ棩鏈�", trigger: "change" }],
+  enterDate: [{ required: true, message: "璇烽�夋嫨褰曞叆鏃ユ湡", trigger: "change" }],
 });
 
 const {
@@ -201,14 +235,18 @@
   title: "鏉ョエ鐧昏",
 });
 
+const emit = defineEmits(['refreshList']);
+
 const columns = [
   {
     label: "浜у搧澶х被",
     prop: "productCategory",
+		width: 120,
   },
   {
     label: "瑙勬牸鍨嬪彿",
     prop: "specificationModel",
+		width: 120,
   },
   {
     label: "鍗曚綅",
@@ -273,28 +311,91 @@
   {
     label: "鏈潵绁ㄦ暟",
     prop: "futureTickets",
+		width: 100,
   },
   {
     label: "鏈潵绁ㄩ噾棰�(鍏�)",
     prop: "futureTicketsAmount",
+		width: 200,
   },
 ];
-
-const getTableData = async (type, id) => {
+const formattedNumber = (row, column, cellValue) => {
+	if (cellValue == 0) {
+		return parseFloat(cellValue).toFixed(2);
+	}
+	if (cellValue) {
+		return parseFloat(cellValue).toFixed(2);
+	} else {
+		return cellValue;
+	}
+};
+const getTableData = async (type, selectedRows) => {
   if (type == "add") {
-    const { data } = await getPurchaseNoById({ id });
-    form.purchaseLedgerNo = data.purchaseContractNumber;
-    form.invoiceAmount = data.invoiceAmount;
-    form.invoiceNumber = data.invoiceNumber;
-    form.entryDate = data.entryDate;
-    form.salesContractNoId = data.salesContractNoId;
-
-    const { data: infoData } = await getInfo({ id });
-    form.salesContractNo = infoData.salesContractNo;
-    form.projectName = infoData.projectName;
-    form.supplierName = infoData.supplierName;
-    form.productData = infoData.productData;
+    // 妫�鏌ユ墍鏈夐�夋嫨鐨勫悎鍚屾槸鍚﹀叿鏈夌浉鍚岀殑渚涘簲鍟嗗悕绉�
+    const firstRow = selectedRows[0];
+    const isSameSupplier = selectedRows.every(row => 
+      row.supplierName === firstRow.supplierName
+    );
+    
+    if (!isSameSupplier) {
+      proxy.$modal.msgError("璇烽�夋嫨鐩稿悓渚涘簲鍟嗗悕绉扮殑鍚堝悓");
+      return;
+    }
+    
+    // 鍏佽涓嶅悓鐨勯噰璐悎鍚屽彿鎵归噺澶勭悊锛屾棤闇�妫�鏌ラ噸澶�
+    
+    // 娓呯┖琛ㄥ崟鏁版嵁
+    Object.keys(form).forEach(key => {
+      if (key !== 'productData') {
+        form[key] = undefined;
+      }
+    });
+    form.productData = [];
+    
+    // 鍔犺浇鎵�鏈夐�変腑鍚堝悓鐨勪骇鍝佹暟鎹�
+    const promises = selectedRows.map(row => 
+      getInfo({ id: row.id })
+    );
+    
+    Promise.all(promises).then(results => {
+      // 鍚堝苟鎵�鏈夊悎鍚岀殑浜у搧鏁版嵁锛屽苟涓烘瘡涓骇鍝佹坊鍔犲搴旂殑鍚堝悓淇℃伅
+      const allProductData = [];
+      results.forEach((result, index) => {
+        const contract = selectedRows[index];
+        const contractId = contract.id;
+        if (result.data && result.data.productData) {
+          result.data.productData.forEach(item => {
+            allProductData.push({
+              ...item,
+              id: contractId, // 鏄庣‘璁剧疆鍚堝悓ID
+              purchaseLedgerNo: contract.purchaseContractNumber, // 娣诲姞閲囪喘鍚堝悓鍙�
+              supplierName: contract.supplierName, // 娣诲姞渚涘簲鍟嗗悕绉�
+              projectName: contract.projectName // 娣诲姞椤圭洰鍚嶇О
+            });
+          });
+        }
+      });
+      
+      // 璁剧疆琛ㄥ崟鏁版嵁锛堜娇鐢ㄧ涓�涓悎鍚岀殑鍩烘湰淇℃伅锛岄噰璐悎鍚屽彿鐣欑┖锛�
+      form.purchaseLedgerNo = ""; // 閲囪喘鍚堝悓鍙风暀绌猴紝鍥犱负浼氬湪浜у搧琛ㄦ牸涓垎鍒樉绀�
+      form.invoiceAmount = 0;
+      form.invoiceNumber = "";
+      form.entryDate = dayjs().format("YYYY-MM-DD");
+      form.enterDate = dayjs().format("YYYY-MM-DD");
+      form.salesContractNo = results[0].data.salesContractNo;
+      form.projectName = results[0].data.projectName;
+      form.supplierName = results[0].data.supplierName;
+      // 淇濈暀褰曞叆浜轰俊鎭�
+      form.issUerId = userStore.id;
+      form.issUer = userStore.nickName;
+      
+      form.productData = allProductData;
+      
+      // 瀛樺偍閫変腑鐨勫悎鍚屾暟鎹�
+      selectedContracts.value = selectedRows;
+    });
   } else if (type == "edit") {
+    const id = Array.isArray(selectedRows) ? selectedRows[0].id : selectedRows;
     const data = await getPurchaseById({ id, type: 2 });
     form.purchaseLedgerNo = data.purchaseContractNumber;
     form.invoiceAmount = data.invoiceAmount;
@@ -306,7 +407,19 @@
     form.productData = data.productData;
   }
 };
-
+// 瀛愯〃鍚堣鏂规硶
+const summarizeChildrenTable = (param) => {
+	return proxy.summarizeTable(param, [
+		"taxInclusiveUnitPrice",
+		"taxInclusiveTotalPrice",
+		"taxExclusiveTotalPrice",
+		"ticketsNum",
+		"ticketsAmount",
+		"ticketsAmountRef",
+		"futureTickets",
+		"futureTicketsAmount",
+	]);
+};
 //鏈鏉ョエ鏁板け鐒︽搷浣�
 const invoiceNumBlur = (row) => {
   if (!row.ticketsNum || row.ticketsNum === "") {
@@ -318,11 +431,11 @@
     return;
   }
   // 璁$畻鏈鏉ョエ閲戦
-  row.ticketsAmount = row.ticketsNum * row.taxInclusiveUnitPrice;
+  row.ticketsAmount = (row.ticketsNum * row.taxInclusiveUnitPrice).toFixed(2)
   // 璁$畻鏈潵绁ㄦ暟
-  row.futureTickets = row.tempFutureTickets - row.ticketsNum;
+  row.futureTickets = (row.tempFutureTickets - row.ticketsNum).toFixed(2)
   // 璁$畻鏈潵绁ㄩ噾棰�
-  row.futureTicketsAmount = row.tempFutureTicketsAmount - row.ticketsAmount;
+  row.futureTicketsAmount = (row.tempFutureTicketsAmount - row.ticketsAmount).toFixed(2)
   calculateinvoiceAmount();
 };
 
@@ -341,9 +454,9 @@
     (row.ticketsAmount / row.taxInclusiveUnitPrice).toFixed(2)
   );
   // 璁$畻鏈潵绁ㄦ暟
-  row.futureTickets = row.tempFutureTickets - row.ticketsNum;
+  row.futureTickets = (row.tempFutureTickets - row.ticketsNum).toFixed(2)
   // 璁$畻鏈潵绁ㄩ噾棰�
-  row.futureTicketsAmount = row.tempFutureTicketsAmount - row.ticketsAmount;
+  row.futureTicketsAmount = (row.tempFutureTicketsAmount - row.ticketsAmount).toFixed(2)
   calculateinvoiceAmount();
 };
 
@@ -351,16 +464,29 @@
   let invoiceAmountTotal = 0;
   form.productData.forEach((item) => {
     if (item.ticketsAmount) {
-      invoiceAmountTotal += item.ticketsAmount;
+      invoiceAmountTotal += Number(item.ticketsAmount);
     }
   });
   form.invoiceAmount = invoiceAmountTotal.toFixed(2);
 };
 
-const open = (type, eid) => {
-  openModal();
-  getTableData(type, eid);
-  id.value = eid;
+const open = async (type, selectedRows) => {
+  visible.value = true;
+  
+  // 濡傛灉鏄壒閲忔搷浣滐紝璁剧疆鏍囬
+  if (Array.isArray(selectedRows) && selectedRows.length > 1) {
+    modalOptions.title = `鎵归噺鏂板 (${selectedRows.length}鏉�)`;
+  } else {
+    modalOptions.title = type == "add" ? "鏂板" : "缂栬緫";
+  }
+  
+  // 濡傛灉鏄崟涓搷浣滐紝鑾峰彇id
+  if (!Array.isArray(selectedRows) || selectedRows.length === 1) {
+    const idValue = Array.isArray(selectedRows) ? selectedRows[0].id : selectedRows;
+    id.value = idValue;
+  }
+  
+  await getTableData(type, selectedRows);
 };
 
 const uploadSuccess = (response) => {
@@ -373,29 +499,101 @@
   form.tempFileIds = form.tempFileIds.filter((item) => item !== tempId);
 };
 
+const closeAndRefresh = () => {
+  closeModal();
+  emit('refreshList');
+};
+
 const submitForm = () => {
-  formRef.value.validate(async (valid, fields) => {
+  proxy.$refs["formRef"].validate((valid) => {
     if (valid) {
-      modalLoading.value = true;
-      const { code } = await addOrUpdateRegistration({
-        purchaseLedgerId: id.value,
-        purchaseContractNumber: form.purchaseLedgerNo,
-        invoiceNumber: form.invoiceNumber,
-        invoiceAmount: form.invoiceAmount,
-        salesContractNo: form.salesContractNo,
-        projectName: form.projectName,
-        productData: form.productData,
-        issueDate: form.entryDate,
-        issUerId: form.issUerId, // 褰曞叆浜篿d
-        issUer: form.issUer, // 褰曞叆浜�
-        salesContractNoId: form.salesContractNoId,
-        supplierName: form.supplierName,
-        tempFileIds: form.tempFileIds,
-        type: 4,
-      });
-      modalLoading.value = false;
-      if (code == 200) {
-        closeModal();
+      // 濡傛灉鏄壒閲忔搷浣滐紝灏嗘墍鏈夊悎鍚岀殑鏁版嵁鏀惧湪涓�涓暟缁勯噷锛屽彧璋冪敤涓�娆℃帴鍙�
+      if (selectedContracts.value.length > 1) {
+        // 鍒涘缓鍖呭惈鎵�鏈夊悎鍚屾暟鎹殑鏁扮粍
+        const batchData = selectedContracts.value.map(contract => {
+          // 绛涢�夊嚭灞炰簬褰撳墠鍚堝悓鐨勪骇鍝佹暟鎹�
+          const contractProductData = form.productData.filter(item => 
+            item.id === contract.id
+          );
+          
+          // 涓烘瘡涓噰璐悎鍚屽垱寤虹嫭绔嬬殑瀵硅薄
+          return {
+            // 鍩虹琛ㄥ崟鏁版嵁
+            invoiceNumber: form.invoiceNumber,
+            invoiceAmount: form.invoiceAmount,
+            entryDate: form.entryDate,
+            enterDate: form.enterDate,
+            issUerId: form.issUerId, // 褰曞叆浜篿d
+            issUer: form.issUer, // 褰曞叆浜�
+            tempFileIds: form.tempFileIds,
+            
+            // 鍚堝悓瀹為檯淇℃伅
+            purchaseLedgerId: contract.id, // 浣跨敤id浣滀负瀛楁鍚嶏紝鍊间负purchaseLedgerId
+            purchaseContractNumber: contract.purchaseContractNumber, // 浣跨敤瀹為檯鐨勯噰璐悎鍚屽彿
+            salesContractNo: contract.salesContractNo, // 浣跨敤瀹為檯鐨勯攢鍞悎鍚屽彿
+            supplierName: contract.supplierName, // 浣跨敤瀹為檯鐨勪緵搴斿晢鍚嶇О
+            projectName: contract.projectName, // 浣跨敤瀹為檯鐨勯」鐩悕绉�
+            
+            // 浜у搧鏁版嵁
+            productData: proxy.HaveJson(contractProductData),
+            
+            // 鎵归噺鏍囪瘑
+            isBatch: true,
+            type: 4
+          };
+        });
+        
+        // 鍙皟鐢ㄤ竴娆℃帴鍙o紝浼犻�掑寘鍚墍鏈夊悎鍚屾暟鎹殑鏁扮粍
+        modalLoading.value = true;
+        addOrUpdateRegistration(batchData).then((res) => {
+          modalLoading.value = false;
+          if (res.code === 200) {
+            proxy.$modal.msgSuccess("鎵归噺鐧昏鎴愬姛");
+            closeAndRefresh();
+          }
+        }).catch(() => {
+          modalLoading.value = false;
+          proxy.$modal.msgError("鎵归噺鐧昏澶辫触");
+        });
+      } else {
+        // 鍗曚釜鍚堝悓鎻愪氦閫昏緫
+        const singleContract = selectedContracts.value[0];
+        const singleForm = {
+          // 鍩虹琛ㄥ崟鏁版嵁
+          invoiceNumber: form.invoiceNumber,
+          invoiceAmount: form.invoiceAmount,
+          entryDate: form.entryDate,
+          enterDate: form.enterDate,
+          issUerId: form.issUerId, // 褰曞叆浜篿d
+          issUer: form.issUer, // 褰曞叆浜�
+          tempFileIds: form.tempFileIds,
+          
+          // 鍚堝悓瀹為檯淇℃伅
+          purchaseLedgerId: singleContract.id, // 浣跨敤id浣滀负瀛楁鍚嶏紝鍊间负purchaseLedgerId
+          purchaseContractNumber: singleContract.purchaseContractNumber, // 浣跨敤瀹為檯鐨勯噰璐悎鍚屽彿
+          salesContractNo: singleContract.salesContractNo, // 浣跨敤瀹為檯鐨勯攢鍞悎鍚屽彿
+          supplierName: singleContract.supplierName, // 浣跨敤瀹為檯鐨勪緵搴斿晢鍚嶇О
+          projectName: singleContract.projectName, // 浣跨敤瀹為檯鐨勯」鐩悕绉�
+          
+          // 浜у搧鏁版嵁
+          productData: proxy.HaveJson(form.productData),
+          
+          // 鎵归噺鏍囪瘑
+          isBatch: false,
+          type: 4
+        };
+        
+        modalLoading.value = true;
+        addOrUpdateRegistration(singleForm).then((res) => {
+          modalLoading.value = false;
+          if (res.code === 200) {
+            proxy.$modal.msgSuccess("鐧昏鎴愬姛");
+            closeAndRefresh();
+          }
+        }).catch(() => {
+          modalLoading.value = false;
+          proxy.$modal.msgError("鐧昏澶辫触");
+        });
       }
     }
   });
@@ -403,6 +601,7 @@
 
 defineExpose({
   open,
+  closeAndRefresh,
 });
 </script>
 

--
Gitblit v1.9.3