地址bug

This commit is contained in:
BAKEYi 2026-04-02 11:17:01 +08:00
parent 7f432b6bf6
commit 48cc4f66a9
1 changed files with 180 additions and 102 deletions

View File

@ -140,6 +140,7 @@
export default { export default {
data() { data() {
return { return {
useApiRawRecognize: false, // APItrue
mapVisible: true, mapVisible: true,
showMapSnapshot: false, showMapSnapshot: false,
mapSnapshotUrl: '', mapSnapshotUrl: '',
@ -394,6 +395,64 @@
}, },
methods: { 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) { startDependencyInitLock(duration = 800) {
this.dependencyInitLock = true this.dependencyInitLock = true
@ -1036,28 +1095,46 @@
const value = String(text || '').trim() const value = String(text || '').trim()
if (!value) return true if (!value) return true
// 1. //
const addressKeywords = [ if (/(价格|价钱|多少钱|举报|投诉|建议|咨询|测试|示例|比如|比方|假设|无效|乱填)/i.test(value)) {
'路', '街', '巷', '道', '号', '栋', '幢', '楼', '层', '室', '单元', return true
'门', '里', '弄', '小区', '花园', '广场', '大厦', '中心', '苑', '园', }
'村', '镇', '乡', '街', '大道', '胡同', '巷子', '店', '场', '城'
]
const hasKeyword = addressKeywords.some(kw => value.includes(kw))
// 2. + /165160ugf8oe
const hasChinese = /[\u4e00-\u9fa5]/.test(value)
const hasDigitOrLetter = /[a-zA-Z0-9]/.test(value)
const isLikelyGarbage = hasChinese && hasDigitOrLetter && !hasKeyword
// 3. //
const longPureLetters = /\b[A-Za-z]{4,}\b/.test(value) && !/[A-Za-z]\d|\d[A-Za-z]/.test(value) if (/^\d{6,}$/.test(value) || /^[A-Za-z]{6,}$/.test(value)) {
return true
}
// 4. //
const hasInvalidNoise = /(价格|价钱|多少钱|举报|投诉|建议|咨询|测试|示例|比如|比方|假设|无效|乱填)/i.test(value) const specialChars = (value.match(/[^\u4e00-\u9fa5a-zA-Z0-9]/g) || []).length
if (specialChars / value.length > 0.3) {
return true
}
if (hasInvalidNoise && !hasKeyword && !hasDigitOrLetter) return true //
if (longPureLetters && !hasKeyword && !hasDigitOrLetter) return true if (value.length < 2) {
if (isLikelyGarbage) return true return true
if (!hasChinese && !hasDigitOrLetter && !hasKeyword) 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 return false
}, },
@ -1076,31 +1153,32 @@
validateRecognizedDetail(detailText, geo, requireKeyword = true) { validateRecognizedDetail(detailText, geo, requireKeyword = true) {
const cleaned = String(detailText || '').trim() const cleaned = String(detailText || '').trim()
if (!cleaned) { if (!cleaned) {
return { valid: false, cleaned: '', reason: 'empty' } return { valid: false, cleaned: '', reason: 'empty' }
} }
// //
const hasKeyword = /(路|街|巷|道|号|栋|幢|楼|层|室|单元|门|里|弄|小区|花园|广场|大厦|中心|苑|园|村|镇|乡)/.test(cleaned)
if (requireKeyword && !hasKeyword) {
return { valid: false, cleaned: '', reason: 'no_address_keyword' }
}
if (this.isLikelyInvalidRecognizedDetail(cleaned)) { if (this.isLikelyInvalidRecognizedDetail(cleaned)) {
return { valid: false, cleaned: '', reason: 'invalid_text' } return { valid: false, cleaned: '', reason: 'invalid_detail' }
} }
//
const geoLevel = String(geo?.level || '').trim()
const preciseLevel = this.isPreciseGeocodeLevel(geoLevel)
const hasAddressFeature = this.hasStrongAddressFeature(cleaned)
//
if (!geo) { if (!geo) {
return { valid: false, cleaned: '', reason: 'geocode_failed' } return { valid: false, cleaned: '', reason: 'geocode_failed' }
} }
// //
if (!this.isPreciseGeocodeLevel(geo.level) && !hasKeyword) { if (hasAddressFeature || preciseLevel) {
return { valid: false, cleaned: '', reason: 'low_precision' } return { valid: true, cleaned, reason: '' }
} }
return { valid: true, cleaned, reason: '' } //
return { valid: false, cleaned: '', reason: 'detail_not_precise' }
}, },
cleanRecognizedDetail(detail, province, city, district, town) { cleanRecognizedDetail(detail, province, city, district, town) {
@ -1136,29 +1214,23 @@
}, },
buildExactRecognizedDetail(hit, sanitizedText, province, city, district) { buildExactRecognizedDetail(hit, sanitizedText, province, city, district) {
const directDetail = ( const directDetail = (hit?.detail || hit?.address || hit?.addr || hit?.full_address_detail || hit?.address_detail || '').trim();
hit?.detail ||
hit?.address ||
hit?.addr ||
hit?.full_address_detail ||
hit?.address_detail ||
''
).trim()
// //
if (directDetail) { const stripped = this.stripLeadingRegionParts(
return directDetail
}
//
return this.stripLeadingRegionParts(
sanitizedText, sanitizedText,
[ [province, city, district].filter(Boolean)
province || '', ).trim();
city && city !== province ? city : '',
district || '' // directDetail 使使 stripped
] if (directDetail && directDetail.length >= 4) {
) // stripped directDetail stripped 使 stripped
if (stripped.length > directDetail.length && stripped.startsWith(directDetail)) {
return stripped;
}
return directDetail;
}
return stripped;
}, },
getRecognizeLevel(hit, detailText, rawText) { getRecognizeLevel(hit, detailText, rawText) {
@ -1457,9 +1529,12 @@
stripLeadingRegionParts(text, parts = []) { stripLeadingRegionParts(text, parts = []) {
let result = String(text || '').trim() let result = String(text || '').trim()
const validParts = parts
.map(item => String(item || '').trim()) const validParts = [...new Set(
.filter(Boolean) parts
.map(item => String(item || '').trim())
.filter(Boolean)
)].sort((a, b) => b.length - a.length)
if (!result || !validParts.length) return result if (!result || !validParts.length) return result
@ -1500,9 +1575,7 @@
} }
const hasNetwork = await this.ensureRecognizeNetworkAvailable() const hasNetwork = await this.ensureRecognizeNetworkAvailable()
if (!hasNetwork) { if (!hasNetwork) return
return
}
const sanitizedText = this.sanitizeRawAddress(originalRawText) const sanitizedText = this.sanitizeRawAddress(originalRawText)
const removedNoise = sanitizedText !== originalRawText const removedNoise = sanitizedText !== originalRawText
@ -1531,15 +1604,18 @@
console.log('智能识别标准化结果:', hit) console.log('智能识别标准化结果:', hit)
const province = (hit.province_name || '').trim() const normalizedRegion = this.normalizeRecognizedRegionParts(
const city = (hit.city_name || '').trim() hit.province_name,
const district = (hit.county_name || '').trim() hit.city_name,
hit.county_name
)
const province = normalizedRegion.province
const city = normalizedRegion.city
const district = normalizedRegion.district
const town = (hit.town_name || '').trim() const town = (hit.town_name || '').trim()
let regionText = '' const regionText = this.buildRegionText(province, city, district)
if (province) regionText += province
if (city && city !== province) regionText += city
if (district) regionText += district
if (!regionText) { if (!regionText) {
uni.hideLoading() uni.hideLoading()
@ -1591,8 +1667,8 @@
geo = fullGeoResult.data geo = fullGeoResult.data
// 使 // ========== 1使 validateRecognizedDetail ==========
// // /
const detailDecision = this.validateRecognizedDetail(detailCandidate, geo, true) const detailDecision = this.validateRecognizedDetail(detailCandidate, geo, true)
detailRejected = !detailDecision.valid && !!detailCandidate detailRejected = !detailDecision.valid && !!detailCandidate
detailText = detailDecision.valid ? detailDecision.cleaned : '' detailText = detailDecision.valid ? detailDecision.cleaned : ''
@ -1606,8 +1682,7 @@
return return
} }
geo = regionGeoResult.data geo = regionGeoResult.data
// detailText = '' //
detailText = ''
} }
if (geo) { if (geo) {
@ -1650,6 +1725,7 @@
detailRejected detailRejected
) )
// //
if (level === 'low' || shouldOnlyToast) { if (level === 'low' || shouldOnlyToast) {
uni.hideLoading() uni.hideLoading()
@ -1678,39 +1754,8 @@
return return
} }
// ====== ====== //
this.currentProvince = province this.commitRecognizedResult(province, city, district, regionText, detailText, geo, level, removedNoise, geocodeOk, hit, detailRejected)
this.currentCity = city
this.currentDistrict = district
this.currentRegion = regionText
this.selectedProvinceCode = hit.province_code || ''
this.selectedCityCode = hit.city_code || ''
this.selectedDistrictCode = hit.county_code || ''
//
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'
})
}
} catch (error) { } catch (error) {
console.error('智能识别失败:', error) console.error('智能识别失败:', error)
uni.hideLoading() uni.hideLoading()
@ -1727,6 +1772,39 @@
} }
}, },
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.selectedCityCode = hit.city_code || ''
this.selectedDistrictCode = hit.county_code || ''
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) { updateMapCenter(longitude, latitude, noReverse = false) {
const lng = parseFloat(longitude) const lng = parseFloat(longitude)