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.
430 lines
12 KiB
430 lines
12 KiB
6 months ago
|
<template>
|
||
|
<div class="container">
|
||
|
<div class="main-map">
|
||
|
<div class="left-map">
|
||
|
<div id="container">
|
||
|
<div class="map-btn">
|
||
|
<div class="Driving" @click.stop="Driving">驾车方案</div>
|
||
|
<div class="Ride" @click.stop="Ride">骑行方案</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div id="panel"></div>
|
||
|
</div>
|
||
|
<div class="right-info">
|
||
|
<div class="top">
|
||
|
<div class="icon" @click.stop="close">
|
||
|
<el-icon><Close /></el-icon>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="price">
|
||
|
<div class="label">订单金额:</div>
|
||
|
<div class="money">{{goodsInfo.otPrice}}元</div>
|
||
|
</div>
|
||
|
<div class="address">
|
||
|
<el-icon><LocationFilled /></el-icon>{{ goodsInfo.province }} {{ goodsInfo.city }} {{ goodsInfo.detail
|
||
|
}}{{ goodsInfo.street }}{{ goodsInfo.detail }}
|
||
|
</div>
|
||
|
<div class="receipt-time">
|
||
|
<div class="label">收货时间变化:</div>
|
||
|
<div class="time">{{ goodsInfo.createTime }}</div>
|
||
|
</div>
|
||
|
<div class="receipt-time">
|
||
|
<div class="label">商品类型:</div>
|
||
|
<div class="time">{{ goodsInfo.productType }}</div>
|
||
|
</div>
|
||
|
<div class="receipt-time">
|
||
|
<div class="label">商品总数:</div>
|
||
|
<div class="time">1</div>
|
||
|
</div>
|
||
|
<div class="line"></div>
|
||
|
<div class="address-ipt-box">
|
||
|
<div style="width: 80%; display: flex; flex-direction: column; justify-content: space-between">
|
||
|
<el-input v-model="startingPoint" placeholder="Please input" @keydown="startingPointEvent">
|
||
|
<template #prepend>起点:</template>
|
||
|
</el-input>
|
||
|
<el-input v-model="terminal" placeholder="Please input" @keydown="startingPointEvent">
|
||
|
<template #prepend>终点:</template>
|
||
|
</el-input>
|
||
|
</div>
|
||
|
<div class="btn" @click.stop="viewMap">查看</div>
|
||
|
</div>
|
||
|
<div class="tisp" v-if="TravelOptions">{{ TravelOptions }}:{{ routes.time }} 约{{ routes.distance }}公里</div>
|
||
|
<div class="submit">
|
||
|
<placerBtn :goodsinfo="goodsInfo" />
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</template>
|
||
|
|
||
|
<script lang="ts" setup>
|
||
|
// @ts-ignore
|
||
|
// 这是要被忽略类型检查的代码
|
||
|
window._AMapSecurityConfig = {
|
||
|
securityJsCode: '0c4dce68b8380eb47ad26dbea2cff570',
|
||
|
}
|
||
|
// 地图map
|
||
|
import feedback from '~/utils/feedback'
|
||
|
import AMapLoader from '@amap/amap-jsapi-loader'
|
||
|
import { onMounted, reactive, ref, toRefs, watch, defineEmits, defineProps } from 'vue'
|
||
|
import { Close, LocationFilled } from '@element-plus/icons-vue'
|
||
|
const emits = defineEmits(['closeChange'])
|
||
|
const props = defineProps(['goodsinfo'])
|
||
|
const close = () => {
|
||
|
emits('closeChange', false)
|
||
|
}
|
||
|
const goodsInfo = <any>ref({})
|
||
|
goodsInfo.value = props.goodsinfo
|
||
|
console.log(goodsInfo.value)
|
||
|
|
||
|
const startingPoint = <any>ref('')
|
||
|
startingPoint.value = goodsInfo.value.sendAddressObj.detailAddress
|
||
|
|
||
|
const terminal = <any>ref('')
|
||
|
terminal.value =
|
||
|
goodsInfo.value.province +
|
||
|
goodsInfo.value.city +
|
||
|
goodsInfo.value.detail +
|
||
|
goodsInfo.value.street +
|
||
|
goodsInfo.value.detail
|
||
|
// 37b09e9ef9458d8e987b9351420563ab
|
||
|
let map: any = null
|
||
|
let amap: any = null
|
||
|
let marker: any = null
|
||
|
let driving: any = null
|
||
|
let Riding: any = null
|
||
|
const routes = <any>ref({
|
||
|
time: '',
|
||
|
distance: '',
|
||
|
})
|
||
|
//进行地图初始化
|
||
|
function initMap() {
|
||
|
AMapLoader.load({
|
||
|
key: '37b09e9ef9458d8e987b9351420563ab', // 申请好的Web端开发者Key,首次调用 load 时必填
|
||
|
plugins: ['AMap.AutoComplete', 'AMap.PlaceSearch', 'AMap.Driving', 'AMap.DragRoute', 'AMap.Riding'],
|
||
|
version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
|
||
|
|
||
|
Loca: {
|
||
|
version: '2.0.0',
|
||
|
},
|
||
|
})
|
||
|
.then((AMap) => {
|
||
|
amap = AMap
|
||
|
map = new AMap.Map('container', {
|
||
|
//设置地图容器id
|
||
|
plugins: ['AMap.AutoComplete', 'AMap.PlaceSearch', 'AMap.Driving', 'AMap.DragRoute', 'AMap.Riding'],
|
||
|
center: [goodsInfo.value.longitude, goodsInfo.value.latitude], //地图中心点
|
||
|
zoom: 10, //地图显示的缩放级别
|
||
|
})
|
||
|
//点标记显示内容
|
||
|
const markerContent = `<div class="custom-content-marker">
|
||
|
<img src="https://a.amap.com/jsapi/static/image/plugin/marker/end.png">
|
||
|
<div class="close-btn" onclick="clearMarker()"></div>
|
||
|
</div>`
|
||
|
const position = new AMap.LngLat(goodsInfo.value.longitude, goodsInfo.value.latitude) //Marker 经纬度
|
||
|
marker = new AMap.Marker({
|
||
|
position: position,
|
||
|
content: markerContent, //将 html 传给 content
|
||
|
offset: new AMap.Pixel(-13, -30), //以 icon 的 [center bottom] 为原点
|
||
|
})
|
||
|
map.add(marker)
|
||
|
|
||
|
// goView() // 获取线路规划
|
||
|
})
|
||
|
.catch((e) => {
|
||
|
console.log(e)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
initMap()
|
||
|
const TravelOptions = <any>ref('')
|
||
|
const goView = () => {
|
||
|
map.remove(marker)
|
||
|
// eslint-disable-next-line no-undef
|
||
|
driving = new amap.Driving({
|
||
|
map: map,
|
||
|
// 驾车路线规划策略,AMap.DrivingPolicy.LEAST_TIME是最快捷模式
|
||
|
policy: amap.DrivingPolicy.LEAST_TIME,
|
||
|
// // panel 指定将结构化的路线详情数据显示的对应的DOM上,传入值需是DOM的ID
|
||
|
// panel: 'panel',
|
||
|
})
|
||
|
// 根据起终点经纬度规划驾车导航路线
|
||
|
driving.search(
|
||
|
// [
|
||
|
// { keyword: goodsInfo.value.sendAddressObj.detailAddress, city: goodsInfo.value.city },
|
||
|
// { keyword: goodsInfo.value.province, city: goodsInfo.value.city },
|
||
|
// ],
|
||
|
// 起点经纬度
|
||
|
[goodsInfo.value.sendAddressObj.longitude, goodsInfo.value.sendAddressObj.latitude],
|
||
|
// 终点经纬度
|
||
|
[goodsInfo.value.longitude, goodsInfo.value.latitude],
|
||
|
function (status: any, result: any) {
|
||
|
// result 即是对应的驾车导航信息,相关数据结构文档请参考 https://lbs.amap.com/api/javascript-api/reference/route-search#m_DrivingResult
|
||
|
if (status === 'complete') {
|
||
|
routes.value.distance = metersToKilometers(result.routes[0].distance)
|
||
|
routes.value.time = formatTime(result.routes[0].time)
|
||
|
console.log('绘制驾车路线完成', result)
|
||
|
TravelOptions.value = '驾车'
|
||
|
routes.value.time = formatTime(result.routes[0].time)
|
||
|
} else {
|
||
|
console.log('获取驾车数据失败:' + result)
|
||
|
}
|
||
|
},
|
||
|
)
|
||
|
}
|
||
|
const viewMap = () => {
|
||
|
goView()
|
||
|
}
|
||
|
const Driving = () => {
|
||
|
TravelOptions.value = '驾车'
|
||
|
if (Riding) {
|
||
|
Riding.clear()
|
||
|
}
|
||
|
if (driving) {
|
||
|
driving.clear()
|
||
|
}
|
||
|
goView()
|
||
|
}
|
||
|
const Ride = () => {
|
||
|
TravelOptions.value = '骑行'
|
||
|
if (driving) {
|
||
|
driving.clear()
|
||
|
}
|
||
|
if (Riding) {
|
||
|
Riding.clear()
|
||
|
}
|
||
|
map.clearMap()
|
||
|
// eslint-disable-next-line no-undef
|
||
|
Riding = new amap.Riding({
|
||
|
map: map,
|
||
|
// 驾车路线规划策略,AMap.DrivingPolicy.LEAST_TIME是最快捷模式
|
||
|
policy: 0,
|
||
|
// // panel 指定将结构化的路线详情数据显示的对应的DOM上,传入值需是DOM的ID
|
||
|
// panel: 'panel',
|
||
|
})
|
||
|
// 根据起终点经纬度规划驾车导航路线
|
||
|
Riding.search(
|
||
|
// 起点经纬度
|
||
|
[goodsInfo.value.sendAddressObj.longitude, goodsInfo.value.sendAddressObj.latitude],
|
||
|
// 终点经纬度
|
||
|
[goodsInfo.value.longitude, goodsInfo.value.latitude],
|
||
|
function (status: any, result: any) {
|
||
|
// result 即是对应的驾车导航信息,相关数据结构文档请参考 https://lbs.amap.com/api/javascript-api/reference/route-search#m_DrivingResult
|
||
|
if (status === 'complete') {
|
||
|
routes.value.distance = metersToKilometers(result.routes[0].distance)
|
||
|
routes.value.time = formatTime(result.routes[0].time)
|
||
|
console.log('绘制骑行路线完成', result)
|
||
|
|
||
|
} else {
|
||
|
feedback.msgError('获取骑行数据失败')
|
||
|
console.log('获取骑行数据失败:' + result)
|
||
|
}
|
||
|
},
|
||
|
)
|
||
|
}
|
||
|
const dialogTableVisible = ref(false)
|
||
|
|
||
|
const changeDialog = () => {
|
||
|
dialogTableVisible.value = !dialogTableVisible.value
|
||
|
}
|
||
|
|
||
|
//暴露方法
|
||
|
defineExpose({
|
||
|
changeDialog,
|
||
|
initMap,
|
||
|
})
|
||
|
function formatTime(seconds: any) {
|
||
|
console.log(seconds)
|
||
|
|
||
|
let hours = Math.floor(seconds / 3600)
|
||
|
let minutes = Math.floor((seconds % 3600) / 60)
|
||
|
let remainingSeconds = seconds % 60
|
||
|
|
||
|
return `${hours}时${minutes}分${remainingSeconds}秒`
|
||
|
}
|
||
|
function metersToKilometers(meters: any) {
|
||
|
let kilometers = meters / 1000
|
||
|
return kilometers
|
||
|
}
|
||
|
const startingPointEvent = (event:any) => {
|
||
|
if (event.keyCode !== 37 && event.keyCode !== 39) {
|
||
|
event.preventDefault();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
</script>
|
||
|
|
||
|
<style lang="scss" scoped>
|
||
|
.custom-content-marker {
|
||
|
position: relative;
|
||
|
width: 25px;
|
||
|
height: 34px;
|
||
|
}
|
||
|
|
||
|
.custom-content-marker img {
|
||
|
width: 100%;
|
||
|
height: 100%;
|
||
|
}
|
||
|
|
||
|
.custom-content-marker .close-btn {
|
||
|
position: absolute;
|
||
|
top: -6px;
|
||
|
right: -8px;
|
||
|
width: 15px;
|
||
|
height: 15px;
|
||
|
font-size: 12px;
|
||
|
background: #ccc;
|
||
|
border-radius: 50%;
|
||
|
color: #fff;
|
||
|
text-align: center;
|
||
|
line-height: 15px;
|
||
|
box-shadow: -1px 1px 1px rgba(10, 10, 10, 0.2);
|
||
|
}
|
||
|
|
||
|
.custom-content-marker .close-btn:hover {
|
||
|
background: #666;
|
||
|
}
|
||
|
.container {
|
||
|
position: fixed;
|
||
|
left: 10%;
|
||
|
top: 0;
|
||
|
z-index: 1010;
|
||
|
width: 100%;
|
||
|
height: 100%;
|
||
|
#container {
|
||
|
width: 100%;
|
||
|
height: 100%;
|
||
|
}
|
||
|
.main-map {
|
||
|
position: absolute;
|
||
|
top: 50%;
|
||
|
left: 50%;
|
||
|
width: 4.5833rem;
|
||
|
height: 2.6042rem;
|
||
|
background-color: #fff;
|
||
|
z-index: 1;
|
||
|
transform: translate(-50%, -50%);
|
||
|
display: flex;
|
||
|
box-shadow: 0px 0px 58px rgba(0, 0, 0, 0.1);
|
||
|
.left-map {
|
||
|
width: 2.7083rem;
|
||
|
height: 100%;
|
||
|
background-color: skyblue;
|
||
|
#container {
|
||
|
position: relative;
|
||
|
}
|
||
|
.map-btn {
|
||
|
position: absolute;
|
||
|
bottom: 0.1563rem;
|
||
|
left: 0.1042rem;
|
||
|
z-index: 1;
|
||
|
display: flex;
|
||
|
.Driving {
|
||
|
margin-right: 0.1042rem;
|
||
|
width: 0.4167rem;
|
||
|
height: 0.1563rem;
|
||
|
text-align: center;
|
||
|
line-height: 0.1563rem;
|
||
|
color: #fff;
|
||
|
border-radius: 0.026rem;
|
||
|
background-color: #ff4e8d;
|
||
|
cursor: pointer;
|
||
|
}
|
||
|
.Ride {
|
||
|
margin-right: 0.1042rem;
|
||
|
width: 0.4167rem;
|
||
|
height: 0.1563rem;
|
||
|
text-align: center;
|
||
|
line-height: 0.1563rem;
|
||
|
color: #fff;
|
||
|
border-radius: 0.026rem;
|
||
|
background-color: #ff4e8d;
|
||
|
cursor: pointer;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
.right-info {
|
||
|
flex: 1;
|
||
|
padding: 0.0781rem;
|
||
|
.top {
|
||
|
width: 100%;
|
||
|
display: flex;
|
||
|
justify-content: end;
|
||
|
align-items: center;
|
||
|
i {
|
||
|
font-size: 0.125rem;
|
||
|
cursor: pointer;
|
||
|
}
|
||
|
}
|
||
|
.label {
|
||
|
font-size: 0.1042rem;
|
||
|
font-weight: 600;
|
||
|
margin-right: 0.0521rem;
|
||
|
}
|
||
|
.price {
|
||
|
display: flex;
|
||
|
align-items: center;
|
||
|
|
||
|
.money {
|
||
|
color: #ff4e8d;
|
||
|
font-size: 0.1042rem;
|
||
|
font-weight: 600;
|
||
|
}
|
||
|
}
|
||
|
.address {
|
||
|
margin-top: 0.1042rem;
|
||
|
font-size: 0.0833rem;
|
||
|
color: #575d6c;
|
||
|
margin-bottom: 0.1042rem;
|
||
|
}
|
||
|
.receipt-time {
|
||
|
display: flex;
|
||
|
align-items: center;
|
||
|
color: #2d3646;
|
||
|
margin: 0.0521rem 0;
|
||
|
.label {
|
||
|
font-size: 0.0833rem;
|
||
|
font-weight: 400;
|
||
|
}
|
||
|
.time {
|
||
|
font-size: 0.0833rem;
|
||
|
}
|
||
|
}
|
||
|
.line {
|
||
|
margin-top: 0.1042rem;
|
||
|
width: 100%;
|
||
|
height: 1px;
|
||
|
background-color: #c2c5cc;
|
||
|
}
|
||
|
.address-ipt-box {
|
||
|
display: flex;
|
||
|
margin-top: 0.1042rem;
|
||
|
|
||
|
height: 0.4063rem;
|
||
|
.btn {
|
||
|
padding: 0.0521rem 0.026rem;
|
||
|
width: 0.1875rem;
|
||
|
height: 0.4063rem;
|
||
|
background-color: #ff4e8d;
|
||
|
margin-left: 0.0521rem;
|
||
|
color: #fff;
|
||
|
font-size: 20px;
|
||
|
text-align: center;
|
||
|
line-height: 0.151rem;
|
||
|
cursor: pointer;
|
||
|
}
|
||
|
}
|
||
|
.tisp {
|
||
|
margin-top: 0.0521rem;
|
||
|
font-size: 0.0625rem;
|
||
|
color: #575d6c;
|
||
|
}
|
||
|
.submit {
|
||
|
margin-top: 0.1563rem;
|
||
|
display: flex;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
</style>
|