charge.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. <template>
  2. <view class="content">
  3. <u-navbar title="" :is-back="false" class="top-navbar">
  4. <text style="position: absolute;z-index: 1;left:40rpx;">收费明细</text>
  5. <u-dropdown ref="filterDropdown">
  6. <u-dropdown-item title="筛选">
  7. <view class="slot-content dropdown-filter-con">
  8. <view class="filter-item">
  9. <text class="filter-label">查询日期</text>
  10. <view class="filter-date" @tap="selectDateRange">
  11. <text>{{filter.endDate.length>0?(filter.startDate+' 至 '+filter.endDate):'请选择'}}</text>
  12. <u-icon name="search" style="margin:0rpx 20rpx;"></u-icon>
  13. </view>
  14. </view>
  15. <!-- <view class="filter-item">
  16. <text class="filter-label">收费状态</text>
  17. <view class="filter-con" @tap="selectFilter('chargeStat',$event)">
  18. <view class="filter-con-item" data-val='0' :class="{'selected-filter-item':filter.chargeStat=='0'}">全部</view>
  19. <view class="filter-con-item" data-val='1' :class="{'selected-filter-item':filter.chargeStat=='1'}">全部</view>
  20. <view class="filter-con-item" data-val='2' :class="{'selected-filter-item':filter.chargeStat=='2'}">全部</view>
  21. <view class="filter-con-item">全部</view>
  22. <view class="filter-con-item">全部</view>
  23. </view>
  24. </view> -->
  25. <!-- <view class="filter-item">
  26. <text class="filter-label">车牌类型</text>
  27. <view class="filter-con">
  28. <view class="filter-con-item">全部</view>
  29. <view class="filter-con-item">全部</view>
  30. <view class="filter-con-item">全部</view>
  31. </view>
  32. </view>
  33. -->
  34. <view class="filter-item">
  35. <text class="filter-label">停车场</text>
  36. <view class="filter-con">
  37. <view @tap="selectedParkVal='all'" class="filter-con-item" :class="{'selected-filter':selectedParkVal=='all'}" data-val="all">全部</view>
  38. <block v-for="(item,index) in myParkSites" :key="item.park_id">
  39. <view @tap="selectedParkVal=item.park_id" class="filter-con-item" :class="{'selected-filter':selectedParkVal==item.park_id}" :data-val="item.park_id">{{item.parking_name.length>7?(item.parking_name.substr(0,7)+'...'):item.parking_name}}</view>
  40. </block>
  41. </view>
  42. </view>
  43. <!-- <view class="filter-item">
  44. <text class="filter-label">闸口</text>
  45. <view class="filter-con">
  46. <view class="filter-con-item">全部</view>
  47. <view class="filter-con-item">全部</view>
  48. <view class="filter-con-item">全部</view>
  49. </view>
  50. </view> -->
  51. <view class="filter-btn">
  52. <view class="filter-btn-reset" @tap="resetFilter">重置</view>
  53. <view class="filter-btn-sure" @tap="sureFilter">确定</view>
  54. </view>
  55. </view>
  56. </u-dropdown-item>
  57. </u-dropdown>
  58. </u-navbar>
  59. <u-calendar v-model="showCalendar" mode="range" @change="changeCalendar"></u-calendar>
  60. <view class="content-top">
  61. <view class="top-item">
  62. <view>实收金额(元)</view>
  63. <text>{{rptPay.todayPayAmount}}</text>
  64. </view>
  65. <view class="top-item">
  66. <view>收款笔数</view>
  67. <text>{{rptPay.todayPayCount}}</text>
  68. </view>
  69. <view class="top-item">
  70. <view>应收金额(元)</view>
  71. <text>{{rptPay.shouldPayAmount}}</text>
  72. </view>
  73. </view>
  74. <view class="charge-list">
  75. <block v-for="(item,index) in pagedPayLog" :key="item.dayDate">
  76. <view class="charge-date">
  77. <view class="charge-date-left">{{item.dayDate}}</view>
  78. <view class="charge-date-right">当日收费 {{item.dayTotal}}元</view>
  79. </view>
  80. <block v-for="(data,didx) in item.dayDatas">
  81. <view class="charge-item">
  82. <view class="charge-item-title">{{data.car_num}}</view>
  83. <view class="charge-item-body">
  84. <view class="charge-dtl">
  85. <view>停车位置:{{data.parking_name}}</view>
  86. <view>进入时间:{{data.in_parking_time}}</view>
  87. <view>离开时间:{{data.out_parking_time}}</view>
  88. <view>停车时长:{{data.parking_time_txt}}</view>
  89. <view>支付方式:{{data.pay_mode}}</view>
  90. </view>
  91. <view class="charge-money" @tap="showChargeDtl(data.parking_log_id)">
  92. <text>{{data.pay_amount}}元</text>
  93. <u-icon name="arrow-right"></u-icon>
  94. </view>
  95. </view>
  96. </view>
  97. </block>
  98. </block>
  99. <view v-show="reachbtm">
  100. <u-loadmore :status="loadMoreStat" :load-text="loadMoreText"/>
  101. </view>
  102. <view v-show="pagedPayLog.length==0" style="margin:50rpx;text-align: center;">未找到相关数据</view>
  103. </view>
  104. </view>
  105. </template>
  106. <script>
  107. import * as api from '@/apis/charge.js'
  108. export default {
  109. data() {
  110. return {
  111. reachbtm:false,
  112. showCalendar:false,
  113. loadMoreStat:'loadmore',
  114. loadMoreText: {
  115. loadmore: '轻轻上拉',
  116. loading: '努力加载中',
  117. nomore: '实在没有了'
  118. },
  119. filter:{
  120. startDate:'',
  121. endDate:''
  122. },
  123. rptPay:{
  124. todayPayAmount:'0.00',
  125. todayPayCount:'0',
  126. shouldPayAmount:'0.00'
  127. },
  128. myParkSites:[],
  129. selectedParkVal:'all',
  130. allParkIds:'',
  131. pagedPayLog:{
  132. datas:[]
  133. },
  134. loadParams:{}
  135. }
  136. },
  137. onLoad(){
  138. this.myParkSites=api.getMyParkSites();
  139. let ids=[];
  140. this.myParkSites.forEach(function(item){
  141. ids.push(item.park_id);
  142. });
  143. this.allParkIds=ids.join(",");
  144. this.loadPageData(this.getLoadParams());
  145. },
  146. onReachBottom(){
  147. this.reachbtm=true;
  148. if(!this.checkHadMore()){ //没有更多数据
  149. return;
  150. }
  151. this.loadMoreStat = 'loading';
  152. this.loadMoreData(this.getLoadParams(true));
  153. },
  154. methods: {
  155. getLoadParams(loadMore){
  156. let crtParams={...this.loadParams};
  157. if(loadMore){
  158. if(crtParams.pageNum<crtParams.pageCount){
  159. crtParams.pageNum+=1;
  160. }
  161. else{ //更换日期,重置页码,其它参数不变
  162. crtParams.chargeDate=api.addDate(crtParams.chargeDate,-1);
  163. crtParams.pageNum=1;
  164. crtParams.pageCount=0;
  165. }
  166. }
  167. else{//全新查询
  168. crtParams.chargeDate=this.filter.endDate;
  169. crtParams.pageNum=1;
  170. crtParams.pageCount=0;
  171. let parkarg=this.selectedParkVal=="all"?this.allParkIds:this.selectedParkVal;
  172. crtParams.parkingIds=parkarg;
  173. crtParams.chargeStart=this.filter.startDate;
  174. crtParams.chargeEnd=this.filter.endDate;
  175. crtParams.pageSize=10;
  176. }
  177. return crtParams;
  178. },
  179. checkHadMore(){
  180. let rst=this.loadParams.pageNum<this.loadParams.pageCount||this.loadParams.chargeDate>this.loadParams.chargeStart;
  181. this.loadMoreStat=rst?'loadmore':'nomore';
  182. return rst;
  183. },
  184. selectDateRange(){
  185. this.showCalendar=true;
  186. },
  187. changeCalendar(e){
  188. //console.log(e);
  189. this.filter.startDate=e.startDate;
  190. this.filter.endDate=e.endDate;
  191. },
  192. selectFilter(filterSort,e){
  193. console.log(filterSort);
  194. console.log(e);
  195. if(e.target.dataset.val!=null){
  196. this.filter[filterSort]=e.target.dataset.val;
  197. }
  198. },
  199. resetFilter(){
  200. let resetObj={
  201. startDate:'',
  202. endDate:''
  203. };
  204. this.filter=resetObj;
  205. this.selectedParkVal='all';
  206. },
  207. sureFilter(){
  208. this.$refs.filterDropdown.close();
  209. this.loadPageData(this.getLoadParams());
  210. //console.log('query'+parkarg)
  211. },
  212. showChargeDtl(id){
  213. //console.log(id);
  214. uni.navigateTo({
  215. url:'chargedtl?parkingLogId='+id
  216. })
  217. },
  218. loadPageData(param){
  219. uni.showLoading({
  220. title:'加载中...'
  221. });
  222. this.reachbtm=false; //全新查询重置该值
  223. console.log(param)
  224. api.loadPageData(param).then(resp => {
  225. uni.hideLoading();
  226. if(!resp.success){
  227. return;
  228. }
  229. if(resp.data){
  230. let rptData=resp.data.rptPay||{};
  231. let tmp={};
  232. tmp.todayPayAmount=rptData.today_pay_amount?rptData.today_pay_amount.toFixed(2):'0.00';
  233. tmp.todayPayCount=rptData.today_pay_count?rptData.today_pay_count.toFixed(0):'0';
  234. tmp.shouldPayAmount=rptData.should_pay_amount?rptData.should_pay_amount.toFixed(2):'0.00';
  235. this.rptPay=tmp;
  236. }
  237. this.pagedPayLog=this.parsePayLog(param,resp.data.payLogs.pagedData,resp.data.payLogs.dayGrp);
  238. this.loadParams=param; //更新查询参数
  239. console.log(this.pagedPayLog)
  240. if(!this.reachbtm&&this.checkHadMore()){ //未到底且还有数据,自动再加载一次
  241. this.loadMoreData(this.getLoadParams(true));
  242. }
  243. }).catch(error => {
  244. uni.hideLoading();
  245. });
  246. },
  247. parsePayLog(param,pagedObj,dayGrp){
  248. //console.log(pagedObj);
  249. let datas=pagedObj.records;
  250. param.pageNum=pagedObj.current;
  251. param.pageCount=pagedObj.pages;
  252. //let viewObj={pageNum:pagedObj.current,pageCount:pagedObj.pages,pageSize:pagedObj.size};
  253. if(datas==null||datas.length==0){
  254. //viewObj['datas']=[];
  255. return [];
  256. }
  257. else{
  258. let dateMap={},mapItem=null,tmp=null,pkh=null;
  259. let listDatas=[];
  260. listDatas.push({dayDate:dayGrp.pay_date,dayTotal:(dayGrp.day_pay_amount||0).toFixed(2),dayDatas:[]});
  261. datas.forEach(function(item,index){
  262. /* if(dateMap[item.pay_date]==null){
  263. listDatas.push({dayDate:item.pay_date,dayTotal:0,dayDatas:[]});
  264. dateMap[item.pay_date]=listDatas.length-1;
  265. } */
  266. item["pay_mode"]={"wechat":"微信","alipay":"支付宝"}[item.pay_name]||'其它';
  267. tmp=item.parking_time;
  268. pkh=Math.floor(tmp/60);
  269. item['parking_time_txt']=pkh>0?(pkh.toFixed(0)+"小时"+(tmp-pkh*60)+"分钟"):(tmp+"分钟");
  270. //mapItem=listDatas[dateMap[item.pay_date]];
  271. //mapItem.dayTotal+=parseFloat((item.pay_amount||0).toFixed(2));
  272. //mapItem.dayDatas.push(item);
  273. listDatas[0].dayDatas.push(item);
  274. });
  275. //viewObj['datas']=listDatas;
  276. return listDatas;
  277. }
  278. },
  279. loadMoreData(param){
  280. console.log(param);
  281. api.queryChargeLog(param).then(resp => {
  282. //console.log(resp)
  283. if(!resp.success){
  284. return;
  285. }
  286. let newDatas=this.parsePayLog(param,resp.data.pagedData,resp.data.dayGrp);
  287. this.loadParams=param; //更新查询参数
  288. if(newDatas&&newDatas.length>0){
  289. /* let preLastItm=this.pagedPayLog.datas[this.pagedPayLog.datas.length-1];
  290. let newFirstItm=newDatas.datas[0];
  291. if(preLastItm.dayDate==newFirstItm.dayDate){ //新旧数据有同日期的先合并再附加新数据
  292. preLastItm.dayTotal+=newFirstItm.dayTotal;
  293. preLastItm.dayDatas=preLastItm.dayDatas.concat(newFirstItm.dayDatas);
  294. newDatas.datas.shift(); //合并后删除避免重复
  295. }
  296. this.pagedPayLog.datas=this.pagedPayLog.datas.concat(newDatas.datas); */
  297. //新旧数据有同日期的先合并再附加新数据
  298. let preLastItm=this.pagedPayLog[this.pagedPayLog.length-1];
  299. if(preLastItm.dayDate==newDatas[0].dayDate){
  300. preLastItm.dayDatas=preLastItm.dayDatas.concat(newDatas[0].dayDatas);
  301. }
  302. else{
  303. this.pagedPayLog=this.pagedPayLog.concat(newDatas);
  304. }
  305. }
  306. this.checkHadMore();
  307. }).catch(error =>{
  308. });
  309. }
  310. }
  311. }
  312. </script>
  313. <style>
  314. page{
  315. background-color: #f4f4f4;
  316. }
  317. .top-navbar/deep/ .u-slot-content{
  318. justify-content: space-between;
  319. padding:0rpx;
  320. }
  321. .top-navbar/deep/ .u-dropdown__menu{
  322. justify-content: flex-end;
  323. }
  324. .top-navbar/deep/ .u-dropdown__menu .u-dropdown__menu__item{
  325. flex:none;
  326. margin-right: 40rpx;
  327. }
  328. /* .top-navbar/deep/ .u-dropdown__menu__item__text{
  329. color:#ffffff !important;
  330. } */
  331. .content {
  332. display: flex;
  333. flex-direction: column;
  334. align-items: center;
  335. justify-content: center;
  336. }
  337. .dropdown-filter-con{
  338. display: flex;
  339. flex-direction: column;
  340. align-items: flex-start;
  341. justify-content: center;
  342. padding:20rpx 0rpx 0rpx;
  343. box-sizing: border-box;
  344. background-color: #fafafa;
  345. font-size: 26rpx;
  346. }
  347. .filter-item{
  348. width:100%;
  349. padding:0rpx 20rpx 30rpx;
  350. }
  351. .filter-item .filter-label{
  352. /* font-family: '楷体'; */
  353. }
  354. .filter-date{
  355. width:100%;
  356. height:55rpx;
  357. line-height: 55rpx;
  358. background-color: #f2f5fa;
  359. margin-top: 20rpx;
  360. display: flex;
  361. align-items:center;
  362. }
  363. .filter-date text{
  364. flex:1;
  365. }
  366. .filter-con{
  367. display: flex;
  368. flex-flow: row wrap;
  369. justify-content:flex-start;
  370. align-items: center;
  371. margin-top: 20rpx;
  372. }
  373. .filter-con .filter-con-item{
  374. padding:10rpx 10rpx;
  375. text-align: center;
  376. background-color: #f2f5fa;
  377. /* color:#ffffff; */
  378. /* height: 45rpx; */
  379. width:28vw;
  380. margin-right: 3vw;
  381. margin-bottom: 20rpx;
  382. }
  383. .filter-con .selected-filter{
  384. background-color: #185ac6;
  385. color:#ffffff;
  386. }
  387. .filter-btn{
  388. display: flex;
  389. flex-flow: row wrap;
  390. justify-content:flex-start;
  391. align-items: center;
  392. height: 80rpx;
  393. width:100vw;
  394. border-top:1px solid #f2f2f2;
  395. }
  396. .filter-btn-reset{
  397. flex:1;
  398. text-align: center;
  399. line-height: 80rpx;
  400. background-color: #f2f2f2;
  401. }
  402. .filter-btn-sure{
  403. flex:2;
  404. text-align: center;
  405. background-color: #185ac6;
  406. color:#ffffff;
  407. line-height: 80rpx;
  408. }
  409. .content-top{
  410. width:100vw;
  411. /* height:130rpx; */
  412. padding:20rpx 0rpx;
  413. display: flex;
  414. flex-flow: row nowrap;
  415. justify-content:space-around;
  416. align-items: center;
  417. background: linear-gradient(#0088ff,#1f58ff);
  418. color: #ffffff;
  419. /* position: fixed; */
  420. top:95rpx;
  421. }
  422. .content-top .top-item{
  423. text-align: center;
  424. }
  425. .content-top .top-item view{
  426. font-size: 24rpx;
  427. color:#efefef;
  428. margin-bottom:10rpx;
  429. }
  430. .content-top .top-item text{
  431. font-size: 36rpx;
  432. }
  433. .charge-list{
  434. width:100vw;
  435. }
  436. .charge-list .charge-date{
  437. padding:20rpx 30rpx;
  438. font-size: 26rpx;
  439. height: 80rpx;
  440. }
  441. .charge-list .charge-date .charge-date-left{
  442. float:left;
  443. }
  444. .charge-list .charge-date .charge-date-right{
  445. float:right;
  446. }
  447. .charge-list .charge-item{
  448. background-color: #ffffff;
  449. padding:10rpx 30rpx;
  450. border-bottom: 1px solid #f2f2f2;
  451. }
  452. .charge-list .charge-item .charge-item-title{
  453. font-size: 28rpx;
  454. font-weight: bold;
  455. padding:10rpx 0rpx;
  456. }
  457. .charge-list .charge-item .charge-dtl{
  458. font-size: 26rpx;
  459. color:#888888;
  460. float:left;
  461. }
  462. .charge-list .charge-item .charge-item-body{
  463. display: flex;
  464. flex-flow: row nowrap;
  465. justify-content:space-between;
  466. align-items: center;
  467. }
  468. .charge-list .charge-item .charge-dtl view{
  469. margin-bottom: 8rpx;
  470. }
  471. .charge-list .charge-item .charge-money{
  472. margin-right: 0rpx;
  473. float:right;
  474. width:180rpx;
  475. text-align: right;
  476. }
  477. .charge-list .charge-item .charge-money text{
  478. font-size:36rpx;
  479. font-weight: bold;
  480. margin-right: 10rpx;
  481. color:#1F58FF;
  482. }
  483. </style>