<template> <div class="article-detail-notes"> <ArticleDetailHeader ref="header" class="article-detail-header" :data="data" :step="100" :title-step="100"> <div v-if="data.articleId && !data.empty" class="title-main"> <div class="title-info" :style="`transform: translate3d(0, ${viewMoreArticles ? '-50%' : '0'}, 0)`"> <ArticleItemHeader class="title-info-author" :share="share" :data="authorData" :lazy="lazy" :more="false" @on-follow="onFollowAuthor"></ArticleItemHeader> <div class="title-info-rec">{{listTitle}}</div> </div> </div> </ArticleDetailHeader> <ArticleItemHeader v-if="share" :share="share" :data="authorData" :lazy="lazy" :more="false" @on-follow="onFollowAuthor"></ArticleItemHeader> <LayoutHeader v-else style="visibility: hidden;"></LayoutHeader> <div v-if="data.empty" class="article-empty"> {{data.emptyTip || '文章不存在或文章被删除'}} </div> <div v-else class="article-context"> <ArticleItemSlide :thumb="thumb" :share="share" :data="slideData" :slide-index="slideIndex" :lazy="lazy" @on-praise="onPraise" @change="onChangeSlide"></ArticleItemSlide> <ProductGroup :article-id="data.articleId" :pos-id="0" :index="0" :thumb="thumb" v-if="productListData.length" :share="share" :data="productListData" :lazy="lazy"></ProductGroup> <ArticleDetailIntro :data="introData"></ArticleDetailIntro> <ArticleItemTopics :data="topicsData" :share="share"></ArticleItemTopics> <div class="publish-time"> <span>{{publishTime}}</span> <div v-if="data.articleId && !share" class="more-wrap"> <i class="iconfont icon-more1" @click="onMore"></i> </div> </div> <ArticleDetailCommentList ref="commentList" v-if="data.articleId && !thumb" :article-id="data.articleId" :share="share" :comment-count="articleState.commentCount"></ArticleDetailCommentList> </div> <div v-if="listTitle" class="rec-article-title"> <LayoutTitle>{{listTitle}}</LayoutTitle> </div> <ArticleDetailFooter ref="footer" class="detail-fixed-footer" :class="{'disable': data.empty}" :style="`transform: translate3d(0, ${viewMoreArticles ? '100%' : '0'}, 0)`" v-bind="footerData" @on-comment-click="toCommentList"> <template v-slot:before> <div class="footer-comment"> <CommentPlaceholder ref="commentInput" :share="share" class="comment-input hover-opacity" :dest-id="data.articleId" :add-type="0" :article-id="data.articleId" :pos-id="posId" :column-type="1001" :autoUpdate="false" @on-comment="onComment"> 添加评论... </CommentPlaceholder> </div> </template> <template v-slot:after> <div></div> </template> </ArticleDetailFooter> </div> </template> <script> import {get} from 'lodash'; import ArticleDetailHeader from './article-header'; import ArticleDetailCommentList from './comment-list'; import ArticleItemHeader from '../article/article-item-header'; import ArticleItemSlide from '../article/article-item-slide'; import ArticleItemTopics from '../article/article-item-topics'; import ArticleDetailFooter from './article-footer'; import ArticleDetailIntro from './article-intro'; import dayjs from 'utils/day'; import {createNamespacedHelpers} from 'vuex'; const {mapState} = createNamespacedHelpers('article'); export default { name: 'ArticleDetailNote', props: { data: { type: Object, default() { return {}; } }, listTitle: String, scrollTop: Number, scrollTo: Function, share: Boolean, posId: Number, }, data() { return { slideIndex: 1, commentList: [], commentPage: 1, commentFetching: false, showCommentMore: false }; }, computed: { ...mapState(['articleStates', 'authorStates']), articleState() { const articleState = this.articleStates[this.data.articleId] || this.data; const authorState = this.authorStates[`${this.data.authorUid}-${this.data.authorType}`] || this.data; return Object.assign({...articleState}, {hasAttention: authorState.hasAttention}); }, thumb() { return !!this.data.thumb; }, viewMoreArticles() { let scrollTop = this.scrollTop; if (this.$refs && this.$refs.header) { scrollTop += this.$refs.header.$el.offsetHeight; return scrollTop > this.$el.offsetHeight; } else { return false; } }, authorData() { return { authorName: this.data.authorName, authorUid: this.data.authorUid, authorType: this.data.authorType, authorHeadIco: this.data.authorHeadIco, authGroupId: this.data.authGroupId, hasAttention: this.articleState.hasAttention, isAuthor: this.data.isAuthor }; }, slideData() { return { blockList: get(this.data, 'blockList', []).filter(block => block.templateKey === 'image'), articleId: this.data.articleId, }; }, productListData() { return this.data.productList || []; }, introData() { let blockList = get(this.data, 'blockList', []); return { intro: get(blockList.filter(block => block.templateKey === 'text'), '[0].contentData', ''), maxLines: 10 }; }, topicsData() { return { topicList: this.data.topicList, articleType: this.data.articleType }; }, footerData() { return { favoriteCount: this.articleState.favoriteCount, praiseCount: this.articleState.praiseCount, commentCount: this.articleState.commentCount, hasFavor: this.articleState.hasFavor, hasPraise: this.articleState.hasPraise, articleId: this.data.articleId, share: this.share }; }, publishTime() { return this.data.publishTime ? dayjs(this.data.publishTime).fromNow() : ''; }, lazy() { return this.data.lazy; } }, methods: { onFollowAuthor(follow) { this.$emit('on-follow', this.data, follow); }, onPraise() { this.$refs.footer.onPraise(); }, onChangeSlide({index}) { this.slideIndex = index; }, onComment({comment}) { this.$refs.commentList && this.$refs.commentList.addComment(comment); }, toCommentList() { if (this.articleState.commentCount) { if (this.$refs.commentList && this.scrollTo) { this.scrollTo({scrollTop: this.$refs.commentList.$el.offsetTop - this.$refs.header.$el.offsetHeight}); } } else { this.$refs.commentInput.$el.click(); } }, onMore() { this.$emit('on-show-more'); } }, components: { ArticleDetailHeader, ArticleItemHeader, ArticleItemSlide, ArticleItemTopics, ArticleDetailIntro, ArticleDetailCommentList, ArticleDetailFooter } }; </script> <style lang="scss" scoped> .title-main { height: 100%; color: #444; overflow: hidden; .title-info { height: 200%; transition: all 200ms; > * { height: 50%; background: none; } .title-info-rec { font-size: 32px; line-height: 1.2; display: flex; justify-content: center; align-items: center; } } /deep/ .avatar { padding-left: 0; } /deep/ .opts { padding-right: 10px; } } .article-empty { height: 900px; color: #ccc; font-size: 28px; background-color: #f0f0f0; display: flex; justify-content: center; align-items: center; } .publish-time { font-size: 24px; color: #b0b0b0; padding: 20px 30px; display: flex; align-items: center; justify-content: space-between; .more-wrap { display: flex; align-items: center; color: #444; .iconfont { font-size: 44px; } } } .rec-article-title { padding: 14px 0 4px; border-top: 1px solid #f0f0f0; } .article-detail-notes .detail-fixed-footer { width: 100%; position: fixed; bottom: 0; z-index: 10; transition: all 300ms; .footer-comment { width: 312px; margin-left: 30px; display: flex; justify-content: center; align-items: center; .comment-input { width: 100%; height: 68px; line-height: 68px; font-size: 28px; color: #b0b0b0; background: #f0f0f0; padding: 0 20px; border-radius: 35px; box-sizing: border-box; } } } </style>