Authored by 杨延青

Merge branch 'feature/detailHeader' into 'release/6.9.6'

Feature/detail header



See merge request !98
@@ -668,7 +668,9 @@ const yoho = { @@ -668,7 +668,9 @@ const yoho = {
668 if (this.isYohoBuy && window.yohoInterface) { 668 if (this.isYohoBuy && window.yohoInterface) {
669 window.yohoInterface.triggerEvent(success || nullFun, fail || nullFun, { 669 window.yohoInterface.triggerEvent(success || nullFun, fail || nullFun, {
670 method: 'go.showshareaction', 670 method: 'go.showshareaction',
671 - arguments: args 671 + arguments: Object.assign({
  672 + isHidePromotion: 1
  673 + }, args || {})
672 }); 674 });
673 } else { 675 } else {
674 // tip(tipInfo); 676 // tip(tipInfo);
1 <template> 1 <template>
2 <Layout class="article-detail"> 2 <Layout class="article-detail">
  3 + <ArticleDetailHeader ref="header" class="article-detail-header" :data="articleInfo" :step="headerAnimateStep" :title-step="headerTitleAnimateStep">
  4 + <div v-if="articleInfo.articleId && !articleInfo.empty" class="title-main">
  5 + <div class="title-info" :style="`transform: translate3d(0, ${viewMoreArticles ? '-50%' : '0'}, 0)`">
  6 + <ArticleItemHeader class="title-info-author" :share="share" :data="authorData" :more="false" @on-follow="onFollowAuthor"></ArticleItemHeader>
  7 + <div class="title-info-rec">{{listTitle}}</div>
  8 + </div>
  9 + </div>
  10 + </ArticleDetailHeader>
3 <RecycleScrollReveal :size="10" ref="scroll" :class="{'preview-page': previewPage}" @scroll="onScroll" :offset="2000" :on-fetch="onFetch" :manual-init="true"> 11 <RecycleScrollReveal :size="10" ref="scroll" :class="{'preview-page': previewPage}" @scroll="onScroll" :offset="2000" :on-fetch="onFetch" :manual-init="true">
4 <template v-slot:eternalTop> 12 <template v-slot:eternalTop>
5 <ArticleDeatilLong 13 <ArticleDeatilLong
@@ -24,7 +32,8 @@ @@ -24,7 +32,8 @@
24 :share="share" 32 :share="share"
25 :pos-id="posId" 33 :pos-id="posId"
26 @on-show-more="onShowMore" 34 @on-show-more="onShowMore"
27 - @on-follow="onFollowAuthor"> 35 + @on-follow="onFollowAuthor"
  36 + @on-praise="onPraise">
28 </ArticleDeatilNote> 37 </ArticleDeatilNote>
29 </template> 38 </template>
30 <template class="article-item" #item="{ data }"> 39 <template class="article-item" #item="{ data }">
@@ -43,6 +52,30 @@ @@ -43,6 +52,30 @@
43 </template> 52 </template>
44 </RecycleScrollReveal> 53 </RecycleScrollReveal>
45 54
  55 + <ArticleDetailFooter ref="footer" v-show="!articleInfo.thumb" class="detail-fixed-footer" :style="`transform: translate3d(0, ${viewMoreArticles ? '100%' : '0'}, 0)`" v-bind="footerData" @on-comment-click="onComment">
  56 + <template v-if="articleInfo.sort != 2" v-slot:before>
  57 + <div class="footer-comment">
  58 + <CommentPlaceholder
  59 + ref="commentInput"
  60 + :share="share"
  61 + class="comment-input hover-opacity"
  62 + :dest-id="articleInfo.articleId"
  63 + :add-type="0"
  64 + :article-id="articleInfo.articleId"
  65 + :pos-id="posId"
  66 + :column-type="1001"
  67 + :autoUpdate="false"
  68 + @on-comment="onCommentInput">
  69 + 添加评论...
  70 + </CommentPlaceholder>
  71 + </div>
  72 + </template>
  73 + <template v-slot:after>
  74 + <div v-if="articleProducts.length" class="article-goods">文中商品</div>
  75 + <div v-else></div>
  76 + </template>
  77 + </ArticleDetailFooter>
  78 +
46 <MoreActionSheet transfer ref="moreAction" @on-follow="onFollowAuthor" @on-delete="onDelete" @on-edit="onEdit"></MoreActionSheet> 79 <MoreActionSheet transfer ref="moreAction" @on-follow="onFollowAuthor" @on-delete="onDelete" @on-edit="onEdit"></MoreActionSheet>
47 </Layout> 80 </Layout>
48 </template> 81 </template>
@@ -51,11 +84,14 @@ @@ -51,11 +84,14 @@
51 import {get} from 'lodash'; 84 import {get} from 'lodash';
52 85
53 import YAS from 'utils/yas-constants'; 86 import YAS from 'utils/yas-constants';
  87 +import ArticleDetailHeader from './components/detail/article-header';
  88 +import ArticleItemHeader from './components/article/article-item-header';
54 import ArticleDeatilLong from './components/detail/article-long'; 89 import ArticleDeatilLong from './components/detail/article-long';
55 import ArticleDeatilNote from './components/detail/article-note'; 90 import ArticleDeatilNote from './components/detail/article-note';
56 import ArticleItem2 from './components/article/article-item2'; 91 import ArticleItem2 from './components/article/article-item2';
  92 +import ArticleDetailFooter from './components/detail/article-footer';
57 import MoreActionSheet from './components/detail/more-action-sheet'; 93 import MoreActionSheet from './components/detail/more-action-sheet';
58 -import {mapState as mapYohoState, createNamespacedHelpers} from 'vuex'; 94 +import {mapState as mapYohoState, mapMutations as mapYohoMutations, createNamespacedHelpers} from 'vuex';
59 const {mapState, mapActions, mapMutations} = createNamespacedHelpers('article'); 95 const {mapState, mapActions, mapMutations} = createNamespacedHelpers('article');
60 96
61 export default { 97 export default {
@@ -72,7 +108,8 @@ export default { @@ -72,7 +108,8 @@ export default {
72 listTitle: '', 108 listTitle: '',
73 colWidthForTwo: 370, 109 colWidthForTwo: 370,
74 posId: YAS.scene.newsDetail, 110 posId: YAS.scene.newsDetail,
75 - previewPage: false 111 + previewPage: false,
  112 + articleProducts: []
76 }; 113 };
77 }, 114 },
78 created() { 115 created() {
@@ -109,14 +146,94 @@ export default { @@ -109,14 +146,94 @@ export default {
109 }, 146 },
110 computed: { 147 computed: {
111 ...mapYohoState(['yoho']), 148 ...mapYohoState(['yoho']),
112 - ...mapState(['articleSingleDetail']), 149 + ...mapState(['articleSingleDetail', 'articleStates', 'authorStates']),
113 articleInfo() { 150 articleInfo() {
114 return this.articleSingleDetail[this.id || this.$route.params.id] || {}; 151 return this.articleSingleDetail[this.id || this.$route.params.id] || {};
115 - } 152 + },
  153 + articleState() {
  154 + const articleState = this.articleStates[this.articleInfo.articleId] || this.articleInfo;
  155 + const authorState = this.authorStates[`${this.articleInfo.authorUid}-${this.articleInfo.authorType}`] || this.articleInfo;
  156 +
  157 + return Object.assign({...articleState}, {hasAttention: authorState.hasAttention});
  158 + },
  159 + headerAnimateStep() {
  160 + if (this.articleInfo.sort !== 2 || this.scrollTop > this.coverHeight) {
  161 + return 100;
  162 + } else if (this.scrollTop > 0) {
  163 + let coverHeight = get(this.$refs, 'detailLong.coverHeight', 0);
  164 + let step = Math.round((this.scrollTop - 10) / (coverHeight - 90) * 100);
  165 +
  166 + step = Math.max(Math.min(step, 100), 0);
  167 + this.SET_STATUS_BAR_COLOR({
  168 + color: step > 55 ? 'black' : 'white'
  169 + });
  170 +
  171 + return step;
  172 + } else {
  173 + this.SET_STATUS_BAR_COLOR({
  174 + color: 'white'
  175 + });
  176 + return 0;
  177 + }
  178 + },
  179 + headerTitleAnimateStep() {
  180 + if (this.articleInfo.sort === 2) {
  181 + let {height, top} = get(this.$refs, 'detailLong.authorBlock', {});;
  182 + let scrollTop = this.scrollTop + get(this.$refs, 'header.$el.offsetHeight', 0);
  183 +
  184 + if (top && height) {
  185 + if (scrollTop >= top + height) {
  186 + return 100;
  187 + } else if (scrollTop > top) {
  188 + let step = Math.round((scrollTop - top) / height * 100);
  189 +
  190 + return Math.max(Math.min(step, 100), 0);
  191 + }
  192 + }
  193 +
  194 + return 0;
  195 + } else {
  196 + return 100;
  197 + }
  198 + },
  199 + viewMoreArticles() {
  200 + let scrollTop = this.scrollTop;
  201 +
  202 + if (this.$refs && this.$refs.header) {
  203 + scrollTop += this.$refs.header.$el.offsetHeight;
  204 +
  205 + return scrollTop > get(this.$refs, `${this.articleInfo.sort === 2 ? 'detailLong' : 'detailNote'}.$el.offsetHeight`);
  206 + } else {
  207 + return false;
  208 + }
  209 + },
  210 + authorData() {
  211 + return {
  212 + authorName: this.articleInfo.authorName,
  213 + authorUid: this.articleInfo.authorUid,
  214 + authorType: this.articleInfo.authorType,
  215 + authorHeadIco: this.articleInfo.authorHeadIco,
  216 + authGroupId: this.articleInfo.authGroupId,
  217 + hasAttention: this.articleState.hasAttention,
  218 + isAuthor: this.articleInfo.isAuthor
  219 + };
  220 + },
  221 + footerData() {
  222 + return {
  223 + favoriteCount: this.articleState.favoriteCount,
  224 + praiseCount: this.articleState.praiseCount,
  225 + commentCount: this.articleState.commentCount,
  226 + hasFavor: this.articleState.hasFavor,
  227 + hasPraise: this.articleState.hasPraise,
  228 + articleId: this.articleInfo.articleId,
  229 + share: this.share
  230 + };
  231 + },
116 }, 232 },
117 methods: { 233 methods: {
118 ...mapActions(['fetchArticleList', 'fetchDetailRecommendAricles']), 234 ...mapActions(['fetchArticleList', 'fetchDetailRecommendAricles']),
119 ...mapMutations(['CHANGE_AUTHOR_FOLLOW']), 235 ...mapMutations(['CHANGE_AUTHOR_FOLLOW']),
  236 + ...mapYohoMutations(['SET_STATUS_BAR_COLOR']),
120 init() { 237 init() {
121 this.recommendArticles = {}; 238 this.recommendArticles = {};
122 this.fetching = true; 239 this.fetching = true;
@@ -125,7 +242,7 @@ export default { @@ -125,7 +242,7 @@ export default {
125 pageVisibileEvent() { 242 pageVisibileEvent() {
126 if (this.articleOnEdit) { 243 if (this.articleOnEdit) {
127 this.articleOnEdit = false; 244 this.articleOnEdit = false;
128 - this.syncServiceArticleDetail(); 245 + this.syncServiceArticleDetail(true);
129 } 246 }
130 }, 247 },
131 loadPreData(articleId) { 248 loadPreData(articleId) {
@@ -147,7 +264,7 @@ export default { @@ -147,7 +264,7 @@ export default {
147 this.scrolling = false; 264 this.scrolling = false;
148 }, 200); 265 }, 200);
149 }, 266 },
150 - syncServiceArticleDetail() { 267 + syncServiceArticleDetail(withoutList) {
151 const articleId = parseInt(this.id, 10); 268 const articleId = parseInt(this.id, 10);
152 269
153 return this.fetchArticleList({ 270 return this.fetchArticleList({
@@ -155,7 +272,7 @@ export default { @@ -155,7 +272,7 @@ export default {
155 fromPlatform: this.previewPage ? 'Y' : 'N', 272 fromPlatform: this.previewPage ? 'Y' : 'N',
156 singleDetail: 'Y' 273 singleDetail: 'Y'
157 }).then((res) => { 274 }).then((res) => {
158 - if (this.$refs.scroll) { 275 + if (this.$refs.scroll && !withoutList) {
159 this.listTitle = ''; 276 this.listTitle = '';
160 this.fetching = false; 277 this.fetching = false;
161 this.$refs.scroll.init(); 278 this.$refs.scroll.init();
@@ -228,6 +345,23 @@ export default { @@ -228,6 +345,23 @@ export default {
228 onEdit() { 345 onEdit() {
229 this.articleOnEdit = true; 346 this.articleOnEdit = true;
230 }, 347 },
  348 + onPraise() {
  349 + this.$refs.footer.onPraise();
  350 + },
  351 + onComment() {
  352 + if (this.articleInfo.sort === 2) {
  353 + this.$refs.detailLong.onComment();
  354 + } else if (this.articleState.commentCount) {
  355 + this.$refs.detailNote.toCommentList();
  356 + } else {
  357 + this.$refs.commentInput.$el.click();
  358 + }
  359 + },
  360 + onCommentInput(comment) {
  361 + if (get(this.$refs, 'detailNote.onComment')) {
  362 + this.$refs.detailNote.onComment(comment);
  363 + }
  364 + },
231 reportArticleShow(items) { 365 reportArticleShow(items) {
232 if (!items || !items.length) { 366 if (!items || !items.length) {
233 return; 367 return;
@@ -305,10 +439,13 @@ export default { @@ -305,10 +439,13 @@ export default {
305 } 439 }
306 }, 440 },
307 components: { 441 components: {
  442 + ArticleDetailHeader,
  443 + ArticleItemHeader,
308 ArticleDeatilLong, 444 ArticleDeatilLong,
309 ArticleDeatilNote, 445 ArticleDeatilNote,
310 ArticleItem2, 446 ArticleItem2,
311 - MoreActionSheet 447 + MoreActionSheet,
  448 + ArticleDetailFooter
312 } 449 }
313 }; 450 };
314 </script> 451 </script>
@@ -356,4 +493,75 @@ export default { @@ -356,4 +493,75 @@ export default {
356 } 493 }
357 } 494 }
358 495
  496 +.title-main {
  497 + height: 100%;
  498 + color: #444;
  499 + overflow: hidden;
  500 +
  501 + .title-info {
  502 + height: 200%;
  503 + transition: all 200ms;
  504 +
  505 + > * {
  506 + height: 50%;
  507 + background: none;
  508 + }
  509 +
  510 + .title-info-rec {
  511 + font-size: 32px;
  512 + line-height: 1.2;
  513 + display: flex;
  514 + justify-content: center;
  515 + align-items: center;
  516 + }
  517 + }
  518 +
  519 + /deep/ .avatar {
  520 + padding-left: 0;
  521 + }
  522 +
  523 + /deep/ .opts {
  524 + padding-right: 10px;
  525 + }
  526 +}
  527 +
  528 +.detail-fixed-footer {
  529 + width: 100%;
  530 + position: absolute!important;
  531 + bottom: 0;
  532 + z-index: 10;
  533 + transition: all 300ms;
  534 +
  535 + .footer-comment {
  536 + width: 312px;
  537 + margin-left: 30px;
  538 + display: flex;
  539 + justify-content: center;
  540 + align-items: center;
  541 +
  542 + .comment-input {
  543 + width: 100%;
  544 + height: 68px;
  545 + line-height: 68px;
  546 + font-size: 28px;
  547 + color: #b0b0b0;
  548 + background: #f0f0f0;
  549 + padding: 0 20px;
  550 + border-radius: 35px;
  551 + box-sizing: border-box;
  552 +
  553 + }
  554 + }
  555 +
  556 + .article-goods {
  557 + width: 200px;
  558 + color: white;
  559 + font-size: 32px;
  560 + line-height: 100px;
  561 + font-weight: 300;
  562 + background-color: #d0021b;
  563 + text-align: center;
  564 + }
  565 +}
  566 +
359 </style> 567 </style>
1 <template> 1 <template>
2 - <div class="fixed-header" :style="headerStyle">  
3 - <LayoutHeader ref="header" theme="transparent"> 2 + <div class="fixed-header">
  3 + <LayoutHeader ref="header" theme="transparent" :style="headerStyle">
4 <template> 4 <template>
5 <div ref="titleBlock" class="title-block" :style="`transform: translate3d(0, ${blockTranslateY}, 0)`"> 5 <div ref="titleBlock" class="title-block" :style="`transform: translate3d(0, ${blockTranslateY}, 0)`">
6 <slot></slot> 6 <slot></slot>
@@ -91,7 +91,7 @@ export default { @@ -91,7 +91,7 @@ export default {
91 91
92 <style scoped> 92 <style scoped>
93 .fixed-header { 93 .fixed-header {
94 - position: fixed; 94 + position: absolute;
95 width: 100%; 95 width: 100%;
96 z-index: 10; 96 z-index: 10;
97 transition: all 100ms; 97 transition: all 100ms;
1 <template> 1 <template>
2 <div class="article-detail-long"> 2 <div class="article-detail-long">
3 - <ArticleDetailHeader ref="header" class="article-detail-header" :data="data" :step="headerAnimateStep" :title-step="headerTitleAnimateStep">  
4 - <div v-if="data.articleId && !data.empty" class="title-main">  
5 - <div class="title-info" :style="`transform: translate3d(0, ${viewMoreArticles ? '-50%' : '0'}, 0)`">  
6 - <ArticleItemHeader class="title-info-author" :share="share" :data="authorData" :lazy="lazy" :more="showMoreOpt" @on-follow="onFollowAuthor"></ArticleItemHeader>  
7 - <div class="title-info-rec">{{listTitle}}</div>  
8 - </div>  
9 - </div>  
10 - </ArticleDetailHeader>  
11 <div class="header-cover"></div> 3 <div class="header-cover"></div>
12 <ArticleItemSlideImage ref="coverFigure" class="cover-figure" :data="coverImage" :thumb-size="coverSize" :style="`transform: translate3d(0, ${coverTranslateY}px, 0)`"> 4 <ArticleItemSlideImage ref="coverFigure" class="cover-figure" :data="coverImage" :thumb-size="coverSize" :style="`transform: translate3d(0, ${coverTranslateY}px, 0)`">
13 </ArticleItemSlideImage> 5 </ArticleItemSlideImage>
@@ -29,12 +21,6 @@ @@ -29,12 +21,6 @@
29 21
30 <LayoutTitle v-if="listTitle" class="rec-article-title">{{listTitle}}</LayoutTitle> 22 <LayoutTitle v-if="listTitle" class="rec-article-title">{{listTitle}}</LayoutTitle>
31 </div> 23 </div>
32 - <ArticleDetailFooter v-show="!data.thumb" class="detail-fixed-footer" :style="`transform: translate3d(0, ${viewMoreArticles ? '100%' : '0'}, 0)`" v-bind="footerData" @on-comment-click="onComment">  
33 - <template v-slot:after>  
34 - <div v-if="articleProducts.length" class="article-goods">文中商品</div>  
35 - <div v-else></div>  
36 - </template>  
37 - </ArticleDetailFooter>  
38 24
39 <YohoActionSheet transfer v-if="showCommentAction" ref="commentAction" :full="true"> 25 <YohoActionSheet transfer v-if="showCommentAction" ref="commentAction" :full="true">
40 <Comment ref="comment" 26 <Comment ref="comment"
@@ -84,7 +70,6 @@ export default { @@ -84,7 +70,6 @@ export default {
84 recomendProduct: [], 70 recomendProduct: [],
85 showCommentAction: false, 71 showCommentAction: false,
86 showCommentActioning: false, 72 showCommentActioning: false,
87 - articleProducts: []  
88 }; 73 };
89 }, 74 },
90 mounted() { 75 mounted() {
@@ -137,55 +122,6 @@ export default { @@ -137,55 +122,6 @@ export default {
137 return 0; 122 return 0;
138 } 123 }
139 }, 124 },
140 - headerAnimateStep() {  
141 - if (this.scrollTop > this.coverHeight) {  
142 - return 100;  
143 - } else if (this.scrollTop > 0) {  
144 - let step = Math.round((this.scrollTop - 10) / (this.coverHeight - 90) * 100);  
145 -  
146 - step = Math.max(Math.min(step, 100), 0);  
147 - this.SET_STATUS_BAR_COLOR({  
148 - color: step > 55 ? 'black' : 'white'  
149 - });  
150 -  
151 - return step;  
152 - } else {  
153 - this.SET_STATUS_BAR_COLOR({  
154 - color: 'white'  
155 - });  
156 - return 0;  
157 - }  
158 - },  
159 - headerTitleAnimateStep() {  
160 - let {height, top} = this.authorBlock;  
161 - let scrollTop = this.scrollTop;  
162 -  
163 - if (this.$refs && this.$refs.header) {  
164 - scrollTop += this.$refs.header.$el.offsetHeight;  
165 - }  
166 -  
167 - if (top && height) {  
168 - if (scrollTop >= top + height) {  
169 - return 100;  
170 - } else if (scrollTop > top) {  
171 - let step = Math.round((scrollTop - top) / height * 100);  
172 -  
173 - return Math.max(Math.min(step, 100), 0);  
174 - }  
175 - }  
176 -  
177 - return 0;  
178 - },  
179 - viewMoreArticles() {  
180 - let scrollTop = this.scrollTop;  
181 -  
182 - if (this.$refs && this.$refs.header) {  
183 - scrollTop += this.$refs.header.$el.offsetHeight;  
184 - return scrollTop > this.$el.offsetHeight;  
185 - } else {  
186 - return false;  
187 - }  
188 - },  
189 authorData() { 125 authorData() {
190 return { 126 return {
191 authorName: this.data.authorName, 127 authorName: this.data.authorName,
@@ -197,17 +133,6 @@ export default { @@ -197,17 +133,6 @@ export default {
197 isAuthor: this.data.isAuthor 133 isAuthor: this.data.isAuthor
198 }; 134 };
199 }, 135 },
200 - footerData() {  
201 - return {  
202 - favoriteCount: this.articleState.favoriteCount,  
203 - praiseCount: this.articleState.praiseCount,  
204 - commentCount: this.articleState.commentCount,  
205 - hasFavor: this.articleState.hasFavor,  
206 - hasPraise: this.articleState.hasPraise,  
207 - articleId: this.data.articleId,  
208 - share: this.share  
209 - };  
210 - },  
211 lazy() { 136 lazy() {
212 return this.data.lazy; 137 return this.data.lazy;
213 } 138 }
@@ -271,38 +196,6 @@ export default { @@ -271,38 +196,6 @@ export default {
271 opacity: 1!important; 196 opacity: 1!important;
272 } 197 }
273 198
274 -.title-main {  
275 - height: 100%;  
276 - color: #444;  
277 - overflow: hidden;  
278 -  
279 - .title-info {  
280 - height: 200%;  
281 - transition: all 200ms;  
282 -  
283 - > * {  
284 - height: 50%;  
285 - background: none;  
286 - }  
287 -  
288 - .title-info-rec {  
289 - font-size: 32px;  
290 - line-height: 1.2;  
291 - display: flex;  
292 - justify-content: center;  
293 - align-items: center;  
294 - }  
295 - }  
296 -  
297 - /deep/ .avatar {  
298 - padding-left: 0;  
299 - }  
300 -  
301 - /deep/ .opts {  
302 - padding-right: 10px;  
303 - }  
304 -}  
305 -  
306 .cover-img { 199 .cover-img {
307 width: 100%; 200 width: 100%;
308 display: block; 201 display: block;
@@ -411,22 +304,4 @@ export default { @@ -411,22 +304,4 @@ export default {
411 .rec-article-title { 304 .rec-article-title {
412 margin-top: -6px; 305 margin-top: -6px;
413 } 306 }
414 -  
415 -.article-detail-long .detail-fixed-footer {  
416 - width: 100%;  
417 - position: fixed;  
418 - bottom: 0;  
419 - z-index: 10;  
420 - transition: all 300ms;  
421 -  
422 - .article-goods {  
423 - width: 200px;  
424 - color: white;  
425 - font-size: 32px;  
426 - line-height: 100px;  
427 - font-weight: 300;  
428 - background-color: #d0021b;  
429 - text-align: center;  
430 - }  
431 -}  
432 </style> 307 </style>
1 <template> 1 <template>
2 <div class="article-detail-notes"> 2 <div class="article-detail-notes">
3 - <ArticleDetailHeader ref="header" class="article-detail-header" :data="data" :step="100" :title-step="100">  
4 - <div v-if="data.articleId && !data.empty" class="title-main">  
5 - <div class="title-info" :style="`transform: translate3d(0, ${viewMoreArticles ? '-50%' : '0'}, 0)`">  
6 - <ArticleItemHeader class="title-info-author" :share="share" :data="authorData" :lazy="lazy" :more="false" @on-follow="onFollowAuthor"></ArticleItemHeader>  
7 - <div class="title-info-rec">{{listTitle}}</div>  
8 - </div>  
9 - </div>  
10 - </ArticleDetailHeader>  
11 -  
12 <ArticleItemHeader v-if="share" :share="share" :data="authorData" :lazy="lazy" :more="false" @on-follow="onFollowAuthor"></ArticleItemHeader> 3 <ArticleItemHeader v-if="share" :share="share" :data="authorData" :lazy="lazy" :more="false" @on-follow="onFollowAuthor"></ArticleItemHeader>
13 - <LayoutHeader v-else style="visibility: hidden;"></LayoutHeader> 4 + <LayoutHeader v-else ref="header" style="visibility: hidden;"></LayoutHeader>
14 5
15 <div v-if="data.empty" class="article-empty"> 6 <div v-if="data.empty" class="article-empty">
16 {{data.emptyTip || '文章不存在或文章被删除'}} 7 {{data.emptyTip || '文章不存在或文章被删除'}}
@@ -34,39 +25,15 @@ @@ -34,39 +25,15 @@
34 <div v-if="listTitle" class="rec-article-title"> 25 <div v-if="listTitle" class="rec-article-title">
35 <LayoutTitle>{{listTitle}}</LayoutTitle> 26 <LayoutTitle>{{listTitle}}</LayoutTitle>
36 </div> 27 </div>
37 - <ArticleDetailFooter v-show="!data.thumb" 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">  
38 - <template v-slot:before>  
39 - <div class="footer-comment">  
40 - <CommentPlaceholder  
41 - ref="commentInput"  
42 - :share="share"  
43 - class="comment-input hover-opacity"  
44 - :dest-id="data.articleId"  
45 - :add-type="0"  
46 - :article-id="data.articleId"  
47 - :pos-id="posId"  
48 - :column-type="1001"  
49 - :autoUpdate="false"  
50 - @on-comment="onComment">  
51 - 添加评论...  
52 - </CommentPlaceholder>  
53 - </div>  
54 - </template>  
55 - <template v-slot:after>  
56 - <div></div>  
57 - </template>  
58 - </ArticleDetailFooter>  
59 </div> 28 </div>
60 </template> 29 </template>
61 30
62 <script> 31 <script>
63 import {get} from 'lodash'; 32 import {get} from 'lodash';
64 -import ArticleDetailHeader from './article-header';  
65 import ArticleDetailCommentList from './comment-list'; 33 import ArticleDetailCommentList from './comment-list';
66 import ArticleItemHeader from '../article/article-item-header'; 34 import ArticleItemHeader from '../article/article-item-header';
67 import ArticleItemSlide from '../article/article-item-slide'; 35 import ArticleItemSlide from '../article/article-item-slide';
68 import ArticleItemTopics from '../article/article-item-topics'; 36 import ArticleItemTopics from '../article/article-item-topics';
69 -import ArticleDetailFooter from './article-footer';  
70 import ArticleDetailIntro from './article-intro'; 37 import ArticleDetailIntro from './article-intro';
71 import dayjs from 'utils/day'; 38 import dayjs from 'utils/day';
72 import {createNamespacedHelpers} from 'vuex'; 39 import {createNamespacedHelpers} from 'vuex';
@@ -107,16 +74,6 @@ export default { @@ -107,16 +74,6 @@ export default {
107 thumb() { 74 thumb() {
108 return !!this.data.thumb; 75 return !!this.data.thumb;
109 }, 76 },
110 - viewMoreArticles() {  
111 - let scrollTop = this.scrollTop;  
112 -  
113 - if (this.$refs && this.$refs.header) {  
114 - scrollTop += this.$refs.header.$el.offsetHeight;  
115 - return scrollTop > this.$el.offsetHeight;  
116 - } else {  
117 - return false;  
118 - }  
119 - },  
120 authorData() { 77 authorData() {
121 return { 78 return {
122 authorName: this.data.authorName, 79 authorName: this.data.authorName,
@@ -151,17 +108,6 @@ export default { @@ -151,17 +108,6 @@ export default {
151 articleType: this.data.articleType 108 articleType: this.data.articleType
152 }; 109 };
153 }, 110 },
154 - footerData() {  
155 - return {  
156 - favoriteCount: this.articleState.favoriteCount,  
157 - praiseCount: this.articleState.praiseCount,  
158 - commentCount: this.articleState.commentCount,  
159 - hasFavor: this.articleState.hasFavor,  
160 - hasPraise: this.articleState.hasPraise,  
161 - articleId: this.data.articleId,  
162 - share: this.share  
163 - };  
164 - },  
165 publishTime() { 111 publishTime() {
166 return this.data.publishTime ? dayjs(this.data.publishTime).fromNow() : ''; 112 return this.data.publishTime ? dayjs(this.data.publishTime).fromNow() : '';
167 }, 113 },
@@ -174,7 +120,7 @@ export default { @@ -174,7 +120,7 @@ export default {
174 this.$emit('on-follow', this.data, follow); 120 this.$emit('on-follow', this.data, follow);
175 }, 121 },
176 onPraise() { 122 onPraise() {
177 - this.$refs.footer.onPraise(); 123 + this.$emit('on-praise');
178 }, 124 },
179 onChangeSlide({index}) { 125 onChangeSlide({index}) {
180 this.slideIndex = index; 126 this.slideIndex = index;
@@ -183,12 +129,8 @@ export default { @@ -183,12 +129,8 @@ export default {
183 this.$refs.commentList && this.$refs.commentList.addComment(comment); 129 this.$refs.commentList && this.$refs.commentList.addComment(comment);
184 }, 130 },
185 toCommentList() { 131 toCommentList() {
186 - if (this.articleState.commentCount) {  
187 - if (this.$refs.commentList && this.scrollTo) {  
188 - this.scrollTo({scrollTop: this.$refs.commentList.$el.offsetTop - this.$refs.header.$el.offsetHeight});  
189 - }  
190 - } else {  
191 - this.$refs.commentInput.$el.click(); 132 + if (this.$refs.commentList && this.scrollTo) {
  133 + this.scrollTo({scrollTop: this.$refs.commentList.$el.offsetTop - get(this.$refs, 'header.$el.offsetHeight', 0)});
192 } 134 }
193 }, 135 },
194 onMore() { 136 onMore() {
@@ -196,50 +138,16 @@ export default { @@ -196,50 +138,16 @@ export default {
196 } 138 }
197 }, 139 },
198 components: { 140 components: {
199 - ArticleDetailHeader,  
200 ArticleItemHeader, 141 ArticleItemHeader,
201 ArticleItemSlide, 142 ArticleItemSlide,
202 ArticleItemTopics, 143 ArticleItemTopics,
203 ArticleDetailIntro, 144 ArticleDetailIntro,
204 ArticleDetailCommentList, 145 ArticleDetailCommentList,
205 - ArticleDetailFooter  
206 } 146 }
207 }; 147 };
208 </script> 148 </script>
209 149
210 <style lang="scss" scoped> 150 <style lang="scss" scoped>
211 -.title-main {  
212 - height: 100%;  
213 - color: #444;  
214 - overflow: hidden;  
215 -  
216 - .title-info {  
217 - height: 200%;  
218 - transition: all 200ms;  
219 -  
220 - > * {  
221 - height: 50%;  
222 - background: none;  
223 - }  
224 -  
225 - .title-info-rec {  
226 - font-size: 32px;  
227 - line-height: 1.2;  
228 - display: flex;  
229 - justify-content: center;  
230 - align-items: center;  
231 - }  
232 - }  
233 -  
234 - /deep/ .avatar {  
235 - padding-left: 0;  
236 - }  
237 -  
238 - /deep/ .opts {  
239 - padding-right: 10px;  
240 - }  
241 -}  
242 -  
243 .article-empty { 151 .article-empty {
244 height: 900px; 152 height: 900px;
245 color: #ccc; 153 color: #ccc;
@@ -273,33 +181,4 @@ export default { @@ -273,33 +181,4 @@ export default {
273 padding: 14px 0 4px; 181 padding: 14px 0 4px;
274 border-top: 1px solid #f0f0f0; 182 border-top: 1px solid #f0f0f0;
275 } 183 }
276 -  
277 -.article-detail-notes .detail-fixed-footer {  
278 - width: 100%;  
279 - position: fixed;  
280 - bottom: 0;  
281 - z-index: 10;  
282 - transition: all 300ms;  
283 -  
284 - .footer-comment {  
285 - width: 312px;  
286 - margin-left: 30px;  
287 - display: flex;  
288 - justify-content: center;  
289 - align-items: center;  
290 -  
291 - .comment-input {  
292 - width: 100%;  
293 - height: 68px;  
294 - line-height: 68px;  
295 - font-size: 28px;  
296 - color: #b0b0b0;  
297 - background: #f0f0f0;  
298 - padding: 0 20px;  
299 - border-radius: 35px;  
300 - box-sizing: border-box;  
301 -  
302 - }  
303 - }  
304 -}  
305 </style> 184 </style>
@@ -24,6 +24,7 @@ function processArticleListData(listData) { @@ -24,6 +24,7 @@ function processArticleListData(listData) {
24 templateKey: 'text', 24 templateKey: 'text',
25 } 25 }
26 ], 26 ],
  27 + hasComment: true,
27 commentCount: 0, 28 commentCount: 0,
28 comments: [], 29 comments: [],
29 dataType: listData.dataType, 30 dataType: listData.dataType,
1 { 1 {
2 "name": "yoho-community-web", 2 "name": "yoho-community-web",
3 - "version": "6.9.5-18", 3 + "version": "6.9.5-beta5",
4 "private": true, 4 "private": true,
5 "description": "A New Yohobuy Project With Express", 5 "description": "A New Yohobuy Project With Express",
6 "repository": { 6 "repository": {