/**
|
* 距离计算 Mixin
|
* 提供地址选择和距离自动计算功能
|
*/
|
import { calculateDistance } from "@/api/map"
|
|
export default {
|
data() {
|
return {
|
// 地址坐标存储
|
addressCoordinates: {
|
start: null,
|
end: null
|
},
|
// 当前正在选择的地址类型
|
currentAddressType: '',
|
// 计算出的距离
|
calculatedDistance: null
|
}
|
},
|
methods: {
|
/**
|
* 设置起点坐标
|
* @param {Object} location - 位置对象 { lat, lng }
|
*/
|
setStartLocation(location) {
|
this.addressCoordinates.start = location
|
this.autoCalculateDistance()
|
},
|
|
/**
|
* 设置终点坐标
|
* @param {Object} location - 位置对象 { lat, lng }
|
*/
|
setEndLocation(location) {
|
this.addressCoordinates.end = location
|
this.autoCalculateDistance()
|
},
|
|
/**
|
* 通过地址选择结果设置坐标
|
* @param {String} type - 地址类型 'start' 或 'end'
|
* @param {Object} address - 地址对象 { title, address, lat, lng }
|
*/
|
setLocationByAddress(type, address) {
|
const location = {
|
lat: address.lat,
|
lng: address.lng
|
}
|
|
if (type === 'start') {
|
this.setStartLocation(location)
|
} else if (type === 'end') {
|
this.setEndLocation(location)
|
}
|
|
return location
|
},
|
|
/**
|
* 自动计算距离(当起点和终点都存在时)
|
*/
|
autoCalculateDistance() {
|
if (this.addressCoordinates.start && this.addressCoordinates.end) {
|
return this.getDistanceBetweenPoints(
|
this.addressCoordinates.start.lat,
|
this.addressCoordinates.start.lng,
|
this.addressCoordinates.end.lat,
|
this.addressCoordinates.end.lng
|
).then(distance => {
|
this.calculatedDistance = distance
|
// 触发距离计算完成事件
|
this.$emit && this.$emit('distance-calculated', distance)
|
return distance
|
}).catch(error => {
|
console.error('距离计算失败:', error)
|
return null
|
})
|
}
|
return Promise.resolve(null)
|
},
|
|
/**
|
* 计算两点之间的距离(公里)
|
* @param {Number} lat1 - 起点纬度
|
* @param {Number} lng1 - 起点经度
|
* @param {Number} lat2 - 终点纬度
|
* @param {Number} lng2 - 终点经度
|
* @returns {Promise<Number>} 距离(公里)
|
*/
|
getDistanceBetweenPoints(lat1, lng1, lat2, lng2) {
|
return new Promise((resolve, reject) => {
|
calculateDistance(lat1, lng1, lat2, lng2).then(response => {
|
if (response.code === 200) {
|
const responseData = typeof response.data === 'string'
|
? JSON.parse(response.data)
|
: response.data
|
|
if (responseData &&
|
responseData.status === 0 &&
|
responseData.result &&
|
responseData.result.elements &&
|
responseData.result.elements.length > 0) {
|
const distanceInKm = responseData.result.elements[0].distance / 1000
|
resolve(distanceInKm)
|
} else {
|
reject(new Error('距离计算接口返回数据格式不正确'))
|
}
|
} else {
|
reject(new Error('距离计算接口调用失败'))
|
}
|
}).catch(error => {
|
reject(error)
|
})
|
})
|
},
|
|
/**
|
* 清空地址坐标
|
*/
|
clearAddressCoordinates() {
|
this.addressCoordinates = {
|
start: null,
|
end: null
|
}
|
this.calculatedDistance = null
|
},
|
|
/**
|
* 格式化距离显示(保留2位小数)
|
* @param {Number} distance - 距离值
|
* @returns {String} 格式化后的距离
|
*/
|
formatDistance(distance) {
|
if (distance === null || distance === undefined) {
|
return ''
|
}
|
return parseFloat(distance).toFixed(2)
|
}
|
}
|
}
|