feat: qr code
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
<template>
|
||||
<Layout>
|
||||
<template #main>
|
||||
<div class="mb-6 text-center">
|
||||
<h1 class="text-h5 font-weight-black text-primary">公益普測與活動預約</h1>
|
||||
<p class="text-caption text-grey">報名免費體能普測,取得個人運動處方</p>
|
||||
</div>
|
||||
<v-card class="mb-6" variant="flat">
|
||||
<v-card-title class="text-primary">公益普測與活動預約</v-card-title>
|
||||
|
||||
<v-card-subtitle class="text-grey-darken-3">
|
||||
報名免費體能普測,取得個人運動處方
|
||||
</v-card-subtitle>
|
||||
</v-card>
|
||||
|
||||
<!-- 活動分類選擇 -->
|
||||
<v-tabs v-model="filterTab" class="mb-4 bg-white rounded-lg elevation-1" color="primary" grow>
|
||||
@@ -169,156 +172,10 @@
|
||||
|
||||
<p class="text-caption text-grey mb-4">請在現場合對處出示此條碼進行報到</p>
|
||||
|
||||
<!-- 模擬 QR Code SVG,更高級精緻 -->
|
||||
<div
|
||||
class="qrcode-wrapper mx-auto mb-4 elevation-3 rounded-lg pa-3 bg-white border d-flex justify-center align-center"
|
||||
>
|
||||
<svg class="qrcode-svg" height="180" viewBox="0 0 100 100" width="180">
|
||||
<!-- 四個角定位框 -->
|
||||
<path d="M 0,0 H 25 V 8 H 8 V 25 H 0 Z" fill="#1D7063" />
|
||||
<path d="M 75,0 H 100 V 25 H 92 V 8 H 75 Z" fill="#1D7063" />
|
||||
<path d="M 0,75 V 100 H 25 V 92 H 8 V 75 Z" fill="#1D7063" />
|
||||
<path d="M 92,75 V 92 H 75 V 100 H 100 V 75 Z" fill="#1D7063" />
|
||||
<!-- 內嵌二維碼方塊 -->
|
||||
<rect
|
||||
fill="#1D7063"
|
||||
height="20"
|
||||
width="20"
|
||||
x="12"
|
||||
y="12"
|
||||
/>
|
||||
|
||||
<rect
|
||||
fill="white"
|
||||
height="12"
|
||||
width="12"
|
||||
x="16"
|
||||
y="16"
|
||||
/>
|
||||
|
||||
<rect
|
||||
fill="#E66926"
|
||||
height="6"
|
||||
width="6"
|
||||
x="19"
|
||||
y="19"
|
||||
/>
|
||||
|
||||
<rect
|
||||
fill="#1D7063"
|
||||
height="20"
|
||||
width="20"
|
||||
x="68"
|
||||
y="12"
|
||||
/>
|
||||
|
||||
<rect
|
||||
fill="white"
|
||||
height="12"
|
||||
width="12"
|
||||
x="72"
|
||||
y="16"
|
||||
/>
|
||||
|
||||
<rect
|
||||
fill="#E66926"
|
||||
height="6"
|
||||
width="6"
|
||||
x="75"
|
||||
y="75"
|
||||
/>
|
||||
|
||||
<rect
|
||||
fill="#1D7063"
|
||||
height="20"
|
||||
width="20"
|
||||
x="12"
|
||||
y="68"
|
||||
/>
|
||||
|
||||
<rect
|
||||
fill="white"
|
||||
height="12"
|
||||
width="12"
|
||||
x="16"
|
||||
y="72"
|
||||
/>
|
||||
|
||||
<rect
|
||||
fill="#1D7063"
|
||||
height="6"
|
||||
width="6"
|
||||
x="19"
|
||||
y="75"
|
||||
/>
|
||||
|
||||
<!-- 中間隨機小方塊 -->
|
||||
<rect
|
||||
fill="#1D7063"
|
||||
height="8"
|
||||
width="8"
|
||||
x="40"
|
||||
y="20"
|
||||
/>
|
||||
|
||||
<rect
|
||||
fill="#E66926"
|
||||
height="14"
|
||||
width="6"
|
||||
x="52"
|
||||
y="12"
|
||||
/>
|
||||
|
||||
<rect
|
||||
fill="#1D7063"
|
||||
height="6"
|
||||
width="16"
|
||||
x="42"
|
||||
y="36"
|
||||
/>
|
||||
|
||||
<rect
|
||||
fill="#47C2A6"
|
||||
height="10"
|
||||
width="28"
|
||||
x="36"
|
||||
y="48"
|
||||
/>
|
||||
|
||||
<rect
|
||||
fill="#1D7063"
|
||||
height="12"
|
||||
width="14"
|
||||
x="68"
|
||||
y="42"
|
||||
/>
|
||||
|
||||
<rect
|
||||
fill="#E66926"
|
||||
height="16"
|
||||
width="16"
|
||||
x="72"
|
||||
y="60"
|
||||
/>
|
||||
|
||||
<rect
|
||||
fill="#1D7063"
|
||||
height="12"
|
||||
width="18"
|
||||
x="44"
|
||||
y="68"
|
||||
/>
|
||||
|
||||
<rect
|
||||
fill="#47C2A6"
|
||||
height="6"
|
||||
width="24"
|
||||
x="40"
|
||||
y="82"
|
||||
/>
|
||||
</svg>
|
||||
<!-- 紅色掃描雷射線 -->
|
||||
<div class="laser-line" />
|
||||
<QRCode :size="220" :value="selectedCheckinPayload" />
|
||||
</div>
|
||||
|
||||
<div class="text-caption text-grey-darken-2 font-weight-bold mb-4">
|
||||
@@ -359,6 +216,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import Layout from '@/components/layout/DefaultLayout.vue'
|
||||
import QRCode from '@/components/QRCode.vue'
|
||||
import { type Appointment, useAppStore } from '@/stores/app'
|
||||
|
||||
const store = useAppStore()
|
||||
@@ -374,6 +232,14 @@ const filteredAppointments = computed(() => {
|
||||
return store.appointments
|
||||
})
|
||||
|
||||
const selectedCheckinPayload = computed(() => {
|
||||
if (!selectedApt.value) {
|
||||
return 'https://hp.local/c'
|
||||
}
|
||||
|
||||
return `https://hp.local/c/${selectedApt.value.id}`
|
||||
})
|
||||
|
||||
function getStatusColor (status: string) {
|
||||
switch (status) {
|
||||
case '未報名': {
|
||||
@@ -422,36 +288,9 @@ function simulateOnSiteCheckin () {
|
||||
|
||||
.qrcode-wrapper {
|
||||
position: relative;
|
||||
width: 204px;
|
||||
height: 204px;
|
||||
width: 244px;
|
||||
height: 244px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.qrcode-svg {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* 掃描雷射線效果 */
|
||||
.laser-line {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
background-color: #ff3b30;
|
||||
box-shadow: 0 0 8px #ff3b30;
|
||||
animation: scan 2.5s infinite linear;
|
||||
}
|
||||
|
||||
@keyframes scan {
|
||||
0% {
|
||||
top: 0%;
|
||||
}
|
||||
50% {
|
||||
top: 100%;
|
||||
}
|
||||
100% {
|
||||
top: 0%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user