| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323 |
- <?php
- namespace app\enterprise\controller;
- use app\BaseController;
- use think\facade\Session;
- use think\facade\Db;
- use app\enterprise\model\{User, Message, GroupUser, Friend,Group,ChatDelog};
- use GatewayClient\Gateway;
- use Exception;
- use think\facade\Cache;
- use app\manage\model\{Config};
- use app\admin\model\GuessAskLanguages;
- use app\admin\model\QuestionLanguages;
- use app\admin\model\Complaint;
- use app\admin\model\ComplaintItem;
- use app\admin\model\Score;
- class Im extends BaseController
- {
- protected $fileType = ['file', 'image','video','voice','emoji'];
- /**
- * 给客服打分
- */
- public function Score()
- {
- $score = $this->request->param('score');
- $msg_id = $this->request->param('msg_id');
- if (empty($msg_id)) {
- return $this->error('参数有误',[], 10009);
- }
- if (empty($score)) {
- return $this->error('请打分',[], 10009);
- }
- $user_id = $this->userInfo['user_id'];
- $user = User::where('user_id', $user_id)->find();
- if (!$user) {
- return $this->error('用户不存在',[], 10009);
- }
- $exist = Message::where('msg_id', $msg_id)->where('to_user', $user_id)->find();
- if ($exist) {
- if ( $exist['is_click'] == 1) {
- return $this->error('已评价',[], 10009);
- }
- $extends = $exist['extends'] && !is_array($exist['extends']) ? json_decode($exist['extends'], true) : $exist['extends'];
- if (!empty($extends['cs_uid'])) {
- Score::create([
- 'user_id' => $user_id,
- 'cs_uid' => $extends['cs_uid'],
- 'score' => (int)$score,
- ]);
- //保留一位小数
- $avg_score = Score::where('cs_uid', $extends['cs_uid'])->avg('score');
- $avg_score = number_format($avg_score, 1);
- User::where('user_id', $extends['cs_uid'])->update(['score' => $avg_score]);
- }
- $exist->is_click = 1;
- $exist->save();
- }
- return $this->success([],'提交成功');
- }
- /**
- */
- public function complaintList()
- {
- try {
- $params = $this->request->param();
- $page = $params['page'] ?? 1;
- $limit = $params['limit'] ?? 15;
- $language_code = $params['language_code'] ?? $this->lang;
-
- $query = ComplaintItem::where('language_code', $language_code);
-
- $count = $query->count();
- $list = $query->order('weight','desc')
- ->limit($limit)
- ->page($page)
- ->select();
- } catch (Exception $e) {
- return $this->error($e->getMessage());
- }
- return $this->success(['count' => $count, 'list' => $list]);
- }
- /**
- * 投诉客服
- */
- public function complaint()
- {
- $params = $this->request->param();
- if (empty($params['complaint_item_id'])) {
- return $this->error('请选择投诉项',[], 10009);
- }
- $user_id = $this->userInfo['user_id'];
- $user = User::where('user_id', $user_id)->find();
- if (!$user) {
- return $this->error('用户不存在',[], 10009);
- }
- $exist = Complaint::where('user_id', $user_id)->where('cs_uid', $user->cs_uid)->find();
- if ($exist) {
- return $this->error('您已投诉过该客服,无需重复投诉',[], 10009);
- }
- Complaint::create([
- 'user_id' => $user_id,
- 'cs_uid' => $user->cs_uid,
- 'complaint_item_id' => $params['complaint_item_id'],
- 'remark' => $params['remark'] ?? '',
- 'language_code' => $this->lang,
- ]);
- return $this->success([],'提交成功');
-
- }
- /**
- * 猜你想问列表
- */
- public function guessask()
- {
- try {
- $params = $this->request->param();
- $page = $params['page'] ?? 1;
- $limit = $params['limit'] ?? 15;
- $language_code = $this->lang;
- $query = GuessAskLanguages::where('language_code', $language_code)->where('status', 1);
- if (!empty($params['keyword'])) {
- $query = $query->where('name', 'like', '%'.$params['keyword'].'%');
- }
- if (isset($params['type']) && $params['type'] != '') {
- $query = $query->where('type', $params['type']);
- }
- $count = $query->count();
- $list = $query->order('is_top','desc')
- ->order('is_rec','desc')
- ->order('click_num','desc')
- ->limit($limit)
- ->page($page)
- ->select();
-
- } catch (Exception $e) {
- return $this->error($e->getMessage());
- }
- return $this->success(['count' => $count, 'list' => $list]);
- }
- /**
- * 猜你想问点击使用
- */
- function guessaskClick()
- {
- try {
- $id = $this->request->param('id');
- $info = GuessAskLanguages::where('id', $id)->where('status', 1)->find();
- if ($info) {
- $info->click_num = $info->click_num + 1;
- $info->save();
- }
- } catch (Exception $e) {
- return $this->error($e->getMessage());
- }
- return $this->success([]);
- }
- /**
- * 问题列表
- */
- function question()
- {
- try {
- $params = $this->request->param();
- $page = $params['page'] ?? 1;
- $limit = $params['limit'] ?? 15;
- $language_code = $this->lang;
- $query = QuestionLanguages::where('language_code', $language_code)->where('status', 1);
-
- if (isset($params['question_type']) && $params['question_type'] != '') {
- $query = $query->where('question_type', $params['question_type']);
- }
- $count = $query->count();
- $list = $query->order('weight','desc')
- ->limit($limit)
- ->page($page)
- ->select();
- } catch (Exception $e) {
- return error($e->getMessage());
- }
- return $this->success(['count' => $count, 'list' => $list]);
- }
- /**
- * 问题点赞、点否
- */
- function questionClick()
- {
- try {
- $is_like = $this->request->param('is_like');
- $msg_id = $this->request->param('msg_id');
- if (empty($msg_id) || !in_array($is_like, [1, 0])) {
- return $this->error('参数有误',[], 10009);
- }
- $user_id = $this->userInfo['user_id'];
- $exist = Message::where('msg_id', $msg_id)->where('to_user', $user_id)->find();
- if ($exist && $exist['is_click'] == 0) {
- $extends = $exist['extends'];
- $id = $extends['question_id'] ?? 0;
- if ($id) {
- if ($is_like == 1) {
- QuestionLanguages::where('id', $id)->update(['like_count'=>Db::raw('like_count+1')]);
- } else {
- QuestionLanguages::where('id', $id)->update(['dislike_count'=>Db::raw('dislike_count+1')]);
- }
- }
- $exist->is_click = $is_like == 1 ? 1 : 2;
- $exist->save();
- }
-
- } catch (Exception $e) {
- return $this->error($e->getMessage());
- }
- return $this->success([]);
- }
- /**
- * 转人工客服
- */
- function transferHuman()
- {
- try {
- $user_id = $this->userInfo['user_id'];
- $user = User::where('user_id', $user_id)->find();
- if (!$user) {
- return $this->error('用户不存在',[], 10009);
- }
- if ($user->role > 0) {
- return $this->error('系统管理员无法转人工',[], 10009);
- }
- if($user->service_status == -1) {
-
- //机器人客服
- $auto_cs_uid = getAutoCsUid();
- $user->service_status = 0;
- $user->service_start = time();
- $user->timeout_type = 0;
- $user->cs_uid = $auto_cs_uid;
- $user->save();
- $param = [
- 'id' => \utils\Str::getUuid(),
- 'type' => 'text',
- 'status' => 'going',
- 'sendTime' => time() * 1000,
- 'toContactId' => $user_id,
- 'content' => Config::getFieldValue('transfer_to_human', $this->lang),
- 'file_id' => 0,
- 'is_group' => 0,
- 'user_id' => $auto_cs_uid,
- ];
- Message::sendMsg($param, 0);
-
- // //通知客服已接线
- // wsSendMsg(0,'handleChat',['user_id'=>$user_id]);
- }
- } catch (Exception $e) {
- return $this->error($e->getMessage());
- }
- return $this->success([]);
- }
- // 获取联系人列表
- public function getContacts()
- {
- $this->userInfo['cs_uid'] = User::where('user_id', $this->userInfo['user_id'])->value('cs_uid');
- $map = [['status', '=', 1], ['user_id', '<>', $this->userInfo['user_id']]];
- // if ($this->userInfo['role'] != 0) {
- // $map[] = ['service_status', '<>', -1];
- // }
- $data = User::getUserList($this->userInfo, $map, $this->userInfo['user_id'] , '', $this->userInfo['role']);
- $count=Friend::where(['status'=>2,'friend_user_id'=>$this->uid])->count();
- $time=Friend::where(['friend_user_id'=>$this->uid,'is_invite'=>1])->order('create_time desc')->value('create_time');
- return success('', $data,$count,$time*1000);
- }
- // 获取聊天列表
- public function getChatList()
- {
- $data = User::getChatList($this->userInfo['user_id']);
- $count=Friend::where(['status'=>2,'friend_user_id'=>$this->uid])->count();
- $time=Friend::where(['friend_user_id'=>$this->uid,'is_invite'=>1])->order('create_time desc')->value('create_time');
- return success('', $data,$count,$time*1000);
- }
- // 获取好友列表
- public function getFriendList()
- {
- $data = User::getFriendList([['status', '=', 1], ['user_id', '<>', $this->userInfo['user_id']]],$this->userInfo['user_id']);
- return success('', $data);
- }
- // 获取群聊列表
- public function getGroupList()
- {
- $data = User::getGroupList($this->userInfo['user_id']);
- return success('', $data);
- }
- // 获取单个人员的信息
- public function getContactInfo(){
- $id = $this->request->param('id');
- $is_group = is_string($id) ? 1 : 0;
- $user=new User;
- $data=$user->setContact($id,$is_group);
- if(!$data){
- return warning($user->getError());
- }
- return success('',$data);
- }
- //发送消息
- public function sendMessage()
- {
- $param = $this->request->param();
- $content = strip_tags($param['content']);
-
- if (empty($content) || $content == '') {
- return warning("请输入内容");
- }
- $param['user_id'] = $this->userInfo['user_id'];
- $param['language_code'] = $this->lang;
- if ($this->userInfo['role'] != 0 && $param['type'] == 'text') {
- //客服或管理员给用户发送消息,需要按照用户的语言做翻译
- $toContactId = $param['toContactId'];
- $toUser = User::where('user_id', $toContactId)->field(['role', 'language_code'])->find();
- if ($toUser && $toUser['role'] == 0 && $toUser['language_code']) {
- //谷歌翻译
- $param['translate_content'] = google_translate($param['content'], $toUser['language_code']);
- $param['language_code'] = $toUser['language_code'];
- }
- }
- // if ($this->userInfo['role'] == 0) {
- // //用户发送消息时,如果是机器人对话的状态,则变更为排队中
- // $service_status = User::where('user_id', $this->userInfo['user_id'])->value('service_status');
- // if ($service_status == -1) {
- // User::where('user_id', $this->userInfo['user_id'])->update(['service_status' => 0]);
- // }
- // }
- $param['language_code'] = $this->lang;
- $message=new Message();
- $data = $message->sendMessage($param,$this->globalConfig);
- //已发送的消息,设置成已读
- // if (isset($data['is_read'])) {
- // $data['is_read'] = 1;
- // }
- if ($data) {
- return success('', $data);
- } else {
- return warning($message->getError());
- }
- }
- //转发消息
- public function forwardMessage()
- {
- $param = $this->request->param();
- $userIds=$param['user_ids'] ?? [];
- if(!$userIds || count($userIds)>5){
- return warning(lang('im.forwardLimit',['count'=>5]));
- }
- $msg_id=$param['msg_id'] ?? 0;
- $message=Message::find($msg_id);
- if(!$message){
- return warning(lang('im.exist'));
- }
- $msg=$message->toArray();
- $userInfo=$this->userInfo;
- queuePush([
- 'action'=>'forwardMessage',
- 'message'=>$msg,
- 'user_ids'=>$userIds,
- 'config'=>$this->globalConfig,
- 'userInfo'=>$userInfo
- ]);
- return success(lang('im.forwardOk'));
- }
- // 获取用户信息
- public function getUserInfo()
- {
- $user_id = $this->request->param('user_id');
- $group_id = $this->request->param('group_id');
- $groupInfo=[];
- if($group_id){
- $group_id = explode('-', $group_id)[1];
- $groupInfo=Group::where(['group_id'=>$group_id])->find();
- if($groupInfo){
- // 查询操作对象的角色
- $groupInfo['userInfo']=GroupUser::where(['user_id'=>$user_id,'group_id'=>$group_id])->find() ?: [];
- // 查询我的角色
- $groupInfo['manageRole']=GroupUser::where(['user_id'=>$this->userInfo['user_id'],'group_id'=>$group_id])->value('role') ?: 3;
- }
- }
- $user=User::find($user_id);
- if(!$user){
- return error(lang('user.exist'));
- }
- $user->avatar=avatarUrl($user->avatar,$user->realname,$user->user_id,120);
- // 账号前面截取3位,后面截取两位,中间星号展示
- $user->account=substr($user->account, 0, 3).'******'.substr($user->account, -2, 2);
- // 查询好友关系
- $friend=Friend::where(['friend_user_id'=>$user_id,'create_user'=>$this->userInfo['user_id'],'status'=>1])->find();
- $user->friend=$friend ? : '';
- $location='';
- if($user->last_login_ip){
- $location=implode(" ", \Ip::find($user->last_login_ip));
- }
- $user->location=$location;
- $user->groupInfo=$groupInfo ? : [];
- $user->password='';
- $userModel=new User;
- $user->contactInfo=$userModel->setContact($user_id,0) ?? [];
- return success('', $user);
- }
- // 扫码登录,向客户端推送数据
- public function tokenLogin(){
- $param = $this->request->param();
- $token=$param['token'] ?? '';
- $client_id='';
- if($token){
- $client_id=authcode(urldecode($token),"DECODE", config('app.app_id'));
- if(!$client_id){
- return warning(lang('user.loginError'));
- }
- }else{
- return warning(lang('user.loginError'));
- }
- $userInfo=$this->userInfo;
- if(!$userInfo){
- return warning(lang('user.loginError'));
- }
- // 如果用户已经有设置
- $setting=$userInfo['setting'] ?: '';
- if($setting){
- $setting['hideMessageName']= $setting['hideMessageName']=='true' ? true : false;
- $setting['hideMessageTime']= $setting['hideMessageTime']=='true' ? true : false;
- $setting['avatarCricle']= $setting['avatarCricle']=='true' ? true : false;
- $setting['isVoice']= $setting['isVoice']=='true' ? true : false;
- $setting['sendKey']= 1;//(int)$setting['sendKey'];
- }
- $userInfo['setting']=$setting;
- Gateway::$registerAddress = config('gateway.registerAddress');
- //如果登录信息中含有client——id则自动进行绑定
- if($client_id){
- $user_id=$userInfo['user_id'];
-
- // 如果当前ID在线,将其他地方登陆挤兑下线
- if(Gateway::isUidOnline($user_id)){
- wsSendMsg($user_id,'offline',['id'=>$user_id,'client_id'=>$client_id,'isMobile'=>false]);
- }
- Gateway::bindUid($client_id, $user_id);
- // 查询团队,如果有团队则加入团队
- $group=Group::getMyGroup(['gu.user_id'=>$user_id,'gu.status'=>1]);
- if($group){
- $group=$group->toArray();
- $group_ids=arrayToString($group,'group_id',false);
- foreach($group_ids as $v){
- Gateway::joinGroup($client_id, $v);
- }
- }
- }
- $update=[
- 'last_login_time'=>time(),
- 'last_login_ip'=>$this->request->ip(),
- 'login_count'=>Db::raw('login_count+1')
- ];
- User::where('user_id',$userInfo['user_id'])->update($update);
- $authToken=User::refreshToken($userInfo,'web');
- $data=[
- 'sessionId'=>Session::getId(),
- 'authToken'=>$authToken,
- 'userInfo'=>$userInfo
- ];
- Gateway::sendToClient($client_id, json_encode(array(
- 'type' => 'tokenLogin',
- 'data' => $data,
- )));
- return success(lang('user.loginOk'),$data);
- }
- // 搜索用户
- public function searchUser(){
- $keywords=$this->request->param('keywords','');
- if(!$keywords){
- return success('',[]);
- }
- $map=['status'=>1,'account'=>$keywords];
- $list=User::where($map)->field(User::$defaultField)->where([['account','<>',$this->userInfo['account']]])->select()->toArray();
- if($list){
- $ids=array_column($list,'user_id');
- $friendList=Friend::getFriend([['create_user','=',$this->uid],['friend_user_id','in',$ids]]);
- foreach($list as $k=>$v){
- $list[$k]['avatar']=avatarUrl($v['avatar'],$v['realname'],$v['user_id'],120);
- $list[$k]['friend']=$friendList[$v['user_id']] ?? '';
- }
- }
- return success('', $list);
- }
- // 获取系统所有人员加搜索
- public function userList(){
- $keywords=$this->request->param('keywords','');
- $listRows=$this->request->param('limit',20);
- $page=$this->request->param('page',1);
- $map=['status'=>1];
- $field="user_id,realname,avatar";
- if(!$keywords){
- $list=User::where($map)->field($field)->order('user_id asc')->limit(20)->paginate(['list_rows'=>$listRows,'page'=>$page]);;
- if($list){
- $list=$list->toArray()['data'];
- }
- }else{
- $list=User::where($map)->field($field)->where([['account','<>',$this->userInfo['account']]])->whereLike('account|realname|name_py','%'.$keywords.'%')->select()->toArray();
- }
- if($list){
- foreach($list as $k=>$v){
- $list[$k]['avatar']=avatarUrl($v['avatar'],$v['realname'],$v['user_id'],120);
- $list[$k]['id']=$v['user_id'];
- }
- }
- return success('', $list);
- }
- // 获取聊天记录
- public function getMessageList()
- {
- $param = $this->request->param();
- $is_group = isset($param['is_group']) ? $param['is_group'] : 0;
- // 如果toContactId是数字,绝对是单聊
- $is_group = is_numeric($param['toContactId']) ? 0 : $is_group;
- // 设置当前聊天消息为已读
- $chat_identify = $this->setIsRead($is_group, $param['toContactId']);
- $type = isset($param['type']) ? $param['type'] : '';
- $is_at = isset($param['is_at']) ? $param['is_at'] : '';
- $map = ['chat_identify' => $chat_identify, 'status' => 1];
- $where = [];
- if ($type && $type != "all") {
- $map['type'] = $type;
- } else {
- if (isset($param['type'])) {
- $where[] = ['type', '<>', 'event'];
- }
- }
- $groupManage=[];
- // 群聊查询入群时间以后的消息
- if($is_group==1){
- $group_id = explode('-', $param['toContactId'])[1];
- $group=Group::where(['group_id'=> $group_id])->find();
- $groupManage=GroupUser::getGroupManage($group_id);
- if($group && $group['setting']){
- $groupSetting=json_decode($group['setting'],true);
- $history=$groupSetting['history'] ?? false;
- // 如果开启了历史记录才可以查看所有记录,否者根据进群时间查询记录
- if(!$history){
- $createTime=GroupUser::where(['group_id'=> $group_id,'user_id'=>$this->userInfo['user_id']])->value('create_time');
- $where[] = ['create_time', '>=', $createTime ? : 0];
- }
- }
- }
- $keywords = isset($param['keywords']) ? $param['keywords'] : '';
- if ($keywords && in_array($type, ['text', 'all'])) {
- $where[] = ['content', 'like', '%' . $keywords . '%'];
- }
- // 如果是查询@数据
- if($is_at){
- $atList=Db::name('message')->where($map)->where($where)->whereFindInSet('at',$this->userInfo['user_id'])->order('msg_id desc')->select()->toArray();
- if($atList){
- $data = $this->recombileMsg($atList,false);
- Message::setAtread($data,$this->userInfo['user_id']);
- return success('', $data, count($data));
- }else{
- return success('', [], 0);
- }
- }
- $listRows = $param['limit'] ?: 20;
- $pageSize = $param['page'] ?: 1;
- $last_id = $param['last_id'] ?? 0;
- if($last_id){
- $where[]=['msg_id','<',$last_id];
- $pageSize=1;
- }
- //判断是客服还是用户
- if ($this->userInfo['role'] == 0) {
- //用户可见历史记录的时长
- $hours = Config::where('field', 'user_show_message')->value('val');
- if ($hours > 0) {
- $start_time = time() - $hours * 60 * 60;
- $where[] = ['create_time', '>=', $start_time];
- }
- } elseif ($this->userInfo['role'] > 0) {
- //客服可见历史记录的时长
- $hours = Config::where('field', 'kefu_show_message')->value('val');
- if ($hours > 0) {
- $start_time = time() - $hours * 60 * 60;
- $where[] = ['create_time', '>=', $start_time];
- }
- $toUser = User::where('user_id', $param['toContactId'])->find();
- if ($toUser && $toUser->service_status == 1 && $toUser->cs_uid == $this->userInfo['user_id']) {
- //将用户待处理的状态更新成服务中
- $toUser->service_status = 2;
- $toUser->service_time = time();
- $toUser->save();
-
- //通知客服-会话服务中
- wsSendMsg(0,'handleChat',['user_id'=>$param['toContactId']]);
- } else {
- // $map['chat_identify'] = $toUser->cs_uid.'-'.$param['toContactId'];
- }
- }
- $list = Message::getList($map, $where, 'msg_id desc', $listRows, $pageSize);
- $data = $this->recombileMsg($list,true,$groupManage);
- // 如果是群聊并且是第一页消息,需要推送@数据给用户
- if($param['is_group']==1 && $param['page']==1){
- $isPush=Cache::get('atMsgPush'.$chat_identify) ?? '';
- $atList=Db::name('message')->where(['chat_identify'=>$chat_identify,'is_group'=>1])->whereFindInSet('at',$this->userInfo['user_id'])->order('msg_id desc')->select()->toArray();
- $msgIda=array_column($atList,'msg_id');
- // 如果两次推送at数据的列表不一样,则推送
- if($isPush!=json_encode($msgIda)){
- $atData=$this->recombileMsg($atList,false);
- wsSendMsg($this->userInfo['user_id'],'atMsgList',[
- 'list'=>$atData,
- 'count'=>count($atData),
- 'toContactId'=>$param['toContactId']
- ]);
- Cache::set('atMsgPush'.$chat_identify,json_encode($msgIda),60);
- }
- }
- // 如果是消息管理器则不用倒序
- if (!isset($param['type'])) {
- $data = array_reverse($data);
- }
- return success('', $data, $list->total());
- }
- // 获取单条消息详情
- public function getMessageInfo()
- {
- $param = $this->request->param();
- $id = $param['msg_id'] ?? 0;
- $message = Message::where(['msg_id' => $id])->find();
- if ($message) {
- $data = $this->recombileMsg([$message], false);
- return success('', $data);
- } else {
- return warning(lang('im.exist'));
- }
- }
- // 获取单条消息上下文
- public function getMessageContext()
- {
- $param = $this->request->param();
- $is_group = isset($param['is_group']) ? $param['is_group'] : 0;
- $id = $param['msg_id'] ?? 0;
- $direction = $param['direction'] ?? 0;
- $message = Message::where(['msg_id' => $id])->find();
- if (!$message) {
- return warning(lang('im.exist'));
- }
- $groupManage=[];
- $where = [];
- $map = ['chat_identify' => $message['chat_identify'], 'status' => 1];
- if($is_group==1 && $direction<2){
- $group_id = $message['to_user'];
- $group=Group::where(['group_id'=> $group_id])->find();
- $groupManage=GroupUser::getGroupManage($group_id);
- if($group && $group['setting']){
- $groupSetting=json_decode($group['setting'],true);
- $history=$groupSetting['history'] ?? false;
- // 如果开启了历史记录才可以查看所有记录,否者根据进群时间查询记录
- if(!$history){
- $createTime=GroupUser::where(['group_id'=> $group_id,'user_id'=>$this->userInfo['user_id']])->value('create_time');
- $where[] = ['create_time', '>=', $createTime ? : 0];
- }
- }
- }
- if($direction==0){
- $where[] = ['msg_id', '<', $id];
- $beforeList = Message::where($map)->where($where)->order('msg_id desc')->limit(5)->select()->toArray();
- $beforeList = array_reverse($beforeList);
- $where2 = [];
- $where2[] = ['msg_id', '>=', $id];
- $afterList = Message::where($map)->where($where2)->order('msg_id asc')->limit(5)->select()->toArray();
- $data = array_merge($beforeList, $afterList);
- }elseif($direction==1){
- $where[] = ['msg_id', '<', $id];
- $data = Message::where($map)->where($where)->order('msg_id desc')->limit(5)->select()->toArray();
- $data = array_reverse($data);
- }else{
- $where[] = ['msg_id', '>', $id];
- $data = Message::where($map)->where($where)->order('msg_id asc')->limit(5)->select()->toArray();
- }
- if($data){
- $data = $this->recombileMsg($data, false,$groupManage);
- }
- return success('', $data);
- }
- protected function recombileMsg($list,$isPagination=true,$manage=[])
- {
- $data = [];
- $userInfo = $this->userInfo;
- if ($list) {
- $listData = $isPagination ? $list->toArray()['data'] : $list;
- $userList = User::matchUser($listData, true, 'from_user', 120);
-
- foreach ($listData as $k => $v) {
- // 屏蔽已删除的消息
- if ($v['del_user']) {
- $delUser = explode(',', $v['del_user']);
- if (in_array($userInfo['user_id'], $delUser)) {
- unset($list[$k]);
- continue;
- // $v['type']="event";
- // $v['content']="删除了一条消息";
- }
- }
- $content = str_encipher($v['content'],false);
- $preview = '';
- $ext='';
- if (in_array($v['type'], $this->fileType)) {
- $content = getFileUrl($content);
- $preview = previewUrl($content);
- $ext=getExtUrl($content);
- }
-
- $fromUser = $userList[$v['from_user']];
- // 处理撤回的消息
- if ($v['type'] == "event" && $v['is_undo']==1) {
- if ($v['from_user'] == $userInfo['user_id']) {
- $content = lang('im.you'). $content;
- } elseif ($v['is_group'] == 1) {
- $content = $fromUser['realname'] . $content;
- } else {
- $content = lang('im.other') . $content;
- }
- }
- $toContactId=$v['is_group'] ==1 ? 'group-'.$v['to_user'] : $v['to_user'];
- $atList=($v['at'] ?? null) ? explode(',',$v['at']): [];
- $role=$manage[$v['from_user']] ?? 3;
- $data[] = [
- 'msg_id' => $v['msg_id'],
- 'id' => $v['id'],
- 'status' => "succeed",
- 'type' => $v['type'],
- 'sendTime' => (is_string($v['create_time']) ? strtotime($v['create_time']) : $v['create_time'])* 1000,
- 'content' => $content,
- 'preview' => $preview,
- 'download' => $v['file_id'] ? getMainHost().'/filedown/'.encryptIds($v['file_id']) : '',
- 'is_read' => $v['is_read'],
- 'is_group' => $v['is_group'],
- 'at' => $atList,
- 'toContactId' => $toContactId,
- 'from_user' => $v['from_user'],
- 'file_id' => $v['file_id'],
- 'file_cate' => $v['file_cate'],
- 'fileName' => $v['file_name'],
- 'fileSize' => $v['file_size'],
- 'is_click' => $v['is_click'],
- 'fromUser' => $fromUser,
- 'extUrl'=>$ext,
- 'role'=>$role,
- 'extends'=>is_string($v['extends'])?json_decode($v['extends'],true) : $v['extends'],
- 'translate_content' => $v['translate_content'],
- 'language_code' => $v['language_code'],
- ];
- }
- }
- return $data;
- }
- // 设置当前窗口的消息默认为已读
- public function setMsgIsRead()
- {
- $param = $this->request->param();
-
- // 判断是否是一个二维数组
- if (is_array($param['messages'][0] ?? '')) {
- $messages=$param['messages'];
- } else {
- $messages=[$param['messages']];
- }
- $this->setIsRead($param['is_group'], $param['toContactId'],$messages);
- if (!$param['is_group']) {
- wsSendMsg($param['fromUser'], 'isRead', $messages, 0);
- }
- return success('');
- }
- // 设置全部为已读
- public function readAllMsg()
- {
- // 阅读所有单聊
- $map = ['to_user' => $this->userInfo['user_id'], 'is_read' => 0, 'is_group' => 0];
- Message::where($map)->update(['is_read' => 1]);
- // 阅读所有群聊
- GroupUser::where(['user_id' => $this->userInfo['user_id'], 'status' => 1])->update(['unread'=>0]);
- return success('');
- }
- // 设置消息已读
- protected function setIsRead($is_group, $to_user,$messages=[])
- {
- if ($is_group==1) {
- $chat_identify = $to_user;
- } else if($is_group==0) {
- $chat_identify = chat_identify($this->userInfo['user_id'], $to_user);
- } else if($is_group==2){
- $chat_identify = $to_user;
- }
- $data=[
- 'action'=>'setIsRead',
- 'is_group'=>$is_group,
- 'to_user'=>$to_user,
- 'messages'=>$messages,
- 'user_id'=>$this->userInfo['user_id']
- ];
- queuePush($data,3);
- return $chat_identify;
- }
- // 聊天设置
- public function setting()
- {
- $param = $this->request->param();
- if ($param) {
- User::where(['user_id' => $this->userInfo['user_id']])->update(['setting' => $param]);
- return success('');
- }
- return warning('');
- }
- // 撤回消息
- public function undoMessage()
- {
- // echo Lang::getLangSet();
- // echo \think\facade\Lang::get('ok');
- // echo \think\facade\Lang::get('im.other');
- // die;
- // Lang::clear();
- // $setRes = Lang::setLangSet('en');
- // dump('设置语言是否成功:', $setRes); // 应返回 true
- // dump('当前语言标识:', Lang::getLangSet()); // 应返回 en
- // dump('已加载的语言文件:', Lang::getLoadFiles()); // 应包含 en.php 路径
- // dump('im.other 值:', Lang::get('im.other')); // 看实际返回值
- // die;
- $param = $this->request->param();
- $id = $param['id'];
- $message = Message::where(['id' => $id])->find();
- if ($message) {
- // 如果时间超过了2分钟也不能撤回
- $createTime=is_string($message['create_time']) ? strtotime($message['create_time']) : $message['create_time'];
- $redoTime=$this->globalConfig['chatInfo']['redoTime'] ?? 120;
- if ($this->userInfo['role'] == 0 && $this->globalConfig['user_cancel_message'] && $this->globalConfig['user_cancel_message']) {
- $redoTime=$this->globalConfig['user_cancel_message_time'] * 60;
- } elseif ($this->userInfo['role'] != 0 && $this->globalConfig['kefu_cancel_message']) {
- $redoTime=$this->globalConfig['kefu_cancel_message'] * 60;
- }
-
- if(time()-$createTime>$redoTime && $message['is_group']==0){
- return warning(lang('im.redoLimitTime',['time'=>floor($redoTime/60)]));
- }
- $text = lang('im.redo');
- $fromUserName = lang('im.other');
- $toContactId = $message['to_user'];
- if ($message['is_group'] == 1) {
- $fromUserName = $this->userInfo['realname'];
- $toContactId = explode('-', $message['chat_identify'])[1];
- // 如果是群聊消息撤回,需要判断是否是群主或者管理员,如果是则可以撤回
- if($message['from_user']!=$this->userInfo['user_id']){
- $groupUser=GroupUser::where(['user_id'=>$this->userInfo['user_id'],'group_id'=>$toContactId])->find();
- if(!$groupUser || !in_array($groupUser['role'],[1,2])){
- return warning(lang('system.notAuth'));
- }
- $text=lang('im.manageRedo');
- }
- }
- $message->content = str_encipher($text);
- $message->type = 'event';
- $message->is_undo = 1;
- //@的数据清空
- $message->at = '';
- $message->save();
- $info = $message->toArray();
- // $data = $info;
- $data['content'] = $fromUserName . $text;
- $data['sendTime'] = $createTime * 1000;
- $data['id'] = $info['id'];
- $data['from_user'] = $info['from_user'];
- $data['msg_id'] = $info['msg_id'];
- $data['status'] = $info['status'];
- $data['type'] = 'event';
- $data['is_last'] = $info['is_last'];
- $data['toContactId'] = $message['is_group'] == 1 ? $info['chat_identify'] : $toContactId;
- $data['isMobile'] = $this->request->isMobile() ? 1 : 0;
- wsSendMsg($toContactId, 'undoMessage', $data, $info['is_group']);
- if($info['is_group']==0){
- // 给自己也发一份推送,多端同步
- $data['content'] =lang('im.you'). $text;
- wsSendMsg($this->userInfo['user_id'], 'undoMessage', $data, $info['is_group']);
- }
- return success('');
- } else {
- return warning();
- }
- }
- // 删除消息
- public function removeMessage()
- {
- $param = $this->request->param();
- $id = $param['id'];
- $map = ['id' => $id];
- $message = Message::where($map)->find();
- if ($message) {
- $message->del_user = $this->userInfo['user_id'];
- if ($message['is_group'] == 1) {
- if ($message['del_user']) {
- $message->del_user .= ',' . $this->userInfo['user_id'];
- }
- } else {
- if ($message['del_user'] > 0) {
- $message->where($map)->delete();
- return success(lang('system.delOk'));
- }
- }
- $message->save();
- return success('');
- } else {
- return warning('');
- }
- }
- // 消息免打扰
- public function isNotice()
- {
- $param = $this->request->param();
- $user_id = $this->userInfo['user_id'];
- $id = $param['id'];
- if ($param['is_group'] == 1) {
- $group_id = explode('-', $param['id'])[1];
- GroupUser::update(['is_notice' => $param['is_notice']], ['user_id' => $user_id, 'group_id' => $group_id]);
- } else {
- $map = ['create_user' => $user_id, 'friend_user_id' => $id];
- $friend = Friend::where($map)->find();
- try {
- if ($friend) {
- $friend->is_notice = $param['is_notice'];
- $friend->save();
- } else {
- $info = [
- 'create_user' => $user_id,
- 'friend_user_id' => $id,
- 'is_notice' => $param['is_notice']
- ];
- Friend::create($info);
- }
- return success('');
- } catch (Exception $e) {
- return error($e->getMessage());
- }
- }
- wsSendMsg($user_id,"setIsNotice",['id'=>$id,'is_notice'=>$param['is_notice'],'is_group'=>$param['is_group']]);
- return success('');
- }
- // 设置聊天置顶
- public function setChatTop()
- {
- $param = $this->request->param();
- $user_id = $this->userInfo['user_id'];
- $is_group = $param['is_group'] ?: 0;
- $id = $param['id'];
-
- try {
- if ($is_group == 1) {
- $group_id = explode('-', $param['id'])[1];
- GroupUser::update(['is_top' => $param['is_top']], ['user_id' => $user_id, 'group_id' => $group_id]);
- } else {
- $map = ['create_user' => $user_id, 'friend_user_id' => $id];
- $friend = Friend::where($map)->find();
- if ($friend) {
- $friend->is_top = $param['is_top'];
- $friend->save();
- } else {
- $info = [
- 'create_user' => $user_id,
- 'friend_user_id' => $id,
- 'is_top' => $param['is_top']
- ];
- Friend::create($info);
- }
- }
- wsSendMsg($user_id,"setChatTop",['id'=>$id,'is_top'=>$param['is_top'],'is_group'=>$is_group]);
- return success('');
- } catch (Exception $e) {
- return error($e->getMessage());
- }
- }
-
- // 删除聊天
- public function delChat()
- {
- $param = $this->request->param();
- $user_id = $this->userInfo['user_id'];
- $is_group = $param['is_group'] ?: 0;
- $id = $param['id'];
- $data=[
- 'user_id'=>$user_id,
- 'is_group'=>$is_group,
- 'to_user'=>$id
- ];
- ChatDelog::create($data);
- ChatDelog::updateCache($user_id);
- return success('');
- }
- // 向用户发送消息
- public function sendToMsg(){
- $param=$this->request->param();
- $toContactId=$param['toContactId'];
-
- $type=$param['type'];
- $status=$param['status'];
- $event=$param['event'] ?? 'calling';
- if($event=='calling'){
- $status=3;
- }
- $sdp=$param['sdp'] ?? '';
- $iceCandidate=$param['iceCandidate'] ?? '';
- $callTime=$param['callTime'] ?? '';
- $msg_id=$param['msg_id'] ?? '';
- $id=$param['id'] ?? '';
- $code=($param['code'] ?? '') ?: 901;
- // 如果该用户不在线,则发送忙线
- Gateway::$registerAddress = config('gateway.registerAddress');
- if(!Gateway::isUidOnline($toContactId)){
- $toContactId=$this->userInfo['user_id'];
- $code=907;
- $event='busy';
- sleep(1);
- }
- switch($code){
- case 902:
- $content=lang('webRtc.cancel');
- break;
- case 903:
- $content=lang('webRtc.refuse');
- break;
- case 905:
- $content=lang('webRtc.notConnected');
- break;
- case 906:
- $content=lang('webRtc.duration',['time'=>date("i:s",$callTime)]);
- break;
- case 907:
- $content=lang('webRtc.busy');
- break;
- case 908:
- $content=lang('webRtc.other');
- break;
- default:
- $content=$type==1 ?lang('webRtc.video') : lang('webRtc.audio');
- break;
- }
- switch($event){
- case 'calling':
- $content=$type==1 ?lang('webRtc.video'): lang('webRtc.audio');
- break;
- case 'acceptRtc':
- $content=lang('webRtc.answer');
- break;
- case 'iceCandidate':
- $content=lang('webRtc.exchange');
- break;
- }
- $userInfo=$this->userInfo;
- $userInfo['id']=$userInfo['user_id'];
- $user = new User();
- $data=[
- 'id'=>$id,
- 'msg_id'=>$msg_id,
- 'sendTime'=>time()*1000,
- 'toContactId'=>$toContactId,
- 'content'=>$content,
- 'type'=>'webrtc',
- 'status'=>'succeed',
- 'is_group'=>0,
- 'is_read'=>0,
- 'fromUser'=>$userInfo,
- 'at'=>[],
- 'extends'=>[
- 'type'=>$type, //通话类型,1视频,0语音。
- 'status'=>$status, //,1拨打方,2接听方
- 'event'=>$event,
- 'callTime'=>$callTime,
- 'sdp'=>$sdp,
- 'code'=>$code, //通话状态:呼叫901,取消902,拒绝903,接听904,未接通905,接通后挂断906,忙线907,其他端操作908
- 'iceCandidate'=>$iceCandidate,
- 'isMobile'=>$this->request->isMobile() ? 1 : 0,
- ]
- ];
- if($event=='calling'){
- $chat_identify=chat_identify($userInfo['id'],$toContactId);
- $msg=[
- 'from_user'=>$userInfo['id'],
- 'to_user'=>$toContactId,
- 'id'=>$id,
- 'content'=>str_encipher($content),
- 'chat_identify'=>$chat_identify,
- 'create_time'=>time(),
- 'type'=>$data['type'],
- 'is_group'=>0,
- 'is_read'=>0,
- 'extends'=>$data['extends'],
- ];
- $message=new Message();
- $message->update(['is_last'=>0],['chat_identify'=>$chat_identify]);
- $message->save($msg);
- $msg_id=$message->msg_id;
- $data['msg_id']=$msg_id;
- // 将接收人设置为发送人才能定位到该消息
- $data['toContactId']=$userInfo['id'];
- $data['toUser']=$toContactId;
- }elseif($event=='hangup'){
- $message=Message::where(['id'=>$id])->find();
- if(!$message){
- return error(lang('webRtc.fail'));
- }
- if($message){
- $message->content=str_encipher($content);
- $extends=$message->extends;
- $extends['code']=$code;
- $extends['callTime']=$callTime;
- $message->extends=$extends;
- $message->save();
- }
- }
- wsSendMsg($toContactId,'webrtc',$data);
- $wsData=$data;
- if(in_array($event,['calling','acceptRtc','hangup'])){
- if(in_array($event,['acceptRtc','hangup'])){
- $data['extends']['event']='otherOpt'; //其他端操作
- }
- $data['toContactId']=$toContactId;
- $data['contactInfo']=$user->setContact($toContactId,0,'webrtc',$content) ? : [];
- wsSendMsg($userInfo['id'],'webrtc',$data);
- }
- return success('',$wsData);
- }
- // 修改密码
- public function editPassword()
- {
- if(env('app.demon_mode',false)){
- return warning(lang('system.demoMode'));
- }
-
- $user_id = $this->userInfo['user_id'];
- $user=User::find($user_id);
- if(!$user){
- return warning(lang('user.exist'));
- }
- $account=$user->account;
- $code=$this->request->param('code','');
- $originalPassword = $this->request->param('originalPassword', '');
- if($code){
- if(Cache::get($account)!=$code){
- return warning(lang('user.codeErr'));
- }
- }elseif($originalPassword){
- if(password_hash_tp($originalPassword,$user->salt)!= $user->password){
- return warning(lang('user.passErr'));
- }
- }else{
- return warning(lang('system.parameterError'));
- }
- try{
- $password = $this->request->param('password','');
- if($password){
- $salt=$user->salt;
- $user->password= password_hash_tp($password,$salt);
- }
- $user->save();
- return success(lang('system.editOk'));
- }catch (\Exception $e){
- return error(lang('system.editFail'));
- }
- }
- // 修改用户信息
- public function updateUserInfo(){
- try{
- $data = $this->request->param();
- $user=User::find($this->uid);
- if(!$user){
- return warning(lang('user.exist'));
- }
- // 接入用户名检测服务
- event('GreenText',['content'=>$data['realname'],'service'=>"nickname_detection"]);
- // 个性签名检测服务
- event('GreenText',['content'=>$data['motto'],'service'=>"comment_detection"]);
- $user->realname =$data['realname'];
- $user->email =$data['email'];
- $user->motto=$data['motto'];
- $user->sex =$data['sex'];
- $user->name_py= pinyin_sentence($data['realname']);
- $user->save();
- return success(lang('system.editOk'), $data);
- }catch (\Exception $e){
- return error($e->getMessage());
- }
- }
- // 修改账户
- public function editAccount(){
- if(env('app.demon_mode',false)){
- return warning(lang('system.demoMode'));
- }
- $code=$this->request->param('code','');
- $newCode=$this->request->param('newCode','');
- $account=$this->request->param('account','');
- $isUser=User::where('account',$account)->find();
- if($isUser){
- return warning(lang('user.already'));
- }
- $user=User::find($this->uid);
- if(!$user){
- return warning(lang('user.exist'));
- }
- // 如果已经认证过了,则需要验证验证码
- if($user->is_auth){
- if(Cache::get($user->account)!=$code){
- return warning(lang('user.codeErr'));
- }
- }
- if(Cache::get($account)!=$newCode){
- return warning(lang('user.newCodeErr'));
- }
- try{
- $user->account=$account;
- $user->is_auth=1;
- $user->save();
- return success(lang('system.editOk'));
- }catch (\Exception $e){
- return error(lang('system.editFail'));
- }
- }
- // 阅读@消息
- public function readAtMsg(){
- $param = $this->request->param();
- $atList=Db::name('message')->where(['chat_identify'=>$param['toContactId'],'is_group'=>1])->whereFindInSet('at',$this->userInfo['user_id'])->order('msg_id desc')->select();
- $atData=$this->recombileMsg($atList,false);
- Message::setAtRead($atData,$this->userInfo['user_id']);
- // $message=Message::where('msg_id',$param['msg_id'])->select();
- // $atList=($message ?? null) ? explode(',',$message): [];
- // // 两个数组取差集
- // $newAtList = array_diff($atList, [$this->userInfo['user_id']]);
- // Message::where('msg_id',$param['msg_id'])->update(['at'=>implode(',',$newAtList)]);
- return success('');
- }
- // 获取系统公告
- public function getAdminNotice(){
- $data=Message::where(['chat_identify'=>'admin_notice'])->order('msg_id desc')->find();
- $extends=$data['extends'] ?? [];
- if(!$extends){
- $extends['title']='';
- }
- $createTime=$data['create_time'] ?? 0;
- if(!$createTime){
- $extends['create_time']=$createTime;
- }else{
- $extends['create_time']=is_string($data['create_time']) ? strtotime($data['create_time']) : $data['create_time'];
- }
-
- return success('',$extends);
- }
- // 双向删除消息
- public function delMessage(){
- $param = $this->request->param();
- $id = $param['id'];
- // if(!$this->globalConfig['chatInfo']['dbDelMsg']){
- // return warning(lang('system.notAuth'));
- // }
- $message = Message::where(['id' => $id])->find();
- if ($message) {
- if($message['from_user']!=$this->userInfo['user_id']){
- return warning(lang('system.notAuth'));
- }
- Message::where(['id' => $id])->delete();
- // 如果是最后一条消息,需要将上一条设置为最后一条
- if($message['is_last']){
- Message::where(['chat_identify'=>$message['chat_identify']])->order('msg_id desc')->limit(1)->update(['is_last'=>1]);
- }
- $toContactId = $message['to_user'];
- if ($message['is_group'] == 1) {
- $toContactId = explode('-', $message['chat_identify'])[1];
- }
- wsSendMsg($toContactId, 'delMessage', $message, $message['is_group']);
- return success('');
- } else {
- return warning(lang('im.exist'));
- }
- }
- }
|