123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495 |
- <?php
- namespace App\Service;
- use App\Log;
- use App\Models\AuthorizeCorp;
- use App\Models\Customer;
- use App\Models\CustomerDetails;
- use App\Models\CustomerDynamic;
- use App\Models\Tag;
- use App\Models\WarnRecordLog;
- use App\Models\WelcomeMsg;
- use App\RedisModel;
- use App\Support\EmailQueue;
- use Illuminate\Support\Facades\DB;
- class ExternalContactService
- {
- /**
- * 外部联系人变更事件回调处理
- * */
- public static function changeExternalContactEvent($msgObj, $isTemplate=0)
- {
- try {
- $changeType = trim($msgObj->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;
- // }
- }
|