123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- <template>
- <view v-if="Object.keys(episode).length" class="episode-part">
- <view class="footer" :class="{episode: footerShow}">
- <view class="bar main-between cross-center" @click="footerShow = !footerShow">
- <view class="icon" />
- <view class="name">
- <u-text :text="episode.name" :color="$colors.infoColor" :lines="1" />
- </view>
- <view class="arrow">
- <u-icon name="arrow-up" :color="$colors.infoColor" size="32rpx" />
- </view>
- </view>
- <view class="episode-container dir-top-wrap">
- <!--分集 横向滚动-->
- <scroll-view
- class="header-box dir-left-nowrap cross-center"
- scroll-x
- scroll-with-animation
- >
- <view
- v-for="(item,index) in episodeTabData"
- :key="index"
- class="header-item"
- :class="{active: episodesTabIndex === index}"
- @click="episodesTabIndex = index"
- >{{ item.title }}</view>
- </scroll-view>
- <!--几集选择-->
- <view class="content dir-left-wrap main-left">
- <view
- v-for="(item, index) in episodeTabData[episodesTabIndex].lists"
- :key="index"
- class="episode-item"
- @click="handleSelectEpisode(item.index)"
- >
- <image :src="episode.cover_img" />
- <text>第{{ item.sort }}集</text>
- <view v-if="currentEpisode.sort === item.sort && isPlaying" class="playing" />
- <view
- v-if="!item.is_free && buyRecord.indexOf(item.id) === -1 && !(episode.is_vip_watch && userInfo.info.is_vip)"
- class="lock main-center cross-center"
- >
- <u-icon name="lock-fill" :color="$colors.defaultColor" size="46rpx" />
- </view>
- </view>
- </view>
- </view>
- </view>
- </view>
- </template>
- <script>
- import { mapState } from 'vuex'
- export default {
- name: 'EpisodePart',
- props: {
- episode: {
- type: Object,
- required: true,
- default() {
- return {}
- }
- },
- currentEpisode: {
- type: Object,
- required: true
- },
- isPlaying: {
- type: Boolean,
- required: true
- },
- buyRecord: {
- type: Array,
- required: true
- }
- },
- data() {
- return {
- footerShow: false, // 底部是否弹出
- episodesTabIndex: 0 // 分集 Tab 选中
- }
- },
- computed: {
- ...mapState({
- userInfo: seate => seate.user.info
- }),
- episodeTabData() {
- const list = []
- if (Object.keys(this.episode).length) {
- let temp = []
- this.episode.lists.forEach((obj, index) => {
- temp.push(obj)
- if (temp.length === 6 || index === (this.episode.lists.length - 1)) {
- const start = list.length ? (list.length * 6) + 1 : 1
- const end = (start - 1) + temp.length
- list.push({ title: `${start}集-${end}集`, lists: temp })
- temp = []
- }
- })
- }
- return list
- }
- },
- watch: {
- currentEpisode() {
- const index = this.episode.lists.findIndex(obj => {
- return obj.sort === this.currentEpisode.sort
- })
- console.log('-->data', index)
- }
- },
- methods: {
- handleSelectEpisode(index) {
- this.$emit('selectEpisode', index)
- this.footerShow = false
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .episode-part {
- .footer{
- position: fixed;
- width: 95vw;
- height: 76rpx;
- background: rgba(24, 28, 47, 0.8);
- // #ifdef MP-KUAISHOU
- bottom: 100rpx;
- // #endif
- // #ifdef MP-TOUTIAO | MP-WEIXIN
- bottom: 100rpx;
- // #endif
- left: 50%;
- transform: translateX(-50%);
- font-size: 26rpx;
- color: $info-color;
- border-radius: 20rpx;
- z-index: 999;
- transition: .3s;
- &.episode{
- bottom: 700rpx;
- margin-top: -4rpx;
- border-bottom-left-radius: 0;
- border-bottom-right-radius: 0;
- .episode-container{
- display: flex;
- margin-top: -4rpx;
- border-bottom-left-radius: 20px;
- border-bottom-right-radius: 20px;
- }
- .bar{
- .arrow{
- transform: rotate(180deg);
- }
- }
- }
- .bar{
- padding: 0 20rpx;
- .icon{
- background: url("/static/image/video.png") no-repeat center;
- background-size: 70%;
- width: 80rpx;
- height: 80rpx;
- }
- .name{
- text-align: left;
- flex: 1;
- padding: 0 30rpx;
- }
- .arrow{
- transition: .3s;
- }
- }
- .episode-container{
- display: none;
- background: inherit;
- min-height: 620rpx;
- .header-box{
- white-space: nowrap;
- margin: 20rpx 0;
- .header-item{
- margin-right: 20rpx;
- border-radius: 20rpx;
- display: inline-block;
- width: 200rpx;
- border: 1rpx solid $default-color;
- text-align: center;
- padding: 10rpx 0;
- color: $default-color;
- &.active{
- border-color: $primary-color;
- color: $primary-color;
- }
- }
- }
- .content{
- margin-top: 20rpx;
- .episode-item{
- position: relative;
- width: calc((100% - #{40rpx}) / 3);
- margin-right: 20rpx;
- margin-bottom: 20rpx;
- overflow: hidden;
- border-radius: 18rpx;
- &:nth-child(3n){
- margin-right: 0;
- }
- .playing{
- position: absolute;
- top: 0;
- left: 0;
- bottom: 0;
- right: 0;
- background: rgba(0,0,0,.5) url("/static/image/playing.png") no-repeat center;
- background-size: 40rpx;
- z-index: 2;
- }
- image{
- width: 100%;
- height: 260rpx;
- }
- text{
- position: absolute;
- left: 0;
- bottom: 0;
- right: 0;
- color: $default-color;
- padding: 20rpx 0;
- text-align: center;
- background: rgba(0,0,0,.3);
- z-index: 1;
- }
- .lock{
- position: absolute;
- top: 0;
- left: 0;
- bottom: 0;
- right: 0;
- background: rgba(0,0,0,.5);
- z-index: 2;
- }
- }
- }
- }
- }
- }
- </style>
|