diff --git a/app/Caches/UserDailyCounter.php b/app/Caches/UserDailyCounter.php index fd9627fc..6eb45a68 100644 --- a/app/Caches/UserDailyCounter.php +++ b/app/Caches/UserDailyCounter.php @@ -24,6 +24,7 @@ class UserDailyCounter extends Counter return [ 'favorite_count' => 0, 'comment_count' => 0, + 'danmu_count' => 0, 'consult_count' => 0, 'order_count' => 0, 'chapter_vote_count' => 0, diff --git a/app/Http/Web/Controllers/ChapterController.php b/app/Http/Web/Controllers/ChapterController.php index b8c065fd..30e405bb 100644 --- a/app/Http/Web/Controllers/ChapterController.php +++ b/app/Http/Web/Controllers/ChapterController.php @@ -24,10 +24,23 @@ class ChapterController extends Controller $chapter = $service->handle($id); + $owned = $chapter['me']['owned'] ?? false; + + if (!$owned) { + $this->response->redirect([ + 'for' => 'web.course.show', + 'id' => $chapter['course']['id'], + ]); + } + $service = new CourseChapterListService(); $chapters = $service->handle($chapter['course']['id']); + $this->siteSeo->prependTitle([$chapter['title'], $chapter['course']['title']]); + $this->siteSeo->setKeywords($chapter['title']); + $this->siteSeo->setDescription($chapter['summary']); + if ($chapter['model'] == 'vod') { $this->view->pick('chapter/show_vod'); } elseif ($chapter['model'] == 'live') { diff --git a/app/Http/Web/Controllers/CourseController.php b/app/Http/Web/Controllers/CourseController.php index af8c94ba..3b428930 100644 --- a/app/Http/Web/Controllers/CourseController.php +++ b/app/Http/Web/Controllers/CourseController.php @@ -87,6 +87,10 @@ class CourseController extends Controller $rewardOptions = $service->handle(); + $this->siteSeo->prependTitle($course['title']); + $this->siteSeo->setKeywords($course['keywords']); + $this->siteSeo->setDescription($course['summary']); + $this->view->setVar('course', $course); $this->view->setVar('chapters', $chapters); $this->view->setVar('teachers', $teachers); diff --git a/app/Http/Web/Controllers/DanmuController.php b/app/Http/Web/Controllers/DanmuController.php new file mode 100644 index 00000000..1bad1354 --- /dev/null +++ b/app/Http/Web/Controllers/DanmuController.php @@ -0,0 +1,30 @@ +handle(); + + $service = new DanmuInfoService(); + + $danmu = $service->handle($danmu->id); + + return $this->jsonSuccess(['danmu' => $danmu]); + } + +} diff --git a/app/Http/Web/Controllers/ImController.php b/app/Http/Web/Controllers/ImController.php index 895970ec..b5d0db46 100644 --- a/app/Http/Web/Controllers/ImController.php +++ b/app/Http/Web/Controllers/ImController.php @@ -51,9 +51,9 @@ class ImController extends LayerController } /** - * @Get("/msg/sys/unread/count", name="web.im.unread_sys_msg_count") + * @Get("/msg/sys/unread", name="web.im.unread_sys_msg") */ - public function unreadSystemMessagesCountAction() + public function unreadSystemMessagesAction() { $service = new ImService(); diff --git a/app/Http/Web/Services/Im.php b/app/Http/Web/Services/Im.php index 826e5c0c..fb76c40a 100644 --- a/app/Http/Web/Services/Im.php +++ b/app/Http/Web/Services/Im.php @@ -498,7 +498,7 @@ class Im extends Service /** * 避免频繁推送消息 */ - if ($onlinePushTime && time() - $onlinePushTime > 600) { + if ($onlinePushTime && time() - $onlinePushTime < 600) { return; } diff --git a/app/Http/Web/Views/chapter/show_live.volt b/app/Http/Web/Views/chapter/show_live.volt index 0a5a42f2..ce6b8f77 100644 --- a/app/Http/Web/Views/chapter/show_live.volt +++ b/app/Http/Web/Views/chapter/show_live.volt @@ -17,7 +17,9 @@
-
+
+
+
@@ -32,12 +34,12 @@ {% if auth_user.id > 0 %}
- +
{% else %} - + {% endif %}
diff --git a/app/Http/Web/Views/chapter/show_vod.volt b/app/Http/Web/Views/chapter/show_vod.volt index dd111449..04454ddd 100644 --- a/app/Http/Web/Views/chapter/show_vod.volt +++ b/app/Http/Web/Views/chapter/show_vod.volt @@ -13,7 +13,25 @@
-
+
+
+
+
+
+
+
+ +
+
+ {% if auth_user.id > 0 %} + + {% else %} + + {% endif %} + +
+
+
{{ partial('chapter/menu') }} @@ -33,6 +51,8 @@ + {{ js_include('lib/jquery.min.js') }} + {{ js_include('lib/jquery.danmu.min.js') }} {{ js_include('web/js/vod.player.js') }} {% endblock %} \ No newline at end of file diff --git a/app/Library/Seo.php b/app/Library/Seo.php index f7092c89..1050d905 100644 --- a/app/Library/Seo.php +++ b/app/Library/Seo.php @@ -47,12 +47,16 @@ class Seo public function appendTitle($text) { - $this->title = $this->title . $this->titleSeparator . $text; + $append = is_array($text) ? implode($this->titleSeparator, $text) : $text; + + $this->title = $this->title . $this->titleSeparator . $append; } public function prependTitle($text) { - $this->title = $text . $this->titleSeparator . $this->title; + $prepend = is_array($text) ? implode($this->titleSeparator, $text) : $text; + + $this->title = $prepend . $this->titleSeparator . $this->title; } public function getTitle() diff --git a/app/Listeners/UserDailyCounter.php b/app/Listeners/UserDailyCounter.php index 523b48cb..f5deff20 100644 --- a/app/Listeners/UserDailyCounter.php +++ b/app/Listeners/UserDailyCounter.php @@ -26,6 +26,11 @@ class UserDailyCounter extends Listener $this->counter->hIncrBy($user->id, 'comment_count'); } + public function incrDanmuCount(Event $event, $source, UserModel $user) + { + $this->counter->hIncrBy($user->id, 'danmu_count'); + } + public function incrConsultCount(Event $event, $source, UserModel $user) { $this->counter->hIncrBy($user->id, 'consult_count'); diff --git a/app/Models/Danmu.php b/app/Models/Danmu.php new file mode 100644 index 00000000..607b13c5 --- /dev/null +++ b/app/Models/Danmu.php @@ -0,0 +1,157 @@ +addBehavior( + new SoftDelete([ + 'field' => 'deleted', + 'value' => 1, + ]) + ); + } + + public function beforeCreate() + { + $this->create_time = time(); + } + + public function beforeUpdate() + { + $this->update_time = time(); + } + + public static function sizeTypes() + { + return [ + '0' => '小号', + '1' => '大号', + ]; + } + + public static function positionTypes() + { + return [ + '0' => '滚动', + '1' => '顶部', + '2' => '底部', + ]; + } +} diff --git a/app/Repos/Danmu.php b/app/Repos/Danmu.php new file mode 100644 index 00000000..6c8e2809 --- /dev/null +++ b/app/Repos/Danmu.php @@ -0,0 +1,85 @@ +modelsManager->createBuilder(); + + $builder->from(DanmuModel::class); + + $builder->where('1 = 1'); + + if (!empty($where['id'])) { + $builder->andWhere('id = :id:', ['id' => $where['id']]); + } + + if (!empty($where['course_id'])) { + $builder->andWhere('course_id = :course_id:', ['course_id' => $where['course_id']]); + } + + if (!empty($where['chapter_id'])) { + $builder->andWhere('chapter_id = :chapter_id:', ['chapter_id' => $where['chapter_id']]); + } + + if (!empty($where['user_id'])) { + $builder->andWhere('user_id = :user_id:', ['user_id' => $where['user_id']]); + } + + if (isset($where['published'])) { + $builder->andWhere('published = :published:', ['published' => $where['published']]); + } + + if (isset($where['deleted'])) { + $builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]); + } + + switch ($sort) { + default: + $orderBy = 'id DESC'; + break; + } + + $builder->orderBy($orderBy); + + $pager = new PagerQueryBuilder([ + 'builder' => $builder, + 'page' => $page, + 'limit' => $limit, + ]); + + return $pager->paginate(); + } + + /** + * @param int $id + * @return DanmuModel|Model|bool + */ + public function findById($id) + { + return DanmuModel::findFirst($id); + } + + /** + * @param array $ids + * @param string|array $columns + * @return ResultsetInterface|Resultset|DanmuModel[] + */ + public function findByIds($ids, $columns = '*') + { + return DanmuModel::query() + ->columns($columns) + ->inWhere('id', $ids) + ->execute(); + } + +} diff --git a/app/Services/Frontend/Danmu/DanmuCreate.php b/app/Services/Frontend/Danmu/DanmuCreate.php new file mode 100644 index 00000000..7ea302a6 --- /dev/null +++ b/app/Services/Frontend/Danmu/DanmuCreate.php @@ -0,0 +1,56 @@ +request->getPost(); + + $user = $this->getLoginUser(); + + $chapter = $this->checkChapter($post['chapter_id']); + + $validator = new UserDailyLimitValidator(); + + $validator->checkDanmuLimit($user); + + $validator = new DanmuValidator(); + + $danmu = new DanmuModel(); + + $data = []; + + $data['text'] = $validator->checkText($post['text']); + $data['time'] = $validator->checkTime($post['time']); + + $data['course_id'] = $chapter->course_id; + $data['chapter_id'] = $chapter->id; + $data['user_id'] = $user->id; + $data['color'] = 'white'; + $data['published'] = 1; + + $danmu->create($data); + + $this->incrUserDailyDanmuCount($user); + + return $danmu; + } + + protected function incrUserDailyDanmuCount(UserModel $user) + { + $this->eventsManager->fire('userDailyCounter:incrDanmuCount', $this, $user); + } + +} diff --git a/app/Services/Frontend/Danmu/DanmuInfo.php b/app/Services/Frontend/Danmu/DanmuInfo.php new file mode 100644 index 00000000..6cdbed96 --- /dev/null +++ b/app/Services/Frontend/Danmu/DanmuInfo.php @@ -0,0 +1,46 @@ +checkDanmu($id); + + return $this->handleDanmu($danmu); + } + + protected function handleDanmu(DanmuModel $danmu) + { + $result = [ + 'id' => $danmu->id, + 'text' => $danmu->text, + 'color' => $danmu->color, + 'size' => $danmu->size, + 'position' => $danmu->position, + 'time' => $danmu->time, + ]; + + $userRepo = new UserRepo(); + + $user = $userRepo->findById($danmu->user_id); + + $result['user'] = [ + 'id' => $user->id, + 'name' => $user->name, + 'avatar' => $user->avatar, + ]; + + return $result; + } + +} diff --git a/app/Services/Frontend/DanmuTrait.php b/app/Services/Frontend/DanmuTrait.php new file mode 100644 index 00000000..05d1da1e --- /dev/null +++ b/app/Services/Frontend/DanmuTrait.php @@ -0,0 +1,17 @@ +checkDanmu($id); + } + +} diff --git a/app/Validators/Danmu.php b/app/Validators/Danmu.php new file mode 100644 index 00000000..8906bc8f --- /dev/null +++ b/app/Validators/Danmu.php @@ -0,0 +1,86 @@ +findById($id); + + if (!$danmu) { + throw new BadRequestException('danmu.not_found'); + } + + return $danmu; + } + + public function checkChapter($id) + { + $validator = new Chapter(); + + return $validator->checkChapter($id); + } + + public function checkText($text) + { + $value = $this->filter->sanitize($text, ['trim', 'string']); + + $length = kg_strlen($value); + + if ($length < 1) { + throw new BadRequestException('danmu.text_too_short'); + } + + if ($length > 100) { + throw new BadRequestException('danmu.text_too_long'); + } + + return $value; + } + + public function checkSize($size) + { + $list = DanmuModel::sizeTypes(); + + if (!isset($list[$size])) { + throw new BadRequestException('danmu.invalid_size'); + } + + return $size; + } + + public function checkPosition($pos) + { + $list = DanmuModel::positionTypes(); + + if (!isset($list[$pos])) { + throw new BadRequestException('danmu.invalid_position'); + } + + return $pos; + } + + public function checkTime($time) + { + $value = (int)$time; + + if ($value < 0) { + throw new BadRequestException('danmu.invalid_time'); + } + + if ($value > 3 * 3600) { + throw new BadRequestException('danmu.invalid_time'); + } + + return $value; + } + +} diff --git a/app/Validators/UserDailyLimit.php b/app/Validators/UserDailyLimit.php index b5b9ed6f..edd44866 100644 --- a/app/Validators/UserDailyLimit.php +++ b/app/Validators/UserDailyLimit.php @@ -38,6 +38,17 @@ class UserDailyLimit extends Validator } } + public function checkDanmuLimit(UserModel $user) + { + $count = $this->counter->hGet($user->id, 'danmu_count'); + + $limit = $user->vip ? 100 : 50; + + if ($count > $limit) { + throw new BadRequestException('user_daily_limit.reach_danmu_limit'); + } + } + public function checkConsultLimit(UserModel $user) { $count = $this->counter->hGet($user->id, 'consult_count'); diff --git a/public/static/lib/jquery.danmu.min.js b/public/static/lib/jquery.danmu.min.js new file mode 100644 index 00000000..a9ff718e --- /dev/null +++ b/public/static/lib/jquery.danmu.min.js @@ -0,0 +1 @@ +!function(a){a.jQueryPlugin=function(b){a.fn[b]=function(c){var d=Array.prototype.slice.call(arguments,1);return this.length?this.each(function(){var e=a.data(this,b)||a.data(this,b,new cyntax.plugins[b](this,c)._init());"string"==typeof c&&(c=c.replace(/^_/,""),e[c]&&e[c].apply(e,d))}):void 0}}}(jQuery);var cyntax={plugins:{}};!function(){function a(){return(new Date).getTime()}var b=jQuery,c="jQuery.pause",d=1,e=b.fn.animate,f={};b.fn.animate=function(g,h,i,j){var k=b.speed(h,i,j);return k.complete=k.old,this.each(function(){this[c]||(this[c]=d++);var h=b.extend({},k);e.apply(b(this),[g,b.extend({},h)]),f[this[c]]={run:!0,prop:g,opt:h,start:a(),done:0}})},b.fn.pause=function(){return this.each(function(){this[c]||(this[c]=d++);var e=f[this[c]];e&&e.run&&(e.done+=a()-e.start,e.done>e.opt.duration?delete f[this[c]]:(b(this).stop().stop().stop(),b(this).stop(),b(this).stop(),b(this).stop(),b(this).stop(),b(this).stop(),b(this).stop(),b(this).stop(),b(this).stop(),b(this).stop(),b(this).stop(),b(this).stop(),b(this).stop(),b(this).stop(),b(this).stop(),e.run=!1))})},b.fn.resume=function(){return this.each(function(){this[c]||(this[c]=d++);var g=f[this[c]];g&&!g.run&&(g.opt.duration-=g.done,g.done=0,g.run=!0,g.start=a(),e.apply(b(this),[g.prop,b.extend({},g.opt)]))})}}(),function(a){cyntax.plugins.timer=function(b,c){this.$this=a(b),this.options=a.extend({},this.defaults,c),this.timer_info={id:null,index:null,state:0}},cyntax.plugins.timer.prototype={defaults:{delay:1e3,repeat:!1,autostart:!0,callback:null,url:"",post:""},_init:function(){return this.options.autostart&&(this.timer_info.state=1,this.timer_info.id=setTimeout(a.proxy(this._timer_fn,this),this.options.delay)),this},_timer_fn:function(){"function"==typeof this.options.callback?a.proxy(this.options.callback,this.$this).call(this,++this.timer_info.index):"string"==typeof this.options.url&&(ajax_options={url:this.options.url,context:this,type:"string"==typeof this.options.post&&""!=typeof this.options.post==""?"POST":"GET",success:function(a){this.$this.html(a)}},"string"==typeof this.options.post&&""!=typeof this.options.post&&(ajax_options.data=this.options.post),a.ajax(ajax_options)),this.options.repeat&&1==this.timer_info.state&&("boolean"==typeof this.options.repeat||parseInt(this.options.repeat)>this.timer_info.index)?this.timer_info.id=setTimeout(a.proxy(this._timer_fn,this),this.options.delay):this.timer_id=null},start:function(){0==this.timer_info.state&&(this.timer_info.index=0,this.timer_info.state=1,this.timer_id=setTimeout(a.proxy(this._timer_fn,this),this.options.delay))},stop:function(){1==this.timer_info.state&&this.timer_info.id&&(clearTimeout(this.timer_info.id),this.timer_id=null),this.timer_info.state=0},pause:function(){1==this.timer_info.state&&this.timer_info.id&&clearTimeout(this.timer_info.id),this.timer_info.state=0},resume:function(){this.timer_info.state=1,this.timer_id=setTimeout(a.proxy(this._timer_fn,this),this.options.delay)}},a.jQueryPlugin("timer")}(jQuery),function(a){function b(b,d){return this.each(function(){var e=a(this),f=a.extend({},c.DEFAULTS,"object"==typeof b&&b),g=e.data("danmu"),h="string"==typeof b?b:0/0;g||e.data("danmu",g=new c(this,f)),h&&g[h](d)})}var c=function(b,c){this.$element=a(b),this.options=c,this.id=a(b).attr("id"),a(b).data("nowTime",0),a(b).data("danmuList",c.danmuList),a(b).data("opacity",c.opacity),a(b).data("paused",1),a(b).data("topSpace",0),a(b).data("bottomSpace",0),this.$element.css({position:"absolute",left:this.options.left,top:this.options.top,width:this.options.width,height:this.options.height,"z-index":this.options.zindex,color:c.defaultFontColor,overflow:"hidden"});var d=this;d.height=this.$element.height(),d.width=this.$element.width(),d.speed=1e3/c.speed,this.launched=[],this.preTime=0;var e=this.options.maxCountInScreen,f=this.options.maxCountPerSec,g=0,h=0;this.rowCount=parseInt(d.height/c.FontSizeBig),d.options.SubtitleProtection&&(d.rowCount=d.rowCount-3),this.rows=[],this.initRows=function(a){for(var b=0;b=a.rowCount){a.initRows(a),b=0;break}return b},d.checkRow=function(b){for(var c in b.rows)0!==b.rows[c]&&"undefined"!=typeof a("#"+b.rows[c]).position()&&a("#"+b.rows[c]).position().left
").appendTo(this.$element),this.$timer=a(".danmakuTimer"),this.$timer.timer({delay:100,repeat:c.sumTime,autostart:!1,callback:function(i){setTimeout(function(){d.options.danmuLoop&&a(b).data("nowTime")>=a(b).data("sumTime")&&a(b).data("nowTime",0),a(b).data("nowTime",a(b).data("nowTime")+1),d.height=a(b).height(),d.width=a(b).width(),Math.abs(a(b).data("nowTime")-(d.preTime+1))>10&&(d.launched=[]),d.preTime=a(b).data("nowTime");var j=d.rowCount;if(d.rowCount=parseInt(d.height/c.FontSizeBig),setTimeout(d.checkRow(d),0),d.options.SubtitleProtection&&(d.rowCount=d.rowCount-3),0!==j&&d.rowCount!==j&&d.initRows(d),h=0,a(b).data("danmuList")[a(b).data("nowTime")]&&d.launched.indexOf(a(b).data("nowTime"))<0){for(var k=a(b).data("nowTime"),l=a(b).data("danmuList")[k],m=l.length-1;m>=0;m--){setTimeout(d.checkRow(d),0);var n="";a(b).append(n);var o=l[m];if(a("#"+d.id+"tempDanmaku").text(o.text).css({color:o.color,"text-shadow":" 0px 0px 2px #000000","-moz-opacity":a(b).data("opacity"),opacity:a(b).data("opacity"),"white-space":"nowrap","font-weight":"bold","font-family":"SimHei","font-size":c.FontSizeBig}),o.color<"#777777"&&a("#"+d.id+"tempDanmaku").css({"text-shadow":" 0px 0px 2px #FFFFFF"}),o.hasOwnProperty("isnew")&&a("#"+d.id+"tempDanmaku").css({border:"2px solid "+o.color}),0==o.size&&a("#"+d.id+"tempDanmaku").css("font-size",c.fontSizeSmall),0==o.position){var p=d.id+"fly"+parseInt((new Date).getTime()).toString();if(a("#"+d.id+"tempDanmaku").attr("id",p),e>=g&&f>=h){d.checkRow(d);var q=d.getRow(d);d.rows[q]=p,o.row=q;var r=q*c.FontSizeBig;o.width=a("#"+p).width();var s=a("#"+d.id).width();a("#"+p).css({width:a("#"+p).width(),position:"absolute",top:r,left:s});var t=(a(b).width()+400)/d.speed;g++,h++,a("#"+p).animate({left:-(a("#"+p).width()+400)},t,function(){a(this).remove(),g--,h--})}else a("#"+p).remove()}else if(1==o.position){var u=d.id+"top"+parseInt(1e4*Math.random()).toString();a("#"+d.id+"tempDanmaku").attr("id",u),a("#"+u).css({width:"100%","text-align":"center",position:"absolute",top:a(b).data("topSpace"),left:"0"}),a(b).data("topSpace",a(b).data("topSpace")+c.FontSizeBig),a("#"+u).fadeTo(c.topBottomDanmuTime,a(b).data("opacity"),function(){a(this).remove(),a(b).data("topSpace",a(b).data("topSpace")-c.FontSizeBig)})}else if(2==o.position){var v=d.id+"bottom"+parseInt(1e4*Math.random()).toString();a("#"+d.id+"tempDanmaku").attr("id",v),a("#"+v).css({width:c.width,left:"0","text-align":"center",position:"absolute",bottom:0+a(b).data("bottomSpace")}),a(b).data("bottomSpace",a(b).data("bottomSpace")+c.FontSizeBig),a("#"+v).fadeTo(c.topBottomDanmuTime,a(b).data("opacity"),function(){a(this).remove(),a(b).data("bottomSpace",a(b).data("bottomSpace")-c.FontSizeBig)})}l[m]=o}a(b).data("danmuList")[k]=l}d.launched.push(a(b).data("nowTime")),i==c.sumTime&&c.isLoop&&(d.$timer.timer("stop"),d.$timer.timer("start"))})}})};c.DEFAULTS={left:0,top:0,height:360,width:640,zindex:100,speed:8e3,sumTime:65535,danmuLoop:!1,danmuList:{},defaultFontColor:"#FFFFFF",fontSizeSmall:16,FontSizeBig:24,opacity:"0.9",topBottomDanmuTime:6e3,SubtitleProtection:!1,positionOptimize:!1,maxCountInScreen:40,maxCountPerSec:10},c.prototype.danmuStart=function(){this.$timer.timer("start"),this.$element.data("paused",0)},c.prototype.danmuStop=function(){this.$timer.timer("stop"),a("#"+this.id+" .danmaku").remove(),nowTime=0,this.$element.data("paused",1),this.$element.data("nowTime",0)},c.prototype.danmuPause=function(){this.$timer.timer("pause"),a("#"+this.id+" .danmaku").pause(),this.$element.data("paused",1)},c.prototype.danmuResume=function(){this.$timer.timer("resume"),a("#"+this.id+" .danmaku").resume(),this.$element.data("paused",0)},c.prototype.danmuHideAll=function(){a("#"+this.id+" .danmaku").css({opacity:0}),this.initRows(this)},c.prototype.setTime=function(b){a("#"+this.id+" .danmaku").remove(),this.$element.data("nowTime",b)},c.prototype.setOpacity=function(b){a("#"+this.id+" .danmaku").css("opacity",b),this.$element.data("opacity",b)},c.prototype.addDanmu=function(a){if(a instanceof Array)for(var b in a)this.$element.data("danmuList")[a[b].time]?this.$element.data("danmuList")[a[b].time].push(a[b]):(this.$element.data("danmuList")[a[b].time]=[],this.$element.data("danmuList")[a[b].time].push(a[b]));else this.$element.data("danmuList")[a.time]?this.$element.data("danmuList")[a.time].push(a):(this.$element.data("danmuList")[a.time]=[],this.$element.data("danmuList")[a.time].push(a))},a.fn.danmu=b,a.fn.danmu.Constructor=c}(jQuery); \ No newline at end of file diff --git a/public/static/web/css/common.css b/public/static/web/css/common.css index 84b76b3c..107a30e2 100644 --- a/public/static/web/css/common.css +++ b/public/static/web/css/common.css @@ -778,7 +778,19 @@ margin-bottom: 0; } -.player { +.danmu-action { + padding: 15px 20px; + margin-bottom: 0; +} + +.danmu-action .layui-input { + height: 32px; + line-height: 32px; + font-size: 12px; +} + +.player-container { + position: relative; width: 760px; height: 428px; } @@ -1425,30 +1437,16 @@ color: #999; } -.layui-layim-list li .msg-count, .layim-chat-list li .msg-count { - position: absolute; - color: white; - background-color: red; -} - .layui-layim-list li .msg-count { + position: absolute; top: 10px; right: 10px; - padding: 2px 5px; - line-height: 16px; - height: 16px; - border-radius: 2px; - font-size: 12px; } .layim-chat-list li .msg-count { + position: absolute; top: 5px; right: 30px; - padding: 1px 3px; - line-height: 12px; - height: 12px; - border-radius: 2px; - font-size: 10px; } .layim-chat-status .online { diff --git a/public/static/web/js/im.js b/public/static/web/js/im.js index 11294d8f..2f7d020d 100644 --- a/public/static/web/js/im.js +++ b/public/static/web/js/im.js @@ -68,7 +68,7 @@ layui.use(['jquery', 'layim'], function () { layui.each(group.list, function (j, user) { var $li = $('.layui-layim-list > .layim-friend' + user.id); if (user.msg_count > 0) { - $li.append('' + user.msg_count + ''); + $li.append('' + user.msg_count + ''); } }); }); @@ -140,7 +140,7 @@ layui.use(['jquery', 'layim'], function () { var count = parseInt($msgCount.text()); $msgCount.text(count + 1).removeClass('layui-hide'); } else { - $li.append('1'); + $li.append('1'); } } @@ -196,7 +196,7 @@ layui.use(['jquery', 'layim'], function () { function refreshMessageBox() { $.ajax({ type: 'GET', - url: '/im/msg/sys/unread/count', + url: '/im/msg/sys/unread', success: function (res) { if (res.count > 0) { layim.msgbox(res.count); diff --git a/public/static/web/js/vod.player.js b/public/static/web/js/vod.player.js index a5b33c3a..5e501bcc 100644 --- a/public/static/web/js/vod.player.js +++ b/public/static/web/js/vod.player.js @@ -1,6 +1,7 @@ -layui.use(['jquery', 'helper'], function () { +layui.use(['jquery', 'form', 'helper'], function () { var $ = layui.jquery; + var form = layui.form; var helper = layui.helper; var interval = null; @@ -31,17 +32,15 @@ layui.use(['jquery', 'helper'], function () { options.m3u8_sd = playUrls.sd.url; } - if (userId !== '0' && planId !== '0') { - options.listener = function (msg) { - if (msg.type === 'play') { - start(); - } else if (msg.type === 'pause') { - stop(); - } else if (msg.type === 'end') { - stop(); - } + options.listener = function (msg) { + if (msg.type === 'play') { + start(); + } else if (msg.type === 'pause') { + stop(); + } else if (msg.type === 'end') { + stop(); } - } + }; var player = new TcPlayer('player', options); @@ -49,31 +48,100 @@ layui.use(['jquery', 'helper'], function () { player.currentTime(position); } + $('#danmu').danmu({ + left: 20, + top: 20, + width: 750, + height: 380 + }); + + //再添加三个弹幕 + $("#danmu").danmu("addDanmu", [ + {text: "这是滚动弹幕", color: "white", size: 0, position: 0, time: 120} + , {text: "这是顶部弹幕", color: "yellow", size: 0, position: 1, time: 120} + , {text: "这是底部弹幕", color: "red", size: 0, position: 2, time: 120} + ]); + + form.on('checkbox(status)', function (data) { + if (data.elem.checked) { + $('#danmu').danmu('setOpacity', 1); + } else { + $('#danmu').danmu('setOpacity', 0); + } + }); + + form.on('submit(chat)', function (data) { + $.ajax({ + type: 'POST', + url: data.form.action, + data: { + text: data.field.text, + time: player.currentTime(), + chapter_id: chapterId, + }, + success: function (res) { + showDanmu(res); + } + }); + return false; + }); + function start() { if (interval != null) { clearInterval(interval); interval = null; } interval = setInterval(learning, intervalTime); + startDanmu(); } function stop() { clearInterval(interval); interval = null; + pauseDanmu(); } function learning() { - $.ajax({ - type: 'POST', - url: learningUrl, - data: { - request_id: requestId, - chapter_id: chapterId, - plan_id: planId, - interval: intervalTime, - position: player.currentTime(), - } + if (userId !== '0' && planId !== '0') { + $.ajax({ + type: 'POST', + url: learningUrl, + data: { + request_id: requestId, + chapter_id: chapterId, + plan_id: planId, + interval: intervalTime, + position: player.currentTime(), + } + }); + } + } + + function startDanmu() { + $('#danmu').danmu('danmuStart'); + } + + function pauseDanmu() { + $('#danmu').danmu('danmuPause'); + } + + function showDanmu(res) { + /* + $('#danmu').danmu('addDanmu', { + text: res.danmu.text, + color: res.danmu.color, + size: res.danmu.size, + time: res.danmu.time, + position: res.danmu.position, + isnew: 1 }); + */ + $("#danmu").danmu("addDanmu", [ + {text: "这是滚动弹幕", color: "white", size: 0, position: 0, time: 300} + , {text: "这是顶部弹幕", color: "yellow", size: 0, position: 0, time: 300} + , {text: "这是底部弹幕", color: "red", size: 0, position: 0, time: 300} + ]); + $('input[name=text]').val(''); } }); \ No newline at end of file