Files
hereconnect/src/views/ManageQRCodeReadyView.vue
T

156 lines
4.9 KiB
Vue
Raw Normal View History

<template>
2024-11-19 15:50:15 +02:00
<div class="flex flex-col min-h-screen">
<main class="flex-grow flex items-center justify-center py-6 px-4 md:px-6">
2024-11-19 18:49:12 +02:00
<section class="max-w-prose w-full flex flex-col gap-1">
2024-11-19 15:50:15 +02:00
<h2 class="text-xl font-semibold mb-4">Ваш QRкод готов</h2>
<p class="text-gray-600 mb-4">Сохраните его и ознакомьтесь с инструкциями по размещению.</p>
2024-11-19 15:50:15 +02:00
<!-- Рендер QRкода -->
2024-11-19 18:49:12 +02:00
<div v-if="!svgQueryIsLoading && svgQueryData" class="border p-4 bg-white rounded-lg mb-6">
<img :src="svgQueryData" alt="QR‑код" />
2024-11-19 15:50:15 +02:00
</div>
2024-11-19 15:50:15 +02:00
<!-- Сообщение об ошибке -->
2024-11-19 18:49:12 +02:00
<p v-if="qrCodeQueryIsError" class="text-red-500 mt-4">
Ошибка загрузки данных QRкода: {{ qrCodeQueryError!.message }}
</p>
<p v-if="svgQueryIsLoading" class="text-gray-500 mt-4">Загрузка...</p>
2024-11-19 15:50:15 +02:00
<!-- Кнопки для скачивания -->
2024-11-19 18:49:12 +02:00
<div
v-if="!svgQueryIsLoading && !qrCodeQueryIsError && svgQueryData"
class="flex flex-row gap-4 justify-center"
>
2024-11-19 15:50:15 +02:00
<Button
label="Скачать SVG"
icon="pi pi-download"
class="p-button-sm"
2024-11-19 18:49:12 +02:00
:href="svgQueryData"
2024-11-19 15:50:15 +02:00
:download="`${sanitizedFileName}.svg`"
as="a"
/>
<Button
label="Скачать PNG"
icon="pi pi-download"
class="p-button-sm p-button-outlined"
@click="downloadPng"
/>
</div>
2024-11-19 18:49:12 +02:00
<!-- Инструкции по размещению -->
<ManagePlacementInstructions
:placement="qrCodeDoc?.placement"
v-if="qrCodeDoc?.placement"
/>
2024-11-19 15:50:15 +02:00
</section>
</main>
<footer class="bg-gray-100 text-center py-4 border-t text-sm text-gray-700">
<p>
Нужен еще один?
<a href="/create" class="underline">Создайте QRкод</a>.
</p>
<p class="mt-1">
Сделайте НаСвязи удобнее. Будем рады вашей&nbsp;<a href="/donate" class="underline"
>поддержке</a
>.
</p>
</footer>
</div>
</template>
<script setup lang="ts">
2024-11-19 18:49:12 +02:00
import { computed } from 'vue'
import { useQuery } from '@tanstack/vue-query'
import QRCodeStyling from 'qr-code-styling'
import { optimize } from 'svgo'
2024-11-19 18:49:12 +02:00
import { getQrCodeDocument } from '@/api/qrCode'
import { type QRCodeDocument } from '@/types/DBDocumentTypes'
const { qr_code_uri } = defineProps<{ qr_code_uri: QRCodeDocument['uri'] }>()
2024-11-19 18:49:12 +02:00
// Хук для загрузки данных QR‑кода
const {
data: qrCodeDoc,
isError: qrCodeQueryIsError,
error: qrCodeQueryError,
} = useQuery({
queryKey: ['qrCode', computed(() => qr_code_uri)],
queryFn: () => getQrCodeDocument(qr_code_uri),
})
// Инициализация QRCodeStyling
const qrCode = new QRCodeStyling({
width: 256 * 4,
height: 256 * 4,
data: '',
type: 'svg',
backgroundOptions: {
color: '#ffffff',
},
})
2024-11-19 18:49:12 +02:00
// Получение имени файла
const sanitizedFileName = computed(() => {
const sanitized = qrCodeDoc.value?.name
?.replace(/[<>:"/\\|?*\x00-\x1F]/g, '') // Убираем запрещённые символы
.replace(/\s+/g, '_') // Заменяем пробелы на подчёркивания
.trim()
return sanitized ? `${sanitized}_QR-Code_HereConnect` : 'QR-Code_HereConnect'
})
// Хук для генерации и оптимизации SVG
const {
isLoading: svgQueryIsLoading,
data: svgQueryData,
error: svgQueryError,
} = useQuery({
queryKey: ['svg', computed(() => qr_code_uri)],
enabled: computed(() => !!qrCodeDoc.value?.url),
queryFn: async () => {
qrCode.update({ data: qrCodeDoc.value!.url })
const blob = await qrCode.getRawData('svg')
if (blob && blob instanceof 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) {
2024-11-19 18:49:12 +02:00
return URL.createObjectURL(new Blob([optimizedSvg.data], { type: 'image/svg+xml' }))
} else {
throw new Error('Ошибка оптимизации SVG')
}
} else {
throw new Error('Ошибка генерации QR‑кода')
}
2024-11-19 18:49:12 +02:00
},
onSettled(data) {
if (!data && svgQueryError) {
console.error('Ошибка загрузки SVG:', svgQueryError.message)
}
},
})
// Скачивание PNG
async function downloadPng() {
try {
await qrCode.download({
name: sanitizedFileName.value,
extension: 'png',
})
} catch (err) {
2024-11-19 18:49:12 +02:00
console.error('Ошибка скачивания PNG:', err)
}
}
</script>