1. 程式人生 > 其它 >uniapp 小程式使用騰訊地圖 模擬規劃路線

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" class="map-wrap" style="width: 100%; height: 80vh;" :latitude="startLat2" :longitude="startLng2"
			:polyline="polyline" :markers="marker" :scale="scale"></map>
		<scroll-view :class="isLess10 ? '':'less10'" :style="'height:' + scrollViewHeight + ';'" class="scroll-v"
			enableBackToTop="true" scroll-y :scroll-top="scrollTop" 
			@scroll="scrollChange">			 
			<view@click="toProcess" class="center-card">
				<deliver-card :item="item" width="730rpx"></deliver-card>
			</view>
			<view class="components-wrap">
				<view class="top-wrap">
					<view class="left">
						貨單構件列表
					</view>
					<view class="right"> 
						共計{{outboundVolumeBlock}}塊,{{outboundVolumeBlock/1000}}m³,{{outboundVolumeBlock/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>已發車</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} from "@/api/deliver.js"
	var QQMapWX = require('@/utils/qqmap-wx-jssdk.min.js');
	// 例項化API核心類  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 {
				outboundVolumeArea: 0,
				outboundVolumeBlock:0,
				outboundVolumeWeight:0,
				componentList:[],
				emptyList:[],
				item:{}, 
				list:[],
				allData:{},
				id:null,
				isLess10: false,
				scrollViewHeight: "calc(100vh - 200rpx)",
				scrollViewHeightCopy: "calc(100vh - 200rpx)",
				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.item = JSON.parse(options.item)
			this.id = this.item.id
			this.getData() 
		},
		onShareAppMessage() {
		  return {
		    title: "交付單運輸中,點選檢視詳情,聯絡司機",
		    path: "/otherPages/pages/deliverDetail"
		  };
		},
		mounted() {			
			uni.getSystemInfo({
				success: (resu) => {
					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)`;

					});
				},
				fail: (res) => {},
			});
		},
		methods: {
			itemClickHandler(id) {
				let projectId = this.allData.projectId
			  uni.navigateTo({
			    url: `./componentDetail?id=${id}&projectId=${projectId}`,
			  });
			},
			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(distance);
						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;
						if (time < 1) {
							that.vehicle(pl[pl.length-2])
						} else {
							// time
							let length = pl.length -1 ;
							let durationPercent = Math.round(length*that.getPercent(that.departureTime, data[0].duration ));
							durationPercent = durationPercent > length ? length : durationPercent;							
							that.vehicle(pl[durationPercent]) 
						}
				
						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(){
				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(){
				deliverDetailApi(this.id).then(res=>{ 
					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 < 4){
						let l = 4 - 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;  //開始時間
				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() {
				uni.navigateBack()
			},
			scrollChange(e) { 
				let top = e.detail.scrollTop
				if (top < 10) {
					this.isLess10 = true
					this.scrollViewHeight = '90vh'
				} else {
					this.scrollViewHeight = this.scrollViewHeightCopy
					this.isLess10 = false
				}
			},
		
			vehicle(pl) {
				console.log(pl) 
				 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,					 
						label: { //為標記點旁邊增加標籤   //因背景顏色H5不支援
							content: '已出發' + this.departureTime + '分鐘',					 
							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;
		z-index: 1;
	}
	
	.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; 
		
		&.less10 {
			margin-top: 160rpx;
		}
	}
	.scroll-v::before{
		content: "";
		position: absolute;
		top: -86rpx;
		left: 0;
		width: 453rpx;
		height: 62rpx;
		background-image: url("../../static/images/map/tip.png");
		background-size: 453rpx 62rpx;
		z-index: 99999;
	}

	.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 {
							width: 48rpx;
							height: 48rpx;
						}
					}
				}

				.common-line {
					margin-top: 8rpx;
					line-height: 39rpx;
					color: #777777;
					font-size: 26rpx;
				}
			}
		}
	}
</style>
<style>
	page {
		background: linear-gradient(180deg, rgba(246, 247, 250, 0) 0%, #F6F7FA 36.47%);
	}
 
</style>