mirror of
https://gitee.com/koogua/course-tencent-cloud.git
synced 2025-06-29 13:51:37 +08:00
完成首页直播课程,新上课程,免费课程,会员课程缓存
This commit is contained in:
parent
7b26961b86
commit
25653b1cf7
@ -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();
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
114
app/Caches/IndexFreeCourseList.php
Normal file
114
app/Caches/IndexFreeCourseList.php
Normal 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();
|
||||
}
|
||||
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Caches;
|
||||
|
||||
class HotTeacherList extends Cache
|
||||
class IndexHotTeacherList extends Cache
|
||||
{
|
||||
|
||||
protected $lifetime = 365 * 86400;
|
141
app/Caches/IndexLiveCourseList.php
Normal file
141
app/Caches/IndexLiveCourseList.php
Normal 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;
|
||||
}
|
||||
|
||||
}
|
113
app/Caches/IndexNewCourseList.php
Normal file
113
app/Caches/IndexNewCourseList.php
Normal 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();
|
||||
}
|
||||
|
||||
}
|
114
app/Caches/IndexVipCourseList.php
Normal file
114
app/Caches/IndexVipCourseList.php
Normal 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();
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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']);
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -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();
|
||||
|
@ -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) }} {{ teacher_info(item.teacher) }}</p>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ url({'for':'admin.course.chapters','id':item.id}) }}">
|
||||
|
@ -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>
|
@ -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>
|
||||
|
@ -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 . ')';
|
||||
});
|
||||
|
||||
|
@ -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');
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user