feat(user): 优化地址添加页面的地图定位功能

- 移除地图选点地址与收货地址的自动同步逻辑
- 改进地图选点地址解析,避免省市区字段重复显示
- 添加经纬度有效性校验,防止无效数值传递给位置选择器
- 将选择定位组件移至表单下方并重新排列布局
- 为收货人和手机号字段添加更严格的验证规则
- 保留地图定位功能的完整交互界面和错误处理
This commit is contained in:
2026-02-09 17:28:00 +08:00
parent 8d2188b928
commit 50ac79d055

View File

@@ -250,16 +250,6 @@ const AddUserAddress = () => {
} }
setSelectedLocation(next) setSelectedLocation(next)
// 将地图选点的地址同步到“收货地址”,减少用户重复输入
const nextDetailAddress = (() => {
const addr = String(res.address || '').trim()
const name = String(res.name || '').trim()
if (!addr && !name) return ''
if (!addr) return name
if (!name) return addr
return addr.includes(name) ? addr : `${addr} ${name}`
})()
// 尝试从地图返回的 address 文本解析省市区best-effort // 尝试从地图返回的 address 文本解析省市区best-effort
const regionResult = res?.provinceName || res?.cityName || res?.adName const regionResult = res?.provinceName || res?.cityName || res?.adName
? { ? {
@@ -269,6 +259,29 @@ const AddUserAddress = () => {
} }
: parseRegion(String(res.address || '')) : parseRegion(String(res.address || ''))
// 将地图选点的地址同步到“收货地址”(不额外拼接省市区字段,省市区由独立字段保存)
const nextDetailAddress = (() => {
const rawAddr = String(res.address || '').trim()
const name = String(res.name || '').trim()
const province = String(regionResult?.province || '').trim()
const city = String(regionResult?.city || '').trim()
const region = String(regionResult?.region || '').trim()
// 选择定位返回的 address 往往包含省市区,这里尽量剥离掉,避免和表单的省市区字段重复
let detail = rawAddr
for (const part of [province, city, region]) {
if (part) detail = detail.replace(part, '')
}
detail = detail.replace(/[,]+/g, ' ').replace(/\s+/g, ' ').trim()
const base = detail || rawAddr
if (!base && !name) return ''
if (!base) return name
if (!name) return base
return base.includes(name) ? base : `${base} ${name}`
})()
setFormData(prev => ({ setFormData(prev => ({
...prev, ...prev,
lng: next.lng, lng: next.lng,
@@ -295,9 +308,11 @@ const AddUserAddress = () => {
try { try {
const initLat = selectedLocation?.lat ? Number(selectedLocation.lat) : undefined const initLat = selectedLocation?.lat ? Number(selectedLocation.lat) : undefined
const initLng = selectedLocation?.lng ? Number(selectedLocation.lng) : undefined const initLng = selectedLocation?.lng ? Number(selectedLocation.lng) : undefined
const latitude = typeof initLat === 'number' && Number.isFinite(initLat) ? initLat : undefined
const longitude = typeof initLng === 'number' && Number.isFinite(initLng) ? initLng : undefined
const res = await Taro.chooseLocation({ const res = await Taro.chooseLocation({
latitude: Number.isFinite(initLat as number) ? (initLat as number) : undefined, latitude,
longitude: Number.isFinite(initLng as number) ? (initLng as number) : undefined longitude
}) })
applyChosenLocation(res) applyChosenLocation(res)
} catch (e: any) { } catch (e: any) {
@@ -452,7 +467,43 @@ const AddUserAddress = () => {
</div> </div>
</CellGroup> </CellGroup>
<View className={'bg-gray-100 h-3'}></View> <View className={'bg-gray-100 h-3'}></View>
<CellGroup className={'px-3'}> <CellGroup style={{padding: '4px 0'}}>
<Form.Item
name="name"
label="收货人"
initialValue={FormData.name}
rules={[{ required: true, message: '请输入收货人姓名' }]}
required
>
<Input placeholder="请输入收货人姓名" maxLength={10}/>
</Form.Item>
<Form.Item
name="phone"
label="手机号"
initialValue={FormData.phone}
rules={[
{ required: true, message: '请输入手机号' },
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号' }
]}
required
>
<Input placeholder="请输入手机号" maxLength={11}/>
</Form.Item>
<Form.Item
label="所在地区"
name="region"
initialValue={FormData.region}
rules={[{message: '请输入您的所在地区'}]}
required
>
<div className={'flex justify-between items-center'} onClick={() => setVisible(true)}>
<Input placeholder="选择所在地区" value={text} disabled/>
<ArrowRight className={'text-gray-400'}/>
</div>
</Form.Item>
<Form.Item name="address" label="收货地址" initialValue={FormData.address} required>
<TextArea maxLength={50} placeholder="请输入详细收货地址"/>
</Form.Item>
<Cell <Cell
title="选择定位" title="选择定位"
description={ description={
@@ -473,30 +524,6 @@ const AddUserAddress = () => {
onClick={chooseGeoLocation} onClick={chooseGeoLocation}
/> />
</CellGroup> </CellGroup>
<View className={'bg-gray-100 h-3'}></View>
<CellGroup style={{padding: '4px 0'}}>
<Form.Item name="name" label="收货人" initialValue={FormData.name} required>
<Input placeholder="请输入收货人姓名" maxLength={10}/>
</Form.Item>
<Form.Item name="phone" label="手机号" initialValue={FormData.phone} required>
<Input placeholder="请输入手机号" maxLength={11}/>
</Form.Item>
<Form.Item
label="所在地区"
name="region"
initialValue={FormData.region}
rules={[{message: '请输入您的所在地区'}]}
required
>
<div className={'flex justify-between items-center'} onClick={() => setVisible(true)}>
<Input placeholder="选择所在地区" value={text} disabled/>
<ArrowRight className={'text-gray-400'}/>
</div>
</Form.Item>
<Form.Item name="address" label="收货地址" initialValue={FormData.address} required>
<TextArea maxLength={50} placeholder="请输入详细收货地址"/>
</Form.Item>
</CellGroup>
</Form> </Form>
<Address <Address