You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

275 lines
5.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="container">
<!-- 顶部装饰条 -->
<view class="top-decoration"></view>
<CustomHeader title="访问凭证" @back="handleBack" />
<view class="credential-card">
<text class="card-title">访客二维码</text>
<text class="card-subtitle">请向工作人员出示此二维码</text>
<view class="qr-code-container">
<image :src="qrCodeUrl" class="qr-code" mode="aspectFit" @click="previewQrCode"></image>
<text class="qr-tip">凭此码可快速通行</text>
</view>
<view class="visitor-info">
<view class="info-item">
<text class="info-label">访客姓名</text>
<text class="info-value">{{ visitorName }}</text>
</view>
<view class="info-item">
<text class="info-label">联系电话</text>
<text class="info-value">{{ visitorPhone }}</text>
</view>
<view class="info-item">
<text class="info-label">车牌号</text>
<text class="info-value">{{ visitorPlate }}</text>
</view>
</view>
<view class="validity-info">
<text class="validity-label">有效期限</text>
<text class="validity-value">{{ validityTime }}</text>
</view>
<view class="status-badge">
<text class="status-text">{{ credentialStatus }}</text>
</view>
</view>
<view class="tips">
<text class="tips-title">使用提示</text>
<view class="tips-list">
<text class="tip-item"> 请妥善保管您的访问凭证</text>
<text class="tip-item"> 凭证仅限本人使用不得转借</text>
<text class="tip-item"> 凭证过期后需重新申请</text>
<text class="tip-item"> 如有疑问请联系工作人员</text>
</view>
</view>
<!-- 底部装饰 -->
<view class="bottom-decoration"></view>
</view>
</template>
<script>
import CustomHeader from '../components/CustomHeader.vue';
export default {
components: { CustomHeader },
data() {
return {
openid: '',
qrCodeUrl: '',
visitorName: '访客用户',
visitorPhone: '138****1234',
visitorPlate: '京A12345',
validityTime: '2026-01-03 00:00 - 2026-01-04 23:59',
credentialStatus: '有效'
};
},
onLoad(options) {
this.openid = options.openid || '';
this.qrCodeUrl = 'https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=visitor_openid_' + this.openid;
},
mounted() {
// 模拟获取访客信息
setTimeout(() => {
this.visitorName = '访客_' + this.openid.slice(-4);
}, 500);
},
methods: {
handleBack() {
uni.navigateBack();
},
previewQrCode() {
if (!this.qrCodeUrl) return;
uni.previewImage({
urls: [this.qrCodeUrl],
current: this.qrCodeUrl
});
},
refreshQrCode() {
this.qrCodeUrl = 'https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=visitor_openid_' + this.openid + '_' + Date.now();
uni.showToast({ title: '二维码已刷新', icon: 'success' });
}
}
};
</script>
<style lang="scss" scoped>
.container {
min-height: 100vh;
background: linear-gradient(135deg, #3a5da6 0%, #4a72c2 100%);
padding: 20rpx;
position: relative;
overflow: hidden;
}
.top-decoration {
position: absolute;
top: 0;
left: 0;
right: 0;
height: 10rpx;
background: linear-gradient(90deg, #ff6b6b, #4ecdc4, #45b7d1, #96ceb4);
}
.credential-card {
background: rgba(255, 255, 255, 0.95);
border-radius: 24rpx;
padding: 50rpx;
box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.15);
backdrop-filter: blur(10rpx);
position: relative;
z-index: 1;
margin-bottom: 40rpx;
margin-top: 12rpx;
}
.card-title {
font-size: 44rpx;
font-weight: bold;
color: #333;
text-align: center;
margin-bottom: 12rpx;
}
.card-subtitle {
font-size: 28rpx;
color: #666;
text-align: center;
display: block;
margin-bottom: 50rpx;
}
.qr-code-container {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 50rpx;
}
.qr-code {
width: 300rpx;
height: 300rpx;
background-color: #fff;
padding: 20rpx;
border-radius: 16rpx;
box-shadow: 0 12rpx 30rpx rgba(0, 0, 0, 0.1);
margin-bottom: 20rpx;
}
.qr-tip {
font-size: 28rpx;
color: #3a5da6;
font-weight: 500;
}
.visitor-info {
background: rgba(58, 93, 166, 0.05);
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 30rpx;
}
.info-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15rpx 0;
border-bottom: 1rpx solid rgba(58, 93, 166, 0.1);
}
.info-item:last-child {
border-bottom: none;
}
.info-label {
font-size: 32rpx;
color: #666;
}
.info-value {
font-size: 32rpx;
color: #333;
font-weight: 500;
}
.validity-info {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx 0;
margin-bottom: 30rpx;
}
.validity-label {
font-size: 32rpx;
color: #666;
}
.validity-value {
font-size: 32rpx;
color: #ff6b6b;
font-weight: 500;
}
.status-badge {
background: linear-gradient(135deg, #4caf50 0%, #45a049 100%);
border-radius: 50rpx;
padding: 15rpx 40rpx;
text-align: center;
margin: 0 auto;
width: fit-content;
}
.status-text {
color: #fff;
font-size: 32rpx;
font-weight: bold;
}
.tips {
background: rgba(255, 255, 255, 0.95);
border-radius: 24rpx;
padding: 40rpx;
box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.15);
backdrop-filter: blur(10rpx);
position: relative;
z-index: 1;
}
.tips-title {
font-size: 36rpx;
font-weight: bold;
color: #333;
margin-bottom: 20rpx;
display: block;
}
.tips-list {
display: flex;
flex-direction: column;
gap: 15rpx;
}
.tip-item {
font-size: 28rpx;
color: #666;
line-height: 44rpx;
}
.bottom-decoration {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 200rpx;
background: linear-gradient(180deg, transparent, rgba(42, 82, 152, 0.2));
opacity: 0.6;
}
</style>