2025-04-10 17:08:23 +08:00
|
|
|
|
<script lang="ts" setup>
|
|
|
|
|
|
import { ref } from 'vue';
|
|
|
|
|
|
|
|
|
|
|
|
import { useVbenModal } from '@vben/common-ui';
|
|
|
|
|
|
|
|
|
|
|
|
import { Avatar, Button, Image } from 'ant-design-vue';
|
|
|
|
|
|
import html2canvas from 'html2canvas';
|
|
|
|
|
|
|
|
|
|
|
|
import { getDoctorInfoByStoreApi } from '#/views/doctor/doctor/api';
|
|
|
|
|
|
|
|
|
|
|
|
const qrCodeUrl = ref('');
|
|
|
|
|
|
const htmlToImage = ref('');
|
|
|
|
|
|
const previewAddress = ref('');
|
|
|
|
|
|
const goodAt = ref('');
|
|
|
|
|
|
const doctorInfo = ref();
|
|
|
|
|
|
const doctorId = ref(0);
|
|
|
|
|
|
const storeId = ref(0);
|
|
|
|
|
|
const [Modal, modalApi] = useVbenModal({
|
|
|
|
|
|
fullscreenButton: false,
|
|
|
|
|
|
footer: false,
|
|
|
|
|
|
showCancelButton: true,
|
|
|
|
|
|
showConfirmButton: true,
|
|
|
|
|
|
confirmText: '保存医生卡片图片',
|
|
|
|
|
|
cancelText: '保存医生二维码图片',
|
|
|
|
|
|
draggable: true,
|
|
|
|
|
|
onCancel() {
|
|
|
|
|
|
doctorInfo.value = null;
|
|
|
|
|
|
modalApi.close();
|
|
|
|
|
|
},
|
|
|
|
|
|
onConfirm: async () => {
|
|
|
|
|
|
doctorInfo.value = null;
|
|
|
|
|
|
modalApi.close();
|
|
|
|
|
|
},
|
|
|
|
|
|
onOpenChange(isOpen: boolean) {
|
2025-04-14 16:58:16 +08:00
|
|
|
|
modalApi.setState({
|
|
|
|
|
|
loading: true,
|
|
|
|
|
|
});
|
2025-04-10 17:08:23 +08:00
|
|
|
|
if (isOpen) {
|
|
|
|
|
|
const { values } = modalApi.getData<Record<string, any>>();
|
|
|
|
|
|
if (values) {
|
|
|
|
|
|
if (values.doctor_id !== undefined) {
|
|
|
|
|
|
doctorId.value = values.doctor_id;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (values.store_id !== undefined) {
|
|
|
|
|
|
storeId.value = values.store_id;
|
|
|
|
|
|
}
|
|
|
|
|
|
getDoctorInfoByStore();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const getDoctorInfoByStore = () => {
|
|
|
|
|
|
getDoctorInfoByStoreApi({
|
|
|
|
|
|
doctor_id: doctorId.value,
|
|
|
|
|
|
store_id: storeId.value,
|
|
|
|
|
|
}).then((res) => {
|
|
|
|
|
|
doctorInfo.value = res;
|
|
|
|
|
|
goodAt.value = res.doctor.good_at;
|
|
|
|
|
|
previewAddress.value =
|
|
|
|
|
|
res.store.province.name + res.store.city.name + res.store.position;
|
2025-04-14 16:58:16 +08:00
|
|
|
|
|
|
|
|
|
|
modalApi.setState({
|
|
|
|
|
|
loading: false,
|
|
|
|
|
|
});
|
2025-04-10 17:08:23 +08:00
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 下载二维码
|
|
|
|
|
|
* @param name
|
|
|
|
|
|
* @param isQr
|
|
|
|
|
|
*/
|
|
|
|
|
|
const downloadQRCode = async (name: string, isQr = false) => {
|
|
|
|
|
|
const element = isQr ? qrCodeUrl.value : htmlToImage.value;
|
|
|
|
|
|
html2canvas(element, {
|
|
|
|
|
|
useCORS: true,
|
|
|
|
|
|
allowTaint: true,
|
|
|
|
|
|
logging: false,
|
|
|
|
|
|
}).then((canvas) => {
|
|
|
|
|
|
// 创建a标签下载
|
|
|
|
|
|
const link = document.createElement('a'); // 创建a标签
|
|
|
|
|
|
link.href = canvas.toDataURL(); // 是canvas对象的一种方法,用于将canvas对象转换为base64位编码
|
|
|
|
|
|
link.setAttribute('download', `${doctorInfo.value.doctor.name}${name}.png`); // 利用了a标签的download 来下载 canvas图片
|
|
|
|
|
|
link.style.display = 'none'; // 将图片隐藏起来
|
|
|
|
|
|
document.body.append(link); // 插入到其中
|
|
|
|
|
|
link.click();
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
|
|
|
<Modal v-if="doctorInfo" title="医生二维码" class="w-[50%]">
|
|
|
|
|
|
<template #footer>
|
|
|
|
|
|
<Button type="primary" @click="downloadQRCode('二维码卡片下载')">
|
|
|
|
|
|
二维码卡片下载
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
<Button type="primary" @click="downloadQRCode('二维码下载', true)">
|
|
|
|
|
|
二维码下载
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<div class="qrBox" style="text-align: center">
|
|
|
|
|
|
<div ref="htmlToImage" class="qrModal">
|
|
|
|
|
|
<div id="qrcode" ref="qrCodeUrl" class="qrcode">
|
|
|
|
|
|
<Avatar :src="doctorInfo.doctor.avatar" />
|
|
|
|
|
|
<div class="qrTitle">
|
|
|
|
|
|
{{ doctorInfo.doctor.name }} {{ doctorInfo.doctor.title.name }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="qrAddress">
|
2026-08-07 13:17:07 +08:00
|
|
|
|
<span class="addressTitle">{{
|
|
|
|
|
|
Number(doctorInfo?.store?.type) === 1 ? '药店地址:' : '诊所地址:'
|
|
|
|
|
|
}}</span>{{ previewAddress }}
|
2025-04-10 17:08:23 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<Image :preview="false" :src="doctorInfo.qr_code" class="mt-3" height="30" width="30" />
|
|
|
|
|
|
<h3 class="border-l-4 border-blue-500 pl-3 text-lg font-semibold">
|
|
|
|
|
|
擅长领域
|
|
|
|
|
|
</h3>
|
|
|
|
|
|
<div
|
|
|
|
|
|
class="prose max-w-none whitespace-pre-wrap"
|
|
|
|
|
|
style="text-indent: 2em"
|
|
|
|
|
|
>
|
|
|
|
|
|
{{ doctorInfo.doctor.good_at }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</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 {
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.qrAddress {
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
margin-top: 10px;
|
|
|
|
|
|
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>
|