1
0
mirror of https://gitee.com/koogua/course-tencent-cloud.git synced 2025-06-24 20:06:09 +08:00

完善弹幕配置部分

This commit is contained in:
xiaochong0302 2020-07-11 20:43:26 +08:00
parent 5039b7891d
commit 3e27353b26
36 changed files with 182 additions and 92 deletions

View File

@ -8,7 +8,7 @@
<a><cite>绑定邮箱</cite></a>
</div>
<div class="account-container container">
<div class="account-wrap wrap">
<form class="layui-form account-form" method="POST" action="{{ url({'for':'web.account.update_email'}) }}">
<div class="layui-form-item">
<div class="layui-input-block">

View File

@ -8,7 +8,7 @@
<a><cite>修改密码</cite></a>
</div>
<div class="account-container container">
<div class="account-wrap wrap">
<form class="layui-form account-form" method="POST" action="{{ url({'for':'web.account.update_pwd'}) }}">
<div class="layui-form-item">
<div class="layui-input-block">

View File

@ -8,7 +8,7 @@
<a><cite>绑定手机</cite></a>
</div>
<div class="account-container container">
<div class="account-wrap wrap">
<form class="layui-form account-form" method="POST" action="{{ url({'for':'web.account.update_phone'}) }}">
<div class="layui-form-item">
<div class="layui-input-block">

View File

@ -7,7 +7,7 @@
<a><cite>重置密码</cite></a>
</div>
<div class="account-container container">
<div class="account-wrap wrap">
<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">

View File

@ -7,7 +7,7 @@
<a><cite>登录</cite></a>
</div>
<div class="login-container container">
<div class="login-wrap wrap">
<div class="layui-tab layui-tab-brief login-tab">
<ul class="layui-tab-title login-tab-title">
<li class="layui-this">密码登录</li>

View File

@ -7,7 +7,7 @@
<a><cite>注册</cite></a>
</div>
<div class="account-container container">
<div class="account-wrap wrap">
<form class="layui-form account-form" method="POST" action="{{ url({'for':'web.account.do_register'}) }}">
<div class="layui-form-item">
<div class="layui-input-block">

View File

@ -1,23 +1,25 @@
<div class="layui-card">
<div class="layui-card-header">课程目录</div>
<div class="layui-card-body">
<div class="sidebar-chapter-list">
{% for item in chapters %}
<div class="chapter-title layui-elip">{{ item.title }}</div>
<ul class="sidebar-lesson-list">
{% for lesson in item.children %}
{% set url = url({'for':'web.chapter.show','id':lesson.id}) %}
{% set active = (chapter.id == lesson.id) ? 'active' : 'normal' %}
<li class="lesson-title layui-elip">
{% if lesson.me.owned == 1 %}
<a class="{{ active }}" href="{{ url }}" title="{{ lesson.title|e }}">{{ lesson.title }}</a>
{% else %}
<span class="deny" title="{{ lesson.title|e }}">{{ lesson.title }}</span>
{% endif %}
</li>
{% endfor %}
</ul>
{% endfor %}
<div class="sidebar-chapter-wrap wrap">
<fieldset class="layui-elem-field layui-field-title">
<legend>课程目录</legend>
<div class="layui-field-box">
<div class="sidebar-chapter-list">
{% for item in chapters %}
<div class="chapter-title layui-elip">{{ item.title }}</div>
<ul class="sidebar-lesson-list">
{% for lesson in item.children %}
{% set url = url({'for':'web.chapter.show','id':lesson.id}) %}
{% set active = (chapter.id == lesson.id) ? 'active' : 'normal' %}
<li class="lesson-title layui-elip">
{% if lesson.me.owned == 1 %}
<a class="{{ active }}" href="{{ url }}" title="{{ lesson.title|e }}">{{ lesson.title }}</a>
{% else %}
<span class="deny" title="{{ lesson.title|e }}">{{ lesson.title }}</span>
{% endif %}
</li>
{% endfor %}
</ul>
{% endfor %}
</div>
</div>
</div>
</div>
</fieldset>
</div>

View File

@ -17,12 +17,12 @@
<div class="layout-main">
<div class="layout-content">
<div class="player-container container">
<div class="player-wrap wrap">
<div id=player"></div>
</div>
</div>
<div class="layout-sidebar">
<div class="chat-container">
<div class="chat-wrap">
<div class="layui-tab layui-tab-brief user-tab">
<ul class="layui-tab-title">
<li class="layui-this">讨论</li>

View File

@ -13,7 +13,7 @@
<div class="layout-main clearfix">
<div class="layout-content">
<div class="read-info container">{{ chapter.content }}</div>
<div class="read-info wrap">{{ chapter.content }}</div>
</div>
<div class="layout-sidebar">
{{ partial('chapter/menu') }}

View File

@ -14,14 +14,14 @@
<div class="layout-main clearfix">
<div class="layout-content">
<div class="player-container container">
<div class="player-wrap wrap">
<div id="player"></div>
<div id="danmu"></div>
</div>
<div class="danmu-action container">
<form class="layui-form" action="{{ url({'for':'web.danmu.create'}) }}">
<div class="layui-input-inline" style="width: 100px;">
<input type="checkbox" name="status" title="弹幕" checked="checked" lay-filter="danmu.status">
<div class="danmu-action-wrap wrap">
<form class="layui-form" lay-filter="danmu.form" action="{{ url({'for':'web.danmu.create'}) }}">
<div class="layui-input-inline" style="width: 50px;">
<a href="javascript:" class="layui-icon layui-icon-set icon-danmu-set"></a>
</div>
<div class="layui-input-inline" style="width: 655px;">
{% if auth_user.id > 0 %}
@ -39,6 +39,52 @@
</div>
</div>
<div id="my-danmu-set" style="display:none;">
<form class="layui-form" lay-filter="danmu.form.set" style="padding:20px 0;">
<div class="layui-form-item">
<label class="layui-form-label">显示弹幕</label>
<div class="layui-input-block">
<input type="checkbox" name="danmu.status" lay-filter="danmu.status" lay-skin="switch" lay-text="是|否" checked="checked">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">透明度</label>
<div class="layui-input-block">
<input type="radio" name="danmu.opacity" lay-filter="danmu.opacity" value="1" title="0" checked="checked">
<input type="radio" name="danmu.opacity" lay-filter="danmu.opacity" value="0.75" title="25%">
<input type="radio" name="danmu.opacity" lay-filter="danmu.opacity" value="0.5" title="50%">
<input type="radio" name="danmu.opacity" lay-filter="danmu.opacity" value="0.25" title="75%">
<input type="radio" name="danmu.opacity" lay-filter="danmu.opacity" value="0" title="100%">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">颜色</label>
<div class="layui-input-block">
<input type="radio" name="danmu.color" value="white" title="白" checked="checked">
<input type="radio" name="danmu.color" value="red" title="红">
<input type="radio" name="danmu.color" value="orange" title="黄">
<input type="radio" name="danmu.color" value="blue" title="蓝">
<input type="radio" name="danmu.color" value="green" title="绿">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">位置</label>
<div class="layui-input-block">
<input type="radio" name="danmu.position" value="0" title="滚动" checked="checked">
<input type="radio" name="danmu.position" value="1" title="顶部">
<input type="radio" name="danmu.position" value="2" title="底部">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">字号</label>
<div class="layui-input-block">
<input type="radio" name="danmu.size" value="0" title="小" checked="checked">
<input type="radio" name="danmu.size" value="1" title="大">
</div>
</div>
</form>
</div>
<div class="layui-hide">
<input type="hidden" name="chapter.id" value="{{ chapter.id }}">
<input type="hidden" name="chapter.position" value="{{ chapter.me.position }}">

View File

@ -2,7 +2,7 @@
<span class="layui-icon layui-icon-up"></span>
</div>
<div class="course-filter container">
<div class="course-filter wrap">
<div class="filter-group">
<div class="title">方向</div>
<div class="content">
@ -47,7 +47,7 @@
</div>
</div>
<div class="course-sort container">
<div class="course-sort wrap">
{% set sort_val = request.get('sort','trim','score') %}
{% for sort in sorts %}
{% set class = sort_val == sort.id ? 'layui-btn layui-btn-xs' : 'none' %}

View File

@ -1,5 +1,5 @@
{% if course.me.owned == 0 and course.market_price > 0 %}
<div class="sidebar-order container">
<div class="sidebar-order wrap">
<div class="order">
{% set order_url = url({'for':'web.order.confirm'},{'item_id':course.id,'item_type':'course'}) %}
<a class="layui-btn layui-btn-fluid layui-bg-red" href="{{ order_url }}">立即购买</a>

View File

@ -14,7 +14,7 @@
</span>
</div>
<div class="course-meta container clearfix">
<div class="course-meta wrap clearfix">
{{ partial('course/meta') }}
</div>
@ -25,7 +25,7 @@
{% set show_tab_reviews = course.review_count > 0 ? 1 : 0 %}
<div class="layout-content">
<div class="container">
<div class="wrap">
<div class="layui-tab layui-tab-brief course-tab">
<ul class="layui-tab-title">
<li class="layui-this">详情</li>

View File

@ -2,7 +2,7 @@
{% block content %}
<div class="page-info container">
<div class="page-info wrap">
<fieldset class="layui-elem-field layui-field-title">
<legend>帮助中心</legend>
<div class="layui-field-box">

View File

@ -2,7 +2,7 @@
{% block content %}
<div class="page-info container">
<div class="page-info wrap">
<fieldset class="layui-elem-field layui-field-title">
<legend>{{ help.title }}</legend>
<div class="layui-field-box page-content">

View File

@ -2,7 +2,7 @@
{% block content %}
<div class="im-search-container">
<div class="im-search-wrap">
<div class="im-search">
<form class="layui-form" method="get" action="{{ url({'for':'web.im.search'}) }}">
<input class="layui-input" type="text" name="query" placeholder="请输入关键字...">

View File

@ -31,7 +31,7 @@
</div>
{%- endmacro %}
<div class="index-container index-carousel container">
<div class="index-wrap index-carousel wrap">
<div class="layui-carousel" id="carousel">
<div class="carousel" carousel-item>
{% for slide in slides %}
@ -45,21 +45,21 @@
</div>
</div>
<div class="index-container container">
<div class="index-wrap wrap">
<div class="header">新上课程</div>
<div class="content">
{{ category_courses(new_courses) }}
</div>
</div>
<div class="index-container container">
<div class="index-wrap wrap">
<div class="header">免费课程</div>
<div class="content">
{{ category_courses(free_courses) }}
</div>
</div>
<div class="index-container container">
<div class="index-wrap wrap">
<div class="header">会员课程</div>
<div class="content">
{{ category_courses(vip_courses) }}

View File

@ -9,7 +9,7 @@
<div class="layout-main">
<div class="layout-sidebar">{{ partial('my/menu') }}</div>
<div class="layout-content">
<div class="container">
<div class="wrap">
<div class="my-nav-title">账号安全</div>
<div class="security-item-list">
<div class="security-item">

View File

@ -7,7 +7,7 @@
{% endif %}
{%- endmacro %}
<div class="my-profile-card container">
<div class="my-profile-card wrap">
<div class="avatar">
<a href="javascript:"><img src="{{ auth_user.avatar }}" alt="{{ auth_user.name }}"></a>
</div>

View File

@ -11,7 +11,7 @@
<a><cite>我的订单</cite></a>
</div>
<div class="container">
<div class="wrap">
<div class="order-filter">
{% set status = request.get('status','trim','all') %}
{% for key,value in status_types %}

View File

@ -5,7 +5,7 @@
<div class="layout-main">
<div class="layout-sidebar">{{ partial('my/menu') }}</div>
<div class="layout-content">
<div class="container">
<div class="wrap">
<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">

View File

@ -11,7 +11,7 @@
<a><cite>我的退款</cite></a>
</div>
<div class="container">
<div class="wrap">
<div class="order-filter">
{% set status = request.get('status','trim','all') %}
{% for key,value in status_types %}

View File

@ -63,7 +63,7 @@
<a><cite>确认订单</cite></a>
</div>
<div class="cart-item-list container">
<div class="cart-item-list wrap">
{% if confirm.item_type == 'course' %}
{% set course = confirm.item_info.course %}
{{ cart_course_card(course, auth_user) }}
@ -79,7 +79,7 @@
{% endif %}
</div>
<div class="cart-stats container clearfix">
<div class="cart-stats wrap clearfix">
<div class="info">
商品总价:<span class="amount">{{ '¥%0.2f'|format(confirm.total_amount) }}</span>
优惠金额:<span class="amount">{{ '¥%0.2f'|format(confirm.discount_amount) }}</span>

View File

@ -11,7 +11,7 @@
<a><cite>{{ order.subject }}</cite></a>
</div>
<div class="container">
<div class="wrap">
<table class="layui-table kg-table order-table" lay-size="lg">
<tr>
<td>基本信息</td>

View File

@ -7,7 +7,7 @@
<a><cite>支付订单</cite></a>
</div>
<div class="payment container">
<div class="payment wrap">
<div class="header">
订单名称:<span>{{ order.subject }}</span>
订单编号:<span>{{ order.sn }}</span>

View File

@ -2,7 +2,7 @@
{% block content %}
<div class="page-info container">
<div class="page-info wrap">
<fieldset class="layui-elem-field layui-field-title">
<legend>{{ page.title }}</legend>
<div class="layui-field-box page-content">

View File

@ -31,7 +31,7 @@
<a><cite>{{ order.subject }}</cite></a>
</div>
<div class="container">
<div class="wrap">
<table class="layui-table kg-table order-table" lay-size="lg">
<tr>
<td>订单编号:{{ order.sn }}</td>

View File

@ -11,7 +11,7 @@
<a><cite>{{ refund.subject }}</cite></a>
</div>
<div class="container">
<div class="wrap">
<table class="layui-table kg-table order-table" lay-size="lg">
<tr>
<td>退款项目</td>

View File

@ -16,7 +16,7 @@
<div class="layout-main clearfix">
<div class="layout-content">
{% if pager.total_pages > 0 %}
<div class="container">
<div class="wrap">
{% if type == 'course' %}
{{ partial('search/content_course') }}
{% elseif type == 'other' %}
@ -25,7 +25,7 @@
</div>
{{ partial('partials/pager') }}
{% else %}
<div class="search-empty container">
<div class="search-empty wrap">
<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

@ -6,7 +6,7 @@
{% set vip_flag = user.vip ? '<i class="layui-icon layui-icon-diamond vip-icon"></i>' : '' %}
<div class="user-profile container clearfix">
<div class="user-profile wrap clearfix">
<div class="avatar">
<img src="{{ user.avatar }}" alt="{{ user.name }}">
</div>
@ -24,7 +24,7 @@
{% set favorites_url = url({'for':'web.user.favorites','id':user.id},{'limit':12}) %}
{% set friends_url = url({'for':'web.user.friends','id':user.id},{'limit':12}) %}
<div class="tab-container">
<div class="tab-wrap">
<div class="layui-tab layui-tab-brief user-tab">
<ul class="layui-tab-title">
<li class="layui-this">课程</li>

View File

@ -4,7 +4,7 @@
<div class="vip-header">会员权益</div>
<div class="vip-reason-list container">
<div class="vip-reason-list wrap">
<span class="layui-badge reason-badge">好课畅学</span>
<span class="layui-badge reason-badge">会员折扣</span>
<span class="layui-badge reason-badge">高清视频</span>
@ -33,7 +33,7 @@
{% set courses_url = url({'for':'web.vip.courses'},{'limit':12}) %}
{% set users_url = url({'for':'web.vip.users'},{'limit':12}) %}
<div class="vip-tab-container">
<div class="vip-tab-wrap">
<div class="layui-tab layui-tab-brief user-tab">
<ul class="layui-tab-title">
<li class="layui-this">课程</li>

View File

@ -155,7 +155,7 @@ class Danmu extends Model
];
}
public static function posTypes()
public static function positionTypes()
{
return [
self::POSITION_MOVE => '滚动',
@ -175,7 +175,7 @@ class Danmu extends Model
];
}
public static function randPos()
public static function randPosition()
{
$types = self::positionTypes();

View File

@ -33,14 +33,15 @@ class DanmuCreate extends FrontendService
$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['user_id'] = $user->id;
$data['position'] = DanmuModel::POSITION_MOVE;
$data['color'] = DanmuModel::COLOR_WHITE;
$data['size'] = DanmuModel::SIZE_SMALL;
$data['published'] = 1;
$danmu->create($data);

View File

@ -46,6 +46,17 @@ class Danmu extends Validator
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();

View File

@ -36,7 +36,7 @@
margin-bottom: 20px;
}
.container {
.wrap {
padding: 20px;
margin-bottom: 20px;
background-color: #fff;
@ -138,19 +138,19 @@
margin-bottom: 15px;
}
.index-container .layui-tab {
.index-wrap .layui-tab {
margin-bottom: 0;
}
.index-container .layui-tab-title {
.index-wrap .layui-tab-title {
border: none;
}
.index-container .layui-tab-content {
.index-wrap .layui-tab-content {
padding: 20px 0 0 0;
}
.index-container .header {
.index-wrap .header {
text-align: center;
font-size: 18px;
padding-bottom: 15px;
@ -735,6 +735,10 @@
margin-right: 10px;
}
.sidebar-chapter-wrap .layui-field-title legend {
text-align: center;
}
.sidebar-chapter-list::-webkit-scrollbar {
width: 5px;
}
@ -789,13 +793,13 @@
font-size: 12px;
}
.player-container {
.player-wrap {
position: relative;
width: 760px;
height: 428px;
}
.chat-container {
.chat-wrap {
padding: 10px 20px 20px 20px;
background-color: white;
}
@ -1050,7 +1054,7 @@
text-align: center;
}
.account-container {
.account-wrap {
padding-top: 40px;
padding-bottom: 30px;
}
@ -1091,17 +1095,17 @@
padding-top: 30px;
}
.login-container .link {
.login-wrap .link {
margin-bottom: 30px;
font-size: 12px;
text-align: center;
}
.login-container .link a {
.login-wrap .link a {
color: #999;
}
.login-container .link .separator {
.login-wrap .link .separator {
margin: 0 15px;
color: #999;
}
@ -1346,7 +1350,7 @@
margin-right: 8px;
}
.im-search-container {
.im-search-wrap {
padding: 20px;
background-color: #f2f2f2;
}

View File

@ -1,7 +1,8 @@
layui.use(['jquery', 'form', 'layer', 'helper'], function () {
layui.use(['jquery', 'form', 'slider', 'layer', 'helper'], function () {
var $ = layui.jquery;
var form = layui.form;
var slider = layui.slider;
var layer = layui.layer;
var helper = layui.helper;
@ -16,26 +17,29 @@ layui.use(['jquery', 'form', 'layer', 'helper'], function () {
var danmuListUrl = $('input[name="chapter.danmu_url"]').val();
var playUrls = JSON.parse($('input[name="chapter.play_urls"]').val());
var $danmuText = $('input[name="danmu.text"]');
var $danmuColor = $('input[name="danmu.color"]');
var $danmuSize = $('input[name="danmu.size"]');
var $danmuPosition = $('input[name="danmu.position"]');
var options = {
var playerOptions = {
autoplay: false,
width: 760,
height: 428
};
if (playUrls.od) {
options.m3u8 = playUrls.od.url;
playerOptions.m3u8 = playUrls.od.url;
}
if (playUrls.hd) {
options.m3u8_hd = playUrls.hd.url;
playerOptions.m3u8_hd = playUrls.hd.url;
}
if (playUrls.sd) {
options.m3u8_sd = playUrls.sd.url;
playerOptions.m3u8_sd = playUrls.sd.url;
}
options.listener = function (msg) {
playerOptions.listener = function (msg) {
if (msg.type === 'play') {
play();
} else if (msg.type === 'pause') {
@ -45,7 +49,7 @@ layui.use(['jquery', 'form', 'layer', 'helper'], function () {
}
};
var player = new TcPlayer('player', options);
var player = new TcPlayer('player', playerOptions);
var position = parseInt(lastPosition);
@ -65,7 +69,11 @@ layui.use(['jquery', 'form', 'layer', 'helper'], function () {
initDanmu();
form.on('checkbox(danmu.status)', function (data) {
$('.icon-danmu-set').on('click', function () {
showMyDanmuSet();
});
form.on('switch(danmu.status)', function (data) {
if (data.elem.checked) {
$('#danmu').danmu('setOpacity', 1);
} else {
@ -73,12 +81,21 @@ layui.use(['jquery', 'form', 'layer', 'helper'], function () {
}
});
form.on('radio(danmu.opacity)', function (data) {
$('#danmu').danmu('setOpacity', parseFloat(data.value));
});
form.on('submit(danmu.send)', function (data) {
var setFormData = form.val('danmu.form.set');
var formData = form.val('danmu.form');
$.ajax({
type: 'POST',
url: data.form.action,
data: {
text: $danmuText.val(),
text: formData['danmu.text'],
color: setFormData['danmu.color'],
size: setFormData['danmu.size'],
position: setFormData['danmu.position'],
time: player.currentTime(),
chapter_id: chapterId
},
@ -150,6 +167,15 @@ layui.use(['jquery', 'form', 'layer', 'helper'], function () {
}
}
function showMyDanmuSet() {
layer.open({
type: 1,
title: '弹幕设置',
area: '600px',
content: $('#my-danmu-set')
});
}
function startDanmu() {
$('#danmu').danmu('danmuResume');
}