post = $post; $this->postData = $postData; $this->postImgs = $postImgs; $this->postComment = $postComment; $this->postCollect = $postCollect; $this->postShare = $postShare; $this->postLog = $postLog; $this->detectionService = $detectionService; $this->topic = $topic; $this->memberFollowTopic = $memberFollowTopic; $this->categoryTopic = $categoryTopic; $this->aliYunVodService = $aliYunVodService; } /** * 发布内容 */ public function create($request) { //验证小号 $userInfo = $this->getUserInfo(); if (empty($userInfo)) { return jsonError('获取用户信息失败'); } if (!$userInfo['sns_status']) { return jsonError('您已被禁言'); } $isValid = 0; if ($userInfo['strength']) { $isValid = 1; } $oneHourTime = Carbon::now()->addHours(-1)->toDateTimeString(); $oneHourPostCount = $this->post->where('uid', $userInfo['uid'])->where('created_at', '>', $oneHourTime)->count(); if ($oneHourPostCount > 5) { return jsonError('创作欲望太强啦,休息一下,看看其他用户的内容吧!'); } $detectionText = $request['title'] . ',' . $request['content']; $detectionTextResult = $this->detectionService->checkText($detectionText); if ($detectionTextResult['code'] < 0) { return jsonError('内容违规,请修正哦'); } $topicIds = json_decode($request['topic_ids'], true); $topicCount = count($topicIds); if ($topicCount == 0 || $topicCount > 5) { return jsonError('所选话题必须1-5个'); } //验证话题 $hasTopicCount = $this->topic->whereIn('id', $topicIds)->count(); if ($topicCount != $hasTopicCount) { Log::error('所选话题非法' . $request['topic_ids']); return jsonError('所选话题非法'); } $imgs = []; if ($request['type'] == 'image') { $imgs = json_decode($request['imgs'], true); $imgCount = count($imgs); if ($imgCount == 0 || $imgCount > 9) { return jsonError('所传图集必须1-9个'); } } $allImg = array_merge($imgs, [$request['img']]); foreach ($allImg as &$img) { $img = $img . '&x-oss-process=image/resize,p_50/quality,Q_50'; } $detectionImageResult = $this->detectionService->checkImg($allImg); if ($detectionImageResult['code'] < 0) { Log::debug('图片违规,请修正哦' . json_encode($detectionImageResult)); return jsonError('图片违规,请修正哦'); } $videoUrl = ""; $videoId = ""; if (isset($request['video']) && $request['video']) { $videoId = $request['video']; for ($i = 0; $i < 3; $i++) { $videoUrl = $this->aliYunVodService->getPlayUrlByVideoId($request['video']); Log::debug('video-url:' . $videoUrl); if ($videoUrl) { break; } } if (empty($videoUrl)) { return jsonError('发布失败,请重试'); } } $fresh = (Carbon::now()->timestamp) - (Carbon::parse("2019-05-01 00:00:00")->timestamp); $score = $fresh / 43200; $data = [ 'uid' => $userInfo['uid'], 'username' => $userInfo['username'], 'mobile' => $userInfo['mobile'], 'avatar' => $userInfo['avatar'] ?? '', 'type' => $request['type'], 'img' => $request['img'], 'video' => $videoUrl, 'video_id' => $videoId, 'topic_ids' => implode(',', $topicIds), 'title' => isset($request['title']) ? $request['title'] : '', 'content' => $request['content'], 'location' => isset($request['location']) ? $request['location'] : '', 'is_suggest' => 0, 'is_hide' => 0, 'weight' => $score ]; $date = date('Y-m-d H:i:s'); DB::beginTransaction(); try { $post = $this->post->create($data); $postData = $this->postData->create([ 'post_id' => $post->id, 'pv' => 0, 'pv_real' => 0, 'dislike_count' => 0, 'praise_count' => 0, 'praise_real_count' => 0, 'share_count' => 0, 'share_real_count' => 0, 'comment_count' => 0, 'collect_count' => 0, 'collect_real_count' => 0, 'available_bean' => $this->availableBean(), 'will_collect_bean' => rand(100, 200), 'collect_bean' => 0 ]); if ($imgs) { $imgData = []; foreach ($imgs as $img) { $imgData[] = [ 'post_id' => $post->id, 'img' => $img, 'created_at' => $date, 'updated_at' => $date ]; } $this->postImgs->insert($imgData); } DB::commit(); Redis::zadd('post_trigger_type', $isValid, $post->id); foreach ($topicIds as $id) { Redis::zincrby('topic.user_uid' . $userInfo['uid'], 1, $id); Redis::zincrby('topic.just_use_count', 1, $id); } Redis::HSET('post_info_' . $post->id, 'id', $post->id, 'uid', $post->uid, 'type', $post->type, 'img', $post->img, 'imgs', json_encode($imgs), 'video', $post->video, 'topic_ids', $post->topic_ids, 'title', $post->title, 'content', $post->content, 'location', $post->location, 'pv', $postData->pv, 'dislike_count', $postData->dislike_count, 'praise_count', $postData->praise_count, 'share_count', $postData->share_count, 'comment_count', $postData->comment_count, 'collect_count', $postData->collect_count, 'available_bean', $postData->available_bean, 'will_collect_bean', $postData->will_collect_bean, 'create_bean', $postData->create_bean, 'collect_bean', $postData->collect_bean, 'created_at', $post->created_at); Log::info('post_create:' . $post->id . ',post_author:' . $post->uid . ',author_ip:' . getClientIp()); return jsonSuccess([ 'post_id' => $post->id, 'h5url' => config('customer.share_post_h5url') . "?post_id={$post->id}&invite_code={$userInfo['invite_code']}", 'bean' => $postData->available_bean, ]); } catch (QueryException $exception) { DB::rollBack(); Log::debug('发布内容失败:' . $exception->getMessage()); return jsonError('发布内容失败,请重试'); } } /** * 评论&回复 */ public function comment($request) { //验证小号 $userInfo = $this->getUserInfo(); if (empty($userInfo)) { return jsonError('获取用户信息失败'); } if (!$userInfo['sns_status']) { return jsonError('您已被禁言'); } $oneHourTime = Carbon::now()->addHours(-1)->toDateTimeString(); $oneHourCommentCount = $this->postComment->where('uid', $userInfo['uid'])->where('created_at', '>', $oneHourTime)->count(); if ($oneHourCommentCount > 59) { return jsonError('回复了这么多,休息休息,喝口水吧!'); } $detectionTextResult = $this->detectionService->checkText($request['content']); if ($detectionTextResult['code'] < 0) { return jsonError('内容违规,请修正哦'); } $post = $this->post->find($request['post_id']); if (!$post) { return jsonError('获取内容信息失败'); } $data = [ 'uid' => $userInfo['uid'], 'post_id' => $request['post_id'], 'parent_id' => 0, 'username' => $userInfo['username'], 'reply_uid' => 0, 'reply_username' => '', 'avatar' => $userInfo['avatar'] ?? '', 'content' => $request['content'], 'is_delete' => 0, ]; if (isset($request['parent_id']) && $request['parent_id'] != 0) { $comment = $this->postComment->find($request['parent_id']); if (!$comment || $comment->post_id != $post->id) { return jsonError('获取评论信息失败'); } if ($comment->parent_id) { return jsonError('只能回复评论'); } if ($comment->is_delete) { return jsonError('不能回复已删除评论'); } $data['parent_id'] = $request['parent_id']; if (isset($request['reply_uid']) && isset($request['reply_username'])) { $data['reply_uid'] = $request['reply_uid']; $data['reply_username'] = $request['reply_username']; } else { $data['reply_uid'] = 0; $data['reply_username'] = ''; } } DB::beginTransaction(); try { $newComment = $this->postComment->create($data); if ($newComment->parent_id) { $this->postComment->where('id', $newComment->parent_id)->increment('reply_count'); } DB::commit(); if ($newComment->parent_id) { Redis::DEL('post_new_reply_' . $newComment->parent_id); } else { Redis::DEL('post_new_comment_' . $newComment->post_id); } return jsonSuccess(['id' => $newComment->id], '评论成功'); } catch (QueryException $exception) { DB::rollBack(); Log::debug('评论内容失败:' . $exception->getMessage()); return jsonError('评论内容失败,请重试'); } } /** * 删除评论 */ public function commentDelete($request) { $userInfo = $this->getUserInfo(); if (empty($userInfo)) { return jsonError('获取用户信息失败'); } $comment = $this->postComment->find($request['id']); if (!$comment) { return jsonError('获取评论信息失败'); } if ($userInfo['uid'] != $comment->uid) { return jsonError('只能删除自己的评论'); } if ($comment->is_delete == 1) { return jsonError('该评论已经删除'); } DB::beginTransaction(); try { $comment->is_delete = 1; $comment->save(); DB::commit(); if (!$comment->parent_id) { Redis::DEL('post_new_comment_' . $comment->post_id); } else { Redis::DEL('post_new_reply_' . $comment->id); } Redis::SADD('delete_post_comment_ids', $comment->id); return jsonSuccess('删除评论成功'); } catch (QueryException $exception) { DB::rollBack(); Log::debug('删除评论:' . $request['id'] . $exception->getMessage()); return jsonError('删除评论失败'); } } /** * 内容列表 */ public function lists($request) { Log::debug('内容列表' . json_encode($request)); $perPage = isset($request['per_page']) ? $request['per_page'] : 20; return $this->post ->where(function ($query) use ($request) { if (isset($request['keyword'])) { $query->where('title', 'like', "%{$request['keyword']}%") ->orWhere('content', 'like', "%{$request['keyword']}%"); } }) ->where(function ($query) use ($request) { if (isset($request['topic_ids']) && $request['topic_ids']) { $topicIds = json_decode($request['topic_ids'], true); foreach ($topicIds as $key => $id) { if ($key == 0) { $query = $query->whereRaw('FIND_IN_SET(' . $id . ', topic_ids)'); } else { $query = $query->orWhereRaw('FIND_IN_SET(' . $id . ', topic_ids)'); } } } }) ->orderBy('weight', 'desc') ->orderBy('id', 'desc') ->paginate($perPage); } /** * 视频列表 */ public function video($request) { $perPage = isset($request['per_page']) ? $request['per_page'] : 20; $where = []; $id = 0; if (isset($request['id'])) { $id = $request['id']; } $where[] = ['type', 'video']; if (isset($request['type']) && $request['type']) { if ($request['type'] == 'hot') { $ids = Redis::get('hotVideoIds'); if (!$ids) { $ids = $this->hotVideoIds(); if (!$ids) { $ids = ''; } } Log::debug('热门视频ids' . $ids); return $this->post ->select('*', DB::raw("IF (id = {$id},1,0) as sort")) ->where($where) ->whereIn('id', explode(',', $ids)) ->orderBy('sort', 'desc') ->orderByRaw(DB::raw("FIELD(id,{$ids})")) ->paginate($perPage); } elseif ($request['type'] == 'one') { $where[] = ['id', $id]; return $this->post ->where($where) ->paginate($perPage); } } return $this->post ->select('*', DB::raw("IF (id = {$id},1,0) as sort")) ->where($where) ->where(function ($query) use ($request) { if (isset($request['topic_id']) && $request['topic_id']) { $query->whereRaw('FIND_IN_SET(' . $request['topic_id'] . ', topic_ids)'); } }) ->orderBy('sort', 'desc') ->orderBy('weight', 'desc') ->orderBy('id', 'desc') ->paginate($perPage); } /** * 个人中心内容列表 */ public function myPost($request, $uid) { $type = $request['type']; $perPage = isset($request['per_page']) ? $request['per_page'] : 18; $where = []; if ($type == 'create') { $where[] = ['post.uid', $uid]; $post = $this->post; $order = 'post.id'; } elseif ($type == 'collect') { $post = $this->post->withTrashed()->join('post_collect', 'post_collect.post_id', '=', 'post.id'); $where[] = ['post_collect.uid', $uid]; $order = 'post_collect.id'; } else { $post = $this->post->withTrashed()->join('post_share', 'post_share.post_id', '=', 'post.id'); $where[] = ['post_share.uid', $uid]; $order = 'post_share.updated_at'; } return $post ->select('post.*') ->where($where) ->orderBy($order, 'desc') ->paginate($perPage); } /** * 内容详情 */ public function detail($id) { return $this->post ->find($id); } /** * 内容是否存在 */ public function detailExists($id) { return $this->post->where('id', $id)->exists(); } /** * 推荐内容列表 */ public function suggestPost($request, $uid) { $perPage = isset($request['per_page']) ? $request['per_page'] : 20; if ($uid) { $blacklist = Redis::smembers('blacklist_' . $uid); } else { $blacklist = []; } $topicIds = []; if (isset($request['category_id']) && $request['category_id']) { $topicIds = $this->categoryTopic->where('category_id', $request['category_id'])->pluck('topic_id')->toArray(); } return $this->post ->where(function ($query) use ($blacklist) { if ($blacklist) { $query->whereNotIn('uid', $blacklist); } }) ->where(function ($query) use ($topicIds) { if ($topicIds) { foreach ($topicIds as $key => $id) { if ($key == 0) { $query = $query->whereRaw('FIND_IN_SET(' . $id . ', topic_ids)'); } else { $query = $query->orWhereRaw('FIND_IN_SET(' . $id . ', topic_ids)'); } } } }) ->where('is_hide', 0) ->orderBy('is_suggest', 'desc') ->orderBy('weight', 'desc') ->orderBy('id', 'desc') ->paginate($perPage); } /** * 话题内容 */ public function topicPost($request) { $perPage = isset($request['per_page']) ? $request['per_page'] : 20; return $this->post ->whereRaw('FIND_IN_SET(' . $request['id'] . ',topic_ids)') ->orderBy('id', 'desc') ->paginate($perPage); } /** * 评论列表 */ public function commentList($request) { $perPage = isset($request['per_page']) ? $request['per_page'] : 20; return $this->postComment ->where('post_id', $request['post_id']) ->where('parent_id', 0) ->orderBy('like_count', 'desc') ->orderBy('id', 'desc') ->paginate($perPage); } /** * 回复列表 */ public function replyList($request) { $perPage = isset($request['per_page']) ? $request['per_page'] : 20; return $this->postComment ->where('parent_id', $request['id']) ->orderBy('id', 'desc') ->paginate($perPage); } /** * 根据评论id获取内容id */ public function getPostId($commentId) { return $this->postComment ->where('id', $commentId) ->value('post_id'); } /** * 话题列表 */ public function topicList($request) { $perPage = isset($request['per_page']) ? $request['per_page'] : 20; $where = []; $topic = $this->topic; if (isset($request['name'])) { $where[] = ['topic.name', 'like', "%{$request['name']}%"]; } if (isset($request['category_id']) && $request['category_id']) { if ($request['category_id'] == -2) { $where[] = ['topic.is_hot', 1]; } else { $topic = $topic->join('category_topic', 'category_topic.topic_id', '=', 'topic.id')->select('topic.*', 'category_topic.id as cid'); $where[] = ['category_topic.category_id', $request['category_id']]; $where[] = ['topic.is_open', 1]; return $topic ->where($where) ->orderBy('cid', 'asc') ->paginate($perPage); } } return $topic ->where($where) ->orderBy('id', 'desc') ->paginate($perPage); } /** * 我的话题列表 */ public function myTopicList($request) { $perPage = isset($request['per_page']) ? $request['per_page'] : 20; $uid = 0; $user = $this->getUserInfo(); if ($user) { $uid = $user['uid']; } return $this->memberFollowTopic ->where('uid', $uid) ->orderBy('id', 'desc') ->paginate($perPage); } /** * 更新帖子统计数量 * @param $request * @return mixed */ public function updatePostData($request) { $postId = isset($request['post_id']) ? $request['post_id'] : 0; if (empty($postId)) { Log::debug("非帖子类操作,不操作帖子统计数量" . json_encode($request)); return true; } //帖子缓存信息key $postInfoKey = "post_info_" . $postId; $post = PostData::where('post_id', $postId)->first(); if (!$post) return true; $row = false; if (isset($request['behavior_flag']) && $request['behavior_flag'] == 'read') { $post->pv += 1; $post->pv_real += 1; Redis::HINCRBY($postInfoKey, 'pv', 1); $topicIdStr = Redis::HGET($postInfoKey, 'topic_ids'); if ($topicIdStr) { Log::debug('话题增加浏览量' . $topicIdStr); $topicIds = explode(',', $topicIdStr); foreach ($topicIds as $id) { $this->topic->where('id', $id)->increment('pv'); } } $row = $post->save(); Log::debug("帖子:" . $postId . "被阅读,pv +1"); } elseif (isset($request['behavior_flag']) && $request['behavior_flag'] == 'unlike') { //用户不喜欢帖子key $postUnLikeKey = "post_unlike_" . $postId; $post->dislike_count += 1; PostDislike::create(['uid' => $request['target_id'], 'post_id' => $request['post_id']]); Redis::sadd($postUnLikeKey, $request['target_id']); Redis::HINCRBY($postInfoKey, 'dislike_count', 1); $row = $post->save(); Log::debug("帖子:" . $postId . "被不喜欢,unlike +1"); } elseif (isset($request['behavior_flag']) && $request['behavior_flag'] == 'like') { //用户点赞帖子 $postLikeKey = "post_like_" . $postId; if ($request['behavior_value']) { $post->praise_count += 1; $post->praise_real_count += 1; PostLike::create(['uid' => $request['target_id'], 'post_id' => $request['post_id']]); Redis::sadd($postLikeKey, $request['target_id']); Redis::HINCRBY($postInfoKey, 'praise_count', 1); Log::debug("帖子:" . $postId . "被点赞,praise_count +1"); } else { $post->praise_count -= 1; $post->praise_real_count -= 1; PostLike::where(['uid' => $request['target_id'], 'post_id' => $request['post_id']])->delete(); Redis::srem($postLikeKey, $request['target_id']); Redis::HINCRBY($postInfoKey, 'praise_count', -1); Log::debug("帖子:" . $postId . "被取消点赞,praise_count -1"); } $row = $post->save(); } elseif (isset($request['behavior_flag']) && $request['behavior_flag'] == 'comment_like') { //用户点赞评论 $comment = PostComment::where('id', $request['comment_id'])->first(); $postLikeKey = "comment_like_" . $postId; if ($request['behavior_value']) { $comment->like_count += 1; PostCommentLike::create(['uid' => $request['target_id'], 'comment_id' => $request['comment_id']]); Redis::zadd($postLikeKey, $request['comment_id'], $request['target_id'] . '_' . $request['comment_id']); Log::debug("评论:" . $request['comment_id'] . "被点赞,like_count +1"); } else { $comment->like_count -= 1; PostCommentLike::where(['uid' => $request['target_id'], 'comment_id' => $request['comment_id']])->delete(); Redis::zrem($postLikeKey, $request['target_id'] . '_' . $request['comment_id']); Log::debug("评论:" . $request['comment_id'] . "被取消点赞,like_count -1"); } $row = $comment->save(); } elseif (isset($request['behavior_flag']) && $request['behavior_flag'] == 'forward') { $post->share_count += 1; $post->share_real_count += 1; Redis::HINCRBY($postInfoKey, 'share_count', 1); $shareRow = PostShare::where(['uid' => $request['target_id'], 'post_id' => $request['post_id']])->first(); if ($shareRow) { PostShare::where(['uid' => $request['target_id'], 'post_id' => $request['post_id']])->update(['uid' => $request['target_id'], 'post_id' => $request['post_id']]); } else { PostShare::create(['uid' => $request['target_id'], 'post_id' => $request['post_id']]); } $row = $post->save(); Log::debug("帖子:" . $postId . "被分享,share_count +1"); } elseif (isset($request['behavior_flag']) && $request['behavior_flag'] == 'comment') { $post->comment_count += 1; Redis::HINCRBY($postInfoKey, 'comment_count', 1); $row = $post->save(); Log::debug("帖子:" . $postId . "被评论,comment_count +1"); } elseif (isset($request['behavior_flag']) && $request['behavior_flag'] == 'collect') { //用户收藏帖子 $postCollectKey = "post_collect_" . $postId; if ($request['behavior_value']) { $post->collect_count += 1; $post->collect_real_count += 1; PostCollect::create(['uid' => $request['target_id'], 'post_id' => $request['post_id']]); Redis::sadd($postCollectKey, $request['target_id']); Redis::HINCRBY($postInfoKey, 'collect_count', 1); Log::debug("帖子:" . $postId . "被收藏,collect_count +1"); } else { $post->collect_count -= 1; $post->collect_real_count -= 1; PostCollect::where(['uid' => $request['target_id'], 'post_id' => $request['post_id']])->delete(); Redis::srem($postCollectKey, $request['target_id']); Redis::HINCRBY($postInfoKey, 'collect_count', -1); Log::debug("帖子:" . $postId . "被取消收藏,collect_count -1"); } $row = $post->save(); } $this->collectPostId($request['post_id']); return $row; } /** * 收集所有有操作的帖子,存入redis * 供后续计算帖子权重 * @param $id */ public function collectPostId($id) { $key = "community_calc_post_score"; Redis::sadd($key, $id); Log::debug('存入帖子' . $id . '到权重列表'); } /** * 话题详情 */ public function topicDetail($id) { return $this->topic ->find($id); } /** * 获取话题 */ public function getTopic($ids) { $topics = $this->topic ->whereIn('id', explode(',', $ids)) ->orderByRaw(DB::raw("FIELD(id,{$ids})")) ->get(); $data = []; foreach ($topics as $topic) { $data[] = [ 'id' => $topic->id, 'name' => $topic->name, 'img' => $topic->img, 'follow_count' => getNumber($topic->use_count + $topic->base_count), ]; } return $data; } /** * 获取内容视频组 */ public function getPostVideo($ids) { $posts = $this->post ->select('id', 'img', 'uid') ->whereIn('id', explode(',', $ids)) ->where('type', 'video') ->get(); foreach ($posts as &$post) { $user = $this->userInfo($post->uid); $post->username = $user['username']; $post->avatar = $user['avatar']; } return $posts; } //用户内容数,转发数,收藏数统计 public function memberPostStatistics($uid) { $postCount = $this->post->where('uid', $uid)->count(); $postCollectCount = $this->postCollect->where('uid', $uid)->count(); $postShareCount = $this->postShare->where('uid', $uid)->count(); $data = ['post_count' => $postCount, 'share_count' => $postShareCount, 'collect_count' => $postCollectCount]; return jsonSuccess($data); } /** * 删除内容 */ public function delete($request) { //验证用户信息 $userInfo = $this->getUserInfo(); if (empty($userInfo)) { return jsonError('获取用户信息失败'); } $post = $this->post->find($request['id']); if (!$post) { return jsonError('获取内容信息失败'); } if ($post->uid != $userInfo['uid']) { return jsonError('只能删除自己发布的内容'); } $logData = [ 'uid' => $userInfo['uid'], 'operator_type' => 'user', 'post_id' => $request['id'], 'username' => $userInfo['username'], 'log_type' => 'delete', 'content' => json_encode(['delete' => $request['id']]), ]; DB::beginTransaction(); try { $post->delete(); $this->postLog->create($logData); DB::commit(); Redis::SADD('delete_post_ids', $request['id']); Log::debug('删除内容失败:' . $request['id']); return jsonSuccess('删除内容成功'); } catch (QueryException $exception) { DB::rollBack(); Log::debug('删除内容失败:' . $request['id'] . $exception->getMessage()); return jsonError('删除内容失败,请重试'); } } /** * 内容评论数 */ public function getCommentCount($id) { $commentCount = 0; $post = $this->post->find($id); if ($post) { $commentCount = $post->data->comment_count; } return $commentCount; } /** * 内容评论数 */ public function checkImage($img) { return $this->detectionService->checkImg($img); } }