123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672 |
- <?php
- namespace App\Service;
- use App\Log;
- use App\Models\AndroidBindCorp;
- use App\Models\AndroidToolRequestLog;
- use App\Models\AuthorizeCorp;
- use App\Models\CustomerDetails;
- use App\Models\DjUser;
- use App\Models\MomentRecord;
- use App\Models\MomentTask;
- use App\Models\MomentFansInteract;
- use App\Models\Customer;
- use App\Models\System\AdminManageCorp;
- use App\Models\System\Users;
- use App\RedisModel;
- use App\Support\EmailQueue;
- class MomentService
- {
- /**
- * 设置朋友圈消息规则
- * */
- public static function setRule($ruleId, $params)
- {
- try {
- if(2 == $params['operate_type']){
- if(1 == $params['is_operation']) {
- $senders = MassMsgRuleService::getSenderListByOperatorGroupId($params['operator_group_id']);
- $params['sender_list'] = '';
- } else {
- $senders = json_decode($params['multiple_senders'], 1);
- $params['sender_list'] = $params['multiple_senders'];
- }
- $corpIdList = MassMsgRuleService::getCorpIdListBySenders($senders);
- $params['corpid'] = implode(',', $corpIdList);
- } else {
- # 校验附件信息合法性
- $attachmentsVerifyCode = MassMsgRuleService::attachmentsVerify($params['attachments'], $params['corpid']);
- if($attachmentsVerifyCode) return $attachmentsVerifyCode;
- }
- if($ruleId){ // 编辑朋友圈规则
- $ruleInfo = MomentTask::where('id', $ruleId)->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;
- }
- }
|