From 132eb9b06347ddef87029fa90ae7fbe46d94e832 Mon Sep 17 00:00:00 2001
From: aaron <>
Date: Sun, 16 Mar 2025 15:00:00 +0800
Subject: [PATCH] update
---
src/components/MapPicker/index.vue | 385 +++++++++++++++--------------
1 file changed, 202 insertions(+), 183 deletions(-)
diff --git a/src/components/MapPicker/index.vue b/src/components/MapPicker/index.vue
index 0d6a58f..21ac550 100644
--- a/src/components/MapPicker/index.vue
+++ b/src/components/MapPicker/index.vue
@@ -2,60 +2,62 @@
-
-
-
-
+
-
-
+
+
+
+ {{ option.label }}
+
+
+
+
+
+
地址搜索仅作为辅助填写小区地址的工具
+
+
+
+
-
-
-
-
-
+
+
-
在地图上点击选择准确位置,或通过上方搜索框搜索地址
+
+
+
+
-
-
-
- 地址将用于配送员导航和定位,请确保准确
-
-
-
-
@@ -193,73 +195,11 @@ export default {
const searchOptions = ref([])
const searchLoading = ref(false)
- // 省市选择
- const provinceOptions = ref(fallbackProvinces)
- const cityOptions = ref([])
- const selectedProvince = ref('')
- const selectedCity = ref('')
-
// 双向绑定的值
const address = ref(props.modelValue.address)
const longitude = ref(props.modelValue.longitude)
const latitude = ref(props.modelValue.latitude)
- // 下拉框筛选函数
- const filterOption = (input, option) => {
- return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
- }
-
- // 处理省份变化
- const handleProvinceChange = (value) => {
- selectedProvince.value = value
- selectedCity.value = ''
-
- // 获取城市数据
- cityOptions.value = fallbackCitiesMap[value] || []
-
- // 如果有地图实例,尝试定位到选择的省份
- if (map.value) {
- try {
- // 使用地理编码获取省份中心点
- const geocoder = createGeocoder()
- geocoder.getLocation(value, (status, result) => {
- if (status === 'complete' && result.info === 'OK' && result.geocodes.length > 0) {
- const location = result.geocodes[0].location
- map.value.setCenter([location.lng, location.lat])
- map.value.setZoom(8) // 省级层面,缩放级别设置为8
- }
- })
- } catch (error) {
- console.error('设置地图中心点失败:', error)
- }
- }
- }
-
- // 处理城市变化
- const handleCityChange = (value) => {
- selectedCity.value = value
-
- // 如果有地图实例,定位到选择的城市
- if (map.value) {
- try {
- // 使用地理编码获取城市中心点
- const geocoder = createGeocoder()
- geocoder.getLocation(value, (status, result) => {
- if (status === 'complete' && result.info === 'OK' && result.geocodes.length > 0) {
- const location = result.geocodes[0].location
- map.value.setCenter([location.lng, location.lat])
- map.value.setZoom(12) // 城市级别,缩放级别设置为12
-
- // 清空搜索框,准备输入详细地址
- searchAddress.value = ''
- }
- })
- } catch (error) {
- console.error('设置地图中心点失败:', error)
- }
- }
- }
-
// 监听props变化
watch(() => props.modelValue, (newVal, oldVal) => {
console.log('props变化:', newVal, oldVal)
@@ -302,24 +242,13 @@ export default {
const city = addressComponent.city
// 更新省份选择
- const foundProvince = provinceOptions.value.find(p =>
+ const foundProvince = fallbackProvinces.find(p =>
province.includes(p.value) || p.value.includes(province)
)
if (foundProvince) {
- selectedProvince.value = foundProvince.value
-
- // 更新城市选择
- cityOptions.value = fallbackCitiesMap[foundProvince.value] || []
-
- if (city) {
- const foundCity = cityOptions.value.find(c =>
- city.includes(c.value) || c.value.includes(city)
- )
- if (foundCity) {
- selectedCity.value = foundCity.value
- }
- }
+ longitude.value = newVal.longitude
+ latitude.value = newVal.latitude
}
}
}
@@ -349,7 +278,8 @@ export default {
emit('update:modelValue', {
address: address.value,
longitude: longitude.value,
- latitude: latitude.value
+ latitude: latitude.value,
+ isValid: !!address.value && !!longitude.value && !!latitude.value
})
}
}
@@ -410,34 +340,21 @@ export default {
const city = addressComponent.city
// 更新省份选择
- const foundProvince = provinceOptions.value.find(p =>
+ const foundProvince = fallbackProvinces.find(p =>
province.includes(p.value) || p.value.includes(province)
)
if (foundProvince) {
- selectedProvince.value = foundProvince.value
-
- // 更新城市选择
- cityOptions.value = fallbackCitiesMap[foundProvince.value] || []
-
- if (city) {
- const foundCity = cityOptions.value.find(c =>
- city.includes(c.value) || c.value.includes(city)
- )
- if (foundCity) {
- selectedCity.value = foundCity.value
- }
- }
+ longitude.value = lng
+ latitude.value = lat
}
}
updateValue()
} else {
// 如果获取地址失败,使用经纬度作为地址
- if (selectedCity.value) {
- address.value = `${selectedProvince.value} ${selectedCity.value} (${lng.toFixed(6)},${lat.toFixed(6)})`
- } else if (selectedProvince.value) {
- address.value = `${selectedProvince.value} (${lng.toFixed(6)},${lat.toFixed(6)})`
+ if (latitude.value) {
+ address.value = `${fallbackProvinces.find(p => p.value === latitude.value.split(' ')[0]).label} (${lng.toFixed(6)},${lat.toFixed(6)})`
} else {
address.value = `位置坐标: ${lng.toFixed(6)},${lat.toFixed(6)}`
}
@@ -498,25 +415,18 @@ export default {
}
const autoComplete = createAutoComplete({
- city: selectedCity.value || selectedProvince.value || '全国',
- citylimit: !!selectedCity.value
+ city: '全国',
+ citylimit: false
})
- // 构建搜索关键词,包含省市信息
- let keyword = value
- if (selectedCity.value) {
- keyword = `${selectedCity.value} ${value}`
- } else if (selectedProvince.value) {
- keyword = `${selectedProvince.value} ${value}`
- }
-
- autoComplete.search(keyword, (status, result) => {
+ autoComplete.search(value, (status, result) => {
if (status === 'complete' && result.tips && result.tips.length > 0) {
searchOptions.value = result.tips.map(tip => ({
value: tip.name,
label: `${tip.name} (${tip.district || ''})`,
location: tip.location
}))
+ console.log('搜索结果:', searchOptions.value)
} else {
// 如果搜索失败,添加一个手动输入选项
searchOptions.value = [{
@@ -542,22 +452,36 @@ export default {
}
}
+ // 地址输入变化
+ const handleAddressChange = (e) => {
+ // 从事件对象中获取值
+ const value = e.target.value
+
+ // 保存输入值
+ searchAddress.value = value
+
+ // 如果清空输入,也清空选项
+ if (!value) {
+ searchOptions.value = []
+ }
+ }
+
// 选择地址
const handleSelect = (value, option) => {
+ // 清空搜索结果
+ searchOptions.value = []
+
// 直接使用选中的值作为地址
address.value = value
- // 查找选中的地址信息
- const selected = searchOptions.value.find(opt => opt.value === value)
-
// 如果是手动输入的地址,或者没有位置信息
- if (!selected || selected.manualInput || !selected.location) {
+ if (!option || option.manualInput || !option.location) {
message.info('请在地图上选择具体位置')
updateValue()
return
}
- const { lng, lat } = selected.location
+ const { lng, lat } = option.location
// 更新标记位置
updateMarkerPosition(lng, lat)
@@ -582,24 +506,13 @@ export default {
const city = addressComponent.city
// 更新省份选择
- const foundProvince = provinceOptions.value.find(p =>
+ const foundProvince = fallbackProvinces.find(p =>
province.includes(p.value) || p.value.includes(province)
)
if (foundProvince) {
- selectedProvince.value = foundProvince.value
-
- // 更新城市选择
- cityOptions.value = fallbackCitiesMap[foundProvince.value] || []
-
- if (city) {
- const foundCity = cityOptions.value.find(c =>
- city.includes(c.value) || c.value.includes(city)
- )
- if (foundCity) {
- selectedCity.value = foundCity.value
- }
- }
+ longitude.value = lng
+ latitude.value = lat
}
}
}
@@ -630,14 +543,7 @@ export default {
latitude,
handleSearch,
handleSelect,
- // 省市选择相关
- provinceOptions,
- cityOptions,
- selectedProvince,
- selectedCity,
- handleProvinceChange,
- handleCityChange,
- filterOption
+ handleAddressChange
}
}
}
@@ -653,18 +559,69 @@ export default {
flex-direction: column;
gap: 12px;
margin-bottom: 8px;
+ position: relative;
}
-.region-selector {
+.search-input-group {
display: flex;
- justify-content: space-between;
gap: 8px;
+ align-items: stretch;
+ height: 32px;
+ position: relative;
+ z-index: 1;
}
.map-picker-input {
+ flex: 1;
+ background: transparent;
+}
+
+.search-tip {
+ font-size: 12px;
+ color: #999;
+ margin-top: 4px;
+ margin-bottom: 8px;
+ font-style: italic;
+}
+
+.search-results {
+ position: absolute;
+ top: 40px;
+ left: 0;
+ right: 0;
+ z-index: 1001;
+ background: white;
+ max-height: 300px;
+ overflow-y: auto;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
+ border-radius: 4px;
+ border: 1px solid #d9d9d9;
+}
+
+.search-results-list {
+ display: flex;
+ flex-direction: column;
width: 100%;
}
+.search-result-item {
+ cursor: pointer;
+ padding: 10px 12px;
+ transition: background-color 0.3s;
+ border-bottom: 1px solid #f0f0f0;
+ line-height: 1.5;
+ width: 100%;
+ text-align: left;
+}
+
+.search-result-item:last-child {
+ border-bottom: none;
+}
+
+.search-result-item:hover {
+ background-color: #f5f5f5;
+}
+
.map-container {
border: 1px solid #d9d9d9;
border-radius: 4px;
@@ -674,6 +631,37 @@ export default {
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
+.address-display {
+ margin-top: 8px;
+}
+
+.address-label {
+ margin-bottom: 4px;
+ font-size: 14px;
+ color: rgba(0, 0, 0, 0.85);
+}
+
+.required-mark {
+ color: #ff4d4f;
+ margin-right: 4px;
+}
+
+.address-input {
+ width: 100%;
+}
+
+:deep(.address-input .ant-input) {
+ background-color: #f5f5f5;
+ cursor: default;
+ color: #333;
+ font-weight: 500;
+}
+
+:deep(.address-input .ant-input:hover),
+:deep(.address-input .ant-input:focus) {
+ background-color: #f0f0f0;
+}
+
.form-item-tip {
margin-top: 8px;
font-size: 0.8em;
@@ -693,7 +681,38 @@ export default {
padding: 6px 12px;
}
+:deep(.ant-input-affix-wrapper),
+:deep(.ant-btn) {
+ height: 32px;
+}
+
:deep(.ant-input-affix-wrapper) {
border-radius: 4px;
+ display: flex;
+ align-items: center;
+ background: white;
+ border: 1px solid #d9d9d9;
+ overflow: hidden;
+}
+
+:deep(.ant-input-affix-wrapper:hover) {
+ border-color: #40a9ff;
+}
+
+:deep(.ant-input-affix-wrapper-focused) {
+ border-color: #40a9ff;
+ box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
+}
+
+:deep(.ant-btn) {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0 15px;
+}
+
+:deep(.ant-input) {
+ height: 100%;
+ background: transparent;
}
\ No newline at end of file