| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437 |
- <template>
- <!-- #ifdef MP-WEIXIN -->
- <page-meta page-style="overflow: {{y ? 'hidden' : 'visible'}}" />
- <!-- #endif -->
- <view :class="['pb-40']" v-if="station">
- <view class="banner">
- <swiper
- class="full-percent"
- circular
- :indicator-dots="true"
- :autoplay="true"
- :interval="3000"
- >
- <swiper-item
- class="full-percent"
- v-for="(item, index) in station.bannerImages"
- :key="index"
- >
- <view
- class="full-percent banner-image"
- :style="{
- backgroundImage: `url(${item})`,
- }"
- @click="previewImage(item)"
- ></view>
- </swiper-item>
- </swiper>
- </view>
- <view class="pl-20 pr-20">
- <view class="station flex-column" v-if="canUseCount >= 0">
- <view class="fs-40 fw-600 color-000">{{ title }}</view>
- <view class="flex-align-center mt-10 height-48 relative flex-shrink">
- <image
- src="/pages-charge/static/machines-banner-address.png"
- mode="widthFix"
- style="width: 16px; display: block; flex-shrink: 0"
- />
- <view class="ml-12 fs-26 color-666">{{ location.address }}</view>
- <view class="flex-center ml-auto nav" @click="openAddress">
- <image
- src="/pages-charge/static/machines-banner-nav.png"
- mode="widthFix"
- />
- <view class="fs-26" style="color: #2d9e95">导航</view>
- </view>
- </view>
- <view
- class="foot mt-30 flex-align-center flex-shrink"
- @click="openDesc"
- >
- <view class="fs-28 color-666">可用充电桩:</view>
- <view class="fs-36 fw-500 color-primary">{{ canUseCount }}</view>
- <view class="fs-28 color-primary ml-6">个</view>
- <view class="fs-28 color-666 ml-auto">{{ canUseTime }}</view>
- </view>
- </view>
- <view class="pt-40 pb-20 fs-32 fw-500 color-999">详细说明</view>
- <view class="desc" v-if="station">
- <view class="flex-align-center" @click="openDesc">
- <view class="width-168 fs-26 color-666">充电费用</view>
- <view class="fs-26 color-000">{{ canUsePrice }}元/度</view>
- <view class="ml-auto lh-0">
- <uni-icons
- type="right"
- size="18"
- color="rgba(0,0,0,0.4)"
- ></uni-icons>
- </view>
- </view>
- <view class="flex-align-center">
- <view class="width-168 fs-26 color-666">停车费用</view>
- <view class="fs-26 color-000">{{
- Number(station.parkFee) > 0
- ? station.parkFee
- : "以停车场公示信息为准"
- }}</view>
- </view>
- <view
- class="flex-align-center"
- v-if="
- station &&
- station.equipmentInfos &&
- station.equipmentInfos.length &&
- station.equipmentInfos[0].connectorInfos
- "
- >
- <view class="width-168 fs-26 color-666">充电桩类型</view>
- <view class="fs-26 color-000"
- >{{
- station.equipmentInfos[0].connectorInfos[0].connectorType === 1
- ? "直流"
- : "交流"
- }}{{ station.equipmentInfos[0].connectorInfos[0].power }}kw</view
- >
- </view>
- </view>
- <view class="pt-40 flex-align-center">
- <view class="fs-32 fw-500 color-999">充电桩</view>
- <view class="fs-26 color-999" v-if="station"
- >(共{{ totalCount }}个)</view
- >
- <view class="ml-auto flex-align-center" @click="openStatus">
- <view class="fs-28 color-333 mr-16">{{
- statusList[status].title
- }}</view>
- <view
- style="
- width: 0;
- height: 0;
- border: 8rpx solid;
- border-color: #333 transparent transparent transparent;
- margin-top: 8rpx;
- "
- ></view>
- </view>
- </view>
- <template
- v-if="station"
- v-for="(item, index) in stationEquipmentInfos"
- :key="index"
- >
- <ChargeMachine
- :title="'NO.' + item.shortId"
- :price="station.totalFee"
- :list="item.connectorInfos"
- :parkingNo="item.parkingNo"
- ></ChargeMachine>
- </template>
- </view>
- <PriceDesc
- v-if="dialogVisible && dialogType === 'desc'"
- :desc="desc"
- @close="closeDialog"
- ></PriceDesc>
- <view
- class="dialog flex-align-end"
- v-if="dialogVisible && dialogType === 'status'"
- >
- <view class="status-dialog">
- <view class="status-dialog_head flex-center">
- <view class="fw-500 color-000" style="font-size: 16px"
- >选择充电桩状态</view
- >
- <view class="close" @click="closeDialog">
- <uni-icons type="closeempty" size="24" color="#2D284B"></uni-icons>
- </view>
- </view>
- <view class="status-dialog_body">
- <view class="status">
- <view
- :class="['fs-32', 'flex-align-center']"
- :style="{ color: status === index ? '#2d9e95' : '#2d284b' }"
- v-for="(statusItem, index) in statusList"
- :key="index"
- @click="changeStatus(index)"
- >
- {{ statusItem.title }}
- </view>
- </view>
- </view>
- </view>
- </view>
- </view>
- </template>
- <script setup lang="ts">
- import { ref } from "vue";
- import { fetchStation, fetchStationPriceDesc } from "../../api/charge";
- import { onLoad } from "@dcloudio/uni-app";
- import ChargeMachine from "./charge-machine/charge-machine.vue";
- import PriceDesc from "./price-desc/price-desc.vue";
- const dialogVisible = ref(false);
- const dialogType = ref("");
- const desc = ref<any[]>([]);
- const status = ref(0);
- const statusList = ref([
- {
- title: "全部",
- },
- {
- title: "空闲",
- },
- {
- title: "充电中",
- },
- ]);
- const totalCount = ref(0);
- const canUseCount = ref(0);
- const canUseTime = ref("");
- const canUsePrice = ref("");
- const title = ref("");
- const location = ref({
- address: "",
- latitude: "",
- longitude: "",
- });
- const station = ref();
- const stationEquipmentInfos = ref();
- const currentTime = ref();
- onLoad((options: any) => {
- const _title = options.title || "";
- uni.setNavigationBarTitle({
- title: _title,
- });
- title.value = _title;
- if (getApp<any>().globalData.lastData.station) {
- const { address, latitude, longitude } =
- getApp<any>().globalData.lastData.station;
- location.value = {
- address,
- latitude,
- longitude,
- };
- getApp<any>().globalData.lastData.station = undefined;
- }
- uni.showLoading({
- title: "加载中",
- mask: true,
- });
- fetchStation(Number(options.id))
- .then((res) => {
- console.log(res);
- let ConnectorID = "";
- if (res.equipmentInfos && res.equipmentInfos.length) {
- res.equipmentInfos.forEach((item: any) => {
- if (item.connectorInfos && item.connectorInfos.length) {
- item.connectorInfos.forEach((con: any) => {
- totalCount.value++;
- if (!ConnectorID) {
- ConnectorID = con.connectorId;
- }
- if (
- con.connectorStatusInfo &&
- con.connectorStatusInfo.status === 1
- ) {
- canUseCount.value++;
- }
- });
- }
- });
- }
- res.bannerImages = res.pictures.split(",");
- station.value = res;
- stationEquipmentInfos.value = res.equipmentInfos.map((item: any) => {
- return {
- ...item,
- };
- });
- if (ConnectorID) {
- return fetchStationPriceDesc(ConnectorID);
- } else {
- // eslint-disable-next-line promise/no-return-wrap
- return Promise.resolve({
- policyInfos: [],
- });
- }
- })
- .then((res) => {
- uni.hideLoading();
- currentTime.value = res.currentTime;
- canUseTime.value = res.useTime;
- canUsePrice.value = `${res.minPrice}~${res.maxPrice}`;
- desc.value = res.policyInfos || [];
- })
- .catch((err) => {
- // eslint-disable-next-line no-console
- console.log(err);
- uni.hideLoading();
- uni.showToast({
- title: "加载失败,请重试",
- icon: "none",
- });
- });
- });
- const openAddress = function () {
- uni.openLocation({
- latitude: Number(location.value.latitude),
- longitude: Number(location.value.longitude),
- scale: 18,
- name: title.value,
- address: location.value.address,
- });
- };
- const openDesc = function () {
- dialogVisible.value = true;
- dialogType.value = "desc";
- };
- const openStatus = function () {
- dialogVisible.value = true;
- dialogType.value = "status";
- };
- const closeDialog = function () {
- dialogVisible.value = false;
- };
- const changeStatus = function (index: number) {
- if (status.value === index) {
- closeDialog();
- return;
- }
- status.value = index;
- if (index === 0) {
- stationEquipmentInfos.value = station.value.equipmentInfos.map(
- (item: any) => {
- return {
- ...item,
- };
- }
- );
- closeDialog();
- return;
- }
- const STATUS_MAP = [-1, 1, 3];
- let newStationEquipmentInfos: any[] = [];
- station.value.equipmentInfos.forEach((item: any) => {
- let check = false;
- if (item.connectorInfos && item.connectorInfos.length) {
- item.connectorInfos.forEach((con: any) => {
- if (
- con.connectorStatusInfo &&
- Number(con.connectorStatusInfo.status) === STATUS_MAP[status.value]
- ) {
- check = true;
- }
- });
- }
- if (check) {
- newStationEquipmentInfos.push(item);
- }
- });
- stationEquipmentInfos.value = newStationEquipmentInfos;
- closeDialog();
- };
- const previewImage = (url: string) => {
- uni.previewImage({
- urls: station.value.bannerImages,
- current: url,
- });
- };
- </script>
- <style lang="scss">
- @import "../../styles/dialog.scss";
- page {
- background-color: #f5f5f5;
- }
- .banner {
- height: 440rpx;
- background-color: transparent;
- .banner-image {
- background-position: center;
- background-size: cover;
- background-repeat: no-repeat;
- }
- }
- .station {
- margin-top: -60rpx;
- border-radius: 20rpx;
- overflow: hidden;
- position: relative;
- background-color: #fff;
- min-height: 264rpx;
- padding: 0 40rpx;
- padding-top: 30rpx;
- .nav {
- flex-shrink: 0;
- width: 120rpx;
- height: 48rpx;
- border-radius: 40rpx;
- background: rgba(52, 125, 255, 0.1);
- image {
- width: 36rpx;
- }
- }
- .foot {
- border-top: 1px dashed rgba(0, 0, 0, 0.1);
- height: 96rpx;
- }
- }
- .desc {
- box-sizing: border-box;
- padding: 0rpx 30rpx;
- border-radius: 20rpx;
- background-color: #fff;
- & > view {
- height: 90rpx;
- border-top: 1px solid rgba(0, 0, 0, 0.1);
- &:first-child {
- border-top: none;
- }
- }
- }
- .status-dialog {
- background-color: transparent;
- width: 100%;
- overflow: hidden;
- border-radius: 20rpx 20rpx 0px 0px;
- &_head {
- padding: 24rpx 0px;
- position: relative;
- background-color: #fff;
- .close {
- position: absolute;
- right: 30rpx;
- top: 50%;
- transform: translateY(-50%);
- }
- }
- &_body {
- max-height: 860rpx;
- box-sizing: border-box;
- padding: 0rpx 30rpx 80rpx 30rpx;
- background-color: #fff;
- overflow-y: auto;
- .status {
- & > view {
- height: 92rpx;
- border-top: 1px solid rgba(0, 0, 0, 0.1);
- &:first-child {
- border-top: none;
- }
- }
- }
- }
- }
- </style>
|