|
|
@@ -1,976 +1,826 @@
|
|
|
<template>
|
|
|
- <view class="hotel-page">
|
|
|
- <!-- 顶部导航栏 -->
|
|
|
- <view class="hotel-nav" :style="{ paddingTop: statusBarHeight + 'px' }">
|
|
|
- <view class="nav-row">
|
|
|
- <view class="nav-back" @tap="goBack">
|
|
|
- <text class="nav-back-icon">‹</text>
|
|
|
+ <view class="page-wrap">
|
|
|
+ <!-- ===== 顶部渐变导航栏 ===== -->
|
|
|
+ <view class="header-gradient">
|
|
|
+ <view class="nav-bar flex-between">
|
|
|
+ <!-- 返回按钮 -->
|
|
|
+ <view class="nav-btn" @click="goBack">
|
|
|
+ <text class="wlIcon wlIcon-fanhui1"></text>
|
|
|
</view>
|
|
|
+ <!-- 页面标题 -->
|
|
|
<text class="nav-title">酒店</text>
|
|
|
- <view class="nav-order" @tap="goOrder">
|
|
|
- <text class="nav-order-icon"></text>
|
|
|
- <text class="nav-order-text">订单</text>
|
|
|
+ <!-- 订单按钮 -->
|
|
|
+ <view class="nav-btn" @click="toOrder">
|
|
|
+ <text class="btn-text">订单</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
-
|
|
|
- <!-- 类型标签 -->
|
|
|
- <view class="type-tabs">
|
|
|
- <view
|
|
|
- v-for="(tab, index) in typeTabs"
|
|
|
- :key="index"
|
|
|
- class="type-tab"
|
|
|
- :class="{ 'type-tab--active': activeTypeTab === index }"
|
|
|
- @tap="selectTypeTab(index)"
|
|
|
- >
|
|
|
- <text class="type-tab__text">{{ tab }}</text>
|
|
|
+ <!-- Tab栏(国内/国际/钟点房/民宿/短租) -->
|
|
|
+ <view class="tab-wrap">
|
|
|
+ <view v-for="(item, index) in tabList" :key="index" class="tab-item" :class="{ active: currentTab === index }"
|
|
|
+ @click="switchTab(index)">
|
|
|
+ {{ item.label }}
|
|
|
</view>
|
|
|
</view>
|
|
|
-
|
|
|
- <!-- 滚动内容区域 -->
|
|
|
- <scroll-view scroll-y class="content-scroll" :style="{ height: scrollHeight + 'px' }">
|
|
|
- <!-- 搜索区域 -->
|
|
|
- <view class="search-section">
|
|
|
- <!-- 城市和搜索框 -->
|
|
|
- <view class="search-header">
|
|
|
- <view class="city-selector" @tap="openCityPicker">
|
|
|
- <text class="city-selector__text">{{ cityName || '选择城市' }}</text>
|
|
|
- <text class="city-selector__arrow">▾</text>
|
|
|
- </view>
|
|
|
- <view class="search-input" @tap="goSearch">
|
|
|
- <text class="search-input__icon">🔍</text>
|
|
|
- <text class="search-input__placeholder">位置/品牌/酒店</text>
|
|
|
- </view>
|
|
|
- <view class="location-btn" @tap="openLocation">
|
|
|
- <text class="location-btn__icon">📍</text>
|
|
|
- </view>
|
|
|
+ <!-- ===== 筛选白色卡片区域 ===== -->
|
|
|
+ <view class="filter-card">
|
|
|
+ <!-- 城市选择 + 搜索框 + 定位按钮 -->
|
|
|
+ <view class="city-search-row flex-between">
|
|
|
+ <!-- 城市选择器 -->
|
|
|
+ <view class="city-select" @click="selectCity">
|
|
|
+ <text class="city-text">{{ cityName }}</text>
|
|
|
+ <text class="wlIcon wlIcon-fanhui4"></text>
|
|
|
</view>
|
|
|
-
|
|
|
- <!-- 定位提示条 -->
|
|
|
- <view class="location-tip" @tap="openLocation">
|
|
|
- <text class="location-tip__icon">📍</text>
|
|
|
- <text class="location-tip__text">开启定位权限,发现附近优质酒店</text>
|
|
|
- <text class="location-tip__action">去开启 ›</text>
|
|
|
+ <!-- 搜索输入框 -->
|
|
|
+ <view class="search-input-box" @click="openSearch">
|
|
|
+ <text class="search-icon">🔍</text>
|
|
|
+ <text class="search-placeholder">位置/品牌/酒店</text>
|
|
|
</view>
|
|
|
-
|
|
|
- <!-- 日期选择 -->
|
|
|
- <view class="date-section">
|
|
|
- <view class="date-item" @tap="openDatePicker">
|
|
|
- <text class="date-item__month">{{ checkInMonth }}月</text>
|
|
|
- <text class="date-item__day">{{ checkInDay }}</text>
|
|
|
- <text class="date-item__label">{{ checkInLabel }}</text>
|
|
|
- </view>
|
|
|
- <view class="date-nights">
|
|
|
- <text class="date-nights__text">{{ nights }}晚</text>
|
|
|
- </view>
|
|
|
- <view class="date-item date-item--right" @tap="openDatePicker">
|
|
|
- <text class="date-item__month">{{ checkOutMonth }}月</text>
|
|
|
- <text class="date-item__day">{{ checkOutDay }}</text>
|
|
|
- <text class="date-item__label">{{ checkOutLabel }}</text>
|
|
|
- </view>
|
|
|
+ <!-- 定位按钮 -->
|
|
|
+ <view class="loc-btn" @click="openLocation">
|
|
|
+ <text class="loc-icon">⚙</text>
|
|
|
</view>
|
|
|
+ </view>
|
|
|
+ <view class="divider"></view>
|
|
|
+ <!-- 定位提示条 -->
|
|
|
+ <view class="location-tip flex-between" @click="goOpenSetting">
|
|
|
+ <view class="tip-left flex-row">
|
|
|
+ <text class="tip-icon">📍</text>
|
|
|
+ <text class="tip-text">开启定位权限,发现附近优质酒店</text>
|
|
|
+ </view>
|
|
|
+ <text class="tip-link">去开启 ›</text>
|
|
|
+ </view>
|
|
|
|
|
|
- <!-- 房间人数和筛选 -->
|
|
|
- <view class="room-section">
|
|
|
- <view class="room-selector" @tap="openPassengerPicker">
|
|
|
- <text class="room-selector__text">{{ roomText }}</text>
|
|
|
- <text class="room-selector__arrow">▾</text>
|
|
|
- </view>
|
|
|
- <view class="filter-btn" @tap="openFilter">
|
|
|
- <text class="filter-btn__text">价格/星级</text>
|
|
|
+ <!-- 日期选择区域(入住日期 - 晚数 - 离店日期) -->
|
|
|
+ <view class="date-row flex-between">
|
|
|
+ <!-- 入住日期 -->
|
|
|
+ <view class="date-block" @click="pickCheckIn">
|
|
|
+ <text class="date-month">{{ checkInMonth }}月</text>
|
|
|
+ <text class="date-num">{{ checkInDay }}</text>
|
|
|
+ <text class="date-desc">{{ checkInLabel }}</text>
|
|
|
+ </view>
|
|
|
+ <!-- 入住晚数 -->
|
|
|
+ <view class="night-tag">{{ nightCount }}晚</view>
|
|
|
+ <!-- 离店日期 -->
|
|
|
+ <view class="date-block" @click="pickCheckOut">
|
|
|
+ <text class="date-month">{{ checkOutMonth }}月</text>
|
|
|
+ <text class="date-num">{{ checkOutDay }}</text>
|
|
|
+ <text class="date-desc">{{ checkOutLabel }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="divider"></view>
|
|
|
+
|
|
|
+ <!-- 房间人数选择 + 价格星级筛选 -->
|
|
|
+ <view class="guest-row flex-between">
|
|
|
+ <!-- 房间人数选择器 -->
|
|
|
+ <view class="guest-select flex-row" @click="selectGuest">
|
|
|
+ <text>{{ roomDesc }}</text>
|
|
|
+ <text class="wlIcon wlIcon-fanhui4 "></text>
|
|
|
+ </view>
|
|
|
+ <!-- 价格/星级筛选 -->
|
|
|
+ <text class="filter-text">价格/星级</text>
|
|
|
+ </view>
|
|
|
+ <view class="divider"></view>
|
|
|
+
|
|
|
+ <!-- 快捷标签横向滚动(亲子出游/环球影城等) -->
|
|
|
+ <scroll-view scroll-x class="tag-scroll" :show-scrollbar="false">
|
|
|
+ <view class="tag-list flex-row">
|
|
|
+ <view v-for="(tag, idx) in hotTagList" :key="idx" class="tag-item" :class="{ active: activeTagIdx === idx }"
|
|
|
+ @click="onTagClick(idx)">
|
|
|
+ {{ tag }}
|
|
|
</view>
|
|
|
</view>
|
|
|
+ </scroll-view>
|
|
|
|
|
|
- <!-- 快捷标签 -->
|
|
|
- <scroll-view scroll-x class="quick-tags" :show-scrollbar="false">
|
|
|
- <view
|
|
|
- v-for="(tag, index) in quickTags"
|
|
|
- :key="index"
|
|
|
- class="quick-tag"
|
|
|
- :class="{ 'quick-tag--active': activeTag === index }"
|
|
|
- @tap="selectTag(index)"
|
|
|
- >
|
|
|
- <text class="quick-tag__text">{{ tag }}</text>
|
|
|
- </view>
|
|
|
- </scroll-view>
|
|
|
+ <!-- 搜索酒店按钮 -->
|
|
|
+ <button class="search-btn" @click="searchHotel">搜索酒店</button>
|
|
|
+ </view>
|
|
|
|
|
|
- <!-- 搜索按钮 -->
|
|
|
- <view class="search-btn" @tap="onSearch">
|
|
|
- <text class="search-btn__text">搜索酒店</text>
|
|
|
- </view>
|
|
|
+ <!-- ===== 最受欢迎酒店横向滚动列表 ===== -->
|
|
|
+ <view class="hot-section">
|
|
|
+ <view class="section-head flex-between">
|
|
|
+ <text class="section-title">最受欢迎</text>
|
|
|
+ <text class="more-link" @click="lookMoreHot">查看全部 ›</text>
|
|
|
</view>
|
|
|
-
|
|
|
- <!-- 最受欢迎 -->
|
|
|
- <view class="section">
|
|
|
- <view class="section-header">
|
|
|
- <text class="section-title">最受欢迎</text>
|
|
|
- <text class="section-more" @tap="goMore">查看全部 ›</text>
|
|
|
- </view>
|
|
|
- <scroll-view scroll-x class="hot-scroll" :show-scrollbar="false">
|
|
|
- <view class="hot-list">
|
|
|
- <view
|
|
|
- v-for="(hotel, index) in hotHotels"
|
|
|
- :key="hotel.id"
|
|
|
- class="hot-item"
|
|
|
- @tap="goHotelDetail(hotel)"
|
|
|
- >
|
|
|
- <image class="hot-item__image" :src="hotel.image" mode="aspectFill" />
|
|
|
- <view class="hot-item__favorite">
|
|
|
- <text class="hot-item__favorite-icon">❤️</text>
|
|
|
- </view>
|
|
|
- <view class="hot-item__info">
|
|
|
- <text class="hot-item__name">{{ hotel.name }}</text>
|
|
|
- <text class="hot-item__address">{{ hotel.address }}</text>
|
|
|
- <view class="hot-item__bottom">
|
|
|
- <view class="hot-item__price">
|
|
|
- <text class="hot-item__price-symbol">¥</text>
|
|
|
- <text class="hot-item__price-value">{{ hotel.price }}</text>
|
|
|
- <text class="hot-item__price-unit">/晚</text>
|
|
|
- </view>
|
|
|
- <view class="hot-item__score">
|
|
|
- <text class="hot-item__score-icon">⭐</text>
|
|
|
- <text class="hot-item__score-value">{{ hotel.score }}</text>
|
|
|
- </view>
|
|
|
+ <scroll-view scroll-x class="hot-card-scroll" :show-scrollbar="false">
|
|
|
+ <view class="hot-card-list flex-row">
|
|
|
+ <view v-for="(hotel, idx) in hotHotelList" :key="idx" class="hot-card" @click="goHotelDetail(hotel)">
|
|
|
+ <!-- 收藏按钮(右上角心形) -->
|
|
|
+ <view class="collect-btn" @click.stop="toggleCollect(hotel)">
|
|
|
+ <text class="heart">{{ hotel.collect ? '❤️' : '' }}</text>
|
|
|
+ </view>
|
|
|
+ <!-- 酒店封面图片(暂时留空,后端接口就绪后替换) -->
|
|
|
+ <image class="card-img" :src="hotel.img" mode="aspectFill"></image>
|
|
|
+ <!-- 酒店信息 -->
|
|
|
+ <view class="card-info">
|
|
|
+ <text class="card-name">{{ hotel.name }}</text>
|
|
|
+ <text class="card-address">{{ hotel.address }}</text>
|
|
|
+ <view class="card-bottom flex-between">
|
|
|
+ <text class="card-price">{{ hotel.price }}</text>
|
|
|
+ <view class="score-box flex-row">
|
|
|
+ <text class="score-star">⭐</text>
|
|
|
+ <text class="score">{{ hotel.score }}</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
- </scroll-view>
|
|
|
- </view>
|
|
|
-
|
|
|
- <!-- 推荐给你 -->
|
|
|
- <view class="section">
|
|
|
- <view class="section-header">
|
|
|
- <text class="section-title">推荐给你</text>
|
|
|
- <text class="section-more" @tap="goMore">查看全部 ›</text>
|
|
|
</view>
|
|
|
-
|
|
|
- <!-- 分类标签 -->
|
|
|
- <view class="category-tabs">
|
|
|
- <view
|
|
|
- v-for="(cat, index) in categoryTabs"
|
|
|
- :key="index"
|
|
|
- class="category-tab"
|
|
|
- :class="{ 'category-tab--active': activeCategory === index }"
|
|
|
- @tap="selectCategory(index)"
|
|
|
- >
|
|
|
- <text class="category-tab__icon">{{ cat.icon }}</text>
|
|
|
- <text class="category-tab__text">{{ cat.name }}</text>
|
|
|
+ </scroll-view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- ===== 推荐给你列表 ===== -->
|
|
|
+ <view class="recommend-section">
|
|
|
+ <view class="section-head flex-between">
|
|
|
+ <text class="section-title">推荐给你</text>
|
|
|
+ <text class="more-link" @click="lookMoreRec">查看全部 ›</text>
|
|
|
+ </view>
|
|
|
+ <!-- 分类标签(所有/别墅/酒店/民宿) -->
|
|
|
+ <scroll-view scroll-x class="cate-scroll" :show-scrollbar="false">
|
|
|
+ <view class="cate-list flex-row">
|
|
|
+ <view v-for="(cate, idx) in cateList" :key="idx" class="cate-item" :class="{ active: activeCateIdx === idx }"
|
|
|
+ @click="onCateClick(idx)">
|
|
|
+ {{ cate.label }}
|
|
|
</view>
|
|
|
</view>
|
|
|
-
|
|
|
- <!-- 推荐列表 -->
|
|
|
- <view class="recommend-list">
|
|
|
- <view
|
|
|
- v-for="hotel in recommendHotels"
|
|
|
- :key="hotel.id"
|
|
|
- class="recommend-item"
|
|
|
- @tap="goHotelDetail(hotel)"
|
|
|
- >
|
|
|
- <image class="recommend-item__image" :src="hotel.image" mode="aspectFill" />
|
|
|
- <view class="recommend-item__content">
|
|
|
- <view class="recommend-item__header">
|
|
|
- <text class="recommend-item__name">{{ hotel.name }}</text>
|
|
|
- <view class="recommend-item__score">
|
|
|
- <text class="recommend-item__score-icon">⭐</text>
|
|
|
- <text class="recommend-item__score-value">{{ hotel.score }}</text>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- <text class="recommend-item__address">📍 {{ hotel.address }}</text>
|
|
|
- <view class="recommend-item__price">
|
|
|
- <text class="recommend-item__price-value">{{ hotel.price }}元/晚</text>
|
|
|
+ </scroll-view>
|
|
|
+ <!-- 酒店列表 -->
|
|
|
+ <view class="rec-list">
|
|
|
+ <view v-for="(item, idx) in recHotelList" :key="idx" class="rec-item flex-row" @click="goHotelDetail(item)">
|
|
|
+ <!-- 酒店封面图片(暂时留空,后端接口就绪后替换) -->
|
|
|
+ <image class="rec-img" :src="item.img" mode="aspectFill"></image>
|
|
|
+ <view class="rec-info flex-col ">
|
|
|
+ <view class="rec-top flex-between">
|
|
|
+ <text class="rec-name">{{ item.name }}</text>
|
|
|
+ <view class="score-box flex-row">
|
|
|
+ <text class="score-star">⭐</text>
|
|
|
+ <text class="score">{{ item.score }}</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
+ <view class="rec-address flex-row">
|
|
|
+ <text class="addr-icon">📍</text>
|
|
|
+ <text class="addr-text">{{ item.address }}</text>
|
|
|
+ </view>
|
|
|
+ <text class="rec-price">{{ item.price }}</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
-
|
|
|
- <uni-load-more :status="loadStatus" />
|
|
|
</view>
|
|
|
- </scroll-view>
|
|
|
-
|
|
|
- <!-- 城市选择器 -->
|
|
|
- <city-picker
|
|
|
- v-model="selectedCity"
|
|
|
- @change="onCityChange"
|
|
|
- />
|
|
|
-
|
|
|
- <!-- 日期选择器 -->
|
|
|
- <date-range-picker
|
|
|
- :check-in="checkInDate"
|
|
|
- :check-out="checkOutDate"
|
|
|
- @confirm="onDateConfirm"
|
|
|
- />
|
|
|
-
|
|
|
- <!-- 人数选择器 -->
|
|
|
- <passenger-picker
|
|
|
- @confirm="onPassengerConfirm"
|
|
|
- />
|
|
|
+ </view>
|
|
|
</view>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import CityPicker from '@/components/travel/city-picker/city-picker.vue'
|
|
|
-import DateRangePicker from '@/components/travel/date-range-picker/date-range-picker.vue'
|
|
|
-import PassengerPicker from '@/components/travel/passenger-picker/passenger-picker.vue'
|
|
|
-import { pullHotelList, pullHotelRecommend } from '@/features/travel/travel-gateway.js'
|
|
|
-
|
|
|
export default {
|
|
|
- components: {
|
|
|
- CityPicker,
|
|
|
- DateRangePicker,
|
|
|
- PassengerPicker
|
|
|
- },
|
|
|
data() {
|
|
|
return {
|
|
|
- statusBarHeight: 0,
|
|
|
- scrollHeight: 0,
|
|
|
- typeTabs: ['国内', '国际', '钟点房', '民宿', '短租'],
|
|
|
- activeTypeTab: 0,
|
|
|
+ // 城市名称
|
|
|
cityName: '北京',
|
|
|
- selectedCity: '',
|
|
|
- checkInDate: '',
|
|
|
- checkOutDate: '',
|
|
|
+ // Tab栏数据
|
|
|
+ tabList: [
|
|
|
+ { label: '国内' },
|
|
|
+ { label: '国际' },
|
|
|
+ { label: '钟点房' },
|
|
|
+ { label: '民宿' },
|
|
|
+ { label: '短租' }
|
|
|
+ ],
|
|
|
+ currentTab: 0,
|
|
|
+ // 日期数据
|
|
|
checkInMonth: 7,
|
|
|
checkInDay: 20,
|
|
|
checkInLabel: '今天',
|
|
|
checkOutMonth: 7,
|
|
|
checkOutDay: 21,
|
|
|
checkOutLabel: '明天',
|
|
|
- nights: 1,
|
|
|
- roomText: '1 间房 2 成人 1 儿童',
|
|
|
- passengerInfo: {
|
|
|
- room: 1,
|
|
|
- adult: 2,
|
|
|
- child: 1,
|
|
|
- infant: 0
|
|
|
- },
|
|
|
- quickTags: ['亲子出游', '环球影城', '天安门广场', '鸟巢', '故宫', '迪士尼'],
|
|
|
- activeTag: 0,
|
|
|
- categoryTabs: [
|
|
|
- { name: '所有', icon: '' },
|
|
|
- { name: '别墅', icon: '🏡' },
|
|
|
- { name: '酒店', icon: '🏨' },
|
|
|
- { name: '民宿', icon: '🏠' }
|
|
|
+ nightCount: 1,
|
|
|
+ // 房间人数
|
|
|
+ roomCount: 1,
|
|
|
+ adultCount: 2,
|
|
|
+ childCount: 1,
|
|
|
+ // 快捷标签
|
|
|
+ hotTagList: ['亲子出游', '环球影城', '天安门广场', '鸟巢', '故宫'],
|
|
|
+ activeTagIdx: 0,
|
|
|
+ // 分类标签
|
|
|
+ cateList: [
|
|
|
+ { label: '所有' },
|
|
|
+ { label: ' 别墅' },
|
|
|
+ { label: '🏨 酒店' },
|
|
|
+ { label: '🏢 民宿' }
|
|
|
],
|
|
|
- activeCategory: 0,
|
|
|
- hotHotels: [],
|
|
|
- recommendHotels: [],
|
|
|
- loadStatus: 'more',
|
|
|
- pageIndex: 1,
|
|
|
- pageSize: 10
|
|
|
+ activeCateIdx: 0,
|
|
|
+ // 横向卡片【最受欢迎】酒店数据
|
|
|
+ hotHotelList: [
|
|
|
+ {
|
|
|
+ name: '地平线撤退',
|
|
|
+ address: '加利福尼亚州洛杉矶',
|
|
|
+ price: '480元/晚',
|
|
|
+ score: '4.5',
|
|
|
+ collect: true,
|
|
|
+ img: ''
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '阿斯特拉大酒店',
|
|
|
+ address: '纽约州纽约市',
|
|
|
+ price: '每晚300元',
|
|
|
+ score: '4.5',
|
|
|
+ collect: false,
|
|
|
+ img: ''
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ // 竖向【推荐给你】酒店列表
|
|
|
+ recHotelList: [
|
|
|
+ {
|
|
|
+ name: '宁静沙滩',
|
|
|
+ address: '檀香山,你好',
|
|
|
+ price: '270元/晚',
|
|
|
+ score: '4.0',
|
|
|
+ img: ''
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '极乐套房',
|
|
|
+ address: '加利福尼亚州圣地亚哥',
|
|
|
+ price: '320元/晚',
|
|
|
+ score: '3.8',
|
|
|
+ img: ''
|
|
|
+ }
|
|
|
+ ]
|
|
|
}
|
|
|
},
|
|
|
- created() {
|
|
|
- this.initPage()
|
|
|
- },
|
|
|
- onShow() {
|
|
|
- this.loadData()
|
|
|
- this.loadHotHotels()
|
|
|
+ computed: {
|
|
|
+ // 房间人数描述
|
|
|
+ roomDesc() {
|
|
|
+ const parts = [`${this.roomCount}间房`, `${this.adultCount}成人`]
|
|
|
+ if (this.childCount > 0) parts.push(`${this.childCount}儿童`)
|
|
|
+ return parts.join(' ')
|
|
|
+ }
|
|
|
},
|
|
|
methods: {
|
|
|
- initPage() {
|
|
|
- const sys = uni.getSystemInfoSync()
|
|
|
- this.statusBarHeight = sys.statusBarHeight || 0
|
|
|
- this.scrollHeight = sys.windowHeight - uni.upx2px(600)
|
|
|
- this.setDefaultDates()
|
|
|
+ // 切换tab
|
|
|
+ switchTab(index) {
|
|
|
+ this.currentTab = index
|
|
|
},
|
|
|
- setDefaultDates() {
|
|
|
- const today = new Date()
|
|
|
- const tomorrow = new Date()
|
|
|
- tomorrow.setDate(today.getDate() + 1)
|
|
|
- this.checkInDate = this.formatDate(today)
|
|
|
- this.checkOutDate = this.formatDate(tomorrow)
|
|
|
- this.checkInMonth = today.getMonth() + 1
|
|
|
- this.checkInDay = today.getDate()
|
|
|
- this.checkOutMonth = tomorrow.getMonth() + 1
|
|
|
- this.checkOutDay = tomorrow.getDate()
|
|
|
+ // 返回上一页
|
|
|
+ goBack() {
|
|
|
+ uni.navigateBack()
|
|
|
},
|
|
|
- formatDate(date) {
|
|
|
- const year = date.getFullYear()
|
|
|
- const month = String(date.getMonth() + 1).padStart(2, '0')
|
|
|
- const day = String(date.getDate()).padStart(2, '0')
|
|
|
- return `${year}-${month}-${day}`
|
|
|
+ // 订单页面
|
|
|
+ toOrder() {
|
|
|
+ uni.navigateTo({ url: '/pages/order/order' })
|
|
|
},
|
|
|
- selectTypeTab(index) {
|
|
|
- this.activeTypeTab = index
|
|
|
+ // 搜索酒店
|
|
|
+ searchHotel() {
|
|
|
+ uni.showToast({ title: '搜索酒店' })
|
|
|
},
|
|
|
- openCityPicker() {
|
|
|
- uni.showToast({
|
|
|
- title: '打开城市选择器',
|
|
|
- icon: 'none'
|
|
|
- })
|
|
|
+ // 选择城市
|
|
|
+ selectCity() {
|
|
|
+ uni.navigateTo({ url: '/pages/travel/city-picker' })
|
|
|
},
|
|
|
- onCityChange(city) {
|
|
|
- this.cityName = city.name || city
|
|
|
- this.selectedCity = city
|
|
|
- },
|
|
|
- goSearch() {
|
|
|
- uni.navigateTo({
|
|
|
- url: '/pages/travel/hotel/search'
|
|
|
- })
|
|
|
+ // 打开搜索
|
|
|
+ openSearch() {
|
|
|
+ uni.navigateTo({ url: '/pages/travel/hotel/hotel-search' })
|
|
|
},
|
|
|
+ // 打开定位
|
|
|
openLocation() {
|
|
|
- uni.showToast({
|
|
|
- title: '打开定位',
|
|
|
- icon: 'none'
|
|
|
- })
|
|
|
- },
|
|
|
- openDatePicker() {
|
|
|
- uni.showToast({
|
|
|
- title: '打开日期选择器',
|
|
|
- icon: 'none'
|
|
|
- })
|
|
|
- },
|
|
|
- onDateConfirm({ checkIn, checkOut, nights }) {
|
|
|
- this.checkInDate = checkIn
|
|
|
- this.checkOutDate = checkOut
|
|
|
- this.nights = nights
|
|
|
- const checkInDate = new Date(checkIn)
|
|
|
- const checkOutDate = new Date(checkOut)
|
|
|
- this.checkInMonth = checkInDate.getMonth() + 1
|
|
|
- this.checkInDay = checkInDate.getDate()
|
|
|
- this.checkOutMonth = checkOutDate.getMonth() + 1
|
|
|
- this.checkOutDay = checkOutDate.getDate()
|
|
|
- },
|
|
|
- openPassengerPicker() {
|
|
|
- uni.showToast({
|
|
|
- title: '打开人数选择器',
|
|
|
- icon: 'none'
|
|
|
- })
|
|
|
- },
|
|
|
- onPassengerConfirm(data) {
|
|
|
- this.passengerInfo = data
|
|
|
- this.roomText = `${data.room}间房 ${data.adult}成人 ${data.child}儿童`
|
|
|
- },
|
|
|
- openFilter() {
|
|
|
- uni.navigateTo({
|
|
|
- url: '/pages/travel/hotel/filter'
|
|
|
+ uni.getLocation({
|
|
|
+ type: 'gcj02',
|
|
|
+ success: (res) => {
|
|
|
+ console.log('定位成功', res)
|
|
|
+ },
|
|
|
+ fail: () => {
|
|
|
+ uni.showToast({ title: '定位失败', icon: 'none' })
|
|
|
+ }
|
|
|
})
|
|
|
},
|
|
|
- selectTag(index) {
|
|
|
- this.activeTag = index
|
|
|
+ // 去开启定位权限
|
|
|
+ goOpenSetting() {
|
|
|
+ uni.openSetting()
|
|
|
},
|
|
|
- onSearch() {
|
|
|
- uni.navigateTo({
|
|
|
- url: '/pages/travel/hotel/list'
|
|
|
- })
|
|
|
+ // 选择入住日期
|
|
|
+ pickCheckIn() {
|
|
|
+ uni.showToast({ title: '选择入住日期' })
|
|
|
},
|
|
|
- selectCategory(index) {
|
|
|
- this.activeCategory = index
|
|
|
- this.pageIndex = 1
|
|
|
- this.recommendHotels = []
|
|
|
- this.loadData()
|
|
|
+ // 选择离店日期
|
|
|
+ pickCheckOut() {
|
|
|
+ uni.showToast({ title: '选择离店日期' })
|
|
|
},
|
|
|
- async loadData() {
|
|
|
- if (this.loadStatus === 'noMore') return
|
|
|
- this.loadStatus = 'loading'
|
|
|
- try {
|
|
|
- const result = await pullHotelList({
|
|
|
- cityName: this.cityName,
|
|
|
- checkInDate: this.checkInDate,
|
|
|
- checkOutDate: this.checkOutDate,
|
|
|
- pageIndex: this.pageIndex,
|
|
|
- pageSize: this.pageSize
|
|
|
- })
|
|
|
- if (result && result.hotelList) {
|
|
|
- if (this.pageIndex === 1) {
|
|
|
- this.recommendHotels = result.hotelList
|
|
|
- } else {
|
|
|
- this.recommendHotels = [...this.recommendHotels, ...result.hotelList]
|
|
|
- }
|
|
|
- this.loadStatus = result.hotelList.length < this.pageSize ? 'noMore' : 'more'
|
|
|
- } else {
|
|
|
- this.loadStatus = 'noMore'
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- console.error('加载酒店列表失败:', error)
|
|
|
- this.loadStatus = 'more'
|
|
|
- }
|
|
|
+ // 选择入住人数
|
|
|
+ selectGuest() {
|
|
|
+ uni.navigateTo({ url: '/pages/travel/hotel/room-picker' })
|
|
|
},
|
|
|
- async loadHotHotels() {
|
|
|
- try {
|
|
|
- const result = await pullHotelRecommend({
|
|
|
- pageSize: 10
|
|
|
- })
|
|
|
- if (result && result.hotelList) {
|
|
|
- this.hotHotels = result.hotelList
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- console.error('加载热门酒店失败:', error)
|
|
|
- }
|
|
|
+ // 热门标签点击
|
|
|
+ onTagClick(idx) {
|
|
|
+ this.activeTagIdx = idx
|
|
|
},
|
|
|
- goHotelDetail(hotel) {
|
|
|
- uni.navigateTo({
|
|
|
- url: `/pages/travel/hotel/detail?id=${hotel.id}`
|
|
|
- })
|
|
|
+ // 分类标签点击
|
|
|
+ onCateClick(idx) {
|
|
|
+ this.activeCateIdx = idx
|
|
|
},
|
|
|
- goOrder() {
|
|
|
- uni.navigateTo({
|
|
|
- url: '/pages/travel/hotel/order-list'
|
|
|
- })
|
|
|
+ // 切换收藏
|
|
|
+ toggleCollect(hotel) {
|
|
|
+ hotel.collect = !hotel.collect
|
|
|
},
|
|
|
- goBack() {
|
|
|
- uni.navigateBack()
|
|
|
+ // 查看更多
|
|
|
+ lookMoreHot() { },
|
|
|
+ lookMoreRec() {
|
|
|
+ uni.navigateTo({ url: '/pages/travel/hotel/hotel-list' })
|
|
|
},
|
|
|
- goMore() {
|
|
|
- uni.navigateTo({
|
|
|
- url: '/pages/travel/hotel/list'
|
|
|
- })
|
|
|
- }
|
|
|
- },
|
|
|
- onReachBottom() {
|
|
|
- if (this.loadStatus === 'more') {
|
|
|
- this.pageIndex++
|
|
|
- this.loadData()
|
|
|
+ // 跳转酒店详情
|
|
|
+ goHotelDetail(item) {
|
|
|
+ console.log('跳转酒店详情:', item.name)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
-.hotel-page {
|
|
|
- background-color: #f5f7fa;
|
|
|
- min-height: 100vh;
|
|
|
-}
|
|
|
-
|
|
|
-.hotel-nav {
|
|
|
- background: linear-gradient(135deg, #74b9ff 0%, #a29bfe 100%);
|
|
|
- padding-bottom: 20rpx;
|
|
|
+page {
|
|
|
+ background-color: #f7f9fc;
|
|
|
+ margin: 0;
|
|
|
+ padding: 0;
|
|
|
}
|
|
|
|
|
|
-.nav-row {
|
|
|
+.flex-row {
|
|
|
display: flex;
|
|
|
- justify-content: space-between;
|
|
|
+ flex-direction: row;
|
|
|
align-items: center;
|
|
|
- padding: 20rpx 30rpx;
|
|
|
}
|
|
|
|
|
|
-.nav-back {
|
|
|
- width: 60rpx;
|
|
|
- height: 60rpx;
|
|
|
- background-color: rgba(255, 255, 255, 0.9);
|
|
|
- border-radius: 16rpx;
|
|
|
+.flex-between {
|
|
|
display: flex;
|
|
|
- justify-content: center;
|
|
|
+ flex-direction: row;
|
|
|
+ justify-content: space-between;
|
|
|
align-items: center;
|
|
|
}
|
|
|
|
|
|
-.nav-back-icon {
|
|
|
- font-size: 40rpx;
|
|
|
- color: #333;
|
|
|
-}
|
|
|
-
|
|
|
-.nav-title {
|
|
|
- font-size: 36rpx;
|
|
|
- font-weight: 700;
|
|
|
- color: #fff;
|
|
|
-}
|
|
|
-
|
|
|
-.nav-order {
|
|
|
+.flex-col {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
- align-items: center;
|
|
|
- padding: 10rpx 20rpx;
|
|
|
- background-color: rgba(255, 255, 255, 0.9);
|
|
|
- border-radius: 16rpx;
|
|
|
}
|
|
|
|
|
|
-.nav-order-icon {
|
|
|
- font-size: 32rpx;
|
|
|
+.page-wrap {
|
|
|
+ min-height: 100vh;
|
|
|
}
|
|
|
|
|
|
-.nav-order-text {
|
|
|
- font-size: 20rpx;
|
|
|
- color: #333;
|
|
|
+/* ========== 顶部渐变导航栏 ========== */
|
|
|
+.header-gradient {
|
|
|
+ background: linear-gradient(90deg, #60d8f7, #3898f2);
|
|
|
+ padding: 16rpx 32rpx;
|
|
|
+ height: 200rpx;
|
|
|
}
|
|
|
|
|
|
-.type-tabs {
|
|
|
- display: flex;
|
|
|
- background-color: #fff;
|
|
|
- padding: 20rpx 30rpx;
|
|
|
- border-radius: 0 0 24rpx 24rpx;
|
|
|
-}
|
|
|
+.nav-bar {
|
|
|
+ margin-bottom: 16rpx;
|
|
|
|
|
|
-.type-tab {
|
|
|
- flex: 1;
|
|
|
- text-align: center;
|
|
|
- padding: 16rpx 0;
|
|
|
-}
|
|
|
+ .nav-btn {
|
|
|
+ width: 88rpx;
|
|
|
+ height: 88rpx;
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 20rpx;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
|
|
|
-.type-tab--active {
|
|
|
- position: relative;
|
|
|
-}
|
|
|
-
|
|
|
-.type-tab--active::after {
|
|
|
- content: '';
|
|
|
- position: absolute;
|
|
|
- bottom: 0;
|
|
|
- left: 50%;
|
|
|
- transform: translateX(-50%);
|
|
|
- width: 40rpx;
|
|
|
- height: 6rpx;
|
|
|
- background-color: #4a8cff;
|
|
|
- border-radius: 3rpx;
|
|
|
-}
|
|
|
+ .nav-icon {
|
|
|
+ font-size: 32rpx;
|
|
|
+ color: #333;
|
|
|
+ }
|
|
|
|
|
|
-.type-tab__text {
|
|
|
- font-size: 28rpx;
|
|
|
- color: #666;
|
|
|
-}
|
|
|
+ .btn-text {
|
|
|
+ font-size: 20rpx;
|
|
|
+ color: #333;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
-.type-tab--active .type-tab__text {
|
|
|
- color: #4a8cff;
|
|
|
- font-weight: 600;
|
|
|
+ .nav-title {
|
|
|
+ font-size: 52rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #222;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-.content-scroll {
|
|
|
- background-color: #f5f7fa;
|
|
|
-}
|
|
|
+/* ========== 筛选白色卡片 ========== */
|
|
|
+.filter-card {
|
|
|
+ margin: 0;
|
|
|
+ padding: 16rpx 24rpx;
|
|
|
|
|
|
-.search-section {
|
|
|
- background-color: #fff;
|
|
|
- padding: 30rpx;
|
|
|
- margin: 20rpx;
|
|
|
- border-radius: 24rpx;
|
|
|
}
|
|
|
|
|
|
-.search-header {
|
|
|
+/* Tab栏(渐变背景 + 选中白色圆角) */
|
|
|
+.tab-wrap {
|
|
|
display: flex;
|
|
|
- align-items: center;
|
|
|
- margin-bottom: 20rpx;
|
|
|
-}
|
|
|
+ background: linear-gradient(180deg, #daeef9, #f9fbfe);
|
|
|
+ border-radius: 36rpx 36rpx 0 0;
|
|
|
+ margin-top: -50rpx;
|
|
|
+ overflow: visible;
|
|
|
+
|
|
|
+ .tab-item {
|
|
|
+ flex: 1;
|
|
|
+ text-align: center;
|
|
|
+ padding: 10rpx;
|
|
|
+ font-size: 34rpx;
|
|
|
+ color: #667799;
|
|
|
+
|
|
|
+ // 第一个tab左上圆角
|
|
|
+ &:first-child {
|
|
|
+ border-radius: 36rpx 0 0 0;
|
|
|
+ }
|
|
|
|
|
|
-.city-selector {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- margin-right: 20rpx;
|
|
|
-}
|
|
|
+ // 最后一个tab右上圆角
|
|
|
+ &:last-child {
|
|
|
+ border-radius: 0 36rpx 0 0;
|
|
|
+ }
|
|
|
|
|
|
-.city-selector__text {
|
|
|
- font-size: 32rpx;
|
|
|
- font-weight: 600;
|
|
|
- color: #333;
|
|
|
+ &.active {
|
|
|
+ background-color: #ffffff;
|
|
|
+ color: #0066ff;
|
|
|
+ font-weight: bold;
|
|
|
+ border-radius: 24rpx 20rpx 0 0; // 选中状态圆角40rpx,比容器大4rpx
|
|
|
+ margin-top: -12rpx;
|
|
|
+ padding-top: 20rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-.city-selector__arrow {
|
|
|
- font-size: 20rpx;
|
|
|
- color: #999;
|
|
|
- margin-left: 8rpx;
|
|
|
-}
|
|
|
+/* 城市选择 + 搜索框 + 定位 */
|
|
|
+.city-search-row {
|
|
|
+ margin-bottom: 32rpx;
|
|
|
|
|
|
-.search-input {
|
|
|
- flex: 1;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- background-color: #f5f5f5;
|
|
|
- border-radius: 30rpx;
|
|
|
- padding: 16rpx 24rpx;
|
|
|
-}
|
|
|
+ .city-select {
|
|
|
+ .city-text {
|
|
|
+ font-size: 40rpx;
|
|
|
+ font-weight: 500;
|
|
|
+ color: #222;
|
|
|
+ }
|
|
|
|
|
|
-.search-input__icon {
|
|
|
- font-size: 28rpx;
|
|
|
- margin-right: 12rpx;
|
|
|
-}
|
|
|
+ .arrow {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #666;
|
|
|
+ margin-left: 8rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
-.search-input__placeholder {
|
|
|
- font-size: 26rpx;
|
|
|
- color: #999;
|
|
|
-}
|
|
|
+ .search-input-box {
|
|
|
+ flex: 1;
|
|
|
+ margin: 0 24rpx;
|
|
|
+ background-color: #f2f3f6;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ padding: 20rpx 24rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .search-icon {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #ccc;
|
|
|
+ margin-right: 8rpx;
|
|
|
+ }
|
|
|
|
|
|
-.location-btn {
|
|
|
- margin-left: 20rpx;
|
|
|
- padding: 12rpx;
|
|
|
-}
|
|
|
+ .search-placeholder {
|
|
|
+ flex: 1;
|
|
|
+ font-size: 30rpx;
|
|
|
+ color: #bbb;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
-.location-btn__icon {
|
|
|
- font-size: 36rpx;
|
|
|
+ .loc-btn {
|
|
|
+ .loc-icon {
|
|
|
+ font-size: 36rpx;
|
|
|
+ color: #0066ff;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
+/* 定位提示条 */
|
|
|
.location-tip {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- background-color: #f0f7ff;
|
|
|
- padding: 16rpx 20rpx;
|
|
|
- border-radius: 12rpx;
|
|
|
- margin-bottom: 24rpx;
|
|
|
-}
|
|
|
-
|
|
|
-.location-tip__icon {
|
|
|
- font-size: 28rpx;
|
|
|
- margin-right: 12rpx;
|
|
|
-}
|
|
|
-
|
|
|
-.location-tip__text {
|
|
|
- flex: 1;
|
|
|
- font-size: 24rpx;
|
|
|
- color: #4a8cff;
|
|
|
-}
|
|
|
-
|
|
|
-.location-tip__action {
|
|
|
- font-size: 24rpx;
|
|
|
- color: #4a8cff;
|
|
|
-}
|
|
|
-
|
|
|
-.date-section {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- margin-bottom: 20rpx;
|
|
|
-}
|
|
|
+ background-color: #e8f4ff;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ padding: 12rpx;
|
|
|
+ margin-bottom: 36rpx;
|
|
|
|
|
|
-.date-item {
|
|
|
- flex: 1;
|
|
|
- text-align: center;
|
|
|
- padding: 20rpx 0;
|
|
|
-}
|
|
|
+ .tip-left {
|
|
|
+ .tip-icon {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #0066ff;
|
|
|
+ margin-right: 8rpx;
|
|
|
+ }
|
|
|
|
|
|
-.date-item--right {
|
|
|
- border-left: 1rpx solid #eee;
|
|
|
-}
|
|
|
+ .tip-text {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #0052aa;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
-.date-item__month {
|
|
|
- display: block;
|
|
|
- font-size: 24rpx;
|
|
|
- color: #999;
|
|
|
- margin-bottom: 8rpx;
|
|
|
+ .tip-link {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #0066ff;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-.date-item__day {
|
|
|
- display: block;
|
|
|
- font-size: 40rpx;
|
|
|
- font-weight: 700;
|
|
|
- color: #333;
|
|
|
- margin-bottom: 8rpx;
|
|
|
-}
|
|
|
+/* 日期选择区域 */
|
|
|
+.date-row {
|
|
|
+ margin-bottom: 24rpx;
|
|
|
|
|
|
-.date-item__label {
|
|
|
- display: block;
|
|
|
- font-size: 22rpx;
|
|
|
- color: #999;
|
|
|
-}
|
|
|
+ .date-block {
|
|
|
+ display: flex;
|
|
|
+ align-items: baseline;
|
|
|
|
|
|
-.date-nights {
|
|
|
- padding: 0 20rpx;
|
|
|
-}
|
|
|
+ .date-month {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #666;
|
|
|
+ margin-right: 4rpx;
|
|
|
+ }
|
|
|
|
|
|
-.date-nights__text {
|
|
|
- font-size: 24rpx;
|
|
|
- color: #666;
|
|
|
- background-color: #f5f5f5;
|
|
|
- padding: 8rpx 20rpx;
|
|
|
- border-radius: 20rpx;
|
|
|
-}
|
|
|
+ .date-num {
|
|
|
+ font-size: 48rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #222;
|
|
|
+ }
|
|
|
|
|
|
-.room-section {
|
|
|
- display: flex;
|
|
|
- justify-content: space-between;
|
|
|
- align-items: center;
|
|
|
- margin-bottom: 20rpx;
|
|
|
- padding-bottom: 20rpx;
|
|
|
- border-bottom: 1rpx solid #f5f5f5;
|
|
|
-}
|
|
|
+ .date-desc {
|
|
|
+ font-size: 30rpx;
|
|
|
+ color: #999;
|
|
|
+ margin-left: 8rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
-.room-selector {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
+ .night-tag {
|
|
|
+ background-color: #f2f3f6;
|
|
|
+ padding: 8rpx 24rpx;
|
|
|
+ border-radius: 99rpx;
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #666;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-.room-selector__text {
|
|
|
- font-size: 26rpx;
|
|
|
- color: #333;
|
|
|
-}
|
|
|
+/* 房间人数 + 价格筛选 */
|
|
|
+.guest-row {
|
|
|
+ margin-bottom: 24rpx;
|
|
|
|
|
|
-.room-selector__arrow {
|
|
|
- font-size: 20rpx;
|
|
|
- color: #999;
|
|
|
- margin-left: 8rpx;
|
|
|
-}
|
|
|
+ .guest-select {
|
|
|
+ font-size: 34rpx;
|
|
|
+ color: #222;
|
|
|
|
|
|
-.filter-btn {
|
|
|
- padding: 12rpx 24rpx;
|
|
|
- background-color: #f5f5f5;
|
|
|
- border-radius: 20rpx;
|
|
|
-}
|
|
|
+ .arrow {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #999;
|
|
|
+ margin-left: 8rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
-.filter-btn__text {
|
|
|
- font-size: 24rpx;
|
|
|
- color: #666;
|
|
|
+ .filter-text {
|
|
|
+ font-size: 34rpx;
|
|
|
+ color: #888;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-.quick-tags {
|
|
|
- white-space: nowrap;
|
|
|
- margin-bottom: 24rpx;
|
|
|
+/* 分割线 */
|
|
|
+.divider {
|
|
|
+ width: 100%;
|
|
|
+ height: 1rpx;
|
|
|
+ background-color: #eeeeee;
|
|
|
+ margin-bottom: 32rpx;
|
|
|
}
|
|
|
|
|
|
-.quick-tag {
|
|
|
- display: inline-block;
|
|
|
- padding: 12rpx 24rpx;
|
|
|
- background-color: #f5f5f5;
|
|
|
- border-radius: 30rpx;
|
|
|
- margin-right: 16rpx;
|
|
|
+/* 快捷标签横向滚动 */
|
|
|
+.tag-scroll {
|
|
|
+ margin-bottom: 44rpx;
|
|
|
}
|
|
|
|
|
|
-.quick-tag--active {
|
|
|
- background-color: #fff0f0;
|
|
|
-}
|
|
|
+.tag-list {
|
|
|
+ gap: 24rpx;
|
|
|
|
|
|
-.quick-tag__text {
|
|
|
- font-size: 24rpx;
|
|
|
- color: #666;
|
|
|
-}
|
|
|
+ .tag-item {
|
|
|
+ padding: 14rpx 36rpx;
|
|
|
+ background-color: #f2f3f6;
|
|
|
+ border-radius: 24rpx;
|
|
|
+ font-size: 30rpx;
|
|
|
+ white-space: nowrap;
|
|
|
+ color: #666;
|
|
|
|
|
|
-.quick-tag--active .quick-tag__text {
|
|
|
- color: #ff6b6b;
|
|
|
+ &.active {
|
|
|
+ background-color: #ffe9ec;
|
|
|
+ color: #ff6b7b;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
+/* 搜索酒店按钮 */
|
|
|
.search-btn {
|
|
|
- background: linear-gradient(135deg, #4a8cff 0%, #667eea 100%);
|
|
|
- border-radius: 40rpx;
|
|
|
- padding: 24rpx 0;
|
|
|
- text-align: center;
|
|
|
-}
|
|
|
-
|
|
|
-.search-btn__text {
|
|
|
- font-size: 30rpx;
|
|
|
+ width: 100%;
|
|
|
+ background-color: #0066ff;
|
|
|
color: #fff;
|
|
|
- font-weight: 600;
|
|
|
-}
|
|
|
-
|
|
|
-.section {
|
|
|
- padding: 30rpx;
|
|
|
-}
|
|
|
-
|
|
|
-.section-header {
|
|
|
- display: flex;
|
|
|
- justify-content: space-between;
|
|
|
- align-items: center;
|
|
|
- margin-bottom: 24rpx;
|
|
|
-}
|
|
|
-
|
|
|
-.section-title {
|
|
|
- font-size: 32rpx;
|
|
|
- font-weight: 600;
|
|
|
- color: #333;
|
|
|
+ font-size: 40rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ border-radius: 50rpx;
|
|
|
+ // padding: 36rpx 0;
|
|
|
+ border: none;
|
|
|
+ box-shadow: 0 6rpx 16rpx rgba(0, 102, 255, 0.22);
|
|
|
}
|
|
|
|
|
|
-.section-more {
|
|
|
- font-size: 24rpx;
|
|
|
- color: #999;
|
|
|
+/* ========== 最受欢迎模块 ========== */
|
|
|
+.hot-section {
|
|
|
+ background-color: #fff;
|
|
|
+ padding: 0 32rpx 36rpx;
|
|
|
}
|
|
|
|
|
|
-.hot-scroll {
|
|
|
- white-space: nowrap;
|
|
|
-}
|
|
|
+.section-head {
|
|
|
+ padding: 36rpx 0 24rpx;
|
|
|
|
|
|
-.hot-list {
|
|
|
- display: inline-flex;
|
|
|
- gap: 20rpx;
|
|
|
-}
|
|
|
+ .section-title {
|
|
|
+ font-size: 40rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #222;
|
|
|
+ }
|
|
|
|
|
|
-.hot-item {
|
|
|
- width: 320rpx;
|
|
|
- position: relative;
|
|
|
- border-radius: 16rpx;
|
|
|
- overflow: hidden;
|
|
|
+ .more-link {
|
|
|
+ font-size: 30rpx;
|
|
|
+ color: #0066ff;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-.hot-item__image {
|
|
|
+.hot-card-scroll {
|
|
|
width: 100%;
|
|
|
- height: 240rpx;
|
|
|
-}
|
|
|
-
|
|
|
-.hot-item__favorite {
|
|
|
- position: absolute;
|
|
|
- top: 12rpx;
|
|
|
- right: 12rpx;
|
|
|
- width: 48rpx;
|
|
|
- height: 48rpx;
|
|
|
- background-color: rgba(255, 255, 255, 0.9);
|
|
|
- border-radius: 50%;
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- align-items: center;
|
|
|
-}
|
|
|
-
|
|
|
-.hot-item__favorite-icon {
|
|
|
- font-size: 24rpx;
|
|
|
-}
|
|
|
-
|
|
|
-.hot-item__info {
|
|
|
- position: absolute;
|
|
|
- bottom: 0;
|
|
|
- left: 0;
|
|
|
- right: 0;
|
|
|
- padding: 20rpx;
|
|
|
- background: linear-gradient(to top, rgba(0, 0, 0, 0.7), transparent);
|
|
|
}
|
|
|
|
|
|
-.hot-item__name {
|
|
|
- display: block;
|
|
|
- font-size: 28rpx;
|
|
|
- color: #fff;
|
|
|
- font-weight: 600;
|
|
|
- margin-bottom: 8rpx;
|
|
|
+.hot-card-list {
|
|
|
+ gap: 28rpx;
|
|
|
}
|
|
|
|
|
|
-.hot-item__address {
|
|
|
- display: block;
|
|
|
- font-size: 22rpx;
|
|
|
- color: rgba(255, 255, 255, 0.8);
|
|
|
- margin-bottom: 12rpx;
|
|
|
+.hot-card {
|
|
|
+ width: 540rpx;
|
|
|
+ border-radius: 28rpx;
|
|
|
overflow: hidden;
|
|
|
- text-overflow: ellipsis;
|
|
|
- white-space: nowrap;
|
|
|
-}
|
|
|
-
|
|
|
-.hot-item__bottom {
|
|
|
- display: flex;
|
|
|
- justify-content: space-between;
|
|
|
- align-items: center;
|
|
|
-}
|
|
|
-
|
|
|
-.hot-item__price {
|
|
|
- display: flex;
|
|
|
- align-items: baseline;
|
|
|
-}
|
|
|
-
|
|
|
-.hot-item__price-symbol {
|
|
|
- font-size: 22rpx;
|
|
|
- color: #fff;
|
|
|
- font-weight: 600;
|
|
|
-}
|
|
|
-
|
|
|
-.hot-item__price-value {
|
|
|
- font-size: 32rpx;
|
|
|
- color: #fff;
|
|
|
- font-weight: 700;
|
|
|
- margin: 0 4rpx;
|
|
|
-}
|
|
|
+ position: relative;
|
|
|
+ flex-shrink: 0;
|
|
|
+
|
|
|
+ .collect-btn {
|
|
|
+ position: absolute;
|
|
|
+ top: 20rpx;
|
|
|
+ right: 20rpx;
|
|
|
+ width: 64rpx;
|
|
|
+ height: 64rpx;
|
|
|
+ background-color: rgba(255, 255, 255, 0.7);
|
|
|
+ border-radius: 50%;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ z-index: 2;
|
|
|
+
|
|
|
+ .heart {
|
|
|
+ font-size: 32rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
-.hot-item__price-unit {
|
|
|
- font-size: 20rpx;
|
|
|
- color: rgba(255, 255, 255, 0.8);
|
|
|
-}
|
|
|
+ .card-img {
|
|
|
+ width: 100%;
|
|
|
+ height: 340rpx;
|
|
|
+ background-color: #f0f0f0;
|
|
|
+ }
|
|
|
|
|
|
-.hot-item__score {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
-}
|
|
|
+ .card-info {
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ bottom: 0;
|
|
|
+ width: 100%;
|
|
|
+ padding: 28rpx;
|
|
|
+ background: linear-gradient(to top, rgba(0, 0, 0, 0.65), transparent);
|
|
|
+ color: #fff;
|
|
|
+
|
|
|
+ .card-name {
|
|
|
+ font-size: 36rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ display: block;
|
|
|
+ }
|
|
|
|
|
|
-.hot-item__score-icon {
|
|
|
- font-size: 20rpx;
|
|
|
-}
|
|
|
+ .card-address {
|
|
|
+ font-size: 28rpx;
|
|
|
+ opacity: 0.9;
|
|
|
+ display: block;
|
|
|
+ margin: 8rpx 0 16rpx;
|
|
|
+ }
|
|
|
|
|
|
-.hot-item__score-value {
|
|
|
- font-size: 22rpx;
|
|
|
- color: #fff;
|
|
|
- margin-left: 4rpx;
|
|
|
-}
|
|
|
+ .card-price {
|
|
|
+ font-size: 30rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
|
|
|
-.category-tabs {
|
|
|
- display: flex;
|
|
|
- gap: 16rpx;
|
|
|
- margin-bottom: 24rpx;
|
|
|
+ .score-box {
|
|
|
+ .score {
|
|
|
+ font-size: 28rpx;
|
|
|
+ margin-left: 6rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-.category-tab {
|
|
|
- flex: 1;
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- align-items: center;
|
|
|
- padding: 20rpx 0;
|
|
|
+/* ========== 推荐模块 ========== */
|
|
|
+.recommend-section {
|
|
|
background-color: #fff;
|
|
|
- border-radius: 16rpx;
|
|
|
+ margin-top: 20rpx;
|
|
|
+ padding: 0 32rpx 100rpx;
|
|
|
}
|
|
|
|
|
|
-.category-tab--active {
|
|
|
- background-color: #4a8cff;
|
|
|
+.cate-scroll {
|
|
|
+ margin-bottom: 32rpx;
|
|
|
}
|
|
|
|
|
|
-.category-tab__icon {
|
|
|
- font-size: 32rpx;
|
|
|
- margin-bottom: 8rpx;
|
|
|
-}
|
|
|
+.cate-list {
|
|
|
+ gap: 24rpx;
|
|
|
|
|
|
-.category-tab__text {
|
|
|
- font-size: 24rpx;
|
|
|
- color: #666;
|
|
|
-}
|
|
|
+ .cate-item {
|
|
|
+ padding: 20rpx 44rpx;
|
|
|
+ border-radius: 18rpx;
|
|
|
+ background-color: #f2f3f6;
|
|
|
+ font-size: 30rpx;
|
|
|
+ white-space: nowrap;
|
|
|
+ color: #666;
|
|
|
|
|
|
-.category-tab--active .category-tab__text {
|
|
|
- color: #fff;
|
|
|
+ &.active {
|
|
|
+ background-color: #0066ff;
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-.recommend-list {
|
|
|
- margin-top: 16rpx;
|
|
|
-}
|
|
|
+.rec-list {
|
|
|
+ .rec-item {
|
|
|
+ padding: 32rpx 0;
|
|
|
+ border-bottom: 1rpx solid #eee;
|
|
|
|
|
|
-.recommend-item {
|
|
|
- display: flex;
|
|
|
- background-color: #fff;
|
|
|
- border-radius: 16rpx;
|
|
|
- overflow: hidden;
|
|
|
- margin-bottom: 20rpx;
|
|
|
-}
|
|
|
-
|
|
|
-.recommend-item__image {
|
|
|
- width: 240rpx;
|
|
|
- height: 200rpx;
|
|
|
-}
|
|
|
+ &:last-child {
|
|
|
+ border-bottom: none;
|
|
|
+ }
|
|
|
|
|
|
-.recommend-item__content {
|
|
|
- flex: 1;
|
|
|
- padding: 20rpx;
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- justify-content: space-between;
|
|
|
-}
|
|
|
+ .rec-img {
|
|
|
+ width: 240rpx;
|
|
|
+ height: 200rpx;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ flex-shrink: 0;
|
|
|
+ background-color: #f0f0f0;
|
|
|
+ }
|
|
|
|
|
|
-.recommend-item__header {
|
|
|
- display: flex;
|
|
|
- justify-content: space-between;
|
|
|
- align-items: flex-start;
|
|
|
-}
|
|
|
+ .rec-info {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: space-between;
|
|
|
+ flex: 1;
|
|
|
+ margin-left: 24rpx;
|
|
|
+ height: 200rpx;
|
|
|
+
|
|
|
+ .rec-top {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin-bottom: 12rpx;
|
|
|
+
|
|
|
+ .rec-name {
|
|
|
+ font-size: 34rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #222;
|
|
|
+ flex: 1;
|
|
|
+ }
|
|
|
|
|
|
-.recommend-item__name {
|
|
|
- flex: 1;
|
|
|
- font-size: 30rpx;
|
|
|
- font-weight: 600;
|
|
|
- color: #333;
|
|
|
- margin-right: 16rpx;
|
|
|
-}
|
|
|
+ .score-box {
|
|
|
+ flex-shrink: 0;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
|
|
|
-.recommend-item__score {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
-}
|
|
|
+ .score-star {
|
|
|
+ font-size: 28rpx;
|
|
|
+ margin-right: 6rpx;
|
|
|
+ }
|
|
|
|
|
|
-.recommend-item__score-icon {
|
|
|
- font-size: 24rpx;
|
|
|
-}
|
|
|
+ .score {
|
|
|
+ font-size: 30rpx;
|
|
|
+ color: #222;
|
|
|
+ font-weight: 500;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
-.recommend-item__score-value {
|
|
|
- font-size: 26rpx;
|
|
|
- color: #ffa940;
|
|
|
- font-weight: 600;
|
|
|
- margin-left: 4rpx;
|
|
|
-}
|
|
|
+ .rec-address {
|
|
|
+ display: flex;
|
|
|
+ align-items: center; // 垂直居中对齐
|
|
|
+ justify-items: start;
|
|
|
+ margin-bottom: 16rpx;
|
|
|
|
|
|
-.recommend-item__address {
|
|
|
- font-size: 24rpx;
|
|
|
- color: #999;
|
|
|
- margin: 12rpx 0;
|
|
|
- overflow: hidden;
|
|
|
- text-overflow: ellipsis;
|
|
|
- white-space: nowrap;
|
|
|
-}
|
|
|
+ .addr-icon {
|
|
|
+ font-size: 22rpx;
|
|
|
+ margin-right: 6rpx;
|
|
|
+ }
|
|
|
|
|
|
-.recommend-item__price {
|
|
|
- align-self: flex-start;
|
|
|
-}
|
|
|
+ .addr-text {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #999;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
-.recommend-item__price-value {
|
|
|
- font-size: 32rpx;
|
|
|
- color: #4a8cff;
|
|
|
- font-weight: 700;
|
|
|
+ .rec-price {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: flex-start;
|
|
|
+ font-size: 34rpx;
|
|
|
+ color: #0066ff;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
</style>
|