<template> <view class="deliver-wrap"> <uni-nav-bar color="#fff" style=" 100vw" statusBar="true" backgroundColor="linear-gradient(84.77deg, #69A9F8 26.48%, #3560DD 81.11%)" title="交付单详情"> <view slot="left"> <uni-icons type="arrowleft" size="24" color="#fff" @click="goBack"></uni-icons> </view> </uni-nav-bar> <map id="map" :style="'top:' + mapTop + ';'" class="map-wrap" style=" 100%; height: 65vh;" :latitude="startLat2" :longitude="startLng2" :polyline="polyline" :markers="marker" :scale="scale"></map> <view :style="{'height':(scrollType === 2?scrollViewHeightCopy:scrollViewHeightCopy3)}" @touchstart.stop="touchstart" @touchmove.stop="touchmove" @touchend.stop="touchend" v-if="scrollType === 3 || scrollType === 2" class="scroll-inner-mask"> </view> <scroll-view :class="[scrollType === 3 ?'less50':'',scrollType === 2 ?'less100':'',scrollType === 1 ?'more100':'',(scrollType !== 1) ? 'scroll-v-b':'']" :style="'height:' + scrollViewHeight + ';'" class="scroll-v" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend" enableBackToTop="true" scroll-y :scroll-top="scrollTop" @scroll="scrollChange"> <view @click="toProcess" class="center-card"> <deliver-card :shareType="shareType" :item="item" width="730rpx"></deliver-card> </view> <view class="components-wrap"> <view class="top-wrap"> <view class="left"> 货单构件列表 </view> <view class="right"> 共计{{outboundVolumeBlock}}块,{{outboundVolumeArea/1000}}m³,{{outboundVolumeWeight/1000}}T </view> </view> <view class="lis"> <block v-for="(component,componentIndex) in componentList" :key="componentIndex"> <view @click="itemClickHandler(component.id)" class="component-item"> <view class="line1"> {{component.model}} </view> <view class="line2 common-line"> <view class="left"> <text>{{component.typeLabel}}</text> <text> <text v-if="component.building">{{component.building}}#</text> <text v-if="component.floor">-{{component.floor}}F</text> </text> </view> <view class="right"> <text>{{filterStatus(component.status)}}</text> <image src="../../static/images/map/right.png" mode=""></image> </view> </view> <view class="line3 common-line"> {{item.projectName}} </view> <view class="line4 common-line"> {{component.code}} </view> </view> </block> <!-- <block v-for="(itemEmpty,emptyIndex) in emptyList" :key="emptyIndex"> <view style="height: 400rpx;"></view> </block> --> </view> </view> </scroll-view> </view> </template> <script> import deliverCard from '../components/deliverCard.vue' import {deliverDetailApi,deliverDetailShareApi} from "@/api/deliver.js" var QQMapWX = require('@/utils/qqmap-wx-jssdk.min.js'); // NTVBZ-BSM6X-4QM4N-TFCRL-VM4UT-WVB5F // EG2BZ-7VRKJ-5WXFI-FYSF5-WA56T-34FD7 var qqmapsdk = new QQMapWX({ key: 'NTVBZ-BSM6X-4QM4N-TFCRL-VM4UT-WVB5F' }); export default { name: "Profile", components: { deliverCard }, data() { return { touchS:0, touchE:0, touchD:0, mapTop:'64px', statusBarHeight:20, timer:null, shareType:0,//0正常 1分享 outboundVolumeArea: 0, outboundVolumeBlock:0, outboundVolumeWeight:0, componentList:[], emptyList:[], item:{}, list:[], allData:{}, tenantCode:null, id:null, scrollType:2,//1全屏 2中屏 3 小屏幕 scrollViewHeight: "calc(100vh - 200rpx)", scrollViewHeightCopy: "calc(100vh - 200rpx)", scrollViewHeightCopy3: "calc(100vh - 500rpx)", loading: false, //控制接口的请求 freshing: false, //控制下拉刷新 scrollTop: 0, // 已发出时间 departureTime: 0, //分钟 startLat: 39.909, startLng: 116.39742, startLat2: 39.909, startLng2: 116.39742, destLat: 40.013, destLng: 118.685, marker: [], polyline: [], scale: 12, //地图缩放程度 }; }, onLoad(options) { this.id = +options.id this.tenantCode = options.tenantCode if(options.shareType){ this.shareType = +options.shareType } this.getData() }, onShareAppMessage() { return { title: "交付单运输中,点击查看详情,联系司机", path: `/otherPages/pages/deliverDetail?shareType=1&id=${this.id}&tenantCode=${this.tenantCode}` }; }, mounted() { uni.getSystemInfo({ success: (resu) => { this.statusBarHeight = resu.statusBarHeight || 20 this.mapTop = `calc(${resu.statusBarHeight}px + 44px)` const query = uni.createSelectorQuery(); query.select(".scroll-v").boundingClientRect(); query.exec((res) => { this.scrollViewHeight = `calc(${resu.windowHeight}px - ${res[0].top}px - 26px)`; this.scrollViewHeightCopy = `calc(${resu.windowHeight}px - ${res[0].top}px - 26px)`; this.scrollViewHeightCopy3 = `calc(${resu.windowHeight}px - ${res[0].top}px - 26px - 160px)`; }); }, fail: (res) => {}, }); }, methods: { touchstart(e){ this.touchS = e.changedTouches[0].clientY // console.log(this.touchS,e,'touchstart') }, touchmove(e){ // console.log(e,'touchmove') }, touchend(e){ this.touchE = e.changedTouches[0].clientY // console.log(this.touchE,e,'touchend') this.touchD = Number(this.touchE) - Number(this.touchS) // console.log(this.touchD) if(this.touchD>0){ // console.log('下滑',this.touchD) if(this.scrollType === 2){ this.scrollType = 3 this.scrollViewHeight = this.scrollViewHeightCopy3 this.scrollTop = 0 + Math.random() } if(this.scrollType === 1 && this.scrollTop < 10){ this.scrollType = 2 this.scrollViewHeight = this.scrollViewHeightCopy this.scrollTop = 0 + Math.random() } }else{ // console.log('上滑',this.touchD) if(this.scrollType === 2){ this.scrollType = 1 this.scrollViewHeight = '90vh' } if(this.scrollType === 3){ this.scrollType = 2 this.scrollViewHeight = this.scrollViewHeightCopy this.scrollTop = 0 + Math.random() } } }, filterStatus(e){ let stepArr = ['待生产','生产中','生产完成','已入库','待出库','已出库','已送达','已退货'] return stepArr[e] || '异常' }, itemClickHandler(id) { if(this.shareType === 1){ return } let projectId = this.allData.projectId uni.navigateTo({ url: `./componentDetail?id=${id}&projectId=${projectId}`, }); }, handleAngleFun(pl,k){ let lng_a = pl[pl.length-k].longitude let lat_a = pl[pl.length-k].latitude let lng_b = pl[pl.length - k + 1].longitude let lat_b = pl[pl.length - k +1].latitude return this.getAngleFun(lng_a,lat_a, lng_b, lat_b) }, handleAngleFun2(pl,k){ let lng_a = pl[k].longitude let lat_a = pl[k].latitude let lng_b = pl[k +1].longitude let lat_b = pl[k].latitude return this.getAngleFun(lng_a,lat_a, lng_b, lat_b) }, getAngleFun(lng_a,lat_a, lng_b, lat_b){ var a = (90 - lat_b) * Math.PI / 180; var b = (90 - lat_a) * Math.PI / 180; var AOC_BOC = (lng_b - lng_a) * Math.PI / 180; var cosc = Math.cos(a) * Math.cos(b) + Math.sin(a) * Math.sin(b) * Math.cos(AOC_BOC); var sinc = Math.sqrt(1 - cosc * cosc); var sinA = Math.sin(a) * Math.sin(AOC_BOC) / sinc; var A = Math.asin(sinA) * 180 / Math.PI; var res = 0; if (lng_b > lng_a && lat_b > lat_a) res = A; else if (lng_b > lng_a && lat_b < lat_a) res = 180 - A; else if (lng_b < lng_a && lat_b < lat_a) res = 180 - A; else if (lng_b < lng_a && lat_b > lat_a) res = 360 + A; else if (lng_b > lng_a && lat_b == lat_a) res = 90; else if (lng_b < lng_a && lat_b == lat_a) res = 270; else if (lng_b == lng_a && lat_b > lat_a) res = 0; else if (lng_b == lng_a && lat_b < lat_a) res = 180; return res - 90 }, initMap(){ const that = this; qqmapsdk.direction({ mode: 'driving', //可选值:'driving'(驾车) trucking 货车 //from参数不填默认当前地址 // latitude纬度 longitude 经度 from: { latitude: that.startLat, longitude: that.startLng }, to: { latitude: that.destLat, longitude: that.destLng }, size: 4, // 车型 1: 微型车 2: 轻型车 3: 中型车 4: 重型车 policy: 'LEAST_TIME', //'9', //参考实时路况,高速优先,尽量躲避拥堵 height: 4, 2.5, length: 13, weight: 6.8, axle_weight: 34, axle_count: 6, is_trailer: 1, success: function(res, data) { that.setMarks() // distance number 是 方案总距离,单位:米 // duration number 是 方案估算时间(含路况),单位:分钟 //计算缩放比例 let distance = data[0].distance / 1000; console.log(res); console.log(data); if (distance > 500) { var scale = 7; } else if (distance > 200) { var scale = 10; } else if (distance > 100) { var scale = 12; } else { var scale = 15; } var ret = res; var coors = ret.result.routes[0].polyline, pl = []; //坐标解压(返回的点串坐标,通过前向差分进行压缩) var kr = 1000000; for (var i = 2; i < coors.length; i++) { coors[i] = Number(coors[i - 2]) + Number(coors[i]) / kr; } //将解压后的坐标放入点串数组pl中 for (var i = 0; i < coors.length; i += 2) { pl.push({ latitude: coors[i], longitude: coors[i + 1] }) } const time = data[0].duration - that.departureTime; let rotate = 0 if (time < 1) { if(pl.length > 10){ rotate = that.handleAngleFun(pl,2) } that.vehicle(pl[pl.length-2],rotate) } else { // time let length = pl.length -1 ; let durationPercent = Math.round(length*that.getPercent(that.departureTime, data[0].duration )); durationPercent = durationPercent > length ? length : durationPercent; if(pl.length > 10 && durationPercent < length - 1){ rotate = that.handleAngleFun2(pl,durationPercent) } that.vehicle(pl[durationPercent],rotate) } console.log(rotate) that.polyline = [{ points: pl, color: '#4AC37A', 5 }] that.scale = scale; }, fail: function(error) { uni.showToast({ title: error.message, duration: 3000, icon: "none", }); } }) }, setMarks(){ this.marker.push({ latitude: this.startLat, longitude: this.startLng, iconPath: '../../static/images/map/send.png', 20, height: 20 }, { latitude: this.destLat, longitude: this.destLng, 20, height: 20, iconPath: '../../static/images/map/receive.png' }) }, toProcess(){ if(this.shareType === 1){ return } let processList = [] if(this.allData.deliveryTime && this.allData.deliveryOperator){ processList.push({ name:'确认送达', time:this.allData.deliveryTime, person:this.allData.deliveryOperator }) } if(this.allData.departureTime && this.allData.departureOperator){ processList.push({ name:'确认发车', time:this.allData.departureTime, person:this.allData.departureOperator }) } if(this.allData.loadTime && this.allData.loader){ processList.push({ name:'装车', time:this.allData.loadTime, person:this.allData.loader }) } if(this.allData.createTime && this.allData.creator){ processList.push({ name:'制单', time:this.allData.createTime, person:this.allData.creator }) } uni.navigateTo({ url:"./componentProcess?list="+JSON.stringify(processList) }) }, getData(){ let currentApi = deliverDetailApi if(this.shareType === 1){ currentApi = deliverDetailShareApi } currentApi(this.id,this.tenantCode).then(res=>{ this.item = { componentInfo: res.data.data.componentInfo, departureTime: res.data.data.departureTime, driverName: res.data.data.driverName, driverPhone: res.data.data.driverPhone, factoryName: res.data.data.factoryName, id: res.data.data.factoryName, projectId: res.data.data.projectId, projectName: res.data.data.projectName, shipmentNumber: res.data.data.shipmentNumber, status: res.data.data.status, tenantCode: res.data.data.tenantCode, transportVehicle: res.data.data.transportVehicle, } this.allData = res.data.data this.componentList = res.data.data.componentList || [] this.outboundVolumeArea = res.data.data.outboundVolumeArea this.outboundVolumeBlock = res.data.data.outboundVolumeBlock this.outboundVolumeWeight = res.data.data.outboundVolumeWeight this.emptyList = [] if(this.componentList.length < 5){ let l = 5 - this.componentList.length for(let i=0;i<l;i+=1){ this.emptyList.push({}) } } // 运输中 this.departureTime = this.getTimeDistance(this.allData.departureTime) // 起点 let factoryLocation = res.data.data.factoryLocation this.startLat = factoryLocation.split(',')[1] this.startLng = factoryLocation.split(',')[0] // 终点 let addressLocation = res.data.data.addressLocation if(addressLocation.split(',').length === 2){ this.destLat = addressLocation.split(',')[1] this.destLng = addressLocation.split(',')[0] }else{ uni.showToast({ title:"项目地点经纬度异常", icon:'none', duration:3000 }) setTimeout(()=>{ uni.navigateBack() },3000) } }).then(()=>{ this.initMap() }) }, getTimeDistance(startTime){ // console.log(startTime) if(!startTime){ return 0 } var date1= startTime.replace(/\-/g, '/'); //开始时间 var date2 = new Date(); //结束时间 var date3 = date2.getTime() - new Date(date1).getTime(); //时间差的毫秒数 if(date3<0){ return 0 } //计算出相差天数 var days=Math.floor(date3/(24*3600*1000)) //计算出小时数 var leave1=date3%(24*3600*1000) //计算天数后剩余的毫秒数 var hours=Math.floor(leave1/(3600*1000)) //计算相差分钟数 var leave2=leave1%(3600*1000) //计算小时数后剩余的毫秒数 var minutes=Math.floor(leave2/(60*1000)) return days*24*60 + hours*60 + minutes }, goBack() { if(this.shareType === 1){ uni.switchTab({ url:"../../pages/tabBar/index" }) }else{ uni.navigateBack() } }, scrollChange(e) { // if(this.timer) clearTimeout(this.timer) // this.timer = setTimeout(()=>{ // console.log(top) // if(top>= 0 && top<=50){ // this.scrollType = 3 // this.scrollViewHeight = this.scrollViewHeightCopy3 // }else if(top>50 && top<100){ // this.scrollType = 2 // this.scrollViewHeight = this.scrollViewHeightCopy // }else if(top>=100){ // this.scrollType = 1 // this.scrollViewHeight = '90vh' // } // },100) }, vehicle(pl,rotate=0) { // console.log(pl,rotate) this.startLat2 = pl.latitude this.startLng2 = pl.longitude if(this.item.status === 3){ this.marker.push({ latitude: pl.latitude, longitude: pl.longitude, iconPath: '../../static/images/map/vehicle.png', 20, height: 20, anchor:{ x:0.01, y:0.5 }, rotate:rotate, label: { //为标记点旁边增加标签 //因背景颜色H5不支持 content: '已出发' + (this.departureTime/60).toFixed(1) + '小时', textAlign: 'left', fontSize: 14, height:'22px', padding:'8px', bgColor: '#5984FE', borderRadius:'4px', color: '#FFF', // label 位置 anchorX: 40, anchorY: -40, } }) } }, getPercent(num, total) { num = parseFloat(num); total = parseFloat(total); // console.log(num, total) if (isNaN(num) || isNaN(total)) { return 0; } return total <= 0 ? 0 : Math.round(num / total ); } }, }; </script> <style lang="scss" scoped> .map-wrap { position: fixed; left: 0; top: 0; z-index: 1; } .scroll-inner-mask{ 100%; height: 65vh; position: fixed; // background-color: rgba(0,0,0,0.4); left: 0; bottom: 0; z-index: 99999; } .scroll-v-b{ position: relative; &::before{ content: ""; position: absolute; top: -86rpx; left: 10rpx; 453rpx; height: 62rpx; background-image: url("../../static/images/map/tip.png"); background-size: 453rpx 62rpx; z-index: 9999; } } .scroll-v { position: relative; margin-top: 550rpx; z-index: 9999; transition: all 0.5s; background: linear-gradient(180deg, rgba(246, 247, 250, 0) 0%, #F6F7FA 36.47%); border-radius: 24rpx; &.less50 { margin-top: 840rpx; } &.less100 { margin-top: 550rpx; } &.more100 { margin-top: 0rpx; } } .components-wrap { background: #FAFBFD; border-radius: 24rpx; 730rpx; box-sizing: border-box; margin: 24rpx auto; overflow: hidden; .top-wrap { height: 93rpx; line-height: 93rpx; padding: 0 24rpx; display: flex; justify-content: space-between; align-content: center; .left { font-weight: 500; font-size: 32rpx; color: #333333; } .right { font-size: 24rpx; color: #666666; } } .lis { background-color: #fff; .component-item+.component-item::before { content: ""; height: 2rpx; background-color: #E5E5E5; position: absolute; 682rpx; left: 24rpx; top: 0rpx; transform: scaleY(0.5); } .component-item { position: relative; padding: 24rpx; box-sizing: border-box; .line1 { font-size: 32rpx; color: #333; line-height: 45rpx; } .line2 { display: flex; justify-content: space-between; align-content: center; .right { display: flex; justify-content: center; align-items: center; image { margin-left: 30rpx; 11rpx; height: 19rpx; } } } .common-line { margin-top: 8rpx; line-height: 39rpx; color: #777777; font-size: 28rpx; } } } } </style> <style> page { background: linear-gradient(180deg, rgba(246, 247, 250, 0) 0%, #F6F7FA 36.47%); } </style>