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

简化投票为单一点赞,设计多维度评价

This commit is contained in:
xiaochong0302 2020-07-12 19:40:31 +08:00
parent 3e27353b26
commit 50c5e403eb
76 changed files with 807 additions and 1575 deletions

View File

@ -31,8 +31,7 @@ class ChapterCounter extends Counter
'user_count' => $chapter->user_count,
'lesson_count' => $chapter->lesson_count,
'comment_count' => $chapter->comment_count,
'agree_count' => $chapter->agree_count,
'oppose_count' => $chapter->oppose_count,
'like_count' => $chapter->like_count,
];
}

View File

@ -29,8 +29,7 @@ class CommentCounter extends Counter
return [
'reply_count' => $comment->reply_count,
'agree_count' => $comment->agree_count,
'oppose_count' => $comment->oppose_count,
'like_count' => $comment->like_count,
];
}

View File

@ -28,8 +28,7 @@ class ConsultCounter extends Counter
if (!$consult) return null;
return [
'agree_count' => $consult->agree_count,
'oppose_count' => $consult->oppose_count,
'like_count' => $consult->like_count,
];
}

View File

@ -28,8 +28,7 @@ class ReviewCounter extends Counter
if (!$review) return null;
return [
'agree_count' => $review->agree_count,
'oppose_count' => $review->oppose_count,
'like_count' => $review->like_count,
];
}

View File

@ -27,10 +27,10 @@ class UserDailyCounter extends Counter
'danmu_count' => 0,
'consult_count' => 0,
'order_count' => 0,
'chapter_vote_count' => 0,
'comment_vote_count' => 0,
'consult_vote_count' => 0,
'review_vote_count' => 0,
'chapter_like_count' => 0,
'comment_like_count' => 0,
'consult_like_count' => 0,
'review_like_count' => 0,
];
}

View File

@ -61,8 +61,7 @@ class SyncChapterCounterTask extends Task
$chapter->user_count = $chapterRepo->countUsers($chapter->id);
$chapter->lesson_count = $chapterRepo->countLessons($chapter->id);
$chapter->comment_count = $chapterRepo->countComments($chapter->id);
$chapter->agree_count = $chapterRepo->countAgrees($chapter->id);
$chapter->oppose_count = $chapterRepo->countOpposes($chapter->id);
$chapter->like_count = $chapterRepo->countLikes($chapter->id);
$chapter->update();
$counterCache->rebuild($chapter->id);
@ -77,8 +76,7 @@ class SyncChapterCounterTask extends Task
$chapter->user_count = $counter['user_count'];
$chapter->lesson_count = $counter['lesson_count'];
$chapter->comment_count = $counter['comment_count'];
$chapter->agree_count = $counter['agree_count'];
$chapter->oppose_count = $counter['oppose_count'];
$chapter->like_count = $counter['like_count'];
$chapter->update();
$chapterCache->rebuild($chapter->id);

View File

@ -56,8 +56,7 @@ class SyncCommentCounterTask extends Task
if ($recount && $hour % 3 == 0) {
$comment->reply_count = $commentRepo->countReplies($comment->id);
$comment->agree_count = $commentRepo->countAgrees($comment->id);
$comment->oppose_count = $commentRepo->countOpposes($comment->id);
$comment->like_count = $commentRepo->countLikes($comment->id);
$comment->update();
$counterCache->rebuild($comment->id);
@ -68,8 +67,7 @@ class SyncCommentCounterTask extends Task
if ($counter) {
$comment->reply_count = $counter['reply_count'];
$comment->agree_count = $counter['agree_count'];
$comment->oppose_count = $counter['oppose_count'];
$comment->like_count = $counter['like_count'];
$comment->update();
}
}

View File

@ -55,8 +55,7 @@ class SyncConsultCounterTask extends Task
if ($recount && $hour % 3 == 0) {
$consult->agree_count = $consultRepo->countAgrees($consult->id);
$consult->oppose_count = $consultRepo->countOpposes($consult->id);
$consult->like_count = $consultRepo->countLikes($consult->id);
$consult->update();
$counterCache->rebuild($consult->id);
@ -66,8 +65,7 @@ class SyncConsultCounterTask extends Task
$counter = $counterCache->get($consult->id);
if ($counter) {
$consult->agree_count = $counter['agree_count'];
$consult->oppose_count = $counter['oppose_count'];
$consult->like_count = $counter['like_count'];
$consult->update();
}
}

View File

@ -55,8 +55,7 @@ class SyncReviewCounterTask extends Task
if ($recount && $hour % 3 == 0) {
$review->agree_count = $reviewRepo->countAgrees($review->id);
$review->oppose_count = $reviewRepo->countOpposes($review->id);
$review->like_count = $reviewRepo->countLikes($review->id);
$review->update();
$counterCache->rebuild($review->id);
@ -66,8 +65,7 @@ class SyncReviewCounterTask extends Task
$counter = $counterCache->get($review->id);
if ($counter) {
$review->agree_count = $counter['agree_count'];
$review->oppose_count = $counter['oppose_count'];
$review->like_count = $counter['like_count'];
$review->update();
}
}

View File

@ -2,12 +2,11 @@
namespace App\Http\Web\Controllers;
use App\Services\Frontend\Chapter\AgreeVote as ChapterAgreeVoteService;
use App\Services\Frontend\Chapter\ChapterInfo as ChapterInfoService;
use App\Services\Frontend\Chapter\ChapterLike as ChapterLikeService;
use App\Services\Frontend\Chapter\CommentList as ChapterCommentListService;
use App\Services\Frontend\Chapter\DanmuList as ChapterDanmuListService;
use App\Services\Frontend\Chapter\Learning as ChapterLearningService;
use App\Services\Frontend\Chapter\OpposeVote as ChapterOpposeVoteService;
use App\Services\Frontend\Course\ChapterList as CourseChapterListService;
/**
@ -79,23 +78,11 @@ class ChapterController extends Controller
}
/**
* @Post("/{id:[0-9]+}/agree", name="web.chapter.agree")
* @Post("/{id:[0-9]+}/like", name="web.chapter.like")
*/
public function agreeAction($id)
public function likeAction($id)
{
$service = new ChapterAgreeVoteService();
$service->handle($id);
return $this->jsonSuccess();
}
/**
* @Post("/{id:[0-9]+}/oppose", name="web.chapter.oppose")
*/
public function opposeAction($id)
{
$service = new ChapterOpposeVoteService();
$service = new ChapterLikeService();
$service->handle($id);

View File

@ -2,12 +2,11 @@
namespace App\Http\Web\Controllers;
use App\Services\Frontend\Comment\AgreeVote as CommentAgreeVoteService;
use App\Services\Frontend\Comment\CommentCreate as CommentCreateService;
use App\Services\Frontend\Comment\CommentDelete as CommentDeleteService;
use App\Services\Frontend\Comment\CommentInfo as CommentInfoService;
use App\Services\Frontend\Comment\CommentLike as CommentLikeService;
use App\Services\Frontend\Comment\CommentUpdate as CommentUpdateService;
use App\Services\Frontend\Comment\OpposeVote as CommentOpposeVoteService;
/**
* @RoutePrefix("/comment")
@ -68,23 +67,11 @@ class CommentController extends Controller
}
/**
* @Post("/{id:[0-9]+}/agree", name="web.comment.agree")
* @Post("/{id:[0-9]+}/like", name="web.comment.like")
*/
public function agreeAction($id)
public function likeAction($id)
{
$service = new CommentAgreeVoteService();
$service->handle($id);
return $this->jsonSuccess();
}
/**
* @Post("/{id:[0-9]+}/oppose", name="web.comment.oppose")
*/
public function opposeAction($id)
{
$service = new CommentOpposeVoteService();
$service = new CommentLikeService();
$service->handle($id);

View File

@ -2,12 +2,11 @@
namespace App\Http\Web\Controllers;
use App\Services\Frontend\Consult\AgreeVote as ConsultAgreeVoteService;
use App\Services\Frontend\Consult\ConsultCreate as ConsultCreateService;
use App\Services\Frontend\Consult\ConsultDelete as ConsultDeleteService;
use App\Services\Frontend\Consult\ConsultInfo as ConsultInfoService;
use App\Services\Frontend\Consult\ConsultLike as ConsultLikeService;
use App\Services\Frontend\Consult\ConsultUpdate as ConsultUpdateService;
use App\Services\Frontend\Consult\OpposeVote as ConsultOpposeVoteService;
/**
* @RoutePrefix("/consult")
@ -68,23 +67,11 @@ class ConsultController extends Controller
}
/**
* @Post("/{id:[0-9]+}/agree", name="web.consult.agree")
* @Post("/{id:[0-9]+}/like", name="web.consult.like")
*/
public function agreeAction($id)
public function likeAction($id)
{
$service = new ConsultAgreeVoteService();
$service->handle($id);
return $this->jsonSuccess();
}
/**
* @Post("/{id:[0-9]+}/oppose", name="web.consult.oppose")
*/
public function opposeAction($id)
{
$service = new ConsultOpposeVoteService();
$service = new ConsultLikeService();
$service->handle($id);

View File

@ -2,11 +2,10 @@
namespace App\Http\Web\Controllers;
use App\Services\Frontend\Review\AgreeVote as ReviewAgreeVoteService;
use App\Services\Frontend\Review\OpposeVote as ReviewOpposeVoteService;
use App\Services\Frontend\Review\ReviewCreate as ReviewCreateService;
use App\Services\Frontend\Review\ReviewDelete as ReviewDeleteService;
use App\Services\Frontend\Review\ReviewInfo as ReviewInfoService;
use App\Services\Frontend\Review\ReviewLike as ReviewLikeService;
use App\Services\Frontend\Review\ReviewUpdate as ReviewUpdateService;
/**
@ -68,23 +67,11 @@ class ReviewController extends Controller
}
/**
* @Post("/{id:[0-9]+}/agree", name="web.review.agree")
* @Post("/{id:[0-9]+}/like", name="web.review.like")
*/
public function agreeAction($id)
public function likeAction($id)
{
$service = new ReviewAgreeVoteService();
$service->handle($id);
return $this->jsonSuccess();
}
/**
* @Post("/{id:[0-9]+}/oppose", name="web.review.oppose")
*/
public function opposeAction($id)
{
$service = new ReviewOpposeVoteService();
$service = new ReviewLikeService();
$service->handle($id);

View File

@ -1,4 +1,4 @@
<div class="sidebar-chapter-wrap wrap">
<div class="sidebar-chapter wrap">
<fieldset class="layui-elem-field layui-field-title">
<legend>课程目录</legend>
<div class="layui-field-box">

View File

@ -2,6 +2,7 @@
{% block content %}
{% set like_url = url({'for':'web.chapter.like','id':chapter.id}) %}
{% set learning_url = url({'for':'web.chapter.learning','id':chapter.id}) %}
{% set danmu_url = url({'for':'web.chapter.danmu','id':chapter.id}) %}
@ -18,19 +19,18 @@
<div id="player"></div>
<div id="danmu"></div>
</div>
<div class="danmu-action-wrap wrap">
<form class="layui-form" lay-filter="danmu.form" action="{{ url({'for':'web.danmu.create'}) }}">
<div class="layui-input-inline" style="width: 50px;">
<a href="javascript:" class="layui-icon layui-icon-set icon-danmu-set"></a>
</div>
<div class="layui-input-inline" style="width: 655px;">
{% if auth_user.id > 0 %}
<input class="layui-input" type="text" name="danmu.text" maxlength="50" placeholder="快来发个弹幕吧" lay-verType="tips" lay-verify="required">
{% else %}
<input class="layui-input" type="text" name="danmu.text" placeholder="登录后才可以发送弹幕哦" readonly="readonly">
{% endif %}
<button class="layui-hide" type="submit" lay-submit="true" lay-filter="danmu.send">发送</button>
</div>
<div class="chapter-action wrap">
<span><i class="layui-icon layui-icon-praise" id="icon-like" title="点赞" data-url="{{ like_url }}"></i><em id="like-count">{{ chapter.like_count }}</em></span>
<span><i class="layui-icon layui-icon-user" id="icon-user" title="学习人次"></i><em>{{ chapter.user_count }}</em></span>
<span><i class="layui-icon layui-icon-share" id="icon-share" title="分享"></i></span>
<span><i class="layui-icon layui-icon-set" id="icon-danmu-set" title="弹幕设置"></i></span>
<form class="layui-form danmu-form" lay-filter="danmu.form" action="{{ url({'for':'web.danmu.create'}) }}">
{% if auth_user.id > 0 %}
<input class="layui-input" type="text" name="danmu.text" maxlength="50" placeholder="快来发个弹幕吧" lay-verType="tips" lay-verify="required">
{% else %}
<input class="layui-input" type="text" name="danmu.text" placeholder="登录后才可以发送弹幕哦" readonly="readonly">
{% endif %}
<button class="layui-hide" type="submit" lay-submit="true" lay-filter="danmu.send">发送</button>
</form>
</div>
</div>
@ -103,5 +103,6 @@
{{ js_include('lib/jquery.min.js') }}
{{ js_include('lib/jquery.danmu.min.js') }}
{{ js_include('web/js/vod.player.js') }}
{{ js_include('web/js/chapter.action.js') }}
{% endblock %}

View File

@ -45,44 +45,16 @@ class ChapterCounter extends Listener
$this->syncChapterCounter($chapter);
}
public function incrAgreeCount(Event $event, $source, ChapterModel $chapter)
public function incrLikeCount(Event $event, $source, ChapterModel $chapter)
{
$this->counter->hIncrBy($chapter->id, 'agree_count');
$this->counter->hIncrBy($chapter->id, 'like_count');
$this->syncChapterCounter($chapter);
}
public function decrAgreeCount(Event $event, $source, ChapterModel $chapter)
public function decrLikeCount(Event $event, $source, ChapterModel $chapter)
{
$this->counter->hDecrBy($chapter->id, 'agree_count');
$this->syncChapterCounter($chapter);
}
public function incrOpposeCount(Event $event, $source, ChapterModel $chapter)
{
$this->counter->hIncrBy($chapter->id, 'oppose_count');
$this->syncChapterCounter($chapter);
}
public function decrOpposeCount(Event $event, $source, ChapterModel $chapter)
{
$this->counter->hDecrBy($chapter->id, 'oppose_count');
$this->syncChapterCounter($chapter);
}
public function incrLessonCount(Event $event, $source, ChapterModel $chapter)
{
$this->counter->hIncrBy($chapter->id, 'lesson_count');
$this->syncChapterCounter($chapter);
}
public function decrLessonCount(Event $event, $source, ChapterModel $chapter)
{
$this->counter->hDecrBy($chapter->id, 'lesson_count');
$this->counter->hDecrBy($chapter->id, 'like_count');
$this->syncChapterCounter($chapter);
}

View File

@ -31,30 +31,16 @@ class CommentCounter extends Listener
$this->syncCommentCounter($comment);
}
public function incrAgreeCount(Event $event, $source, CommentModel $comment)
public function incrLikeCount(Event $event, $source, CommentModel $comment)
{
$this->counter->hIncrBy($comment->id, 'agree_count');
$this->counter->hIncrBy($comment->id, 'like_count');
$this->syncCommentCounter($comment);
}
public function decrAgreeCount(Event $event, $source, CommentModel $comment)
public function decrLikeCount(Event $event, $source, CommentModel $comment)
{
$this->counter->hDecrBy($comment->id, 'agree_count');
$this->syncCommentCounter($comment);
}
public function incrOpposeCount(Event $event, $source, CommentModel $comment)
{
$this->counter->hIncrBy($comment->id, 'oppose_count');
$this->syncCommentCounter($comment);
}
public function decrOpposeCount(Event $event, $source, CommentModel $comment)
{
$this->counter->hDecrBy($comment->id, 'oppose_count');
$this->counter->hDecrBy($comment->id, 'like_count');
$this->syncCommentCounter($comment);
}

View File

@ -17,30 +17,16 @@ class ConsultCounter extends Listener
$this->counter = new CacheConsultCounter();
}
public function incrAgreeCount(Event $event, $source, ConsultModel $consult)
public function incrLikeCount(Event $event, $source, ConsultModel $consult)
{
$this->counter->hIncrBy($consult->id, 'agree_count');
$this->counter->hIncrBy($consult->id, 'like_count');
$this->syncConsultCounter($consult);
}
public function decrAgreeCount(Event $event, $source, ConsultModel $consult)
public function decrLikeCount(Event $event, $source, ConsultModel $consult)
{
$this->counter->hDecrBy($consult->id, 'agree_count');
$this->syncConsultCounter($consult);
}
public function incrOpposeCount(Event $event, $source, ConsultModel $consult)
{
$this->counter->hIncrBy($consult->id, 'oppose_count');
$this->syncConsultCounter($consult);
}
public function decrOpposeCount(Event $event, $source, ConsultModel $consult)
{
$this->counter->hDecrBy($consult->id, 'oppose_count');
$this->counter->hDecrBy($consult->id, 'like_count');
$this->syncConsultCounter($consult);
}

View File

@ -36,20 +36,6 @@ class CourseCounter extends Listener
$this->syncCourseIndex($course);
}
public function incrCommentCount(Event $event, $source, CourseModel $course)
{
$this->counter->hIncrBy($course->id, 'comment_count');
$this->syncCourseCounter($course);
}
public function decrCommentCount(Event $event, $source, CourseModel $course)
{
$this->counter->hDecrBy($course->id, 'comment_count');
$this->syncCourseCounter($course);
}
public function incrConsultCount(Event $event, $source, CourseModel $course)
{
$this->counter->hIncrBy($course->id, 'consult_count');
@ -92,20 +78,6 @@ class CourseCounter extends Listener
$this->syncCourseCounter($course);
}
public function incrLessonCount(Event $event, $source, CourseModel $course)
{
$this->counter->hIncrBy($course->id, 'lesson_count');
$this->syncCourseCounter($course);
}
public function decrLessonCount(Event $event, $source, CourseModel $course)
{
$this->counter->hDecrBy($course->id, 'lesson_count');
$this->syncCourseCounter($course);
}
protected function syncCourseCounter(CourseModel $course)
{
$syncer = new CourseCounterSyncer();

View File

@ -17,30 +17,16 @@ class ReviewCounter extends Listener
$this->counter = new CacheReviewCounter();
}
public function incrAgreeCount(Event $event, $source, ReviewModel $review)
public function incrLikeCount(Event $event, $source, ReviewModel $review)
{
$this->counter->hIncrBy($review->id, 'agree_count');
$this->counter->hIncrBy($review->id, 'like_count');
$this->syncReviewCounter($review);
}
public function decrAgreeCount(Event $event, $source, ReviewModel $review)
public function decrLikeCount(Event $event, $source, ReviewModel $review)
{
$this->counter->hDecrBy($review->id, 'agree_count');
$this->syncReviewCounter($review);
}
public function incrOpposeCount(Event $event, $source, ReviewModel $review)
{
$this->counter->hIncrBy($review->id, 'oppose_count');
$this->syncReviewCounter($review);
}
public function decrOpposeCount(Event $event, $source, ReviewModel $review)
{
$this->counter->hDecrBy($review->id, 'oppose_count');
$this->counter->hDecrBy($review->id, 'like_count');
$this->syncReviewCounter($review);
}

View File

@ -46,24 +46,24 @@ class UserDailyCounter extends Listener
$this->counter->hIncrBy($user->id, 'order_count');
}
public function incrCommentVoteCount(Event $event, $source, UserModel $user)
public function incrCommentLikeCount(Event $event, $source, UserModel $user)
{
$this->counter->hIncrBy($user->id, 'comment_vote_count');
$this->counter->hIncrBy($user->id, 'comment_like_count');
}
public function incrConsultVoteCount(Event $event, $source, UserModel $user)
public function incrConsultLikeCount(Event $event, $source, UserModel $user)
{
$this->counter->hIncrBy($user->id, 'consult_vote_count');
$this->counter->hIncrBy($user->id, 'consult_like_count');
}
public function incrChapterVoteCount(Event $event, $source, UserModel $user)
public function incrChapterLikeCount(Event $event, $source, UserModel $user)
{
$this->counter->hIncrBy($user->id, 'chapter_vote_count');
$this->counter->hIncrBy($user->id, 'chapter_like_count');
}
public function incrReviewVoteCount(Event $event, $source, UserModel $user)
public function incrReviewLikeCount(Event $event, $source, UserModel $user)
{
$this->counter->hIncrBy($user->id, 'review_vote_count');
$this->counter->hIncrBy($user->id, 'review_like_count');
}
}

View File

@ -133,18 +133,11 @@ class Chapter extends Model
public $comment_count;
/**
*
* 赞数
*
* @var int
*/
public $agree_count;
/**
* 反对数
*
* @var int
*/
public $oppose_count;
public $like_count;
/**
* 发布标识

View File

@ -4,16 +4,9 @@ namespace App\Models;
use Phalcon\Mvc\Model\Behavior\SoftDelete;
class ChapterVote extends Model
class ChapterLike extends Model
{
/**
* 投票类型
*/
const TYPE_AGREE = 1; // 赞成
const TYPE_OPPOSE = 2; // 反对
const TYPE_NONE = 3; // 中立
/**
* 主键编号
*
@ -35,13 +28,6 @@ class ChapterVote extends Model
*/
public $user_id;
/**
* 投票类型
*
* @var int
*/
public $type;
/**
* 删除标识
*
@ -65,7 +51,7 @@ class ChapterVote extends Model
public function getSource(): string
{
return 'kg_chapter_vote';
return 'kg_chapter_like';
}
public function initialize()

View File

@ -42,15 +42,6 @@ class Comment extends Model
*/
public $user_id;
/**
* 提及用户
*
* 数据结构: [{id:123,name:'foo'}]
*
* @var string
*/
public $mentions;
/**
* 内容
*
@ -66,18 +57,11 @@ class Comment extends Model
public $reply_count;
/**
*
* 赞数
*
* @var int
*/
public $agree_count;
/**
* 反对数
*
* @var int
*/
public $oppose_count;
public $like_count;
/**
* 发布标识
@ -127,26 +111,11 @@ class Comment extends Model
public function beforeCreate()
{
$this->create_time = time();
if (is_array($this->mentions) && !empty($this->mentions)) {
$this->mentions = kg_json_encode($this->mentions);
}
}
public function beforeUpdate()
{
$this->update_time = time();
if (is_array($this->mentions) && !empty($this->mentions)) {
$this->mentions = kg_json_encode($this->mentions);
}
}
public function afterFetch()
{
if (!empty($this->mentions)) {
$this->mentions = json_decode($this->mentions, true);
}
}
}

View File

@ -4,16 +4,9 @@ namespace App\Models;
use Phalcon\Mvc\Model\Behavior\SoftDelete;
class CommentVote extends Model
class CommentLike extends Model
{
/**
* 投票类型
*/
const TYPE_AGREE = 1; // 赞成
const TYPE_OPPOSE = 2; // 反对
const TYPE_NONE = 3; // 中立
/**
* 主键编号
*
@ -35,13 +28,6 @@ class CommentVote extends Model
*/
public $user_id;
/**
* 投票类型
*
* @var int
*/
public $type;
/**
* 删除标识
*
@ -65,7 +51,7 @@ class CommentVote extends Model
public function getSource(): string
{
return 'kg_comment_vote';
return 'kg_comment_like';
}
public function initialize()

View File

@ -47,14 +47,7 @@ class Consult extends Model
*
* @var int
*/
public $agree_count;
/**
* 反对数
*
* @var int
*/
public $oppose_count;
public $like_count;
/**
* 私密标识

View File

@ -4,16 +4,9 @@ namespace App\Models;
use Phalcon\Mvc\Model\Behavior\SoftDelete;
class ConsultVote extends Model
class ConsultLike extends Model
{
/**
* 投票类型
*/
const TYPE_AGREE = 1; // 赞成
const TYPE_OPPOSE = 2; // 反对
const TYPE_NONE = 3; // 中立
/**
* 主键编号
*
@ -35,13 +28,6 @@ class ConsultVote extends Model
*/
public $user_id;
/**
* 投票类型
*
* @var int
*/
public $type;
/**
* 删除标识
*
@ -58,7 +44,7 @@ class ConsultVote extends Model
public function getSource(): string
{
return 'kg_consult_vote';
return 'kg_consult_like';
}
public function initialize()

View File

@ -185,13 +185,6 @@ class Course extends Model
*/
public $package_count;
/**
* 评论数
*
* @var int
*/
public $comment_count;
/**
* 咨询数
*
@ -302,6 +295,10 @@ class Course extends Model
public function afterCreate()
{
$courseRating = new CourseRating();
$courseRating->create(['course_id' => $this->id]);
$cache = new MaxCourseIdCache();
$cache->rebuild();

100
app/Models/CourseRating.php Normal file
View File

@ -0,0 +1,100 @@
<?php
namespace App\Models;
use Phalcon\Mvc\Model\Behavior\SoftDelete;
class CourseRating extends Model
{
/**
* 主键编号
*
* @var int
*/
public $id;
/**
* 课程编号
*
* @var int
*/
public $course_id;
/**
* 综合评分
*
* @var float
*/
public $rating;
/**
* 维度1评分
*
* @var float
*/
public $rating1;
/**
* 维度2评分
*
* @var float
*/
public $rating2;
/**
* 维度3评分
*
* @var float
*/
public $rating3;
/**
* 删除标识
*
* @var int
*/
public $deleted;
/**
* 创建时间
*
* @var int
*/
public $create_time;
/**
* 更新时间
*
* @var int
*/
public $update_time;
public function getSource(): string
{
return 'kg_course_rating';
}
public function initialize()
{
parent::initialize();
$this->addBehavior(
new SoftDelete([
'field' => 'deleted',
'value' => 1,
])
);
}
public function beforeCreate()
{
$this->create_time = time();
}
public function beforeUpdate()
{
$this->update_time = time();
}
}

View File

@ -43,25 +43,39 @@ class Review extends Model
public $reply;
/**
* 课程评分
* 综合评分
*
* @var int
* @var float
*/
public $rating;
/**
* 赞同数量
* 维度1评分
*
* @var int
* @var float
*/
public $agree_count;
public $rating1;
/**
* 反对数量
* 维度2评分
*
* @var float
*/
public $rating2;
/**
* 维度3评分
*
* @var float
*/
public $rating3;
/**
* 点赞数量
*
* @var int
*/
public $oppose_count;
public $like_count;
/**
* 发布标识

View File

@ -4,16 +4,9 @@ namespace App\Models;
use Phalcon\Mvc\Model\Behavior\SoftDelete;
class ReviewVote extends Model
class ReviewLike extends Model
{
/**
* 投票类型
*/
const TYPE_AGREE = 1; // 赞成
const TYPE_OPPOSE = 2; // 反对
const TYPE_NONE = 3; // 中立
/**
* 主键编号
*
@ -35,13 +28,6 @@ class ReviewVote extends Model
*/
public $user_id;
/**
* 投票类型
*
* @var int
*/
public $type;
/**
* 删除标识
*
@ -58,7 +44,7 @@ class ReviewVote extends Model
public function getSource(): string
{
return 'kg_review_vote';
return 'kg_review_like';
}
public function initialize()

View File

@ -3,13 +3,12 @@
namespace App\Repos;
use App\Models\Chapter as ChapterModel;
use App\Models\ChapterLike as ChapterLikeModel;
use App\Models\ChapterLive as ChapterLiveModel;
use App\Models\ChapterRead as ChapterReadModel;
use App\Models\ChapterUser as ChapterUserModel;
use App\Models\ChapterVod as ChapterVodModel;
use App\Models\ChapterVote as ChapterVoteModel;
use App\Models\Comment as CommentModel;
use App\Models\CommentVote as CommentVoteModel;
use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
@ -120,22 +119,6 @@ class Chapter extends Repository
]);
}
/**
* @param int $chapterId
* @param int $userId
* @return ResultsetInterface|Resultset|CommentVoteModel[]
*/
public function findUserCommentVotes($chapterId, $userId)
{
return $this->modelsManager->createBuilder()
->columns('cv.*')
->addFrom(CommentModel::class, 'c')
->join(CommentVoteModel::class, 'c.id = cv.comment_id', 'cv')
->where('c.chapter_id = :chapter_id:', ['chapter_id' => $chapterId])
->andWhere('cv.user_id = :user_id:', ['user_id' => $userId])
->getQuery()->execute();
}
public function maxChapterPriority($courseId)
{
return ChapterModel::maximum([
@ -178,31 +161,11 @@ class Chapter extends Repository
]);
}
public function countAgrees($chapterId)
public function countLikes($chapterId)
{
$type = ChapterVoteModel::TYPE_AGREE;
return ChapterVoteModel::count([
'conditions' => 'chapter_id = :chapter_id: AND type = :type: AND deleted = 0',
'bind' => ['chapter_id' => $chapterId, 'type' => $type],
]);
}
public function countOpposes($chapterId)
{
$type = ChapterVoteModel::TYPE_OPPOSE;
return ChapterVoteModel::count([
'conditions' => 'chapter_id = :chapter_id: AND type = :type: AND deleted = 0',
'bind' => ['chapter_id' => $chapterId, 'type' => $type],
]);
}
public function countUserComments($chapterId, $userId)
{
return CommentModel::count([
'conditions' => 'chapter_id = :chapter_id: AND user_id = :user_id:',
'bind' => ['chapter_id' => $chapterId, 'user_id' => $userId],
return ChapterLikeModel::count([
'conditions' => 'chapter_id = :chapter_id: AND deleted = 0',
'bind' => ['chapter_id' => $chapterId],
]);
}

View File

@ -2,20 +2,20 @@
namespace App\Repos;
use App\Models\ChapterVote as ChapterVoteModel;
use App\Models\ChapterLike as ChapterLikeModel;
use Phalcon\Mvc\Model;
class ChapterVote extends Repository
class ChapterLike extends Repository
{
/**
* @param int $chapterId
* @param int $userId
* @return ChapterVoteModel|Model|bool
* @return ChapterLikeModel|Model|bool
*/
public function findChapterVote($chapterId, $userId)
public function findChapterLike($chapterId, $userId)
{
return ChapterVoteModel::findFirst([
return ChapterLikeModel::findFirst([
'conditions' => 'chapter_id = :chapter_id: AND user_id = :user_id:',
'bind' => ['chapter_id' => $chapterId, 'user_id' => $userId],
]);

View File

@ -4,7 +4,7 @@ namespace App\Repos;
use App\Library\Paginator\Adapter\QueryBuilder as PagerQueryBuilder;
use App\Models\Comment as CommentModel;
use App\Models\CommentVote as CommentVoteModel;
use App\Models\CommentLike as CommentLikeModel;
use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
@ -95,23 +95,11 @@ class Comment extends Repository
]);
}
public function countAgrees($commentId)
public function countLikes($commentId)
{
$type = CommentVoteModel::TYPE_AGREE;
return CommentVoteModel::count([
'conditions' => 'comment_id = :comment_id: AND type = :type: AND deleted = 0',
'bind' => ['comment_id' => $commentId, 'type' => $type],
]);
}
public function countOpposes($commentId)
{
$type = CommentVoteModel::TYPE_OPPOSE;
return CommentVoteModel::count([
'conditions' => 'comment_id = :comment_id: AND type = :type: AND deleted = 0',
'bind' => ['comment_id' => $commentId, 'type' => $type],
return CommentLikeModel::count([
'conditions' => 'comment_id = :comment_id: AND deleted = 0',
'bind' => ['comment_id' => $commentId],
]);
}

View File

@ -2,25 +2,23 @@
namespace App\Repos;
use App\Models\CommentVote as CommentVoteModel;
use App\Models\CommentLike as CommentLikeModel;
use Phalcon\Mvc\Model;
class CommentVote extends Repository
class CommentLike extends Repository
{
/**
* @param int $commentId
* @param int $userId
* @return CommentVoteModel|Model|bool
* @return CommentLikeModel|Model|bool
*/
public function findCommentVote($commentId, $userId)
public function findCommentLike($commentId, $userId)
{
$result = CommentVoteModel::findFirst([
return CommentLikeModel::findFirst([
'conditions' => 'comment_id = :comment_id: AND user_id = :user_id:',
'bind' => ['comment_id' => $commentId, 'user_id' => $userId],
]);
return $result;
}
}

View File

@ -4,7 +4,7 @@ namespace App\Repos;
use App\Library\Paginator\Adapter\QueryBuilder as PagerQueryBuilder;
use App\Models\Consult as ConsultModel;
use App\Models\ConsultVote as ConsultVoteModel;
use App\Models\ConsultLike as ConsultLikeModel;
use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
@ -83,28 +83,12 @@ class Consult extends Repository
->execute();
}
public function countAgrees($consultId)
public function countLikes($consultId)
{
$type = ConsultVoteModel::TYPE_AGREE;
$count = ConsultVoteModel::count([
'conditions' => 'consult_id = :consult_id: AND type = :type: AND deleted = 0',
'bind' => ['consult_id' => $consultId, 'type' => $type],
return ConsultLikeModel::count([
'conditions' => 'consult_id = :consult_id: AND deleted = 0',
'bind' => ['consult_id' => $consultId],
]);
return $count;
}
public function countOpposes($consultId)
{
$type = ConsultVoteModel::TYPE_OPPOSE;
$count = ConsultVoteModel::count([
'conditions' => 'consult_id = :consult_id: AND type = :type: AND deleted = 0',
'bind' => ['consult_id' => $consultId, 'type' => $type],
]);
return $count;
}
}

View File

@ -2,20 +2,20 @@
namespace App\Repos;
use App\Models\ConsultVote as ConsultVoteModel;
use App\Models\ConsultLike as ConsultLikeModel;
use Phalcon\Mvc\Model;
class ConsultVote extends Repository
class ConsultLike extends Repository
{
/**
* @param int $consultId
* @param int $userId
* @return ConsultVoteModel|Model|bool
* @return ConsultLikeModel|Model|bool
*/
public function findConsultVote($consultId, $userId)
public function findConsultLike($consultId, $userId)
{
return ConsultVoteModel::findFirst([
return ConsultLikeModel::findFirst([
'conditions' => 'consult_id = :consult_id: AND user_id = :user_id:',
'bind' => ['consult_id' => $consultId, 'user_id' => $userId],
]);

View File

@ -8,7 +8,7 @@ use App\Models\Chapter as ChapterModel;
use App\Models\ChapterUser as ChapterUserModel;
use App\Models\Comment as CommentModel;
use App\Models\Consult as ConsultModel;
use App\Models\ConsultVote as ConsultVoteModel;
use App\Models\ConsultLike as ConsultLikeModel;
use App\Models\Course as CourseModel;
use App\Models\CourseCategory as CourseCategoryModel;
use App\Models\CourseFavorite as CourseFavoriteModel;
@ -17,7 +17,7 @@ use App\Models\CourseRelated as CourseRelatedModel;
use App\Models\CourseUser as CourseUserModel;
use App\Models\Package as PackageModel;
use App\Models\Review as ReviewModel;
use App\Models\ReviewVote as ReviewVoteModel;
use App\Models\ReviewLike as ReviewLikeModel;
use App\Models\User as UserModel;
use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Resultset;
@ -238,14 +238,14 @@ class Course extends Repository
/**
* @param int $courseId
* @param int $userId
* @return ResultsetInterface|Resultset|ConsultVoteModel[]
* @return ResultsetInterface|Resultset|ConsultLikeModel[]
*/
public function findUserConsultVotes($courseId, $userId)
public function findUserConsultLikes($courseId, $userId)
{
return $this->modelsManager->createBuilder()
->columns('cv.*')
->addFrom(ConsultModel::class, 'c')
->join(ConsultVoteModel::class, 'c.id = cv.consult_id', 'cv')
->join(ConsultLikeModel::class, 'c.id = cv.consult_id', 'cv')
->where('c.course_id = :course_id:', ['course_id' => $courseId])
->andWhere('cv.user_id = :user_id:', ['user_id' => $userId])
->getQuery()->execute();
@ -254,14 +254,14 @@ class Course extends Repository
/**
* @param int $courseId
* @param int $userId
* @return ResultsetInterface|Resultset|ReviewVoteModel[]
* @return ResultsetInterface|Resultset|ReviewLikeModel[]
*/
public function findUserReviewVotes($courseId, $userId)
public function findUserReviewLikes($courseId, $userId)
{
return $this->modelsManager->createBuilder()
->columns('rv.*')
->addFrom(ReviewModel::class, 'r')
->join(ReviewVoteModel::class, 'r.id = rv.review_id', 'rv')
->join(ReviewLikeModel::class, 'r.id = rv.review_id', 'rv')
->where('r.course_id = :course_id:', ['course_id' => $courseId])
->andWhere('rv.user_id = :user_id:', ['user_id' => $userId])
->getQuery()->execute();

View File

@ -4,7 +4,7 @@ namespace App\Repos;
use App\Library\Paginator\Adapter\QueryBuilder as PagerQueryBuilder;
use App\Models\Review as ReviewModel;
use App\Models\ReviewVote as ReviewVoteModel;
use App\Models\ReviewLike as ReviewLikeModel;
use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
@ -106,23 +106,11 @@ class Review extends Repository
->execute();
}
public function countAgrees($reviewId)
public function countLikes($reviewId)
{
$type = ReviewVoteModel::TYPE_AGREE;
return ReviewVoteModel::count([
'conditions' => 'review_id = :review_id: AND type = :type: AND deleted = 0',
'bind' => ['review_id' => $reviewId, 'type' => $type],
]);
}
public function countOpposes($reviewId)
{
$type = ReviewVoteModel::TYPE_OPPOSE;
return ReviewVoteModel::count([
'conditions' => 'review_id = :review_id: AND type = :type: AND deleted = 0',
'bind' => ['review_id' => $reviewId, 'type' => $type],
return ReviewLikeModel::count([
'conditions' => 'review_id = :review_id: AND deleted = 0',
'bind' => ['review_id' => $reviewId],
]);
}

View File

@ -2,25 +2,23 @@
namespace App\Repos;
use App\Models\ReviewVote as ReviewVoteModel;
use App\Models\ReviewLike as ReviewLikeModel;
use Phalcon\Mvc\Model;
class ReviewVote extends Repository
class ReviewLike extends Repository
{
/**
* @param int $reviewId
* @param int $userId
* @return ReviewVoteModel|Model|bool
* @return ReviewLikeModel|Model|bool
*/
public function findReviewVote($reviewId, $userId)
public function findReviewLike($reviewId, $userId)
{
$result = ReviewVoteModel::findFirst([
return ReviewLikeModel::findFirst([
'conditions' => 'review_id = :review_id: AND user_id = :user_id:',
'bind' => ['review_id' => $reviewId, 'user_id' => $userId],
]);
return $result;
}
}

View File

@ -1,73 +0,0 @@
<?php
namespace App\Services\Frontend\Chapter;
use App\Models\ChapterVote as ChapterVoteModel;
use App\Repos\ChapterVote as ChapterVoteRepo;
use App\Services\Frontend\ChapterTrait;
use App\Services\Frontend\Service as FrontendService;
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
class AgreeVote extends FrontendService
{
use ChapterTrait, VoteTrait;
public function handle($id)
{
$chapter = $this->checkChapter($id);
$user = $this->getLoginUser();
$validator = new UserDailyLimitValidator();
$validator->checkChapterVoteLimit($user);
$chapterVoteRepo = new ChapterVoteRepo();
$chapterVote = $chapterVoteRepo->findChapterVote($chapter->id, $user->id);
if (!$chapterVote) {
$chapterVote = new ChapterVoteModel();
$chapterVote->chapter_id = $chapter->id;
$chapterVote->user_id = $user->id;
$chapterVote->type = ChapterVoteModel::TYPE_AGREE;
$chapterVote->create();
$this->incrAgreeCount($chapter);
} else {
if ($chapterVote->type == ChapterVoteModel::TYPE_AGREE) {
$chapterVote->type = ChapterVoteModel::TYPE_NONE;
$this->decrAgreeCount($chapter);
} elseif ($chapterVote->type == ChapterVoteModel::TYPE_OPPOSE) {
$chapterVote->type = ChapterVoteModel::TYPE_AGREE;
$this->incrAgreeCount($chapter);
$this->decrOpposeCount($chapter);
} elseif ($chapterVote->type == ChapterVoteModel::TYPE_NONE) {
$chapterVote->type = ChapterVoteModel::TYPE_AGREE;
$this->incrAgreeCount($chapter);
}
$chapterVote->update();
}
$this->incrUserDailyChapterVoteCount($user);
return $chapter;
}
}

View File

@ -60,8 +60,7 @@ class ChapterBasic extends FrontendService
'model' => $chapter->model,
'play_urls' => $playUrls,
'user_count' => $chapter->user_count,
'agree_count' => $chapter->agree_count,
'oppose_count' => $chapter->oppose_count,
'like_count' => $chapter->like_count,
'comment_count' => $chapter->comment_count,
];
}
@ -98,8 +97,7 @@ class ChapterBasic extends FrontendService
'start_time' => $live->start_time,
'end_time' => $live->end_time,
'user_count' => $chapter->user_count,
'agree_count' => $chapter->agree_count,
'oppose_count' => $chapter->oppose_count,
'like_count' => $chapter->like_count,
'comment_count' => $chapter->comment_count,
];
}
@ -117,8 +115,7 @@ class ChapterBasic extends FrontendService
'model' => $chapter->model,
'content' => $read->content,
'user_count' => $chapter->user_count,
'agree_count' => $chapter->agree_count,
'oppose_count' => $chapter->oppose_count,
'like_count' => $chapter->like_count,
'comment_count' => $chapter->comment_count,
];
}

View File

@ -4,12 +4,10 @@ namespace App\Services\Frontend\Chapter;
use App\Models\Chapter as ChapterModel;
use App\Models\ChapterUser as ChapterUserModel;
use App\Models\ChapterVote as ChapterVoteModel;
use App\Models\Course as CourseModel;
use App\Models\CourseUser as CourseUserModel;
use App\Models\User as UserModel;
use App\Repos\Chapter as ChapterRepo;
use App\Repos\ChapterVote as ChapterVoteRepo;
use App\Services\ChapterVod as ChapterVodService;
use App\Services\Frontend\ChapterTrait;
use App\Services\Frontend\CourseTrait;
@ -49,10 +47,10 @@ class ChapterInfo extends FrontendService
$this->setChapterUser($chapter, $user);
$this->handleChapterUser($chapter, $user);
return $this->handleChapter($chapter, $user);
return $this->handleChapter($chapter);
}
protected function handleChapter(ChapterModel $chapter, UserModel $user)
protected function handleChapter(ChapterModel $chapter)
{
$result = $this->formatChapter($chapter);
@ -63,8 +61,6 @@ class ChapterInfo extends FrontendService
'position' => 0,
'joined' => 0,
'owned' => 0,
'agreed' => 0,
'opposed' => 0,
];
if ($this->courseUser) {
@ -78,18 +74,6 @@ class ChapterInfo extends FrontendService
$me['joined'] = $this->joinedChapter ? 1 : 0;
$me['owned'] = $this->ownedChapter ? 1 : 0;
if ($user->id > 0) {
$chapterVoteRepo = new ChapterVoteRepo();
$chapterVote = $chapterVoteRepo->findChapterVote($chapter->id, $user->id);
if ($chapterVote) {
$me['agreed'] = $chapterVote->type == ChapterVoteModel::TYPE_AGREE ? 1 : 0;
$me['opposed'] = $chapterVote->type == ChapterVoteModel::TYPE_OPPOSE ? 1 : 0;
}
}
$result['me'] = $me;
return $result;
@ -142,8 +126,7 @@ class ChapterInfo extends FrontendService
'model' => $chapter->model,
'play_urls' => $playUrls,
'user_count' => $chapter->user_count,
'agree_count' => $chapter->agree_count,
'oppose_count' => $chapter->oppose_count,
'like_count' => $chapter->like_count,
'comment_count' => $chapter->comment_count,
];
}
@ -182,8 +165,7 @@ class ChapterInfo extends FrontendService
'end_time' => $live->end_time,
'play_urls' => $playUrls,
'user_count' => $chapter->user_count,
'agree_count' => $chapter->agree_count,
'oppose_count' => $chapter->oppose_count,
'like_count' => $chapter->like_count,
'comment_count' => $chapter->comment_count,
];
}
@ -201,8 +183,7 @@ class ChapterInfo extends FrontendService
'model' => $chapter->model,
'content' => $read->content,
'user_count' => $chapter->user_count,
'agree_count' => $chapter->agree_count,
'oppose_count' => $chapter->oppose_count,
'like_count' => $chapter->like_count,
'comment_count' => $chapter->comment_count,
];
}

View File

@ -0,0 +1,89 @@
<?php
namespace App\Services\Frontend\Chapter;
use App\Models\Chapter as ChapterModel;
use App\Models\ChapterLike as ChapterLikeModel;
use App\Models\User as UserModel;
use App\Repos\ChapterLike as ChapterLikeRepo;
use App\Services\Frontend\ChapterTrait;
use App\Services\Frontend\Service as FrontendService;
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
use Phalcon\Di as Di;
use Phalcon\Events\Manager as EventsManager;
class ChapterLike extends FrontendService
{
use ChapterTrait;
public function handle($id)
{
$chapter = $this->checkChapter($id);
$user = $this->getLoginUser();
$validator = new UserDailyLimitValidator();
$validator->checkChapterLikeLimit($user);
$chapterLikeRepo = new ChapterLikeRepo();
$chapterLike = $chapterLikeRepo->findChapterLike($chapter->id, $user->id);
if (!$chapterLike) {
$chapterLike = new ChapterLikeModel();
$chapterLike->create([
'chapter_id' => $chapter->id,
'user_id' => $user->id,
]);
$this->incrLikeCount($chapter);
} else {
if ($chapterLike->deleted == 0) {
$chapterLike->update(['deleted' => 1]);
$this->decrLikeCount($chapter);
} else {
$chapterLike->update(['deleted' => 0]);
$this->incrLikeCount($chapter);
}
}
$this->incrUserDailyChapterLikeCount($user);
return $chapter;
}
protected function incrLikeCount(ChapterModel $chapter)
{
$this->getPhEventsManager()->fire('chapterCounter:incrLikeCount', $this, $chapter);
}
protected function decrLikeCount(ChapterModel $chapter)
{
$this->getPhEventsManager()->fire('chapterCounter:decrLikeCount', $this, $chapter);
}
protected function incrUserDailyChapterLikeCount(UserModel $user)
{
$this->getPhEventsManager()->fire('userDailyCounter:incrChapterLikeCount', $this, $user);
}
/**
* @return EventsManager
*/
protected function getPhEventsManager()
{
return Di::getDefault()->get('eventsManager');
}
}

View File

@ -4,10 +4,6 @@ namespace App\Services\Frontend\Chapter;
use App\Builders\CommentList as CommentListBuilder;
use App\Library\Paginator\Query as PagerQuery;
use App\Models\Chapter as ChapterModel;
use App\Models\CommentVote as CommentVoteModel;
use App\Models\User as UserModel;
use App\Repos\Chapter as ChapterRepo;
use App\Repos\Comment as CommentRepo;
use App\Services\Frontend\ChapterTrait;
use App\Services\Frontend\Service as FrontendService;
@ -15,29 +11,17 @@ use App\Services\Frontend\Service as FrontendService;
class CommentList extends FrontendService
{
/**
* @var ChapterModel
*/
protected $chapter;
/**
* @var UserModel
*/
protected $user;
use ChapterTrait;
public function handle($chapterId)
{
$this->chapter = $this->checkChapter($chapterId);
$this->user = $this->getCurrentUser();
$chapter = $this->checkChapter($chapterId);
$pagerQuery = new PagerQuery();
$params = $pagerQuery->getParams();
$params['chapter_id'] = $this->chapter->id;
$params['chapter_id'] = $chapter->id;
$params['published'] = 1;
$params['deleted'] = 0;
@ -64,8 +48,6 @@ class CommentList extends FrontendService
$users = $builder->getUsers($comments);
$votes = $this->getCommentVotes($this->chapter, $this->user);
$items = [];
foreach ($comments as $comment) {
@ -74,21 +56,14 @@ class CommentList extends FrontendService
$comment['mentions'] = $comment['mentions'] ? json_decode($comment['mentions']) : [];
$me = [
'agreed' => $votes[$comment['id']]['agreed'] ?? 0,
'opposed' => $votes[$comment['id']]['opposed'] ?? 0,
];
$items[] = [
'id' => $comment['id'],
'content' => $comment['content'],
'mentions' => $comment['mentions'],
'agree_count' => $comment['agree_count'],
'oppose_count' => $comment['oppose_count'],
'like_count' => $comment['like_count'],
'reply_count' => $comment['reply_count'],
'create_time' => $comment['create_time'],
'user' => $user,
'me' => $me,
];
}
@ -97,30 +72,4 @@ class CommentList extends FrontendService
return $pager;
}
protected function getCommentVotes(ChapterModel $chapter, UserModel $user)
{
if ($chapter->id == 0 || $user->id == 0) {
return [];
}
$chapterRepo = new ChapterRepo();
$votes = $chapterRepo->findUserCommentVotes($chapter->id, $user->id);
if ($votes->count() == 0) {
return [];
}
$result = [];
foreach ($votes as $vote) {
$result[$vote->comment_id] = [
'agreed' => $vote->type == CommentVoteModel::TYPE_AGREE ? 1 : 0,
'opposed' => $vote->type == CommentVoteModel::TYPE_OPPOSE ? 1 : 0,
];
}
return $result;
}
}

View File

@ -1,73 +0,0 @@
<?php
namespace App\Services\Frontend\Chapter;
use App\Models\ChapterVote as ChapterVoteModel;
use App\Repos\ChapterVote as ChapterVoteRepo;
use App\Services\Frontend\ChapterTrait;
use App\Services\Frontend\Service as FrontendService;
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
class OpposeVote extends FrontendService
{
use ChapterTrait, VoteTrait;
public function handle($id)
{
$chapter = $this->checkChapter($id);
$user = $this->getLoginUser();
$validator = new UserDailyLimitValidator();
$validator->checkChapterVoteLimit($user);
$chapterVoteRepo = new ChapterVoteRepo();
$chapterVote = $chapterVoteRepo->findChapterVote($chapter->id, $user->id);
if (!$chapterVote) {
$chapterVote = new ChapterVoteModel();
$chapterVote->chapter_id = $chapter->id;
$chapterVote->user_id = $user->id;
$chapterVote->type = ChapterVoteModel::TYPE_OPPOSE;
$chapterVote->create();
$this->incrOpposeCount($chapter);
} else {
if ($chapterVote->type == ChapterVoteModel::TYPE_AGREE) {
$chapterVote->type = ChapterVoteModel::TYPE_OPPOSE;
$this->decrAgreeCount($chapter);
$this->incrOpposeCount($chapter);
} elseif ($chapterVote->type == ChapterVoteModel::TYPE_OPPOSE) {
$chapterVote->type = ChapterVoteModel::TYPE_NONE;
$this->decrOpposeCount($chapter);
} elseif ($chapterVote->type == ChapterVoteModel::TYPE_NONE) {
$chapterVote->type = ChapterVoteModel::TYPE_OPPOSE;
$this->incrOpposeCount($chapter);
}
$chapterVote->update();
}
$this->incrUserDailyChapterVoteCount($user);
return $chapter;
}
}

View File

@ -1,46 +0,0 @@
<?php
namespace App\Services\Frontend\Chapter;
use App\Models\Chapter as ChapterModel;
use App\Models\User as UserModel;
use Phalcon\Di as Di;
use Phalcon\Events\Manager as EventsManager;
trait VoteTrait
{
protected function incrAgreeCount(ChapterModel $chapter)
{
$this->getPhEventsManager()->fire('chapterCounter:incrAgreeCount', $this, $chapter);
}
protected function decrAgreeCount(ChapterModel $chapter)
{
$this->getPhEventsManager()->fire('chapterCounter:decrAgreeCount', $this, $chapter);
}
protected function incrOpposeCount(ChapterModel $chapter)
{
$this->getPhEventsManager()->fire('chapterCounter:incrOpposeCount', $this, $chapter);
}
protected function decrOpposeCount(ChapterModel $chapter)
{
$this->getPhEventsManager()->fire('chapterCounter:decrOpposeCount', $this, $chapter);
}
protected function incrUserDailyChapterVoteCount(UserModel $user)
{
$this->getPhEventsManager()->fire('userDailyCounter:incrChapterVoteCount', $this, $user);
}
/**
* @return EventsManager
*/
protected function getPhEventsManager()
{
return Di::getDefault()->get('eventsManager');
}
}

View File

@ -1,73 +0,0 @@
<?php
namespace App\Services\Frontend\Comment;
use App\Models\CommentVote as CommentVoteModel;
use App\Repos\CommentVote as CommentVoteRepo;
use App\Services\Frontend\CommentTrait;
use App\Services\Frontend\Service as FrontendService;
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
class AgreeVote extends FrontendService
{
use CommentTrait, VoteTrait;
public function handle($id)
{
$comment = $this->checkComment($id);
$user = $this->getLoginUser();
$validator = new UserDailyLimitValidator();
$validator->checkCommentVoteLimit($user);
$commentVoteRepo = new CommentVoteRepo();
$commentVote = $commentVoteRepo->findCommentVote($comment->id, $user->id);
if (!$commentVote) {
$commentVote = new CommentVoteModel();
$commentVote->comment_id = $comment->id;
$commentVote->user_id = $user->id;
$commentVote->type = CommentVoteModel::TYPE_AGREE;
$commentVote->create();
$this->incrAgreeCount($comment);
} else {
if ($commentVote->type == CommentVoteModel::TYPE_AGREE) {
$commentVote->type = CommentVoteModel::TYPE_NONE;
$this->decrAgreeCount($comment);
} elseif ($commentVote->type == CommentVoteModel::TYPE_OPPOSE) {
$commentVote->type = CommentVoteModel::TYPE_AGREE;
$this->incrAgreeCount($comment);
$this->decrOpposeCount($comment);
} elseif ($commentVote->type == CommentVoteModel::TYPE_NONE) {
$commentVote->type = CommentVoteModel::TYPE_AGREE;
$this->incrAgreeCount($comment);
}
$commentVote->update();
}
$this->incrUserDailyCommentVoteCount($user);
return $comment;
}
}

View File

@ -3,9 +3,6 @@
namespace App\Services\Frontend\Comment;
use App\Models\Comment as CommentModel;
use App\Models\CommentVote as CommentVoteModel;
use App\Models\User as UserModel;
use App\Repos\CommentVote as CommentVoteRepo;
use App\Repos\User as UserRepo;
use App\Services\Frontend\CommentTrait;
use App\Services\Frontend\Service as FrontendService;
@ -19,52 +16,29 @@ class CommentInfo extends FrontendService
{
$comment = $this->checkComment($id);
$user = $this->getCurrentUser();
return $this->handleComment($comment, $user);
return $this->handleComment($comment);
}
protected function handleComment(CommentModel $comment, UserModel $user)
protected function handleComment(CommentModel $comment)
{
$result = [
'id' => $comment->id,
'content' => $comment->content,
'mentions' => $comment->mentions,
'agree_count' => $comment->agree_count,
'oppose_count' => $comment->oppose_count,
'like_count' => $comment->like_count,
'create_time' => $comment->create_time,
'update_time' => $comment->update_time,
];
$me = [
'agreed' => 0,
'opposed' => 0,
];
if ($user->id > 0) {
$voteRepo = new CommentVoteRepo();
$vote = $voteRepo->findCommentVote($comment->id, $user->id);
if ($vote) {
$me['agreed'] = $vote->type == CommentVoteModel::TYPE_AGREE ? 1 : 0;
$me['opposed'] = $vote->type == CommentVoteModel::TYPE_OPPOSE ? 1 : 0;
}
}
$userRepo = new UserRepo();
$owner = $userRepo->findById($comment->user_id);
$result['owner'] = [
$result['user'] = [
'id' => $owner->id,
'name' => $owner->name,
'avatar' => $owner->avatar,
];
$result['me'] = $me;
return $result;
}

View File

@ -0,0 +1,89 @@
<?php
namespace App\Services\Frontend\Comment;
use App\Models\Comment as CommentModel;
use App\Models\CommentLike as CommentLikeModel;
use App\Models\User as UserModel;
use App\Repos\CommentLike as CommentLikeRepo;
use App\Services\Frontend\CommentTrait;
use App\Services\Frontend\Service as FrontendService;
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
use Phalcon\Di as Di;
use Phalcon\Events\Manager as EventsManager;
class CommentLike extends FrontendService
{
use CommentTrait;
public function handle($id)
{
$comment = $this->checkComment($id);
$user = $this->getLoginUser();
$validator = new UserDailyLimitValidator();
$validator->checkCommentLikeLimit($user);
$commentLikeRepo = new CommentLikeRepo();
$commentLike = $commentLikeRepo->findCommentLike($comment->id, $user->id);
if (!$commentLike) {
$commentLike = new CommentLikeModel();
$commentLike->create([
'comment_id' => $comment->id,
'user_id' => $user->id,
]);
$this->incrLikeCount($comment);
} else {
if ($commentLike->deleted == 0) {
$commentLike->update(['deleted' => 1]);
$this->decrLikeCount($comment);
} else {
$commentLike->update(['deleted' => 0]);
$this->incrLikeCount($comment);
}
}
$this->incrUserDailyCommentLikeCount($user);
return $comment;
}
protected function incrLikeCount(CommentModel $comment)
{
$this->getPhEventsManager()->fire('commentCounter:incrLikeCount', $this, $comment);
}
protected function decrLikeCount(CommentModel $comment)
{
$this->getPhEventsManager()->fire('commentCounter:decrLikeCount', $this, $comment);
}
protected function incrUserDailyCommentLikeCount(UserModel $user)
{
$this->getPhEventsManager()->fire('userDailyCounter:incrCommentLikeCount', $this, $user);
}
/**
* @return EventsManager
*/
protected function getPhEventsManager()
{
return Di::getDefault()->get('eventsManager');
}
}

View File

@ -1,73 +0,0 @@
<?php
namespace App\Services\Frontend\Comment;
use App\Models\CommentVote as CommentVoteModel;
use App\Repos\CommentVote as CommentVoteRepo;
use App\Services\Frontend\CommentTrait;
use App\Services\Frontend\Service as FrontendService;
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
class OpposeVote extends FrontendService
{
use CommentTrait, VoteTrait;
public function handle($id)
{
$comment = $this->checkComment($id);
$user = $this->getLoginUser();
$validator = new UserDailyLimitValidator();
$validator->checkCommentVoteLimit($user);
$commentVoteRepo = new CommentVoteRepo();
$commentVote = $commentVoteRepo->findCommentVote($comment->id, $user->id);
if (!$commentVote) {
$commentVote = new CommentVoteModel();
$commentVote->comment_id = $comment->id;
$commentVote->user_id = $user->id;
$commentVote->type = CommentVoteModel::TYPE_OPPOSE;
$commentVote->create();
$this->incrOpposeCount($comment);
} else {
if ($commentVote->type == CommentVoteModel::TYPE_AGREE) {
$commentVote->type = CommentVoteModel::TYPE_OPPOSE;
$this->decrAgreeCount($comment);
$this->incrOpposeCount($comment);
} elseif ($commentVote->type == CommentVoteModel::TYPE_OPPOSE) {
$commentVote->type = CommentVoteModel::TYPE_NONE;
$this->decrOpposeCount($comment);
} elseif ($commentVote->type == CommentVoteModel::TYPE_NONE) {
$commentVote->type = CommentVoteModel::TYPE_OPPOSE;
$this->incrOpposeCount($comment);
}
$commentVote->update();
}
$this->incrUserDailyCommentVoteCount($user);
return $comment;
}
}

View File

@ -1,46 +0,0 @@
<?php
namespace App\Services\Frontend\Comment;
use App\Models\Comment as CommentModel;
use App\Models\User as UserModel;
use Phalcon\Di as Di;
use Phalcon\Events\Manager as EventsManager;
trait VoteTrait
{
protected function incrAgreeCount(CommentModel $comment)
{
$this->getPhEventsManager()->fire('commentCounter:incrAgreeCount', $this, $comment);
}
protected function decrAgreeCount(CommentModel $comment)
{
$this->getPhEventsManager()->fire('commentCounter:decrAgreeCount', $this, $comment);
}
protected function incrOpposeCount(CommentModel $comment)
{
$this->getPhEventsManager()->fire('commentCounter:incrOpposeCount', $this, $comment);
}
protected function decrOpposeCount(CommentModel $comment)
{
$this->getPhEventsManager()->fire('commentCounter:decrOpposeCount', $this, $comment);
}
protected function incrUserDailyCommentVoteCount(UserModel $user)
{
$this->getPhEventsManager()->fire('userDailyCounter:incrCommentVoteCount', $this, $user);
}
/**
* @return EventsManager
*/
protected function getPhEventsManager()
{
return Di::getDefault()->get('eventsManager');
}
}

View File

@ -1,73 +0,0 @@
<?php
namespace App\Services\Frontend\Consult;
use App\Models\ConsultVote as ConsultVoteModel;
use App\Repos\ConsultVote as ConsultVoteRepo;
use App\Services\Frontend\ConsultTrait;
use App\Services\Frontend\Service as FrontendService;
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
class AgreeVote extends FrontendService
{
use ConsultTrait, VoteTrait;
public function handle($id)
{
$consult = $this->checkConsult($id);
$user = $this->getLoginUser();
$validator = new UserDailyLimitValidator();
$validator->checkConsultVoteLimit($user);
$consultVoteRepo = new ConsultVoteRepo();
$consultVote = $consultVoteRepo->findConsultVote($consult->id, $user->id);
if (!$consultVote) {
$consultVote = new ConsultVoteModel();
$consultVote->consult_id = $consult->id;
$consultVote->user_id = $user->id;
$consultVote->type = ConsultVoteModel::TYPE_AGREE;
$consultVote->create();
$this->incrAgreeCount($consult);
} else {
if ($consultVote->type == ConsultVoteModel::TYPE_AGREE) {
$consultVote->type = ConsultVoteModel::TYPE_NONE;
$this->decrAgreeCount($consult);
} elseif ($consultVote->type == ConsultVoteModel::TYPE_OPPOSE) {
$consultVote->type = ConsultVoteModel::TYPE_AGREE;
$this->incrAgreeCount($consult);
$this->decrOpposeCount($consult);
} elseif ($consultVote->type == ConsultVoteModel::TYPE_NONE) {
$consultVote->type = ConsultVoteModel::TYPE_AGREE;
$this->incrAgreeCount($consult);
}
$consultVote->update();
}
$this->incrUserDailyConsultVoteCount($user);
return $consult;
}
}

View File

@ -3,9 +3,6 @@
namespace App\Services\Frontend\Consult;
use App\Models\Consult as ConsultModel;
use App\Models\ConsultVote as ConsultVoteModel;
use App\Models\User as UserModel;
use App\Repos\ConsultVote as ConsultVoteRepo;
use App\Repos\User as UserRepo;
use App\Services\Frontend\ConsultTrait;
use App\Services\Frontend\Service as FrontendService;
@ -19,52 +16,30 @@ class ConsultInfo extends FrontendService
{
$consult = $this->checkConsult($id);
$user = $this->getCurrentUser();
return $this->handleConsult($consult, $user);
return $this->handleConsult($consult);
}
protected function handleConsult(ConsultModel $consult, UserModel $user)
protected function handleConsult(ConsultModel $consult)
{
$result = [
'id' => $consult->id,
'question' => $consult->question,
'answer' => $consult->answer,
'agree_count' => $consult->agree_count,
'oppose_count' => $consult->oppose_count,
'like_count' => $consult->like_count,
'create_time' => $consult->create_time,
'update_time' => $consult->update_time,
];
$me = [
'agreed' => 0,
'opposed' => 0,
];
if ($user->id > 0) {
$voteRepo = new ConsultVoteRepo();
$vote = $voteRepo->findConsultVote($consult->id, $user->id);
if ($vote) {
$me['agreed'] = $vote->type == ConsultVoteModel::TYPE_AGREE ? 1 : 0;
$me['opposed'] = $vote->type == ConsultVoteModel::TYPE_OPPOSE ? 1 : 0;
}
}
$userRepo = new UserRepo();
$owner = $userRepo->findById($consult->user_id);
$result['owner'] = [
$result['user'] = [
'id' => $owner->id,
'name' => $owner->name,
'avatar' => $owner->avatar,
];
$result['me'] = $me;
return $result;
}

View File

@ -0,0 +1,89 @@
<?php
namespace App\Services\Frontend\Consult;
use App\Models\Consult as ConsultModel;
use App\Models\ConsultLike as ConsultLikeModel;
use App\Models\User as UserModel;
use App\Repos\ConsultLike as ConsultLikeRepo;
use App\Services\Frontend\ConsultTrait;
use App\Services\Frontend\Service as FrontendService;
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
use Phalcon\Di as Di;
use Phalcon\Events\Manager as EventsManager;
class ConsultLike extends FrontendService
{
use ConsultTrait;
public function handle($id)
{
$consult = $this->checkConsult($id);
$user = $this->getLoginUser();
$validator = new UserDailyLimitValidator();
$validator->checkConsultLikeLimit($user);
$consultLikeRepo = new ConsultLikeRepo();
$consultLike = $consultLikeRepo->findConsultLike($consult->id, $user->id);
if (!$consultLike) {
$consultLike = new ConsultLikeModel();
$consultLike->create([
'consult_id' => $consult->id,
'user_id' => $user->id,
]);
$this->incrLikeCount($consult);
} else {
if ($consultLike->deleted == 0) {
$consultLike->update(['deleted' => 1]);
$this->decrLikeCount($consult);
} else {
$consultLike->update(['deleted' => 0]);
$this->incrLikeCount($consult);
}
}
$this->incrUserDailyConsultLikeCount($user);
return $consult;
}
protected function incrLikeCount(ConsultModel $consult)
{
$this->getPhEventsManager()->fire('consultCounter:incrLikeCount', $this, $consult);
}
protected function decrLikeCount(ConsultModel $consult)
{
$this->getPhEventsManager()->fire('consultCounter:decrLikeCount', $this, $consult);
}
protected function incrUserDailyConsultLikeCount(UserModel $user)
{
$this->getPhEventsManager()->fire('userDailyCounter:incrConsultLikeCount', $this, $user);
}
/**
* @return EventsManager
*/
protected function getPhEventsManager()
{
return Di::getDefault()->get('eventsManager');
}
}

View File

@ -1,73 +0,0 @@
<?php
namespace App\Services\Frontend\Consult;
use App\Models\ConsultVote as ConsultVoteModel;
use App\Repos\ConsultVote as ConsultVoteRepo;
use App\Services\Frontend\ConsultTrait;
use App\Services\Frontend\Service as FrontendService;
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
class OpposeVote extends FrontendService
{
use ConsultTrait, VoteTrait;
public function handle($id)
{
$consult = $this->checkConsult($id);
$user = $this->getLoginUser();
$validator = new UserDailyLimitValidator();
$validator->checkConsultVoteLimit($user);
$consultVoteRepo = new ConsultVoteRepo();
$consultVote = $consultVoteRepo->findConsultVote($consult->id, $user->id);
if (!$consultVote) {
$consultVote = new ConsultVoteModel();
$consultVote->consult_id = $consult->id;
$consultVote->user_id = $user->id;
$consultVote->type = ConsultVoteModel::TYPE_OPPOSE;
$consultVote->create();
$this->incrOpposeCount($consult);
} else {
if ($consultVote->type == ConsultVoteModel::TYPE_AGREE) {
$consultVote->type = ConsultVoteModel::TYPE_OPPOSE;
$this->decrAgreeCount($consult);
$this->incrOpposeCount($consult);
} elseif ($consultVote->type == ConsultVoteModel::TYPE_OPPOSE) {
$consultVote->type = ConsultVoteModel::TYPE_NONE;
$this->decrOpposeCount($consult);
} elseif ($consultVote->type == ConsultVoteModel::TYPE_NONE) {
$consultVote->type = ConsultVoteModel::TYPE_OPPOSE;
$this->incrOpposeCount($consult);
}
$consultVote->update();
}
$this->incrUserDailyConsultVoteCount($user);
return $consult;
}
}

View File

@ -1,46 +0,0 @@
<?php
namespace App\Services\Frontend\Consult;
use App\Models\Consult as ConsultModel;
use App\Models\User as UserModel;
use Phalcon\Di as Di;
use Phalcon\Events\Manager as EventsManager;
trait VoteTrait
{
protected function incrAgreeCount(ConsultModel $consult)
{
$this->getPhEventsManager()->fire('consultCounter:incrAgreeCount', $this, $consult);
}
protected function decrAgreeCount(ConsultModel $consult)
{
$this->getPhEventsManager()->fire('consultCounter:decrAgreeCount', $this, $consult);
}
protected function incrOpposeCount(ConsultModel $consult)
{
$this->getPhEventsManager()->fire('consultCounter:incrOpposeCount', $this, $consult);
}
protected function decrOpposeCount(ConsultModel $consult)
{
$this->getPhEventsManager()->fire('consultCounter:decrOpposeCount', $this, $consult);
}
protected function incrUserDailyConsultVoteCount(UserModel $user)
{
$this->getPhEventsManager()->fire('userDailyCounter:incrConsultVoteCount', $this, $user);
}
/**
* @return EventsManager
*/
protected function getPhEventsManager()
{
return Di::getDefault()->get('eventsManager');
}
}

View File

@ -4,34 +4,18 @@ namespace App\Services\Frontend\Course;
use App\Builders\ConsultList as ConsultListBuilder;
use App\Library\Paginator\Query as PagerQuery;
use App\Models\ConsultVote as ConsultVoteModel;
use App\Models\Course as CourseModel;
use App\Models\User as UserModel;
use App\Repos\Consult as ConsultRepo;
use App\Repos\Course as CourseRepo;
use App\Services\Frontend\CourseTrait;
use App\Services\Frontend\Service as FrontendService;
class ConsultList extends FrontendService
{
/**
* @var CourseModel
*/
protected $course;
/**
* @var UserModel
*/
protected $user;
use CourseTrait;
public function handle($id)
{
$this->course = $this->checkCourse($id);
$this->user = $this->getCurrentUser();
$course = $this->checkCourse($id);
$pagerQuery = new PagerQuery();
@ -40,7 +24,7 @@ class ConsultList extends FrontendService
$limit = $pagerQuery->getLimit();
$params = [
'course_id' => $this->course->id,
'course_id' => $course->id,
'private' => 0,
'published' => 1,
'deleted' => 0,
@ -65,28 +49,20 @@ class ConsultList extends FrontendService
$users = $builder->getUsers($consults);
$votes = $this->getConsultVotes($this->course, $this->user);
$items = [];
foreach ($consults as $consult) {
$user = $users[$consult['user_id']] ?? new \stdClass();
$me = [
'agreed' => $votes[$consult['id']]['agreed'] ?? 0,
'opposed' => $votes[$consult['id']]['opposed'] ?? 0,
];
$items[] = [
'id' => $consult['id'],
'question' => $consult['question'],
'answer' => $consult['answer'],
'agree_count' => $consult['agree_count'],
'oppose_count' => $consult['oppose_count'],
'like_count' => $consult['like_count'],
'create_time' => $consult['create_time'],
'update_time' => $consult['update_time'],
'user' => $user,
'me' => $me,
];
}
@ -95,30 +71,4 @@ class ConsultList extends FrontendService
return $pager;
}
protected function getConsultVotes(CourseModel $course, UserModel $user)
{
if ($course->id == 0 || $user->id == 0) {
return [];
}
$courseRepo = new CourseRepo();
$votes = $courseRepo->findUserConsultVotes($course->id, $user->id);
if ($votes->count() == 0) {
return [];
}
$result = [];
foreach ($votes as $vote) {
$result[$vote->consult_id] = [
'agreed' => $vote->type == ConsultVoteModel::TYPE_AGREE ? 1 : 0,
'opposed' => $vote->type == ConsultVoteModel::TYPE_OPPOSE ? 1 : 0,
];
}
return $result;
}
}

View File

@ -4,10 +4,6 @@ namespace App\Services\Frontend\Course;
use App\Builders\ReviewList as ReviewListBuilder;
use App\Library\Paginator\Query as PagerQuery;
use App\Models\Course as CourseModel;
use App\Models\ReviewVote as ReviewVoteModel;
use App\Models\User as UserModel;
use App\Repos\Course as CourseRepo;
use App\Repos\Review as ReviewRepo;
use App\Services\Frontend\CourseTrait;
use App\Services\Frontend\Service as FrontendService;
@ -15,23 +11,11 @@ use App\Services\Frontend\Service as FrontendService;
class ReviewList extends FrontendService
{
/**
* @var CourseModel
*/
protected $course;
/**
* @var UserModel
*/
protected $user;
use CourseTrait;
public function handle($id)
{
$this->course = $this->checkCourse($id);
$this->user = $this->getCurrentUser();
$course = $this->checkCourse($id);
$pagerQuery = new PagerQuery();
@ -40,7 +24,7 @@ class ReviewList extends FrontendService
$limit = $pagerQuery->getLimit();
$params = [
'course_id' => $this->course->id,
'course_id' => $course->id,
'published' => 1,
'deleted' => 0,
];
@ -64,28 +48,19 @@ class ReviewList extends FrontendService
$users = $builder->getUsers($reviews);
$votes = $this->getReviewVotes($this->course, $this->user);
$items = [];
foreach ($reviews as $review) {
$user = $users[$review['user_id']] ?? new \stdClass();
$me = [
'agreed' => $votes[$review['id']]['agreed'] ?? 0,
'opposed' => $votes[$review['id']]['opposed'] ?? 0,
];
$items[] = [
'id' => $review['id'],
'rating' => $review['rating'],
'content' => $review['content'],
'agree_count' => $review['agree_count'],
'oppose_count' => $review['oppose_count'],
'like_count' => $review['like_count'],
'create_time' => $review['create_time'],
'user' => $user,
'me' => $me,
];
}
@ -94,30 +69,4 @@ class ReviewList extends FrontendService
return $pager;
}
protected function getReviewVotes(CourseModel $course, UserModel $user)
{
if ($course->id == 0 || $user->id == 0) {
return [];
}
$courseRepo = new CourseRepo();
$votes = $courseRepo->findUserReviewVotes($course->id, $user->id);
if ($votes->count() == 0) {
return [];
}
$result = [];
foreach ($votes as $vote) {
$result[$vote->review_id] = [
'agreed' => $vote->type == ReviewVoteModel::TYPE_AGREE ? 1 : 0,
'opposed' => $vote->type == ReviewVoteModel::TYPE_OPPOSE ? 1 : 0,
];
}
return $result;
}
}

View File

@ -57,8 +57,7 @@ class ConsultList extends FrontendService
'id' => $consult['id'],
'question' => $consult['question'],
'answer' => $consult['answer'],
'agree_count' => $consult['agree_count'],
'oppose_count' => $consult['oppose_count'],
'like_count' => $consult['like_count'],
'create_time' => $consult['create_time'],
'update_time' => $consult['update_time'],
'course' => $course,

View File

@ -57,8 +57,7 @@ class ReviewList extends FrontendService
'id' => $review['id'],
'question' => $review['question'],
'answer' => $review['answer'],
'agree_count' => $review['agree_count'],
'oppose_count' => $review['oppose_count'],
'like_count' => $review['like_count'],
'create_time' => $review['create_time'],
'update_time' => $review['update_time'],
'course' => $course,

View File

@ -1,73 +0,0 @@
<?php
namespace App\Services\Frontend\Review;
use App\Models\ReviewVote as ReviewVoteModel;
use App\Repos\ReviewVote as ReviewVoteRepo;
use App\Services\Frontend\ReviewTrait;
use App\Services\Frontend\Service as FrontendService;
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
class AgreeVote extends FrontendService
{
use ReviewTrait, VoteTrait;
public function handle($id)
{
$review = $this->checkReview($id);
$user = $this->getLoginUser();
$validator = new UserDailyLimitValidator();
$validator->checkReviewVoteLimit($user);
$reviewVoteRepo = new ReviewVoteRepo();
$reviewVote = $reviewVoteRepo->findReviewVote($review->id, $user->id);
if (!$reviewVote) {
$reviewVote = new ReviewVoteModel();
$reviewVote->review_id = $review->id;
$reviewVote->user_id = $user->id;
$reviewVote->type = ReviewVoteModel::TYPE_AGREE;
$reviewVote->create();
$this->incrAgreeCount($review);
} else {
if ($reviewVote->type == ReviewVoteModel::TYPE_AGREE) {
$reviewVote->type = ReviewVoteModel::TYPE_NONE;
$this->decrAgreeCount($review);
} elseif ($reviewVote->type == ReviewVoteModel::TYPE_OPPOSE) {
$reviewVote->type = ReviewVoteModel::TYPE_AGREE;
$this->incrAgreeCount($review);
$this->decrOpposeCount($review);
} elseif ($reviewVote->type == ReviewVoteModel::TYPE_NONE) {
$reviewVote->type = ReviewVoteModel::TYPE_AGREE;
$this->incrAgreeCount($review);
}
$reviewVote->update();
}
$this->incrUserDailyReviewVoteCount($user);
return $review;
}
}

View File

@ -1,73 +0,0 @@
<?php
namespace App\Services\Frontend\Review;
use App\Models\ReviewVote as ReviewVoteModel;
use App\Repos\ReviewVote as ReviewVoteRepo;
use App\Services\Frontend\ReviewTrait;
use App\Services\Frontend\Service as FrontendService;
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
class OpposeVote extends FrontendService
{
use ReviewTrait, VoteTrait;
public function handle($id)
{
$review = $this->checkReview($id);
$user = $this->getLoginUser();
$validator = new UserDailyLimitValidator();
$validator->checkReviewVoteLimit($user);
$reviewVoteRepo = new ReviewVoteRepo();
$reviewVote = $reviewVoteRepo->findReviewVote($review->id, $user->id);
if (!$reviewVote) {
$reviewVote = new ReviewVoteModel();
$reviewVote->review_id = $review->id;
$reviewVote->user_id = $user->id;
$reviewVote->type = ReviewVoteModel::TYPE_OPPOSE;
$reviewVote->create();
$this->incrOpposeCount($review);
} else {
if ($reviewVote->type == ReviewVoteModel::TYPE_AGREE) {
$reviewVote->type = ReviewVoteModel::TYPE_OPPOSE;
$this->decrAgreeCount($review);
$this->incrOpposeCount($review);
} elseif ($reviewVote->type == ReviewVoteModel::TYPE_OPPOSE) {
$reviewVote->type = ReviewVoteModel::TYPE_NONE;
$this->decrOpposeCount($review);
} elseif ($reviewVote->type == ReviewVoteModel::TYPE_NONE) {
$reviewVote->type = ReviewVoteModel::TYPE_OPPOSE;
$this->incrOpposeCount($review);
}
$reviewVote->update();
}
$this->incrUserDailyReviewVoteCount($user);
return $review;
}
}

View File

@ -29,19 +29,22 @@ class ReviewCreate extends FrontendService
$validator = new ReviewValidator();
$content = $validator->checkContent($post['content']);
$rating = $validator->checkRating($post['rating']);
$data = [];
$data['content'] = $validator->checkContent($post['content']);
$data['rating1'] = $validator->checkRating($post['rating1']);
$data['rating2'] = $validator->checkRating($post['rating2']);
$data['rating3'] = $validator->checkRating($post['rating3']);
$validator->checkIfReviewed($course->id, $user->id);
$data['rating'] = $this->getAvgRating($data['rating1'], $data['rating2'], $data['rating3']);
$data['course_id'] = $course->id;
$data['user_id'] = $user->id;
$review = new ReviewModel();
$review->course_id = $course->id;
$review->user_id = $user->id;
$review->content = $content;
$review->rating = $rating;
$review->create();
$review->create($data);
$this->incrCourseReviewCount($course);
@ -50,6 +53,11 @@ class ReviewCreate extends FrontendService
return $review;
}
protected function getAvgRating($rating1, $rating2, $rating3)
{
return round(($rating1 + $rating2 + $rating3) / 3, 2);
}
protected function incrCourseReviewCount(CourseModel $course)
{
$this->eventsManager->fire('courseCounter:incrReviewCount', $this, $course);

View File

@ -3,9 +3,6 @@
namespace App\Services\Frontend\Review;
use App\Models\Review as ReviewModel;
use App\Models\ReviewVote as ReviewVoteModel;
use App\Models\User as UserModel;
use App\Repos\ReviewVote as ReviewVoteRepo;
use App\Repos\User as UserRepo;
use App\Services\Frontend\ReviewTrait;
use App\Services\Frontend\Service as FrontendService;
@ -19,53 +16,31 @@ class ReviewInfo extends FrontendService
{
$review = $this->checkReview($id);
$user = $this->getCurrentUser();
return $this->handleReview($review, $user);
return $this->handleReview($review);
}
protected function handleReview(ReviewModel $review, UserModel $user)
protected function handleReview(ReviewModel $review)
{
$result = [
'id' => $review->id,
'content' => $review->content,
'reply' => $review->reply,
'rating' => $review->rating,
'agree_count' => $review->agree_count,
'oppose_count' => $review->oppose_count,
'like_count' => $review->like_count,
'create_time' => $review->create_time,
'update_time' => $review->update_time,
];
$me = [
'agreed' => 0,
'opposed' => 0,
];
if ($user->id > 0) {
$voteRepo = new ReviewVoteRepo();
$vote = $voteRepo->findReviewVote($review->id, $user->id);
if ($vote) {
$me['agreed'] = $vote->type == ReviewVoteModel::TYPE_AGREE ? 1 : 0;
$me['opposed'] = $vote->type == ReviewVoteModel::TYPE_OPPOSE ? 1 : 0;
}
}
$userRepo = new UserRepo();
$owner = $userRepo->findById($review->user_id);
$result['owner'] = [
$result['user'] = [
'id' => $owner->id,
'name' => $owner->name,
'avatar' => $owner->avatar,
];
$result['me'] = $me;
return $result;
}

View File

@ -0,0 +1,91 @@
<?php
namespace App\Services\Frontend\Review;
use App\Models\Review as ReviewModel;
use App\Models\ReviewLike as ReviewLikeModel;
use App\Models\User as UserModel;
use App\Repos\ReviewLike as ReviewLikeRepo;
use App\Services\Frontend\ReviewTrait;
use App\Services\Frontend\Service as FrontendService;
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
use Phalcon\Di as Di;
use Phalcon\Events\Manager as EventsManager;
class ReviewLike extends FrontendService
{
use ReviewTrait;
public function handle($id)
{
$review = $this->checkReview($id);
$user = $this->getLoginUser();
$validator = new UserDailyLimitValidator();
$validator->checkReviewLikeLimit($user);
$reviewLikeRepo = new ReviewLikeRepo();
$reviewLike = $reviewLikeRepo->findReviewLike($review->id, $user->id);
if (!$reviewLike) {
$reviewLike = new ReviewLikeModel();
$reviewLike->create([
'review_id' => $review->id,
'user_id' => $user->id,
]);
$this->incrLikeCount($review);
} else {
if ($reviewLike->deleted == 0) {
$reviewLike->update(['deleted' => 1]);
$this->decrLikeCount($review);
} else {
$reviewLike->update(['deleted' => 0]);
$this->incrLikeCount($review);
}
$reviewLike->update();
}
$this->incrUserDailyReviewLikeCount($user);
return $review;
}
protected function incrLikeCount(ReviewModel $review)
{
$this->getPhEventsManager()->fire('reviewCounter:incrLikeCount', $this, $review);
}
protected function decrLikeCount(ReviewModel $review)
{
$this->getPhEventsManager()->fire('reviewCounter:decrLikeCount', $this, $review);
}
protected function incrUserDailyReviewLikeCount(UserModel $user)
{
$this->getPhEventsManager()->fire('userDailyCounter:incrReviewLikeCount', $this, $user);
}
/**
* @return EventsManager
*/
protected function getPhEventsManager()
{
return Di::getDefault()->get('eventsManager');
}
}

View File

@ -1,46 +0,0 @@
<?php
namespace App\Services\Frontend\Review;
use App\Models\Review as ReviewModel;
use App\Models\User as UserModel;
use Phalcon\Di as Di;
use Phalcon\Events\Manager as EventsManager;
trait VoteTrait
{
protected function incrAgreeCount(ReviewModel $review)
{
$this->getPhEventsManager()->fire('reviewCounter:incrAgreeCount', $this, $review);
}
protected function decrAgreeCount(ReviewModel $review)
{
$this->getPhEventsManager()->fire('reviewCounter:decrAgreeCount', $this, $review);
}
protected function incrOpposeCount(ReviewModel $review)
{
$this->getPhEventsManager()->fire('reviewCounter:incrOpposeCount', $this, $review);
}
protected function decrOpposeCount(ReviewModel $review)
{
$this->getPhEventsManager()->fire('reviewCounter:decrOpposeCount', $this, $review);
}
protected function incrUserDailyReviewVoteCount(UserModel $user)
{
$this->getPhEventsManager()->fire('userDailyCounter:incrReviewVoteCount', $this, $user);
}
/**
* @return EventsManager
*/
protected function getPhEventsManager()
{
return Di::getDefault()->get('eventsManager');
}
}

View File

@ -8,6 +8,7 @@ use App\Exceptions\BadRequest as BadRequestException;
use App\Models\Chapter as ChapterModel;
use App\Models\Course as CourseModel;
use App\Repos\Chapter as ChapterRepo;
use App\Repos\ChapterLike as ChapterLikeRepo;
use App\Repos\Course as CourseRepo;
class Chapter extends Validator
@ -173,4 +174,15 @@ class Chapter extends Validator
}
}
public function checkIfLiked($chapterId, $userId)
{
$repo = new ChapterLikeRepo();
$record = $repo->findChapterLike($chapterId, $userId);
if ($record && time() - $record->create_time > 86400) {
throw new BadRequestException('chapter.has_liked');
}
}
}

View File

@ -5,6 +5,7 @@ namespace App\Validators;
use App\Exceptions\BadRequest as BadRequestException;
use App\Repos\Chapter as ChapterRepo;
use App\Repos\Comment as CommentRepo;
use App\Repos\CommentLike as CommentLikeRepo;
use App\Repos\Course as CourseRepo;
class Comment extends Validator
@ -66,11 +67,6 @@ class Comment extends Validator
return $value;
}
public function checkMentions($mentions)
{
}
public function checkPublishStatus($status)
{
if (!in_array($status, [0, 1])) {
@ -80,4 +76,15 @@ class Comment extends Validator
return $status;
}
public function checkIfLiked($chapterId, $userId)
{
$repo = new CommentLikeRepo();
$record = $repo->findCommentLike($chapterId, $userId);
if ($record && time() - $record->create_time > 86400) {
throw new BadRequestException('comment.has_liked');
}
}
}

View File

@ -4,6 +4,7 @@ namespace App\Validators;
use App\Exceptions\BadRequest as BadRequestException;
use App\Repos\Consult as ConsultRepo;
use App\Repos\ConsultLike as ConsultLikeRepo;
class Consult extends Validator
{
@ -80,4 +81,15 @@ class Consult extends Validator
return $status;
}
public function checkIfLiked($chapterId, $userId)
{
$repo = new ConsultLikeRepo();
$record = $repo->findConsultLike($chapterId, $userId);
if ($record && time() - $record->create_time > 86400) {
throw new BadRequestException('consult.has_liked');
}
}
}

View File

@ -5,6 +5,7 @@ namespace App\Validators;
use App\Exceptions\BadRequest;
use App\Exceptions\BadRequest as BadRequestException;
use App\Repos\Review as ReviewRepo;
use App\Repos\ReviewLike as ReviewLikeRepo;
class Review extends Validator
{
@ -75,4 +76,15 @@ class Review extends Validator
}
}
public function checkIfLiked($chapterId, $userId)
{
$repo = new ReviewLikeRepo();
$record = $repo->findReviewLike($chapterId, $userId);
if ($record && time() - $record->create_time > 86400) {
throw new BadRequestException('review.has_liked');
}
}
}

View File

@ -78,47 +78,47 @@ class UserDailyLimit extends Validator
}
}
public function checkChapterVoteLimit(UserModel $user)
public function checkChapterLikeLimit(UserModel $user)
{
$count = $this->counter->hGet($user->id, 'chapter_vote_count');
$count = $this->counter->hGet($user->id, 'chapter_like_count');
$limit = $user->vip ? 200 : 100;
if ($count > $limit) {
throw new BadRequestException('user_daily_limit.reach_vote_limit');
throw new BadRequestException('user_daily_limit.reach_like_limit');
}
}
public function checkCommentVoteLimit(UserModel $user)
public function checkCommentLikeLimit(UserModel $user)
{
$count = $this->counter->hGet($user->id, 'comment_vote_count');
$count = $this->counter->hGet($user->id, 'comment_like_count');
$limit = $user->vip ? 200 : 100;
if ($count > $limit) {
throw new BadRequestException('user_daily_limit.reach_vote_limit');
throw new BadRequestException('user_daily_limit.reach_like_limit');
}
}
public function checkConsultVoteLimit(UserModel $user)
public function checkConsultLikeLimit(UserModel $user)
{
$count = $this->counter->hGet($user->id, 'consult_vote_count');
$count = $this->counter->hGet($user->id, 'consult_like_count');
$limit = $user->vip ? 200 : 100;
if ($count > $limit) {
throw new BadRequestException('user_daily_limit.reach_vote_limit');
throw new BadRequestException('user_daily_limit.reach_like_limit');
}
}
public function checkReviewVoteLimit(UserModel $user)
public function checkReviewLikeLimit(UserModel $user)
{
$count = $this->counter->hGet($user->id, 'review_vote_count');
$count = $this->counter->hGet($user->id, 'review_like_count');
$limit = $user->vip ? 200 : 100;
if ($count > $limit) {
throw new BadRequestException('user_daily_limit.reach_vote_limit');
throw new BadRequestException('user_daily_limit.reach_like_limit');
}
}

View File

@ -157,6 +157,7 @@ $error['chapter.read_not_ready'] = '文章内容尚未就绪';
$error['chapter.live_not_start'] = '直播尚未开始';
$error['chapter.live_time_empty'] = '直播时间尚未设置';
$error['chapter.child_existed'] = '不允许相关操作(存在子章节)';
$error['chapter.has_liked'] = '你已经点过赞啦';
/**
* 点播相关
@ -190,28 +191,28 @@ $error['review.invalid_rating'] = '无效的评分范围1-5';
$error['review.invalid_publish_status'] = '无效的发布状态';
$error['review.content_too_short'] = '评价内容太短少于5个字符';
$error['review.content_too_long'] = '评价内容太长多于255个字符';
$error['review.has_liked'] = '你已经点过赞啦';
/**
* 咨询相关
*/
$error['consult.not_found'] = '咨询不存在';
$error['consult.course_not_found'] = '课程不存在';
$error['consult.invalid_private_status'] = '无效的私密状态';
$error['consult.invalid_publish_status'] = '无效的发布状态';
$error['consult.question_too_short'] = '提问太短少于5个字符';
$error['consult.question_too_long'] = '提问太长多于1000个字符';
$error['consult.answer_too_short'] = '回复太短少于5个字符';
$error['consult.answer_too_long'] = '回复太长多于1000个字符';
$error['consult.has_liked'] = '你已经点过赞啦';
/**
* 评论相关
*/
$error['comment.not_found'] = '评价不存在';
$error['comment.course_not_found'] = '课程不存在';
$error['comment.chapter_not_found'] = '章节不存在';
$error['comment.invalid_publish_status'] = '无效的发布状态';
$error['comment.content_too_short'] = '评价太短少于1个字符';
$error['comment.content_too_long'] = '评价太长多于1000个字符';
$error['comment.has_liked'] = '你已经点过赞啦';
/**
* 单页相关
@ -303,7 +304,7 @@ $error['user_daily_limit.reach_comment_limit'] = '超出日评论限额';
$error['user_daily_limit.reach_consult_limit'] = '超出日咨询限额';
$error['user_daily_limit.reach_review_limit'] = '超出日评价限额';
$error['user_daily_limit.reach_order_limit'] = '超出日订单限额';
$error['user_daily_limit.reach_vote_limit'] = '超出日投票限额';
$error['user_daily_limit.reach_like_limit'] = '超出日点赞限额';
/**
* 课程查询

View File

@ -735,7 +735,11 @@
margin-right: 10px;
}
.sidebar-chapter-wrap .layui-field-title legend {
.sidebar-chapter .layui-field-title {
margin-top: 0;
}
.sidebar-chapter .layui-field-title legend {
text-align: center;
}
@ -782,12 +786,45 @@
margin-bottom: 0;
}
.danmu-action {
padding: 15px 20px;
.chapter-action {
position: relative;
padding: 20px;
margin-bottom: 0;
}
.danmu-action .layui-input {
.chapter-action .layui-icon {
margin-right: 5px;
cursor: pointer;
}
.chapter-action .active, .chapter-action .layui-icon:hover {
color: green;
}
.chapter-action span {
margin-right: 5px;
}
.chapter-action i {
margin-right: 5px;
}
.chapter-action em {
font-style: normal;
color: #999;
}
#icon-danmu-set {
position: absolute;
top: 22px;
right: 530px;
}
.chapter-action .layui-input {
position: absolute;
top: 15px;
right: 20px;
width: 500px;
height: 32px;
line-height: 32px;
font-size: 12px;

View File

@ -0,0 +1,37 @@
layui.use(['jquery', 'form', 'layer'], function () {
var $ = layui.jquery;
var layer = layui.layer;
var $likeIcon = $('#icon-like');
var $likeCount = $('#like-count');
var likeCount = parseInt($likeCount.text());
$likeIcon.on('click', function () {
$.ajax({
type: 'POST',
url: $(this).data('url'),
success: function (res) {
if ($likeIcon.hasClass('active')) {
$likeIcon.removeClass('active');
$likeCount.text(likeCount - 1);
likeCount -= 1;
} else {
$likeIcon.addClass('active');
$likeCount.text(likeCount + 1);
likeCount += 1;
}
},
error: function (xhr) {
var res = JSON.parse(xhr.responseText);
layer.msg(res.msg, {icon: 2});
}
});
});
$('#icon-share').on('click', function () {
});
});

View File

@ -69,7 +69,7 @@ layui.use(['jquery', 'form', 'slider', 'layer', 'helper'], function () {
initDanmu();
$('.icon-danmu-set').on('click', function () {
$('#icon-danmu-set').on('click', function () {
showMyDanmuSet();
});