200) { $limit = 50; } $pdo = DB::getInstance()->getPdo(); $stmt = $pdo->prepare("SELECT id, full_name, hometown, graduated_from, gender, work_location FROM persons WHERE id = ?"); $stmt->execute([$personId]); $target = $stmt->fetch(); if (!$target) { Response::error('人员不存在'); } /** 省-市名称归一化:湖南省衡阳市 -> 湖南衡阳;新疆维吾尔自治区乌鲁木齐市 -> 新疆乌鲁木齐;北京市 -> 北京 */ function normalizeAreaName($s) { $s = trim((string)$s); if ($s === '') { return ''; } $muni = ['北京市' => '北京', '天津市' => '天津', '上海市' => '上海', '重庆市' => '重庆']; if (isset($muni[$s])) { return $muni[$s]; } // 自治区后缀(维吾尔/壮族/回族)及省后缀 $s = preg_replace('/(维吾尔|壮族|回族)?自治区$/', '', $s); $s = str_replace('省', '', $s); // 去掉末尾「市」 $s = preg_replace('/市$/', '', $s); $s = str_replace('特别行政区', '', $s); return $s; } $tHometown = normalizeAreaName($target['hometown']); $tWorkLoc = normalizeAreaName($target['work_location']); $tSchool = trim((string)$target['graduated_from']); $tGender = $target['gender']; $isGenderPair = ($tGender === '男' || $tGender === '女'); // 目标人员的任职公司集合:company_id => 入职年份 $expMap = []; // person_id => [ ['company_id'=>x,'sy'=>yyyy|null], ... ] $targetComps = []; // company_id => sy $stmt = $pdo->prepare( "SELECT person_id, company_id, YEAR(start_date) AS sy FROM person_work_experiences WHERE is_active = 1 AND person_id != ?" ); $stmt->execute([$personId]); $candIds = []; foreach ($stmt as $row) { $pid = (int)$row['person_id']; $expMap[$pid][] = ['company_id' => (int)$row['company_id'], 'sy' => $row['sy'] !== null ? (int)$row['sy'] : null]; $candIds[$pid] = true; } $stmt = $pdo->prepare( "SELECT company_id, YEAR(start_date) AS sy FROM person_work_experiences WHERE is_active = 1 AND person_id = ?" ); $stmt->execute([$personId]); foreach ($stmt as $row) { $targetComps[(int)$row['company_id']] = $row['sy'] !== null ? (int)$row['sy'] : null; } // 候选人员基本信息 $candList = $pdo->query( "SELECT id, full_name, hometown, graduated_from, gender, work_location FROM persons WHERE id != $personId AND is_active = 1" )->fetchAll(); // 手机号(常用优先) $phones = []; foreach ($pdo->query( "SELECT owner_id, account_id FROM social_accounts WHERE owner_type = 'person' AND platform = 'phone' AND is_active = 1 ORDER BY is_defult DESC, is_primary DESC, id DESC" ) as $row) { if (!isset($phones[$row['owner_id']])) { $phones[$row['owner_id']] = $row['account_id']; } } $result = []; foreach ($candList as $c) { $tags = []; $score = 0; // 老乡:市级一致(归一化后整体相等即省市都一致) $cHometown = normalizeAreaName($c['hometown']); if ($tHometown !== '' && $cHometown !== '' && $tHometown === $cHometown) { $tags[] = '老乡'; $score += 20; } // 校友 $cSchool = trim((string)$c['graduated_from']); if ($tSchool !== '' && $cSchool !== '' && $tSchool === $cSchool) { $tags[] = '校友'; $score += 20; } // 同事:任职公司交集 $shared = []; // company_id => [targetSy, candSy] foreach (($expMap[$c['id']] ?? []) as $e) { if (isset($targetComps[$e['company_id']])) { $shared[$e['company_id']] = [$targetComps[$e['company_id']], $e['sy']]; } } if ($shared) { $tags[] = '同事'; $score += 20; // 同一家公司任职次数≥2(两家及以上共同任职公司) if (count($shared) >= 2) { $score += 10; } // 同事且入职年份一致 foreach ($shared as $pair) { if ($pair[0] !== null && $pair[1] !== null && $pair[0] === $pair[1]) { $score += 10; break; } } } // 工作地点一致 $cWorkLoc = normalizeAreaName($c['work_location']); if ($tWorkLoc !== '' && $cWorkLoc !== '' && $tWorkLoc === $cWorkLoc) { $score += 10; } // 性别一致(均为男或均为女) if ($isGenderPair && ($c['gender'] === '男' || $c['gender'] === '女') && $c['gender'] === $tGender) { $score += 5; } // 至少有一种交集才进入人脉 if (!$tags) { continue; } // 随机 0~5(剩余百分比),总亲密上限 99(不能达到 100%) $score += mt_rand(0, 5); $score = min(99, $score); $result[] = [ 'id' => (int)$c['id'], 'full_name' => $c['full_name'], 'phone' => $phones[$c['id']] ?? '', 'tags' => $tags, 'intimacy' => $score, ]; } // 亲密度降序,其次按 id 升序 usort($result, function ($a, $b) { if ($b['intimacy'] !== $a['intimacy']) { return $b['intimacy'] - $a['intimacy']; } return $a['id'] - $b['id']; }); $result = array_slice($result, 0, $limit); Response::success(['list' => $result]);