| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375 |
- <?php
- /**
- * raingad IM [ThinkPHP6]
- * @author xiekunyu <raingad@foxmail.com>
- */
- namespace app\enterprise\model;
- use app\admin\model\KeywordLanguages;
- use app\admin\model\QuestionLanguages;
- use app\manage\model\Config;
- use app\BaseModel;
- use think\facade\Db;
- use think\facade\Cache;
- class Message extends BaseModel
- {
- protected $pk="msg_id";
- protected $json = ["extends"];
- protected $jsonAssoc = true;
- protected static $fileType=['file','image','video','voice','emoji'];
- //给用户发送自动消息
- public static function sendAutoReply($field, $user_id, $cs_uid, $language_code){
- //获取自动回复的消息内容
- $content = Config::getFieldValue($field, $language_code);
- // 如果设置了自动回复消息,则发送
- if($content){
- $userInfo=User::field('user_id,realname,avatar')->where(['user_id'=>$cs_uid])->find();//客服信息
-
- if($userInfo){
- $userInfo = $userInfo->toArray();
- $userInfo['dispalayName']=$userInfo['realname'];
- $userInfo['id']=$userInfo['user_id'];
- $userInfo['avatar']=avatarUrl($userInfo['avatar'],$userInfo['realname'],$userInfo['user_id']);
- $msg=[
- 'id'=>\utils\Str::getUuid(),
- 'user_id'=>$cs_uid,
- 'content'=>$content,
- 'toContactId'=>$user_id,
- 'sendTime'=>time()*1000,
- 'type'=>'event',
- 'is_group'=>0,
- 'status'=>'succeed',
- 'fromUser'=>$userInfo,
- 'at'=>[],
- ];
- if (!empty($msg['content'])) {
- self::sendMsg($msg,0,1);
- }
- }
- }
- }
- // 添加聊天记录
- public static function addData($data){
- return Db::name('message')->insert($data);
- }
- // 更新消息状态
- public static function editData($update,$map){
- return Db::name('message')->where($map)->update($update);
- }
- // 查询聊天记录
- public static function getList($map,$where,$sort,$listRows,$pageSize){
- $list= Db::name('message')
- ->where($map)
- ->where($where)
- ->order($sort)
- ->paginate(['list_rows'=>$listRows,'page'=>$pageSize]);
- return $list;
- }
- // 发送消息
- public function sendMessage($param,$globalConfig=false){
- $param['language_code'] = $param['language_code'] ?? 'en';
- $is_group = $param['is_group'] ?? 0;
- $uid=self::$uid ? : ($param['user_id'] ?? 1);
- $is_robot = false; //是否给机器人发送消息
- if($param['toContactId']==-1){
- $is_group=0;
- }
- // 如果是系统账号,直接禁言
- if($is_group>1){
- $this->error=lang('im.forbidChat');
- return false;
- }
- $isForward=$param['is_forward'] ?? 0;
- $sendInterval = $globalConfig['chatInfo']['sendInterval'] ?? 0;
- // 如果设置了消息频率则验证,转发不收限制
- if ($sendInterval && !$isForward) {
- if (Cache::has('send_' . $uid)) {
- $this->error=lang('im.sendTimeLimit',['time'=>$sendInterval]);
- return false;
- }
- }
- if($param['type']=='text'){
- // 限制文字内容长度
- $text = strip_tags($param['content']);
- $textLen = mb_strlen($text);
- if ($textLen > 2048) {
- $this->error=lang('im.msgContentLimit') . $textLen;
- return false;
- }
- $param['content'] = preg_link($param['content']);
- // 接入聊天内容检测服务
- event('GreenText',['content'=>$param['content'],'service'=>"chat_detection"]);
- }
- $chatSetting = $globalConfig['chatInfo'];
- if($param['toContactId']!=-1){
- if ($is_group == 0) {
- $kefuUser=$chatSetting['autoAddUser']['user_ids'] ?? [];
- $manageUser=User::where([['status','=',1],['role','>',0]])->column('user_id');
- $kefu=array_unique(array_merge($kefuUser,$manageUser));
- $csUid = self::$userInfo['cs_uid'] ?? 0;
- $manage=false;
- // 发送者和接受者是客服或者管理员也可以发送消息
- if(in_array($uid,$kefu) || in_array($param['toContactId'],$kefu)){
- $manage=true;
- }
- if($chatSetting['simpleChat'] == 0 && !$manage){
- $this->error=lang('im.forbidChat');
- return false;
- }
- // 如果是单聊,并且是社区模式和不是自己的客服、需要判断是否是好友
- if ($globalConfig['sysInfo']['runMode'] == 2 && $csUid != $param['toContactId'] && !$manage) {
- // 判断我是不是对方的客服
- $cus = User::where(['user_id' => $param['toContactId']])->value('cs_uid');
- if ($cus != $uid) {
- $friend = Friend::where(['friend_user_id' => $uid, 'create_user' => $param['toContactId']])->find();
- if (!$friend) {
- $this->error=lang('im.notFriend');
- return false;
- }
- $otherFriend = Friend::where(['friend_user_id' => $param['toContactId'], 'create_user' => $uid])->find();
- if (!$otherFriend) {
- $this->error=lang('im.friendNot');
- return false;
- }
- }
- }
- //判断是否给机器人客服发送消息
- $autoCsUid = getAutoCsUid();
- if ($autoCsUid && $param['toContactId'] == $autoCsUid) {
- $is_robot = true;
- }
- }else{
- // 群聊必须群成员才能发送消息
- $group_id = explode('-', $param['toContactId'])[1] ?? '';
- if(!$group_id){
- $this->error=lang('system.parameterError');
- return false;
- }
- if(!self::nospeak($group_id,$uid)){
- if($isForward){
- return false;
- }
- return shutdown(lang('group.notSpeak'));
- }
- // 群聊必须群成员才能发送消息
- $groupUser=GroupUser::where(['user_id'=>$uid,'status'=>1,'group_id'=>$group_id,'delete_time'=>0])->find();
- if(!$groupUser){
- $this->error = lang('group.notCustom');
- return false;
- }
- if($groupUser['no_speak_time']>time()){
- $this->error = lang('group.notSpeak',['time'=>date('Y-m-d H:i:s',$groupUser['no_speak_time'])]);
- return false;
- }
- }
- }
- if ($sendInterval) {
- Cache::set('send_' . $uid, time(), $sendInterval);
- }
- $data = self::sendMsg($param,$is_group, 0, $uid);
- // 机器人自动回复问题推送给用户
- if ($is_robot && $param['type'] == 'text') {
- if (!empty($param['question_id'])) {
- $param['type'] = 'answer';
- $param['content'] = QuestionLanguages::where('id', $param['question_id'])->value('answer');
- $param['extends'] = json_encode([
- 'question_id' => $param['question_id'],
- ]);
- } else {
- //获取关键词匹配
- $keyword_ids = KeywordLanguages::getKeywordByContent($param['content']);
- $question = QuestionLanguages::getQuestion($keyword_ids, $param['content']);
- $data['question'] = $question;
- if ($question) {
- $param['type'] = 'list';
- $content = [
- 'title' => Config::getFieldValue('reply_keyword',$param['language_code']),
- 'list' => $question,
- ];
- $param['content'] = json_encode($content);
- } else {
- $param['type'] = 'text';
- $param['content'] = Config::getFieldValue('reply_keyword_math_fail',$param['language_code']);
- }
- }
-
- if (!empty($param['content'])) {
- $fromUserId = (int)$param['toContactId'];
- $user_id = (int)$param['user_id'];
- $param['toContactId'] = $user_id;
- $param['user_id'] = $fromUserId;
- $param['fromUser'] = null;
- $param['id'] = \utils\Str::getUuid();
- self::sendMsg($param,$is_group, 0, $user_id);
- }
- }
- return $data;
- }
- //实际发送消息
- public static function sendMsg($param,$is_group=0,$is_sys=0, $uid=0){
- // $uid = $uid ?: ($param['user_id'] ?? 1);
- $uid = self::$uid ?: ($param['user_id'] ?? 1);
- $toContactId=$param['toContactId'];
- $manage=[];
- // 重新建立会话,更新会话删除记录
- $isDelChat=ChatDelog::where(['user_id'=>$uid,'to_user'=>$toContactId])->find();
- if($isDelChat){
- ChatDelog::where(['user_id'=>$uid,'to_user'=>$toContactId])->delete();
- ChatDelog::updateCache($uid);
- }
- if($is_group==1){
- $group_id = explode('-', $param['toContactId'])[1] ?? '';
- $chat_identify=$toContactId;
- $toContactId=$group_id;
- $manage=GroupUser::getGroupManage($group_id);
- }else{
- $chat_identify=chat_identify($param['user_id'],$toContactId);
- }
- $fileSzie=isset($param['file_size'])?$param['file_size']:'';
- $fileName=isset($param['file_name'])?$param['file_name']:'';
- $ossUrl=getDiskUrl();
- // 如果是转发图片文件的消息,必须把域名去除掉
- $content=$param['content'];
- if(in_array($param['type'],self::$fileType)){
- if(strpos($param['content'],$ossUrl)!==false){
- $content=str_replace($ossUrl,'',$param['content']);
- }
- }
- $param['content']=$content;
- $atList=($param['at'] ?? null) ? array_map('intval', $param['at']): [];
- // 如果at里面有0,代表@所有人
- if($atList && in_array(0,$atList)){
- $atList=GroupUser::where([['group_id','=',$toContactId],['status','=',1],['user_id','<>',$param['user_id']]])->column('user_id');
- }
- $at=$atList ? implode(',',$atList) : null;
- $data=[
- 'from_user'=>$param['user_id'],
- 'to_user'=>$toContactId,
- 'id'=>$param['id'],
- 'content'=>$param['type'] != 'list' ? str_encipher($param['content'],true) : $param['content'],
- 'chat_identify'=>$chat_identify,
- 'create_time'=>time(),
- 'type'=>$param['type'],
- 'is_group'=>$toContactId==-1 ? 3 : $is_group,
- 'is_read'=>$is_group ? 1 : 0,
- 'file_id'=>$param['file_id'] ?? 0,
- "file_cate"=>$param['file_cate'] ?? 0,
- 'file_size'=>$fileSzie,
- 'file_name'=>$fileName,
- 'at'=>$at,
- 'pid'=>$param['pid'] ?? 0,
- 'extends'=>($param['extends'] ?? null) ? $param['extends'] : null,
- 'translate_content' => $param['translate_content'] ?? null,
- 'language_code' => $param['language_code'] ?? '',
- ];
- $message=new self();
- $message->update(['is_last'=>0],['chat_identify'=>$chat_identify]);
- $message->save($data);
-
- // 拼接消息推送
- $type=$is_group?'group':'simple';
- $sendData=$param;
- $sendData['status']='succeed';
- $sendData['at']=$atList;
- $sendData['msg_id']=$message->msg_id;
- $sendData['is_click']=(int)$message->is_click;
- $sendData['is_read']=0;
- $sendData['to_user']=(string)$toContactId;
- $sendData['role']=$manage[self::$uid] ?? 3;
- $sendData['sendTime']=(int)$sendData['sendTime'];
- $sendData['translate_content'] = $param['translate_content'] ?? '';
-
- //这里单聊中发送对方的消息,对方是接受状态,自己是对方的联系人,要把发送对象设置为发送者的ID。
- if($is_group){
- $sendData['toContactId']=$param['toContactId'];
- // 将团队所有成员的未读状态+1
- GroupUser::editGroupUser([['group_id','=',$toContactId],['user_id','<>',$uid]],['unread'=>Db::raw('unread+1')]);
- }else{
- //$sendData['toContactId']=$toContactId;//$uid;
- $sendData['toContactId'] = $param['user_id'];
- }
- $sendData['fileSize']=$fileSzie;
- $sendData['fileName']=$fileName;
- if(in_array($sendData['type'],self::$fileType)){
- $sendData['content']=getFileUrl($sendData['content']);
- if($sendData['type']=='image'){
- $pre=1;
- }else{
- $pre=2;
- }
- $sendData['preview']=previewUrl($sendData['content'],$pre);
- $sendData['extUrl']=getExtUrl($sendData['content']);
- $sendData['download']= $sendData['file_id'] ? getMainHost().'/filedown/'.encryptIds($sendData['file_id']) : '';
- }
- $forContactId=$sendData['toContactId'];
- if($is_sys){
- $forContactId=$toContactId;
- }
- if($is_group==0){
- $toContactId=[$toContactId,$param['user_id']];
- }
-
- $sendData['toUser']=(string)$param['toContactId'];
- $user=new User();
- // 将聊天窗口的联系人信息带上,方便临时会话
-
- $sendData['contactInfo']=$user->setContact($forContactId,$is_group,$sendData['type'],$sendData['content']);
- if (empty($sendData['fromUser'])) {
- $sendData['fromUser'] = [
- 'id' => $sendData['contactInfo']['id'],
- 'displayName' => $sendData['contactInfo']['displayName'],
- 'avatar' => $sendData['contactInfo']['avatar'],
- 'account' => '',
- ];
- }
- $sendData['fromUser']['id']=(int)$sendData['fromUser']['id'];
- // 向发送方发送消息
- wsSendMsg($toContactId,$type,$sendData,$is_group);
- $sendData['toContactId']=$param['toContactId'];
- return $sendData;
- }
- // 群禁言
- public static function nospeak($group_id,$user_id){
- $group=Group::find($group_id);
- if($group->owner_id==$user_id){
- return true;
- }
- if($group->setting){
- $setting=json_decode($group->setting,true);
- $nospeak=isset($setting['nospeak'])?$setting['nospeak']:0;
- $role=GroupUser::where(['group_id'=>$group_id,'user_id'=>$user_id])->value('role');
- if($nospeak==1 && $role>2){
- return false;
- }elseif($nospeak==2 && $role!=1){
- return false;
- }
- }
- return true;
- }
- // 将消息中的@用户加入到atListQueue中
- public static function setAtread($messages,$user_id){
- foreach($messages as $k=>$v){
- if(!isset($v['at'])){
- continue;
- }
- if($v['at'] && in_array($user_id,$v['at'])){
- $atListQueue=Cache::get("atListQueue");
- $atListQueue[$v['msg_id']][]=$user_id;
- Cache::set("atListQueue",$atListQueue);
- }
- }
- }
- }
|