Commit 8376444d by xiaolanchong

pc样式 红包样式 rem 接口不过网关

parent 5b9c006c

2.59 KB | W: | H:

4.54 KB | W: | H:

assets/img/phone-head.png
assets/img/phone-head.png
assets/img/phone-head.png
assets/img/phone-head.png
  • 2-up
  • Swipe
  • Onion skin
<template> <template>
<div class="auth"> <div class="auth-box">
<div class="watch-pay" v-if="isWatchPay" @click="goAuth"> <div class="watch-pay" v-if="isWatchPay" @click="goAuth">
<img src="./img/pay.png" alt="" /> <img src="./img/pay.png" alt="" />
<span>免费试看 {{ expire | formatTime("mm:ss") }}</span> <span>免费试看 {{ expire | formatTime('mm:ss') }}</span>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { getPayWatchInfo } from "@/plugins/API/apiAuth"; import { getPayWatchInfo } from '@/plugins/API/apiAuth';
import { mapGetters } from "vuex"; import { mapGetters } from 'vuex';
export default { export default {
name: 'auth-box',
data() { data() {
return { return {
timet: null, timet: null,
...@@ -21,8 +22,8 @@ export default { ...@@ -21,8 +22,8 @@ export default {
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
channelInfo: "channelInfo", channelInfo: 'channelInfo',
jumpUrls: "jumpUrls" jumpUrls: 'jumpUrls'
}) })
}, },
mounted() { mounted() {
...@@ -85,27 +86,28 @@ export default { ...@@ -85,27 +86,28 @@ export default {
<style lang="less" scoped> <style lang="less" scoped>
.watch-pay { .watch-pay {
display: inline-block; display: inline-block;
height: 35px; height: 0.35rem;
line-height: 35px; line-height: 0.35rem;
padding: 0 19px 0 7px; padding: 0 0.19rem 0 0.07rem;
position: absolute; position: absolute;
bottom: 60px; bottom: 0.6rem;
left: 9px; left: 0.09rem;
z-index: 110; z-index: 110;
background-color: rgba(0, 141, 246, 0.5); background-color: rgba(0, 141, 246, 0.5);
border-radius: 10px; border-radius: 0.1rem;
font-size: 0; font-size: 0;
cursor: pointer;
img { img {
vertical-align: middle; vertical-align: middle;
display: inline-block; display: inline-block;
margin-right: 5px; margin-right: 0.05rem;
width: 16px; width: 0.16rem;
height: 16px; height: 0.16rem;
} }
span { span {
vertical-align: middle; vertical-align: middle;
display: inline-block; display: inline-block;
font-size: 14px; font-size: 0.14rem;
color: #fff; color: #fff;
} }
} }
......
<template> <template>
<div class="encrypt"> <div class="encrypt">
<div class="box"> <div class="box">
<div class="title">{{ channelInfo.tips || "欢迎观看直播" }}</div> <div class="title">{{ channelInfo.tips || '欢迎观看直播' }}</div>
<input <input class="pass" type="text" name="password" v-model="password" placeholder="请输入密码" />
class="pass"
type="text"
name="password"
v-model="password"
placeholder="请输入密码"
/>
<button type="button" class="sub" @click="_sub">立即登录</button> <button type="button" class="sub" @click="_sub">立即登录</button>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { checkPassword } from "@/plugins/API/apiAll"; import { checkPassword } from '@/plugins/API/apiAll';
import { mapGetters, mapMutations } from "vuex"; import { mapGetters, mapMutations } from 'vuex';
export default { export default {
name: 'encrypt-box',
data() { data() {
return { return {
password: "" password: ''
}; };
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
type: "type", type: 'type',
channelInfo: "channelInfo" channelInfo: 'channelInfo'
}), }),
tokenKey() { tokenKey() {
return `encrypt-${this.type}-${this.channelInfo.id}`; return `encrypt-${this.type}-${this.channelInfo.id}`;
...@@ -37,10 +32,10 @@ export default { ...@@ -37,10 +32,10 @@ export default {
}, },
methods: { methods: {
...mapMutations({ ...mapMutations({
set_encrypt: "set_encrypt" set_encrypt: 'set_encrypt'
}), }),
async get_encrypt() { async get_encrypt() {
let passToken = this.$cookie.get(this.tokenKey) || ""; let passToken = this.$cookie.get(this.tokenKey) || '';
if (passToken) { if (passToken) {
const res = await checkPassword({ const res = await checkPassword({
id: this.channelInfo.id, id: this.channelInfo.id,
...@@ -77,7 +72,7 @@ export default { ...@@ -77,7 +72,7 @@ export default {
z-index: 2000; z-index: 2000;
width: 100%; width: 100%;
height: 100%; height: 100%;
background: url("./img/encrypt.jpg") no-repeat center center; background: url('./img/encrypt.jpg') no-repeat center center;
background-size: cover; background-size: cover;
.box { .box {
...@@ -85,7 +80,7 @@ export default { ...@@ -85,7 +80,7 @@ export default {
top: 50%; top: 50%;
left: 50%; left: 50%;
width: 100%; width: 100%;
max-width: 300px; max-width: 3rem;
transform: translate(-50%, -70%); transform: translate(-50%, -70%);
.title, .title,
.pass, .pass,
...@@ -94,22 +89,22 @@ export default { ...@@ -94,22 +89,22 @@ export default {
margin: auto; margin: auto;
} }
.title { .title {
margin-bottom: 80px; margin-bottom: 0.8rem;
font-size: 30px; font-size: 0.3rem;
color: #fff; color: #fff;
text-align: center; text-align: center;
} }
.pass { .pass {
margin-bottom: 20px; margin-bottom: 0.2rem;
width: 100%; width: 100%;
max-width: 300px; max-width: 3rem;
height: 50px; height: 0.5rem;
background-color: transparent; background-color: transparent;
border: 1px solid #c9edec; border: 0.01rem solid #c9edec;
color: #ffffff; color: #ffffff;
text-align: center; text-align: center;
font-size: 16px; font-size: 0.16rem;
border-radius: 50px; border-radius: 0.5rem;
outline: none; outline: none;
&::-webkit-input-placeholder { &::-webkit-input-placeholder {
color: #bae0e0; color: #bae0e0;
...@@ -117,14 +112,14 @@ export default { ...@@ -117,14 +112,14 @@ export default {
} }
.sub { .sub {
width: 100%; width: 100%;
max-width: 300px; max-width: 3rem;
height: 50px; height: 0.5rem;
background-color: #ffffff; background-color: #ffffff;
border: 1px solid #ffffff; border: 0.01rem solid #ffffff;
color: #1fb5ad; color: #1fb5ad;
text-align: center; text-align: center;
font-size: 16px; font-size: 0.16rem;
border-radius: 50px; border-radius: 0.5rem;
outline: none; outline: none;
} }
} }
......
<template> <template>
<div class="extend-ad"> <div class="extend-ad">
<transition name="move-right"> <transition name="move-right">
<mid-right <mid-right v-if="midRightConfig.isDisable" :config="midRightConfig"></mid-right>
v-if="midRightConfig.isDisable"
:config="midRightConfig"
></mid-right>
</transition> </transition>
<transition name="fade"> <transition name="fade">
<mid-box v-if="midConfig.isDisable" :config="midConfig"></mid-box> <mid-box v-if="midConfig.isDisable" :config="midConfig"></mid-box>
...@@ -12,12 +9,13 @@ ...@@ -12,12 +9,13 @@
</div> </div>
</template> </template>
<script> <script>
import { getChannelAdConfig } from "@/plugins/API/apiExtend"; import { getChannelAdConfig } from '@/plugins/API/apiExtend';
import { mapGetters } from "vuex"; import { mapGetters } from 'vuex';
const midBox = resolve => require(["./mid"], resolve); const midBox = resolve => require(['./mid'], resolve);
const midRight = resolve => require(["./midRight"], resolve); const midRight = resolve => require(['./midRight'], resolve);
export default { export default {
name: 'extend-ad-box',
components: { components: {
midBox, midBox,
midRight midRight
...@@ -29,7 +27,7 @@ export default { ...@@ -29,7 +27,7 @@ export default {
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
channelInfo: "channelInfo" channelInfo: 'channelInfo'
}), }),
midConfig() { midConfig() {
return this.adConfig.mid || {}; return this.adConfig.mid || {};
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
</template> </template>
<script> <script>
export default { export default {
name: 'extend-ad-mid',
props: { props: {
config: {} config: {}
}, },
...@@ -50,11 +51,11 @@ export default { ...@@ -50,11 +51,11 @@ export default {
.mid__box__img { .mid__box__img {
flex: 0 0 auto; flex: 0 0 auto;
margin: auto; margin: auto;
padding-bottom: 40px; padding-bottom: 0.4rem;
position: relative; position: relative;
width: 90%; width: 90%;
max-width: 315px; max-width: 3.15rem;
height: 400px; height: 4rem;
max-height: 90%; max-height: 90%;
a, a,
img { img {
...@@ -66,11 +67,11 @@ export default { ...@@ -66,11 +67,11 @@ export default {
.mid__box__img--close { .mid__box__img--close {
position: absolute; position: absolute;
bottom: 0; bottom: 0;
left: calc(50% - 15px); left: calc(50% - 0.15rem);
z-index: 100; z-index: 100;
width: 30px; width: 0.3rem;
height: 30px; height: 0.3rem;
background-image: url("./img/icon-close.png"); background-image: url('./img/icon-close.png');
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center center; background-position: center center;
background-size: 100% 100%; background-size: 100% 100%;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
</template> </template>
<script> <script>
export default { export default {
name: 'extend-ad-midRight',
props: { props: {
config: {} config: {}
}, },
...@@ -45,7 +46,7 @@ export default { ...@@ -45,7 +46,7 @@ export default {
.mid-right__box__img { .mid-right__box__img {
position: relative; position: relative;
display: inline-block; display: inline-block;
height: 50px; height: 0.5rem;
a, a,
img { img {
display: block; display: block;
...@@ -54,12 +55,12 @@ export default { ...@@ -54,12 +55,12 @@ export default {
} }
.mid-right__box__img--close { .mid-right__box__img--close {
position: absolute; position: absolute;
top: -10px; top: -0.1rem;
left: -10px; left: -0.1rem;
z-index: 100; z-index: 100;
width: 20px; width: 0.2rem;
height: 20px; height: 0.2rem;
background-image: url("./img/icon-close.png"); background-image: url('./img/icon-close.png');
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center center; background-position: center center;
background-size: 100% 100%; background-size: 100% 100%;
......
...@@ -9,8 +9,9 @@ ...@@ -9,8 +9,9 @@
</div> </div>
</template> </template>
<script> <script>
import { mapGetters } from "vuex"; import { mapGetters } from 'vuex';
export default { export default {
name: 'extend-commodity-box',
data() { data() {
return { return {
spread: this.$route.query.spread, spread: this.$route.query.spread,
...@@ -19,7 +20,7 @@ export default { ...@@ -19,7 +20,7 @@ export default {
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
advertMiddle: "advertMiddle" advertMiddle: 'advertMiddle'
}), }),
commodity() { commodity() {
let list = this.advertMiddle.list || []; let list = this.advertMiddle.list || [];
...@@ -34,14 +35,14 @@ export default { ...@@ -34,14 +35,14 @@ export default {
} }
}, },
mounted() { mounted() {
this.$Bus.$on("bus-commodity", this.setCommodity); this.$Bus.$on('bus-commodity', this.setCommodity);
}, },
methods: { methods: {
setCommodity(list) { setCommodity(list) {
this.list = list.map(x => { this.list = list.map(x => {
let l = x.l; let l = x.l;
if (this.spread) { if (this.spread) {
l += `${l.split("?")[1] ? "&" : "?"}spread=${this.spread}`; l += `${l.split('?')[1] ? '&' : '?'}spread=${this.spread}`;
} }
x.l = l; x.l = l;
return x; return x;
...@@ -57,7 +58,7 @@ export default { ...@@ -57,7 +58,7 @@ export default {
} }
}, },
beforeDestroy() { beforeDestroy() {
this.$Bus.$off("bus-commodity", this.setCommodity); this.$Bus.$off('bus-commodity', this.setCommodity);
} }
}; };
</script> </script>
......
<template> <template>
<div class="camera" ref="cameraBox"> <div class="camera-box" ref="cameraBox">
<div class="go-left" @click="_scrollGo('left')"></div> <div class="go-left" @click="_scrollGo('left')"></div>
<div class="list-box" ref="listBox"> <div class="list-box">
<ul class="list" ref="list"> <ul class="list" :style="{'left': page * -100 +'%'}">
<li <li
class="item" class="item"
:class="{ 'z-active': playerInfo.playUrl == item.playUrl }" :class="{ 'z-active': playerInfo.playUrl == item.playUrl }"
...@@ -10,8 +10,11 @@ ...@@ -10,8 +10,11 @@
:key="index" :key="index"
@click="_changePlayer(item.playUrl, item.id)" @click="_changePlayer(item.playUrl, item.id)"
> >
<div class="mark">{{ item.name }}</div> <div class="box">
<img v-if="item.thumbnail" :src="item.thumbnail" alt="" class="img" /> <div class="name">{{ item.name }}</div>
<img class="img" v-if="item.thumbnail" :src="item.thumbnail" alt="" />
<div class="icon" v-else></div>
</div>
</li> </li>
</ul> </ul>
</div> </div>
...@@ -20,46 +23,41 @@ ...@@ -20,46 +23,41 @@
</template> </template>
<script> <script>
import { getCaremaList } from "@/plugins/API/apiAll"; import { getCaremaList } from '@/plugins/API/apiAll';
import { mapGetters, mapMutations } from "vuex"; import { mapGetters, mapMutations } from 'vuex';
export default { export default {
name: 'pc-camera-box',
data() { data() {
return { return {
list: [], page: 0,
list: []
}; };
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
channelInfo: "channelInfo", channelInfo: 'channelInfo',
playerInfo: "playerInfo", playerInfo: 'playerInfo'
}), }),
}, maxPage(){
watch: { return Math.floor(this.list.length / 6);
playerInfo: { }
handler() {
this.$nextTick(() => {
this._scroll();
});
},
deep: true,
},
}, },
mounted() { mounted() {
this._getCaremaList(); this._getCaremaList();
}, },
methods: { methods: {
...mapMutations({ ...mapMutations({
set_playerInfo: "set_playerInfo", set_playerInfo: 'set_playerInfo'
}), }),
// 获取多机位 // 获取多机位
async _getCaremaList() { async _getCaremaList() {
const res = await getCaremaList({ const res = await getCaremaList({
id: this.channelInfo.id, id: this.channelInfo.id,
uin: this.channelInfo.uin, uin: this.channelInfo.uin
}); });
if (res.code === 200 && res.errorCode === 0) { if (res.code === 200 && res.errorCode === 0) {
let list = res.data || []; let list = res.data || [];
this.list = list.filter((x) => { this.list = list.filter(x => {
return x.display; return x.display;
}); });
} }
...@@ -70,52 +68,33 @@ export default { ...@@ -70,52 +68,33 @@ export default {
info.cameraId = id; info.cameraId = id;
this.set_playerInfo(info); this.set_playerInfo(info);
}, },
_scroll() {
let dom = document.querySelector(".camera .item.z-active");
if (dom) {
this.$refs.list.style.left = `-${dom.offsetLeft}px`;
}
},
_scrollGo(go) { _scrollGo(go) {
let listBox = this.$refs.listBox.clientWidth; let page = this.page
let list = document.querySelectorAll(".camera .item").length * 330; if (go === 'left') {
let left = parseInt(this.$refs.list.style.left, 10); page = page - 1 > 0 ? page - 1 : 0;
if (go === "left") { } else if (go === 'right') {
if (left + listBox >= 0) { page = page + 1 <= this.maxPage ? page + 1 : this.maxPage;
left = 0;
} else {
left = left + listBox;
}
} else if (go === "right") {
if (-(left - listBox) >= list) {
left = -list;
} else {
left = left - listBox;
}
} }
this.$refs.list.style.left = `${left}px`; this.page = page
}, }
}, },
}; };
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.camera { .camera-box {
display: flex; display: flex;
margin: 10px 0;
padding: 5px 0; padding: 5px 0;
background-color: rgba(225, 225, 225, 0.6); background-color: #2f3035;
border-radius: 8px;
font-size: 0; font-size: 0;
.go-left, .go-left,
.go-right { .go-right {
position: relative; position: relative;
flex: 0 0 30px; flex: 0 0 30px;
width: 30px; width: 30px;
cursor: pointer; cursor: pointer;
&:before { &:before {
content: " "; content: ' ';
display: block; display: block;
position: absolute; position: absolute;
top: 50%; top: 50%;
...@@ -129,19 +108,19 @@ export default { ...@@ -129,19 +108,19 @@ export default {
.go-left { .go-left {
&:before { &:before {
margin: -10px -15px; margin: -10px -15px;
border-right-color: #adadad; border-right-color: #27282e;
} }
&:hover:before { &:hover:before {
border-right-color: var(--main-color); border-right-color: #fff;
} }
} }
.go-right { .go-right {
&:before { &:before {
margin: -10px -5px; margin: -10px -5px;
border-left-color: #adadad; border-left-color: #27282e;
} }
&:hover:before { &:hover:before {
border-left-color: var(--main-color); border-left-color: #fff;
} }
} }
.list-box { .list-box {
...@@ -149,51 +128,51 @@ export default { ...@@ -149,51 +128,51 @@ export default {
width: 100%; width: 100%;
margin: 0 5px; margin: 0 5px;
overflow: hidden; overflow: hidden;
.list { .list {
width: 100%;
position: relative; position: relative;
white-space: nowrap; white-space: nowrap;
transition: all 0.5s; transition: all 0.5s;
.item { .item {
display: inline-block; display: inline-block;
position: relative;
margin: 0 5px; margin: 0 5px;
width: 320px; width: 100% / 6;
height: 180px; border-radius: 2px;
background: url(./img/icon-video.png) no-repeat center center; border: 1px solid transparent;
background-size: 100% 100%; overflow: hidden;
cursor: pointer; cursor: pointer;
.box{
.img { position: relative;
display: block; padding-top: 9 / 16 *100%;
width: 100%; .img {
height: 100%; position: absolute;
background-color: #333333; top: 0;
} left: 0;
.mark { display: block;
position: absolute; width: 100%;
top: 10px; height: 100%;
left: 0; background-color: #333333;
min-width: 30%; }
max-width: 90%; .icon{
height: 30px; position: absolute;
line-height: 30px; top: 0;
background-color: #d5d5d5; left: 0;
color: #1f1f1f; width: 100%;
padding: 0 15px 0 5px; height: 100%;
font-size: 17px; background: #4A4A4A url(./img/icon-video.png) no-repeat center center;
white-space: nowrap; background-size: 20% auto;
overflow: hidden; }
text-overflow: ellipsis; .name {
border-top-right-radius: 30px; position: absolute;
border-bottom-right-radius: 30px; top: 5px;
left: 5px;
z-index: 100;
font-size: 20px;
color: #fff;
}
} }
&.z-active { &.z-active {
.mark { border-color: var(--main-color);
background-color: var(--main-color);
color: #ffffff;
}
} }
} }
} }
......
...@@ -13,28 +13,29 @@ ...@@ -13,28 +13,29 @@
</template> </template>
<script> <script>
import { mapGetters } from "vuex"; import { mapGetters } from 'vuex';
export default { export default {
name: 'pc-chat-img',
props: { props: {
info: {}, info: {}
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
channelInfo: "channelInfo", channelInfo: 'channelInfo'
}), }),
userHead() { userHead() {
let userHeadImg = this.info.userHeadImg; let userHeadImg = this.info.userHeadImg;
if (userHeadImg === "phoneHead") { if (userHeadImg === 'phoneHead') {
return this.channelInfo.defaultPhoneHeadAva; return this.channelInfo.defaultPhoneHeadAva;
} else if (userHeadImg === "default") { } else if (userHeadImg === 'default') {
return this.channelInfo.defaultUserAva; return this.channelInfo.defaultUserAva;
} else if (!userHeadImg) { } else if (!userHeadImg) {
return this.channelInfo.defaultUserAva; return this.channelInfo.defaultUserAva;
} else { } else {
return userHeadImg; return userHeadImg;
} }
}, }
}, }
}; };
</script> </script>
...@@ -64,7 +65,7 @@ export default { ...@@ -64,7 +65,7 @@ export default {
display: inline-block; display: inline-block;
max-width: 80%; max-width: 80%;
background: var(--chat-bg); background: var(--chat-bg);
border-radius: 5px; border-radius: 4px;
border: 1px solid var(--chat-border-color); border: 1px solid var(--chat-border-color);
img { img {
max-width: 100%; max-width: 100%;
......
<template>
<div class="get-red" @click="_showRed(4, info.redpacketId)">
<div class="tip">
<i class="icon"></i>
{{ info.userNick }}领到一个竞答红包
<em>{{ info.money }}</em>
元红包
</div>
</div>
</template>
<script>
import { mapMutations } from 'vuex';
export default {
name: 'pc-chat-red-business-tip',
props: {
info: {}
},
methods: {
...mapMutations({
set_showRedInfo: 'set_showRedInfo'
}),
_showRed(type, id) {
let obj = {
type: type,
id: id
};
this.set_showRedInfo(obj);
}
}
};
</script>
<style lang="less" scoped>
.get-red {
.tip {
line-height: 25px;
padding: 8px 10px;
border-radius: 8px;
font-size: 14px;
color: var(--chat-color);
background: var(--chat-bg);
.icon {
display: inline-block;
vertical-align: middle;
width: 22px;
height: 22px;
background-image: url('./img/icon-red.png');
background-repeat: no-repeat;
background-size: 20px auto;
background-position: center center;
}
em {
color: #d84e43;
}
}
}
</style>
<template>
<div class="get-red" @click="_showRed(5, info.redpacketId)">
<div class="tip">
<i class="icon"></i>
{{ info.userNick }}领取了
<em>{{ info.redFrom }}</em>
的一个商家红包
<em>{{ info.money }}</em>
</div>
</div>
</template>
<script>
import { mapMutations } from 'vuex';
export default {
name: 'pc-chat-red-business-tip',
props: {
info: {}
},
methods: {
...mapMutations({
set_showRedInfo: 'set_showRedInfo'
}),
_showRed(type, id) {
let obj = {
type: type,
id: id
};
this.set_showRedInfo(obj);
}
}
};
</script>
<style lang="less" scoped>
.get-red {
.tip {
line-height: 25px;
padding: 8px 10px;
border-radius: 8px;
font-size: 14px;
color: var(--chat-color);
background: var(--chat-bg);
.icon {
display: inline-block;
vertical-align: middle;
width: 22px;
height: 22px;
background-image: url('./img/icon-red.png');
background-repeat: no-repeat;
background-size: 20px auto;
background-position: center center;
}
em {
color: #d84e43;
}
}
}
</style>
...@@ -8,10 +8,7 @@ ...@@ -8,10 +8,7 @@
<div class="content" @click="_showRed(1, info.redpacketId)"> <div class="content" @click="_showRed(1, info.redpacketId)">
<div class="info"> <div class="info">
<i class="icon"></i> <i class="icon"></i>
<div class="text"> <div class="text">{{ info.filterContent }}</div>
<div>{{ info.filterContent }}</div>
<div>领取红包</div>
</div>
</div> </div>
<div class="peg">直播间普通红包</div> <div class="peg">直播间普通红包</div>
</div> </div>
...@@ -20,46 +17,41 @@ ...@@ -20,46 +17,41 @@
</template> </template>
<script> <script>
import { mapGetters, mapMutations } from "vuex"; import { mapGetters, mapMutations } from 'vuex';
export default { export default {
name: 'pc-chat-red-default',
props: { props: {
info: {}, info: {}
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
channelInfo: "channelInfo", channelInfo: 'channelInfo'
userInfo: "userInfo",
}), }),
userHead() { userHead() {
let userHeadImg = this.info.userHeadImg; let userHeadImg = this.info.userHeadImg;
if (userHeadImg === "phoneHead") { if (userHeadImg === 'phoneHead') {
return this.channelInfo.defaultPhoneHeadAva; return this.channelInfo.defaultPhoneHeadAva;
} else if (userHeadImg === "default") { } else if (userHeadImg === 'default') {
return this.channelInfo.defaultUserAva; return this.channelInfo.defaultUserAva;
} else if (!userHeadImg) { } else if (!userHeadImg) {
return this.channelInfo.defaultUserAva; return this.channelInfo.defaultUserAva;
} else { } else {
return userHeadImg; return userHeadImg;
} }
}, }
}, },
methods: { methods: {
...mapMutations({ ...mapMutations({
set_showRedInfo: "set_showRedInfo", set_showRedInfo: 'set_showRedInfo'
}), }),
_showRed(type, id) { _showRed(type, id) {
let obj = { let obj = {
type: type, type: type,
id: id, id: id
}; };
if (this.userInfo.id) { this.set_showRedInfo(obj);
this.set_showRedInfo(obj); }
} else { }
this.$layer.msg("登陆后才能领取红包哦!~");
this.$Bus.$emit("bus-showLogin", true);
}
},
},
}; };
</script> </script>
...@@ -87,45 +79,40 @@ export default { ...@@ -87,45 +79,40 @@ export default {
} }
.content { .content {
display: inline-block; display: inline-block;
padding: 0 16px;
min-width: 220px; min-width: 220px;
max-width: 100%; max-width: 100%;
line-height: 20px; line-height: 20px;
border-radius: 5px; border-radius: 5px;
font-size: 12px; font-size: 12px;
color: #404040; color: #fff;
background: #febe5c;
border-radius: 4px;
overflow: hidden; overflow: hidden;
.info { .info {
padding: 6px 0;
display: flex; display: flex;
padding: 10px; align-items: center;
background: #fa9d3b; border-bottom: 1px solid #ffb139;
border: 1px solid #e28f3b;
.icon { .icon {
vertical-align: top;
margin-right: 10px;
display: inline-block;
flex: 0 0 auto; flex: 0 0 auto;
width: 35px; margin-right: 10px;
height: 45px; width: 25px;
background-image: url("./img/icon-red.png"); height: 35px;
background-repeat: no-repeat; background: url('./img/icon-red.png') no-repeat center center;
background-size: 35px auto; background-size: 100% auto;
background-position: center center;
} }
.text { .text {
min-width: 100px; flex: 1;
line-height: 22px; line-height: 22px;
font-size: 14px; font-size: 14px;
color: #fff;
word-break: break-all; word-break: break-all;
} }
} }
.peg { .peg {
height: 20px; padding: 4px 0;
line-height: 20px; font-size: 10px;
padding: 0 5px; color: #fff;
background: #fff;
font-size: 14px;
color: #ccc;
} }
} }
} }
......
<template>
<div class="get-red" @click="_showRed(1, info.redpacketId)">
<div class="tip">
<i class="icon"></i>
{{ info.userNick }}领取了
<em>{{ info.redFrom }}</em>
<em>{{ info.money }}</em>
元红包
</div>
</div>
</template>
<script>
import { mapMutations } from 'vuex';
export default {
name: 'pc-chat-red-default-tip',
props: {
info: {}
},
methods: {
...mapMutations({
set_showRedInfo: 'set_showRedInfo'
}),
_showRed(type, id) {
let obj = {
type: type,
id: id
};
this.set_showRedInfo(obj);
}
}
};
</script>
<style lang="less" scoped>
.get-red {
.tip {
line-height: 25px;
padding: 8px 10px;
border-radius: 8px;
font-size: 14px;
color: var(--chat-color);
background: var(--chat-bg);
.icon {
display: inline-block;
vertical-align: middle;
width: 22px;
height: 22px;
background-image: url('./img/icon-red.png');
background-repeat: no-repeat;
background-size: 20px auto;
background-position: center center;
}
em {
color: #d84e43;
}
}
}
</style>
...@@ -8,10 +8,7 @@ ...@@ -8,10 +8,7 @@
<div class="content" @click="_showRed(3, info.redpacketId)"> <div class="content" @click="_showRed(3, info.redpacketId)">
<div class="info"> <div class="info">
<i class="icon"></i> <i class="icon"></i>
<div class="text"> <div class="text">{{ info.filterContent }}</div>
<div>{{ info.filterContent }}</div>
<div>领取红包</div>
</div>
</div> </div>
<div class="peg">直播间口令红包</div> <div class="peg">直播间口令红包</div>
</div> </div>
...@@ -20,46 +17,41 @@ ...@@ -20,46 +17,41 @@
</template> </template>
<script> <script>
import { mapGetters, mapMutations } from "vuex"; import { mapGetters, mapMutations } from 'vuex';
export default { export default {
name: 'pc-chat-red-password',
props: { props: {
info: {}, info: {}
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
channelInfo: "channelInfo", channelInfo: 'channelInfo'
userInfo: "userInfo",
}), }),
userHead() { userHead() {
let userHeadImg = this.info.userHeadImg; let userHeadImg = this.info.userHeadImg;
if (userHeadImg === "phoneHead") { if (userHeadImg === 'phoneHead') {
return this.channelInfo.defaultPhoneHeadAva; return this.channelInfo.defaultPhoneHeadAva;
} else if (userHeadImg === "default") { } else if (userHeadImg === 'default') {
return this.channelInfo.defaultUserAva; return this.channelInfo.defaultUserAva;
} else if (!userHeadImg) { } else if (!userHeadImg) {
return this.channelInfo.defaultUserAva; return this.channelInfo.defaultUserAva;
} else { } else {
return userHeadImg; return userHeadImg;
} }
}, }
}, },
methods: { methods: {
...mapMutations({ ...mapMutations({
set_showRedInfo: "set_showRedInfo", set_showRedInfo: 'set_showRedInfo'
}), }),
_showRed(type, id) { _showRed(type, id) {
let obj = { let obj = {
type: type, type: type,
id: id, id: id
}; };
if (this.userInfo.id) { this.set_showRedInfo(obj);
this.set_showRedInfo(obj); }
} else { }
this.$layer.msg("登陆后才能领取红包哦!~");
this.$Bus.$emit("bus-showLogin", true);
}
},
},
}; };
</script> </script>
...@@ -87,45 +79,40 @@ export default { ...@@ -87,45 +79,40 @@ export default {
} }
.content { .content {
display: inline-block; display: inline-block;
padding: 0 16px;
min-width: 220px; min-width: 220px;
max-width: 100%; max-width: 100%;
line-height: 20px; line-height: 20px;
border-radius: 5px; border-radius: 5px;
font-size: 12px; font-size: 12px;
color: #404040; color: #fff;
background: #febe5c;
border-radius: 4px;
overflow: hidden; overflow: hidden;
.info { .info {
padding: 6px 0;
display: flex; display: flex;
padding: 10px; align-items: center;
background: #fa9d3b; border-bottom: 1px solid #ffb139;
border: 1px solid #e28f3b;
.icon { .icon {
vertical-align: top;
margin-right: 10px;
display: inline-block;
flex: 0 0 auto; flex: 0 0 auto;
width: 35px; margin-right: 10px;
height: 45px; width: 25px;
background-image: url("./img/icon-red.png"); height: 35px;
background-repeat: no-repeat; background: url('./img/icon-red.png') no-repeat center center;
background-size: 35px auto; background-size: 100% auto;
background-position: center center;
} }
.text { .text {
min-width: 100px; flex: 1;
line-height: 22px; line-height: 22px;
font-size: 14px; font-size: 14px;
color: #fff;
word-break: break-all; word-break: break-all;
} }
} }
.peg { .peg {
height: 20px; padding: 4px 0;
line-height: 20px; font-size: 10px;
padding: 0 5px; color: #fff;
background: #fff;
font-size: 14px;
color: #ccc;
} }
} }
} }
......
<template>
<div class="get-red" @click="_showRed(3, info.redpacketId)">
<div class="tip">
<i class="icon"></i>
{{ info.userNick }}领到一个口令红包
<em>{{ info.money }}</em>
元红包
</div>
</div>
</template>
<script>
import { mapMutations } from 'vuex';
export default {
name: 'pc-chat-red-password-tip',
props: {
info: {}
},
methods: {
...mapMutations({
set_showRedInfo: 'set_showRedInfo'
}),
_showRed(type, id) {
let obj = {
type: type,
id: id
};
this.set_showRedInfo(obj);
}
}
};
</script>
<style lang="less" scoped>
.get-red {
.tip {
line-height: 25px;
padding: 8px 10px;
border-radius: 8px;
font-size: 14px;
color: var(--chat-color);
background: var(--chat-bg);
.icon {
display: inline-block;
vertical-align: middle;
width: 22px;
height: 22px;
background-image: url('./img/icon-red.png');
background-repeat: no-repeat;
background-size: 20px auto;
background-position: center center;
}
em {
color: #d84e43;
}
}
}
</style>
<template>
<div class="get-red" @click="_showRed(2, info.redpacketId)">
<div class="tip">
<i class="icon"></i>
{{ info.userNick }}通过分享获得了
<em>{{ info.money }}</em>
元红包
</div>
</div>
</template>
<script>
import { mapMutations } from 'vuex';
export default {
name: 'pc-chat-red-share-tip',
props: {
info: {}
},
methods: {
...mapMutations({
set_showRedInfo: 'set_showRedInfo'
}),
_showRed(type, id) {
let obj = {
type: type,
id: id
};
this.set_showRedInfo(obj);
}
}
};
</script>
<style lang="less" scoped>
.get-red {
.tip {
line-height: 25px;
padding: 8px 10px;
border-radius: 8px;
font-size: 14px;
color: var(--chat-color);
background: var(--chat-bg);
.icon {
display: inline-block;
vertical-align: middle;
width: 22px;
height: 22px;
background-image: url('./img/icon-red.png');
background-repeat: no-repeat;
background-size: 20px auto;
background-position: center center;
}
em {
color: #d84e43;
}
}
}
</style>
<template>
<div class="reward-info">
<div class="tip">
<em>{{ info.userNick }}</em>
打赏
<em>{{ info.money }}</em>
元红包
</div>
</div>
</template>
<script>
export default {
name: 'pc-chat-reward-cash',
props: {
info: {}
}
};
</script>
<style lang="less" scoped>
.reward-info {
.tip {
line-height: 25px;
padding: 8px 10px;
border-radius: 8px;
font-size: 14px;
color: var(--chat-color);
background: var(--chat-bg);
em {
color: #d84e43;
}
}
}
</style>
<template>
<div class="reward-info">
<div class="tip">
<i class="icon"></i>
<em>{{ info.userNick }}</em>
赠送
<img v-if="gift.img" :src="gift.img" />
<img v-else :src="`//static-pro.guangdianyun.tv/static/reward/gift-${gift.imgType}.png`" />
{{ gift.name }}
<em>* {{ gift.num }}</em>
</div>
</div>
</template>
<script>
export default {
name: 'pc-chat-reward-gift',
props: {
info: {}
},
computed: {
gift() {
return JSON.parse(this.info.filterContent || '{}');
}
}
};
</script>
<style lang="less" scoped>
.reward-info {
.tip {
line-height: 25px;
padding: 8px 10px;
border-radius: 8px;
font-size: 14px;
color: var(--chat-color);
background: var(--chat-bg);
.icon {
display: inline-block;
vertical-align: middle;vertical-align: middle;
width: 22px;
height: 22px;
background-image: url('./img/icon-gift.png');
background-repeat: no-repeat;
background-size: 20px auto;
background-position: center center;
}
em {
color: #d84e43;
}
img {
vertical-align: middle;
height: 30px;
}
}
}
</style>
...@@ -12,13 +12,13 @@ ...@@ -12,13 +12,13 @@
<div class="text"> <div class="text">
<template v-if="info.replyContent"> <template v-if="info.replyContent">
<div class="quote"> <div class="quote">
{{ info.replyNick }}<span {{ info.replyNick }}
v-html="$options.filters.emojiParse(info.replyContent)" <span v-html="$options.filters.emojiParse(info.replyContent)"></span>
></span
>
</div> </div>
<div class="reply"> <div class="reply">
回复:<span 回复:
<span
:style="{ color: info.contentColor }" :style="{ color: info.contentColor }"
v-html="$options.filters.emojiParse(info.filterContent)" v-html="$options.filters.emojiParse(info.filterContent)"
></span> ></span>
...@@ -35,38 +35,39 @@ ...@@ -35,38 +35,39 @@
</div> </div>
</template> </template>
<script> <script>
import { mapGetters } from "vuex"; import { mapGetters } from 'vuex';
export default { export default {
name: 'pc-chat-test',
props: { props: {
info: {}, info: {},
isTop: {}, isTop: {}
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
channelInfo: "channelInfo", channelInfo: 'channelInfo'
}), }),
userHead() { userHead() {
let userHeadImg = this.info.userHeadImg; let userHeadImg = this.info.userHeadImg;
if (userHeadImg === "phoneHead") { if (userHeadImg === 'phoneHead') {
return this.channelInfo.defaultPhoneHeadAva; return this.channelInfo.defaultPhoneHeadAva;
} else if (userHeadImg === "default") { } else if (userHeadImg === 'default') {
return this.channelInfo.defaultUserAva; return this.channelInfo.defaultUserAva;
} else if (!userHeadImg) { } else if (!userHeadImg) {
return this.channelInfo.defaultUserAva; return this.channelInfo.defaultUserAva;
} else { } else {
return userHeadImg; return userHeadImg;
} }
}, }
}, },
methods: { methods: {
_reply(id, name) { _reply(id, name) {
let obj = { let obj = {
id: id, id: id,
name: name, name: name
}; };
this.$Bus.$emit("bus-setReply", obj); this.$Bus.$emit('bus-setReply', obj);
}, }
}, }
}; };
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
...@@ -86,9 +87,9 @@ export default { ...@@ -86,9 +87,9 @@ export default {
flex: 1; flex: 1;
padding: 0px 10px; padding: 0px 10px;
.name { .name {
line-height: 20px; line-height: 25px;
color: #9b9b9b; color: #9b9b9b;
font-size: 12px; font-size: 14px;
.isTop { .isTop {
display: inline-block; display: inline-block;
padding: 0 6px; padding: 0 6px;
...@@ -98,20 +99,18 @@ export default { ...@@ -98,20 +99,18 @@ export default {
background: var(--main-color); background: var(--main-color);
color: #fff; color: #fff;
font-size: 12px; font-size: 12px;
transform: scale(0.5);
transform-origin: 0 auto;
} }
} }
.content { .content {
position: relative; position: relative;
padding: 5px 10px; padding: 6px 12px;
display: inline-block; display: inline-block;
min-height: 20px; min-height: 25px;
line-height: 20px; line-height: 25px;
background: var(--chat-bg); background: var(--chat-bg);
border-radius: 5px; border-radius: 4px;
border: 1px solid var(--chat-border-color); border: 1px solid var(--chat-border-color);
font-size: 14px; font-size: 15px;
color: var(--chat-color); color: var(--chat-color);
word-break: break-word; word-break: break-word;
.text { .text {
...@@ -120,8 +119,8 @@ export default { ...@@ -120,8 +119,8 @@ export default {
::v-deep { ::v-deep {
.emoji { .emoji {
display: inline-block; display: inline-block;
width: 30px; width: 24px;
height: 30px; height: 24px;
vertical-align: middle; vertical-align: middle;
} }
} }
...@@ -134,17 +133,6 @@ export default { ...@@ -134,17 +133,6 @@ export default {
padding: 5px 0; padding: 5px 0;
} }
} }
&::after {
content: "";
position: absolute;
bottom: -4px;
right: -4px;
display: block;
width: 20px;
height: 20px;
background: var(--chat-icon-br) no-repeat bottom right;
background-size: contain;
}
} }
} }
} }
......
<template>
<div class="chat-time">{{ (info.addTime * 1000) | formatDate }}</div>
</template>
<script>
export default {
name: 'pc-chat-time',
props: {
info: {}
}
};
</script>
<style lang="less" scoped>
.chat-time {
margin: 5px 0;
font-size: 12px;
color: #999;
text-align: center;
}
</style>
...@@ -52,32 +52,33 @@ ...@@ -52,32 +52,33 @@
</template> </template>
<script> <script>
import chatTime from "./chatTime"; import chatTime from './chatTime';
import chatText from "./chatText"; import chatText from './chatText';
import chatRewardCash from "./chatRewardCash"; import chatRewardCash from './chatRewardCash';
import chatRedDefault from "./chatRedDefault"; import chatRedDefault from './chatRedDefault';
import chatRedDefaultTip from "./chatRedDefaultTip"; import chatRedDefaultTip from './chatRedDefaultTip';
import chatImg from "./chatImg"; import chatImg from './chatImg';
import chatRedShareTip from "./chatRedShareTip"; import chatRedShareTip from './chatRedShareTip';
import chatRedPassword from "./chatRedPassword"; import chatRedPassword from './chatRedPassword';
import chatRedPasswordTip from "./chatRedPasswordTip"; import chatRedPasswordTip from './chatRedPasswordTip';
import chatRedAnswerTip from "./chatRedAnswerTip"; import chatRedAnswerTip from './chatRedAnswerTip';
import chatRedBusinessTip from "./chatRedBusinessTip"; import chatRedBusinessTip from './chatRedBusinessTip';
import chatRewardGift from "./chatRewardGift"; import chatRewardGift from './chatRewardGift';
export default { export default {
name: 'pc-chat-item',
props: { props: {
info: { info: {
type: Object, type: Object,
default() { default() {
return {}; return {};
}, }
}, },
isTop: { isTop: {
type: Boolean, type: Boolean,
default() { default() {
return false; return false;
}, }
}, }
}, },
components: { components: {
chatTime, chatTime,
...@@ -91,7 +92,7 @@ export default { ...@@ -91,7 +92,7 @@ export default {
chatRedPasswordTip, chatRedPasswordTip,
chatRedAnswerTip, chatRedAnswerTip,
chatRedBusinessTip, chatRedBusinessTip,
chatRewardGift, chatRewardGift
}, }
}; };
</script> </script>
<template>
<div class="chat-list">
<div class="list-box" ref="chatListBox" @scroll="getMore">
<div class="loading" v-show="!isAjax">{{ loadingMsg }}</div>
<div id="chatList" class="list" ref="chatList">
<div class="item" v-for="item in list" :key="item.id" :data-chatid="item.id">
<chat-item :info="item"></chat-item>
</div>
</div>
</div>
<div class="chat-unread" v-show="unreadChatNum">
<span @click="_scrollBottom">{{ unreadChatNum }}条消息未读</span>
</div>
</div>
</template>
<script>
import { getChatList } from '@/plugins/API/apiAll';
import { mapGetters } from 'vuex';
import chatItem from './chatItem/index';
export default {
name: 'pc-chat-list',
components: {
chatItem
},
data() {
return {
isAjax: true,
loadingMsg: '',
page: 1,
num: 50,
list: [],
unreadChatNum: 0
};
},
computed: {
...mapGetters({
userInfo: 'userInfo',
channelInfo: 'channelInfo'
})
},
mounted() {
this.$Bus.$on('bus-addChat', this.addChat);
this.$Bus.$on('bus-delChat', this.delChat);
this.getChatList();
},
methods: {
getMore() {
let chatListBoxDom = this.$refs.chatListBox;
let chatListDom = this.$refs.chatList;
if (chatListBoxDom && chatListDom) {
let boxHeight = chatListBoxDom.clientHeight;
let boxScrollTop = chatListBoxDom.scrollTop;
let listHeigth = chatListDom.clientHeight;
if (boxScrollTop <= 100) {
this.getChatList();
}
if (listHeigth - boxHeight - boxScrollTop < 250) {
this.unreadChatNum = 0;
}
}
},
async getChatList() {
if (!this.isAjax) {
return false;
}
this.isAjax = false;
this.loadingMsg = '加载中...';
const res = await getChatList({
uin: this.channelInfo.uin,
channelId: this.channelInfo.id,
page: this.page,
num: this.num
});
if (res.code === 200 && res.errorCode === 0) {
let list = res.data || [];
let firstLi =
document.querySelector('#chatList') && document.querySelector('#chatList').children[0];
list.forEach(item => {
this.addChat(item, true);
});
this.$nextTick(() => {
if (this.page === 1) {
this._scrollBottom();
} else {
let chatListBoxDom = this.$refs.chatListBox;
if (chatListBoxDom && firstLi) {
chatListBoxDom.scrollTop = firstLi.offsetTop;
}
}
if (list.length < 50) {
this.isAjax = false;
this.loadingMsg = '已加载所有评论';
} else {
this.page++;
this.isAjax = true;
this.loadingMsg = '';
}
});
} else {
this.isAjax = true;
this.loadingMsg = '';
}
},
addChat(obj, order = false) {
let chatObj = obj;
this.list = this.list.filter(x => {
return Number(x.id) !== Number(chatObj.id);
});
if (this.list.length) {
let newTime = chatObj.addTime;
let prevTime = order ? this.list[0].addTime : this.list[this.list.length - 1].addTime;
if (Math.abs(newTime - prevTime) > 600) {
chatObj.showTime = true;
}
}
if (order) {
this.list.unshift(chatObj);
} else {
this.list.push(chatObj);
this._scrollKeep();
}
if (this.list.length > 250) {
this.list.splice(50, 100);
}
},
delChat(id) {
this.list = this.list.filter(x => {
return Number(x.id) !== Number(id);
});
},
_scrollKeep() {
let chatListBoxDom = this.$refs.chatListBox;
let chatListDom = this.$refs.chatList;
if (chatListBoxDom && chatListDom) {
let boxHeight = chatListBoxDom.clientHeight;
let boxScrollTop = chatListBoxDom.scrollTop;
let listHeigth = chatListDom.clientHeight;
if (boxHeight + boxScrollTop > listHeigth - 250) {
this.$nextTick(() => {
chatListBoxDom.scrollTop = this.$refs.chatList.clientHeight;
});
} else {
this.unreadChatNum++;
}
}
},
_scrollBottom() {
let chatListBoxDom = this.$refs.chatListBox;
let chatListDom = this.$refs.chatList;
if (chatListBoxDom && chatListDom) {
let listHeigth = chatListDom.clientHeight;
chatListBoxDom.scrollTop = listHeigth;
}
}
},
beforeDestroy() {
this.$Bus.$off('bus-addChat', this.addChat);
this.$Bus.$off('bus-delChat', this.delChat);
}
};
</script>
<style lang="less" scoped>
.chat-list {
position: relative;
height: 100%;
}
.list-box {
height: 100%;
width: 100%;
overflow-y: auto;
&::-webkit-scrollbar {
background: #2f3035;
width: 5px;
}
&::-webkit-scrollbar-track-piece {
background-color: #2f3035;
margin: -2px;
}
&::-webkit-scrollbar-thumb {
background: #383940;
min-height: 150px;
min-width: 150px;
border-radius: 10px;
}
.loading {
height: 30px;
line-height: 30px;
text-align: center;
color: #858587;
font-size: 14px;
}
.list {
position: relative;
.item {
padding: 5px 10px;
}
}
}
.chat-unread {
position: absolute;
bottom: 10px;
left: 0;
z-index: 1;
width: 100%;
text-align: center;
span {
padding: 10px 15px;
background-color: var(--main-color);
border-radius: 30px;
font-size: 16px;
color: #fff;
}
}
</style>
...@@ -7,29 +7,30 @@ ...@@ -7,29 +7,30 @@
</template> </template>
<script> <script>
import { getTopChatList } from "@/plugins/API/apiAll"; import { getTopChatList } from '@/plugins/API/apiAll';
import { mapGetters } from "vuex"; import { mapGetters } from 'vuex';
import chatItem from "./chatItem/index"; import chatItem from './chatItem/index';
export default { export default {
name: 'pc-top-chat-list',
components: { components: {
chatItem, chatItem
}, },
data() { data() {
return { return {
page: 1, page: 1,
num: 50, num: 50,
list: [], list: []
}; };
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
userInfo: "userInfo", userInfo: 'userInfo',
channelInfo: "channelInfo", channelInfo: 'channelInfo'
}), })
}, },
mounted() { mounted() {
this.$Bus.$on("bus-addTopChat", this.addChat); this.$Bus.$on('bus-addTopChat', this.addChat);
this.$Bus.$on("bus-delTopChat", this.delChat); this.$Bus.$on('bus-delTopChat', this.delChat);
this.getChatList(); this.getChatList();
}, },
methods: { methods: {
...@@ -38,7 +39,7 @@ export default { ...@@ -38,7 +39,7 @@ export default {
uin: this.channelInfo.uin, uin: this.channelInfo.uin,
channelId: this.channelInfo.id, channelId: this.channelInfo.id,
page: this.page, page: this.page,
num: this.num, num: this.num
}); });
if (res.code === 200 && res.errorCode === 0) { if (res.code === 200 && res.errorCode === 0) {
this.list = res.data || []; this.list = res.data || [];
...@@ -48,15 +49,15 @@ export default { ...@@ -48,15 +49,15 @@ export default {
this.list.unshift(obj); this.list.unshift(obj);
}, },
delChat(id) { delChat(id) {
this.list = this.list.filter((x) => { this.list = this.list.filter(x => {
return Number(x.id) !== Number(id); return Number(x.id) !== Number(id);
}); });
}, }
}, },
beforeDestroy() { beforeDestroy() {
this.$Bus.$off("bus-addTopChat", this.addChat); this.$Bus.$off('bus-addTopChat', this.addChat);
this.$Bus.$off("bus-delTopChat", this.delChat); this.$Bus.$off('bus-delTopChat', this.delChat);
}, }
}; };
</script> </script>
......
<template> <template>
<div class="chat"> <div class="chat-box">
<div class="top-chat-list"> <div class="top-chat-list">
<top-chat-box></top-chat-box> <top-chat-list></top-chat-list>
</div> </div>
<div class="chat-box"> <div class="chat-list">
<chat-box></chat-box> <chat-list></chat-list>
</div>
<div class="chat-send">
<send-box></send-box>
</div> </div>
<send-box v-show="isShowChat" v-transfer-dom></send-box>
<suspension-box v-show="isShowChat" v-transfer-dom></suspension-box>
</div> </div>
</template> </template>
<script> <script>
import { mapGetters } from "vuex"; import { mapGetters } from 'vuex';
import topChatBox from "./chat/topChat"; import topChatList from './chatList/topChatList';
import chatBox from "./chat/chat"; import chatList from './chatList/chatList';
import sendBox from "@/components/modules/sendBox/index"; import sendBox from '../sendBox';
import suspensionBox from "@/components/modules/suspension/index";
export default { export default {
name: 'pc-chat-box',
components: { components: {
topChatBox, topChatList,
chatBox, chatList,
sendBox, sendBox
suspensionBox,
},
props: {
isShowChat: {},
}, },
data() { data() {
return {}; return {};
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
userInfo: "userInfo", userInfo: 'userInfo',
channelInfo: "channelInfo", channelInfo: 'channelInfo'
}), })
}, }
methods: {},
}; };
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.chat { .chat-box {
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
padding-top: 5px;
padding-bottom: 50px;
.top-chat-list { .top-chat-list {
flex: 0 0 auto; flex: 0 0 auto;
} }
.chat-box { .chat-list {
flex: 1; flex: 1;
height: 100%; height: 100%;
width: 100%; width: 100%;
overflow-y: auto; overflow-y: auto;
} }
.chat-send {
flex: 0 0 auto;
padding: 10px;
height: 140px;
}
} }
</style> </style>
<template> <template>
<div <div class="follow-box">
class="follow-mask"
v-show="wechatInfo.isShow"
v-if="wechatInfo.status"
@click="_hide"
>
<div class="follow" @click.stop> <div class="follow" @click.stop>
<div class="top"> <div class="top">
<span>{{ wechatInfo.WeChatName }}</span> <span>{{ wechatInfo.WeChatName }}</span>
...@@ -19,43 +14,31 @@ ...@@ -19,43 +14,31 @@
</template> </template>
<script> <script>
import { getWechatInfo } from "@/plugins/API/apiAll";
import { mapGetters, mapMutations } from "vuex";
export default { export default {
computed: { name: 'pc-follow-box',
...mapGetters({ props: {
channelInfo: "channelInfo", value: {}
wechatInfo: "wechatInfo",
}),
}, },
mounted() { computed: {
this._getWechatInfo(); wechatInfo: {
get() {
return this.value;
},
set(nVal) {
this.$emit('input', nVal);
}
}
}, },
methods: { methods: {
...mapMutations({
set_wechatInfo: "set_wechatInfo",
}),
// 获取多机位
async _getWechatInfo() {
const res = await getWechatInfo({
id: this.channelInfo.id,
});
if (res.code === 200 && res.errorCode === 0) {
this.set_wechatInfo(res.data);
}
},
_hide() { _hide() {
let info = JSON.parse(JSON.stringify(this.wechatInfo)); this.wechatInfo.isShow = false;
info.isShow = false; }
this.set_wechatInfo(info); }
},
},
}; };
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.follow-mask { .follow-box {
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
...@@ -63,7 +46,6 @@ export default { ...@@ -63,7 +46,6 @@ export default {
bottom: 0; bottom: 0;
z-index: 1000; z-index: 1000;
background: rgba(0, 0, 0, 0.3); background: rgba(0, 0, 0, 0.3);
.follow { .follow {
position: absolute; position: absolute;
top: 50%; top: 50%;
...@@ -73,7 +55,6 @@ export default { ...@@ -73,7 +55,6 @@ export default {
transform: translateX(-50%) translateY(-50%); transform: translateX(-50%) translateY(-50%);
background-color: #fff; background-color: #fff;
border-radius: 5px; border-radius: 5px;
.top { .top {
line-height: 20px; line-height: 20px;
padding: 0 30px 15px; padding: 0 30px 15px;
...@@ -85,7 +66,6 @@ export default { ...@@ -85,7 +66,6 @@ export default {
text-overflow: ellipsis; text-overflow: ellipsis;
color: #404040; color: #404040;
overflow: hidden; overflow: hidden;
span { span {
color: var(--main-color); color: var(--main-color);
} }
...@@ -95,7 +75,6 @@ export default { ...@@ -95,7 +75,6 @@ export default {
margin: 10px auto; margin: 10px auto;
padding-top: 100%; padding-top: 100%;
height: 0; height: 0;
.img { .img {
display: block; display: block;
position: absolute; position: absolute;
...@@ -118,19 +97,18 @@ export default { ...@@ -118,19 +97,18 @@ export default {
z-index: 100; z-index: 100;
width: 30px; width: 30px;
height: 30px; height: 30px;
background-image: url("./img/icon-close.png"); background-image: url('./img/icon-close.png');
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center center; background-position: center center;
background-size: 100% 100%; background-size: 100% 100%;
cursor: pointer; cursor: pointer;
&:before { &:before {
position: absolute; position: absolute;
top: 30px; top: 30px;
left: 14px; left: 14px;
display: block; display: block;
width: 0; width: 0;
content: ""; content: '';
border: 1px solid #fff; border: 1px solid #fff;
height: 30px; height: 30px;
} }
......
<template>
<div class="header-box">
<div class="header-left-box">
<div class="name">
<div class="icon"></div>
<span class="title">{{ channelInfo.channelName }}</span>
</div>
</div>
<div class="header-right-box">
<div class="user" v-if="userInfo.id" @click="_goMyCenter">
<span class="name">{{ userInfo.userNick }}</span>
<img class="head" :src="userInfo.userHeadImg" alt />
</div>
<div class="login" v-else @click="_goMyCenter">登录</div>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
export default {
name: 'pc-header-box',
computed: {
...mapGetters({
corpId: 'corpId',
channelInfo: 'channelInfo',
userInfo: 'userInfo',
jumpUrls: 'jumpUrls'
})
},
methods: {
_goMyCenter() {
if (!this.userInfo.id) {
this.$Bus.$emit('bus-showLogin', true);
} else if (this.corpId === 1421) {
return false;
} else {
window.location.href = this.jumpUrls.center;
}
}
}
};
</script>
<style lang="less" scoped>
.header-box {
height: 100%;
display: flex;
align-items: center;
.header-left-box {
flex: 1;
.name {
.icon {
vertical-align: middle;
margin-right: 12px;
display: inline-block;
width: 24px;
height: 24px;
background: url(./img/icon-zb.png) no-repeat center center;
background-size: 100% 100%;
}
.title {
vertical-align: middle;
font-size: 22px;
}
}
}
.header-right-box {
flex: 0 0 auto;
.user {
cursor: pointer;
.name {
vertical-align: middle;
margin-right: 5px;
font-size: 18px;
}
.head {
vertical-align: middle;
width: 40px;
height: 40px;
border-radius: 4px;
}
}
.login {
width: 104px;
height: 36px;
line-height: 36px;
background: var(--main-color);
text-align: center;
border-radius: 36px;
font-size: 18px;
cursor: pointer;
}
}
}
</style>
<template>
<div class="info-box">
<div class="info-left-box">
<div class="status" v-if="liveNowStatus" v-html="liveNowStatus"></div>
<div class="watch" v-if="channelInfo.isDisplayWatchNum === 1">
<div class="icon"></div>
<span class="title">{{ allWatchNum | formatNum }}观看</span>
</div>
</div>
<div class="info-right-box">
<div class="follow" v-if="wechatInfo.status" @click="_showFollow">关注</div>
<div v-if="wechatInfo.status" v-transfer-dom>
<transition name="fade">
<follow-box v-show="wechatInfo.isShow" v-model="wechatInfo"></follow-box>
</transition>
</div>
</div>
</div>
</template>
<script>
import { getWatchNum, getWechatInfo } from '@/plugins/API/apiAll';
import { mapGetters } from 'vuex';
const followBox = resolve => require(['@/components/modules-pc/followBox'], resolve);
export default {
name: 'pc-info-box',
components: {
followBox
},
data() {
return {
watchNum: {
custom: 0,
real: 0
},
wechatInfo: {}
};
},
computed: {
...mapGetters({
channelInfo: 'channelInfo'
}),
allWatchNum() {
return this.watchNum.custom + this.watchNum.real;
},
liveNowStatus() {
let status = this.channelInfo.liveNowStatus;
if (status === 1) {
return '<span class="type green"><span class="icon"></span><span class="title">直播中</span></span>';
}
if (status === -1) {
return '<span class="type red"><span class="icon"></span><span class="title">直播已结束</span></span>';
}
if (status === 0) {
return '<span class="type"><span class="icon"></span><span class="title">未直播</span></span>';
}
if (status === 4) {
return '<span class="type"><span class="icon"></span><span class="title">直播未开始</span></span>';
}
return false;
}
},
mounted() {
this.getWatchNum();
this.getWechatInfo();
this.$Bus.$on('bus-realWatchNum', this.changeWatchNum);
this.$Bus.$on('bus-customWatchNum', this.changeWatchNumCustom);
},
methods: {
async getWatchNum() {
const res = await getWatchNum({
id: this.channelInfo.id,
uin: this.channelInfo.uin
});
if (res.code === 200 && res.errorCode === 0) {
let { customWatchNum, watchNum } = res.data;
this.watchNum = {
custom: Number(customWatchNum) || 0,
real: Number(watchNum) || 0
};
}
},
changeWatchNum(num) {
if (num) {
this.watchNum.real = Number(num) || 0;
}
},
changeWatchNumCustom(num) {
if (num) {
this.watchNum.custom += Number(num) || 0;
}
},
async getWechatInfo() {
const res = await getWechatInfo({
id: this.channelInfo.id
});
if (res.code === 200 && res.errorCode === 0) {
this.wechatInfo = res.data || {};
}
},
_showFollow() {
this.wechatInfo.isShow = true;
}
},
beforeDestroy() {
this.$Bus.$off('bus-customWatchNum', this.changeWatchNumCustom);
this.$Bus.$off('bus-realWatchNum', this.changeWatchNum);
}
};
</script>
<style lang="less" scoped>
.info-box {
height: 100%;
display: flex;
align-items: center;
.info-left-box {
flex: 1;
.status {
display: inline-block;
margin-right: 20px;
::v-deep .type {
display: inline-block;
color: #999;
font-size: 18px;
.icon {
margin-right: 8px;
vertical-align: middle;
display: inline-block;
width: 8px;
height: 8px;
border-radius: 100%;
background: #999;
}
.title {
vertical-align: middle;
}
&.green {
color: #29ce42;
.icon {
background: #29ce42;
}
}
&.red {
color: #ff3b3b;
.icon {
background: #ff3b3b;
}
}
}
}
.watch {
vertical-align: middle;
display: inline-block;
.icon {
vertical-align: middle;
margin-right: 4px;
display: inline-block;
width: 20px;
height: 20px;
background: url(./img/icon-user.png) no-repeat center center;
background-size: 100% 100%;
}
.title {
vertical-align: middle;
font-size: 18px;
}
}
}
.info-right-box {
flex: 0 0 auto;
.follow {
width: 80px;
height: 36px;
line-height: 36px;
background: var(--main-color);
text-align: center;
font-size: 18px;
border-radius: 2px;
cursor: pointer;
}
}
}
</style>
<template>
<div class="interact-box" v-if="chatMenu.length">
<div class="interact-tab">
{{ chatMenu[0].menuName }}
</div>
<div class="interact-list">
<chat-box></chat-box>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
const chatBox = resolve => require(['@/components/modules-pc/chatBox'], resolve);
export default {
name: 'pc-interact-box',
components: {
chatBox
},
computed: {
...mapGetters({
channelInfo: 'channelInfo',
menuList: 'menuList'
}),
chatMenu() {
return this.menuList.filter(obj => {
return obj.menuType === 'chat';
});
}
},
methods: {}
};
</script>
<style lang="less" scoped>
.interact-box {
display: flex;
flex-direction: column;
height: 100%;
.interact-tab {
flex: 0 0 auto;
position: relative;
height: 64px;
line-height: 64px;
font-size: 18px;
border-bottom: 2px solid #27282e;
text-align: center;
&:after {
content: '';
display: block;
position: absolute;
left: calc(50% - 20px);
bottom: 0;
width: 40px;
height: 4px;
background: var(--main-color);
border-radius: 4px;
}
}
.interact-list {
flex: 1;
height: 0;
}
}
</style>
<template>
<div class="list-box">
<ul class="list">
<li
class="item"
:class="{ 'z-active': value == index }"
v-for="(item, index) in menuListPc"
:key="index"
>
<template v-if="item.menuType == 'imagetext'">
<image-text :menuInfo="item.menuInfo"></image-text>
</template>
<template v-else-if="item.menuType == 'playlists'">
<play-lists :listId="item.menuInfo"></play-lists>
</template>
<template v-else-if="item.menuType == 'report'">
<report-box :id="item.menuInfo"></report-box>
</template>
<template v-else-if="item.menuType == 'iframeLine'">
<iframe-line :menuInfo="item.menuInfo"></iframe-line>
</template>
<template v-else>
<empty404></empty404>
</template>
</li>
</ul>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import imageText from './menuClass/imageText';
import playLists from './menuClass/playLists';
import reportBox from './menuClass/report';
import iframeLine from './menuClass/iframeLine';
import empty404 from './menuClass/404';
export default {
name: 'pv-menu-list',
components: {
imageText,
playLists,
reportBox,
iframeLine,
empty404
},
props: {
value: {}
},
computed: {
...mapGetters({
menuListPc: 'menuListPc'
})
}
};
</script>
<style lang="less" scoped>
.list-box {
.list {
.item {
height: 800px;
display: none;
&.z-active {
display: block;
}
}
}
::v-deep ::-webkit-scrollbar {
background: #2f3035;
width: 5px;
}
::v-deep ::-webkit-scrollbar-track-piece {
background-color: #2f3035;
margin: -2px;
}
::v-deep ::-webkit-scrollbar-thumb {
background: #383940;
min-height: 150px;
min-width: 150px;
border-radius: 10px;
}
}
</style>
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
<script> <script>
export default { export default {
name: 'pc-menu-404',
computed: {}, computed: {},
methods: {} methods: {}
}; };
......
<template> <template>
<div class="iframe-line"> <div class="iframe-line">
<client-only> <client-only>
<iframe <iframe :src="menuInfo" frameborder="0" width="100%" height="100%" scrolling="auto"></iframe>
:src="menuInfo"
frameborder="0"
width="100%"
height="100%"
scrolling="auto"
></iframe>
</client-only> </client-only>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
name: 'pc-menu-iframeLine',
props: { props: {
menuInfo: {} menuInfo: {}
} }
......
...@@ -5,10 +5,11 @@ ...@@ -5,10 +5,11 @@
</template> </template>
<script> <script>
import "quill/dist/quill.core.css"; import 'quill/dist/quill.core.css';
import "quill/dist/quill.snow.css"; import 'quill/dist/quill.snow.css';
import "quill/dist/quill.bubble.css"; import 'quill/dist/quill.bubble.css';
export default { export default {
name: 'pc-menu-imageText',
props: { props: {
menuInfo: {} menuInfo: {}
} }
......
<template>
<div class="play-list">
<div class="list-box">
<div class="list">
<div class="item" v-for="item in list" :key="item.id">
<div class="box" @click="_play(item.materialUrl)">
<div class="img-box">
<div class="img">
<img :src="item.coverUrl" alt="" />
<div class="state" v-if="item.materialUrl == playerInfo.playUrl">
播放中
</div>
</div>
</div>
<div class="title">{{ item.name }}</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { getPlaylistList } from '@/plugins/API/apiAll';
import { mapGetters, mapMutations } from 'vuex';
export default {
name: 'pc-menu-playLists',
props: {
listId: {}
},
data() {
return {
list: []
};
},
computed: {
...mapGetters({
channelInfo: 'channelInfo',
playerInfo: 'playerInfo'
})
},
mounted() {
if (this.listId) {
this._getPlaylistList();
}
},
methods: {
...mapMutations({
set_playerInfo: 'set_playerInfo'
}),
async _getPlaylistList() {
const res = await getPlaylistList({
uin: this.channelInfo.uin,
listId: Number(this.listId)
});
if (res.code === 200 && res.errorCode === 0) {
this.list = res.data.detail;
}
},
_play(url) {
let info = JSON.parse(JSON.stringify(this.playerInfo));
info.playUrl = url;
info.cameraId = '';
this.set_playerInfo(info);
}
}
};
</script>
<style lang="less" scoped>
.play-list {
position: relative;
padding: 6px;
height: 100%;
.list-box {
height: 100%;
overflow: auto;
}
}
.list {
display: flex;
flex-wrap: wrap;
.item {
flex: 0 0 auto;
padding: 8px;
width: 100% / 6;
.box {
display: flex;
flex-direction: column;
.img-box {
flex: 1;
.img {
position: relative;
padding-top: 100% * 9 /16;
img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
.state {
position: absolute;
top: 0;
left: 0;
padding: 0 14px;
height: 20px;
line-height: 20px;
font-size: 12px;
color: #fff;
&:before {
content: '';
display: block;
position: absolute;
top: 8px;
left: 5px;
width: 4px;
height: 4px;
border-radius: 100%;
background: var(--main-color);
}
}
}
}
.title {
flex: 1;
max-height: 40px;
line-height: 20px;
overflow: hidden;
font-size: 14px;
color: #fff;
text-align: justify;
word-break: break-all;
}
}
}
}
</style>
...@@ -5,8 +5,9 @@ ...@@ -5,8 +5,9 @@
</template> </template>
<script> <script>
import reportList from "./report/index"; import reportList from './report/index';
export default { export default {
name: 'pc-menu-report-box',
components: { components: {
reportList reportList
}, },
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<div class="top"> <div class="top">
<div class="sort"> <div class="sort">
<div class="btn" @click="_sort"> <div class="btn" @click="_sort">
{{ sort ? "倒序浏览" : "正序浏览" }} {{ sort ? '倒序浏览' : '正序浏览' }}
</div> </div>
</div> </div>
<div class="count">{{ count }}条报道</div> <div class="count">{{ count }}条报道</div>
...@@ -36,16 +36,17 @@ ...@@ -36,16 +36,17 @@
</div> </div>
</template> </template>
<script> <script>
import { getReportListFront, getReportInfo } from "@/plugins/API/apiReport"; import { getReportListFront, getReportInfo } from '@/plugins/API/apiReport';
import reportText from "./reportType/reportText"; import reportText from './reportType/reportText';
import reportImg from "./reportType/reportImg"; import reportImg from './reportType/reportImg';
import reportVideo from "./reportType/reportVideo"; import reportVideo from './reportType/reportVideo';
export default { export default {
name: 'pc-menu-report',
components: { components: {
"report-text": reportText, reportText,
"report-img": reportImg, reportImg,
"report-video": reportVideo reportVideo
}, },
props: { props: {
id: {} id: {}
...@@ -75,7 +76,7 @@ export default { ...@@ -75,7 +76,7 @@ export default {
} }
}, },
mounted() { mounted() {
this.$Bus.$on("bus-reportAdd", this.addList); this.$Bus.$on('bus-reportAdd', this.addList);
this.getList(); this.getList();
}, },
methods: { methods: {
...@@ -166,27 +167,24 @@ export default { ...@@ -166,27 +167,24 @@ export default {
} }
}, },
beforeDestroy() { beforeDestroy() {
this.$Bus.$off("bus-reportAdd", this.addList); this.$Bus.$off('bus-reportAdd', this.addList);
} }
}; };
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.report-container { .report-container {
height: 100%; height: 100%;
background-color: #f0f1f3;
overflow: auto; overflow: auto;
} }
.top { .top {
display: flex; display: flex;
padding: 5px 10px 0 10px; padding: 5px 10px 0 10px;
line-height: 30px; line-height: 30px;
.sort { .sort {
flex: 0 0 auto; flex: 0 0 auto;
margin-right: 10px; margin-right: 10px;
font-size: 10px; font-size: 10px;
color: #808080; color: #808080;
.btn { .btn {
display: inline-block; display: inline-block;
height: 20px; height: 20px;
...@@ -210,9 +208,8 @@ export default { ...@@ -210,9 +208,8 @@ export default {
position: relative; position: relative;
padding: 0 4px 0 12px; padding: 0 4px 0 12px;
max-width: 640px; max-width: 640px;
&:before { &:before {
content: ""; content: '';
display: block; display: block;
position: absolute; position: absolute;
left: 16px; left: 16px;
...@@ -225,13 +222,11 @@ export default { ...@@ -225,13 +222,11 @@ export default {
.item { .item {
position: relative; position: relative;
margin-bottom: 10px; margin-bottom: 10px;
.top { .top {
display: flex; display: flex;
position: relative; position: relative;
padding: 0 10px; padding: 0 10px;
line-height: 25px; line-height: 25px;
.dot { .dot {
flex: 0 0 auto; flex: 0 0 auto;
position: absolute; position: absolute;
...@@ -251,17 +246,14 @@ export default { ...@@ -251,17 +246,14 @@ export default {
} }
.content { .content {
padding: 0 16px; padding: 0 16px;
.content-box { .content-box {
background-color: #fff; background-color: #383940;
padding: 10px; padding: 10px;
border-radius: 4px; border-radius: 4px;
.info { .info {
display: flex; display: flex;
line-height: 25px; line-height: 25px;
padding-bottom: 2px; padding-bottom: 2px;
.head { .head {
flex: 0 0 auto; flex: 0 0 auto;
display: block; display: block;
...@@ -273,10 +265,6 @@ export default { ...@@ -273,10 +265,6 @@ export default {
.text { .text {
vertical-align: top; vertical-align: top;
flex: 1; flex: 1;
font-size: 12px;
color: #333;
word-break: break-all;
text-align: justify;
} }
} }
} }
......
...@@ -3,30 +3,21 @@ ...@@ -3,30 +3,21 @@
<div class="imgs img-type-1" v-if="imgs.length == 1"> <div class="imgs img-type-1" v-if="imgs.length == 1">
<div class="item" v-for="(item, index) in imgs" :key="index"> <div class="item" v-for="(item, index) in imgs" :key="index">
<div class="box"> <div class="box">
<img <img v-lazy="`${item.resize}`" v-photoswipe="{ group: 'report', origin: item.origin }" />
v-lazy="`${item.resize}`"
v-photoswipe="{ group: 'report', origin: item.origin }"
/>
</div> </div>
</div> </div>
</div> </div>
<div class="imgs img-type-2" v-else-if="imgs.length == 2"> <div class="imgs img-type-2" v-else-if="imgs.length == 2">
<div class="item" v-for="(item, index) in imgs" :key="index"> <div class="item" v-for="(item, index) in imgs" :key="index">
<div class="box"> <div class="box">
<img <img v-lazy="`${item.resize}`" v-photoswipe="{ group: 'report', origin: item.origin }" />
v-lazy="`${item.resize}`"
v-photoswipe="{ group: 'report', origin: item.origin }"
/>
</div> </div>
</div> </div>
</div> </div>
<div class="imgs img-type-3" v-else> <div class="imgs img-type-3" v-else>
<div class="item" v-for="(item, index) in imgs" :key="index"> <div class="item" v-for="(item, index) in imgs" :key="index">
<div class="box"> <div class="box">
<img <img v-lazy="`${item.resize}`" v-photoswipe="{ group: 'report', origin: item.origin }" />
v-lazy="`${item.resize}`"
v-photoswipe="{ group: 'report', origin: item.origin }"
/>
</div> </div>
</div> </div>
</div> </div>
...@@ -35,6 +26,7 @@ ...@@ -35,6 +26,7 @@
<script> <script>
export default { export default {
name: 'pc-menu-report-img',
props: { props: {
imgs: {} imgs: {}
}, },
...@@ -44,7 +36,6 @@ export default { ...@@ -44,7 +36,6 @@ export default {
<style scoped lang="less"> <style scoped lang="less">
.imgs { .imgs {
font-size: 0; font-size: 0;
&.img-type-1 { &.img-type-1 {
width: 100%; width: 100%;
.item { .item {
...@@ -60,12 +51,10 @@ export default { ...@@ -60,12 +51,10 @@ export default {
.item { .item {
width: 50%; width: 50%;
padding: 5px; padding: 5px;
.box { .box {
position: relative; position: relative;
padding-top: 100%; padding-top: 100%;
height: 0; height: 0;
img { img {
position: absolute; position: absolute;
top: 0; top: 0;
...@@ -79,16 +68,13 @@ export default { ...@@ -79,16 +68,13 @@ export default {
} }
&.img-type-3 { &.img-type-3 {
width: 100%; width: 100%;
.item { .item {
width: 33.333%; width: 33.333%;
padding: 5px; padding: 5px;
.box { .box {
position: relative; position: relative;
padding-top: 100%; padding-top: 100%;
height: 0; height: 0;
img { img {
position: absolute; position: absolute;
top: 0; top: 0;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
<script> <script>
export default { export default {
name: 'pc-menu-report-text',
props: { props: {
content: {} content: {}
} }
...@@ -16,7 +17,7 @@ pre { ...@@ -16,7 +17,7 @@ pre {
margin: 0; margin: 0;
padding: 0; padding: 0;
line-height: 24px; line-height: 24px;
color: #666; color: #fff;
font-size: 14px; font-size: 14px;
white-space: pre-wrap; white-space: pre-wrap;
word-break: break-all; word-break: break-all;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
</template> </template>
<script> <script>
export default { export default {
name: 'pc-menu-report-video',
props: { props: {
video: {}, video: {},
source: {}, source: {},
......
<template>
<div class="tab-box">
<ul class="list">
<li
class="item"
:class="{ 'z-active': activeIndex == index }"
v-for="(item, index) in menuListPc"
:key="index"
>
<div class="title" @click="_tabSwitch(index)">{{ item.menuName }}</div>
</li>
</ul>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
export default {
name: 'pv-menu-tab',
props: {
value: {}
},
computed: {
...mapGetters({
menuListPc: 'menuListPc'
}),
activeIndex: {
get() {
return this.value;
},
set(nVal) {
this.$emit('input', nVal);
}
}
},
methods: {
_tabSwitch(num) {
this.activeIndex = num;
}
}
};
</script>
<style lang="less" scoped>
.tab-box {
max-width: 80%;
margin: 16px auto;
.list {
display: flex;
align-items: center;
font-size: 18px;
.item {
flex: 1;
text-align: center;
.title {
position: relative;
display: inline-block;
min-width: 100px;
height: 45px;
line-height: 35px;
cursor: pointer;
}
&.z-active {
.title {
&:after {
content: '';
display: block;
position: absolute;
left: calc(50% - 20px);
bottom: 0;
width: 40px;
height: 4px;
background: var(--main-color);
border-radius: 4px;
}
}
}
}
}
}
</style>
<template>
<div class="player-box">
<div id="mps">
<div class="videoPlayer" id="videoPlayer">
<div style="display:none;">
<video></video>
</div>
</div>
</div>
<div v-show="!isFullScreen">
<div class="more">
<more-box :mps="mpsPlayerObj"></more-box>
</div>
</div>
</div>
</template>
<script>
import { getAddressForGet } from '@/plugins/API/apiAll';
import { mapGetters, mapMutations } from 'vuex';
import moreBox from './more';
export default {
name: 'pc-player-box',
components: {
moreBox
},
data() {
return {
mpsPlayerObj: null,
onePlayer: true, // 切换自动播放问题
isFullScreen: false
};
},
computed: {
...mapGetters({
channelInfo: 'channelInfo',
playerInfo: 'playerInfo'
}),
isUseNewH5() {
let arr = [1610, 1436, 1043];
let uin = this.channelInfo.uin;
return arr.some(x => x === uin);
},
mpsBackgroundUrl() {
let bgUrl = this.channelInfo.mpsBackgroundUrl;
return bgUrl ? `${bgUrl}?x-oss-process=style/twzb_origin` : '';
},
mpsOptions() {
let options = {};
if (this.channelInfo.hlsPwdStatus === 1) {
options = {
crypUrl: getAddressForGet(),
cryptBeforeSendFn: function(XMLHttpRequest) {
XMLHttpRequest.setRequestHeader('X-Ca-Stage', process.env.X_CA_STAGE);
},
cryptUrlType: 'get',
iv: '1152922081067', // 偏移量
sendKey: { channelId: this.channelInfo.id }, // 验证参数
crymode: 'CBC' // 默认CBC
};
} else {
options = {
hlsUrl: this.channelInfo.livePlayHlsUrl
};
}
return options;
}
},
mounted() {
this.$nextTick(() => {
this._mpsPlayerInit();
});
},
methods: {
...mapMutations({
set_playerInfo: 'set_playerInfo'
}),
_mpsPlayerInit() {
const self = this;
if (this.mpsPlayerObj) {
return false;
}
this.mpsPlayerObj = new mpsPlayer({
container: 'videoPlayer',
uin: this.channelInfo.aodianUin,
appId: this.channelInfo.mpsDynamicVodAppId,
width: '100%',
height: '100%',
controlbardisplay: 'enable',
orientation: 'portraint',
enablehtml5: true,
useNewH5: this.isUseNewH5,
coverImg: this.mpsBackgroundUrl,
...this.mpsOptions,
onReady() {
self._resetConfig();
setTimeout(() => {
self.mpsPlayerObj.addPlayerCallback('Play.Stop', function(fn) {
fn({ type: 3 });
});
self.mpsPlayerObj.addPlayerCallback('enterFullScreen', function() {
self.isFullScreen = true;
});
self.mpsPlayerObj.addPlayerCallback('exitFullScreen', function() {
self.isFullScreen = false;
});
}, 2000);
}
});
},
_resetConfig() {
let playUrl = '';
let saveUrl = '';
if (this.channelInfo.liveStatus === 1) {
playUrl = this.channelInfo.livePlayHlsUrl;
saveUrl = this.channelInfo.livePlayHlsUrl;
} else if (this.channelInfo.vodUrl && this.channelInfo.vodStatus) {
playUrl = this.channelInfo.vodUrl;
saveUrl = this.channelInfo.vodUrl;
} else {
playUrl = 'http://';
saveUrl = 'http://';
}
this.set_playerInfo({
playUrl: playUrl,
saveUrl: saveUrl,
cameraId: ''
});
},
_reviseProtocol(url) {
let path = url;
if (!path) {
return '';
}
if (window.location.protocol === 'http:') {
path = path.replace('https://', 'http://');
} else {
path = path.replace('http://', 'https://');
}
return path;
},
_changePlayer() {
let obj = null;
if (this.channelInfo.hlsPwdStatus === 1) {
if (this.playerInfo.playUrl === this.channelInfo.livePlayHlsUrl) {
obj = { channelId: this.channelInfo.id };
} else if (this.playerInfo.cameraId) {
obj = {
channelId: this.channelInfo.id,
cameraId: this.playerInfo.cameraId
};
} else {
obj = this._reviseProtocol(this.playerInfo.playUrl);
}
} else {
obj = this._reviseProtocol(this.playerInfo.playUrl);
}
if (this.mpsPlayerObj && this.mpsPlayerObj.changePlayer) {
if (this.onePlayer) {
this.mpsPlayerObj.changePlayer(obj, false);
this.onePlayer = false;
} else {
this.mpsPlayerObj.changePlayer(obj);
}
}
}
},
watch: {
playerInfo: {
handler() {
this._changePlayer();
},
deep: true
},
'channelInfo.liveStatus'(a) {
setTimeout(() => {
this._resetConfig();
}, 10000);
}
}
};
</script>
<style lang="less" scoped>
.player-box {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
.more {
position: absolute;
bottom: 50px;
right: -50px;
z-index: 200;
transition: right 0.5s ease 3s;
}
&:hover {
.more {
right: 10px;
transition: right 0.5s ease 0s;
}
}
}
#mps {
position: relative;
width: 100%;
height: 100%;
::v-deep div {
box-sizing: unset;
}
::v-deep #videoBox {
width: 100% !important;
height: 100% !important;
}
.videoPlayer {
position: relative;
z-index: 100;
width: 100%;
height: 100%;
}
}
</style>
<template>
<div class="more-box">
<div class="barrage" v-if="barrageInfo.status == 1" @click="_setBarrage">
<div class="icon-show" v-if="showBarrage"></div>
<div class="icon-hide" v-else></div>
</div>
<div class="back" v-if="showBack" @click="_backPlay">
<div class="icon"></div>
</div>
</div>
</template>
<script>
import { mapGetters, mapMutations } from 'vuex';
export default {
name: 'pc-player-more',
props: {
mps: {}
},
data() {
return {
showBarrage: true
};
},
computed: {
...mapGetters({
channelInfo: 'channelInfo',
playerInfo: 'playerInfo'
}),
barrageInfo() {
return this.channelInfo.barrageInfo;
},
showBack() {
return this.playerInfo.playUrl !== this.playerInfo.saveUrl;
}
},
mounted() {
this.$Bus.$on('bus-sendBarrage', this._sendBarrage);
},
methods: {
...mapMutations({
set_playerInfo: 'set_playerInfo'
}),
_backPlay() {
let info = JSON.parse(JSON.stringify(this.playerInfo));
info.playUrl = info.saveUrl;
info.cameraId = '';
this.set_playerInfo(info);
},
_setBarrage() {
this.showBarrage = !this.showBarrage;
if (!this.showBarrage && this.mps) {
this.mps.removelement();
}
},
makeColor() {
let colorArray = '0123456789abcdef';
let color = '';
for (let i = 0; i < 6; i++) {
color += colorArray[Math.floor(Math.random() * 16)];
}
return color;
},
_sendBarrage(str) {
let content = str.replace(/(#)[\u4e00-\u9fa5A-Za-z0-9.]+(#)/gi, '');
if (!this.mps || !content || !this.showBarrage || this.barrageInfo.status !== 1) {
return false;
}
let fontColor = this.barrageInfo.fontColor || 'FFFFFF';
let fontSize = this.barrageInfo.fontSize || 2;
let fontSpeed = this.barrageInfo.speed || 2;
let color = fontColor === 'random' ? this.makeColor() : fontColor;
let sizeArr = { '1': 16, '2': 20, '3': 32 };
let speedArr = { '1': 100, '2': 50, '3': 20 };
let size = sizeArr[fontSize] || 16;
let speed = speedArr[fontSpeed] || 50;
this.mps.sendbarrage2(content, size, '#' + color, speed, '', '微软雅黑');
}
},
beforeDestroy() {
this.$Bus.$off('bus-sendBarrage', this._sendBarrage);
}
};
</script>
<style lang="less" scoped>
.more-box {
.barrage {
margin-top: 10px;
width: 40px;
height: 40px;
border-radius: 100%;
background: rgba(0, 0, 0, 0.5);
cursor: pointer;
.icon-show {
width: 100%;
height: 100%;
background: url(./img/icon-barrage.png) no-repeat center center;
background-size: 50% auto;
}
.icon-hide {
width: 100%;
height: 100%;
background: url(./img/icon-barrage-no.png) no-repeat center center;
background-size: 50% auto;
}
}
.back {
margin-top: 10px;
width: 40px;
height: 40px;
border-radius: 100%;
background: rgba(0, 0, 0, 0.5);
cursor: pointer;
.icon {
width: 100%;
height: 100%;
background: url(./img/icon-back.png) no-repeat center center;
background-size: 50% auto;
}
}
}
</style>
<template>
<div class="qrcode-box">
<div class="watch">
<div class="watch-btn">
<div class="icon"></div>
<span class="title">手机观看</span>
</div>
<div class="watch-qr">
<img :src="watchQr" alt="" />
</div>
</div>
</div>
</template>
<script>
export default {
name: 'pc-qrcode-box',
data() {
return {
slefHref: ''
};
},
computed: {
watchQr() {
return `https://console.guangdianyun.tv/qrcode.php?level=L&size=10&text=${this.slefHref}`;
}
},
mounted() {
this.slefHref = encodeURIComponent(window.location.href);
}
};
</script>
<style lang="less" scoped>
.qrcode-box {
padding: 0 40px;
height: 100%;
.watch {
display: inline-block;
position: relative;
z-index: 100;
height: 100%;
.watch-btn {
color: #999999;
cursor: pointer;
.icon {
vertical-align: middle;
display: inline-block;
width: 16px;
height: 16px;
background: url(./img/icon-sj.png) no-repeat center center;
background-size: 100% 100%;
}
.title {
vertical-align: middle;
font-size: 18px;
}
}
&:hover {
.watch-qr {
display: block;
}
}
.watch-qr {
position: absolute;
bottom: 100%;
left: calc(50% - 100px);
display: none;
padding: 10px;
width: 200px;
height: 200px;
background: #27282e;
&::after {
content: '';
position: absolute;
bottom: -24px;
left: calc(50% - 12px);
display: inline-block;
width: 0;
height: 0;
border: 12px solid;
border-color: #27282e transparent transparent transparent;
}
img {
width: 100%;
height: 100%;
}
}
}
}
</style>
<template> <template>
<div class="red-box"> <div class="red-box" v-show="showRed && showRedInfo.id">
<div v-show="showRed && showRedInfo.id"> <div class="info-box">
<div class="default"> <div class="head">
<div class="get-box"> 手机扫描领取红包
<i class="close" @click="_closeRed"></i>
<div class="head-box">
<div class="title">手机扫描领取红包</div>
</div>
<div class="ewm">
<img
:src="
`https://console.guangdianyun.tv/qrcode.php?level=L&size=10&text=${slefHref}`
"
/>
</div>
</div>
</div> </div>
<div class="ewm">
<img :src="watchQr" />
</div>
<i class="close" @click="_closeRed"></i>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { mapGetters, mapMutations } from "vuex"; import { mapGetters, mapMutations } from 'vuex';
export default { export default {
name: 'pc-red-box',
data() { data() {
return { return {
slefHref: "" slefHref: ''
}; };
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
showRed: "showRed", showRed: 'showRed',
showRedInfo: "showRedInfo" showRedInfo: 'showRedInfo'
}) }),
watchQr() {
return `https://console.guangdianyun.tv/qrcode.php?level=L&size=10&text=${this.slefHref}`;
}
}, },
mounted() { mounted() {
this.slefHref = encodeURIComponent(window.location.href); this.slefHref = encodeURIComponent(window.location.href);
}, },
methods: { methods: {
...mapMutations({ ...mapMutations({
set_showRed: "set_showRed" set_showRed: 'set_showRed'
}), }),
_closeRed() { _closeRed() {
this.set_showRed(false); this.set_showRed(false);
...@@ -50,67 +46,53 @@ export default { ...@@ -50,67 +46,53 @@ export default {
<style lang="less" scoped> <style lang="less" scoped>
.red-box { .red-box {
.default { position: fixed;
position: fixed; top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 500;
background-color: rgba(0, 0, 0, 0.3);
.info-box {
position: absolute;
top: 0; top: 0;
left: 0; left: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
z-index: 500; z-index: 100;
background-color: rgba(0, 0, 0, 0.3); margin: auto;
width: 330px;
.get-box, height: 480px;
.luck-box { background: url('./img/red-bg.png') no-repeat 0 0;
background-size: 100% 100%;
.head {
padding-top: 130px;
color: #fff;
font-size: 25px;
text-align: center;
}
.ewm {
position: absolute; position: absolute;
top: 0; bottom: 20px;
left: 0; left: calc(50% - 145px);
right: 0; width: 290px;
bottom: 0; height: 290px;
height: 600px; img {
width: 400px; display: block;
margin: auto; width: 100%;
height: 100%;
.close {
position: absolute;
right: 10px;
top: 10px;
z-index: 2;
width: 20px;
height: 20px;
background: url("./img/red-close.png") no-repeat center center;
background-size: 100% 100%;
cursor: pointer;
} }
} }
.get-box { .close {
z-index: 100; position: absolute;
background: url("./img/red-bg.png") no-repeat 0 0; right: 0px;
top: -10px;
z-index: 2;
width: 40px;
height: 40px;
background: url('./img/red-close.png') no-repeat center center;
background-size: 100% 100%; background-size: 100% 100%;
cursor: pointer;
.head-box {
display: table;
width: 100%;
height: 22%;
text-align: center;
.title {
display: table-cell;
vertical-align: middle;
font-size: 30px;
color: #fff;
}
}
.ewm {
margin: 30px auto;
width: 300px;
height: 300px;
img {
display: block;
width: 100%;
height: 100%;
}
}
} }
} }
} }
......
<template> <template>
<div class="emoji" v-show="isShow"> <div class="emoji-box">
<div class="swiper-container" ref="emojiList"> <div class="swiper-container" ref="emojiList">
<div class="swiper-wrapper"> <div class="swiper-wrapper">
<div <div class="swiper-slide" v-for="(list, index) in emojiArr" :key="index">
class="swiper-slide"
v-for="(list, index) in emojiArr"
:key="index"
>
<ul class="list"> <ul class="list">
<li class="item" v-for="(item, index) in list" :key="index"> <li class="item" v-for="(item, index) in list" :key="index">
<div <div class="icon-item" v-if="item.index != 0" @click="_addText(item.icon)">
class="icon-item"
v-if="item.index != 0"
@click="_addText(item.icon)"
>
<i <i
class="icon-emoji" class="icon-emoji"
:style="{ :style="{
backgroundPositionY: -30 * (item.index - 1) + 'px', backgroundPositionY: -30 * (item.index - 1) + 'px'
}" }"
></i> ></i>
</div> </div>
<div class="icon-item" v-else @click="_remText"> <div class="icon-item" v-else @click="_remText">
<i <i class="icon-emoji" :style="{ backgroundPosition: 'left bottom' }"></i>
class="icon-emoji"
:style="{ backgroundPosition: 'left bottom' }"
></i>
</div> </div>
</li> </li>
</ul> </ul>
...@@ -37,19 +26,26 @@ ...@@ -37,19 +26,26 @@
</template> </template>
<script> <script>
import emoji_icon from "@/plugins/Filters/emoji/icons"; import emoji_icon from '@/plugins/Filters/emoji/icons';
export default { export default {
name: 'pc-send-emoji',
props: { props: {
value: {}, value: {}
isShow: {},
}, },
data() { data() {
return { return {
content: this.value, swiper: null
swiper: null,
}; };
}, },
computed: { computed: {
content: {
get() {
return this.value;
},
set(nVal) {
this.$emit('input', nVal);
}
},
emojiArr() { emojiArr() {
let arr = []; let arr = [];
let num = 20; let num = 20;
...@@ -61,21 +57,24 @@ export default { ...@@ -61,21 +57,24 @@ export default {
} }
arr[index].push({ index: key, icon: emoji_icon[key] }); arr[index].push({ index: key, icon: emoji_icon[key] });
if (key >= num && key % num === 0) { if (key >= num && key % num === 0) {
arr[index].push({ index: 0, icon: "删除" }); arr[index].push({ index: 0, icon: '删除' });
} }
} }
} }
return arr; return arr;
}, }
},
mounted() {
this._initSwiper();
}, },
methods: { methods: {
_initSwiper() { _initSwiper() {
if (!this.swiper) { if (!this.swiper) {
let option = { let option = {
direction: "horizontal", direction: 'horizontal',
pagination: { pagination: {
el: this.$refs.emojiPagination, el: this.$refs.emojiPagination
}, }
}; };
this.swiper = new this.$swiper(this.$refs.emojiList, option); this.swiper = new this.$swiper(this.$refs.emojiList, option);
} }
...@@ -88,74 +87,65 @@ export default { ...@@ -88,74 +87,65 @@ export default {
let reg = /(#)[\u4e00-\u9fa5A-Za-z0-9.]+(#)$/; let reg = /(#)[\u4e00-\u9fa5A-Za-z0-9.]+(#)$/;
if (text) { if (text) {
if (text.match(reg) != null) { if (text.match(reg) != null) {
text = text.replace(reg, ""); text = text.replace(reg, '');
} else { } else {
text = text.substring(0, text.length - 1); text = text.substring(0, text.length - 1);
} }
} }
this.content = text; this.content = text;
}, }
}, }
watch: {
isShow() {
this.$nextTick(() => {
this._initSwiper();
});
},
value(nVal) {
this.content = nVal;
},
content(nVal) {
this.$emit("input", nVal);
},
},
}; };
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.emoji { .emoji-box {
position: relative; position: absolute;
height: 150px; top: 100%;
padding: 5px 5px 0 5px; left: 0;
z-index: 100;
width: 100%;
padding: 5px;
height: 140px;
background: #fff;
.swiper-container { .swiper-container {
width: 100%; width: 100%;
height: 100%; height: 100%;
.swiper-slide { .swiper-slide {
text-align: center;
font-size: 18px;
background: #fff;
height: 100%; height: 100%;
.list {
display: flex;
flex-wrap: wrap;
.item {
flex: 0 0 auto;
width: 100% / 7;
height: 40px;
line-height: 40px;
text-align: center;
.icon-item {
display: inline-block;
vertical-align: middle;
}
}
}
.icon-emoji {
display: block;
margin: auto;
width: 30px;
height: 30px;
background-position: left top;
background-size: 30px auto;
background-repeat: no-repeat;
background-image: url("//static-pro.guangdianyun.tv/static/emoji/newqq/list.jpg");
}
} }
} }
.swiper-pagination {
bottom: 0;
::v-deep .swiper-pagination-bullet-active {
background-color: var(--main-color);
}
}
}
.list {
display: flex;
flex-wrap: wrap;
.item {
flex: 0 0 auto;
width: 100% / 7;
height: 40px;
line-height: 40px;
text-align: center;
.icon-item {
display: inline-block;
vertical-align: middle;
cursor: pointer;
}
}
.icon-emoji {
display: block;
margin: auto;
width: 30px;
height: 30px;
background-position: left top;
background-size: 30px auto;
background-repeat: no-repeat;
background-image: url('//static-pro.guangdianyun.tv/static/emoji/newqq/list.jpg');
}
} }
</style> </style>
<template>
<div class="send-box">
<div class="send-content">
<div class="disabled" v-if="channelInfo.chatDisable">全员禁言中</div>
<div class="disabled" v-else-if="userInfo.isDisableChat == 1">
你已被禁言
</div>
<textarea
class="textarea"
v-else-if="allowChat"
maxlength="100"
v-model="content"
placeholder="我也要说点什么"
></textarea>
<div class="login" v-else>
<span @click="_isDisabled()">登录</span>
后可参与互动
</div>
</div>
<div class="send-operation">
<div class="send-img" @click.stop="_uplaod">
<input
type="file"
style="display: none"
ref="file"
@change="_uploadImg"
accept="image/png,image/jpeg,image/jpg"
/>
</div>
<div class="send-emoji" @click.stop="_toggleEmoji"></div>
<div class="send-btn" @click.stop="_sendChat">发送</div>
<keep-alive>
<emoji-box v-if="showEmoji" v-model="content"></emoji-box>
</keep-alive>
</div>
</div>
</template>
<script>
import { sendChat, sendPhoto } from '@/plugins/API/apiAll';
import { mapGetters } from 'vuex';
import emojiBox from './emoji';
export default {
name: 'pc-send-box',
components: {
emojiBox
},
data() {
return {
showEmoji: false,
sendDate: 0,
content: ''
};
},
computed: {
...mapGetters({
channelInfo: 'channelInfo',
userInfo: 'userInfo'
}),
allowChat() {
if (!this.userInfo.id && this.channelInfo.chatLogin) {
return false;
} else {
return true;
}
}
},
methods: {
// 发送聊天
async _sendChat() {
this.showEmoji = false;
if (this._isDisabled()) {
return false;
}
if (new Date().getTime() - this.sendDate <= 3000) {
this.$layer.msg('您的操作太频繁了');
return false;
}
if (!this.content.trim() || this.content.trim().length > 100) {
this.$layer.msg('评论不能为空,且不超过100个字!');
return;
}
this.sendDate = new Date().getTime();
const res = await sendChat({
uin: this.channelInfo.uin,
channelId: this.channelInfo.id,
replyId: '',
content: this.content.trim()
});
if (res.code === 200 && res.errorCode === 0) {
this.content = '';
if (res.data.chatAuthModel === 1) {
this.$layer.msg('已提交审核,请耐心等待');
}
}
},
_isDisabled() {
if (this.userInfo.isDisableChat === 1) {
this.$layer.msg('你已经被禁言,该功能暂时无法使用');
return true;
} else if (this.channelInfo.chatDisable) {
this.content = '';
return true;
}
if (!this.allowChat) {
this.$Bus.$emit('bus-showLogin', true);
return true;
}
},
_toggleEmoji() {
if (this._isDisabled()) {
return false;
}
this.showEmoji = !this.showEmoji;
},
_uplaod() {
if (this._isDisabled()) {
return false;
}
this.$refs.file.click();
},
_uploadImg(e) {
let self = this;
let input = e.target;
if (!input.value) {
return false;
}
if (input.files && input.files[0]) {
let reader = new FileReader();
reader.onload = function() {
self._createCanvas(reader.result);
input.value = '';
};
reader.readAsDataURL(input.files[0]);
}
},
_createCanvas(src) {
let self = this;
let canvas = document.createElement('canvas');
let cxt = canvas.getContext('2d');
let img = new Image();
img.src = src;
let maxW = 400;
let maxH = 600;
img.onload = function() {
let w = img.width;
let h = img.height;
if (w > maxW || h > maxH) {
let p = w / maxW > h / maxH ? w / maxW : h / maxH;
w = img.width / p;
h = img.height / p;
img.width = w;
img.height = h;
}
canvas.width = w;
canvas.height = h;
cxt.drawImage(img, 0, 0, w, h);
let newsrc = canvas.toDataURL('image/jpeg', 0.9);
self._sendPhoto(newsrc);
};
},
async _sendPhoto(src) {
if (src) {
const res = await sendPhoto({
uin: this.channelInfo.uin,
channelId: this.channelInfo.id,
img: src
});
if (res.code === 200 && res.errorCode === 0) {
this.$layer.msg('已提交审核,请耐心等待');
}
}
}
}
};
</script>
<style lang="less" scoped>
.send-box {
position: relative;
padding: 10px;
height: 100%;
background: #27282e;
border-radius: 8px;
.send-content {
height: 60px;
line-height: 60px;
.disabled {
text-align: center;
font-size: 16px;
}
.textarea {
width: 100%;
height: 100%;
line-height: 20px;
background: transparent;
border: 0;
font-size: 16px;
color: #fff;
outline: none;
resize: none;
}
.login {
text-align: center;
font-size: 14px;
span {
color: var(--main-color);
cursor: pointer;
}
}
}
.send-operation {
position: relative;
height: 50px;
text-align: right;
.send-img {
vertical-align: middle;
margin-right: 12px;
display: inline-block;
width: 24px;
height: 24px;
background: url(./img/icon-upload.png) no-repeat center center;
background-size: 100% 100%;
cursor: pointer;
}
.send-emoji {
vertical-align: middle;
margin-right: 12px;
display: inline-block;
width: 24px;
height: 24px;
background: url(./img/icon-emoji.png) no-repeat center center;
background-size: 100% 100%;
cursor: pointer;
}
.send-btn {
vertical-align: middle;
display: inline-block;
width: 80px;
height: 36px;
line-height: 36px;
background: var(--main-color);
text-align: center;
font-size: 18px;
border-radius: 2px;
cursor: pointer;
}
}
}
</style>
...@@ -16,8 +16,9 @@ ...@@ -16,8 +16,9 @@
</div> </div>
</template> </template>
<script> <script>
import { mapGetters, mapMutations } from "vuex"; import { mapGetters, mapMutations } from 'vuex';
export default { export default {
name: 'advert-middle',
data() { data() {
return { return {
spread: this.$route.query.spread, spread: this.$route.query.spread,
...@@ -27,7 +28,7 @@ export default { ...@@ -27,7 +28,7 @@ export default {
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
advertMiddle: "advertMiddle" advertMiddle: 'advertMiddle'
}) })
}, },
mounted() { mounted() {
...@@ -38,12 +39,12 @@ export default { ...@@ -38,12 +39,12 @@ export default {
}, },
methods: { methods: {
...mapMutations({ ...mapMutations({
set_advertMiddle: "set_advertMiddle" set_advertMiddle: 'set_advertMiddle'
}), }),
_initSwiper() { _initSwiper() {
let self = this; let self = this;
let option = { let option = {
direction: "horizontal", direction: 'horizontal',
loop: true, loop: true,
autoplay: self.list.length > 1 ? { delay: 5000 } : false autoplay: self.list.length > 1 ? { delay: 5000 } : false
}; };
...@@ -56,7 +57,7 @@ export default { ...@@ -56,7 +57,7 @@ export default {
} }
}, },
watch: { watch: {
"advertMiddle.list"(nVal) { 'advertMiddle.list'(nVal) {
this.list = nVal; this.list = nVal;
this.$nextTick(() => { this.$nextTick(() => {
this._initSwiper(); this._initSwiper();
...@@ -96,10 +97,10 @@ export default { ...@@ -96,10 +97,10 @@ export default {
right: 0; right: 0;
top: 0; top: 0;
z-index: 10; z-index: 10;
width: 30px; width: 0.3rem;
height: 30px; height: 0.3rem;
background: url("./img/icon-close.png") no-repeat center center; background: url('./img/icon-close.png') no-repeat center center;
background-size: 20px 20px; background-size: 0.2rem 0.2rem;
} }
} }
} }
......
...@@ -9,25 +9,26 @@ ...@@ -9,25 +9,26 @@
</div> </div>
</template> </template>
<script> <script>
import { mapGetters } from "vuex"; import { mapGetters } from 'vuex';
export default { export default {
name: 'advert-text',
computed: { computed: {
...mapGetters({ ...mapGetters({
advertText: "advertText", advertText: 'advertText'
}), })
}, },
methods: {}, methods: {}
}; };
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.ad-text { .ad-text {
width: 100%; width: 100%;
height: 30px; height: 0.3rem;
line-height: 30px; line-height: 0.3rem;
background: #ffe9bd; background: #ffe9bd;
font-size: 14px; font-size: 0.14rem;
a { a {
display: block; display: block;
height: 100%; height: 100%;
......
...@@ -16,8 +16,9 @@ ...@@ -16,8 +16,9 @@
</div> </div>
</template> </template>
<script> <script>
import { mapGetters, mapMutations } from "vuex"; import { mapGetters, mapMutations } from 'vuex';
export default { export default {
name: 'advert-top',
data() { data() {
return { return {
spread: this.$route.query.spread, spread: this.$route.query.spread,
...@@ -27,7 +28,7 @@ export default { ...@@ -27,7 +28,7 @@ export default {
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
advertTop: "advertTop" advertTop: 'advertTop'
}) })
}, },
mounted() { mounted() {
...@@ -38,12 +39,12 @@ export default { ...@@ -38,12 +39,12 @@ export default {
}, },
methods: { methods: {
...mapMutations({ ...mapMutations({
set_advertTop: "set_advertTop" set_advertTop: 'set_advertTop'
}), }),
_initSwiper() { _initSwiper() {
let self = this; let self = this;
let option = { let option = {
direction: "vertical", direction: 'vertical',
loop: true, loop: true,
autoplay: self.list.length > 1 ? { delay: 5000 } : false autoplay: self.list.length > 1 ? { delay: 5000 } : false
}; };
...@@ -56,7 +57,7 @@ export default { ...@@ -56,7 +57,7 @@ export default {
} }
}, },
watch: { watch: {
"advertTop.list"(nVal) { 'advertTop.list'(nVal) {
this.list = nVal; this.list = nVal;
this.$nextTick(() => { this.$nextTick(() => {
this._initSwiper(); this._initSwiper();
...@@ -96,10 +97,10 @@ export default { ...@@ -96,10 +97,10 @@ export default {
right: 0; right: 0;
top: 0; top: 0;
z-index: 10; z-index: 10;
width: 30px; width: 0.3rem;
height: 30px; height: 0.3rem;
background: url("./img/icon-close.png") no-repeat center center; background: url('./img/icon-close.png') no-repeat center center;
background-size: 20px 20px; background-size: 0.2rem 0.2rem;
} }
} }
} }
......
...@@ -9,15 +9,16 @@ ...@@ -9,15 +9,16 @@
> >
<div class="name">{{ item.name }}</div> <div class="name">{{ item.name }}</div>
<img class="img" v-if="item.thumbnail" :src="item.thumbnail" alt="" /> <img class="img" v-if="item.thumbnail" :src="item.thumbnail" alt="" />
<img class="img" v-else src="./img/icon-video.png" alt="" /> <div class="icon" v-else></div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { getCaremaList } from "@/plugins/API/apiAll"; import { getCaremaList } from '@/plugins/API/apiAll';
import { mapGetters, mapMutations } from "vuex"; import { mapGetters, mapMutations } from 'vuex';
export default { export default {
name: 'camera-box',
data() { data() {
return { return {
list: [] list: []
...@@ -25,8 +26,8 @@ export default { ...@@ -25,8 +26,8 @@ export default {
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
channelInfo: "channelInfo", channelInfo: 'channelInfo',
playerInfo: "playerInfo" playerInfo: 'playerInfo'
}) })
}, },
mounted() { mounted() {
...@@ -34,7 +35,7 @@ export default { ...@@ -34,7 +35,7 @@ export default {
}, },
methods: { methods: {
...mapMutations({ ...mapMutations({
set_playerInfo: "set_playerInfo" set_playerInfo: 'set_playerInfo'
}), }),
// 获取多机位 // 获取多机位
async _getCaremaList() { async _getCaremaList() {
...@@ -61,8 +62,8 @@ export default { ...@@ -61,8 +62,8 @@ export default {
<style lang="less" scoped> <style lang="less" scoped>
.camera { .camera {
height: 53px; height: 0.53rem;
padding: 4px 6px; padding: 0.04rem 0.06rem;
overflow-x: auto; overflow-x: auto;
background-color: #f6f6f6; background-color: #f6f6f6;
white-space: nowrap; white-space: nowrap;
...@@ -70,11 +71,11 @@ export default { ...@@ -70,11 +71,11 @@ export default {
.box { .box {
display: inline-block; display: inline-block;
position: relative; position: relative;
margin-right: 6px; margin-right: 0.06rem;
width: 80px; width: 0.8rem;
height: 45px; height: 0.45rem;
border-radius: 2px; border-radius: 0.02rem;
border: 1px solid transparent; border: 0.01rem solid transparent;
overflow: hidden; overflow: hidden;
.img { .img {
display: block; display: block;
...@@ -82,11 +83,17 @@ export default { ...@@ -82,11 +83,17 @@ export default {
height: 100%; height: 100%;
background-color: #333333; background-color: #333333;
} }
.icon {
width: 100%;
height: 100%;
background: #4a4a4a url(./img/icon-video.png) no-repeat center center;
background-size: 20% auto;
}
.name { .name {
position: absolute; position: absolute;
top: 2px; top: 0.02rem;
left: 2px; left: 0.02rem;
font-size: 6px; font-size: 0.06rem;
color: #fff; color: #fff;
} }
&.z-active { &.z-active {
......
<template>
<div class="follow-mask" @click="_hide">
<div class="follow" @click.stop>
<div class="top">
<span>{{ wechatInfo.WeChatName }}</span>
</div>
<div class="img-box">
<img class="img" :src="wechatInfo.imgUrl" alt="" />
</div>
<div class="bottom">关注后可以收到直播最新动态哦~</div>
<div class="close" @click="_hide"></div>
</div>
</div>
</template>
<script>
export default {
name: 'follow-box',
props: {
value: {}
},
computed: {
wechatInfo: {
get() {
return this.value;
},
set(nVal) {
this.$emit('input', nVal);
}
}
},
methods: {
_hide() {
this.wechatInfo.isShow = false;
}
}
};
</script>
<style lang="less" scoped>
.follow-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1000;
background: rgba(0, 0, 0, 0.3);
.follow {
position: absolute;
top: 50%;
left: 50%;
width: 2.6rem;
padding: 0.15rem 0.3rem;
transform: translateX(-50%) translateY(-50%);
background-color: #fff;
border-radius: 0.05rem;
.top {
line-height: 0.2rem;
padding: 0 0.3rem 0.15rem;
margin: 0 -0.3rem;
border-bottom: 0.01rem solid #cfcfcf;
text-align: center;
font-size: 0.15rem;
white-space: nowrap;
text-overflow: ellipsis;
color: #404040;
overflow: hidden;
span {
color: var(--main-color);
}
}
.img-box {
position: relative;
margin: 0.1rem auto;
padding-top: 100%;
height: 0;
.img {
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
}
.bottom {
line-height: 0.2rem;
text-align: center;
color: #9d9d9d;
font-size: 0.13rem;
}
.close {
position: absolute;
right: 0;
top: -0.5rem;
z-index: 100;
width: 0.3rem;
height: 0.3rem;
background-image: url('./img/icon-close.png');
background-repeat: no-repeat;
background-position: center center;
background-size: 100% 100%;
cursor: pointer;
&:before {
position: absolute;
top: 0.3rem;
left: 0.14rem;
display: block;
width: 0;
content: '';
border: 0.01rem solid #fff;
height: 0.3rem;
}
}
}
}
</style>
...@@ -2,11 +2,7 @@ ...@@ -2,11 +2,7 @@
<div class="wrapper"> <div class="wrapper">
<div class="swiper-container" ref="swiper"> <div class="swiper-container" ref="swiper">
<div class="swiper-wrapper"> <div class="swiper-wrapper">
<div <div class="swiper-slide" v-for="(item, index) in menuList" :key="index">
class="swiper-slide"
v-for="(item, index) in menuList"
:key="index"
>
<template v-if="item.menuType == 'imagetext'"> <template v-if="item.menuType == 'imagetext'">
<image-text :menuInfo="item.menuInfo"></image-text> <image-text :menuInfo="item.menuInfo"></image-text>
</template> </template>
...@@ -40,18 +36,19 @@ ...@@ -40,18 +36,19 @@
</div> </div>
</template> </template>
<script> <script>
import { mapGetters } from "vuex"; import { mapGetters } from 'vuex';
const imageText = resolve => require(["./menuClass/imageText"], resolve); const imageText = resolve => require(['./menuClass/imageText'], resolve);
const playLists = resolve => require(["./menuClass/playLists/index"], resolve); const playLists = resolve => require(['./menuClass/playLists/index'], resolve);
const inviteBox = resolve => require(["./menuClass/invite"], resolve); const inviteBox = resolve => require(['./menuClass/invite'], resolve);
const shopBox = resolve => require(["./menuClass/shop"], resolve); const shopBox = resolve => require(['./menuClass/shop'], resolve);
const couponBox = resolve => require(["./menuClass/coupon"], resolve); const couponBox = resolve => require(['./menuClass/coupon'], resolve);
const reportBox = resolve => require(["./menuClass/report"], resolve); const reportBox = resolve => require(['./menuClass/report'], resolve);
const chatBox = resolve => require(["./menuClass/chat"], resolve); const chatBox = resolve => require(['./menuClass/chat'], resolve);
const iframeLine = resolve => require(["./menuClass/iframeLine"], resolve); const iframeLine = resolve => require(['./menuClass/iframeLine'], resolve);
const empty404 = resolve => require(["./menuClass/404"], resolve); const empty404 = resolve => require(['./menuClass/404'], resolve);
export default { export default {
name: 'menu-list',
components: { components: {
imageText, imageText,
playLists, playLists,
...@@ -74,13 +71,13 @@ export default { ...@@ -74,13 +71,13 @@ export default {
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
menuList: "menuList" menuList: 'menuList'
}), }),
isShowChat() { isShowChat() {
let index = -1; let index = -1;
for (let i = 0; i < this.menuList.length; i++) { for (let i = 0; i < this.menuList.length; i++) {
let item = this.menuList[i]; let item = this.menuList[i];
if (item.menuType === "chat") { if (item.menuType === 'chat') {
index = i; index = i;
} }
} }
...@@ -115,7 +112,7 @@ export default { ...@@ -115,7 +112,7 @@ export default {
this._tabSwitch(); this._tabSwitch();
}, },
active(nVal) { active(nVal) {
this.$emit("input", nVal); this.$emit('input', nVal);
} }
} }
}; };
......
<template>
<div class="state404">
<!-- 404 -->
<img src="@/assets/img/404.png" alt="" />
</div>
</template>
<script>
export default {
name: 'menu-404',
computed: {},
methods: {}
};
</script>
<style lang="less" scoped>
.state404 {
width: 100%;
height: 100%;
background: #fff;
img {
object-fit: scale-down;
display: block;
width: 100%;
height: 100%;
}
}
</style>
...@@ -6,30 +6,38 @@ ...@@ -6,30 +6,38 @@
<div class="chat-box"> <div class="chat-box">
<chat-box></chat-box> <chat-box></chat-box>
</div> </div>
<send-box v-show="isShowChat" v-transfer-dom></send-box>
<suspension-box v-show="isShowChat" v-transfer-dom></suspension-box>
</div> </div>
</template> </template>
<script> <script>
import { mapGetters } from "vuex"; import { mapGetters } from 'vuex';
import topChatBox from "./chat/topChat"; import topChatBox from './chat/topChat';
import chatBox from "./chat/chat"; import chatBox from './chat/chat';
import sendBox from '@/components/modules/sendBox';
import suspensionBox from '@/components/modules/suspensionBox';
export default { export default {
name: 'menu-chat-box',
components: { components: {
topChatBox, topChatBox,
chatBox, chatBox,
sendBox,
suspensionBox
}, },
props: { props: {
isShowChat: {}, isShowChat: {}
}, },
data() { data() {
return {}; return {};
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
userInfo: "userInfo", userInfo: 'userInfo',
channelInfo: "channelInfo", channelInfo: 'channelInfo'
}), })
}, },
methods: {}
}; };
</script> </script>
...@@ -39,6 +47,8 @@ export default { ...@@ -39,6 +47,8 @@ export default {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
padding-top: 0.05rem;
padding-bottom: 0.5rem;
.top-chat-list { .top-chat-list {
flex: 0 0 auto; flex: 0 0 auto;
} }
......
...@@ -3,12 +3,7 @@ ...@@ -3,12 +3,7 @@
<div class="list-box" ref="chatListBox" @scroll="getMore"> <div class="list-box" ref="chatListBox" @scroll="getMore">
<div class="loading" v-show="!isAjax">{{ loadingMsg }}</div> <div class="loading" v-show="!isAjax">{{ loadingMsg }}</div>
<div id="chatList" class="list" ref="chatList"> <div id="chatList" class="list" ref="chatList">
<div <div class="item" v-for="item in list" :key="item.id" :data-chatid="item.id">
class="item"
v-for="item in list"
:key="item.id"
:data-chatid="item.id"
>
<chat-item :info="item"></chat-item> <chat-item :info="item"></chat-item>
</div> </div>
</div> </div>
...@@ -29,12 +24,7 @@ ...@@ -29,12 +24,7 @@
<div class="list-box" ref="chatListBox"> <div class="list-box" ref="chatListBox">
<div id="chatList" class="list" ref="chatList"> <div id="chatList" class="list" ref="chatList">
<div class="loading" v-if="redList.length == 0">暂无数据</div> <div class="loading" v-if="redList.length == 0">暂无数据</div>
<div <div class="item" v-for="item in redList" :key="item.id" :data-chatid="item.id">
class="item"
v-for="item in redList"
:key="item.id"
:data-chatid="item.id"
>
<chat-item :info="item"></chat-item> <chat-item :info="item"></chat-item>
</div> </div>
</div> </div>
...@@ -43,35 +33,36 @@ ...@@ -43,35 +33,36 @@
</template> </template>
<script> <script>
import { getChatList } from "@/plugins/API/apiAll"; import { getChatList } from '@/plugins/API/apiAll';
import { mapGetters } from "vuex"; import { mapGetters } from 'vuex';
import chatItem from "./chatItem/index"; import chatItem from './chatItem/index';
export default { export default {
name: 'chat-list',
components: { components: {
chatItem, chatItem
}, },
data() { data() {
return { return {
isAjax: true, isAjax: true,
loadingMsg: "", loadingMsg: '',
page: 1, page: 1,
num: 50, num: 50,
list: [], list: [],
redList: [], redList: [],
unreadChatNum: 0, unreadChatNum: 0,
replyChatId: "", replyChatId: ''
}; };
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
userInfo: "userInfo", userInfo: 'userInfo',
channelInfo: "channelInfo", channelInfo: 'channelInfo',
onlySeeRed: "onlySeeRed", onlySeeRed: 'onlySeeRed'
}), })
}, },
mounted() { mounted() {
this.$Bus.$on("bus-addChat", this.addChat); this.$Bus.$on('bus-addChat', this.addChat);
this.$Bus.$on("bus-delChat", this.delChat); this.$Bus.$on('bus-delChat', this.delChat);
this.getChatList(); this.getChatList();
}, },
methods: { methods: {
...@@ -95,21 +86,20 @@ export default { ...@@ -95,21 +86,20 @@ export default {
return false; return false;
} }
this.isAjax = false; this.isAjax = false;
this.loadingMsg = "加载中..."; this.loadingMsg = '加载中...';
const res = await getChatList({ const res = await getChatList({
uin: this.channelInfo.uin, uin: this.channelInfo.uin,
channelId: this.channelInfo.id, channelId: this.channelInfo.id,
page: this.page, page: this.page,
num: this.num, num: this.num
}); });
if (res.code === 200 && res.errorCode === 0) { if (res.code === 200 && res.errorCode === 0) {
let list = res.data || []; let list = res.data || [];
let firstLi = let firstLi =
document.querySelector("#chatList") && document.querySelector('#chatList') && document.querySelector('#chatList').children[0];
document.querySelector("#chatList").children[0]; list.forEach(item => {
list.forEach((item) => {
this.addChat(item, true); this.addChat(item, true);
}); });
this.$nextTick(() => { this.$nextTick(() => {
...@@ -123,20 +113,20 @@ export default { ...@@ -123,20 +113,20 @@ export default {
} }
if (list.length < 50) { if (list.length < 50) {
this.isAjax = false; this.isAjax = false;
this.loadingMsg = "已加载所有评论"; this.loadingMsg = '已加载所有评论';
} else { } else {
this.page++; this.page++;
this.isAjax = true; this.isAjax = true;
this.loadingMsg = ""; this.loadingMsg = '';
} }
}); });
} else { } else {
this.isAjax = true; this.isAjax = true;
this.loadingMsg = ""; this.loadingMsg = '';
} }
}, },
addRedList(obj, order) { addRedList(obj, order) {
this.redList = this.redList.filter((x) => { this.redList = this.redList.filter(x => {
return Number(x.id) !== Number(obj.id); return Number(x.id) !== Number(obj.id);
}); });
if (order) { if (order) {
...@@ -146,14 +136,14 @@ export default { ...@@ -146,14 +136,14 @@ export default {
} }
}, },
delRedList(id) { delRedList(id) {
this.redList = this.redList.filter((x) => { this.redList = this.redList.filter(x => {
return Number(x.id) !== Number(id); return Number(x.id) !== Number(id);
}); });
}, },
addChat(obj, order = false) { addChat(obj, order = false) {
let chatObj = obj; let chatObj = obj;
let redType = [3, 8]; // msgType红包类型 let redType = [3, 8]; // msgType红包类型
this.list = this.list.filter((x) => { this.list = this.list.filter(x => {
return Number(x.id) !== Number(chatObj.id); return Number(x.id) !== Number(chatObj.id);
}); });
if (redType.indexOf(Number(chatObj.msgType)) !== -1) { if (redType.indexOf(Number(chatObj.msgType)) !== -1) {
...@@ -162,9 +152,7 @@ export default { ...@@ -162,9 +152,7 @@ export default {
} }
if (this.list.length) { if (this.list.length) {
let newTime = chatObj.addTime; let newTime = chatObj.addTime;
let prevTime = order let prevTime = order ? this.list[0].addTime : this.list[this.list.length - 1].addTime;
? this.list[0].addTime
: this.list[this.list.length - 1].addTime;
if (Math.abs(newTime - prevTime) > 600) { if (Math.abs(newTime - prevTime) > 600) {
chatObj.showTime = true; chatObj.showTime = true;
} }
...@@ -181,7 +169,7 @@ export default { ...@@ -181,7 +169,7 @@ export default {
} }
}, },
delChat(id) { delChat(id) {
this.list = this.list.filter((x) => { this.list = this.list.filter(x => {
return Number(x.id) !== Number(id); return Number(x.id) !== Number(id);
}); });
this.delRedList(id); this.delRedList(id);
...@@ -230,20 +218,20 @@ export default { ...@@ -230,20 +218,20 @@ export default {
this._closeReply(); this._closeReply();
}, },
_closeReply() { _closeReply() {
this.replyChatId = ""; this.replyChatId = '';
}, }
}, },
watch: { watch: {
onlySeeRed() { onlySeeRed() {
this.$nextTick(() => { this.$nextTick(() => {
this._scrollBottom(); this._scrollBottom();
}); });
}, }
}, },
beforeDestroy() { beforeDestroy() {
this.$Bus.$off("bus-addChat", this.addChat); this.$Bus.$off('bus-addChat', this.addChat);
this.$Bus.$off("bus-delChat", this.delChat); this.$Bus.$off('bus-delChat', this.delChat);
}, }
}; };
</script> </script>
...@@ -257,51 +245,51 @@ export default { ...@@ -257,51 +245,51 @@ export default {
width: 100%; width: 100%;
overflow-y: auto; overflow-y: auto;
.loading { .loading {
height: 30px; height: 0.3rem;
line-height: 30px; line-height: 0.3rem;
text-align: center; text-align: center;
color: #858587; color: #858587;
font-size: 14px; font-size: 0.14rem;
} }
.list { .list {
position: relative; position: relative;
.item { .item {
padding: 5px 10px; padding: 0.05rem 0.1rem;
} }
} }
} }
.chat-unread { .chat-unread {
position: absolute; position: absolute;
bottom: 10px; bottom: 0.1rem;
left: 0; left: 0;
z-index: 1; z-index: 1;
width: 100%; width: 100%;
text-align: center; text-align: center;
span { span {
padding: 3px 10px; padding: 0.03rem 0.1rem;
background-color: var(--main-color); background-color: var(--main-color);
border-radius: 30px; border-radius: 0.3rem;
font-size: 12px; font-size: 0.12rem;
color: #fff; color: #fff;
} }
} }
.chat-reply { .chat-reply {
position: absolute; position: absolute;
bottom: 10px; bottom: 0.1rem;
left: 10px; left: 0.1rem;
z-index: 1; z-index: 1;
padding: 3px 5px; padding: 0.03rem 0.05rem;
background-color: var(--main-color); background-color: var(--main-color);
border-radius: 3px; border-radius: 0.03rem;
.title { .title {
color: #fff; color: #fff;
font-size: 14px; font-size: 0.14rem;
} }
.close { .close {
display: inline-block; display: inline-block;
vertical-align: top; vertical-align: top;
margin-left: 3px; margin-left: 0.03rem;
font-size: 16px; font-size: 0.16rem;
color: #333; color: #333;
} }
} }
......
<template>
<div class="chat-img">
<div class="user-head">
<img :src="userHead" alt="" />
</div>
<div class="right">
<div class="name">{{ info.userNick }}</div>
<div class="content">
<img v-photoswipe="{ group: 'chat' }" :src="info.filterContent" />
</div>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
export default {
name: 'chat-img',
props: {
info: {}
},
computed: {
...mapGetters({
channelInfo: 'channelInfo'
}),
userHead() {
let userHeadImg = this.info.userHeadImg;
if (userHeadImg === 'phoneHead') {
return this.channelInfo.defaultPhoneHeadAva;
} else if (userHeadImg === 'default') {
return this.channelInfo.defaultUserAva;
} else if (!userHeadImg) {
return this.channelInfo.defaultUserAva;
} else {
return userHeadImg;
}
}
}
};
</script>
<style lang="less" scoped>
.chat-img {
display: flex;
.user-head {
width: 0.36rem;
height: 0.36rem;
border-radius: 0.04rem;
overflow: hidden;
img {
width: 100%;
height: 100%;
}
}
.right {
flex: 1;
padding: 0 0.1rem;
.name {
line-height: 0.2rem;
color: #9b9b9b;
font-size: 0.12rem;
}
.content {
padding: 0.05rem;
display: inline-block;
max-width: 80%;
background: var(--chat-bg);
border-radius: 0.05rem;
border: 0.01rem solid var(--chat-border-color);
img {
max-width: 100%;
max-height: 1.5rem;
}
}
}
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment