Files
pingxiangcard/src/packages/user/pages/card/qrcode.vue
T
jacobxu666andClaude 455b865931 fix: cleanup remaining font-weight:bold, remove stale scenic-spots.ts
- Replace font-weight: bold with 700 (plain CSS) or $font-weight-bold (SCSS)
  in qrcode.vue, card-item.vue, bind.vue, activate.vue
- Remove src/data/scenic-spots.ts (replaced by mock/scenic.ts)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-26 11:15:08 +08:00

89 lines
3.5 KiB
Vue

<template>
<view class="page">
<!-- 年卡信息头部 -->
<view class="card-top">
<text class="card-label">{{ qrInfo?.cardName || '年卡' }}</text>
<text class="user-name">{{ qrInfo?.userName || '---' }}</text>
<text class="expire-date">有效期至 {{ qrInfo?.expireDate || '---' }}</text>
</view>
<!-- 二维码区域 -->
<view class="qr-card">
<view class="qr-area">
<image v-if="qrInfo?.qrCode" class="qr-image" :src="qrInfo.qrCode" mode="aspectFit" />
<view v-else class="qr-placeholder"><text>加载中...</text></view>
</view>
<text class="qr-tip">扫码入园 · 每60秒自动刷新</text>
</view>
<!-- 操作按钮 -->
<view class="actions">
<button class="btn-secondary" @click="showComingSoon">预约景区</button>
<button class="btn-primary" @click="refreshQrCode">刷新二维码</button>
</view>
</view>
</template>
<script setup lang="ts">
import { ref, onBeforeUnmount } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { getEntryQrCode } from '../../api/card'
import { showToast } from '../../../../utils'
import type { QrCodeInfo } from '../../../../api/types'
const cardId = ref('')
const qrInfo = ref<QrCodeInfo | null>(null)
let refreshTimer: ReturnType<typeof setInterval> | null = null
/** 页面加载时获取入园码并启动定时刷新 */
onLoad((options) => {
cardId.value = options?.cardId || ''
if (cardId.value) {
loadQrCode()
// 每60秒自动刷新二维码
refreshTimer = setInterval(() => {
loadQrCode()
}, 60000)
}
})
/** 页面销毁时清除定时器 */
onBeforeUnmount(() => {
if (refreshTimer) clearInterval(refreshTimer)
})
/** 加载入园码 */
async function loadQrCode() {
try {
qrInfo.value = await getEntryQrCode(cardId.value)
} catch (err: any) {
showToast(err.message || '获取入园码失败')
}
}
/** 手动刷新二维码 */
function refreshQrCode() {
loadQrCode()
showToast('已刷新', 'success')
}
/** 预约景区(暂未开放) */
function showComingSoon() {
showToast('即将上线,敬请期待')
}
</script>
<style lang="scss" scoped>
.page { min-height: 100vh; background: #f5f5f5; padding: 20rpx; box-sizing: border-box; font-family: 'SourceHanSerifCN', '思源宋体', -apple-system, 'PingFang SC', sans-serif; }
.card-top { background: linear-gradient(135deg, #3c9cff, #398ade); border-radius: 24rpx; padding: 30rpx; color: #fff; margin-bottom: -20rpx; }
.card-label { font-size: 24rpx; opacity: 0.8; display: block; }
.user-name { font-size: 36rpx; font-weight: 700; display: block; margin: 12rpx 0 8rpx; }
.expire-date { font-size: 22rpx; opacity: 0.7; display: block; }
.qr-card { background: #fff; border-radius: 24rpx; padding: 30rpx; margin-top: 30rpx; box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.08); text-align: center; }
.qr-area { width: 360rpx; height: 360rpx; margin: 20rpx auto; display: flex; align-items: center; justify-content: center; background: #f8f8f8; border-radius: 12rpx; }
.qr-image { width: 320rpx; height: 320rpx; }
.qr-placeholder { color: #999; font-size: 28rpx; }
.qr-tip { font-size: 24rpx; color: #999; display: block; margin-top: 16rpx; }
.actions { display: flex; gap: 20rpx; padding: 40rpx 20rpx; }
.btn-secondary { flex: 1; height: 88rpx; line-height: 88rpx; background: #fff; color: #3c9cff; border: 2rpx solid #3c9cff; border-radius: 40rpx; font-size: 28rpx; }
.btn-primary { flex: 1; height: 88rpx; line-height: 88rpx; background: #3c9cff; color: #fff; border-radius: 40rpx; font-size: 28rpx; border: none; }
</style>