<?php /** * 微吼直播消息通知记录表 (防止重复推送) */ namespace Common\Service; use Common\Common\Constant; use Common\Common\Department; use Common\Model\VhallModel; use Common\Model\VhMsgLogModel; use VcySDK\Cron; use Common\Common\Msg; use VcySDK\Service; use VcySDK\Member; use Common\Common\Tag; use Common\Common\User; class VhMsgLogService extends AbstractService { public $_vh_main = null; // 构造方法 public function __construct() { $this->_d = new VhMsgLogModel(); $this->_vh_main = new VhallModel(); parent::__construct(); } /** * 获取目标范围内没有发送过消息的 uids * @param int $lmId * @param array $rangeUids 范围对象内的人员 ID * @param bool $rangeIsAll 如果范围是全公司 * @return array */ public function sendMsgRangeDiffUids($lmId, $rangeUids, $rangeIsAll = false) { // 获取历史消息推送记录 $msgLogList = []; if (!empty($lmId)) { $msgLogConds = ['vh_id' => $lmId, 'type' => VhMsgLogModel::TYPE_LIVE_PUSH]; $msgLogList = $this->_d->list_by_conds($msgLogConds); } if (!empty($msgLogList)) { // 有全公司 不用再发消息了 if (in_array(Constant::RANGE_TYPE_ALL, array_column($msgLogList, 'obj_id'))) { return []; } // 去掉已经发过的 foreach ($msgLogList as $item) { $uids = explode(',', $item['obj_id']); $rangeUids = array_diff($rangeUids, $uids); } } // 写入数据库 if (!empty($rangeUids)) { // 如果是全公司 if ($rangeIsAll) { $this->insert([ 'vh_id' => $lmId, 'obj_id' => Constant::RANGE_TYPE_ALL, 'type' => VhMsgLogModel::TYPE_LIVE_PUSH ]); } else { $insertLog = []; foreach (array_chunk($rangeUids, Constant::OBJ_ID_SINGLE_TOTAL) as $item) { $insertLog[] = [ 'vh_id' => $lmId, 'obj_id' => implode(',', $item), 'type' => VhMsgLogModel::TYPE_LIVE_PUSH ]; } $this->insert_all($insertLog); } } return $rangeUids; } /** * 创建计划任务并保存 * @param $lmId * @param $remark * @param $type * @param $time * @return bool */ public function createCron($lmId, $remark, $type, $time) { $cronSdk = new Cron(Service::instance()); // 建立 Job 发送消息 $cronResult = $cronSdk->add([ 'crRemark' => $remark, 'crType' => Cron::CR_TYPE_CALLBACK, 'crParams' => json_encode([ 'lm_id' => $lmId, 'type' => $type, ]), 'crMethod' => 'POST', // 回调地址 'crReqUrl' => oaUrl('Frontend/Callback/PushVhMsg/Index'), 'crTimes' => 1, 'crCron' => rgmdate((String)$time, 's i G j n ? Y'), 'crMonitorExecution' => $cronSdk::CR_MONITOR_EXECUTION_FALSE, 'crDescription' => '直播开始时推送消息提醒', ]); if (empty($cronResult['crId'])) { E(L('_ERR_CRON_OPTION_FAILED', ['option' => '创建'])); } // 开始前提醒 if (Constant::TYPE_LIVE_WILL_START == $type) { $data['notice_will_start_cron_id'] = $cronResult['crId']; } // 开始时提醒 if (Constant::TYPE_LIVE_START == $type) { $data['notice_notice_start_cron_id'] = $cronResult['crId']; } $this->_vh_main->update_by_conds(['vh_id' => $lmId], $data); return true; } /** * 即时消息通知方法 【发消息统一写这里,方便维护】 * @param $params -通知参数 * + uids -用户uid数组 * + memID -用户uid * + dp_ids -部门id数组 * + dpID -部门id * + tag_ids -标签id数组 * + tagID -标签id * + job_ids -岗位id数组 * + jobID -岗位id * + role_ids -角色id数组 * + roleID -角色id * + lm_id -直播ID * + name -直播标题 * + start_time -直播开始时间 * + estimated_duration -直播预计时长 * + desc -直播摘要 * @param $type -通知文案类型 * @return bool */ public function send_vh_Msg($params, $type) { // 获取应用名称 $application_name = cfg('APPLICATION_NAME'); // 过滤内容中的空格标签 $search = [" ", " "]; $replace = [" ", " "]; $content = str_replace($search, $replace, strip_tags($params['liveDesc'])); // 开始时间 $rgmDate = rgmdate($params['liveStartTime'], 'Y-m-d H:i'); // 本方法根据类型区分拼接不通的文案 switch ($type) { case self::MSG_LIVE_PUBLISH: $data = [ 'title' => '【' . cfg('APPLICATION_NAME') . '】有新的直播活动发布,快来观看吧!', 'description' => "标题:{$params['liveName']}\r\n开始时间:{$rgmDate}\r\n预计时长:{$params['liveTimeLength']}分钟\r\n主讲人:{$params['teacher_name']}\r\n直播简介:" . $this->cutstr($content, 0, 20) . "\r\n主讲人简介:{$params['teacher_desc']}", 'picUrl' => '', ]; break; case self::MSG_REMAIND_NO_JOIN_USERS: $data = [ 'title' => '【' . $application_name . '】您有一个直播未观看,快去瞧瞧吧!', 'description' => "标题:{$params['liveName']}\r\n开始时间:{$rgmDate}\r\n预计时长:{$params['liveTimeLength']}分钟\r\n主讲人:{$params['teacher_name']}\r\n直播简介:" . $this->cutstr($content, 0, 20) . "\r\n主讲人简介:{$params['teacher_desc']}", 'picUrl' => '', ]; break; case self::MSG_LIVE_WILL_START: $data = [ 'title' => '【' . $application_name . '】直播活动仅剩' . $params['notice_will_start'] . '分钟开始,快来观看吧!', 'description' => "标题:{$params['liveName']}\r\n开始时间:{$rgmDate}\r\n预计时长:{$params['liveTimeLength']}分钟\r\n主讲人:{$params['teacher_name']}\r\n直播简介:" . $this->cutstr($content, 0, 20) . "\r\n主讲人简介:{$params['teacher_desc']}", 'picUrl' => '', ]; break; case self::MSG_LIVE_START: $data = [ 'title' => '【' . $application_name . '】直播活动已经开始,快来观看吧!', 'description' => "标题:{$params['liveName']}\r\n开始时间:{$rgmDate}\r\n预计时长:{$params['liveTimeLength']}分钟\r\n主讲人:{$params['teacher_name']}\r\n直播简介:" . $this->cutstr($content, 0, 20) . "\r\n主讲人简介:{$params['teacher_desc']}", 'picUrl' => '', ]; break; case self::MSG_LECTURER_APPOINTMENT: // 直播地址 $pushUrl = (is_ssl() ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . '/admincp/#/live-pc?liveId=' . $params['id'].'&epId='.$params['epId']; // 跳转地址 (send 方法内用到) $params['jumpUrl'] = oaUrl('Frontend/Index/VhLive/guide', ['liveId' => $params['id']]); $data = [ 'title' => '【' . $application_name . '】您已被设置为直播讲师,请做好准备!', 'description' => "标题:{$params['liveName']}\r\n开始时间:{$rgmDate}\r\n直播口令:{$params['livePassword']}\r\n直播地址:" . $pushUrl, 'picUrl' => '', ]; break; default: return true; } $this->send_vh($params, $data); return true; } private function send_vh($params = [], $condition = []) { // 发送消息接收人 $msgUser = !empty($params['liveScopeUsers']) ? $params['liveScopeUsers'] : []; $toUser = isset($params['liveScopeAll']) && !empty($params['liveScopeAll']) ? '@all' : $msgUser; // 发送消息部门 $toParty = !empty($params['liveScopeDepts']) ? $params['liveScopeDepts'] : []; // 角色或者岗位发送消息 if (!empty($params['liveScopeJobs']) || !empty($params['liveScopeRoles'] || !empty($params['liveScopeTags']))) { // 获取权限下的uids $uids = $this->get_auth_uids($params); // 如果权限里有人员并且选择的不是全公司 if (!empty($uids) && empty($params['liveScopeAll'])) { $toUser = array_merge($toUser, $uids); // 去重复人员 $toUser = array_unique($toUser); } } // 如果用户和部门为空则不发消息 if (empty($toUser) && empty($toParty)) { return true; } $articles = array( array( 'title' => $condition['title'], 'description' => $condition['description'], 'url' => !isset($params['jumpUrl']) ? oaUrl('Frontend/Index/VhLive/room', array('liveId' => $params['id'], 'liveVhallId' => $params['liveVhallId'])) : $params['jumpUrl'], 'picUrl' => '', ), ); try { $msgServ = &Msg::instance(); $msgServ->sendNews($toUser, $toParty, '', $articles); } catch (\Exception $e) { \Think\Log::record('发送消息失败:::' . var_export($e, true)); E($e->getCode() . ':' . $e->getMessage()); } return true; } /** * 通过岗位角色标签人员部门信息获取 * @param array $params * @return array */ public function get_auth_uids($params = []) { $uids = $params['liveScopeUsers'] ? $params['liveScopeUsers'] : []; if (is_json($params['liveScopeUsers']) && !is_array($params['liveScopeUsers'])) { $uids = json_decode($params['liveScopeUsers'], true); } // 初始化标签下的部门 $tag_dp_id = []; $user = User::instance(); // 处理岗位 if (!empty($params['liveScopeJobs'])) { if (is_json($params['liveScopeJobs']) && !is_array($params['liveScopeJobs'])) { $params['liveScopeJobs'] = json_decode($params['liveScopeJobs'], true); } $params['liveScopeJobs'] = array_unique($params['liveScopeJobs']); sort($params['liveScopeJobs']); // 获取岗位列表 $job_list = $user->listAll(array('jobIdList' => $params['liveScopeJobs'])); // 如果岗位下存在人员 if (!empty($job_list)) { $uids = array_column($job_list, 'memUid'); } } // 处理角色 if (!empty($params['liveScopeRoles'])) { if (is_json($params['liveScopeRoles']) && !is_array($params['liveScopeRoles'])) { $params['liveScopeRoles'] = json_decode($params['liveScopeRoles'], true); } $params['liveScopeRoles'] = array_unique($params['liveScopeRoles']); sort($params['liveScopeRoles']); // 获取角色列表 $role_List = $user->listAll(array('roleIdList' => $params['liveScopeRoles'])); // 如果岗位下存在人员 if (!empty($role_List)) { $uids = array_merge($uids, array_column($role_List, 'memUid')); } } // 处理标签 if (!empty($params['liveScopeTags'])) { if (is_json($params['liveScopeTags']) && !is_array($params['liveScopeTags'])) { $params['liveScopeTags'] = json_decode($params['liveScopeTags'], true); } $params['liveScopeTags'] = array_unique($params['liveScopeTags']); sort($params['liveScopeTags']); $tag = new Tag(); $tag_List = $tag->listUserByTagId($params['liveScopeTags'], 1, 1000); // 如果标签下存在人员 if (!empty($tag_List['list'])) { $uids = array_merge($uids, array_column($tag_List['list'], 'memUid')); } $tag_dp_id = array_filter(array_column($tag_List['list'], 'dpId')); $tag_dp_id = (array)$tag_dp_id; } // 处理部门 if (!empty($params['liveScopeDepts']) || !empty($tag_dp_id)) { // 获取标签下的部门 if (is_json($params['liveScopeDepts'])&& !is_array($params['liveScopeDepts'])) { $params['liveScopeDepts'] = json_decode($params['liveScopeDepts'], true); } // 合并标签下的部门ID集合 $params['liveScopeDepts'] = array_merge((array) $params['liveScopeDepts'], $tag_dp_id); $params['liveScopeDepts'] = array_unique($params['liveScopeDepts']); sort($params['liveScopeDepts']); $dp_conds = ['dpIdList' => $params['liveScopeDepts'], 'departmentChildrenFlag' => 1]; $dp_users = $user->listAll($dp_conds); if (!empty($dp_users)) { // 部门下的员工id集合 $d_uids = array_column($dp_users, 'memUid'); $uids = array_merge($uids, $d_uids); } } $uids = array_unique(array_filter($uids)); return $uids; } /*** * 赋值导师id * 去除权限数据 * 发送消息 * @param array $params * @param $type * @return bool */ public function send_teacher_msg($params = [], $type) { $uid = $params['teacher_id']; foreach (Constant::VH_SCOPE_SETTING_FIELD as $item) { unset($params[$item]); } $params['liveScopeUsers'] = $uid; $this->send_vh_Msg($params, $type); return true; } }