<template> <view class="page" v-if="loading"> <u-navbar title="运营数据" :border-bottom="false" :background="bgc" title-color='#000' title-size='36' height='45'></u-navbar> <view class="top_box"> <view class="left_text"> 时间范围 </view> <view class="timebox"> <view class="left_time" @click="time1=true"> {{firsTime}} </view> - <view class="right_time" @click="time2=true"> {{lasTime}} </view> </view> </view> <view class="data_box"> <view class="data_cont " :class="cutidx==0?'act1':''" @click="changeTime(0)"> 今日 </view> <view class="data_cont" :class="cutidx==1?'act1':''" @click="changeTime(1)"> 昨日 </view> <view class="data_cont" :class="cutidx==2?'act1':''" @click="changeTime(2)"> 本月 </view> <view class="data_cont" :class="cutidx==3?'act1':''" @click="changeTime(3)"> 上个月 </view> </view> <view class="top_card"> <view class="tit"> <image src="https://lxnapi.ccttiot.com/bike/img/static/uR7EhQMLnjuRoi0G3tA6" mode=""></image> 收入相关 </view> <view class="info"> <view class="info_li"> 订单总费用: <span style="color: #4C97E7;" >¥{{displayAmount(info.income.totalFee) }}</span> </view> <view class="info_li"> 手续费: <span style="color: #4C97E7;" >¥{{displayAmount(info.income.handlingFee)}}</span> </view> </view> <view class="info"> <view class="info_li"> 总营收: <span style="color: #4C97E7;" v-if="info.income.totalIncome">¥{{info.income.totalIncome}}</span> <span style="color: #4C97E7;" v-else>¥--</span> </view> <view class="info_li"> 累计待支付: <span style="color: #4C97E7;" v-if="info.income.totalUnpaid">¥{{info.income.totalUnpaid}}</span> <span style="color: #4C97E7;" v-else>¥--</span> </view> </view> <view class="info"> <view class="info_li"> 已支付: <span style="color: #3D3D3D;" v-if="info.income.totalPaid">¥{{info.income.totalPaid}}</span> <span style="color: #3D3D3D;" v-else>¥--</span> </view> <view class="info_li"> 已退款: <span style="color: #3D3D3D;" v-if="info.income.totalRefund">¥{{info.income.totalRefund}}</span> <span style="color: #3D3D3D;" v-else>¥--</span> </view> </view> </view> <view class="cont_box"> <view class="cont_info"> <view class="info_li" style="color:#4C97E7 ;"> 租赁费 </view> <view class="info_li" style="color:#4C97E7 ;"> 调度费 </view> </view> <view class="cont_info"> <view class="info_li" v-if="info.income.totalRidingFee"> 已支付:¥{{info.income.totalRidingFee}} </view> <view class="info_li" v-else> 已支付:¥-- </view> <view class="info_li" v-if="info.income.totalDispatchFee"> 已支付:¥{{info.income.totalDispatchFee}} </view> <view class="info_li" v-else> 已支付:¥-- </view> </view> <view class="cont_info"> <view class="info_li"> 已退款:¥{{ displayAmount(info.income.totalRidingRefund)}} </view> <view class="info_li"> 已退款:¥{{ displayAmount(info.income.totalDispatchRefund)}} </view> </view> <view class="cont_info"> <view class="info_li" style="color:#4C97E7 ;"> 预约费 </view> <view class="info_li" style="color:#4C97E7 ;"> 管理费 </view> </view> <view class="cont_info"> <view class="info_li"> 已支付:¥{{displayAmount(info.income.totalAppointmentFee) }} </view> <view class="info_li"> 已支付:¥{{displayAmount(info.income.totalManageFee) }} </view> </view> <view class="cont_info"> <view class="info_li"> 已退款:¥{{displayAmount(info.income.totalAppointmentRefund) }} </view> <view class="info_li"> 已退款:¥{{displayAmount(info.income.totalManageRefund) }} </view> </view> </view> <view class="card"> <view class="tit"> <image src="https://lxnapi.ccttiot.com/bike/img/static/uGs0Ayq797AurrBpU8xm" mode=""></image> 订单相关 </view> <view class="info_box"> <view class="one_cont"> <view class="text"> {{displayAmount(info.order.ridingOrder) }} </view> <view class="text"> 新增行程订单 </view> </view> <view class="one_cont"> <view class="text"> {{displayAmount(info.order.paidOrder) }} </view> <view class="text"> 已支付订单 </view> </view> <view class="one_cont"> <view class="text"> {{displayAmount(info.order.refundOrder)}} </view> <view class="text"> 已退款订单 </view> </view> <view class="one_cont"> <view class="text"> {{displayAmount(info.order.unpaidOrder) }} </view> <view class="text"> 待支付订单 </view> </view> </view> </view> <view class="lines"></view> <view class="card"> <view class="tit"> <image src="https://lxnapi.ccttiot.com/bike/img/static/uBgz6OZvl3KHGGGJ16vy" mode=""></image> 车辆相关 </view> <view class="info_box"> <view class="one_cont"> <view class="text"> {{displayAmount(info.device.inOperationDevice)}} </view> <view class="text"> 运营中车辆 </view> </view> <view class="one_cont"> <view class="text"> {{displayAmount(info.device.inOrderDevice)}} </view> <view class="text"> 有订单车辆 </view> </view> <view class="one_cont"> <view class="text"> {{displayAmount(info.device.noOrderDevice)}} </view> <view class="text"> 无订单车辆 </view> </view> </view> </view> <view class="lines"></view> <view class="card"> <view class="tit"> <image src="https://lxnapi.ccttiot.com/bike/img/static/uCpE3kS6X0uD9q6pWzUu" mode=""></image> 用户相关 </view> <view class="info_box"> <view class="one_cont"> <view class="text"> {{ displayAmount(info.user.totalUser)}} </view> <view class="text"> 用户总数 </view> </view> <view class="one_cont"> <view class="text"> {{displayAmount(info.user.newUser) }} </view> <view class="text"> 新增用户 </view> </view> <view class="one_cont"> <view class="text"> {{displayAmount(info.user.leaseUser) }} </view> <view class="text"> 租赁用户 </view> </view> </view> </view> <u-picker mode="time" v-model="time1" :params="params" @confirm="confirm1" :default-time='firsTime'></u-picker> <u-picker mode="time" v-model="time2" :params="params" @confirm="confirm2" :default-time='lasTime'></u-picker> </view> </template> <script> export default { data() { return { bgc: { backgroundColor: "#fff", }, time1: false, time2: false, lasTime: '', firsTime: '', params: { year: true, month: true, day: true, hour: false, minute: false, second: false }, cutidx: 0, info: {}, areaId: 0, loading:false } }, onLoad() { let today = new Date(); // 获取七天前的日期 // 格式化日期为 yyyy-MM-dd this.firsTime = this.formatDate(today); this.lasTime = this.formatDate(today); if (uni.getStorageSync('adminAreaid')) { this.areaId = uni.getStorageSync('adminAreaid') this.operatingData() } }, methods: { displayAmount(amount) { return amount ? amount : '--'; }, changeTime(num) { if (num == 0) { this.cutidx = num; let today = new Date(); this.firsTime = this.formatDate(today); this.lasTime = this.formatDate(today); this.operatingData() } else if (num == 1) { this.cutidx = num; let yesterday = new Date(); yesterday.setDate(yesterday.getDate() - 1); this.firsTime = this.formatDate(yesterday); this.lasTime =this.formatDate(yesterday); this.operatingData() } else if (num == 2) { this.cutidx = num; let today = new Date(); let firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1); this.firsTime = this.formatDate(firstDayOfMonth); this.lasTime = this.formatDate(new Date()); this.operatingData() } else if (num == 3) { this.cutidx = num; let today = new Date(); let firstDayOfLastMonth = new Date(today.getFullYear(), today.getMonth() - 1, 1); let lastDayOfLastMonth = new Date(today.getFullYear(), today.getMonth(), 0); this.firsTime = this.formatDate(firstDayOfLastMonth); this.lasTime = this.formatDate(lastDayOfLastMonth); this.operatingData() } }, formatDate(date) { let year = date.getFullYear(); let month = String(date.getMonth() + 1).padStart(2, '0'); let day = String(date.getDate()).padStart(2, '0'); return `${year}-${month}-${day}`; }, operatingData() { let data = { timeStart: this.firsTime, timeEnd: this.lasTime, areaId: this.areaId } this.$u.get('/appVerify/operatingData', data).then((res) => { if (res.code === 200) { // 处理接口返回的数据,将边界数据转换为地图组件需要的折线结构 this.info = res.data this.loading=true } }).catch(error => { console.error("Error fetching area data:", error); }); }, confirm1(e) { this.firsTime = e.year + '-' + e.month + '-' + e.day this.cutidx = -1 this.operatingData() }, confirm2(e) { this.lasTime = e.year + '-' + e.month + '-' + e.day this.cutidx = -1 this.operatingData() }, } } </script> <style lang="scss"> page { background-color: #fff; } .page { width: 750rpx; .lines { width: 748rpx; height: 22rpx; background: #F6F6F6; border-radius: 0rpx 0rpx 0rpx 0rpx; } .cont_box { padding: 14rpx 30rpx; width: 750rpx; background: #F6F6F6; border-radius: 0rpx 0rpx 0rpx 0rpx; .cont_info { margin-top: 8rpx; display: flex; flex-wrap: nowrap; .info_li { width: 50%; font-weight: 400; font-size: 28rpx; color: #3D3D3D; } } } .card { padding: 30rpx 30rpx; background: #FFFFFF; // box-shadow: 0rpx 4rpx 22rpx 0rpx rgba(0, 0, 0, 0.2); width: 750rpx; // border-radius: 40rpx 40rpx 0 0; .tit { display: flex; flex-wrap: nowrap; align-items: center; image { margin-right: 18rpx; width: 38rpx; height: 38rpx; } font-weight: 500; font-size: 32rpx; color: #3D3D3D; } .info_box { display: flex; flex-wrap: nowrap; .one_cont { display: flex; flex-wrap: wrap; .text { margin-top: 12rpx; text-align: center; width: 170rpx; } } } } .top_card { padding: 30rpx 30rpx; background: #FFFFFF; box-shadow: 0rpx 4rpx 22rpx 0rpx rgba(0, 0, 0, 0.2); width: 750rpx; border-radius: 40rpx 40rpx 0 0; .info { margin-top: 28rpx; display: flex; flex-wrap: nowrap; align-items: center; .info_li { width: 50%; } } .tit { display: flex; flex-wrap: nowrap; align-items: center; image { margin-right: 18rpx; width: 38rpx; height: 38rpx; } font-weight: 500; font-size: 32rpx; color: #3D3D3D; } } .data_box { width: 672rpx; margin: 36rpx auto; display: flex; flex-wrap: nowrap; align-items: center; justify-content: space-between; .data_cont { display: flex; align-items: center; justify-content: center; width: 150rpx; height: 60rpx; background: #FFFFFF; box-shadow: 0rpx 4rpx 22rpx 0rpx rgba(0, 0, 0, 0.07); border-radius: 10rpx 10rpx 10rpx 10rpx; font-weight: 400; font-size: 32rpx; color: #3D3D3D; border: 2rpx solid #fff; } .act1 { background: #E2F2FF; box-shadow: 0rpx 4rpx 22rpx 0rpx rgba(0, 0, 0, 0.07); color: #4C97E7; border: 2rpx solid #4C97E7; } } .top_box { display: flex; flex-wrap: nowrap; align-items: center; padding: 28rpx 30rpx; margin: 20rpx auto; width: 672rpx; height: 100rpx; background: #FFFFFF; box-shadow: 0rpx 4rpx 22rpx 0rpx rgba(0, 0, 0, 0.07); border-radius: 10rpx 10rpx 10rpx 10rpx; .left_text { width: 25%; font-weight: 400; font-size: 32rpx; color: #3D3D3D; } .timebox { width: 75%; display: flex; flex-wrap: nowrap; align-items: center; margin-left: 34rpx; .left_time { text-align: center; margin-right: 6rpx; height: 50rpx; width: 45%; border: 2rpx solid #ccc; border-radius: 12rpx; font-weight: 400; font-size: 32rpx; color: #979797; } .right_time { text-align: center; margin-left: 6rpx; height: 50rpx; width: 45%; border: 2rpx solid #ccc; border-radius: 12rpx; font-weight: 400; font-size: 32rpx; color: #979797; } } } } </style>