отдельной страницей вывел готовый qr-код /manage/:qr_code_uri/view
Main daploy / deploy (push) Successful in 38s

This commit is contained in:
2024-11-18 23:28:33 +02:00
parent 6b87a2ca87
commit fe4317982f
11 changed files with 264 additions and 272 deletions
@@ -1,118 +0,0 @@
<template>
<section>
<h2 class="text-xl font-semibold mb-4">Ваш QR-код готов</h2>
<p class="text-gray-600 mb-4">Сохраните его и ознакомьтесь с инструкциями по размещению.</p>
<!-- Рендер QR-кода -->
<div class="border p-4 bg-white rounded-lg mb-6" v-if="svgUrl">
<img :src="svgUrl" alt="QR-код" />
</div>
<!-- Кнопки для скачивания -->
<div class="flex flex-col md:flex-row gap-4 justify-center">
<!-- Основная кнопка для скачивания SVG -->
<Button
v-if="svgUrl"
label="Скачать SVG"
icon="pi pi-download"
class="p-button-sm"
:href="svgUrl"
:download="`${sanitizedFileName}.svg`"
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>
</section>
</template>
<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 ? `${sanitized}_QR-Code_HereConnect` : 'QR-Code_HereConnect'
})
const error = ref<string | null>(null)
const svgUrl = ref<string | null>(null)
// Инициализация QRCodeStyling
const qrCode = new QRCodeStyling({
width: 256 * 4,
height: 256 * 4,
data: qrCodeUrl,
type: 'svg',
backgroundOptions: {
color: '#ffffff',
},
})
// Генерация и оптимизация SVG
async function generateOptimizedSvg() {
try {
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 {
error.value = 'Ошибка оптимизации SVG'
}
} else {
error.value = 'Ошибка генерации 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(() => {
generateOptimizedSvg()
})
// Очистка ресурсов при размонтировании
onUnmounted(() => {
if (svgUrl.value) {
URL.revokeObjectURL(svgUrl.value)
}
})
</script>
+13 -24
View File
@@ -5,14 +5,14 @@
<form @submit.prevent="saveQRCode">
<label for="name" class="block text-gray-700 font-semibold mb-2">Название</label>
<InputText id="name" v-model="nameModel" class="w-full" placeholder="Введите название" />
<p v-if="!nameModel" class="text-red-500 text-sm mt-1">Название обязательно.</p>
<InputText id="name" v-model="name" class="w-full" placeholder="Введите название" />
<p v-if="!name" class="text-red-500 text-sm mt-1">Название обязательно.</p>
<Button
type="submit"
label="Создать QR-код"
class="p-button-md mt-4 mb-4"
:disabled="!nameModel"
:disabled="!name"
/>
</form>
<p v-if="error" class="text-red-500 mt-4">Ошибка создания QR-кода: {{ error }}</p>
@@ -21,8 +21,11 @@
<script setup lang="ts">
import { ref } from 'vue'
import { qrCodeDb } from '@/dbs'
import { useRouter } from 'vue-router'
import { type QRCodeDocument } from '@/types/DBDocumentTypes'
import { createQrCodeDocument } from '@/api/qrCode'
const router = useRouter()
const { placement, actions, deliveryMethod, user_uuid, predefinedMessage } = defineProps<{
placement: QRCodeDocument['placement']
@@ -32,37 +35,23 @@ const { placement, actions, deliveryMethod, user_uuid, predefinedMessage } = def
predefinedMessage: QRCodeDocument['predefinedMessage'] | undefined
}>()
const uriModel = defineModel<QRCodeDocument['uri']>('uri', { required: true })
const nameModel = defineModel<QRCodeDocument['name']>('name', { required: true })
const emit = defineEmits(['nextStep'])
const name = ref<QRCodeDocument['name']>('')
const error = ref<string | null>(null)
async function saveQRCode() {
try {
// Генерация уникального uri
const EPOHE = 1731661630981
const uri = Math.abs(Date.now() - EPOHE).toString(36)
const qrCodeDoc: QRCodeDocument = {
_id: `qr_code:${uri}`,
type: 'qr_code',
uri,
url: `https://hereconnect.condev.ru/read/${uri}`,
name: nameModel.value,
const qrCodeDocument = await createQrCodeDocument({
name: name.value,
deliveryMethod,
created_at: new Date().toISOString(),
placement,
actions,
user_uuid,
predefinedMessage,
}
})
await qrCodeDb.put(qrCodeDoc)
uriModel.value = uri
error.value = null
emit('nextStep')
// Перенаправление на страницу /manage/:qr/ready
await router.push({ name: 'ManageQRCodeReady', params: { qr_code_uri: qrCodeDocument.uri } })
} catch (err) {
error.value = (err as Error).message || 'Неизвестная ошибка'
}