Files
xk-admin/apps/web-antd/src/components/modal/QrCodePreview.vue

153 lines
4.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script lang="ts" setup>
/**
* 诊所/药店二维码预览弹窗
* 按门店 type0 诊所 / 1 药店)切换「诊所|药店」文案,列表页与门店卡片共用
*/
import { computed, ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { Button, Image } from 'ant-design-vue';
import html2canvas from 'html2canvas';
const qrCodeUrl = ref('');
const htmlToImage = ref('');
const url = ref('');
const previewTitle = ref('二维码');
const previewAddress = ref('');
/** 门店类型0=诊所 1=药店,未传时按诊所示 */
const storeType = ref(0);
const isPharmacy = computed(() => Number(storeType.value) === 1);
const kindLabel = computed(() => (isPharmacy.value ? '药店' : '诊所'));
const addressLabel = computed(() => `${kindLabel.value}地址:`);
const [Modal, modalApi] = useVbenModal({
fullscreenButton: false,
footer: false,
header: false,
showCancelButton: true,
showConfirmButton: true,
confirmText: '保存诊所卡片图片',
cancelText: '保存诊所二维码图片',
draggable: true,
onCancel() {
modalApi.close();
},
onConfirm: async () => {
modalApi.close();
},
onOpenChange(isOpen: boolean) {
if (isOpen) {
const { values, title, address, type, store_type } =
modalApi.getData<Record<string, any>>() || {};
if (values) {
url.value = values;
qrCodeUrl.value = values;
previewTitle.value = title;
previewAddress.value = address;
// 兼容 type / store_type 两种传参
storeType.value = Number(type ?? store_type ?? 0);
modalApi.setState({
confirmText: `保存${kindLabel.value}卡片图片`,
cancelText: `保存${kindLabel.value}二维码图片`,
});
}
}
},
});
/**
* 下载二维码卡片或纯二维码图片
* @param name 文件名后缀
* @param isQr true=只截二维码区域false=截整张卡片
*/
const downloadQRCode = async (name: string, isQr = false) => {
const element = isQr ? qrCodeUrl.value : htmlToImage.value;
html2canvas(element, {
useCORS: true,
allowTaint: true,
logging: false,
}).then((canvas) => {
const link = document.createElement('a');
link.href = canvas.toDataURL();
link.setAttribute('download', `${previewTitle.value}${name}.png`);
link.style.display = 'none';
document.body.append(link);
link.click();
});
};
</script>
<template>
<Modal :title="`${previewTitle}二维码`">
<div class="qrBox" style="text-align: center">
<div ref="htmlToImage" class="qrModal">
<div id="qrcode" ref="qrCodeUrl" class="qrcode">
<div class="qrTitle">{{ previewTitle }}</div>
<Image :preview="false" :src="url" height="30" width="30" />
<div class="qrAddress">
<span class="addressTitle">{{ addressLabel }}</span>{{ previewAddress }}
</div>
</div>
</div>
<Button
style="margin: 20px auto"
type="primary"
@click="downloadQRCode('二维码卡片下载')"
>
二维码卡片下载
</Button>
<Button
style="margin: 20px auto 20px 20px"
type="primary"
@click="downloadQRCode('二维码下载', true)"
>
二维码下载
</Button>
</div>
</Modal>
</template>
<style lang="scss" scoped>
.qrModal {
// 宽度适应文本长度
margin: 0 auto;
text-align: center;
background: radial-gradient(
circle at center,
rgba(173, 216, 230, 0.8),
rgba(135, 206, 235, 0.8),
rgba(100, 149, 237, 0.8)
);
padding: 20px 30px;
.qrTitle {
font-size: 20px;
margin-bottom: 30px;
color: #333;
font-weight: bold;
}
.qrAddress {
font-size: 12px;
margin-top: 30px;
color: #333;
font-weight: bold;
}
.addressTitle {
color: #3a8ee6;
}
.qrcode {
width: fit-content;
//width: 50%;
margin: 0 auto;
text-align: center;
padding: 20px 30px;
background-color: #fff;
border-radius: 20px;
}
}
</style>