|
|
@@ -1,961 +1,961 @@
|
|
|
-<template>
|
|
|
- <view class="container">
|
|
|
- <navigation-bar @ready="handleNavReady"></navigation-bar>
|
|
|
- <view class="dialog" v-if="styleData.dialog" :style="styleData.dialog">
|
|
|
- <view class="height-88 flex-align-center bg-fff">
|
|
|
- <view class="dialog_logo ml-24"></view>
|
|
|
- <view class="dialog_search ml-24" @click.stop="toSearch"></view>
|
|
|
- </view>
|
|
|
- <!-- <view class="height-72 flex" style="background-color: #f9f9f9">
|
|
|
- <view class="width-half flex-center" @click.stop="checkFilterDistance">
|
|
|
- <view class="fs-26 color-000-6 mr-8">距离</view>
|
|
|
- <view
|
|
|
- class="width-20 height-20 br-round bg-000-08 lh-10 text-center transition"
|
|
|
- :style="{
|
|
|
- transform: filterDialog.distanceSelector ? 'rotate(180deg)' : '',
|
|
|
- }"
|
|
|
- >
|
|
|
- <uni-icons
|
|
|
- type="bottom"
|
|
|
- size="8"
|
|
|
- color="rgba(0,0,0,0.4)"
|
|
|
- ></uni-icons>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- <view class="width-half flex-center">
|
|
|
- <view
|
|
|
- class="width-32 height-32 br-round lh-20 text-center"
|
|
|
- :style="{
|
|
|
- border: filterDialog.discounts
|
|
|
- ? '1px solid var(--color-primary)'
|
|
|
- : '1px solid rgba(0, 0, 0, 0.4)',
|
|
|
- backgroundColor: filterDialog.discounts
|
|
|
- ? 'var(--color-primary)'
|
|
|
- : '#fff',
|
|
|
- }"
|
|
|
- >
|
|
|
- <uni-icons
|
|
|
- type="checkmarkempty"
|
|
|
- size="10"
|
|
|
- color="#ffffff"
|
|
|
- ></uni-icons>
|
|
|
- </view>
|
|
|
- <view
|
|
|
- :class="[
|
|
|
- 'fs-26',
|
|
|
- 'ml-8',
|
|
|
- filterDialog.discounts ? 'color-primary' : 'color-000-6',
|
|
|
- ]"
|
|
|
- >支持省钱充电</view
|
|
|
- >
|
|
|
- </view>
|
|
|
- </view> -->
|
|
|
- <view
|
|
|
- class="dialog_selector"
|
|
|
- :style="{
|
|
|
- height: filterDialog.distanceSelector ? '190rpx' : '0rpx',
|
|
|
- borderTop: `1rpx solid rgba(0, 0, 0, ${
|
|
|
- filterDialog.distanceSelector ? '0.1' : '0'
|
|
|
- })`,
|
|
|
- }"
|
|
|
- >
|
|
|
- <view class="flex-center flex-wrap pb-14">
|
|
|
- <view
|
|
|
- :class="[
|
|
|
- 'type',
|
|
|
- 'flex-shrink',
|
|
|
- 'flex-center',
|
|
|
- 'mt-20',
|
|
|
- (index + 1) % 5 === 0 ? 'mr-0' : 'mr-20',
|
|
|
- `type-${
|
|
|
- item.value === filterDialog.options.distance ? 'active' : ''
|
|
|
- }`,
|
|
|
- ]"
|
|
|
- v-for="(item, index) in filterDialog.distanceRange"
|
|
|
- :key="index"
|
|
|
- @click.stop="changeFilterDistance(index)"
|
|
|
- style="width: 117rpx"
|
|
|
- >{{ item.value }}km</view
|
|
|
- >
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- <view class="dialog_event" v-if="ready && mapBanner.length > 0">
|
|
|
- <swiper
|
|
|
- class="swiper"
|
|
|
- circular
|
|
|
- :indicator-dots="true"
|
|
|
- :autoplay="mapBanner.length > 1"
|
|
|
- :interval="3000"
|
|
|
- >
|
|
|
- <swiper-item
|
|
|
- class="swiper-item full-percent"
|
|
|
- v-for="(item, index) in mapBanner"
|
|
|
- :key="index"
|
|
|
- @click="to(item.linkUrl)"
|
|
|
- >
|
|
|
- <view
|
|
|
- class="full-percent"
|
|
|
- :style="{
|
|
|
- backgroundImage: `url(${item.bannerUrl})`,
|
|
|
- }"
|
|
|
- ></view>
|
|
|
- </swiper-item>
|
|
|
- </swiper>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- <view
|
|
|
- v-if="styleData.dialogPlaceHolderHeight"
|
|
|
- :style="{ height: `${styleData.dialogPlaceHolderHeight}px` }"
|
|
|
- ></view>
|
|
|
- <map
|
|
|
- v-if="ready"
|
|
|
- id="map"
|
|
|
- :style="{
|
|
|
- width: '100%',
|
|
|
- height: styleData.dialogHeight
|
|
|
- ? `calc(100vh - ${styleData.dialogHeight}px - ${
|
|
|
- styleData.cardHeight - 24
|
|
|
- }px)`
|
|
|
- : '50vh',
|
|
|
- zIndex: 1,
|
|
|
- pointerEvents: loading || !mapMode ? 'none' : 'auto',
|
|
|
- }"
|
|
|
- :latitude="mapProps.latitude"
|
|
|
- :longitude="mapProps.longitude"
|
|
|
- :markers="markers"
|
|
|
- min-scale="1"
|
|
|
- :scale="mapProps.scale"
|
|
|
- @regionchange="mapChange"
|
|
|
- @updated="mapUpdated"
|
|
|
- @labeltap="tapMarker"
|
|
|
- @markertap="tapMarker"
|
|
|
- :show-scale="true"
|
|
|
- ></map>
|
|
|
- <block v-else>
|
|
|
- <view
|
|
|
- v-if="styleData.dialogHeight"
|
|
|
- class="mock-map flex-center"
|
|
|
- :style="{
|
|
|
- height: `calc(100vh - ${styleData.dialogHeight}px - ${
|
|
|
- styleData.cardHeight - 24
|
|
|
- }px)`,
|
|
|
- }"
|
|
|
- >
|
|
|
- <image
|
|
|
- src="/static/images/map-bg.jpg"
|
|
|
- mode="widthFix"
|
|
|
- style="width: 100%"
|
|
|
- ></image>
|
|
|
- <image
|
|
|
- src="/static/images/map-current.png"
|
|
|
- mode="widthFix"
|
|
|
- class="absolute-center"
|
|
|
- style="width: 34px"
|
|
|
- ></image>
|
|
|
- </view>
|
|
|
- </block>
|
|
|
- <view
|
|
|
- class="card"
|
|
|
- :style="{
|
|
|
- height: mapMode
|
|
|
- ? `${styleData.cardHeight}px`
|
|
|
- : `calc(100vh - ${styleData.navHeight}px)`,
|
|
|
- bottom: '0px',
|
|
|
- borderRadius: mapMode ? '16rpx 16rpx 0px 0px' : '0px',
|
|
|
- overflowY: mapMode ? 'visible' : 'auto',
|
|
|
- }"
|
|
|
- @touchstart="touchCardStart"
|
|
|
- @touchmove="touchCardMove"
|
|
|
- >
|
|
|
- <view
|
|
|
- v-if="mapMode"
|
|
|
- class="card_location height-64 width-64 bg-fff flex-center"
|
|
|
- @touchstart.stop="resetLocation"
|
|
|
- >
|
|
|
- <image
|
|
|
- src="/static/images/map-re-location.png"
|
|
|
- mode="widthFix"
|
|
|
- class="width-48"
|
|
|
- ></image>
|
|
|
- </view>
|
|
|
- <block v-if="station.length">
|
|
|
- <!-- 列表 -->
|
|
|
- <block v-if="!mapMode">
|
|
|
- <view class="station" v-for="(item, index) in station" :key="index">
|
|
|
- <view v-if="index !== 0" class="card_line"></view>
|
|
|
- <charge-station
|
|
|
- :title="item.stationName"
|
|
|
- :address="item.address"
|
|
|
- :price="item.totalFee"
|
|
|
- :fast="item.fastEquipmentInfos"
|
|
|
- :slow="item.slowEquipmentInfos"
|
|
|
- :sId="item.StationID"
|
|
|
- :distance="item.stationLatDistance"
|
|
|
- :latitude="item.location.stationLat"
|
|
|
- :longitude="item.location.stationLng"
|
|
|
- :fromMap="true"
|
|
|
- ></charge-station>
|
|
|
- </view>
|
|
|
- <view class="station-placeholder"></view>
|
|
|
- <view class="station-iphonex"></view>
|
|
|
- </block>
|
|
|
- <block v-else>
|
|
|
- <!-- 单个 -->
|
|
|
- <view class="station">
|
|
|
- <charge-station
|
|
|
- :title="station[markersIndex].stationName"
|
|
|
- :address="station[markersIndex].address"
|
|
|
- :price="station[markersIndex].totalFee"
|
|
|
- :fast="station[markersIndex].fastEquipmentInfos"
|
|
|
- :slow="station[markersIndex].slowEquipmentInfos"
|
|
|
- :sId="station[markersIndex].StationID"
|
|
|
- :distance="station[markersIndex].stationLatDistance"
|
|
|
- :latitude="station[markersIndex].location.stationLat"
|
|
|
- :longitude="station[markersIndex].location.stationLng"
|
|
|
- :fromMap="true"
|
|
|
- ></charge-station>
|
|
|
- </view>
|
|
|
- </block>
|
|
|
- </block>
|
|
|
- <block v-else>
|
|
|
- <view class="card_empty flex-column flex-align-center pt-20">
|
|
|
- <view v-if="loading" class="mt-60 animation-loading"
|
|
|
- ><uni-icons
|
|
|
- type="spinner-cycle"
|
|
|
- size="20"
|
|
|
- color="rgba(0, 0, 0, 0.5)"
|
|
|
- ></uni-icons
|
|
|
- ></view>
|
|
|
- <image
|
|
|
- class="image"
|
|
|
- v-else
|
|
|
- src="/static/images/map-empty.png"
|
|
|
- mode="widthFix"
|
|
|
- />
|
|
|
- <view class="fs-22 mt-14 color-000-5">{{
|
|
|
- loading
|
|
|
- ? "加载中"
|
|
|
- : token
|
|
|
- ? "暂无充电站信息"
|
|
|
- : "登录后查看更多电站信息"
|
|
|
- }}</view>
|
|
|
- </view>
|
|
|
- </block>
|
|
|
- </view>
|
|
|
- <view
|
|
|
- class="charging flex-align-center"
|
|
|
- v-if="charging"
|
|
|
- @click="toCharging"
|
|
|
- >
|
|
|
- <image
|
|
|
- class="width-64 ml-12"
|
|
|
- src="/static/images/map-charging.png"
|
|
|
- mode="widthFix"
|
|
|
- ></image>
|
|
|
- <view class="fs-26 color-fff ml-12">{{
|
|
|
- charging.chargeStatus === 0 ? "已预约" : "充电中"
|
|
|
- }}</view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- <view class="login-mask" v-if="!token">
|
|
|
- <button open-type="getPhoneNumber" @getphonenumber="loginMask" class="full">
|
|
|
- 登录按钮
|
|
|
- </button>
|
|
|
- </view>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script setup lang="ts">
|
|
|
-const defaulDistance = 3;
|
|
|
-const defaultScale = 12;
|
|
|
-const pointSize = {
|
|
|
- width: 34,
|
|
|
- height: 58,
|
|
|
- fontSize: 10,
|
|
|
- iconPath: "/static/images/map-point.png",
|
|
|
- currentWidth: 52,
|
|
|
- currentHeight: 86,
|
|
|
- currentFontSize: 11,
|
|
|
- currentIconPath: "/static/images/map-point-current.png",
|
|
|
- androidX: -14,
|
|
|
- androidCurrentX: -20,
|
|
|
-};
|
|
|
-import { fetchHomeBanner } from "@/api";
|
|
|
-import { deCode } from "../../utils/code";
|
|
|
-import { rpxToPx } from "../../utils/device";
|
|
|
-import { fetchToken, login, onLogin } from "@/api/auth";
|
|
|
-import { fetchStations, fetchChargeStatus } from "@/api/charge";
|
|
|
-import { fetchCollectList } from "@/api/user";
|
|
|
-import { fetchLocation } from "@/utils/location";
|
|
|
-import { to } from "@/utils/navigate";
|
|
|
-import { onLoad, onShow } from "@dcloudio/uni-app";
|
|
|
-import { ref } from "vue";
|
|
|
-
|
|
|
-const isIOS = ref(false);
|
|
|
-const token = ref<string>();
|
|
|
-const ready = ref(false);
|
|
|
-const loading = ref(false);
|
|
|
-const styleData = ref({
|
|
|
- dialog: "",
|
|
|
- dialogHeight: 0,
|
|
|
- dialogPlaceHolderHeight: 0,
|
|
|
- cardHeight: 0,
|
|
|
- navHeight: 0,
|
|
|
-});
|
|
|
-
|
|
|
-const filterDialog = ref({
|
|
|
- discounts: false,
|
|
|
- distanceSelector: false,
|
|
|
- distanceRange: [
|
|
|
- {
|
|
|
- value: 1,
|
|
|
- scale: defaultScale + 3,
|
|
|
- },
|
|
|
- {
|
|
|
- value: 2,
|
|
|
- scale: defaultScale + 1,
|
|
|
- },
|
|
|
- {
|
|
|
- value: 3,
|
|
|
- scale: defaultScale,
|
|
|
- },
|
|
|
- {
|
|
|
- value: 5,
|
|
|
- scale: defaultScale - 0.2,
|
|
|
- },
|
|
|
- {
|
|
|
- value: 10,
|
|
|
- scale: defaultScale - 0.5,
|
|
|
- },
|
|
|
- {
|
|
|
- value: 20,
|
|
|
- scale: defaultScale - 1.5,
|
|
|
- },
|
|
|
- {
|
|
|
- value: 30,
|
|
|
- scale: defaultScale - 2,
|
|
|
- },
|
|
|
- {
|
|
|
- value: 50,
|
|
|
- scale: defaultScale - 2.5,
|
|
|
- },
|
|
|
- {
|
|
|
- value: 100,
|
|
|
- scale: defaultScale - 3.5,
|
|
|
- },
|
|
|
- {
|
|
|
- value: 200,
|
|
|
- scale: defaultScale - 4.5,
|
|
|
- },
|
|
|
- ],
|
|
|
- options: {
|
|
|
- distance: defaulDistance,
|
|
|
- status: 0,
|
|
|
- },
|
|
|
- status: [
|
|
|
- {
|
|
|
- title: "全部",
|
|
|
- },
|
|
|
- {
|
|
|
- title: "空闲",
|
|
|
- },
|
|
|
- {
|
|
|
- title: "忙碌",
|
|
|
- },
|
|
|
- ],
|
|
|
-});
|
|
|
-
|
|
|
-const stationPage = ref({
|
|
|
- page: 1,
|
|
|
- pageSize: 6,
|
|
|
- hasNext: false,
|
|
|
-});
|
|
|
-const station = ref<any[]>([]);
|
|
|
-const charging = ref<any>();
|
|
|
-
|
|
|
-const mapMode = ref(true);
|
|
|
-const mapProps = ref({
|
|
|
- latitude: 23.098994,
|
|
|
- longitude: 113.32252,
|
|
|
- selflatitude: 23.098994,
|
|
|
- selflongitude: 113.32252,
|
|
|
- scale: defaultScale,
|
|
|
-});
|
|
|
-const markersIndex = ref(-1);
|
|
|
-const markers = ref<any[]>([]);
|
|
|
-const mapBanner = ref<any[]>([]);
|
|
|
-
|
|
|
-let isIgnoreChangeLocation = false;
|
|
|
-
|
|
|
-const refreshStation = (location: any) => {
|
|
|
- let length = 0;
|
|
|
- let available = 0;
|
|
|
- const { latitude, longitude } = location;
|
|
|
- if (!token.value) {
|
|
|
- return;
|
|
|
- }
|
|
|
- return fetchStations(
|
|
|
- stationPage.value.page,
|
|
|
- stationPage.value.pageSize,
|
|
|
- latitude,
|
|
|
- longitude,
|
|
|
- mapProps.value.selflatitude,
|
|
|
- mapProps.value.selflongitude,
|
|
|
- {
|
|
|
- distance: filterDialog.value.options.distance,
|
|
|
- status: filterDialog.value.options.status,
|
|
|
- }
|
|
|
- ).then((res) => {
|
|
|
- const _markersIndex = stationPage.value.page === 1 ? 0 : markersIndex.value;
|
|
|
- const _markers: any[] = res.map((item, index) => {
|
|
|
- length = 0;
|
|
|
- available = 0;
|
|
|
- item.equipmentInfos &&
|
|
|
- item.equipmentInfos.forEach((eq: any) => {
|
|
|
- eq.connectorInfos &&
|
|
|
- eq.connectorInfos.forEach((co: any) => {
|
|
|
- length += 1;
|
|
|
- if (
|
|
|
- co.connectorStatusInfo &&
|
|
|
- co.connectorStatusInfo.status === 1
|
|
|
- ) {
|
|
|
- available += 1;
|
|
|
- }
|
|
|
- });
|
|
|
- });
|
|
|
- return {
|
|
|
- id: Number(item.StationID),
|
|
|
- latitude: item.location.stationLat,
|
|
|
- longitude: item.location.stationLng,
|
|
|
- iconPath:
|
|
|
- index === _markersIndex
|
|
|
- ? pointSize.currentIconPath
|
|
|
- : pointSize.iconPath,
|
|
|
- width:
|
|
|
- index === _markersIndex ? pointSize.currentWidth : pointSize.width,
|
|
|
- height:
|
|
|
- index === _markersIndex ? pointSize.currentHeight : pointSize.height,
|
|
|
- label: {
|
|
|
- content: `${available}/${length}`,
|
|
|
- color: "#ffffff",
|
|
|
- fontSize:
|
|
|
- index === _markersIndex
|
|
|
- ? pointSize.currentFontSize
|
|
|
- : pointSize.fontSize,
|
|
|
- textAlign: isIOS.value ? "center" : "left",
|
|
|
- anchorX: isIOS.value
|
|
|
- ? 0
|
|
|
- : index === _markersIndex
|
|
|
- ? pointSize.androidCurrentX
|
|
|
- : pointSize.androidX,
|
|
|
- anchorY: -(
|
|
|
- (index === _markersIndex
|
|
|
- ? pointSize.currentHeight
|
|
|
- : pointSize.height) - 3
|
|
|
- ),
|
|
|
- },
|
|
|
- };
|
|
|
- });
|
|
|
- if (stationPage.value.page === 1) {
|
|
|
- _markers.push({
|
|
|
- id: -1,
|
|
|
- latitude: mapProps.value.selflatitude,
|
|
|
- longitude: mapProps.value.selflongitude,
|
|
|
- iconPath: "/static/images/map-current.png",
|
|
|
- width: 34,
|
|
|
- height: 34,
|
|
|
- });
|
|
|
- }
|
|
|
- isIgnoreChangeLocation = markers.value.length !== _markers.length;
|
|
|
- stationPage.value.hasNext = res.length >= stationPage.value.pageSize;
|
|
|
- // empty.value = stationPage.value.page === 1 ? res.length <= 0 : false;
|
|
|
- station.value =
|
|
|
- stationPage.value.page === 1 ? res : [...station.value, ...res];
|
|
|
- markersIndex.value = _markersIndex;
|
|
|
- markers.value = _markers;
|
|
|
- return res;
|
|
|
- });
|
|
|
-};
|
|
|
-
|
|
|
-const refresh = () => {
|
|
|
- if (loading.value) {
|
|
|
- return;
|
|
|
- }
|
|
|
- console.log("刷新电站");
|
|
|
- uni.showLoading({
|
|
|
- title: "加载中",
|
|
|
- });
|
|
|
- loading.value = true;
|
|
|
- stationPage.value.page = 1;
|
|
|
- stationPage.value.hasNext = false;
|
|
|
- station.value = [];
|
|
|
- markers.value = [];
|
|
|
- markersIndex.value = 0;
|
|
|
- fetchLocation()
|
|
|
- .then((res: any) => {
|
|
|
- mapProps.value.latitude = res.latitude;
|
|
|
- mapProps.value.longitude = res.longitude;
|
|
|
- mapProps.value.selflatitude = res.latitude;
|
|
|
- mapProps.value.selflongitude = res.longitude;
|
|
|
- isIgnoreChangeLocation = true;
|
|
|
- return refreshStation(res);
|
|
|
- })
|
|
|
- .then(() => {
|
|
|
- uni.hideLoading();
|
|
|
- loading.value = false;
|
|
|
- ready.value = true;
|
|
|
- })
|
|
|
- .catch((err) => {
|
|
|
- console.log(err);
|
|
|
- uni.hideLoading();
|
|
|
- loading.value = false;
|
|
|
- uni.showModal({
|
|
|
- content: `${err.errMsg},请重试`,
|
|
|
- });
|
|
|
- });
|
|
|
-};
|
|
|
-
|
|
|
-const handleNavReady = (e: any) => {
|
|
|
- console.log(e);
|
|
|
- styleData.value.dialog = `padding-top:${e.detail.statusBarHeight - 6}px;`;
|
|
|
- const searchHeight = rpxToPx(88);
|
|
|
- const filterHeight = 0; // rpxToPx(72);
|
|
|
- styleData.value.dialogHeight =
|
|
|
- e.detail.statusBarHeight - 6 + searchHeight + filterHeight;
|
|
|
- styleData.value.dialogPlaceHolderHeight =
|
|
|
- styleData.value.dialogHeight - e.detail.navigationBarHeight;
|
|
|
- styleData.value.cardHeight = rpxToPx(402) + e.detail.statusBarHeight;
|
|
|
- styleData.value.navHeight = e.detail.navigationBarHeight;
|
|
|
-};
|
|
|
-
|
|
|
-const toSearch = () => {
|
|
|
- if (!ready.value) {
|
|
|
- return;
|
|
|
- }
|
|
|
- uni.navigateTo({
|
|
|
- url: "/pages-charge/search/search",
|
|
|
- });
|
|
|
-};
|
|
|
-
|
|
|
-onLoad((query: any) => {
|
|
|
- // 只为了打包进tab-bar使用
|
|
|
- console.log(fetchToken, login, onLogin);
|
|
|
- // 扫普通码
|
|
|
- if (query.q) {
|
|
|
- console.log("扫普通码", decodeURIComponent(query.q));
|
|
|
- getApp<any>().globalData.normalCode = decodeURIComponent(query.q); // 获取到二维码原始链接内容
|
|
|
- }
|
|
|
- const device = uni.getSystemInfoSync();
|
|
|
- isIOS.value = device.osName === "ios";
|
|
|
-
|
|
|
- setTimeout(() => {
|
|
|
- token.value = getApp<any>().globalData.token || "";
|
|
|
- if (!token.value) {
|
|
|
- isIgnoreChangeLocation = true;
|
|
|
- fetchLocation().then((res: any) => {
|
|
|
- mapProps.value.latitude = res.latitude;
|
|
|
- mapProps.value.longitude = res.longitude;
|
|
|
- mapProps.value.selflatitude = res.latitude;
|
|
|
- mapProps.value.selflongitude = res.longitude;
|
|
|
- markers.value = [
|
|
|
- {
|
|
|
- id: -1,
|
|
|
- latitude: res.latitude,
|
|
|
- longitude: res.longitude,
|
|
|
- iconPath: "/static/images/map-current.png",
|
|
|
- width: 34,
|
|
|
- height: 34,
|
|
|
- },
|
|
|
- ];
|
|
|
- });
|
|
|
- onLogin((_token) => {
|
|
|
- if (getApp<any>().globalData.normalCode) {
|
|
|
- const code: string = getApp<any>().globalData.normalCode;
|
|
|
- getApp<any>().globalData.normalCode = "";
|
|
|
- deCode(code);
|
|
|
- }
|
|
|
- token.value = _token;
|
|
|
- fetchCollectList().then(() => {
|
|
|
- refresh();
|
|
|
- fetchCharging();
|
|
|
- fetchBanner();
|
|
|
- });
|
|
|
- });
|
|
|
- return;
|
|
|
- }
|
|
|
- fetchCollectList().then(() => {
|
|
|
- if (getApp<any>().globalData.normalCode) {
|
|
|
- const code: string = getApp<any>().globalData.normalCode;
|
|
|
- getApp<any>().globalData.normalCode = "";
|
|
|
- deCode(code);
|
|
|
- }
|
|
|
- refresh();
|
|
|
- fetchCharging();
|
|
|
- fetchBanner();
|
|
|
- });
|
|
|
- }, 300);
|
|
|
-});
|
|
|
-
|
|
|
-onShow(() => {
|
|
|
- if (token.value) {
|
|
|
- fetchBanner();
|
|
|
- charging.value = undefined;
|
|
|
- setTimeout(() => {
|
|
|
- fetchCharging();
|
|
|
- }, 2000);
|
|
|
- }
|
|
|
-});
|
|
|
-
|
|
|
-const fetchCharging = () => {
|
|
|
- fetchChargeStatus().then((res) => {
|
|
|
- if (res && [0, 1, 2, 3].includes(res.chargeStatus)) {
|
|
|
- charging.value = res;
|
|
|
- }
|
|
|
- });
|
|
|
-};
|
|
|
-
|
|
|
-const fetchBanner = () => {
|
|
|
- fetchHomeBanner().then((res) => {
|
|
|
- mapBanner.value = res.filter((item: any) => item.status === 1);
|
|
|
- });
|
|
|
-};
|
|
|
-
|
|
|
-// const checkDiscounts = () => {
|
|
|
-// filterDialog.value.discounts = !filterDialog.value.discounts;
|
|
|
-// };
|
|
|
-
|
|
|
-const checkFilterDistance = () => {
|
|
|
- if (isIgnoreChangeLocation) {
|
|
|
- return;
|
|
|
- }
|
|
|
- if (!mapMode.value) {
|
|
|
- mapMode.value = true;
|
|
|
- }
|
|
|
- filterDialog.value.distanceSelector = !filterDialog.value.distanceSelector;
|
|
|
-};
|
|
|
-
|
|
|
-const changeFilterDistance = (index: number) => {
|
|
|
- filterDialog.value.options.distance =
|
|
|
- filterDialog.value.distanceRange[index].value;
|
|
|
- if (mapProps.value.scale === filterDialog.value.distanceRange[index].scale) {
|
|
|
- refresh();
|
|
|
- return;
|
|
|
- }
|
|
|
- mapProps.value.scale = filterDialog.value.distanceRange[index].scale;
|
|
|
- checkFilterDistance();
|
|
|
-};
|
|
|
-
|
|
|
-const resetLocation = () => {
|
|
|
- if (loading.value) {
|
|
|
- return;
|
|
|
- }
|
|
|
- // eslint-disable-next-line promise/catch-or-return
|
|
|
- fetchLocation().then((res: any) => {
|
|
|
- const mapCtx = uni.createMapContext("map");
|
|
|
- const { latitude, longitude } = res;
|
|
|
- mapCtx.moveToLocation({
|
|
|
- latitude,
|
|
|
- longitude,
|
|
|
- });
|
|
|
- mapProps.value.scale = defaultScale;
|
|
|
- });
|
|
|
-};
|
|
|
-
|
|
|
-const mapUpdated = (e: any) => {
|
|
|
- // console.log('map updated', isIgnoreChangeLocation)
|
|
|
- setTimeout(() => {
|
|
|
- isIgnoreChangeLocation = false;
|
|
|
- }, 500);
|
|
|
-};
|
|
|
-const mapChange = (e: any) => {
|
|
|
- if (isIgnoreChangeLocation) {
|
|
|
- return;
|
|
|
- }
|
|
|
- if (e.type === "end" && markers.value.length) {
|
|
|
- // console.log("map change end", {
|
|
|
- // ...e.detail.centerLocation,
|
|
|
- // });
|
|
|
- const current = e.target.centerLocation;
|
|
|
- const { latitude, longitude } = current;
|
|
|
- stationPage.value.page = 1;
|
|
|
- refreshStation({
|
|
|
- latitude,
|
|
|
- longitude,
|
|
|
- });
|
|
|
- }
|
|
|
-};
|
|
|
-const _changeMarker = (current: number) => {
|
|
|
- const _markers = JSON.parse(JSON.stringify(markers.value));
|
|
|
- const markersNewIndex = current;
|
|
|
- _markers[markersIndex.value].iconPath = pointSize.iconPath;
|
|
|
- _markers[markersIndex.value].width = pointSize.width;
|
|
|
- _markers[markersIndex.value].height = pointSize.height;
|
|
|
- _markers[markersIndex.value].label.fontSize = pointSize.fontSize;
|
|
|
- _markers[markersIndex.value].label.anchorY = -(pointSize.height - 3);
|
|
|
- if (!isIOS) {
|
|
|
- _markers[markersIndex.value].label.anchorX = pointSize.androidX;
|
|
|
- }
|
|
|
-
|
|
|
- _markers[markersNewIndex].iconPath = pointSize.currentIconPath;
|
|
|
- _markers[markersNewIndex].width = pointSize.currentWidth;
|
|
|
- _markers[markersNewIndex].height = pointSize.currentHeight;
|
|
|
- _markers[markersNewIndex].label.fontSize = pointSize.currentFontSize;
|
|
|
- _markers[markersNewIndex].label.anchorY = -(pointSize.currentHeight - 3);
|
|
|
- if (!isIOS) {
|
|
|
- _markers[markersNewIndex].label.anchorX = pointSize.androidCurrentX;
|
|
|
- }
|
|
|
-
|
|
|
- isIgnoreChangeLocation = true;
|
|
|
- markers.value = _markers;
|
|
|
- markersIndex.value = markersNewIndex;
|
|
|
- if (stationPage.value.hasNext && markersNewIndex >= _markers.length - 2) {
|
|
|
- stationPage.value.page += 1;
|
|
|
- refreshStation({
|
|
|
- latitude: mapProps.value.selflatitude,
|
|
|
- longitude: mapProps.value.selflongitude,
|
|
|
- });
|
|
|
- }
|
|
|
-};
|
|
|
-const tapMarker = (e: any) => {
|
|
|
- if (e.detail.markerId === -1) {
|
|
|
- return;
|
|
|
- }
|
|
|
- const findIndex = station.value.findIndex(
|
|
|
- (item) => Number(item.StationID) === Number(e.detail.markerId)
|
|
|
- );
|
|
|
- if (findIndex >= 0) {
|
|
|
- _changeMarker(findIndex);
|
|
|
- }
|
|
|
-};
|
|
|
-const loginMask = (e: any) => {
|
|
|
- login(e);
|
|
|
-};
|
|
|
-
|
|
|
-let startpageY = 0;
|
|
|
-const touchCardStart = (e: any) => {
|
|
|
- if (loading.value || station.value.length <= 0) {
|
|
|
- return;
|
|
|
- }
|
|
|
- if (e.touches && e.touches.length) {
|
|
|
- startpageY = e.touches[0].pageY;
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-const touchCardMove = (e: any) => {
|
|
|
- if (!startpageY) {
|
|
|
- return;
|
|
|
- }
|
|
|
- const threshold = 200;
|
|
|
- if (e.touches && e.touches.length) {
|
|
|
- if (mapMode.value && startpageY - e.touches[0].pageY > threshold) {
|
|
|
- mapMode.value = false;
|
|
|
- }
|
|
|
- if (!mapMode.value && e.touches[0].pageY - startpageY > threshold) {
|
|
|
- mapMode.value = true;
|
|
|
- }
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-const toCharging = () => {
|
|
|
- to(
|
|
|
- charging.value.chargeStatus === 0
|
|
|
- ? `/pages-charge/appointment/appointment?sn=${charging.value.connectorId}`
|
|
|
- : `/pages-charge/ordering/ordering?sn=${charging.value.connectorId}&start=1`
|
|
|
- );
|
|
|
-};
|
|
|
-</script>
|
|
|
-
|
|
|
-<style lang="scss">
|
|
|
-page {
|
|
|
- background-color: #ffffff;
|
|
|
-}
|
|
|
-
|
|
|
-.container {
|
|
|
- position: relative;
|
|
|
- height: 100vh;
|
|
|
- width: 100vw;
|
|
|
- background-color: #ffffff;
|
|
|
-}
|
|
|
-
|
|
|
-.mock-map {
|
|
|
- position: relative;
|
|
|
- width: 100vw;
|
|
|
- background-color: #ffffff;
|
|
|
- overflow: hidden;
|
|
|
-}
|
|
|
-
|
|
|
-.login-mask {
|
|
|
- position: fixed;
|
|
|
- left: 0;
|
|
|
- top: 0;
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- z-index: 999999;
|
|
|
- opacity: 0;
|
|
|
-
|
|
|
- .full {
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.dialog {
|
|
|
- position: fixed;
|
|
|
- top: 0;
|
|
|
- left: 0;
|
|
|
- width: 100%;
|
|
|
- z-index: 1000;
|
|
|
-
|
|
|
- &_logo {
|
|
|
- width: 156rpx;
|
|
|
- height: 100%;
|
|
|
- background-position: center;
|
|
|
- background-size: 100% auto;
|
|
|
- background-repeat: no-repeat;
|
|
|
- background-image: url("/static/images/map-logo.png");
|
|
|
- }
|
|
|
-
|
|
|
- &_search {
|
|
|
- width: 352rpx;
|
|
|
- height: 100%;
|
|
|
- background-position: center;
|
|
|
- background-size: 100% auto;
|
|
|
- background-repeat: no-repeat;
|
|
|
- background-image: url("/static/images/map-input.png");
|
|
|
- }
|
|
|
-
|
|
|
- &_event {
|
|
|
- margin-top: 20rpx;
|
|
|
- padding: 0rpx 32rpx;
|
|
|
- .swiper {
|
|
|
- height: 160rpx;
|
|
|
- width: 100%;
|
|
|
- border-radius: 16rpx;
|
|
|
- overflow: hidden;
|
|
|
- .swiper-item {
|
|
|
- border-radius: 16rpx;
|
|
|
- overflow: hidden;
|
|
|
- }
|
|
|
- view {
|
|
|
- background-position: center;
|
|
|
- background-repeat: no-repeat;
|
|
|
- background-size: 100% 100%;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- &_selector {
|
|
|
- background-color: #f9f9f9;
|
|
|
- transition: all 0.3s;
|
|
|
- overflow: hidden;
|
|
|
- .type {
|
|
|
- width: 160rpx;
|
|
|
- height: 60rpx;
|
|
|
- background: var(--color-sec);
|
|
|
- border-radius: 4rpx;
|
|
|
- color: #666;
|
|
|
- font-size: 26rpx;
|
|
|
- border: 1px solid var(--color-sec);
|
|
|
- }
|
|
|
-
|
|
|
- .type-active {
|
|
|
- border: 1px solid var(--color-primary);
|
|
|
- color: var(--color-primary);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* .slider {
|
|
|
- position: relative;
|
|
|
- height: 12rpx;
|
|
|
- width: 100%;
|
|
|
- border-radius: 8rpx;
|
|
|
- background-color: var(--color-sec);
|
|
|
- margin-top: 10rpx;
|
|
|
-
|
|
|
- &_active {
|
|
|
- position: absolute;
|
|
|
- left: 0;
|
|
|
- top: 0;
|
|
|
- background-color: var(--color-primary);
|
|
|
- border-radius: 8rpx;
|
|
|
- height: 12rpx;
|
|
|
- width: 0%;
|
|
|
- }
|
|
|
-
|
|
|
- &_block {
|
|
|
- position: absolute;
|
|
|
- width: 40rpx;
|
|
|
- height: 40rpx;
|
|
|
- border-radius: 50%;
|
|
|
- top: -15rpx;
|
|
|
- left: 0;
|
|
|
- background: rgba(255, 255, 255, 1);
|
|
|
- box-shadow: 0px 4rpx 6rpx rgba(52, 125, 255, 0.4);
|
|
|
- }
|
|
|
-
|
|
|
- &_wx {
|
|
|
- position: absolute;
|
|
|
- width: 100%;
|
|
|
- left: 0px;
|
|
|
- top: -5px;
|
|
|
- margin: 0;
|
|
|
- opacity: 0;
|
|
|
- }
|
|
|
- } */
|
|
|
-}
|
|
|
-
|
|
|
-.card {
|
|
|
- position: fixed;
|
|
|
- width: 100%;
|
|
|
- left: 0px;
|
|
|
- z-index: 1000;
|
|
|
- transition: all 0.3s;
|
|
|
- box-shadow: 0px 8rpx 20rpx rgba(0, 0, 0, 0.2);
|
|
|
- background-color: #fff;
|
|
|
-
|
|
|
- &_location {
|
|
|
- position: absolute;
|
|
|
- border-radius: 16rpx;
|
|
|
- box-shadow: 0px 8rpx 20rpx 0px rgba(0, 0, 0, 0.2);
|
|
|
- right: 20rpx;
|
|
|
- top: -104rpx;
|
|
|
- z-index: 99;
|
|
|
- }
|
|
|
-
|
|
|
- &_line {
|
|
|
- height: 1rpx;
|
|
|
- background-color: rgba(0, 0, 0, 0.1);
|
|
|
- margin-left: 30rpx;
|
|
|
- margin-right: 30rpx;
|
|
|
- }
|
|
|
-
|
|
|
- &_empty {
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- .image {
|
|
|
- width: 160rpx;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .station-placeholder {
|
|
|
- min-height: 104rpx;
|
|
|
- }
|
|
|
- .station-iphonex {
|
|
|
- box-sizing: content-box;
|
|
|
- padding-bottom: constant(safe-area-inset-bottom);
|
|
|
- padding-bottom: env(safe-area-inset-bottom);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.charging {
|
|
|
- position: fixed;
|
|
|
- z-index: 1000;
|
|
|
- right: 0;
|
|
|
- bottom: 164rpx;
|
|
|
- width: 186rpx;
|
|
|
- height: 88rpx;
|
|
|
- border-radius: 88rpx 0px 0px 88rpx;
|
|
|
- background: #2d9e95;
|
|
|
- margin-bottom: constant(safe-area-inset-bottom);
|
|
|
- margin-bottom: env(safe-area-inset-bottom);
|
|
|
-}
|
|
|
-</style>
|
|
|
+<template>
|
|
|
+ <view class="container">
|
|
|
+ <navigation-bar @ready="handleNavReady"></navigation-bar>
|
|
|
+ <view class="dialog" v-if="styleData.dialog" :style="styleData.dialog">
|
|
|
+ <view class="height-88 flex-align-center bg-fff">
|
|
|
+ <view class="dialog_logo ml-24"></view>
|
|
|
+ <view class="dialog_search ml-24" @click.stop="toSearch"></view>
|
|
|
+ </view>
|
|
|
+ <!-- <view class="height-72 flex" style="background-color: #f9f9f9">
|
|
|
+ <view class="width-half flex-center" @click.stop="checkFilterDistance">
|
|
|
+ <view class="fs-26 color-000-6 mr-8">距离</view>
|
|
|
+ <view
|
|
|
+ class="width-20 height-20 br-round bg-000-08 lh-10 text-center transition"
|
|
|
+ :style="{
|
|
|
+ transform: filterDialog.distanceSelector ? 'rotate(180deg)' : '',
|
|
|
+ }"
|
|
|
+ >
|
|
|
+ <uni-icons
|
|
|
+ type="bottom"
|
|
|
+ size="8"
|
|
|
+ color="rgba(0,0,0,0.4)"
|
|
|
+ ></uni-icons>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="width-half flex-center">
|
|
|
+ <view
|
|
|
+ class="width-32 height-32 br-round lh-20 text-center"
|
|
|
+ :style="{
|
|
|
+ border: filterDialog.discounts
|
|
|
+ ? '1px solid var(--color-primary)'
|
|
|
+ : '1px solid rgba(0, 0, 0, 0.4)',
|
|
|
+ backgroundColor: filterDialog.discounts
|
|
|
+ ? 'var(--color-primary)'
|
|
|
+ : '#fff',
|
|
|
+ }"
|
|
|
+ >
|
|
|
+ <uni-icons
|
|
|
+ type="checkmarkempty"
|
|
|
+ size="10"
|
|
|
+ color="#ffffff"
|
|
|
+ ></uni-icons>
|
|
|
+ </view>
|
|
|
+ <view
|
|
|
+ :class="[
|
|
|
+ 'fs-26',
|
|
|
+ 'ml-8',
|
|
|
+ filterDialog.discounts ? 'color-primary' : 'color-000-6',
|
|
|
+ ]"
|
|
|
+ >支持省钱充电</view
|
|
|
+ >
|
|
|
+ </view>
|
|
|
+ </view> -->
|
|
|
+ <view
|
|
|
+ class="dialog_selector"
|
|
|
+ :style="{
|
|
|
+ height: filterDialog.distanceSelector ? '190rpx' : '0rpx',
|
|
|
+ borderTop: `1rpx solid rgba(0, 0, 0, ${
|
|
|
+ filterDialog.distanceSelector ? '0.1' : '0'
|
|
|
+ })`,
|
|
|
+ }"
|
|
|
+ >
|
|
|
+ <view class="flex-center flex-wrap pb-14">
|
|
|
+ <view
|
|
|
+ :class="[
|
|
|
+ 'type',
|
|
|
+ 'flex-shrink',
|
|
|
+ 'flex-center',
|
|
|
+ 'mt-20',
|
|
|
+ (index + 1) % 5 === 0 ? 'mr-0' : 'mr-20',
|
|
|
+ `type-${
|
|
|
+ item.value === filterDialog.options.distance ? 'active' : ''
|
|
|
+ }`,
|
|
|
+ ]"
|
|
|
+ v-for="(item, index) in filterDialog.distanceRange"
|
|
|
+ :key="index"
|
|
|
+ @click.stop="changeFilterDistance(index)"
|
|
|
+ style="width: 117rpx"
|
|
|
+ >{{ item.value }}km</view
|
|
|
+ >
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="dialog_event" v-if="ready && mapBanner.length > 0">
|
|
|
+ <swiper
|
|
|
+ class="swiper"
|
|
|
+ circular
|
|
|
+ :indicator-dots="true"
|
|
|
+ :autoplay="mapBanner.length > 1"
|
|
|
+ :interval="3000"
|
|
|
+ >
|
|
|
+ <swiper-item
|
|
|
+ class="swiper-item full-percent"
|
|
|
+ v-for="(item, index) in mapBanner"
|
|
|
+ :key="index"
|
|
|
+ @click="to(item.linkUrl)"
|
|
|
+ >
|
|
|
+ <view
|
|
|
+ class="full-percent"
|
|
|
+ :style="{
|
|
|
+ backgroundImage: `url(${item.bannerUrl})`,
|
|
|
+ }"
|
|
|
+ ></view>
|
|
|
+ </swiper-item>
|
|
|
+ </swiper>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view
|
|
|
+ v-if="styleData.dialogPlaceHolderHeight"
|
|
|
+ :style="{ height: `${styleData.dialogPlaceHolderHeight}px` }"
|
|
|
+ ></view>
|
|
|
+ <map
|
|
|
+ v-if="ready"
|
|
|
+ id="map"
|
|
|
+ :style="{
|
|
|
+ width: '100%',
|
|
|
+ height: styleData.dialogHeight
|
|
|
+ ? `calc(100vh - ${styleData.dialogHeight}px - ${
|
|
|
+ styleData.cardHeight - 24
|
|
|
+ }px)`
|
|
|
+ : '50vh',
|
|
|
+ zIndex: 1,
|
|
|
+ pointerEvents: loading || !mapMode ? 'none' : 'auto',
|
|
|
+ }"
|
|
|
+ :latitude="mapProps.latitude"
|
|
|
+ :longitude="mapProps.longitude"
|
|
|
+ :markers="markers"
|
|
|
+ min-scale="1"
|
|
|
+ :scale="mapProps.scale"
|
|
|
+ @regionchange="mapChange"
|
|
|
+ @updated="mapUpdated"
|
|
|
+ @labeltap="tapMarker"
|
|
|
+ @markertap="tapMarker"
|
|
|
+ :show-scale="true"
|
|
|
+ ></map>
|
|
|
+ <block v-else>
|
|
|
+ <view
|
|
|
+ v-if="styleData.dialogHeight"
|
|
|
+ class="mock-map flex-center"
|
|
|
+ :style="{
|
|
|
+ height: `calc(100vh - ${styleData.dialogHeight}px - ${
|
|
|
+ styleData.cardHeight - 24
|
|
|
+ }px)`,
|
|
|
+ }"
|
|
|
+ >
|
|
|
+ <image
|
|
|
+ src="/static/images/map-bg.jpg"
|
|
|
+ mode="widthFix"
|
|
|
+ style="width: 100%"
|
|
|
+ ></image>
|
|
|
+ <image
|
|
|
+ src="/static/images/map-current.png"
|
|
|
+ mode="widthFix"
|
|
|
+ class="absolute-center"
|
|
|
+ style="width: 34px"
|
|
|
+ ></image>
|
|
|
+ </view>
|
|
|
+ </block>
|
|
|
+ <view
|
|
|
+ class="card"
|
|
|
+ :style="{
|
|
|
+ height: mapMode
|
|
|
+ ? `${styleData.cardHeight}px`
|
|
|
+ : `calc(100vh - ${styleData.navHeight}px)`,
|
|
|
+ bottom: '0px',
|
|
|
+ borderRadius: mapMode ? '16rpx 16rpx 0px 0px' : '0px',
|
|
|
+ overflowY: mapMode ? 'visible' : 'auto',
|
|
|
+ }"
|
|
|
+ @touchstart="touchCardStart"
|
|
|
+ @touchmove="touchCardMove"
|
|
|
+ >
|
|
|
+ <view
|
|
|
+ v-if="mapMode"
|
|
|
+ class="card_location height-64 width-64 bg-fff flex-center"
|
|
|
+ @touchstart.stop="resetLocation"
|
|
|
+ >
|
|
|
+ <image
|
|
|
+ src="/static/images/map-re-location.png"
|
|
|
+ mode="widthFix"
|
|
|
+ class="width-48"
|
|
|
+ ></image>
|
|
|
+ </view>
|
|
|
+ <block v-if="station.length">
|
|
|
+ <!-- 列表 -->
|
|
|
+ <block v-if="!mapMode">
|
|
|
+ <view class="station" v-for="(item, index) in station" :key="index">
|
|
|
+ <view v-if="index !== 0" class="card_line"></view>
|
|
|
+ <charge-station
|
|
|
+ :title="item.stationName"
|
|
|
+ :address="item.address"
|
|
|
+ :price="item.totalFee"
|
|
|
+ :fast="item.fastEquipmentInfos"
|
|
|
+ :slow="item.slowEquipmentInfos"
|
|
|
+ :sId="item.StationID"
|
|
|
+ :distance="item.stationLatDistance"
|
|
|
+ :latitude="item.location.stationLat"
|
|
|
+ :longitude="item.location.stationLng"
|
|
|
+ :fromMap="true"
|
|
|
+ ></charge-station>
|
|
|
+ </view>
|
|
|
+ <view class="station-placeholder"></view>
|
|
|
+ <view class="station-iphonex"></view>
|
|
|
+ </block>
|
|
|
+ <block v-else>
|
|
|
+ <!-- 单个 -->
|
|
|
+ <view class="station">
|
|
|
+ <charge-station
|
|
|
+ :title="station[markersIndex].stationName"
|
|
|
+ :address="station[markersIndex].address"
|
|
|
+ :price="station[markersIndex].totalFee"
|
|
|
+ :fast="station[markersIndex].fastEquipmentInfos"
|
|
|
+ :slow="station[markersIndex].slowEquipmentInfos"
|
|
|
+ :sId="station[markersIndex].StationID"
|
|
|
+ :distance="station[markersIndex].stationLatDistance"
|
|
|
+ :latitude="station[markersIndex].location.stationLat"
|
|
|
+ :longitude="station[markersIndex].location.stationLng"
|
|
|
+ :fromMap="true"
|
|
|
+ ></charge-station>
|
|
|
+ </view>
|
|
|
+ </block>
|
|
|
+ </block>
|
|
|
+ <block v-else>
|
|
|
+ <view class="card_empty flex-column flex-align-center pt-20">
|
|
|
+ <view v-if="loading" class="mt-60 animation-loading"
|
|
|
+ ><uni-icons
|
|
|
+ type="spinner-cycle"
|
|
|
+ size="20"
|
|
|
+ color="rgba(0, 0, 0, 0.5)"
|
|
|
+ ></uni-icons
|
|
|
+ ></view>
|
|
|
+ <image
|
|
|
+ class="image"
|
|
|
+ v-else
|
|
|
+ src="/static/images/map-empty.png"
|
|
|
+ mode="widthFix"
|
|
|
+ />
|
|
|
+ <view class="fs-22 mt-14 color-000-5">{{
|
|
|
+ loading
|
|
|
+ ? "加载中"
|
|
|
+ : token
|
|
|
+ ? "暂无充电站信息"
|
|
|
+ : "登录后查看更多电站信息"
|
|
|
+ }}</view>
|
|
|
+ </view>
|
|
|
+ </block>
|
|
|
+ </view>
|
|
|
+ <view
|
|
|
+ class="charging flex-align-center"
|
|
|
+ v-if="charging"
|
|
|
+ @click="toCharging"
|
|
|
+ >
|
|
|
+ <image
|
|
|
+ class="width-64 ml-12"
|
|
|
+ src="/static/images/map-charging.png"
|
|
|
+ mode="widthFix"
|
|
|
+ ></image>
|
|
|
+ <view class="fs-26 color-fff ml-12">{{
|
|
|
+ charging.chargeStatus === 0 ? "已预约" : "充电中"
|
|
|
+ }}</view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="login-mask" v-if="!token">
|
|
|
+ <button open-type="getPhoneNumber" @getphonenumber="loginMask" class="full">
|
|
|
+ 登录按钮
|
|
|
+ </button>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+const defaulDistance = 3;
|
|
|
+const defaultScale = 12;
|
|
|
+const pointSize = {
|
|
|
+ width: 34,
|
|
|
+ height: 58,
|
|
|
+ fontSize: 10,
|
|
|
+ iconPath: "/static/images/map-point.png",
|
|
|
+ currentWidth: 52,
|
|
|
+ currentHeight: 86,
|
|
|
+ currentFontSize: 11,
|
|
|
+ currentIconPath: "/static/images/map-point-current.png",
|
|
|
+ androidX: -14,
|
|
|
+ androidCurrentX: -20,
|
|
|
+};
|
|
|
+import { fetchHomeBanner } from "@/api";
|
|
|
+import { deCode } from "../../utils/code";
|
|
|
+import { rpxToPx } from "../../utils/device";
|
|
|
+import { fetchToken, login, onLogin } from "@/api/auth";
|
|
|
+import { fetchStations, fetchChargeStatus } from "@/api/charge";
|
|
|
+import { fetchCollectList } from "@/api/user";
|
|
|
+import { fetchLocation } from "@/utils/location";
|
|
|
+import { to } from "@/utils/navigate";
|
|
|
+import { onLoad, onShow } from "@dcloudio/uni-app";
|
|
|
+import { ref } from "vue";
|
|
|
+
|
|
|
+const isIOS = ref(false);
|
|
|
+const token = ref<string>();
|
|
|
+const ready = ref(false);
|
|
|
+const loading = ref(false);
|
|
|
+const styleData = ref({
|
|
|
+ dialog: "",
|
|
|
+ dialogHeight: 0,
|
|
|
+ dialogPlaceHolderHeight: 0,
|
|
|
+ cardHeight: 0,
|
|
|
+ navHeight: 0,
|
|
|
+});
|
|
|
+
|
|
|
+const filterDialog = ref({
|
|
|
+ discounts: false,
|
|
|
+ distanceSelector: false,
|
|
|
+ distanceRange: [
|
|
|
+ {
|
|
|
+ value: 1,
|
|
|
+ scale: defaultScale + 3,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: 2,
|
|
|
+ scale: defaultScale + 1,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: 3,
|
|
|
+ scale: defaultScale,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: 5,
|
|
|
+ scale: defaultScale - 0.2,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: 10,
|
|
|
+ scale: defaultScale - 0.5,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: 20,
|
|
|
+ scale: defaultScale - 1.5,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: 30,
|
|
|
+ scale: defaultScale - 2,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: 50,
|
|
|
+ scale: defaultScale - 2.5,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: 100,
|
|
|
+ scale: defaultScale - 3.5,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: 200,
|
|
|
+ scale: defaultScale - 4.5,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ options: {
|
|
|
+ distance: defaulDistance,
|
|
|
+ status: 0,
|
|
|
+ },
|
|
|
+ status: [
|
|
|
+ {
|
|
|
+ title: "全部",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "空闲",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "忙碌",
|
|
|
+ },
|
|
|
+ ],
|
|
|
+});
|
|
|
+
|
|
|
+const stationPage = ref({
|
|
|
+ page: 1,
|
|
|
+ pageSize: 6,
|
|
|
+ hasNext: false,
|
|
|
+});
|
|
|
+const station = ref<any[]>([]);
|
|
|
+const charging = ref<any>();
|
|
|
+
|
|
|
+const mapMode = ref(true);
|
|
|
+const mapProps = ref({
|
|
|
+ latitude: 23.098994,
|
|
|
+ longitude: 113.32252,
|
|
|
+ selflatitude: 23.098994,
|
|
|
+ selflongitude: 113.32252,
|
|
|
+ scale: defaultScale,
|
|
|
+});
|
|
|
+const markersIndex = ref(-1);
|
|
|
+const markers = ref<any[]>([]);
|
|
|
+const mapBanner = ref<any[]>([]);
|
|
|
+
|
|
|
+let isIgnoreChangeLocation = false;
|
|
|
+
|
|
|
+const refreshStation = (location: any) => {
|
|
|
+ let length = 0;
|
|
|
+ let available = 0;
|
|
|
+ const { latitude, longitude } = location;
|
|
|
+ if (!token.value) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ return fetchStations(
|
|
|
+ stationPage.value.page,
|
|
|
+ stationPage.value.pageSize,
|
|
|
+ latitude,
|
|
|
+ longitude,
|
|
|
+ mapProps.value.selflatitude,
|
|
|
+ mapProps.value.selflongitude,
|
|
|
+ {
|
|
|
+ distance: filterDialog.value.options.distance,
|
|
|
+ status: filterDialog.value.options.status,
|
|
|
+ }
|
|
|
+ ).then((res) => {
|
|
|
+ const _markersIndex = stationPage.value.page === 1 ? 0 : markersIndex.value;
|
|
|
+ const _markers: any[] = res.map((item, index) => {
|
|
|
+ length = 0;
|
|
|
+ available = 0;
|
|
|
+ item.equipmentInfos &&
|
|
|
+ item.equipmentInfos.forEach((eq: any) => {
|
|
|
+ eq.connectorInfos &&
|
|
|
+ eq.connectorInfos.forEach((co: any) => {
|
|
|
+ length += 1;
|
|
|
+ if (
|
|
|
+ co.connectorStatusInfo &&
|
|
|
+ co.connectorStatusInfo.status === 1
|
|
|
+ ) {
|
|
|
+ available += 1;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ return {
|
|
|
+ id: Number(item.StationID),
|
|
|
+ latitude: item.location.stationLat,
|
|
|
+ longitude: item.location.stationLng,
|
|
|
+ iconPath:
|
|
|
+ index === _markersIndex
|
|
|
+ ? pointSize.currentIconPath
|
|
|
+ : pointSize.iconPath,
|
|
|
+ width:
|
|
|
+ index === _markersIndex ? pointSize.currentWidth : pointSize.width,
|
|
|
+ height:
|
|
|
+ index === _markersIndex ? pointSize.currentHeight : pointSize.height,
|
|
|
+ label: {
|
|
|
+ content: `${available}/${length}`,
|
|
|
+ color: "#ffffff",
|
|
|
+ fontSize:
|
|
|
+ index === _markersIndex
|
|
|
+ ? pointSize.currentFontSize
|
|
|
+ : pointSize.fontSize,
|
|
|
+ textAlign: isIOS.value ? "center" : "left",
|
|
|
+ anchorX: isIOS.value
|
|
|
+ ? 0
|
|
|
+ : index === _markersIndex
|
|
|
+ ? pointSize.androidCurrentX
|
|
|
+ : pointSize.androidX,
|
|
|
+ anchorY: -(
|
|
|
+ (index === _markersIndex
|
|
|
+ ? pointSize.currentHeight
|
|
|
+ : pointSize.height) - 3
|
|
|
+ ),
|
|
|
+ },
|
|
|
+ };
|
|
|
+ });
|
|
|
+ if (stationPage.value.page === 1) {
|
|
|
+ _markers.push({
|
|
|
+ id: -1,
|
|
|
+ latitude: mapProps.value.selflatitude,
|
|
|
+ longitude: mapProps.value.selflongitude,
|
|
|
+ iconPath: "/static/images/map-current.png",
|
|
|
+ width: 34,
|
|
|
+ height: 34,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ isIgnoreChangeLocation = markers.value.length !== _markers.length;
|
|
|
+ stationPage.value.hasNext = res.length >= stationPage.value.pageSize;
|
|
|
+ // empty.value = stationPage.value.page === 1 ? res.length <= 0 : false;
|
|
|
+ station.value =
|
|
|
+ stationPage.value.page === 1 ? res : [...station.value, ...res];
|
|
|
+ markersIndex.value = _markersIndex;
|
|
|
+ markers.value = _markers;
|
|
|
+ return res;
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const refresh = () => {
|
|
|
+ if (loading.value) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ console.log("刷新电站");
|
|
|
+ uni.showLoading({
|
|
|
+ title: "加载中",
|
|
|
+ });
|
|
|
+ loading.value = true;
|
|
|
+ stationPage.value.page = 1;
|
|
|
+ stationPage.value.hasNext = false;
|
|
|
+ station.value = [];
|
|
|
+ markers.value = [];
|
|
|
+ markersIndex.value = 0;
|
|
|
+ fetchLocation()
|
|
|
+ .then((res: any) => {
|
|
|
+ mapProps.value.latitude = res.latitude;
|
|
|
+ mapProps.value.longitude = res.longitude;
|
|
|
+ mapProps.value.selflatitude = res.latitude;
|
|
|
+ mapProps.value.selflongitude = res.longitude;
|
|
|
+ isIgnoreChangeLocation = true;
|
|
|
+ return refreshStation(res);
|
|
|
+ })
|
|
|
+ .then(() => {
|
|
|
+ uni.hideLoading();
|
|
|
+ loading.value = false;
|
|
|
+ ready.value = true;
|
|
|
+ })
|
|
|
+ .catch((err) => {
|
|
|
+ console.log(err);
|
|
|
+ uni.hideLoading();
|
|
|
+ loading.value = false;
|
|
|
+ uni.showModal({
|
|
|
+ content: `${err.errMsg},请重试`,
|
|
|
+ });
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const handleNavReady = (e: any) => {
|
|
|
+ console.log(e);
|
|
|
+ styleData.value.dialog = `padding-top:${e.detail.statusBarHeight - 6}px;`;
|
|
|
+ const searchHeight = rpxToPx(88);
|
|
|
+ const filterHeight = 0; // rpxToPx(72);
|
|
|
+ styleData.value.dialogHeight =
|
|
|
+ e.detail.statusBarHeight - 6 + searchHeight + filterHeight;
|
|
|
+ styleData.value.dialogPlaceHolderHeight =
|
|
|
+ styleData.value.dialogHeight - e.detail.navigationBarHeight;
|
|
|
+ styleData.value.cardHeight = rpxToPx(402) + e.detail.statusBarHeight;
|
|
|
+ styleData.value.navHeight = e.detail.navigationBarHeight;
|
|
|
+};
|
|
|
+
|
|
|
+const toSearch = () => {
|
|
|
+ if (!ready.value) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ uni.navigateTo({
|
|
|
+ url: "/pages-charge/search/search",
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+onLoad((query: any) => {
|
|
|
+ // 只为了打包进tab-bar使用
|
|
|
+ console.log(fetchToken, login, onLogin);
|
|
|
+ // 扫普通码
|
|
|
+ if (query.q) {
|
|
|
+ console.log("扫普通码", decodeURIComponent(query.q));
|
|
|
+ getApp<any>().globalData.normalCode = decodeURIComponent(query.q); // 获取到二维码原始链接内容
|
|
|
+ }
|
|
|
+ const device = uni.getSystemInfoSync();
|
|
|
+ isIOS.value = device.osName === "ios";
|
|
|
+
|
|
|
+ setTimeout(() => {
|
|
|
+ token.value = getApp<any>().globalData.token || "";
|
|
|
+ if (!token.value) {
|
|
|
+ isIgnoreChangeLocation = true;
|
|
|
+ fetchLocation().then((res: any) => {
|
|
|
+ mapProps.value.latitude = res.latitude;
|
|
|
+ mapProps.value.longitude = res.longitude;
|
|
|
+ mapProps.value.selflatitude = res.latitude;
|
|
|
+ mapProps.value.selflongitude = res.longitude;
|
|
|
+ markers.value = [
|
|
|
+ {
|
|
|
+ id: -1,
|
|
|
+ latitude: res.latitude,
|
|
|
+ longitude: res.longitude,
|
|
|
+ iconPath: "/static/images/map-current.png",
|
|
|
+ width: 34,
|
|
|
+ height: 34,
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ });
|
|
|
+ onLogin((_token) => {
|
|
|
+ if (getApp<any>().globalData.normalCode) {
|
|
|
+ const code: string = getApp<any>().globalData.normalCode;
|
|
|
+ getApp<any>().globalData.normalCode = "";
|
|
|
+ deCode(code);
|
|
|
+ }
|
|
|
+ token.value = _token;
|
|
|
+ fetchCollectList().then(() => {
|
|
|
+ refresh();
|
|
|
+ fetchCharging();
|
|
|
+ fetchBanner();
|
|
|
+ });
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ fetchCollectList().then(() => {
|
|
|
+ if (getApp<any>().globalData.normalCode) {
|
|
|
+ const code: string = getApp<any>().globalData.normalCode;
|
|
|
+ getApp<any>().globalData.normalCode = "";
|
|
|
+ deCode(code);
|
|
|
+ }
|
|
|
+ refresh();
|
|
|
+ fetchCharging();
|
|
|
+ fetchBanner();
|
|
|
+ });
|
|
|
+ }, 300);
|
|
|
+});
|
|
|
+
|
|
|
+onShow(() => {
|
|
|
+ if (token.value) {
|
|
|
+ fetchBanner();
|
|
|
+ charging.value = undefined;
|
|
|
+ setTimeout(() => {
|
|
|
+ fetchCharging();
|
|
|
+ }, 2000);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+const fetchCharging = () => {
|
|
|
+ fetchChargeStatus().then((res) => {
|
|
|
+ if (res && [0, 1, 2, 3].includes(res.chargeStatus)) {
|
|
|
+ charging.value = res;
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const fetchBanner = () => {
|
|
|
+ fetchHomeBanner().then((res) => {
|
|
|
+ mapBanner.value = res.filter((item: any) => item.status === 1);
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+// const checkDiscounts = () => {
|
|
|
+// filterDialog.value.discounts = !filterDialog.value.discounts;
|
|
|
+// };
|
|
|
+
|
|
|
+const checkFilterDistance = () => {
|
|
|
+ if (isIgnoreChangeLocation) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!mapMode.value) {
|
|
|
+ mapMode.value = true;
|
|
|
+ }
|
|
|
+ filterDialog.value.distanceSelector = !filterDialog.value.distanceSelector;
|
|
|
+};
|
|
|
+
|
|
|
+const changeFilterDistance = (index: number) => {
|
|
|
+ filterDialog.value.options.distance =
|
|
|
+ filterDialog.value.distanceRange[index].value;
|
|
|
+ if (mapProps.value.scale === filterDialog.value.distanceRange[index].scale) {
|
|
|
+ refresh();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ mapProps.value.scale = filterDialog.value.distanceRange[index].scale;
|
|
|
+ checkFilterDistance();
|
|
|
+};
|
|
|
+
|
|
|
+const resetLocation = () => {
|
|
|
+ if (loading.value) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // eslint-disable-next-line promise/catch-or-return
|
|
|
+ fetchLocation().then((res: any) => {
|
|
|
+ const mapCtx = uni.createMapContext("map");
|
|
|
+ const { latitude, longitude } = res;
|
|
|
+ mapCtx.moveToLocation({
|
|
|
+ latitude,
|
|
|
+ longitude,
|
|
|
+ });
|
|
|
+ mapProps.value.scale = defaultScale;
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const mapUpdated = (e: any) => {
|
|
|
+ // console.log('map updated', isIgnoreChangeLocation)
|
|
|
+ setTimeout(() => {
|
|
|
+ isIgnoreChangeLocation = false;
|
|
|
+ }, 500);
|
|
|
+};
|
|
|
+const mapChange = (e: any) => {
|
|
|
+ if (isIgnoreChangeLocation) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (e.type === "end" && markers.value.length) {
|
|
|
+ // console.log("map change end", {
|
|
|
+ // ...e.detail.centerLocation,
|
|
|
+ // });
|
|
|
+ const current = e.target.centerLocation;
|
|
|
+ const { latitude, longitude } = current;
|
|
|
+ stationPage.value.page = 1;
|
|
|
+ refreshStation({
|
|
|
+ latitude,
|
|
|
+ longitude,
|
|
|
+ });
|
|
|
+ }
|
|
|
+};
|
|
|
+const _changeMarker = (current: number) => {
|
|
|
+ const _markers = JSON.parse(JSON.stringify(markers.value));
|
|
|
+ const markersNewIndex = current;
|
|
|
+ _markers[markersIndex.value].iconPath = pointSize.iconPath;
|
|
|
+ _markers[markersIndex.value].width = pointSize.width;
|
|
|
+ _markers[markersIndex.value].height = pointSize.height;
|
|
|
+ _markers[markersIndex.value].label.fontSize = pointSize.fontSize;
|
|
|
+ _markers[markersIndex.value].label.anchorY = -(pointSize.height - 3);
|
|
|
+ if (!isIOS) {
|
|
|
+ _markers[markersIndex.value].label.anchorX = pointSize.androidX;
|
|
|
+ }
|
|
|
+
|
|
|
+ _markers[markersNewIndex].iconPath = pointSize.currentIconPath;
|
|
|
+ _markers[markersNewIndex].width = pointSize.currentWidth;
|
|
|
+ _markers[markersNewIndex].height = pointSize.currentHeight;
|
|
|
+ _markers[markersNewIndex].label.fontSize = pointSize.currentFontSize;
|
|
|
+ _markers[markersNewIndex].label.anchorY = -(pointSize.currentHeight - 3);
|
|
|
+ if (!isIOS) {
|
|
|
+ _markers[markersNewIndex].label.anchorX = pointSize.androidCurrentX;
|
|
|
+ }
|
|
|
+
|
|
|
+ isIgnoreChangeLocation = true;
|
|
|
+ markers.value = _markers;
|
|
|
+ markersIndex.value = markersNewIndex;
|
|
|
+ if (stationPage.value.hasNext && markersNewIndex >= _markers.length - 2) {
|
|
|
+ stationPage.value.page += 1;
|
|
|
+ refreshStation({
|
|
|
+ latitude: mapProps.value.selflatitude,
|
|
|
+ longitude: mapProps.value.selflongitude,
|
|
|
+ });
|
|
|
+ }
|
|
|
+};
|
|
|
+const tapMarker = (e: any) => {
|
|
|
+ if (e.detail.markerId === -1) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const findIndex = station.value.findIndex(
|
|
|
+ (item) => Number(item.StationID) === Number(e.detail.markerId)
|
|
|
+ );
|
|
|
+ if (findIndex >= 0) {
|
|
|
+ _changeMarker(findIndex);
|
|
|
+ }
|
|
|
+};
|
|
|
+const loginMask = (e: any) => {
|
|
|
+ login(e);
|
|
|
+};
|
|
|
+
|
|
|
+let startpageY = 0;
|
|
|
+const touchCardStart = (e: any) => {
|
|
|
+ if (loading.value || station.value.length <= 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (e.touches && e.touches.length) {
|
|
|
+ startpageY = e.touches[0].pageY;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const touchCardMove = (e: any) => {
|
|
|
+ if (!startpageY) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const threshold = 200;
|
|
|
+ if (e.touches && e.touches.length) {
|
|
|
+ if (mapMode.value && startpageY - e.touches[0].pageY > threshold) {
|
|
|
+ mapMode.value = false;
|
|
|
+ }
|
|
|
+ if (!mapMode.value && e.touches[0].pageY - startpageY > threshold) {
|
|
|
+ mapMode.value = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const toCharging = () => {
|
|
|
+ to(
|
|
|
+ charging.value.chargeStatus === 0
|
|
|
+ ? `/pages-charge/appointment/appointment?sn=${charging.value.connectorId}`
|
|
|
+ : `/pages-charge/ordering/ordering?sn=${charging.value.connectorId}&start=1`
|
|
|
+ );
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss">
|
|
|
+page {
|
|
|
+ background-color: #ffffff;
|
|
|
+}
|
|
|
+
|
|
|
+.container {
|
|
|
+ position: relative;
|
|
|
+ height: 100vh;
|
|
|
+ width: 100vw;
|
|
|
+ background-color: #ffffff;
|
|
|
+}
|
|
|
+
|
|
|
+.mock-map {
|
|
|
+ position: relative;
|
|
|
+ width: 100vw;
|
|
|
+ background-color: #ffffff;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
+.login-mask {
|
|
|
+ position: fixed;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ z-index: 999999;
|
|
|
+ opacity: 0;
|
|
|
+
|
|
|
+ .full {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.dialog {
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ z-index: 1000;
|
|
|
+
|
|
|
+ &_logo {
|
|
|
+ width: 156rpx;
|
|
|
+ height: 100%;
|
|
|
+ background-position: center;
|
|
|
+ background-size: 100% auto;
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-image: url("/static/images/map-logo.png");
|
|
|
+ }
|
|
|
+
|
|
|
+ &_search {
|
|
|
+ width: 352rpx;
|
|
|
+ height: 100%;
|
|
|
+ background-position: center;
|
|
|
+ background-size: 100% auto;
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-image: url("/static/images/map-input.png");
|
|
|
+ }
|
|
|
+
|
|
|
+ &_event {
|
|
|
+ margin-top: 20rpx;
|
|
|
+ padding: 0rpx 32rpx;
|
|
|
+ .swiper {
|
|
|
+ height: 160rpx;
|
|
|
+ width: 100%;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ overflow: hidden;
|
|
|
+ .swiper-item {
|
|
|
+ border-radius: 16rpx;
|
|
|
+ overflow: hidden;
|
|
|
+ }
|
|
|
+ view {
|
|
|
+ background-position: center;
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &_selector {
|
|
|
+ background-color: #f9f9f9;
|
|
|
+ transition: all 0.3s;
|
|
|
+ overflow: hidden;
|
|
|
+ .type {
|
|
|
+ width: 160rpx;
|
|
|
+ height: 60rpx;
|
|
|
+ background: var(--color-sec);
|
|
|
+ border-radius: 4rpx;
|
|
|
+ color: #666;
|
|
|
+ font-size: 26rpx;
|
|
|
+ border: 1px solid var(--color-sec);
|
|
|
+ }
|
|
|
+
|
|
|
+ .type-active {
|
|
|
+ border: 1px solid var(--color-primary);
|
|
|
+ color: var(--color-primary);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* .slider {
|
|
|
+ position: relative;
|
|
|
+ height: 12rpx;
|
|
|
+ width: 100%;
|
|
|
+ border-radius: 8rpx;
|
|
|
+ background-color: var(--color-sec);
|
|
|
+ margin-top: 10rpx;
|
|
|
+
|
|
|
+ &_active {
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ background-color: var(--color-primary);
|
|
|
+ border-radius: 8rpx;
|
|
|
+ height: 12rpx;
|
|
|
+ width: 0%;
|
|
|
+ }
|
|
|
+
|
|
|
+ &_block {
|
|
|
+ position: absolute;
|
|
|
+ width: 40rpx;
|
|
|
+ height: 40rpx;
|
|
|
+ border-radius: 50%;
|
|
|
+ top: -15rpx;
|
|
|
+ left: 0;
|
|
|
+ background: rgba(255, 255, 255, 1);
|
|
|
+ box-shadow: 0px 4rpx 6rpx rgba(52, 125, 255, 0.4);
|
|
|
+ }
|
|
|
+
|
|
|
+ &_wx {
|
|
|
+ position: absolute;
|
|
|
+ width: 100%;
|
|
|
+ left: 0px;
|
|
|
+ top: -5px;
|
|
|
+ margin: 0;
|
|
|
+ opacity: 0;
|
|
|
+ }
|
|
|
+ } */
|
|
|
+}
|
|
|
+
|
|
|
+.card {
|
|
|
+ position: fixed;
|
|
|
+ width: 100%;
|
|
|
+ left: 0px;
|
|
|
+ z-index: 1000;
|
|
|
+ transition: all 0.3s;
|
|
|
+ box-shadow: 0px 8rpx 20rpx rgba(0, 0, 0, 0.2);
|
|
|
+ background-color: #fff;
|
|
|
+
|
|
|
+ &_location {
|
|
|
+ position: absolute;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ box-shadow: 0px 8rpx 20rpx 0px rgba(0, 0, 0, 0.2);
|
|
|
+ right: 20rpx;
|
|
|
+ top: -104rpx;
|
|
|
+ z-index: 99;
|
|
|
+ }
|
|
|
+
|
|
|
+ &_line {
|
|
|
+ height: 1rpx;
|
|
|
+ background-color: rgba(0, 0, 0, 0.1);
|
|
|
+ margin-left: 30rpx;
|
|
|
+ margin-right: 30rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ &_empty {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ .image {
|
|
|
+ width: 160rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .station-placeholder {
|
|
|
+ min-height: 104rpx;
|
|
|
+ }
|
|
|
+ .station-iphonex {
|
|
|
+ box-sizing: content-box;
|
|
|
+ padding-bottom: constant(safe-area-inset-bottom);
|
|
|
+ padding-bottom: env(safe-area-inset-bottom);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.charging {
|
|
|
+ position: fixed;
|
|
|
+ z-index: 1000;
|
|
|
+ right: 0;
|
|
|
+ bottom: 164rpx;
|
|
|
+ width: 186rpx;
|
|
|
+ height: 88rpx;
|
|
|
+ border-radius: 88rpx 0px 0px 88rpx;
|
|
|
+ background: #2d9e95;
|
|
|
+ margin-bottom: constant(safe-area-inset-bottom);
|
|
|
+ margin-bottom: env(safe-area-inset-bottom);
|
|
|
+}
|
|
|
+</style>
|