Chat.php 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. <?php
  2. namespace App\Module;
  3. use Cache;
  4. use DB;
  5. /**
  6. * Class Chat
  7. * @package App\Module
  8. */
  9. class Chat
  10. {
  11. /**
  12. * 打开对话(创建对话)
  13. * @param string $username 发送者用户名
  14. * @param string $receive 接受者用户名
  15. * @param bool $forceRefresh 是否强制刷新缓存
  16. * @return mixed
  17. */
  18. public static function openDialog($username, $receive, $forceRefresh = false)
  19. {
  20. if (!$username || !$receive) {
  21. return Base::retError('参数错误!');
  22. }
  23. $cacheKey = $username . "@" . $receive;
  24. if ($forceRefresh === true) {
  25. Cache::forget($cacheKey);
  26. }
  27. $result = Cache::remember($cacheKey, now()->addMinutes(10), function() use ($receive, $username) {
  28. $row = Base::DBC2A(DB::table('chat_dialog')->where([
  29. 'user1' => $username,
  30. 'user2' => $receive,
  31. ])->first());
  32. if ($row) {
  33. $row['recField'] = 2; //接受者的字段位置
  34. return Base::retSuccess('already1', $row);
  35. }
  36. $row = Base::DBC2A(DB::table('chat_dialog')->where([
  37. 'user1' => $receive,
  38. 'user2' => $username,
  39. ])->first());
  40. if ($row) {
  41. $row['recField'] = 1;
  42. return Base::retSuccess('already2', $row);
  43. }
  44. //
  45. DB::table('chat_dialog')->insert([
  46. 'user1' => $username,
  47. 'user2' => $receive,
  48. 'indate' => Base::time()
  49. ]);
  50. $row = Base::DBC2A(DB::table('chat_dialog')->where([
  51. 'user1' => $username,
  52. 'user2' => $receive,
  53. ])->first());
  54. if ($row) {
  55. $row['recField'] = 2;
  56. return Base::retSuccess('success', $row);
  57. }
  58. //
  59. return Base::retError('系统繁忙,请稍后再试!');
  60. });
  61. if (Base::isError($result)) {
  62. Cache::forget($cacheKey);
  63. }
  64. return $result;
  65. }
  66. /**
  67. * 删除对话缓存
  68. * @param $username
  69. * @param $receive
  70. * @return bool
  71. */
  72. public static function forgetDialog($username, $receive)
  73. {
  74. if (!$username || !$receive) {
  75. return false;
  76. }
  77. Cache::forget($username . "@" . $receive);
  78. Cache::forget($receive . "@" . $username);
  79. return true;
  80. }
  81. /**
  82. * 保存对话消息
  83. * @param string $username 发送者用户名
  84. * @param string $receive 接受者用户名
  85. * @param array $message
  86. * @return mixed
  87. */
  88. public static function saveMessage($username, $receive, $message)
  89. {
  90. $dialog = self::openDialog($username, $receive);
  91. if (Base::isError($dialog)) {
  92. return $dialog;
  93. } else {
  94. $dialog = $dialog['data'];
  95. }
  96. //
  97. $indate = abs($message['indate'] - time()) > 60 ? time() : $message['indate'];
  98. if (isset($message['id'])) unset($message['id']);
  99. if (isset($message['username'])) unset($message['username']);
  100. if (isset($message['userimg'])) unset($message['userimg']);
  101. if (isset($message['indate'])) unset($message['indate']);
  102. if (isset($message['replaceId'])) unset($message['replaceId']);
  103. $inArray = [
  104. 'did' => $dialog['id'],
  105. 'username' => $username,
  106. 'receive' => $receive,
  107. 'message' => Base::array2string($message),
  108. 'indate' => $indate
  109. ];
  110. //
  111. if (mb_strlen($message['text']) > 20000) {
  112. return Base::retError("发送内容长度已超出最大限制!");
  113. }
  114. $field = ($dialog['recField'] == 1 ? 'unread1' : 'unread2');
  115. $unread = intval(DB::table('chat_dialog')->where('id', $dialog['id'])->value($field));
  116. $lastText = self::messageDesc($message);
  117. if ($lastText) {
  118. $upArray = [];
  119. if ($username != $receive) {
  120. $upArray = Base::DBUP([
  121. $field => 1,
  122. ]);
  123. $unread += 1;
  124. }
  125. $upArray['lasttext'] = mb_substr($lastText, 0, 100);
  126. $upArray['lastdate'] = $indate;
  127. if ($dialog['del1']) {
  128. $upArray['del1'] = 0;
  129. }
  130. if ($dialog['del2']) {
  131. $upArray['del2'] = 0;
  132. }
  133. DB::table('chat_dialog')->where('id', $dialog['id'])->update($upArray);
  134. if ($dialog['del1'] || $dialog['del2']) {
  135. Chat::forgetDialog($dialog['user1'], $dialog['user2']);
  136. }
  137. }
  138. $inArray['id'] = DB::table('chat_msg')->insertGetId($inArray);
  139. $inArray['message'] = $message;
  140. $inArray['unread'] = $unread;
  141. //
  142. return Base::retSuccess('success', $inArray);
  143. }
  144. /**
  145. * 格式化信息(来自接收)
  146. * @param $data
  147. * @return array
  148. */
  149. public static function formatMsgReceive($data) {
  150. return self::formatMsgData(Base::json2array($data));
  151. }
  152. /**
  153. * 格式化信息(用于发送)
  154. * @param $array
  155. * @return string
  156. */
  157. public static function formatMsgSend($array) {
  158. return Base::array2json(self::formatMsgData($array));
  159. }
  160. /**
  161. * 格式化信息
  162. * @param array $array
  163. * @return array
  164. */
  165. public static function formatMsgData($array = []) {
  166. if (!is_array($array)) {
  167. $array = [];
  168. }
  169. //messageType来自客户端(前端->后端):refresh/unread/read/roger/user/info/team/docs/appActivity
  170. //messageType来自服务端(后端->前端):error/open/kick/user/back/unread/docs
  171. if (!isset($array['messageType'])) $array['messageType'] = ''; //消息类型
  172. if (!isset($array['messageId'])) $array['messageId'] = ''; //消息ID(用于back给客户端)
  173. if (!isset($array['contentId'])) $array['contentId'] = 0; //消息数据ID(用于roger给服务端)
  174. if (!isset($array['channel'])) $array['channel'] = ''; //渠道(用于多端登录)
  175. if (!isset($array['username'])) $array['username'] = ''; //发送者
  176. if (!isset($array['target'])) $array['target'] = null; //接受者
  177. if (!isset($array['body'])) $array['body'] = []; //正文内容
  178. if (!isset($array['time'])) $array['time'] = time(); //时间
  179. //
  180. $array['contentId'] = intval($array['contentId']);
  181. if (!is_array($array['body']) || empty($array['body'])) $array['body'] = ['_' => time()];
  182. return $array;
  183. }
  184. /**
  185. * 获取跟任务有关系的(在线)用户(关注的、在项目里的、负责人、创建者)
  186. * @param $taskId
  187. * @return array
  188. */
  189. public static function getTaskUsers($taskId)
  190. {
  191. $tmpLists = Project::taskSomeUsers($taskId);
  192. if (empty($tmpLists)) {
  193. return [];
  194. }
  195. //
  196. return Base::DBC2A(DB::table('ws')->select(['fd', 'username', 'channel'])->where([
  197. ['update', '>', time() - 600],
  198. ])->whereIn('username', array_values(array_unique($tmpLists)))->get());
  199. }
  200. /**
  201. * 获取消息简述
  202. * @param array $message
  203. * @return mixed|string
  204. */
  205. public static function messageDesc($message)
  206. {
  207. switch ($message['type']) {
  208. case 'text':
  209. $lastText = $message['text'];
  210. break;
  211. case 'image':
  212. $lastText = '[图片]';
  213. break;
  214. case 'file':
  215. $lastText = '[文件]';
  216. break;
  217. case 'taskB':
  218. $lastText = $message['text'] . " [来自关注任务]";
  219. break;
  220. case 'report':
  221. $lastText = $message['text'] . " [来自工作报告]";
  222. break;
  223. case 'video':
  224. $lastText = '[视频通话]';
  225. break;
  226. case 'voice':
  227. $lastText = '[语音通话]';
  228. break;
  229. default:
  230. $lastText = '[未知类型]';
  231. break;
  232. }
  233. return $lastText;
  234. }
  235. }