|
@@ -1,92 +1,139 @@
|
|
|
<template>
|
|
<template>
|
|
|
- <!-- <uv-navbar placeholder leftIcon="" title="Yeswash洗车"
|
|
|
|
|
- :border="false"></uv-navbar>-->
|
|
|
|
|
- <view class="content">
|
|
|
|
|
- <!-- <image class="logo" src="/static/logo.png"/>
|
|
|
|
|
- <view class="text-area">
|
|
|
|
|
- <text class="title">{{ title }}</text>
|
|
|
|
|
- </view>-->
|
|
|
|
|
- <view style="width: 100%;" class="swiper-content">
|
|
|
|
|
- <swiper :style="state.customStyle" circular :indicator-dots="true" :autoplay="true" :interval="3000"
|
|
|
|
|
- :duration="500">
|
|
|
|
|
- <swiper-item v-for="(item,idx) in state.swiperList" :key="idx">
|
|
|
|
|
- <image :src="item" mode="scaleToFill" :style="state.customStyle" @click="handleBannerClick(idx)"></image>
|
|
|
|
|
- </swiper-item>
|
|
|
|
|
- </swiper>
|
|
|
|
|
|
|
+ <view class="page-container">
|
|
|
|
|
+ <!-- 自定义导航栏 -->
|
|
|
|
|
+ <view class="custom-navbar" :style="{paddingTop: statusBarHeight + 'px'}">
|
|
|
|
|
+ <view class="navbar-content">
|
|
|
|
|
+ <view class="navbar-title">
|
|
|
|
|
+ <uv-icon name="home-fill" color="white" size="20"></uv-icon>
|
|
|
|
|
+ <text class="title-text">Yeswash洗车</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
- <view class="w100 gap"></view>
|
|
|
|
|
-
|
|
|
|
|
- <official-account @binderror="handleOAerror" @bindload="handleOAload" style="width: 100%"></official-account>
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- <view class="menu-content w100">
|
|
|
|
|
- <uv-grid :border="false" :col="4">
|
|
|
|
|
- <uv-grid-item v-for="(item,index) in state.menuList" :key="index" @click="handleMenuClick(item)">
|
|
|
|
|
- <image :src="item.icon" mode="widthFit" style="width: 48rpx;height: 48rpx"></image>
|
|
|
|
|
- <text class="grid-text" style="font-size: 14px;">{{ item.title }}</text>
|
|
|
|
|
- </uv-grid-item>
|
|
|
|
|
- </uv-grid>
|
|
|
|
|
|
|
+ <!-- 优化后的轮播图区域 -->
|
|
|
|
|
+ <view class="banner-wrapper">
|
|
|
|
|
+ <view class="banner-container">
|
|
|
|
|
+ <swiper
|
|
|
|
|
+ class="banner-swiper"
|
|
|
|
|
+ :style="bannerStyle"
|
|
|
|
|
+ circular
|
|
|
|
|
+ :indicator-dots="true"
|
|
|
|
|
+ :autoplay="true"
|
|
|
|
|
+ :interval="3000"
|
|
|
|
|
+ :duration="500"
|
|
|
|
|
+ indicator-color="rgba(255, 255, 255, 0.5)"
|
|
|
|
|
+ indicator-active-color="#C6171E"
|
|
|
|
|
+ >
|
|
|
|
|
+ <swiper-item v-for="(item,idx) in state.swiperList" :key="idx">
|
|
|
|
|
+ <image
|
|
|
|
|
+ class="banner-image"
|
|
|
|
|
+ :src="item"
|
|
|
|
|
+ mode="aspectFill"
|
|
|
|
|
+ @click="handleBannerClick(idx)"
|
|
|
|
|
+ ></image>
|
|
|
|
|
+ </swiper-item>
|
|
|
|
|
+ </swiper>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 渐变遮罩层 -->
|
|
|
|
|
+ <view class="banner-overlay"></view>
|
|
|
|
|
+ </view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
- <view class="w100 gap"></view>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 站点清单 start-->
|
|
|
|
|
- <view class="w100 content_station">
|
|
|
|
|
-<!-- <template v-if="isLogin">-->
|
|
|
|
|
- <WashStation v-for="item in state.stationList" :key="item.id" :item="item"></WashStation>
|
|
|
|
|
-<!-- </template>-->
|
|
|
|
|
-<!-- <uv-empty v-if="!isLogin" mode="order" text="请先登录" :marginTop="100" @click="gotoLogin"></uv-empty>-->
|
|
|
|
|
|
|
+ <!-- 微信公众号 -->
|
|
|
|
|
+ <official-account
|
|
|
|
|
+ @binderror="handleOAerror"
|
|
|
|
|
+ @bindload="handleOAload"
|
|
|
|
|
+ class="official-account"
|
|
|
|
|
+ ></official-account>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 优化后的菜单区域 -->
|
|
|
|
|
+ <view class="menu-section">
|
|
|
|
|
+ <view class="menu-card">
|
|
|
|
|
+ <view class="menu-header">
|
|
|
|
|
+ <view class="menu-title">
|
|
|
|
|
+ <view class="title-icon"></view>
|
|
|
|
|
+ <text>快捷服务</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
|
|
+ <view class="menu-grid">
|
|
|
|
|
+ <view
|
|
|
|
|
+ class="menu-item"
|
|
|
|
|
+ v-for="(item,index) in state.menuList"
|
|
|
|
|
+ :key="index"
|
|
|
|
|
+ @click="handleMenuClick(item)"
|
|
|
|
|
+ >
|
|
|
|
|
+ <view class="menu-icon-wrapper">
|
|
|
|
|
+ <image class="menu-icon" :src="item.icon" mode="aspectFit"></image>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <text class="menu-title-text">{{ item.title }}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
</view>
|
|
</view>
|
|
|
-<!--
|
|
|
|
|
- <movable-area class="mov-area">
|
|
|
|
|
- <movable-view :x="state.screenWidth" :y="state.screenHeight-100" direction="all" @change="onChange" class="customer-service">
|
|
|
|
|
- <button open-type="contact" @contact="handleContact" class="contact" send-message-title="YesWash洗车客服">在线客服</button>
|
|
|
|
|
- <image class="cs" src="/static/iconfont/cs.svg"/>
|
|
|
|
|
- </movable-view>
|
|
|
|
|
- </movable-area>-->
|
|
|
|
|
|
|
|
|
|
|
|
+ <!-- 站点列表区域(保留列表,移除标题) -->
|
|
|
|
|
+ <view class="station-section" :style="stationSectionStyle">
|
|
|
|
|
+ <scroll-view
|
|
|
|
|
+ class="station-scroll"
|
|
|
|
|
+ scroll-y="true"
|
|
|
|
|
+ :show-scrollbar="true"
|
|
|
|
|
+ >
|
|
|
|
|
+ <view class="station-list">
|
|
|
|
|
+ <WashStation
|
|
|
|
|
+ v-for="item in state.stationList"
|
|
|
|
|
+ :key="item.id"
|
|
|
|
|
+ :item="item"
|
|
|
|
|
+ ></WashStation>
|
|
|
|
|
+
|
|
|
|
|
+ <uv-empty
|
|
|
|
|
+ v-if="!state.stationList || state.stationList.length === 0"
|
|
|
|
|
+ mode="list"
|
|
|
|
|
+ text="附近暂无站点"
|
|
|
|
|
+ :marginTop="60"
|
|
|
|
|
+ ></uv-empty>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </scroll-view>
|
|
|
|
|
+ </view>
|
|
|
|
|
|
|
|
|
|
+ <!-- 客服按钮 -->
|
|
|
<custom-service></custom-service>
|
|
<custom-service></custom-service>
|
|
|
- <!-- 站点清单 end-->
|
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
- <!-- 停车券-->
|
|
|
|
|
- <uv-popup ref="parking_popup_ref">
|
|
|
|
|
- <view class="parking_box">
|
|
|
|
|
- <text>长按识别二维码获取停车优惠</text>
|
|
|
|
|
- <image show-menu-by-longpress src="/static/parking-qrcode.jpg"/>
|
|
|
|
|
|
|
+ <!-- 停车券弹窗 -->
|
|
|
|
|
+ <uv-popup ref="parking_popup_ref" mode="center" :round="16">
|
|
|
|
|
+ <view class="parking-popup">
|
|
|
|
|
+ <view class="popup-title">停车优惠</view>
|
|
|
|
|
+ <view class="popup-content">
|
|
|
|
|
+ <text class="popup-desc">长按识别二维码获取停车优惠</text>
|
|
|
|
|
+ <image
|
|
|
|
|
+ class="qrcode-image"
|
|
|
|
|
+ show-menu-by-longpress
|
|
|
|
|
+ src="/static/parking-qrcode.jpg"
|
|
|
|
|
+ />
|
|
|
|
|
+ </view>
|
|
|
</view>
|
|
</view>
|
|
|
</uv-popup>
|
|
</uv-popup>
|
|
|
|
|
|
|
|
- <!-- <cover-view class="login_bar">
|
|
|
|
|
- <login-bar class="w100 text-center"></login-bar>
|
|
|
|
|
- </cover-view>-->
|
|
|
|
|
- <!-- <cover-view class="login_bar" v-show="!isLogin">-->
|
|
|
|
|
- <!-- <login-bar class="w100 text-center" ></login-bar>-->
|
|
|
|
|
- <!-- </cover-view>-->
|
|
|
|
|
|
|
+ <!-- 底部导航栏 -->
|
|
|
<tab-bar :index="0"></tab-bar>
|
|
<tab-bar :index="0"></tab-bar>
|
|
|
</view>
|
|
</view>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
-import {nextTick, reactive, ref} from 'vue'
|
|
|
|
|
|
|
+import {computed, nextTick, reactive, ref} from 'vue'
|
|
|
import {onHide, onLoad, onShow} from "@dcloudio/uni-app";
|
|
import {onHide, onLoad, onShow} from "@dcloudio/uni-app";
|
|
|
import TabBar from "@/components/tab-bar/index.vue";
|
|
import TabBar from "@/components/tab-bar/index.vue";
|
|
|
import WashStation from "@/components/station/index.vue"
|
|
import WashStation from "@/components/station/index.vue"
|
|
|
import {get, post} from "@/utils/https";
|
|
import {get, post} from "@/utils/https";
|
|
|
import {calcMapDistance} from "@/utils/common"
|
|
import {calcMapDistance} from "@/utils/common"
|
|
|
import {checkLogin, fetchToken, loadUserInfo, tryLogin} from "@/utils/auth";
|
|
import {checkLogin, fetchToken, loadUserInfo, tryLogin} from "@/utils/auth";
|
|
|
-import {rpxToPx} from "@/utils/device";
|
|
|
|
|
|
|
|
|
|
const parking_popup_ref = ref();
|
|
const parking_popup_ref = ref();
|
|
|
const isLogin = ref(false)
|
|
const isLogin = ref(false)
|
|
|
-const isDragging = ref(false)
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-const change = () => {
|
|
|
|
|
- console.log("change")
|
|
|
|
|
-}
|
|
|
|
|
|
|
+const statusBarHeight = ref(0)
|
|
|
|
|
+const navbarHeight = ref(0)
|
|
|
|
|
+const bannerHeight = ref(0)
|
|
|
|
|
+const menuHeight = ref(0)
|
|
|
|
|
|
|
|
const initState = () => ({
|
|
const initState = () => ({
|
|
|
bannerList: [],
|
|
bannerList: [],
|
|
@@ -97,51 +144,49 @@ const initState = () => ({
|
|
|
{name: "coupon", auth: false, title: "消费券", icon: '/static/iconfont/default/coupon.svg'},
|
|
{name: "coupon", auth: false, title: "消费券", icon: '/static/iconfont/default/coupon.svg'},
|
|
|
{name: "parking", auth: false, title: "停车券", icon: '/static/iconfont/default/parking.svg'},
|
|
{name: "parking", auth: false, title: "停车券", icon: '/static/iconfont/default/parking.svg'},
|
|
|
],
|
|
],
|
|
|
- qrcodeOption: {
|
|
|
|
|
- style: 'round',
|
|
|
|
|
- size: 230,
|
|
|
|
|
- // 指定二维码前景,一般可在中间放logo
|
|
|
|
|
- foregroundImageSrc: 'https://www.uvui.cn/common/logo.png'
|
|
|
|
|
- },
|
|
|
|
|
- customStyle: {
|
|
|
|
|
- height: '180px',
|
|
|
|
|
- width: '100%',
|
|
|
|
|
- },
|
|
|
|
|
- notice: '中秋佳节,全场8折,快来洗车吧!',
|
|
|
|
|
stationList: [],
|
|
stationList: [],
|
|
|
location: {
|
|
location: {
|
|
|
latitude: 0,
|
|
latitude: 0,
|
|
|
longitude: 0,
|
|
longitude: 0,
|
|
|
},
|
|
},
|
|
|
- startAxis: {},
|
|
|
|
|
- csAxis: {
|
|
|
|
|
- right: '0rpx',
|
|
|
|
|
- top: '200rpx'
|
|
|
|
|
- },
|
|
|
|
|
- areaStyle: {
|
|
|
|
|
- "height": "100vh",
|
|
|
|
|
- "width": "750rpx",
|
|
|
|
|
- top: 0,
|
|
|
|
|
- position: "fixed",
|
|
|
|
|
-
|
|
|
|
|
- },
|
|
|
|
|
- screenWidth: 350,
|
|
|
|
|
- screenHeight: 1200
|
|
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
const state = reactive(initState())
|
|
const state = reactive(initState())
|
|
|
|
|
|
|
|
|
|
+// 轮播图高度计算
|
|
|
|
|
+const bannerStyle = computed(() => {
|
|
|
|
|
+ const windowInfo = uni.getWindowInfo();
|
|
|
|
|
+ // 使用固定宽高比 16:9 或 2:1,确保各设备上一致
|
|
|
|
|
+ const height = windowInfo.windowWidth * 0.5; // 2:1 比例
|
|
|
|
|
+ bannerHeight.value = height;
|
|
|
|
|
+ return {
|
|
|
|
|
+ height: `${height}px`
|
|
|
|
|
+ }
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+// 计算站点列表区域的高度
|
|
|
|
|
+const stationSectionStyle = computed(() => {
|
|
|
|
|
+ const windowInfo = uni.getWindowInfo();
|
|
|
|
|
+ // 导航栏总高度 = 状态栏高度 + 导航内容高度(88rpx转px)
|
|
|
|
|
+ const navTotalHeight = statusBarHeight.value + (88 * windowInfo.windowWidth / 750);
|
|
|
|
|
+ // 轮播图高度
|
|
|
|
|
+ const bannerH = bannerHeight.value || 0;
|
|
|
|
|
+ // 快捷服务区域预估高度(卡片padding + 标题 + 图标 + 间距,约280rpx转px)
|
|
|
|
|
+ const menuH = 280 * windowInfo.windowWidth / 750;
|
|
|
|
|
+ // 底部tabbar高度(约100rpx转px)
|
|
|
|
|
+ const tabbarH = 100 * windowInfo.windowWidth / 750;
|
|
|
|
|
+ // 可用高度 = 窗口高度 - 固定区域高度
|
|
|
|
|
+ const availableHeight = windowInfo.windowHeight - navTotalHeight - bannerH - menuH - tabbarH;
|
|
|
|
|
+
|
|
|
|
|
+ return {
|
|
|
|
|
+ height: `${availableHeight}px`
|
|
|
|
|
+ }
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
onLoad((e: any) => {
|
|
onLoad((e: any) => {
|
|
|
- let height = uni.getWindowInfo().windowHeight;
|
|
|
|
|
- // console.log(height, width, "screen")
|
|
|
|
|
- state.screenWidth = uni.getWindowInfo().windowWidth;
|
|
|
|
|
- state.screenHeight = uni.getWindowInfo().windowHeight;
|
|
|
|
|
- // const bound = uni.getMenuButtonBoundingClientRect();
|
|
|
|
|
- // width: 100%;height:170px;
|
|
|
|
|
- state.customStyle = {
|
|
|
|
|
- width: '100%',
|
|
|
|
|
- height: `${(height - rpxToPx(60)) / 4}px`
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ // 获取状态栏高度
|
|
|
|
|
+ const systemInfo = uni.getSystemInfoSync();
|
|
|
|
|
+ statusBarHeight.value = systemInfo.statusBarHeight || 0;
|
|
|
|
|
|
|
|
let token = fetchToken();
|
|
let token = fetchToken();
|
|
|
if (token) {
|
|
if (token) {
|
|
@@ -149,14 +194,12 @@ onLoad((e: any) => {
|
|
|
getApp<any>().globalData.isLogin = true;
|
|
getApp<any>().globalData.isLogin = true;
|
|
|
|
|
|
|
|
let gd = getApp<any>().globalData;
|
|
let gd = getApp<any>().globalData;
|
|
|
- console.log(gd)
|
|
|
|
|
if (!gd.user || !gd.user.id) {
|
|
if (!gd.user || !gd.user.id) {
|
|
|
loadUserInfo();
|
|
loadUserInfo();
|
|
|
} else {
|
|
} else {
|
|
|
isLogin.value = true;
|
|
isLogin.value = true;
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
- //主动退出的不自动登录
|
|
|
|
|
let manualLogout = getApp<any>().globalData.manualLogout;
|
|
let manualLogout = getApp<any>().globalData.manualLogout;
|
|
|
if (!manualLogout) {
|
|
if (!manualLogout) {
|
|
|
tryLogin().then(token => {
|
|
tryLogin().then(token => {
|
|
@@ -165,7 +208,6 @@ onLoad((e: any) => {
|
|
|
isLogin.value = true;
|
|
isLogin.value = true;
|
|
|
}).catch(e => {
|
|
}).catch(e => {
|
|
|
console.error(e)
|
|
console.error(e)
|
|
|
- gotoLogin()
|
|
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -176,14 +218,6 @@ onLoad((e: any) => {
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
onShow(() => {
|
|
onShow(() => {
|
|
|
- let height = uni.getWindowInfo().windowHeight;
|
|
|
|
|
- // const bound = uni.getMenuButtonBoundingClientRect();
|
|
|
|
|
- // width: 100%;height:170px;
|
|
|
|
|
- state.customStyle = {
|
|
|
|
|
- width: '100%',
|
|
|
|
|
- height: `${(height - rpxToPx(60)) / 4}px`
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
loadInitData()
|
|
loadInitData()
|
|
|
});
|
|
});
|
|
|
|
|
|
|
@@ -193,7 +227,6 @@ onHide(() => {
|
|
|
|
|
|
|
|
|
|
|
|
|
const loadInitData = () => {
|
|
const loadInitData = () => {
|
|
|
- console.log("show index>>>>", isLogin.value, state.stationList, state.location)
|
|
|
|
|
let locationData = getApp<any>().globalData.location;
|
|
let locationData = getApp<any>().globalData.location;
|
|
|
if (!locationData || !locationData.longitude) {
|
|
if (!locationData || !locationData.longitude) {
|
|
|
loadCurrentLocation();
|
|
loadCurrentLocation();
|
|
@@ -275,7 +308,7 @@ const handleMenuItemNative = (menu:any) => {
|
|
|
} else {
|
|
} else {
|
|
|
uni.showToast({
|
|
uni.showToast({
|
|
|
icon: 'none',
|
|
icon: 'none',
|
|
|
- title: '敬请期待',
|
|
|
|
|
|
|
+ title: '敲请期待',
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -288,7 +321,7 @@ const loadCurrentLocation = () => {
|
|
|
scope: 'scope.userLocation',
|
|
scope: 'scope.userLocation',
|
|
|
success() {
|
|
success() {
|
|
|
uni.getLocation({
|
|
uni.getLocation({
|
|
|
- type: 'gcj02', //返回可以用于uni.openLocation的经纬度
|
|
|
|
|
|
|
+ type: 'gcj02',
|
|
|
success: res => {
|
|
success: res => {
|
|
|
let location = {
|
|
let location = {
|
|
|
latitude: res.latitude,
|
|
latitude: res.latitude,
|
|
@@ -296,7 +329,6 @@ const loadCurrentLocation = () => {
|
|
|
}
|
|
}
|
|
|
getApp<any>().globalData.location = location;
|
|
getApp<any>().globalData.location = location;
|
|
|
state.location = location
|
|
state.location = location
|
|
|
- console.log("loadCurrentLocation location", res)
|
|
|
|
|
loadWashStationList();
|
|
loadWashStationList();
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
@@ -306,7 +338,6 @@ const loadCurrentLocation = () => {
|
|
|
console.log("authorize location fail", e)
|
|
console.log("authorize location fail", e)
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
-
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const loadWashStationList = () => {
|
|
const loadWashStationList = () => {
|
|
@@ -322,37 +353,14 @@ const loadWashStationList = () => {
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-const handleNavMap = (station: any) => {
|
|
|
|
|
- let location = JSON.parse(station.location)
|
|
|
|
|
- uni.openLocation({
|
|
|
|
|
- latitude: location.stationLat,
|
|
|
|
|
- longitude: location.stationLng,
|
|
|
|
|
- scale: 18,
|
|
|
|
|
- name: station.stationName,
|
|
|
|
|
- address: station.address,
|
|
|
|
|
- });
|
|
|
|
|
|
|
+const handleOAerror = (e: any) => {
|
|
|
|
|
+ console.log("handleOAerror official-account", e)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-const handleNavStation = (station: any) => {
|
|
|
|
|
- getApp<any>().globalData.pageData = {station}
|
|
|
|
|
- uni.navigateTo({
|
|
|
|
|
- url: '/pages-wash/station/index?id=' + station.id
|
|
|
|
|
- })
|
|
|
|
|
- console.log(station)
|
|
|
|
|
|
|
+const handleOAload = (e: any) => {
|
|
|
|
|
+ console.log("handleOAload official-account", e)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-const handleOAerror = (e) => {
|
|
|
|
|
- console.log("handleOAerror official-account",e)
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-const handleOAload = (e) => {
|
|
|
|
|
- console.log("handleOAload official-account",e)
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
<style scoped lang="scss">
|
|
@@ -360,195 +368,251 @@ page {
|
|
|
background: $uni-bg-color-page;
|
|
background: $uni-bg-color-page;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.content {
|
|
|
|
|
- width: 100%;
|
|
|
|
|
- display: flex;
|
|
|
|
|
- flex-direction: column;
|
|
|
|
|
- align-items: center;
|
|
|
|
|
- background-color: $uni-bg-color-page;
|
|
|
|
|
|
|
+.page-container {
|
|
|
|
|
+ min-height: 100vh;
|
|
|
|
|
+ background: linear-gradient(
|
|
|
|
|
+ 180deg,
|
|
|
|
|
+ #FFE8E8 0%,
|
|
|
|
|
+ #FFF5F5 30%,
|
|
|
|
|
+ $uni-bg-color-page 60%
|
|
|
|
|
+ );
|
|
|
|
|
+ padding-bottom: 120rpx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.logo {
|
|
|
|
|
- height: 200rpx;
|
|
|
|
|
- width: 200rpx;
|
|
|
|
|
- margin: 200rpx auto 50rpx;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.menu-content {
|
|
|
|
|
- width: 100%;
|
|
|
|
|
- padding: 30rpx 20rpx;
|
|
|
|
|
- background-color: $uni-bg-color-card;
|
|
|
|
|
- margin-top: -20rpx;
|
|
|
|
|
- border-radius: 20rpx 20rpx 0 0;
|
|
|
|
|
- box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
|
|
|
|
|
|
|
+// 自定义导航栏
|
|
|
|
|
+.custom-navbar {
|
|
|
|
|
+ position: fixed;
|
|
|
|
|
+ top: 0;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ right: 0;
|
|
|
|
|
+ z-index: 1000;
|
|
|
|
|
+ background: linear-gradient(
|
|
|
|
|
+ 135deg,
|
|
|
|
|
+ #C6171E 0%,
|
|
|
|
|
+ #E84545 100%
|
|
|
|
|
+ );
|
|
|
|
|
+ box-shadow: 0 2rpx 12rpx rgba(198, 23, 30, 0.15);
|
|
|
|
|
+
|
|
|
|
|
+ .navbar-content {
|
|
|
|
|
+ height: 88rpx;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ padding: 0 32rpx;
|
|
|
|
|
+
|
|
|
|
|
+ .navbar-title {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 12rpx;
|
|
|
|
|
+
|
|
|
|
|
+ .title-text {
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ font-size: 36rpx;
|
|
|
|
|
+ font-weight: $uni-font-weight-semibold;
|
|
|
|
|
+ letter-spacing: 2rpx;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 菜单按钮交互效果
|
|
|
|
|
-.uv-grid-item {
|
|
|
|
|
- transition: all 0.3s ease;
|
|
|
|
|
- cursor: pointer;
|
|
|
|
|
- border-radius: 16rpx;
|
|
|
|
|
- padding: 20rpx 0;
|
|
|
|
|
- margin: 0 10rpx;
|
|
|
|
|
|
|
+// 优化后的轮播图区域
|
|
|
|
|
+.banner-wrapper {
|
|
|
|
|
+ margin-top: 88rpx;
|
|
|
|
|
+ position: relative;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.uv-grid-item:active {
|
|
|
|
|
- transform: scale(0.95);
|
|
|
|
|
- background-color: $uni-bg-color-hover;
|
|
|
|
|
-}
|
|
|
|
|
|
|
+.banner-container {
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
|
|
|
-.grid-text {
|
|
|
|
|
- font-size: $uni-font-size-xs !important;
|
|
|
|
|
- color: $uni-text-color-secondary;
|
|
|
|
|
- margin-top: 12rpx;
|
|
|
|
|
- transition: color 0.2s ease;
|
|
|
|
|
-}
|
|
|
|
|
|
|
+ .banner-swiper {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
-.uv-grid-item:active .grid-text {
|
|
|
|
|
- color: $uni-color-primary;
|
|
|
|
|
-}
|
|
|
|
|
|
|
+ .banner-image {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ display: block;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
-.uv-grid-item image {
|
|
|
|
|
- transition: all 0.2s ease;
|
|
|
|
|
|
|
+ // 渐变遮罩层,与下方内容过渡
|
|
|
|
|
+ .banner-overlay {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ bottom: 0;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ right: 0;
|
|
|
|
|
+ height: 60rpx;
|
|
|
|
|
+ background: linear-gradient(
|
|
|
|
|
+ to bottom,
|
|
|
|
|
+ rgba(255, 255, 255, 0),
|
|
|
|
|
+ rgba(255, 245, 245, 0.8)
|
|
|
|
|
+ );
|
|
|
|
|
+ pointer-events: none;
|
|
|
|
|
+ z-index: 1;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.uv-grid-item:active image {
|
|
|
|
|
- transform: scale(0.9);
|
|
|
|
|
|
|
+// 公众号区域
|
|
|
|
|
+.official-account {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ margin: 20rpx 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.qrcode-content {
|
|
|
|
|
- margin-top: 40rpx;
|
|
|
|
|
|
|
+// 优化后的菜单区域
|
|
|
|
|
+.menu-section {
|
|
|
padding: 0 20rpx;
|
|
padding: 0 20rpx;
|
|
|
- width: 100%;
|
|
|
|
|
- display: flex;
|
|
|
|
|
- flex-direction: column;
|
|
|
|
|
- align-items: center;
|
|
|
|
|
- align-content: center;
|
|
|
|
|
- justify-content: center;
|
|
|
|
|
-}
|
|
|
|
|
|
|
+ margin-bottom: 20rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.menu-card {
|
|
|
|
|
+ background: white;
|
|
|
|
|
+ border-radius: 24rpx;
|
|
|
|
|
+ padding: 24rpx 20rpx;
|
|
|
|
|
+ box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);
|
|
|
|
|
+
|
|
|
|
|
+ .menu-header {
|
|
|
|
|
+ margin-bottom: 24rpx;
|
|
|
|
|
+
|
|
|
|
|
+ .menu-title {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 12rpx;
|
|
|
|
|
+ font-size: 30rpx;
|
|
|
|
|
+ font-weight: $uni-font-weight-semibold;
|
|
|
|
|
+ color: $uni-text-color;
|
|
|
|
|
+
|
|
|
|
|
+ .title-icon {
|
|
|
|
|
+ width: 6rpx;
|
|
|
|
|
+ height: 28rpx;
|
|
|
|
|
+ background: linear-gradient(
|
|
|
|
|
+ to bottom,
|
|
|
|
|
+ $uni-color-primary,
|
|
|
|
|
+ $uni-color-primary-light
|
|
|
|
|
+ );
|
|
|
|
|
+ border-radius: 3rpx;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
-.gap {
|
|
|
|
|
- width: 100%;
|
|
|
|
|
- height: 20rpx;
|
|
|
|
|
- background-color: $uni-bg-color-page;
|
|
|
|
|
-}
|
|
|
|
|
|
|
+ .menu-grid {
|
|
|
|
|
+ display: grid;
|
|
|
|
|
+ grid-template-columns: repeat(4, 1fr);
|
|
|
|
|
+ gap: 16rpx;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
-.swiper-content {
|
|
|
|
|
- width: 100%;
|
|
|
|
|
- border-radius: 0 0 20rpx 20rpx;
|
|
|
|
|
- overflow: hidden;
|
|
|
|
|
- box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
|
|
|
|
|
-}
|
|
|
|
|
|
|
+ .menu-item {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 12rpx;
|
|
|
|
|
+ padding: 16rpx 0;
|
|
|
|
|
+ border-radius: 16rpx;
|
|
|
|
|
+ transition: all 0.3s ease;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+
|
|
|
|
|
+ &:active {
|
|
|
|
|
+ transform: scale(0.95);
|
|
|
|
|
+ background: $uni-bg-color-hover;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
-// 轮播图样式增强
|
|
|
|
|
-.swiper-content swiper {
|
|
|
|
|
- border-radius: 0 0 20rpx 20rpx;
|
|
|
|
|
-}
|
|
|
|
|
|
|
+ .menu-icon-wrapper {
|
|
|
|
|
+ width: 80rpx;
|
|
|
|
|
+ height: 80rpx;
|
|
|
|
|
+ background: linear-gradient(
|
|
|
|
|
+ 135deg,
|
|
|
|
|
+ rgba(198, 23, 30, 0.08),
|
|
|
|
|
+ rgba(232, 69, 69, 0.05)
|
|
|
|
|
+ );
|
|
|
|
|
+ border-radius: 20rpx;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ box-shadow: 0 4rpx 12rpx rgba(198, 23, 30, 0.08);
|
|
|
|
|
+ transition: all 0.3s ease;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
-.swiper-content swiper-item {
|
|
|
|
|
- border-radius: 0 0 20rpx 20rpx;
|
|
|
|
|
- overflow: hidden;
|
|
|
|
|
- position: relative;
|
|
|
|
|
-}
|
|
|
|
|
|
|
+ &:active .menu-icon-wrapper {
|
|
|
|
|
+ transform: scale(0.9);
|
|
|
|
|
+ box-shadow: 0 2rpx 8rpx rgba(198, 23, 30, 0.12);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
-// 轮播图点击效果
|
|
|
|
|
-.swiper-content swiper-item image {
|
|
|
|
|
- transition: all 0.2s ease;
|
|
|
|
|
- cursor: pointer;
|
|
|
|
|
-}
|
|
|
|
|
|
|
+ .menu-icon {
|
|
|
|
|
+ width: 48rpx;
|
|
|
|
|
+ height: 48rpx;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
-.swiper-content swiper-item:active image {
|
|
|
|
|
- transform: scale(0.98);
|
|
|
|
|
- opacity: 0.95;
|
|
|
|
|
-}
|
|
|
|
|
|
|
+ .menu-title-text {
|
|
|
|
|
+ font-size: 24rpx;
|
|
|
|
|
+ color: $uni-text-color-secondary;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+ transition: color 0.2s ease;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
-.guide-content {
|
|
|
|
|
- text-align: center;
|
|
|
|
|
|
|
+ &:active .menu-title-text {
|
|
|
|
|
+ color: $uni-color-primary;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.loginbar {
|
|
|
|
|
- position: fixed;
|
|
|
|
|
- bottom: 20rpx;
|
|
|
|
|
|
|
+// 站点列表区域(移除标题,保留列表)
|
|
|
|
|
+.station-section {
|
|
|
|
|
+ padding: 0 20rpx;
|
|
|
|
|
+ margin-bottom: 20rpx;
|
|
|
|
|
+ overflow: hidden;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.content_station {
|
|
|
|
|
- padding: 0 20rpx 200rpx;
|
|
|
|
|
|
|
+.station-scroll {
|
|
|
width: 100%;
|
|
width: 100%;
|
|
|
- box-sizing: border-box;
|
|
|
|
|
|
|
+ height: 100%;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.customer-service {
|
|
|
|
|
- height: 100rpx;
|
|
|
|
|
- width: 100rpx;
|
|
|
|
|
-
|
|
|
|
|
- image {
|
|
|
|
|
- width: 80rpx !important;
|
|
|
|
|
- height: 80rpx !important;
|
|
|
|
|
- z-index: 100;
|
|
|
|
|
- position: absolute;
|
|
|
|
|
- margin-top: -60rpx;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- .contact {
|
|
|
|
|
- opacity: 0;
|
|
|
|
|
- z-index: 9999;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+.station-list {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ padding-bottom: 20rpx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.mov-area {
|
|
|
|
|
- pointer-events: none;
|
|
|
|
|
|
|
+// 停车券弹窗
|
|
|
|
|
+.parking-popup {
|
|
|
|
|
+ width: 600rpx;
|
|
|
|
|
+ background: white;
|
|
|
|
|
+ border-radius: 24rpx;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
|
|
|
- .movable-view {
|
|
|
|
|
- width: 100rpx !important;
|
|
|
|
|
- height: 100rpx !important;
|
|
|
|
|
- pointer-events: auto;
|
|
|
|
|
|
|
+ .popup-title {
|
|
|
|
|
+ background: linear-gradient(
|
|
|
|
|
+ 135deg,
|
|
|
|
|
+ $uni-color-primary 0%,
|
|
|
|
|
+ $uni-color-primary-light 100%
|
|
|
|
|
+ );
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ font-size: 32rpx;
|
|
|
|
|
+ font-weight: $uni-font-weight-semibold;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ padding: 32rpx;
|
|
|
}
|
|
}
|
|
|
-}
|
|
|
|
|
|
|
|
|
|
-$all_width: 96rpx;
|
|
|
|
|
-$all_height: 96rpx;
|
|
|
|
|
-movable-area {
|
|
|
|
|
- height: calc(100vh - 200rpx);
|
|
|
|
|
- width: 750rpx;
|
|
|
|
|
- top: 0;
|
|
|
|
|
- position: fixed;
|
|
|
|
|
- pointer-events: none;
|
|
|
|
|
- movable-view {
|
|
|
|
|
- width: $all_width;
|
|
|
|
|
- height: $all_height;
|
|
|
|
|
- pointer-events: auto;
|
|
|
|
|
- image {
|
|
|
|
|
- width: $all_width;
|
|
|
|
|
- height: $all_height;
|
|
|
|
|
|
|
+ .popup-content {
|
|
|
|
|
+ padding: 40rpx;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 32rpx;
|
|
|
|
|
+
|
|
|
|
|
+ .popup-desc {
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ color: $uni-text-color-secondary;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ line-height: 1.6;
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
|
|
|
|
|
-.parking_box {
|
|
|
|
|
- width: 500rpx;
|
|
|
|
|
- background-color: $uni-bg-color-card;
|
|
|
|
|
- padding: 40rpx;
|
|
|
|
|
- display: flex;
|
|
|
|
|
- flex-direction: column;
|
|
|
|
|
- justify-content: center;
|
|
|
|
|
- align-items: center;
|
|
|
|
|
- border-radius: 16rpx;
|
|
|
|
|
- box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.15);
|
|
|
|
|
-
|
|
|
|
|
- text {
|
|
|
|
|
- padding-bottom: 30rpx;
|
|
|
|
|
- font-size: 16px;
|
|
|
|
|
- color: $uni-text-color;
|
|
|
|
|
- font-weight: 500;
|
|
|
|
|
- text-align: center;
|
|
|
|
|
- line-height: 1.5;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- image {
|
|
|
|
|
- border-radius: 12rpx;
|
|
|
|
|
- width: 420rpx;
|
|
|
|
|
- height: 420rpx;
|
|
|
|
|
- box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
|
|
|
|
|
|
+ .qrcode-image {
|
|
|
|
|
+ width: 480rpx;
|
|
|
|
|
+ height: 480rpx;
|
|
|
|
|
+ border-radius: 16rpx;
|
|
|
|
|
+ box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
</style>
|
|
</style>
|