diff --git a/app/Http/Web/Controllers/CourseController.php b/app/Http/Web/Controllers/CourseController.php index 86af553a..c10150fc 100644 --- a/app/Http/Web/Controllers/CourseController.php +++ b/app/Http/Web/Controllers/CourseController.php @@ -12,8 +12,8 @@ use App\Services\Frontend\Course\PackageList as CoursePackageListService; use App\Services\Frontend\Course\RecommendedList as CourseRecommendedListService; use App\Services\Frontend\Course\RelatedList as CourseRelatedListService; use App\Services\Frontend\Course\ReviewList as CourseReviewListService; -use App\Services\Frontend\Course\TeacherList as CourseTeacherListService; use App\Services\Frontend\Course\TopicList as CourseTopicListService; +use App\Services\Frontend\Course\UserList as CourseTeacherListService; use App\Services\Frontend\Reward\OptionList as RewardOptionList; use Phalcon\Mvc\View; diff --git a/app/Http/Web/Controllers/VipController.php b/app/Http/Web/Controllers/VipController.php new file mode 100644 index 00000000..c24a9ad4 --- /dev/null +++ b/app/Http/Web/Controllers/VipController.php @@ -0,0 +1,62 @@ +handle(); + + $this->view->setVar('vip_option_list', $vipOptionList); + } + + /** + * @Get("/courses", name="web.vip.courses") + */ + public function coursesAction() + { + $target = $this->request->get('target', 'trim', 'tab-courses'); + + $service = new VipCourseListService(); + + $pager = $service->handle(); + $pager->items = kg_array_object($pager->items); + $pager->target = $target; + + $this->view->setRenderLevel(View::LEVEL_ACTION_VIEW); + $this->view->setVar('pager', $pager); + } + + /** + * @Get("/users", name="web.vip.users") + */ + public function usersAction() + { + $target = $this->request->get('target', 'trim', 'tab-users'); + + $service = new VipUserListService(); + + $pager = $service->handle(); + $pager->items = kg_array_object($pager->items); + $pager->target = $target; + + $this->view->setRenderLevel(View::LEVEL_ACTION_VIEW); + $this->view->setVar('pager', $pager); + } + +} diff --git a/app/Http/Web/Views/partials/macro_course.volt b/app/Http/Web/Views/partials/macro_course.volt index 42644550..43983898 100644 --- a/app/Http/Web/Views/partials/macro_course.volt +++ b/app/Http/Web/Views/partials/macro_course.volt @@ -32,7 +32,15 @@ {{ course.title }}
- {% if course.market_price > 0 %} + {% if course.market_price > course.vip_price %} + ¥{{ course.market_price }} + {% if course.vip_price > 0 %} + 会员¥{{ course.vip_price }} + {% else %} + 会员免费 + {% endif %} + {{ course.user_count }}人购买 + {% elseif course.market_price > 0 %} ¥{{ course.market_price }} {{ level_info(course.level) }} {{ course.lesson_count }}节课 diff --git a/app/Http/Web/Views/teacher/list.volt b/app/Http/Web/Views/teacher/list.volt index 2e839b83..92770b82 100644 --- a/app/Http/Web/Views/teacher/list.volt +++ b/app/Http/Web/Views/teacher/list.volt @@ -8,11 +8,11 @@
{% if pager.total_pages > 0 %} -
+
{% for item in pager.items %} {% set teacher_title = item.title ? item.title : '小小教书匠' %} {% set teacher_url = url({'for':'web.teacher.show','id':item.id}) %} -
+
{{ item.name }}
diff --git a/app/Http/Web/Views/vip/courses.volt b/app/Http/Web/Views/vip/courses.volt new file mode 100644 index 00000000..4d0fc711 --- /dev/null +++ b/app/Http/Web/Views/vip/courses.volt @@ -0,0 +1,10 @@ +{{ partial('partials/macro_course') }} + +{% if pager.total_pages > 0 %} +
+ {% for item in pager.items %} + {{ course_card(item) }} + {% endfor %} +
+ {{ partial('partials/pager_ajax') }} +{% endif %} \ No newline at end of file diff --git a/app/Http/Web/Views/vip/index.volt b/app/Http/Web/Views/vip/index.volt new file mode 100644 index 00000000..4ce36a98 --- /dev/null +++ b/app/Http/Web/Views/vip/index.volt @@ -0,0 +1,60 @@ +{% extends 'templates/full.volt' %} + +{% block content %} + +
会员权益
+ +
+ 好课畅学 + 会员折扣 + 高清视频 + 广告免疫 + 会员标识 + 贴心服务 +
+ +
开通会员
+ +
+ {% for option in vip_option_list %} + {% set order_url = url({'for':'web.order.confirm'},{'item_id':option.id,'item_type':'vip'}) %} +
+
{{ option.title }}
+
¥{{ option.price }}
+ +
+ {% endfor %} +
+ + {% set courses_url = url({'for':'web.vip.courses'}) %} + {% set users_url = url({'for':'web.vip.users'}) %} + +
+
+
    +
  • 课程
  • +
  • 成员
  • +
+
+
+
+
+
+
+ +{% endblock %} + +{% block inline_js %} + + + +{% endblock %} \ No newline at end of file diff --git a/app/Http/Web/Views/vip/users.volt b/app/Http/Web/Views/vip/users.volt new file mode 100644 index 00000000..46512a30 --- /dev/null +++ b/app/Http/Web/Views/vip/users.volt @@ -0,0 +1,15 @@ +{% if pager.total_pages > 0 %} +
+ {% for item in pager.items %} + {% set user_url = url({'for':'web.user.show','id':item.id}) %} +
+
+ {{ item.name }} +
+ +
vip
+
+ {% endfor %} +
+ {{ partial('partials/pager_ajax') }} +{% endif %} diff --git a/app/Repos/Course.php b/app/Repos/Course.php index db2e6c2b..f1b89ae9 100644 --- a/app/Repos/Course.php +++ b/app/Repos/Course.php @@ -60,10 +60,6 @@ class Course extends Repository $builder->andWhere('level = :level:', ['level' => $where['level']]); } - if ($sort == 'free') { - $where['free'] = 1; - } - if (isset($where['free'])) { if ($where['free'] == 1) { $builder->andWhere('market_price = 0'); @@ -80,6 +76,14 @@ class Course extends Repository $builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]); } + if ($sort == 'free') { + $builder->andWhere('market_price = 0'); + } elseif ($sort == 'vip') { + $builder->andWhere('vip_price < market_price'); + } elseif ($sort == 'vip_free') { + $builder->andWhere('vip_price = 0'); + } + switch ($sort) { case 'score': $orderBy = 'score DESC'; diff --git a/app/Services/Frontend/Vip/CourseList.php b/app/Services/Frontend/Vip/CourseList.php new file mode 100644 index 00000000..cf9b98f4 --- /dev/null +++ b/app/Services/Frontend/Vip/CourseList.php @@ -0,0 +1,67 @@ +getParams(); + + $params['published'] = 1; + $params['deleted'] = 0; + + $sort = 'vip'; + $page = $pagerQuery->getPage(); + $limit = $pagerQuery->getLimit(); + + $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; + } + + $courses = $pager->items->toArray(); + + $baseUrl = kg_ci_base_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'], + ]; + } + + $pager->items = $items; + + return $pager; + } + +} diff --git a/app/Services/Frontend/Vip/OptionList.php b/app/Services/Frontend/Vip/OptionList.php new file mode 100644 index 00000000..1269877a --- /dev/null +++ b/app/Services/Frontend/Vip/OptionList.php @@ -0,0 +1,35 @@ +findAll(['deleted' => 0]); + + if ($vips->count() == 0) { + return []; + } + + $result = []; + + foreach ($vips as $vip) { + $result[] = [ + 'id' => $vip->id, + 'title' => $vip->title, + 'expiry' => $vip->expiry, + 'price' => $vip->price, + ]; + } + + return $result; + } + +} \ No newline at end of file diff --git a/app/Services/Frontend/Vip/UserList.php b/app/Services/Frontend/Vip/UserList.php new file mode 100644 index 00000000..ee0ddf0e --- /dev/null +++ b/app/Services/Frontend/Vip/UserList.php @@ -0,0 +1,62 @@ +getParams(); + + $params['vip'] = 1; + $params['deleted'] = 0; + + $sort = $pagerQuery->getSort(); + $page = $pagerQuery->getPage(); + $limit = $pagerQuery->getLimit(); + + $userRepo = new UserRepo(); + + $pager = $userRepo->paginate($params, $sort, $page, $limit); + + return $this->handleUsers($pager); + } + + protected function handleUsers($pager) + { + if ($pager->total_items == 0) { + return $pager; + } + + $users = $pager->items->toArray(); + + $baseUrl = kg_ci_base_url(); + + $items = []; + + foreach ($users as $user) { + + $user['avatar'] = $baseUrl . $user['avatar']; + + $items[] = [ + 'id' => $user['id'], + 'name' => $user['name'], + 'avatar' => $user['avatar'], + 'title' => $user['title'], + 'about' => $user['about'], + ]; + } + + $pager->items = $items; + + return $pager; + } + +} diff --git a/public/static/web/css/common.css b/public/static/web/css/common.css index 9d54c6bb..18e52e15 100644 --- a/public/static/web/css/common.css +++ b/public/static/web/css/common.css @@ -660,6 +660,58 @@ margin-right: 10px; } +.vip-header { + font-size: 18px; + text-align: center; + margin-bottom: 30px; +} + +.vip-reason-list { + padding: 30px; + margin-bottom: 30px; + text-align: center; +} + +.vip-reason-list .reason-badge { + height: 30px; + line-height: 30px; + padding: 0 10px; + margin-right: 15px; + background-color: #1E9FFF; +} + +.vip-option-list { + margin-bottom: 30px; +} + +.vip-option-card { + float: left; + width: 262px; + height: 150px; + padding-top: 30px; + margin-right: 30px; + background-color: #fff; + border-radius: 2px; + text-align: center; + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); +} + +.vip-option-card:last-child { + margin-right: 0; +} + +.vip-option-card .title { + margin-bottom: 15px; + font-size: 18px; +} + +.vip-option-card .price { + margin-bottom: 20px; + font-size: 20px; + font-weight: 600; + color: red; +} + .cart-course-card { padding-bottom: 10px; margin-bottom: 10px; @@ -937,40 +989,50 @@ color: #666; } -.teacher-card { - float: left; +.teach-user-list .user-card { width: 203px; - height: 200px; - margin-right: 25px; margin-bottom: 25px; - text-align: center; background-color: #fff; border-radius: 2px; box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); } -.teacher-card .avatar { - margin-top: 20px; - margin-bottom: 10px; +.vip-user-list { + margin-bottom: 15px; } -.teacher-card .avatar img { +.vip-user-list .user-card { + width: 195px; +} + +.user-card { + float: left; + height: 210px; + margin-right: 25px; + text-align: center; +} + +.user-card .avatar { + margin-top: 20px; + margin-bottom: 15px; +} + +.user-card .avatar img { width: 96px; height: 96px; border-radius: 100px; transition: 0.5s; } -.teacher-card .avatar img:hover { +.user-card .avatar img:hover { transform: rotateY(180deg); } -.teacher-card .name { - margin-bottom: 10px; +.user-card .name { + margin-bottom: 15px; } -.teacher-card .title { - margin-bottom: 10px; +.user-card .title { color: #666; font-size: 12px; } @@ -1032,8 +1094,4 @@ .security-item .action { float: right; -} - -.layer-container .account-form { - padding-top: 40px; } \ No newline at end of file