<template>
	<view class="search-address-page">
		<!-- 自定义导航栏 -->
		<custom-navbar title="搜索地址" :showBack="true" backgroundColor="#FFFFFF"></custom-navbar>

		<!-- 城市选择-->
		<view class="search-container" v-if="isSelectCity">
			<text class="search-container-text" @click="goSelectCity">{{ city.name }}</text>
			<image src="https://mrrplus.oss-cn-beijing.aliyuncs.com/wxstaic/images/Fill.jpg" mode="aspectFit"
				class="text-img"></image>
		</view>

		<!-- 地图容器 -->
		<view class="map-container" :style="{ height: mapHeight + 'rpx' }">
			<map v-if="mapVisible" :key="mapRenderKey" id="map" class="map" :latitude="latitude" :longitude="longitude"
				scale="19" @tap="onMapTap" @regionchange="changeMap"></map>

			<image v-if="showMapSnapshot" class="map-snapshot" :src="mapSnapshotUrl" mode="aspectFill"
				@load="onSnapshotLoad" @error="onSnapshotError"></image>

			<cover-view v-if="mapVisible" class="center-marker">
				<cover-image
					src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/04007cab-3047-42b0-baab-44df344a92d2"
					class="center-marker-img"></cover-image>
			</cover-view>
		</view>

		<!-- 底部编辑区域 -->
		<view class="bottom-edit-section">
			<!-- 地址识别输入行 -->
			<view class="address-input-row">
				<textarea class="raw-address-input" v-model="rawAddress" placeholder="粘贴文本到此处，将自动识别地址信息。"
					placeholder-style="color: #C6C9CC; font-size: 14px;" :maxlength="200" :adjust-position="true" />
				<view class="action-buttons">
					<view class="action-btn paste-btn" @click="hasRawContent ? clearRawAddress() : onPaste()">
						<text class="btn-text" :style="{ color: '#333333' }">{{ hasRawContent ? '一键清空' : '粘贴' }}</text>
					</view>
					<view class="action-btn smart-btn" :class="{ 'smart-btn-active': hasRawContent }"
						@click="onSmartRecognize">
						<text class="btn-text"
							:style="{ color: hasRawContent ? '#E8101E' : '#999999' }">{{ smartBtnText }}</text>
					</view>
				</view>
			</view>

			<!-- 地址信息栏 -->
			<view class="address-info-panel">
				<view class="info-row" @click="selectRegion">
					<text class="row-label">所在地区</text>
					<view class="row-content">
						<text :class="currentRegion ? 'content-text' : 'placeholder'">{{ currentRegion || "请选择"}}</text>
						<image
							src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/71c63001-a104-49ad-a90d-30d2ade73f4d.png"
							mode="aspectFit" class="arrow-icon"></image>
					</view>
				</view>
				<view class="line"></view>
				<view class="info-row">
					<text class="row-label">详细地址</text>
					<input type="text" class="detail-input" v-model="detailAddress" @input="onDetailInput"
						placeholder="请填写详细地址" placeholder-style="color: #999999; font-size: 14px;"
						:adjust-position="true" />
				</view>
				<view class="line"></view>
			</view>

			<!-- 确认按钮 -->
			<view class="fixed-confirm-bar">
				<view class="confirm-btn" @click="onConfirm">
					<text class="con-btn-text">确认</text>
				</view>
			</view>
		</view>

		<!-- 地区选择弹窗（用户端） -->
		<view class="popup" :class="{ show: showRegionPicker }">
			<view class="popup-mask" @click="closeRegionPicker"></view>
			<view class="popup-content">
				<view class="popup-header">
					<text class="popup-title">选择所在地区</text>
					<text class="popup-close" @click="closeRegionPicker">×</text>
				</view>
				<view class="region-body">
					<picker-view @change="onRegionChange" class="picker-scroll" :indicator-style="indicatorStyle"
						:value="regionPickerValue">
						<picker-view-column>
							<view class="picker-item" v-for="(item, index) in regionProvinceList" :key="index">
								{{ item.province }}</view>
						</picker-view-column>
						<picker-view-column>
							<view class="picker-item" v-for="(item, index) in regionCityList" :key="index">
								{{ item.city }}</view>
						</picker-view-column>
						<picker-view-column>
							<view class="picker-item" v-for="(item, index) in regionDistrictList" :key="index">
								{{ item.area }}</view>
						</picker-view-column>
					</picker-view>
				</view>
				<view class="popup-footer">
					<view class="popup-btn cancel" @click="closeRegionPicker">
						<text class="btn-text">取消</text>
					</view>
					<view class="popup-btn confirm" @click="confirmRegion">
						<text class="btn-text">确定</text>
					</view>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	import request from '@/utils/request'
	import ChinaCitys from './data/ChinaCitys.json'
	import store from '@/store'
	import {
		setVersion
	} from '@/utils/version.js'

	export default {
		data() {
			return {
				useApiRawRecognize: false,
				mapVisible: true,
				showMapSnapshot: false,
				mapSnapshotUrl: '',
				mapRenderKey: 0,
				mapMoveTimer: null,
				mapProgrammaticUntil: 0,
				mapGuardTimer: null,
				mapReverseTimer: null,
				popupRestoreTimer: null,
				reverseGeocodeRequestId: 0,
				dependencyInitLock: false,
				dependencyInitTimer: null,
				blankPageInitLock: false,

				// 地图与定位相关
				systemInfo: {},
				latitude: 0,
				longitude: 0,
				newLatitude: 0,
				newLongitude: 0,
				mapHeight: 670,
				city: {
					center: '',
					name: ''
				},
				isSelectCity: false,
				searchCity: uni.getStorageSync('searchCity'),
				source: '',
				recognizeMapMoving: false,
				recognizeMapMoveTimer: null,

				// 编辑区数据
				manualDetail: '',
				isManualDetail: false,
				currentProvince: '',
				currentCity: '',
				currentDistrict: '',
				currentDetail: '',
				selectedProvinceCode: '',
				selectedCityCode: '',
				selectedDistrictCode: '',
				rawAddress: '',
				hasRawContent: false,
				smartBtnText: '智能识别',
				hasDetailContent: false,
				currentRegion: '',
				detailAddress: '',

				// 首次进入且上页没有详细地址时，禁止自动回填详细地址
				suppressInitDetailFill: false,
				ignoreRegionChangeOnce: false,

				// 地区选择弹窗数据
				showRegionPicker: false,
				regionProvinceList: [],
				regionCityList: [],
				regionDistrictList: [],
				regionPickerValue: [0, 0, 0],

				indicatorStyle: 'height: 68rpx;',
				userSelectedRegion: false,

				// 高德地图 key
				amapKey: '30b7eb1a1b2f88edc085b9b3ee9a2188'
			}
		},

		watch: {
			rawAddress(newVal) {
				this.hasRawContent = (newVal || '').trim().length > 0
				this.smartBtnText = '智能识别'
			},
			detailAddress(newVal) {
				this.hasDetailContent = (newVal || '').trim().length > 0
			}
		},

		onLoad(options) {
			console.log('ChinaCitys 数据:', ChinaCitys)
			console.log('ChinaCitys 长度:', ChinaCitys?.length)

			this.systemInfo = uni.getSystemInfoSync()
			this.source = options.source || ''
			this.mapHeight = 670

			const incomingAddress = options.address ? decodeURIComponent(options.address) : ''
			const hasDependency = !!options.dependency
			const hasLocation = !!(options.longitude && options.latitude)
			const skipAutoLocate = String(options.skip_auto_locate || '') === '1'
			const initCurrentLocation = String(options.init_current_location || '') === '1'
			const silentLocate = String(options.silent_locate || '') === '1'

			// 1. 有传入地区：优先按传入地区初始化，禁止首屏地图自动反写
			if (hasDependency) {
				const regions = decodeURIComponent(options.dependency).split('-')
				console.log('传入地区信息:', regions)

				this.currentProvince = regions[0] || ''
				this.currentCity = regions[1] || ''
				this.currentDistrict = regions[2] || ''

				let regionText = ''
				if (this.currentProvince) regionText += this.currentProvince
				if (this.currentCity && this.currentCity !== this.currentProvince) regionText += this.currentCity
				if (this.currentDistrict) regionText += this.currentDistrict
				this.currentRegion = regionText

				if (incomingAddress) {
					this.detailAddress = incomingAddress
					this.manualDetail = incomingAddress
					this.currentDetail = incomingAddress
					this.isManualDetail = true
					this.suppressInitDetailFill = false
				} else {
					this.detailAddress = ''
					this.manualDetail = ''
					this.currentDetail = ''
					this.isManualDetail = false
					this.suppressInitDetailFill = true
				}

				this.startDependencyInitLock()
				if (hasLocation) {
					
					this.applyMapLocation(options.longitude, options.latitude, false)
					return
				}

				const dependencyCode = options.dependency_code

				;
				(async () => {
					let center = null
					
					if (dependencyCode && regions[2]) {
						center = await this.getDistrictCenter(regions[2], dependencyCode)
					}

					if (!center && regions[2]) {
						center = await this.getDistrictCenter(regions[2])
					}
					if (!center && regions[1] && regions[1] !== regions[0]) {
						center = await this.getDistrictCenter(regions[1])
					}
					if (!center && regions[0]) {
						center = await this.getDistrictCenter(regions[0])
					}

					if (center) {
						const locationRes = center.split(',')
						if (locationRes.length >= 2) {
							this.updateMapCenter(
								parseFloat(locationRes[0]),
								parseFloat(locationRes[1]),
								false
							)
						}
					} else if (!skipAutoLocate) {
						this.clearDependencyInitLock()
						this.getCurrentLocation()
					} else {
						this.clearDependencyInitLock()
					}
				})()

				return
			}

			// 2. 只有经纬度，没有地区
			if (hasLocation) {
				this.applyMapLocation(options.longitude, options.latitude, true)

				if (incomingAddress) {
					this.detailAddress = incomingAddress
					this.manualDetail = incomingAddress
					this.currentDetail = incomingAddress
					this.isManualDetail = true
					this.suppressInitDetailFill = false
				} else {
					this.detailAddress = ''
					this.manualDetail = ''
					this.currentDetail = ''
					this.isManualDetail = false
					this.suppressInitDetailFill = true
				}
				

				this.reverseGeocode(parseFloat(options.longitude), parseFloat(options.latitude))
				return
			}

			// 3. 从城市选择页进入
			if (options.city) {
				const city = JSON.parse(decodeURIComponent(options.city))
				this.city = city
				this.ignoreRegionChangeOnce = true
				this.getNowLocation(city.center)
				this.isSelectCity = true
				return
			}

			// 4. 仅标记城市选择模式
			if (options.isSelectCity) {
				this.isSelectCity = true
				this.getCurrentLocation()
				return
			}

			// 5. 手艺人信息页首次进入且详细地址为空：按当前定位初始化
			if (initCurrentLocation) {
				this.blankPageInitLock = false
				this.getCurrentLocation(silentLocate, true)
				return
			}

			// 6. 空白进入且明确要求不自动定位
			if (skipAutoLocate && !hasDependency && !hasLocation) {
				this.blankPageInitLock = true
				this.currentProvince = ''
				this.currentCity = ''
				this.currentDistrict = ''
				this.currentRegion = ''
				this.detailAddress = ''
				this.manualDetail = ''
				this.currentDetail = ''
				this.isManualDetail = false
				this.suppressInitDetailFill = true
				return
			}

			// 7. 默认当前位置
			if (!skipAutoLocate) {
				this.blankPageInitLock = false
				this.getCurrentLocation(silentLocate, false)
			}
		},

		onShow() {
			if (!this.isSelectCity) return

			const searchCity = uni.getStorageSync('searchCity')
			if (searchCity && this.city.name !== searchCity.name) {
				this.city = searchCity
				this.searchCity = searchCity
				this.ignoreRegionChangeOnce = true
				this.getNowLocation(searchCity.center)
			}
		},

		methods: {
			normalizeMunicipalityName(name) {
				const value = String(name || '').trim()

				const map = {
					'北京': '北京市',
					'北京市': '北京市',
					'上海': '上海市',
					'上海市': '上海市',
					'天津': '天津市',
					'天津市': '天津市',
					'重庆': '重庆市',
					'重庆市': '重庆市',
					'香港': '香港特别行政区',
					'香港特别行政区': '香港特别行政区',
					'澳门': '澳门特别行政区',
					'澳门特别行政区': '澳门特别行政区'
				}

				return map[value] || value
			},

			normalizeRecognizedRegionParts(province, city, district) {
				let p = this.normalizeMunicipalityName(province)
				let c = this.normalizeMunicipalityName(city)
				const d = String(district || '').trim()

				const municipalities = [
					'北京市',
					'上海市',
					'天津市',
					'重庆市',
					'香港特别行政区',
					'澳门特别行政区'
				]

				if (!p && municipalities.includes(c)) {
					p = c
				}

				if (!c && municipalities.includes(p)) {
					c = p
				}

				return {
					province: p,
					city: c,
					district: d
				}
			},

			buildRegionText(province, city, district) {
				let text = ''
				if (province) text += province
				if (city && city !== province) text += city
				if (district) text += district
				return text
			},

			startDependencyInitLock(duration = 800) {
				this.dependencyInitLock = true

				if (this.dependencyInitTimer) {
					clearTimeout(this.dependencyInitTimer)
				}

				this.dependencyInitTimer = setTimeout(() => {
					this.dependencyInitLock = false
					this.dependencyInitTimer = null
				}, duration)
			},

			clearDependencyInitLock() {
				this.dependencyInitLock = false

				if (this.dependencyInitTimer) {
					clearTimeout(this.dependencyInitTimer)
					this.dependencyInitTimer = null
				}
			},

			clearBlankPageInitLock() {
				this.blankPageInitLock = false
			},

			isUserGestureMapEvent(causedBy) {
				return ['gesture', 'drag', 'scale'].includes(String(causedBy || '').toLowerCase())
			},

			applyMapLocation(longitude, latitude, noReverse = true) {
				const lng = Number(longitude)
				const lat = Number(latitude)

				if (!Number.isFinite(lng) || !Number.isFinite(lat)) return

				this.ignoreRegionChangeOnce = true
				this.mapProgrammaticUntil = Date.now() + 280

				this.longitude = lng
				this.latitude = lat
				this.newLongitude = lng
				this.newLatitude = lat

				if (this.mapGuardTimer) {
					clearTimeout(this.mapGuardTimer)
				}
				this.mapGuardTimer = setTimeout(() => {
					this.ignoreRegionChangeOnce = false
					this.mapGuardTimer = null
				}, 320)

				if (this.mapReverseTimer) {
					clearTimeout(this.mapReverseTimer)
					this.mapReverseTimer = null
				}
				

				if (!noReverse) {
					this.mapReverseTimer = setTimeout(() => {
						this.reverseGeocode(lng, lat)
						this.mapReverseTimer = null
					}, 220)
				}
			},

			normalizeCityName(province, city) {
				let cityName = ''

				if (Array.isArray(city)) {
					cityName = city[0] || ''
				} else {
					cityName = city || ''
				}

				const fallbackCities = [
					'北京市',
					'上海市',
					'天津市',
					'重庆市',
					'香港特别行政区',
					'澳门特别行政区'
				]

				if (!cityName && fallbackCities.includes(province)) {
					cityName = province
				}

				return cityName
			},

			buildMapSnapshotUrl() {
				const lng = Number(this.longitude || this.newLongitude || 0).toFixed(6)
				const lat = Number(this.latitude || this.newLatitude || 0).toFixed(6)
				return `https://restapi.amap.com/v3/staticmap?location=${lng},${lat}&zoom=17&size=750*500&scale=2&markers=mid,0xE8101E,A:${lng},${lat}&key=${this.amapKey}`
			},

			onSnapshotLoad() {
				console.log('地图加载成功:', this.mapSnapshotUrl)
			},

			onSnapshotError(e) {
				console.log('地图加载失败:', e, this.mapSnapshotUrl)
				uni.showToast({
					title: '地图加载失败',
					icon: 'none'
				})
			},

			findRegionIndexByCode(baseData, provinceCode, cityCode, areaCode) {
				const result = {
					provinceIndex: -1,
					cityIndex: -1,
					areaIndex: -1
				}
				const targetProvinceCode = (provinceCode || '').slice(0, 6)
				const targetCityCode = (cityCode || '').slice(0, 6)
				const targetAreaCode = (areaCode || '').slice(0, 6)
				if (!targetProvinceCode || !targetCityCode || !targetAreaCode) return result

				for (let pIdx = 0; pIdx < baseData.length; pIdx++) {
					const provinceItem = baseData[pIdx]
					const currentProvinceCode = (provinceItem.code || '').slice(0, 6)
					if (currentProvinceCode === targetProvinceCode) {
						result.provinceIndex = pIdx
						const citys = provinceItem.citys || []
						for (let cIdx = 0; cIdx < citys.length; cIdx++) {
							const cityItem = citys[cIdx]
							const currentCityCode = (cityItem.code || '').slice(0, 6)
							if (currentCityCode === targetCityCode) {
								result.cityIndex = cIdx
								const areas = cityItem?.areas || []
								for (let aIdx = 0; aIdx < areas.length; aIdx++) {
									const areaItem = areas[aIdx]
									const currentAreaCode = (areaItem.code || '').slice(0, 6)
									if (currentAreaCode === targetAreaCode) {
										result.areaIndex = aIdx
										return result
									}
								}
								return result
							}
						}
						return result
					}
				}
				return result
			},

			convert(item) {
				const data = {
					key: this.amapKey,
					locations: `${item.longitude},${item.latitude}`,
					coordsys: 'gps'
				}
				return new Promise((resolve) => {
					uni.request({
						url: 'https://restapi.amap.com/v3/assistant/coordinate/convert',
						method: 'GET',
						data,
						success(res) {
							resolve(res.data)
						}
					})
				})
			},

			getLocation(silent = false) {
				return new Promise((resolve, reject) => {
					const handleFail = (err) => {
						if (!silent) {
							uni.showToast({
								title: '获取位置失败',
								icon: 'none'
							})
						}
						reject(err)
					}

					if (this.$store?.state?.version?.DeviceBrand === 'ios') {
						uni.getLocation({
							type: 'wgs84',
							isHighAccuracy: true,
							success: async (res) => {
								try {
									const convert = await this.convert(res)
									const locations = String(convert?.locations || '').split(',')

									if (locations.length >= 2) {
										res.longitude = Number(locations[0])
										res.latitude = Number(locations[1])
									}

									resolve(res)
								} catch (error) {
									handleFail(error)
								}
							},
							fail: handleFail
						})
					} else {
						uni.getLocation({
							type: 'gcj02',
							geocode: true,
							success: (res) => resolve(res),
							fail: handleFail
						})
					}
				})
			},

			async getCurrentLocation(silent = false, lockInit = false) {
				this.blankPageInitLock = false

				try {
					const locationRes = await this.getLocation(silent)

					if (lockInit) {
						this.startDependencyInitLock(1200)
						this.userSelectedRegion = false
						this.isManualDetail = false
						this.suppressInitDetailFill = false
					}

					this.updateMapCenter(locationRes.longitude, locationRes.latitude, false)
				} catch (error) {
					if (silent) {
						this.latitude = 0
						this.longitude = 0
						this.newLatitude = 0
						this.newLongitude = 0

						this.currentProvince = ''
						this.currentCity = ''
						this.currentDistrict = ''
						this.currentRegion = ''
						this.detailAddress = ''
						this.manualDetail = ''
						this.currentDetail = ''
						this.isManualDetail = false

						this.blankPageInitLock = true
						this.suppressInitDetailFill = true
					}

					console.log('定位失败', error)
				}
			},

			getNowLocation(center) {
				if (!center) return
				const locationRes = center.split(',')
				if (locationRes.length < 2) return

				this.updateMapCenter(
					parseFloat(locationRes[0]),
					parseFloat(locationRes[1]),
					false
				)
			},

			normalizeAdcode6(code) {
				return String(code || '').slice(0, 6)
			},

			validateLocationWithDependency(longitude, latitude, dependencyCode) {
				return new Promise((resolve) => {
					const targetCode = this.normalizeAdcode6(dependencyCode)

					if (!targetCode || !longitude || !latitude) {
						resolve(true)
						return
					}

					uni.request({
						url: 'https://restapi.amap.com/v3/geocode/regeo',
						method: 'GET',
						data: {
							key: this.amapKey,
							location: `${longitude},${latitude}`,
							extensions: 'base'
						},
						success: (res) => {
							const adcode = this.normalizeAdcode6(
								res?.data?.regeocode?.addressComponent?.adcode || ''
							)

							if (!adcode) {
								resolve(true)
								return
							}

							resolve(adcode === targetCode)
						},
						fail: () => {
							resolve(true)
						}
					})
				})
			},

			async locateByDependencyCenter(regions, dependencyCode, skipAutoLocate) {
				let center = null

				if (dependencyCode && regions[2]) {
					center = await this.getDistrictCenter(regions[2], dependencyCode)
				}

				if (!center && regions[2]) {
					center = await this.getDistrictCenter(regions[2])
				}
				if (!center && regions[1] && regions[1] !== regions[0]) {
					center = await this.getDistrictCenter(regions[1])
				}
				if (!center && regions[0]) {
					center = await this.getDistrictCenter(regions[0])
				}

				if (center) {
					const locationRes = center.split(',')
					if (locationRes.length >= 2) {
						this.updateMapCenter(
							parseFloat(locationRes[0]),
							parseFloat(locationRes[1]),
							true
						)
					}
				} else if (!skipAutoLocate) {
					this.getCurrentLocation()
				}
			},

			reverseGeocode(lng, lat) {
				const requestId = ++this.reverseGeocodeRequestId
				const targetLng = parseFloat(lng)
				const targetLat = parseFloat(lat)

				if (!Number.isFinite(targetLng) || !Number.isFinite(targetLat)) return

				uni.request({
					url: 'https://restapi.amap.com/v3/geocode/regeo',
					data: {
						key: this.amapKey,
						location: `${targetLng},${targetLat}`,
						extensions: 'base'
					},
					success: (res) => {
						if (requestId !== this.reverseGeocodeRequestId) return

						if (res.data.status === '1' && res.data.regeocode) {
							if (this.recognizeMapMoving) return

							const regeo = res.data.regeocode
							const formatted = regeo.formatted_address || ''
							const addrComp = regeo.addressComponent || {}

							const provinceName = addrComp.province || ''
							const cityName = this.normalizeCityName(provinceName, addrComp.city)
							const districtName = addrComp.district || ''

							let region = ''
							if (provinceName) region += provinceName
							if (cityName && cityName !== provinceName) region += cityName
							if (districtName) region += districtName

							if (!this.userSelectedRegion) {
								this.currentRegion = region || formatted
								this.currentProvince = provinceName
								this.currentCity = cityName
								this.currentDistrict = districtName

								const adcode = addrComp.adcode || ''
								if (adcode.length >= 6) {
									this.selectedDistrictCode = adcode
									this.selectedCityCode = adcode.substring(0, 4) + '00'
									this.selectedProvinceCode = adcode.substring(0, 2) + '0000'
								}
							}

							let detail = ''
							if (region && formatted.startsWith(region)) {
								detail = formatted.substring(region.length).trim()
							} else {
								detail = formatted.trim()
							}

							if (this.suppressInitDetailFill) {
								this.suppressInitDetailFill = false
								return
							}

							if (!this.isManualDetail) {
								this.detailAddress = detail || formatted
								this.manualDetail = this.detailAddress
								this.currentDetail = this.detailAddress
							}
						}
					},
					fail: (err) => {
						if (requestId !== this.reverseGeocodeRequestId) return
						console.error('逆地理编码失败:', err)
					}
				})
			},

			onMapTap(e) {
				this.clearDependencyInitLock()
				this.clearBlankPageInitLock()

				this.userSelectedRegion = false
				this.isManualDetail = false
				this.suppressInitDetailFill = false

				const tapLat = Number(e?.detail?.latitude)
				const tapLng = Number(e?.detail?.longitude)

				if (Number.isFinite(tapLat) && Number.isFinite(tapLng)) {
					this.latitude = tapLat
					this.longitude = tapLng
					this.newLatitude = tapLat
					this.newLongitude = tapLng
					this.reverseGeocode(tapLng, tapLat)
					return
				}

				const mapCtx = uni.createMapContext('map', this)
				mapCtx.getCenterLocation({
					success: (res) => {
						this.latitude = res.latitude
						this.longitude = res.longitude
						this.newLatitude = res.latitude
						this.newLongitude = res.longitude
						this.reverseGeocode(res.longitude, res.latitude)
					},
					fail: (err) => {
						console.error('点击地图获取中心点失败', err)
					}
				})
			},

			syncCenterFromMap() {
				if (this.dependencyInitLock) return
				if (this.blankPageInitLock) return

				const mapCtx = uni.createMapContext('map', this)

				mapCtx.getCenterLocation({
					success: (res) => {
						if (
							!res ||
							!Number.isFinite(Number(res.longitude)) ||
							!Number.isFinite(Number(res.latitude))
						) {
							return
						}

						this.userSelectedRegion = false
						this.isManualDetail = false
						this.suppressInitDetailFill = false

						this.latitude = Number(res.latitude)
						this.longitude = Number(res.longitude)
						this.newLatitude = Number(res.latitude)
						this.newLongitude = Number(res.longitude)

						this.reverseGeocode(this.longitude, this.latitude)
					},
					fail: (err) => {
						console.error('syncCenterFromMap失败', err)
					}
				})
			},

			changeMap(e) {
				if (this.showRegionPicker || !this.mapVisible) return
				if (this.recognizeMapMoving) return
				if (this.dependencyInitLock) return

				const eventType = e?.detail?.type || e?.type || ''
				const causedBy = e?.detail?.causedBy || e?.causedBy || ''

				if (this.blankPageInitLock) {
					if (this.isUserGestureMapEvent(causedBy)) {
						this.clearBlankPageInitLock()
					} else {
						return
					}
				}

				if (eventType === 'begin') return

				if (Date.now() < this.mapProgrammaticUntil) {
					return
				}

				const isProgrammaticEvent = causedBy && causedBy !== 'gesture'

				if (isProgrammaticEvent && this.ignoreRegionChangeOnce) {
					this.ignoreRegionChangeOnce = false
					return
				}

				if (this.mapMoveTimer) {
					clearTimeout(this.mapMoveTimer)
				}

				const delay = eventType === 'end' ? 80 : 260

				this.mapMoveTimer = setTimeout(() => {
					this.syncCenterFromMap()

					setTimeout(() => {
						this.syncCenterFromMap()
					}, 180)

					this.mapMoveTimer = null
				}, delay)
			},

			goSelectCity() {
				uni.navigateTo({
					url: '/subPackages/address/selectCity'
				})
			},

			clearRawAddress() {
				this.rawAddress = ''
				uni.showToast({
					title: '已清空',
					icon: 'none'
				})
			},

			onDetailInput(e) {
				const val = e.detail.value || ''
				this.detailAddress = val
				this.manualDetail = val
				this.currentDetail = val
				this.isManualDetail = val.trim().length > 0
			},

			onPaste() {
				uni.getClipboardData({
					success: (res) => {
						if (res.data) {
							this.rawAddress = res.data
							uni.showToast({
								title: '已粘贴',
								icon: 'none'
							})
						}
					}
				})
			},

			sanitizeRawAddress(raw) {
				let text = (raw || '')
					.replace(/[\r\n\t]+/g, ' ')
					.replace(/　/g, ' ')
					.replace(/\s+/g, ' ')
					.trim()

				const addressMatch = text.match(/地址[:：]\s*(.*)/)
				if (addressMatch && addressMatch[1]) {
					text = addressMatch[1].trim()
				}

				text = text
					.replace(/(收货人|联系人|姓名)[:：]\s*[\u4e00-\u9fa5A-Za-z·]{1,20}/g, '')
					.replace(/(电话|手机)[:：]?\s*1[3-9]\d{9}/g, '')
					.replace(/1[3-9]\d{9}/g, '')
					.replace(/[，,；;]+/g, ' ')
					.replace(/\s+/g, ' ')
					.trim()

				return text
			},

			escapeRegExp(str) {
				return (str || '').replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
			},

			getNetworkTypeSafe() {
				return new Promise((resolve) => {
					uni.getNetworkType({
						success: (res) => resolve(res.networkType || 'unknown'),
						fail: () => resolve('unknown')
					})
				})
			},

			async ensureRecognizeNetworkAvailable() {
				const networkType = await this.getNetworkTypeSafe()

				if (networkType === 'none') {
					this.showRecognizeNetworkError()
					return false
				}

				return true
			},

			showRecognizeNetworkError() {
				uni.showToast({
					title: '网络异常，无法进行地址识别与地图定位，请检查网络后重试',
					icon: 'none',
					duration: 3500
				})
			},

			isLikelyNetworkError(error) {
				const msg = String(
					error?.errMsg ||
					error?.message ||
					error ||
					''
				).toLowerCase()

				return (
					msg.includes('network') ||
					msg.includes('timeout') ||
					msg.includes('request:fail') ||
					msg.includes('fail')
				)
			},

			hasStrongAddressFeature(text) {
				return /(\d|号|栋|幢|单元|室|楼|层|座|路|街|巷|道|村|镇|乡|里|弄|园|苑|小区|大厦|广场|市场|学校|医院|公寓|酒店|中心|胡同)/.test(text || '')
			},

			containsObviousInvalidNoise(text) {
				return /(价格|价钱|多少钱|举报|投诉|建议|咨询|测试|示例|比如|比方|假设|无效|乱填)/i.test(text || '')
			},

			isLikelyInvalidRecognizedDetail(text) {
				const value = String(text || '').trim()
				if (!value) return true

				if (/(价格|价钱|多少钱|举报|投诉|建议|咨询|测试|示例|比如|比方|假设|无效|乱填)/i.test(value)) {
					return true
				}

				if (/^\d{6,}$/.test(value) || /^[A-Za-z]{6,}$/.test(value)) {
					return true
				}

				const specialChars = (value.match(/[^\u4e00-\u9fa5a-zA-Z0-9]/g) || []).length
				if (specialChars / value.length > 0.3) {
					return true
				}

				if (value.length < 2) {
					return true
				}

				const hasLongLetterChunk = /[A-Za-z]{6,}/.test(value)
				const letterCount = (value.match(/[A-Za-z]/g) || []).length
				const letterRatio = value.length ? (letterCount / value.length) : 0
				const hasAddressFeature = this.hasStrongAddressFeature(value)

				if (hasLongLetterChunk && !hasAddressFeature) {
					return true
				}

				if (letterRatio > 0.35 && !hasAddressFeature) {
					return true
				}

				return false
			},

			isPreciseGeocodeLevel(level) {
				return [
					'门牌号',
					'兴趣点',
					'道路',
					'道路交叉口',
					'乡镇',
					'村庄',
					'村级地名',
					'roadno',
					'poi'
				].includes(String(level || '').trim())
			},

			normalizeDistrictName(name) {
				return String(name || '').trim()
			},

			validateRecognizedDetail(detailText, geo, hit = {}) {
				const cleaned = String(detailText || '').trim()
				if (!cleaned) {
					return {
						valid: false,
						cleaned: '',
						reason: 'empty'
					}
				}

				if (this.isLikelyInvalidRecognizedDetail(cleaned)) {
					return {
						valid: false,
						cleaned: '',
						reason: 'invalid_detail'
					}
				}

				if (!geo) {
					return {
						valid: false,
						cleaned: '',
						reason: 'geocode_failed'
					}
				}

				const geoLevel = String(geo?.level || '').trim()
				const preciseLevel = this.isPreciseGeocodeLevel(geoLevel)
				const hasAddressFeature = this.hasStrongAddressFeature(cleaned)

				const hitCountyCode = String(hit?.county_code || '').slice(0, 6)
				const geoAdcode = String(geo?.adcode || '').slice(0, 6)

				const hitDistrictName = this.normalizeDistrictName(hit?.county_name)
				const geoDistrictName = this.normalizeDistrictName(geo?.district)

				const sameDistrictByCode = !!hitCountyCode && !!geoAdcode && hitCountyCode === geoAdcode
				const sameDistrictByName = !!hitDistrictName && !!geoDistrictName && hitDistrictName === geoDistrictName
				const sameDistrict = sameDistrictByCode || sameDistrictByName

				const purePoiLike =
					cleaned.length >= 2 &&
					/^[\u4e00-\u9fa5A-Za-z0-9]+$/.test(cleaned) &&
					!/[A-Za-z]{6,}/.test(cleaned)

				if (hasAddressFeature || preciseLevel) {
					return {
						valid: true,
						cleaned,
						reason: ''
					}
				}

				if (sameDistrict && purePoiLike) {
					return {
						valid: true,
						cleaned,
						reason: 'district_geo_verified'
					}
				}

				return {
					valid: false,
					cleaned: '',
					reason: 'detail_not_precise'
				}
			},

			cleanRecognizedDetail(detail, province, city, district) {
				let text = this.stripLeadingRegionParts(detail, [
					province,
					city,
					district
				])

				text = text
					.replace(/(收货人|联系人|姓名)[:：].*$/g, '')
					.replace(/(电话|手机)[:：]?\s*1[3-9]\d{9}.*$/g, '')
					.replace(/备注[:：].*$/g, '')
					.replace(/1[3-9]\d{9}/g, '')
					.replace(/[（(][^）)]*[）)]/g, '')
					.replace(/^[，,；;、\s]+/, '')
					.replace(/\s+/g, ' ')
					.trim()

				return text
			},

			appendIfMissing(base, part) {
				const src = String(base || '').trim()
				const seg = String(part || '').trim()

				if (!seg) return src
				if (!src) return seg
				if (src.includes(seg)) return src

				return `${src}${seg}`
			},

			deriveCodesFromDivision(divcode = '') {
				const code = String(divcode || '').trim()
				if (!/^\d{12}$/.test(code)) {
					return {
						province_code: '',
						city_code: '',
						county_code: ''
					}
				}

				return {
					province_code: `${code.slice(0, 2)}0000`,
					city_code: `${code.slice(0, 4)}00`,
					county_code: code.slice(0, 6)
				}
			},

			parseDivisionInfo(area = {}) {
				const divisionInfo = area?.division_info || {}
				const divisionName = String(divisionInfo.division_name || '').trim()
				const divcode = String(divisionInfo.divcode || '').trim()

				let parts = []
				if (divisionName.includes(';')) {
					parts = divisionName.split(';')
				} else if (divisionName) {
					parts = divisionName.split(/\s+/)
				}

				const derivedCodes = this.deriveCodesFromDivision(divcode)

				return {
					province_name: String(parts[0] || '').trim(),
					city_name: String(parts[1] || '').trim(),
					county_name: String(parts[2] || '').trim(),
					town_name: String(parts[3] || '').trim(),
					province_code: derivedCodes.province_code,
					city_code: derivedCodes.city_code,
					county_code: derivedCodes.county_code
				}
			},

			parseLonlatInfo(lonlat = {}) {
				const offline = lonlat?.offline_geocode || {}

				return {
					gcj02: String(offline.gcj02 || '').trim(),
					wgs84: String(offline.wgs84 || '').trim(),
					level: String(offline.level || '').trim()
				}
			},

			parseStreetStd(streetStd = '') {
				const parsed = {}

				String(streetStd)
					.split(/\t+/)
					.forEach(item => {
						const index = item.indexOf('=')
						if (index === -1) return

						const key = item.slice(0, index).trim().toLowerCase()
						const value = item.slice(index + 1).trim()

						if (key) {
							parsed[key] = value
						}
					})

				return {
					province_name: (parsed.prov || parsed.province || '').trim(),
					city_name: (parsed.city || '').trim(),
					county_name: (parsed.district || parsed.county || parsed.area || '').trim(),
					town_name: (parsed.town || parsed.street || '').trim(),
					road_name: (parsed.road || '').trim(),
					road_no: (parsed.roadno || parsed.road_no || '').trim(),
					poi_name: (parsed.poi || parsed.poi_name || '').trim(),
					house_no: (parsed.houseno || parsed.house_no || '').trim(),
					room_no: (parsed.roomno || parsed.room_no || '').trim(),
					floor_no: (parsed.floor || parsed.floor_no || '').trim(),
					unit_no: (parsed.unit || parsed.unit_no || '').trim(),
					building_no: (parsed.building || parsed.building_no || '').trim(),
					block_no: (parsed.block || parsed.block_no || '').trim(),
					detail: (parsed.detail || parsed.address || parsed.addr || '').trim(),
					address: (parsed.address || parsed.detail || parsed.addr || '').trim(),
					province_code: (parsed.province_code || parsed.prov_code || '').trim(),
					city_code: (parsed.city_code || '').trim(),
					county_code: (parsed.county_code || parsed.district_code || parsed.area_code || '').trim(),
					_street_std_map: parsed
				}
			},

			normalizeRecognizeHit(res) {
				if (!res || (res.code !== 200 && res.code !== 0)) return null

				// 旧格式1：data是数组
				if (Array.isArray(res.data) && res.data.length) {
					const item = res.data[0]
					return {
						province_name: (item.province_name || '').trim(),
						city_name: (item.city_name || '').trim(),
						county_name: (item.county_name || '').trim(),
						town_name: (item.town_name || '').trim(),
						road_name: '',
						road_no: '',
						poi_name: '',
						house_no: '',
						room_no: '',
						floor_no: '',
						unit_no: '',
						building_no: '',
						block_no: '',
						detail: (item.detail || '').trim(),
						address: (item.address || item.detail || '').trim(),
						province_code: (item.province_code || '').trim(),
						city_code: (item.city_code || '').trim(),
						county_code: (item.county_code || '').trim(),
						backend_gcj02: '',
						backend_wgs84: '',
						backend_level: '',
						_street_std_map: {}
					}
				}

				// 旧格式2：data.data是数组
				if (Array.isArray(res?.data?.data) && res.data.data.length) {
					const item = res.data.data[0]
					return {
						province_name: (item.province_name || '').trim(),
						city_name: (item.city_name || '').trim(),
						county_name: (item.county_name || '').trim(),
						town_name: (item.town_name || '').trim(),
						road_name: '',
						road_no: '',
						poi_name: '',
						house_no: '',
						room_no: '',
						floor_no: '',
						unit_no: '',
						building_no: '',
						block_no: '',
						detail: (item.detail || '').trim(),
						address: (item.address || item.detail || '').trim(),
						province_code: (item.province_code || '').trim(),
						city_code: (item.city_code || '').trim(),
						county_code: (item.county_code || '').trim(),
						backend_gcj02: '',
						backend_wgs84: '',
						backend_level: '',
						_street_std_map: {}
					}
				}

				// 旧格式3：result是数组
				if (Array.isArray(res.result) && res.result.length) {
					const item = res.result[0]
					return {
						province_name: (item.province_name || '').trim(),
						city_name: (item.city_name || '').trim(),
						county_name: (item.county_name || '').trim(),
						town_name: (item.town_name || '').trim(),
						road_name: '',
						road_no: '',
						poi_name: '',
						house_no: '',
						room_no: '',
						floor_no: '',
						unit_no: '',
						building_no: '',
						block_no: '',
						detail: (item.detail || '').trim(),
						address: (item.address || item.detail || '').trim(),
						province_code: (item.province_code || '').trim(),
						city_code: (item.city_code || '').trim(),
						county_code: (item.county_code || '').trim(),
						backend_gcj02: '',
						backend_wgs84: '',
						backend_level: '',
						_street_std_map: {}
					}
				}

				// 新格式：data本身就是对象
				if (
					res.data &&
					typeof res.data === 'object' &&
					(
						res.data.province_name ||
						res.data.city_name ||
						res.data.county_name ||
						res.data.detail ||
						res.data.address
					)
				) {
					return {
						province_name: (res.data.province_name || '').trim(),
						city_name: (res.data.city_name || '').trim(),
						county_name: (res.data.county_name || '').trim(),
						town_name: (res.data.town_name || '').trim(),
						road_name: (res.data.road_name || res.data.road || '').trim(),
						road_no: (res.data.road_no || res.data.roadno || '').trim(),
						poi_name: (res.data.poi_name || res.data.poi || '').trim(),
						house_no: (res.data.house_no || res.data.houseno || '').trim(),
						room_no: (res.data.room_no || res.data.roomno || '').trim(),
						floor_no: (res.data.floor_no || res.data.floor || '').trim(),
						unit_no: (res.data.unit_no || res.data.unit || '').trim(),
						building_no: (res.data.building_no || res.data.building || '').trim(),
						block_no: (res.data.block_no || res.data.block || '').trim(),
						detail: (res.data.detail || '').trim(),
						address: (res.data.address || res.data.detail || '').trim(),
						province_code: (res.data.province_code || '').trim(),
						city_code: (res.data.city_code || '').trim(),
						county_code: (res.data.county_code || '').trim(),
						backend_gcj02: '',
						backend_wgs84: '',
						backend_level: '',
						_street_std_map: {}
					}
				}

				// 新格式：data.street + data.area + data.lonlat
				if (res?.data?.street && typeof res.data.street === 'object') {
					const street = res.data.street
					const stdParsed = this.parseStreetStd(street.street_std || '')
					const divisionParsed = this.parseDivisionInfo(res?.data?.area || {})
					const lonlatParsed = this.parseLonlatInfo(res?.data?.lonlat || {})

					return {
						province_name: (street.province_name || street.province || stdParsed.province_name ||
							divisionParsed.province_name || '').trim(),
						city_name: (street.city_name || street.city || stdParsed.city_name || divisionParsed.city_name ||
							'').trim(),
						county_name: (street.county_name || street.district || street.county || stdParsed.county_name ||
							divisionParsed.county_name || '').trim(),
						town_name: (street.town_name || street.town || street.street_name || stdParsed.town_name ||
							divisionParsed.town_name || '').trim(),
						road_name: (street.road_name || street.road || stdParsed.road_name || '').trim(),
						road_no: (street.road_no || street.roadno || stdParsed.road_no || '').trim(),
						poi_name: (street.poi_name || street.poi || stdParsed.poi_name || '').trim(),
						house_no: (street.house_no || street.houseno || stdParsed.house_no || '').trim(),
						room_no: (street.room_no || street.roomno || stdParsed.room_no || '').trim(),
						floor_no: (street.floor_no || street.floor || stdParsed.floor_no || '').trim(),
						unit_no: (street.unit_no || street.unit || stdParsed.unit_no || '').trim(),
						building_no: (street.building_no || street.building || stdParsed.building_no || '').trim(),
						block_no: (street.block_no || street.block || stdParsed.block_no || '').trim(),
						detail: (street.detail || street.address || stdParsed.detail || stdParsed.address || '').trim(),
						address: (street.address || street.detail || stdParsed.address || stdParsed.detail || '').trim(),
						province_code: (street.province_code || stdParsed.province_code || divisionParsed.province_code ||
							'').trim(),
						city_code: (street.city_code || stdParsed.city_code || divisionParsed.city_code || '').trim(),
						county_code: (street.county_code || street.district_code || stdParsed.county_code || divisionParsed
							.county_code || '').trim(),
						backend_gcj02: lonlatParsed.gcj02,
						backend_wgs84: lonlatParsed.wgs84,
						backend_level: lonlatParsed.level,
						_street_std_map: stdParsed._street_std_map || {}
					}
				}

				return null
			},

			getRecognizeApiUrl() {
				const app = typeof getApp === 'function' ? getApp() : null

				const baseUrl =
					app?.globalData?.url ||
					app?.globalData?.baseUrl ||
					app?.globalData?.apiBaseUrl ||
					'https://api.mrrwlkj.top'

				return `${String(baseUrl).replace(/\/+$/, '')}/api/recognize/address`
			},

			buildMultipartFormData(fields = {}) {
				const boundary = '----UniFormBoundary' + Date.now()
				let body = ''

				Object.keys(fields).forEach((key) => {
					const value = fields[key] == null ? '' : String(fields[key])
					body += `--${boundary}\r\n`
					body += `Content-Disposition: form-data; name="${key}"\r\n\r\n`
					body += `${value}\r\n`
				})

				body += `--${boundary}--\r\n`

				return {
					boundary,
					body
				}
			},

			requestRecognizeAddress(rawText) {
				return request.post('/api/recognize/address', {
					text: rawText
				})
			},

			buildGeoFromBackend(hit) {
				const location = String(hit?.backend_gcj02 || '').trim()
				if (!location) return null

				return {
					location,
					adcode: String(hit?.county_code || '').trim(),
					level: String(hit?.backend_level || '').trim(),
					district: String(hit?.county_name || '').trim()
				}
			},

			geocodeRecognizedAddress(address) {
				return new Promise((resolve) => {
					if (!address) {
						resolve({
							ok: true,
							data: null,
							error: null
						})
						return
					}

					uni.request({
						url: 'https://restapi.amap.com/v3/geocode/geo',
						method: 'GET',
						data: {
							key: this.amapKey,
							address,
							output: 'JSON'
						},
						success: (res) => {
							if (res.data.status === '1' && res.data.geocodes?.length > 0) {
								resolve({
									ok: true,
									data: res.data.geocodes[0],
									error: null
								})
							} else {
								resolve({
									ok: true,
									data: null,
									error: null
								})
							}
						},
						fail: (error) => resolve({
							ok: false,
							data: null,
							error
						})
					})
				})
			},

			stripLeadingRegionParts(text, parts = []) {
				let result = String(text || '').trim()

				const validParts = [...new Set(
					parts
					.map(item => String(item || '').trim())
					.filter(Boolean)
				)].sort((a, b) => b.length - a.length)

				if (!result || !validParts.length) return result

				let changed = true

				while (changed && result) {
					changed = false
					result = result.replace(/^\s+/, '')

					for (const part of validParts) {
						const reg = new RegExp(`^${this.escapeRegExp(part)}(?:\\s+|\\b)?`)
						if (reg.test(result)) {
							result = result.replace(reg, '').trim()
							changed = true
							break
						}
					}
				}

				return result
			},

			assembleDetailByInterfaceFields(hit, sanitizedText, province, city, district) {
				const directDetail = String(
					hit?.detail ||
					hit?.address ||
					hit?.addr ||
					hit?.full_address_detail ||
					hit?.address_detail ||
					''
				).trim()

				const structuredValues = [
					String(hit?.town_name || '').trim(),
					String(hit?.road_name || '').trim(),
					String(hit?.road_no || '').trim(),
					String(hit?.poi_name || '').trim(),
					String(hit?.house_no || '').trim(),
					String(hit?.unit_no || '').trim(),
					String(hit?.floor_no || '').trim(),
					String(hit?.room_no || '').trim(),
					String(hit?.building_no || '').trim(),
					String(hit?.block_no || '').trim()
				]

				let result = ''

				// 先放街道/镇
				result = this.appendIfMissing(result, structuredValues[0])

				// 再放接口直接给出的detail/address
				if (directDetail) {
					const cleanedDirect = this.stripLeadingRegionParts(
						directDetail,
						[province, city, district].filter(Boolean)
					).trim()
					result = this.appendIfMissing(result, cleanedDirect)
				}

				// 再按结构化字段补齐
				for (let i = 1; i < structuredValues.length; i++) {
					result = this.appendIfMissing(result, structuredValues[i])
				}

				// 再把street_std中其他未知字段补齐，做到“有什么就拼什么”
				const rawMap = hit?._street_std_map || {}
				const ignoredKeys = new Set([
					'prov', 'province',
					'city',
					'district', 'county', 'area',
					'town', 'street',
					'road',
					'roadno', 'road_no',
					'poi', 'poi_name',
					'houseno', 'house_no',
					'roomno', 'room_no',
					'floor', 'floor_no',
					'unit', 'unit_no',
					'building', 'building_no',
					'block', 'block_no',
					'detail', 'address', 'addr',
					'province_code', 'prov_code',
					'city_code',
					'county_code', 'district_code', 'area_code'
				])

				Object.keys(rawMap).forEach((key) => {
					if (ignoredKeys.has(key)) return
					const value = String(rawMap[key] || '').trim()
					if (!value) return
					result = this.appendIfMissing(result, value)
				})

				// 最后兜底原始文本扣省市区
				if (!result) {
					result = this.stripLeadingRegionParts(
						sanitizedText,
						[province, city, district].filter(Boolean)
					).trim()
				}

				// 最终再次确保详细地址不带省市区
				result = this.stripLeadingRegionParts(
					result,
					[province, city, district].filter(Boolean)
				).trim()

				return result
			},

			buildExactRecognizedDetail(hit, sanitizedText, province, city, district) {
				return this.assembleDetailByInterfaceFields(
					hit,
					sanitizedText,
					province,
					city,
					district
				)
			},

			async onSmartRecognize() {
				this.clearBlankPageInitLock()
				this.userSelectedRegion = false
				this.isManualDetail = false
				this.suppressInitDetailFill = false

				if (!this.hasRawContent) {
					uni.showToast({
						title: '请先粘贴或输入地址',
						icon: 'none'
					})
					return
				}

				const originalRawText = (this.rawAddress || '').trim()
				if (!originalRawText) {
					uni.showToast({
						title: '请先粘贴或输入地址',
						icon: 'none'
					})
					return
				}

				const hasNetwork = await this.ensureRecognizeNetworkAvailable()
				if (!hasNetwork) return

				const sanitizedText = this.sanitizeRawAddress(originalRawText)
				const removedNoise = sanitizedText !== originalRawText

				if (!sanitizedText) {
					uni.showToast({
						title: '未提取到有效地址',
						icon: 'none'
					})
					return
				}

				uni.showLoading({
					title: '识别中...'
				})

				try {
					const res = await this.requestRecognizeAddress(sanitizedText)
					console.log('智能识别接口返回:', res)

					const hit = this.normalizeRecognizeHit(res)

					if (!res || (res.code !== 0 && res.code !== 200) || !hit) {
						uni.hideLoading()
						uni.showToast({
							title: res?.msg || '地址解析失败',
							icon: 'none'
						})
						return
					}

					console.log('智能识别标准化结果:', hit)

					const normalizedRegion = this.normalizeRecognizedRegionParts(
						hit.province_name,
						hit.city_name,
						hit.county_name
					)

					const province = normalizedRegion.province
					const city = normalizedRegion.city
					const district = normalizedRegion.district

					const regionText = this.buildRegionText(province, city, district)

					if (!regionText) {
						uni.hideLoading()
						const tip = this.getRecognizeToast('low', removedNoise, false, hit, '', false)
						if (tip.type === 'modal') {
							uni.showModal({
								title: tip.title,
								content: tip.content,
								showCancel: false
							})
						} else {
							uni.showToast({
								title: tip.title,
								icon: 'none'
							})
						}
						return
					}

					const detailCandidate = this.cleanRecognizedDetail(
						this.buildExactRecognizedDetail(
							hit,
							sanitizedText,
							province,
							city,
							district
						),
						province,
						city,
						district
					)

					const fullAddress = `${regionText}${detailCandidate}`.trim()
					console.log('用于定位的完整地址:', fullAddress)

					let geocodeOk = false
					let geo = null
					let detailRejected = false
					let detailText = ''

					const fullGeoResult = await this.geocodeRecognizedAddress(fullAddress)

					if (!fullGeoResult.ok) {
						uni.hideLoading()
						this.showRecognizeNetworkError()
						return
					}

					geo = fullGeoResult.data || this.buildGeoFromBackend(hit)

					const detailDecision = this.validateRecognizedDetail(detailCandidate, geo, hit)
					detailRejected = !detailDecision.valid && !!detailCandidate
					detailText = detailDecision.valid ? detailDecision.cleaned : ''

					if (!detailText) {
						const regionGeoResult = await this.geocodeRecognizedAddress(regionText)
						if (!regionGeoResult.ok) {
							uni.hideLoading()
							this.showRecognizeNetworkError()
							return
						}
						geo = regionGeoResult.data || this.buildGeoFromBackend(hit)
						detailText = ''
					}

					if (geo) {
						const location = geo.location
						const adcode = geo.adcode || ''

						if (adcode.length >= 6) {
							this.selectedDistrictCode = adcode.slice(0, 6)
							this.selectedCityCode = adcode.slice(0, 4) + '00'
							this.selectedProvinceCode = adcode.slice(0, 2) + '0000'
						} else {
							this.selectedProvinceCode = hit.province_code || this.selectedProvinceCode || ''
							this.selectedCityCode = hit.city_code || this.selectedCityCode || ''
							this.selectedDistrictCode = hit.county_code || this.selectedDistrictCode || ''
						}

						if (location) {
							const [lng, lat] = location.split(',')
							this.longitude = parseFloat(lng)
							this.latitude = parseFloat(lat)
							this.newLongitude = this.longitude
							this.newLatitude = this.latitude

							this.recognizeMapMoving = true
							if (this.recognizeMapMoveTimer) {
								clearTimeout(this.recognizeMapMoveTimer)
							}

							this.updateMapCenter(this.longitude, this.latitude, true)
							geocodeOk = true

							this.recognizeMapMoveTimer = setTimeout(() => {
								this.recognizeMapMoving = false
								this.recognizeMapMoveTimer = null
							}, 1500)
						}
					}

					const level = this.getRecognizeLevel(hit, detailText, sanitizedText)
					const shouldOnlyToast = this.shouldOnlyToastForGarbageRecognize(
						sanitizedText,
						hit,
						detailText,
						detailRejected,
						geocodeOk
					)

					if (level === 'low' || shouldOnlyToast) {
						uni.hideLoading()

						if (shouldOnlyToast) {
							uni.showModal({
								title: '未识别到有效地址',
								content: '当前输入内容无效，系统未自动填入所在地区和详细地址，请检查后重新输入，或手动选择地址。',
								showCancel: false
							})
						} else {
							const tip = this.getRecognizeToast(level, removedNoise, geocodeOk, hit, detailText,
								detailRejected)
							if (tip.type === 'modal') {
								uni.showModal({
									title: tip.title,
									content: tip.content,
									showCancel: false
								})
							} else {
								uni.showToast({
									title: tip.title,
									icon: 'none'
								})
							}
						}
						return
					}

					this.commitRecognizedResult(province, city, district, regionText, detailText, geo, level,
						removedNoise, geocodeOk, hit, detailRejected)
				} catch (error) {
					console.error('智能识别失败:', error)
					uni.hideLoading()

					if (this.isLikelyNetworkError(error)) {
						this.showRecognizeNetworkError()
						return
					}

					uni.showToast({
						title: '识别失败，请稍后重试',
						icon: 'none'
					})
				}
			},

			getRecognizeLevel(hit, detailText, rawText) {
				const province = (hit?.province_name || '').trim()
				const city = (hit?.city_name || '').trim()
				const district = (hit?.county_name || '').trim()

				if (/火星市|月球|银河|测试地址/.test(rawText || '')) {
					return 'low'
				}

				if (!province || (!city && !district)) {
					return 'low'
				}

				if (!detailText || detailText.length < 2) {
					return 'medium'
				}

				return 'high'
			},

			shouldOnlyToastForGarbageRecognize(rawText, hit, detailText, detailRejected = false, geocodeOk = false) {
				if (geocodeOk) return false

				const input = String(rawText || '').trim()
				if (!input) return true

				const province = (hit?.province_name || '').trim()
				const city = (hit?.city_name || '').trim()
				const district = (hit?.county_name || '').trim()

				const hasFullRegion = !!(province && (city || district))
				if (!hasFullRegion) return false

				const hasAddressFeature = this.hasStrongAddressFeature(input)
				const hasRegionKeyword = /(省|市|区|县|旗|镇|乡|村|街道)/.test(input)
				const hasLongLetterChunk = /[A-Za-z]{2,}/.test(input)
				const hasInvalidNoise = this.containsObviousInvalidNoise(input)

				if (!hasAddressFeature && !hasRegionKeyword && !detailText) {
					if (hasLongLetterChunk || hasInvalidNoise || detailRejected) {
						return true
					}
				}

				return false
			},

			getRecognizeToast(level, removedNoise, geocodeOk, hit, detailText, detailRejected = false) {
				const province = (hit?.province_name || '').trim()
				const city = (hit?.city_name || '').trim()
				const district = (hit?.county_name || '').trim()

				const hasRegion = !!(province || city || district)
				const hasFullRegion = !!(province && (city || district))
				const hasDetail = !!(detailText && detailText.trim())

				if (detailRejected && hasFullRegion && !hasDetail) {
					return {
						type: 'modal',
						title: '已识别到地区，详细地址未自动填入',
						content: '已识别到省市区，但检测到详细地址中包含无效或不完整内容，系统未自动填入详细地址，请手动补充。'
					}
				}

				if (level === 'low') {
					if (!hasRegion) {
						return {
							type: 'modal',
							title: '已识别，但未匹配到有效地区',
							content: '未查找到明确的省市区信息，请手动选择所在地区，并检查输入内容是否包含错别字、备注或无效地址。'
						}
					}

					if (hasRegion && !hasFullRegion) {
						return {
							type: 'modal',
							title: '已识别到部分地区信息',
							content: '当前仅识别到部分地区，未能完整匹配到市区县，请手动补全所在地区并核对详细地址。'
						}
					}

					if (hasFullRegion && !hasDetail) {
						return {
							type: 'modal',
							title: '已识别到地区，但详细地址不完整',
							content: '已识别到省市区，但未能准确提取详细地址，请补充门牌号、楼栋号等信息。'
						}
					}

					return {
						type: 'modal',
						title: '已识别，但未匹配到有效地区',
						content: '当前地址未匹配到有效地区，请核对所在地区和详细地址，必要时请手动修正。'
					}
				}

				if (level === 'medium') {
					if (!hasDetail) {
						return {
							type: 'toast',
							title: removedNoise ? '已识别到地区，请补充详细地址' : '已识别到地区，请补充详细地址'
						}
					}

					if (!geocodeOk) {
						return {
							type: 'toast',
							title: removedNoise ? '已识别，但未查到地图位置' : '已识别，但未查到对应地图位置'
						}
					}

					return {
						type: 'toast',
						title: removedNoise ? '已识别到部分地址，请核对' : '已识别到部分地址，请核对'
					}
				}

				if (!geocodeOk) {
					return {
						type: 'toast',
						title: removedNoise ? '已识别，但未查到地图位置' : '已识别，请核对地址和地图位置'
					}
				}

				return {
					type: 'toast',
					title: removedNoise ? '识别成功，请核对' : '识别成功，请核对'
				}
			},

			commitRecognizedResult(province, city, district, regionText, detailText, geo, level, removedNoise, geocodeOk,
				hit, detailRejected) {
				this.currentProvince = province
				this.currentCity = city
				this.currentDistrict = district
				this.currentRegion = regionText

				this.selectedProvinceCode = hit.province_code || this.selectedProvinceCode || ''
				this.selectedCityCode = hit.city_code || this.selectedCityCode || ''
				this.selectedDistrictCode = hit.county_code || this.selectedDistrictCode || ''

				this.detailAddress = detailText
				this.manualDetail = detailText
				this.currentDetail = detailText
				this.isManualDetail = !!detailText

				this.smartBtnText = '已识别'
				uni.hideLoading()

				const tip = this.getRecognizeToast(level, removedNoise, geocodeOk, hit, detailText, detailRejected)
				if (tip.type === 'modal') {
					uni.showModal({
						title: tip.title,
						content: tip.content,
						showCancel: false
					})
				} else {
					uni.showToast({
						title: tip.title,
						icon: 'none'
					})
				}
			},

			updateMapCenter(longitude, latitude, noReverse = false) {
				const lng = parseFloat(longitude)
				const lat = parseFloat(latitude)

				if (!Number.isFinite(lng) || !Number.isFinite(lat)) return

				this.applyMapLocation(lng, lat, noReverse)
			},

			selectRegion() {
				this.openRegionPicker()
			},

			openRegionPicker() {
				this.regionProvinceList = ChinaCitys || []

				let provinceIndex = 0
				let cityIndex = 0
				let areaIndex = 0

				if (this.selectedProvinceCode && this.selectedCityCode && this.selectedDistrictCode) {
					const idx = this.findRegionIndexByCode(
						ChinaCitys,
						this.selectedProvinceCode,
						this.selectedCityCode,
						this.selectedDistrictCode
					)
					provinceIndex = idx.provinceIndex >= 0 ? idx.provinceIndex : 0
					cityIndex = idx.cityIndex >= 0 ? idx.cityIndex : 0
					areaIndex = idx.areaIndex >= 0 ? idx.areaIndex : 0
				}

				this.regionCityList = this.regionProvinceList[provinceIndex]?.citys || []
				this.regionDistrictList = this.regionCityList[cityIndex]?.areas || []
				this.regionPickerValue = [provinceIndex, cityIndex, areaIndex]

				if (this.mapMoveTimer) {
					clearTimeout(this.mapMoveTimer)
					this.mapMoveTimer = null
				}

				this.mapSnapshotUrl = this.buildMapSnapshotUrl()
				this.showMapSnapshot = true
				this.mapVisible = false
				this.showRegionPicker = true
			},

			closeRegionPicker() {
				this.showRegionPicker = false

				if (this.popupRestoreTimer) {
					clearTimeout(this.popupRestoreTimer)
				}

				this.popupRestoreTimer = setTimeout(() => {
					this.showMapSnapshot = false
					this.mapSnapshotUrl = ''

					this.ignoreRegionChangeOnce = true
					this.mapProgrammaticUntil = Date.now() + 500

					if (this.mapGuardTimer) {
						clearTimeout(this.mapGuardTimer)
					}
					this.mapGuardTimer = setTimeout(() => {
						this.ignoreRegionChangeOnce = false
						this.mapGuardTimer = null
					}, 550)

					this.mapVisible = true
					this.mapRenderKey += 1
					this.popupRestoreTimer = null
				}, 300)
			},

			onRegionChange(e) {
				const val = e.detail.value
				this.regionPickerValue = val

				const provinceIdx = val[0]
				const cityIdx = val[1] || 0

				if (this.regionProvinceList.length > provinceIdx) {
					this.regionCityList = this.regionProvinceList[provinceIdx].citys || []
					const maxCityIdx = this.regionCityList.length - 1
					const adjustedCityIdx = Math.min(cityIdx, maxCityIdx)

					if (adjustedCityIdx !== cityIdx) {
						this.regionPickerValue = [provinceIdx, adjustedCityIdx, 0]
					}

					if (this.regionCityList.length > adjustedCityIdx) {
						this.regionDistrictList = this.regionCityList[adjustedCityIdx].areas || []
						const areaIdx = val[2] || 0
						const maxAreaIdx = this.regionDistrictList.length - 1
						if (areaIdx > maxAreaIdx) {
							this.regionPickerValue = [provinceIdx, adjustedCityIdx, 0]
						}
					} else {
						this.regionDistrictList = []
						this.regionPickerValue = [provinceIdx, 0, 0]
					}
				} else {
					this.regionCityList = []
					this.regionDistrictList = []
					this.regionPickerValue = [0, 0, 0]
				}
			},

			async confirmRegion() {
				this.clearBlankPageInitLock()
				const [provinceIdx, cityIdx, districtIdx] = this.regionPickerValue
				const provinceItem = this.regionProvinceList[provinceIdx]
				const cityItem = this.regionCityList[cityIdx]
				const districtItem = this.regionDistrictList[districtIdx]

				if (!provinceItem || !cityItem || !districtItem) {
					uni.showToast({
						title: '选择无效',
						icon: 'none'
					})
					return
				}

				this.userSelectedRegion = true

				const regionStr = provinceItem.province + cityItem.city + districtItem.area
				this.currentProvince = provinceItem.province
				this.currentCity = cityItem.city
				this.currentDistrict = districtItem.area
				this.currentRegion = regionStr

				this.selectedProvinceCode = provinceItem.code
				this.selectedCityCode = cityItem.code
				this.selectedDistrictCode = districtItem.code

				this.isManualDetail = false
				this.suppressInitDetailFill = true
				this.detailAddress = ''
				this.manualDetail = ''
				this.currentDetail = ''

				const shortCode = districtItem.code ? districtItem.code.toString().slice(0, 6) : ''
				this.startDependencyInitLock()
				const center = await this.getDistrictCenter(districtItem.area, shortCode)

				if (center) {
					const [lng, lat] = center.split(',')
					this.updateMapCenter(parseFloat(lng), parseFloat(lat), true)
				} else {
					uni.showToast({
						title: '无法定位该地区，请手动拖动地图',
						icon: 'none'
					})
				}

				this.closeRegionPicker()
			},

			getDistrictCenter(keyword, adcode = '', subdistrict = 0) {
				return new Promise((resolve) => {
					const params = {
						key: this.amapKey,
						subdistrict,
						extensions: 'all'
					}

					const queryAdcode = () => {
						if (!adcode) return Promise.resolve(null)

						return new Promise((resolveInner) => {
							uni.request({
								url: 'https://restapi.amap.com/v3/config/district',
								method: 'GET',
								data: {
									...params,
									keywords: adcode.slice(0, 6)
								},
								success: (res) => {
									if (res.data.status === '1' && res.data.districts &&
										res.data.districts.length > 0) {
										const district = res.data.districts[0]
										if (district.center) {
											resolveInner(district.center)
											return
										}
									}
									resolveInner(null)
								},
								fail: () => resolveInner(null)
							})
						})
					}

					const queryKeyword = () => {
						return new Promise((resolveInner) => {
							uni.request({
								url: 'https://restapi.amap.com/v3/config/district',
								method: 'GET',
								data: {
									...params,
									keywords: keyword
								},
								success: (res) => {
									if (res.data.status === '1' && res.data.districts &&
										res.data.districts.length > 0) {
										const district = res.data.districts[0]
										if (district.center) {
											resolveInner(district.center)
											return
										}
									}
									resolveInner(null)
								},
								fail: () => resolveInner(null)
							})
						})
					}

					queryAdcode().then(center => {
						if (center) {
							resolve(center)
						} else {
							queryKeyword().then(resolve)
						}
					})
				})
			},

			onConfirm() {
				const fullAddress = (this.currentRegion + (this.detailAddress ? ' ' + this.detailAddress : '')).trim()

				const addressItem = {
					name: fullAddress,
					address: this.detailAddress,
					location: `${this.longitude},${this.latitude}`,
					pname: this.currentProvince,
					cityname: this.currentCity,
					adname: this.currentDistrict,
					province: this.currentProvince,
					city: this.currentCity,
					district: this.currentDistrict,
					provinceCode: this.selectedProvinceCode,
					cityCode: this.selectedCityCode,
					districtCode: this.selectedDistrictCode,
					source: this.source
				}

				const pages = getCurrentPages()
				const prevPage = pages[pages.length - 2]
				const currentPage = pages[pages.length - 1]
				const source = this.source || currentPage.options.source

				//特殊处理重庆
				if (addressItem.cityCode == 500100) {
					addressItem.cityname = "重庆城区"
				}
				if (addressItem.cityCode == 500200) {
					addressItem.cityname = "重庆郊县"
				}


				if (source === 'syr_info') {
					uni.$emit('address-selected-for-syr', addressItem)
					uni.setStorageSync('syr_selected_address', addressItem)
				} else if (source === 'sj_info') {
					uni.$emit('address-selected-for-sj', addressItem)
					uni.setStorageSync('sj_selected_address', addressItem)
					if (getApp().globalData) getApp().globalData.selectedAddress = addressItem
				} else if (prevPage) {
					if (prevPage.$vm && typeof prevPage.$vm.editAddress === 'function') {
						prevPage.$vm.editAddress(addressItem)
					} else {
						uni.$emit('address-selected', addressItem)
					}
				} else {
					uni.$emit('address-selected', addressItem)
				}

				uni.navigateBack()
			}
		}
	}
</script>

<style scoped lang="less">
	.search-address-page {
		flex: 1;
		height: 100vh;
		overflow: hidden;
		display: flex;
		flex-direction: column;
		background-color: #FFFFFF;
	}

	/* 城市选择 */
	.search-container {
		background-color: #FFFFFF;
		display: flex;
		flex-direction: row;
		align-items: center;
		padding: 32rpx 30rpx 20rpx 30rpx;

		.search-container-text {
			font-family: PingFangSC, PingFang SC;
			font-weight: 500;
			font-size: 32rpx;
			color: #333333;
			line-height: 45rpx;
		}

		.text-img {
			width: 20rpx;
			height: 12rpx;
			margin-left: 8rpx;
			margin-right: 26rpx;
		}
	}

	/* 地图区域 */
	.map-container {
		width: 750rpx;
		position: relative;
		overflow: hidden;
	}

	.map {
		width: 750rpx;
		height: 100%;
	}

	.map-snapshot {
		position: absolute;
		left: 0;
		top: 0;
		width: 750rpx;
		height: 100%;
		display: block;
		z-index: 2;
		background: #f5f5f5;
	}

	.center-marker {
		position: absolute;
		left: 375rpx;
		transform: translateX(-50%);
		top: 250rpx;
		width: 42rpx;
		height: 69rpx;
		z-index: 3;

		.center-marker-img {
			width: 42rpx;
		}
	}

	.map-snapshot {
		width: 750rpx;
		height: 100%;
		display: block;
	}

	/* 底部编辑区域（用户端样式） */
	.bottom-edit-section {
		background-color: #FFFFFF;
		padding: 20rpx 20rpx 120rpx 20rpx;
		flex: 1;
		display: flex;
		flex-direction: column;
	}

	/* 固定按钮栏 */
	.fixed-confirm-bar {
		position: fixed;
		bottom: 0;
		left: 0;
		right: 0;
		background-color: #FFFFFF;
		padding: 20rpx 20rpx env(safe-area-inset-bottom) 20rpx;
		/* 适配刘海屏 */
		box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
		z-index: 10;
	}

	.address-input-row {
		// width: 702rpx;
		display: flex;
		flex-direction: column;
		background-color: #F5F5F5;
		border-radius: 20rpx;
		padding: 16rpx 24rpx;
		margin-bottom: 30rpx;
	}

	.raw-address-input {
		width: 100%;
		height: 120rpx;
		font-size: 14px;
		color: #333333;
		background-color: transparent;
		border-width: 0;
		padding: 0;
		margin: 0;
	}

	.action-buttons {
		display: flex;
		flex-direction: row;
		justify-content: flex-end;
		margin-top: 0rpx;
	}

	.action-btn {
		margin-left: 16rpx;
		padding: 7rpx 20rpx;
		font-size: 24rpx;
		border-radius: 11rpx;
		border-width: 1rpx;
		border-style: solid;
		background-color: transparent;
		align-items: center;
		justify-content: center;
	}

	.action-btn:first-child {
		margin-left: 0;
	}

	.btn-text {
		font-size: 24rpx;
		font-weight: 400;
		line-height: 33rpx;
	}

	.paste-btn {
		border-color: #C6C9CC;
		color: #333333;
	}

	.smart-btn {
		border-color: #C6C9CC;
		color: #999999;
	}

	.smart-btn.smart-btn-active {
		border-color: #E8101E;
		color: #E8101E;
	}

	.address-info-panel {
		background-color: #FFFFFF;
		border-radius: 16rpx;
		margin-bottom: 40rpx;
	}

	.info-row {
		display: flex;
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
		padding: 30rpx 0;
	}

	.line {
		border-bottom: 1rpx solid #F0F0F0;
		width: 540rpx;
		margin-left: 150rpx;
	}

	.row-label {
		font-size: 28rpx;
		color: #333333;
		font-weight: 500;
		width: 160rpx;
	}

	.row-content {
		flex: 1;
		display: flex;
		flex-direction: row;
		align-items: center;
		justify-content: flex-start;
	}

	.content-text {
		font-size: 28rpx;
		color: #333333;
		margin-right: 12rpx;
		flex: 1;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}

	.placeholder {
		color: #999999;
		font-size: 28rpx;
	}

	.arrow-icon {
		width: 14rpx;
		height: 26rpx;
		position: absolute;
		right: 60rpx;
	}

	.detail-input {
		flex: 1;
		font-size: 28rpx;
		color: #333333;
		padding: 0;
		border-width: 0;
		background-color: transparent;
		height: 60rpx;
	}

	.confirm-btn {
		background-color: #E8101E;
		border-radius: 49rpx;
		height: 98rpx;
		display: flex;
		align-items: center;
		justify-content: center;
		font-size: 32rpx;
		color: #FFFFFF;
		// margin-top: 40rpx;
	}

	.con-btn-text {
		font-size: 32rpx;
		color: #FFFFFF;
	}

	/* 弹窗基础 */
	.popup {
		position: fixed;
		left: 0;
		right: 0;
		bottom: 0;
		z-index: 9999;
		visibility: hidden;
		opacity: 0;
		transition: all 0.3s ease;
	}

	.popup.show {
		visibility: visible !important;
		opacity: 1 !important;
	}

	.popup-mask {
		position: fixed;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		background-color: rgba(0, 0, 0, 0.5);
	}

	.popup-content {
		position: relative;
		background-color: #ffffff;
		border-radius: 24rpx 24rpx 0 0;
		padding: 32rpx;
		transform: translateY(100%);
		transition: transform 0.3s ease;
		max-height: 70vh;
	}

	.popup.show .popup-content {
		transform: translateY(0);
	}

	.popup-header {
		display: flex;
		align-items: center;
		justify-content: space-between;
		margin-bottom: 20rpx;
		padding: 0 0 20rpx 0;
		border-bottom: 1rpx solid #F0F0F0;
	}

	.popup-title {
		font-size: 32rpx;
		font-weight: 500;
		color: #333;
	}

	.popup-close {
		font-size: 40rpx;
		color: #999;
		padding: 10rpx;
	}

	.region-body {
		height: 400rpx;
		overflow: hidden;
	}

	.picker-scroll {
		height: 400rpx;
	}

	.picker-item {
		height: 68rpx;
		line-height: 68rpx;
		text-align: center;
		font-size: 28rpx;
		color: #333;
	}

	.popup-footer {
		display: flex;
		margin-top: 30rpx;
		padding-top: 20rpx;
		border-top: 1rpx solid #F0F0F0;
	}

	.popup-btn {
		flex: 1;
		height: 88rpx;
		border-radius: 44rpx;
		display: flex;
		align-items: center;
		justify-content: center;
		margin: 0 16rpx;
	}

	.popup-btn.cancel {
		background-color: #f5f5f5;
	}

	.popup-btn.confirm {
		background: #e8101e;
	}

	.popup-btn .btn-text {
		font-size: 32rpx;
		font-weight: 500;
	}

	.popup-btn.cancel .btn-text {
		color: #666666;
	}

	.popup-btn.confirm .btn-text {
		color: #ffffff;
	}

	/* 指示器样式（沿用原有） */
	.indicatorStyle {
		height: 68rpx;
	}
</style>