diff --git a/app/inquiry/service/FbFileImportService.php b/app/inquiry/service/FbFileImportService.php index c598158..94e11c4 100644 --- a/app/inquiry/service/FbFileImportService.php +++ b/app/inquiry/service/FbFileImportService.php @@ -91,18 +91,35 @@ class FbFileImportService case 'is_organic': $item['is_organic'] = $this->normalizeIsOrganic($raw); break; + case 'fb_created_time': - // ✅ 方案B:写入 DATETIME 字符串 - $item['fb_created_time'] = $this->normalizeCreatedTime($raw); + $item['fb_created_time'] = $this->normalizeCreatedTime($raw); // 你方案B的datetime break; + + // ✅ 这些是数值ID字段:可能出现 ag:/as:/c:/f:/l: 前缀 + case 'ad_id': + case 'adset_id': + case 'campaign_id': + case 'form_id': + $item[$field] = $this->normalizeNumericId($raw); + break; + + // ✅ lead id 也经常是 l:xxxx + case 'fb_lead_id': + $item['fb_lead_id'] = $this->normalizeNumericId($raw); + break; + + // ✅ 电话可能是 p:+233xxxx + case 'phone': + $item['phone'] = $this->normalizePhone($raw); + break; + default: - // 小增强:字符串统一 trim(避免 " xxx ") - if (is_string($raw)) { - $raw = trim($raw); - } + if (is_string($raw)) $raw = trim($raw); $item[$field] = $raw; break; } + } // 未知列收集到 extra_data(宽松模式) @@ -131,6 +148,51 @@ class FbFileImportService return count($insertData); } + /** + * 把 "ag:120..." / "l:831..." / "120..." 这种值清洗成纯数字(int 或 string数字) + * - 如果你的 DB 字段是 BIGINT UNSIGNED,PHP int 在 64 位环境下是够用的 + * - 解析失败返回 0(避免 insert 失败) + */ + protected function normalizeNumericId($raw) + { + if ($raw === null || $raw === '') return 0; + + // 数字直接返回 + if (is_int($raw)) return $raw; + if (is_float($raw)) return (int)$raw; + + $s = trim((string)$raw); + if ($s === '') return 0; + + // 取出所有数字拼成一段(ag:120... -> 120..., l:xxx -> xxx) + $digits = preg_replace('/\D+/', '', $s); + if ($digits === '') return 0; + + // 这里返回字符串数字也可以,MySQL 会转;返回 int 在 64 位一般没问题 + // 若你担心超出 int,可直接 return $digits; + return $digits; + } + + /** + * 电话清洗:去掉 "p:" 前缀,保留 + 和数字 + */ + protected function normalizePhone($raw): string + { + if ($raw === null) return ''; + + $s = trim((string)$raw); + if ($s === '') return ''; + + // 去掉类似 "p:" "tel:" 等前缀 + $s = preg_replace('/^[a-zA-Z]+:\s*/', '', $s); + + // 保留 + 和数字 + $s = preg_replace('/[^\d\+]+/', '', $s); + + return $s; + } + + /** * 规范化 is_organic 字段为 0/1 */ diff --git a/app/inquiry/utils/FbLeadHeaderMapper.php b/app/inquiry/utils/FbLeadHeaderMapper.php index 60b17dc..8f9e888 100644 --- a/app/inquiry/utils/FbLeadHeaderMapper.php +++ b/app/inquiry/utils/FbLeadHeaderMapper.php @@ -78,6 +78,44 @@ class FbLeadHeaderMapper 'email', ]; + /** + * 表头别名:标准化后表头 => headerMap里的key + */ + protected array $aliases = [ + // ===== full_name ===== + 'name' => 'full_name', + 'full_name' => 'full_name', + 'full_name_(full_name)' => 'full_name', + 'full_name_(full_name_)' => 'full_name', + 'full_name_full_name' => 'full_name', + 'full name' => 'full_name', // 万一没被替换成 _ + 'full_name(full_name)' => 'full_name', + '姓名' => 'full_name', + '姓名_full_name' => 'full_name', + '姓名(full_name)' => 'full_name', + + // ===== phone ===== + 'phone' => 'phone', + 'phone_number' => 'phone_number', + 'phone number' => 'phone_number', + 'telephone' => 'phone', + 'tel' => 'phone', + 'mobile' => 'phone', + 'mobile_number' => 'phone', + '手机号' => 'phone', + '电话' => 'phone', + '电话号码' => 'phone', + 'whatsapp' => 'phone', // 有的表单把 whatsapp 当电话 + + // ===== email ===== + 'email' => 'email', + 'e-mail' => 'email', + 'mail' => 'email', + '邮箱' => 'email', + '电子邮箱' => 'email', + ]; + + /** * 返回所有支持的 Excel 表头(标准化后的 key) */ @@ -92,6 +130,7 @@ class FbLeadHeaderMapper public function mapHeader(string $rawHeader): ?string { $key = $this->normalizeHeader($rawHeader); + $key = $this->aliases[$key] ?? $key; return $this->headerMap[$key] ?? null; } @@ -146,7 +185,9 @@ class FbLeadHeaderMapper continue; } - $field = $this->headerMap[$key] ?? null; + // $field = $this->headerMap[$key] ?? null; + $aliasKey = $this->aliases[$key] ?? $key; + $field = $this->headerMap[$aliasKey] ?? null; if ($field === null) { // 宽松:记录未知列(保留原始表头用于展示) @@ -192,21 +233,31 @@ class FbLeadHeaderMapper { // 去掉 UTF-8 BOM $header = preg_replace('/^\xEF\xBB\xBF/', '', $header); - - // 去掉前后空白 $header = trim($header); + if ($header === '') return ''; - if ($header === '') { - return ''; - } + // 统一全角括号 + $header = str_replace(['(',')'], ['(',')'], $header); - // 可选增强(默认不开启,避免影响中文): - // $header = mb_strtolower($header); - // $header = preg_replace('/\s+/', '_', $header); + // 小写化(对英文有效,中文不受影响) + $header = mb_strtolower($header); + + // 把括号内容保留下来,但用下划线连接: "姓名(Full name)" -> "姓名_full_name" + $header = preg_replace('/\((.*?)\)/', '_$1', $header); + + // 空白转下划线 + $header = preg_replace('/\s+/', '_', $header); + + // 连续下划线压缩 + $header = preg_replace('/_+/', '_', $header); + + // 去掉首尾下划线 + $header = trim($header, '_'); // ✅ 去掉末尾连续的 "_" / "?" $header = rtrim($header, "_?"); return $header; } + }