mirror of
https://gitee.com/koogua/course-tencent-cloud.git
synced 2025-07-15 04:46:06 +08:00
完成会员页
This commit is contained in:
parent
61cd08ac4c
commit
63067e228e
@ -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;
|
||||
|
||||
|
62
app/Http/Web/Controllers/VipController.php
Normal file
62
app/Http/Web/Controllers/VipController.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Web\Controllers;
|
||||
|
||||
use App\Services\Frontend\Vip\CourseList as VipCourseListService;
|
||||
use App\Services\Frontend\Vip\OptionList as VipOptionListService;
|
||||
use App\Services\Frontend\Vip\UserList as VipUserListService;
|
||||
use Phalcon\Mvc\View;
|
||||
|
||||
/**
|
||||
* @RoutePrefix("/vip")
|
||||
*/
|
||||
class VipController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* @Get("/", name="web.vip.index")
|
||||
*/
|
||||
public function indexAction()
|
||||
{
|
||||
$service = new VipOptionListService();
|
||||
|
||||
$vipOptionList = $service->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);
|
||||
}
|
||||
|
||||
}
|
@ -32,7 +32,15 @@
|
||||
<a href="{{ course_url }}" title="{{ course.title|e }}">{{ course.title }}</a>
|
||||
</div>
|
||||
<div class="meta">
|
||||
{% if course.market_price > 0 %}
|
||||
{% if course.market_price > course.vip_price %}
|
||||
<span>¥{{ course.market_price }}</span>
|
||||
{% if course.vip_price > 0 %}
|
||||
<span class="price">会员¥{{ course.vip_price }}</span>
|
||||
{% else %}
|
||||
<span class="free">会员免费</span>
|
||||
{% endif %}
|
||||
<span class="user">{{ course.user_count }}人购买</span>
|
||||
{% elseif course.market_price > 0 %}
|
||||
<span class="price">¥{{ course.market_price }}</span>
|
||||
<span class="level">{{ level_info(course.level) }}</span>
|
||||
<span class="lesson">{{ course.lesson_count }}节课</span>
|
||||
|
@ -8,11 +8,11 @@
|
||||
</div>
|
||||
|
||||
{% if pager.total_pages > 0 %}
|
||||
<div class="teacher-list clearfix">
|
||||
<div class="teach-user-list clearfix">
|
||||
{% for item in pager.items %}
|
||||
{% set teacher_title = item.title ? item.title : '小小教书匠' %}
|
||||
{% set teacher_url = url({'for':'web.teacher.show','id':item.id}) %}
|
||||
<div class="teacher-card" title="{{ item.about|e }}">
|
||||
<div class="user-card" title="{{ item.about|e }}">
|
||||
<div class="avatar">
|
||||
<a href="{{ teacher_url }}"><img src="{{ item.avatar }}" alt="{{ item.name }}"></a>
|
||||
</div>
|
||||
|
10
app/Http/Web/Views/vip/courses.volt
Normal file
10
app/Http/Web/Views/vip/courses.volt
Normal file
@ -0,0 +1,10 @@
|
||||
{{ partial('partials/macro_course') }}
|
||||
|
||||
{% if pager.total_pages > 0 %}
|
||||
<div class="course-list clearfix">
|
||||
{% for item in pager.items %}
|
||||
{{ course_card(item) }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{{ partial('partials/pager_ajax') }}
|
||||
{% endif %}
|
60
app/Http/Web/Views/vip/index.volt
Normal file
60
app/Http/Web/Views/vip/index.volt
Normal file
@ -0,0 +1,60 @@
|
||||
{% extends 'templates/full.volt' %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="vip-header">会员权益</div>
|
||||
|
||||
<div class="vip-reason-list container">
|
||||
<span class="layui-badge reason-badge">好课畅学</span>
|
||||
<span class="layui-badge reason-badge">会员折扣</span>
|
||||
<span class="layui-badge reason-badge">高清视频</span>
|
||||
<span class="layui-badge reason-badge">广告免疫</span>
|
||||
<span class="layui-badge reason-badge">会员标识</span>
|
||||
<span class="layui-badge reason-badge">贴心服务</span>
|
||||
</div>
|
||||
|
||||
<div class="vip-header">开通会员</div>
|
||||
|
||||
<div class="vip-option-list clearfix">
|
||||
{% for option in vip_option_list %}
|
||||
{% set order_url = url({'for':'web.order.confirm'},{'item_id':option.id,'item_type':'vip'}) %}
|
||||
<div class="vip-option-card">
|
||||
<div class="title">{{ option.title }}</div>
|
||||
<div class="price">¥{{ option.price }}</div>
|
||||
<div class="order"><a class="layui-btn layui-btn-sm layui-bg-red" href="{{ order_url }}">立即开通</a></div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% set courses_url = url({'for':'web.vip.courses'}) %}
|
||||
{% set users_url = url({'for':'web.vip.users'}) %}
|
||||
|
||||
<div class="container">
|
||||
<div class="layui-tab layui-tab-brief user-tab">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this">课程</li>
|
||||
<li>成员</li>
|
||||
</ul>
|
||||
<div class="layui-tab-content">
|
||||
<div class="layui-tab-item layui-show" id="tab-courses" data-url="{{ courses_url }}"></div>
|
||||
<div class="layui-tab-item" id="tab-users" data-url="{{ users_url }}"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block inline_js %}
|
||||
|
||||
<script>
|
||||
if ($('#tab-courses').length > 0) {
|
||||
var $tabCourses = $('#tab-courses');
|
||||
helper.ajaxLoadHtml($tabCourses.attr('data-url'), $tabCourses.attr('id'));
|
||||
}
|
||||
if ($('#tab-users').length > 0) {
|
||||
var $tabUsers = $('#tab-users');
|
||||
helper.ajaxLoadHtml($tabUsers.attr('data-url'), $tabUsers.attr('id'));
|
||||
}
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
15
app/Http/Web/Views/vip/users.volt
Normal file
15
app/Http/Web/Views/vip/users.volt
Normal file
@ -0,0 +1,15 @@
|
||||
{% if pager.total_pages > 0 %}
|
||||
<div class="vip-user-list clearfix">
|
||||
{% for item in pager.items %}
|
||||
{% set user_url = url({'for':'web.user.show','id':item.id}) %}
|
||||
<div class="user-card" title="{{ item.about|e }}">
|
||||
<div class="avatar">
|
||||
<a href="{{ user_url }}"><img src="{{ item.avatar }}" alt="{{ item.name }}"></a>
|
||||
</div>
|
||||
<div class="name"><a href="{{ user_url }}">{{ item.name }}</a></div>
|
||||
<div class="title"><span class="layui-badge layui-bg-orange">vip</span></div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{{ partial('partials/pager_ajax') }}
|
||||
{% endif %}
|
@ -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';
|
||||
|
67
app/Services/Frontend/Vip/CourseList.php
Normal file
67
app/Services/Frontend/Vip/CourseList.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Frontend\Vip;
|
||||
|
||||
use App\Library\Paginator\Query as PagerQuery;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use App\Services\Frontend\Service as FrontendService;
|
||||
|
||||
class CourseList extends FrontendService
|
||||
{
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$pagerQuery = new PagerQuery();
|
||||
|
||||
$params = $pagerQuery->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;
|
||||
}
|
||||
|
||||
}
|
35
app/Services/Frontend/Vip/OptionList.php
Normal file
35
app/Services/Frontend/Vip/OptionList.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Frontend\Vip;
|
||||
|
||||
use App\Repos\Vip as VipRepo;
|
||||
use App\Services\Frontend\Service as FrontendService;
|
||||
|
||||
class OptionList extends FrontendService
|
||||
{
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$vipRepo = new VipRepo();
|
||||
|
||||
$vips = $vipRepo->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;
|
||||
}
|
||||
|
||||
}
|
62
app/Services/Frontend/Vip/UserList.php
Normal file
62
app/Services/Frontend/Vip/UserList.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Frontend\Vip;
|
||||
|
||||
use App\Library\Paginator\Query as PagerQuery;
|
||||
use App\Repos\User as UserRepo;
|
||||
use App\Services\Frontend\Service as FrontendService;
|
||||
|
||||
class UserList extends FrontendService
|
||||
{
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$pagerQuery = new PagerQuery();
|
||||
|
||||
$params = $pagerQuery->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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user