From 73a8b690a2e4ed608212bda2110698a599563210 Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期一, 01 九月 2025 13:50:40 +0800
Subject: [PATCH] 完成打印机打印功能

---
 src/views/inventoryManagement/dispatchLog/index.vue |  584 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 577 insertions(+), 7 deletions(-)

diff --git a/src/views/inventoryManagement/dispatchLog/index.vue b/src/views/inventoryManagement/dispatchLog/index.vue
index 504074e..27d8f33 100644
--- a/src/views/inventoryManagement/dispatchLog/index.vue
+++ b/src/views/inventoryManagement/dispatchLog/index.vue
@@ -19,6 +19,7 @@
         <!-- <el-button type="primary" @click="openForm('add')">鏂板</el-button> -->
         <el-button @click="handleOut">瀵煎嚭</el-button>
         <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
+        <el-button type="primary" plain @click="handlePrint">鎵撳嵃</el-button>
       </div>
     </div>
     <div class="table_list">
@@ -128,6 +129,120 @@
         @pagination="paginationChange"
       />
     </div>
+
+    <!-- 鎵撳嵃棰勮寮圭獥 -->
+    <el-dialog
+      v-model="printPreviewVisible"
+      title="鎵撳嵃棰勮"
+      width="90%"
+      :close-on-click-modal="false"
+      class="print-preview-dialog"
+    >
+      <div class="print-preview-container">
+                 <div class="print-preview-header">
+           <el-button type="primary" @click="executePrint">鎵ц鎵撳嵃</el-button>
+           <el-button @click="printPreviewVisible = false">鍏抽棴棰勮</el-button>
+         </div>
+                   <div class="print-preview-content">
+          <div v-if="printData.length === 0" style="text-align: center; padding: 50px; color: #999;">
+            鏆傛棤鎵撳嵃鏁版嵁
+          </div>
+          <div v-else style="text-align: center; padding: 10px; color: #666; font-size: 14px; background: #e8f4fd; margin-bottom: 10px;">
+            鍏� {{ printData.length }} 鏉℃暟鎹緟鎵撳嵃
+          </div>
+          <div v-for="(item, index) in printData" :key="index" class="print-page">
+            <div class="delivery-note">
+              <div class="header">
+                <div class="company-name">榧庤瘹鐟炲疄涓氭湁闄愯矗浠诲叕鍙�</div>
+                <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.supplierName || '寮犵埍鏈�' }}</span>
+                   </div>
+                </div>
+                <div class="info-row">
+                  <span class="label">鍗曞彿锛�</span>
+                  <span class="value">{{ item.code }}</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>
+                    <tr>
+                      <td>{{ item.productCategory || '鐮傜伆鐮�' }}</td>
+                      <td>{{ item.specificationModel || '鏍囧噯' }}</td>
+                      <td>{{ item.unit || '鍧�' }}</td>
+                      <td>{{ item.taxInclusiveUnitPrice || '0' }}</td>
+                      <td>{{ item.inboundNum || '2000' }}</td>
+                      <td>{{ item.taxInclusiveTotalPrice || '0' }}</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">{{ item.inboundNum || '2000' }}</td>
+                       <td class="total-value">{{ item.taxInclusiveTotalPrice || '0' }}</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>
+        </div>
+      </div>
+    </el-dialog>
+
+
   </div>
 </template>
 
@@ -136,7 +251,6 @@
 import { ref } from "vue";
 import { ElMessageBox } from "element-plus";
 import useUserStore from "@/store/modules/user";
-import { userListNoPage } from "@/api/system/user.js";
 import {
   getStockOutPage,
   delStockOut,
@@ -146,19 +260,18 @@
 const { proxy } = getCurrentInstance();
 const tableData = ref([]);
 const selectedRows = ref([]);
-const userList = ref([]);
 const tableLoading = ref(false);
-const productList = ref([])
 const page = reactive({
   current: 1,
   size: 100,
 });
 const total = ref(0);
-const fileList = ref([]);
+
+// 鎵撳嵃鐩稿叧
+const printPreviewVisible = ref(false);
+const printData = ref([]);
 
 // 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const operationType = ref("");
-const dialogFormVisible = ref(false);
 const data = reactive({
   searchForm: {
     supplierName: "",
@@ -268,6 +381,296 @@
       proxy.$modal.msg("宸插彇娑�");
     });
 };
+
+// 鎵撳嵃鍔熻兘
+const handlePrint = () => {
+  if (selectedRows.value.length === 0) {
+    proxy.$modal.msgWarning("璇烽�夋嫨瑕佹墦鍗扮殑鏁版嵁");
+    return;
+  }
+  printData.value = [...selectedRows.value];
+  console.log('鎵撳嵃鏁版嵁:', printData.value);
+  printPreviewVisible.value = true;
+};
+
+// 鎵ц鎵撳嵃
+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="company-name">榧庤瘹鐟炲疄涓氭湁闄愯矗浠诲叕鍙�</div>
+            <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.supplierName || '寮犵埍鏈�'}</span>
+              </div>
+            </div>
+            <div class="info-row">
+              <span class="label">鍗曞彿锛�</span>
+              <span class="value">${item.code || ''}</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>
+                <tr>
+                  <td>${item.productCategory || '鐮傜伆鐮�'}</td>
+                  <td>${item.specificationModel || '鏍囧噯'}</td>
+                  <td>${item.unit || '鍧�'}</td>
+                  <td>${item.taxInclusiveUnitPrice || '0'}</td>
+                  <td>${item.inboundNum || '2000'}</td>
+                  <td>${item.taxInclusiveTotalPrice || '0'}</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">${item.inboundNum || '2000'}</td>
+                  <td class="total-value">${item.taxInclusiveTotalPrice || '0'}</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();
+  const date = new Date(dateString);
+  const year = date.getFullYear();
+  const month = String(date.getMonth() + 1).padStart(2, "0");
+  const day = String(date.getDate()).padStart(2, "0");
+  return `${year}/${month}/${day}`;
+};
+
+// 鏍煎紡鍖栨棩鏈熸椂闂�
+const formatDateTime = (date) => {
+  const year = date.getFullYear();
+  const month = String(date.getMonth() + 1).padStart(2, "0");
+  const day = String(date.getDate()).padStart(2, "0");
+  const hours = String(date.getHours()).padStart(2, "0");
+  const minutes = String(date.getMinutes()).padStart(2, "0");
+  const seconds = String(date.getSeconds()).padStart(2, "0");
+  return `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`;
+};
 // 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
 function getCurrentDate() {
   const today = new Date();
@@ -281,4 +684,171 @@
 });
 </script>
 
-<style scoped lang="scss"></style>
+<style scoped lang="scss">
+.print-preview-dialog {
+  .el-dialog__body {
+    padding: 0;
+    max-height: 80vh;
+    overflow-y: auto;
+  }
+}
+
+.print-preview-container {
+  .print-preview-header {
+    padding: 15px;
+    border-bottom: 1px solid #e4e7ed;
+    text-align: center;
+    
+    .el-button {
+      margin: 0 10px;
+    }
+  }
+  
+  .print-preview-content {
+  padding: 20px;
+  background-color: #f5f5f5;
+  min-height: 400px;
+}
+}
+
+.print-page {
+  width: 220mm;
+  height: 90mm;
+  padding: 10mm;
+  margin: 0 auto;
+  background: white;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
+  margin-bottom: 10px;
+  box-sizing: border-box;
+}
+
+.delivery-note {
+  width: 100%;
+  height: 100%;
+  font-family: "SimSun", serif;
+  font-size: 10px;
+  line-height: 1.2;
+  display: flex;
+  flex-direction: column;
+}
+
+.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: 14px;
+    }
+    
+    .value {
+      margin-right: 20px;
+      min-width: 80px;
+      font-size: 14px;
+    }
+  }
+}
+
+.table-section {
+  margin-bottom: 4px;
+  flex: 1;
+  
+  .product-table {
+    width: 100%;
+    border-collapse: collapse;
+    border: 1px solid #000;
+    
+         th, td {
+       border: 1px solid #000;
+       padding: 6px;
+       text-align: center;
+       font-size: 14px;
+       line-height: 1.4;
+     }
+    
+    th {
+      font-weight: bold;
+    }
+    
+    .total-label {
+      text-align: right;
+      font-weight: bold;
+    }
+    
+    .total-value {
+      font-weight: bold;
+    }
+  }
+}
+
+.footer-section {
+  .footer-row {
+    display: flex;
+    margin-bottom: 3px;
+    line-height: 20px;
+    justify-content: space-between;
+    
+         .footer-item {
+       display: flex;
+       margin-right: 20px;
+       
+       .label {
+         font-weight: bold;
+         width: 80px;
+         font-size: 14px;
+       }
+       
+       .value {
+         min-width: 80px;
+         font-size: 14px;
+       }
+       
+       &.address-item {
+         .address-value {
+           min-width: 200px;
+         }
+       }
+     }
+  }
+}
+
+@media print {
+  .app-container {
+    display: none;
+  }
+  
+           .print-page {
+      box-shadow: none;
+      margin: 0;
+      padding: 10mm;
+      padding-left: 20mm;
+      page-break-inside: avoid;
+      page-break-after: always;
+    }
+   .print-page:last-child {
+     page-break-after: avoid;
+   }
+}
+</style>

--
Gitblit v1.9.3