123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654 |
- <template>
- <cover-view class="wrapper" :style="'width:'+getBannerStyle.width+'px;height:'+getBannerStyle.height+'px'">
- <cover-view v-if="liveApplyInfo && ownerInfo" class="div room-content wrapper" :style="'width:'+getBannerStyle.width+'px;height:'+getBannerStyle.height+'px'">
- <!-- 头部 start -->
- <room-header :style="'width:'+getBannerStyle.width+'px'" :showcoupon="showcoupon" @attention="attention" :groupInfo="groupInfo"
- :ifLike="ifLike" :ownerInfo="ownerInfo" @coupon="coupon" @quitGroup="quitGroup"></room-header>
- <!-- 头部 end -->
- <!-- 聊天室 start -->
- <chatroom class="chatroom" :style="'width:'+getBannerStyle.width+'px'" :message="messageQueen"></chatroom>
- <!-- 聊天室 end -->
- <!-- 底部 -->
- <room-bottom class="room-bottom" :style="'width:'+getBannerStyle.width+'px'" @send-message="sendMessage" :isTimReady="ifConnect" @like="like"
- @showGift="showGift" @showgoods="showgoods"></room-bottom>
- <!-- 底部 -->
-
-
- <!-- 礼物以及动画 start -->
- <gift-animation v-if="hasgift" class="gift-animation" :avatar="giftAvatar" :nick="giftNick" @hideani="hideani">
- </gift-animation>
- <!-- 礼物以及动画 end -->
-
- <!-- 公告start -->
- <!-- <notice class="notice" :noticeText="noticeText" v-if="roomStatus!=='0'"></notice> -->
- <!-- 公告 end -->
- </cover-view>
- <no-owner v-else></no-owner>
- <uni-popup background-color="#fff" ref="animation" type="bottom">
- <!-- 礼物面板 start -->
- <gifts class="gifts" @hideGift="hideGift" @sendgift="sendgift"></gifts>
- <!-- 礼物面板 end -->
- </uni-popup>
- <uni-popup background-color="#fff" ref="animation2" type="bottom">
- <!-- 商品面板 start -->
- <goods-list class="goodslist" @hidegoods="hidegoods" @buy="buy" :goods="goods">
- </goods-list>
- <!-- 商品面板 end -->
- </uni-popup>
- <uni-popup ref="hascoupon">
- <!-- 优惠券 -->
- <coupon class="coupon" :voucher="voucher" @hidecoupon="hidecoupon" @usecoupon="usecoupon">
- </coupon>
- <!-- 优惠券 -->
- </uni-popup>
- <uni-popup background-color="#fff" ref="confirm" type="dialog">
- <uni-popup-dialog :mode="dialog.mode" :title="dialog.title" :content="dialog.content"
- :placeholder="dialog.content" @confirm="confirmDialog" @close="closeDialog"></uni-popup-dialog>
- </uni-popup>
- </cover-view>
- </template>
- <script>
- import {
- mapState
- } from 'vuex'
- import roomHeader from './header'
- import roomBottom from './bottom'
- import chatroom from './chatroom'
- import gifts from './gifts'
- import coupon from './coupon'
- import notice from './notice'
- import goodsList from './goodslist'
- import giftAnimation from './gift-animation'
- import noOwner from './noowner'
- import {
- joinLive,
- leaveLive,
- addGift,
- addLike
- } from '../../../../api/memberLive'
- import {
- addInstantMessage
- } from '../../../../api/memberInstantMessage'
- import {
- receiveVoucher,
- getStoreVoucher
- } from '../../../../api/homestoredetail'
- import {
- addFavoriteStore,
- delFavoriteStore
- } from '../../../../api/memberFavorite'
- import {
- cartAdd
- } from '../../../../api/homecart'
- export default {
- data() {
- return {
- canReconnect:true,
- dialog: {},
- message: [],
- groupInfo: {},
- ownerInfo: false,
- ifLike: false,
- hasgift: false,
- giftAvatar: '',
- giftNick: '',
- showcoupon: false,
- voucherList: false,
- voucher: {},
- voucherIndex: 0,
- goods: [],
- noticeText: '',
- showChat: true,
- ifConnect: false,
- clientId: false,
- openLive: false,
- closeLive: false,
- lockReconnect: false,
- timeOut: false,
- ifWait: false
- }
- },
- props: ['liveApplyInfo','onlineInfo'],
- components: {
- roomHeader,
- roomBottom,
- chatroom,
- gifts,
- coupon,
- notice,
- goodsList,
- giftAnimation,
- noOwner
- },
- computed: {
- ...mapState({
- config: state => state.config.config,
- user: state => state.member.info
- }),
- getBannerStyle: function () {
- const res = uni.getSystemInfoSync()
- var width = res.windowWidth
- var height = res.windowHeight
- let itemWidth = width
- let itemHeight = height
- return {
- width: itemWidth,
- height: itemHeight
- }
- },
- messageQueen: function() {
- const queenLen = 100 // 内存里面放100条消息,以免观看直播太久撑爆内存
- if (this.message.length > queenLen) {
- const vl = this.message.length - queenLen
- for (let i = 0; i < vl; i++) {
- this.message.shift()
- }
- }
- return this.message
- }
- },
- created() {
- getStoreVoucher(this.liveApplyInfo.live_apply_user_id).then(res => {
- this.voucherList = res.result.voucher_list
- if (this.voucherList.length) {
- this.showcoupon = true
- }
- }).catch(error => {
- uni.showToast({
- icon: 'none',
- title: error.message
- })
- })
- if (this.liveApplyInfo.goods_list) {
- this.goods = this.liveApplyInfo.goods_list
- }
- this.groupInfo = {
- groupID: this.liveApplyInfo.live_apply_id,
- memberNum: this.onlineInfo.online_count
- }
- this.ifLike = this.liveApplyInfo.is_favorate
- this.ownerInfo = {
- avatar: this.liveApplyInfo.live_apply_user_avatar,
- nick: this.liveApplyInfo.live_apply_user_name,
- fans: this.liveApplyInfo.live_apply_fans
- }
- this.openLive = true
- if (this.liveApplyInfo.instant_message_url) {
- this.createWebSocket()
- }
- },
- beforeDestroy: function () {
- this.canReconnect=false
- heartCheck.stop()
- },
- methods: {
- showPopup(id){
- this.$refs[id].open()
- },
- hidePopup(id){
- this.$refs[id].close()
- },
- closeDialog() {},
- confirmDialog(value) {
- switch (this.dialog.condition) {
- case 3:
- addGift(this.liveApplyInfo.live_apply_id).then(res => {
- this.hideGift()
- this.ifWait = false
- }).catch(error => {
- uni.showToast({
- icon: 'none',
- title: error.message
- })
- this.ifWait = false
- })
- break
- case 4:
- if (this.openLive) {
- this.closeLive = true
- }
- if (this.clientId) {
- leaveLive(this.liveApplyInfo.live_apply_id, this.clientId).then(res => {
- uni.navigateBack({
- delta: 1
- })
- }).catch(error => {
- uni.showToast({
- icon: 'none',
- title: error.message
- })
- })
- } else {
- uni.navigateBack({
- delta: 1
- })
- }
- break
- case 5:
- if (this.openLive) {
- this.closeLive = true
- }
- if (this.clientId) {
- leaveLive(this.liveApplyInfo.live_apply_id, this.clientId).then(res => {
- uni.navigateBack({
- delta: 1
- })
- }).catch(error => {
- uni.showToast({
- icon: 'none',
- title: error.message
- })
- })
- } else {
- uni.navigateBack({
- delta: 1
- })
- }
- break
- }
- },
- hidecoupon() {
- this.hidePopup('hascoupon')
- },
- usecoupon() {
- if (this.ifWait) {
- return
- }
- this.ifWait = true
- receiveVoucher(
- this.voucher.vouchertemplate_id
- ).then((res) => {
- this.voucherList.splice(this.voucherIndex, 1)
- if (!this.voucherList.length) {
- this.showcoupon = false
- }
- uni.showToast({
- icon: 'none',
- title: res.message
- })
- this.ifWait = false
- }).catch(function(error) {
- uni.showToast({
- icon: 'none',
- title: error.message
- })
- this.ifWait = false
- })
- this.hidecoupon()
- },
- coupon() {
- this.voucherIndex = Math.floor(Math.random() * this.voucherList.length) % this.voucherList.length
- this.voucher = this.voucherList[this.voucherIndex]
- this.showPopup('hascoupon')
- },
- buy(data) {
- if (this.ifWait) {
- return
- }
- this.ifWait = true
- cartAdd(data.goods_id, 1).then(
- res => {
- uni.showToast({
- icon: 'none',
- title: res.message
- })
- this.ifWait = false
- },
- error => {
- uni.showToast({
- icon: 'none',
- title: error.message
- })
- this.ifWait = false
- }
- )
- },
- hideani() {
- this.hasgift = false
- this.giftAvatar = ''
- this.giftNick = ''
- },
- showgoods() {
- this.showPopup('animation2')
- },
- hidegoods() {
- this.hidePopup('animation2')
- },
- showGift() {
- this.showPopup('animation')
- },
- sendgift() {
- if (this.ifWait) {
- return
- }
- this.ifWait = true
- this.dialog = {
- condition: 3,
- content: '确定要给主播送礼物?'
- }
- this.$refs.confirm.open()
- },
- hideGift() {
- this.hidePopup('animation')
- },
- like() {
- if (this.ifWait) {
- return
- }
- this.ifWait = true
- addLike(this.liveApplyInfo.live_apply_id).then(res => {
- this.ifWait = false
- }).catch(error => {
- this.ifWait = false
- })
- },
- attention() {
- if (this.ifWait) {
- return
- }
- this.ifWait = true
- if (!this.ifLike) {
- addFavoriteStore(this.liveApplyInfo.live_apply_user_id).then(
- response => {
- uni.showToast({
- icon: 'none',
- title: response.message
- })
- this.ifLike = !this.ifLike
- this.ifWait = false
- },
- error => {
- uni.showToast({
- icon: 'none',
- title: error.message
- })
- this.ifWait = false
- }
- )
- } else {
- delFavoriteStore(this.liveApplyInfo.live_apply_user_id).then(
- response => {
- uni.showToast({
- icon: 'none',
- title: response.message
- })
- this.ifLike = !this.ifLike
- this.ifWait = false
- },
- error => {
- uni.showToast({
- icon: 'none',
- title: error.message
- })
- this.ifWait = false
- }
- )
- }
- },
- quitGroup() {
- this.dialog = {
- condition: 4,
- content: '您确认要退出直播吗?'
- }
- this.$refs.confirm.open()
- },
- _getVarsByKey(arr, key) {
- var res
- for (var i = 0; i < arr.length; i++) {
- if (arr[i].key === key) {
- res = arr[i].value
- break
- }
- }
- return res
- },
- toggleChat() {
- this.showChat = !this.showChat
- },
- sendMessage(data) {
- if (!this.ifConnect) {
- uni.showToast({
- icon: 'none',
- title: '未接入聊天系统'
- })
- return
- }
- if (!data) {
- uni.showToast({
- icon: 'none',
- title: '请输入聊天内容'
- })
- return
- }
- addInstantMessage({
- to_id: this.liveApplyInfo.live_apply_id,
- to_type: 2,
- message: data,
- message_type: 0
- }).then(res => {
- uni.showToast({
- icon: 'none',
- title: res.message
- })
- }).catch(error => {
- uni.showToast({
- icon: 'none',
- title: error.message
- })
- })
- },
- goCloseLive() {
- this.dialog = {
- condition: 5,
- title: '退出提醒',
- content: '您确认要退出直播吗?'
- }
- this.$refs.confirm.open()
- },
- createWebSocket() {
- uni.connectSocket({
- url: this.liveApplyInfo.instant_message_url,
- }).then(res => {
- this.init()
- }).catch(error => {
- this.reconnect()
- })
- },
- init() {
- uni.onSocketOpen(res => {
- this.wsOpen()
- })
- uni.onSocketMessage(res => {
- this.wsMessage(res)
- })
- uni.onSocketClose(res => {
- this.wsClose(res)
- })
- uni.onSocketError(res => {
- this.wsError(res)
- })
- },
- reconnect() {
- if (this.lockReconnect) {
- return
- };
- this.lockReconnect = true
- // 没连接上会一直重连,设置延迟避免请求过多
- this.timeOut && clearTimeout(this.timeOut)
- var _this = this
- this.timeOut = setTimeout(function() {
- _this.createWebSocket()
- _this.lockReconnect = false
- }, 4000)
- },
- wsOpen() {
- this.ifConnect = true
- // 心跳检测重置
- heartCheck.start()
- },
- wsMessage(res) {
- var message = JSON.parse(res.data)
- if (!message) {
- uni.showToast({
- icon: 'none',
- title: '消息转换失败:' + res.data
- })
- return
- }
- var type = message.type || ''
- switch (type) {
- // Events.php中返回的init类型的消息,将client_id发给后台进行uid绑定
- case 'init':
- this.clientId = message.client_id
- joinLive(this.liveApplyInfo.live_apply_id, this.clientId).then(res => {
- }).catch(error => {
- uni.showToast({
- icon: 'none',
- title: error.message
- })
- })
- break
- case 'leave':
- this.groupInfo.memberNum = message.online_count
- break
- case 'join':
- this.groupInfo.memberNum = message.online_count
- break
- case 'gift':
- this.hasgift = true
- this.giftAvatar = message.member.member_avatar
- this.giftNick = message.member.member_name
- setTimeout(() => {
- this.hasgift = false
- this.giftAvatar = ''
- this.giftNick = ''
- }, 1000)
- break
- default:
- let msg = []
- msg.push({
- name: message.instant_message_from_name,
- message: message.instant_message,
- id: message.instant_message_id
- })
- this.message = this.message.concat(msg)
- this.$forceUpdate()
- }
- heartCheck.start()
- },
- wsClose(res) {
- this.ifConnect = false
- if (res.reason) {
- uni.showToast({
- icon: 'none',
- title: '聊天系统连接断开:' + res.reason
- })
- }
- if(this.canReconnect){
- this.reconnect();
- }
- },
- wsError(res) {
- uni.showToast({
- icon: 'none',
- title: res.errMsg
- })
- this.reconnect()
- }
- }
- }
- // 心跳检测
- var heartCheck = {
- timeout: 3000,
- timeoutObj: null,
- start: function() {
- var self = this
- this.timeoutObj && clearInterval(this.timeoutObj)
- this.timeoutObj = setInterval(function() {
- // 这里发送一个心跳,后端收到后,返回一个心跳消息,
- uni.sendSocketMessage({
- data: '123456789'
- })
- }, this.timeout)
- },
- stop:function(){
- this.timeoutObj && clearInterval(this.timeoutObj)
- }
- }
- </script>
- <style lang="scss" scoped>
- .wrapper{
- position: fixed;
- top: 0;
- left: 0;
- z-index: 100;
- }
- .room-content {
- position: absolute;
- top:0;
- left:0;
- z-index: 2;
- }
- .room-bottom {
- position: absolute;
- z-index: 2;
- padding-bottom: 20rpx;
- bottom:0;
- left:0;
- /* #ifndef APP-PLUS-NVUE */
- margin-bottom: constant(safe-area-inset-bottom);
- /* 兼容 iOS < 11.2 */
- margin-bottom: env(safe-area-inset-bottom);
- /* 兼容 iOS >= 11.2 */
- /* #endif */
- }
- .chatroom {
- left:0;
- height: 800rpx;
- position: absolute;
- bottom: 100rpx;
- z-index: 100;
- padding: 22rpx;
- overflow: hidden;
- }
- .gifts{
- height: 800rpx;
- }
- .goodslist {
- height: 800rpx;
- }
- .gift-animation {
- position: absolute;
- z-index: 100;
- top: 500rpx;
- left: 20rpx;
- height: 170rpx;
- /* #ifndef APP-PLUS-NVUE */
- display: flex;
- /* #endif */
- flex-direction: column;
- justify-content: center;
- }
- .coupon {
- }
- .notice {
- position: absolute;
- left: 20rpx;
- bottom: 50vh;
- /* #ifndef APP-PLUS-NVUE */
- max-width: 60vw;
- /* #endif */
- }
- </style>
|