rk
2025-09-24 f3c59a17062fb0a89b5f89b7845341386952a6b1
h5/pages/waybill/waybillDetail.vue
@@ -1,207 +1,503 @@
<template>
   <view class="main_app">
      <image src="@/static/driver/wuliuche_bg@2x.png" class="main_bg"></image>
      <view class="form_wrap">
         <view class="item">
            <view class="label">合同编号</view>
            <view class="line">
               <view class="input_wrap"><input v-model="param.aa" placeholder="请输入合同编号" placeholder-class="place" type="text" /></view>
      <!-- <image class="bg" src="@/static/wuliuche_bg@2x.png" mode="widthFix"></image> -->
      <map id="map" :latitude="latitude" :longitude="longitude" :polyline="polyline" :markers="markers" :scale="scale">
      </map>
      <view class="main_content">
         <view class="info">
            <view class="stock_status" v-if="info.overStock && info.overStock == 1">
               <image src="@/static/ic_tip@2x.png" mode=""></image>
               <view class="">因库存不足,订单暂时无法配载</view>
            </view>
         </view>
         <view class="item">
            <view class="label">需方编号</view>
            <view class="line">
               <view class="input_wrap"><input v-model="param.aa" placeholder="请输入合同中需方编号" placeholder-class="place" type="text" /></view>
            </view>
         </view>
         <view class="item">
            <view class="label">验证码</view>
            <view class="line">
               <view class="input_wrap"><input v-model="param.aa" placeholder="请输入验证码" placeholder-class="place" type="text" /></view>
               <image src="" class="auth_code" mode=""></image>
            </view>
         </view>
         <view class="query">查询</view>
            <view class="head">
               <view class="code">{{info.contractNumber}}</view>
               <view class="status">{{info.orderStatusDesc}}</view>
            </view>
            <view class="content">
               <view class="line">
                  <view class="la">发货地</view>
                  <view class="val">{{info.deliveryEnterprise || '-'}}</view>
               </view>
               <view class="line">
                  <view class="la">到货地</view>
                  <view class="val">{{info.receiveEnterprise || '-'}}</view>
               </view>
               <view class="line">
                  <view class="la">车牌号</view>
                  <view class="val">{{info.plateName || '-'}}</view>
               </view>
               <view class="line">
                  <view class="la">司机信息</view>
                  <view class="val" @click="callPhone(info.driverTel)">{{ info.driverName  }} <text
                        class="primaryColor ml12">{{info.driverTel}}</text> </view>
               </view>
               <view class="line">
                  <view class="la">车辆位置</view>
                  <view class="val">{{ info.address || '-'}}</view>
               </view>
               <view class="line">
                  <view class="la">预计到达</view>
                  <view class="val primaryColor" v-if="info.plannedArrivedDate">{{info.plannedArrivedDate.slice(0,11)}}</view>
               </view>
               <view v-if="showRecord" class="table">
                  <view class="ite header">
                     <view class="name">品规名称</view>
                     <view class="num">数量<text>(万支)</text></view>
                  </view>
                  <view class="ite" v-for="ite in info.orderDetailVOList">
                     <view class="name">{{ite.productName}}</view>
                     <view class="num">{{ite.pnumber}}</view>
                  </view>
               </view>
               <view class="line switch" @click="showRecord = !showRecord">
                  <view class="">{{  showRecord ? '收起品规明细' : '查看品规明细'}}</view>
                  <u-icon v-if="!showRecord" name="arrow-down" size="12" class="ml6" color='#666666'></u-icon>
                  <u-icon v-if="showRecord" name="arrow-up" size="12" class="ml6" color='#666666'></u-icon>
               </view>
            </view>
         </view>
         <view class="drive_info">
            <view class="title">物流信息</view>
            <view class="drive_list" v-for="dri,k in info.cicleStatusList">
               <view class="separate" v-if="k < info.cicleStatusList.length - 1"></view>
               <view class="item_title">
                  <view class="icon_wrap">
                     <image v-if="dri.key == 0 && k != 0" src="@/static/waybill/ic_dingdan@2x.png" class="icon"></image>
                     <image v-if="dri.key == 0 && k == 0" src="@/static/waybill/ic_dingdan_sel@2x.png" class="icon"></image>
                     <image v-if="dri.key == 1 && k != 0" src="@/static/waybill/ic_peizai@2x.png" class="icon"></image>
                     <image v-if="dri.key == 1 && k == 0" src="@/static/waybill/ic_peizai_sel@2x.png" class="icon"></image>
                     <image v-if="dri.key == 2 && k != 0" src="@/static/waybill/ic_cangku@2x.png" class="icon"></image>
                     <image v-if="dri.key == 2 && k == 0" src="@/static/waybill/ic_cangku_sel@2x.png" class="icon"></image>
                     <image v-if="dri.key == 3 && k != 0" src="@/static/waybill/ic_yunshu@2x.png" class="icon"></image>
                     <image v-if="dri.key == 3 && k == 0" src="@/static/waybill/ic_yunshu_sel@2x.png" class="icon"></image>
                     <image v-if="dri.key == 4 && k != 0" src="@/static/waybill/ic_dingdan@2x.png" class="icon"></image>
                     <image v-if="dri.key == 4 && k == 0" src="@/static/waybill/ic_daohuo_sel@2x.png" class="icon"></image>
                     <image v-if="dri.key == 5" src="@/static/waybill/ic_ruku.png" class="icon"></image>
                  </view>
                  <view class="" :class="{primaryColor: k == 0}">{{dri.name}}</view>
               </view>
               <view class="item" v-for="item,i in dri.secondList">
                  <view class="h2" v-if="item.orderStatusDes">
                     <view class="icon_wrap" v-if="i != 0">
                        <image src="@/static/driver/ic_mostarted.png" class="icon"></image>
                     </view>
                     <view v-else class="icon_wrap"></view>
                     <view class="text" :class="{placeholder3: k==0 && i== 0}">
                        <text :style="{ color: item.orderStatus === 9 ? 'red' : '#666666'}">{{item.orderStatusDes}}</text>
                        <text v-if="item.tel">,发货仓库电话:</text>
                        <template v-if="item.tel">
                           <text v-for="phone,p in item.tel.split(',')" @click="callPhone(phone)" class="primaryColor">{{phone}}<text v-if="p < item.tel.split(',').length - 1">,</text></text>
                        </template>
                     </view>
                  </view>
                  <view class="time">{{item.recordDate}}</view>
               </view>
            </view>
         </view>
      </view>
      <view class="title">查询结果</view>
      <view class="drive_info">
         <view class="title">合同编号</view>
         <view class="line">
            <view class="label">运输车辆</view>
            <view class="val">11</view>
         </view>
         <view class="line">
            <view class="label">司机信息</view>
            <view class="val">11</view>
         </view>
         <view class="line">
            <view class="label">车辆位置</view>
            <view class="val">11</view>
         </view>
      </view>
      <view class="drive_info">
         <view class="title">物流信息</view>
         <view class="item">
            <view class="h2">
               <view class="icon_wrap"><image src="@/static/driver/ic_mostarted.png" class="icon"></image></view>
               <view class="text">到达卸货地</view>
            </view>
            <view class="time">202422222222</view>
            <view class="separate"></view>
         </view>
         <view class="item">
            <view class="h2 h1">
               <view class="icon_wrap"><image src="@/static/driver/ic_dangqian.png" class="icon"></image></view>
               <view class="text">到达卸货地</view>
            </view>
            <view class="time">202422222222</view>
            <view class="separate separate_ac"></view>
         </view>
         <view class="item">
            <view class="h2">
               <view class="icon_wrap"><image src="@/static/driver/ic_mostarted.png" class="icon"></image></view>
               <view class="text">到达卸货地</view>
            </view>
            <view class="time">202422222222</view>
            <view class="separate"></view>
         </view>
      </view>
   </view>
</template>
<script>
   import {
      orderInfoTms
   } from '@/api'
   export default {
      data() {
         return {
            param: {}
            id: '',
            info: {},
            param: {},
            latitude: 31.783205,
            longitude: 117.262635,
            scale: 5,
            markers: [],
            includePoints: [
               // {latitude: 31.783205, longitude: 117.262635}, {latitude: 36.783205, longitude: 118.10},
            ],
            polyline: [
               // {
               //    points: [{
               //       latitude: 31.783205,
               //       longitude: 117.262635
               //    }, {
               //       latitude: 36.783205,
               //       longitude: 118.10
               //    }],
               //    color: '#FF0000',
               //    width: 3
               // },
            ],
            showRecord: false
         };
      },
      onLoad(options) {
         this.id = options.id
         this.getDetail()
      },
      methods: {
         getDetail() {
            orderInfoTms({
               contractNumber: this.id
            }).then(res => {
               this.info = res.data
               if (res.data.deliveryLat && res.data.receiveLat) {
                  this.markers = []
                  this.markers.push({
                     id: 1,
                     latitude: res.data.deliveryLat,
                     longitude: res.data.deliveryLon,
                     width: 36,
                     iconPath: '/static/driver/ic_fahuodi@2x.png',
                     label: {
                        content: ' ',
                        padding: 3,
                        borderWidth: 2,
                        borderRadius: '50%',
                        borderColor: '#fff',
                        borderRadius: 32,
                        bgColor: '#FF0000'
                     }
                  })
                  this.markers.push({
                     id: 2,
                     latitude: res.data.receiveLat,
                     longitude: res.data.receiveLon,
                     width: 36,
                     iconPath: '/static/driver/ic_huowu@2x.png',
                     label: {
                        content: ' ',
                        padding: 3,
                        borderWidth: 2,
                        borderRadius: '50%',
                        borderColor: '#fff',
                        borderRadius: 32,
                        bgColor: '#FF0000'
                     }
                  })
                  this.latitude = (Number(this.markers[0].latitude) + Number(this.markers[1].latitude)) / 2 - 4
                  this.longitude = (Number(this.markers[0].longitude) + Number(this.markers[1].longitude)) / 2
                  const distance = this.distance()
                  console.log('distance', distance);
                  if(distance > 1500000){
                     this.scale = 4
                  }else if(distance < 600000){
                     this.scale = 6
                  }else{
                     this.scale = 5
                  }
               }
               if (res.data && res.data.gisList && res.data.gisList.length > 0) {
                  this.gisInfo = res.data.gisList[0]
                  if (this.gisInfo && this.gisInfo.gisList && this.gisInfo.gisList.length > 0) {
                     // const apiKey = 'd9a554b1808ce10a12a932ed9b0db1d0';
                     const apiKey = '3916a7b434e7f13ae1a0af64e88ec0a3';
                     let adsInfo = this.gisInfo.gisList[this.gisInfo.gisList.length - 1]
                     const location = adsInfo.lon1 + ',' + adsInfo.lat1;
                     uni.request({
                        url: `https://restapi.amap.com/v3/geocode/regeo?key=${apiKey}&location=${location}`,
                        method: 'GET',
                        success: (res) => {
                           this.$set(this.info, 'address', res.data.regeocode.formatted_address)
                        },
                     })
                     this.polyline = []
                     let temp = {
                        color: '#ff0000',
                        width: 3,
                        points: this.gisInfo.gisList.map(item => {
                           return {
                              latitude: item.lat,
                              longitude: item.lon,
                           }
                        })
                     }
                     this.polyline.push(temp)
                  }
               }
            })
         },
         distance() {
            const {
               latitude: lat1,
               longitude: lng1
            } = this.markers[0];
            const {
               latitude: lat2,
               longitude: lng2
            } = this.markers[1];
            const radLat1 = this.rad(lat1);
            const radLat2 = this.rad(lat2);
            const a = radLat1 - radLat2;
            const b = this.rad(lng1) - this.rad(lng2);
            const Haversin = Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2),
               2);
            const radius = 6378137; // 地球半径
            return 2 * radius * Math.asin(Math.sqrt(Haversin));
         },
         rad(d) {
            return d * Math.PI / 180.0;
         },
         callPhone(phone) {
            uni.makePhoneCall({
               phoneNumber: phone
            });
         }
      }
   }
</script>
<style lang="scss" scoped>
   .form_wrap {
      width: 690rpx;
      height: 646rpx;
      background: #FFFFFF;
      box-shadow: 0rpx 4rpx 20rpx 0rpx rgba(39,155,170,0.16);
      border-radius: 16rpx;
      padding: 10rpx 30rpx;
      margin-bottom: 40rpx;
      .item{
         height: 154rpx;
         padding: 30rpx 0 8rpx;
         border-bottom: 1rpx solid #E5E5E5;
         .label{}
         .line{
            display: flex;
            .input_wrap{
               padding: 18rpx 0;
               flex: 1;
               .place{
                  color: #999999;
                  font-size: 28rpx;
               }
            }
            .auth_code{
               width: 160rpx;
               height: 64rpx;
               border: 2px solid;
            }
         }
      }
      .query{
         width: 630rpx;
         height: 88rpx;
         background: $uni-color-primary;
         border-radius: 44rpx;
         margin-top: 40rpx;
         color: #fff;
         display: flex;
         justify-content: center;
         align-items: center;
         font-size: 30rpx;
      }
   page {
      background-color: #f7f7f7;
   }
   .main_app{
      padding-top: 218rpx;
      .title{
         font-weight: 500;
         font-size: 32rpx;
         margin-bottom: 30rpx;
      }
      .drive_info{
         background: #F7F7F7;
         border-radius: 16rpx;
         padding: 30rpx;
         margin-bottom: 20rpx;
         .line{
            display: flex;
            margin-bottom: 24rpx;
            .label{
               color: #666666;
               margin-right: 40rpx;
            }
            .val{
            }
         }
         .item{
            position: relative;
            color: #999999;
            margin-bottom: 30rpx;
            .h2{
               display: flex;
               align-items: center;
               height: 48rpx;
               .icon_wrap{
                  width: 48rpx;
                  margin-right: 30rpx;
                  display: flex;
                  align-items: center;
                  justify-content: center;
                  .icon{
                     width: 24rpx;
                     height: 24rpx;
                     position: relative;
                     z-index: 2;
                  }
               }
            }
            .h1{
               .icon_wrap{
                  .icon{
                     width: 48rpx;
                     height: 48rpx;
                  }
               }
            }
            .time{
               padding-left: 78rpx;
               font-size: 24rpx;
               margin-top: 6rpx;
            }
            .separate{
               height: calc( 100% );
               width: 2rpx;
               border: 2rpx dashed red;
               position: absolute;
               left: 22rpx;
               top: 24rpx;
               z-index: 1;
            }
            .separate_ac{
               top: 48rpx;
            }
         }
      }
   .main_app {
      padding-top: 45vh;
      // .main_content{
      //    height: 55vh ;
      //    overflow: auto;
      //    padding: 20rpx 30rpx 0;
      //    position: relative;
      //    z-index: 999;
      // }
      #map {
         width: 750rpx;
         position: fixed;
         left: 0;
         top: 0;
         height: 105vh;
         ::v-deep .amap-marker-label {
            top: 36px !important;
            left: 12px !important;
            border: 3px solid #fff !important;
            border-radius: 50%;
            box-shadow: #222222 0px 0px 1px;
         }
      }
      .drive_info {
         background: #fff;
         border-radius: 16rpx;
         padding: 30rpx;
         margin-bottom: 20rpx;
         position: relative;
         z-index: 999;
         .drive_list{
            position: relative;
            z-index: 999;
            .separate {
               height: calc(100% - 48rpx);
               width: 1rpx;
               border: 1rpx dashed #CCCCCC;
               position: absolute;
               left: 24rpx;
               top: 48rpx;
               z-index: -1;
            }
         }
         .title {
            font-weight: 500;
            font-size: 32rpx;
            color: #222222;
            margin-bottom: 20rpx;
         }
         .line {
            display: flex;
            margin-bottom: 24rpx;
            .label {
               color: #666666;
               margin-right: 40rpx;
            }
            .val {}
         }
         .item_title {
            font-weight: 600;
            font-size: 32rpx;
            display: flex;
            align-items: center;
         }
         .icon_wrap {
            width: 50rpx;
            margin-right: 30rpx;
            display: flex;
            // align-items: center;
            justify-content: center;
            flex-shrink: 0;
            .icon {
               width: 50rpx;
               height: 50rpx;
               position: relative;
               z-index: 2;
            }
         }
         .item {
            position: relative;
            color: #999999;
            margin-bottom: 30rpx;
            &:nth-last-child(1){
               margin-bottom: 0;
               padding-bottom: 30rpx;
            }
            .text {
               color: #666666;
               flex: 1;
            }
            .icon {
               width: 20rpx;
               height: 20rpx;
               position: relative;
               z-index: 2;
               margin-top: 12rpx;
            }
            .h2 {
               display: flex;
               // align-items: center;
               // height: 48rpx;
            }
            .h1 {}
            .time {
               padding-left: 78rpx;
               font-size: 24rpx;
               margin-top: 6rpx;
            }
         }
      }
      .info {
         border-radius: 12rpx;
         margin-bottom: 20rpx;
         padding: 0 30rpx;
         background-color: #fff;
         overflow: hidden;
         position: relative;
         z-index: 1;
         .stock_status{
            background: #FFEEEE;
            font-size: 26rpx;
            color: #ED4545;
            display: flex;
            align-items: center;
            border-radius: 8rpx 8rpx 0rpx 0rpx;
            height: 80rpx;
            margin: 0rpx -30rpx 0;
            position: relative;
            z-index: 1;
            padding: 0 30rpx;
            image{
               width: 28rpx;
               height: 28rpx;
               margin-right: 10rpx;
            }
         }
         .head {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 0 30rpx;
            width: 690rpx;
            border-radius: 8rpx 8rpx 0rpx 0rpx;
            height: 84rpx;
            margin: 0 -30rpx;
            background: linear-gradient(270deg, #FEFEFF 0%, #E1F7FE 100%);
            position: relative;
            z-index: 11;
            .code {
               font-weight: 500;
               font-size: 32rpx;
               color: #222222;
            }
            .status {
               color: $uni-color-primary;
            }
         }
         .content {
            padding: 20rpx 0rpx;
            margin-bottom: 20rpx;
            .line {
               display: flex;
               margin-bottom: 16rpx;
               font-size: 28rpx;
               .la {
                  color: #666666;
                  width: 140rpx;
               }
               .val {
                  flex: 1;
               }
               &:nth-last-child(1) {
                  margin-bottom: 0;
               }
            }
            .table{
               margin: 0 auto 20rpx;
               .ite{
                  width: 100%;
                  height: 68rpx;
                  background: #FFFFFF;
                  border-bottom: 1rpx solid #E5E5E5;
                  display: flex;
                  align-items: center;
                  font-size: 28rpx;
                  padding-left: 30rpx;
                  .name{
                     flex: 8;
                     // padding-left: 20rpx;
                  }
                  .num{
                     flex: 3;
                  }
               }
               .header{
                  background: #F4F7FC;
                  font-weight: 500;
                  text{
                     font-size: 22rpx;
                  }
               }
            }
            .switch{
               display: flex;
               align-items: center;
               justify-content: center;
               color: #666666;
            }
         }
      }
   }
   .main_bg {
      position: absolute;
      left: 0;
   .main_bg {
      position: absolute;
      left: 0;
      top: 0;
      width: 100%;
      z-index: -1;
      width: 100%;
      z-index: -1;
      color: #222222;
   }
</style>