bookDetail.vue 9.5 KB
<template>
  <div class="book-detail-page content-bg">
    <div class="modify-top"></div>
    <div class="book-detail">
      <div style="text-align: center;">
        <van-image width="220" height="220" :src="bookInfo.cover" />
      </div>
      <div class="book-intro">
        <p class="book-post">{{ bookInfo.name }}</p>
        <div id="book-intro" :class="{ 'van-multi-ellipsis--l3': isToggle }">{{ bookInfo.note }}</div>
        <div v-if="hasToggle">
          <div v-if="isToggle" @click="onToggle(false)" class="book-toggle-icon">展开&nbsp;
            <van-icon style="vertical-align: middle;" size="0.9rem" :name="icon_down" />
          </div>
          <div v-else @click="onToggle(true)" class="book-toggle-icon">折叠&nbsp;
            <van-icon style="vertical-align: middle;" size="0.9rem" :name="icon_up" />
          </div>
        </div>
      </div>

      <van-sticky>
        <div class="book-video-title">
          <van-row>
            <van-col span="12">
              作品演绎
              <div style="background-color: #F9D95C; width: 70px; height: 4px;"></div>
            </van-col>
            <van-col span="12">
              <div style="font-size: 1rem; color: #999999; text-align: right;">
                <van-icon :name="icon_video" />
                {{ bookInfo.total }}个作品
              </div>
            </van-col>
          </van-row>
        </div>
        <div class="book-video-language">
          <van-row>
            <van-col span="6">
              <div @click="toggleLanguage('mandarin')" :class="[checkMandarin ? 'checked' : 'uncheck']">普通话</div>
            </van-col>
            <van-col span="6">
              <div @click="toggleLanguage('localism')" :class="[checkLocalism ? 'checked' : 'uncheck']">方言</div>
            </van-col>
            <van-col span="12" v-if="checkLocalism" @click="showPicker = true">
              <div class="choose-wrapper">
                <div class="text">
                  &nbsp;{{ chooseLanguage.text }}
                </div>
                <div class="icon">
                  <van-icon name="arrow-down" />&nbsp;
                </div>
              </div>
            </van-col>
          </van-row>
          <van-popup v-model:show="showPicker" round position="bottom">
            <van-picker :columns="columns" :columns-field-names="{ text: 'text', value: 'val', children: 'children' }"
              @cancel="showPicker = false" @confirm="onConfirm" />
          </van-popup>
        </div>
      </van-sticky>

      <div class="book-video-list">
        <van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="onLoad">
          <template v-for="item in prod_list" :key="item" style="height: 3rem;">
            <video-card :item="item"></video-card>
          </template>
        </van-list>
      </div>
    </div>
    <div style="height: 5rem;"></div>
    <div class="book-bar">
      <div @click="onSubscribe" class="text">
        <van-icon v-if="!bookInfo.is_subscribe" :name="icon_subscribed" size="1.25rem" style="margin: 0 auto;" />
        <van-icon v-else :name="icon_unsubscribe" size="1.25rem" style="margin: 0 auto;" />
        <span style="font-size: 0.85rem;">订阅</span>
      </div>
      <div class="button">
        <my-button @on-click="payFor" type="plain">爱心捐书</my-button>
      </div>
      <div class="button">
        <my-button @on-click="uploadVideo" type="primary">上传作品</my-button>
      </div>
    </div>
    <shortcut-fixed type="C" :item="['home', 'me']"></shortcut-fixed>
  </div>

  <!-- 写评论时,如果没有实名认证提示弹框 -->
  <notice-overlay :show="showNotice" text="前往认证" @on-submit="onSubmit" @on-close="onClose">
    <div style="color: #333333;">
      <p>您还没有实名认证</p>
      <p>请前往个人中心进行实名认证</p>
    </div>
  </notice-overlay>
</template>

<script setup>
import { useVideoList } from '@/composables/useVideoList.js'

import MyButton from '@/components/MyButton/index.vue'
import VideoCard from '@/components/VideoCard/index.vue'
import NoticeOverlay from '@/components/NoticeOverlay/index.vue'

import icon_video from '@images/video.png'
import icon_up from '@images/icon-guanbi@2x.png'
import icon_down from '@images/icon-zhankai@2x.png'
import icon_subscribed from '@images/icon-dingyue01@2x.png'
import icon_unsubscribe from '@images/icon-dingyue02@2x.png'

import ShortcutFixed from '@/components/ShortcutFixed/index.vue'
import tools from '@/common/tool'
import { ref, reactive, onMounted, nextTick } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import axios from '@/utils/axios';
import $ from 'jquery'
import _ from 'lodash'
import { Toast } from 'vant';
const $route = useRoute();
const $router = useRouter();

const { toggleLanguage, onLoad, columns, prod_list, finished, loading, bookInfo, showPicker, checkLocalism, checkMandarin, onConfirm, chooseLanguage } = useVideoList($route);

const gotoMe = () => {
  console.warn('跳转我的地址');
}

// 判断是否显示简介的展开图标
const hasToggle = ref(false); // 判断是否有展开文字,默认没有
const isToggle = ref(true); // 判断展开状态,默认展开

const onToggle = (v) => { // 展开/折叠
  isToggle.value = v
}

onMounted(() => {
  // 判断是否显示简介的展开图标
  nextTick(() => {
    hasToggle.value = tools.hasEllipsis('book-intro');
  })
})

/**
 * 书籍订阅
 */
const onSubscribe = () => {
  axios.post('/srv/?a=add_subscribe', {
    book_id: $route.query.id
  })
  .then(res => {
    if (res.data.code === 1) {
      if (res.data.msg === 'add subscribe OK') {
        bookInfo.value.is_subscribe = true;
        Toast.success('订阅成功')
      } else {
        bookInfo.value.is_subscribe = false;
        Toast.success('取消订阅')
      }
    } else {
      console.warn(res);
      Toast({
        icon: 'close',
        message: res.data.msg
      });
    }
  })
  .catch(err => {
    console.error(err); 
  })
}

// 爱心捐书
const payFor = () => {
  console.warn('弹出框');
}

// 未实名认证提示
const showNotice = ref(false)
const onClose = () => { // 关闭提示框回调
  showNotice.value = false;
}
// 跳转个人中心
const onSubmit = () => {
  $router.push({
    path: '/me/index'
  });
}

/**
 * 上传作品回调
 */
const uploadVideo = () => {
  axios.get('/srv/?a=can_upload')
  .then(res => {
    if (res.data.code === 1) {
      if (res.data.data.can_upload) {
        // TODO: 上传视频直接跳转?不需要表示判断是上传哪个幼儿园吗?
        // 实名认证之后直接跳转上传页面
        location.href = 'https://jinshuju.net/f/NAGn1D';
      } else {
        // 如果没有实名认证需要提示用户实名认证
        showNotice.value = true;
      }
    } else {
      console.warn(res);
      Toast({
        icon: 'close',
        message: res.data.msg
      });
    }
  })
  .catch(err => {
    console.error(err); 
  })
}
</script>

<script>
import mixin from 'common/mixin';

export default {
  mixins: [mixin.init],
  data() {
    return {
    }
  },
  created() {
  },
  methods: {
  }
}
</script>

<style lang="less" scoped>
@import url('@css/content-bg.less');

.book-detail-page {
  // overflow: auto;

  .book-detail {
    margin: 1rem;
    // margin-top: 1.25rem;
    margin-top: 0;
    padding-top: 1rem;
    border-radius: 10px;
    background-color: rgba(255, 255, 255, 1);
    box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.13);

    .book-intro {
      padding: 1rem;

      .book-post {
        color: #222222;
        font-size: 1.25rem;
        font-weight: bold;
      }

      #book-intro {
        color: #333333;
        margin-top: 0.25rem;
      }

      .book-toggle-icon {
        text-align: right;
        color: #713610;
        font-size: 1rem;
      }
    }

    .book-video-title {
      background-color: #F7F7F7;
      padding: 1rem 1.5rem;
    }

    .book-video-language {
      padding: 1rem;
      background-color: white;

      .uncheck {
        background: #F7F7F7;
        border-radius: 15px;
        padding: 0.5rem;
        text-align: center;
        color: #222222;
        margin: 0 0.25rem;
      }

      .checked {
        background: #F9D95C;
        border-radius: 15px;
        padding: 0.5rem;
        text-align: center;
        color: #222222;
        margin: 0 0.25rem;
      }

      .choose-wrapper {
        background: #F7F7F7;
        border-radius: 15px;
        padding: 0.5rem;
        text-align: center;
        color: #B0B0B0;
        margin: 0 0.25rem;

        .text {
          display: inline-block;
          text-align: left;
          width: 80%;
        }

        .icon {
          display: inline-block;
          text-align: right;
          width: 20%;
        }
      }
    }
  }

  .book-bar {
    z-index: 999;
    position: fixed;
    right: 0;
    bottom: 0;
    left: 0;
    display: flex;
    align-items: center;
    box-sizing: content-box;
    background-color: white;
    padding: 1rem;

    .text {
      display: flex;
      flex-direction: column;
      justify-content: center;
      min-width: 3rem;
      color: #713610;
      text-align: center;
    }

    .button {
      display: flex;
      flex-direction: column;
      justify-content: center;
      flex: 1;
      padding: 0 0.5rem;
    }
  }
}

.wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  width: auto;
  text-align: center;
}

.block {
  width: 80%;
  // height: 25rem;
  background-color: #fff;
  border-radius: 10px;
  padding: 1rem;
  position: relative;
  margin-top: 1rem;
  margin-bottom: 5rem;
}
</style>