Files
zyt/sync_qywx.php
T

250 lines
8.5 KiB
PHP

<?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);
}