|
|
<!-- +---------------------------------------------------------------------- -->
|
|
|
<!-- | 天诚科技 [ 刘海东 17600099397赋能开发者,助力企业发展 ] -->
|
|
|
<!-- +---------------------------------------------------------------------- -->
|
|
|
<!-- | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved. -->
|
|
|
<!-- +---------------------------------------------------------------------- -->
|
|
|
<!-- | Licensed 该系统并不是自由软件,未经许可不能去掉相关版权 -->
|
|
|
<!-- +---------------------------------------------------------------------- -->
|
|
|
<!-- | Author:甘肃天诚志信电子商务有限公司 刘海东 联系电话维系17600099397 -->
|
|
|
<!-- +---------------------------------------------------------------------- -->
|
|
|
{extend name="public/container"}
|
|
|
{block name="title"}直播间{/block}
|
|
|
{block name="app"}
|
|
|
<div v-cloak id="app">
|
|
|
<base-header :public-data="publicData" :user-info="userInfo"></base-header>
|
|
|
<div class="layout">
|
|
|
<div class="container">
|
|
|
<div class="classroom">
|
|
|
<div class="classroom_video">
|
|
|
<div class="classroom_video_title">
|
|
|
<div class="classroom_video_title_value">
|
|
|
<span>{{ liveInfo.live_title }}</span>
|
|
|
</div>
|
|
|
<div class="classroom_video_title_teacher">
|
|
|
<div v-if="lecturer.lecturer_head" class="classroom_video_title_teacher_avatar">
|
|
|
<img :src="lecturer.lecturer_head" :alt="lecturer.lecturer_name">
|
|
|
</div>
|
|
|
<div v-if="lecturer.lecturer_name" class="classroom_video_title_teacher_name">
|
|
|
<span>{{ lecturer.lecturer_name }}</span>
|
|
|
</div>
|
|
|
<div v-if="user_type == 1" class="classroom_video_title_teacher_tip">
|
|
|
<span>讲师</span>
|
|
|
</div>
|
|
|
<div v-else-if="user_type == 0" class="classroom_video_title_teacher_tip">
|
|
|
<span>助教</span>
|
|
|
</div>
|
|
|
<div class="classroom_video_title_teacher_time">
|
|
|
<span class="iconfont"></span>
|
|
|
<span>直播时间:</span>
|
|
|
<span>{{ liveInfo.start_play_time }} - {{ liveInfo.stop_play_time }}</span>
|
|
|
</div>
|
|
|
<div class="classroom_video_title_teacher_audience">
|
|
|
<span class="iconfont"></span>
|
|
|
<span>{{ UserSum }}人</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="classroom_video_content">
|
|
|
<div v-if="liveInfo.is_play || liveInfo.is_playback" class="prism-player" id="J_prismPlayer"></div>
|
|
|
<template v-else>
|
|
|
<div v-if="live_status == 0" class="tip">直播即将开始</div>
|
|
|
<div v-else-if="live_status == -1 || live_status == 1" class="tip">讲师离开一会~马上回来</div>
|
|
|
<div v-else-if="live_status == 2" class="tip">直播已结束</div>
|
|
|
<img :src="liveInfo.live_image" class="cover">
|
|
|
<div class="shade"></div>
|
|
|
</template>
|
|
|
</div>
|
|
|
<div class="classroom_video_methods">
|
|
|
<!-- 礼物 -->
|
|
|
<div class="classroom_video_methods_giftList">
|
|
|
<div class="swiper-container">
|
|
|
<div class="swiper-wrapper">
|
|
|
<div v-for="item in giftList" :key="item.id" class="swiper-slide">
|
|
|
<el-popover placement="top-start" width="368" trigger="hover" popper-class="gift-popover" @show="onPopoverShow">
|
|
|
<div class="gift-info">
|
|
|
<img :src="item.live_gift_show_img" :alt="item.live_gift_name">
|
|
|
<span>{{ item.live_gift_name }}</span>
|
|
|
<span>({{ item.live_gift_price }}{{ goldInfo.gold_name }}/个)</span>
|
|
|
</div>
|
|
|
<div class="gift-size">
|
|
|
<div class="radio-group">
|
|
|
<label v-for="num in item.live_gift_num" :key="num">
|
|
|
<input v-model="giftRadio" :value="num" type="radio" hidden>
|
|
|
<span>{{ num }}</span>
|
|
|
</label>
|
|
|
</div>
|
|
|
<input v-model.number="giftInput" type="number" min="1" step="1" @focus="giftRadio = ''"
|
|
|
@blur="!giftInput || 0 >= giftInput ? giftInput = 1 : null">
|
|
|
<button @click="sendGift(item)">赠送</button>
|
|
|
</div>
|
|
|
<img slot="reference" :src="item.live_gift_show_img" :alt="item.live_gift_name" :title="item.live_gift_name">
|
|
|
</el-popover>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="swiper-button-prev"></div>
|
|
|
<div class="swiper-button-next"></div>
|
|
|
</div>
|
|
|
<!-- 金币 -->
|
|
|
<div class="classroom_video_methods_pay">
|
|
|
<div class="classroom_video_methods_pay_item">
|
|
|
<div>
|
|
|
<img :src="goldInfo.gold_image" :alt="goldInfo.gold_name">
|
|
|
</div>
|
|
|
<div>
|
|
|
<span>{{ userInfo && userInfo.gold_num }}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="classroom_video_methods_pay_item" @click="rechargeIcon">
|
|
|
<div>
|
|
|
<img src="{__PUBLIC_WEB_PATH}pc/images/recharge.png" alt="充值">
|
|
|
</div>
|
|
|
<div>
|
|
|
<span>充值</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div v-if="tapList.length" class="classroom_chat">
|
|
|
<div class="classroom_chat_fun">
|
|
|
<div class="classroom_chat_fun_item" v-for="(item, index) in tapList" :key="index" :class="{ 'selectEdTap': selectTapId == item.id }"
|
|
|
@click="handleSelectTap(item)">
|
|
|
<span>{{item.label}}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
<!-- 聊天 -->
|
|
|
<div ref="chatContent1" class="classroom_chat_con" v-show="selectTapId == 1" @scroll="chatContentScroll1">
|
|
|
<div :class="{ right_box: item.uid == userInfo.uid }" class="classroom_chat_con_item" v-for="(item, index) in messageList" :key="item.id">
|
|
|
<div class="classroom_chat_con_item_avator">
|
|
|
<img :src="item.avatar" :alt="item.nickname">
|
|
|
</div>
|
|
|
<div class="classroom_chat_con_item_msg">
|
|
|
<div class="user_message">
|
|
|
<div class="nickname">{{ item.nickname }}</div>
|
|
|
<div v-if="item.user_type == 1" class="identity">
|
|
|
<span>讲师</span>
|
|
|
</div>
|
|
|
<div v-if="item.user_type == 0" class="identity">
|
|
|
<span>助教</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="message" v-if="item.type == 1">
|
|
|
<span v-html="item.content"></span>
|
|
|
</div>
|
|
|
<div class="message" v-else-if="item.type == 2">
|
|
|
<img :src="item.content" alt="">
|
|
|
</div>
|
|
|
<div class="gift" v-else-if="item.type == 4">
|
|
|
<div>{{ item.content }}</div>
|
|
|
<div>
|
|
|
<img :src="item.gift_image" :alt="item.gift_name">
|
|
|
</div>
|
|
|
<div>
|
|
|
<span>×{{ item.gift_num }}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<!-- 聊天结束 -->
|
|
|
<!-- 课堂开始 -->
|
|
|
<div ref="chatContent2" class="classroom_chat_con" v-show="selectTapId == 2" @scroll="chatContentScroll2">
|
|
|
<div class="classroom_chat_con_item" v-for="(item, index) in classChatList" :key="item.id">
|
|
|
<div class="classroom_chat_con_item_avator">
|
|
|
<img :src="item.avatar" :alt="item.nickname">
|
|
|
</div>
|
|
|
<div class="classroom_chat_con_item_msg">
|
|
|
<div class="user_message">
|
|
|
<div class="nickname">{{ item.nickname }}</div>
|
|
|
<div v-if="item.user_type == 1" class="identity">
|
|
|
<span>讲师</span>
|
|
|
</div>
|
|
|
<div v-if="item.user_type == 0" class="identity">
|
|
|
<span>助教</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="message" v-if="item.type == 1">
|
|
|
<span v-html="item.content"></span>
|
|
|
</div>
|
|
|
<div class="message" v-else-if="item.type == 2">
|
|
|
<img :src="item.content" alt="">
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<!-- 课堂结束 -->
|
|
|
<!-- 讲师推荐开始 -->
|
|
|
<div class="classroom_chat_con classroom_chat_con3" v-show="selectTapId == 3">
|
|
|
<div v-for="item in goodsList" :key="item.id" class="instructor_recommendation" @click="goSpecial(item)">
|
|
|
<div class="instructor_recommendation_img">
|
|
|
<img :src="item.image" :alt="item.title">
|
|
|
<div>{{ item.gfake_type ? '活动' : '专题' }}</div>
|
|
|
</div>
|
|
|
<div class="instructor_recommendation_value">
|
|
|
<div class="instructor_recommendation_value_title">{{ item.title }}</div>
|
|
|
<div class="instructor_recommendation_value_price">
|
|
|
<span>¥</span><span>{{ item.money }}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<!-- 讲师推荐结束 -->
|
|
|
<!-- 榜单开始 -->
|
|
|
<div class="classroom_chat_con classroom_chat_con4" v-show="selectTapId == 4" v-infinite-scroll="get_live_reward"
|
|
|
:infinite-scroll-immediate="liveRewardFinished">
|
|
|
<div v-for="(item, index) in liveRewardList" class="classroom_chat_con_item">
|
|
|
<div v-if="index + 1 == 1" class="classroom_chat_con_noun">
|
|
|
<img src="{__PUBLIC_WEB_PATH}pc/images/live_rank1.png" alt="">
|
|
|
</div>
|
|
|
<div v-else-if="index + 1 == 2" class="classroom_chat_con_noun">
|
|
|
<img src="{__PUBLIC_WEB_PATH}pc/images/live_rank2.png" alt="">
|
|
|
</div>
|
|
|
<div v-else-if="index + 1 == 3" class="classroom_chat_con_noun">
|
|
|
<img src="{__PUBLIC_WEB_PATH}pc/images/live_rank3.png" alt="">
|
|
|
</div>
|
|
|
<div v-else class="classroom_chat_con_noun">
|
|
|
<span>{{ index + 1 > 9 ? index + 1 : '0' + (index + 1) }}</span>
|
|
|
</div>
|
|
|
<div class="classroom_chat_con_user">
|
|
|
<div class="avatar">
|
|
|
<img :src="item.avatar" :alt="item.nickname">
|
|
|
</div>
|
|
|
<div class="nickname">
|
|
|
<span>{{ item.nickname }}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="classroom_chat_con_payEd">
|
|
|
<span>{{ item.total_price }}</span>
|
|
|
<img :src="goldInfo.gold_image" :alt="goldInfo.gold_name">
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<!-- 榜单结束 -->
|
|
|
<div v-show="selectTapId == 1 || (selectTapId == 2 && (user_type == 0 || user_type == 1))" class="classroom_chat_bottom">
|
|
|
<div class="classroom_chat_bottom_top">
|
|
|
<div class="faceList">
|
|
|
<el-popover placement="top" width="332" trigger="hover" popper-class="emoji-popover">
|
|
|
<img v-for="item in emojiList" :src="item.url" :alt="item.name" :title="item.name" @click="sendEmoji(item)">
|
|
|
<span slot="reference" class="face"></span>
|
|
|
</el-popover>
|
|
|
<el-upload action="" :show-file-list="false" :http-request="httpRequest">
|
|
|
<span class="face"></span>
|
|
|
</el-upload>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="classroom_chat_bottom_input">
|
|
|
<input v-model="message" type="text" @keyup.enter="sendMessage">
|
|
|
<button @click="sendMessage">发送</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="container">
|
|
|
<div class="container_detils_con">
|
|
|
<div class="container_selectTap">
|
|
|
<div class="container_selectTap_tip" :style="{ left: tipLeft}">
|
|
|
<img src="{__PUBLIC_WEB_PATH}pc/images/select.png" alt="">
|
|
|
</div>
|
|
|
<div class="container_selectTap_item">
|
|
|
<div class="container_selectTap_item_value" :class="{'selectEd': selectValue == item.value}" v-for="(item, index) in tipList" :key="index"
|
|
|
:ref=`react${item.value}` @click="selectTip(item, index)">
|
|
|
<span>{{item.title}}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="container_introduce">
|
|
|
<div class="introduce" v-if="selectValue == 1" v-html="liveInfo.content"></div>
|
|
|
<div class="catalogue course_catalogue" v-if="selectValue == 2">
|
|
|
<div class="course_catalogue_item" v-for="(item, index) in courseList" :key="item.id" :class="{ active: item.playback_url == PullUrl}"
|
|
|
@click="selectCourse(item)">
|
|
|
<div class="course_catalogue_item_value">
|
|
|
<div class="playback-tag">回放</div>
|
|
|
<div class="course_catalogue_item_value_message">
|
|
|
<span>{{ index > 8 ? index + 1 : '0' + (index + 1) }} | {{ item.playback_name || liveInfo.live_title }}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<el-empty v-if="!courseList.length" image="{__PUBLIC_WEB_PATH}pc/images/empty2.png" description=" "></el-empty>
|
|
|
<el-pagination :page-size="limit" :total="total" :current-page.sync="liveRecordPage" layout="prev, pager, next" prev-text="上一页" next-text="下一页"
|
|
|
hide-on-single-page @current-change="get_live_record_list"></el-pagination>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<base-footer :user-info="userInfo" :public-data="publicData"></base-footer>
|
|
|
<base-login :public-data="publicData" :agree-content="agreeContent"></base-login>
|
|
|
<base-agree :agree-content="agreeContent"></base-agree>
|
|
|
</div>
|
|
|
{/block}
|
|
|
{block name="vm"}
|
|
|
<script>
|
|
|
require([
|
|
|
'vue',
|
|
|
'ELEMENT',
|
|
|
'components/base-header/index',
|
|
|
'components/base-footer/index',
|
|
|
'components/base-login/index',
|
|
|
'components/base-agree/index',
|
|
|
'mixins/base',
|
|
|
'api/auth',
|
|
|
'api/live',
|
|
|
'scripts/util',
|
|
|
'swiper',
|
|
|
'../wap/first/zsff/face/emoji',
|
|
|
// 'hls',
|
|
|
'router/index',
|
|
|
'scripts/socket',
|
|
|
// 'aliplayer',
|
|
|
'css!styles/classroom.css'
|
|
|
], function (Vue, ELEMENT, BaseHeader, BaseFooter, BaseLogin, BaseAgree, baseMixin, authApi, liveApi, util, Swiper, emoji, router, Socket) {
|
|
|
// this.Hls = Hls;
|
|
|
|
|
|
Vue.use(ELEMENT);
|
|
|
Vue.use(router);
|
|
|
var tapList = [
|
|
|
{
|
|
|
id: 1,
|
|
|
label: '聊天'
|
|
|
},
|
|
|
{
|
|
|
id: 2,
|
|
|
label: '课堂'
|
|
|
},
|
|
|
{
|
|
|
id: 3,
|
|
|
label: '讲师推荐'
|
|
|
},
|
|
|
{
|
|
|
id: 4,
|
|
|
label: '榜单'
|
|
|
}
|
|
|
];
|
|
|
var vm = new Vue({
|
|
|
el: '#app',
|
|
|
components: {
|
|
|
'base-header': BaseHeader,
|
|
|
'base-footer': BaseFooter,
|
|
|
'base-login': BaseLogin,
|
|
|
'base-agree': BaseAgree
|
|
|
},
|
|
|
mixins: [baseMixin],
|
|
|
data: {
|
|
|
CommentCount: 0,
|
|
|
CommentTime: 0,
|
|
|
OpenCommentCount: 0,
|
|
|
OpenCommentTime: 0,
|
|
|
PullUrl: '',
|
|
|
UserSum: '0',
|
|
|
goldInfo: {},
|
|
|
lecturer: {},
|
|
|
liveInfo: {},
|
|
|
live_status: -1,
|
|
|
user_type: -1,
|
|
|
workerman: {},
|
|
|
openCommentPage: 1,
|
|
|
commentPage: 1,
|
|
|
liveRewardPage: 1,
|
|
|
liveRecordPage: 1,
|
|
|
limit: 15,
|
|
|
openCommentLoading: false,
|
|
|
openCommentFinished: false,
|
|
|
commentLoading: false,
|
|
|
commentFinished: false,
|
|
|
liveRewardFinished: false,
|
|
|
liveRecordFinished: false,
|
|
|
goodsList: [],
|
|
|
liveRewardList: [],
|
|
|
tipLeft: 0,
|
|
|
selectValue: 1,
|
|
|
tipList: [
|
|
|
{
|
|
|
title: '直播介绍',
|
|
|
value: 1
|
|
|
},
|
|
|
{
|
|
|
title: '回放目录',
|
|
|
value: 2
|
|
|
},
|
|
|
],
|
|
|
userId: 1,
|
|
|
selectTapId: 1,
|
|
|
tapList: [],
|
|
|
messageList: [],
|
|
|
classChatList: [],
|
|
|
giftList: [],
|
|
|
timeOut: '',
|
|
|
// 课程列表
|
|
|
courseList: [],
|
|
|
message: '',
|
|
|
giftRadio: '',
|
|
|
giftInput: 1,
|
|
|
emojiList: [],
|
|
|
isHandshake: false,
|
|
|
total: 0,
|
|
|
socket: null
|
|
|
},
|
|
|
computed: {
|
|
|
canSocket: function () {
|
|
|
return this.workerman.port && this.userInfo && this.userInfo.uid && this.room;
|
|
|
},
|
|
|
canGetReward: function () {
|
|
|
return this.canSocket && this.liveInfo.is_ranking;
|
|
|
}
|
|
|
},
|
|
|
watch: {
|
|
|
canGetReward: function (value) {
|
|
|
if (value) {
|
|
|
this.get_live_reward();
|
|
|
}
|
|
|
},
|
|
|
selectValue: {
|
|
|
handler(val) {
|
|
|
this.$nextTick(() => {
|
|
|
this.tipLeft = this.$refs[`react${val}`][0].offsetLeft + 'px';
|
|
|
})
|
|
|
},
|
|
|
immediate: false
|
|
|
},
|
|
|
canSocket: function (value) {
|
|
|
if (value) {
|
|
|
this.connectSocket();
|
|
|
}
|
|
|
},
|
|
|
giftRadio: function (value) {
|
|
|
if (typeof value === 'string' && !value) {
|
|
|
this.giftInput = 1;
|
|
|
} else {
|
|
|
this.giftInput = value;
|
|
|
}
|
|
|
},
|
|
|
liveInfo: function (value) {
|
|
|
for (var i = tapList.length; i--;) {
|
|
|
if (tapList[i].id === 1 && !value.is_chat) {
|
|
|
tapList.splice(i, 1);
|
|
|
} else if (tapList[i].id === 2 && !value.is_class_chat) {
|
|
|
tapList.splice(i, 1);
|
|
|
} else if (tapList[i].id === 3 && !value.is_live_recommend) {
|
|
|
tapList.splice(i, 1);
|
|
|
} else if (tapList[i].id === 4 && !value.is_ranking) {
|
|
|
tapList.splice(i, 1);
|
|
|
}
|
|
|
}
|
|
|
if (tapList.length) {
|
|
|
this.tapList = tapList;
|
|
|
this.selectTapId = tapList[0].id;
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
created: function () {
|
|
|
this.stream_name = util.getParmas('stream_name');
|
|
|
this.record_id = util.getParmas('record_id');
|
|
|
this.live_studio_index();
|
|
|
this.live_gift_list();
|
|
|
var emojiList = [];
|
|
|
emoji.forEach(function (item) {
|
|
|
emojiList = emojiList.concat(item);
|
|
|
});
|
|
|
this.emojiList = emojiList;
|
|
|
},
|
|
|
methods: {
|
|
|
// 直播间信息
|
|
|
live_studio_index: function () {
|
|
|
var vm = this;
|
|
|
liveApi.live_studio_index({
|
|
|
stream_name: vm.stream_name
|
|
|
}).then(function (res) {
|
|
|
var data = res.data;
|
|
|
vm.CommentCount = data.CommentCount;
|
|
|
vm.CommentTime = data.CommentTime || 0;
|
|
|
vm.OpenCommentCount = data.OpenCommentCount;
|
|
|
vm.OpenCommentTime = data.OpenCommentTime || 0;
|
|
|
vm.PullUrl = data.PullUrl;
|
|
|
vm.UserSum = data.UserSum;
|
|
|
vm.goldInfo = data.goldInfo;
|
|
|
vm.is_ban = data.is_ban;
|
|
|
vm.lecturer = data.lecturer;
|
|
|
vm.liveInfo = data.liveInfo;
|
|
|
vm.live_status = data.live_status;
|
|
|
vm.room = data.room;
|
|
|
vm.user_type = data.user_type;
|
|
|
vm.workerman = data.workerman;
|
|
|
if (vm.liveInfo.is_chat) {
|
|
|
vm.get_open_comment_list();
|
|
|
}
|
|
|
if (vm.liveInfo.is_class_chat) {
|
|
|
vm.get_comment_list();
|
|
|
}
|
|
|
if (vm.liveInfo.is_live_recommend) {
|
|
|
vm.live_goods_list();
|
|
|
}
|
|
|
vm.get_live_record_list();
|
|
|
if (vm.liveInfo.is_play) {
|
|
|
vm.$nextTick(function () {
|
|
|
vm.player = new Aliplayer({
|
|
|
id: 'J_prismPlayer',
|
|
|
height: '100%',
|
|
|
autoplay: true,
|
|
|
isLive: true,
|
|
|
source: vm.PullUrl,
|
|
|
cover: vm.liveInfo.live_image
|
|
|
}, function () {
|
|
|
console.log('播放器创建好了。')
|
|
|
});
|
|
|
});
|
|
|
} else if (vm.liveInfo.is_playback) {
|
|
|
vm.$nextTick(function () {
|
|
|
vm.player = new Aliplayer({
|
|
|
id: 'J_prismPlayer',
|
|
|
height: '100%',
|
|
|
autoplay: true,
|
|
|
isLive: false,
|
|
|
source: vm.PullUrl,
|
|
|
cover: vm.liveInfo.live_image
|
|
|
}, function () {
|
|
|
console.log('播放器创建好了。')
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
document.title = vm.liveInfo.live_title;
|
|
|
}).catch(function (err) {
|
|
|
vm.$message.error(err.msg);
|
|
|
});
|
|
|
},
|
|
|
// 礼物
|
|
|
live_gift_list: function () {
|
|
|
var vm = this;
|
|
|
liveApi.live_gift_list().then(function (res) {
|
|
|
var data = res.data;
|
|
|
data.forEach(function (item) {
|
|
|
item.visible = false;
|
|
|
});
|
|
|
vm.giftList = res.data;
|
|
|
vm.$nextTick(function () {
|
|
|
var mySwiper = new Swiper('.swiper-container', {
|
|
|
slidesPerView: 'auto',
|
|
|
spaceBetween: 10,
|
|
|
navigation: {
|
|
|
nextEl: '.swiper-button-next',
|
|
|
prevEl: '.swiper-button-prev'
|
|
|
},
|
|
|
observer: true,
|
|
|
observeParents: true,
|
|
|
observeSlideChildren: true
|
|
|
})
|
|
|
});
|
|
|
}).catch(function (err) {
|
|
|
vm.$message.error(err.msg);
|
|
|
});
|
|
|
},
|
|
|
// 聊天
|
|
|
get_open_comment_list: function () {
|
|
|
var vm = this;
|
|
|
if (vm.openCommentLoading || vm.openCommentFinished) {
|
|
|
return;
|
|
|
}
|
|
|
vm.openCommentLoading = true;
|
|
|
liveApi.get_open_comment_list({
|
|
|
page: vm.openCommentPage++,
|
|
|
limit: vm.limit,
|
|
|
live_id: vm.room,
|
|
|
add_time: vm.OpenCommentTime
|
|
|
}).then(function (res) {
|
|
|
var list = res.data.list;
|
|
|
vm.openCommentLoading = false;
|
|
|
vm.openCommentFinished = vm.limit > list.length;
|
|
|
vm.scrollHeight1 = vm.$refs.chatContent1.scrollHeight;
|
|
|
list.forEach(function (item) {
|
|
|
if (item.type == 1) {
|
|
|
item.content = vm.replace_em(item.content);
|
|
|
}
|
|
|
vm.messageList.unshift(item);
|
|
|
});
|
|
|
vm.$nextTick(function () {
|
|
|
vm.$refs.chatContent1.scrollTop = vm.$refs.chatContent1.scrollHeight - vm.scrollHeight1;
|
|
|
for (var i = vm.$refs.chatContent1.getElementsByTagName('img').length; i--;) {
|
|
|
vm.$refs.chatContent1.getElementsByTagName('img')[i].addEventListener('load', function () {
|
|
|
vm.$refs.chatContent1.scrollTop = vm.$refs.chatContent1.scrollHeight - vm.scrollHeight1;
|
|
|
vm.scrollTop1 = vm.$refs.chatContent1.scrollTop;
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
if (vm.openCommentPage == 2) {
|
|
|
if (vm.socket) {
|
|
|
vm.socket.send({
|
|
|
uid: vm.userInfo.uid,
|
|
|
room: vm.room,
|
|
|
type: 'room_user_count'
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
},
|
|
|
// 课堂
|
|
|
get_comment_list: function () {
|
|
|
var vm = this;
|
|
|
if (vm.commentLoading || vm.commentFinished) {
|
|
|
return;
|
|
|
}
|
|
|
vm.commentLoading = true;
|
|
|
liveApi.get_comment_list({
|
|
|
page: vm.commentPage++,
|
|
|
limit: vm.limit,
|
|
|
live_id: vm.liveInfo.id,
|
|
|
add_time: vm.CommentTime
|
|
|
}).then(function (res) {
|
|
|
var list = res.data.list;
|
|
|
vm.commentLoading = false;
|
|
|
vm.commentFinished = vm.limit > list.length;
|
|
|
vm.scrollHeight2 = vm.$refs.chatContent2.scrollHeight;
|
|
|
list.forEach(function (item) {
|
|
|
if (item.type == 1) {
|
|
|
item.content = vm.replace_em(item.content);
|
|
|
}
|
|
|
vm.classChatList.unshift(item);
|
|
|
});
|
|
|
vm.$nextTick(function () {
|
|
|
vm.$refs.chatContent2.scrollTop = vm.$refs.chatContent2.scrollHeight - vm.scrollHeight2;
|
|
|
for (var i = vm.$refs.chatContent2.getElementsByTagName('img').length; i--;) {
|
|
|
vm.$refs.chatContent2.getElementsByTagName('img')[i].addEventListener('load', function () {
|
|
|
vm.$refs.chatContent2.scrollTop = vm.$refs.chatContent2.scrollHeight - vm.scrollHeight2;
|
|
|
vm.scrollTop2 = vm.$refs.chatContent2.scrollTop;
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
}).catch(function (err) {
|
|
|
vm.$message.error(err.msg);
|
|
|
});
|
|
|
},
|
|
|
// 讲师推荐
|
|
|
live_goods_list: function () {
|
|
|
var vm = this;
|
|
|
liveApi.live_goods_list({
|
|
|
live_id: vm.liveInfo.id,
|
|
|
}).then(function (res) {
|
|
|
vm.goodsList = res.data.list;
|
|
|
}).catch(function (err) {
|
|
|
vm.$message.error(err.msg);
|
|
|
});
|
|
|
},
|
|
|
// 排行榜
|
|
|
get_live_reward: function () {
|
|
|
var vm = this;
|
|
|
liveApi.get_live_reward({
|
|
|
uid: vm.userInfo.uid,
|
|
|
live_id: vm.liveInfo.id,
|
|
|
page: vm.liveRewardPage++,
|
|
|
limit: vm.limit
|
|
|
}).then(function (res) {
|
|
|
var list = res.data.list;
|
|
|
vm.liveRewardFinished = vm.limit > list.length;
|
|
|
vm.liveRewardList = vm.liveRewardList.concat(list);
|
|
|
}).catch(function (err) {
|
|
|
vm.$message.error(err.msg);
|
|
|
});
|
|
|
},
|
|
|
// 回放目录
|
|
|
get_live_record_list: function () {
|
|
|
var vm = this;
|
|
|
liveApi.get_live_record_list({
|
|
|
special_id: vm.liveInfo.special_id,
|
|
|
page: vm.liveRecordPage,
|
|
|
limit: vm.limit
|
|
|
}).then(function (res) {
|
|
|
vm.courseList = res.data.data;
|
|
|
vm.total = res.data.count;
|
|
|
}).catch(function (err) {
|
|
|
vm.$message.error(err.msg);
|
|
|
});
|
|
|
},
|
|
|
socketOpen: function () {
|
|
|
this.socket.send({
|
|
|
uid: vm.userInfo.uid,
|
|
|
room: vm.room,
|
|
|
role: 'user',
|
|
|
type: 'handshake'
|
|
|
});
|
|
|
},
|
|
|
socketMessage: function (data) {
|
|
|
switch (data.type) {
|
|
|
case 'handshake':
|
|
|
this.isHandshake = true;
|
|
|
break;
|
|
|
case 'room_user_count':
|
|
|
this.receiveWelcome(data);
|
|
|
break;
|
|
|
case 'message':
|
|
|
this.receiveMessage(data);
|
|
|
break;
|
|
|
case 'live_reward':
|
|
|
this.receiveGift(data);
|
|
|
break;
|
|
|
case 'live_ing':
|
|
|
this.changeLive(true, data.pull_url);
|
|
|
break;
|
|
|
case 'live_end':
|
|
|
this.changeLive();
|
|
|
break;
|
|
|
case 'recall':
|
|
|
this.changeLive(false);
|
|
|
break;
|
|
|
case 'ban':
|
|
|
this.changeLive(false);
|
|
|
break;
|
|
|
}
|
|
|
},
|
|
|
connectSocket: function (port, uid, room) {
|
|
|
this.socket = new Socket({
|
|
|
port: this.workerman.port,
|
|
|
params: {
|
|
|
uid: this.userInfo.uid,
|
|
|
room: this.room
|
|
|
},
|
|
|
onopen: this.socketOpen,
|
|
|
onmessage: this.socketMessage
|
|
|
});
|
|
|
},
|
|
|
handleSelectTap(item) {
|
|
|
this.selectTapId = item.id;
|
|
|
},
|
|
|
selectTip(item, index) {
|
|
|
this.selectValue = item.value
|
|
|
},
|
|
|
// 展开选中得课程
|
|
|
selectCourse(item) {
|
|
|
vm.PullUrl = item.playback_url;
|
|
|
if (vm.player) {
|
|
|
vm.player.dispose();
|
|
|
vm.player = null;
|
|
|
}
|
|
|
vm.player = new Aliplayer({
|
|
|
id: 'J_prismPlayer',
|
|
|
height: '100%',
|
|
|
autoplay: true,
|
|
|
isLive: false,
|
|
|
source: vm.PullUrl,
|
|
|
cover: vm.liveInfo.live_image
|
|
|
}, function () {
|
|
|
console.log('播放器创建好了。')
|
|
|
});
|
|
|
},
|
|
|
// 点击发送
|
|
|
sendMessage: function () {
|
|
|
if (this.is_ban) {
|
|
|
this.$message('您已被禁言!');
|
|
|
return;
|
|
|
}
|
|
|
if (!this.message.trim()) {
|
|
|
return;
|
|
|
}
|
|
|
if (this.socket) {
|
|
|
this.socket.send({
|
|
|
uid: this.userInfo.uid,
|
|
|
room: this.room,
|
|
|
content: this.message,
|
|
|
type: 'send',
|
|
|
ms_type: 1
|
|
|
});
|
|
|
this.message = '';
|
|
|
}
|
|
|
},
|
|
|
// 接收消息
|
|
|
receiveMessage: function (data) {
|
|
|
this.messageList.push({
|
|
|
id: data.id,
|
|
|
uid: data.userInfo.uid,
|
|
|
avatar: data.userInfo.avatar,
|
|
|
nickname: data.userInfo.nickname,
|
|
|
user_type: data.user_type,
|
|
|
content: data.m_type == 1 ? this.replace_em(data.message) : data.message,
|
|
|
type: data.m_type
|
|
|
});
|
|
|
if (data.user_type == 0 || data.user_type == 1) {
|
|
|
this.classChatList.push({
|
|
|
avatar: data.userInfo.avatar,
|
|
|
nickname: data.userInfo.nickname,
|
|
|
content: data.m_type == 1 ? this.replace_em(data.message) : data.message,
|
|
|
user_type: data.user_type,
|
|
|
type: data.m_type
|
|
|
});
|
|
|
this.$nextTick(function () {
|
|
|
this.$refs.chatContent2.scrollTop = this.$refs.chatContent2.scrollHeight - this.$refs.chatContent2.offsetHeight;
|
|
|
for (var i = this.$refs.chatContent2.getElementsByTagName('img').length; i--;) {
|
|
|
this.$refs.chatContent2.getElementsByTagName('img')[i].addEventListener('load', function () {
|
|
|
vm.$refs.chatContent2.scrollTop = vm.$refs.chatContent2.scrollHeight - vm.$refs.chatContent2.offsetHeight;
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
this.$nextTick(function () {
|
|
|
this.$refs.chatContent1.scrollTop = this.$refs.chatContent1.scrollHeight - this.$refs.chatContent1.offsetHeight;
|
|
|
for (var i = this.$refs.chatContent1.getElementsByTagName('img').length; i--;) {
|
|
|
this.$refs.chatContent1.getElementsByTagName('img')[i].addEventListener('load', function () {
|
|
|
vm.$refs.chatContent1.scrollTop = vm.$refs.chatContent1.scrollHeight - vm.$refs.chatContent1.offsetHeight;
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
},
|
|
|
// 点击充值
|
|
|
rechargeIcon: function () {
|
|
|
window.location.assign(this.$router.user + '?activeName=currency');
|
|
|
},
|
|
|
// 点击赠送
|
|
|
sendGift: function (gift) {
|
|
|
var live_gift_num = this.giftInput;
|
|
|
if (this.giftRadio) {
|
|
|
if (parseInt(this.giftRadio) * parseFloat(gift.live_gift_price) > this.userInfo.gold_num) {
|
|
|
this.$message('您的' + this.goldInfo.gold_name + '不足,请先去充值');
|
|
|
return;
|
|
|
}
|
|
|
live_gift_num = this.giftRadio;
|
|
|
} else {
|
|
|
if (this.giftInput * parseFloat(gift.live_gift_price) > this.userInfo.gold_num) {
|
|
|
this.$message('您的' + this.goldInfo.gold_name + '不足,请先去充值');
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
if (this.socket) {
|
|
|
this.socket.send({
|
|
|
uid: this.userInfo.uid,
|
|
|
type: 'live_reward',
|
|
|
live_gift_id: gift.id,
|
|
|
live_gift_num: live_gift_num,
|
|
|
live_id: this.room,
|
|
|
special_id: this.liveInfo.special_id
|
|
|
});
|
|
|
}
|
|
|
},
|
|
|
// 接收礼物
|
|
|
receiveGift: function (data) {
|
|
|
if (!data.recharge_status) {
|
|
|
this.$message('您的' + this.goldInfo.gold_name + '不足,请先去充值');
|
|
|
return;
|
|
|
}
|
|
|
var gift = this.giftList.find(function (item) {
|
|
|
return item.id == data.live_gift_id;
|
|
|
});
|
|
|
this.messageList.push({
|
|
|
uid: data.uid,
|
|
|
nickname: data.username,
|
|
|
avatar: data.user_avatar,
|
|
|
user_type: data.user_type,
|
|
|
type: 4,
|
|
|
content: '赠送给主播',
|
|
|
gift_image: gift.live_gift_show_img,
|
|
|
gift_name: gift.live_gift_name,
|
|
|
gift_num: data.live_gift_num
|
|
|
});
|
|
|
this.$nextTick(function () {
|
|
|
for (var i = this.$refs.chatContent1.getElementsByTagName('img').length; i--;) {
|
|
|
this.$refs.chatContent1.getElementsByTagName('img')[i].addEventListener('load', function () {
|
|
|
vm.$refs.chatContent1.scrollTop = vm.$refs.chatContent1.scrollHeight - vm.$refs.chatContent1.offsetHeight;
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
this.getUserInfo();
|
|
|
},
|
|
|
// 接收欢迎语
|
|
|
receiveWelcome: function (data) {
|
|
|
this.UserSum = data.onLine_user_count;
|
|
|
this.messageList.push({
|
|
|
uid: this.liveInfo.uid,
|
|
|
nickname: this.lecturer.lecturer_name,
|
|
|
avatar: this.lecturer.lecturer_head,
|
|
|
user_type: data.user_type,
|
|
|
type: 1,
|
|
|
content: data.notice_content
|
|
|
});
|
|
|
this.$nextTick(function () {
|
|
|
this.$refs.chatContent1.scrollTop = this.$refs.chatContent1.scrollHeight - this.$refs.chatContent1.offsetHeight;
|
|
|
});
|
|
|
},
|
|
|
// 点击表情
|
|
|
sendEmoji: function (emoji) {
|
|
|
this.message += emoji.type;
|
|
|
},
|
|
|
// 替换表情
|
|
|
replace_em: function (str) {
|
|
|
str = str.replace(/\</g, '<');
|
|
|
str = str.replace(/\>/g, '>');
|
|
|
str = str.replace(/\n/g, '<br/>');
|
|
|
str = str.replace(/\[qq_([0-9]*)\]/g, "<img class='img' src='/wap/first/zsff/face/emoji1/$1.gif' />");
|
|
|
str = str.replace(/\[em_([0-9]*)\]/g, "<img class='img' src='/wap/first/zsff/face/emoji2/$1.png' />");
|
|
|
str = str.replace(/\[other_([0-9]*)\]/g, "<img class='img' src='/wap/first/zsff/face/emoji3/$1.png' />");
|
|
|
return str;
|
|
|
},
|
|
|
// 聊天向下滚动
|
|
|
chatContentScroll1: function () {
|
|
|
if (this.scrollTop1 > this.$refs.chatContent1.scrollTop && !this.$refs.chatContent1.scrollTop) {
|
|
|
this.get_open_comment_list();
|
|
|
}
|
|
|
},
|
|
|
// 课堂向下滚动
|
|
|
chatContentScroll2: function () {
|
|
|
if (this.scrollTop2 > this.$refs.chatContent2.scrollTop && !this.$refs.chatContent2.scrollTop) {
|
|
|
this.get_comment_list();
|
|
|
}
|
|
|
},
|
|
|
// 点击讲师推荐的专题
|
|
|
goSpecial: function (special) {
|
|
|
if (special.gfake_type) {
|
|
|
window.location.assign(this.$router.activity_detail + '?id=' + special.id);
|
|
|
} else {
|
|
|
if (special.is_light) {
|
|
|
window.location.href = this.$router.single_detail + '?id=' + special.id;
|
|
|
} else {
|
|
|
window.location.href = this.$router.special_detail + '?id=' + special.id;
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
// 发送图片
|
|
|
httpRequest: function (elUpload) {
|
|
|
var vm = this;
|
|
|
var formData = new FormData();
|
|
|
formData.append('file', elUpload.file)
|
|
|
authApi.upload(formData).then(function (res) {
|
|
|
if (vm.socket) {
|
|
|
vm.socket.send({
|
|
|
uid: vm.userInfo.uid,
|
|
|
room: vm.room,
|
|
|
content: res.data.url,
|
|
|
type: 'send',
|
|
|
ms_type: 2
|
|
|
});
|
|
|
}
|
|
|
}).catch(function (err) {
|
|
|
vm.$message.error(err.msg);
|
|
|
});
|
|
|
},
|
|
|
// 直播状态改变
|
|
|
changeLive: function () {
|
|
|
this.live_studio_index();
|
|
|
},
|
|
|
onPopoverShow: function () {
|
|
|
if (this.giftRadio) {
|
|
|
this.giftRadio = '';
|
|
|
} else {
|
|
|
this.giftInput = 1;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
});
|
|
|
</script>
|
|
|
{/block} |