153 lines
4.0 KiB
Vue
153 lines
4.0 KiB
Vue
<script lang="ts" setup>
|
||
/**
|
||
* 诊所/药店二维码预览弹窗
|
||
* 按门店 type(0 诊所 / 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>
|