mirror of
https://gitee.com/koogua/course-tencent-cloud.git
synced 2025-06-30 22:24:55 +08:00
去除评论,去除异步更新
This commit is contained in:
parent
ac51d23934
commit
7f16e9710c
@ -1,37 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Caches;
|
||||
|
||||
use App\Repos\Chapter as ChapterRepo;
|
||||
|
||||
class ChapterCounter extends Counter
|
||||
{
|
||||
|
||||
protected $lifetime = 1 * 86400;
|
||||
|
||||
public function getLifetime()
|
||||
{
|
||||
return $this->lifetime;
|
||||
}
|
||||
|
||||
public function getKey($id = null)
|
||||
{
|
||||
return "chapter_counter:{$id}";
|
||||
}
|
||||
|
||||
public function getContent($id = null)
|
||||
{
|
||||
$chapterRepo = new ChapterRepo();
|
||||
|
||||
$chapter = $chapterRepo->findById($id);
|
||||
|
||||
if (!$chapter) return null;
|
||||
|
||||
return [
|
||||
'user_count' => $chapter->user_count,
|
||||
'consult_count' => $chapter->consult_count,
|
||||
'like_count' => $chapter->like_count,
|
||||
];
|
||||
}
|
||||
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Caches;
|
||||
|
||||
use App\Repos\Consult as ConsultRepo;
|
||||
|
||||
class ConsultCounter extends Counter
|
||||
{
|
||||
|
||||
protected $lifetime = 1 * 86400;
|
||||
|
||||
public function getLifetime()
|
||||
{
|
||||
return $this->lifetime;
|
||||
}
|
||||
|
||||
public function getKey($id = null)
|
||||
{
|
||||
return "consult_counter:{$id}";
|
||||
}
|
||||
|
||||
public function getContent($id = null)
|
||||
{
|
||||
$consultRepo = new ConsultRepo();
|
||||
|
||||
$consult = $consultRepo->findById($id);
|
||||
|
||||
if (!$consult) return null;
|
||||
|
||||
return [
|
||||
'like_count' => $consult->like_count,
|
||||
];
|
||||
}
|
||||
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Caches;
|
||||
|
||||
use App\Repos\Course as CourseRepo;
|
||||
|
||||
class CourseCounter extends Counter
|
||||
{
|
||||
|
||||
protected $lifetime = 1 * 86400;
|
||||
|
||||
public function getLifetime()
|
||||
{
|
||||
return $this->lifetime;
|
||||
}
|
||||
|
||||
public function getKey($id = null)
|
||||
{
|
||||
return "course_counter:{$id}";
|
||||
}
|
||||
|
||||
public function getContent($id = null)
|
||||
{
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
$course = $courseRepo->findById($id);
|
||||
|
||||
if (!$course) return null;
|
||||
|
||||
return [
|
||||
'user_count' => $course->user_count,
|
||||
'lesson_count' => $course->lesson_count,
|
||||
'comment_count' => $course->comment_count,
|
||||
'consult_count' => $course->consult_count,
|
||||
'review_count' => $course->review_count,
|
||||
'favorite_count' => $course->favorite_count,
|
||||
];
|
||||
}
|
||||
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Caches;
|
||||
|
||||
use App\Repos\Review as ReviewRepo;
|
||||
|
||||
class ReviewCounter extends Counter
|
||||
{
|
||||
|
||||
protected $lifetime = 1 * 86400;
|
||||
|
||||
public function getLifetime()
|
||||
{
|
||||
return $this->lifetime;
|
||||
}
|
||||
|
||||
public function getKey($id = null)
|
||||
{
|
||||
return "review_counter:{$id}";
|
||||
}
|
||||
|
||||
public function getContent($id = null)
|
||||
{
|
||||
$reviewRepo = new ReviewRepo();
|
||||
|
||||
$review = $reviewRepo->findById($id);
|
||||
|
||||
if (!$review) return null;
|
||||
|
||||
return [
|
||||
'like_count' => $review->like_count,
|
||||
];
|
||||
}
|
||||
|
||||
}
|
@ -1,98 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Tasks;
|
||||
|
||||
use App\Caches\Chapter as ChapterCache;
|
||||
use App\Caches\ChapterCounter as ChapterCounterCache;
|
||||
use App\Library\Cache\Backend\Redis as RedisCache;
|
||||
use App\Repos\Chapter as ChapterRepo;
|
||||
use App\Services\Syncer\ChapterCounter as ChapterCounterSyncer;
|
||||
|
||||
class SyncChapterCounterTask extends Task
|
||||
{
|
||||
|
||||
/**
|
||||
* @var RedisCache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* @var \Redis
|
||||
*/
|
||||
protected $redis;
|
||||
|
||||
public function mainAction()
|
||||
{
|
||||
$this->cache = $this->getDI()->get('cache');
|
||||
|
||||
$this->redis = $this->cache->getRedis();
|
||||
|
||||
$this->rebuild();
|
||||
}
|
||||
|
||||
protected function rebuild()
|
||||
{
|
||||
$key = $this->getCacheKey();
|
||||
|
||||
$chapterIds = $this->redis->sRandMember($key, 500);
|
||||
|
||||
if (!$chapterIds) return;
|
||||
|
||||
$chapterRepo = new ChapterRepo();
|
||||
|
||||
$chapters = $chapterRepo->findByIds($chapterIds);
|
||||
|
||||
if ($chapters->count() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$counterCache = new ChapterCounterCache();
|
||||
|
||||
$chapterCache = new ChapterCache();
|
||||
|
||||
$allowRecount = $this->allowRecount();
|
||||
|
||||
foreach ($chapters as $chapter) {
|
||||
|
||||
if ($allowRecount) {
|
||||
|
||||
$chapter->user_count = $chapterRepo->countUsers($chapter->id);
|
||||
$chapter->comment_count = $chapterRepo->countComments($chapter->id);
|
||||
$chapter->like_count = $chapterRepo->countLikes($chapter->id);
|
||||
$chapter->update();
|
||||
|
||||
$counterCache->rebuild($chapter->id);
|
||||
$chapterCache->rebuild($chapter->id);
|
||||
|
||||
} else {
|
||||
|
||||
$counter = $counterCache->get($chapter->id);
|
||||
|
||||
if ($counter) {
|
||||
|
||||
$chapter->user_count = $counter['user_count'];
|
||||
$chapter->comment_count = $counter['comment_count'];
|
||||
$chapter->like_count = $counter['like_count'];
|
||||
$chapter->update();
|
||||
|
||||
$chapterCache->rebuild($chapter->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->redis->sRem($key, ...$chapterIds);
|
||||
}
|
||||
|
||||
protected function getCacheKey()
|
||||
{
|
||||
$syncer = new ChapterCounterSyncer();
|
||||
|
||||
return $syncer->getSyncKey();
|
||||
}
|
||||
|
||||
protected function allowRecount()
|
||||
{
|
||||
return date('H') % 3 == 0;
|
||||
}
|
||||
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Tasks;
|
||||
|
||||
use App\Caches\ConsultCounter as ConsultCounterCache;
|
||||
use App\Library\Cache\Backend\Redis as RedisCache;
|
||||
use App\Repos\Consult as ConsultRepo;
|
||||
use App\Services\Syncer\ConsultCounter as ConsultCounterSyncer;
|
||||
|
||||
class SyncConsultCounterTask extends Task
|
||||
{
|
||||
|
||||
/**
|
||||
* @var RedisCache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* @var \Redis
|
||||
*/
|
||||
protected $redis;
|
||||
|
||||
public function mainAction()
|
||||
{
|
||||
$this->cache = $this->getDI()->get('cache');
|
||||
|
||||
$this->redis = $this->cache->getRedis();
|
||||
|
||||
$this->rebuild();
|
||||
}
|
||||
|
||||
protected function rebuild()
|
||||
{
|
||||
$key = $this->getCacheKey();
|
||||
|
||||
$consultIds = $this->redis->sRandMember($key, 500);
|
||||
|
||||
if (!$consultIds) return;
|
||||
|
||||
$consultRepo = new ConsultRepo();
|
||||
|
||||
$consults = $consultRepo->findByIds($consultIds);
|
||||
|
||||
if ($consults->count() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$counterCache = new ConsultCounterCache();
|
||||
|
||||
$allowRecount = $this->allowRecount();
|
||||
|
||||
foreach ($consults as $consult) {
|
||||
|
||||
if ($allowRecount) {
|
||||
|
||||
$consult->like_count = $consultRepo->countLikes($consult->id);
|
||||
$consult->update();
|
||||
|
||||
$counterCache->rebuild($consult->id);
|
||||
|
||||
} else {
|
||||
|
||||
$counter = $counterCache->get($consult->id);
|
||||
|
||||
if ($counter) {
|
||||
$consult->like_count = $counter['like_count'];
|
||||
$consult->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->redis->sRem($key, ...$consultIds);
|
||||
}
|
||||
|
||||
protected function getCacheKey()
|
||||
{
|
||||
$syncer = new ConsultCounterSyncer();
|
||||
|
||||
return $syncer->getSyncKey();
|
||||
}
|
||||
|
||||
protected function allowRecount()
|
||||
{
|
||||
return date('H') % 4 == 0;
|
||||
}
|
||||
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Tasks;
|
||||
|
||||
use App\Caches\Course as CourseCache;
|
||||
use App\Caches\CourseCounter as CourseCounterCache;
|
||||
use App\Library\Cache\Backend\Redis as RedisCache;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use App\Services\Syncer\CourseCounter as CourseCounterSyncer;
|
||||
|
||||
class SyncCourseCounterTask extends Task
|
||||
{
|
||||
|
||||
/**
|
||||
* @var RedisCache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* @var \Redis
|
||||
*/
|
||||
protected $redis;
|
||||
|
||||
public function mainAction()
|
||||
{
|
||||
$this->cache = $this->getDI()->get('cache');
|
||||
|
||||
$this->redis = $this->cache->getRedis();
|
||||
|
||||
$this->rebuild();
|
||||
}
|
||||
|
||||
protected function rebuild()
|
||||
{
|
||||
$key = $this->getCacheKey();
|
||||
|
||||
$courseIds = $this->redis->sRandMember($key, 100);
|
||||
|
||||
if (!$courseIds) return;
|
||||
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
$courses = $courseRepo->findByIds($courseIds);
|
||||
|
||||
if ($courses->count() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$counterCache = new CourseCounterCache();
|
||||
|
||||
$courseCache = new CourseCache();
|
||||
|
||||
$allowRecount = $this->allowRecount();
|
||||
|
||||
foreach ($courses as $course) {
|
||||
|
||||
if ($allowRecount) {
|
||||
|
||||
$course->user_count = $courseRepo->countUsers($course->id);
|
||||
$course->comment_count = $courseRepo->countComments($course->id);
|
||||
$course->consult_count = $courseRepo->countConsults($course->id);
|
||||
$course->review_count = $courseRepo->countReviews($course->id);
|
||||
$course->favorite_count = $courseRepo->countFavorites($course->id);
|
||||
$course->update();
|
||||
|
||||
$counterCache->rebuild($course->id);
|
||||
$courseCache->rebuild($course->id);
|
||||
|
||||
} else {
|
||||
|
||||
$counter = $counterCache->get($course->id);
|
||||
|
||||
if ($counter) {
|
||||
|
||||
$course->user_count = $counter['user_count'];
|
||||
$course->comment_count = $counter['comment_count'];
|
||||
$course->consult_count = $counter['consult_count'];
|
||||
$course->review_count = $counter['review_count'];
|
||||
$course->favorite_count = $counter['favorite_count'];
|
||||
$course->update();
|
||||
|
||||
$courseCache->rebuild($course->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->redis->sRem($key, ...$courseIds);
|
||||
}
|
||||
|
||||
protected function getCacheKey()
|
||||
{
|
||||
$syncer = new CourseCounterSyncer();
|
||||
|
||||
return $syncer->getSyncKey();
|
||||
}
|
||||
|
||||
protected function allowRecount()
|
||||
{
|
||||
return date('H') % 3 == 0;
|
||||
}
|
||||
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Tasks;
|
||||
|
||||
use App\Caches\ReviewCounter as ReviewCounterCache;
|
||||
use App\Library\Cache\Backend\Redis as RedisCache;
|
||||
use App\Repos\Review as ReviewRepo;
|
||||
use App\Services\Syncer\ReviewCounter as ReviewCounterSyncer;
|
||||
|
||||
class SyncReviewCounterTask extends Task
|
||||
{
|
||||
|
||||
/**
|
||||
* @var RedisCache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* @var \Redis
|
||||
*/
|
||||
protected $redis;
|
||||
|
||||
public function mainAction()
|
||||
{
|
||||
$this->cache = $this->getDI()->get('cache');
|
||||
|
||||
$this->redis = $this->cache->getRedis();
|
||||
|
||||
$this->rebuild();
|
||||
}
|
||||
|
||||
protected function rebuild()
|
||||
{
|
||||
$key = $this->getCacheKey();
|
||||
|
||||
$reviewIds = $this->redis->sRandMember($key, 500);
|
||||
|
||||
if (!$reviewIds) return;
|
||||
|
||||
$reviewRepo = new ReviewRepo();
|
||||
|
||||
$reviews = $reviewRepo->findByIds($reviewIds);
|
||||
|
||||
if ($reviews->count() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$counterCache = new ReviewCounterCache();
|
||||
|
||||
$allowRecount = $this->allowRecount();
|
||||
|
||||
foreach ($reviews as $review) {
|
||||
|
||||
if ($allowRecount) {
|
||||
|
||||
$review->like_count = $reviewRepo->countLikes($review->id);
|
||||
$review->update();
|
||||
|
||||
$counterCache->rebuild($review->id);
|
||||
|
||||
} else {
|
||||
|
||||
$counter = $counterCache->get($review->id);
|
||||
|
||||
if ($counter) {
|
||||
$review->like_count = $counter['like_count'];
|
||||
$review->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->redis->sRem($key, ...$reviewIds);
|
||||
}
|
||||
|
||||
protected function getCacheKey()
|
||||
{
|
||||
$syncer = new ReviewCounterSyncer();
|
||||
|
||||
return $syncer->getSyncKey();
|
||||
}
|
||||
|
||||
protected function allowRecount()
|
||||
{
|
||||
return date('H') % 4 == 0;
|
||||
}
|
||||
|
||||
}
|
@ -25,7 +25,7 @@
|
||||
<p>类型:{{ item.client_type }}</p>
|
||||
<p>地址:<a href="javascript:" class="kg-ip2region" title="查看位置" data-ip="{{ item.client_ip }}">{{ item.client_ip }}</a></p>
|
||||
</td>
|
||||
<td>{{ item.duration|total_duration }}</td>
|
||||
<td>{{ item.duration|duration }}</td>
|
||||
<td>{{ date('Y-m-d H:i:s',item.active_time) }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
@ -61,7 +61,7 @@
|
||||
</td>
|
||||
<td>
|
||||
<p>进度:{{ item.progress }}%</p>
|
||||
<p>时长:{{ item.duration|total_duration }}</p>
|
||||
<p>时长:{{ item.duration|duration }}</p>
|
||||
</td>
|
||||
<td>{{ source_type_info(item.source_type) }}</td>
|
||||
<td>
|
||||
|
@ -71,10 +71,6 @@ class CourseController extends Controller
|
||||
|
||||
$course = $service->handle($id);
|
||||
|
||||
$service = new CourseQueryService();
|
||||
|
||||
$course['category_paths'] = $service->handleCategoryPaths($course['category_id']);
|
||||
|
||||
$service = new RewardOptionList();
|
||||
|
||||
$rewards = $service->handle();
|
||||
|
@ -51,6 +51,30 @@ class MyController extends Controller
|
||||
$this->view->setVar('account', $account);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/courses", name="web.my.courses")
|
||||
*/
|
||||
public function coursesAction()
|
||||
{
|
||||
$service = new MyConsultListService();
|
||||
|
||||
$pager = $service->handle();
|
||||
|
||||
$this->view->setVar('pager', $pager);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/favorites", name="web.my.favorites")
|
||||
*/
|
||||
public function favoritesAction()
|
||||
{
|
||||
$service = new MyConsultListService();
|
||||
|
||||
$pager = $service->handle();
|
||||
|
||||
$this->view->setVar('pager', $pager);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/consults", name="web.my.consults")
|
||||
*/
|
||||
|
@ -74,7 +74,7 @@
|
||||
|
||||
{{ js_include('web/js/chapter.live.player.js') }}
|
||||
{{ js_include('web/js/chapter.live.im.js') }}
|
||||
{{ js_include('web/js/chapter.like.js') }}
|
||||
{{ js_include('web/js/chapter.action.js') }}
|
||||
{{ js_include('web/js/course.share.js') }}
|
||||
|
||||
{% endblock %}
|
@ -6,6 +6,7 @@
|
||||
{% set course_url = url({'for':'web.course.show','id':chapter.course.id}) %}
|
||||
{% set learning_url = url({'for':'web.chapter.learning','id':chapter.id}) %}
|
||||
{% set like_url = url({'for':'web.chapter.like','id':chapter.id}) %}
|
||||
{% set consult_url = url({'for':'web.consult.add'},{'chapter_id':chapter.id}) %}
|
||||
{% set qrcode_url = url({'for':'web.qrcode_img'},{'text':chapter_full_url}) %}
|
||||
|
||||
<div class="breadcrumb">
|
||||
@ -17,6 +18,7 @@
|
||||
<span class="share">
|
||||
<a href="javascript:" title="点赞" data-url="{{ like_url }}"><i class="layui-icon layui-icon-praise icon-praise"></i><em class="like-count">{{ chapter.like_count }}</em></a>
|
||||
<a href="javascript:" title="学习人次"><i class="layui-icon layui-icon-user"></i><em>{{ chapter.user_count }}</em></a>
|
||||
<a href="javascript:" title="我要提问" data-url="{{ consult_url }}"><i class="layui-icon layui-icon-help icon-help"></i></a>
|
||||
<a href="javascript:" title="分享到微信" data-url=""><i class="layui-icon layui-icon-login-wechat icon-wechat"></i></a>
|
||||
<a href="javascript:" title="分享到QQ空间"><i class="layui-icon layui-icon-login-qq icon-qq"></i></a>
|
||||
<a href="javascript:" title="分享到微博"><i class="layui-icon layui-icon-login-weibo icon-weibo"></i></a>
|
||||
@ -49,8 +51,8 @@
|
||||
|
||||
{% block include_js %}
|
||||
|
||||
{{ js_include('web/js/chapter.read.js') }}
|
||||
{{ js_include('web/js/chapter.like.js') }}
|
||||
{{ js_include('web/js/course.share.js') }}
|
||||
{{ js_include('web/js/chapter.read.js') }}
|
||||
{{ js_include('web/js/chapter.action.js') }}
|
||||
|
||||
{% endblock %}
|
@ -20,7 +20,7 @@
|
||||
<span class="share">
|
||||
<a href="javascript:" title="学习人次"><i class="layui-icon layui-icon-user"></i><em>{{ chapter.user_count }}</em></a>
|
||||
<a href="javascript:" title="我要点赞" data-url="{{ like_url }}"><i class="layui-icon layui-icon-praise icon-praise {{ liked_class }}"></i><em class="like-count">{{ chapter.like_count }}</em></a>
|
||||
<a href="javascript:" title="我要提问" data-url="{{ consult_url }}"><i class="layui-icon layui-icon-help icon-help"></i><em>{{ chapter.consult_count }}</em></a>
|
||||
<a href="javascript:" title="我要提问" data-url="{{ consult_url }}"><i class="layui-icon layui-icon-help icon-help"></i></a>
|
||||
<a href="javascript:" title="分享到微信"><i class="layui-icon layui-icon-login-wechat icon-wechat"></i></a>
|
||||
<a href="javascript:" title="分享到QQ空间"><i class="layui-icon layui-icon-login-qq icon-qq"></i></a>
|
||||
<a href="javascript:" title="分享到微博"><i class="layui-icon layui-icon-login-weibo icon-weibo"></i></a>
|
||||
@ -119,8 +119,7 @@
|
||||
{{ js_include('lib/jquery.min.js') }}
|
||||
{{ js_include('lib/jquery.danmu.min.js') }}
|
||||
{{ js_include('web/js/course.share.js') }}
|
||||
{{ js_include('web/js/chapter.like.js') }}
|
||||
{{ js_include('web/js/chapter.vod.js') }}
|
||||
{{ js_include('web/js/chapter.action.js') }}
|
||||
{{ js_include('web/js/chapter.vod.player.js') }}
|
||||
|
||||
{% endblock %}
|
@ -8,9 +8,9 @@
|
||||
<span class="layui-badge free-badge">免费</span>
|
||||
{% endif %}
|
||||
{% if lesson.me.duration > 0 %}
|
||||
<span class="study-time" title="学习时长:{{ lesson.me.duration|total_duration }}"><i class="layui-icon layui-icon-time"></i></span>
|
||||
<span class="study-time" title="学习时长:{{ lesson.me.duration|duration }}"><i class="layui-icon layui-icon-time"></i></span>
|
||||
{% endif %}
|
||||
<span class="duration">{{ lesson.attrs.duration|total_duration }}</span>
|
||||
<span class="duration">{{ lesson.attrs.duration|duration }}</span>
|
||||
</a>
|
||||
{%- endmacro %}
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
<span class="layui-badge free-badge">免费</span>
|
||||
{% endif %}
|
||||
{% if lesson.me.duration > 0 %}
|
||||
<span class="study-time" title="学习时长:{{ lesson.me.duration|total_duration }}"><i class="layui-icon layui-icon-time"></i></span>
|
||||
<span class="study-time" title="学习时长:{{ lesson.me.duration|duration }}"><i class="layui-icon layui-icon-time"></i></span>
|
||||
{% endif %}
|
||||
<span class="live">{{ date('m月d日',lesson.attrs.start_time) }} {{ date('H:i',lesson.attrs.start_time) }}~{{ date('H:i',lesson.attrs.end_time) }} {{ over_flag }}</span>
|
||||
</a>
|
||||
@ -41,7 +41,7 @@
|
||||
<span class="layui-badge free-badge">免费</span>
|
||||
{% endif %}
|
||||
{% if lesson.me.duration > 0 %}
|
||||
<span class="study-time" title="学习时长:{{ lesson.me.duration|total_duration }}"><i class="layui-icon layui-icon-time"></i></span>
|
||||
<span class="study-time" title="学习时长:{{ lesson.me.duration|duration }}"><i class="layui-icon layui-icon-time"></i></span>
|
||||
{% endif %}
|
||||
</a>
|
||||
{%- endmacro %}
|
||||
|
@ -85,10 +85,7 @@
|
||||
|
||||
<div class="layout-sidebar">
|
||||
{{ partial('course/show_order') }}
|
||||
{% if show_sidebar_teachers %}
|
||||
{% set teachers_url = url({'for':'web.course.teachers','id':course.id}) %}
|
||||
<div class="sidebar" id="sidebar-teachers" data-url="{{ teachers_url }}"></div>
|
||||
{% endif %}
|
||||
{{ partial('course/show_teacher') }}
|
||||
{% if show_sidebar_topics %}
|
||||
{% set topics_url = url({'for':'web.course.topics','id':course.id}) %}
|
||||
<div class="sidebar" id="sidebar-topics" data-url="{{ topics_url }}"></div>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<div class="info">
|
||||
{% if course.model == 'vod' %}
|
||||
<p class="item">
|
||||
<span class="key">课程时长</span><span class="value">{{ course.attrs.duration|total_duration }}</span>
|
||||
<span class="key">课程时长</span><span class="value">{{ course.attrs.duration|duration }}</span>
|
||||
</p>
|
||||
{% elseif course.model == 'live' %}
|
||||
<p class="item">
|
||||
|
@ -1,8 +1,8 @@
|
||||
{% if teachers %}
|
||||
{% if course.teachers %}
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">授课教师</div>
|
||||
<div class="layui-card-body">
|
||||
{% for teacher in teachers %}
|
||||
{% for teacher in course.teachers %}
|
||||
{% set teacher_url = url({'for':'web.user.show','id':teacher.id}) %}
|
||||
<div class="sidebar-teacher-card clearfix" title="{{ teacher.about|e }}">
|
||||
<div class="avatar">
|
@ -14,6 +14,38 @@
|
||||
<div class="name">{{ auth_user.name }} {{ vip_info(auth_user) }}</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">课程中心</div>
|
||||
<div class="layui-card-body">
|
||||
<ul class="my-menu">
|
||||
<li><a href="{{ url({'for':'web.my.courses'}) }}">我的课程</a></li>
|
||||
<li><a href="{{ url({'for':'web.my.consults'}) }}">我的咨询</a></li>
|
||||
<li><a href="{{ url({'for':'web.my.favorites'}) }}">我的收藏</a></li>
|
||||
<li><a href="{{ url({'for':'web.my.reviews'}) }}">我的评价</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">订单中心</div>
|
||||
<div class="layui-card-body">
|
||||
<ul class="my-menu">
|
||||
<li><a href="{{ url({'for':'web.my.orders'}) }}">我的订单</a></li>
|
||||
<li><a href="{{ url({'for':'web.my.refunds'}) }}">我的退款</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">聊天设置</div>
|
||||
<div class="layui-card-body">
|
||||
<ul class="my-menu">
|
||||
<li><a href="{{ url({'for':'web.my.profile'}) }}">我的好友</a></li>
|
||||
<li><a href="{{ url({'for':'web.my.account'}) }}">我的群组</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">个人设置</div>
|
||||
<div class="layui-card-body">
|
||||
|
@ -6,59 +6,39 @@
|
||||
|
||||
{% set status_types = {'all':'全部','pending':'待支付','finished':'已完成','closed':'已关闭','refunded':'已退款'} %}
|
||||
|
||||
<div class="layui-breadcrumb breadcrumb">
|
||||
<a href="/">首页</a>
|
||||
<a><cite>我的订单</cite></a>
|
||||
</div>
|
||||
|
||||
<div class="wrap">
|
||||
<div class="order-filter">
|
||||
{% set status = request.get('status','trim','all') %}
|
||||
{% for key,value in status_types %}
|
||||
{% set class = (status == key) ? 'layui-btn layui-btn-sm' : 'none' %}
|
||||
{% set url = (key == 'all') ? url({'for':'web.my.orders'}) : url({'for':'web.my.orders'},{'status':key}) %}
|
||||
<a class="{{ class }}" href="{{ url }}">{{ value }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% if pager.total_pages > 0 %}
|
||||
<table class="layui-table order-table kg-table" lay-size="lg" lay-skin="nob">
|
||||
<colgroup>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>基本信息</th>
|
||||
<th>订单金额</th>
|
||||
<th>创建时间</th>
|
||||
<th>订单状态</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in pager.items %}
|
||||
{% set info_url = url({'for':'web.order.info'},{'sn':item.sn}) %}
|
||||
<tr>
|
||||
<td>
|
||||
<p>名称:{{ item.subject }}</p>
|
||||
<p>单号:{{ item.sn }}</p>
|
||||
</td>
|
||||
<td><span class="price">{{ '¥%0.2f'|format(item.amount) }}</span></td>
|
||||
<td>{{ date('Y-m-d H:i:s',item.create_time) }}</td>
|
||||
<td>{{ order_status(item.status) }}</td>
|
||||
<td align="center">
|
||||
<a class="layui-btn layui-btn-sm" href="{{ info_url }}">订单详情</a>
|
||||
</td>
|
||||
</tr>
|
||||
<div class="layout-main">
|
||||
<div class="my-sidebar">{{ partial('my/menu') }}</div>
|
||||
<div class="my-content">
|
||||
<div class="order-filter wrap">
|
||||
{% set status = request.get('status','trim','all') %}
|
||||
{% for key,value in status_types %}
|
||||
{% set class = (status == key) ? 'layui-btn layui-btn-xs' : 'none' %}
|
||||
{% set url = (key == 'all') ? url({'for':'web.my.orders'}) : url({'for':'web.my.orders'},{'status':key}) %}
|
||||
<a class="{{ class }}" href="{{ url }}">{{ value }}</a>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{{ partial('partials/pager') }}
|
||||
{% else %}
|
||||
<div class="search-empty">未发现相关记录</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if pager.total_pages > 0 %}
|
||||
<div class="order-list">
|
||||
{% for item in pager.items %}
|
||||
<div class="order-card">
|
||||
<div class="header">
|
||||
<span class="sn">编号:{{ item.sn }}</span>
|
||||
<span class="time">时间:{{ date('Y-m-d H:i:s',item.create_time) }}</span>
|
||||
</div>
|
||||
<div class="body clearfix">
|
||||
<div class="column subject">{{ item.subject }}</div>
|
||||
<div class="column price">{{ '¥%0.2f'|format(item.amount) }}</div>
|
||||
<div class="column status">{{ order_status(item.status) }}</div>
|
||||
<div class="column action">
|
||||
<a class="layui-btn layui-btn-sm" href="javascript:">详情</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{{ partial('partials/pager') }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
@ -3,8 +3,8 @@
|
||||
{% block content %}
|
||||
|
||||
<div class="layout-main">
|
||||
<div class="layout-sidebar">{{ partial('my/menu') }}</div>
|
||||
<div class="layout-content">
|
||||
<div class="my-sidebar">{{ partial('my/menu') }}</div>
|
||||
<div class="my-content">
|
||||
<div class="wrap">
|
||||
<div class="my-nav-title">个人信息</div>
|
||||
<form class="layui-form my-form" method="post" action="{{ url({'for':'web.my.update_profile'}) }}">
|
||||
@ -42,4 +42,5 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
@ -6,59 +6,39 @@
|
||||
|
||||
{% set status_types = {'all':'全部','pending':'待处理','canceled':'已取消','approved':'退款中','finished':'已完成'} %}
|
||||
|
||||
<div class="layui-breadcrumb breadcrumb">
|
||||
<a href="/">首页</a>
|
||||
<a><cite>我的退款</cite></a>
|
||||
</div>
|
||||
|
||||
<div class="wrap">
|
||||
<div class="order-filter">
|
||||
{% set status = request.get('status','trim','all') %}
|
||||
{% for key,value in status_types %}
|
||||
{% set class = (status == key) ? 'layui-btn layui-btn-sm' : 'none' %}
|
||||
{% set url = (key == 'all') ? url({'for':'web.my.refunds'}) : url({'for':'web.my.refunds'},{'status':key}) %}
|
||||
<a class="{{ class }}" href="{{ url }}">{{ value }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% if pager.total_pages > 0 %}
|
||||
<table class="layui-table order-table kg-table" lay-size="lg" lay-skin="nob">
|
||||
<colgroup>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>退款项目</th>
|
||||
<th>订单金额</th>
|
||||
<th>退款金额</th>
|
||||
<th>创建时间</th>
|
||||
<th>退款状态</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in pager.items %}
|
||||
{% set info_url = url({'for':'web.refund.info'},{'sn':item.sn}) %}
|
||||
<tr>
|
||||
<td>{{ item.subject }}</td>
|
||||
<td><span class="price">{{ '¥%0.2f'|format(item.order.amount) }}</span></td>
|
||||
<td><span class="price">{{ '¥%0.2f'|format(item.amount) }}</span></td>
|
||||
<td>{{ date('Y-m-d H:i:s',item.create_time) }}</td>
|
||||
<td>{{ refund_status(item.status) }}</td>
|
||||
<td align="center">
|
||||
<a class="layui-btn layui-btn-sm" href="{{ info_url }}">退款详情</a>
|
||||
</td>
|
||||
</tr>
|
||||
<div class="layout-main">
|
||||
<div class="my-sidebar">{{ partial('my/menu') }}</div>
|
||||
<div class="my-content">
|
||||
<div class="order-filter wrap">
|
||||
{% set status = request.get('status','trim','all') %}
|
||||
{% for key,value in status_types %}
|
||||
{% set class = (status == key) ? 'layui-btn layui-btn-xs' : 'none' %}
|
||||
{% set url = (key == 'all') ? url({'for':'web.my.refunds'}) : url({'for':'web.my.refunds'},{'status':key}) %}
|
||||
<a class="{{ class }}" href="{{ url }}">{{ value }}</a>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{{ partial('partials/pager') }}
|
||||
{% else %}
|
||||
<div class="search-empty">未发现相关记录</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if pager.total_pages > 0 %}
|
||||
<div class="order-list">
|
||||
{% for item in pager.items %}
|
||||
<div class="order-card">
|
||||
<div class="header">
|
||||
<span class="sn">编号:{{ item.sn }}</span>
|
||||
<span class="time">时间:{{ date('Y-m-d H:i:s',item.create_time) }}</span>
|
||||
</div>
|
||||
<div class="body clearfix">
|
||||
<div class="column subject">{{ item.subject }}</div>
|
||||
<div class="column price">{{ '¥%0.2f'|format(item.amount) }}</div>
|
||||
<div class="column status">{{ refund_status(item.status) }}</div>
|
||||
<div class="column action">
|
||||
<a class="layui-btn layui-btn-sm" href="javascript:">详情</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{{ partial('partials/pager') }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
@ -108,7 +108,7 @@
|
||||
<div class="layui-progress-bar" lay-percent="{{ item.progress }}%"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="duration">已学习 {{ item.duration|total_duration }}</div>
|
||||
<div class="duration">已学习 {{ item.duration|duration }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{%- endmacro %}
|
@ -1,69 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Listeners;
|
||||
|
||||
use App\Caches\ChapterCounter as CacheChapterCounter;
|
||||
use App\Models\Chapter as ChapterModel;
|
||||
use App\Services\Syncer\ChapterCounter as ChapterCounterSyncer;
|
||||
use Phalcon\Events\Event;
|
||||
|
||||
class ChapterCounter extends Listener
|
||||
{
|
||||
|
||||
protected $counter;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->counter = new CacheChapterCounter();
|
||||
}
|
||||
|
||||
public function incrUserCount(Event $event, $source, ChapterModel $chapter)
|
||||
{
|
||||
$this->counter->hIncrBy($chapter->id, 'user_count');
|
||||
|
||||
$this->syncChapterCounter($chapter);
|
||||
}
|
||||
|
||||
public function decrUserCount(Event $event, $source, ChapterModel $chapter)
|
||||
{
|
||||
$this->counter->hDecrBy($chapter->id, 'user_count');
|
||||
|
||||
$this->syncChapterCounter($chapter);
|
||||
}
|
||||
|
||||
public function incrConsultCount(Event $event, $source, ChapterModel $chapter)
|
||||
{
|
||||
$this->counter->hIncrBy($chapter->id, 'consult_count');
|
||||
|
||||
$this->syncChapterCounter($chapter);
|
||||
}
|
||||
|
||||
public function decrConsultCount(Event $event, $source, ChapterModel $chapter)
|
||||
{
|
||||
$this->counter->hDecrBy($chapter->id, 'consult_count');
|
||||
|
||||
$this->syncChapterCounter($chapter);
|
||||
}
|
||||
|
||||
public function incrLikeCount(Event $event, $source, ChapterModel $chapter)
|
||||
{
|
||||
$this->counter->hIncrBy($chapter->id, 'like_count');
|
||||
|
||||
$this->syncChapterCounter($chapter);
|
||||
}
|
||||
|
||||
public function decrLikeCount(Event $event, $source, ChapterModel $chapter)
|
||||
{
|
||||
$this->counter->hDecrBy($chapter->id, 'like_count');
|
||||
|
||||
$this->syncChapterCounter($chapter);
|
||||
}
|
||||
|
||||
protected function syncChapterCounter(ChapterModel $chapter)
|
||||
{
|
||||
$syncer = new ChapterCounterSyncer();
|
||||
|
||||
$syncer->addItem($chapter->id);
|
||||
}
|
||||
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Listeners;
|
||||
|
||||
use App\Caches\ConsultCounter as CacheConsultCounter;
|
||||
use App\Models\Consult as ConsultModel;
|
||||
use App\Services\Syncer\ConsultCounter as ConsultCounterSyncer;
|
||||
use Phalcon\Events\Event;
|
||||
|
||||
class ConsultCounter extends Listener
|
||||
{
|
||||
|
||||
protected $counter;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->counter = new CacheConsultCounter();
|
||||
}
|
||||
|
||||
public function incrLikeCount(Event $event, $source, ConsultModel $consult)
|
||||
{
|
||||
$this->counter->hIncrBy($consult->id, 'like_count');
|
||||
|
||||
$this->syncConsultCounter($consult);
|
||||
}
|
||||
|
||||
public function decrLikeCount(Event $event, $source, ConsultModel $consult)
|
||||
{
|
||||
$this->counter->hDecrBy($consult->id, 'like_count');
|
||||
|
||||
$this->syncConsultCounter($consult);
|
||||
}
|
||||
|
||||
protected function syncConsultCounter(ConsultModel $consult)
|
||||
{
|
||||
$syncer = new ConsultCounterSyncer();
|
||||
|
||||
$syncer->addItem($consult->id);
|
||||
}
|
||||
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Listeners;
|
||||
|
||||
use App\Caches\CourseCounter as CacheCourseCounter;
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Services\Syncer\CourseCounter as CourseCounterSyncer;
|
||||
use App\Services\Syncer\CourseIndex as CourseIndexSyncer;
|
||||
use Phalcon\Events\Event;
|
||||
|
||||
class CourseCounter extends Listener
|
||||
{
|
||||
|
||||
protected $counter;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->counter = new CacheCourseCounter();
|
||||
}
|
||||
|
||||
public function incrUserCount(Event $event, $source, CourseModel $course)
|
||||
{
|
||||
$this->counter->hIncrBy($course->id, 'user_count');
|
||||
|
||||
$this->syncCourseCounter($course);
|
||||
|
||||
$this->syncCourseIndex($course);
|
||||
}
|
||||
|
||||
public function decrUserCount(Event $event, $source, CourseModel $course)
|
||||
{
|
||||
$this->counter->hDecrBy($course->id, 'user_count');
|
||||
|
||||
$this->syncCourseCounter($course);
|
||||
|
||||
$this->syncCourseIndex($course);
|
||||
}
|
||||
|
||||
public function incrConsultCount(Event $event, $source, CourseModel $course)
|
||||
{
|
||||
$this->counter->hIncrBy($course->id, 'consult_count');
|
||||
|
||||
$this->syncCourseCounter($course);
|
||||
}
|
||||
|
||||
public function decrConsultCount(Event $event, $source, CourseModel $course)
|
||||
{
|
||||
$this->counter->hDecrBy($course->id, 'consult_count');
|
||||
|
||||
$this->syncCourseCounter($course);
|
||||
}
|
||||
|
||||
public function incrReviewCount(Event $event, $source, CourseModel $course)
|
||||
{
|
||||
$this->counter->hIncrBy($course->id, 'review_count');
|
||||
|
||||
$this->syncCourseCounter($course);
|
||||
|
||||
$this->syncCourseIndex($course);
|
||||
}
|
||||
|
||||
public function decrReviewCount(Event $event, $source, CourseModel $course)
|
||||
{
|
||||
$this->counter->hDecrBy($course->id, 'review_count');
|
||||
|
||||
$this->syncCourseCounter($course);
|
||||
|
||||
$this->syncCourseIndex($course);
|
||||
}
|
||||
|
||||
public function incrFavoriteCount(Event $event, $source, CourseModel $course)
|
||||
{
|
||||
$this->counter->hIncrBy($course->id, 'favorite_count');
|
||||
|
||||
$this->syncCourseCounter($course);
|
||||
}
|
||||
|
||||
public function decrFavoriteCount(Event $event, $source, CourseModel $course)
|
||||
{
|
||||
$this->counter->hDecrBy($course->id, 'favorite_count');
|
||||
|
||||
$this->syncCourseCounter($course);
|
||||
}
|
||||
|
||||
protected function syncCourseCounter(CourseModel $course)
|
||||
{
|
||||
$syncer = new CourseCounterSyncer();
|
||||
|
||||
$syncer->addItem($course->id);
|
||||
}
|
||||
|
||||
protected function syncCourseIndex(CourseModel $course)
|
||||
{
|
||||
$syncer = new CourseIndexSyncer();
|
||||
|
||||
$syncer->addItem($course->id);
|
||||
}
|
||||
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Listeners;
|
||||
|
||||
use App\Caches\ReviewCounter as CacheReviewCounter;
|
||||
use App\Models\Review as ReviewModel;
|
||||
use App\Services\Syncer\ReviewCounter as ReviewCounterSyncer;
|
||||
use Phalcon\Events\Event;
|
||||
|
||||
class ReviewCounter extends Listener
|
||||
{
|
||||
|
||||
protected $counter;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->counter = new CacheReviewCounter();
|
||||
}
|
||||
|
||||
public function incrLikeCount(Event $event, $source, ReviewModel $review)
|
||||
{
|
||||
$this->counter->hIncrBy($review->id, 'like_count');
|
||||
|
||||
$this->syncReviewCounter($review);
|
||||
}
|
||||
|
||||
public function decrLikeCount(Event $event, $source, ReviewModel $review)
|
||||
{
|
||||
$this->counter->hDecrBy($review->id, 'like_count');
|
||||
|
||||
$this->syncReviewCounter($review);
|
||||
}
|
||||
|
||||
protected function syncReviewCounter(ReviewModel $review)
|
||||
{
|
||||
$syncer = new ReviewCounterSyncer();
|
||||
|
||||
$syncer->addItem($review->id);
|
||||
}
|
||||
|
||||
}
|
@ -126,11 +126,11 @@ class Chapter extends Model
|
||||
public $user_count;
|
||||
|
||||
/**
|
||||
* 评论数
|
||||
* 咨询数
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $comment_count;
|
||||
public $consult_count;
|
||||
|
||||
/**
|
||||
* 点赞数
|
||||
|
29
app/Services/Frontend/Chapter/ChapterBasicInfo.php
Normal file
29
app/Services/Frontend/Chapter/ChapterBasicInfo.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Frontend\Chapter;
|
||||
|
||||
use App\Services\Frontend\ChapterTrait;
|
||||
use App\Services\Frontend\CourseTrait;
|
||||
use App\Services\Frontend\Service as FrontendService;
|
||||
|
||||
class ChapterBasicInfo extends FrontendService
|
||||
{
|
||||
|
||||
use CourseTrait;
|
||||
use ChapterTrait;
|
||||
use ChapterBasicInfoTrait;
|
||||
|
||||
public function handle($id)
|
||||
{
|
||||
$chapter = $this->checkChapter($id);
|
||||
|
||||
$course = $this->checkCourse($chapter->course_id);
|
||||
|
||||
$result = $this->handleBasicInfo($chapter);
|
||||
|
||||
$result['course'] = $this->handleCourseInfo($course);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
@ -6,24 +6,13 @@ use App\Models\Chapter as ChapterModel;
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Repos\Chapter as ChapterRepo;
|
||||
use App\Services\ChapterVod as ChapterVodService;
|
||||
use App\Services\Frontend\ChapterTrait;
|
||||
use App\Services\Frontend\Service as FrontendService;
|
||||
use App\Services\Live as LiveService;
|
||||
use WhichBrowser\Parser as BrowserParser;
|
||||
|
||||
class ChapterInfoBasic extends FrontendService
|
||||
trait ChapterBasicInfoTrait
|
||||
{
|
||||
|
||||
use ChapterTrait;
|
||||
|
||||
public function handle($id)
|
||||
{
|
||||
$chapter = $this->checkChapterCache($id);
|
||||
|
||||
return $this->handleChapter($chapter);
|
||||
}
|
||||
|
||||
protected function handleChapter(ChapterModel $chapter)
|
||||
protected function handleBasicInfo(ChapterModel $chapter)
|
||||
{
|
||||
$result = [];
|
||||
|
||||
@ -42,6 +31,15 @@ class ChapterInfoBasic extends FrontendService
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function handleCourseInfo(CourseModel $course)
|
||||
{
|
||||
return [
|
||||
'id' => $course->id,
|
||||
'title' => $course->title,
|
||||
'cover' => $course->cover,
|
||||
];
|
||||
}
|
||||
|
||||
protected function formatChapterVod(ChapterModel $chapter)
|
||||
{
|
||||
$chapterVodService = new ChapterVodService();
|
||||
@ -56,7 +54,6 @@ class ChapterInfoBasic extends FrontendService
|
||||
'play_urls' => $playUrls,
|
||||
'user_count' => $chapter->user_count,
|
||||
'like_count' => $chapter->like_count,
|
||||
'comment_count' => $chapter->comment_count,
|
||||
];
|
||||
}
|
||||
|
||||
@ -88,7 +85,6 @@ class ChapterInfoBasic extends FrontendService
|
||||
'end_time' => $live->end_time,
|
||||
'user_count' => $chapter->user_count,
|
||||
'like_count' => $chapter->like_count,
|
||||
'comment_count' => $chapter->comment_count,
|
||||
];
|
||||
}
|
||||
|
||||
@ -106,7 +102,6 @@ class ChapterInfoBasic extends FrontendService
|
||||
'content' => $read->content,
|
||||
'user_count' => $chapter->user_count,
|
||||
'like_count' => $chapter->like_count,
|
||||
'comment_count' => $chapter->comment_count,
|
||||
];
|
||||
}
|
||||
|
@ -7,13 +7,10 @@ use App\Models\ChapterUser as ChapterUserModel;
|
||||
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\ChapterLike as ChapterLikeRepo;
|
||||
use App\Services\ChapterVod as ChapterVodService;
|
||||
use App\Services\Frontend\ChapterTrait;
|
||||
use App\Services\Frontend\CourseTrait;
|
||||
use App\Services\Frontend\Service as FrontendService;
|
||||
use App\Services\Live as LiveService;
|
||||
|
||||
class ChapterInfo extends FrontendService
|
||||
{
|
||||
@ -30,12 +27,13 @@ class ChapterInfo extends FrontendService
|
||||
|
||||
use CourseTrait;
|
||||
use ChapterTrait;
|
||||
use ChapterBasicInfoTrait;
|
||||
|
||||
public function handle($id)
|
||||
{
|
||||
$chapter = $this->checkChapterCache($id);
|
||||
$chapter = $this->checkChapter($id);
|
||||
|
||||
$course = $this->checkCourseCache($chapter->course_id);
|
||||
$course = $this->checkCourse($chapter->course_id);
|
||||
|
||||
$this->course = $course;
|
||||
|
||||
@ -54,9 +52,9 @@ class ChapterInfo extends FrontendService
|
||||
|
||||
protected function handleChapter(ChapterModel $chapter, UserModel $user)
|
||||
{
|
||||
$result = $this->formatChapter($chapter);
|
||||
$result = $this->handleBasicInfo($chapter);
|
||||
|
||||
$result['course'] = $this->handleCourse($this->course);
|
||||
$result['course'] = $this->handleCourseInfo($this->course);
|
||||
|
||||
$me = [
|
||||
'plan_id' => 0,
|
||||
@ -93,109 +91,6 @@ class ChapterInfo extends FrontendService
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function handleCourse(CourseModel $course)
|
||||
{
|
||||
return [
|
||||
'id' => $course->id,
|
||||
'title' => $course->title,
|
||||
'cover' => $course->cover,
|
||||
];
|
||||
}
|
||||
|
||||
protected function formatChapter(ChapterModel $chapter)
|
||||
{
|
||||
$item = [];
|
||||
|
||||
switch ($chapter->model) {
|
||||
case CourseModel::MODEL_VOD:
|
||||
$item = $this->formatChapterVod($chapter);
|
||||
break;
|
||||
case CourseModel::MODEL_LIVE:
|
||||
$item = $this->formatChapterLive($chapter);
|
||||
break;
|
||||
case CourseModel::MODEL_READ:
|
||||
$item = $this->formatChapterRead($chapter);
|
||||
break;
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
protected function formatChapterVod(ChapterModel $chapter)
|
||||
{
|
||||
$service = new ChapterVodService();
|
||||
|
||||
$playUrls = $service->getPlayUrls($chapter->id);
|
||||
|
||||
return [
|
||||
'id' => $chapter->id,
|
||||
'title' => $chapter->title,
|
||||
'summary' => $chapter->summary,
|
||||
'model' => $chapter->model,
|
||||
'play_urls' => $playUrls,
|
||||
'user_count' => $chapter->user_count,
|
||||
'like_count' => $chapter->like_count,
|
||||
'consult_count' => $chapter->consult_count,
|
||||
];
|
||||
}
|
||||
|
||||
protected function formatChapterLive(ChapterModel $chapter)
|
||||
{
|
||||
$service = new LiveService();
|
||||
|
||||
$streamName = $this->getLiveStreamName($chapter->id);
|
||||
|
||||
$chapterRepo = new ChapterRepo();
|
||||
|
||||
$live = $chapterRepo->findChapterLive($chapter->id);
|
||||
|
||||
$playUrls = [];
|
||||
|
||||
if ($live->start_time - time() > 1800) {
|
||||
$status = 'pending';
|
||||
} elseif (time() - $live->end_time > 1800) {
|
||||
$status = 'finished';
|
||||
} else {
|
||||
$status = $service->getStreamState($streamName);
|
||||
}
|
||||
|
||||
if ($status == 'active') {
|
||||
$playUrls = $service->getPullUrls($streamName);
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => $chapter->id,
|
||||
'title' => $chapter->title,
|
||||
'summary' => $chapter->summary,
|
||||
'model' => $chapter->model,
|
||||
'status' => $status,
|
||||
'start_time' => $live->start_time,
|
||||
'end_time' => $live->end_time,
|
||||
'play_urls' => $playUrls,
|
||||
'user_count' => $chapter->user_count,
|
||||
'like_count' => $chapter->like_count,
|
||||
'consult_count' => $chapter->consult_count,
|
||||
];
|
||||
}
|
||||
|
||||
protected function formatChapterRead(ChapterModel $chapter)
|
||||
{
|
||||
$chapterRepo = new ChapterRepo();
|
||||
|
||||
$read = $chapterRepo->findChapterRead($chapter->id);
|
||||
|
||||
return [
|
||||
'id' => $chapter->id,
|
||||
'title' => $chapter->title,
|
||||
'summary' => $chapter->summary,
|
||||
'model' => $chapter->model,
|
||||
'content' => $read->content,
|
||||
'user_count' => $chapter->user_count,
|
||||
'like_count' => $chapter->like_count,
|
||||
'consult_count' => $chapter->consult_count,
|
||||
];
|
||||
}
|
||||
|
||||
protected function handleCourseUser(CourseModel $course, UserModel $user)
|
||||
{
|
||||
if ($user->id == 0) return;
|
||||
@ -247,11 +142,6 @@ class ChapterInfo extends FrontendService
|
||||
$this->incrChapterUserCount($chapter);
|
||||
}
|
||||
|
||||
protected function getVodPosition(ChapterModel $chapter, UserModel $user)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected function getLiveStreamName($id)
|
||||
{
|
||||
return "chapter_{$id}";
|
||||
@ -259,12 +149,16 @@ class ChapterInfo extends FrontendService
|
||||
|
||||
protected function incrCourseUserCount(CourseModel $course)
|
||||
{
|
||||
$this->eventsManager->fire('courseCounter:incrUserCount', $this, $course);
|
||||
$course->user_count += 1;
|
||||
|
||||
$course->update();
|
||||
}
|
||||
|
||||
protected function incrChapterUserCount(ChapterModel $chapter)
|
||||
{
|
||||
$this->eventsManager->fire('chapterCounter:incrUserCount', $this, $chapter);
|
||||
$chapter->user_count += 1;
|
||||
|
||||
$chapter->update();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ 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\Events\Manager as EventsManager;
|
||||
|
||||
class ChapterLike extends FrontendService
|
||||
{
|
||||
@ -64,25 +63,21 @@ class ChapterLike extends FrontendService
|
||||
|
||||
protected function incrLikeCount(ChapterModel $chapter)
|
||||
{
|
||||
$this->getPhEventsManager()->fire('chapterCounter:incrLikeCount', $this, $chapter);
|
||||
$chapter->like_count += 1;
|
||||
|
||||
$chapter->update();
|
||||
}
|
||||
|
||||
protected function decrLikeCount(ChapterModel $chapter)
|
||||
{
|
||||
$this->getPhEventsManager()->fire('chapterCounter:decrLikeCount', $this, $chapter);
|
||||
$chapter->like_count -= 1;
|
||||
|
||||
$chapter->update();
|
||||
}
|
||||
|
||||
protected function incrUserDailyChapterLikeCount(UserModel $user)
|
||||
{
|
||||
$this->getPhEventsManager()->fire('userDailyCounter:incrChapterLikeCount', $this, $user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return EventsManager
|
||||
*/
|
||||
protected function getPhEventsManager()
|
||||
{
|
||||
return $this->getDI()->get('eventsManager');
|
||||
$this->eventsManager->fire('userDailyCounter:incrChapterLikeCount', $this, $user);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,75 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Frontend\Chapter;
|
||||
|
||||
use App\Builders\CommentList as CommentListBuilder;
|
||||
use App\Library\Paginator\Query as PagerQuery;
|
||||
use App\Repos\Comment as CommentRepo;
|
||||
use App\Services\Frontend\ChapterTrait;
|
||||
use App\Services\Frontend\Service as FrontendService;
|
||||
|
||||
class CommentList extends FrontendService
|
||||
{
|
||||
|
||||
use ChapterTrait;
|
||||
|
||||
public function handle($chapterId)
|
||||
{
|
||||
$chapter = $this->checkChapter($chapterId);
|
||||
|
||||
$pagerQuery = new PagerQuery();
|
||||
|
||||
$params = $pagerQuery->getParams();
|
||||
|
||||
$params['chapter_id'] = $chapter->id;
|
||||
$params['published'] = 1;
|
||||
$params['deleted'] = 0;
|
||||
|
||||
$sort = $pagerQuery->getSort();
|
||||
$page = $pagerQuery->getPage();
|
||||
$limit = $pagerQuery->getLimit();
|
||||
|
||||
$commentRepo = new CommentRepo();
|
||||
|
||||
$pager = $commentRepo->paginate($params, $sort, $page, $limit);
|
||||
|
||||
return $this->handleComments($pager);
|
||||
}
|
||||
|
||||
protected function handleComments($pager)
|
||||
{
|
||||
if ($pager->total_items == 0) {
|
||||
return $pager;
|
||||
}
|
||||
|
||||
$comments = $pager->items->toArray();
|
||||
|
||||
$builder = new CommentListBuilder();
|
||||
|
||||
$users = $builder->getUsers($comments);
|
||||
|
||||
$items = [];
|
||||
|
||||
foreach ($comments as $comment) {
|
||||
|
||||
$user = $users[$comment['user_id']] ?? new \stdClass();
|
||||
|
||||
$comment['mentions'] = $comment['mentions'] ? json_decode($comment['mentions']) : [];
|
||||
|
||||
$items[] = [
|
||||
'id' => $comment['id'],
|
||||
'content' => $comment['content'],
|
||||
'mentions' => $comment['mentions'],
|
||||
'like_count' => $comment['like_count'],
|
||||
'reply_count' => $comment['reply_count'],
|
||||
'create_time' => $comment['create_time'],
|
||||
'user' => $user,
|
||||
];
|
||||
}
|
||||
|
||||
$pager->items = $items;
|
||||
|
||||
return $pager;
|
||||
}
|
||||
|
||||
}
|
@ -52,7 +52,9 @@ class ConsultCreate extends FrontendService
|
||||
$consult->create();
|
||||
|
||||
$this->incrCourseConsultCount($course);
|
||||
|
||||
$this->incrChapterConsultCount($chapter);
|
||||
|
||||
$this->incrUserDailyConsultCount($user);
|
||||
|
||||
return $consult;
|
||||
@ -76,12 +78,16 @@ class ConsultCreate extends FrontendService
|
||||
|
||||
protected function incrCourseConsultCount(CourseModel $course)
|
||||
{
|
||||
$this->eventsManager->fire('courseCounter:incrConsultCount', $this, $course);
|
||||
$course->consult_count += 1;
|
||||
|
||||
$course->update();
|
||||
}
|
||||
|
||||
protected function incrChapterConsultCount(ChapterModel $chapter)
|
||||
{
|
||||
$this->eventsManager->fire('chapterCounter:incrConsultCount', $this, $chapter);
|
||||
$chapter->consult_count += 1;
|
||||
|
||||
$chapter->update();
|
||||
}
|
||||
|
||||
protected function incrUserDailyConsultCount(UserModel $user)
|
||||
|
@ -2,7 +2,9 @@
|
||||
|
||||
namespace App\Services\Frontend\Consult;
|
||||
|
||||
use App\Models\Chapter as ChapterModel;
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Services\Frontend\ChapterTrait;
|
||||
use App\Services\Frontend\ConsultTrait;
|
||||
use App\Services\Frontend\CourseTrait;
|
||||
use App\Services\Frontend\Service as FrontendService;
|
||||
@ -11,8 +13,9 @@ use App\Validators\Consult as ConsultValidator;
|
||||
class ConsultDelete extends FrontendService
|
||||
{
|
||||
|
||||
use ConsultTrait;
|
||||
use CourseTrait;
|
||||
use ChapterTrait;
|
||||
use ConsultTrait;
|
||||
|
||||
public function handle($id)
|
||||
{
|
||||
@ -20,20 +23,33 @@ class ConsultDelete extends FrontendService
|
||||
|
||||
$course = $this->checkCourse($consult->course_id);
|
||||
|
||||
$chapter = $this->checkChapter($consult->chapter_id);
|
||||
|
||||
$user = $this->getLoginUser();
|
||||
|
||||
$validator = new ConsultValidator();
|
||||
|
||||
$validator->checkOwner($user->id, $consult->user_id);
|
||||
|
||||
$consult->delete();
|
||||
$consult->update(['deleted' => 1]);
|
||||
|
||||
$this->decrCourseConsultCount($course);
|
||||
|
||||
$this->decrChapterConsultCount($chapter);
|
||||
}
|
||||
|
||||
protected function decrCourseConsultCount(CourseModel $course)
|
||||
{
|
||||
$this->eventsManager->fire('courseCounter:decrConsultCount', $this, $course);
|
||||
$course->consult_count -= 1;
|
||||
|
||||
$course->update();
|
||||
}
|
||||
|
||||
protected function decrChapterConsultCount(ChapterModel $chapter)
|
||||
{
|
||||
$chapter->consult_count -= 1;
|
||||
|
||||
$chapter->update();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ 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\Events\Manager as EventsManager;
|
||||
|
||||
class ConsultLike extends FrontendService
|
||||
{
|
||||
@ -64,25 +63,21 @@ class ConsultLike extends FrontendService
|
||||
|
||||
protected function incrLikeCount(ConsultModel $consult)
|
||||
{
|
||||
$this->getPhEventsManager()->fire('consultCounter:incrLikeCount', $this, $consult);
|
||||
$consult->like_count += 1;
|
||||
|
||||
$consult->update();
|
||||
}
|
||||
|
||||
protected function decrLikeCount(ConsultModel $consult)
|
||||
{
|
||||
$this->getPhEventsManager()->fire('consultCounter:decrLikeCount', $this, $consult);
|
||||
$consult->like_count -= 1;
|
||||
|
||||
$consult->update();
|
||||
}
|
||||
|
||||
protected function incrUserDailyConsultLikeCount(UserModel $user)
|
||||
{
|
||||
$this->getPhEventsManager()->fire('userDailyCounter:incrConsultLikeCount', $this, $user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return EventsManager
|
||||
*/
|
||||
protected function getPhEventsManager()
|
||||
{
|
||||
return $this->getDI()->get('eventsManager');
|
||||
$this->eventsManager->fire('userDailyCounter:incrConsultLikeCount', $this, $user);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,14 +3,12 @@
|
||||
namespace App\Services\Frontend\Consult;
|
||||
|
||||
use App\Services\Frontend\ConsultTrait;
|
||||
use App\Services\Frontend\CourseTrait;
|
||||
use App\Services\Frontend\Service as FrontendService;
|
||||
use App\Validators\Consult as ConsultValidator;
|
||||
|
||||
class ConsultUpdate extends FrontendService
|
||||
{
|
||||
|
||||
use CourseTrait;
|
||||
use ConsultTrait;
|
||||
|
||||
public function handle($id)
|
||||
|
21
app/Services/Frontend/Course/CourseBasicInfo.php
Normal file
21
app/Services/Frontend/Course/CourseBasicInfo.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Frontend\Course;
|
||||
|
||||
use App\Services\Frontend\CourseTrait;
|
||||
use App\Services\Frontend\Service as FrontendService;
|
||||
|
||||
class CourseBasicInfo extends FrontendService
|
||||
{
|
||||
|
||||
use CourseTrait;
|
||||
use CourseBasicInfoTrait;
|
||||
|
||||
public function handle($id)
|
||||
{
|
||||
$course = $this->checkCourse($id);
|
||||
|
||||
return $this->handleBasicInfo($course);
|
||||
}
|
||||
|
||||
}
|
77
app/Services/Frontend/Course/CourseBasicInfoTrait.php
Normal file
77
app/Services/Frontend/Course/CourseBasicInfoTrait.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Frontend\Course;
|
||||
|
||||
use App\Caches\CourseTeacherList as CourseTeacherListCache;
|
||||
use App\Http\Web\Services\CourseQuery as CourseQueryService;
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
|
||||
trait CourseBasicInfoTrait
|
||||
{
|
||||
|
||||
protected function handleBasicInfo(CourseModel $course)
|
||||
{
|
||||
$categoryPaths = $this->handleCategoryPaths($course);
|
||||
|
||||
$teachers = $this->handleTeachers($course);
|
||||
|
||||
$ratings = $this->handleRatings($course);
|
||||
|
||||
return [
|
||||
'id' => $course->id,
|
||||
'title' => $course->title,
|
||||
'cover' => $course->cover,
|
||||
'summary' => $course->summary,
|
||||
'details' => $course->details,
|
||||
'keywords' => $course->keywords,
|
||||
'market_price' => $course->market_price,
|
||||
'vip_price' => $course->vip_price,
|
||||
'study_expiry' => $course->study_expiry,
|
||||
'refund_expiry' => $course->refund_expiry,
|
||||
'category_paths' => $categoryPaths,
|
||||
'teachers' => $teachers,
|
||||
'ratings' => $ratings,
|
||||
'model' => $course->model,
|
||||
'level' => $course->level,
|
||||
'attrs' => $course->attrs,
|
||||
'user_count' => $course->user_count,
|
||||
'lesson_count' => $course->lesson_count,
|
||||
'package_count' => $course->package_count,
|
||||
'review_count' => $course->review_count,
|
||||
'consult_count' => $course->consult_count,
|
||||
'favorite_count' => $course->favorite_count,
|
||||
];
|
||||
}
|
||||
|
||||
protected function handleCategoryPaths(CourseModel $course)
|
||||
{
|
||||
$service = new CourseQueryService();
|
||||
|
||||
return $service->handleCategoryPaths($course->category_id);
|
||||
}
|
||||
|
||||
protected function handleRatings(CourseModel $course)
|
||||
{
|
||||
$repo = new CourseRepo();
|
||||
|
||||
$rating = $repo->findCourseRating($course->id);
|
||||
|
||||
return [
|
||||
'rating' => $rating->rating,
|
||||
'rating1' => $rating->rating1,
|
||||
'rating2' => $rating->rating2,
|
||||
'rating3' => $rating->rating3,
|
||||
];
|
||||
}
|
||||
|
||||
protected function handleTeachers(CourseModel $course)
|
||||
{
|
||||
$cache = new CourseTeacherListCache();
|
||||
|
||||
$result = $cache->get($course->id);
|
||||
|
||||
return $result ?: [];
|
||||
}
|
||||
|
||||
}
|
@ -4,7 +4,6 @@ namespace App\Services\Frontend\Course;
|
||||
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Models\User as UserModel;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use App\Repos\CourseFavorite as CourseFavoriteRepo;
|
||||
use App\Services\Frontend\CourseTrait;
|
||||
use App\Services\Frontend\Service as FrontendService;
|
||||
@ -13,10 +12,11 @@ class CourseInfo extends FrontendService
|
||||
{
|
||||
|
||||
use CourseTrait;
|
||||
use CourseBasicInfoTrait;
|
||||
|
||||
public function handle($id)
|
||||
{
|
||||
$course = $this->checkCourseCache($id);
|
||||
$course = $this->checkCourse($id);
|
||||
|
||||
$user = $this->getCurrentUser();
|
||||
|
||||
@ -27,41 +27,7 @@ class CourseInfo extends FrontendService
|
||||
|
||||
protected function handleCourse(CourseModel $course, UserModel $user)
|
||||
{
|
||||
$repo = new CourseRepo();
|
||||
|
||||
$rating = $repo->findCourseRating($course->id);
|
||||
|
||||
$ratings = [
|
||||
'rating' => $rating->rating,
|
||||
'rating1' => $rating->rating1,
|
||||
'rating2' => $rating->rating2,
|
||||
'rating3' => $rating->rating3,
|
||||
];
|
||||
|
||||
$result = [
|
||||
'id' => $course->id,
|
||||
'title' => $course->title,
|
||||
'cover' => $course->cover,
|
||||
'summary' => $course->summary,
|
||||
'details' => $course->details,
|
||||
'keywords' => $course->keywords,
|
||||
'category_id' => $course->category_id,
|
||||
'teacher_id' => $course->teacher_id,
|
||||
'market_price' => $course->market_price,
|
||||
'vip_price' => $course->vip_price,
|
||||
'study_expiry' => $course->study_expiry,
|
||||
'refund_expiry' => $course->refund_expiry,
|
||||
'ratings' => $ratings,
|
||||
'model' => $course->model,
|
||||
'level' => $course->level,
|
||||
'attrs' => $course->attrs,
|
||||
'user_count' => $course->user_count,
|
||||
'lesson_count' => $course->lesson_count,
|
||||
'package_count' => $course->package_count,
|
||||
'review_count' => $course->review_count,
|
||||
'consult_count' => $course->consult_count,
|
||||
'favorite_count' => $course->favorite_count,
|
||||
];
|
||||
$result = $this->handleBasicInfo($course);
|
||||
|
||||
$me = [
|
||||
'plan_id' => 0,
|
||||
|
@ -1,48 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Frontend\Course;
|
||||
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Services\Frontend\CourseTrait;
|
||||
use App\Services\Frontend\Service as FrontendService;
|
||||
|
||||
class CourseInfoBasic extends FrontendService
|
||||
{
|
||||
|
||||
use CourseTrait;
|
||||
|
||||
public function handle($id)
|
||||
{
|
||||
$course = $this->checkCourseCache($id);
|
||||
|
||||
return $this->handleCourse($course);
|
||||
}
|
||||
|
||||
protected function handleCourse(CourseModel $course)
|
||||
{
|
||||
return [
|
||||
'id' => $course->id,
|
||||
'title' => $course->title,
|
||||
'cover' => $course->cover,
|
||||
'summary' => $course->summary,
|
||||
'details' => $course->details,
|
||||
'keywords' => $course->keywords,
|
||||
'market_price' => $course->market_price,
|
||||
'vip_price' => $course->vip_price,
|
||||
'study_expiry' => $course->study_expiry,
|
||||
'refund_expiry' => $course->refund_expiry,
|
||||
'rating' => $course->rating,
|
||||
'model' => $course->model,
|
||||
'level' => $course->level,
|
||||
'attrs' => $course->attrs,
|
||||
'user_count' => $course->user_count,
|
||||
'lesson_count' => $course->lesson_count,
|
||||
'package_count' => $course->package_count,
|
||||
'review_count' => $course->review_count,
|
||||
'comment_count' => $course->comment_count,
|
||||
'consult_count' => $course->consult_count,
|
||||
'favorite_count' => $course->favorite_count,
|
||||
];
|
||||
}
|
||||
|
||||
}
|
@ -5,8 +5,8 @@ namespace App\Services\Frontend\Review;
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Models\Review as ReviewModel;
|
||||
use App\Models\User as UserModel;
|
||||
use App\Repos\CourseRating as CourseRatingRepo;
|
||||
use App\Services\Frontend\CourseTrait;
|
||||
use App\Services\Frontend\ReviewTrait;
|
||||
use App\Services\Frontend\Service as FrontendService;
|
||||
use App\Validators\CourseUser as CourseUserValidator;
|
||||
use App\Validators\Review as ReviewValidator;
|
||||
@ -16,6 +16,7 @@ class ReviewCreate extends FrontendService
|
||||
{
|
||||
|
||||
use CourseTrait;
|
||||
use ReviewTrait;
|
||||
|
||||
public function handle()
|
||||
{
|
||||
@ -36,14 +37,15 @@ class ReviewCreate extends FrontendService
|
||||
|
||||
$validator = new ReviewValidator();
|
||||
|
||||
$data = [];
|
||||
$data = [
|
||||
'course_id' => $course->id,
|
||||
'user_id' => $user->id,
|
||||
];
|
||||
|
||||
$data['content'] = $validator->checkContent($post['content']);
|
||||
$data['rating1'] = $validator->checkRating($post['rating1']);
|
||||
$data['rating2'] = $validator->checkRating($post['rating2']);
|
||||
$data['rating3'] = $validator->checkRating($post['rating3']);
|
||||
$data['course_id'] = $course->id;
|
||||
$data['user_id'] = $user->id;
|
||||
|
||||
$review = new ReviewModel();
|
||||
|
||||
@ -58,25 +60,11 @@ class ReviewCreate extends FrontendService
|
||||
return $review;
|
||||
}
|
||||
|
||||
protected function updateCourseRating(CourseModel $course)
|
||||
{
|
||||
$repo = new CourseRatingRepo();
|
||||
|
||||
$courseRating = $repo->findByCourseId($course->id);
|
||||
|
||||
$courseRating->rating = $repo->averageRating($course->id);
|
||||
$courseRating->rating1 = $repo->averageRating1($course->id);
|
||||
$courseRating->rating2 = $repo->averageRating2($course->id);
|
||||
$courseRating->rating3 = $repo->averageRating3($course->id);
|
||||
$courseRating->update();
|
||||
|
||||
$course->rating = $courseRating->rating;
|
||||
$course->update();
|
||||
}
|
||||
|
||||
protected function incrCourseReviewCount(CourseModel $course)
|
||||
{
|
||||
$this->eventsManager->fire('courseCounter:incrReviewCount', $this, $course);
|
||||
$course->review_count += 1;
|
||||
|
||||
$course->update();
|
||||
}
|
||||
|
||||
protected function incrUserDailyReviewCount(UserModel $user)
|
||||
|
@ -18,7 +18,7 @@ class ReviewDelete extends FrontendService
|
||||
{
|
||||
$review = $this->checkReview($id);
|
||||
|
||||
$course = $this->checkCourseCache($review->course_id);
|
||||
$course = $this->checkCourse($review->course_id);
|
||||
|
||||
$user = $this->getLoginUser();
|
||||
|
||||
@ -29,11 +29,15 @@ class ReviewDelete extends FrontendService
|
||||
$review->delete();
|
||||
|
||||
$this->decrCourseReviewCount($course);
|
||||
|
||||
$this->updateCourseRating($course);
|
||||
}
|
||||
|
||||
protected function decrCourseReviewCount(CourseModel $course)
|
||||
{
|
||||
$this->eventsManager->fire('courseCounter:decrReviewCount', $this, $course);
|
||||
$course->review_count -= 1;
|
||||
|
||||
$course->update();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ 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\Events\Manager as EventsManager;
|
||||
|
||||
class ReviewLike extends FrontendService
|
||||
{
|
||||
@ -64,25 +63,21 @@ class ReviewLike extends FrontendService
|
||||
|
||||
protected function incrLikeCount(ReviewModel $review)
|
||||
{
|
||||
$this->getPhEventsManager()->fire('reviewCounter:incrLikeCount', $this, $review);
|
||||
$review->like_count += 1;
|
||||
|
||||
$review->update();
|
||||
}
|
||||
|
||||
protected function decrLikeCount(ReviewModel $review)
|
||||
{
|
||||
$this->getPhEventsManager()->fire('reviewCounter:decrLikeCount', $this, $review);
|
||||
$review->like_count -= 1;
|
||||
|
||||
$review->update();
|
||||
}
|
||||
|
||||
protected function incrUserDailyReviewLikeCount(UserModel $user)
|
||||
{
|
||||
$this->getPhEventsManager()->fire('userDailyCounter:incrReviewLikeCount', $this, $user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return EventsManager
|
||||
*/
|
||||
protected function getPhEventsManager()
|
||||
{
|
||||
return $this->getDI()->get('eventsManager');
|
||||
$this->eventsManager->fire('userDailyCounter:incrReviewLikeCount', $this, $user);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,18 +19,24 @@ class ReviewUpdate extends FrontendService
|
||||
|
||||
$review = $this->checkReview($id);
|
||||
|
||||
$course = $this->checkCourse($review->course_id);
|
||||
|
||||
$user = $this->getLoginUser();
|
||||
|
||||
$validator = new ReviewValidator();
|
||||
|
||||
$validator->checkOwner($user->id, $review->user_id);
|
||||
|
||||
$content = $validator->checkContent($post['content']);
|
||||
$rating = $validator->checkRating($post['rating']);
|
||||
$data = [];
|
||||
|
||||
$review->content = $content;
|
||||
$review->rating = $rating;
|
||||
$review->update();
|
||||
$data['content'] = $validator->checkContent($post['content']);
|
||||
$data['rating1'] = $validator->checkRating($post['rating1']);
|
||||
$data['rating2'] = $validator->checkRating($post['rating2']);
|
||||
$data['rating3'] = $validator->checkRating($post['rating3']);
|
||||
|
||||
$review->update($data);
|
||||
|
||||
$this->updateCourseRating($course);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Services\Frontend;
|
||||
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Repos\CourseRating as CourseRatingRepo;
|
||||
use App\Validators\Review as ReviewValidator;
|
||||
|
||||
trait ReviewTrait
|
||||
@ -14,4 +16,22 @@ trait ReviewTrait
|
||||
return $validator->checkReview($id);
|
||||
}
|
||||
|
||||
public function updateCourseRating(CourseModel $course)
|
||||
{
|
||||
$repo = new CourseRatingRepo();
|
||||
|
||||
$courseRating = $repo->findByCourseId($course->id);
|
||||
|
||||
$courseRating->rating = $repo->averageRating($course->id);
|
||||
$courseRating->rating1 = $repo->averageRating1($course->id);
|
||||
$courseRating->rating2 = $repo->averageRating2($course->id);
|
||||
$courseRating->rating3 = $repo->averageRating3($course->id);
|
||||
|
||||
$courseRating->update();
|
||||
|
||||
$course->rating = $courseRating->rating;
|
||||
|
||||
$course->update();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -84,7 +84,6 @@ class CourseDocument extends Component
|
||||
'teacher' => $teacher,
|
||||
'user_count' => $course->user_count,
|
||||
'lesson_count' => $course->lesson_count,
|
||||
'comment_count' => $course->comment_count,
|
||||
'consult_count' => $course->consult_count,
|
||||
'review_count' => $course->review_count,
|
||||
'favorite_count' => $course->favorite_count,
|
||||
|
@ -1,47 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Syncer;
|
||||
|
||||
use App\Library\Cache\Backend\Redis as RedisCache;
|
||||
use App\Services\Service;
|
||||
|
||||
class ChapterCounter extends Service
|
||||
{
|
||||
|
||||
/**
|
||||
* @var RedisCache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* @var \Redis
|
||||
*/
|
||||
protected $redis;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $lifetime = 86400;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->cache = $this->getDI()->get('cache');
|
||||
|
||||
$this->redis = $this->cache->getRedis();
|
||||
}
|
||||
|
||||
public function addItem($chapterId)
|
||||
{
|
||||
$key = $this->getSyncKey();
|
||||
|
||||
$this->redis->sAdd($key, $chapterId);
|
||||
|
||||
$this->redis->expire($key, $this->lifetime);
|
||||
}
|
||||
|
||||
public function getSyncKey()
|
||||
{
|
||||
return 'chapter_counter_sync';
|
||||
}
|
||||
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Syncer;
|
||||
|
||||
use App\Library\Cache\Backend\Redis as RedisCache;
|
||||
use App\Services\Service;
|
||||
|
||||
class CommentCounter extends Service
|
||||
{
|
||||
|
||||
/**
|
||||
* @var RedisCache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* @var \Redis
|
||||
*/
|
||||
protected $redis;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $lifetime = 86400;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->cache = $this->getDI()->get('cache');
|
||||
|
||||
$this->redis = $this->cache->getRedis();
|
||||
}
|
||||
|
||||
public function addItem($commentId)
|
||||
{
|
||||
$key = $this->getSyncKey();
|
||||
|
||||
$this->redis->sAdd($key, $commentId);
|
||||
|
||||
$this->redis->expire($key, $this->lifetime);
|
||||
}
|
||||
|
||||
public function getSyncKey()
|
||||
{
|
||||
return 'comment_counter_sync';
|
||||
}
|
||||
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Syncer;
|
||||
|
||||
use App\Library\Cache\Backend\Redis as RedisCache;
|
||||
use App\Services\Service;
|
||||
|
||||
class ConsultCounter extends Service
|
||||
{
|
||||
|
||||
/**
|
||||
* @var RedisCache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* @var \Redis
|
||||
*/
|
||||
protected $redis;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $lifetime = 86400;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->cache = $this->getDI()->get('cache');
|
||||
|
||||
$this->redis = $this->cache->getRedis();
|
||||
}
|
||||
|
||||
public function addItem($consultId)
|
||||
{
|
||||
$key = $this->getSyncKey();
|
||||
|
||||
$this->redis->sAdd($key, $consultId);
|
||||
|
||||
$this->redis->expire($key, $this->lifetime);
|
||||
}
|
||||
|
||||
public function getSyncKey()
|
||||
{
|
||||
return 'consult_counter_sync';
|
||||
}
|
||||
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Syncer;
|
||||
|
||||
use App\Library\Cache\Backend\Redis as RedisCache;
|
||||
use App\Services\Service;
|
||||
|
||||
class CourseCounter extends Service
|
||||
{
|
||||
|
||||
/**
|
||||
* @var RedisCache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* @var \Redis
|
||||
*/
|
||||
protected $redis;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $lifetime = 86400;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->cache = $this->getDI()->get('cache');
|
||||
|
||||
$this->redis = $this->cache->getRedis();
|
||||
}
|
||||
|
||||
public function addItem($courseId)
|
||||
{
|
||||
$key = $this->getSyncKey();
|
||||
|
||||
$this->redis->sAdd($key, $courseId);
|
||||
|
||||
$this->redis->expire($key, $this->lifetime);
|
||||
}
|
||||
|
||||
public function getSyncKey()
|
||||
{
|
||||
return 'course_counter_sync';
|
||||
}
|
||||
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Syncer;
|
||||
|
||||
use App\Library\Cache\Backend\Redis as RedisCache;
|
||||
use App\Services\Service;
|
||||
|
||||
class ReviewCounter extends Service
|
||||
{
|
||||
|
||||
/**
|
||||
* @var RedisCache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* @var \Redis
|
||||
*/
|
||||
protected $redis;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $lifetime = 86400;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->cache = $this->getDI()->get('cache');
|
||||
|
||||
$this->redis = $this->cache->getRedis();
|
||||
}
|
||||
|
||||
public function addItem($reviewId)
|
||||
{
|
||||
$key = $this->getSyncKey();
|
||||
|
||||
$this->redis->sAdd($key, $reviewId);
|
||||
|
||||
$this->redis->expire($key, $this->lifetime);
|
||||
}
|
||||
|
||||
public function getSyncKey()
|
||||
{
|
||||
return 'review_counter_sync';
|
||||
}
|
||||
|
||||
}
|
@ -1,19 +1,11 @@
|
||||
<?php
|
||||
|
||||
use App\Listeners\ChapterCounter;
|
||||
use App\Listeners\ConsultCounter;
|
||||
use App\Listeners\CourseCounter;
|
||||
use App\Listeners\Pay;
|
||||
use App\Listeners\Profiler;
|
||||
use App\Listeners\ReviewCounter;
|
||||
use App\Listeners\UserDailyCounter;
|
||||
|
||||
return [
|
||||
'db' => Profiler::class,
|
||||
'pay' => Pay::class,
|
||||
'courseCounter' => CourseCounter::class,
|
||||
'chapterCounter' => ChapterCounter::class,
|
||||
'consultCounter' => ConsultCounter::class,
|
||||
'reviewCounter' => ReviewCounter::class,
|
||||
'userDailyCounter' => UserDailyCounter::class,
|
||||
];
|
@ -1327,6 +1327,16 @@ body {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.my-sidebar {
|
||||
float: left;
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
.my-content {
|
||||
float: right;
|
||||
width: 900px;
|
||||
}
|
||||
|
||||
.my-profile-card {
|
||||
text-align: center;
|
||||
}
|
||||
@ -1336,8 +1346,8 @@ body {
|
||||
}
|
||||
|
||||
.my-profile-card .avatar img {
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
border-radius: 100px;
|
||||
}
|
||||
|
||||
@ -1347,7 +1357,7 @@ body {
|
||||
|
||||
.my-menu li {
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.my-nav-title {
|
||||
@ -1388,8 +1398,7 @@ body {
|
||||
}
|
||||
|
||||
.order-filter {
|
||||
line-height: 40px;
|
||||
margin-bottom: 20px;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.order-filter a {
|
||||
@ -1404,20 +1413,56 @@ body {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.order-item {
|
||||
.order-card {
|
||||
padding: 15px;
|
||||
margin-bottom: 20px;
|
||||
background-color: white;
|
||||
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.order-card .header {
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 10px;
|
||||
border-bottom: 1px solid #e6e6e6;
|
||||
}
|
||||
|
||||
.order-item:last-child {
|
||||
padding-bottom: 0;
|
||||
margin-bottom: 0;
|
||||
border-bottom: none;
|
||||
.order-card .header span {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.order-item span {
|
||||
margin-right: 8px;
|
||||
.order-card .header .sn {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.order-card .header .time {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.order-card .body {
|
||||
}
|
||||
|
||||
.order-card .column {
|
||||
float: left;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.order-card .subject {
|
||||
width: 50%;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.order-card .price {
|
||||
width: 20%;
|
||||
color: red;
|
||||
}
|
||||
|
||||
.order-card .status {
|
||||
width: 20%;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.order-card .action {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
.im-search-wrap {
|
||||
|
@ -3,6 +3,9 @@ layui.use(['jquery', 'helper'], function () {
|
||||
var $ = layui.jquery;
|
||||
var helper = layui.helper;
|
||||
|
||||
/**
|
||||
* 点赞
|
||||
*/
|
||||
$('.icon-praise').on('click', function () {
|
||||
var $this = $(this);
|
||||
var $parent = $this.parent();
|
||||
@ -29,4 +32,19 @@ layui.use(['jquery', 'helper'], function () {
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* 咨询
|
||||
*/
|
||||
$('.icon-help').on('click', function () {
|
||||
var url = $(this).parent().data('url');
|
||||
helper.checkLogin(function () {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '课程咨询',
|
||||
content: [url, 'no'],
|
||||
area: ['640px', '300px']
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
@ -1,21 +0,0 @@
|
||||
layui.use(['jquery', 'helper'], function () {
|
||||
|
||||
var $ = layui.jquery;
|
||||
var helper = layui.helper;
|
||||
|
||||
/**
|
||||
* 咨询
|
||||
*/
|
||||
$('.icon-help').on('click', function () {
|
||||
var url = $(this).parent().data('url');
|
||||
helper.checkLogin(function () {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '课程咨询',
|
||||
content: [url, 'no'],
|
||||
area: ['640px', '300px']
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
@ -121,11 +121,6 @@ layui.use(['jquery', 'layer', 'helper'], function () {
|
||||
helper.ajaxLoadHtml($tabReviews.data('url'), $tabReviews.attr('id'));
|
||||
}
|
||||
|
||||
if ($('#sidebar-teachers').length > 0) {
|
||||
var $sdTeachers = $('#sidebar-teachers');
|
||||
helper.ajaxLoadHtml($sdTeachers.data('url'), $sdTeachers.attr('id'));
|
||||
}
|
||||
|
||||
if ($('#sidebar-topics').length > 0) {
|
||||
var $sdTopics = $('#sidebar-topics');
|
||||
helper.ajaxLoadHtml($sdTopics.data('url'), $sdTopics.attr('id'));
|
||||
|
@ -40,9 +40,6 @@ $scheduler->php($script, $bin, ['--task' => 'sync_course_counter', '--action' =>
|
||||
$scheduler->php($script, $bin, ['--task' => 'sync_chapter_counter', '--action' => 'main'])
|
||||
->hourly(17);
|
||||
|
||||
$scheduler->php($script, $bin, ['--task' => 'sync_comment_counter', '--action' => 'main'])
|
||||
->hourly(19);
|
||||
|
||||
$scheduler->php($script, $bin, ['--task' => 'sync_consult_counter', '--action' => 'main'])
|
||||
->hourly(23);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user