1
0
mirror of https://gitee.com/koogua/course-tencent-cloud.git synced 2025-06-27 21:10:24 +08:00

春节更新

This commit is contained in:
xiaochong0302 2020-01-30 16:49:48 +08:00
parent 8395074dde
commit aae4459fbe
332 changed files with 9583 additions and 4940 deletions

View File

@ -1,10 +1,10 @@
<?php
namespace App\Transformers;
namespace App\Builders;
use Phalcon\Mvc\User\Component as UserComponent;
class Transformer extends UserComponent
class Builder extends UserComponent
{
public function arrayToObject($array)

View File

@ -0,0 +1,44 @@
<?php
namespace App\Builders;
class CategoryList extends Builder
{
public function handleTreeList($categories)
{
$list = [];
foreach ($categories as $category) {
if ($category['parent_id'] == 0) {
$key = $category['id'];
$list[$key] = [
'id' => $category['id'],
'name' => $category['name'],
'priority' => $category['priority'],
'children' => [],
];
} else {
$key = $category['parent_id'];
$list[$key]['children'][] = [
'id' => $category['id'],
'name' => $category['name'],
'priority' => $category['priority'],
];
}
}
usort($list, function ($a, $b) {
return $a['priority'] > $b['priority'];
});
foreach ($list as $key => $value) {
usort($list[$key]['children'], function ($a, $b) {
return $a['priority'] > $b['priority'];
});
}
return $list;
}
}

19
app/Builders/Chapter.php Normal file
View File

@ -0,0 +1,19 @@
<?php
namespace App\Builders;
use App\Models\Chapter as ChapterModel;
class Chapter extends Builder
{
/**
* @param ChapterModel $chapter
* @return ChapterModel
*/
public function handleChapter(ChapterModel $chapter)
{
return $chapter;
}
}

View File

@ -0,0 +1,71 @@
<?php
namespace App\Builders;
use App\Models\Course as CourseModel;
class ChapterList extends Builder
{
/**
* @param array $chapters
* @return array
*/
public function handleTreeList($chapters)
{
$list = [];
foreach ($chapters as $chapter) {
if ($chapter['parent_id'] == 0) {
$key = $chapter['id'];
$list[$key] = [
'id' => $chapter['id'],
'title' => $chapter['title'],
'summary' => $chapter['summary'],
'priority' => $chapter['priority'],
'children' => [],
];
} else {
$key = $chapter['parent_id'];
$list[$key]['children'][] = $this->handleChapter($chapter);
}
}
usort($list, function ($a, $b) {
return $a['priority'] > $b['priority'];
});
foreach ($list as $key => $value) {
usort($list[$key]['children'], function ($a, $b) {
return $a['priority'] > $b['priority'];
});
}
return $list;
}
/**
* @param array $chapter
* @return array
*/
protected function handleChapter($chapter)
{
$attrs = json_decode($chapter['attrs'], true);
if ($attrs['model'] == CourseModel::MODEL_VOD) {
unset($attrs['file_id'], $attrs['file_status']);
}
$result = [
'id' => $chapter['id'],
'title' => $chapter['title'],
'summary' => $chapter['summary'],
'priority' => $chapter['priority'],
'free' => $chapter['free'],
'attrs' => $attrs,
];
return $result;
}
}

21
app/Builders/Course.php Normal file
View File

@ -0,0 +1,21 @@
<?php
namespace App\Builders;
use App\Models\Course as CourseModel;
class Course extends Builder
{
/**
* @param CourseModel $course
* @return CourseModel
*/
public function handleCourse(CourseModel $course)
{
$course->cover = kg_img_url($course->cover);
return $course;
}
}

View File

@ -0,0 +1,86 @@
<?php
namespace App\Builders;
use App\Models\Course as CourseModel;
class CourseChapterUser extends Builder
{
/**
* 处理课时进度
*
* @param array $chapters
* @param array $studyHistory
* @return array
*/
public function handleProcess($chapters, $studyHistory)
{
$status = [];
if ($studyHistory) {
foreach ($studyHistory as $value) {
$status[$value['chapter_id']] = [
'duration' => $value['duration'],
'finished' => $value['finished'],
];
}
}
foreach ($chapters as $key => $chapter) {
if ($chapter['parent_id'] > 0) {
$me = [
'duration' => $status[$chapter['id']]['duration'] ?? 0,
'finished' => $status[$chapter['id']]['finished'] ?? 0,
];
$chapters[$key]['me'] = $me;
}
}
return $chapters;
}
/**
* @param array $chapter
* @return array
*/
protected function handleChapter($chapter)
{
$attrs = json_decode($chapter['attrs'], true);
$me = $chapter['me'] ?? [];
$clickable = $chapter['published'];
if ($attrs['model'] == CourseModel::MODEL_VOD) {
unset($attrs['file_id'], $attrs['file_status']);
}
/**
* 直播前后半小时缓冲区间可用
*/
if ($attrs['model'] == CourseModel::MODEL_LIVE) {
$caseA = $attrs['start_time'] - time() < 1800;
$caseB = time() - $attrs['end_time'] < 1800;
if ($caseA && $caseB) {
$clickable = 1;
}
}
$result = [
'id' => $chapter['id'],
'title' => $chapter['title'],
'summary' => $chapter['summary'],
'free' => $chapter['free'],
'clickable' => $clickable,
'attrs' => $attrs,
'me' => $me,
];
return $result;
}
}

126
app/Builders/CourseList.php Normal file
View File

@ -0,0 +1,126 @@
<?php
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)
{
$imgBaseUrl = kg_img_base_url();
$result = [];
foreach ($courses as $course) {
$course['categories'] = [];
$course['cover'] = $imgBaseUrl . $course['cover'];
$course['attrs'] = json_decode($course['attrs'], true);
$result[] = [
'id' => $course['id'],
'model' => $course['model'],
'title' => $course['title'],
'summary' => $course['summary'],
'cover' => $course['cover'],
'market_price' => (float)$course['market_price'],
'vip_price' => (float)$course['vip_price'],
'expiry' => $course['expiry'],
'level' => $course['level'],
'score' => $course['score'],
'attrs' => $course['attrs'],
'categories' => $course['categories'],
'user_count' => $course['user_count'],
'lesson_count' => $course['lesson_count'],
'thread_count' => $course['thread_count'],
'review_count' => $course['review_count'],
'favorite_count' => $course['favorite_count'],
];
}
return $result;
}
public function handleCategories($courses)
{
$categories = $this->getCategories($courses);
foreach ($courses as $key => $course) {
$courses[$key]['categories'] = $categories[$course['id']] ?? [];
}
return $courses;
}
public function handleUsers($courses)
{
$users = $this->getUsers($courses);
foreach ($courses as $key => $course) {
$courses[$key]['user'] = $users[$course['user_id']] ?? [];
}
return $courses;
}
protected function getCategories($courses)
{
$categoryListCache = new CategoryListCache();
$categoryList = $categoryListCache->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);
$result = [];
foreach ($relations as $relation) {
$categoryId = $relation->category_id;
$courseId = $relation->course_id;
$result[$courseId][] = $mapping[$categoryId] ?? [];
}
return $result;
}
protected function getUsers($courses)
{
$ids = kg_array_column($courses, 'user_id');
$userRepo = new UserRepo();
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar']);
$imgBaseUrl = kg_img_base_url();
$result = [];
foreach ($users->toArray() as $user) {
$user['avatar'] = $imgBaseUrl . $user['avatar'];
$result[$user['id']] = $user;
}
return $result;
}
}

View File

@ -1,11 +1,11 @@
<?php
namespace App\Transformers;
namespace App\Builders;
use App\Repos\Course as CourseRepo;
use App\Repos\User as UserRepo;
class CourseUserList extends Transformer
class CourseUserList extends Builder
{
public function handleCourses($relations)

View File

@ -1,12 +1,12 @@
<?php
namespace App\Transformers;
namespace App\Builders;
use App\Repos\Chapter as ChapterRepo;
use App\Repos\Course as CourseRepo;
use App\Repos\User as UserRepo;
class LearningList extends Transformer
class LearningList extends Builder
{
public function handleCourses($relations)

46
app/Builders/NavList.php Normal file
View File

@ -0,0 +1,46 @@
<?php
namespace App\Builders;
class NavList extends Builder
{
public function handleTreeList($navs)
{
$list = [];
foreach ($navs as $nav) {
if ($nav['parent_id'] == 0) {
$key = $nav['id'];
$list[$key] = [
'id' => $nav['id'],
'name' => $nav['name'],
'priority' => $nav['priority'],
'children' => [],
];
} else {
$key = $nav['parent_id'];
$list[$key]['children'][] = [
'id' => $nav['id'],
'name' => $nav['name'],
'priority' => $nav['priority'],
'target' => $nav['target'],
'url' => $nav['url'],
];
}
}
usort($list, function ($a, $b) {
return $a['priority'] > $b['priority'];
});
foreach ($list as $key => $value) {
usort($list[$key]['children'], function ($a, $b) {
return $a['priority'] > $b['priority'];
});
}
return $list;
}
}

View File

@ -1,11 +1,11 @@
<?php
namespace App\Transformers;
namespace App\Builders;
use App\Models\Order as OrderModel;
use App\Repos\User as UserRepo;
class OrderList extends Transformer
class OrderList extends Builder
{
protected $imgBaseUrl;

View File

@ -1,10 +1,10 @@
<?php
namespace App\Transformers;
namespace App\Builders;
use App\Repos\User as UserRepo;
class RefundList extends Transformer
class RefundList extends Builder
{
public function handleUsers($refunds)
@ -24,11 +24,16 @@ class RefundList extends Transformer
$userRepo = new UserRepo();
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar'])->toArray();
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar']);
$result = [];
foreach ($users as $user) {
$imgBaseUrl = kg_img_base_url();
foreach ($users->toArray() as $user) {
$user['avatar'] = $imgBaseUrl . $user['avatar'];
$result[$user['id']] = $user;
}

View File

@ -1,11 +1,11 @@
<?php
namespace App\Transformers;
namespace App\Builders;
use App\Repos\Course as CourseRepo;
use App\Repos\User as UserRepo;
class ReviewList extends Transformer
class ReviewList extends Builder
{
public function handleCourses($reviews)
@ -13,7 +13,7 @@ class ReviewList extends Transformer
$courses = $this->getCourses($reviews);
foreach ($reviews as $key => $review) {
$reviews[$key]['course'] = $courses[$review['course_id']];
$reviews[$key]['course'] = $courses[$review['course_id']] ?? [];
}
return $reviews;
@ -24,7 +24,7 @@ class ReviewList extends Transformer
$users = $this->getUsers($reviews);
foreach ($reviews as $key => $review) {
$reviews[$key]['user'] = $users[$review['user_id']];
$reviews[$key]['user'] = $users[$review['user_id']] ?? [];
}
return $reviews;
@ -36,11 +36,11 @@ class ReviewList extends Transformer
$courseRepo = new CourseRepo();
$courses = $courseRepo->findByIds($ids, ['id', 'title'])->toArray();
$courses = $courseRepo->findByIds($ids, ['id', 'title']);
$result = [];
foreach ($courses as $course) {
foreach ($courses->toArray() as $course) {
$result[$course['id']] = $course;
}
@ -53,11 +53,14 @@ class ReviewList extends Transformer
$userRepo = new UserRepo();
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar'])->toArray();
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar']);
$result = [];
foreach ($users as $user) {
$imgBaseUrl = kg_img_base_url();
foreach ($users->toArray() as $user) {
$user['avatar'] = $imgBaseUrl . $user['avatar'];
$result[$user['id']] = $user;
}

View File

@ -0,0 +1,19 @@
<?php
namespace App\Builders;
class SlideList extends Builder
{
public function handleSlides($slides)
{
$imgBaseUrl = kg_img_base_url();
foreach ($slides as $key => $slide) {
$slides[$key]['cover'] = $imgBaseUrl . $slide['cover'];
}
return $slides;
}
}

View File

@ -1,10 +1,10 @@
<?php
namespace App\Transformers;
namespace App\Builders;
use App\Repos\User as UserRepo;
class TradeList extends Transformer
class TradeList extends Builder
{
public function handleUsers($trades)

21
app/Builders/User.php Normal file
View File

@ -0,0 +1,21 @@
<?php
namespace App\Builders;
use App\Models\User as UserModel;
class User extends Builder
{
/**
* @param UserModel $user
* @return UserModel
*/
public function handleUser(UserModel $user)
{
$user->avatar = kg_img_url($user->avatar);
return $user;
}
}

View File

@ -1,13 +1,24 @@
<?php
namespace App\Transformers;
namespace App\Builders;
use App\Models\User as UserModel;
use App\Repos\Role as RoleRepo;
class UserList extends Transformer
class UserList extends Builder
{
public function handleUsers($users)
{
$imgBaseUrl = kg_img_base_url();
foreach ($users as $key => $user) {
$users[$key]['avatar'] = $imgBaseUrl . $user['avatar'];
}
return $users;
}
public function handleAdminRoles($users)
{
$roles = $this->getAdminRoles($users);

View File

@ -2,13 +2,11 @@
namespace App\Caches;
use Phalcon\Mvc\User\Component as UserComponent;
abstract class Cache extends UserComponent
abstract class Cache extends \Phalcon\Mvc\User\Component
{
/**
* @var \Phalcon\Cache\Backend
* @var \Phalcon\Cache\Backend\Redis
*/
protected $cache;
@ -20,18 +18,26 @@ abstract class Cache extends UserComponent
/**
* 获取缓存内容
*
* @param mixed $params
* @param mixed $id
* @return mixed
*/
public function get($params = null)
public function get($id = null)
{
$key = $this->getKey($params);
$content = $this->cache->get($key);
$lifetime = $this->getLifetime();
$key = $this->getKey($id);
$content = $this->cache->get($key);
if (!$this->cache->exists($key)) {
$content = $this->getContent($id);
/**
* 原始内容为空,设置较短的生存时间,简单防止穿透
*/
$lifetime = $content ? $this->getLifetime() : 5 * 60;
if (!$content) {
$content = $this->getContent($params);
$this->cache->save($key, $content, $lifetime);
$content = $this->cache->get($key);
}
@ -41,35 +47,48 @@ abstract class Cache extends UserComponent
/**
* 删除缓存内容
*
* @param mixed $params
* @param mixed $id
*/
public function delete($params = null)
public function delete($id = null)
{
$key = $this->getKey($params);
$key = $this->getKey($id);
$this->cache->delete($key);
}
/**
* 重建缓存内容
*
* @param mixed $id
*/
public function rebuild($id = null)
{
$this->delete($id);
$this->get($id);
}
/**
* 获取缓存有效期
*
* @return integer
* @return int
*/
abstract protected function getLifetime();
abstract public function getLifetime();
/**
* 获取键值
*
* @param mixed $params
* @param mixed $id
* @return string
*/
abstract protected function getKey($params = null);
abstract public function getKey($id = null);
/**
* 获取原始内容
*
* @param mixed $params
* @param mixed $id
* @return mixed
*/
abstract protected function getContent($params = null);
abstract public function getContent($id = null);
}

View File

@ -1,57 +1,35 @@
<?php
namespace App\Library\Cache;
namespace App\Caches;
use App\Exceptions\NotFound as ModelNotFoundException;
use App\Models\Category as CategoryModel;
use App\Repos\Category as CategoryRepo;
class Category extends \Phalcon\Di\Injectable
class Category extends Cache
{
private $lifetime = 86400 * 30;
public function getOrFail($id)
{
$result = $this->getById($id);
if (!$result) {
throw new ModelNotFoundException('category.not_found');
}
return $result;
}
public function get($id)
{
$cacheOptions = [
'key' => $this->getKey($id),
'lifetime' => $this->getLifetime(),
];
$result = CategoryModel::query()
->where('id = :id:', ['id' => $id])
->cache($cacheOptions)
->execute()
->getFirst();
return $result;
}
public function delete($id)
{
$key = $this->getKey($id);
$this->modelsCache->delete($key);
}
public function getKey($id)
{
return "category:{$id}";
}
protected $lifetime = 365 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return "category:{$id}";
}
public function getContent($id = null)
{
$categoryRepo = new CategoryRepo();
$category = $categoryRepo->findById($id);
if (!$category) {
return new \stdClass();
}
return $category;
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace App\Caches;
use App\Models\Category as CategoryModel;
class CategoryList extends Cache
{
protected $lifetime = 365 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'category_list';
}
/**
* @param null $id
* @return array
*/
public function getContent($id = null)
{
$categories = CategoryModel::query()
->columns(['id', 'parent_id', 'name', 'priority', 'level', 'path'])
->where('published = 1 AND deleted = 0')
->execute();
if ($categories->count() == 0) {
return [];
}
return $categories->toArray();
}
}

View File

@ -0,0 +1,51 @@
<?php
namespace App\Caches;
use App\Builders\CategoryList as CategoryTreeListBuilder;
use App\Models\Category as CategoryModel;
class CategoryTreeList extends Cache
{
protected $lifetime = 365 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'category_tree';
}
public function getContent($id = null)
{
$categories = CategoryModel::query()
->where('published = 1 AND deleted = 0')
->execute();
if ($categories->count() == 0) {
return [];
}
return $this->handleContent($categories);
}
/**
* @param \App\Models\Category[] $categories
* @return array
*/
protected function handleContent($categories)
{
$items = $categories->toArray();
$builder = new CategoryTreeListBuilder();
$content = $builder->handleTreeList($items);
return $content;
}
}

35
app/Caches/Chapter.php Normal file
View File

@ -0,0 +1,35 @@
<?php
namespace App\Caches;
use App\Repos\Chapter as ChapterRepo;
class Chapter extends Cache
{
protected $lifetime = 7 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return "chapter:{$id}";
}
public function getContent($id = null)
{
$chapterRepo = new ChapterRepo();
$chapter = $chapterRepo->findById($id);
if (!$chapter) {
return new \stdClass();
}
return $chapter;
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace App\Caches;
use App\Repos\Chapter as ChapterRepo;
class ChapterCounter extends Counter
{
protected $lifetime = 7 * 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 [];
$content = [
'lesson_count' => $chapter->lesson_count,
'user_count' => $chapter->user_count,
'comment_count' => $chapter->comment_count,
'like_count' => $chapter->like_count,
];
return $content;
}
}

View File

@ -13,19 +13,21 @@ class Config extends Cache
* 获取某组配置项
*
* @param string $section
* @return \stdClass|null
* @return array
*/
public function getSectionConfig($section)
{
$items = $this->get();
if (!$items) return;
$result = [];
$result = new \stdClass();
if (!$items) {
return $result;
}
foreach ($items as $item) {
if ($item->section == $section) {
$result->{$item->item_key} = $item->item_value;
if ($item['section'] == $section) {
$result[$item['item_key']] = $item['item_value'];
}
}
@ -43,28 +45,28 @@ class Config extends Cache
{
$config = $this->getSectionConfig($section);
$result = $config->{$key} ?? null;
$result = $config[$key] ?? null;
return $result;
}
protected function getLifetime()
public function getLifetime()
{
return $this->lifetime;
}
protected function getKey($params = null)
public function getKey($id = null)
{
return 'site_config';
return 'config';
}
protected function getContent($params = null)
public function getContent($id = null)
{
$configRepo = new ConfigRepo();
$items = $configRepo->findAll();
return $items;
return $items->toArray();
}
}

122
app/Caches/Counter.php Normal file
View File

@ -0,0 +1,122 @@
<?php
namespace App\Caches;
abstract class Counter extends \Phalcon\Mvc\User\Component
{
/**
* @var \App\Library\Cache\Backend\Redis
*/
protected $cache;
/**
* @var \Redis
*/
protected $redis;
public function __construct()
{
$this->cache = $this->getDI()->get('cache');
$this->redis = $this->cache->getRedis();
}
/**
* 获取缓存内容
*
* @param mixed $id
* @return array
*/
public function get($id = null)
{
$key = $this->getKey($id);
$content = $this->redis->hGetAll($key);
if (!$this->cache->exists($key)) {
$content = $this->getContent($id);
$lifetime = $this->getLifetime();
/**
* 原始内容为空,设置较短的生存时间,简单防止穿透
*/
if (!$content) {
$lifetime = 5 * 60;
$content = ['default' => 0];
}
$this->redis->hMSet($key, $content);
$this->redis->expire($key, $lifetime);
}
return $content;
}
/**
* 删除缓存内容
*
* @param mixed $id
*/
public function delete($id = null)
{
$key = $this->getKey($id);
$this->cache->delete($key);
}
/**
* 重建缓存内容
*
* @param mixed $id
*/
public function rebuild($id = null)
{
$this->delete($id);
$this->get($id);
}
public function increment($id, $hashKey, $value = 1)
{
$key = $this->getKey($id);
$this->redis->hIncrBy($key, $hashKey, $value);
}
public function decrement($id, $hashKey, $value = 1)
{
$key = $this->getKey($id);
$this->redis->hIncrBy($key, $hashKey, 0 - $value);
}
/**
* 获取缓存有效期
*
* @return int
*/
abstract public function getLifetime();
/**
* 获取键值
*
* @param mixed $id
* @return string
*/
abstract public function getKey($id = null);
/**
* 获取原始内容
*
* @param mixed $id
* @return mixed
*/
abstract public function getContent($id = null);
}

View File

@ -1,57 +1,35 @@
<?php
namespace App\Library\Cache;
namespace App\Caches;
use App\Exceptions\NotFound as ModelNotFoundException;
use App\Models\Course as CourseModel;
use App\Repos\Course as CourseRepo;
class Course extends \Phalcon\Di\Injectable
class Course extends Cache
{
private $lifetime = 86400;
public function getOrFail($id)
{
$result = $this->getById($id);
if (!$result) {
throw new ModelNotFoundException('course.not_found');
}
return $result;
}
public function get($id)
{
$cacheOptions = [
'key' => $this->getKey($id),
'lifetime' => $this->getLifetime(),
];
$result = CourseModel::query()
->where('id = :id:', ['id' => $id])
->cache($cacheOptions)
->execute()
->getFirst();
return $result;
}
public function delete($id)
{
$key = $this->getKey($id);
$this->modelsCache->delete($key);
}
public function getKey($id)
{
return "course:{$id}";
}
protected $lifetime = 7 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return "course:{$id}";
}
public function getContent($id = null)
{
$courseRepo = new CourseRepo();
$course = $courseRepo->findById($id);
if (!$course) {
return new \stdClass();
}
return $course;
}
}

View File

@ -0,0 +1,53 @@
<?php
namespace App\Caches;
use App\Repos\Course as CourseRepo;
class CourseCategoryList extends Cache
{
protected $lifetime = 7 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return "course_category_list:{$id}";
}
public function getContent($id = null)
{
$courseRepo = new CourseRepo();
$categories = $courseRepo->findCategories($id);
if ($categories->count() == 0) {
return [];
}
return $this->handleContent($categories);
}
/**
* @param \App\Models\Category[] $categories
* @return array
*/
public function handleContent($categories)
{
$result = [];
foreach ($categories as $category) {
$result[] = [
'id' => $category->id,
'name' => $category->name,
];
}
return $result;
}
}

View File

@ -0,0 +1,51 @@
<?php
namespace App\Caches;
use App\Builders\ChapterList as ChapterListBuilder;
use App\Repos\Course as CourseRepo;
class CourseChapterList extends Cache
{
protected $lifetime = 7 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return "course_chapter_list:{$id}";
}
public function getContent($id = null)
{
$courseRepo = new CourseRepo();
$chapters = $courseRepo->findChapters($id);
if ($chapters->count() == 0) {
return [];
}
return $this->handleContent($chapters);
}
/**
* @param \App\Models\Chapter[] $chapters
* @return array
*/
protected function handleContent($chapters)
{
$items = $chapters->toArray();
$builder = new ChapterListBuilder();
$content = $builder->handleTreeList($items);
return $content;
}
}

View File

@ -0,0 +1,41 @@
<?php
namespace App\Caches;
use App\Repos\Course as CourseRepo;
class CourseCounter extends Counter
{
protected $lifetime = 7 * 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 [];
$content = [
'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 $content;
}
}

View File

@ -0,0 +1,82 @@
<?php
namespace App\Caches;
use App\Repos\Course as CourseRepo;
class CoursePackageList extends Cache
{
protected $lifetime = 7 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return "course_package_list:{$id}";
}
public function getContent($id = null)
{
$courseRepo = new CourseRepo();
$packages = $courseRepo->findPackages($id);
if ($packages->count() == 0) {
return [];
}
return $this->handleContent($packages);
}
/**
* @param \App\Models\Package[] $packages
* @return array
*/
protected function handleContent($packages)
{
$result = [];
foreach ($packages as $package) {
$courses = $this->getPackageCourses($package->id);
$result[] = [
'id' => $package->id,
'title' => $package->title,
'market_price' => $package->market_price,
'vip_price' => $package->vip_price,
'courses' => $courses,
];
}
return $result;
}
protected function getPackageCourses($packageId)
{
$packageRepo = new PackageRepo();
$courses = $packageRepo->findCourses($packageId);
$result = [];
foreach ($courses as $course) {
$result[] = [
'id' => $course->id,
'model' => $course->model,
'title' => $course->title,
'summary' => $course->summary,
'cover' => $course->cover,
'market_price' => $course->market_price,
'vip_price' => $course->vip_price,
];
}
return $result;
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace App\Caches;
use App\Repos\Course as CourseRepo;
class CourseRelatedList extends Cache
{
protected $lifetime = 7 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return "course_related_list:{$id}";
}
public function getContent($id = null)
{
$courseRepo = new CourseRepo();
$courses = $courseRepo->findRelatedCourses($id);
if ($courses->count() == 0) {
return [];
}
return $this->handleContent($courses);
}
/**
* @param \App\Models\Course[] $courses
* @return array
*/
public function handleContent($courses)
{
$result = [];
foreach ($courses as $course) {
$result[] = [
'id' => $course->id,
'model' => $course->model,
'title' => $course->title,
'cover' => $course->cover,
'summary' => $course->summary,
'market_price' => $course->market_price,
'vip_price' => $course->vip_price,
];
}
return $result;
}
}

View File

@ -0,0 +1,56 @@
<?php
namespace App\Caches;
use App\Repos\Course as CourseRepo;
class CourseTeacherList extends Cache
{
protected $lifetime = 7 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return "course_teacher_list:{$id}";
}
public function getContent($id = null)
{
$courseRepo = new CourseRepo();
$users = $courseRepo->findTeachers($id);
if ($users->count() == 0) {
return [];
}
return $this->handleContent($users);
}
/**
* @param \App\Models\User[] $users
* @return array
*/
public function handleContent($users)
{
$result = [];
foreach ($users as $user) {
$result[] = [
'id' => $user->id,
'name' => $user->name,
'avatar' => $user->avatar,
'title' => $user->title,
'about' => $user->about,
];
}
return $result;
}
}

43
app/Caches/CourseUser.php Normal file
View File

@ -0,0 +1,43 @@
<?php
namespace App\Caches;
use App\Repos\CourseUser as CourseUserRepo;
class CourseUser extends Cache
{
protected $lifetime = 7 * 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);
if (!$courseUser) {
return new \stdClass();
}
return $courseUser;
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace App\Caches;
use App\Repos\Course as CourseRepo;
class HotCourseList extends Cache
{
protected $lifetime = 7 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'hot_course_list';
}
public function getContent($id = null)
{
$courseRepo = new CourseRepo();
$courses = $courseRepo->findRelatedCourses($id);
if ($courses->count() == 0) {
return [];
}
return $this->handleContent($courses);
}
/**
* @param \App\Models\Course[] $courses
* @return array
*/
public function handleContent($courses)
{
$result = [];
foreach ($courses as $course) {
$result[] = [
'id' => $course->id,
'model' => $course->model,
'title' => $course->title,
'summary' => $course->summary,
'cover' => $course->cover,
'market_price' => $course->market_price,
'vip_price' => $course->vip_price,
];
}
return $result;
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace App\Caches;
class HotTeacherList extends Cache
{
protected $lifetime = 365 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'hot_teacher_list';
}
public function getContent($id = null)
{
}
protected function handleContent($users)
{
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace App\Caches;
use App\Repos\Course as CourseRepo;
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)
{
$courseRepo = new CourseRepo();
$courses = $courseRepo->findRelatedCourses($id);
if ($courses->count() == 0) {
return [];
}
return $this->handleContent($courses);
}
/**
* @param \App\Models\Course[] $courses
* @return array
*/
public function handleContent($courses)
{
$result = [];
foreach ($courses as $course) {
$result[] = [
'id' => $course->id,
'model' => $course->model,
'title' => $course->title,
'summary' => $course->summary,
'cover' => $course->cover,
'market_price' => $course->market_price,
'vip_price' => $course->vip_price,
];
}
return $result;
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace App\Caches;
use App\Models\Chapter as ChapterModel;
class MaxChapterId extends Cache
{
protected $lifetime = 365 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'max_chapter_id';
}
public function getContent($id = null)
{
$chapter = ChapterModel::findFirst(['order' => 'id DESC']);
return $chapter->id;
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace App\Caches;
use App\Models\Course as CourseModel;
class MaxCourseId extends Cache
{
protected $lifetime = 365 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'max_course_id';
}
public function getContent($id = null)
{
$course = CourseModel::findFirst(['order' => 'id DESC']);
return $course->id;
}
}

29
app/Caches/MaxUserId.php Normal file
View File

@ -0,0 +1,29 @@
<?php
namespace App\Caches;
use App\Models\User as UserModel;
class MaxUserId extends Cache
{
protected $lifetime = 365 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'max_user_id';
}
public function getContent($id = null)
{
$course = UserModel::findFirst(['order' => 'id DESC']);
return $course->id;
}
}

View File

@ -1,53 +0,0 @@
<?php
namespace App\Caches;
use App\Repos\Nav as NavRepo;
class Nav extends Cache
{
protected $lifetime = 365 * 86400;
public function getTopNav()
{
$items = $this->get();
if (!$items) return;
$result = new \stdClass();
foreach ($items as $item) {
if ($item->position == 'top') {
$result->{$item->item_key} = $item->item_value;
}
}
return $result;
}
public function getBottomNav()
{
}
protected function getLifetime()
{
return $this->lifetime;
}
protected function getKey($params = null)
{
return 'nav';
}
protected function getContent($params = null)
{
$navRepo = new NavRepo();
$items = $navRepo->findAll();
return $items;
}
}

View File

@ -0,0 +1,66 @@
<?php
namespace App\Caches;
use App\Builders\NavList as NavListBuilder;
use App\Models\Nav as NavModel;
class NavTreeList extends Cache
{
protected $lifetime = 365 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'nav_tree_list';
}
public function getContent($id = null)
{
$navs = NavModel::query()
->where('published = 1 AND deleted = 0')
->orderBy('position ASC, priority ASC')
->execute();
if ($navs->count() == 0) {
return [];
}
return $this->handleContent($navs);
}
/**
* @param \App\Models\Nav[] $navs
* @return array
*/
protected function handleContent($navs)
{
$list = [
'top' => [],
'bottom' => [],
];
foreach ($navs->toArray() as $nav) {
if ($nav['position'] == 'top') {
$list['top'][] = $nav;
} elseif ($nav['position'] == 'bottom') {
$list['bottom'][] = $nav;
}
}
$builder = new NavListBuilder();
$content = [
'top' => $builder->handleTreeList($list['top']),
'bottom' => $builder->handleTreeList($list['bottom']),
];
return $content;
}
}

59
app/Caches/SlideList.php Normal file
View File

@ -0,0 +1,59 @@
<?php
namespace App\Caches;
use App\Models\Slide as SlideModel;
class SlideList extends Cache
{
protected $lifetime = 365 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'slide_list';
}
public function getContent($id = null)
{
$slides = SlideModel::query()
->columns(['id', 'title', 'cover', 'summary', 'target', 'content'])
->where('published = 1 AND deleted = 0')
->orderBy('priority ASC')
->execute();
if ($slides->count() == 0) {
return [];
}
return $this->handleContent($slides);
}
/**
* @param \App\Models\Slide[] $slides
* @return array
*/
protected function handleContent($slides)
{
$result = [];
foreach ($slides as $slide) {
$result[] = [
'id' => $slide->id,
'title' => $slide->title,
'cover' => $slide->cover,
'summary' => $slide->summary,
'target' => $slide->target,
'content' => $slide->content,
];
}
return $result;
}
}

View File

@ -1,57 +1,35 @@
<?php
namespace App\Library\Cache;
namespace App\Caches;
use App\Exceptions\NotFound as ModelNotFoundException;
use App\Models\User as UserModel;
use App\Repos\User as UserRepo;
class User extends \Phalcon\Di\Injectable
class User extends Cache
{
private $lifetime = 86400 * 30;
public function getOrFail($id)
{
$result = $this->getById($id);
if (!$result) {
throw new ModelNotFoundException('user.not_found');
}
return $result;
}
public function get($id)
{
$cacheOptions = [
'key' => $this->getKey($id),
'lifetime' => $this->getLifetime(),
];
$result = UserModel::query()
->where('id = :id:', ['id' => $id])
->cache($cacheOptions)
->execute()
->getFirst();
return $result;
}
public function delete($id)
{
$key = $this->getKey($id);
$this->modelsCache->delete($key);
}
public function getKey($id)
{
return "user:{$id}";
}
protected $lifetime = 7 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return "user:{$id}";
}
public function getContent($id = null)
{
$userRepo = new UserRepo();
$user = $userRepo->findById($id);
if (!$user) {
return new \stdClass();
}
return $user;
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace App\Caches;
use App\Repos\User as UserRepo;
class UserCounter extends Counter
{
protected $lifetime = 7 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return "user_counter:{$id}";
}
public function getContent($id = null)
{
$userRepo = new UserRepo();
$user = $userRepo->findById($id);
if (!$user) return [];
$content = [
'notice_count' => $user->notice_count,
'msg_count' => $user->msg_count,
];
return $content;
}
}

View File

@ -123,7 +123,7 @@ class CleanLogTask extends Task
* 清理日志文件
*
* @param string $prefix
* @param integer $keepDays 保留天数
* @param int $keepDays 保留天数
* @return mixed
*/
protected function cleanLog($prefix, $keepDays)

View File

@ -25,7 +25,7 @@ class CloseOrderTask extends Task
/**
* 查找待关闭订单
*
* @param integer $limit
* @param int $limit
* @return \Phalcon\Mvc\Model\ResultsetInterface
*/
protected function findOrders($limit = 1000)

View File

@ -0,0 +1,40 @@
<?php
namespace App\Console\Tasks;
use App\Models\Slide as SlideModel;
use Phalcon\Cli\Task;
class CloseSlideTask extends Task
{
public function mainAction()
{
$slides = $this->findSlides();
if ($slides->count() == 0) {
return;
}
foreach ($slides as $slide) {
$slide->published = 0;
$slide->update();
}
}
/**
* 查找待关闭轮播
*
* @return \Phalcon\Mvc\Model\ResultsetInterface
*/
protected function findSlides()
{
$Slides = SlideModel::query()
->where('published = 1')
->andWhere('end_time < :end_time:', ['end_time' => time()])
->execute();
return $Slides;
}
}

View File

@ -73,7 +73,7 @@ class CloseTradeTask extends Task
/**
* 查找待关闭交易
*
* @param integer $limit
* @param int $limit
* @return \Phalcon\Mvc\Model\ResultsetInterface
*/
protected function findTrades($limit = 5)

View File

@ -10,15 +10,15 @@ class CountCourseTask extends Task
public function mainAction()
{
$repo = new CategoryRepo();
$categoryRepo = new CategoryRepo();
$mapping = [];
$subCategories = $repo->findAll(['level' => 2, 'deleted' => 0]);
$subCategories = $categoryRepo->findAll(['level' => 2, 'deleted' => 0]);
foreach ($subCategories as $category) {
$courseCount = $repo->countCourses($category->id);
$courseCount = $categoryRepo->countCourses($category->id);
$category->course_count = $courseCount;
$category->update();
@ -31,7 +31,7 @@ class CountCourseTask extends Task
}
}
$topCategories = $repo->findAll(['level' => 1, 'deleted' => 0]);
$topCategories = $categoryRepo->findAll(['level' => 1, 'deleted' => 0]);
foreach ($topCategories as $category) {
if (isset($mapping[$category->id])) {

View File

@ -13,24 +13,40 @@ class ImageSyncTask extends Task
public function mainAction()
{
$courses = Course::query()
->where('id = 42')
->execute();
->where('id > 1155')
->execute();
$storage = new Storage();
foreach ($courses as $course) {
$cover = $course->cover;
if (Text::startsWith($cover, '//')) {
$cover = 'http:' . $cover;
}
$url = str_replace('-240-135', '', $cover);
$url = str_replace('-360-202', '', $cover);
$fileName = parse_url($url, PHP_URL_PATH);
$filePath = tmp_path() . $fileName;
$content = file_get_contents($url);
file_put_contents($filePath, $content);
if ($content === false) {
echo "get course {$course->id} cover failed" . PHP_EOL;
return;
}
$put = file_put_contents($filePath, $content);
if ($put === false) {
echo "put course {$course->id} cover failed" . PHP_EOL;
return;
}
$keyName = $this->getKeyName($filePath);
$remoteUrl = $storage->putFile($keyName, $filePath);
if ($remoteUrl) {
$course->cover = $keyName;
$course->update();

View File

@ -2,6 +2,7 @@
namespace App\Console\Tasks;
use App\Models\Course as CourseModel;
use App\Models\Learning as LearningModel;
use App\Repos\Chapter as ChapterRepo;
use App\Repos\ChapterUser as ChapterUserRepo;
@ -24,9 +25,7 @@ class LearningTask extends Task
$keys = $this->cache->queryKeys('learning:');
if (empty($keys)) {
return;
}
if (!$keys) return;
$keys = array_slice($keys, 0, 500);
@ -40,32 +39,21 @@ class LearningTask extends Task
{
$content = $this->cache->get($key);
if (empty($content->user_id)) {
return;
}
if (!empty($content->client_ip)) {
$region = kg_ip2region($content->client_ip);
$content->country = $region->country;
$content->province = $region->province;
$content->city = $region->city;
}
if (!$content) return;
$learningRepo = new LearningRepo();
$learning = $learningRepo->findByRequestId($content->request_id);
$learning = $learningRepo->findByRequestId($content['request_id']);
if (!$learning) {
$learning = new LearningModel();
$data = kg_object_array($content);
$learning->create($data);
$learning->create($content);
} else {
$learning->duration += $content->duration;
$learning->duration += $content['duration'];
$learning->update();
}
$this->updateChapterUser($content->chapter_id, $content->user_id, $content->duration, $content->position);
$this->updateCourseUser($content->course_id, $content->user_id, $content->duration);
$this->updateChapterUser($content['chapter_id'], $content['user_id'], $content['duration'], $content['position']);
$this->cache->delete($key);
}
@ -76,63 +64,87 @@ class LearningTask extends Task
$chapterUser = $chapterUserRepo->findChapterUser($chapterId, $userId);
if (!$chapterUser) {
return;
}
if (!$chapterUser) return;
$chapterRepo = new ChapterRepo();
$chapter = $chapterRepo->findById($chapterId);
if (!$chapter) {
return;
}
if (!$chapter) return;
$chapter->duration = $chapter->attrs['duration'] ?: 0;
$chapterModel = $chapter->attrs['model'];
$chapterUser->duration += $duration;
$chapterUser->position = floor($position);
/**
* 观看时长超过视频时长80%标记完成学习
* 消费规则
* 1.点播观看时间大于时长30%
* 2.直播观看时间超过10分钟
* 3.图文浏览即消费
*/
if ($chapterUser->duration > $chapter->duration * 0.8) {
if ($chapterUser->finished == 0) {
$chapterUser->finished = 1;
$this->updateCourseProgress($chapterUser->course_id, $chapterUser->user_id);
}
if ($chapterModel == CourseModel::MODEL_VOD) {
$chapterDuration = $chapter->attrs['duration'] ?: 300;
$progress = floor(100 * $chapterUser->duration / $chapterDuration);
$chapterUser->position = floor($position);
$chapterUser->progress = $progress < 100 ? $progress : 100;
$chapterUser->consumed = $chapterUser->duration > 0.3 * $chapterDuration ? 1 : 0;
} elseif ($chapterModel == CourseModel::MODEL_LIVE) {
$chapterUser->consumed = $chapterUser->duration > 600 ? 1 : 0;
} elseif ($chapterModel == CourseModel::MODEL_READ) {
$chapterUser->consumed = 1;
}
$chapterUser->update();
}
protected function updateCourseUser($courseId, $userId, $duration)
{
$courseUserRepo = new CourseUserRepo();
$courseUser = $courseUserRepo->findCourseUser($courseId, $userId);
if ($courseUser) {
$courseUser->duration += $duration;
$courseUser->update();
if ($chapterUser->consumed == 1) {
$this->updateCourseUser($chapterUser->course_id, $chapterUser->user_id);
}
}
protected function updateCourseProgress($courseId, $userId)
protected function updateCourseUser($courseId, $userId)
{
$courseUserRepo = new CourseUserRepo();
$courseUser = $courseUserRepo->findCourseUser($courseId, $userId);
$courseRepo = new CourseRepo();
$course = $courseRepo->findById($courseId);
$courseLessons = $courseRepo->findLessons($courseId);
if ($courseUser) {
$count = $courseUserRepo->countFinishedChapters($courseId, $userId);
$courseUser->progress = intval(100 * $count / $course->lesson_count);
$courseUser->update();
if ($courseLessons->count() == 0) {
return;
}
$userLearnings = $courseRepo->findConsumedUserLearnings($courseId, $userId);
if ($userLearnings->count() == 0) {
return;
}
$duration = 0;
foreach ($userLearnings as $learning) {
$duration += $learning->duration;
}
$courseLessonIds = kg_array_column($courseLessons->toArray(), 'id');
$userLessonIds = kg_array_column($userLearnings->toArray(), 'chapter_id');
$consumedLessonIds = array_intersect($courseLessonIds, $userLessonIds);
$totalCount = count($courseLessonIds);
$consumedCount = count($consumedLessonIds);
$progress = intval(100 * $consumedCount / $totalCount);
$courseUserRepo = new CourseUserRepo();
$courseUser = $courseUserRepo->findCourseUser($courseId, $userId);
$courseUser->progress = $progress;
$courseUser->duration = $duration;
$courseUser->update();
}
}

View File

@ -0,0 +1,130 @@
<?php
namespace App\Console\Tasks;
use App\Models\Course as CourseModel;
use App\Searchers\CourseDocumenter;
use App\Searchers\CourseSearcher;
use Phalcon\Cli\Task;
class ManageCourseIndexTask extends Task
{
/**
* 搜索测试
*
* @command: php console.php manage_course_index search {query}
* @param array $params
* @throws \XSException
*/
public function searchAction($params)
{
$query = $params[0] ?? null;
if (!$query) {
exit("please special a query word" . PHP_EOL);
}
$result = $this->searchCourses($query);
var_export($result);
}
/**
* 清空索引
*
* @command: php console.php manage_course_index clean
*/
public function cleanAction()
{
$this->cleanCourseIndex();
}
/**
* 重建索引
*
* @command: php console.php manage_course_index rebuild
*/
public function rebuildAction()
{
$this->rebuildCourseIndex();
}
/**
* 清空索引
*/
protected function cleanCourseIndex()
{
$searcher = new CourseSearcher();
$index = $searcher->getXS()->getIndex();
echo "start clean index" . PHP_EOL;
$index->clean();
echo "end clean index" . PHP_EOL;
}
/**
* 重建索引
*/
protected function rebuildCourseIndex()
{
$courses = $this->findCourses();
if ($courses->count() == 0) {
return;
}
$searcher = new CourseSearcher();
$documenter = new CourseDocumenter();
$index = $searcher->getXS()->getIndex();
echo "start rebuild index" . PHP_EOL;
$index->beginRebuild();
foreach ($courses as $course) {
$document = $documenter->setDocument($course);
$index->add($document);
}
$index->endRebuild();
echo "end rebuild index" . PHP_EOL;
}
/**
* 搜索课程
*
* @param string $query
* @return array $result
* @throws \XSException
*/
protected function searchCourses($query)
{
$searcher = new CourseSearcher();
$result = $searcher->search($query);
return $result;
}
/**
* 查找课程
*
* @return \Phalcon\Mvc\Model\ResultsetInterface
*/
protected function findCourses()
{
$courses = CourseModel::query()
->where('published = 1')
->execute();
return $courses;
}
}

View File

@ -1,166 +0,0 @@
<?php
namespace App\Console\Tasks;
use App\Models\Course as CourseModel;
use App\Searchers\Course as CourseSearcher;
use Phalcon\Cli\Task;
class ManageIndexTask extends Task
{
/**
* 搜索测试
*
* @command: php console.php index search {type} {query}
* @param array $params
* @throws \XSException
*/
public function searchAction($params)
{
$type = $params[0] ?? null;
$query = $params[1] ?? null;
if (!in_array($type, $this->getItemTypes())) {
exit("Invalid item type" . PHP_EOL);
}
if (!$query) {
exit("Please special a query word" . PHP_EOL);
}
$result = [];
if ($type == 'course') {
$result = $this->searchCourses($query);
}
var_export($result);
}
/**
* 清空索引
*
* @command: php console.php index clean {type}
* @param array $params
*/
public function cleanAction($params)
{
$type = $params[0] ?? null;
if (in_array($type, $this->getItemTypes())) {
exit("Invalid item type" . PHP_EOL);
}
if ($type == 'course') {
$this->cleanCourseIndex();
}
}
/**
* 重建索引
*
* @command: php console.php index rebuild {type}
* @param array $params
*/
public function rebuildAction($params)
{
$type = $params[0] ?? null;
if (in_array($type, $this->getItemTypes())) {
exit("Invalid item type" . PHP_EOL);
}
if ($type == 'course') {
$this->rebuildCourseIndex();
}
}
/**
* 清空课程索引
*/
protected function cleanCourseIndex()
{
$searcher = new CourseSearcher();
$index = $searcher->getXS()->getIndex();
echo "Start clean index" . PHP_EOL;
$index->clean();
echo "End clean index" . PHP_EOL;
}
/**
* 重建课程索引
*/
protected function rebuildCourseIndex()
{
$courses = $this->findCourses();
if ($courses->count() == 0) {
return;
}
$searcher = new CourseSearcher();
$index = $searcher->getXS()->getIndex();
echo "Start rebuild index" . PHP_EOL;
$index->beginRebuild();
foreach ($courses as $course) {
$document = $searcher->setDocument($course);
$index->add($document);
}
$index->endRebuild();
echo "End rebuild index" . PHP_EOL;
}
/**
* 搜索课程
*
* @param string $query
* @return \stdClass $result
* @throws \XSException
*/
protected function searchCourses($query)
{
$searcher = new CourseSearcher();
$result = $searcher->search($query);
return $result;
}
/**
* 查找课程
*
* @return \Phalcon\Mvc\Model\ResultsetInterface
*/
protected function findCourses()
{
$courses = CourseModel::query()
->where('published = 1')
->execute();
return $courses;
}
/**
* 获取条目类型
*
* @return array
*/
protected function getItemTypes()
{
$types = ['course'];
return $types;
}
}

View File

@ -0,0 +1,69 @@
<?php
namespace App\Console\Tasks;
use App\Caches\Chapter as ChapterCache;
use App\Caches\ChapterCounter as ChapterCounterCache;
use App\Repos\Chapter as ChapterRepo;
use App\Services\ChapterCacheSyncer;
class RebuildChapterCacheTask extends Task
{
/**
* @var \App\Library\Cache\Backend\Redis
*/
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;
}
$chapterCache = new ChapterCache();
$counterCache = new ChapterCounterCache();
foreach ($chapters as $chapter) {
$chapter->user_count = $chapterRepo->countUsers($chapter->id);
$chapter->comment_count = $chapterRepo->countComments($chapter->id);
$chapter->like_count = $chapterRepo->countLikes($chapter->id);
$chapter->update();
$chapterCache->rebuild($chapter->id);
$counterCache->rebuild($chapter->id);
}
}
protected function getCacheKey()
{
$syncer = new ChapterCacheSyncer();
return $syncer->getCacheKey();
}
}

View File

@ -0,0 +1,72 @@
<?php
namespace App\Console\Tasks;
use App\Caches\Course as CourseCache;
use App\Caches\CourseCounter as CourseCounterCache;
use App\Repos\Course as CourseRepo;
use App\Services\CourseCacheSyncer;
class RebuildCourseCacheTask extends Task
{
/**
* @var \App\Library\Cache\Backend\Redis
*/
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;
}
$courseCache = new CourseCache();
$counterCache = new CourseCounterCache();
foreach ($courses as $course) {
$course->user_count = $courseRepo->countUsers($course->id);
$course->comment_count = $courseRepo->countComments($course->id);
$course->review_count = $courseRepo->countReviews($course->id);
$course->favorite_count = $courseRepo->countFavorites($course->id);
$course->update();
$courseCache->rebuild($course->id);
$counterCache->rebuild($course->id);
}
$this->redis->sRem($key, ...$courseIds);
}
protected function getCacheKey()
{
$syncer = new CourseCacheSyncer();
return $syncer->getCacheKey();
}
}

View File

@ -0,0 +1,77 @@
<?php
namespace App\Console\Tasks;
use App\Repos\Course as CourseRepo;
use App\Searchers\CourseDocumenter;
use App\Searchers\CourseSearcher;
use App\Services\CourseIndexSyncer;
class RebuildCourseIndexTask extends Task
{
/**
* @var \App\Library\Cache\Backend\Redis
*/
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;
}
$document = new CourseDocumenter();
$searcher = new CourseSearcher();
$index = $searcher->getXS()->getIndex();
$index->openBuffer();
foreach ($courses as $course) {
$doc = $document->setDocument($course);
if ($course->published == 1) {
$index->update($doc);
} else {
$index->del($course->id);
}
}
$index->closeBuffer();
$this->redis->sRem($key, ...$courseIds);
}
protected function getCacheKey()
{
$syncer = new CourseIndexSyncer();
return $syncer->getCacheKey();
}
}

View File

@ -247,12 +247,6 @@ class RefundTask extends Task
}
/**
* 查找退款任务
*
* @param integer $limit
* @return \Phalcon\Mvc\Model\ResultsetInterface
*/
protected function findTasks($limit = 5)
{
$itemType = TaskModel::TYPE_REFUND;

View File

@ -4,18 +4,53 @@ namespace App\Console\Tasks;
use App\Models\Chapter as ChapterModel;
use App\Models\Course as CourseModel;
use App\Models\CourseUser as CourseUserModel;
use App\Models\User as UserModel;
use App\Repos\CourseUser as CourseUserRepo;
use Phalcon\Cli\Task;
use QL\QueryList;
class SpiderTask extends Task
{
public function testAction()
public function ctAction()
{
$subject = '1-1 课程简介(01:40)开始学习';
preg_match('/(\d{1,}-\d{1,})\s{1,}(.*?)\((.*?)\)/', $subject, $matches);
dd($matches);
$courses = CourseModel::query()
->where('class_id = 0')
->execute();
foreach ($courses as $course) {
$url = "http://www.imooc.com/learn/{$course->id}";
$ql = QueryList::getInstance()->get($url);
$userId = $ql->find('img.js-usercard-dialog')->attr('data-userid');
if ($userId) {
$user = UserModel::findFirst($userId);
if (!$user || !$user->avatar) {
$this->handleUserInfo2($course->id, $userId);
}
}
$ql->destruct();
echo "finished course " . $course->id . PHP_EOL;
}
}
public function user2Action()
{
$users = UserModel::query()
->where('edu_role = 2')
->andWhere('name = :name:', ['name' => ''])
->execute();
foreach ($users as $user) {
$this->handleUserInfo($user->id);
echo "finished user: {$user->id}" . PHP_EOL;
}
}
public function courseListAction($params)
@ -64,91 +99,191 @@ class SpiderTask extends Task
public function courseAction()
{
$courses = CourseModel::query()
->where('1 = 1')
->andWhere('id > :id:', ['id' => 1128])
->where('id = 762')
->orderBy('id asc')
->execute();
$baseUrl = 'http://www.imooc.com/learn';
$instance = QueryList::getInstance();
foreach ($courses as $course) {
$url = $baseUrl . '/' . $course->id;
$url = "http://www.imooc.com/learn/{$course->id}";
$ql = $instance->get($url);
$result = $this->handleCourseInfo($course, $ql);
if (!$result) {
continue;
}
//$this->handleCourseInfo($course, $ql);
$this->handleCourseChapters($course, $ql);
//$ql->destruct();
echo "finished course " . $course->id . PHP_EOL;
sleep(1);
}
}
public function teacherAction()
{
$courses = CourseModel::query()
->where('1 = 1')
->groupBy('user_id')
->execute();
foreach ($courses as $course) {
$this->handleTeacherInfo($course->user_id);
echo "finished teacher: {$course->user_id}" . PHP_EOL;
sleep(1);
}
}
public function userAction()
{
$users = UserModel::query()
->where('1 = 1')
->andWhere('name = :name:', ['name' => ''])
->where('edu_role = 2')
->execute();
foreach ($users as $user) {
$this->handleUserInfo($user->id);
echo "finished user: {$user->id}" . PHP_EOL;
sleep(1);
try {
$this->handleTeacherInfo2($user);
echo "finished teacher: {$user->id}" . PHP_EOL;
} catch (\Exception $e) {
echo $e->getMessage() . PHP_EOL;
}
}
}
protected function handleUserInfo($id)
protected function handleTeacherInfo2(UserModel $user)
{
$url = 'http://www.imooc.com/u/'. $id;
$url = "http://www.imooc.com/t/{$user->id}";
$ql = QueryList::getInstance()->get($url);
$data = [];
$data['id'] = $id;
$data['avatar'] = $ql->find('.user-pic-bg>img')->attr('src');
$data['name'] = $ql->find('h3.user-name>span')->text();
$data['about'] = $ql->find('p.user-desc')->text();
$user = new UserModel();
$user->save($data);
}
protected function handleTeacherInfo($id)
{
$url = 'http://www.imooc.com/t/'. $id;
$ql = QueryList::getInstance()->get($url);
$data = [];
$data['id'] = $id;
$data['avatar'] = $ql->find('img.tea-header')->attr('src');
$data['name'] = $ql->find('p.tea-nickname')->text();
$data['title'] = $ql->find('p.tea-professional')->text();
$data['about'] = $ql->find('p.tea-desc')->text();
$user = new UserModel();
$user->update($data);
}
$user->create($data);
public function userAction()
{
$users = UserModel::query()
->where('edu_role = 1')
->execute();
foreach ($users as $user) {
$this->handleUserInfo($user->id);
echo "finished user: {$user->id}" . PHP_EOL;
}
}
protected function handleUserInfo($id)
{
$url = 'https://www.imooc.com/u/' . $id;
$user = UserModel::findFirst($id);
try {
$ql = QueryList::getInstance()->get($url);
$data = [];
$data['avatar'] = $ql->find('.user-pic-bg>img')->attr('src');
$data['name'] = $ql->find('h3.user-name>span')->text();
$data['about'] = $ql->find('p.user-desc')->text();
print_r($data);
$user->update($data);
$ql->destruct();
} catch (\Exception $e) {
$user->update(['deleted' => 1]);
echo "user {$id} not found" . PHP_EOL;
}
}
protected function handleUserInfo2($courseId, $userId)
{
$url = 'https://www.imooc.com/u/' . $userId;
$user = UserModel::findFirst($userId);
try {
$ql = QueryList::getInstance()->get($url);
$data = [];
$data['avatar'] = $ql->find('.user-pic-bg>img')->attr('src');
$data['name'] = $ql->find('h3.user-name>span')->text();
$data['about'] = $ql->find('p.user-desc')->text();
$data['edu_role'] = UserModel::EDU_ROLE_TEACHER;
if ($user) {
$user->update($data);
} else {
$user = new UserModel();
$user->create($data);
}
$cuRepo = new CourseUserRepo();
$courseUser = $cuRepo->findCourseUser($courseId, $userId);
if (!$courseUser) {
$courseUser = new CourseUserModel();
$courseUser->course_id = $courseId;
$courseUser->user_id = $userId;
$courseUser->role_type = CourseUserModel::ROLE_TEACHER;
$courseUser->expire_time = strtotime('+15 years');
$courseUser->create();
}
echo "teacher {$userId} off " . PHP_EOL;
$ql->destruct();
} catch (\Exception $e) {
$user->update(['deleted' => 1]);
echo "user {$userId} not found" . PHP_EOL;
}
}
protected function handleTeacherInfo($courseId, $userId)
{
$url = "http://www.imooc.com/t/{$userId}";
$ql = QueryList::getInstance()->get($url);
$data = [];
$data['id'] = $userId;
$data['avatar'] = $ql->find('img.tea-header')->attr('src');
$data['name'] = $ql->find('p.tea-nickname')->text();
$data['title'] = $ql->find('p.tea-professional')->text();
$data['about'] = $ql->find('p.tea-desc')->text();
$data['edu_role'] = UserModel::EDU_ROLE_TEACHER;
$user = UserModel::findFirst($userId);
if ($user) {
$user->update($data);
} else {
$user = new UserModel();
$user->create($data);
}
$cuRepo = new CourseUserRepo();
$courseUser = $cuRepo->findCourseUser($courseId, $userId);
if (!$courseUser) {
$courseUser = new CourseUserModel();
$courseUser->course_id = $courseId;
$courseUser->user_id = $userId;
$courseUser->role_type = CourseUserModel::ROLE_TEACHER;
$courseUser->expire_time = strtotime('+15 years');
$courseUser->create();
}
$ql->destruct();
echo "teacher ok" . PHP_EOL;
}
protected function handleCourseInfo(CourseModel $course, QueryList $ql)
@ -160,27 +295,33 @@ class SpiderTask extends Task
$data['duration'] = $ql->find('.static-item:eq(1)>.meta-value')->text();
$data['score'] = $ql->find('.score-btn>.meta-value')->text();
if (empty($data['user_id'])) {
return false;
$data['attrs']['duration'] = $this->getCourseDuration($data['duration']);
$course->update($data);
if ($data['user_id']) {
$this->handleTeacherInfo($course->id, $data['user_id']);
}
$data['duration'] = $this->getCourseDuration($data['duration']);
return $course->update($data);
echo "course info ok" . PHP_EOL;
}
protected function handleCourseChapters(CourseModel $course, QueryList $ql)
{
echo "top chapter" . PHP_EOL;
$topChapters = $ql->rules([
'title' => ['.chapter>h3', 'text'],
'sub_chapter_html' => ['.chapter>.video', 'html'],
'title' => ['.chapter > h3', 'text'],
'sub_chapter_html' => ['.chapter > .video', 'html'],
])->query()->getData();
if ($topChapters->count() == 0) {
return false;
}
foreach ($topChapters->all() as $item) {
$data = [
'course_id' => $course->id,
'title' => $item['title'],
@ -208,16 +349,29 @@ class SpiderTask extends Task
}
foreach ($chapters->all() as $item) {
preg_match('/(\d{1,}-\d{1,})\s{1,}(.*?)\((.*?)\)/s', $item, $matches);
if (!isset($matches[3]) || empty($matches[3])) {
continue;
}
$data = [
'course_id' => $topChapter->course_id,
'parent_id' => $topChapter->id,
'title' => $matches[2],
'duration' => $this->getChapterDuration($matches[3]),
];
/**
*
* preg_match('/(\d{1,}-\d{1,})\s{1,}(.*?)\((.*?)\)/s', $item, $matches);
*
* if (!isset($matches[3]) || empty($matches[3])) {
* continue;
* }
*
* $data = [
* 'title' => $matches[2],
* 'duration' => $this->getChapterDuration($matches[3]),
* ];
*/
$title = str_replace(["开始学习", "\r", "\n", "\t", " "], "", $item);
$title = preg_replace('/\(\d{2}:\d{2}\)/', '', $title);
$data = [];
$data['course_id'] = $topChapter->course_id;
$data['parent_id'] = $topChapter->id;
$data['title'] = trim($title);
$model = new ChapterModel();
$model->create($data);
}
@ -231,6 +385,8 @@ class SpiderTask extends Task
if (preg_match('/(.*?)小时(.*?)分/s', $duration, $matches)) {
$hours = trim($matches[1]);
$minutes = trim($matches[2]);
} elseif (preg_match('/(.*?)小时/s', $duration, $matches)) {
$hours = trim($matches[1]);
} elseif (preg_match('/(.*?)分/s', $duration, $matches)) {
$minutes = trim($matches[1]);
}
@ -254,7 +410,7 @@ class SpiderTask extends Task
$mapping = [
'入门' => CourseModel::LEVEL_ENTRY,
'初级' => CourseModel::LEVEL_JUNIOR,
'中级' => CourseModel::LEVEL_MIDDLE,
'中级' => CourseModel::LEVEL_MEDIUM,
'高级' => CourseModel::LEVEL_SENIOR,
];

View File

@ -1,66 +0,0 @@
<?php
namespace App\Console\Tasks;
use App\Models\Course as CourseModel;
use App\Searchers\Course as CourseSearcher;
class SyncIndexTask extends Task
{
/**
* @var \App\Library\Cache\Backend\Redis
*/
protected $cache;
public function mainAction()
{
$this->cache = $this->getDI()->get('cache');
$this->handleCourseIndex();
}
protected function handleCourseIndex()
{
$keys = $this->cache->queryKeys('sync:index:course:');
if (empty($keys)) {
return;
}
$keys = array_slice($keys, 0, 100);
$searcher = new CourseSearcher();
$index = $searcher->getXS()->getIndex();
$index->openBuffer();
foreach ($keys as $key) {
$lastKey = $this->cache->getRawKeyName($key);
$content = $this->cache->get($lastKey);
if (empty($content->id)) {
continue;
}
$course = CourseModel::findFirstById($content->id);
$document = $searcher->setDocument($course);
if ($content->type == 'update') {
$index->update($document);
} elseif ($content->type == 'delete') {
$index->del($course->id);
} elseif ($content->type == 'restore') {
$index->update($document);
}
$this->cache->delete($lastKey);
}
$index->closeBuffer();
}
}

View File

@ -18,7 +18,7 @@ class UnlockUserTask extends Task
foreach ($users as $user) {
$user->locked = 0;
$user->locked_expiry = 0;
$user->lock_expiry = 0;
$user->update();
}
}
@ -26,7 +26,7 @@ class UnlockUserTask extends Task
/**
* 查找待解锁用户
*
* @param integer $limit
* @param int $limit
* @return \Phalcon\Mvc\Model\ResultsetInterface
*/
protected function findUsers($limit = 1000)
@ -35,7 +35,7 @@ class UnlockUserTask extends Task
$users = UserModel::query()
->where('locked = 1')
->andWhere('locked_expiry < :time:', ['time' => $time])
->andWhere('lock_expiry < :time:', ['time' => $time])
->limit($limit)
->execute();

View File

@ -15,9 +15,7 @@ class VodEventTask extends Task
{
$events = $this->pullEvents();
if (!$events) {
return;
}
if (!$events) return;
$handles = [];
@ -49,9 +47,7 @@ class VodEventTask extends Task
$chapter = $chapterRepo->findByFileId($fileId);
if (!$chapter) {
return;
}
if (!$chapter) return;
$vodService = new VodService();
@ -62,14 +58,14 @@ class VodEventTask extends Task
}
/**
* @var \stdClass $attrs
* @var array $attrs
*/
$attrs = $chapter->attrs;
$attrs->file_status = ChapterModel::FS_TRANSLATING;
$attrs->duration = $duration;
$attrs['file_status'] = ChapterModel::FS_TRANSLATING;
$attrs['duration'] = (int)$duration;
$chapter->update(['attrs' => $attrs]);
$this->updateCourseDuration($chapter->course_id);
$this->updateVodAttrs($chapter->course_id);
}
protected function handleProcedureStateChangedEvent($event)
@ -81,9 +77,7 @@ class VodEventTask extends Task
$chapter = $chapterRepo->findByFileId($fileId);
if (!$chapter) {
return;
}
if (!$chapter) return;
$failCount = $successCount = 0;
@ -97,26 +91,26 @@ class VodEventTask extends Task
}
}
$status = ChapterModel::FS_TRANSLATING;
$fileStatus = ChapterModel::FS_TRANSLATING;
/**
* 当有一个成功标记为成功
*/
if ($successCount > 0) {
$status = ChapterModel::FS_TRANSLATED;
$fileStatus = ChapterModel::FS_TRANSLATED;
} elseif ($failCount > 0) {
$status = ChapterModel::FS_FAILED;
$fileStatus = ChapterModel::FS_FAILED;
}
if ($status == ChapterModel::FS_TRANSLATING) {
if ($fileStatus == ChapterModel::FS_TRANSLATING) {
return;
}
/**
* @var \stdClass $attrs
* @var array $attrs
*/
$attrs = $chapter->attrs;
$attrs->file_status = $status;
$attrs['file_status'] = $fileStatus;
$chapter->update(['attrs' => $attrs]);
}
@ -147,11 +141,11 @@ class VodEventTask extends Task
return $result;
}
protected function updateCourseDuration($courseId)
protected function updateVodAttrs($courseId)
{
$courseStats = new CourseStatsService();
$courseStats->updateVodDuration($courseId);
$courseStats->updateVodAttrs($courseId);
}
}

View File

@ -31,7 +31,7 @@ class AuditController extends Controller
}
/**
* @Get("/{id}/show", name="admin.audit.show")
* @Get("/{id:[0-9]+}/show", name="admin.audit.show")
*/
public function showAction($id)
{

View File

@ -17,10 +17,10 @@ class CategoryController extends Controller
{
$parentId = $this->request->get('parent_id', 'int', 0);
$service = new CategoryService();
$categoryService = new CategoryService();
$parent = $service->getParentCategory($parentId);
$categories = $service->getChildCategories($parentId);
$parent = $categoryService->getParentCategory($parentId);
$categories = $categoryService->getChildCategories($parentId);
$this->view->setVar('parent', $parent);
$this->view->setVar('categories', $categories);
@ -33,9 +33,9 @@ class CategoryController extends Controller
{
$parentId = $this->request->get('parent_id', 'int', 0);
$service = new CategoryService();
$categoryService = new CategoryService();
$topCategories = $service->getTopCategories();
$topCategories = $categoryService->getTopCategories();
$this->view->setVar('parent_id', $parentId);
$this->view->setVar('top_categories', $topCategories);
@ -46,9 +46,9 @@ class CategoryController extends Controller
*/
public function createAction()
{
$service = new CategoryService();
$categoryService = new CategoryService();
$category = $service->createCategory();
$category = $categoryService->createCategory();
$location = $this->url->get(
['for' => 'admin.category.list'],
@ -64,27 +64,27 @@ class CategoryController extends Controller
}
/**
* @Get("/{id}/edit", name="admin.category.edit")
* @Get("/{id:[0-9]+}/edit", name="admin.category.edit")
*/
public function editAction($id)
{
$service = new CategoryService();
$categoryService = new CategoryService();
$category = $service->getCategory($id);
$category = $categoryService->getCategory($id);
$this->view->setVar('category', $category);
}
/**
* @Post("/{id}/update", name="admin.category.update")
* @Post("/{id:[0-9]+}/update", name="admin.category.update")
*/
public function updateAction($id)
{
$service = new CategoryService();
$categoryService = new CategoryService();
$category = $service->getCategory($id);
$category = $categoryService->getCategory($id);
$service->updateCategory($id);
$categoryService->updateCategory($id);
$location = $this->url->get(
['for' => 'admin.category.list'],
@ -100,13 +100,13 @@ class CategoryController extends Controller
}
/**
* @Post("/{id}/delete", name="admin.category.delete")
* @Post("/{id:[0-9]+}/delete", name="admin.category.delete")
*/
public function deleteAction($id)
{
$service = new CategoryService();
$categoryService = new CategoryService();
$service->deleteCategory($id);
$categoryService->deleteCategory($id);
$location = $this->request->getHTTPReferer();
@ -119,13 +119,13 @@ class CategoryController extends Controller
}
/**
* @Post("/{id}/restore", name="admin.category.restore")
* @Post("/{id:[0-9]+}/restore", name="admin.category.restore")
*/
public function restoreAction($id)
{
$service = new CategoryService();
$categoryService = new CategoryService();
$service->restoreCategory($id);
$categoryService->restoreCategory($id);
$location = $this->request->getHTTPReferer();

View File

@ -15,19 +15,19 @@ class ChapterController extends Controller
{
/**
* @Get("/{id}/lessons", name="admin.chapter.lessons")
* @Get("/{id:[0-9]+}/lessons", name="admin.chapter.lessons")
*/
public function lessonsAction($id)
{
$chapterService = new ChapterService();
$courseService = new CourseService();
$chapterService = new ChapterService();
$chapter = $chapterService->getChapter($id);
$course = $courseService->getCourse($chapter->course_id);
$lessons = $chapterService->getLessons($chapter->id);
$course = $courseService->getCourse($chapter->course_id);
$this->view->setVar('lessons', $lessons);
$this->view->setVar('chapter', $chapter);
$this->view->setVar('lessons', $lessons);
$this->view->setVar('course', $course);
}
@ -40,14 +40,14 @@ class ChapterController extends Controller
$parentId = $this->request->getQuery('parent_id');
$type = $this->request->getQuery('type');
$chapterService = new ChapterService();
$courseService = new CourseService();
$course = $chapterService->getCourse($courseId);
$courseChapters = $chapterService->getCourseChapters($courseId);
$course = $courseService->getCourse($courseId);
$chapters = $courseService->getChapters($courseId);
$this->view->setVar('course', $course);
$this->view->setVar('parent_id', $parentId);
$this->view->setVar('course_chapters', $courseChapters);
$this->view->setVar('chapters', $chapters);
if ($type == 'chapter') {
$this->view->pick('chapter/add_chapter');
@ -61,9 +61,9 @@ class ChapterController extends Controller
*/
public function createAction()
{
$service = new ChapterService();
$chapterService = new ChapterService();
$chapter = $service->createChapter();
$chapter = $chapterService->createChapter();
$location = $this->url->get([
'for' => 'admin.course.chapters',
@ -79,54 +79,57 @@ class ChapterController extends Controller
}
/**
* @Get("/{id}/edit", name="admin.chapter.edit")
* @Get("/{id:[0-9]+}/edit", name="admin.chapter.edit")
*/
public function editAction($id)
{
$contentService = new ChapterContentService();
$chapterService = new ChapterService();
$courseService = new CourseService();
$configService = new ConfigService();
$chapter = $chapterService->getChapter($id);
$course = $chapterService->getCourse($chapter->course_id);
$course = $courseService->getCourse($chapter->course_id);
$storage = $configService->getSectionConfig('storage');
switch ($course->model) {
case CourseModel::MODEL_VOD:
$vod = $contentService->getChapterVod($chapter->id);
$translatedFiles = $contentService->getTranslatedFiles($vod->file_id);
$this->view->setVar('vod', $vod);
$this->view->setVar('translated_files', $translatedFiles);
break;
case CourseModel::MODEL_LIVE:
$live = $contentService->getChapterLive($chapter->id);
$this->view->setVar('live', $live);
break;
case CourseModel::MODEL_ARTICLE:
$article = $contentService->getChapterArticle($chapter->id);
$this->view->setVar('article', $article);
break;
}
$this->view->setVar('storage', $storage);
$this->view->setVar('chapter', $chapter);
$this->view->setVar('course', $course);
if ($chapter->parent_id > 0) {
switch ($course->model) {
case CourseModel::MODEL_VOD:
$vod = $contentService->getChapterVod($chapter->id);
$vodFiles = $contentService->getVodFiles($chapter->id);
$this->view->setVar('vod', $vod);
$this->view->setVar('vod_files', $vodFiles);
break;
case CourseModel::MODEL_LIVE:
$live = $contentService->getChapterLive($chapter->id);
$this->view->setVar('live', $live);
break;
case CourseModel::MODEL_READ:
$read = $contentService->getChapterRead($chapter->id);
$this->view->setVar('read', $read);
break;
}
$this->view->pick('chapter/edit_lesson');
} else {
$this->view->pick('chapter/edit_chapter');
}
}
/**
* @Post("/{id}/update", name="admin.chapter.update")
* @Post("/{id:[0-9]+}/update", name="admin.chapter.update")
*/
public function updateAction($id)
{
$service = new ChapterService();
$chapterService = new ChapterService();
$chapter = $service->updateChapter($id);
$chapter = $chapterService->updateChapter($id);
if ($chapter->parent_id > 0) {
$location = $this->url->get([
@ -149,13 +152,13 @@ class ChapterController extends Controller
}
/**
* @Post("/{id}/delete", name="admin.chapter.delete")
* @Post("/{id:[0-9]+}/delete", name="admin.chapter.delete")
*/
public function deleteAction($id)
{
$service = new ChapterService();
$chapterService = new ChapterService();
$service->deleteChapter($id);
$chapterService->deleteChapter($id);
$location = $this->request->getHTTPReferer();
@ -168,13 +171,13 @@ class ChapterController extends Controller
}
/**
* @Post("/{id}/restore", name="admin.chapter.restore")
* @Post("/{id:[0-9]+}/restore", name="admin.chapter.restore")
*/
public function restoreAction($id)
{
$service = new ChapterService();
$chapterService = new ChapterService();
$service->restoreChapter($id);
$chapterService->restoreChapter($id);
$location = $this->request->getHTTPReferer();
@ -187,7 +190,7 @@ class ChapterController extends Controller
}
/**
* @Post("/{id}/content", name="admin.chapter.content")
* @Post("/{id:[0-9]+}/content", name="admin.chapter.content")
*/
public function contentAction($id)
{

View File

@ -11,27 +11,27 @@ class ConfigController extends Controller
{
/**
* @Route("/website", name="admin.config.website")
* @Route("/site", name="admin.config.site")
*/
public function websiteAction()
public function siteAction()
{
$section = 'website';
$section = 'site';
$service = new ConfigService();
$configService = new ConfigService();
if ($this->request->isPost()) {
$data = $this->request->getPost();
$service->updateSectionConfig($section, $data);
$configService->updateSectionConfig($section, $data);
return $this->ajaxSuccess(['msg' => '更新配置成功']);
} else {
$website = $service->getSectionConfig($section);
$site = $configService->getSectionConfig($section);
$this->view->setVar('website', $website);
$this->view->setVar('site', $site);
}
}
@ -42,19 +42,19 @@ class ConfigController extends Controller
{
$section = 'secret';
$service = new ConfigService();
$configService = new ConfigService();
if ($this->request->isPost()) {
$data = $this->request->getPost();
$service->updateStorageConfig($section, $data);
$configService->updateStorageConfig($section, $data);
return $this->ajaxSuccess(['msg' => '更新配置成功']);
} else {
$secret = $service->getSectionConfig($section);
$secret = $configService->getSectionConfig($section);
$this->view->setVar('secret', $secret);
}
@ -67,19 +67,19 @@ class ConfigController extends Controller
{
$section = 'storage';
$service = new ConfigService();
$configService = new ConfigService();
if ($this->request->isPost()) {
$data = $this->request->getPost();
$service->updateStorageConfig($section, $data);
$configService->updateStorageConfig($section, $data);
return $this->ajaxSuccess(['msg' => '更新配置成功']);
} else {
$storage = $service->getSectionConfig($section);
$storage = $configService->getSectionConfig($section);
$this->view->setVar('storage', $storage);
}
@ -92,19 +92,19 @@ class ConfigController extends Controller
{
$section = 'vod';
$service = new ConfigService();
$configService = new ConfigService();
if ($this->request->isPost()) {
$data = $this->request->getPost();
$service->updateVodConfig($section, $data);
$configService->updateVodConfig($section, $data);
return $this->ajaxSuccess(['msg' => '更新配置成功']);
} else {
$vod = $service->getSectionConfig($section);
$vod = $configService->getSectionConfig($section);
$this->view->setVar('vod', $vod);
}
@ -117,19 +117,19 @@ class ConfigController extends Controller
{
$section = 'live';
$service = new ConfigService();
$configService = new ConfigService();
if ($this->request->isPost()) {
$data = $this->request->getPost();
$service->updateLiveConfig($section, $data);
$configService->updateLiveConfig($section, $data);
return $this->ajaxSuccess(['msg' => '更新配置成功']);
} else {
$live = $service->getSectionConfig($section);
$live = $configService->getSectionConfig($section);
$ptt = json_decode($live->pull_trans_template);
@ -143,21 +143,21 @@ class ConfigController extends Controller
*/
public function paymentAction()
{
$service = new ConfigService();
$configService = new ConfigService();
if ($this->request->isPost()) {
$section = $this->request->getPost('section');
$data = $this->request->getPost();
$service->updateSectionConfig($section, $data);
$configService->updateSectionConfig($section, $data);
return $this->ajaxSuccess(['msg' => '更新配置成功']);
} else {
$alipay = $service->getSectionConfig('payment.alipay');
$wxpay = $service->getSectionConfig('payment.wxpay');
$alipay = $configService->getSectionConfig('payment.alipay');
$wxpay = $configService->getSectionConfig('payment.wxpay');
$this->view->setVar('alipay', $alipay);
$this->view->setVar('wxpay', $wxpay);
@ -171,19 +171,19 @@ class ConfigController extends Controller
{
$section = 'smser';
$service = new ConfigService();
$configService = new ConfigService();
if ($this->request->isPost()) {
$data = $this->request->getPost();
$service->updateSmserConfig($section, $data);
$configService->updateSmserConfig($section, $data);
return $this->ajaxSuccess(['msg' => '更新配置成功']);
} else {
$smser = $service->getSectionConfig($section);
$smser = $configService->getSectionConfig($section);
$template = json_decode($smser->template);
@ -199,19 +199,19 @@ class ConfigController extends Controller
{
$section = 'mailer';
$service = new ConfigService();
$configService = new ConfigService();
if ($this->request->isPost()) {
$data = $this->request->getPost();
$service->updateSectionConfig($section, $data);
$configService->updateSectionConfig($section, $data);
return $this->ajaxSuccess(['msg' => '更新配置成功']);
} else {
$mailer = $service->getSectionConfig($section);
$mailer = $configService->getSectionConfig($section);
$this->view->setVar('mailer', $mailer);
}
@ -224,13 +224,13 @@ class ConfigController extends Controller
{
$section = 'captcha';
$service = new ConfigService();
$configService = new ConfigService();
if ($this->request->isPost()) {
$data = $this->request->getPost();
$service->updateSectionConfig($section, $data);
$configService->updateSectionConfig($section, $data);
$content = [
'location' => $this->request->getHTTPReferer(),
@ -241,7 +241,7 @@ class ConfigController extends Controller
} else {
$captcha = $service->getSectionConfig($section);
$captcha = $configService->getSectionConfig($section);
$this->view->setVar('captcha', $captcha);
}
@ -254,19 +254,19 @@ class ConfigController extends Controller
{
$section = 'vip';
$service = new ConfigService();
$configService = new ConfigService();
if ($this->request->isPost()) {
$data = $this->request->getPost();
$service->updateSectionConfig($section, $data);
$configService->updateSectionConfig($section, $data);
return $this->ajaxSuccess(['msg' => '更新配置成功']);
} else {
$vip = $service->getSectionConfig($section);
$vip = $configService->getSectionConfig($section);
$this->view->setVar('vip', $vip);
}

View File

@ -16,17 +16,17 @@ class Controller extends \Phalcon\Mvc\Controller
public function beforeExecuteRoute(Dispatcher $dispatcher)
{
if ($this->notSafeRequest()) {
if ($this->isNotSafeRequest()) {
if (!$this->checkHttpReferer() || !$this->checkCsrfToken()) {
$dispatcher->forward([
'controller' => 'public',
'action' => 'csrf',
'action' => 'robot',
]);
return false;
}
}
$this->authUser = $this->getDI()->get('auth')->getAuthUser();
$this->authUser = $this->getAuthUser();
if (!$this->authUser) {
$dispatcher->forward([
@ -43,7 +43,7 @@ class Controller extends \Phalcon\Mvc\Controller
/**
* 管理员忽略权限检查
*/
if ($this->authUser->admin) {
if ($this->authUser->root == 1) {
return true;
}
@ -51,26 +51,21 @@ class Controller extends \Phalcon\Mvc\Controller
* 特例白名单
*/
$whitelist = [
'controller' => [
'public', 'index', 'storage', 'vod', 'test',
'xm_course',
],
'route' => [
'admin.package.guiding',
],
'controllers' => ['public', 'index', 'storage', 'vod', 'test', 'xm_course'],
'routes' => ['admin.package.guiding'],
];
/**
* 特定控制器忽略权限检查
*/
if (in_array($controller, $whitelist['controller'])) {
if (in_array($controller, $whitelist['controllers'])) {
return true;
}
/**
* 特定路由忽略权限检查
*/
if (in_array($route->getName(), $whitelist['route'])) {
if (in_array($route->getName(), $whitelist['routes'])) {
return true;
}
@ -110,4 +105,11 @@ class Controller extends \Phalcon\Mvc\Controller
}
}
protected function getAuthUser()
{
$auth = $this->getDI()->get('auth');
return $auth->getAuthInfo();
}
}

View File

@ -65,7 +65,7 @@ class CourseController extends Controller
}
/**
* @Get("/{id}/edit", name="admin.course.edit")
* @Get("/{id:[0-9]+}/edit", name="admin.course.edit")
*/
public function editAction($id)
{
@ -83,7 +83,7 @@ class CourseController extends Controller
}
/**
* @Post("/{id}/update", name="admin.course.update")
* @Post("/{id:[0-9]+}/update", name="admin.course.update")
*/
public function updateAction($id)
{
@ -97,7 +97,7 @@ class CourseController extends Controller
}
/**
* @Post("/{id}/delete", name="admin.course.delete")
* @Post("/{id:[0-9]+}/delete", name="admin.course.delete")
*/
public function deleteAction($id)
{
@ -114,7 +114,7 @@ class CourseController extends Controller
}
/**
* @Post("/{id}/restore", name="admin.course.restore")
* @Post("/{id:[0-9]+}/restore", name="admin.course.restore")
*/
public function restoreAction($id)
{
@ -131,7 +131,7 @@ class CourseController extends Controller
}
/**
* @Get("/{id}/chapters", name="admin.course.chapters")
* @Get("/{id:[0-9]+}/chapters", name="admin.course.chapters")
*/
public function chaptersAction($id)
{

View File

@ -0,0 +1,121 @@
<?php
namespace App\Http\Admin\Controllers;
use App\Http\Admin\Services\Help as HelpService;
/**
* @RoutePrefix("/admin/help")
*/
class HelpController extends Controller
{
/**
* @Get("/list", name="admin.help.list")
*/
public function listAction()
{
$helpService = new HelpService();
$helps = $helpService->getHelps();
$this->view->setVar('helps', $helps);
}
/**
* @Get("/add", name="admin.help.add")
*/
public function addAction()
{
}
/**
* @Post("/create", name="admin.help.create")
*/
public function createAction()
{
$helpService = new HelpService();
$helpService->createHelp();
$location = $this->url->get(['for' => 'admin.help.list']);
$content = [
'location' => $location,
'msg' => '创建帮助成功',
];
return $this->ajaxSuccess($content);
}
/**
* @Get("/{id:[0-9]+}/edit", name="admin.help.edit")
*/
public function editAction($id)
{
$helpService = new HelpService;
$help = $helpService->getHelp($id);
$this->view->setVar('help', $help);
}
/**
* @Post("/{id:[0-9]+}/update", name="admin.help.update")
*/
public function updateAction($id)
{
$helpService = new HelpService();
$helpService->updateHelp($id);
$location = $this->url->get(['for' => 'admin.help.list']);
$content = [
'location' => $location,
'msg' => '更新帮助成功',
];
return $this->ajaxSuccess($content);
}
/**
* @Post("/{id:[0-9]+}/delete", name="admin.help.delete")
*/
public function deleteAction($id)
{
$helpService = new HelpService();
$helpService->deleteHelp($id);
$location = $this->request->getHTTPReferer();
$content = [
'location' => $location,
'msg' => '删除帮助成功',
];
return $this->ajaxSuccess($content);
}
/**
* @Post("/{id:[0-9]+}/restore", name="admin.help.restore")
*/
public function restoreAction($id)
{
$helpService = new HelpService();
$helpService->restoreHelp($id);
$location = $this->request->getHTTPReferer();
$content = [
'location' => $location,
'msg' => '还原帮助成功',
];
return $this->ajaxSuccess($content);
}
}

View File

@ -2,7 +2,7 @@
namespace App\Http\Admin\Controllers;
use App\Http\Admin\Services\AuthMenu as AuthMenuService;
use App\Http\Admin\Services\Index as IndexService;
use Phalcon\Mvc\View;
/**
@ -16,13 +16,12 @@ class IndexController extends Controller
*/
public function indexAction()
{
$authMenu = new AuthMenuService();
$indexService = new IndexService();
$topMenus = $authMenu->getTopMenus();
$leftMenus = $authMenu->getLeftMenus();
$topMenus = $indexService->getTopMenus();
$leftMenus = $indexService->getLeftMenus();
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
$this->view->setVar('top_menus', $topMenus);
$this->view->setVar('left_menus', $leftMenus);
}
@ -32,23 +31,6 @@ class IndexController extends Controller
*/
public function mainAction()
{
/*
$service = new \App\Services\Order();
$course = \App\Models\Course::findFirstById(1152);
$service->createCourseOrder($course);
*/
/*
$service = new \App\Services\Order();
$package = \App\Models\Package::findFirstById(5);
$service->createPackageOrder($package);
*/
$refund = new \App\Services\Refund();
$order = \App\Models\Order::findFirstById(131);
$amount = $refund->getRefundAmount($order);
dd($amount);
}

View File

@ -64,7 +64,7 @@ class NavController extends Controller
}
/**
* @Get("/{id}/edit", name="admin.nav.edit")
* @Get("/{id:[0-9]+}/edit", name="admin.nav.edit")
*/
public function editAction($id)
{
@ -76,7 +76,7 @@ class NavController extends Controller
}
/**
* @Post("/{id}/update", name="admin.nav.update")
* @Post("/{id:[0-9]+}/update", name="admin.nav.update")
*/
public function updateAction($id)
{
@ -100,7 +100,7 @@ class NavController extends Controller
}
/**
* @Post("/{id}/delete", name="admin.nav.delete")
* @Post("/{id:[0-9]+}/delete", name="admin.nav.delete")
*/
public function deleteAction($id)
{
@ -119,7 +119,7 @@ class NavController extends Controller
}
/**
* @Post("/{id}/restore", name="admin.nav.restore")
* @Post("/{id:[0-9]+}/restore", name="admin.nav.restore")
*/
public function restoreAction($id)
{

View File

@ -31,7 +31,7 @@ class OrderController extends Controller
}
/**
* @Get("/{id}/show", name="admin.order.show")
* @Get("/{id:[0-9]+}/show", name="admin.order.show")
*/
public function showAction($id)
{
@ -40,16 +40,18 @@ class OrderController extends Controller
$order = $orderService->getOrder($id);
$trades = $orderService->getTrades($order->sn);
$refunds = $orderService->getRefunds($order->sn);
$account = $orderService->getAccount($order->user_id);
$user = $orderService->getUser($order->user_id);
$this->view->setVar('order', $order);
$this->view->setVar('trades', $trades);
$this->view->setVar('refunds', $refunds);
$this->view->setVar('account', $account);
$this->view->setVar('user', $user);
}
/**
* @Post("/{id}/close", name="admin.order.close")
* @Post("/{id:[0-9]+}/close", name="admin.order.close")
*/
public function closeAction($id)
{

View File

@ -69,7 +69,7 @@ class PackageController extends Controller
}
/**
* @Get("/{id}/edit", name="admin.package.edit")
* @Get("/{id:[0-9]+}/edit", name="admin.package.edit")
*/
public function editAction($id)
{
@ -83,7 +83,7 @@ class PackageController extends Controller
}
/**
* @Post("/{id}/update", name="admin.package.update")
* @Post("/{id:[0-9]+}/update", name="admin.package.update")
*/
public function updateAction($id)
{
@ -97,7 +97,7 @@ class PackageController extends Controller
}
/**
* @Post("/{id}/delete", name="admin.package.delete")
* @Post("/{id:[0-9]+}/delete", name="admin.package.delete")
*/
public function deleteAction($id)
{
@ -114,7 +114,7 @@ class PackageController extends Controller
}
/**
* @Post("/{id}/restore", name="admin.package.restore")
* @Post("/{id:[0-9]+}/restore", name="admin.package.restore")
*/
public function restoreAction($id)
{

View File

@ -15,9 +15,9 @@ class PageController extends Controller
*/
public function listAction()
{
$service = new PageService();
$pageService = new PageService();
$pager = $service->getPages();
$pager = $pageService->getPages();
$this->view->setVar('pager', $pager);
}
@ -35,9 +35,9 @@ class PageController extends Controller
*/
public function createAction()
{
$service = new PageService();
$pageService = new PageService();
$service->createPage();
$pageService->createPage();
$location = $this->url->get(['for' => 'admin.page.list']);
@ -50,25 +50,25 @@ class PageController extends Controller
}
/**
* @Get("/{id}/edit", name="admin.page.edit")
* @Get("/{id:[0-9]+}/edit", name="admin.page.edit")
*/
public function editAction($id)
{
$service = new PageService;
$pageService = new PageService;
$page = $service->getPage($id);
$page = $pageService->getPage($id);
$this->view->setVar('page', $page);
}
/**
* @Post("/{id}/update", name="admin.page.update")
* @Post("/{id:[0-9]+}/update", name="admin.page.update")
*/
public function updateAction($id)
{
$service = new PageService();
$pageService = new PageService();
$service->updatePage($id);
$pageService->updatePage($id);
$location = $this->url->get(['for' => 'admin.page.list']);
@ -81,13 +81,13 @@ class PageController extends Controller
}
/**
* @Post("/{id}/delete", name="admin.page.delete")
* @Post("/{id:[0-9]+}/delete", name="admin.page.delete")
*/
public function deleteAction($id)
{
$service = new PageService();
$pageService = new PageService();
$service->deletePage($id);
$pageService->deletePage($id);
$location = $this->request->getHTTPReferer();
@ -100,13 +100,13 @@ class PageController extends Controller
}
/**
* @Post("/{id}/restore", name="admin.page.restore")
* @Post("/{id:[0-9]+}/restore", name="admin.page.restore")
*/
public function restoreAction($id)
{
$service = new PageService();
$pageService = new PageService();
$service->restorePage($id);
$pageService->restorePage($id);
$location = $this->request->getHTTPReferer();

View File

@ -25,15 +25,13 @@ class PublicController extends \Phalcon\Mvc\Controller
}
/**
* @Route("/csrf", name="admin.csrf")
* @Route("/robot", name="admin.robot")
*/
public function csrfAction()
public function robotAction()
{
if ($this->request->isAjax()) {
return $this->ajaxError(['msg' => 'CSRF令牌验证失败']);
return $this->ajaxError(['msg' => '疑似机器人请求']);
}
$this->view->pick('public/csrf');
}
/**
@ -44,8 +42,6 @@ class PublicController extends \Phalcon\Mvc\Controller
if ($this->request->isAjax()) {
return $this->ajaxError(['msg' => '无相关操作权限']);
}
$this->view->pick('public/forbidden');
}
/**

View File

@ -31,7 +31,7 @@ class RefundController extends Controller
}
/**
* @Get("/{id}/show", name="admin.refund.show")
* @Get("/{id:[0-9]+}/show", name="admin.refund.show")
*/
public function showAction($id)
{
@ -40,16 +40,18 @@ class RefundController extends Controller
$refund = $refundService->getRefund($id);
$order = $refundService->getOrder($refund->order_sn);
$trade = $refundService->getTrade($refund->trade_sn);
$account = $refundService->getAccount($trade->user_id);
$user = $refundService->getUser($trade->user_id);
$this->view->setVar('refund', $refund);
$this->view->setVar('order', $order);
$this->view->setVar('trade', $trade);
$this->view->setVar('account', $account);
$this->view->setVar('user', $user);
}
/**
* @Post("/{id}/review", name="admin.refund.review")
* @Post("/{id:[0-9]+}/review", name="admin.refund.review")
*/
public function reviewAction($id)
{

View File

@ -23,16 +23,16 @@ class ReviewController extends Controller
*/
public function listAction()
{
$service = new ReviewService();
$reviewService = new ReviewService();
$pager = $service->getReviews();
$pager = $reviewService->getReviews();
$courseId = $this->request->getQuery('course_id', 'int', 0);
$course = null;
if ($courseId > 0) {
$course = $service->getCourse($courseId);
$course = $reviewService->getCourse($courseId);
}
$this->view->setVar('pager', $pager);
@ -40,25 +40,25 @@ class ReviewController extends Controller
}
/**
* @Get("/{id}/edit", name="admin.review.edit")
* @Get("/{id:[0-9]+}/edit", name="admin.review.edit")
*/
public function editAction($id)
{
$service = new ReviewService();
$reviewService = new ReviewService();
$review = $service->getReview($id);
$review = $reviewService->getReview($id);
$this->view->setVar('review', $review);
}
/**
* @Post("/{id}/update", name="admin.review.update")
* @Post("/{id:[0-9]+}/update", name="admin.review.update")
*/
public function updateAction($id)
{
$service = new ReviewService();
$reviewService = new ReviewService();
$service->updateReview($id);
$reviewService->updateReview($id);
$content = [
'msg' => '更新评价成功',
@ -68,13 +68,13 @@ class ReviewController extends Controller
}
/**
* @Post("/{id}/delete", name="admin.review.delete")
* @Post("/{id:[0-9]+}/delete", name="admin.review.delete")
*/
public function deleteAction($id)
{
$service = new ReviewService();
$reviewService = new ReviewService();
$service->deleteReview($id);
$reviewService->deleteReview($id);
$location = $this->request->getHTTPReferer();
@ -87,13 +87,13 @@ class ReviewController extends Controller
}
/**
* @Post("/{id}/restore", name="admin.review.restore")
* @Post("/{id:[0-9]+}/restore", name="admin.review.restore")
*/
public function restoreAction($id)
{
$service = new ReviewService();
$reviewService = new ReviewService();
$service->restoreReview($id);
$reviewService->restoreReview($id);
$location = $this->request->getHTTPReferer();

View File

@ -2,7 +2,6 @@
namespace App\Http\Admin\Controllers;
use App\Http\Admin\Services\AuthNode;
use App\Http\Admin\Services\Role as RoleService;
/**
@ -54,26 +53,21 @@ class RoleController extends Controller
}
/**
* @Get("/{id}/edit", name="admin.role.edit")
* @Get("/{id:[0-9]+}/edit", name="admin.role.edit")
*/
public function editAction($id)
{
$roleService = new RoleService();
$role = $roleService->getRole($id);
//dd($role->routes);
$adminNode = new AuthNode();
$nodes = $adminNode->getAllNodes();
$authNodes = $roleService->getAuthNodes();
$this->view->setVar('role', $role);
$this->view->setVar('nodes', kg_array_object($nodes));
$this->view->setVar('auth_nodes', $authNodes);
}
/**
* @Post("/{id}/update", name="admin.role.update")
* @Post("/{id:[0-9]+}/update", name="admin.role.update")
*/
public function updateAction($id)
{
@ -92,7 +86,7 @@ class RoleController extends Controller
}
/**
* @Post("/{id}/delete", name="admin.role.delete")
* @Post("/{id:[0-9]+}/delete", name="admin.role.delete")
*/
public function deleteAction($id)
{
@ -111,7 +105,7 @@ class RoleController extends Controller
}
/**
* @Post("/{id}/restore", name="admin.role.restore")
* @Post("/{id:[0-9]+}/restore", name="admin.role.restore")
*/
public function restoreAction($id)
{

View File

@ -26,7 +26,7 @@ class SessionController extends \Phalcon\Mvc\Controller
if (!$this->checkHttpReferer() || !$this->checkCsrfToken()) {
$this->dispatcher->forward([
'controller' => 'public',
'action' => 'forbidden',
'action' => 'robot',
]);
return false;
}

View File

@ -15,9 +15,9 @@ class SlideController extends Controller
*/
public function listAction()
{
$service = new SlideService();
$slideService = new SlideService();
$pager = $service->getSlides();
$pager = $slideService->getSlides();
$this->view->setVar('pager', $pager);
}
@ -35,9 +35,9 @@ class SlideController extends Controller
*/
public function createAction()
{
$service = new SlideService();
$slideService = new SlideService();
$slide = $service->createSlide();
$slide = $slideService->createSlide();
$location = $this->url->get([
'for' => 'admin.slide.edit',
@ -53,25 +53,25 @@ class SlideController extends Controller
}
/**
* @Get("/{id}/edit", name="admin.slide.edit")
* @Get("/{id:[0-9]+}/edit", name="admin.slide.edit")
*/
public function editAction($id)
{
$service = new SlideService();
$slideService = new SlideService();
$slide = $service->getSlide($id);
$slide = $slideService->getSlide($id);
$this->view->setVar('slide', $slide);
}
/**
* @Post("/{id}/update", name="admin.slide.update")
* @Post("/{id:[0-9]+}/update", name="admin.slide.update")
*/
public function updateAction($id)
{
$service = new SlideService();
$slideService = new SlideService();
$service->updateSlide($id);
$slideService->updateSlide($id);
$location = $this->url->get(['for' => 'admin.slide.list']);
@ -84,13 +84,13 @@ class SlideController extends Controller
}
/**
* @Post("/{id}/delete", name="admin.slide.delete")
* @Post("/{id:[0-9]+}/delete", name="admin.slide.delete")
*/
public function deleteAction($id)
{
$service = new SlideService();
$slideService = new SlideService();
$service->deleteSlide($id);
$slideService->deleteSlide($id);
$location = $this->request->getHTTPReferer();
@ -103,13 +103,13 @@ class SlideController extends Controller
}
/**
* @Post("/{id}/restore", name="admin.slide.restore")
* @Post("/{id:[0-9]+}/restore", name="admin.slide.restore")
*/
public function restoreAction($id)
{
$service = new SlideService();
$slideService = new SlideService();
$service->restoreSlide($id);
$slideService->restoreSlide($id);
$location = $this->request->getHTTPReferer();

View File

@ -25,9 +25,9 @@ class StudentController extends Controller
{
$courseId = $this->request->getQuery('course_id', 'int', '');
$service = new CourseStudentService();
$courseStudentService = new CourseStudentService();
$pager = $service->getCourseStudents();
$pager = $courseStudentService->getCourseStudents();
$this->view->setVar('pager', $pager);
$this->view->setVar('course_id', $courseId);
@ -48,9 +48,9 @@ class StudentController extends Controller
*/
public function createAction()
{
$service = new CourseStudentService();
$courseStudentService = new CourseStudentService();
$student = $service->createCourseStudent();
$student = $courseStudentService->createCourseStudent();
$location = $this->url->get(
['for' => 'admin.student.list'],
@ -73,11 +73,11 @@ class StudentController extends Controller
$courseId = $this->request->getQuery('course_id', 'int');
$userId = $this->request->getQuery('user_id', 'int');
$service = new CourseStudentService();
$courseStudentService = new CourseStudentService();
$courseStudent = $service->getCourseStudent($courseId, $userId);
$course = $service->getCourse($courseId);
$student = $service->getStudent($userId);
$courseStudent = $courseStudentService->getCourseStudent($courseId, $userId);
$course = $courseStudentService->getCourse($courseId);
$student = $courseStudentService->getStudent($userId);
$this->view->setVar('course_student', $courseStudent);
$this->view->setVar('course', $course);
@ -89,9 +89,9 @@ class StudentController extends Controller
*/
public function updateAction()
{
$service = new CourseStudentService();
$courseStudentService = new CourseStudentService();
$student = $service->updateCourseStudent();
$student = $courseStudentService->updateCourseStudent();
$location = $this->url->get(
['for' => 'admin.student.list'],
@ -111,9 +111,9 @@ class StudentController extends Controller
*/
public function learningAction()
{
$service = new CourseStudentService();
$courseStudentService = new CourseStudentService();
$pager = $service->getCourseLearnings();
$pager = $courseStudentService->getCourseLearnings();
$this->view->setVar('pager', $pager);
}

View File

@ -0,0 +1,117 @@
<?php
namespace App\Http\Admin\Controllers;
use App\Http\Admin\Services\Topic as TopicService;
/**
* @RoutePrefix("/admin/topic")
*/
class TopicController extends Controller
{
/**
* @Get("/list", name="admin.topic.list")
*/
public function listAction()
{
$topicService = new TopicService();
$pager = $topicService->getTopics();
$this->view->setVar('pager', $pager);
}
/**
* @Get("/add", name="admin.topic.add")
*/
public function addAction()
{
}
/**
* @Post("/create", name="admin.topic.create")
*/
public function createAction()
{
$topicService = new TopicService();
$topic = $topicService->createTopic();
$location = $this->url->get([
'for' => 'admin.topic.edit',
'id' => $topic->id,
]);
$content = [
'location' => $location,
'msg' => '创建话题成功',
];
return $this->ajaxSuccess($content);
}
/**
* @Get("/{id:[0-9]+}/edit", name="admin.topic.edit")
*/
public function editAction($id)
{
$topicService = new TopicService();
$topic = $topicService->getTopic($id);
$xmCourses = $topicService->getXmCourses($id);
$this->view->setVar('topic', $topic);
$this->view->setVar('xm_courses', $xmCourses);
}
/**
* @Post("/{id:[0-9]+}/update", name="admin.topic.update")
*/
public function updateAction($id)
{
$topicService = new TopicService();
$topicService->updateTopic($id);
$content = ['msg' => '更新话题成功'];
return $this->ajaxSuccess($content);
}
/**
* @Post("/{id:[0-9]+}/delete", name="admin.topic.delete")
*/
public function deleteAction($id)
{
$topicService = new TopicService();
$topicService->deleteTopic($id);
$content = [
'location' => $this->request->getHTTPReferer(),
'msg' => '删除话题成功',
];
return $this->ajaxSuccess($content);
}
/**
* @Post("/{id:[0-9]+}/restore", name="admin.topic.restore")
*/
public function restoreAction($id)
{
$topicService = new TopicService();
$topicService->restoreTopic($id);
$content = [
'location' => $this->request->getHTTPReferer(),
'msg' => '还原话题成功',
];
return $this->ajaxSuccess($content);
}
}

View File

@ -31,7 +31,7 @@ class TradeController extends Controller
}
/**
* @Get("/{id}/show", name="admin.trade.show")
* @Get("/{id:[0-9]+}/show", name="admin.trade.show")
*/
public function showAction($id)
{
@ -40,16 +40,18 @@ class TradeController extends Controller
$trade = $tradeService->getTrade($id);
$refunds = $tradeService->getRefunds($trade->sn);
$order = $tradeService->getOrder($trade->order_sn);
$account = $tradeService->getAccount($trade->user_id);
$user = $tradeService->getUser($trade->user_id);
$this->view->setVar('refunds', $refunds);
$this->view->setVar('trade', $trade);
$this->view->setVar('order', $order);
$this->view->setVar('account', $account);
$this->view->setVar('user', $user);
}
/**
* @Post("/{id}/close", name="admin.trade.close")
* @Post("/{id:[0-9]+}/close", name="admin.trade.close")
*/
public function closeAction($id)
{
@ -68,7 +70,7 @@ class TradeController extends Controller
}
/**
* @Post("/{id}/refund", name="admin.trade.refund")
* @Post("/{id:[0-9]+}/refund", name="admin.trade.refund")
*/
public function refundAction($id)
{

View File

@ -35,7 +35,7 @@ class UserController extends Controller
}
/**
* @Get("/{id}/show", name="admin.user.show")
* @Get("/{id:[0-9]+}/show", name="admin.user.show")
*/
public function showAction($id)
{
@ -74,7 +74,7 @@ class UserController extends Controller
}
/**
* @Get("/{id}/edit", name="admin.user.edit")
* @Get("/{id:[0-9]+}/edit", name="admin.user.edit")
*/
public function editAction($id)
{
@ -88,7 +88,7 @@ class UserController extends Controller
}
/**
* @Post("/{id}/update", name="admin.user.update")
* @Post("/{id:[0-9]+}/update", name="admin.user.update")
*/
public function updateAction($id)
{

View File

@ -3,7 +3,7 @@
namespace App\Http\Admin\Controllers;
use App\Models\Learning as LearningModel;
use App\Services\Learning as LearningService;
use App\Services\LearningSyncer as LearningSyncerService;
use App\Services\Vod as VodService;
use Phalcon\Mvc\View;
@ -58,9 +58,9 @@ class VodController extends Controller
$learning->chapter_id = $query['chapter_id'];
$learning->position = $query['position'];
$learningService = new LearningService();
$syncerService = new LearningSyncerService();
$learningService->save($learning, $query['timeout']);
$syncerService->save($learning, $query['timeout']);
return $this->ajaxSuccess();
}

View File

@ -17,7 +17,7 @@ class Module implements ModuleDefinitionInterface
public function registerServices(DiInterface $di)
{
$di->set('view', function () {
$di->setShared('view', function () {
$view = new View();
$view->setViewsDir(__DIR__ . '/Views');
$view->registerEngines([

View File

@ -8,7 +8,7 @@ class AuthMenu extends UserComponent
{
protected $nodes = [];
protected $authNodes = [];
protected $ownedRoutes = [];
protected $owned1stLevelIds = [];
protected $owned2ndLevelIds = [];
@ -17,8 +17,8 @@ class AuthMenu extends UserComponent
public function __construct()
{
$this->authUser = $this->getAuthUser();
$this->nodes = $this->getAllNodes();
$this->authUser = $this->getAuthInfo();
$this->authNodes = $this->getAuthNodes();
$this->setOwnedLevelIds();
}
@ -26,8 +26,8 @@ class AuthMenu extends UserComponent
{
$menus = [];
foreach ($this->nodes as $node) {
if ($this->authUser->admin || in_array($node['id'], $this->owned1stLevelIds)) {
foreach ($this->authNodes as $node) {
if ($this->authUser->root || in_array($node['id'], $this->owned1stLevelIds)) {
$menus[] = [
'id' => $node['id'],
'label' => $node['label'],
@ -35,17 +35,17 @@ class AuthMenu extends UserComponent
}
}
return kg_array_object($menus);
return $menus;
}
public function getLeftMenus()
{
$menus = [];
foreach ($this->nodes as $key => $level) {
foreach ($this->authNodes as $key => $level) {
foreach ($level['child'] as $key2 => $level2) {
foreach ($level2['child'] as $key3 => $level3) {
$hasRight = $this->authUser->admin || in_array($level3['id'], $this->owned3rdLevelIds);
$hasRight = $this->authUser->root || in_array($level3['id'], $this->owned3rdLevelIds);
if ($level3['type'] == 'menu' && $hasRight) {
$menus[$key]['id'] = $level['id'];
$menus[$key]['label'] = $level['label'];
@ -61,7 +61,7 @@ class AuthMenu extends UserComponent
}
}
return kg_array_object($menus);
return $menus;
}
protected function setOwnedLevelIds()
@ -92,7 +92,7 @@ class AuthMenu extends UserComponent
{
$mapping = [];
foreach ($this->nodes as $level) {
foreach ($this->authNodes as $level) {
foreach ($level['child'] as $level2) {
foreach ($level2['child'] as $level3) {
if ($level3['type'] == 'menu') {
@ -105,18 +105,18 @@ class AuthMenu extends UserComponent
return $mapping;
}
protected function getAllNodes()
protected function getAuthNodes()
{
$authNode = new AuthNode();
return $authNode->getAllNodes();
return $authNode->getNodes();
}
protected function getAuthUser()
protected function getAuthInfo()
{
$auth = $this->getDI()->get('auth');
return $auth->getAuthUser();
return $auth->getAuthInfo();
}
}

View File

@ -5,7 +5,7 @@ namespace App\Http\Admin\Services;
class AuthNode extends Service
{
public function getAllNodes()
public function getNodes()
{
$nodes = [];
@ -123,6 +123,37 @@ class AuthNode extends Service
],
],
],
[
'id' => '1-4',
'label' => '话题管理',
'type' => 'menu',
'child' => [
[
'id' => '1-4-1',
'label' => '话题列表',
'type' => 'menu',
'route' => 'admin.topic.list',
],
[
'id' => '1-4-2',
'label' => '添加话题',
'type' => 'menu',
'route' => 'admin.topic.add',
],
[
'id' => '1-4-3',
'label' => '编辑话题',
'type' => 'button',
'route' => 'admin.topic.edit',
],
[
'id' => '1-4-4',
'label' => '删除话题',
'type' => 'button',
'route' => 'admin.topic.delete',
],
],
],
],
];
@ -290,6 +321,37 @@ class AuthNode extends Service
],
],
],
[
'id' => '2-7',
'label' => '帮助管理',
'type' => 'menu',
'child' => [
[
'id' => '2-7-1',
'label' => '帮助列表',
'type' => 'menu',
'route' => 'admin.help.list',
],
[
'id' => '2-7-2',
'label' => '添加帮助',
'type' => 'menu',
'route' => 'admin.help.add',
],
[
'id' => '2-7-3',
'label' => '编辑帮助',
'type' => 'button',
'route' => 'admin.help.edit',
],
[
'id' => '2-7-4',
'label' => '删除帮助',
'type' => 'button',
'route' => 'admin.help.delete',
],
],
],
],
];
@ -515,7 +577,7 @@ class AuthNode extends Service
'id' => '5-1-1',
'label' => '网站设置',
'type' => 'menu',
'route' => 'admin.config.website',
'route' => 'admin.config.site',
],
[
'id' => '5-1-2',

View File

@ -4,9 +4,9 @@ namespace App\Http\Admin\Services;
use App\Models\Role as RoleModel;
use App\Models\User as UserModel;
use Phalcon\Mvc\User\Component as UserComponent;
use App\Repos\Role as RoleRepo;
class AuthUser extends UserComponent
class AuthUser extends \Phalcon\Mvc\User\Component
{
/**
@ -17,11 +17,15 @@ class AuthUser extends UserComponent
*/
public function hasPermission($route)
{
$authUser = $this->getAuthUser();
$authUser = $this->getAuthInfo();
if ($authUser->admin) return true;
if ($authUser->root) {
return true;
}
if (in_array($route, $authUser->routes)) return true;
if (in_array($route, $authUser->routes)) {
return true;
}
return false;
}
@ -31,27 +35,23 @@ class AuthUser extends UserComponent
*
* @param UserModel $user
*/
public function setAuthUser(UserModel $user)
public function setAuthInfo(UserModel $user)
{
$role = RoleModel::findFirstById($user->admin_role);
$roleRepo = new RoleRepo();
if ($role->id == RoleModel::ROLE_ADMIN) {
$admin = 1;
$routes = [];
} else {
$admin = 0;
$routes = $role->routes;
}
$role = $roleRepo->findById($user->admin_role);
$authKey = $this->getAuthKey();
$root = $role->id == RoleModel::ROLE_ROOT ? 1 : 0;
$authUser = new \stdClass();
$authUser->id = $user->id;
$authUser->name = $user->name;
$authUser->avatar = $user->avatar;
$authUser->admin = $admin;
$authUser->routes = $routes;
$authUser->routes = $role->routes;
$authUser->root = $root;
$authKey = $this->getAuthKey();
$this->session->set($authKey, $authUser);
}
@ -59,7 +59,7 @@ class AuthUser extends UserComponent
/**
* 清除会话
*/
public function removeAuthUser()
public function removeAuthInfo()
{
$authKey = $this->getAuthKey();
@ -71,7 +71,7 @@ class AuthUser extends UserComponent
*
* @return mixed
*/
public function getAuthUser()
public function getAuthInfo()
{
$authKey = $this->getAuthKey();
@ -85,7 +85,7 @@ class AuthUser extends UserComponent
*/
public function getAuthKey()
{
return 'admin';
return 'admin_info';
}
}

View File

@ -91,6 +91,8 @@ class Category extends Service
$category->update();
$this->updateCategoryStats($category);
return $category;
}
@ -114,10 +116,19 @@ class Category extends Service
if (isset($post['published'])) {
$data['published'] = $validator->checkPublishStatus($post['published']);
if ($category->parent_id == 0) {
if ($category->published == 0 && $post['published'] == 1) {
$this->enableChildCategories($category->id);
} elseif ($category->published == 1 && $post['published'] == 0) {
$this->disableChildCategories($category->id);
}
}
}
$category->update($data);
$this->updateCategoryStats($category);
return $category;
}
@ -125,14 +136,16 @@ class Category extends Service
{
$category = $this->findOrFail($id);
if ($category->deleted == 1) {
return false;
}
$validator = new CategoryValidator();
$validator->checkDeleteAbility($category);
$category->deleted = 1;
$category->update();
$this->updateCategoryStats($category);
return $category;
}
@ -140,17 +153,60 @@ class Category extends Service
{
$category = $this->findOrFail($id);
if ($category->deleted == 0) {
return false;
}
$category->deleted = 0;
$category->update();
$this->updateCategoryStats($category);
return $category;
}
protected function updateCategoryStats(CategoryModel $category)
{
$categoryRepo = new CategoryRepo();
if ($category->parent_id > 0) {
$category = $categoryRepo->findById($category->parent_id);
}
$childCount = $categoryRepo->countChildCategories($category->id);
$category->child_count = $childCount;
$category->update();
}
protected function enableChildCategories($parentId)
{
$categoryRepo = new CategoryRepo();
$categories = $categoryRepo->findAll(['parent_id' => $parentId]);
if ($categories->count() == 0) {
return;
}
foreach ($categories as $category) {
$category->published = 1;
$category->update();
}
}
protected function disableChildCategories($parentId)
{
$categoryRepo = new CategoryRepo();
$categories = $categoryRepo->findAll(['parent_id' => $parentId]);
if ($categories->count() == 0) {
return;
}
foreach ($categories as $category) {
$category->published = 0;
$category->update();
}
}
protected function findOrFail($id)
{
$validator = new CategoryValidator();

View File

@ -12,28 +12,6 @@ use App\Validators\Chapter as ChapterValidator;
class Chapter extends Service
{
public function getCourse($courseId)
{
$courseRepo = new CourseRepo();
$result = $courseRepo->findById($courseId);
return $result;
}
public function getCourseChapters($courseId)
{
$chapterRepo = new ChapterRepo();
$result = $chapterRepo->findAll([
'course_id' => $courseId,
'parent_id' => 0,
'deleted' => 0,
]);
return $result;
}
public function getLessons($parentId)
{
$deleted = $this->request->getQuery('deleted', 'int', 0);
@ -117,7 +95,7 @@ class Chapter extends Service
if (isset($post['published'])) {
$data['published'] = $validator->checkPublishStatus($post['published']);
if ($post['published'] == 1) {
if ($chapter->published == 0 && $post['published'] == 1) {
$validator->checkPublishAbility($chapter);
}
}
@ -134,17 +112,16 @@ class Chapter extends Service
{
$chapter = $this->findOrFail($id);
if ($chapter->deleted == 1) {
return false;
}
$validator = new ChapterValidator();
$validator->checkDeleteAbility($chapter);
$chapter->deleted = 1;
$chapter->update();
if ($chapter->parent_id == 0) {
$this->deleteChildChapters($chapter->id);
}
$this->updateChapterStats($chapter);
$this->updateCourseStats($chapter);
return $chapter;
}
@ -153,57 +130,17 @@ class Chapter extends Service
{
$chapter = $this->findOrFail($id);
if ($chapter->deleted == 0) {
return false;
}
$chapter->deleted = 0;
$chapter->update();
if ($chapter->parent_id == 0) {
$this->restoreChildChapters($chapter->id);
}
$this->updateChapterStats($chapter);
$this->updateCourseStats($chapter);
return $chapter;
}
protected function deleteChildChapters($parentId)
{
$chapterRepo = new ChapterRepo();
$chapters = $chapterRepo->findAll(['parent_id' => $parentId]);
if ($chapters->count() == 0) {
return;
}
foreach ($chapters as $chapter) {
$chapter->deleted = 1;
$chapter->update();
}
}
protected function restoreChildChapters($parentId)
{
$chapterRepo = new ChapterRepo();
$chapters = $chapterRepo->findAll(['parent_id' => $parentId]);
if ($chapters->count() == 0) {
return;
}
foreach ($chapters as $chapter) {
$chapter->deleted = 0;
$chapter->update();
}
}
protected function updateChapterStats($chapter)
protected function updateChapterStats(ChapterModel $chapter)
{
$chapterRepo = new ChapterRepo();
@ -214,10 +151,9 @@ class Chapter extends Service
$lessonCount = $chapterRepo->countLessons($chapter->id);
$chapter->lesson_count = $lessonCount;
$chapter->update();
}
protected function updateCourseStats($chapter)
protected function updateCourseStats(ChapterModel $chapter)
{
$courseRepo = new CourseRepo();
@ -228,11 +164,11 @@ class Chapter extends Service
$courseStats->updateLessonCount($course->id);
if ($course->model == CourseModel::MODEL_VOD) {
$courseStats->updateVodDuration($course->id);
$courseStats->updateVodAttrs($course->id);
} elseif ($course->model == CourseModel::MODEL_LIVE) {
$courseStats->updateLiveDateRange($course->id);
} elseif ($course->model == CourseModel::MODEL_ARTICLE) {
$courseStats->updateArticleWordCount($course->id);
$courseStats->updateLiveAttrs($course->id);
} elseif ($course->model == CourseModel::MODEL_READ) {
$courseStats->updateReadAttrs($course->id);
}
}

View File

@ -7,10 +7,10 @@ use App\Models\Chapter as ChapterModel;
use App\Models\Course as CourseModel;
use App\Repos\Chapter as ChapterRepo;
use App\Repos\Course as CourseRepo;
use App\Services\ChapterVod as ChapterVodService;
use App\Services\CourseStats as CourseStatsService;
use App\Services\Vod as VodService;
use App\Validators\ChapterArticle as ChapterArticleValidator;
use App\Validators\ChapterLive as ChapterLiveValidator;
use App\Validators\ChapterRead as ChapterReadValidator;
use App\Validators\ChapterVod as ChapterVodValidator;
class ChapterContent extends Service
@ -34,48 +34,22 @@ class ChapterContent extends Service
return $result;
}
public function getChapterArticle($chapterId)
public function getChapterRead($chapterId)
{
$chapterRepo = new ChapterRepo();
$result = $chapterRepo->findChapterArticle($chapterId);
$result = $chapterRepo->findChapterRead($chapterId);
return $result;
}
public function getTranslatedFiles($fileId)
public function getVodFiles($chapterId)
{
if (!$fileId) return;
$chapterVodService = new ChapterVodService();
$vodService = new VodService();
$vodFiles = $chapterVodService->getVodFiles($chapterId);
$mediaInfo = $vodService->getMediaInfo($fileId);
if (!$mediaInfo) return;
$result = [];
$files = $mediaInfo['MediaInfoSet'][0]['TranscodeInfo']['TranscodeSet'];
foreach ($files as $file) {
if ($file['Definition'] == 0) {
continue;
}
$result[] = [
'play_url' => $vodService->getPlayUrl($file['Url']),
'width' => $file['Width'],
'height' => $file['Height'],
'definition' => $file['Definition'],
'duration' => kg_play_duration($file['Duration']),
'format' => pathinfo($file['Url'], PATHINFO_EXTENSION),
'size' => sprintf('%0.2f', $file['Size'] / 1024 / 1024),
'bit_rate' => intval($file['Bitrate'] / 1024),
];
}
return kg_array_object($result);
return kg_array_object($vodFiles);
}
public function updateChapterContent($chapterId)
@ -93,13 +67,13 @@ class ChapterContent extends Service
case CourseModel::MODEL_LIVE:
$this->updateChapterLive($chapter);
break;
case CourseModel::MODEL_ARTICLE:
$this->updateChapterArticle($chapter);
case CourseModel::MODEL_READ:
$this->updateChapterRead($chapter);
break;
}
}
protected function updateChapterVod($chapter)
protected function updateChapterVod(ChapterModel $chapter)
{
$post = $this->request->getPost();
@ -115,15 +89,28 @@ class ChapterContent extends Service
return;
}
$vod->update(['file_id' => $fileId]);
$vod->update([
'file_id' => $fileId,
'file_attrs' => '',
]);
/**
* @var array $attrs
*/
$attrs = $chapter->attrs;
$attrs->file_id = $fileId;
$attrs->file_status = ChapterModel::FS_UPLOADED;
$attrs['duration'] = 0;
$attrs['file_id'] = $fileId;
$attrs['file_status'] = ChapterModel::FS_UPLOADED;
$chapter->update(['attrs' => $attrs]);
$courseStats = new CourseStatsService();
$courseStats->updateVodAttrs($chapter->course_id);
}
protected function updateChapterLive($chapter)
protected function updateChapterLive(ChapterModel $chapter)
{
$post = $this->request->getPost();
@ -142,37 +129,50 @@ class ChapterContent extends Service
$live->update($data);
/**
* @var array $attrs
*/
$attrs = $chapter->attrs;
$attrs->start_time = $data['start_time'];
$attrs->end_time = $data['end_time'];
$attrs['start_time'] = $data['start_time'];
$attrs['end_time'] = $data['end_time'];
$chapter->update(['attrs' => $attrs]);
$courseStats = new CourseStatsService();
$courseStats->updateLiveDateRange($chapter->course_id);
$courseStats->updateLiveAttrs($chapter->course_id);
}
protected function updateChapterArticle($chapter)
protected function updateChapterRead(ChapterModel $chapter)
{
$post = $this->request->getPost();
$chapterRepo = new ChapterRepo();
$article = $chapterRepo->findChapterArticle($chapter->id);
$read = $chapterRepo->findChapterRead($chapter->id);
$validator = new ChapterArticleValidator();
$validator = new ChapterReadValidator();
$data = [];
$data['content'] = $validator->checkContent($post['content']);
$article->update($data);
$read->update($data);
/**
* @var array $attrs
*/
$attrs = $chapter->attrs;
$attrs->word_count = WordUtil::getWordCount($article->content);
$attrs['word_count'] = WordUtil::getWordCount($read->content);
$attrs['duration'] = WordUtil::getWordDuration($read->content);
$chapter->update(['attrs' => $attrs]);
$courseStats = new CourseStatsService();
$courseStats->updateArticleWordCount($chapter->course_id);
$courseStats->updateReadAttrs($chapter->course_id);
}
}

View File

@ -2,7 +2,6 @@
namespace App\Http\Admin\Services;
use App\Caches\Config as ConfigCache;
use App\Repos\Config as ConfigRepo;
class Config extends Service
@ -36,10 +35,6 @@ class Config extends Service
$item->update();
}
}
$configCache = new ConfigCache();
$configCache->delete();
}
public function updateStorageConfig($section, $config)

View File

@ -2,6 +2,7 @@
namespace App\Http\Admin\Services;
use App\Builders\CourseList as CourseListBuilder;
use App\Library\Paginator\Query as PagerQuery;
use App\Models\Course as CourseModel;
use App\Models\CourseCategory as CourseCategoryModel;
@ -14,7 +15,6 @@ use App\Repos\CourseCategory as CourseCategoryRepo;
use App\Repos\CourseRelated as CourseRelatedRepo;
use App\Repos\CourseUser as CourseUserRepo;
use App\Repos\User as UserRepo;
use App\Transformers\CourseList as CourseListTransformer;
use App\Validators\Course as CourseValidator;
class Course extends Service
@ -26,8 +26,9 @@ class Course extends Service
$params = $pagerQuery->getParams();
if (isset($params['xm_category_ids'])) {
$params['id'] = $this->getCategoryCourseIds($params['xm_category_ids']);
if (!empty($params['xm_category_ids'])) {
$xmCategoryIds = explode(',', $params['xm_category_ids']);
$params['category_id'] = count($xmCategoryIds) > 1 ? $xmCategoryIds : $xmCategoryIds[0];
}
$params['deleted'] = $params['deleted'] ?? 0;
@ -66,8 +67,6 @@ class Course extends Service
$course->create($data);
$this->eventsManager->fire('course:afterCreate', $this, $course);
return $course;
}
@ -137,8 +136,6 @@ class Course extends Service
$course->update($data);
$this->eventsManager->fire('course:afterUpdate', $this, $course);
return $course;
}
@ -146,16 +143,10 @@ class Course extends Service
{
$course = $this->findOrFail($id);
if ($course->deleted == 1) {
return false;
}
$course->deleted = 1;
$course->update();
$this->eventsManager->fire('course:afterDelete', $this, $course);
return $course;
}
@ -163,16 +154,10 @@ class Course extends Service
{
$course = $this->findOrFail($id);
if ($course->deleted == 0) {
return false;
}
$course->deleted = 0;
$course->update();
$this->eventsManager->fire('course:afterRestore', $this, $course);
return $course;
}
@ -308,7 +293,7 @@ class Course extends Service
return $result;
}
protected function saveTeachers($course, $teacherIds)
protected function saveTeachers(CourseModel $course, $teacherIds)
{
$courseRepo = new CourseRepo();
@ -351,7 +336,7 @@ class Course extends Service
}
}
protected function saveCategories($course, $categoryIds)
protected function saveCategories(CourseModel $course, $categoryIds)
{
$courseRepo = new CourseRepo();
@ -391,7 +376,7 @@ class Course extends Service
}
}
protected function saveRelatedCourses($course, $courseIds)
protected function saveRelatedCourses(CourseModel $course, $courseIds)
{
$courseRepo = new CourseRepo();
@ -452,39 +437,17 @@ class Course extends Service
}
}
protected function getCategoryCourseIds($categoryIds)
{
if (empty($categoryIds)) return [];
$courseCategoryRepo = new CourseCategoryRepo();
$categoryIds = explode(',', $categoryIds);
$relations = $courseCategoryRepo->findByCategoryIds($categoryIds);
$result = [];
if ($relations->count() > 0) {
foreach ($relations as $relation) {
$result[] = $relation->course_id;
}
}
return $result;
}
protected function handleCourses($pager)
{
if ($pager->total_items > 0) {
$transformer = new CourseListTransformer();
$builder = new CourseListBuilder();
$pipeA = $pager->items->toArray();
$pipeB = $transformer->handleCourses($pipeA);
$pipeC = $transformer->handleCategories($pipeB);
$pipeD = $transformer->arrayToObject($pipeC);
$pipeB = $builder->handleCategories($pipeA);
$pipeC = $builder->arrayToObject($pipeB);
$pager->items = $pipeD;
$pager->items = $pipeC;
}
return $pager;

View File

@ -2,14 +2,14 @@
namespace App\Http\Admin\Services;
use App\Builders\CourseUserList as CourseUserListBuilder;
use App\Builders\LearningList as LearningListBuilder;
use App\Library\Paginator\Query as PagerQuery;
use App\Models\CourseUser as CourseUserModel;
use App\Repos\Course as CourseRepo;
use App\Repos\CourseUser as CourseUserRepo;
use App\Repos\Learning as LearningRepo;
use App\Repos\User as UserRepo;
use App\Transformers\CourseUserList as CourseUserListTransformer;
use App\Transformers\LearningList as LearningListTransformer;
use App\Validators\CourseUser as CourseUserValidator;
class CourseStudent extends Service
@ -94,7 +94,7 @@ class CourseStudent extends Service
$courseUser->create($data);
$this->updateStudentCount($data['course_id']);
$this->updateUserCount($data['course_id']);
return $courseUser;
}
@ -122,7 +122,7 @@ class CourseStudent extends Service
return $courseStudent;
}
protected function updateStudentCount($courseId)
protected function updateUserCount($courseId)
{
$courseRepo = new CourseRepo();
@ -130,7 +130,7 @@ class CourseStudent extends Service
$updater = new CourseStatsUpdater();
$updater->updateStudentCount($course);
$updater->updateUserCount($course);
}
protected function findOrFail($courseId, $userId)
@ -146,12 +146,12 @@ class CourseStudent extends Service
{
if ($pager->total_items > 0) {
$transformer = new CourseUserListTransformer();
$builder = new CourseUserListBuilder();
$pipeA = $pager->items->toArray();
$pipeB = $transformer->handleCourses($pipeA);
$pipeC = $transformer->handleUsers($pipeB);
$pipeD = $transformer->arrayToObject($pipeC);
$pipeB = $builder->handleCourses($pipeA);
$pipeC = $builder->handleUsers($pipeB);
$pipeD = $builder->arrayToObject($pipeC);
$pager->items = $pipeD;
}
@ -163,13 +163,13 @@ class CourseStudent extends Service
{
if ($pager->total_items > 0) {
$transformer = new LearningListTransformer();
$builder = new LearningListBuilder();
$pipeA = $pager->items->toArray();
$pipeB = $transformer->handleCourses($pipeA);
$pipeC = $transformer->handleChapters($pipeB);
$pipeD = $transformer->handleUsers($pipeC);
$pipeE = $transformer->arrayToObject($pipeD);
$pipeB = $builder->handleCourses($pipeA);
$pipeC = $builder->handleChapters($pipeB);
$pipeD = $builder->handleUsers($pipeC);
$pipeE = $builder->arrayToObject($pipeD);
$pager->items = $pipeE;
}

View File

@ -0,0 +1,114 @@
<?php
namespace App\Http\Admin\Services;
use App\Models\Help as HelpModel;
use App\Repos\Help as HelpRepo;
use App\Validators\Help as HelpValidator;
class Help extends Service
{
public function getHelps()
{
$deleted = $this->request->getQuery('deleted', 'int', 0);
$helpRepo = new HelpRepo();
$helps = $helpRepo->findAll([
'deleted' => $deleted,
]);
return $helps;
}
public function getHelp($id)
{
$help = $this->findOrFail($id);
return $help;
}
public function createHelp()
{
$post = $this->request->getPost();
$validator = new HelpValidator();
$data = [];
$data['title'] = $validator->checkTitle($post['title']);
$data['content'] = $validator->checkContent($post['content']);
$data['priority'] = $validator->checkPriority($post['priority']);
$data['published'] = $validator->checkPublishStatus($post['published']);
$help = new HelpModel();
$help->create($data);
return $help;
}
public function updateHelp($id)
{
$help = $this->findOrFail($id);
$post = $this->request->getPost();
$validator = new HelpValidator();
$data = [];
if (isset($post['title'])) {
$data['title'] = $validator->checkTitle($post['title']);
}
if (isset($post['content'])) {
$data['content'] = $validator->checkContent($post['content']);
}
if (isset($post['priority'])) {
$data['priority'] = $validator->checkPriority($post['priority']);
}
if (isset($post['published'])) {
$data['published'] = $validator->checkPublishStatus($post['published']);
}
$help->update($data);
return $help;
}
public function deleteHelp($id)
{
$help = $this->findOrFail($id);
$help->deleted = 1;
$help->update();
return $help;
}
public function restoreHelp($id)
{
$help = $this->findOrFail($id);
$help->deleted = 0;
$help->update();
return $help;
}
protected function findOrFail($id)
{
$validator = new HelpValidator();
$result = $validator->checkHelp($id);
return $result;
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace App\Http\Admin\Services;
class Index extends Service
{
public function getTopMenus()
{
$authMenu = new AuthMenu();
$topMenus = $authMenu->getTopMenus();
return kg_array_object($topMenus);
}
public function getLeftMenus()
{
$authMenu = new AuthMenu();
$leftMenus = $authMenu->getLeftMenus();
return kg_array_object($leftMenus);
}
}

View File

@ -2,6 +2,7 @@
namespace App\Http\Admin\Services;
use App\Caches\NavList as NavListCache;
use App\Models\Nav as NavModel;
use App\Repos\Nav as NavRepo;
use App\Validators\Nav as NavValidator;
@ -95,6 +96,8 @@ class Nav extends Service
$nav->update();
$this->updateNavStats($nav);
return $nav;
}
@ -130,10 +133,19 @@ class Nav extends Service
if (isset($post['published'])) {
$data['published'] = $validator->checkPublishStatus($post['published']);
if ($nav->parent_id == 0) {
if ($nav->published == 0 && $post['published'] == 1) {
$this->enableChildNavs($nav->id);
} elseif ($nav->published == 1 && $post['published'] == 0) {
$this->disableChildNavs($nav->id);
}
}
}
$nav->update($data);
$this->updateNavStats($nav);
return $nav;
}
@ -141,14 +153,16 @@ class Nav extends Service
{
$nav = $this->findOrFail($id);
if ($nav->deleted == 1) {
return false;
}
$validator = new NavValidator();
$validator->checkDeleteAbility($nav);
$nav->deleted = 1;
$nav->update();
$this->updateNavStats($nav);
return $nav;
}
@ -156,17 +170,63 @@ class Nav extends Service
{
$nav = $this->findOrFail($id);
if ($nav->deleted == 0) {
return false;
}
$nav->deleted = 0;
$nav->update();
$this->updateNavStats($nav);
return $nav;
}
protected function updateNavStats(NavModel $nav)
{
$navRepo = new NavRepo();
if ($nav->parent_id > 0) {
$nav = $navRepo->findById($nav->parent_id);
}
$childCount = $navRepo->countChildNavs($nav->id);
$nav->child_count = $childCount;
$nav->update();
$cache = new NavListCache();
$cache->rebuild();
}
protected function enableChildNavs($parentId)
{
$navRepo = new NavRepo();
$navs = $navRepo->findAll(['parent_id' => $parentId]);
if ($navs->count() == 0) {
return;
}
foreach ($navs as $nav) {
$nav->published = 1;
$nav->update();
}
}
protected function disableChildNavs($parentId)
{
$navRepo = new NavRepo();
$navs = $navRepo->findAll(['parent_id' => $parentId]);
if ($navs->count() == 0) {
return;
}
foreach ($navs as $nav) {
$nav->published = 0;
$nav->update();
}
}
protected function findOrFail($id)
{
$validator = new NavValidator();

View File

@ -2,11 +2,12 @@
namespace App\Http\Admin\Services;
use App\Builders\OrderList as OrderListBuilder;
use App\Library\Paginator\Query as PaginateQuery;
use App\Models\Order as OrderModel;
use App\Repos\Account as AccountRepo;
use App\Repos\Order as OrderRepo;
use App\Repos\User as UserRepo;
use App\Transformers\OrderList as OrderListTransformer;
use App\Validators\Order as OrderValidator;
class Order extends Service
@ -55,6 +56,15 @@ class Order extends Service
return $user;
}
public function getAccount($userId)
{
$accountRepo = new AccountRepo();
$account = $accountRepo->findById($userId);
return $account;
}
public function getOrder($id)
{
$order = $this->findOrFail($id);
@ -87,12 +97,12 @@ class Order extends Service
{
if ($pager->total_items > 0) {
$transformer = new OrderListTransformer();
$builder = new OrderListBuilder();
$pipeA = $pager->items->toArray();
$pipeB = $transformer->handleItems($pipeA);
$pipeC = $transformer->handleUsers($pipeB);
$pipeD = $transformer->arrayToObject($pipeC);
$pipeB = $builder->handleItems($pipeA);
$pipeC = $builder->handleUsers($pipeB);
$pipeD = $builder->arrayToObject($pipeC);
$pager->items = $pipeD;
}

View File

@ -102,10 +102,6 @@ class Package extends Service
{
$package = $this->findOrFail($id);
if ($package->deleted == 1) {
return false;
}
$package->deleted = 1;
$package->update();
@ -117,10 +113,6 @@ class Package extends Service
{
$package = $this->findOrFail($id);
if ($package->deleted == 0) {
return false;
}
$package->deleted = 0;
$package->update();
@ -183,7 +175,7 @@ class Package extends Service
return $list;
}
protected function saveCourses($package, $courseIds)
protected function saveCourses(PackageModel $package, $courseIds)
{
$packageRepo = new PackageRepo();
@ -223,7 +215,7 @@ class Package extends Service
}
}
protected function updateCourseCount($package)
protected function updateCourseCount(PackageModel $package)
{
$packageRepo = new PackageRepo();

View File

@ -86,10 +86,6 @@ class Page extends Service
{
$page = $this->findOrFail($id);
if ($page->deleted == 1) {
return false;
}
$page->deleted = 1;
$page->update();
@ -101,10 +97,6 @@ class Page extends Service
{
$page = $this->findOrFail($id);
if ($page->deleted == 0) {
return false;
}
$page->deleted = 0;
$page->update();

Some files were not shown because too many files have changed in this diff Show More