You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
224 lines
6.3 KiB
224 lines
6.3 KiB
<template> |
|
<basic-container> |
|
<div class="avue-crud"> |
|
<div class="mabxmp"> |
|
<div class="mapbox"> |
|
<div class="bmap" id="container"></div> |
|
</div> |
|
<div class="maplists"> |
|
<el-scrollbar> |
|
<div class="mbx"> |
|
<el-text v-for="item in datalists" class="mx-1 txbx" type="primary" |
|
> |
|
{{item.content}}--时间:{{item.time}}--距离:{{item.distance}}公里({{item.items.handQuantity}}件) |
|
</el-text |
|
> |
|
</div> |
|
</el-scrollbar> |
|
</div> |
|
</div> |
|
<div style="display: flex; align-items: center; justify-content: center"> |
|
<el-button icon="el-icon-circle-close" @click="back">返 回</el-button> |
|
</div> |
|
</div> |
|
</basic-container> |
|
</template> |
|
|
|
<script setup> |
|
import { useStore } from 'vuex'; |
|
import { getReservationAddr } from '@/api/distribution/distributionReservation'; |
|
import { getDictionaryBiz } from '@/api/system/dict'; |
|
import { onMounted, reactive, toRefs, watchEffect } from 'vue'; |
|
import { useRouter } from 'vue-router'; |
|
import { selectStockArticleAtlasInfo } from '@/api/distribution/distributionDeliveryList'; |
|
let router = useRouter(); |
|
let useStores=useStore() |
|
let details = reactive({ |
|
name: 'BmapDemo', |
|
item: null, |
|
error: null, |
|
addressList: [], |
|
reservationData: [], |
|
reservationIds: [], |
|
mapLoc: null, |
|
markersarr: [], |
|
lng: '', |
|
lat: '', |
|
datalists: [], |
|
abbreviation:'', |
|
drivingarrs:[], |
|
// datalist:[] |
|
}); |
|
onMounted(() => { |
|
initmap(); |
|
}); |
|
watchEffect(() => { |
|
// console.log(router.currentRoute.value.query.item) |
|
details.item = JSON.parse(router.currentRoute.value.query.item); |
|
selectStockArticleAtlasInfo(details.item.id).then(res => { |
|
const data = res.data.data.orderInfo; |
|
details.lng = res.data.data.jingdu; |
|
details.lat = res.data.data.weidu; |
|
details.abbreviation=res?.data?.data?.warehouseData?.name |
|
// console.log('res------------->', data); |
|
details.reservationData = data; |
|
details.mapLoc.remove(details.markersarr); |
|
details.drivingarrs.map(item=>{ |
|
if(item){ |
|
item.clear() |
|
} |
|
}) |
|
details.drivingarrs=[] |
|
details.datalists = []; |
|
setTimeout(() => { |
|
init(data); |
|
}, 1000); |
|
}); |
|
// setTimeout(() => { |
|
// init(); |
|
// }, 5000); |
|
}); |
|
function initmap() { |
|
details.mapLoc = new AMap.Map('container', { |
|
viewMode: '2D', // 默认使用 2D 模式 |
|
zoom: 9, //初始化地图层级 |
|
center: [104.293242, 30.582939], //初始化地图中心点 |
|
}); |
|
} |
|
function init(data) { |
|
// maplabel() |
|
console.log(details.mapLoc); |
|
var marker = new AMap.Marker({ |
|
map:details.mapLoc, |
|
position: [details.lng,details.lat], |
|
icon: '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png', |
|
anchor:'bottom-center', |
|
offset: new AMap.Pixel(0, 0) |
|
}); |
|
marker.setMap(details.mapLoc); |
|
marker.setLabel({ |
|
offset: new AMap.Pixel(0, -5), //设置文本标注偏移量 |
|
content: `<div class='info'>${details.abbreviation}</div>`, //设置文本标注内容 |
|
direction: 'top', //设置文本标注方位 |
|
}); |
|
details.markersarr.push(marker); |
|
let geocodess = []; |
|
var geocoder = new AMap.Geocoder({}); |
|
data.map(async (item, index) => { |
|
await geocoder.getLocation(item.customerAddress, (status, result) => { |
|
if (status === 'complete' && result.info === 'OK') { |
|
// result中对应详细地理坐标信息 |
|
details.mapLoc.setCenter([result.geocodes[0].location.lng, result.geocodes[0].location.lat]) |
|
geocodess.push({ |
|
pontion: result.geocodes[0].location, |
|
content: item.customerName + '--' + item.customerAddress+'' + '--' + item.customerTelephone, |
|
items: item, |
|
}); |
|
if (index + 1 == data.length) { |
|
maker(geocodess); |
|
Driving(geocodess); |
|
} |
|
} |
|
}); |
|
}); |
|
} |
|
//地图标点 |
|
function maker(geocodess) { |
|
geocodess.map(item => { |
|
var marker = new AMap.Marker({ |
|
map:details.mapLoc, |
|
position: item.pontion, |
|
icon: '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png', |
|
anchor:'bottom-center', |
|
offset: new AMap.Pixel(0, 0) |
|
}); |
|
marker.setMap(details.mapLoc); |
|
marker.setLabel({ |
|
offset: new AMap.Pixel(0, -5), //设置文本标注偏移量 |
|
content: `<div class='info'>${item.content}</div>`, //设置文本标注内容 |
|
direction: 'top', //设置文本标注方位 |
|
}); |
|
details.markersarr.push(marker); |
|
}); |
|
} |
|
//地图公里数和时间计算 |
|
function Driving(geocodess) { |
|
|
|
// 根据起终点经纬度规划驾车导航路线 |
|
geocodess.map(item => { |
|
var driving = new AMap.Driving({ |
|
map:details.mapLoc, |
|
hideMarkers:true |
|
}); |
|
driving.search( |
|
new AMap.LngLat(details.lng, details.lat), |
|
new AMap.LngLat(item.pontion.lng, item.pontion.lat), |
|
function (status, result) { |
|
if (status === 'complete') { |
|
// console.log(result.routes[0]); |
|
item.time=formatSeconds(result.routes[0].time) |
|
item.distance=result.routes[0].distance/1000 |
|
// item.distance=result.routes[0].distance/1000 |
|
details.datalists.push(item) |
|
} else { |
|
console.log('获取驾车数据失败:'+ result) |
|
} |
|
} |
|
); |
|
details.drivingarrs.push(driving) |
|
}); |
|
} |
|
//将秒数转化为多少小时多少分 |
|
function formatSeconds(seconds) { |
|
var hours = Math.floor(seconds / 3600); |
|
var minutes = Math.floor((seconds % 3600) / 60); |
|
var remainingSeconds = seconds % 60; |
|
var result = ""; |
|
if(hours > 0) { |
|
result += hours.toString().padStart(2, '0') + "小时"; |
|
} |
|
result += minutes.toString().padStart(2, '0')+'分钟'; |
|
return result; |
|
} |
|
function back() { |
|
useStores.commit('DEL_TAG_CURRENT'); |
|
router.back(-1) |
|
} |
|
const { datalists } = toRefs(details); |
|
</script> |
|
|
|
<style lang="scss" scoped> |
|
.bmap { |
|
width: 100%; |
|
height: 500px; |
|
margin-bottom: 60px; |
|
/* border: 1px solid pink; */ |
|
} |
|
.mabxmp { |
|
display: flex; |
|
align-items: flex-start; |
|
> .mapbox { |
|
width: 50%; |
|
} |
|
> .maplists { |
|
width: 50%; |
|
height: 500px; |
|
padding: 0 20px; |
|
box-sizing: border-box; |
|
.mbx { |
|
display: flex; |
|
flex-direction: column; |
|
align-items: flex-start; |
|
|
|
} |
|
} |
|
} |
|
.info { |
|
font-size: 10px !important; |
|
} |
|
.txbx { |
|
padding: 5px 0px; |
|
box-sizing: border-box; |
|
width: 100%; |
|
} |
|
</style>
|
|
|