Files
kccharge-app/pages/equipment-detail/index.vue
T
2025-10-28 09:25:46 +08:00

426 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<s-layout title="开始充电" navbar="normal" onShareAppMessage @clickLeft="clearTimer">
<kx-equipment-info :detail="detail"></kx-equipment-info>
<uni-card is-shadow spacing="0" padding="30rpx">
<view class="header">
<view class="line"></view>
<view>
价格信息
</view>
</view>
<view class="time">
价格时段:{{currentCostTemplatePrice.startTimeStr}}-{{currentCostTemplatePrice.endTimeStr}}
</view>
<view class="charge">
<view class="price">
<text>{{(currentCostTemplatePriceType.pricePower+currentCostTemplatePriceType.priceService).toFixed(2)}}</text>
/
</view>
<view class="vip">
<image src="https://kxcharge.oss-cn-beijing.aliyuncs.com/16568@2x.png" mode="aspectFit"></image>
<text>
{{(currentCostTemplatePriceType.pricePower+currentCostTemplatePriceType.priceService).toFixed(2)}}/
</text>
</view>
</view>
<view class="time" style="margin-bottom: 0;">
电价{{currentCostTemplatePriceType.pricePower}}/服务费{{currentCostTemplatePriceType.priceService}}/
</view>
</uni-card>
<uni-card is-shadow spacing="0" padding="30rpx">
<view class="header">
<view class="line"></view>
<view>
停车场收费
</view>
</view>
<view class="remark">
{{detail.stationVo.openExplain}}
</view>
</uni-card>
<uni-card is-shadow spacing="0" padding="30rpx">
<view class="header">
<view class="line"></view>
<view>
占用收费
</view>
</view>
<view class="remark">
充电完成后超过30分钟不拔枪系统将按照0.17/分钟计算收取设备占用费费用上线为30元
</view>
</uni-card>
<uni-card is-shadow spacing="0" padding="30rpx">
<view class="header">
<view class="line"></view>
<view>
充电爱车
</view>
<view style="flex:1;">
<view class="right" @click="toPage('/pages/my-car/add-my-car/add-my-car')">
<image src="https://kxcharge.oss-cn-beijing.aliyuncs.com/27672.png" style="width:28rpx;height:28rpx;margin-right: 10rpx;"></image>
<text>添加爱车</text>
</view>
</view>
</view>
<view class="car-info" @click="toPage(`/pages/my-car/my-car?connectorCode=${connectorCode}`)">
<image src="https://kxcharge.oss-cn-beijing.aliyuncs.com/27673.png"></image>
<text>{{ plateNumber }}</text>
</view>
</uni-card>
<uni-card is-shadow spacing="0" padding="30rpx">
<view class="header">
<view class="line"></view>
<view>
付款方式
</view>
</view>
<view class="pay-info">
<view class="account">
<text>账户余额</text>
<text class="value">{{ balance }}</text>
</view>
<view class="recharge" @click="toPage(`/pages/pay/recharge?connectorCode=${connectorCode}`)">去充值 ></view>
</view>
</uni-card>
<ljs-loading v-if="progress>0">{{progress}}%</ljs-loading>
<template v-slot:kxTabBar>
<kx-tabbar-wrapper>
<view class="tab-bar" @click="startCharge">
开始充电
</view>
</kx-tabbar-wrapper>
</template>
</s-layout>
</template>
<script setup>
import PayWalletApi from '@/sheep/api/pay/wallet';
import * as MemberApi from "@/sheep/api/charge/member";
import * as OrderApi from "@/sheep/api/charge/order";
import dayjs from 'dayjs'
import customParseFormat from 'dayjs/plugin/customParseFormat'
import {
getConnectorInfo as getConnectorInfoApi
} from '@/sheep/api/charge/operations'
dayjs.extend(customParseFormat);
const balance = ref(0);
const plateNumber = ref('');
const orderSeqNumber = ref('');
const progress = ref(0);
const connectorCode = ref('');
const detail = ref({
equipmentModelRespVO: {},
stationVo: {},
workState: 3,
connectorCode: ''
})
let timer = null
let getDataTimer = null
const currentCostTemplatePrice = ref({})
const currentCostTemplatePriceType = ref({})
const toPage = (url) => {
uni.navigateTo({
url
});
};
const getConnectorInfo = async id => {
const res = await getConnectorInfoApi(id)
detail.value = res.data
getDataTimer = setTimeout(() => {
getConnectorInfo(id)
}, 5000)
}
const getPrice = () => {
const now = dayjs()
const {
costTemplatePriceRespVOS: costTemplatePrice,
costTemplatePriceTypeRespVOS: costTemplatePriceType
} = detail.value.stationVo.costTemplateRespVO
currentCostTemplatePrice.value = costTemplatePrice.filter(({
endTimeStr,
startTimeStr
}) => {
const start = dayjs(startTimeStr, 'HH:mm'),
end = dayjs(endTimeStr, 'HH:mm')
return start.isBefore(now) && end.isAfter(now)
})?.[0]
currentCostTemplatePriceType.value = costTemplatePriceType.filter(({
typeName
}) => currentCostTemplatePrice.value.priceTypeId === typeName)?.[0]
}
onLoad(async (options) => {
connectorCode.value = options.connectorCode;
if (options.carInfo) {
plateNumber.value = JSON.parse(options.carInfo).plateNumber
}
await getConnectorInfo(options.connectorCode)
getPrice()
});
// 将初始化逻辑提取到单独的函数
const initData = async () => {
const response = await PayWalletApi.getPayWallet();
if (response.code === 0) {
balance.value = (response.data.balance / 100).toFixed(2);
}
};
onMounted(async () => {
const responseCar = await MemberApi.getMyCar();
if (responseCar.code === 0) {
const cars = responseCar.data;
// 查找 isDefault = 1 的车辆
const defaultCar = cars.find(car => car.isDefault === 1);
if (plateNumber.value === '') {
if (defaultCar) {
plateNumber.value = defaultCar.plateNumber; // 有默认车辆,赋值
} else if (cars.length > 0) {
plateNumber.value = cars[0].plateNumber; // 没有默认车辆,取第一辆
} else {
plateNumber.value = ""; // 没有车辆,设为空
}
}
}
initData(); // 页面初次加载时调用
});
onShow(() => {
initData(); // 页面再次显示时调用
});
const startCharge = async () => {
const response = await OrderApi.startCharge(connectorCode.value, plateNumber.value, 1);
if (response.code === 0) {
orderSeqNumber.value = response.data;
startProgress();
}
};
onHide(() => {
progress.value = 0;
clearTimer()
})
onBackPress(() => {
progress.value = 0;
clearTimer()
})
onUnmounted(() => {
progress.value = 0;
clearTimer()
})
const clearTimer = () => {
if (timer) {
clearTimeout(timer)
timer = null
}
if (getDataTimer) {
clearTimeout(getDataTimer)
getDataTimer = null
}
}
const startProgress = () => {
progress.value = 0;
let count = 0;
const query = async () => {
progress.value += 3
count++
const orderResponse = await OrderApi.getOrderInfo(orderSeqNumber.value);
// TODO
if (count >= 1 || orderResponse.data.orderStatus === 2) {
progress.value = 100
clearTimer()
uni.navigateTo({
url: '/pages/charging/index?seqNumber=' + orderResponse.data.seqNumber
});
return
}
if (count >= 1 || orderResponse.data.orderStatus === 6) {
progress.value = 100
clearTimer()
uni.navigateTo({
url: `/pages/order-info/order-info?id=` + orderResponse.data.seqNumber
})
return
}
timer = setTimeout(() => {
query();
}, 1000)
}
query()
}
// const startProgress = () => {
// progress.value = 0;
// intervalId.value = setInterval(async () => {
// progress.value += 10;
// if (progress.value >= 3000) {
// clearInterval(intervalId.value);
// setTimeout(() => {
// uni.navigateTo({
// url: '/pages/charging/index'
// });
// }, 1000);
// return;
// }
// const orderResponse = await OrderApi.getOrderInfo(orderSeqNumber.value);
// if (orderResponse.data.orderStatus === 4) {
// clearInterval(intervalId.value);
// progress.value = 100;
// setTimeout(() => {
// uni.navigateTo({
// url: '/pages/charging/index'
// });
// }, 1000);
// }
// }, 1000);
// };
</script>
<style lang="scss" scoped>
.header {
font-weight: 800;
font-size: 32rpx;
color: #333333;
display: flex;
align-items: center;
margin-bottom: 20rpx;
.line {
width: 7rpx;
height: 32rpx;
margin-right: 16rpx;
background: #3072F6;
}
.right {
float: right;
font-size: 30rpx;
color: #337BFB;
}
}
.time {
font-size: 24rpx;
color: #333333;
margin: 20rpx 0;
}
.price {
font-size: 24rpx;
color: #333;
display: inline-block;
margin-right: 18rpx;
vertical-align: middle;
text {
font-size: 40rpx;
color: #EB5336;
}
}
.vip {
width: 230rpx;
height: 45rpx;
background: linear-gradient(180deg, #FADBB7 0%, #F6BA85 100%);
border-radius: 10rpx 10rpx 10rpx 10rpx;
display: inline-block;
image {
width: 82rpx;
height: 45rpx;
}
text {
font-size: 24rpx;
color: #3A3E5E;
}
}
.remark {
font-size: 28rpx;
color: #333333;
}
.car-info {
background: #F5F6FA;
border-radius: 20rpx;
font-size: 30rpx;
color: #323551;
text-align: center;
padding: 30rpx 0;
image {
width: 50rpx;
height: 40rpx;
margin-right: 10rpx;
}
}
.pay-info {
display: flex;
justify-content: space-between;
.account {
font-size: 24rpx;
color: #000000;
}
.value {
font-weight: bold;
font-size: 32rpx;
margin-left: 10rpx;
}
.recharge {
font-size: 26rpx;
color: #666666;
}
}
.tab-bar {
background: linear-gradient(132deg, #4A8EFC 0%, #50C3FD 100%);
border-radius: 45rpx;
font-weight: bold;
font-size: 30rpx;
color: #FFF;
text-align: center;
padding: 24rpx 0;
width: 90%;
}
.progress-bar {
width: 100%;
height: 20rpx;
background-color: #e0e0e0;
border-radius: 10rpx;
overflow: hidden;
margin-top: 20rpx;
.progress {
height: 100%;
background-color: #4A8EFC;
width: v-bind(progress + '%');
transition: width 1s linear;
}
}
</style>