Im.php 49 KB

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