importOneFile($filePath, $channelId); $count++; // 导入成功后,把文件重命名为 .xlsx.done,避免下次重复导入 $newPath = $filePath . '.done'; if (!@rename($filePath, $newPath)) { Log::warning("FbFileImportService: 文件导入成功,但重命名失败:{$filePath} -> {$newPath}"); } else { Log::info("FbFileImportService: 文件导入并标记完成:{$newPath}(行数:{$rows})"); } } return $count; } /** * 导入单个 Excel 到 fb_leads * * @param string $filePath * @param int $channelId 渠道ID * @return int 导入的记录条数 * @throws BusinessException */ public function importOneFile(string $filePath, int $channelId): int { if (!is_file($filePath)) { throw new BusinessException("Excel 文件不存在:{$filePath}"); } $spreadsheet = IOFactory::load($filePath); $sheet = $spreadsheet->getActiveSheet(); $rows = $sheet->toArray(null, true, true, true); if (empty($rows)) { throw new BusinessException('Excel 内容为空:' . $filePath); } // 表头 $headerRow = array_shift($rows); $mapper = new FbLeadHeaderMapper(); // 如有未知字段,会在这里抛异常 $colToField = $mapper->buildColumnFieldMap($headerRow); $insertData = []; $now = time(); $sourceFile = basename($filePath); foreach ($rows as $row) { $item = []; foreach ($colToField as $colIndex => $field) { $raw = $row[$colIndex] ?? null; switch ($field) { case 'is_organic': $item['is_organic'] = $this->normalizeIsOrganic($raw); break; case 'fb_created_time': $item['fb_created_time'] = $this->normalizeCreatedTime($raw); break; default: $item[$field] = $raw; break; } } $item['source_file'] = $sourceFile; $item['channel'] = $channelId; // 👈 渠道ID记录到 fb_leads $item['created_at'] = $now; $item['updated_at'] = $now; $item['sync_status'] = 0; // 未同步到 inquiry_log $insertData[] = $item; } if ($insertData) { Db::table('fb_leads')->insert($insertData); } return count($insertData); } /** * 规范化 is_organic 字段为 0/1 */ protected function normalizeIsOrganic($raw): int { if (is_bool($raw)) { return $raw ? 1 : 0; } $str = strtolower((string)$raw); if ($str === '') { return 0; } return in_array($str, ['1', 'true', 'yes', 'organic'], true) ? 1 : 0; } /** * FB 创建时间目前按原始字符串存储 */ protected function normalizeCreatedTime($raw) { return $raw; } }