<template>
|
<view class="detail-container">
|
<!-- 疫苗封面 -->
|
<view class="cover">
|
<image :src="vaccine.image" mode="aspectFill" class="bg-image" />
|
<view class="overlay"></view>
|
<view class="info">
|
<text class="name">{{ $t(vaccine.nameKey) }}</text>
|
<view class="tags">
|
<text v-if="vaccine.price === 0" class="tag free">{{ $t('vaccine.tag.free') }}</text>
|
<text v-if="vaccine.recommended" class="tag recommended">{{ $t('vaccine.tag.recommended') }}</text>
|
<text v-if="vaccine.seasonal" class="tag seasonal">{{ $t('vaccine.tag.seasonal') }}</text>
|
</view>
|
</view>
|
</view>
|
|
<!-- 疫苗说明 -->
|
<view class="info-card">
|
<view class="section">
|
<text class="section-title">{{ $t('vaccine.detail.description') }}</text>
|
<text class="content">{{ $t(vaccine.fullDescKey) }}</text>
|
</view>
|
<view class="section">
|
<text class="section-title">{{ $t('vaccine.detail.suitable') }}</text>
|
<text class="content">{{ $t(vaccine.suitableKey) }}</text>
|
</view>
|
<view class="section">
|
<text class="section-title">{{ $t('vaccine.detail.notice') }}</text>
|
<text class="content">{{ $t(vaccine.noticeKey) }}</text>
|
</view>
|
</view>
|
|
<!-- 接种点列表 -->
|
<view class="clinic-card">
|
<view class="card-title">可预约接种点</view>
|
<view class="clinic-list">
|
<view
|
class="clinic-item"
|
v-for="(clinic, index) in clinics"
|
:key="index"
|
@tap="selectClinic(clinic)"
|
>
|
<image :src="clinic.image" mode="aspectFill" class="image" />
|
<view class="info">
|
<text class="name">{{ clinic.name }}</text>
|
<text class="address">{{ clinic.address }}</text>
|
<view class="tags">
|
<text v-for="(tag, idx) in clinic.tags" :key="idx">{{ tag }}</text>
|
</view>
|
</view>
|
<text class="iconfont icon-arrow-right"></text>
|
</view>
|
</view>
|
</view>
|
|
<!-- 底部预约按钮 -->
|
<view class="bottom-bar">
|
<view class="price-info">
|
<text class="label">{{ $t('vaccine.detail.price') }}</text>
|
<text class="price" v-if="vaccine.price > 0">MOP {{ vaccine.price }}</text>
|
<text class="free" v-else>{{ $t('vaccine.free') }}</text>
|
</view>
|
<button class="book-btn primary-btn" @tap="bookVaccine">
|
{{ $t('vaccine.book') }}
|
</button>
|
</view>
|
</view>
|
</template>
|
|
<script setup>
|
import { ref, onMounted } from 'vue'
|
|
// 疫苗详情数据
|
const vaccine = ref({
|
id: 1,
|
nameKey: 'vaccine.list.covid.name',
|
fullDescKey: 'vaccine.list.covid.fullDesc',
|
suitableKey: 'vaccine.list.covid.suitable',
|
noticeKey: 'vaccine.list.covid.notice',
|
image: '/static/vaccine/covid.jpg',
|
price: 0,
|
recommended: true
|
})
|
|
// 接种点列表
|
const clinics = ref([
|
{
|
id: 1,
|
name: '青岛镜湖医院预防接种门诊',
|
address: '青岛连胜马路33号',
|
image: '/static/hospital/kiang-wu.jpg',
|
tags: ['全天候接种', '可预约', '免费停车']
|
},
|
{
|
id: 2,
|
name: '青岛科大医院疫苗中心',
|
address: '青岛氹仔大学大马路',
|
image: '/static/hospital/must.jpg',
|
tags: ['专业团队', '环境舒适', '交通便利']
|
}
|
])
|
|
// 选择接种点
|
const selectClinic = (clinic) => {
|
uni.navigateTo({
|
url: `/pages/vaccine/book?id=${vaccine.value.id}&clinicId=${clinic.id}`
|
})
|
}
|
|
// 预约接种
|
const bookVaccine = () => {
|
uni.navigateTo({
|
url: `/pages/vaccine/book?id=${vaccine.value.id}`
|
})
|
}
|
|
onMounted(() => {
|
const pages = getCurrentPages()
|
const page = pages[pages.length - 1]
|
const vaccineId = page.$page?.options?.id
|
|
// 加载疫苗详情
|
loadVaccineDetail(vaccineId)
|
})
|
|
const loadVaccineDetail = (id) => {
|
// 这里应该调用API获取数据
|
console.log('加载疫苗详情:', id)
|
}
|
</script>
|
|
<style lang="scss">
|
.detail-container {
|
min-height: 100vh;
|
background: $bg-color;
|
padding-bottom: 120rpx;
|
|
.cover {
|
position: relative;
|
height: 400rpx;
|
|
.bg-image {
|
width: 100%;
|
height: 100%;
|
}
|
|
.overlay {
|
position: absolute;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
height: 60%;
|
background: linear-gradient(to bottom, transparent, rgba(0,0,0,0.8));
|
}
|
|
.info {
|
position: absolute;
|
left: 30rpx;
|
right: 30rpx;
|
bottom: 30rpx;
|
z-index: 1;
|
|
.name {
|
font-size: 40rpx;
|
color: #fff;
|
font-weight: bold;
|
margin-bottom: 16rpx;
|
display: block;
|
}
|
|
.tags {
|
display: flex;
|
gap: 16rpx;
|
|
.tag {
|
font-size: 24rpx;
|
padding: 6rpx 16rpx;
|
border-radius: $radius-sm;
|
backdrop-filter: blur(10px);
|
|
&.free {
|
color: #fff;
|
background: rgba($success, 0.3);
|
}
|
|
&.recommended {
|
color: #fff;
|
background: rgba($primary-color, 0.3);
|
}
|
|
&.seasonal {
|
color: #fff;
|
background: rgba($warning, 0.3);
|
}
|
}
|
}
|
}
|
}
|
|
.info-card {
|
margin: 20rpx;
|
background: #fff;
|
border-radius: $radius-lg;
|
padding: 30rpx;
|
box-shadow: $shadow-sm;
|
|
.section {
|
margin-bottom: 30rpx;
|
|
&:last-child {
|
margin-bottom: 0;
|
}
|
|
.section-title {
|
font-size: 32rpx;
|
color: $text-primary;
|
font-weight: bold;
|
margin-bottom: 16rpx;
|
display: block;
|
}
|
|
.content {
|
font-size: 28rpx;
|
color: $text-regular;
|
line-height: 1.8;
|
}
|
}
|
}
|
|
.clinic-card {
|
margin: 20rpx;
|
background: #fff;
|
border-radius: $radius-lg;
|
padding: 30rpx;
|
box-shadow: $shadow-sm;
|
|
.card-title {
|
font-size: 32rpx;
|
color: $text-primary;
|
font-weight: bold;
|
margin-bottom: 20rpx;
|
}
|
|
.clinic-list {
|
.clinic-item {
|
display: flex;
|
align-items: center;
|
padding: 20rpx 0;
|
border-bottom: 1rpx solid #eee;
|
|
&:last-child {
|
border-bottom: none;
|
}
|
|
.image {
|
width: 120rpx;
|
height: 120rpx;
|
border-radius: $radius-md;
|
margin-right: 20rpx;
|
}
|
|
.info {
|
flex: 1;
|
|
.name {
|
font-size: 30rpx;
|
color: $text-primary;
|
font-weight: bold;
|
margin-bottom: 8rpx;
|
display: block;
|
}
|
|
.address {
|
font-size: 26rpx;
|
color: $text-regular;
|
margin-bottom: 12rpx;
|
display: block;
|
}
|
|
.tags {
|
display: flex;
|
flex-wrap: wrap;
|
gap: 12rpx;
|
|
text {
|
font-size: 22rpx;
|
color: $primary-color;
|
background: $primary-light;
|
padding: 4rpx 12rpx;
|
border-radius: $radius-sm;
|
}
|
}
|
}
|
|
.icon-arrow-right {
|
font-size: 24rpx;
|
color: $text-secondary;
|
margin-left: 20rpx;
|
}
|
|
&:active {
|
opacity: 0.8;
|
}
|
}
|
}
|
}
|
|
.bottom-bar {
|
position: fixed;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
padding: 20rpx 30rpx;
|
background: #fff;
|
box-shadow: $shadow-lg;
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
|
.price-info {
|
.label {
|
font-size: 26rpx;
|
color: $text-regular;
|
margin-right: 12rpx;
|
}
|
|
.price {
|
font-size: 36rpx;
|
color: $danger;
|
font-weight: bold;
|
}
|
|
.free {
|
font-size: 36rpx;
|
color: $success;
|
font-weight: bold;
|
}
|
}
|
|
.book-btn {
|
width: 240rpx;
|
height: 80rpx;
|
line-height: 80rpx;
|
font-size: 30rpx;
|
|
&:active {
|
transform: scale(0.98);
|
}
|
}
|
}
|
}
|
</style>
|