护理区域生成二维码功能
This commit is contained in:
parent
45a0a86b2f
commit
6a34074404
|
@ -0,0 +1,104 @@
|
||||||
|
<template>
|
||||||
|
<div class="qr-code-container">
|
||||||
|
<canvas ref="qrCanvas" ></canvas>
|
||||||
|
<button @click="downloadQR">下载二维码</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import QRCode from 'qrcode';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
text: { type: String, required: true }, // 二维码内容
|
||||||
|
logoUrl: { type: String, default: '' }, // Logo 图片 URL
|
||||||
|
size: { type: Number, default: 200 }, // 二维码大小
|
||||||
|
logoSize: { type: Number, default: 20 }, // Logo 大小
|
||||||
|
margin: { type: Number, default: 1 }, // 二维码边距
|
||||||
|
});
|
||||||
|
|
||||||
|
const qrCanvas = ref(null);
|
||||||
|
|
||||||
|
// 生成带 Logo 的二维码
|
||||||
|
const generateQR = async () => {
|
||||||
|
try {
|
||||||
|
// 1. 生成基础二维码
|
||||||
|
await QRCode.toCanvas(qrCanvas.value, props.text, {
|
||||||
|
width: props.size,
|
||||||
|
margin: props.margin,
|
||||||
|
color: {
|
||||||
|
dark: '#000000', // 二维码颜色
|
||||||
|
light: '#ffffff' // 背景色
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2. 添加 Logo
|
||||||
|
if (props.logoUrl) {
|
||||||
|
const canvas = qrCanvas.value;
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
// 加载 Logo 图片
|
||||||
|
const logoImg = new Image();
|
||||||
|
logoImg.src = props.logoUrl;
|
||||||
|
logoImg.crossOrigin = 'Anonymous'; // 解决跨域问题
|
||||||
|
// 添加错误监听
|
||||||
|
logoImg.onerror = () => {
|
||||||
|
console.error('图片加载失败!请检查 URL 或跨域设置:', props.logoUrl);
|
||||||
|
};
|
||||||
|
|
||||||
|
logoImg.onload = () => {
|
||||||
|
// 计算 Logo 位置(居中)
|
||||||
|
const logoPos = (props.size - props.logoSize) / 2;
|
||||||
|
// 绘制白色背景(可选,增强 Logo 可视性)
|
||||||
|
ctx.fillStyle = '#ffffff';
|
||||||
|
ctx.fillRect(logoPos, logoPos, props.logoSize, props.logoSize);
|
||||||
|
// 绘制 Logo
|
||||||
|
ctx.drawImage(logoImg, logoPos, logoPos, props.logoSize, props.logoSize);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('生成二维码失败:', err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 下载二维码
|
||||||
|
const downloadQR = () => {
|
||||||
|
const originalCanvas = qrCanvas.value;
|
||||||
|
const scale = 4; // 放大倍数
|
||||||
|
|
||||||
|
// 创建一个新的高清 Canvas
|
||||||
|
const hdCanvas = document.createElement('canvas');
|
||||||
|
hdCanvas.width = originalCanvas.width * scale;
|
||||||
|
hdCanvas.height = originalCanvas.height * scale;
|
||||||
|
|
||||||
|
// 将原始内容放大绘制到新 Canvas
|
||||||
|
const ctx = hdCanvas.getContext('2d');
|
||||||
|
ctx.imageSmoothingEnabled = false; // 禁用抗锯齿(保持锐利)
|
||||||
|
ctx.drawImage(originalCanvas, 0, 0, hdCanvas.width, hdCanvas.height);
|
||||||
|
// ctx.drawImage(
|
||||||
|
// originalCanvas,
|
||||||
|
// 0, 0,
|
||||||
|
// originalCanvas.width, originalCanvas.height, // 源尺寸
|
||||||
|
// -280, -280,
|
||||||
|
// hdCanvas.width*2 -50, hdCanvas.height*2-50 // 目标尺寸(放大后)
|
||||||
|
// );
|
||||||
|
|
||||||
|
// 下载高清图片
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.download = props.text+'-ewm.png';
|
||||||
|
link.href = hdCanvas.toDataURL('image/png');
|
||||||
|
link.click();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 组件挂载时生成二维码
|
||||||
|
onMounted(generateQR);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.qr-code-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -30,6 +30,12 @@ export const columns: BasicColumn[] = [
|
||||||
align: "center",
|
align: "center",
|
||||||
dataIndex: 'status_dictText',
|
dataIndex: 'status_dictText',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '二维码',
|
||||||
|
align: "center",
|
||||||
|
dataIndex: 'ewm',
|
||||||
|
width:150
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
// 高级查询数据
|
// 高级查询数据
|
||||||
|
|
|
@ -68,6 +68,15 @@
|
||||||
<template v-else-if="column.key === 'nuName'">
|
<template v-else-if="column.key === 'nuName'">
|
||||||
<a @click="handleWlsb(record)">{{text}}</a>
|
<a @click="handleWlsb(record)">{{text}}</a>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-else-if="column.key === 'ewm'">
|
||||||
|
<QRCodeWithLogo
|
||||||
|
:text="record.nuId"
|
||||||
|
:logoUrl="logoUrl"
|
||||||
|
:size="150"
|
||||||
|
:logoSize="40"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
</BasicTable>
|
</BasicTable>
|
||||||
<!-- 表单区域 -->
|
<!-- 表单区域 -->
|
||||||
|
@ -93,7 +102,9 @@
|
||||||
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
|
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
|
||||||
import JSelectMultiple from '/@/components/Form/src/jeecg/components/JSelectMultiple.vue';
|
import JSelectMultiple from '/@/components/Form/src/jeecg/components/JSelectMultiple.vue';
|
||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
|
import QRCodeWithLogo from './EwmImage.vue';
|
||||||
|
|
||||||
|
const logoUrl = 'https://www.focusnu.com/devops/resource/img/logo.png'; // 替换为你的 Logo URL
|
||||||
|
|
||||||
const { createMessage } = useMessage();
|
const { createMessage } = useMessage();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue