feat: qr code

This commit is contained in:
skytek_xinliang
2026-06-23 11:06:11 +08:00
parent 6cc393cd8a
commit e58e9d40d7
5 changed files with 660 additions and 222 deletions
+19 -180
View File
@@ -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>
+11 -12
View File
@@ -180,23 +180,24 @@
<template v-else>
<div class="text-center mb-6">
<BrandAvatar class="elevation-3 mb-4" :icon-size="42" :size="72" />
<p class="text-body-medium text-grey-darken-1 mb-0">
不登入也可以先完成線上健康自評,<br />登入後可預約普測與查看量測紀錄。
</p>
<BrandAvatar class="elevation-2" :icon-size="42" :size="72" />
</div>
<v-card class="rounded-xl elevation-2 mb-4" color="surface">
<v-card class="rounded-xl elevation-2 mb-12 py-4" color="surface">
<v-card-text>
<div class="d-flex align-center mb-4">
<v-avatar class="mr-3 text-white" color="accent" size="36">
<v-avatar class="mr-4 text-white" color="accent" size="36">
<v-icon icon="mdi-clipboard-text-outline" />
</v-avatar>
<div class="text-left">
<div class="text-title-medium font-weight-bold text-primary">先做線上健康自評</div>
<div class="text-title-small text-grey">約 3 分鐘完成,取得初步健康風險分級。</div>
<div class="text-title-medium font-weight-bold text-primary">
無須登入,先做線上健康自評
</div>
<div class="text-title-small text-grey mt-2">
約 3 分鐘完成,取得初步健康風險分級。
</div>
</div>
</div>
@@ -231,9 +232,7 @@
<div>
<div class="font-weight-bold text-grey-darken-4">登入後可使用完整功能</div>
<div class="text-title-small text-grey">
普測預約、現場報到、量測紀錄與運動處方需要登入狀態。
</div>
<div class="text-title-small text-grey">普測預約、現場報到、量測紀錄與運動處方。</div>
</div>
</v-card-text>
</v-card>