bool, 'message' => string, 'toAccountId' => int|null] */ public function transferFriend($wechatFriendId, $currentAccountId, $reason = '') { try { // 获取好友信息 $friend = Db::table('s2_wechat_friend')->where('id', $wechatFriendId)->find(); if (empty($friend)) { return [ 'success' => false, 'message' => '好友不存在', 'toAccountId' => null ]; } // 获取当前账号的部门信息 $accountData = Db::table('s2_company_account')->where('id', $currentAccountId)->find(); if (empty($accountData)) { return [ 'success' => false, 'message' => '当前账号不存在', 'toAccountId' => null ]; } // 获取同部门的在线账号列表 $accountController = new AccountController(); $accountController->getlist([ 'pageIndex' => 0, 'pageSize' => 100, 'departmentId' => $accountData['departmentId'] ]); $accountIds = Db::table('s2_company_account') ->where([ 'departmentId' => $accountData['departmentId'], 'alive' => 1 ]) ->column('id'); if (empty($accountIds)) { return [ 'success' => false, 'message' => '没有可用的在线账号', 'toAccountId' => null ]; } // 如果好友当前账号不在可用账号列表中,或者需要迁移到其他账号 $needTransfer = !in_array($friend['accountId'], $accountIds); // 如果需要迁移,选择目标账号 if ($needTransfer || $currentAccountId != $friend['accountId']) { // 排除当前账号,选择其他账号 $availableAccountIds = array_filter($accountIds, function($id) use ($currentAccountId) { return $id != $currentAccountId; }); if (empty($availableAccountIds)) { return [ 'success' => false, 'message' => '没有其他可用的在线账号', 'toAccountId' => null ]; } // 随机选择一个账号 $availableAccountIds = array_values($availableAccountIds); $randomKey = array_rand($availableAccountIds, 1); $toAccountId = $availableAccountIds[$randomKey]; // 获取目标账号信息 $toAccountData = Db::table('s2_company_account')->where('id', $toAccountId)->find(); if (empty($toAccountData)) { return [ 'success' => false, 'message' => '目标账号不存在', 'toAccountId' => null ]; } // 执行迁移 $automaticAssign = new AutomaticAssign(); $result = $automaticAssign->allotWechatFriend([ 'wechatFriendId' => $wechatFriendId, 'toAccountId' => $toAccountId ], true); $resultData = json_decode($result, true); if (isset($resultData['code']) && $resultData['code'] == 200) { // 更新好友的账号信息 Db::table('s2_wechat_friend') ->where('id', $wechatFriendId) ->update([ 'accountId' => $toAccountId, 'accountUserName' => $toAccountData['userName'], 'accountRealName' => $toAccountData['realName'], 'accountNickname' => $toAccountData['nickname'], ]); $logMessage = "好友迁移成功:好友ID={$wechatFriendId},从账号{$currentAccountId}迁移到账号{$toAccountId}"; if (!empty($reason)) { $logMessage .= ",原因:{$reason}"; } Log::info($logMessage); return [ 'success' => true, 'message' => '好友迁移成功', 'toAccountId' => $toAccountId ]; } else { $errorMsg = isset($resultData['msg']) ? $resultData['msg'] : '迁移失败'; Log::error("好友迁移失败:好友ID={$wechatFriendId},错误:{$errorMsg}"); return [ 'success' => false, 'message' => $errorMsg, 'toAccountId' => null ]; } } return [ 'success' => true, 'message' => '好友已在正确的账号上,无需迁移', 'toAccountId' => $friend['accountId'] ]; } catch (\Exception $e) { Log::error("好友迁移异常:好友ID={$wechatFriendId},错误:" . $e->getMessage()); return [ 'success' => false, 'message' => '迁移异常:' . $e->getMessage(), 'toAccountId' => null ]; } } /** * 检查并迁移未读或未回复的好友 * @param int $unreadMinutes 未读分钟数,默认30分钟 * @return array ['total' => int, 'transferred' => int, 'failed' => int] */ public function checkAndTransferUnreadOrUnrepliedFriends($unreadMinutes = 30) { $total = 0; $transferred = 0; $failed = 0; try { $timeThreshold = time() - ($unreadMinutes * 60); // 查询需要迁移的好友 // 条件:最后一条消息是用户发送的消息(isSend=0),且超过指定分钟数,且客服在这之后没有回复 // 即:用户发送了消息,但客服超过30分钟没有回复,需要迁移给其他客服处理 // 使用子查询找到每个好友的最后一条消息 // SQL逻辑说明: // 1. 找到每个好友的最后一条消息(通过MAX(id)) // 2. 最后一条消息必须是用户发送的(isSend=0,即客服接收的消息) // 3. 这条消息的时间超过30分钟前(wm.wechatTime <= timeThreshold) // 4. 在这条用户消息之后,客服没有发送任何回复(NOT EXISTS isSend=1的消息) // 5. 满足以上条件的好友,说明客服超过30分钟未回复,需要迁移给其他客服 $sql = " SELECT DISTINCT wf.id as friendId, wf.accountId, wm.wechatAccountId, wm.wechatTime, wm.id as lastMessageId FROM s2_wechat_friend wf INNER JOIN ( SELECT wechatFriendId, MAX(id) as maxId FROM s2_wechat_message WHERE type = 1 GROUP BY wechatFriendId ) last_msg ON wf.id = last_msg.wechatFriendId INNER JOIN s2_wechat_message wm ON wm.id = last_msg.maxId WHERE wf.isDeleted = 0 AND wm.type = 1 AND wm.isSend = 0 -- 最后一条消息是用户发送的(客服接收的) AND wm.wechatTime <= ? -- 超过指定时间(默认30分钟) AND NOT EXISTS ( -- 检查在这条用户消息之后,是否有客服的回复 SELECT 1 FROM s2_wechat_message WHERE wechatFriendId = wf.id AND type = 1 AND isSend = 1 -- 客服发送的消息 AND wechatTime > wm.wechatTime -- 在用户消息之后 ) AND wf.accountId IS NOT NULL "; $friends = Db::query($sql, [$timeThreshold]); $total = count($friends); Log::info("开始检查未读/未回复好友,共找到 {$total} 个需要迁移的好友"); foreach ($friends as $friend) { $result = $this->transferFriend( $friend['friendId'], $friend['accountId'], "消息未读或未回复超过{$unreadMinutes}分钟" ); if ($result['success']) { $transferred++; } else { $failed++; Log::warning("好友迁移失败:好友ID={$friend['friendId']},原因:{$result['message']}"); } } Log::info("未读/未回复好友迁移完成:总计{$total},成功{$transferred},失败{$failed}"); return [ 'total' => $total, 'transferred' => $transferred, 'failed' => $failed ]; } catch (\Exception $e) { Log::error("检查未读/未回复好友异常:" . $e->getMessage()); return [ 'total' => $total, 'transferred' => $transferred, 'failed' => $failed ]; } } }