uniapp 小程序使用腾讯地图 模拟规划路线

 

 

 

 

 

 

<template>
	<view class="deliver-wrap">		
		<uni-nav-bar color="#fff" style="width: 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="width: 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,
					width: 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',
							width: 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',
					width: 20,
					height: 20
				}, {  
					latitude: this.destLat,
					longitude: this.destLng,
					width: 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',
						width: 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{
		width: 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;
			width: 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;
		width: 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;
				width: 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;
							width: 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>

  

  

 

posted @ 2022-03-26 15:21  福超  阅读(2377)  评论(0编辑  收藏  举报