$v > 0
));
if (empty($userIds)) {
throw new BusinessException('SALES_USER_IDS 业务员列表不能为空,请先在命令中配置.');
}
// 取出“待分配”的询盘(你可以根据自己系统调整条件)
// 当前策略:status = 0 且 recipient = 0 的视为未分配
$inquiries = Db::table('inquiry_log')
->where('enter_user_id', 186)
->where('channel', 10)
->where('status', 0)
->where('recipient', 0)
->where('id', '>', 34426)
->orderBy('id')
->limit(static::BATCH_LIMIT)
->get();
if ($inquiries->isEmpty()) {
$output->writeln('没有需要分配的询盘(status=0 且 recipient=0)');
return self::SUCCESS;
}
$now = time();
$count = 0;
foreach ($inquiries as $row) {
$inquiryId = (int)$row->id;
sleep(1);
// 轮询取出一个业务员 ID
$recipientUserId = $this->nextRecipientId($userIds, static::ROUND_ROBIN_GROUP_KEY);
// 对每一条记录单独事务,避免单条异常拖垮全部
Db::transaction(function () use ($inquiryId, $recipientUserId, $now, $output, &$count) {
// 1)更新 inquiry_log
$affected = Db::table('inquiry_log')
->where('id', $inquiryId)
->update([
'recipient' => $recipientUserId,
'status' => 2,
'r_time' => $now,
't_time' => $now,
'updated_at' => $now,
]);
if ($affected === 0) {
// 被其他进程抢先更新也有可能,这里只打印提示不中断整个批次
$output->writeln("询盘 {$inquiryId} 未更新(可能已被处理)");
return;
}
// 2)构造队列 payload(后续 CRM 消费时至少知道 ID)
$res = [
'id' => $inquiryId,
'recipient' => $recipientUserId,
'dispatched_at' => $now,
'source' => 'fb_leads_inquiry',
];
// 3)推送到 CRM 队列
RedisQueueRedis::send('inquiry-to-crm-new', $res);
$count++;
$output->writeln("已分配询盘 {$inquiryId} 给业务员 {$recipientUserId},并推送到队列");
});
}
$output->writeln("本次共分配成功 {$count} 条询盘");
return self::SUCCESS;
}
/**
* 轮询获取“下一位业务员 ID”
*
* @param int[] $userIds
* @param string $groupKey
* @return int
* @throws BusinessException
*/
protected function nextRecipientId(array $userIds, string $groupKey = 'default'): int
{
$userIds = array_values(array_filter(array_map('intval', $userIds), fn($v) => $v > 0));
if (empty($userIds)) {
throw new BusinessException('轮询分配失败:业务员列表为空');
}
$count = count($userIds);
$key = 'inquiry:assign:round_robin:' . $groupKey;
// Redis INCR 是原子操作,适合并发下使用
$val = Redis::incr($key); // 第一次会从 0 变成 1
// 换算为从 0 开始的下标
$index = ($val - 1) % $count;
return $userIds[$index];
}
}