|
@@ -250,47 +250,23 @@
|
|
|
<FamilyEmptyState type="card" />
|
|
<FamilyEmptyState type="card" />
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
- <!-- 区域选择弹窗(省市区三级联动) -->
|
|
|
|
|
- <view class="region-mask" v-if="showRegionPicker" @click="cancelRegion">
|
|
|
|
|
- <view class="region-picker" @click.stop>
|
|
|
|
|
- <view class="region-header">
|
|
|
|
|
- <text class="region-header-btn" @click="cancelRegion">取消</text>
|
|
|
|
|
- <text class="region-header-title">选择地区</text>
|
|
|
|
|
- <text class="region-header-btn region-confirm" @click="confirmRegion">确定</text>
|
|
|
|
|
- </view>
|
|
|
|
|
- <view class="region-breadcrumb">
|
|
|
|
|
- <text
|
|
|
|
|
- v-for="(name, i) in regionBreadcrumb"
|
|
|
|
|
- :key="i"
|
|
|
|
|
- :class="['crumb-item', i === currentRegionLevel ? 'crumb-active' : '']"
|
|
|
|
|
- @click="jumpRegionLevel(i)"
|
|
|
|
|
- >{{ name || '请选择' }}</text>
|
|
|
|
|
- <text class="crumb-arrow" v-if="currentRegionLevel < 2">›</text>
|
|
|
|
|
- </view>
|
|
|
|
|
- <scroll-view class="region-list" scroll-y>
|
|
|
|
|
- <view
|
|
|
|
|
- v-for="(item, idx) in currentRegionItems"
|
|
|
|
|
- :key="idx"
|
|
|
|
|
- :class="['region-item', isRegionSelected(item) ? 'region-item-selected' : '']"
|
|
|
|
|
- @click="selectRegionItem(item)"
|
|
|
|
|
- >
|
|
|
|
|
- <text class="region-item-text">{{ getRegionName(item) }}</text>
|
|
|
|
|
- <text class="region-item-check" v-if="isRegionSelected(item)">✓</text>
|
|
|
|
|
- </view>
|
|
|
|
|
- <view v-if="regionLoading" class="region-loading">
|
|
|
|
|
- <text>加载中...</text>
|
|
|
|
|
- </view>
|
|
|
|
|
- </scroll-view>
|
|
|
|
|
- </view>
|
|
|
|
|
- </view>
|
|
|
|
|
|
|
+ <!-- 区域选择弹窗:统一使用 components/address-picker.vue(3 级省市区) -->
|
|
|
|
|
+ <address-picker
|
|
|
|
|
+ ref="addressPicker"
|
|
|
|
|
+ :levels="3"
|
|
|
|
|
+ :show-trigger="false"
|
|
|
|
|
+ :initial="regionInitial"
|
|
|
|
|
+ @change="onRegionChange"
|
|
|
|
|
+ />
|
|
|
</view>
|
|
</view>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
<script>
|
|
|
import { updateUserInfo, createFamily, directRegister, getUserInfo, requestJoinByCode, getMyMembership, bindReferralIfNotSelf } from '../../utils/api.js'
|
|
import { updateUserInfo, createFamily, directRegister, getUserInfo, requestJoinByCode, getMyMembership, bindReferralIfNotSelf } from '../../utils/api.js'
|
|
|
-import config from '@/config.js'
|
|
|
|
|
|
|
+import AddressPicker from '@/components/address-picker.vue'
|
|
|
|
|
|
|
|
export default {
|
|
export default {
|
|
|
|
|
+ components: { AddressPicker },
|
|
|
data() {
|
|
data() {
|
|
|
return {
|
|
return {
|
|
|
isEdit: false,
|
|
isEdit: false,
|
|
@@ -325,16 +301,6 @@ export default {
|
|
|
district: '',
|
|
district: '',
|
|
|
street: ''
|
|
street: ''
|
|
|
},
|
|
},
|
|
|
- // 区域选择弹窗(省市区三级联动,与订单收货人地址一致)
|
|
|
|
|
- showRegionPicker: false,
|
|
|
|
|
- currentRegionLevel: 0, // 0=省份, 1=城市, 2=区县
|
|
|
|
|
- regionLoading: false,
|
|
|
|
|
- provinceList: [],
|
|
|
|
|
- cityList: [],
|
|
|
|
|
- districtList: [],
|
|
|
|
|
- tempProvince: null,
|
|
|
|
|
- tempCity: null,
|
|
|
|
|
- tempDistrict: null,
|
|
|
|
|
ethnicityOptions: ['汉族','蒙古族','回族','藏族','维吾尔族','苗族','彝族','壮族','布依族','朝鲜族','满族','侗族','瑶族','白族','土家族','哈尼族','哈萨克族','傣族','黎族','其他'],
|
|
ethnicityOptions: ['汉族','蒙古族','回族','藏族','维吾尔族','苗族','彝族','壮族','布依族','朝鲜族','满族','侗族','瑶族','白族','土家族','哈尼族','哈萨克族','傣族','黎族','其他'],
|
|
|
bloodTypeOptions: ['A','B','AB','O','未知'],
|
|
bloodTypeOptions: ['A','B','AB','O','未知'],
|
|
|
birthHourOptions: ['子时(23-01)','丑时(01-03)','寅时(03-05)','卯时(05-07)','辰时(07-09)','巳时(09-11)','午时(11-13)','未时(13-15)','申时(15-17)','酉时(17-19)','戌时(19-21)','亥时(21-23)'],
|
|
birthHourOptions: ['子时(23-01)','丑时(01-03)','寅时(03-05)','卯时(05-07)','辰时(07-09)','巳时(09-11)','午时(11-13)','未时(13-15)','申时(15-17)','酉时(17-19)','戌时(19-21)','亥时(21-23)'],
|
|
@@ -375,19 +341,14 @@ export default {
|
|
|
if (this.token) return true
|
|
if (this.token) return true
|
|
|
return this.$store.getters.hasFamily
|
|
return this.$store.getters.hasFamily
|
|
|
},
|
|
},
|
|
|
- regionBreadcrumb: function() {
|
|
|
|
|
- var names = []
|
|
|
|
|
- names.push(this.tempProvince ? this.getRegionName(this.tempProvince) : '省份')
|
|
|
|
|
- names.push(this.tempCity ? this.getRegionName(this.tempCity) : '城市')
|
|
|
|
|
- names.push(this.tempDistrict ? this.getRegionName(this.tempDistrict) : '区县')
|
|
|
|
|
- return names
|
|
|
|
|
- },
|
|
|
|
|
- currentRegionItems: function() {
|
|
|
|
|
- if (this.currentRegionLevel === 0) return this.provinceList
|
|
|
|
|
- if (this.currentRegionLevel === 1) return this.cityList
|
|
|
|
|
- if (this.currentRegionLevel === 2) return this.districtList
|
|
|
|
|
- return []
|
|
|
|
|
- },
|
|
|
|
|
|
|
+ // 编辑回显:把已保存的省/市/区县名称传给统一地址组件,打开时按名称回选
|
|
|
|
|
+ regionInitial() {
|
|
|
|
|
+ return {
|
|
|
|
|
+ province: this.form.province || '',
|
|
|
|
|
+ city: this.form.city || '',
|
|
|
|
|
+ district: this.form.district || ''
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
},
|
|
},
|
|
|
onLoad(options) {
|
|
onLoad(options) {
|
|
|
// 注册零填写改造:本页仅保留「个人中心编辑资料」用途
|
|
// 注册零填写改造:本页仅保留「个人中心编辑资料」用途
|
|
@@ -486,135 +447,17 @@ export default {
|
|
|
goUpgrade() {
|
|
goUpgrade() {
|
|
|
uni.navigateTo({ url: '/pages/membership/upgrade' })
|
|
uni.navigateTo({ url: '/pages/membership/upgrade' })
|
|
|
},
|
|
},
|
|
|
- // ===== 省市区三级联动弹窗(与订单收货人地址一致) =====
|
|
|
|
|
|
|
+ // ===== 区域选择(统一组件 components/address-picker.vue) =====
|
|
|
openRegionPicker() {
|
|
openRegionPicker() {
|
|
|
- this.tempProvince = this.form.province ? { name: this.form.province, id: null } : null
|
|
|
|
|
- this.tempCity = this.form.city ? { name: this.form.city, id: null } : null
|
|
|
|
|
- this.tempDistrict = this.form.district ? { name: this.form.district, id: null } : null
|
|
|
|
|
- this.currentRegionLevel = 0
|
|
|
|
|
- this.showRegionPicker = true
|
|
|
|
|
- this.loadRegionProvinces()
|
|
|
|
|
- },
|
|
|
|
|
- loadRegionProvinces() {
|
|
|
|
|
- var self = this
|
|
|
|
|
- self.regionLoading = true
|
|
|
|
|
- uni.request({
|
|
|
|
|
- url: config.api('/api/region/provinces'),
|
|
|
|
|
- method: 'POST',
|
|
|
|
|
- header: {
|
|
|
|
|
- 'Content-Type': 'application/json',
|
|
|
|
|
- 'Authorization': 'Bearer ' + uni.getStorageSync('token')
|
|
|
|
|
- },
|
|
|
|
|
- success: function(res) {
|
|
|
|
|
- self.regionLoading = false
|
|
|
|
|
- if (res.data && res.data.code === 200) {
|
|
|
|
|
- self.provinceList = res.data.data || []
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
- fail: function() {
|
|
|
|
|
- self.regionLoading = false
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
- },
|
|
|
|
|
- loadRegionCities(parentId) {
|
|
|
|
|
- if (!parentId) return
|
|
|
|
|
- var self = this
|
|
|
|
|
- self.regionLoading = true
|
|
|
|
|
- uni.request({
|
|
|
|
|
- url: config.api('/api/region/cities'),
|
|
|
|
|
- method: 'POST',
|
|
|
|
|
- data: { parentId: parentId },
|
|
|
|
|
- header: {
|
|
|
|
|
- 'Content-Type': 'application/json',
|
|
|
|
|
- 'Authorization': 'Bearer ' + uni.getStorageSync('token')
|
|
|
|
|
- },
|
|
|
|
|
- success: function(res) {
|
|
|
|
|
- self.regionLoading = false
|
|
|
|
|
- if (res.data && res.data.code === 200) {
|
|
|
|
|
- self.cityList = res.data.data || []
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
- fail: function() {
|
|
|
|
|
- self.regionLoading = false
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
- },
|
|
|
|
|
- loadRegionDistricts(parentId) {
|
|
|
|
|
- if (!parentId) return
|
|
|
|
|
- var self = this
|
|
|
|
|
- self.regionLoading = true
|
|
|
|
|
- uni.request({
|
|
|
|
|
- url: config.api('/api/region/districts'),
|
|
|
|
|
- method: 'POST',
|
|
|
|
|
- data: { parentId: parentId },
|
|
|
|
|
- header: {
|
|
|
|
|
- 'Content-Type': 'application/json',
|
|
|
|
|
- 'Authorization': 'Bearer ' + uni.getStorageSync('token')
|
|
|
|
|
- },
|
|
|
|
|
- success: function(res) {
|
|
|
|
|
- self.regionLoading = false
|
|
|
|
|
- if (res.data && res.data.code === 200) {
|
|
|
|
|
- self.districtList = res.data.data || []
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
- fail: function() {
|
|
|
|
|
- self.regionLoading = false
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
- },
|
|
|
|
|
- selectRegionItem(item) {
|
|
|
|
|
- if (this.currentRegionLevel === 0) {
|
|
|
|
|
- this.tempProvince = item
|
|
|
|
|
- this.tempCity = null
|
|
|
|
|
- this.tempDistrict = null
|
|
|
|
|
- this.cityList = []
|
|
|
|
|
- this.districtList = []
|
|
|
|
|
- this.currentRegionLevel = 1
|
|
|
|
|
- this.loadRegionCities(this.getRegionId(item))
|
|
|
|
|
- } else if (this.currentRegionLevel === 1) {
|
|
|
|
|
- this.tempCity = item
|
|
|
|
|
- this.tempDistrict = null
|
|
|
|
|
- this.districtList = []
|
|
|
|
|
- this.currentRegionLevel = 2
|
|
|
|
|
- this.loadRegionDistricts(this.getRegionId(item))
|
|
|
|
|
- } else if (this.currentRegionLevel === 2) {
|
|
|
|
|
- this.tempDistrict = item
|
|
|
|
|
- this.confirmRegion()
|
|
|
|
|
|
|
+ if (this.$refs.addressPicker) {
|
|
|
|
|
+ this.$refs.addressPicker.open()
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
- confirmRegion() {
|
|
|
|
|
- if (this.tempProvince) {
|
|
|
|
|
- this.form.province = this.getRegionName(this.tempProvince)
|
|
|
|
|
- }
|
|
|
|
|
- if (this.tempCity) {
|
|
|
|
|
- this.form.city = this.getRegionName(this.tempCity)
|
|
|
|
|
- }
|
|
|
|
|
- if (this.tempDistrict) {
|
|
|
|
|
- this.form.district = this.getRegionName(this.tempDistrict)
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ onRegionChange(data) {
|
|
|
|
|
+ this.form.province = data.province || ''
|
|
|
|
|
+ this.form.city = data.city || ''
|
|
|
|
|
+ this.form.district = data.district || ''
|
|
|
this.updateFullAddress()
|
|
this.updateFullAddress()
|
|
|
- this.showRegionPicker = false
|
|
|
|
|
- },
|
|
|
|
|
- cancelRegion() {
|
|
|
|
|
- this.showRegionPicker = false
|
|
|
|
|
- },
|
|
|
|
|
- jumpRegionLevel(level) {
|
|
|
|
|
- if (level < this.currentRegionLevel) {
|
|
|
|
|
- this.currentRegionLevel = level
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
- getRegionName(item) {
|
|
|
|
|
- return item && (item.name || item.province || item.city || item.district || '')
|
|
|
|
|
- },
|
|
|
|
|
- getRegionId(item) {
|
|
|
|
|
- return item && (item.id || item.code)
|
|
|
|
|
- },
|
|
|
|
|
- isRegionSelected(item) {
|
|
|
|
|
- var name = this.getRegionName(item)
|
|
|
|
|
- if (this.currentRegionLevel === 0) return this.tempProvince && this.getRegionName(this.tempProvince) === name
|
|
|
|
|
- if (this.currentRegionLevel === 1) return this.tempCity && this.getRegionName(this.tempCity) === name
|
|
|
|
|
- if (this.currentRegionLevel === 2) return this.tempDistrict && this.getRegionName(this.tempDistrict) === name
|
|
|
|
|
- return false
|
|
|
|
|
},
|
|
},
|
|
|
updateFullAddress() {
|
|
updateFullAddress() {
|
|
|
this.form.address = (this.form.province || '') + (this.form.city || '') + (this.form.district || '') + (this.form.street || '')
|
|
this.form.address = (this.form.province || '') + (this.form.city || '') + (this.form.district || '') + (this.form.street || '')
|
|
@@ -1181,104 +1024,6 @@ bindReferralIfNotSelf(code).then(function(res) {
|
|
|
color: #999;
|
|
color: #999;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* ===== 区域选择弹窗 ===== */
|
|
|
|
|
-.region-mask {
|
|
|
|
|
- position: fixed;
|
|
|
|
|
- top: 0;
|
|
|
|
|
- left: 0;
|
|
|
|
|
- right: 0;
|
|
|
|
|
- bottom: 0;
|
|
|
|
|
- background: rgba(0, 0, 0, 0.5);
|
|
|
|
|
- z-index: 999;
|
|
|
|
|
- display: flex;
|
|
|
|
|
- align-items: flex-end;
|
|
|
|
|
-}
|
|
|
|
|
-.region-picker {
|
|
|
|
|
- background: #fff;
|
|
|
|
|
- border-radius: 20rpx 20rpx 0 0;
|
|
|
|
|
- width: 100%;
|
|
|
|
|
- max-height: 70vh;
|
|
|
|
|
- display: flex;
|
|
|
|
|
- flex-direction: column;
|
|
|
|
|
-}
|
|
|
|
|
-.region-header {
|
|
|
|
|
- display: flex;
|
|
|
|
|
- justify-content: space-between;
|
|
|
|
|
- align-items: center;
|
|
|
|
|
- padding: 24rpx 30rpx;
|
|
|
|
|
- border-bottom: 1rpx solid #f0f0f0;
|
|
|
|
|
-}
|
|
|
|
|
-.region-header-btn {
|
|
|
|
|
- font-size: 28rpx;
|
|
|
|
|
- color: #999;
|
|
|
|
|
-}
|
|
|
|
|
-.region-confirm {
|
|
|
|
|
- color: #F97316;
|
|
|
|
|
- font-weight: bold;
|
|
|
|
|
-}
|
|
|
|
|
-.region-header-title {
|
|
|
|
|
- font-size: 30rpx;
|
|
|
|
|
- font-weight: bold;
|
|
|
|
|
- color: #333;
|
|
|
|
|
-}
|
|
|
|
|
-.region-breadcrumb {
|
|
|
|
|
- display: flex;
|
|
|
|
|
- align-items: center;
|
|
|
|
|
- padding: 20rpx 30rpx;
|
|
|
|
|
- border-bottom: 1rpx solid #f5f5f5;
|
|
|
|
|
-}
|
|
|
|
|
-.crumb-item {
|
|
|
|
|
- font-size: 26rpx;
|
|
|
|
|
- color: #999;
|
|
|
|
|
- padding: 8rpx 12rpx;
|
|
|
|
|
- border-radius: 8rpx;
|
|
|
|
|
-}
|
|
|
|
|
-.crumb-item.crumb-active {
|
|
|
|
|
- color: #F97316;
|
|
|
|
|
- font-weight: bold;
|
|
|
|
|
-}
|
|
|
|
|
-.crumb-arrow {
|
|
|
|
|
- font-size: 24rpx;
|
|
|
|
|
- color: #ccc;
|
|
|
|
|
- margin: 0 8rpx;
|
|
|
|
|
-}
|
|
|
|
|
-.region-list {
|
|
|
|
|
- max-height: 50vh;
|
|
|
|
|
- overflow-y: auto;
|
|
|
|
|
-}
|
|
|
|
|
-.region-item {
|
|
|
|
|
- display: flex;
|
|
|
|
|
- justify-content: space-between;
|
|
|
|
|
- align-items: center;
|
|
|
|
|
- padding: 28rpx 30rpx;
|
|
|
|
|
- border-bottom: 1rpx solid #f5f5f5;
|
|
|
|
|
-}
|
|
|
|
|
-.region-item:active {
|
|
|
|
|
- background: #FFF7ED;
|
|
|
|
|
-}
|
|
|
|
|
-.region-item-text {
|
|
|
|
|
- font-size: 28rpx;
|
|
|
|
|
- color: #333;
|
|
|
|
|
-}
|
|
|
|
|
-.region-item-check {
|
|
|
|
|
- font-size: 28rpx;
|
|
|
|
|
- color: #F97316;
|
|
|
|
|
- font-weight: bold;
|
|
|
|
|
-}
|
|
|
|
|
-.region-item-selected {
|
|
|
|
|
- background: #FFF7ED;
|
|
|
|
|
-}
|
|
|
|
|
-.region-item-selected .region-item-text {
|
|
|
|
|
- color: #F97316;
|
|
|
|
|
- font-weight: bold;
|
|
|
|
|
-}
|
|
|
|
|
-.region-loading {
|
|
|
|
|
- padding: 40rpx;
|
|
|
|
|
- text-align: center;
|
|
|
|
|
- font-size: 26rpx;
|
|
|
|
|
- color: #999;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
/* ===== 地址行(所在地区) ===== */
|
|
/* ===== 地址行(所在地区) ===== */
|
|
|
.address-row {
|
|
.address-row {
|
|
|
display: flex;
|
|
display: flex;
|