отдельной страницей вывел готовый 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:
@@ -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>
|
||||
@@ -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 || 'Неизвестная ошибка'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user