index.vue 10.9 KB
<template>
<div class='container'>
<div class='nav-bar' :style="'height:'+navBarHeight+'px'" catchtouchmove>
  <div @tap="getNews('refresh')" :class='{fade:showFilter}'><img :style="'margin-top:'+statusBarHeight+'px;'" :class='{rotate:!hasLoad}' src='/static/imgs/refresh_arrow.png'></div>
  <div @tap='_showFilter' :class='{fade:showFilter}'><img :style="'margin-top:'+statusBarHeight+'px;'" src='/static/imgs/filter.png'></div>
</div>
<div class='nav-bar-blank' :style="'height:'+navBarHeight+'px;'"></div>
<div @tap='navigateToDetail(i)' v-for='(v,i) in news' :key='i' hover-class='hover' class='news-item'>
<div>
  <div class='title'><div v-if='v.is_Top' class='top'>置顶</div><div v-if='v.is_Top' class='blank'/>{{v.info_Title}}</div>
  <div class='time'><div class='tag'>{{v.info_Tag}}</div>&nbsp;&nbsp;&nbsp;浏览{{v.read_Count}}&nbsp;&nbsp;&nbsp;{{v.createDate}}</div>
</div>
<img :src="rootAvatar + v.title_Pic" mode='aspectFill' lazy-load>
</div>
<div v-if='news.length===0 && hasLoad' class='nodata'><img src='/static/images/empty.png'>暂无内容</div>
<div class='filter-bar' :style="'top:'+top+'px;'" catchtouchmove>
  <div class='tips'>选择该页面显示的新闻类型</div>
  <div class='types'>
    <div v-for='(v,i) in types' :key='i' @tap='changeSelect(i)' :class="hideArr[i] ? 'type-hide' : 'type-show'">{{v}}
      <div v-if='!hideArr[i]' class='selected'/>
      <img v-if='!hideArr[i]' src='data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNTU4NDM4MTQxOTgwIiBjbGFzcz0iaWNvbiIgc3R5bGU9IiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjE5MDM5IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIj48ZGVmcz48c3R5bGUgdHlwZT0idGV4dC9jc3MiPkBmb250LWZhY2UgeyBmb250LWZhbWlseTogcmJpY29uOyBzcmM6IHVybCgiY2hyb21lLWV4dGVuc2lvbjovL2RpcGlhZ2lpb2hmbGpjaWNlZ3BnZmZwYm5qbWdqY25mL2ZvbnRzL3JiaWNvbi53b2ZmMiIpIGZvcm1hdCgid29mZjIiKTsgZm9udC13ZWlnaHQ6IG5vcm1hbDsgZm9udC1zdHlsZTogbm9ybWFsOyB9Cjwvc3R5bGU+PC9kZWZzPjxwYXRoIGQ9Ik05NDIuNzMxNTggMjA1LjUwMTM3NGMtMTkuMjI0ODU0LTE5LjIyNTg3Ny01MC4zNjA5OTEtMTkuMjI1ODc3LTY5LjU4Nzg5MSAwTDM1NS40Mzg3NTcgNzIzLjc1MDcwNSAxNDYuODU4MjU0IDUxNC42ODUxNTVjLTE4Ljk4MzM1My0xOC45MjI5NzgtNDkuNjM1NDY3LTE4LjkyMjk3OC02OC41NTk0NjkgMC0xOC45ODQzNzcgMTguOTg0Mzc3LTE4Ljk4NDM3NyA0OS42OTY4NjYgMCA2OC41NTk0NjlsMjM2LjUxMjY2OCAyMzcuMTE4NDY2YzkuNjczMzEzIDkuNjczMzEzIDIyLjM3MDQ5NyAxNC4yNjc5NTggMzQuOTQ0ODgzIDE0LjAyNjQ1OCAxNi4yMDMwMyAzLjk4ODg0OCAzMy44NTYwODYgMC40ODQwMjQgNDYuNDkyODk0LTEyLjE1Mjc4NGw1NDYuNDgyMzQ5LTU0Ny4wMjY3NDhDOTYxLjk1NzQ1NyAyNTUuOTg1MTYyIDk2MS45NTc0NTcgMjI0Ljc4NzYyNiA5NDIuNzMxNTggMjA1LjUwMTM3NHoiIHAtaWQ9IjE5MDQwIiBmaWxsPSIjZmZmZmZmIj48L3BhdGg+PC9zdmc+'>
    </div>
  </div>
  <div class='btns'>
    <div @tap='cancel' hover-class='fade' style='color: #09BB07;' hover-start-time=0 hover-stay-time=50>取消</div>
    <div @tap='confirm' hover-class='fade' style='color: #E64340;' hover-start-time=0 hover-stay-time=50>确认</div>
  </div>
</div>
<div :hidden='!showFilter' class='black-mask' :style="'top:'+navBarHeight+'px;'" catchtouchmove></div>
</div>
</template>

<script>
let hideArrBeforeSelect = []
export default {
  data () {
    return {
      news: [],
      types:[],
      statusBarHeight: 20,
      navBarHeight: 44,
      top: -600,
      showFilter: false,
      hideArr: [],
      hasLoad: false
    }
  },
  methods: {
    getNews(e){
      if(e==='refresh' && this.showFilter) return
      this.hasLoad = false
      const _timestamp = new Date().getTime()
      const hideArr = this.hideArr
      const allTypeSelected = hideArr.indexOf(true) < 0
      let selectedTypes = []
      this.types.forEach((v,i) => {
        if(!hideArr[i]) selectedTypes.push(v)
      })
      if(hideArr[0]===false) selectedTypes = []
      wx.request({
        url: this.rootUrl + '/jpub/list',
        method: selectedTypes.length ? 'POST' : 'GET',
        header: {'content-type': 'application/x-www-form-urlencoded'},
        data: selectedTypes.length ? {tags: selectedTypes.join(',')} : undefined,
        success: res => {
          const news = res.data
          news.forEach(v => {
            const timeObj = this.service.correctTime(v.createDate,'all')
            v.timeFull = timeObj.full
            v.createDate = timeObj.semantic
          })
          console.log(res.data)
          this.news = news
          wx.setStorageSync('newsList',news)
          if(this.news.length){
            if(new Date().getTime() - _timestamp < 500){
              setTimeout(()=>{
                this.hasLoad = true
                if(e==='refresh')
                  wx.showToast({title:'已刷新'})
              },500)
            } else {
              this.hasLoad = true
              if(e==='refresh')
                wx.showToast({title:'已刷新'})
            }
          } else this.hasLoad = true
        }
      })
    },
    getTypes(){
      wx.request({
        url: this.rootUrl + '/jpub/tags',
        success: res => {
          const types = ['全部',...res.data.map(v=>v.info_Tag)]
          if(types.toString() !== this.types.toString()){
            const hideArr = new Array(types.length).fill(true)
            hideArr[0] = false
            this.hideArr = hideArr
          }
          this.types = types
        }
      })
    },
    navigateToDetail(i){
      wx.navigateTo({url:'../newsDetail/main?index='+i})
    },
    _showFilter(){
      if(!this.showFilter){
        this.top = this.navBarHeight
        hideArrBeforeSelect = this.hideArr.concat()
        setTimeout(() => {
          this.showFilter = true
        },100)
      }
    },
    changeSelect(i){
      // 多选
      // this.$set(this.hideArr,i,this.hideArr[i] ? false : true)

      //单选
      const hideArr = new Array(this.types.length).fill(true)
      hideArr[i] = false
      this.hideArr = hideArr
    },
    cancel(){
      this.top = -600
      setTimeout(() => {
        this.hideArr = hideArrBeforeSelect.concat()
        this.showFilter = false
      },100)
    },
    confirm(){
      this.top = -600
      this.getNews()
      setTimeout(() => {
        this.showFilter = false
      },100)

    },
    checkAuth(){
      return new Promise( resolve => {
        wx.getSetting({
          success(res) {
            resolve(res.authSetting['scope.userInfo'])
          }
        })
      })
    },
    getUnionId(){
      return new Promise(resolve => {
        this.service.getUnionId(this.rootAvatar,this.rootUrl).then( res => {
          if(res === 'unverified'){
            wx.setStorageSync('isVerify', false)
            wx.redirectTo({ url: '../verify/main' })
            resolve(false)
          }
          else resolve(true)
        })
      })
    },
  },
  onLoad(){
    this.getUnionId();

    wx.getSystemInfo({
      success: res => {
        this.statusBarHeight = res.statusBarHeight
        let mbbc;
        try{
          mbbc = wx.getMenuButtonBoundingClientRect()?wx.getMenuButtonBoundingClientRect():null;
          if(!mbbc){
            throw new Error('getMenuButtonBoundingClientRect error');
          }else{
            this.navBarHeight = mbbc.bottom + mbbc.top - res.statusBarHeight;
          }
        }catch (e) {
          this.navBarHeight = 44
          this.statusBarHeight = 20
        }
      },
      fail: (err) => {
        this.navBarHeight = 44
        this.statusBarHeight = 20
      }
    })
    
    this.checkAuth().then( res => {
      if(!res) wx.redirectTo({ url: '../welcome/main' })
    })
  },
  onShow(){
    this.getTypes()
    if(!wx.getStorageSync('isVerify'))
      this.getUnionId().then(res => {if(res) this.getNews()})
    else this.getNews()
  },
  onUnload(){
    this.hasLoad = false
  }
}
</script>

<style lang="stylus" scoped>
.container
  position absolute
  Height_Width(100%)
  background #EEE
  .nav-bar
    background themeColor
    Flex(flex,,center)
    position fixed
    z-index 99
    width 100%
    top 0
    left 0
    padding-left 15rpx
    div
      margin-top 15rpx
      &.fade
        opacity .7
    img
      Height_Width(45rpx)
      margin 15rpx
      &.rotate
        animation loading 1s steps(30) infinite
  .news-item
    padding 25rpx
    background white
    border-bottom 1rpx solid #dedede
    Flex(flex,space-between,center)
    >div
      align-self stretch
      width calc(100% - 225rpx)
      Flex(flex,space-between,,column)
      .title
        font-size 32rpx
        line-height 42rpx
        position relative
        overflow hidden
        text-overflow ellipsis
        display -webkit-box
        -webkit-line-clamp 2
        -webkit-box-orient vertical
        .top
          position absolute
          top 8rpx
          font-size 24rpx
          line-height 36rpx
          background-color #aa001a
          color #fff
          padding 0 10rpx
          border-radius 6rpx
        .blank
          Height_Width(40rpx,80rpx)
          display inline-block
      .time
        height 36rpx
        margin-top 25rpx
        Font(28rpx)
        Flex(flex,,center)
        color grey
        .tag
          color #aa001a
          font-size 26rpx
          line-height 40rpx
          padding 0 10rpx
          border-radius 6rpx
          border 1rpx solid #aa001a
    img
      Height_Width(150rpx,200rpx)
      border-radius 10rpx
      margin-left 25rpx
      background-color #eee
  .nodata
    position fixed
    height 100%
    width 100%
    display flex
    justify-content center
    align-items center
    flex-direction column
    font 35rpx/35rpx !specified
    background white
    color #555
    img
      height 200rpx
      width 200rpx
      margin-bottom 20rpx
  .black-mask
    position fixed
    left 0
    Height_Width(100%)
    background rgba(0,0,0,.5)
  .filter-bar
    position fixed
    width 100%
    left 0
    background #F2F2F2
    z-index 1
    transition top .1s ease
    .tips
      padding 20rpx 30rpx
      Font(32rpx)
      color #555
    .types
      display flex
      flex-wrap wrap
      padding 0 20rpx
      >div
        flex 1
        white-space nowrap
        Font(30rpx)
        margin 10rpx
        padding 15rpx 24rpx
        border-radius 5rpx
        text-align center
        position relative
        border 1rpx solid themeColor
        &.type-show
          background white
          border 1rpx solid white
          // color white
        &.type-hide
          background #E0E0E0
          border 1rpx solid #EEE
          color #777
        .selected
          position absolute
          bottom -1rpx
          right -1rpx
          Height_Width(0)
          border-width 0 0 28rpx 30rpx
          border-color orange transparent
          border-style solid
          Flex(flex,center,center)
        img
          position absolute
          bottom -1rpx
          right 0
          Height_Width(16rpx)
    .btns
      padding 10rpx 0
      Flex(flex,space-between,center)
      Font(32rpx,62rpx,bold)
      div
        padding 0 30rpx
</style>