Im.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747
  1. <?php
  2. namespace app\enterprise\controller;
  3. use app\BaseController;
  4. use think\facade\Request;
  5. use think\facade\Db;
  6. use app\enterprise\model\{User, Message, GroupUser, Friend};
  7. use GatewayClient\Gateway;
  8. use Exception;
  9. use League\Flysystem\Util;
  10. use think\facade\Cache;
  11. class Im extends BaseController
  12. {
  13. protected $fileType = ['file', 'image','video','voice'];
  14. // 获取联系人列表
  15. public function getContacts()
  16. {
  17. $data = User::getUserList([['status', '=', 1], ['user_id', '<>', $this->userInfo['user_id']]], $this->userInfo['user_id']);
  18. $count=Friend::where(['status'=>2,'friend_user_id'=>$this->uid])->count();
  19. $time=Friend::where(['friend_user_id'=>$this->uid,'is_invite'=>1])->order('create_time desc')->value('create_time');
  20. return success('', $data,$count,$time*1000);
  21. }
  22. //发送消息
  23. public function sendMessage()
  24. {
  25. $param = $this->request->param();
  26. $param['user_id'] = $this->userInfo['user_id'];
  27. $is_group=$param['is_group']??0;
  28. $chatSetting=$this->chatSetting;
  29. if($is_group==0 && $chatSetting['simpleChat']==0){
  30. return warning('目前禁止用户私聊!');
  31. }
  32. // 如果是单聊,并且是社区模式,需要判断是否是好友
  33. if($is_group==0 && $this->globalConfig['sysInfo']['runMode']==2){
  34. $friend=Friend::where(['friend_user_id'=>$this->uid,'create_user'=>$param['toContactId']])->find();
  35. if(!$friend){
  36. return warning('您不在TA的好友列表,不能发消息!');
  37. }
  38. $otherFriend=Friend::where(['friend_user_id'=>$param['toContactId'],'create_user'=>$this->uid])->find();
  39. if(!$otherFriend){
  40. return warning('TA还不是您的好友,不能发消息!');
  41. }
  42. }
  43. $data = Message::sendMessage($param);
  44. if ($data) {
  45. return success('', $data);
  46. } else {
  47. return error('发送失败');
  48. }
  49. }
  50. //转发消息
  51. public function forwardMessage()
  52. {
  53. $param = $this->request->param();
  54. $userIds=$param['user_ids'] ?? [];
  55. if(!$userIds || count($userIds)>5){
  56. return warning('请选择转发的用户或者数量不操作5个!');
  57. }
  58. $msg_id=$param['msg_id'] ?? 0;
  59. $message=Message::find($msg_id);
  60. if(!$message){
  61. return warning('消息不存在');
  62. }
  63. $message=$message->toArray();
  64. $userInfo=$this->userInfo;
  65. try{
  66. $is_group=0;
  67. $error=0;
  68. $chatSetting=$this->chatSetting;
  69. foreach($userIds as $k=>$v){
  70. $msgInfo=$message;
  71. if(strpos($v,'group')!==false){
  72. $is_group=1;
  73. }else{
  74. $is_group=0;
  75. }
  76. if($is_group==0 && $chatSetting['simpleChat']==0){
  77. $error++;
  78. continue;
  79. }
  80. $msgInfo['id']=\utils\Str::getUuid();
  81. $msgInfo['status']='successd';
  82. $msgInfo['user_id']=$userInfo['user_id'];
  83. $msgInfo['sendTime']=time()*1000;
  84. $msgInfo['toContactId']=$v;
  85. $msgInfo['content']=str_encipher($msgInfo['content'],false);
  86. $msgInfo['fromUser']=[
  87. 'id'=>$userInfo['user_id'],
  88. 'avatar'=>avatarUrl($userInfo['avatar'],$userInfo['realname'],$userInfo['user_id'],120),
  89. 'displayName'=>$userInfo['realname']
  90. ];
  91. $msgInfo['is_group']=$is_group;
  92. // 如果是单聊,并且是社区模式,需要判断是否是好友
  93. if($is_group==0 && $this->globalConfig['sysInfo']['runMode']==2){
  94. $friend=Friend::where(['friend_user_id'=>$this->uid,'create_user'=>$v])->find();
  95. if(!$friend){
  96. $error++;
  97. continue;
  98. }
  99. $otherFriend=Friend::where(['friend_user_id'=>$v,'create_user'=>$this->uid])->find();
  100. if(!$otherFriend){
  101. $error++;
  102. continue;
  103. }
  104. }
  105. Message::sendMessage($msgInfo);
  106. }
  107. }catch(\Exception $e){
  108. return error($e->getMessage());
  109. }
  110. if ($error) {
  111. $text='由于规则限制,转发失败'.$error.'条';
  112. } else {
  113. $text='转发成功';
  114. }
  115. return success($text);
  116. }
  117. // 获取用户信息
  118. public function getUserInfo()
  119. {
  120. $user_id = $this->request->param('user_id');
  121. $user=User::find($user_id);
  122. if(!$user){
  123. return error('用户不存在');
  124. }
  125. $user->avatar=avatarUrl($user->avatar,$user->realname,$user->user_id,120);
  126. // 查询好友关系
  127. $friend=Friend::where(['friend_user_id'=>$user_id,'create_user'=>$this->userInfo['user_id']])->find();
  128. $user->friend=$friend ? : '';
  129. $location='';
  130. if($user->last_login_ip){
  131. $location=implode(" ", \Ip::find($user->last_login_ip));
  132. }
  133. $user->location=$location;
  134. $user->password='';
  135. return success('', $user);
  136. }
  137. // 搜索用户
  138. public function searchUser(){
  139. $keywords=$this->request->param('keywords','');
  140. if(!$keywords){
  141. return success('',[]);
  142. }
  143. $map=['status'=>1,'account'=>$keywords];
  144. $list=User::where($map)->field(User::$defaultField)->where([['account','<>',$this->userInfo['account']]])->select()->toArray();
  145. if($list){
  146. $ids=array_column($list,'user_id');
  147. $friendList=Friend::getFriend([['create_user','=',$this->uid],['friend_user_id','in',$ids]]);
  148. foreach($list as $k=>$v){
  149. $list[$k]['avatar']=avatarUrl($v['avatar'],$v['realname'],$v['user_id'],120);
  150. $list[$k]['friend']=$friendList[$v['user_id']] ?? '';
  151. }
  152. }
  153. return success('', $list);
  154. }
  155. // 获取聊天记录
  156. public function getMessageList()
  157. {
  158. $param = $this->request->param();
  159. $is_group = isset($param['is_group']) ? $param['is_group'] : 0;
  160. // 设置当前聊天消息为已读
  161. $chat_identify = $this->setIsRead($is_group, $param['toContactId']);
  162. $type = isset($param['type']) ? $param['type'] : '';
  163. $is_at = isset($param['is_at']) ? $param['is_at'] : '';
  164. $map = ['chat_identify' => $chat_identify, 'status' => 1, 'is_group' => $is_group];
  165. $where = [];
  166. if ($type && $type != "all") {
  167. $map['type'] = $type;
  168. } else {
  169. if (isset($param['type'])) {
  170. $where[] = ['type', '<>', 'event'];
  171. }
  172. }
  173. $keywords = isset($param['keywords']) ? $param['keywords'] : '';
  174. if ($keywords && in_array($type, ['text', 'all'])) {
  175. $where[] = ['content', 'like', '%' . $keywords . '%'];
  176. }
  177. // 如果是查询@数据
  178. if($is_at){
  179. $atList=Db::name('message')->where($map)->where($where)->whereFindInSet('at',$this->userInfo['user_id'])->order('msg_id desc')->select()->toArray();
  180. if($atList){
  181. $data = $this->recombileMsg($atList,false);
  182. Message::setAtread($data,$this->userInfo['user_id']);
  183. return success('', $data, count($data));
  184. }else{
  185. return success('', [], 0);
  186. }
  187. }
  188. $listRows = $param['limit'] ?: 20;
  189. $pageSize = $param['page'] ?: 1;
  190. $last_id = $param['last_id'] ?? 0;
  191. if($last_id){
  192. $where[]=['msg_id','<',$last_id];
  193. }
  194. $list = Message::getList($map, $where, 'msg_id desc', $listRows, $pageSize);
  195. $data = $this->recombileMsg($list);
  196. // 如果是群聊并且是第一页消息,需要推送@数据给用户
  197. if($param['is_group']==1 && $param['page']==1){
  198. $isPush=Cache::get('atMsgPush'.$chat_identify) ?? '';
  199. $atList=Db::name('message')->where(['chat_identify'=>$chat_identify,'is_group'=>1])->whereFindInSet('at',$this->userInfo['user_id'])->order('msg_id desc')->select()->toArray();
  200. $msgIda=array_column($atList,'msg_id');
  201. // 如果两次推送at数据的列表不一样,则推送
  202. if($isPush!=json_encode($msgIda)){
  203. $atData=$this->recombileMsg($atList,false);
  204. wsSendMsg($this->userInfo['user_id'],'atMsgList',[
  205. 'list'=>$atData,
  206. 'count'=>count($atData),
  207. 'toContactId'=>$param['toContactId']
  208. ]);
  209. Cache::set('atMsgPush'.$chat_identify,json_encode($msgIda),60);
  210. }
  211. }
  212. // 如果是消息管理器则不用倒序
  213. if (!isset($param['type'])) {
  214. $data = array_reverse($data);
  215. }
  216. return success('', $data, $list->total());
  217. }
  218. protected function recombileMsg($list,$isPagination=true)
  219. {
  220. $data = [];
  221. $userInfo = $this->userInfo;
  222. if ($list) {
  223. $listData = $isPagination ? $list->toArray()['data'] : $list;
  224. $userList = User::matchUser($listData, true, 'from_user', 120);
  225. foreach ($listData as $k => $v) {
  226. // 屏蔽已删除的消息
  227. if ($v['del_user']) {
  228. $delUser = explode(',', $v['del_user']);
  229. if (in_array($userInfo['user_id'], $delUser)) {
  230. unset($list[$k]);
  231. continue;
  232. // $v['type']="event";
  233. // $v['content']="删除了一条消息";
  234. }
  235. }
  236. $content = str_encipher($v['content'],false);
  237. $preview = '';
  238. $ext='';
  239. if (in_array($v['type'], $this->fileType)) {
  240. $content = getFileUrl($content);
  241. $preview = previewUrl($content);
  242. $ext=getExtUrl($content);
  243. }
  244. $fromUser = $userList[$v['from_user']];
  245. // 处理撤回的消息
  246. if ($v['type'] == "event") {
  247. if ($v['from_user'] == $userInfo['user_id']) {
  248. $content = "你" . $content;
  249. } elseif ($v['is_group'] == 1) {
  250. $content = $fromUser['realname'] . $content;
  251. } else {
  252. $content = "对方" . $content;
  253. }
  254. }
  255. $toContactId=$v['is_group'] ==1 ? 'group-'.$v['to_user'] : $v['to_user'];
  256. $atList=($v['at'] ?? null) ? explode(',',$v['at']): [];
  257. $data[] = [
  258. 'msg_id' => $v['msg_id'],
  259. 'id' => $v['id'],
  260. 'status' => "succeed",
  261. 'type' => $v['type'],
  262. 'sendTime' => $v['create_time'] * 1000,
  263. 'content' => $content,
  264. 'preview' => $preview,
  265. 'download' => $v['file_id'] ? request()->domain().'/filedown/'.encryptIds($v['file_id']) : '',
  266. 'is_read' => $v['is_read'],
  267. 'is_group' => $v['is_group'],
  268. 'at' => $atList,
  269. 'toContactId' => $toContactId,
  270. 'from_user' => $v['from_user'],
  271. 'file_id' => $v['file_id'],
  272. 'file_cate' => $v['file_cate'],
  273. 'fileName' => $v['file_name'],
  274. 'fileSize' => $v['file_size'],
  275. 'fromUser' => $fromUser,
  276. 'extUrl'=>$ext,
  277. 'extends'=>is_string($v['extends'])?json_decode($v['extends'],true) : $v['extends']
  278. ];
  279. }
  280. }
  281. return $data;
  282. }
  283. // 设置当前窗口的消息默认为已读
  284. public function setMsgIsRead()
  285. {
  286. $param = $this->request->param();
  287. // 判断是否是一个二维数组
  288. if (is_array($param['messages'][0] ?? '')) {
  289. $messages=$param['messages'];
  290. } else {
  291. $messages=[$param['messages']];
  292. }
  293. $this->setIsRead($param['is_group'], $param['toContactId'],$messages);
  294. if (!$param['is_group']) {
  295. wsSendMsg($param['fromUser'], 'isRead', $messages, 0);
  296. }
  297. return success('');
  298. }
  299. // 设置消息已读
  300. protected function setIsRead($is_group, $to_user,$messages=[])
  301. {
  302. if ($is_group) {
  303. $chat_identify = $to_user;
  304. $toContactId = explode('-', $to_user)[1];
  305. // 将@消息放到定时任务中逐步清理
  306. if($messages){
  307. Message::setAtRead($messages,$this->userInfo['user_id']);
  308. }
  309. // 更新群里面我的所有未读消息为0
  310. GroupUser::editGroupUser(['user_id' => $this->userInfo['user_id'], 'group_id' => $toContactId], ['unread' => 0]);
  311. } else {
  312. $chat_identify = chat_identify($this->userInfo['user_id'], $to_user);
  313. // 更新我的未读消息为0
  314. Message::update(['is_read' => 1], [['chat_identify', '=', $chat_identify], ['to_user', '=', $this->userInfo['user_id']]]);
  315. // 告诉对方我阅读了消息
  316. wsSendMsg($to_user, 'readAll', ['toContactId' => $this->userInfo['user_id']]);
  317. }
  318. return $chat_identify;
  319. }
  320. // 聊天设置
  321. public function setting()
  322. {
  323. $param = $this->request->param();
  324. if ($param) {
  325. User::where(['user_id' => $this->userInfo['user_id']])->update(['setting' => $param]);
  326. return success('');
  327. }
  328. return warning('设置失败');
  329. }
  330. // 撤回消息
  331. public function undoMessage()
  332. {
  333. $param = $this->request->param();
  334. $id = $param['id'];
  335. $message = Message::where(['id' => $id])->find();
  336. if ($message) {
  337. // 如果时间超过了2分钟也不能撤回
  338. $createTime=is_string($message['create_time']) ? strtotime($message['create_time']) : $message['create_time'];
  339. if(time()-$createTime>120 && $message['is_group']==0){
  340. return warning('超过2分钟不能撤回!');
  341. }
  342. $text = "撤回了一条消息";
  343. $fromUserName = "对方";
  344. $toContactId = $message['to_user'];
  345. if ($message['is_group'] == 1) {
  346. $fromUserName = $this->userInfo['realname'];
  347. $toContactId = explode('-', $message['chat_identify'])[1];
  348. // 如果是群聊消息撤回,需要判断是否是群主或者管理员,如果是则可以撤回
  349. if($message['from_user']!=$this->userInfo['user_id']){
  350. $groupUser=GroupUser::where(['user_id'=>$this->userInfo['user_id'],'group_id'=>$toContactId])->find();
  351. if(!$groupUser || !in_array($groupUser['role'],[1,2])){
  352. return warning('您没有权限撤回该消息!');
  353. }
  354. $text='被(管理员)撤回了一条消息';
  355. }
  356. }
  357. $message->content = str_encipher($text);
  358. $message->type = 'event';
  359. $message->is_undo = 1;
  360. $message->save();
  361. $info = $message->toArray();
  362. // $data = $info;
  363. $data['content'] = $fromUserName . $text;
  364. $data['sendTime'] = $createTime * 1000;
  365. $data['id'] = $info['id'];
  366. $data['from_user'] = $info['from_user'];
  367. $data['msg_id'] = $info['msg_id'];
  368. $data['status'] = $info['status'];
  369. $data['type'] = 'event';
  370. $data['isMobile'] = $this->request->isMobile() ? 1 : 0;
  371. wsSendMsg($toContactId, 'undoMessage', $data, $info['is_group']);
  372. if($info['is_group']==0){
  373. // 给自己也发一份推送,多端同步
  374. $data['content'] = "你". $text;
  375. wsSendMsg($this->userInfo['user_id'], 'undoMessage', $data, $info['is_group']);
  376. }
  377. return success('');
  378. } else {
  379. return warning();
  380. }
  381. }
  382. // 删除消息
  383. public function removeMessage()
  384. {
  385. $param = $this->request->param();
  386. $id = $param['id'];
  387. $map = ['id' => $id];
  388. $message = Message::where($map)->find();
  389. if ($message) {
  390. $message->del_user = $this->userInfo['user_id'];
  391. if ($message['is_group'] == 1) {
  392. if ($message['del_user']) {
  393. $message->del_user .= ',' . $this->userInfo['user_id'];
  394. }
  395. } else {
  396. if ($message['del_user'] > 0) {
  397. $message->where($map)->delete();
  398. return success('删除成功!');
  399. }
  400. }
  401. $message->save();
  402. return success('');
  403. } else {
  404. return warning('');
  405. }
  406. }
  407. // 消息免打扰
  408. public function isNotice()
  409. {
  410. $param = $this->request->param();
  411. $user_id = $this->userInfo['user_id'];
  412. $id = $param['id'];
  413. if ($param['is_group'] == 1) {
  414. $group_id = explode('-', $param['id'])[1];
  415. GroupUser::update(['is_notice' => $param['is_notice']], ['user_id' => $user_id, 'group_id' => $group_id]);
  416. } else {
  417. $map = ['create_user' => $user_id, 'friend_user_id' => $id];
  418. $friend = Friend::where($map)->find();
  419. try {
  420. if ($friend) {
  421. $friend->is_notice = $param['is_notice'];
  422. $friend->save();
  423. } else {
  424. $info = [
  425. 'create_user' => $user_id,
  426. 'friend_user_id' => $id,
  427. 'is_notice' => $param['is_notice']
  428. ];
  429. Friend::create($info);
  430. }
  431. return success('');
  432. } catch (Exception $e) {
  433. return error($e->getMessage());
  434. }
  435. }
  436. wsSendMsg($user_id,"setIsNotice",['id'=>$id,'is_notice'=>$param['is_notice'],'is_group'=>$param['is_group']]);
  437. return success('');
  438. }
  439. // 设置聊天置顶
  440. public function setChatTop()
  441. {
  442. $param = $this->request->param();
  443. $user_id = $this->userInfo['user_id'];
  444. $is_group = $param['is_group'] ?: 0;
  445. $id = $param['id'];
  446. try {
  447. if ($is_group == 1) {
  448. $group_id = explode('-', $param['id'])[1];
  449. GroupUser::update(['is_top' => $param['is_top']], ['user_id' => $user_id, 'group_id' => $group_id]);
  450. } else {
  451. $map = ['create_user' => $user_id, 'friend_user_id' => $id];
  452. $friend = Friend::where($map)->find();
  453. if ($friend) {
  454. $friend->is_top = $param['is_top'];
  455. $friend->save();
  456. } else {
  457. $info = [
  458. 'create_user' => $user_id,
  459. 'friend_user_id' => $id,
  460. 'is_top' => $param['is_top']
  461. ];
  462. Friend::create($info);
  463. }
  464. }
  465. wsSendMsg($user_id,"setChatTop",['id'=>$id,'is_top'=>$param['is_top'],'is_group'=>$is_group]);
  466. return success('');
  467. } catch (Exception $e) {
  468. return error($e->getMessage());
  469. }
  470. }
  471. // 删除聊天
  472. public function delChat()
  473. {
  474. $param = $this->request->param();
  475. $user_id = $this->userInfo['user_id'];
  476. $is_group = $param['is_group'] ?: 0;
  477. $id = $param['id'];
  478. if(!$is_group){
  479. $chat_identify=chat_identify($user_id,$id);
  480. }else{
  481. return success('');
  482. }
  483. Message::where(['chat_identify' => $chat_identify])->update(['is_last' => 0]);
  484. return success('');
  485. }
  486. // 向用户发送消息
  487. public function sendToMsg(){
  488. $param=$this->request->param();
  489. $toContactId=$param['toContactId'];
  490. $type=$param['type'];
  491. $status=$param['status'];
  492. $event=$param['event'] ?? 'calling';
  493. if($event=='calling'){
  494. $status=3;
  495. }
  496. $sdp=$param['sdp'] ?? '';
  497. $iceCandidate=$param['iceCandidate'] ?? '';
  498. $callTime=$param['callTime'] ?? '';
  499. $msg_id=$param['msg_id'] ?? '';
  500. $id=$param['id'] ?? '';
  501. $code=($param['code'] ?? '') ?: 901;
  502. // 如果该用户不在线,则发送忙线
  503. Gateway::$registerAddress = config('gateway.registerAddress');
  504. if(!Gateway::isUidOnline($toContactId)){
  505. $toContactId=$this->userInfo['user_id'];
  506. $code=907;
  507. $event='busy';
  508. sleep(1);
  509. }
  510. switch($code){
  511. case 902:
  512. $content='已取消通话';
  513. break;
  514. case 903:
  515. $content='已拒绝';
  516. break;
  517. case 905:
  518. $content='未接通';
  519. break;
  520. case 906:
  521. $content='通话时长 '.date("i:s",$callTime);
  522. break;
  523. case 907:
  524. $content='忙线中';
  525. break;
  526. case 908:
  527. $content='其他端已操作';
  528. break;
  529. default:
  530. $content=$type==1 ?'视频通话' : '语音通话';
  531. break;
  532. }
  533. switch($event){
  534. case 'calling':
  535. $content=$type==1 ?'视频通话' : '语音通话';
  536. break;
  537. case 'acceptRtc':
  538. $content='接听通话请求';
  539. break;
  540. case 'iceCandidate':
  541. $content='数据交换中';
  542. break;
  543. }
  544. $userInfo=$this->userInfo;
  545. $userInfo['id']=$userInfo['user_id'];
  546. $data=[
  547. 'id'=>$id,
  548. 'msg_id'=>$msg_id,
  549. 'sendTime'=>time()*1000,
  550. 'toContactId'=>$toContactId,
  551. 'content'=>$content,
  552. 'type'=>'webrtc',
  553. 'status'=>'succeed',
  554. 'is_group'=>0,
  555. 'is_read'=>0,
  556. 'fromUser'=>$userInfo,
  557. 'at'=>[],
  558. 'extends'=>[
  559. 'type'=>$type, //通话类型,1视频,0语音。
  560. 'status'=>$status, //,1拨打方,2接听方
  561. 'event'=>$event,
  562. 'callTime'=>$callTime,
  563. 'sdp'=>$sdp,
  564. 'code'=>$code, //通话状态:呼叫901,取消902,拒绝903,接听904,未接通905,接通后挂断906,忙线907,其他端操作908
  565. 'iceCandidate'=>$iceCandidate,
  566. 'isMobile'=>$this->request->isMobile() ? 1 : 0,
  567. ]
  568. ];
  569. if($event=='calling'){
  570. $chat_identify=chat_identify($userInfo['id'],$toContactId);
  571. $msg=[
  572. 'from_user'=>$userInfo['id'],
  573. 'to_user'=>$toContactId,
  574. 'id'=>$id,
  575. 'content'=>str_encipher($content),
  576. 'chat_identify'=>$chat_identify,
  577. 'create_time'=>time(),
  578. 'type'=>$data['type'],
  579. 'is_group'=>0,
  580. 'is_read'=>0,
  581. 'extends'=>$data['extends'],
  582. ];
  583. $message=new Message();
  584. $message->update(['is_last'=>0],['chat_identify'=>$chat_identify]);
  585. $message->save($msg);
  586. $msg_id=$message->msg_id;
  587. $data['msg_id']=$msg_id;
  588. // 将接收人设置为发送人才能定位到该消息
  589. $data['toContactId']=$userInfo['id'];
  590. $data['toUser']=$toContactId;
  591. }elseif($event=='hangup'){
  592. $message=Message::where(['id'=>$id])->find();
  593. if(!$message){
  594. return error('通话失败!');
  595. }
  596. if($message){
  597. $message->content=str_encipher($content);
  598. $extends=$message->extends;
  599. $extends['code']=$code;
  600. $extends['callTime']=$callTime;
  601. $message->extends=$extends;
  602. $message->save();
  603. }
  604. }
  605. wsSendMsg($toContactId,'webrtc',$data);
  606. $wsData=$data;
  607. if(in_array($event,['calling','acceptRtc','hangup'])){
  608. if(in_array($event,['acceptRtc','hangup'])){
  609. $data['extends']['event']='otherOpt'; //其他端操作
  610. }
  611. $data['toContactId']=$toContactId;
  612. wsSendMsg($userInfo['id'],'webrtc',$data);
  613. }
  614. return success('',$wsData);
  615. }
  616. // 修改密码
  617. public function editPassword()
  618. {
  619. if(env('app.demon_mode',false)){
  620. return warning('演示模式不支持修改');
  621. }
  622. $user_id = $this->userInfo['user_id'];
  623. $user=User::find($user_id);
  624. if(!$user){
  625. return warning('用户不存在');
  626. }
  627. $account=$user->account;
  628. $code=$this->request->param('code','');
  629. $originalPassword = $this->request->param('originalPassword', '');
  630. if($code){
  631. if(Cache::get($account)!=$code){
  632. return warning('验证码不正确!');
  633. }
  634. }elseif($originalPassword){
  635. if(password_hash_tp($originalPassword,$user->salt)!= $user->password){
  636. return warning('原密码不正确!');
  637. }
  638. }else{
  639. return warning('参数错误!');
  640. }
  641. try{
  642. $password = $this->request->param('password','');
  643. if($password){
  644. $salt=$user->salt;
  645. $user->password= password_hash_tp($password,$salt);
  646. }
  647. $user->save();
  648. return success('修改成功');
  649. }catch (\Exception $e){
  650. return error('修改失败');
  651. }
  652. }
  653. // 修改用户信息
  654. public function updateUserInfo(){
  655. try{
  656. $data = $this->request->param();
  657. $user=User::find($this->uid);
  658. if(!$user){
  659. return warning('用户不存在');
  660. }
  661. $user->realname =$data['realname'];
  662. $user->email =$data['email'];
  663. $user->motto=$data['motto'];
  664. $user->sex =$data['sex'];
  665. $user->name_py= pinyin_sentence($data['realname']);
  666. $user->save();
  667. return success('修改成功', $data);
  668. }catch (\Exception $e){
  669. return error($e->getMessage());
  670. }
  671. }
  672. // 修改账户
  673. public function editAccount(){
  674. if(env('app.demon_mode',false)){
  675. return warning('演示模式不支持修改');
  676. }
  677. $code=$this->request->param('code','');
  678. $newCode=$this->request->param('newCode','');
  679. $account=$this->request->param('account','');
  680. $isUser=User::where('account',$account)->find();
  681. if($isUser){
  682. return warning('账户已存在');
  683. }
  684. $user=User::find($this->uid);
  685. if(!$user){
  686. return warning('用户不存在');
  687. }
  688. // 如果已经认证过了,则需要验证验证码
  689. if($user->is_auth){
  690. if(Cache::get($user->account)!=$code){
  691. return warning('验证码不正确!');
  692. }
  693. }
  694. if(Cache::get($account)!=$newCode){
  695. return warning('新账户验证码不正确!');
  696. }
  697. try{
  698. $user->account=$account;
  699. $user->is_auth=1;
  700. $user->save();
  701. return success('修改成功');
  702. }catch (\Exception $e){
  703. return error('修改失败');
  704. }
  705. }
  706. // 阅读@消息
  707. public function readAtMsg(){
  708. $param = $this->request->param();
  709. $atList=Db::name('message')->where(['chat_identify'=>$param['toContactId'],'is_group'=>1])->whereFindInSet('at',$this->userInfo['user_id'])->order('msg_id desc')->select();
  710. $atData=$this->recombileMsg($atList,false);
  711. Message::setAtRead($atData,$this->userInfo['user_id']);
  712. // $message=Message::where('msg_id',$param['msg_id'])->select();
  713. // $atList=($message ?? null) ? explode(',',$message): [];
  714. // // 两个数组取差集
  715. // $newAtList = array_diff($atList, [$this->userInfo['user_id']]);
  716. // Message::where('msg_id',$param['msg_id'])->update(['at'=>implode(',',$newAtList)]);
  717. return success('');
  718. }
  719. }