ChangeType); $corpid = trim($msgObj->AuthCorpId); switch($changeType) { case 'add_external_contact': // 添加企业客户事件 case 'edit_external_contact': // 编辑客户事件 case 'add_half_external_contact': // 外部联系人免验证添加成员事件 $data['corpid'] = $corpid; $data['user_id'] = trim($msgObj->UserID); $data['external_userid'] = trim($msgObj->ExternalUserID); $data['state'] = trim($msgObj->State); $welcomeCode = trim($msgObj->WelcomeCode); # 新添加客户入队列发送欢迎语 if(!empty($welcomeCode)) { $newUserInfo = array( 'corpid' => $corpid, 'user_id' => $data['user_id'], 'welcome_code' => $welcomeCode ); RedisModel::lPush(WelcomeMsg::WELCOME_USER_RDS, json_encode($newUserInfo)); } if($isTemplate) { $rdsKey = Customer::CUSTOMER_UPDATE_WAITING_TEMPLATE_RDS; } else { $rdsKey = Customer::CUSTOMER_UPDATE_WAITING_RDS; } // Log::loginfo('客户信息',[ // 'welcomeCode' => $welcomeCode, // 'user_id' => $data['user_id'], // 'is_template' => $isTemplate, // 'rds_key' => $rdsKey // ], 'TemplateWelcomeMsg'); $result = RedisModel::lPush($rdsKey, json_encode($data)); if(!$result) { // Todo::增加报警 Log::logError('新添加客户信息入队列失败', $data, 'UpdateExternalContact'); return false; } if($changeType != 'edit_external_contact') { # 添加成员动态信息 $result = CustomerDynamic::customerDynamicSave($corpid, $data['external_userid'], $data['user_id'], 1); if(!$result) { Log::logError('(添加客户)客户动态信息存储失败', $data, 'CustomerDynamicSave'); } } break; case 'del_external_contact': // 删除企业客户事件 $data['corpid'] = $corpid; $data['user_id'] = trim($msgObj->UserID); $data['external_userid'] = trim($msgObj->ExternalUserID); $data['source'] = trim($msgObj->Source); $result = RedisModel::lPush(Customer::DEL_CUSTOMER_RDS, json_encode($data)); if(!$result) { // Todo::增加报警 Log::logError('新添加客户信息入队列失败', $data, 'DeleteExternalContact'); return false; } # 添加成员动态信息 $result = CustomerDynamic::customerDynamicSave($corpid, $data['external_userid'], $data['user_id'], 2); if(!$result) { Log::logError('(删除企业客户)客户动态信息存储失败', $data, 'CustomerDynamicSave'); } break; case 'del_follow_user': // 删除跟进成员事件 $data['corpid'] = $corpid; $data['user_id'] = trim($msgObj->UserID); $data['external_userid'] = trim($msgObj->ExternalUserID); $result = RedisModel::lPush(Customer::DEL_FOLLOW_USER_RDS, json_encode($data)); if(!$result) { // Todo::增加报警 Log::logError('新添加客户信息入队列失败', $data, 'DeleteFollowUser'); return false; } # 添加成员动态信息 $result = CustomerDynamic::customerDynamicSave($corpid, $data['external_userid'], $data['user_id'], 3); if(!$result) { Log::logError('(删除跟进成员)客户动态信息存储失败', $data, 'CustomerDynamicSave'); } break; case 'customer_refused': // 客户接替失败事件 $data['corpid'] = $corpid; $data['user_id'] = trim($msgObj->UserID); $data['external_userid'] = trim($msgObj->ExternalUserID); $data['fail_reason'] = trim($msgObj->FailReason); $result = RedisModel::lPush(Customer::CUSTOMER_REFUSED_RDS, json_encode($data)); if(!$result) { // Todo::增加报警 Log::logError('新添加客户信息入队列失败', $data, 'CustomerRefused'); return false; } break; } } catch (\Exception $e) { Log::logError('外部联系人变更事件回调处理发生异常', [ 'line' => $e->getLine(), 'msg' => $e->getMessage(), 'data' => $msgObj ], 'ChangeExternalContactEvent-Exception'); return false; } return true; } /** * 获取外部联系人信息详情 * @param $corpid string 授权方企业微信id * @param $externalUserid string 外部联系人的userid * @param $cursor string 上次请求返回的next_cursor,用于分页请求(见官方文档) * @param $retry integer 重试次数,默认为0 * */ public static function getExternalContactDetail($corpid, $externalUserid, $cursor=null, $retry=0) { # 获取SuiteAccessToken $accessToken = AuthorizeCorp::getAccessToken($corpid, '获取外部联系人信息详情'); if(empty($accessToken)) { // 令牌获取失败,发送报警 Log::logError('【获取外部联系人信息详情】令牌获取失败', [ 'corpid' => $corpid, 'externalUserId' => $externalUserid, 'cursor' => $cursor, 'retry' => $retry, 'access_token' => $accessToken ], 'GetExternalContactDetail'); return false; } # 获取外部联系人详情信息API $getExternalContactUri = config('qyWechat.external_contact_detail'); $getExternalContactUri .= $accessToken . '&external_userid=' . $externalUserid; if($cursor) { $getExternalContactUri .= '&cursor=' . $cursor; } $response = HttpService::httpGet($getExternalContactUri); $responseData = json_decode($response, true); if(isset($responseData['errcode']) && $responseData['errcode']) { if($retry <=5 && $responseData['errcode'] == -1) { $retry++; return ExternalContactService::getExternalContactDetail($corpid, $externalUserid, $cursor, $retry); } if($responseData['errcode'] == '84061') { # 获取客户在系统中已有的客户关系 $userIdList = CustomerDetails::suffix($corpid)->where('corpid', $corpid)->where('loss_status', 1) ->where('external_userid', $externalUserid)->pluck('user_id'); if(!empty($userIdList)) { foreach ($userIdList as $userId) { RedisModel::lPush(CustomerDetails::CUSTOMER_LOSS_INFO_RDS, json_encode([ 'corpid' => $corpid, 'user_id' => $userId, 'external_userid' => $externalUserid, ])); } } else { Log::logError('外部联系人详情信息获取异常,提示无好友关系,且系统未查到对应用户数据', [ 'response' => $responseData, 'corpid' => $corpid, 'externalUserId' => $externalUserid, 'cursor' => $cursor ], 'GetExternalContactDetail'); } } else { if($responseData['errcode'] != '701008') { Log::logError('外部联系人详情信息获取失败', [ 'response' => $responseData, 'corpid' => $corpid, 'externalUserId' => $externalUserid, 'cursor' => $cursor ], 'GetExternalContactDetail'); } } return []; } return $responseData; } /** * 内部员工删除企业客户 * */ public static function deleteExternalContact($corpid, $userId, $externalUserid, $source) { try { // 开启事务 DB::beginTransaction(); # 判断该企业主体是否有其它员工负责该客户 $followedCount = CustomerDetails::followUsersCount($corpid, $externalUserid); if($followedCount == 1) { # 更新客户状态为被内部员工删除 $result = Customer::changeCustomerStatus($corpid, $externalUserid, 0); if(!$result) { DB::rollBack(); return false; } } # 员工客户关系表对应状态更新 $result = CustomerDetails::changeRelationStatus($corpid, $userId, $externalUserid, 1, $source, false, date("Y-m-d H:i:s")); if(!$result) { DB::rollBack(); return false; } # 删除客户数据缓存 RedisModel::sAdd('Playlet::deleteFollowUser##'.$corpid.'##'.$userId, $externalUserid); DB::commit(); } catch (\Exception $e) { DB::rollBack(); Log::logError('内部员工删除企业客户处理逻辑发生异常', [ 'line' => $e->getLine(), 'msg' => $e->getMessage() ], 'DeleteExternalContact'); return false; } return true; } /** * 客户删除跟进成员事件 * */ public static function deleteFollowUser($corpid, $userId, $externalUserid) { try { DB::beginTransaction(); # 判断该企业主体是否有其它员工负责该客户 $followedCount = CustomerDetails::followUsersCount($corpid, $externalUserid); if($followedCount == 1) { # 更新客户状态为客户删除跟进成员 $result = Customer::changeCustomerStatus($corpid, $externalUserid, 0); if(!$result) { DB::rollBack(); return false; } } # 员工客户关系表对应状态更新 $result = CustomerDetails::changeRelationStatus($corpid, $userId, $externalUserid, 2, '', false, date("Y-m-d H:i:s")); if(!$result) { DB::rollBack(); return false; } # 更新客户首次关注时间 $customerInfo = Customer::suffix($corpid) ->select('name', 'avatar') ->where('corpid', $corpid)->where('external_userid', $externalUserid) ->first(); $createtime = CustomerDetails::suffix($corpid)->where('corpid', $corpid)->where('user_id', $userId)->where('external_userid', $externalUserid)->value('createtime'); Log::logInfo('更新用户留存信息中最早关注时间日志', [ 'user' => $customerInfo->toArray(), 'createtime' => $createtime, 'corpid' => $corpid, 'user_id' => $userId, 'external_userid' => $externalUserid ], 'UpdateCustomerFirstAddTime'); CustomerService::updateCustomerFirstAddTime($customerInfo->name, $customerInfo->avatar, $createtime); # 删除客户数据缓存 RedisModel::sAdd('Playlet::deleteFollowUser##'.$corpid.'##'.$userId, $externalUserid); DB::commit(); } catch (\Exception $e) { DB::rollBack(); Log::logError('客户删除跟进成员处理逻辑发生异常', [ 'line' => $e->getLine(), 'msg' => $e->getMessage() ], 'DeleteFollowUser'); } return true; } /** * 更新外部联系人信息至数据库 * */ public static function updateExternalContacts($externalUserData, $corpid, $userId, $state, $changeType, &$customerId) { try{ # 客户基本信息 $externalContact = $externalUserData['external_contact']; # 客户跟进信息 $followData = $externalUserData['follow_user']; DB::beginTransaction(); # 更新客户信息到Customer表 $customerId = Customer::externalContactDataSave($corpid, $externalContact); if(!$customerId) { // 更新客户信息失败,事务回滚 Log::logError('更新客户信息失败', [ 'corpid' => $corpid, 'user_id' => $userId, 'state' => $state, 'externalUserData' => $externalUserData ], 'UpdateExternalContact'); DB::rollBack(); return false; } # 更新客户关系到CustomerDetails表 foreach ($followData as $followInfo) { if($followInfo['userid'] != $userId) { continue; } # 处理标签信息 $tagList = ''; if(isset($followInfo['tags'])) { foreach ($followInfo['tags'] as $tagInfo) { $tagId = isset($tagInfo['tag_id']) ? $tagInfo['tag_id'] : ''; if(!$tagId) { Log::logError('标签信息异常', $tagInfo, 'ExternalContactUpService'); continue; } $type = isset($tagInfo['type']) ? $tagInfo['type'] : 1; $groupName = isset($tagInfo['group_name']) ? $tagInfo['group_name'] : ''; $tagName = isset($tagInfo['tag_name']) ? $tagInfo['tag_name'] : ''; # 判断tag_id是否存在于tag表中 $tagMd5 = Tag::where('corpid', $corpid)->where('tag_id', $tagId)->value('tag_md5'); if(empty($tagMd5)) { // 标签数据不存在 $tagMd5 = md5($tagId); $tagInsertData = [ 'corpid' => $corpid, 'tag_id' => $tagId, 'tag_name' => $tagName, 'tag_md5' => $tagMd5 ]; $result = Tag::updateOrCreate(['corpid' => $corpid, 'tag_id' => $tagId], $tagInsertData); if(!$result) { Log::logError('标签信息插入到标签表失败', $tagInsertData, 'TagInfoInsert'); DB::rollBack(); return false; } } # 构造tagList $tagList .= $tagMd5 . ','; } } # 更新客户关系到CustomerDetails表 $tagList = trim($tagList, ','); $followInfo['tag_list'] = $tagList; $followInfoId = CustomerDetails::followInfoDataSaveV2($corpid, $followInfo, $customerId, $externalContact); if(!$followInfoId) { Log::logError('客户关系表中更新数据失败', $followInfo, 'ExternalContactUpService'); DB::rollBack(); return false; } // 预警检测 if ($followInfo['userid'] == $userId) { WarnRecordLog::warnRecordIntoQueue($changeType, $corpid, $followInfo, $externalContact); } // 批量加好友 BatchAddCustomerService::addTagForCustomer($changeType, $corpid, $followInfo, $externalContact); } DB::commit(); } catch (\Exception $e) { EmailQueue::rPush('更新外部联系人信息至数据库过程发生异常', $e->getTraceAsString(), ['xiaohua.hou@kuxuan-inc.com'], '更新外部联系人信息至数据库过程发生异常'); Log::logError('更新外部联系人信息至数据库过程发生异常', [ 'line' => $e->getLine(), 'msg' => $e->getMessage(), 'data' => $externalUserData, 'corpid' => $corpid, 'state' => $state ], 'ExternalContactUpService'); DB::rollBack(); return false; } return true; } // /** // * 更新外部联系人信息至数据库 // * */ // public static function updateExternalContact($externalUserData, $corpid, $userId, $state, &$customerId) // { // try{ // # 客户基本信息 // $externalContact = $externalUserData['external_contact']; // # 客户跟进信息 // $followData = $externalUserData['follow_user']; // // DB::beginTransaction(); // # 更新客户信息到Customer表 // $customerId = Customer::externalContactDataSave($corpid, $externalContact); // // if(!$customerId) { // 更新客户信息失败,事务回滚 // Log::logError('更新客户信息失败', [ // 'corpid' => $corpid, // 'user_id' => $userId, // 'state' => $state, // 'externalUserData' => $externalUserData // ], 'UpdateExternalContact'); // DB::rollBack(); // return false; // } // // # 更新客户关系到CustomerDetails表 // foreach ($followData as $followInfo) { // $followInfoId = CustomerRelation::followInfoDataSave($corpid, $followInfo, $customerId, $externalContact['external_userid']); // // if(!$followInfoId) { // Log::logError('客户关系表中更新数据失败', $followInfo, 'ExternalContactUpService'); // continue; // } // // if(isset($followInfo['tags'])) { // foreach ($followInfo['tags'] as $tagInfo) { // $tagId = isset($tagInfo['tag_id']) ? $tagInfo['tag_id'] : ''; // if(!$tagId) { // Log::logError('标签信息异常', $tagInfo, 'ExternalContactUpService'); // continue; // } // $type = isset($tagInfo['type']) ? $tagInfo['type'] : 1; // $groupName = isset($tagInfo['group_name']) ? $tagInfo['group_name'] : ''; // $tagName = isset($tagInfo['tag_name']) ? $tagInfo['tag_name'] : ''; // $result = CustomerTag::suffix($corpid)->updateOrCreate([ // 'corpid' => $corpid, // 'user_id' => $followInfo['userid'], // 'customer_id' => $customerId, // 'tag_id' => $tagId, // ], [ // 'external_userid' => $externalContact['external_userid'], // 'group_name' => $groupName, // 'tag_name' => $tagName, // 'type' => $type // ]); // // if(!$result) { // Log::logError('标签信息异常', $tagInfo, 'ExternalContactUpService'); // } // } // } // } // // DB::commit(); // } catch (\Exception $e) { // Log::logError('更新外部联系人信息至数据库过程发生异常', [ // 'line' => $e->getLine(), // 'msg' => $e->getMessage(), // 'data' => $externalUserData, // 'corpid' => $corpid, // 'state' => $state // ], 'ExternalContactUpService'); // // return false; // } // // return true; // } }