1
0
mirror of https://gitee.com/koogua/course-tencent-cloud.git synced 2025-06-29 13:51:37 +08:00

完成首页直播课程,新上课程,免费课程,会员课程缓存

This commit is contained in:
xiaochong0302 2020-04-28 19:07:59 +08:00
parent 7b26961b86
commit 25653b1cf7
25 changed files with 609 additions and 300 deletions

View File

@ -3,111 +3,56 @@
namespace App\Builders;
use App\Caches\CategoryList as CategoryListCache;
use App\Repos\CourseCategory as CourseCategoryRepo;
use App\Repos\User as UserRepo;
class CourseList extends Builder
{
public function handleCourses($courses)
{
$baseUrl = kg_ci_base_url();
$list = [];
foreach ($courses as $course) {
$course['categories'] = [];
$course['cover'] = $baseUrl . $course['cover'];
$course['attrs'] = json_decode($course['attrs'], true);
$result[] = [
'id' => $course['id'],
'title' => $course['title'],
'cover' => $course['cover'],
'summary' => $course['summary'],
'categories' => $course['categories'],
'market_price' => (float)$course['market_price'],
'vip_price' => (float)$course['vip_price'],
'study_expiry' => $course->study_expiry,
'refund_expiry' => $course->refund_expiry,
'rating' => (float)$course['rating'],
'score' => (float)$course['score'],
'model' => $course['model'],
'level' => $course['level'],
'attrs' => $course['attrs'],
'user_count' => $course['user_count'],
'lesson_count' => $course['lesson_count'],
'comment_count' => $course['comment_count'],
'review_count' => $course['review_count'],
'favorite_count' => $course['favorite_count'],
];
}
return $list;
}
public function handleCategories($courses)
{
$categories = $this->getCategories($courses);
$categories = $this->getCategories();
foreach ($courses as $key => $course) {
$courses[$key]['categories'] = $categories[$course['id']] ?? [];
$courses[$key]['category'] = $categories[$course['category_id']] ?? [];
}
return $courses;
}
public function handleUsers($courses)
public function handleTeachers($courses)
{
$users = $this->getUsers($courses);
$teachers = $this->getTeachers($courses);
foreach ($courses as $key => $course) {
$courses[$key]['user'] = $users[$course['user_id']] ?? [];
$courses[$key]['teacher'] = $teachers[$course['teacher_id']] ?? [];
}
return $courses;
}
protected function getCategories($courses)
protected function getCategories()
{
$categoryListCache = new CategoryListCache();
$cache = new CategoryListCache();
$categoryList = $categoryListCache->get();
$items = $cache->get();
if (!$categoryList) {
return [];
}
$mapping = [];
foreach ($categoryList as $category) {
$mapping[$category['id']] = [
'id' => $category['id'],
'name' => $category['name'],
];
}
$courseIds = kg_array_column($courses, 'id');
$courseCategoryRepo = new CourseCategoryRepo();
$relations = $courseCategoryRepo->findByCourseIds($courseIds);
if (!$items) return null;
$result = [];
foreach ($relations as $relation) {
$categoryId = $relation->category_id;
$courseId = $relation->course_id;
$result[$courseId][] = $mapping[$categoryId] ?? [];
foreach ($items as $item) {
$result[$item['id']] = [
'id' => $item['id'],
'name' => $item['name'],
];
}
return $result;
}
protected function getUsers($courses)
protected function getTeachers($courses)
{
$ids = kg_array_column($courses, 'user_id');
$ids = kg_array_column($courses, 'teacher_id');
$userRepo = new UserRepo();

View File

@ -47,7 +47,6 @@ class CourseRelatedList extends Cache
'id' => $course->id,
'title' => $course->title,
'cover' => $course->cover,
'summary' => $course->summary,
'market_price' => $course->market_price,
'vip_price' => $course->vip_price,
'rating' => $course->rating,

View File

@ -1,39 +0,0 @@
<?php
namespace App\Caches;
use App\Repos\CourseUser as CourseUserRepo;
class CourseUser extends Cache
{
protected $lifetime = 1 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
/**
* id = {$courseId}_{$userId}
*
* @param string $id
* @return string
*/
public function getKey($id = null)
{
return "course_user:{$id}";
}
public function getContent($id = null)
{
list($courseId, $userId) = explode('_', $id);
$courseUserRepo = new CourseUserRepo();
$courseUser = $courseUserRepo->findCourseUser($courseId, $userId);
return $courseUser ?: null;
}
}

View File

@ -1,72 +0,0 @@
<?php
namespace App\Caches;
use App\Models\Course as CourseModel;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
class HotCourseList extends Cache
{
protected $lifetime = 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'hot_course_list';
}
public function getContent($id = null)
{
$courses = $this->findHotCourses($id);
if ($courses->count() == 0) {
return [];
}
return $this->handleContent($courses);
}
/**
* @param CourseModel[] $courses
* @return array
*/
public function handleContent($courses)
{
$result = [];
foreach ($courses as $course) {
$result[] = [
'id' => $course->id,
'title' => $course->title,
'summary' => $course->summary,
'cover' => $course->cover,
'market_price' => $course->market_price,
'vip_price' => $course->vip_price,
'model' => $course->model,
'level' => $course->level,
];
}
return $result;
}
/**
* @param int $limit
* @return ResultsetInterface|Resultset|CourseModel[]
*/
protected function findHotCourses($limit = 10)
{
return CourseModel::query()
->where('deleted = 0')
->orderBy('score DESC')
->limit($limit)
->execute();
}
}

View File

@ -0,0 +1,114 @@
<?php
namespace App\Caches;
use App\Models\Category as CategoryModel;
use App\Models\Course as CourseModel;
use App\Services\Category as CategoryService;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
/**
* 免费课程
*
* Class IndexNewbieCourseList
* @package App\Caches
*/
class IndexFreeCourseList extends Cache
{
protected $lifetime = 1 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'index_free_course_list';
}
public function getContent($id = null)
{
$result = [];
$categoryLimit = 5;
$courseLimit = 5;
$categories = $this->findCategories($categoryLimit);
if ($categories->count() == 0) {
return null;
}
foreach ($categories as $category) {
$categoryItem = [
'id' => $category->id,
'name' => $category->name,
];
$courses = $this->findCategoryCourses($category->id, $courseLimit);
if ($courses->count() == 0) continue;
$categoryCourses = [];
foreach ($courses as $course) {
$categoryCourses[] = [
'id' => $course->id,
'title' => $course->title,
'cover' => $course->cover,
'market_price' => $course->market_price,
'vip_price' => $course->vip_price,
'model' => $course->model,
'level' => $course->level,
'user_count' => $course->user_count,
'lesson_count' => $course->lesson_count,
];
}
$categoryItem['courses'] = $categoryCourses;
$result[] = $categoryItem;
}
return $result;
}
/**
* @param int $limit
* @return ResultsetInterface|Resultset|CategoryModel[]
*/
protected function findCategories($limit = 5)
{
return CategoryModel::query()
->andWhere('published = 1')
->orderBy('priority ASC')
->limit($limit)
->execute();
}
/**
* @param int $categoryId
* @param int $limit
* @return ResultsetInterface|Resultset|CourseModel[]
*/
protected function findCategoryCourses($categoryId, $limit = 10)
{
$categoryService = new CategoryService();
$categoryIds = $categoryService->getChildCategoryIds($categoryId);
return CourseModel::query()
->inWhere('category_id', $categoryIds)
->andWhere('published = 1')
->andWhere('market_price = 0')
->orderBy('id DESC')
->limit($limit)
->execute();
}
}

View File

@ -2,7 +2,7 @@
namespace App\Caches;
class HotTeacherList extends Cache
class IndexHotTeacherList extends Cache
{
protected $lifetime = 365 * 86400;

View File

@ -0,0 +1,141 @@
<?php
namespace App\Caches;
use App\Models\ChapterLive as ChapterLiveModel;
use App\Repos\Chapter as ChapterRepo;
use App\Repos\Course as CourseRepo;
use App\Repos\User as UserRepo;
use Phalcon\Mvc\Model\Resultset;
/**
* 直播课程
*
* Class IndexLiveCourseList
* @package App\Caches
*/
class IndexLiveCourseList extends Cache
{
protected $lifetime = 1 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'index_live_course_list';
}
public function getContent($id = null)
{
/**
* 限制输出多少天数(一维限额)
*/
$dayLimit = 3;
/**
* 限制每天维度下的输出数(二维限额)
*/
$perDayLimit = 5;
$beginTime = strtotime('today');
$endTime = strtotime("+30 days");
$result = [];
/**
* @var Resultset|ChapterLiveModel[] $lives
*/
$lives = ChapterLiveModel::query()
->betweenWhere('start_time', $beginTime, $endTime)
->orderBy('start_time ASC')
->execute();
if ($lives->count() == 0) {
return $result;
}
$chapterIds = kg_array_column($lives->toArray(), 'chapter_id');
$chapterRepo = new ChapterRepo();
$chapters = $chapterRepo->findByIds($chapterIds);
$chapterMappings = [];
foreach ($chapters as $chapter) {
$chapterMappings[$chapter->id] = $chapter;
}
$courseIds = kg_array_column($lives->toArray(), 'course_id');
$courseRepo = new CourseRepo();
$courses = $courseRepo->findByIds($courseIds);
$courseMappings = [];
foreach ($courses as $course) {
$courseMappings[$course->id] = $course;
}
$teacherIds = kg_array_column($courses->toArray(), 'teacher_id');
$userRepo = new UserRepo();
$teachers = $userRepo->findByIds($teacherIds);
$teacherMappings = [];
foreach ($teachers as $teacher) {
$teacherMappings[$teacher->id] = $teacher;
}
foreach ($lives as $live) {
if (count($result) >= $dayLimit) {
break;
}
$day = date('y-m-d', $live->start_time);
if (isset($result[$day]) && count($result[$day]) >= $perDayLimit) {
continue;
}
$chapter = $chapterMappings[$live->chapter_id];
$course = $courseMappings[$chapter->course_id];
$teacher = $teacherMappings[$course->teacher_id];
$chapterInfo = [
'id' => $chapter->id,
'title' => $chapter->title,
];
$courseInfo = [
'id' => $course->id,
'title' => $course->title,
'cover' => $course->cover,
];
$teacherInfo = [
'id' => $teacher->id,
'name' => $teacher->name,
'avatar' => $teacher->avatar,
];
$result[$day][] = [
'course' => $courseInfo,
'chapter' => $chapterInfo,
'teacher' => $teacherInfo,
'start_time' => $live->start_time,
];
}
return $result;
}
}

View File

@ -0,0 +1,113 @@
<?php
namespace App\Caches;
use App\Models\Category as CategoryModel;
use App\Models\Course as CourseModel;
use App\Services\Category as CategoryService;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
/**
* 新上课程
*
* Class IndexLatestCourseList
* @package App\Caches
*/
class IndexNewCourseList extends Cache
{
protected $lifetime = 1 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'index_new_course_list';
}
public function getContent($id = null)
{
$result = [];
$categoryLimit = 5;
$courseLimit = 5;
$categories = $this->findCategories($categoryLimit);
if ($categories->count() == 0) {
return null;
}
foreach ($categories as $category) {
$categoryItem = [
'id' => $category->id,
'name' => $category->name,
];
$courses = $this->findCategoryCourses($category->id, $courseLimit);
if ($courses->count() == 0) continue;
$categoryCourses = [];
foreach ($courses as $course) {
$categoryCourses[] = [
'id' => $course->id,
'title' => $course->title,
'cover' => $course->cover,
'market_price' => $course->market_price,
'vip_price' => $course->vip_price,
'model' => $course->model,
'level' => $course->level,
'user_count' => $course->user_count,
'lesson_count' => $course->lesson_count,
];
}
$categoryItem['courses'] = $categoryCourses;
$result[] = $categoryItem;
}
return $result;
}
/**
* @param int $limit
* @return ResultsetInterface|Resultset|CategoryModel[]
*/
protected function findCategories($limit = 5)
{
return CategoryModel::query()
->andWhere('published = 1')
->orderBy('priority ASC')
->limit($limit)
->execute();
}
/**
* @param int $categoryId
* @param int $limit
* @return ResultsetInterface|Resultset|CourseModel[]
*/
protected function findCategoryCourses($categoryId, $limit = 10)
{
$categoryService = new CategoryService();
$categoryIds = $categoryService->getChildCategoryIds($categoryId);
return CourseModel::query()
->inWhere('category_id', $categoryIds)
->andWhere('published = 1')
->orderBy('id DESC')
->limit($limit)
->execute();
}
}

View File

@ -0,0 +1,114 @@
<?php
namespace App\Caches;
use App\Models\Category as CategoryModel;
use App\Models\Course as CourseModel;
use App\Services\Category as CategoryService;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
/**
* 会员特价课程
*
* Class IndexNewbieCourseList
* @package App\Caches
*/
class IndexVipCourseList extends Cache
{
protected $lifetime = 1 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'index_vip_course_list';
}
public function getContent($id = null)
{
$result = [];
$categoryLimit = 5;
$courseLimit = 5;
$categories = $this->findCategories($categoryLimit);
if ($categories->count() == 0) {
return null;
}
foreach ($categories as $category) {
$categoryItem = [
'id' => $category->id,
'name' => $category->name,
];
$courses = $this->findCategoryCourses($category->id, $courseLimit);
if ($courses->count() == 0) continue;
$categoryCourses = [];
foreach ($courses as $course) {
$categoryCourses[] = [
'id' => $course->id,
'title' => $course->title,
'cover' => $course->cover,
'market_price' => $course->market_price,
'vip_price' => $course->vip_price,
'model' => $course->model,
'level' => $course->level,
'user_count' => $course->user_count,
'lesson_count' => $course->lesson_count,
];
}
$categoryItem['courses'] = $categoryCourses;
$result[] = $categoryItem;
}
return $result;
}
/**
* @param int $limit
* @return ResultsetInterface|Resultset|CategoryModel[]
*/
protected function findCategories($limit = 5)
{
return CategoryModel::query()
->andWhere('published = 1')
->orderBy('priority ASC')
->limit($limit)
->execute();
}
/**
* @param int $categoryId
* @param int $limit
* @return ResultsetInterface|Resultset|CourseModel[]
*/
protected function findCategoryCourses($categoryId, $limit = 10)
{
$categoryService = new CategoryService();
$categoryIds = $categoryService->getChildCategoryIds($categoryId);
return CourseModel::query()
->inWhere('category_id', $categoryIds)
->andWhere('published = 1')
->andWhere('vip_price >= 0')
->orderBy('id DESC')
->limit($limit)
->execute();
}
}

View File

@ -1,77 +0,0 @@
<?php
namespace App\Caches;
use App\Models\Course as CourseModel;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
class LatestCourseList extends Cache
{
protected $lifetime = 7 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'latest_course_list';
}
public function getContent($id = null)
{
$courses = $this->findLatestCourses(5);
if ($courses->count() == 0) {
return [];
}
return $this->handleContent($courses);
}
/**
* @param CourseModel[] $courses
* @return array
*/
public function handleContent($courses)
{
$result = [];
$baseUrl = kg_ci_base_url();
foreach ($courses as $course) {
$course->cover = $baseUrl . $course->cover;
$result[] = [
'id' => $course->id,
'title' => $course->title,
'summary' => $course->summary,
'cover' => $course->cover,
'market_price' => $course->market_price,
'vip_price' => $course->vip_price,
'model' => $course->model,
'level' => $course->level,
];
}
return $result;
}
/**
* @param int $limit
* @return ResultsetInterface|Resultset|CourseModel[]
*/
protected function findLatestCourses($limit = 10)
{
return CourseModel::query()
->where('deleted = 0')
->orderBy('create_time DESC')
->limit($limit)
->execute();
}
}

View File

@ -46,7 +46,6 @@ class PackageCourseList extends Cache
'id' => $course->id,
'title' => $course->title,
'cover' => $course->cover,
'summary' => $course->summary,
'market_price' => $course->market_price,
'vip_price' => $course->vip_price,
'rating' => $course->rating,

View File

@ -46,7 +46,6 @@ class TopicCourseList extends Cache
'id' => $course->id,
'title' => $course->title,
'cover' => $course->cover,
'summary' => $course->summary,
'market_price' => $course->market_price,
'vip_price' => $course->vip_price,
'rating' => $course->rating,

View File

@ -2,6 +2,7 @@
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;
@ -45,11 +46,13 @@ class SyncChapterCounterTask extends Task
return;
}
$cache = new ChapterCounterCache();
$chapterCache = new ChapterCache();
$chapterCounterCache = new ChapterCounterCache();
foreach ($chapters as $chapter) {
$counter = $cache->get($chapter->id);
$counter = $chapterCounterCache->get($chapter->id);
if ($counter) {
@ -60,6 +63,8 @@ class SyncChapterCounterTask extends Task
$chapter->oppose_count = $counter['oppose_count'];
$chapter->update();
$chapterCache->rebuild($chapter->id);
}
}

View File

@ -2,6 +2,7 @@
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;
@ -45,11 +46,13 @@ class SyncCourseCounterTask extends Task
return;
}
$cache = new CourseCounterCache();
$courseCounterCache = new CourseCounterCache();
$courseCache = new CourseCache();
foreach ($courses as $course) {
$counter = $cache->get($course->id);
$counter = $courseCounterCache->get($course->id);
if ($counter) {
@ -61,6 +64,8 @@ class SyncCourseCounterTask extends Task
$course->favorite_count = $counter['favorite_count'];
$course->update();
$courseCache->rebuild($course->id);
}
}

View File

@ -18,8 +18,10 @@ class CourseController extends Controller
$courseService = new CourseService();
$xmCategories = $courseService->getXmCategories(0);
$xmTeachers = $courseService->getXmTeachers(0);
$this->view->setVar('xm_categories', $xmCategories);
$this->view->setVar('xm_teachers', $xmTeachers);
}
/**

View File

@ -44,13 +44,13 @@ class Chapter extends Service
$data['course_id'] = $course->id;
$data['title'] = $validator->checkTitle($post['title']);
$data['summary'] = $validator->checkSummary($post['summary']);
$data['free'] = $validator->checkFreeStatus($post['free']);
$chapterRepo = new ChapterRepo();
if (isset($post['parent_id'])) {
$parent = $validator->checkParent($post['parent_id']);
$data['parent_id'] = $parent->id;
$data['free'] = $validator->checkFreeStatus($post['free']);
$data['priority'] = $chapterRepo->maxLessonPriority($post['parent_id']);
} else {
$data['priority'] = $chapterRepo->maxChapterPriority($post['course_id']);

View File

@ -36,6 +36,11 @@ class Course extends Service
$params['category_id'] = count($xmCategoryIds) > 1 ? $xmCategoryIds : $xmCategoryIds[0];
}
if (!empty($params['xm_teacher_ids'])) {
$xmTeacherIds = explode(',', $params['xm_teacher_ids']);
$params['teacher_id'] = count($xmTeacherIds) > 1 ? $xmTeacherIds : $xmTeacherIds[0];
}
$params['deleted'] = $params['deleted'] ?? 0;
$sort = $pagerQuery->getSort();
@ -516,9 +521,10 @@ class Course extends Service
$pipeA = $pager->items->toArray();
$pipeB = $builder->handleCategories($pipeA);
$pipeC = $builder->objects($pipeB);
$pipeC = $builder->handleTeachers($pipeB);
$pipeD = $builder->objects($pipeC);
$pager->items = $pipeC;
$pager->items = $pipeD;
}
return $pager;

View File

@ -13,7 +13,7 @@
{% if course.cover %}
<img id="cover-img" class="kg-cover" src="{{ course.cover }}">
{% else %}
<img id="cover-img" class="kg-cover" src="{{ image('admin/img/default_cover.png') }}">
{{ image('id':'cover-img','class':'kg-cover','src':'admin/img/default_cover.png') }}
{% endif %}
<input type="hidden" name="cover" value="{{ course.cover }}">
</div>
@ -49,7 +49,7 @@
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<button class="layui-btn" lay-submit="true" lay-filter="go">提交</button>
<button class="layui-btn kg-submit" lay-submit="true" lay-filter="go">提交</button>
<button type="button" class="kg-back layui-btn layui-btn-primary">返回</button>
</div>
</div>
@ -85,4 +85,27 @@
data: {{ xm_teachers|json_encode }}
});
layui.use(['jquery', 'layer'], function () {
var $ = layui.jquery;
var layer = layui.layer;
$('.kg-submit').on('click', function () {
var xm_category_ids = $('input[name=xm_category_ids]');
var xm_teacher_ids = $('input[name=xm_teacher_ids]');
if (xm_category_ids.val() === '') {
layer.msg('请选择分类', {icon: 2});
return false;
}
if (xm_teacher_ids.val() === '') {
layer.msg('请选择讲师', {icon: 2});
return false;
}
});
})
</script>

View File

@ -66,7 +66,7 @@
form.on('radio(price-mode)', function (data) {
var priceBlock = $('#price-block');
if (data.value == 'free') {
if (data.value === 'free') {
priceBlock.hide();
} else {
priceBlock.show();

View File

@ -8,10 +8,16 @@
{% endif %}
{%- endmacro %}
{%- macro category_info(items) %}
{% for item in items %}
<a class="layui-badge layui-bg-green" href="{{ url({'for':'admin.course.list'},{'category_id':item.id}) }}">{{ item.name }}</a>
{% endfor %}
{%- macro category_info(category) %}
{% if category %}
分类:<a class="layui-badge layui-bg-gray" href="{{ url({'for':'admin.course.list'},{'category_id':category.id}) }}">{{ category.name }}</a>
{% endif %}
{%- endmacro %}
{%- macro teacher_info(teacher) %}
{% if teacher %}
讲师:<a class="layui-badge layui-bg-gray" href="{{ url({'for':'admin.course.list'},{'teacher_id':teacher.id}) }}">{{ teacher.name }}</a>
{% endif %}
{%- endmacro %}
<div class="kg-nav">
@ -54,7 +60,7 @@
<tr>
<td>
<p>标题:<a href="{{ url({'for':'admin.course.chapters','id':item.id}) }}">{{ item.title }}</a> {{ model_info(item.model) }}</p>
<p>分类:{{ category_info(item.categories) }}</p>
<p>{{ category_info(item.category) }}&nbsp;&nbsp;{{ teacher_info(item.teacher) }}</p>
</td>
<td>
<a href="{{ url({'for':'admin.course.chapters','id':item.id}) }}">

View File

@ -25,6 +25,13 @@
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">讲师</label>
<div class="layui-input-block">
<div id="xm-teacher-ids"></div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">模型</label>
<div class="layui-input-block">
@ -85,4 +92,15 @@
data: {{ xm_categories|json_encode }}
});
xmSelect.render({
el: '#xm-teacher-ids',
name: 'xm_teacher_ids',
max: 5,
prop: {
name: 'name',
value: 'id'
},
data: {{ xm_teachers|json_encode }}
});
</script>

View File

@ -20,7 +20,7 @@
{% if slide.cover %}
<img id="cover-img" class="kg-cover" src="{{ slide.cover }}">
{% else %}
<img id="cover-img" class="kg-cover" src="{{ image('admin/img/default_cover.png') }}">
{{ image('id':'cover-img','class':'kg-cover','src':'admin/img/default_cover.png') }}
{% endif %}
<input type="hidden" name="cover" value="{{ slide.cover }}">
</div>

View File

@ -38,7 +38,7 @@ class Volt extends Provider
return 'kg_js_include(' . $resolvedArgs . ')';
});
$compiler->addFunction('ci_image', function ($resolvedArgs) {
$compiler->addFunction('ci_img_url', function ($resolvedArgs) {
return 'kg_ci_img_url(' . $resolvedArgs . ')';
});

View File

@ -31,13 +31,16 @@ class Course extends Repository
$builder = $this->modelsManager->createBuilder();
if (!empty($where['category_id'])) {
$where['category_id'] = is_array($where['category_id']) ? $where['category_id'] : [$where['category_id']];
$builder->addFrom(CourseModel::class, 'c');
$builder->join(CourseCategoryModel::class, 'c.id = cc.course_id', 'cc');
if (is_array($where['category_id'])) {
$builder->inWhere('cc.category_id', $where['category_id']);
} else {
$builder->where('cc.category_id = :category_id:', ['category_id' => $where['category_id']]);
}
} elseif (!empty($where['teacher_id'])) {
$where['teacher_id'] = is_array($where['teacher_id']) ? $where['teacher_id'] : [$where['teacher_id']];
$builder->addFrom(CourseModel::class, 'c');
$builder->join(CourseUserModel::class, 'c.id = cu.course_id', 'cu');
$builder->inWhere('cu.user_id', $where['teacher_id']);
$builder->andWhere('cu.role_type = :role_type:', ['role_type' => CourseUserModel::ROLE_TEACHER]);
} else {
$builder->addFrom(CourseModel::class, 'c');
$builder->where('1 = 1');

View File

@ -19,7 +19,7 @@ class CourseInfo extends Service
public function getCourse($id)
{
$course = $this->checkCourse($id);
$course = $this->checkCourseCache($id);
$user = $this->getCurrentUser();
@ -49,6 +49,7 @@ class CourseInfo extends Service
'lesson_count' => $course->lesson_count,
'review_count' => $course->review_count,
'comment_count' => $course->comment_count,
'consult_count' => $course->consult_count,
'favorite_count' => $course->favorite_count,
];
@ -107,28 +108,32 @@ class CourseInfo extends Service
$chapters = $cache->get($course->id);
$learningMapping = $this->getLearningMapping($course, $user);
if ($user->id == 0) {
foreach ($chapters as &$chapter) {
foreach ($chapter['children'] as &$lesson) {
$owned = ($this->ownedCourse || $lesson['free']) ? 1 : 0;
$progress = $learningMapping[$lesson['id']]['progress'] ?? 0;
$lesson['me'] = [
'owned' => $owned,
'progress' => $progress,
'owned' => $this->ownedCourse || $lesson['free'] ? 1 : 0,
'progress' => 0,
];
}
}
} else {
$mapping = $this->getLearningMapping($course, $user);
foreach ($chapters as &$chapter) {
foreach ($chapter['children'] as &$lesson) {
$lesson['me'] = [
'owned' => $this->ownedCourse || $lesson['free'] ? 1 : 0,
'progress' => $mapping[$lesson['id']]['progress'] ?? 0,
];
}
}
}
return $chapters;
}
protected function getLearningMapping(CourseModel $course, UserModel $user)
{
if ($user->id == 0) {
return [];
}
$courseRepo = new CourseRepo();
$userLearnings = $courseRepo->findUserLearnings($course->id, $user->id);