| | |
| | | <template> |
| | | <view> |
| | | |
| | | <view class="itinerary-page"> |
| | | <view class="top-fixed"> |
| | | <view class="top-gradient"></view> |
| | | <view class="top-inner"> |
| | | <view :style="{ height: statusbarHeight + 'px' }"></view> |
| | | <view class="header-bar" :style="{ height: navHeight + 'px' }"> |
| | | <text class="header-title">我的行程</text> |
| | | </view> |
| | | <scroll-view scroll-x class="tabs-row page-padding" style="padding: 0 0 0 30rpx !important;" show-scrollbar="false"> |
| | | <view class="tabs-inner"> |
| | | <view |
| | | v-for="item in filterTabs" |
| | | :key="item.value" |
| | | class="filter-tab" |
| | | :class="{ active: activeTab === item.value }" |
| | | @tap="activeTab = item.value" |
| | | > |
| | | {{ item.label }} |
| | | </view> |
| | | </view> |
| | | </scroll-view> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="content-wrap"> |
| | | <view class="page-padding card-list"> |
| | | <view v-for="(item, index) in dataList" :key="item.id" class="order-card"> |
| | | <view class="order-head" :class="item.mode === 'city' ? 'city-head-bg' : 'local-head-bg'"> |
| | | <view v-if="item.type === 0" class="head-local"> |
| | | <view class="mode-tag local-tag">就地寄存</view> |
| | | <view class="head-copy single-copy"> |
| | | <text class="head-name text-ellipsis">{{ item.depositShopName||'' }}</text> |
| | | <text class="head-user">{{ item.takeUser ||'' }}</text> |
| | | </view> |
| | | </view> |
| | | <view v-else class="head-city"> |
| | | <view class="head-copy city-left"> |
| | | <view class="mode-tag city-tag">同城寄送</view> |
| | | <text class="head-name text-ellipsis">{{ item.depositShopName || '' }}</text> |
| | | <text class="head-user">{{ item.takeUser||'' }}</text> |
| | | </view> |
| | | <view class="city-arrow"> |
| | | <view class="arrow-line"></view> |
| | | <view class="arrow-head"></view> |
| | | </view> |
| | | <view class="head-copy city-right align-right"> |
| | | <text class="status-text">{{ item.statusName||'待发货' }}</text> |
| | | <text class="head-name text-ellipsis">{{ item.takeShopName||'对对对' }}</text> |
| | | <text class="head-user">{{ item.takeUser||'' }}</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="goods-area" v-if="item.detailList"> |
| | | <view v-for="goods in item.detailList " :key="goods.luggageName" class="goods-row"> |
| | | <view class="goods-left"> |
| | | <text class="goods-name">{{ goods.luggageName ||'' }}</text> |
| | | <text class="goods-size">{{ goods.luggageDetail || '' }}</text> |
| | | </view> |
| | | <view class="goods-right"> |
| | | <text class="goods-price">{{((goods.subtotal || 0)/100).toFixed(2) }}</text> |
| | | <text class="goods-count">x{{ goods.num || 1}}</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view class="amount-area"> |
| | | <view class="pay-row"> |
| | | <text class="pay-label">实付款:</text> |
| | | <text class="pay-value">{{((item.estimatedAmount || 0)/100).toFixed(2) }}</text> |
| | | </view> |
| | | <view class="insurance-row"> |
| | | <text class="insurance-label">含行李保费:</text> |
| | | <text class="insurance-value">{{((item.declaredFee || 0)/100).toFixed(2) }}</text> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="card-footer"> |
| | | <view class="pickup-wrap" v-if="item.expectedTakeTime"> |
| | | <text class="pickup-label">预计取件时间:</text> |
| | | <text class="pickup-value">{{ item.expectedTakeTime ||'' }}</text> |
| | | </view> |
| | | <view class="pickup-wrap" v-else></view> |
| | | <view class="footer-actions"> |
| | | <!-- <view class="footer-btn contact-btn">联系门店</view> |
| | | --> <view class="footer-btn contact-btn" v-if="item.status ===0">取消订单</view> |
| | | <view class="footer-btn primary-btn" v-if="item.status ===0">立即支付</view> |
| | | <view class="footer-btn contact-btn" v-if="item.status ===1">联系门店</view> |
| | | <view class="footer-btn primary-btn" v-if="item.status ===1">申请退款</view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <view v-if="isLoadingMore" class="loading-text">加载中...</view> |
| | | <view v-else-if="!hasNext && dataList.length" class="loading-text">没有更多了</view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import { mapState } from 'vuex' |
| | | export default { |
| | | computed: { |
| | | ...mapState(['navHeight', 'statusbarHeight']) |
| | | }, |
| | | data() { |
| | | return { |
| | | activeTab: -1, |
| | | pageSize: 10, |
| | | currentPage: 1, |
| | | total:0, |
| | | hasNext:true, |
| | | userType: 0, |
| | | isLoadingMore: false, |
| | | filterTabs: [ |
| | | { label: '全部' ,value: -1}, |
| | | { label: '待支付',value: 0 }, |
| | | { label: '待核验', value: 1}, |
| | | { label: '待配送', value: 2 }, |
| | | { label: '待收货', value: 3}, |
| | | { label: '已完成', value: 4}, |
| | | { label: '已退款', value: 5} |
| | | ], |
| | | dataList: [] |
| | | } |
| | | }, |
| | | watch: { |
| | | activeTab() { |
| | | this.getFirstPageData() |
| | | } |
| | | }, |
| | | onLoad(options) { |
| | | console.log(options ) |
| | | this.activeTab = -1 |
| | | if (options.status) { |
| | | this.activeTab = Number(options.status) |
| | | } |
| | | this.getFirstPageData() |
| | | var that =this |
| | | uni.$on('updateOrder',function(data){ |
| | | console.log('监听到事件来自 update ,携带参数 msg 为:' ,data); |
| | | if(data.delete == 1){ |
| | | //删除订单,强制刷新数据 |
| | | that.getFirstPageData() |
| | | }else if(data.info!=null && data.info.orderId!=null){ |
| | | console.log('监听到事件来自 update 01:' ,data); |
| | | that.dataList.forEach((item,index)=>{ |
| | | if(item.id==data.info.orderId){ |
| | | console.log('监听到事件来自 update 02:' ,data); |
| | | item.status = data.info.orderStatus |
| | | } |
| | | }) |
| | | } |
| | | |
| | | }; |
| | | }) |
| | | }, |
| | | onShow() { |
| | | // this.showDone=false |
| | | // this.showCancel=false |
| | | // this.showDelete=false |
| | | // this.showQrcode=false |
| | | // this.showPay=false |
| | | // this.showPhone=false |
| | | this.loading=false, |
| | | this.currentOrder=null |
| | | }, |
| | | onReachBottom(){ |
| | | this.getDataList(); |
| | | }, |
| | | methods: { |
| | | getFirstPageData(){ |
| | | this.currentPage = 0 |
| | | this.hasNext=true |
| | | this.total=0 |
| | | this.dataList=[] |
| | | this.getDataList() |
| | | }, |
| | | async getDataList(){ |
| | | if(this.loading || !this.hasNext){ |
| | | return |
| | | } |
| | | this.loading=true |
| | | this.currentPage = this.currentPage+1 |
| | | if(this.currentPage == 1){ |
| | | this.hasNext =true |
| | | this.dataList=[] |
| | | } |
| | | var that =this |
| | | let res ={}; |
| | | res = await that.$u.api.myOrderPage({ |
| | | capacity:10, |
| | | model: { |
| | | combinedStatus: this.activeTab == -1?'':this.activeTab |
| | | }, |
| | | page:this.currentPage |
| | | }); |
| | | |
| | | console.log(res) |
| | | if (res.code === 200 ) { |
| | | if ( res.data && res.data.page ===this.currentPage) { |
| | | res.data.records = res.data.records||[] |
| | | that.dataList.push(...res.data.records) |
| | | that.total=res.data.total |
| | | if( this.currentPage >= res.data.pageCount||0){ |
| | | that.hasNext=false |
| | | }else{ |
| | | that.hasNext=true |
| | | } |
| | | } |
| | | } |
| | | this.loading=false |
| | | }, |
| | | jumpOrderDetail(id){ |
| | | uni.navigateTo({ |
| | | url:'/pages/details-entry/details-entry?userType='+this.userType+'&id='+id |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | <style lang="scss" scoped> |
| | | .itinerary-page { |
| | | min-height: 100vh; |
| | | background: #f7f7f7; |
| | | } |
| | | |
| | | </style> |
| | | .top-fixed { |
| | | position: sticky; |
| | | left: 0; |
| | | top: 0; |
| | | width: 100%; |
| | | z-index: 20; |
| | | } |
| | | |
| | | .top-gradient { |
| | | position: absolute; |
| | | left: 0; |
| | | top: 0; |
| | | width: 100%; |
| | | height: 100%; |
| | | background: linear-gradient(90deg, #1ba8fa 0%, #73e5cf 100%); |
| | | } |
| | | |
| | | .top-inner { |
| | | position: relative; |
| | | z-index: 1; |
| | | padding-bottom: 18rpx; |
| | | } |
| | | |
| | | .page-padding { |
| | | padding: 0 30rpx; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .header-bar { |
| | | padding: 0 30rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .header-title { |
| | | font-weight: 600; |
| | | font-size: 40rpx; |
| | | color: #FFFFFF; |
| | | } |
| | | |
| | | .tabs-row { |
| | | margin-top: 16rpx; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | .tabs-inner { |
| | | display: inline-flex; |
| | | align-items: center; |
| | | gap: 20rpx; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | .filter-tab { |
| | | flex-shrink: 0; |
| | | height: 50rpx; |
| | | padding: 0 20rpx; |
| | | border-radius: 25rpx; |
| | | background: #ffffff; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | font-size: 24rpx; |
| | | font-weight: 500; |
| | | color: #81858d; |
| | | } |
| | | |
| | | .filter-tab.active { |
| | | color: #19adf8; |
| | | } |
| | | |
| | | .content-wrap { |
| | | position: relative; |
| | | z-index: 1; |
| | | padding: 30rpx 0; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .order-card { |
| | | margin-bottom: 20rpx; |
| | | background: #ffffff; |
| | | border-radius: 14rpx; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .order-head { |
| | | padding: 24rpx 30rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .local-head-bg { |
| | | background: #eff9ff; |
| | | } |
| | | |
| | | .city-head-bg { |
| | | background: #fff4e8; |
| | | } |
| | | |
| | | .head-local, |
| | | .head-city { |
| | | flex: 1; |
| | | min-width: 0; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .head-copy { |
| | | min-width: 0; |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .single-copy, |
| | | .city-left, |
| | | .city-right { |
| | | flex: 1; |
| | | } |
| | | |
| | | .align-right { |
| | | align-items: flex-end; |
| | | text-align: right; |
| | | } |
| | | |
| | | .mode-tag { |
| | | width: 112rpx; |
| | | height: 38rpx; |
| | | border-radius: 8rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | font-weight: 400; |
| | | font-size: 24rpx; |
| | | color: #FFFFFF; |
| | | margin-right: 14rpx; |
| | | flex-shrink: 0; |
| | | } |
| | | |
| | | .local-tag { |
| | | background: linear-gradient(90deg, #18abf8 0%, #39c5ff 100%); |
| | | } |
| | | |
| | | .city-tag { |
| | | background: linear-gradient(90deg, #ff8b28 0%, #ffb14f 100%); |
| | | margin-right: 0; |
| | | margin-bottom: 8rpx; |
| | | } |
| | | |
| | | .head-name { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | font-weight: 600; |
| | | font-size: 30rpx; |
| | | color: #222222; |
| | | margin-top: 20rpx; |
| | | } |
| | | |
| | | .head-user { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | margin-top: 10rpx; |
| | | font-weight: 400; |
| | | font-size: 24rpx; |
| | | color: #666666; |
| | | } |
| | | |
| | | .text-ellipsis { |
| | | white-space: nowrap; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | } |
| | | |
| | | .city-arrow { |
| | | width: 82rpx; |
| | | margin: 0 54rpx; |
| | | position: relative; |
| | | height: 24rpx; |
| | | flex-shrink: 0; |
| | | } |
| | | |
| | | .arrow-line { |
| | | position: absolute; |
| | | left: 8rpx; |
| | | top: 8rpx; |
| | | width: 42rpx; |
| | | height: 0; |
| | | border-top: 3rpx solid #ff8c1f; |
| | | } |
| | | |
| | | .arrow-head { |
| | | position: absolute; |
| | | right: 8rpx; |
| | | top: 3rpx; |
| | | width: 12rpx; |
| | | height: 12rpx; |
| | | border-top: 3rpx solid #ff8c1f; |
| | | border-right: 3rpx solid #ff8c1f; |
| | | transform: rotate(45deg); |
| | | } |
| | | |
| | | .status-text { |
| | | font-weight: 400; |
| | | font-size: 26rpx; |
| | | color: #10B2FA; |
| | | flex-shrink: 0; |
| | | } |
| | | |
| | | .goods-area { |
| | | padding: 22rpx 30rpx; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .goods-row { |
| | | display: flex; |
| | | align-items: flex-start; |
| | | justify-content: space-between; |
| | | margin-bottom: 26rpx; |
| | | &:last-child { |
| | | margin: 0 !important; |
| | | } |
| | | } |
| | | |
| | | .goods-left { |
| | | flex: 1; |
| | | min-width: 0; |
| | | } |
| | | |
| | | .goods-name { |
| | | display: block; |
| | | font-weight: 600; |
| | | font-size: 28rpx; |
| | | color: #333333; |
| | | } |
| | | |
| | | .goods-size { |
| | | display: block; |
| | | margin-top: 12rpx; |
| | | font-weight: 400; |
| | | font-size: 24rpx; |
| | | color: #8C939F; |
| | | } |
| | | |
| | | .goods-right { |
| | | width: 92rpx; |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: flex-end; |
| | | } |
| | | |
| | | .goods-price { |
| | | font-weight: 400; |
| | | font-size: 30rpx; |
| | | color: #333333; |
| | | } |
| | | |
| | | .goods-count { |
| | | margin-top: 12rpx; |
| | | font-weight: 400; |
| | | font-size: 24rpx; |
| | | color: #8C939F; |
| | | } |
| | | |
| | | .amount-area { |
| | | padding: 0 30rpx; |
| | | box-sizing: border-box; |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: flex-end; |
| | | } |
| | | |
| | | .pay-row, |
| | | .insurance-row { |
| | | display: flex; |
| | | align-items: baseline; |
| | | } |
| | | |
| | | .pay-label, |
| | | .insurance-label { |
| | | font-weight: 400; |
| | | font-size: 26rpx; |
| | | color: #333333; |
| | | } |
| | | |
| | | .pay-value { |
| | | font-weight: 600; |
| | | font-size: 26rpx; |
| | | color: #222222; |
| | | } |
| | | |
| | | .insurance-row { |
| | | margin-top: 12rpx; |
| | | } |
| | | |
| | | .insurance-value { |
| | | font-size: 20rpx; |
| | | color: #999999; |
| | | } |
| | | |
| | | .card-footer { |
| | | padding: 0 30rpx 30rpx 30rpx; |
| | | box-sizing: border-box; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | margin-top: 30rpx; |
| | | } |
| | | |
| | | .pickup-wrap { |
| | | display: flex; |
| | | align-items: flex-start; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .pickup-label { |
| | | font-weight: 400; |
| | | font-size: 26rpx; |
| | | color: #333333; |
| | | } |
| | | |
| | | .pickup-value { |
| | | font-weight: 400; |
| | | font-size: 26rpx; |
| | | color: #10B2FA; |
| | | } |
| | | |
| | | .footer-actions { |
| | | margin-left: auto; |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 10rpx; |
| | | margin: 0 !important; |
| | | } |
| | | |
| | | .footer-btn { |
| | | height: 64rpx; |
| | | border-radius: 34rpx; |
| | | padding: 0 18rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | font-size: 28rpx; |
| | | box-sizing: border-box; |
| | | margin-right: 20rpx; |
| | | &:last-child { |
| | | margin: 0 !important; |
| | | } |
| | | } |
| | | |
| | | .contact-btn { |
| | | border: 1rpx solid #B2B2B2; |
| | | background: #ffffff; |
| | | color: #666666; |
| | | } |
| | | |
| | | .primary-btn { |
| | | background: #10B2FA; |
| | | color: #ffffff; |
| | | } |
| | | |
| | | .loading-text { |
| | | padding: 18rpx 0 8rpx; |
| | | text-align: center; |
| | | font-size: 22rpx; |
| | | color: #a5aab3; |
| | | } |
| | | </style> |