MrShi
2026-04-22 82f707ece09a906007f3d760b6bb025896e3bba6
small-program/pages/itinerary/itinerary.vue
@@ -33,7 +33,10 @@
                        <text class="head-name text-ellipsis">{{ item.depositShopName||'' }}</text>
                        <text class="head-user">{{ item.takeUser ||'' }}</text>
                     </view>
                  </view>
                     <text v-if="item.status < 7" class=" status-text status-orange">{{ item.statusName||'' }}</text>
                     <text v-else-if="item.status ===7" class=" status-text">{{ item.statusName||'' }}</text>
                     <text v-else-if="item.status >7" class=" status-text status-grey">{{ item.statusName||'' }}</text>
                  </view>
                  <view v-else class="head-city">
                     <view class="head-copy city-left">
                        <view class="mode-tag city-tag">同城寄送</view>
@@ -45,7 +48,9 @@
                        <view class="arrow-head"></view>
                     </view>
                     <view class="head-copy city-right align-right">
                        <text class="status-text">{{ item.statusName||'待发货' }}</text>
                        <text v-if="item.status < 7" class=" status-text status-orange">{{ item.statusName||'' }}</text>
                        <text v-else-if="item.status ===7" class="status-text">{{ item.statusName||'' }}</text>
                        <text v-else-if="item.status >7" class=" status-text status-grey">{{ item.statusName||'' }}</text>
                        <text class="head-name text-ellipsis">{{ item.takeShopName||'对对对' }}</text>
                        <text class="head-user">{{ item.takeUser||'' }}</text>
                     </view>
@@ -64,60 +69,162 @@
                     </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="price-line" >
                  <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 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>
               <view class="card-footer">
                  <view class="footer-actions" v-if="item.type===0">
                     <view class="footer-btn contact-btn" @click="contactPhone(item,0)" v-if="item.status ===1 || item.status==2 || item.status===98">联系门店</view>
                      <view class="footer-btn contact-btn" v-if="item.status ===0 || item.status ===1"  @click="cancelOrder(item)">取消订单</view>
                     <view class="footer-btn contact-btn" @click="deleteOrder(item)" v-if="item.status ===7 || item.status===96 || item.status == 99">删除订单</view>
                     <view class="footer-btn primary-btn"  @click="payOrder(item)" v-if="item.status ===0">立即支付</view>
                     <view class="footer-btn primary-btn" v-if="item.status >=1 &&item.status <7 " @click="openQrcode(item)" >核销码</view>
                     <view class="footer-btn primary-btn" v-if="item.status ===7 && !commentStatus ">评价订单</view>
                  </view>
                  <view class="footer-actions" v-else>
                     <view class="footer-btn contact-btn" @click="contactPhone(item,0)" v-if="item.status ===1 || item.status ==2">联系门店</view>
                     <view class="footer-btn contact-btn" @click="contactPhone(item,2)" v-if="item.status ===3 || item.status ===4 ">联系骑手</view>
                     <view class="footer-btn contact-btn" @click="contactPhone(item,1)" v-if="item.status ===5">联系门店</view>
                        <view class="footer-btn contact-btn" v-if="item.status ===0"  @click="cancelOrder(item)">取消订单</view>
                        <view class="footer-btn primary-btn" @click="payOrder(item)" v-if="item.status ===0">立即支付</view>
                     <view class="footer-btn contact-btn" @click="deleteOrder(item)" v-if="item.status ===7 || item.status===96 || item.status == 99">删除订单</view>
                     <view class="footer-btn primary-btn" @click="cancelOrder(item)" v-if="item.status ===1">申请退款</view>
                     <view class="footer-btn primary-btn" v-if="item.status ===1 || (item.takeShopId && item.status ===5)" @click="openQrcode(item)" >核销码</view>
                     <view class="footer-btn primary-btn"  @click="doneOrder(item)"  v-if="!item.takeShopId && item.status ===5">确认收货</view>
                     <view class="footer-btn primary-btn" v-if="item.status ===7 && !commentStatus ">评价订单</view>
                  </view>
               </view>
            </view>
            <view v-if="isLoadingMore" class="loading-text">加载中...</view>
            <view v-else-if="!hasNext && dataList.length" class="loading-text">没有更多了</view>
            <view v-else-if="!hasNext && !dataList.length" class="loading-text">暂无数据</view>
         </view>
      </view>
      <custom-tabbar></custom-tabbar>
      <u-popup :show="showPhone" round="15" mode="bottom" :safeAreaInsetBottom="true"  @close="contactPhone()" :closeable="true" :closeOnClickOverlay="true">
         <view class="phone">
            <view class="phone-head">
               <view></view>
               <text>联系客户</text>
            </view>
            <!-- <view class="phone-item">
               <view>
                  <image style="width: 36rpx;height: 36rpx" src="/static/icon/ic_kefu.png" mode="widthFix"></image>
                  <button open-type="contact" plain="true" bindcontact="handleContact">在线客服</button>
               </view>
                <view class="line" v-if="serverPhone && serverPhone.length"></view>
            </view> -->
             <view class="phone-item" >
                <view>
                  <image src="/static/icon/ic_call@2x.png" mode="widthFix" @click="contactPhoneDo()" ></image>
                  <text>{{linkItem.linkname||''}} </text>
                  <text style="margin-left: 10px;"> {{linkItem.linkphone||''}}</text>
               </view>
             </view>
             <view style="width: 100%; height: 30rpx;"></view>
            <!-- <view class="phone-botton"  @click="contactPhone()" >关闭</view> -->
         </view>
      </u-popup>
      <!-- 确认收货 -->
      <u-popup :show="showDone" round="15" :safeAreaInsetBottom="false" mode="center">
         <view class="tc">
            <view class="tc-contemt">
               <view class="tc-contemt-title">确认收货提醒</view>
               <view class="tc-contemt-nr">
                  您确认已经收到您的行李了吗?
               </view>
            </view>
            <view class="tc-btn">
               <view class="tc-btn-item" @click="showDone = false;currentOrder=null;">取消</view>
               <view class="tc-btn-item" style="color: #004096;" @click="doneOrderDo()">确认收货</view>
            </view>
         </view>
      </u-popup>
      <u-popup :show="showCancel" round="15" :safeAreaInsetBottom="false" mode="center">
         <view class="tc">
            <view class="tc-contemt">
               <view class="tc-contemt-title">确定取消提醒</view>
               <view class="tc-contemt-nr">
                  您确认取消该订单吗?
               </view>
            </view>
            <view class="tc-btn">
               <view class="tc-btn-item" @click="showCancel = false;currentOrder=null;">我再想想</view>
               <view class="tc-btn-item" style="color: red;" @click="cancelOrderDo">确认取消</view>
            </view>
         </view>
      </u-popup>
      <!-- 删除订单 -->
      <u-popup :show="showDelete" round="15" :safeAreaInsetBottom="false" mode="center">
         <view class="tc">
            <view class="tc-contemt">
               <view class="tc-contemt-title">确认删除提醒</view>
               <view class="tc-contemt-nr">
                  您确认删除该订单吗?
               </view>
            </view>
            <view class="tc-btn">
               <view class="tc-btn-item" @click="showDelete = false;currentOrder=null;">我再想想</view>
               <view class="tc-btn-item" style="color: red;" @click="deleteOrderDo">确认删除</view>
            </view>
         </view>
      </u-popup>
      <u-popup :show="showQrcode" round="15" @close="openQrcode()"   :safeAreaInsetBottom="false" mode="bottom"  :closeable="true" :closeOnClickOverlay="false">
         <view class="tc" style="height: 700rpx;width: 100%; ">
            <view class="tc-contemt" style="text-align: center;">
               <view class="tc-contemt-title" style="text-align: center;">核销码</view>
               <view class="qrcode-box">
                  <canvas canvas-id="qrcodeCanvas" id="qrcodeCanvas" style="width: 100px; height: 100px;"></canvas>
                  <image class="qrcode-image" :src="qrcodeImage" mode="widthFix"></image>
               </view>
               <text class="pickup-code">{{ currentOrder.memberVerifyCode||'' }}</text>
               <text class="pickup-tip" @tap="copyCode">点击复制自提码</text>
            </view>
         </view>
      </u-popup>
   </view>
</template>
<script>
   import { mapState } from 'vuex'
   import CustomTabbar from '@/components/custom-tabbar/custom-tabbar.vue'
   import drawQrcode from 'weapp-qrcode'
   export default {
      components: {
         CustomTabbar
      },
      computed: {
         ...mapState(['navHeight', 'statusbarHeight'])
      },
      data() {
         return {
            activeTab: -1,
            loading:false,
            pageSize: 10,
            currentPage: 1,
            showDone:false,
            showCancel:false,
            showDelete:false,
            showQrcode:false,
            showPay:false,
            showPhone:false,
            total:0,
            hasNext:true,
            userType: 0,
            qrcodeImage:null,
            isLoadingMore: false,
            currentOrder:null,
            filterTabs: [
               { label: '全部'  ,value: -1},
               { label: '待支付',value: 0 },
@@ -161,19 +268,167 @@
          })
      },
      onShow() {
         // this.showDone=false
         // this.showCancel=false
         // this.showDelete=false
         // this.showQrcode=false
         // this.showPay=false
         // this.showPhone=false
         this.loading=false,
         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: {
         payOrder(item){
            var that = this;
            uni.showLoading({ title: '发起支付中...', mask: true })
            this.$u.api.continuePayOrder({
               orderId: item.id
            }).then(res => {
               uni.hideLoading()
               if (res.code === 200 && res.data) {
                  let paymentData = res.data.response
                  uni.requestPayment({
                     provider: 'wxpay',
                     timeStamp: paymentData.timeStamp || '',
                     nonceStr: paymentData.nonceStr || '',
                     package: paymentData.package || '',
                     signType: paymentData.signType || 'MD5',
                     paySign: paymentData.paySign || '',
                     success: (res) => {
                        that.getFirstPageData()
                     },
                     fail: (err) => {
                        if (err.errMsg.includes('cancel')) {
                           uni.showToast({ title: '已取消支付', icon: 'none' })
                        } else {
                           uni.showToast({ title: '支付失败', icon: 'none' })
                        }
                     }
                  })
               } else {
                  uni.showToast({ title: res.msg || '支付失败', icon: 'none' })
               }
            }).catch(err => {
               uni.hideLoading()
               uni.showToast({ title: '支付失败', icon: 'none' })
            })
         },
         doneOrder(item){
            this.currentOrder = null
            this.showDone = !this.showDone
            if(this.showDone){
               this.currentOrder = item
            }
         },
         async  doneOrderDo(){
            if(this.userType == 1 || this.currentOrder==null || this.currentOrder.id == null) {
               return
            }
            var that =this
            let res = await this.$u.api.confirmReceipt({ orderId: this.currentOrder.id  });
            if (res.code === 200 ) {
               that.showDone = false
               that.getFirstPageData()
               that.showDone()
            }
         },
         contactPhone(item){
             this.showPhone = !this.showPhone
             this.linkItem = item ||{}
             console.log("==================================",this.showPhone)
         },
         contactPhoneDo(){
            if(this.linkItem.linkphone !=null && this.linkItem.linkphone!=''){
               uni.makePhoneCall({
                  phoneNumber: this.linkItem.linkphone
               })
            }
         },
         cancelOrder(item){
            this.currentOrder = null
            this.showCancel = !this.showCancel
            if(this.showCancel){
               this.currentOrder = item
            }
         },
         deleteOrder(item){
            this.currentOrder = null
            this.showDelete = !this.showDelete
            if(this.showDelete){
               this.currentOrder = item
            }
         },
         async cancelOrderDo(){
            if( this.currentOrder==null || this.currentOrder.id == null) {
               return
            }
               var that =this
            let res = await that.$u.api.cancelOrder({ orderId: this.currentOrder.id  });
            if (res.code === 200 ) {
               this.showCancel = false
               //修改订单状态
               this.dataList.forEach(item=>{
                  if(item.id==this.currentOrder.id){
                     item.status = 4
                  }
               })
               that.getFirstPageData()
            }
         },
         async deleteOrderDo(){
            if( this.currentOrder==null || this.currentOrder.id == null) {
               return
            }
            var that =this
            let res = await that.$u.api.deleteOrder({ orderId: this.currentOrder.id  });
            if (res.code === 200 ) {
               this.showDelete = false
               this.getFirstPageData()
            }
         },
         copyCode() {
            if (!this.currentOrder || !this.currentOrder.memberVerifyCode) {
               return
            }
            uni.setClipboardData({
               data: this.currentOrder.memberVerifyCode,
               success: () => {
                  uni.showToast({
                     title: '已复制自提码',
                     icon: 'none'
                  })
               }
            })
         },
         async openQrcode(item){
            this.currentOrder = null
            this.qrcodeImage=null
            var that =this
            if(!this.showQrcode){
               this.showQrcode =true
               this.currentOrder = item
               drawQrcode({
                  canvasId: 'qrcodeCanvas',
                  text: item.memberVerifyCode,
                  width: 100,
                  height: 100,
                  correctLevel: 2
               })
               setTimeout(() => {
                  uni.canvasToTempFilePath({
                     canvasId: 'qrcodeCanvas',
                     success: (res) => {
                        that.qrcodeImage = res.tempFilePath
                     }
                  }, this)
               }, 100)
            }else{
               this.showQrcode = false
            }
         },
         getFirstPageData(){
            this.currentPage = 0
            this.hasNext=true
@@ -226,6 +481,11 @@
</script>
<style lang="scss" scoped>
   .tc-contemt{
          display: flex;
          flex-direction: column;
          align-items: center;
   }
   .itinerary-page {
      min-height: 100vh;
      background: #f7f7f7;
@@ -318,7 +578,7 @@
   }
   .order-head {
      padding: 24rpx 30rpx;
      // padding: 24rpx 30rpx;
      display: flex;
      align-items: center;
      justify-content: space-between;
@@ -333,10 +593,19 @@
      background: #fff4e8;
   }
   .head-local,
   .head-local{
          flex: 1;
          padding: 24rpx 30rpx;
          min-width: 0;
          display: flex;
          align-items: center;
          background: linear-gradient(90deg, #15B9F7 -20%, #ffffff 100%);
   }
   .head-city {
      flex: 1;
      min-width: 0;
       padding: 24rpx 30rpx;
       background: linear-gradient(90deg, #FA8010 -20%, #ffffff 100%);
      display: flex;
      align-items: center;
   }
@@ -364,7 +633,7 @@
      height: 38rpx;
      border-radius: 8rpx;
      display: flex;
      align-items: center;
      align-items: baseline;
      justify-content: center;
      font-weight: 400;
      font-size: 24rpx;
@@ -374,12 +643,14 @@
   }
   .local-tag {
      background: linear-gradient(90deg, #18abf8 0%, #39c5ff 100%);
      background: #18abf8;
      // background: linear-gradient(90deg, #18abf8 0%, #39c5ff 100%);
   }
   .city-tag {
      background: linear-gradient(90deg, #ff8b28 0%, #ffb14f 100%);
      // background: linear-gradient(90deg, #ff8b28 0%, #ffb14f 100%);
      margin-right: 0;
      background: #ff8b28;
      margin-bottom: 8rpx;
   }
@@ -439,15 +710,35 @@
   .status-text {
      font-weight: 400;
      line-height: 36rpx;
      font-size: 26rpx;
      color: #10B2FA;
      flex-shrink: 0;
   }
   .status-orange{
      color: #FA8010 !important;
   }
   .status-grey{
      color: #666666 !important;
   }
   .goods-area {
      padding: 22rpx 30rpx;
      box-sizing: border-box;
   }
   .status-orange{
      color: #FA8010 !important;
   }
   .status-orange{
      color: #FA8010 !important;
   }
   .goods-row {
      display: flex;
@@ -498,8 +789,13 @@
      font-size: 24rpx;
      color: #8C939F;
   }
   .price-line{
      box-sizing: border-box;
      display: flex;
      align-items: flex-end;
   }
   .amount-area {
      width: 50%;
      padding: 0 30rpx;
      box-sizing: border-box;
      display: flex;
@@ -548,6 +844,7 @@
      display: flex;
      align-items: flex-start;
      flex-direction: column;
      width: 50%;
   }
   .pickup-label {
@@ -563,11 +860,12 @@
   }
   .footer-actions {
      margin-left: auto;
      display: flex;
      align-items: center;
      justify-content: flex-end;
      align-items: flex-end;
      gap: 10rpx;
      margin: 0 !important;
      width: 100%;
   }
   .footer-btn {
@@ -602,4 +900,36 @@
      font-size: 22rpx;
      color: #a5aab3;
   }
   .qrcode-box {
      margin-top: 40rpx;
      width: 360rpx;
      height: 360rpx;
      border-radius: 8rpx;
      box-sizing: border-box;
      position: relative;
      canvas {
         position: absolute;
         top: 0;
         left: 0;
         opacity: 0;
      }
   }
   .qrcode-image {
      width: 100%;
      height: 100%;
   }
   .pickup-code {
      margin-top: 32rpx;
      font-weight: 600;
      font-size: 36rpx;
      color: #222222;
   }
   .pickup-tip {
      font-weight: 400;
      font-size: 24rpx;
      color: #999999;
      margin-top: 24rpx;
   }
</style>