|
|
@@ -8,53 +8,55 @@
|
|
|
<u-icon name="map" size="36rpx" color="#007AFF" marginRight="16rpx"></u-icon>
|
|
|
<text class="map-text">通过地图选择地址(可选)</text>
|
|
|
</view>
|
|
|
-
|
|
|
- <!-- 省/市/区三级地址(手动填写为主) -->
|
|
|
+
|
|
|
+ <!-- 省/市/区三级联动选择器 -->
|
|
|
<view class="form-item">
|
|
|
- <view class="item-label"> 所在省份 <text class="required">*</text></view>
|
|
|
- <u-input
|
|
|
- v-model="province"
|
|
|
- placeholder="请输入省份,例:广东省"
|
|
|
- clearable
|
|
|
- class="custom-input"
|
|
|
+ <view class="item-label">所在省份 <text class="required">*</text></view>
|
|
|
+ <picker
|
|
|
+ :range="provinces"
|
|
|
+ :range-key="'name'"
|
|
|
+ v-model="provinceIndex"
|
|
|
+ @change="onProvinceChange"
|
|
|
>
|
|
|
- <template #prefix>
|
|
|
- <u-icon name="location" size="36rpx" color="#999" marginRight="20rpx"></u-icon>
|
|
|
- </template>
|
|
|
- </u-input>
|
|
|
+ <view class="picker-view">
|
|
|
+ {{ provinceIndex !== null ? provinces[provinceIndex].name : '请选择省份' }}
|
|
|
+ </view>
|
|
|
+ </picker>
|
|
|
</view>
|
|
|
|
|
|
<view class="form-item">
|
|
|
- <view class="item-label"> 所在城市 <text class="required">*</text></view>
|
|
|
- <u-input
|
|
|
- v-model="city"
|
|
|
- placeholder="请输入城市,例:深圳市"
|
|
|
- clearable
|
|
|
- class="custom-input"
|
|
|
+ <view class="item-label">所在城市 <text class="required">*</text></view>
|
|
|
+ <picker
|
|
|
+ :range="cities"
|
|
|
+ :range-key="'name'"
|
|
|
+ v-model="cityIndex"
|
|
|
+ @change="onCityChange"
|
|
|
+ :disabled="provinceIndex === null"
|
|
|
>
|
|
|
- <template #prefix>
|
|
|
- <u-icon name="map-pin" size="36rpx" color="#999" marginRight="20rpx"></u-icon>
|
|
|
- </template>
|
|
|
- </u-input>
|
|
|
+ <view class="picker-view">
|
|
|
+ {{ cityIndex !== null && cities.length > 0 ? cities[cityIndex].name : '请先选择省份' }}
|
|
|
+ </view>
|
|
|
+ </picker>
|
|
|
</view>
|
|
|
|
|
|
<view class="form-item">
|
|
|
- <view class="item-label"> 所在区域 <text class="required">*</text></view>
|
|
|
- <u-input
|
|
|
- v-model="district"
|
|
|
- placeholder="请输入区域,例:南山区"
|
|
|
- clearable
|
|
|
- class="custom-input"
|
|
|
+ <view class="item-label">所在区域 <text class="required">*</text></view>
|
|
|
+ <picker
|
|
|
+ :range="districts"
|
|
|
+ :range-key="'name'"
|
|
|
+ v-model="districtIndex"
|
|
|
+ @change="onDistrictChange"
|
|
|
+ :disabled="cityIndex === null || cities.length === 0"
|
|
|
>
|
|
|
- <template #prefix>
|
|
|
- <u-icon name="map-marker" size="36rpx" color="#999" marginRight="20rpx"></u-icon>
|
|
|
- </template>
|
|
|
- </u-input>
|
|
|
+ <view class="picker-view">
|
|
|
+ {{ districtIndex !== null && districts.length > 0 ? districts[districtIndex].name : '请先选择城市' }}
|
|
|
+ </view>
|
|
|
+ </picker>
|
|
|
</view>
|
|
|
|
|
|
<!-- 详细地址信息 -->
|
|
|
<view class="form-item">
|
|
|
- <view class="item-label"> 街道/楼宇 <text class="required">*</text></view>
|
|
|
+ <view class="item-label">街道/楼宇 <text class="required">*</text></view>
|
|
|
<u-input
|
|
|
placeholder="请输入街道或楼宇名称,例:科技园路1号"
|
|
|
v-model="address"
|
|
|
@@ -68,7 +70,7 @@
|
|
|
</view>
|
|
|
|
|
|
<view class="form-item">
|
|
|
- <view class="item-label"> 楼层/单元室 </view>
|
|
|
+ <view class="item-label">楼层/单元室</view>
|
|
|
<u-input
|
|
|
placeholder="例:3层302室(选填)"
|
|
|
v-model="addressDetail"
|
|
|
@@ -93,12 +95,22 @@
|
|
|
|
|
|
<script>
|
|
|
import navBar from "@/components/nav-bar/index.vue";
|
|
|
+import addr from "@/utils/addr.json";
|
|
|
+
|
|
|
export default {
|
|
|
data() {
|
|
|
return {
|
|
|
- province: "", // 省份(必填)
|
|
|
- city: "", // 城市(必填)
|
|
|
- district: "", // 区域(必填)
|
|
|
+ // 三级联动数据
|
|
|
+ provinces: [], // 所有省份
|
|
|
+ cities: [], // 选中省份对应的城市
|
|
|
+ districts: [], // 选中城市对应的区域
|
|
|
+
|
|
|
+ // 选中索引
|
|
|
+ provinceIndex: null, // 选中的省份索引
|
|
|
+ cityIndex: null, // 选中的城市索引
|
|
|
+ districtIndex: null, // 选中的区域索引
|
|
|
+
|
|
|
+ // 地址信息
|
|
|
address: "", // 街道/楼宇(必填)
|
|
|
addressDetail: '', // 楼层/单元室(选填)
|
|
|
latitude: '', // 纬度(地图选点获取)
|
|
|
@@ -108,27 +120,98 @@ export default {
|
|
|
components: {
|
|
|
navBar,
|
|
|
},
|
|
|
+ // created() {
|
|
|
+ // // 初始化省份数据
|
|
|
+ // this.provinces = addr;
|
|
|
+ // },
|
|
|
onLoad(options) {
|
|
|
+ this.provinces = addr;
|
|
|
// 回显上一页传递的地址信息
|
|
|
- if (options.province) this.province = decodeURIComponent(options.province);
|
|
|
- if (options.city) this.city = decodeURIComponent(options.city);
|
|
|
- if (options.district) this.district = decodeURIComponent(options.district);
|
|
|
if (options.address) this.address = decodeURIComponent(options.address);
|
|
|
if (options.addressDetail) this.addressDetail = decodeURIComponent(options.addressDetail);
|
|
|
if (options.latitude) this.latitude = options.latitude;
|
|
|
if (options.longitude) this.longitude = options.longitude;
|
|
|
+
|
|
|
+ // 如果有省市区信息,进行回显
|
|
|
+ if (options.province && options.city && options.district) {
|
|
|
+ this.setAddressValue(
|
|
|
+ decodeURIComponent(options.province),
|
|
|
+ decodeURIComponent(options.city),
|
|
|
+ decodeURIComponent(options.district)
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
},
|
|
|
methods: {
|
|
|
- // 打开地图选择地址(辅助填充详细地址)
|
|
|
+ // 省份选择改变
|
|
|
+ onProvinceChange(e) {
|
|
|
+ const index = e.detail.value;
|
|
|
+ this.provinceIndex = index;
|
|
|
+
|
|
|
+ // 重置城市和区域选择
|
|
|
+ this.cityIndex = null;
|
|
|
+ this.districtIndex = null;
|
|
|
+
|
|
|
+ // 加载对应省份的城市
|
|
|
+ this.cities = this.provinces[index].children || [];
|
|
|
+
|
|
|
+ // 如果有城市数据,自动加载第一个城市的区域
|
|
|
+ if (this.cities.length > 0) {
|
|
|
+ this.districts = this.cities[0].children || [];
|
|
|
+ } else {
|
|
|
+ this.districts = [];
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 城市选择改变
|
|
|
+ onCityChange(e) {
|
|
|
+ const index = e.detail.value;
|
|
|
+ this.cityIndex = index;
|
|
|
+
|
|
|
+ // 重置区域选择
|
|
|
+ this.districtIndex = null;
|
|
|
+
|
|
|
+ // 加载对应城市的区域
|
|
|
+ this.districts = this.cities[index].children || [];
|
|
|
+ },
|
|
|
+
|
|
|
+ // 区域选择改变
|
|
|
+ onDistrictChange(e) {
|
|
|
+ this.districtIndex = e.detail.value;
|
|
|
+ },
|
|
|
+
|
|
|
+ // 根据省市区名称设置选择器值(用于回显)
|
|
|
+ setAddressValue(provinceName, cityName, districtName) {
|
|
|
+ // 查找省份索引
|
|
|
+ const provinceIndex = this.provinces.findIndex(item => item.name === provinceName);
|
|
|
+ if (provinceIndex !== -1) {
|
|
|
+ this.provinceIndex = provinceIndex;
|
|
|
+ this.cities = this.provinces[provinceIndex].children || [];
|
|
|
+
|
|
|
+ // 查找城市索引
|
|
|
+ const cityIndex = this.cities.findIndex(item => item.name === cityName);
|
|
|
+ if (cityIndex !== -1) {
|
|
|
+ this.cityIndex = cityIndex;
|
|
|
+ this.districts = this.cities[cityIndex].children || [];
|
|
|
+
|
|
|
+ // 查找区域索引
|
|
|
+ const districtIndex = this.districts.findIndex(item => item.name === districtName);
|
|
|
+ if (districtIndex !== -1) {
|
|
|
+ this.districtIndex = districtIndex;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 打开地图选择地址
|
|
|
openMapSelector() {
|
|
|
uni.chooseLocation({
|
|
|
success: (res) => {
|
|
|
- // 地图选点仅填充街道/楼宇信息,省市区留给用户手动确认
|
|
|
this.address = res.name || res.address;
|
|
|
this.latitude = res.latitude;
|
|
|
this.longitude = res.longitude;
|
|
|
|
|
|
- // 提示用户补充省市区信息
|
|
|
uni.showToast({
|
|
|
title: '请确认并补充省/市/区信息',
|
|
|
icon: 'none',
|
|
|
@@ -144,17 +227,22 @@ export default {
|
|
|
});
|
|
|
},
|
|
|
|
|
|
- // 确认地址并回传(严格验证三级地址)
|
|
|
+ // 确认地址并回传
|
|
|
confirmAddress() {
|
|
|
+ // 获取选中的省市区信息
|
|
|
+ const province = this.provinceIndex !== null ? this.provinces[this.provinceIndex].name : '';
|
|
|
+ const city = this.cityIndex !== null && this.cities.length > 0 ? this.cities[this.cityIndex].name : '';
|
|
|
+ const district = this.districtIndex !== null && this.districts.length > 0 ? this.districts[this.districtIndex].name : '';
|
|
|
+
|
|
|
// 验证必填项
|
|
|
- if (!this.province.trim()) {
|
|
|
- return uni.showToast({ title: '请输入所在省份', icon: 'none' });
|
|
|
+ if (!province) {
|
|
|
+ return uni.showToast({ title: '请选择省份', icon: 'none' });
|
|
|
}
|
|
|
- if (!this.city.trim()) {
|
|
|
- return uni.showToast({ title: '请输入所在城市', icon: 'none' });
|
|
|
+ if (!city) {
|
|
|
+ return uni.showToast({ title: '请选择城市', icon: 'none' });
|
|
|
}
|
|
|
- if (!this.district.trim()) {
|
|
|
- return uni.showToast({ title: '请输入所在区域', icon: 'none' });
|
|
|
+ if (!district) {
|
|
|
+ return uni.showToast({ title: '请选择区域', icon: 'none' });
|
|
|
}
|
|
|
if (!this.address.trim()) {
|
|
|
return uni.showToast({ title: '请输入街道或楼宇名称', icon: 'none' });
|
|
|
@@ -162,14 +250,14 @@ export default {
|
|
|
|
|
|
// 合并完整地址信息
|
|
|
const fullAddress = {
|
|
|
- province: this.province.trim(),
|
|
|
- city: this.city.trim(),
|
|
|
- district: this.district.trim(),
|
|
|
+ province,
|
|
|
+ city,
|
|
|
+ district,
|
|
|
address: this.address.trim(),
|
|
|
addressDetail: this.addressDetail.trim(),
|
|
|
latitude: this.latitude || '',
|
|
|
longitude: this.longitude || '',
|
|
|
- fullText: `${this.province.trim()}${this.city.trim()}${this.district.trim()}${this.address.trim()}${this.addressDetail.trim() ? ' ' + this.addressDetail.trim() : ''}`
|
|
|
+ fullText: `${province}${city}${district}${this.address.trim()}${this.addressDetail.trim() ? ' ' + this.addressDetail.trim() : ''}`
|
|
|
};
|
|
|
|
|
|
// 回传上一页
|
|
|
@@ -181,6 +269,31 @@ export default {
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
+/* 原有样式保持不变,添加以下选择器样式 */
|
|
|
+.picker-view {
|
|
|
+ box-sizing: border-box;
|
|
|
+ width: 100%;
|
|
|
+ border: 2rpx solid #9ea1a8;
|
|
|
+ border-radius: 100rpx;
|
|
|
+ padding: 8rpx 36rpx;
|
|
|
+ height: 96rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333;
|
|
|
+}
|
|
|
+
|
|
|
+picker {
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+/* 禁用状态样式 */
|
|
|
+picker:disabled .picker-view {
|
|
|
+ color: #999;
|
|
|
+ background-color: #f5f5f5;
|
|
|
+}
|
|
|
+
|
|
|
+/* 其他原有样式保持不变 */
|
|
|
.switch-roles {
|
|
|
background-color: #fff;
|
|
|
position: absolute;
|
|
|
@@ -250,24 +363,23 @@ export default {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
.custom-input {
|
|
|
box-sizing: border-box;
|
|
|
border: 2rpx solid #9ea1a8;
|
|
|
border-radius: 100rpx;
|
|
|
- /* 增加左右内边距,让内容更舒展 */
|
|
|
padding: 8rpx 36rpx;
|
|
|
height: 96rpx;
|
|
|
}
|
|
|
|
|
|
-/* 调整图标与输入文字的间距 */
|
|
|
::v-deep .u-input__prefix {
|
|
|
- margin-right: 24rpx !important; /* 增加图标右侧间距 */
|
|
|
+ margin-right: 24rpx !important;
|
|
|
}
|
|
|
|
|
|
-/* 输入框文字区域增加左侧间距(配合图标) */
|
|
|
::v-deep .u-input input {
|
|
|
- padding-left: 32rpx; /* 避免文字紧贴图标 */
|
|
|
+ padding-left: 32rpx;
|
|
|
}
|
|
|
+
|
|
|
.form-item {
|
|
|
margin-bottom: 26rpx;
|
|
|
width: 100%;
|
|
|
@@ -281,15 +393,6 @@ export default {
|
|
|
align-items: center;
|
|
|
}
|
|
|
|
|
|
-.custom-input {
|
|
|
- box-sizing: border-box;
|
|
|
- border: 2rpx solid #9ea1a8;
|
|
|
- border-radius: 100rpx;
|
|
|
- padding: 8rpx 24rpx;
|
|
|
- height: 96rpx;
|
|
|
-}
|
|
|
-
|
|
|
-/* 输入框聚焦样式 */
|
|
|
::v-deep .u-input input:focus {
|
|
|
border-color: #007AFF !important;
|
|
|
outline: none;
|