order.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. <template>
  2. <view>
  3. <view class="swiper-wrap">
  4. <view class="u-tabs-box">
  5. <u-tabs-swiper
  6. activeColor="#008CFF"
  7. ref="tabs"
  8. :list="list"
  9. :current="current"
  10. @change="change"
  11. :is-scroll="false"
  12. swiperWidth="100%"
  13. ></u-tabs-swiper>
  14. </view>
  15. <swiper class="swiper-box" :current="swiperCurrent" @transition="transition" @animationfinish="animationfinish">
  16. <swiper-item class="swiper-item" v-for="(item, index) in list" :key="index">
  17. <scroll-view scroll-y style="height: 100%; width: 100%" @scrolltolower="reachBottom">
  18. <view class="page-box">
  19. <view class="order" @click="goDetails(orderItem)" v-for="(orderItem, index) in orderList[current]" :key="'o-' + index">
  20. <view class="order-top u-flex">
  21. <view class="order-top-left u-flex-1">
  22. <view class="car">{{ orderItem.vehicleNo }}</view>
  23. <view class="addr">{{ orderItem.roadName }}</view>
  24. </view>
  25. <!--
  26. 显示申请退款按钮满足一下条件:
  27. 1.允许退款allowRefund等于1 并且
  28. 2.退款状态auditStatus等于2 已驳回 或者
  29. 3.退款状态auditStatus不能为空 并且不能等于0
  30. -->
  31. <view
  32. class="order-top-right apply-refund"
  33. v-show="orderItem.allowRefund == 1 && (orderItem.auditStatus == 2 || (!orderItem.auditStatus && orderItem.auditStatus != 0))"
  34. @click.stop="applyRefund(orderItem)"
  35. >申请退款</view
  36. >
  37. <!--
  38. 显示申请状态满足以下条件
  39. 申请状态存在或者审核状态存在(由于0比较特殊,所以单独拉出来判断)
  40. -->
  41. <view
  42. class="order-top-right apply-refund"
  43. @click.stop="applyRefundDetails(orderItem)"
  44. v-if="orderItem.refundStatus || orderItem.refundStatus == 0 || orderItem.auditStatus || orderItem.auditStatus == 0"
  45. >{{ orderItem | verifyRefundStatus }}</view
  46. >
  47. <view class="order-top-right" v-else :class="{ 'order-top-right-finished': orderItem.orderStatus == '4' }">
  48. {{ orderItem.orderStatus | verifyStatusFilter }}
  49. </view>
  50. </view>
  51. <!-- 路段显示字段 -->
  52. <view class="order-center" v-if="typeCurrent.value === 'road'">
  53. <view class="order-center-item">订单编号:{{ orderItem.orderId }}</view>
  54. <!-- <view class="order-center-item">入场时间:{{ orderItem.inTime }}</view> -->
  55. <view class="order-center-item" v-if="orderItem.deviceType == 1"> 入场时间:{{ orderItem.inTime }}</view>
  56. <view class="order-center-item" v-else>开始计费:{{ orderItem.inTime }}</view>
  57. <template v-if="orderItem.deviceType == 1">
  58. <view class="order-center-item" v-if="orderItem.orderStatus == 1 && orderItem.outTime"> 出场时间:{{ `未出场` }}</view>
  59. <view class="order-center-item" v-if="orderItem.orderStatus !== 1"> 出场时间:{{ orderItem.outTime }}</view>
  60. </template>
  61. <template v-else>
  62. <view class="order-center-item" v-if="orderItem.orderStatus == 1 && orderItem.outTime"> 结束计费:{{ `未出场` }}</view>
  63. <view class="order-center-item" v-if="orderItem.orderStatus !== 1"> 结束计费:{{ orderItem.outTime }}</view>
  64. </template>
  65. <!-- <view class="order-center-item">
  66. 停车时长:{{ orderItem.duration || 0 }}</view> -->
  67. <!-- <view class="order-center-item" v-if="orderItem.orderStatus !== 1">
  68. 免费时长:{{ orderItem.freeDuration || 0 }}</view> -->
  69. <view class="order-center-item" v-if="orderItem.deviceType == 1"> 免费时长:{{ orderItem.freeDuration || `0天0时${free_time}分0秒` }}</view>
  70. <!-- <view class="order-center-item" v-if="orderItem.deviceType == 2">
  71. 免费时长:0天0时15分0秒</view> -->
  72. <view class="order-center-item" v-if="orderItem.deviceType == 2">
  73. 免费时长:{{ orderItem.freeDuration || `0天0时${free_time}分0秒` }}</view
  74. >
  75. <!-- <view class="order-center-item" v-if="orderItem.orderStatus !== 1">
  76. 计费时长:{{ orderItem.calcDuration || 0 }}</view> -->
  77. <view class="order-center-item"> 计费时长:{{ orderItem.calcDuration || 0 }}</view>
  78. <view class="order-center-item"> 累计停车时长:{{ orderItem.duration || 0 }}</view>
  79. <view class="order-center-item" v-if="orderItem.orderStatus == 1">
  80. 预计金额:
  81. <span class="pay-amount">{{ orderItem.payAmount || 0 }}</span>
  82. </view>
  83. <view class="order-center-item" v-else>
  84. 应付金额:
  85. <span class="pay-amount">{{ orderItem.payAmount || 0 }}</span>
  86. </view>
  87. <view
  88. class="order-center-item"
  89. v-if="(orderItem.actualAmount || orderItem.actualAmount === 0) && orderItem.orderStatus !== 2 && orderItem.orderStatus !== 1"
  90. >
  91. 实缴金额:
  92. <span class="pay-amount">{{ orderItem.actualAmount || 0 }}</span>
  93. </view>
  94. <view class="order-center-item">泊位号:{{ orderItem.spaceName }}</view>
  95. <view class="order-center-item" v-if="Number(orderItem.deviceType) !== 1"> 车位锁设备号:{{ orderItem.deviceNo }}</view>
  96. </view>
  97. <!-- 停车场显示字段 -->
  98. <view class="order-center" v-if="typeCurrent.value === 'park'">
  99. <view class="order-center-item">订单编号:{{ orderItem.orderId }}</view>
  100. <view class="order-center-item"> 入场通道:{{ orderItem.roadwayName }}</view>
  101. <view class="order-center-item"> 入场时间:{{ orderItem.inTime }}</view>
  102. <view class="order-center-item" v-if="orderItem.orderStatus == 1 && orderItem.outTime"> 出场通道:{{ `未出场` }}</view>
  103. <view class="order-center-item" v-if="orderItem.orderStatus !== 1"> 出场通道:{{ orderItem.outParkingName }}</view>
  104. <view class="order-center-item" v-if="orderItem.orderStatus !== 1"> 出场时间:{{ orderItem.inTime }}</view>
  105. <view class="order-center-item"> 免费时长:{{ orderItem.freeDuration || `0天0时${free_time}分0秒` }}</view>
  106. <view class="order-center-item"> 计费时长:{{ orderItem.calcDuration || 0 }}</view>
  107. <view class="order-center-item"> 累计停车时长:{{ orderItem.duration || 0 }}</view>
  108. <view class="order-center-item">
  109. 应缴金额:
  110. <span class="pay-amount">{{ orderItem.payAmount || 0 }}</span>
  111. </view>
  112. <view
  113. class="order-center-item"
  114. v-if="(orderItem.actualAmount || orderItem.actualAmount === 0) && orderItem.orderStatus !== 2 && orderItem.orderStatus !== 1"
  115. >
  116. 实缴金额:
  117. <span class="pay-amount">{{ orderItem.actualAmount || 0 }}</span>
  118. </view>
  119. </view>
  120. <view class="order-bottom">
  121. <u-cell-item title="收费标准" @click.native.stop="jumpChargeStandard(orderItem)"> </u-cell-item>
  122. </view>
  123. </view>
  124. <u-loadmore :status="loadStatus[index]" bg-color="#F6F6FF"></u-loadmore>
  125. </view>
  126. </scroll-view>
  127. </swiper-item>
  128. </swiper>
  129. </view>
  130. <!-- 停车场和路段切换 -->
  131. <view class="type-list">
  132. <view
  133. class="type-list-item"
  134. v-for="(item, index) in typeList"
  135. :key="index"
  136. :class="{ 'type-list-item-current': typeCurrent.value === item.value }"
  137. @click="typeTabClick(item)"
  138. >
  139. {{ item.label }}
  140. </view>
  141. </view>
  142. <u-toast ref="uToast" />
  143. </view>
  144. </template>
  145. <script>
  146. // 订单状态orderStatus: 1-停放中 2-出场中 3-欠费 4-完成
  147. export default {
  148. data() {
  149. return {
  150. orderList: [[], [], [], []],
  151. list: [
  152. {
  153. index: 0,
  154. name: '全部',
  155. orderStatus: null,
  156. pageNum: 1,
  157. total: null
  158. },
  159. {
  160. index: 1,
  161. name: '停放中',
  162. orderStatus: 1,
  163. pageNum: 1,
  164. total: null
  165. },
  166. {
  167. index: 2,
  168. name: '欠费未缴',
  169. orderStatus: 2,
  170. pageNum: 1,
  171. total: null
  172. },
  173. {
  174. index: 3,
  175. name: '已完成',
  176. orderStatus: 4,
  177. pageNum: 1,
  178. total: null
  179. }
  180. ],
  181. current: 0,
  182. swiperCurrent: 0,
  183. tabsHeight: 0,
  184. dx: 0,
  185. loadStatus: ['loadmore', 'loadmore', 'loadmore', 'loadmore'],
  186. // 停车类型
  187. typeList: [
  188. {
  189. label: '路段',
  190. value: 'road'
  191. },
  192. {
  193. label: '停车场',
  194. value: 'park'
  195. }
  196. ],
  197. typeCurrent: {
  198. //设置停车类型默认值
  199. label: '路段',
  200. value: 'road'
  201. }
  202. };
  203. },
  204. onShow() {},
  205. onLoad(options) {
  206. let questCurrent = options.orderStatus;
  207. if (questCurrent) {
  208. this.current = questCurrent;
  209. this.change(questCurrent);
  210. } else {
  211. this.list[this.current].pageNum = 1;
  212. this.orderList = [[], [], [], []];
  213. this.getOrderList(this.list[this.current], this.typeCurrent);
  214. }
  215. },
  216. computed: {
  217. // 价格小数
  218. priceDecimal() {
  219. return (val) => {
  220. if (val !== parseInt(val)) return val.slice(-2);
  221. else return '00';
  222. };
  223. },
  224. // 价格整数
  225. priceInt() {
  226. return (val) => {
  227. if (val !== parseInt(val)) return val.split('.')[0];
  228. else return val;
  229. };
  230. }
  231. },
  232. onBackPress(e) {
  233. // 返回主页面tabBar
  234. uni.switchTab({
  235. url: '../../center/index'
  236. });
  237. // 此处一定要return为true,否则页面不会返回到指定路径
  238. return true;
  239. },
  240. methods: {
  241. reachBottom() {
  242. if (this.orderList[this.current].length >= this.list[this.current].total) {
  243. this.loadStatus.splice(this.list[this.current].index, 1, 'nomore');
  244. return;
  245. }
  246. this.loadStatus.splice(this.list[this.current].index, 1, 'loading');
  247. this.getOrderList(this.list[this.current], this.typeCurrent);
  248. },
  249. // 页面数据
  250. getOrderList(orderType, typeCurrent) {
  251. //初始化订单列表
  252. const param = {
  253. pageNum: orderType.pageNum,
  254. orderStatus: orderType.orderStatus
  255. };
  256. // 未出场: orderStatus = 1-停放中
  257. // 缴费中: orderStatus = 2-出场中 && payStatus = 2-支付中
  258. // 完成: orderStatus = 4-完成
  259. if (typeCurrent.value == 'road') {
  260. this.$u.api
  261. .getOrderList(param)
  262. .then((res) => {
  263. for (const item of res.data.pageInfo.rows) {
  264. this.orderList[orderType.index].push(item);
  265. }
  266. this.list[this.current].total = res.data.pageInfo.total;
  267. this.list[orderType.index].pageNum++;
  268. if (this.orderList[this.current].length >= this.list[this.current].total) {
  269. this.loadStatus.splice(this.list[orderType.index].index, 1, 'nomore');
  270. }
  271. })
  272. .catch((err) => {
  273. this.$refs.uToast.show({
  274. title: err.msg,
  275. type: 'error'
  276. });
  277. });
  278. } else {
  279. this.$u.api
  280. .getRoomParkingApi(param)
  281. .then((res) => {
  282. for (const item of res.data.pageInfo.rows) {
  283. this.orderList[orderType.index].push(item);
  284. }
  285. this.list[this.current].total = res.data.pageInfo.total;
  286. this.list[orderType.index].pageNum++;
  287. if (this.orderList[this.current].length >= this.list[this.current].total) {
  288. this.loadStatus.splice(this.list[orderType.index].index, 1, 'nomore');
  289. }
  290. })
  291. .catch((err) => {
  292. this.$refs.uToast.show({
  293. title: err.msg,
  294. type: 'error'
  295. });
  296. });
  297. }
  298. this.loadStatus.splice(this.current, 1, 'loadmore');
  299. },
  300. // tab栏切换
  301. change(index) {
  302. this.swiperCurrent = index;
  303. //重新初始化
  304. this.orderList = [[], [], [], []];
  305. this.list[index].pageNum = 1;
  306. this.getOrderList(this.list[index], this.typeCurrent);
  307. },
  308. transition({ detail: { dx } }) {
  309. this.$refs.tabs.setDx(dx);
  310. },
  311. animationfinish({ detail: { current } }) {
  312. this.$refs.tabs.setFinishCurrent(current);
  313. this.swiperCurrent = current;
  314. this.current = current;
  315. },
  316. /**
  317. * 跳转详情
  318. * 未发起退款或者未退款成功的
  319. * */
  320. goDetails(item) {
  321. this.$u.route({
  322. url: 'pages/center/order/orderDetails/orderDetails',
  323. params: {
  324. orderId: item.id,
  325. orderType: this.typeCurrent.value
  326. }
  327. });
  328. },
  329. jumpChargeStandard(item) {
  330. let roadNo = item?.roadNo;
  331. if (this.typeCurrent.value === 'park') {
  332. roadNo = item?.parkingNo;
  333. }
  334. this.$u.route({
  335. url: 'pages/chargeStandard/chargeStandard',
  336. params: {
  337. roadNo
  338. }
  339. });
  340. },
  341. // 申请退款
  342. applyRefund(item) {
  343. this.$u.route('pages/applyRefund/applyRefund', {
  344. orderId: item.orderId,
  345. payAmount: item.actualAmount
  346. });
  347. },
  348. /**
  349. * 申请退款详情
  350. * 只要申请退款状态等于1并且审批状态等于1跳转到退款完成详情页
  351. * 否则跳转到退款过程页
  352. * */
  353. applyRefundDetails(item) {
  354. if (item.refundStatus === 1 && item.auditStatus === 1) {
  355. this.$u.route('pages/applyRefundDetails/applyRefundAchieveDetails', {
  356. orderId: item.orderId
  357. });
  358. } else {
  359. this.$u.route('pages/applyRefundDetails/applyRefundDetails', {
  360. orderId: item.orderId
  361. });
  362. }
  363. },
  364. /**
  365. * 类型切换
  366. * @param {Object} item
  367. */
  368. typeTabClick(item) {
  369. this.typeCurrent = item;
  370. //重新初始化
  371. this.orderList = [[], [], [], []];
  372. this.list[this.current].pageNum = 1;
  373. this.getOrderList(this.list[this.current], this.typeCurrent);
  374. }
  375. },
  376. filters: {
  377. verifyStatusFilter(value) {
  378. if (value === 0) {
  379. return '';
  380. } else if (value === 1) {
  381. return '停放中';
  382. } else if (value === 2) {
  383. return '欠费未缴';
  384. } else if (value === 4) {
  385. return '已完成';
  386. } else {
  387. return '';
  388. }
  389. },
  390. verifyRefundStatus(item) {
  391. if (item.auditStatus === 0) {
  392. return '申请退款中';
  393. } else if (item.auditStatus === 1) {
  394. if (item.refundStatus === 0) {
  395. return '退款失败';
  396. } else if (item.refundStatus === 1) {
  397. return '退款成功';
  398. }
  399. } else if (item.auditStatus === 2) {
  400. return '已驳回';
  401. }
  402. }
  403. }
  404. };
  405. </script>
  406. <style>
  407. /* #ifndef H5 */
  408. page {
  409. height: 100%;
  410. background-color: #f6f6ff;
  411. }
  412. /* #endif */
  413. </style>
  414. <style lang="scss" scoped>
  415. @import './order.scss';
  416. </style>