|
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 {
|
border: 1px solid #000;
|
padding: 5mm; /* 使用毫米单位更适配打印尺寸 */
|
font-size: 2mm; /* 按比例缩小字体 */
|
position: relative;
|
width: 70mm; /* 略小于纸张宽度,留边距 */
|
height: 50mm; /* 略小于纸张高度,留边距 */
|
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 = `
|
<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="qr-wrapper">
|
<img src="${qrCodeUrl}" alt="物料二维码" />
|
</div>
|
</div>
|
`;
|
|
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;
|