Files
sbnews/server/app/api/logic/ArticleInteractLogic.php
2026-06-11 12:15:29 +08:00

197 lines
6.4 KiB
PHP

<?php
namespace app\api\logic;
use app\common\logic\BaseLogic;
use app\common\model\article\Article;
use app\common\model\article\ArticleComment;
use app\common\model\article\ArticleVote;
use app\common\model\user\User;
use think\facade\Db;
/**
* 文章互动逻辑(评论/点赞/踩)
* Class ArticleInteractLogic
* @package app\api\logic
*/
class ArticleInteractLogic extends BaseLogic
{
/**
* @notes 评论列表
*/
public static function commentList($articleId, $pageNo = 1, $pageSize = 15)
{
$where = [
'article_id' => $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;
}
}