mobileNewsRead.vue 8 KB
<template>
  <van-popup
    ref="mobileNewsRead"
    v-model="newsReadVisible"
    class="news-read-detail"
    get-container="body"
    position="left"
    style="width: 100vw; height: 100vh"
    :close-on-click-overlay="false"
    :overlay="true"
    @click-overlay="closeDialog"
  >
    <van-sticky>
      <van-nav-bar left-arrow @click-left="closeDialog">
        <slot slot="title" name="title">
          {{ $t('hp.news.detailDialogTitle') }}
        </slot>
      </van-nav-bar>
    </van-sticky>
    <div class="container">
      <div class="news-header">
        <div class="news-header__title">
          <h4>{{ newsDetail.title }}</h4>
          <h5 v-if="newsDetail.titleDescription">
            {{ newsDetail.titleDescription }}
          </h5>
        </div>
        <div class="news-header__info">
          <span v-if="newsDetail.drafter">
            {{ $t('hp.news.drafter') }}:{{ newsDetail.drafter }}
          </span>
          <span v-if="newsDetail.createTime">
            {{ newsDetail.createTime | dateTimeFormat }}
          </span>
          <!-- <span v-if="newsDetail.endTime">
            {{ $t('hp.news.endTime') }}:{{
              newsDetail.endTime | dateTimeFormat
            }}
          </span> -->
        </div>
      </div>
      <div class="news-content">
        <div v-if="newsDetail.isUrl === 'true'">
          <iframe
            ref="iframe"
            frameborder="0"
            :src="newsDetail.url"
            :height="newsDetail.pageHeight + 'px'"
            style="width: 100%; height: 560px"
          ></iframe>
        </div>
        <div v-else v-html="newsDetail.content"></div>
      </div>
      <div v-if="fileJson.length > 0" class="fjAll">
        <div class="fjStyle">
          <span>附件</span>
          <el-button type="text" style="font-size: 15px" @click="downloadAll">
            全部下载
            <i class="downloadAllImg icon-download"></i>
          </el-button>
        </div>
        <div
          v-for="(item, index) in fileJson"
          :key="'new-file-' + index"
          class="fileJsonItem"
        >
          <div style="position: relative">
            <div class="leftConten">
              <i class="iconFiles icon-tupian4"></i>
              <div class="middle">
                <div class="downName">{{ item.name }}</div>
                <div class="downSize">{{ item.sizeChange }}</div>
              </div>
            </div>
            <i class="iconDown icon-download" @click="download(item)"></i>
          </div>
        </div>
      </div>
    </div>
  </van-popup>
</template>

<script>
  const { saveAs } = require('file-saver')
  export default {
    name: 'MobileNewsRead',
    filters: {
      dateTimeFormat(val) {
        const moment = require('moment')
        return val ? moment(val).format('YYYY-MM-DD HH:mm:ss') : ''
      },
    },
    props: {
      newsItem: {
        type: Object,
        default: () => {},
      },
    },
    data() {
      return {
        newsDetail: {},
        newsReadVisible: false,
        fileJson: [],
      }
    },
    watch: {
      newsItem: {
        handler(val) {
          this.newsDetail = {}
          this.newsReadVisible && val && this.getNewsDetail(val)
        },
        immediate: true,
        deep: true,
      },
    },
    methods: {
      handlePreview(file) {
        window.open(
          this.$requestConfig.filePreview(file.response && file.response.fileId)
        )
      },
      closeDialog() {
        this.newsReadVisible = false
        this.$emit('refresh')
      },
      setFile(fileJson) {
        let files = JSON.parse(fileJson)
        files.forEach((item) => {
          if (item.size) {
            item.sizeChange = this.sizeFilter(item.size)
          }
        })

        let result = files.map((item) => {
          return {
            ...item,
            fileId: item.id,
            response: {
              fileId: item.id,
              fileName: item.name,
            },
          }
        })
        this.fileJson = result
      },
      showDialog() {
        this.newsReadVisible = true
      },
      getNewsDetail(item) {
        this.fileJson.length = 0
        let param = {
          id: item.id,
          read: item.reader == 0 ? true : '',
        }
        this.$requestConfig.getNewsOrPictureDetailById(param).then((data) => {
          this.newsDetail = data ? data : {}
          if (this.newsDetail.file) {
            this.setFile(this.newsDetail.file)
          }
        })
      },
      download(file) {
        if (this.$requestConfig.download) {
          this.$requestConfig
            .download(file.response.fileId)
            .then(({ data, headers }) => {
              if (data && headers) {
                // 附件下载
                const fileName = decodeURIComponent(
                  headers['content-disposition']
                    .split(';')[1]
                    .split('filename=')[1]
                )
                const blob = new Blob([data])
                saveAs(blob, fileName)
              }
            })
            .catch((err) => {
              this.$message.error(
                `${this.$t('hp.meetingRoom.downloadFail')}:${err}`
              )
            })
        }
      },
      //全部下载
      async downloadAll() {
        if (this.fileJson.length > 0) {
          for (const item of this.fileJson) {
            await {
              then: this.download(item),
            }
          }
        }
      },
      //字节转化
      sizeFilter($bytesize) {
        let $i = 0
        // 当$bytesize 大于是1024字节时,开始循环,当循环到第4次时跳出;
        while (Math.abs($bytesize) >= 1024) {
          $bytesize = $bytesize / 1024
          $i++
          if ($i === 4) break
        }
        // 将Bytes,KB,MB,GB,TB定义成一维数组;
        const $units = ['Bytes', 'KB', 'MB', 'GB', 'TB']
        const $newsize = Math.round($bytesize, 2)
        return $newsize + ' ' + $units[$i]
      },
    },
  }
</script>

<style lang="scss" scoped>
  $base-font-size-small: 12px;
  $base-border-color: #dcdfe6;
  .container {
    height: calc(#{$vh} - 46px);
    overflow: auto;
    .news-header {
      padding: 0 0 16px;
      border-bottom: 1px solid $base-border-color;
      margin: 0 16px 16px;
      .news-header__title {
        h4,
        h5 {
          text-align: center;
          margin: 15px 0;
          font-size: 16px;
        }
      }
      .news-header__info {
        display: flex;
        justify-content: space-between;
        span {
          color: #8c8c8c;
          font-size: $base-font-size-small;
        }
      }
    }
  }
  .news-content {
    font-size: 14px;
    color: #666;
    margin: 0 16px 16px;
  }
  .fjAll {
    border-top: 13px solid rgb(245, 245, 245);
    padding: 0 16px 16px;
    .iconDown {
      position: absolute;
      right: 0;
      top: 10px;
      font-size: 22px;
      font-weight: 600;
      color: #409eff;
    }
    .downSize {
      position: absolute;
      bottom: 2px;
      color: #999999;
      font-size: 12px;
    }
    .downName {
      text-overflow: ellipsis;
      white-space: nowrap;
      overflow: hidden;
      width: 100%;
    }
    .middle {
      height: 42px;
      position: relative;
      font-size: 14px;
      margin-left: 8px;
      width: calc(100% - 32px);
    }
    .iconFiles {
      font-size: 40px;
      color: #409eff;
    }

    .leftConten {
      display: flex;
      width: calc(100% - 15px);
    }
  }
  .fjStyle {
    display: flex;
    justify-content: space-between;
    align-items: center;
    height: 48px;
    line-height: 48px;
    span {
      font-size: 15px;
    }
    svg {
      vertical-align: bottom;
    }
  }
  .downloadAllImg {
    font-size: 22px;
    font-weight: 600;
    vertical-align: middle;
  }
  .fileJsonItem {
    height: 42px;
    padding: 15px 0;
    border-top: 1px solid #e6e6e6;
  }
  ::v-deep {
    .van-nav-bar__left {
      padding-left: 10px;
    }
    .van-icon {
      color: #262626;
      font-size: 22px;
    }
  }
  ::v-deep .van-nav-bar__title {
    font-weight: 800;
    font-size: 17px;
  }
</style>