mirror of
https://gitee.com/koogua/course-tencent-cloud.git
synced 2025-06-17 15:55:31 +08:00
疫情期间更新
This commit is contained in:
parent
57957f19eb
commit
7a4aa88218
@ -2,9 +2,9 @@
|
||||
|
||||
namespace App\Builders;
|
||||
|
||||
use Phalcon\Mvc\User\Component as UserComponent;
|
||||
use Phalcon\Mvc\User\Component;
|
||||
|
||||
class Builder extends UserComponent
|
||||
class Builder extends Component
|
||||
{
|
||||
|
||||
public function arrayToObject($array)
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Builders;
|
||||
|
||||
class CategoryList extends Builder
|
||||
class CategoryTreeList extends Builder
|
||||
{
|
||||
|
||||
public function handleTreeList($categories)
|
@ -4,7 +4,7 @@ namespace App\Builders;
|
||||
|
||||
use App\Models\Course as CourseModel;
|
||||
|
||||
class ChapterList extends Builder
|
||||
class ChapterTreeList extends Builder
|
||||
{
|
||||
|
||||
/**
|
99
app/Builders/CommentList.php
Normal file
99
app/Builders/CommentList.php
Normal file
@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace App\Builders;
|
||||
|
||||
use App\Repos\Chapter as ChapterRepo;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use App\Repos\User as UserRepo;
|
||||
|
||||
class CommentList extends Builder
|
||||
{
|
||||
|
||||
public function handleCourses($comments)
|
||||
{
|
||||
$courses = $this->getCourses($comments);
|
||||
|
||||
foreach ($comments as $key => $comment) {
|
||||
$comments[$key]['course'] = $courses[$comment['course_id']] ?? [];
|
||||
}
|
||||
|
||||
return $comments;
|
||||
}
|
||||
|
||||
public function handleChapters($comments)
|
||||
{
|
||||
$chapters = $this->getChapters($comments);
|
||||
|
||||
foreach ($comments as $key => $comment) {
|
||||
$comments[$key]['chapter'] = $chapters[$comment['chapter_id']] ?? [];
|
||||
}
|
||||
|
||||
return $comments;
|
||||
}
|
||||
|
||||
public function handleUsers($comments)
|
||||
{
|
||||
$users = $this->getUsers($comments);
|
||||
|
||||
foreach ($comments as $key => $comment) {
|
||||
$comments[$key]['user'] = $users[$comment['user_id']] ?? [];
|
||||
}
|
||||
|
||||
return $comments;
|
||||
}
|
||||
|
||||
public function getCourses($comments)
|
||||
{
|
||||
$ids = kg_array_column($comments, 'course_id');
|
||||
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
$courses = $courseRepo->findByIds($ids, ['id', 'title']);
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($courses->toArray() as $course) {
|
||||
$result[$course['id']] = $course;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getChapters($comments)
|
||||
{
|
||||
$ids = kg_array_column($comments, 'chapter_id');
|
||||
|
||||
$chapterRepo = new ChapterRepo();
|
||||
|
||||
$chapters = $chapterRepo->findByIds($ids, ['id', 'title']);
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($chapters->toArray() as $chapter) {
|
||||
$result[$chapter['id']] = $chapter;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getUsers($comments)
|
||||
{
|
||||
$ids = kg_array_column($comments, '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;
|
||||
}
|
||||
|
||||
}
|
70
app/Builders/ConsultList.php
Normal file
70
app/Builders/ConsultList.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace App\Builders;
|
||||
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use App\Repos\User as UserRepo;
|
||||
|
||||
class ConsultList extends Builder
|
||||
{
|
||||
|
||||
public function handleCourses($consults)
|
||||
{
|
||||
$courses = $this->getCourses($consults);
|
||||
|
||||
foreach ($consults as $key => $consult) {
|
||||
$consults[$key]['course'] = $courses[$consult['course_id']] ?? [];
|
||||
}
|
||||
|
||||
return $consults;
|
||||
}
|
||||
|
||||
public function handleUsers($consults)
|
||||
{
|
||||
$users = $this->getUsers($consults);
|
||||
|
||||
foreach ($consults as $key => $consult) {
|
||||
$consults[$key]['user'] = $users[$consult['user_id']] ?? [];
|
||||
}
|
||||
|
||||
return $consults;
|
||||
}
|
||||
|
||||
public function getCourses($consults)
|
||||
{
|
||||
$ids = kg_array_column($consults, 'course_id');
|
||||
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
$courses = $courseRepo->findByIds($ids, ['id', 'title']);
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($courses->toArray() as $course) {
|
||||
$result[$course['id']] = $course;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getUsers($consults)
|
||||
{
|
||||
$ids = kg_array_column($consults, '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;
|
||||
}
|
||||
|
||||
}
|
80
app/Builders/CourseFavoriteList.php
Normal file
80
app/Builders/CourseFavoriteList.php
Normal file
@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace App\Builders;
|
||||
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use App\Repos\User as UserRepo;
|
||||
|
||||
class CourseFavoriteList extends Builder
|
||||
{
|
||||
|
||||
public function handleCourses($relations)
|
||||
{
|
||||
$courses = $this->getCourses($relations);
|
||||
|
||||
foreach ($relations as $key => $value) {
|
||||
$relations[$key]['course'] = $courses[$value['course_id']];
|
||||
}
|
||||
|
||||
return $relations;
|
||||
}
|
||||
|
||||
public function handleUsers($relations)
|
||||
{
|
||||
$users = $this->getUsers($relations);
|
||||
|
||||
foreach ($relations as $key => $value) {
|
||||
$relations[$key]['user'] = $users[$value['user_id']];
|
||||
}
|
||||
|
||||
return $relations;
|
||||
}
|
||||
|
||||
public function getCourses($relations)
|
||||
{
|
||||
$ids = kg_array_column($relations, 'course_id');
|
||||
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
$columns = [
|
||||
'id', 'title', 'cover', 'summary',
|
||||
'market_price', 'vip_price', 'model', 'level', 'attrs',
|
||||
'user_count', 'lesson_count', 'review_count', 'favorite_count',
|
||||
];
|
||||
|
||||
$courses = $courseRepo->findByIds($ids, $columns);
|
||||
|
||||
$imgBaseUrl = kg_img_base_url();
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($courses->toArray() as $course) {
|
||||
$course['cover'] = $imgBaseUrl . $course['cover'];
|
||||
$course['attrs'] = json_decode($course['attrs'], true);
|
||||
$result[$course['id']] = $course;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getUsers($relations)
|
||||
{
|
||||
$ids = kg_array_column($relations, '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;
|
||||
}
|
||||
|
||||
}
|
@ -13,7 +13,7 @@ class CourseList extends Builder
|
||||
{
|
||||
$imgBaseUrl = kg_img_base_url();
|
||||
|
||||
$result = [];
|
||||
$list = [];
|
||||
|
||||
foreach ($courses as $course) {
|
||||
|
||||
@ -36,13 +36,13 @@ class CourseList extends Builder
|
||||
'categories' => $course['categories'],
|
||||
'user_count' => $course['user_count'],
|
||||
'lesson_count' => $course['lesson_count'],
|
||||
'thread_count' => $course['thread_count'],
|
||||
'comment_count' => $course['comment_count'],
|
||||
'review_count' => $course['review_count'],
|
||||
'favorite_count' => $course['favorite_count'],
|
||||
];
|
||||
}
|
||||
|
||||
return $result;
|
||||
return $list;
|
||||
}
|
||||
|
||||
public function handleCategories($courses)
|
||||
|
@ -30,34 +30,47 @@ class CourseUserList extends Builder
|
||||
return $relations;
|
||||
}
|
||||
|
||||
protected function getCourses($relations)
|
||||
public function getCourses($relations)
|
||||
{
|
||||
$ids = kg_array_column($relations, 'course_id');
|
||||
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
$courses = $courseRepo->findByIds($ids, ['id', 'title', 'cover'])->toArray();
|
||||
$columns = [
|
||||
'id', 'title', 'cover', 'summary',
|
||||
'market_price', 'vip_price', 'model', 'level', 'attrs',
|
||||
'user_count', 'lesson_count', 'review_count', 'favorite_count',
|
||||
];
|
||||
|
||||
$courses = $courseRepo->findByIds($ids, $columns);
|
||||
|
||||
$imgBaseUrl = kg_img_base_url();
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($courses as $course) {
|
||||
foreach ($courses->toArray() as $course) {
|
||||
$course['cover'] = $imgBaseUrl . $course['cover'];
|
||||
$course['attrs'] = json_decode($course['attrs'], true);
|
||||
$result[$course['id']] = $course;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function getUsers($relations)
|
||||
public function getUsers($relations)
|
||||
{
|
||||
$ids = kg_array_column($relations, 'user_id');
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar'])->toArray();
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar']);
|
||||
|
||||
$imgBaseUrl = kg_img_base_url();
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($users as $user) {
|
||||
foreach ($users->toArray() as $user) {
|
||||
$user['avatar'] = $imgBaseUrl . $user['avatar'];
|
||||
$result[$user['id']] = $user;
|
||||
}
|
||||
|
||||
|
@ -48,11 +48,11 @@ class LearningList extends Builder
|
||||
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
$courses = $courseRepo->findByIds($ids, ['id', 'title', 'cover'])->toArray();
|
||||
$courses = $courseRepo->findByIds($ids, ['id', 'title', 'cover']);
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($courses as $course) {
|
||||
foreach ($courses->toArray() as $course) {
|
||||
$result[$course['id']] = $course;
|
||||
}
|
||||
|
||||
@ -65,11 +65,11 @@ class LearningList extends Builder
|
||||
|
||||
$chapterRepo = new ChapterRepo();
|
||||
|
||||
$chapters = $chapterRepo->findByIds($ids, ['id', 'title'])->toArray();
|
||||
$chapters = $chapterRepo->findByIds($ids, ['id', 'title']);
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($chapters as $chapter) {
|
||||
foreach ($chapters->toArray() as $chapter) {
|
||||
$result[$chapter['id']] = $chapter;
|
||||
}
|
||||
|
||||
@ -82,11 +82,11 @@ class LearningList extends Builder
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar'])->toArray();
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar']);
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($users as $user) {
|
||||
foreach ($users->toArray() as $user) {
|
||||
$result[$user['id']] = $user;
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Builders;
|
||||
|
||||
class NavList extends Builder
|
||||
class NavTreeList extends Builder
|
||||
{
|
||||
|
||||
public function handleTreeList($navs)
|
@ -7,6 +7,7 @@ use App\Repos\User as UserRepo;
|
||||
|
||||
class OrderList extends Builder
|
||||
{
|
||||
|
||||
protected $imgBaseUrl;
|
||||
|
||||
public function __construct()
|
||||
@ -14,28 +15,64 @@ class OrderList extends Builder
|
||||
$this->imgBaseUrl = kg_img_base_url();
|
||||
}
|
||||
|
||||
public function handleItems($orders)
|
||||
/**
|
||||
* @param array $orders
|
||||
* @return array
|
||||
*/
|
||||
public function handleUsers(array $orders)
|
||||
{
|
||||
$itemInfo = [];
|
||||
$users = $this->getUsers($orders);
|
||||
|
||||
foreach ($orders as $key => $order) {
|
||||
switch ($order['item_type']) {
|
||||
case OrderModel::TYPE_COURSE:
|
||||
$itemInfo = $this->handleCourseInfo($order['item_info']);
|
||||
break;
|
||||
case OrderModel::TYPE_PACKAGE:
|
||||
$itemInfo = $this->handlePackageInfo($order['item_info']);
|
||||
break;
|
||||
case OrderModel::TYPE_REWARD:
|
||||
$itemInfo = $this->handleRewardInfo($order['item_info']);
|
||||
break;
|
||||
}
|
||||
$orders[$key]['user'] = $users[$order['user_id']];
|
||||
}
|
||||
|
||||
return $orders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $orders
|
||||
* @return array
|
||||
*/
|
||||
public function handleItems(array $orders)
|
||||
{
|
||||
foreach ($orders as $key => $order) {
|
||||
|
||||
$itemInfo = $this->handleItem($order);
|
||||
|
||||
$orders[$key]['item_info'] = $itemInfo;
|
||||
}
|
||||
|
||||
return $orders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $order
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function handleItem(array $order)
|
||||
{
|
||||
$itemInfo = [];
|
||||
|
||||
switch ($order['item_type']) {
|
||||
case OrderModel::ITEM_COURSE:
|
||||
$itemInfo = $this->handleCourseInfo($order['item_info']);
|
||||
break;
|
||||
case OrderModel::ITEM_PACKAGE:
|
||||
$itemInfo = $this->handlePackageInfo($order['item_info']);
|
||||
break;
|
||||
case OrderModel::ITEM_VIP:
|
||||
$itemInfo = $this->handleVipInfo($order['item_info']);
|
||||
break;
|
||||
}
|
||||
|
||||
return $itemInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $itemInfo
|
||||
* @return mixed
|
||||
*/
|
||||
protected function handleCourseInfo($itemInfo)
|
||||
{
|
||||
if (!empty($itemInfo) && is_string($itemInfo)) {
|
||||
@ -46,6 +83,10 @@ class OrderList extends Builder
|
||||
return $itemInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $itemInfo
|
||||
* @return mixed
|
||||
*/
|
||||
protected function handlePackageInfo($itemInfo)
|
||||
{
|
||||
if (!empty($itemInfo) && is_string($itemInfo)) {
|
||||
@ -58,6 +99,10 @@ class OrderList extends Builder
|
||||
return $itemInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $itemInfo
|
||||
* @return mixed
|
||||
*/
|
||||
protected function handleRewardInfo($itemInfo)
|
||||
{
|
||||
if (!empty($itemInfo) && is_string($itemInfo)) {
|
||||
@ -68,28 +113,34 @@ class OrderList extends Builder
|
||||
return $itemInfo;
|
||||
}
|
||||
|
||||
public function handleUsers($orders)
|
||||
/**
|
||||
* @param string $itemInfo
|
||||
* @return mixed
|
||||
*/
|
||||
protected function handleVipInfo($itemInfo)
|
||||
{
|
||||
$users = $this->getUsers($orders);
|
||||
|
||||
foreach ($orders as $key => $order) {
|
||||
$orders[$key]['user'] = $users[$order['user_id']];
|
||||
if (!empty($itemInfo) && is_string($itemInfo)) {
|
||||
$itemInfo = json_decode($itemInfo, true);
|
||||
}
|
||||
|
||||
return $orders;
|
||||
return $itemInfo;
|
||||
}
|
||||
|
||||
protected function getUsers($orders)
|
||||
/**
|
||||
* @param array $orders
|
||||
* @return array
|
||||
*/
|
||||
protected function getUsers(array $orders)
|
||||
{
|
||||
$ids = kg_array_column($orders, 'user_id');
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar'])->toArray();
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name']);
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($users as $user) {
|
||||
foreach ($users->toArray() as $user) {
|
||||
$result[$user['id']] = $user;
|
||||
}
|
||||
|
||||
|
@ -2,11 +2,23 @@
|
||||
|
||||
namespace App\Builders;
|
||||
|
||||
use App\Repos\Order as OrderRepo;
|
||||
use App\Repos\User as UserRepo;
|
||||
|
||||
class RefundList extends Builder
|
||||
{
|
||||
|
||||
public function handleOrders($trades)
|
||||
{
|
||||
$orders = $this->getOrders($trades);
|
||||
|
||||
foreach ($trades as $key => $trade) {
|
||||
$trades[$key]['order'] = $orders[$trade['order_id']];
|
||||
}
|
||||
|
||||
return $trades;
|
||||
}
|
||||
|
||||
public function handleUsers($refunds)
|
||||
{
|
||||
$users = $this->getUsers($refunds);
|
||||
@ -18,22 +30,34 @@ class RefundList extends Builder
|
||||
return $refunds;
|
||||
}
|
||||
|
||||
protected function getUsers($refunds)
|
||||
public function getOrders($trades)
|
||||
{
|
||||
$ids = kg_array_column($trades, 'order_id');
|
||||
|
||||
$orderRepo = new OrderRepo();
|
||||
|
||||
$orders = $orderRepo->findByIds($ids, ['id', 'sn', 'subject', 'amount']);
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($orders->toArray() as $order) {
|
||||
$result[$order['id']] = $order;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getUsers($refunds)
|
||||
{
|
||||
$ids = kg_array_column($refunds, 'user_id');
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar']);
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name']);
|
||||
|
||||
$result = [];
|
||||
|
||||
$imgBaseUrl = kg_img_base_url();
|
||||
|
||||
foreach ($users->toArray() as $user) {
|
||||
|
||||
$user['avatar'] = $imgBaseUrl . $user['avatar'];
|
||||
|
||||
$result[$user['id']] = $user;
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ class ReviewList extends Builder
|
||||
return $reviews;
|
||||
}
|
||||
|
||||
protected function getCourses($reviews)
|
||||
public function getCourses($reviews)
|
||||
{
|
||||
$ids = kg_array_column($reviews, 'course_id');
|
||||
|
||||
@ -47,7 +47,7 @@ class ReviewList extends Builder
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function getUsers($reviews)
|
||||
public function getUsers($reviews)
|
||||
{
|
||||
$ids = kg_array_column($reviews, 'user_id');
|
||||
|
||||
@ -55,10 +55,10 @@ class ReviewList extends Builder
|
||||
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar']);
|
||||
|
||||
$result = [];
|
||||
|
||||
$imgBaseUrl = kg_img_base_url();
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($users->toArray() as $user) {
|
||||
$user['avatar'] = $imgBaseUrl . $user['avatar'];
|
||||
$result[$user['id']] = $user;
|
||||
|
@ -2,11 +2,23 @@
|
||||
|
||||
namespace App\Builders;
|
||||
|
||||
use App\Repos\Order as OrderRepo;
|
||||
use App\Repos\User as UserRepo;
|
||||
|
||||
class TradeList extends Builder
|
||||
{
|
||||
|
||||
public function handleOrders($trades)
|
||||
{
|
||||
$orders = $this->getOrders($trades);
|
||||
|
||||
foreach ($trades as $key => $trade) {
|
||||
$trades[$key]['order'] = $orders[$trade['order_id']];
|
||||
}
|
||||
|
||||
return $trades;
|
||||
}
|
||||
|
||||
public function handleUsers($trades)
|
||||
{
|
||||
$users = $this->getUsers($trades);
|
||||
@ -18,17 +30,34 @@ class TradeList extends Builder
|
||||
return $trades;
|
||||
}
|
||||
|
||||
protected function getUsers($trades)
|
||||
public function getOrders($trades)
|
||||
{
|
||||
$ids = kg_array_column($trades, 'order_id');
|
||||
|
||||
$orderRepo = new OrderRepo();
|
||||
|
||||
$orders = $orderRepo->findByIds($ids, ['id', 'sn', 'subject', 'amount']);
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($orders->toArray() as $order) {
|
||||
$result[$order['id']] = $order;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getUsers($trades)
|
||||
{
|
||||
$ids = kg_array_column($trades, 'user_id');
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar'])->toArray();
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name']);
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($users as $user) {
|
||||
foreach ($users->toArray() as $user) {
|
||||
$result[$user['id']] = $user;
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ class UserList extends Builder
|
||||
|
||||
public function handleEduRoles($users)
|
||||
{
|
||||
$roles = $this->getEduRoles($users);
|
||||
$roles = $this->getEduRoles();
|
||||
|
||||
foreach ($users as $key => $user) {
|
||||
$users[$key]['edu_role'] = $roles[$user['edu_role']] ?? ['id' => 0, 'name' => 'N/A'];
|
||||
@ -41,24 +41,24 @@ class UserList extends Builder
|
||||
return $users;
|
||||
}
|
||||
|
||||
private function getAdminRoles($users)
|
||||
protected function getAdminRoles($users)
|
||||
{
|
||||
$ids = kg_array_column($users, 'admin_role');
|
||||
|
||||
$roleRepo = new RoleRepo();
|
||||
|
||||
$roles = $roleRepo->findByIds($ids, ['id', 'name'])->toArray();
|
||||
$roles = $roleRepo->findByIds($ids, ['id', 'name']);
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($roles as $role) {
|
||||
foreach ($roles->toArray() as $role) {
|
||||
$result[$role['id']] = $role;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function getEduRoles()
|
||||
protected function getEduRoles()
|
||||
{
|
||||
$result = [
|
||||
UserModel::EDU_ROLE_STUDENT => [
|
||||
|
@ -2,11 +2,14 @@
|
||||
|
||||
namespace App\Caches;
|
||||
|
||||
abstract class Cache extends \Phalcon\Mvc\User\Component
|
||||
use Phalcon\Cache\Backend\Redis as RedisCache;
|
||||
use Phalcon\Mvc\User\Component;
|
||||
|
||||
abstract class Cache extends Component
|
||||
{
|
||||
|
||||
/**
|
||||
* @var \Phalcon\Cache\Backend\Redis
|
||||
* @var RedisCache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace App\Caches;
|
||||
|
||||
use App\Models\Category as CategoryModel;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
|
||||
class CategoryList extends Cache
|
||||
{
|
||||
@ -25,6 +26,9 @@ class CategoryList extends Cache
|
||||
*/
|
||||
public function getContent($id = null)
|
||||
{
|
||||
/**
|
||||
* @var Resultset $categories
|
||||
*/
|
||||
$categories = CategoryModel::query()
|
||||
->columns(['id', 'parent_id', 'name', 'priority', 'level', 'path'])
|
||||
->where('published = 1 AND deleted = 0')
|
||||
|
@ -2,8 +2,9 @@
|
||||
|
||||
namespace App\Caches;
|
||||
|
||||
use App\Builders\CategoryList as CategoryTreeListBuilder;
|
||||
use App\Builders\CategoryTreeList as CategoryTreeListBuilder;
|
||||
use App\Models\Category as CategoryModel;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
|
||||
class CategoryTreeList extends Cache
|
||||
{
|
||||
@ -17,11 +18,14 @@ class CategoryTreeList extends Cache
|
||||
|
||||
public function getKey($id = null)
|
||||
{
|
||||
return 'category_tree';
|
||||
return 'category_tree_list';
|
||||
}
|
||||
|
||||
public function getContent($id = null)
|
||||
{
|
||||
/**
|
||||
* @var Resultset $categories
|
||||
*/
|
||||
$categories = CategoryModel::query()
|
||||
->where('published = 1 AND deleted = 0')
|
||||
->execute();
|
||||
@ -34,7 +38,7 @@ class CategoryTreeList extends Cache
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \App\Models\Category[] $categories
|
||||
* @param Resultset $categories
|
||||
* @return array
|
||||
*/
|
||||
protected function handleContent($categories)
|
||||
|
@ -1,40 +0,0 @@
|
||||
<?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;
|
||||
}
|
||||
|
||||
}
|
@ -2,10 +2,11 @@
|
||||
|
||||
namespace App\Caches;
|
||||
|
||||
use App\Builders\ChapterList as ChapterListBuilder;
|
||||
use App\Builders\ChapterTreeList as ChapterTreeListBuilder;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
|
||||
class CourseChapterList extends Cache
|
||||
class ChapterTreeList extends Cache
|
||||
{
|
||||
|
||||
protected $lifetime = 7 * 86400;
|
||||
@ -17,13 +18,16 @@ class CourseChapterList extends Cache
|
||||
|
||||
public function getKey($id = null)
|
||||
{
|
||||
return "course_chapter_list:{$id}";
|
||||
return "chapter_tree_list:{$id}";
|
||||
}
|
||||
|
||||
public function getContent($id = null)
|
||||
{
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
/**
|
||||
* @var Resultset $chapters
|
||||
*/
|
||||
$chapters = $courseRepo->findChapters($id);
|
||||
|
||||
if ($chapters->count() == 0) {
|
||||
@ -34,14 +38,14 @@ class CourseChapterList extends Cache
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \App\Models\Chapter[] $chapters
|
||||
* @param Resultset $chapters
|
||||
* @return array
|
||||
*/
|
||||
protected function handleContent($chapters)
|
||||
{
|
||||
$items = $chapters->toArray();
|
||||
|
||||
$builder = new ChapterListBuilder();
|
||||
$builder = new ChapterTreeListBuilder();
|
||||
|
||||
$content = $builder->handleTreeList($items);
|
||||
|
@ -2,11 +2,14 @@
|
||||
|
||||
namespace App\Caches;
|
||||
|
||||
abstract class Counter extends \Phalcon\Mvc\User\Component
|
||||
use App\Library\Cache\Backend\Redis as RedisCache;
|
||||
use Phalcon\Mvc\User\Component;
|
||||
|
||||
abstract class Counter extends Component
|
||||
{
|
||||
|
||||
/**
|
||||
* @var \App\Library\Cache\Backend\Redis
|
||||
* @var RedisCache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
@ -40,16 +43,6 @@ abstract class Counter extends \Phalcon\Mvc\User\Component
|
||||
|
||||
$lifetime = $this->getLifetime();
|
||||
|
||||
/**
|
||||
* 原始内容为空,设置较短的生存时间,简单防止穿透
|
||||
*/
|
||||
if (!$content) {
|
||||
|
||||
$lifetime = 5 * 60;
|
||||
|
||||
$content = ['default' => 0];
|
||||
}
|
||||
|
||||
$this->redis->hMSet($key, $content);
|
||||
|
||||
$this->redis->expire($key, $lifetime);
|
||||
@ -82,17 +75,47 @@ abstract class Counter extends \Phalcon\Mvc\User\Component
|
||||
$this->get($id);
|
||||
}
|
||||
|
||||
public function increment($id, $hashKey, $value = 1)
|
||||
public function hGet($id, $hashKey)
|
||||
{
|
||||
$key = $this->getKey($id);
|
||||
|
||||
if (!$this->redis->exists($key)) {
|
||||
$this->get($id);
|
||||
}
|
||||
|
||||
$value = $this->redis->hGet($key, $hashKey);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function hDel($id, $hashKey)
|
||||
{
|
||||
$key = $this->getKey($id);
|
||||
|
||||
$value = $this->redis->hDel($key, $hashKey);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function hIncrBy($id, $hashKey, $value = 1)
|
||||
{
|
||||
$key = $this->getKey($id);
|
||||
|
||||
if (!$this->redis->exists($key)) {
|
||||
$this->get($id);
|
||||
}
|
||||
|
||||
$this->redis->hIncrBy($key, $hashKey, $value);
|
||||
}
|
||||
|
||||
public function decrement($id, $hashKey, $value = 1)
|
||||
public function hDecrBy($id, $hashKey, $value = 1)
|
||||
{
|
||||
$key = $this->getKey($id);
|
||||
|
||||
if (!$this->redis->exists($key)) {
|
||||
$this->get($id);
|
||||
}
|
||||
|
||||
$this->redis->hIncrBy($key, $hashKey, 0 - $value);
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,8 @@ class Course extends Cache
|
||||
|
||||
$course = $courseRepo->findById($id);
|
||||
|
||||
$course->cover = kg_img_url($course->cover);
|
||||
|
||||
if (!$course) {
|
||||
return new \stdClass();
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace App\Caches;
|
||||
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
|
||||
class CourseCategoryList extends Cache
|
||||
{
|
||||
@ -23,6 +24,9 @@ class CourseCategoryList extends Cache
|
||||
{
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
/**
|
||||
* @var Resultset $categories
|
||||
*/
|
||||
$categories = $courseRepo->findCategories($id);
|
||||
|
||||
if ($categories->count() == 0) {
|
||||
@ -33,7 +37,7 @@ class CourseCategoryList extends Cache
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \App\Models\Category[] $categories
|
||||
* @param Resultset $categories
|
||||
* @return array
|
||||
*/
|
||||
public function handleContent($categories)
|
||||
|
@ -1,41 +0,0 @@
|
||||
<?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;
|
||||
}
|
||||
|
||||
}
|
@ -2,7 +2,10 @@
|
||||
|
||||
namespace App\Caches;
|
||||
|
||||
use App\Models\Package as PackageModel;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use App\Repos\Package as PackageRepo;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
|
||||
class CoursePackageList extends Cache
|
||||
{
|
||||
@ -23,6 +26,9 @@ class CoursePackageList extends Cache
|
||||
{
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
/**
|
||||
* @var Resultset $packages
|
||||
*/
|
||||
$packages = $courseRepo->findPackages($id);
|
||||
|
||||
if ($packages->count() == 0) {
|
||||
@ -33,7 +39,7 @@ class CoursePackageList extends Cache
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \App\Models\Package[] $packages
|
||||
* @param PackageModel[] $packages
|
||||
* @return array
|
||||
*/
|
||||
protected function handleContent($packages)
|
||||
@ -64,15 +70,21 @@ class CoursePackageList extends Cache
|
||||
|
||||
$result = [];
|
||||
|
||||
$imgBaseUrl = kg_img_base_url();
|
||||
|
||||
foreach ($courses as $course) {
|
||||
|
||||
$course->cover = $imgBaseUrl . $course->cover;
|
||||
|
||||
$result[] = [
|
||||
'id' => $course->id,
|
||||
'model' => $course->model,
|
||||
'title' => $course->title,
|
||||
'summary' => $course->summary,
|
||||
'cover' => $course->cover,
|
||||
'summary' => $course->summary,
|
||||
'market_price' => $course->market_price,
|
||||
'vip_price' => $course->vip_price,
|
||||
'model' => $course->model,
|
||||
'level' => $course->level,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,9 @@
|
||||
|
||||
namespace App\Caches;
|
||||
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
|
||||
class CourseRelatedList extends Cache
|
||||
{
|
||||
@ -23,6 +25,9 @@ class CourseRelatedList extends Cache
|
||||
{
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
/**
|
||||
* @var Resultset $courses
|
||||
*/
|
||||
$courses = $courseRepo->findRelatedCourses($id);
|
||||
|
||||
if ($courses->count() == 0) {
|
||||
@ -34,22 +39,28 @@ class CourseRelatedList extends Cache
|
||||
|
||||
|
||||
/**
|
||||
* @param \App\Models\Course[] $courses
|
||||
* @param CourseModel[] $courses
|
||||
* @return array
|
||||
*/
|
||||
public function handleContent($courses)
|
||||
{
|
||||
$result = [];
|
||||
|
||||
$imgBaseUrl = kg_img_base_url();
|
||||
|
||||
foreach ($courses as $course) {
|
||||
|
||||
$course->cover = $imgBaseUrl . $course->cover;
|
||||
|
||||
$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,
|
||||
'model' => $course->model,
|
||||
'level' => $course->level,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,9 @@
|
||||
|
||||
namespace App\Caches;
|
||||
|
||||
use App\Models\User as UserModel;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
|
||||
class CourseTeacherList extends Cache
|
||||
{
|
||||
@ -23,6 +25,9 @@ class CourseTeacherList extends Cache
|
||||
{
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
/**
|
||||
* @var Resultset $users
|
||||
*/
|
||||
$users = $courseRepo->findTeachers($id);
|
||||
|
||||
if ($users->count() == 0) {
|
||||
@ -33,14 +38,19 @@ class CourseTeacherList extends Cache
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \App\Models\User[] $users
|
||||
* @param UserModel[] $users
|
||||
* @return array
|
||||
*/
|
||||
public function handleContent($users)
|
||||
{
|
||||
$result = [];
|
||||
|
||||
$imgBaseUrl = kg_img_base_url();
|
||||
|
||||
foreach ($users as $user) {
|
||||
|
||||
$user->avatar = $imgBaseUrl . $user->avatar;
|
||||
|
||||
$result[] = [
|
||||
'id' => $user->id,
|
||||
'name' => $user->name,
|
||||
|
@ -2,12 +2,14 @@
|
||||
|
||||
namespace App\Caches;
|
||||
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
|
||||
class HotCourseList extends Cache
|
||||
{
|
||||
|
||||
protected $lifetime = 7 * 86400;
|
||||
protected $lifetime = 86400;
|
||||
|
||||
public function getLifetime()
|
||||
{
|
||||
@ -23,6 +25,9 @@ class HotCourseList extends Cache
|
||||
{
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
/**
|
||||
* @var Resultset $courses
|
||||
*/
|
||||
$courses = $courseRepo->findRelatedCourses($id);
|
||||
|
||||
if ($courses->count() == 0) {
|
||||
@ -32,9 +37,8 @@ class HotCourseList extends Cache
|
||||
return $this->handleContent($courses);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param \App\Models\Course[] $courses
|
||||
* @param CourseModel[] $courses
|
||||
* @return array
|
||||
*/
|
||||
public function handleContent($courses)
|
||||
@ -44,12 +48,13 @@ class HotCourseList extends Cache
|
||||
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,
|
||||
'model' => $course->model,
|
||||
'level' => $course->level,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,9 @@
|
||||
|
||||
namespace App\Caches;
|
||||
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
|
||||
class LatestCourseList extends Cache
|
||||
{
|
||||
@ -23,6 +25,9 @@ class LatestCourseList extends Cache
|
||||
{
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
/**
|
||||
* @var Resultset $courses
|
||||
*/
|
||||
$courses = $courseRepo->findRelatedCourses($id);
|
||||
|
||||
if ($courses->count() == 0) {
|
||||
@ -34,22 +39,28 @@ class LatestCourseList extends Cache
|
||||
|
||||
|
||||
/**
|
||||
* @param \App\Models\Course[] $courses
|
||||
* @param CourseModel[] $courses
|
||||
* @return array
|
||||
*/
|
||||
public function handleContent($courses)
|
||||
{
|
||||
$result = [];
|
||||
|
||||
$imgBaseUrl = kg_img_base_url();
|
||||
|
||||
foreach ($courses as $course) {
|
||||
|
||||
$course->cover = $imgBaseUrl . $course->cover;
|
||||
|
||||
$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,
|
||||
'model' => $course->model,
|
||||
'level' => $course->level,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -2,8 +2,9 @@
|
||||
|
||||
namespace App\Caches;
|
||||
|
||||
use App\Builders\NavList as NavListBuilder;
|
||||
use App\Builders\NavTreeList as NavTreeListBuilder;
|
||||
use App\Models\Nav as NavModel;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
|
||||
class NavTreeList extends Cache
|
||||
{
|
||||
@ -22,6 +23,9 @@ class NavTreeList extends Cache
|
||||
|
||||
public function getContent($id = null)
|
||||
{
|
||||
/**
|
||||
* @var Resultset $navs
|
||||
*/
|
||||
$navs = NavModel::query()
|
||||
->where('published = 1 AND deleted = 0')
|
||||
->orderBy('position ASC, priority ASC')
|
||||
@ -35,7 +39,7 @@ class NavTreeList extends Cache
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \App\Models\Nav[] $navs
|
||||
* @param Resultset $navs
|
||||
* @return array
|
||||
*/
|
||||
protected function handleContent($navs)
|
||||
@ -53,7 +57,7 @@ class NavTreeList extends Cache
|
||||
}
|
||||
}
|
||||
|
||||
$builder = new NavListBuilder();
|
||||
$builder = new NavTreeListBuilder();
|
||||
|
||||
$content = [
|
||||
'top' => $builder->handleTreeList($list['top']),
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace App\Caches;
|
||||
|
||||
use App\Models\Slide as SlideModel;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
|
||||
class SlideList extends Cache
|
||||
{
|
||||
@ -21,6 +22,9 @@ class SlideList extends Cache
|
||||
|
||||
public function getContent($id = null)
|
||||
{
|
||||
/**
|
||||
* @var Resultset $slides
|
||||
*/
|
||||
$slides = SlideModel::query()
|
||||
->columns(['id', 'title', 'cover', 'summary', 'target', 'content'])
|
||||
->where('published = 1 AND deleted = 0')
|
||||
@ -35,7 +39,7 @@ class SlideList extends Cache
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \App\Models\Slide[] $slides
|
||||
* @param SlideModel[] $slides
|
||||
* @return array
|
||||
*/
|
||||
protected function handleContent($slides)
|
||||
|
@ -1,38 +0,0 @@
|
||||
<?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;
|
||||
}
|
||||
|
||||
}
|
40
app/Caches/UserDailyCounter.php
Normal file
40
app/Caches/UserDailyCounter.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Caches;
|
||||
|
||||
class UserDailyCounter extends Counter
|
||||
{
|
||||
|
||||
protected $lifetime = 86400;
|
||||
|
||||
public function getLifetime()
|
||||
{
|
||||
$tomorrow = strtotime('tomorrow');
|
||||
|
||||
$lifetime = $tomorrow - time();
|
||||
|
||||
return $lifetime;
|
||||
}
|
||||
|
||||
public function getKey($id = null)
|
||||
{
|
||||
return "user_daily_counter:{$id}";
|
||||
}
|
||||
|
||||
public function getContent($id = null)
|
||||
{
|
||||
$content = [
|
||||
'favorite_count' => 0,
|
||||
'comment_count' => 0,
|
||||
'consult_count' => 0,
|
||||
'order_count' => 0,
|
||||
'chapter_vote_count' => 0,
|
||||
'comment_vote_count' => 0,
|
||||
'consult_vote_count' => 0,
|
||||
'review_vote_count' => 0,
|
||||
];
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Tasks;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Services\Storage;
|
||||
use Phalcon\Cli\Task;
|
||||
use Phalcon\Text;
|
||||
|
||||
class AvatarSyncTask extends Task
|
||||
{
|
||||
|
||||
public function mainAction()
|
||||
{
|
||||
$limit = 250;
|
||||
|
||||
foreach (range(1, 2) as $page) {
|
||||
|
||||
$offset = ($page - 1) * $limit;
|
||||
|
||||
$users = User::query()
|
||||
->where('edu_role = 1')
|
||||
->limit($limit, $offset)
|
||||
->execute();
|
||||
|
||||
if ($users->count() > 0) {
|
||||
$this->handleUsers($users);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function handleUsers($users)
|
||||
{
|
||||
$storage = new Storage();
|
||||
|
||||
foreach ($users as $user) {
|
||||
|
||||
$avatar = $user->avatar;
|
||||
|
||||
if (!$avatar) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Text::startsWith($avatar, '/img/avatar')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Text::startsWith($avatar, '//')) {
|
||||
$avatar = 'http:' . $avatar;
|
||||
}
|
||||
|
||||
$url = str_replace(['-40-40', '-80-80', '-140-140', '-160-160'], '-200-200', $avatar);
|
||||
|
||||
$fileName = parse_url($url, PHP_URL_PATH);
|
||||
$filePath = tmp_path('avatar') . $fileName;
|
||||
|
||||
$content = file_get_contents($url);
|
||||
|
||||
if ($content === false) {
|
||||
echo "get user {$user->id} avatar failed" . PHP_EOL;
|
||||
continue;
|
||||
}
|
||||
|
||||
$put = file_put_contents($filePath, $content);
|
||||
|
||||
if ($put === false) {
|
||||
echo "put user {$user->id} cover failed" . PHP_EOL;
|
||||
continue;
|
||||
}
|
||||
|
||||
$keyName = $this->getKeyName($filePath);
|
||||
$remoteUrl = $storage->putFile($keyName, $filePath);
|
||||
|
||||
if ($remoteUrl) {
|
||||
$user->avatar = $keyName;
|
||||
$user->deleted = 2;
|
||||
$user->update();
|
||||
echo "upload avatar of user {$user->id} success" . PHP_EOL;
|
||||
} else {
|
||||
echo "upload avatar of user {$user->id} failed" . PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function getKeyName($filePath)
|
||||
{
|
||||
$ext = pathinfo($filePath, PATHINFO_EXTENSION);
|
||||
return '/img/avatar/' . date('YmdHis') . rand(1000, 9999) . '.' . $ext;
|
||||
}
|
||||
|
||||
}
|
@ -1,511 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Tasks;
|
||||
|
||||
use App\Models\Chapter as ChapterModel;
|
||||
use App\Models\Consult as ConsultModel;
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Models\CoursePackage as CoursePackageModel;
|
||||
use App\Models\CourseUser as CourseUserModel;
|
||||
use App\Models\Package as PackageModel;
|
||||
use App\Models\Review as ReviewModel;
|
||||
use App\Models\User as UserModel;
|
||||
use App\Repos\CoursePackage as CoursePackageRepo;
|
||||
use Phalcon\Cli\Task;
|
||||
use QL\QueryList;
|
||||
|
||||
class ClassSpiderTask extends Task
|
||||
{
|
||||
|
||||
public function listAction()
|
||||
{
|
||||
$ql = QueryList::rules([
|
||||
'course_link' => ['div.shizhan-course-wrap > a', 'href'],
|
||||
'course_cover' => ['div.img-box > img.shizhan-course-img', 'src'],
|
||||
'course_title' => ['div.img-box > img.shizhan-course-img', 'alt'],
|
||||
]);
|
||||
|
||||
$this->handleList($ql);
|
||||
}
|
||||
|
||||
protected function handleList($ql)
|
||||
{
|
||||
foreach (range(1, 6) as $page) {
|
||||
|
||||
$url = "https://coding.imooc.com/?sort=0&unlearn=0&page={$page}";
|
||||
|
||||
echo "============== Page {$page} =================" . PHP_EOL;
|
||||
|
||||
$data = $ql->get($url)->query()->getData();
|
||||
|
||||
if ($data->count() == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
foreach ($data->all() as $item) {
|
||||
|
||||
$courseData = [
|
||||
'class_id' => $this->getCourseId($item['course_link']),
|
||||
'title' => $item['course_title'],
|
||||
'cover' => $item['course_cover'],
|
||||
];
|
||||
|
||||
//print_r($courseData);
|
||||
|
||||
if ($courseData['class_id']) {
|
||||
$course = CourseModel::findFirstByClassId($courseData['class_id']);
|
||||
if (!$course) {
|
||||
$course = new CourseModel();
|
||||
$course->create($courseData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$ql->destruct();
|
||||
}
|
||||
|
||||
public function courseAction()
|
||||
{
|
||||
$courses = CourseModel::query()
|
||||
->where('class_id > 114')
|
||||
->orderBy('class_id ASC')
|
||||
->execute();
|
||||
|
||||
foreach ($courses as $course) {
|
||||
$this->handleCourse($course);
|
||||
sleep(5);
|
||||
}
|
||||
}
|
||||
|
||||
public function chapterAction()
|
||||
{
|
||||
$ql = QueryList::rules([
|
||||
'chapter_title' => ['.chapter-bd > h5.name', 'text'],
|
||||
'chapter_summary' => ['.chapter-bd > p.desc', 'text'],
|
||||
'lesson_html' => ['.chapter-bd > ul', 'html'],
|
||||
]);
|
||||
|
||||
$courses = CourseModel::query()
|
||||
->where('class_id > 114')
|
||||
->orderBy('class_id ASC')
|
||||
->execute();
|
||||
|
||||
foreach ($courses as $course) {
|
||||
$this->handleChapter($ql, $course);
|
||||
sleep(5);
|
||||
}
|
||||
}
|
||||
|
||||
protected function handleChapter(QueryList $ql, $course)
|
||||
{
|
||||
echo " course id: {$course->id} , class_id :{$course->class_id} " . PHP_EOL;
|
||||
|
||||
$url = "https://coding.imooc.com/class/chapter/{$course->class_id}.html";
|
||||
|
||||
$data = $ql->get($url)->query()->getData();
|
||||
|
||||
if ($data->count() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$lesson_ql = QueryList::rules([
|
||||
'lesson_title' => ['span.title_info', 'text'],
|
||||
'lesson_free' => ['span.watch-free', 'text'],
|
||||
]);
|
||||
|
||||
foreach ($data->all() as $item) {
|
||||
|
||||
$chapterData = [
|
||||
'course_id' => $course->id,
|
||||
'title' => trim($item['chapter_title']),
|
||||
'summary' => trim($item['chapter_summary']),
|
||||
];
|
||||
|
||||
$chapter = new ChapterModel();
|
||||
$chapter->create($chapterData);
|
||||
|
||||
$this->handleLesson($chapter, $lesson_ql, $item['lesson_html']);
|
||||
}
|
||||
|
||||
$ql->destruct();
|
||||
}
|
||||
|
||||
protected function handleLesson($chapter, QueryList $lesson_ql, $html)
|
||||
{
|
||||
|
||||
$lessons = $lesson_ql->html($html)->query()->getData();
|
||||
|
||||
if ($lessons->count() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($lessons->all() as $item) {
|
||||
$data = [
|
||||
'course_id' => $chapter->course_id,
|
||||
'parent_id' => $chapter->id,
|
||||
'title' => $item['lesson_title'],
|
||||
'free' => $item['lesson_free'] ? 1 : 0,
|
||||
];
|
||||
|
||||
$model = new ChapterModel();
|
||||
$model->create($data);
|
||||
}
|
||||
|
||||
$lesson_ql->destruct();
|
||||
}
|
||||
|
||||
public function consultAction()
|
||||
{
|
||||
$courses = CourseModel::query()
|
||||
->where('class_id > 0')
|
||||
->orderBy('class_id ASC')
|
||||
->execute();
|
||||
|
||||
foreach ($courses as $course) {
|
||||
$this->handleConsult($course);
|
||||
sleep(5);
|
||||
}
|
||||
}
|
||||
|
||||
protected function handleConsult($course)
|
||||
{
|
||||
|
||||
foreach (range(1, 20) as $page) {
|
||||
|
||||
echo "course {$course->id}, page {$page}" . PHP_EOL;
|
||||
|
||||
$url = "https://coding.imooc.com/class/ajaxconsultsearch?cid={$course->class_id}&page={$page}&pagesize=15";
|
||||
|
||||
$content = file_get_contents($url);
|
||||
|
||||
$json = json_decode($content, true);
|
||||
|
||||
$consults = $json['data']['data_adv'];
|
||||
|
||||
if (empty($consults)) {
|
||||
break;
|
||||
}
|
||||
|
||||
foreach ($consults as $item) {
|
||||
$data = [
|
||||
'question' => $item['content'],
|
||||
'answer' => $item['answer'],
|
||||
'like_count' => $item['praise'],
|
||||
'created_at' => strtotime($item['create_time']),
|
||||
];
|
||||
$consult = new ConsultModel();
|
||||
$consult->create($data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function reviewAction()
|
||||
{
|
||||
$ql = QueryList::rules([
|
||||
'review_content' => ['p.cmt-txt', 'text'],
|
||||
'review_rating' => ['div.stars > span', 'text'],
|
||||
]);
|
||||
|
||||
$courses = CourseModel::query()
|
||||
->where('class_id > 0')
|
||||
->orderBy('class_id ASC')
|
||||
->execute();
|
||||
|
||||
foreach ($courses as $course) {
|
||||
$this->handleReview($ql, $course);
|
||||
sleep(5);
|
||||
}
|
||||
}
|
||||
|
||||
protected function handleReview($ql, $course)
|
||||
{
|
||||
foreach (range(1, 10) as $page) {
|
||||
|
||||
$url = "https://coding.imooc.com/class/evaluation/{$course->class_id}.html?page={$page}";
|
||||
|
||||
echo "============== Course {$course->id}, Page {$page} =================" . PHP_EOL;
|
||||
|
||||
$data = $ql->get($url)->query()->getData();
|
||||
|
||||
if ($data->count() == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
foreach ($data->all() as $item) {
|
||||
|
||||
$reviewData = [
|
||||
'course_id' => $course->id,
|
||||
'content' => $item['review_content'],
|
||||
'rating' => $this->getReviewRating($item['review_rating']),
|
||||
];
|
||||
|
||||
$review = new ReviewModel();
|
||||
$review->create($reviewData);
|
||||
}
|
||||
}
|
||||
|
||||
$ql->destruct();
|
||||
}
|
||||
|
||||
public function packageAction()
|
||||
{
|
||||
$ql = QueryList::rules([
|
||||
'id' => ['a.js-buy-package', 'data-cid'],
|
||||
'title' => ['p.package-title', 'text'],
|
||||
'price' => ['p.package-price', 'text'],
|
||||
'other_html' => ['div.other-course-wrap', 'html'],
|
||||
]);
|
||||
|
||||
$courses = CourseModel::query()
|
||||
->where('class_id > 0')
|
||||
->orderBy('class_id ASC')
|
||||
->execute();
|
||||
|
||||
foreach ($courses as $course) {
|
||||
$this->handlePackage($ql, $course);
|
||||
sleep(5);
|
||||
}
|
||||
}
|
||||
|
||||
protected function handlePackage(QueryList $ql, $course)
|
||||
{
|
||||
echo " course id: {$course->id} , class_id :{$course->class_id} " . PHP_EOL;
|
||||
|
||||
$url = "https://coding.imooc.com/class/package/{$course->class_id}.html";
|
||||
|
||||
$data = $ql->get($url)->query()->getData();
|
||||
|
||||
if ($data->count() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$other_ql = QueryList::rules([
|
||||
'href' => ['a.course-item', 'href'],
|
||||
]);
|
||||
|
||||
foreach ($data->all() as $item) {
|
||||
|
||||
$packageData = [
|
||||
'id' => trim($item['id']),
|
||||
'title' => trim($item['title']),
|
||||
'market_price' => $this->getMarketPrice($item['price']),
|
||||
];
|
||||
|
||||
$package = PackageModel::findFirst($packageData['id']);
|
||||
|
||||
if (!$package) {
|
||||
$package = new PackageModel();
|
||||
$package->create($packageData);
|
||||
}
|
||||
|
||||
$cpRepo = new CoursePackageRepo();
|
||||
|
||||
$cp = $cpRepo->findCoursePackage($course->id, $package->id);
|
||||
|
||||
if (!$cp) {
|
||||
$cp = new CoursePackageModel();
|
||||
$cp->course_id = $course->id;
|
||||
$cp->package_id = $package->id;
|
||||
$cp->create();
|
||||
}
|
||||
|
||||
$this->handleOtherPackageCourse($package, $other_ql, $item['other_html']);
|
||||
}
|
||||
|
||||
$ql->destruct();
|
||||
}
|
||||
|
||||
protected function handleOtherPackageCourse($package, QueryList $other_ql, $html)
|
||||
{
|
||||
$courses = $other_ql->html($html)->query()->getData();
|
||||
|
||||
if ($courses->count() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($courses->all() as $item) {
|
||||
|
||||
$courseId = str_replace(['//coding.imooc.com/class/', '.html'], '', $item['href']);
|
||||
|
||||
$cpRepo = new CoursePackageRepo();
|
||||
|
||||
$cp = $cpRepo->findCoursePackage($courseId, $package->id);
|
||||
|
||||
if (!$cp) {
|
||||
$cp = new CoursePackageModel();
|
||||
$cp->course_id = (int)$courseId;
|
||||
$cp->package_id = $package->id;
|
||||
$cp->create();
|
||||
}
|
||||
}
|
||||
|
||||
$other_ql->destruct();
|
||||
}
|
||||
|
||||
protected function handleCourse($course)
|
||||
{
|
||||
echo " =============== class id {$course->class_id} ============" . PHP_EOL;
|
||||
|
||||
$url = "https://coding.imooc.com/class/{$course->class_id}.html";
|
||||
|
||||
$ql = QueryList::getInstance()->get($url);
|
||||
|
||||
$summary = $ql->find('div.info-desc')->text();
|
||||
$userLink = $ql->find('div.teacher > a')->attr('href');
|
||||
$marketPrice = $ql->find('div.ori-price')->text();
|
||||
$level = $ql->find('div.info-bar > span:eq(1)')->text();
|
||||
$duration = $ql->find('div.info-bar > span:eq(3)')->text();
|
||||
$userCount = $ql->find('div.info-bar > span:eq(5)')->text();
|
||||
$score = $ql->find('div.info-bar > span:eq(7)')->text();
|
||||
|
||||
$courseData = [
|
||||
'summary' => trim($summary),
|
||||
'user_count' => intval($userCount),
|
||||
'market_price' => $this->getMarketPrice($marketPrice),
|
||||
'level' => $this->getLevel($level),
|
||||
'score' => $this->getScore($score),
|
||||
'attrs' => [
|
||||
'duration' => $this->getCourseDuration($duration),
|
||||
],
|
||||
];
|
||||
|
||||
$course->update($courseData);
|
||||
|
||||
$ql->destruct();
|
||||
|
||||
$userId = $this->getUserId($userLink);
|
||||
|
||||
$user = UserModel::findFirst($userId);
|
||||
|
||||
if ($user) {
|
||||
|
||||
$user->edu_role = UserModel::EDU_ROLE_TEACHER;
|
||||
$user->update();
|
||||
|
||||
$cuRepo = new \App\Repos\CourseUser();
|
||||
|
||||
$row = $cuRepo->findCourseTeacher($course->id, $user->id);
|
||||
|
||||
if (!$row) {
|
||||
$courseUser = new CourseUserModel();
|
||||
$courseUser->course_id = $course->id;
|
||||
$courseUser->user_id = $user->id;
|
||||
$courseUser->role_type = CourseUserModel::ROLE_TEACHER;
|
||||
$courseUser->expire_time = strtotime('+15 years');
|
||||
$courseUser->create();
|
||||
}
|
||||
}
|
||||
|
||||
$this->handleTeacherInfo($userId);
|
||||
|
||||
}
|
||||
|
||||
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 = UserModel::findFirst($id);
|
||||
|
||||
if (!$user) {
|
||||
$user = new UserModel();
|
||||
$user->create($data);
|
||||
}
|
||||
|
||||
$ql->destruct();
|
||||
}
|
||||
|
||||
protected function getUserId($userLink)
|
||||
{
|
||||
$result = str_replace(['http://www.imooc.com/u/'], '', $userLink);
|
||||
|
||||
return trim($result);
|
||||
}
|
||||
|
||||
protected function getCourseId($courseLink)
|
||||
{
|
||||
if (!strpos($courseLink, '.html')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = str_replace(['/class/', '.html'], '', $courseLink);
|
||||
|
||||
return trim($result);
|
||||
}
|
||||
|
||||
protected function getMarketPrice($price)
|
||||
{
|
||||
$price = str_replace('¥', '', $price);
|
||||
return floatval(trim($price));
|
||||
}
|
||||
|
||||
protected function getScore($score)
|
||||
{
|
||||
return floatval(trim($score) * 10);
|
||||
}
|
||||
|
||||
protected function getCourseDuration($duration)
|
||||
{
|
||||
$hours = 0;
|
||||
$minutes = 0;
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
return 3600 * $hours + 60 * $minutes;
|
||||
}
|
||||
|
||||
protected function getChapterDuration($duration)
|
||||
{
|
||||
if (strpos($duration, ':') === false) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
list($minutes, $seconds) = explode(':', trim($duration));
|
||||
|
||||
return 60 * $minutes + $seconds;
|
||||
}
|
||||
|
||||
protected function getLevel($type)
|
||||
{
|
||||
$mapping = [
|
||||
'入门' => CourseModel::LEVEL_ENTRY,
|
||||
'初级' => CourseModel::LEVEL_JUNIOR,
|
||||
'中级' => CourseModel::LEVEL_MEDIUM,
|
||||
'高级' => CourseModel::LEVEL_SENIOR,
|
||||
];
|
||||
|
||||
return $mapping[$type] ?? CourseModel::LEVEL_ENTRY;
|
||||
}
|
||||
|
||||
protected function getReviewRating($type)
|
||||
{
|
||||
$mapping = [
|
||||
'好评' => 10,
|
||||
'中评' => 8,
|
||||
'差评' => 6,
|
||||
];
|
||||
|
||||
return $mapping[$type] ?? 8;
|
||||
}
|
||||
|
||||
}
|
@ -11,6 +11,7 @@ class CleanLogTask extends Task
|
||||
{
|
||||
$this->cleanCommonLog();
|
||||
$this->cleanConsoleLog();
|
||||
$this->cleanHttpLog();
|
||||
$this->cleanSqlLog();
|
||||
$this->cleanListenerLog();
|
||||
$this->cleanCaptchaLog();
|
||||
@ -19,7 +20,7 @@ class CleanLogTask extends Task
|
||||
$this->cleanVodLog();
|
||||
$this->cleanStorageLog();
|
||||
$this->cleanAlipayLog();
|
||||
$this->cleanWxpayLog();
|
||||
$this->cleanWechatLog();
|
||||
$this->cleanRefundLog();
|
||||
}
|
||||
|
||||
@ -31,6 +32,14 @@ class CleanLogTask extends Task
|
||||
$this->cleanLog('common', 7);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理Http日志
|
||||
*/
|
||||
protected function cleanHttpLog()
|
||||
{
|
||||
$this->cleanLog('http', 7);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理Console日志
|
||||
*/
|
||||
@ -106,9 +115,9 @@ class CleanLogTask extends Task
|
||||
/**
|
||||
* 清理微信支付服务日志
|
||||
*/
|
||||
protected function cleanWxpayLog()
|
||||
protected function cleanWechatLog()
|
||||
{
|
||||
$this->cleanLog('wxpay', 30);
|
||||
$this->cleanLog('wechat', 30);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4,6 +4,8 @@ namespace App\Console\Tasks;
|
||||
|
||||
use App\Models\Order as OrderModel;
|
||||
use Phalcon\Cli\Task;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
use Phalcon\Mvc\Model\ResultsetInterface;
|
||||
|
||||
class CloseOrderTask extends Task
|
||||
{
|
||||
@ -26,7 +28,7 @@ class CloseOrderTask extends Task
|
||||
* 查找待关闭订单
|
||||
*
|
||||
* @param int $limit
|
||||
* @return \Phalcon\Mvc\Model\ResultsetInterface
|
||||
* @return ResultsetInterface|Resultset|OrderModel[]
|
||||
*/
|
||||
protected function findOrders($limit = 1000)
|
||||
{
|
||||
|
@ -1,40 +0,0 @@
|
||||
<?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;
|
||||
}
|
||||
|
||||
}
|
@ -4,7 +4,10 @@ namespace App\Console\Tasks;
|
||||
|
||||
use App\Models\Trade as TradeModel;
|
||||
use App\Services\Alipay as AlipayService;
|
||||
use App\Services\Wechat as WechatService;
|
||||
use Phalcon\Cli\Task;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
use Phalcon\Mvc\Model\ResultsetInterface;
|
||||
|
||||
class CloseTradeTask extends Task
|
||||
{
|
||||
@ -20,8 +23,8 @@ class CloseTradeTask extends Task
|
||||
foreach ($trades as $trade) {
|
||||
if ($trade->channel == TradeModel::CHANNEL_ALIPAY) {
|
||||
$this->closeAlipayTrade($trade);
|
||||
} elseif ($trade->channel == TradeModel::CHANNEL_WXPAY) {
|
||||
$this->closeWxpayTrade($trade);
|
||||
} elseif ($trade->channel == TradeModel::CHANNEL_WECHAT) {
|
||||
$this->closeWechatTrade($trade);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -53,9 +56,9 @@ class CloseTradeTask extends Task
|
||||
*
|
||||
* @param TradeModel $trade
|
||||
*/
|
||||
protected function closeWxpayTrade($trade)
|
||||
protected function closeWechatTrade($trade)
|
||||
{
|
||||
$service = new WxpayService();
|
||||
$service = new WechatService();
|
||||
|
||||
$wxOrder = $service->findOrder($trade->sn);
|
||||
|
||||
@ -74,7 +77,7 @@ class CloseTradeTask extends Task
|
||||
* 查找待关闭交易
|
||||
*
|
||||
* @param int $limit
|
||||
* @return \Phalcon\Mvc\Model\ResultsetInterface
|
||||
* @return Resultset|ResultsetInterface
|
||||
*/
|
||||
protected function findTrades($limit = 5)
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Console\Tasks;
|
||||
|
||||
use App\Models\Category as CategoryModel;
|
||||
use App\Repos\Category as CategoryRepo;
|
||||
use Phalcon\Cli\Task;
|
||||
|
||||
@ -14,6 +15,9 @@ class CountCourseTask extends Task
|
||||
|
||||
$mapping = [];
|
||||
|
||||
/**
|
||||
* @var CategoryModel[] $subCategories
|
||||
*/
|
||||
$subCategories = $categoryRepo->findAll(['level' => 2, 'deleted' => 0]);
|
||||
|
||||
foreach ($subCategories as $category) {
|
||||
@ -31,6 +35,9 @@ class CountCourseTask extends Task
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @var CategoryModel[] $topCategories
|
||||
*/
|
||||
$topCategories = $categoryRepo->findAll(['level' => 1, 'deleted' => 0]);
|
||||
|
||||
foreach ($topCategories as $category) {
|
||||
|
@ -1,66 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Tasks;
|
||||
|
||||
use App\Models\Course;
|
||||
use App\Services\Storage;
|
||||
use Phalcon\Cli\Task;
|
||||
use Phalcon\Text;
|
||||
|
||||
class ImageSyncTask extends Task
|
||||
{
|
||||
|
||||
public function mainAction()
|
||||
{
|
||||
$courses = Course::query()
|
||||
->where('id > 1155')
|
||||
->execute();
|
||||
|
||||
$storage = new Storage();
|
||||
|
||||
foreach ($courses as $course) {
|
||||
|
||||
$cover = $course->cover;
|
||||
|
||||
if (Text::startsWith($cover, '//')) {
|
||||
$cover = 'http:' . $cover;
|
||||
}
|
||||
|
||||
$url = str_replace('-360-202', '', $cover);
|
||||
|
||||
$fileName = parse_url($url, PHP_URL_PATH);
|
||||
$filePath = tmp_path() . $fileName;
|
||||
$content = file_get_contents($url);
|
||||
|
||||
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();
|
||||
echo "upload cover of course {$course->id} success" . PHP_EOL;
|
||||
} else {
|
||||
echo "upload cover of course {$course->id} failed" . PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function getKeyName($filePath)
|
||||
{
|
||||
$ext = pathinfo($filePath, PATHINFO_EXTENSION);
|
||||
return '/img/cover/' . date('YmdHis') . rand(1000, 9999) . '.' . $ext;
|
||||
}
|
||||
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Console\Tasks;
|
||||
|
||||
use App\Library\Cache\Backend\Redis as RedisCache;
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Models\Learning as LearningModel;
|
||||
use App\Repos\Chapter as ChapterRepo;
|
||||
@ -9,88 +10,109 @@ use App\Repos\ChapterUser as ChapterUserRepo;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use App\Repos\CourseUser as CourseUserRepo;
|
||||
use App\Repos\Learning as LearningRepo;
|
||||
use App\Services\LearningSyncer;
|
||||
use Phalcon\Cli\Task;
|
||||
|
||||
class LearningTask extends Task
|
||||
{
|
||||
|
||||
/**
|
||||
* @var \App\Library\Cache\Backend\Redis
|
||||
* @var RedisCache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* @var \Redis
|
||||
*/
|
||||
protected $redis;
|
||||
|
||||
public function mainAction()
|
||||
{
|
||||
$this->cache = $this->getDI()->get('cache');
|
||||
|
||||
$keys = $this->cache->queryKeys('learning:');
|
||||
$this->redis = $this->cache->getRedis();
|
||||
|
||||
if (!$keys) return;
|
||||
$syncer = new LearningSyncer();
|
||||
|
||||
$keys = array_slice($keys, 0, 500);
|
||||
$syncKey = $syncer->getSyncKey();
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$lastKey = $this->cache->getRawKeyName($key);
|
||||
$this->handleLearning($lastKey);
|
||||
$requestIds = $this->redis->sMembers($syncKey);
|
||||
|
||||
if (!$requestIds) return;
|
||||
|
||||
foreach ($requestIds as $requestId) {
|
||||
$itemKey = $syncer->getItemKey($requestId);
|
||||
$this->handleLearning($itemKey);
|
||||
}
|
||||
|
||||
$this->redis->sRem($syncKey, ...$requestIds);
|
||||
}
|
||||
|
||||
protected function handleLearning($key)
|
||||
/**
|
||||
* @param string $itemKey
|
||||
*/
|
||||
protected function handleLearning($itemKey)
|
||||
{
|
||||
$content = $this->cache->get($key);
|
||||
/**
|
||||
* @var LearningModel $cacheLearning
|
||||
*/
|
||||
$cacheLearning = $this->cache->get($itemKey);
|
||||
|
||||
if (!$content) return;
|
||||
if (!$cacheLearning) return;
|
||||
|
||||
$learningRepo = new LearningRepo();
|
||||
|
||||
$learning = $learningRepo->findByRequestId($content['request_id']);
|
||||
$dbLearning = $learningRepo->findByRequestId($cacheLearning->request_id);
|
||||
|
||||
if (!$learning) {
|
||||
$learning = new LearningModel();
|
||||
$learning->create($content);
|
||||
if (!$dbLearning) {
|
||||
$cacheLearning->create();
|
||||
} else {
|
||||
$learning->duration += $content['duration'];
|
||||
$learning->update();
|
||||
$dbLearning->duration += $cacheLearning->duration;
|
||||
$dbLearning->update();
|
||||
}
|
||||
|
||||
$this->updateChapterUser($content['chapter_id'], $content['user_id'], $content['duration'], $content['position']);
|
||||
$this->updateChapterUser($dbLearning);
|
||||
|
||||
$this->cache->delete($key);
|
||||
$this->cache->delete($itemKey);
|
||||
}
|
||||
|
||||
protected function updateChapterUser($chapterId, $userId, $duration = 0, $position = 0)
|
||||
/**
|
||||
* @param LearningModel $learning
|
||||
*/
|
||||
protected function updateChapterUser(LearningModel $learning)
|
||||
{
|
||||
$chapterUserRepo = new ChapterUserRepo();
|
||||
|
||||
$chapterUser = $chapterUserRepo->findChapterUser($chapterId, $userId);
|
||||
$chapterUser = $chapterUserRepo->findChapterUser($learning->chapter_id, $learning->user_id);
|
||||
|
||||
if (!$chapterUser) return;
|
||||
|
||||
$chapterRepo = new ChapterRepo();
|
||||
|
||||
$chapter = $chapterRepo->findById($chapterId);
|
||||
$chapter = $chapterRepo->findById($learning->chapter_id);
|
||||
|
||||
if (!$chapter) return;
|
||||
|
||||
$chapterModel = $chapter->attrs['model'];
|
||||
|
||||
$chapterUser->duration += $duration;
|
||||
$chapterUser->duration += $learning->duration;
|
||||
|
||||
/**
|
||||
* 消费规则
|
||||
*
|
||||
* 1.点播观看时间大于时长30%
|
||||
* 2.直播观看时间超过10分钟
|
||||
* 3.图文浏览即消费
|
||||
*/
|
||||
if ($chapterModel == CourseModel::MODEL_VOD) {
|
||||
|
||||
$chapterDuration = $chapter->attrs['duration'] ?: 300;
|
||||
$duration = $chapter->attrs['duration'] ?: 300;
|
||||
|
||||
$progress = floor(100 * $chapterUser->duration / $chapterDuration);
|
||||
$progress = floor(100 * $chapterUser->duration / $duration);
|
||||
|
||||
$chapterUser->position = floor($position);
|
||||
$chapterUser->position = floor($learning->position);
|
||||
$chapterUser->progress = $progress < 100 ? $progress : 100;
|
||||
$chapterUser->consumed = $chapterUser->duration > 0.3 * $chapterDuration ? 1 : 0;
|
||||
$chapterUser->consumed = $chapterUser->duration > 0.3 * $duration ? 1 : 0;
|
||||
|
||||
} elseif ($chapterModel == CourseModel::MODEL_LIVE) {
|
||||
|
||||
@ -108,6 +130,10 @@ class LearningTask extends Task
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $courseId
|
||||
* @param int $userId
|
||||
*/
|
||||
protected function updateCourseUser($courseId, $userId)
|
||||
{
|
||||
$courseRepo = new CourseRepo();
|
||||
@ -142,9 +168,11 @@ class LearningTask extends Task
|
||||
|
||||
$courseUser = $courseUserRepo->findCourseUser($courseId, $userId);
|
||||
|
||||
$courseUser->progress = $progress;
|
||||
$courseUser->duration = $duration;
|
||||
$courseUser->update();
|
||||
if ($courseUser) {
|
||||
$courseUser->progress = $progress;
|
||||
$courseUser->duration = $duration;
|
||||
$courseUser->update();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,9 +3,11 @@
|
||||
namespace App\Console\Tasks;
|
||||
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Searchers\CourseDocumenter;
|
||||
use App\Searchers\CourseSearcher;
|
||||
use App\Searchers\CourseDocument;
|
||||
use App\Searchers\CourseSearch;
|
||||
use Phalcon\Cli\Task;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
use Phalcon\Mvc\Model\ResultsetInterface;
|
||||
|
||||
class ManageCourseIndexTask extends Task
|
||||
{
|
||||
@ -55,7 +57,7 @@ class ManageCourseIndexTask extends Task
|
||||
*/
|
||||
protected function cleanCourseIndex()
|
||||
{
|
||||
$searcher = new CourseSearcher();
|
||||
$searcher = new CourseSearch();
|
||||
|
||||
$index = $searcher->getXS()->getIndex();
|
||||
|
||||
@ -77,9 +79,9 @@ class ManageCourseIndexTask extends Task
|
||||
return;
|
||||
}
|
||||
|
||||
$searcher = new CourseSearcher();
|
||||
$searcher = new CourseSearch();
|
||||
|
||||
$documenter = new CourseDocumenter();
|
||||
$documenter = new CourseDocument();
|
||||
|
||||
$index = $searcher->getXS()->getIndex();
|
||||
|
||||
@ -106,7 +108,7 @@ class ManageCourseIndexTask extends Task
|
||||
*/
|
||||
protected function searchCourses($query)
|
||||
{
|
||||
$searcher = new CourseSearcher();
|
||||
$searcher = new CourseSearch();
|
||||
|
||||
$result = $searcher->search($query);
|
||||
|
||||
@ -116,7 +118,7 @@ class ManageCourseIndexTask extends Task
|
||||
/**
|
||||
* 查找课程
|
||||
*
|
||||
* @return \Phalcon\Mvc\Model\ResultsetInterface
|
||||
* @return Resultset|ResultsetInterface
|
||||
*/
|
||||
protected function findCourses()
|
||||
{
|
||||
|
190
app/Console/Tasks/ProcessOrderTask.php
Normal file
190
app/Console/Tasks/ProcessOrderTask.php
Normal file
@ -0,0 +1,190 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Tasks;
|
||||
|
||||
use App\Models\CourseUser as CourseUserModel;
|
||||
use App\Models\Order as OrderModel;
|
||||
use App\Models\Task as TaskModel;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use App\Repos\CourseUser as CourseUserRepo;
|
||||
use App\Repos\Order as OrderRepo;
|
||||
use App\Repos\User as UserRepo;
|
||||
use Phalcon\Cli\Task;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
use Phalcon\Mvc\Model\ResultsetInterface;
|
||||
|
||||
class ProcessOrderTask extends Task
|
||||
{
|
||||
|
||||
const TRY_COUNT = 3;
|
||||
|
||||
public function mainAction()
|
||||
{
|
||||
$tasks = $this->findTasks();
|
||||
|
||||
if ($tasks->count() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$orderRepo = new OrderRepo();
|
||||
|
||||
foreach ($tasks as $task) {
|
||||
|
||||
try {
|
||||
|
||||
/**
|
||||
* @var array $itemInfo
|
||||
*/
|
||||
$itemInfo = $task->item_info;
|
||||
|
||||
$order = $orderRepo->findById($itemInfo['order']['id']);
|
||||
|
||||
switch ($order->item_type) {
|
||||
case OrderModel::ITEM_COURSE:
|
||||
$this->handleCourseOrder($order);
|
||||
break;
|
||||
case OrderModel::ITEM_PACKAGE:
|
||||
$this->handlePackageOrder($order);
|
||||
break;
|
||||
case OrderModel::ITEM_VIP:
|
||||
$this->handleVipOrder($order);
|
||||
break;
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
|
||||
$task->try_count += 1;
|
||||
$task->priority += 1;
|
||||
|
||||
if ($task->try_count > self::TRY_COUNT) {
|
||||
$task->status = TaskModel::STATUS_FAILED;
|
||||
}
|
||||
|
||||
$task->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param OrderModel $order
|
||||
*/
|
||||
protected function handleCourseOrder(OrderModel $order)
|
||||
{
|
||||
/**
|
||||
* @var array $itemInfo
|
||||
*/
|
||||
$itemInfo = $order->item_info;
|
||||
|
||||
$data = [
|
||||
'user_id' => $order->user_id,
|
||||
'course_id' => $order->item_id,
|
||||
'expiry_time' => $itemInfo['course']['expiry_time'],
|
||||
'role_type' => CourseUserModel::ROLE_STUDENT,
|
||||
'source_type' => CourseUserModel::SOURCE_CHARGE,
|
||||
];
|
||||
|
||||
$courseUser = new CourseUserModel();
|
||||
|
||||
if ($courseUser->create($data) === false) {
|
||||
throw new \RuntimeException('Create Course User Failed');
|
||||
}
|
||||
|
||||
$this->handleCourseHistory($data['course_id'], $data['user_id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param OrderModel $order
|
||||
*/
|
||||
protected function handlePackageOrder(OrderModel $order)
|
||||
{
|
||||
/**
|
||||
* @var array $itemInfo
|
||||
*/
|
||||
$itemInfo = $order->item_info;
|
||||
|
||||
foreach ($itemInfo['courses'] as $course) {
|
||||
|
||||
$data = [
|
||||
'user_id' => $order->user_id,
|
||||
'course_id' => $course['id'],
|
||||
'expiry_time' => $course['expiry_time'],
|
||||
'role_type' => CourseUserModel::ROLE_STUDENT,
|
||||
'source_type' => CourseUserModel::SOURCE_CHARGE,
|
||||
];
|
||||
|
||||
$courseUser = new CourseUserModel();
|
||||
|
||||
if ($courseUser->create($data) === false) {
|
||||
throw new \RuntimeException('Create Course User Failed');
|
||||
}
|
||||
|
||||
$this->handleCourseHistory($data['course_id'], $data['user_id']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param OrderModel $order
|
||||
*/
|
||||
protected function handleVipOrder(OrderModel $order)
|
||||
{
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$user = $userRepo->findById($order->user_id);
|
||||
|
||||
/**
|
||||
* @var array $itemInfo
|
||||
*/
|
||||
$itemInfo = $order->item_info;
|
||||
|
||||
$user->vip_expiry_time = $itemInfo['vip']['expiry_time'];
|
||||
|
||||
if ($user->update() === false) {
|
||||
throw new \RuntimeException('Update Vip Expiry Failed');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $courseId
|
||||
* @param int $userId
|
||||
*/
|
||||
protected function handleCourseHistory($courseId, $userId)
|
||||
{
|
||||
$courseUserRepo = new CourseUserRepo();
|
||||
|
||||
$courseUser = $courseUserRepo->findCourseStudent($courseId, $userId);
|
||||
|
||||
if ($courseUser) {
|
||||
$courseUser->update(['deleted' => 1]);
|
||||
}
|
||||
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
$userLearnings = $courseRepo->findUserLearnings($courseId, $userId);
|
||||
|
||||
if ($userLearnings->count() > 0) {
|
||||
$userLearnings->update(['deleted' => 1]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $limit
|
||||
* @return ResultsetInterface|Resultset|TaskModel[]
|
||||
*/
|
||||
protected function findTasks($limit = 100)
|
||||
{
|
||||
$itemType = TaskModel::TYPE_PROCESS_ORDER;
|
||||
$status = TaskModel::STATUS_PENDING;
|
||||
$tryCount = self::TRY_COUNT;
|
||||
|
||||
$tasks = TaskModel::query()
|
||||
->where('item_type = :item_type:', ['item_type' => $itemType])
|
||||
->andWhere('status = :status:', ['status' => $status])
|
||||
->andWhere('try_count < :try_count:', ['try_count' => $tryCount])
|
||||
->orderBy('priority ASC')
|
||||
->limit($limit)
|
||||
->execute();
|
||||
|
||||
return $tasks;
|
||||
}
|
||||
|
||||
}
|
@ -6,6 +6,7 @@ use App\Caches\Chapter as ChapterCache;
|
||||
use App\Caches\ChapterCounter as ChapterCounterCache;
|
||||
use App\Repos\Chapter as ChapterRepo;
|
||||
use App\Services\ChapterCacheSyncer;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
|
||||
class RebuildChapterCacheTask extends Task
|
||||
{
|
||||
@ -39,6 +40,9 @@ class RebuildChapterCacheTask extends Task
|
||||
|
||||
$chapterRepo = new ChapterRepo();
|
||||
|
||||
/**
|
||||
* @var Resultset $chapters
|
||||
*/
|
||||
$chapters = $chapterRepo->findByIds($chapterIds);
|
||||
|
||||
if ($chapters->count() == 0) {
|
||||
|
@ -4,14 +4,17 @@ namespace App\Console\Tasks;
|
||||
|
||||
use App\Caches\Course as CourseCache;
|
||||
use App\Caches\CourseCounter as CourseCounterCache;
|
||||
use App\Library\Cache\Backend\Redis as RedisCache;
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use App\Services\CourseCacheSyncer;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
|
||||
class RebuildCourseCacheTask extends Task
|
||||
{
|
||||
|
||||
/**
|
||||
* @var \App\Library\Cache\Backend\Redis
|
||||
* @var RedisCache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
@ -39,6 +42,9 @@ class RebuildCourseCacheTask extends Task
|
||||
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
/**
|
||||
* @var Resultset|CourseModel[] $courses
|
||||
*/
|
||||
$courses = $courseRepo->findByIds($courseIds);
|
||||
|
||||
if ($courses->count() == 0) {
|
||||
@ -49,10 +55,12 @@ class RebuildCourseCacheTask extends Task
|
||||
$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);
|
||||
|
@ -2,16 +2,17 @@
|
||||
|
||||
namespace App\Console\Tasks;
|
||||
|
||||
use App\Library\Cache\Backend\Redis as RedisCache;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use App\Searchers\CourseDocumenter;
|
||||
use App\Searchers\CourseSearcher;
|
||||
use App\Searchers\CourseDocument;
|
||||
use App\Searchers\CourseSearch;
|
||||
use App\Services\CourseIndexSyncer;
|
||||
|
||||
class RebuildCourseIndexTask extends Task
|
||||
{
|
||||
|
||||
/**
|
||||
* @var \App\Library\Cache\Backend\Redis
|
||||
* @var RedisCache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
@ -31,7 +32,7 @@ class RebuildCourseIndexTask extends Task
|
||||
|
||||
protected function rebuild()
|
||||
{
|
||||
$key = $this->getCacheKey();
|
||||
$key = $this->getSyncKey();
|
||||
|
||||
$courseIds = $this->redis->sRandMember($key, 100);
|
||||
|
||||
@ -45,16 +46,18 @@ class RebuildCourseIndexTask extends Task
|
||||
return;
|
||||
}
|
||||
|
||||
$document = new CourseDocumenter();
|
||||
$document = new CourseDocument();
|
||||
|
||||
$searcher = new CourseSearcher();
|
||||
$searcher = new CourseSearch();
|
||||
|
||||
$index = $searcher->getXS()->getIndex();
|
||||
|
||||
$index->openBuffer();
|
||||
|
||||
foreach ($courses as $course) {
|
||||
|
||||
$doc = $document->setDocument($course);
|
||||
|
||||
if ($course->published == 1) {
|
||||
$index->update($doc);
|
||||
} else {
|
||||
@ -67,11 +70,11 @@ class RebuildCourseIndexTask extends Task
|
||||
$this->redis->sRem($key, ...$courseIds);
|
||||
}
|
||||
|
||||
protected function getCacheKey()
|
||||
protected function getSyncKey()
|
||||
{
|
||||
$syncer = new CourseIndexSyncer();
|
||||
|
||||
return $syncer->getCacheKey();
|
||||
return $syncer->getSyncKey();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -10,13 +10,19 @@ use App\Repos\CourseUser as CourseUserRepo;
|
||||
use App\Repos\Order as OrderRepo;
|
||||
use App\Repos\Refund as RefundRepo;
|
||||
use App\Repos\Trade as TradeRepo;
|
||||
use App\Repos\User as UserRepo;
|
||||
use App\Services\Alipay as AlipayService;
|
||||
use App\Services\Wxpay as WxpayService;
|
||||
use App\Services\Wechat as WechatService;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
use Phalcon\Mvc\Model\ResultsetInterface;
|
||||
|
||||
class RefundTask extends Task
|
||||
{
|
||||
|
||||
const TRY_COUNT = 5;
|
||||
/**
|
||||
* 重试次数
|
||||
*/
|
||||
const TRY_COUNT = 3;
|
||||
|
||||
public function mainAction()
|
||||
{
|
||||
@ -34,15 +40,21 @@ class RefundTask extends Task
|
||||
|
||||
foreach ($tasks as $task) {
|
||||
|
||||
$refund = $refundRepo->findBySn($task->item_info['refund']['sn']);
|
||||
$trade = $tradeRepo->findBySn($task->item_info['refund']['trade_sn']);
|
||||
$order = $orderRepo->findBySn($task->item_info['refund']['order_sn']);
|
||||
/**
|
||||
* @var array $itemInfo
|
||||
*/
|
||||
$itemInfo = $task->item_info;
|
||||
|
||||
$refund = $refundRepo->findById($itemInfo['refund']['id']);
|
||||
$trade = $tradeRepo->findById($itemInfo['refund']['trade_id']);
|
||||
$order = $orderRepo->findById($itemInfo['refund']['order_id']);
|
||||
|
||||
try {
|
||||
|
||||
$this->db->begin();
|
||||
|
||||
$this->handleTradeRefund($trade, $refund);
|
||||
|
||||
$this->handleOrderRefund($order);
|
||||
|
||||
$refund->status = RefundModel::STATUS_FINISHED;
|
||||
@ -76,6 +88,7 @@ class RefundTask extends Task
|
||||
$this->db->rollback();
|
||||
|
||||
$task->try_count += 1;
|
||||
$task->priority += 1;
|
||||
|
||||
if ($task->try_count > self::TRY_COUNT) {
|
||||
$task->status = TaskModel::STATUS_FAILED;
|
||||
@ -104,18 +117,23 @@ class RefundTask extends Task
|
||||
$response = false;
|
||||
|
||||
if ($trade->channel == TradeModel::CHANNEL_ALIPAY) {
|
||||
|
||||
$alipay = new AlipayService();
|
||||
|
||||
$response = $alipay->refundOrder([
|
||||
'out_trade_no' => $trade->sn,
|
||||
'out_request_no' => $refund->sn,
|
||||
'refund_amount' => $refund->amount,
|
||||
]);
|
||||
} elseif ($trade->channel == TradeModel::CHANNEL_WXPAY) {
|
||||
$wxpay = new WxpayService();
|
||||
$response = $wxpay->refundOrder([
|
||||
|
||||
} elseif ($trade->channel == TradeModel::CHANNEL_WECHAT) {
|
||||
|
||||
$wechat = new WechatService();
|
||||
|
||||
$response = $wechat->refundOrder([
|
||||
'out_trade_no' => $trade->sn,
|
||||
'out_refund_no' => $refund->sn,
|
||||
'total_fee' => 100 * $trade->order_amount,
|
||||
'total_fee' => 100 * $trade->amount,
|
||||
'refund_fee' => 100 * $refund->amount,
|
||||
]);
|
||||
}
|
||||
@ -133,19 +151,16 @@ class RefundTask extends Task
|
||||
protected function handleOrderRefund(OrderModel $order)
|
||||
{
|
||||
switch ($order->item_type) {
|
||||
case OrderModel::TYPE_COURSE:
|
||||
case OrderModel::ITEM_COURSE:
|
||||
$this->handleCourseOrderRefund($order);
|
||||
break;
|
||||
case OrderModel::TYPE_PACKAGE:
|
||||
case OrderModel::ITEM_PACKAGE:
|
||||
$this->handlePackageOrderRefund($order);
|
||||
break;
|
||||
case OrderModel::TYPE_REWARD:
|
||||
$this->handleRewardOrderRefund($order);
|
||||
break;
|
||||
case OrderModel::TYPE_VIP:
|
||||
case OrderModel::ITEM_VIP:
|
||||
$this->handleVipOrderRefund($order);
|
||||
break;
|
||||
case OrderModel::TYPE_TEST:
|
||||
case OrderModel::ITEM_TEST:
|
||||
$this->handleTestOrderRefund($order);
|
||||
break;
|
||||
}
|
||||
@ -179,8 +194,15 @@ class RefundTask extends Task
|
||||
{
|
||||
$courseUserRepo = new CourseUserRepo();
|
||||
|
||||
foreach ($order->item_info['courses'] as $course) {
|
||||
/**
|
||||
* @var array $itemInfo
|
||||
*/
|
||||
$itemInfo = $order->item_info;
|
||||
|
||||
foreach ($itemInfo['courses'] as $course) {
|
||||
|
||||
$courseUser = $courseUserRepo->findCourseStudent($course['id'], $order->user_id);
|
||||
|
||||
if ($courseUser) {
|
||||
$courseUser->deleted = 1;
|
||||
if ($courseUser->update() === false) {
|
||||
@ -201,24 +223,17 @@ class RefundTask extends Task
|
||||
|
||||
$user = $userRepo->findById($order->user_id);
|
||||
|
||||
$baseTime = $user->vip_expiry;
|
||||
/**
|
||||
* @var array $itemInfo
|
||||
*/
|
||||
$itemInfo = $order->item_info;
|
||||
|
||||
switch ($order->item_info['vip']['duration']) {
|
||||
case 'one_month':
|
||||
$user->vip_expiry = strtotime('-1 months', $baseTime);
|
||||
break;
|
||||
case 'three_month':
|
||||
$user->vip_expiry = strtotime('-3 months', $baseTime);
|
||||
break;
|
||||
case 'six_month':
|
||||
$user->vip_expiry = strtotime('-6 months', $baseTime);
|
||||
break;
|
||||
case 'twelve_month':
|
||||
$user->vip_expiry = strtotime('-12 months', $baseTime);
|
||||
break;
|
||||
}
|
||||
$diffTime = "-{$itemInfo['vip']['expiry']} months";
|
||||
$baseTime = $itemInfo['vip']['expiry_time'];
|
||||
|
||||
if ($user->vip_expiry < time()) {
|
||||
$user->vip_expiry_time = strtotime($diffTime, $baseTime);
|
||||
|
||||
if ($user->vip_expiry_time < time()) {
|
||||
$user->vip = 0;
|
||||
}
|
||||
|
||||
@ -227,16 +242,6 @@ class RefundTask extends Task
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理打赏订单退款
|
||||
*
|
||||
* @param OrderModel $order
|
||||
*/
|
||||
protected function handleRewardOrderRefund(OrderModel $order)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理测试订单退款
|
||||
*
|
||||
@ -247,6 +252,10 @@ class RefundTask extends Task
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $limit
|
||||
* @return ResultsetInterface|Resultset|TaskModel[]
|
||||
*/
|
||||
protected function findTasks($limit = 5)
|
||||
{
|
||||
$itemType = TaskModel::TYPE_REFUND;
|
||||
@ -257,7 +266,7 @@ class RefundTask extends Task
|
||||
->where('item_type = :item_type:', ['item_type' => $itemType])
|
||||
->andWhere('status = :status:', ['status' => $status])
|
||||
->andWhere('try_count < :try_count:', ['try_count' => $tryCount])
|
||||
->orderBy('priority ASC,try_count DESC')
|
||||
->orderBy('priority ASC')
|
||||
->limit($limit)
|
||||
->execute();
|
||||
|
||||
|
@ -1,156 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Tasks;
|
||||
|
||||
use App\Models\Reply as ReplyModel;
|
||||
use App\Models\Thread as ThreadModel;
|
||||
use App\Models\User as UserModel;
|
||||
use Phalcon\Cli\Task;
|
||||
use QL\QueryList;
|
||||
|
||||
class ReplySpiderTask extends Task
|
||||
{
|
||||
|
||||
public function mainAction()
|
||||
{
|
||||
$threads = ThreadModel::query()
|
||||
->columns(['id'])
|
||||
->where('id > 59429')
|
||||
->orderBy('id ASC')
|
||||
->execute();
|
||||
|
||||
$ql = $this->getRules();
|
||||
|
||||
foreach ($threads as $thread) {
|
||||
$this->handleList($ql, $thread->id);
|
||||
sleep(5);
|
||||
}
|
||||
}
|
||||
|
||||
protected function getRules()
|
||||
{
|
||||
$ql = QueryList::getInstance()->rules([
|
||||
'thread_content' => ['div.qa-disscus', 'html'],
|
||||
'user_link' => ['div.qa-comment-author > a', 'href'],
|
||||
'user_img' => ['div.qa-comment-author > a > img', 'src'],
|
||||
'user_name' => ['span.qa-comment-nick', 'text'],
|
||||
'reply_id' => ['div.qa-comment', 'data-cid'],
|
||||
'reply_content' => ['div.qa-comment-c > div.rich-text', 'html'],
|
||||
'reply_time' => ['span.qa-comment-time', 'text'],
|
||||
]);
|
||||
|
||||
return $ql;
|
||||
}
|
||||
|
||||
protected function handleList($ql, $threadId)
|
||||
{
|
||||
|
||||
$thread = ThreadModel::findFirst($threadId);
|
||||
|
||||
$first = true;
|
||||
|
||||
foreach (range(1, 10) as $page) {
|
||||
|
||||
$url = "https://www.imooc.com/qadetail/{$threadId}?page={$page}";
|
||||
|
||||
echo "============== Thread {$threadId}, Page {$page} =================" . PHP_EOL;
|
||||
|
||||
$data = $ql->get($url)->query()->getData();
|
||||
|
||||
if ($data->count() == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
foreach ($data->all() as $item) {
|
||||
|
||||
if ($first) {
|
||||
$threadContent = $this->getThreadContent($item['thread_content']);
|
||||
if ($threadContent) {
|
||||
$thread->update(['content' => $threadContent]);
|
||||
}
|
||||
$first = false;
|
||||
}
|
||||
|
||||
$userData = [
|
||||
'id' => $this->getUserId($item['user_link']),
|
||||
'name' => $this->getUserName($item['user_name']),
|
||||
'avatar' => $item['user_img'],
|
||||
];
|
||||
|
||||
$user = UserModel::findFirst($userData['id']);
|
||||
|
||||
if (!$user) {
|
||||
$user = new UserModel();
|
||||
$user->create($userData);
|
||||
}
|
||||
|
||||
$replyData = [
|
||||
'thread_id' => $threadId,
|
||||
'author_id' => $user->id,
|
||||
'id' => $item['reply_id'],
|
||||
'content' => $this->getReplyContent($item['reply_content']),
|
||||
'created_at' => $this->getReplyTime($item['reply_time']),
|
||||
];
|
||||
|
||||
$reply = ReplyModel::findFirst($replyData['id']);
|
||||
|
||||
if (!$reply && $replyData['content']) {
|
||||
$reply = new ReplyModel();
|
||||
$reply->create($replyData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$ql->destruct();
|
||||
}
|
||||
|
||||
protected function getUserId($userLink)
|
||||
{
|
||||
$result = str_replace(['/u/', '/bbs'], '', $userLink);
|
||||
|
||||
return trim($result);
|
||||
}
|
||||
|
||||
protected function getUserName($userName)
|
||||
{
|
||||
$result = mb_substr($userName, 0, 30);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function getThreadContent($content)
|
||||
{
|
||||
$content = str_replace(' ', ' ', $content);
|
||||
if (mb_strlen($content) > 3000) {
|
||||
return false;
|
||||
}
|
||||
$result = mb_substr($content, 0, 3000);
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function getReplyContent($content)
|
||||
{
|
||||
$content = str_replace(' ', ' ', $content);
|
||||
if (mb_strlen($content) > 1500) {
|
||||
return false;
|
||||
}
|
||||
$result = mb_substr($content, 0, 1500);
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function getReplyTime($time)
|
||||
{
|
||||
$date = $this->filter->sanitize($time, ['trim', 'string']);
|
||||
|
||||
if (strpos($date, '天')) {
|
||||
$days = str_replace(['天前'], '', $date);
|
||||
$days = intval($days);
|
||||
$result = strtotime("-{$days} days");
|
||||
} else {
|
||||
$result = strtotime(trim($date));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
@ -1,117 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Tasks;
|
||||
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Models\Review as ReviewModel;
|
||||
use App\Models\User as UserModel;
|
||||
use App\Repos\Review as ReviewRepo;
|
||||
use Phalcon\Cli\Task;
|
||||
use QL\QueryList;
|
||||
|
||||
class ReviewSpiderTask extends Task
|
||||
{
|
||||
|
||||
const BASE_URL = 'https://www.imooc.com';
|
||||
|
||||
public function mainAction()
|
||||
{
|
||||
$courses = CourseModel::query()
|
||||
->columns(['id'])
|
||||
->where('id > 778')
|
||||
->orderBy('id ASC')
|
||||
->execute();
|
||||
|
||||
$ql = $this->getRules();
|
||||
|
||||
foreach ($courses as $course) {
|
||||
$this->handleList($ql, $course->id);
|
||||
sleep(5);
|
||||
}
|
||||
}
|
||||
|
||||
protected function getRules()
|
||||
{
|
||||
$ql = QueryList::rules([
|
||||
'user_link' => ['a.img-box', 'href'],
|
||||
'user_img' => ['a.img-box > img', 'src'],
|
||||
'user_name' => ['a.img-box > img', 'alt'],
|
||||
'review_content' => ['p.content', 'text'],
|
||||
'review_rating' => ['div.star-box > span', 'text'],
|
||||
]);
|
||||
|
||||
return $ql;
|
||||
}
|
||||
|
||||
protected function handleList($ql, $courseId)
|
||||
{
|
||||
|
||||
foreach (range(1, 7) as $page) {
|
||||
|
||||
$url = "https://www.imooc.com/course/coursescore/id/{$courseId}?page={$page}";
|
||||
|
||||
echo "============== Course {$courseId}, Page {$page} =================" . PHP_EOL;
|
||||
|
||||
$data = $ql->get($url)->query()->getData();
|
||||
|
||||
if ($data->count() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($data->all() as $item) {
|
||||
|
||||
$userData = [
|
||||
'id' => $this->getUserId($item['user_link']),
|
||||
'name' => $item['user_name'],
|
||||
'avatar' => $item['user_img'],
|
||||
];
|
||||
|
||||
$user = UserModel::findFirst($userData['id']);
|
||||
|
||||
if (!$user) {
|
||||
$user = new UserModel();
|
||||
$user->create($userData);
|
||||
}
|
||||
|
||||
$reviewData = [
|
||||
'user_id' => $user->id,
|
||||
'course_id' => $courseId,
|
||||
'content' => $this->getReviewContent($item['review_content']),
|
||||
'rating' => $this->getReviewRating($item['review_rating']),
|
||||
];
|
||||
|
||||
$reviewRepo = new ReviewRepo();
|
||||
|
||||
$reviewExist = $reviewRepo->findReview($courseId, $user->id);
|
||||
|
||||
if (!$reviewExist) {
|
||||
$review = new ReviewModel();
|
||||
$review->create($reviewData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$ql->destruct();
|
||||
}
|
||||
|
||||
protected function getUserId($userLink)
|
||||
{
|
||||
$result = str_replace(['/u/', '/courses'], '', $userLink);
|
||||
|
||||
return trim($result);
|
||||
}
|
||||
|
||||
protected function getReviewRating($rating)
|
||||
{
|
||||
$result = str_replace(['分'], '', $rating);
|
||||
|
||||
return intval($result);
|
||||
}
|
||||
|
||||
protected function getReviewContent($content)
|
||||
{
|
||||
$result = $this->filter->sanitize($content, ['trim', 'string']);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
46
app/Console/Tasks/RevokeVipTask.php
Normal file
46
app/Console/Tasks/RevokeVipTask.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Tasks;
|
||||
|
||||
use App\Models\User as UserModel;
|
||||
use Phalcon\Cli\Task;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
use Phalcon\Mvc\Model\ResultsetInterface;
|
||||
|
||||
class RevokeVipTask extends Task
|
||||
{
|
||||
|
||||
public function mainAction()
|
||||
{
|
||||
$users = $this->findUsers();
|
||||
|
||||
if ($users->count() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($users as $user) {
|
||||
$user->vip = 0;
|
||||
$user->update();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找待解锁用户
|
||||
*
|
||||
* @param int $limit
|
||||
* @return UserModel[]|Resultset|ResultsetInterface
|
||||
*/
|
||||
protected function findUsers($limit = 1000)
|
||||
{
|
||||
$time = time();
|
||||
|
||||
$users = UserModel::query()
|
||||
->where('vip = 1')
|
||||
->andWhere('vip_expiry < :time:', ['time' => $time])
|
||||
->limit($limit)
|
||||
->execute();
|
||||
|
||||
return $users;
|
||||
}
|
||||
|
||||
}
|
@ -1,438 +0,0 @@
|
||||
<?php
|
||||
|
||||
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 ctAction()
|
||||
{
|
||||
$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)
|
||||
{
|
||||
$category = $params[0] ?? 'html';
|
||||
$page = $params[1] ?? 1;
|
||||
|
||||
$categoryId = $this->getCategoryId($category);
|
||||
|
||||
if (empty($categoryId)) {
|
||||
throw new \Exception('invalid category');
|
||||
}
|
||||
|
||||
$url = "http://www.imooc.com/course/list?c={$category}&page={$page}";
|
||||
|
||||
$data = QueryList::get($url)->rules([
|
||||
'link' => ['a.course-card', 'href'],
|
||||
'title' => ['h3.course-card-name', 'text'],
|
||||
'cover' => ['img.course-banner', 'data-original'],
|
||||
'summary' => ['p.course-card-desc', 'text'],
|
||||
'level' => ['.course-card-info>span:even', 'text'],
|
||||
'user_count' => ['.course-card-info>span:odd', 'text'],
|
||||
])->query()->getData();
|
||||
|
||||
if ($data->count() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($data->all() as $item) {
|
||||
$course = [
|
||||
'id' => substr($item['link'], 7),
|
||||
'category_id' => $categoryId,
|
||||
'title' => $item['title'],
|
||||
'cover' => $item['cover'],
|
||||
'summary' => $item['summary'],
|
||||
'user_count' => $item['user_count'],
|
||||
'level' => $this->getLevel($item['level']),
|
||||
];
|
||||
$model = new CourseModel();
|
||||
$model->save($course);
|
||||
}
|
||||
|
||||
echo sprintf("saved: %d course", $data->count());
|
||||
}
|
||||
|
||||
public function courseAction()
|
||||
{
|
||||
$courses = CourseModel::query()
|
||||
->where('id = 762')
|
||||
->orderBy('id asc')
|
||||
->execute();
|
||||
|
||||
$instance = QueryList::getInstance();
|
||||
|
||||
foreach ($courses as $course) {
|
||||
|
||||
$url = "http://www.imooc.com/learn/{$course->id}";
|
||||
|
||||
$ql = $instance->get($url);
|
||||
|
||||
//$this->handleCourseInfo($course, $ql);
|
||||
|
||||
$this->handleCourseChapters($course, $ql);
|
||||
|
||||
//$ql->destruct();
|
||||
|
||||
echo "finished course " . $course->id . PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
public function teacherAction()
|
||||
{
|
||||
$users = UserModel::query()
|
||||
->where('edu_role = 2')
|
||||
->execute();
|
||||
|
||||
foreach ($users as $user) {
|
||||
try {
|
||||
$this->handleTeacherInfo2($user);
|
||||
echo "finished teacher: {$user->id}" . PHP_EOL;
|
||||
} catch (\Exception $e) {
|
||||
echo $e->getMessage() . PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function handleTeacherInfo2(UserModel $user)
|
||||
{
|
||||
$url = "http://www.imooc.com/t/{$user->id}";
|
||||
|
||||
$ql = QueryList::getInstance()->get($url);
|
||||
|
||||
$data = [];
|
||||
|
||||
$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->update($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)
|
||||
{
|
||||
$data = [];
|
||||
|
||||
$data['user_id'] = $ql->find('img.js-usercard-dialog')->attr('data-userid');
|
||||
$data['description'] = $ql->find('.course-description')->text();
|
||||
$data['duration'] = $ql->find('.static-item:eq(1)>.meta-value')->text();
|
||||
$data['score'] = $ql->find('.score-btn>.meta-value')->text();
|
||||
|
||||
$data['attrs']['duration'] = $this->getCourseDuration($data['duration']);
|
||||
|
||||
$course->update($data);
|
||||
|
||||
if ($data['user_id']) {
|
||||
$this->handleTeacherInfo($course->id, $data['user_id']);
|
||||
}
|
||||
|
||||
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'],
|
||||
])->query()->getData();
|
||||
|
||||
|
||||
if ($topChapters->count() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($topChapters->all() as $item) {
|
||||
|
||||
$data = [
|
||||
'course_id' => $course->id,
|
||||
'title' => $item['title'],
|
||||
];
|
||||
|
||||
// create top chapter
|
||||
$chapter = new ChapterModel();
|
||||
$chapter->create($data);
|
||||
|
||||
// create sub chapter
|
||||
if (!empty($item['sub_chapter_html'])) {
|
||||
$this->handleSubChapters($chapter, $item['sub_chapter_html']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function handleSubChapters(ChapterModel $topChapter, $subChapterHtml)
|
||||
{
|
||||
$ql = QueryList::html($subChapterHtml);
|
||||
|
||||
$chapters = $ql->find('li')->texts();
|
||||
|
||||
if ($chapters->count() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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 = [
|
||||
* '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);
|
||||
}
|
||||
}
|
||||
|
||||
protected function getCourseDuration($duration)
|
||||
{
|
||||
$hours = 0;
|
||||
$minutes = 0;
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
return 3600 * $hours + 60 * $minutes;
|
||||
}
|
||||
|
||||
protected function getChapterDuration($duration)
|
||||
{
|
||||
if (strpos($duration, ':') === false) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
list($minutes, $seconds) = explode(':', trim($duration));
|
||||
|
||||
return 60 * $minutes + $seconds;
|
||||
}
|
||||
|
||||
protected function getLevel($type)
|
||||
{
|
||||
$mapping = [
|
||||
'入门' => CourseModel::LEVEL_ENTRY,
|
||||
'初级' => CourseModel::LEVEL_JUNIOR,
|
||||
'中级' => CourseModel::LEVEL_MEDIUM,
|
||||
'高级' => CourseModel::LEVEL_SENIOR,
|
||||
];
|
||||
|
||||
return $mapping[$type] ?? CourseModel::LEVEL_ENTRY;
|
||||
}
|
||||
|
||||
protected function getCategoryId($type)
|
||||
{
|
||||
$mapping = [
|
||||
'html' => 1, 'javascript' => 2, 'vuejs' => 10, 'reactjs' => 19,
|
||||
'angular' => 18, 'nodejs' => 16, 'jquery' => 15,
|
||||
'bootstrap' => 17, 'sassless' => 21, 'webapp' => 22, 'fetool' => 23,
|
||||
'html5' => 13, 'css3' => 14,
|
||||
'php' => 24, 'java' => 25, 'python' => 26, 'c' => 27, 'cplusplus' => 28, 'ruby' => 29, 'go' => 30, 'csharp' => 31,
|
||||
'android' => 32, 'ios' => 33,
|
||||
'mysql' => 36, 'mongodb' => 37, 'redis' => 38, 'oracle' => 39, 'pgsql' => 40,
|
||||
'cloudcomputing' => 42, 'bigdata' => 43,
|
||||
'unity3d' => 34, 'cocos2dx' => 35,
|
||||
'dxdh' => 46, 'uitool' => 47, 'uijc' => 48,
|
||||
];
|
||||
|
||||
return $mapping[$type] ?? 0;
|
||||
}
|
||||
|
||||
}
|
@ -1,145 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Tasks;
|
||||
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Models\Thread as ThreadModel;
|
||||
use App\Models\User as UserModel;
|
||||
use Phalcon\Cli\Task;
|
||||
use QL\QueryList;
|
||||
|
||||
class ThreadSpiderTask extends Task
|
||||
{
|
||||
|
||||
public function mainAction()
|
||||
{
|
||||
$courses = CourseModel::query()
|
||||
->columns(['id'])
|
||||
->where('id > 494')
|
||||
->orderBy('id ASC')
|
||||
->execute();
|
||||
|
||||
$ql = $this->getRules();
|
||||
|
||||
foreach ($courses as $course) {
|
||||
$this->handleList($ql, $course->id);
|
||||
sleep(5);
|
||||
}
|
||||
}
|
||||
|
||||
protected function getRules()
|
||||
{
|
||||
$ql = QueryList::rules([
|
||||
'user_link' => ['a.media', 'href'],
|
||||
'user_img' => ['a.media > img', 'src'],
|
||||
'user_name' => ['a.media', 'title'],
|
||||
//'chapter_link' => ['div.l-box > a:eq(1)', 'href'],
|
||||
'thread_link' => ['a.qa-tit', 'href'],
|
||||
'thread_title' => ['a.qa-tit', 'text'],
|
||||
'thread_time' => ['em.r', 'text'],
|
||||
]);
|
||||
|
||||
return $ql;
|
||||
}
|
||||
|
||||
protected function handleList($ql, $courseId)
|
||||
{
|
||||
|
||||
foreach (range(1, 10) as $page) {
|
||||
|
||||
$url = "https://www.imooc.com/course/qa/id/{$courseId}/t/2?page={$page}";
|
||||
|
||||
echo "============== Course {$courseId}, Page {$page} =================" . PHP_EOL;
|
||||
|
||||
$data = $ql->get($url)->query()->getData();
|
||||
|
||||
if ($data->count() == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
foreach ($data->all() as $item) {
|
||||
|
||||
$userData = [
|
||||
'id' => $this->getUserId($item['user_link']),
|
||||
'name' => $this->getUserName($item['user_name']),
|
||||
'avatar' => $item['user_img'],
|
||||
];
|
||||
|
||||
$user = UserModel::findFirst($userData['id']);
|
||||
|
||||
if (!$user) {
|
||||
$user = new UserModel();
|
||||
$user->create($userData);
|
||||
}
|
||||
|
||||
$threadData = [
|
||||
'course_id' => $courseId,
|
||||
'author_id' => $user->id,
|
||||
'id' => $this->getThreadId($item['thread_link']),
|
||||
'title' => $this->getThreadTitle($item['thread_title']),
|
||||
'created_at' => $this->getThreadTime($item['thread_time']),
|
||||
];
|
||||
|
||||
$thread = ThreadModel::findFirst($threadData['id']);
|
||||
|
||||
if (!$thread) {
|
||||
$thread = new ThreadModel();
|
||||
$thread->create($threadData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$ql->destruct();
|
||||
}
|
||||
|
||||
protected function getUserId($userLink)
|
||||
{
|
||||
$result = str_replace(['/u/', '/courses'], '', $userLink);
|
||||
|
||||
return trim($result);
|
||||
}
|
||||
|
||||
protected function getUserName($userName)
|
||||
{
|
||||
$result = mb_substr($userName, 0, 30);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function getChapterId($chapterLink)
|
||||
{
|
||||
$result = str_replace(['/video/'], '', $chapterLink);
|
||||
|
||||
return trim($result);
|
||||
}
|
||||
|
||||
protected function getThreadId($threadLink)
|
||||
{
|
||||
$result = str_replace(['/qadetail/'], '', $threadLink);
|
||||
|
||||
return trim($result);
|
||||
}
|
||||
|
||||
protected function getThreadTitle($title)
|
||||
{
|
||||
$title = $this->filter->sanitize($title, ['trim']);
|
||||
$result = mb_substr($title, 0, 120);
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function getThreadTime($time)
|
||||
{
|
||||
$date = $this->filter->sanitize($time, ['trim', 'string']);
|
||||
|
||||
if (strpos($date, '天')) {
|
||||
$days = str_replace(['天前'], '', $date);
|
||||
$days = intval($days);
|
||||
$result = strtotime("-{$days} days");
|
||||
} else {
|
||||
$result = strtotime(trim($date));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Tasks;
|
||||
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Models\Topic as TopicModel;
|
||||
use Phalcon\Cli\Task;
|
||||
|
||||
class TopicSpiderTask extends Task
|
||||
{
|
||||
|
||||
public function mainAction()
|
||||
{
|
||||
$courses = CourseModel::query()
|
||||
->columns(['id'])
|
||||
->where('id > 810')
|
||||
->orderBy('id ASC')
|
||||
->execute();
|
||||
|
||||
foreach ($courses as $course) {
|
||||
$this->handleList($course->id);
|
||||
sleep(5);
|
||||
}
|
||||
}
|
||||
|
||||
protected function handleList($courseId)
|
||||
{
|
||||
$url = "https://www.imooc.com/course/ajaxskillcourse?cid={$courseId}";
|
||||
|
||||
$content = file_get_contents($url);
|
||||
|
||||
$result = json_decode($content, true);
|
||||
|
||||
$topics = $result['data'];
|
||||
|
||||
echo "============== Course {$courseId} =================" . PHP_EOL;
|
||||
|
||||
if (empty($topics)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($topics as $item) {
|
||||
|
||||
$topicData = [
|
||||
'id' => $item['subject_id'],
|
||||
'title' => $item['title'],
|
||||
'alias' => $this->getAlias($item['url']),
|
||||
];
|
||||
|
||||
$topic = TopicModel::findFirst($topicData['id']);
|
||||
|
||||
if (!$topic) {
|
||||
$topic = new TopicModel();
|
||||
$topic->create($topicData);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected function getAlias($url)
|
||||
{
|
||||
$result = str_replace('//www.imooc.com/topic/', '', $url);
|
||||
return trim($result);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -4,6 +4,8 @@ namespace App\Console\Tasks;
|
||||
|
||||
use App\Models\User as UserModel;
|
||||
use Phalcon\Cli\Task;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
use Phalcon\Mvc\Model\ResultsetInterface;
|
||||
|
||||
class UnlockUserTask extends Task
|
||||
{
|
||||
@ -18,7 +20,6 @@ class UnlockUserTask extends Task
|
||||
|
||||
foreach ($users as $user) {
|
||||
$user->locked = 0;
|
||||
$user->lock_expiry = 0;
|
||||
$user->update();
|
||||
}
|
||||
}
|
||||
@ -27,7 +28,7 @@ class UnlockUserTask extends Task
|
||||
* 查找待解锁用户
|
||||
*
|
||||
* @param int $limit
|
||||
* @return \Phalcon\Mvc\Model\ResultsetInterface
|
||||
* @return UserModel[]|Resultset|ResultsetInterface
|
||||
*/
|
||||
protected function findUsers($limit = 1000)
|
||||
{
|
||||
|
@ -101,9 +101,9 @@ class ChapterController extends Controller
|
||||
switch ($course->model) {
|
||||
case CourseModel::MODEL_VOD:
|
||||
$vod = $contentService->getChapterVod($chapter->id);
|
||||
$vodFiles = $contentService->getVodFiles($chapter->id);
|
||||
$playUrls = $contentService->getPlayUrls($chapter->id);
|
||||
$this->view->setVar('vod', $vod);
|
||||
$this->view->setVar('vod_files', $vodFiles);
|
||||
$this->view->setVar('play_urls', $playUrls);
|
||||
break;
|
||||
case CourseModel::MODEL_LIVE:
|
||||
$live = $contentService->getChapterLive($chapter->id);
|
||||
|
121
app/Http/Admin/Controllers/CommentController.php
Normal file
121
app/Http/Admin/Controllers/CommentController.php
Normal file
@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Admin\Controllers;
|
||||
|
||||
use App\Http\Admin\Services\Comment as CommentService;
|
||||
|
||||
/**
|
||||
* @RoutePrefix("/admin/comment")
|
||||
*/
|
||||
class CommentController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* @Get("/search", name="admin.comment.search")
|
||||
*/
|
||||
public function searchAction()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/list", name="admin.comment.list")
|
||||
*/
|
||||
public function listAction()
|
||||
{
|
||||
$courseId = $this->request->getQuery('course_id', 'int', 0);
|
||||
$chapterId = $this->request->getQuery('chapter_id', 'int', 0);
|
||||
|
||||
$commentService = new CommentService();
|
||||
|
||||
$pager = $commentService->getComments();
|
||||
|
||||
$chapter = null;
|
||||
|
||||
if ($chapterId > 0) {
|
||||
$chapter = $commentService->getChapter($chapterId);
|
||||
$courseId = $chapter->course_id;
|
||||
}
|
||||
|
||||
$course = null;
|
||||
|
||||
if ($courseId > 0) {
|
||||
$course = $commentService->getCourse($courseId);
|
||||
}
|
||||
|
||||
$this->view->setVar('pager', $pager);
|
||||
$this->view->setVar('course', $course);
|
||||
$this->view->setVar('chapter', $chapter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/{id:[0-9]+}/edit", name="admin.comment.edit")
|
||||
*/
|
||||
public function editAction($id)
|
||||
{
|
||||
$commentService = new CommentService();
|
||||
|
||||
$comment = $commentService->getComment($id);
|
||||
|
||||
$this->view->setVar('comment', $comment);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/{id:[0-9]+}/update", name="admin.comment.update")
|
||||
*/
|
||||
public function updateAction($id)
|
||||
{
|
||||
$commentService = new CommentService();
|
||||
|
||||
$commentService->update($id);
|
||||
|
||||
$location = $this->request->getHTTPReferer();
|
||||
|
||||
$content = [
|
||||
'location' => $location,
|
||||
'msg' => '更新评论成功',
|
||||
];
|
||||
|
||||
return $this->ajaxSuccess($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/{id:[0-9]+}/delete", name="admin.comment.delete")
|
||||
*/
|
||||
public function deleteAction($id)
|
||||
{
|
||||
$commentService = new CommentService();
|
||||
|
||||
$commentService->deleteComment($id);
|
||||
|
||||
$location = $this->request->getHTTPReferer();
|
||||
|
||||
$content = [
|
||||
'location' => $location,
|
||||
'msg' => '删除评论成功',
|
||||
];
|
||||
|
||||
return $this->ajaxSuccess($content);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @Post("/{id:[0-9]+}/restore", name="admin.comment.restore")
|
||||
*/
|
||||
public function restoreAction($id)
|
||||
{
|
||||
$commentService = new CommentService();
|
||||
|
||||
$commentService->restoreComment($id);
|
||||
|
||||
$location = $this->request->getHTTPReferer();
|
||||
|
||||
$content = [
|
||||
'location' => $location,
|
||||
'msg' => '还原评论成功',
|
||||
];
|
||||
|
||||
return $this->ajaxSuccess($content);
|
||||
}
|
||||
|
||||
}
|
@ -157,10 +157,10 @@ class ConfigController extends Controller
|
||||
} else {
|
||||
|
||||
$alipay = $configService->getSectionConfig('payment.alipay');
|
||||
$wxpay = $configService->getSectionConfig('payment.wxpay');
|
||||
$wechat = $configService->getSectionConfig('payment.wechat');
|
||||
|
||||
$this->view->setVar('alipay', $alipay);
|
||||
$this->view->setVar('wxpay', $wxpay);
|
||||
$this->view->setVar('wechat', $wechat);
|
||||
}
|
||||
}
|
||||
|
||||
@ -252,23 +252,21 @@ class ConfigController extends Controller
|
||||
*/
|
||||
public function vipAction()
|
||||
{
|
||||
$section = 'vip';
|
||||
|
||||
$configService = new ConfigService();
|
||||
|
||||
if ($this->request->isPost()) {
|
||||
|
||||
$data = $this->request->getPost();
|
||||
$data = $this->request->getPost('vip');
|
||||
|
||||
$configService->updateSectionConfig($section, $data);
|
||||
$configService->updateVipConfig($data);
|
||||
|
||||
return $this->ajaxSuccess(['msg' => '更新配置成功']);
|
||||
|
||||
} else {
|
||||
|
||||
$vip = $configService->getSectionConfig($section);
|
||||
$vips = $configService->getVipConfig();
|
||||
|
||||
$this->view->setVar('vip', $vip);
|
||||
$this->view->setVar('vips', $vips);
|
||||
}
|
||||
}
|
||||
|
||||
|
108
app/Http/Admin/Controllers/ConsultController.php
Normal file
108
app/Http/Admin/Controllers/ConsultController.php
Normal file
@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Admin\Controllers;
|
||||
|
||||
use App\Http\Admin\Services\Consult as ConsultService;
|
||||
|
||||
/**
|
||||
* @RoutePrefix("/admin/consult")
|
||||
*/
|
||||
class ConsultController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* @Get("/search", name="admin.consult.search")
|
||||
*/
|
||||
public function searchAction()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/list", name="admin.consult.list")
|
||||
*/
|
||||
public function listAction()
|
||||
{
|
||||
$courseId = $this->request->getQuery('course_id', 'int', 0);
|
||||
|
||||
$consultService = new ConsultService();
|
||||
|
||||
$pager = $consultService->getConsults();
|
||||
|
||||
$course = null;
|
||||
|
||||
if ($courseId > 0) {
|
||||
$course = $consultService->getCourse($courseId);
|
||||
}
|
||||
|
||||
$this->view->setVar('pager', $pager);
|
||||
$this->view->setVar('course', $course);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/{id:[0-9]+}/edit", name="admin.consult.edit")
|
||||
*/
|
||||
public function editAction($id)
|
||||
{
|
||||
$consultService = new ConsultService();
|
||||
|
||||
$consult = $consultService->getConsult($id);
|
||||
|
||||
$this->view->setVar('consult', $consult);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/{id:[0-9]+}/update", name="admin.consult.update")
|
||||
*/
|
||||
public function updateAction($id)
|
||||
{
|
||||
$consultService = new ConsultService();
|
||||
|
||||
$consultService->updateConsult($id);
|
||||
|
||||
$content = [
|
||||
'msg' => '更新咨询成功',
|
||||
];
|
||||
|
||||
return $this->ajaxSuccess($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/{id:[0-9]+}/delete", name="admin.consult.delete")
|
||||
*/
|
||||
public function deleteAction($id)
|
||||
{
|
||||
$consultService = new ConsultService();
|
||||
|
||||
$consultService->deleteConsult($id);
|
||||
|
||||
$location = $this->request->getHTTPReferer();
|
||||
|
||||
$content = [
|
||||
'location' => $location,
|
||||
'msg' => '删除咨询成功',
|
||||
];
|
||||
|
||||
return $this->ajaxSuccess($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/{id:[0-9]+}/restore", name="admin.consult.restore")
|
||||
*/
|
||||
public function restoreAction($id)
|
||||
{
|
||||
$consultService = new ConsultService();
|
||||
|
||||
$consultService->restoreConsult($id);
|
||||
|
||||
$location = $this->request->getHTTPReferer();
|
||||
|
||||
$content = [
|
||||
'location' => $location,
|
||||
'msg' => '还原咨询成功',
|
||||
];
|
||||
|
||||
return $this->ajaxSuccess($content);
|
||||
}
|
||||
|
||||
}
|
@ -75,11 +75,15 @@ class CourseController extends Controller
|
||||
$xmTeachers = $courseService->getXmTeachers($id);
|
||||
$xmCategories = $courseService->getXmCategories($id);
|
||||
$xmCourses = $courseService->getXmCourses($id);
|
||||
$studyExpiryOptions = $courseService->getStudyExpiryOptions();
|
||||
$refundExpiryOptions = $courseService->getRefundExpiryOptions();
|
||||
|
||||
$this->view->setVar('course', $course);
|
||||
$this->view->setVar('xm_teachers', $xmTeachers);
|
||||
$this->view->setVar('xm_categories', $xmCategories);
|
||||
$this->view->setVar('xm_courses', $xmCourses);
|
||||
$this->view->setVar('study_expiry_options', $studyExpiryOptions);
|
||||
$this->view->setVar('refund_expiry_options', $refundExpiryOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,8 +38,8 @@ class OrderController extends Controller
|
||||
$orderService = new OrderService();
|
||||
|
||||
$order = $orderService->getOrder($id);
|
||||
$trades = $orderService->getTrades($order->sn);
|
||||
$refunds = $orderService->getRefunds($order->sn);
|
||||
$trades = $orderService->getTrades($order->id);
|
||||
$refunds = $orderService->getRefunds($order->id);
|
||||
$account = $orderService->getAccount($order->user_id);
|
||||
$user = $orderService->getUser($order->user_id);
|
||||
|
||||
|
@ -38,8 +38,8 @@ class RefundController extends Controller
|
||||
$refundService = new RefundService();
|
||||
|
||||
$refund = $refundService->getRefund($id);
|
||||
$order = $refundService->getOrder($refund->order_sn);
|
||||
$trade = $refundService->getTrade($refund->trade_sn);
|
||||
$order = $refundService->getOrder($refund->order_id);
|
||||
$trade = $refundService->getTrade($refund->trade_id);
|
||||
$account = $refundService->getAccount($trade->user_id);
|
||||
$user = $refundService->getUser($trade->user_id);
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Http\Admin\Controllers;
|
||||
|
||||
use App\Http\Admin\Services\CourseStudent as CourseStudentService;
|
||||
use App\Http\Admin\Services\Student as StudentService;
|
||||
|
||||
/**
|
||||
* @RoutePrefix("/admin/student")
|
||||
@ -23,14 +23,20 @@ class StudentController extends Controller
|
||||
*/
|
||||
public function listAction()
|
||||
{
|
||||
$courseId = $this->request->getQuery('course_id', 'int', '');
|
||||
$courseId = $this->request->getQuery('course_id', 'int', 0);
|
||||
|
||||
$courseStudentService = new CourseStudentService();
|
||||
$studentService = new StudentService();
|
||||
|
||||
$pager = $courseStudentService->getCourseStudents();
|
||||
$pager = $studentService->getPlans();
|
||||
|
||||
$course = null;
|
||||
|
||||
if ($courseId > 0) {
|
||||
$course = $studentService->getCourse($courseId);
|
||||
}
|
||||
|
||||
$this->view->setVar('pager', $pager);
|
||||
$this->view->setVar('course_id', $courseId);
|
||||
$this->view->setVar('course', $course);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -38,9 +44,17 @@ class StudentController extends Controller
|
||||
*/
|
||||
public function addAction()
|
||||
{
|
||||
$courseId = $this->request->getQuery('course_id', 'int', '');
|
||||
$courseId = $this->request->getQuery('course_id', 'int', 0);
|
||||
|
||||
$this->view->setVar('course_id', $courseId);
|
||||
$studentService = new StudentService();
|
||||
|
||||
$course = null;
|
||||
|
||||
if ($courseId > 0) {
|
||||
$course = $studentService->getCourse($courseId);
|
||||
}
|
||||
|
||||
$this->view->setVar('course', $course);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -48,9 +62,9 @@ class StudentController extends Controller
|
||||
*/
|
||||
public function createAction()
|
||||
{
|
||||
$courseStudentService = new CourseStudentService();
|
||||
$studentService = new StudentService();
|
||||
|
||||
$student = $courseStudentService->createCourseStudent();
|
||||
$student = $studentService->createPlan();
|
||||
|
||||
$location = $this->url->get(
|
||||
['for' => 'admin.student.list'],
|
||||
@ -70,16 +84,15 @@ class StudentController extends Controller
|
||||
*/
|
||||
public function editAction()
|
||||
{
|
||||
$courseId = $this->request->getQuery('course_id', 'int');
|
||||
$userId = $this->request->getQuery('user_id', 'int');
|
||||
$planId = $this->request->getQuery('plan_id');
|
||||
|
||||
$courseStudentService = new CourseStudentService();
|
||||
$studentService = new StudentService();
|
||||
|
||||
$courseStudent = $courseStudentService->getCourseStudent($courseId, $userId);
|
||||
$course = $courseStudentService->getCourse($courseId);
|
||||
$student = $courseStudentService->getStudent($userId);
|
||||
$plan = $studentService->getPlan($planId);
|
||||
$course = $studentService->getCourse($plan->course_id);
|
||||
$student = $studentService->getStudent($plan->user_id);
|
||||
|
||||
$this->view->setVar('course_student', $courseStudent);
|
||||
$this->view->setVar('plan', $plan);
|
||||
$this->view->setVar('course', $course);
|
||||
$this->view->setVar('student', $student);
|
||||
}
|
||||
@ -89,14 +102,11 @@ class StudentController extends Controller
|
||||
*/
|
||||
public function updateAction()
|
||||
{
|
||||
$courseStudentService = new CourseStudentService();
|
||||
$studentService = new StudentService();
|
||||
|
||||
$student = $courseStudentService->updateCourseStudent();
|
||||
$studentService->updatePlan();
|
||||
|
||||
$location = $this->url->get(
|
||||
['for' => 'admin.student.list'],
|
||||
['course_id' => $student->course_id]
|
||||
);
|
||||
$location = $this->url->get(['for' => 'admin.student.list']);
|
||||
|
||||
$content = [
|
||||
'location' => $location,
|
||||
@ -111,9 +121,9 @@ class StudentController extends Controller
|
||||
*/
|
||||
public function learningAction()
|
||||
{
|
||||
$courseStudentService = new CourseStudentService();
|
||||
$studentService = new StudentService();
|
||||
|
||||
$pager = $courseStudentService->getCourseLearnings();
|
||||
$pager = $studentService->getLearnings();
|
||||
|
||||
$this->view->setVar('pager', $pager);
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ class TestController extends Controller
|
||||
$this->db->rollback();
|
||||
}
|
||||
|
||||
$this->view->pick('config/alipay_test');
|
||||
$this->view->pick('config/payment_alipay_test');
|
||||
$this->view->setVar('trade', $trade);
|
||||
$this->view->setVar('qrcode', $qrcode);
|
||||
}
|
||||
|
@ -38,8 +38,8 @@ class TradeController extends Controller
|
||||
$tradeService = new TradeService();
|
||||
|
||||
$trade = $tradeService->getTrade($id);
|
||||
$refunds = $tradeService->getRefunds($trade->sn);
|
||||
$order = $tradeService->getOrder($trade->order_sn);
|
||||
$refunds = $tradeService->getRefunds($trade->id);
|
||||
$order = $tradeService->getOrder($trade->order_id);
|
||||
$account = $tradeService->getAccount($trade->user_id);
|
||||
$user = $tradeService->getUser($trade->user_id);
|
||||
|
||||
|
@ -5,13 +5,13 @@ namespace App\Http\Admin\Controllers;
|
||||
use App\Services\Storage as StorageService;
|
||||
|
||||
/**
|
||||
* @RoutePrefix("/admin/storage")
|
||||
* @RoutePrefix("/admin/upload")
|
||||
*/
|
||||
class StorageController extends Controller
|
||||
class UploadController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* @Post("/cover/img/upload", name="admin.storage.cover.img.upload")
|
||||
* @Post("/cover/img", name="admin.upload.cover.img")
|
||||
*/
|
||||
public function uploadCoverImageAction()
|
||||
{
|
||||
@ -29,7 +29,7 @@ class StorageController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/content/img/upload", name="admin.content.img.upload")
|
||||
* @Post("/content/img", name="admin.upload.content.img")
|
||||
*/
|
||||
public function uploadContentImageAction()
|
||||
{
|
@ -81,9 +81,11 @@ class UserController extends Controller
|
||||
$userService = new UserService();
|
||||
|
||||
$user = $userService->getUser($id);
|
||||
$account = $userService->getAccount($id);
|
||||
$roles = $userService->getRoles();
|
||||
|
||||
$this->view->setVar('user', $user);
|
||||
$this->view->setVar('account', $account);
|
||||
$this->view->setVar('roles', $roles);
|
||||
}
|
||||
|
||||
@ -92,9 +94,15 @@ class UserController extends Controller
|
||||
*/
|
||||
public function updateAction($id)
|
||||
{
|
||||
$type = $this->request->getPost('type');
|
||||
|
||||
$userService = new UserService();
|
||||
|
||||
$userService->updateUser($id);
|
||||
if ($type == 'user') {
|
||||
$userService->updateUser($id);
|
||||
} else {
|
||||
$userService->updateAccount($id);
|
||||
}
|
||||
|
||||
$location = $this->url->get(['for' => 'admin.user.list']);
|
||||
|
||||
|
@ -18,9 +18,9 @@ class VodController extends Controller
|
||||
*/
|
||||
public function uploadSignatureAction()
|
||||
{
|
||||
$service = new VodService();
|
||||
$vodService = new VodService();
|
||||
|
||||
$signature = $service->getUploadSignature();
|
||||
$signature = $vodService->getUploadSignature();
|
||||
|
||||
return $this->ajaxSuccess(['signature' => $signature]);
|
||||
}
|
||||
@ -30,7 +30,6 @@ class VodController extends Controller
|
||||
*/
|
||||
public function playerAction()
|
||||
{
|
||||
$courseId = $this->request->getQuery('course_id');
|
||||
$chapterId = $this->request->getQuery('chapter_id');
|
||||
$playUrl = $this->request->getQuery('play_url');
|
||||
|
||||
@ -38,7 +37,6 @@ class VodController extends Controller
|
||||
|
||||
$this->view->pick('public/vod_player');
|
||||
|
||||
$this->view->setVar('course_id', $courseId);
|
||||
$this->view->setVar('chapter_id', $chapterId);
|
||||
$this->view->setVar('play_url', urldecode($playUrl));
|
||||
}
|
||||
@ -54,13 +52,12 @@ class VodController extends Controller
|
||||
|
||||
$learning->user_id = $this->authUser->id;
|
||||
$learning->request_id = $query['request_id'];
|
||||
$learning->course_id = $query['course_id'];
|
||||
$learning->chapter_id = $query['chapter_id'];
|
||||
$learning->position = $query['position'];
|
||||
|
||||
$syncerService = new LearningSyncerService();
|
||||
|
||||
$syncerService->save($learning, $query['timeout']);
|
||||
$syncerService->addItem($learning, $query['timeout']);
|
||||
|
||||
return $this->ajaxSuccess();
|
||||
}
|
||||
|
@ -26,7 +26,9 @@ class AlipayTest extends PaymentTest
|
||||
];
|
||||
|
||||
$alipayService = new AlipayService();
|
||||
|
||||
$qrcode = $alipayService->getQrCode($outOrder);
|
||||
|
||||
$result = $qrcode ?: false;
|
||||
|
||||
return $result;
|
||||
@ -40,12 +42,15 @@ class AlipayTest extends PaymentTest
|
||||
public function cancelTestOrder($sn)
|
||||
{
|
||||
$tradeRepo = new TradeRepo();
|
||||
|
||||
$trade = $tradeRepo->findBySn($sn);
|
||||
|
||||
$orderRepo = new OrderRepo();
|
||||
$order = $orderRepo->findBySn($trade->order_sn);
|
||||
|
||||
$order = $orderRepo->findById($trade->order_id);
|
||||
|
||||
$alipayService = new AlipayService();
|
||||
|
||||
$response = $alipayService->cancelOrder($trade->sn);
|
||||
|
||||
if ($response) {
|
||||
|
@ -2,9 +2,9 @@
|
||||
|
||||
namespace App\Http\Admin\Services;
|
||||
|
||||
use Phalcon\Mvc\User\Component as UserComponent;
|
||||
use Phalcon\Mvc\User\Component;
|
||||
|
||||
class AuthMenu extends UserComponent
|
||||
class AuthMenu extends Component
|
||||
|
||||
{
|
||||
|
||||
|
@ -154,6 +154,68 @@ class AuthNode extends Service
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'id' => '1-5',
|
||||
'label' => '单页管理',
|
||||
'type' => 'menu',
|
||||
'child' => [
|
||||
[
|
||||
'id' => '1-5-1',
|
||||
'label' => '单页列表',
|
||||
'type' => 'menu',
|
||||
'route' => 'admin.page.list',
|
||||
],
|
||||
[
|
||||
'id' => '1-5-2',
|
||||
'label' => '添加单页',
|
||||
'type' => 'menu',
|
||||
'route' => 'admin.page.add',
|
||||
],
|
||||
[
|
||||
'id' => '1-5-3',
|
||||
'label' => '编辑单页',
|
||||
'type' => 'button',
|
||||
'route' => 'admin.page.edit',
|
||||
],
|
||||
[
|
||||
'id' => '1-5-4',
|
||||
'label' => '删除单页',
|
||||
'type' => 'button',
|
||||
'route' => 'admin.page.delete',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'id' => '1-6',
|
||||
'label' => '帮助管理',
|
||||
'type' => 'menu',
|
||||
'child' => [
|
||||
[
|
||||
'id' => '1-6-1',
|
||||
'label' => '帮助列表',
|
||||
'type' => 'menu',
|
||||
'route' => 'admin.help.list',
|
||||
],
|
||||
[
|
||||
'id' => '1-6-2',
|
||||
'label' => '添加帮助',
|
||||
'type' => 'menu',
|
||||
'route' => 'admin.help.add',
|
||||
],
|
||||
[
|
||||
'id' => '1-6-3',
|
||||
'label' => '编辑帮助',
|
||||
'type' => 'button',
|
||||
'route' => 'admin.help.edit',
|
||||
],
|
||||
[
|
||||
'id' => '1-6-4',
|
||||
'label' => '删除帮助',
|
||||
'type' => 'button',
|
||||
'route' => 'admin.help.delete',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
@ -167,30 +229,30 @@ class AuthNode extends Service
|
||||
'label' => '运营管理',
|
||||
'child' => [
|
||||
[
|
||||
'id' => '2-5',
|
||||
'id' => '2-1',
|
||||
'label' => '学员管理',
|
||||
'type' => 'menu',
|
||||
'child' => [
|
||||
[
|
||||
'id' => '2-5-1',
|
||||
'id' => '2-1-1',
|
||||
'label' => '学员列表',
|
||||
'type' => 'menu',
|
||||
'route' => 'admin.student.list',
|
||||
],
|
||||
[
|
||||
'id' => '2-5-2',
|
||||
'id' => '2-1-2',
|
||||
'label' => '搜索学员',
|
||||
'type' => 'menu',
|
||||
'route' => 'admin.student.search',
|
||||
],
|
||||
[
|
||||
'id' => '2-5-3',
|
||||
'id' => '2-1-3',
|
||||
'label' => '添加学员',
|
||||
'type' => 'menu',
|
||||
'route' => 'admin.student.add',
|
||||
],
|
||||
[
|
||||
'id' => '2-5-4',
|
||||
'id' => '2-1-4',
|
||||
'label' => '编辑学员',
|
||||
'type' => 'button',
|
||||
'route' => 'admin.student.edit',
|
||||
@ -198,30 +260,61 @@ class AuthNode extends Service
|
||||
],
|
||||
],
|
||||
[
|
||||
'id' => '2-1',
|
||||
'id' => '2-2',
|
||||
'label' => '咨询管理',
|
||||
'type' => 'menu',
|
||||
'child' => [
|
||||
[
|
||||
'id' => '2-2-1',
|
||||
'label' => '咨询列表',
|
||||
'type' => 'menu',
|
||||
'route' => 'admin.consult.list',
|
||||
],
|
||||
[
|
||||
'id' => '2-2-2',
|
||||
'label' => '搜索咨询',
|
||||
'type' => 'menu',
|
||||
'route' => 'admin.consult.search',
|
||||
],
|
||||
[
|
||||
'id' => '2-2-3',
|
||||
'label' => '编辑咨询',
|
||||
'type' => 'button',
|
||||
'route' => 'admin.consult.edit',
|
||||
],
|
||||
[
|
||||
'id' => '2-2-4',
|
||||
'label' => '删除咨询',
|
||||
'type' => 'button',
|
||||
'route' => 'admin.consult.delete',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'id' => '2-3',
|
||||
'label' => '评价管理',
|
||||
'type' => 'menu',
|
||||
'child' => [
|
||||
[
|
||||
'id' => '2-1-1',
|
||||
'id' => '2-3-1',
|
||||
'label' => '评价列表',
|
||||
'type' => 'menu',
|
||||
'route' => 'admin.review.list',
|
||||
],
|
||||
[
|
||||
'id' => '2-1-2',
|
||||
'id' => '2-3-2',
|
||||
'label' => '搜索评价',
|
||||
'type' => 'menu',
|
||||
'route' => 'admin.review.search',
|
||||
],
|
||||
[
|
||||
'id' => '2-1-3',
|
||||
'id' => '2-3-3',
|
||||
'label' => '编辑评价',
|
||||
'type' => 'button',
|
||||
'route' => 'admin.review.edit',
|
||||
],
|
||||
[
|
||||
'id' => '2-1-4',
|
||||
'id' => '2-3-4',
|
||||
'label' => '删除评价',
|
||||
'type' => 'button',
|
||||
'route' => 'admin.review.delete',
|
||||
@ -229,67 +322,67 @@ class AuthNode extends Service
|
||||
],
|
||||
],
|
||||
[
|
||||
'id' => '2-3',
|
||||
'id' => '2-4',
|
||||
'label' => '评论管理',
|
||||
'type' => 'menu',
|
||||
'child' => [
|
||||
[
|
||||
'id' => '2-4-1',
|
||||
'label' => '评论列表',
|
||||
'type' => 'menu',
|
||||
'route' => 'admin.comment.list',
|
||||
],
|
||||
[
|
||||
'id' => '2-4-2',
|
||||
'label' => '搜索评论',
|
||||
'type' => 'menu',
|
||||
'route' => 'admin.comment.search',
|
||||
],
|
||||
[
|
||||
'id' => '2-4-3',
|
||||
'label' => '编辑评论',
|
||||
'type' => 'button',
|
||||
'route' => 'admin.comment.edit',
|
||||
],
|
||||
[
|
||||
'id' => '2-4-4',
|
||||
'label' => '删除评论',
|
||||
'type' => 'button',
|
||||
'route' => 'admin.comment.delete',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'id' => '2-5',
|
||||
'label' => '轮播管理',
|
||||
'type' => 'menu',
|
||||
'child' => [
|
||||
[
|
||||
'id' => '2-3-1',
|
||||
'id' => '2-5-1',
|
||||
'label' => '轮播列表',
|
||||
'type' => 'menu',
|
||||
'route' => 'admin.slide.list',
|
||||
],
|
||||
[
|
||||
'id' => '2-3-2',
|
||||
'id' => '2-5-2',
|
||||
'label' => '添加轮播',
|
||||
'type' => 'menu',
|
||||
'route' => 'admin.slide.add',
|
||||
],
|
||||
[
|
||||
'id' => '2-3-3',
|
||||
'id' => '2-5-3',
|
||||
'label' => '编辑轮播',
|
||||
'type' => 'button',
|
||||
'route' => 'admin.slide.edit',
|
||||
],
|
||||
[
|
||||
'id' => '2-3-4',
|
||||
'id' => '2-5-4',
|
||||
'label' => '删除轮播',
|
||||
'type' => 'button',
|
||||
'route' => 'admin.slide.delete',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'id' => '2-4',
|
||||
'label' => '单页管理',
|
||||
'type' => 'menu',
|
||||
'child' => [
|
||||
[
|
||||
'id' => '2-4-1',
|
||||
'label' => '单页列表',
|
||||
'type' => 'menu',
|
||||
'route' => 'admin.page.list',
|
||||
],
|
||||
[
|
||||
'id' => '2-4-2',
|
||||
'label' => '添加单页',
|
||||
'type' => 'menu',
|
||||
'route' => 'admin.page.add',
|
||||
],
|
||||
[
|
||||
'id' => '2-4-3',
|
||||
'label' => '编辑单页',
|
||||
'type' => 'button',
|
||||
'route' => 'admin.page.edit',
|
||||
],
|
||||
[
|
||||
'id' => '2-4-4',
|
||||
'label' => '删除单页',
|
||||
'type' => 'button',
|
||||
'route' => 'admin.page.delete',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'id' => '2-6',
|
||||
'label' => '导航管理',
|
||||
@ -321,37 +414,6 @@ 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',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
|
@ -5,8 +5,9 @@ namespace App\Http\Admin\Services;
|
||||
use App\Models\Role as RoleModel;
|
||||
use App\Models\User as UserModel;
|
||||
use App\Repos\Role as RoleRepo;
|
||||
use Phalcon\Mvc\User\Component;
|
||||
|
||||
class AuthUser extends \Phalcon\Mvc\User\Component
|
||||
class AuthUser extends Component
|
||||
{
|
||||
|
||||
/**
|
||||
|
@ -5,6 +5,7 @@ namespace App\Http\Admin\Services;
|
||||
use App\Models\Category as CategoryModel;
|
||||
use App\Repos\Category as CategoryRepo;
|
||||
use App\Validators\Category as CategoryValidator;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
|
||||
class Category extends Service
|
||||
{
|
||||
@ -179,6 +180,9 @@ class Category extends Service
|
||||
{
|
||||
$categoryRepo = new CategoryRepo();
|
||||
|
||||
/**
|
||||
* @var Resultset|CategoryModel[] $categories
|
||||
*/
|
||||
$categories = $categoryRepo->findAll(['parent_id' => $parentId]);
|
||||
|
||||
if ($categories->count() == 0) {
|
||||
@ -195,6 +199,9 @@ class Category extends Service
|
||||
{
|
||||
$categoryRepo = new CategoryRepo();
|
||||
|
||||
/**
|
||||
* @var Resultset|CategoryModel[] $categories
|
||||
*/
|
||||
$categories = $categoryRepo->findAll(['parent_id' => $parentId]);
|
||||
|
||||
if ($categories->count() == 0) {
|
||||
|
@ -64,6 +64,8 @@ class Chapter extends Service
|
||||
$this->updateChapterStats($chapter);
|
||||
$this->updateCourseStats($chapter);
|
||||
|
||||
$this->eventsManager->fire('chapterAdmin:afterCreate', $this, $chapter);
|
||||
|
||||
return $chapter;
|
||||
}
|
||||
|
||||
@ -105,6 +107,8 @@ class Chapter extends Service
|
||||
$this->updateChapterStats($chapter);
|
||||
$this->updateCourseStats($chapter);
|
||||
|
||||
$this->eventsManager->fire('chapterAdmin:afterUpdate', $this, $chapter);
|
||||
|
||||
return $chapter;
|
||||
}
|
||||
|
||||
@ -123,6 +127,8 @@ class Chapter extends Service
|
||||
$this->updateChapterStats($chapter);
|
||||
$this->updateCourseStats($chapter);
|
||||
|
||||
$this->eventsManager->fire('chapterAdmin:afterDelete', $this, $chapter);
|
||||
|
||||
return $chapter;
|
||||
}
|
||||
|
||||
@ -137,6 +143,8 @@ class Chapter extends Service
|
||||
$this->updateChapterStats($chapter);
|
||||
$this->updateCourseStats($chapter);
|
||||
|
||||
$this->eventsManager->fire('chapterAdmin:afterRestore', $this, $chapter);
|
||||
|
||||
return $chapter;
|
||||
}
|
||||
|
||||
|
@ -43,13 +43,13 @@ class ChapterContent extends Service
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getVodFiles($chapterId)
|
||||
public function getPlayUrls($chapterId)
|
||||
{
|
||||
$chapterVodService = new ChapterVodService();
|
||||
|
||||
$vodFiles = $chapterVodService->getVodFiles($chapterId);
|
||||
$playUrls = $chapterVodService->getPlayUrls($chapterId);
|
||||
|
||||
return kg_array_object($vodFiles);
|
||||
return kg_array_object($playUrls);
|
||||
}
|
||||
|
||||
public function updateChapterContent($chapterId)
|
||||
|
161
app/Http/Admin/Services/Comment.php
Normal file
161
app/Http/Admin/Services/Comment.php
Normal file
@ -0,0 +1,161 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Admin\Services;
|
||||
|
||||
use App\Builders\CommentList as CommentListBuilder;
|
||||
use App\Library\Paginator\Query as PagerQuery;
|
||||
use App\Repos\Chapter as ChapterRepo;
|
||||
use App\Repos\Comment as CommentRepo;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use App\Validators\Comment as CommentValidator;
|
||||
|
||||
class Comment extends Service
|
||||
{
|
||||
|
||||
public function getComments()
|
||||
{
|
||||
$pagerQuery = new PagerQuery();
|
||||
|
||||
$params = $pagerQuery->getParams();
|
||||
|
||||
$params['deleted'] = $params['deleted'] ?? 0;
|
||||
|
||||
$sort = $pagerQuery->getSort();
|
||||
$page = $pagerQuery->getPage();
|
||||
$limit = $pagerQuery->getLimit();
|
||||
|
||||
$commentRepo = new CommentRepo();
|
||||
|
||||
$pager = $commentRepo->paginate($params, $sort, $page, $limit);
|
||||
|
||||
$result = $this->handleComments($pager);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getCourse($courseId)
|
||||
{
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
$result = $courseRepo->findById($courseId);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getChapter($chapterId)
|
||||
{
|
||||
$chapterRepo = new ChapterRepo();
|
||||
|
||||
$result = $chapterRepo->findById($chapterId);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getComment($id)
|
||||
{
|
||||
$comment = $this->findOrFail($id);
|
||||
|
||||
return $comment;
|
||||
}
|
||||
|
||||
public function updateComment($id)
|
||||
{
|
||||
$comment = $this->findOrFail($id);
|
||||
|
||||
$post = $this->request->getPost();
|
||||
|
||||
$validator = new CommentValidator();
|
||||
|
||||
$data = [];
|
||||
|
||||
if (isset($post['content'])) {
|
||||
$data['content'] = $validator->checkContent($post['content']);
|
||||
}
|
||||
|
||||
if (isset($post['published'])) {
|
||||
$data['published'] = $validator->checkPublishStatus($post['published']);
|
||||
}
|
||||
|
||||
$comment->update($data);
|
||||
|
||||
return $comment;
|
||||
}
|
||||
|
||||
public function deleteComment($id)
|
||||
{
|
||||
$comment = $this->findOrFail($id);
|
||||
|
||||
$comment->deleted = 1;
|
||||
|
||||
$comment->update();
|
||||
|
||||
$chapterRepo = new ChapterRepo();
|
||||
|
||||
$chapter = $chapterRepo->findById($comment->chapter_id);
|
||||
|
||||
$chapter->comment_count -= 1;
|
||||
|
||||
$chapter->update();
|
||||
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
$course = $courseRepo->findById($comment->course_id);
|
||||
|
||||
$course->comment_count -= 1;
|
||||
|
||||
$course->update();
|
||||
}
|
||||
|
||||
public function restoreComment($id)
|
||||
{
|
||||
$comment = $this->findOrFail($id);
|
||||
|
||||
$comment->deleted = 0;
|
||||
|
||||
$comment->update();
|
||||
|
||||
$chapterRepo = new ChapterRepo();
|
||||
|
||||
$chapter = $chapterRepo->findById($comment->chapter_id);
|
||||
|
||||
$chapter->comment_count += 1;
|
||||
|
||||
$chapter->update();
|
||||
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
$course = $courseRepo->findById($comment->course_id);
|
||||
|
||||
$course->comment_count += 1;
|
||||
|
||||
$course->update();
|
||||
}
|
||||
|
||||
private function findOrFail($id)
|
||||
{
|
||||
$validator = new CommentValidator();
|
||||
|
||||
$result = $validator->checkComment($id);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function handleComments($pager)
|
||||
{
|
||||
if ($pager->total_items > 0) {
|
||||
|
||||
$builder = new CommentListBuilder();
|
||||
|
||||
$pipeA = $pager->items->toArray();
|
||||
$pipeB = $builder->handleCourses($pipeA);
|
||||
$pipeC = $builder->handleChapters($pipeB);
|
||||
$pipeD = $builder->handleUsers($pipeC);
|
||||
$pipeE = $builder->arrayToObject($pipeD);
|
||||
|
||||
$pager->items = $pipeE;
|
||||
}
|
||||
|
||||
return $pager;
|
||||
}
|
||||
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
namespace App\Http\Admin\Services;
|
||||
|
||||
use App\Repos\Config as ConfigRepo;
|
||||
use App\Repos\Vip as VipRepo;
|
||||
|
||||
class Config extends Service
|
||||
{
|
||||
@ -108,4 +109,24 @@ class Config extends Service
|
||||
$this->updateSectionConfig($section, $config);
|
||||
}
|
||||
|
||||
public function getVipConfig()
|
||||
{
|
||||
$vipRepo = new VipRepo();
|
||||
|
||||
$config = $vipRepo->findAll(['deleted' => 0]);
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
public function updateVipConfig($items)
|
||||
{
|
||||
$vipRepo = new VipRepo();
|
||||
|
||||
foreach ($items as $id => $price) {
|
||||
$vip = $vipRepo->findById($id);
|
||||
$vip->price = $price;
|
||||
$vip->update();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
136
app/Http/Admin/Services/Consult.php
Normal file
136
app/Http/Admin/Services/Consult.php
Normal file
@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Admin\Services;
|
||||
|
||||
use App\Builders\ConsultList as ConsultListBuilder;
|
||||
use App\Library\Paginator\Query as PagerQuery;
|
||||
use App\Repos\Consult as ConsultRepo;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use App\Validators\Consult as ConsultValidator;
|
||||
|
||||
class Consult extends Service
|
||||
{
|
||||
|
||||
public function getConsults()
|
||||
{
|
||||
$pagerQuery = new PagerQuery();
|
||||
|
||||
$params = $pagerQuery->getParams();
|
||||
|
||||
$params['deleted'] = $params['deleted'] ?? 0;
|
||||
|
||||
$sort = $pagerQuery->getSort();
|
||||
$page = $pagerQuery->getPage();
|
||||
$limit = $pagerQuery->getLimit();
|
||||
|
||||
$consultRepo = new ConsultRepo();
|
||||
|
||||
$pager = $consultRepo->paginate($params, $sort, $page, $limit);
|
||||
|
||||
return $this->handleConsults($pager);
|
||||
}
|
||||
|
||||
public function getCourse($courseId)
|
||||
{
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
$result = $courseRepo->findById($courseId);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getConsult($id)
|
||||
{
|
||||
$result = $this->findOrFail($id);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function updateConsult($id)
|
||||
{
|
||||
$consult = $this->findOrFail($id);
|
||||
|
||||
$post = $this->request->getPost();
|
||||
|
||||
$validator = new ConsultValidator();
|
||||
|
||||
$data = [];
|
||||
|
||||
if (isset($post['question'])) {
|
||||
$data['question'] = $validator->checkQuestion($post['question']);
|
||||
}
|
||||
|
||||
if (isset($post['answer'])) {
|
||||
$data['answer'] = $validator->checkAnswer($post['answer']);
|
||||
}
|
||||
|
||||
if (isset($post['published'])) {
|
||||
$data['published'] = $validator->checkPublishStatus($post['published']);
|
||||
}
|
||||
|
||||
$consult->update($data);
|
||||
|
||||
return $consult;
|
||||
}
|
||||
|
||||
public function deleteConsult($id)
|
||||
{
|
||||
$consult = $this->findOrFail($id);
|
||||
|
||||
$consult->deleted = 1;
|
||||
|
||||
$consult->update();
|
||||
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
$course = $courseRepo->findById($consult->course_id);
|
||||
|
||||
$course->consult_count -= 1;
|
||||
|
||||
$course->update();
|
||||
}
|
||||
|
||||
public function restoreConsult($id)
|
||||
{
|
||||
$consult = $this->findOrFail($id);
|
||||
|
||||
$consult->deleted = 0;
|
||||
|
||||
$consult->update();
|
||||
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
$course = $courseRepo->findById($consult->course_id);
|
||||
|
||||
$course->consult_count += 1;
|
||||
|
||||
$course->update();
|
||||
}
|
||||
|
||||
protected function findOrFail($id)
|
||||
{
|
||||
$validator = new ConsultValidator();
|
||||
|
||||
$result = $validator->checkConsult($id);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function handleConsults($pager)
|
||||
{
|
||||
if ($pager->total_items > 0) {
|
||||
|
||||
$builder = new ConsultListBuilder();
|
||||
|
||||
$pipeA = $pager->items->toArray();
|
||||
$pipeB = $builder->handleCourses($pipeA);
|
||||
$pipeC = $builder->handleUsers($pipeB);
|
||||
$pipeD = $builder->arrayToObject($pipeC);
|
||||
|
||||
$pager->items = $pipeD;
|
||||
}
|
||||
|
||||
return $pager;
|
||||
}
|
||||
|
||||
}
|
@ -4,10 +4,12 @@ namespace App\Http\Admin\Services;
|
||||
|
||||
use App\Builders\CourseList as CourseListBuilder;
|
||||
use App\Library\Paginator\Query as PagerQuery;
|
||||
use App\Models\Category as CategoryModel;
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Models\CourseCategory as CourseCategoryModel;
|
||||
use App\Models\CourseRelated as CourseRelatedModel;
|
||||
use App\Models\CourseUser as CourseUserModel;
|
||||
use App\Models\User as UserModel;
|
||||
use App\Repos\Category as CategoryRepo;
|
||||
use App\Repos\Chapter as ChapterRepo;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
@ -16,6 +18,7 @@ use App\Repos\CourseRelated as CourseRelatedRepo;
|
||||
use App\Repos\CourseUser as CourseUserRepo;
|
||||
use App\Repos\User as UserRepo;
|
||||
use App\Validators\Course as CourseValidator;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
|
||||
class Course extends Service
|
||||
{
|
||||
@ -61,12 +64,13 @@ class Course extends Service
|
||||
|
||||
$data['model'] = $validator->checkModel($post['model']);
|
||||
$data['title'] = $validator->checkTitle($post['title']);
|
||||
$data['published'] = 0;
|
||||
|
||||
$course = new CourseModel();
|
||||
|
||||
$course->create($data);
|
||||
|
||||
$this->eventsManager->fire('courseAdmin:afterCreate', $this, $course);
|
||||
|
||||
return $course;
|
||||
}
|
||||
|
||||
@ -111,7 +115,8 @@ class Course extends Service
|
||||
} else {
|
||||
$data['market_price'] = $validator->checkMarketPrice($post['market_price']);
|
||||
$data['vip_price'] = $validator->checkVipPrice($post['vip_price']);
|
||||
$data['expiry'] = $validator->checkExpiry($post['expiry']);
|
||||
$data['study_expiry'] = $validator->checkStudyExpiry($post['study_expiry']);
|
||||
$data['refund_expiry'] = $validator->checkRefundExpiry($post['refund_expiry']);
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,6 +141,8 @@ class Course extends Service
|
||||
|
||||
$course->update($data);
|
||||
|
||||
$this->eventsManager->fire('courseAdmin:afterUpdate', $this, $course);
|
||||
|
||||
return $course;
|
||||
}
|
||||
|
||||
@ -147,6 +154,8 @@ class Course extends Service
|
||||
|
||||
$course->update();
|
||||
|
||||
$this->eventsManager->fire('courseAdmin:afterDelete', $this, $course);
|
||||
|
||||
return $course;
|
||||
}
|
||||
|
||||
@ -158,13 +167,32 @@ class Course extends Service
|
||||
|
||||
$course->update();
|
||||
|
||||
$this->eventsManager->fire('courseAdmin:afterRestore', $this, $course);
|
||||
|
||||
return $course;
|
||||
}
|
||||
|
||||
public function getStudyExpiryOptions()
|
||||
{
|
||||
$options = CourseModel::studyExpiryOptions();
|
||||
|
||||
return kg_array_object($options);
|
||||
}
|
||||
|
||||
public function getRefundExpiryOptions()
|
||||
{
|
||||
$options = CourseModel::refundExpiryOptions();
|
||||
|
||||
return kg_array_object($options);
|
||||
}
|
||||
|
||||
public function getXmCategories($id)
|
||||
{
|
||||
$categoryRepo = new CategoryRepo();
|
||||
|
||||
/**
|
||||
* @var Resultset|CategoryModel[] $allCategories
|
||||
*/
|
||||
$allCategories = $categoryRepo->findAll(['deleted' => 0]);
|
||||
|
||||
if ($allCategories->count() == 0) {
|
||||
@ -174,8 +202,14 @@ class Course extends Service
|
||||
$courseCategoryIds = [];
|
||||
|
||||
if ($id > 0) {
|
||||
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
/**
|
||||
* @var Resultset|CategoryModel[] $courseCategories
|
||||
*/
|
||||
$courseCategories = $courseRepo->findCategories($id);
|
||||
|
||||
if ($courseCategories->count() > 0) {
|
||||
foreach ($courseCategories as $category) {
|
||||
$courseCategoryIds[] = $category->id;
|
||||
@ -214,6 +248,9 @@ class Course extends Service
|
||||
{
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
/**
|
||||
* @var Resultset|UserModel[] $allTeachers
|
||||
*/
|
||||
$allTeachers = $userRepo->findTeachers();
|
||||
|
||||
if ($allTeachers->count() == 0) {
|
||||
@ -223,8 +260,14 @@ class Course extends Service
|
||||
$courseTeacherIds = [];
|
||||
|
||||
if ($id > 0) {
|
||||
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
/**
|
||||
* @var Resultset|UserModel[] $courseTeachers
|
||||
*/
|
||||
$courseTeachers = $courseRepo->findTeachers($id);
|
||||
|
||||
if ($courseTeachers->count() > 0) {
|
||||
foreach ($courseTeachers as $teacher) {
|
||||
$courseTeacherIds[] = $teacher->id;
|
||||
@ -250,6 +293,9 @@ class Course extends Service
|
||||
{
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
/**
|
||||
* @var Resultset|CourseModel[] $courses
|
||||
*/
|
||||
$courses = $courseRepo->findRelatedCourses($id);
|
||||
|
||||
$list = [];
|
||||
@ -297,6 +343,9 @@ class Course extends Service
|
||||
{
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
/**
|
||||
* @var Resultset|UserModel[] $courseTeachers
|
||||
*/
|
||||
$courseTeachers = $courseRepo->findTeachers($course->id);
|
||||
|
||||
$originTeacherIds = [];
|
||||
@ -318,7 +367,7 @@ class Course extends Service
|
||||
'user_id' => $teacherId,
|
||||
'role_type' => CourseUserModel::ROLE_TEACHER,
|
||||
'source_type' => CourseUserModel::SOURCE_IMPORT,
|
||||
'expire_time' => strtotime('+10 years'),
|
||||
'expiry_time' => strtotime('+10 years'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -340,6 +389,9 @@ class Course extends Service
|
||||
{
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
/**
|
||||
* @var Resultset|CategoryModel[] $courseCategories
|
||||
*/
|
||||
$courseCategories = $courseRepo->findCategories($course->id);
|
||||
|
||||
$originCategoryIds = [];
|
||||
@ -380,6 +432,9 @@ class Course extends Service
|
||||
{
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
/**
|
||||
* @var Resultset|CourseModel[] $relatedCourses
|
||||
*/
|
||||
$relatedCourses = $courseRepo->findRelatedCourses($course->id);
|
||||
|
||||
$originRelatedIds = [];
|
||||
|
@ -2,10 +2,11 @@
|
||||
|
||||
namespace App\Http\Admin\Services;
|
||||
|
||||
use App\Caches\NavList as NavListCache;
|
||||
use App\Caches\NavTreeList as NavTreeListCache;
|
||||
use App\Models\Nav as NavModel;
|
||||
use App\Repos\Nav as NavRepo;
|
||||
use App\Validators\Nav as NavValidator;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
|
||||
class Nav extends Service
|
||||
{
|
||||
@ -191,7 +192,7 @@ class Nav extends Service
|
||||
$nav->child_count = $childCount;
|
||||
$nav->update();
|
||||
|
||||
$cache = new NavListCache();
|
||||
$cache = new NavTreeListCache();
|
||||
$cache->rebuild();
|
||||
}
|
||||
|
||||
@ -199,6 +200,9 @@ class Nav extends Service
|
||||
{
|
||||
$navRepo = new NavRepo();
|
||||
|
||||
/**
|
||||
* @var Resultset $navs
|
||||
*/
|
||||
$navs = $navRepo->findAll(['parent_id' => $parentId]);
|
||||
|
||||
if ($navs->count() == 0) {
|
||||
@ -215,6 +219,9 @@ class Nav extends Service
|
||||
{
|
||||
$navRepo = new NavRepo();
|
||||
|
||||
/**
|
||||
* @var Resultset $navs
|
||||
*/
|
||||
$navs = $navRepo->findAll(['parent_id' => $parentId]);
|
||||
|
||||
if ($navs->count() == 0) {
|
||||
|
@ -88,7 +88,7 @@ class Order extends Service
|
||||
{
|
||||
$validator = new OrderValidator();
|
||||
|
||||
$result = $validator->checkOrder($id);
|
||||
$result = $validator->checkOrderById($id);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
@ -23,7 +23,8 @@ abstract class PaymentTest extends Service
|
||||
$order->subject = '测试 - 支付测试0.01元';
|
||||
$order->amount = 0.01;
|
||||
$order->user_id = $authUser->id;
|
||||
$order->item_type = OrderModel::TYPE_TEST;
|
||||
$order->item_type = OrderModel::ITEM_TEST;
|
||||
|
||||
$order->create();
|
||||
|
||||
return $order;
|
||||
@ -40,10 +41,11 @@ abstract class PaymentTest extends Service
|
||||
$trade = new TradeModel();
|
||||
|
||||
$trade->user_id = $order->user_id;
|
||||
$trade->order_sn = $order->sn;
|
||||
$trade->order_id = $order->id;
|
||||
$trade->subject = $order->subject;
|
||||
$trade->amount = $order->amount;
|
||||
$trade->channel = TradeModel::CHANNEL_ALIPAY;
|
||||
|
||||
$trade->create();
|
||||
|
||||
return $trade;
|
||||
|
@ -20,6 +20,16 @@ class Refund extends Service
|
||||
$pageQuery = new PaginateQuery();
|
||||
|
||||
$params = $pageQuery->getParams();
|
||||
|
||||
/**
|
||||
* 兼容订单编号或订单序号查询
|
||||
*/
|
||||
if (isset($params['order_id']) && strlen($params['order_id']) > 10) {
|
||||
$orderRepo = new OrderRepo();
|
||||
$order = $orderRepo->findBySn($params['order_id']);
|
||||
$params['order_id'] = $order ? $order->id : -1000;
|
||||
}
|
||||
|
||||
$sort = $pageQuery->getSort();
|
||||
$page = $pageQuery->getPage();
|
||||
$limit = $pageQuery->getLimit();
|
||||
@ -38,29 +48,29 @@ class Refund extends Service
|
||||
return $refund;
|
||||
}
|
||||
|
||||
public function getTrade($sn)
|
||||
public function getTrade($tradeId)
|
||||
{
|
||||
$tradeRepo = new TradeRepo();
|
||||
|
||||
$trade = $tradeRepo->findBySn($sn);
|
||||
$trade = $tradeRepo->findById($tradeId);
|
||||
|
||||
return $trade;
|
||||
}
|
||||
|
||||
public function getOrder($sn)
|
||||
public function getOrder($orderId)
|
||||
{
|
||||
$orderRepo = new OrderRepo();
|
||||
|
||||
$order = $orderRepo->findBySn($sn);
|
||||
$order = $orderRepo->findById($orderId);
|
||||
|
||||
return $order;
|
||||
}
|
||||
|
||||
public function getUser($id)
|
||||
public function getUser($userId)
|
||||
{
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$user = $userRepo->findById($id);
|
||||
$user = $userRepo->findById($userId);
|
||||
|
||||
return $user;
|
||||
}
|
||||
@ -121,9 +131,10 @@ class Refund extends Service
|
||||
|
||||
$pipeA = $pager->items->toArray();
|
||||
$pipeB = $builder->handleUsers($pipeA);
|
||||
$pipeC = $builder->arrayToObject($pipeB);
|
||||
$pipeC = $builder->handleOrders($pipeB);
|
||||
$pipeD = $builder->arrayToObject($pipeC);
|
||||
|
||||
$pager->items = $pipeC;
|
||||
$pager->items = $pipeD;
|
||||
}
|
||||
|
||||
return $pager;
|
||||
|
@ -2,7 +2,9 @@
|
||||
|
||||
namespace App\Http\Admin\Services;
|
||||
|
||||
class Service extends \Phalcon\Mvc\User\Component
|
||||
use Phalcon\Mvc\User\Component;
|
||||
|
||||
class Service extends Component
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ class Session extends Service
|
||||
{
|
||||
|
||||
/**
|
||||
* @var \App\Http\Admin\Services\AuthUser
|
||||
* @var AuthUser
|
||||
*/
|
||||
protected $auth;
|
||||
|
||||
|
@ -57,10 +57,7 @@ class Slide extends Service
|
||||
$data['content'] = $validator->checkLink($post['content']);
|
||||
}
|
||||
|
||||
$data['start_time'] = strtotime(date('Y-m-d'));
|
||||
$data['end_time'] = strtotime('+15 days', $data['start_time']);
|
||||
$data['priority'] = 10;
|
||||
$data['published'] = 0;
|
||||
|
||||
$slide = new SlideModel();
|
||||
|
||||
@ -107,12 +104,6 @@ class Slide extends Service
|
||||
$data['priority'] = $validator->checkPriority($post['priority']);
|
||||
}
|
||||
|
||||
if (isset($post['start_time']) || isset($post['end_time'])) {
|
||||
$data['start_time'] = $validator->checkStartTime($post['start_time']);
|
||||
$data['end_time'] = $validator->checkEndTime($post['end_time']);
|
||||
$validator->checkTimeRange($post['start_time'], $post['end_time']);
|
||||
}
|
||||
|
||||
if (isset($post['published'])) {
|
||||
$data['published'] = $validator->checkPublishStatus($post['published']);
|
||||
}
|
||||
|
@ -10,9 +10,10 @@ 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\Services\CourseStats as CourseStatsUpdater;
|
||||
use App\Validators\CourseUser as CourseUserValidator;
|
||||
|
||||
class CourseStudent extends Service
|
||||
class Student extends Service
|
||||
{
|
||||
|
||||
public function getCourse($courseId)
|
||||
@ -29,7 +30,7 @@ class CourseStudent extends Service
|
||||
return $repo->findById($userId);
|
||||
}
|
||||
|
||||
public function getCourseStudents()
|
||||
public function getPlans()
|
||||
{
|
||||
$pagerQuery = new PagerQuery();
|
||||
|
||||
@ -46,10 +47,10 @@ class CourseStudent extends Service
|
||||
|
||||
$pager = $courseUserRepo->paginate($params, $sort, $page, $limit);
|
||||
|
||||
return $this->handleCourseStudents($pager);
|
||||
return $this->handlePlans($pager);
|
||||
}
|
||||
|
||||
public function getCourseLearnings()
|
||||
public function getLearnings()
|
||||
{
|
||||
$pagerQuery = new PagerQuery();
|
||||
|
||||
@ -63,17 +64,17 @@ class CourseStudent extends Service
|
||||
|
||||
$pager = $learningRepo->paginate($params, $sort, $page, $limit);
|
||||
|
||||
return $this->handleCourseLearnings($pager);
|
||||
return $this->handleLearnings($pager);
|
||||
}
|
||||
|
||||
public function getCourseStudent($courseId, $userId)
|
||||
public function getPlan($id)
|
||||
{
|
||||
$result = $this->findOrFail($courseId, $userId);
|
||||
$result = $this->findOrFail($id);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function createCourseStudent()
|
||||
public function createPlan()
|
||||
{
|
||||
$post = $this->request->getPost();
|
||||
|
||||
@ -86,7 +87,7 @@ class CourseStudent extends Service
|
||||
|
||||
$data['course_id'] = $validator->checkCourseId($post['course_id']);
|
||||
$data['user_id'] = $validator->checkUserId($post['user_id']);
|
||||
$data['expire_time'] = $validator->checkExpireTime($post['expire_time']);
|
||||
$data['expiry_time'] = $validator->checkExpiryTime($post['expiry_time']);
|
||||
|
||||
$validator->checkIfJoined($post['course_id'], $post['user_id']);
|
||||
|
||||
@ -99,27 +100,23 @@ class CourseStudent extends Service
|
||||
return $courseUser;
|
||||
}
|
||||
|
||||
public function updateCourseStudent()
|
||||
public function updatePlan()
|
||||
{
|
||||
$post = $this->request->getPost();
|
||||
|
||||
$courseStudent = $this->findOrFail($post['course_id'], $post['user_id']);
|
||||
$plan = $this->findOrFail($post['plan_id']);
|
||||
|
||||
$validator = new CourseUserValidator();
|
||||
|
||||
$data = [];
|
||||
|
||||
if (isset($post['expire_time'])) {
|
||||
$data['expire_time'] = $validator->checkExpireTime($post['expire_time']);
|
||||
if (isset($post['expiry_time'])) {
|
||||
$data['expiry_time'] = $validator->checkExpiryTime($post['expiry_time']);
|
||||
}
|
||||
|
||||
if (isset($post['locked'])) {
|
||||
$data['locked'] = $validator->checkLockStatus($post['locked']);
|
||||
}
|
||||
$plan->update($data);
|
||||
|
||||
$courseStudent->update($data);
|
||||
|
||||
return $courseStudent;
|
||||
return $plan;
|
||||
}
|
||||
|
||||
protected function updateUserCount($courseId)
|
||||
@ -130,19 +127,19 @@ class CourseStudent extends Service
|
||||
|
||||
$updater = new CourseStatsUpdater();
|
||||
|
||||
$updater->updateUserCount($course);
|
||||
$updater->updateUserCount($course->id);
|
||||
}
|
||||
|
||||
protected function findOrFail($courseId, $userId)
|
||||
protected function findOrFail($id)
|
||||
{
|
||||
$validator = new CourseUserValidator();
|
||||
|
||||
$result = $validator->checkCourseStudent($courseId, $userId);
|
||||
$result = $validator->checkCourseUser($id);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function handleCourseStudents($pager)
|
||||
protected function handlePlans($pager)
|
||||
{
|
||||
if ($pager->total_items > 0) {
|
||||
|
||||
@ -159,7 +156,7 @@ class CourseStudent extends Service
|
||||
return $pager;
|
||||
}
|
||||
|
||||
protected function handleCourseLearnings($pager)
|
||||
protected function handleLearnings($pager)
|
||||
{
|
||||
if ($pager->total_items > 0) {
|
||||
|
@ -20,6 +20,16 @@ class Trade extends Service
|
||||
$pageQuery = new PaginateQuery();
|
||||
|
||||
$params = $pageQuery->getParams();
|
||||
|
||||
/**
|
||||
* 兼容订单编号或订单序号查询
|
||||
*/
|
||||
if (isset($params['order_id']) && strlen($params['order_id']) > 10) {
|
||||
$orderRepo = new OrderRepo();
|
||||
$order = $orderRepo->findBySn($params['order_id']);
|
||||
$params['order_id'] = $order ? $order->id : -1000;
|
||||
}
|
||||
|
||||
$sort = $pageQuery->getSort();
|
||||
$page = $pageQuery->getPage();
|
||||
$limit = $pageQuery->getLimit();
|
||||
@ -40,29 +50,29 @@ class Trade extends Service
|
||||
return $trade;
|
||||
}
|
||||
|
||||
public function getOrder($sn)
|
||||
public function getOrder($orderId)
|
||||
{
|
||||
$orderRepo = new OrderRepo();
|
||||
|
||||
$order = $orderRepo->findBySn($sn);
|
||||
$order = $orderRepo->findById($orderId);
|
||||
|
||||
return $order;
|
||||
}
|
||||
|
||||
public function getRefunds($sn)
|
||||
public function getRefunds($tradeId)
|
||||
{
|
||||
$tradeRepo = new TradeRepo();
|
||||
|
||||
$refunds = $tradeRepo->findRefunds($sn);
|
||||
$refunds = $tradeRepo->findRefunds($tradeId);
|
||||
|
||||
return $refunds;
|
||||
}
|
||||
|
||||
public function getUser($id)
|
||||
public function getUser($userId)
|
||||
{
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$user = $userRepo->findById($id);
|
||||
$user = $userRepo->findById($userId);
|
||||
|
||||
return $user;
|
||||
}
|
||||
@ -103,9 +113,9 @@ class Trade extends Service
|
||||
$refund->subject = $trade->subject;
|
||||
$refund->amount = $trade->amount;
|
||||
$refund->user_id = $trade->user_id;
|
||||
$refund->order_sn = $trade->order_sn;
|
||||
$refund->trade_sn = $trade->sn;
|
||||
$refund->apply_reason = '后台人工申请退款';
|
||||
$refund->order_id = $trade->order_id;
|
||||
$refund->trade_id = $trade->sn;
|
||||
$refund->apply_note = '后台人工申请退款';
|
||||
|
||||
$refund->create();
|
||||
|
||||
@ -129,9 +139,10 @@ class Trade extends Service
|
||||
|
||||
$pipeA = $pager->items->toArray();
|
||||
$pipeB = $builder->handleUsers($pipeA);
|
||||
$pipeC = $builder->arrayToObject($pipeB);
|
||||
$pipeC = $builder->handleOrders($pipeB);
|
||||
$pipeD = $builder->arrayToObject($pipeC);
|
||||
|
||||
$pager->items = $pipeC;
|
||||
$pager->items = $pipeD;
|
||||
}
|
||||
|
||||
return $pager;
|
||||
|
@ -4,10 +4,11 @@ namespace App\Http\Admin\Services;
|
||||
|
||||
use App\Builders\UserList as UserListBuilder;
|
||||
use App\Library\Paginator\Query as PaginateQuery;
|
||||
use App\Library\Util\Password as PasswordUtil;
|
||||
use App\Models\User as UserModel;
|
||||
use App\Models\Account as AccountModel;
|
||||
use App\Repos\Account as AccountRepo;
|
||||
use App\Repos\Role as RoleRepo;
|
||||
use App\Repos\User as UserRepo;
|
||||
use App\Validators\Account as AccountValidator;
|
||||
use App\Validators\User as UserValidator;
|
||||
|
||||
class User extends Service
|
||||
@ -47,33 +48,49 @@ class User extends Service
|
||||
return $user;
|
||||
}
|
||||
|
||||
public function getAccount($id)
|
||||
{
|
||||
$accountRepo = new AccountRepo();
|
||||
|
||||
$account = $accountRepo->findById($id);
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
public function createUser()
|
||||
{
|
||||
$post = $this->request->getPost();
|
||||
|
||||
$validator = new UserValidator();
|
||||
$accountValidator = new AccountValidator();
|
||||
|
||||
$name = $validator->checkName($post['name']);
|
||||
$password = $validator->checkPassword($post['password']);
|
||||
$eduRole = $validator->checkEduRole($post['edu_role']);
|
||||
$adminRole = $validator->checkAdminRole($post['admin_role']);
|
||||
$phone = $accountValidator->checkPhone($post['phone']);
|
||||
$password = $accountValidator->checkPassword($post['password']);
|
||||
|
||||
$validator->checkIfNameTaken($name);
|
||||
$accountValidator->checkIfPhoneTaken($post['phone']);
|
||||
|
||||
$data = [];
|
||||
$userValidator = new UserValidator();
|
||||
|
||||
$data['name'] = $name;
|
||||
$data['salt'] = PasswordUtil::salt();
|
||||
$data['password'] = PasswordUtil::hash($password, $data['salt']);
|
||||
$data['edu_role'] = $eduRole;
|
||||
$data['admin_role'] = $adminRole;
|
||||
$eduRole = $userValidator->checkEduRole($post['edu_role']);
|
||||
$adminRole = $userValidator->checkAdminRole($post['admin_role']);
|
||||
|
||||
$user = new UserModel();
|
||||
$account = new AccountModel();
|
||||
|
||||
$user->create($data);
|
||||
$account->phone = $phone;
|
||||
$account->password = $password;
|
||||
|
||||
if ($user->admin_role > 0) {
|
||||
$this->updateAdminUserCount($user->admin_role);
|
||||
$account->create();
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$user = $userRepo->findById($account->id);
|
||||
|
||||
$user->edu_role = $eduRole;
|
||||
$user->admin_role = $adminRole;
|
||||
|
||||
$user->update();
|
||||
|
||||
if ($adminRole > 0) {
|
||||
$this->updateAdminUserCount($adminRole);
|
||||
}
|
||||
|
||||
return $user;
|
||||
@ -89,6 +106,13 @@ class User extends Service
|
||||
|
||||
$data = [];
|
||||
|
||||
if (isset($post['name'])) {
|
||||
$data['name'] = $validator->checkName($post['name']);
|
||||
if ($post['name'] != $user->name) {
|
||||
$validator->checkIfNameTaken($post['name']);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($post['title'])) {
|
||||
$data['title'] = $validator->checkTitle($post['title']);
|
||||
}
|
||||
@ -105,13 +129,24 @@ class User extends Service
|
||||
$data['admin_role'] = $validator->checkAdminRole($post['admin_role']);
|
||||
}
|
||||
|
||||
if (isset($post['vip'])) {
|
||||
$data['vip'] = $validator->checkVipStatus($post['vip']);
|
||||
}
|
||||
|
||||
if (isset($post['vip_expiry_time'])) {
|
||||
$data['vip_expiry_time'] = $validator->checkVipExpiryTime($post['vip_expiry_time']);
|
||||
if ($data['vip_expiry_time'] < time()) {
|
||||
$data['vip'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($post['locked'])) {
|
||||
$data['locked'] = $validator->checkLockStatus($post['locked']);
|
||||
}
|
||||
|
||||
if (isset($post['lock_expiry'])) {
|
||||
$data['lock_expiry'] = $validator->checkLockExpiry($post['lock_expiry']);
|
||||
if ($data['lock_expiry'] < time()) {
|
||||
if (isset($post['lock_expiry_time'])) {
|
||||
$data['lock_expiry_time'] = $validator->checkLockExpiryTime($post['lock_expiry_time']);
|
||||
if ($data['lock_expiry_time'] < time()) {
|
||||
$data['locked'] = 0;
|
||||
}
|
||||
}
|
||||
@ -131,6 +166,41 @@ class User extends Service
|
||||
return $user;
|
||||
}
|
||||
|
||||
public function updateAccount($id)
|
||||
{
|
||||
$post = $this->request->getPost();
|
||||
|
||||
$accountRepo = new AccountRepo();
|
||||
|
||||
$account = $accountRepo->findById($id);
|
||||
|
||||
$validator = new AccountValidator();
|
||||
|
||||
$data = [];
|
||||
|
||||
if (!empty($post['phone'])) {
|
||||
$data['phone'] = $validator->checkPhone($post['phone']);
|
||||
if ($post['phone'] != $account->phone) {
|
||||
$validator->checkIfPhoneTaken($post['phone']);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($post['email'])) {
|
||||
$data['email'] = $validator->checkEmail($post['email']);
|
||||
if ($post['email'] != $account->email) {
|
||||
$validator->checkIfEmailTaken($post['email']);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($post['password'])) {
|
||||
$data['password'] = $validator->checkPassword($post['password']);
|
||||
}
|
||||
|
||||
$account->update($data);
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
protected function findOrFail($id)
|
||||
{
|
||||
$validator = new UserValidator();
|
||||
@ -146,9 +216,7 @@ class User extends Service
|
||||
|
||||
$role = $roleRepo->findById($roleId);
|
||||
|
||||
if (!$role) {
|
||||
return false;
|
||||
}
|
||||
if (!$role) return;
|
||||
|
||||
$userCount = $roleRepo->countUsers($roleId);
|
||||
|
||||
|
66
app/Http/Admin/Services/WechatTest.php
Normal file
66
app/Http/Admin/Services/WechatTest.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Admin\Services;
|
||||
|
||||
use App\Models\Order as OrderModel;
|
||||
use App\Models\Trade as TradeModel;
|
||||
use App\Repos\Order as OrderRepo;
|
||||
use App\Repos\Trade as TradeRepo;
|
||||
use App\Services\Wechat as WechatService;
|
||||
|
||||
class WechatTest extends PaymentTest
|
||||
{
|
||||
|
||||
/**
|
||||
* 获取测试二维码
|
||||
*
|
||||
* @param TradeModel $trade
|
||||
* @return mixed
|
||||
*/
|
||||
public function getTestQrcode($trade)
|
||||
{
|
||||
$outOrder = [
|
||||
'out_trade_no' => $trade->sn,
|
||||
'total_fee' => 100 * $trade->amount,
|
||||
'body' => $trade->subject,
|
||||
];
|
||||
|
||||
$wechatService = new WechatService();
|
||||
|
||||
$qrcode = $wechatService->getQrCode($outOrder);
|
||||
|
||||
$result = $qrcode ?: false;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消测试订单
|
||||
*
|
||||
* @param string $sn
|
||||
*/
|
||||
public function cancelTestOrder($sn)
|
||||
{
|
||||
$tradeRepo = new TradeRepo();
|
||||
|
||||
$trade = $tradeRepo->findBySn($sn);
|
||||
|
||||
$orderRepo = new OrderRepo();
|
||||
|
||||
$order = $orderRepo->findById($trade->order_id);
|
||||
|
||||
$wechatService = new WechatService();
|
||||
|
||||
$response = $wechatService->closeOrder($trade->sn);
|
||||
|
||||
if ($response) {
|
||||
$trade->status = TradeModel::STATUS_CLOSED;
|
||||
$trade->update();
|
||||
if ($order->status != OrderModel::STATUS_PENDING) {
|
||||
$order->status = OrderModel::STATUS_PENDING;
|
||||
$order->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Admin\Services;
|
||||
|
||||
use App\Models\Trade as TradeModel;
|
||||
|
||||
class WxpayTest extends PaymentTest
|
||||
{
|
||||
|
||||
/**
|
||||
* 获取测试二维码
|
||||
*
|
||||
* @param TradeModel $trade
|
||||
* @return mixed
|
||||
*/
|
||||
public function getTestQrcode($trade)
|
||||
{
|
||||
$outOrder = [
|
||||
'out_trade_no' => $trade->sn,
|
||||
'total_fee' => 100 * $trade->amount,
|
||||
'body' => $trade->subject,
|
||||
];
|
||||
|
||||
$wxpayService = new WxpayService();
|
||||
$qrcode = $wxpayService->qrcode($outOrder);
|
||||
$result = $qrcode ?: false;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消测试订单
|
||||
*
|
||||
* @param string $sn
|
||||
*/
|
||||
public function cancelTestOrder($sn)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -101,7 +101,7 @@
|
||||
var categoryId = $(this).attr('category-id');
|
||||
var checked = $(this).is(':checked');
|
||||
var published = checked ? 1 : 0;
|
||||
var tips = published == 1 ? '确定要发布分类?' : '确定要下线分类?';
|
||||
var tips = published === 1 ? '确定要发布分类?' : '确定要下线分类?';
|
||||
layer.confirm(tips, function () {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% if vod_files %}
|
||||
{% if play_urls %}
|
||||
<fieldset class="layui-elem-field layui-field-title">
|
||||
<legend>视频信息</legend>
|
||||
</fieldset>
|
||||
@ -11,7 +11,7 @@
|
||||
<th>大小</th>
|
||||
<th width="16%">操作</th>
|
||||
</tr>
|
||||
{% for item in vod_files %}
|
||||
{% for item in play_urls %}
|
||||
<tr>
|
||||
<td>{{ item.format }}</td>
|
||||
<td>{{ item.duration|play_duration }}</td>
|
||||
@ -19,7 +19,7 @@
|
||||
<td>{{ item.rate }}kbps</td>
|
||||
<td>{{ item.size }}M</td>
|
||||
<td>
|
||||
<span class="layui-btn layui-btn-sm kg-preview" course-id="{{ chapter.course_id }}" chapter-id="{{ chapter.id }}" play-url="{{ item.url|url_encode }}">预览</span>
|
||||
<span class="layui-btn layui-btn-sm kg-preview" chapter-id="{{ chapter.id }}" play-url="{{ item.url|url_encode }}">预览</span>
|
||||
<span class="layui-btn layui-btn-sm kg-copy" data-clipboard-text="{{ item.url }}">复制</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -46,8 +46,10 @@
|
||||
<td>{{ file_status(item.attrs['file_status']) }}</td>
|
||||
<td>{{ item.attrs['duration']|play_duration }}</td>
|
||||
<td><input class="layui-input kg-priority-input" type="text" name="priority" value="{{ item.priority }}" chapter-id="{{ item.id }}"></td>
|
||||
<td><input type="checkbox" name="free" value="1" lay-skin="switch" lay-text="是|否" lay-filter="switch-free" chapter-id="{{ item.id }}" {% if item.free == 1 %}checked{% endif %}></td>
|
||||
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="switch-published" chapter-id="{{ item.id }}" {% if item.published == 1 %}checked{% endif %}></td>
|
||||
<td><input type="checkbox" name="free" value="1" lay-skin="switch" lay-text="是|否" lay-filter="switch-free" chapter-id="{{ item.id }}"
|
||||
{% if item.free == 1 %}checked{% endif %}></td>
|
||||
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="switch-published" chapter-id="{{ item.id }}"
|
||||
{% if item.published == 1 %}checked{% endif %}></td>
|
||||
<td align="center">
|
||||
<div class="layui-dropdown">
|
||||
<button class="layui-btn layui-btn-sm">操作 <span class="layui-icon layui-icon-triangle-d"></span></button>
|
||||
|
30
app/Http/Admin/Views/comment/edit.volt
Normal file
30
app/Http/Admin/Views/comment/edit.volt
Normal file
@ -0,0 +1,30 @@
|
||||
<fieldset class="layui-elem-field layui-field-title">
|
||||
<legend>编辑评论</legend>
|
||||
</fieldset>
|
||||
|
||||
<form class="layui-form" method="POST" action="{{ url({'for':'admin.comment.update','id':comment.id}) }}">
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">内容</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="content" lay-verify="required" class="layui-textarea">{{ comment.content }}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">开启</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="published" value="1" title="是" {% if comment.published == 1 %}checked="true"{% endif %}>
|
||||
<input type="radio" name="published" value="0" title="否" {% if comment.published == 0 %}checked="true"{% endif %}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"></label>
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn" lay-submit lay-filter="go">提交</button>
|
||||
<button type="reset" class="kg-back layui-btn layui-btn-primary">返回</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
114
app/Http/Admin/Views/comment/list.volt
Normal file
114
app/Http/Admin/Views/comment/list.volt
Normal file
@ -0,0 +1,114 @@
|
||||
<div class="kg-nav">
|
||||
<div class="kg-nav-left">
|
||||
<span class="layui-breadcrumb">
|
||||
<a class="kg-back"><i class="layui-icon layui-icon-return"></i> 返回</a>
|
||||
{% if course %}
|
||||
<a><cite>{{ course.title }}</cite></a>
|
||||
{% endif %}
|
||||
{% if chapter %}
|
||||
<a><cite>{{ chapter.title }}</cite></a>
|
||||
{% endif %}
|
||||
<a><cite>评论管理</cite></a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="kg-nav-right">
|
||||
<a class="layui-btn layui-btn-sm" href="{{ url({'for':'admin.comment.search'}) }}">
|
||||
<i class="layui-icon layui-icon-search"></i>搜索评论
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="kg-table layui-table layui-form">
|
||||
<colgroup>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col width="10%">
|
||||
<col width="10%">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>评论</th>
|
||||
<th>用户</th>
|
||||
<th>时间</th>
|
||||
<th>发布</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in pager.items %}
|
||||
<tr>
|
||||
<td>
|
||||
<p>课程:<a href="{{ url({'for':'admin.comment.list'},{'course_id':item.course.id}) }}">{{ item.course.title }}</a></p>
|
||||
{% if item.chapter %}
|
||||
<p>章节:<a href="{{ url({'for':'admin.comment.list'},{'chapter_id':item.chapter.id}) }}">{{ item.chapter.title }}</a></p>
|
||||
{% endif %}
|
||||
<p>评论:<a href="javascript:" title="{{ item.content }}">{{ substr(item.content,0,25) }}</a></p>
|
||||
</td>
|
||||
<td>
|
||||
<p>昵称:{{ item.user.name }}</p>
|
||||
<p>编号:{{ item.user.id }}</p>
|
||||
</td>
|
||||
<td>{{ date('Y-m-d H:i',item.created_at) }}</td>
|
||||
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否"
|
||||
lay-filter="switch-published" comment-id="{{ item.id }}"
|
||||
{% if item.published == 1 %}checked{% endif %}></td>
|
||||
<td align="center">
|
||||
<div class="layui-dropdown">
|
||||
<button class="layui-btn layui-btn-sm">操作 <span class="layui-icon layui-icon-triangle-d"></span>
|
||||
</button>
|
||||
<ul>
|
||||
<li><a href="{{ url({'for':'admin.comment.edit','id':item.id}) }}">编辑</a></li>
|
||||
{% if item.deleted == 0 %}
|
||||
<li><a href="javascript:" url="{{ url({'for':'admin.comment.delete','id':item.id}) }}"
|
||||
class="kg-delete">删除</a></li>
|
||||
{% else %}
|
||||
<li><a href="javascript:" url="{{ url({'for':'admin.comment.restore','id':item.id}) }}"
|
||||
class="kg-delete">还原</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{{ partial('partials/pager') }}
|
||||
|
||||
<script>
|
||||
|
||||
layui.use(['jquery', 'form'], function () {
|
||||
|
||||
var $ = layui.jquery;
|
||||
var form = layui.form;
|
||||
|
||||
form.on('switch(switch-published)', function (data) {
|
||||
var commentId = $(this).attr('comment-id');
|
||||
var checked = $(this).is(':checked');
|
||||
var published = checked ? 1 : 0;
|
||||
var tips = published === 1 ? '确定要上线评论?' : '确定要下线评论?';
|
||||
layer.confirm(tips, function () {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: '/admin/comment/' + commentId + '/update',
|
||||
data: {published: published},
|
||||
success: function (res) {
|
||||
layer.msg(res.msg, {icon: 1});
|
||||
},
|
||||
error: function (xhr) {
|
||||
var json = JSON.parse(xhr.responseText);
|
||||
layer.msg(json.msg, {icon: 2});
|
||||
data.elem.checked = !checked;
|
||||
form.render();
|
||||
}
|
||||
});
|
||||
}, function () {
|
||||
data.elem.checked = !checked;
|
||||
form.render();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
67
app/Http/Admin/Views/comment/search.volt
Normal file
67
app/Http/Admin/Views/comment/search.volt
Normal file
@ -0,0 +1,67 @@
|
||||
<fieldset class="layui-elem-field layui-field-title">
|
||||
<legend>搜索评论</legend>
|
||||
</fieldset>
|
||||
|
||||
<form class="layui-form" method="GET" action="{{ url({'for':'admin.comment.list'}) }}">
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">评论编号</label>
|
||||
<div class="layui-input-block">
|
||||
<input class="layui-input" type="text" name="id" placeholder="评论编号精确匹配">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">课程编号</label>
|
||||
<div class="layui-input-block">
|
||||
<input class="layui-input" type="text" name="course_id" placeholder="课程编号精确匹配">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">章节编号</label>
|
||||
<div class="layui-input-block">
|
||||
<input class="layui-input" type="text" name="chapter_id" placeholder="章节编号精确匹配">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">用户编号</label>
|
||||
<div class="layui-input-block">
|
||||
<input class="layui-input" type="text" name="author_id" placeholder="用户编号精确匹配">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">发布</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="published" value="1" title="是">
|
||||
<input type="radio" name="published" value="0" title="否">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">删除</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="deleted" value="1" title="是">
|
||||
<input type="radio" name="deleted" value="0" title="否">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"></label>
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn" lay-submit>提交</button>
|
||||
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
<script>
|
||||
|
||||
layui.use('form', function () {
|
||||
var form = layui.form;
|
||||
});
|
||||
|
||||
</script>
|
@ -2,8 +2,8 @@
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"></label>
|
||||
<div class="layui-input-inline" style="width:150px;margin:10px 0px 5px 110px;">
|
||||
<div id="qrcode" class="qrcode" qrcode-text="{{ push_url }}"></div>
|
||||
<div class="layui-input-inline" style="width:150px;margin-left:110px;">
|
||||
<img src="/qrcode/img?text={{ push_url|url_encode }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -38,23 +38,4 @@
|
||||
|
||||
</form>
|
||||
|
||||
{{ partial('partials/clipboard_tips') }}
|
||||
|
||||
{{ javascript_include('lib/jquery.min.js') }}
|
||||
{{ javascript_include('lib/jquery.qrcode.min.js') }}
|
||||
|
||||
<script>
|
||||
|
||||
layui.use(['jquery'], function () {
|
||||
|
||||
var $ = layui.jquery;
|
||||
|
||||
$('#qrcode').qrcode({
|
||||
text: $('#qrcode').attr('qrcode-text'),
|
||||
width: 120,
|
||||
height: 120
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
{{ partial('partials/clipboard_tips') }}
|
@ -8,7 +8,7 @@
|
||||
{{ partial('config/payment_alipay') }}
|
||||
</div>
|
||||
<div class="layui-tab-item">
|
||||
{{ partial('config/payment_wxpay') }}
|
||||
{{ partial('config/payment_wechat') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user