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.
429 lines
12 KiB
429 lines
12 KiB
<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>
|
|
|