parkinglog.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
  1. <template>
  2. <view class="content">
  3. <u-navbar title="" :is-back="false" :background="{backgroundColor: '#ffffff'}" class="top-navbar">
  4. <text style="position: absolute;z-index: 1;left:40rpx;">停车记录</text>
  5. <u-dropdown ref="filterDropdown">
  6. <u-dropdown-item v-model="selectedParkIdx" :title="selectedParkName" :options="myParkSites" @change="changePark">
  7. <!--
  8. <view class="slot-content dropdown-filter-con">
  9. <view class="filter-item">
  10. <text class="filter-label">出场日期</text>
  11. <view class="filter-date" @tap="showCalendar=true">
  12. <text>{{filter.endDate.length>0?(filter.startDate+' 至 '+filter.endDate):'请选择'}}</text>
  13. <u-icon name="search" style="margin:0rpx 20rpx;"></u-icon>
  14. </view>
  15. </view>
  16. <view class="filter-item">
  17. <text class="filter-label">停车场</text>
  18. <view class="filter-con">
  19. <view @tap="selectedParkVal='all'" class="filter-con-item" :class="{'selected-filter':selectedParkVal=='all'}" data-val="all">全部</view>
  20. <block v-for="(item,index) in myParkSites" :key="item.park_id">
  21. <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>
  22. </block>
  23. </view>
  24. </view>
  25. <view class="filter-item">
  26. <text class="filter-label">车牌号</text>
  27. <view style="background-color:#f2f5fa;height:72rpx;margin-top:15rpx;"><u-input type="text" v-model="filter.carNum" :border="false" placeholder="请输入车牌号" :custom-style="filterInputCss" :placeholder-style="filterInputCss.phstyle"/></view>
  28. </view>
  29. <view class="filter-btn">
  30. <view class="filter-btn-reset" @tap="resetFilter">重置</view>
  31. <view class="filter-btn-sure" @tap="sureFilter">确定</view>
  32. </view>
  33. </view>-->
  34. </u-dropdown-item>
  35. </u-dropdown>
  36. </u-navbar>
  37. <u-calendar v-model="showCalendar" mode="range" @change="changeCalendar"></u-calendar>
  38. <u-tabs :list="tablist" :is-scroll="false" :current="currentTab" @change="changeTab"></u-tabs>
  39. <!--已离场列表 start-->
  40. <view class="tab-con-wrap" v-show="currentTab==0">
  41. <view class="tab-con-header">
  42. <view style="display: flex;align-items: center;padding:10rpx 0rpx;">
  43. <u-icon name="calendar" size="48" color="#5555ff" style="margin:0rpx 40rpx;" @tap="showCalendar=true"></u-icon>
  44. <u-search shape="round" border-color="#72b2ff" placeholder="输入车牌号模糊查找" v-model="filter.carNum" @search="searchHandler('off')" @custom="searchHandler('off')"></u-search>
  45. </view>
  46. </view>
  47. <view class="tab-con-body">
  48. <scroll-view style="padding:20rpx;height:calc(100vh - 170px)" scroll-y="true" lower-threshold="0.5" @scrolltolower="scrollbtm('off')">
  49. <view class="tab-con-item" v-for="(item,index) in offPageData.records" :key="index">
  50. <view class="item-top">
  51. <u-image width="200rpx" height="160rpx" :src="item.car_img" border-radius="5rpx" @click="previewCarPhoto(item.car_img)"></u-image>
  52. <view class="item-top-right">
  53. <view style="margin-bottom: 10rpx;"><text>{{item.parking_name}}</text></view>
  54. <view class="top-right-con">
  55. <view>进场时间:{{item.in_parking_time}}</view>
  56. <view v-if="item.release_status=='1'">离场时间:{{item.out_parking_time}}</view>
  57. <view>停车时长:{{item.parking_time_txt}}</view>
  58. <view>离场方式:{{item.out_type_name}}</view>
  59. <view v-if="item.out_type=='3'">缴费金额:{{item.pay_amount?(item.pay_amount+'元'):''}}</view>
  60. </view>
  61. </view>
  62. </view>
  63. <view class="item-footer">
  64. <text class="car-num">{{item.car_num}}</text>
  65. <template v-if="item.out_type=='2'">
  66. <u-button type="warning" size="mini" style="margin:0rpx;" @tap="restoreManualOut(item)">还原手动出场</u-button>
  67. </template>
  68. </view>
  69. </view>
  70. <!-- <u-loadmore :status="loadMoreStat"/> -->
  71. <view v-show="offPageData.showMoreTip">
  72. <u-loadmore :status="offPageData.loadMoreStat" :load-text="loadMoreText"/>
  73. </view>
  74. </scroll-view>
  75. </view>
  76. </view>
  77. <!--已离场列表 end-->
  78. <!--未离场列表 start-->
  79. <view class="tab-con-wrap" v-show="currentTab==1">
  80. <view class="tab-con-header">
  81. <view style="display: flex;align-items: center;padding:10rpx 30rpx;">
  82. <u-search shape="round" border-color="#72b2ff" placeholder="输入车牌号模糊查找" v-model="filter.carNum" @search="searchHandler('in')" @custom="searchHandler('in')"></u-search>
  83. </view>
  84. </view>
  85. <view class="tab-con-body">
  86. <scroll-view style="padding:20rpx;height:calc(100vh - 340rpx)" scroll-y="true" lower-threshold="0.5" @scrolltolower="scrollbtm('in')">
  87. <view class="tab-con-item" v-for="(item,index) in inPageData.records" :key="index">
  88. <view class="item-top">
  89. <u-image width="200rpx" height="160rpx" :src="item.car_img" border-radius="5rpx" @click="previewCarPhoto(item.car_img)"></u-image>
  90. <view class="item-top-right">
  91. <view style="margin-bottom: 10rpx;"><text>{{item.parking_name}}</text></view>
  92. <view class="top-right-con">
  93. <view>进场时间:{{item.in_parking_time}}</view>
  94. <view v-if="item.release_status=='1'">离场时间:{{item.out_parking_time}}</view>
  95. <view>停车时长:{{item.parking_time_txt}}</view>
  96. </view>
  97. </view>
  98. </view>
  99. <view class="item-footer">
  100. <text class="car-num">{{item.car_num}}</text>
  101. <template v-if="item.mark_in">
  102. <u-tag text="已标记在场" type="success" />
  103. <u-button type="warning" size="mini" style="margin:0rpx;" @tap="cancelMarkCarIn(item.id)">取消标记</u-button>
  104. </template>
  105. <template v-else>
  106. <u-button type="primary" size="mini" style="margin:0rpx;" @tap="manualOut(item)">手动出场</u-button>
  107. <u-button type="warning" size="mini" style="margin:0rpx;" @tap="markCarIn(item.id)">标记在场</u-button>
  108. </template>
  109. </view>
  110. </view>
  111. <!-- <u-loadmore :status="loadMoreStat"/> -->
  112. <view v-show="inPageData.showMoreTip">
  113. <u-loadmore :status="inPageData.loadMoreStat" :load-text="loadMoreText"/>
  114. </view>
  115. </scroll-view>
  116. </view>
  117. </view>
  118. <!--未离场列表 end-->
  119. <!--已标记列表 start-->
  120. <view class="tab-con-wrap" v-show="currentTab==2">
  121. <view class="tab-con-header">
  122. <view style="display: flex;align-items: center;padding:10rpx 10rpx;">
  123. <u-button type="primary" size="medium" style="margin:0rpx 10rpx;padding:0rpx 30rpx;" @tap="batchOff" v-show="true">批量移出未标记车辆</u-button>
  124. <u-search shape="round" border-color="#72b2ff" placeholder="输入车牌号模糊查找" v-model="filter.carNum" @search="searchHandler('marked')" @custom="searchHandler('marked')"></u-search>
  125. </view>
  126. </view>
  127. <view class="tab-con-body">
  128. <scroll-view style="padding:20rpx;height:calc(100vh - 340rpx);" scroll-y="true" lower-threshold="0.5" @scrolltolower="scrollbtm('marked')">
  129. <view class="tab-con-item" v-for="(item,index) in markedPageData.records" :key="index">
  130. <view class="item-top">
  131. <u-image width="200rpx" height="160rpx" :src="item.car_img" border-radius="5rpx" @click="previewCarPhoto(item.car_img)"></u-image>
  132. <view class="item-top-right">
  133. <view style="margin-bottom: 10rpx;"><text>{{item.parking_name}}</text></view>
  134. <view class="top-right-con">
  135. <view>进场时间:{{item.in_parking_time}}</view>
  136. <view>停车时长:{{item.parking_time_txt}}</view>
  137. </view>
  138. </view>
  139. </view>
  140. <view class="item-footer">
  141. <text class="car-num">{{item.car_num}}</text>
  142. <u-tag text="已标记在场" type="success" />
  143. <u-button type="warning" size="mini" style="margin:0rpx;" @tap="cancelMarkCarIn(item.id)">取消标记</u-button>
  144. </view>
  145. </view>
  146. <view v-show="markedPageData.showMoreTip">
  147. <u-loadmore :status="markedPageData.loadMoreStat" :load-text="loadMoreText"/>
  148. </view>
  149. </scroll-view>
  150. </view>
  151. </view>
  152. <!--已标记列表 end-->
  153. </view>
  154. </template>
  155. <script>
  156. import * as api from '@/apis/parkinglog.js'
  157. import app from '@/utils/app.js'
  158. export default {
  159. data() {
  160. return {
  161. showCalendar:false,
  162. tablist:[
  163. {
  164. name:'今日已离场'
  165. },
  166. {
  167. name:'未离场'
  168. },
  169. {
  170. name:'已标记'
  171. }
  172. ],
  173. currentTab:0,
  174. loadMoreStat:'loadmore',
  175. showMoreTip:false,
  176. loadMoreText: {
  177. loadmore: '轻轻上拉',
  178. loading: '努力加载中',
  179. nomore: '实在没有了'
  180. },
  181. loadingMore:false,
  182. filter:{
  183. startDate:'',
  184. endDate:'',
  185. carNum:''
  186. },
  187. myParkSites:[],
  188. selectedParkVal:'all',
  189. allParkIds:'',
  190. selectedParkIdx:null,
  191. filterInputCss:{
  192. 'background-color':'#f2f5fa',
  193. 'padding-left':'10rpx',
  194. 'phstyle':'font-size:24rpx;'
  195. },
  196. pagedData:{},
  197. offPageData:{loadMoreStat:'loadmore',showMoreTip:false}, //已离场
  198. inPageData:{loadMoreStat:'loadmore',showMoreTip:false} ,//未离场
  199. markedPageData:{loadMoreStat:'loadmore',showMoreTip:false} //已标记
  200. }
  201. },
  202. onLoad(){
  203. this.loadMyParkSites()
  204. this.changePark()
  205. },
  206. onShow(){
  207. //this.loadPageData(this.getLoadParams(1),false,"in");
  208. //this.loadPageData(this.getLoadParams(1),false,"off");
  209. },
  210. computed:{
  211. selectedParkName(){
  212. let chk=this.myParkSites && this.selectedParkIdx!=null
  213. return chk ? this.myParkSites[this.selectedParkIdx].label:'选择停车场'
  214. }
  215. },
  216. methods: {
  217. getLoadParams(pnum){
  218. let selParkId=this.myParkSites[this.selectedParkIdx].park_id
  219. let status=this.currentTab==0?"off":"in"
  220. let {carNum,startDate:queryStart,endDate:queryEnd}=this.filter
  221. /*
  222. if(status=="off"){
  223. return {outType:'2',parkId:selParkId,status,carNum,queryStart,queryEnd,pageNum:pnum,pageSize:10}
  224. }
  225. else{
  226. return {parkId:selParkId,status,carNum,queryStart,queryEnd,pageNum:pnum,pageSize:10}
  227. }*/
  228. return {parkId:selParkId,status,carNum,queryStart,queryEnd,pageNum:pnum,pageSize:10}
  229. },
  230. checkHadMore(offType){
  231. let rst=null
  232. if(offType=="off"){
  233. rst=this.offPageData.pageNum<this.offPageData.pageCount;
  234. this.offPageData.showMoreTip=true;
  235. this.offPageData.loadMoreStat=rst?'loadmore':'nomore';
  236. }
  237. else if(offType=="in"){
  238. rst=this.inPageData.pageNum<this.inPageData.pageCount;
  239. this.inPageData.showMoreTip=true;
  240. this.inPageData.loadMoreStat=rst?'loadmore':'nomore';
  241. }
  242. else if(offType=="marked"){
  243. rst=this.markedPageData.pageNum<this.markedPageData.pageCount;
  244. this.markedPageData.showMoreTip=true;
  245. this.markedPageData.loadMoreStat=rst?'loadmore':'nomore';
  246. }
  247. return rst;
  248. },
  249. changePark(val){
  250. //console.log(val)
  251. //切换停车场时,清空之前的时间条件
  252. this.filter.startDate=null;
  253. this.filter.endDate=null;
  254. this.loadPageData(this.getLoadParams(1),false,"in");
  255. this.loadPageData(this.getLoadParams(1),false,"off");
  256. this.loadMarked(this.getLoadParams(1),false)
  257. },
  258. changeTab(idx){
  259. this.currentTab=idx;
  260. },
  261. searchHandler(type){
  262. //3个搜索框的搜索处理
  263. if(type=="off"){ //已离场
  264. this.loadPageData(this.getLoadParams(1),false,"off")
  265. }
  266. else if(type=="in"){
  267. this.loadPageData(this.getLoadParams(1),false,"in")
  268. }
  269. else if(type=="marked"){
  270. this.loadMarked(this.getLoadParams(1),false)
  271. }
  272. },
  273. changeCalendar(e){
  274. this.filter.startDate=e.startDate;
  275. this.filter.endDate=e.endDate;
  276. //日期查询目前只用于已离场
  277. this.loadPageData(this.getLoadParams(1),false,"off");
  278. },
  279. scrollbtm(offType){
  280. //console.log('scroll btm')
  281. //触底事件会反复触发,会导致同时发出多个相同请求,需要同步控制
  282. /*if(this.loadingMore){
  283. return;
  284. }
  285. this.loadingMore=true;
  286. */
  287. if(!this.checkHadMore(offType)){
  288. return;
  289. }
  290. let pnum=1;
  291. if(offType=="off" && this.offPageData.loadMoreStat!='loading'){
  292. this.offPageData.loadMoreStat='loading';
  293. pnum=this.offPageData.pageNum+1;
  294. this.loadPageData(this.getLoadParams(pnum),true,offType)
  295. }
  296. else if(offType=="in" && this.inPageData.loadMoreStat!='loading'){
  297. this.inPageData.loadMoreStat='loading';
  298. pnum=this.inPageData.pageNum+1;
  299. this.loadPageData(this.getLoadParams(pnum),true,offType)
  300. }
  301. else if(offType=="marked" && this.markedPageData.loadMoreStat!='loading'){
  302. this.markedPageData.loadMoreStat='loading';
  303. pnum=this.markedPageData.pageNum+1;
  304. this.loadMarked(this.getLoadParams(pnum),true)
  305. }
  306. },
  307. loadMyParkSites(){
  308. //本地缓存中获取停车场,需刷新首页才能更新
  309. let pks=api.getMyParkSites();
  310. if(!pks){
  311. return;
  312. }
  313. let ids=[];
  314. pks.forEach(function(item,index){
  315. ids.push(item.park_id);
  316. item['value']=index;
  317. item['label']=item.parking_name;
  318. });
  319. this.allParkIds=ids.join(",");
  320. this.myParkSites=pks;
  321. this.selectedParkIdx=0;
  322. },
  323. loadMarked(param,moreLoad){
  324. //加载已标记记录
  325. let offType='marked'
  326. if(!moreLoad){
  327. this.markedPageData.records=[] //避免加载失败后旧数据还在显示
  328. }
  329. uni.showLoading({
  330. title:'加载中...'
  331. });
  332. api.loadMarked(param).then(resp=>{
  333. uni.hideLoading()
  334. //console.log(resp)
  335. if(!resp.success){
  336. uni.showToast({
  337. title:resp.msg||'加载已标记数据失败',
  338. icon:'none'
  339. })
  340. return;
  341. }
  342. let pagedData=resp.data.pagedData
  343. this.parseDatas(pagedData);
  344. if(moreLoad && this.markedPageData && this.markedPageData.records){
  345. pagedData.records=this.markedPageData.records.concat(pagedData.records)
  346. }
  347. pagedData.showMoreTip=this.markedPageData.showMoreTip
  348. pagedData.loadMoreStat=this.markedPageData.loadMoreStat
  349. this.markedPageData=pagedData
  350. this.checkHadMore(offType);
  351. this.renderSortTab(pagedData,offType);
  352. }).catch(err=>{
  353. console.log(err)
  354. uni.hideLoading()
  355. uni.showToast({
  356. title:'加载已标记数据出错',
  357. icon:'none'
  358. })
  359. })
  360. },
  361. loadPageData(param,moreLoad,offType){
  362. uni.showLoading({
  363. title:'加载中...'
  364. });
  365. param.status=offType
  366. api.loadPageData(param).then(resp => {
  367. //console.log(resp)
  368. uni.hideLoading();
  369. if(!resp.success){
  370. uni.showToast({
  371. title:resp.msg||'加载数据失败',
  372. icon:'none'
  373. })
  374. return;
  375. }
  376. let pagedData=resp.data.pagedData;
  377. this.parseDatas(pagedData);
  378. if(offType=="off"){ //查询已离场数据结果
  379. if(moreLoad){
  380. pagedData.records=pagedData.records?this.offPageData.records.concat(pagedData.records):this.offPageData.records;
  381. }
  382. pagedData.showMoreTip=this.offPageData.showMoreTip
  383. pagedData.loadMoreStat=this.offPageData.loadMoreStat
  384. this.offPageData=pagedData
  385. }
  386. else{ //未离场
  387. if(moreLoad){
  388. pagedData.records=pagedData.records?this.inPageData.records.concat(pagedData.records):this.inPageData.records;
  389. }
  390. pagedData.showMoreTip=this.inPageData.showMoreTip
  391. pagedData.loadMoreStat=this.inPageData.loadMoreStat
  392. this.inPageData=pagedData
  393. }
  394. this.renderSortTab(pagedData,offType);
  395. this.checkHadMore(offType);
  396. }).catch(error => {
  397. console.log(error)
  398. uni.hideLoading();
  399. });
  400. },
  401. renderSortTab(pageMode,offType){ //rptData
  402. let [tab1,tab2,tab3]=this.tablist
  403. if(offType=="off"){
  404. let tmpname=this.filter.startDate && this.filter.startDate!=''?'已离场':'今日已离场';
  405. tab1={name:`${tmpname}(${pageMode.total!=null?pageMode.total:0})`}
  406. }
  407. else if(offType=="in"){
  408. tab2={name:`未离场(${pageMode.total!=null?pageMode.total:0})`}
  409. }
  410. else if(offType=="marked"){
  411. tab3={name:`已标记(${pageMode.total!=null?pageMode.total:0})`}
  412. }
  413. this.tablist=[tab1,tab2,tab3]
  414. },
  415. parseDatas(respData){
  416. respData['pageNum']=respData.current;
  417. respData['pageCount']=respData.pages;
  418. respData['pageSize']=respData.size;
  419. let outTypeOpt={'1':'手动抬杆','2':'手动移出','3':'缴费离场','4':'VIP会员'}
  420. let datas=respData.records;
  421. let tmp=null,pkh=null;
  422. datas.forEach((item) => {
  423. tmp=item.release_status=='0'?item.cal_parking_time:item.parking_time;
  424. tmp=!tmp?0:tmp;
  425. pkh=Math.floor(tmp/60);
  426. item['parking_time_txt']=pkh>0?(pkh.toFixed(0)+"小时"+(tmp-pkh*60)+"分钟"):(tmp+"分钟");
  427. item['car_img']=item.release_status=='0'?item.in_image:item.out_image;
  428. if(!item['car_img']){
  429. item['car_img']='../../static/img/def_car.png';
  430. }
  431. item['out_type_name']=outTypeOpt[item['out_type']] || '';
  432. item['pay_amount']=item['pay_amount']?item['pay_amount'].toFixed(2):null;
  433. //item['out_type']=='3' &&
  434. });
  435. },
  436. previewCarPhoto(img){
  437. let array = [];
  438. array.push(img);
  439. uni.previewImage({
  440. urls: array,
  441. current: array[0]
  442. });
  443. },
  444. manualOut(record){
  445. let con=`确定要对车辆【${record.car_num}](停车${record.parking_time_txt})进行手动出场吗?`;
  446. uni.showModal({
  447. title:'手动出场确认',
  448. content:con,
  449. success:(res)=>{
  450. if (res.confirm) {
  451. this.manualOutSubmit(record.id)
  452. } else if (res.cancel) {
  453. console.log('用户取消手动出场');
  454. }
  455. }
  456. })
  457. },
  458. manualOutSubmit(recordId){
  459. api.manualOut(recordId,app.takeSetting('user_id')).then(resp=>{
  460. if(!resp.success){
  461. uni.showToast({
  462. title:resp.msg||'手动出场失败',
  463. icon:'none'
  464. })
  465. return;
  466. }
  467. uni.showToast({
  468. title:'操作成功',
  469. icon:'success'
  470. })
  471. //避免成功提示跳过
  472. setTimeout(()=>{
  473. //let pn=this.inPageData.pageNum
  474. this.loadPageData(this.getLoadParams(1),false,'in') //刷新当前页
  475. this.loadPageData(this.getLoadParams(1),false,'off')
  476. },1000)
  477. }).catch(err=>{
  478. console.log(err)
  479. uni.showToast({
  480. title:'手动出场出错',
  481. icon:'none'
  482. })
  483. })
  484. },
  485. markCarIn(recordId){
  486. api.markCarIn(recordId,app.takeSetting('user_id')).then(resp=>{
  487. if(!resp.success){
  488. uni.showToast({
  489. title:resp.msg||'标记车辆失败',
  490. icon:'none'
  491. })
  492. return;
  493. }
  494. uni.showToast({
  495. title:'标记成功',
  496. icon:'success'
  497. })
  498. setTimeout(()=>{
  499. //let pn=this.inPageData.pageNum
  500. this.loadPageData(this.getLoadParams(1),false,'in')
  501. this.loadMarked(this.getLoadParams(1),false)
  502. },1000)
  503. }).catch(err=>{
  504. uni.showToast({
  505. title:'标记车辆出错',
  506. icon:'none'
  507. })
  508. })
  509. },
  510. cancelMarkCarIn(recordId){
  511. api.cancelMarkCarIn(recordId,app.takeSetting('user_id')).then(resp=>{
  512. if(!resp.success){
  513. uni.showToast({
  514. title:resp.msg||'取消标记失败',
  515. icon:'none'
  516. })
  517. return;
  518. }
  519. uni.showToast({
  520. title:'取消标记成功',
  521. icon:'success'
  522. })
  523. setTimeout(()=>{
  524. //let pn=this.inPageData.pageNum
  525. this.loadPageData(this.getLoadParams(1),false,'in')
  526. this.loadMarked(this.getLoadParams(1),false)
  527. },1000)
  528. }).catch(err=>{
  529. uni.showToast({
  530. title:'取消标记出错',
  531. icon:'none'
  532. })
  533. })
  534. },
  535. batchOff(){
  536. let markedCount=this.markedPageData ? this.markedPageData.total :0
  537. if(markedCount<=0){
  538. uni.showToast({
  539. title:'还未标记任何车辆',
  540. icon:'none'
  541. })
  542. return
  543. }
  544. let selPark=this.myParkSites?this.myParkSites[this.selectedParkIdx]:null
  545. if(!selPark){
  546. uni.showToast({
  547. title:'还未选择停车场',
  548. icon:'none'
  549. })
  550. return
  551. }
  552. if(this.markedPageData.records[0].park_id != selPark.park_id){
  553. uni.showModal({
  554. title:'操作提示',
  555. content:'标记车辆所在停车场与选择的停车场不一致',
  556. showCancel:false
  557. })
  558. return
  559. }
  560. uni.showModal({
  561. title:'未标记车辆出场确认',
  562. content:`请确认信息:停车场【${selPark.parking_name}】,已完成标记数【${markedCount}】,未标记表示车辆实际已不在场内,将被移出并更新状态`,
  563. showCancel:true,
  564. success:(res)=>{
  565. if (res.confirm) {
  566. this.batchOffSubmit(selPark.park_id);
  567. } else if (res.cancel) {
  568. console.log('用户点击取消');
  569. }
  570. }
  571. })
  572. },
  573. batchOffSubmit(parkId){
  574. uni.showLoading({
  575. title:'处理中...',
  576. mask:true
  577. });
  578. api.batchOffUnmarked(parkId).then(resp=>{
  579. uni.hideLoading()
  580. if(!resp.success){
  581. uni.showToast({
  582. title:resp.msg||'批量出场失败',
  583. icon:'none'
  584. })
  585. return;
  586. }
  587. uni.showToast({
  588. title:'批量出场成功',
  589. icon:'success'
  590. })
  591. setTimeout(()=>{
  592. this.changePark()
  593. },1000)
  594. }).catch(err=>{
  595. uni.hideLoading()
  596. console.log(err)
  597. uni.showToast({
  598. title:'批量出场失败',
  599. icon:'none'
  600. })
  601. })
  602. },
  603. restoreManualOut(record){
  604. let con=`确定要对车辆【${record.car_num}](停车${record.parking_time_txt})还原手动出场吗?`;
  605. uni.showModal({
  606. title:'还原手动出场确认',
  607. content:con,
  608. showCancel:true,
  609. success:(res)=>{
  610. if (res.confirm) {
  611. this.restoreManualOutSubmit(record.id);
  612. } else if (res.cancel) {
  613. console.log('用户点击取消');
  614. }
  615. }
  616. })
  617. },
  618. restoreManualOutSubmit(parkingLogId){
  619. uni.showLoading({
  620. title:'处理中...',
  621. mask:true
  622. });
  623. api.restoreManualOut(parkingLogId,app.takeSetting('user_id')).then(resp=>{
  624. uni.hideLoading()
  625. if(!resp.success){
  626. uni.showToast({
  627. title:resp.msg||'还原手动出场失败',
  628. icon:'none'
  629. })
  630. return;
  631. }
  632. uni.showToast({
  633. title:'还原手动出场成功',
  634. icon:'success'
  635. })
  636. setTimeout(()=>{
  637. this.loadPageData(this.getLoadParams(1),false,'off')
  638. this.loadPageData(this.getLoadParams(1),false,'in')
  639. },1000)
  640. }).catch(err=>{
  641. uni.hideLoading()
  642. uni.showToast({
  643. title:'还原手动出场出错',
  644. icon:'none'
  645. })
  646. })
  647. }
  648. }
  649. }
  650. </script>
  651. <style>
  652. page{
  653. background-color: #f4f4f4;
  654. overflow: hidden;
  655. }
  656. .top-navbar/deep/ .u-slot-content{
  657. justify-content: space-between;
  658. padding:0rpx;
  659. }
  660. .top-navbar/deep/ .u-dropdown__menu{
  661. justify-content: flex-end;
  662. }
  663. .top-navbar/deep/ .u-dropdown__menu .u-dropdown__menu__item{
  664. flex:none;
  665. margin-right: 40rpx;
  666. }
  667. .top-navbar/deep/ .u-dropdown__menu__item__text{
  668. color:#0055ff !important;
  669. }
  670. .top-navbar{
  671. font-size:28rpx;
  672. }
  673. uni-scroll-view{
  674. box-sizing: border-box;
  675. }
  676. .tab-con-item{
  677. background-color: #ffffff;
  678. border-radius: 10rpx;
  679. padding:20rpx;
  680. margin-bottom: 20rpx;
  681. }
  682. .tab-con-item .item-top{
  683. padding:0rpx;
  684. display: flex;
  685. flex-flow: row nowrap;
  686. justify-content:flex-start;
  687. align-items: center;
  688. margin-bottom: 10rpx;
  689. }
  690. .tab-con-item .item-top-right{
  691. display: flex;
  692. flex-flow: column nowrap;
  693. justify-content:space-between;
  694. margin-left:20rpx;
  695. }
  696. .tab-con-item .item-top-right>text{
  697. color:#000000;
  698. margin-bottom:20rpx;
  699. }
  700. .tab-con-item .item-top-right .top-right-con{
  701. font-size:24rpx;
  702. }
  703. .tab-con-item .item-top-right .top-right-con>view{
  704. margin-bottom:10rpx;
  705. }
  706. .tab-con-item .item-footer{
  707. display: flex;
  708. flex-flow: row nowrap;
  709. justify-content:space-between;
  710. align-items: center;
  711. font-size:24rpx;
  712. }
  713. .tab-con-item .item-footer .car-num{
  714. font-size:28rpx;
  715. font-weight: bold;
  716. }
  717. .tab-con-item .item-footer .item-footer-btn{
  718. padding:10rpx 15rpx;
  719. color:#ffffff;
  720. background-color: #185AC6;
  721. border-radius: 6rpx;
  722. }
  723. .dropdown-filter-con{
  724. display: flex;
  725. flex-direction: column;
  726. align-items: flex-start;
  727. justify-content: center;
  728. padding:20rpx 0rpx 0rpx;
  729. box-sizing: border-box;
  730. background-color: #fafafa;
  731. font-size: 26rpx;
  732. }
  733. .filter-item{
  734. width:100%;
  735. padding:0rpx 20rpx 30rpx;
  736. }
  737. .filter-item .filter-label{
  738. /* font-family: '楷体'; */
  739. }
  740. .filter-item .uni-input-wrapper{
  741. background-color: #f2f5fa;
  742. }
  743. .filter-date{
  744. width:100%;
  745. height:72rpx;
  746. line-height: 55rpx;
  747. background-color: #f2f5fa;
  748. margin-top: 20rpx;
  749. display: flex;
  750. align-items:center;
  751. padding-left:10rpx;
  752. }
  753. .filter-date text{
  754. flex:1;
  755. }
  756. .filter-con{
  757. display: flex;
  758. flex-flow: row wrap;
  759. justify-content:flex-start;
  760. align-items: center;
  761. margin-top: 20rpx;
  762. }
  763. .filter-con .filter-con-item{
  764. padding:10rpx 10rpx;
  765. text-align: center;
  766. background-color: #f2f5fa;
  767. /* color:#ffffff; */
  768. /* height: 45rpx; */
  769. width:28vw;
  770. margin-right: 3vw;
  771. margin-bottom: 20rpx;
  772. }
  773. .filter-con .selected-filter{
  774. background-color: #185ac6;
  775. color:#ffffff;
  776. }
  777. .filter-btn{
  778. display: flex;
  779. flex-flow: row wrap;
  780. justify-content:flex-start;
  781. align-items: center;
  782. height: 80rpx;
  783. width:100vw;
  784. border-top:1px solid #f2f2f2;
  785. }
  786. .filter-btn-reset{
  787. flex:1;
  788. text-align: center;
  789. line-height: 80rpx;
  790. background-color: #f2f2f2;
  791. }
  792. .filter-btn-sure{
  793. flex:2;
  794. text-align: center;
  795. background-color: #185ac6;
  796. color:#ffffff;
  797. line-height: 80rpx;
  798. }
  799. </style>