From 1bef24f21707abf23db12707c3cf609bb6d77084 Mon Sep 17 00:00:00 2001 From: xiaochong0302 Date: Sat, 16 Sep 2023 20:51:31 +0800 Subject: [PATCH 01/21] =?UTF-8?q?1.kg=5Fcourse=E8=A1=A8=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E7=B4=A2=E5=BC=95=202.=E4=BC=98=E5=8C=96=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E9=A1=B5=203.=E4=BC=98=E5=8C=96=E5=AF=8C=E6=96=87=E6=9C=AC?= =?UTF-8?q?=E5=86=85=E5=AE=B9=E9=95=BF=E5=BA=A6=E8=8E=B7=E5=8F=96=204.?= =?UTF-8?q?=E4=BC=98=E5=8C=96layer=E5=85=B3=E9=97=AD=E7=AA=97=E5=8F=A3?= =?UTF-8?q?=E5=90=8E=E5=8F=91=E5=B8=83=E7=8A=B6=E6=80=81=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 ++ app/Builders/ArticleList.php | 4 +- app/Builders/CourseList.php | 4 +- app/Builders/HelpList.php | 4 +- app/Builders/QuestionList.php | 4 +- app/Caches/CategoryAllList.php | 50 +++++++++++++++++++ app/Http/Admin/Services/Category.php | 9 ++-- app/Http/Admin/Services/Chapter.php | 2 + app/Http/Admin/Services/Course.php | 1 + app/Http/Admin/Services/Util.php | 37 ++++++-------- app/Http/Admin/Views/article/list.volt | 14 ++++-- app/Http/Admin/Views/course/list.volt | 14 ++++-- app/Http/Admin/Views/question/list.volt | 11 +++- app/Http/Admin/Views/review/list.volt | 2 +- app/Http/Admin/Views/student/learning.volt | 19 ++----- app/Http/Home/Views/error/show401.volt | 1 + app/Http/Home/Views/error/show403.volt | 1 + app/Http/Home/Views/error/show404.volt | 1 + app/Http/Home/Views/error/show500.volt | 1 + app/Http/Home/Views/error/show503.volt | 1 + app/Library/AppInfo.php | 2 +- app/Library/Helper.php | 15 ++++++ app/Repos/Category.php | 4 +- app/Repos/Course.php | 2 +- app/Services/Logic/Course/ReviewList.php | 8 +-- app/Services/Logic/Review/ReviewCreate.php | 19 ++----- app/Services/Logic/Review/ReviewDataTrait.php | 39 +++++++++++++++ ...ndexCourseCache.php => IndexPageCache.php} | 8 ++- app/Validators/Account.php | 4 +- app/Validators/Answer.php | 2 +- app/Validators/Article.php | 2 +- app/Validators/ChapterVod.php | 2 +- app/Validators/Course.php | 6 +-- app/Validators/Help.php | 2 +- app/Validators/Page.php | 2 +- app/Validators/PointGift.php | 2 +- app/Validators/Question.php | 2 +- app/Validators/Review.php | 9 ++++ db/migrations/20230910174508.php | 39 +++++++++++++++ public/static/admin/js/common.js | 8 ++- 40 files changed, 266 insertions(+), 94 deletions(-) create mode 100644 app/Caches/CategoryAllList.php create mode 100644 app/Services/Logic/Review/ReviewDataTrait.php rename app/Services/Utils/{IndexCourseCache.php => IndexPageCache.php} (88%) create mode 100644 db/migrations/20230910174508.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 505a5ed3..091cff25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +### [v1.6.7](https://gitee.com/koogua/course-tencent-cloud/releases/v1.6.7)(2023-10-30) + + ### [v1.6.6](https://gitee.com/koogua/course-tencent-cloud/releases/v1.6.6)(2023-08-30) - 还原意外删除的AnswerList.php文件 diff --git a/app/Builders/ArticleList.php b/app/Builders/ArticleList.php index 7ef8ca46..68a78f5d 100644 --- a/app/Builders/ArticleList.php +++ b/app/Builders/ArticleList.php @@ -7,7 +7,7 @@ namespace App\Builders; -use App\Caches\CategoryList as CategoryListCache; +use App\Caches\CategoryAllList as CategoryAllListCache; use App\Models\Category as CategoryModel; use App\Repos\User as UserRepo; @@ -47,7 +47,7 @@ class ArticleList extends Builder public function getCategories() { - $cache = new CategoryListCache(); + $cache = new CategoryAllListCache(); $items = $cache->get(CategoryModel::TYPE_ARTICLE); diff --git a/app/Builders/CourseList.php b/app/Builders/CourseList.php index e5a3c383..d0dffdf4 100644 --- a/app/Builders/CourseList.php +++ b/app/Builders/CourseList.php @@ -7,7 +7,7 @@ namespace App\Builders; -use App\Caches\CategoryList as CategoryListCache; +use App\Caches\CategoryAllList as CategoryAllListCache; use App\Models\Category as CategoryModel; use App\Repos\User as UserRepo; @@ -38,7 +38,7 @@ class CourseList extends Builder public function getCategories() { - $cache = new CategoryListCache(); + $cache = new CategoryAllListCache(); $items = $cache->get(CategoryModel::TYPE_COURSE); diff --git a/app/Builders/HelpList.php b/app/Builders/HelpList.php index f451548d..bc0ee1c2 100644 --- a/app/Builders/HelpList.php +++ b/app/Builders/HelpList.php @@ -7,7 +7,7 @@ namespace App\Builders; -use App\Caches\CategoryList as CategoryListCache; +use App\Caches\CategoryAllList as CategoryAllListCache; use App\Models\Category as CategoryModel; class HelpList extends Builder @@ -26,7 +26,7 @@ class HelpList extends Builder public function getCategories() { - $cache = new CategoryListCache(); + $cache = new CategoryAllListCache(); $items = $cache->get(CategoryModel::TYPE_HELP); diff --git a/app/Builders/QuestionList.php b/app/Builders/QuestionList.php index aeabd0e8..acd093f3 100644 --- a/app/Builders/QuestionList.php +++ b/app/Builders/QuestionList.php @@ -7,7 +7,7 @@ namespace App\Builders; -use App\Caches\CategoryList as CategoryListCache; +use App\Caches\CategoryAllList as CategoryAllListCache; use App\Models\Category as CategoryModel; use App\Repos\User as UserRepo; @@ -48,7 +48,7 @@ class QuestionList extends Builder public function getCategories() { - $cache = new CategoryListCache(); + $cache = new CategoryAllListCache(); $items = $cache->get(CategoryModel::TYPE_QUESTION); diff --git a/app/Caches/CategoryAllList.php b/app/Caches/CategoryAllList.php new file mode 100644 index 00000000..5fdfbc08 --- /dev/null +++ b/app/Caches/CategoryAllList.php @@ -0,0 +1,50 @@ +lifetime; + } + + public function getKey($type = null) + { + return "category_all_list:{$type}"; + } + + /** + * @param null $type + * @return array + */ + public function getContent($type = null) + { + /** + * @var Resultset $categories + */ + $categories = CategoryModel::query() + ->columns(['id', 'parent_id', 'name', 'priority', 'level', 'path']) + ->where('type = :type:', ['type' => $type]) + ->orderBy('level ASC, priority ASC') + ->execute(); + + if ($categories->count() == 0) { + return []; + } + + return $categories->toArray(); + } + +} diff --git a/app/Http/Admin/Services/Category.php b/app/Http/Admin/Services/Category.php index 92e8caf8..2401fa99 100644 --- a/app/Http/Admin/Services/Category.php +++ b/app/Http/Admin/Services/Category.php @@ -8,6 +8,7 @@ namespace App\Http\Admin\Services; use App\Caches\Category as CategoryCache; +use App\Caches\CategoryAllList as CategoryAllListCache; use App\Caches\CategoryList as CategoryListCache; use App\Caches\CategoryTreeList as CategoryTreeListCache; use App\Models\Category as CategoryModel; @@ -140,7 +141,6 @@ class Category extends Service $category->update(); $this->updateCategoryStats($category); - $this->rebuildCategoryCache($category); return $category; @@ -182,7 +182,6 @@ class Category extends Service $category->update($data); $this->updateCategoryStats($category); - $this->rebuildCategoryCache($category); return $category; @@ -201,7 +200,6 @@ class Category extends Service $category->update(); $this->updateCategoryStats($category); - $this->rebuildCategoryCache($category); return $category; @@ -216,7 +214,6 @@ class Category extends Service $category->update(); $this->updateCategoryStats($category); - $this->rebuildCategoryCache($category); return $category; @@ -250,6 +247,10 @@ class Category extends Service $cache = new CategoryTreeListCache(); $cache->rebuild($category->type); + + $cache = new CategoryAllListCache(); + + $cache->rebuild($category->type); } protected function enableChildCategories($parentId) diff --git a/app/Http/Admin/Services/Chapter.php b/app/Http/Admin/Services/Chapter.php index 5b01ce92..5df3290a 100644 --- a/app/Http/Admin/Services/Chapter.php +++ b/app/Http/Admin/Services/Chapter.php @@ -201,7 +201,9 @@ class Chapter extends Service } $lessonCount = $chapterRepo->countLessons($chapter->id); + $chapter->lesson_count = $lessonCount; + $chapter->update(); } diff --git a/app/Http/Admin/Services/Course.php b/app/Http/Admin/Services/Course.php index 7e8bd99f..7e98d612 100644 --- a/app/Http/Admin/Services/Course.php +++ b/app/Http/Admin/Services/Course.php @@ -453,6 +453,7 @@ class Course extends Service $courseTeacher->user_id = $teacherId; $courseTeacher->role_type = CourseUserModel::ROLE_TEACHER; $courseTeacher->source_type = CourseUserModel::SOURCE_IMPORT; + $courseTeacher->expiry_time = strtotime('+30 years'); $courseTeacher->create(); } } diff --git a/app/Http/Admin/Services/Util.php b/app/Http/Admin/Services/Util.php index b9352de6..552f235b 100644 --- a/app/Http/Admin/Services/Util.php +++ b/app/Http/Admin/Services/Util.php @@ -7,8 +7,7 @@ namespace App\Http\Admin\Services; -use App\Caches\IndexSlideList as IndexSlideListCache; -use App\Services\Utils\IndexCourseCache as IndexCourseCacheUtil; +use App\Services\Utils\IndexPageCache as IndexPageCacheUtil; class Util extends Service { @@ -17,29 +16,25 @@ class Util extends Service { $items = $this->request->getPost('items'); - if ($items['slide'] == 1) { - $cache = new IndexSlideListCache(); - $cache->rebuild(); + $sections = [ + 'slide', + 'featured_course', + 'new_course', + 'free_course', + 'vip_course', + ]; + + if (empty($items)) { + $items = $sections; } - $util = new IndexCourseCacheUtil(); + $util = new IndexPageCacheUtil(); - if ($items['featured_course'] == 1) { - $util->rebuild('featured_course'); + foreach ($sections as $section) { + if (in_array($section, $items)) { + $util->rebuild($section); + } } - - if ($items['new_course'] == 1) { - $util->rebuild('new_course'); - } - - if ($items['free_course'] == 1) { - $util->rebuild('free_course'); - } - - if ($items['vip_course'] == 1) { - $util->rebuild('vip_course'); - } - } } diff --git a/app/Http/Admin/Views/article/list.volt b/app/Http/Admin/Views/article/list.volt index 13269e08..50f9c6f6 100644 --- a/app/Http/Admin/Views/article/list.volt +++ b/app/Http/Admin/Views/article/list.volt @@ -80,8 +80,10 @@ {{ item.like_count }} {{ item.favorite_count }} {{ publish_status(item.published) }} - - + +
@@ -126,7 +128,13 @@ var featured = checked ? 1 : 0; var url = $(this).data('url'); var tips = featured === 1 ? '确定要推荐?' : '确定要取消推荐?'; - layer.confirm(tips, function () { + layer.confirm(tips, { + cancel: function (index) { + layer.close(index); + data.elem.checked = !checked; + form.render(); + } + }, function () { $.ajax({ type: 'POST', url: url, diff --git a/app/Http/Admin/Views/course/list.volt b/app/Http/Admin/Views/course/list.volt index 0b17998e..0c25d653 100644 --- a/app/Http/Admin/Views/course/list.volt +++ b/app/Http/Admin/Views/course/list.volt @@ -96,8 +96,10 @@

市场:{{ '¥%0.2f'|format(item.market_price) }}

会员:{{ '¥%0.2f'|format(item.vip_price) }}

- - + +
@@ -144,7 +146,13 @@ var featured = checked ? 1 : 0; var url = $(this).data('url'); var tips = featured === 1 ? '确定要推荐?' : '确定要取消推荐?'; - layer.confirm(tips, function () { + layer.confirm(tips, { + cancel: function (index) { + layer.close(index); + data.elem.checked = !checked; + form.render(); + } + }, function () { $.ajax({ type: 'POST', url: url, diff --git a/app/Http/Admin/Views/question/list.volt b/app/Http/Admin/Views/question/list.volt index 66d8e660..da8d49d9 100644 --- a/app/Http/Admin/Views/question/list.volt +++ b/app/Http/Admin/Views/question/list.volt @@ -78,7 +78,8 @@ {{ item.like_count }} {{ item.favorite_count }} {{ publish_status(item.published) }} - +
@@ -124,7 +125,13 @@ var closed = checked ? 1 : 0; var url = $(this).data('url'); var tips = closed === 1 ? '确定要关闭讨论?' : '确定要开启讨论?'; - layer.confirm(tips, function () { + layer.confirm(tips, { + cancel: function (index) { + layer.close(index); + data.elem.checked = !checked; + form.render(); + } + }, function () { $.ajax({ type: 'POST', url: url, diff --git a/app/Http/Admin/Views/review/list.volt b/app/Http/Admin/Views/review/list.volt index 59276eff..6dc86644 100644 --- a/app/Http/Admin/Views/review/list.volt +++ b/app/Http/Admin/Views/review/list.volt @@ -52,7 +52,7 @@

课程:{{ item.course.title }}({{ item.course.id }})

-

评价:{{ item.content }}

+

评价:{{ substr(item.content,0,30) }}({{ item.id }})

时间:{{ date('Y-m-d H:i:s',item.create_time) }}

diff --git a/app/Http/Admin/Views/student/learning.volt b/app/Http/Admin/Views/student/learning.volt index 314ef2c2..61d5d226 100644 --- a/app/Http/Admin/Views/student/learning.volt +++ b/app/Http/Admin/Views/student/learning.volt @@ -2,17 +2,7 @@ {% block content %} - {%- macro client_type_info(value) %} - {% if value == 1 %} - desktop - {% elseif value == 2 %} - mobile - {% elseif value == 3 %} - app - {% elseif value == 4 %} - 小程序 - {% endif %} - {%- endmacro %} + {{ partial('macros/common') }} @@ -20,7 +10,6 @@ - @@ -36,11 +25,11 @@ {% set active_time = item.active_time > 0 ? date('Y-m-d H:i:s',item.active_time) : 'N/A' %} diff --git a/app/Http/Home/Views/error/show401.volt b/app/Http/Home/Views/error/show401.volt index c483a510..b42bae93 100644 --- a/app/Http/Home/Views/error/show401.volt +++ b/app/Http/Home/Views/error/show401.volt @@ -5,6 +5,7 @@
+
无操作权限,请先登录认证

4 diff --git a/app/Http/Home/Views/error/show403.volt b/app/Http/Home/Views/error/show403.volt index c4ef6f50..5b807f52 100644 --- a/app/Http/Home/Views/error/show403.volt +++ b/app/Http/Home/Views/error/show403.volt @@ -5,6 +5,7 @@
+
无操作权限,禁止访问

4 diff --git a/app/Http/Home/Views/error/show404.volt b/app/Http/Home/Views/error/show404.volt index c20a6f27..1e1e276b 100644 --- a/app/Http/Home/Views/error/show404.volt +++ b/app/Http/Home/Views/error/show404.volt @@ -5,6 +5,7 @@
+
迷失自我,相关资源不存在

4 diff --git a/app/Http/Home/Views/error/show500.volt b/app/Http/Home/Views/error/show500.volt index 5a8cff68..e579901e 100644 --- a/app/Http/Home/Views/error/show500.volt +++ b/app/Http/Home/Views/error/show500.volt @@ -5,6 +5,7 @@
+
尴尬到家,服务器内部错误

5 diff --git a/app/Http/Home/Views/error/show503.volt b/app/Http/Home/Views/error/show503.volt index 4cf9059a..31f883eb 100644 --- a/app/Http/Home/Views/error/show503.volt +++ b/app/Http/Home/Views/error/show503.volt @@ -5,6 +5,7 @@
+
压力山大,当前服务不可用

5 diff --git a/app/Library/AppInfo.php b/app/Library/AppInfo.php index db1f3483..a33bb0a3 100644 --- a/app/Library/AppInfo.php +++ b/app/Library/AppInfo.php @@ -16,7 +16,7 @@ class AppInfo protected $link = 'https://www.koogua.com'; - protected $version = '1.6.6'; + protected $version = '1.6.7'; public function __get($name) { diff --git a/app/Library/Helper.php b/app/Library/Helper.php index 0240e6ec..55f5a8f5 100644 --- a/app/Library/Helper.php +++ b/app/Library/Helper.php @@ -424,6 +424,21 @@ function kg_cos_img_style_trim($path) return preg_replace('/!\w+/', '', $path); } +/** + * 获取编辑器内容长度 + * + * @param string $content + * @return int + */ +function kg_editor_content_length($content) +{ + $content = trim($content); + + $content = strip_tags($content,''); + + return kg_strlen($content); +} + /** * 清理html内容 * diff --git a/app/Repos/Category.php b/app/Repos/Category.php index 3de5830e..7a97ffca 100644 --- a/app/Repos/Category.php +++ b/app/Repos/Category.php @@ -85,6 +85,7 @@ class Category extends Repository ->where('type = :type:', ['type' => $type]) ->andWhere('parent_id = 0') ->andWhere('published = 1') + ->andWhere('deleted = 0') ->orderBy('priority ASC') ->execute(); } @@ -98,6 +99,7 @@ class Category extends Repository return CategoryModel::query() ->where('parent_id = :parent_id:', ['parent_id' => $categoryId]) ->andWhere('published = 1') + ->andWhere('deleted = 0') ->orderBy('priority ASC') ->execute(); } @@ -105,7 +107,7 @@ class Category extends Repository public function countChildCategories($categoryId) { return (int)CategoryModel::count([ - 'conditions' => 'parent_id = :parent_id: AND published = 1', + 'conditions' => 'parent_id = :parent_id: AND published = 1 AND deleted = 0', 'bind' => ['parent_id' => $categoryId], ]); } diff --git a/app/Repos/Course.php b/app/Repos/Course.php index 40000ae0..7a504ef3 100644 --- a/app/Repos/Course.php +++ b/app/Repos/Course.php @@ -79,7 +79,7 @@ class Course extends Repository if (!empty($where['level'])) { if (is_array($where['level'])) { - $builder->inWhere('level', $where['model']); + $builder->inWhere('level', $where['level']); } else { $builder->andWhere('level = :level:', ['level' => $where['level']]); } diff --git a/app/Services/Logic/Course/ReviewList.php b/app/Services/Logic/Course/ReviewList.php index 5e97dd97..f3a1c270 100644 --- a/app/Services/Logic/Course/ReviewList.php +++ b/app/Services/Logic/Course/ReviewList.php @@ -102,11 +102,11 @@ class ReviewList extends LogicService $result = []; - foreach ($reviews as $consult) { - $result[$consult['id']] = [ + foreach ($reviews as $review) { + $result[$review['id']] = [ 'logged' => $user->id > 0 ? 1 : 0, - 'liked' => in_array($consult['id'], $likedIds) ? 1 : 0, - 'owned' => $consult['owner_id'] == $user->id ? 1 : 0, + 'liked' => in_array($review['id'], $likedIds) ? 1 : 0, + 'owned' => $review['owner_id'] == $user->id ? 1 : 0, ]; } diff --git a/app/Services/Logic/Review/ReviewCreate.php b/app/Services/Logic/Review/ReviewCreate.php index 07d4520d..52aa2507 100644 --- a/app/Services/Logic/Review/ReviewCreate.php +++ b/app/Services/Logic/Review/ReviewCreate.php @@ -16,16 +16,14 @@ use App\Services\Logic\CourseTrait; use App\Services\Logic\Point\History\CourseReview as CourseReviewPointHistory; use App\Services\Logic\ReviewTrait; use App\Services\Logic\Service as LogicService; -use App\Traits\Client as ClientTrait; use App\Validators\CourseUser as CourseUserValidator; -use App\Validators\Review as ReviewValidator; class ReviewCreate extends LogicService { - use ClientTrait; use CourseTrait; use ReviewTrait; + use ReviewDataTrait; public function handle() { @@ -41,19 +39,10 @@ class ReviewCreate extends LogicService $validator->checkIfReviewed($course->id, $user->id); - $validator = new ReviewValidator(); + $data = $this->handlePostData($post); - $data = [ - 'client_type' => $this->getClientType(), - 'client_ip' => $this->getClientIp(), - 'course_id' => $course->id, - 'owner_id' => $user->id, - ]; - - $data['content'] = $validator->checkContent($post['content']); - $data['rating1'] = $validator->checkRating($post['rating1']); - $data['rating2'] = $validator->checkRating($post['rating2']); - $data['rating3'] = $validator->checkRating($post['rating3']); + $data['course_id'] = $course->id; + $data['owner_id'] = $user->id; $data['published'] = 1; $review = new ReviewModel(); diff --git a/app/Services/Logic/Review/ReviewDataTrait.php b/app/Services/Logic/Review/ReviewDataTrait.php new file mode 100644 index 00000000..649cda30 --- /dev/null +++ b/app/Services/Logic/Review/ReviewDataTrait.php @@ -0,0 +1,39 @@ +getClientType(); + $data['client_ip'] = $this->getClientIp(); + + $validator = new ReviewValidator(); + + $data['content'] = $validator->checkContent($post['content']); + $data['rating1'] = $validator->checkRating($post['rating1']); + $data['rating2'] = $validator->checkRating($post['rating2']); + $data['rating3'] = $validator->checkRating($post['rating3']); + + if (isset($post['anonymous'])) { + $data['anonymous'] = $validator->checkAnonymous($post['anonymous']); + } + + return $data; + } + +} diff --git a/app/Services/Utils/IndexCourseCache.php b/app/Services/Utils/IndexPageCache.php similarity index 88% rename from app/Services/Utils/IndexCourseCache.php rename to app/Services/Utils/IndexPageCache.php index 7b56a4be..76c737b4 100644 --- a/app/Services/Utils/IndexCourseCache.php +++ b/app/Services/Utils/IndexPageCache.php @@ -7,6 +7,7 @@ namespace App\Services\Utils; +use App\Caches\IndexSlideList as IndexSlideListCache; use App\Caches\IndexFeaturedCourseList as IndexFeaturedCourseListCache; use App\Caches\IndexFreeCourseList as IndexFreeCourseListCache; use App\Caches\IndexNewCourseList as IndexNewCourseListCache; @@ -17,11 +18,16 @@ use App\Caches\IndexSimpleVipCourseList as IndexSimpleVipCourseListCache; use App\Caches\IndexVipCourseList as IndexVipCourseListCache; use App\Services\Service as AppService; -class IndexCourseCache extends AppService +class IndexPageCache extends AppService { public function rebuild($section = null) { + if (!$section || $section == 'slide') { + $cache = new IndexSlideListCache(); + $cache->rebuild(); + } + if (!$section || $section == 'featured_course') { $cache = new IndexFeaturedCourseListCache(); $cache->rebuild(); diff --git a/app/Validators/Account.php b/app/Validators/Account.php index a70e8878..7daec3fd 100644 --- a/app/Validators/Account.php +++ b/app/Validators/Account.php @@ -159,9 +159,7 @@ class Account extends Validator $account = $this->checkAccount($name); - $hash = PasswordUtil::hash($password, $account->salt); - - if ($hash != $account->password) { + if (!PasswordUtil::checkHash($password, $account->salt, $account->password)) { throw new BadRequestException('account.login_pwd_incorrect'); } diff --git a/app/Validators/Answer.php b/app/Validators/Answer.php index bb1099a4..d8c2eef1 100644 --- a/app/Validators/Answer.php +++ b/app/Validators/Answer.php @@ -63,7 +63,7 @@ class Answer extends Validator $value = $storage->handle($value); - $length = kg_strlen($value); + $length = kg_editor_content_length($value); if ($length < 10) { throw new BadRequestException('answer.content_too_short'); diff --git a/app/Validators/Article.php b/app/Validators/Article.php index 9987d097..7aeaccdc 100644 --- a/app/Validators/Article.php +++ b/app/Validators/Article.php @@ -99,7 +99,7 @@ class Article extends Validator $value = $storage->handle($value); - $length = kg_strlen($value); + $length = kg_editor_content_length($value); if ($length < 10) { throw new BadRequestException('article.content_too_short'); diff --git a/app/Validators/ChapterVod.php b/app/Validators/ChapterVod.php index 81651391..0d19bcec 100644 --- a/app/Validators/ChapterVod.php +++ b/app/Validators/ChapterVod.php @@ -26,7 +26,7 @@ class ChapterVod extends Validator public function checkDuration($duration) { - $value = $value = $this->filter->sanitize($duration, ['trim', 'int']); + $value = $this->filter->sanitize($duration, ['trim', 'int']); if ($value < 10 || $value > 10 * 3600) { throw new BadRequestException('chapter_vod.invalid_duration'); diff --git a/app/Validators/Course.php b/app/Validators/Course.php index b562d98f..b791adf2 100644 --- a/app/Validators/Course.php +++ b/app/Validators/Course.php @@ -124,7 +124,7 @@ class Course extends Validator $value = $storage->handle($value); - $length = kg_strlen($value); + $length = kg_editor_content_length($value); if ($length > 30000) { throw new BadRequestException('course.details_too_long'); @@ -257,11 +257,11 @@ class Course extends Validator public function checkPublishAbility(CourseModel $course) { - if ($course->model == CourseModel::MODEL_OFFLINE) return true; - if ($course->teacher_id == 0) { throw new BadRequestException('course.teacher_not_assigned'); } + + return true; } } diff --git a/app/Validators/Help.php b/app/Validators/Help.php index c5acab63..a1356f5a 100644 --- a/app/Validators/Help.php +++ b/app/Validators/Help.php @@ -95,7 +95,7 @@ class Help extends Validator $value = $storage->handle($value); - $length = kg_strlen($value); + $length = kg_editor_content_length($value); if ($length < 10) { throw new BadRequestException('help.content_too_short'); diff --git a/app/Validators/Page.php b/app/Validators/Page.php index 2080d7a6..7bf04814 100644 --- a/app/Validators/Page.php +++ b/app/Validators/Page.php @@ -129,7 +129,7 @@ class Page extends Validator $value = $storage->handle($value); - $length = kg_strlen($value); + $length = kg_editor_content_length($value); if ($length < 10) { throw new BadRequestException('page.content_too_short'); diff --git a/app/Validators/PointGift.php b/app/Validators/PointGift.php index 4f7e30b1..352f6504 100644 --- a/app/Validators/PointGift.php +++ b/app/Validators/PointGift.php @@ -91,7 +91,7 @@ class PointGift extends Validator $value = $storage->handle($value); - $length = kg_strlen($value); + $length = kg_editor_content_length($value); if ($length > 30000) { throw new BadRequestException('point_gift.details_too_long'); diff --git a/app/Validators/Question.php b/app/Validators/Question.php index 84d1e98d..b4ff8be4 100644 --- a/app/Validators/Question.php +++ b/app/Validators/Question.php @@ -111,7 +111,7 @@ class Question extends Validator $value = $storage->handle($value); - $length = kg_strlen($value); + $length = kg_editor_content_length($value); if ($length > 30000) { throw new BadRequestException('question.content_too_long'); diff --git a/app/Validators/Review.php b/app/Validators/Review.php index b5faf25f..2ab09073 100644 --- a/app/Validators/Review.php +++ b/app/Validators/Review.php @@ -61,6 +61,15 @@ class Review extends Validator return $rating; } + public function checkAnonymous($status) + { + if (!in_array($status, [0, 1])) { + throw new BadRequestException('review.invalid_anonymous_status'); + } + + return $status; + } + public function checkPublishStatus($status) { if (!in_array($status, [0, 1])) { diff --git a/db/migrations/20230910174508.php b/db/migrations/20230910174508.php new file mode 100644 index 00000000..7cc60ada --- /dev/null +++ b/db/migrations/20230910174508.php @@ -0,0 +1,39 @@ +alterCourseTable(); + } + + protected function alterCourseTable() + { + $table = $this->table('kg_course'); + + if (!$table->hasIndexByName('category_id')) { + $table->addIndex(['category_id'], [ + 'name' => 'category_id', + 'unique' => false, + ]); + } + + if (!$table->hasIndexByName('teacher_id')) { + $table->addIndex(['teacher_id'], [ + 'name' => 'teacher_id', + 'unique' => false, + ]); + } + + $table->save(); + } + +} diff --git a/public/static/admin/js/common.js b/public/static/admin/js/common.js index 2773c11f..97fc1e05 100644 --- a/public/static/admin/js/common.js +++ b/public/static/admin/js/common.js @@ -84,7 +84,13 @@ layui.use(['jquery', 'form', 'element', 'layer', 'kgDropdown'], function () { var published = checked ? 1 : 0; var url = $(this).data('url'); var tips = published === 1 ? '确定要上线?' : '确定要下线?'; - layer.confirm(tips, function () { + layer.confirm(tips, { + cancel: function (index) { + layer.close(index); + data.elem.checked = !checked; + form.render(); + } + }, function () { $.ajax({ type: 'POST', url: url, From 7d54f0e933a4ad95dee220eb5d36013ccd7cf872 Mon Sep 17 00:00:00 2001 From: xiaochong0302 Date: Sat, 16 Sep 2023 21:44:23 +0800 Subject: [PATCH 02/21] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8C=BF=E5=90=8D?= =?UTF-8?q?=E8=AF=84=E4=BB=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Admin/Controllers/ReviewController.php | 2 ++ app/Http/Admin/Services/Review.php | 4 ++++ app/Http/Admin/Views/review/edit.volt | 16 ++++++++++++++++ app/Http/Admin/Views/review/search.volt | 7 +++++++ app/Http/Home/Views/course/reviews.volt | 14 ++++++++++---- app/Http/Home/Views/review/add.volt | 7 +++++++ app/Http/Home/Views/review/edit.volt | 7 +++++++ app/Services/Logic/Course/ReviewList.php | 1 + app/Services/Logic/Review/ReviewInfo.php | 1 + 9 files changed, 55 insertions(+), 4 deletions(-) diff --git a/app/Http/Admin/Controllers/ReviewController.php b/app/Http/Admin/Controllers/ReviewController.php index b76c569e..1434f9b9 100644 --- a/app/Http/Admin/Controllers/ReviewController.php +++ b/app/Http/Admin/Controllers/ReviewController.php @@ -56,8 +56,10 @@ class ReviewController extends Controller $reviewService = new ReviewService(); $review = $reviewService->getReview($id); + $publishTypes = $reviewService->getPublishTypes(); $this->view->setVar('review', $review); + $this->view->setVar('publish_types', $publishTypes); } /** diff --git a/app/Http/Admin/Services/Review.php b/app/Http/Admin/Services/Review.php index 14bc5aa7..efd5a2cc 100644 --- a/app/Http/Admin/Services/Review.php +++ b/app/Http/Admin/Services/Review.php @@ -91,6 +91,10 @@ class Review extends Service $data['rating3'] = $validator->checkRating($post['rating3']); } + if (isset($post['anonymous'])) { + $data['anonymous'] = $validator->checkAnonymous($post['anonymous']); + } + if (isset($post['published'])) { $data['published'] = $validator->checkPublishStatus($post['published']); $this->recountCourseReviews($course); diff --git a/app/Http/Admin/Views/review/edit.volt b/app/Http/Admin/Views/review/edit.volt index eff64270..d7ff6bd6 100644 --- a/app/Http/Admin/Views/review/edit.volt +++ b/app/Http/Admin/Views/review/edit.volt @@ -33,6 +33,22 @@

+
+ +
+ {% for value,title in publish_types %} + {% set checked = value == review.published ? 'checked="checked"' : '' %} + + {% endfor %} +
+
+
+ +
+ + +
+
diff --git a/app/Http/Admin/Views/review/search.volt b/app/Http/Admin/Views/review/search.volt index 048436df..b2f0271f 100644 --- a/app/Http/Admin/Views/review/search.volt +++ b/app/Http/Admin/Views/review/search.volt @@ -32,6 +32,13 @@ {% endfor %}
+
+ +
+ + +
+
diff --git a/app/Http/Home/Views/course/reviews.volt b/app/Http/Home/Views/course/reviews.volt index 352573c3..0949507d 100644 --- a/app/Http/Home/Views/course/reviews.volt +++ b/app/Http/Home/Views/course/reviews.volt @@ -3,18 +3,24 @@ {% if pager.total_pages > 0 %}
{% for item in pager.items %} - {% set owner_url = url({'for':'home.user.show','id':item.owner.id}) %} + {% if item.anonymous == 0 %} + {% set owner_url = url({'for':'home.user.show','id':item.owner.id}) %} + {% set owner_name = item.owner.name %} + {% else %} + {% set owner_url = 'javascript:' %} + {% set owner_name = '匿名用户' %} + {% endif %} {% set like_url = url({'for':'home.review.like','id':item.id}) %}
{{ star_info(item.rating) }}
{{ item.content }}
+
+ +
+ + +
+
diff --git a/app/Http/Home/Views/review/edit.volt b/app/Http/Home/Views/review/edit.volt index 5a46d685..a6056c66 100644 --- a/app/Http/Home/Views/review/edit.volt +++ b/app/Http/Home/Views/review/edit.volt @@ -29,6 +29,13 @@
+
+ +
+ + +
+
diff --git a/app/Services/Logic/Course/ReviewList.php b/app/Services/Logic/Course/ReviewList.php index f3a1c270..a41acbba 100644 --- a/app/Services/Logic/Course/ReviewList.php +++ b/app/Services/Logic/Course/ReviewList.php @@ -69,6 +69,7 @@ class ReviewList extends LogicService 'id' => $review['id'], 'rating' => $review['rating'], 'content' => $review['content'], + 'anonymous' => $review['anonymous'], 'like_count' => $review['like_count'], 'create_time' => $review['create_time'], 'update_time' => $review['update_time'], diff --git a/app/Services/Logic/Review/ReviewInfo.php b/app/Services/Logic/Review/ReviewInfo.php index 7a2ac9c9..6e3cd18f 100644 --- a/app/Services/Logic/Review/ReviewInfo.php +++ b/app/Services/Logic/Review/ReviewInfo.php @@ -44,6 +44,7 @@ class ReviewInfo extends LogicService 'rating1' => $review->rating1, 'rating2' => $review->rating2, 'rating3' => $review->rating3, + 'anonymous' => $review->anonymous, 'published' => $review->published, 'deleted' => $review->deleted, 'like_count' => $review->like_count, From 2c881547b489e95a17988d13df73ee7e2f804008 Mon Sep 17 00:00:00 2001 From: xiaochong0302 Date: Mon, 18 Sep 2023 06:52:40 +0800 Subject: [PATCH 03/21] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E8=AF=BE=E7=A8=8B?= =?UTF-8?q?=E8=AF=BE=E4=BB=B6=E8=B5=84=E6=BA=90=E5=88=97=E8=A1=A8=E6=9D=83?= =?UTF-8?q?=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Admin/Services/Role.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Admin/Services/Role.php b/app/Http/Admin/Services/Role.php index 354c6b7f..e6e50b2e 100644 --- a/app/Http/Admin/Services/Role.php +++ b/app/Http/Admin/Services/Role.php @@ -147,8 +147,8 @@ class Role extends Service if (in_array('admin.course.list', $routes)) { $list[] = 'admin.course.chapters'; + $list[] = 'admin.course.resources'; $list[] = 'admin.chapter.lessons'; - $list[] = 'admin.chapter.resources'; } if (array_intersect(['admin.course.add', 'admin.course.edit'], $routes)) { From 0a86fc3f05c5027c59dbbaaf141f7beda7d3e720 Mon Sep 17 00:00:00 2001 From: xiaochong0302 Date: Fri, 22 Sep 2023 20:41:42 +0800 Subject: [PATCH 04/21] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E7=BB=91=E5=AE=9A?= =?UTF-8?q?=E9=82=AE=E7=AE=B1password=E6=9C=AA=E5=AE=9A=E4=B9=89=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Home/Controllers/UserConsoleController.php | 2 -- app/Services/Logic/User/Console/AccountInfo.php | 5 ++++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/Http/Home/Controllers/UserConsoleController.php b/app/Http/Home/Controllers/UserConsoleController.php index 32e64e71..672b497e 100644 --- a/app/Http/Home/Controllers/UserConsoleController.php +++ b/app/Http/Home/Controllers/UserConsoleController.php @@ -19,8 +19,6 @@ use App\Services\Logic\User\Console\ContactInfo as ContactInfoService; use App\Services\Logic\User\Console\ContactUpdate as ContactUpdateService; use App\Services\Logic\User\Console\CourseList as CourseListService; use App\Services\Logic\User\Console\FavoriteList as FavoriteListService; -use App\Services\Logic\User\Console\FriendList as FriendListService; -use App\Services\Logic\User\Console\GroupList as GroupListService; use App\Services\Logic\User\Console\NotificationList as NotificationListService; use App\Services\Logic\User\Console\NotificationRead as NotificationReadService; use App\Services\Logic\User\Console\NotifyStats as NotifyStatsService; diff --git a/app/Services/Logic/User/Console/AccountInfo.php b/app/Services/Logic/User/Console/AccountInfo.php index 41a88140..7f8a54bd 100644 --- a/app/Services/Logic/User/Console/AccountInfo.php +++ b/app/Services/Logic/User/Console/AccountInfo.php @@ -29,8 +29,11 @@ class AccountInfo extends LogicService return [ 'id' => $account->id, - 'phone' => $account->phone, 'email' => $account->email, + 'phone' => $account->phone, + 'password' => $account->password, + 'create_time' => $account->create_time, + 'update_time' => $account->update_time, ]; } From 51de0ed94ba25e0ad377f06ec8dced257f236cc3 Mon Sep 17 00:00:00 2001 From: koogua Date: Sun, 1 Oct 2023 11:05:53 +0800 Subject: [PATCH 05/21] =?UTF-8?q?=E5=AD=97=E6=95=B0=E7=BB=9F=E8=AE=A1?= =?UTF-8?q?=E5=8A=A0=E4=B8=8A=E5=9B=BE=E7=89=87=E5=AD=97=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Library/Utils/Word.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/Library/Utils/Word.php b/app/Library/Utils/Word.php index 9193e8e4..6bca8601 100644 --- a/app/Library/Utils/Word.php +++ b/app/Library/Utils/Word.php @@ -14,13 +14,15 @@ class Word public static function getWordCount($str) { + $imageWordCount = self::getImageWordCount($str); + $chineseWordCount = self::getChineseWordCount($str); $str = self::filterChineseWords($str); $englishWordCount = self::getEnglishWordCount($str); - $count = $chineseWordCount + $englishWordCount; + $count = $imageWordCount + $chineseWordCount + $englishWordCount; return (int)$count; } @@ -54,6 +56,11 @@ class Word return (int)$count; } + public static function getImageWordCount($str) + { + return 100 * substr_count($str, ' Date: Sun, 29 Oct 2023 22:30:14 +0800 Subject: [PATCH 06/21] =?UTF-8?q?=E7=B2=BE=E7=AE=80=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Admin/Views/course/edit_related.volt | 2 +- app/Http/Admin/Views/package/add.volt | 2 +- app/Http/Admin/Views/package/edit.volt | 2 +- app/Http/Admin/Views/refund/show.volt | 2 +- app/Http/Admin/Views/role/add.volt | 2 +- app/Http/Admin/Views/role/edit.volt | 2 +- app/Http/Admin/Views/tag/add.volt | 2 +- app/Http/Admin/Views/tag/edit.volt | 2 +- app/Http/Admin/Views/topic/add.volt | 2 +- app/Http/Admin/Views/topic/edit_basic.volt | 2 +- app/Http/Admin/Views/topic/edit_course.volt | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/Http/Admin/Views/course/edit_related.volt b/app/Http/Admin/Views/course/edit_related.volt index 739b1085..473ee342 100644 --- a/app/Http/Admin/Views/course/edit_related.volt +++ b/app/Http/Admin/Views/course/edit_related.volt @@ -8,7 +8,7 @@
- +
diff --git a/app/Http/Admin/Views/package/add.volt b/app/Http/Admin/Views/package/add.volt index 7a0a4163..e5f8ab33 100644 --- a/app/Http/Admin/Views/package/add.volt +++ b/app/Http/Admin/Views/package/add.volt @@ -15,7 +15,7 @@
- +
diff --git a/app/Http/Admin/Views/package/edit.volt b/app/Http/Admin/Views/package/edit.volt index e7eedc14..b23c5016 100644 --- a/app/Http/Admin/Views/package/edit.volt +++ b/app/Http/Admin/Views/package/edit.volt @@ -55,7 +55,7 @@
- +
diff --git a/app/Http/Admin/Views/refund/show.volt b/app/Http/Admin/Views/refund/show.volt index 4d9692a1..d46e8d87 100644 --- a/app/Http/Admin/Views/refund/show.volt +++ b/app/Http/Admin/Views/refund/show.volt @@ -60,7 +60,7 @@
- +
diff --git a/app/Http/Admin/Views/role/add.volt b/app/Http/Admin/Views/role/add.volt index 837f6094..7e8d40ca 100644 --- a/app/Http/Admin/Views/role/add.volt +++ b/app/Http/Admin/Views/role/add.volt @@ -21,7 +21,7 @@
- +
diff --git a/app/Http/Admin/Views/role/edit.volt b/app/Http/Admin/Views/role/edit.volt index d54835c6..a8d6dcb2 100644 --- a/app/Http/Admin/Views/role/edit.volt +++ b/app/Http/Admin/Views/role/edit.volt @@ -43,7 +43,7 @@
- +
diff --git a/app/Http/Admin/Views/tag/add.volt b/app/Http/Admin/Views/tag/add.volt index b2d30288..9b81ad04 100644 --- a/app/Http/Admin/Views/tag/add.volt +++ b/app/Http/Admin/Views/tag/add.volt @@ -15,7 +15,7 @@
- +
diff --git a/app/Http/Admin/Views/tag/edit.volt b/app/Http/Admin/Views/tag/edit.volt index d7a190c0..c6b4814f 100644 --- a/app/Http/Admin/Views/tag/edit.volt +++ b/app/Http/Admin/Views/tag/edit.volt @@ -49,7 +49,7 @@
- +
diff --git a/app/Http/Admin/Views/topic/add.volt b/app/Http/Admin/Views/topic/add.volt index 573ba53a..f57b584d 100644 --- a/app/Http/Admin/Views/topic/add.volt +++ b/app/Http/Admin/Views/topic/add.volt @@ -15,7 +15,7 @@
- +
diff --git a/app/Http/Admin/Views/topic/edit_basic.volt b/app/Http/Admin/Views/topic/edit_basic.volt index 31285bae..20740037 100644 --- a/app/Http/Admin/Views/topic/edit_basic.volt +++ b/app/Http/Admin/Views/topic/edit_basic.volt @@ -31,7 +31,7 @@
- +
diff --git a/app/Http/Admin/Views/topic/edit_course.volt b/app/Http/Admin/Views/topic/edit_course.volt index 19443fde..f303888a 100644 --- a/app/Http/Admin/Views/topic/edit_course.volt +++ b/app/Http/Admin/Views/topic/edit_course.volt @@ -8,7 +8,7 @@
- +
From 79a678fa546c5e3551309dfdd71a012ae31320c9 Mon Sep 17 00:00:00 2001 From: xiaochong0302 Date: Mon, 4 Dec 2023 19:46:54 +0800 Subject: [PATCH 07/21] =?UTF-8?q?=E9=98=B6=E6=AE=B5=E6=80=A7=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Builders/DanmuList.php | 104 ----- app/Builders/QuestionList.php | 4 +- app/Builders/UserList.php | 32 ++ app/Caches/FlashSale.php | 36 -- app/Caches/IndexFlashSaleList.php | 36 -- app/Caches/MaxFlashSaleId.php | 34 -- app/Console/Tasks/CloseFlashSaleOrderTask.php | 86 ---- app/Console/Tasks/CloseOrderTask.php | 2 - app/Console/Tasks/DeliverTask.php | 4 +- app/Console/Tasks/RefundTask.php | 5 +- .../Admin/Controllers/AnswerController.php | 38 ++ .../Admin/Controllers/ArticleController.php | 48 ++- .../Admin/Controllers/CommentController.php | 38 ++ .../Admin/Controllers/ConsultController.php | 42 ++ .../Admin/Controllers/CourseController.php | 96 ++++- .../Admin/Controllers/FlashSaleController.php | 153 ------- .../Admin/Controllers/QuestionController.php | 55 ++- .../Admin/Controllers/ReviewController.php | 42 ++ .../Admin/Controllers/StudentController.php | 141 ------- app/Http/Admin/Controllers/VipController.php | 126 ++++++ app/Http/Admin/Services/Answer.php | 110 +++-- app/Http/Admin/Services/Article.php | 148 ++++--- app/Http/Admin/Services/AuthNode.php | 211 ++++------ app/Http/Admin/Services/Comment.php | 130 +++++- app/Http/Admin/Services/Consult.php | 178 +++++++- app/Http/Admin/Services/Course.php | 296 +++++--------- app/Http/Admin/Services/CourseLearning.php | 64 +++ app/Http/Admin/Services/CourseUser.php | 101 +++++ app/Http/Admin/Services/FlashSale.php | 380 ------------------ app/Http/Admin/Services/Order.php | 25 ++ app/Http/Admin/Services/Question.php | 134 ++++-- app/Http/Admin/Services/Refund.php | 16 + app/Http/Admin/Services/Review.php | 165 +++++++- app/Http/Admin/Services/Role.php | 3 + app/Http/Admin/Services/Student.php | 223 ---------- app/Http/Admin/Services/Trade.php | 16 + app/Http/Admin/Services/User.php | 9 +- app/Http/Admin/Services/Vip.php | 120 ++++++ app/Http/Admin/Views/answer/list.volt | 24 +- app/Http/Admin/Views/answer/moderate.volt | 4 +- app/Http/Admin/Views/answer/report.volt | 6 +- app/Http/Admin/Views/answer/search.volt | 32 +- app/Http/Admin/Views/article/edit.volt | 7 + app/Http/Admin/Views/article/edit_basic.volt | 41 +- app/Http/Admin/Views/article/edit_desc.volt | 2 +- app/Http/Admin/Views/article/edit_seo.volt | 21 + app/Http/Admin/Views/article/list.volt | 111 ++--- app/Http/Admin/Views/article/moderate.volt | 6 +- app/Http/Admin/Views/article/report.volt | 8 +- app/Http/Admin/Views/article/search.volt | 64 +-- app/Http/Admin/Views/audit/search.volt | 2 +- app/Http/Admin/Views/category/list.volt | 13 +- .../Admin/Views/chapter/lessons_live.volt | 2 +- .../Admin/Views/chapter/lessons_offline.volt | 2 +- .../Admin/Views/chapter/lessons_read.volt | 2 +- app/Http/Admin/Views/chapter/lessons_vod.volt | 2 +- app/Http/Admin/Views/comment/list.volt | 31 +- app/Http/Admin/Views/comment/moderate.volt | 6 +- app/Http/Admin/Views/comment/report.volt | 8 +- app/Http/Admin/Views/consult/list.volt | 38 +- app/Http/Admin/Views/consult/moderate.volt | 59 ++- app/Http/Admin/Views/consult/search.volt | 57 ++- .../add.volt => course/add_user.volt} | 36 +- app/Http/Admin/Views/course/edit.volt | 35 +- app/Http/Admin/Views/course/edit_basic.volt | 58 ++- app/Http/Admin/Views/course/edit_desc.volt | 2 +- app/Http/Admin/Views/course/edit_offline.volt | 2 +- app/Http/Admin/Views/course/edit_related.volt | 2 +- app/Http/Admin/Views/course/edit_sale.volt | 2 +- app/Http/Admin/Views/course/learnings.volt | 48 +++ app/Http/Admin/Views/course/list.volt | 110 ++--- app/Http/Admin/Views/course/search.volt | 70 ++-- app/Http/Admin/Views/course/search_user.volt | 103 +++++ app/Http/Admin/Views/course/users.volt | 100 +++++ app/Http/Admin/Views/flash_sale/add.volt | 105 ----- app/Http/Admin/Views/flash_sale/edit.volt | 103 ----- app/Http/Admin/Views/flash_sale/search.volt | 46 --- app/Http/Admin/Views/help/list.volt | 17 +- app/Http/Admin/Views/macros/answer.volt | 2 +- app/Http/Admin/Views/macros/article.volt | 9 +- app/Http/Admin/Views/macros/comment.volt | 2 +- app/Http/Admin/Views/macros/consult.volt | 2 +- app/Http/Admin/Views/macros/course.volt | 4 +- app/Http/Admin/Views/macros/course_user.volt | 19 + app/Http/Admin/Views/macros/question.volt | 9 +- app/Http/Admin/Views/macros/review.volt | 2 +- app/Http/Admin/Views/moderation/answers.volt | 25 +- app/Http/Admin/Views/moderation/articles.volt | 33 +- app/Http/Admin/Views/moderation/comments.volt | 19 +- app/Http/Admin/Views/moderation/consults.volt | 28 +- .../Admin/Views/moderation/questions.volt | 31 +- app/Http/Admin/Views/moderation/reviews.volt | 24 +- app/Http/Admin/Views/nav/list.volt | 5 +- app/Http/Admin/Views/order/list.volt | 13 +- app/Http/Admin/Views/order/macro.volt | 10 - app/Http/Admin/Views/order/order_info.volt | 1 - app/Http/Admin/Views/order/search.volt | 50 ++- app/Http/Admin/Views/package/list.volt | 11 +- app/Http/Admin/Views/page/list.volt | 18 +- .../Admin/Views/point_gift/edit_course.volt | 4 +- .../Admin/Views/point_gift/edit_goods.volt | 4 +- app/Http/Admin/Views/point_gift/list.volt | 3 +- app/Http/Admin/Views/question/edit_basic.volt | 12 + app/Http/Admin/Views/question/list.volt | 82 ++-- app/Http/Admin/Views/question/moderate.volt | 6 +- app/Http/Admin/Views/question/report.volt | 8 +- app/Http/Admin/Views/question/search.volt | 47 ++- app/Http/Admin/Views/refund/list.volt | 10 +- app/Http/Admin/Views/refund/search.volt | 38 +- app/Http/Admin/Views/report/answers.volt | 22 +- app/Http/Admin/Views/report/articles.volt | 30 +- app/Http/Admin/Views/report/comments.volt | 16 +- app/Http/Admin/Views/report/questions.volt | 28 +- app/Http/Admin/Views/review/list.volt | 32 +- app/Http/Admin/Views/review/moderate.volt | 24 +- app/Http/Admin/Views/review/search.volt | 57 ++- app/Http/Admin/Views/setting/point.volt | 2 +- app/Http/Admin/Views/setting/sms.volt | 2 +- app/Http/Admin/Views/setting/vip.volt | 2 +- .../Admin/Views/setting/wechat_oa_menu.volt | 2 +- .../Admin/Views/setting/wechat_oa_notice.volt | 2 +- app/Http/Admin/Views/slide/list.volt | 5 +- app/Http/Admin/Views/student/edit.volt | 67 --- app/Http/Admin/Views/student/learning.volt | 50 --- app/Http/Admin/Views/student/list.volt | 135 ------- app/Http/Admin/Views/student/search.volt | 63 --- app/Http/Admin/Views/tag/list.volt | 9 +- app/Http/Admin/Views/tag/search.volt | 34 +- app/Http/Admin/Views/topic/edit.volt | 2 +- app/Http/Admin/Views/topic/edit_basic.volt | 14 +- app/Http/Admin/Views/topic/edit_course.volt | 2 +- app/Http/Admin/Views/topic/list.volt | 17 +- app/Http/Admin/Views/topic/search.volt | 34 +- app/Http/Admin/Views/trade/list.volt | 14 +- app/Http/Admin/Views/trade/search.volt | 40 +- app/Http/Admin/Views/user/edit.volt | 273 +++++++------ app/Http/Admin/Views/user/list.volt | 51 +-- app/Http/Admin/Views/user/search.volt | 50 ++- app/Http/Admin/Views/vip/add.volt | 35 ++ app/Http/Admin/Views/vip/edit.volt | 43 ++ .../Admin/Views/{flash_sale => vip}/list.volt | 48 +-- .../Api/Controllers/ArticleController.php | 20 - .../Api/Controllers/FlashSaleController.php | 48 --- app/Http/Api/Controllers/IndexController.php | 12 - .../Home/Controllers/ArticleController.php | 34 +- app/Http/Home/Controllers/DanmuController.php | 35 -- .../Home/Controllers/FlashSaleController.php | 63 --- .../Home/Controllers/QuestionController.php | 10 +- app/Http/Home/Controllers/UserController.php | 34 -- app/Http/Home/Services/Article.php | 18 +- app/Http/Home/Services/ArticleQuery.php | 71 +++- app/Http/Home/Services/Question.php | 12 +- app/Http/Home/Services/QuestionQuery.php | 71 +++- app/Http/Home/Views/article/edit.volt | 16 +- app/Http/Home/Views/article/list.volt | 22 +- app/Http/Home/Views/article/list_filter.volt | 32 ++ app/Http/Home/Views/article/show.volt | 17 +- app/Http/Home/Views/chapter/live/active.volt | 4 +- app/Http/Home/Views/chapter/read.volt | 11 +- app/Http/Home/Views/chapter/vod.volt | 14 +- app/Http/Home/Views/course/list.volt | 5 +- app/Http/Home/Views/course/list_filter.volt | 22 +- app/Http/Home/Views/course/show.volt | 9 +- app/Http/Home/Views/course/show_order.volt | 2 +- app/Http/Home/Views/course/show_teacher.volt | 27 +- app/Http/Home/Views/flash_sale/index.volt | 157 -------- app/Http/Home/Views/macros/answer.volt | 6 +- app/Http/Home/Views/macros/article.volt | 4 +- app/Http/Home/Views/macros/notification.volt | 2 +- app/Http/Home/Views/macros/order.volt | 10 - app/Http/Home/Views/macros/question.volt | 2 +- app/Http/Home/Views/order/pay.volt | 6 +- app/Http/Home/Views/question/answers.volt | 2 +- app/Http/Home/Views/question/edit.volt | 14 +- app/Http/Home/Views/question/list.volt | 26 +- app/Http/Home/Views/question/list_filter.volt | 31 ++ app/Http/Home/Views/question/show.volt | 9 +- app/Http/Home/Views/user/console/orders.volt | 2 - app/Library/Helper.php | 56 ++- app/Listeners/Trade.php | 9 - app/Listeners/UserDailyCounter.php | 5 - app/Models/Article.php | 27 +- app/Models/ChapterUser.php | 14 + app/Models/Consult.php | 2 +- app/Models/Course.php | 21 +- app/Models/CourseCategory.php | 51 --- app/Models/CourseUser.php | 40 +- app/Models/Danmu.php | 203 ---------- app/Models/FlashSale.php | 195 --------- app/Models/Order.php | 40 -- app/Models/Reason.php | 24 ++ app/Models/Resource.php | 7 - app/Models/Vip.php | 7 + app/Repos/Answer.php | 8 +- app/Repos/Article.php | 36 +- app/Repos/Category.php | 32 +- app/Repos/ChapterUser.php | 8 +- app/Repos/Comment.php | 14 +- app/Repos/Consult.php | 14 +- app/Repos/Course.php | 101 ++--- app/Repos/CourseCategory.php | 53 --- app/Repos/CourseUser.php | 77 +--- app/Repos/Danmu.php | 140 ------- app/Repos/FlashSale.php | 127 ------ app/Repos/Help.php | 4 + app/Repos/Learning.php | 14 +- app/Repos/Notification.php | 6 + app/Repos/Online.php | 6 + app/Repos/Order.php | 16 +- app/Repos/Package.php | 6 + app/Repos/Page.php | 4 + app/Repos/PointGift.php | 10 +- app/Repos/PointHistory.php | 6 + app/Repos/Question.php | 6 + app/Repos/Refund.php | 8 +- app/Repos/Report.php | 10 +- app/Repos/Resource.php | 11 - app/Repos/Review.php | 6 + app/Repos/Slide.php | 6 + app/Repos/Stat.php | 8 +- app/Repos/Tag.php | 6 + app/Repos/Task.php | 18 +- app/Repos/Topic.php | 6 + app/Repos/Trade.php | 8 +- app/Repos/User.php | 12 + app/Repos/Vip.php | 59 ++- app/Services/Category.php | 29 ++ app/Services/Logic/Answer/AnswerInfo.php | 20 +- .../Logic/Article/ArticleDataTrait.php | 14 +- app/Services/Logic/Article/ArticleInfo.php | 25 +- app/Services/Logic/Article/ArticleList.php | 39 +- app/Services/Logic/Article/ArticlePrivate.php | 36 -- app/Services/Logic/Chapter/ChapterInfo.php | 27 +- app/Services/Logic/Chapter/DanmuList.php | 72 ---- app/Services/Logic/ChapterTrait.php | 2 +- app/Services/Logic/Comment/CommentInfo.php | 21 +- app/Services/Logic/Consult/ConsultCreate.php | 75 +--- app/Services/Logic/Consult/ConsultDelete.php | 29 +- app/Services/Logic/Consult/ConsultInfo.php | 38 +- app/Services/Logic/Course/BasicInfo.php | 36 +- app/Services/Logic/Course/CourseInfo.php | 4 +- app/Services/Logic/Course/CourseUserTrait.php | 102 +++++ app/Services/Logic/CourseTrait.php | 17 +- app/Services/Logic/Danmu/DanmuCreate.php | 64 --- app/Services/Logic/Danmu/DanmuInfo.php | 43 -- app/Services/Logic/Deliver/CourseDeliver.php | 19 +- app/Services/Logic/FlashSale/OrderCreate.php | 116 ------ app/Services/Logic/FlashSale/Queue.php | 82 ---- app/Services/Logic/FlashSale/SaleList.php | 161 -------- .../Logic/FlashSale/UserOrderCache.php | 47 --- app/Services/Logic/FlashSaleTrait.php | 29 -- app/Services/Logic/Help/HelpInfo.php | 11 + app/Services/Logic/Order/OrderCreate.php | 27 -- app/Services/Logic/Order/OrderInfo.php | 16 +- .../Logic/Question/QuestionDataTrait.php | 5 + app/Services/Logic/Question/QuestionInfo.php | 34 +- app/Services/Logic/Question/QuestionList.php | 35 +- app/Services/Logic/Refund/RefundInfo.php | 38 +- app/Services/Logic/Review/ReviewCreate.php | 2 +- app/Services/Logic/Review/ReviewInfo.php | 21 +- app/Services/Logic/Trade/TradeInfo.php | 12 +- app/Services/Logic/Url/FullH5Url.php | 5 - app/Services/Logic/User/Console/OrderList.php | 3 - app/Services/Logic/User/CourseList.php | 2 - app/Services/Logic/User/ShallowUserInfo.php | 38 ++ app/Services/Logic/UserTrait.php | 18 - app/Services/Logic/Vip/OptionList.php | 11 +- app/Services/Refund.php | 2 +- app/Services/Storage.php | 8 +- app/Validators/Answer.php | 7 - app/Validators/Article.php | 30 +- app/Validators/ArticleQuery.php | 14 +- app/Validators/Comment.php | 7 - app/Validators/Course.php | 34 +- app/Validators/CourseQuery.php | 24 +- app/Validators/CourseUser.php | 4 +- app/Validators/Danmu.php | 102 ----- app/Validators/FlashSale.php | 203 ---------- app/Validators/Learning.php | 18 +- app/Validators/Question.php | 7 - app/Validators/QuestionQuery.php | 4 +- app/Validators/UserLimit.php | 11 - app/Validators/Vip.php | 23 +- config/errors.php | 21 +- db/migrations/20231108085025.php | 226 +++++++++++ public/static/admin/css/common.css | 35 +- public/static/admin/js/common.js | 31 +- public/static/home/css/common.css | 6 +- public/static/home/js/article.list.js | 12 +- public/static/home/js/article.show.js | 12 - public/static/home/js/chapter.live.player.js | 2 +- public/static/home/js/chapter.read.js | 43 +- public/static/home/js/chapter.vod.player.js | 14 +- public/static/home/js/common.js | 92 +++-- public/static/home/js/flashsale.js | 35 -- public/static/home/js/list.filter.js | 18 + public/static/home/js/question.list.js | 12 +- public/static/home/js/user.console.js | 4 +- scheduler.php | 3 - 299 files changed, 5092 insertions(+), 6398 deletions(-) delete mode 100644 app/Builders/DanmuList.php delete mode 100644 app/Caches/FlashSale.php delete mode 100644 app/Caches/IndexFlashSaleList.php delete mode 100644 app/Caches/MaxFlashSaleId.php delete mode 100644 app/Console/Tasks/CloseFlashSaleOrderTask.php delete mode 100644 app/Http/Admin/Controllers/FlashSaleController.php delete mode 100644 app/Http/Admin/Controllers/StudentController.php create mode 100644 app/Http/Admin/Controllers/VipController.php create mode 100644 app/Http/Admin/Services/CourseLearning.php create mode 100644 app/Http/Admin/Services/CourseUser.php delete mode 100644 app/Http/Admin/Services/FlashSale.php delete mode 100644 app/Http/Admin/Services/Student.php create mode 100644 app/Http/Admin/Services/Vip.php create mode 100644 app/Http/Admin/Views/article/edit_seo.volt rename app/Http/Admin/Views/{student/add.volt => course/add_user.volt} (54%) create mode 100644 app/Http/Admin/Views/course/learnings.volt create mode 100644 app/Http/Admin/Views/course/search_user.volt create mode 100644 app/Http/Admin/Views/course/users.volt delete mode 100644 app/Http/Admin/Views/flash_sale/add.volt delete mode 100644 app/Http/Admin/Views/flash_sale/edit.volt delete mode 100644 app/Http/Admin/Views/flash_sale/search.volt create mode 100644 app/Http/Admin/Views/macros/course_user.volt delete mode 100644 app/Http/Admin/Views/student/edit.volt delete mode 100644 app/Http/Admin/Views/student/learning.volt delete mode 100644 app/Http/Admin/Views/student/list.volt delete mode 100644 app/Http/Admin/Views/student/search.volt create mode 100644 app/Http/Admin/Views/vip/add.volt create mode 100644 app/Http/Admin/Views/vip/edit.volt rename app/Http/Admin/Views/{flash_sale => vip}/list.volt (52%) delete mode 100644 app/Http/Api/Controllers/FlashSaleController.php delete mode 100644 app/Http/Home/Controllers/DanmuController.php delete mode 100644 app/Http/Home/Controllers/FlashSaleController.php create mode 100644 app/Http/Home/Views/article/list_filter.volt delete mode 100644 app/Http/Home/Views/flash_sale/index.volt create mode 100644 app/Http/Home/Views/question/list_filter.volt delete mode 100644 app/Models/CourseCategory.php delete mode 100644 app/Models/Danmu.php delete mode 100644 app/Models/FlashSale.php delete mode 100644 app/Repos/CourseCategory.php delete mode 100644 app/Repos/Danmu.php delete mode 100644 app/Repos/FlashSale.php delete mode 100644 app/Services/Logic/Article/ArticlePrivate.php delete mode 100644 app/Services/Logic/Chapter/DanmuList.php create mode 100644 app/Services/Logic/Course/CourseUserTrait.php delete mode 100644 app/Services/Logic/Danmu/DanmuCreate.php delete mode 100644 app/Services/Logic/Danmu/DanmuInfo.php delete mode 100644 app/Services/Logic/FlashSale/OrderCreate.php delete mode 100644 app/Services/Logic/FlashSale/Queue.php delete mode 100644 app/Services/Logic/FlashSale/SaleList.php delete mode 100644 app/Services/Logic/FlashSale/UserOrderCache.php delete mode 100644 app/Services/Logic/FlashSaleTrait.php create mode 100644 app/Services/Logic/User/ShallowUserInfo.php delete mode 100644 app/Validators/Danmu.php delete mode 100644 app/Validators/FlashSale.php create mode 100644 db/migrations/20231108085025.php delete mode 100644 public/static/home/js/flashsale.js create mode 100644 public/static/home/js/list.filter.js diff --git a/app/Builders/DanmuList.php b/app/Builders/DanmuList.php deleted file mode 100644 index 2ee29569..00000000 --- a/app/Builders/DanmuList.php +++ /dev/null @@ -1,104 +0,0 @@ -getCourses($danmus); - - foreach ($danmus as $key => $danmu) { - $danmus[$key]['course'] = $courses[$danmu['course_id']] ?? new \stdClass(); - } - - return $danmus; - } - - public function handleChapters(array $danmus) - { - $chapters = $this->getChapters($danmus); - - foreach ($danmus as $key => $danmu) { - $danmus[$key]['chapter'] = $chapters[$danmu['chapter_id']] ?? new \stdClass(); - } - - return $danmus; - } - - public function handleUsers(array $danmus) - { - $users = $this->getUsers($danmus); - - foreach ($danmus as $key => $danmu) { - $danmus[$key]['owner'] = $users[$danmu['owner_id']] ?? new \stdClass(); - } - - return $danmus; - } - - public function getCourses(array $danmus) - { - $ids = kg_array_column($danmus, '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(array $danmus) - { - $ids = kg_array_column($danmus, '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(array $danmus) - { - $ids = kg_array_column($danmus, 'owner_id'); - - $userRepo = new UserRepo(); - - $users = $userRepo->findShallowUserByIds($ids); - - $baseUrl = kg_cos_url(); - - $result = []; - - foreach ($users->toArray() as $user) { - $user['avatar'] = $baseUrl . $user['avatar']; - $result[$user['id']] = $user; - } - - return $result; - } - -} diff --git a/app/Builders/QuestionList.php b/app/Builders/QuestionList.php index acd093f3..b4d25292 100644 --- a/app/Builders/QuestionList.php +++ b/app/Builders/QuestionList.php @@ -27,8 +27,8 @@ class QuestionList extends Builder { $categories = $this->getCategories(); - foreach ($questions as $key => $article) { - $questions[$key]['category'] = $categories[$article['category_id']] ?? new \stdClass(); + foreach ($questions as $key => $question) { + $questions[$key]['category'] = $categories[$question['category_id']] ?? new \stdClass(); } return $questions; diff --git a/app/Builders/UserList.php b/app/Builders/UserList.php index 7dbb1f27..fcee87c5 100644 --- a/app/Builders/UserList.php +++ b/app/Builders/UserList.php @@ -8,6 +8,7 @@ namespace App\Builders; use App\Models\User as UserModel; +use App\Repos\Account as AccountRepo; use App\Repos\Role as RoleRepo; class UserList extends Builder @@ -24,6 +25,17 @@ class UserList extends Builder return $users; } + public function handleAccounts(array $users) + { + $accounts = $this->getAccounts($users); + + foreach ($users as $key => $user) { + $users[$key]['account'] = $accounts[$user['id']] ?? new \stdClass(); + } + + return $users; + } + public function handleAdminRoles(array $users) { $roles = $this->getAdminRoles($users); @@ -46,6 +58,26 @@ class UserList extends Builder return $users; } + protected function getAccounts(array $users) + { + $ids = kg_array_column($users, 'id'); + + $accountRepo = new AccountRepo(); + + $accounts = $accountRepo->findByIds($ids); + + $result = []; + + foreach ($accounts as $account) { + $result[$account->id] = [ + 'phone' => $account->phone, + 'email' => $account->email, + ]; + } + + return $result; + } + protected function getAdminRoles(array $users) { $ids = kg_array_column($users, 'admin_role'); diff --git a/app/Caches/FlashSale.php b/app/Caches/FlashSale.php deleted file mode 100644 index d8b89f43..00000000 --- a/app/Caches/FlashSale.php +++ /dev/null @@ -1,36 +0,0 @@ -lifetime; - } - - public function getKey($id = null) - { - return "flash_sale:{$id}"; - } - - public function getContent($id = null) - { - $saleRepo = new FlashSaleRepo(); - - $sale = $saleRepo->findById($id); - - return $sale ?: null; - } - -} diff --git a/app/Caches/IndexFlashSaleList.php b/app/Caches/IndexFlashSaleList.php deleted file mode 100644 index 7fd379b6..00000000 --- a/app/Caches/IndexFlashSaleList.php +++ /dev/null @@ -1,36 +0,0 @@ -handle(); - - return $sales[0]['items'] ?? []; - } - -} diff --git a/app/Caches/MaxFlashSaleId.php b/app/Caches/MaxFlashSaleId.php deleted file mode 100644 index b6a7030c..00000000 --- a/app/Caches/MaxFlashSaleId.php +++ /dev/null @@ -1,34 +0,0 @@ -lifetime; - } - - public function getKey($id = null) - { - return 'max_flash_sale_id'; - } - - public function getContent($id = null) - { - $sale = FlashSaleModel::findFirst(['order' => 'id DESC']); - - return $sale->id ?? 0; - } - -} diff --git a/app/Console/Tasks/CloseFlashSaleOrderTask.php b/app/Console/Tasks/CloseFlashSaleOrderTask.php deleted file mode 100644 index b83afe2b..00000000 --- a/app/Console/Tasks/CloseFlashSaleOrderTask.php +++ /dev/null @@ -1,86 +0,0 @@ -findOrders(); - - echo sprintf('pending orders: %s', $orders->count()) . PHP_EOL; - - if ($orders->count() == 0) return; - - echo '------ start close order task ------' . PHP_EOL; - - foreach ($orders as $order) { - $this->incrFlashSaleStock($order->promotion_id); - $this->pushFlashSaleQueue($order->promotion_id); - $this->deleteUserOrderCache($order->owner_id, $order->promotion_id); - $order->status = OrderModel::STATUS_CLOSED; - $order->update(); - } - - echo '------ end close order task ------' . PHP_EOL; - } - - protected function incrFlashSaleStock($saleId) - { - $flashSaleRepo = new FlashSaleRepo(); - - $flashSale = $flashSaleRepo->findById($saleId); - - $flashSale->stock += 1; - - $flashSale->update(); - } - - protected function pushFlashSaleQueue($saleId) - { - $queue = new FlashSaleQueue(); - - $queue->push($saleId); - } - - protected function deleteUserOrderCache($userId, $saleId) - { - $cache = new UserOrderCache(); - - $cache->delete($userId, $saleId); - } - - /** - * 查找待关闭订单 - * - * @param int $limit - * @return ResultsetInterface|Resultset|OrderModel[] - */ - protected function findOrders($limit = 1000) - { - $status = OrderModel::STATUS_PENDING; - $type = OrderModel::PROMOTION_FLASH_SALE; - $time = time() - 15 * 60; - - return OrderModel::query() - ->where('status = :status:', ['status' => $status]) - ->andWhere('promotion_type = :type:', ['type' => $type]) - ->andWhere('create_time < :time:', ['time' => $time]) - ->limit($limit) - ->execute(); - } - -} diff --git a/app/Console/Tasks/CloseOrderTask.php b/app/Console/Tasks/CloseOrderTask.php index f56c9077..8b17ed81 100644 --- a/app/Console/Tasks/CloseOrderTask.php +++ b/app/Console/Tasks/CloseOrderTask.php @@ -42,11 +42,9 @@ class CloseOrderTask extends Task { $status = OrderModel::STATUS_PENDING; $time = time() - 12 * 3600; - $type = 0; return OrderModel::query() ->where('status = :status:', ['status' => $status]) - ->andWhere('promotion_type = :type:', ['type' => $type]) ->andWhere('create_time < :time:', ['time' => $time]) ->limit($limit) ->execute(); diff --git a/app/Console/Tasks/DeliverTask.php b/app/Console/Tasks/DeliverTask.php index 1e34d458..6fe6c8a3 100644 --- a/app/Console/Tasks/DeliverTask.php +++ b/app/Console/Tasks/DeliverTask.php @@ -172,9 +172,7 @@ class DeliverTask extends Task ]; foreach ($orders as $order) { - $case1 = in_array($order->item_type, $itemTypes); - $case2 = $order->promotion_type == 0; - if ($case1 && $case2) { + if (in_array($order->item_type, $itemTypes)) { $order->status = OrderModel::STATUS_CLOSED; $order->update(); } diff --git a/app/Console/Tasks/RefundTask.php b/app/Console/Tasks/RefundTask.php index 108cc60e..d28dc013 100644 --- a/app/Console/Tasks/RefundTask.php +++ b/app/Console/Tasks/RefundTask.php @@ -168,7 +168,8 @@ class RefundTask extends Task protected function handleCourseOrderRefund(OrderModel $order) { $courseUserRepo = new CourseUserRepo(); - $courseUser = $courseUserRepo->findCourseStudent($order->item_id, $order->owner_id); + + $courseUser = $courseUserRepo->findCourseUser($order->item_id, $order->owner_id); if ($courseUser) { $courseUser->deleted = 1; @@ -191,7 +192,7 @@ class RefundTask extends Task foreach ($itemInfo['courses'] as $course) { - $courseUser = $courseUserRepo->findCourseStudent($course['id'], $order->owner_id); + $courseUser = $courseUserRepo->findCourseUser($course['id'], $order->owner_id); if ($courseUser) { $courseUser->deleted = 1; diff --git a/app/Http/Admin/Controllers/AnswerController.php b/app/Http/Admin/Controllers/AnswerController.php index 0e1a1fec..69cc0846 100644 --- a/app/Http/Admin/Controllers/AnswerController.php +++ b/app/Http/Admin/Controllers/AnswerController.php @@ -219,4 +219,42 @@ class AnswerController extends Controller $this->view->setVar('reports', $reports); } + /** + * @Post("/moderate/batch", name="admin.answer.batch_moderate") + */ + public function batchModerateAction() + { + $answerService = new AnswerService(); + + $answerService->batchModerate(); + + $location = $this->url->get(['for' => 'admin.mod.answers']); + + $content = [ + 'location' => $location, + 'msg' => '批量审核成功', + ]; + + return $this->jsonSuccess($content); + } + + /** + * @Post("/delete/batch", name="admin.answer.batch_delete") + */ + public function batchDeleteAction() + { + $answerService = new AnswerService(); + + $answerService->batchDelete(); + + $location = $this->url->get(['for' => 'admin.answer.list']); + + $content = [ + 'location' => $location, + 'msg' => '批量删除成功', + ]; + + return $this->jsonSuccess($content); + } + } diff --git a/app/Http/Admin/Controllers/ArticleController.php b/app/Http/Admin/Controllers/ArticleController.php index d6d8a7b9..05689bb4 100644 --- a/app/Http/Admin/Controllers/ArticleController.php +++ b/app/Http/Admin/Controllers/ArticleController.php @@ -38,12 +38,12 @@ class ArticleController extends Controller $publishTypes = $articleService->getPublishTypes(); $sourceTypes = $articleService->getSourceTypes(); - $categories = $articleService->getCategories(); + $categoryOptions = $articleService->getCategoryOptions(); $xmTags = $articleService->getXmTags(0); $this->view->setVar('publish_types', $publishTypes); $this->view->setVar('source_types', $sourceTypes); - $this->view->setVar('categories', $categories); + $this->view->setVar('category_options', $categoryOptions); $this->view->setVar('xm_tags', $xmTags); } @@ -80,14 +80,14 @@ class ArticleController extends Controller $publishTypes = $articleService->getPublishTypes(); $sourceTypes = $articleService->getSourceTypes(); - $categories = $articleService->getCategories(); + $categoryOptions = $articleService->getCategoryOptions(); $article = $articleService->getArticle($id); $xmTags = $articleService->getXmTags($id); + $this->view->setVar('article', $article); $this->view->setVar('publish_types', $publishTypes); $this->view->setVar('source_types', $sourceTypes); - $this->view->setVar('categories', $categories); - $this->view->setVar('article', $article); + $this->view->setVar('category_options', $categoryOptions); $this->view->setVar('xm_tags', $xmTags); } @@ -229,4 +229,42 @@ class ArticleController extends Controller $this->view->setVar('article', $article); } + /** + * @Post("/moderate/batch", name="admin.article.batch_moderate") + */ + public function batchModerateAction() + { + $articleService = new ArticleService(); + + $articleService->batchModerate(); + + $location = $this->url->get(['for' => 'admin.mod.articles']); + + $content = [ + 'location' => $location, + 'msg' => '批量审核成功', + ]; + + return $this->jsonSuccess($content); + } + + /** + * @Post("/delete/batch", name="admin.article.batch_delete") + */ + public function batchDeleteAction() + { + $articleService = new ArticleService(); + + $articleService->batchDelete(); + + $location = $this->url->get(['for' => 'admin.mod.articles']); + + $content = [ + 'location' => $location, + 'msg' => '批量删除成功', + ]; + + return $this->jsonSuccess($content); + } + } diff --git a/app/Http/Admin/Controllers/CommentController.php b/app/Http/Admin/Controllers/CommentController.php index ec0ad6b0..a34340aa 100644 --- a/app/Http/Admin/Controllers/CommentController.php +++ b/app/Http/Admin/Controllers/CommentController.php @@ -139,4 +139,42 @@ class CommentController extends Controller $this->view->setVar('reports', $reports); } + /** + * @Post("/moderate/batch", name="admin.comment.batch_moderate") + */ + public function batchModerateAction() + { + $commentService = new CommentService(); + + $commentService->batchModerate(); + + $location = $this->url->get(['for' => 'admin.mod.comments']); + + $content = [ + 'location' => $location, + 'msg' => '批量审核成功', + ]; + + return $this->jsonSuccess($content); + } + + /** + * @Post("/delete/batch", name="admin.comment.batch_delete") + */ + public function batchDeleteAction() + { + $commentService = new CommentService(); + + $commentService->batchDelete(); + + $location = $this->url->get(['for' => 'admin.mod.comments']); + + $content = [ + 'location' => $location, + 'msg' => '批量审核成功', + ]; + + return $this->jsonSuccess($content); + } + } diff --git a/app/Http/Admin/Controllers/ConsultController.php b/app/Http/Admin/Controllers/ConsultController.php index c0cbdb9c..ac3aea38 100644 --- a/app/Http/Admin/Controllers/ConsultController.php +++ b/app/Http/Admin/Controllers/ConsultController.php @@ -23,8 +23,10 @@ class ConsultController extends Controller $consultService = new ConsultService(); $publishTypes = $consultService->getPublishTypes(); + $xmCourses = $consultService->getXmCourses(); $this->view->setVar('publish_types', $publishTypes); + $this->view->setVar('xm_courses', $xmCourses); } /** @@ -135,9 +137,49 @@ class ConsultController extends Controller return $this->jsonSuccess($content); } + $reasons = $consultService->getReasons(); $consult = $consultService->getConsultInfo($id); + $this->view->setVar('reasons', $reasons); $this->view->setVar('consult', $consult); } + /** + * @Post("/moderate/batch", name="admin.consult.batch_moderate") + */ + public function batchModerateAction() + { + $consultService = new ConsultService(); + + $consultService->batchModerate(); + + $location = $this->url->get(['for' => 'admin.mod.consults']); + + $content = [ + 'location' => $location, + 'msg' => '批量审核成功', + ]; + + return $this->jsonSuccess($content); + } + + /** + * @Post("/delete/batch", name="admin.consult.batch_delete") + */ + public function batchDeleteAction() + { + $consultService = new ConsultService(); + + $consultService->batchDelete(); + + $location = $this->url->get(['for' => 'admin.mod.consults']); + + $content = [ + 'location' => $location, + 'msg' => '批量删除成功', + ]; + + return $this->jsonSuccess($content); + } + } diff --git a/app/Http/Admin/Controllers/CourseController.php b/app/Http/Admin/Controllers/CourseController.php index 2121110f..84d7c264 100644 --- a/app/Http/Admin/Controllers/CourseController.php +++ b/app/Http/Admin/Controllers/CourseController.php @@ -8,6 +8,8 @@ namespace App\Http\Admin\Controllers; use App\Http\Admin\Services\Course as CourseService; +use App\Http\Admin\Services\CourseLearning as CourseLearningService; +use App\Http\Admin\Services\CourseUser as CourseUserService; use App\Models\Category as CategoryModel; use Phalcon\Mvc\View; @@ -37,13 +39,13 @@ class CourseController extends Controller { $courseService = new CourseService(); - $xmCategories = $courseService->getXmCategories(0); - $xmTeachers = $courseService->getXmTeachers(0); + $categoryOptions = $courseService->getCategoryOptions(); + $teacherOptions = $courseService->getTeacherOptions(); $modelTypes = $courseService->getModelTypes(); $levelTypes = $courseService->getLevelTypes(); - $this->view->setVar('xm_categories', $xmCategories); - $this->view->setVar('xm_teachers', $xmTeachers); + $this->view->setVar('category_options', $categoryOptions); + $this->view->setVar('teacher_options', $teacherOptions); $this->view->setVar('model_types', $modelTypes); $this->view->setVar('level_types', $levelTypes); } @@ -103,17 +105,21 @@ class CourseController extends Controller $cos = $courseService->getSettings('cos'); $course = $courseService->getCourse($id); - $xmTeachers = $courseService->getXmTeachers($id); - $xmCategories = $courseService->getXmCategories($id); + $xmTags = $courseService->getXmTags($id); $xmCourses = $courseService->getXmCourses($id); + $levelTypes = $courseService->getLevelTypes(); + $categoryOptions = $courseService->getCategoryOptions(); + $teacherOptions = $courseService->getTeacherOptions(); $studyExpiryOptions = $courseService->getStudyExpiryOptions(); $refundExpiryOptions = $courseService->getRefundExpiryOptions(); $this->view->setVar('cos', $cos); $this->view->setVar('course', $course); - $this->view->setVar('xm_teachers', $xmTeachers); - $this->view->setVar('xm_categories', $xmCategories); + $this->view->setVar('xm_tags', $xmTags); $this->view->setVar('xm_courses', $xmCourses); + $this->view->setVar('level_types', $levelTypes); + $this->view->setVar('category_options', $categoryOptions); + $this->view->setVar('teacher_options', $teacherOptions); $this->view->setVar('study_expiry_options', $studyExpiryOptions); $this->view->setVar('refund_expiry_options', $refundExpiryOptions); } @@ -193,4 +199,78 @@ class CourseController extends Controller $this->view->setVar('resources', $resources); } + /** + * @Get("/{id:[0-9]+}/learnings", name="admin.course.learnings") + */ + public function learningsAction($id) + { + $service = new CourseLearningService(); + + $pager = $service->getLearnings($id); + + $this->view->setVar('pager', $pager); + } + + /** + * @Get("/{id:[0-9]+}/users", name="admin.course.users") + */ + public function usersAction($id) + { + $service = new CourseService(); + $course = $service->getCourse($id); + + $service = new CourseUserService(); + $pager = $service->getUsers($id); + + $this->view->setVar('course', $course); + $this->view->setVar('pager', $pager); + } + + /** + * @Get("/{id:[0-9]+}/user/search", name="admin.course.search_user") + */ + public function searchUserAction($id) + { + $service = new CourseService(); + $course = $service->getCourse($id); + + $service = new CourseUserService(); + $sourceTypes = $service->getSourceTypes(); + + $this->view->pick('course/search_user'); + $this->view->setVar('source_types', $sourceTypes); + $this->view->setVar('course', $course); + } + + /** + * @Get("/{id:[0-9]+}/user/add", name="admin.course.add_user") + */ + public function addUserAction($id) + { + $service = new CourseService(); + $course = $service->getCourse($id); + + $this->view->pick('course/add_user'); + $this->view->setVar('course', $course); + } + + /** + * @Post("/{id:[0-9]+}/user/create", name="admin.course.create_user") + */ + public function createUserAction($id) + { + $service = new CourseUserService(); + + $service->create($id); + + $location = $this->url->get(['for' => 'admin.course.users']); + + $content = [ + 'location' => $location, + 'msg' => '添加学员成功', + ]; + + return $this->jsonSuccess($content); + } + } diff --git a/app/Http/Admin/Controllers/FlashSaleController.php b/app/Http/Admin/Controllers/FlashSaleController.php deleted file mode 100644 index 9249d971..00000000 --- a/app/Http/Admin/Controllers/FlashSaleController.php +++ /dev/null @@ -1,153 +0,0 @@ -getFlashSales(); - - $this->view->setVar('pager', $pager); - } - - /** - * @Get("/search", name="admin.flash_sale.search") - */ - public function searchAction() - { - $service = new FlashSaleService(); - - $itemTypes = $service->getItemTypes(); - - $this->view->setVar('item_types', $itemTypes); - } - - /** - * @Get("/add", name="admin.flash_sale.add") - */ - public function addAction() - { - $service = new FlashSaleService(); - - $itemTypes = $service->getItemTypes(); - $xmPackages = $service->getXmPackages(); - $xmCourses = $service->getXmCourses(); - $xmVips = $service->getXmVips(); - - $this->view->setVar('item_types', $itemTypes); - $this->view->setVar('xm_packages', $xmPackages); - $this->view->setVar('xm_courses', $xmCourses); - $this->view->setVar('xm_vips', $xmVips); - } - - /** - * @Get("/{id:[0-9]+}/edit", name="admin.flash_sale.edit") - */ - public function editAction($id) - { - $service = new FlashSaleService(); - - $sale = $service->getFlashSale($id); - $xmSchedules = $service->getXmSchedules($id); - - $this->view->setVar('sale', $sale); - $this->view->setVar('xm_schedules', $xmSchedules); - } - - /** - * @Post("/create", name="admin.flash_sale.create") - */ - public function createAction() - { - $service = new FlashSaleService(); - - $sale = $service->createFlashSale(); - - $location = $this->url->get([ - 'for' => 'admin.flash_sale.edit', - 'id' => $sale->id, - ]); - - $content = [ - 'location' => $location, - 'msg' => '添加商品成功', - ]; - - return $this->jsonSuccess($content); - } - - /** - * @Post("/{id:[0-9]+}/update", name="admin.flash_sale.update") - */ - public function updateAction($id) - { - $service = new FlashSaleService(); - - $service->updateFlashSale($id); - - $location = $this->url->get(['for' => 'admin.flash_sale.list']); - - $content = [ - 'location' => $location, - 'msg' => '更新商品成功', - ]; - - return $this->jsonSuccess($content); - } - - /** - * @Post("/{id:[0-9]+}/delete", name="admin.flash_sale.delete") - */ - public function deleteAction($id) - { - $service = new FlashSaleService(); - - $service->deleteFlashSale($id); - - $location = $this->request->getHTTPReferer(); - - $content = [ - 'location' => $location, - 'msg' => '删除商品成功', - ]; - - return $this->jsonSuccess($content); - } - - /** - * @Post("/{id:[0-9]+}/restore", name="admin.flash_sale.restore") - */ - public function restoreAction($id) - { - $service = new FlashSaleService(); - - $service->restoreFlashSale($id); - - $location = $this->request->getHTTPReferer(); - - $content = [ - 'location' => $location, - 'msg' => '还原商品成功', - ]; - - return $this->jsonSuccess($content); - } - -} diff --git a/app/Http/Admin/Controllers/QuestionController.php b/app/Http/Admin/Controllers/QuestionController.php index 0bc2aebf..7496f57b 100644 --- a/app/Http/Admin/Controllers/QuestionController.php +++ b/app/Http/Admin/Controllers/QuestionController.php @@ -23,7 +23,7 @@ class QuestionController extends Controller { $location = $this->url->get( ['for' => 'admin.category.list'], - ['type' => CategoryModel::TYPE_ARTICLE] + ['type' => CategoryModel::TYPE_QUESTION] ); return $this->response->redirect($location); @@ -37,12 +37,10 @@ class QuestionController extends Controller $questionService = new QuestionService(); $publishTypes = $questionService->getPublishTypes(); - $categories = $questionService->getCategories(); - $xmTags = $questionService->getXmTags(0); + $categoryOptions = $questionService->getCategoryOptions(); + $this->view->setVar('category_options', $categoryOptions); $this->view->setVar('publish_types', $publishTypes); - $this->view->setVar('categories', $categories); - $this->view->setVar('xm_tags', $xmTags); } /** @@ -62,11 +60,7 @@ class QuestionController extends Controller */ public function addAction() { - $questionService = new QuestionService(); - $categories = $questionService->getCategories(); - - $this->view->setVar('categories', $categories); } /** @@ -77,12 +71,12 @@ class QuestionController extends Controller $questionService = new QuestionService(); $publishTypes = $questionService->getPublishTypes(); - $categories = $questionService->getCategories(); + $categoryOptions = $questionService->getCategoryOptions(); $question = $questionService->getQuestion($id); $xmTags = $questionService->getXmTags($id); $this->view->setVar('publish_types', $publishTypes); - $this->view->setVar('categories', $categories); + $this->view->setVar('category_options', $categoryOptions); $this->view->setVar('question', $question); $this->view->setVar('xm_tags', $xmTags); } @@ -225,4 +219,43 @@ class QuestionController extends Controller $this->view->setVar('reports', $reports); } + + /** + * @Post("/moderate/batch", name="admin.question.batch_moderate") + */ + public function batchModerateAction() + { + $questionService = new QuestionService(); + + $questionService->batchModerate(); + + $location = $this->url->get(['for' => 'admin.mod.questions']); + + $content = [ + 'location' => $location, + 'msg' => '批量审核成功', + ]; + + return $this->jsonSuccess($content); + } + + /** + * @Post("/delete/batch", name="admin.question.batch_delete") + */ + public function batchDeleteAction() + { + $questionService = new QuestionService(); + + $questionService->batchDelete(); + + $location = $this->url->get(['for' => 'admin.question.list']); + + $content = [ + 'location' => $location, + 'msg' => '批量删除成功', + ]; + + return $this->jsonSuccess($content); + } + } diff --git a/app/Http/Admin/Controllers/ReviewController.php b/app/Http/Admin/Controllers/ReviewController.php index 1434f9b9..b853ae6b 100644 --- a/app/Http/Admin/Controllers/ReviewController.php +++ b/app/Http/Admin/Controllers/ReviewController.php @@ -23,8 +23,10 @@ class ReviewController extends Controller $reviewService = new ReviewService(); $publishTypes = $reviewService->getPublishTypes(); + $xmCourses = $reviewService->getXmCourses(); $this->view->setVar('publish_types', $publishTypes); + $this->view->setVar('xm_courses', $xmCourses); } /** @@ -137,9 +139,49 @@ class ReviewController extends Controller return $this->jsonSuccess($content); } + $reasons = $reviewService->getReasons(); $review = $reviewService->getReviewInfo($id); + $this->view->setVar('reasons', $reasons); $this->view->setVar('review', $review); } + /** + * @Post("/moderate/batch", name="admin.review.batch_moderate") + */ + public function batchModerateAction() + { + $reviewService = new ReviewService(); + + $reviewService->batchModerate(); + + $location = $this->url->get(['for' => 'admin.mod.reviews']); + + $content = [ + 'location' => $location, + 'msg' => '批量审核成功', + ]; + + return $this->jsonSuccess($content); + } + + /** + * @Post("/delete/batch", name="admin.review.batch_delete") + */ + public function batchDeleteAction() + { + $reviewService = new ReviewService(); + + $reviewService->batchDelete(); + + $location = $this->url->get(['for' => 'admin.mod.reviews']); + + $content = [ + 'location' => $location, + 'msg' => '批量删除成功', + ]; + + return $this->jsonSuccess($content); + } + } diff --git a/app/Http/Admin/Controllers/StudentController.php b/app/Http/Admin/Controllers/StudentController.php deleted file mode 100644 index 324c6943..00000000 --- a/app/Http/Admin/Controllers/StudentController.php +++ /dev/null @@ -1,141 +0,0 @@ -request->getQuery('course_id', 'int', 0); - - $studentService = new StudentService(); - - $sourceTypes = $studentService->getSourceTypes(); - - $xmCourses = $studentService->getXmCourses('all', $courseId); - - $this->view->setVar('source_types', $sourceTypes); - $this->view->setVar('xm_courses', $xmCourses); - } - - /** - * @Get("/list", name="admin.student.list") - */ - public function listAction() - { - $courseId = $this->request->getQuery('course_id', 'int', 0); - - $studentService = new StudentService(); - - $pager = $studentService->getRelations(); - - $course = null; - - if ($courseId > 0) { - $course = $studentService->getCourse($courseId); - } - - $this->view->setVar('pager', $pager); - $this->view->setVar('course', $course); - } - - /** - * @Get("/add", name="admin.student.add") - */ - public function addAction() - { - $courseId = $this->request->getQuery('course_id', 'int', 0); - - $studentService = new StudentService(); - - $xmCourses = $studentService->getXmCourses('all', $courseId); - - $this->view->setVar('xm_courses', $xmCourses); - } - - /** - * @Post("/create", name="admin.student.create") - */ - public function createAction() - { - $studentService = new StudentService(); - - $student = $studentService->createRelation(); - - $location = $this->url->get( - ['for' => 'admin.student.list'], - ['course_id' => $student->course_id] - ); - - $content = [ - 'location' => $location, - 'msg' => '添加学员成功', - ]; - - return $this->jsonSuccess($content); - } - - /** - * @Get("/edit", name="admin.student.edit") - */ - public function editAction() - { - $relationId = $this->request->getQuery('relation_id', 'int'); - - $studentService = new StudentService(); - - $relation = $studentService->getRelation($relationId); - $course = $studentService->getCourse($relation->course_id); - $student = $studentService->getStudent($relation->user_id); - - $this->view->setVar('relation', $relation); - $this->view->setVar('course', $course); - $this->view->setVar('student', $student); - } - - /** - * @Post("/update", name="admin.student.update") - */ - public function updateAction() - { - $studentService = new StudentService(); - - $studentService->updateRelation(); - - $location = $this->url->get(['for' => 'admin.student.list']); - - $content = [ - 'location' => $location, - 'msg' => '更新学员成功', - ]; - - return $this->jsonSuccess($content); - } - - /** - * @Get("/learning", name="admin.student.learning") - */ - public function learningAction() - { - $studentService = new StudentService(); - - $pager = $studentService->getLearnings(); - - $this->view->setVar('pager', $pager); - } - -} diff --git a/app/Http/Admin/Controllers/VipController.php b/app/Http/Admin/Controllers/VipController.php new file mode 100644 index 00000000..047070b6 --- /dev/null +++ b/app/Http/Admin/Controllers/VipController.php @@ -0,0 +1,126 @@ +getVips(); + + $this->view->setVar('pager', $pager); + } + + /** + * @Get("/add", name="admin.vip.add") + */ + public function addAction() + { + + } + + /** + * @Post("/create", name="admin.vip.create") + */ + public function createAction() + { + $vipService = new VipService(); + + $vipService->createVip(); + + $location = $this->url->get(['for' => 'admin.vip.list']); + + $content = [ + 'location' => $location, + 'msg' => '创建套餐成功', + ]; + + return $this->jsonSuccess($content); + } + + /** + * @Get("/{id:[0-9]+}/edit", name="admin.vip.edit") + */ + public function editAction($id) + { + $vipService = new VipService(); + + $vip = $vipService->getVip($id); + + $this->view->setVar('vip', $vip); + } + + /** + * @Post("/{id:[0-9]+}/update", name="admin.vip.update") + */ + public function updateAction($id) + { + $vipService = new VipService(); + + $vipService->updateVip($id); + + $location = $this->url->get(['for' => 'admin.vip.list']); + + $content = [ + 'location' => $location, + 'msg' => '更新套餐成功', + ]; + + return $this->jsonSuccess($content); + } + + /** + * @Post("/{id:[0-9]+}/delete", name="admin.vip.delete") + */ + public function deleteAction($id) + { + $vipService = new VipService(); + + $vipService->deleteVip($id); + + $location = $this->request->getHTTPReferer(); + + $content = [ + 'location' => $location, + 'msg' => '删除套餐成功', + ]; + + return $this->jsonSuccess($content); + } + + /** + * @Post("/{id:[0-9]+}/restore", name="admin.vip.restore") + */ + public function restoreAction($id) + { + $vipService = new VipService(); + + $vipService->restoreVip($id); + + $location = $this->request->getHTTPReferer(); + + $content = [ + 'location' => $location, + 'msg' => '还原套餐成功', + ]; + + return $this->jsonSuccess($content); + } + +} diff --git a/app/Http/Admin/Services/Answer.php b/app/Http/Admin/Services/Answer.php index 1b2f527a..c705c432 100644 --- a/app/Http/Admin/Services/Answer.php +++ b/app/Http/Admin/Services/Answer.php @@ -213,30 +213,15 @@ class Answer extends Service $reason = $this->request->getPost('reason', ['trim', 'string']); $answer = $this->findOrFail($id); - - $validator = new AnswerValidator(); - - if ($type == 'approve') { - $answer->published = AnswerModel::PUBLISH_APPROVED; - } elseif ($type == 'reject') { - $validator->checkRejectReason($reason); - $answer->published = AnswerModel::PUBLISH_REJECTED; - } - - $answer->update(); - $question = $this->findQuestion($answer->question_id); - - $this->recountQuestionAnswers($question); - $owner = $this->findUser($answer->owner_id); - - $this->recountUserAnswers($owner); - $sender = $this->getLoginUser(); if ($type == 'approve') { + $answer->published = AnswerModel::PUBLISH_APPROVED; + $answer->update(); + if ($answer->owner_id != $question->owner_id) { $this->handleAnswerPostPoint($answer); $this->handleQuestionAnsweredNotice($answer); @@ -248,17 +233,17 @@ class Answer extends Service } elseif ($type == 'reject') { - $options = ReasonModel::answerRejectOptions(); - - if (array_key_exists($reason, $options)) { - $reason = $options[$reason]; - } + $answer->published = AnswerModel::PUBLISH_REJECTED; + $answer->update(); $this->handleAnswerRejectedNotice($answer, $sender, $reason); $this->eventsManager->fire('Answer:afterReject', $this, $answer); } + $this->recountQuestionAnswers($question); + $this->recountUserAnswers($owner); + return $answer; } @@ -298,6 +283,78 @@ class Answer extends Service $this->recountUserAnswers($user); } + public function batchModerate() + { + $type = $this->request->getQuery('type', ['trim', 'string']); + $ids = $this->request->getPost('ids', ['trim', 'int']); + + $answerRepo = new AnswerRepo(); + + $answers = $answerRepo->findByIds($ids); + + if ($answers->count() == 0) return; + + $sender = $this->getLoginUser(); + + foreach ($answers as $answer) { + + $question = $this->findQuestion($answer->question_id); + $owner = $this->findUser($answer->owner_id); + + if ($type == 'approve') { + + $answer->published = AnswerModel::PUBLISH_APPROVED; + $answer->update(); + + if ($answer->owner_id != $question->owner_id) { + $this->handleAnswerPostPoint($answer); + $this->handleQuestionAnsweredNotice($answer); + } + + $this->handleAnswerApprovedNotice($answer, $sender); + + } elseif ($type == 'reject') { + + $answer->published = AnswerModel::PUBLISH_REJECTED; + $answer->update(); + + $this->handleAnswerRejectedNotice($answer, $sender, ''); + } + + $this->recountQuestionAnswers($question); + $this->recountUserAnswers($owner); + } + } + + public function batchDelete() + { + $ids = $this->request->getPost('ids', ['trim', 'int']); + + $answerRepo = new AnswerRepo(); + + $answers = $answerRepo->findByIds($ids); + + if ($answers->count() == 0) return; + + $sender = $this->getLoginUser(); + + foreach ($answers as $answer) { + + $answer->deleted = 1; + $answer->update(); + + $this->handleAnswerDeletedNotice($answer, $sender); + + $question = $this->findQuestion($answer->question_id); + + $this->recountQuestionAnswers($question); + + $owner = $this->findUser($answer->owner_id); + + $this->recountUserAnswers($owner); + } + } + protected function findOrFail($id) { $validator = new AnswerValidator(); @@ -390,7 +447,7 @@ class Answer extends Service $notice->handle($answer, $sender); } - protected function handleAnswerRejectedNotice(AnswerModel $answer, UserModel $sender, $reason) + protected function handleAnswerRejectedNotice(AnswerModel $answer, UserModel $sender, $reason = '') { $notice = new AnswerRejectedNotice(); @@ -398,6 +455,11 @@ class Answer extends Service } + protected function handleAnswerDeletedNotice(AnswerModel $answer, UserModel $sender, $reason = '') + { + + } + protected function handleAnswerPostPoint(AnswerModel $answer) { $service = new AnswerPostPointHistory(); diff --git a/app/Http/Admin/Services/Article.php b/app/Http/Admin/Services/Article.php index 42cc02a1..dd445fdb 100644 --- a/app/Http/Admin/Services/Article.php +++ b/app/Http/Admin/Services/Article.php @@ -18,9 +18,9 @@ use App\Models\Reason as ReasonModel; use App\Models\Report as ReportModel; use App\Models\User as UserModel; use App\Repos\Article as ArticleRepo; -use App\Repos\Category as CategoryRepo; use App\Repos\Report as ReportRepo; use App\Repos\User as UserRepo; +use App\Services\Category as CategoryService; use App\Services\Logic\Article\ArticleDataTrait; use App\Services\Logic\Article\ArticleInfo as ArticleInfoService; use App\Services\Logic\Article\XmTagList as XmTagListService; @@ -42,16 +42,11 @@ class Article extends Service return $service->handle($id); } - public function getCategories() + public function getCategoryOptions() { - $categoryRepo = new CategoryRepo(); + $categoryService = new CategoryService(); - return $categoryRepo->findAll([ - 'type' => CategoryModel::TYPE_ARTICLE, - 'level' => 1, - 'published' => 1, - 'deleted' => 0, - ]); + return $categoryService->getCategoryOptions(CategoryModel::TYPE_ARTICLE); } public function getPublishTypes() @@ -161,15 +156,14 @@ class Article extends Service $data = []; - if (isset($post['category_id'])) { - $category = $validator->checkCategory($post['category_id']); - $data['category_id'] = $category->id; - } - if (isset($post['title'])) { $data['title'] = $validator->checkTitle($post['title']); } + if (isset($post['summary'])) { + $data['summary'] = $validator->checkSummary($post['summary']); + } + if (isset($post['keywords'])) { $data['keywords'] = $validator->checkKeywords($post['keywords']); } @@ -186,22 +180,23 @@ class Article extends Service } } - if (isset($post['closed'])) { - $data['closed'] = $validator->checkCloseStatus($post['closed']); - } - - if (isset($post['private'])) { - $data['private'] = $validator->checkPrivateStatus($post['private']); - } - if (isset($post['featured'])) { $data['featured'] = $validator->checkFeatureStatus($post['featured']); } + if (isset($post['closed'])) { + $data['closed'] = $validator->checkCloseStatus($post['closed']); + } + if (isset($post['published'])) { $data['published'] = $validator->checkPublishStatus($post['published']); } + if (isset($post['category_id'])) { + $category = $validator->checkCategory($post['category_id']); + $data['category_id'] = $category->id; + } + if (isset($post['xm_tag_ids'])) { $this->saveTags($article, $post['xm_tag_ids']); } @@ -266,31 +261,12 @@ class Article extends Service $reason = $this->request->getPost('reason', ['trim', 'string']); $article = $this->findOrFail($id); - - $validator = new ArticleValidator(); + $sender = $this->getLoginUser(); if ($type == 'approve') { $article->published = ArticleModel::PUBLISH_APPROVED; - - } elseif ($type == 'reject') { - - $validator->checkRejectReason($reason); - - $article->published = ArticleModel::PUBLISH_REJECTED; - } - - $article->update(); - - $owner = $this->findUser($article->owner_id); - - $this->rebuildArticleCache($article); - $this->rebuildArticleIndex($article); - $this->recountUserArticles($owner); - - $sender = $this->getLoginUser(); - - if ($type == 'approve') { + $article->update(); $this->handleArticlePostPoint($article); $this->handleArticleApprovedNotice($article, $sender); @@ -299,17 +275,20 @@ class Article extends Service } elseif ($type == 'reject') { - $options = ReasonModel::articleRejectOptions(); - - if (array_key_exists($reason, $options)) { - $reason = $options[$reason]; - } + $article->published = ArticleModel::PUBLISH_REJECTED; + $article->update(); $this->handleArticleRejectedNotice($article, $sender, $reason); $this->eventsManager->fire('Article:afterReject', $this, $article); } + $owner = $this->findUser($article->owner_id); + + $this->rebuildArticleCache($article); + $this->rebuildArticleIndex($article); + $this->recountUserArticles($owner); + return $article; } @@ -347,6 +326,72 @@ class Article extends Service $this->recountUserArticles($owner); } + public function batchModerate() + { + $type = $this->request->getQuery('type', ['trim', 'string']); + $ids = $this->request->getPost('ids', ['trim', 'int']); + + $articleRepo = new ArticleRepo(); + + $articles = $articleRepo->findByIds($ids); + + if ($articles->count() == 0) return; + + $sender = $this->getLoginUser(); + + foreach ($articles as $article) { + + if ($type == 'approve') { + + $article->published = ArticleModel::PUBLISH_APPROVED; + $article->update(); + + $this->handleArticlePostPoint($article); + $this->handleArticleApprovedNotice($article, $sender); + + } elseif ($type == 'reject') { + + $article->published = ArticleModel::PUBLISH_REJECTED; + $article->update(); + + $this->handleArticleRejectedNotice($article, $sender); + } + + $owner = $this->findUser($article->owner_id); + + $this->recountUserArticles($owner); + $this->rebuildArticleCache($article); + $this->rebuildArticleIndex($article); + } + } + + public function batchDelete() + { + $ids = $this->request->getPost('ids', ['trim', 'int']); + + $articleRepo = new ArticleRepo(); + + $articles = $articleRepo->findByIds($ids); + + if ($articles->count() == 0) return; + + $sender = $this->getLoginUser(); + + foreach ($articles as $article) { + + $article->published = ArticleModel::PUBLISH_REJECTED; + $article->update(); + + $this->handleArticleDeletedNotice($article, $sender); + + $owner = $this->findUser($article->owner_id); + + $this->recountUserArticles($owner); + $this->rebuildArticleCache($article); + $this->rebuildArticleIndex($article); + } + } + protected function findOrFail($id) { $validator = new ArticleValidator(); @@ -402,13 +447,18 @@ class Article extends Service $notice->handle($article, $sender); } - protected function handleArticleRejectedNotice(ArticleModel $article, UserModel $sender, $reason) + protected function handleArticleRejectedNotice(ArticleModel $article, UserModel $sender, $reason = '') { $notice = new ArticleRejectedNotice(); $notice->handle($article, $sender, $reason); } + protected function handleArticleDeletedNotice(ArticleModel $article, UserModel $sender, $reason = '') + { + + } + protected function handleArticles($pager) { if ($pager->total_items > 0) { diff --git a/app/Http/Admin/Services/AuthNode.php b/app/Http/Admin/Services/AuthNode.php index 35c59e85..319c1f2d 100644 --- a/app/Http/Admin/Services/AuthNode.php +++ b/app/Http/Admin/Services/AuthNode.php @@ -55,6 +55,80 @@ class AuthNode extends Service ], ], ], + [ + 'id' => '1-6', + 'title' => '文章管理', + 'type' => 'menu', + 'children' => [ + [ + 'id' => '1-6-1', + 'title' => '文章列表', + 'type' => 'menu', + 'route' => 'admin.article.list', + ], + [ + 'id' => '1-6-2', + 'title' => '搜索文章', + 'type' => 'menu', + 'route' => 'admin.article.search', + ], + [ + 'id' => '1-6-3', + 'title' => '添加文章', + 'type' => 'menu', + 'route' => 'admin.article.add', + ], + [ + 'id' => '1-6-4', + 'title' => '编辑文章', + 'type' => 'button', + 'route' => 'admin.article.edit', + ], + [ + 'id' => '1-6-5', + 'title' => '删除文章', + 'type' => 'button', + 'route' => 'admin.article.delete', + ], + [ + 'id' => '1-6-6', + 'title' => '文章详情', + 'type' => 'button', + 'route' => 'admin.article.show', + ], + [ + 'id' => '1-6-7', + 'title' => '审核文章', + 'type' => 'button', + 'route' => 'admin.article.moderate', + ], + [ + 'id' => '1-6-8', + 'title' => '审核举报', + 'type' => 'button', + 'route' => 'admin.article.report', + ], + ], + ], + [ + 'id' => '1-7', + 'title' => '问答管理', + 'type' => 'menu', + 'children' => [ + [ + 'id' => '1-7-1', + 'title' => '问题列表', + 'type' => 'menu', + 'route' => 'admin.question.list', + ], + [ + 'id' => '1-7-2', + 'title' => '答案列表', + 'type' => 'menu', + 'route' => 'admin.answer.list', + ], + ], + ], [ 'id' => '1-2', 'title' => '导航管理', @@ -191,80 +265,6 @@ class AuthNode extends Service ], ], ], - [ - 'id' => '1-6', - 'title' => '文章管理', - 'type' => 'menu', - 'children' => [ - [ - 'id' => '1-6-1', - 'title' => '文章列表', - 'type' => 'menu', - 'route' => 'admin.article.list', - ], - [ - 'id' => '1-6-2', - 'title' => '搜索文章', - 'type' => 'menu', - 'route' => 'admin.article.search', - ], - [ - 'id' => '1-6-3', - 'title' => '添加文章', - 'type' => 'menu', - 'route' => 'admin.article.add', - ], - [ - 'id' => '1-6-4', - 'title' => '编辑文章', - 'type' => 'button', - 'route' => 'admin.article.edit', - ], - [ - 'id' => '1-6-5', - 'title' => '删除文章', - 'type' => 'button', - 'route' => 'admin.article.delete', - ], - [ - 'id' => '1-6-6', - 'title' => '文章详情', - 'type' => 'button', - 'route' => 'admin.article.show', - ], - [ - 'id' => '1-6-7', - 'title' => '审核文章', - 'type' => 'button', - 'route' => 'admin.article.moderate', - ], - [ - 'id' => '1-6-8', - 'title' => '审核举报', - 'type' => 'button', - 'route' => 'admin.article.report', - ], - ], - ], - [ - 'id' => '1-7', - 'title' => '问答管理', - 'type' => 'menu', - 'children' => [ - [ - 'id' => '1-7-1', - 'title' => '问题列表', - 'type' => 'menu', - 'route' => 'admin.question.list', - ], - [ - 'id' => '1-7-2', - 'title' => '答案列表', - 'type' => 'menu', - 'route' => 'admin.answer.list', - ], - ], - ], [ 'id' => '1-20', 'title' => '分类管理', @@ -624,7 +624,7 @@ class AuthNode extends Service 'id' => '2-2-1', 'title' => '会员套餐', 'type' => 'menu', - 'route' => 'admin.setting.vip', + 'route' => 'admin.vip.list', ], [ 'id' => '2-2-2', @@ -632,43 +632,6 @@ class AuthNode extends Service 'type' => 'menu', 'route' => 'admin.point_gift.list', ], - [ - 'id' => '2-2-3', - 'title' => '限时秒杀', - 'type' => 'menu', - 'route' => 'admin.flash_sale.list', - ], - ], - ], - [ - 'id' => '2-3', - 'title' => '学员管理', - 'type' => 'menu', - 'children' => [ - [ - 'id' => '2-3-1', - 'title' => '学员列表', - 'type' => 'menu', - 'route' => 'admin.student.list', - ], - [ - 'id' => '2-3-2', - 'title' => '搜索学员', - 'type' => 'menu', - 'route' => 'admin.student.search', - ], - [ - 'id' => '2-3-3', - 'title' => '添加学员', - 'type' => 'menu', - 'route' => 'admin.student.add', - ], - [ - 'id' => '2-3-4', - 'title' => '编辑学员', - 'type' => 'button', - 'route' => 'admin.student.edit', - ], ], ], [ @@ -901,38 +864,32 @@ class AuthNode extends Service ], [ 'id' => '2-21', - 'title' => '限时秒杀', + 'title' => '会员套餐', 'type' => 'button', 'children' => [ [ 'id' => '2-21-1', - 'title' => '商品列表', + 'title' => '套餐列表', 'type' => 'button', - 'route' => 'admin.flash_sale.list', + 'route' => 'admin.vip.list', ], [ 'id' => '2-21-2', - 'title' => '添加商品', + 'title' => '添加套餐', 'type' => 'button', - 'route' => 'admin.flash_sale.add', + 'route' => 'admin.vip.add', ], [ 'id' => '2-21-3', - 'title' => '搜索商品', + 'title' => '编辑套餐', 'type' => 'button', - 'route' => 'admin.flash_sale.search', + 'route' => 'admin.vip.edit', ], [ 'id' => '2-21-4', - 'title' => '编辑商品', + 'title' => '删除套餐', 'type' => 'button', - 'route' => 'admin.flash_sale.edit', - ], - [ - 'id' => '2-21-5', - 'title' => '删除商品', - 'type' => 'button', - 'route' => 'admin.flash_sale.delete', + 'route' => 'admin.vip.delete', ], ], ], diff --git a/app/Http/Admin/Services/Comment.php b/app/Http/Admin/Services/Comment.php index b97f29cd..6f48a764 100644 --- a/app/Http/Admin/Services/Comment.php +++ b/app/Http/Admin/Services/Comment.php @@ -13,6 +13,7 @@ use App\Library\Paginator\Query as PagerQuery; use App\Models\Comment as CommentModel; use App\Models\Reason as ReasonModel; use App\Models\Report as ReportModel; +use App\Models\User as UserModel; use App\Repos\Comment as CommentRepo; use App\Repos\Report as ReportRepo; use App\Repos\User as UserRepo; @@ -126,6 +127,12 @@ class Comment extends Service $this->decrUserCommentCount($owner); + $sender = $this->getLoginUser(); + + $this->handleCommentDeletedNotice($comment, $sender); + + $this->eventsManager->fire('Comment:afterDelete', $this, $comment); + return $comment; } @@ -164,23 +171,14 @@ class Comment extends Service $validator = new CommentValidator(); + $sender = $this->getLoginUser(); + if ($type == 'approve') { $comment->published = CommentModel::PUBLISH_APPROVED; - - } elseif ($type == 'reject') { - - $validator->checkRejectReason($reason); - - $comment->published = CommentModel::PUBLISH_REJECTED; - } - - $comment->update(); - - if ($type == 'approve') { + $comment->update(); $owner = $this->findUser($comment->owner_id); - $item = $validator->checkItem($comment->item_id, $comment->item_type); $this->incrItemCommentCount($item); @@ -197,11 +195,17 @@ class Comment extends Service } $this->handleCommentPostPoint($comment); + $this->handleCommentApprovedNotice($comment, $sender); $this->eventsManager->fire('Comment:afterApprove', $this, $comment); } elseif ($type == 'reject') { + $comment->published = CommentModel::PUBLISH_REJECTED; + $comment->update(); + + $this->handleCommentRejectedNotice($comment, $sender, $reason); + $this->eventsManager->fire('Comment:afterReject', $this, $comment); } @@ -236,6 +240,93 @@ class Comment extends Service $comment->update(); } + public function batchModerate() + { + $type = $this->request->getQuery('type', ['trim', 'string']); + $ids = $this->request->getPost('ids', ['trim', 'int']); + + $commentRepo = new CommentRepo(); + + $comments = $commentRepo->findByIds($ids); + + if ($comments->count() == 0) return; + + $validator = new CommentValidator(); + + $sender = $this->getLoginUser(); + + foreach ($comments as $comment) { + + if ($type == 'approve') { + + $owner = $this->findUser($comment->owner_id); + $item = $validator->checkItem($comment->item_id, $comment->item_type); + + $this->incrItemCommentCount($item); + $this->incrUserCommentCount($owner); + + $comment->published = CommentModel::PUBLISH_APPROVED; + $comment->update(); + + if ($comment->parent_id == 0) { + $this->handleItemCommentedNotice($item, $comment); + } + + if ($comment->parent_id > 0) { + $parent = $validator->checkParent($comment->parent_id); + $this->incrCommentReplyCount($parent); + $this->handleCommentRepliedNotice($comment); + } + + $this->handleCommentPostPoint($comment); + $this->handleCommentApprovedNotice($comment, $sender); + + } elseif ($type == 'reject') { + + $comment->published = CommentModel::PUBLISH_REJECTED; + $comment->update(); + + $this->handleCommentRejectedNotice($comment, $sender); + } + } + } + + public function batchDelete() + { + $ids = $this->request->getPost('ids', ['trim', 'int']); + + $commentRepo = new CommentRepo(); + + $comments = $commentRepo->findByIds($ids); + + if ($comments->count() == 0) return; + + $validator = new CommentValidator(); + + $sender = $this->getLoginUser(); + + foreach ($comments as $comment) { + + $comment->deleted = 1; + $comment->update(); + + if ($comment->parent_id > 0) { + $parent = $validator->checkParent($comment->parent_id); + $this->decrCommentReplyCount($parent); + } + + $this->handleCommentDeletedNotice($comment, $sender); + + $item = $validator->checkItem($comment->item_id, $comment->item_type); + + $this->decrItemCommentCount($item); + + $owner = $this->findUser($comment->owner_id); + + $this->decrUserCommentCount($owner); + } + } + protected function findOrFail($id) { $validator = new CommentValidator(); @@ -250,6 +341,21 @@ class Comment extends Service return $userRepo->findById($id); } + protected function handleCommentApprovedNotice(CommentModel $comment, UserModel $sender) + { + + } + + protected function handleCommentRejectedNotice(CommentModel $comment, UserModel $sender, $reason = '') + { + + } + + protected function handleCommentDeletedNotice(CommentModel $comment, UserModel $sender, $reason = '') + { + + } + protected function handleComments($pager) { if ($pager->total_items > 0) { diff --git a/app/Http/Admin/Services/Consult.php b/app/Http/Admin/Services/Consult.php index 4934ff69..44ae915c 100644 --- a/app/Http/Admin/Services/Consult.php +++ b/app/Http/Admin/Services/Consult.php @@ -9,9 +9,13 @@ namespace App\Http\Admin\Services; use App\Builders\ConsultList as ConsultListBuilder; use App\Library\Paginator\Query as PagerQuery; +use App\Library\Validators\Common as CommonValidator; use App\Models\Chapter as ChapterModel; use App\Models\Consult as ConsultModel; use App\Models\Course as CourseModel; +use App\Models\Reason as ReasonModel; +use App\Models\User as UserModel; +use App\Repos\Account as AccountRepo; use App\Repos\Chapter as ChapterRepo; use App\Repos\Consult as ConsultRepo; use App\Repos\Course as CourseRepo; @@ -27,6 +31,34 @@ class Consult extends Service return ConsultModel::publishTypes(); } + public function getReasons() + { + return ReasonModel::consultRejectOptions(); + } + + public function getXmCourses() + { + $courseRepo = new CourseRepo(); + + $items = $courseRepo->findAll([ + 'published' => 1, + 'deleted' => 0, + ]); + + if ($items->count() == 0) return []; + + $result = []; + + foreach ($items as $item) { + $result[] = [ + 'name' => sprintf('%s - %s(¥%0.2f)', $item->id, $item->title, $item->market_price), + 'value' => $item->id, + ]; + } + + return $result; + } + public function getConsults() { $pagerQuery = new PagerQuery(); @@ -35,6 +67,21 @@ class Consult extends Service $params['deleted'] = $params['deleted'] ?? 0; + $accountRepo = new AccountRepo(); + + /** + * 兼容用户编号|手机号码|邮箱地址查询 + */ + if (!empty($params['owner_id'])) { + if (CommonValidator::phone($params['owner_id'])) { + $account = $accountRepo->findByPhone($params['owner_id']); + $params['owner_id'] = $account ? $account->id : -1000; + } elseif (CommonValidator::email($params['owner_id'])) { + $account = $accountRepo->findByEmail($params['owner_id']); + $params['owner_id'] = $account ? $account->id : -1000; + } + } + $sort = $pagerQuery->getSort(); $page = $pagerQuery->getPage(); $limit = $pagerQuery->getLimit(); @@ -95,7 +142,6 @@ class Consult extends Service if (isset($post['published'])) { $data['published'] = $validator->checkPublishStatus($post['published']); - $this->handleItemConsults($consult); } $consult->update($data); @@ -104,6 +150,10 @@ class Consult extends Service $this->handleReplyNotice($consult); } + $this->recountItemConsults($consult); + + $this->eventsManager->fire('Consult:afterUpdate', $this, $consult); + return $consult; } @@ -115,7 +165,13 @@ class Consult extends Service $consult->update(); - $this->handleItemConsults($consult); + $this->recountItemConsults($consult); + + $sender = $this->getLoginUser(); + + $this->handleConsultDeletedNotice($consult, $sender); + + $this->eventsManager->fire('Consult:afterDelete', $this, $consult); } public function restoreConsult($id) @@ -126,52 +182,97 @@ class Consult extends Service $consult->update(); - $this->handleItemConsults($consult); + $this->recountItemConsults($consult); + + $this->eventsManager->fire('Consult:afterRestore', $this, $consult); } public function moderate($id) { $type = $this->request->getPost('type', ['trim', 'string']); + $reason = $this->request->getPost('reason', ['trim', 'string']); $consult = $this->findOrFail($id); + $sender = $this->getLoginUser(); if ($type == 'approve') { + $consult->published = ConsultModel::PUBLISH_APPROVED; - } elseif ($type == 'reject') { - $consult->published = ConsultModel::PUBLISH_REJECTED; - } + $consult->update(); - $consult->update(); + $this->handleConsultApprovedNotice($consult, $sender); - $this->handleItemConsults($consult); - - if ($type == 'approve') { $this->eventsManager->fire('Consult:afterApprove', $this, $consult); + } elseif ($type == 'reject') { + + $consult->published = ConsultModel::PUBLISH_REJECTED; + $consult->update(); + + $this->handleConsultRejectedNotice($consult, $sender, $reason); + $this->eventsManager->fire('Consult:afterReject', $this, $consult); } + $this->recountItemConsults($consult); + return $consult; } - protected function handleItemConsults(ConsultModel $consult) + public function batchModerate() { - if ($consult->course_id > 0) { - $course = $this->findCourse($consult->course_id); - $this->recountCourseConsults($course); - } + $type = $this->request->getQuery('type', ['trim', 'string']); + $ids = $this->request->getPost('ids', ['trim', 'int']); - if ($consult->chapter_id > 0) { - $chapter = $this->findChapter($consult->chapter_id); - $this->recountChapterConsults($chapter); + $consultRepo = new ConsultRepo(); + + $consults = $consultRepo->findByIds($ids); + + if ($consults->count() == 0) return; + + $sender = $this->getLoginUser(); + + foreach ($consults as $consult) { + + if ($type == 'approve') { + + $consult->published = ConsultModel::PUBLISH_APPROVED; + $consult->update(); + + $this->handleConsultApprovedNotice($consult, $sender); + + } elseif ($type == 'reject') { + + $consult->published = ConsultModel::PUBLISH_REJECTED; + $consult->update(); + + $this->handleConsultRejectedNotice($consult, $sender); + } + + $this->recountItemConsults($consult); } } - protected function handleReplyNotice(ConsultModel $consult) + public function batchDelete() { - $notice = new ConsultReplyNotice(); + $ids = $this->request->getPost('ids', ['trim', 'int']); - $notice->createTask($consult); + $consultRepo = new ConsultRepo(); + + $consults = $consultRepo->findByIds($ids); + + if ($consults->count() == 0) return; + + $sender = $this->getLoginUser(); + + foreach ($consults as $consult) { + + $consult->deleted = 1; + $consult->update(); + + $this->handleConsultDeletedNotice($consult, $sender); + $this->recountItemConsults($consult); + } } protected function findOrFail($id) @@ -195,6 +296,41 @@ class Consult extends Service return $chapterRepo->findById($id); } + protected function handleReplyNotice(ConsultModel $consult) + { + $notice = new ConsultReplyNotice(); + + $notice->createTask($consult); + } + + protected function handleConsultApprovedNotice(ConsultModel $review, UserModel $sender) + { + + } + + protected function handleConsultRejectedNotice(ConsultModel $review, UserModel $sender, $reason = '') + { + + } + + protected function handleConsultDeletedNotice(ConsultModel $review, UserModel $sender, $reason = '') + { + + } + + protected function recountItemConsults(ConsultModel $consult) + { + if ($consult->course_id > 0) { + $course = $this->findCourse($consult->course_id); + $this->recountCourseConsults($course); + } + + if ($consult->chapter_id > 0) { + $chapter = $this->findChapter($consult->chapter_id); + $this->recountChapterConsults($chapter); + } + } + protected function recountCourseConsults(CourseModel $course) { $courseRepo = new CourseRepo(); diff --git a/app/Http/Admin/Services/Course.php b/app/Http/Admin/Services/Course.php index 7e98d612..1d4ade92 100644 --- a/app/Http/Admin/Services/Course.php +++ b/app/Http/Admin/Services/Course.php @@ -10,22 +10,20 @@ namespace App\Http\Admin\Services; use App\Builders\CourseList as CourseListBuilder; use App\Builders\ResourceList as ResourceListBuilder; use App\Caches\Course as CourseCache; -use App\Caches\CourseCategoryList as CourseCategoryListCache; use App\Caches\CourseRelatedList as CourseRelatedListCache; -use App\Caches\CourseTeacherList as CourseTeacherListCache; 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\Repos\Category as CategoryRepo; +use App\Models\CourseTag as CourseTagModel; use App\Repos\Chapter as ChapterRepo; use App\Repos\Course as CourseRepo; -use App\Repos\CourseCategory as CourseCategoryRepo; use App\Repos\CourseRelated as CourseRelatedRepo; -use App\Repos\CourseUser as CourseUserRepo; +use App\Repos\CourseTag as CourseTagRepo; +use App\Repos\Tag as TagRepo; use App\Repos\User as UserRepo; +use App\Services\Category as CategoryService; +use App\Services\Logic\Course\XmTagList as XmTagListService; use App\Services\Sync\CourseIndex as CourseIndexSync; use App\Validators\Course as CourseValidator; use App\Validators\CourseOffline as CourseOfflineValidator; @@ -39,12 +37,8 @@ class Course extends Service $params = $pagerQuery->getParams(); - if (!empty($params['xm_category_ids'])) { - $params['category_id'] = explode(',', $params['xm_category_ids']); - } - - if (!empty($params['xm_teacher_ids'])) { - $params['teacher_id'] = explode(',', $params['xm_teacher_ids']); + if (!empty($params['xm_tag_ids'])) { + $params['tag_id'] = explode(',', $params['xm_tag_ids']); } $params['deleted'] = $params['deleted'] ?? 0; @@ -155,10 +149,6 @@ class Course extends Service $data['refund_expiry'] = $validator->checkRefundExpiry($post['refund_expiry']); } - if (isset($post['origin_price'])) { - $data['origin_price'] = $validator->checkOriginPrice($post['origin_price']); - } - if (isset($post['market_price'])) { $data['market_price'] = $validator->checkMarketPrice($post['market_price']); } @@ -173,17 +163,20 @@ class Course extends Service if (isset($post['published'])) { $data['published'] = $validator->checkPublishStatus($post['published']); - if ($post['published'] == 1) { - $validator->checkPublishAbility($course); - } } - if (isset($post['xm_category_ids'])) { - $this->saveCategories($course, $post['xm_category_ids']); + if (isset($post['category_id'])) { + $category = $validator->checkCategory($post['category_id']); + $data['category_id'] = $category->id; } - if (isset($post['xm_teacher_ids'])) { - $this->saveTeachers($course, $post['xm_teacher_ids']); + if (isset($post['teacher_id'])) { + $teacher = $validator->checkTeacher($post['teacher_id']); + $data['teacher_id'] = $teacher->id; + } + + if (isset($post['xm_tag_ids'])) { + $this->saveTags($course, $post['xm_tag_ids']); } if (isset($post['xm_course_ids'])) { @@ -258,6 +251,33 @@ class Course extends Service return CourseModel::levelTypes(); } + public function getTeacherOptions() + { + $userRepo = new UserRepo(); + + $teachers = $userRepo->findTeachers(); + + if ($teachers->count() == 0) return []; + + $options = []; + + foreach ($teachers as $teacher) { + $options[] = [ + 'id' => $teacher->id, + 'name' => $teacher->name, + ]; + } + + return $options; + } + + public function getCategoryOptions() + { + $categoryService = new CategoryService(); + + return $categoryService->getCategoryOptions(CategoryModel::TYPE_COURSE); + } + public function getStudyExpiryOptions() { return CourseModel::studyExpiryOptions(); @@ -268,92 +288,11 @@ class Course extends Service return CourseModel::refundExpiryOptions(); } - public function getXmCategories($id) + public function getXmTags($id) { - $categoryRepo = new CategoryRepo(); + $service = new XmTagListService(); - $allCategories = $categoryRepo->findAll([ - 'type' => CategoryModel::TYPE_COURSE, - 'published' => 1, - 'deleted' => 0, - ]); - - if ($allCategories->count() == 0) return []; - - $courseCategoryIds = []; - - if ($id > 0) { - $courseRepo = new CourseRepo(); - $courseCategories = $courseRepo->findCategories($id); - if ($courseCategories->count() > 0) { - foreach ($courseCategories as $category) { - $courseCategoryIds[] = $category->id; - } - } - } - - $list = []; - - /** - * 没有二级分类的不显示 - */ - foreach ($allCategories as $category) { - if ($category->level == 1 && $category->child_count > 0) { - $list[$category->id] = [ - 'name' => $category->name, - 'value' => $category->id, - 'children' => [], - ]; - } - } - - foreach ($allCategories as $category) { - $selected = in_array($category->id, $courseCategoryIds); - $parentId = $category->parent_id; - if ($category->level == 2) { - $list[$parentId]['children'][] = [ - 'name' => $category->name, - 'value' => $category->id, - 'selected' => $selected, - ]; - } - } - - return array_values($list); - } - - public function getXmTeachers($id) - { - $userRepo = new UserRepo(); - - $allTeachers = $userRepo->findTeachers(); - - if ($allTeachers->count() == 0) return []; - - $courseTeacherIds = []; - - if ($id > 0) { - $courseRepo = new CourseRepo(); - $courseTeachers = $courseRepo->findTeachers($id); - if ($courseTeachers->count() > 0) { - foreach ($courseTeachers as $teacher) { - $courseTeacherIds[] = $teacher->id; - } - } - } - - $list = []; - - foreach ($allTeachers as $teacher) { - $selected = in_array($teacher->id, $courseTeacherIds); - $list[] = [ - 'name' => $teacher->name, - 'value' => $teacher->id, - 'selected' => $selected, - ]; - } - - return $list; + return $service->handle($id); } public function getXmCourses($id) @@ -409,7 +348,7 @@ class Course extends Service { $courseRepo = new CourseRepo(); - $resources = $courseRepo->findResources($id); + $resources = $courseRepo->findResources($id); if ($resources->count() == 0) return []; @@ -429,107 +368,65 @@ class Course extends Service return $validator->checkCourse($id); } - protected function saveTeachers(CourseModel $course, $teacherIds) + protected function saveTags(CourseModel $course, $tagIds) { - $courseRepo = new CourseRepo(); + /** + * 修改数据后,afterFetch设置的属性会失效,重新执行 + */ + $course->afterFetch(); - $courseTeachers = $courseRepo->findTeachers($course->id); + if (is_string($tagIds) && strlen($tagIds) > 0) { + $tagIds = explode(',', $tagIds); + } - $originTeacherIds = []; + $originTagIds = []; - if ($courseTeachers->count() > 0) { - foreach ($courseTeachers as $teacher) { - $originTeacherIds[] = $teacher->id; + if ($course->tags) { + $originTagIds = kg_array_column($course->tags, 'id'); + } + + $newTagIds = $tagIds ?: []; + $addedTagIds = array_diff($newTagIds, $originTagIds); + + if ($addedTagIds) { + foreach ($addedTagIds as $tagId) { + $courseTag = new CourseTagModel(); + $courseTag->course_id = $course->id; + $courseTag->tag_id = $tagId; + $courseTag->create(); + $this->recountTagCourses($tagId); } } - $newTeacherIds = $teacherIds ? explode(',', $teacherIds) : []; - $addedTeacherIds = array_diff($newTeacherIds, $originTeacherIds); + $deletedTagIds = array_diff($originTagIds, $newTagIds); - if ($addedTeacherIds) { - foreach ($addedTeacherIds as $teacherId) { - $courseTeacher = new CourseUserModel(); - $courseTeacher->course_id = $course->id; - $courseTeacher->user_id = $teacherId; - $courseTeacher->role_type = CourseUserModel::ROLE_TEACHER; - $courseTeacher->source_type = CourseUserModel::SOURCE_IMPORT; - $courseTeacher->expiry_time = strtotime('+30 years'); - $courseTeacher->create(); - } - } - - $deletedTeacherIds = array_diff($originTeacherIds, $newTeacherIds); - - if ($deletedTeacherIds) { - $courseUserRepo = new CourseUserRepo(); - foreach ($deletedTeacherIds as $teacherId) { - $courseTeacher = $courseUserRepo->findCourseTeacher($course->id, $teacherId); - if ($courseTeacher) { - $courseTeacher->delete(); + if ($deletedTagIds) { + $courseTagRepo = new CourseTagRepo(); + foreach ($deletedTagIds as $tagId) { + $courseTag = $courseTagRepo->findCourseTag($course->id, $tagId); + if ($courseTag) { + $courseTag->delete(); + $this->recountTagCourses($tagId); } } } - $teacherId = $newTeacherIds[0] ?? 0; + $courseTags = []; - if ($teacherId) { - $course->teacher_id = $teacherId; - $course->update(); - } - - $cache = new CourseTeacherListCache(); - - $cache->rebuild($course->id); - } - - protected function saveCategories(CourseModel $course, $categoryIds) - { - $courseRepo = new CourseRepo(); - - $courseCategories = $courseRepo->findCategories($course->id); - - $originCategoryIds = []; - - if ($courseCategories->count() > 0) { - foreach ($courseCategories as $category) { - $originCategoryIds[] = $category->id; - } - } - - $newCategoryIds = $categoryIds ? explode(',', $categoryIds) : []; - $addedCategoryIds = array_diff($newCategoryIds, $originCategoryIds); - - if ($addedCategoryIds) { - foreach ($addedCategoryIds as $categoryId) { - $courseCategory = new CourseCategoryModel(); - $courseCategory->course_id = $course->id; - $courseCategory->category_id = $categoryId; - $courseCategory->create(); - } - } - - $deletedCategoryIds = array_diff($originCategoryIds, $newCategoryIds); - - if ($deletedCategoryIds) { - $courseCategoryRepo = new CourseCategoryRepo(); - foreach ($deletedCategoryIds as $categoryId) { - $courseCategory = $courseCategoryRepo->findCourseCategory($course->id, $categoryId); - if ($courseCategory) { - $courseCategory->delete(); + if ($newTagIds) { + $tagRepo = new TagRepo(); + $tags = $tagRepo->findByIds($newTagIds); + if ($tags->count() > 0) { + foreach ($tags as $tag) { + $courseTags[] = ['id' => $tag->id, 'name' => $tag->name]; + $this->recountTagCourses($tag->id); } } } - $categoryId = $newCategoryIds[0] ?? 0; + $course->tags = $courseTags; - if ($categoryId) { - $course->category_id = $categoryId; - $course->update(); - } - - $cache = new CourseCategoryListCache(); - - $cache->rebuild($course->id); + $course->update(); } protected function saveRelatedCourses(CourseModel $course, $courseIds) @@ -609,6 +506,21 @@ class Course extends Service $sync->addItem($course->id); } + protected function recountTagCourses($tagId) + { + $tagRepo = new TagRepo(); + + $tag = $tagRepo->findById($tagId); + + if (!$tag) return; + + $courseCount = $tagRepo->countCourses($tagId); + + $tag->course_count = $courseCount; + + $tag->update(); + } + protected function handleCourses($pager) { if ($pager->total_items > 0) { diff --git a/app/Http/Admin/Services/CourseLearning.php b/app/Http/Admin/Services/CourseLearning.php new file mode 100644 index 00000000..02113df1 --- /dev/null +++ b/app/Http/Admin/Services/CourseLearning.php @@ -0,0 +1,64 @@ +findCourseOrFail($id); + + $pagerQuery = new PagerQuery(); + + $params = $pagerQuery->getParams(); + + $params['course_id'] = $course->id; + + $sort = $pagerQuery->getSort(); + $page = $pagerQuery->getPage(); + $limit = $pagerQuery->getLimit(); + + $learningRepo = new LearningRepo(); + + $pager = $learningRepo->paginate($params, $sort, $page, $limit); + + return $this->handleLearnings($pager); + } + + protected function findCourseOrFail($id) + { + $validator = new CourseValidator(); + + return $validator->checkCourse($id); + } + + protected function handleLearnings($pager) + { + if ($pager->total_items > 0) { + + $builder = new LearningListBuilder(); + + $pipeA = $pager->items->toArray(); + $pipeB = $builder->handleCourses($pipeA); + $pipeC = $builder->handleChapters($pipeB); + $pipeD = $builder->handleUsers($pipeC); + $pipeE = $builder->objects($pipeD); + + $pager->items = $pipeE; + } + + return $pager; + } + +} diff --git a/app/Http/Admin/Services/CourseUser.php b/app/Http/Admin/Services/CourseUser.php new file mode 100644 index 00000000..a3963d47 --- /dev/null +++ b/app/Http/Admin/Services/CourseUser.php @@ -0,0 +1,101 @@ +request->getPost(); + + $validator = new CourseUserValidator(); + + $course = $validator->checkCourse($id); + + $user = $validator->checkUser($post['user_id']); + + $expiryTime = $validator->checkExpiryTime($post['expiry_time']); + + $sourceType = CourseUserModel::SOURCE_MANUAL; + + return $this->assignUserCourse($course, $user, $expiryTime, $sourceType); + } + + public function getUsers($id) + { + $validator = new CourseUserValidator(); + + $course = $validator->checkCourse($id); + + $pagerQuery = new PagerQuery(); + + $params = $pagerQuery->getParams(); + + $params['course_id'] = $course->id; + $params['deleted'] = 0; + + $accountRepo = new AccountRepo(); + + /** + * 兼容用户编号|手机号码|邮箱地址查询 + */ + if (!empty($params['user_id'])) { + if (CommonValidator::phone($params['user_id'])) { + $account = $accountRepo->findByPhone($params['user_id']); + $params['user_id'] = $account ? $account->id : -1000; + } elseif (CommonValidator::email($params['user_id'])) { + $account = $accountRepo->findByEmail($params['user_id']); + $params['user_id'] = $account ? $account->id : -1000; + } + } + + $sort = $pagerQuery->getSort(); + $page = $pagerQuery->getPage(); + $limit = $pagerQuery->getLimit(); + + $repo = new CourseUserRepo(); + + $pager = $repo->paginate($params, $sort, $page, $limit); + + return $this->handleUsers($pager); + } + + protected function handleUsers($pager) + { + if ($pager->total_items > 0) { + + $builder = new CourseUserListBuilder(); + + $items = $pager->items->toArray(); + $pipeA = $builder->handleUsers($items); + $pipeB = $builder->objects($pipeA); + + $pager->items = $pipeB; + } + + return $pager; + } + +} diff --git a/app/Http/Admin/Services/FlashSale.php b/app/Http/Admin/Services/FlashSale.php deleted file mode 100644 index b903a6c6..00000000 --- a/app/Http/Admin/Services/FlashSale.php +++ /dev/null @@ -1,380 +0,0 @@ -findOrFail($id); - - $result = []; - - foreach ($schedules as $schedule) { - $result[] = [ - 'name' => $schedule['name'], - 'value' => $schedule['hour'], - 'selected' => in_array($schedule['hour'], $sale->schedules), - ]; - } - - return $result; - } - - public function getXmCourses() - { - $courseRepo = new CourseRepo(); - - $items = $courseRepo->findAll([ - 'free' => 0, - 'published' => 1, - 'deleted' => 0, - ]); - - if ($items->count() == 0) return []; - - $result = []; - - foreach ($items as $item) { - $result[] = [ - 'name' => sprintf('%s(¥%0.2f)', $item->title, $item->market_price), - 'value' => $item->id, - ]; - } - - return $result; - } - - public function getXmPackages() - { - $packageRepo = new PackageRepo(); - - $items = $packageRepo->findAll([ - 'published' => 1, - 'deleted' => 0, - ]); - - if ($items->count() == 0) return []; - - $result = []; - - foreach ($items as $item) { - $result[] = [ - 'name' => sprintf('%s(¥%0.2f)', $item->title, $item->market_price), - 'value' => $item->id, - ]; - } - - return $result; - } - - public function getXmVips() - { - $vipRepo = new VipRepo(); - - $items = $vipRepo->findAll(); - - if ($items->count() == 0) return []; - - $result = []; - - foreach ($items as $item) { - $result[] = [ - 'name' => sprintf('%s(¥%0.2f)', $item->title, $item->price), - 'value' => $item->id, - ]; - } - - return $result; - } - - public function getFlashSales() - { - $pagerQuery = new PagerQuery(); - - $params = $pagerQuery->getParams(); - - $params['deleted'] = $params['deleted'] ?? 0; - - $sort = $pagerQuery->getSort(); - $page = $pagerQuery->getPage(); - $limit = $pagerQuery->getLimit(); - - $saleRepo = new FlashSaleRepo(); - - return $saleRepo->paginate($params, $sort, $page, $limit); - } - - public function getFlashSale($id) - { - return $this->findOrFail($id); - } - - public function createFlashSale() - { - $post = $this->request->getPost(); - - $validator = new FlashSaleValidator(); - - $post['item_type'] = $validator->checkItemType($post['item_type']); - - $sale = new FlashSaleModel(); - - switch ($post['item_type']) { - case FlashSaleModel::ITEM_COURSE: - $sale = $this->createCourseFlashSale($post); - break; - case FlashSaleModel::ITEM_PACKAGE: - $sale = $this->createPackageFlashSale($post); - break; - case FlashSaleModel::ITEM_VIP: - $sale = $this->createVipFlashSale($post); - break; - } - - $this->rebuildFlashSaleCache($sale); - - return $sale; - } - - public function updateFlashSale($id) - { - $sale = $this->findOrFail($id); - - $post = $this->request->getPost(); - - $originInfo = $this->getOriginInfo($sale->item_id, $sale->item_type); - - $validator = new FlashSaleValidator(); - - $data = []; - - $data['item_info'] = $originInfo['item_info']; - - 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($data['start_time'], $data['end_time']); - } - - if (isset($post['xm_schedules'])) { - $data['schedules'] = $validator->checkSchedules($post['xm_schedules']); - } - - if (isset($post['stock'])) { - $data['stock'] = $validator->checkStock($post['stock']); - } - - if (isset($post['price'])) { - $data['price'] = $validator->checkPrice($originInfo['item_price'], $post['price']); - } - - if (isset($post['published'])) { - $data['published'] = $validator->checkPublishStatus($post['published']); - } - - $sale->update($data); - - $this->initFlashSaleQueue($sale); - $this->rebuildFlashSaleCache($sale); - - return $sale; - } - - public function deleteFlashSale($id) - { - $sale = $this->findOrFail($id); - - $sale->deleted = 1; - - $sale->update(); - - $this->rebuildFlashSaleCache($sale); - - return $sale; - } - - public function restoreFlashSale($id) - { - $sale = $this->findOrFail($id); - - $sale->deleted = 0; - - $sale->update(); - - $this->rebuildFlashSaleCache($sale); - - return $sale; - } - - protected function findOrFail($id) - { - $validator = new FlashSaleValidator(); - - return $validator->checkFlashSale($id); - } - - protected function initFlashSaleQueue(FlashSaleModel $sale) - { - $queue = new FlashSaleQueue(); - - $queue->init($sale->id); - } - - protected function rebuildFlashSaleCache(FlashSaleModel $sale) - { - $cache = new FlashSaleCache(); - - $cache->rebuild($sale->id); - } - - protected function createCourseFlashSale($post) - { - $validator = new FlashSaleValidator(); - - $course = $validator->checkCourse($post['xm_course_id']); - - $originInfo = $this->getOriginInfo($course->id, FlashSaleModel::ITEM_COURSE); - - $sale = new FlashSaleModel(); - - $sale->item_id = $course->id; - $sale->item_type = FlashSaleModel::ITEM_COURSE; - $sale->item_info = $originInfo['item_info']; - - $sale->create(); - - return $sale; - } - - protected function createPackageFlashSale($post) - { - $validator = new FlashSaleValidator(); - - $package = $validator->checkPackage($post['xm_package_id']); - - $originInfo = $this->getOriginInfo($package->id, FlashSaleModel::ITEM_PACKAGE); - - $sale = new FlashSaleModel(); - - $sale->item_id = $package->id; - $sale->item_type = FlashSaleModel::ITEM_PACKAGE; - $sale->item_info = $originInfo['item_info']; - - $sale->create(); - - return $sale; - } - - protected function createVipFlashSale($post) - { - $validator = new FlashSaleValidator(); - - $vip = $validator->checkVip($post['xm_vip_id']); - - $originInfo = $this->getOriginInfo($vip->id, FlashSaleModel::ITEM_VIP); - - $sale = new FlashSaleModel(); - - $sale->item_id = $vip->id; - $sale->item_type = FlashSaleModel::ITEM_VIP; - $sale->item_info = $originInfo['item_info']; - - $sale->create(); - - return $sale; - } - - protected function getOriginInfo($itemId, $itemType) - { - $result = [ - 'item_info' => [], - 'item_price' => 0.00, - ]; - - if ($itemType == FlashSaleModel::ITEM_COURSE) { - - $courseRepo = new CourseRepo(); - - $course = $courseRepo->findById($itemId); - - $result = [ - 'item_info' => [ - 'course' => [ - 'id' => $course->id, - 'title' => $course->title, - 'cover' => CourseModel::getCoverPath($course->cover), - 'market_price' => $course->market_price, - ], - ], - 'item_price' => $course->market_price, - ]; - - } elseif ($itemType == FlashSaleModel::ITEM_PACKAGE) { - - $packageRepo = new PackageRepo(); - - $package = $packageRepo->findById($itemId); - - $result = [ - 'item_info' => [ - 'package' => [ - 'id' => $package->id, - 'title' => $package->title, - 'cover' => PackageModel::getCoverPath($package->cover), - 'market_price' => $package->market_price, - ], - ], - 'item_price' => $package->market_price, - ]; - - } elseif ($itemType == FlashSaleModel::ITEM_VIP) { - - $vipRepo = new VipRepo(); - - $vip = $vipRepo->findById($itemId); - - $result = [ - 'item_info' => [ - 'vip' => [ - 'id' => $vip->id, - 'title' => $vip->title, - 'cover' => VipModel::getCoverPath($vip->cover), - 'expiry' => $vip->expiry, - 'price' => $vip->price, - ], - ], - 'item_price' => $vip->price, - ]; - } - - return $result; - } - -} diff --git a/app/Http/Admin/Services/Order.php b/app/Http/Admin/Services/Order.php index 995cf065..b69745d9 100644 --- a/app/Http/Admin/Services/Order.php +++ b/app/Http/Admin/Services/Order.php @@ -9,6 +9,7 @@ namespace App\Http\Admin\Services; use App\Builders\OrderList as OrderListBuilder; use App\Library\Paginator\Query as PaginateQuery; +use App\Library\Validators\Common as CommonValidator; use App\Models\Order as OrderModel; use App\Repos\Account as AccountRepo; use App\Repos\Order as OrderRepo; @@ -36,6 +37,30 @@ class Order extends Service $params['deleted'] = $params['deleted'] ?? 0; + /** + * 兼容订单编号或订单序号查询 + */ + if (isset($params['id']) && strlen($params['id']) > 10) { + $orderRepo = new OrderRepo(); + $order = $orderRepo->findBySn($params['id']); + $params['id'] = $order ? $order->id : -1000; + } + + $accountRepo = new AccountRepo(); + + /** + * 兼容用户编号|手机号码|邮箱地址查询 + */ + if (!empty($params['owner_id'])) { + if (CommonValidator::phone($params['owner_id'])) { + $account = $accountRepo->findByPhone($params['owner_id']); + $params['owner_id'] = $account ? $account->id : -1000; + } elseif (CommonValidator::email($params['owner_id'])) { + $account = $accountRepo->findByEmail($params['owner_id']); + $params['owner_id'] = $account ? $account->id : -1000; + } + } + $sort = $pageQuery->getSort(); $page = $pageQuery->getPage(); $limit = $pageQuery->getLimit(); diff --git a/app/Http/Admin/Services/Question.php b/app/Http/Admin/Services/Question.php index ad1450b7..7a5f2102 100644 --- a/app/Http/Admin/Services/Question.php +++ b/app/Http/Admin/Services/Question.php @@ -16,10 +16,10 @@ use App\Models\Question as QuestionModel; use App\Models\Reason as ReasonModel; use App\Models\Report as ReportModel; use App\Models\User as UserModel; -use App\Repos\Category as CategoryRepo; use App\Repos\Question as QuestionRepo; use App\Repos\Report as ReportRepo; use App\Repos\User as UserRepo; +use App\Services\Category as CategoryService; use App\Services\Logic\Notice\Internal\QuestionApproved as QuestionApprovedNotice; use App\Services\Logic\Notice\Internal\QuestionRejected as QuestionRejectedNotice; use App\Services\Logic\Point\History\QuestionPost as QuestionPostPointHistory; @@ -41,16 +41,11 @@ class Question extends Service return $service->handle($id); } - public function getCategories() + public function getCategoryOptions() { - $categoryRepo = new CategoryRepo(); + $categoryService = new CategoryService(); - return $categoryRepo->findAll([ - 'type' => CategoryModel::TYPE_QUESTION, - 'level' => 1, - 'published' => 1, - 'deleted' => 0, - ]); + return $categoryService->getCategoryOptions(CategoryModel::TYPE_QUESTION); } public function getPublishTypes() @@ -155,11 +150,6 @@ class Question extends Service $data = []; - if (isset($post['category_id'])) { - $category = $validator->checkCategory($post['category_id']); - $data['category_id'] = $category->id; - } - if (isset($post['title'])) { $data['title'] = $validator->checkTitle($post['title']); } @@ -184,6 +174,11 @@ class Question extends Service $data['published'] = $validator->checkPublishStatus($post['published']); } + if (isset($post['category_id'])) { + $category = $validator->checkCategory($post['category_id']); + $data['category_id'] = $category->id; + } + if (isset($post['xm_tag_ids'])) { $this->saveTags($question, $post['xm_tag_ids']); } @@ -210,6 +205,10 @@ class Question extends Service $question->update(); + $sender = $this->getLoginUser(); + + $this->handleQuestionDeletedNotice($question, $sender); + $owner = $this->findUser($question->owner_id); $this->saveDynamicAttrs($question); @@ -247,28 +246,13 @@ class Question extends Service $reason = $this->request->getPost('reason', ['trim', 'string']); $question = $this->findOrFail($id); - - $validator = new QuestionValidator(); - - if ($type == 'approve') { - $question->published = QuestionModel::PUBLISH_APPROVED; - } elseif ($type == 'reject') { - $validator->checkRejectReason($reason); - $question->published = QuestionModel::PUBLISH_REJECTED; - } - - $question->update(); - - $owner = $this->findUser($question->owner_id); - - $this->rebuildQuestionCache($question); - $this->rebuildQuestionIndex($question); - $this->recountUserQuestions($owner); - $sender = $this->getLoginUser(); if ($type == 'approve') { + $question->published = QuestionModel::PUBLISH_APPROVED; + $question->update(); + $this->handleQuestionPostPoint($question); $this->handleQuestionApprovedNotice($question, $sender); @@ -276,17 +260,20 @@ class Question extends Service } elseif ($type == 'reject') { - $options = ReasonModel::questionRejectOptions(); - - if (array_key_exists($reason, $options)) { - $reason = $options[$reason]; - } + $question->published = QuestionModel::PUBLISH_REJECTED; + $question->update(); $this->handleQuestionRejectedNotice($question, $sender, $reason); $this->eventsManager->fire('Question:afterReject', $this, $question); } + $owner = $this->findUser($question->owner_id); + + $this->recountUserQuestions($owner); + $this->rebuildQuestionCache($question); + $this->rebuildQuestionIndex($question); + return $question; } @@ -324,6 +311,72 @@ class Question extends Service $this->recountUserQuestions($owner); } + public function batchModerate() + { + $type = $this->request->getQuery('type', ['trim', 'string']); + $ids = $this->request->getPost('ids', ['trim', 'int']); + + $questionRepo = new QuestionRepo(); + + $questions = $questionRepo->findByIds($ids); + + if ($questions->count() == 0) return; + + $sender = $this->getLoginUser(); + + foreach ($questions as $question) { + + if ($type == 'approve') { + + $question->published = QuestionModel::PUBLISH_APPROVED; + $question->update(); + + $this->handleQuestionPostPoint($question); + $this->handleQuestionApprovedNotice($question, $sender); + + } elseif ($type == 'reject') { + + $question->published = QuestionModel::PUBLISH_REJECTED; + $question->update(); + + $this->handleQuestionRejectedNotice($question, $sender); + } + + $owner = $this->findUser($question->owner_id); + + $this->recountUserQuestions($owner); + $this->rebuildQuestionCache($question); + $this->rebuildQuestionIndex($question); + } + } + + public function batchDelete() + { + $ids = $this->request->getPost('ids', ['trim', 'int']); + + $questionRepo = new QuestionRepo(); + + $questions = $questionRepo->findByIds($ids); + + if ($questions->count() == 0) return; + + $sender = $this->getLoginUser(); + + foreach ($questions as $question) { + + $question->published = QuestionModel::PUBLISH_REJECTED; + $question->update(); + + $this->handleQuestionDeletedNotice($question, $sender); + + $owner = $this->findUser($question->owner_id); + + $this->recountUserQuestions($owner); + $this->rebuildQuestionCache($question); + $this->rebuildQuestionIndex($question); + } + } + protected function findOrFail($id) { $validator = new QuestionValidator(); @@ -379,13 +432,18 @@ class Question extends Service $notice->handle($question, $sender); } - protected function handleQuestionRejectedNotice(QuestionModel $question, UserModel $sender, $reason) + protected function handleQuestionRejectedNotice(QuestionModel $question, UserModel $sender, $reason = '') { $notice = new QuestionRejectedNotice(); $notice->handle($question, $sender, $reason); } + protected function handleQuestionDeletedNotice(QuestionModel $question, UserModel $sender, $reason = '') + { + + } + protected function handleQuestions($pager) { if ($pager->total_items > 0) { diff --git a/app/Http/Admin/Services/Refund.php b/app/Http/Admin/Services/Refund.php index 6c21711a..ed8aeed0 100644 --- a/app/Http/Admin/Services/Refund.php +++ b/app/Http/Admin/Services/Refund.php @@ -9,6 +9,7 @@ namespace App\Http\Admin\Services; use App\Builders\RefundList as RefundListBuilder; use App\Library\Paginator\Query as PaginateQuery; +use App\Library\Validators\Common as CommonValidator; use App\Models\Refund as RefundModel; use App\Models\Task as TaskModel; use App\Repos\Account as AccountRepo; @@ -43,6 +44,21 @@ class Refund extends Service $params['order_id'] = $order ? $order->id : -1000; } + $accountRepo = new AccountRepo(); + + /** + * 兼容用户编号|手机号码|邮箱地址查询 + */ + if (!empty($params['owner_id'])) { + if (CommonValidator::phone($params['owner_id'])) { + $account = $accountRepo->findByPhone($params['owner_id']); + $params['owner_id'] = $account ? $account->id : -1000; + } elseif (CommonValidator::email($params['owner_id'])) { + $account = $accountRepo->findByEmail($params['owner_id']); + $params['owner_id'] = $account ? $account->id : -1000; + } + } + $sort = $pageQuery->getSort(); $page = $pageQuery->getPage(); $limit = $pageQuery->getLimit(); diff --git a/app/Http/Admin/Services/Review.php b/app/Http/Admin/Services/Review.php index efd5a2cc..26922213 100644 --- a/app/Http/Admin/Services/Review.php +++ b/app/Http/Admin/Services/Review.php @@ -9,8 +9,12 @@ namespace App\Http\Admin\Services; use App\Builders\ReviewList as ReviewListBuilder; use App\Library\Paginator\Query as PagerQuery; +use App\Library\Validators\Common as CommonValidator; use App\Models\Course as CourseModel; +use App\Models\Reason as ReasonModel; use App\Models\Review as ReviewModel; +use App\Models\User as UserModel; +use App\Repos\Account as AccountRepo; use App\Repos\Course as CourseRepo; use App\Repos\Review as ReviewRepo; use App\Services\CourseStat as CourseStatService; @@ -25,6 +29,34 @@ class Review extends Service return ReviewModel::publishTypes(); } + public function getReasons() + { + return ReasonModel::reviewRejectOptions(); + } + + public function getXmCourses() + { + $courseRepo = new CourseRepo(); + + $items = $courseRepo->findAll([ + 'published' => 1, + 'deleted' => 0, + ]); + + if ($items->count() == 0) return []; + + $result = []; + + foreach ($items as $item) { + $result[] = [ + 'name' => sprintf('%s - %s(¥%0.2f)', $item->id, $item->title, $item->market_price), + 'value' => $item->id, + ]; + } + + return $result; + } + public function getReviews() { $pagerQuery = new PagerQuery(); @@ -33,6 +65,21 @@ class Review extends Service $params['deleted'] = $params['deleted'] ?? 0; + $accountRepo = new AccountRepo(); + + /** + * 兼容用户编号|手机号码|邮箱地址查询 + */ + if (!empty($params['owner_id'])) { + if (CommonValidator::phone($params['owner_id'])) { + $account = $accountRepo->findByPhone($params['owner_id']); + $params['owner_id'] = $account ? $account->id : -1000; + } elseif (CommonValidator::email($params['owner_id'])) { + $account = $accountRepo->findByEmail($params['owner_id']); + $params['owner_id'] = $account ? $account->id : -1000; + } + } + $sort = $pagerQuery->getSort(); $page = $pagerQuery->getPage(); $limit = $pagerQuery->getLimit(); @@ -103,6 +150,7 @@ class Review extends Service $review->update($data); $this->updateCourseRating($course); + $this->recountCourseReviews($course); $this->eventsManager->fire('Review:afterUpdate', $this, $review); @@ -121,6 +169,12 @@ class Review extends Service $this->recountCourseReviews($course); + $this->updateCourseRating($course); + + $sender = $this->getLoginUser(); + + $this->handleReviewDeletedNotice($review, $sender); + $this->eventsManager->fire('Review:afterReview', $this, $review); } @@ -142,30 +196,102 @@ class Review extends Service public function moderate($id) { $type = $this->request->getPost('type', ['trim', 'string']); + $reason = $this->request->getPost('reason', ['trim', 'string']); $review = $this->findOrFail($id); - if ($type == 'approve') { - $review->published = ReviewModel::PUBLISH_APPROVED; - } elseif ($type == 'reject') { - $review->published = ReviewModel::PUBLISH_REJECTED; - } + $sender = $this->getLoginUser(); - $review->update(); + if ($type == 'approve') { + + $review->published = ReviewModel::PUBLISH_APPROVED; + $review->update(); + + $this->handleReviewApprovedNotice($review, $sender); + + $this->eventsManager->fire('Review:afterApprove', $this, $review); + + } elseif ($type == 'reject') { + + $review->published = ReviewModel::PUBLISH_REJECTED; + $review->update(); + + $this->handleReviewRejectedNotice($review, $sender, $reason); + + $this->eventsManager->fire('Review:afterReject', $this, $review); + } $course = $this->findCourse($review->course_id); $this->recountCourseReviews($course); - - if ($type == 'approve') { - $this->eventsManager->fire('Review:afterApprove', $this, $review); - } elseif ($type == 'reject') { - $this->eventsManager->fire('Review:afterReject', $this, $review); - } + $this->updateCourseRating($course); return $review; } + public function batchModerate() + { + $type = $this->request->getQuery('type', ['trim', 'string']); + $ids = $this->request->getPost('ids', ['trim', 'int']); + + $reviewRepo = new ReviewRepo(); + + $reviews = $reviewRepo->findByIds($ids); + + if ($reviews->count() == 0) return; + + $sender = $this->getLoginUser(); + + foreach ($reviews as $review) { + + if ($type == 'approve') { + + $review->published = ReviewModel::PUBLISH_APPROVED; + $review->update(); + + $this->handleReviewApprovedNotice($review, $sender); + + } elseif ($type == 'reject') { + + $review->published = ReviewModel::PUBLISH_REJECTED; + $review->update(); + + $this->handleReviewRejectedNotice($review, $sender); + } + + $course = $this->findCourse($review->course_id); + + $this->recountCourseReviews($course); + $this->updateCourseRating($course); + } + } + + public function batchDelete() + { + $ids = $this->request->getPost('ids', ['trim', 'int']); + + $reviewRepo = new ReviewRepo(); + + $reviews = $reviewRepo->findByIds($ids); + + if ($reviews->count() == 0) return; + + $sender = $this->getLoginUser(); + + foreach ($reviews as $review) { + + $review->deleted = 1; + $review->update(); + + $this->handleReviewDeletedNotice($review, $sender); + + $course = $this->findCourse($review->course_id); + + $this->recountCourseReviews($course); + $this->updateCourseRating($course); + } + } + protected function findOrFail($id) { $validator = new ReviewValidator(); @@ -180,6 +306,21 @@ class Review extends Service return $courseRepo->findById($id); } + protected function handleReviewApprovedNotice(ReviewModel $review, UserModel $sender) + { + + } + + protected function handleReviewRejectedNotice(ReviewModel $review, UserModel $sender, $reason = '') + { + + } + + protected function handleReviewDeletedNotice(ReviewModel $review, UserModel $sender, $reason = '') + { + + } + protected function recountCourseReviews(CourseModel $course) { $courseRepo = new CourseRepo(); diff --git a/app/Http/Admin/Services/Role.php b/app/Http/Admin/Services/Role.php index e6e50b2e..3899d6cd 100644 --- a/app/Http/Admin/Services/Role.php +++ b/app/Http/Admin/Services/Role.php @@ -140,6 +140,9 @@ class Role extends Service $list[] = str_replace('.edit', '.list', $route); } elseif (strpos($route, '.delete')) { $list[] = str_replace('.delete', '.restore', $route); + $list[] = str_replace('.delete', '.batch_delete', $route); + } elseif (strpos($route, '.moderate')) { + $list[] = str_replace('.moderate', '.batch_moderate', $route); } elseif (strpos($route, '.search')) { $list[] = str_replace('.search', '.list', $route); } diff --git a/app/Http/Admin/Services/Student.php b/app/Http/Admin/Services/Student.php deleted file mode 100644 index 1743e513..00000000 --- a/app/Http/Admin/Services/Student.php +++ /dev/null @@ -1,223 +0,0 @@ - 1, - 'deleted' => 0, - ]; - - /** - * 过滤付费课程 - */ - if ($scope == 'charge') { - $where['free'] = 0; - } - - $items = $courseRepo->findAll($where); - - if ($items->count() == 0) return []; - - $result = []; - - foreach ($items as $item) { - $result[] = [ - 'name' => sprintf('%s - %s(¥%0.2f)', $item->id, $item->title, $item->market_price), - 'value' => $item->id, - 'selected' => $item->id == $courseId, - ]; - } - - return $result; - } - - public function getSourceTypes() - { - return CourseUserModel::sourceTypes(); - } - - public function getCourse($id) - { - $repo = new CourseRepo(); - - return $repo->findById($id); - } - - public function getStudent($id) - { - $repo = new UserRepo(); - - return $repo->findById($id); - } - - public function getRelations() - { - $pagerQuery = new PagerQuery(); - - $params = $pagerQuery->getParams(); - - $params['role_type'] = CourseUserModel::ROLE_STUDENT; - - $validator = new CourseUserValidator(); - - if (!empty($params['xm_course_id'])) { - $course = $validator->checkCourse($params['xm_course_id']); - $params['course_id'] = $course->id; - } - - if (!empty($params['xm_user_id'])) { - $user = $validator->checkUser($params['xm_user_id']); - $params['user_id'] = $user->id; - } - - $sort = $pagerQuery->getSort(); - $page = $pagerQuery->getPage(); - $limit = $pagerQuery->getLimit(); - - $courseUserRepo = new CourseUserRepo(); - - $pager = $courseUserRepo->paginate($params, $sort, $page, $limit); - - return $this->handleRelations($pager); - } - - public function getLearnings() - { - $pagerQuery = new PagerQuery(); - - $params = $pagerQuery->getParams(); - - $sort = $pagerQuery->getSort(); - $page = $pagerQuery->getPage(); - $limit = $pagerQuery->getLimit(); - - $learningRepo = new LearningRepo(); - - $pager = $learningRepo->paginate($params, $sort, $page, $limit); - - return $this->handleLearnings($pager); - } - - public function getRelation($id) - { - return $this->findOrFail($id); - } - - public function createRelation() - { - $post = $this->request->getPost(); - - $validator = new CourseUserValidator(); - - $data = [ - 'role_type' => CourseUserModel::ROLE_STUDENT, - 'source_type' => CourseUserModel::SOURCE_IMPORT, - ]; - - $course = $validator->checkCourse($post['xm_course_id']); - $user = $validator->checkUser($post['xm_user_id']); - $expiryTime = $validator->checkExpiryTime($post['expiry_time']); - - $data['course_id'] = $course->id; - $data['user_id'] = $user->id; - $data['expiry_time'] = $expiryTime; - - $validator->checkIfImported($course->id, $user->id); - - $courseUser = new CourseUserModel(); - - $courseUser->create($data); - - $course->user_count += 1; - $course->update(); - - $user->course_count += 1; - $user->update(); - - return $courseUser; - } - - public function updateRelation() - { - $post = $this->request->getPost(); - - $relation = $this->findOrFail($post['relation_id']); - - $validator = new CourseUserValidator(); - - $data = []; - - if (isset($post['expiry_time'])) { - $data['expiry_time'] = $validator->checkExpiryTime($post['expiry_time']); - } - - $relation->update($data); - - return $relation; - } - - protected function findOrFail($id) - { - $validator = new CourseUserValidator(); - - return $validator->checkRelation($id); - } - - protected function handleRelations($pager) - { - if ($pager->total_items > 0) { - - $builder = new CourseUserListBuilder(); - - $pipeA = $pager->items->toArray(); - $pipeB = $builder->handleCourses($pipeA); - $pipeC = $builder->handleUsers($pipeB); - $pipeD = $builder->objects($pipeC); - - $pager->items = $pipeD; - } - - return $pager; - } - - protected function handleLearnings($pager) - { - if ($pager->total_items > 0) { - - $builder = new LearningListBuilder(); - - $pipeA = $pager->items->toArray(); - $pipeB = $builder->handleCourses($pipeA); - $pipeC = $builder->handleChapters($pipeB); - $pipeD = $builder->handleUsers($pipeC); - $pipeE = $builder->objects($pipeD); - - $pager->items = $pipeE; - } - - return $pager; - } - -} diff --git a/app/Http/Admin/Services/Trade.php b/app/Http/Admin/Services/Trade.php index 42616281..3023e9ae 100644 --- a/app/Http/Admin/Services/Trade.php +++ b/app/Http/Admin/Services/Trade.php @@ -9,6 +9,7 @@ namespace App\Http\Admin\Services; use App\Builders\TradeList as TradeListBuilder; use App\Library\Paginator\Query as PaginateQuery; +use App\Library\Validators\Common as CommonValidator; use App\Models\Refund as RefundModel; use App\Models\Trade as TradeModel; use App\Repos\Account as AccountRepo; @@ -46,6 +47,21 @@ class Trade extends Service $params['order_id'] = $order ? $order->id : -1000; } + $accountRepo = new AccountRepo(); + + /** + * 兼容用户编号|手机号码|邮箱地址查询 + */ + if (!empty($params['owner_id'])) { + if (CommonValidator::phone($params['owner_id'])) { + $account = $accountRepo->findByPhone($params['owner_id']); + $params['owner_id'] = $account ? $account->id : -1000; + } elseif (CommonValidator::email($params['owner_id'])) { + $account = $accountRepo->findByEmail($params['owner_id']); + $params['owner_id'] = $account ? $account->id : -1000; + } + } + $sort = $pageQuery->getSort(); $page = $pageQuery->getPage(); $limit = $pageQuery->getLimit(); diff --git a/app/Http/Admin/Services/User.php b/app/Http/Admin/Services/User.php index 7a15e29f..be2f4039 100644 --- a/app/Http/Admin/Services/User.php +++ b/app/Http/Admin/Services/User.php @@ -335,11 +335,12 @@ class User extends Service $items = $pager->items->toArray(); $pipeA = $builder->handleUsers($items); - $pipeB = $builder->handleAdminRoles($pipeA); - $pipeC = $builder->handleEduRoles($pipeB); - $pipeD = $builder->objects($pipeC); + $pipeB = $builder->handleAccounts($pipeA); + $pipeC = $builder->handleAdminRoles($pipeB); + $pipeD = $builder->handleEduRoles($pipeC); + $pipeE = $builder->objects($pipeD); - $pager->items = $pipeD; + $pager->items = $pipeE; } return $pager; diff --git a/app/Http/Admin/Services/Vip.php b/app/Http/Admin/Services/Vip.php new file mode 100644 index 00000000..a926aba7 --- /dev/null +++ b/app/Http/Admin/Services/Vip.php @@ -0,0 +1,120 @@ +getParams(); + + $params['deleted'] = $params['deleted'] ?? 0; + + $sort = $pagerQuery->getSort(); + $page = $pagerQuery->getPage(); + $limit = $pagerQuery->getLimit(); + + $vipRepo = new VipRepo(); + + return $vipRepo->paginate($params, $sort, $page, $limit); + } + + public function getVip($id) + { + return $this->findOrFail($id); + } + + public function createVip() + { + $post = $this->request->getPost(); + + $validator = new VipValidator(); + + $data = []; + + $data['expiry'] = $validator->checkExpiry($post['expiry']); + $data['price'] = $validator->checkPrice($post['price']); + $data['title'] = sprintf('%s个月', $data['expiry']); + + $vip = new VipModel(); + + $vip->create($data); + + return $vip; + } + + public function updateVip($id) + { + $vip = $this->findOrFail($id); + + $post = $this->request->getPost(); + + $validator = new VipValidator(); + + $data = []; + + if (isset($post['cover'])) { + $data['cover'] = $validator->checkCover($post['cover']); + } + + if (isset($post['expiry'])) { + $data['expiry'] = $validator->checkExpiry($post['expiry']); + $data['title'] = sprintf('%s个月', $data['expiry']); + } + + if (isset($post['price'])) { + $data['price'] = $validator->checkPrice($post['price']); + } + + if (isset($post['published'])) { + $data['published'] = $validator->checkPublishStatus($post['published']); + } + + $vip->update($data); + + return $vip; + } + + public function deleteVip($id) + { + $vip = $this->findOrFail($id); + + $vip->deleted = 1; + + $vip->update(); + + return $vip; + } + + public function restoreVip($id) + { + $vip = $this->findOrFail($id); + + $vip->deleted = 0; + + $vip->update(); + + return $vip; + } + + protected function findOrFail($id) + { + $validator = new VipValidator(); + + return $validator->checkVip($id); + } + +} diff --git a/app/Http/Admin/Views/answer/list.volt b/app/Http/Admin/Views/answer/list.volt index a2fb6054..7bbaf4d6 100644 --- a/app/Http/Admin/Views/answer/list.volt +++ b/app/Http/Admin/Views/answer/list.volt @@ -5,12 +5,17 @@ {{ partial('macros/answer') }} {% set search_url = url({'for':'admin.answer.search'}) %} + {% set batch_delete_url = url({'for':'admin.answer.batch_delete'}) %}
+ {% if request.get('course_id') > 0 %} + 返回 + {% endif %} 回答管理 + 批量删除
-

-

课程:{{ item.course.title }}

-

章节:{{ item.chapter.title }}

+

课程:{{ item.course.title }}({{ item.course.id }})

+

章节:{{ item.chapter.title }}({{ item.chaper.id }})

-

类型:{{ client_type_info(item.client_type) }}

+

类型:{{ client_type(item.client_type) }}

地址:{{ item.client_ip }}

{{ duration }}
+
+ + @@ -29,7 +36,9 @@ - + + + @@ -46,10 +55,15 @@ {% set restore_url = url({'for':'admin.answer.restore','id':item.id}) %} {% set moderate_url = url({'for':'admin.answer.moderate','id':item.id}) %} + + diff --git a/app/Http/Admin/Views/answer/moderate.volt b/app/Http/Admin/Views/answer/moderate.volt index 703cebd4..4dec226a 100644 --- a/app/Http/Admin/Views/answer/moderate.volt +++ b/app/Http/Admin/Views/answer/moderate.volt @@ -37,8 +37,8 @@
diff --git a/app/Http/Admin/Views/answer/report.volt b/app/Http/Admin/Views/answer/report.volt index f0b06c78..62b8bba0 100644 --- a/app/Http/Admin/Views/answer/report.volt +++ b/app/Http/Admin/Views/answer/report.volt @@ -23,13 +23,13 @@
{{ answer.question.title }}
{{ answer.owner.name }} - {{ date('Y-m-d H:i',answer.create_time) }} + {{ date('Y-m-d H:i:s',answer.create_time) }}
{{ answer.content }}
-
信息作者信息问答信息 评论 点赞 状态
-

问题:{{ item.question.title }}

-

回答:{{ substr(item.summary,0,32) }}

-

作者:{{ item.owner.name }} 创建:{{ date('Y-m-d',item.create_time) }}

+

昵称:{{ item.owner.name }}

+

编号:{{ item.owner.id }}

+
+

问题:{{ item.question.title }}({{ item.question.id }})

+

回答:{{ item.summary }}({{ item.id }})

+

创建:{{ date('Y-m-d',item.create_time) }}

{{ item.comment_count }} {{ item.like_count }}
+
@@ -73,7 +73,7 @@
- +
diff --git a/app/Http/Admin/Views/answer/search.volt b/app/Http/Admin/Views/answer/search.volt index cd0e7b6f..198944c4 100644 --- a/app/Http/Admin/Views/answer/search.volt +++ b/app/Http/Admin/Views/answer/search.volt @@ -24,11 +24,21 @@ +
+ +
+ +
+
-
+
+ +
+
{% for value,title in publish_types %} - + {% endfor %}
@@ -55,4 +65,24 @@ +{% endblock %} + +{% block inline_js %} + + + {% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/article/edit.volt b/app/Http/Admin/Views/article/edit.volt index 041fd3b6..1046feeb 100644 --- a/app/Http/Admin/Views/article/edit.volt +++ b/app/Http/Admin/Views/article/edit.volt @@ -2,6 +2,8 @@ {% block content %} + {% set update_url = url({'for':'admin.article.update','id':article.id}) %} +
编辑文章
@@ -9,12 +11,16 @@
  • 基本信息
  • +
  • 搜索优化
  • 文章内容
{{ partial('article/edit_basic') }}
+
+ {{ partial('article/edit_seo') }} +
{{ partial('article/edit_desc') }}
@@ -29,6 +35,7 @@ {{ js_include('lib/kindeditor/kindeditor.min.js') }} {{ js_include('lib/kindeditor/lang/zh-CN.js') }} {{ js_include('admin/js/content.editor.js') }} + {{ js_include('admin/js/cover.upload.js') }} {% endblock %} diff --git a/app/Http/Admin/Views/article/edit_basic.volt b/app/Http/Admin/Views/article/edit_basic.volt index d76f9e88..1b956c39 100644 --- a/app/Http/Admin/Views/article/edit_basic.volt +++ b/app/Http/Admin/Views/article/edit_basic.volt @@ -1,6 +1,16 @@ {% set source_url_display = article.source_type == 1 ? 'display:none' : 'display:block' %} -
+ +
+ +
+ + +
+
+ +
+
@@ -8,15 +18,21 @@
- +
-
+
- +
- +
@@ -43,16 +59,23 @@
- +
- - + + +
+
+
+ +
+ +
- +
diff --git a/app/Http/Admin/Views/article/edit_desc.volt b/app/Http/Admin/Views/article/edit_desc.volt index f3b32586..bd0b4927 100644 --- a/app/Http/Admin/Views/article/edit_desc.volt +++ b/app/Http/Admin/Views/article/edit_desc.volt @@ -1,4 +1,4 @@ - +
diff --git a/app/Http/Admin/Views/article/edit_seo.volt b/app/Http/Admin/Views/article/edit_seo.volt new file mode 100644 index 00000000..5dfa0d94 --- /dev/null +++ b/app/Http/Admin/Views/article/edit_seo.volt @@ -0,0 +1,21 @@ + +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ + +
+
+ \ No newline at end of file diff --git a/app/Http/Admin/Views/article/list.volt b/app/Http/Admin/Views/article/list.volt index 50f9c6f6..19cbc66d 100644 --- a/app/Http/Admin/Views/article/list.volt +++ b/app/Http/Admin/Views/article/list.volt @@ -6,14 +6,20 @@ {% set add_url = url({'for':'admin.article.add'}) %} {% set search_url = url({'for':'admin.article.search'}) %} + {% set category_url = url({'for':'admin.article.category'}) %} + {% set batch_delete_url = url({'for':'admin.article.batch_delete'}) %}
文章管理 + 批量删除
-
+
- - + @@ -37,11 +42,10 @@ - - - - - + + + + @@ -59,30 +63,34 @@ {% set moderate_url = url({'for':'admin.article.moderate','id':item.id}) %} {% set comment_url = url({'for':'admin.comment.list'},{'item_id':item.id,'item_type':2}) %} + + - - - - + - -
文章浏览评论点赞收藏作者信息文章信息统计信息 状态 推荐 关闭
+

昵称:{{ item.owner.name }}

+

编号:{{ item.owner.id }}

+

标题:{{ item.title }}({{ item.id }})

{% if item.category.id is defined %} 分类:{{ item.category.name }} {% endif %} - {% if item.tags %} - 标签:{{ tags_info(item.tags) }} - {% endif %} -

-

- 来源:{{ source_type(item.source_type) }} - 作者:{{ item.owner.name }} 创建:{{ date('Y-m-d',item.create_time) }}

{{ item.view_count }}{{ item.comment_count }}{{ item.like_count }}{{ item.favorite_count }} +

+ 浏览:{{ item.view_count }} + 评论:{{ item.comment_count }} +

+

+ 点赞:{{ item.like_count }} + 收藏:{{ item.favorite_count }} +

+
{{ publish_status(item.published) }}
@@ -117,70 +125,11 @@ diff --git a/app/Http/Admin/Views/audit/search.volt b/app/Http/Admin/Views/audit/search.volt index 2167810e..7a8ce8c4 100644 --- a/app/Http/Admin/Views/audit/search.volt +++ b/app/Http/Admin/Views/audit/search.volt @@ -35,7 +35,7 @@
-
-
+
-
diff --git a/app/Http/Admin/Views/category/list.volt b/app/Http/Admin/Views/category/list.volt index 2b79388e..3f6351a0 100644 --- a/app/Http/Admin/Views/category/list.volt +++ b/app/Http/Admin/Views/category/list.volt @@ -22,7 +22,7 @@
- +
@@ -39,7 +39,7 @@ - + @@ -54,20 +54,21 @@ {% set restore_url = url({'for':'admin.category.restore','id':item.id}) %} - - {% if item.type == 1 %} + + {% if item.type in [1,3,4] %} {% if item.level == 1 %} {% else %} {% endif %} - {% elseif item.type == 2 %} + {% else %} {% endif %} - +
图标 名称 层级子节点子类 排序 发布 操作
{{ item.id }}{{ item.name }}{{ item.name }} {{ item.name }}{{ item.name }}{{ item.name }}{{ item.level }} {{ item.child_count }}
diff --git a/app/Http/Admin/Views/chapter/lessons_live.volt b/app/Http/Admin/Views/chapter/lessons_live.volt index 6871a304..0ff808d0 100644 --- a/app/Http/Admin/Views/chapter/lessons_live.volt +++ b/app/Http/Admin/Views/chapter/lessons_live.volt @@ -17,7 +17,7 @@ {% endif %} {%- endmacro %} - +
diff --git a/app/Http/Admin/Views/chapter/lessons_offline.volt b/app/Http/Admin/Views/chapter/lessons_offline.volt index 91b9fa67..dae91e84 100644 --- a/app/Http/Admin/Views/chapter/lessons_offline.volt +++ b/app/Http/Admin/Views/chapter/lessons_offline.volt @@ -7,7 +7,7 @@ {% endif %} {%- endmacro %} -
+
diff --git a/app/Http/Admin/Views/chapter/lessons_read.volt b/app/Http/Admin/Views/chapter/lessons_read.volt index b2125d94..317c5908 100644 --- a/app/Http/Admin/Views/chapter/lessons_read.volt +++ b/app/Http/Admin/Views/chapter/lessons_read.volt @@ -1,4 +1,4 @@ -
+
diff --git a/app/Http/Admin/Views/chapter/lessons_vod.volt b/app/Http/Admin/Views/chapter/lessons_vod.volt index 7f31d3d1..4a2018f8 100644 --- a/app/Http/Admin/Views/chapter/lessons_vod.volt +++ b/app/Http/Admin/Views/chapter/lessons_vod.volt @@ -12,7 +12,7 @@ {% endif %} {%- endmacro %} -
+
diff --git a/app/Http/Admin/Views/comment/list.volt b/app/Http/Admin/Views/comment/list.volt index 539ebbd9..eec11649 100644 --- a/app/Http/Admin/Views/comment/list.volt +++ b/app/Http/Admin/Views/comment/list.volt @@ -4,20 +4,36 @@ {{ partial('macros/common') }} -
+ {% set batch_delete_url = url({'for':'admin.comment.batch_delete'}) %} + +
+
+ + {% if request.get('item_id') > 0 %} + 返回 + {% endif %} + 评论管理 + + 批量删除 +
+
+ +
+ - + + + - - + @@ -28,9 +44,12 @@ {% set delete_url = url({'for':'admin.comment.delete','id':item.id}) %} {% set restore_url = url({'for':'admin.comment.restore','id':item.id}) %} - + + + -
评论作者内容回复 点赞用户时间创建 操作
{{ item.content }}{{ item.owner.name }}({{ item.owner.id }}) +

{{ item.content }}

+
{{ item.reply_count }} {{ item.like_count }}{{ item.owner.name }} {{ date('Y-m-d',item.create_time) }} {% if item.deleted == 0 %} diff --git a/app/Http/Admin/Views/comment/moderate.volt b/app/Http/Admin/Views/comment/moderate.volt index d34bbe26..d78e7500 100644 --- a/app/Http/Admin/Views/comment/moderate.volt +++ b/app/Http/Admin/Views/comment/moderate.volt @@ -37,8 +37,8 @@
@@ -46,7 +46,7 @@
- +
diff --git a/app/Http/Admin/Views/comment/report.volt b/app/Http/Admin/Views/comment/report.volt index da53925a..75bfb15a 100644 --- a/app/Http/Admin/Views/comment/report.volt +++ b/app/Http/Admin/Views/comment/report.volt @@ -22,13 +22,13 @@
{{ comment.owner.name }} - {{ date('Y-m-d H:i',comment.create_time) }} + {{ date('Y-m-d H:i:s',comment.create_time) }}
{{ comment.content }}
- +
@@ -47,7 +47,7 @@ - + {% endfor %} @@ -72,7 +72,7 @@
- +
diff --git a/app/Http/Admin/Views/consult/list.volt b/app/Http/Admin/Views/consult/list.volt index 2b025356..5aa25265 100644 --- a/app/Http/Admin/Views/consult/list.volt +++ b/app/Http/Admin/Views/consult/list.volt @@ -2,19 +2,20 @@ {% block content %} -{{ partial('macros/consult') }} + {{ partial('macros/consult') }} {% set search_url = url({'for':'admin.consult.search'}) %} + {% set batch_delete_url = url({'for':'admin.consult.batch_delete'}) %}
- 返回 - {% if course %} - {{ course.title }} + {% if request.get('course_id') > 0 %} + 返回 {% endif %} 咨询管理 + 批量删除
-
{{ item.owner.name }} {{ item.reason }}{{ date('Y-m-d',item.create_time) }}{{ date('Y-m-d H:i:s',item.create_time) }}
+
+ + @@ -33,42 +36,47 @@ - + + + {% for item in pager.items %} {% set item.answer = item.answer ? item.answer : 'N/A' %} - {% set list_by_course_url = url({'for':'admin.consult.list'},{'course_id':item.course.id}) %} - {% set list_by_user_url = url({'for':'admin.consult.list'},{'owner_id':item.owner.id}) %} + {% set course_url = url({'for':'home.course.show','id':item.course.id}) %} + {% set owner_url = url({'for':'home.user.show','id':item.owner.id}) %} {% set moderate_url = url({'for':'admin.consult.moderate','id':item.id}) %} {% set edit_url = url({'for':'admin.consult.edit','id':item.id}) %} {% set update_url = url({'for':'admin.consult.update','id':item.id}) %} {% set delete_url = url({'for':'admin.consult.delete','id':item.id}) %} {% set restore_url = url({'for':'admin.consult.restore','id':item.id}) %} + + - + - - + + - + @@ -48,11 +52,12 @@ {% set restore_url = url({'for':'admin.help.restore','id':item.id}) %} - + - - + +
问答 用户内容 时间 状态私密 操作
-

课程:{{ item.course.title }}({{ item.course.id }}){{ private_info(item.private) }}

+

昵称:{{ item.owner.name }}

+

编号:{{ item.owner.id }}

+
+

课程:{{ item.course.title }}({{ item.course.id }})

提问:{{ item.question }}

回复:{{ item.answer }}

-

昵称:{{ item.owner.name }}

-

编号:{{ item.owner.id }}

-
-

提问:{{ date('Y-m-d H:i:s',item.create_time) }}

+

提问:{{ date('Y-m-d',item.create_time) }}

{% if item.reply_time > 0 %} -

回复:{{ date('Y-m-d H:i:s',item.reply_time) }}

+

回复:{{ date('Y-m-d',item.reply_time) }}

{% else %}

回复:N/A

{% endif %}
{{ publish_status(item.published) }}
diff --git a/app/Http/Admin/Views/consult/moderate.volt b/app/Http/Admin/Views/consult/moderate.volt index 04345558..7016a4be 100644 --- a/app/Http/Admin/Views/consult/moderate.volt +++ b/app/Http/Admin/Views/consult/moderate.volt @@ -7,22 +7,12 @@
- {% if consult.course.id is defined %} -
- -
-
{{ consult.course.title }}
-
+
+ +
+
{{ consult.course.title }}
- {% endif %} - {% if consult.chapter.id is defined %} -
- -
-
{{ consult.chapter.title }}
-
-
- {% endif %} +
@@ -45,13 +35,50 @@
+
- +
+{% endblock %} + +{% block inline_js %} + + + {% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/consult/search.volt b/app/Http/Admin/Views/consult/search.volt index bc683c0c..bc9f476c 100644 --- a/app/Http/Admin/Views/consult/search.volt +++ b/app/Http/Admin/Views/consult/search.volt @@ -13,22 +13,32 @@
- +
- +
- +
- +
+
+
+
+ +
+ +
+
-
+
+
{% for value,title in publish_types %} - + {% endfor %}
@@ -55,4 +65,41 @@ +{% endblock %} + +{% block include_js %} + + {{ js_include('lib/xm-select.js') }} + +{% endblock %} + +{% block inline_js %} + + + {% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/student/add.volt b/app/Http/Admin/Views/course/add_user.volt similarity index 54% rename from app/Http/Admin/Views/student/add.volt rename to app/Http/Admin/Views/course/add_user.volt index 40dbcd56..f6731e94 100644 --- a/app/Http/Admin/Views/student/add.volt +++ b/app/Http/Admin/Views/course/add_user.volt @@ -2,20 +2,23 @@ {% block content %} -
-
- 添加学员 -
+ {% set create_url = url({'for':'admin.course.create_user','id':course.id}) %} + +
+ 添加学员 +
+ +
- +
-
+
{{ course.title }}
- +
- +
@@ -35,12 +38,6 @@ {% endblock %} -{% block include_js %} - - {{ js_include('lib/xm-select.js') }} - -{% endblock %} - {% block inline_js %} diff --git a/app/Http/Admin/Views/course/edit_basic.volt b/app/Http/Admin/Views/course/edit_basic.volt index bf0f5709..60ebe801 100644 --- a/app/Http/Admin/Views/course/edit_basic.volt +++ b/app/Http/Admin/Views/course/edit_basic.volt @@ -1,10 +1,4 @@ - -
- -
- -
-
+
@@ -15,25 +9,63 @@
+
+ +
+ +
+
-
+
-
+ +
+
+
+ +
+
- - - - + {% for value,title in level_types %} + {% set checked = course.level == value ? 'checked="checked"' : '' %} + + {% endfor %} +
+
+
+ +
+ + +
+
+
+ +
+ +
diff --git a/app/Http/Admin/Views/course/edit_desc.volt b/app/Http/Admin/Views/course/edit_desc.volt index 0c9893c3..a1a511fd 100644 --- a/app/Http/Admin/Views/course/edit_desc.volt +++ b/app/Http/Admin/Views/course/edit_desc.volt @@ -1,4 +1,4 @@ - +
diff --git a/app/Http/Admin/Views/course/edit_offline.volt b/app/Http/Admin/Views/course/edit_offline.volt index 2ec4f202..f82fba81 100644 --- a/app/Http/Admin/Views/course/edit_offline.volt +++ b/app/Http/Admin/Views/course/edit_offline.volt @@ -1,4 +1,4 @@ - +
diff --git a/app/Http/Admin/Views/course/edit_related.volt b/app/Http/Admin/Views/course/edit_related.volt index 473ee342..6d72aaf0 100644 --- a/app/Http/Admin/Views/course/edit_related.volt +++ b/app/Http/Admin/Views/course/edit_related.volt @@ -1,4 +1,4 @@ - +
diff --git a/app/Http/Admin/Views/course/edit_sale.volt b/app/Http/Admin/Views/course/edit_sale.volt index d08ff074..4991243c 100644 --- a/app/Http/Admin/Views/course/edit_sale.volt +++ b/app/Http/Admin/Views/course/edit_sale.volt @@ -1,4 +1,4 @@ - +
diff --git a/app/Http/Admin/Views/course/learnings.volt b/app/Http/Admin/Views/course/learnings.volt new file mode 100644 index 00000000..62b64093 --- /dev/null +++ b/app/Http/Admin/Views/course/learnings.volt @@ -0,0 +1,48 @@ +{% extends 'templates/main.volt' %} + +{% block content %} + + {{ partial('macros/common') }} + + {% if pager.total_pages > 0 %} + + + + + + + + + + + + + + + + + + + {% for item in pager.items %} + {% set duration = item.duration > 0 ? item.duration|duration : 'N/A' %} + {% set active_time = item.active_time > 0 ? date('Y-m-d H:i:s',item.active_time) : 'N/A' %} + + + + + + + + {% endfor %} + +
章节名称终端类型终端地址学习时长最近学习
{{ item.chapter.title }}({{ item.chapter.id }}){{ client_type(item.client_type) }}{{ item.client_ip }}{{ duration }}{{ active_time }}
+ {{ partial('partials/pager') }} + {% endif %} + +{% endblock %} + +{% block include_js %} + + {{ js_include('admin/js/ip2region.js') }} + +{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/course/list.volt b/app/Http/Admin/Views/course/list.volt index 0c25d653..4203088b 100644 --- a/app/Http/Admin/Views/course/list.volt +++ b/app/Http/Admin/Views/course/list.volt @@ -27,13 +27,8 @@
- +
- - - - - @@ -43,14 +38,9 @@ - - - - - - - - + + + @@ -63,13 +53,13 @@ {% set update_url = url({'for':'admin.course.update','id':item.id}) %} {% set delete_url = url({'for':'admin.course.delete','id':item.id}) %} {% set restore_url = url({'for':'admin.course.restore','id':item.id}) %} - {% set catalog_url = url({'for':'admin.course.chapters','id':item.id}) %} - {% set student_url = url({'for':'admin.student.list'},{'course_id':item.id}) %} - {% set review_url = url({'for':'admin.review.list'},{'course_id':item.id}) %} - {% set consult_url = url({'for':'admin.consult.list'},{'course_id':item.id}) %} + {% set chapters_url = url({'for':'admin.course.chapters','id':item.id}) %} + {% set users_url = url({'for':'admin.course.users','id':item.id}) %} + {% set reviews_url = url({'for':'admin.review.list'},{'course_id':item.id}) %} + {% set consults_url = url({'for':'admin.consult.list'},{'course_id':item.id}) %} - - - - - - - + - @@ -129,51 +124,4 @@ {{ partial('partials/pager') }} -{% endblock %} - -{% block inline_js %} - - - {% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/course/search.volt b/app/Http/Admin/Views/course/search.volt index bded8418..6a807e3b 100644 --- a/app/Http/Admin/Views/course/search.volt +++ b/app/Http/Admin/Views/course/search.volt @@ -7,34 +7,54 @@ 搜索课程
- +
- +
- +
-
+
- +
-
+ +
+
+
+ +
+ +
+
-
+
+
{% for value,title in model_types %} - + {% endfor %}
@@ -42,7 +62,7 @@
{% for value,title in level_types %} - + {% endfor %}
@@ -85,36 +105,20 @@ {% endblock %} -{% block include_js %} - - {{ js_include('lib/xm-select.js') }} - -{% endblock %} - {% block inline_js %} diff --git a/app/Http/Admin/Views/course/search_user.volt b/app/Http/Admin/Views/course/search_user.volt new file mode 100644 index 00000000..68dde0bf --- /dev/null +++ b/app/Http/Admin/Views/course/search_user.volt @@ -0,0 +1,103 @@ +{% extends 'templates/main.volt' %} + +{% block content %} + + {% set target = request.get('target','string','search') %} + {% set count = request.get('count','int',-1) %} + + {% if target == 'search' %} + {% set action_url = url({'for':'admin.course.users','id':course.id}) %} + {% set title = '搜索学员' %} + {% else %} + {% set action_url = url({'for':'admin.course.export_user','id':course.id}) %} + {% set title = '导出学员' %} + {% endif %} + + +
+ {{ title }} +
+
+ +
+
{{ course.title }}
+
+
+
+ +
+ +
+
+
+ +
+ {% for value,title in source_types %} + + {% endfor %} +
+
+
+ +
+ +
+
-
+
+ +
+
+
+ +
+ + + + +
+
+ + +{% endblock %} + +{% block inline_js %} + + + +{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/course/users.volt b/app/Http/Admin/Views/course/users.volt new file mode 100644 index 00000000..2222791f --- /dev/null +++ b/app/Http/Admin/Views/course/users.volt @@ -0,0 +1,100 @@ +{% extends 'templates/main.volt' %} + +{% block content %} + + {{ partial('macros/course_user') }} + + {% set add_url = url({'for':'admin.course.add_user','id':course.id}) %} + {% set search_url = url({'for':'admin.course.search_user','id':course.id}) %} + + + +
课程课时课件学员收藏咨询评价价格基本信息统计信息价格信息 推荐 发布 操作
-

标题:{{ item.title }}({{ item.id }})

+

标题:{{ item.title }}({{ item.id }})

{% if item.category.id is defined %} 分类:{{ item.category.name }} @@ -85,20 +75,25 @@ 创建:{{ date('Y-m-d',item.create_time) }}

{{ item.lesson_count }}{{ item.resource_count }}{{ item.user_count }}{{ item.favorite_count }}{{ item.consult_count }}{{ item.review_count }} -

原始:{{ '¥%0.2f'|format(item.origin_price) }}

-

市场:{{ '¥%0.2f'|format(item.market_price) }}

-

会员:{{ '¥%0.2f'|format(item.vip_price) }}

+

+ 学员:{{ item.user_count }} + 咨询:{{ item.consult_count }} + 评价:{{ item.review_count }} +

+

+ 课时:{{ item.lesson_count }} + 课件:{{ item.resource_count }} + 收藏:{{ item.favorite_count }} +

+

市场价:{{ '¥%0.2f'|format(item.market_price) }}

+

会员价:{{ '¥%0.2f'|format(item.vip_price) }}

+
+ + + + + + + + + + + + + + + + + + + + + + {% for item in pager.items %} + {% set learnings_url = url({'for':'admin.course.learnings','id':item.course_id},{'user_id':item.user_id,'plan_id':item.plan_id}) %} + {% set user_url = url({'for':'home.user.show','id':item.user_id}) %} + {% set expiry_time = item.expiry_time > 0 ? date('Y-m-d H:i:s',item.expiry_time) : 'N/A' %} + {% set active_time = item.active_time > 0 ? date('Y-m-d H:i:s',item.active_time) : 'N/A' %} + + + + + + + + + + {% endfor %} + +
用户信息学习情况来源类型加入时间过期时间最近学习操作
{{ item.user.name }}({{ item.user.id }}) +

进度:{{ item.progress }}%

+

时长:{{ item.duration|duration }}

+
{{ source_type(item.source_type) }}{{ date('Y-m-d H:i:s',item.create_time) }}{{ expiry_time }}{{ active_time }} + 学习记录 +
+ + {{ partial('partials/pager') }} + +{% endblock %} + +{% block inline_js %} + + + +{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/flash_sale/add.volt b/app/Http/Admin/Views/flash_sale/add.volt deleted file mode 100644 index abfa320a..00000000 --- a/app/Http/Admin/Views/flash_sale/add.volt +++ /dev/null @@ -1,105 +0,0 @@ -{% extends 'templates/main.volt' %} - -{% block content %} - -
-
- 添加商品 -
-
- -
- {% for value,title in item_types %} - - {% endfor %} -
-
- - - -
- -
- - -
-
-
- -{% endblock %} - -{% block include_js %} - - {{ js_include('lib/xm-select.js') }} - -{% endblock %} - -{% block inline_js %} - - - -{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/flash_sale/edit.volt b/app/Http/Admin/Views/flash_sale/edit.volt deleted file mode 100644 index 6142bac2..00000000 --- a/app/Http/Admin/Views/flash_sale/edit.volt +++ /dev/null @@ -1,103 +0,0 @@ -{% extends 'templates/main.volt' %} - -{% block content %} - - {{ partial('macros/flash_sale') }} - - {% set sale.item_info = array_object(sale.item_info) %} - {% set sale.start_time = sale.start_time > 0 ? date('Y-m-d H:i:s',sale.start_time) : '' %} - {% set sale.end_time = sale.end_time > 0 ? date('Y-m-d H:i:s',sale.end_time) : '' %} - -
-
- 编辑商品 -
-
- -
- {{ item_full_info(sale.item_type,sale.item_info) }} -
-
-
- -
- -
-
-
- -
- -
-
-
- -
-
-
-
-
- -
- -
-
-
- -
- -
-
-
- -
- - -
-
-
- -
- - -
-
-
- -{% endblock %} - -{% block include_js %} - - {{ js_include('lib/xm-select.js') }} - -{% endblock %} - -{% block inline_js %} - - - -{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/flash_sale/search.volt b/app/Http/Admin/Views/flash_sale/search.volt deleted file mode 100644 index 0036dd70..00000000 --- a/app/Http/Admin/Views/flash_sale/search.volt +++ /dev/null @@ -1,46 +0,0 @@ -{% extends 'templates/main.volt' %} - -{% block content %} - -
-
- 搜索商品 -
-
- -
- -
-
-
- -
- {% for value,title in item_types %} - - {% endfor %} -
-
-
- -
- - -
-
-
- -
- - -
-
-
- -
- - -
-
-
- -{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/help/list.volt b/app/Http/Admin/Views/help/list.volt index 6f1af71c..7be5ae54 100644 --- a/app/Http/Admin/Views/help/list.volt +++ b/app/Http/Admin/Views/help/list.volt @@ -3,6 +3,7 @@ {% block content %} {% set add_url = url({'for':'admin.help.add'}) %} + {% set category_url = url({'for':'admin.help.category'}) %}
@@ -11,6 +12,9 @@
编号标题 分类标题 浏览 排序 发布
{{ item.id }}{{ item.title }} {{ item.category.name }}{{ item.title }} {{ item.view_count }}
diff --git a/app/Http/Admin/Views/macros/answer.volt b/app/Http/Admin/Views/macros/answer.volt index 05de2d9f..a395e01a 100644 --- a/app/Http/Admin/Views/macros/answer.volt +++ b/app/Http/Admin/Views/macros/answer.volt @@ -6,6 +6,6 @@ {% elseif type == 3 %} 未通过 {% else %} - 未知 + N/A {% endif %} {%- endmacro %} \ No newline at end of file diff --git a/app/Http/Admin/Views/macros/article.volt b/app/Http/Admin/Views/macros/article.volt index fa74535e..91a8eb3a 100644 --- a/app/Http/Admin/Views/macros/article.volt +++ b/app/Http/Admin/Views/macros/article.volt @@ -6,7 +6,7 @@ {% elseif type == 3 %} 未通过 {% else %} - 未知 + N/A {% endif %} {%- endmacro %} @@ -20,11 +20,4 @@ {% else %} N/A {% endif %} -{%- endmacro %} - -{%- macro tags_info(items) %} - {% for item in items %} - {% set comma = loop.last ? '' : ',' %} - {{ item.name ~ comma }} - {% endfor %} {%- endmacro %} \ No newline at end of file diff --git a/app/Http/Admin/Views/macros/comment.volt b/app/Http/Admin/Views/macros/comment.volt index 05de2d9f..a395e01a 100644 --- a/app/Http/Admin/Views/macros/comment.volt +++ b/app/Http/Admin/Views/macros/comment.volt @@ -6,6 +6,6 @@ {% elseif type == 3 %} 未通过 {% else %} - 未知 + N/A {% endif %} {%- endmacro %} \ No newline at end of file diff --git a/app/Http/Admin/Views/macros/consult.volt b/app/Http/Admin/Views/macros/consult.volt index ce3c3a92..3210346a 100644 --- a/app/Http/Admin/Views/macros/consult.volt +++ b/app/Http/Admin/Views/macros/consult.volt @@ -6,7 +6,7 @@ {% elseif type == 3 %} 未通过 {% else %} - 未知 + N/A {% endif %} {%- endmacro %} diff --git a/app/Http/Admin/Views/macros/course.volt b/app/Http/Admin/Views/macros/course.volt index bb716a69..2617aa2b 100644 --- a/app/Http/Admin/Views/macros/course.volt +++ b/app/Http/Admin/Views/macros/course.volt @@ -8,7 +8,7 @@ {% elseif value == 4 %} 面授 {% else %} - 未知 + N/A {% endif %} {%- endmacro %} @@ -22,6 +22,6 @@ {% elseif value == 4 %} 高级 {% else %} - 未知 + N/A {% endif %} {%- endmacro %} \ No newline at end of file diff --git a/app/Http/Admin/Views/macros/course_user.volt b/app/Http/Admin/Views/macros/course_user.volt new file mode 100644 index 00000000..0f3cb9db --- /dev/null +++ b/app/Http/Admin/Views/macros/course_user.volt @@ -0,0 +1,19 @@ +{%- macro source_type(value) %} + {% if value == 1 %} + 免费 + {% elseif value == 2 %} + 付费 + {% elseif value == 3 %} + 畅学 + {% elseif value == 4 %} + 分配 + {% elseif value == 5 %} + 积分兑换 + {% elseif value == 6 %} + 抽奖兑换 + {% elseif value == 10 %} + 试听 + {% else %} + N/A + {% endif %} +{%- endmacro %} \ No newline at end of file diff --git a/app/Http/Admin/Views/macros/question.volt b/app/Http/Admin/Views/macros/question.volt index 6593e6ea..a395e01a 100644 --- a/app/Http/Admin/Views/macros/question.volt +++ b/app/Http/Admin/Views/macros/question.volt @@ -6,13 +6,6 @@ {% elseif type == 3 %} 未通过 {% else %} - 未知 + N/A {% endif %} -{%- endmacro %} - -{%- macro tags_info(items) %} - {% for item in items %} - {% set comma = loop.last ? '' : ',' %} - {{ item.name ~ comma }} - {% endfor %} {%- endmacro %} \ No newline at end of file diff --git a/app/Http/Admin/Views/macros/review.volt b/app/Http/Admin/Views/macros/review.volt index 05de2d9f..a395e01a 100644 --- a/app/Http/Admin/Views/macros/review.volt +++ b/app/Http/Admin/Views/macros/review.volt @@ -6,6 +6,6 @@ {% elseif type == 3 %} 未通过 {% else %} - 未知 + N/A {% endif %} {%- endmacro %} \ No newline at end of file diff --git a/app/Http/Admin/Views/moderation/answers.volt b/app/Http/Admin/Views/moderation/answers.volt index 24d18077..11d4e9bc 100644 --- a/app/Http/Admin/Views/moderation/answers.volt +++ b/app/Http/Admin/Views/moderation/answers.volt @@ -4,26 +4,32 @@ {{ partial('macros/answer') }} + {% set batch_moderate_url = url({'for':'admin.answer.batch_moderate'}) %} +
回答审核 + 批量通过 + 批量拒绝
- +
- + + - - - + + + + @@ -33,14 +39,15 @@ {% set owner_url = url({'for':'home.user.show','id':item.owner.id}) %} {% set moderate_url = url({'for':'admin.answer.moderate','id':item.id}) %} - + +
回答作者时间用户信息问答信息创建时间 操作
-

问题:{{ item.question.title }}

-

回答:{{ substr(item.summary,0,32) }}

-

昵称:{{ item.owner.name }}

编号:{{ item.owner.id }}

+

问题:{{ item.question.title }}

+

回答:{{ substr(item.summary,0,32) }}

+
{{ date('Y-m-d H:i:s',item.create_time) }} 详情 diff --git a/app/Http/Admin/Views/moderation/articles.volt b/app/Http/Admin/Views/moderation/articles.volt index cc1184a3..a5314447 100644 --- a/app/Http/Admin/Views/moderation/articles.volt +++ b/app/Http/Admin/Views/moderation/articles.volt @@ -4,16 +4,21 @@ {{ partial('macros/article') }} + {% set batch_moderate_url = url({'for':'admin.article.batch_moderate'}) %} +
文章审核 + 批量通过 + 批量拒绝
- +
+ @@ -21,9 +26,10 @@ - - - + + + + @@ -32,19 +38,20 @@ {% set owner_url = url({'for':'home.user.show','id':item.owner.id}) %} {% set moderate_url = url({'for':'admin.article.moderate','id':item.id}) %} - + +
文章作者时间用户信息文章信息创建时间 操作
-

标题:{{ item.title }}

-

- 来源:{{ source_type(item.source_type) }} - {% if item.tags %} - 标签:{{ tags_info(item.tags) }} - {% endif %} -

-

昵称:{{ item.owner.name }}

编号:{{ item.owner.id }}

+

标题:{{ item.title }}

+

+ {% if item.category.id is defined %} + 分类:{{ item.category.name }} + {% endif %} + 来源:{{ source_type(item.source_type) }} +

+
{{ date('Y-m-d H:i:s',item.create_time) }} 详情 diff --git a/app/Http/Admin/Views/moderation/comments.volt b/app/Http/Admin/Views/moderation/comments.volt index 6100004d..f6b15afa 100644 --- a/app/Http/Admin/Views/moderation/comments.volt +++ b/app/Http/Admin/Views/moderation/comments.volt @@ -4,26 +4,32 @@ {{ partial('macros/comment') }} + {% set batch_moderate_url = url({'for':'admin.comment.batch_moderate'}) %} +
评论审核 + 批量通过 + 批量拒绝
- +
- + + - - - + + + + @@ -32,11 +38,12 @@ {% set owner_url = url({'for':'home.user.show','id':item.owner.id}) %} {% set moderate_url = url({'for':'admin.comment.moderate','id':item.id}) %} - + +
评论作者时间用户信息评论信息创建时间 操作
{{ substr(item.content,0,32) }}

昵称:{{ item.owner.name }}

编号:{{ item.owner.id }}

{{ substr(item.content,0,32) }} {{ date('Y-m-d H:i:s',item.create_time) }} 详情 diff --git a/app/Http/Admin/Views/moderation/consults.volt b/app/Http/Admin/Views/moderation/consults.volt index 6009231d..c08c40b3 100644 --- a/app/Http/Admin/Views/moderation/consults.volt +++ b/app/Http/Admin/Views/moderation/consults.volt @@ -3,17 +3,21 @@ {% block content %} {% set search_url = url({'for':'admin.consult.search'}) %} + {% set batch_moderate_url = url({'for':'admin.consult.batch_moderate'}) %}
咨询审核 + 批量通过 + 批量拒绝
- +
+ @@ -21,9 +25,10 @@ - - - + + + + @@ -34,23 +39,16 @@ {% set course_url = url({'for':'home.course.show','id':item.course.id}) %} {% set moderate_url = url({'for':'admin.consult.moderate','id':item.id}) %} - + + diff --git a/app/Http/Admin/Views/moderation/questions.volt b/app/Http/Admin/Views/moderation/questions.volt index 71e922d3..1c7ed23f 100644 --- a/app/Http/Admin/Views/moderation/questions.volt +++ b/app/Http/Admin/Views/moderation/questions.volt @@ -4,16 +4,21 @@ {{ partial('macros/question') }} + {% set batch_moderate_url = url({'for':'admin.question.batch_moderate'}) %} +
问题审核 + 批量通过 + 批量拒绝
-
问答用户时间用户信息咨询信息创建时间 操作
-

课程:{{ item.course.title }}({{ item.course.id }})

-

提问:{{ item.question }}

-

回复:{{ item.answer }}

-

昵称:{{ item.owner.name }}

编号:{{ item.owner.id }}

-

提问:{{ date('Y-m-d H:i:s',item.create_time) }}

- {% if item.reply_time > 0 %} -

回复:{{ date('Y-m-d H:i:s',item.reply_time) }}

- {% else %} -

回复:N/A

- {% endif %} +

课程:{{ item.course.title }}({{ item.course.id }})

+

咨询:{{ item.question }}

{{ date('Y-m-d H:i:s',item.create_time) }} 详情
+
+ @@ -21,9 +26,10 @@ - - - + + + + @@ -32,18 +38,19 @@ {% set owner_url = url({'for':'home.user.show','id':item.owner.id}) %} {% set moderate_url = url({'for':'admin.question.moderate','id':item.id}) %} - + +
问题作者时间用户信息问题信息创建时间 操作
-

标题:{{ item.title }}

-

- {% if item.tags %} - 标签:{{ tags_info(item.tags) }} - {% endif %} -

-

昵称:{{ item.owner.name }}

编号:{{ item.owner.id }}

+

标题:{{ item.title }}

+

+ {% if item.category.id is defined %} + 分类:{{ item.category.name }} + {% endif %} +

+
{{ date('Y-m-d H:i:s',item.create_time) }} 详情 diff --git a/app/Http/Admin/Views/moderation/reviews.volt b/app/Http/Admin/Views/moderation/reviews.volt index f3cc40c3..da90d9a7 100644 --- a/app/Http/Admin/Views/moderation/reviews.volt +++ b/app/Http/Admin/Views/moderation/reviews.volt @@ -3,17 +3,21 @@ {% block content %} {% set search_url = url({'for':'admin.review.search'}) %} + {% set batch_moderate_url = url({'for':'admin.review.batch_moderate'}) %}
评价审核 + 批量通过 + 批量拒绝
- +
+ @@ -22,10 +26,11 @@ - - - - + + + + + @@ -35,6 +40,11 @@ {% set course_url = url({'for':'home.course.show','id':item.course.id}) %} {% set moderate_url = url({'for':'admin.review.moderate','id':item.id}) %} + + -
內容评分用户时间用户信息评价信息课程评分创建时间 操作
+

昵称:{{ item.owner.name }}

+

编号:{{ item.owner.id }}

+

课程:{{ item.course.title }}({{ item.course.id }})

评价:{{ item.content }}

@@ -44,10 +54,6 @@

通俗易懂:{{ item.rating2 }}

逻辑清晰:{{ item.rating3 }}

-

昵称:{{ item.owner.name }}

-

编号:{{ item.owner.id }}

-
{{ date('Y-m-d H:i:s',item.create_time) }} 详情 diff --git a/app/Http/Admin/Views/nav/list.volt b/app/Http/Admin/Views/nav/list.volt index 04788648..0781172b 100644 --- a/app/Http/Admin/Views/nav/list.volt +++ b/app/Http/Admin/Views/nav/list.volt @@ -38,7 +38,7 @@ - +
@@ -82,7 +82,8 @@ - + - - - + @@ -44,15 +42,14 @@ {% for item in pager.items %} {% set show_url = url({'for':'admin.order.show','id':item.id}) %} - - + diff --git a/app/Http/Admin/Views/order/macro.volt b/app/Http/Admin/Views/order/macro.volt index f2b4fc1a..b7ffb616 100644 --- a/app/Http/Admin/Views/order/macro.volt +++ b/app/Http/Admin/Views/order/macro.volt @@ -81,14 +81,4 @@ {% elseif value == 5 %} 已退款 {% endif %} -{%- endmacro %} - -{%- macro promotion_type(value) %} - {% if value == 1 %} - 秒杀 - {% elseif value == 2 %} - 折扣 - {% else %} - N/A - {% endif %} {%- endmacro %} \ No newline at end of file diff --git a/app/Http/Admin/Views/order/order_info.volt b/app/Http/Admin/Views/order/order_info.volt index 4cc52a4d..efe116e9 100644 --- a/app/Http/Admin/Views/order/order_info.volt +++ b/app/Http/Admin/Views/order/order_info.volt @@ -8,7 +8,6 @@ diff --git a/app/Http/Admin/Views/order/search.volt b/app/Http/Admin/Views/order/search.volt index 1f266a06..14f94fd1 100644 --- a/app/Http/Admin/Views/order/search.volt +++ b/app/Http/Admin/Views/order/search.volt @@ -6,12 +6,6 @@
搜索订单
-
- -
- -
-
@@ -19,10 +13,26 @@
- + +
+ +
+
+
+ +
+ +
+
-
+
+ +
+
+
+
{% for value,title in item_types %} - + {% endfor %}
@@ -30,20 +40,10 @@
{% for value,title in status_types %} - + {% endfor %}
-
- -
- -
-
-
-
- -
-
@@ -59,16 +59,14 @@ diff --git a/app/Http/Admin/Views/refund/list.volt b/app/Http/Admin/Views/refund/list.volt index ced2cf7e..f21e4301 100644 --- a/app/Http/Admin/Views/refund/list.volt +++ b/app/Http/Admin/Views/refund/list.volt @@ -30,8 +30,8 @@
- + @@ -42,14 +42,14 @@ {% for item in pager.items %} {% set show_url = url({'for':'admin.refund.show','id':item.id}) %} - + diff --git a/app/Http/Admin/Views/refund/search.volt b/app/Http/Admin/Views/refund/search.volt index eab5c260..e52077d3 100644 --- a/app/Http/Admin/Views/refund/search.volt +++ b/app/Http/Admin/Views/refund/search.volt @@ -13,29 +13,29 @@
- +
- + +
+
+
+ +
+ +
+
-
+
+
{% for value,title in status_types %} - + {% endfor %}
-
- -
- -
-
-
-
- -
-
@@ -51,16 +51,14 @@ diff --git a/app/Http/Admin/Views/review/search.volt b/app/Http/Admin/Views/review/search.volt index b2f0271f..29c5dc4a 100644 --- a/app/Http/Admin/Views/review/search.volt +++ b/app/Http/Admin/Views/review/search.volt @@ -13,22 +13,32 @@
- +
- +
- +
- +
+
+
+
+ +
+ +
+
-
+
+
{% for value,title in publish_types %} - + {% endfor %}
@@ -55,4 +65,41 @@ +{% endblock %} + +{% block include_js %} + + {{ js_include('lib/xm-select.js') }} + +{% endblock %} + +{% block inline_js %} + + + {% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/setting/point.volt b/app/Http/Admin/Views/setting/point.volt index 62568942..ba266dcb 100644 --- a/app/Http/Admin/Views/setting/point.volt +++ b/app/Http/Admin/Views/setting/point.volt @@ -36,7 +36,7 @@
行为奖励规则
-
{{ position_info(item.position) }} {{ target_info(item.target) }}
diff --git a/app/Http/Admin/Views/order/list.volt b/app/Http/Admin/Views/order/list.volt index 6e7ac38c..853805ac 100644 --- a/app/Http/Admin/Views/order/list.volt +++ b/app/Http/Admin/Views/order/list.volt @@ -26,14 +26,12 @@
商品信息 买家信息促销类型商品信息 订单金额 订单状态 创建时间
-

名称:{{ item.subject }}

-

单号:{{ item.sn }}

-

昵称:{{ item.owner.name }}

编号:{{ item.owner.id }}

{{ promotion_type(item.promotion_type) }} +

名称:{{ item.subject }}

+

单号:{{ item.sn }}

+
{{ '¥%0.2f'|format(item.amount) }} {{ order_status(item.status) }} {{ date('Y-m-d H:i:s',item.create_time) }}
订单编号:{{ order.sn }} - 促销类型:{{ promotion_type(order.promotion_type) }}
商品信息 买家信息商品信息 退款金额 退款状态 创建时间
-

商品:{{ item.order.subject }}

-

单号:{{ item.order.sn }}

-

昵称:{{ item.owner.name }}

编号:{{ item.owner.id }}

+

商品:{{ item.order.subject }}

+

单号:{{ item.order.sn }}

+
{{ '¥%0.2f'|format(item.amount) }} {{ refund_status(item.status) }} {{ date('Y-m-d H:i:s',item.create_time) }}
+
diff --git a/app/Http/Admin/Views/setting/sms.volt b/app/Http/Admin/Views/setting/sms.volt index f2d8b7a4..1969543b 100644 --- a/app/Http/Admin/Views/setting/sms.volt +++ b/app/Http/Admin/Views/setting/sms.volt @@ -29,7 +29,7 @@
模板配置
-
+
diff --git a/app/Http/Admin/Views/setting/vip.volt b/app/Http/Admin/Views/setting/vip.volt index 3631a9a2..a458e0b5 100644 --- a/app/Http/Admin/Views/setting/vip.volt +++ b/app/Http/Admin/Views/setting/vip.volt @@ -6,7 +6,7 @@
会员设置
-
+
diff --git a/app/Http/Admin/Views/setting/wechat_oa_menu.volt b/app/Http/Admin/Views/setting/wechat_oa_menu.volt index 0c34b148..0fff9af8 100644 --- a/app/Http/Admin/Views/setting/wechat_oa_menu.volt +++ b/app/Http/Admin/Views/setting/wechat_oa_menu.volt @@ -1,5 +1,5 @@ -
+
diff --git a/app/Http/Admin/Views/setting/wechat_oa_notice.volt b/app/Http/Admin/Views/setting/wechat_oa_notice.volt index 2040b9a1..7b86a162 100644 --- a/app/Http/Admin/Views/setting/wechat_oa_notice.volt +++ b/app/Http/Admin/Views/setting/wechat_oa_notice.volt @@ -1,7 +1,7 @@ {% set notice_template = oa.notice_template|json_decode %} -
+
diff --git a/app/Http/Admin/Views/slide/list.volt b/app/Http/Admin/Views/slide/list.volt index 2a3bbd0c..c69ca372 100644 --- a/app/Http/Admin/Views/slide/list.volt +++ b/app/Http/Admin/Views/slide/list.volt @@ -23,7 +23,7 @@ -
+
@@ -56,7 +56,8 @@ - +
{{ target_info(item.target) }} {{ target_attrs_info(item.target_attrs) }}
diff --git a/app/Http/Admin/Views/student/edit.volt b/app/Http/Admin/Views/student/edit.volt deleted file mode 100644 index 0fb3c08f..00000000 --- a/app/Http/Admin/Views/student/edit.volt +++ /dev/null @@ -1,67 +0,0 @@ -{% extends 'templates/main.volt' %} - -{% block content %} - - {% set expiry_editable = relation.source_type in [2,4,5,6] %} - - -
- 编辑学员 -
-
- -
-
{{ course.title }}
-
-
-
- -
-
{{ student.name }}
-
-
- {% if expiry_editable %} -
- -
- -
-
- {% else %} -
- -
-
{{ date('Y-m-d H:i:s',relation.expiry_time) }}
-
-
- {% endif %} -
- -
- - - -
-
- - -{% endblock %} - -{% block inline_js %} - - - -{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/student/learning.volt b/app/Http/Admin/Views/student/learning.volt deleted file mode 100644 index 61d5d226..00000000 --- a/app/Http/Admin/Views/student/learning.volt +++ /dev/null @@ -1,50 +0,0 @@ -{% extends 'templates/main.volt' %} - -{% block content %} - - {{ partial('macros/common') }} - - - - - - - - - - - - - - - - - - {% for item in pager.items %} - {% set duration = item.duration > 0 ? item.duration|duration : 'N/A' %} - {% set active_time = item.active_time > 0 ? date('Y-m-d H:i:s',item.active_time) : 'N/A' %} - - - - - - - {% endfor %} - -
课时信息终端信息学习时长活跃时间
-

课程:{{ item.course.title }}({{ item.course.id }})

-

章节:{{ item.chapter.title }}({{ item.chaper.id }})

-
-

类型:{{ client_type(item.client_type) }}

-

地址:{{ item.client_ip }}

-
{{ duration }}{{ active_time }}
- - {{ partial('partials/pager') }} - -{% endblock %} - -{% block include_js %} - - {{ js_include('admin/js/ip2region.js') }} - -{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/student/list.volt b/app/Http/Admin/Views/student/list.volt deleted file mode 100644 index 7f3dfd71..00000000 --- a/app/Http/Admin/Views/student/list.volt +++ /dev/null @@ -1,135 +0,0 @@ -{% extends 'templates/main.volt' %} - -{% block content %} - - {%- macro source_type_info(value) %} - {% if value == 1 %} - 免费 - {% elseif value == 2 %} - 付费 - {% elseif value == 3 %} - 畅学 - {% elseif value == 4 %} - 导入 - {% elseif value == 5 %} - 积分 - {% elseif value == 6 %} - 抽奖 - {% endif %} - {%- endmacro %} - - {% if course %} - {% set add_url = url({'for':'admin.student.add'},{'course_id':course.id}) %} - {% set search_url = url({'for':'admin.student.search'},{'course_id':course.id}) %} - {% else %} - {% set add_url = url({'for':'admin.student.add'}) %} - {% set search_url = url({'for':'admin.student.search'}) %} - {% endif %} - -
-
- - 返回 - {% if course %} - {{ course.title }} - {% endif %} - 学员管理 - -
- -
- - - - - - - - - - - - - - - - - - - - - - {% for item in pager.items %} - {% set learning_url = url({'for':'admin.student.learning'},{'course_id':item.course_id,'user_id':item.user_id,'plan_id':item.plan_id}) %} - {% set course_url = url({'for':'home.course.show','id':item.course.id}) %} - {% set user_url = url({'for':'home.user.show','id':item.user_id}) %} - {% set edit_url = url({'for':'admin.student.edit'},{'relation_id':item.id}) %} - - - - - - - - - {% endfor %} - -
基本信息学习情况来源类型加入日期有效期限操作
-

课程:{{ item.course.title }}({{ item.course.id }})

-

学员:{{ item.user.name }}({{ item.user.id }})

-
-

进度:{{ item.progress }}%

-

时长:{{ item.duration|duration }}

-
{{ source_type_info(item.source_type) }}{{ date('Y-m-d',item.create_time) }} - {% if item.source_type in [1,3] %} - N/A - {% else %} -

开始:{{ date('Y-m-d',item.create_time) }}

-

结束:{{ date('Y-m-d',item.expiry_time) }}

- {% endif %} -
-
- - -
-
- - {{ partial('partials/pager') }} - -{% endblock %} - -{% block inline_js %} - - - -{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/student/search.volt b/app/Http/Admin/Views/student/search.volt deleted file mode 100644 index 66213406..00000000 --- a/app/Http/Admin/Views/student/search.volt +++ /dev/null @@ -1,63 +0,0 @@ -{% extends 'templates/main.volt' %} - -{% block content %} - -
-
- 搜索学员 -
-
- -
-
-
-
-
- -
- -
-
-
- -
- {% for value,title in source_types %} - - {% endfor %} -
-
-
- -
- - -
-
-
- -{% endblock %} - -{% block include_js %} - - {{ js_include('lib/xm-select.js') }} - -{% endblock %} - -{% block inline_js %} - - - -{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/tag/list.volt b/app/Http/Admin/Views/tag/list.volt index 4ca7498e..e13c8f4e 100644 --- a/app/Http/Admin/Views/tag/list.volt +++ b/app/Http/Admin/Views/tag/list.volt @@ -21,7 +21,7 @@
- +
@@ -30,7 +30,6 @@ - @@ -38,7 +37,6 @@ - @@ -56,12 +54,11 @@ - - +
编号 图标 名称关注 课程 文章 问题{{ item.id }} {{ item.name }} {{ item.name }}{{ item.follow_count }} {{ item.course_count }} {{ item.article_count }} {{ item.question_count }} -
diff --git a/app/Http/Admin/Views/tag/search.volt b/app/Http/Admin/Views/tag/search.volt index c82bc7b0..70bb8ebe 100644 --- a/app/Http/Admin/Views/tag/search.volt +++ b/app/Http/Admin/Views/tag/search.volt @@ -7,17 +7,27 @@ 搜索标签
- +
- +
+
+ +
+ +
+
-
+
+ +
+
@@ -41,4 +51,24 @@
+{% endblock %} + +{% block inline_js %} + + + {% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/topic/edit.volt b/app/Http/Admin/Views/topic/edit.volt index a450e8ee..cd1bfdd7 100644 --- a/app/Http/Admin/Views/topic/edit.volt +++ b/app/Http/Admin/Views/topic/edit.volt @@ -2,7 +2,7 @@ {% block content %} - {% set action_url = url({'for':'admin.topic.update','id':topic.id}) %} + {% set update_url = url({'for':'admin.topic.update','id':topic.id}) %}
编辑专题 diff --git a/app/Http/Admin/Views/topic/edit_basic.volt b/app/Http/Admin/Views/topic/edit_basic.volt index 20740037..f959bd9a 100644 --- a/app/Http/Admin/Views/topic/edit_basic.volt +++ b/app/Http/Admin/Views/topic/edit_basic.volt @@ -1,10 +1,4 @@ -
-
- -
- -
-
+
@@ -15,6 +9,12 @@
+
+ +
+ +
+
diff --git a/app/Http/Admin/Views/topic/edit_course.volt b/app/Http/Admin/Views/topic/edit_course.volt index f303888a..f1262ae4 100644 --- a/app/Http/Admin/Views/topic/edit_course.volt +++ b/app/Http/Admin/Views/topic/edit_course.volt @@ -1,4 +1,4 @@ - +
diff --git a/app/Http/Admin/Views/topic/list.volt b/app/Http/Admin/Views/topic/list.volt index 1e49e4f9..3d60758b 100644 --- a/app/Http/Admin/Views/topic/list.volt +++ b/app/Http/Admin/Views/topic/list.volt @@ -21,23 +21,19 @@
- +
- - - - - + @@ -50,12 +46,11 @@ {% set delete_url = url({'for':'admin.topic.delete','id':item.id}) %} {% set restore_url = url({'for':'admin.topic.restore','id':item.id}) %} - - + - - - + + - - + + @@ -44,16 +44,16 @@ {% for item in pager.items %} {% set show_url = url({'for':'admin.trade.show','id':item.id}) %} - - + +
编号 标题 课程数创建时间更新时间创建 发布 操作
{{ item.id }}{{ item.title }}{{ item.title }}({{ item.id }}) {{ item.course_count }}{{ date('Y-m-d H:i:s',item.create_time) }}{{ date('Y-m-d H:i:s',item.update_time) }}{{ date('Y-m-d',item.create_time) }}
diff --git a/app/Http/Admin/Views/topic/search.volt b/app/Http/Admin/Views/topic/search.volt index 96577795..3d1a4fc0 100644 --- a/app/Http/Admin/Views/topic/search.volt +++ b/app/Http/Admin/Views/topic/search.volt @@ -7,17 +7,27 @@ 搜索专题
- +
- +
+
+ +
+ +
+
-
+
+ +
+
@@ -41,4 +51,24 @@
+{% endblock %} + +{% block inline_js %} + + + {% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/trade/list.volt b/app/Http/Admin/Views/trade/list.volt index a8177d81..d3a35689 100644 --- a/app/Http/Admin/Views/trade/list.volt +++ b/app/Http/Admin/Views/trade/list.volt @@ -31,10 +31,10 @@
商品信息 买家信息交易金额商品信息 交易平台交易金额 交易状态 创建时间 操作
-

商品:{{ item.order.subject }}

-

单号:{{ item.order.sn }}

-

昵称:{{ item.owner.name }}

编号:{{ item.owner.id }}

{{ '¥%0.2f'|format(item.amount) }} +

商品:{{ item.order.subject }}

+

单号:{{ item.order.sn }}

+
{{ channel_type(item.channel) }}{{ '¥%0.2f'|format(item.amount) }} {{ trade_status(item.status) }} {{ date('Y-m-d H:i:s',item.create_time) }} diff --git a/app/Http/Admin/Views/trade/search.volt b/app/Http/Admin/Views/trade/search.volt index d8bc32f2..dfd0f483 100644 --- a/app/Http/Admin/Views/trade/search.volt +++ b/app/Http/Admin/Views/trade/search.volt @@ -13,16 +13,26 @@
- +
- + +
+
+
+ +
+ +
+
-
+
+
{% for value,title in channel_types %} - + {% endfor %}
@@ -30,20 +40,10 @@
{% for value,title in status_types %} - + {% endfor %}
-
- -
- -
-
-
-
- -
-
@@ -59,16 +59,14 @@ + {% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/vip/add.volt b/app/Http/Admin/Views/vip/add.volt new file mode 100644 index 00000000..9e8d9583 --- /dev/null +++ b/app/Http/Admin/Views/vip/add.volt @@ -0,0 +1,35 @@ +{% extends 'templates/main.volt' %} + +{% block content %} + +
+
+ 添加套餐 +
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ + +
+
+
+ +{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/vip/edit.volt b/app/Http/Admin/Views/vip/edit.volt new file mode 100644 index 00000000..b60be3e4 --- /dev/null +++ b/app/Http/Admin/Views/vip/edit.volt @@ -0,0 +1,43 @@ +{% extends 'templates/main.volt' %} + +{% block content %} + +
+
+ 编辑套餐 +
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/flash_sale/list.volt b/app/Http/Admin/Views/vip/list.volt similarity index 52% rename from app/Http/Admin/Views/flash_sale/list.volt rename to app/Http/Admin/Views/vip/list.volt index 9960be4c..36ea6781 100644 --- a/app/Http/Admin/Views/flash_sale/list.volt +++ b/app/Http/Admin/Views/vip/list.volt @@ -2,64 +2,54 @@ {% block content %} - {{ partial('macros/flash_sale') }} - - {% set add_url = url({'for':'admin.flash_sale.add'}) %} - {% set search_url = url({'for':'admin.flash_sale.search'}) %} + {% set add_url = url({'for':'admin.vip.add'}) %} - - +
+ - - + - - - - - + + + + {% for item in pager.items %} - {% set edit_url = url({'for':'admin.flash_sale.edit','id':item.id}) %} - {% set update_url = url({'for':'admin.flash_sale.update','id':item.id}) %} - {% set delete_url = url({'for':'admin.flash_sale.delete','id':item.id}) %} - {% set restore_url = url({'for':'admin.flash_sale.restore','id':item.id}) %} + {% set edit_url = url({'for':'admin.vip.edit','id':item.id}) %} + {% set update_url = url({'for':'admin.vip.update','id':item.id}) %} + {% set delete_url = url({'for':'admin.vip.delete','id':item.id}) %} + {% set restore_url = url({'for':'admin.vip.restore','id':item.id}) %} - + + + - - - - - @@ -48,7 +47,6 @@ 时间:{{ date('Y-m-d',item.create_time) }}

- - + diff --git a/app/Http/Admin/Views/index/main_app_info.volt b/app/Http/Admin/Views/index/main_app_info.volt index 7b59198e..eaa4b24e 100644 --- a/app/Http/Admin/Views/index/main_app_info.volt +++ b/app/Http/Admin/Views/index/main_app_info.volt @@ -12,7 +12,7 @@ - + diff --git a/app/Http/Home/Controllers/TeacherController.php b/app/Http/Home/Controllers/TeacherController.php index 5260f285..91b2ab65 100644 --- a/app/Http/Home/Controllers/TeacherController.php +++ b/app/Http/Home/Controllers/TeacherController.php @@ -8,7 +8,9 @@ namespace App\Http\Home\Controllers; use App\Http\Home\Services\FullH5Url as FullH5UrlService; +use App\Services\Logic\Teacher\CourseList as TeacherCourseListService; use App\Services\Logic\Teacher\TeacherList as TeacherListService; +use App\Services\Logic\User\UserInfo as UserInfoService; use Phalcon\Mvc\View; /** @@ -29,7 +31,7 @@ class TeacherController extends Controller return $this->response->redirect($location); } - $this->seo->prependTitle('师资'); + $this->seo->prependTitle('教师'); } /** @@ -59,11 +61,34 @@ class TeacherController extends Controller return $this->response->redirect($location); } - $this->dispatcher->forward([ - 'controller' => 'user', - 'action' => 'show', - 'params' => ['id' => $id], - ]); + $service = new UserInfoService(); + + $user = $service->handle($id); + + if ($user['deleted'] == 1) { + $this->notFound(); + } + + $this->seo->prependTitle(['讲师', $user['name']]); + + $this->view->setVar('user', $user); + } + + /** + * @Get("/{id:[0-9]+}/courses", name="home.teacher.courses") + */ + public function coursesAction($id) + { + $model = $this->request->getQuery('model', 'trim', 'vod'); + + $service = new TeacherCourseListService(); + + $pager = $service->handle($id); + + $pager->target = "tab-{$model}"; + + $this->view->setRenderLevel(View::LEVEL_ACTION_VIEW); + $this->view->setVar('pager', $pager); } } diff --git a/app/Http/Home/Services/ArticleQuery.php b/app/Http/Home/Services/ArticleQuery.php index 5d587329..fe898d92 100644 --- a/app/Http/Home/Services/ArticleQuery.php +++ b/app/Http/Home/Services/ArticleQuery.php @@ -131,23 +131,22 @@ class ArticleQuery extends Service $validator = new ArticleQueryValidator(); if (isset($query['tag_id'])) { - $validator->checkTag($query['tag_id']); - $params['tag_id'] = $query['tag_id']; + $tag = $validator->checkTag($query['tag_id']); + $params['tag_id'] = $tag->id; } if (isset($query['tc']) && $query['tc'] != 'all') { - $validator->checkCategory($query['tc']); - $params['tc'] = $query['tc']; + $category = $validator->checkCategory($query['tc']); + $params['tc'] = $category->id; } if (isset($query['sc']) && $query['sc'] != 'all') { - $validator->checkCategory($query['sc']); - $params['sc'] = $query['sc']; + $category = $validator->checkCategory($query['sc']); + $params['sc'] = $category->id; } if (isset($query['sort'])) { - $validator->checkSort($query['sort']); - $params['sort'] = $query['sort']; + $params['sort'] = $validator->checkSort($query['sort']);; } return $params; diff --git a/app/Http/Home/Services/CourseQuery.php b/app/Http/Home/Services/CourseQuery.php index 11db94bb..6c0d8fe2 100644 --- a/app/Http/Home/Services/CourseQuery.php +++ b/app/Http/Home/Services/CourseQuery.php @@ -7,7 +7,6 @@ namespace App\Http\Home\Services; -use App\Caches\Category as CategoryCache; use App\Models\Category as CategoryModel; use App\Models\Course as CourseModel; use App\Services\Category as CategoryService; @@ -187,32 +186,6 @@ class CourseQuery extends Service return $result; } - public function handleCategoryPaths($categoryId) - { - $result = []; - - $cache = new CategoryCache(); - - $subCategory = $cache->get($categoryId); - $topCategory = $cache->get($subCategory->parent_id); - - $topParams = ['tc' => $topCategory->id]; - - $result['top'] = [ - 'name' => $topCategory->name, - 'url' => $this->baseUrl . $this->buildParams($topParams), - ]; - - $subParams = ['tc' => $topCategory->id, 'sc' => $subCategory->id]; - - $result['sub'] = [ - 'name' => $subCategory->name, - 'url' => $this->baseUrl . $this->buildParams($subParams), - ]; - - return $result; - } - public function getParams() { $query = $this->request->getQuery(); @@ -221,29 +194,31 @@ class CourseQuery extends Service $validator = new CourseQueryValidator(); + if (isset($query['tag_id'])) { + $tag = $validator->checkTag($query['tag_id']); + $params['tag_id'] = $tag->id; + } + if (isset($query['tc']) && $query['tc'] != 'all') { - $validator->checkTopCategory($query['tc']); - $params['tc'] = $query['tc']; + $category = $validator->checkCategory($query['tc']); + $params['tc'] = $category->id; } if (isset($query['sc']) && $query['sc'] != 'all') { - $validator->checkSubCategory($query['sc']); - $params['sc'] = $query['sc']; + $category = $validator->checkCategory($query['sc']); + $params['sc'] = $category->id; } if (isset($query['model']) && $query['model'] != 'all') { - $validator->checkModel($query['model']); - $params['model'] = $query['model']; + $params['model'] = $validator->checkModel($query['model']); } if (isset($query['level']) && $query['level'] != 'all') { - $validator->checkLevel($query['level']); - $params['level'] = $query['level']; + $params['level'] = $validator->checkLevel($query['level']); } if (isset($query['sort'])) { - $validator->checkSort($query['sort']); - $params['sort'] = $query['sort']; + $params['sort'] = $validator->checkSort($query['sort']); } return $params; diff --git a/app/Http/Home/Services/QuestionQuery.php b/app/Http/Home/Services/QuestionQuery.php index bea74aee..4a71dad1 100644 --- a/app/Http/Home/Services/QuestionQuery.php +++ b/app/Http/Home/Services/QuestionQuery.php @@ -131,23 +131,22 @@ class QuestionQuery extends Service $validator = new QuestionQueryValidator(); if (isset($query['tag_id'])) { - $validator->checkTag($query['tag_id']); - $params['tag_id'] = $query['tag_id']; + $tag = $validator->checkTag($query['tag_id']); + $params['tag_id'] = $tag->id; } if (isset($query['tc']) && $query['tc'] != 'all') { - $validator->checkCategory($query['tc']); - $params['tc'] = $query['tc']; + $category = $validator->checkCategory($query['tc']); + $params['tc'] = $category->id; } if (isset($query['sc']) && $query['sc'] != 'all') { - $validator->checkCategory($query['sc']); - $params['sc'] = $query['sc']; + $category = $validator->checkCategory($query['sc']); + $params['sc'] = $category->id; } if (isset($query['sort'])) { - $validator->checkSort($query['sort']); - $params['sort'] = $query['sort']; + $params['sort'] = $validator->checkSort($query['sort']);; } return $params; diff --git a/app/Http/Home/Views/course/show_teacher.volt b/app/Http/Home/Views/course/show_teacher.volt index e5e18a3d..e10b581c 100644 --- a/app/Http/Home/Views/course/show_teacher.volt +++ b/app/Http/Home/Views/course/show_teacher.volt @@ -4,7 +4,7 @@
授课教师
- {% set teacher_url = url({'for':'home.user.show','id':teacher.id}) %} + {% set teacher_url = url({'for':'home.teacher.show','id':teacher.id}) %}
商品信息秒杀价格秒杀库存秒杀时间参与场次编号套餐名称套餐期限(月)套餐价格 发布 操作
{{ item_full_info(item.item_type,item.item_info) }}{{ item.id }}{{ item.title }}{{ item.expiry }} {{ '¥%0.2f'|format(item.price) }}{{ item.stock }} -

开始:{{ date('Y-m-d H:i:s',item.start_time) }}

-

结束:{{ date('Y-m-d H:i:s',item.end_time) }}

+
{{ schedules_info(item.schedules) }}
diff --git a/app/Http/Api/Controllers/ArticleController.php b/app/Http/Api/Controllers/ArticleController.php index c61ac491..af7b9d74 100644 --- a/app/Http/Api/Controllers/ArticleController.php +++ b/app/Http/Api/Controllers/ArticleController.php @@ -14,7 +14,6 @@ use App\Services\Logic\Article\ArticleFavorite as ArticleFavoriteService; use App\Services\Logic\Article\ArticleInfo as ArticleInfoService; use App\Services\Logic\Article\ArticleLike as ArticleLikeService; use App\Services\Logic\Article\ArticleList as ArticleListService; -use App\Services\Logic\Article\ArticlePrivate as ArticlePrivateService; use App\Services\Logic\Article\CategoryList as CategoryListService; use App\Services\Logic\Article\CommentList as CommentListService; @@ -63,16 +62,11 @@ class ArticleController extends Controller $approved = $article['published'] == ArticleModel::PUBLISH_APPROVED; $owned = $article['me']['owned'] == 1; - $private = $article['private'] == 1; if (!$approved && !$owned) { $this->notFound(); } - if ($private && !$owned) { - $this->forbidden(); - } - return $this->jsonSuccess(['article' => $article]); } @@ -114,20 +108,6 @@ class ArticleController extends Controller return $this->jsonSuccess(['msg' => $msg]); } - /** - * @Post("/{id:[0-9]+}/private", name="home.article.private") - */ - public function privateAction($id) - { - $service = new ArticlePrivateService(); - - $article = $service->handle($id); - - $msg = $article->private == 1 ? '开启仅我可见成功' : '关闭仅我可见成功'; - - return $this->jsonSuccess(['msg' => $msg]); - } - /** * @Post("/{id:[0-9]+}/favorite", name="api.article.favorite") */ diff --git a/app/Http/Api/Controllers/FlashSaleController.php b/app/Http/Api/Controllers/FlashSaleController.php deleted file mode 100644 index b6b7f46d..00000000 --- a/app/Http/Api/Controllers/FlashSaleController.php +++ /dev/null @@ -1,48 +0,0 @@ -handle(); - - return $this->jsonSuccess(['sales' => $sales]); - } - - /** - * @Post("/order", name="api.flash_sale.order") - */ - public function orderAction() - { - $service = new OrderCreateService(); - - $order = $service->handle(); - - $service = new OrderInfoService(); - - $order = $service->handle($order->sn); - - return $this->jsonSuccess(['order' => $order]); - } - -} diff --git a/app/Http/Api/Controllers/IndexController.php b/app/Http/Api/Controllers/IndexController.php index d6efa30c..b288df8c 100644 --- a/app/Http/Api/Controllers/IndexController.php +++ b/app/Http/Api/Controllers/IndexController.php @@ -84,18 +84,6 @@ class IndexController extends Controller return $this->jsonSuccess(['teachers' => $teachers]); } - /** - * @Get("/flash/sales", name="api.index.flash_sales") - */ - public function flashSalesAction() - { - $cache = new IndexFlashSaleList(); - - $sales = $cache->get(); - - return $this->jsonSuccess(['sales' => $sales]); - } - /** * @Get("/courses/featured", name="api.index.featured_courses") */ diff --git a/app/Http/Home/Controllers/ArticleController.php b/app/Http/Home/Controllers/ArticleController.php index e22dc7fa..f6effe5a 100644 --- a/app/Http/Home/Controllers/ArticleController.php +++ b/app/Http/Home/Controllers/ArticleController.php @@ -18,7 +18,6 @@ use App\Services\Logic\Article\ArticleFavorite as ArticleFavoriteService; use App\Services\Logic\Article\ArticleInfo as ArticleInfoService; use App\Services\Logic\Article\ArticleLike as ArticleLikeService; use App\Services\Logic\Article\ArticleList as ArticleListService; -use App\Services\Logic\Article\ArticlePrivate as ArticlePrivateService; use App\Services\Logic\Article\ArticleUpdate as ArticleUpdateService; use App\Services\Logic\Article\RelatedArticleList as RelatedArticleListService; use Phalcon\Mvc\View; @@ -43,11 +42,15 @@ class ArticleController extends Controller $service = new ArticleQueryService(); + $topCategories = $service->handleTopCategories(); + $subCategories = $service->handleSubCategories(); $sorts = $service->handleSorts(); $params = $service->getParams(); $this->seo->prependTitle('专栏'); + $this->view->setVar('top_categories', $topCategories); + $this->view->setVar('sub_categories', $subCategories); $this->view->setVar('sorts', $sorts); $this->view->setVar('params', $params); } @@ -74,16 +77,18 @@ class ArticleController extends Controller { $service = new ArticleService(); - $sourceTypes = $service->getSourceTypes(); $article = $service->getArticleModel(); + $categoryOptions = $service->getCategoryOptions(); + $sourceTypes = $service->getSourceTypes(); $xmTags = $service->getXmTags(0); $this->seo->prependTitle('撰写文章'); $this->view->pick('article/edit'); + $this->view->setVar('article', $article); + $this->view->setVar('category_options', $categoryOptions); $this->view->setVar('source_types', $sourceTypes); $this->view->setVar('xm_tags', $xmTags); - $this->view->setVar('article', $article); } /** @@ -93,14 +98,16 @@ class ArticleController extends Controller { $service = new ArticleService(); + $categoryOptions = $service->getCategoryOptions(); $sourceTypes = $service->getSourceTypes(); $article = $service->getArticle($id); $xmTags = $service->getXmTags($id); $this->seo->prependTitle('编辑文章'); - $this->view->setVar('source_types', $sourceTypes); $this->view->setVar('article', $article); + $this->view->setVar('category_options', $categoryOptions); + $this->view->setVar('source_types', $sourceTypes); $this->view->setVar('xm_tags', $xmTags); } @@ -126,16 +133,11 @@ class ArticleController extends Controller $approved = $article['published'] == ArticleModel::PUBLISH_APPROVED; $owned = $article['me']['owned'] == 1; - $private = $article['private'] == 1; if (!$approved && !$owned) { $this->notFound(); } - if ($private && !$owned) { - $this->forbidden(); - } - $this->seo->prependTitle(['专栏', $article['title']]); $this->seo->setDescription($article['summary']); @@ -238,20 +240,6 @@ class ArticleController extends Controller return $this->jsonSuccess(['msg' => $msg]); } - /** - * @Post("/{id:[0-9]+}/private", name="home.article.private") - */ - public function privateAction($id) - { - $service = new ArticlePrivateService(); - - $article = $service->handle($id); - - $msg = $article->private == 1 ? '开启仅我可见成功' : '关闭仅我可见成功'; - - return $this->jsonSuccess(['msg' => $msg]); - } - /** * @Post("/{id:[0-9]+}/favorite", name="home.article.favorite") */ diff --git a/app/Http/Home/Controllers/DanmuController.php b/app/Http/Home/Controllers/DanmuController.php deleted file mode 100644 index 16e3a0e9..00000000 --- a/app/Http/Home/Controllers/DanmuController.php +++ /dev/null @@ -1,35 +0,0 @@ -handle(); - - $service = new DanmuInfoService(); - - $danmu = $service->handle($danmu->id); - - return $this->jsonSuccess(['danmu' => $danmu]); - } - -} diff --git a/app/Http/Home/Controllers/FlashSaleController.php b/app/Http/Home/Controllers/FlashSaleController.php deleted file mode 100644 index d5d26620..00000000 --- a/app/Http/Home/Controllers/FlashSaleController.php +++ /dev/null @@ -1,63 +0,0 @@ -authUser->id == 0) { - $this->response->redirect(['for' => 'home.account.login']); - return false; - } - - return true; - } - - /** - * @Get("/", name="home.flash_sale.index") - */ - public function indexAction() - { - $this->seo->prependTitle('秒杀'); - - $service = new SaleListService(); - - $sales = $service->handle(); - - $this->view->setVar('sales', $sales); - } - - /** - * @Post("/order", name="home.flash_sale.order") - */ - public function orderAction() - { - $service = new OrderCreateService(); - - $order = $service->handle(); - - $location = $this->url->get( - ['for' => 'home.order.pay'], - ['sn' => $order->sn] - ); - - return $this->jsonSuccess(['location' => $location]); - } - -} diff --git a/app/Http/Home/Controllers/QuestionController.php b/app/Http/Home/Controllers/QuestionController.php index a9f8526a..eeb603e4 100644 --- a/app/Http/Home/Controllers/QuestionController.php +++ b/app/Http/Home/Controllers/QuestionController.php @@ -42,11 +42,15 @@ class QuestionController extends Controller $service = new QuestionQueryService(); + $topCategories = $service->handleTopCategories(); + $subCategories = $service->handleSubCategories(); $sorts = $service->handleSorts(); $params = $service->getParams(); $this->seo->prependTitle('问答'); + $this->view->setVar('top_categories', $topCategories); + $this->view->setVar('sub_categories', $subCategories); $this->view->setVar('sorts', $sorts); $this->view->setVar('params', $params); } @@ -74,13 +78,14 @@ class QuestionController extends Controller $service = new QuestionService(); $question = $service->getQuestionModel(); - + $categoryOptions = $service->getCategoryOptions(); $xmTags = $service->getXmTags(0); $this->seo->prependTitle('提问'); $this->view->pick('question/edit'); $this->view->setVar('question', $question); + $this->view->setVar('category_options', $categoryOptions); $this->view->setVar('xm_tags', $xmTags); } @@ -92,12 +97,13 @@ class QuestionController extends Controller $service = new QuestionService(); $question = $service->getQuestion($id); - + $categoryOptions = $service->getCategoryOptions(); $xmTags = $service->getXmTags($id); $this->seo->prependTitle('编辑问题'); $this->view->setVar('question', $question); + $this->view->setVar('category_options', $categoryOptions); $this->view->setVar('xm_tags', $xmTags); } diff --git a/app/Http/Home/Controllers/UserController.php b/app/Http/Home/Controllers/UserController.php index 7e141f01..a1bb9b61 100644 --- a/app/Http/Home/Controllers/UserController.php +++ b/app/Http/Home/Controllers/UserController.php @@ -11,8 +11,6 @@ use App\Http\Home\Services\FullH5Url as FullH5UrlService; use App\Services\Logic\User\AnswerList as UserAnswerListService; use App\Services\Logic\User\ArticleList as UserArticleListService; use App\Services\Logic\User\CourseList as UserCourseListService; -use App\Services\Logic\User\FriendList as UserFriendListService; -use App\Services\Logic\User\GroupList as UserGroupListService; use App\Services\Logic\User\QuestionList as UserQuestionListService; use App\Services\Logic\User\UserInfo as UserInfoService; use Phalcon\Mvc\View; @@ -112,36 +110,4 @@ class UserController extends Controller $this->view->setVar('pager', $pager); } - /** - * @Get("/{id:[0-9]+}/friends", name="home.user.friends") - */ - public function friendsAction($id) - { - $service = new UserFriendListService(); - - $pager = $service->handle($id); - - $pager->target = 'tab-friends'; - - $this->view->setRenderLevel(View::LEVEL_ACTION_VIEW); - $this->view->pick('user/friends'); - $this->view->setVar('pager', $pager); - } - - /** - * @Get("/{id:[0-9]+}/groups", name="home.user.groups") - */ - public function groupsAction($id) - { - $service = new UserGroupListService(); - - $pager = $service->handle($id); - - $pager->target = 'tab-groups'; - - $this->view->setRenderLevel(View::LEVEL_ACTION_VIEW); - $this->view->pick('user/groups'); - $this->view->setVar('pager', $pager); - } - } diff --git a/app/Http/Home/Services/Article.php b/app/Http/Home/Services/Article.php index 7264c9d4..496e4f47 100644 --- a/app/Http/Home/Services/Article.php +++ b/app/Http/Home/Services/Article.php @@ -9,8 +9,7 @@ namespace App\Http\Home\Services; use App\Models\Article as ArticleModel; use App\Models\Category as CategoryModel; -use App\Models\Reason as ReasonModel; -use App\Repos\Category as CategoryRepo; +use App\Services\Category as CategoryService; use App\Services\Logic\Article\XmTagList as XmTagListService; use App\Services\Logic\ArticleTrait; @@ -35,15 +34,11 @@ class Article extends Service return $service->handle($id); } - public function getCategories() + public function getCategoryOptions() { - $categoryRepo = new CategoryRepo(); + $categoryService = new CategoryService(); - return $categoryRepo->findAll([ - 'type' => CategoryModel::TYPE_ARTICLE, - 'level' => 1, - 'published' => 1, - ]); + return $categoryService->getCategoryOptions(CategoryModel::TYPE_ARTICLE); } public function getSourceTypes() @@ -51,11 +46,6 @@ class Article extends Service return ArticleModel::sourceTypes(); } - public function getReportReasons() - { - return ReasonModel::reportOptions(); - } - public function getArticle($id) { return $this->checkArticle($id); diff --git a/app/Http/Home/Services/ArticleQuery.php b/app/Http/Home/Services/ArticleQuery.php index 2ae41942..5d587329 100644 --- a/app/Http/Home/Services/ArticleQuery.php +++ b/app/Http/Home/Services/ArticleQuery.php @@ -22,12 +22,16 @@ class ArticleQuery extends Service $this->baseUrl = $this->url->get(['for' => 'home.article.list']); } - public function handleCategories() + public function handleTopCategories() { $params = $this->getParams(); - if (isset($params['category_id'])) { - unset($params['category_id']); + if (isset($params['tc'])) { + unset($params['tc']); + } + + if (isset($params['sc'])) { + unset($params['sc']); } $defaultItem = [ @@ -44,8 +48,50 @@ class ArticleQuery extends Service $topCategories = $categoryService->getChildCategories(CategoryModel::TYPE_ARTICLE, 0); - foreach ($topCategories as $key => $category) { - $params['category_id'] = $category['id']; + foreach ($topCategories as $category) { + $params['tc'] = $category['id']; + $result[] = [ + 'id' => $category['id'], + 'name' => $category['name'], + 'url' => $this->baseUrl . $this->buildParams($params), + ]; + } + + return $result; + } + + public function handleSubCategories() + { + $params = $this->getParams(); + + if (empty($params['tc'])) { + return []; + } + + $categoryService = new CategoryService(); + + $subCategories = $categoryService->getChildCategories(CategoryModel::TYPE_ARTICLE, $params['tc']); + + if (empty($subCategories)) { + return []; + } + + if (isset($params['sc'])) { + unset($params['sc']); + } + + $defaultItem = [ + 'id' => 'all', + 'name' => '全部', + 'url' => $this->baseUrl . $this->buildParams($params), + ]; + + $result = []; + + $result[] = $defaultItem; + + foreach ($subCategories as $category) { + $params['sc'] = $category['id']; $result[] = [ 'id' => $category['id'], 'name' => $category['name'], @@ -84,16 +130,21 @@ class ArticleQuery extends Service $validator = new ArticleQueryValidator(); - if (isset($query['category_id']) && $query['category_id'] != 'all') { - $validator->checkCategory($query['category_id']); - $params['category_id'] = $query['category_id']; - } - if (isset($query['tag_id'])) { $validator->checkTag($query['tag_id']); $params['tag_id'] = $query['tag_id']; } + if (isset($query['tc']) && $query['tc'] != 'all') { + $validator->checkCategory($query['tc']); + $params['tc'] = $query['tc']; + } + + if (isset($query['sc']) && $query['sc'] != 'all') { + $validator->checkCategory($query['sc']); + $params['sc'] = $query['sc']; + } + if (isset($query['sort'])) { $validator->checkSort($query['sort']); $params['sort'] = $query['sort']; diff --git a/app/Http/Home/Services/Question.php b/app/Http/Home/Services/Question.php index 3e541ac0..bfcdea34 100644 --- a/app/Http/Home/Services/Question.php +++ b/app/Http/Home/Services/Question.php @@ -9,7 +9,7 @@ namespace App\Http\Home\Services; use App\Models\Category as CategoryModel; use App\Models\Question as QuestionModel; -use App\Repos\Category as CategoryRepo; +use App\Services\Category as CategoryService; use App\Services\Logic\Question\XmTagList as XmTagListService; use App\Services\Logic\QuestionTrait; use App\Services\Logic\Service as LogicService; @@ -28,15 +28,11 @@ class Question extends LogicService return $question; } - public function getCategories() + public function getCategoryOptions() { - $categoryRepo = new CategoryRepo(); + $categoryService = new CategoryService(); - return $categoryRepo->findAll([ - 'type' => CategoryModel::TYPE_ARTICLE, - 'level' => 1, - 'published' => 1, - ]); + return $categoryService->getCategoryOptions(CategoryModel::TYPE_QUESTION); } public function getXmTags($id) diff --git a/app/Http/Home/Services/QuestionQuery.php b/app/Http/Home/Services/QuestionQuery.php index d4b99971..bea74aee 100644 --- a/app/Http/Home/Services/QuestionQuery.php +++ b/app/Http/Home/Services/QuestionQuery.php @@ -22,12 +22,16 @@ class QuestionQuery extends Service $this->baseUrl = $this->url->get(['for' => 'home.question.list']); } - public function handleCategories() + public function handleTopCategories() { $params = $this->getParams(); - if (isset($params['category_id'])) { - unset($params['category_id']); + if (isset($params['tc'])) { + unset($params['tc']); + } + + if (isset($params['sc'])) { + unset($params['sc']); } $defaultItem = [ @@ -44,8 +48,50 @@ class QuestionQuery extends Service $topCategories = $categoryService->getChildCategories(CategoryModel::TYPE_QUESTION, 0); - foreach ($topCategories as $key => $category) { - $params['category_id'] = $category['id']; + foreach ($topCategories as $category) { + $params['tc'] = $category['id']; + $result[] = [ + 'id' => $category['id'], + 'name' => $category['name'], + 'url' => $this->baseUrl . $this->buildParams($params), + ]; + } + + return $result; + } + + public function handleSubCategories() + { + $params = $this->getParams(); + + if (empty($params['tc'])) { + return []; + } + + $categoryService = new CategoryService(); + + $subCategories = $categoryService->getChildCategories(CategoryModel::TYPE_QUESTION, $params['tc']); + + if (empty($subCategories)) { + return []; + } + + if (isset($params['sc'])) { + unset($params['sc']); + } + + $defaultItem = [ + 'id' => 'all', + 'name' => '全部', + 'url' => $this->baseUrl . $this->buildParams($params), + ]; + + $result = []; + + $result[] = $defaultItem; + + foreach ($subCategories as $category) { + $params['sc'] = $category['id']; $result[] = [ 'id' => $category['id'], 'name' => $category['name'], @@ -84,16 +130,21 @@ class QuestionQuery extends Service $validator = new QuestionQueryValidator(); - if (isset($query['category_id']) && $query['category_id'] != 'all') { - $validator->checkCategory($query['category_id']); - $params['category_id'] = $query['category_id']; - } - if (isset($query['tag_id'])) { $validator->checkTag($query['tag_id']); $params['tag_id'] = $query['tag_id']; } + if (isset($query['tc']) && $query['tc'] != 'all') { + $validator->checkCategory($query['tc']); + $params['tc'] = $query['tc']; + } + + if (isset($query['sc']) && $query['sc'] != 'all') { + $validator->checkCategory($query['sc']); + $params['sc'] = $query['sc']; + } + if (isset($query['sort'])) { $validator->checkSort($query['sort']); $params['sort'] = $query['sort']; diff --git a/app/Http/Home/Views/article/edit.volt b/app/Http/Home/Views/article/edit.volt index 911072bb..df148410 100644 --- a/app/Http/Home/Views/article/edit.volt +++ b/app/Http/Home/Views/article/edit.volt @@ -2,7 +2,7 @@ {% block content %} - {% set title = article.id > 0 ? '编辑文章' : '撰写文章' %} + {% set title = article.id > 0 ? '编辑文章' : '发布文章' %} {% set action_url = article.id > 0 ? url({'for':'home.article.update','id':article.id}) : url({'for':'home.article.create'}) %} {% set source_url_display = article.source_type == 1 ? 'display:none;' : 'display:block;' %} @@ -29,7 +29,19 @@
- + +
+ +
+
+
+
diff --git a/app/Http/Home/Views/article/list.volt b/app/Http/Home/Views/article/list.volt index 11fe75e8..16a1859e 100644 --- a/app/Http/Home/Views/article/list.volt +++ b/app/Http/Home/Views/article/list.volt @@ -2,17 +2,14 @@ {% block content %} - {% set sort_val = request.get('sort','trim','latest') %} + {% if top_categories|length > 1 %} + {{ partial('article/list_filter') }} + {% endif %} + + {% set post_url = url({'for':'home.article.add'}) %} {% set pager_url = url({'for':'home.article.pager'}, params) %} {% set top_authors_url = url({'for':'home.widget.top_authors'},{'limit':5}) %} - {% set my_tags_url = url({'for':'home.widget.my_tags'},{'type':'article'}) %} - - + {% set sort_val = request.get('sort','trim','latest') %}
@@ -33,9 +30,9 @@
- {% if auth_user.id > 0 %} - - {% endif %} +
@@ -44,6 +41,7 @@ {% block include_js %} + {{ js_include('home/js/list.filter.js') }} {{ js_include('home/js/article.list.js') }} {% endblock %} \ No newline at end of file diff --git a/app/Http/Home/Views/article/list_filter.volt b/app/Http/Home/Views/article/list_filter.volt new file mode 100644 index 00000000..c38d092c --- /dev/null +++ b/app/Http/Home/Views/article/list_filter.volt @@ -0,0 +1,32 @@ +{% set tc_val = request.get('tc','int','all') %} +{% set sc_val = request.get('sc','int','all') %} +{% set sort_val = request.get('sort','trim','latest') %} + +
+ +
+ +
+ {% if top_categories %} +
+
方向
+
+ {% for category in top_categories %} + {% set class = tc_val == category.id ? 'layui-btn layui-btn-xs' : 'none' %} + {{ category.name }} + {% endfor %} +
+
+ {% endif %} + {% if sub_categories %} +
+
分类
+
+ {% for category in sub_categories %} + {% set class = sc_val == category.id ? 'layui-btn layui-btn-xs' : 'none' %} + {{ category.name }} + {% endfor %} +
+
+ {% endif %} +
diff --git a/app/Http/Home/Views/article/show.volt b/app/Http/Home/Views/article/show.volt index 98dbb75c..6f128ead 100644 --- a/app/Http/Home/Views/article/show.volt +++ b/app/Http/Home/Views/article/show.volt @@ -8,7 +8,6 @@ {% set qrcode_url = url({'for':'home.qrcode'},{'text':share_url}) %} {% set article_edit_url = url({'for':'home.article.edit','id':article.id}) %} {% set article_delete_url = url({'for':'home.article.delete','id':article.id}) %} - {% set article_private_url = url({'for':'home.article.private','id':article.id}) %} {% set article_close_url = url({'for':'home.article.close','id':article.id}) %} {% set article_owner_url = url({'for':'home.user.show','id':article.owner.id}) %} {% set article_related_url = url({'for':'home.article.related','id':article.id}) %} @@ -21,9 +20,10 @@ 详情
@@ -44,17 +44,12 @@
举报 - {% if auth_user.id == article.owner.id %} + {% if article.me.owned == 1 %} {% if article.closed == 0 %} 关闭 {% else %} 打开 {% endif %} - {% if article.private == 0 %} - 私密 - {% else %} - 共享 - {% endif %} 编辑 删除 {% endif %} @@ -121,8 +116,10 @@ {% block include_js %} + {{ js_include('lib/clipboard.min.js') }} {{ js_include('home/js/article.show.js') }} {{ js_include('home/js/article.share.js') }} {{ js_include('home/js/comment.js') }} + {{ js_include('home/js/copy.js') }} {% endblock %} \ No newline at end of file diff --git a/app/Http/Home/Views/chapter/live/active.volt b/app/Http/Home/Views/chapter/live/active.volt index 6e7b6d35..393d7e69 100644 --- a/app/Http/Home/Views/chapter/live/active.volt +++ b/app/Http/Home/Views/chapter/live/active.volt @@ -53,9 +53,9 @@
- +
@@ -71,11 +71,13 @@ {% block include_js %} + {{ js_include('lib/clipboard.min.js') }} {{ js_include('lib/dplayer/flv.min.js') }} {{ js_include('lib/dplayer/DPlayer.min.js') }} {{ js_include('home/js/chapter.live.player.js') }} {{ js_include('home/js/chapter.live.chat.js') }} {{ js_include('home/js/chapter.show.js') }} {{ js_include('home/js/course.share.js') }} + {{ js_include('home/js/copy.js') }} {% endblock %} \ No newline at end of file diff --git a/app/Http/Home/Views/chapter/read.volt b/app/Http/Home/Views/chapter/read.volt index 9624486a..b2380bbe 100644 --- a/app/Http/Home/Views/chapter/read.volt +++ b/app/Http/Home/Views/chapter/read.volt @@ -12,9 +12,10 @@ 返回课程
@@ -42,8 +43,8 @@
- +
@@ -63,9 +64,11 @@ {% block include_js %} + {{ js_include('lib/clipboard.min.js') }} {{ js_include('home/js/course.share.js') }} {{ js_include('home/js/chapter.read.js') }} {{ js_include('home/js/chapter.show.js') }} {{ js_include('home/js/comment.js') }} + {{ js_include('home/js/copy.js') }} {% endblock %} \ No newline at end of file diff --git a/app/Http/Home/Views/chapter/vod.volt b/app/Http/Home/Views/chapter/vod.volt index 0226cd4d..2bdde288 100644 --- a/app/Http/Home/Views/chapter/vod.volt +++ b/app/Http/Home/Views/chapter/vod.volt @@ -13,9 +13,10 @@ {{ chapter.title }}
@@ -43,10 +44,11 @@
- - + + +
@@ -60,11 +62,13 @@ {% block include_js %} + {{ js_include('lib/clipboard.min.js') }} {{ js_include('lib/dplayer/hls.min.js') }} {{ js_include('lib/dplayer/DPlayer.min.js') }} {{ js_include('home/js/course.share.js') }} {{ js_include('home/js/chapter.show.js') }} {{ js_include('home/js/chapter.vod.player.js') }} {{ js_include('home/js/comment.js') }} + {{ js_include('home/js/copy.js') }} {% endblock %} \ No newline at end of file diff --git a/app/Http/Home/Views/course/list.volt b/app/Http/Home/Views/course/list.volt index 59134b89..fbedd877 100644 --- a/app/Http/Home/Views/course/list.volt +++ b/app/Http/Home/Views/course/list.volt @@ -2,7 +2,9 @@ {% block content %} - {{ partial('course/list_filter') }} + {% if top_categories|length > 1 %} + {{ partial('course/list_filter') }} + {% endif %} {% set pager_url = url({'for':'home.course.pager'}, params) %} @@ -12,6 +14,7 @@ {% block include_js %} + {{ js_include('home/js/list.filter.js') }} {{ js_include('home/js/course.list.js') }} {% endblock %} \ No newline at end of file diff --git a/app/Http/Home/Views/course/list_filter.volt b/app/Http/Home/Views/course/list_filter.volt index 4f919e64..2f71026c 100644 --- a/app/Http/Home/Views/course/list_filter.volt +++ b/app/Http/Home/Views/course/list_filter.volt @@ -8,16 +8,18 @@
-
-
-
方向
-
- {% for category in top_categories %} - {% set class = tc_val == category.id ? 'layui-btn layui-btn-xs' : 'none' %} - {{ category.name }} - {% endfor %} +
+ {% if top_categories %} +
+
方向
+
+ {% for category in top_categories %} + {% set class = tc_val == category.id ? 'layui-btn layui-btn-xs' : 'none' %} + {{ category.name }} + {% endfor %} +
-
+ {% endif %} {% if sub_categories %}
分类
@@ -49,7 +51,7 @@
-
+
{% for sort in sorts %} {% set class = sort_val == sort.id ? 'layui-btn layui-btn-xs' : 'none' %} {{ sort.name }} diff --git a/app/Http/Home/Views/course/show.volt b/app/Http/Home/Views/course/show.volt index b03dcb0d..11353557 100644 --- a/app/Http/Home/Views/course/show.volt +++ b/app/Http/Home/Views/course/show.volt @@ -14,9 +14,10 @@ {{ course.title }}
@@ -121,7 +122,9 @@ {% block include_js %} + {{ js_include('lib/clipboard.min.js') }} {{ js_include('home/js/course.show.js') }} {{ js_include('home/js/course.share.js') }} + {{ js_include('home/js/copy.js') }} {% endblock %} \ No newline at end of file diff --git a/app/Http/Home/Views/course/show_order.volt b/app/Http/Home/Views/course/show_order.volt index f5ab79d3..0aba8192 100644 --- a/app/Http/Home/Views/course/show_order.volt +++ b/app/Http/Home/Views/course/show_order.volt @@ -6,7 +6,7 @@ {% elseif course.me.allow_order == 1 %} {% set order_url = url({'for':'home.order.confirm'},{'item_id':course.id,'item_type':1}) %} {% endif %} diff --git a/app/Http/Home/Views/course/show_teacher.volt b/app/Http/Home/Views/course/show_teacher.volt index cbe0dfc3..e5e18a3d 100644 --- a/app/Http/Home/Views/course/show_teacher.volt +++ b/app/Http/Home/Views/course/show_teacher.volt @@ -1,22 +1,21 @@ -{% if course.teachers %} +{% if course.teacher %} + {% set teacher = course.teacher %}
diff --git a/app/Http/Home/Views/question/answers.volt b/app/Http/Home/Views/question/answers.volt index 4eff911f..4a0ac9b3 100644 --- a/app/Http/Home/Views/question/answers.volt +++ b/app/Http/Home/Views/question/answers.volt @@ -2,7 +2,7 @@ {% if pager.total_pages > 0 %} {% for item in pager.items %} - {{ answer_card(item,auth_user) }} + {{ answer_card(item) }} {% endfor %} {{ partial('partials/pager_ajax') }} {% endif %} \ No newline at end of file diff --git a/app/Http/Home/Views/question/edit.volt b/app/Http/Home/Views/question/edit.volt index 7d8317c0..385f34f6 100644 --- a/app/Http/Home/Views/question/edit.volt +++ b/app/Http/Home/Views/question/edit.volt @@ -28,7 +28,19 @@
- + +
+ +
+
+
+
diff --git a/app/Http/Home/Views/question/list.volt b/app/Http/Home/Views/question/list.volt index d5455c69..d196c1a3 100644 --- a/app/Http/Home/Views/question/list.volt +++ b/app/Http/Home/Views/question/list.volt @@ -2,18 +2,15 @@ {% block content %} - {% set sort_val = request.get('sort','trim','latest') %} - {% set pager_url = url({'for':'home.question.pager'}, params) %} - {% set hot_questions_url = url({'for':'home.widget.hot_questions'},{'limit':10}) %} - {% set top_answerers_url = url({'for':'home.widget.top_answerers'},{'limit':5}) %} - {% set my_tags_url = url({'for':'home.widget.my_tags'},{'type':'question'}) %} + {% if top_categories|length > 1 %} + {{ partial('question/list_filter') }} + {% endif %} - + {% set ask_url = url({'for':'home.question.add'}) %} + {% set pager_url = url({'for':'home.question.pager'}, params) %} + {% set hot_questions_url = url({'for':'home.widget.hot_questions'},{'limit':5}) %} + {% set top_answerers_url = url({'for':'home.widget.top_answerers'},{'limit':5}) %} + {% set sort_val = request.get('sort','trim','latest') %}
@@ -34,9 +31,9 @@
- {% if auth_user.id > 0 %} - - {% endif %} +
@@ -46,6 +43,7 @@ {% block include_js %} + {{ js_include('home/js/list.filter.js') }} {{ js_include('home/js/question.list.js') }} {% endblock %} \ No newline at end of file diff --git a/app/Http/Home/Views/question/list_filter.volt b/app/Http/Home/Views/question/list_filter.volt new file mode 100644 index 00000000..4093d3de --- /dev/null +++ b/app/Http/Home/Views/question/list_filter.volt @@ -0,0 +1,31 @@ +{% set tc_val = request.get('tc','int','all') %} +{% set sc_val = request.get('sc','int','all') %} + +
+ +
+ +
+ {% if top_categories %} +
+
方向
+
+ {% for category in top_categories %} + {% set class = tc_val == category.id ? 'layui-btn layui-btn-xs' : 'none' %} + {{ category.name }} + {% endfor %} +
+
+ {% endif %} + {% if sub_categories %} +
+
分类
+
+ {% for category in sub_categories %} + {% set class = sc_val == category.id ? 'layui-btn layui-btn-xs' : 'none' %} + {{ category.name }} + {% endfor %} +
+
+ {% endif %} +
diff --git a/app/Http/Home/Views/question/show.volt b/app/Http/Home/Views/question/show.volt index 6f08ca1b..7844baed 100644 --- a/app/Http/Home/Views/question/show.volt +++ b/app/Http/Home/Views/question/show.volt @@ -24,9 +24,10 @@ 详情
@@ -46,7 +47,7 @@
举报 - {% if auth_user.id == question.owner.id %} + {% if question.me.owned == 1 %} 编辑 删除 {% endif %} diff --git a/app/Http/Home/Views/user/console/orders.volt b/app/Http/Home/Views/user/console/orders.volt index 783cebc6..93f028a3 100644 --- a/app/Http/Home/Views/user/console/orders.volt +++ b/app/Http/Home/Views/user/console/orders.volt @@ -31,7 +31,6 @@
商品促销 价格 状态 操作 {{ promotion_type(item.promotion_type) }} {{ '¥%0.2f'|format(item.amount) }} {{ order_status(item.status) }} diff --git a/app/Library/Helper.php b/app/Library/Helper.php index 55f5a8f5..9236b96f 100644 --- a/app/Library/Helper.php +++ b/app/Library/Helper.php @@ -41,6 +41,36 @@ function kg_substr($str, $start, $length, $suffix = '...') return $str == $result ? $str : $result . $suffix; } +/** + * 从数组获取随机值 + * + * @param $array + * @param $amount + * @return array|mixed + */ +function kg_array_rand($array, $amount = 1) +{ + $max = count($array); + + if ($amount > $max) { + $amount = $max; + } + + $keys = array_rand($array, $amount); + + if ($amount == 1) { + return $array[$keys]; + } + + $result = []; + + foreach ($keys as $key) { + $result[] = $array[$key]; + } + + return $result; +} + /** * 占位替换 * @@ -199,6 +229,16 @@ function kg_default_user_avatar_path() return '/img/default/user_avatar.png'; } +/** + * 获取默认专栏封面路径 + * + * @return string + */ +function kg_default_article_cover_path() +{ + return '/img/default/article_cover.png'; +} + /** * 获取默认课程封面路径 * @@ -315,6 +355,20 @@ function kg_cos_user_avatar_url($path, $style = null) return kg_cos_img_url($path, $style); } +/** + * 获取专栏封面URL + * + * @param string $path + * @param string $style + * @return string + */ +function kg_cos_article_cover_url($path, $style = null) +{ + $path = $path ?: kg_default_article_cover_path(); + + return kg_cos_img_url($path, $style); +} + /** * 获取课程封面URL * @@ -505,7 +559,7 @@ function kg_parse_first_content_image($content) $matched = preg_match('/src="(.*?)\/img\/content\/(.*?)"/', $content, $matches); if ($matched) { - $url = sprintf('%s/img/content/%s', trim($matches[1]), trim($matches[2])); + $url = sprintf('/img/content/%s', trim($matches[2])); $result = kg_cos_img_style_trim($url); } diff --git a/app/Listeners/Trade.php b/app/Listeners/Trade.php index c400e327..f49f8ae0 100644 --- a/app/Listeners/Trade.php +++ b/app/Listeners/Trade.php @@ -11,7 +11,6 @@ use App\Models\Order as OrderModel; use App\Models\Task as TaskModel; use App\Models\Trade as TradeModel; use App\Repos\Order as OrderRepo; -use App\Services\Logic\FlashSale\UserOrderCache as FlashSaleLockCache; use Phalcon\Events\Event as PhEvent; use Phalcon\Logger\Adapter\File as FileLogger; @@ -56,14 +55,6 @@ class Trade extends Listener $this->db->commit(); - /** - * 解除秒杀锁定 - */ - if ($order->promotion_type == OrderModel::PROMOTION_FLASH_SALE) { - $cache = new FlashSaleLockCache(); - $cache->delete($order->owner_id, $order->promotion_id); - } - } catch (\Exception $e) { $this->db->rollback(); diff --git a/app/Listeners/UserDailyCounter.php b/app/Listeners/UserDailyCounter.php index 933f9d06..9a352820 100644 --- a/app/Listeners/UserDailyCounter.php +++ b/app/Listeners/UserDailyCounter.php @@ -51,11 +51,6 @@ class UserDailyCounter extends Listener $this->counter->hIncrBy($user->id, 'comment_count'); } - public function incrDanmuCount(PhEvent $event, $source, UserModel $user) - { - $this->counter->hIncrBy($user->id, 'danmu_count'); - } - public function incrConsultCount(PhEvent $event, $source, UserModel $user) { $this->counter->hIncrBy($user->id, 'consult_count'); diff --git a/app/Models/Article.php b/app/Models/Article.php index 82629ed8..cdc3e701 100644 --- a/app/Models/Article.php +++ b/app/Models/Article.php @@ -11,6 +11,7 @@ use App\Caches\MaxArticleId as MaxArticleIdCache; use App\Services\Sync\ArticleIndex as ArticleIndexSync; use App\Services\Sync\ArticleScore as ArticleScoreSync; use Phalcon\Mvc\Model\Behavior\SoftDelete; +use Phalcon\Text; class Article extends Model { @@ -127,13 +128,6 @@ class Article extends Model */ public $score = 0.00; - /** - * 私有标识 - * - * @var int - */ - public $private = 0; - /** * 推荐标识 * @@ -255,6 +249,12 @@ class Article extends Model public function beforeSave() { + if (empty($this->cover)) { + $this->cover = kg_default_article_cover_path(); + } elseif (Text::startsWith($this->cover, 'http')) { + $this->cover = self::getCoverPath($this->cover); + } + if (is_array($this->tags) || is_object($this->tags)) { $this->tags = kg_json_encode($this->tags); } @@ -269,11 +269,24 @@ class Article extends Model public function afterFetch() { + if (!Text::startsWith($this->cover, 'http')) { + $this->cover = kg_cos_article_cover_url($this->cover); + } + if (is_string($this->tags)) { $this->tags = json_decode($this->tags, true); } } + public static function getCoverPath($url) + { + if (Text::startsWith($url, 'http')) { + return parse_url($url, PHP_URL_PATH); + } + + return $url; + } + public static function sourceTypes() { return [ diff --git a/app/Models/ChapterUser.php b/app/Models/ChapterUser.php index 62519558..5f92dabf 100644 --- a/app/Models/ChapterUser.php +++ b/app/Models/ChapterUser.php @@ -73,6 +73,20 @@ class ChapterUser extends Model */ public $consumed = 0; + /** + * 删除标识 + * + * @var int + */ + public $deleted = 0; + + /** + * 活跃时间 + * + * @var int + */ + public $active_time = 0; + /** * 创建时间 * diff --git a/app/Models/Consult.php b/app/Models/Consult.php index 469cb8eb..094ebf32 100644 --- a/app/Models/Consult.php +++ b/app/Models/Consult.php @@ -115,7 +115,7 @@ class Consult extends Model * * @var int */ - public $published = 0; + public $published = self::PUBLISH_PENDING; /** * 删除标识 diff --git a/app/Models/Course.php b/app/Models/Course.php index 12a5c87e..f72ca29d 100644 --- a/app/Models/Course.php +++ b/app/Models/Course.php @@ -136,15 +136,6 @@ class Course extends Model */ public $teacher_id = 0; - /** - * 原始价格 - * - * @deprecated since v1.5.7 - * - * @var float - */ - public $origin_price = 0.00; - /** * 优惠价格 * @@ -396,7 +387,6 @@ class Course extends Model public function afterFetch() { - $this->origin_price = (float)$this->origin_price; $this->market_price = (float)$this->market_price; $this->vip_price = (float)$this->vip_price; $this->rating = (float)$this->rating; @@ -415,6 +405,17 @@ class Course extends Model } } + public function getUserCount() + { + $userCount = $this->user_count; + + if ($this->fake_user_count > $userCount) { + $userCount = $this->fake_user_count; + } + + return $userCount; + } + public static function getCoverPath($url) { if (Text::startsWith($url, 'http')) { diff --git a/app/Models/CourseCategory.php b/app/Models/CourseCategory.php deleted file mode 100644 index 49f43c13..00000000 --- a/app/Models/CourseCategory.php +++ /dev/null @@ -1,51 +0,0 @@ -create_time = time(); - } - -} diff --git a/app/Models/CourseUser.php b/app/Models/CourseUser.php index 78021932..64dbf479 100644 --- a/app/Models/CourseUser.php +++ b/app/Models/CourseUser.php @@ -10,21 +10,16 @@ namespace App\Models; class CourseUser extends Model { - /** - * 角色类型 - */ - const ROLE_STUDENT = 1; // 学员 - const ROLE_TEACHER = 2; // 讲师 - /** * 来源类型 */ const SOURCE_FREE = 1; // 免费 const SOURCE_CHARGE = 2; // 付费 - const SOURCE_VIP = 3; // 会员(畅学) - const SOURCE_IMPORT = 4; // 导入 + const SOURCE_VIP = 3; // 畅学 + const SOURCE_MANUAL = 4; // 分配 const SOURCE_POINT_REDEEM = 5; // 积分兑换 const SOURCE_LUCKY_REDEEM = 6; // 抽奖兑换 + const SOURCE_TRIAL = 10; // 试听 /** * 主键编号 @@ -54,13 +49,6 @@ class CourseUser extends Model */ public $plan_id = 0; - /** - * 角色类型 - * - * @var int - */ - public $role_type = 0; - /** * 来源类型 * @@ -103,6 +91,13 @@ class CourseUser extends Model */ public $deleted = 0; + /** + * 活跃时间 + * + * @var int + */ + public $active_time = 0; + /** * 创建时间 * @@ -124,7 +119,7 @@ class CourseUser extends Model public function beforeCreate() { - $this->plan_id = (int)date('Ymd'); + $this->plan_id = (int)date('ymd'); $this->create_time = time(); } @@ -134,21 +129,14 @@ class CourseUser extends Model $this->update_time = time(); } - public static function roleTypes() - { - return [ - self::ROLE_STUDENT => '学员', - self::ROLE_TEACHER => '讲师', - ]; - } - public static function sourceTypes() { return [ self::SOURCE_FREE => '免费', self::SOURCE_CHARGE => '付费', - self::SOURCE_VIP => '会员', - self::SOURCE_IMPORT => '导入', + self::SOURCE_TRIAL => '试听', + self::SOURCE_VIP => '畅学', + self::SOURCE_MANUAL => '分配', self::SOURCE_POINT_REDEEM => '积分兑换', self::SOURCE_LUCKY_REDEEM => '抽奖兑换', ]; diff --git a/app/Models/Danmu.php b/app/Models/Danmu.php deleted file mode 100644 index 7e0e0bb1..00000000 --- a/app/Models/Danmu.php +++ /dev/null @@ -1,203 +0,0 @@ -addBehavior( - new SoftDelete([ - 'field' => 'deleted', - 'value' => 1, - ]) - ); - } - - public function beforeCreate() - { - $this->create_time = time(); - } - - public function beforeUpdate() - { - $this->update_time = time(); - } - - public static function sizeTypes() - { - return [ - self::SIZE_SMALL => '小号', - self::SIZE_BIG => '大号', - ]; - } - - public static function posTypes() - { - return [ - self::POS_MOVE => '滚动', - self::POS_TOP => '顶部', - self::POS_BOTTOM => '底部', - ]; - } - - public static function colorTypes() - { - return [ - self::COLOR_WHITE => '白色', - self::COLOR_RED => '红色', - self::COLOR_GREEN => '绿色', - self::COLOR_BLUE => '蓝色', - self::COLOR_YELLOW => '黄色', - ]; - } - - public static function randPosition() - { - $types = self::posTypes(); - - $keys = array_keys($types); - $index = array_rand($keys); - - return $keys[$index]; - } - - public static function randColor() - { - $types = self::colorTypes(); - - $keys = array_keys($types); - $index = array_rand($keys); - - return $keys[$index]; - } - -} diff --git a/app/Models/FlashSale.php b/app/Models/FlashSale.php deleted file mode 100644 index f8316c5d..00000000 --- a/app/Models/FlashSale.php +++ /dev/null @@ -1,195 +0,0 @@ -addBehavior( - new SoftDelete([ - 'field' => 'deleted', - 'value' => 1, - ]) - ); - } - - public function beforeCreate() - { - $this->create_time = time(); - } - - public function beforeUpdate() - { - $this->update_time = time(); - } - - public function beforeSave() - { - if (is_array($this->item_info) || is_object($this->item_info)) { - $this->item_info = kg_json_encode($this->item_info); - } - - if (is_array($this->schedules) || is_object($this->schedules)) { - $this->schedules = kg_json_encode($this->schedules); - } - } - - public function afterCreate() - { - $cache = new MaxFlashSaleIdCache(); - - $cache->rebuild(); - } - - public function afterFetch() - { - if (is_string($this->item_info)) { - $this->item_info = json_decode($this->item_info, true); - } - - if (is_string($this->schedules)) { - $this->schedules = json_decode($this->schedules, true); - } - } - - public static function itemTypes() - { - return [ - self::ITEM_COURSE => '课程', - self::ITEM_PACKAGE => '套餐', - self::ITEM_VIP => '会员', - ]; - } - - public static function schedules() - { - $result = []; - - foreach (range(10, 20, 2) as $hour) { - $result[] = [ - 'name' => sprintf('%02d点', $hour), - 'hour' => sprintf('%02d', $hour), - 'start_time' => sprintf('%02d:%02d:%02d', $hour, 0, 0), - 'end_time' => sprintf('%02d:%02d:%02d', $hour + 1, 59, 59) - ]; - } - - return $result; - } - -} diff --git a/app/Models/Order.php b/app/Models/Order.php index cf8e3f5b..3cd04bcc 100644 --- a/app/Models/Order.php +++ b/app/Models/Order.php @@ -21,9 +21,6 @@ class Order extends Model const ITEM_VIP = 4; // 会员 const ITEM_TEST = 99; // 测试 - const PROMOTION_FLASH_SALE = 1; // 限时秒杀 - const PROMOTION_DISCOUNT = 2; // 限时折扣 - /** * 状态类型 */ @@ -89,27 +86,6 @@ class Order extends Model */ public $item_info = []; - /** - * 促销编号 - * - * @var int - */ - public $promotion_id = 0; - - /** - * 促销类型 - * - * @var int - */ - public $promotion_type = 0; - - /** - * 促销信息 - * - * @var array|string - */ - public $promotion_info = []; - /** * 终端类型 * @@ -188,10 +164,6 @@ class Order extends Model if (is_array($this->item_info) || is_object($this->item_info)) { $this->item_info = kg_json_encode($this->item_info); } - - if (is_array($this->promotion_info) || is_object($this->promotion_info)) { - $this->promotion_info = kg_json_encode($this->promotion_info); - } } public function afterSave() @@ -211,10 +183,6 @@ class Order extends Model if (is_string($this->item_info)) { $this->item_info = json_decode($this->item_info, true); } - - if (is_string($this->promotion_info)) { - $this->promotion_info = json_decode($this->promotion_info, true); - } } public static function itemTypes() @@ -228,14 +196,6 @@ class Order extends Model ]; } - public static function promotionTypes() - { - return [ - self::PROMOTION_FLASH_SALE => '限时秒杀', - self::PROMOTION_DISCOUNT => '限时折扣', - ]; - } - public static function statusTypes() { return [ diff --git a/app/Models/Reason.php b/app/Models/Reason.php index ad18d3d5..056cff24 100644 --- a/app/Models/Reason.php +++ b/app/Models/Reason.php @@ -74,6 +74,30 @@ class Reason ]; } + public static function reviewRejectOptions() + { + return [ + 101 => '广告软文', + 102 => '违法内容', + 103 => '恶意对比', + 104 => '低俗色情', + 105 => '人身攻击', + 106 => '其它问题', + ]; + } + + public static function consultRejectOptions() + { + return [ + 101 => '广告软文', + 102 => '违法内容', + 103 => '恶意对比', + 104 => '低俗色情', + 105 => '人身攻击', + 106 => '其它问题', + ]; + } + public static function reportOptions() { return [ diff --git a/app/Models/Resource.php b/app/Models/Resource.php index adc0deac..2f6e962b 100644 --- a/app/Models/Resource.php +++ b/app/Models/Resource.php @@ -24,13 +24,6 @@ class Resource extends Model */ public $course_id = 0; - /** - * 章节编号 - * - * @var int - */ - public $chapter_id = 0; - /** * 上传编号 * diff --git a/app/Models/Vip.php b/app/Models/Vip.php index e19ef2a7..5aa4bfbd 100644 --- a/app/Models/Vip.php +++ b/app/Models/Vip.php @@ -48,6 +48,13 @@ class Vip extends Model */ public $price = 0.00; + /** + * 发布标识 + * + * @var int + */ + public $published = 0; + /** * 删除标识 * diff --git a/app/Repos/Answer.php b/app/Repos/Answer.php index c38d6df9..0ce586cb 100644 --- a/app/Repos/Answer.php +++ b/app/Repos/Answer.php @@ -38,7 +38,7 @@ class Answer extends Repository $builder->andWhere('question_id = :question_id:', ['question_id' => $where['question_id']]); } - if (isset($where['published'])) { + if (!empty($where['published'])) { if (is_array($where['published'])) { $builder->inWhere('published', $where['published']); } else { @@ -46,6 +46,12 @@ class Answer extends Repository } } + if (!empty($where['create_time'][0]) && !empty($where['create_time'][1])) { + $startTime = strtotime($where['create_time'][0]); + $endTime = strtotime($where['create_time'][1]); + $builder->betweenWhere('create_time', $startTime, $endTime); + } + if (isset($where['deleted'])) { $builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]); } diff --git a/app/Repos/Article.php b/app/Repos/Article.php index c4d02014..9f964e1b 100644 --- a/app/Repos/Article.php +++ b/app/Repos/Article.php @@ -57,11 +57,7 @@ class Article extends Repository } } - if (!empty($where['owner_id'])) { - $builder->andWhere('owner_id = :owner_id:', ['owner_id' => $where['owner_id']]); - } - - if (isset($where['source_type'])) { + if (!empty($where['source_type'])) { if (is_array($where['source_type'])) { $builder->inWhere('source_type', $where['source_type']); } else { @@ -69,18 +65,6 @@ class Article extends Repository } } - if (!empty($where['title'])) { - $builder->andWhere('title LIKE :title:', ['title' => "%{$where['title']}%"]); - } - - if (isset($where['private'])) { - $builder->andWhere('private = :private:', ['private' => $where['private']]); - } - - if (isset($where['featured'])) { - $builder->andWhere('featured = :featured:', ['featured' => $where['featured']]); - } - if (!empty($where['published'])) { if (is_array($where['published'])) { $builder->inWhere('published', $where['published']); @@ -89,6 +73,24 @@ class Article extends Repository } } + if (!empty($where['owner_id'])) { + $builder->andWhere('owner_id = :owner_id:', ['owner_id' => $where['owner_id']]); + } + + if (!empty($where['title'])) { + $builder->andWhere('title LIKE :title:', ['title' => "%{$where['title']}%"]); + } + + if (!empty($where['create_time'][0]) && !empty($where['create_time'][1])) { + $startTime = strtotime($where['create_time'][0]); + $endTime = strtotime($where['create_time'][1]); + $builder->betweenWhere('create_time', $startTime, $endTime); + } + + if (isset($where['featured'])) { + $builder->andWhere('featured = :featured:', ['featured' => $where['featured']]); + } + if (isset($where['closed'])) { $builder->andWhere('closed = :closed:', ['closed' => $where['closed']]); } diff --git a/app/Repos/Category.php b/app/Repos/Category.php index 7a97ffca..2ce2ebe4 100644 --- a/app/Repos/Category.php +++ b/app/Repos/Category.php @@ -25,18 +25,34 @@ class Category extends Repository $query->where('1 = 1'); + if (!empty($where['id'])) { + $query->andWhere('id = :id:', ['id' => $where['id']]); + } + + if (!empty($where['name'])) { + $query->andWhere('name LIKE :name:', ['name' => "%{$where['name']}%"]); + } + + if (!empty($where['type'])) { + if (is_array($where['type'])) { + $query->inWhere('type', $where['type']); + } else { + $query->andWhere('type = :type:', ['type' => $where['type']]); + } + } + + if (!empty($where['level'])) { + if (is_array($where['level'])) { + $query->inWhere('level', $where['level']); + } else { + $query->andWhere('level = :level:', ['level' => $where['level']]); + } + } + if (isset($where['parent_id'])) { $query->andWhere('parent_id = :parent_id:', ['parent_id' => $where['parent_id']]); } - if (isset($where['type'])) { - $query->andWhere('type = :type:', ['type' => $where['type']]); - } - - if (isset($where['level'])) { - $query->andWhere('level = :level:', ['level' => $where['level']]); - } - if (isset($where['published'])) { $query->andWhere('published = :published:', ['published' => $where['published']]); } diff --git a/app/Repos/ChapterUser.php b/app/Repos/ChapterUser.php index f4a9c738..796cd917 100644 --- a/app/Repos/ChapterUser.php +++ b/app/Repos/ChapterUser.php @@ -37,6 +37,10 @@ class ChapterUser extends Repository $query->andWhere('user_id = :user_id:', ['user_id' => $where['user_id']]); } + if (!empty($where['plan_id'])) { + $query->andWhere('plan_id = :plan_id:', ['plan_id' => $where['plan_id']]); + } + return $query->execute(); } @@ -48,7 +52,7 @@ class ChapterUser extends Repository public function findChapterUser($chapterId, $userId) { return ChapterUserModel::findFirst([ - 'conditions' => 'chapter_id = ?1 AND user_id = ?2', + 'conditions' => 'chapter_id = ?1 AND user_id = ?2 AND deleted = 0', 'bind' => [1 => $chapterId, 2 => $userId], 'order' => 'id DESC', ]); @@ -63,7 +67,7 @@ class ChapterUser extends Repository public function findPlanChapterUser($chapterId, $userId, $planId) { return ChapterUserModel::findFirst([ - 'conditions' => 'chapter_id = ?1 AND user_id = ?2 AND plan_id = ?3', + 'conditions' => 'chapter_id = ?1 AND user_id = ?2 AND plan_id = ?3 AND deleted = 0', 'bind' => [1 => $chapterId, 2 => $userId, 3 => $planId], ]); } diff --git a/app/Repos/Comment.php b/app/Repos/Comment.php index ba7115cb..68404d51 100644 --- a/app/Repos/Comment.php +++ b/app/Repos/Comment.php @@ -44,10 +44,6 @@ class Comment extends Repository } } - if (isset($where['parent_id'])) { - $builder->andWhere('parent_id = :parent_id:', ['parent_id' => $where['parent_id']]); - } - if (!empty($where['published'])) { if (is_array($where['published'])) { $builder->inWhere('published', $where['published']); @@ -56,6 +52,16 @@ class Comment extends Repository } } + if (!empty($where['create_time'][0]) && !empty($where['create_time'][1])) { + $startTime = strtotime($where['create_time'][0]); + $endTime = strtotime($where['create_time'][1]); + $builder->betweenWhere('create_time', $startTime, $endTime); + } + + if (isset($where['parent_id'])) { + $builder->andWhere('parent_id = :parent_id:', ['parent_id' => $where['parent_id']]); + } + if (isset($where['deleted'])) { $builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]); } diff --git a/app/Repos/Consult.php b/app/Repos/Consult.php index c1a87dda..fbc58945 100644 --- a/app/Repos/Consult.php +++ b/app/Repos/Consult.php @@ -45,10 +45,6 @@ class Consult extends Repository $builder->andWhere('reply_time > 0'); } - if (isset($where['private'])) { - $builder->andWhere('private = :private:', ['private' => $where['private']]); - } - if (!empty($where['published'])) { if (is_array($where['published'])) { $builder->inWhere('published', $where['published']); @@ -57,6 +53,16 @@ class Consult extends Repository } } + if (!empty($where['create_time'][0]) && !empty($where['create_time'][1])) { + $startTime = strtotime($where['create_time'][0]); + $endTime = strtotime($where['create_time'][1]); + $builder->betweenWhere('create_time', $startTime, $endTime); + } + + if (isset($where['private'])) { + $builder->andWhere('private = :private:', ['private' => $where['private']]); + } + if (isset($where['deleted'])) { $builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]); } diff --git a/app/Repos/Course.php b/app/Repos/Course.php index 7a504ef3..8f677ea1 100644 --- a/app/Repos/Course.php +++ b/app/Repos/Course.php @@ -8,12 +8,10 @@ namespace App\Repos; use App\Library\Paginator\Adapter\QueryBuilder as PagerQueryBuilder; -use App\Models\Category as CategoryModel; use App\Models\Chapter as ChapterModel; use App\Models\ChapterUser as ChapterUserModel; use App\Models\Consult as ConsultModel; use App\Models\Course as CourseModel; -use App\Models\CourseCategory as CourseCategoryModel; use App\Models\CourseFavorite as CourseFavoriteModel; use App\Models\CoursePackage as CoursePackageModel; use App\Models\CourseRating as CourseRatingModel; @@ -24,7 +22,6 @@ use App\Models\Package as PackageModel; use App\Models\Resource as ResourceModel; use App\Models\Review as ReviewModel; use App\Models\Tag as TagModel; -use App\Models\User as UserModel; use Phalcon\Mvc\Model; use Phalcon\Mvc\Model\Resultset; use Phalcon\Mvc\Model\ResultsetInterface; @@ -42,13 +39,8 @@ class Course extends Repository $fakeId = false; - if (!empty($where['category_id'])) { - $where['id'] = $this->getCategoryCourseIds($where['category_id']); - $fakeId = empty($where['id']); - } - - if (!empty($where['teacher_id'])) { - $where['id'] = $this->getTeacherCourseIds($where['teacher_id']); + if (!empty($where['tag_id'])) { + $where['id'] = $this->getTagCourseIds($where['tag_id']); $fakeId = empty($where['id']); } @@ -65,8 +57,20 @@ class Course extends Repository } } - if (!empty($where['title'])) { - $builder->andWhere('title LIKE :title:', ['title' => "%{$where['title']}%"]); + if (!empty($where['category_id'])) { + if (is_array($where['category_id'])) { + $builder->inWhere('category_id', $where['category_id']); + } else { + $builder->andWhere('category_id = :category_id:', ['category_id' => $where['category_id']]); + } + } + + if (!empty($where['teacher_id'])) { + if (is_array($where['teacher_id'])) { + $builder->inWhere('teacher_id', $where['teacher_id']); + } else { + $builder->andWhere('teacher_id = :teacher_id:', ['teacher_id' => $where['teacher_id']]); + } } if (!empty($where['model'])) { @@ -85,6 +89,16 @@ class Course extends Repository } } + if (!empty($where['create_time'][0]) && !empty($where['create_time'][1])) { + $startTime = strtotime($where['create_time'][0]); + $endTime = strtotime($where['create_time'][1]); + $builder->betweenWhere('create_time', $startTime, $endTime); + } + + if (!empty($where['title'])) { + $builder->andWhere('title LIKE :title:', ['title' => "%{$where['title']}%"]); + } + if (isset($where['free'])) { if ($where['free'] == 1) { $builder->andWhere('market_price = 0'); @@ -198,40 +212,6 @@ class Course extends Repository ]); } - /** - * @param int $courseId - * @return ResultsetInterface|Resultset|UserModel[] - */ - public function findTeachers($courseId) - { - $roleType = CourseUserModel::ROLE_TEACHER; - - return $this->modelsManager->createBuilder() - ->columns('u.*') - ->addFrom(UserModel::class, 'u') - ->join(CourseUserModel::class, 'u.id = cu.user_id', 'cu') - ->where('cu.course_id = :course_id:', ['course_id' => $courseId]) - ->andWhere('cu.role_type = :role_type:', ['role_type' => $roleType]) - ->andWhere('cu.deleted = 0') - ->getQuery()->execute(); - } - - /** - * @param int $courseId - * @return ResultsetInterface|Resultset|CategoryModel[] - */ - public function findCategories($courseId) - { - return $this->modelsManager->createBuilder() - ->columns('c.*') - ->addFrom(CategoryModel::class, 'c') - ->join(CourseCategoryModel::class, 'c.id = cc.category_id', 'cc') - ->where('cc.course_id = :course_id:', ['course_id' => $courseId]) - ->andWhere('c.published = 1') - ->andWhere('c.deleted = 0') - ->getQuery()->execute(); - } - /** * @param int $courseId * @return ResultsetInterface|Resultset|TagModel[] @@ -362,8 +342,8 @@ class Course extends Repository public function countUsers($courseId) { return (int)CourseUserModel::count([ - 'conditions' => 'course_id = ?1 AND role_type = ?2 AND deleted = 0', - 'bind' => [1 => $courseId, 2 => CourseUserModel::ROLE_STUDENT], + 'conditions' => 'course_id = :course_id: AND deleted = 0', + 'bind' => ['course_id' => $courseId], ]); } @@ -400,30 +380,13 @@ class Course extends Repository ]); } - protected function getCategoryCourseIds($categoryId) + protected function getTagCourseIds($tagId) { - $categoryIds = is_array($categoryId) ? $categoryId : [$categoryId]; + $tagIds = is_array($tagId) ? $tagId : [$tagId]; - $repo = new CourseCategory(); + $repo = new CourseTag(); - $rows = $repo->findByCategoryIds($categoryIds); - - $result = []; - - if ($rows->count() > 0) { - $result = kg_array_column($rows->toArray(), 'course_id'); - } - - return $result; - } - - protected function getTeacherCourseIds($teacherId) - { - $teacherIds = is_array($teacherId) ? $teacherId : [$teacherId]; - - $repo = new CourseUser(); - - $rows = $repo->findByTeacherIds($teacherIds); + $rows = $repo->findByTagIds($tagIds); $result = []; diff --git a/app/Repos/CourseCategory.php b/app/Repos/CourseCategory.php deleted file mode 100644 index 543f4840..00000000 --- a/app/Repos/CourseCategory.php +++ /dev/null @@ -1,53 +0,0 @@ - 'course_id = :course_id: AND category_id = :category_id:', - 'bind' => ['course_id' => $courseId, 'category_id' => $categoryId], - ]); - } - - /** - * @param array $categoryIds - * @return ResultsetInterface|Resultset|CourseCategoryModel[] - */ - public function findByCategoryIds($categoryIds) - { - return CourseCategoryModel::query() - ->inWhere('category_id', $categoryIds) - ->execute(); - } - - /** - * @param array $courseIds - * @return ResultsetInterface|Resultset|CourseCategoryModel[] - */ - public function findByCourseIds($courseIds) - { - return CourseCategoryModel::query() - ->inWhere('course_id', $courseIds) - ->execute(); - } - -} diff --git a/app/Repos/CourseUser.php b/app/Repos/CourseUser.php index 613d1b2f..2dfdc91b 100644 --- a/app/Repos/CourseUser.php +++ b/app/Repos/CourseUser.php @@ -32,14 +32,26 @@ class CourseUser extends Repository $builder->andWhere('user_id = :user_id:', ['user_id' => $where['user_id']]); } - if (!empty($where['role_type'])) { - $builder->andWhere('role_type = :role_type:', ['role_type' => $where['role_type']]); + if (!empty($where['plan_id'])) { + $builder->andWhere('plan_id = :plan_id:', ['plan_id' => $where['plan_id']]); } if (!empty($where['source_type'])) { $builder->andWhere('source_type = :source_type:', ['source_type' => $where['source_type']]); } + if (!empty($where['create_time'][0]) && !empty($where['create_time'][1])) { + $startTime = strtotime($where['create_time'][0]); + $endTime = strtotime($where['create_time'][1]); + $builder->betweenWhere('create_time', $startTime, $endTime); + } + + if (!empty($where['expiry_time'][0]) && !empty($where['expiry_time'][1])) { + $startTime = strtotime($where['expiry_time'][0]); + $endTime = strtotime($where['expiry_time'][1]); + $builder->betweenWhere('expiry_time', $startTime, $endTime); + } + if (isset($where['deleted'])) { $builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]); } @@ -73,20 +85,6 @@ class CourseUser extends Repository return CourseUserModel::findFirst($id); } - /** - * @param int $courseId - * @param int $userId - * @param int $planId - * @return CourseUserModel|Model|bool - */ - public function findPlanCourseUser($courseId, $userId, $planId) - { - return CourseUserModel::findFirst([ - 'conditions' => 'course_id = ?1 AND user_id = ?2 AND plan_id = ?3 AND deleted = 0', - 'bind' => [1 => $courseId, 2 => $userId, 3 => $planId], - ]); - } - /** * @param int $courseId * @param int $userId @@ -104,56 +102,17 @@ class CourseUser extends Repository /** * @param int $courseId * @param int $userId + * @param int $planId * @return CourseUserModel|Model|bool */ - public function findCourseTeacher($courseId, $userId) - { - $roleType = CourseUserModel::ROLE_TEACHER; - - return $this->findRoleCourseUser($courseId, $userId, $roleType); - } - - /** - * @param int $courseId - * @param int $userId - * @return CourseUserModel|Model|bool - */ - public function findCourseStudent($courseId, $userId) - { - $roleType = CourseUserModel::ROLE_STUDENT; - - return $this->findRoleCourseUser($courseId, $userId, $roleType); - } - - /** - * @param int $courseId - * @param int $userId - * @param string $roleType - * @return CourseUserModel|Model|bool - */ - protected function findRoleCourseUser($courseId, $userId, $roleType) + public function findPlanCourseUser($courseId, $userId, $planId) { return CourseUserModel::findFirst([ - 'conditions' => 'course_id = ?1 AND user_id = ?2 AND role_type = ?3 AND deleted = 0', - 'bind' => [1 => $courseId, 2 => $userId, 3 => $roleType], - 'order' => 'id DESC', + 'conditions' => 'course_id = ?1 AND user_id = ?2 AND plan_id = ?3 AND deleted = 0', + 'bind' => [1 => $courseId, 2 => $userId, 3 => $planId], ]); } - /** - * @param array $teacherIds - * @return ResultsetInterface|Resultset|CourseUserModel[] - */ - public function findByTeacherIds($teacherIds) - { - $roleType = CourseUserModel::ROLE_TEACHER; - - return CourseUserModel::query() - ->inWhere('user_id', $teacherIds) - ->andWhere('role_type = :role_type:', ['role_type' => $roleType]) - ->execute(); - } - /** * @param int $courseId * @return ResultsetInterface|Resultset|CourseUserModel[] diff --git a/app/Repos/Danmu.php b/app/Repos/Danmu.php deleted file mode 100644 index d5b03c93..00000000 --- a/app/Repos/Danmu.php +++ /dev/null @@ -1,140 +0,0 @@ -modelsManager->createBuilder(); - - $builder->from(DanmuModel::class); - - $builder->where('1 = 1'); - - if (!empty($where['id'])) { - $builder->andWhere('id = :id:', ['id' => $where['id']]); - } - - if (!empty($where['course_id'])) { - $builder->andWhere('course_id = :course_id:', ['course_id' => $where['course_id']]); - } - - if (!empty($where['chapter_id'])) { - $builder->andWhere('chapter_id = :chapter_id:', ['chapter_id' => $where['chapter_id']]); - } - - if (!empty($where['owner_id'])) { - $builder->andWhere('owner_id = :owner_id:', ['owner_id' => $where['owner_id']]); - } - - if (isset($where['published'])) { - $builder->andWhere('published = :published:', ['published' => $where['published']]); - } - - if (isset($where['deleted'])) { - $builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]); - } - - switch ($sort) { - case 'oldest': - $orderBy = 'id ASC'; - break; - default: - $orderBy = 'id DESC'; - break; - } - - $builder->orderBy($orderBy); - - $pager = new PagerQueryBuilder([ - 'builder' => $builder, - 'page' => $page, - 'limit' => $limit, - ]); - - return $pager->paginate(); - } - - /** - * @param int $id - * @return DanmuModel|Model|bool - */ - public function findById($id) - { - return DanmuModel::findFirst([ - 'conditions' => 'id = :id:', - 'bind' => ['id' => $id], - ]); - } - - /** - * @param array $ids - * @param string|array $columns - * @return ResultsetInterface|Resultset|DanmuModel[] - */ - public function findByIds($ids, $columns = '*') - { - return DanmuModel::query() - ->columns($columns) - ->inWhere('id', $ids) - ->execute(); - } - - /** - * @param array $where - * @return ResultsetInterface|Resultset|DanmuModel[] - */ - public function findAll($where = []) - { - $query = DanmuModel::query(); - - $query->where('1 = 1'); - - if (!empty($where['course_id'])) { - $query->andWhere('course_id = :course_id:', ['course_id' => $where['course_id']]); - } - - if (!empty($where['chapter_id'])) { - $query->andWhere('chapter_id = :chapter_id:', ['chapter_id' => $where['chapter_id']]); - } - - if (!empty($where['owner_id'])) { - $query->andWhere('owner_id = :owner_id:', ['owner_id' => $where['owner_id']]); - } - - if (!empty($where['start_time']) && !empty($where['end_time'])) { - $query->betweenWhere('time', $where['start_time'], $where['end_time']); - } - - if (isset($where['published'])) { - $query->andWhere('published = :published:', ['published' => $where['published']]); - } - - if (isset($where['deleted'])) { - $query->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]); - } - - $query->orderBy('id DESC'); - - return $query->execute(); - } - - public function countDanmus() - { - return (int)DanmuModel::count(['conditions' => 'published = 1']); - } - -} diff --git a/app/Repos/FlashSale.php b/app/Repos/FlashSale.php deleted file mode 100644 index f17085ea..00000000 --- a/app/Repos/FlashSale.php +++ /dev/null @@ -1,127 +0,0 @@ -modelsManager->createBuilder(); - - $builder->from(FlashSaleModel::class); - - $builder->where('1 = 1'); - - if (!empty($where['id'])) { - $builder->andWhere('id = :id:', ['id' => $where['id']]); - } - - if (!empty($where['item_id'])) { - $builder->andWhere('item_id = :item_id:', ['item_id' => $where['item_id']]); - } - - if (!empty($where['item_type'])) { - if (is_array($where['item_type'])) { - $builder->inWhere('item_type', $where['item_type']); - } else { - $builder->andWhere('item_type = :item_type:', ['item_type' => $where['item_type']]); - } - } - - if (isset($where['published'])) { - $builder->andWhere('published = :published:', ['published' => $where['published']]); - } - - if (isset($where['deleted'])) { - $builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]); - } - - $now = time(); - - if (!empty($where['status'])) { - switch ($where['status']) { - case 'pending': - $builder->andWhere('start_time > :start_time:', ['start_time' => $now]); - break; - case 'finished': - $builder->andWhere('end_time < :end_time:', ['end_time' => $now]); - break; - case 'active': - $builder->andWhere('start_time < :start_time:', ['start_time' => $now]); - $builder->andWhere('end_time > :end_time:', ['end_time' => $now]); - break; - } - } - - switch ($sort) { - case 'oldest': - $orderBy = 'id ASC'; - break; - default: - $orderBy = 'id DESC'; - break; - } - - $builder->orderBy($orderBy); - - $pager = new PagerQueryBuilder([ - 'builder' => $builder, - 'page' => $page, - 'limit' => $limit, - ]); - - return $pager->paginate(); - } - - /** - * @param string $date - * @return ResultsetInterface|Resultset|FlashSaleModel[] - */ - public function findFutureSales($date) - { - $time = strtotime($date); - - return FlashSaleModel::query() - ->where('published = 1') - ->andWhere('end_time > :time:', ['time' => $time]) - ->execute(); - } - - /** - * @param int $id - * @return FlashSaleModel|Model|bool - */ - public function findById($id) - { - return FlashSaleModel::findFirst([ - 'conditions' => 'id = :id:', - 'bind' => ['id' => $id], - ]); - } - - /** - * @param array $ids - * @param string|array $columns - * @return ResultsetInterface|Resultset|FlashSaleModel[] - */ - public function findByIds($ids, $columns = '*') - { - return FlashSaleModel::query() - ->columns($columns) - ->inWhere('id', $ids) - ->execute(); - } - -} diff --git a/app/Repos/Help.php b/app/Repos/Help.php index 1b0993fc..68911876 100644 --- a/app/Repos/Help.php +++ b/app/Repos/Help.php @@ -50,6 +50,10 @@ class Help extends Repository $query->where('1 = 1'); + if (!empty($where['id'])) { + $query->andWhere('id = :id:', ['id' => $where['id']]); + } + if (!empty($where['category_id'])) { $query->andWhere('category_id = :category_id:', ['category_id' => $where['category_id']]); } diff --git a/app/Repos/Learning.php b/app/Repos/Learning.php index b526a70d..cbd7ac49 100644 --- a/app/Repos/Learning.php +++ b/app/Repos/Learning.php @@ -22,10 +22,6 @@ class Learning extends Repository $builder->where('1 = 1'); - if (!empty($where['plan_id'])) { - $builder->andWhere('plan_id = :plan_id:', ['plan_id' => $where['plan_id']]); - } - if (!empty($where['course_id'])) { $builder->andWhere('course_id = :course_id:', ['course_id' => $where['course_id']]); } @@ -38,6 +34,16 @@ class Learning extends Repository $builder->andWhere('user_id = :user_id:', ['user_id' => $where['user_id']]); } + if (!empty($where['plan_id'])) { + $builder->andWhere('plan_id = :plan_id:', ['plan_id' => $where['plan_id']]); + } + + if (!empty($where['create_time'][0]) && !empty($where['create_time'][1])) { + $startTime = strtotime($where['create_time'][0]); + $endTime = strtotime($where['create_time'][1]); + $builder->betweenWhere('create_time', $startTime, $endTime); + } + switch ($sort) { case 'oldest': $orderBy = 'id ASC'; diff --git a/app/Repos/Notification.php b/app/Repos/Notification.php index c6c011f9..8029a5b8 100644 --- a/app/Repos/Notification.php +++ b/app/Repos/Notification.php @@ -44,6 +44,12 @@ class Notification extends Repository } } + if (!empty($where['create_time'][0]) && !empty($where['create_time'][1])) { + $startTime = strtotime($where['create_time'][0]); + $endTime = strtotime($where['create_time'][1]); + $builder->betweenWhere('create_time', $startTime, $endTime); + } + if (isset($where['viewed'])) { $builder->andWhere('viewed = :viewed:', ['viewed' => $where['viewed']]); } diff --git a/app/Repos/Online.php b/app/Repos/Online.php index 52f344e9..0623afb6 100644 --- a/app/Repos/Online.php +++ b/app/Repos/Online.php @@ -27,6 +27,12 @@ class Online extends Repository $builder->andWhere('user_id = :user_id:', ['user_id' => $where['user_id']]); } + if (!empty($where['create_time'][0]) && !empty($where['create_time'][1])) { + $startTime = strtotime($where['create_time'][0]); + $endTime = strtotime($where['create_time'][1]); + $builder->betweenWhere('create_time', $startTime, $endTime); + } + switch ($sort) { case 'oldest': $orderBy = 'id ASC'; diff --git a/app/Repos/Order.php b/app/Repos/Order.php index 0e670e03..087b20e2 100644 --- a/app/Repos/Order.php +++ b/app/Repos/Order.php @@ -51,14 +51,6 @@ class Order extends Repository } } - if (!empty($where['promotion_type'])) { - if (is_array($where['promotion_type'])) { - $builder->inWhere('promotion_type', $where['promotion_type']); - } else { - $builder->andWhere('promotion_type = :promotion_type:', ['promotion_type' => $where['promotion_type']]); - } - } - if (!empty($where['status'])) { if (is_array($where['status'])) { $builder->inWhere('status', $where['status']); @@ -67,16 +59,16 @@ class Order extends Repository } } - if (isset($where['deleted'])) { - $builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]); - } - if (!empty($where['start_time']) && !empty($where['end_time'])) { $startTime = strtotime($where['start_time']); $endTime = strtotime($where['end_time']); $builder->betweenWhere('create_time', $startTime, $endTime); } + if (isset($where['deleted'])) { + $builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]); + } + switch ($sort) { case 'oldest': $orderBy = 'id ASC'; diff --git a/app/Repos/Package.php b/app/Repos/Package.php index bf560860..0c40d036 100644 --- a/app/Repos/Package.php +++ b/app/Repos/Package.php @@ -34,6 +34,12 @@ class Package extends Repository $builder->andWhere('title LIKE :title:', ['title' => "%{$where['title']}%"]); } + if (!empty($where['create_time'][0]) && !empty($where['create_time'][1])) { + $startTime = strtotime($where['create_time'][0]); + $endTime = strtotime($where['create_time'][1]); + $builder->betweenWhere('create_time', $startTime, $endTime); + } + if (isset($where['published'])) { $builder->andWhere('published = :published:', ['published' => $where['published']]); } diff --git a/app/Repos/Page.php b/app/Repos/Page.php index 90d1c1ab..fe633a44 100644 --- a/app/Repos/Page.php +++ b/app/Repos/Page.php @@ -24,6 +24,10 @@ class Page extends Repository $builder->where('1 = 1'); + if (!empty($where['id'])) { + $builder->andWhere('id = :id:', ['id' => $where['id']]); + } + if (!empty($where['title'])) { $builder->andWhere('title LIKE :title:', ['title' => "%{$where['title']}%"]); } diff --git a/app/Repos/PointGift.php b/app/Repos/PointGift.php index e73161ae..2717219b 100644 --- a/app/Repos/PointGift.php +++ b/app/Repos/PointGift.php @@ -28,6 +28,10 @@ class PointGift extends Repository $builder->andWhere('id = :id:', ['id' => $where['id']]); } + if (!empty($where['name'])) { + $builder->andWhere('name LIKE :name:', ['name' => "%{$where['name']}%"]); + } + if (!empty($where['type'])) { if (is_array($where['type'])) { $builder->inWhere('type', $where['type']); @@ -36,8 +40,10 @@ class PointGift extends Repository } } - if (!empty($where['name'])) { - $builder->andWhere('name LIKE :name:', ['name' => "%{$where['name']}%"]); + if (!empty($where['create_time'][0]) && !empty($where['create_time'][1])) { + $startTime = strtotime($where['create_time'][0]); + $endTime = strtotime($where['create_time'][1]); + $builder->betweenWhere('create_time', $startTime, $endTime); } if (isset($where['published'])) { diff --git a/app/Repos/PointHistory.php b/app/Repos/PointHistory.php index c5a54d14..b3e130d8 100644 --- a/app/Repos/PointHistory.php +++ b/app/Repos/PointHistory.php @@ -40,6 +40,12 @@ class PointHistory extends Repository } } + if (!empty($where['create_time'][0]) && !empty($where['create_time'][1])) { + $startTime = strtotime($where['create_time'][0]); + $endTime = strtotime($where['create_time'][1]); + $builder->betweenWhere('create_time', $startTime, $endTime); + } + switch ($sort) { case 'oldest': $orderBy = 'id ASC'; diff --git a/app/Repos/Question.php b/app/Repos/Question.php index 04fb05ff..8b874716 100644 --- a/app/Repos/Question.php +++ b/app/Repos/Question.php @@ -86,6 +86,12 @@ class Question extends Repository } } + if (!empty($where['create_time'][0]) && !empty($where['create_time'][1])) { + $startTime = strtotime($where['create_time'][0]); + $endTime = strtotime($where['create_time'][1]); + $builder->betweenWhere('create_time', $startTime, $endTime); + } + if (isset($where['deleted'])) { $builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]); } diff --git a/app/Repos/Refund.php b/app/Repos/Refund.php index bc18f914..51523929 100644 --- a/app/Repos/Refund.php +++ b/app/Repos/Refund.php @@ -42,16 +42,16 @@ class Refund extends Repository } } - if (isset($where['deleted'])) { - $builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]); - } - if (!empty($where['start_time']) && !empty($where['end_time'])) { $startTime = strtotime($where['start_time']); $endTime = strtotime($where['end_time']); $builder->betweenWhere('create_time', $startTime, $endTime); } + if (isset($where['deleted'])) { + $builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]); + } + switch ($sort) { case 'oldest': $orderBy = 'id ASC'; diff --git a/app/Repos/Report.php b/app/Repos/Report.php index b0b9942c..0f39c56f 100644 --- a/app/Repos/Report.php +++ b/app/Repos/Report.php @@ -24,6 +24,10 @@ class Report extends Repository $builder->where('1 = 1'); + if (!empty($where['owner_id'])) { + $builder->andWhere('owner_id = :owner_id:', ['owner_id' => $where['owner_id']]); + } + if (!empty($where['item_id'])) { $builder->andWhere('item_id = :item_id:', ['item_id' => $where['item_id']]); } @@ -36,8 +40,10 @@ class Report extends Repository } } - if (!empty($where['owner_id'])) { - $builder->andWhere('owner_id = :owner_id:', ['owner_id' => $where['owner_id']]); + if (!empty($where['create_time'][0]) && !empty($where['create_time'][1])) { + $startTime = strtotime($where['create_time'][0]); + $endTime = strtotime($where['create_time'][1]); + $builder->betweenWhere('create_time', $startTime, $endTime); } if (isset($where['reviewed'])) { diff --git a/app/Repos/Resource.php b/app/Repos/Resource.php index 756cf537..dbcd1f6a 100644 --- a/app/Repos/Resource.php +++ b/app/Repos/Resource.php @@ -51,15 +51,4 @@ class Resource extends Repository ->execute(); } - /** - * @param int $chapterId - * @return ResultsetInterface|Resultset|ResourceModel[] - */ - public function findByChapterId($chapterId) - { - return ResourceModel::query() - ->where('chapter_id = :chapter_id:', ['chapter_id' => $chapterId]) - ->execute(); - } - } diff --git a/app/Repos/Review.php b/app/Repos/Review.php index 42b9424e..8f3f7a0a 100644 --- a/app/Repos/Review.php +++ b/app/Repos/Review.php @@ -45,6 +45,12 @@ class Review extends Repository } } + if (!empty($where['create_time'][0]) && !empty($where['create_time'][1])) { + $startTime = strtotime($where['create_time'][0]); + $endTime = strtotime($where['create_time'][1]); + $builder->betweenWhere('create_time', $startTime, $endTime); + } + if (isset($where['deleted'])) { $builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]); } diff --git a/app/Repos/Slide.php b/app/Repos/Slide.php index 91f9000c..532f0ded 100644 --- a/app/Repos/Slide.php +++ b/app/Repos/Slide.php @@ -36,6 +36,12 @@ class Slide extends Repository $builder->andWhere('target = :target:', ['target' => $where['target']]); } + if (!empty($where['create_time'][0]) && !empty($where['create_time'][1])) { + $startTime = strtotime($where['create_time'][0]); + $endTime = strtotime($where['create_time'][1]); + $builder->betweenWhere('create_time', $startTime, $endTime); + } + if (isset($where['published'])) { $builder->andWhere('published = :published:', ['published' => $where['published']]); } diff --git a/app/Repos/Stat.php b/app/Repos/Stat.php index c8d073e8..921b7b2f 100644 --- a/app/Repos/Stat.php +++ b/app/Repos/Stat.php @@ -76,28 +76,28 @@ class Stat extends Repository public function countReportedArticles() { return (int)ArticleModel::count([ - 'conditions' => 'report_count > 0', + 'conditions' => 'report_count > 0 AND deleted = 0', ]); } public function countReportedQuestions() { return (int)QuestionModel::count([ - 'conditions' => 'report_count > 0', + 'conditions' => 'report_count > 0 AND deleted = 0', ]); } public function countReportedAnswers() { return (int)AnswerModel::count([ - 'conditions' => 'report_count > 0', + 'conditions' => 'report_count > 0 AND deleted = 0', ]); } public function countReportedComments() { return (int)CommentModel::count([ - 'conditions' => 'report_count > 0', + 'conditions' => 'report_count > 0 AND deleted = 0', ]); } diff --git a/app/Repos/Tag.php b/app/Repos/Tag.php index 0d53979c..393d26cc 100644 --- a/app/Repos/Tag.php +++ b/app/Repos/Tag.php @@ -35,6 +35,12 @@ class Tag extends Repository $builder->andWhere('name LIKE :name:', ['name' => "%{$where['name']}%"]); } + if (!empty($where['create_time'][0]) && !empty($where['create_time'][1])) { + $startTime = strtotime($where['create_time'][0]); + $endTime = strtotime($where['create_time'][1]); + $builder->betweenWhere('create_time', $startTime, $endTime); + } + if (isset($where['published'])) { $builder->andWhere('published = :published:', ['published' => $where['published']]); } diff --git a/app/Repos/Task.php b/app/Repos/Task.php index 3bcee4ff..5e25c3d4 100644 --- a/app/Repos/Task.php +++ b/app/Repos/Task.php @@ -33,11 +33,25 @@ class Task extends Repository } if (!empty($where['item_type'])) { - $builder->andWhere('item_type = :item_type:', ['item_type' => $where['item_type']]); + if (is_array($where['item_type'])) { + $builder->inWhere('item_type', $where['item_type']); + } else { + $builder->andWhere('item_type = :item_type:', ['item_type' => $where['item_type']]); + } } if (!empty($where['status'])) { - $builder->andWhere('status = :status:', ['status' => $where['status']]); + if (is_array($where['status'])) { + $builder->inWhere('status', $where['status']); + } else { + $builder->andWhere('status = :status:', ['status' => $where['status']]); + } + } + + if (!empty($where['create_time'][0]) && !empty($where['create_time'][1])) { + $startTime = strtotime($where['create_time'][0]); + $endTime = strtotime($where['create_time'][1]); + $builder->betweenWhere('create_time', $startTime, $endTime); } if (isset($where['locked'])) { diff --git a/app/Repos/Topic.php b/app/Repos/Topic.php index 3ab32d11..deec1883 100644 --- a/app/Repos/Topic.php +++ b/app/Repos/Topic.php @@ -34,6 +34,12 @@ class Topic extends Repository $builder->andWhere('title LIKE :title:', ['title' => "%{$where['title']}%"]); } + if (!empty($where['create_time'][0]) && !empty($where['create_time'][1])) { + $startTime = strtotime($where['create_time'][0]); + $endTime = strtotime($where['create_time'][1]); + $builder->betweenWhere('create_time', $startTime, $endTime); + } + if (isset($where['published'])) { $builder->andWhere('published = :published:', ['published' => $where['published']]); } diff --git a/app/Repos/Trade.php b/app/Repos/Trade.php index 1dfd7470..bfd63a03 100644 --- a/app/Repos/Trade.php +++ b/app/Repos/Trade.php @@ -58,16 +58,16 @@ class Trade extends Repository } } - if (isset($where['deleted'])) { - $builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]); - } - if (!empty($where['start_time']) && !empty($where['end_time'])) { $startTime = strtotime($where['start_time']); $endTime = strtotime($where['end_time']); $builder->betweenWhere('create_time', $startTime, $endTime); } + if (isset($where['deleted'])) { + $builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]); + } + switch ($sort) { case 'oldest': $orderBy = 'id ASC'; diff --git a/app/Repos/User.php b/app/Repos/User.php index c2a3e908..6038f167 100644 --- a/app/Repos/User.php +++ b/app/Repos/User.php @@ -56,6 +56,18 @@ class User extends Repository } } + if (!empty($where['create_time'][0]) && !empty($where['create_time'][1])) { + $startTime = strtotime($where['create_time'][0]); + $endTime = strtotime($where['create_time'][1]); + $builder->betweenWhere('create_time', $startTime, $endTime); + } + + if (!empty($where['active_time'][0]) && !empty($where['active_time'][1])) { + $startTime = strtotime($where['active_time'][0]); + $endTime = strtotime($where['active_time'][1]); + $builder->betweenWhere('active_time', $startTime, $endTime); + } + if (isset($where['vip'])) { $builder->andWhere('vip = :vip:', ['vip' => $where['vip']]); } diff --git a/app/Repos/Vip.php b/app/Repos/Vip.php index 4ef15e83..8e00e228 100644 --- a/app/Repos/Vip.php +++ b/app/Repos/Vip.php @@ -7,6 +7,8 @@ namespace App\Repos; +use App\Library\Paginator\Adapter\QueryBuilder as PagerQueryBuilder; +use App\Models\Page as PageModel; use App\Models\Vip as VipModel; use Phalcon\Mvc\Model; use Phalcon\Mvc\Model\Resultset; @@ -15,21 +17,58 @@ use Phalcon\Mvc\Model\ResultsetInterface; class Vip extends Repository { - /** - * @param array $where - * @return ResultsetInterface|Resultset|VipModel[] - */ - public function findAll($where = []) + public function paginate($where = [], $sort = 'latest', $page = 1, $limit = 15) { - $query = VipModel::query(); + $builder = $this->modelsManager->createBuilder(); - $query->where('1 = 1'); + $builder->from(VipModel::class); - if (isset($where['deleted'])) { - $query->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]); + $builder->where('1 = 1'); + + if (isset($where['published'])) { + $builder->andWhere('published = :published:', ['published' => $where['published']]); } - return $query->execute(); + if (isset($where['deleted'])) { + $builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]); + } + + switch ($sort) { + case 'price': + $orderBy = 'price ASC'; + break; + case 'oldest': + $orderBy = 'id ASC'; + break; + default: + $orderBy = 'id DESC'; + break; + } + + $builder->orderBy($orderBy); + + $pager = new PagerQueryBuilder([ + 'builder' => $builder, + 'page' => $page, + 'limit' => $limit, + ]); + + return $pager->paginate(); + } + + /** + * @param array $where + * @param string $sort + * @return ResultsetInterface|Resultset|PageModel[] + */ + public function findAll($where = [], $sort = 'latest') + { + /** + * 一个偷懒的实现,适用于中小体量数据 + */ + $paginate = $this->paginate($where, $sort, 1, 10000); + + return $paginate->items; } /** diff --git a/app/Services/Category.php b/app/Services/Category.php index 69922526..0e87ee5c 100644 --- a/app/Services/Category.php +++ b/app/Services/Category.php @@ -9,11 +9,40 @@ namespace App\Services; use App\Caches\Category as CategoryCache; use App\Caches\CategoryList as CategoryListCache; +use App\Caches\CategoryTreeList as CategoryTreeListCache; use App\Models\Category as CategoryModel; class Category extends Service { + public function getCategoryOptions($type) + { + $cache = new CategoryTreeListCache(); + + $categories = $cache->get($type); + + $result = []; + + if (!$categories) return $result; + + foreach ($categories as $category) { + $result[] = [ + 'id' => $category['id'], + 'name' => $category['name'], + ]; + if (count($category['children']) > 0) { + foreach ($category['children'] as $child) { + $result[] = [ + 'id' => $child['id'], + 'name' => sprintf('|--- %s', $child['name']), + ]; + } + } + } + + return $result; + } + /** * 获取节点路径 * diff --git a/app/Services/Logic/Answer/AnswerInfo.php b/app/Services/Logic/Answer/AnswerInfo.php index 1bdd1260..50d7fba0 100644 --- a/app/Services/Logic/Answer/AnswerInfo.php +++ b/app/Services/Logic/Answer/AnswerInfo.php @@ -13,13 +13,12 @@ use App\Repos\AnswerLike as AnswerLikeRepo; use App\Repos\Question as QuestionRepo; use App\Services\Logic\AnswerTrait; use App\Services\Logic\Service as LogicService; -use App\Services\Logic\UserTrait; +use App\Services\Logic\User\ShallowUserInfo; class AnswerInfo extends LogicService { use AnswerTrait; - use UserTrait; public function handle($id) { @@ -33,7 +32,7 @@ class AnswerInfo extends LogicService protected function handleAnswer(AnswerModel $answer, UserModel $user) { $question = $this->handleQuestionInfo($answer->question_id); - $owner = $this->handleShallowUserInfo($answer->owner_id); + $owner = $this->handleOwnerInfo($answer->owner_id); $me = $this->handleMeInfo($answer, $user); return [ @@ -65,6 +64,13 @@ class AnswerInfo extends LogicService ]; } + protected function handleOwnerInfo($userId) + { + $service = new ShallowUserInfo(); + + return $service->handle($userId); + } + protected function handleMeInfo(AnswerModel $answer, UserModel $user) { $me = [ @@ -73,12 +79,12 @@ class AnswerInfo extends LogicService 'owned' => 0, ]; - if ($user->id == $answer->owner_id) { - $me['owned'] = 1; - } - if ($user->id > 0) { + if ($user->id == $answer->owner_id) { + $me['owned'] = 1; + } + $me['logged'] = 1; $likeRepo = new AnswerLikeRepo(); diff --git a/app/Services/Logic/Article/ArticleDataTrait.php b/app/Services/Logic/Article/ArticleDataTrait.php index ef40bdfa..5128c79f 100644 --- a/app/Services/Logic/Article/ArticleDataTrait.php +++ b/app/Services/Logic/Article/ArticleDataTrait.php @@ -49,10 +49,6 @@ trait ArticleDataTrait $data['closed'] = $validator->checkCloseStatus($post['closed']); } - if (isset($post['private'])) { - $data['private'] = $validator->checkPrivateStatus($post['private']); - } - return $data; } @@ -63,8 +59,14 @@ trait ArticleDataTrait protected function saveDynamicAttrs(ArticleModel $article) { - $article->cover = kg_parse_first_content_image($article->content); - $article->summary = kg_parse_summary($article->content); + if (empty($article->cover)) { + $article->cover = kg_parse_first_content_image($article->content); + } + + if (empty($article->summary)) { + $article->summary = kg_parse_summary($article->content); + } + $article->word_count = WordUtil::getWordCount($article->content); $article->update(); diff --git a/app/Services/Logic/Article/ArticleInfo.php b/app/Services/Logic/Article/ArticleInfo.php index bb480272..6ad3bdbe 100644 --- a/app/Services/Logic/Article/ArticleInfo.php +++ b/app/Services/Logic/Article/ArticleInfo.php @@ -15,20 +15,19 @@ use App\Repos\ArticleFavorite as ArticleFavoriteRepo; use App\Repos\ArticleLike as ArticleLikeRepo; use App\Services\Logic\ArticleTrait; use App\Services\Logic\Service as LogicService; -use App\Services\Logic\UserTrait; +use App\Services\Logic\User\ShallowUserInfo; class ArticleInfo extends LogicService { use ArticleTrait; - use UserTrait; public function handle($id) { - $user = $this->getCurrentUser(true); - $article = $this->checkArticle($id); + $user = $this->getCurrentUser(true); + $result = $this->handleArticle($article, $user); $this->incrArticleViewCount($article); @@ -41,7 +40,7 @@ class ArticleInfo extends LogicService protected function handleArticle(ArticleModel $article, UserModel $user) { $category = $this->handleCategoryInfo($article->category_id); - $owner = $this->handleShallowUserInfo($article->owner_id); + $owner = $this->handleOwnerInfo($article->owner_id); $me = $this->handleMeInfo($article, $user); return [ @@ -52,7 +51,6 @@ class ArticleInfo extends LogicService 'keywords' => $article->keywords, 'tags' => $article->tags, 'content' => $article->content, - 'private' => $article->private, 'closed' => $article->closed, 'published' => $article->published, 'deleted' => $article->deleted, @@ -88,6 +86,13 @@ class ArticleInfo extends LogicService ]; } + protected function handleOwnerInfo($userId) + { + $service = new ShallowUserInfo(); + + return $service->handle($userId); + } + protected function handleMeInfo(ArticleModel $article, UserModel $user) { $me = [ @@ -97,12 +102,12 @@ class ArticleInfo extends LogicService 'owned' => 0, ]; - if ($user->id == $article->owner_id) { - $me['owned'] = 1; - } - if ($user->id > 0) { + if ($user->id == $article->owner_id) { + $me['owned'] = 1; + } + $me['logged'] = 1; $likeRepo = new ArticleLikeRepo(); diff --git a/app/Services/Logic/Article/ArticleList.php b/app/Services/Logic/Article/ArticleList.php index fdfd9e8a..4dec3ad8 100644 --- a/app/Services/Logic/Article/ArticleList.php +++ b/app/Services/Logic/Article/ArticleList.php @@ -11,6 +11,7 @@ use App\Builders\ArticleList as ArticleListBuilder; use App\Library\Paginator\Query as PagerQuery; use App\Models\Article as ArticleModel; use App\Repos\Article as ArticleRepo; +use App\Services\Category as CategoryService; use App\Services\Logic\Service as LogicService; use App\Validators\ArticleQuery as ArticleQueryValidator; @@ -25,8 +26,28 @@ class ArticleList extends LogicService $params = $this->checkQueryParams($params); + /** + * tc => top_category + * sc => sub_category + */ + if (!empty($params['sc'])) { + + $params['category_id'] = $params['sc']; + + } elseif (!empty($params['tc'])) { + + $categoryService = new CategoryService(); + + $childCategoryIds = $categoryService->getChildCategoryIds($params['tc']); + + $parentCategoryIds = [$params['tc']]; + + $allCategoryIds = array_merge($parentCategoryIds, $childCategoryIds); + + $params['category_id'] = $allCategoryIds; + } + $params['published'] = ArticleModel::PUBLISH_APPROVED; - $params['private'] = 0; $params['deleted'] = 0; $sort = $pagerQuery->getSort(); @@ -72,7 +93,6 @@ class ArticleList extends LogicService 'source_type' => $article['source_type'], 'source_url' => $article['source_url'], 'tags' => $article['tags'], - 'private' => $article['private'], 'published' => $article['published'], 'closed' => $article['closed'], 'view_count' => $article['view_count'], @@ -97,12 +117,19 @@ class ArticleList extends LogicService $query = []; - if (isset($params['category_id'])) { - $query['category_id'] = $validator->checkCategory($params['category_id']); + if (isset($params['tag_id'])) { + $tag = $validator->checkTag($params['tag_id']); + $query['tag_id'] = $tag->id; } - if (isset($params['tag_id'])) { - $query['tag_id'] = $validator->checkTag($params['tag_id']); + if (isset($params['tc'])) { + $category = $validator->checkCategory($params['tc']); + $query['tc'] = $category->id; + } + + if (isset($params['sc'])) { + $category = $validator->checkCategory($params['sc']); + $query['sc'] = $category->id; } if (isset($params['sort'])) { diff --git a/app/Services/Logic/Article/ArticlePrivate.php b/app/Services/Logic/Article/ArticlePrivate.php deleted file mode 100644 index e9e0d59a..00000000 --- a/app/Services/Logic/Article/ArticlePrivate.php +++ /dev/null @@ -1,36 +0,0 @@ -checkArticle($id); - - $user = $this->getLoginUser(); - - $validator = new AppValidator(); - - $validator->checkOwner($user->id, $article->owner_id); - - $article->private = $article->private == 1 ? 0 : 1; - - $article->update(); - - return $article; - } - -} diff --git a/app/Services/Logic/Chapter/ChapterInfo.php b/app/Services/Logic/Chapter/ChapterInfo.php index cc7e34a4..b6cd75b5 100644 --- a/app/Services/Logic/Chapter/ChapterInfo.php +++ b/app/Services/Logic/Chapter/ChapterInfo.php @@ -90,17 +90,19 @@ class ChapterInfo extends LogicService $courseUser = new CourseUserModel(); - $roleType = CourseUserModel::ROLE_STUDENT; $sourceType = CourseUserModel::SOURCE_FREE; - if ($course->market_price > 0 && $course->vip_price == 0 && $user->vip == 1) { - $sourceType = CourseUserModel::SOURCE_VIP; + if ($course->market_price > 0) { + if ($course->vip_price == 0 && $user->vip == 1) { + $sourceType = CourseUserModel::SOURCE_VIP; + } else { + $sourceType = CourseUserModel::SOURCE_TRIAL; + } } $courseUser->course_id = $course->id; $courseUser->user_id = $user->id; $courseUser->source_type = $sourceType; - $courseUser->role_type = $roleType; $courseUser->create(); @@ -109,7 +111,6 @@ class ChapterInfo extends LogicService $this->joinedCourse = true; $this->incrCourseUserCount($course); - $this->incrUserCourseCount($user); } @@ -125,7 +126,6 @@ class ChapterInfo extends LogicService $chapterUser = new ChapterUserModel(); - $chapterUser->plan_id = $this->courseUser->plan_id; $chapterUser->course_id = $chapter->course_id; $chapterUser->chapter_id = $chapter->id; $chapterUser->user_id = $user->id; @@ -142,8 +142,8 @@ class ChapterInfo extends LogicService protected function handleMeInfo(ChapterModel $chapter, UserModel $user) { $me = [ - 'role_type' => 0, 'plan_id' => 0, + 'manager' => 0, 'position' => 0, 'logged' => 0, 'joined' => 0, @@ -153,6 +153,8 @@ class ChapterInfo extends LogicService if ($user->id > 0) { + $me['logged'] = 1; + if ($this->joinedChapter) { $me['joined'] = 1; } @@ -161,8 +163,6 @@ class ChapterInfo extends LogicService $me['owned'] = 1; } - $me['logged'] = 1; - $likeRepo = new ChapterLikeRepo(); $like = $likeRepo->findChapterLike($chapter->id, $user->id); @@ -171,14 +171,17 @@ class ChapterInfo extends LogicService $me['liked'] = 1; } - if ($this->courseUser) { - $me['role_type'] = $this->courseUser->role_type; - $me['plan_id'] = $this->courseUser->plan_id; + if ($this->course->teacher_id == $user->id) { + $me['manager'] = 1; } if ($this->chapterUser) { $me['position'] = $this->chapterUser->position; } + + if ($this->courseUser) { + $me['plan_id'] = $this->courseUser->plan_id; + } } return $me; diff --git a/app/Services/Logic/Chapter/DanmuList.php b/app/Services/Logic/Chapter/DanmuList.php deleted file mode 100644 index 2c866afa..00000000 --- a/app/Services/Logic/Chapter/DanmuList.php +++ /dev/null @@ -1,72 +0,0 @@ -checkChapter($id); - - $params = []; - - $params['chapter_id'] = $chapter->id; - $params['published'] = 1; - - $danmuRepo = new DanmuRepo(); - - $items = $danmuRepo->findAll($params); - - $result = []; - - if ($items->count() > 0) { - $result = $this->handleItems($items->toArray()); - } - - return $result; - } - - /** - * @param array $items - * @return array - */ - protected function handleItems($items) - { - $builder = new DanmuListBuilder(); - - $users = $builder->getUsers($items); - - $result = []; - - foreach ($items as $item) { - - $owner = $users[$item['owner_id']] ?? new \stdClass(); - - $result[] = [ - 'id' => $item['id'], - 'text' => $item['text'], - 'color' => $item['color'], - 'size' => $item['size'], - 'time' => $item['time'], - 'position' => $item['position'], - 'owner' => $owner, - ]; - } - - return $result; - } - -} diff --git a/app/Services/Logic/ChapterTrait.php b/app/Services/Logic/ChapterTrait.php index 6a2c19a9..877c111c 100644 --- a/app/Services/Logic/ChapterTrait.php +++ b/app/Services/Logic/ChapterTrait.php @@ -80,7 +80,7 @@ trait ChapterTrait if ($courseUser) { $chapterUserRepo = new ChapterUserRepo(); - $chapterUser = $chapterUserRepo->findPlanChapterUser($chapter->id, $user->id, $courseUser->plan_id); + $chapterUser = $chapterUserRepo->findChapterUser($chapter->id, $user->id); } $this->chapterUser = $chapterUser; diff --git a/app/Services/Logic/Comment/CommentInfo.php b/app/Services/Logic/Comment/CommentInfo.php index dc5b6ad7..d0322310 100644 --- a/app/Services/Logic/Comment/CommentInfo.php +++ b/app/Services/Logic/Comment/CommentInfo.php @@ -12,6 +12,7 @@ use App\Models\User as UserModel; use App\Repos\AnswerLike as AnswerLikeRepo; use App\Services\Logic\CommentTrait; use App\Services\Logic\Service as LogicService; +use App\Services\Logic\User\ShallowUserInfo; use App\Services\Logic\UserTrait; class CommentInfo extends LogicService @@ -31,8 +32,8 @@ class CommentInfo extends LogicService protected function handleComment(CommentModel $comment, UserModel $user) { - $toUser = $this->handleShallowUserInfo($comment->to_user_id); - $owner = $this->handleShallowUserInfo($comment->owner_id); + $toUser = $this->handleToUserInfo($comment->to_user_id); + $owner = $this->handleOwnerInfo($comment->owner_id); $me = $this->handleMeInfo($comment, $user); return [ @@ -51,6 +52,22 @@ class CommentInfo extends LogicService ]; } + protected function handleToUserInfo($userId) + { + if ($userId == 0) return new \stdClass(); + + $service = new ShallowUserInfo(); + + return $service->handle($userId); + } + + protected function handleOwnerInfo($userId) + { + $service = new ShallowUserInfo(); + + return $service->handle($userId); + } + protected function handleMeInfo(CommentModel $comment, UserModel $user) { $me = [ diff --git a/app/Services/Logic/Consult/ConsultCreate.php b/app/Services/Logic/Consult/ConsultCreate.php index 28f52634..402ddb5c 100644 --- a/app/Services/Logic/Consult/ConsultCreate.php +++ b/app/Services/Logic/Consult/ConsultCreate.php @@ -7,13 +7,10 @@ namespace App\Services\Logic\Consult; -use App\Models\Chapter as ChapterModel; use App\Models\Consult as ConsultModel; use App\Models\Course as CourseModel; use App\Models\User as UserModel; -use App\Repos\Chapter as ChapterRepo; use App\Repos\Course as CourseRepo; -use App\Services\Logic\ChapterTrait; use App\Services\Logic\CourseTrait; use App\Services\Logic\Notice\External\DingTalk\ConsultCreate as ConsultCreateNotice; use App\Services\Logic\Service as LogicService; @@ -24,13 +21,11 @@ use App\Validators\UserLimit as UserLimitValidator; class ConsultCreate extends LogicService { - use ChapterTrait; use ClientTrait; use CourseTrait; public function handle() { - $chapterId = $this->request->getPost('chapter_id', 'int', 0); $courseId = $this->request->getPost('course_id', 'int', 0); $user = $this->getLoginUser(); @@ -43,18 +38,9 @@ class ConsultCreate extends LogicService $validator->checkDailyConsultLimit($user); - if ($chapterId > 0) { + $course = $this->checkCourse($courseId); - $chapter = $this->checkChapter($chapterId); - - return $this->handleChapterConsult($chapter, $user); - - } elseif ($courseId > 0) { - - $course = $this->checkCourse($courseId); - - return $this->handleCourseConsult($course, $user); - } + return $this->handleCourseConsult($course, $user); } protected function handleCourseConsult(CourseModel $course, UserModel $user) @@ -84,7 +70,7 @@ class ConsultCreate extends LogicService $consult->owner_id = $user->id; $consult->client_type = $this->getClientType(); $consult->client_ip = $this->getClientIp(); - $consult->published = 1; + $consult->published = ConsultModel::PUBLISH_PENDING; $consult->create(); @@ -97,50 +83,6 @@ class ConsultCreate extends LogicService return $consult; } - protected function handleChapterConsult(ChapterModel $chapter, UserModel $user) - { - $course = $this->checkCourse($chapter->course_id); - - $post = $this->request->getPost(); - - $validator = new ConsultValidator(); - - $question = $validator->checkQuestion($post['question']); - - $private = 0; - - if (isset($post['private'])) { - $private = $validator->checkPrivateStatus($post['private']); - } - - $validator->checkIfDuplicated($course->id, $user->id, $question); - - $priority = $this->getPriority($course, $user); - - $consult = new ConsultModel(); - - $consult->question = $question; - $consult->private = $private; - $consult->priority = $priority; - $consult->course_id = $course->id; - $consult->chapter_id = $chapter->id; - $consult->owner_id = $user->id; - $consult->client_type = $this->getClientType(); - $consult->client_ip = $this->getClientIp(); - $consult->published = 1; - - $consult->create(); - - $this->recountCourseConsults($course); - $this->recountChapterConsults($chapter); - $this->incrUserDailyConsultCount($user); - $this->handleConsultCreateNotice($consult); - - $this->eventsManager->fire('Consult:afterCreate', $this, $consult); - - return $consult; - } - protected function getPriority(CourseModel $course, UserModel $user) { $charge = $course->market_price > 0; @@ -169,17 +111,6 @@ class ConsultCreate extends LogicService $course->update(); } - protected function recountChapterConsults(ChapterModel $chapter) - { - $chapterRepo = new ChapterRepo(); - - $consultCount = $chapterRepo->countConsults($chapter->id); - - $chapter->consult_count = $consultCount; - - $chapter->update(); - } - protected function incrUserDailyConsultCount(UserModel $user) { $this->eventsManager->fire('UserDailyCounter:incrConsultCount', $this, $user); diff --git a/app/Services/Logic/Consult/ConsultDelete.php b/app/Services/Logic/Consult/ConsultDelete.php index bd26b0ed..56a798f4 100644 --- a/app/Services/Logic/Consult/ConsultDelete.php +++ b/app/Services/Logic/Consult/ConsultDelete.php @@ -7,11 +7,8 @@ namespace App\Services\Logic\Consult; -use App\Models\Chapter as ChapterModel; use App\Models\Course as CourseModel; -use App\Repos\Chapter as ChapterRepo; use App\Repos\Course as CourseRepo; -use App\Services\Logic\ChapterTrait; use App\Services\Logic\ConsultTrait; use App\Services\Logic\CourseTrait; use App\Services\Logic\Service as LogicService; @@ -21,7 +18,6 @@ class ConsultDelete extends LogicService { use CourseTrait; - use ChapterTrait; use ConsultTrait; public function handle($id) @@ -38,19 +34,9 @@ class ConsultDelete extends LogicService $consult->update(); - if ($consult->course_id > 0) { + $course = $this->checkCourse($consult->course_id); - $course = $this->checkCourse($consult->course_id); - - $this->recountCourseConsults($course); - } - - if ($consult->chapter_id > 0) { - - $chapter = $this->checkChapter($consult->chapter_id); - - $this->recountChapterConsults($chapter); - } + $this->recountCourseConsults($course); $this->eventsManager->fire('Consult:afterDelete', $this, $consult); } @@ -66,15 +52,4 @@ class ConsultDelete extends LogicService $course->update(); } - protected function recountChapterConsults(ChapterModel $chapter) - { - $chapterRepo = new ChapterRepo(); - - $consultCount = $chapterRepo->countConsults($chapter->id); - - $chapter->consult_count = $consultCount; - - $chapter->update(); - } - } diff --git a/app/Services/Logic/Consult/ConsultInfo.php b/app/Services/Logic/Consult/ConsultInfo.php index cb92232b..7370fef0 100644 --- a/app/Services/Logic/Consult/ConsultInfo.php +++ b/app/Services/Logic/Consult/ConsultInfo.php @@ -9,18 +9,16 @@ namespace App\Services\Logic\Consult; use App\Models\Consult as ConsultModel; use App\Models\User as UserModel; -use App\Repos\Chapter as ChapterRepo; use App\Repos\ConsultLike as ConsultLikeRepo; use App\Repos\Course as CourseRepo; use App\Services\Logic\ConsultTrait; use App\Services\Logic\Service as LogicService; -use App\Services\Logic\UserTrait; +use App\Services\Logic\User\ShallowUserInfo; class ConsultInfo extends LogicService { use ConsultTrait; - use UserTrait; public function handle($id) { @@ -34,9 +32,8 @@ class ConsultInfo extends LogicService protected function handleConsult(ConsultModel $consult, UserModel $user) { $course = $this->handleCourseInfo($consult->course_id); - $chapter = $this->handleChapterInfo($consult->chapter_id); - $replier = $this->handleShallowUserInfo($consult->replier_id); - $owner = $this->handleShallowUserInfo($consult->owner_id); + $replier = $this->handleReplierInfo($consult->replier_id); + $owner = $this->handleOwnerInfo($consult->owner_id); $me = $this->handleMeInfo($consult, $user); return [ @@ -51,7 +48,6 @@ class ConsultInfo extends LogicService 'create_time' => $consult->create_time, 'update_time' => $consult->update_time, 'course' => $course, - 'chapter' => $chapter, 'replier' => $replier, 'owner' => $owner, 'me' => $me, @@ -64,8 +60,6 @@ class ConsultInfo extends LogicService $course = $courseRepo->findById($courseId); - if (!$course) return new \stdClass(); - return [ 'id' => $course->id, 'title' => $course->title, @@ -73,18 +67,20 @@ class ConsultInfo extends LogicService ]; } - protected function handleChapterInfo($chapterId) + protected function handleOwnerInfo($userId) { - $chapterRepo = new ChapterRepo(); + $service = new ShallowUserInfo(); - $chapter = $chapterRepo->findById($chapterId); + return $service->handle($userId); + } - if (!$chapter) return new \stdClass(); + protected function handleReplierInfo($userId) + { + if ($userId == 0) return new \stdClass(); - return [ - 'id' => $chapter->id, - 'title' => $chapter->title, - ]; + $service = new ShallowUserInfo(); + + return $service->handle($userId); } protected function handleMeInfo(ConsultModel $consult, UserModel $user) @@ -95,12 +91,12 @@ class ConsultInfo extends LogicService 'owned' => 0, ]; - if ($user->id == $consult->owner_id) { - $me['owned'] = 1; - } - if ($user->id > 0) { + if ($user->id == $consult->owner_id) { + $me['owned'] = 1; + } + $me['logged'] = 1; $likeRepo = new ConsultLikeRepo(); diff --git a/app/Services/Logic/Course/BasicInfo.php b/app/Services/Logic/Course/BasicInfo.php index 26602ebe..81968130 100644 --- a/app/Services/Logic/Course/BasicInfo.php +++ b/app/Services/Logic/Course/BasicInfo.php @@ -7,11 +7,12 @@ namespace App\Services\Logic\Course; -use App\Caches\CourseTeacherList as CourseTeacherListCache; use App\Models\Course as CourseModel; use App\Repos\Course as CourseRepo; +use App\Services\Category as CategoryService; use App\Services\Logic\CourseTrait; use App\Services\Logic\Service as LogicService; +use App\Services\Logic\User\ShallowUserInfo as ShallowUserInfoService; class BasicInfo extends LogicService { @@ -27,14 +28,8 @@ class BasicInfo extends LogicService public function handleBasicInfo(CourseModel $course) { - $userCount = $course->user_count; - - if ($course->fake_user_count > $course->user_count) { - $userCount = $course->fake_user_count; - } - - $teachers = $this->handleTeachers($course); - + $categoryPaths = $this->handleCategoryPaths($course->category_id); + $teacher = $this->handleTeacherInfo($course->teacher_id); $ratings = $this->handleRatings($course); return [ @@ -44,19 +39,19 @@ class BasicInfo extends LogicService 'summary' => $course->summary, 'details' => $course->details, 'keywords' => $course->keywords, - 'origin_price' => (float)$course->origin_price, 'market_price' => (float)$course->market_price, 'vip_price' => (float)$course->vip_price, 'study_expiry' => $course->study_expiry, 'refund_expiry' => $course->refund_expiry, - 'teachers' => $teachers, + 'category_paths' => $categoryPaths, + 'teacher' => $teacher, 'ratings' => $ratings, 'model' => $course->model, 'level' => $course->level, 'attrs' => $course->attrs, 'published' => $course->published, 'deleted' => $course->deleted, - 'user_count' => $userCount, + 'user_count' => $course->getUserCount(), 'lesson_count' => $course->lesson_count, 'resource_count' => $course->resource_count, 'package_count' => $course->package_count, @@ -82,13 +77,22 @@ class BasicInfo extends LogicService ]; } - protected function handleTeachers(CourseModel $course) + protected function handleCategoryPaths($categoryId) { - $cache = new CourseTeacherListCache(); + if ($categoryId == 0) return new \stdClass(); - $result = $cache->get($course->id); + $service = new CategoryService(); - return $result ?: []; + return $service->getCategoryPaths($categoryId); + } + + protected function handleTeacherInfo($userId) + { + if ($userId == 0) return new \stdClass(); + + $service = new ShallowUserInfoService(); + + return $service->handle($userId); } } diff --git a/app/Services/Logic/Course/CourseInfo.php b/app/Services/Logic/Course/CourseInfo.php index 35132017..ca4c53d8 100644 --- a/app/Services/Logic/Course/CourseInfo.php +++ b/app/Services/Logic/Course/CourseInfo.php @@ -75,6 +75,8 @@ class CourseInfo extends LogicService if ($user->id > 0) { + $me['logged'] = 1; + if ($caseOwned && $casePrice && $caseModel) { $me['allow_order'] = 1; } @@ -91,8 +93,6 @@ class CourseInfo extends LogicService $me['owned'] = 1; } - $me['logged'] = 1; - $favoriteRepo = new CourseFavoriteRepo(); $favorite = $favoriteRepo->findCourseFavorite($course->id, $user->id); diff --git a/app/Services/Logic/Course/CourseUserTrait.php b/app/Services/Logic/Course/CourseUserTrait.php new file mode 100644 index 00000000..4c8a1608 --- /dev/null +++ b/app/Services/Logic/Course/CourseUserTrait.php @@ -0,0 +1,102 @@ +findCourseUser($course->id, $user->id); + + if (!$relation) { + + $relation = $this->createCourseUser($course, $user, $expiryTime, $sourceType); + + } else { + + switch ($relation->source_type) { + case CourseUserModel::SOURCE_FREE: + case CourseUserModel::SOURCE_TRIAL: + $this->createCourseUser($course, $user, $expiryTime, $sourceType); + $this->deleteCourseUser($relation); + break; + case CourseUserModel::SOURCE_MANUAL: + $relation->expiry_time = $expiryTime; + $relation->update(); + break; + case CourseUserModel::SOURCE_CHARGE: + case CourseUserModel::SOURCE_POINT_REDEEM: + case CourseUserModel::SOURCE_LUCKY_REDEEM: + if ($relation->expiry_time < time()) { + $this->createCourseUser($course, $user, $expiryTime, $sourceType); + $this->deleteCourseUser($relation); + } + break; + } + } + + $this->recountCourseUsers($course); + $this->recountUserCourses($user); + + return $relation; + } + + protected function createCourseUser(CourseModel $course, UserModel $user, int $expiryTime, int $sourceType) + { + $courseUser = new CourseUserModel(); + + $courseUser->course_id = $course->id; + $courseUser->user_id = $user->id; + $courseUser->expiry_time = $expiryTime; + $courseUser->source_type = $sourceType; + + $courseUser->create(); + + return $courseUser; + } + + protected function deleteCourseUser(CourseUserModel $relation) + { + $relation->deleted = 1; + + $relation->update(); + } + + protected function recountCourseUsers(CourseModel $course) + { + $courseRepo = new CourseRepo(); + + $userCount = $courseRepo->countUsers($course->id); + + $course->user_count = $userCount; + + $course->update(); + } + + protected function recountUserCourses(UserModel $user) + { + $userRepo = new UserRepo(); + + $courseCount = $userRepo->countCourses($user->id); + + $user->course_count = $courseCount; + + $user->update(); + } + +} diff --git a/app/Services/Logic/CourseTrait.php b/app/Services/Logic/CourseTrait.php index 15c6dbf6..91330c89 100644 --- a/app/Services/Logic/CourseTrait.php +++ b/app/Services/Logic/CourseTrait.php @@ -47,12 +47,11 @@ trait CourseTrait public function setCourseUser(CourseModel $course, UserModel $user) { - $courseUser = null; + if ($user->id == 0) return; - if ($user->id > 0) { - $courseUserRepo = new CourseUserRepo(); - $courseUser = $courseUserRepo->findCourseUser($course->id, $user->id); - } + $courseUserRepo = new CourseUserRepo(); + + $courseUser = $courseUserRepo->findCourseUser($course->id, $user->id); $this->courseUser = $courseUser; @@ -68,15 +67,11 @@ trait CourseTrait $this->ownedCourse = true; - } elseif ($courseUser && $courseUser->role_type == CourseUserModel::ROLE_TEACHER) { - - $this->ownedCourse = true; - - } elseif ($courseUser && $courseUser->role_type == CourseUserModel::ROLE_STUDENT) { + } elseif ($courseUser) { $sourceTypes = [ CourseUserModel::SOURCE_CHARGE, - CourseUserModel::SOURCE_IMPORT, + CourseUserModel::SOURCE_MANUAL, CourseUserModel::SOURCE_POINT_REDEEM, CourseUserModel::SOURCE_LUCKY_REDEEM, ]; diff --git a/app/Services/Logic/Danmu/DanmuCreate.php b/app/Services/Logic/Danmu/DanmuCreate.php deleted file mode 100644 index 3883b4a1..00000000 --- a/app/Services/Logic/Danmu/DanmuCreate.php +++ /dev/null @@ -1,64 +0,0 @@ -request->getPost(); - - $user = $this->getLoginUser(); - - $chapter = $this->checkChapter($post['chapter_id']); - - $validator = new UserLimitValidator(); - - $validator->checkDailyDanmuLimit($user); - - $validator = new DanmuValidator(); - - $danmu = new DanmuModel(); - - $data = []; - - $data['text'] = $validator->checkText($post['text']); - $data['position'] = $validator->checkPosition($post['position']); - $data['color'] = $validator->checkColor($post['color']); - $data['size'] = $validator->checkSize($post['size']); - $data['time'] = $validator->checkTime($post['time']); - - $data['course_id'] = $chapter->course_id; - $data['chapter_id'] = $chapter->id; - $data['owner_id'] = $user->id; - - $data['published'] = 1; - - $danmu->create($data); - - $this->incrUserDailyDanmuCount($user); - - return $danmu; - } - - protected function incrUserDailyDanmuCount(UserModel $user) - { - $this->eventsManager->fire('UserDailyCounter:incrDanmuCount', $this, $user); - } - -} diff --git a/app/Services/Logic/Danmu/DanmuInfo.php b/app/Services/Logic/Danmu/DanmuInfo.php deleted file mode 100644 index 9095e23a..00000000 --- a/app/Services/Logic/Danmu/DanmuInfo.php +++ /dev/null @@ -1,43 +0,0 @@ -checkDanmu($id); - - return $this->handleDanmu($danmu); - } - - protected function handleDanmu(DanmuModel $danmu) - { - $owner = $this->handleShallowUserInfo($danmu->owner_id); - - return [ - 'id' => $danmu->id, - 'text' => $danmu->text, - 'color' => $danmu->color, - 'size' => $danmu->size, - 'position' => $danmu->position, - 'time' => $danmu->time, - 'owner' => $owner, - ]; - } - -} diff --git a/app/Services/Logic/Deliver/CourseDeliver.php b/app/Services/Logic/Deliver/CourseDeliver.php index a52220a8..dbd9153e 100644 --- a/app/Services/Logic/Deliver/CourseDeliver.php +++ b/app/Services/Logic/Deliver/CourseDeliver.php @@ -11,11 +11,14 @@ 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 App\Services\Logic\Course\CourseUserTrait; use App\Services\Logic\Service as LogicService; class CourseDeliver extends LogicService { + use CourseUserTrait; + public function handle(CourseModel $course, UserModel $user) { $this->revokeCourseUser($course, $user); @@ -30,19 +33,11 @@ class CourseDeliver extends LogicService $expiryTime = strtotime("+{$course->study_expiry} months"); } - $courseUser = new CourseUserModel(); - $courseUser->user_id = $user->id; - $courseUser->course_id = $course->id; - $courseUser->expiry_time = $expiryTime; - $courseUser->role_type = CourseUserModel::ROLE_STUDENT; - $courseUser->source_type = CourseUserModel::SOURCE_CHARGE; - $courseUser->create(); + $sourceType = CourseUserModel::SOURCE_CHARGE; - $course->user_count += 1; - $course->update(); - - $user->course_count += 1; - $user->update(); + $this->createCourseUser($course, $user, $expiryTime, $sourceType); + $this->recountCourseUsers($course); + $this->recountUserCourses($user); } protected function revokeCourseUser(CourseModel $course, UserModel $user) diff --git a/app/Services/Logic/FlashSale/OrderCreate.php b/app/Services/Logic/FlashSale/OrderCreate.php deleted file mode 100644 index 137568b3..00000000 --- a/app/Services/Logic/FlashSale/OrderCreate.php +++ /dev/null @@ -1,116 +0,0 @@ -request->getPost('id', 'int'); - - $user = $this->getLoginUser(); - - $sale = $this->checkFlashSale($id); - - $saleValidator = new FlashSaleValidator(); - - $saleValidator->checkIfExpired($sale->end_time); - $saleValidator->checkIfOutSchedules($sale->schedules); - $saleValidator->checkIfNotPaid($user->id, $sale->id); - - $queue = new Queue(); - - if ($queue->pop($id) === false) { - throw new BadRequestException('flash_sale.out_stock'); - } - - $this->amount = $sale->price; - $this->promotion_id = $sale->id; - $this->promotion_type = OrderModel::PROMOTION_FLASH_SALE; - $this->promotion_info = [ - 'flash_sale' => [ - 'id' => $sale->id, - 'price' => $sale->price, - ] - ]; - - $orderValidator = new OrderValidator(); - - $orderValidator->checkAmount($this->amount); - - try { - - $order = new OrderModel(); - - if ($sale->item_type == FlashSaleModel::ITEM_COURSE) { - - $course = $orderValidator->checkCourse($sale->item_id); - - $orderValidator->checkIfBoughtCourse($user->id, $course->id); - - $order = $this->createCourseOrder($course, $user); - - } elseif ($sale->item_type == FlashSaleModel::ITEM_PACKAGE) { - - $package = $orderValidator->checkPackage($sale->item_id); - - $orderValidator->checkIfBoughtPackage($user->id, $package->id); - - $order = $this->createPackageOrder($package, $user); - - } elseif ($sale->item_type == FlashSaleModel::ITEM_VIP) { - - $vip = $orderValidator->checkVip($sale->item_id); - - $order = $this->createVipOrder($vip, $user); - } - - $this->decrFlashSaleStock($sale); - - $this->saveUserOrderCache($user->id, $sale->id); - - return $order; - - } catch (\Exception $e) { - - $queue->push($sale->id); - - throw new BadRequestException($e->getMessage()); - } - } - - protected function decrFlashSaleStock(FlashSaleModel $sale) - { - if ($sale->stock < 1) return; - - if ($sale->stock == 1) $sale->published = 0; - - $sale->stock -= 1; - - $sale->update(); - } - - protected function saveUserOrderCache($userId, $saleId) - { - $cache = new UserOrderCache(); - - return $cache->save($userId, $saleId); - } - -} diff --git a/app/Services/Logic/FlashSale/Queue.php b/app/Services/Logic/FlashSale/Queue.php deleted file mode 100644 index 1e4caa6a..00000000 --- a/app/Services/Logic/FlashSale/Queue.php +++ /dev/null @@ -1,82 +0,0 @@ -checkFlashSale($id); - - if ($sale->stock < 1) return; - - $redis = $this->getRedis(); - - $keyName = $this->getKeyName($id); - - $ttl = $sale->end_time - time(); - - $values = []; - - for ($i = 0; $i < $sale->stock; $i++) { - $values[] = 1; - } - - $redis->del($keyName); - $redis->lPush($keyName, ...$values); - $redis->expire($keyName, $ttl); - } - - public function pop($id) - { - $redis = $this->getRedis(); - - $keyName = $this->getKeyName($id); - - return $redis->lPop($keyName); - } - - public function push($id) - { - $redis = $this->getRedis(); - - $keyName = $this->getKeyName($id); - - return $redis->lPush($keyName, 1); - } - - public function delete($id) - { - $redis = $this->getRedis(); - - $keyName = $this->getKeyName($id); - - return $redis->del($keyName); - } - - public function length($id) - { - $redis = $this->getRedis(); - - $keyName = $this->getKeyName($id); - - return $redis->lLen($keyName); - } - - protected function getKeyName($id) - { - return "flash_sale_queue:{$id}"; - } - -} diff --git a/app/Services/Logic/FlashSale/SaleList.php b/app/Services/Logic/FlashSale/SaleList.php deleted file mode 100644 index df80645e..00000000 --- a/app/Services/Logic/FlashSale/SaleList.php +++ /dev/null @@ -1,161 +0,0 @@ -cosUrl = kg_cos_url(); - - $days = 3; - - $date = date('Y-m-d'); - - $saleRepo = new FlashSaleRepo(); - - $sales = $saleRepo->findFutureSales($date); - - if ($sales->count() == 0) return []; - - return $this->handleSales($sales, $days); - } - - protected function handleSales($sales, $days) - { - $dates = $this->getFutureDates($days); - - $result = []; - - foreach ($dates as $date) { - $result[] = [ - 'date' => date('m / d', strtotime($date)), - 'items' => $this->getDateSales($sales, $date), - ]; - } - - return $result; - } - - /** - * @param FlashSaleModel[] $sales - * @param string $date - * @return array - */ - protected function getDateSales($sales, $date) - { - $result = []; - - $schedules = FlashSaleModel::schedules(); - - $hasActiveStatus = false; - - foreach ($schedules as $schedule) { - - $items = []; - - $hour = $schedule['hour']; - - foreach ($sales as $sale) { - - $sale->item_info = $this->handleItemInfo($sale->item_type, $sale->item_info); - - $item = [ - 'id' => $sale->id, - 'stock' => $sale->stock, - 'price' => (float)$sale->price, - 'item_id' => $sale->item_id, - 'item_type' => $sale->item_type, - 'item_info' => $sale->item_info, - ]; - - $case1 = $sale->start_time <= strtotime($date); - $case2 = $sale->end_time > strtotime($date); - $case3 = in_array($hour, $sale->schedules); - - if ($case1 && $case2 && $case3) { - $items[] = $item; - } - } - - $status = $this->getSaleStatus($date, $hour); - - if ($status == 'active') { - $hasActiveStatus = true; - } - - $result[] = [ - 'hour' => sprintf('%02d:00', $hour), - 'selected' => $status == 'active' ? 1 : 0, - 'status' => $status, - 'items' => $items, - ]; - } - - /** - * 所在date无active状态,设置第一项为selected - */ - if (!$hasActiveStatus) { - $result[0]['selected'] = 1; - } - - return $result; - } - - protected function getFutureDates($days = 7) - { - $result = []; - - for ($i = 0; $i < $days; $i++) { - $result[] = date('Y-m-d', strtotime("+{$i} days")); - } - - return $result; - } - - protected function getSaleStatus($date, $hour) - { - if (strtotime($date) - strtotime('today') > 0) { - return 'pending'; - } - - $curHour = date('H'); - - if ($curHour >= $hour + 2) { - return 'finished'; - } elseif ($curHour >= $hour && $curHour < $hour + 2) { - return 'active'; - } else { - return 'pending'; - } - } - - protected function handleItemInfo($itemType, &$itemInfo) - { - if ($itemType == FlashSaleModel::ITEM_COURSE) { - $itemInfo['course']['cover'] = $this->cosUrl . $itemInfo['course']['cover']; - } elseif ($itemType == FlashSaleModel::ITEM_PACKAGE) { - $itemInfo['package']['cover'] = $this->cosUrl . $itemInfo['package']['cover']; - } elseif ($itemType == FlashSaleModel::ITEM_VIP) { - $itemInfo['vip']['cover'] = $this->cosUrl . $itemInfo['vip']['cover']; - } - - return $itemInfo; - } - -} diff --git a/app/Services/Logic/FlashSale/UserOrderCache.php b/app/Services/Logic/FlashSale/UserOrderCache.php deleted file mode 100644 index 3ebd9ca1..00000000 --- a/app/Services/Logic/FlashSale/UserOrderCache.php +++ /dev/null @@ -1,47 +0,0 @@ -getCache(); - - $keyName = $this->getKeyName($userId, $saleId); - - return $cache->get($keyName); - } - - public function save($userId, $saleId) - { - $cache = $this->getCache(); - - $keyName = $this->getKeyName($userId, $saleId); - - return $cache->save($keyName, 1, 2 * 3600); - } - - public function delete($userId, $saleId) - { - $cache = $this->getCache(); - - $keyName = $this->getKeyName($userId, $saleId); - - return $cache->delete($keyName); - } - - protected function getKeyName($userId, $saleId) - { - return "flash_sale_user_order:{$userId}_{$saleId}"; - } - -} diff --git a/app/Services/Logic/FlashSaleTrait.php b/app/Services/Logic/FlashSaleTrait.php deleted file mode 100644 index 71d8184d..00000000 --- a/app/Services/Logic/FlashSaleTrait.php +++ /dev/null @@ -1,29 +0,0 @@ -checkFlashSale($id); - } - - public function checkFlashSaleCache($id) - { - $validator = new FlashSaleValidator(); - - return $validator->checkFlashSaleCache($id); - } - -} diff --git a/app/Services/Logic/Help/HelpInfo.php b/app/Services/Logic/Help/HelpInfo.php index 912f32e9..83afad15 100644 --- a/app/Services/Logic/Help/HelpInfo.php +++ b/app/Services/Logic/Help/HelpInfo.php @@ -20,6 +20,10 @@ class HelpInfo extends LogicService { $help = $this->checkHelp($id); + $this->incrHelpViewCount($help); + + $this->eventsManager->fire('Help:afterView', $this, $help); + return $this->handleHelp($help); } @@ -38,4 +42,11 @@ class HelpInfo extends LogicService ]; } + protected function incrHelpViewCount(HelpModel $help) + { + $help->view_count += 1; + + $help->update(); + } + } diff --git a/app/Services/Logic/Order/OrderCreate.php b/app/Services/Logic/Order/OrderCreate.php index 65461ece..85ba1105 100644 --- a/app/Services/Logic/Order/OrderCreate.php +++ b/app/Services/Logic/Order/OrderCreate.php @@ -27,21 +27,6 @@ class OrderCreate extends LogicService */ protected $amount = 0.00; - /** - * @var int 促销编号 - */ - protected $promotion_id = 0; - - /** - * @var int 促销类型 - */ - protected $promotion_type = 0; - - /** - * @var array 促销信息 - */ - protected $promotion_info = []; - use ClientTrait; public function handle() @@ -129,9 +114,6 @@ class OrderCreate extends LogicService $order->client_ip = $this->getClientIp(); $order->subject = "课程 - {$course->title}"; $order->amount = $this->amount; - $order->promotion_id = $this->promotion_id; - $order->promotion_type = $this->promotion_type; - $order->promotion_info = $this->promotion_info; $order->create(); @@ -167,9 +149,6 @@ class OrderCreate extends LogicService $order->client_ip = $this->getClientIp(); $order->subject = "套餐 - {$package->title}"; $order->amount = $this->amount; - $order->promotion_id = $this->promotion_id; - $order->promotion_type = $this->promotion_type; - $order->promotion_info = $this->promotion_info; $order->create(); @@ -201,9 +180,6 @@ class OrderCreate extends LogicService $order->client_ip = $this->getClientIp(); $order->subject = "会员 - 会员服务({$vip->title})"; $order->amount = $this->amount; - $order->promotion_id = $this->promotion_id; - $order->promotion_type = $this->promotion_type; - $order->promotion_info = $this->promotion_info; $order->create(); @@ -231,9 +207,6 @@ class OrderCreate extends LogicService $order->client_ip = $this->getClientIp(); $order->subject = "赞赏 - {$course->title}"; $order->amount = $this->amount; - $order->promotion_id = $this->promotion_id; - $order->promotion_type = $this->promotion_type; - $order->promotion_info = $this->promotion_info; $order->create(); diff --git a/app/Services/Logic/Order/OrderInfo.php b/app/Services/Logic/Order/OrderInfo.php index 60d59789..47a7bef5 100644 --- a/app/Services/Logic/Order/OrderInfo.php +++ b/app/Services/Logic/Order/OrderInfo.php @@ -12,14 +12,12 @@ use App\Models\Order as OrderModel; use App\Models\User as UserModel; use App\Repos\Order as OrderRepo; use App\Services\Logic\Service as LogicService; -use App\Services\Logic\UserTrait; +use App\Services\Logic\User\ShallowUserInfo; use App\Validators\Order as OrderValidator; class OrderInfo extends LogicService { - use UserTrait; - public function handle($sn) { $validator = new OrderValidator(); @@ -44,15 +42,12 @@ class OrderInfo extends LogicService 'item_id' => $order->item_id, 'item_type' => $order->item_type, 'item_info' => $order->item_info, - 'promotion_id' => $order->promotion_id, - 'promotion_type' => $order->promotion_type, - 'promotion_info' => $order->promotion_info, 'create_time' => $order->create_time, 'update_time' => $order->update_time, ]; $result['status_history'] = $this->handleStatusHistory($order->id); - $result['owner'] = $this->handleShallowUserInfo($order->owner_id); + $result['owner'] = $this->handleOwnerInfo($order->owner_id); $result['me'] = $this->handleMeInfo($order, $user); return $result; @@ -78,6 +73,13 @@ class OrderInfo extends LogicService return $result; } + protected function handleOwnerInfo($userId) + { + $service = new ShallowUserInfo(); + + return $service->handle($userId); + } + protected function handleMeInfo(OrderModel $order, UserModel $user) { $result = [ diff --git a/app/Services/Logic/Question/QuestionDataTrait.php b/app/Services/Logic/Question/QuestionDataTrait.php index 17187e0f..66a13906 100644 --- a/app/Services/Logic/Question/QuestionDataTrait.php +++ b/app/Services/Logic/Question/QuestionDataTrait.php @@ -32,6 +32,11 @@ trait QuestionDataTrait $data['title'] = $validator->checkTitle($post['title']); $data['content'] = $validator->checkContent($post['content']); + if (isset($post['category_id'])) { + $category = $validator->checkCategory($post['category_id']); + $data['category_id'] = $category->id; + } + if (isset($post['closed'])) { $data['closed'] = $validator->checkCloseStatus($post['closed']); } diff --git a/app/Services/Logic/Question/QuestionInfo.php b/app/Services/Logic/Question/QuestionInfo.php index 7f2907a8..939f0910 100644 --- a/app/Services/Logic/Question/QuestionInfo.php +++ b/app/Services/Logic/Question/QuestionInfo.php @@ -16,13 +16,12 @@ use App\Repos\QuestionFavorite as QuestionFavoriteRepo; use App\Repos\QuestionLike as QuestionLikeRepo; use App\Services\Logic\QuestionTrait; use App\Services\Logic\Service as LogicService; -use App\Services\Logic\UserTrait; +use App\Services\Logic\User\ShallowUserInfo; class QuestionInfo extends LogicService { use QuestionTrait; - use UserTrait; public function handle($id) { @@ -41,9 +40,9 @@ class QuestionInfo extends LogicService protected function handleQuestion(QuestionModel $question, UserModel $user) { - $lastReplier = $this->handleShallowUserInfo($question->last_replier_id); + $lastReplier = $this->handleLastReplierInfo($question->last_replier_id); $category = $this->handleCategoryInfo($question->category_id); - $owner = $this->handleShallowUserInfo($question->owner_id); + $owner = $this->handleOwnerInfo($question->owner_id); $me = $this->handleMeInfo($question, $user); return [ @@ -91,10 +90,27 @@ class QuestionInfo extends LogicService ]; } + protected function handleLastReplierInfo($userId) + { + if ($userId == 0) return new \stdClass(); + + $service = new ShallowUserInfo(); + + return $service->handle($userId); + } + + protected function handleOwnerInfo($userId) + { + $service = new ShallowUserInfo(); + + return $service->handle($userId); + } + protected function handleMeInfo(QuestionModel $question, UserModel $user) { $me = [ 'allow_answer' => 0, + 'logged' => 0, 'liked' => 0, 'favorited' => 0, 'answered' => 0, @@ -105,12 +121,14 @@ class QuestionInfo extends LogicService $closed = $question->closed == 1; $solved = $question->solved == 1; - if ($user->id == $question->owner_id) { - $me['owned'] = 1; - } - if ($user->id > 0) { + $me['logged'] = 1; + + if ($user->id == $question->owner_id) { + $me['owned'] = 1; + } + $likeRepo = new QuestionLikeRepo(); $like = $likeRepo->findQuestionLike($question->id, $user->id); diff --git a/app/Services/Logic/Question/QuestionList.php b/app/Services/Logic/Question/QuestionList.php index 19ad8af4..f9eadfd9 100644 --- a/app/Services/Logic/Question/QuestionList.php +++ b/app/Services/Logic/Question/QuestionList.php @@ -11,6 +11,7 @@ use App\Builders\QuestionList as QuestionListBuilder; use App\Library\Paginator\Query as PagerQuery; use App\Models\Question as QuestionModel; use App\Repos\Question as QuestionRepo; +use App\Services\Category as CategoryService; use App\Services\Logic\Service as LogicService; use App\Validators\QuestionQuery as QuestionQueryValidator; @@ -25,6 +26,27 @@ class QuestionList extends LogicService $params = $this->checkQueryParams($params); + /** + * tc => top_category + * sc => sub_category + */ + if (!empty($params['sc'])) { + + $params['category_id'] = $params['sc']; + + } elseif (!empty($params['tc'])) { + + $categoryService = new CategoryService(); + + $childCategoryIds = $categoryService->getChildCategoryIds($params['tc']); + + $parentCategoryIds = [$params['tc']]; + + $allCategoryIds = array_merge($parentCategoryIds, $childCategoryIds); + + $params['category_id'] = $allCategoryIds; + } + $params['published'] = QuestionModel::PUBLISH_APPROVED; $params['deleted'] = 0; @@ -102,7 +124,18 @@ class QuestionList extends LogicService $query = []; if (isset($params['tag_id'])) { - $query['tag_id'] = $validator->checkTag($params['tag_id']); + $tag = $validator->checkTag($params['tag_id']); + $query['tag_id'] = $tag->id; + } + + if (isset($params['tc'])) { + $category = $validator->checkCategory($params['tc']); + $query['tc'] = $category->id; + } + + if (isset($params['sc'])) { + $category = $validator->checkCategory($params['sc']); + $query['sc'] = $category->id; } if (isset($params['sort'])) { diff --git a/app/Services/Logic/Refund/RefundInfo.php b/app/Services/Logic/Refund/RefundInfo.php index f5f3c7cb..5a85ff11 100644 --- a/app/Services/Logic/Refund/RefundInfo.php +++ b/app/Services/Logic/Refund/RefundInfo.php @@ -13,6 +13,7 @@ use App\Repos\Order as OrderRepo; use App\Repos\Refund as RefundRepo; use App\Services\Logic\RefundTrait; use App\Services\Logic\Service as LogicService; +use App\Services\Logic\User\ShallowUserInfo; use App\Services\Logic\UserTrait; class RefundInfo extends LogicService @@ -34,7 +35,7 @@ class RefundInfo extends LogicService { $statusHistory = $this->handleStatusHistory($refund->id); $order = $this->handleOrderInfo($refund->order_id); - $owner = $this->handleShallowUserInfo($refund->owner_id); + $owner = $this->handleOwnerInfo($refund->owner_id); $me = $this->handleMeInfo($refund, $user); return [ @@ -54,20 +55,6 @@ class RefundInfo extends LogicService ]; } - protected function handleOrderInfo($orderId) - { - $orderRepo = new OrderRepo(); - - $order = $orderRepo->findById($orderId); - - return [ - 'id' => $order->id, - 'sn' => $order->sn, - 'subject' => $order->subject, - 'amount' => $order->amount, - ]; - } - protected function handleStatusHistory($refundId) { $refundRepo = new RefundRepo(); @@ -90,6 +77,27 @@ class RefundInfo extends LogicService return $result; } + protected function handleOrderInfo($orderId) + { + $orderRepo = new OrderRepo(); + + $order = $orderRepo->findById($orderId); + + return [ + 'id' => $order->id, + 'sn' => $order->sn, + 'subject' => $order->subject, + 'amount' => $order->amount, + ]; + } + + protected function handleOwnerInfo($userId) + { + $service = new ShallowUserInfo(); + + return $service->handle($userId); + } + protected function handleMeInfo(RefundModel $refund, UserModel $user) { $result = [ diff --git a/app/Services/Logic/Review/ReviewCreate.php b/app/Services/Logic/Review/ReviewCreate.php index 52aa2507..497f25b6 100644 --- a/app/Services/Logic/Review/ReviewCreate.php +++ b/app/Services/Logic/Review/ReviewCreate.php @@ -43,7 +43,7 @@ class ReviewCreate extends LogicService $data['course_id'] = $course->id; $data['owner_id'] = $user->id; - $data['published'] = 1; + $data['published'] = ReviewModel::PUBLISH_PENDING; $review = new ReviewModel(); diff --git a/app/Services/Logic/Review/ReviewInfo.php b/app/Services/Logic/Review/ReviewInfo.php index 6e3cd18f..afd811af 100644 --- a/app/Services/Logic/Review/ReviewInfo.php +++ b/app/Services/Logic/Review/ReviewInfo.php @@ -13,6 +13,7 @@ use App\Repos\Course as CourseRepo; use App\Repos\ReviewLike as ReviewLikeRepo; use App\Services\Logic\ReviewTrait; use App\Services\Logic\Service as LogicService; +use App\Services\Logic\User\ShallowUserInfo; use App\Services\Logic\UserTrait; class ReviewInfo extends LogicService @@ -33,7 +34,7 @@ class ReviewInfo extends LogicService protected function handleReview(ReviewModel $review, UserModel $user) { $course = $this->handleCourseInfo($review->course_id); - $owner = $this->handleShallowUserInfo($review->owner_id); + $owner = $this->handleOwnerInfo($review->owner_id); $me = $this->handleMeInfo($review, $user); return [ @@ -71,19 +72,29 @@ class ReviewInfo extends LogicService ]; } + protected function handleOwnerInfo($userId) + { + $service = new ShallowUserInfo(); + + return $service->handle($userId); + } + protected function handleMeInfo(ReviewModel $review, UserModel $user) { $me = [ + 'logged' => 0, 'liked' => 0, 'owned' => 0, ]; - if ($user->id == $review->owner_id) { - $me['owned'] = 1; - } - if ($user->id > 0) { + if ($user->id == $review->owner_id) { + $me['owned'] = 1; + } + + $me['logged'] = 1; + $likeRepo = new ReviewLikeRepo(); $like = $likeRepo->findReviewLike($review->id, $user->id); diff --git a/app/Services/Logic/Trade/TradeInfo.php b/app/Services/Logic/Trade/TradeInfo.php index d6dc3986..73260166 100644 --- a/app/Services/Logic/Trade/TradeInfo.php +++ b/app/Services/Logic/Trade/TradeInfo.php @@ -13,6 +13,7 @@ use App\Repos\Order as OrderRepo; use App\Repos\Trade as TradeRepo; use App\Services\Logic\Service as LogicService; use App\Services\Logic\TradeTrait; +use App\Services\Logic\User\ShallowUserInfo; use App\Services\Logic\UserTrait; class TradeInfo extends LogicService @@ -33,7 +34,8 @@ class TradeInfo extends LogicService protected function handleTrade(TradeModel $trade, UserModel $user) { $statusHistory = $this->handleStatusHistory($trade->id); - $owner = $this->handleShallowUserInfo($trade->owner_id); + $order = $this->handleOrderInfo($trade->order_id); + $owner = $this->handleOwnerInfo($trade->owner_id); $me = $this->handleMeInfo($trade, $user); return [ @@ -46,6 +48,7 @@ class TradeInfo extends LogicService 'create_time' => $trade->create_time, 'update_time' => $trade->update_time, 'status_history' => $statusHistory, + 'order' => $order, 'owner' => $owner, 'me' => $me, ]; @@ -65,6 +68,13 @@ class TradeInfo extends LogicService ]; } + protected function handleOwnerInfo($userId) + { + $service = new ShallowUserInfo(); + + return $service->handle($userId); + } + protected function handleStatusHistory($tradeId) { $tradeRepo = new TradeRepo(); diff --git a/app/Services/Logic/Url/FullH5Url.php b/app/Services/Logic/Url/FullH5Url.php index eabc5e3a..be8cb36a 100644 --- a/app/Services/Logic/Url/FullH5Url.php +++ b/app/Services/Logic/Url/FullH5Url.php @@ -91,11 +91,6 @@ class FullH5Url extends AppService return $this->getFullUrl('/teacher/list'); } - public function getFlashSaleListUrl() - { - return $this->getFullUrl('/flash-sale/list'); - } - public function getPointGiftListUrl() { return $this->getFullUrl('/point/gift/list'); diff --git a/app/Services/Logic/User/Console/OrderList.php b/app/Services/Logic/User/Console/OrderList.php index 7ab24fa1..250f782b 100644 --- a/app/Services/Logic/User/Console/OrderList.php +++ b/app/Services/Logic/User/Console/OrderList.php @@ -73,9 +73,6 @@ class OrderList extends LogicService 'item_id' => $order['item_id'], 'item_type' => $order['item_type'], 'item_info' => $order['item_info'], - 'promotion_id' => $order['promotion_id'], - 'promotion_type' => $order['promotion_type'], - 'promotion_info' => $order['promotion_info'], 'create_time' => $order['create_time'], 'update_time' => $order['update_time'], 'me' => $me, diff --git a/app/Services/Logic/User/CourseList.php b/app/Services/Logic/User/CourseList.php index 88b78fbd..4b6756cd 100644 --- a/app/Services/Logic/User/CourseList.php +++ b/app/Services/Logic/User/CourseList.php @@ -28,7 +28,6 @@ class CourseList extends LogicService $params = $pagerQuery->getParams(); $params['user_id'] = $user->id; - $params['role_type'] = CourseUserModel::ROLE_STUDENT; $params['deleted'] = 0; $sort = $pagerQuery->getSort(); @@ -61,7 +60,6 @@ class CourseList extends LogicService $course = $courses[$relation['course_id']] ?? new \stdClass(); $items[] = [ - 'plan_id' => $relation['plan_id'], 'progress' => $relation['progress'], 'duration' => $relation['duration'], 'reviewed' => $relation['reviewed'], diff --git a/app/Services/Logic/User/ShallowUserInfo.php b/app/Services/Logic/User/ShallowUserInfo.php new file mode 100644 index 00000000..cf1285d5 --- /dev/null +++ b/app/Services/Logic/User/ShallowUserInfo.php @@ -0,0 +1,38 @@ +checkUser($id); + + return $this->handleUser($user); + } + + protected function handleUser(UserModel $user) + { + return [ + 'id' => $user->id, + 'name' => $user->name, + 'avatar' => $user->avatar, + 'title' => $user->title, + 'about' => $user->about, + 'vip' => $user->vip, + ]; + } + +} diff --git a/app/Services/Logic/UserTrait.php b/app/Services/Logic/UserTrait.php index 2f379c30..6631cd2b 100644 --- a/app/Services/Logic/UserTrait.php +++ b/app/Services/Logic/UserTrait.php @@ -7,7 +7,6 @@ namespace App\Services\Logic; -use App\Repos\User as UserRepo; use App\Validators\User as UserValidator; trait UserTrait @@ -27,21 +26,4 @@ trait UserTrait return $validator->checkUserCache($id); } - public function handleShallowUserInfo($id) - { - if (empty($id)) return new \stdClass(); - - $userRepo = new UserRepo(); - - $user = $userRepo->findShallowUserById($id); - - if (!$user) return new \stdClass(); - - $result = $user->toArray(); - - $result['avatar'] = kg_cos_user_avatar_url($user->avatar); - - return $result; - } - } diff --git a/app/Services/Logic/Vip/OptionList.php b/app/Services/Logic/Vip/OptionList.php index be098576..71c53978 100644 --- a/app/Services/Logic/Vip/OptionList.php +++ b/app/Services/Logic/Vip/OptionList.php @@ -17,11 +17,14 @@ class OptionList extends LogicService { $vipRepo = new VipRepo(); - $vips = $vipRepo->findAll(['deleted' => 0]); + $where = [ + 'published' => 1, + 'deleted' => 0, + ]; - if ($vips->count() == 0) { - return []; - } + $vips = $vipRepo->findAll($where, 'price'); + + if ($vips->count() == 0) return []; $result = []; diff --git a/app/Services/Refund.php b/app/Services/Refund.php index 90d66b1d..3dc23a27 100644 --- a/app/Services/Refund.php +++ b/app/Services/Refund.php @@ -198,7 +198,7 @@ class Refund extends Service if (!$courseUser) return 1.00; - $userLearnings = $courseRepo->findUserLearnings($courseId, $userId, $courseUser->plan_id); + $userLearnings = $courseRepo->findUserLearnings($courseId, $userId); if ($userLearnings->count() == 0) return 1.00; diff --git a/app/Services/Storage.php b/app/Services/Storage.php index 3ff42df8..f670fb57 100644 --- a/app/Services/Storage.php +++ b/app/Services/Storage.php @@ -47,7 +47,7 @@ class Storage extends Service /** * 获取临时凭证 * - * @return GetFederationTokenResponse + * @return GetFederationTokenResponse|bool */ public function getFederationToken() { @@ -99,7 +99,7 @@ class Storage extends Service $request->fromJsonString($params); - return $client->GetFederationToken($request); + $result = $client->GetFederationToken($request); } catch (TencentCloudSDKException $e) { @@ -108,8 +108,10 @@ class Storage extends Service 'message' => $e->getMessage(), ])); - throw new \Exception('Get Tmp Token Exception'); + $result = false; } + + return $result; } /** diff --git a/app/Validators/Answer.php b/app/Validators/Answer.php index d8c2eef1..73cfe297 100644 --- a/app/Validators/Answer.php +++ b/app/Validators/Answer.php @@ -85,13 +85,6 @@ class Answer extends Validator return $status; } - public function checkRejectReason($reason) - { - if (!array_key_exists($reason, ReasonModel::answerRejectOptions())) { - throw new BadRequestException('answer.invalid_reject_reason'); - } - } - public function checkIfAllowAnswer(QuestionModel $question, UserModel $user) { $allowed = true; diff --git a/app/Validators/Article.php b/app/Validators/Article.php index 7aeaccdc..4d7598d4 100644 --- a/app/Validators/Article.php +++ b/app/Validators/Article.php @@ -12,7 +12,6 @@ use App\Caches\MaxArticleId as MaxArticleIdCache; use App\Exceptions\BadRequest as BadRequestException; use App\Library\Validators\Common as CommonValidator; use App\Models\Article as ArticleModel; -use App\Models\Reason as ReasonModel; use App\Repos\Article as ArticleRepo; use App\Services\EditorStorage as EditorStorageService; @@ -91,6 +90,19 @@ class Article extends Validator return $value; } + public function checkSummary($summary) + { + $value = $this->filter->sanitize($summary, ['trim', 'string']); + + $length = kg_strlen($value); + + if ($length > 255) { + throw new BadRequestException('article.summary_too_long'); + } + + return $value; + } + public function checkContent($content) { $value = $this->filter->sanitize($content, ['trim']); @@ -163,15 +175,6 @@ class Article extends Validator return $status; } - public function checkPrivateStatus($status) - { - if (!in_array($status, [0, 1])) { - throw new BadRequestException('article.invalid_private_status'); - } - - return $status; - } - public function checkCloseStatus($status) { if (!in_array($status, [0, 1])) { @@ -181,13 +184,6 @@ class Article extends Validator return $status; } - public function checkRejectReason($reason) - { - if (!array_key_exists($reason, ReasonModel::questionRejectOptions())) { - throw new BadRequestException('article.invalid_reject_reason'); - } - } - public function checkIfAllowEdit(ArticleModel $article) { $approved = $article->published == ArticleModel::PUBLISH_APPROVED; diff --git a/app/Validators/ArticleQuery.php b/app/Validators/ArticleQuery.php index 578cc48c..7f6d47a8 100644 --- a/app/Validators/ArticleQuery.php +++ b/app/Validators/ArticleQuery.php @@ -7,9 +7,9 @@ namespace App\Validators; -use App\Caches\Tag as TagCache; use App\Exceptions\BadRequest as BadRequestException; use App\Models\Article as ArticleModel; +use App\Models\Category as CategoryModel; class ArticleQuery extends Validator { @@ -24,20 +24,24 @@ class ArticleQuery extends Validator throw new BadRequestException('article_query.invalid_category'); } - return $category->id; + if ($category->type != CategoryModel::TYPE_ARTICLE) { + throw new BadRequestException('article_query.invalid_category'); + } + + return $category; } public function checkTag($id) { - $tagCache = new TagCache(); + $validator = new Tag(); - $tag = $tagCache->get($id); + $tag = $validator->checkTagCache($id); if (!$tag) { throw new BadRequestException('article_query.invalid_tag'); } - return $tag->id; + return $tag; } public function checkSort($sort) diff --git a/app/Validators/Comment.php b/app/Validators/Comment.php index c06a92be..0026cbb9 100644 --- a/app/Validators/Comment.php +++ b/app/Validators/Comment.php @@ -102,13 +102,6 @@ class Comment extends Validator return $value; } - public function checkRejectReason($reason) - { - if (!array_key_exists($reason, ReasonModel::commentRejectOptions())) { - throw new BadRequestException('comment.invalid_reject_reason'); - } - } - public function checkPublishStatus($status) { if (!array_key_exists($status, CommentModel::publishTypes())) { diff --git a/app/Validators/Course.php b/app/Validators/Course.php index b791adf2..43e38884 100644 --- a/app/Validators/Course.php +++ b/app/Validators/Course.php @@ -66,6 +66,20 @@ class Course extends Validator } } + public function checkCategory($id) + { + $validator = new Category(); + + return $validator->checkCategory($id); + } + + public function checkTeacher($id) + { + $validator = new User(); + + return $validator->checkUser($id); + } + public function checkModel($model) { $list = CourseModel::modelTypes(); @@ -182,17 +196,6 @@ class Course extends Validator return $value; } - public function checkOriginPrice($price) - { - $value = $this->filter->sanitize($price, ['trim', 'float']); - - if ($value < 0 || $value > 999999) { - throw new BadRequestException('course.invalid_origin_price'); - } - - return $value; - } - public function checkMarketPrice($price) { $value = $this->filter->sanitize($price, ['trim', 'float']); @@ -255,13 +258,4 @@ class Course extends Validator return $status; } - public function checkPublishAbility(CourseModel $course) - { - if ($course->teacher_id == 0) { - throw new BadRequestException('course.teacher_not_assigned'); - } - - return true; - } - } diff --git a/app/Validators/CourseQuery.php b/app/Validators/CourseQuery.php index f3b897e2..e50c3b77 100644 --- a/app/Validators/CourseQuery.php +++ b/app/Validators/CourseQuery.php @@ -8,36 +8,42 @@ namespace App\Validators; use App\Caches\Category as CategoryCache; +use App\Caches\Tag as TagCache; use App\Exceptions\BadRequest as BadRequestException; +use App\Models\Category as CategoryModel; use App\Models\Course as CourseModel; class CourseQuery extends Validator { - public function checkTopCategory($id) + public function checkCategory($id) { $validator = new Category(); $category = $validator->checkCategoryCache($id); if (!$category) { - throw new BadRequestException('course_query.invalid_top_category'); + throw new BadRequestException('course_query.invalid_category'); } - return $category->id; + if ($category->type != CategoryModel::TYPE_COURSE) { + throw new BadRequestException('course_query.invalid_category'); + } + + return $category; } - public function checkSubCategory($id) + public function checkTag($id) { - $categoryCache = new CategoryCache(); + $validator = new Tag(); - $category = $categoryCache->get($id); + $tag = $validator->checkTagCache($id); - if (!$category) { - throw new BadRequestException('course_query.invalid_sub_category'); + if (!$tag) { + throw new BadRequestException('course_query.invalid_tag'); } - return $category->id; + return $tag; } public function checkLevel($level) diff --git a/app/Validators/CourseUser.php b/app/Validators/CourseUser.php index baeeb819..1642733e 100644 --- a/app/Validators/CourseUser.php +++ b/app/Validators/CourseUser.php @@ -74,9 +74,9 @@ class CourseUser extends Validator { $repo = new CourseUserRepo(); - $courseUser = $repo->findCourseStudent($courseId, $userId); + $courseUser = $repo->findCourseUser($courseId, $userId); - if ($courseUser && $courseUser->source_type == CourseUserModel::SOURCE_IMPORT) { + if ($courseUser && $courseUser->source_type == CourseUserModel::SOURCE_MANUAL) { throw new BadRequestException('course_user.has_imported'); } } diff --git a/app/Validators/Danmu.php b/app/Validators/Danmu.php deleted file mode 100644 index 10bdb875..00000000 --- a/app/Validators/Danmu.php +++ /dev/null @@ -1,102 +0,0 @@ -findById($id); - - if (!$danmu) { - throw new BadRequestException('danmu.not_found'); - } - - return $danmu; - } - - public function checkChapter($id) - { - $validator = new Chapter(); - - return $validator->checkChapter($id); - } - - public function checkText($text) - { - $value = $this->filter->sanitize($text, ['trim', 'string']); - - $length = kg_strlen($value); - - if ($length < 1) { - throw new BadRequestException('danmu.text_too_short'); - } - - if ($length > 100) { - throw new BadRequestException('danmu.text_too_long'); - } - - return $value; - } - - public function checkColor($color) - { - $list = DanmuModel::colorTypes(); - - if (!isset($list[$color])) { - throw new BadRequestException('danmu.invalid_color'); - } - - return $color; - } - - public function checkSize($size) - { - $list = DanmuModel::sizeTypes(); - - if (!isset($list[$size])) { - throw new BadRequestException('danmu.invalid_size'); - } - - return $size; - } - - public function checkPosition($pos) - { - $list = DanmuModel::posTypes(); - - if (!isset($list[$pos])) { - throw new BadRequestException('danmu.invalid_position'); - } - - return $pos; - } - - public function checkTime($time) - { - $value = (int)$time; - - if ($value < 0) { - throw new BadRequestException('danmu.invalid_time'); - } - - if ($value > 3 * 3600) { - throw new BadRequestException('danmu.invalid_time'); - } - - return $value; - } - -} diff --git a/app/Validators/FlashSale.php b/app/Validators/FlashSale.php deleted file mode 100644 index 391cf719..00000000 --- a/app/Validators/FlashSale.php +++ /dev/null @@ -1,203 +0,0 @@ -checkId($id); - - $saleCache = new FlashSaleCache(); - - $sale = $saleCache->get($id); - - if (!$sale) { - throw new BadRequestException('flash_sale.not_found'); - } - - return $sale; - } - - public function checkFlashSale($id) - { - $saleRepo = new FlashSaleRepo(); - - $sale = $saleRepo->findById($id); - - if (!$sale) { - throw new BadRequestException('flash_sale.not_found'); - } - - return $sale; - } - - public function checkId($id) - { - $id = intval($id); - - $maxSaleIdCache = new MaxFlashSaleIdCache(); - - $maxId = $maxSaleIdCache->get(); - - if ($id < 1 || $id > $maxId) { - throw new BadRequestException('flash_sale.not_found'); - } - } - - public function checkItemType($type) - { - $list = FlashSaleModel::itemTypes(); - - if (!array_key_exists($type, $list)) { - throw new BadRequestException('flash_sale.invalid_item_type'); - } - - return (int)$type; - } - - public function checkStartTime($startTime) - { - if (!CommonValidator::date($startTime, 'Y-m-d H:i:s')) { - throw new BadRequestException('flash_sale.invalid_start_time'); - } - - return strtotime($startTime); - } - - public function checkEndTime($endTime) - { - if (!CommonValidator::date($endTime, 'Y-m-d H:i:s')) { - throw new BadRequestException('flash_sale.invalid_end_time'); - } - - return strtotime($endTime); - } - - public function checkTimeRange($startTime, $endTime) - { - if ($startTime >= $endTime) { - throw new BadRequestException('flash_sale.start_gt_end'); - } - } - - public function checkSchedules($schedules) - { - if (empty($schedules)) { - throw new BadRequestException('flash_sale.invalid_schedules'); - } - - $result = explode(',', $schedules); - - sort($result); - - return $result; - } - - public function checkStock($stock) - { - $value = $this->filter->sanitize($stock, ['trim', 'int']); - - if ($value < 0 || $value > 999999) { - throw new BadRequestException('flash_sale.invalid_stock'); - } - - return (int)$value; - } - - public function checkPrice($marketPrice, $salePrice) - { - if ($salePrice < 0.01) { - throw new BadRequestException('flash_sale.invalid_price'); - } - - if ($salePrice > $marketPrice) { - throw new BadRequestException('flash_sale.unreasonable_price'); - } - - return (float)$salePrice; - } - - public function checkPublishStatus($status) - { - if (!in_array($status, [0, 1])) { - throw new BadRequestException('flash_sale.invalid_publish_status'); - } - - return (int)$status; - } - - public function checkCourse($id) - { - $validator = new Course(); - - return $validator->checkCourse($id); - } - - public function checkPackage($id) - { - $validator = new Package(); - - return $validator->checkPackage($id); - } - - public function checkVip($id) - { - $validator = new Vip(); - - return $validator->checkVip($id); - } - - public function checkIfExpired($endTime) - { - if ($endTime < time()) { - throw new BadRequestException('flash_sale.expired'); - } - } - - public function checkIfOutSchedules($schedules) - { - $curHour = date('H'); - - $flag = true; - - foreach ($schedules as $schedule) { - if ($curHour >= $schedule && $curHour < $schedule + 2) { - $flag = false; - } - } - - if ($flag) { - throw new BadRequestException('flash_sale.out_schedules'); - } - } - - public function checkIfNotPaid($userId, $saleId) - { - $cache = new UserOrderCache(); - - if ($cache->get($userId, $saleId)) { - throw new BadRequestException('flash_sale.not_paid'); - } - } - -} diff --git a/app/Validators/Learning.php b/app/Validators/Learning.php index 122f33d4..ac841ad0 100644 --- a/app/Validators/Learning.php +++ b/app/Validators/Learning.php @@ -13,15 +13,6 @@ use App\Library\Validators\Common as CommonValidator; class Learning extends Validator { - public function checkPlanId($planId) - { - if (!CommonValidator::date($planId, 'Ymd')) { - throw new BadRequestException('learning.invalid_plan_id'); - } - - return $planId; - } - public function checkRequestId($requestId) { if (!$requestId) { @@ -31,6 +22,15 @@ class Learning extends Validator return $requestId; } + public function checkPlanId($planId) + { + if (!CommonValidator::date($planId, 'Ymd')) { + throw new BadRequestException('learning.invalid_plan_id'); + } + + return $planId; + } + public function checkIntervalTime($intervalTime) { $value = $this->filter->sanitize($intervalTime, ['trim', 'int']); diff --git a/app/Validators/Question.php b/app/Validators/Question.php index b4ff8be4..e2ccfe06 100644 --- a/app/Validators/Question.php +++ b/app/Validators/Question.php @@ -147,13 +147,6 @@ class Question extends Validator return $status; } - public function checkRejectReason($reason) - { - if (!array_key_exists($reason, ReasonModel::questionRejectOptions())) { - throw new BadRequestException('question.invalid_reject_reason'); - } - } - public function checkIfAllowEdit(QuestionModel $question) { $approved = $question->published == QuestionModel::PUBLISH_APPROVED; diff --git a/app/Validators/QuestionQuery.php b/app/Validators/QuestionQuery.php index 83a1dbd0..68bdf3b5 100644 --- a/app/Validators/QuestionQuery.php +++ b/app/Validators/QuestionQuery.php @@ -24,7 +24,7 @@ class QuestionQuery extends Validator throw new BadRequestException('question_query.invalid_category'); } - return $category->id; + return $category; } public function checkTag($id) @@ -37,7 +37,7 @@ class QuestionQuery extends Validator throw new BadRequestException('question_query.invalid_tag'); } - return $tag->id; + return $tag; } public function checkSort($sort) diff --git a/app/Validators/UserLimit.php b/app/Validators/UserLimit.php index 95fbcc9e..d6cd65dd 100644 --- a/app/Validators/UserLimit.php +++ b/app/Validators/UserLimit.php @@ -85,17 +85,6 @@ class UserLimit extends Validator } } - public function checkDailyDanmuLimit(UserModel $user) - { - $count = $this->counter->hGet($user->id, 'danmu_count'); - - $limit = $user->vip ? 100 : 50; - - if ($count > $limit) { - throw new BadRequestException('user_limit.reach_daily_danmu_limit'); - } - } - public function checkDailyConsultLimit(UserModel $user) { $count = $this->counter->hGet($user->id, 'consult_count'); diff --git a/app/Validators/Vip.php b/app/Validators/Vip.php index 122c9f17..76a6e50e 100644 --- a/app/Validators/Vip.php +++ b/app/Validators/Vip.php @@ -8,6 +8,7 @@ namespace App\Validators; use App\Exceptions\BadRequest as BadRequestException; +use App\Library\Validators\Common as CommonValidator; use App\Repos\Vip as VipRepo; class Vip extends Validator @@ -43,6 +44,17 @@ class Vip extends Validator return $value; } + public function checkCover($cover) + { + $value = $this->filter->sanitize($cover, ['trim', 'string']); + + if (!CommonValidator::url($value)) { + throw new BadRequestException('vip.invalid_cover'); + } + + return kg_cos_img_style_trim($value); + } + public function checkExpiry($expiry) { $value = $this->filter->sanitize($expiry, ['trim', 'int']); @@ -58,11 +70,20 @@ class Vip extends Validator { $value = $this->filter->sanitize($price, ['trim', 'float']); - if ($value < 0.01 || $value > 10000) { + if ($value < 1 || $value > 999999) { throw new BadRequestException('vip.invalid_price'); } return $value; } + public function checkPublishStatus($status) + { + if (!in_array($status, [0, 1])) { + throw new BadRequestException('vip.invalid_publish_status'); + } + + return $status; + } + } diff --git a/config/errors.php b/config/errors.php index ac374977..d1c570cc 100644 --- a/config/errors.php +++ b/config/errors.php @@ -126,7 +126,6 @@ $error['article.invalid_source_type'] = '无效的来源类型'; $error['article.invalid_source_url'] = '无效的来源网址'; $error['article.invalid_feature_status'] = '无效的推荐状态'; $error['article.invalid_publish_status'] = '无效的发布状态'; -$error['article.invalid_private_status'] = '无效的私有状态'; $error['article.invalid_close_status'] = '无效的关闭状态'; $error['article.invalid_reject_reason'] = '无效的拒绝理由'; $error['article.edit_not_allowed'] = '当前不允许编辑文章'; @@ -447,8 +446,8 @@ $error['course_query.invalid_sort'] = '无效的排序类别'; /** * 课时学习 */ -$error['learning.invalid_plan_id'] = '无效的计划编号'; $error['learning.invalid_request_id'] = '无效的请求编号'; +$error['learning.invalid_plan_id'] = '无效的计划编号'; $error['learning.invalid_interval_time'] = '无效的间隔时间'; $error['learning.invalid_position'] = '无效的播放位置'; @@ -485,24 +484,6 @@ $error['point_gift_redeem.reach_redeem_limit'] = '超出物品兑换限额'; $error['point_gift_redeem.no_enough_point'] = '您的积分余额不足以抵扣此次兑换'; $error['point_gift_redeem.no_enough_stock'] = '兑换物品库存不足'; -/** - * 限时秒杀相关 - */ -$error['flash_sale.not_found'] = '秒杀活动不存在'; -$error['flash_sale.invalid_item_type'] = '无效的商品类型'; -$error['flash_sale.invalid_start_time'] = '无效的开始时间'; -$error['flash_sale.invalid_end_time'] = '无效的结束时间'; -$error['flash_sale.start_gt_end'] = '开始时间大于结束时间'; -$error['flash_sale.invalid_schedules'] = '无效的秒杀场次'; -$error['flash_sale.invalid_price'] = '无效的价格(范围:0.01-10000)'; -$error['flash_sale.unreasonable_price'] = '不合理的定价(秒杀价大于销售价)'; -$error['flash_sale.invalid_stock'] = '无效的库存值(范围:1-999999)'; -$error['flash_sale.invalid_publish_status'] = '无效的发布状态'; -$error['flash_sale.expired'] = '活动已过期'; -$error['flash_sale.out_schedules'] = '当前时间和秒杀场次不匹配'; -$error['flash_sale.not_paid'] = '订单尚未完成,请前往用户中心支付'; -$error['flash_sale.out_stock'] = '下手太慢,商品被秒光啦'; - /** * 举报相关 */ diff --git a/db/migrations/20231108085025.php b/db/migrations/20231108085025.php new file mode 100644 index 00000000..557e4c74 --- /dev/null +++ b/db/migrations/20231108085025.php @@ -0,0 +1,226 @@ +alterVipTable(); + $this->alterArticleTable(); + $this->alterConsultTable(); + $this->alterResourceTable(); + $this->alterCourseUserTable(); + $this->alterChapterUserTable(); + $this->dropCourseCategoryTable(); + $this->dropFlashSaleTable(); + $this->dropDanmuTable(); + $this->handleArticles(); + $this->handleNavs(); + $this->handleVips(); + } + + protected function alterVipTable() + { + $table = $this->table('kg_vip'); + + if (!$table->hasColumn('published')) { + $table->addColumn('published', 'integer', [ + 'null' => false, + 'default' => '0', + 'limit' => MysqlAdapter::INT_REGULAR, + 'signed' => false, + 'comment' => '发布标识', + 'after' => 'price', + ]); + } + + $table->save(); + } + + protected function alterArticleTable() + { + $table = $this->table('kg_article'); + + if ($table->hasColumn('private')) { + $table->removeColumn('private'); + } + + $table->save(); + } + + protected function alterConsultTable() + { + $table = $this->table('kg_consult'); + + if ($table->hasColumn('chapter_id')) { + $table->removeColumn('chapter_id'); + } + + $table->save(); + } + + protected function alterResourceTable() + { + $table = $this->table('kg_resource'); + + if ($table->hasColumn('chapter_id')) { + $table->removeColumn('chapter_id'); + } + + $table->save(); + } + + protected function alterCourseUserTable() + { + $table = $this->table('kg_course_user'); + + if ($table->hasColumn('role_type')) { + $this->deleteCourseTeachers(); + } + + if ($table->hasColumn('role_type')) { + $table->removeColumn('role_type'); + } + + if (!$table->hasColumn('active_time')) { + $table->addColumn('active_time', 'integer', [ + 'null' => false, + 'default' => '0', + 'limit' => MysqlAdapter::INT_REGULAR, + 'signed' => false, + 'comment' => '活跃时间', + 'after' => 'deleted', + ]); + } + + if ($table->hasIndexByName('course_user')) { + $table->removeIndexByName('course_user'); + } + + $table->save(); + } + + protected function alterChapterUserTable() + { + $table = $this->table('kg_chapter_user'); + + if (!$table->hasColumn('deleted')) { + $table->addColumn('deleted', 'integer', [ + 'null' => false, + 'default' => '0', + 'limit' => MysqlAdapter::INT_REGULAR, + 'signed' => false, + 'comment' => '删除标识', + 'after' => 'consumed', + ]); + } + + if (!$table->hasColumn('active_time')) { + $table->addColumn('active_time', 'integer', [ + 'null' => false, + 'default' => '0', + 'limit' => MysqlAdapter::INT_REGULAR, + 'signed' => false, + 'comment' => '活跃时间', + 'after' => 'deleted', + ]); + } + + $table->save(); + } + + protected function dropCourseCategoryTable() + { + $table = $this->table('kg_course_category'); + + if ($table->exists()) { + $table->drop()->save(); + } + } + + protected function dropFlashSaleTable() + { + $table = $this->table('kg_flash_sale'); + + if ($table->exists()) { + $table->drop()->save(); + } + } + + protected function dropDanmuTable() + { + $table = $this->table('kg_danmu'); + + if ($table->exists()) { + $table->drop()->save(); + } + } + + protected function deleteCourseTeachers() + { + $this->getQueryBuilder() + ->delete('kg_course_user') + ->where(['role_type' => 2]) + ->execute(); + } + + protected function handleArticles() + { + /** + * 处理封面为空的记录 + */ + $this->getQueryBuilder() + ->update('kg_article') + ->set('cover', '/img/default/article_cover.png') + ->where(['cover' => '']) + ->execute(); + + $articles = $this->getQueryBuilder() + ->select('*') + ->from('kg_article') + ->where(['cover LIKE' => 'http%']) + ->execute()->fetchAll(PDO::FETCH_ASSOC); + + if (count($articles) == 0) return; + + /** + * 去除封面URL中的域名 + */ + foreach ($articles as $article) { + $matched = preg_match('/\/img\/content\/(.*?)$/', $article['cover'], $matches); + if ($matched) { + $cover = sprintf('/img/content/%s', $matches[1]); + $this->getQueryBuilder() + ->update('kg_article') + ->where(['id' => $article['id']]) + ->set('cover', $cover) + ->execute(); + } + } + } + + protected function handleNavs() + { + $this->getQueryBuilder() + ->delete('kg_nav') + ->where(['url' => '/flash/sale']) + ->execute(); + } + + protected function handleVips() + { + $this->getQueryBuilder() + ->update('kg_vip') + ->set('published', 1) + ->execute(); + } + +} diff --git a/public/static/admin/css/common.css b/public/static/admin/css/common.css index 7ce26329..d1ee38bc 100644 --- a/public/static/admin/css/common.css +++ b/public/static/admin/css/common.css @@ -11,7 +11,7 @@ } .layui-layout-admin .layui-body { - bottom: 0; + padding-bottom: 0; } .layui-copyright { @@ -41,12 +41,6 @@ color: gray; } -.avatar-sm { - width: 64px; - height: 64px; - border-radius: 100%; -} - .loading { padding: 30px; text-align: center; @@ -162,11 +156,6 @@ left: 230px; } -.kg-breadcrumb { - margin-left: 3px; - margin-bottom: 15px; -} - .kg-nav { position: relative; height: 30px; @@ -180,6 +169,10 @@ left: 5px; } +.kg-nav-left .layui-breadcrumb { + margin-right: 20px; +} + .kg-nav-right { position: absolute; top: 0; @@ -244,9 +237,15 @@ img.kg-cover { } img.kg-avatar { - width: 96px; - height: 96px; - border-radius: 96px; + width: 64px; + height: 64px; + border-radius: 64px; +} + +img.kg-avatar-sm { + width: 48px; + height: 48px; + border-radius: 48px; } img.kg-icon { @@ -255,6 +254,12 @@ img.kg-icon { border-radius: 64px; } +img.kg-icon-sm { + width: 48px; + height: 48px; + border-radius: 48px; +} + .kg-form .layui-form-label { width: 120px; } diff --git a/public/static/admin/js/common.js b/public/static/admin/js/common.js index 97fc1e05..36a916f4 100644 --- a/public/static/admin/js/common.js +++ b/public/static/admin/js/common.js @@ -79,11 +79,21 @@ layui.use(['jquery', 'form', 'element', 'layer', 'kgDropdown'], function () { return false; }); - form.on('switch(published)', function (data) { + form.on('switch(go)', function (data) { + var postData = {}; + var name = $(this).attr('name'); var checked = $(this).is(':checked'); - var published = checked ? 1 : 0; + var value = checked ? 1 : 0; var url = $(this).data('url'); - var tips = published === 1 ? '确定要上线?' : '确定要下线?'; + var onTips = $(this).data('on-tips'); + var offTips = $(this).data('off-tips'); + var tips = '确定要执行操作?'; + if (value === 1 && onTips) { + tips = onTips; + } else if (value === 0 && offTips) { + tips = offTips; + } + postData[name] = value; layer.confirm(tips, { cancel: function (index) { layer.close(index); @@ -94,7 +104,7 @@ layui.use(['jquery', 'form', 'element', 'layer', 'kgDropdown'], function () { $.ajax({ type: 'POST', url: url, - data: {published: published}, + data: postData, success: function (res) { layer.msg(res.msg, {icon: 1}); }, @@ -111,6 +121,19 @@ layui.use(['jquery', 'form', 'element', 'layer', 'kgDropdown'], function () { }); }); + form.on('checkbox(all)', function (data) { + $('input:checkbox[class="item"]').each(function (index, item) { + item.checked = data.elem.checked; + }); + form.render('checkbox'); + }); + + form.on('checkbox(item)', function (data) { + var allChecked = $('input:checkbox[class="item"]:not(:checked)').length === 0; + $('input:checkbox[class="all"]').prop('checked', allChecked); + form.render('checkbox'); + }); + $('.kg-priority').on('change', function () { var priority = $(this).val(); var url = $(this).data('url'); diff --git a/public/static/home/css/common.css b/public/static/home/css/common.css index 5f5427dc..033d8da7 100644 --- a/public/static/home/css/common.css +++ b/public/static/home/css/common.css @@ -858,7 +858,7 @@ cursor: pointer; } -.course-filter { +.filter-wrap { margin-bottom: 20px; } @@ -878,11 +878,11 @@ margin-right: 15px; } -.course-sort { +.filter-sort { padding: 10px 20px; } -.course-sort a { +.filter-sort a { margin-right: 20px; } diff --git a/public/static/home/js/article.list.js b/public/static/home/js/article.list.js index 2540ebe7..d45b7a9d 100644 --- a/public/static/home/js/article.list.js +++ b/public/static/home/js/article.list.js @@ -3,18 +3,20 @@ layui.use(['jquery', 'helper'], function () { var $ = layui.jquery; var helper = layui.helper; + $('.btn-post').on('click', function () { + var url = $(this).data('url'); + helper.checkLogin(function () { + window.location.href = url; + }); + }); + var $articleList = $('#article-list'); var $sidebarTopAuthors = $('#sidebar-top-authors'); - var $sidebarMyTags = $('#sidebar-my-tags'); if ($articleList.length > 0) { helper.ajaxLoadHtml($articleList.data('url'), $articleList.attr('id')); } - if ($sidebarMyTags.length > 0) { - helper.ajaxLoadHtml($sidebarMyTags.data('url'), $sidebarMyTags.attr('id')); - } - if ($sidebarTopAuthors.length > 0) { helper.ajaxLoadHtml($sidebarTopAuthors.data('url'), $sidebarTopAuthors.attr('id')); } diff --git a/public/static/home/js/article.show.js b/public/static/home/js/article.show.js index 5e52fa33..161a5589 100644 --- a/public/static/home/js/article.show.js +++ b/public/static/home/js/article.show.js @@ -31,18 +31,6 @@ layui.use(['jquery', 'layer', 'helper'], function () { }); }); - $('.article-private').on('click', function () { - var url = $(this).data('url'); - $.post(url, function (res) { - if (res.msg) { - layer.msg(res.msg, {icon: 1}); - } - setTimeout(function () { - window.location.reload() - }, 1500); - }); - }); - $('.icon-star').on('click', function () { var $this = $(this); var $parent = $this.parent(); diff --git a/public/static/home/js/chapter.live.player.js b/public/static/home/js/chapter.live.player.js index 7c0285e8..5b62118f 100644 --- a/public/static/home/js/chapter.live.player.js +++ b/public/static/home/js/chapter.live.player.js @@ -7,7 +7,7 @@ layui.use(['jquery', 'helper'], function () { var intervalTime = 15000; var userId = window.user.id; var requestId = helper.getRequestId(); - var planId = $('input[name="chapter.plan_id"]').val(); + var planId = $('input[name="chapter.me.plan_id"]').val(); var learningUrl = $('input[name="chapter.learning_url"]').val(); var playUrls = JSON.parse($('input[name="chapter.play_urls"]').val()); diff --git a/public/static/home/js/chapter.read.js b/public/static/home/js/chapter.read.js index dee01578..fd315ea2 100644 --- a/public/static/home/js/chapter.read.js +++ b/public/static/home/js/chapter.read.js @@ -6,20 +6,19 @@ layui.use(['jquery', 'helper'], function () { var interval = null; var intervalTime = 15000; var userId = window.user.id; - var planId = $('input[name="chapter.plan_id"]').val(); - var learningUrl = $('input[name="chapter.learning_url"]').val(); var requestId = helper.getRequestId(); + var planId = $('input[name="chapter.me.plan_id"]').val(); + var learningUrl = $('input[name="chapter.learning_url"]').val(); - if (userId !== '0' && planId !== '0') { - start(); - document.addEventListener('visibilitychange', function () { - if (document.visibilityState === 'hidden') { - stop(); - } else if (document.visibilityState === 'visible') { - start(); - } - }); - } + document.addEventListener('visibilitychange', function () { + if (document.visibilityState === 'hidden') { + stop(); + } else if (document.visibilityState === 'visible') { + start(); + } + }); + + start(); function start() { if (interval != null) { @@ -35,15 +34,17 @@ layui.use(['jquery', 'helper'], function () { } function learning() { - $.ajax({ - type: 'POST', - url: learningUrl, - data: { - plan_id: planId, - request_id: requestId, - interval_time: intervalTime, - } - }); + if (userId !== '0' && planId !== '0') { + $.ajax({ + type: 'POST', + url: learningUrl, + data: { + plan_id: planId, + request_id: requestId, + interval_time: intervalTime, + } + }); + } } }); \ No newline at end of file diff --git a/public/static/home/js/chapter.vod.player.js b/public/static/home/js/chapter.vod.player.js index 0af43dbc..3ef7a682 100644 --- a/public/static/home/js/chapter.vod.player.js +++ b/public/static/home/js/chapter.vod.player.js @@ -8,8 +8,9 @@ layui.use(['jquery', 'helper'], function () { var userId = window.user.id; var requestId = helper.getRequestId(); var chapterId = $('input[name="chapter.id"]').val(); - var planId = $('input[name="chapter.plan_id"]').val(); - var lastPosition = $('input[name="chapter.position"]').val(); + var cover = $('input[name="chapter.cover"]').val(); + var planId = $('input[name="chapter.me.plan_id"]').val(); + var position = $('input[name="chapter.me.position"]').val(); var learningUrl = $('input[name="chapter.learning_url"]').val(); var playUrls = JSON.parse($('input[name="chapter.play_urls"]').val()); @@ -33,6 +34,7 @@ layui.use(['jquery', 'helper'], function () { var player = new DPlayer({ container: document.getElementById('player'), video: { + pic: cover, quality: quality, defaultQuality: 0, } @@ -60,13 +62,13 @@ layui.use(['jquery', 'helper'], function () { player.toggle(); }); - var position = getLastPosition(); + var lastPosition = getLastPosition(); /** * 上次播放位置 */ - if (position > 0) { - player.seek(position); + if (lastPosition > 0) { + player.seek(lastPosition); } function getPositionKey() { @@ -76,7 +78,7 @@ layui.use(['jquery', 'helper'], function () { function getLastPosition() { var key = getPositionKey(); var value = localStorage.getItem(key); - return value != null ? parseInt(value) : lastPosition; + return value != null ? parseInt(value) : position; } function setLastPosition(value) { diff --git a/public/static/home/js/common.js b/public/static/home/js/common.js index c539f443..a5df2cba 100644 --- a/public/static/home/js/common.js +++ b/public/static/home/js/common.js @@ -95,53 +95,10 @@ layui.use(['jquery', 'form', 'element', 'layer', 'helper'], function () { return false; }); - $('.kg-delete').on('click', function () { - var url = $(this).data('url'); - var tips = $(this).data('tips'); - tips = tips || '确定要删除吗?'; - layer.confirm(tips, function () { - $.ajax({ - type: 'POST', - url: url, - success: function (res) { - if (res.msg !== '') { - layer.msg(res.msg, {icon: 1}); - } - if (res.location) { - setTimeout(function () { - window.location.href = res.location; - }, 1500); - } else { - setTimeout(function () { - window.location.reload(); - }, 1500); - } - } - }); - }); - }); - $('.kg-back').on('click', function () { window.history.back(); }); - $('.ke-content').on('click', 'img', function () { - var width = $(window).width() * 0.8 + 'px'; - var height = $(window).height() * 0.8 + 'px'; - var src = $(this).attr('src'); - var style = 'max-width:' + width + ';max-height:' + height; - var content = 'preview'; - layer.open({ - type: 1, - title: false, - closeBtn: 0, - area: ['auto'], - skin: 'layui-layer-nobg', - shadeClose: true, - content: content, - }); - }); - $('.nav-search').on('click', function () { var content = '
'; content += ''; @@ -169,6 +126,29 @@ layui.use(['jquery', 'form', 'element', 'layer', 'helper'], function () { }); }); + /** + * 内容图片放大 + */ + $('body').on('click', '.ke-content img,.kg-thumbs img', function () { + var width = $(window).width() * 0.8 + 'px'; + var height = $(window).height() * 0.8 + 'px'; + var src = $(this).attr('src'); + var style = 'max-width:' + width + ';max-height:' + height; + var content = 'preview'; + layer.open({ + type: 1, + title: false, + closeBtn: 0, + area: ['auto'], + skin: 'layui-layer-nobg', + shadeClose: true, + content: content, + }); + }); + + /** + * 分页异步加载 + */ $('body').on('click', '.layui-laypage > a', function () { var url = $(this).data('url'); var target = $(this).data('target'); @@ -190,4 +170,30 @@ layui.use(['jquery', 'form', 'element', 'layer', 'helper'], function () { }); }); + $('body').on('click', '.kg-delete', function () { + var url = $(this).data('url'); + var tips = $(this).data('tips'); + tips = tips || '确定要删除吗?'; + layer.confirm(tips, function () { + $.ajax({ + type: 'POST', + url: url, + success: function (res) { + if (res.msg !== '') { + layer.msg(res.msg, {icon: 1}); + } + if (res.location) { + setTimeout(function () { + window.location.href = res.location; + }, 1500); + } else { + setTimeout(function () { + window.location.reload(); + }, 1500); + } + } + }); + }); + }); + }); \ No newline at end of file diff --git a/public/static/home/js/flashsale.js b/public/static/home/js/flashsale.js deleted file mode 100644 index a20bce95..00000000 --- a/public/static/home/js/flashsale.js +++ /dev/null @@ -1,35 +0,0 @@ -layui.use(['jquery', 'layer', 'helper'], function () { - - var $ = layui.jquery; - var layer = layui.layer; - var helper = layui.helper; - - setInterval(function () { - window.location.reload(); - }, 60000); - - $('.package-link').on('click', function () { - var url = $(this).data('url'); - layer.open({ - type: 2, - title: '套餐课程', - content: url, - area: ['800px', '280px'] - }); - }); - - $('.order').on('click', function () { - var id = $(this).data('id'); - helper.checkLogin(function () { - $.ajax({ - type: 'POST', - url: '/flash/sale/order', - data: {id: id}, - success: function (res) { - window.location.href = res.location; - } - }); - }); - }); - -}); \ No newline at end of file diff --git a/public/static/home/js/list.filter.js b/public/static/home/js/list.filter.js new file mode 100644 index 00000000..d4b167f8 --- /dev/null +++ b/public/static/home/js/list.filter.js @@ -0,0 +1,18 @@ +layui.use(['jquery'], function () { + + var $ = layui.jquery; + + var $filter = $('.filter-wrap'); + + $('.filter-toggle').on('click', function () { + var $icon = $(this).find('.layui-icon'); + if ($icon.hasClass('layui-icon-up')) { + $icon.removeClass('layui-icon-up').addClass('layui-icon-down'); + $filter.hide(); + } else { + $icon.removeClass('layui-icon-down').addClass('layui-icon-up'); + $filter.show(); + } + }); + +}); \ No newline at end of file diff --git a/public/static/home/js/question.list.js b/public/static/home/js/question.list.js index e7793a43..1640b8be 100644 --- a/public/static/home/js/question.list.js +++ b/public/static/home/js/question.list.js @@ -3,8 +3,14 @@ layui.use(['jquery', 'helper'], function () { var $ = layui.jquery; var helper = layui.helper; + $('.btn-ask').on('click', function () { + var url = $(this).data('url'); + helper.checkLogin(function () { + window.location.href = url; + }); + }); + var $questionList = $('#question-list'); - var $sidebarMyTags = $('#sidebar-my-tags'); var $sidebarHotQuestions = $('#sidebar-hot-questions'); var $sidebarTopAnswerers = $('#sidebar-top-answerers'); @@ -12,10 +18,6 @@ layui.use(['jquery', 'helper'], function () { helper.ajaxLoadHtml($questionList.data('url'), $questionList.attr('id')); } - if ($sidebarMyTags.length > 0) { - helper.ajaxLoadHtml($sidebarMyTags.data('url'), $sidebarMyTags.attr('id')); - } - if ($sidebarHotQuestions.length > 0) { helper.ajaxLoadHtml($sidebarHotQuestions.data('url'), $sidebarHotQuestions.attr('id')); } diff --git a/public/static/home/js/user.console.js b/public/static/home/js/user.console.js index 41b5e07f..4e28e434 100644 --- a/public/static/home/js/user.console.js +++ b/public/static/home/js/user.console.js @@ -41,7 +41,7 @@ layui.use(['jquery', 'layer'], function () { type: 2, title: '发布评价', content: [url, 'no'], - area: ['640px', '400px'], + area: ['640px', '480px'], cancel: function () { parent.location.reload(); } @@ -57,7 +57,7 @@ layui.use(['jquery', 'layer'], function () { type: 2, title: '修改评价', content: [url, 'no'], - area: ['640px', '400px'], + area: ['640px', '480px'], cancel: function () { parent.location.reload(); } diff --git a/scheduler.php b/scheduler.php index 98806369..f6556b56 100644 --- a/scheduler.php +++ b/scheduler.php @@ -36,9 +36,6 @@ $scheduler->php($script, $bin, ['--task' => 'server_monitor', '--action' => 'mai $scheduler->php($script, $bin, ['--task' => 'close_trade', '--action' => 'main']) ->everyMinute(13); -$scheduler->php($script, $bin, ['--task' => 'close_flash_sale_order', '--action' => 'main']) - ->everyMinute(15); - $scheduler->php($script, $bin, ['--task' => 'notice', '--action' => 'main']) ->everyMinute(); From 3dd5490bdb048d76ab89720ffbe128a42dc5d483 Mon Sep 17 00:00:00 2001 From: xiaochong0302 Date: Wed, 6 Dec 2023 20:24:09 +0800 Subject: [PATCH 08/21] =?UTF-8?q?=E9=98=B6=E6=AE=B5=E6=80=A7=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Admin/Views/category/list.volt | 2 +- app/Http/Admin/Views/index/main_app_info.volt | 2 +- .../Home/Controllers/TeacherController.php | 37 +++++++-- app/Http/Home/Services/ArticleQuery.php | 15 ++-- app/Http/Home/Services/CourseQuery.php | 49 +++-------- app/Http/Home/Services/QuestionQuery.php | 15 ++-- app/Http/Home/Views/course/show_teacher.volt | 2 +- app/Http/Home/Views/macros/consult.volt | 8 +- app/Http/Home/Views/partials/empty.volt | 4 + .../Home/Views/teacher/console/consults.volt | 3 - .../Home/Views/teacher/console/courses.volt | 11 +-- app/Http/Home/Views/teacher/courses.volt | 16 ++++ app/Http/Home/Views/teacher/list.volt | 2 +- app/Http/Home/Views/teacher/show.volt | 81 +++++++++++++++++++ app/Repos/TeacherLive.php | 4 +- app/Services/Logic/Article/ArticleList.php | 5 ++ app/Services/Logic/Consult/ConsultList.php | 73 +++++++++++++++++ app/Services/Logic/Course/CourseList.php | 18 ++++- app/Services/Logic/Question/QuestionList.php | 5 ++ .../Logic/Teacher/Console/ConsultList.php | 45 ++--------- .../Logic/Teacher/Console/LiveList.php | 6 +- app/Services/Logic/Teacher/CourseList.php | 47 +++-------- app/Services/Logic/User/AnswerList.php | 2 +- app/Services/Logic/User/ArticleList.php | 3 +- app/Services/Logic/User/CourseList.php | 10 +-- app/Services/Logic/User/QuestionList.php | 2 +- app/Validators/ArticleQuery.php | 24 ++---- app/Validators/CourseQuery.php | 26 ++---- app/Validators/QuestionQuery.php | 22 ++--- db/migrations/20210403184518.php | 2 +- public/static/home/css/common.css | 14 ++++ public/static/home/js/teacher.show.js | 26 ++++++ 32 files changed, 359 insertions(+), 222 deletions(-) create mode 100644 app/Http/Home/Views/partials/empty.volt create mode 100644 app/Http/Home/Views/teacher/courses.volt create mode 100644 app/Http/Home/Views/teacher/show.volt create mode 100644 app/Services/Logic/Consult/ConsultList.php create mode 100644 public/static/home/js/teacher.show.js diff --git a/app/Http/Admin/Views/category/list.volt b/app/Http/Admin/Views/category/list.volt index 3f6351a0..7e2efff7 100644 --- a/app/Http/Admin/Views/category/list.volt +++ b/app/Http/Admin/Views/category/list.volt @@ -39,7 +39,7 @@
图标 名称 层级子类子节点 排序 发布 操作
当前版本{{ app_info.version }}{{ app_info.alias }} {{ app_info.version }}
获取渠道
- @@ -30,7 +29,6 @@ - @@ -47,7 +45,6 @@

咨询:{{ item.question }}

回复:{{ answer }}

- - - - + + - @@ -33,10 +31,9 @@ {% for item in pager.items %} {% set course_url = url({'for':'home.course.show','id':item.id}) %} - - + + - {% endfor %} diff --git a/app/Http/Home/Views/teacher/courses.volt b/app/Http/Home/Views/teacher/courses.volt new file mode 100644 index 00000000..6363f1ed --- /dev/null +++ b/app/Http/Home/Views/teacher/courses.volt @@ -0,0 +1,16 @@ +{{ partial('macros/course') }} + +{% if pager.total_pages > 0 %} +
+
+ {% for item in pager.items %} +
+ {{ course_card(item) }} +
+ {% endfor %} +
+
+ {{ partial('partials/pager_ajax') }} +{% else %} + {{ partial('partials/empty') }} +{% endif %} \ No newline at end of file diff --git a/app/Http/Home/Views/teacher/list.volt b/app/Http/Home/Views/teacher/list.volt index 2b850ea3..8d8fb097 100644 --- a/app/Http/Home/Views/teacher/list.volt +++ b/app/Http/Home/Views/teacher/list.volt @@ -6,7 +6,7 @@
diff --git a/app/Http/Home/Views/teacher/show.volt b/app/Http/Home/Views/teacher/show.volt new file mode 100644 index 00000000..43bfcc36 --- /dev/null +++ b/app/Http/Home/Views/teacher/show.volt @@ -0,0 +1,81 @@ +{% extends 'templates/main.volt' %} + +{% block content %} + + {{ partial('macros/user') }} + + {% set share_url = share_url('user',user.id,auth_user.id) %} + {% set qrcode_url = url({'for':'home.qrcode'},{'text':share_url}) %} + {% set avatar_class = user.vip == 1 ? 'avatar vip' : 'avatar' %} + + + + + + {% set courses_url = url({'for':'home.teacher.courses','id':user.id}) %} + +
+
+
    +
  • 点播课程
  • +
  • 直播课程
  • +
  • 图文课程
  • +
  • 面授课程
  • +
+
+
+
+
+
+
+
+
+ +
+ + + + +
+ +{% endblock %} + +{% block include_js %} + + {{ js_include('lib/clipboard.min.js') }} + {{ js_include('home/js/teacher.show.js') }} + {{ js_include('home/js/user.share.js') }} + {{ js_include('home/js/copy.js') }} + +{% endblock %} \ No newline at end of file diff --git a/app/Repos/TeacherLive.php b/app/Repos/TeacherLive.php index 8214471f..cd961a07 100644 --- a/app/Repos/TeacherLive.php +++ b/app/Repos/TeacherLive.php @@ -32,9 +32,7 @@ class TeacherLive extends Repository ->addFrom(ChapterModel::class, 'chapter') ->join(ChapterLiveModel::class, 'chapter.id = cl.chapter_id', 'cl') ->join(CourseModel::class, 'chapter.course_id = course.id', 'course') - ->join(CourseUserModel::class, 'course.id = cu.course_id', 'cu') - ->where('cu.user_id = :user_id:', ['user_id' => $userId]) - ->andWhere('cu.role_type = :role_type:', ['role_type' => CourseUserModel::ROLE_TEACHER]) + ->where('course.teacher_id = :teacher_id:', ['teacher_id' => $userId]) ->andWhere('course.model = :model:', ['model' => CourseModel::MODEL_LIVE]) ->andWhere('cl.start_time > :start_time:', ['start_time' => strtotime('today')]) ->orderBy('cl.start_time ASC'); diff --git a/app/Services/Logic/Article/ArticleList.php b/app/Services/Logic/Article/ArticleList.php index 4dec3ad8..615314f6 100644 --- a/app/Services/Logic/Article/ArticleList.php +++ b/app/Services/Logic/Article/ArticleList.php @@ -117,6 +117,11 @@ class ArticleList extends LogicService $query = []; + if (isset($params['owner_id'])) { + $user = $validator->checkUser($params['owner_id']); + $query['owner_id'] = $user->id; + } + if (isset($params['tag_id'])) { $tag = $validator->checkTag($params['tag_id']); $query['tag_id'] = $tag->id; diff --git a/app/Services/Logic/Consult/ConsultList.php b/app/Services/Logic/Consult/ConsultList.php new file mode 100644 index 00000000..5718355d --- /dev/null +++ b/app/Services/Logic/Consult/ConsultList.php @@ -0,0 +1,73 @@ +getSort(); + $page = $pagerQuery->getPage(); + $limit = $pagerQuery->getLimit(); + $params = $pagerQuery->getParams(); + + $params['deleted'] = 0; + + $consultRepo = new ConsultRepo(); + + $pager = $consultRepo->paginate($params, $sort, $page, $limit); + + return $this->handleConsults($pager); + } + + public function handleConsults($pager) + { + if ($pager->total_items == 0) { + return $pager; + } + + $builder = new ConsultListBuilder(); + + $consults = $pager->items->toArray(); + $courses = $builder->getCourses($consults); + $users = $builder->getUsers($consults); + + $items = []; + + foreach ($consults as $consult) { + + $course = $courses[$consult['course_id']] ?? new \stdClass(); + $owner = $users[$consult['owner_id']] ?? new \stdClass(); + + $items[] = [ + 'id' => $consult['id'], + 'question' => $consult['question'], + 'answer' => $consult['answer'], + 'priority' => $consult['priority'], + 'like_count' => $consult['like_count'], + 'reply_time' => $consult['reply_time'], + 'create_time' => $consult['create_time'], + 'course' => $course, + 'owner' => $owner, + ]; + } + + $pager->items = $items; + + return $pager; + } + +} diff --git a/app/Services/Logic/Course/CourseList.php b/app/Services/Logic/Course/CourseList.php index ef4eb900..1cfd9f5a 100644 --- a/app/Services/Logic/Course/CourseList.php +++ b/app/Services/Logic/Course/CourseList.php @@ -58,7 +58,7 @@ class CourseList extends LogicService return $this->handleCourses($pager); } - protected function handleCourses($pager) + public function handleCourses($pager) { if ($pager->total_items == 0) { return $pager; @@ -105,12 +105,24 @@ class CourseList extends LogicService $query = []; + if (isset($params['teacher_id'])) { + $user = $validator->checkUser($params['teacher_id']); + $query['teacher_id'] = $user->id; + } + + if (isset($params['tag_id'])) { + $tag = $validator->checkTag($params['tag_id']); + $query['tag_id'] = $tag->id; + } + if (isset($params['tc'])) { - $query['tc'] = $validator->checkTopCategory($params['tc']); + $category = $validator->checkCategory($params['tc']); + $query['tc'] = $category->id; } if (isset($params['sc'])) { - $query['sc'] = $validator->checkSubCategory($params['sc']); + $category = $validator->checkCategory($params['sc']); + $query['sc'] = $category->id; } if (isset($params['model'])) { diff --git a/app/Services/Logic/Question/QuestionList.php b/app/Services/Logic/Question/QuestionList.php index f9eadfd9..4664d9b5 100644 --- a/app/Services/Logic/Question/QuestionList.php +++ b/app/Services/Logic/Question/QuestionList.php @@ -123,6 +123,11 @@ class QuestionList extends LogicService $query = []; + if (isset($params['owner_id'])) { + $user = $validator->checkUser($params['owner_id']); + $query['owner_id'] = $user->id; + } + if (isset($params['tag_id'])) { $tag = $validator->checkTag($params['tag_id']); $query['tag_id'] = $tag->id; diff --git a/app/Services/Logic/Teacher/Console/ConsultList.php b/app/Services/Logic/Teacher/Console/ConsultList.php index 11e99f8a..c875575f 100644 --- a/app/Services/Logic/Teacher/Console/ConsultList.php +++ b/app/Services/Logic/Teacher/Console/ConsultList.php @@ -7,9 +7,9 @@ namespace App\Services\Logic\Teacher\Console; -use App\Builders\ConsultList as ConsultListBuilder; use App\Library\Paginator\Query as PagerQuery; use App\Repos\TeacherConsult as TeacherConsultRepo; +use App\Services\Logic\Consult\ConsultList as ConsultListService; use App\Services\Logic\Service as LogicService; class ConsultList extends LogicService @@ -21,13 +21,12 @@ class ConsultList extends LogicService $pagerQuery = new PagerQuery(); - $params = $pagerQuery->getParams(); $sort = $pagerQuery->getSort(); $page = $pagerQuery->getPage(); $limit = $pagerQuery->getLimit(); + $params = $pagerQuery->getParams(); - $params['user_id'] = $user->id; - + $params['teacher_id'] = $user->id; $params['status'] = $params['status'] ?? null; if ($params['status'] == 'pending') { @@ -45,43 +44,9 @@ class ConsultList extends LogicService protected function handleConsults($pager) { - if ($pager->total_items == 0) { - return $pager; - } + $service = new ConsultListService(); - $builder = new ConsultListBuilder(); - - $consults = $pager->items->toArray(); - - $courses = $builder->getCourses($consults); - $chapters = $builder->getChapters($consults); - $users = $builder->getUsers($consults); - - $items = []; - - foreach ($consults as $consult) { - - $course = $courses[$consult['course_id']] ?? new \stdClass(); - $chapter = $chapters[$consult['chapter_id']] ?? new \stdClass(); - $owner = $users[$consult['owner_id']] ?? new \stdClass(); - - $items[] = [ - 'id' => $consult['id'], - 'question' => $consult['question'], - 'answer' => $consult['answer'], - 'priority' => $consult['priority'], - 'like_count' => $consult['like_count'], - 'reply_time' => $consult['reply_time'], - 'create_time' => $consult['create_time'], - 'course' => $course, - 'chapter' => $chapter, - 'owner' => $owner, - ]; - } - - $pager->items = $items; - - return $pager; + return $service->handleConsults($pager); } } diff --git a/app/Services/Logic/Teacher/Console/LiveList.php b/app/Services/Logic/Teacher/Console/LiveList.php index cd9c3dc5..4f971309 100644 --- a/app/Services/Logic/Teacher/Console/LiveList.php +++ b/app/Services/Logic/Teacher/Console/LiveList.php @@ -18,14 +18,14 @@ class LiveList extends LogicService { $user = $this->getLoginUser(); - $teacherLiveRepo = new TeacherLiveRepo(); - $pagerQuery = new PagerQuery(); $page = $pagerQuery->getPage(); $limit = $pagerQuery->getLimit(); - $pager = $teacherLiveRepo->paginate($user->id, $page, $limit); + $repo = new TeacherLiveRepo(); + + $pager = $repo->paginate($user->id, $page, $limit); if ($pager->total_items == 0) { return $pager; diff --git a/app/Services/Logic/Teacher/CourseList.php b/app/Services/Logic/Teacher/CourseList.php index 00efbc69..aa971cd6 100644 --- a/app/Services/Logic/Teacher/CourseList.php +++ b/app/Services/Logic/Teacher/CourseList.php @@ -8,7 +8,8 @@ namespace App\Services\Logic\Teacher; use App\Library\Paginator\Query as PagerQuery; -use App\Repos\TeacherCourse as TeacherCourseRepo; +use App\Repos\Course as CourseRepo; +use App\Services\Logic\Course\CourseList as CourseListService; use App\Services\Logic\Service as LogicService; use App\Services\Logic\UserTrait; @@ -19,55 +20,29 @@ class CourseList extends LogicService public function handle($id) { - $user = $this->checkUser($id); + $user = $this->checkUserCache($id); $pagerQuery = new PagerQuery(); + $sort = $pagerQuery->getSort(); $page = $pagerQuery->getPage(); $limit = $pagerQuery->getLimit(); + $params = $pagerQuery->getParams(); - $repo = new TeacherCourseRepo(); + $params['teacher_id'] = $user->id; - $pager = $repo->paginate($user->id, $page, $limit); + $courseRepo = new CourseRepo(); + + $pager = $courseRepo->paginate($params, $sort, $page, $limit); return $this->handleCourses($pager); } protected function handleCourses($pager) { - if ($pager->total_items == 0) { - return $pager; - } + $service = new CourseListService(); - $courses = $pager->items->toArray(); - - $baseUrl = kg_cos_url(); - - $items = []; - - foreach ($courses as $course) { - - $course['cover'] = $baseUrl . $course['cover']; - - $items[] = [ - 'id' => $course['id'], - 'title' => $course['title'], - 'cover' => $course['cover'], - 'market_price' => (float)$course['market_price'], - 'vip_price' => (float)$course['vip_price'], - 'rating' => (float)$course['rating'], - 'model' => $course['model'], - 'level' => $course['level'], - 'user_count' => $course['user_count'], - 'lesson_count' => $course['lesson_count'], - 'review_count' => $course['review_count'], - 'favorite_count' => $course['favorite_count'], - ]; - } - - $pager->items = $items; - - return $pager; + return $service->handleCourses($pager); } } diff --git a/app/Services/Logic/User/AnswerList.php b/app/Services/Logic/User/AnswerList.php index 31afe7c7..4e43e902 100644 --- a/app/Services/Logic/User/AnswerList.php +++ b/app/Services/Logic/User/AnswerList.php @@ -21,7 +21,7 @@ class AnswerList extends LogicService public function handle($id) { - $user = $this->checkUser($id); + $user = $this->checkUserCache($id); $pagerQuery = new PagerQuery(); diff --git a/app/Services/Logic/User/ArticleList.php b/app/Services/Logic/User/ArticleList.php index a567322f..dbae803e 100644 --- a/app/Services/Logic/User/ArticleList.php +++ b/app/Services/Logic/User/ArticleList.php @@ -21,7 +21,7 @@ class ArticleList extends LogicService public function handle($id) { - $user = $this->checkUser($id); + $user = $this->checkUserCache($id); $pagerQuery = new PagerQuery(); @@ -29,7 +29,6 @@ class ArticleList extends LogicService $params['owner_id'] = $user->id; $params['published'] = ArticleModel::PUBLISH_APPROVED; - $params['private'] = 0; $params['deleted'] = 0; $sort = $pagerQuery->getSort(); diff --git a/app/Services/Logic/User/CourseList.php b/app/Services/Logic/User/CourseList.php index 4b6756cd..a8e0c044 100644 --- a/app/Services/Logic/User/CourseList.php +++ b/app/Services/Logic/User/CourseList.php @@ -21,7 +21,7 @@ class CourseList extends LogicService public function handle($id) { - $user = $this->checkUser($id); + $user = $this->checkUserCache($id); $pagerQuery = new PagerQuery(); @@ -34,14 +34,14 @@ class CourseList extends LogicService $page = $pagerQuery->getPage(); $limit = $pagerQuery->getLimit(); - $courseUserRepo = new CourseUserRepo(); + $repo = new CourseUserRepo(); - $pager = $courseUserRepo->paginate($params, $sort, $page, $limit); + $pager = $repo->paginate($params, $sort, $page, $limit); - return $this->handleCourses($pager); + return $this->handlePager($pager); } - protected function handleCourses($pager) + protected function handlePager($pager) { if ($pager->total_items == 0) { return $pager; diff --git a/app/Services/Logic/User/QuestionList.php b/app/Services/Logic/User/QuestionList.php index 27c02dc8..102bc263 100644 --- a/app/Services/Logic/User/QuestionList.php +++ b/app/Services/Logic/User/QuestionList.php @@ -21,7 +21,7 @@ class QuestionList extends LogicService public function handle($id) { - $user = $this->checkUser($id); + $user = $this->checkUserCache($id); $pagerQuery = new PagerQuery(); diff --git a/app/Validators/ArticleQuery.php b/app/Validators/ArticleQuery.php index 7f6d47a8..8a4cf13e 100644 --- a/app/Validators/ArticleQuery.php +++ b/app/Validators/ArticleQuery.php @@ -9,7 +9,6 @@ namespace App\Validators; use App\Exceptions\BadRequest as BadRequestException; use App\Models\Article as ArticleModel; -use App\Models\Category as CategoryModel; class ArticleQuery extends Validator { @@ -18,30 +17,21 @@ class ArticleQuery extends Validator { $validator = new Category(); - $category = $validator->checkCategoryCache($id); - - if (!$category) { - throw new BadRequestException('article_query.invalid_category'); - } - - if ($category->type != CategoryModel::TYPE_ARTICLE) { - throw new BadRequestException('article_query.invalid_category'); - } - - return $category; + return $validator->checkCategoryCache($id); } public function checkTag($id) { $validator = new Tag(); - $tag = $validator->checkTagCache($id); + return $validator->checkTagCache($id); + } - if (!$tag) { - throw new BadRequestException('article_query.invalid_tag'); - } + public function checkUser($id) + { + $validator = new User(); - return $tag; + return $validator->checkUserCache($id); } public function checkSort($sort) diff --git a/app/Validators/CourseQuery.php b/app/Validators/CourseQuery.php index e50c3b77..6892c713 100644 --- a/app/Validators/CourseQuery.php +++ b/app/Validators/CourseQuery.php @@ -7,10 +7,7 @@ namespace App\Validators; -use App\Caches\Category as CategoryCache; -use App\Caches\Tag as TagCache; use App\Exceptions\BadRequest as BadRequestException; -use App\Models\Category as CategoryModel; use App\Models\Course as CourseModel; class CourseQuery extends Validator @@ -20,30 +17,21 @@ class CourseQuery extends Validator { $validator = new Category(); - $category = $validator->checkCategoryCache($id); - - if (!$category) { - throw new BadRequestException('course_query.invalid_category'); - } - - if ($category->type != CategoryModel::TYPE_COURSE) { - throw new BadRequestException('course_query.invalid_category'); - } - - return $category; + return $validator->checkCategoryCache($id); } public function checkTag($id) { $validator = new Tag(); - $tag = $validator->checkTagCache($id); + return $validator->checkTagCache($id); + } - if (!$tag) { - throw new BadRequestException('course_query.invalid_tag'); - } + public function checkUser($id) + { + $validator = new User(); - return $tag; + return $validator->checkUserCache($id); } public function checkLevel($level) diff --git a/app/Validators/QuestionQuery.php b/app/Validators/QuestionQuery.php index 68bdf3b5..ec907110 100644 --- a/app/Validators/QuestionQuery.php +++ b/app/Validators/QuestionQuery.php @@ -7,7 +7,6 @@ namespace App\Validators; -use App\Caches\Tag as TagCache; use App\Exceptions\BadRequest as BadRequestException; use App\Models\Question as QuestionModel; @@ -18,26 +17,21 @@ class QuestionQuery extends Validator { $validator = new Category(); - $category = $validator->checkCategoryCache($id); - - if (!$category) { - throw new BadRequestException('question_query.invalid_category'); - } - - return $category; + return $validator->checkCategoryCache($id); } public function checkTag($id) { - $tagCache = new TagCache(); + $validator = new Tag(); - $tag = $tagCache->get($id); + return $validator->checkTagCache($id); + } - if (!$tag) { - throw new BadRequestException('question_query.invalid_tag'); - } + public function checkUser($id) + { + $validator = new User(); - return $tag; + return $validator->checkUserCache($id); } public function checkSort($sort) diff --git a/db/migrations/20210403184518.php b/db/migrations/20210403184518.php index 787453a3..cc46ce94 100644 --- a/db/migrations/20210403184518.php +++ b/db/migrations/20210403184518.php @@ -155,7 +155,7 @@ final class V20210403184518 extends AbstractMigration 'id' => 5, 'parent_id' => 0, 'level' => 1, - 'name' => '师资', + 'name' => '教师', 'path' => ',5,', 'target' => '_self', 'url' => '/teacher/list', diff --git a/public/static/home/css/common.css b/public/static/home/css/common.css index 033d8da7..7012fd2e 100644 --- a/public/static/home/css/common.css +++ b/public/static/home/css/common.css @@ -96,6 +96,20 @@ background-color: #f2f2f2; } +.no-records { + padding: 20px; + color: #999; + text-align: center; +} + +.no-records .icon { + margin-bottom: 10px; +} + +.no-records .icon .layui-icon { + font-size: 100px; +} + .pager { margin-top: 20px; text-align: center; diff --git a/public/static/home/js/teacher.show.js b/public/static/home/js/teacher.show.js new file mode 100644 index 00000000..06bbe916 --- /dev/null +++ b/public/static/home/js/teacher.show.js @@ -0,0 +1,26 @@ +layui.use(['jquery', 'helper'], function () { + + var $ = layui.jquery; + var helper = layui.helper; + + if ($('#tab-vod').length > 0) { + var $tabVod = $('#tab-vod'); + helper.ajaxLoadHtml($tabVod.data('url'), $tabVod.attr('id')); + } + + if ($('#tab-live').length > 0) { + var $tabLive = $('#tab-live'); + helper.ajaxLoadHtml($tabLive.data('url'), $tabLive.attr('id')); + } + + if ($('#tab-read').length > 0) { + var $tabRead = $('#tab-read'); + helper.ajaxLoadHtml($tabRead.data('url'), $tabRead.attr('id')); + } + + if ($('#tab-offline').length > 0) { + var $tabOffline = $('#tab-offline'); + helper.ajaxLoadHtml($tabOffline.data('url'), $tabOffline.attr('id')); + } + +}); \ No newline at end of file From f3fcb6956aec099c57ccf4d8dc968ba5d79aec31 Mon Sep 17 00:00:00 2001 From: xiaochong0302 Date: Thu, 7 Dec 2023 17:09:28 +0800 Subject: [PATCH 09/21] beta --- CHANGELOG.md | 9 +- app/Console/Migrations/V20231201101515.php | 87 +++++++++++++++++++ .../Home/Controllers/TeacherController.php | 2 +- app/Http/Home/Views/teacher/list.volt | 2 +- db/migrations/20210403184518.php | 2 +- 5 files changed, 98 insertions(+), 4 deletions(-) create mode 100644 app/Console/Migrations/V20231201101515.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 091cff25..3e1502d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ -### [v1.6.7](https://gitee.com/koogua/course-tencent-cloud/releases/v1.6.7)(2023-10-30) +### [v1.6.7](https://gitee.com/koogua/course-tencent-cloud/releases/v1.6.7)(2023-12-15) +- 增加文章分类功能 +- 增加问题分类功能 +- 增加审核等批量功能 +- 增加若干业务插件埋点 +- 精简重构大量业务逻辑 +- 移除秒杀营销功能 +- 已发现的问题修复 ### [v1.6.6](https://gitee.com/koogua/course-tencent-cloud/releases/v1.6.6)(2023-08-30) diff --git a/app/Console/Migrations/V20231201101515.php b/app/Console/Migrations/V20231201101515.php new file mode 100644 index 00000000..0fbecd3f --- /dev/null +++ b/app/Console/Migrations/V20231201101515.php @@ -0,0 +1,87 @@ +handleCourseUsers(); + $this->handleChapterUsers(); + } + + protected function handleCourseUsers() + { + $courseUsers = $this->findCourseUsers(); + + if ($courseUsers->count() == 0) return; + + $mappings = []; + + /** + * 只保留第一条记录 + */ + foreach ($courseUsers as $courseUser) { + $key = $courseUser->course_id . '-' . $courseUser->user_id; + if (!isset($mappings[$key])) { + $mappings[$key] = 1; + } else { + $courseUser->deleted = 1; + $courseUser->update(); + } + } + } + + protected function handleChapterUsers() + { + $chapterUsers = $this->findChapterUsers(); + + if ($chapterUsers->count() == 0) return; + + /** + * 只保留第一条记录 + */ + foreach ($chapterUsers as $chapterUser) { + $key = $chapterUser->chapter_id . '-' . $chapterUser->user_id; + if (!isset($mappings[$key])) { + $mappings[$key] = 1; + } else { + $chapterUser->deleted = 1; + $chapterUser->update(); + } + } + } + + /** + * @return ResultsetInterface|CourseUserModel[] + */ + protected function findCourseUsers() + { + return CourseUserModel::query() + ->where('deleted = 0') + ->orderBy('id DESC') + ->execute(); + } + + /** + * @return ResultsetInterface|ChapterUserModel[] + */ + protected function findChapterUsers() + { + return ChapterUserModel::query() + ->where('deleted = 0') + ->orderBy('id DESC') + ->execute(); + } + +} \ No newline at end of file diff --git a/app/Http/Home/Controllers/TeacherController.php b/app/Http/Home/Controllers/TeacherController.php index 91b2ab65..6dfc10c6 100644 --- a/app/Http/Home/Controllers/TeacherController.php +++ b/app/Http/Home/Controllers/TeacherController.php @@ -31,7 +31,7 @@ class TeacherController extends Controller return $this->response->redirect($location); } - $this->seo->prependTitle('教师'); + $this->seo->prependTitle('师资'); } /** diff --git a/app/Http/Home/Views/teacher/list.volt b/app/Http/Home/Views/teacher/list.volt index 8d8fb097..2b850ea3 100644 --- a/app/Http/Home/Views/teacher/list.volt +++ b/app/Http/Home/Views/teacher/list.volt @@ -6,7 +6,7 @@
diff --git a/db/migrations/20210403184518.php b/db/migrations/20210403184518.php index cc46ce94..787453a3 100644 --- a/db/migrations/20210403184518.php +++ b/db/migrations/20210403184518.php @@ -155,7 +155,7 @@ final class V20210403184518 extends AbstractMigration 'id' => 5, 'parent_id' => 0, 'level' => 1, - 'name' => '教师', + 'name' => '师资', 'path' => ',5,', 'target' => '_self', 'url' => '/teacher/list', From 982b1d5ca78634a58318cdeb7c9ba44486b247c7 Mon Sep 17 00:00:00 2001 From: xiaochong0302 Date: Thu, 7 Dec 2023 20:57:25 +0800 Subject: [PATCH 10/21] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Console/Migrations/V20231201101515.php | 87 ---------------------- app/Repos/TeacherConsult.php | 29 ++++---- app/Repos/TeacherCourse.php | 39 ---------- 3 files changed, 14 insertions(+), 141 deletions(-) delete mode 100644 app/Console/Migrations/V20231201101515.php delete mode 100644 app/Repos/TeacherCourse.php diff --git a/app/Console/Migrations/V20231201101515.php b/app/Console/Migrations/V20231201101515.php deleted file mode 100644 index 0fbecd3f..00000000 --- a/app/Console/Migrations/V20231201101515.php +++ /dev/null @@ -1,87 +0,0 @@ -handleCourseUsers(); - $this->handleChapterUsers(); - } - - protected function handleCourseUsers() - { - $courseUsers = $this->findCourseUsers(); - - if ($courseUsers->count() == 0) return; - - $mappings = []; - - /** - * 只保留第一条记录 - */ - foreach ($courseUsers as $courseUser) { - $key = $courseUser->course_id . '-' . $courseUser->user_id; - if (!isset($mappings[$key])) { - $mappings[$key] = 1; - } else { - $courseUser->deleted = 1; - $courseUser->update(); - } - } - } - - protected function handleChapterUsers() - { - $chapterUsers = $this->findChapterUsers(); - - if ($chapterUsers->count() == 0) return; - - /** - * 只保留第一条记录 - */ - foreach ($chapterUsers as $chapterUser) { - $key = $chapterUser->chapter_id . '-' . $chapterUser->user_id; - if (!isset($mappings[$key])) { - $mappings[$key] = 1; - } else { - $chapterUser->deleted = 1; - $chapterUser->update(); - } - } - } - - /** - * @return ResultsetInterface|CourseUserModel[] - */ - protected function findCourseUsers() - { - return CourseUserModel::query() - ->where('deleted = 0') - ->orderBy('id DESC') - ->execute(); - } - - /** - * @return ResultsetInterface|ChapterUserModel[] - */ - protected function findChapterUsers() - { - return ChapterUserModel::query() - ->where('deleted = 0') - ->orderBy('id DESC') - ->execute(); - } - -} \ No newline at end of file diff --git a/app/Repos/TeacherConsult.php b/app/Repos/TeacherConsult.php index cc9025e2..8732b65b 100644 --- a/app/Repos/TeacherConsult.php +++ b/app/Repos/TeacherConsult.php @@ -9,7 +9,7 @@ namespace App\Repos; use App\Library\Paginator\Adapter\QueryBuilder as PagerQueryBuilder; use App\Models\Consult as ConsultModel; -use App\Models\CourseUser as CourseUserModel; +use App\Models\Course as CourseModel; class TeacherConsult extends Repository { @@ -17,35 +17,34 @@ class TeacherConsult extends Repository public function paginate($where, $sort = 'latest', $page = 1, $limit = 15) { $builder = $this->modelsManager->createBuilder() - ->columns('c.*') - ->addFrom(ConsultModel::class, 'c') - ->join(CourseUserModel::class, 'c.course_id = cu.course_id', 'cu') + ->columns('consult.*') + ->addFrom(ConsultModel::class, 'consult') + ->join(CourseModel::class, 'consult.course_id = course.id', 'course') ->where('1 = 1'); - if (!empty($where['user_id'])) { - $builder->andWhere('cu.user_id = :user_id:', ['user_id' => $where['user_id']]); - $builder->andWhere('cu.role_type = :role_type:', ['role_type' => CourseUserModel::ROLE_TEACHER]); - $builder->andWhere('cu.deleted = 0'); + if (!empty($where['teacher_id'])) { + $builder->andWhere('course.teacher_id = :teacher_id:', ['teacher_id' => $where['teacher_id']]); + $builder->andWhere('course.published = 1'); + $builder->andWhere('course.deleted = 0'); } if (isset($where['replied'])) { if ($where['replied'] == 1) { - $builder->andWhere('c.reply_time > 0'); + $builder->andWhere('consult.reply_time > 0'); } else { - $builder->andWhere('c.reply_time = 0'); + $builder->andWhere('consult.reply_time = 0'); } } - $builder->andWhere('c.published = :published:', ['published' => ConsultModel::PUBLISH_APPROVED]); - - $builder->andWhere('c.deleted = 0'); + $builder->andWhere('consult.published = :published:', ['published' => ConsultModel::PUBLISH_APPROVED]); + $builder->andWhere('consult.deleted = 0'); switch ($sort) { case 'oldest': - $orderBy = 'c.id ASC'; + $orderBy = 'consult.id ASC'; break; default: - $orderBy = 'c.id DESC'; + $orderBy = 'consult.id DESC'; break; } diff --git a/app/Repos/TeacherCourse.php b/app/Repos/TeacherCourse.php deleted file mode 100644 index b74a1ac9..00000000 --- a/app/Repos/TeacherCourse.php +++ /dev/null @@ -1,39 +0,0 @@ -modelsManager->createBuilder() - ->columns('course.*') - ->addFrom(CourseModel::class, 'course') - ->join(CourseUserModel::class, 'course.id = cu.course_id', 'cu') - ->where('cu.user_id = :user_id:', ['user_id' => $userId]) - ->andWhere('cu.role_type = :role_type:', ['role_type' => CourseUserModel::ROLE_TEACHER]) - ->andWhere('course.published = 1') - ->andWhere('course.deleted = 0') - ->orderBy('cu.id DESC'); - - $pager = new PagerQueryBuilder([ - 'builder' => $builder, - 'page' => $page, - 'limit' => $limit, - ]); - - return $pager->paginate(); - } - -} From 8f22cab2826a3e8f7d83e453e1ae9de7ad71f531 Mon Sep 17 00:00:00 2001 From: xiaochong0302 Date: Fri, 8 Dec 2023 20:17:39 +0800 Subject: [PATCH 11/21] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=90=8E=E7=9A=84=E8=B7=B3=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Caches/CategoryAllList.php | 12 ++++-------- app/Caches/CategoryList.php | 4 ---- app/Http/Admin/Controllers/AnswerController.php | 4 +--- app/Http/Admin/Controllers/ArticleController.php | 8 +------- app/Http/Admin/Controllers/CommentController.php | 6 ++---- app/Http/Admin/Controllers/ConsultController.php | 4 +--- app/Http/Admin/Controllers/QuestionController.php | 4 +--- app/Http/Admin/Controllers/ReviewController.php | 4 +--- app/Http/Admin/Services/Article.php | 2 +- app/Http/Admin/Services/Question.php | 2 +- 10 files changed, 13 insertions(+), 37 deletions(-) diff --git a/app/Caches/CategoryAllList.php b/app/Caches/CategoryAllList.php index 5fdfbc08..01866cc0 100644 --- a/app/Caches/CategoryAllList.php +++ b/app/Caches/CategoryAllList.php @@ -20,23 +20,19 @@ class CategoryAllList extends Cache return $this->lifetime; } - public function getKey($type = null) + public function getKey($id = null) { - return "category_all_list:{$type}"; + return "category_all_list:{$id}"; } - /** - * @param null $type - * @return array - */ - public function getContent($type = null) + public function getContent($id = null) { /** * @var Resultset $categories */ $categories = CategoryModel::query() ->columns(['id', 'parent_id', 'name', 'priority', 'level', 'path']) - ->where('type = :type:', ['type' => $type]) + ->where('type = :type:', ['type' => $id]) ->orderBy('level ASC, priority ASC') ->execute(); diff --git a/app/Caches/CategoryList.php b/app/Caches/CategoryList.php index 78a203eb..aede8d99 100644 --- a/app/Caches/CategoryList.php +++ b/app/Caches/CategoryList.php @@ -25,10 +25,6 @@ class CategoryList extends Cache return "category_list:{$id}"; } - /** - * @param null $id - * @return array - */ public function getContent($id = null) { /** diff --git a/app/Http/Admin/Controllers/AnswerController.php b/app/Http/Admin/Controllers/AnswerController.php index 69cc0846..b0ecffa5 100644 --- a/app/Http/Admin/Controllers/AnswerController.php +++ b/app/Http/Admin/Controllers/AnswerController.php @@ -247,10 +247,8 @@ class AnswerController extends Controller $answerService->batchDelete(); - $location = $this->url->get(['for' => 'admin.answer.list']); - $content = [ - 'location' => $location, + 'location' => $this->request->getHTTPReferer(), 'msg' => '批量删除成功', ]; diff --git a/app/Http/Admin/Controllers/ArticleController.php b/app/Http/Admin/Controllers/ArticleController.php index 05689bb4..2da839d3 100644 --- a/app/Http/Admin/Controllers/ArticleController.php +++ b/app/Http/Admin/Controllers/ArticleController.php @@ -64,11 +64,7 @@ class ArticleController extends Controller */ public function addAction() { - $articleService = new ArticleService(); - $categories = $articleService->getCategories(); - - $this->view->setVar('categories', $categories); } /** @@ -257,10 +253,8 @@ class ArticleController extends Controller $articleService->batchDelete(); - $location = $this->url->get(['for' => 'admin.mod.articles']); - $content = [ - 'location' => $location, + 'location' => $this->request->getHTTPReferer(), 'msg' => '批量删除成功', ]; diff --git a/app/Http/Admin/Controllers/CommentController.php b/app/Http/Admin/Controllers/CommentController.php index a34340aa..eea1a474 100644 --- a/app/Http/Admin/Controllers/CommentController.php +++ b/app/Http/Admin/Controllers/CommentController.php @@ -167,11 +167,9 @@ class CommentController extends Controller $commentService->batchDelete(); - $location = $this->url->get(['for' => 'admin.mod.comments']); - $content = [ - 'location' => $location, - 'msg' => '批量审核成功', + 'location' => $this->request->getHTTPReferer(), + 'msg' => '批量删除成功', ]; return $this->jsonSuccess($content); diff --git a/app/Http/Admin/Controllers/ConsultController.php b/app/Http/Admin/Controllers/ConsultController.php index ac3aea38..7f66dcf5 100644 --- a/app/Http/Admin/Controllers/ConsultController.php +++ b/app/Http/Admin/Controllers/ConsultController.php @@ -172,10 +172,8 @@ class ConsultController extends Controller $consultService->batchDelete(); - $location = $this->url->get(['for' => 'admin.mod.consults']); - $content = [ - 'location' => $location, + 'location' => $this->request->getHTTPReferer(), 'msg' => '批量删除成功', ]; diff --git a/app/Http/Admin/Controllers/QuestionController.php b/app/Http/Admin/Controllers/QuestionController.php index 7496f57b..f6140c1f 100644 --- a/app/Http/Admin/Controllers/QuestionController.php +++ b/app/Http/Admin/Controllers/QuestionController.php @@ -248,10 +248,8 @@ class QuestionController extends Controller $questionService->batchDelete(); - $location = $this->url->get(['for' => 'admin.question.list']); - $content = [ - 'location' => $location, + 'location' => $this->request->getHTTPReferer(), 'msg' => '批量删除成功', ]; diff --git a/app/Http/Admin/Controllers/ReviewController.php b/app/Http/Admin/Controllers/ReviewController.php index b853ae6b..3013dd78 100644 --- a/app/Http/Admin/Controllers/ReviewController.php +++ b/app/Http/Admin/Controllers/ReviewController.php @@ -174,10 +174,8 @@ class ReviewController extends Controller $reviewService->batchDelete(); - $location = $this->url->get(['for' => 'admin.mod.reviews']); - $content = [ - 'location' => $location, + 'location' => $this->request->getHTTPReferer(), 'msg' => '批量删除成功', ]; diff --git a/app/Http/Admin/Services/Article.php b/app/Http/Admin/Services/Article.php index dd445fdb..115d0f80 100644 --- a/app/Http/Admin/Services/Article.php +++ b/app/Http/Admin/Services/Article.php @@ -379,7 +379,7 @@ class Article extends Service foreach ($articles as $article) { - $article->published = ArticleModel::PUBLISH_REJECTED; + $article->deleted = 1; $article->update(); $this->handleArticleDeletedNotice($article, $sender); diff --git a/app/Http/Admin/Services/Question.php b/app/Http/Admin/Services/Question.php index 7a5f2102..18bfc401 100644 --- a/app/Http/Admin/Services/Question.php +++ b/app/Http/Admin/Services/Question.php @@ -364,7 +364,7 @@ class Question extends Service foreach ($questions as $question) { - $question->published = QuestionModel::PUBLISH_REJECTED; + $question->deleted = 1; $question->update(); $this->handleQuestionDeletedNotice($question, $sender); From 51428ac97a57620278d80a0016e59210440f7622 Mon Sep 17 00:00:00 2001 From: xiaochong0302 Date: Sat, 9 Dec 2023 09:01:18 +0800 Subject: [PATCH 12/21] =?UTF-8?q?=E8=A1=A5=E5=85=85=E9=81=97=E6=BC=8F?= =?UTF-8?q?=E7=9A=84=E6=89=B9=E9=87=8F=E5=88=A0=E9=99=A4=E7=82=B9=E5=87=BB?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/static/admin/js/common.js | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/public/static/admin/js/common.js b/public/static/admin/js/common.js index 36a916f4..d363faea 100644 --- a/public/static/admin/js/common.js +++ b/public/static/admin/js/common.js @@ -147,6 +147,38 @@ layui.use(['jquery', 'form', 'element', 'layer', 'kgDropdown'], function () { }); }); + $('.kg-batch').on('click', function () { + var url = $(this).data('url'); + var tips = $(this).data('tips'); + var defaultTips = '确定要执行批量操作吗?'; + var ids = []; + $('input:checkbox[class="item"]:checked').each(function (index, item) { + ids.push(item.value); + }); + if (ids.length === 0) { + layer.msg('没有选中任何条目', {icon: 2}); + return false; + } + tips = tips || defaultTips; + layer.confirm(tips, function () { + $.ajax({ + type: 'POST', + url: url, + data: {'ids': ids}, + success: function (res) { + layer.msg(res.msg, {icon: 1}); + if (res.location) { + setTimeout(function () { + window.location.href = res.location; + }, 1500); + } else { + window.location.reload(); + } + } + }); + }); + }); + $('.kg-delete,.kg-restore').on('click', function () { var url = $(this).data('url'); var tips = $(this).hasClass('kg-delete') ? '确定要删除吗?' : '确定要还原吗?'; From 817b32b067de6555dbbd79db7e5825c69bc6a389 Mon Sep 17 00:00:00 2001 From: xiaochong0302 Date: Sat, 9 Dec 2023 19:02:05 +0800 Subject: [PATCH 13/21] =?UTF-8?q?=E6=94=BE=E5=BC=83=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=9C=B0=E6=96=B9=E7=BC=93=E5=AD=98=E7=9A=84=E4=BD=BF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Caches/AppInfo.php | 8 ++--- app/Http/Admin/Services/Article.php | 4 +++ app/Http/Home/Views/article/edit.volt | 36 ++++++++++--------- app/Http/Home/Views/question/edit.volt | 38 +++++++++++--------- app/Library/Validators/Common.php | 9 +++++ app/Models/Article.php | 6 ++-- app/Models/Course.php | 4 +-- app/Models/Question.php | 18 ++++++++++ app/Services/Logic/Article/ArticleInfo.php | 2 +- app/Services/Logic/Article/ArticleList.php | 11 ++++++ app/Services/Logic/Comment/CommentInfo.php | 2 +- app/Services/Logic/Consult/ConsultInfo.php | 2 +- app/Services/Logic/Course/ResourceList.php | 2 +- app/Services/Logic/Question/QuestionInfo.php | 2 +- app/Services/Logic/Question/QuestionList.php | 7 ++++ app/Services/Logic/Trade/TradeInfo.php | 2 +- app/Validators/Article.php | 11 ++++++ app/Validators/Course.php | 2 +- app/Validators/Package.php | 2 +- app/Validators/PointGift.php | 2 +- app/Validators/Slide.php | 2 +- app/Validators/Topic.php | 2 +- app/Validators/Vip.php | 2 +- 23 files changed, 120 insertions(+), 56 deletions(-) diff --git a/app/Caches/AppInfo.php b/app/Caches/AppInfo.php index 0803bb9a..dd93d1b2 100644 --- a/app/Caches/AppInfo.php +++ b/app/Caches/AppInfo.php @@ -27,10 +27,10 @@ class AppInfo extends Cache $appInfo = new \App\Library\AppInfo(); return [ - 'name' => $appInfo->name, - 'alias' => $appInfo->alias, - 'link' => $appInfo->link, - 'version' => $appInfo->version, + 'name' => $appInfo->get('name'), + 'alias' => $appInfo->get('alias'), + 'link' => $appInfo->get('link'), + 'version' => $appInfo->get('version'), ]; } diff --git a/app/Http/Admin/Services/Article.php b/app/Http/Admin/Services/Article.php index 115d0f80..fb9c0b03 100644 --- a/app/Http/Admin/Services/Article.php +++ b/app/Http/Admin/Services/Article.php @@ -160,6 +160,10 @@ class Article extends Service $data['title'] = $validator->checkTitle($post['title']); } + if (isset($post['cover'])) { + $data['cover'] = $validator->checkCover($post['cover']); + } + if (isset($post['summary'])) { $data['summary'] = $validator->checkSummary($post['summary']); } diff --git a/app/Http/Home/Views/article/edit.volt b/app/Http/Home/Views/article/edit.volt index df148410..3049e516 100644 --- a/app/Http/Home/Views/article/edit.volt +++ b/app/Http/Home/Views/article/edit.volt @@ -28,24 +28,28 @@
-
- -
- + {% if category_options|length > 0 %} +
+ +
+ +
-
-
- -
-
+ {% endif %} + {% if xm_tags|length > 0 %} +
+ +
+
+
-
+ {% endif %}
diff --git a/app/Http/Home/Views/question/edit.volt b/app/Http/Home/Views/question/edit.volt index 385f34f6..d8b35ae8 100644 --- a/app/Http/Home/Views/question/edit.volt +++ b/app/Http/Home/Views/question/edit.volt @@ -2,7 +2,7 @@ {% block content %} - {% set title = question.id > 0 ? '编辑问题' : '提问题' %} + {% set title = question.id > 0 ? '编辑问题' : '发布问题' %} {% set action_url = question.id > 0 ? url({'for':'home.question.update','id':question.id}) : url({'for':'home.question.create'}) %}
-
- -
- + {% if category_options|length > 0 %} +
+ +
+ +
-
-
- -
-
+ {% endif %} + {% if xm_tags|length > 0 %} +
+ +
+
+
-
+ {% endif %}
diff --git a/app/Library/Validators/Common.php b/app/Library/Validators/Common.php index bfa7e8da..856592a2 100644 --- a/app/Library/Validators/Common.php +++ b/app/Library/Validators/Common.php @@ -114,4 +114,13 @@ class Common return $str == $date; } + public static function image($path) + { + $exts = ['png', 'gif', 'jpg', 'jpeg', 'webp']; + + $ext = pathinfo($path, PATHINFO_EXTENSION); + + return in_array(strtolower($ext), $exts); + } + } diff --git a/app/Models/Article.php b/app/Models/Article.php index cdc3e701..3ebfe3f7 100644 --- a/app/Models/Article.php +++ b/app/Models/Article.php @@ -249,9 +249,7 @@ class Article extends Model public function beforeSave() { - if (empty($this->cover)) { - $this->cover = kg_default_article_cover_path(); - } elseif (Text::startsWith($this->cover, 'http')) { + if (Text::startsWith($this->cover, 'http')) { $this->cover = self::getCoverPath($this->cover); } @@ -269,7 +267,7 @@ class Article extends Model public function afterFetch() { - if (!Text::startsWith($this->cover, 'http')) { + if (!empty($this->cover) && !Text::startsWith($this->cover, 'http')) { $this->cover = kg_cos_article_cover_url($this->cover); } diff --git a/app/Models/Course.php b/app/Models/Course.php index f72ca29d..6821c7b0 100644 --- a/app/Models/Course.php +++ b/app/Models/Course.php @@ -351,9 +351,7 @@ class Course extends Model public function beforeSave() { - if (empty($this->cover)) { - $this->cover = kg_default_course_cover_path(); - } elseif (Text::startsWith($this->cover, 'http')) { + if (Text::startsWith($this->cover, 'http')) { $this->cover = self::getCoverPath($this->cover); } diff --git a/app/Models/Question.php b/app/Models/Question.php index 66b8e05c..c06d35a3 100644 --- a/app/Models/Question.php +++ b/app/Models/Question.php @@ -11,6 +11,7 @@ use App\Caches\MaxQuestionId as MaxQuestionIdCache; use App\Services\Sync\QuestionIndex as QuestionIndexSync; use App\Services\Sync\QuestionScore as QuestionScoreSync; use Phalcon\Mvc\Model\Behavior\SoftDelete; +use Phalcon\Text; class Question extends Model { @@ -269,6 +270,10 @@ class Question extends Model public function beforeSave() { + if (Text::startsWith($this->cover, 'http')) { + $this->cover = self::getCoverPath($this->cover); + } + if (is_array($this->tags) || is_object($this->tags)) { $this->tags = kg_json_encode($this->tags); } @@ -283,11 +288,24 @@ class Question extends Model public function afterFetch() { + if (!empty($this->cover) && !Text::startsWith($this->cover, 'http')) { + $this->cover = kg_cos_article_cover_url($this->cover); + } + if (is_string($this->tags)) { $this->tags = json_decode($this->tags, true); } } + public static function getCoverPath($url) + { + if (Text::startsWith($url, 'http')) { + return parse_url($url, PHP_URL_PATH); + } + + return $url; + } + public static function publishTypes() { return [ diff --git a/app/Services/Logic/Article/ArticleInfo.php b/app/Services/Logic/Article/ArticleInfo.php index 6ad3bdbe..47c03f90 100644 --- a/app/Services/Logic/Article/ArticleInfo.php +++ b/app/Services/Logic/Article/ArticleInfo.php @@ -26,7 +26,7 @@ class ArticleInfo extends LogicService { $article = $this->checkArticle($id); - $user = $this->getCurrentUser(true); + $user = $this->getCurrentUser(); $result = $this->handleArticle($article, $user); diff --git a/app/Services/Logic/Article/ArticleList.php b/app/Services/Logic/Article/ArticleList.php index 615314f6..d34377b9 100644 --- a/app/Services/Logic/Article/ArticleList.php +++ b/app/Services/Logic/Article/ArticleList.php @@ -14,6 +14,7 @@ use App\Repos\Article as ArticleRepo; use App\Services\Category as CategoryService; use App\Services\Logic\Service as LogicService; use App\Validators\ArticleQuery as ArticleQueryValidator; +use Phalcon\Text; class ArticleList extends LogicService { @@ -77,10 +78,20 @@ class ArticleList extends LogicService $items = []; + $baseUrl = kg_cos_url(); + foreach ($articles as $article) { $article['tags'] = json_decode($article['tags'], true); + if (empty($article['cover'])) { + $article['cover'] = kg_default_article_cover_path(); + } + + if (!Text::startsWith($article['cover'], 'http')) { + $article['cover'] = $baseUrl . $article['cover']; + } + $category = $categories[$article['category_id']] ?? new \stdClass(); $owner = $users[$article['owner_id']] ?? new \stdClass(); diff --git a/app/Services/Logic/Comment/CommentInfo.php b/app/Services/Logic/Comment/CommentInfo.php index d0322310..04f873a6 100644 --- a/app/Services/Logic/Comment/CommentInfo.php +++ b/app/Services/Logic/Comment/CommentInfo.php @@ -25,7 +25,7 @@ class CommentInfo extends LogicService { $comment = $this->checkComment($id); - $user = $this->getCurrentUser(true); + $user = $this->getCurrentUser(); return $this->handleComment($comment, $user); } diff --git a/app/Services/Logic/Consult/ConsultInfo.php b/app/Services/Logic/Consult/ConsultInfo.php index 7370fef0..76177ccd 100644 --- a/app/Services/Logic/Consult/ConsultInfo.php +++ b/app/Services/Logic/Consult/ConsultInfo.php @@ -24,7 +24,7 @@ class ConsultInfo extends LogicService { $consult = $this->checkConsult($id); - $user = $this->getCurrentUser(true); + $user = $this->getCurrentUser(); return $this->handleConsult($consult, $user); } diff --git a/app/Services/Logic/Course/ResourceList.php b/app/Services/Logic/Course/ResourceList.php index abead04c..b16beda9 100644 --- a/app/Services/Logic/Course/ResourceList.php +++ b/app/Services/Logic/Course/ResourceList.php @@ -21,7 +21,7 @@ class ResourceList extends LogicService { $course = $this->checkCourse($id); - $user = $this->getCurrentUser(true); + $user = $this->getCurrentUser(); $this->setCourseUser($course, $user); diff --git a/app/Services/Logic/Question/QuestionInfo.php b/app/Services/Logic/Question/QuestionInfo.php index 939f0910..c72d8dcd 100644 --- a/app/Services/Logic/Question/QuestionInfo.php +++ b/app/Services/Logic/Question/QuestionInfo.php @@ -25,7 +25,7 @@ class QuestionInfo extends LogicService public function handle($id) { - $user = $this->getCurrentUser(true); + $user = $this->getCurrentUser(); $question = $this->checkQuestion($id); diff --git a/app/Services/Logic/Question/QuestionList.php b/app/Services/Logic/Question/QuestionList.php index 4664d9b5..1c44fd0b 100644 --- a/app/Services/Logic/Question/QuestionList.php +++ b/app/Services/Logic/Question/QuestionList.php @@ -14,6 +14,7 @@ use App\Repos\Question as QuestionRepo; use App\Services\Category as CategoryService; use App\Services\Logic\Service as LogicService; use App\Validators\QuestionQuery as QuestionQueryValidator; +use Phalcon\Text; class QuestionList extends LogicService { @@ -77,8 +78,14 @@ class QuestionList extends LogicService $items = []; + $cosUrl = kg_cos_url(); + foreach ($questions as $question) { + if (!empty($question['cover']) && !Text::startsWith($question['cover'], 'http')) { + $question['cover'] = $cosUrl . $question['cover']; + } + $question['tags'] = json_decode($question['tags'], true); $category = $categories[$question['category_id']] ?? new \stdClass(); diff --git a/app/Services/Logic/Trade/TradeInfo.php b/app/Services/Logic/Trade/TradeInfo.php index 73260166..bd06ffe4 100644 --- a/app/Services/Logic/Trade/TradeInfo.php +++ b/app/Services/Logic/Trade/TradeInfo.php @@ -26,7 +26,7 @@ class TradeInfo extends LogicService { $trade = $this->checkTradeBySn($sn); - $user = $this->getCurrentUser(true); + $user = $this->getCurrentUser(); return $this->handleTrade($trade, $user); } diff --git a/app/Validators/Article.php b/app/Validators/Article.php index 4d7598d4..2d29ec76 100644 --- a/app/Validators/Article.php +++ b/app/Validators/Article.php @@ -90,6 +90,17 @@ class Article extends Validator return $value; } + public function checkCover($cover) + { + $value = $this->filter->sanitize($cover, ['trim', 'string']); + + if (!CommonValidator::image($value)) { + throw new BadRequestException('article.invalid_cover'); + } + + return kg_cos_img_style_trim($value); + } + public function checkSummary($summary) { $value = $this->filter->sanitize($summary, ['trim', 'string']); diff --git a/app/Validators/Course.php b/app/Validators/Course.php index 43e38884..16bbae68 100644 --- a/app/Validators/Course.php +++ b/app/Validators/Course.php @@ -106,7 +106,7 @@ class Course extends Validator { $value = $this->filter->sanitize($cover, ['trim', 'string']); - if (!CommonValidator::url($value)) { + if (!CommonValidator::image($value)) { throw new BadRequestException('course.invalid_cover'); } diff --git a/app/Validators/Package.php b/app/Validators/Package.php index bcee13e3..8ccde670 100644 --- a/app/Validators/Package.php +++ b/app/Validators/Package.php @@ -69,7 +69,7 @@ class Package extends Validator { $value = $this->filter->sanitize($cover, ['trim', 'string']); - if (!CommonValidator::url($value)) { + if (!CommonValidator::image($value)) { throw new BadRequestException('package.invalid_cover'); } diff --git a/app/Validators/PointGift.php b/app/Validators/PointGift.php index 352f6504..99d7de0f 100644 --- a/app/Validators/PointGift.php +++ b/app/Validators/PointGift.php @@ -104,7 +104,7 @@ class PointGift extends Validator { $value = $this->filter->sanitize($cover, ['trim', 'string']); - if (!CommonValidator::url($value)) { + if (!CommonValidator::image($value)) { throw new BadRequestException('point_gift.invalid_cover'); } diff --git a/app/Validators/Slide.php b/app/Validators/Slide.php index 37874e42..ada286db 100644 --- a/app/Validators/Slide.php +++ b/app/Validators/Slide.php @@ -63,7 +63,7 @@ class Slide extends Validator { $value = $this->filter->sanitize($cover, ['trim', 'string']); - if (!CommonValidator::url($value)) { + if (!CommonValidator::image($value)) { throw new BadRequestException('slide.invalid_cover'); } diff --git a/app/Validators/Topic.php b/app/Validators/Topic.php index 5a146b02..d05ac0c5 100644 --- a/app/Validators/Topic.php +++ b/app/Validators/Topic.php @@ -86,7 +86,7 @@ class Topic extends Validator { $value = $this->filter->sanitize($cover, ['trim', 'string']); - if (!CommonValidator::url($value)) { + if (!CommonValidator::image($value)) { throw new BadRequestException('topic.invalid_cover'); } diff --git a/app/Validators/Vip.php b/app/Validators/Vip.php index 76a6e50e..67c04b65 100644 --- a/app/Validators/Vip.php +++ b/app/Validators/Vip.php @@ -48,7 +48,7 @@ class Vip extends Validator { $value = $this->filter->sanitize($cover, ['trim', 'string']); - if (!CommonValidator::url($value)) { + if (!CommonValidator::image($value)) { throw new BadRequestException('vip.invalid_cover'); } From dca1ccf79a48428fec9c80bf66af994e771e1abd Mon Sep 17 00:00:00 2001 From: xiaochong0302 Date: Sun, 10 Dec 2023 20:55:26 +0800 Subject: [PATCH 14/21] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=8E=92=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Caches/CourseRecommendedList.php | 90 ------------------- app/Console/Tasks/CleanDemoDataTask.php | 9 +- .../Admin/Controllers/AnswerController.php | 3 + .../Admin/Controllers/ConsultController.php | 3 + app/Http/Admin/Services/Question.php | 4 + app/Http/Admin/Views/answer/edit.volt | 19 +++- app/Http/Admin/Views/article/edit_basic.volt | 14 +-- app/Http/Admin/Views/consult/edit.volt | 16 ++++ app/Http/Admin/Views/package/edit.volt | 12 +-- app/Http/Admin/Views/question/edit.volt | 6 ++ app/Http/Admin/Views/question/edit_basic.volt | 15 ++-- app/Http/Admin/Views/question/edit_desc.volt | 2 +- app/Http/Admin/Views/question/edit_seo.volt | 21 +++++ .../Home/Controllers/CourseController.php | 14 --- app/Http/Home/Views/course/show.volt | 5 -- app/Http/Home/Views/macros/course.volt | 21 ++--- app/Http/Home/Views/partials/header.volt | 8 +- app/Http/Home/Views/search/index.volt | 32 +++++-- .../Home/Views/user/console/favorites.volt | 2 +- app/Models/Article.php | 2 +- app/Services/Logic/Article/ArticleList.php | 14 ++- app/Services/Logic/Course/RecommendedList.php | 30 ------- app/Services/Logic/Deliver/CourseDeliver.php | 7 +- app/Validators/Consult.php | 15 +--- app/Validators/Question.php | 13 +++ config/errors.php | 2 + public/static/home/css/common.css | 4 + public/static/home/js/article.edit.js | 20 +---- public/static/home/js/common.js | 1 - public/static/home/js/course.show.js | 5 -- public/static/home/js/question.edit.js | 19 +--- 31 files changed, 168 insertions(+), 260 deletions(-) delete mode 100644 app/Caches/CourseRecommendedList.php create mode 100644 app/Http/Admin/Views/question/edit_seo.volt delete mode 100644 app/Services/Logic/Course/RecommendedList.php diff --git a/app/Caches/CourseRecommendedList.php b/app/Caches/CourseRecommendedList.php deleted file mode 100644 index c810082f..00000000 --- a/app/Caches/CourseRecommendedList.php +++ /dev/null @@ -1,90 +0,0 @@ -lifetime; - } - - public function getKey($id = null) - { - return "course_recommended_list:{$id}"; - } - - public function getContent($id = null) - { - $courses = $this->findCourses(5); - - if ($courses->count() == 0) { - return []; - } - - return $this->handleContent($courses); - } - - /** - * @param CourseModel[] $courses - * @return array - */ - public function handleContent($courses) - { - $result = []; - - foreach ($courses as $course) { - - $userCount = $course->user_count; - - if ($course->fake_user_count > $course->user_count) { - $userCount = $course->fake_user_count; - } - - $result[] = [ - 'id' => $course->id, - 'title' => $course->title, - 'cover' => $course->cover, - 'model' => $course->model, - 'level' => $course->level, - 'rating' => round($course->rating, 1), - 'market_price' => (float)$course->market_price, - 'vip_price' => (float)$course->vip_price, - 'user_count' => $userCount, - 'lesson_count' => $course->lesson_count, - 'review_count' => $course->review_count, - 'favorite_count' => $course->favorite_count, - ]; - } - - return $result; - } - - /** - * @param int $limit - * @return ResultsetInterface|Resultset|CourseModel[] - */ - public function findCourses($limit = 5) - { - return CourseModel::query() - ->where('market_price > 0') - ->andWhere('published = 1') - ->andWhere('deleted = 0') - ->orderBy('RAND()') - ->limit($limit) - ->execute(); - } - -} diff --git a/app/Console/Tasks/CleanDemoDataTask.php b/app/Console/Tasks/CleanDemoDataTask.php index 24cba3df..fabd6a6d 100644 --- a/app/Console/Tasks/CleanDemoDataTask.php +++ b/app/Console/Tasks/CleanDemoDataTask.php @@ -8,12 +8,13 @@ namespace App\Console\Tasks; use App\Caches\CategoryList as CategoryListCache; +use App\Caches\CategoryAllList as CategoryAllListCache; use App\Caches\CategoryTreeList as CategoryTreeListCache; use App\Caches\IndexSlideList as IndexSlideListCache; use App\Models\Account as AccountModel; use App\Models\Category as CategoryModel; use App\Repos\User as UserRepo; -use App\Services\Utils\IndexCourseCache as IndexCourseCacheUtil; +use App\Services\Utils\IndexPageCache as IndexPageCacheUtil; class CleanDemoDataTask extends Task { @@ -81,17 +82,19 @@ class CleanDemoDataTask extends Task protected function cleanCache() { - $util = new IndexCourseCacheUtil(); + $util = new IndexPageCacheUtil(); $util->rebuild(); $slideListCache = new IndexSlideListCache(); $slideListCache->rebuild(); $categoryListCache = new CategoryListCache(); + $categoryAllListCache = new CategoryAllListCache(); $categoryTreeListCache = new CategoryTreeListCache(); foreach (CategoryModel::types() as $key => $value) { $categoryListCache->rebuild($key); + $categoryAllListCache->rebuild($key); $categoryTreeListCache->rebuild($key); } } @@ -114,7 +117,7 @@ class CleanDemoDataTask extends Task $user = $userRepo->findById(100015); - return $user ? true : false; + return (bool)$user; } } diff --git a/app/Http/Admin/Controllers/AnswerController.php b/app/Http/Admin/Controllers/AnswerController.php index b0ecffa5..d592c327 100644 --- a/app/Http/Admin/Controllers/AnswerController.php +++ b/app/Http/Admin/Controllers/AnswerController.php @@ -61,12 +61,15 @@ class AnswerController extends Controller { $answerService = new AnswerService(); + $publishTypes = $answerService->getPublishTypes(); + $answer = $answerService->getAnswer($id); $questionService = new QuestionService(); $question = $questionService->getQuestion($answer->question_id); + $this->view->setVar('publish_types', $publishTypes); $this->view->setVar('question', $question); $this->view->setVar('answer', $answer); } diff --git a/app/Http/Admin/Controllers/ConsultController.php b/app/Http/Admin/Controllers/ConsultController.php index 7f66dcf5..92a22c0d 100644 --- a/app/Http/Admin/Controllers/ConsultController.php +++ b/app/Http/Admin/Controllers/ConsultController.php @@ -57,8 +57,11 @@ class ConsultController extends Controller { $consultService = new ConsultService(); + $publishTypes = $consultService->getPublishTypes(); + $consult = $consultService->getConsult($id); + $this->view->setVar('publish_types', $publishTypes); $this->view->setVar('consult', $consult); } diff --git a/app/Http/Admin/Services/Question.php b/app/Http/Admin/Services/Question.php index 18bfc401..9e69c819 100644 --- a/app/Http/Admin/Services/Question.php +++ b/app/Http/Admin/Services/Question.php @@ -162,6 +162,10 @@ class Question extends Service $data['keywords'] = $validator->checkKeywords($post['keywords']); } + if (isset($post['summary'])) { + $data['summary'] = $validator->checkSummary($post['keywords']); + } + if (isset($post['anonymous'])) { $data['anonymous'] = $validator->checkAnonymousStatus($post['anonymous']); } diff --git a/app/Http/Admin/Views/answer/edit.volt b/app/Http/Admin/Views/answer/edit.volt index 9f5d83a5..3e354819 100644 --- a/app/Http/Admin/Views/answer/edit.volt +++ b/app/Http/Admin/Views/answer/edit.volt @@ -7,16 +7,27 @@ 编辑答案
-
- + +
+
{{ question.title }}
-
+ +
-
+
+ +
+ {% for value,title in publish_types %} + {% set checked = value == answer.published ? 'checked="checked"' : '' %} + + {% endfor %} +
+
+
diff --git a/app/Http/Admin/Views/article/edit_basic.volt b/app/Http/Admin/Views/article/edit_basic.volt index 1b956c39..05d12083 100644 --- a/app/Http/Admin/Views/article/edit_basic.volt +++ b/app/Http/Admin/Views/article/edit_basic.volt @@ -52,10 +52,12 @@
- +
- - + {% for value,title in publish_types %} + {% set checked = value == article.published ? 'checked="checked"' : '' %} + + {% endfor %}
@@ -66,10 +68,10 @@
- +
- - + +
diff --git a/app/Http/Admin/Views/consult/edit.volt b/app/Http/Admin/Views/consult/edit.volt index d556935b..f01813fc 100644 --- a/app/Http/Admin/Views/consult/edit.volt +++ b/app/Http/Admin/Views/consult/edit.volt @@ -18,6 +18,22 @@
+
+ +
+ {% for value,title in publish_types %} + {% set checked = value == consult.published ? 'checked="checked"' : '' %} + + {% endfor %} +
+
+
+ +
+ + +
+
diff --git a/app/Http/Admin/Views/package/edit.volt b/app/Http/Admin/Views/package/edit.volt index b23c5016..c7c97b97 100644 --- a/app/Http/Admin/Views/package/edit.volt +++ b/app/Http/Admin/Views/package/edit.volt @@ -6,12 +6,6 @@
编辑套餐
-
- -
- -
-
@@ -22,6 +16,12 @@
+
+ +
+ +
+
diff --git a/app/Http/Admin/Views/question/edit.volt b/app/Http/Admin/Views/question/edit.volt index 0b895993..0552b16c 100644 --- a/app/Http/Admin/Views/question/edit.volt +++ b/app/Http/Admin/Views/question/edit.volt @@ -2,6 +2,8 @@ {% block content %} + {% set update_url = url({'for':'admin.question.update','id':question.id}) %} +
编辑问题
@@ -9,12 +11,16 @@
  • 基本信息
  • +
  • 搜索优化
  • 内容详情
{{ partial('question/edit_basic') }}
+
+ {{ partial('question/edit_seo') }} +
{{ partial('question/edit_desc') }}
diff --git a/app/Http/Admin/Views/question/edit_basic.volt b/app/Http/Admin/Views/question/edit_basic.volt index 5517328e..9df6661f 100644 --- a/app/Http/Admin/Views/question/edit_basic.volt +++ b/app/Http/Admin/Views/question/edit_basic.volt @@ -1,4 +1,4 @@ - +
@@ -24,20 +24,23 @@
- +
- + {% for value,title in publish_types %} + {% set checked = value == question.published ? 'checked="checked"' : '' %} + + {% endfor %}
- +
- +
@@ -46,7 +49,7 @@
- +
diff --git a/app/Http/Admin/Views/question/edit_desc.volt b/app/Http/Admin/Views/question/edit_desc.volt index c6282d55..2deb0bb5 100644 --- a/app/Http/Admin/Views/question/edit_desc.volt +++ b/app/Http/Admin/Views/question/edit_desc.volt @@ -1,4 +1,4 @@ - +
diff --git a/app/Http/Admin/Views/question/edit_seo.volt b/app/Http/Admin/Views/question/edit_seo.volt new file mode 100644 index 00000000..c5c0d1b0 --- /dev/null +++ b/app/Http/Admin/Views/question/edit_seo.volt @@ -0,0 +1,21 @@ + +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ + +
+
+ \ No newline at end of file diff --git a/app/Http/Home/Controllers/CourseController.php b/app/Http/Home/Controllers/CourseController.php index 6047b3e9..48a84342 100644 --- a/app/Http/Home/Controllers/CourseController.php +++ b/app/Http/Home/Controllers/CourseController.php @@ -15,7 +15,6 @@ use App\Services\Logic\Course\CourseFavorite as CourseFavoriteService; use App\Services\Logic\Course\CourseInfo as CourseInfoService; use App\Services\Logic\Course\CourseList as CourseListService; use App\Services\Logic\Course\PackageList as CoursePackageListService; -use App\Services\Logic\Course\RecommendedList as CourseRecommendedListService; use App\Services\Logic\Course\RelatedList as CourseRelatedListService; use App\Services\Logic\Course\ResourceList as CourseResourceListService; use App\Services\Logic\Course\ReviewList as CourseReviewListService; @@ -174,19 +173,6 @@ class CourseController extends Controller $this->view->setVar('items', $items); } - /** - * @Get("/{id:[0-9]+}/recommended", name="home.course.recommended") - */ - public function recommendedAction($id) - { - $service = new CourseRecommendedListService(); - - $courses = $service->handle($id); - - $this->view->setRenderLevel(View::LEVEL_ACTION_VIEW); - $this->view->setVar('courses', $courses); - } - /** * @Get("/{id:[0-9]+}/related", name="home.course.related") */ diff --git a/app/Http/Home/Views/course/show.volt b/app/Http/Home/Views/course/show.volt index 11353557..e1051ac9 100644 --- a/app/Http/Home/Views/course/show.volt +++ b/app/Http/Home/Views/course/show.volt @@ -79,7 +79,6 @@
{% set show_sidebar_topics = 1 %} - {% set show_sidebar_recommended = 1 %} {% set show_sidebar_related = 1 %}
@@ -89,10 +88,6 @@ {% set topics_url = url({'for':'home.course.topics','id':course.id}) %} {% endif %} - {% if show_sidebar_recommended %} - {% set recommended_url = url({'for':'home.course.recommended','id':course.id}) %} - - {% endif %} {% if show_sidebar_related %} {% set related_url = url({'for':'home.course.related','id':course.id}) %} diff --git a/app/Http/Home/Views/macros/course.volt b/app/Http/Home/Views/macros/course.volt index 704a4564..94dd056b 100644 --- a/app/Http/Home/Views/macros/course.volt +++ b/app/Http/Home/Views/macros/course.volt @@ -43,25 +43,18 @@ {{ course.title }}
- {% if course.market_price > course.vip_price %} - {{ '¥%0.2f'|format(course.market_price) }} - {% if course.vip_price > 0 %} - {{ '会员¥%0.2f'|format(course.vip_price) }} - {% else %} - 会员免费 - {% endif %} - {{ level_type(course.level) }} + {% if course.market_price == 0 %} + 全员免费 + {{ course.lesson_count }}节课 + {{ course.user_count }}人报名 + {% elseif course.vip_price == 0 %} + 会员免费 + {{ course.lesson_count }}节课 {{ course.user_count }}人购买 {% elseif course.market_price > 0 %} {{ '¥%0.2f'|format(course.market_price) }} - {{ level_type(course.level) }} {{ course.lesson_count }}节课 {{ course.user_count }}人购买 - {% else %} - 免费 - {{ level_type(course.level) }} - {{ course.lesson_count }}节课 - {{ course.user_count }}人报名 {% endif %}
diff --git a/app/Http/Home/Views/partials/header.volt b/app/Http/Home/Views/partials/header.volt index b06e3480..3b8dff4f 100644 --- a/app/Http/Home/Views/partials/header.volt +++ b/app/Http/Home/Views/partials/header.volt @@ -22,17 +22,13 @@
-{% set s_type = request.get('type',['trim','string'],'course') %} -{% set s_query = request.get('query',['trim','striptags'],'') %} -{% set s_url = url({'for':'home.search.index'}) %} -
  • - 搜索 + 搜索
  • - 会员 + 会员
  • {% if auth_user.id > 0 %}
  • diff --git a/app/Http/Home/Views/search/index.volt b/app/Http/Home/Views/search/index.volt index 9ca3d0e9..59c2a956 100644 --- a/app/Http/Home/Views/search/index.volt +++ b/app/Http/Home/Views/search/index.volt @@ -8,13 +8,18 @@ {% set type = request.get('type','trim','course') %} {% set query = request.get('query','striptags','') %} - +
    +
    +
    + +
    +
    + + +
    +
    + - {% set tab_show = type %}
    @@ -50,4 +55,19 @@
    +{% endblock %} + +{% block inline_js %} + + + {% endblock %} \ No newline at end of file diff --git a/app/Http/Home/Views/user/console/favorites.volt b/app/Http/Home/Views/user/console/favorites.volt index 09db7f85..54c56715 100644 --- a/app/Http/Home/Views/user/console/favorites.volt +++ b/app/Http/Home/Views/user/console/favorites.volt @@ -2,7 +2,7 @@ {% block content %} - {% set types = {'course':'课程','article':'文章','question':'问题'} %} + {% set types = {'course':'课程','article':'专栏','question':'问题'} %} {% set type = request.get('type','trim','course') %}
    diff --git a/app/Models/Article.php b/app/Models/Article.php index 3ebfe3f7..4fac85c1 100644 --- a/app/Models/Article.php +++ b/app/Models/Article.php @@ -267,7 +267,7 @@ class Article extends Model public function afterFetch() { - if (!empty($this->cover) && !Text::startsWith($this->cover, 'http')) { + if (!Text::startsWith($this->cover, 'http')) { $this->cover = kg_cos_article_cover_url($this->cover); } diff --git a/app/Services/Logic/Article/ArticleList.php b/app/Services/Logic/Article/ArticleList.php index d34377b9..53147885 100644 --- a/app/Services/Logic/Article/ArticleList.php +++ b/app/Services/Logic/Article/ArticleList.php @@ -78,20 +78,16 @@ class ArticleList extends LogicService $items = []; - $baseUrl = kg_cos_url(); + $cosUrl = kg_cos_url(); foreach ($articles as $article) { + if (!empty($question['cover']) && !Text::startsWith($question['cover'], 'http')) { + $question['cover'] = $cosUrl . $question['cover']; + } + $article['tags'] = json_decode($article['tags'], true); - if (empty($article['cover'])) { - $article['cover'] = kg_default_article_cover_path(); - } - - if (!Text::startsWith($article['cover'], 'http')) { - $article['cover'] = $baseUrl . $article['cover']; - } - $category = $categories[$article['category_id']] ?? new \stdClass(); $owner = $users[$article['owner_id']] ?? new \stdClass(); diff --git a/app/Services/Logic/Course/RecommendedList.php b/app/Services/Logic/Course/RecommendedList.php deleted file mode 100644 index f8aa1e70..00000000 --- a/app/Services/Logic/Course/RecommendedList.php +++ /dev/null @@ -1,30 +0,0 @@ -checkCourse($id); - - $cache = new CourseRecommendedListCache(); - - $result = $cache->get($course->id); - - return $result ?: []; - } - -} diff --git a/app/Services/Logic/Deliver/CourseDeliver.php b/app/Services/Logic/Deliver/CourseDeliver.php index dbd9153e..19eec15f 100644 --- a/app/Services/Logic/Deliver/CourseDeliver.php +++ b/app/Services/Logic/Deliver/CourseDeliver.php @@ -27,10 +27,10 @@ class CourseDeliver extends LogicService protected function handleCourseUser(CourseModel $course, UserModel $user) { + $expiryTime = strtotime("+{$course->study_expiry} months"); + if ($course->model == CourseModel::MODEL_OFFLINE) { $expiryTime = strtotime($course->attrs['end_date']); - } else { - $expiryTime = strtotime("+{$course->study_expiry} months"); } $sourceType = CourseUserModel::SOURCE_CHARGE; @@ -50,8 +50,7 @@ class CourseDeliver extends LogicService foreach ($relations as $relation) { if ($relation->deleted == 0) { - $relation->deleted = 1; - $relation->update(); + $this->deleteCourseUser($relation); } } } diff --git a/app/Validators/Consult.php b/app/Validators/Consult.php index e555a588..38422bae 100644 --- a/app/Validators/Consult.php +++ b/app/Validators/Consult.php @@ -89,7 +89,7 @@ class Consult extends Validator public function checkPublishStatus($status) { - if (!in_array($status, [0, 1])) { + if (!array_key_exists($status, ConsultModel::publishTypes())) { throw new BadRequestException('consult.invalid_publish_status'); } @@ -98,18 +98,11 @@ class Consult extends Validator public function checkReplyPriv(ConsultModel $consult, UserModel $user) { - $repo = new CourseRepo(); + $courseRepo = new CourseRepo(); - $teachers = $repo->findTeachers($consult->course_id); + $course = $courseRepo->findById($consult->course_id); - $isTeacher = false; - - if ($teachers->count() > 0) { - $teacherIds = kg_array_column($teachers->toArray(), 'id'); - $isTeacher = in_array($user->id, $teacherIds); - } - - if (!$isTeacher) { + if ($course->teacher_id != $user->id) { throw new ForbiddenException('sys.forbidden'); } } diff --git a/app/Validators/Question.php b/app/Validators/Question.php index e2ccfe06..5f3d66b7 100644 --- a/app/Validators/Question.php +++ b/app/Validators/Question.php @@ -90,6 +90,19 @@ class Question extends Validator return $value; } + public function checkSummary($summary) + { + $value = $this->filter->sanitize($summary, ['trim', 'string']); + + $length = kg_strlen($value); + + if ($length > 255) { + throw new BadRequestException('question.summary_too_long'); + } + + return $value; + } + public function checkKeywords($keywords) { $keywords = $this->filter->sanitize($keywords, ['trim', 'string']); diff --git a/config/errors.php b/config/errors.php index d1c570cc..2c6283af 100644 --- a/config/errors.php +++ b/config/errors.php @@ -120,6 +120,7 @@ $error['article.not_found'] = '文章不存在'; $error['article.title_too_short'] = '标题太短(少于2个字符)'; $error['article.title_too_long'] = '标题太长(多于50个字符)'; $error['article.keyword_too_long'] = '关键字太长(多于100个字符)'; +$error['article.summary_too_long'] = '摘要太长(多于255个字符)'; $error['article.content_too_short'] = '内容太短(少于10个字符)'; $error['article.content_too_long'] = '内容太长(多于30000个字符)'; $error['article.invalid_source_type'] = '无效的来源类型'; @@ -138,6 +139,7 @@ $error['question.not_found'] = '问题不存在'; $error['question.title_too_short'] = '标题太短(少于5个字符)'; $error['question.title_too_long'] = '标题太长(多于50个字符)'; $error['question.keyword_too_long'] = '关键字太长(多于100个字符)'; +$error['question.summary_too_long'] = '摘要太长(多于255个字符)'; $error['question.content_too_short'] = '内容太短(少于10个字符)'; $error['question.content_too_long'] = '内容太长(多于30000个字符)'; $error['question.invalid_publish_status'] = '无效的发布状态'; diff --git a/public/static/home/css/common.css b/public/static/home/css/common.css index 7012fd2e..231bcd9a 100644 --- a/public/static/home/css/common.css +++ b/public/static/home/css/common.css @@ -330,6 +330,10 @@ height: 100%; } +.query-input { + width: 720px; +} + .search-tab { margin: 0; } diff --git a/public/static/home/js/article.edit.js b/public/static/home/js/article.edit.js index 23207122..65523688 100644 --- a/public/static/home/js/article.edit.js +++ b/public/static/home/js/article.edit.js @@ -1,23 +1,7 @@ -layui.use(['jquery', 'form', 'layer'], function () { +layui.use(['jquery', 'form'], function () { var $ = layui.jquery; var form = layui.form; - var layer = layui.layer; - - $('.publish').on('click', function () { - var layerWidth = 360; - var layerTop = $(this).offset().top + $(this).height() + 5 + 'px'; - var layerLeft = ($(this).offset().left + $(this).width() - layerWidth) + 'px'; - layer.open({ - type: 1, - title: false, - closeBtn: false, - shadeClose: true, - content: $('#layer-publish'), - offset: [layerTop, layerLeft], - area: layerWidth + 'px', - }); - }); form.on('select(source_type)', function (data) { var block = $('#source-url-block'); @@ -35,8 +19,6 @@ layui.use(['jquery', 'form', 'layer'], function () { name: 'xm_tag_ids', max: 3, data: xmTags, - layVerify: 'required', - layVerType: 'msg', autoRow: true, filterable: true, filterMethod: function (val, item, index, prop) { diff --git a/public/static/home/js/common.js b/public/static/home/js/common.js index a5df2cba..3d379ed9 100644 --- a/public/static/home/js/common.js +++ b/public/static/home/js/common.js @@ -102,7 +102,6 @@ layui.use(['jquery', 'form', 'element', 'layer', 'helper'], function () { $('.nav-search').on('click', function () { var content = '
    '; content += ''; - content += ''; content += ''; layer.open({ type: 1, diff --git a/public/static/home/js/course.show.js b/public/static/home/js/course.show.js index ae7ae753..9604de82 100644 --- a/public/static/home/js/course.show.js +++ b/public/static/home/js/course.show.js @@ -145,11 +145,6 @@ layui.use(['jquery', 'layer', 'helper'], function () { helper.ajaxLoadHtml($sdTopics.data('url'), $sdTopics.attr('id')); } - if ($('#sidebar-recommended').length > 0) { - var $sdRecommended = $('#sidebar-recommended'); - helper.ajaxLoadHtml($sdRecommended.data('url'), $sdRecommended.attr('id')); - } - if ($('#sidebar-related').length > 0) { var $sdRelated = $('#sidebar-related'); helper.ajaxLoadHtml($sdRelated.data('url'), $sdRelated.attr('id')); diff --git a/public/static/home/js/question.edit.js b/public/static/home/js/question.edit.js index 99bf6d10..b627ece8 100644 --- a/public/static/home/js/question.edit.js +++ b/public/static/home/js/question.edit.js @@ -1,22 +1,7 @@ -layui.use(['jquery', 'form', 'layer'], function () { +layui.use(['jquery'], function () { var $ = layui.jquery; - $('.publish').on('click', function () { - var layerWidth = 360; - var layerTop = $(this).offset().top + $(this).height() + 5 + 'px'; - var layerLeft = ($(this).offset().left + $(this).width() - layerWidth) + 'px'; - layer.open({ - type: 1, - title: false, - closeBtn: false, - shadeClose: true, - content: $('#layer-publish'), - offset: [layerTop, layerLeft], - area: [layerWidth + 'px', '360px'], - }); - }); - var xmTags = JSON.parse($('input[name=xm_tags]').val()); xmSelect.render({ @@ -24,8 +9,6 @@ layui.use(['jquery', 'form', 'layer'], function () { name: 'xm_tag_ids', max: 3, data: xmTags, - layVerify: 'required', - layVerType: 'msg', autoRow: true, filterable: true, filterMethod: function (val, item, index, prop) { From 435bc12035ca34ad9964c9f8a9e63de530fa53b0 Mon Sep 17 00:00:00 2001 From: xiaochong0302 Date: Mon, 11 Dec 2023 12:23:42 +0800 Subject: [PATCH 15/21] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E6=8E=A8=E8=8D=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Caches/FeaturedArticleList.php | 2 +- app/Caches/FeaturedCourseList.php | 2 +- app/Caches/FeaturedQuestionList.php | 74 +++++++++++++++++++ app/Http/Admin/Services/Question.php | 4 + app/Http/Admin/Views/question/edit_basic.volt | 6 +- app/Http/Admin/Views/question/list.volt | 4 + app/Http/Admin/Views/question/search.volt | 6 +- app/Http/Home/Views/search/index.volt | 4 +- .../Home/Views/widget/featured_articles.volt | 2 +- .../Home/Views/widget/featured_questions.volt | 20 +++++ app/Models/Question.php | 10 ++- app/Repos/Question.php | 40 +++++----- app/Services/Logic/Article/ArticleList.php | 4 +- app/Validators/Question.php | 10 ++- db/migrations/20231108085025.php | 19 +++++ public/static/home/css/common.css | 8 +- 16 files changed, 180 insertions(+), 35 deletions(-) create mode 100644 app/Caches/FeaturedQuestionList.php create mode 100644 app/Http/Home/Views/widget/featured_questions.volt diff --git a/app/Caches/FeaturedArticleList.php b/app/Caches/FeaturedArticleList.php index bd5fc0f2..61d718e2 100644 --- a/app/Caches/FeaturedArticleList.php +++ b/app/Caches/FeaturedArticleList.php @@ -75,7 +75,7 @@ class FeaturedArticleList extends Cache ->where('featured = 1') ->andWhere('published = 1') ->andWhere('deleted = 0') - ->orderBy('id DESC') + ->orderBy('RAND()') ->limit($limit) ->execute(); } diff --git a/app/Caches/FeaturedCourseList.php b/app/Caches/FeaturedCourseList.php index cb2817a8..8243ce1d 100644 --- a/app/Caches/FeaturedCourseList.php +++ b/app/Caches/FeaturedCourseList.php @@ -77,7 +77,7 @@ class FeaturedCourseList extends Cache ->where('featured = 1') ->andWhere('published = 1') ->andWhere('deleted = 0') - ->orderBy('id DESC') + ->orderBy('RAND()') ->limit($limit) ->execute(); } diff --git a/app/Caches/FeaturedQuestionList.php b/app/Caches/FeaturedQuestionList.php new file mode 100644 index 00000000..bbb599fb --- /dev/null +++ b/app/Caches/FeaturedQuestionList.php @@ -0,0 +1,74 @@ +findQuestions($limit); + + if ($questions->count() == 0) { + return []; + } + + $result = []; + + foreach ($questions as $question) { + + $result[] = [ + 'id' => $question->id, + 'title' => $question->title, + 'cover' => $question->cover, + 'favorite_count' => $question->favorite_count, + 'answer_count' => $question->answer_count, + 'view_count' => $question->view_count, + 'like_count' => $question->like_count, + ]; + } + + return $result; + } + + /** + * @param int $limit + * @return ResultsetInterface|Resultset|QuestionModel[] + */ + protected function findQuestions($limit = 5) + { + return QuestionModel::query() + ->where('featured = 1') + ->andWhere('published = 1') + ->andWhere('deleted = 0') + ->orderBy('RAND()') + ->limit($limit) + ->execute(); + } + +} diff --git a/app/Http/Admin/Services/Question.php b/app/Http/Admin/Services/Question.php index 9e69c819..e17a687d 100644 --- a/app/Http/Admin/Services/Question.php +++ b/app/Http/Admin/Services/Question.php @@ -170,6 +170,10 @@ class Question extends Service $data['anonymous'] = $validator->checkAnonymousStatus($post['anonymous']); } + if (isset($post['featured'])) { + $data['featured'] = $validator->checkFeatureStatus($post['featured']); + } + if (isset($post['closed'])) { $data['closed'] = $validator->checkCloseStatus($post['closed']); } diff --git a/app/Http/Admin/Views/question/edit_basic.volt b/app/Http/Admin/Views/question/edit_basic.volt index 9df6661f..af731d39 100644 --- a/app/Http/Admin/Views/question/edit_basic.volt +++ b/app/Http/Admin/Views/question/edit_basic.volt @@ -33,10 +33,10 @@
    - +
    - - + +
    diff --git a/app/Http/Admin/Views/question/list.volt b/app/Http/Admin/Views/question/list.volt index 25190239..f5efc030 100644 --- a/app/Http/Admin/Views/question/list.volt +++ b/app/Http/Admin/Views/question/list.volt @@ -37,6 +37,7 @@
+ @@ -46,6 +47,7 @@ + @@ -87,6 +89,8 @@

+
内容优先级 时间 操作
{{ priority_info(item.priority) }} {{ date('Y-m-d',item.create_time) }} diff --git a/app/Http/Home/Views/teacher/console/courses.volt b/app/Http/Home/Views/teacher/console/courses.volt index ac6f76ee..368f5c1f 100644 --- a/app/Http/Home/Views/teacher/console/courses.volt +++ b/app/Http/Home/Views/teacher/console/courses.volt @@ -18,14 +18,12 @@
名称课时标题类型 学员收藏 评分
{{ item.title }} {{ model_type(item.model) }}{{ item.lesson_count }}{{ item.title }}{{ model_type(item.model) }} {{ item.user_count }}{{ item.favorite_count }} {{ "%0.1f"|format(item.rating) }}
问题信息 统计信息 状态推荐 关闭 操作
{{ publish_status(item.published) }} diff --git a/app/Http/Admin/Views/question/search.volt b/app/Http/Admin/Views/question/search.volt index b03e952c..cf5a92fc 100644 --- a/app/Http/Admin/Views/question/search.volt +++ b/app/Http/Admin/Views/question/search.volt @@ -54,10 +54,10 @@
- +
- - + +
diff --git a/app/Http/Home/Views/search/index.volt b/app/Http/Home/Views/search/index.volt index 59c2a956..0533bb49 100644 --- a/app/Http/Home/Views/search/index.volt +++ b/app/Http/Home/Views/search/index.volt @@ -8,13 +8,13 @@ {% set type = request.get('type','trim','course') %} {% set query = request.get('query','striptags','') %} -
+
- +
diff --git a/app/Http/Home/Views/widget/featured_articles.volt b/app/Http/Home/Views/widget/featured_articles.volt index 18a2e213..a3486b21 100644 --- a/app/Http/Home/Views/widget/featured_articles.volt +++ b/app/Http/Home/Views/widget/featured_articles.volt @@ -5,7 +5,7 @@
{% for article in articles %} {% set article_url = url({'for':'home.article.show','id':article.id}) %} -
+
diff --git a/app/Http/Home/Views/widget/featured_questions.volt b/app/Http/Home/Views/widget/featured_questions.volt new file mode 100644 index 00000000..4aad80ce --- /dev/null +++ b/app/Http/Home/Views/widget/featured_questions.volt @@ -0,0 +1,20 @@ +{% if questions|length > 0 %} +
+
推荐问题
+
+ +
+
+{% endif %} \ No newline at end of file diff --git a/app/Models/Question.php b/app/Models/Question.php index c06d35a3..c6f3d809 100644 --- a/app/Models/Question.php +++ b/app/Models/Question.php @@ -149,6 +149,13 @@ class Question extends Model */ public $published = self::PUBLISH_PENDING; + /** + * 推荐标识 + * + * @var integer + */ + public $featured = 0; + /** * 删除标识 * @@ -318,9 +325,10 @@ class Question extends Model public static function sortTypes() { return [ - 'latest' => '最新提问', + 'latest' => '最新问题', 'active' => '最新回答', 'unanswered' => '尚未回答', + 'featured' => '推荐问题', ]; } diff --git a/app/Repos/Question.php b/app/Repos/Question.php index 8b874716..8db156ad 100644 --- a/app/Repos/Question.php +++ b/app/Repos/Question.php @@ -58,6 +58,20 @@ class Question extends Repository } } + if (!empty($where['published'])) { + if (is_array($where['published'])) { + $builder->inWhere('published', $where['published']); + } else { + $builder->andWhere('published = :published:', ['published' => $where['published']]); + } + } + + if (!empty($where['create_time'][0]) && !empty($where['create_time'][1])) { + $startTime = strtotime($where['create_time'][0]); + $endTime = strtotime($where['create_time'][1]); + $builder->betweenWhere('create_time', $startTime, $endTime); + } + if (!empty($where['owner_id'])) { $builder->andWhere('owner_id = :owner_id:', ['owner_id' => $where['owner_id']]); } @@ -74,33 +88,23 @@ class Question extends Repository $builder->andWhere('closed = :closed:', ['closed' => $where['closed']]); } + if (isset($where['featured'])) { + $builder->andWhere('featured = :featured:', ['featured' => $where['featured']]); + } + if (isset($where['solved'])) { $builder->andWhere('solved = :solved:', ['solved' => $where['solved']]); } - if (!empty($where['published'])) { - if (is_array($where['published'])) { - $builder->inWhere('published', $where['published']); - } else { - $builder->andWhere('published = :published:', ['published' => $where['published']]); - } - } - - if (!empty($where['create_time'][0]) && !empty($where['create_time'][1])) { - $startTime = strtotime($where['create_time'][0]); - $endTime = strtotime($where['create_time'][1]); - $builder->betweenWhere('create_time', $startTime, $endTime); - } - if (isset($where['deleted'])) { $builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]); } - if ($sort == 'unanswered') { + if ($sort == 'featured') { + $builder->andWhere('featured = 1'); + } elseif ($sort == 'unanswered') { $builder->andWhere('answer_count = 0'); - } - - if ($sort == 'reported') { + } elseif ($sort == 'reported') { $builder->andWhere('report_count > 0'); } diff --git a/app/Services/Logic/Article/ArticleList.php b/app/Services/Logic/Article/ArticleList.php index 53147885..d04b53e2 100644 --- a/app/Services/Logic/Article/ArticleList.php +++ b/app/Services/Logic/Article/ArticleList.php @@ -82,8 +82,8 @@ class ArticleList extends LogicService foreach ($articles as $article) { - if (!empty($question['cover']) && !Text::startsWith($question['cover'], 'http')) { - $question['cover'] = $cosUrl . $question['cover']; + if (!empty($article['cover']) && !Text::startsWith($article['cover'], 'http')) { + $article['cover'] = $cosUrl . $article['cover']; } $article['tags'] = json_decode($article['tags'], true); diff --git a/app/Validators/Question.php b/app/Validators/Question.php index 5f3d66b7..28ac33ad 100644 --- a/app/Validators/Question.php +++ b/app/Validators/Question.php @@ -11,7 +11,6 @@ use App\Caches\MaxQuestionId as MaxQuestionIdCache; use App\Caches\Question as QuestionCache; use App\Exceptions\BadRequest as BadRequestException; use App\Models\Question as QuestionModel; -use App\Models\Reason as ReasonModel; use App\Repos\Question as QuestionRepo; use App\Services\EditorStorage as EditorStorageService; @@ -151,6 +150,15 @@ class Question extends Validator return $status; } + public function checkFeatureStatus($status) + { + if (!in_array($status, [0, 1])) { + throw new BadRequestException('question.invalid_feature_status'); + } + + return $status; + } + public function checkCloseStatus($status) { if (!in_array($status, [0, 1])) { diff --git a/db/migrations/20231108085025.php b/db/migrations/20231108085025.php index 557e4c74..771a8111 100644 --- a/db/migrations/20231108085025.php +++ b/db/migrations/20231108085025.php @@ -14,6 +14,7 @@ final class V20231108085025 extends AbstractMigration public function up() { $this->alterVipTable(); + $this->alterQuestionTable(); $this->alterArticleTable(); $this->alterConsultTable(); $this->alterResourceTable(); @@ -45,6 +46,24 @@ final class V20231108085025 extends AbstractMigration $table->save(); } + protected function alterQuestionTable() + { + $table = $this->table('kg_question'); + + if (!$table->hasColumn('featured')) { + $table->addColumn('featured', 'integer', [ + 'null' => false, + 'default' => '0', + 'limit' => MysqlAdapter::INT_REGULAR, + 'signed' => false, + 'comment' => '推荐标识', + 'after' => 'published', + ]); + } + + $table->save(); + } + protected function alterArticleTable() { $table = $this->table('kg_article'); diff --git a/public/static/home/css/common.css b/public/static/home/css/common.css index 231bcd9a..e8ca5767 100644 --- a/public/static/home/css/common.css +++ b/public/static/home/css/common.css @@ -330,8 +330,12 @@ height: 100%; } -.query-input { - width: 720px; +.search-form .query-input { + width: 696px; +} + +.search-form .search-btn { + padding: 0 30px; } .search-tab { From c859deec44d4b7be9241b54411b42d56e22d6e57 Mon Sep 17 00:00:00 2001 From: xiaochong0302 Date: Mon, 11 Dec 2023 12:38:47 +0800 Subject: [PATCH 16/21] vip.js -> vip.index.js --- .../Home/Controllers/WidgetController.php | 15 ++++++++++ app/Http/Home/Views/search/index.volt | 13 ++------- app/Http/Home/Views/search/sidebar.volt | 11 ++++++++ app/Http/Home/Views/vip/index.volt | 2 +- .../Home/Views/widget/featured_questions.volt | 4 +-- public/static/home/js/search.index.js | 28 +++++++++++++++++++ .../static/home/js/{vip.js => vip.index.js} | 0 7 files changed, 59 insertions(+), 14 deletions(-) create mode 100644 public/static/home/js/search.index.js rename public/static/home/js/{vip.js => vip.index.js} (100%) diff --git a/app/Http/Home/Controllers/WidgetController.php b/app/Http/Home/Controllers/WidgetController.php index 1d558745..f7dd3843 100644 --- a/app/Http/Home/Controllers/WidgetController.php +++ b/app/Http/Home/Controllers/WidgetController.php @@ -9,6 +9,7 @@ namespace App\Http\Home\Controllers; use App\Caches\FeaturedArticleList as FeaturedArticleListCache; use App\Caches\FeaturedCourseList as FeaturedCourseListCache; +use App\Caches\FeaturedQuestionList as FeaturedQuestionListCache; use App\Services\Logic\Article\TopAuthorList as TopAuthorListService; use App\Services\Logic\Question\HotQuestionList as HotQuestionListService; use App\Services\Logic\Question\TopAnswererList as TopAnswererListService; @@ -63,6 +64,20 @@ class WidgetController extends Controller $this->view->setVar('articles', $articles); } + /** + * @Get("/featured/questions", name="home.widget.featured_questions") + */ + public function featuredQuestionsAction() + { + $cache = new FeaturedQuestionListCache(); + + $questions = $cache->get(); + + $this->view->setRenderLevel(View::LEVEL_ACTION_VIEW); + $this->view->pick('widget/featured_questions'); + $this->view->setVar('questions', $questions); + } + /** * @Get("/hot/questions", name="home.widget.hot_questions") */ diff --git a/app/Http/Home/Views/search/index.volt b/app/Http/Home/Views/search/index.volt index 0533bb49..7532e58c 100644 --- a/app/Http/Home/Views/search/index.volt +++ b/app/Http/Home/Views/search/index.volt @@ -57,17 +57,8 @@ {% endblock %} -{% block inline_js %} +{% block include_js %} - + {{ js_include('home/js/search.index.js') }} {% endblock %} \ No newline at end of file diff --git a/app/Http/Home/Views/search/sidebar.volt b/app/Http/Home/Views/search/sidebar.volt index d5083cdb..9d23d64f 100644 --- a/app/Http/Home/Views/search/sidebar.volt +++ b/app/Http/Home/Views/search/sidebar.volt @@ -10,6 +10,17 @@
{% endif %} +{% if type == 'course' %} + {% set load_url = url({'for':'home.widget.featured_courses'}) %} + +{% elseif type == 'article' %} + {% set load_url = url({'for':'home.widget.featured_articles'}) %} +
+{% elseif type == 'question' %} + {% set load_url = url({'for':'home.widget.featured_questions'}) %} + +{% endif %} + {% if related_queries %}
相关搜索
diff --git a/app/Http/Home/Views/vip/index.volt b/app/Http/Home/Views/vip/index.volt index be178f65..e7fe11d7 100644 --- a/app/Http/Home/Views/vip/index.volt +++ b/app/Http/Home/Views/vip/index.volt @@ -55,6 +55,6 @@ {% block include_js %} - {{ js_include('home/js/vip.js') }} + {{ js_include('home/js/vip.index.js') }} {% endblock %} \ No newline at end of file diff --git a/app/Http/Home/Views/widget/featured_questions.volt b/app/Http/Home/Views/widget/featured_questions.volt index 4aad80ce..ca4a2d0b 100644 --- a/app/Http/Home/Views/widget/featured_questions.volt +++ b/app/Http/Home/Views/widget/featured_questions.volt @@ -2,7 +2,7 @@
推荐问题
- -
- -
- - -
-
From e0da7b71b3f8e332e60c3554149524a3c07d6cb6 Mon Sep 17 00:00:00 2001 From: xiaochong0302 Date: Tue, 12 Dec 2023 16:19:04 +0800 Subject: [PATCH 18/21] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=86=85=E5=AE=B9?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Caches/CourseCategoryList.php | 59 ------------------ app/Caches/CourseTeacherList.php | 63 -------------------- app/Caches/FeaturedArticleList.php | 8 +-- app/Caches/FeaturedCourseList.php | 6 +- app/Caches/FeaturedQuestionList.php | 6 +- app/Caches/HelpList.php | 2 +- app/Caches/HotQuestionList.php | 6 +- app/Caches/IndexArticleList.php | 2 +- app/Caches/IndexFeaturedCourseList.php | 2 +- app/Caches/IndexFreeCourseList.php | 2 +- app/Caches/IndexLiveList.php | 2 +- app/Caches/IndexNewCourseList.php | 2 +- app/Caches/IndexQuestionList.php | 2 +- app/Caches/IndexSimpleFeaturedCourseList.php | 2 +- app/Caches/IndexSimpleFreeCourseList.php | 2 +- app/Caches/IndexSimpleNewCourseList.php | 2 +- app/Caches/IndexSimpleVipCourseList.php | 2 +- app/Caches/IndexSlideList.php | 2 +- app/Caches/IndexVipCourseList.php | 2 +- app/Caches/TaggedArticleList.php | 2 +- app/Caches/TaggedQuestionList.php | 2 +- app/Caches/TopAnswererList.php | 2 +- app/Caches/TopAuthorList.php | 2 +- app/Services/Logic/Course/TeacherList.php | 30 ---------- 24 files changed, 29 insertions(+), 183 deletions(-) delete mode 100644 app/Caches/CourseCategoryList.php delete mode 100644 app/Caches/CourseTeacherList.php delete mode 100644 app/Services/Logic/Course/TeacherList.php diff --git a/app/Caches/CourseCategoryList.php b/app/Caches/CourseCategoryList.php deleted file mode 100644 index 12681a06..00000000 --- a/app/Caches/CourseCategoryList.php +++ /dev/null @@ -1,59 +0,0 @@ -lifetime; - } - - public function getKey($id = null) - { - return "course_category_list:{$id}"; - } - - public function getContent($id = null) - { - $courseRepo = new CourseRepo(); - - $categories = $courseRepo->findCategories($id); - - if ($categories->count() == 0) { - return []; - } - - return $this->handleContent($categories); - } - - /** - * @param CategoryModel[] $categories - * @return array - */ - public function handleContent($categories) - { - $result = []; - - foreach ($categories as $category) { - $result[] = [ - 'id' => $category->id, - 'name' => $category->name, - ]; - } - - return $result; - } - -} diff --git a/app/Caches/CourseTeacherList.php b/app/Caches/CourseTeacherList.php deleted file mode 100644 index 1c676f1a..00000000 --- a/app/Caches/CourseTeacherList.php +++ /dev/null @@ -1,63 +0,0 @@ -lifetime; - } - - public function getKey($id = null) - { - return "course_teacher_list:{$id}"; - } - - public function getContent($id = null) - { - $courseRepo = new CourseRepo(); - - $users = $courseRepo->findTeachers($id); - - if ($users->count() == 0) { - return []; - } - - return $this->handleContent($users); - } - - /** - * @param UserModel[] $users - * @return array - */ - public function handleContent($users) - { - $result = []; - - foreach ($users as $user) { - $result[] = [ - 'id' => $user->id, - 'name' => $user->name, - 'avatar' => $user->avatar, - 'vip' => $user->vip, - 'title' => $user->title, - 'about' => $user->about, - ]; - } - - return $result; - } - -} diff --git a/app/Caches/FeaturedArticleList.php b/app/Caches/FeaturedArticleList.php index 86507ebe..7f1d7640 100644 --- a/app/Caches/FeaturedArticleList.php +++ b/app/Caches/FeaturedArticleList.php @@ -16,6 +16,8 @@ class FeaturedArticleList extends Cache protected $lifetime = 3600; + protected $limit = 5; + public function getLifetime() { return $this->lifetime; @@ -28,9 +30,7 @@ class FeaturedArticleList extends Cache public function getContent($id = null) { - $limit = 8; - - $articles = $this->findArticles($limit); + $articles = $this->findArticles($this->limit); if ($articles->count() == 0) { return []; @@ -67,7 +67,7 @@ class FeaturedArticleList extends Cache * @param int $limit * @return ResultsetInterface|Resultset|ArticleModel[] */ - protected function findArticles($limit = 8) + protected function findArticles($limit = 5) { return ArticleModel::query() ->where('featured = 1') diff --git a/app/Caches/FeaturedCourseList.php b/app/Caches/FeaturedCourseList.php index c5c05c58..d9b26459 100644 --- a/app/Caches/FeaturedCourseList.php +++ b/app/Caches/FeaturedCourseList.php @@ -16,6 +16,8 @@ class FeaturedCourseList extends Cache protected $lifetime = 3600; + protected $limit = 5; + public function getLifetime() { return $this->lifetime; @@ -28,9 +30,7 @@ class FeaturedCourseList extends Cache public function getContent($id = null) { - $limit = 5; - - $courses = $this->findCourses($limit); + $courses = $this->findCourses($this->limit); if ($courses->count() == 0) { return []; diff --git a/app/Caches/FeaturedQuestionList.php b/app/Caches/FeaturedQuestionList.php index 9a64b958..07ee392c 100644 --- a/app/Caches/FeaturedQuestionList.php +++ b/app/Caches/FeaturedQuestionList.php @@ -16,6 +16,8 @@ class FeaturedQuestionList extends Cache protected $lifetime = 3600; + protected $limit = 5; + public function getLifetime() { return $this->lifetime; @@ -28,9 +30,7 @@ class FeaturedQuestionList extends Cache public function getContent($id = null) { - $limit = 5; - - $questions = $this->findQuestions($limit); + $questions = $this->findQuestions($this->limit); if ($questions->count() == 0) { return []; diff --git a/app/Caches/HelpList.php b/app/Caches/HelpList.php index 2899bbd8..5c30bea4 100644 --- a/app/Caches/HelpList.php +++ b/app/Caches/HelpList.php @@ -15,7 +15,7 @@ use Phalcon\Mvc\Model\ResultsetInterface; class HelpList extends Cache { - protected $lifetime = 365 * 86400; + protected $lifetime = 7 * 86400; public function getLifetime() { diff --git a/app/Caches/HotQuestionList.php b/app/Caches/HotQuestionList.php index 64220fd8..3afbec0b 100644 --- a/app/Caches/HotQuestionList.php +++ b/app/Caches/HotQuestionList.php @@ -14,13 +14,11 @@ use Phalcon\Mvc\Model\ResultsetInterface; class HotQuestionList extends Cache { - protected $lifetime = 86400; + protected $lifetime = 3600; public function getLifetime() { - $tomorrow = strtotime('tomorrow'); - - return $tomorrow - time(); + return $this->lifetime; } public function getKey($id = null) diff --git a/app/Caches/IndexArticleList.php b/app/Caches/IndexArticleList.php index c892923f..43075b7c 100644 --- a/app/Caches/IndexArticleList.php +++ b/app/Caches/IndexArticleList.php @@ -14,7 +14,7 @@ use App\Services\Logic\Article\ArticleList as ArticleListService; class IndexArticleList extends Cache { - protected $lifetime = 15 * 60; + protected $lifetime = 3600; public function getLifetime() { diff --git a/app/Caches/IndexFeaturedCourseList.php b/app/Caches/IndexFeaturedCourseList.php index f7d0e6ae..77bb347b 100644 --- a/app/Caches/IndexFeaturedCourseList.php +++ b/app/Caches/IndexFeaturedCourseList.php @@ -19,7 +19,7 @@ use Phalcon\Mvc\Model\ResultsetInterface; class IndexFeaturedCourseList extends Cache { - protected $lifetime = 86400; + protected $lifetime = 3600; public function getLifetime() { diff --git a/app/Caches/IndexFreeCourseList.php b/app/Caches/IndexFreeCourseList.php index bc20a9dc..9ae4226c 100644 --- a/app/Caches/IndexFreeCourseList.php +++ b/app/Caches/IndexFreeCourseList.php @@ -19,7 +19,7 @@ use Phalcon\Mvc\Model\ResultsetInterface; class IndexFreeCourseList extends Cache { - protected $lifetime = 86400; + protected $lifetime = 3600; public function getLifetime() { diff --git a/app/Caches/IndexLiveList.php b/app/Caches/IndexLiveList.php index 734150a1..ae3dff4e 100644 --- a/app/Caches/IndexLiveList.php +++ b/app/Caches/IndexLiveList.php @@ -18,7 +18,7 @@ use Phalcon\Mvc\Model\ResultsetInterface; class IndexLiveList extends Cache { - protected $lifetime = 86400; + protected $lifetime = 3600; public function getLifetime() { diff --git a/app/Caches/IndexNewCourseList.php b/app/Caches/IndexNewCourseList.php index 4975cb27..457eb8ce 100644 --- a/app/Caches/IndexNewCourseList.php +++ b/app/Caches/IndexNewCourseList.php @@ -19,7 +19,7 @@ use Phalcon\Mvc\Model\ResultsetInterface; class IndexNewCourseList extends Cache { - protected $lifetime = 86400; + protected $lifetime = 3600; public function getLifetime() { diff --git a/app/Caches/IndexQuestionList.php b/app/Caches/IndexQuestionList.php index b79db98b..12bb02c1 100644 --- a/app/Caches/IndexQuestionList.php +++ b/app/Caches/IndexQuestionList.php @@ -14,7 +14,7 @@ use App\Services\Logic\Question\QuestionList as QuestionListService; class IndexQuestionList extends Cache { - protected $lifetime = 15 * 60; + protected $lifetime = 3600; public function getLifetime() { diff --git a/app/Caches/IndexSimpleFeaturedCourseList.php b/app/Caches/IndexSimpleFeaturedCourseList.php index b5433216..616a37bd 100644 --- a/app/Caches/IndexSimpleFeaturedCourseList.php +++ b/app/Caches/IndexSimpleFeaturedCourseList.php @@ -17,7 +17,7 @@ use Phalcon\Mvc\Model\ResultsetInterface; class IndexSimpleFeaturedCourseList extends Cache { - protected $lifetime = 86400; + protected $lifetime = 3600; public function getLifetime() { diff --git a/app/Caches/IndexSimpleFreeCourseList.php b/app/Caches/IndexSimpleFreeCourseList.php index 34a6d4f7..16b0e64f 100644 --- a/app/Caches/IndexSimpleFreeCourseList.php +++ b/app/Caches/IndexSimpleFreeCourseList.php @@ -17,7 +17,7 @@ use Phalcon\Mvc\Model\ResultsetInterface; class IndexSimpleFreeCourseList extends Cache { - protected $lifetime = 86400; + protected $lifetime = 3600; public function getLifetime() { diff --git a/app/Caches/IndexSimpleNewCourseList.php b/app/Caches/IndexSimpleNewCourseList.php index 7dffa5af..9dbd225c 100644 --- a/app/Caches/IndexSimpleNewCourseList.php +++ b/app/Caches/IndexSimpleNewCourseList.php @@ -17,7 +17,7 @@ use Phalcon\Mvc\Model\ResultsetInterface; class IndexSimpleNewCourseList extends Cache { - protected $lifetime = 86400; + protected $lifetime = 3600; public function getLifetime() { diff --git a/app/Caches/IndexSimpleVipCourseList.php b/app/Caches/IndexSimpleVipCourseList.php index 6756b39e..90f8b493 100644 --- a/app/Caches/IndexSimpleVipCourseList.php +++ b/app/Caches/IndexSimpleVipCourseList.php @@ -17,7 +17,7 @@ use Phalcon\Mvc\Model\ResultsetInterface; class IndexSimpleVipCourseList extends Cache { - protected $lifetime = 86400; + protected $lifetime = 3600; public function getLifetime() { diff --git a/app/Caches/IndexSlideList.php b/app/Caches/IndexSlideList.php index abc7d28c..00f15ae1 100644 --- a/app/Caches/IndexSlideList.php +++ b/app/Caches/IndexSlideList.php @@ -14,7 +14,7 @@ use Phalcon\Mvc\Model\ResultsetInterface; class IndexSlideList extends Cache { - protected $lifetime = 365 * 86400; + protected $lifetime = 3600; public function getLifetime() { diff --git a/app/Caches/IndexVipCourseList.php b/app/Caches/IndexVipCourseList.php index 6b268160..e11ce1b2 100644 --- a/app/Caches/IndexVipCourseList.php +++ b/app/Caches/IndexVipCourseList.php @@ -19,7 +19,7 @@ use Phalcon\Mvc\Model\ResultsetInterface; class IndexVipCourseList extends Cache { - protected $lifetime = 86400; + protected $lifetime = 3600; public function getLifetime() { diff --git a/app/Caches/TaggedArticleList.php b/app/Caches/TaggedArticleList.php index d57faf7b..1c5c6df0 100644 --- a/app/Caches/TaggedArticleList.php +++ b/app/Caches/TaggedArticleList.php @@ -15,7 +15,7 @@ class TaggedArticleList extends Cache protected $limit = 5; - protected $lifetime = 86400; + protected $lifetime = 3600; public function getLifetime() { diff --git a/app/Caches/TaggedQuestionList.php b/app/Caches/TaggedQuestionList.php index 7495823b..f76a5b29 100644 --- a/app/Caches/TaggedQuestionList.php +++ b/app/Caches/TaggedQuestionList.php @@ -15,7 +15,7 @@ class TaggedQuestionList extends Cache protected $limit = 5; - protected $lifetime = 86400; + protected $lifetime = 3600; public function getLifetime() { diff --git a/app/Caches/TopAnswererList.php b/app/Caches/TopAnswererList.php index 37991604..4acaa8e7 100644 --- a/app/Caches/TopAnswererList.php +++ b/app/Caches/TopAnswererList.php @@ -16,7 +16,7 @@ use Phalcon\Mvc\Model\ResultsetInterface; class TopAnswererList extends Cache { - protected $lifetime = 86400; + protected $lifetime = 3600; public function getLifetime() { diff --git a/app/Caches/TopAuthorList.php b/app/Caches/TopAuthorList.php index 882e4cab..1e6a2404 100644 --- a/app/Caches/TopAuthorList.php +++ b/app/Caches/TopAuthorList.php @@ -16,7 +16,7 @@ use Phalcon\Mvc\Model\ResultsetInterface; class TopAuthorList extends Cache { - protected $lifetime = 86400; + protected $lifetime = 3600; public function getLifetime() { diff --git a/app/Services/Logic/Course/TeacherList.php b/app/Services/Logic/Course/TeacherList.php deleted file mode 100644 index c40e5d48..00000000 --- a/app/Services/Logic/Course/TeacherList.php +++ /dev/null @@ -1,30 +0,0 @@ -checkCourse($id); - - $cache = new CourseTeacherListCache(); - - $result = $cache->get($course->id); - - return $result ?: []; - } - -} From b192760deb49a930acdd0e0a88bfe3a06b71cad8 Mon Sep 17 00:00:00 2001 From: xiaochong0302 Date: Tue, 12 Dec 2023 17:18:24 +0800 Subject: [PATCH 19/21] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E6=96=87=E7=AB=A0=E5=92=8C=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Caches/TaggedArticleList.php | 2 +- app/Caches/TaggedQuestionList.php | 2 +- app/Http/Admin/Views/public/login.volt | 4 ++-- .../Logic/Article/RelatedArticleList.php | 22 ++++++++++++++----- .../Logic/Question/RelatedQuestionList.php | 22 ++++++++++++++----- 5 files changed, 38 insertions(+), 14 deletions(-) diff --git a/app/Caches/TaggedArticleList.php b/app/Caches/TaggedArticleList.php index 1c5c6df0..05640fff 100644 --- a/app/Caches/TaggedArticleList.php +++ b/app/Caches/TaggedArticleList.php @@ -13,7 +13,7 @@ use App\Repos\Article as ArticleRepo; class TaggedArticleList extends Cache { - protected $limit = 5; + protected $limit = 15; protected $lifetime = 3600; diff --git a/app/Caches/TaggedQuestionList.php b/app/Caches/TaggedQuestionList.php index f76a5b29..f6adb8b4 100644 --- a/app/Caches/TaggedQuestionList.php +++ b/app/Caches/TaggedQuestionList.php @@ -13,7 +13,7 @@ use App\Repos\Question as QuestionRepo; class TaggedQuestionList extends Cache { - protected $limit = 5; + protected $limit = 15; protected $lifetime = 3600; diff --git a/app/Http/Admin/Views/public/login.volt b/app/Http/Admin/Views/public/login.volt index df649e74..66c249d9 100644 --- a/app/Http/Admin/Views/public/login.volt +++ b/app/Http/Admin/Views/public/login.volt @@ -35,7 +35,7 @@