Im.php 49 KB

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