|
|
@@ -1,7 +1,7 @@
|
|
|
<template>
|
|
|
<view :class="['page']">
|
|
|
<view v-if="station && priceInfo">
|
|
|
- <view class="block">
|
|
|
+ <view class="block anim-fade-up">
|
|
|
<view class="station">
|
|
|
<ChargeMachine
|
|
|
:title="'NO.' + equipment.shortId"
|
|
|
@@ -21,49 +21,49 @@
|
|
|
</view>
|
|
|
<!-- <view class="mt-40 ml-30 color-999 fs-32 fw-500">费用说明</view>-->
|
|
|
<view
|
|
|
- class="mt-20 block height-96 flex-align-center pl-30 pr-30"
|
|
|
+ class="mt-20 block height-96 flex-align-center pl-30 pr-30 pressable anim-fade-up"
|
|
|
+ style="animation-delay: 0.04s"
|
|
|
+ hover-class="pressed"
|
|
|
@click="openPriceDesc"
|
|
|
>
|
|
|
- <view class="fs-28 color-000">充电费用</view>
|
|
|
- <view class="ml-64 fs-26 color-333"
|
|
|
+ <view class="fs-28 color-333 fw-500">充电费用</view>
|
|
|
+ <view class="ml-auto fs-26 color-666 mr-8"
|
|
|
>{{ priceInfo.minPrice }}~{{ priceInfo.maxPrice }}元/度
|
|
|
</view
|
|
|
>
|
|
|
- <view class="ml-auto">
|
|
|
- <uni-icons type="right" size="16" color="rgba(28,43,41,0.4)"></uni-icons>
|
|
|
- </view>
|
|
|
+ <uni-icons type="right" size="16" color="rgba(28,43,41,0.4)"></uni-icons>
|
|
|
</view>
|
|
|
<template v-if="appointmentData">
|
|
|
- <view class="mt-40 color-999 fs-32 fw-500">已预约充电</view>
|
|
|
- <view class="mt-20 block flex-align-center" style="height: 180rpx">
|
|
|
- <image
|
|
|
- src="../static/icon-alarm.png"
|
|
|
- mode="widthFix"
|
|
|
- style="width: 32rpx; display: block"
|
|
|
- ></image>
|
|
|
- <view class="ml-24">
|
|
|
- <view class="flex" v-if="appointmentCountDown">
|
|
|
- <view class="fs-28 color-000">将在</view>
|
|
|
- <view class="fs-44 lh-36 color-primary ml-8 mr-8">{{
|
|
|
- appointmentCountDown
|
|
|
- }}
|
|
|
- </view>
|
|
|
- <view class="fs-28 color-000">后开始充电</view>
|
|
|
+ <view class="mt-20 block hero anim-fade-up" style="animation-delay: 0.08s">
|
|
|
+ <view class="flex-align-center pl-30 pr-30 pt-30">
|
|
|
+ <view class="hero-icon flex-center anim-breathe">
|
|
|
+ <uni-icons type="notification-filled" size="22" color="#2d9e95"></uni-icons>
|
|
|
</view>
|
|
|
- <view class="fs-24 color-999 mt-8"
|
|
|
- >注意:启动充电前请勿拔插充电枪!
|
|
|
- </view
|
|
|
- >
|
|
|
+ <view class="ml-16 fs-30 fw-600 color-333">已预约充电</view>
|
|
|
+ <view class="hero-tag ml-auto">等待开始</view>
|
|
|
+ </view>
|
|
|
+ <view class="mt-28 fs-24 color-999 text-center">距开始充电</view>
|
|
|
+ <view class="mt-16 flex-center">
|
|
|
+ <view v-for="(part, i) in countdownParts" :key="i" class="hero-cell">
|
|
|
+ <view class="hero-num">{{ part }}</view>
|
|
|
+ <view class="hero-unit">{{ ["时", "分", "秒"][i] }}</view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="mt-20 fs-24 color-999 text-center" v-if="appointmentStartText"
|
|
|
+ >预计 {{ appointmentStartText }} 开始充电
|
|
|
+ </view>
|
|
|
+ <view class="hero-tip flex-align-center ml-30 mr-30 mt-24">
|
|
|
+ <uni-icons type="info" size="14" color="#2d9e95"></uni-icons>
|
|
|
+ <view class="ml-8 fs-24 color-666">启动充电前请勿拔插充电枪</view>
|
|
|
+ </view>
|
|
|
+ <view class="mt-30 hero-divider"></view>
|
|
|
+ <view class="flex-center pt-20 pb-24">
|
|
|
+ <view
|
|
|
+ class="hero-cancel pressable flex-center"
|
|
|
+ hover-class="pressed"
|
|
|
+ @click="cancelAppointment"
|
|
|
+ >取消预约</view>
|
|
|
</view>
|
|
|
- </view>
|
|
|
- <view class="mt-40 flex-center">
|
|
|
- <view
|
|
|
- class="flex-center height-68 br-68 fs-26 color-666"
|
|
|
- style="width: 184rpx; border: 1px solid #c9d4d2"
|
|
|
- @click="cancelAppointment"
|
|
|
- >取消预约
|
|
|
- </view
|
|
|
- >
|
|
|
</view>
|
|
|
</template>
|
|
|
<template v-else>
|
|
|
@@ -175,39 +175,40 @@
|
|
|
</template>
|
|
|
<!-- 当前余额 + 低余额提醒,点击去充值(充值后返回本页) -->
|
|
|
<view
|
|
|
- class="mt-20 block flex-align-center pl-30 pr-30 pt-30 pb-30"
|
|
|
- :style="isLowBalance ? 'background-color: #fff5f5; border: 1rpx solid rgba(244, 54, 54, 0.25);' : ''"
|
|
|
+ class="mt-20 block flex-align-center pl-30 pr-30 pt-30 pb-30 pressable anim-fade-up"
|
|
|
+ :class="{ 'balance-low': isLowBalance }"
|
|
|
+ style="animation-delay: 0.12s"
|
|
|
+ hover-class="pressed"
|
|
|
@click="to('/pages-user/wallet-recharge/wallet-recharge?back=1')"
|
|
|
>
|
|
|
- <view class="flex-column">
|
|
|
- <view class="flex-align-center">
|
|
|
- <uni-icons type="wallet-filled" size="16" :color="isLowBalance ? '#f43636' : '#999'"></uni-icons>
|
|
|
- <view class="fs-26 ml-8 color-333">当前余额</view>
|
|
|
- </view>
|
|
|
- <view class="mt-8">
|
|
|
- <view class="fs-40 fw-600" :style="{ color: isLowBalance ? '#f43636' : '#333' }">{{ balanceText }}</view>
|
|
|
+ <view class="balance-icon flex-center flex-shrink">
|
|
|
+ <uni-icons
|
|
|
+ type="wallet-filled"
|
|
|
+ size="18"
|
|
|
+ :color="isLowBalance ? '#f43636' : '#2d9e95'"
|
|
|
+ ></uni-icons>
|
|
|
+ </view>
|
|
|
+ <view class="ml-20">
|
|
|
+ <view class="fs-24 color-999">当前余额</view>
|
|
|
+ <view class="flex-align-baseline mt-6">
|
|
|
+ <text class="fs-24 fw-500 color-666">¥</text>
|
|
|
+ <text
|
|
|
+ class="fs-44 fw-600 ml-4 lh-44"
|
|
|
+ :style="{ color: isLowBalance ? 'var(--color-error)' : 'var(--text-1)' }"
|
|
|
+ >{{ balanceValue }}
|
|
|
+ </text>
|
|
|
</view>
|
|
|
<view
|
|
|
v-if="isLowBalance"
|
|
|
- class="fs-24 mt-8 lh-30"
|
|
|
- style="color: #f43636"
|
|
|
- >余额仅 {{ balanceText }},可能无法完成本次充电
|
|
|
- </view
|
|
|
- >
|
|
|
- </view>
|
|
|
- <view class="ml-auto">
|
|
|
- <view
|
|
|
- class="flex-center fs-24 fw-500"
|
|
|
- :style="isLowBalance
|
|
|
- ? 'height: 56rpx; border-radius: 56rpx; background-color: var(--color-error); color: #fff; padding: 0 28rpx;'
|
|
|
- : 'height: 56rpx; border-radius: 56rpx; border: 1rpx solid #c9d4d2; color: #666; padding: 0 28rpx;'"
|
|
|
- >去充值
|
|
|
- </view
|
|
|
- >
|
|
|
+ class="fs-22 mt-4 lh-30"
|
|
|
+ style="color: var(--color-error)"
|
|
|
+ >余额较低,可能无法完成本次充电
|
|
|
+ </view>
|
|
|
</view>
|
|
|
+ <view class="ml-auto recharge-pill flex-center fs-24 fw-500 flex-shrink">去充值</view>
|
|
|
</view>
|
|
|
<view class="pt-60 pb-80"></view>
|
|
|
- <style-bottom-view>
|
|
|
+ <style-bottom-view :shadow="true">
|
|
|
<view class="pt-20 pl-40 pr-40 pb-20 bg-fff flex">
|
|
|
<template v-if="appointmentData">
|
|
|
<view class="mr-10" style="width: 50%">
|
|
|
@@ -375,7 +376,7 @@ const LOW_BALANCE_THRESHOLD = 30;
|
|
|
const isLowBalance = computed(
|
|
|
() => Number(balance.value) > 0 && Number(balance.value) < LOW_BALANCE_THRESHOLD
|
|
|
);
|
|
|
-const balanceText = computed(() => `${Number(balance.value).toFixed(2)}元`);
|
|
|
+const balanceValue = computed(() => Number(balance.value).toFixed(2));
|
|
|
|
|
|
|
|
|
const refreshUserBalance = () => {
|
|
|
@@ -691,6 +692,25 @@ const formatAppointmentCountDown = (time: string) => {
|
|
|
}:${secondTime < 10 ? "0" + secondTime : secondTime}`;
|
|
|
};
|
|
|
|
|
|
+/** 倒计时分段:["01", "20", "52"] 对应 时/分/秒 */
|
|
|
+const countdownParts = computed(() => {
|
|
|
+ const cd = appointmentCountDown.value;
|
|
|
+ return cd ? String(cd).split(":") : ["--", "--", "--"];
|
|
|
+});
|
|
|
+
|
|
|
+/** 预约开始时间的展示文案:今天/明天 M月d日 HH:mm */
|
|
|
+const appointmentStartText = computed(() => {
|
|
|
+ if (!appointmentData.value?.startTime) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ const ts = parseDate(appointmentData.value.startTime).getTime();
|
|
|
+ const dayDiff = Math.round(
|
|
|
+ (new Date(ts).setHours(0, 0, 0, 0) - new Date().setHours(0, 0, 0, 0)) / DAY
|
|
|
+ );
|
|
|
+ const dayText = dayDiff <= 0 ? "今天" : dayDiff === 1 ? "明天" : format("M月d日", ts);
|
|
|
+ return `${dayText} ${format("h:m", ts)}`;
|
|
|
+});
|
|
|
+
|
|
|
const submit = () => {
|
|
|
if (
|
|
|
chargeType.value === 0 &&
|
|
|
@@ -946,8 +966,8 @@ onUnload(() => {
|
|
|
.page {
|
|
|
min-height: 100vh;
|
|
|
width: 100%;
|
|
|
- padding: 20rpx;
|
|
|
- background-color: #f6f7fa;
|
|
|
+ padding: 24rpx 30rpx 0;
|
|
|
+ background-color: var(--bg-page);
|
|
|
}
|
|
|
|
|
|
.block {
|
|
|
@@ -960,6 +980,107 @@ onUnload(() => {
|
|
|
border-bottom: 1rpx solid var(--divider);
|
|
|
}
|
|
|
|
|
|
+/* ============ 预约状态主卡 ============ */
|
|
|
+.hero-icon {
|
|
|
+ width: 72rpx;
|
|
|
+ height: 72rpx;
|
|
|
+ border-radius: 50%;
|
|
|
+ background: var(--color-primary-tint-strong);
|
|
|
+ flex-shrink: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.hero-tag {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ height: 44rpx;
|
|
|
+ padding: 0 20rpx;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ background: var(--color-primary-tint);
|
|
|
+ color: var(--color-primary);
|
|
|
+ font-size: 24rpx;
|
|
|
+ font-weight: 500;
|
|
|
+ flex-shrink: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.hero-cell {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ width: 128rpx;
|
|
|
+ padding: 20rpx 0 14rpx;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ background: var(--color-primary-tint);
|
|
|
+}
|
|
|
+
|
|
|
+.hero-cell + .hero-cell {
|
|
|
+ margin-left: 16rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.hero-num {
|
|
|
+ font-size: 52rpx;
|
|
|
+ line-height: 56rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: var(--color-primary);
|
|
|
+ font-variant-numeric: tabular-nums;
|
|
|
+}
|
|
|
+
|
|
|
+.hero-unit {
|
|
|
+ margin-top: 4rpx;
|
|
|
+ font-size: 20rpx;
|
|
|
+ color: var(--text-3);
|
|
|
+}
|
|
|
+
|
|
|
+.hero-tip {
|
|
|
+ height: 64rpx;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ background: var(--color-sec);
|
|
|
+}
|
|
|
+
|
|
|
+.hero-divider {
|
|
|
+ border-top: 1rpx solid var(--divider);
|
|
|
+}
|
|
|
+
|
|
|
+.hero-cancel {
|
|
|
+ min-width: 240rpx;
|
|
|
+ height: 64rpx;
|
|
|
+ padding: 0 48rpx;
|
|
|
+ border: 1rpx solid var(--divider);
|
|
|
+ border-radius: 32rpx;
|
|
|
+ background: #fff;
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: var(--text-2);
|
|
|
+}
|
|
|
+
|
|
|
+/* ============ 余额卡 ============ */
|
|
|
+.balance-icon {
|
|
|
+ width: 72rpx;
|
|
|
+ height: 72rpx;
|
|
|
+ border-radius: 50%;
|
|
|
+ background: var(--color-primary-tint-strong);
|
|
|
+}
|
|
|
+
|
|
|
+.balance-low {
|
|
|
+ background-color: rgba(244, 54, 54, 0.04);
|
|
|
+ border: 1rpx solid rgba(244, 54, 54, 0.25);
|
|
|
+}
|
|
|
+
|
|
|
+.balance-low .balance-icon {
|
|
|
+ background: rgba(244, 54, 54, 0.08);
|
|
|
+}
|
|
|
+
|
|
|
+.recharge-pill {
|
|
|
+ height: 56rpx;
|
|
|
+ padding: 0 28rpx;
|
|
|
+ border-radius: 28rpx;
|
|
|
+ background: var(--color-primary-tint);
|
|
|
+ color: var(--color-primary);
|
|
|
+}
|
|
|
+
|
|
|
+.balance-low .recharge-pill {
|
|
|
+ background: var(--color-error);
|
|
|
+ color: #fff;
|
|
|
+}
|
|
|
+
|
|
|
/* ============ 时间选择器 ============ */
|
|
|
.time-picker {
|
|
|
background-color: #fff;
|