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

整理前端代码

This commit is contained in:
xiaochong0302 2020-05-27 18:25:42 +08:00
parent 2450d70fdc
commit abdb4e1584
21 changed files with 427 additions and 118 deletions

View File

@ -45,6 +45,7 @@ class CoursePackageList extends Cache
$result[] = [
'id' => $package->id,
'title' => $package->title,
'course_count' => $package->course_count,
'market_price' => $package->market_price,
'vip_price' => $package->vip_price,
];

View File

@ -52,16 +52,17 @@ class SyncChapterCounterTask extends Task
$hour = date('H');
$recount = $this->checkEnableRecount();
foreach ($chapters as $chapter) {
if ($hour % 3 == 0) {
if ($recount && $hour % 3 == 0) {
$chapter->user_count = $chapterRepo->countUsers($chapter->id);
$chapter->lesson_count = $chapterRepo->countLessons($chapter->id);
$chapter->comment_count = $chapterRepo->countComments($chapter->id);
$chapter->agree_count = $chapterRepo->countAgrees($chapter->id);
$chapter->oppose_count = $chapterRepo->countOpposes($chapter->id);
$chapter->update();
$counterCache->rebuild($chapter->id);
@ -78,7 +79,6 @@ class SyncChapterCounterTask extends Task
$chapter->comment_count = $counter['comment_count'];
$chapter->agree_count = $counter['agree_count'];
$chapter->oppose_count = $counter['oppose_count'];
$chapter->update();
$chapterCache->rebuild($chapter->id);
@ -96,4 +96,11 @@ class SyncChapterCounterTask extends Task
return $syncer->getSyncKey();
}
protected function checkEnableRecount()
{
$config = $this->getDI()->get('config');
return $config['recount_chapter'] ?? false;
}
}

View File

@ -49,14 +49,15 @@ class SyncCommentCounterTask extends Task
$hour = date('H');
$recount = $this->checkEnableRecount();
foreach ($comments as $comment) {
if ($hour % 3 == 0) {
if ($recount && $hour % 3 == 0) {
$comment->reply_count = $commentRepo->countReplies($comment->id);
$comment->agree_count = $commentRepo->countAgrees($comment->id);
$comment->oppose_count = $commentRepo->countOpposes($comment->id);
$comment->update();
$counterCache->rebuild($comment->id);
@ -66,11 +67,9 @@ class SyncCommentCounterTask extends Task
$counter = $counterCache->get($comment->id);
if ($counter) {
$comment->reply_count = $counter['reply_count'];
$comment->agree_count = $counter['agree_count'];
$comment->oppose_count = $counter['oppose_count'];
$comment->update();
}
}
@ -86,4 +85,11 @@ class SyncCommentCounterTask extends Task
return $syncer->getSyncKey();
}
protected function checkEnableRecount()
{
$config = $this->getDI()->get('config');
return $config['recount_comment'] ?? false;
}
}

View File

@ -49,13 +49,14 @@ class SyncConsultCounterTask extends Task
$hour = date('H');
$recount = $this->checkEnableRecount();
foreach ($consults as $consult) {
if ($hour % 3 == 0) {
if ($recount && $hour % 3 == 0) {
$consult->agree_count = $consultRepo->countAgrees($consult->id);
$consult->oppose_count = $consultRepo->countOpposes($consult->id);
$consult->update();
$counterCache->rebuild($consult->id);
@ -65,10 +66,8 @@ class SyncConsultCounterTask extends Task
$counter = $counterCache->get($consult->id);
if ($counter) {
$consult->agree_count = $counter['agree_count'];
$consult->oppose_count = $counter['oppose_count'];
$consult->update();
}
}
@ -84,4 +83,11 @@ class SyncConsultCounterTask extends Task
return $syncer->getSyncKey();
}
protected function checkEnableRecount()
{
$config = $this->getDI()->get('config');
return $config['recount_consult'] ?? false;
}
}

View File

@ -52,9 +52,11 @@ class SyncCourseCounterTask extends Task
$hour = date('H');
$recount = $this->checkEnableRecount();
foreach ($courses as $course) {
if ($hour % 3 == 0) {
if ($recount && $hour % 3 == 0) {
$course->user_count = $courseRepo->countUsers($course->id);
$course->lesson_count = $courseRepo->countLessons($course->id);
@ -62,7 +64,6 @@ class SyncCourseCounterTask extends Task
$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);
@ -73,14 +74,12 @@ class SyncCourseCounterTask extends Task
$counter = $counterCache->get($course->id);
if ($counter) {
$course->user_count = $counter['user_count'];
$course->lesson_count = $counter['lesson_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();
}
}
@ -96,4 +95,11 @@ class SyncCourseCounterTask extends Task
return $syncer->getSyncKey();
}
protected function checkEnableRecount()
{
$config = $this->getDI()->get('config');
return $config['recount_course'] ?? false;
}
}

View File

@ -49,13 +49,14 @@ class SyncReviewCounterTask extends Task
$hour = date('H');
$recount = $this->checkEnableRecount();
foreach ($reviews as $review) {
if ($hour % 3 == 0) {
if ($recount && $hour % 3 == 0) {
$review->agree_count = $reviewRepo->countAgrees($review->id);
$review->oppose_count = $reviewRepo->countOpposes($review->id);
$review->update();
$counterCache->rebuild($review->id);
@ -65,10 +66,8 @@ class SyncReviewCounterTask extends Task
$counter = $counterCache->get($review->id);
if ($counter) {
$review->agree_count = $counter['agree_count'];
$review->oppose_count = $counter['oppose_count'];
$review->update();
}
}
@ -84,4 +83,11 @@ class SyncReviewCounterTask extends Task
return $syncer->getSyncKey();
}
protected function checkEnableRecount()
{
$config = $this->getDI()->get('config');
return $config['recount_review'] ?? false;
}
}

View File

@ -1,28 +0,0 @@
{%- macro lesson_info(lesson) %}
{% set url = lesson.me.owned ? url({'for':'web.chapter.show','id':lesson.id}) : 'javascript:' %}
{% set free_badge = lesson.free ? '<span class="layui-badge">免费</span>' : '' %}
{% if lesson.attrs.model == 'vod' %}
<a href="{{ url }}"><i class="layui-icon layui-icon-play"></i> {{ lesson.title }} {{ free_badge }}</a>
{% elseif lesson.attrs.model == 'live' %}
<a href="{{ url }}"><i class="layui-icon layui-icon-video"></i> {{ lesson.title }} {{ free_badge }}</a>
{% elseif lesson.attrs.model == 'read' %}
<a href="{{ url }}"><i class="layui-icon layui-icon-note"></i> {{ lesson.title }} {{ free_badge }}</a>
{% endif %}
{%- endmacro %}
<div class="layui-collapse">
{% for chapter in chapters %}
<div class="layui-colla-item">
<h2 class="layui-colla-title">{{ chapter.title }}</h2>
<div class="layui-colla-content layui-show">
<ul class="lesson-list">
{% for lesson in chapter.children %}
<li>{{ lesson_info(lesson) }}</li>
{% endfor %}
</ul>
</div>
</div>
{% endfor %}
</div>

View File

@ -0,0 +1,33 @@
{%- macro live_lesson_info(lesson) %}
{% set url = lesson.me.owned ? url({'for':'web.chapter.show','id':lesson.id}) : 'javascript:' %}
{% set over_flag = lesson.attrs.end_time < time() ? '已结束' : '' %}
<a href="{{ url }}">
<i class="layui-icon layui-icon-video"></i>
<span class="title">{{ lesson.title }}</span>
{% if lesson.free == 1 %}
<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>
{% 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>
{%- endmacro %}
<div class="layui-collapse">
{% for chapter in chapters %}
<div class="layui-colla-item">
<h2 class="layui-colla-title">{{ chapter.title }}</h2>
<div class="layui-colla-content layui-show">
<ul class="lesson-list">
{% for lesson in chapter.children %}
<li class="lesson-item">{{ live_lesson_info(lesson) }}</li>
{% endfor %}
</ul>
</div>
</div>
{% endfor %}
</div>

View File

@ -0,0 +1,31 @@
{%- macro read_lesson_info(lesson) %}
{% set url = lesson.me.owned ? url({'for':'web.chapter.show','id':lesson.id}) : 'javascript:' %}
<a href="{{ url }}">
<i class="layui-icon layui-icon-read"></i>
<span class="title">{{ lesson.title|e }}</span>
{% if lesson.free == 1 %}
<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>
{% endif %}
</a>
{%- endmacro %}
<div class="layui-collapse">
{% for chapter in chapters %}
<div class="layui-colla-item">
<h2 class="layui-colla-title">{{ chapter.title|e }}</h2>
<div class="layui-colla-content layui-show">
<ul class="lesson-list">
{% for lesson in chapter.children %}
<li class="lesson-item">{{ read_lesson_info(lesson) }}</li>
{% endfor %}
</ul>
</div>
</div>
{% endfor %}
</div>

View File

@ -0,0 +1,32 @@
{%- macro vod_lesson_info(lesson) %}
{% set url = lesson.me.owned ? url({'for':'web.chapter.show','id':lesson.id}) : 'javascript:' %}
<a href="{{ url }}">
<i class="layui-icon layui-icon-play"></i>
<span class="title">{{ lesson.title }}</span>
{% if lesson.free == 1 %}
<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>
{% endif %}
<span class="duration">{{ lesson.attrs.duration|total_duration }}</span>
</a>
{%- endmacro %}
<div class="layui-collapse">
{% for chapter in chapters %}
<div class="layui-colla-item">
<h2 class="layui-colla-title">{{ chapter.title }}</h2>
<div class="layui-colla-content layui-show">
<ul class="lesson-list">
{% for lesson in chapter.children %}
<li class="lesson-item clearfix">{{ vod_lesson_info(lesson) }}</li>
{% endfor %}
</ul>
</div>
</div>
{% endfor %}
</div>

View File

@ -0,0 +1,20 @@
<div class="cover">
<img src="{{ course.cover }}" alt="{{ course.summary|e }}">
</div>
<div class="info">
<p class="duration">课程时长:{{ course.attrs.duration|total_duration }}</p>
<p class="expiry">
<span class="study-expiry">学习期限:<span class="layui-badge-rim">{{ course.study_expiry }}个月</span></span>
<span class="refund-expiry">退款期限:<span class="layui-badge-rim">{{ course.refund_expiry }}天</span></span>
</p>
<p class="price">
<span class="market-price">市场价格:<span class="layui-badge-rim">¥{{ course.market_price }}</span></span>
<span class="vip-price">会员价格:<span class="layui-badge-rim">¥{{ course.vip_price }}</span></span>
</p>
<p class="stats">
<span class="user-count">{{ course.user_count }}次学习</span>
<span class="review-count">{{ course.review_count }}次评价</span>
<span class="favorite-count">{{ course.favorite_count }}次收藏</span>
</p>
</div>

View File

@ -0,0 +1,30 @@
<div class="package-list">
{% for package in packages %}
{% set order_url = url({'for':'web.order.confirm'},{'item_id':package.id,'item_type':'package'}) %}
<div class="package-item clearfix">
<div class="package-info">
<div class="title">{{ package.title }}</div>
<div class="origin-price">
<span>{{ package.course_count }} 门课程</span>
<span>总价 <i>¥{{ package.origin_price }}</i></span>
</div>
<div class="price">
<span>市场价 <i>¥{{ package.market_price }}</i></span>
<span>会员价 <i>¥{{ package.vip_price }}</i></span>
</div>
<div class="order">
<a class="layui-btn layui-btn-sm" href="{{ order_url }}">立即购买</a>
</div>
</div>
<div class="package-course-list">
{% for course in package.courses %}
{% set course_url = url({'for':'web.course.show','id':course.id}) %}
<div class="package-course-card">
<div class="cover"><img src="{{ course.cover }}!cover_270" alt="{{ course.title }}"></div>
<div class="title"><a href="{{ course_url }}">{{ course.title }}</a></div>
</div>
{% endfor %}
</div>
</div>
{% endfor %}
</div>

View File

@ -2,6 +2,8 @@
{% block content %}
{{ partial('partials/macro_course') }}
<div class="breadcrumb">
<span class="layui-breadcrumb">
<a href="{{ url({'for':'web.course.list'}) }}">全部课程</a>
@ -12,26 +14,52 @@
</span>
</div>
<div class="layout-main clearfix">
<div class="layout-content">
<div class="course-meta">
<div class="left"></div>
<div class="right"></div>
<div class="course-meta module clearfix">
{{ partial('course/meta') }}
</div>
{% set show_packages = packages ? 1 : 0 %}
{% set show_consults = course.market_price > 0 ? 1 : 0 %}
{% set show_reviews = course.market_price > 0 ? 1 : 0 %}
<div class="layout-main clearfix">
<div class="layout-content module">
<div class="layui-tab layui-tab-brief course-info-tab">
<ul class="layui-tab-title">
<li class="layui-this">详情</li>
<li>目录</li>
{% if show_packages == 1 %}
<li>套餐</li>
{% endif %}
{% if show_consults == 1 %}
<li>咨询</li>
{% endif %}
{% if show_reviews == 1 %}
<li>评价</li>
{% endif %}
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<div class="course-details">{{ course.details }}</div>
</div>
<div class="layui-tab-item">
{{ partial('course/chapters', {'chapters':chapters}) }}
{% if course.model == 'vod' %}
{{ partial('course/chapters_vod') }}
{% elseif course.model == 'live' %}
{{ partial('course/chapters_live') }}
{% elseif course.model == 'read' %}
{{ partial('course/chapters_read') }}
{% endif %}
</div>
<div class="layui-tab-item">内容3</div>
{% if show_packages == 1 %}
<div class="layui-tab-item">{{ partial('course/packages') }}</div>
{% endif %}
{% if show_consults == 1 %}
<div class="layui-tab-item">咨询</div>
{% endif %}
{% if show_reviews == 1 %}
<div class="layui-tab-item">评价</div>
{% endif %}
</div>
</div>
</div>

View File

@ -2,22 +2,7 @@
<div class="layui-card-header">推荐课程</div>
<div class="layui-card-body">
{% for course in recommended_courses %}
{% set url = url({'for':'web.course.show','id':course.id}) %}
<div class="sidebar-course-card clearfix">
<div class="cover">
<img src="{{ course.cover }}!cover_270" alt="{{ course.title }}">
</div>
<div class="info">
<div class="title">
<a href="{{ url }}" title="{{ course.title }}">{{ substr(course.title,0,15) }}</a>
</div>
<div class="meta">
<span class="price">¥{{ course.market_price }}</span>
<span class="level">中级</span>
<span class="user">{{ course.user_count }}</span>
</div>
</div>
</div>
{{ sidebar_course_card(course) }}
{% endfor %}
</div>
</div>

View File

@ -2,22 +2,7 @@
<div class="layui-card-header">相关课程</div>
<div class="layui-card-body">
{% for course in related_courses %}
{% set url = url({'for':'web.course.show','id':course.id}) %}
<div class="sidebar-course-card clearfix">
<div class="cover">
<img src="{{ course.cover }}!cover_270" alt="{{ course.title }}">
</div>
<div class="info">
<div class="title">
<a href="{{ url }}" title="{{ course.title }}">{{ substr(course.title,0,15) }}</a>
</div>
<div class="meta">
<span class="price">¥{{ course.market_price }}</span>
<span class="level">中级</span>
<span class="user">{{ course.user_count }}</span>
</div>
</div>
</div>
{{ sidebar_course_card(course) }}
{% endfor %}
</div>
</div>

View File

@ -21,14 +21,15 @@
{%- endmacro %}
{%- macro course_card(course) %}
{% set course_url = url({'for':'web.course.show','id':course.id}) %}
<div class="course-card">
<div class="cover">
<a href="{{ url({'for':'web.course.show','id':course.id}) }}">
<a href="{{ course_url }}">
<img src="{{ course.cover }}!cover_270" alt="{{ course.title }}">
</a>
</div>
<div class="title">
<a href="{{ url({'for':'web.course.show','id':course.id}) }}">{{ substr(course.title,0,15) }}</a>
<a href="{{ course_url }}">{{ substr(course.title,0,15) }}</a>
</div>
<div class="meta">
{% if course.market_price > 0 %}
@ -45,3 +46,28 @@
</div>
</div>
{%- endmacro %}
{%- macro sidebar_course_card(course) %}
{% set course_url = url({'for':'web.course.show','id':course.id}) %}
<div class="sidebar-course-card clearfix">
<div class="cover">
<img src="{{ course.cover }}!cover_270" alt="{{ course.title }}">
</div>
<div class="info">
<div class="title">
<a href="{{ course_url }}" title="{{ course.title }}">{{ substr(course.title,0,15) }}</a>
</div>
<div class="meta">
{% if course.market_price > 0 %}
<span class="price">¥{{ course.market_price }}</span>
<span class="level">{{ level_info(course.level) }}</span>
<span class="user">{{ course.user_count }}人购买</span>
{% else %}
<span class="free">免费</span>
<span class="level">{{ level_info(course.level) }}</span>
<span class="user">{{ course.user_count }}人报名</span>
{% endif %}
</div>
</div>
</div>
{%- endmacro %}

View File

@ -13,7 +13,7 @@
</div>
<div class="layout-main clearfix">
<div class="layout-content">
<div class="layout-content module">
{% if type == 'course' %}
{{ partial('search/content_course') }}
{% elseif type == 'other' %}

View File

@ -267,11 +267,11 @@ function kg_total_duration($time)
$format = [];
if ($hours >= 0) {
if ($hours > 0) {
$format[] = sprintf('%02d小时', $hours);
}
if ($minutes >= 0) {
if ($minutes > 0) {
$format[] = sprintf('%02d分钟', $minutes);
}

View File

@ -41,6 +41,7 @@ class ChapterList extends FrontendService
$lesson['me'] = [
'owned' => $this->ownedCourse || $lesson['free'] ? 1 : 0,
'progress' => 0,
'duration' => 0,
];
}
}
@ -51,6 +52,7 @@ class ChapterList extends FrontendService
$lesson['me'] = [
'owned' => $this->ownedCourse || $lesson['free'] ? 1 : 0,
'progress' => $mappings[$lesson['id']]['progress'] ?? 0,
'duration' => $mappings[$lesson['id']]['duration'] ?? 0,
];
}
}
@ -74,6 +76,8 @@ class ChapterList extends FrontendService
foreach ($userLearnings as $learning) {
$mappings[$learning['chapter_id']] = [
'progress' => $learning['progress'],
'duration' => $learning['duration'],
'consumed' => $learning['consumed'],
];
}

View File

@ -32,7 +32,15 @@ class PackageList extends FrontendService
$courses = $cache->get($package['id']);
$package['courses'] = $courses ?: [];
$package['origin_price'] = 0.00;
$package['courses'] = [];
if ($courses) {
foreach ($courses as $course) {
$package['origin_price'] += $course['market_price'];
}
$package['courses'] = $courses;
}
$result[] = $package;
}

View File

@ -22,6 +22,14 @@ body {
float: right;
}
.bg-white {
background-color: #fff;
}
.layui-badge, .layui-badge-rim {
padding-bottom: 1px;
}
#header {
left: 0;
top: 0;
@ -88,15 +96,21 @@ body {
margin-bottom: 20px;
}
.module {
padding: 20px;
margin-bottom: 15px;
background-color: #fff;
border-radius: 2px;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
}
.pager {
text-align: center;
}
.layout-content {
float: left;
width: 730px;
padding: 30px;
background-color: #fff;
width: 760px;
}
.layout-sidebar {
@ -167,6 +181,12 @@ body {
border-bottom: 1px dashed #ccc;
}
.search-course-card:last-child {
padding-bottom: 0;
margin-bottom: 0;
border: none;
}
.search-course-card .cover {
float: left;
width: 210px;
@ -284,40 +304,147 @@ body {
margin-bottom: 20px;
}
.course-meta {
border: 1px dashed #ccc;
margin-bottom: 30px;
}
.course-meta .left {
.course-meta .cover {
float: left;
margin-right: 10px;
}
.course-meta .right {
float: right;
.course-meta .info {
float: left;
font-size: 12px;
}
.course-meta .cover img {
width: 210px;
height: 118px;
}
.course-meta p {
line-height: 30px;
}
.course-meta .stats span {
margin-right: 5px;
}
.course-info-tab {
margin: 0;
}
.course-info-tab .layui-tab-content {
padding-top: 30px;
padding: 20px 0;
}
ul.lesson-list {
}
.lesson-list li {
padding-left: 10px;
.lesson-item {
position: relative;
padding: 0 10px;
line-height: 40px;
}
.lesson-list li a {
.lesson-item a {
display: block;
}
.lesson-list li:hover {
.lesson-item .title {
margin: 0 5px;
}
.lesson-item .free-badge {
margin-right: 5px;
}
.lesson-item .duration, .lesson-item .live {
top: 0;
right: 10px;
position: absolute;
color: #999;
}
.lesson-item .study-time {
color: green;
}
.lesson-item:hover {
background-color: #f2f2f2;
}
.package-item {
margin-bottom: 15px;
border-bottom: 1px dashed #ccc;
}
.package-item:last-child {
padding-bottom: 0;
margin-bottom: 0;
border: none;
}
.package-info {
float: left;
width: 180px;
font-size: 12px;
text-align: center;
}
.package-info span {
margin-right: 5px;
}
.package-info .title {
margin-bottom: 10px;
}
.package-info .origin-price {
color: #999;
margin-bottom: 10px;
}
.package-info .origin-price i {
color: red;
font-style: normal;
text-decoration: line-through;
}
.package-info .price {
color: #999;
margin-bottom: 15px;
}
.package-info .price i {
color: red;
font-style: normal;
}
.package-course-list {
width: 580px;
height: 170px;
overflow-x: auto;
white-space: nowrap;
}
.package-course-card {
width: 180px;
display: inline-block;
margin-right: 10px;
vertical-align: top;
}
.package-course-card .cover {
width: 180px;
height: 96px;
margin-bottom: 10px;
}
.package-course-card .cover img {
width: 100%;
height: 100%;
}
.package-course-card .title {
font-size: 12px;
white-space: normal;
}
.sidebar-teacher-card {
margin-bottom: 15px;
}
@ -380,18 +507,14 @@ ul.lesson-list {
float: left;
width: 190px;
color: #999;
font-size: 12px;
overflow: hidden;
}
.sidebar-course-card .title {
font-size: 12px;
white-space: nowrap;
}
.sidebar-course-card .meta {
font-size: 10px;
}
.sidebar-course-card .meta span {
margin-right: 10px;
}