1
0
mirror of https://gitee.com/koogua/course-tencent-cloud.git synced 2025-06-22 03:32:47 +08:00

加入layim

This commit is contained in:
xiaochong0302 2020-06-06 20:18:11 +08:00
parent 2d944cf9af
commit eed693cd15
52 changed files with 1492 additions and 78 deletions

View File

@ -51,6 +51,9 @@ class CourseFavoriteList extends Builder
foreach ($courses->toArray() as $course) {
$course['cover'] = $baseUrl . $course['cover'];
$course['market_price'] = (float)$course['market_price'];
$course['vip_price'] = (float)$course['vip_price'];
$course['rating'] = (float)$course['rating'];
$course['attrs'] = json_decode($course['attrs'], true);
$result[$course['id']] = $course;
}

View File

@ -7,6 +7,7 @@ use App\Services\Frontend\Account\EmailUpdate as EmailUpdateService;
use App\Services\Frontend\Account\PasswordReset as PasswordResetService;
use App\Services\Frontend\Account\PasswordUpdate as PasswordUpdateService;
use App\Services\Frontend\Account\PhoneUpdate as PhoneUpdateService;
use Phalcon\Mvc\View;
/**
* @RoutePrefix("/account")
@ -138,6 +139,60 @@ class AccountController extends Controller
$this->view->setVar('captcha', $captcha);
}
/**
* @Get("/password/edit", name="web.account.edit_pwd")
*/
public function editPasswordAction()
{
if ($this->authUser->id == 0) {
$this->response->redirect(['for' => 'web.account.login']);
}
$service = new AccountService();
$captcha = $service->getSectionSettings('captcha');
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
$this->view->pick('account/edit_password');
$this->view->setVar('captcha', $captcha);
}
/**
* @Get("/phone/edit", name="web.account.edit_phone")
*/
public function editPhoneAction()
{
if ($this->authUser->id == 0) {
$this->response->redirect(['for' => 'web.account.login']);
}
$service = new AccountService();
$captcha = $service->getSectionSettings('captcha');
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
$this->view->pick('account/edit_phone');
$this->view->setVar('captcha', $captcha);
}
/**
* @Get("/email/edit", name="web.account.edit_email")
*/
public function editEmailAction()
{
if ($this->authUser->id == 0) {
$this->response->redirect(['for' => 'web.account.login']);
}
$service = new AccountService();
$captcha = $service->getSectionSettings('captcha');
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
$this->view->pick('account/edit_email');
$this->view->setVar('captcha', $captcha);
}
/**
* @Post("/password/reset", name="web.account.reset_pwd")
*/

View File

@ -31,7 +31,6 @@ class CourseController extends Controller
$service = new CourseListService();
$pager = $service->handle();
$pager->items = kg_array_object($pager->items);
$service = new CourseQueryService();
@ -105,7 +104,6 @@ class CourseController extends Controller
$service = new CourseConsultListService();
$pager = $service->handle($id);
$pager->items = kg_array_object($pager->items);
$pager->target = $target;
@ -123,7 +121,6 @@ class CourseController extends Controller
$service = new CourseReviewListService();
$pager = $service->handle($id);
$pager->items = kg_array_object($pager->items);
$pager->target = $target;

View File

@ -2,12 +2,12 @@
namespace App\Http\Web\Controllers;
use App\Services\Frontend\My\AccountInfo as AccountInfoService;
use App\Services\Frontend\My\ConsultList as MyConsultListService;
use App\Services\Frontend\My\CourseList as MyCourseListService;
use App\Services\Frontend\My\FavoriteList as MyFavoriteListService;
use App\Services\Frontend\My\OrderList as MyOrderListService;
use App\Services\Frontend\My\RefundList as MyRefundListService;
use App\Services\Frontend\My\ReviewList as MyReviewListService;
use App\Services\Frontend\My\UserInfo as UserInfoService;
/**
* @RoutePrefix("/my")
@ -16,27 +16,50 @@ class MyController extends Controller
{
/**
* @Get("/courses", name="web.my.courses")
* @Get("/home", name="web.my.home")
*/
public function coursesAction()
public function homeAction()
{
$service = new MyCourseListService();
$pager = $service->handle();
$this->view->setVar('pager', $pager);
$this->dispatcher->forward([
'for' => 'web.user.show',
'id' => $this->authUser->id,
]);
}
/**
* @Get("/favorites", name="web.my.favorites")
* @Get("/profile", name="web.my.profile")
*/
public function favoritesAction()
public function profileAction()
{
$service = new MyFavoriteListService();
$service = new UserInfoService();
$pager = $service->handle();
$user = $service->handle();
$this->view->setVar('pager', $pager);
$this->view->setVar('user', $user);
}
/**
* @Get("/account", name="web.my.account")
*/
public function accountAction()
{
$service = new AccountInfoService();
$account = $service->handle();
$this->view->setVar('account', $account);
}
/**
* @Post("/profile/update", name="web.my.update_profile")
*/
public function updateProfileAction()
{
$service = new UserInfoService();
$user = $service->handle();
$this->view->setVar('user', $user);
}
/**

View File

@ -0,0 +1,35 @@
<?php
namespace App\Http\Web\Controllers;
use App\Services\Frontend\Teacher\TeacherList as TeacherListService;
/**
* @RoutePrefix("/teacher")
*/
class TeacherController extends Controller
{
/**
* @Get("/list", name="web.teacher")
*/
public function listAction()
{
$service = new TeacherListService();
$pager = $service->handle();
$pager->items = kg_array_object($pager->items);
$this->view->setVar('pager', $pager);
}
/**
* @Get("/{id:[0-9]+}", name="web.teacher.show")
*/
public function showAction()
{
}
}

View File

@ -3,7 +3,9 @@
namespace App\Http\Web\Controllers;
use App\Services\Frontend\User\CourseList as UserCourseListService;
use App\Services\Frontend\User\FavoriteList as UserFavoriteListService;
use App\Services\Frontend\User\UserInfo as UserInfoService;
use Phalcon\Mvc\View;
/**
* @RoutePrefix("/user")
@ -28,11 +30,50 @@ class UserController extends Controller
*/
public function coursesAction($id)
{
$target = $this->request->get('target', 'trim', 'tab-courses');
$service = new UserCourseListService();
$courses = $service->handle($id);
$pager = $service->handle($id);
$pager->items = kg_array_object($pager->items);
$pager->target = $target;
return $this->jsonSuccess(['courses' => $courses]);
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
$this->view->setVar('pager', $pager);
}
/**
* @Get("/{id:[0-9]+}/favorites", name="web.user.favorites")
*/
public function favoritesAction($id)
{
$target = $this->request->get('target', 'trim', 'tab-favorites');
$service = new UserFavoriteListService();
$pager = $service->handle($id);
$pager->items = kg_array_object($pager->items);
$pager->target = $target;
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
$this->view->setVar('pager', $pager);
}
/**
* @Get("/{id:[0-9]+}/friends", name="web.user.friends")
*/
public function friendsAction($id)
{
$target = $this->request->get('target', 'trim', 'tab-friends');
$service = new UserFavoriteListService();
$pager = $service->handle($id);
$pager->items = kg_array_object($pager->items);
$pager->target = $target;
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
$this->view->setVar('pager', $pager);
}
}

View File

@ -0,0 +1,43 @@
{% extends 'templates/content.volt' %}
{% block content %}
<div class="account-container container">
<form class="layui-form account-form" method="POST" action="{{ url({'for':'web.account.reset_pwd'}) }}">
<div class="layui-form-item">
<div class="layui-input-block">
<input id="cv-account" class="layui-input" type="text" name="account" autocomplete="off" placeholder="手机 / 邮箱" lay-verify="required">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<input class="layui-input" type="password" name="new_password" autocomplete="off" placeholder="新密码" lay-verify="required">
</div>
</div>
<div class="layui-form-item">
<div class="verify-input-inline">
<input class="layui-input" type="text" name="verify_code" placeholder="验证码" lay-verify="required">
</div>
<div class="verify-btn-inline">
<button id="cv-verify-emit" class="layui-btn layui-btn-primary layui-btn-disabled" type="button" disabled="disabled">获取验证码</button>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button id="cv-submit-btn" class="layui-btn layui-btn-fluid layui-btn-disabled" disabled="disabled" lay-submit="true" lay-filter="go">立即重置</button>
<input id="cv-app-id" type="hidden" value="{{ captcha.app_id }}">
<input id="cv-ticket" type="hidden" name="ticket">
<input id="cv-rand" type="hidden" name="rand">
</div>
</div>
</form>
</div>
{% endblock %}
{% block include_js %}
{{ js_include('https://ssl.captcha.qq.com/TCaptcha.js',false) }}
{{ js_include('web/js/captcha.verify.js') }}
{% endblock %}

View File

@ -0,0 +1,43 @@
{% extends 'templates/content.volt' %}
{% block content %}
<div class="account-container container">
<form class="layui-form account-form" method="POST" action="{{ url({'for':'web.account.reset_pwd'}) }}">
<div class="layui-form-item">
<div class="layui-input-block">
<input id="cv-account" class="layui-input" type="text" name="account" autocomplete="off" placeholder="手机 / 邮箱" lay-verify="required">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<input class="layui-input" type="password" name="new_password" autocomplete="off" placeholder="新密码" lay-verify="required">
</div>
</div>
<div class="layui-form-item">
<div class="verify-input-inline">
<input class="layui-input" type="text" name="verify_code" placeholder="验证码" lay-verify="required">
</div>
<div class="verify-btn-inline">
<button id="cv-verify-emit" class="layui-btn layui-btn-primary layui-btn-disabled" type="button" disabled="disabled">获取验证码</button>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button id="cv-submit-btn" class="layui-btn layui-btn-fluid layui-btn-disabled" disabled="disabled" lay-submit="true" lay-filter="go">立即重置</button>
<input id="cv-app-id" type="hidden" value="{{ captcha.app_id }}">
<input id="cv-ticket" type="hidden" name="ticket">
<input id="cv-rand" type="hidden" name="rand">
</div>
</div>
</form>
</div>
{% endblock %}
{% block include_js %}
{{ js_include('https://ssl.captcha.qq.com/TCaptcha.js',false) }}
{{ js_include('web/js/captcha.verify.js') }}
{% endblock %}

View File

@ -0,0 +1,43 @@
{% extends 'templates/content.volt' %}
{% block content %}
<div class="account-container container">
<form class="layui-form account-form" method="POST" action="{{ url({'for':'web.account.reset_pwd'}) }}">
<div class="layui-form-item">
<div class="layui-input-block">
<input id="cv-account" class="layui-input" type="text" name="account" autocomplete="off" placeholder="手机 / 邮箱" lay-verify="required">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<input class="layui-input" type="password" name="new_password" autocomplete="off" placeholder="新密码" lay-verify="required">
</div>
</div>
<div class="layui-form-item">
<div class="verify-input-inline">
<input class="layui-input" type="text" name="verify_code" placeholder="验证码" lay-verify="required">
</div>
<div class="verify-btn-inline">
<button id="cv-verify-emit" class="layui-btn layui-btn-primary layui-btn-disabled" type="button" disabled="disabled">获取验证码</button>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button id="cv-submit-btn" class="layui-btn layui-btn-fluid layui-btn-disabled" disabled="disabled" lay-submit="true" lay-filter="go">立即重置</button>
<input id="cv-app-id" type="hidden" value="{{ captcha.app_id }}">
<input id="cv-ticket" type="hidden" name="ticket">
<input id="cv-rand" type="hidden" name="rand">
</div>
</div>
</form>
</div>
{% endblock %}
{% block include_js %}
{{ js_include('https://ssl.captcha.qq.com/TCaptcha.js',false) }}
{{ js_include('web/js/captcha.verify.js') }}
{% endblock %}

View File

@ -1,4 +1,4 @@
{% extends 'templates/base.volt' %}
{% extends 'templates/full.volt' %}
{% block content %}

View File

@ -1,4 +1,4 @@
{% extends 'templates/base.volt' %}
{% extends 'templates/full.volt' %}
{% block content %}

View File

@ -1,4 +1,4 @@
{% extends 'templates/base.volt' %}
{% extends 'templates/full.volt' %}
{% block content %}

View File

@ -1,4 +1,4 @@
{% extends 'templates/base.volt' %}
{% extends 'templates/full.volt' %}
{% block content %}

View File

@ -1,4 +1,4 @@
{% extends 'templates/base.volt' %}
{% extends 'templates/full.volt' %}
{% block content %}
@ -25,12 +25,13 @@
{% set show_tab_consults = course.consult_count > 0 ? 1 : 0 %}
{% set show_tab_reviews = course.review_count > 0 ? 1 : 0 %}
<div class="layout-content container">
<div class="layui-tab layui-tab-brief course-tab">
<ul class="layui-tab-title">
<li class="layui-this">详情</li>
<li>目录</li>
{% if show_tab_packages == 1 %}
<div class="layout-content">
<div class="container">
<div class="layui-tab layui-tab-brief course-tab">
<ul class="layui-tab-title">
<li class="layui-this">详情</li>
<li>目录</li>
{% if show_tab_packages == 1 %}
<li>套餐</li>
{% endif %}
{% if show_tab_consults == 1 %}
@ -60,6 +61,7 @@
<div class="layui-tab-item" id="tab-reviews" data-url="{{ review_url }}"></div>
{% endif %}
</div>
</div>
</div>
</div>

View File

@ -1,4 +1,4 @@
{% extends 'templates/base.volt' %}
{% extends 'templates/full.volt' %}
{% block content %}

View File

@ -0,0 +1,80 @@
{% extends 'templates/full.volt' %}
{% block content %}
{% set act_pwd_url = url({'for':'web.account.edit_pwd'}) %}
{% set act_phone_url = url({'for':'web.account.edit_phone'}) %}
{% set act_email_url = url({'for':'web.account.edit_email'}) %}
<div class="layout-main">
<div class="layout-sidebar">{{ partial('my/menu') }}</div>
<div class="layout-content">
<div class="container">
<div class="my-nav-title">账号安全</div>
<div class="security-item-list">
<div class="security-item">
<span class="icon"><i class="layui-icon layui-icon-password"></i></span>
<span class="title">登录密码</span>
<span class="summary">经常更改密码有助于保护您的帐号安全</span>
<span class="action"><a href="javascript:" id="act-pwd-btn" class="layui-btn layui-btn-sm" data-url="{{ act_pwd_url }}">修改</a></span>
</div>
<div class="security-item">
<span class="icon"><i class="layui-icon layui-icon-cellphone"></i></span>
<span class="title">手机绑定</span>
{% if account.phone %}
<span class="summary">已绑定手机:{{ account.phone }}</span>
<span class="action"><a href="javascript:" id="act-phone-btn" class="layui-btn layui-btn-sm" data-url="{{ act_phone_url }}">修改</a></span>
{% else %}
<span class="summary">可用于登录和重置密码</span>
<span class="action"><a href="javascript:" id="act-phone-btn" class="layui-btn layui-btn-sm" data-url="{{ act_phone_url }}">绑定</a></span>
{% endif %}
</div>
<div class="security-item">
<span class="icon"><i class="layui-icon layui-icon-email"></i></span>
<span class="title">邮箱绑定</span>
{% if account.phone %}
<span class="summary">已绑定邮箱:{{ account.email }}</span>
<span class="action"><a href="javascript:" id="act-email-btn" class="layui-btn layui-btn-sm" data-url="{{ act_email_url }}">修改</a></span>
{% else %}
<span class="summary">可用于登录和重置密码</span>
<span class="action"><a href="javascript:" id="act-email-btn" class="layui-btn layui-btn-sm" data-url="{{ act_email_url }}">绑定</a></span>
{% endif %}
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block inline_js %}
<script>
var $ = layui.jquery;
var layer = layui.layer;
$('#act-pwd-btn').on('click', function () {
showFrameLayer('密码修改', $(this).attr('data-url'));
});
$('#act-phone-btn').on('click', function () {
showFrameLayer('手机绑定', $(this).attr('data-url'));
});
$('#act-email-btn').on('click', function () {
showFrameLayer('邮箱绑定', $(this).attr('data-url'));
});
function showFrameLayer(title, url) {
layer.open({
type: 2,
content: url,
area: ['800px', '400px']
});
}
</script>
{% endblock %}

View File

@ -0,0 +1,25 @@
{%- macro vip_info(user) %}
{% set vip_url = '#' %}
{% if user.vip == 1 %}
<a class="layui-badge layui-bg-orange" title="到期时间:{{ date('Y-m-d',user.vip_expiry_time) }}" href="{{ vip_url }}">会员</a>
{% else %}
<a class="layui-badge layui-bg-gray" title="开通会员" href="{{ vip_url }}">会员</a>
{% endif %}
{%- endmacro %}
<div class="my-profile-card container">
<div class="avatar">
<a href="javascript:"><img src="{{ auth_user.avatar }}" alt="{{ auth_user.name }}"></a>
</div>
<div class="name">{{ auth_user.name }} {{ vip_info(auth_user) }}</div>
</div>
<div class="layui-card">
<div class="layui-card-header">个人设置</div>
<div class="layui-card-body">
<ul class="my-menu">
<li><a href="{{ url({'for':'web.my.profile'}) }}">个人信息</a></li>
<li><a href="{{ url({'for':'web.my.account'}) }}">帐号安全</a></li>
</ul>
</div>
</div>

View File

@ -0,0 +1,45 @@
{% extends 'templates/full.volt' %}
{% block content %}
<div class="layout-main">
<div class="layout-sidebar">{{ partial('my/menu') }}</div>
<div class="layout-content">
<div class="container">
<div class="my-nav-title">个人信息</div>
<form class="layui-form my-form" method="post" action="{{ url({'for':'web.my.update_profile'}) }}">
<div class="layui-form-item">
<label class="layui-form-label">昵称</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="name" lay-verify="required">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">性别</label>
<div class="layui-input-block">
{% set male_checked = user.gender == 1 ? 'checked' : '' %}
{% set female_checked = user.gender == 2 ? 'checked' : '' %}
{% set none_checked = user.gender == 3 ? 'checked' : '' %}
<input type="radio" name="gender" value="1" title="男" {{ male_checked }}>
<input type="radio" name="gender" value="2" title="女" {{ female_checked }}>
<input type="radio" name="gender" value="3" title="保密" {{ none_checked }}>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">简介</label>
<div class="layui-input-block">
<textarea class="layui-textarea" name="about" lay-verify="required">{{ user.about }}</textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<button class="layui-btn" lay-submit="true" lay-filter="go">提交</button>
<button class="layui-btn layui-btn-primary" type="reset">重置</button>
</div>
</div>
</form>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,4 +1,4 @@
{% extends 'templates/base.volt' %}
{% extends 'templates/full.volt' %}
{% block content %}

View File

@ -1,4 +1,4 @@
{% extends 'templates/base.volt' %}
{% extends 'templates/full.volt' %}
{% block content %}

View File

@ -30,15 +30,12 @@
<div class="user layui-layout-right">
{% if auth_user.id > 0 %}
<ul class="layui-nav">
<li class="layui-nav-item"><a href="{{ url({'for':'web.my.courses'}) }}">消息</a></li>
<li class="layui-nav-item"><a href="#">消息</a></li>
<li class="layui-nav-item">
<a href="javascript:">{{ auth_user.name }}</a>
<dl class="layui-nav-child">
<dd><a href="{{ url({'for':'web.my.courses'}) }}">我的课程</a></dd>
<dd><a href="{{ url({'for':'web.my.courses'}) }}">我的收藏</a></dd>
<dd><a href="{{ url({'for':'web.my.courses'}) }}">我的咨询</a></dd>
<dd><a href="{{ url({'for':'web.my.courses'}) }}">我的订单</a></dd>
<dd><a href="{{ url({'for':'web.my.courses'}) }}">个人设置</a></dd>
<dd><a href="{{ url({'for':'web.my.home'}) }}">我的主页</a></dd>
<dd><a href="{{ url({'for':'web.my.profile'}) }}">个人设置</a></dd>
<dd><a href="{{ url({'for':'web.account.logout'}) }}">退出登录</a></dd>
</dl>
</li>

View File

@ -70,4 +70,25 @@
</div>
</div>
</div>
{%- endmacro %}
{%- macro learning_course_card(item) %}
{% set course_title = item.course.title|e %}
{% set course_url = url({'for':'web.course.show','id':item.course.id}) %}
<div class="course-card learning-course-card">
<div class="cover">
<a href="{{ course_url }}" title="{{ course_title }}">
<img src="{{ item.course.cover }}!cover_270" alt="{{ course_title }}">
</a>
</div>
<div class="title layui-elip">
<a href="{{ course_url }}" title="{{ course_title }}">{{ course_title }}</a>
</div>
<div class="progress">
<div class="layui-progress" lay-showPercent="yes">
<div class="layui-progress-bar" lay-percent="{{ item.progress }}%"></div>
</div>
</div>
<div class="duration">已学习 {{ item.duration|total_duration }}</div>
</div>
{%- endmacro %}

View File

@ -1,4 +1,4 @@
{% extends 'templates/base.volt' %}
{% extends 'templates/full.volt' %}
{% block content %}
@ -14,16 +14,18 @@
</div>
<div class="layout-main clearfix">
<div class="layout-content container">
<div class="layout-content">
{% if pager.total_pages > 0 %}
{% if type == 'course' %}
{{ partial('search/content_course') }}
{% elseif type == 'other' %}
{{ partial('search/content_other') }}
{% endif %}
<div class="container">
{% if type == 'course' %}
{{ partial('search/content_course') }}
{% elseif type == 'other' %}
{{ partial('search/content_other') }}
{% endif %}
</div>
{{ partial('partials/pager') }}
{% else %}
<div class="search-empty">
<div class="search-empty container">
<div class="icon"><i class="layui-icon layui-icon-face-surprised"></i></div>
<div class="text">没有找到<span class="query">{{ query }}</span>相关内容,换个关键字试试吧!</div>
</div>

View File

@ -0,0 +1,27 @@
{% extends 'templates/full.volt' %}
{% block content %}
<div class="layui-breadcrumb breadcrumb">
<a href="/">首页</a>
<a><cite>名师</cite></a>
</div>
{% if pager.total_pages > 0 %}
<div class="teacher-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="avatar">
<a href="{{ teacher_url }}"><img src="{{ item.avatar }}" alt="{{ item.name }}"></a>
</div>
<div class="name"><a href="{{ teacher_url }}">{{ item.name }}</a></div>
<div class="title">{{ teacher_title }}</div>
</div>
{% endfor %}
</div>
{{ partial('partials/pager') }}
{% endif %}
{% endblock %}

View File

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="zh-CN-Hans">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="keywords" content="{{ site_seo.getKeywords() }}">
<meta name="description" content="{{ site_seo.getDescription() }}">
<meta name="csrf-token" content="{{ csrfToken.getToken() }}">
<title>{{ site_seo.getTitle() }}</title>
{{ icon_link('favicon.ico') }}
{{ css_link('lib/layui/css/layui.css') }}
{{ css_link('web/css/common.css') }}
{% block link_css %}{% endblock %}
{% block inline_css %}{% endblock %}
</head>
<body>
<div class="layui-main">
{% block content %}{% endblock %}
</div>
{{ js_include('lib/layui/layui.all.js') }}
{{ js_include('web/js/common.js') }}
{% block include_js %}{% endblock %}
{% block inline_js %}{% endblock %}
</body>
</html>

View File

@ -14,25 +14,18 @@
{% block inline_css %}{% endblock %}
</head>
<body>
<div id="header">
{{ partial('partials/header') }}
</div>
<div id="main" class="layui-main">
{% block content %}{% endblock %}
</div>
<div id="footer">
{{ partial('partials/footer') }}
</div>
{{ js_include('lib/layui/layui.all.js') }}
{{ js_include('web/js/common.js') }}
{% block include_js %}{% endblock %}
{% block inline_js %}{% endblock %}
</body>
</html>

View File

@ -0,0 +1,10 @@
{{ partial('partials/macro_course') }}
{% if pager.total_pages > 0 %}
<div class="course-list clearfix">
{% for item in pager.items %}
{{ learning_course_card(item) }}
{% endfor %}
</div>
{{ partial('partials/pager_ajax') }}
{% endif %}

View 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 %}

View File

@ -0,0 +1,57 @@
{% extends 'templates/full.volt' %}
{% block content %}
{{ partial('partials/macro_course') }}
{% set vip_flag = user.vip ? '<i class="layui-icon layui-icon-diamond vip-icon"></i>' : '' %}
<div class="user-profile container clearfix">
<div class="avatar">
<img src="{{ user.avatar }}" alt="{{ user.name }}">
</div>
<div class="info">
<h3>{{ user.name }} {{ vip_flag }}</h3>
<p><span><i class="layui-icon layui-icon-location"></i></span><span>{{ user.location }}</span></p>
<p><span><i class="layui-icon layui-icon-time"></i></span><span>{{ date('Y-m-d H:i',user.last_login_time) }}</span></p>
</div>
{% if user.about %}
<div class="about">{{ user.about }}</div>
{% endif %}
</div>
{% set course_url = url({'for':'web.user.courses','id':user.id}) %}
{% set favorite_url = url({'for':'web.user.favorites','id':user.id}) %}
{% set friend_url = url({'for':'web.user.friends','id':user.id}) %}
<div class="container">
<div class="layui-tab layui-tab-brief user-tab">
<ul class="layui-tab-title">
<li class="layui-this">课程</li>
<li>收藏</li>
<li>好友</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show" id="tab-courses" data-url="{{ course_url }}"></div>
<div class="layui-tab-item" id="tab-favorites" data-url="{{ favorite_url }}"></div>
<div class="layui-tab-item" id="tab-friends" data-url="{{ friend_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-favorites').length > 0) {
var $tabFavorites = $('#tab-favorites');
helper.ajaxLoadHtml($tabFavorites.attr('data-url'), $tabFavorites.attr('id'));
}
</script>
{% endblock %}

View File

@ -130,8 +130,7 @@ class CourseUser extends Model
public function beforeCreate()
{
$this->plan_id = (int)date('Y-m-d');
$this->plan_id = (int)date('Ymd');
$this->create_time = time();
}

View File

@ -85,6 +85,27 @@ class User extends Model
*/
public $admin_role;
/**
* VIP标识
*
* @var int
*/
public $vip;
/**
* 锁定标识
*
* @var int
*/
public $block;
/**
* 删除标识
*
* @var int
*/
public $deleted;
/**
* 最近登录IP
*
@ -99,13 +120,6 @@ class User extends Model
*/
public $last_login_time;
/**
* VIP标识
*
* @var int
*/
public $vip;
/**
* VIP期限
*
@ -113,12 +127,6 @@ class User extends Model
*/
public $vip_expiry_time;
/**
* 锁定标识
*
* @var int
*/
public $block;
/**
* 锁定期限
@ -127,13 +135,6 @@ class User extends Model
*/
public $lock_expiry_time;
/**
* 删除标识
*
* @var int
*/
public $deleted;
/**
* 通知数量
*

View File

@ -0,0 +1,32 @@
<?php
namespace App\Services\Frontend\My;
use App\Models\User as UserModel;
use App\Repos\Account as AccountRepo;
use App\Services\Frontend\Service as FrontendService;
class AccountInfo extends FrontendService
{
public function handle()
{
$user = $this->getLoginUser();
return $this->handleAccount($user);
}
protected function handleAccount(UserModel $user)
{
$accountRepo = new AccountRepo();
$account = $accountRepo->findById($user->id);
return [
'id' => $account->id,
'phone' => $account->phone,
'email' => $account->email,
];
}
}

View File

@ -0,0 +1,64 @@
<?php
namespace App\Services\Frontend\Teacher;
use App\Library\Paginator\Query as PagerQuery;
use App\Repos\User as UserRepo;
use App\Services\Frontend\Service as FrontendService;
class TeacherList extends FrontendService
{
public function handle()
{
$pagerQuery = new PagerQuery();
$params = $pagerQuery->getParams();
$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();
$items = [];
$baseUrl = kg_ci_base_url();
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'],
'location' => $user['location'],
'create_time' => $user['create_time'],
'last_login_time' => $user['last_login_time'],
];
}
$pager->items = $items;
return $pager;
}
}

View File

@ -55,7 +55,7 @@ class CourseList extends FrontendService
$course = $courses[$relation['course_id']] ?? new \stdClass();
$items = [
$items[] = [
'course' => $course,
'progress' => $relation['progress'],
'duration' => $relation['duration'],

View File

@ -0,0 +1,62 @@
<?php
namespace App\Services\Frontend\User;
use App\Builders\CourseFavoriteList as CourseFavoriteListBuilder;
use App\Library\Paginator\Query as PagerQuery;
use App\Repos\CourseFavorite as CourseFavoriteRepo;
use App\Services\Frontend\Service as FrontendService;
use App\Services\Frontend\UserTrait;
class FavoriteList extends FrontendService
{
use UserTrait;
public function handle($id)
{
$user = $this->checkUserCache($id);
$pagerQuery = new PagerQuery();
$params = $pagerQuery->getParams();
$params['user_id'] = $user->id;
$params['deleted'] = 0;
$sort = $pagerQuery->getSort();
$page = $pagerQuery->getPage();
$limit = $pagerQuery->getLimit();
$favoriteRepo = new CourseFavoriteRepo();
$pager = $favoriteRepo->paginate($params, $sort, $page, $limit);
return $this->handleCourses($pager);
}
protected function handleCourses($pager)
{
if ($pager->total_items == 0) {
return $pager;
}
$builder = new CourseFavoriteListBuilder();
$relations = $pager->items->toArray();
$courses = $builder->getCourses($relations);
$items = [];
foreach ($relations as $relation) {
$course = $courses[$relation['course_id']] ?? new \stdClass();
$items[] = $course;
}
$pager->items = $items;
return $pager;
}
}

View File

@ -30,6 +30,8 @@ class UserInfo extends FrontendService
'gender' => $user->gender,
'vip' => $user->vip,
'locked' => $user->locked,
'last_login_time' => $user->last_login_time,
'create_time' => $user->create_time,
];
}

View File

@ -0,0 +1,96 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>聊天记录</title>
<link rel="stylesheet" href="http://local.res.layui.com/layui/src/css/layui.css">
<style>
body .layim-chat-main {
height: auto;
}
</style>
</head>
<body>
<div class="layim-chat-main">
<ul id="LAY_view"></ul>
</div>
<div id="LAY_page" style="margin: 0 10px;"></div>
<textarea title="消息模版" id="LAY_tpl" style="display:none;">
{{# layui.each(d.data, function(index, item){
if(item.id == parent.layui.layim.cache().mine.id){ }}
<li class="layim-chat-mine"><div class="layim-chat-user"><img src="{{ item.avatar }}"><cite><i>{{ layui.data.date(item.timestamp) }}</i>{{ item.username }}</cite></div><div class="layim-chat-text">{{ layui.layim.content(item.content) }}</div></li>
{{# } else { }}
<li><div class="layim-chat-user"><img src="{{ item.avatar }}"><cite>{{ item.username }}<i>{{ layui.data.date(item.timestamp) }}</i></cite></div><div class="layim-chat-text">{{ layui.layim.content(item.content) }}</div></li>
{{# }
}); }}
</textarea>
<!--
上述模版采用了 laytpl 语法不了解的同学可以去看下文档http://www.layui.com/doc/modules/laytpl.html
-->
<script src="http://local.res.layui.com/layui/src/layui.js"></script>
<script>
layui.use(['layim', 'laypage'], function () {
var layim = layui.layim
, layer = layui.layer
, laytpl = layui.laytpl
, $ = layui.jquery
, laypage = layui.laypage;
//聊天记录的分页此处不做演示你可以采用laypage不了解的同学见文档http://www.layui.com/doc/modules/laypage.html
//开始请求聊天记录
var param = location.search //获得URL参数。该窗口url会携带会话id和type他们是你请求聊天记录的重要凭据
//实际使用时下述的res一般是通过Ajax获得而此处仅仅只是演示数据格式
, res = {
code: 0
, msg: ''
, data: [{
username: '纸飞机'
, id: 100000
, avatar: 'http://tva3.sinaimg.cn/crop.0.0.512.512.180/8693225ajw8f2rt20ptykj20e80e8weu.jpg'
, timestamp: 1480897882000
, content: 'face[抱抱] face[心] 你好啊小美女'
}, {
username: 'Z_子晴'
, id: 108101
, avatar: 'http://tva3.sinaimg.cn/crop.0.0.512.512.180/8693225ajw8f2rt20ptykj20e80e8weu.jpg'
, timestamp: 1480897892000
, content: '你没发错吧face[微笑]'
}, {
username: 'Z_子晴'
, id: 108101
, avatar: 'http://tva3.sinaimg.cn/crop.0.0.512.512.180/8693225ajw8f2rt20ptykj20e80e8weu.jpg'
, timestamp: 1480897898000
, content: '你是谁呀亲。。我爱的是贤心!我爱的是贤心!我爱的是贤心!重要的事情要说三遍~'
}, {
username: 'Z_子晴'
, id: 108101
, avatar: 'http://tva3.sinaimg.cn/crop.0.0.512.512.180/8693225ajw8f2rt20ptykj20e80e8weu.jpg'
, timestamp: 1480897908000
, content: '注意:这些都是模拟数据,实际使用时,需将其中的模拟接口改为你的项目真实接口。\n该模版文件所在目录相对于layui.js\n/css/modules/layim/html/chatlog.html'
}]
}
//console.log(param)
var html = laytpl(LAY_tpl.value).render({
data: res.data
});
$('#LAY_view').html(html);
});
</script>
</body>
</html>

View File

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>发现</title>
<link rel="stylesheet" href="http://local.res.layui.com/layui/src/css/layui.css">
<style>
</style>
</head>
<body>
<div style="margin: 15px;">
<blockquote class="layui-elem-quote">此为自定义的【查找】页面,因需求不一,所以官方暂不提供该模版结构与样式,实际使用时,可移至该文件到你的项目中,对页面自行把控。
<br>文件所在目录相对于layui.js/css/modules/layim/html/find.html
</blockquote>
</div>
<script src="http://local.res.layui.com/layui/src/layui.js"></script>
<script>
layui.use(['layim', 'laypage'], function () {
var layim = layui.layim
, layer = layui.layer
, laytpl = layui.laytpl
, $ = layui.jquery
, laypage = layui.laypage;
//一些添加好友请求之类的交互参见文档
});
</script>
</body>
</html>

View File

@ -0,0 +1,87 @@
{
"code": 0,
"pages": 1,
"data": [
{
"id": 76,
"content": "申请添加你为好友",
"uid": 168,
"from": 166488,
"from_group": 0,
"type": 1,
"remark": "有问题要问",
"href": null,
"read": 1,
"time": "刚刚",
"user": {
"id": 166488,
"avatar": "http://q.qlogo.cn/qqapp/101235792/B704597964F9BD0DB648292D1B09F7E8/100",
"username": "李彦宏",
"sign": null
}
},
{
"id": 75,
"content": "申请添加你为好友",
"uid": 168,
"from": 347592,
"from_group": 0,
"type": 1,
"remark": "你好啊!",
"href": null,
"read": 1,
"time": "刚刚",
"user": {
"id": 347592,
"avatar": "http://q.qlogo.cn/qqapp/101235792/B78751375E0531675B1272AD994BA875/100",
"username": "麻花疼",
"sign": null
}
},
{
"id": 62,
"content": "雷军 拒绝了你的好友申请",
"uid": 168,
"from": null,
"from_group": null,
"type": 1,
"remark": null,
"href": null,
"read": 1,
"time": "10天前",
"user": {
"id": null
}
},
{
"id": 60,
"content": "马小云 已经同意你的好友申请",
"uid": 168,
"from": null,
"from_group": null,
"type": 1,
"remark": null,
"href": null,
"read": 1,
"time": "10天前",
"user": {
"id": null
}
},
{
"id": 61,
"content": "贤心 已经同意你的好友申请",
"uid": 168,
"from": null,
"from_group": null,
"type": 1,
"remark": null,
"href": null,
"read": 1,
"time": "10天前",
"user": {
"id": null
}
}
]
}

View File

@ -0,0 +1,257 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>消息盒子</title>
<link rel="stylesheet" href="../../../layui.css?v=1">
<style>
.layim-msgbox {
margin: 15px;
}
.layim-msgbox li {
position: relative;
margin-bottom: 10px;
padding: 0 130px 10px 60px;
padding-bottom: 10px;
line-height: 22px;
border-bottom: 1px dotted #e2e2e2;
}
.layim-msgbox .layim-msgbox-tips {
margin: 0;
padding: 10px 0;
border: none;
text-align: center;
color: #999;
}
.layim-msgbox .layim-msgbox-system {
padding: 0 10px 10px 10px;
}
.layim-msgbox li p span {
padding-left: 5px;
color: #999;
}
.layim-msgbox li p em {
font-style: normal;
color: #FF5722;
}
.layim-msgbox-avatar {
position: absolute;
left: 0;
top: 0;
width: 50px;
height: 50px;
}
.layim-msgbox-user {
padding-top: 5px;
}
.layim-msgbox-content {
margin-top: 3px;
}
.layim-msgbox .layui-btn-small {
padding: 0 15px;
margin-left: 5px;
}
.layim-msgbox-btn {
position: absolute;
right: 0;
top: 12px;
color: #999;
}
</style>
</head>
<body>
<ul class="layim-msgbox" id="LAY_view"></ul>
<div style="margin: 0 15px;">
<blockquote class="layui-elem-quote">注意:这些都是模拟数据,实际使用时,需将其中的模拟接口改为你的项目真实接口。
<br>该模版文件所在目录相对于layui.js/css/modules/layim/html/msgbox.html
</blockquote>
</div>
<textarea title="消息模版" id="LAY_tpl" style="display:none;">
{{# layui.each(d.data, function(index, item){
if(item.from){ }}
<li data-uid="{{ item.from }}" data-fromGroup="{{ item.from_group }}">
<a href="/u/{{ item.from }}/" target="_blank">
<img src="{{ item.user.avatar }}" class="layui-circle layim-msgbox-avatar">
</a>
<p class="layim-msgbox-user">
<a href="/u/{{ item.from }}/" target="_blank">{{ item.user.username||'' }}</a>
<span>{{ item.time }}</span>
</p>
<p class="layim-msgbox-content">
{{ item.content }}
<span>{{ item.remark ? '附言: '+item.remark : '' }}</span>
</p>
<p class="layim-msgbox-btn">
<button class="layui-btn layui-btn-small" data-type="agree">同意</button>
<button class="layui-btn layui-btn-small layui-btn-primary" data-type="refuse">拒绝</button>
</p>
</li>
{{# } else { }}
<li class="layim-msgbox-system">
<p><em>系统:</em>{{ item.content }}<span>{{ item.time }}</span></p>
</li>
{{# }
}); }}
</textarea>
<!--
上述模版采用了 laytpl 语法不了解的同学可以去看下文档http://www.layui.com/doc/modules/laytpl.html
-->
<script src="../../../../layui.js?v=1"></script>
<script>
layui.use(['layim', 'flow'], function () {
var layim = layui.layim
, layer = layui.layer
, laytpl = layui.laytpl
, $ = layui.jquery
, flow = layui.flow;
var cache = {}; //用于临时记录请求到的数据
//请求消息
var renderMsg = function (page, callback) {
//实际部署时,请将下述 getmsg.json 改为你的接口地址
$.get('getmsg.json', {
page: page || 1
}, function (res) {
if (res.code != 0) {
return layer.msg(res.msg);
}
//记录来源用户信息
layui.each(res.data, function (index, item) {
cache[item.from] = item.user;
});
callback && callback(res.data, res.pages);
});
};
//消息信息流
flow.load({
elem: '#LAY_view' //流加载容器
, isAuto: false
, end: '<li class="layim-msgbox-tips">暂无更多新消息</li>'
, done: function (page, next) { //加载下一页
renderMsg(page, function (data, pages) {
var html = laytpl(LAY_tpl.value).render({
data: data
, page: page
});
next(html, page < pages);
});
}
});
//打开页面即把消息标记为已读
/*
$.post('/message/read', {
type: 1
});
*/
//操作
var active = {
//同意
agree: function (othis) {
var li = othis.parents('li')
, uid = li.data('uid')
, from_group = li.data('fromGroup')
, user = cache[uid];
//选择分组
parent.layui.layim.setFriendGroup({
type: 'friend'
, username: user.username
, avatar: user.avatar
, group: parent.layui.layim.cache().friend //获取好友分组数据
, submit: function (group, index) {
//将好友追加到主面板
parent.layui.layim.addList({
type: 'friend'
, avatar: user.avatar //好友头像
, username: user.username //好友昵称
, groupid: group //所在的分组id
, id: uid //好友ID
, sign: user.sign //好友签名
});
parent.layer.close(index);
othis.parent().html('已同意');
//实际部署时,请开启下述注释,并改成你的接口地址
/*
$.post('/im/agreeFriend', {
uid: uid //对方用户ID
,from_group: from_group //对方设定的好友分组
,group: group //我设定的好友分组
}, function(res){
if(res.code != 0){
return layer.msg(res.msg);
}
//将好友追加到主面板
parent.layui.layim.addList({
type: 'friend'
,avatar: user.avatar //好友头像
,username: user.username //好友昵称
,groupid: group //所在的分组id
,id: uid //好友ID
,sign: user.sign //好友签名
});
parent.layer.close(index);
othis.parent().html('已同意');
});
*/
}
});
}
//拒绝
, refuse: function (othis) {
var li = othis.parents('li')
, uid = li.data('uid');
layer.confirm('确定拒绝吗?', function (index) {
$.post('/im/refuseFriend', {
uid: uid //对方用户ID
}, function (res) {
if (res.code != 0) {
return layer.msg(res.msg);
}
layer.close(index);
othis.parent().html('<em>已拒绝</em>');
});
});
}
};
$('body').on('click', '.layui-btn', function () {
var othis = $(this), type = othis.data('type');
active[type] ? active[type].call(this, othis) : '';
});
});
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

File diff suppressed because one or more lines are too long

View File

@ -106,7 +106,7 @@ body {
.layout-content {
float: left;
width: 760px;
width: 800px;
}
.layout-sidebar {
@ -250,11 +250,17 @@ body {
width: 210px;
height: 118px;
margin-bottom: 10px;
overflow: hidden;
}
.course-card .cover img {
width: 100%;
height: 100%;
transition: all 0.6s;
}
.course-card .cover img:hover {
transform: scale(1.2);
}
.course-card .title {
@ -273,6 +279,10 @@ body {
margin-right: 10px;
}
.course-card .meta span:last-child {
margin-right: 0;
}
.course-card .price {
color: red;
}
@ -839,4 +849,187 @@ body {
.login-container .link .separator {
margin: 0 15px;
color: #999;
}
.user-profile {
position: relative;
}
.user-profile .avatar {
float: left;
margin-right: 30px;
}
.user-profile .avatar img {
width: 96px;
height: 96px;
border-radius: 100px;
}
.user-profile .vip-icon {
color: orange;
}
.user-profile .info {
float: left;
}
.user-profile .info h3 {
padding-top: 5px;
margin-bottom: 10px;
}
.user-profile .info p {
margin-bottom: 10px;
color: #666;
}
.user-profile .info span {
color: #999;
margin-right: 5px;
}
.user-profile .about {
position: absolute;
top: 25px;
right: 20px;
width: 400px;
height: 70px;
padding: 10px;
color: #999;
font-size: 12px;
background-color: #f2f2f2;
}
.user-tab {
margin: 0;
}
.user-tab .layui-tab-title {
text-align: center;
border-bottom: none;
}
.user-tab .layui-tab-content {
padding: 25px 0;
}
.user-tab .loading {
text-align: center;
padding: 15px;
}
.user-tab .loading .layui-icon {
font-size: 30px;
}
.learning-course-card {
height: 230px;
}
.learning-course-card .progress {
width: 210px;
padding: 15px 0;
}
.learning-course-card .duration {
font-size: 12px;
color: #666;
}
.teacher-card {
float: left;
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;
}
.teacher-card .avatar img {
width: 96px;
height: 96px;
border-radius: 100px;
transition: 0.5s;
}
.teacher-card .avatar img:hover {
transform: rotateY(180deg);
}
.teacher-card .name {
margin-bottom: 10px;
}
.teacher-card .title {
margin-bottom: 10px;
color: #666;
font-size: 12px;
}
.my-profile-card {
text-align: center;
}
.my-profile-card .avatar {
margin-bottom: 10px;
}
.my-profile-card .avatar img {
width: 96px;
height: 96px;
border-radius: 100px;
}
.my-profile-card .name {
margin-bottom: 10px;
}
.my-menu li {
line-height: 30px;
}
.my-nav-title {
font-size: 16px;
padding-bottom: 15px;
margin-bottom: 30px;
border-bottom: 1px solid #e6e6e6;
}
.my-form {
width: 95%;
}
.security-item {
padding: 15px;
line-height: 50px;
border-bottom: 1px dashed #ccc;
}
.security-item:last-child {
border-bottom: none;
}
.security-item .icon {
margin-right: 15px;
}
.security-item .title {
margin-right: 15px;
}
.security-item .summary {
color: #666;
}
.security-item .action {
float: right;
}

View File

@ -28,6 +28,7 @@ helper.ajaxLoadHtml = function (url, target) {
$target.html(html);
$.get(url, function (html) {
$target.html(html);
element.init();
});
}