| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380 |
- <script setup lang="ts">
- import chargeSearch from '../components/search.vue'
- import chargeFooter from '../components/charge-tab.vue'
- import router from '@/router'
- import { StaticUrl } from '@/config'
- import { createGlobalLoadingMiddleware } from '@/api/core/middleware'
- const { statusBarHeight, MenuButtonHeight, opcity } = storeToRefs(useSysStore())
- const { token, userInfo } = storeToRefs(useUserStore())
- const { Location } = storeToRefs(useAddressStore())
- definePage({
- name: 'charge-index',
- islogin: false,
- style: {
- navigationStyle: 'custom',
- navigationBarTitleText: '',
- backgroundColorBottom: '#fff',
- },
- })
- const activeFilter = ref<number>(1)
- const loading = ref(true)
- const filterOptions = [
- { key: 1, label: '离我最近', widthClass: 'w-152rpx' },
- { key: 2, label: '空闲最多', widthClass: '' },
- { key: 3, label: '电费最低', widthClass: '' },
- ]
- /**
- * 获取充电站列表
- */
- const { data: stationList, isLastPage, page, refresh, reload } = usePagination((pageNum, pageSize) =>
- Apis.charge.getStationInfoPage({ data: { pageNum, pageSize, sortType: activeFilter.value, longitude: Location.value.longitude || 106.620256, latitude: Location.value.latitude || 26.648327, userId: userInfo.value.id } }), {
- data: (resp) => {
- return resp.data?.list
- },
- initialData: [],
- initialPage: 1,
- initialPageSize: 10,
- append: true,
- immediate: true,
- middleware: createGlobalLoadingMiddleware(),
- }).onSuccess(() => {
- loading.value = false
- })
- onMounted(() => {
- getUserAccountInfo()
- opcity.value = 0
- })
- onShow(() => {
- refresh()
- getUserAccountInfo()
- getDefaultVehicle()
- queryVehicleList()
- })
- onPageScroll((e) => {
- const calculatedOpacity = e.scrollTop / 100
- opcity.value = Math.min(1, Math.max(0.1, calculatedOpacity))
- })
- onReachBottom(() => {
- if (!isLastPage.value) {
- page.value++
- }
- })
- /**
- * 获取用户账户信息
- */
- const userAccountInfo = ref()
- async function getUserAccountInfo() {
- const res = await Apis.charge.getMemberInfo({})
- userAccountInfo.value = res.data
- }
- /**
- * 获取用户默认车辆
- */
- const defaultVehicle = ref<Api.UserVehicleVO>()
- async function getDefaultVehicle() {
- const res = await Apis.charge.default({})
- defaultVehicle.value = res.data
- }
- // 获取车辆列表判断是否提示用户添加车辆
- async function queryVehicleList() {
- const res = await Apis.charge.vehicleList({})
- if (res.data.length === 0) {
- useGlobalMessage().confirm({
- title: '充电车主专享',
- msg: '绑定车牌可享充电停车费减免及更多权益',
- success: () => {
- router.push({ name: 'charge-plate-list' })
- },
- })
- }
- }
- // 处理筛选项点击的方法
- function handleFilterClick(filterKey: number) {
- activeFilter.value = filterKey
- reload()
- }
- /**
- * 申请退款
- */
- function refund() {
- useGlobalMessage().confirm({
- title: '提示',
- msg: '退款按照购券记录进行逐笔退款,可能产生多笔退款到账记录,请注意查收。',
- success: async () => {
- const res = await Apis.charge.userCouponRefund({})
- if (res.code === '00000') {
- useGlobalMessage().confirm({
- title: '提示',
- msg: '申请退款成功,预计3个工作日内分一笔或多笔退还,到期如未到账请联系客服!',
- success: () => {
- refresh()
- },
- fail: () => {
- refresh()
- },
- })
- }
- },
- })
- }
- </script>
- <template>
- <view class="min-h-screen from-[#E2FF91] to-[rgba(158,214,5,0)] bg-gradient-to-b">
- <wd-navbar
- title="" :custom-style="`background-color: rgba(226, 255, 145, ${opcity})`" :bordered="false"
- :z-index="99" safe-area-inset-top left-arrow fixed @click-left="router.back()"
- >
- <template #left>
- <view class="flex items-center">
- <wd-icon name="arrow-left" size="22px" color="#000" />
- <view class="relative z-10 h62rpx w-full w180rpx opacity-100">
- <image class="absolute left-0 top-0 h62rpx w180rpx" :src="`${StaticUrl}/charge-logo.png`" />
- </view>
- </view>
- </template>
- </wd-navbar>
- <view :style="{ paddingTop: `${(Number(statusBarHeight) || 44) + MenuButtonHeight + 12}px` }" class="px24rpx">
- <charge-search map-mode-text-value="地图模式" @map-mode-click="router.replace({ name: 'charge-map' })" />
- <view class="userInfo-card">
- <view class="flex items-center gap-20rpx">
- <image
- class="h-100rpx w-100rpx"
- :src="`${userInfo && userInfo?.avatarUrl ? userInfo.avatarUrl : `${StaticUrl}/charge-default-avatar.png`}`"
- />
- <view>
- <view class="flex items-center gap-16rpx">
- <view class="text-32rpx text-#2B303A font-bold">
- {{ userInfo?.nickName || '暂未登录' }}
- </view>
- <view v-if="!token" class="text-24rpx text-#9ED605" @click="router.replace({ name: 'smqjh-login' })">
- 授权登录
- </view>
- <view v-else class="rounded-8rpx bg-#E9FFAC px12rpx py4rpx text-24rpx text-#9ED605">
- {{ userInfo.channelName }}
- </view>
- </view>
- <view class="mt-16rpx text-28rpx font-bold">
- {{ userInfo?.mobile }}
- </view>
- </view>
- </view>
- <view class="mt-20rpx rounded-16rpx bg-#F3FFD1 px-24rpx py-30rpx">
- <view class="relative flex items-center justify-between">
- <view class="flex items-center gap-16rpx">
- <view class="h-40rpx w-40rpx">
- <image
- class="h-40rpx w-40rpx"
- :src="`${StaticUrl}/charge-mine-wallet.png`"
- mode="scaleToFill"
- />
- </view>
- <view class="text-32rpx font-bold">
- 我的钱包
- </view>
- </view>
- <view class="absolute right-[-24rpx] h-44rpx w-120rpx rounded-[22rpx_0_0_22rpx] bg-#9ED605 text-center text-28rpx text-#FFF line-height-[44rpx]" @click="refund">
- 退还
- </view>
- </view>
- <view class="mt-24rpx flex items-center justify-around">
- <view class="text-center">
- <view class="text-28rpx">
- 企业积分
- </view>
- <view class="mt-16rpx text-40rpx text-#9ED605 font-bold">
- {{ userAccountInfo?.availablePoints || '0.00' }}
- </view>
- </view>
- <view class="h-92rpx w-2rpx bg-#9ED605" />
- <view class="text-center">
- <view class="text-28rpx">
- 平台券
- </view>
- <view class="mt-16rpx text-40rpx text-#9ED605 font-bold">
- <text class="text-24rpx">
- ¥
- </text>{{ userAccountInfo?.couponBalance || '0.00' }}
- </view>
- </view>
- </view>
- </view>
- </view>
- <view class="mt-24rpx flex justify-between">
- <view class="flex items-center gap-18rpx rounded-16rpx bg-#FFF px-24rpx py-28rpx">
- <view>
- <view class="flex items-center gap-16rpx" @click="router.push({ name: 'charge-order-list' })">
- <text class="text-32rpx font-bold">
- 充电订单
- </text>
- <view class="h-30rpx w-30rpx rounded-50% bg-#000 text-center line-height-[30rpx]">
- <wd-icon name="arrow-right" color="#FFFFFF" size="30rpx" />
- </view>
- </view>
- <view class="mt-16rpx text-24rpx">
- 查看充电订单
- </view>
- </view>
- <view class="h-100rpx w-100rpx">
- <image
- class="h-100rpx w-100rpx"
- :src="`${StaticUrl}/charge-mine-order.png`"
- mode="scaleToFill"
- />
- </view>
- </view>
- <view class="flex items-center gap-18rpx rounded-16rpx bg-#FFF px-24rpx py-28rpx" @click="router.push({ name: 'charge-voucher', params: { couponBalance: userAccountInfo?.couponBalance } })">
- <view>
- <view class="flex items-center gap-16rpx">
- <text class="text-32rpx font-bold">
- 购券中心
- </text>
- <view class="h-30rpx w-30rpx rounded-50% bg-#000 text-center line-height-[30rpx]">
- <wd-icon name="arrow-right" color="#FFFFFF" size="30rpx" />
- </view>
- </view>
- <view class="mt-16rpx text-24rpx">
- 平台券充值
- </view>
- </view>
- <view class="h-100rpx w-100rpx">
- <image
- class="h-100rpx w-100rpx"
- :src="`${StaticUrl}/charge-mine-voucher.png`"
- mode="scaleToFill"
- />
- </view>
- </view>
- </view>
- <view class="mt-24rpx flex items-center justify-between rounded-16rpx bg-#FFF p-20rpx">
- <view class="text-32rpx font-bold">
- 我的车辆
- </view>
- <!-- 无车辆时显示添加提示 -->
- <view v-if="!defaultVehicle" class="flex items-center gap-10rpx" @click="router.push({ name: 'charge-plate-list' })">
- <view class="text-26rpx">
- 添加车辆,享更多权益
- </view>
- <view class="h-50rpx w-50rpx rounded-50% bg-[linear-gradient(90deg,#DBFC81_0%,#9ED605_100%)] text-center text-30rpx text-#FFF font-bold line-height-[50rpx]">
- +
- </view>
- </view>
- <!-- 有车辆时显示车牌和管理入口 -->
- <view v-else class="flex items-center gap-50rpx text-26rpx text-#9ED605" @click="router.push({ name: 'charge-plate-list' })">
- <view>{{ defaultVehicle.licensePlate }}</view>
- <view>管理>></view>
- </view>
- </view>
- <view class="mt-24rpx flex items-center gap-20rpx">
- <view
- v-for="option in filterOptions"
- :key="option.key"
- class="select-item h-60rpx w-152rpx text-28rpx line-height-[60rpx]" :class="[
- option.widthClass,
- { 'select-item-active': activeFilter === option.key },
- ]"
- @click="handleFilterClick(option.key)"
- >
- {{ option.label }}
- </view>
- </view>
- <view :class="[loading ? 'pt-24rpx' : '']">
- <wd-skeleton theme="paragraph" animation="gradient" :loading="loading" :row-col="[{ height: '100px', width: '100%' }, { height: '100px', width: '100%' }, { height: '100px', width: '100%' }]">
- <view v-for="item in stationList" :key="item.stationId" class="relative mt-24rpx rounded-16rpx bg-#FFFFFF p-24rpx" @click="router.push({ name: 'charge-site-detail', params: { stationId: String(item.stationId) } })">
- <image
- class="absolute right-0 top-0 h-52rpx w-186rpx"
- :src="`${StaticUrl}/charge-firm-tag.png`"
- />
- <view class="text-32rpx text-#2B303A font-bold">
- {{ item.stationName }}
- </view>
- <view class="mt-20rpx text-24rpx text-#aaa">
- {{ item.tips || '暂无提示' }}
- </view>
- <view class="mt-24rpx flex items-center rounded-16rpx bg-[linear-gradient(90deg,rgba(170,255,235,0.3)_0%,rgba(175,247,252,0.2)_43.57%,rgba(139,232,252,0)_100%)] p-20rpx">
- <view class="flex items-center gap-16rpx">
- <view class="h-40rpx w-40rpx rounded-8rpx bg-[linear-gradient(180deg,#4FEF86_0%,#00AA3A_100%)] text-center text-28rpx text-#FFF font-bold line-height-[40rpx]">
- 快
- </view>
- <view class="flex items-center">
- <text class="text-32rpx font-bold">
- {{ item.fastCharging }}
- </text>
- </view>
- </view>
- <view class="ml-40rpx flex items-center gap-16rpx">
- <view class="h-40rpx w-40rpx rounded-8rpx bg-[linear-gradient(180deg,#8EB1FF_0%,#3071FF_100%)] text-center text-28rpx text-#FFF font-bold line-height-[40rpx]">
- 慢
- </view>
- <view class="flex items-center">
- <text class="text-32rpx font-bold">
- {{ item.slowCharging }}
- </text>
- </view>
- </view>
- <view class="ml-150rpx h-44rpx w-148rpx flex items-center border-2rpx border-#3EB6F8 rounded-34rpx border-solid line-height-[44rpx]">
- <view class="w-44rpx rounded-[34rpx_0rpx_0rpx_34rpx] bg-#3EB6F8 text-center">
- <wd-icon name="location" size="16px" color="#FFF" />
- </view>
- <view class="text-24rpx text-#3EB6F8">
- {{ item.distance }}km
- </view>
- </view>
- </view>
- <view class="mt-28rpx flex items-center justify-between">
- <view class="relative flex">
- <view class="absolute left-30rpx z-10 flex items-center -top-26rpx">
- <text class="text-40rpx text-#FF6464 font-bold">
- {{ item.platformPrice }}
- </text>
- <text class="w-100rpx text-24rpx">
- 元/度
- </text>
- </view>
- <image
- class="absolute h-60rpx w-365rpx -top-30rpx"
- :src="`${StaticUrl}/to-charge-tag.png`"
- />
- </view>
- <view class="text-24rpx text-#2B303A">
- {{ item.peakValue }}:{{ item.peakTime }}
- </view>
- </view>
- </view>
- </wd-skeleton>
- </view>
- <view class="h-160rpx" />
- </view>
- <chargeFooter />
- </view>
- </template>
- <style scoped lang="scss">
- .userInfo-card {
- background: #FFFFFF;
- box-shadow: inset 0rpx 20rpx 40rpx 2rpx rgba(158, 214, 5, 0.2);
- border-radius: 16rpx;
- padding: 24rpx;
- margin-top: 24rpx;
- }
- .select-item{
- background: #FFFFFF;
- border-radius: 16rpx;
- color: #2B303A;
- text-align: center;
- }
- .select-item-active{
- background: #9ED605;
- box-shadow: inset 0rpx 20rpx 40rpx 2rpx rgba(100,255,218,0.26);
- border-radius: 0rpx 16rpx 0rpx 16rpx;
- font-weight: bold;
- color: #FFFFFF;
- }
- </style>
|