企业微信外部联系人同步
This commit is contained in:
+250
@@ -0,0 +1,250 @@
|
||||
<?php
|
||||
// 同步企业微信客户的后台脚本
|
||||
|
||||
// 设置错误报告
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
// 设置执行时间
|
||||
set_time_limit(300);
|
||||
|
||||
// 设置内存限制
|
||||
ini_set('memory_limit', '512M');
|
||||
|
||||
// 引入框架
|
||||
require __DIR__ . '/server/thinkphp/start.php';
|
||||
|
||||
// 获取参数
|
||||
$paramFile = $argv[1] ?? '';
|
||||
$taskId = $argv[2] ?? '';
|
||||
|
||||
if (empty($paramFile) || empty($taskId)) {
|
||||
echo "Missing parameters\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// 读取参数文件
|
||||
if (!file_exists($paramFile)) {
|
||||
echo "Parameter file not found\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$params = json_decode(file_get_contents($paramFile), true);
|
||||
if (!$params) {
|
||||
echo "Invalid parameter file\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// 清理临时文件
|
||||
unlink($paramFile);
|
||||
|
||||
// 保存任务状态
|
||||
$cacheKey = 'qywx_sync_task_' . $taskId;
|
||||
Cache::set($cacheKey, [
|
||||
'status' => 'running',
|
||||
'progress' => 0,
|
||||
'start_time' => time(),
|
||||
'params' => $params
|
||||
], 86400);
|
||||
|
||||
try {
|
||||
$limit = $params['limit'] ?? 30;
|
||||
$fullSync = $params['full_sync'] ?? false;
|
||||
$syncMode = $params['sync_mode'] ?? 'all';
|
||||
$selectedUsers = $params['selected_users'] ?? [];
|
||||
$days = $params['days'] ?? 7;
|
||||
|
||||
$service = new \app\common\service\wechat\WechatWorkService();
|
||||
|
||||
// 1. 获取员工列表
|
||||
$userList = $service->getDepartmentUserList();
|
||||
if (empty($userList)) {
|
||||
throw new \Exception('未获取到员工列表');
|
||||
}
|
||||
|
||||
// 按同步模式过滤员工
|
||||
if ($syncMode === 'specific' && !empty($selectedUsers)) {
|
||||
$userList = array_filter($userList, function($user) use ($selectedUsers) {
|
||||
return in_array($user['userid'] ?? '', $selectedUsers);
|
||||
});
|
||||
}
|
||||
|
||||
$syncCount = 0;
|
||||
$newCount = 0;
|
||||
$updateCount = 0;
|
||||
$processedCustomers = [];
|
||||
|
||||
// 获取上次同步时间(使用缓存存储)
|
||||
$lastSyncCacheKey = 'qywx_last_sync_time';
|
||||
$lastSyncTime = Cache::get($lastSyncCacheKey, 0);
|
||||
$currentTime = time();
|
||||
|
||||
// 计算时间范围(最近N天)
|
||||
$timeLimit = $currentTime - ($days * 86400);
|
||||
|
||||
// 总任务量
|
||||
$totalTasks = count($userList);
|
||||
$currentTask = 0;
|
||||
|
||||
// 2. 遍历每个员工,获取其客户列表
|
||||
foreach ($userList as $user) {
|
||||
$userId = $user['userid'] ?? '';
|
||||
if (empty($userId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$currentTask++;
|
||||
$progress = round(($currentTask / $totalTasks) * 100);
|
||||
|
||||
// 更新任务状态
|
||||
Cache::set($cacheKey, [
|
||||
'status' => 'running',
|
||||
'progress' => $progress,
|
||||
'start_time' => $currentTime,
|
||||
'current_user' => $userId,
|
||||
'params' => $params
|
||||
], 86400);
|
||||
|
||||
// 获取该成员的客户列表(支持分页)
|
||||
$cursor = '';
|
||||
$hasMore = true;
|
||||
|
||||
while ($hasMore && $syncCount < $limit) {
|
||||
$customerResult = $service->getExternalContactList($userId, $cursor, 100);
|
||||
if (empty($customerResult) || empty($customerResult['external_userid'])) {
|
||||
break;
|
||||
}
|
||||
|
||||
$customerList = $customerResult['external_userid'] ?? [];
|
||||
$cursor = $customerResult['next_cursor'] ?? '';
|
||||
$hasMore = !empty($cursor);
|
||||
|
||||
// 3. 处理客户,限制总数量
|
||||
foreach ($customerList as $externalUserId) {
|
||||
// 达到限制数量,停止同步
|
||||
if ($syncCount >= $limit) {
|
||||
$hasMore = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// 避免重复处理同一个客户
|
||||
if (isset($processedCustomers[$externalUserId])) {
|
||||
continue;
|
||||
}
|
||||
$processedCustomers[$externalUserId] = true;
|
||||
|
||||
// 增量同步:检查客户是否已存在且更新时间较新
|
||||
if (!$fullSync) {
|
||||
$existing = \app\common\model\QywxExternalContact::where('external_user_id', $externalUserId)->find();
|
||||
if ($existing && $existing->update_time && strtotime($existing->update_time) > time() - 86400) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取客户详情
|
||||
$detail = $service->getExternalContactDetail($externalUserId);
|
||||
if (empty($detail)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$externalContact = $detail['external_contact'] ?? [];
|
||||
$followUsers = $detail['follow_user'] ?? [];
|
||||
|
||||
// 获取客户实际添加时间
|
||||
$createTime = time();
|
||||
if (!empty($followUsers)) {
|
||||
// 取第一个跟进人的添加时间
|
||||
$firstFollow = reset($followUsers);
|
||||
if (isset($firstFollow['create_time'])) {
|
||||
$createTime = $firstFollow['create_time'];
|
||||
}
|
||||
}
|
||||
|
||||
// 增量同步:只同步上次同步时间之后的客户
|
||||
if (!$fullSync && $createTime <= $lastSyncTime) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 时间范围过滤:只同步最近N天的客户
|
||||
if ($createTime < $timeLimit) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 保存或更新客户信息
|
||||
$data = [
|
||||
'external_user_id' => $externalContact['external_userid'] ?? '',
|
||||
'name' => $externalContact['name'] ?? '',
|
||||
'avatar' => $externalContact['avatar'] ?? '',
|
||||
'type' => $externalContact['type'] ?? 1,
|
||||
'gender' => $externalContact['gender'] ?? 0,
|
||||
'unionid' => $externalContact['unionid'] ?? '',
|
||||
'position' => $externalContact['position'] ?? '',
|
||||
'corp_name' => $externalContact['corp_name'] ?? '',
|
||||
'corp_full_name' => $externalContact['corp_full_name'] ?? '',
|
||||
'external_profile' => json_encode($externalContact['external_profile'] ?? [], JSON_UNESCAPED_UNICODE),
|
||||
'follow_users' => json_encode($followUsers, JSON_UNESCAPED_UNICODE),
|
||||
];
|
||||
|
||||
// 处理添加人信息
|
||||
if (!empty($followUsers)) {
|
||||
// 取第一个跟进人作为添加人
|
||||
$firstFollow = reset($followUsers);
|
||||
if (isset($firstFollow['userid']) && isset($firstFollow['name'])) {
|
||||
$data['first_staff_id'] = $firstFollow['userid'];
|
||||
$data['first_staff_name'] = $firstFollow['name'];
|
||||
$data['first_add_time'] = date('Y-m-d H:i:s', $createTime);
|
||||
$data['last_staff_id'] = $firstFollow['userid'];
|
||||
$data['last_staff_name'] = $firstFollow['name'];
|
||||
$data['last_add_time'] = date('Y-m-d H:i:s', $createTime);
|
||||
}
|
||||
}
|
||||
|
||||
$existing = \app\common\model\QywxExternalContact::where('external_user_id', $data['external_user_id'])->find();
|
||||
if ($existing) {
|
||||
$existing->save($data);
|
||||
$updateCount++;
|
||||
} else {
|
||||
\app\common\model\QywxExternalContact::create($data);
|
||||
$newCount++;
|
||||
}
|
||||
|
||||
$syncCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// 达到限制数量,停止同步
|
||||
if ($syncCount >= $limit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 保存本次同步时间(使用缓存存储)
|
||||
Cache::set($lastSyncCacheKey, $currentTime, 86400 * 30); // 缓存30天
|
||||
|
||||
// 更新任务状态
|
||||
Cache::set($cacheKey, [
|
||||
'status' => 'completed',
|
||||
'progress' => 100,
|
||||
'start_time' => $currentTime,
|
||||
'end_time' => time(),
|
||||
'sync_count' => $syncCount,
|
||||
'new_count' => $newCount,
|
||||
'update_count' => $updateCount,
|
||||
'params' => $params
|
||||
], 86400);
|
||||
|
||||
echo "Sync completed: {$syncCount} records processed\n";
|
||||
exit(0);
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
// 更新任务状态为失败
|
||||
Cache::set($cacheKey, [
|
||||
'status' => 'failed',
|
||||
'progress' => 0,
|
||||
'error' => $e->getMessage(),
|
||||
'params' => $params
|
||||
], 86400);
|
||||
|
||||
echo "Sync failed: {$e->getMessage()}\n";
|
||||
exit(1);
|
||||
}
|
||||
Reference in New Issue
Block a user