Im.php 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267
  1. <?php
  2. namespace app\enterprise\controller;
  3. use app\BaseController;
  4. use think\facade\Session;
  5. use think\facade\Db;
  6. use app\enterprise\model\{User, Message, GroupUser, Friend,Group,ChatDelog};
  7. use GatewayClient\Gateway;
  8. use Exception;
  9. use League\Flysystem\Util;
  10. use think\facade\Cache;
  11. use app\manage\model\{Config};
  12. use app\admin\model\GuessAskLanguages;
  13. use app\admin\model\QuestionLanguages;
  14. use app\admin\model\Complaint;
  15. use app\admin\model\ComplaintItem;
  16. use app\admin\model\Score;
  17. class Im extends BaseController
  18. {
  19. protected $fileType = ['file', 'image','video','voice','emoji'];
  20. /**
  21. * 给客服打分
  22. */
  23. public function Score()
  24. {
  25. $score = $this->request->param('score');
  26. $msg_id = $this->request->param('msg_id');
  27. if (empty($msg_id)) {
  28. return $this->error('参数有误');
  29. }
  30. if (empty($score)) {
  31. return $this->error('请打分');
  32. }
  33. $user_id = $this->userInfo['user_id'];
  34. $user = User::where('user_id', $user_id)->find();
  35. if (!$user) {
  36. return $this->error('用户不存在');
  37. }
  38. $exist = Message::where('msg_id', $msg_id)->where('to_user', $user_id)->find();
  39. if ($exist && $exist['is_click'] == 0) {
  40. Score::create([
  41. 'user_id' => $user_id,
  42. 'cs_uid' => $user->cs_uid,
  43. 'score' => (int)$score,
  44. ]);
  45. }
  46. return $this->success('提交成功');
  47. }
  48. /**
  49. */
  50. public function complaintList()
  51. {
  52. try {
  53. $params = $this->request->param();
  54. $page = $params['page'] ?? 1;
  55. $limit = $params['limit'] ?? 15;
  56. $language_code = $params['language_code'] ?? $this->lang;
  57. $query = ComplaintItem::where('language_code', $language_code);
  58. $count = $query->count();
  59. $list = $query->order('weight','desc')
  60. ->limit($limit)
  61. ->page($page)
  62. ->select();
  63. } catch (Exception $e) {
  64. return $this->error($e->getMessage());
  65. }
  66. return $this->success(['count' => $count, 'list' => $list]);
  67. }
  68. /**
  69. * 投诉客服
  70. */
  71. public function complaint()
  72. {
  73. $params = $this->request->param();
  74. if (empty($params['complaint_item_id'])) {
  75. return $this->error('请选择投诉项');
  76. }
  77. $user_id = $this->userInfo['user_id'];
  78. $user = User::where('user_id', $user_id)->find();
  79. if (!$user) {
  80. return $this->error('用户不存在');
  81. }
  82. $exist = Complaint::where('user_id', $user_id)->where('cs_uid', $user->cs_uid)->find();
  83. if ($exist) {
  84. return $this->error('您已投诉过该客服,无需重复投诉');
  85. }
  86. Complaint::create([
  87. 'user_id' => $user_id,
  88. 'cs_uid' => $user->cs_uid,
  89. 'complaint_item_id' => $params['complaint_item_id'],
  90. 'remark' => $params['remark'] ?? '',
  91. 'language_code' => $this->lang,
  92. ]);
  93. $data = $this->request->param();
  94. $data['user_id'] = $user['id'];
  95. $data['status'] = 0;
  96. $data['type'] = 1;
  97. Db::name('complaint')->insert($data);
  98. return $this->success('提交成功');
  99. }
  100. /**
  101. * 猜你想问列表
  102. */
  103. public function guessask()
  104. {
  105. try {
  106. $params = $this->request->param();
  107. $page = $params['page'] ?? 1;
  108. $limit = $params['limit'] ?? 15;
  109. $language_code = $this->lang;
  110. $query = GuessAskLanguages::where('language_code', $language_code)->where('status', 1);
  111. if (!empty($params['keyword'])) {
  112. $query = $query->where('name', 'like', '%'.$params['keyword'].'%');
  113. }
  114. if (isset($params['type']) && $params['type'] != '') {
  115. $query = $query->where('type', $params['type']);
  116. }
  117. $count = $query->count();
  118. $list = $query->order('is_top','desc')
  119. ->order('is_rec','desc')
  120. ->order('click_num','desc')
  121. ->limit($limit)
  122. ->page($page)
  123. ->select();
  124. } catch (Exception $e) {
  125. return $this->error($e->getMessage());
  126. }
  127. return $this->success([ 'count' => $count, 'list' => $list]);
  128. }
  129. /**
  130. * 猜你想问点击使用
  131. */
  132. function guessaskClick()
  133. {
  134. try {
  135. $id = $this->request->param('id');
  136. $info = GuessAskLanguages::where('id', $id)->where('status', 1)->find();
  137. if ($info) {
  138. $info->click_num = $info->click_num + 1;
  139. $info->save();
  140. }
  141. } catch (Exception $e) {
  142. return $this->error($e->getMessage());
  143. }
  144. return $this->success([]);
  145. }
  146. /**
  147. * 问题列表
  148. */
  149. function question()
  150. {
  151. try {
  152. $params = $this->request->param();
  153. $page = $params['page'] ?? 1;
  154. $limit = $params['limit'] ?? 15;
  155. $language_code = $this->lang;
  156. $query = QuestionLanguages::where('language_code', $language_code)->where('status', 1);
  157. if (isset($params['question_type']) && $params['question_type'] != '') {
  158. $query = $query->where('question_type', $params['question_type']);
  159. }
  160. $count = $query->count();
  161. $list = $query->order('weight','desc')
  162. ->limit($limit)
  163. ->page($page)
  164. ->select();
  165. } catch (Exception $e) {
  166. return error($e->getMessage());
  167. }
  168. return $this->success([ 'count' => $count, 'list' => $list]);
  169. }
  170. /**
  171. * 问题点赞、点否
  172. */
  173. function questionClick()
  174. {
  175. try {
  176. $is_like = $this->request->param('is_like');
  177. $msg_id = $this->request->param('msg_id');
  178. if (empty($msg_id) || !in_array($is_like, [1, 0])) {
  179. return $this->error('参数有误');
  180. }
  181. $user_id = $this->userInfo['user_id'];
  182. $exist = Message::where('msg_id', $msg_id)->where('to_user', $user_id)->find();
  183. if ($exist && $exist['is_click'] == 0) {
  184. $extends = $exist['extends'];
  185. $extends = json_decode($extends, true);
  186. $id = $extends['question_id'] ?? 0;
  187. if ($id) {
  188. $question = QuestionLanguages::where('id', $id)->find();
  189. if ($question) {
  190. if ($is_like == 1) {
  191. $question->like_count = $question->like_count + 1;
  192. } else {
  193. $question->dislike_count = $question->dislike_count + 1;
  194. }
  195. $question->save();
  196. }
  197. }
  198. }
  199. } catch (Exception $e) {
  200. return $this->error($e->getMessage());
  201. }
  202. return $this->success([]);
  203. }
  204. /**
  205. * 转人工客服
  206. */
  207. function transferHuman()
  208. {
  209. try {
  210. $user_id = $this->userInfo['user_id'];
  211. $user = User::where('user_id', $user_id)->find();
  212. if (!$user) {
  213. return $this->error('用户不存在');
  214. }
  215. if ($user->role > 0) {
  216. return $this->error('系统管理员无法转人工');
  217. }
  218. // ($user->service_status == -1) {
  219. $user->service_status = 0;
  220. $user->service_start = time();
  221. $user->cs_uid = 0;
  222. $user->save();
  223. //机器人客服
  224. $autoTask = Config::autoTask();
  225. $param = [
  226. 'id' => \utils\Str::getUuid(),
  227. 'type' => 'text',
  228. 'status' => 'going',
  229. 'sendTime' => time() * 1000,
  230. 'toContactId' => $user_id,
  231. 'content' => Config::where('field','transfer_to_human')->value('val'),
  232. 'file_id' => 0,
  233. 'is_group' => 0,
  234. 'user_id' => !empty($autoTask['user_id']) ? $autoTask['user_id'] : 1,
  235. ];
  236. Message::sendMsg($param, 0);
  237. //通知客服用户排队中
  238. wsSendMsg(0,'handleChat',['user_id'=>$user_id]);
  239. //
  240. } catch (Exception $e) {
  241. return $this->error($e->getMessage());
  242. }
  243. return $this->success([]);
  244. }
  245. // 获取联系人列表
  246. public function getContacts()
  247. {
  248. $data = User::getUserList([['status', '=', 1], ['user_id', '<>', $this->userInfo['user_id']]], $this->userInfo['user_id'] , '', $this->userInfo['role']);
  249. $count=Friend::where(['status'=>2,'friend_user_id'=>$this->uid])->count();
  250. $time=Friend::where(['friend_user_id'=>$this->uid,'is_invite'=>1])->order('create_time desc')->value('create_time');
  251. return success('', $data,$count,$time*1000);
  252. }
  253. // 获取聊天列表
  254. public function getChatList()
  255. {
  256. $data = User::getChatList($this->userInfo['user_id']);
  257. $count=Friend::where(['status'=>2,'friend_user_id'=>$this->uid])->count();
  258. $time=Friend::where(['friend_user_id'=>$this->uid,'is_invite'=>1])->order('create_time desc')->value('create_time');
  259. return success('', $data,$count,$time*1000);
  260. }
  261. // 获取好友列表
  262. public function getFriendList()
  263. {
  264. $data = User::getFriendList([['status', '=', 1], ['user_id', '<>', $this->userInfo['user_id']]],$this->userInfo['user_id']);
  265. return success('', $data);
  266. }
  267. // 获取群聊列表
  268. public function getGroupList()
  269. {
  270. $data = User::getGroupList($this->userInfo['user_id']);
  271. return success('', $data);
  272. }
  273. // 获取单个人员的信息
  274. public function getContactInfo(){
  275. $id = $this->request->param('id');
  276. $is_group = is_string($id) ? 1 : 0;
  277. $user=new User;
  278. $data=$user->setContact($id,$is_group);
  279. if(!$data){
  280. return warning($user->getError());
  281. }
  282. return success('',$data);
  283. }
  284. //发送消息
  285. public function sendMessage()
  286. {
  287. $param = $this->request->param();
  288. $param['user_id'] = $this->userInfo['user_id'];
  289. $message=new Message();
  290. $data = $message->sendMessage($param,$this->globalConfig);
  291. if ($data) {
  292. return success('', $data);
  293. } else {
  294. return warning($message->getError());
  295. }
  296. }
  297. //转发消息
  298. public function forwardMessage()
  299. {
  300. $param = $this->request->param();
  301. $userIds=$param['user_ids'] ?? [];
  302. if(!$userIds || count($userIds)>5){
  303. return warning(lang('im.forwardLimit',['count'=>5]));
  304. }
  305. $msg_id=$param['msg_id'] ?? 0;
  306. $message=Message::find($msg_id);
  307. if(!$message){
  308. return warning(lang('im.exist'));
  309. }
  310. $msg=$message->toArray();
  311. $userInfo=$this->userInfo;
  312. queuePush([
  313. 'action'=>'forwardMessage',
  314. 'message'=>$msg,
  315. 'user_ids'=>$userIds,
  316. 'config'=>$this->globalConfig,
  317. 'userInfo'=>$userInfo
  318. ]);
  319. return success(lang('im.forwardOk'));
  320. }
  321. // 获取用户信息
  322. public function getUserInfo()
  323. {
  324. $user_id = $this->request->param('user_id');
  325. $group_id = $this->request->param('group_id');
  326. $groupInfo=[];
  327. if($group_id){
  328. $group_id = explode('-', $group_id)[1];
  329. $groupInfo=Group::where(['group_id'=>$group_id])->find();
  330. if($groupInfo){
  331. // 查询操作对象的角色
  332. $groupInfo['userInfo']=GroupUser::where(['user_id'=>$user_id,'group_id'=>$group_id])->find() ?: [];
  333. // 查询我的角色
  334. $groupInfo['manageRole']=GroupUser::where(['user_id'=>$this->userInfo['user_id'],'group_id'=>$group_id])->value('role') ?: 3;
  335. }
  336. }
  337. $user=User::find($user_id);
  338. if(!$user){
  339. return error(lang('user.exist'));
  340. }
  341. $user->avatar=avatarUrl($user->avatar,$user->realname,$user->user_id,120);
  342. // 账号前面截取3位,后面截取两位,中间星号展示
  343. $user->account=substr($user->account, 0, 3).'******'.substr($user->account, -2, 2);
  344. // 查询好友关系
  345. $friend=Friend::where(['friend_user_id'=>$user_id,'create_user'=>$this->userInfo['user_id'],'status'=>1])->find();
  346. $user->friend=$friend ? : '';
  347. $location='';
  348. if($user->last_login_ip){
  349. $location=implode(" ", \Ip::find($user->last_login_ip));
  350. }
  351. $user->location=$location;
  352. $user->groupInfo=$groupInfo ? : [];
  353. $user->password='';
  354. $userModel=new User;
  355. $user->contactInfo=$userModel->setContact($user_id,0) ?? [];
  356. return success('', $user);
  357. }
  358. // 扫码登录,向客户端推送数据
  359. public function tokenLogin(){
  360. $param = $this->request->param();
  361. $token=$param['token'] ?? '';
  362. $client_id='';
  363. if($token){
  364. $client_id=authcode(urldecode($token),"DECODE", config('app.app_id'));
  365. if(!$client_id){
  366. return warning(lang('user.loginError'));
  367. }
  368. }else{
  369. return warning(lang('user.loginError'));
  370. }
  371. $userInfo=$this->userInfo;
  372. if(!$userInfo){
  373. return warning(lang('user.loginError'));
  374. }
  375. // 如果用户已经有设置
  376. $setting=$userInfo['setting'] ?: '';
  377. if($setting){
  378. $setting['hideMessageName']= $setting['hideMessageName']=='true' ? true : false;
  379. $setting['hideMessageTime']= $setting['hideMessageTime']=='true' ? true : false;
  380. $setting['avatarCricle']= $setting['avatarCricle']=='true' ? true : false;
  381. $setting['isVoice']= $setting['isVoice']=='true' ? true : false;
  382. $setting['sendKey']=(int)$setting['sendKey'];
  383. }
  384. $userInfo['setting']=$setting;
  385. Gateway::$registerAddress = config('gateway.registerAddress');
  386. //如果登录信息中含有client——id则自动进行绑定
  387. if($client_id){
  388. $user_id=$userInfo['user_id'];
  389. // 如果当前ID在线,将其他地方登陆挤兑下线
  390. if(Gateway::isUidOnline($user_id)){
  391. wsSendMsg($user_id,'offline',['id'=>$user_id,'client_id'=>$client_id,'isMobile'=>false]);
  392. }
  393. Gateway::bindUid($client_id, $user_id);
  394. // 查询团队,如果有团队则加入团队
  395. $group=Group::getMyGroup(['gu.user_id'=>$user_id,'gu.status'=>1]);
  396. if($group){
  397. $group=$group->toArray();
  398. $group_ids=arrayToString($group,'group_id',false);
  399. foreach($group_ids as $v){
  400. Gateway::joinGroup($client_id, $v);
  401. }
  402. }
  403. }
  404. $update=[
  405. 'last_login_time'=>time(),
  406. 'last_login_ip'=>$this->request->ip(),
  407. 'login_count'=>Db::raw('login_count+1')
  408. ];
  409. User::where('user_id',$userInfo['user_id'])->update($update);
  410. $authToken=User::refreshToken($userInfo,'web');
  411. $data=[
  412. 'sessionId'=>Session::getId(),
  413. 'authToken'=>$authToken,
  414. 'userInfo'=>$userInfo
  415. ];
  416. Gateway::sendToClient($client_id, json_encode(array(
  417. 'type' => 'tokenLogin',
  418. 'data' => $data,
  419. )));
  420. return success(lang('user.loginOk'),$data);
  421. }
  422. // 搜索用户
  423. public function searchUser(){
  424. $keywords=$this->request->param('keywords','');
  425. if(!$keywords){
  426. return success('',[]);
  427. }
  428. $map=['status'=>1,'account'=>$keywords];
  429. $list=User::where($map)->field(User::$defaultField)->where([['account','<>',$this->userInfo['account']]])->select()->toArray();
  430. if($list){
  431. $ids=array_column($list,'user_id');
  432. $friendList=Friend::getFriend([['create_user','=',$this->uid],['friend_user_id','in',$ids]]);
  433. foreach($list as $k=>$v){
  434. $list[$k]['avatar']=avatarUrl($v['avatar'],$v['realname'],$v['user_id'],120);
  435. $list[$k]['friend']=$friendList[$v['user_id']] ?? '';
  436. }
  437. }
  438. return success('', $list);
  439. }
  440. // 获取系统所有人员加搜索
  441. public function userList(){
  442. $keywords=$this->request->param('keywords','');
  443. $listRows=$this->request->param('limit',20);
  444. $page=$this->request->param('page',1);
  445. $map=['status'=>1];
  446. $field="user_id,realname,avatar";
  447. if(!$keywords){
  448. $list=User::where($map)->field($field)->order('user_id asc')->limit(20)->paginate(['list_rows'=>$listRows,'page'=>$page]);;
  449. if($list){
  450. $list=$list->toArray()['data'];
  451. }
  452. }else{
  453. $list=User::where($map)->field($field)->where([['account','<>',$this->userInfo['account']]])->whereLike('account|realname|name_py','%'.$keywords.'%')->select()->toArray();
  454. }
  455. if($list){
  456. foreach($list as $k=>$v){
  457. $list[$k]['avatar']=avatarUrl($v['avatar'],$v['realname'],$v['user_id'],120);
  458. $list[$k]['id']=$v['user_id'];
  459. }
  460. }
  461. return success('', $list);
  462. }
  463. // 获取聊天记录
  464. public function getMessageList()
  465. {
  466. $param = $this->request->param();
  467. $is_group = isset($param['is_group']) ? $param['is_group'] : 0;
  468. // 如果toContactId是数字,绝对是单聊
  469. $is_group = is_numeric($param['toContactId']) ? 0 : $is_group;
  470. // 设置当前聊天消息为已读
  471. $chat_identify = $this->setIsRead($is_group, $param['toContactId']);
  472. $type = isset($param['type']) ? $param['type'] : '';
  473. $is_at = isset($param['is_at']) ? $param['is_at'] : '';
  474. $map = ['chat_identify' => $chat_identify, 'status' => 1];
  475. $where = [];
  476. if ($type && $type != "all") {
  477. $map['type'] = $type;
  478. } else {
  479. if (isset($param['type'])) {
  480. $where[] = ['type', '<>', 'event'];
  481. }
  482. }
  483. $groupManage=[];
  484. // 群聊查询入群时间以后的消息
  485. if($is_group==1){
  486. $group_id = explode('-', $param['toContactId'])[1];
  487. $group=Group::where(['group_id'=> $group_id])->find();
  488. $groupManage=GroupUser::getGroupManage($group_id);
  489. if($group && $group['setting']){
  490. $groupSetting=json_decode($group['setting'],true);
  491. $history=$groupSetting['history'] ?? false;
  492. // 如果开启了历史记录才可以查看所有记录,否者根据进群时间查询记录
  493. if(!$history){
  494. $createTime=GroupUser::where(['group_id'=> $group_id,'user_id'=>$this->userInfo['user_id']])->value('create_time');
  495. $where[] = ['create_time', '>=', $createTime ? : 0];
  496. }
  497. }
  498. }
  499. $keywords = isset($param['keywords']) ? $param['keywords'] : '';
  500. if ($keywords && in_array($type, ['text', 'all'])) {
  501. $where[] = ['content', 'like', '%' . $keywords . '%'];
  502. }
  503. // 如果是查询@数据
  504. if($is_at){
  505. $atList=Db::name('message')->where($map)->where($where)->whereFindInSet('at',$this->userInfo['user_id'])->order('msg_id desc')->select()->toArray();
  506. if($atList){
  507. $data = $this->recombileMsg($atList,false);
  508. Message::setAtread($data,$this->userInfo['user_id']);
  509. return success('', $data, count($data));
  510. }else{
  511. return success('', [], 0);
  512. }
  513. }
  514. $listRows = $param['limit'] ?: 20;
  515. $pageSize = $param['page'] ?: 1;
  516. $last_id = $param['last_id'] ?? 0;
  517. if($last_id){
  518. $where[]=['msg_id','<',$last_id];
  519. $pageSize=1;
  520. }
  521. //判断是客服还是用户
  522. if ($this->userInfo['role'] == 0) {
  523. //用户可见历史记录的时长
  524. $hours = Config::where('field', 'user_show_message')->value('val');
  525. if ($hours > 0) {
  526. $start_time = time() - $hours * 60 * 60;
  527. $where[] = ['create_time', '>=', $start_time];
  528. }
  529. } elseif ($this->userInfo['role'] == 3) {
  530. //客服可见历史记录的时长
  531. $hours = Config::where('field', 'kefu_show_message')->value('val');
  532. if ($hours > 0) {
  533. $start_time = time() - $hours * 60 * 60;
  534. $where[] = ['create_time', '>=', $start_time];
  535. }
  536. $toUser = User::where('user_id', $param['toContactId'])->find();
  537. if ($toUser && $toUser->service_status == 1) {
  538. //将用户待处理的状态更新成服务中
  539. $toUser->service_status = 2;
  540. $toUser->service_time = time();
  541. $toUser->save();
  542. }
  543. }
  544. $list = Message::getList($map, $where, 'msg_id desc', $listRows, $pageSize);
  545. $data = $this->recombileMsg($list,true,$groupManage);
  546. // 如果是群聊并且是第一页消息,需要推送@数据给用户
  547. if($param['is_group']==1 && $param['page']==1){
  548. $isPush=Cache::get('atMsgPush'.$chat_identify) ?? '';
  549. $atList=Db::name('message')->where(['chat_identify'=>$chat_identify,'is_group'=>1])->whereFindInSet('at',$this->userInfo['user_id'])->order('msg_id desc')->select()->toArray();
  550. $msgIda=array_column($atList,'msg_id');
  551. // 如果两次推送at数据的列表不一样,则推送
  552. if($isPush!=json_encode($msgIda)){
  553. $atData=$this->recombileMsg($atList,false);
  554. wsSendMsg($this->userInfo['user_id'],'atMsgList',[
  555. 'list'=>$atData,
  556. 'count'=>count($atData),
  557. 'toContactId'=>$param['toContactId']
  558. ]);
  559. Cache::set('atMsgPush'.$chat_identify,json_encode($msgIda),60);
  560. }
  561. }
  562. // 如果是消息管理器则不用倒序
  563. if (!isset($param['type'])) {
  564. $data = array_reverse($data);
  565. }
  566. return success('', $data, $list->total());
  567. }
  568. // 获取单条消息详情
  569. public function getMessageInfo()
  570. {
  571. $param = $this->request->param();
  572. $id = $param['msg_id'] ?? 0;
  573. $message = Message::where(['msg_id' => $id])->find();
  574. if ($message) {
  575. $data = $this->recombileMsg([$message], false);
  576. return success('', $data);
  577. } else {
  578. return warning(lang('im.exist'));
  579. }
  580. }
  581. // 获取单条消息上下文
  582. public function getMessageContext()
  583. {
  584. $param = $this->request->param();
  585. $is_group = isset($param['is_group']) ? $param['is_group'] : 0;
  586. $id = $param['msg_id'] ?? 0;
  587. $direction = $param['direction'] ?? 0;
  588. $message = Message::where(['msg_id' => $id])->find();
  589. if (!$message) {
  590. return warning(lang('im.exist'));
  591. }
  592. $groupManage=[];
  593. $where = [];
  594. $map = ['chat_identify' => $message['chat_identify'], 'status' => 1];
  595. if($is_group==1 && $direction<2){
  596. $group_id = $message['to_user'];
  597. $group=Group::where(['group_id'=> $group_id])->find();
  598. $groupManage=GroupUser::getGroupManage($group_id);
  599. if($group && $group['setting']){
  600. $groupSetting=json_decode($group['setting'],true);
  601. $history=$groupSetting['history'] ?? false;
  602. // 如果开启了历史记录才可以查看所有记录,否者根据进群时间查询记录
  603. if(!$history){
  604. $createTime=GroupUser::where(['group_id'=> $group_id,'user_id'=>$this->userInfo['user_id']])->value('create_time');
  605. $where[] = ['create_time', '>=', $createTime ? : 0];
  606. }
  607. }
  608. }
  609. if($direction==0){
  610. $where[] = ['msg_id', '<', $id];
  611. $beforeList = Message::where($map)->where($where)->order('msg_id desc')->limit(5)->select()->toArray();
  612. $beforeList = array_reverse($beforeList);
  613. $where2 = [];
  614. $where2[] = ['msg_id', '>=', $id];
  615. $afterList = Message::where($map)->where($where2)->order('msg_id asc')->limit(5)->select()->toArray();
  616. $data = array_merge($beforeList, $afterList);
  617. }elseif($direction==1){
  618. $where[] = ['msg_id', '<', $id];
  619. $data = Message::where($map)->where($where)->order('msg_id desc')->limit(5)->select()->toArray();
  620. $data = array_reverse($data);
  621. }else{
  622. $where[] = ['msg_id', '>', $id];
  623. $data = Message::where($map)->where($where)->order('msg_id asc')->limit(5)->select()->toArray();
  624. }
  625. if($data){
  626. $data = $this->recombileMsg($data, false,$groupManage);
  627. }
  628. return success('', $data);
  629. }
  630. protected function recombileMsg($list,$isPagination=true,$manage=[])
  631. {
  632. $data = [];
  633. $userInfo = $this->userInfo;
  634. if ($list) {
  635. $listData = $isPagination ? $list->toArray()['data'] : $list;
  636. $userList = User::matchUser($listData, true, 'from_user', 120);
  637. foreach ($listData as $k => $v) {
  638. // 屏蔽已删除的消息
  639. if ($v['del_user']) {
  640. $delUser = explode(',', $v['del_user']);
  641. if (in_array($userInfo['user_id'], $delUser)) {
  642. unset($list[$k]);
  643. continue;
  644. // $v['type']="event";
  645. // $v['content']="删除了一条消息";
  646. }
  647. }
  648. $content = str_encipher($v['content'],false);
  649. $preview = '';
  650. $ext='';
  651. if (in_array($v['type'], $this->fileType)) {
  652. $content = getFileUrl($content);
  653. $preview = previewUrl($content);
  654. $ext=getExtUrl($content);
  655. }
  656. $fromUser = $userList[$v['from_user']];
  657. // 处理撤回的消息
  658. if ($v['type'] == "event" && $v['is_undo']==1) {
  659. if ($v['from_user'] == $userInfo['user_id']) {
  660. $content = lang('im.you'). $content;
  661. } elseif ($v['is_group'] == 1) {
  662. $content = $fromUser['realname'] . $content;
  663. } else {
  664. $content = lang('im.other') . $content;
  665. }
  666. }
  667. $toContactId=$v['is_group'] ==1 ? 'group-'.$v['to_user'] : $v['to_user'];
  668. $atList=($v['at'] ?? null) ? explode(',',$v['at']): [];
  669. $role=$manage[$v['from_user']] ?? 3;
  670. $data[] = [
  671. 'msg_id' => $v['msg_id'],
  672. 'id' => $v['id'],
  673. 'status' => "succeed",
  674. 'type' => $v['type'],
  675. 'sendTime' => (is_string($v['create_time']) ? strtotime($v['create_time']) : $v['create_time'])* 1000,
  676. 'content' => $content,
  677. 'preview' => $preview,
  678. 'download' => $v['file_id'] ? getMainHost().'/filedown/'.encryptIds($v['file_id']) : '',
  679. 'is_read' => $v['is_read'],
  680. 'is_group' => $v['is_group'],
  681. 'at' => $atList,
  682. 'toContactId' => $toContactId,
  683. 'from_user' => $v['from_user'],
  684. 'file_id' => $v['file_id'],
  685. 'file_cate' => $v['file_cate'],
  686. 'fileName' => $v['file_name'],
  687. 'fileSize' => $v['file_size'],
  688. 'is_click' => $v['is_click'],
  689. 'fromUser' => $fromUser,
  690. 'extUrl'=>$ext,
  691. 'role'=>$role,
  692. 'extends'=>is_string($v['extends'])?json_decode($v['extends'],true) : $v['extends']
  693. ];
  694. }
  695. }
  696. return $data;
  697. }
  698. // 设置当前窗口的消息默认为已读
  699. public function setMsgIsRead()
  700. {
  701. $param = $this->request->param();
  702. // 判断是否是一个二维数组
  703. if (is_array($param['messages'][0] ?? '')) {
  704. $messages=$param['messages'];
  705. } else {
  706. $messages=[$param['messages']];
  707. }
  708. $this->setIsRead($param['is_group'], $param['toContactId'],$messages);
  709. if (!$param['is_group']) {
  710. wsSendMsg($param['fromUser'], 'isRead', $messages, 0);
  711. }
  712. return success('');
  713. }
  714. // 设置全部为已读
  715. public function readAllMsg()
  716. {
  717. // 阅读所有单聊
  718. $map = ['to_user' => $this->userInfo['user_id'], 'is_read' => 0, 'is_group' => 0];
  719. Message::where($map)->update(['is_read' => 1]);
  720. // 阅读所有群聊
  721. GroupUser::where(['user_id' => $this->userInfo['user_id'], 'status' => 1])->update(['unread'=>0]);
  722. return success('');
  723. }
  724. // 设置消息已读
  725. protected function setIsRead($is_group, $to_user,$messages=[])
  726. {
  727. if ($is_group==1) {
  728. $chat_identify = $to_user;
  729. } else if($is_group==0) {
  730. $chat_identify = chat_identify($this->userInfo['user_id'], $to_user);
  731. } else if($is_group==2){
  732. $chat_identify = $to_user;
  733. }
  734. $data=[
  735. 'action'=>'setIsRead',
  736. 'is_group'=>$is_group,
  737. 'to_user'=>$to_user,
  738. 'messages'=>$messages,
  739. 'user_id'=>$this->userInfo['user_id']
  740. ];
  741. queuePush($data,3);
  742. return $chat_identify;
  743. }
  744. // 聊天设置
  745. public function setting()
  746. {
  747. $param = $this->request->param();
  748. if ($param) {
  749. User::where(['user_id' => $this->userInfo['user_id']])->update(['setting' => $param]);
  750. return success('');
  751. }
  752. return warning('');
  753. }
  754. // 撤回消息
  755. public function undoMessage()
  756. {
  757. $param = $this->request->param();
  758. $id = $param['id'];
  759. $message = Message::where(['id' => $id])->find();
  760. if ($message) {
  761. // 如果时间超过了2分钟也不能撤回
  762. $createTime=is_string($message['create_time']) ? strtotime($message['create_time']) : $message['create_time'];
  763. $redoTime=$this->globalConfig['chatInfo']['redoTime'] ?? 120;
  764. if ($this->userInfo['role'] == 0 && $this->globalConfig['user_cancel_message'] && $this->globalConfig['user_cancel_message']) {
  765. $redoTime=$this->globalConfig['user_cancel_message_time'] * 60;
  766. } elseif ($this->userInfo['role'] != 0 && $this->globalConfig['kefu_cancel_message']) {
  767. $redoTime=$this->globalConfig['kefu_cancel_message'] * 60;
  768. }
  769. if(time()-$createTime>$redoTime && $message['is_group']==0){
  770. return warning(lang('im.redoLimitTime',['time'=>floor($redoTime/60)]));
  771. }
  772. $text = lang('im.redo');
  773. $fromUserName = lang('im.other');
  774. $toContactId = $message['to_user'];
  775. if ($message['is_group'] == 1) {
  776. $fromUserName = $this->userInfo['realname'];
  777. $toContactId = explode('-', $message['chat_identify'])[1];
  778. // 如果是群聊消息撤回,需要判断是否是群主或者管理员,如果是则可以撤回
  779. if($message['from_user']!=$this->userInfo['user_id']){
  780. $groupUser=GroupUser::where(['user_id'=>$this->userInfo['user_id'],'group_id'=>$toContactId])->find();
  781. if(!$groupUser || !in_array($groupUser['role'],[1,2])){
  782. return warning(lang('system.notAuth'));
  783. }
  784. $text=lang('im.manageRedo');
  785. }
  786. }
  787. $message->content = str_encipher($text);
  788. $message->type = 'event';
  789. $message->is_undo = 1;
  790. //@的数据清空
  791. $message->at = '';
  792. $message->save();
  793. $info = $message->toArray();
  794. // $data = $info;
  795. $data['content'] = $fromUserName . $text;
  796. $data['sendTime'] = $createTime * 1000;
  797. $data['id'] = $info['id'];
  798. $data['from_user'] = $info['from_user'];
  799. $data['msg_id'] = $info['msg_id'];
  800. $data['status'] = $info['status'];
  801. $data['type'] = 'event';
  802. $data['is_last'] = $info['is_last'];
  803. $data['toContactId'] = $message['is_group'] == 1 ? $info['chat_identify'] : $toContactId;
  804. $data['isMobile'] = $this->request->isMobile() ? 1 : 0;
  805. wsSendMsg($toContactId, 'undoMessage', $data, $info['is_group']);
  806. if($info['is_group']==0){
  807. // 给自己也发一份推送,多端同步
  808. $data['content'] =lang('im.you'). $text;
  809. wsSendMsg($this->userInfo['user_id'], 'undoMessage', $data, $info['is_group']);
  810. }
  811. return success('');
  812. } else {
  813. return warning();
  814. }
  815. }
  816. // 删除消息
  817. public function removeMessage()
  818. {
  819. $param = $this->request->param();
  820. $id = $param['id'];
  821. $map = ['id' => $id];
  822. $message = Message::where($map)->find();
  823. if ($message) {
  824. $message->del_user = $this->userInfo['user_id'];
  825. if ($message['is_group'] == 1) {
  826. if ($message['del_user']) {
  827. $message->del_user .= ',' . $this->userInfo['user_id'];
  828. }
  829. } else {
  830. if ($message['del_user'] > 0) {
  831. $message->where($map)->delete();
  832. return success(lang('system.delOk'));
  833. }
  834. }
  835. $message->save();
  836. return success('');
  837. } else {
  838. return warning('');
  839. }
  840. }
  841. // 消息免打扰
  842. public function isNotice()
  843. {
  844. $param = $this->request->param();
  845. $user_id = $this->userInfo['user_id'];
  846. $id = $param['id'];
  847. if ($param['is_group'] == 1) {
  848. $group_id = explode('-', $param['id'])[1];
  849. GroupUser::update(['is_notice' => $param['is_notice']], ['user_id' => $user_id, 'group_id' => $group_id]);
  850. } else {
  851. $map = ['create_user' => $user_id, 'friend_user_id' => $id];
  852. $friend = Friend::where($map)->find();
  853. try {
  854. if ($friend) {
  855. $friend->is_notice = $param['is_notice'];
  856. $friend->save();
  857. } else {
  858. $info = [
  859. 'create_user' => $user_id,
  860. 'friend_user_id' => $id,
  861. 'is_notice' => $param['is_notice']
  862. ];
  863. Friend::create($info);
  864. }
  865. return success('');
  866. } catch (Exception $e) {
  867. return error($e->getMessage());
  868. }
  869. }
  870. wsSendMsg($user_id,"setIsNotice",['id'=>$id,'is_notice'=>$param['is_notice'],'is_group'=>$param['is_group']]);
  871. return success('');
  872. }
  873. // 设置聊天置顶
  874. public function setChatTop()
  875. {
  876. $param = $this->request->param();
  877. $user_id = $this->userInfo['user_id'];
  878. $is_group = $param['is_group'] ?: 0;
  879. $id = $param['id'];
  880. try {
  881. if ($is_group == 1) {
  882. $group_id = explode('-', $param['id'])[1];
  883. GroupUser::update(['is_top' => $param['is_top']], ['user_id' => $user_id, 'group_id' => $group_id]);
  884. } else {
  885. $map = ['create_user' => $user_id, 'friend_user_id' => $id];
  886. $friend = Friend::where($map)->find();
  887. if ($friend) {
  888. $friend->is_top = $param['is_top'];
  889. $friend->save();
  890. } else {
  891. $info = [
  892. 'create_user' => $user_id,
  893. 'friend_user_id' => $id,
  894. 'is_top' => $param['is_top']
  895. ];
  896. Friend::create($info);
  897. }
  898. }
  899. wsSendMsg($user_id,"setChatTop",['id'=>$id,'is_top'=>$param['is_top'],'is_group'=>$is_group]);
  900. return success('');
  901. } catch (Exception $e) {
  902. return error($e->getMessage());
  903. }
  904. }
  905. // 删除聊天
  906. public function delChat()
  907. {
  908. $param = $this->request->param();
  909. $user_id = $this->userInfo['user_id'];
  910. $is_group = $param['is_group'] ?: 0;
  911. $id = $param['id'];
  912. $data=[
  913. 'user_id'=>$user_id,
  914. 'is_group'=>$is_group,
  915. 'to_user'=>$id
  916. ];
  917. ChatDelog::create($data);
  918. ChatDelog::updateCache($user_id);
  919. return success('');
  920. }
  921. // 向用户发送消息
  922. public function sendToMsg(){
  923. $param=$this->request->param();
  924. $toContactId=$param['toContactId'];
  925. $type=$param['type'];
  926. $status=$param['status'];
  927. $event=$param['event'] ?? 'calling';
  928. if($event=='calling'){
  929. $status=3;
  930. }
  931. $sdp=$param['sdp'] ?? '';
  932. $iceCandidate=$param['iceCandidate'] ?? '';
  933. $callTime=$param['callTime'] ?? '';
  934. $msg_id=$param['msg_id'] ?? '';
  935. $id=$param['id'] ?? '';
  936. $code=($param['code'] ?? '') ?: 901;
  937. // 如果该用户不在线,则发送忙线
  938. Gateway::$registerAddress = config('gateway.registerAddress');
  939. if(!Gateway::isUidOnline($toContactId)){
  940. $toContactId=$this->userInfo['user_id'];
  941. $code=907;
  942. $event='busy';
  943. sleep(1);
  944. }
  945. switch($code){
  946. case 902:
  947. $content=lang('webRtc.cancel');
  948. break;
  949. case 903:
  950. $content=lang('webRtc.refuse');
  951. break;
  952. case 905:
  953. $content=lang('webRtc.notConnected');
  954. break;
  955. case 906:
  956. $content=lang('webRtc.duration',['time'=>date("i:s",$callTime)]);
  957. break;
  958. case 907:
  959. $content=lang('webRtc.busy');
  960. break;
  961. case 908:
  962. $content=lang('webRtc.other');
  963. break;
  964. default:
  965. $content=$type==1 ?lang('webRtc.video') : lang('webRtc.audio');
  966. break;
  967. }
  968. switch($event){
  969. case 'calling':
  970. $content=$type==1 ?lang('webRtc.video'): lang('webRtc.audio');
  971. break;
  972. case 'acceptRtc':
  973. $content=lang('webRtc.answer');
  974. break;
  975. case 'iceCandidate':
  976. $content=lang('webRtc.exchange');
  977. break;
  978. }
  979. $userInfo=$this->userInfo;
  980. $userInfo['id']=$userInfo['user_id'];
  981. $user = new User();
  982. $data=[
  983. 'id'=>$id,
  984. 'msg_id'=>$msg_id,
  985. 'sendTime'=>time()*1000,
  986. 'toContactId'=>$toContactId,
  987. 'content'=>$content,
  988. 'type'=>'webrtc',
  989. 'status'=>'succeed',
  990. 'is_group'=>0,
  991. 'is_read'=>0,
  992. 'fromUser'=>$userInfo,
  993. 'at'=>[],
  994. 'extends'=>[
  995. 'type'=>$type, //通话类型,1视频,0语音。
  996. 'status'=>$status, //,1拨打方,2接听方
  997. 'event'=>$event,
  998. 'callTime'=>$callTime,
  999. 'sdp'=>$sdp,
  1000. 'code'=>$code, //通话状态:呼叫901,取消902,拒绝903,接听904,未接通905,接通后挂断906,忙线907,其他端操作908
  1001. 'iceCandidate'=>$iceCandidate,
  1002. 'isMobile'=>$this->request->isMobile() ? 1 : 0,
  1003. ]
  1004. ];
  1005. if($event=='calling'){
  1006. $chat_identify=chat_identify($userInfo['id'],$toContactId);
  1007. $msg=[
  1008. 'from_user'=>$userInfo['id'],
  1009. 'to_user'=>$toContactId,
  1010. 'id'=>$id,
  1011. 'content'=>str_encipher($content),
  1012. 'chat_identify'=>$chat_identify,
  1013. 'create_time'=>time(),
  1014. 'type'=>$data['type'],
  1015. 'is_group'=>0,
  1016. 'is_read'=>0,
  1017. 'extends'=>$data['extends'],
  1018. ];
  1019. $message=new Message();
  1020. $message->update(['is_last'=>0],['chat_identify'=>$chat_identify]);
  1021. $message->save($msg);
  1022. $msg_id=$message->msg_id;
  1023. $data['msg_id']=$msg_id;
  1024. // 将接收人设置为发送人才能定位到该消息
  1025. $data['toContactId']=$userInfo['id'];
  1026. $data['toUser']=$toContactId;
  1027. }elseif($event=='hangup'){
  1028. $message=Message::where(['id'=>$id])->find();
  1029. if(!$message){
  1030. return error(lang('webRtc.fail'));
  1031. }
  1032. if($message){
  1033. $message->content=str_encipher($content);
  1034. $extends=$message->extends;
  1035. $extends['code']=$code;
  1036. $extends['callTime']=$callTime;
  1037. $message->extends=$extends;
  1038. $message->save();
  1039. }
  1040. }
  1041. wsSendMsg($toContactId,'webrtc',$data);
  1042. $wsData=$data;
  1043. if(in_array($event,['calling','acceptRtc','hangup'])){
  1044. if(in_array($event,['acceptRtc','hangup'])){
  1045. $data['extends']['event']='otherOpt'; //其他端操作
  1046. }
  1047. $data['toContactId']=$toContactId;
  1048. $data['contactInfo']=$user->setContact($toContactId,0,'webrtc',$content) ? : [];
  1049. wsSendMsg($userInfo['id'],'webrtc',$data);
  1050. }
  1051. return success('',$wsData);
  1052. }
  1053. // 修改密码
  1054. public function editPassword()
  1055. {
  1056. if(env('app.demon_mode',false)){
  1057. return warning(lang('system.demoMode'));
  1058. }
  1059. $user_id = $this->userInfo['user_id'];
  1060. $user=User::find($user_id);
  1061. if(!$user){
  1062. return warning(lang('user.exist'));
  1063. }
  1064. $account=$user->account;
  1065. $code=$this->request->param('code','');
  1066. $originalPassword = $this->request->param('originalPassword', '');
  1067. if($code){
  1068. if(Cache::get($account)!=$code){
  1069. return warning(lang('user.codeErr'));
  1070. }
  1071. }elseif($originalPassword){
  1072. if(password_hash_tp($originalPassword,$user->salt)!= $user->password){
  1073. return warning(lang('user.passErr'));
  1074. }
  1075. }else{
  1076. return warning(lang('system.parameterError'));
  1077. }
  1078. try{
  1079. $password = $this->request->param('password','');
  1080. if($password){
  1081. $salt=$user->salt;
  1082. $user->password= password_hash_tp($password,$salt);
  1083. }
  1084. $user->save();
  1085. return success(lang('system.editOk'));
  1086. }catch (\Exception $e){
  1087. return error(lang('system.editFail'));
  1088. }
  1089. }
  1090. // 修改用户信息
  1091. public function updateUserInfo(){
  1092. try{
  1093. $data = $this->request->param();
  1094. $user=User::find($this->uid);
  1095. if(!$user){
  1096. return warning(lang('user.exist'));
  1097. }
  1098. // 接入用户名检测服务
  1099. event('GreenText',['content'=>$data['realname'],'service'=>"nickname_detection"]);
  1100. // 个性签名检测服务
  1101. event('GreenText',['content'=>$data['motto'],'service'=>"comment_detection"]);
  1102. $user->realname =$data['realname'];
  1103. $user->email =$data['email'];
  1104. $user->motto=$data['motto'];
  1105. $user->sex =$data['sex'];
  1106. $user->name_py= pinyin_sentence($data['realname']);
  1107. $user->save();
  1108. return success(lang('system.editOk'), $data);
  1109. }catch (\Exception $e){
  1110. return error($e->getMessage());
  1111. }
  1112. }
  1113. // 修改账户
  1114. public function editAccount(){
  1115. if(env('app.demon_mode',false)){
  1116. return warning(lang('system.demoMode'));
  1117. }
  1118. $code=$this->request->param('code','');
  1119. $newCode=$this->request->param('newCode','');
  1120. $account=$this->request->param('account','');
  1121. $isUser=User::where('account',$account)->find();
  1122. if($isUser){
  1123. return warning(lang('user.already'));
  1124. }
  1125. $user=User::find($this->uid);
  1126. if(!$user){
  1127. return warning(lang('user.exist'));
  1128. }
  1129. // 如果已经认证过了,则需要验证验证码
  1130. if($user->is_auth){
  1131. if(Cache::get($user->account)!=$code){
  1132. return warning(lang('user.codeErr'));
  1133. }
  1134. }
  1135. if(Cache::get($account)!=$newCode){
  1136. return warning(lang('user.newCodeErr'));
  1137. }
  1138. try{
  1139. $user->account=$account;
  1140. $user->is_auth=1;
  1141. $user->save();
  1142. return success(lang('system.editOk'));
  1143. }catch (\Exception $e){
  1144. return error(lang('system.editFail'));
  1145. }
  1146. }
  1147. // 阅读@消息
  1148. public function readAtMsg(){
  1149. $param = $this->request->param();
  1150. $atList=Db::name('message')->where(['chat_identify'=>$param['toContactId'],'is_group'=>1])->whereFindInSet('at',$this->userInfo['user_id'])->order('msg_id desc')->select();
  1151. $atData=$this->recombileMsg($atList,false);
  1152. Message::setAtRead($atData,$this->userInfo['user_id']);
  1153. // $message=Message::where('msg_id',$param['msg_id'])->select();
  1154. // $atList=($message ?? null) ? explode(',',$message): [];
  1155. // // 两个数组取差集
  1156. // $newAtList = array_diff($atList, [$this->userInfo['user_id']]);
  1157. // Message::where('msg_id',$param['msg_id'])->update(['at'=>implode(',',$newAtList)]);
  1158. return success('');
  1159. }
  1160. // 获取系统公告
  1161. public function getAdminNotice(){
  1162. $data=Message::where(['chat_identify'=>'admin_notice'])->order('msg_id desc')->find();
  1163. $extends=$data['extends'] ?? [];
  1164. if(!$extends){
  1165. $extends['title']='';
  1166. }
  1167. $createTime=$data['create_time'] ?? 0;
  1168. if(!$createTime){
  1169. $extends['create_time']=$createTime;
  1170. }else{
  1171. $extends['create_time']=is_string($data['create_time']) ? strtotime($data['create_time']) : $data['create_time'];
  1172. }
  1173. return success('',$extends);
  1174. }
  1175. // 双向删除消息
  1176. public function delMessage(){
  1177. $param = $this->request->param();
  1178. $id = $param['id'];
  1179. if(!$this->globalConfig['chatInfo']['dbDelMsg']){
  1180. return warning(lang('system.notAuth'));
  1181. }
  1182. $message = Message::where(['id' => $id])->find();
  1183. if ($message) {
  1184. if($message['from_user']!=$this->userInfo['user_id']){
  1185. return warning(lang('system.notAuth'));
  1186. }
  1187. Message::where(['id' => $id])->delete();
  1188. // 如果是最后一条消息,需要将上一条设置为最后一条
  1189. if($message['is_last']){
  1190. Message::where(['chat_identify'=>$message['chat_identify']])->order('msg_id desc')->limit(1)->update(['is_last'=>1]);
  1191. }
  1192. $toContactId = $message['to_user'];
  1193. if ($message['is_group'] == 1) {
  1194. $toContactId = explode('-', $message['chat_identify'])[1];
  1195. }
  1196. wsSendMsg($toContactId, 'delMessage', $message, $message['is_group']);
  1197. return success('');
  1198. } else {
  1199. return warning(lang('im.exist'));
  1200. }
  1201. }
  1202. }