From bd7f920a53ba17016ee4f6324d155eef2bc4cece Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期一, 03 八月 2026 17:00:37 +0800
Subject: [PATCH] feat: 发货信息展示源单号

---
 src/views/salesManagement/salesLedger/index.vue |  560 +++++++++++++++----------------------------------------
 1 files changed, 159 insertions(+), 401 deletions(-)

diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index ea656cf..693c97b 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -129,7 +129,8 @@
                                show-overflow-tooltip />
               <el-table-column label="鍙戣揣杞︾墝"
                                minWidth="100px"
-                               align="center">
+                               align="center"
+                               v-if="false">
                 <template #default="scope">
                   <div>
                     <el-tag type="success"
@@ -161,7 +162,7 @@
                                prop="taxRate" />
               <el-table-column label="鍚◣鍗曚环(鍏�)"
                                prop="taxInclusiveUnitPrice"
-                               :formatter="sensitiveUnitPriceFormatter" />
+                               :formatter="sensitiveAmountFormatter" />
               <el-table-column label="鍚◣鎬讳环(鍏�)"
                                prop="taxInclusiveTotalPrice"
                                :formatter="sensitiveAmountFormatter" />
@@ -248,7 +249,7 @@
             </el-button>
             <el-button link
                        type="primary"
-                       @click="openFileDialog(scope.row)">闄勪欢
+                       @click="downloadOrder(scope.row.id)">涓嬭浇
             </el-button>
           </template>
         </el-table-column>
@@ -378,7 +379,7 @@
                          :reserve-keyword="false"
                          placeholder="璇烽�夋嫨"
                          clearable
-                         :disabled="operationType === 'view'"
+                         disabled
                          @change="changs">
                 <el-option v-for="item in userList"
                            :key="item.userId"
@@ -455,8 +456,8 @@
           <el-table-column label="绋庣巼(%)"
                            prop="taxRate" />
           <el-table-column label="鍚◣鍗曚环(鍏�)"
-                            prop="taxInclusiveUnitPrice"
-                            :formatter="unitPriceFormatter" />
+                           prop="taxInclusiveUnitPrice"
+                           :formatter="formattedNumber" />
           <el-table-column label="鍚◣鎬讳环(鍏�)"
                            prop="taxInclusiveTotalPrice"
                            :formatter="formattedNumber" />
@@ -566,7 +567,7 @@
                          width="160"
                          align="right">
           <template #default="scope">
-            {{ Number(scope.row.totalAmount ?? 0).toFixed(2) }}
+            {{ formatDecimal(scope.row.totalAmount) }}
           </template>
         </el-table-column>
         <el-table-column fixed="right"
@@ -664,7 +665,7 @@
           <el-col :span="12">
             <el-form-item label="鍚◣鍗曚环(鍏�)锛�"
                           prop="taxInclusiveUnitPrice">
-              <el-input-number :step="0.01"
+              <el-input-number :step="0.000001"
                                :min="0"
                                v-model="productForm.taxInclusiveUnitPrice"
                                style="width: 100%"
@@ -725,12 +726,33 @@
           <el-col :span="12">
             <el-form-item label="鏄惁鐢熶骇锛�"
                           prop="isProduction">
-              <el-radio-group v-model="productForm.isProduction">
-                <el-radio label="鏄�"
-                          :value="true" />
-                <el-radio label="鍚�"
-                          :value="false" />
-              </el-radio-group>
+              <div style="display: flex; align-items: center; width: 100%;">
+                <el-radio-group v-model="productForm.isProduction">
+                  <el-radio label="鏄�"
+                            :value="true" />
+                  <el-radio label="鍚�"
+                            :value="false" />
+                </el-radio-group>
+                <div 
+                  v-if="currentStock !== null" 
+                  :style="{
+                    marginLeft: '20px',
+                    padding: '0 12px',
+                    height: '28px',
+                    lineHeight: '28px',
+                    borderRadius: '4px',
+                    fontSize: '13px',
+                    fontWeight: '500',
+                    display: 'inline-block',
+                    whiteSpace: 'nowrap',
+                    backgroundColor: (productForm.quantity || 0) > currentStock ? '#fff0f0' : '#f0f9eb',
+                    border: (productForm.quantity || 0) > currentStock ? '1px solid #ffcccc' : '1px solid #e1f3d8',
+                    color: (productForm.quantity || 0) > currentStock ? '#f56c6c' : '#67c23a'
+                  }"
+                >
+                  <span>褰撳墠搴撳瓨锛歿{ currentStock }} {{ productForm.unit || '' }}</span>
+                </div>
+              </div>
             </el-form-item>
           </el-col>
         </el-row>
@@ -811,7 +833,7 @@
                     <span class="label">鍙戣揣鏃ユ湡锛�</span>
                     <span class="value">{{ formatDate(item.createTime) }}</span>
                   </div>
-                  <div>
+                  <div v-if="false">
                     <span class="label">鍙戣揣杞︾墝鍙凤細</span>
                     <span class="value">{{ item.shippingCarNumber }}</span>
                   </div>
@@ -899,7 +921,7 @@
     <!-- 鍙戣揣寮规 -->
     <el-dialog v-model="deliveryFormVisible"
                title="鍙戣揣淇℃伅"
-               width="40%"
+               width="960px"
                @close="closeDeliveryDia">
       <el-form :model="deliveryForm"
                label-width="120px"
@@ -914,10 +936,10 @@
                          placeholder="璇烽�夋嫨鍙戣揣绫诲瀷"
                          style="width: 100%"
                          @change="handleDeliveryTypeChange">
-                <el-option label="璐ц溅"
-                           value="璐ц溅" />
                 <el-option label="蹇��"
                            value="蹇��" />
+                <el-option label="璐ц溅"
+                           value="璐ц溅" />
               </el-select>
             </el-form-item>
           </el-col>
@@ -939,7 +961,7 @@
             </el-form-item>
           </el-col>
           <el-col :span="24"
-                  v-else>
+                  v-else-if="false">
             <el-form-item label="蹇�掑叕鍙革細"
                           prop="expressCompany">
               <el-input v-model="deliveryForm.expressCompany"
@@ -949,7 +971,7 @@
           </el-col>
         </el-row>
         <el-row :gutter="30"
-                v-if="deliveryForm.type === '蹇��'">
+                >
           <el-col :span="24">
             <el-form-item label="蹇�掑崟鍙凤細"
                           prop="expressNumber">
@@ -979,6 +1001,13 @@
                 <el-table-column label="鎵瑰彿"
                                  prop="batchNo"
                                  min-width="180" />
+                <el-table-column label="閿�鍞鍗曞彿"
+                                 min-width="180"
+                                 show-overflow-tooltip>
+                  <template #default="scope">
+                    {{ formatDeliveryBatchSalesOrderNo(scope.row) }}
+                  </template>
+                </el-table-column>
                 <el-table-column label="浜у搧澶х被"
                                  prop="productName"
                                  min-width="100" />
@@ -1017,6 +1046,7 @@
       <template #footer>
         <div class="dialog-footer">
           <el-button type="primary"
+                     :loading="deliveryLoading"
                      @click="submitDelivery">纭鍙戣揣
           </el-button>
           <el-button @click="closeDeliveryDia">鍙栨秷</el-button>
@@ -1047,12 +1077,19 @@
     delProduct,
     delLedgerFile,
     getProductInventory,
+    getPrintData,
   } from "@/api/salesManagement/salesLedger.js";
+  import { downloadSalesJpg, printSalesMulti } from "@/utils/documentPrint.js";
   import { getStockInventoryByModelId } from "@/api/inventoryManagement/stockInventory.js";
   import { modelList, productTreeList } from "@/api/basicData/product.js";
   import useFormData from "@/hooks/useFormData.js";
   import dayjs from "dayjs";
   import FileUpload from "@/components/AttachmentUpload/file/index.vue";
+  import {
+    tableAmountFormatter,
+    formatDecimal,
+    buildAmountSummaryFormat,
+  } from "@/utils/numberFormat";
   import ImageUpload from "@/components/AttachmentUpload/image/index.vue";
   import { getCurrentDate } from "@/utils/index.js";
   import { listCustomer } from "@/api/basicData/customer.js";
@@ -1182,6 +1219,7 @@
 
   // 鍙戣揣鐩稿叧
   const deliveryFormVisible = ref(false);
+  const deliveryLoading = ref(false);
   const currentDeliveryRow = ref(null);
   const getDeliveryBatchQuantity = item => {
     const quantity =
@@ -1192,6 +1230,29 @@
       item?.qualifiedQuantity ??
       item?.stockQuantity;
     return quantity ?? 0;
+  };
+  const formatDeliveryBatchSalesOrderNo = item =>
+    item?.salesContractNo || item?.sourceOrderNo || item?.salesOrderNo || "--";
+  const currentStock = ref(null);
+  const fetchCurrentStock = async (productModelId) => {
+    if (!productModelId) {
+      currentStock.value = null;
+      return;
+    }
+    try {
+      const res = await getStockInventoryByModelId(productModelId);
+      const rawList = Array.isArray(res?.data)
+        ? res.data
+        : res?.data?.records || res?.data?.rows || [];
+      let total = 0;
+      rawList.forEach(item => {
+        total += Number(getDeliveryBatchQuantity(item) || 0);
+      });
+      currentStock.value = total;
+    } catch (e) {
+      console.error(e);
+      currentStock.value = 0;
+    }
   };
   const getCurrentDeliveryRowQuantity = () => {
     return Number(currentDeliveryRow.value?.noQuantity || 0);
@@ -1278,7 +1339,7 @@
       shippingCarNumber: "",
       expressCompany: "",
       expressNumber: "",
-      type: "璐ц溅", // 璐ц溅, 蹇��
+      type: "蹇��", // 璐ц溅, 蹇��
     },
     deliveryRules: {
       shippingCarNumber: [
@@ -1396,18 +1457,7 @@
       return productOptions.value;
     });
   };
-  const formattedNumber = (row, column, cellValue) => {
-    if (cellValue === undefined || cellValue === null || cellValue === "") {
-      return "0.00";
-    }
-    return parseFloat(cellValue).toFixed(2);
-  };
-  const unitPriceFormatter = (row, column, cellValue) => {
-    if (cellValue === undefined || cellValue === null || cellValue === "") {
-      return "0.000000";
-    }
-    return parseFloat(cellValue).toFixed(6);
-  };
+  const formattedNumber = tableAmountFormatter;
   const findLedgerRecordByRow = row => {
     if (!row) return null;
     if (
@@ -1461,15 +1511,10 @@
     }
     return formattedNumber(row, column, cellValue);
   };
-  const sensitiveUnitPriceFormatter = (row, column, cellValue) => {
-    if (!isCurrentUserMaintainer(row)) {
-      return "*****";
-    }
-    return unitPriceFormatter(row, column, cellValue);
-  };
   // 鑾峰彇tree瀛愭暟鎹�
   const getModels = value => {
     productForm.value.productCategory = findNodeById(productOptions.value, value);
+    currentStock.value = null;
     modelList({ id: value }).then(res => {
       modelOptions.value = res;
     });
@@ -1479,9 +1524,11 @@
     if (index !== -1) {
       productForm.value.specificationModel = modelOptions.value[index].model;
       productForm.value.unit = modelOptions.value[index].unit;
+      fetchCurrentStock(value);
     } else {
       productForm.value.specificationModel = null;
       productForm.value.unit = null;
+      currentStock.value = null;
     }
   };
   const findNodeById = (nodes, productId) => {
@@ -1576,11 +1623,15 @@
   };
   // 涓昏〃鍚堣鏂规硶
   const summarizeMainTable = param => {
-    return proxy.summarizeTable(param, [
-      "contractAmount",
-      "taxInclusiveTotalPrice",
-      "taxExclusiveTotalPrice",
-    ]);
+    return proxy.summarizeTable(
+      param,
+      ["contractAmount", "taxInclusiveTotalPrice", "taxExclusiveTotalPrice"],
+      buildAmountSummaryFormat([
+        "contractAmount",
+        "taxInclusiveTotalPrice",
+        "taxExclusiveTotalPrice",
+      ])
+    );
   };
   // 瀛愯〃鍚堣鏂规硶
   const summarizeChildrenTable = (param, parentRow) => {
@@ -1602,11 +1653,19 @@
         return "";
       });
     }
-    return proxy.summarizeTable(param, [
-      "taxInclusiveUnitPrice",
-      "taxInclusiveTotalPrice",
-      "taxExclusiveTotalPrice",
-    ]);
+    return proxy.summarizeTable(
+      param,
+      [
+        "taxInclusiveUnitPrice",
+        "taxInclusiveTotalPrice",
+        "taxExclusiveTotalPrice",
+      ],
+      buildAmountSummaryFormat([
+        "taxInclusiveUnitPrice",
+        "taxInclusiveTotalPrice",
+        "taxExclusiveTotalPrice",
+      ])
+    );
   };
   // 鎵撳紑寮规
   const openForm = async (type, row) => {
@@ -1734,7 +1793,7 @@
       const quantity = Number(p.quantity ?? 0) || 0;
       const unitPrice = Number(p.unitPrice ?? 0) || 0;
       const taxRate = "13"; // 榛樿 13%锛屼究浜庣洿鎺ユ彁浜わ紙濡傞渶鍙湪浜у搧涓嚜琛屼慨鏀癸級
-      const taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
+      const taxInclusiveTotalPrice = formatDecimal(unitPrice * quantity);
       const taxExclusiveTotalPrice = proxy.calculateTaxExclusiveTotalPrice(
         taxInclusiveTotalPrice,
         taxRate
@@ -1746,7 +1805,7 @@
         unit: p.unit || "",
         quantity: quantity,
         taxRate: taxRate,
-        taxInclusiveUnitPrice: unitPrice.toFixed(6),
+        taxInclusiveUnitPrice: formatDecimal(unitPrice),
         taxInclusiveTotalPrice: taxInclusiveTotalPrice,
         taxExclusiveTotalPrice: taxExclusiveTotalPrice,
         invoiceType: "澧炴櫘绁�",
@@ -1805,6 +1864,7 @@
 
     productOperationType.value = type;
     productForm.value = {};
+    currentStock.value = null;
     if (type === "add") {
       productForm.value.isProduction = true;
     }
@@ -1831,6 +1891,7 @@
           );
           if (currentModel) {
             productForm.value.productModelId = currentModel.id;
+            fetchCurrentStock(currentModel.id);
           }
         }
       } catch (e) {
@@ -2033,359 +2094,31 @@
       });
   };
 
-  // 鎵撳嵃鍔熻兘
+  // 鎵撳嵃鍔熻兘 - 澶氶�夊悎骞堕瑙�
   const handlePrint = async () => {
     if (selectedRows.value.length === 0) {
       proxy.$modal.msgWarning("璇烽�夋嫨瑕佹墦鍗扮殑鏁版嵁");
       return;
     }
-
-    // 鏄剧ず鍔犺浇鐘舵��
-    proxy.$modal.loading("姝e湪鑾峰彇浜у搧鏁版嵁锛岃绋嶅��...");
-
+    proxy.$modal.loading("姝e湪鍔犺浇鎵撳嵃鏁版嵁...");
     try {
-      // 涓烘瘡涓�変腑鐨勯攢鍞彴璐﹁褰曟煡璇㈠搴旂殑浜у搧鏁版嵁
-      const printDataWithProducts = [];
-
+      const orders = [];
+      let companyName = '';
       for (const row of selectedRows.value) {
-        try {
-          // 璋冪敤productList鎺ュ彛鏌ヨ浜у搧鏁版嵁
-          const productRes = await productList({
-            salesLedgerId: row.id,
-            type: 1,
-          });
-
-          // 灏嗕骇鍝佹暟鎹暣鍚堝埌閿�鍞彴璐﹁褰曚腑
-          const rowWithProducts = {
-            ...row,
-            products: productRes.data || [],
-          };
-
-          printDataWithProducts.push(rowWithProducts);
-        } catch (error) {
-          console.error(`鑾峰彇閿�鍞彴璐� ${row.id} 鐨勪骇鍝佹暟鎹け璐�:`, error);
-          // 鍗充娇鏌愪釜璁板綍鐨勪骇鍝佹暟鎹幏鍙栧け璐ワ紝涔熻鍖呭惈璇ヨ褰�
-          printDataWithProducts.push({
-            ...row,
-            products: [],
-          });
-        }
+        const res = await getPrintData(row.id);
+        const data = res.data || res;
+        companyName = data.companyName || companyName;
+        orders.push(data.ledger);
       }
-
-      printData.value = printDataWithProducts;
-      console.log("鎵撳嵃鏁版嵁锛堝寘鍚骇鍝侊級:", printData.value);
-      printPreviewVisible.value = true;
-    } catch (error) {
-      console.error("鑾峰彇浜у搧鏁版嵁澶辫触:", error);
-      proxy.$modal.msgError("鑾峰彇浜у搧鏁版嵁澶辫触锛岃閲嶈瘯");
+      printSalesMulti(companyName, orders);
+    } catch (e) {
+      console.error('鎵撳嵃澶辫触:', e);
+      proxy.$modal.msgError("鎵撳嵃澶辫触");
     } finally {
       proxy.$modal.closeLoading();
     }
   };
-  // 鎵ц鎵撳嵃
-  const executePrint = () => {
-    console.log("寮�濮嬫墽琛屾墦鍗帮紝鏁版嵁鏉℃暟:", printData.value.length);
-    console.log("鎵撳嵃鏁版嵁:", printData.value);
 
-    // 鍒涘缓涓�涓柊鐨勬墦鍗扮獥鍙�
-    const printWindow = window.open("", "_blank", "width=800,height=600");
-
-    // 鏋勫缓鎵撳嵃鍐呭
-    let printContent = `
-                                                                                  <!DOCTYPE html>
-                                                                                  <html>
-                                                                                  <head>
-                                                                                    <meta charset="UTF-8">
-                                                                                    <title>鎵撳嵃棰勮</title>
-                                                                                    <style>
-                                                                                      body {
-                                                                                        margin: 0;
-                                                                                        padding: 0;
-                                                                                        font-family: "SimSun", serif;
-                                                                                        background: white;
-                                                                                      }
-                                                                                                                                   .print-page {
-                                                                                          width: 200mm;
-                                                                                          height: 75mm;
-                                                                                          padding: 10mm;
-                                                                                          padding-left: 20mm;
-                                                                                          background: white;
-                                                                                          box-sizing: border-box;
-                                                                                          page-break-after: always;
-                                                                                          page-break-inside: avoid;
-                                                                                        }
-                                                                                       .print-page:last-child {
-                                                                                         page-break-after: avoid;
-                                                                                       }
-                                                                                      .delivery-note {
-                                                                                        width: 100%;
-                                                                                        height: 100%;
-                                                                                        font-size: 12px;
-                                                                                        line-height: 1.2;
-                                                                                        display: flex;
-                                                                                        flex-direction: column;
-                                                                                        color: #000;
-                                                                                      }
-                                                                                      .header {
-                                                                                        text-align: center;
-                                                                                        margin-bottom: 8px;
-                                                                                      }
-                                                                                      .company-name {
-                                                                                        font-size: 18px;
-                                                                                        font-weight: bold;
-                                                                                        margin-bottom: 4px;
-                                                                                      }
-                                                                                      .document-title {
-                                                                                        font-size: 16px;
-                                                                                        font-weight: bold;
-                                                                                      }
-                                                                                      .info-section {
-                                                                                        margin-bottom: 8px;
-                                                                                        display: flex;
-                                                                                        justify-content: space-between;
-                                                                                        align-items: center;
-                                                                                      }
-                                                                                      .info-row {
-                                                                                        line-height: 20px;
-                                                                                      }
-                                                                                      .label {
-                                                                                        font-weight: bold;
-                                                                                        width: 60px;
-                                                                                        font-size: 12px;
-                                                                                      }
-                                                                                      .value {
-                                                                                        margin-right: 20px;
-                                                                                        min-width: 80px;
-                                                                                        font-size: 12px;
-                                                                                      }
-                                                                                               .table-section {
-                                                                                               margin-bottom: 40px;
-                                                                                        //  flex: 0.6;
-                                                                                       }
-                                                                                      .product-table {
-                                                                                        width: 100%;
-                                                                                        border-collapse: collapse;
-                                                                                        border: 1px solid #000;
-                                                                                      }
-                                                                                               .product-table th, .product-table td {
-                                                                                         border: 1px solid #000;
-                                                                                         padding: 6px;
-                                                                                         text-align: center;
-                                                                                         font-size: 12px;
-                                                                                         line-height: 1.4;
-                                                                                       }
-                                                                                      .product-table th {
-                                                                                        font-weight: bold;
-                                                                                      }
-                                                                                      .total-value {
-                                                                                        font-weight: bold;
-                                                                                      }
-                                                                                      .footer-section {
-                                                                                        margin-top: auto;
-                                                                                      }
-                                                                                      .footer-row {
-                                                                                        display: flex;
-                                                                                        margin-bottom: 3px;
-                                                                                        line-height: 22px;
-                                                                                        justify-content: space-between;
-                                                                                      }
-                                                                                      .footer-item {
-                                                                                        display: flex;
-                                                                                        margin-right: 20px;
-                                                                                      }
-                                                                                      .footer-item .label {
-                                                                                        font-weight: bold;
-                                                                                        width: 80px;
-                                                                                        font-size: 12px;
-                                                                                      }
-                                                                                      .footer-item .value {
-                                                                                        min-width: 80px;
-                                                                                        font-size: 12px;
-                                                                                      }
-                                                                                      .address-item .address-value {
-                                                                                        min-width: 200px;
-                                                                                      }
-                                                                                      @media print {
-                                                                                        body {
-                                                                                          margin: 0;
-                                                                                          padding: 0;
-                                                                                        }
-                                                                                                   .print-page {
-                                                                                           margin: 0;
-                                                                                           padding: 10mm;
-                                                                                           /* padding-left: 20mm; */
-                                                                                           page-break-inside: avoid;
-                                                                                           page-break-after: always;
-                                                                                         }
-                                                                                         .print-page:last-child {
-                                                                                           page-break-after: avoid;
-                                                                                         }
-                                                                                      }
-                                                                                    </style>
-                                                                                  </head>
-                                                                                  <body>
-                                                                                `;
-
-    // 涓烘瘡鏉℃暟鎹敓鎴愭墦鍗伴〉闈�
-    printData.value.forEach((item, index) => {
-      printContent += `
-                                                                                    <div class="print-page">
-                                                                                      <div class="delivery-note">
-                                                                                        <div class="header">
-                                                                                          <div class="document-title">闆跺敭鍙戣揣鍗�</div>
-                                                                                        </div>
-                                                                                        
-                                                                                        <div class="info-section">
-                                                                                          <div class="info-row">
-                                                                                            <div>
-                                                                                              <span class="label">鍙戣揣鏃ユ湡锛�</span>
-                                                                                              <span class="value">${formatDate(
-                                                                                                item.createTime
-                                                                                              )}</span>
-                                                                                            </div>
-                                                                                            <div>
-                                                                                              <span class="label">瀹㈡埛鍚嶇О锛�</span>
-                                                                                              <span class="value">${
-                                                                                                item.customerName
-                                                                                              }</span>
-                                                                                            </div>
-                                                                                          </div>
-                                                                                          <div class="info-row">
-                                                                                            <span class="label">鍗曞彿锛�</span>
-                                                                                            <span class="value">${
-                                                                                              item.salesContractNo ||
-                                                                                              ""
-                                                                                            }</span>
-                                                                                          </div>
-                                                                                        </div>
-
-                                                                                        <div class="table-section">
-                                                                                          <table class="product-table">
-                                                                                            <thead>
-                                                                                              <tr>
-                                                                                                <th>浜у搧鍚嶇О</th>
-                                                                                                <th>瑙勬牸鍨嬪彿</th>
-                                                                                                <th>鍗曚綅</th>
-                                                                                                <th>鍗曚环</th>
-                                                                                                <th>闆跺敭鏁伴噺</th>
-                                                                                                <th>闆跺敭閲戦</th>
-                                                                                              </tr>
-                                                                                            </thead>
-                                                                                            <tbody>
-                                                                                              ${
-                                                                                                item.products &&
-                                                                                                item
-                                                                                                  .products
-                                                                                                  .length >
-                                                                                                  0
-                                                                                                  ? item.products
-                                                                                                      .map(
-                                                                                                        product => `
-                                                                                                  <tr>
-                                                                                                    <td>${
-                                                                                                      product.productCategory ||
-                                                                                                      ""
-                                                                                                    }</td>
-                                                                                                    <td>${
-                                                                                                      product.specificationModel ||
-                                                                                                      ""
-                                                                                                    }</td>
-                                                                                                    <td>${
-                                                                                                      product.unit ||
-                                                                                                      ""
-                                                                                                    }</td>
-                                                                                                    <td>${
-                                                                                                      product.taxInclusiveUnitPrice ||
-                                                                                                      "0"
-                                                                                                    }</td>
-                                                                                                    <td>${
-                                                                                                      product.quantity ||
-                                                                                                      "0"
-                                                                                                    }</td>
-                                                                                                    <td>${
-                                                                                                      product.taxInclusiveTotalPrice ||
-                                                                                                      "0"
-                                                                                                    }</td>
-                                                                                                  </tr>
-                                                                                                `
-                                                                                                      )
-                                                                                                      .join(
-                                                                                                        ""
-                                                                                                      )
-                                                                                                  : '<tr><td colspan="6" style="text-align: center; color: #999;">鏆傛棤浜у搧鏁版嵁</td></tr>'
-                                                                                              }
-                                                                                            </tbody>
-                                                                                            <tfoot>
-                                                                                              <tr>
-                                                                                                <td class="label">鍚堣</td>
-                                                                                                <td class="total-value"></td>
-                                                                                                <td class="total-value"></td>
-                                                                                                <td class="total-value"></td>
-                                                                                                <td class="total-value">${getTotalQuantityForPrint(
-                                                                                                  item.products
-                                                                                                )}</td>
-                                                                                                <td class="total-value">${getTotalAmountForPrint(
-                                                                                                  item.products
-                                                                                                )}</td>
-                                                                                              </tr>
-                                                                                            </tfoot>
-                                                                                          </table>
-                                                                                        </div>
-
-                                                                                        <div class="footer-section">
-                                                                                          <div class="footer-row">
-                                                                                            <div class="footer-item">
-                                                                                              <span class="label">鏀惰揣鐢佃瘽锛�</span>
-                                                                                              <span class="value"></span>
-                                                                                            </div>
-                                                                                            <div class="footer-item">
-                                                                                              <span class="label">鏀惰揣浜猴細</span>
-                                                                                              <span class="value"></span>
-                                                                                            </div>
-                                                                                            <div class="footer-item address-item">
-                                                                                              <span class="label">鏀惰揣鍦板潃锛�</span>
-                                                                                              <span class="value address-value"></span>
-                                                                                            </div>
-                                                                                          </div>
-                                                                                          <div class="footer-row">
-                                                                                            <div class="footer-item">
-                                                                                              <span class="label">鎿嶄綔鍛橈細</span>
-                                                                                              <span class="value">${
-                                                                                                userStore.nickName ||
-                                                                                                "鎾曞紑鍓�"
-                                                                                              }</span>
-                                                                                            </div>
-                                                                                            <div class="footer-item">
-                                                                                              <span class="label">鎵撳嵃鏃ユ湡锛�</span>
-                                                                                              <span class="value">${formatDateTime(
-                                                                                                new Date()
-                                                                                              )}</span>
-                                                                                            </div>
-                                                                                          </div>
-                                                                                        </div>
-                                                                                      </div>
-                                                                                    </div>
-                                                                                  `;
-    });
-
-    printContent += `
-                                                                                  </body>
-                                                                                  </html>
-                                                                                `;
-
-    // 鍐欏叆鍐呭鍒版柊绐楀彛
-    printWindow.document.write(printContent);
-    printWindow.document.close();
-
-    // 绛夊緟鍐呭鍔犺浇瀹屾垚鍚庢墦鍗�
-    printWindow.onload = () => {
-      setTimeout(() => {
-        printWindow.print();
-        printWindow.close();
-        printPreviewVisible.value = false;
-      }, 500);
-    };
-  };
   // 鏍煎紡鍖栨棩鏈�
   const formatDate = dateString => {
     if (!dateString) return getCurrentDate();
@@ -2420,7 +2153,7 @@
     const total = products.reduce((sum, product) => {
       return sum + (parseFloat(product.taxInclusiveTotalPrice) || 0);
     }, 0);
-    return total.toFixed(2);
+    return formatDecimal(total);
   };
 
   // 鐢ㄤ簬鎵撳嵃鐨勮绠楀嚱鏁�
@@ -2437,7 +2170,7 @@
     const total = products.reduce((sum, product) => {
       return sum + (parseFloat(product.taxInclusiveTotalPrice) || 0);
     }, 0);
-    return total.toFixed(2);
+    return formatDecimal(total);
   };
 
   const mathNum = () => {
@@ -2478,7 +2211,7 @@
     isCalculating.value = true;
 
     // 璁$畻鍚◣鍗曚环 = 鍚◣鎬讳环 / 鏁伴噺
-    productForm.value.taxInclusiveUnitPrice = (totalPrice / quantity).toFixed(6);
+    productForm.value.taxInclusiveUnitPrice = formatDecimal(totalPrice / quantity);
 
     // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
     if (productForm.value.taxRate) {
@@ -2515,12 +2248,12 @@
     // 鍏堣绠楀惈绋庢�讳环 = 涓嶅惈绋庢�讳环 / (1 - 绋庣巼/100)
     const taxRateDecimal = taxRate / 100;
     const inclusiveTotalPrice = exclusiveTotalPrice / (1 - taxRateDecimal);
-    productForm.value.taxInclusiveTotalPrice = inclusiveTotalPrice.toFixed(2);
+    productForm.value.taxInclusiveTotalPrice = formatDecimal(inclusiveTotalPrice);
 
     // 璁$畻鍚◣鍗曚环 = 鍚◣鎬讳环 / 鏁伴噺
-    productForm.value.taxInclusiveUnitPrice = (
+    productForm.value.taxInclusiveUnitPrice = formatDecimal(
       inclusiveTotalPrice / quantity
-    ).toFixed(6);
+    );
 
     isCalculating.value = false;
   };
@@ -2543,7 +2276,7 @@
     isCalculating.value = true;
 
     // 璁$畻鍚◣鎬讳环
-    productForm.value.taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
+    productForm.value.taxInclusiveTotalPrice = formatDecimal(unitPrice * quantity);
 
     // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
     if (productForm.value.taxRate) {
@@ -2575,7 +2308,7 @@
     isCalculating.value = true;
 
     // 璁$畻鍚◣鎬讳环
-    productForm.value.taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
+    productForm.value.taxInclusiveTotalPrice = formatDecimal(unitPrice * quantity);
 
     // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
     if (productForm.value.taxRate) {
@@ -2716,6 +2449,28 @@
     fileDialogVisible.value = true;
   };
 
+  // 涓嬭浇閿�鍞崟
+  const downloadOrder = async (id) => {
+    try {
+      const res = await getPrintData(id);
+      const data = res.data || res;
+      downloadSalesJpg(data.companyName, data.ledger, '閿�鍞崟_' + (data.ledger.salesContractNo || id) + '.jpg');
+    } catch (e) {
+      console.error('涓嬭浇澶辫触:', e);
+    }
+  };
+
+  // 鎵撳嵃閿�鍞崟
+  const printOrder = async (id) => {
+    try {
+      const res = await getPrintData(id);
+      const data = res.data || res;
+      printSales(data.companyName, data.ledger);
+    } catch (e) {
+      console.error('鎵撳嵃澶辫触:', e);
+    }
+  };
+
   // 鎵撳紑鍙戣揣寮规
   const openDeliveryForm = async row => {
     // 妫�鏌ユ槸鍚﹀彲浠ュ彂璐�
@@ -2734,7 +2489,7 @@
       shippingCarNumber: "",
       expressCompany: "",
       expressNumber: "",
-      type: "璐ц溅",
+      type: "蹇��",
       batchNo: [],
       batchNoList,
     };
@@ -2772,6 +2527,7 @@
         const productModelId =
           currentDeliveryRow.value.productModelId ||
           currentDeliveryRow.value.modelId;
+        deliveryLoading.value = true;
         addShippingInfo({
           salesLedgerId: salesLedgerId,
           salesLedgerProductId: currentDeliveryRow.value.id,
@@ -2822,6 +2578,8 @@
               });
             }
           });
+        }).finally(() => {
+            deliveryLoading.value = false;
         });
       }
     });
@@ -3056,4 +2814,4 @@
       page-break-after: avoid;
     }
   }
-</style>
\ No newline at end of file
+</style>

--
Gitblit v1.9.3