197 lines
6.4 KiB
PHP
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;
|
|
}
|
|
}
|