Authored by TaoHuang

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

... ... @@ -612,18 +612,6 @@ const yoho = {
} else {
// tip(tipInfo);
}
},
// 跳转个人信息页
goMineInfo(args, success, fail) {
if (this.isYohoBuy && window.yohoInterface) {
window.yohoInterface.triggerEvent(success || nullFun, fail || nullFun, {
method: 'go.mineinfo',
arguments: args
});
} else {
// tip(tipInfo);
}
}
};
... ...
<template>
<div class="layout-header" :class="{[`theme-${theme}`]: theme}">
<div class="back flex hover-opacity" @click="onBack">
<div class="back flex hover-opacity" @touchend="onBack">
<slot name="back" v-if="back">
<i class="iconfont icon-left"></i>
</slot>
</div>
<div class="title flex" :style="{opacity}">
<slot>
{{title}}
<span class="title-inner">{{title}}</span>
</slot>
</div>
<div class="opts flex" :style="{opacity}">
... ... @@ -120,6 +120,15 @@ export default {
letter-spacing: 0.09PX;
overflow: hidden;
z-index: 1;
.title-inner {
display: inline-block;
max-width: 90%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: inline-block;
}
}
.opts {
... ...
... ... @@ -27,7 +27,8 @@ export default {
single: Boolean,
lazy: Boolean,
product: Object,
share: Boolean
share: Boolean,
thumb: Boolean
},
data() {
return {
... ... @@ -42,11 +43,15 @@ export default {
},
computed: {
favClass() {
return {'btn-is-fav': this.favorite, loading: this.posting};
return {
'btn-is-fav': this.favorite,
loading: this.posting,
invisible: this.thumb
};
},
favText() {
return this.favorite ? '已收藏' : '收藏';
}
},
},
methods: {
...mapActions(['postProductFav']),
... ... @@ -100,7 +105,9 @@ export default {
}
},
onClick() {
this.product.product_skn && this.$yoho.goProductDetail(this.product.product_skn);
let skn = this.product.product_skn || this.product.productSkn;
skn && this.$yoho.goProductDetail(skn);
}
}
};
... ...
... ... @@ -3,6 +3,7 @@
<ProductGroupItem
v-for="(product, inx) in data"
:share="share"
:thumb="thumb"
:single="single"
:product="product"
:lazy="lazy"
... ... @@ -27,7 +28,8 @@ export default {
type: Boolean,
default: true
},
share: Boolean
share: Boolean,
thumb: Boolean
},
computed: {
single() {
... ...
<template>
<AuthComponent :auth="isAuth" class="icon-btn" @click="onClick" :style="btnStyle">
<AuthComponent :auth="isAuth" class="icon-btn" :class="{'btn-selected': viewOption.selected}" @click="onClick" :style="btnStyle">
<i class="iconfont" :class="iconClass" :style="iconStyle"></i>
<p v-if="viewText" class="icon-btn-text" :style="textStyle">
<span class="view-text">{{Number(viewText) ? viewText : ''}}</span>
... ... @@ -75,7 +75,6 @@ export default {
return {
currentClass: {},
viewOption: {},
btnSelected: false,
actionClass: '',
editText: null
};
... ... @@ -102,7 +101,7 @@ export default {
btnStyle() {
let color = this.viewOption.color || defaultOption.color;
return `color: ${this.btnSelected ? (this.viewOption.selectedColor || color) : color};`;
return `color: ${this.viewOption.selected ? (this.viewOption.selectedColor || color) : color};`;
},
iconClass() {
if (this.actionClass) {
... ... @@ -150,12 +149,12 @@ export default {
type() {
this.setCurrentClass();
},
option(val) {
if (this.viewOption.selected !== this.option.selected) {
option(val, oldVal) {
if (oldVal.selected !== val.selected) {
this.actionClass = '';
}
if (this.viewOption.iconBold !== this.option.iconBold) {
if (oldVal.iconBold !== val.iconBold) {
this.setCurrentClass();
}
... ... @@ -182,6 +181,7 @@ export default {
forEach(defaultOption, (value, key) => {
this.viewOption[key] = this.option.hasOwnProperty(key) ? this.option[key] : defaultOption[key];
});
this.viewOption = {...this.viewOption};
},
setCurrentClass() {
... ... @@ -197,15 +197,15 @@ export default {
this.currentClass = currentClass;
},
changeBtnStatus() {
this.btnSelected = !this.btnSelected;
this.viewOption.selected = !this.viewOption.selected;
if (this.viewOption.textAutoChange) {
if (!isNaN(Number(this.viewText))) {
this.editText = Number(this.viewText) + (this.btnSelected ? 1 : -1);
this.editText = Number(this.viewText) + (this.viewOption.selected ? 1 : -1);
}
}
this.actionClass = this.btnSelected ? currentClass.selected : currentClass.default;
this.actionClass = this.viewOption.selected ? this.currentClass.selected : this.currentClass.default;
},
syncService(type, data) {
if (typeof this[type] === 'function') {
... ... @@ -248,7 +248,7 @@ export default {
this.syncService(this.syncFnName, {
articleId: this.articleId,
commentId: this.commentId,
status: this.btnSelected
status: this.viewOption.selected
}).then(backFn).catch(backFn);
}
}
... ...
... ... @@ -2,7 +2,11 @@
<Article
ref="article"
type="article"
:thumb="true"
:on-fetch="onFetch">
<template v-slot:thumb>
<ArticleItem :thumb="true" type="article" v-for="(item, index) in articleThumbList" :key="index" :data="item"></ArticleItem>
</template>
</Article>
</template>
... ... @@ -11,7 +15,7 @@ import {get} from 'lodash';
import Article from './components/article/article';
import ArticleItem from './components/article/article-item';
import {createNamespacedHelpers} from 'vuex';
const {mapActions} = createNamespacedHelpers('article');
const {mapState, mapActions} = createNamespacedHelpers('article');
export default {
name: 'ArticlePage',
... ... @@ -30,6 +34,21 @@ export default {
this.init();
}
},
async serverPrefetch() {
const articleId = parseInt(this.id, 10);
if (!articleId) {
return;
}
return this.fetchArticleList({
articleId,
limit: 2,
thumb: true
});
},
computed: {
...mapState(['articleThumbList'])
},
methods: {
...mapActions(['fetchArticleList', 'fetchArticleProductFavs']),
init() {
... ... @@ -45,9 +64,6 @@ export default {
const result = await this.fetchArticleList({
articleId,
page: this.page,
authorUid: this.authorUid,
authorType: this.authorType,
type: this.type
});
if (result.code === 200) {
... ...
... ... @@ -25,7 +25,7 @@
</CommentPlaceholder>
</div>
<div class="total-comment">
<div class="total hover-opacity" @click="onShowComment">查看{{articleState.commentCount}}条评论</div>
<div class="total hover-opacity" :class="invisibleClass" @click="onShowComment">查看{{articleState.commentCount}}条评论</div>
<div class="last-time">{{data.date}}</div>
</div>
</div>
... ... @@ -45,13 +45,19 @@ export default {
}
},
type: String,
share: Boolean
share: Boolean,
thumb: Boolean
},
computed: {
...mapState(['articleStates']),
articleState() {
return this.articleStates[this.data.articleId] || this.data;
},
invisibleClass() {
return {
invisible: this.thumb
};
},
},
methods: {
...mapMutations(['ASYNC_ARTICLE_COMMENT']),
... ...
... ... @@ -5,7 +5,7 @@
<span class="user-name">{{data.authorName}}</span>
</div>
<div class="opts">
<WidgetFollow :share="share" :author-uid="data.authorUid" :authorType="data.authorType" :follow="data.hasAttention === 'Y'" @on-follow="onFollow"></WidgetFollow>
<WidgetFollow :class="invisibleClass" :share="share" :author-uid="data.authorUid" :authorType="data.authorType" :follow="data.hasAttention === 'Y'" @on-follow="onFollow"></WidgetFollow>
<i class="iconfont icon-more1" @click="onMore"></i>
</div>
</div>
... ... @@ -29,7 +29,15 @@ export default {
default: true
},
type: String,
share: Boolean
share: Boolean,
thumb: Boolean
},
computed: {
invisibleClass() {
return {
invisible: this.thumb
};
}
},
methods: {
...mapMutations(['CHANGE_AUTHOR_FOLLOW']),
... ...
... ... @@ -20,15 +20,16 @@
<WidgetShare :share="share" @click.native="onShare"></WidgetShare>
</div>
<div class="opts">
<WidgetFav :share="share" :num="articleState.praiseCount" :article-id="data.articleId" :option="praiseOption"></WidgetFav>
<WidgetLike :share="share" :num="articleState.favoriteCount" :article-id="data.articleId" :option="favoriteOption"></WidgetLike>
<WidgetComment :share="share" :num="articleState.commentCount" @click.native="onShowComment"></WidgetComment>
<WidgetFav :class="invisibleClass" :share="share" :num="articleState.praiseCount" :article-id="data.articleId" :option="praiseOption"></WidgetFav>
<WidgetLike :class="invisibleClass" :share="share" :num="articleState.favoriteCount" :article-id="data.articleId" :option="favoriteOption"></WidgetLike>
<WidgetComment :class="invisibleClass" :share="share" :num="articleState.commentCount" @click.native="onShowComment"></WidgetComment>
</div>
</div>
</div>
</template>
<script>
import {get} from 'lodash';
import {createNamespacedHelpers} from 'vuex';
const {mapMutations, mapState} = createNamespacedHelpers('article');
... ... @@ -42,12 +43,12 @@ export default {
}
},
type: String,
share: Boolean
share: Boolean,
thumb: Boolean
},
data() {
return {
isPreExpand: false,
introCollapseHeight: 0,
};
},
watch: {
... ... @@ -57,6 +58,11 @@ export default {
},
computed: {
...mapState(['articleStates']),
invisibleClass() {
return {
invisible: this.thumb
};
},
articleState() {
return this.articleStates[this.data.articleId] || this.data;
},
... ... @@ -88,7 +94,7 @@ export default {
if (this.data.isExpand) {
introHeight = this.data.introHeight;
} else {
introHeight = this.introCollapseHeight;
introHeight = this.data.introCollapseHeight;
}
return {
... ... @@ -107,13 +113,11 @@ export default {
},
},
mounted() {
if (this.$refs.intro) {
this.introCollapseHeight = this.$refs.intro.scrollHeight;
}
if (this.$refs.introPool) {
if (this.data.introHeight === 0) {
this.CHANGE_ARTICLE_LIST_INTRO_HEIGHT({
articleId: this.data.articleId,
introHeight: this.$refs.introPool.scrollHeight + 20,
introHeight: get(this.$refs, 'introPool.scrollHeight', 0) + 20,
introCollapseHeight: get(this.$refs, 'intro.scrollHeight', 0),
type: this.type
});
}
... ... @@ -155,7 +159,7 @@ export default {
return;
}
const isExpand = !this.data.isExpand;
const height = isExpand ? this.data.introHeight : this.introCollapseHeight;
const height = isExpand ? this.data.introHeight : this.data.introCollapseHeight;
this.$emit('on-expanding');
... ...
<template>
<ImageFormat :mode="1" :lazy="lazy" :style="imageStyle" class="image-slide-item" :src="data.contentData" :width="imageSize.width" :height="imageSize.height"></ImageFormat>
<ImageFormat :mode="1" :lazy="lazy" :style="imageStyle" class="image-slide-item" :src="data.contentData" :width="data.width" :height="data.height"></ImageFormat>
</template>
<script>
... ... @@ -18,8 +18,8 @@ export default {
const {width, height} = this.itemSize;
return {
width: `${width}px`,
height: `${height}px`
width: `${width}rem`,
height: `${height}rem`
};
},
itemSize() {
... ... @@ -28,31 +28,20 @@ export default {
if (scale > 1) {
return {
width: parseInt(this.yoho.window.clientWidth, 10),
height: parseInt(this.yoho.window.clientWidth / scale, 10)
width: 750 / 40,
height: 750 / 40 / scale
};
} else if (scale < 1) {
return {
width: parseInt(fHeight * scale, 10),
height: parseInt(fHeight, 10)
width: fHeight * scale,
height: fHeight
};
} else {
return {
width: this.yoho.window.clientWidth,
height: this.yoho.window.clientWidth
width: 750 / 40,
height: 750 / 40
};
}
},
imageSize() {
const {width, height} = this.itemSize;
if (this.data.width < width && this.data.height < height) {
return this.itemSize;
}
return {
width: parseInt(this.data.width, 10),
height: parseInt(this.data.height, 10),
};
}
}
};
... ...
... ... @@ -3,7 +3,7 @@
<ArticleItemSlideImage v-if="data.blockList.length === 1" :lazy="false" :data="data.blockList[0]" :thumb-size="firstBlockSize"></ArticleItemSlideImage>
<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">
<SlideItem class="slide-item" :style="slideItemStyle" v-for="(item, inx) in data.blockList" :key="inx">
<ArticleItemSlideImage :data="item" :thumb-size="firstBlockSize"></ArticleItemSlideImage>
<ArticleItemSlideImage v-if="!thumb || inx === 0" :lazy="lazy && inx > 0" :data="item" :thumb-size="firstBlockSize"></ArticleItemSlideImage>
</SlideItem>
<template slot="dots" slot-scope="props">
<span class="slide-dot"
... ... @@ -40,7 +40,8 @@ export default {
type: Boolean,
default: true
},
type: String
type: String,
thumb: Boolean
},
data() {
return {
... ... @@ -56,8 +57,8 @@ export default {
if (width && height) {
return {
width: `${width}px`,
height: `${height}px`,
width: `${width}rem`,
height: `${height}rem`,
};
}
},
... ... @@ -68,8 +69,8 @@ export default {
const scale = width / height;
return {
width: this.yoho.window.clientWidth,
height: this.yoho.window.clientWidth / scale,
width: 750 / 40,
height: (750 / 40) / scale,
};
}
return {};
... ...
<template>
<div class="article-item">
<ArticleItemHeader :type="type" :share="share" :data="headerData" :lazy="lazy" @on-follow="onFollow"></ArticleItemHeader>
<ArticleItemSlide :type="type" :share="share" :data="slideData" :slide-index="data.blockIndex" :lazy="lazy"></ArticleItemSlide>
<ProductGroup v-if="productListData.length" :share="share" :data="productListData" :lazy="lazy"></ProductGroup>
<ArticleItemIntro :type="type" :share="share" :data="introData" @on-expand="onExpand" @on-expanding="onExpanding" @on-show-guang="onShowGuang" @on-show-comment="onShowComment"></ArticleItemIntro>
<ArticleItemComment :type="type" :share="share" :data="commentData" @on-show-comment="onShowComment" @on-resize="onResize"></ArticleItemComment>
<ArticleItemHeader :type="type" :thumb="thumb" :share="share" :data="headerData" :lazy="lazy" @on-follow="onFollow"></ArticleItemHeader>
<ArticleItemSlide :type="type" :thumb="thumb" :share="share" :data="slideData" :slide-index="data.blockIndex" :lazy="lazy"></ArticleItemSlide>
<ProductGroup :thumb="thumb" v-if="productListData.length" :share="share" :data="productListData" :lazy="lazy"></ProductGroup>
<ArticleItemIntro :thumb="thumb" :type="type" :share="share" :data="introData" @on-expand="onExpand" @on-expanding="onExpanding" @on-show-guang="onShowGuang" @on-show-comment="onShowComment"></ArticleItemIntro>
<ArticleItemComment :thumb="thumb" :type="type" :share="share" :data="commentData" @on-show-comment="onShowComment" @on-resize="onResize"></ArticleItemComment>
<div class="line"></div>
</div>
</template>
... ... @@ -27,7 +27,8 @@ export default {
}
},
share: Boolean,
type: String
type: String,
thumb: Boolean
},
computed: {
articleState() {
... ... @@ -53,6 +54,7 @@ export default {
intro: get(get(this.data, 'blockList', []).filter(block => block.templateKey === 'text'), '[0].contentData', ''),
isExpand: this.data.isExpand,
introHeight: this.data.introHeight,
introCollapseHeight: this.data.introCollapseHeight,
articleType: this.data.articleType,
labelList: this.data.labelList,
hasFavor: this.data.hasFavor,
... ...
... ... @@ -12,7 +12,7 @@
<WidgetFollow :share="share" class="widget-follow" :author-uid="currentAuthor.authorUid" :follow="currentAuthor.hasAttention === 'Y'" @on-follow="follow => onFollow(currentAuthor, follow)"></WidgetFollow>
</template>
</LayoutHeader>
<LayoutRecycleList :size="30" ref="scroll" @scroll="onScroll" :offset="2000" :on-fetch="onFetch">
<LayoutRecycleList :size="10" ref="scroll" @scroll="onScroll" :offset="2000" :on-fetch="onScrollFetch">
<template class="article-item" v-slot:item="{ data }">
<ArticleItem
:id="`item${data.index}`"
... ... @@ -27,6 +27,9 @@
<div :id="`ph${data.index}`"></div>
</template>
</LayoutRecycleList>
<div class="thumbs" v-if="showThumb">
<slot name="thumb"></slot>
</div>
</Layout>
<ArticleActionSheet v-if="showArticleDetailAction" ref="actionSheet"></ArticleActionSheet>
<YohoActionSheet transfer v-if="showCommentAction" ref="commentAction" :full="true">
... ... @@ -51,13 +54,20 @@ export default {
},
share: Boolean,
type: String,
thumb: Boolean,
onFetch: Function
},
mounted() {
this.scrollPreLazy = debounce(this.changeItem.bind(this), 200);
},
computed: {
showThumb() {
return !this.isMounted && this.thumb;
}
},
data() {
return {
isMounted: false,
articleId: 0,
articleIndex: -1,
showCommentAction: false,
... ... @@ -84,6 +94,14 @@ export default {
},
methods: {
...mapMutations(['CHANGE_ARTICLE_LIST_PRELAZY', 'ASYNC_ARTICLE_COMMENT']),
async onScrollFetch() {
const result = await this.onFetch();
setTimeout(() => {
this.isMounted = true;
}, 0);
return result;
},
toUserPage() {
if (this.share) {
return this.$links.toDownloadApp();
... ... @@ -177,6 +195,17 @@ export default {
background-color: #f0f0f0;
}
.thumbs {
bottom: 0;
position: absolute;
top: 0;
left: 0;
right: 0;
width: 100%;
height: 100%;
overflow-y: auto;
}
.avatar-wrapper {
display: flex;
justify-content: center;
... ...
... ... @@ -3,7 +3,11 @@
ref="article"
:title="userName"
type="userArticle"
:thumb="true"
:on-fetch="onFetch">
<template v-slot:thumb>
<ArticleItem type="userArticle" v-for="(item, index) in articleUserThumbList" :key="index" :data="item"></ArticleItem>
</template>
</Article>
</template>
... ... @@ -12,7 +16,7 @@ import {get} from 'lodash';
import Article from './components/article/article';
import ArticleItem from './components/article/article-item';
import {createNamespacedHelpers} from 'vuex';
const {mapActions} = createNamespacedHelpers('article');
const {mapState, mapActions} = createNamespacedHelpers('article');
export default {
name: 'ArticlePage',
... ... @@ -54,6 +58,24 @@ export default {
}
next();
},
async serverPrefetch() {
const articleId = parseInt(this.id, 10);
if (!articleId) {
return;
}
return this.fetchArticleUserList({
articleId,
limit: 2,
thumb: true,
authorUid: this.authorUid,
authorType: this.authorType,
type: this.type
});
},
computed: {
...mapState(['articleUserThumbList'])
},
methods: {
...mapActions(['fetchArticleUserList', 'fetchArticleProductFavs']),
init() {
... ...
... ... @@ -57,8 +57,9 @@
<p v-else class="load-text">没有更多了</p>
</div>
</div>
</cube-scroll>
<a v-if="isOwner" class="publish hover-opacity" :href="publishUrl"></a>
</Layout>
</template>
... ... @@ -78,6 +79,7 @@
return {
scrollY: 0,
mineInfoUrl: '//m.yohobuy.com/home/mydetails?openby:yohobuy={"action":"go.mineinfo"}',
publishUrl: '?openby:yohobuy={"action":"go.grasspublish"}',
autherInfo: {},
fansList: {
attCount: '关注',
... ... @@ -348,7 +350,7 @@
tip = this.isOwner ? '发布你的第一篇潮人态度' : 'TA还没有分享过哦';
break;
case 1:
tip = this.isOwner ? '快去种下你的第一棵草吧;' : 'TA还没有种过草哦';
tip = this.isOwner ? '快去收藏你的第一篇内容吧' : 'TA还没有收藏内容';
break;
}
}
... ... @@ -494,10 +496,12 @@
}
.num {
min-width: 30px;
font-size: 28px;
font-weight: 500;
padding-bottom: 6px;
display: block;
text-align: center;
}
.name {
... ... @@ -566,4 +570,15 @@
text-align: center;
}
}
.publish {
width: 100px;
height: 100px;
position: absolute;
bottom: 52px;
right: 40px;
background-image: url('../../statics/image/userpage/publish.png');
background-size: 100% 100%;
z-index: 10;
}
</style>
... ...
... ... @@ -133,6 +133,10 @@ export default {
.fav {
line-height: 60px;
.btn-selected > .icon-btn-text {
color: #d90025!important;
}
}
}
... ...
<template>
<div class="tabs-wrap">
<ul class="tabs-list">
<li v-for="(item, index) in tabList" :key="index" :class="{'active': active === index}" @click="changeType(index, true)">
{{item.name}}
<span v-if="item.num" class="t-num">({{item.num}})</span>
<li v-for="(item, index) in tabList" :key="index" @click="changeType(index, true)">
<div class="tabs-item" :class="{'active': active === index}">
{{item.name}}
<span v-if="item.num" class="t-num">({{item.num}})</span>
</div>
</li>
</ul>
</div>
... ... @@ -68,7 +70,7 @@ export default {
<style>
.tabs-wrap {
padding: 20px 30px 30px;
padding: 0 30px;
background-color: #fff;
display: flex;
justify-content: space-between;
... ... @@ -81,7 +83,7 @@ export default {
font-size: 32px;
color: #b0b0b0;
font-weight: 300;
margin-right: 40px;
padding: 20px 40px 30px 0;
}
.active {
... ...
... ... @@ -21,7 +21,7 @@ export default {
colsList: [],
loadedIndex: 0,
colsHeight: []
}
};
},
props: {
list: {
... ...
... ... @@ -687,4 +687,8 @@ img[lazy=loaded] {
button {
border: none;
}
.invisible {
visibility: hidden;
}
\ No newline at end of file
... ...
... ... @@ -4,7 +4,7 @@ import * as guangProcess from './guangProcess';
import * as sleep from '../../utils/sleep';
export default {
async fetchArticleList({ commit }, { articleId, authorUid, authorType, limit = 5, page = 1 }) {
async fetchArticleList({ commit }, { articleId, authorUid, authorType, limit = 5, page = 1, thumb = false}) {
commit(Types.FETCH_ARTICLE_LIST_REQUEST, {refresh: page === 1});
const result = await this.$api.get('/api/grass/columnArticleDetail', {
articleId,
... ... @@ -21,6 +21,7 @@ export default {
}
commit(Types.FETCH_ARTICLE_LIST_SUCCESS, {
data: result.data.detailList,
thumb
});
} else {
commit(Types.FETCH_ARTICLE_LIST_FAILD);
... ... @@ -49,7 +50,7 @@ export default {
}
return result;
},
async fetchArticleUserList({ commit }, { articleId, authorUid, authorType, type, limit = 5, page = 1 }) {
async fetchArticleUserList({ commit }, { articleId, authorUid, authorType, type, limit = 5, page = 1, thumb = false }) {
commit(Types.FETCH_ARTICLE_LIST_USER_REQUEST, {refresh: page === 1});
let api;
... ... @@ -73,6 +74,7 @@ export default {
}
commit(Types.FETCH_ARTICLE_LIST_USER_SUCCESS, {
data: result.data.detailList,
thumb
});
} else {
commit(Types.FETCH_ARTICLE_LIST_USER_FAILD);
... ...
... ... @@ -7,10 +7,12 @@ export default function() {
state: {
fetchArticleList: false,
articleList: [],
articleThumbList: [],
fetchArticleListByTopic: false,
articleListByTopic: [],
fetchArticleUserList: false,
articleUserList: [],
articleUserThumbList: [],
articleDetail: null,
articleLastedTimeByTopic: 0,
articleStates: {}
... ...
... ... @@ -3,13 +3,13 @@ import {getArticleImageSize} from 'utils/image-handler';
import { get } from 'lodash';
import Vue from 'vue';
function articlefield(type) {
function articlefield(type, thumb) {
if (type === 'article') {
return 'articleList';
return `article${thumb ? 'Thumb' : ''}List`;
} else if (type === 'topic') {
return 'articleListByTopic';
return `article${thumb ? 'Thumb' : ''}ListByTopic`;
} else if (type === 'userArticle') {
return 'articleUserList';
return `articleUser${thumb ? 'Thumb' : ''}List`;
}
return '';
}
... ... @@ -25,7 +25,7 @@ function updateArticleState(state, item) {
});
}
function setArticleList(state, data, type) {
function setArticleList(state, data, type, thumb) {
data.forEach((item, index) => {
get(item, 'productList', []).forEach(product => {
product.favorite = false;
... ... @@ -34,11 +34,22 @@ function setArticleList(state, data, type) {
item.lazy = index >= 1;
item.isExpand = false;
item.introHeight = 0;
updateArticleState(state, item);
item.introCollapseHeight = 0;
if (!thumb) {
updateArticleState(state, item);
} else {
item.comments = [];
item.hasAttention = 'N';
item.hasFavor = 'N';
item.hasPraise = 'N';
item.commentCount = 0;
item.favoriteCount = 0;
item.praiseCount = 0;
}
});
state[articlefield(type)] = state[articlefield(type)].concat(data);
state[articlefield(type, thumb)] = state[articlefield(type, thumb)].concat(data);
state[articlefield(type)].forEach((item, index) => {
state[articlefield(type, thumb)].forEach((item, index) => {
const imageBlocks = get(item, 'blockList', []).filter(block => block.templateKey === 'image');
imageBlocks.forEach((img, inx) => {
... ... @@ -62,9 +73,9 @@ export default {
state.articleList = [];
}
},
[Types.FETCH_ARTICLE_LIST_SUCCESS](state, {data}) {
[Types.FETCH_ARTICLE_LIST_SUCCESS](state, {data, thumb}) {
state.fetchArticleList = false;
setArticleList(state, data, 'article');
setArticleList(state, data, 'article', thumb);
},
[Types.FETCH_ARTICLE_LIST_FAILD](state) {
state.fetchArticleList = false;
... ... @@ -75,9 +86,9 @@ export default {
state.articleUserList = [];
}
},
[Types.FETCH_ARTICLE_LIST_USER_SUCCESS](state, {data}) {
[Types.FETCH_ARTICLE_LIST_USER_SUCCESS](state, {data, thumb}) {
state.fetchArticleUserList = false;
setArticleList(state, data, 'userArticle');
setArticleList(state, data, 'userArticle', thumb);
},
[Types.FETCH_ARTICLE_LIST_USER_FAILD](state) {
state.fetchArticleUserList = false;
... ... @@ -159,11 +170,12 @@ export default {
find.isExpand = isExpand;
}
},
[Types.CHANGE_ARTICLE_LIST_INTRO_HEIGHT](state, {articleId, introHeight, type}) {
[Types.CHANGE_ARTICLE_LIST_INTRO_HEIGHT](state, {articleId, introHeight, introCollapseHeight, type}) {
const find = state[articlefield(type)].find(article => article.articleId === articleId);
if (find) {
find.introHeight = introHeight || find.introHeight;
find.introCollapseHeight = introCollapseHeight || find.introCollapseHeight;
}
}
};
... ...
const MAX_WIDTH = 750;
export function getArticleImageSize({width, height, MIN_SCALE}) {
width = +width;
height = +height;
if (width > MAX_WIDTH) {
height = height / (width / MAX_WIDTH);
width = MAX_WIDTH;
}
if (MIN_SCALE && width / height < MIN_SCALE) {
return {
width,
height: width / MIN_SCALE
};
height = width / MIN_SCALE;
}
if (width === 1) {
width = MAX_WIDTH / 2;
}
if (height === 1) {
height = MAX_WIDTH / 2;
}
return {width, height};
}
... ...
... ... @@ -17,6 +17,7 @@ module.exports = {
},
'/api/grass/columnArticleDetail': {
api: 'app.grass.columnArticleDetail',
cache: true,
auth: true,
params: {
page: {type: Number, require: false},
... ...
module.exports = {
'/api/grass/getGrassUserBaseInfo': {
api: 'app.grass.getGrassUserBaseInfo',
cache: true,
auth: true,
params: {
authorUid: {type: Number, require: true},
... ... @@ -40,7 +39,6 @@ module.exports = {
},
'/api/grass/getMineGrassBaseInfo': {
api: 'app.grass.getGrassUserBaseInfo',
cache: true,
auth: true,
params: {
authorUid: {type: Number, require: true, alias: 'uid'},
... ...
module.exports = [
{
route: /grass\/article\/\d+/,
route: /grass\/article\/\d+$/,
cacheKey: '$url$params',
cache: true
},
{
route: /grass\/article\/\d+\/user/,
cacheKey: '$url$params',
cache: true
},
... ...
... ... @@ -64,7 +64,7 @@ module.exports = (app) => {
},
cookie: {
domain: 'yohobuy.com',
httpOnly: true
httpOnly: false
},
store: new RedisStore(Object.assign(config.redis.session, {
logErrors: (e) => {
... ... @@ -81,7 +81,7 @@ module.exports = (app) => {
cookie: {
domain: 'yohobuy.com',
ephemeral: true,
httpOnly: true
httpOnly: false
}
}));
... ...
... ... @@ -3867,16 +3867,6 @@ is-directory@^0.3.1:
version "0.3.1"
resolved "http://npm.yohops.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1"
is-dom-node-list@^1.2.1:
version "1.2.1"
resolved "http://npm.yohops.com/is-dom-node-list/-/is-dom-node-list-1.2.1.tgz#141ded0c66de759d0976800d21370bb908f2950f"
dependencies:
is-dom-node "^1.0.4"
is-dom-node@^1.0.4:
version "1.0.4"
resolved "http://npm.yohops.com/is-dom-node/-/is-dom-node-1.0.4.tgz#abb18af7133f1e687610cfeb274da1ced342f1c5"
is-extendable@^0.1.0, is-extendable@^0.1.1:
version "0.1.1"
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:
safe-buffer "^5.1.2"
yallist "^3.0.0"
miniraf@1.0.0:
version "1.0.0"
resolved "http://npm.yohops.com/miniraf/-/miniraf-1.0.0.tgz#5d88e108bbdcb55b4a2ff3da337f24a13a3377e1"
minizlib@^1.1.1:
version "1.2.1"
resolved "http://npm.yohops.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614"
... ... @@ -6068,10 +6054,6 @@ remark@^10.0.1:
remark-stringify "^6.0.0"
unified "^7.0.0"
rematrix@0.3.0:
version "0.3.0"
resolved "http://npm.yohops.com/rematrix/-/rematrix-0.3.0.tgz#4f3f9156aa80ded8a8ca23785f48c6012b6dea4a"
remove-trailing-separator@^1.0.1:
version "1.1.0"
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:
ajv-errors "^1.0.0"
ajv-keywords "^3.1.0"
scrollreveal@^4.0.5:
version "4.0.5"
resolved "http://npm.yohops.com/scrollreveal/-/scrollreveal-4.0.5.tgz#cf83cc5d9874dc0d92ef9c89a8894e57f3f8e034"
dependencies:
miniraf "1.0.0"
rematrix "0.3.0"
tealight "0.3.6"
scss-tokenizer@^0.2.3:
version "0.2.3"
resolved "http://npm.yohops.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1"
... ... @@ -7004,13 +6978,6 @@ tar@^4:
safe-buffer "^5.1.2"
yallist "^3.0.2"
tealight@0.3.6:
version "0.3.6"
resolved "http://npm.yohops.com/tealight/-/tealight-0.3.6.tgz#14c8071ce3c188972a5cb7d8a5668ca2820b4292"
dependencies:
is-dom-node "^1.0.4"
is-dom-node-list "^1.2.1"
term-size@^1.2.0:
version "1.2.0"
resolved "http://npm.yohops.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69"
... ...