url=getDiskUrl().'/'; } // 朋友圈列表 public function index() { $where = '(p.delete_time = 0 and p.privacy > 0 and p.status = 1) '; $where .= ' and ( p.user_id = ' . $this->uid; $friendIds = Friend::getFriendIds($this->uid); if ($friendIds) { $friendIdStr = implode(',',$friendIds); $where .= ' or ( p.privacy = 1 and p.user_id in (' . $friendIdStr . '))'; // 可见 $where = $this->getPostsWhereOr($where); } $where .= ')'; $field = 'p.id,p.content,p.location,p.address as location_address,p.type,p.user_id,p.create_time'; $order = 'p.create_time desc'; $model = new PostsModel(); $list = $this->paginate($model->alias('p')->where($where)->field($field)->order($order)); $data = []; if ($list) { $data = $list->toArray()['data']; foreach ($data as &$item) { $item['user'] = $this->getFriendUserInfo($item['user_id']); $item['files'] = PostsFile::getPostsFile($item['id']); $userIdArr = $friendIds; $userIdArr[] = $this->uid; $likesData = Likes::getPostsLikes($item['id'], $this->uid, $userIdArr); $item['likes'] = $likesData['likes']; $item['is_like'] = $likesData['is_like']; $item['comment'] = Comment::getPostsComment($item['id'], $this->uid, $userIdArr); } } return success('', $data,$list->total(),$list->currentPage()); } // 获取好友用户信息 protected function getFriendUserInfo($user_id):array { $friendNickname = Friend::where(['create_user' => $this->uid, 'friend_user_id' => $user_id, 'status' => 1])->value('nickname'); $user = User::getUserInfo(['user_id' => $user_id, 'status' => 1], 'realname, avatar, user_id'); if (empty($friendNickname)) { $friendNickname = $user['realname']; } return [ 'user_id' => $user_id, 'avatar' => $user['avatar'] ? getDiskUrl() .'/'. $user['avatar'] : avatarUrl($user['avatar'], $user['realname'], $user['user_id'], 120), 'nickname' => $friendNickname ]; } // 好友可见、不可见查询条件 protected function getPostsWhereOr($whereOr):string { $prefix = config('database.connections.mysql.prefix'); $whereOr .= " or ( p.privacy = 2 and exists ( select 1 from {$prefix}posts_privacy_users pvu where pvu.posts_id = p.id and pvu.type = 1 and pvu.user_id in ({$this->uid}) ))"; // 不可见 $whereOr .= " or ( p.privacy = 4 and not exists ( select 1 from {$prefix}posts_privacy_users peu where peu.posts_id = p.id and peu.type = 2 and peu.user_id = {$this->uid} ))"; return $whereOr; } // 我的朋友圈列表 public function myPosts() { $user_id = $this->uid; // 好有朋友圈 $friendUserId = $this->request->param('friend_user_id', ''); $whereAnd = " ( p.status = 1 and p.delete_time = 0"; $whereOr = ''; if (!empty($friendUserId)) { // 验证是否为当前用户的好友 if (!is_numeric($friendUserId)) { return warning(lang('system.error')); } $friendIds = Friend::getFriendIds($this->uid); if (!in_array($friendUserId, $friendIds)) { return warning(lang('system.forbidden')); } $user_id = $friendUserId; $whereOr .= ' and ( p.privacy = 1 '; $whereOr = $this->getPostsWhereOr($whereOr); $whereOr .= ')'; } else { $whereAnd .= ' and p.privacy in (1,2,3,4)'; } $whereAnd .= " and p.user_id = {$user_id} )"; $where = $whereAnd . $whereOr; $field = 'p.id,p.content,p.location,p.address,p.type,p.user_id,p.create_time,p.privacy,p.avatar'; $order = 'create_time desc'; $model = new PostsModel(); $list = $this->paginate($model->alias('p')->where($where)->field($field)->order($order)); $data = []; if ($list) { $data = $list->toArray()['data']; foreach ($data as &$item) { $src = ''; if (empty($item['avatar'])) { $item['files'] = PostsFile::getPostsFile($item['id']); if (strpos($item['type'], '2') !== false && count($item['files']) > 1) { $imageFileArr = array_column($item['files'], 'src'); $src = PostsModel::createPostsAvatar($item['id'], $imageFileArr); } } else { $src = $item['avatar']; } if ($src) { $item['files'][] = ['file_id' => 0, 'type' => 1, 'src' => $src]; } unset($data['avatar']); } } return success('', $data,$list->total(),$list->currentPage()); } public function details() { $posts_id = $this->request->param('posts_id'); $friendUserId = $this->request->param('friend_user_id', ''); if (empty($posts_id)) { return warning(lang('system.error')); } $where = [ ['id', '=', $posts_id], ['status', '=', 1], ['delete_time', '=', 0] ]; if (!empty($friendUserId)) { // 验证是否为当前用户的好友 if (!is_numeric($friendUserId)) { return warning(lang('system.error')); } $friendIds = Friend::getFriendIds($this->uid); if (!in_array($friendUserId, $friendIds)) { return warning(lang('system.error')); } $where[] = ['user_id', '=', $friendUserId]; $where[] = ['privacy', 'in', [1,2,4]]; } else { $where[] = ['user_id', '=', $this->uid]; $where[] = ['privacy', 'in', [1,2,3,4]]; } $field = 'id,content,location,address,type,user_id,create_time,privacy'; $data = (new PostsModel())->where($where)->field($field)->find(); if (!$data) { return warning(lang('posts.postsDel')); } $data['files'] = PostsFile::getPostsFile($data['id']); $friendIds = Friend::getFriendIds($this->uid); $friendIds[] = $this->uid; $likesData = Likes::getPostsLikes($data['id'], $this->uid, $friendIds); $data['likes'] = $likesData['likes']; $data['is_like'] = $likesData['is_like']; $data['comment'] = Comment::getPostsComment($data['id'], $this->uid, $friendIds); $data['user'] = $this->getFriendUserInfo($data['user_id']); return success('', $data); } // 删除帖子 public function del() { try { $posts_id = $this->request->param('posts_id'); if (empty($posts_id)) { throw new \Exception(''); } $existsWhere = [ 'id' => $posts_id, 'user_id' => $this->uid, 'delete_time' => 0 ]; $exists = (new PostsModel())->where($existsWhere)->find(); if (!$exists) { throw new \Exception(''); } PostsModel::update(['delete_time' => time()], ['id' => $posts_id]); return success(lang('system.success')); } catch (\Exception $e) { return warning(lang('system.error')); } } // 添加帖子 public function add() { $content = $this->request->param('content', ''); $privacy = $this->request->param('privacy', ''); $location = $this->request->param('location', ''); $address = $this->request->param('address', ''); $video_file = $this->request->param('video_file', ''); $poster_file = $this->request->param('poster_file', ''); $imgArr = $this->request->param('img_arr', []); $posts_id = $this->request->param('posts_id', ''); $user_ids = $this->request->param('user_ids', []); $status = $this->request->param('status', '1'); if (!in_array($status, ['1','2'])) { return error(lang('system.error')); } $privacy_user_arr = $this->privacyUserArr; if (in_array($privacy, $privacy_user_arr)) { if (empty($user_ids) || !is_array($user_ids)) { return error(lang('posts.user_empty')); } } $type = ''; if (!empty($content)) { $type = '1'; $detectionRes = $this->detectionProcessingText($content); if (isset($detectionRes['error'])) { return error($detectionRes['error']); } $content = $detectionRes['content']; } if (!empty($imgArr)) { if (is_array($imgArr) && count($imgArr) > 9) { return error(lang('posts.img_max_length')); } $type .= '2'; } elseif (!empty($video_file)) { $type .= '3'; } $exists = []; if ($posts_id) { $existsWhere = [ 'id' => $posts_id, 'status' => 2, 'user_id' => $this->uid ]; $exists = (new PostsModel())->where($existsWhere)->find()->toArray(); if (!$exists) { return error(lang('posts.exists')); } } Db::startTrans(); try { $info = [ 'user_id' => $this->uid, 'type' => $type, 'content' => $content, 'privacy' => $privacy, 'location' => $location ?? '', 'address' => $address ?? '', 'status' => $status ]; if ($posts_id) { $info['update_time'] = time(); PostsModel::update($info,['id' => $posts_id]); PostsFile::update(['delete_time' => time()],['posts_id' => $posts_id]); if (in_array($exists['privacy'], $privacy_user_arr)) { (new PostsPrivacyUsers())->where(['posts_id' => $posts_id])->delete(); } } else { $info['create_time'] = time(); $posts_id = (new PostsModel())->insertGetId($info); } $fileSaveArr = []; if ($imgArr) { foreach ($imgArr as $key => $img_url) { $fileSaveArr = $this->addPostsFileData( $img_url, $posts_id, $fileSaveArr, $key + 1 ); } PostsModel::createAvatar($posts_id); } elseif ($video_file && $poster_file) { $fileSaveArr = $this->addPostsFileData( $video_file, $posts_id, $fileSaveArr, 1, 2 ); $fileSaveArr = $this->addPostsFileData( $poster_file, $posts_id, $fileSaveArr, 2 ); } if ($imgArr || ($video_file && $poster_file)) { if (empty($fileSaveArr)) { throw new \Exception(lang('system.error')); } } if ($fileSaveArr) { (new PostsFile())->saveAll($fileSaveArr); } if (!empty($user_ids) && in_array($info['privacy'], $privacy_user_arr)) { $user_type = $info['privacy'] == 2 ? 1 : 2; $privacy_users = []; foreach ($user_ids as $user_id) { if (!is_numeric($user_id)) { throw new \Exception(lang('system.error')); } $privacy_users[] = [ 'posts_id' => $posts_id, 'user_id' => $user_id, 'type' => $user_type ]; } if ($privacy_users) { (new PostsPrivacyUsers())->saveAll($privacy_users); } } Db::commit(); return $status == 2 ? success('') : success(lang('posts.submit')); } catch (\Exception $e) { Db::rollback(); return warning(lang('system.error')); } } // 添加图片视频数据处理 protected function addPostsFileData($url, $posts_id, $data, $sort = 1, $type = 1) { $imgUrl = str_replace($this->url, '', $url); $whereFile = ['src' => $imgUrl, 'user_id' => $this->uid, 'delete_time' => 0]; $img_file_id = File::where($whereFile)->value('file_id'); if ($img_file_id) { $data[] = [ 'posts_id' => $posts_id, 'type' => $type, 'file_id' => $img_file_id, 'sort' => $sort ]; } return $data; } // 检查文本输入内容 protected function detectionProcessingText($content, $type = 1) { // 限制文字内容长度 $text = strip_tags($content); $textLen = mb_strlen($text); $length = 2048; $error = lang('posts.msgContentLimit') . $textLen; if ($type == 2) { $length = 500; $error = lang('im.msgContentLimit') . $textLen; } else { //$content = preg_link($content); } if ($textLen > $length) { return ['error' => $error]; } // 接入聊天内容检测服务 event('GreenText',['content'=>$content,'service'=>"chat_detection"]); return ['content' => $content]; } // 获取上传草稿帖子数据 public function getLastPosts() { $existsWhere = ['user_id' => $this->uid, 'status' => 2, 'delete_time' => 0]; $field = 'id as posts_id,content,type,location,address as location_address,privacy'; $data = PostsModel::where($existsWhere)->field($field)->find(); if ($data) { $data['files'] = PostsFile::getPostsFile($data['posts_id']); $privacy_user =[]; if (in_array($data['privacy'], $this->privacyUserArr)) { $PrivacyUsers = PostsPrivacyUsers::where(['posts_id' => $data['posts_id']])->column('user_id'); foreach ($PrivacyUsers as $user_id) { $privacy_user[] = $this->getFriendUserInfo($user_id); } } $data['privacy_user'] = $privacy_user; } return success('', $data); } // 点赞帖子 public function like() { $posts_id = $this->request->param('posts_id'); if (empty($posts_id)) { return error(lang('system.fail')); } $reply_user_id = PostsModel::where('id', $posts_id)->value('user_id'); if (empty($reply_user_id)) { return error(lang('system.fail')); } $info = [ 'user_id' => $this->uid, 'type' => 1, 'relevance_id' => $posts_id ]; $exists_id = Likes::where($info)->value('id'); if ($exists_id) { (new Likes())->where('id', $exists_id)->delete(); PostsNotice::optionNotice($posts_id, $exists_id, $reply_user_id, 1, 'del'); $this->wsSendMsg($reply_user_id, 0, 'postsNotice'); return success(lang('posts.cancel_like')); } $info['create_time'] = time(); $id = (new Likes())->insertGetId($info); if ($reply_user_id != $this->uid) { PostsNotice::optionNotice($posts_id, $id, $reply_user_id); // 向作者好友推送新的消息 $this->wsSendMsg($reply_user_id, 0, 'postsNotice'); } return success(lang('posts.success_like')); } /** * @param int $user_id // 推送数据 * @param int $id // 数据$id * @param string $type // 推送类型 postsComment 评论 postsLikes 点赞 postsNotice 提醒 * @return void */ protected function wsSendMsg(int $user_id, int $id, string $type = 'postsComment') { $userIds = []; $data = []; switch ($type) { case 'postsComment' : $comment = (new Comment())->where('id', $id)->field('id,content,user_id,reply_user_id')->find(); $data = Comment::dataOption($comment, $this->uid); break; case 'postsLikes' : $data = Likes::where('id', $id)->field('user_id')->find(); $friend = Friend::getFriendName($this, $data['user_id']); $data['nickname'] = $friend['nickname']; $data['avatar'] = $friend['avatar']; break; case 'postsNotice' : $count = PostsNotice::where(['user_id' => $this->uid, 'is_read' => 0])->count(); $data['count'] = $count ?? 0; $userIds[] = $user_id; break; } if (in_array($type, ['postsComment', 'postsLikes'])) { $userIds = Friend::getFriendIds($user_id); // 不推送给当前用户 // $key = array_search($this->uid, $userIds); // if ($key !== false) { // unset($userIds[$key]); // } } wsSendMsg($userIds,$type,$data); } // 评论帖子 public function comment() { $posts_id = $this->request->param('posts_id'); if (empty($posts_id)) { return error(lang('system.fail')); } $content = $this->request->param('content'); $content = trim($content); if (empty($content)) { return error(lang('posts.commentEmpty')); } $detectionRes = $this->detectionProcessingText($content, 2); if (isset($detectionRes['error'])) { return error($detectionRes['error']); } $content = $detectionRes['content']; $pid = $this->request->param('pid', 0); $reply_user_id = 0; if (!empty($pid)) { $reply_comment = Comment::where('id', $pid)->field('user_id,type,relevance_id,delete_time')->find(); if ($reply_comment) { $reply_user_id = $reply_comment['user_id']; if ($reply_comment['type'] != 1 || $reply_comment['relevance_id'] != $posts_id) { return error(lang('system.fail')); } if ($reply_comment['delete_time'] > 0) { return error(lang('posts.comment_del')); } } else { return error(lang('system.fail')); } } $info = [ 'user_id' => $this->uid, 'content' => $content, 'type' => 1, 'relevance_id' => $posts_id, 'reply_user_id' => $reply_user_id, 'pid' => $pid, 'create_time' => time() ]; $id = (new Comment())->insertGetId($info); if (!$reply_user_id) { $reply_user_id = PostsModel::where('id', $posts_id)->value('user_id'); } if ($reply_user_id != $this->uid) { PostsNotice::optionNotice($posts_id, $id, $reply_user_id, 2); $this->wsSendMsg($reply_user_id, 0, 'postsNotice'); } return success(lang('system.success')); } // 删除评论 public function delComment() { $posts_id = $this->request->param('posts_id'); if (empty($posts_id)) { return error(lang('system.fail')); } $comment_id = $this->request->param('comment_id'); if (empty($comment_id)) { return error(lang('system.fail')); } $existsWhere = [ 'id' => $comment_id, 'user_id' => $this->uid, 'type' => 1, 'relevance_id' => $posts_id ]; $exists = (new Comment())->where($existsWhere)->find(); if (!$exists) { return error(lang('system.fail')); } // 提醒用户取消删除提醒 $reply_user_id = $exists->reply_user_id; $exists->delete_time = time(); $exists->save(); // 删除用户提醒 if (!$reply_user_id) { $reply_user_id = PostsModel::where('id', $posts_id)->value('user_id'); } if ($reply_user_id) { PostsNotice::optionNotice($posts_id, $exists['id'], $reply_user_id, 2, 'del'); $this->wsSendMsg($reply_user_id, 0, 'postsNotice'); } return success(lang('system.success')); } // 提醒消息列表 public function getNoticeList() { $model = new PostsNotice(); $where = [ ['user_id', '=', $this->uid] ]; $field = '*'; $order = 'is_read asc,id desc'; $list = $this->paginate($model->where($where)->field($field)->order($order)); $data = []; if ($list) { $data = $list->toArray()['data']; foreach ($data as &$item) { // 第一张图 或是视频 $fileWhere = [ 'posts_id' => $item['posts_id'], 'type' => 1, 'delete_time' => 0 ]; $files = PostsFile::where($fileWhere) ->field('file_id,type') ->order('sort asc') ->find(); // 存在视频赋予默认图片 $item['file'] = []; $fileWhere['type'] = 2; $query = PostsFile::where($fileWhere)->find(); if ($query) { $item['file'] = ['src' => '/static/common/img/video.png']; } if ($files) { $filesWhere = ['file_id' => $files['file_id'], 'delete_time' => 0]; $files['src'] = File::where($filesWhere)->value('src'); $item['file'] = $files; } // 标记已读 if (!$item['is_read']) { PostsNotice::read($item['id']); } if ($item['type'] == 2) { $commentWhere = [ 'id' => $item['relevance_id'], 'delete_time' => 0, 'type' => 1 ]; $comment = Comment::where($commentWhere)->field('content,reply_user_id,user_id,relevance_id')->find(); $item['content'] = $comment['content'] ?? lang('posts.comment_del'); $item['reply_user'] = []; $item['option_user'] = []; if ($comment) { if ($comment['reply_user_id']) { $item['reply_user'] = $this->getFriendUserInfo($comment['reply_user_id']); } if ($comment['user_id']) { $item['option_user'] = $this->getFriendUserInfo($comment['user_id']); } } } $item['posts_user_id'] = PostsModel::where('id', $item['posts_id'])->value('user_id'); if ($item['type'] == 1) { $likesWhere = [ 'id' => $item['relevance_id'], 'type' => 1 ]; $Likes = Likes::where($likesWhere)->field('user_id,relevance_id')->find(); if ($Likes) { if ($Likes['user_id']) { $item['option_user'] = $this->getFriendUserInfo($Likes['user_id']); } } } // 用户信息 $item['user'] = $this->getFriendUserInfo($item['user_id']); // 评论回复 //unset($item['is_read']); } } return success('', $data,$list->total(),$list->currentPage()); } // 获取未读消息数量 public function getNoticeCount() { $uid = $this->uid; $count = PostsNotice::where(['user_id' => $uid, 'is_read' => 0])->count(); return success('', ['count' => $count ?? 0]); } }