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