import QRCode from 'qrcode'; // 二维码生成库 import { ElDialog, ElButton, ElMessage ,ElImage,ElMessageBox } from 'element-plus';// 引入ElMessage,解决提示无反应 import { h,createVNode, render } from 'vue'; //此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码 let extension = { components: { //查询界面扩展组件 gridHeader: '', gridBody: '', gridFooter: '', //新建、编辑弹出框扩展组件 modelHeader: '', modelBody: '', modelFooter: '' }, tableAction: '', buttons: { view: [{ name: '生成二维码', type: 'success', value: '生成二维码', onClick: async function () { // 1. 校验选中行 const selectedRows = this.$refs.table.getSelected(); if (selectedRows.length === 0) { ElMessage.warning('请先选择一行数据'); return; } if (selectedRows.length > 1) { ElMessage.warning('仅支持选择一行数据生成二维码'); return; } // 2. 获取核心物料字段(料号、品名、规格等) const { materielCode, materialName, specification, lotNo, batchNo, date } = selectedRows[0]; if (!materielCode) { ElMessage.error('选中数据缺少料号信息'); return; } // 3. 生成二维码(内容为料号,可根据需求拼接更多信息) let qrCodeUrl = ''; try { qrCodeUrl = await QRCode.toDataURL(materielCode, { width: 150, // 适配标识卡尺寸 margin: 1 }); } catch (err) { ElMessage.error('二维码生成失败,请重试'); console.error('二维码生成错误:', err); return; } // 4. 创建弹窗挂载节点 const mountNode = document.createElement('div'); document.body.appendChild(mountNode); // 打印专用样式 const addPrintStyle = () => { const style = document.createElement('style'); style.id = 'qr-print-style'; style.textContent = ` @media print { body > *:not(.print-container) { display: none !important; } .print-container { 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; } .material-card { padding: 5mm; /* 使用毫米单位更适配打印尺寸 */ font-size: 2mm; /* 按比例缩小字体 */ position: relative; width: 80mm; /* 略小于纸张宽度,留边距 */ height: 60mm; /* 略小于纸张高度,留边距 */ box-sizing: border-box; /* 确保padding不影响整体尺寸 */ } .card-title { text-align: center; font-size: 2mm; /* 标题略大 */ font-weight: bold; margin-top: 5mm; /* 减小顶部间距 */ margin-right: 20mm; /* 适配缩小的二维码位置 */ } .card-fields { display: flex; flex-wrap: wrap; justify-content: space-between; gap:1.5mm; /* 缩小间距 */ margin-top: 8mm; /* 调整字段容器位置 */ } .field-item { width: 48%; /* 保持两列布局 */ line-height: 1.3; /* 紧凑行高 */ } .qr-wrapper { position: absolute; top: 5mm; /* 调整二维码顶部位置 */ right: 3mm; /* 调整二维码右侧位置 */ width: 15mm; /* 二维码尺寸适配小卡片 */ height: 15mm; } .qr-wrapper img { width: 100% !important; /* 确保二维码填充满容器 */ height: 100% !important; object-fit: contain; } } `; document.head.appendChild(style); return style; }; // 打印函数 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 = `
卓力能物料标识卡(小包)
料号:${materielCode}
供应商编码:
品名:${materialName || '无'}
采购单号:
规格:${specification || '无'}
数量/总数:0PCS/0PCS
批号:${lotNo || '无'}
批次:${batchNo || '无'}
厂区:卓力能三厂
日期:${date || '无'}
物料二维码
`; const printStyle = addPrintStyle(); const cleanUp = () => { 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: '500px', modelValue: true, style: { maxHeight: '500px', overflowY: 'auto' }, appendToBody: true, 'onUpdate:modelValue': (isVisible) => { if (!isVisible) { const printStyle = document.getElementById('qr-print-style'); printStyle && document.head.removeChild(printStyle); render(null, mountNode); document.body.removeChild(mountNode); } } }, { default: () => [ h('div', { style: { padding: '20px' } }, [ 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, [ h(ElButton, { type: 'default', onClick: () => { const printStyle = document.getElementById('qr-print-style'); printStyle && document.head.removeChild(printStyle); render(null, mountNode); document.body.removeChild(mountNode); } }, '关闭'), h(ElButton, { type: 'primary', onClick: () => { ElMessageBox.confirm( '是否打印该物料标识卡?', '打印确认', { confirmButtonText: '确认打印', cancelButtonText: '取消', type: 'info' } ).then(async () => { try { await printQrCode(); setTimeout(() => { render(null, 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('已取消打印'); } }); } }, '打印') ]) }); vnode.appContext = this.$.appContext; render(vnode, mountNode); } }], box: [], detail: [] }, //扩展的按钮 methods: { //下面这些方法可以保留也可以删除 onInit() { }, onInited() { //框架初始化配置后 //如果要配置明细表,在此方法操作 //this.detailOptions.columns.forEach(column=>{ }); }, searchBefore(param) { //界面查询前,可以给param.wheres添加查询参数 //返回false,则不会执行查询 return true; }, searchAfter(result) { //查询后,result返回的查询数据,可以在显示到表格前处理表格的值 return true; }, addBefore(formData) { //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值 return true; }, updateBefore(formData) { //编辑保存前formData为对象,包括明细表、删除行的Id return true; }, rowClick({ row, column, event }) { //查询界面点击行事件 this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行; }, modelOpenAfter(row) { //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据 //(1)判断是编辑还是新建操作: this.currentAction=='Add'; //(2)给弹出框设置默认值 //(3)this.editFormFields.字段='xxx'; //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值 //看不懂就把输出看:console.log(this.editFormOptions) } } }; export default extension;