index.vue 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. <template>
  2. <view class="content">
  3. <u-navbar title="" :is-back="false" :background="{backgroundColor: '#1f58ff'}" class="top-navbar">
  4. <text style="position: absolute;z-index: 1;left:40rpx;">收费统计</text>
  5. <u-dropdown>
  6. <u-dropdown-item v-model="selparking" :title="parkingMenuTitle" :options="parkingMenuItems" @change="changeFilterMenu"></u-dropdown-item>
  7. </u-dropdown>
  8. </u-navbar>
  9. <view class="rpt-top">
  10. <u-circle-progress :percent="seatpie.percent" active-color="#22fd8d" bg-color="rgba(0,0,0,0)" inactive-color="#65a8ff" width="280">
  11. <view class="u-progress-content">
  12. <text class="subtitle">空闲/总车位</text>
  13. <text class='title'>{{seatpie.idle}}/{{seatpie.total}}</text>
  14. </view>
  15. </u-circle-progress>
  16. <view class="income-rpt">
  17. <view class="income-item">
  18. <view>总收入(元)</view>
  19. <text>{{incomerpt.total}}</text>
  20. </view>
  21. <view class="income-item">
  22. <view>本月收入(元)</view>
  23. <text>{{incomerpt.month}}</text>
  24. </view>
  25. <view class="income-item">
  26. <view>今日收入(元)</view>
  27. <text>{{incomerpt.today}}</text>
  28. </view>
  29. </view>
  30. </view>
  31. <view class="rpt-mid">
  32. <view class="rpt-mid-title">今日分时车流量趋势</view>
  33. <view style="height:30vh;"><qiun-data-charts type="line" :chartData="chartData" :opts="lineChartOpt" tooltipFormat="toolTipParkingFlow"/></view>
  34. </view>
  35. <u-card class="parking-card" full margin="0rpx 0rpx 20rpx" v-for="(item,index) in parksitList" :key="item.park_id">
  36. <view class="card-head" slot="head">
  37. <view @tap="showParkDtl(item.park_id)">{{item.parking_name}}</view>
  38. <u-icon :name="item.offline_count>0?'wifi-off':'wifi'" :color="item.offline_count>0?'#909090':'#48bc28'" size="32"></u-icon>
  39. </view>
  40. <view class="card-body" slot="body">
  41. <view class="body-item">
  42. <view>今日实收(元)</view>
  43. <text>{{item.today_pay_amount?item.today_pay_amount.toFixed(2):'0.00'}}</text>
  44. </view>
  45. <view class="body-item">
  46. <view>收款笔数</view>
  47. <text>{{item.today_pay_count?item.today_pay_count.toFixed(0):'0'}}</text>
  48. </view>
  49. <view class="body-item">
  50. <view>应收金额(元)</view>
  51. <text>{{item.should_pay?item.should_pay.toFixed(2):'0.00'}}</text>
  52. </view>
  53. </view>
  54. <view class="card-foot" slot="foot">
  55. <!-- <text>异常放行:0</text> -->
  56. <text>免单车次:{{item.free_pay_count?item.free_pay_count.toFixed(0):'0'}}</text>
  57. <text>剩余车位:{{item.idle_seat>0?item.idle_seat:0}}</text>
  58. </view>
  59. </u-card>
  60. </view>
  61. </template>
  62. <script>
  63. import * as api from '@/apis/index.js'
  64. import app from '@/utils/app.js'
  65. export default {
  66. data() {
  67. return {
  68. allParkIds:'',
  69. selparking:'all',
  70. parkingMenuTitle:'停车场',
  71. parkingMenuItems:[
  72. ],
  73. seatpie:{
  74. total:0,
  75. idle:0,
  76. percent:0
  77. },
  78. incomerpt:{
  79. total:0,
  80. month:0,
  81. today:0
  82. },
  83. parksitList:[
  84. ],
  85. chartData:{},
  86. lineChartOpt:{
  87. legend:{
  88. position:'bottom'
  89. },
  90. xAxis:{
  91. labelCount:8 ,//设置了X轴单屏数量 xAxis.itemCount 设置X轴密度
  92. //itemCount:5,
  93. //format:'xAxisDemo1'
  94. },
  95. yAxis:{
  96. showTitle: true,
  97. data:[
  98. {
  99. title:'车次'
  100. }
  101. ]
  102. }
  103. }
  104. }
  105. },
  106. onLoad() {
  107. //this.loadParkSites();
  108. //this.getServerData();
  109. },
  110. onShow(){
  111. this.loadParkSites();
  112. this.updatePageData(this.selparking!='all'?this.selparking:this.allParkIds);
  113. },
  114. methods: {
  115. showParkDtl(parkId){
  116. uni.navigateTo({
  117. url:'../parking/parkingSiteDes?park_id='+parkId
  118. })
  119. },
  120. changeFilterMenu(opt){
  121. //console.log(opt.label.length);
  122. //更换菜单后,将选中菜单名称显示在下拉标题中,字符过长进行截取
  123. if(opt.label.length>6){
  124. this.parkingMenuTitle=(opt.label).substr(0,6)+'...';
  125. }
  126. else{
  127. this.parkingMenuTitle=opt.label
  128. }
  129. this.updatePageData(opt.value!='all'?opt.value:this.allParkIds);
  130. },
  131. changeParkingMenuTitle(name){
  132. if(!name || name==""){
  133. return
  134. }
  135. this.parkingMenuTitle=name.length>6?(name.substr(0,6)+'...'):name
  136. },
  137. loadParkSites(){
  138. api.loadMyParkSites().then(resp => {
  139. if(!resp.success){
  140. uni.showToast({
  141. title: resp.msg||' 加载数据失败',
  142. icon: "none"
  143. })
  144. return;
  145. }
  146. this.parseForFilterMenu(resp.data);
  147. //this.parseAndUpdateData(resp.data.parkRunWrap);
  148. }).catch(error => {
  149. });
  150. },
  151. updatePageData(parkIds){
  152. api.loadParkTrends(parkIds).then(resp => {
  153. //console.log(resp)
  154. this.parseAndUpdateData(resp.data);
  155. }).catch(error => {
  156. });
  157. },
  158. parseForFilterMenu(dataObj){
  159. if(dataObj&&dataObj.parkBase){
  160. let parkIds=[],parkAry=[];
  161. dataObj.parkBase.forEach(function(item){
  162. parkIds.push(item.park_id);
  163. parkAry.push({park_id:item.park_id,parking_name:item.parking_name});
  164. });
  165. if(dataObj.parkBase.length==1){ //只有一个停车场的下拉菜单直接显示其名
  166. this.changeParkingMenuTitle(dataObj.parkBase[0].label)
  167. this.selparking=dataObj.parkBase[0].value
  168. }
  169. dataObj.parkBase.unshift({label:'全部停车场',value:'all'}); //因为引用关系 unshift 可能时vue内的改造过的方法
  170. this.parkingMenuItems=dataObj.parkBase;
  171. this.allParkIds=parkIds.join(",");
  172. app.putSetting('myParks',parkAry);
  173. }
  174. this.parseAndUpdateData(dataObj.parkRunWrap);
  175. },
  176. parseAndUpdateData(dataObj){ //dataObj:[parkRun]
  177. if(!dataObj||!dataObj.parkRun){
  178. return;
  179. }
  180. this.parksitList=dataObj.parkRun;
  181. //计算总车位信息,收入累计
  182. let seatrpt={total:0,idle:0,percent:0};
  183. let income={total:0,month:0,today:0};
  184. let tmp=0;
  185. for(let i=0,len=dataObj.parkRun.length;i<len;i++){
  186. seatrpt.total+=dataObj.parkRun[i].total_seat||0;
  187. tmp=dataObj.parkRun[i].idle_seat;
  188. seatrpt.idle+=tmp&&tmp>0?tmp:0;
  189. income.total+=dataObj.parkRun[i].total_pay_amount||0;
  190. income.month+=dataObj.parkRun[i].month_pay_amount||0;
  191. income.today+=dataObj.parkRun[i].today_pay_amount||0;
  192. }
  193. if(seatrpt.total>0){
  194. tmp=seatrpt.idle*100/seatrpt.total;
  195. seatrpt.percent=parseInt(tmp.toFixed(0));
  196. }
  197. this.seatpie=seatrpt;
  198. income.total=(income.total).toFixed(2);
  199. income.month=(income.month).toFixed(2);
  200. income.today=(income.today).toFixed(2);
  201. this.incomerpt=income;
  202. //折线图数据准备
  203. dataObj.chartDatas.categories.forEach(function(item,index){
  204. dataObj.chartDatas.categories[index]=item+"时";
  205. });
  206. let lineChartData={};
  207. lineChartData.categories=dataObj.chartDatas.categories;
  208. lineChartData.series=[];
  209. lineChartData.series.push({name:'入场',data:dataObj.chartDatas.seriesIn});
  210. lineChartData.series.push({name:'出场',data:dataObj.chartDatas.seriesOut});
  211. this.chartData=lineChartData;
  212. }
  213. }
  214. }
  215. </script>
  216. <style scoped>
  217. page{
  218. /* height:100%; */
  219. background-color: #f4f4f4;
  220. /* padding-bottom: 50px; */
  221. }
  222. .top-navbar/deep/ .u-slot-content{
  223. justify-content: space-between;
  224. padding:0rpx;
  225. color:#ffffff;
  226. }
  227. .top-navbar/deep/ .u-dropdown__menu{
  228. justify-content: flex-end;
  229. }
  230. .top-navbar/deep/ .u-dropdown__menu .u-dropdown__menu__item{
  231. flex:none;
  232. margin-right: 40rpx;
  233. }
  234. .top-navbar/deep/ .u-dropdown__menu__item__text{
  235. color:#ffffff !important;
  236. }
  237. .content {
  238. display: flex;
  239. flex-direction: column;
  240. align-items: center;
  241. justify-content: center;
  242. }
  243. .rpt-top{
  244. background: linear-gradient(#1f58ff, #00aaff);
  245. height:35vh;
  246. width:100vw;
  247. display: flex;
  248. flex-direction: column;
  249. align-items: center;
  250. justify-content: center;
  251. }
  252. .rpt-mid{
  253. background-color: #ffffff;
  254. /* height:45vh; */
  255. width:100vw;
  256. margin-bottom: 20rpx;
  257. /* position: absolute;
  258. z-index: 100; */
  259. }
  260. .rpt-mid .rpt-mid-title{
  261. font-size:28rpx;
  262. /* font-family: '宋体'; */
  263. margin:20rpx;
  264. padding-left:20rpx;
  265. border-left: 8rpx solid #1F58FF;
  266. }
  267. .parking-card{
  268. width:100%;
  269. box-sizing: border-box;
  270. margin:0rpx;
  271. }
  272. /deep/ .parking-card .u-card__head{
  273. padding: 20rpx !important;
  274. }
  275. .parking-card .card-head{
  276. display: flex;
  277. flex-flow: row nowrap;
  278. justify-content:space-between;
  279. align-items: center;
  280. color:#000000;
  281. /* font-family: '黑体'; */
  282. }
  283. .parking-card .card-body{
  284. padding:0rpx;
  285. display: flex;
  286. flex-flow: row nowrap;
  287. justify-content:space-around;
  288. align-items: center;
  289. }
  290. .parking-card .card-body .body-item{
  291. text-align: center;
  292. }
  293. .parking-card .card-body .body-item view{
  294. font-size: 24rpx;
  295. color:#6f867d;
  296. margin-bottom:10rpx;
  297. }
  298. .parking-card .card-body .body-item text{
  299. font-size: 36rpx;
  300. color:#007AFF;
  301. }
  302. .parking-card .card-foot{
  303. padding:0rpx;
  304. display: flex;
  305. flex-flow: row nowrap;
  306. justify-content:space-around;
  307. align-items: center;
  308. font-size: 24rpx;
  309. color:#6f867d;
  310. }
  311. .u-progress-content{
  312. color:#ffffff;
  313. display: flex;
  314. flex-direction: column;
  315. align-items: center;
  316. justify-content: center;
  317. }
  318. .u-progress-content .title{
  319. font-size: 48rpx;
  320. font-weight: bold;
  321. margin:10rpx 0rpx;
  322. }
  323. .u-progress-content .subtitle{
  324. font-size: 28rpx;
  325. }
  326. .rpt-top .income-rpt{
  327. width:100%;
  328. height:100rpx;
  329. padding:30rpx;
  330. display: flex;
  331. flex-flow: row nowrap;
  332. justify-content:space-around;
  333. align-items: center;
  334. color:#ffffff;
  335. }
  336. .rpt-top .income-rpt .income-item{
  337. text-align: center;
  338. }
  339. .rpt-top .income-rpt .income-item view{
  340. font-size: 26rpx;
  341. margin-bottom:5rpx;
  342. }
  343. .rpt-top .income-rpt .income-item text{
  344. font-size: 32rpx;
  345. }
  346. </style>