@@ -10,15 +10,24 @@
|
||||
|
||||
<!-- Кнопки для скачивания -->
|
||||
<div class="flex flex-col md:flex-row gap-4 justify-center">
|
||||
<a
|
||||
<!-- Основная кнопка для скачивания SVG -->
|
||||
<Button
|
||||
v-if="svgUrl"
|
||||
label="Скачать SVG"
|
||||
icon="pi pi-download"
|
||||
class="p-button-sm"
|
||||
:href="svgUrl"
|
||||
:download="`${sanitizedFileName}.svg`"
|
||||
class="p-button p-button-sm p-button-outlined text-center"
|
||||
>
|
||||
Скачать SVG
|
||||
</a>
|
||||
<Button label="Скачать PNG" icon="pi pi-download" class="p-button-sm" @click="downloadPng" />
|
||||
as="a"
|
||||
/>
|
||||
|
||||
<!-- Кнопка для скачивания PNG с outlined стилем -->
|
||||
<Button
|
||||
label="Скачать PNG"
|
||||
icon="pi pi-download"
|
||||
class="p-button-sm p-button-outlined"
|
||||
@click="downloadPng"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<p v-if="error" class="text-red-500 mt-4">Ошибка: {{ error }}</p>
|
||||
@@ -28,14 +37,14 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||||
import QRCodeStyling from 'qr-code-styling'
|
||||
import { optimize } from 'svgo'
|
||||
|
||||
// Пропсы
|
||||
const { uri, name } = defineProps<{ uri: string; name: string }>()
|
||||
|
||||
const qrCodeUrl = `https://hereconnect.condev.ru/read/${uri}`
|
||||
const sanitizedFileName = computed(() => {
|
||||
const sanitized = name.replace(/[^a-zA-Z0-9-_]/g, '').trim()
|
||||
return sanitized || 'qr-code'
|
||||
return sanitized ? `${sanitized}_QR-Code_HereConnect` : 'QR-Code_HereConnect'
|
||||
})
|
||||
|
||||
const error = ref<string | null>(null)
|
||||
@@ -47,45 +56,63 @@ const qrCode = new QRCodeStyling({
|
||||
height: 256 * 4,
|
||||
data: qrCodeUrl,
|
||||
type: 'svg',
|
||||
// dotsOptions: {
|
||||
// color: '#000',
|
||||
// type: 'rounded',
|
||||
// },
|
||||
backgroundOptions: {
|
||||
color: '#ffffff',
|
||||
},
|
||||
})
|
||||
|
||||
// Генерация SVG и отображение QR-кода
|
||||
onMounted(async () => {
|
||||
// Генерация и оптимизация SVG
|
||||
async function generateOptimizedSvg() {
|
||||
try {
|
||||
const blob = await qrCode.getRawData('svg')
|
||||
if (blob && blob instanceof Blob) {
|
||||
svgUrl.value = URL.createObjectURL(blob)
|
||||
const text = await blob.text()
|
||||
|
||||
const optimizedSvg = optimize(text, {
|
||||
plugins: [
|
||||
{ name: 'removeDoctype' },
|
||||
{ name: 'removeComments' },
|
||||
{ name: 'removeDimensions' },
|
||||
{ name: 'convertShapeToPath' },
|
||||
{ name: 'convertPathData' },
|
||||
{ name: 'mergePaths' },
|
||||
],
|
||||
})
|
||||
|
||||
if (optimizedSvg.data) {
|
||||
svgUrl.value = URL.createObjectURL(new Blob([optimizedSvg.data], { type: 'image/svg+xml' }))
|
||||
} else {
|
||||
error.value = 'Ошибка оптимизации SVG'
|
||||
}
|
||||
} else {
|
||||
error.value = 'Ошибка генерации QR-кода'
|
||||
}
|
||||
} catch (err) {
|
||||
error.value = (err as Error).message
|
||||
error.value = (err as Error).message || 'Неизвестная ошибка'
|
||||
}
|
||||
}
|
||||
|
||||
// Скачивание PNG
|
||||
async function downloadPng() {
|
||||
try {
|
||||
await qrCode.download({
|
||||
name: sanitizedFileName.value,
|
||||
extension: 'png',
|
||||
})
|
||||
} catch (err) {
|
||||
error.value = (err as Error).message || 'Ошибка при скачивании QR-кода'
|
||||
}
|
||||
}
|
||||
|
||||
// Монтирование
|
||||
onMounted(() => {
|
||||
generateOptimizedSvg()
|
||||
})
|
||||
|
||||
// Очистка ресурсов при размонтировании
|
||||
onUnmounted(() => {
|
||||
if (svgUrl.value) {
|
||||
URL.revokeObjectURL(svgUrl.value)
|
||||
}
|
||||
})
|
||||
|
||||
// Скачивание PNG
|
||||
async function downloadPng() {
|
||||
try {
|
||||
const blob = await qrCode.getRawData('png') // Получение PNG в формате Blob
|
||||
const link = document.createElement('a')
|
||||
link.href = URL.createObjectURL(blob)
|
||||
link.download = `${sanitizedFileName.value}.png`
|
||||
link.click()
|
||||
} catch (err) {
|
||||
error.value = (err as Error).message || 'Ошибка при скачивании QR-кода'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -16,6 +16,7 @@ watch(
|
||||
() => props.isActive,
|
||||
(isActive) => {
|
||||
if (isActive) {
|
||||
sectionRef.value?.querySelector('input')?.focus()
|
||||
sectionRef.value?.scrollIntoView({ behavior: 'smooth' })
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user