1
0
mirror of https://gitee.com/koogua/course-tencent-cloud.git synced 2025-08-06 14:31:39 +08:00

v1.3.5阶段提交

This commit is contained in:
koogua 2021-05-16 19:19:20 +08:00
parent cc19004c12
commit 6254ac94ca
61 changed files with 1162 additions and 280 deletions

View File

@ -133,6 +133,33 @@
<td><input class="layui-input" type="text" name="event_rule[answer_post][point]" value="{{ event_rule.answer_post.point }}" lay-verify="required"></td>
<td><input class="layui-input" type="text" name="event_rule[answer_post][limit]" value="{{ event_rule.answer_post.limit }}" lay-verify="required"></td>
</tr>
<tr>
<td>文章被赞</td>
<td>
<input type="radio" name="event_rule[article_liked][enabled]" value="1" title="是" {% if event_rule.article_liked.enabled == "1" %}checked="checked"{% endif %}>
<input type="radio" name="event_rule[article_liked][enabled]" value="0" title="否" {% if event_rule.article_liked.enabled == "0" %}checked="checked"{% endif %}>
</td>
<td><input class="layui-input" type="text" name="event_rule[article_liked][point]" value="{{ event_rule.article_liked.point }}" lay-verify="required"></td>
<td><input class="layui-input" type="text" name="event_rule[article_liked][limit]" value="{{ event_rule.article_liked.limit }}" lay-verify="required"></td>
</tr>
<tr>
<td>问题被赞</td>
<td>
<input type="radio" name="event_rule[question_liked][enabled]" value="1" title="是" {% if event_rule.question_liked.enabled == "1" %}checked="checked"{% endif %}>
<input type="radio" name="event_rule[question_liked][enabled]" value="0" title="否" {% if event_rule.question_liked.enabled == "0" %}checked="checked"{% endif %}>
</td>
<td><input class="layui-input" type="text" name="event_rule[question_liked][point]" value="{{ event_rule.question_liked.point }}" lay-verify="required"></td>
<td><input class="layui-input" type="text" name="event_rule[question_liked][limit]" value="{{ event_rule.question_liked.limit }}" lay-verify="required"></td>
</tr>
<tr>
<td>回答被赞</td>
<td>
<input type="radio" name="event_rule[answer_liked][enabled]" value="1" title="是" {% if event_rule.answer_liked.enabled == "1" %}checked="checked"{% endif %}>
<input type="radio" name="event_rule[answer_liked][enabled]" value="0" title="否" {% if event_rule.answer_liked.enabled == "0" %}checked="checked"{% endif %}>
</td>
<td><input class="layui-input" type="text" name="event_rule[answer_liked][point]" value="{{ event_rule.answer_liked.point }}" lay-verify="required"></td>
<td><input class="layui-input" type="text" name="event_rule[answer_liked][limit]" value="{{ event_rule.answer_liked.limit }}" lay-verify="required"></td>
</tr>
</tbody>
</table>
<br>

View File

@ -51,6 +51,12 @@
<span class="type">发布问题</span>
{% elseif value == 12 %}
<span class="type">发布回答</span>
{% elseif value == 13 %}
<span class="type">文章被赞</span>
{% elseif value == 14 %}
<span class="type">提问被赞</span>
{% elseif value == 15 %}
<span class="type">回答被赞</span>
{% endif %}
{%- endmacro %}
@ -86,7 +92,16 @@
{% set question_url = url({'for':'home.question.show','id':info.question.id}) %}
<p class="question"><a href="{{ question_url }}" target="_blank">{{ info.question.title }}</a></p>
{% elseif type == 12 %}
{% set question_url = url({'for':'home.question.show','id':info.question.id}) %}
<p class="answer"><a href="{{ question_url }}" target="_blank">{{ info.question.title }}</a></p>
{% elseif type == 13 %}
{% set article_url = url({'for':'home.article.show','id':info.article.id}) %}
<p class="article"><a href="{{ article_url }}" target="_blank">{{ info.article.title }}</a></p>
{% elseif type == 14 %}
{% set question_url = url({'for':'home.question.show','id':info.question.id}) %}
<p class="question"><a href="{{ question_url }}" target="_blank">{{ info.question.title }}</a></p>
{% elseif type == 15 %}
{% set question_url = url({'for':'home.question.show','id':info.question.id}) %}
<p class="answer"><a href="{{ question_url }}" target="_blank">{{ info.question.title }}</a></p>
{% endif %}
{%- endmacro %}

View File

@ -12,7 +12,9 @@
<img src="{{ item.owner.avatar }}!avatar_160" alt="{{ item.owner.name }}">
</a>
</span>
<span class="name">{{ item.owner.name }}</span>
<span class="name">
<a href="{{ owner_url }}" target="_blank">{{ item.owner.name }}</a>
</span>
</div>
<div class="content markdown-body">{{ item.content }}</div>
<div class="footer">

View File

@ -26,6 +26,13 @@ class AnswerLike extends Model
*/
public $user_id = 0;
/**
* 删除标识
*
* @var int
*/
public $deleted = 0;
/**
* 创建时间
*
@ -33,6 +40,13 @@ class AnswerLike extends Model
*/
public $create_time = 0;
/**
* 更新时间
*
* @var int
*/
public $update_time = 0;
public function getSource(): string
{
return 'kg_answer_like';
@ -43,4 +57,9 @@ class AnswerLike extends Model
$this->create_time = time();
}
public function beforeUpdate()
{
$this->update_time = time();
}
}

View File

@ -26,6 +26,13 @@ class ArticleFavorite extends Model
*/
public $user_id = 0;
/**
* 删除标识
*
* @var int
*/
public $deleted = 0;
/**
* 创建时间
*
@ -33,6 +40,13 @@ class ArticleFavorite extends Model
*/
public $create_time = 0;
/**
* 更新时间
*
* @var int
*/
public $update_time = 0;
public function getSource(): string
{
return 'kg_article_favorite';
@ -43,4 +57,9 @@ class ArticleFavorite extends Model
$this->create_time = time();
}
public function beforeUpdate()
{
$this->update_time = time();
}
}

View File

@ -26,6 +26,13 @@ class ArticleLike extends Model
*/
public $user_id = 0;
/**
* 删除标识
*
* @var int
*/
public $deleted = 0;
/**
* 创建时间
*
@ -33,6 +40,13 @@ class ArticleLike extends Model
*/
public $create_time = 0;
/**
* 更新时间
*
* @var int
*/
public $update_time = 0;
public function getSource(): string
{
return 'kg_article_like';
@ -43,4 +57,9 @@ class ArticleLike extends Model
$this->create_time = time();
}
public function beforeUpdate()
{
$this->update_time = time();
}
}

View File

@ -26,6 +26,13 @@ class ChapterLike extends Model
*/
public $user_id = 0;
/**
* 删除标识
*
* @var int
*/
public $deleted = 0;
/**
* 创建时间
*
@ -33,6 +40,13 @@ class ChapterLike extends Model
*/
public $create_time = 0;
/**
* 更新时间
*
* @var int
*/
public $update_time = 0;
public function getSource(): string
{
return 'kg_chapter_like';
@ -43,4 +57,9 @@ class ChapterLike extends Model
$this->create_time = time();
}
public function beforeUpdate()
{
$this->update_time = time();
}
}

View File

@ -26,6 +26,13 @@ class CommentLike extends Model
*/
public $user_id = 0;
/**
* 删除标识
*
* @var int
*/
public $deleted = 0;
/**
* 创建时间
*
@ -33,6 +40,13 @@ class CommentLike extends Model
*/
public $create_time = 0;
/**
* 更新时间
*
* @var int
*/
public $update_time = 0;
public function getSource(): string
{
return 'kg_comment_like';
@ -43,4 +57,9 @@ class CommentLike extends Model
$this->create_time = time();
}
public function beforeUpdate()
{
$this->update_time = time();
}
}

View File

@ -26,6 +26,13 @@ class ConsultLike extends Model
*/
public $user_id = 0;
/**
* 删除标识
*
* @var int
*/
public $deleted = 0;
/**
* 创建时间
*
@ -33,6 +40,13 @@ class ConsultLike extends Model
*/
public $create_time = 0;
/**
* 更新时间
*
* @var int
*/
public $update_time = 0;
public function getSource(): string
{
return 'kg_consult_like';
@ -43,4 +57,9 @@ class ConsultLike extends Model
$this->create_time = time();
}
public function beforeUpdate()
{
$this->update_time = time();
}
}

View File

@ -26,6 +26,13 @@ class CourseFavorite extends Model
*/
public $user_id = 0;
/**
* 删除标识
*
* @var int
*/
public $deleted = 0;
/**
* 创建时间
*
@ -33,6 +40,13 @@ class CourseFavorite extends Model
*/
public $create_time = 0;
/**
* 更新时间
*
* @var int
*/
public $update_time = 0;
public function getSource(): string
{
return 'kg_course_favorite';
@ -43,4 +57,9 @@ class CourseFavorite extends Model
$this->create_time = time();
}
public function beforeUpdate()
{
$this->update_time = time();
}
}

View File

@ -20,10 +20,10 @@ class PointHistory extends Model
const EVENT_ARTICLE_POST = 10; // 发布文章
const EVENT_QUESTION_POST = 11; // 发布问题
const EVENT_ANSWER_POST = 12; // 发布回答
const EVENT_ANSWER_ACCEPTED = 13; // 回答被采纳
const EVENT_ANSWER_LIKED = 14; // 回答被点赞
const EVENT_ARTICLE_LIKED = 15; // 文章被点赞
const EVENT_QUESTION_LIKED = 16; // 提问被点赞
const EVENT_ARTICLE_LIKED = 13; // 文章被点赞
const EVENT_QUESTION_LIKED = 14; // 提问被点赞
const EVENT_ANSWER_LIKED = 15; // 回答被点赞
const EVENT_ANSWER_ACCEPTED = 16; // 回答被采纳
/**
* 主键编号

View File

@ -26,6 +26,13 @@ class QuestionFavorite extends Model
*/
public $user_id = 0;
/**
* 删除标识
*
* @var int
*/
public $deleted = 0;
/**
* 创建时间
*
@ -33,6 +40,13 @@ class QuestionFavorite extends Model
*/
public $create_time = 0;
/**
* 更新时间
*
* @var int
*/
public $update_time = 0;
public function getSource(): string
{
return 'kg_question_favorite';
@ -43,4 +57,9 @@ class QuestionFavorite extends Model
$this->create_time = time();
}
public function beforeUpdate()
{
$this->update_time = time();
}
}

View File

@ -26,6 +26,13 @@ class QuestionLike extends Model
*/
public $user_id = 0;
/**
* 删除标识
*
* @var int
*/
public $deleted = 0;
/**
* 创建时间
*
@ -33,6 +40,13 @@ class QuestionLike extends Model
*/
public $create_time = 0;
/**
* 更新时间
*
* @var int
*/
public $update_time = 0;
public function getSource(): string
{
return 'kg_question_like';
@ -43,4 +57,9 @@ class QuestionLike extends Model
$this->create_time = time();
}
public function beforeUpdate()
{
$this->update_time = time();
}
}

View File

@ -26,6 +26,13 @@ class ReviewLike extends Model
*/
public $user_id = 0;
/**
* 删除标识
*
* @var int
*/
public $deleted = 0;
/**
* 创建时间
*
@ -33,6 +40,13 @@ class ReviewLike extends Model
*/
public $create_time = 0;
/**
* 更新时间
*
* @var int
*/
public $update_time = 0;
public function getSource(): string
{
return 'kg_review_like';
@ -43,4 +57,9 @@ class ReviewLike extends Model
$this->create_time = time();
}
public function beforeUpdate()
{
$this->update_time = time();
}
}

View File

@ -12,7 +12,6 @@ use App\Services\Logic\Notice\System\QuestionAnswered as QuestionAnsweredNotice;
use App\Services\Logic\Point\History\AnswerPost as AnswerPostPointHistory;
use App\Services\Logic\QuestionTrait;
use App\Services\Logic\Service as LogicService;
use App\Services\Sync\QuestionScore as QuestionScoreSync;
use App\Traits\Client as ClientTrait;
use App\Validators\Answer as AnswerValidator;
@ -38,7 +37,6 @@ class AnswerCreate extends LogicService
$answer = new AnswerModel();
$answer->published = $this->getPublishStatus($user);
$answer->content = $validator->checkContent($post['content']);
$answer->client_type = $this->getClientType();
$answer->client_ip = $this->getClientIp();
@ -58,9 +56,10 @@ class AnswerCreate extends LogicService
$question->update();
$this->syncQuestionScore($question);
$this->handleAnswerPostPoint($answer);
$this->handleQuestionAnsweredNotice($answer);
if ($user->id != $question->owner_id) {
$this->handleAnswerPostPoint($answer);
$this->handleQuestionAnsweredNotice($answer);
}
}
$this->eventsManager->fire('Answer:afterCreate', $this, $answer);
@ -95,13 +94,6 @@ class AnswerCreate extends LogicService
$user->update();
}
protected function syncQuestionScore(QuestionModel $question)
{
$sync = new QuestionScoreSync();
$sync->addItem($question->id);
}
protected function handleQuestionAnsweredNotice(AnswerModel $answer)
{
if ($answer->published != AnswerModel::PUBLISH_APPROVED) return;

View File

@ -9,7 +9,6 @@ use App\Repos\User as UserRepo;
use App\Services\Logic\AnswerTrait;
use App\Services\Logic\QuestionTrait;
use App\Services\Logic\Service as LogicService;
use App\Services\Sync\QuestionScore as QuestionScoreSync;
use App\Validators\Answer as AnswerValidator;
class AnswerDelete extends LogicService
@ -66,11 +65,4 @@ class AnswerDelete extends LogicService
$user->update();
}
protected function syncQuestionScore(QuestionModel $question)
{
$sync = new QuestionScoreSync();
$sync->addItem($question->id);
}
}

View File

@ -8,6 +8,7 @@ use App\Models\User as UserModel;
use App\Repos\AnswerLike as AnswerLikeRepo;
use App\Services\Logic\AnswerTrait;
use App\Services\Logic\Notice\System\AnswerLiked as AnswerLikedNotice;
use App\Services\Logic\Point\History\AnswerLiked as AnswerLikedPointHistory;
use App\Services\Logic\Service as LogicService;
use App\Validators\UserLimit as UserLimitValidator;
@ -30,9 +31,9 @@ class AnswerLike extends LogicService
$answerLike = $likeRepo->findAnswerLike($answer->id, $user->id);
if (!$answerLike) {
$isFirstTime = true;
$action = 'do';
if (!$answerLike) {
$answerLike = new AnswerLikeModel();
@ -41,9 +42,22 @@ class AnswerLike extends LogicService
$answerLike->create();
$this->incrAnswerLikeCount($answer);
} else {
$this->handleLikeNotice($answer, $user);
$isFirstTime = false;
$answerLike->deleted = $answerLike->deleted == 1 ? 0 : 1;
$answerLike->update();
}
$this->incrUserDailyAnswerLikeCount($user);
if ($answerLike->deleted == 0) {
$action = 'do';
$this->incrAnswerLikeCount($answer);
$this->eventsManager->fire('Answer:afterLike', $this, $answer);
@ -51,14 +65,20 @@ class AnswerLike extends LogicService
$action = 'undo';
$answerLike->delete();
$this->decrAnswerLikeCount($answer);
$this->eventsManager->fire('Answer:afterUndoLike', $this, $answer);
}
$this->incrUserDailyAnswerLikeCount($user);
$isOwner = $user->id == $answer->owner_id;
/**
* 仅首次点赞发送通知和奖励积分
*/
if ($isFirstTime && !$isOwner) {
$this->handleAnswerLikedNotice($answer, $user);
$this->handleAnswerLikedPoint($answerLike);
}
return [
'action' => $action,
@ -86,11 +106,18 @@ class AnswerLike extends LogicService
$this->eventsManager->fire('UserDailyCounter:incrAnswerLikeCount', $this, $user);
}
protected function handleLikeNotice(AnswerModel $answer, UserModel $sender)
protected function handleAnswerLikedNotice(AnswerModel $answer, UserModel $sender)
{
$notice = new AnswerLikedNotice();
$notice->handle($answer, $sender);
}
protected function handleAnswerLikedPoint(AnswerLikeModel $answerLike)
{
$service = new AnswerLikedPointHistory();
$service->handle($answerLike);
}
}

View File

@ -2,11 +2,9 @@
namespace App\Services\Logic\Answer;
use App\Models\Question as QuestionModel;
use App\Services\Logic\AnswerTrait;
use App\Services\Logic\QuestionTrait;
use App\Services\Logic\Service as LogicService;
use App\Services\Sync\QuestionScore as QuestionScoreSync;
use App\Traits\Client as ClientTrait;
use App\Validators\Answer as AnswerValidator;
@ -42,11 +40,4 @@ class AnswerUpdate extends LogicService
return $answer;
}
protected function syncQuestionScore(QuestionModel $question)
{
$sync = new QuestionScoreSync();
$sync->addItem($question->id);
}
}

View File

@ -6,14 +6,14 @@ use App\Library\Paginator\Query as PagerQuery;
use App\Models\Comment as CommentModel;
use App\Repos\Comment as CommentRepo;
use App\Services\Logic\AnswerTrait;
use App\Services\Logic\Comment\CommentListTrait;
use App\Services\Logic\Comment\ListTrait;
use App\Services\Logic\Service as LogicService;
class CommentList extends LogicService
{
use AnswerTrait;
use CommentListTrait;
use ListTrait;
public function handle($id)
{

View File

@ -5,6 +5,7 @@ namespace App\Services\Logic\Article;
use App\Models\Article as ArticleModel;
use App\Models\User as UserModel;
use App\Repos\User as UserRepo;
use App\Services\Logic\Point\History\ArticlePost as ArticlePostPointHistory;
use App\Services\Logic\Service as LogicService;
class ArticleCreate extends LogicService
@ -34,6 +35,10 @@ class ArticleCreate extends LogicService
$this->recountUserArticles($user);
if ($article->published == ArticleModel::PUBLISH_APPROVED) {
$this->handleArticlePostPoint($article);
}
$this->eventsManager->fire('Article:afterCreate', $this, $article);
return $article;
@ -55,4 +60,13 @@ class ArticleCreate extends LogicService
$user->update();
}
protected function handleArticlePostPoint(ArticleModel $article)
{
if ($article->published != ArticleModel::PUBLISH_APPROVED) return;
$service = new ArticlePostPointHistory();
$service->handle($article);
}
}

View File

@ -32,8 +32,6 @@ class ArticleFavorite extends LogicService
if (!$favorite) {
$action = 'do';
$favorite = new ArticleFavoriteModel();
$favorite->article_id = $article->id;
@ -41,27 +39,41 @@ class ArticleFavorite extends LogicService
$favorite->create();
} else {
$favorite->deleted = $favorite->deleted == 1 ? 0 : 1;
$favorite->update();
}
if ($favorite->deleted == 0) {
$action = 'do';
$this->incrArticleFavoriteCount($article);
$this->incrUserFavoriteCount($user);
$this->handleFavoriteNotice($article, $user);
$this->eventsManager->fire('Article:afterFavorite', $this, $article);
} else {
$action = 'undo';
$favorite->delete();
$this->decrArticleFavoriteCount($article);
$this->decrUserFavoriteCount($user);
$this->eventsManager->fire('Article:afterUndoFavorite', $this, $article);
}
$isOwner = $user->id == $article->owner_id;
/**
* 仅首次收藏发送通知
*/
if (!$favorite && !$isOwner) {
$this->handleFavoriteNotice($article, $user);
}
return [
'action' => $action,
'count' => $article->favorite_count,

View File

@ -47,9 +47,6 @@ class ArticleInfo extends LogicService
'summary' => $article->summary,
'tags' => $article->tags,
'content' => $content,
'category' => $category,
'owner' => $owner,
'me' => $me,
'private' => $article->private,
'closed' => $article->closed,
'published' => $article->published,
@ -62,6 +59,9 @@ class ArticleInfo extends LogicService
'favorite_count' => $article->favorite_count,
'create_time' => $article->create_time,
'update_time' => $article->update_time,
'category' => $category,
'owner' => $owner,
'me' => $me,
];
}
@ -87,7 +87,7 @@ class ArticleInfo extends LogicService
$like = $likeRepo->findArticleLike($article->id, $user->id);
if ($like) {
if ($like && $like->deleted == 0) {
$me['liked'] = 1;
}
@ -95,7 +95,7 @@ class ArticleInfo extends LogicService
$favorite = $favoriteRepo->findArticleFavorite($article->id, $user->id);
if ($favorite) {
if ($favorite && $favorite->deleted == 0) {
$me['favorited'] = 1;
}
}

View File

@ -8,6 +8,7 @@ use App\Models\User as UserModel;
use App\Repos\ArticleLike as ArticleLikeRepo;
use App\Services\Logic\ArticleTrait;
use App\Services\Logic\Notice\System\ArticleLiked as ArticleLikedNotice;
use App\Services\Logic\Point\History\ArticleLiked as ArticleLikedPointHistory;
use App\Services\Logic\Service as LogicService;
use App\Validators\UserLimit as UserLimitValidator;
@ -30,9 +31,9 @@ class ArticleLike extends LogicService
$articleLike = $likeRepo->findArticleLike($article->id, $user->id);
if (!$articleLike) {
$isFirstTime = true;
$action = 'do';
if (!$articleLike) {
$articleLike = new ArticleLikeModel();
@ -41,9 +42,22 @@ class ArticleLike extends LogicService
$articleLike->create();
$this->incrArticleLikeCount($article);
} else {
$this->handleLikeNotice($article, $user);
$isFirstTime = false;
$articleLike->deleted = $articleLike->deleted == 1 ? 0 : 1;
$articleLike->update();
}
$this->incrUserDailyArticleLikeCount($user);
if ($articleLike->deleted == 0) {
$action = 'do';
$this->incrArticleLikeCount($article);
$this->eventsManager->fire('Article:afterLike', $this, $article);
@ -51,14 +65,22 @@ class ArticleLike extends LogicService
$action = 'undo';
$articleLike->delete();
$this->decrArticleLikeCount($article);
$this->eventsManager->fire('Article:afterUndoLike', $this, $article);
}
$this->incrUserDailyArticleLikeCount($user);
$isOwner = $user->id == $article->owner_id;
$logger = $this->getLogger('http');
/**
* 仅首次点赞发送通知和奖励积分
*/
if ($isFirstTime && !$isOwner) {
$this->handleArticleLikedNotice($article, $user);
$this->handleArticleLikedPoint($articleLike);
}
return [
'action' => $action,
@ -86,11 +108,18 @@ class ArticleLike extends LogicService
$this->eventsManager->fire('UserDailyCounter:incrArticleLikeCount', $this, $user);
}
protected function handleLikeNotice(ArticleModel $article, UserModel $sender)
protected function handleArticleLikedNotice(ArticleModel $article, UserModel $sender)
{
$notice = new ArticleLikedNotice();
$notice->handle($article, $sender);
}
protected function handleArticleLikedPoint(ArticleLikeModel $articleLike)
{
$service = new ArticleLikedPointHistory();
$service->handle($articleLike);
}
}

View File

@ -6,14 +6,14 @@ use App\Library\Paginator\Query as PagerQuery;
use App\Models\Comment as CommentModel;
use App\Repos\Comment as CommentRepo;
use App\Services\Logic\ArticleTrait;
use App\Services\Logic\Comment\CommentListTrait;
use App\Services\Logic\Comment\ListTrait;
use App\Services\Logic\Service as LogicService;
class CommentList extends LogicService
{
use ArticleTrait;
use CommentListTrait;
use ListTrait;
public function handle($id)
{

View File

@ -78,7 +78,7 @@ class ChapterInfo extends LogicService
$like = $likeRepo->findChapterLike($chapter->id, $user->id);
if ($like) {
if ($like && $like->deleted == 0) {
$me['liked'] = 1;
}

View File

@ -31,8 +31,6 @@ class ChapterLike extends LogicService
if (!$chapterLike) {
$action = 'do';
$chapterLike = new ChapterLikeModel();
$chapterLike->chapter_id = $chapter->id;
@ -40,19 +38,28 @@ class ChapterLike extends LogicService
$chapterLike->create();
} else {
$chapterLike->deleted = $chapterLike->deleted == 1 ? 0 : 1;
$chapterLike->update();
}
$this->incrUserDailyChapterLikeCount($user);
if ($chapterLike->deleted == 0) {
$action = 'do';
$this->incrChapterLikeCount($chapter);
} else {
$action = 'undo';
$chapterLike->delete();
$this->decrChapterLikeCount($chapter);
}
$this->incrUserDailyChapterLikeCount($user);
return [
'action' => $action,
'count' => $chapter->like_count,

View File

@ -6,14 +6,14 @@ use App\Library\Paginator\Query as PagerQuery;
use App\Models\Comment as CommentModel;
use App\Repos\Comment as CommentRepo;
use App\Services\Logic\ChapterTrait;
use App\Services\Logic\Comment\CommentListTrait;
use App\Services\Logic\Comment\ListTrait;
use App\Services\Logic\Service as LogicService;
class CommentList extends LogicService
{
use ChapterTrait;
use CommentListTrait;
use ListTrait;
public function handle($id)
{

View File

@ -0,0 +1,75 @@
<?php
namespace App\Services\Logic\Comment;
use App\Models\Answer as AnswerModel;
use App\Models\Article as ArticleModel;
use App\Models\Comment as CommentModel;
use App\Models\Question as QuestionModel;
use App\Models\User as UserModel;
use App\Services\Logic\Notice\System\AnswerCommented as AnswerCommentedNotice;
use App\Services\Logic\Notice\System\ArticleCommented as ArticleCommentedNotice;
use App\Services\Logic\Notice\System\QuestionCommented as QuestionCommentedNotice;
use App\Services\Logic\Point\History\CommentPost as CommentPostPointHistory;
trait AfterCreateTrait
{
use CountTrait;
protected function handleNoticeAndPoint($item, CommentModel $comment, UserModel $user)
{
if ($comment->published != CommentModel::PUBLISH_APPROVED) return;
if ($item instanceof ArticleModel) {
$this->incrArticleCommentCount($item);
if ($user->id != $item->owner_id) {
$this->handleArticleCommentedNotice($item, $comment);
$this->handleCommentPostPoint($comment);
}
} elseif ($item instanceof QuestionModel) {
$this->incrQuestionCommentCount($item);
if ($user->id != $item->owner_id) {
$this->handleQuestionCommentedNotice($item, $comment);
$this->handleCommentPostPoint($comment);
}
} elseif ($item instanceof AnswerModel) {
$this->incrAnswerCommentCount($item);
if ($user->id != $item->owner_id) {
$this->handleAnswerCommentedNotice($item, $comment);
$this->handleCommentPostPoint($comment);
}
}
}
protected function handleArticleCommentedNotice(ArticleModel $article, CommentModel $comment)
{
$notice = new ArticleCommentedNotice();
$notice->handle($article, $comment);
}
protected function handleQuestionCommentedNotice(QuestionModel $question, CommentModel $comment)
{
$notice = new QuestionCommentedNotice();
$notice->handle($question, $comment);
}
protected function handleAnswerCommentedNotice(AnswerModel $answer, CommentModel $comment)
{
$notice = new AnswerCommentedNotice();
$notice->handle($answer, $comment);
}
protected function handleCommentPostPoint(CommentModel $comment)
{
if ($comment->published != CommentModel::PUBLISH_APPROVED) return;
$service = new CommentPostPointHistory();
$service->handle($comment);
}
}

View File

@ -3,11 +3,6 @@
namespace App\Services\Logic\Comment;
use App\Models\Comment as CommentModel;
use App\Services\Logic\ArticleTrait;
use App\Services\Logic\ChapterTrait;
use App\Services\Logic\Notice\System\ArticleCommented as ArticleCommentedNotice;
use App\Services\Logic\Notice\System\ChapterCommented as ChapterCommentedNotice;
use App\Services\Logic\Point\History\CommentPost as CommentPostPointHistory;
use App\Services\Logic\Service as LogicService;
use App\Traits\Client as ClientTrait;
use App\Validators\Comment as CommentValidator;
@ -16,10 +11,9 @@ use App\Validators\UserLimit as UserLimitValidator;
class CommentCreate extends LogicService
{
use ArticleTrait;
use ChapterTrait;
use AfterCreateTrait;
use CountTrait;
use ClientTrait;
use CommentCountTrait;
public function handle()
{
@ -33,7 +27,7 @@ class CommentCreate extends LogicService
$validator = new CommentValidator();
$validator->checkItemType($post['item_type']);
$item = $validator->checkItem($post['item_type'], $post['item_id']);
$comment = new CommentModel();
@ -56,48 +50,13 @@ class CommentCreate extends LogicService
$this->incrUserDailyCommentCount($user);
$this->incrItemCommentCount($comment);
$this->handlePostNotice($comment);
$this->handlePostPoint($comment);
if ($comment->published == CommentModel::PUBLISH_APPROVED) {
$this->handleNoticeAndPoint($item, $comment, $user);
}
$this->eventsManager->fire('Comment:afterCreate', $this, $comment);
return $comment;
}
protected function handlePostNotice(CommentModel $comment)
{
if ($comment->item_type == CommentModel::ITEM_CHAPTER) {
$chapter = $this->checkChapter($comment->item_id);
$this->incrChapterCommentCount($chapter);
$notice = new ChapterCommentedNotice();
$notice->handle($comment);
} elseif ($comment->item_type == CommentModel::ITEM_ARTICLE) {
$article = $this->checkArticle($comment->item_id);
$this->incrArticleCommentCount($article);
$notice = new ArticleCommentedNotice();
$notice->handle($comment);
}
}
protected function handlePostPoint(CommentModel $comment)
{
if ($comment->published != CommentModel::PUBLISH_APPROVED) return;
$service = new CommentPostPointHistory();
$service->handle($comment);
}
}

View File

@ -10,7 +10,7 @@ class CommentDelete extends LogicService
{
use CommentTrait;
use CommentCountTrait;
use CountTrait;
public function handle($id)
{

View File

@ -32,8 +32,6 @@ class CommentLike extends LogicService
if (!$commentLike) {
$action = 'do';
$commentLike = new CommentLikeModel();
$commentLike->comment_id = $comment->id;
@ -41,25 +39,41 @@ class CommentLike extends LogicService
$commentLike->create();
} else {
$commentLike->comment_id = $commentLike->deleted == 1 ? 0 : 1;
$commentLike->update();
$this->decrCommentLikeCount($comment);
}
if ($commentLike->deleted == 0) {
$action = 'do';
$this->incrCommentLikeCount($comment);
$this->incrUserDailyCommentLikeCount($user);
$this->handleLikeNotice($comment, $user);
$this->eventsManager->fire('Comment:afterLike', $this, $comment);
} else {
$action = 'undo';
$commentLike->delete();
$this->decrCommentLikeCount($comment);
$this->eventsManager->fire('Comment:afterUndoLike', $this, $comment);
}
$isOwner = $user->id == $comment->owner_id;
/**
* 仅首次点赞发送通知
*/
if (!$commentLike && $isOwner) {
$this->handleCommentLikedNotice($comment, $user);
}
return [
'action' => $action,
'count' => $comment->like_count,
@ -87,7 +101,7 @@ class CommentLike extends LogicService
$this->eventsManager->fire('UserDailyCounter:incrCommentLikeCount', $this, $user);
}
protected function handleLikeNotice(CommentModel $comment, UserModel $sender)
protected function handleCommentLikedNotice(CommentModel $comment, UserModel $sender)
{
$notice = new CommentLikedNotice();

View File

@ -10,7 +10,7 @@ use App\Services\Logic\Service as LogicService;
class CommentList extends LogicService
{
use CommentListTrait;
use ListTrait;
public function handle()
{

View File

@ -4,8 +4,6 @@ namespace App\Services\Logic\Comment;
use App\Models\Comment as CommentModel;
use App\Services\Logic\CommentTrait;
use App\Services\Logic\Notice\System\CommentReplied as CommentRepliedNotice;
use App\Services\Logic\Point\History\CommentPost as CommentPostPointHistory;
use App\Services\Logic\Service as LogicService;
use App\Traits\Client as ClientTrait;
use App\Validators\Comment as CommentValidator;
@ -14,9 +12,10 @@ use App\Validators\UserLimit as UserLimitValidator;
class CommentReply extends LogicService
{
use ClientTrait;
use AfterCreateTrait;
use CommentTrait;
use CommentCountTrait;
use CountTrait;
use ClientTrait;
public function handle($id)
{
@ -41,6 +40,11 @@ class CommentReply extends LogicService
'owner_id' => $user->id,
];
$item = $validator->checkItem($comment->item_type, $comment->item_id);
/**
* 子评论中回复用户
*/
if ($comment->parent_id > 0) {
$parent = $validator->checkParent($comment->parent_id);
$data['parent_id'] = $parent->id;
@ -60,37 +64,16 @@ class CommentReply extends LogicService
$reply->create($data);
$parent = $this->checkComment($reply->parent_id);
$this->incrUserDailyCommentCount($user);
$this->incrCommentReplyCount($parent);
$this->incrItemCommentCount($reply);
$this->handlePostNotice($reply);
$this->handlePostPoint($reply);
if ($reply->published == CommentModel::PUBLISH_APPROVED) {
$this->incrCommentReplyCount($parent);
$this->handleNoticeAndPoint($item, $reply, $user);
}
$this->eventsManager->fire('Comment:afterReply', $this, $reply);
return $reply;
}
protected function handlePostNotice(CommentModel $comment)
{
$notice = new CommentRepliedNotice();
$notice->handle($comment);
}
protected function handlePostPoint(CommentModel $comment)
{
if ($comment->published != CommentModel::PUBLISH_APPROVED) return;
$service = new CommentPostPointHistory();
$service->handle($comment);
}
}

View File

@ -2,63 +2,19 @@
namespace App\Services\Logic\Comment;
use App\Models\Answer as AnswerModel;
use App\Models\Article as ArticleModel;
use App\Models\Chapter as ChapterModel;
use App\Models\Comment as CommentModel;
use App\Models\Question as QuestionModel;
use App\Models\User as UserModel;
use App\Services\Logic\ArticleTrait;
use App\Services\Logic\ChapterTrait;
use App\Services\Logic\Notice\System\ArticleCommented as ArticleCommentedNotice;
use App\Services\Logic\Notice\System\ChapterCommented as ChapterCommentedNotice;
use App\Repos\Chapter as ChapterRepo;
use Phalcon\Di as Di;
use Phalcon\Events\Manager as EventsManager;
trait CommentCountTrait
trait CountTrait
{
use ArticleTrait;
use ChapterTrait;
protected function incrItemCommentCount(CommentModel $comment)
{
if ($comment->item_type == CommentModel::ITEM_CHAPTER) {
$chapter = $this->checkChapter($comment->item_id);
$this->incrChapterCommentCount($chapter);
$notice = new ChapterCommentedNotice();
$notice->handle($comment);
} elseif ($comment->item_type == CommentModel::ITEM_ARTICLE) {
$article = $this->checkArticle($comment->item_id);
$this->incrArticleCommentCount($article);
$notice = new ArticleCommentedNotice();
$notice->handle($comment);
}
}
protected function decrItemCommentCount(CommentModel $comment)
{
if ($comment->item_type == CommentModel::ITEM_CHAPTER) {
$chapter = $this->checkChapter($comment->item_id);
$this->decrChapterCommentCount($chapter);
} elseif ($comment->item_type == CommentModel::ITEM_ARTICLE) {
$article = $this->checkArticle($comment->item_id);
$this->decrArticleCommentCount($article);
}
}
protected function incrCommentReplyCount(CommentModel $comment)
{
$comment->reply_count += 1;
@ -72,7 +28,7 @@ trait CommentCountTrait
$chapter->update();
$parent = $this->checkChapter($chapter->parent_id);
$parent = $this->findChapter($chapter->parent_id);
$parent->comment_count += 1;
@ -86,6 +42,20 @@ trait CommentCountTrait
$article->update();
}
protected function incrQuestionCommentCount(QuestionModel $question)
{
$question->comment_count += 1;
$question->update();
}
protected function incrAnswerCommentCount(AnswerModel $answer)
{
$answer->comment_count += 1;
$answer->update();
}
protected function decrCommentReplyCount(CommentModel $comment)
{
if ($comment->reply_count > 0) {
@ -101,7 +71,7 @@ trait CommentCountTrait
$chapter->update();
}
$parent = $this->checkChapter($chapter->parent_id);
$parent = $this->findChapter($chapter->parent_id);
if ($parent->comment_count > 0) {
$parent->comment_count -= 1;
@ -117,6 +87,22 @@ trait CommentCountTrait
}
}
protected function decrQuestionCommentCount(QuestionModel $question)
{
if ($question->comment_count > 0) {
$question->comment_count -= 1;
$question->update();
}
}
protected function decrAnswerCommentCount(AnswerModel $answer)
{
if ($answer->comment_count > 0) {
$answer->comment_count += 1;
$answer->update();
}
}
protected function incrUserDailyCommentCount(UserModel $user)
{
/**
@ -127,4 +113,11 @@ trait CommentCountTrait
$eventsManager->fire('UserDailyCounter:incrCommentCount', $this, $user);
}
protected function findChapter($id)
{
$chapterRepo = new ChapterRepo();
return $chapterRepo->findById($id);
}
}

View File

@ -5,7 +5,7 @@ namespace App\Services\Logic\Comment;
use App\Builders\CommentList as CommentListBuilder;
use App\Repos\CommentLike as CommentLikeRepo;
trait CommentListTrait
trait ListTrait
{
public function handleComments($pager)
@ -58,8 +58,13 @@ trait CommentListTrait
$likedIds = [];
if ($user->id > 0) {
$likes = $likeRepo->findByUserId($user->id);
$likedIds = array_column($likes->toArray(), 'comment_id');
$likes = $likeRepo->findByUserId($user->id)
->filter(function ($like) {
if ($like->deleted == 0) {
return $like;
}
});
$likedIds = array_column($likes, 'comment_id');
}
$result = [];

View File

@ -12,15 +12,17 @@ class ReplyList extends LogicService
{
use CommentTrait;
use CommentListTrait;
use ListTrait;
public function handle($id)
{
$comment = $this->checkComment($id);
$pagerQuery = new PagerQuery();
$params = $pagerQuery->getParams();
$params['parent_id'] = $id;
$params['parent_id'] = $comment->id;
$params['published'] = CommentModel::PUBLISH_APPROVED;
$params['deleted'] = 0;

View File

@ -32,8 +32,6 @@ class ConsultLike extends LogicService
if (!$consultLike) {
$action = 'do';
$consultLike = new ConsultLikeModel();
$consultLike->consult_id = $consult->id;
@ -41,9 +39,20 @@ class ConsultLike extends LogicService
$consultLike->create();
$this->incrConsultLikeCount($consult);
} else {
$this->handleLikeNotice($consult, $user);
$consultLike->deleted = $consultLike->deleted == 1 ? 0 : 1;
$consultLike->update();
}
$this->incrUserDailyConsultLikeCount($user);
if ($consultLike->deleted == 0) {
$action = 'do';
$this->incrConsultLikeCount($consult);
$this->eventsManager->fire('Consult:afterLike', $this, $consult);
@ -51,14 +60,19 @@ class ConsultLike extends LogicService
$action = 'undo';
$consultLike->delete();
$this->decrConsultLikeCount($consult);
$this->eventsManager->fire('Consult:afterUndoLike', $this, $consult);
}
$this->incrUserDailyConsultLikeCount($user);
$isOwner = $user->id == $consult->owner_id;
/**
* 仅首次点赞发送通知
*/
if (!$consultLike && !$isOwner) {
$this->handleConsultLikedNotice($consult, $user);
}
return [
'action' => $action,
@ -86,7 +100,7 @@ class ConsultLike extends LogicService
$this->eventsManager->fire('UserDailyCounter:incrConsultLikeCount', $this, $user);
}
protected function handleLikeNotice(ConsultModel $consult, UserModel $sender)
protected function handleConsultLikedNotice(ConsultModel $consult, UserModel $sender)
{
$notice = new ConsultLikedNotice();

View File

@ -31,8 +31,6 @@ class CourseFavorite extends LogicService
if (!$favorite) {
$action = 'do';
$favorite = new CourseFavoriteModel();
$favorite->course_id = $course->id;
@ -40,6 +38,17 @@ class CourseFavorite extends LogicService
$favorite->create();
} else {
$favorite->deleted = $favorite->deleted == 1 ? 0 : 1;
$favorite->update();
}
if ($favorite->deleted == 0) {
$action = 'do';
$this->incrCourseFavoriteCount($course);
$this->incrUserFavoriteCount($user);
@ -47,8 +56,6 @@ class CourseFavorite extends LogicService
$action = 'undo';
$favorite->delete();
$this->decrCourseFavoriteCount($course);
$this->decrUserFavoriteCount($user);
}

View File

@ -48,7 +48,7 @@ class CourseInfo extends LogicService
$favorite = $favoriteRepo->findCourseFavorite($course->id, $user->id);
if ($favorite) {
if ($favorite && $favorite->deleted == 0) {
$me['favorited'] = 1;
}

View File

@ -0,0 +1,43 @@
<?php
namespace App\Services\Logic\Notice\System;
use App\Models\Answer as AnswerModel;
use App\Models\Comment as CommentModel;
use App\Models\Notification as NotificationModel;
use App\Repos\Question as QuestionRepo;
use App\Services\Logic\Service as LogicService;
class AnswerCommented extends LogicService
{
public function handle(AnswerModel $answer, CommentModel $comment)
{
$answerSummary = kg_substr($answer->summary, 0, 32);
$commentContent = kg_substr($comment->content, 0, 32);
$question = $this->findQuestion($answer->question_id);
$notification = new NotificationModel();
$notification->sender_id = $comment->owner_id;
$notification->receiver_id = $answer->owner_id;
$notification->event_id = $comment->id;
$notification->event_type = NotificationModel::TYPE_ANSWER_COMMENTED;
$notification->event_info = [
'question' => ['id' => $question->id, 'title' => $question->title],
'answer' => ['id' => $answer->id, 'summary' => $answerSummary],
'comment' => ['id' => $comment->id, 'content' => $commentContent],
];
$notification->create();
}
protected function findQuestion($id)
{
$questionRepo = new QuestionRepo();
return $questionRepo->findById($id);
}
}

View File

@ -2,21 +2,18 @@
namespace App\Services\Logic\Notice\System;
use App\Models\Article as ArticleModel;
use App\Models\Comment as CommentModel;
use App\Models\Notification as NotificationModel;
use App\Repos\Article as ArticleRepo;
use App\Repos\User as UserRepo;
use App\Services\Logic\Service as LogicService;
class ArticleCommented extends LogicService
{
public function handle(CommentModel $comment)
public function handle(ArticleModel $article, CommentModel $comment)
{
$commentContent = kg_substr($comment->content, 0, 32);
$article = $this->findArticle($comment->item_id);
$notification = new NotificationModel();
$notification->sender_id = $comment->owner_id;
@ -31,18 +28,4 @@ class ArticleCommented extends LogicService
$notification->create();
}
protected function findArticle($id)
{
$articleRepo = new ArticleRepo();
return $articleRepo->findById($id);
}
protected function findUser($id)
{
$userRepo = new UserRepo();
return $userRepo->findById($id);
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace App\Services\Logic\Notice\System;
use App\Models\Comment as CommentModel;
use App\Models\Notification as NotificationModel;
use App\Models\Question as QuestionModel;
use App\Services\Logic\Service as LogicService;
class QuestionCommented extends LogicService
{
public function handle(QuestionModel $question, CommentModel $comment)
{
$commentContent = kg_substr($comment->content, 0, 32);
$notification = new NotificationModel();
$notification->sender_id = $comment->owner_id;
$notification->receiver_id = $question->owner_id;
$notification->event_id = $comment->id;
$notification->event_type = NotificationModel::TYPE_QUESTION_COMMENTED;
$notification->event_info = [
'question' => ['id' => $question->id, 'title' => $question->title],
'comment' => ['id' => $comment->id, 'content' => $commentContent],
];
$notification->create();
}
}

View File

@ -31,6 +31,7 @@ class AnswerAccepted extends PointHistory
if ($eventPoint <= 0) return;
$eventId = $answer->id;
$eventType = PointHistoryModel::EVENT_ANSWER_ACCEPTED;
$historyRepo = new PointHistoryRepo();

View File

@ -36,6 +36,7 @@ class AnswerLiked extends PointHistory
if ($dailyPointLimit <= 0) return;
$eventId = $answerLike->id;
$eventType = PointHistoryModel::EVENT_ANSWER_LIKED;
$historyRepo = new PointHistoryRepo();

View File

@ -35,6 +35,7 @@ class AnswerPost extends PointHistory
if ($dailyPointLimit <= 0) return;
$eventId = $answer->id;
$eventType = PointHistoryModel::EVENT_ANSWER_POST;
$historyRepo = new PointHistoryRepo();

View File

@ -0,0 +1,81 @@
<?php
namespace App\Services\Logic\Point\History;
use App\Models\ArticleLike as ArticleLikeModel;
use App\Models\PointHistory as PointHistoryModel;
use App\Repos\Article as ArticleRepo;
use App\Repos\PointHistory as PointHistoryRepo;
use App\Repos\User as UserRepo;
use App\Services\Logic\Point\PointHistory;
class ArticleLiked extends PointHistory
{
public function handle(ArticleLikeModel $articleLike)
{
$setting = $this->getSettings('point');
$pointEnabled = $setting['enabled'] ?? 0;
if ($pointEnabled == 0) return;
$eventRule = json_decode($setting['event_rule'], true);
$eventEnabled = $eventRule['article_liked']['enabled'] ?? 0;
if ($eventEnabled == 0) return;
$eventPoint = $eventRule['article_liked']['point'] ?? 0;
if ($eventPoint <= 0) return;
$dailyPointLimit = $eventRule['article_liked']['limit'] ?? 0;
if ($dailyPointLimit <= 0) return;
$eventId = $articleLike->id;
$eventType = PointHistoryModel::EVENT_ARTICLE_LIKED;
$historyRepo = new PointHistoryRepo();
$history = $historyRepo->findEventHistory($eventId, $eventType);
if ($history) return;
$articleRepo = new ArticleRepo();
$article = $articleRepo->findById($articleLike->article_id);
/**
* @todo 使用缓存优化
*/
$dailyPoints = $historyRepo->sumUserDailyEventPoints($article->owner_id, $eventType, date('Ymd'));
if ($dailyPoints >= $dailyPointLimit) return;
$userRepo = new UserRepo();
$user = $userRepo->findById($article->owner_id);
$eventInfo = [
'article' => [
'id' => $article->id,
'title' => $article->title,
]
];
$history = new PointHistoryModel();
$history->user_id = $user->id;
$history->user_name = $user->name;
$history->event_id = $eventId;
$history->event_type = $eventType;
$history->event_info = $eventInfo;
$history->event_point = $eventPoint;
$this->handlePointHistory($history);
}
}

View File

@ -34,6 +34,7 @@ class ArticlePost extends PointHistory
if ($dailyPointLimit <= 0) return;
$eventId = $article->id;
$eventType = PointHistoryModel::EVENT_ARTICLE_POST;
$historyRepo = new PointHistoryRepo();

View File

@ -32,6 +32,7 @@ class ChapterStudy extends PointHistory
if ($eventPoint <= 0) return;
$eventId = $chapterUser->id;
$eventType = PointHistoryModel::EVENT_CHAPTER_STUDY;
$historyRepo = new PointHistoryRepo();

View File

@ -34,6 +34,7 @@ class CommentPost extends PointHistory
if ($dailyPointLimit <= 0) return;
$eventId = $comment->id;
$eventType = PointHistoryModel::EVENT_COMMENT_POST;
$historyRepo = new PointHistoryRepo();

View File

@ -31,6 +31,7 @@ class CourseReview extends PointHistory
if ($eventPoint <= 0) return;
$eventId = $review->id;
$eventType = PointHistoryModel::EVENT_COURSE_REVIEW;
$historyRepo = new PointHistoryRepo();

View File

@ -0,0 +1,81 @@
<?php
namespace App\Services\Logic\Point\History;
use App\Models\PointHistory as PointHistoryModel;
use App\Models\QuestionLike as QuestionLikeModel;
use App\Repos\PointHistory as PointHistoryRepo;
use App\Repos\Question as QuestionRepo;
use App\Repos\User as UserRepo;
use App\Services\Logic\Point\PointHistory;
class QuestionLiked extends PointHistory
{
public function handle(QuestionLikeModel $questionLike)
{
$setting = $this->getSettings('point');
$pointEnabled = $setting['enabled'] ?? 0;
if ($pointEnabled == 0) return;
$eventRule = json_decode($setting['event_rule'], true);
$eventEnabled = $eventRule['question_liked']['enabled'] ?? 0;
if ($eventEnabled == 0) return;
$eventPoint = $eventRule['question_liked']['point'] ?? 0;
if ($eventPoint <= 0) return;
$dailyPointLimit = $eventRule['question_liked']['limit'] ?? 0;
if ($dailyPointLimit <= 0) return;
$eventId = $questionLike->id;
$eventType = PointHistoryModel::EVENT_QUESTION_LIKED;
$historyRepo = new PointHistoryRepo();
$history = $historyRepo->findEventHistory($eventId, $eventType);
if ($history) return;
$questionRepo = new QuestionRepo();
$question = $questionRepo->findById($questionLike->question_id);
/**
* @todo 使用缓存优化
*/
$dailyPoints = $historyRepo->sumUserDailyEventPoints($question->owner_id, $eventType, date('Ymd'));
if ($dailyPoints >= $dailyPointLimit) return;
$userRepo = new UserRepo();
$user = $userRepo->findById($question->owner_id);
$eventInfo = [
'question' => [
'id' => $question->id,
'title' => $question->title,
]
];
$history = new PointHistoryModel();
$history->user_id = $user->id;
$history->user_name = $user->name;
$history->event_id = $eventId;
$history->event_type = $eventType;
$history->event_info = $eventInfo;
$history->event_point = $eventPoint;
$this->handlePointHistory($history);
}
}

View File

@ -34,6 +34,7 @@ class QuestionPost extends PointHistory
if ($dailyPointLimit <= 0) return;
$eventId = $question->id;
$eventType = PointHistoryModel::EVENT_QUESTION_POST;
$historyRepo = new PointHistoryRepo();

View File

@ -90,8 +90,13 @@ class AnswerList extends LogicService
$likedIds = [];
if ($user->id > 0) {
$likes = $likeRepo->findByUserId($user->id);
$likedIds = array_column($likes->toArray(), 'answer_id');
$likes = $likeRepo->findByUserId($user->id)
->filter(function ($like) {
if ($like->deleted == 0) {
return $like;
}
});
$likedIds = array_column($likes, 'answer_id');
}
$result = [];

View File

@ -5,7 +5,7 @@ namespace App\Services\Logic\Question;
use App\Library\Paginator\Query as PagerQuery;
use App\Models\Comment as CommentModel;
use App\Repos\Comment as CommentRepo;
use App\Services\Logic\Comment\CommentListTrait;
use App\Services\Logic\Comment\ListTrait;
use App\Services\Logic\QuestionTrait;
use App\Services\Logic\Service as LogicService;
@ -13,7 +13,7 @@ class CommentList extends LogicService
{
use QuestionTrait;
use CommentListTrait;
use ListTrait;
public function handle($id)
{

View File

@ -32,8 +32,6 @@ class QuestionFavorite extends LogicService
if (!$favorite) {
$action = 'do';
$favorite = new QuestionFavoriteModel();
$favorite->question_id = $question->id;
@ -41,27 +39,41 @@ class QuestionFavorite extends LogicService
$favorite->create();
} else {
$favorite->deleted = $favorite->deleted == 1 ? 0 : 1;
$favorite->update();
}
if ($favorite->deleted == 0) {
$action = 'do';
$this->incrQuestionFavoriteCount($question);
$this->incrUserFavoriteCount($user);
$this->handleFavoriteNotice($question, $user);
$this->eventsManager->fire('Question:afterFavorite', $this, $question);
} else {
$action = 'undo';
$favorite->delete();
$this->decrQuestionFavoriteCount($question);
$this->decrUserFavoriteCount($user);
$this->eventsManager->fire('Question:afterUndoFavorite', $this, $question);
}
$isOwner = $user->id == $question->owner_id;
/**
* 仅首次收藏发送通知
*/
if (!$favorite && !$isOwner) {
$this->handleFavoriteNotice($question, $user);
}
return [
'action' => $action,
'count' => $question->favorite_count,

View File

@ -108,7 +108,7 @@ class QuestionInfo extends LogicService
$like = $likeRepo->findQuestionLike($question->id, $user->id);
if ($like) {
if ($like && $like->deleted == 0) {
$me['liked'] = 1;
}
@ -116,7 +116,7 @@ class QuestionInfo extends LogicService
$favorite = $favoriteRepo->findQuestionFavorite($question->id, $user->id);
if ($favorite) {
if ($favorite && $favorite->deleted == 0) {
$me['favorited'] = 1;
}

View File

@ -7,6 +7,7 @@ use App\Models\QuestionLike as QuestionLikeModel;
use App\Models\User as UserModel;
use App\Repos\QuestionLike as QuestionLikeRepo;
use App\Services\Logic\Notice\System\QuestionLiked as QuestionLikedNotice;
use App\Services\Logic\Point\History\QuestionLiked as QuestionLikedPointHistory;
use App\Services\Logic\QuestionTrait;
use App\Services\Logic\Service as LogicService;
use App\Validators\UserLimit as UserLimitValidator;
@ -30,9 +31,9 @@ class QuestionLike extends LogicService
$questionLike = $likeRepo->findQuestionLike($question->id, $user->id);
if (!$questionLike) {
$isFirstTime = true;
$action = 'do';
if (!$questionLike) {
$questionLike = new QuestionLikeModel();
@ -41,9 +42,22 @@ class QuestionLike extends LogicService
$questionLike->create();
$this->incrQuestionLikeCount($question);
} else {
$this->handleLikeNotice($question, $user);
$isFirstTime = false;
$questionLike->deleted = $questionLike->deleted == 1 ? 0 : 1;
$questionLike->update();
}
$this->incrUserDailyQuestionLikeCount($user);
if ($questionLike->deleted == 0) {
$action = 'do';
$this->incrQuestionLikeCount($question);
$this->eventsManager->fire('Question:afterLike', $this, $question);
@ -51,14 +65,20 @@ class QuestionLike extends LogicService
$action = 'undo';
$questionLike->delete();
$this->decrQuestionLikeCount($question);
$this->eventsManager->fire('Question:afterUndoLike', $this, $question);
}
$this->incrUserDailyQuestionLikeCount($user);
$isOwner = $user->id == $question->owner_id;
/**
* 仅首次点赞发送通知和奖励积分
*/
if ($isFirstTime && !$isOwner) {
$this->handleQuestionLikedNotice($question, $user);
$this->handleQuestionLikedPoint($questionLike);
}
return [
'action' => $action,
@ -86,11 +106,18 @@ class QuestionLike extends LogicService
$this->eventsManager->fire('UserDailyCounter:incrQuestionLikeCount', $this, $user);
}
protected function handleLikeNotice(QuestionModel $question, UserModel $sender)
protected function handleQuestionLikedNotice(QuestionModel $question, UserModel $sender)
{
$notice = new QuestionLikedNotice();
$notice->handle($question, $sender);
}
protected function handleQuestionLikedPoint(QuestionLikeModel $questionLike)
{
$service = new QuestionLikedPointHistory();
$service->handle($questionLike);
}
}

View File

@ -32,8 +32,6 @@ class ReviewLike extends LogicService
if (!$reviewLike) {
$action = 'do';
$reviewLike = new ReviewLikeModel();
$reviewLike->review_id = $review->id;
@ -41,6 +39,19 @@ class ReviewLike extends LogicService
$reviewLike->create();
} else {
$reviewLike->deleted = $reviewLike->deleted == 1 ? 0 : 1;
$reviewLike->update();
}
$this->incrUserDailyReviewLikeCount($user);
if ($reviewLike->deleted == 0) {
$action = 'do';
$this->incrReviewLikeCount($review);
$this->handleLikeNotice($review, $user);
@ -51,14 +62,19 @@ class ReviewLike extends LogicService
$action = 'undo';
$reviewLike->delete();
$this->decrReviewLikeCount($review);
$this->eventsManager->fire('Review:afterUndoLike', $this, $review);
}
$this->incrUserDailyReviewLikeCount($user);
$isOwner = $user->id == $review->owner_id;
/**
* 仅首次点赞发送通知
*/
if (!$reviewLike && !$isOwner) {
$this->handleLikeNotice($review, $user);
}
return [
'action' => $action,

View File

@ -5,7 +5,7 @@ namespace App\Services\Logic\User;
use App\Library\Paginator\Query as PagerQuery;
use App\Models\Article as ArticleModel;
use App\Repos\Article as ArticleRepo;
use App\Services\Logic\Article\QuestionList as ArticleListService;
use App\Services\Logic\Article\ArticleList as ArticleListService;
use App\Services\Logic\Service as LogicService;
use App\Services\Logic\UserTrait;

View File

@ -49,13 +49,34 @@ class Comment extends Validator
return $user;
}
public function checkItemType($itemType)
public function checkItem($itemType, $itemId)
{
if (!array_key_exists($itemType, CommentModel::itemTypes())) {
throw new BadRequestException('comment.invalid_item_type');
}
return $itemType;
$result = null;
switch ($itemType) {
case CommentModel::ITEM_CHAPTER:
$validator = new Chapter();
$result = $validator->checkChapter($itemId);
break;
case CommentModel::ITEM_ARTICLE:
$validator = new Article();
$result = $validator->checkArticle($itemId);
break;
case CommentModel::ITEM_QUESTION:
$validator = new Question();
$result = $validator->checkQuestion($itemId);
break;
case CommentModel::ITEM_ANSWER:
$validator = new Answer();
$result = $validator->checkAnswer($itemId);
break;
}
return $result;
}
public function checkContent($content)

View File

@ -0,0 +1,224 @@
<?php
use Phinx\Db\Adapter\MysqlAdapter;
class V20210515063211 extends Phinx\Migration\AbstractMigration
{
public function up()
{
$this->modifyArticleFavoriteTable();
$this->modifyArticleLikeTable();
$this->modifyChapterLikeTable();
$this->modifyCommentLikeTable();
$this->modifyConsultLikeTable();
$this->modifyCourseFavoriteTable();
$this->handlePointEventRules();
}
protected function modifyArticleFavoriteTable()
{
$this->table('kg_article_favorite')
->addColumn('deleted', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '删除标识',
'after' => 'user_id',
])
->changeColumn('create_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '创建时间',
'after' => 'deleted',
])
->addColumn('update_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '更新时间',
'after' => 'create_time',
])
->save();
}
protected function modifyArticleLikeTable()
{
$this->table('kg_article_like')
->addColumn('deleted', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '删除标识',
'after' => 'user_id',
])
->changeColumn('create_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '创建时间',
'after' => 'deleted',
])
->addColumn('update_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '更新时间',
'after' => 'create_time',
])
->save();
}
protected function modifyChapterLikeTable()
{
$this->table('kg_chapter_like')
->addColumn('deleted', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '删除标识',
'after' => 'user_id',
])
->changeColumn('create_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '创建时间',
'after' => 'deleted',
])
->addColumn('update_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '更新时间',
'after' => 'create_time',
])
->save();
}
protected function modifyCommentLikeTable()
{
$this->table('kg_comment_like')
->addColumn('deleted', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '删除标识',
'after' => 'user_id',
])
->changeColumn('create_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '创建时间',
'after' => 'deleted',
])
->addColumn('update_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '更新时间',
'after' => 'create_time',
])
->save();
}
protected function modifyConsultLikeTable()
{
$this->table('kg_consult_like')
->addColumn('deleted', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '删除标识',
'after' => 'user_id',
])
->changeColumn('create_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '创建时间',
'after' => 'deleted',
])
->addColumn('update_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '更新时间',
'after' => 'create_time',
])
->save();
}
protected function modifyCourseFavoriteTable()
{
$this->table('kg_course_favorite')
->addColumn('deleted', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '删除标识',
'after' => 'user_id',
])
->changeColumn('create_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '创建时间',
'after' => 'deleted',
])
->addColumn('update_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '更新时间',
'after' => 'create_time',
])
->save();
}
protected function handlePointEventRules()
{
$setting = $this->getQueryBuilder()
->select('*')
->from('kg_setting')
->where(['section' => 'point', 'item_key' => 'event_rule'])
->execute()->fetch('assoc');
if (!$setting) return;
$itemValue = json_decode($setting['item_value'], true);
$itemValue['article_liked'] = ['point' => 1, 'enabled' => 1, 'limit' => 50];
$itemValue['question_liked'] = ['point' => 1, 'enabled' => 1, 'limit' => 50];
$itemValue['answer_liked'] = ['point' => 1, 'enabled' => 1, 'limit' => 50];
$itemValue = json_encode($itemValue);
$this->getQueryBuilder()
->update('kg_setting')
->where(['id' => $setting['id']])
->set('item_value', $itemValue)
->execute();
}
}