pan
2025-11-19 6cf884fcafe6fa25e0a0eef35014bd7766d30bb6
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/inbound/Dt_MaterielToMes.js
@@ -14,9 +14,9 @@
    modelBody: '',
    modelFooter: ''
  },
  tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
  tableAction: '',
  buttons: { view: [{
 name: '生成二维码',
  name: '生成二维码',
  type: 'success',
  value: '生成二维码',
  onClick: async function () {
@@ -31,43 +31,18 @@
      return;
    }
    // 2. èŽ·å–å•æ®ç¼–å·
    const newMaterialBarCode = selectedRows[0].newMaterialBarCode;
    if (!newMaterialBarCode) {
      ElMessage.error('选中的数据中未找到单据编号');
    // 2. èŽ·å–æ ¸å¿ƒç‰©æ–™å­—æ®µï¼ˆæ–™å·ã€å“åã€è§„æ ¼ç­‰ï¼‰
    const { materielCode, materialName, specification, lotNo, batchNo, date } = selectedRows[0];
    if (!materielCode) {
      ElMessage.error('选中数据缺少料号信息');
      return;
    }
    // 3. èŽ·å–å•æ®æ˜Žç»†æ•°æ®ï¼ˆæ–°å¢žï¼šé€šè¿‡å•æ®ç¼–å·èŽ·å–QtyTrans、MaterialCode、MaterialName)
    // let detailList  = [];
    // const loading = ElLoading.service({ text: '获取单据明细中...' });
    // try {
    //   const res = await http.post('/api/DocumentDetail/details', { transNo: transNo });
    //   // æ ¡éªŒè¿”回格式(必须是数组且至少有一条数据)
    //   if (!res.status || !Array.isArray(res.data) || res.data.length === 0) {
    //     throw new Error('未查询到单据明细数据');
    //   }
    //   detailList = res.data;
    //   // æ ¡éªŒæ¯æ¡æ˜Žç»†çš„必填字段
    //   detailList.forEach((item, index) => {
    //     if (!item.qtyTrans || !item.materialCode || !item.materialName) {
    //       throw new Error(`第${index + 1}条明细数据不完整`);
    //     }
    //   });
    // } catch (err) {
    //   ElMessage.error(err.message || '获取单据明细失败');
    //   loading.close();
    //   return;
    // } finally {
    //   loading.close();
    // }
    // 4. ç”ŸæˆäºŒç»´ç 
    // 3. ç”ŸæˆäºŒç»´ç ï¼ˆå†…容为料号,可根据需求拼接更多信息)
    let qrCodeUrl = '';
    try {
      qrCodeUrl = await QRCode.toDataURL(newMaterialBarCode, {
        width: 200, // äºŒç»´ç å¤§å°é€‚配布局
      qrCodeUrl = await QRCode.toDataURL(materielCode, {
        width: 150, // é€‚配标识卡尺寸
        margin: 1
      });
    } catch (err) {
@@ -76,11 +51,11 @@
      return;
    }
    // 5. åˆ›å»ºå¼¹çª—
    // 4. åˆ›å»ºå¼¹çª—挂载节点
    const mountNode = document.createElement('div');
    document.body.appendChild(mountNode);
    // æ·»åŠ æ‰“å°ä¸“ç”¨æ ·å¼
    // æ‰“印专用样式
    const addPrintStyle = () => {
      const style = document.createElement('style');
      style.id = 'qr-print-style';
@@ -88,39 +63,60 @@
        @media print {
          body > *:not(.print-container) { display: none !important; }
          .print-container {
            position: fixed !important;
            top: 50px !important;
            left: 50px !important;
            width: 90% !important;
            height: auto !important;
              position: fixed !important;
              top: 0 !important;
              left: 0 !important;
              width: 100% !important;
              height: 100% !important;
              display: flex !important;
              align-items: center !important;
              justify-content: center !important;
              padding: 0 !important;
              margin: 0 !important;
          }
          /* æ‰“印内容布局 */
          .print-content {
            display: flex !important;
            flex-direction: column !important;
            gap: 20px !important;
          .material-card {
              padding: 5mm; /* ä½¿ç”¨æ¯«ç±³å•位更适配打印尺寸 */
              font-size: 2mm; /* æŒ‰æ¯”例缩小字体 */
              position: relative;
              width: 80mm; /* ç•¥å°äºŽçº¸å¼ å®½åº¦ï¼Œç•™è¾¹è· */
              height: 60mm; /* ç•¥å°äºŽçº¸å¼ é«˜åº¦ï¼Œç•™è¾¹è· */
              box-sizing: border-box; /* ç¡®ä¿padding不影响整体尺寸 */
          }
          .qr-wrapper {
            align-self: flex-start !important; /* äºŒç»´ç é å·¦ */
          .card-title {
            text-align: center;
            font-size: 2mm; /* æ ‡é¢˜ç•¥å¤§ */
            font-weight: bold;
            margin-top: 5mm; /* å‡å°é¡¶éƒ¨é—´è· */
            margin-right: 20mm; /* é€‚配缩小的二维码位置 */
          }
          .detail-fields {
            display: flex !important;
            justify-content: space-around !important; /* å­—段均匀分布 */
            width: 100% !important;
            margin-top: 20px !important;
            font-size: 16px !important;
          .card-fields {
            display: flex;
            flex-wrap: wrap;
            justify-content: space-between;
            gap:1.5mm; /* ç¼©å°é—´è· */
            margin-top: 8mm; /* è°ƒæ•´å­—段容器位置 */
          }
          .field-item {
            text-align: center !important;
            padding: 10px !important;
            border: 1px solid #eee !important;
            border-radius: 4px !important;
            width: 30% !important; /* æ¯ä¸ªå­—段占1/3宽度 */
            width: 48%; /* ä¿æŒä¸¤åˆ—布局 */
            line-height: 1.3; /* ç´§å‡‘行高 */
          }
          .field-label {
            font-weight: bold !important;
            margin-bottom: 5px !important;
            display: block !important;
          .qr-wrapper {
            position: absolute;
            top: 5mm; /* è°ƒæ•´äºŒç»´ç é¡¶éƒ¨ä½ç½® */
            right: 3mm; /* è°ƒæ•´äºŒç»´ç å³ä¾§ä½ç½® */
            width: 15mm; /* äºŒç»´ç å°ºå¯¸é€‚配小卡片 */
            height: 15mm;
          }
          .qr-wrapper img {
            width: 100% !important; /* ç¡®ä¿äºŒç»´ç å¡«å……满容器 */
            height: 100% !important;
            object-fit: contain;
          }
        }
      `;
@@ -130,106 +126,83 @@
    // æ‰“印函数
    const printQrCode = () => {
      // åˆ›å»ºæ‰“印容器
      const printContainer = document.createElement('div');
      printContainer.className = 'print-container';
      printContainer.style = 'position:fixed; top:-9999px; left:-9999px;';
      document.body.appendChild(printContainer);
      // å¡«å……打印内容(布局:二维码左上角 + ä¸‰ä¸ªå­—段均匀分布)
      // æž„建物料标识卡HTML结构
      printContainer.innerHTML = `
        <div class="print-content">
          <!-- äºŒç»´ç ï¼ˆå·¦ä¸Šè§’) -->
          <div class="qr-wrapper">
            <img src="${qrCodeUrl}" style="width: 200px; height: 200px;" />
            <p style="margin-top: 10px; font-size: 16px;">单据编号:${newMaterialBarCode}</p>
        <div class="material-card">
          <div class="card-title">卓力能物料标识卡(小包)</div>
          <div class="card-fields">
            <div class="field-item">料号:${materielCode}</div>
            <div class="field-item">供应商编码:</div>
            <div class="field-item">品名:${materialName || '无'}</div>
            <div class="field-item">采购单号:</div>
            <div class="field-item">规格:${specification || '无'}</div>
            <div class="field-item">数量/总数:0PCS/0PCS</div>
            <div class="field-item">批号:${lotNo || '无'}</div>
            <div class="field-item">批次:${batchNo || '无'}</div>
            <div class="field-item">厂区:卓力能三厂</div>
            <div class="field-item">日期:${date || '无'}</div>
          </div>
          <!-- æ˜Žç»†å­—段(均匀分布) -->
          <div class="detail-fields">
            <div class="field-item">
              <span class="field-label">交易数量</span>
              <span>${detailList[0].qtyTrans}</span>
            </div>
            <div class="field-item">
              <span class="field-label">物料编码</span>
              <span>${detailList[0].materialCode}</span>
            </div>
            <div class="field-item">
              <span class="field-label">物料名称</span>
              <span>${detailList[0].materialName}</span>
            </div>
          <div class="qr-wrapper">
            <img src="${qrCodeUrl}" alt="物料二维码" />
          </div>
        </div>
      `;
      // æ·»åŠ æ‰“å°æ ·å¼
      const printStyle = addPrintStyle();
      // æ¸…理函数(防止重复移除)
      const cleanUp = () => {
        if (printContainer.parentNode === document.body) {
          document.body.removeChild(printContainer);
        }
        if (printStyle && printStyle.parentNode === document.head) {
          document.head.removeChild(printStyle);
        }
        document.body.removeChild(printContainer);
        document.head.removeChild(printStyle);
        window.removeEventListener('afterprint', cleanUp);
      };
      // ç›‘听打印完成
      window.addEventListener('afterprint', cleanUp, { once: true });
      // è§¦å‘打印
      window.print();
    };
    // å¼¹çª—组件(预览布局)
    // å¼¹çª—预览组件
    const vnode = createVNode(ElDialog, {
      title: '单据二维码及明细',
      width: '600px',
      title: '物料标识卡及二维码',
      width: '500px',
      modelValue: true,
      style: { maxHeight: '500px', overflowY: 'auto' },
      appendToBody: true,
      'onUpdate:modelValue': (isVisible) => {
        if (!isVisible) {
          const printStyle = document.getElementById('qr-print-style');
          if (printStyle && printStyle.parentNode === document.head) {
            document.head.removeChild(printStyle);
          }
          printStyle && document.head.removeChild(printStyle);
          render(null, mountNode);
          if (mountNode.parentNode === document.body) {
            document.body.removeChild(mountNode);
          }
          document.body.removeChild(mountNode);
        }
      }
    }, {
      default: () => [
        // é¢„览区布局(和打印布局一致)
        h('div', { style: { padding: '20px' } }, [
          // äºŒç»´ç é¢„览(左上角)
          h('div', { style: { marginBottom: '20px' } }, [
            h(ElImage, {
              src: qrCodeUrl,
              alt: '单据二维码',
              style: { width: '200px', height: '200px' }
            }),
            h('p', { style: { marginTop: '10px', fontSize: '16px' } }, `单据编号:${newMaterialBarCode}`)
          ]),
          // æ˜Žç»†å­—段预览(均匀分布)
        //   h('div', { style: { display: 'flex', justifyContent: 'space-around', gap: '10px' } }, [
        //     h('div', { style: { textAlign: 'center', padding: '10px', border: '1px solid #eee', width: '30%' } }, [
        //       h('div', { style: { fontWeight: 'bold', marginBottom: '5px' } }, '交易数量'),
        //       h('div', null, detailList[0].qtyTrans)
        //     ]),
        //     h('div', { style: { textAlign: 'center', padding: '10px', border: '1px solid #eee', width: '30%' } }, [
        //       h('div', { style: { fontWeight: 'bold', marginBottom: '5px' } }, '物料编码'),
        //       h('div', null, detailList[0].materialCode)
        //     ]),
        //     h('div', { style: { textAlign: 'center', padding: '10px', border: '1px solid #eee', width: '30%' } }, [
        //       h('div', { style: { fontWeight: 'bold', marginBottom: '5px' } }, '物料名称'),
        //       h('div', null, detailList[0].materialName)
        //     ])
        //   ])
          h('div', { style: { border: '1px solid #000', padding: '15px' ,position:'relative',height:'280px'} }, [
            h('div', { style: { textAlign: 'center', fontSize: '18px', fontWeight: 'bold', marginTop: '20px' ,marginRight:'100px'} }, '卓力能物料标识卡(小包)'),
            h('div', { style: { display: 'flex', flexWrap: 'wrap', justifyContent: 'space-between', gap: '10px',marginTop:'60px'} }, [
              h('div', { style: { width: '48%' } }, `料号:${materielCode}`),
              h('div', { style: { width: '48%' } }, '供应商编码:'),
              h('div', { style: { width: '48%' } }, `品名:${materialName || '无'}`),
              h('div', { style: { width: '48%' } }, '采购单号:'),
              h('div', { style: { width: '48%' } }, `规格:${specification || '无'}`),
              h('div', { style: { width: '48%' } }, '数量/总数:0PCS/0PCS'),
              h('div', { style: { width: '48%' } }, `批号:${lotNo || '无'}`),
              h('div', { style: { width: '48%' } }, `批次:${batchNo || '无'}`),
              h('div', { style: { width: '48%' } }, '厂区:卓力能三厂'),
              h('div', { style: { width: '48%' } }, `日期:${date || '无'}`),
            ]),
            h('div', { style: { position:'absolute',top:'1px',right:'15px',width:'100px',heigth:'100px' } }, [
              h(ElImage, {
                src: qrCodeUrl,
                alt: '物料二维码',
                style: { width: '100px', height: '100px' }
              })
            ])
          ])
        ])
      ],
      footer: () => h('div', null, [
@@ -237,18 +210,16 @@
          type: 'default',
          onClick: () => {
            const printStyle = document.getElementById('qr-print-style');
            if (printStyle) document.head.removeChild(printStyle);
            printStyle && document.head.removeChild(printStyle);
            render(null, mountNode);
            if (mountNode.parentNode === document.body) {
              document.body.removeChild(mountNode);
            }
            document.body.removeChild(mountNode);
          }
        }, '关闭'),
        h(ElButton, {
          type: 'primary',
          onClick: () => {
            ElMessageBox.confirm(
              '是否打印该内容?',
              '是否打印该物料标识卡?',
              '打印确认',
              {
                confirmButtonText: '确认打印',
@@ -257,21 +228,16 @@
              }
            ).then(async () => {
              try {
                // æ‰§è¡Œæ‰“印并等待完成,捕获可能的错误
                await printQrCode(); 
                setTimeout(() => {
                  render(null, mountNode);
                  if (mountNode.parentNode === document.body) {
                    document.body.removeChild(mountNode);
                  }
                  document.body.removeChild(mountNode);
                }, 500);
              } catch (printErr) {
                // æ˜¾ç¤ºçœŸå®žé”™è¯¯ï¼ˆè€Œéžâ€œå·²å–消”)
                ElMessage.error(`打印失败:${printErr.message || '未知错误'}`);
                console.error('打印错误:', printErr);
              }
            }).catch((err) => {
              // ä»…用户主动取消时才显示“已取消”
              if (err === 'cancel' || err.name === 'CanceledError') {
                ElMessage.info('已取消打印');
              }