charge.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  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. onShow(){
  147. this.loadPageData(this.getLoadParams());
  148. },
  149. onReachBottom(){
  150. this.reachbtm=true;
  151. if(!this.checkHadMore()){ //没有更多数据
  152. return;
  153. }
  154. this.loadMoreStat = 'loading';
  155. this.loadMoreData(this.getLoadParams(true));
  156. },
  157. methods: {
  158. getLoadParams(loadMore){
  159. let crtParams={...this.loadParams};
  160. if(loadMore){
  161. if(crtParams.pageNum<crtParams.pageCount){
  162. crtParams.pageNum+=1;
  163. }
  164. else{ //更换日期,重置页码,其它参数不变
  165. crtParams.chargeDate=api.addDate(crtParams.chargeDate,-1);
  166. crtParams.pageNum=1;
  167. crtParams.pageCount=0;
  168. }
  169. }
  170. else{//全新查询
  171. crtParams.chargeDate=this.filter.endDate;
  172. crtParams.pageNum=1;
  173. crtParams.pageCount=0;
  174. let parkarg=this.selectedParkVal=="all"?this.allParkIds:this.selectedParkVal;
  175. crtParams.parkingIds=parkarg;
  176. crtParams.chargeStart=this.filter.startDate;
  177. crtParams.chargeEnd=this.filter.endDate;
  178. crtParams.pageSize=10;
  179. }
  180. return crtParams;
  181. },
  182. checkHadMore(){
  183. let rst=this.loadParams.pageNum<this.loadParams.pageCount||this.loadParams.chargeDate>this.loadParams.chargeStart;
  184. this.loadMoreStat=rst?'loadmore':'nomore';
  185. return rst;
  186. },
  187. selectDateRange(){
  188. this.showCalendar=true;
  189. },
  190. changeCalendar(e){
  191. //console.log(e);
  192. this.filter.startDate=e.startDate;
  193. this.filter.endDate=e.endDate;
  194. },
  195. selectFilter(filterSort,e){
  196. console.log(filterSort);
  197. console.log(e);
  198. if(e.target.dataset.val!=null){
  199. this.filter[filterSort]=e.target.dataset.val;
  200. }
  201. },
  202. resetFilter(){
  203. let resetObj={
  204. startDate:'',
  205. endDate:''
  206. };
  207. this.filter=resetObj;
  208. this.selectedParkVal='all';
  209. },
  210. sureFilter(){
  211. this.$refs.filterDropdown.close();
  212. this.loadPageData(this.getLoadParams());
  213. //console.log('query'+parkarg)
  214. },
  215. showChargeDtl(id){
  216. //console.log(id);
  217. uni.navigateTo({
  218. url:'chargedtl?parkingLogId='+id
  219. })
  220. },
  221. loadPageData(param){ //全新查询,按chargeStart-chargeEnd 先查chargeEnd的
  222. uni.showLoading({
  223. title:'加载中...'
  224. });
  225. this.reachbtm=false; //全新查询重置该值
  226. console.log(param)
  227. api.loadPageData(param).then(resp => {
  228. //console.log(resp)
  229. uni.hideLoading();
  230. if(!resp.success){
  231. return;
  232. }
  233. if(resp.data){
  234. let rptData=resp.data.rptPay||{};
  235. let tmp={};
  236. tmp.todayPayAmount=rptData.today_pay_amount?rptData.today_pay_amount.toFixed(2):'0.00';
  237. tmp.todayPayCount=rptData.today_pay_count?rptData.today_pay_count.toFixed(0):'0';
  238. tmp.shouldPayAmount=rptData.should_pay_amount?rptData.should_pay_amount.toFixed(2):'0.00';
  239. this.rptPay=tmp;
  240. }
  241. if(resp.data.maxValiDate){ //实际查询的最大日期
  242. param.chargeDate=resp.data.maxValiDate
  243. }
  244. this.pagedPayLog=this.parsePayLog(param,resp.data.payLogs.pagedData,resp.data.payLogs.dayGrp);
  245. this.loadParams=param; //更新查询参数
  246. //console.log(this.pagedPayLog)
  247. if(!this.reachbtm&&this.checkHadMore()){ //未到底且还有数据,自动再加载一次
  248. this.loadMoreData(this.getLoadParams(true));
  249. }
  250. }).catch(error => {
  251. uni.hideLoading();
  252. });
  253. },
  254. parsePayLog(param,pagedObj,dayGrp){
  255. //console.log(pagedObj);
  256. let datas=pagedObj.records;
  257. param.pageNum=pagedObj.current;
  258. param.pageCount=pagedObj.pages;
  259. //let viewObj={pageNum:pagedObj.current,pageCount:pagedObj.pages,pageSize:pagedObj.size};
  260. if(datas==null||datas.length==0){
  261. //viewObj['datas']=[];
  262. return [];
  263. }
  264. else{
  265. let dateMap={},mapItem=null,tmp=null,pkh=null;
  266. let listDatas=[];
  267. listDatas.push({dayDate:dayGrp.pay_date,dayTotal:(dayGrp.day_pay_amount||0).toFixed(2),dayDatas:[]});
  268. datas.forEach(function(item,index){
  269. /* if(dateMap[item.pay_date]==null){
  270. listDatas.push({dayDate:item.pay_date,dayTotal:0,dayDatas:[]});
  271. dateMap[item.pay_date]=listDatas.length-1;
  272. } */
  273. item["pay_mode"]={"wechat":"微信","alipay":"支付宝"}[item.pay_name]||'其它';
  274. tmp=item.parking_time;
  275. pkh=Math.floor(tmp/60);
  276. item['parking_time_txt']=pkh>0?(pkh.toFixed(0)+"小时"+(tmp-pkh*60)+"分钟"):(tmp+"分钟");
  277. //mapItem=listDatas[dateMap[item.pay_date]];
  278. //mapItem.dayTotal+=parseFloat((item.pay_amount||0).toFixed(2));
  279. //mapItem.dayDatas.push(item);
  280. listDatas[0].dayDatas.push(item);
  281. });
  282. //viewObj['datas']=listDatas;
  283. return listDatas;
  284. }
  285. },
  286. loadMoreData(param){ //按chargeDate参数查询
  287. console.log(param);
  288. api.queryChargeLog(param).then(resp => {
  289. //console.log(resp)
  290. if(!resp.success){
  291. return;
  292. }
  293. let newDatas=this.parsePayLog(param,resp.data.pagedData,resp.data.dayGrp);
  294. this.loadParams=param; //更新查询参数
  295. if(newDatas&&newDatas.length>0){
  296. /* let preLastItm=this.pagedPayLog.datas[this.pagedPayLog.datas.length-1];
  297. let newFirstItm=newDatas.datas[0];
  298. if(preLastItm.dayDate==newFirstItm.dayDate){ //新旧数据有同日期的先合并再附加新数据
  299. preLastItm.dayTotal+=newFirstItm.dayTotal;
  300. preLastItm.dayDatas=preLastItm.dayDatas.concat(newFirstItm.dayDatas);
  301. newDatas.datas.shift(); //合并后删除避免重复
  302. }
  303. this.pagedPayLog.datas=this.pagedPayLog.datas.concat(newDatas.datas); */
  304. //新旧数据有同日期的先合并再附加新数据
  305. let preLastItm=this.pagedPayLog[this.pagedPayLog.length-1];
  306. if(preLastItm.dayDate==newDatas[0].dayDate){
  307. preLastItm.dayDatas=preLastItm.dayDatas.concat(newDatas[0].dayDatas);
  308. }
  309. else{
  310. this.pagedPayLog=this.pagedPayLog.concat(newDatas);
  311. }
  312. }
  313. this.checkHadMore();
  314. }).catch(error =>{
  315. });
  316. }
  317. }
  318. }
  319. </script>
  320. <style>
  321. page{
  322. background-color: #f4f4f4;
  323. }
  324. .top-navbar/deep/ .u-slot-content{
  325. justify-content: space-between;
  326. padding:0rpx;
  327. }
  328. .top-navbar/deep/ .u-dropdown__menu{
  329. justify-content: flex-end;
  330. }
  331. .top-navbar/deep/ .u-dropdown__menu .u-dropdown__menu__item{
  332. flex:none;
  333. margin-right: 40rpx;
  334. }
  335. /* .top-navbar/deep/ .u-dropdown__menu__item__text{
  336. color:#ffffff !important;
  337. } */
  338. .content {
  339. display: flex;
  340. flex-direction: column;
  341. align-items: center;
  342. justify-content: center;
  343. }
  344. .dropdown-filter-con{
  345. display: flex;
  346. flex-direction: column;
  347. align-items: flex-start;
  348. justify-content: center;
  349. padding:20rpx 0rpx 0rpx;
  350. box-sizing: border-box;
  351. background-color: #fafafa;
  352. font-size: 26rpx;
  353. }
  354. .filter-item{
  355. width:100%;
  356. padding:0rpx 20rpx 30rpx;
  357. }
  358. .filter-item .filter-label{
  359. /* font-family: '楷体'; */
  360. }
  361. .filter-date{
  362. width:100%;
  363. height:55rpx;
  364. line-height: 55rpx;
  365. background-color: #f2f5fa;
  366. margin-top: 20rpx;
  367. display: flex;
  368. align-items:center;
  369. }
  370. .filter-date text{
  371. flex:1;
  372. }
  373. .filter-con{
  374. display: flex;
  375. flex-flow: row wrap;
  376. justify-content:flex-start;
  377. align-items: center;
  378. margin-top: 20rpx;
  379. }
  380. .filter-con .filter-con-item{
  381. padding:10rpx 10rpx;
  382. text-align: center;
  383. background-color: #f2f5fa;
  384. /* color:#ffffff; */
  385. /* height: 45rpx; */
  386. width:28vw;
  387. margin-right: 3vw;
  388. margin-bottom: 20rpx;
  389. }
  390. .filter-con .selected-filter{
  391. background-color: #185ac6;
  392. color:#ffffff;
  393. }
  394. .filter-btn{
  395. display: flex;
  396. flex-flow: row wrap;
  397. justify-content:flex-start;
  398. align-items: center;
  399. height: 80rpx;
  400. width:100vw;
  401. border-top:1px solid #f2f2f2;
  402. }
  403. .filter-btn-reset{
  404. flex:1;
  405. text-align: center;
  406. line-height: 80rpx;
  407. background-color: #f2f2f2;
  408. }
  409. .filter-btn-sure{
  410. flex:2;
  411. text-align: center;
  412. background-color: #185ac6;
  413. color:#ffffff;
  414. line-height: 80rpx;
  415. }
  416. .content-top{
  417. width:100vw;
  418. /* height:130rpx; */
  419. padding:20rpx 0rpx;
  420. display: flex;
  421. flex-flow: row nowrap;
  422. justify-content:space-around;
  423. align-items: center;
  424. background: linear-gradient(#0088ff,#1f58ff);
  425. color: #ffffff;
  426. /* position: fixed; */
  427. top:95rpx;
  428. }
  429. .content-top .top-item{
  430. text-align: center;
  431. }
  432. .content-top .top-item view{
  433. font-size: 24rpx;
  434. color:#efefef;
  435. margin-bottom:10rpx;
  436. }
  437. .content-top .top-item text{
  438. font-size: 36rpx;
  439. }
  440. .charge-list{
  441. width:100vw;
  442. }
  443. .charge-list .charge-date{
  444. padding:20rpx 30rpx;
  445. font-size: 26rpx;
  446. height: 80rpx;
  447. }
  448. .charge-list .charge-date .charge-date-left{
  449. float:left;
  450. }
  451. .charge-list .charge-date .charge-date-right{
  452. float:right;
  453. }
  454. .charge-list .charge-item{
  455. background-color: #ffffff;
  456. padding:10rpx 30rpx;
  457. border-bottom: 1px solid #f2f2f2;
  458. }
  459. .charge-list .charge-item .charge-item-title{
  460. font-size: 28rpx;
  461. font-weight: bold;
  462. padding:10rpx 0rpx;
  463. }
  464. .charge-list .charge-item .charge-dtl{
  465. font-size: 26rpx;
  466. color:#888888;
  467. float:left;
  468. }
  469. .charge-list .charge-item .charge-item-body{
  470. display: flex;
  471. flex-flow: row nowrap;
  472. justify-content:space-between;
  473. align-items: center;
  474. }
  475. .charge-list .charge-item .charge-dtl view{
  476. margin-bottom: 8rpx;
  477. }
  478. .charge-list .charge-item .charge-money{
  479. margin-right: 0rpx;
  480. float:right;
  481. width:180rpx;
  482. text-align: right;
  483. }
  484. .charge-list .charge-item .charge-money text{
  485. font-size:36rpx;
  486. font-weight: bold;
  487. margin-right: 10rpx;
  488. color:#1F58FF;
  489. }
  490. </style>