Authored by yyq

Merge branch 'master' of git.yoho.cn:fe/yoho-community-web

@@ -80,7 +80,7 @@ export default { @@ -80,7 +80,7 @@ export default {
80 favType: 0 80 favType: 0
81 }); 81 });
82 } 82 }
83 - }, 1000); 83 + }, 3000);
84 } else { 84 } else {
85 this.prompt && this.prompt.hide(); 85 this.prompt && this.prompt.hide();
86 this.$createToast({ 86 this.$createToast({
@@ -2,7 +2,11 @@ @@ -2,7 +2,11 @@
2 <Article 2 <Article
3 ref="article" 3 ref="article"
4 type="article" 4 type="article"
  5 + :thumb="true"
5 :on-fetch="onFetch"> 6 :on-fetch="onFetch">
  7 + <template v-slot:thumb>
  8 + <ArticleItem type="article" v-for="(item, index) in articleThumbList" :key="index" :data="item"></ArticleItem>
  9 + </template>
6 </Article> 10 </Article>
7 </template> 11 </template>
8 12
@@ -11,7 +15,7 @@ import {get} from 'lodash'; @@ -11,7 +15,7 @@ import {get} from 'lodash';
11 import Article from './components/article/article'; 15 import Article from './components/article/article';
12 import ArticleItem from './components/article/article-item'; 16 import ArticleItem from './components/article/article-item';
13 import {createNamespacedHelpers} from 'vuex'; 17 import {createNamespacedHelpers} from 'vuex';
14 -const {mapActions} = createNamespacedHelpers('article'); 18 +const {mapState, mapActions} = createNamespacedHelpers('article');
15 19
16 export default { 20 export default {
17 name: 'ArticlePage', 21 name: 'ArticlePage',
@@ -30,6 +34,21 @@ export default { @@ -30,6 +34,21 @@ export default {
30 this.init(); 34 this.init();
31 } 35 }
32 }, 36 },
  37 + async serverPrefetch() {
  38 + const articleId = parseInt(this.id, 10);
  39 +
  40 + if (!articleId) {
  41 + return;
  42 + }
  43 + return this.fetchArticleList({
  44 + articleId,
  45 + limit: 2,
  46 + thumb: true
  47 + });
  48 + },
  49 + computed: {
  50 + ...mapState(['articleThumbList'])
  51 + },
33 methods: { 52 methods: {
34 ...mapActions(['fetchArticleList', 'fetchArticleProductFavs']), 53 ...mapActions(['fetchArticleList', 'fetchArticleProductFavs']),
35 init() { 54 init() {
@@ -45,9 +64,6 @@ export default { @@ -45,9 +64,6 @@ export default {
45 const result = await this.fetchArticleList({ 64 const result = await this.fetchArticleList({
46 articleId, 65 articleId,
47 page: this.page, 66 page: this.page,
48 - authorUid: this.authorUid,  
49 - authorType: this.authorType,  
50 - type: this.type  
51 }); 67 });
52 68
53 if (result.code === 200) { 69 if (result.code === 200) {
@@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
12 <WidgetFollow :share="share" class="widget-follow" :author-uid="currentAuthor.authorUid" :follow="currentAuthor.hasAttention === 'Y'" @on-follow="follow => onFollow(currentAuthor, follow)"></WidgetFollow> 12 <WidgetFollow :share="share" class="widget-follow" :author-uid="currentAuthor.authorUid" :follow="currentAuthor.hasAttention === 'Y'" @on-follow="follow => onFollow(currentAuthor, follow)"></WidgetFollow>
13 </template> 13 </template>
14 </LayoutHeader> 14 </LayoutHeader>
15 - <LayoutRecycleList :size="30" ref="scroll" @scroll="onScroll" :offset="2000" :on-fetch="onFetch"> 15 + <LayoutRecycleList :size="30" ref="scroll" @scroll="onScroll" :offset="2000" :on-fetch="onScrollFetch">
16 <template class="article-item" v-slot:item="{ data }"> 16 <template class="article-item" v-slot:item="{ data }">
17 <ArticleItem 17 <ArticleItem
18 :id="`item${data.index}`" 18 :id="`item${data.index}`"
@@ -27,6 +27,9 @@ @@ -27,6 +27,9 @@
27 <div :id="`ph${data.index}`"></div> 27 <div :id="`ph${data.index}`"></div>
28 </template> 28 </template>
29 </LayoutRecycleList> 29 </LayoutRecycleList>
  30 + <div class="thumbs">
  31 + <slot name="thumb" v-if="showThumb"></slot>
  32 + </div>
30 </Layout> 33 </Layout>
31 <ArticleActionSheet v-if="showArticleDetailAction" ref="actionSheet"></ArticleActionSheet> 34 <ArticleActionSheet v-if="showArticleDetailAction" ref="actionSheet"></ArticleActionSheet>
32 <YohoActionSheet transfer v-if="showCommentAction" ref="commentAction" :full="true"> 35 <YohoActionSheet transfer v-if="showCommentAction" ref="commentAction" :full="true">
@@ -51,13 +54,20 @@ export default { @@ -51,13 +54,20 @@ export default {
51 }, 54 },
52 share: Boolean, 55 share: Boolean,
53 type: String, 56 type: String,
  57 + thumb: Boolean,
54 onFetch: Function 58 onFetch: Function
55 }, 59 },
56 mounted() { 60 mounted() {
57 this.scrollPreLazy = debounce(this.changeItem.bind(this), 200); 61 this.scrollPreLazy = debounce(this.changeItem.bind(this), 200);
58 }, 62 },
  63 + computed: {
  64 + showThumb() {
  65 + return !this.isMounted && this.thumb;
  66 + }
  67 + },
59 data() { 68 data() {
60 return { 69 return {
  70 + isMounted: false,
61 articleId: 0, 71 articleId: 0,
62 articleIndex: -1, 72 articleIndex: -1,
63 showCommentAction: false, 73 showCommentAction: false,
@@ -84,6 +94,14 @@ export default { @@ -84,6 +94,14 @@ export default {
84 }, 94 },
85 methods: { 95 methods: {
86 ...mapMutations(['CHANGE_ARTICLE_LIST_PRELAZY', 'ASYNC_ARTICLE_COMMENT']), 96 ...mapMutations(['CHANGE_ARTICLE_LIST_PRELAZY', 'ASYNC_ARTICLE_COMMENT']),
  97 + async onScrollFetch() {
  98 + const result = await this.onFetch();
  99 +
  100 + setTimeout(() => {
  101 + this.isMounted = true;
  102 + }, 0);
  103 + return result;
  104 + },
87 toUserPage() { 105 toUserPage() {
88 if (this.share) { 106 if (this.share) {
89 return this.$links.toDownloadApp(); 107 return this.$links.toDownloadApp();
@@ -177,6 +195,16 @@ export default { @@ -177,6 +195,16 @@ export default {
177 background-color: #f0f0f0; 195 background-color: #f0f0f0;
178 } 196 }
179 197
  198 +.thumbs {
  199 + bottom: 0;
  200 + position: absolute;
  201 + top: 0;
  202 + left: 0;
  203 + right: 0;
  204 + width: 100%;
  205 + height: 100%;
  206 +}
  207 +
180 .avatar-wrapper { 208 .avatar-wrapper {
181 display: flex; 209 display: flex;
182 justify-content: center; 210 justify-content: center;
@@ -3,7 +3,11 @@ @@ -3,7 +3,11 @@
3 ref="article" 3 ref="article"
4 :title="userName" 4 :title="userName"
5 type="userArticle" 5 type="userArticle"
  6 + :thumb="true"
6 :on-fetch="onFetch"> 7 :on-fetch="onFetch">
  8 + <template v-slot:thumb>
  9 + <ArticleItem type="userArticle" v-for="(item, index) in articleUserThumbList" :key="index" :data="item"></ArticleItem>
  10 + </template>
7 </Article> 11 </Article>
8 </template> 12 </template>
9 13
@@ -12,7 +16,7 @@ import {get} from 'lodash'; @@ -12,7 +16,7 @@ import {get} from 'lodash';
12 import Article from './components/article/article'; 16 import Article from './components/article/article';
13 import ArticleItem from './components/article/article-item'; 17 import ArticleItem from './components/article/article-item';
14 import {createNamespacedHelpers} from 'vuex'; 18 import {createNamespacedHelpers} from 'vuex';
15 -const {mapActions} = createNamespacedHelpers('article'); 19 +const {mapState, mapActions} = createNamespacedHelpers('article');
16 20
17 export default { 21 export default {
18 name: 'ArticlePage', 22 name: 'ArticlePage',
@@ -54,6 +58,24 @@ export default { @@ -54,6 +58,24 @@ export default {
54 } 58 }
55 next(); 59 next();
56 }, 60 },
  61 + async serverPrefetch() {
  62 + const articleId = parseInt(this.id, 10);
  63 +
  64 + if (!articleId) {
  65 + return;
  66 + }
  67 + return this.fetchArticleUserList({
  68 + articleId,
  69 + limit: 2,
  70 + thumb: true,
  71 + authorUid: this.authorUid,
  72 + authorType: this.authorType,
  73 + type: this.type
  74 + });
  75 + },
  76 + computed: {
  77 + ...mapState(['articleUserThumbList'])
  78 + },
57 methods: { 79 methods: {
58 ...mapActions(['fetchArticleUserList', 'fetchArticleProductFavs']), 80 ...mapActions(['fetchArticleUserList', 'fetchArticleProductFavs']),
59 init() { 81 init() {
@@ -4,7 +4,7 @@ import * as guangProcess from './guangProcess'; @@ -4,7 +4,7 @@ import * as guangProcess from './guangProcess';
4 import * as sleep from '../../utils/sleep'; 4 import * as sleep from '../../utils/sleep';
5 5
6 export default { 6 export default {
7 - async fetchArticleList({ commit }, { articleId, authorUid, authorType, limit = 5, page = 1 }) { 7 + async fetchArticleList({ commit }, { articleId, authorUid, authorType, limit = 5, page = 1, thumb = false}) {
8 commit(Types.FETCH_ARTICLE_LIST_REQUEST, {refresh: page === 1}); 8 commit(Types.FETCH_ARTICLE_LIST_REQUEST, {refresh: page === 1});
9 const result = await this.$api.get('/api/grass/columnArticleDetail', { 9 const result = await this.$api.get('/api/grass/columnArticleDetail', {
10 articleId, 10 articleId,
@@ -21,6 +21,7 @@ export default { @@ -21,6 +21,7 @@ export default {
21 } 21 }
22 commit(Types.FETCH_ARTICLE_LIST_SUCCESS, { 22 commit(Types.FETCH_ARTICLE_LIST_SUCCESS, {
23 data: result.data.detailList, 23 data: result.data.detailList,
  24 + thumb
24 }); 25 });
25 } else { 26 } else {
26 commit(Types.FETCH_ARTICLE_LIST_FAILD); 27 commit(Types.FETCH_ARTICLE_LIST_FAILD);
@@ -49,7 +50,7 @@ export default { @@ -49,7 +50,7 @@ export default {
49 } 50 }
50 return result; 51 return result;
51 }, 52 },
52 - async fetchArticleUserList({ commit }, { articleId, authorUid, authorType, type, limit = 5, page = 1 }) { 53 + async fetchArticleUserList({ commit }, { articleId, authorUid, authorType, type, limit = 5, page = 1, thumb = false }) {
53 commit(Types.FETCH_ARTICLE_LIST_USER_REQUEST, {refresh: page === 1}); 54 commit(Types.FETCH_ARTICLE_LIST_USER_REQUEST, {refresh: page === 1});
54 let api; 55 let api;
55 56
@@ -73,6 +74,7 @@ export default { @@ -73,6 +74,7 @@ export default {
73 } 74 }
74 commit(Types.FETCH_ARTICLE_LIST_USER_SUCCESS, { 75 commit(Types.FETCH_ARTICLE_LIST_USER_SUCCESS, {
75 data: result.data.detailList, 76 data: result.data.detailList,
  77 + thumb
76 }); 78 });
77 } else { 79 } else {
78 commit(Types.FETCH_ARTICLE_LIST_USER_FAILD); 80 commit(Types.FETCH_ARTICLE_LIST_USER_FAILD);
@@ -7,10 +7,12 @@ export default function() { @@ -7,10 +7,12 @@ export default function() {
7 state: { 7 state: {
8 fetchArticleList: false, 8 fetchArticleList: false,
9 articleList: [], 9 articleList: [],
  10 + articleThumbList: [],
10 fetchArticleListByTopic: false, 11 fetchArticleListByTopic: false,
11 articleListByTopic: [], 12 articleListByTopic: [],
12 fetchArticleUserList: false, 13 fetchArticleUserList: false,
13 articleUserList: [], 14 articleUserList: [],
  15 + articleUserThumbList: [],
14 articleDetail: null, 16 articleDetail: null,
15 articleLastedTimeByTopic: 0, 17 articleLastedTimeByTopic: 0,
16 articleStates: {} 18 articleStates: {}
@@ -3,13 +3,13 @@ import {getArticleImageSize} from 'utils/image-handler'; @@ -3,13 +3,13 @@ import {getArticleImageSize} from 'utils/image-handler';
3 import { get } from 'lodash'; 3 import { get } from 'lodash';
4 import Vue from 'vue'; 4 import Vue from 'vue';
5 5
6 -function articlefield(type) { 6 +function articlefield(type, thumb) {
7 if (type === 'article') { 7 if (type === 'article') {
8 - return 'articleList'; 8 + return `article${thumb ? 'Thumb' : ''}List`;
9 } else if (type === 'topic') { 9 } else if (type === 'topic') {
10 - return 'articleListByTopic'; 10 + return `article${thumb ? 'Thumb' : ''}ListByTopic`;
11 } else if (type === 'userArticle') { 11 } else if (type === 'userArticle') {
12 - return 'articleUserList'; 12 + return `articleUser${thumb ? 'Thumb' : ''}List`;
13 } 13 }
14 return ''; 14 return '';
15 } 15 }
@@ -25,7 +25,7 @@ function updateArticleState(state, item) { @@ -25,7 +25,7 @@ function updateArticleState(state, item) {
25 }); 25 });
26 } 26 }
27 27
28 -function setArticleList(state, data, type) { 28 +function setArticleList(state, data, type, thumb) {
29 data.forEach((item, index) => { 29 data.forEach((item, index) => {
30 get(item, 'productList', []).forEach(product => { 30 get(item, 'productList', []).forEach(product => {
31 product.favorite = false; 31 product.favorite = false;
@@ -34,11 +34,21 @@ function setArticleList(state, data, type) { @@ -34,11 +34,21 @@ function setArticleList(state, data, type) {
34 item.lazy = index >= 1; 34 item.lazy = index >= 1;
35 item.isExpand = false; 35 item.isExpand = false;
36 item.introHeight = 0; 36 item.introHeight = 0;
  37 + if (!thumb) {
37 updateArticleState(state, item); 38 updateArticleState(state, item);
  39 + } else {
  40 + item.comments = [];
  41 + item.hasAttention = 'N';
  42 + item.hasFavor = 'N';
  43 + item.hasPraise = 'N';
  44 + item.commentCount = 0;
  45 + item.favoriteCount = 0;
  46 + item.praiseCount = 0;
  47 + }
38 }); 48 });
39 - state[articlefield(type)] = state[articlefield(type)].concat(data); 49 + state[articlefield(type, thumb)] = state[articlefield(type, thumb)].concat(data);
40 50
41 - state[articlefield(type)].forEach((item, index) => { 51 + state[articlefield(type, thumb)].forEach((item, index) => {
42 const imageBlocks = get(item, 'blockList', []).filter(block => block.templateKey === 'image'); 52 const imageBlocks = get(item, 'blockList', []).filter(block => block.templateKey === 'image');
43 53
44 imageBlocks.forEach((img, inx) => { 54 imageBlocks.forEach((img, inx) => {
@@ -62,9 +72,9 @@ export default { @@ -62,9 +72,9 @@ export default {
62 state.articleList = []; 72 state.articleList = [];
63 } 73 }
64 }, 74 },
65 - [Types.FETCH_ARTICLE_LIST_SUCCESS](state, {data}) { 75 + [Types.FETCH_ARTICLE_LIST_SUCCESS](state, {data, thumb}) {
66 state.fetchArticleList = false; 76 state.fetchArticleList = false;
67 - setArticleList(state, data, 'article'); 77 + setArticleList(state, data, 'article', thumb);
68 }, 78 },
69 [Types.FETCH_ARTICLE_LIST_FAILD](state) { 79 [Types.FETCH_ARTICLE_LIST_FAILD](state) {
70 state.fetchArticleList = false; 80 state.fetchArticleList = false;
@@ -75,9 +85,9 @@ export default { @@ -75,9 +85,9 @@ export default {
75 state.articleUserList = []; 85 state.articleUserList = [];
76 } 86 }
77 }, 87 },
78 - [Types.FETCH_ARTICLE_LIST_USER_SUCCESS](state, {data}) { 88 + [Types.FETCH_ARTICLE_LIST_USER_SUCCESS](state, {data, thumb}) {
79 state.fetchArticleUserList = false; 89 state.fetchArticleUserList = false;
80 - setArticleList(state, data, 'userArticle'); 90 + setArticleList(state, data, 'userArticle', thumb);
81 }, 91 },
82 [Types.FETCH_ARTICLE_LIST_USER_FAILD](state) { 92 [Types.FETCH_ARTICLE_LIST_USER_FAILD](state) {
83 state.fetchArticleUserList = false; 93 state.fetchArticleUserList = false;
@@ -3867,16 +3867,6 @@ is-directory@^0.3.1: @@ -3867,16 +3867,6 @@ is-directory@^0.3.1:
3867 version "0.3.1" 3867 version "0.3.1"
3868 resolved "http://npm.yohops.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" 3868 resolved "http://npm.yohops.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1"
3869 3869
3870 -is-dom-node-list@^1.2.1:  
3871 - version "1.2.1"  
3872 - resolved "http://npm.yohops.com/is-dom-node-list/-/is-dom-node-list-1.2.1.tgz#141ded0c66de759d0976800d21370bb908f2950f"  
3873 - dependencies:  
3874 - is-dom-node "^1.0.4"  
3875 -  
3876 -is-dom-node@^1.0.4:  
3877 - version "1.0.4"  
3878 - resolved "http://npm.yohops.com/is-dom-node/-/is-dom-node-1.0.4.tgz#abb18af7133f1e687610cfeb274da1ced342f1c5"  
3879 -  
3880 is-extendable@^0.1.0, is-extendable@^0.1.1: 3870 is-extendable@^0.1.0, is-extendable@^0.1.1:
3881 version "0.1.1" 3871 version "0.1.1"
3882 resolved "http://npm.yohops.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" 3872 resolved "http://npm.yohops.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
@@ -4677,10 +4667,6 @@ minipass@^2.2.1, minipass@^2.3.4: @@ -4677,10 +4667,6 @@ minipass@^2.2.1, minipass@^2.3.4:
4677 safe-buffer "^5.1.2" 4667 safe-buffer "^5.1.2"
4678 yallist "^3.0.0" 4668 yallist "^3.0.0"
4679 4669
4680 -miniraf@1.0.0:  
4681 - version "1.0.0"  
4682 - resolved "http://npm.yohops.com/miniraf/-/miniraf-1.0.0.tgz#5d88e108bbdcb55b4a2ff3da337f24a13a3377e1"  
4683 -  
4684 minizlib@^1.1.1: 4670 minizlib@^1.1.1:
4685 version "1.2.1" 4671 version "1.2.1"
4686 resolved "http://npm.yohops.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" 4672 resolved "http://npm.yohops.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614"
@@ -6068,10 +6054,6 @@ remark@^10.0.1: @@ -6068,10 +6054,6 @@ remark@^10.0.1:
6068 remark-stringify "^6.0.0" 6054 remark-stringify "^6.0.0"
6069 unified "^7.0.0" 6055 unified "^7.0.0"
6070 6056
6071 -rematrix@0.3.0:  
6072 - version "0.3.0"  
6073 - resolved "http://npm.yohops.com/rematrix/-/rematrix-0.3.0.tgz#4f3f9156aa80ded8a8ca23785f48c6012b6dea4a"  
6074 -  
6075 remove-trailing-separator@^1.0.1: 6057 remove-trailing-separator@^1.0.1:
6076 version "1.1.0" 6058 version "1.1.0"
6077 resolved "http://npm.yohops.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" 6059 resolved "http://npm.yohops.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
@@ -6308,14 +6290,6 @@ schema-utils@^1.0.0: @@ -6308,14 +6290,6 @@ schema-utils@^1.0.0:
6308 ajv-errors "^1.0.0" 6290 ajv-errors "^1.0.0"
6309 ajv-keywords "^3.1.0" 6291 ajv-keywords "^3.1.0"
6310 6292
6311 -scrollreveal@^4.0.5:  
6312 - version "4.0.5"  
6313 - resolved "http://npm.yohops.com/scrollreveal/-/scrollreveal-4.0.5.tgz#cf83cc5d9874dc0d92ef9c89a8894e57f3f8e034"  
6314 - dependencies:  
6315 - miniraf "1.0.0"  
6316 - rematrix "0.3.0"  
6317 - tealight "0.3.6"  
6318 -  
6319 scss-tokenizer@^0.2.3: 6293 scss-tokenizer@^0.2.3:
6320 version "0.2.3" 6294 version "0.2.3"
6321 resolved "http://npm.yohops.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1" 6295 resolved "http://npm.yohops.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1"
@@ -7004,13 +6978,6 @@ tar@^4: @@ -7004,13 +6978,6 @@ tar@^4:
7004 safe-buffer "^5.1.2" 6978 safe-buffer "^5.1.2"
7005 yallist "^3.0.2" 6979 yallist "^3.0.2"
7006 6980
7007 -tealight@0.3.6:  
7008 - version "0.3.6"  
7009 - resolved "http://npm.yohops.com/tealight/-/tealight-0.3.6.tgz#14c8071ce3c188972a5cb7d8a5668ca2820b4292"  
7010 - dependencies:  
7011 - is-dom-node "^1.0.4"  
7012 - is-dom-node-list "^1.2.1"  
7013 -  
7014 term-size@^1.2.0: 6981 term-size@^1.2.0:
7015 version "1.2.0" 6982 version "1.2.0"
7016 resolved "http://npm.yohops.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" 6983 resolved "http://npm.yohops.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69"