9 changed files with 976 additions and 75 deletions
-
18pages.json
-
8pages/home/home.vue
-
10pages/user/user.vue
-
5static/iconfont.css
-
BINstatic/iconfont.ttf
-
BINstatic/images/lib.png
-
336subpkg/pages/booking-detail/booking-detail.vue
-
289subpkg/pages/booking-record/booking-record.vue
-
241subpkg/pages/seat-booking/seat-booking.vue
|
After Width: 150 | Height: 150 | Size: 46 KiB |
@ -0,0 +1,336 @@ |
|||
<template> |
|||
<view class="booking-detail"> |
|||
<view class="section"> |
|||
<view class="section-title">日期选择</view> |
|||
<view class="calendar"> |
|||
<view class="calendar-header"> |
|||
<text class="month">{{ currentYear }}年{{ currentMonth }}月</text> |
|||
</view> |
|||
<view class="calendar-weekdays"> |
|||
<text v-for="day in weekdays" :key="day" class="weekday">{{ day }}</text> |
|||
</view> |
|||
<view class="calendar-days"> |
|||
<view |
|||
v-for="(day, index) in calendarDays" |
|||
:key="index" |
|||
class="day-item" |
|||
:class="{ |
|||
'other-month': !day.currentMonth, |
|||
'selected': day.date === selectedDate, |
|||
'disabled': !day.available, |
|||
'today': day.isToday |
|||
}" |
|||
@click="selectDate(day)" |
|||
> |
|||
<text class="day-num">{{ day.day }}</text> |
|||
<text v-if="day.available && !day.isToday" class="available-tag">开放日</text> |
|||
<text v-if="day.isToday" class="today-tag">今天</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="section"> |
|||
<view class="section-title">时间选择</view> |
|||
<view class="time-slots"> |
|||
<view |
|||
v-for="slot in timeSlots" |
|||
:key="slot.id" |
|||
class="time-slot" |
|||
:class="{ 'selected': selectedTime === slot.time }" |
|||
@click="selectTime(slot)" |
|||
> |
|||
<text class="time-text">{{ slot.time }}</text> |
|||
<text v-if="slot.available" class="available-badge">可选</text> |
|||
<text v-else class="unavailable-badge">已满</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="bottom-bar"> |
|||
<button class="btn-primary" @click="confirmBooking">确认预约</button> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
currentYear: new Date().getFullYear(), |
|||
currentMonth: new Date().getMonth() + 1, |
|||
selectedDate: '', |
|||
selectedTime: '', |
|||
weekdays: ['日', '一', '二', '三', '四', '五', '六'], |
|||
calendarDays: [], |
|||
timeSlots: [ |
|||
{ id: 1, time: '09:15-12:45', available: true }, |
|||
{ id: 2, time: '13:00-16:30', available: false }, |
|||
{ id: 3, time: '16:45-20:15', available: true } |
|||
] |
|||
}; |
|||
}, |
|||
onLoad(options) { |
|||
this.generateCalendar(); |
|||
}, |
|||
methods: { |
|||
generateCalendar() { |
|||
const year = this.currentYear; |
|||
const month = this.currentMonth; |
|||
const firstDay = new Date(year, month - 1, 1); |
|||
const lastDay = new Date(year, month, 0); |
|||
const daysInMonth = lastDay.getDate(); |
|||
const startWeekday = firstDay.getDay(); |
|||
const today = new Date(); |
|||
const todayStr = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`; |
|||
|
|||
const days = []; |
|||
const prevMonthLastDay = new Date(year, month - 1, 0).getDate(); |
|||
for (let i = startWeekday - 1; i >= 0; i--) { |
|||
days.push({ |
|||
day: prevMonthLastDay - i, |
|||
date: '', |
|||
currentMonth: false, |
|||
available: false, |
|||
isToday: false |
|||
}); |
|||
} |
|||
|
|||
const todayDate = new Date(); |
|||
const availableDates = []; |
|||
for (let i = 0; i < 7; i++) { |
|||
const date = new Date(todayDate); |
|||
date.setDate(todayDate.getDate() + i); |
|||
const dateStr = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`; |
|||
availableDates.push(dateStr); |
|||
} |
|||
|
|||
for (let i = 1; i <= daysInMonth; i++) { |
|||
const dateStr = `${year}-${String(month).padStart(2, '0')}-${String(i).padStart(2, '0')}`; |
|||
const isAvailable = availableDates.includes(dateStr); |
|||
const isToday = dateStr === todayStr; |
|||
|
|||
days.push({ |
|||
day: i, |
|||
date: dateStr, |
|||
currentMonth: true, |
|||
available: isAvailable, |
|||
isToday: isToday |
|||
}); |
|||
} |
|||
|
|||
const remainingDays = 42 - days.length; |
|||
for (let i = 1; i <= remainingDays; i++) { |
|||
days.push({ |
|||
day: i, |
|||
date: '', |
|||
currentMonth: false, |
|||
available: false, |
|||
isToday: false |
|||
}); |
|||
} |
|||
|
|||
this.calendarDays = days; |
|||
if (availableDates.length > 0) { |
|||
this.selectedDate = availableDates[0]; |
|||
} |
|||
}, |
|||
selectDate(day) { |
|||
if (!day.available || !day.currentMonth) return; |
|||
this.selectedDate = day.date; |
|||
}, |
|||
selectTime(slot) { |
|||
if (!slot.available) return; |
|||
this.selectedTime = slot.time; |
|||
}, |
|||
confirmBooking() { |
|||
if (!this.selectedDate) { |
|||
uni.showToast({ title: '请选择日期', icon: 'none' }); |
|||
return; |
|||
} |
|||
if (!this.selectedTime) { |
|||
uni.showToast({ title: '请选择时间段', icon: 'none' }); |
|||
return; |
|||
} |
|||
|
|||
uni.showLoading({ title: '预约中...' }); |
|||
setTimeout(() => { |
|||
uni.hideLoading(); |
|||
uni.showModal({ |
|||
title: '预约成功', |
|||
content: `您已成功预约\n日期:${this.selectedDate}\n时间:${this.selectedTime}`, |
|||
showCancel: false, |
|||
confirmText: '确定', |
|||
success: () => { |
|||
uni.navigateBack({ delta: 2 }); |
|||
} |
|||
}); |
|||
}, 1500); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.booking-detail { |
|||
min-height: 100vh; |
|||
background-color: #f5f5f5; |
|||
padding-bottom: 70px; |
|||
} |
|||
|
|||
.section { |
|||
background-color: #fff; |
|||
margin: 10px; |
|||
border-radius: 12px; |
|||
padding: 16px; |
|||
} |
|||
|
|||
.section-title { |
|||
font-size: 16px; |
|||
font-weight: bold; |
|||
color: #333; |
|||
margin-bottom: 16px; |
|||
} |
|||
|
|||
/* 日历 */ |
|||
.calendar-header { |
|||
text-align: center; |
|||
margin-bottom: 12px; |
|||
} |
|||
.month { |
|||
font-size: 16px; |
|||
color: #333; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.calendar-weekdays { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
margin-bottom: 10px; |
|||
} |
|||
.weekday { |
|||
width: 14.28%; |
|||
text-align: center; |
|||
font-size: 13px; |
|||
color: #999; |
|||
} |
|||
|
|||
.calendar-days { |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
} |
|||
.day-item { |
|||
width: 14.28%; |
|||
aspect-ratio: 1; |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
margin-bottom: 6px; |
|||
border-radius: 6px; |
|||
position: relative; |
|||
} |
|||
.day-item.other-month .day-num { |
|||
color: #ccc; |
|||
} |
|||
.day-item.disabled .day-num { |
|||
color: #ccc; |
|||
} |
|||
.day-item.selected { |
|||
background-color: #01a4fe; |
|||
} |
|||
.day-item.selected .day-num { |
|||
color: #fff; |
|||
font-size: 15px; |
|||
font-weight: bold; |
|||
} |
|||
.day-item.selected .available-tag, |
|||
.day-item.selected .today-tag { |
|||
color: rgba(255, 255, 255, 0.9); |
|||
font-size: 10px; |
|||
} |
|||
.day-item.today:not(.selected) { |
|||
background-color: #fff3cd; |
|||
} |
|||
.day-item.today:not(.selected) .day-num { |
|||
color: #856404; |
|||
} |
|||
|
|||
.day-num { |
|||
font-size: 14px; |
|||
color: #333; |
|||
} |
|||
.available-tag { |
|||
font-size: 10px; |
|||
color: #01a4fe; |
|||
margin-top: 2px; |
|||
} |
|||
.today-tag { |
|||
font-size: 10px; |
|||
color: #856404; |
|||
margin-top: 2px; |
|||
} |
|||
|
|||
/* 时间选择 */ |
|||
.time-slots { |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
gap: 10px; |
|||
} |
|||
.time-slot { |
|||
width: calc(50% - 5px); |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
padding: 12px; |
|||
background-color: #f8f8f8; |
|||
border-radius: 8px; |
|||
border: 1px solid transparent; |
|||
} |
|||
.time-slot.selected { |
|||
background-color: #e8f4fd; |
|||
border-color: #01a4fe; |
|||
} |
|||
.time-text { |
|||
font-size: 14px; |
|||
color: #333; |
|||
} |
|||
.available-badge { |
|||
font-size: 12px; |
|||
color: #01a4fe; |
|||
background-color: #e8f4fd; |
|||
padding: 2px 8px; |
|||
border-radius: 10px; |
|||
} |
|||
.unavailable-badge { |
|||
font-size: 12px; |
|||
color: #999; |
|||
background-color: #f0f0f0; |
|||
padding: 2px 8px; |
|||
border-radius: 10px; |
|||
} |
|||
|
|||
/* 底部按钮 */ |
|||
.bottom-bar { |
|||
position: fixed; |
|||
bottom: 0; |
|||
left: 0; |
|||
right: 0; |
|||
padding: 10px; |
|||
background-color: #fff; |
|||
box-shadow: 0 -1px 5px rgba(0, 0, 0, 0.1); |
|||
} |
|||
.btn-primary { |
|||
width: 100%; |
|||
height: 44px; |
|||
line-height: 44px; |
|||
background-color: #01a4fe; |
|||
color: #fff; |
|||
border-radius: 22px; |
|||
font-size: 15px; |
|||
border: none; |
|||
} |
|||
.btn-primary::after { |
|||
border: none; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,289 @@ |
|||
<template> |
|||
<view class="activity-list"> |
|||
<view class="tab-box"> |
|||
<view |
|||
class="tab-item" |
|||
:class="{ active: currentTab === 0 }" |
|||
@click="switchTab(0)" |
|||
> |
|||
未开始 |
|||
</view> |
|||
<view |
|||
class="tab-item" |
|||
:class="{ active: currentTab === 1 }" |
|||
@click="switchTab(1)" |
|||
> |
|||
进行中 |
|||
</view> |
|||
<view |
|||
class="tab-item" |
|||
:class="{ active: currentTab === 2 }" |
|||
@click="switchTab(2)" |
|||
> |
|||
已结束 |
|||
</view> |
|||
</view> |
|||
|
|||
<scroll-view |
|||
scroll-y |
|||
refresher-enabled |
|||
:refresher-triggered="refreshing" |
|||
@refresherrefresh="onRefresh" |
|||
lower-threshold="100" |
|||
class="scroll-view" |
|||
> |
|||
<view |
|||
class="activity-item" |
|||
v-for="item in displayList" |
|||
:key="item.id" |
|||
@click="toActivityDetail(item)" |
|||
> |
|||
<view class="activity-info"> |
|||
<text class="title">{{ item.area }}</text> |
|||
<view class="item-info"> |
|||
<text class="label">开始时间:</text> |
|||
<text class="value">{{ item.startTime }}</text> |
|||
</view> |
|||
<view class="item-info"> |
|||
<text class="label">结束时间:</text> |
|||
<text class="value">{{ item.endTime }}</text> |
|||
</view> |
|||
<view class="item-info"> |
|||
<text class="label">座位号:</text> |
|||
<text class="value">{{ item.seatNumber }}</text> |
|||
</view> |
|||
<view class="item-info"> |
|||
<text class="label">状态:</text> |
|||
<text class="value status-tag" :class="item.statusClass">{{ item.statusText }}</text> |
|||
</view> |
|||
<view class="btn-box" v-if="item.status === 0"> |
|||
<button class="activity-btn" type="primary" @click.stop="cancelAppoint(item)"> |
|||
取消预约 |
|||
</button> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="empty-box" v-if="displayList.length === 0"> |
|||
<uni-icons type="empty" size="80" color="#ccc"></uni-icons> |
|||
<text class="empty-text">{{ getEmptyText() }}</text> |
|||
</view> |
|||
</scroll-view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
currentTab: 0, |
|||
activityList: [], |
|||
refreshing: false |
|||
}; |
|||
}, |
|||
computed: { |
|||
displayList() { |
|||
const statusMap = { |
|||
0: [0, '0', '未开始', 'pending'], |
|||
1: [1, '1', '进行中', 'ongoing'], |
|||
2: [2, '2', '已结束', 'ended'] |
|||
}; |
|||
const targetStatuses = statusMap[this.currentTab] || []; |
|||
return this.activityList.filter(item => { |
|||
const itemStatus = String(item.status); |
|||
return targetStatuses.some(status => String(status) === itemStatus); |
|||
}); |
|||
} |
|||
}, |
|||
onLoad() { |
|||
this.getActivityList(); |
|||
}, |
|||
methods: { |
|||
switchTab(index) { |
|||
this.currentTab = index; |
|||
}, |
|||
|
|||
getActivityList() { |
|||
this.refreshing = true; |
|||
setTimeout(() => { |
|||
const rawData = [ |
|||
{id:1,area:'一楼自习区',startTime:'2026-05-21 08:00:00',endTime:'2026-05-21 11:30:00',seatNumber:'8号',status:0,statusText:'已预约'}, |
|||
{id:2,area:'综合阅览一',startTime:'2026-05-21 08:00:00',endTime:'2026-05-21 11:30:00',seatNumber:'8号',status:1,statusText:'进行中'}, |
|||
{id:4,area:'专题阅览室',startTime:'2026-05-21 08:00:00',endTime:'2026-05-21 11:30:00',seatNumber:'8号',status:0,statusText:'已预约'}, |
|||
]; |
|||
this.activityList = rawData.map(item => ({ |
|||
...item, |
|||
statusClass: `status-${item.status}` |
|||
})); |
|||
this.refreshing = false; |
|||
}, 500); |
|||
}, |
|||
|
|||
onRefresh() { |
|||
this.getActivityList(); |
|||
}, |
|||
|
|||
cancelAppoint(item) { |
|||
uni.showModal({ |
|||
title: '提示', |
|||
content: `确定要取消${item.area}的预约吗?`, |
|||
success: (res) => { |
|||
if (res.confirm) { |
|||
uni.showToast({ title: '取消成功', icon: 'success' }); |
|||
this.getActivityList(); |
|||
} |
|||
} |
|||
}) |
|||
}, |
|||
|
|||
toActivityDetail(item) { |
|||
uni.navigateTo({ |
|||
url: "/subpkg/pages/activity-detail/activity-detail?item=" + encodeURIComponent(JSON.stringify(item)) |
|||
}); |
|||
}, |
|||
|
|||
getEmptyText() { |
|||
const textMap = { |
|||
0: '未开始', |
|||
1: '进行中', |
|||
2: '已结束' |
|||
} |
|||
return `暂无${textMap[this.currentTab]}的预约~` |
|||
} |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.activity-list { |
|||
padding: 0; |
|||
height: 100vh; |
|||
box-sizing: border-box; |
|||
background-color: #f5f5f5; |
|||
} |
|||
|
|||
.tab-box { |
|||
display: flex; |
|||
background-color: #fff; |
|||
margin-bottom: 10px; |
|||
position: sticky; |
|||
top: 0; |
|||
z-index: 99; |
|||
} |
|||
.tab-item { |
|||
flex: 1; |
|||
text-align: center; |
|||
padding: 12px 0; |
|||
font-size: 15px; |
|||
color: #666; |
|||
position: relative; |
|||
} |
|||
.tab-item.active { |
|||
color: #01a4fe; |
|||
font-weight: bold; |
|||
} |
|||
.tab-item.active::after { |
|||
content: ''; |
|||
position: absolute; |
|||
width: 30px; |
|||
height: 3px; |
|||
background-color: #01a4fe; |
|||
bottom: 0; |
|||
left: 50%; |
|||
transform: translateX(-50%); |
|||
border-radius: 2px; |
|||
} |
|||
|
|||
.scroll-view { |
|||
height: calc(100vh - 60px); |
|||
padding: 0 12px; |
|||
box-sizing: border-box; |
|||
} |
|||
|
|||
.empty-box { |
|||
height: calc(100vh - 200px); |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
.empty-text { |
|||
margin-top: 16px; |
|||
font-size: 14px; |
|||
color: #999; |
|||
} |
|||
|
|||
.activity-item { |
|||
background: #fff; |
|||
border-radius: 12px; |
|||
margin-bottom: 12px; |
|||
overflow: hidden; |
|||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.06); |
|||
cursor: pointer; |
|||
transition: transform 0.2s; |
|||
|
|||
&:active { |
|||
transform: scale(0.98); |
|||
} |
|||
} |
|||
|
|||
.activity-info { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: flex-start; |
|||
padding: 16px; |
|||
.title { |
|||
font-size: 16px; |
|||
font-weight: bold; |
|||
color: #222; |
|||
margin-bottom: 12px; |
|||
display: block; |
|||
} |
|||
.item-info { |
|||
display: flex; |
|||
padding: 4px 0; |
|||
font-size: 14px; |
|||
.label { |
|||
color: #666; |
|||
width: 72px; |
|||
} |
|||
.value { |
|||
color: #333; |
|||
flex: 1; |
|||
} |
|||
} |
|||
} |
|||
|
|||
/* 正确的状态样式 */ |
|||
.status-tag { |
|||
padding: 2px 8px; |
|||
border-radius: 4px; |
|||
font-size: 12px; |
|||
} |
|||
.status-tag.status-0 { |
|||
color: #01a4fe; |
|||
background: #e6f7ff; |
|||
} |
|||
.status-tag.status-1 { |
|||
color: #00b42a; |
|||
background: #e6ffed; |
|||
} |
|||
.status-tag.status-2 { |
|||
color: #999; |
|||
background: #f5f5f5; |
|||
} |
|||
|
|||
.btn-box { |
|||
width: 100%; |
|||
display: flex; |
|||
justify-content: flex-end; |
|||
margin-top: 10px; |
|||
} |
|||
.activity-btn { |
|||
background-color: #01a4fe; |
|||
font-size: 13px; |
|||
border-radius: 6px; |
|||
padding: 0 14px; |
|||
height: 28px; |
|||
line-height: 28px; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,241 @@ |
|||
<template> |
|||
<view class="seat-booking"> |
|||
<!-- 顶部横幅 --> |
|||
<view class="banner"> |
|||
<image class="banner-bg" src="@/static/images/mingqi-beij@2x.png" mode="aspectFill"></image> |
|||
<view class="banner-overlay"> |
|||
<text class="banner-text">葛店经济开发区图书馆预约</text> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="content"> |
|||
<!-- 场馆选择下拉框 --> |
|||
<!-- <view class="venue-select"> |
|||
<picker :value="venueIndex" :range="venues" @change="onVenueChange"> |
|||
<view class="picker-content"> |
|||
<text>{{ venues[venueIndex] }}</text> |
|||
<uni-icons type="down" size="16" color="#666" /> |
|||
</view> |
|||
</picker> |
|||
</view> --> |
|||
|
|||
<!-- 楼层/区域卡片列表 --> |
|||
<view class="floor-list"> |
|||
<view class="floor-item" v-for="floor in floorList" :key="floor.id"> |
|||
<text class="floor-name">{{ floor.floor }}</text> |
|||
<div class="floor-info"> |
|||
<view class="floor-left"> |
|||
<text class="floor-title">{{ floor.title }}</text> |
|||
<image class="banner-bg" src="@/static/images/lib.png" mode="aspectFill"></image> |
|||
</view> |
|||
<view class="floor-right"> |
|||
<text class="floor-desc">{{ floor.desc }}</text> |
|||
<view style="display: flex; justify-content: flex-end; width: 100%; text-align: end;"> |
|||
<button class="booking-btn" @click="bookingFloor(floor)">预约</button> |
|||
</view> |
|||
</view> |
|||
</div> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
venueIndex: 0, |
|||
venues: ['所有场馆', '东馆', '西馆', '南馆'], |
|||
floorList: [ |
|||
{ |
|||
id: 1, |
|||
floor: '3楼', |
|||
title: '综合阅览一', |
|||
desc: '葛店图书馆三楼阅读广场共有464个座位,为读者提供备电源,读者可预约选择心仪的座位。区域采光良好,环境优美,读者可在休息时一览楼下的风景。', |
|||
image: '@/static/images/lib.png' |
|||
}, |
|||
{ |
|||
id: 2, |
|||
floor: '3楼', |
|||
title: '少儿阅览室', |
|||
desc: '少儿阅览室共有464个座位,为读者提供备电源、读者可自助选择位置,各个区采光良好,环境优美,读者可在休息时一览楼下的风景。', |
|||
image: '@/static/images/lib.png' |
|||
}, |
|||
{ |
|||
id: 3, |
|||
floor: '3楼', |
|||
title: '专题阅览室', |
|||
desc: '专题阅览室共有464个座位,为读者提供备电源、读者可自助选择位置,各个区采光良好,环境优美,读者可在休息时一览楼下的风景。', |
|||
image: '@/static/images/lib.png' |
|||
} |
|||
] |
|||
}; |
|||
}, |
|||
onLoad() { |
|||
this.loadSeatInfo(); |
|||
}, |
|||
methods: { |
|||
loadSeatInfo() { |
|||
console.log('加载座位信息'); |
|||
}, |
|||
onVenueChange(e) { |
|||
this.venueIndex = e.detail.value; |
|||
console.log('切换场馆:', this.venues[this.venueIndex]); |
|||
}, |
|||
bookingFloor(floor) { |
|||
uni.navigateTo({ |
|||
url: `/subpkg/pages/booking-detail/booking-detail?floor=${floor.floor}&title=${floor.title}` |
|||
}); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.seat-booking { |
|||
min-height: 100vh; |
|||
background-color: #f5f7fa; |
|||
} |
|||
|
|||
/* 顶部横幅 */ |
|||
.banner { |
|||
position: relative; |
|||
height: 140px; |
|||
} |
|||
.banner-bg { |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
.banner-overlay { |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
background-color: rgba(0, 0, 0, 0.2); |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
.banner-text { |
|||
color: #fff; |
|||
font-size: 20px; |
|||
font-weight: 500; |
|||
} |
|||
|
|||
.content { |
|||
padding: 16px; |
|||
// margin-top: -20px; |
|||
position: relative; |
|||
z-index: 10; |
|||
} |
|||
|
|||
/* 场馆选择下拉框 */ |
|||
.venue-select { |
|||
display: flex; |
|||
justify-content: flex-end; |
|||
margin-bottom: 16px; |
|||
} |
|||
.picker-content { |
|||
display: flex; |
|||
align-items: center; |
|||
gap: 4px; |
|||
padding: 8px 16px; |
|||
background-color: #fff; |
|||
border: 1px solid #ddd; |
|||
border-radius: 4px; |
|||
font-size: 14px; |
|||
color: #333; |
|||
} |
|||
|
|||
/* 楼层卡片 */ |
|||
.floor-list { |
|||
background-color: #fff; |
|||
border-radius: 12px; |
|||
padding: 16px; |
|||
box-shadow: 0 2px 8px rgba(0,0,0,0.05); |
|||
} |
|||
.floor-item { |
|||
margin-bottom: 16px; |
|||
padding-bottom: 16px; |
|||
border-bottom: 1px solid #eee; |
|||
&:last-child { |
|||
margin-bottom: 0; |
|||
padding-bottom: 0; |
|||
border-bottom: none; |
|||
} |
|||
} |
|||
|
|||
.floor-name { |
|||
display: block; |
|||
font-size: 16px; |
|||
font-weight: bold; |
|||
padding-bottom: 8px; |
|||
} |
|||
.floor-info{ |
|||
display: inline-flex; |
|||
align-items: flex-start; |
|||
justify-content: space-between; |
|||
} |
|||
|
|||
.floor-left { |
|||
position: relative; |
|||
width: 90px; |
|||
height: 100px; |
|||
border-radius: 8px; |
|||
margin-right: 12px; |
|||
} |
|||
|
|||
.floor-image { |
|||
width: 90px; |
|||
height: 100px; |
|||
|
|||
object-fit: cover; |
|||
} |
|||
.floor-title { |
|||
position: absolute; |
|||
bottom: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
text-align: center; |
|||
padding: 4px 0; |
|||
background-color: rgba(0, 0, 0, 0.5); |
|||
color: #fff; |
|||
// font-weight: bold; |
|||
font-size: 12px; |
|||
// font-weight: bold; |
|||
} |
|||
|
|||
.floor-right { |
|||
flex: 1; |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: space-between; |
|||
} |
|||
|
|||
.floor-desc { |
|||
font-size: 13px; |
|||
color: #666; |
|||
line-height: 1.5; |
|||
margin-bottom: 8px; |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
display: -webkit-box; |
|||
-webkit-box-orient: vertical; |
|||
-webkit-line-clamp: 3; |
|||
} |
|||
.booking-btn { |
|||
background-color: #01a4fe; |
|||
color: #fff; |
|||
font-size: 14px; |
|||
padding: 0 20px; |
|||
border: none; |
|||
margin: 6px 0 0 0; |
|||
height: 30px; |
|||
line-height: 30px; |
|||
} |
|||
.booking-btn::after { |
|||
border: none; |
|||
} |
|||
</style> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue