$articleId, 'parent_id' => 0, 'is_show' => 1, ]; $count = ArticleComment::where($where)->count(); $list = ArticleComment::where($where) ->order('id', 'desc') ->page($pageNo, $pageSize) ->select() ->toArray(); $userIds = array_column($list, 'user_id'); // 取子评论的user_id $commentIds = array_column($list, 'id'); $replies = []; if (!empty($commentIds)) { $repliesRaw = ArticleComment::where('parent_id', 'in', $commentIds) ->where('is_show', 1) ->order('id', 'asc') ->select() ->toArray(); $replyUserIds = array_column($repliesRaw, 'user_id'); $replyTargetUserIds = array_column($repliesRaw, 'reply_user_id'); $userIds = array_merge($userIds, $replyUserIds, $replyTargetUserIds); foreach ($repliesRaw as $r) { $replies[$r['parent_id']][] = $r; } } // 批量获取用户信息 $userIds = array_unique(array_filter($userIds)); $users = []; if (!empty($userIds)) { $usersRaw = User::whereIn('id', $userIds) ->field('id,nickname,avatar') ->select() ->toArray(); foreach ($usersRaw as $u) { $users[$u['id']] = $u; } } $defaultUser = ['nickname' => '匿名用户', 'avatar' => '']; foreach ($list as &$item) { $u = $users[$item['user_id']] ?? $defaultUser; $item['nickname'] = $u['nickname']; $item['avatar'] = $u['avatar']; $item['reply_list'] = []; if (isset($replies[$item['id']])) { foreach ($replies[$item['id']] as $reply) { $ru = $users[$reply['user_id']] ?? $defaultUser; $reply['nickname'] = $ru['nickname']; $reply['avatar'] = $ru['avatar']; $reply['reply_nickname'] = ''; if ($reply['reply_user_id'] > 0) { $tu = $users[$reply['reply_user_id']] ?? $defaultUser; $reply['reply_nickname'] = $tu['nickname']; } $item['reply_list'][] = $reply; } } } unset($item); return [ 'count' => $count, 'lists' => $list, 'page_no' => $pageNo, 'page_size' => $pageSize, ]; } /** * @notes 发布评论 */ public static function addComment($userId, $params) { Db::startTrans(); try { $comment = ArticleComment::create([ 'article_id' => $params['article_id'], 'user_id' => $userId, 'parent_id' => $params['parent_id'] ?? 0, 'reply_user_id' => $params['reply_user_id'] ?? 0, 'content' => $params['content'], ]); Article::where('id', $params['article_id']) ->inc('comment_count') ->update(); Db::commit(); return $comment->id; } catch (\Exception $e) { Db::rollback(); self::setError($e->getMessage()); return false; } } /** * @notes 点赞/踩 */ public static function vote($userId, $articleId, $voteType) { Db::startTrans(); try { $existing = ArticleVote::where([ 'article_id' => $articleId, 'user_id' => $userId, ])->findOrEmpty(); if (!$existing->isEmpty()) { if ($existing->vote_type == $voteType) { // 取消 $field = $voteType == ArticleVote::VOTE_LIKE ? 'like_count' : 'dislike_count'; $existing->delete(); Article::where('id', $articleId)->where($field, '>', 0)->dec($field)->update(); Db::commit(); return ['action' => 'cancel', 'vote_type' => $voteType]; } else { // 切换: 旧的减,新的加 $oldField = $existing->vote_type == ArticleVote::VOTE_LIKE ? 'like_count' : 'dislike_count'; $newField = $voteType == ArticleVote::VOTE_LIKE ? 'like_count' : 'dislike_count'; $existing->vote_type = $voteType; $existing->save(); Article::where('id', $articleId)->where($oldField, '>', 0)->dec($oldField)->update(); Article::where('id', $articleId)->inc($newField)->update(); Db::commit(); return ['action' => 'switch', 'vote_type' => $voteType]; } } else { // 新增 ArticleVote::create([ 'article_id' => $articleId, 'user_id' => $userId, 'vote_type' => $voteType, ]); $field = $voteType == ArticleVote::VOTE_LIKE ? 'like_count' : 'dislike_count'; Article::where('id', $articleId)->inc($field)->update(); Db::commit(); return ['action' => 'add', 'vote_type' => $voteType]; } } catch (\Exception $e) { Db::rollback(); self::setError($e->getMessage()); return false; } } /** * @notes 获取用户对文章的投票状态 */ public static function getVoteStatus($userId, $articleId) { if (empty($userId)) { return 0; } $vote = ArticleVote::where([ 'article_id' => $articleId, 'user_id' => $userId, ])->findOrEmpty(); return $vote->isEmpty() ? 0 : $vote->vote_type; } }