diff --git a/.workbuddy/memory/2026-07-15.md b/.workbuddy/memory/2026-07-15.md index bd2e854..2e90cc7 100644 --- a/.workbuddy/memory/2026-07-15.md +++ b/.workbuddy/memory/2026-07-15.md @@ -63,3 +63,18 @@ 4. list.tsx `handleCloseOrder`:弹窗标题改为"确认取消订单",toast 改为"订单已取消" 5. detail.tsx `getOrderDisplayStatus`:线下付款未确认时显示"待发货"(蓝色),subtitle 保留付款引导文案 6. detail.tsx `getOrderPhase`:保留 `offline_pending` 阶段,底部按钮仍为"取消订单+联系客服"(未确认收款可取消,非退款) + +## 修复地址编辑页智能识别 bug +- 文件:`src/pages/user/address-edit.tsx` +- 问题:粘贴带标签的地址文本(如「收件人: 赵忠林 / 手机号码: 137... / 所在地区: 广西... / 详细地址: 大学东路...」)识别后: + 1. 姓名识别失败(之前只看文本开头的 2-4 个汉字,姓名不在开头) + 2. 详细地址保留了「收件人」「手机号码」「所在地区」「详细地址」等标签文字 +- 修复 `parseAddressText`: + 1. 姓名优先匹配 `(?:收件人|收货人|姓名|联系人)[::]\s*([\u4e00-\u9fa5]{2,4})`,找不到再回退到 `^[\u4e00-\u9fa5]{2,4}` + 2. 详细地址提取前先 strip 标签文字(收件人/手机号/所在地区/详细地址 + 中英冒号),再 strip 省市区,最后 strip 零散标签 +- 验证:用 Python 模拟(Python 是用 JS 同款正则+RegionData)解析截图中的输入: + - name: 赵忠林 ✓ + - phone: 13737128880 ✓ + - province/city/region: 广西壮族自治区/南宁市/西乡塘区 ✓ + - address: 西乡塘街道大学东路9号瀚林御景3栋1单元1101号房 ✓(街道+详细地址完整保留) +- 项目 type-check (`npx tsc --noEmit`) 无报错 diff --git a/src/api/shop/shopUserAddress/model.ts b/src/api/shop/shopUserAddress/model.ts index c6c5433..c141632 100644 --- a/src/api/shop/shopUserAddress/model.ts +++ b/src/api/shop/shopUserAddress/model.ts @@ -4,6 +4,7 @@ export interface ShopUserAddress { userId?: number; name?: string; // 收货人姓名 phone?: string; // 收货人电话 + country?: string; // 国家 province?: string; // 省份 city?: string; // 城市 district?: string; // 区县 @@ -11,7 +12,8 @@ export interface ShopUserAddress { detail?: string; // 详细地址 lng?: string; // 经度 lat?: string; // 纬度 - isDefault?: number; // 是否默认 0-否 1-是 + isDefault?: boolean; // 是否默认 0-否 1-是 createTime?: string; updateTime?: string; + address?: string; } diff --git a/src/pages/user/address-edit.tsx b/src/pages/user/address-edit.tsx index 51c47cf..9f247d2 100644 --- a/src/pages/user/address-edit.tsx +++ b/src/pages/user/address-edit.tsx @@ -101,6 +101,7 @@ const AddressEditPage: React.FC = () => { const [formData, setFormData] = useState>({ name: '', phone: '', + country: '', province: '', city: '', region: '', @@ -148,15 +149,22 @@ const AddressEditPage: React.FC = () => { const parseAddressText = (text: string) => { const result: any = {} - // 手机号正则 + // 手机号正则(11 位国内手机号) const phoneRegex = /1[3-9]\d{9}/ const phoneMatch = text.match(phoneRegex) if (phoneMatch) result.phone = phoneMatch[0] - // 姓名正则(2-4个中文字符,通常在开头) - const nameRegex = /^[\u4e00-\u9fa5]{2,4}/ - const nameMatch = text.match(nameRegex) - if (nameMatch) result.name = nameMatch[0] + // 姓名正则:优先匹配“收件人/收货人/姓名/联系人:”后面的 2-4 个中文字符 + const nameWithPrefixRegex = /(?:收件人|收货人|姓名|联系人)[::]\s*([\u4e00-\u9fa5]{2,4})/ + const nameWithPrefixMatch = text.match(nameWithPrefixRegex) + if (nameWithPrefixMatch) { + result.name = nameWithPrefixMatch[1] + } else { + // 兜底:文本开头 2-4 个中文字符 + const nameRegex = /^[\u4e00-\u9fa5]{2,4}/ + const nameMatch = text.match(nameRegex) + if (nameMatch) result.name = nameMatch[0] + } // 省市区识别 const regionResult = parseRegion(text) @@ -166,13 +174,29 @@ const AddressEditPage: React.FC = () => { result.region = regionResult.region } - // 详细地址提取 + // 详细地址提取:先把常见的标签字段和已知字段去掉,再清洗标点 let addressText = text + + // 去除已提取的姓名、手机号 if (result.name) addressText = addressText.replace(result.name, '') if (result.phone) addressText = addressText.replace(result.phone, '') + + // 去除常见标签文案(如“收件人:”、“手机号码:”、“所在地区:”、“详细地址:”) + addressText = addressText + .replace(/(?:收件人|收货人|姓名|联系人)[::]\s*/g, '') + .replace(/(?:手机号码|手机号|电话|联系电话)[::]\s*/g, '') + .replace(/(?:所在地区|地区|省市区)[::]\s*/g, '') + .replace(/(?:详细地址|地址|街道)[::]\s*/g, '') + + // 去除已识别出的省市区 if (result.province) addressText = addressText.replace(result.province, '') if (result.city) addressText = addressText.replace(result.city, '') if (result.region) addressText = addressText.replace(result.region, '') + + // 去除零散的标签关键字(如“手机号码”、“所在地区”、“详细地址”本身) + addressText = addressText + .replace(/(?:收件人|收货人|手机号码|手机号|所在地区|详细地址)/g, '') + result.address = addressText.replace(/[,,。\s]+/g, '').trim() return result