article.vue 9.69 KB
<template>
  <div>
    <Layout class="article">
      <LayoutHeader v-if="!noHeader" theme="white" slot='header' :title="title">
        <template v-if="showHeader">
          <div class="avatar-wrapper" @click="toUserPage">
            <WidgetAvatar class="widget-avatar" :src="currentAuthor.authorHeadIco" :width="70" :height="70"></WidgetAvatar>
            <span class="user-name">{{currentAuthor.authorName}}</span>
          </div>
        </template>
        <template v-if="showHeader" v-slot:opts>
          <WidgetFollow :share="share" class="widget-follow" :class="headerFollowClass" :author-uid="currentAuthor.authorUid" :follow="currentAuthor.hasAttention === 'Y'" @on-follow="follow => onFollow(currentAuthor, follow)" :pos-id="posId"></WidgetFollow>
          <i class="iconfont icon-more1" @click="onShowMore(currentAuthor)"></i>
        </template>
      </LayoutHeader>
      <LayoutRecycleList :size="10" :thumbs="thumbs" ref="scroll" @scroll="onScroll" :offset="2000" :on-fetch="onFetch"
      @on-inited="onInited">
        <template class="article-item" #item="{ data }">
          <ArticleItem
            :type="type"
            :index="data.index"
            :data="data.data"
            :share="share"
            :article-id="data.data.articleId"
            :user-head-ico="userHeadIco"
            :pos-id="posId"
            @on-follow="follow => onFollow(data.data, follow)"
            @on-resize="onResize"
            @on-unlock-height="onUnlockHeight"
            @on-show-guang="onShowGuang"
            @on-show-comment="onShowComment"
            @on-show-more="onShowMore">
              <template v-if="data.data.dataType == 2">
                <ArticleResource :data="data.data"></ArticleResource>
              </template>
            </ArticleItem>
        </template>
      </LayoutRecycleList>
    </Layout>
    <ArticleActionSheet v-if="showArticleDetailAction" ref="actionSheet"></ArticleActionSheet>
    <YohoActionSheet transfer v-if="showCommentAction" ref="commentAction" :full="true">
      <Comment ref="comment"
        :destId="articleId"
        :popup="true"
        :article-id="articleId"
        :comment-id="commentId"
        :commentCount="onShowCommentCount"
        :pos-id="posId"
        @on-close="onClose"
        @on-comment="onActionComment"></Comment>
    </YohoActionSheet>
    <MoreActionSheet transfer ref="moreAction" @on-follow="onFollow" @on-delete="onDelete"></MoreActionSheet>
  </div>
</template>

<script>
import {throttle} from 'lodash';
import YAS from 'utils/yas-constants';
import ArticleItem from './article-item';
import ArticleActionSheet from '../detail/article-action-sheet';
import ArticleResource from './article-resource-item';
import MoreActionSheet from '../detail/more-action-sheet';
import {mapState, createNamespacedHelpers} from 'vuex';
const {mapMutations} = createNamespacedHelpers('article');

export default {
  name: 'Article',
  props: {
    title: {
      type: String,
      default: '逛'
    },
    share: Boolean,
    type: String,
    onFetch: Function,
    noHeader: Boolean,
    thumbs: {
      type: Array,
      default() {
        return [];
      }
    },
    posId: Number,
    userUid: Number
  },
  mounted() {
    if (this.$cookie && this.$cookie.get) {
      this.userHeadIco = this.$cookie.get('_head_ico');
    }
    this.scrollEvent = throttle(this.onDounceScroll.bind(this), 100);
    this.reportShow = this.startReportShow();
  },
  data() {
    return {
      articleId: 0,
      commentId: 0,
      articleIndex: -1,
      onShowCommentCount: 0,
      showCommentAction: false,
      showCommentActioning: false,
      showArticleDetailAction: false,
      showMoreAction: true,
      inx: 0,
      scrollTop: 0,
      showHeader: false,
      userHeadIco: '',
      currentId: 0,
      currentAuthor: {
        authorUid: 0,
        authorName: '',
        authorHeadIco: '',
        hasAttention: 'N',
        isAuthor: 'N',
        isShare: false,
        authorType: 1
      },
    };
  },
  activated() {
    if (this.scrollTop > 0) {
      this.$refs.scroll.$el.scrollTop = this.scrollTop;
    }
  },
  computed: {
    ...mapState(['yoho']),
    headerFollowClass() {
      return {
        invisible: (this.currentAuthor.isAuthor === 'Y' || this.currentAuthor.hasAttention === 'Y')
      }
    }
  },
  methods: {
    ...mapMutations(['ASYNC_ARTICLE_COMMENT', 'CHANGE_AUTHOR_FOLLOW']),
    toUserPage() {
      if (this.share) {
        return this.$links.toDownloadApp();
      }

      this.$router.push({
        name: 'author',
        params: {
          type: this.currentAuthor.authorType,
          id: this.currentAuthor.authorUid
        }
      });

      this.reportClickAvatar();
    },
    onShowComment({articleId, index, commentCount, commentId}) {
      this.articleId = articleId;
      this.commentId = commentId || 0;
      this.articleIndex = index;
      this.onShowCommentCount = commentCount || 0;
      this.showCommentAction = true;
      this.$nextTick(() => {
        if (this.showCommentActioning) {
          return;
        }
        this.showCommentActioning = true;
        this.$refs.comment.init();
        this.$refs.commentAction.show();
        setTimeout(() => {
          this.showCommentActioning = false;
        }, 300);
      });
    },
    onShowMore({article, index}) {
      this.$refs.moreAction.show(article, this.userUid, index);
    },
    onDelete(index) {
      this.$refs.scroll.delete(index);
    },
    onPageReady({success}) {
      if (success && this.showCommentAction) {
        this.$refs.commentAction.show();
        setTimeout(() => {
          this.showCommentActioning = false;
        }, 300);
      } else {
        this.showCommentActioning = false;
      }
    },
    onUnlockHeight(params) {
      this.$refs.scroll.unlockHight(params);
    },
    onClose() {
      this.$refs.commentAction.hide();
    },
    onActionComment() {
      this.ASYNC_ARTICLE_COMMENT({articleId: this.articleId, type: this.type});
      this.onResize(this.articleIndex);
    },
    onScroll(params) {
      this.scrollEvent(params);
    },
    onDounceScroll({item, scrollTop, startIndex}) {
      this.scrollTop = scrollTop;

      // 产品要求去掉头部交互
      return;

      // user 详情页禁止头部交互
      if (this.type === 'userArticle') {
        return;
      }

      if (scrollTop <= 0) {
        this.showHeader = false;
      } else if (item) {
        if (item.data && item.data.dataType === 2) {
          return this.showHeader = false;
        }

        if (this.currentId !== item.data.articleId) {
          this.currentId = item.data.articleId;
        }

        this.currentAuthor.authorUid = item.data.authorUid;
        this.currentAuthor.authorName = item.data.authorName;
        this.currentAuthor.authorHeadIco = item.data.authorHeadIco;
        this.currentAuthor.hasAttention = item.data.hasAttention;
        this.currentAuthor.authorType = item.data.authorType;
        this.currentAuthor.isAuthor = item.data.isAuthor;
        this.currentAuthor.article = item.data;
        this.currentAuthor.index = item.index;

        this.showHeader = true;

        this.reportShow(startIndex, item);
      }
    },
    init() {
      this.$refs.scroll.$el.scrollTop = 0;
      this.$refs.scroll.init();
    },
    onInited(item) {
      if (item) {
        this.reportShow(0, item);
      }
    },
    onFollow(data, follow) {
      if (data.authorUid === this.currentAuthor.authorUid) {
        this.currentAuthor.hasAttention = follow ? 'Y' : 'N';
      }
      this.CHANGE_AUTHOR_FOLLOW({authorUid: data.authorUid, follow, type: this.type});
    },
    onResize(index) {
      this.$nextTick(() => {
        this.$refs.scroll.resize(index);
      });
    },
    onShowGuang(params) {
      this.showArticleDetailAction = true;
      this.$nextTick(() => {
        this.$refs.actionSheet.show(params);
      });
    },
    reportClickAvatar() {
      this.$store.dispatch('reportYas', {
        params: {
          appop: YAS.eventName.avatar,
          param: {
            AUTH_ID: this.currentAuthor.authorUid,
            POS_ID: this.posId
          }
        }
      });
    },
    startReportShow() {
      let preview = null;
      let name = this.$yoho.isiOS ? 'iFP_ArticleList' : 'aFP_ArticleList';

      return (index, item) => {
        if (preview === item.data.articleId) {
          return;
        }

        preview = item.data.articleId;

        this.$store.dispatch('reportYas', {
          params: {
            appop: YAS.eventName.show,
            param: {
              DATA: [{
                P_NAME: name,
                P_PARAM: preview,
                I_INDEX: index,
                ARTICLE_ID: preview,
                POS_ID: this.posId
              }, ...(item.data.productList || []).map(p => {
                return {
                  P_NAME: name,
                  P_PARAM: preview,
                  I_INDEX: index,
                  PRD_SKN: p.productSkn,
                  POS_ID: this.posId
                };
              })],
            }
          }
        });
      };
    }
  },
  components: {
    ArticleItem,
    ArticleActionSheet,
    MoreActionSheet,
    ArticleResource
  }
};
</script>

<style lang="scss" scoped>
.article {
  background-color: #f0f0f0;
}

.thumbs {
  bottom: 0;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  width: 100%;
  height: 100%;
  overflow-y: auto;
}

.avatar-wrapper {
  display: flex;
  justify-content: center;
  align-items: center;
}

.widget-avatar {
  width: 52px;
  height: 52px;
}

.widget-follow {
  margin-right: 10px;
}

.user-name {
  margin-left: 10px;
  font-size: 24px;
  line-height: 1.2;
  color: #000;
  max-width: 250px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.icon-more1 {
  font-size: 40px!important;
  margin-right: 6px;
}
</style>