<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="top_info_box" v-if="false"> <view class="info_lis"> <view class="lis_top" @click="showtipss(1)"> 营业收入 <image src="https://lxnapi.ccttiot.com/bike/img/static/uJFB9IlTZQG31V17R5Pn" mode=""></image> </view> <view class="lis_bot"> ¥{{info.income.operatingIncome}} </view> </view> <view class="info_lis"> <view class="lis_top" @click="showtipss(2)"> 押金余额 <image src="https://lxnapi.ccttiot.com/bike/img/static/uJFB9IlTZQG31V17R5Pn" mode=""></image> </view> <view class="lis_bot"> ¥{{info.income.depositBalance}} </view> </view> <view class="info_lis"> <view class="lis_top" @click="showtipss(3)"> 账户盈余 <image src="https://lxnapi.ccttiot.com/bike/img/static/uJFB9IlTZQG31V17R5Pn" mode=""></image> </view> <view class="lis_bot"> ¥{{info.income.accountSurplus}} </view> </view> </view> <view class="lines"></view> <view class="cont_info_box" v-if="false"> <view class="info_li2"> 总流水:{{info.income.totalFlowAmount}} </view> <view class="info_li3"> 订单支付:{{info.income.orderPaid}} <span>(包含押金抵扣:{{info.income.deductionAmount}})</span> </view> <view class="info_li3"> 押金充值:{{info.income.depositPaid}} </view> <view class="info_li2" style="margin-top: 38rpx;"> 总支出:{{info.income.totalExpenditure}} </view> <view class="info_li3" style=" display: flex;" > <span style="width: 50%;color: #3D3D3D;">订单退款:{{info.income.orderRefund}} </span><span style="color: #3D3D3D;width: 50%;">押金退款:{{info.income.depositRefund}}</span> </view> <view class="info_li3" style=" display: flex; "> <span style="width: 50%;color: #3D3D3D;">手续费:{{info.income.handlingFee}}</span> <span style="color: #3D3D3D;width: 50%;">平台服务费:{{info.income.platformServiceFee}}</span> </view> </view> <view class="lines"></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> <u-mask :show="showtips" :z-index='100' /> <view class="tip_box1" v-if="showtips"> <image class="close" src="https://lxnapi.ccttiot.com/bike/img/static/uyRmNa7d2WThHjr1Jzqk" mode="" @click="showtips=false"></image> <view class="top1"> <view class="tip"> {{tiptit}} </view> <view class="txt" v-html="tiptxt"> <!-- {{tiptxt}} --> </view> </view> <!-- <view class="bot1"> <view class="bot_right" @click="showtips=false"> 确定 </view> </view> --> </view> </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, showtips:false, tiptxt:'', tiptit:'' } }, 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: { showtipss(num){ if(num==1){ this.tiptxt='该时间段骑车实际利润' this.tiptit='营业收入' }else if(num==2){ this.tiptxt='该时间段押金余额' this.tiptit='押金余额' }else if(num==3){ this.tiptxt='该时间段账户盈余<br/>总流水减去总支出' this.tiptit='账户盈余' } this.showtips=true }, 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; .tip_box1 { position: fixed; left: 72rpx; top: 628rpx; width: 610rpx; // height: 282rpx; background: #FFFFFF; border-radius: 30rpx 30rpx 30rpx 30rpx; z-index: 110; padding-bottom: 10rpx; .close{ position: absolute; width: 60rpx; height: 60rpx; bottom: -98rpx; left: 274rpx; } .top1 { padding: 52rpx 38rpx 42rpx 36rpx; .ipt_box { margin-top: 22rpx; display: flex; flex-wrap: nowrap; align-items: center; .text { width: 350rpx; font-weight: 400; font-size: 32rpx; color: #3D3D3D; } .ipt { padding: 10rpx 18rpx; display: flex; align-items: center; justify-content: space-between; margin-left: 26rpx; width: 420rpx; height: 64rpx; border-radius: 0rpx 0rpx 0rpx 0rpx; border: 2rpx solid #979797; .input { width: 80%; } } } .tip { width: 100%; text-align: center; font-weight: 700; font-size: 32rpx; color: #3D3D3D; } .txt { margin-top: 32rpx; width: 100%; text-align: center; font-weight: 500; font-size: 24 rpx; color: #3D3D3D; } } .bot1 { position: absolute; width: 610rpx; // border-top: 2rpx solid #D8D8D8; display: flex; flex-wrap: nowrap; // height: 100%; // bottom: -20rpx; justify-content: center; .bot_left { border-radius: 0rpx 0rpx 0rpx 30rpx; width: 50%; height: 86rpx; display: flex; align-items: center; justify-content: center; font-weight: 500; font-size: 32rpx; color: #3D3D3D; background: #EEEEEE; } .bot_right { border-radius: 30rpx 30rpx 30rpx 30rpx; width: 60%; height: 86rpx; background: #4C97E7; display: flex; align-items: center; justify-content: center; color: #FFFFFF; // border-left: 2rpx solid #D8D8D8; font-weight: 500; font-size: 32rpx; // color: #4C97E7; } } } .top_info_box{ padding: 70rpx 50rpx; display: flex; justify-content: space-around; background: #FFFFFF; box-shadow: 0rpx 4rpx 22rpx 0rpx rgba(0,0,0,0.2); border-radius: 40rpx 40rpx 0 0; .info_lis{ display: flex; flex-wrap: wrap; width: 180rpx; .lis_top{ display: inline-flex; align-items: center; flex-wrap: nowrap; font-weight: 500; font-size: 32rpx; color: #3D3D3D; image{ margin-left: 16rpx; width: 31.83rpx; height: 31.83rpx; } } .lis_bot{ text-align: center; margin-top: 16rpx; font-weight: 500; font-size: 40rpx; color: #4C97E7; } } } .cont_info_box{ padding: 36rpx 38rpx; display: flex; flex-wrap: wrap; background: #FFFFFF; .info_li2{ width: 100%; font-weight: 600; font-size: 32rpx; color: #3D3D3D; } .info_li3{ margin-top: 22rpx; width: 100%; font-weight: 400; font-size: 28rpx; color: #3D3D3D; span{ color: #979797; } } } .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>