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

Merge branch 'koogua/v1.4.3' into demo

This commit is contained in:
koogua 2021-08-22 18:56:56 +08:00
commit ffda2b41aa
33 changed files with 479 additions and 141 deletions

View File

@ -1,3 +1,15 @@
### [v1.4.3](https://gitee.com/koogua/course-tencent-cloud/releases/v1.4.3)(2021-08-23)
- 优化邮件验证码
- 优化logo和favicon上传
- 优化api验证码中使用的ticket和rand
- 优化点播和直播地址获取
- 修复部分清晰度外链播放地址为空时切换卡死问题
- 增加QQ微信微博邮件电话等联系配置
- 用户控制台文章和提问列表增加删除过滤
- 去除layim在线客服
- 提高视频转码分辨率
### [v1.4.2](https://gitee.com/koogua/course-tencent-cloud/releases/v1.4.2)(2021-08-13) ### [v1.4.2](https://gitee.com/koogua/course-tencent-cloud/releases/v1.4.2)(2021-08-13)
- 后台增加转码码率配置选项 - 后台增加转码码率配置选项

View File

@ -409,4 +409,29 @@ class SettingController extends Controller
} }
} }
/**
* @Route("/contact", name="admin.setting.contact")
*/
public function contactAction()
{
$section = 'contact';
$settingService = new SettingService();
if ($this->request->isPost()) {
$data = $this->request->getPost();
$settingService->updateSettings($section, $data);
return $this->jsonSuccess(['msg' => '更新配置成功']);
} else {
$contact = $settingService->getSettings($section);
$this->view->setVar('contact', $contact);
}
}
} }

View File

@ -16,48 +16,6 @@ use App\Services\Vod as VodService;
class UploadController extends Controller class UploadController extends Controller
{ {
/**
* @Post("/site/logo", name="admin.upload.site_logo")
*/
public function uploadSiteLogoAction()
{
$service = new StorageService();
$file = $service->uploadSiteLogo();
if (!$file) {
return $this->jsonError(['msg' => '上传文件失败']);
}
$data = [
'src' => $service->getImageUrl($file->path),
'title' => $file->name,
];
return $this->jsonSuccess(['data' => $data]);
}
/**
* @Post("/site/favicon", name="admin.upload.site_favicon")
*/
public function uploadSiteFaviconAction()
{
$service = new StorageService();
$file = $service->uploadSiteFavicon();
if (!$file) {
return $this->jsonError(['msg' => '上传文件失败']);
}
$data = [
'src' => $service->getImageUrl($file->path),
'title' => $file->name,
];
return $this->jsonSuccess(['data' => $data]);
}
/** /**
* @Post("/icon/img", name="admin.upload.icon_img") * @Post("/icon/img", name="admin.upload.icon_img")
*/ */

View File

@ -1221,6 +1221,12 @@ class AuthNode extends Service
'type' => 'menu', 'type' => 'menu',
'route' => 'admin.setting.dingtalk_robot', 'route' => 'admin.setting.dingtalk_robot',
], ],
[
'id' => '5-1-16',
'title' => '联系方式',
'type' => 'menu',
'route' => 'admin.setting.contact',
],
], ],
], ],
], ],

View File

@ -56,11 +56,11 @@
$.each(formats, function (i, format) { $.each(formats, function (i, format) {
$.each(rates, function (k, rate) { $.each(rates, function (k, rate) {
if (playUrls.hasOwnProperty(format) && playUrls[format].hasOwnProperty(rate.name)) { if (playUrls.hasOwnProperty(format) && playUrls[format].hasOwnProperty(rate.name)) {
quality[k] = { quality.push({
name: rate.label, name: rate.label,
url: playUrls[format][rate.name], url: playUrls[format][rate.name],
type: 'flv', type: 'flv',
}; });
} }
}); });
}); });

View File

@ -0,0 +1,119 @@
{% extends 'templates/main.volt' %}
{% block content %}
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.setting.contact'}) }}">
<fieldset class="layui-elem-field layui-field-title">
<legend>联系方式</legend>
</fieldset>
<div class="layui-form-item">
<label class="layui-form-label">微信二维码</label>
<div class="layui-inline" style="width:40%;">
<input class="layui-input" type="text" name="wechat" placeholder="请确保存储已正确配置" value="{{ contact.wechat }}">
</div>
<div class="layui-inline">
<button class="layui-btn" type="button" id="upload-wechat">上传文件</button>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">头条二维码</label>
<div class="layui-inline" style="width:40%;">
<input class="layui-input" type="text" name="toutiao" placeholder="请确保存储已正确配置" value="{{ contact.toutiao }}">
</div>
<div class="layui-inline">
<button class="layui-btn" type="button" id="upload-toutiao">上传文件</button>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">客服QQ</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="qq" value="{{ contact.qq }}" placeholder="请前往 https://shang.qq.com/v3/widget.html 开通服务">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">微博帐号</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="weibo" value="{{ contact.weibo }}" placeholder="https://weibo.com/u/{账号}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">知乎帐号</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="zhihu" value="{{ contact.zhihu }}" placeholder="https://www.zhihu.com/people/{帐号}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">联系电话</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="phone" value="{{ contact.phone }}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">联系邮箱</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="email" value="{{ contact.email }}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">联系地址</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="address" value="{{ contact.address }}">
</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 type="button" class="kg-back layui-btn layui-btn-primary">返回</button>
</div>
</div>
</form>
{% endblock %}
{% block inline_js %}
<script>
layui.use(['jquery', 'layer', 'upload'], function () {
var $ = layui.jquery;
var upload = layui.upload;
upload.render({
elem: '#upload-wechat',
url: '/admin/upload/icon/img',
exts: 'gif|jpg|png',
before: function () {
layer.load();
},
done: function (res, index, upload) {
$('input[name=wechat]').val(res.data.src);
layer.closeAll('loading');
},
error: function (index, upload) {
layer.msg('上传文件失败', {icon: 2});
}
});
upload.render({
elem: '#upload-toutiao',
url: '/admin/upload/icon/img',
exts: 'gif|jpg|png',
before: function () {
layer.load();
},
done: function (res, index, upload) {
$('input[name=toutiao]').val(res.data.src);
layer.closeAll('loading');
},
error: function (index, upload) {
layer.msg('上传文件失败', {icon: 2});
}
});
});
</script>
{% endblock %}

View File

@ -5,15 +5,11 @@
<div class="layui-tab layui-tab-brief"> <div class="layui-tab layui-tab-brief">
<ul class="layui-tab-title kg-tab-title"> <ul class="layui-tab-title kg-tab-title">
<li class="layui-this">微聊设置</li> <li class="layui-this">微聊设置</li>
<li>在线客服</li>
</ul> </ul>
<div class="layui-tab-content"> <div class="layui-tab-content">
<div class="layui-tab-item layui-show"> <div class="layui-tab-item layui-show">
{{ partial('setting/im_main') }} {{ partial('setting/im_main') }}
</div> </div>
<div class="layui-tab-item">
{{ partial('setting/im_cs') }}
</div>
</div> </div>
</div> </div>

View File

@ -163,7 +163,7 @@
upload.render({ upload.render({
elem: '#upload-logo', elem: '#upload-logo',
url: '/admin/upload/site/logo', url: '/admin/upload/icon/img',
exts: 'gif|jpg|png', exts: 'gif|jpg|png',
before: function () { before: function () {
layer.load(); layer.load();
@ -179,7 +179,7 @@
upload.render({ upload.render({
elem: '#upload-favicon', elem: '#upload-favicon',
url: '/admin/upload/site/favicon', url: '/admin/upload/icon/img',
exts: 'gif|jpg|png|ico', exts: 'gif|jpg|png|ico',
before: function () { before: function () {
layer.load(); layer.load();

View File

@ -16,7 +16,7 @@ class PageController extends Controller
{ {
/** /**
* @Get("/{id:[0-9]+}/info", name="api.page.info") * @Get("/{id}/info", name="api.page.info")
*/ */
public function infoAction($id) public function infoAction($id)
{ {

View File

@ -7,8 +7,9 @@
namespace App\Http\Api\Controllers; namespace App\Http\Api\Controllers;
use App\Services\Logic\Verify\EmailCode as EmailCodeService; use App\Services\Logic\Verify\MailCode as MailCodeService;
use App\Services\Logic\Verify\SmsCode as SmsCodeService; use App\Services\Logic\Verify\SmsCode as SmsCodeService;
use App\Services\Logic\Verify\Ticket as TicketService;
/** /**
* @RoutePrefix("/api/verify") * @RoutePrefix("/api/verify")
@ -16,6 +17,18 @@ use App\Services\Logic\Verify\SmsCode as SmsCodeService;
class VerifyController extends Controller class VerifyController extends Controller
{ {
/**
* @Post("/ticket", name="api.verify.ticket")
*/
public function ticketAction()
{
$service = new TicketService();
$ticket = $service->handle();
return $this->jsonSuccess(['ticket' => $ticket]);
}
/** /**
* @Post("/sms/code", name="api.verify.sms_code") * @Post("/sms/code", name="api.verify.sms_code")
*/ */
@ -29,11 +42,11 @@ class VerifyController extends Controller
} }
/** /**
* @Post("/email/code", name="api.verify.email_code") * @Post("/mail/code", name="api.verify.mail_code")
*/ */
public function emailCodeAction() public function mailCodeAction()
{ {
$service = new EmailCodeService(); $service = new MailCodeService();
$service->handle(); $service->handle();

View File

@ -40,6 +40,11 @@ class Controller extends \Phalcon\Mvc\Controller
*/ */
protected $siteInfo; protected $siteInfo;
/**
* @var array
*/
protected $contactInfo;
/** /**
* @var array * @var array
*/ */
@ -83,6 +88,7 @@ class Controller extends \Phalcon\Mvc\Controller
$this->seo = $this->getSeo(); $this->seo = $this->getSeo();
$this->navs = $this->getNavs(); $this->navs = $this->getNavs();
$this->appInfo = $this->getAppInfo(); $this->appInfo = $this->getAppInfo();
$this->contactInfo = $this->getContactInfo();
$this->imInfo = $this->getImInfo(); $this->imInfo = $this->getImInfo();
$this->seo->setTitle($this->siteInfo['title']); $this->seo->setTitle($this->siteInfo['title']);
@ -92,6 +98,7 @@ class Controller extends \Phalcon\Mvc\Controller
$this->view->setVar('auth_user', $this->authUser); $this->view->setVar('auth_user', $this->authUser);
$this->view->setVar('app_info', $this->appInfo); $this->view->setVar('app_info', $this->appInfo);
$this->view->setVar('site_info', $this->siteInfo); $this->view->setVar('site_info', $this->siteInfo);
$this->view->setVar('contact_info', $this->contactInfo);
$this->view->setVar('im_info', $this->imInfo); $this->view->setVar('im_info', $this->imInfo);
} }
@ -122,6 +129,11 @@ class Controller extends \Phalcon\Mvc\Controller
return $this->getSettings('site'); return $this->getSettings('site');
} }
protected function getContactInfo()
{
return $this->getSettings('contact');
}
protected function getAppInfo() protected function getAppInfo()
{ {
return new AppInfo(); return new AppInfo();

View File

@ -7,7 +7,7 @@
namespace App\Http\Home\Controllers; namespace App\Http\Home\Controllers;
use App\Services\Logic\Verify\EmailCode as EmailCodeService; use App\Services\Logic\Verify\MailCode as MailCodeService;
use App\Services\Logic\Verify\SmsCode as SmsCodeService; use App\Services\Logic\Verify\SmsCode as SmsCodeService;
use App\Traits\Response as ResponseTrait; use App\Traits\Response as ResponseTrait;
@ -32,11 +32,11 @@ class VerifyController extends \Phalcon\Mvc\Controller
} }
/** /**
* @Post("/email/code", name="home.verify.email_code") * @Post("/mail/code", name="home.verify.mail_code")
*/ */
public function emailCodeAction() public function mailCodeAction()
{ {
$service = new EmailCodeService(); $service = new MailCodeService();
$service->handle(); $service->handle();

View File

@ -31,12 +31,9 @@ class Index extends Service
*/ */
$slides = $cache->get(); $slides = $cache->get();
if (empty($slides)) { if (empty($slides)) return [];
return [];
}
foreach ($slides as $key => $slide) { foreach ($slides as $key => $slide) {
switch ($slide['target']) { switch ($slide['target']) {
case SlideModel::TARGET_COURSE: case SlideModel::TARGET_COURSE:
$slides[$key]['url'] = $this->url->get([ $slides[$key]['url'] = $this->url->get([
@ -53,8 +50,6 @@ class Index extends Service
case SlideModel::TARGET_LINK: case SlideModel::TARGET_LINK:
$slides[$key]['url'] = $slide['content']; $slides[$key]['url'] = $slide['content'];
break; break;
default:
break;
} }
} }

View File

@ -34,9 +34,10 @@
<div class="layui-card-header">客户服务</div> <div class="layui-card-header">客户服务</div>
<div class="layui-card-body"> <div class="layui-card-body">
<p>没解决你的疑问?试试联系客服吧!</p> <p>没解决你的疑问?试试联系客服吧!</p>
{% if im_info.cs.enabled == 1 %} {% if contact_info.qq %}
{% set link_url = 'https://wpa.qq.com/msgrd?v=3&uin=%s&site=qq&menu=yes'|format(contact_info.qq) %}
<p class="center"> <p class="center">
<button class="layui-btn layui-btn-sm btn-cs">联系客服</button> <a href="{{ link_url }}" class="layui-btn layui-btn-sm">联系客服</a>
</p> </p>
{% endif %} {% endif %}
</div> </div>

View File

@ -1,11 +1,10 @@
<div class="layui-main"> <div class="layui-main">
<div class="left"> <div class="row nav">
<div class="bottom-nav">
{% for nav in navs.bottom %} {% for nav in navs.bottom %}
<a href="{{ nav.url }}" target="{{ nav.target }}">{{ nav.name }}</a> <a href="{{ nav.url }}" target="{{ nav.target }}">{{ nav.name }}</a>
{% endfor %} {% endfor %}
</div> </div>
<div class="copyright"> <div class="row copyright">
{% if site_info.copyright %} {% if site_info.copyright %}
<span>&copy; {{ site_info.copyright }}</span> <span>&copy; {{ site_info.copyright }}</span>
{% endif %} {% endif %}
@ -17,6 +16,35 @@
<a href="{{ site_info.police_link }}" target="_blank">{{ site_info.police_sn }}</a> <a href="{{ site_info.police_link }}" target="_blank">{{ site_info.police_sn }}</a>
{% endif %} {% endif %}
</div> </div>
<div class="row contact">
{% if contact_info.qq %}
{% set link_url = 'https://wpa.qq.com/msgrd?v=3&uin=%s&site=qq&menu=yes'|format(contact_info.qq) %}
<a class="qq" href="{{ link_url }}" title="客服QQ{{ contact_info.qq }}"><span class="iconfont icon-qq"></span></a>
{% endif %}
{% if contact_info.wechat %}
<a class="wechat" href="javascript:" title="微信公众号"><span class="iconfont icon-wechat"></span></a>
{% endif %}
{% if contact_info.toutiao %}
<a class="toutiao" href="javascript:" title="头条号"><span class="iconfont icon-toutiao"></span></a>
{% endif %}
{% if contact_info.weibo %}
{% set link_url = 'https://weibo.com/u/%s'|format(contact_info.weibo) %}
<a class="weibo" href="{{ link_url }}" title="微博主页"><span class="iconfont icon-weibo"></span></a>
{% endif %}
{% if contact_info.zhihu %}
{% set link_url = 'https://www.zhihu.com/people/%s'|format(contact_info.zhihu) %}
<a class="zhihu" href="{{ link_url }}" title="知乎主页"><span class="iconfont icon-zhihu"></span></a>
{% endif %}
{% if contact_info.email %}
{% set link_url = 'mailto:%s'|format(contact_info.email) %}
<a class="mail" href="{{ link_url }}" title="联系邮箱:{{ contact_info.email }}"><span class="iconfont icon-mail"></span></a>
{% endif %}
{% if contact_info.phone %}
<a class="phone" href="javascript:" title="联系电话:{{ contact_info.phone }}"><span class="iconfont icon-phone"></span></a>
{% endif %}
{% if contact_info.address %}
{% set link_url = 'https://map.baidu.com/search/%s?querytype=s&wd=%s'|format(contact_info.address,contact_info.address) %}
<a class="location" href="{{ link_url }}" title="联系地址:{{ contact_info.address }}"><span class="iconfont icon-location"></span></a>
{% endif %}
</div> </div>
<div class="right"></div>
</div> </div>

View File

@ -8,6 +8,17 @@
vip: '{{ auth_user.vip }}' vip: '{{ auth_user.vip }}'
}; };
window.contact = {
qq: '{{ contact_info.qq }}',
wechat: '{{ contact_info.wechat }}',
toutiao: '{{ contact_info.toutiao }}',
weibo: '{{ contact_info.weibo }}',
zhihu: '{{ contact_info.zhihu }}',
phone: '{{ contact_info.phone }}',
email: '{{ contact_info.email }}',
address: '{{ contact_info.address }}'
};
window.im = { window.im = {
main: { main: {
title: '{{ im_info.main.title }}', title: '{{ im_info.main.title }}',

View File

@ -13,6 +13,8 @@
{% else %} {% else %}
{{ icon_link('favicon.ico') }} {{ icon_link('favicon.ico') }}
{% endif %} {% endif %}
<link rel="preload" href="//at.alicdn.com/t/font_2760791_c83l29k7bz.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="stylesheet" href="//at.alicdn.com/t/font_2760791_c83l29k7bz.css">
{{ css_link('lib/layui/css/layui.css') }} {{ css_link('lib/layui/css/layui.css') }}
{{ css_link('home/css/common.css') }} {{ css_link('home/css/common.css') }}
{% block link_css %}{% endblock %} {% block link_css %}{% endblock %}

View File

@ -16,7 +16,7 @@ class AppInfo
protected $link = 'https://koogua.com'; protected $link = 'https://koogua.com';
protected $version = '1.4.2'; protected $version = '1.4.3';
public function __get($name) public function __get($name)
{ {

View File

@ -30,6 +30,10 @@ class ArticleFavorite extends Repository
$builder->andWhere('user_id = :user_id:', ['user_id' => $where['user_id']]); $builder->andWhere('user_id = :user_id:', ['user_id' => $where['user_id']]);
} }
if (isset($where['deleted'])) {
$builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]);
}
switch ($sort) { switch ($sort) {
default: default:
$orderBy = 'id DESC'; $orderBy = 'id DESC';

View File

@ -30,6 +30,10 @@ class QuestionFavorite extends Repository
$builder->andWhere('user_id = :user_id:', ['user_id' => $where['user_id']]); $builder->andWhere('user_id = :user_id:', ['user_id' => $where['user_id']]);
} }
if (isset($where['deleted'])) {
$builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]);
}
switch ($sort) { switch ($sort) {
default: default:
$orderBy = 'id DESC'; $orderBy = 'id DESC';

View File

@ -92,9 +92,9 @@ class ChapterVod extends Service
protected function getVodTemplates() protected function getVodTemplates()
{ {
return [ return [
'hd' => ['height' => 720, 'rate' => 1800], 'hd' => ['height' => 1080, 'rate' => 2500],
'sd' => ['height' => 540, 'rate' => 1000], 'sd' => ['height' => 720, 'rate' => 1800],
'fd' => ['height' => 360, 'rate' => 400], 'fd' => ['height' => 540, 'rate' => 1000],
]; ];
} }

View File

@ -70,6 +70,13 @@ class BasicInfo extends LogicService
$playUrls = $chapterVodService->getPlayUrls($chapter->id); $playUrls = $chapterVodService->getPlayUrls($chapter->id);
/**
*过滤播放地址为空的条目
*/
foreach ($playUrls as $key => $value) {
if (empty($value['url'])) unset($playUrls[$key]);
}
return [ return [
'id' => $chapter->id, 'id' => $chapter->id,
'title' => $chapter->title, 'title' => $chapter->title,

View File

@ -7,12 +7,12 @@
namespace App\Services\Logic\Verify; namespace App\Services\Logic\Verify;
use App\Services\Logic\Notice\Mail\Verify as VerifyMailService; use App\Services\Logic\Notice\Mail\Verify as MailVerifyService;
use App\Services\Logic\Service as LogicService; use App\Services\Logic\Service as LogicService;
use App\Validators\Captcha as CaptchaValidator; use App\Validators\Captcha as CaptchaValidator;
use App\Validators\Verify as VerifyValidator; use App\Validators\Verify as VerifyValidator;
class EmailCode extends LogicService class MailCode extends LogicService
{ {
public function handle() public function handle()
@ -27,7 +27,7 @@ class EmailCode extends LogicService
$validator->checkCode($post['ticket'], $post['rand']); $validator->checkCode($post['ticket'], $post['rand']);
$service = new VerifyMailService(); $service = new MailVerifyService();
$service->handle($post['email']); $service->handle($post['email']);
} }

View File

@ -0,0 +1,27 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Services\Logic\Verify;
use App\Services\Logic\Service as LogicService;
use App\Validators\Verify as VerifyValidator;
class Ticket extends LogicService
{
public function handle()
{
$rand = $this->request->getPost('rand', ['trim', 'string']);
$validator = new VerifyValidator();
$rand = $validator->checkRand($rand);
return $this->crypt->encryptBase64($rand);
}
}

View File

@ -119,26 +119,6 @@ class MyStorage extends Storage
return $this->putFile($key, $filename); return $this->putFile($key, $filename);
} }
/**
* 上传站点LOGO
*
* @return UploadModel|bool
*/
public function uploadSiteLogo()
{
return $this->upload('/img/icon/', self::MIME_IMAGE, UploadModel::TYPE_DEFAULT_IMG);
}
/**
* 上传站点ICON
*
* @return UploadModel|bool
*/
public function uploadSiteFavicon()
{
return $this->upload('/img/icon/', self::MIME_IMAGE, UploadModel::TYPE_DEFAULT_IMG);
}
/** /**
* 上传封面图片 * 上传封面图片
* *

View File

@ -633,15 +633,15 @@ class Vod extends Service
public function getVideoTransTemplates() public function getVideoTransTemplates()
{ {
$hlsTemplates = [ $hlsTemplates = [
100210 => ['quality' => 'fd', 'height' => 360, 'bit_rate' => 400, 'frame_rate' => 25], 100220 => ['quality' => 'fd', 'height' => 540, 'bit_rate' => 1000, 'frame_rate' => 25],
100220 => ['quality' => 'sd', 'height' => 540, 'bit_rate' => 1000, 'frame_rate' => 25], 100230 => ['quality' => 'sd', 'height' => 720, 'bit_rate' => 1800, 'frame_rate' => 25],
100230 => ['quality' => 'hd', 'height' => 720, 'bit_rate' => 1800, 'frame_rate' => 25], 100240 => ['quality' => 'hd', 'height' => 1080, 'bit_rate' => 2500, 'frame_rate' => 25],
]; ];
$mp4Templates = [ $mp4Templates = [
100010 => ['quality' => 'fd', 'height' => 360, 'bit_rate' => 400, 'frame_rate' => 25], 100020 => ['quality' => 'fd', 'height' => 540, 'bit_rate' => 1000, 'frame_rate' => 25],
100020 => ['quality' => 'sd', 'height' => 540, 'bit_rate' => 1000, 'frame_rate' => 25], 100030 => ['quality' => 'sd', 'height' => 720, 'bit_rate' => 1800, 'frame_rate' => 25],
100030 => ['quality' => 'hd', 'height' => 720, 'bit_rate' => 1800, 'frame_rate' => 25], 100040 => ['quality' => 'hd', 'height' => 360, 'bit_rate' => 2500, 'frame_rate' => 25],
]; ];
$format = $this->settings['video_format'] ?: 'hls'; $format = $this->settings['video_format'] ?: 'hls';

View File

@ -65,4 +65,28 @@ class Verify extends Validator
} }
} }
public function checkRand($rand)
{
list($time, $number) = explode('-', $rand);
if (abs($time - time()) > 300) {
throw new BadRequestException('verify.invalid_rand');
}
if ($number < 1000 || $number > 9999) {
throw new BadRequestException('verify.invalid_rand');
}
return $rand;
}
public function checkTicket($ticket, $rand)
{
$ticket = $this->crypt->decrypt($ticket);
if ($ticket != $rand) {
throw new BadRequestException('verify.invalid_ticket');
}
}
} }

View File

@ -0,0 +1,66 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
use Phinx\Migration\AbstractMigration;
final class V20210820064755 extends AbstractMigration
{
public function up()
{
$this->handleContactSetting();
}
protected function handleContactSetting()
{
$rows = [
[
'section' => 'contact',
'item_key' => 'qq',
'item_value' => '',
],
[
'section' => 'contact',
'item_key' => 'wechat',
'item_value' => '',
],
[
'section' => 'contact',
'item_key' => 'toutiao',
'item_value' => '',
],
[
'section' => 'contact',
'item_key' => 'weibo',
'item_value' => '',
],
[
'section' => 'contact',
'item_key' => 'zhihu',
'item_value' => '',
],
[
'section' => 'contact',
'item_key' => 'email',
'item_value' => '',
],
[
'section' => 'contact',
'item_key' => 'phone',
'item_value' => '',
],
[
'section' => 'contact',
'item_key' => 'address',
'item_value' => '',
],
];
$this->table('kg_setting')->insert($rows)->save();
}
}

View File

@ -233,27 +233,39 @@
background: none; background: none;
} }
#footer .row {
line-height: 18px;
margin-bottom: 15px;
}
#footer .row:last-child {
margin-bottom: 0;
}
#footer .contact {
line-height: 24px;
}
#footer span, #footer a { #footer span, #footer a {
color: #999; color: #999;
} }
#footer a:hover { #footer a:hover,
#footer .iconfont:hover {
color: #fff; color: #fff;
} }
.bottom-nav { #footer .nav a,
margin-bottom: 10px; #footer .copyright span,
line-height: 18px; #footer .copyright a,
} #footer .contact a {
.copyright {
line-height: 18px;
}
.bottom-nav a, .copyright span, .copyright a {
margin-right: 10px; margin-right: 10px;
} }
#footer .iconfont {
font-size: 20px;
}
.layout-sidebar .loading { .layout-sidebar .loading {
padding: 15px; padding: 15px;
text-align: center; text-align: center;

View File

@ -25,7 +25,7 @@ layui.use(['jquery', 'util'], function () {
postUrl = '/verify/sms/code'; postUrl = '/verify/sms/code';
} else if (isEmail($account.val())) { } else if (isEmail($account.val())) {
postData.email = $account.val(); postData.email = $account.val();
postUrl = '/verify/email/code'; postUrl = '/verify/mail/code';
} }
$.ajax({ $.ajax({
type: 'POST', type: 'POST',

View File

@ -25,11 +25,11 @@ layui.use(['jquery', 'helper'], function () {
$.each(formats, function (i, format) { $.each(formats, function (i, format) {
$.each(rates, function (k, rate) { $.each(rates, function (k, rate) {
if (playUrls.hasOwnProperty(format) && playUrls[format].hasOwnProperty(rate.name)) { if (playUrls.hasOwnProperty(format) && playUrls[format].hasOwnProperty(rate.name)) {
quality[k] = { quality.push({
name: rate.label, name: rate.label,
url: playUrls[format][rate.name], url: playUrls[format][rate.name],
type: 'flv', type: 'flv',
}; });
} }
}); });
}); });

View File

@ -22,13 +22,15 @@ layui.use(['jquery', 'helper'], function () {
$.each(rates, function (k, rate) { $.each(rates, function (k, rate) {
if (playUrls.hasOwnProperty(rate.name)) { if (playUrls.hasOwnProperty(rate.name)) {
quality[k] = { quality.push({
name: rate.label, name: rate.label,
url: playUrls[rate.name]['url'], url: playUrls[rate.name]['url'],
}; });
} }
}); });
console.log(quality)
var player = new DPlayer({ var player = new DPlayer({
container: document.getElementById('player'), container: document.getElementById('player'),
video: { video: {

View File

@ -1,16 +1,50 @@
layui.use(['helper', 'util'], function () { layui.use(['jquery', 'helper', 'util'], function () {
var helper = layui.helper; var $ = layui.jquery;
var util = layui.util; var util = layui.util;
var showQQDialog = function () {
window.open('https://wpa.qq.com/msgrd?v=3&uin=' + window.contact.qq + '&site=qq&menu=yes');
}
var showWechatCode = function () {
var content = '<div class="qrcode"><img src="' + window.contact.wechat + '" alt="扫码关注"></div>';
layer.open({
type: 1,
title: false,
closeBtn: 0,
shadeClose: true,
content: content
});
}
var showTouTiaoCode = function () {
var content = '<div class="qrcode"><img src="' + window.contact.toutiao + '" alt="扫码关注"></div>';
layer.open({
type: 1,
title: false,
closeBtn: 0,
shadeClose: true,
content: content
});
}
$('.icon-wechat').on('click', function () {
showWechatCode();
});
$('.icon-toutiao').on('click', function () {
showTouTiaoCode();
});
util.fixbar({ util.fixbar({
bar1: window.im.cs.enabled === '1' ? '&#xe626;' : false, bar1: window.contact.qq ? '&#xe676;' : false,
bar2: true, bar2: window.contact.wechat ? '&#xe677;' : false,
click: function (type) { click: function (type) {
if (type === 'bar1') { if (type === 'bar1') {
helper.cs(); showQQDialog();
} else if (type === 'bar2') { } else if (type === 'bar2') {
window.open('/help', 'help'); showWechatCode();
} }
} }
}); });