mirror of
https://gitee.com/koogua/course-tencent-cloud.git
synced 2025-06-26 12:23:06 +08:00
完善点赞
This commit is contained in:
parent
50c5e403eb
commit
fe968a394a
@ -98,7 +98,7 @@ class SyncChapterCounterTask extends Task
|
||||
{
|
||||
$config = $this->getDI()->get('config');
|
||||
|
||||
return $config['recount_chapter'] ?? false;
|
||||
return $config->syncer->recount_chapter ?? false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ class SyncCommentCounterTask extends Task
|
||||
{
|
||||
$config = $this->getDI()->get('config');
|
||||
|
||||
return $config['recount_comment'] ?? false;
|
||||
return $config->syncer->recount_comment ?? false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ class SyncConsultCounterTask extends Task
|
||||
{
|
||||
$config = $this->getDI()->get('config');
|
||||
|
||||
return $config['recount_consult'] ?? false;
|
||||
return $config->syncer->recount_consult ?? false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ class SyncCourseCounterTask extends Task
|
||||
{
|
||||
$config = $this->getDI()->get('config');
|
||||
|
||||
return $config['recount_course'] ?? false;
|
||||
return $config->syncer->recount_course ?? false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ class SyncReviewCounterTask extends Task
|
||||
{
|
||||
$config = $this->getDI()->get('config');
|
||||
|
||||
return $config['recount_review'] ?? false;
|
||||
return $config->syncer->recount_review ?? false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -191,6 +191,18 @@ class CourseController extends Controller
|
||||
$this->view->setVar('options', $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/{id:[0-9]+}/rating", name="web.course.rating")
|
||||
*/
|
||||
public function ratingAction($id)
|
||||
{
|
||||
$service = new CourseInfoService();
|
||||
|
||||
$course = $service->handle($id);
|
||||
|
||||
$this->view->setVar('course', $course);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/{id:[0-9]+}/favorite", name="web.course.favorite")
|
||||
*/
|
||||
|
@ -39,7 +39,12 @@ class ReviewController extends Controller
|
||||
|
||||
$review = $service->handle($review->id);
|
||||
|
||||
return $this->jsonSuccess(['review' => $review]);
|
||||
$content = [
|
||||
'review' => $review,
|
||||
'msg' => '发布课程评价成功',
|
||||
];
|
||||
|
||||
return $this->jsonSuccess($content);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -51,7 +56,12 @@ class ReviewController extends Controller
|
||||
|
||||
$review = $service->handle($id);
|
||||
|
||||
return $this->jsonSuccess(['review' => $review]);
|
||||
$content = [
|
||||
'review' => $review,
|
||||
'msg' => '更新课程评价成功',
|
||||
];
|
||||
|
||||
return $this->jsonSuccess($content);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,6 +2,7 @@
|
||||
<div class="review-list">
|
||||
{% for item in pager.items %}
|
||||
{% set user_url = url({'for':'web.user.show','id':item.id}) %}
|
||||
{% set like_url = url({'for':'web.consult.like','id':item.id}) %}
|
||||
<div class="review-card clearfix">
|
||||
<div class="avatar">
|
||||
<a href="{{ user_url }}">
|
||||
@ -12,7 +13,11 @@
|
||||
<div class="title">{{ item.question }}</div>
|
||||
<div class="content">{{ item.answer }}</div>
|
||||
<div class="footer">
|
||||
<span>{{ date('Y-m-d H:i',item.create_time) }}</span>
|
||||
<span class="time">{{ date('Y-m-d H:i',item.create_time) }}</span>
|
||||
<span class="like">
|
||||
<i class="layui-icon layui-icon-praise like-icon" data-url="{{ like_url }}"></i>
|
||||
<em class="like-count">{{ item.like_count }}</em>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -10,6 +10,12 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% set rating_url = url({'for':'web.course.rating','id':course.id}) %}
|
||||
|
||||
<div class="sidebar-rating wrap">
|
||||
<a class="layui-btn layui-btn-fluid layui-bg-green rating-btn" href="javascript:" data-url="{{ rating_url }}">课程评价</a>
|
||||
</div>
|
||||
|
||||
{% if course.market_price == 0 %}
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">赞赏支持</div>
|
||||
|
47
app/Http/Web/Views/course/rating.volt
Normal file
47
app/Http/Web/Views/course/rating.volt
Normal file
@ -0,0 +1,47 @@
|
||||
{% extends 'templates/layer.volt' %}
|
||||
|
||||
{% block content %}
|
||||
<form class="layui-form rating-form" method="post" action="{{ url({'for':'web.review.create'}) }}">
|
||||
<div class="layui-form-item mb0">
|
||||
<label class="layui-form-label">内容实用</label>
|
||||
<div class="layui-input-block">
|
||||
<div id="rating1"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item mb0">
|
||||
<label class="layui-form-label">通俗易懂</label>
|
||||
<div class="layui-input-block">
|
||||
<div id="rating2"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">逻辑清晰</label>
|
||||
<div class="layui-input-block">
|
||||
<div id="rating3"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">评价内容</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="content" class="layui-textarea" placeholder="请描述你的学习经历,例如学习成果、课程内容、讲师风格、教学服务等。"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"></label>
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn" lay-submit="true" lay-filter="go">提交</button>
|
||||
<button type="button" class="layui-btn layui-btn-primary cancel-rating">取消</button>
|
||||
<input type="hidden" name="course_id" value="{{ course.id }}">
|
||||
<input type="hidden" name="rating1" value="5">
|
||||
<input type="hidden" name="rating2" value="5">
|
||||
<input type="hidden" name="rating3" value="5">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
{% block include_js %}
|
||||
|
||||
{{ js_include('web/js/course.rating.js') }}
|
||||
|
||||
{% endblock %}
|
@ -9,6 +9,7 @@
|
||||
<div class="review-list">
|
||||
{% for item in pager.items %}
|
||||
{% set user_url = url({'for':'web.user.show','id':item.id}) %}
|
||||
{% set like_url = url({'for':'web.review.like','id':item.id}) %}
|
||||
<div class="review-card clearfix">
|
||||
<div class="avatar">
|
||||
<img src="{{ item.user.avatar }}" alt="{{ item.user.name }}">
|
||||
@ -20,7 +21,11 @@
|
||||
</div>
|
||||
<div class="content">{{ item.content }}</div>
|
||||
<div class="footer">
|
||||
<span>{{ date('Y-m-d H:i',item.create_time) }}</span>
|
||||
<span class="time">{{ date('Y-m-d H:i',item.create_time) }}</span>
|
||||
<span class="like">
|
||||
<i class="layui-icon layui-icon-praise like-icon" title="点赞" data-url="{{ like_url }}"></i>
|
||||
<em class="like-count">{{ item.like_count }}</em>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -64,6 +64,20 @@ class CourseCounter extends Listener
|
||||
$this->syncCourseCounter($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 incrFavoriteCount(Event $event, $source, CourseModel $course)
|
||||
{
|
||||
$this->counter->hIncrBy($course->id, 'favorite_count');
|
||||
|
@ -42,6 +42,13 @@ class Comment extends Model
|
||||
*/
|
||||
public $user_id;
|
||||
|
||||
/**
|
||||
* 回复用户
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $to_user_id;
|
||||
|
||||
/**
|
||||
* 内容
|
||||
*
|
||||
|
@ -7,13 +7,6 @@ use Phalcon\Mvc\Model\Behavior\SoftDelete;
|
||||
class CourseRating extends Model
|
||||
{
|
||||
|
||||
/**
|
||||
* 主键编号
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* 课程编号
|
||||
*
|
||||
|
@ -125,11 +125,22 @@ class Review extends Model
|
||||
public function beforeCreate()
|
||||
{
|
||||
$this->create_time = time();
|
||||
|
||||
$this->rating = $this->getAvgRating();
|
||||
}
|
||||
|
||||
public function beforeUpdate()
|
||||
{
|
||||
$this->update_time = time();
|
||||
|
||||
$this->rating = $this->getAvgRating();
|
||||
}
|
||||
|
||||
protected function getAvgRating()
|
||||
{
|
||||
$sumRating = $this->rating1 + $this->rating2 + $this->rating3;
|
||||
|
||||
return round($sumRating / 3, 2);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,11 +5,10 @@ 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\Chapter as ChapterValidator;
|
||||
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
|
||||
use Phalcon\Di as Di;
|
||||
use Phalcon\Events\Manager as EventsManager;
|
||||
|
||||
class ChapterLike extends FrontendService
|
||||
@ -27,9 +26,9 @@ class ChapterLike extends FrontendService
|
||||
|
||||
$validator->checkChapterLikeLimit($user);
|
||||
|
||||
$chapterLikeRepo = new ChapterLikeRepo();
|
||||
$validator = new ChapterValidator();
|
||||
|
||||
$chapterLike = $chapterLikeRepo->findChapterLike($chapter->id, $user->id);
|
||||
$chapterLike = $validator->checkIfLiked($chapter->id, $user->id);
|
||||
|
||||
if (!$chapterLike) {
|
||||
|
||||
@ -83,7 +82,7 @@ class ChapterLike extends FrontendService
|
||||
*/
|
||||
protected function getPhEventsManager()
|
||||
{
|
||||
return Di::getDefault()->get('eventsManager');
|
||||
return $this->getDI()->get('eventsManager');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -42,10 +42,6 @@ class CommentCreate extends FrontendService
|
||||
$data['parent_id'] = $parent->id;
|
||||
}
|
||||
|
||||
if (isset($post['mentions'])) {
|
||||
$data['mentions'] = $validator->checkMentions($post['mentions']);
|
||||
}
|
||||
|
||||
$comment = new CommentModel();
|
||||
|
||||
$data['course_id'] = $course->id;
|
||||
@ -63,11 +59,6 @@ class CommentCreate extends FrontendService
|
||||
return $comment;
|
||||
}
|
||||
|
||||
protected function handleMentions($mentions)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected function incrChapterCommentCount(ChapterModel $chapter)
|
||||
{
|
||||
$this->eventsManager->fire('chapterCounter:incrCommentCount', $this, $chapter);
|
||||
|
@ -5,11 +5,10 @@ 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\Comment as CommentValidator;
|
||||
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
|
||||
use Phalcon\Di as Di;
|
||||
use Phalcon\Events\Manager as EventsManager;
|
||||
|
||||
class CommentLike extends FrontendService
|
||||
@ -27,9 +26,9 @@ class CommentLike extends FrontendService
|
||||
|
||||
$validator->checkCommentLikeLimit($user);
|
||||
|
||||
$commentLikeRepo = new CommentLikeRepo();
|
||||
$validator = new CommentValidator();
|
||||
|
||||
$commentLike = $commentLikeRepo->findCommentLike($comment->id, $user->id);
|
||||
$commentLike = $validator->checkIfLiked($comment->id, $user->id);
|
||||
|
||||
if (!$commentLike) {
|
||||
|
||||
@ -83,7 +82,7 @@ class CommentLike extends FrontendService
|
||||
*/
|
||||
protected function getPhEventsManager()
|
||||
{
|
||||
return Di::getDefault()->get('eventsManager');
|
||||
return $this->getDI()->get('eventsManager');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,11 +5,10 @@ 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\Consult as ConsultValidator;
|
||||
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
|
||||
use Phalcon\Di as Di;
|
||||
use Phalcon\Events\Manager as EventsManager;
|
||||
|
||||
class ConsultLike extends FrontendService
|
||||
@ -27,9 +26,9 @@ class ConsultLike extends FrontendService
|
||||
|
||||
$validator->checkConsultLikeLimit($user);
|
||||
|
||||
$consultLikeRepo = new ConsultLikeRepo();
|
||||
$validator = new ConsultValidator();
|
||||
|
||||
$consultLike = $consultLikeRepo->findConsultLike($consult->id, $user->id);
|
||||
$consultLike = $validator->checkIfLiked($consult->id, $user->id);
|
||||
|
||||
if (!$consultLike) {
|
||||
|
||||
@ -83,7 +82,7 @@ class ConsultLike extends FrontendService
|
||||
*/
|
||||
protected function getPhEventsManager()
|
||||
{
|
||||
return Di::getDefault()->get('eventsManager');
|
||||
return $this->getDI()->get('eventsManager');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ use App\Models\Review as ReviewModel;
|
||||
use App\Models\User as UserModel;
|
||||
use App\Services\Frontend\CourseTrait;
|
||||
use App\Services\Frontend\Service as FrontendService;
|
||||
use App\Validators\CourseUser as CourseUserValidator;
|
||||
use App\Validators\Review as ReviewValidator;
|
||||
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
|
||||
|
||||
@ -27,6 +28,11 @@ class ReviewCreate extends FrontendService
|
||||
|
||||
$validator->checkReviewLimit($user);
|
||||
|
||||
$validator = new CourseUserValidator();
|
||||
|
||||
$validator->checkCourseUser($course->id, $user->id);
|
||||
$validator->checkIfReviewed($course->id, $user->id);
|
||||
|
||||
$validator = new ReviewValidator();
|
||||
|
||||
$data = [];
|
||||
@ -35,10 +41,6 @@ class ReviewCreate extends FrontendService
|
||||
$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;
|
||||
|
||||
@ -53,11 +55,6 @@ 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);
|
||||
|
@ -5,11 +5,10 @@ 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\Review as ReviewValidator;
|
||||
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
|
||||
use Phalcon\Di as Di;
|
||||
use Phalcon\Events\Manager as EventsManager;
|
||||
|
||||
class ReviewLike extends FrontendService
|
||||
@ -27,9 +26,9 @@ class ReviewLike extends FrontendService
|
||||
|
||||
$validator->checkReviewLikeLimit($user);
|
||||
|
||||
$reviewLikeRepo = new ReviewLikeRepo();
|
||||
$validator = new ReviewValidator();
|
||||
|
||||
$reviewLike = $reviewLikeRepo->findReviewLike($review->id, $user->id);
|
||||
$reviewLike = $validator->checkIfLiked($review->id, $user->id);
|
||||
|
||||
if (!$reviewLike) {
|
||||
|
||||
@ -56,8 +55,6 @@ class ReviewLike extends FrontendService
|
||||
|
||||
$this->incrLikeCount($review);
|
||||
}
|
||||
|
||||
$reviewLike->update();
|
||||
}
|
||||
|
||||
$this->incrUserDailyReviewLikeCount($user);
|
||||
@ -85,7 +82,7 @@ class ReviewLike extends FrontendService
|
||||
*/
|
||||
protected function getPhEventsManager()
|
||||
{
|
||||
return Di::getDefault()->get('eventsManager');
|
||||
return $this->getDI()->get('eventsManager');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -178,11 +178,13 @@ class Chapter extends Validator
|
||||
{
|
||||
$repo = new ChapterLikeRepo();
|
||||
|
||||
$record = $repo->findChapterLike($chapterId, $userId);
|
||||
$chapterLike = $repo->findChapterLike($chapterId, $userId);
|
||||
|
||||
if ($record && time() - $record->create_time > 86400) {
|
||||
if ($chapterLike && time() - $chapterLike->create_time > 5 * 60) {
|
||||
throw new BadRequestException('chapter.has_liked');
|
||||
}
|
||||
|
||||
return $chapterLike;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -80,11 +80,13 @@ class Comment extends Validator
|
||||
{
|
||||
$repo = new CommentLikeRepo();
|
||||
|
||||
$record = $repo->findCommentLike($chapterId, $userId);
|
||||
$commentLike = $repo->findCommentLike($chapterId, $userId);
|
||||
|
||||
if ($record && time() - $record->create_time > 86400) {
|
||||
if ($commentLike && time() - $commentLike->create_time > 5 * 60) {
|
||||
throw new BadRequestException('comment.has_liked');
|
||||
}
|
||||
|
||||
return $commentLike;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -85,11 +85,13 @@ class Consult extends Validator
|
||||
{
|
||||
$repo = new ConsultLikeRepo();
|
||||
|
||||
$record = $repo->findConsultLike($chapterId, $userId);
|
||||
$consultLike = $repo->findConsultLike($chapterId, $userId);
|
||||
|
||||
if ($record && time() - $record->create_time > 86400) {
|
||||
if ($consultLike && time() - $consultLike->create_time > 5 * 60) {
|
||||
throw new BadRequestException('consult.has_liked');
|
||||
}
|
||||
|
||||
return $consultLike;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,6 +22,19 @@ class CourseUser extends Validator
|
||||
return $courseUser;
|
||||
}
|
||||
|
||||
public function checkCourseUser($courseId, $userId)
|
||||
{
|
||||
$repo = new CourseUserRepo();
|
||||
|
||||
$courseUser = $repo->findCourseUser($courseId, $userId);
|
||||
|
||||
if (!$courseUser) {
|
||||
throw new BadRequestException('course_user.not_found');
|
||||
}
|
||||
|
||||
return $courseUser;
|
||||
}
|
||||
|
||||
public function checkCourse($id)
|
||||
{
|
||||
$validator = new Course();
|
||||
@ -54,7 +67,18 @@ class CourseUser extends Validator
|
||||
$courseUser = $repo->findCourseStudent($courseId, $userId);
|
||||
|
||||
if ($courseUser) {
|
||||
throw new BadRequestException('course_user.has_joined_course');
|
||||
throw new BadRequestException('course_user.has_joined');
|
||||
}
|
||||
}
|
||||
|
||||
public function checkIfReviewed($courseId, $userId)
|
||||
{
|
||||
$repo = new CourseUserRepo();
|
||||
|
||||
$courseUser = $repo->findCourseUser($courseId, $userId);
|
||||
|
||||
if ($courseUser && $courseUser->reviewed) {
|
||||
throw new BadRequestException('course_user.has_reviewed');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ class Review extends Validator
|
||||
|
||||
$length = kg_strlen($value);
|
||||
|
||||
if ($length < 5) {
|
||||
if ($length < 10) {
|
||||
throw new BadRequestException('review.content_too_short');
|
||||
}
|
||||
|
||||
@ -65,26 +65,17 @@ class Review extends Validator
|
||||
return $status;
|
||||
}
|
||||
|
||||
public function checkIfReviewed($courseId, $userId)
|
||||
{
|
||||
$reviewRepo = new ReviewRepo();
|
||||
|
||||
$review = $reviewRepo->findReview($courseId, $userId);
|
||||
|
||||
if ($review) {
|
||||
throw new BadRequestException('review.has_reviewed');
|
||||
}
|
||||
}
|
||||
|
||||
public function checkIfLiked($chapterId, $userId)
|
||||
public function checkIfLiked($reviewId, $userId)
|
||||
{
|
||||
$repo = new ReviewLikeRepo();
|
||||
|
||||
$record = $repo->findReviewLike($chapterId, $userId);
|
||||
$reviewLike = $repo->findReviewLike($reviewId, $userId);
|
||||
|
||||
if ($record && time() - $record->create_time > 86400) {
|
||||
if ($reviewLike && time() - $reviewLike->create_time > 5 * 60) {
|
||||
throw new BadRequestException('review.has_liked');
|
||||
}
|
||||
|
||||
return $reviewLike;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -132,4 +132,13 @@ $config['websocket']['url'] = 'ws://127.0.0.1:8282';
|
||||
*/
|
||||
$config['websocket']['register_address'] = '127.0.0.1:1238';
|
||||
|
||||
/**
|
||||
* 同步器设置
|
||||
*/
|
||||
$config['syncer']['recount_course'] = false;
|
||||
$config['syncer']['recount_chapter'] = false;
|
||||
$config['syncer']['recount_consult'] = false;
|
||||
$config['syncer']['recount_review'] = false;
|
||||
$config['syncer']['recount_comment'] = false;
|
||||
|
||||
return $config;
|
||||
|
@ -136,10 +136,11 @@ $error['package.invalid_publish_status'] = '无效的发布状态';
|
||||
/**
|
||||
* 课程成员
|
||||
*/
|
||||
$error['course_user.not_found'] = '课程学员不存在';
|
||||
$error['course_user.apply_not_allowed'] = '当前不允许申请课程';
|
||||
$error['course_user.has_joined_course'] = '已经加入当前课程';
|
||||
$error['course_user.not_found'] = '课程学员关系不存在';
|
||||
$error['course_user.invalid_expiry_time'] = '无效的过期时间';
|
||||
$error['course_user.review_not_allowed'] = '当前不允许评价课程';
|
||||
$error['course_user.has_joined'] = '已经加入过该课程';
|
||||
$error['course_user.has_reviewed'] = '已经评价过该课程';
|
||||
|
||||
/**
|
||||
* 章节相关
|
||||
@ -189,7 +190,7 @@ $error['chapter_read.content_too_long'] = '文章内容太长(多于65535个
|
||||
$error['review.not_found'] = '评价不存在';
|
||||
$error['review.invalid_rating'] = '无效的评分(范围:1-5)';
|
||||
$error['review.invalid_publish_status'] = '无效的发布状态';
|
||||
$error['review.content_too_short'] = '评价内容太短(少于5个字符)';
|
||||
$error['review.content_too_short'] = '评价内容太短(少于10个字符)';
|
||||
$error['review.content_too_long'] = '评价内容太长(多于255个字符)';
|
||||
$error['review.has_liked'] = '你已经点过赞啦';
|
||||
|
||||
|
@ -8,6 +8,10 @@
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
.layer {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.clearfix {
|
||||
zoom: 1
|
||||
}
|
||||
@ -28,6 +32,14 @@
|
||||
float: right;
|
||||
}
|
||||
|
||||
.mb0 {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.padding20 {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
@ -44,6 +56,11 @@
|
||||
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.layer-wrap {
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.pager {
|
||||
text-align: center;
|
||||
}
|
||||
@ -617,7 +634,6 @@
|
||||
.review-card .info {
|
||||
float: left;
|
||||
width: 650px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.review-card .rating {
|
||||
@ -637,21 +653,39 @@
|
||||
}
|
||||
|
||||
.review-card .user {
|
||||
margin-bottom: 10px;
|
||||
margin-bottom: 15px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.review-card .content {
|
||||
margin-bottom: 10px;
|
||||
color: #666;
|
||||
margin-bottom: 15px;
|
||||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.review-card .footer {
|
||||
line-height: 1.2em;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.review-card .footer span {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.review-card .like-icon {
|
||||
margin-right: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.like .active, .like .like-icon:hover {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.review-card .like-count {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.sidebar-order .order {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
@ -781,6 +815,10 @@
|
||||
color: gray;
|
||||
}
|
||||
|
||||
.rating-form .layui-rate {
|
||||
padding-top: 6px;
|
||||
}
|
||||
|
||||
.read-info {
|
||||
min-height: 428px;
|
||||
margin-bottom: 0;
|
||||
|
31
public/static/web/js/course.rating.js
Normal file
31
public/static/web/js/course.rating.js
Normal file
@ -0,0 +1,31 @@
|
||||
layui.use(['jquery', 'rate'], function () {
|
||||
|
||||
var $ = layui.jquery;
|
||||
var rate = layui.rate;
|
||||
|
||||
$('.cancel-rating').on('click', function () {
|
||||
parent.layer.closeAll();
|
||||
});
|
||||
|
||||
rate.render({
|
||||
elem: '#rating1',
|
||||
choose: function (value) {
|
||||
$('input[name=rating1]').val(value);
|
||||
}
|
||||
});
|
||||
|
||||
rate.render({
|
||||
elem: '#rating2',
|
||||
choose: function (value) {
|
||||
$('input[name=rating2]').val(value);
|
||||
}
|
||||
});
|
||||
|
||||
rate.render({
|
||||
elem: '#rating3',
|
||||
choose: function (value) {
|
||||
$('input[name=rating3]').val(value);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
@ -1,8 +1,44 @@
|
||||
layui.use(['jquery', 'helper'], function () {
|
||||
layui.use(['jquery', 'layer', 'helper'], function () {
|
||||
|
||||
var $ = layui.jquery;
|
||||
var layer = layui.layer;
|
||||
var helper = layui.helper;
|
||||
|
||||
$('.rating-btn').on('click', function () {
|
||||
var url = $(this).data('url');
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '课程评分',
|
||||
content: [url, 'no'],
|
||||
area: ['640px', '400px']
|
||||
});
|
||||
});
|
||||
|
||||
$('body').on('click', '.like-icon', function () {
|
||||
var $this = $(this);
|
||||
var $likeCount = $this.next();
|
||||
var likeCount = parseInt($likeCount.text());
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: $this.data('url'),
|
||||
success: function (res) {
|
||||
if ($this.hasClass('active')) {
|
||||
$this.removeClass('active');
|
||||
$likeCount.text(likeCount - 1);
|
||||
likeCount -= 1;
|
||||
} else {
|
||||
$this.addClass('active');
|
||||
$likeCount.text(likeCount + 1);
|
||||
likeCount += 1;
|
||||
}
|
||||
},
|
||||
error: function (xhr) {
|
||||
var res = JSON.parse(xhr.responseText);
|
||||
layer.msg(res.msg, {icon: 2});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if ($('#tab-packages').length > 0) {
|
||||
var $tabPackages = $('#tab-packages');
|
||||
helper.ajaxLoadHtml($tabPackages.data('url'), $tabPackages.attr('id'));
|
||||
|
Loading…
x
Reference in New Issue
Block a user