feat:

修改二维码生成逻辑,改为一次性二维码,存储更多信息
This commit is contained in:
砂糖
2025-08-22 11:30:23 +08:00
parent 4301301312
commit 3c694130c2
8 changed files with 711 additions and 47 deletions

View File

@@ -1,4 +1,4 @@
import QRCode from 'qrcode';
/**
* 通用js方法封装处理
@@ -231,3 +231,117 @@ export function tansParams(params) {
export function blobValidate(data) {
return data.type !== 'application/json'
}
/**
* 保存二维码为图片
* @param {string} code 二维码内容
* @param {string} text 下方文字
* @param {number} index 索引,用于生成文件名
* @param {Object} context Vue组件实例上下文需要包含$message、barcodeWidth、barcodeHeight
*/
export async function saveAsImage(code, text, index, context) {
// 确保上下文存在
if (!context) {
console.error('缺少组件上下文请传入Vue实例');
return;
}
try {
// 检查QRCode库是否加载
if (typeof QRCode === 'undefined') {
throw new Error('QRCode库未加载请确保已引入');
}
// 创建临时canvas用于绘制二维码和文字
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
if (!ctx) {
throw new Error('无法获取canvas上下文');
}
// 从上下文获取尺寸参数,提供默认值
const barcodeWidth = context.barcodeWidth || 200;
const barcodeHeight = context.barcodeHeight || 200;
const textHeight = 30; // 文字区域高度
canvas.width = barcodeWidth;
canvas.height = barcodeHeight + textHeight;
// 绘制二维码
const qrCanvas = document.createElement('canvas');
qrCanvas.width = barcodeWidth;
qrCanvas.height = barcodeHeight;
// 等待二维码绘制完成
await new Promise((resolve, reject) => {
QRCode.toCanvas(qrCanvas, code, {
width: barcodeWidth,
height: barcodeHeight,
margin: 0,
errorCorrectionLevel: 'M'
}, (error) => {
if (error) reject(error);
else resolve();
});
});
// 将二维码绘制到主canvas
ctx.drawImage(qrCanvas, 0, 0);
// 绘制文字(处理文字过长情况)
ctx.fillStyle = '#000';
ctx.font = '14px Arial, sans-serif';
ctx.textAlign = 'center';
ctx.textBaseline = 'top';
// 处理过长文字最多显示2行
const maxTextWidth = barcodeWidth - 20; // 预留边距
let displayText = text;
if (ctx.measureText(text).width > maxTextWidth) {
// 尝试截断并添加省略号
let i = text.length;
while (ctx.measureText(text.substring(0, i)).width > maxTextWidth && i > 0) {
i--;
}
displayText = text.substring(0, i) + '...';
}
ctx.fillText(displayText, barcodeWidth / 2, barcodeHeight + 5);
// 创建图片链接并下载
canvas.toBlob(blob => {
if (!blob) {
throw new Error('无法生成图片blob对象');
}
try {
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
// 处理文件名特殊字符
a.download = `二维码_${index + 1}.png`;
a.href = url;
// 模拟点击下载
document.body.appendChild(a);
const event = new MouseEvent('click');
a.dispatchEvent(event);
// 清理资源
setTimeout(() => {
document.body.removeChild(a);
URL.revokeObjectURL(url);
}, 100);
context.$message.success('图片保存成功');
} catch (urlError) {
console.error('创建下载链接失败:', urlError);
context.$message.error('创建下载链接失败');
}
}, 'image/png'); // 明确指定MIME类型
} catch (error) {
console.error('保存图片失败:', error);
context.$message.error(`保存图片失败: ${error.message || '未知错误'}`);
}
}