<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, true)
            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]),
                        true
                    )
                }
            } 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 (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>
