|
|
@ -29,12 +29,33 @@ |
|
|
|
<scroll-view scroll-y class="scroll-view"> |
|
|
|
<!-- 二级地址 --> |
|
|
|
<template v-if="selectedProvince && !selectedCity"> |
|
|
|
<!-- 选择整个省份选项 --> |
|
|
|
<view |
|
|
|
v-if="showSelectWholeCity" |
|
|
|
class="address-item whole-city-item" |
|
|
|
@click="selectWholeProvince"> |
|
|
|
<uv-icon name="checkmark-circle" size="30rpx" color="#3796F8"></uv-icon> |
|
|
|
选择整个{{ selectedProvince.adress }} |
|
|
|
</view> |
|
|
|
|
|
|
|
<view |
|
|
|
class="address-item" |
|
|
|
:class="{ |
|
|
|
'selected': multiple && isCitySelected(item), |
|
|
|
'active': !multiple && selectedCity && selectedCity.id === item.id |
|
|
|
}" |
|
|
|
v-for="item in cityList" |
|
|
|
:key="item.id" |
|
|
|
@click="selectCity(item)"> |
|
|
|
{{ item.adress }} |
|
|
|
<uv-icon v-if="multiple && isCitySelected(item)" |
|
|
|
name="checkmark-circle" size="30rpx" color="#3796F8"></uv-icon> |
|
|
|
</view> |
|
|
|
|
|
|
|
<!-- 多选时的确认按钮 --> |
|
|
|
<view v-if="multiple && selectedCities.length > 0" |
|
|
|
class="confirm-btn" @click="confirmMultipleCitySelection"> |
|
|
|
<button class="confirm-button">确认选择城市 ({{ selectedCities.length }})</button> |
|
|
|
</view> |
|
|
|
</template> |
|
|
|
|
|
|
@ -46,12 +67,34 @@ |
|
|
|
<uv-icon name="arrow-left" size="30rpx"></uv-icon> |
|
|
|
返回{{ selectedProvince.adress }} |
|
|
|
</view> |
|
|
|
|
|
|
|
<!-- 选择整个城市选项 --> |
|
|
|
<view |
|
|
|
v-if="showSelectWholeCity" |
|
|
|
class="address-item whole-city-item" |
|
|
|
@click="selectWholeCity"> |
|
|
|
<uv-icon name="checkmark-circle" size="30rpx" color="#3796F8"></uv-icon> |
|
|
|
选择整个{{ selectedCity.adress }} |
|
|
|
</view> |
|
|
|
|
|
|
|
<view |
|
|
|
class="address-item" |
|
|
|
:class="{ |
|
|
|
'selected': multiple && isDistrictSelected(item), |
|
|
|
'active': !multiple && selectedDistrict && selectedDistrict.id === item.id |
|
|
|
}" |
|
|
|
v-for="item in districtList" |
|
|
|
:key="item.id" |
|
|
|
@click="selectDistrict(item)"> |
|
|
|
{{ item.adress }} |
|
|
|
<uv-icon v-if="multiple && isDistrictSelected(item)" |
|
|
|
name="checkmark-circle" size="30rpx" color="#3796F8"></uv-icon> |
|
|
|
</view> |
|
|
|
|
|
|
|
<!-- 多选时的确认按钮 --> |
|
|
|
<view v-if="multiple && selectedDistricts.length > 0" |
|
|
|
class="confirm-btn" @click="confirmMultipleSelection"> |
|
|
|
<button class="confirm-button">确认选择 ({{ selectedDistricts.length }})</button> |
|
|
|
</view> |
|
|
|
</template> |
|
|
|
</scroll-view> |
|
|
@ -71,6 +114,16 @@ |
|
|
|
onlyCity: { |
|
|
|
type: Boolean, |
|
|
|
default: false |
|
|
|
}, |
|
|
|
// 是否支持多选区县 |
|
|
|
multiple: { |
|
|
|
type: Boolean, |
|
|
|
default: false |
|
|
|
}, |
|
|
|
// 是否显示"选择整个城市"选项 |
|
|
|
showSelectWholeCity: { |
|
|
|
type: Boolean, |
|
|
|
default: false |
|
|
|
} |
|
|
|
}, |
|
|
|
data() { |
|
|
@ -78,6 +131,8 @@ |
|
|
|
selectedProvince: null, // 选中的省份 |
|
|
|
selectedCity: null, // 选中的城市 |
|
|
|
selectedDistrict: null, // 选中的区县 |
|
|
|
selectedCities: [], // 多选时选中的城市列表 |
|
|
|
selectedDistricts: [], // 多选时选中的区县列表 |
|
|
|
cityList: [], // 城市列表 |
|
|
|
districtList: [], // 区县列表 |
|
|
|
} |
|
|
@ -101,6 +156,8 @@ |
|
|
|
this.selectedProvince = null |
|
|
|
this.selectedCity = null |
|
|
|
this.selectedDistrict = null |
|
|
|
this.selectedCities = [] |
|
|
|
this.selectedDistricts = [] |
|
|
|
this.cityList = [] |
|
|
|
this.districtList = [] |
|
|
|
}, |
|
|
@ -129,33 +186,96 @@ |
|
|
|
|
|
|
|
// 选择城市 |
|
|
|
async selectCity(city) { |
|
|
|
this.selectedCity = city |
|
|
|
this.selectedDistrict = null |
|
|
|
|
|
|
|
// 如果只选择到市级,直接确认 |
|
|
|
if (this.onlyCity) { |
|
|
|
this.confirm() |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
// 获取区县列表 |
|
|
|
try { |
|
|
|
this.districtList = await this.$store.dispatch('getChildAddressList', city.id) |
|
|
|
// 如果没有下级地址,直接确认 |
|
|
|
if (this.districtList.length === 0) { |
|
|
|
if (this.multiple) { |
|
|
|
// 多选模式 |
|
|
|
const index = this.selectedCities.findIndex(item => item.id === city.id) |
|
|
|
if (index > -1) { |
|
|
|
// 取消选择 |
|
|
|
this.selectedCities.splice(index, 1) |
|
|
|
} else { |
|
|
|
// 添加选择 |
|
|
|
this.selectedCities.push(city) |
|
|
|
} |
|
|
|
} else { |
|
|
|
// 单选模式 |
|
|
|
this.selectedCity = city |
|
|
|
this.selectedDistrict = null |
|
|
|
|
|
|
|
// 如果只选择到市级,直接确认 |
|
|
|
if (this.onlyCity) { |
|
|
|
this.confirm() |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
// 获取区县列表 |
|
|
|
try { |
|
|
|
this.districtList = await this.$store.dispatch('getChildAddressList', city.id) |
|
|
|
// 如果没有下级地址,直接确认 |
|
|
|
if (this.districtList.length === 0) { |
|
|
|
this.confirm() |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
console.error('获取区县列表失败:', error) |
|
|
|
this.districtList = [] |
|
|
|
// 获取失败时也直接确认 |
|
|
|
this.confirm() |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
console.error('获取区县列表失败:', error) |
|
|
|
this.districtList = [] |
|
|
|
// 获取失败时也直接确认 |
|
|
|
this.confirm() |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
// 选择区县 |
|
|
|
selectDistrict(district) { |
|
|
|
this.selectedDistrict = district |
|
|
|
if (this.multiple) { |
|
|
|
// 多选模式 |
|
|
|
const index = this.selectedDistricts.findIndex(item => item.id === district.id) |
|
|
|
if (index > -1) { |
|
|
|
// 取消选择 |
|
|
|
this.selectedDistricts.splice(index, 1) |
|
|
|
} else { |
|
|
|
// 添加选择 |
|
|
|
this.selectedDistricts.push(district) |
|
|
|
} |
|
|
|
} else { |
|
|
|
// 单选模式 |
|
|
|
this.selectedDistrict = district |
|
|
|
this.confirm() |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
// 检查城市是否被选中(多选模式) |
|
|
|
isCitySelected(city) { |
|
|
|
return this.selectedCities.some(item => item.id === city.id) |
|
|
|
}, |
|
|
|
|
|
|
|
// 检查区县是否被选中(多选模式) |
|
|
|
isDistrictSelected(district) { |
|
|
|
return this.selectedDistricts.some(item => item.id === district.id) |
|
|
|
}, |
|
|
|
|
|
|
|
// 选择整个省份 |
|
|
|
selectWholeProvince() { |
|
|
|
this.selectedCity = null |
|
|
|
this.selectedCities = [] |
|
|
|
this.selectedDistrict = null |
|
|
|
this.selectedDistricts = [] |
|
|
|
this.confirm() |
|
|
|
}, |
|
|
|
|
|
|
|
// 选择整个城市 |
|
|
|
selectWholeCity() { |
|
|
|
this.selectedDistrict = null |
|
|
|
this.selectedDistricts = [] |
|
|
|
this.confirm() |
|
|
|
}, |
|
|
|
|
|
|
|
// 确认多选城市选择 |
|
|
|
confirmMultipleCitySelection() { |
|
|
|
// 直接返回多选城市的数据 |
|
|
|
this.confirm() |
|
|
|
}, |
|
|
|
|
|
|
|
// 确认多选选择 |
|
|
|
confirmMultipleSelection() { |
|
|
|
this.confirm() |
|
|
|
}, |
|
|
|
|
|
|
@ -171,7 +291,9 @@ |
|
|
|
const result = { |
|
|
|
province: this.selectedProvince, |
|
|
|
city: this.selectedCity, |
|
|
|
district: this.selectedDistrict |
|
|
|
district: this.selectedDistrict, |
|
|
|
cities: this.selectedCities, |
|
|
|
districts: this.selectedDistricts |
|
|
|
} |
|
|
|
|
|
|
|
// 生成完整地址文本 |
|
|
@ -179,15 +301,36 @@ |
|
|
|
if (this.selectedProvince) { |
|
|
|
fullAddress += this.selectedProvince.adress |
|
|
|
} |
|
|
|
if (this.selectedCity) { |
|
|
|
|
|
|
|
// 多选城市模式 |
|
|
|
if (this.multiple && this.selectedCities.length > 0) { |
|
|
|
const cityNames = this.selectedCities.map(item => item.adress).join(',') |
|
|
|
fullAddress += cityNames |
|
|
|
result.selectedAddress = this.selectedProvince // 多选城市时返回省份作为选中地址 |
|
|
|
result.selectedCities = this.selectedCities |
|
|
|
} else if (this.selectedCity) { |
|
|
|
fullAddress += this.selectedCity.adress |
|
|
|
} |
|
|
|
if (this.selectedDistrict) { |
|
|
|
fullAddress += this.selectedDistrict.adress |
|
|
|
|
|
|
|
// 多选区县模式 |
|
|
|
if (this.multiple && this.selectedDistricts.length > 0) { |
|
|
|
const districtNames = this.selectedDistricts.map(item => item.adress).join(',') |
|
|
|
fullAddress += districtNames |
|
|
|
result.selectedAddress = this.selectedCity // 多选时返回城市作为选中地址 |
|
|
|
result.selectedDistricts = this.selectedDistricts |
|
|
|
} else if (this.selectedDistrict) { |
|
|
|
// 单选区县模式 |
|
|
|
fullAddress += this.selectedDistrict.adress |
|
|
|
result.selectedAddress = this.selectedDistrict |
|
|
|
} else { |
|
|
|
// 选择整个城市 |
|
|
|
result.selectedAddress = this.selectedCity |
|
|
|
} |
|
|
|
} else { |
|
|
|
// 选择整个省份 |
|
|
|
result.selectedAddress = this.selectedProvince |
|
|
|
} |
|
|
|
|
|
|
|
result.fullAddress = fullAddress |
|
|
|
result.selectedAddress = this.selectedDistrict || this.selectedCity || this.selectedProvince |
|
|
|
|
|
|
|
this.$emit('confirm', result) |
|
|
|
this.close() |
|
|
@ -274,6 +417,53 @@ |
|
|
|
margin-right: 10rpx; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
&.whole-city-item { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
color: #3796F8; |
|
|
|
background: rgba(#3796F8, 0.1); |
|
|
|
font-weight: bold; |
|
|
|
|
|
|
|
uv-icon { |
|
|
|
margin-right: 10rpx; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
&.selected { |
|
|
|
background: rgba($uni-color, 0.1); |
|
|
|
color: $uni-color; |
|
|
|
font-weight: bold; |
|
|
|
position: relative; |
|
|
|
|
|
|
|
&::after { |
|
|
|
content: ''; |
|
|
|
position: absolute; |
|
|
|
right: 0; |
|
|
|
top: 0; |
|
|
|
bottom: 0; |
|
|
|
width: 6rpx; |
|
|
|
background: $uni-color; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.confirm-btn { |
|
|
|
position: sticky; |
|
|
|
bottom: 0; |
|
|
|
background: #fff; |
|
|
|
padding: 20rpx; |
|
|
|
border-top: 1px solid #eee; |
|
|
|
|
|
|
|
.confirm-button { |
|
|
|
width: 100%; |
|
|
|
background: $uni-color; |
|
|
|
color: #fff; |
|
|
|
border: none; |
|
|
|
border-radius: 10rpx; |
|
|
|
padding: 20rpx; |
|
|
|
font-size: 28rpx; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |