first(); if(!isset($ruleInfo->status) || !in_array($ruleInfo->status, [-2, -1, 1])) { // 判断是否为可编辑的状态 return 2502; } unset($params['multiple_senders']); $result = MomentTask::where('id', $ruleId)->update($params); } else { # 设置新群发规则 $momentMsgModel = new MomentTask(); $momentMsgModel->admin_id = $params['admin_id']; $momentMsgModel->corpid = $params['corpid']; $momentMsgModel->name = $params['name']; $momentMsgModel->filter_type = $params['filter_type']; $momentMsgModel->send_type = $params['send_type']; $momentMsgModel->send_time = $params['send_time']; $momentMsgModel->sender_list = $params['sender_list']; $momentMsgModel->department_list = $params['department_list']; $momentMsgModel->customer_filter = $params['customer_filter']; $momentMsgModel->customer_tag_list = $params['customer_tag_list']; $momentMsgModel->content = $params['content']; $momentMsgModel->attachments = html_entity_decode($params['attachments']); $momentMsgModel->operate_type = $params['operate_type']; $momentMsgModel->operator_group_id = $params['operator_group_id']; $momentMsgModel->is_operation = $params['is_operation']; $result = $momentMsgModel->save(); $ruleId = isset($momentMsgModel->id) ? $momentMsgModel->id : ''; } if(!$result) return 2503; # 置入队列获取预估可见客户数 if(2 == $params['operate_type']){ RedisModel::lPush(MomentTask::MOMENT_MSG_ESTIMATED_MULTIPLE_CORP_USER_COUNT_RDS, $ruleId); } else { RedisModel::lPush(MomentTask::MOMENT_MSG_ESTIMATED_USER_COUNT_RDS, $ruleId); } } catch (\Exception $e) { Log::logError('朋友圈消息设置发生异常', [ 'line' => $e->getLine(), 'msg' => $e->getMessage(), 'params' => $params ], 'SetMomentMsgRule'); return 2501; } return 0; } /** * 朋友圈任务列表 * */ public static function taskList($corpid, $creatorId, $filterType, $sendTimeStart, $sendTimeEnd,$createTimeStart,$createTimeEnd,$sortColumn,$sortMethod, $page, $pageSize, &$errno) { try { list($list, $count) = MomentTask::getTaskLists($corpid, $creatorId, $filterType, $sendTimeStart, $sendTimeEnd,$createTimeStart,$createTimeEnd,$sortColumn,$sortMethod, $page, $pageSize); # 获取创建人信息 $adminIds = $list->pluck('admin_id'); $adminData = Users::select(['id','name'])->whereIn('id', $adminIds)->get(); # 统计发送信息 $ruleIds = $list->pluck('rule_id'); $publishedStatData = MomentRecord::selectRaw("sum(case when publish_status=1 then 1 else 0 end) as published_count, sum(case when publish_status=0 then 1 else 0 end) as unpublished_count, count(1) as published_total, rule_id") ->whereIn('rule_id', $ruleIds)->groupBy(['rule_id'])->get(); $errcodeConf = config('qyWechat.errcode'); # 处理数据 foreach($list as $datum) { # 创建人信息 $adminInfo = $adminData->where('id', $datum->admin_id)->first(); $datum->creator = isset($adminInfo->name) ? $adminInfo->name : ''; # 统计发送情况 $sendStatInfo = $publishedStatData->where('rule_id', $datum->rule_id)->first(); $datum->published_count = isset($sendStatInfo->published_count) ? $sendStatInfo->published_count : 0; $datum->unpublished_count = isset($sendStatInfo->unpublished_count) ? $sendStatInfo->unpublished_count : 0; $datum->published_total = isset($sendStatInfo->published_total) ? $sendStatInfo->published_total : 0; # 附件信息处理 $attachments = json_decode($datum->attachments, true); if(!empty($attachments)) { foreach ($attachments as $key=>&$attachment) { if(isset($attachment['msgtype']) && $attachment['msgtype'] == 'radar') { // 雷达附件信息回显 $radarId = $attachment['radar']['radar_id'] ?? 0; $radarInfo = RadarService::getRadarContent($corpid, $radarId); if(empty($radarInfo)) { unset($attachment[$key]); continue; } $attachment['radar'] = $radarInfo; } } } $datum->err_msg = $errcodeConf[$datum->err_code] ?? null; $datum->attachments = json_encode($attachments, 256); unset($datum->admin_id); } } catch(\Exception $e) { Log::logError('获取朋友圈任务列表发生异常', [ 'line' => $e->getLine(), 'msg' => $e->getMessage(), ], 'MomentTaskList'); $errno = 2505; return [[], 0]; } return [$list, $count]; } /** * 朋友圈消息规则详情 * @param $corpid string 企业ID * @param $ruleId integer 朋友圈消息规则ID * */ public static function ruleDetail($corpid, $ruleId, &$errno) { try{ $detail = MomentTask::selectRaw('id as rule_id, admin_id, corpid, name, filter_type, send_type, send_time, sender_list, department_list, customer_filter, content, customer_tag_list, estimated_user, invalid_sender_list, invalid_department_list, invalid_customer_tag_list, err_msg, attachments, status, enable, operate_type, operator_group_id, is_operation') ->whereRaw("FIND_IN_SET('".$corpid."', `corpid`)")->where('id', $ruleId) ->first(); if(empty($detail)) return []; # 获取创建人信息 $detail->creator = Users::where('id', $detail->admin_id)->value('name'); # 附件信息处理 $attachments = json_decode($detail->attachments, true); if(!empty($attachments)) { foreach ($attachments as $key=>&$attachment) { if(isset($attachment['msgtype']) && $attachment['msgtype'] == 'radar') { // 雷达附件信息回显 $radarId = $attachment['radar']['radar_id'] ?? 0; $radarInfo = RadarService::getRadarContent($corpid, $radarId); if(empty($radarInfo)) { unset($attachment[$key]); continue; } $attachment['radar'] = $radarInfo; } } } $detail->attachments = json_encode($attachments, 256); # 获取执行朋友圈发送成员信息 $publishUserList = MomentRecord::select(['sender', 'publish_status', 'err_msg', 'err_code'])->where('rule_id', $ruleId)->get(); if($publishUserList->count()) { $userIds = $publishUserList->pluck('sender'); $userList = DjUser::select('user_id', 'name', 'avatar')->whereIn('user_id', $userIds)->groupBy(['user_id'])->get(); } foreach ($publishUserList as $publisher) { $publisherInfo = $userList->where('user_id', $publisher->sender)->first(); $publisher->sender = isset($publisherInfo->name) ? $publisherInfo->name : ''; $publisher->avatar = isset($publisherInfo->avatar) ? $publisherInfo->avatar : ''; } $detail->published_count = $publishUserList->where('publish_status', 1)->count(); $detail->unpublished_count = $publishUserList->where('publish_status', 0)->count(); $detail->published_total = $publishUserList->count(); $publisherUser = $publishUserList->where('publish_status', 1)->all(); $unpublishedUser = $publishUserList->where('publish_status', 0)->all(); $detail->publish_list = [ 'published_user' => array_values($publisherUser), 'unpublished_user' => array_values($unpublishedUser) ]; if($detail->operate_type == 2) { $detail->multiple_senders = $detail->sender_list; } } catch (\Exception $e) { Log::logError('群发详情获取过程发生异常', [ 'line' => $e->getLine(), 'msg' => $e->getMessage(), 'rule_id' => $ruleId ], 'MomentRuleDetail'); $errno = 2504; return []; } return $detail; } /** * 更新朋友圈消息状态 * */ public static function updateRuleStatus($corpid, $ruleId, $status) { # 验证规则是否存在 $isExist = MomentTask::whereRaw('FIND_IN_SET("'.$corpid.'", `corpid`)')->where('id', $ruleId)->exists(); if(!$isExist) return 2506; # 变更规则状态 $result = MomentTask::where('id', $ruleId)->update(['enable' => $status]); if(!$result) return 2507; return 0; } /** * 给朋友圈消息未发送成员发送消息提醒 * */ public static function noticeUser($corpid, $ruleId) { try { # 查询未发送消息的成员user_id $unpublishedUserList = MomentRecord::select(['sender', 'publish_status', 'err_msg', 'err_code'])->where('rule_id', $ruleId)->whereRaw('FIND_IN_SET("'.$corpid.'", `corpid`)') ->where('rule_id', $ruleId)->where('publish_status', 0)->pluck('sender')->toArray(); if(empty($unpublishedUserList)) return 2511; # 发送消息提醒 $responseData = ApplicationMsgService::sendTextMsg($corpid, '请及时确认发送朋友圈消息。', $unpublishedUserList); if(isset($responseData['errcode']) && $responseData['errcode'] != 0) { $logData = [ 'corpid' => $corpid, 'rule_id' => $ruleId, 'responseData' => $responseData ]; EmailQueue::rPush('发送朋友圈消息提醒失败', json_encode($logData, JSON_UNESCAPED_UNICODE), ['xiaohua.hou@kuxuan-inc.com'], '发送朋友圈消息提醒失败'); Log::logError('发送朋友圈消息提醒失败', $logData, 'noticeUserFailed'); return 2512; } # 记录发送日志 Log::logInfo('发送朋友圈消息提醒日志', [ 'corpid' => $corpid, 'rule_id' => $ruleId, 'responseData' => $responseData ], 'noticeUserLog'); } catch (\Exception $e) { EmailQueue::rPush('发送朋友圈消息提醒流程发生异常', $e->getTraceAsString(), ['xiaohua.hou@kuxuan-inc.com'], '发送朋友圈消息提醒流程发生异常'); Log::logInfo('发送朋友圈消息提醒流程发生异常', [ 'corpid' => $corpid, 'rule_id' => $ruleId, 'line' => $e->getLine(), 'msg' => $e->getMessage() ], 'noticeUserLog-Exception'); return 2514; } return 0; } /** * 校验朋友圈消息的附件信息合法性 * */ public static function attachmentsVerify($attachments) { if(!is_array($attachments)) $attachments = json_decode($attachments, true); # 校验是否只有一种附件类型 $msgType = array_unique(array_column($attachments, 'msgtype')); $msgTypeCount = count($msgType); if($msgTypeCount > 1) return 2509; if($msgType == 'image') { $imgCount = count($attachments); if($imgCount > 9) return 2510; } elseif (in_array($msgType, ['link', 'video'])) { $imgCount = count($attachments); if($imgCount > 1) return 2513; } return 0; } /** * 获取朋友圈消息预计展示的客户数 * */ public static function getCustomerMatchCount($params, &$total) { try { $corpid = $params['corpid']; # 发送朋友圈成员userid处理 if(!is_array($params['sender_list'])) { $senders = !empty($params['sender_list']) ? explode(',', $params['sender_list']) : []; } else { $senders = $params['sender_list']; } # 发送朋友圈部门id换取user_id $userList = array(); if(!empty($params['department_list'])) { $departmentList = explode(',', $params['sender_list']); foreach($departmentList as $dpId) { $sendersByDepartment = DjUser::whereRaw('find_in_set("' . $dpId . '", `department`)')->where('corpid', $corpid)->pluck('user_id')->toArray(); $userList = array_merge($userList, $sendersByDepartment); } } $senders = array_unique(array_merge($userList, $senders)); $search = array(); $customerFilter = $params['customer_filter']; if($customerFilter){ $tagList = $params['customer_tag_list']; // 0全部客户 1筛选客户 if(!empty($tagList)) { $search['tag_screen_type'] = 1; $search['tag_list'] = explode(',', $tagList); } } if(!empty($senders)) { $search['user_ids'] = $senders; } $total = CustomerDetails::getCustomerMatchCount($corpid, $search); } catch (\Exception $e) { Log::logError('获取朋友圈展示预估展示人数过程发生异常', [ 'line' => $e->getLine(), 'msg' => $e->getMessage() ], 'MomentGetCustomerTotal-Exception'); $total = 0; } return 0; } public static function getMultipleCorpCustomerMatchCount($params, &$total) { try { $data = $params; if(1 == $params['is_operation']) { $senders = MassMsgRuleService::getSenderListByOperatorGroupId($params['operator_group_id']);//从运营组中查询客服以及企微信息 } else { $senders = json_decode($params['multiple_senders'], 1); } foreach ($senders as $item) { $singleTotal = 0; $data['corpid'] = $item['corpid']; $data['sender_list'] = implode(',', $item['user_list']); self::getCustomerMatchCount($data, $singleTotal); $total += $singleTotal; } } catch (\Exception $e) { Log::logError('多企微获取群发条件匹配的外部联系人数过程发生异常', [ 'params' => $params, 'line' => $e->getLine(), 'msg' => $e->getMessage() ], 'GetMultipleCorpCustomer-Exception'); EmailQueue::rPush('多企微获取朋友圈匹配的外部联系人数过程发生异常', $e->getTraceAsString(), ['xiaohua.hou@kuxuan-inc.com'], '猎羽'); } return 0; } /** * 创建朋友圈任务 * @param string $corpid 企业id * @param string $content 文本内容 * @param array $attachments 附件内容 * @param array $visibleRange 指定的发表范围 * */ public static function momentMsgTaskCreate($corpid, $content, $attachments, $visibleRange=null) { # 获取AccessToken $accessToken = AuthorizeCorp::getAccessToken($corpid); if(empty($accessToken)) { return false; } $postData = [ 'text' => [ 'content' => $content ], 'attachments' => $attachments ]; if(!empty($visibleRange)) { // 指定了发表范围 $postData['visible_range'] = $visibleRange; } $requestUri = config('qyWechat.add_moment_task'); $requestUri .= $accessToken; $response = HttpService::httpPost($requestUri, json_encode($postData)); $responseData = json_decode($response, true); Log::logInfo('【'.$corpid.'】朋友圈创建响应日志:', [ 'corpid' => $corpid, 'postData' => $postData, 'responseData' => $responseData ], 'MomentMsgTaskCreateLog'); return $responseData; } /** * 朋友圈点赞评论数据统计 */ public static function momentInteract($corpid, $moment_id, $userid) { $res = [ 'like_total' => 0, 'comment_total' => 0, 'like_users' => null, 'comment_users' => null ]; $list = MomentFansInteract::select('external_userid', 'create_time', 'interact_type') ->where('corpid', $corpid) ->where('moment_id', $moment_id) ->where('sender', $userid) ->orderBy('create_time', 'desc') ->get(); if($list->isEmpty()){ return $res; } //获取客户头像信息 $external_userids = $list->pluck('external_userid')->all(); $cust_info = Customer::suffix($corpid)->select('external_userid', 'name', 'avatar') ->whereIn('external_userid', $external_userids) ->get() ->keyBy('external_userid') ->toArray(); foreach($list as $v){ if($v->interact_type == 1){ $res['like_total']++; if( isset($cust_info[$v->external_userid]) ){ $res['like_users'][] = $cust_info[$v->external_userid]; } } else { $res['comment_total']++; if( isset($cust_info[$v->external_userid]) ){ $res['comment_users'][$v->external_userid] = $cust_info[$v->external_userid]; } } } $res['comment_users'] = !empty($res['comment_users']) ? array_values($res['comment_users']) : null; return $res; } /** * 朋友圈发送记录列表 * @param $corpid string 企微id * @param $userIdList array 员工id数组 * @param $sendTimeStart string 起始发布时间 * @param $sendTimeEnd string 截止发布时间 * @param $page int 页码 * @param $pageSize int 每页数据 * @param $errno int * @return mixed */ public static function momentRecordList( $corpid, $userIdList, $sendTimeStart, $sendTimeEnd, $page, $pageSize, &$errno ) { $requestData = [ 'corpid' => $corpid, 'user_id_list' => $userIdList, 'send_time_start' => $sendTimeStart, 'send_time_end' => $sendTimeEnd, 'page' => $page, 'page_size' => $pageSize ]; try { list($list, $count) = MomentRecord::recordLists($corpid, $userIdList, $sendTimeStart, $sendTimeEnd, $page, $pageSize); $listArr = $list->toArray(); // 提取朋友圈规则id列表 $ruleIdList = array_unique(array_column($listArr, 'rule_id')); // 提取发布成员列表 $senderList = array_unique(array_column($listArr, 'sender')); // 获取朋友圈规则信息 $momentTaskList = MomentTask::query() ->whereIn('id', $ruleIdList) ->get(); // 获取发布成员信息 $senderDataList = DjUser::query() ->where('corpid', $corpid) ->whereIn('user_id', $senderList) ->get(); # 处理数据 foreach($list as $datum) { $momentTask = $momentTaskList->where('id', $datum->rule_id)->first(); if(empty($momentTask)) { $datum->filter_type = null; $datum->content = null; $datum->attachments = null; } else { $datum->filter_type = $momentTask->filter_type; $datum->content = $momentTask->content; # 附件信息处理 $attachments = json_decode($momentTask->attachments, true); if(!empty($attachments)) { foreach ($attachments as $key=>&$attachment) { if(isset($attachment['msgtype']) && $attachment['msgtype'] == 'radar') { // 雷达附件信息回显 $radarId = $attachment['radar']['radar_id'] ?? 0; $radarInfo = RadarService::getRadarContent($corpid, $radarId); if(empty($radarInfo)) { unset($attachment[$key]); continue; } $attachment['radar'] = $radarInfo; } } } $datum->attachments = json_encode($attachments, 256); } $sender = $senderDataList->where('user_id', $datum->sender)->first(); if(empty($sender)) { $datum->sender_avatar = null; $datum->sender_name = null; } else { $datum->sender_avatar = $sender->avatar; $datum->sender_name = $sender->name; } } } catch(\Exception $e) { Log::logError('获取朋友圈发布记录列表发生异常 请求参数:'.json_encode($requestData, 256), [ 'line' => $e->getLine(), 'msg' => $e->getMessage(), ], 'momentRecordList'); $errno = 2508; return [[], 0]; } return [$list, $count]; } /** * 判断是否为雷达朋友圈 * @param array $attachments 朋友圈附件 * */ public static function isRadarMoment($attachments) { Log::logInfo('检验朋友圈消息是否为雷达类', [ 'attachments' => $attachments ], 'IsRadarMoment'); $isRadar = false; foreach ($attachments as $attachment) { if(isset($attachment['msgtype']) && $attachment['msgtype'] == 'radar') { Log::logInfo('此朋友圈消息为雷达类', [ 'attachments' => $attachments ], 'IsRadarMoment'); $isRadar = true; } } return $isRadar; } /** * 获取待确认发送的消息列表 * */ public static function senderConfirmList($deviceId) { # 查询支持无障碍模式的企微列表 $corpidList = AndroidBindCorp::getcorpList($deviceId); $corpidList = json_decode(json_encode($corpidList), 1); # 查询待发送群发消息记录 $msgList = MomentRecord::select('corpid')->where('show_total', 0) ->whereIn('corpid', $corpidList) ->where('created_at', '>=', date('Y-m-d H:i:s', strtotime('-60 minutes'))) ->groupBy(['corpid']) ->get(); $corpList = AuthorizeCorp::select('corpid', 'corp_name')->where('enable', 1)->get(); // $userIdList = $msgList->pluck('sender'); // $userList = DjUser::select('corpid', 'user_id', 'name')->whereIn('user_id', $userIdList)->get(); foreach ($msgList as $item) { # 获取企微名称 $corpInfo = $corpList->where('corpid', $item->corpid)->first(); $item->companyName = $corpInfo->corp_name; # 获取客服名 // $userInfo = $userList->where('user_id', $item->sender)->where('corpid', $item->corpid)->first(); // $item->userName = $userInfo->name; } Log::logInfo('设备请求朋友圈日志', [ 'type' => 3, 'device_id' => $deviceId, 'msg_list' => $msgList->toArray(), ], 'SenderConfirmList'); return $msgList; } }