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;