Authored by TaoHuang

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

@@ -612,18 +612,6 @@ const yoho = { @@ -612,18 +612,6 @@ const yoho = {
612 } else { 612 } else {
613 // tip(tipInfo); 613 // tip(tipInfo);
614 } 614 }
615 - },  
616 -  
617 - // 跳转个人信息页  
618 - goMineInfo(args, success, fail) {  
619 - if (this.isYohoBuy && window.yohoInterface) {  
620 - window.yohoInterface.triggerEvent(success || nullFun, fail || nullFun, {  
621 - method: 'go.mineinfo',  
622 - arguments: args  
623 - });  
624 - } else {  
625 - // tip(tipInfo);  
626 - }  
627 } 615 }
628 }; 616 };
629 617
1 <template> 1 <template>
2 <div class="layout-header" :class="{[`theme-${theme}`]: theme}"> 2 <div class="layout-header" :class="{[`theme-${theme}`]: theme}">
3 - <div class="back flex hover-opacity" @click="onBack"> 3 + <div class="back flex hover-opacity" @touchend="onBack">
4 <slot name="back" v-if="back"> 4 <slot name="back" v-if="back">
5 <i class="iconfont icon-left"></i> 5 <i class="iconfont icon-left"></i>
6 </slot> 6 </slot>
7 </div> 7 </div>
8 <div class="title flex" :style="{opacity}"> 8 <div class="title flex" :style="{opacity}">
9 <slot> 9 <slot>
10 - {{title}} 10 + <span class="title-inner">{{title}}</span>
11 </slot> 11 </slot>
12 </div> 12 </div>
13 <div class="opts flex" :style="{opacity}"> 13 <div class="opts flex" :style="{opacity}">
@@ -120,6 +120,15 @@ export default { @@ -120,6 +120,15 @@ export default {
120 letter-spacing: 0.09PX; 120 letter-spacing: 0.09PX;
121 overflow: hidden; 121 overflow: hidden;
122 z-index: 1; 122 z-index: 1;
  123 +
  124 + .title-inner {
  125 + display: inline-block;
  126 + max-width: 90%;
  127 + overflow: hidden;
  128 + text-overflow: ellipsis;
  129 + white-space: nowrap;
  130 + display: inline-block;
  131 + }
123 } 132 }
124 133
125 .opts { 134 .opts {
@@ -27,7 +27,8 @@ export default { @@ -27,7 +27,8 @@ export default {
27 single: Boolean, 27 single: Boolean,
28 lazy: Boolean, 28 lazy: Boolean,
29 product: Object, 29 product: Object,
30 - share: Boolean 30 + share: Boolean,
  31 + thumb: Boolean
31 }, 32 },
32 data() { 33 data() {
33 return { 34 return {
@@ -42,11 +43,15 @@ export default { @@ -42,11 +43,15 @@ export default {
42 }, 43 },
43 computed: { 44 computed: {
44 favClass() { 45 favClass() {
45 - return {'btn-is-fav': this.favorite, loading: this.posting}; 46 + return {
  47 + 'btn-is-fav': this.favorite,
  48 + loading: this.posting,
  49 + invisible: this.thumb
  50 + };
46 }, 51 },
47 favText() { 52 favText() {
48 return this.favorite ? '已收藏' : '收藏'; 53 return this.favorite ? '已收藏' : '收藏';
49 - } 54 + },
50 }, 55 },
51 methods: { 56 methods: {
52 ...mapActions(['postProductFav']), 57 ...mapActions(['postProductFav']),
@@ -100,7 +105,9 @@ export default { @@ -100,7 +105,9 @@ export default {
100 } 105 }
101 }, 106 },
102 onClick() { 107 onClick() {
103 - this.product.product_skn && this.$yoho.goProductDetail(this.product.product_skn); 108 + let skn = this.product.product_skn || this.product.productSkn;
  109 +
  110 + skn && this.$yoho.goProductDetail(skn);
104 } 111 }
105 } 112 }
106 }; 113 };
@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 <ProductGroupItem 3 <ProductGroupItem
4 v-for="(product, inx) in data" 4 v-for="(product, inx) in data"
5 :share="share" 5 :share="share"
  6 + :thumb="thumb"
6 :single="single" 7 :single="single"
7 :product="product" 8 :product="product"
8 :lazy="lazy" 9 :lazy="lazy"
@@ -27,7 +28,8 @@ export default { @@ -27,7 +28,8 @@ export default {
27 type: Boolean, 28 type: Boolean,
28 default: true 29 default: true
29 }, 30 },
30 - share: Boolean 31 + share: Boolean,
  32 + thumb: Boolean
31 }, 33 },
32 computed: { 34 computed: {
33 single() { 35 single() {
1 <template> 1 <template>
2 - <AuthComponent :auth="isAuth" class="icon-btn" @click="onClick" :style="btnStyle"> 2 + <AuthComponent :auth="isAuth" class="icon-btn" :class="{'btn-selected': viewOption.selected}" @click="onClick" :style="btnStyle">
3 <i class="iconfont" :class="iconClass" :style="iconStyle"></i> 3 <i class="iconfont" :class="iconClass" :style="iconStyle"></i>
4 <p v-if="viewText" class="icon-btn-text" :style="textStyle"> 4 <p v-if="viewText" class="icon-btn-text" :style="textStyle">
5 <span class="view-text">{{Number(viewText) ? viewText : ''}}</span> 5 <span class="view-text">{{Number(viewText) ? viewText : ''}}</span>
@@ -75,7 +75,6 @@ export default { @@ -75,7 +75,6 @@ export default {
75 return { 75 return {
76 currentClass: {}, 76 currentClass: {},
77 viewOption: {}, 77 viewOption: {},
78 - btnSelected: false,  
79 actionClass: '', 78 actionClass: '',
80 editText: null 79 editText: null
81 }; 80 };
@@ -102,7 +101,7 @@ export default { @@ -102,7 +101,7 @@ export default {
102 btnStyle() { 101 btnStyle() {
103 let color = this.viewOption.color || defaultOption.color; 102 let color = this.viewOption.color || defaultOption.color;
104 103
105 - return `color: ${this.btnSelected ? (this.viewOption.selectedColor || color) : color};`; 104 + return `color: ${this.viewOption.selected ? (this.viewOption.selectedColor || color) : color};`;
106 }, 105 },
107 iconClass() { 106 iconClass() {
108 if (this.actionClass) { 107 if (this.actionClass) {
@@ -150,12 +149,12 @@ export default { @@ -150,12 +149,12 @@ export default {
150 type() { 149 type() {
151 this.setCurrentClass(); 150 this.setCurrentClass();
152 }, 151 },
153 - option(val) {  
154 - if (this.viewOption.selected !== this.option.selected) { 152 + option(val, oldVal) {
  153 + if (oldVal.selected !== val.selected) {
155 this.actionClass = ''; 154 this.actionClass = '';
156 } 155 }
157 156
158 - if (this.viewOption.iconBold !== this.option.iconBold) { 157 + if (oldVal.iconBold !== val.iconBold) {
159 this.setCurrentClass(); 158 this.setCurrentClass();
160 } 159 }
161 160
@@ -182,6 +181,7 @@ export default { @@ -182,6 +181,7 @@ export default {
182 forEach(defaultOption, (value, key) => { 181 forEach(defaultOption, (value, key) => {
183 this.viewOption[key] = this.option.hasOwnProperty(key) ? this.option[key] : defaultOption[key]; 182 this.viewOption[key] = this.option.hasOwnProperty(key) ? this.option[key] : defaultOption[key];
184 }); 183 });
  184 +
185 this.viewOption = {...this.viewOption}; 185 this.viewOption = {...this.viewOption};
186 }, 186 },
187 setCurrentClass() { 187 setCurrentClass() {
@@ -197,15 +197,15 @@ export default { @@ -197,15 +197,15 @@ export default {
197 this.currentClass = currentClass; 197 this.currentClass = currentClass;
198 }, 198 },
199 changeBtnStatus() { 199 changeBtnStatus() {
200 - this.btnSelected = !this.btnSelected; 200 + this.viewOption.selected = !this.viewOption.selected;
201 201
202 if (this.viewOption.textAutoChange) { 202 if (this.viewOption.textAutoChange) {
203 if (!isNaN(Number(this.viewText))) { 203 if (!isNaN(Number(this.viewText))) {
204 - this.editText = Number(this.viewText) + (this.btnSelected ? 1 : -1); 204 + this.editText = Number(this.viewText) + (this.viewOption.selected ? 1 : -1);
205 } 205 }
206 } 206 }
207 207
208 - this.actionClass = this.btnSelected ? currentClass.selected : currentClass.default; 208 + this.actionClass = this.viewOption.selected ? this.currentClass.selected : this.currentClass.default;
209 }, 209 },
210 syncService(type, data) { 210 syncService(type, data) {
211 if (typeof this[type] === 'function') { 211 if (typeof this[type] === 'function') {
@@ -248,7 +248,7 @@ export default { @@ -248,7 +248,7 @@ export default {
248 this.syncService(this.syncFnName, { 248 this.syncService(this.syncFnName, {
249 articleId: this.articleId, 249 articleId: this.articleId,
250 commentId: this.commentId, 250 commentId: this.commentId,
251 - status: this.btnSelected 251 + status: this.viewOption.selected
252 }).then(backFn).catch(backFn); 252 }).then(backFn).catch(backFn);
253 } 253 }
254 } 254 }
@@ -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 :thumb="true" 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) {
@@ -25,7 +25,7 @@ @@ -25,7 +25,7 @@
25 </CommentPlaceholder> 25 </CommentPlaceholder>
26 </div> 26 </div>
27 <div class="total-comment"> 27 <div class="total-comment">
28 - <div class="total hover-opacity" @click="onShowComment">查看{{articleState.commentCount}}条评论</div> 28 + <div class="total hover-opacity" :class="invisibleClass" @click="onShowComment">查看{{articleState.commentCount}}条评论</div>
29 <div class="last-time">{{data.date}}</div> 29 <div class="last-time">{{data.date}}</div>
30 </div> 30 </div>
31 </div> 31 </div>
@@ -45,13 +45,19 @@ export default { @@ -45,13 +45,19 @@ export default {
45 } 45 }
46 }, 46 },
47 type: String, 47 type: String,
48 - share: Boolean 48 + share: Boolean,
  49 + thumb: Boolean
49 }, 50 },
50 computed: { 51 computed: {
51 ...mapState(['articleStates']), 52 ...mapState(['articleStates']),
52 articleState() { 53 articleState() {
53 return this.articleStates[this.data.articleId] || this.data; 54 return this.articleStates[this.data.articleId] || this.data;
54 }, 55 },
  56 + invisibleClass() {
  57 + return {
  58 + invisible: this.thumb
  59 + };
  60 + },
55 }, 61 },
56 methods: { 62 methods: {
57 ...mapMutations(['ASYNC_ARTICLE_COMMENT']), 63 ...mapMutations(['ASYNC_ARTICLE_COMMENT']),
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 <span class="user-name">{{data.authorName}}</span> 5 <span class="user-name">{{data.authorName}}</span>
6 </div> 6 </div>
7 <div class="opts"> 7 <div class="opts">
8 - <WidgetFollow :share="share" :author-uid="data.authorUid" :authorType="data.authorType" :follow="data.hasAttention === 'Y'" @on-follow="onFollow"></WidgetFollow> 8 + <WidgetFollow :class="invisibleClass" :share="share" :author-uid="data.authorUid" :authorType="data.authorType" :follow="data.hasAttention === 'Y'" @on-follow="onFollow"></WidgetFollow>
9 <i class="iconfont icon-more1" @click="onMore"></i> 9 <i class="iconfont icon-more1" @click="onMore"></i>
10 </div> 10 </div>
11 </div> 11 </div>
@@ -29,7 +29,15 @@ export default { @@ -29,7 +29,15 @@ export default {
29 default: true 29 default: true
30 }, 30 },
31 type: String, 31 type: String,
32 - share: Boolean 32 + share: Boolean,
  33 + thumb: Boolean
  34 + },
  35 + computed: {
  36 + invisibleClass() {
  37 + return {
  38 + invisible: this.thumb
  39 + };
  40 + }
33 }, 41 },
34 methods: { 42 methods: {
35 ...mapMutations(['CHANGE_AUTHOR_FOLLOW']), 43 ...mapMutations(['CHANGE_AUTHOR_FOLLOW']),
@@ -20,15 +20,16 @@ @@ -20,15 +20,16 @@
20 <WidgetShare :share="share" @click.native="onShare"></WidgetShare> 20 <WidgetShare :share="share" @click.native="onShare"></WidgetShare>
21 </div> 21 </div>
22 <div class="opts"> 22 <div class="opts">
23 - <WidgetFav :share="share" :num="articleState.praiseCount" :article-id="data.articleId" :option="praiseOption"></WidgetFav>  
24 - <WidgetLike :share="share" :num="articleState.favoriteCount" :article-id="data.articleId" :option="favoriteOption"></WidgetLike>  
25 - <WidgetComment :share="share" :num="articleState.commentCount" @click.native="onShowComment"></WidgetComment> 23 + <WidgetFav :class="invisibleClass" :share="share" :num="articleState.praiseCount" :article-id="data.articleId" :option="praiseOption"></WidgetFav>
  24 + <WidgetLike :class="invisibleClass" :share="share" :num="articleState.favoriteCount" :article-id="data.articleId" :option="favoriteOption"></WidgetLike>
  25 + <WidgetComment :class="invisibleClass" :share="share" :num="articleState.commentCount" @click.native="onShowComment"></WidgetComment>
26 </div> 26 </div>
27 </div> 27 </div>
28 </div> 28 </div>
29 </template> 29 </template>
30 30
31 <script> 31 <script>
  32 +import {get} from 'lodash';
32 import {createNamespacedHelpers} from 'vuex'; 33 import {createNamespacedHelpers} from 'vuex';
33 const {mapMutations, mapState} = createNamespacedHelpers('article'); 34 const {mapMutations, mapState} = createNamespacedHelpers('article');
34 35
@@ -42,12 +43,12 @@ export default { @@ -42,12 +43,12 @@ export default {
42 } 43 }
43 }, 44 },
44 type: String, 45 type: String,
45 - share: Boolean 46 + share: Boolean,
  47 + thumb: Boolean
46 }, 48 },
47 data() { 49 data() {
48 return { 50 return {
49 isPreExpand: false, 51 isPreExpand: false,
50 - introCollapseHeight: 0,  
51 }; 52 };
52 }, 53 },
53 watch: { 54 watch: {
@@ -57,6 +58,11 @@ export default { @@ -57,6 +58,11 @@ export default {
57 }, 58 },
58 computed: { 59 computed: {
59 ...mapState(['articleStates']), 60 ...mapState(['articleStates']),
  61 + invisibleClass() {
  62 + return {
  63 + invisible: this.thumb
  64 + };
  65 + },
60 articleState() { 66 articleState() {
61 return this.articleStates[this.data.articleId] || this.data; 67 return this.articleStates[this.data.articleId] || this.data;
62 }, 68 },
@@ -88,7 +94,7 @@ export default { @@ -88,7 +94,7 @@ export default {
88 if (this.data.isExpand) { 94 if (this.data.isExpand) {
89 introHeight = this.data.introHeight; 95 introHeight = this.data.introHeight;
90 } else { 96 } else {
91 - introHeight = this.introCollapseHeight; 97 + introHeight = this.data.introCollapseHeight;
92 } 98 }
93 99
94 return { 100 return {
@@ -107,13 +113,11 @@ export default { @@ -107,13 +113,11 @@ export default {
107 }, 113 },
108 }, 114 },
109 mounted() { 115 mounted() {
110 - if (this.$refs.intro) {  
111 - this.introCollapseHeight = this.$refs.intro.scrollHeight;  
112 - }  
113 - if (this.$refs.introPool) { 116 + if (this.data.introHeight === 0) {
114 this.CHANGE_ARTICLE_LIST_INTRO_HEIGHT({ 117 this.CHANGE_ARTICLE_LIST_INTRO_HEIGHT({
115 articleId: this.data.articleId, 118 articleId: this.data.articleId,
116 - introHeight: this.$refs.introPool.scrollHeight + 20, 119 + introHeight: get(this.$refs, 'introPool.scrollHeight', 0) + 20,
  120 + introCollapseHeight: get(this.$refs, 'intro.scrollHeight', 0),
117 type: this.type 121 type: this.type
118 }); 122 });
119 } 123 }
@@ -155,7 +159,7 @@ export default { @@ -155,7 +159,7 @@ export default {
155 return; 159 return;
156 } 160 }
157 const isExpand = !this.data.isExpand; 161 const isExpand = !this.data.isExpand;
158 - const height = isExpand ? this.data.introHeight : this.introCollapseHeight; 162 + const height = isExpand ? this.data.introHeight : this.data.introCollapseHeight;
159 163
160 this.$emit('on-expanding'); 164 this.$emit('on-expanding');
161 165
1 <template> 1 <template>
2 - <ImageFormat :mode="1" :lazy="lazy" :style="imageStyle" class="image-slide-item" :src="data.contentData" :width="imageSize.width" :height="imageSize.height"></ImageFormat> 2 + <ImageFormat :mode="1" :lazy="lazy" :style="imageStyle" class="image-slide-item" :src="data.contentData" :width="data.width" :height="data.height"></ImageFormat>
3 </template> 3 </template>
4 4
5 <script> 5 <script>
@@ -18,8 +18,8 @@ export default { @@ -18,8 +18,8 @@ export default {
18 const {width, height} = this.itemSize; 18 const {width, height} = this.itemSize;
19 19
20 return { 20 return {
21 - width: `${width}px`,  
22 - height: `${height}px` 21 + width: `${width}rem`,
  22 + height: `${height}rem`
23 }; 23 };
24 }, 24 },
25 itemSize() { 25 itemSize() {
@@ -28,31 +28,20 @@ export default { @@ -28,31 +28,20 @@ export default {
28 28
29 if (scale > 1) { 29 if (scale > 1) {
30 return { 30 return {
31 - width: parseInt(this.yoho.window.clientWidth, 10),  
32 - height: parseInt(this.yoho.window.clientWidth / scale, 10) 31 + width: 750 / 40,
  32 + height: 750 / 40 / scale
33 }; 33 };
34 } else if (scale < 1) { 34 } else if (scale < 1) {
35 return { 35 return {
36 - width: parseInt(fHeight * scale, 10),  
37 - height: parseInt(fHeight, 10) 36 + width: fHeight * scale,
  37 + height: fHeight
38 }; 38 };
39 } else { 39 } else {
40 return { 40 return {
41 - width: this.yoho.window.clientWidth,  
42 - height: this.yoho.window.clientWidth 41 + width: 750 / 40,
  42 + height: 750 / 40
43 }; 43 };
44 } 44 }
45 - },  
46 - imageSize() {  
47 - const {width, height} = this.itemSize;  
48 -  
49 - if (this.data.width < width && this.data.height < height) {  
50 - return this.itemSize;  
51 - }  
52 - return {  
53 - width: parseInt(this.data.width, 10),  
54 - height: parseInt(this.data.height, 10),  
55 - };  
56 } 45 }
57 } 46 }
58 }; 47 };
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 <ArticleItemSlideImage v-if="data.blockList.length === 1" :lazy="false" :data="data.blockList[0]" :thumb-size="firstBlockSize"></ArticleItemSlideImage> 3 <ArticleItemSlideImage v-if="data.blockList.length === 1" :lazy="false" :data="data.blockList[0]" :thumb-size="firstBlockSize"></ArticleItemSlideImage>
4 <Slide :key="`slide${data.articleId}`" v-else ref="slide" :data="data.blockList" :refresh-reset-current="false" :initial-index="slideIndex - 1" :threshold="0.2" :auto-play="false" :loop="false" :options="scrollOption" @change="onChange"> 4 <Slide :key="`slide${data.articleId}`" v-else ref="slide" :data="data.blockList" :refresh-reset-current="false" :initial-index="slideIndex - 1" :threshold="0.2" :auto-play="false" :loop="false" :options="scrollOption" @change="onChange">
5 <SlideItem class="slide-item" :style="slideItemStyle" v-for="(item, inx) in data.blockList" :key="inx"> 5 <SlideItem class="slide-item" :style="slideItemStyle" v-for="(item, inx) in data.blockList" :key="inx">
6 - <ArticleItemSlideImage :data="item" :thumb-size="firstBlockSize"></ArticleItemSlideImage> 6 + <ArticleItemSlideImage v-if="!thumb || inx === 0" :lazy="lazy && inx > 0" :data="item" :thumb-size="firstBlockSize"></ArticleItemSlideImage>
7 </SlideItem> 7 </SlideItem>
8 <template slot="dots" slot-scope="props"> 8 <template slot="dots" slot-scope="props">
9 <span class="slide-dot" 9 <span class="slide-dot"
@@ -40,7 +40,8 @@ export default { @@ -40,7 +40,8 @@ export default {
40 type: Boolean, 40 type: Boolean,
41 default: true 41 default: true
42 }, 42 },
43 - type: String 43 + type: String,
  44 + thumb: Boolean
44 }, 45 },
45 data() { 46 data() {
46 return { 47 return {
@@ -56,8 +57,8 @@ export default { @@ -56,8 +57,8 @@ export default {
56 57
57 if (width && height) { 58 if (width && height) {
58 return { 59 return {
59 - width: `${width}px`,  
60 - height: `${height}px`, 60 + width: `${width}rem`,
  61 + height: `${height}rem`,
61 }; 62 };
62 } 63 }
63 }, 64 },
@@ -68,8 +69,8 @@ export default { @@ -68,8 +69,8 @@ export default {
68 const scale = width / height; 69 const scale = width / height;
69 70
70 return { 71 return {
71 - width: this.yoho.window.clientWidth,  
72 - height: this.yoho.window.clientWidth / scale, 72 + width: 750 / 40,
  73 + height: (750 / 40) / scale,
73 }; 74 };
74 } 75 }
75 return {}; 76 return {};
1 <template> 1 <template>
2 <div class="article-item"> 2 <div class="article-item">
3 - <ArticleItemHeader :type="type" :share="share" :data="headerData" :lazy="lazy" @on-follow="onFollow"></ArticleItemHeader>  
4 - <ArticleItemSlide :type="type" :share="share" :data="slideData" :slide-index="data.blockIndex" :lazy="lazy"></ArticleItemSlide>  
5 - <ProductGroup v-if="productListData.length" :share="share" :data="productListData" :lazy="lazy"></ProductGroup>  
6 - <ArticleItemIntro :type="type" :share="share" :data="introData" @on-expand="onExpand" @on-expanding="onExpanding" @on-show-guang="onShowGuang" @on-show-comment="onShowComment"></ArticleItemIntro>  
7 - <ArticleItemComment :type="type" :share="share" :data="commentData" @on-show-comment="onShowComment" @on-resize="onResize"></ArticleItemComment> 3 + <ArticleItemHeader :type="type" :thumb="thumb" :share="share" :data="headerData" :lazy="lazy" @on-follow="onFollow"></ArticleItemHeader>
  4 + <ArticleItemSlide :type="type" :thumb="thumb" :share="share" :data="slideData" :slide-index="data.blockIndex" :lazy="lazy"></ArticleItemSlide>
  5 + <ProductGroup :thumb="thumb" v-if="productListData.length" :share="share" :data="productListData" :lazy="lazy"></ProductGroup>
  6 + <ArticleItemIntro :thumb="thumb" :type="type" :share="share" :data="introData" @on-expand="onExpand" @on-expanding="onExpanding" @on-show-guang="onShowGuang" @on-show-comment="onShowComment"></ArticleItemIntro>
  7 + <ArticleItemComment :thumb="thumb" :type="type" :share="share" :data="commentData" @on-show-comment="onShowComment" @on-resize="onResize"></ArticleItemComment>
8 <div class="line"></div> 8 <div class="line"></div>
9 </div> 9 </div>
10 </template> 10 </template>
@@ -27,7 +27,8 @@ export default { @@ -27,7 +27,8 @@ export default {
27 } 27 }
28 }, 28 },
29 share: Boolean, 29 share: Boolean,
30 - type: String 30 + type: String,
  31 + thumb: Boolean
31 }, 32 },
32 computed: { 33 computed: {
33 articleState() { 34 articleState() {
@@ -53,6 +54,7 @@ export default { @@ -53,6 +54,7 @@ export default {
53 intro: get(get(this.data, 'blockList', []).filter(block => block.templateKey === 'text'), '[0].contentData', ''), 54 intro: get(get(this.data, 'blockList', []).filter(block => block.templateKey === 'text'), '[0].contentData', ''),
54 isExpand: this.data.isExpand, 55 isExpand: this.data.isExpand,
55 introHeight: this.data.introHeight, 56 introHeight: this.data.introHeight,
  57 + introCollapseHeight: this.data.introCollapseHeight,
56 articleType: this.data.articleType, 58 articleType: this.data.articleType,
57 labelList: this.data.labelList, 59 labelList: this.data.labelList,
58 hasFavor: this.data.hasFavor, 60 hasFavor: this.data.hasFavor,
@@ -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="10" 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" v-if="showThumb">
  31 + <slot name="thumb"></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,17 @@ export default { @@ -177,6 +195,17 @@ 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 + overflow-y: auto;
  207 +}
  208 +
180 .avatar-wrapper { 209 .avatar-wrapper {
181 display: flex; 210 display: flex;
182 justify-content: center; 211 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() {
@@ -57,8 +57,9 @@ @@ -57,8 +57,9 @@
57 <p v-else class="load-text">没有更多了</p> 57 <p v-else class="load-text">没有更多了</p>
58 </div> 58 </div>
59 </div> 59 </div>
60 -  
61 </cube-scroll> 60 </cube-scroll>
  61 +
  62 + <a v-if="isOwner" class="publish hover-opacity" :href="publishUrl"></a>
62 </Layout> 63 </Layout>
63 </template> 64 </template>
64 65
@@ -78,6 +79,7 @@ @@ -78,6 +79,7 @@
78 return { 79 return {
79 scrollY: 0, 80 scrollY: 0,
80 mineInfoUrl: '//m.yohobuy.com/home/mydetails?openby:yohobuy={"action":"go.mineinfo"}', 81 mineInfoUrl: '//m.yohobuy.com/home/mydetails?openby:yohobuy={"action":"go.mineinfo"}',
  82 + publishUrl: '?openby:yohobuy={"action":"go.grasspublish"}',
81 autherInfo: {}, 83 autherInfo: {},
82 fansList: { 84 fansList: {
83 attCount: '关注', 85 attCount: '关注',
@@ -348,7 +350,7 @@ @@ -348,7 +350,7 @@
348 tip = this.isOwner ? '发布你的第一篇潮人态度' : 'TA还没有分享过哦'; 350 tip = this.isOwner ? '发布你的第一篇潮人态度' : 'TA还没有分享过哦';
349 break; 351 break;
350 case 1: 352 case 1:
351 - tip = this.isOwner ? '快去种下你的第一棵草吧;' : 'TA还没有种过草哦'; 353 + tip = this.isOwner ? '快去收藏你的第一篇内容吧' : 'TA还没有收藏内容';
352 break; 354 break;
353 } 355 }
354 } 356 }
@@ -494,10 +496,12 @@ @@ -494,10 +496,12 @@
494 } 496 }
495 497
496 .num { 498 .num {
  499 + min-width: 30px;
497 font-size: 28px; 500 font-size: 28px;
498 font-weight: 500; 501 font-weight: 500;
499 padding-bottom: 6px; 502 padding-bottom: 6px;
500 display: block; 503 display: block;
  504 + text-align: center;
501 } 505 }
502 506
503 .name { 507 .name {
@@ -566,4 +570,15 @@ @@ -566,4 +570,15 @@
566 text-align: center; 570 text-align: center;
567 } 571 }
568 } 572 }
  573 +
  574 + .publish {
  575 + width: 100px;
  576 + height: 100px;
  577 + position: absolute;
  578 + bottom: 52px;
  579 + right: 40px;
  580 + background-image: url('../../statics/image/userpage/publish.png');
  581 + background-size: 100% 100%;
  582 + z-index: 10;
  583 + }
569 </style> 584 </style>
@@ -133,6 +133,10 @@ export default { @@ -133,6 +133,10 @@ export default {
133 133
134 .fav { 134 .fav {
135 line-height: 60px; 135 line-height: 60px;
  136 +
  137 + .btn-selected > .icon-btn-text {
  138 + color: #d90025!important;
  139 + }
136 } 140 }
137 } 141 }
138 142
1 <template> 1 <template>
2 <div class="tabs-wrap"> 2 <div class="tabs-wrap">
3 <ul class="tabs-list"> 3 <ul class="tabs-list">
4 - <li v-for="(item, index) in tabList" :key="index" :class="{'active': active === index}" @click="changeType(index, true)">  
5 - {{item.name}}  
6 - <span v-if="item.num" class="t-num">({{item.num}})</span> 4 + <li v-for="(item, index) in tabList" :key="index" @click="changeType(index, true)">
  5 + <div class="tabs-item" :class="{'active': active === index}">
  6 + {{item.name}}
  7 + <span v-if="item.num" class="t-num">({{item.num}})</span>
  8 + </div>
7 </li> 9 </li>
8 </ul> 10 </ul>
9 </div> 11 </div>
@@ -68,7 +70,7 @@ export default { @@ -68,7 +70,7 @@ export default {
68 70
69 <style> 71 <style>
70 .tabs-wrap { 72 .tabs-wrap {
71 - padding: 20px 30px 30px; 73 + padding: 0 30px;
72 background-color: #fff; 74 background-color: #fff;
73 display: flex; 75 display: flex;
74 justify-content: space-between; 76 justify-content: space-between;
@@ -81,7 +83,7 @@ export default { @@ -81,7 +83,7 @@ export default {
81 font-size: 32px; 83 font-size: 32px;
82 color: #b0b0b0; 84 color: #b0b0b0;
83 font-weight: 300; 85 font-weight: 300;
84 - margin-right: 40px; 86 + padding: 20px 40px 30px 0;
85 } 87 }
86 88
87 .active { 89 .active {
@@ -21,7 +21,7 @@ export default { @@ -21,7 +21,7 @@ export default {
21 colsList: [], 21 colsList: [],
22 loadedIndex: 0, 22 loadedIndex: 0,
23 colsHeight: [] 23 colsHeight: []
24 - } 24 + };
25 }, 25 },
26 props: { 26 props: {
27 list: { 27 list: {
@@ -687,4 +687,8 @@ img[lazy=loaded] { @@ -687,4 +687,8 @@ img[lazy=loaded] {
687 687
688 button { 688 button {
689 border: none; 689 border: none;
  690 +}
  691 +
  692 +.invisible {
  693 + visibility: hidden;
690 } 694 }
@@ -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,22 @@ function setArticleList(state, data, type) { @@ -34,11 +34,22 @@ 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 - updateArticleState(state, item); 37 + item.introCollapseHeight = 0;
  38 + if (!thumb) {
  39 + updateArticleState(state, item);
  40 + } else {
  41 + item.comments = [];
  42 + item.hasAttention = 'N';
  43 + item.hasFavor = 'N';
  44 + item.hasPraise = 'N';
  45 + item.commentCount = 0;
  46 + item.favoriteCount = 0;
  47 + item.praiseCount = 0;
  48 + }
38 }); 49 });
39 - state[articlefield(type)] = state[articlefield(type)].concat(data); 50 + state[articlefield(type, thumb)] = state[articlefield(type, thumb)].concat(data);
40 51
41 - state[articlefield(type)].forEach((item, index) => { 52 + state[articlefield(type, thumb)].forEach((item, index) => {
42 const imageBlocks = get(item, 'blockList', []).filter(block => block.templateKey === 'image'); 53 const imageBlocks = get(item, 'blockList', []).filter(block => block.templateKey === 'image');
43 54
44 imageBlocks.forEach((img, inx) => { 55 imageBlocks.forEach((img, inx) => {
@@ -62,9 +73,9 @@ export default { @@ -62,9 +73,9 @@ export default {
62 state.articleList = []; 73 state.articleList = [];
63 } 74 }
64 }, 75 },
65 - [Types.FETCH_ARTICLE_LIST_SUCCESS](state, {data}) { 76 + [Types.FETCH_ARTICLE_LIST_SUCCESS](state, {data, thumb}) {
66 state.fetchArticleList = false; 77 state.fetchArticleList = false;
67 - setArticleList(state, data, 'article'); 78 + setArticleList(state, data, 'article', thumb);
68 }, 79 },
69 [Types.FETCH_ARTICLE_LIST_FAILD](state) { 80 [Types.FETCH_ARTICLE_LIST_FAILD](state) {
70 state.fetchArticleList = false; 81 state.fetchArticleList = false;
@@ -75,9 +86,9 @@ export default { @@ -75,9 +86,9 @@ export default {
75 state.articleUserList = []; 86 state.articleUserList = [];
76 } 87 }
77 }, 88 },
78 - [Types.FETCH_ARTICLE_LIST_USER_SUCCESS](state, {data}) { 89 + [Types.FETCH_ARTICLE_LIST_USER_SUCCESS](state, {data, thumb}) {
79 state.fetchArticleUserList = false; 90 state.fetchArticleUserList = false;
80 - setArticleList(state, data, 'userArticle'); 91 + setArticleList(state, data, 'userArticle', thumb);
81 }, 92 },
82 [Types.FETCH_ARTICLE_LIST_USER_FAILD](state) { 93 [Types.FETCH_ARTICLE_LIST_USER_FAILD](state) {
83 state.fetchArticleUserList = false; 94 state.fetchArticleUserList = false;
@@ -159,11 +170,12 @@ export default { @@ -159,11 +170,12 @@ export default {
159 find.isExpand = isExpand; 170 find.isExpand = isExpand;
160 } 171 }
161 }, 172 },
162 - [Types.CHANGE_ARTICLE_LIST_INTRO_HEIGHT](state, {articleId, introHeight, type}) { 173 + [Types.CHANGE_ARTICLE_LIST_INTRO_HEIGHT](state, {articleId, introHeight, introCollapseHeight, type}) {
163 const find = state[articlefield(type)].find(article => article.articleId === articleId); 174 const find = state[articlefield(type)].find(article => article.articleId === articleId);
164 175
165 if (find) { 176 if (find) {
166 find.introHeight = introHeight || find.introHeight; 177 find.introHeight = introHeight || find.introHeight;
  178 + find.introCollapseHeight = introCollapseHeight || find.introCollapseHeight;
167 } 179 }
168 } 180 }
169 }; 181 };
1 const MAX_WIDTH = 750; 1 const MAX_WIDTH = 750;
2 2
3 export function getArticleImageSize({width, height, MIN_SCALE}) { 3 export function getArticleImageSize({width, height, MIN_SCALE}) {
  4 + width = +width;
  5 + height = +height;
4 if (width > MAX_WIDTH) { 6 if (width > MAX_WIDTH) {
5 height = height / (width / MAX_WIDTH); 7 height = height / (width / MAX_WIDTH);
6 width = MAX_WIDTH; 8 width = MAX_WIDTH;
7 } 9 }
8 10
9 if (MIN_SCALE && width / height < MIN_SCALE) { 11 if (MIN_SCALE && width / height < MIN_SCALE) {
10 - return {  
11 - width,  
12 - height: width / MIN_SCALE  
13 - }; 12 + height = width / MIN_SCALE;
  13 + }
  14 + if (width === 1) {
  15 + width = MAX_WIDTH / 2;
  16 + }
  17 + if (height === 1) {
  18 + height = MAX_WIDTH / 2;
14 } 19 }
15 return {width, height}; 20 return {width, height};
16 } 21 }
@@ -17,6 +17,7 @@ module.exports = { @@ -17,6 +17,7 @@ module.exports = {
17 }, 17 },
18 '/api/grass/columnArticleDetail': { 18 '/api/grass/columnArticleDetail': {
19 api: 'app.grass.columnArticleDetail', 19 api: 'app.grass.columnArticleDetail',
  20 + cache: true,
20 auth: true, 21 auth: true,
21 params: { 22 params: {
22 page: {type: Number, require: false}, 23 page: {type: Number, require: false},
1 module.exports = { 1 module.exports = {
2 '/api/grass/getGrassUserBaseInfo': { 2 '/api/grass/getGrassUserBaseInfo': {
3 api: 'app.grass.getGrassUserBaseInfo', 3 api: 'app.grass.getGrassUserBaseInfo',
4 - cache: true,  
5 auth: true, 4 auth: true,
6 params: { 5 params: {
7 authorUid: {type: Number, require: true}, 6 authorUid: {type: Number, require: true},
@@ -40,7 +39,6 @@ module.exports = { @@ -40,7 +39,6 @@ module.exports = {
40 }, 39 },
41 '/api/grass/getMineGrassBaseInfo': { 40 '/api/grass/getMineGrassBaseInfo': {
42 api: 'app.grass.getGrassUserBaseInfo', 41 api: 'app.grass.getGrassUserBaseInfo',
43 - cache: true,  
44 auth: true, 42 auth: true,
45 params: { 43 params: {
46 authorUid: {type: Number, require: true, alias: 'uid'}, 44 authorUid: {type: Number, require: true, alias: 'uid'},
1 module.exports = [ 1 module.exports = [
2 { 2 {
3 - route: /grass\/article\/\d+/, 3 + route: /grass\/article\/\d+$/,
  4 + cacheKey: '$url$params',
  5 + cache: true
  6 + },
  7 + {
  8 + route: /grass\/article\/\d+\/user/,
4 cacheKey: '$url$params', 9 cacheKey: '$url$params',
5 cache: true 10 cache: true
6 }, 11 },
@@ -64,7 +64,7 @@ module.exports = (app) => { @@ -64,7 +64,7 @@ module.exports = (app) => {
64 }, 64 },
65 cookie: { 65 cookie: {
66 domain: 'yohobuy.com', 66 domain: 'yohobuy.com',
67 - httpOnly: true 67 + httpOnly: false
68 }, 68 },
69 store: new RedisStore(Object.assign(config.redis.session, { 69 store: new RedisStore(Object.assign(config.redis.session, {
70 logErrors: (e) => { 70 logErrors: (e) => {
@@ -81,7 +81,7 @@ module.exports = (app) => { @@ -81,7 +81,7 @@ module.exports = (app) => {
81 cookie: { 81 cookie: {
82 domain: 'yohobuy.com', 82 domain: 'yohobuy.com',
83 ephemeral: true, 83 ephemeral: true,
84 - httpOnly: true 84 + httpOnly: false
85 } 85 }
86 })); 86 }));
87 87
@@ -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"