отдельной страницей вывел готовый qr-код /manage/:qr_code_uri/view
Main daploy / deploy (push) Successful in 38s
Main daploy / deploy (push) Successful in 38s
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
<template>
|
||||
<div class="max-w-lg mx-auto py-6 px-4 md:px-6">
|
||||
<section class="content text-center">
|
||||
<h2 class="text-xl font-semibold mb-4">Ваш QR-код готов</h2>
|
||||
<p class="text-gray-600 mb-4">Сохраните его и ознакомьтесь с инструкциями по размещению.</p>
|
||||
|
||||
<!-- Рендер QR-кода -->
|
||||
<div v-if="!loading && svgUrl" class="border p-4 bg-white rounded-lg mb-6">
|
||||
<img :src="svgUrl" alt="QR-код" />
|
||||
</div>
|
||||
|
||||
<!-- Сообщение об ошибке -->
|
||||
<p v-if="error" class="text-red-500 mt-4">{{ error }}</p>
|
||||
<p v-if="loading" class="text-gray-500 mt-4">Загрузка...</p>
|
||||
|
||||
<!-- Кнопки для скачивания -->
|
||||
<div v-if="!loading && !error" class="flex flex-row gap-4 justify-center">
|
||||
<Button
|
||||
v-if="svgUrl"
|
||||
label="Скачать SVG"
|
||||
icon="pi pi-download"
|
||||
class="p-button-sm"
|
||||
:href="svgUrl"
|
||||
:download="`${sanitizedFileName}.svg`"
|
||||
as="a"
|
||||
/>
|
||||
<Button
|
||||
label="Скачать PNG"
|
||||
icon="pi pi-download"
|
||||
class="p-button-sm p-button-outlined"
|
||||
@click="downloadPng"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import QRCodeStyling from 'qr-code-styling'
|
||||
import { getQrCodeDocument } from '@/api/qrCode'
|
||||
import { optimize } from 'svgo'
|
||||
|
||||
// Получаем параметры маршрута
|
||||
const route = useRoute()
|
||||
const { qr_code_uri } = route.params as { qr_code_uri: string }
|
||||
|
||||
// Локальные состояния
|
||||
const loading = ref(true)
|
||||
const error = ref<string | null>(null)
|
||||
const qrCodeData = ref<null | { name: string; url: string }>(null)
|
||||
const svgUrl = ref<string | null>(null)
|
||||
|
||||
// Получение имени файла
|
||||
const sanitizedFileName = computed(() => {
|
||||
const sanitized = qrCodeData.value?.name.replace(/[^a-zA-Z0-9-_]/g, '').trim()
|
||||
return sanitized ? `${sanitized}_QR-Code_HereConnect` : 'QR-Code_HereConnect'
|
||||
})
|
||||
|
||||
// Инициализация QRCodeStyling
|
||||
const qrCode = new QRCodeStyling({
|
||||
width: 256 * 4,
|
||||
height: 256 * 4,
|
||||
data: '',
|
||||
type: 'svg',
|
||||
backgroundOptions: {
|
||||
color: '#ffffff',
|
||||
},
|
||||
})
|
||||
|
||||
// Генерация и оптимизация SVG
|
||||
async function generateOptimizedSvg(url: string) {
|
||||
try {
|
||||
qrCode.update({ data: 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) {
|
||||
svgUrl.value = URL.createObjectURL(new Blob([optimizedSvg.data], { type: 'image/svg+xml' }))
|
||||
} else {
|
||||
throw new Error('Ошибка оптимизации SVG')
|
||||
}
|
||||
} else {
|
||||
throw new Error('Ошибка генерации QR-кода')
|
||||
}
|
||||
} catch (err) {
|
||||
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(async () => {
|
||||
try {
|
||||
// Загружаем данные QR-кода
|
||||
const doc = await getQrCodeDocument(qr_code_uri)
|
||||
qrCodeData.value = { name: doc.name, url: doc.url }
|
||||
await generateOptimizedSvg(doc.url)
|
||||
} catch (err) {
|
||||
error.value = (err as Error).message || 'Ошибка загрузки данных QR-кода'
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
|
||||
// Очистка ресурсов при размонтировании
|
||||
onUnmounted(() => {
|
||||
if (svgUrl.value) {
|
||||
URL.revokeObjectURL(svgUrl.value)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
Reference in New Issue
Block a user