From d9016669e35e9f5611a8924c5f85c0a303a3e622 Mon Sep 17 00:00:00 2001 From: xiaochong0302 Date: Sat, 12 Sep 2020 19:57:28 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Caches/Cache.php | 2 +- app/Caches/Counter.php | 2 +- app/Console/Tasks/CleanSessionTask.php | 2 +- app/Console/Tasks/LiveNotifyTask.php | 2 +- app/Console/Tasks/SyncCourseIndexTask.php | 2 +- app/Console/Tasks/SyncGroupIndexTask.php | 2 +- app/Console/Tasks/SyncLearningTask.php | 2 +- app/Console/Tasks/SyncUserIndexTask.php | 2 +- app/Console/Tasks/Task.php | 12 ++- app/Console/Tasks/UpgradeTask.php | 4 +- app/Http/Admin/Views/nav/edit.volt | 4 +- app/Http/Admin/Views/setting/pay_wxpay.volt | 8 +- app/Http/Admin/Views/setting/site.volt | 31 +++++-- .../Desktop/Controllers/ChapterController.php | 14 +++- app/Http/Desktop/Controllers/Controller.php | 8 +- .../Desktop/Controllers/LiveController.php | 12 +++ app/Http/Desktop/Services/Live.php | 28 +++---- app/Http/Desktop/Views/chapter/live.volt | 83 ++++--------------- .../Desktop/Views/chapter/live_active.volt | 80 ++++++++++++++++++ .../Desktop/Views/chapter/live_forbid.volt | 15 ++++ .../Desktop/Views/chapter/live_inactive.volt | 42 ++++++++++ app/Http/Desktop/Views/templates/main.volt | 4 +- app/Library/Helper.php | 8 +- app/Library/Logger.php | 8 +- app/Models/Chapter.php | 2 +- app/Services/Auth/Api.php | 13 +-- .../Frontend/Chapter/BasicInfoTrait.php | 2 + .../{Chapter => }/ChapterLiveTrait.php | 2 +- app/Services/Frontend/ChapterTrait.php | 21 +++++ .../Frontend/Teaching/LivePushUrl.php | 2 +- app/Services/LiveNotify.php | 8 +- app/Services/Pay/AlipayGateway.php | 12 +-- app/Services/Pay/WxpayGateway.php | 20 +++-- app/Services/Service.php | 12 ++- app/Services/Syncer/CourseIndex.php | 26 ++---- app/Services/Syncer/GroupIndex.php | 26 ++---- app/Services/Syncer/Learning.php | 34 +++----- app/Services/Syncer/UserIndex.php | 26 ++---- app/Services/Throttle.php | 15 ++-- app/Services/Verify.php | 2 +- app/Validators/Chapter.php | 39 +++++++++ app/Validators/ChapterLive.php | 11 +-- bootstrap/Helper.php | 28 ++++--- config/alipay/.gitignore | 2 + config/cert/alipay/.gitignore | 2 - config/cert/wxpay/.gitignore | 2 - config/wxpay/.gitignore | 2 + public/static/desktop/css/common.css | 28 +++++++ .../desktop/js/chapter.live.countdown.js | 32 +++++++ 49 files changed, 470 insertions(+), 276 deletions(-) create mode 100644 app/Http/Desktop/Views/chapter/live_active.volt create mode 100644 app/Http/Desktop/Views/chapter/live_forbid.volt create mode 100644 app/Http/Desktop/Views/chapter/live_inactive.volt rename app/Services/Frontend/{Chapter => }/ChapterLiveTrait.php (74%) create mode 100644 config/alipay/.gitignore delete mode 100644 config/cert/alipay/.gitignore delete mode 100644 config/cert/wxpay/.gitignore create mode 100644 config/wxpay/.gitignore create mode 100644 public/static/desktop/js/chapter.live.countdown.js diff --git a/app/Caches/Cache.php b/app/Caches/Cache.php index c832247c..f0b2cee4 100644 --- a/app/Caches/Cache.php +++ b/app/Caches/Cache.php @@ -15,7 +15,7 @@ abstract class Cache extends Component public function __construct() { - $this->cache = $this->getDI()->get('cache'); + $this->cache = $this->getDI()->getShared('cache'); } /** diff --git a/app/Caches/Counter.php b/app/Caches/Counter.php index 7c2dcbca..ad52c178 100644 --- a/app/Caches/Counter.php +++ b/app/Caches/Counter.php @@ -20,7 +20,7 @@ abstract class Counter extends Component public function __construct() { - $this->cache = $this->getDI()->get('cache'); + $this->cache = $this->getDI()->getShared('cache'); $this->redis = $this->cache->getRedis(); } diff --git a/app/Console/Tasks/CleanSessionTask.php b/app/Console/Tasks/CleanSessionTask.php index 53b6f1f8..fb27ddef 100644 --- a/app/Console/Tasks/CleanSessionTask.php +++ b/app/Console/Tasks/CleanSessionTask.php @@ -9,7 +9,7 @@ class CleanSessionTask extends Task { $config = $this->getConfig(); $cache = $this->getCache(); - $redis = $cache->getRedis(); + $redis = $this->getRedis(); $redis->select($config->path('session.db')); diff --git a/app/Console/Tasks/LiveNotifyTask.php b/app/Console/Tasks/LiveNotifyTask.php index abd33a2a..5dd5b542 100644 --- a/app/Console/Tasks/LiveNotifyTask.php +++ b/app/Console/Tasks/LiveNotifyTask.php @@ -14,7 +14,7 @@ class LiveNotifyTask extends Task { $cache = $this->getCache(); - $redis = $cache->getRedis(); + $redis = $this->getRedis(); $service = new LiveNotifyService(); diff --git a/app/Console/Tasks/SyncCourseIndexTask.php b/app/Console/Tasks/SyncCourseIndexTask.php index a3b9f8cc..abbe3b5b 100644 --- a/app/Console/Tasks/SyncCourseIndexTask.php +++ b/app/Console/Tasks/SyncCourseIndexTask.php @@ -14,7 +14,7 @@ class SyncCourseIndexTask extends Task { $cache = $this->getCache(); - $redis = $cache->getRedis(); + $redis = $this->getRedis(); $key = $this->getSyncKey(); diff --git a/app/Console/Tasks/SyncGroupIndexTask.php b/app/Console/Tasks/SyncGroupIndexTask.php index 2f33e9b6..65ead9a9 100644 --- a/app/Console/Tasks/SyncGroupIndexTask.php +++ b/app/Console/Tasks/SyncGroupIndexTask.php @@ -14,7 +14,7 @@ class SyncGroupIndexTask extends Task { $cache = $this->getCache(); - $redis = $cache->getRedis(); + $redis = $this->getRedis(); $key = $this->getSyncKey(); diff --git a/app/Console/Tasks/SyncLearningTask.php b/app/Console/Tasks/SyncLearningTask.php index 5c82b879..cac1e4dc 100644 --- a/app/Console/Tasks/SyncLearningTask.php +++ b/app/Console/Tasks/SyncLearningTask.php @@ -18,7 +18,7 @@ class SyncLearningTask extends Task { $cache = $this->getCache(); - $redis = $cache->getRedis(); + $redis = $this->getRedis(); $syncer = new LearningSyncer(); diff --git a/app/Console/Tasks/SyncUserIndexTask.php b/app/Console/Tasks/SyncUserIndexTask.php index 9ddb2fb4..b8cb5669 100644 --- a/app/Console/Tasks/SyncUserIndexTask.php +++ b/app/Console/Tasks/SyncUserIndexTask.php @@ -14,7 +14,7 @@ class SyncUserIndexTask extends Task { $cache = $this->getCache(); - $redis = $cache->getRedis(); + $redis = $this->getRedis(); $key = $this->getSyncKey(); diff --git a/app/Console/Tasks/Task.php b/app/Console/Tasks/Task.php index b2b8cc79..44f9e1d4 100644 --- a/app/Console/Tasks/Task.php +++ b/app/Console/Tasks/Task.php @@ -16,7 +16,7 @@ class Task extends \Phalcon\Cli\Task */ public function getConfig() { - return $this->getDI()->get('config'); + return $this->getDI()->getShared('config'); } /** @@ -24,7 +24,15 @@ class Task extends \Phalcon\Cli\Task */ public function getCache() { - return $this->getDI()->get('cache'); + return $this->getDI()->getShared('cache'); + } + + /** + * @return \Redis + */ + public function getRedis() + { + return $this->getCache()->getRedis(); } /** diff --git a/app/Console/Tasks/UpgradeTask.php b/app/Console/Tasks/UpgradeTask.php index 913696b1..a8600332 100644 --- a/app/Console/Tasks/UpgradeTask.php +++ b/app/Console/Tasks/UpgradeTask.php @@ -44,7 +44,7 @@ class UpgradeTask extends Task { $config = $this->getConfig(); $cache = $this->getCache(); - $redis = $cache->getRedis(); + $redis = $this->getRedis(); $dbIndex = $config->path('annotation.db'); $statsKey = $config->path('annotation.statsKey'); @@ -75,7 +75,7 @@ class UpgradeTask extends Task { $config = $this->getConfig(); $cache = $this->getCache(); - $redis = $cache->getRedis(); + $redis = $this->getRedis(); $dbIndex = $config->path('metadata.db'); $statsKey = $config->path('metadata.statsKey'); diff --git a/app/Http/Admin/Views/nav/edit.volt b/app/Http/Admin/Views/nav/edit.volt index cd970355..60ad58ad 100644 --- a/app/Http/Admin/Views/nav/edit.volt +++ b/app/Http/Admin/Views/nav/edit.volt @@ -27,8 +27,8 @@
- - + +
diff --git a/app/Http/Admin/Views/setting/pay_wxpay.volt b/app/Http/Admin/Views/setting/pay_wxpay.volt index 57cca245..3cea4cdd 100644 --- a/app/Http/Admin/Views/setting/pay_wxpay.volt +++ b/app/Http/Admin/Views/setting/pay_wxpay.volt @@ -7,19 +7,19 @@
- +
- +
- +
- +
diff --git a/app/Http/Admin/Views/setting/site.volt b/app/Http/Admin/Views/setting/site.volt index 4443f487..1b474648 100644 --- a/app/Http/Admin/Views/setting/site.volt +++ b/app/Http/Admin/Views/setting/site.volt @@ -2,7 +2,8 @@ {% block content %} - {% set closed_tips_display = site.enabled == 0 ? 'display:block' : 'display:none' %} + {% set closed_tips_display = site.status == 'closed' ? 'display:block' : 'display:none' %} + {% set analytics_script_display = site.analytics_enabled == 1 ? 'display:block' : 'display:none' %}
@@ -11,8 +12,8 @@
- - + +
@@ -89,9 +90,18 @@
- +
- + + +
+
+
+
+ +
+ +
@@ -117,7 +127,16 @@ form.on('radio(status)', function (data) { var block = $('#closed-tips-block'); - if (data.value === '0') { + if (data.value === 'closed') { + block.show(); + } else { + block.hide(); + } + }); + + form.on('radio(analytics_enabled)', function (data) { + var block = $('#analytics-script-block'); + if (data.value === '1') { block.show(); } else { block.hide(); diff --git a/app/Http/Desktop/Controllers/ChapterController.php b/app/Http/Desktop/Controllers/ChapterController.php index b575881a..03fbe309 100644 --- a/app/Http/Desktop/Controllers/ChapterController.php +++ b/app/Http/Desktop/Controllers/ChapterController.php @@ -2,6 +2,7 @@ namespace App\Http\Desktop\Controllers; +use App\Models\ChapterLive as LiveModel; use App\Models\Course as CourseModel; use App\Services\Frontend\Chapter\ChapterInfo as ChapterInfoService; use App\Services\Frontend\Chapter\ChapterLike as ChapterLikeService; @@ -38,12 +39,21 @@ class ChapterController extends Controller $catalog = $service->handle($chapter['course']['id']); $this->seo->prependTitle(['章节', $chapter['title'], $chapter['course']['title']]); - $this->seo->setDescription($chapter['summary']); + + if (!empty($chapter['summary'])) { + $this->seo->setDescription($chapter['summary']); + } if ($chapter['model'] == CourseModel::MODEL_VOD) { $this->view->pick('chapter/vod'); } elseif ($chapter['model'] == CourseModel::MODEL_LIVE) { - $this->view->pick('chapter/live'); + if ($chapter['status'] == LiveModel::STATUS_ACTIVE) { + $this->view->pick('chapter/live_active'); + } elseif ($chapter['status'] == LiveModel::STATUS_INACTIVE) { + $this->view->pick('chapter/live_inactive'); + } elseif ($chapter['status'] == LiveModel::STATUS_FORBID) { + $this->view->pick('chapter/live_forbid'); + } } elseif ($chapter['model'] == CourseModel::MODEL_READ) { $this->view->pick('chapter/read'); } diff --git a/app/Http/Desktop/Controllers/Controller.php b/app/Http/Desktop/Controllers/Controller.php index add4d228..d91cd7ca 100644 --- a/app/Http/Desktop/Controllers/Controller.php +++ b/app/Http/Desktop/Controllers/Controller.php @@ -60,7 +60,11 @@ class Controller extends \Phalcon\Mvc\Controller $this->checkCsrfToken(); } - $this->checkRateLimit(); + $config = $this->getConfig(); + + if ($config->path('throttle.enabled')) { + $this->checkRateLimit(); + } return true; } @@ -149,7 +153,7 @@ class Controller extends \Phalcon\Mvc\Controller protected function checkSiteStatus() { - if ($this->siteInfo['enabled'] == 0) { + if ($this->siteInfo['status'] == 'closed') { $this->dispatcher->forward([ 'controller' => 'error', 'action' => 'maintain', diff --git a/app/Http/Desktop/Controllers/LiveController.php b/app/Http/Desktop/Controllers/LiveController.php index dbfb011c..9ba31814 100644 --- a/app/Http/Desktop/Controllers/LiveController.php +++ b/app/Http/Desktop/Controllers/LiveController.php @@ -54,6 +54,18 @@ class LiveController extends Controller return $this->jsonSuccess($stats); } + /** + * @Get("/{id:[0-9]+}/status", name="desktop.live.status") + */ + public function statusAction($id) + { + $service = new LiveService(); + + $status = $service->getStatus($id); + + return $this->jsonSuccess(['status' => $status]); + } + /** * @Post("/{id:[0-9]+}/user/bind", name="desktop.live.bind_user") */ diff --git a/app/Http/Desktop/Services/Live.php b/app/Http/Desktop/Services/Live.php index 0b43410f..c6c7a1b7 100644 --- a/app/Http/Desktop/Services/Live.php +++ b/app/Http/Desktop/Services/Live.php @@ -2,7 +2,6 @@ namespace App\Http\Desktop\Services; -use App\Library\Cache\Backend\Redis as RedisCache; use App\Services\Frontend\ChapterTrait; use GatewayClient\Gateway; @@ -32,6 +31,13 @@ class Live extends Service return $result; } + public function getStatus($id) + { + $chapterLive = $this->checkChapterLive($id); + + return $chapterLive->status; + } + public function getStats($id) { $chapter = $this->checkChapter($id); @@ -84,7 +90,7 @@ class Live extends Service public function sendMessage($id) { - $chapter = $this->checkChapterCache($id); + $chapter = $this->checkChapter($id); $user = $this->getLoginUser(); @@ -114,7 +120,7 @@ class Live extends Service $redis = $this->getRedis(); - $key = $this->getRedisListKey($id); + $key = $this->getRecentChatKey($id); $redis->lPush($key, $encodeMessage); @@ -125,11 +131,6 @@ class Live extends Service return $message; } - protected function getGroupName($id) - { - return "live_{$id}"; - } - protected function getRegisterAddress() { $config = $this->getConfig(); @@ -139,17 +140,12 @@ class Live extends Service protected function getRecentChatKey($id) { - return "live_recent_chat:{$id}"; + return "chapter_recent_chat:{$id}"; } - protected function getRedis() + protected function getGroupName($id) { - /** - * @var RedisCache $cache - */ - $cache = $this->getDI()->get('cache'); - - return $cache->getRedis(); + return "chapter_{$id}"; } } diff --git a/app/Http/Desktop/Views/chapter/live.volt b/app/Http/Desktop/Views/chapter/live.volt index 05831875..b95476ee 100644 --- a/app/Http/Desktop/Views/chapter/live.volt +++ b/app/Http/Desktop/Views/chapter/live.volt @@ -2,79 +2,24 @@ {% block content %} - {% set full_chapter_url = full_url({'for':'desktop.chapter.show','id':chapter.id}) %} - {% set course_url = url({'for':'desktop.course.show','id':chapter.course.id}) %} - {% set learning_url = url({'for':'desktop.chapter.learning','id':chapter.id}) %} - {% set live_chats_url = url({'for':'desktop.live.chats','id':chapter.id}) %} - {% set live_stats_url = url({'for':'desktop.live.stats','id':chapter.id}) %} - {% set send_msg_url = url({'for':'desktop.live.send_msg','id':chapter.id}) %} - {% set bind_user_url = url({'for':'desktop.live.bind_user','id':chapter.id}) %} - {% set like_url = url({'for':'desktop.chapter.like','id':chapter.id}) %} - {% set qrcode_url = url({'for':'desktop.qrcode'},{'text':full_chapter_url}) %} - - - -
-
-
-
-
-
-
-
-
直播讨论
-
-
- - {% if auth_user.id > 0 %} - - {% else %} - - {% endif %} - - -
-
-
-
- -
- - - - - - -
- -
- - - - -
+ {% if chapter.status == 'active' %} + {{ partial('live/live_active') }} + {% elseif chapter.status == 'inactive' %} + {{ partial('live/live_inactive') }} + {% elseif chapter.status =='forbid' %} + {{ partial('live/live_forbid') }} + {% endif %} {% endblock %} {% block include_js %} - {{ js_include('https://imgcache.qq.com/open/qcloud/video/vcplayer/TcPlayer-2.3.3.js', false) }} - {{ js_include('desktop/js/chapter.live.player.js') }} - {{ js_include('desktop/js/chapter.live.chat.js') }} - {{ js_include('desktop/js/chapter.action.js') }} - {{ js_include('desktop/js/course.share.js') }} + {% if chapter.status == 'active' %} + {{ js_include('https://imgcache.qq.com/open/qcloud/video/vcplayer/TcPlayer-2.3.3.js', false) }} + {{ js_include('desktop/js/chapter.live.player.js') }} + {{ js_include('desktop/js/chapter.live.chat.js') }} + {{ js_include('desktop/js/chapter.action.js') }} + {{ js_include('desktop/js/course.share.js') }} + {% endif %} {% endblock %} \ No newline at end of file diff --git a/app/Http/Desktop/Views/chapter/live_active.volt b/app/Http/Desktop/Views/chapter/live_active.volt new file mode 100644 index 00000000..05831875 --- /dev/null +++ b/app/Http/Desktop/Views/chapter/live_active.volt @@ -0,0 +1,80 @@ +{% extends 'templates/main.volt' %} + +{% block content %} + + {% set full_chapter_url = full_url({'for':'desktop.chapter.show','id':chapter.id}) %} + {% set course_url = url({'for':'desktop.course.show','id':chapter.course.id}) %} + {% set learning_url = url({'for':'desktop.chapter.learning','id':chapter.id}) %} + {% set live_chats_url = url({'for':'desktop.live.chats','id':chapter.id}) %} + {% set live_stats_url = url({'for':'desktop.live.stats','id':chapter.id}) %} + {% set send_msg_url = url({'for':'desktop.live.send_msg','id':chapter.id}) %} + {% set bind_user_url = url({'for':'desktop.live.bind_user','id':chapter.id}) %} + {% set like_url = url({'for':'desktop.chapter.like','id':chapter.id}) %} + {% set qrcode_url = url({'for':'desktop.qrcode'},{'text':full_chapter_url}) %} + + + +
+
+
+
+
+
+
+
+
直播讨论
+
+
+
+ {% if auth_user.id > 0 %} + + {% else %} + + {% endif %} + +
+
+
+
+
+ +
+ + + + + + +
+ +
+ + + + +
+ +{% endblock %} + +{% block include_js %} + + {{ js_include('https://imgcache.qq.com/open/qcloud/video/vcplayer/TcPlayer-2.3.3.js', false) }} + {{ js_include('desktop/js/chapter.live.player.js') }} + {{ js_include('desktop/js/chapter.live.chat.js') }} + {{ js_include('desktop/js/chapter.action.js') }} + {{ js_include('desktop/js/course.share.js') }} + +{% endblock %} \ No newline at end of file diff --git a/app/Http/Desktop/Views/chapter/live_forbid.volt b/app/Http/Desktop/Views/chapter/live_forbid.volt new file mode 100644 index 00000000..4687a76b --- /dev/null +++ b/app/Http/Desktop/Views/chapter/live_forbid.volt @@ -0,0 +1,15 @@ +{% extends 'templates/main.volt' %} + +{% block content %} + + {% set course_url = url({'for':'desktop.course.show','id':chapter.course.id}) %} + + + +{% endblock %} \ No newline at end of file diff --git a/app/Http/Desktop/Views/chapter/live_inactive.volt b/app/Http/Desktop/Views/chapter/live_inactive.volt new file mode 100644 index 00000000..9b02f73b --- /dev/null +++ b/app/Http/Desktop/Views/chapter/live_inactive.volt @@ -0,0 +1,42 @@ +{% extends 'templates/main.volt' %} + +{% block content %} + + {% set course_url = url({'for':'desktop.course.show','id':chapter.course.id}) %} + {% set live_status_url = url({'for':'desktop.live.status','id':chapter.id}) %} + {% set show_countdown = time() < chapter.start_time ? 1 : 0 %} + + + + {% if show_countdown == 1 %} +
+
+
+
开播倒计时开始啦,敬请关注!
+
+ {% else %} +
+
+
直播已结束,谢谢关注!
+
+ {% endif %} + +
+ + + +
+ +{% endblock %} + +{% block include_js %} + + {{ js_include('desktop/js/chapter.live.countdown.js') }} + +{% endblock %} \ No newline at end of file diff --git a/app/Http/Desktop/Views/templates/main.volt b/app/Http/Desktop/Views/templates/main.volt index 6de3e4e1..ab3d66aa 100644 --- a/app/Http/Desktop/Views/templates/main.volt +++ b/app/Http/Desktop/Views/templates/main.volt @@ -36,8 +36,8 @@ {% block include_js %}{% endblock %} {% block inline_js %}{% endblock %} -{% if site_info.analytics %} - {{ site_info.analytics }} +{% if site_info.analytics_enabled == 1 %} + {{ site_info.analytics_script }} {% endif %} diff --git a/app/Library/Helper.php b/app/Library/Helper.php index 09b28cd5..be48cd45 100644 --- a/app/Library/Helper.php +++ b/app/Library/Helper.php @@ -4,6 +4,7 @@ use App\Caches\Setting as SettingCache; use App\Library\Validators\Common as CommonValidator; use App\Services\Storage as StorageService; use Koogua\Ip2Region\Searcher as Ip2RegionSearcher; +use Phalcon\Config; use Phalcon\Di; use Phalcon\Text; @@ -404,12 +405,15 @@ function kg_js_include($path, $local = true, $version = null) */ function kg_static_url($path, $local = true, $version = null) { + /** + * @var Config $config + */ $config = Di::getDefault()->getShared('config'); - $baseUri = rtrim($config->static_base_uri, '/'); + $baseUri = rtrim($config->get('static_base_uri'), '/'); $path = ltrim($path, '/'); $url = $local ? $baseUri . '/' . $path : $path; - $version = $version ? $version : $config->static_version; + $version = $version ? $version : $config->get('static_version'); if ($version) { $url .= '?v=' . $version; diff --git a/app/Library/Logger.php b/app/Library/Logger.php index 24b0202f..d3f411ad 100644 --- a/app/Library/Logger.php +++ b/app/Library/Logger.php @@ -2,6 +2,7 @@ namespace App\Library; +use Phalcon\Config; use Phalcon\Di; use Phalcon\Logger as PhLogger; use Phalcon\Logger\Adapter\File as FileLogger; @@ -15,7 +16,10 @@ class Logger */ public function getInstance($channel = null) { - $config = Di::getDefault()->get('config'); + /** + * @var Config $config + */ + $config = Di::getDefault()->getShared('config'); $channel = $channel ? $channel : 'common'; @@ -23,7 +27,7 @@ class Logger $path = log_path($filename); - $level = $config->env != ENV_DEV ? $config->log->level : PhLogger::DEBUG; + $level = $config->get('env') != ENV_DEV ? $config->path('log.level') : PhLogger::DEBUG; $logger = new FileLogger($path); diff --git a/app/Models/Chapter.php b/app/Models/Chapter.php index ca974deb..a6fa270c 100644 --- a/app/Models/Chapter.php +++ b/app/Models/Chapter.php @@ -21,7 +21,7 @@ class Chapter extends Model * 推流状态 */ const SS_ACTIVE = 'active'; // 活跃 - const SS_INACTIVE = 'inactive'; // 非活跃 + const SS_INACTIVE = 'inactive'; // 静默 const SS_FORBID = 'forbid'; // 禁播 /** diff --git a/app/Services/Auth/Api.php b/app/Services/Auth/Api.php index 4ccdd3f9..06afce50 100644 --- a/app/Services/Auth/Api.php +++ b/app/Services/Auth/Api.php @@ -19,7 +19,7 @@ class Api extends AuthService $config = $this->getConfig(); - $expireTime = time() + $config->jwt->lifetime; + $expireTime = time() + $config->path('jwt.lifetime'); $builder->expiresAt($expireTime); $builder->withClaim('user_id', $user->id); @@ -27,7 +27,7 @@ class Api extends AuthService $singer = new JwtSingerSha256(); - $key = new JwtSingerKey($config->jwt->key); + $key = new JwtSingerKey($config->path('jwt.key')); $token = $builder->getToken($singer, $key); @@ -51,7 +51,7 @@ class Api extends AuthService $token = $parser->parse($authToken); - $data = new JWTValidationData(time(), $config->jwt->leeway); + $data = new JWTValidationData(time(), $config->path('jwt.leeway')); if (!$token->validate($data)) { return null; @@ -59,7 +59,7 @@ class Api extends AuthService $singer = new JwtSingerSha256(); - if (!$token->verify($singer, $config->jwt->key)) { + if (!$token->verify($singer, $config->path('jwt.key'))) { return null; } @@ -76,9 +76,4 @@ class Api extends AuthService return trim(str_ireplace('Bearer', '', $authorization)); } - protected function getConfig() - { - return $this->getDI()->get('config'); - } - } diff --git a/app/Services/Frontend/Chapter/BasicInfoTrait.php b/app/Services/Frontend/Chapter/BasicInfoTrait.php index 803ccfd7..1d2b395e 100644 --- a/app/Services/Frontend/Chapter/BasicInfoTrait.php +++ b/app/Services/Frontend/Chapter/BasicInfoTrait.php @@ -6,6 +6,7 @@ use App\Models\Chapter as ChapterModel; use App\Models\Course as CourseModel; use App\Repos\Chapter as ChapterRepo; use App\Services\ChapterVod as ChapterVodService; +use App\Services\Frontend\ChapterLiveTrait; use App\Services\Live as LiveService; use WhichBrowser\Parser as BrowserParser; @@ -85,6 +86,7 @@ trait BasicInfoTrait 'play_urls' => $playUrls, 'start_time' => $live->start_time, 'end_time' => $live->end_time, + 'status' => $live->status, 'user_count' => $chapter->user_count, 'like_count' => $chapter->like_count, ]; diff --git a/app/Services/Frontend/Chapter/ChapterLiveTrait.php b/app/Services/Frontend/ChapterLiveTrait.php similarity index 74% rename from app/Services/Frontend/Chapter/ChapterLiveTrait.php rename to app/Services/Frontend/ChapterLiveTrait.php index af6a2e32..5f8cb0ec 100644 --- a/app/Services/Frontend/Chapter/ChapterLiveTrait.php +++ b/app/Services/Frontend/ChapterLiveTrait.php @@ -1,6 +1,6 @@ checkChapterVod($id); + } + + public function checkChapterLive($id) + { + $validator = new ChapterValidator(); + + return $validator->checkChapterLive($id); + } + + public function checkChapterRead($id) + { + $validator = new ChapterValidator(); + + return $validator->checkChapterRead($id); + } + public function checkChapter($id) { $validator = new ChapterValidator(); diff --git a/app/Services/Frontend/Teaching/LivePushUrl.php b/app/Services/Frontend/Teaching/LivePushUrl.php index a37d63be..4407941b 100644 --- a/app/Services/Frontend/Teaching/LivePushUrl.php +++ b/app/Services/Frontend/Teaching/LivePushUrl.php @@ -2,7 +2,7 @@ namespace App\Services\Frontend\Teaching; -use App\Services\Frontend\Chapter\ChapterLiveTrait; +use App\Services\Frontend\ChapterLiveTrait; use App\Services\Frontend\ChapterTrait; use App\Services\Frontend\Service as FrontendService; use App\Services\Live as LiveService; diff --git a/app/Services/LiveNotify.php b/app/Services/LiveNotify.php index 66136244..924c7136 100644 --- a/app/Services/LiveNotify.php +++ b/app/Services/LiveNotify.php @@ -2,7 +2,6 @@ namespace App\Services; -use App\Library\Cache\Backend\Redis as RedisCache; use App\Models\Chapter as ChapterModel; use App\Models\ChapterLive as ChapterLiveModel; use App\Repos\Chapter as ChapterRepo; @@ -129,12 +128,9 @@ class LiveNotify extends Service protected function sendBeginNotify(ChapterModel $chapter) { - /** - * @var RedisCache $cache - */ - $cache = $this->getDI()->get('cache'); + $cache = $this->getCache(); - $redis = $cache->getRedis(); + $redis = $this->getRedis(); $key = $this->getNotifyKey(); diff --git a/app/Services/Pay/AlipayGateway.php b/app/Services/Pay/AlipayGateway.php index a23d5f84..58b88400 100644 --- a/app/Services/Pay/AlipayGateway.php +++ b/app/Services/Pay/AlipayGateway.php @@ -41,11 +41,11 @@ class AlipayGateway extends Service */ public function getInstance() { - $config = $this->getDI()->get('config'); + $config = $this->getConfig(); - $level = $config->env == ENV_DEV ? 'debug' : 'info'; + $level = $config->get('env') == ENV_DEV ? 'debug' : 'info'; - $payConfig = [ + $options = [ 'app_id' => $this->settings['app_id'], 'ali_public_key' => $this->settings['public_key'], 'private_key' => $this->settings['private_key'], @@ -59,11 +59,11 @@ class AlipayGateway extends Service ], ]; - if ($config->env == ENV_DEV) { - $payConfig['mode'] = 'dev'; + if ($config->get('env') == ENV_DEV) { + $options['mode'] = 'dev'; } - return Pay::alipay($payConfig); + return Pay::alipay($options); } } diff --git a/app/Services/Pay/WxpayGateway.php b/app/Services/Pay/WxpayGateway.php index 8e06c588..cad58752 100644 --- a/app/Services/Pay/WxpayGateway.php +++ b/app/Services/Pay/WxpayGateway.php @@ -36,17 +36,19 @@ class WxpayGateway extends Service */ public function getInstance() { - $config = $this->getDI()->get('config'); + $config = $this->getConfig(); - $level = $config->env == ENV_DEV ? 'debug' : 'info'; + $level = $config->get('env') == ENV_DEV ? 'debug' : 'info'; - $payConfig = [ - 'app_id' => $this->settings['app_id'], + $options = [ + 'appid' => $this->settings['app_id'], // App AppId + 'app_id' => $this->settings['mp_app_id'], // 公众号 AppId + 'miniapp_id' => $this->settings['mini_app_id'], // 小程序 AppId 'mch_id' => $this->settings['mch_id'], 'key' => $this->settings['key'], 'notify_url' => $this->settings['notify_url'], - 'cert_client' => '', - 'cert_key' => '', + 'cert_client' => config_path('wxpay/client_cert.pem'), + 'cert_key' => config_path('wxpay/client_key.pem'), 'log' => [ 'file' => log_path('wxpay.log'), 'level' => $level, @@ -55,11 +57,11 @@ class WxpayGateway extends Service ], ]; - if ($config->env == ENV_DEV) { - $payConfig['mode'] = 'dev'; + if ($config->get('env') == ENV_DEV) { + $options['mode'] = 'dev'; } - return Pay::wechat($payConfig); + return Pay::wechat($options); } } diff --git a/app/Services/Service.php b/app/Services/Service.php index 0f1c3964..8f28c98a 100644 --- a/app/Services/Service.php +++ b/app/Services/Service.php @@ -20,7 +20,7 @@ class Service extends Component */ public function getConfig() { - return $this->getDI()->get('config'); + return $this->getDI()->getShared('config'); } /** @@ -28,7 +28,15 @@ class Service extends Component */ public function getCache() { - return $this->getDI()->get('cache'); + return $this->getDI()->getShared('cache'); + } + + /** + * @return \Redis + */ + public function getRedis() + { + return $this->getCache()->getRedis(); } /** diff --git a/app/Services/Syncer/CourseIndex.php b/app/Services/Syncer/CourseIndex.php index 7a411f95..acc987f9 100644 --- a/app/Services/Syncer/CourseIndex.php +++ b/app/Services/Syncer/CourseIndex.php @@ -2,42 +2,26 @@ namespace App\Services\Syncer; -use App\Library\Cache\Backend\Redis as RedisCache; use App\Services\Service; class CourseIndex extends Service { - /** - * @var RedisCache - */ - protected $cache; - - /** - * @var \Redis - */ - protected $redis; - /** * @var int */ protected $lifetime = 86400; - public function __construct() - { - $this->cache = $this->getDI()->get('cache'); - - $this->redis = $this->cache->getRedis(); - } - public function addItem($courseId) { + $redis = $this->getRedis(); + $key = $this->getSyncKey(); - $this->redis->sAdd($key, $courseId); + $redis->sAdd($key, $courseId); - if ($this->redis->sCard($key) == 1) { - $this->redis->expire($key, $this->lifetime); + if ($redis->sCard($key) == 1) { + $redis->expire($key, $this->lifetime); } } diff --git a/app/Services/Syncer/GroupIndex.php b/app/Services/Syncer/GroupIndex.php index 53f9206f..3a4ff35e 100644 --- a/app/Services/Syncer/GroupIndex.php +++ b/app/Services/Syncer/GroupIndex.php @@ -2,42 +2,26 @@ namespace App\Services\Syncer; -use App\Library\Cache\Backend\Redis as RedisCache; use App\Services\Service; class GroupIndex extends Service { - /** - * @var RedisCache - */ - protected $cache; - - /** - * @var \Redis - */ - protected $redis; - /** * @var int */ protected $lifetime = 86400; - public function __construct() - { - $this->cache = $this->getDI()->get('cache'); - - $this->redis = $this->cache->getRedis(); - } - public function addItem($groupId) { + $redis = $this->getRedis(); + $key = $this->getSyncKey(); - $this->redis->sAdd($key, $groupId); + $redis->sAdd($key, $groupId); - if ($this->redis->sCard($key) == 1) { - $this->redis->expire($key, $this->lifetime); + if ($redis->sCard($key) == 1) { + $redis->expire($key, $this->lifetime); } } diff --git a/app/Services/Syncer/Learning.php b/app/Services/Syncer/Learning.php index bc4fa432..bc294dc0 100644 --- a/app/Services/Syncer/Learning.php +++ b/app/Services/Syncer/Learning.php @@ -2,7 +2,6 @@ namespace App\Services\Syncer; -use App\Library\Cache\Backend\Redis as RedisCache; use App\Models\Learning as LearningModel; use App\Services\Service; use App\Traits\Client as ClientTrait; @@ -12,40 +11,27 @@ class Learning extends Service use ClientTrait; - /** - * @var RedisCache - */ - protected $cache; - - /** - * @var \Redis - */ - protected $redis; - /** * @var int */ protected $lifetime = 86400; - public function __construct() - { - $this->cache = $this->getDI()->get('cache'); - - $this->redis = $this->cache->getRedis(); - } - /** * @param LearningModel $learning * @param int $interval */ public function addItem(LearningModel $learning, $interval = 10) { + $cache = $this->getCache(); + + $redis = $this->getRedis(); + $itemKey = $this->getItemKey($learning->request_id); /** * @var LearningModel $cacheLearning */ - $cacheLearning = $this->cache->get($itemKey); + $cacheLearning = $cache->get($itemKey); if (!$cacheLearning) { @@ -54,7 +40,7 @@ class Learning extends Service $learning->duration = $interval; $learning->active_time = time(); - $this->cache->save($itemKey, $learning, $this->lifetime); + $cache->save($itemKey, $learning, $this->lifetime); } else { @@ -62,15 +48,15 @@ class Learning extends Service $cacheLearning->position = $learning->position; $cacheLearning->active_time = time(); - $this->cache->save($itemKey, $cacheLearning, $this->lifetime); + $cache->save($itemKey, $cacheLearning, $this->lifetime); } $key = $this->getSyncKey(); - $this->redis->sAdd($key, $learning->request_id); + $redis->sAdd($key, $learning->request_id); - if ($this->redis->sCard($key) == 1) { - $this->redis->expire($key, $this->lifetime); + if ($redis->sCard($key) == 1) { + $redis->expire($key, $this->lifetime); } } diff --git a/app/Services/Syncer/UserIndex.php b/app/Services/Syncer/UserIndex.php index ef39fd0d..fb45032c 100644 --- a/app/Services/Syncer/UserIndex.php +++ b/app/Services/Syncer/UserIndex.php @@ -2,42 +2,26 @@ namespace App\Services\Syncer; -use App\Library\Cache\Backend\Redis as RedisCache; use App\Services\Service; class UserIndex extends Service { - /** - * @var RedisCache - */ - protected $cache; - - /** - * @var \Redis - */ - protected $redis; - /** * @var int */ protected $lifetime = 86400; - public function __construct() - { - $this->cache = $this->getDI()->get('cache'); - - $this->redis = $this->cache->getRedis(); - } - public function addItem($userId) { + $redis = $this->getRedis(); + $key = $this->getSyncKey(); - $this->redis->sAdd($key, $userId); + $redis->sAdd($key, $userId); - if ($this->redis->sCard($key) == 1) { - $this->redis->expire($key, $this->lifetime); + if ($redis->sCard($key) == 1) { + $redis->expire($key, $this->lifetime); } } diff --git a/app/Services/Throttle.php b/app/Services/Throttle.php index 1ba76b37..1d0d0e33 100644 --- a/app/Services/Throttle.php +++ b/app/Services/Throttle.php @@ -2,23 +2,18 @@ namespace App\Services; -use Phalcon\Cache\Backend\Redis as RedisCache; - class Throttle extends Service { public function checkRateLimit() { - $config = $this->getDI()->get('config'); + $config = $this->getConfig(); - if ($config->throttle->enabled == false) { + if ($config->path('throttle.enabled') == false) { return true; } - /** - * @var RedisCache $cache - */ - $cache = $this->getDI()->get('cache'); + $cache = $this->getCache(); $sign = $this->getRequestSignature(); @@ -27,13 +22,13 @@ class Throttle extends Service $rateLimit = $cache->get($cacheKey); if ($rateLimit) { - if ($rateLimit >= $config->throttle->rate_limit) { + if ($rateLimit >= $config->path('throttle.rate_limit')) { return false; } else { $cache->increment($cacheKey, 1); } } else { - $cache->save($cacheKey, 1, $config->throttle->lifetime); + $cache->save($cacheKey, 1, $config->path('throttle.lifetime')); } return true; diff --git a/app/Services/Verify.php b/app/Services/Verify.php index ee5775f2..171e636b 100644 --- a/app/Services/Verify.php +++ b/app/Services/Verify.php @@ -15,7 +15,7 @@ class Verify extends Service public function __construct() { - $this->cache = $this->getDI()->get('cache'); + $this->cache = $this->getCache(); } public function getSmsCode($phone, $lifetime = 300) diff --git a/app/Validators/Chapter.php b/app/Validators/Chapter.php index 800c9268..788084e7 100644 --- a/app/Validators/Chapter.php +++ b/app/Validators/Chapter.php @@ -43,6 +43,45 @@ class Chapter extends Validator return $chapter; } + public function checkChapterVod($id) + { + $chapterRepo = new ChapterRepo(); + + $chapterVod = $chapterRepo->findChapterVod($id); + + if (!$chapterVod) { + throw new BadRequestException('chapter.vod_not_found'); + } + + return $chapterVod; + } + + public function checkChapterLive($id) + { + $chapterRepo = new ChapterRepo(); + + $chapterLive = $chapterRepo->findChapterLive($id); + + if (!$chapterLive) { + throw new BadRequestException('chapter.live_not_found'); + } + + return $chapterLive; + } + + public function checkChapterRead($id) + { + $chapterRepo = new ChapterRepo(); + + $chapterRead = $chapterRepo->findChapterRead($id); + + if (!$chapterRead) { + throw new BadRequestException('chapter.read_not_found'); + } + + return $chapterRead; + } + public function checkChapter($id) { $chapterRepo = new ChapterRepo(); diff --git a/app/Validators/ChapterLive.php b/app/Validators/ChapterLive.php index 3c272fd8..8b6c1c3b 100644 --- a/app/Validators/ChapterLive.php +++ b/app/Validators/ChapterLive.php @@ -28,22 +28,19 @@ class ChapterLive extends Validator public function checkTimeRange($startTime, $endTime) { - $startTimeStamp = strtotime($startTime); - $endTimeStamp = strtotime($endTime); - - if ($startTimeStamp < time()) { + if ($startTime < time()) { throw new BadRequestException('chapter_live.start_lt_now'); } - if ($endTimeStamp < time()) { + if ($startTime < time()) { throw new BadRequestException('chapter_live.end_lt_now'); } - if ($startTimeStamp >= $endTimeStamp) { + if ($startTime >= $endTime) { throw new BadRequestException('chapter_live.start_gt_end'); } - if ($endTimeStamp - $startTimeStamp > 3 * 3600) { + if ($endTime - $startTime > 3 * 3600) { throw new BadRequestException('chapter_live.time_too_long'); } } diff --git a/bootstrap/Helper.php b/bootstrap/Helper.php index 6fca6bf2..42b8fdde 100644 --- a/bootstrap/Helper.php +++ b/bootstrap/Helper.php @@ -12,7 +12,7 @@ define('ENV_PRO', 'pro'); */ function root_path($path = '') { - return dirname(__DIR__) . ($path ? "/{$path}" : ''); + return dirname(__DIR__) . trim_path($path); } /** @@ -23,7 +23,7 @@ function root_path($path = '') */ function app_path($path = '') { - return root_path('app') . ($path ? "/{$path}" : ''); + return root_path('app') . trim_path($path); } /** @@ -34,7 +34,7 @@ function app_path($path = '') */ function bootstrap_path($path = '') { - return root_path('bootstrap') . ($path ? "/{$path}" : ''); + return root_path('bootstrap') . trim_path($path); } /** @@ -45,7 +45,7 @@ function bootstrap_path($path = '') */ function config_path($path = '') { - return root_path('config') . ($path ? "/{$path}" : ''); + return root_path('config') . trim_path($path); } /** @@ -56,7 +56,7 @@ function config_path($path = '') */ function storage_path($path = '') { - return root_path('storage') . ($path ? "/{$path}" : ''); + return root_path('storage') . trim_path($path); } /** @@ -67,7 +67,7 @@ function storage_path($path = '') */ function vendor_path($path = '') { - return root_path('vendor') . ($path ? "/{$path}" : ''); + return root_path('vendor') . trim_path($path); } /** @@ -78,7 +78,7 @@ function vendor_path($path = '') */ function public_path($path = '') { - return root_path('public') . ($path ? "/{$path}" : ''); + return root_path('public') . trim_path($path); } /** @@ -89,7 +89,7 @@ function public_path($path = '') */ function cache_path($path = '') { - return storage_path('cache') . ($path ? "/{$path}" : ''); + return storage_path('cache') . trim_path($path); } /** @@ -100,7 +100,7 @@ function cache_path($path = '') */ function log_path($path = '') { - return storage_path('log') . ($path ? "/{$path}" : ''); + return storage_path('log') . trim_path($path); } /** @@ -111,18 +111,20 @@ function log_path($path = '') */ function tmp_path($path = '') { - return storage_path('tmp') . ($path ? "/{$path}" : ''); + return storage_path('tmp') . trim_path($path); } /** * Rtrim slash * - * @param string $str + * @param string $path * @return string */ -function rtrim_slash($str) +function trim_path($path) { - return rtrim($str, '/'); + $path = trim($path, '/'); + + return $path ? "/{$path}" : ''; } /** diff --git a/config/alipay/.gitignore b/config/alipay/.gitignore new file mode 100644 index 00000000..cf57c3b0 --- /dev/null +++ b/config/alipay/.gitignore @@ -0,0 +1,2 @@ +.gitignore +!.gitignore \ No newline at end of file diff --git a/config/cert/alipay/.gitignore b/config/cert/alipay/.gitignore deleted file mode 100644 index c96a04f0..00000000 --- a/config/cert/alipay/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/config/cert/wxpay/.gitignore b/config/cert/wxpay/.gitignore deleted file mode 100644 index c96a04f0..00000000 --- a/config/cert/wxpay/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/config/wxpay/.gitignore b/config/wxpay/.gitignore new file mode 100644 index 00000000..cf57c3b0 --- /dev/null +++ b/config/wxpay/.gitignore @@ -0,0 +1,2 @@ +.gitignore +!.gitignore \ No newline at end of file diff --git a/public/static/desktop/css/common.css b/public/static/desktop/css/common.css index 9e44a1d9..a73789de 100644 --- a/public/static/desktop/css/common.css +++ b/public/static/desktop/css/common.css @@ -909,6 +909,34 @@ body { color: #666; } +.countdown { + color: #666; + margin-top: 50px; + text-align: center; +} + +.countdown .icon { + margin-bottom: 10px; +} + +.countdown .icon .layui-icon { + font-size: 150px; +} + +.countdown .tips { + font-size: 18px; + margin: 20px 0; +} + +.countdown .timer { + font-size: 32px; +} + +.countdown .timer span { + color: green; + padding: 10px; +} + .player-wrap { position: relative; width: 760px; diff --git a/public/static/desktop/js/chapter.live.countdown.js b/public/static/desktop/js/chapter.live.countdown.js new file mode 100644 index 00000000..2c2c8078 --- /dev/null +++ b/public/static/desktop/js/chapter.live.countdown.js @@ -0,0 +1,32 @@ +layui.use(['jquery', 'util'], function () { + + var $ = layui.jquery; + var util = layui.util; + + var endTime = $('input[name="countdown.end_time"]').val(); + var serverTime = $('input[name="countdown.server_time"]').val(); + var liveStatusUrl = $('input[name="live.status_url"]').val(); + + util.countdown(1000 * parseInt(endTime), 1000 * parseInt(serverTime), function (date, serverTime, timer) { + var items = [ + {date: date[0], label: '天'}, + {date: date[1], label: '时'}, + {date: date[2], label: '分'}, + {date: date[3], label: '秒'} + ]; + var html = ''; + layui.each(items, function (index, item) { + html += '' + item.date + '' + item.label; + }); + $('.countdown > .timer').html(html); + }); + + setInterval(function () { + $.get(liveStatusUrl, function (res) { + if (res.status === 1) { + window.location.reload(); + } + }); + }, 30000); + +}); \ No newline at end of file