Skip to content

Commit

Permalink
refactor(SPA): 抽出文章点赞、打赏小组件
Browse files Browse the repository at this point in the history
issue #512
  • Loading branch information
mutoe committed Dec 13, 2018
1 parent b03f853 commit 54bbb40
Show file tree
Hide file tree
Showing 13 changed files with 210 additions and 149 deletions.
16 changes: 16 additions & 0 deletions resources/spa/src/api/feeds.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,22 @@ export function getRewards (feedId, params) {
return api.get(url, { params, validateStatus: s => s === 200 })
}

/**
* 获取点赞列表
*
* @author mutoe <[email protected]>
* @export
* @param {number} feedId
* @param {Object} params
* @param {number} [params.limit=20]
* @param {number} [params.after=0]
* @returns {Promise<Object[]>}
*/
export function getFeedLikers (feedId, params) {
const url = `/feeds/${feedId}/likes`
return api.get(url, { params, validateStatus: s => s === 200 })
}

/**
* 打赏动态
* @author mutoe <[email protected]>
Expand Down
16 changes: 16 additions & 0 deletions resources/spa/src/api/news.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,22 @@ export function deleteNewsComment (newsId, commentId) {
})
}

/**
* 获取资讯点赞列表
*
* @author mutoe <[email protected]>
* @export
* @param {number} newsId
* @param {Object} params
* @param {number} [params.limit]
* @param {number} [params.after]
* @returns {Promise<Object[]>}
*/
export function getNewsLikers (newsId, params) {
const url = `/news/${newsId}/likes`
return api.get(url, { params, validateStatus: s => s === 200 })
}

/**
* 获取资讯打赏列表
* @author mutoe <[email protected]>
Expand Down
52 changes: 52 additions & 0 deletions resources/spa/src/components/common/ArticleLikeBadge.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<template>
<RouterLink
tag="div"
class="c-article-like-badge"
to="likers"
append
>
<ul class="avatar-list">
<li
v-for="({user = {}, id}, index) in likers.slice(0, 5)"
:key="id"
:style="{ zIndex: 5-index, backgroundImage: user.avatar && `url(${getAvatar(user)})`}"
:class="`m-avatar-box-${user.sex}`"
class="m-avatar-box tiny"
/>
</ul>
<span class="total">{{ total | formatNum }}人点赞</span>
</RouterLink>
</template>

<script>
export default {
name: 'ArticleLikeBadge',
props: {
likers: { type: Array, default: () => [] },
total: { type: Number, default: 0 },
},
methods: {
getAvatar (user = {}) {
const avatar = user.avatar
if (!avatar) return ''
return avatar.url || ''
},
},
}
</script>

<style lang="less" scoped>
.c-article-like-badge {
display: flex;
align-items: center;
.avatar-list {
flex: none;
}
.total {
margin-left: 0.5em;
color: @primary;
}
}
</style>
44 changes: 44 additions & 0 deletions resources/spa/src/components/common/ArticleRewardBadge.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<template>
<div class="c-article-reward-badge">
<p class="m-art-rew-label">
<a href="javascript:;">{{ total | formatNum }}</a> 人打赏,
共 <a href="javascript:;">{{ ~~amount }}</a> {{ currencyUnit }}
</p>
<RouterLink
tag="ul"
to="rewarders"
append
class="m-box m-aln-center m-art-rew-list"
>
<li
v-for="{id, user} in rewarders"
:key="id"
:class="`m-avatar-box-${user.sex}`"
class="m-flex-grow0 m-flex-shrink0 m-art-rew m-avatar-box tiny"
:style="{backgroundImage: user.avatar && `url(${getAvatar(user.avatar)})`}"
/>
<li v-if="rewarders.length > 0" class="m-box m-aln-center">
<svg class="m-style-svg m-svg-def" style="color: #bfbfbf;">
<use xlink:href="#icon-arrow-right" />
</svg>
</li>
</RouterLink>
</div>
</template>

<script>
export default {
name: 'ArticleRewardBadge',
props: {
total: { type: [Number, String], default: 0 },
amount: { type: [Number, String], default: 0 },
rewarders: { type: Array, default: () => [] },
},
methods: {
getAvatar (avatar) {
if (!avatar) return undefined
return avatar.url || null
},
},
}
</script>
51 changes: 9 additions & 42 deletions resources/spa/src/page/article/ArticleCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,13 @@
<Transition>
<div class="c-article-card">
<div class="m-box-model m-art-card">
<header
ref="head"
class="m-box-model m-pos-f m-head-top"
>
<header ref="head" class="m-box-model m-pos-f m-head-top">
<slot name="head">
<CommonHeader>资讯详情</CommonHeader>
</slot>
</header>

<div
v-if="loading"
class="m-spinner pos-f"
>
<div />
<div />
</div>
<div v-if="loading" class="m-spinner pos-f"> <div /> <div /> </div>

<main class="m-box-model">
<slot />
Expand All @@ -29,37 +20,25 @@
class="m-pos-f"
>
<slot name="foot">
<a
class="m-box-model m-aln-center"
@click.prevent="handelLike"
>
<a class="m-box-model m-aln-center" @click.prevent="handelLike">
<svg class="m-style-svg m-svg-def">
<use :xlink:href="liked ? '#icon-like' :'#icon-unlike'" />
</svg>
<span>喜欢</span>
</a>
<a
class="m-box-model m-aln-center"
@click.prevent="handelComment"
>
<a class="m-box-model m-aln-center" @click.prevent="handelComment">
<svg class="m-style-svg m-svg-def">
<use xlink:href="#icon-comment" />
</svg>
<span>评论</span>
</a>
<a
class="m-box-model m-aln-center"
@click.prevent="handelShare"
>
<a class="m-box-model m-aln-center" @click.prevent="handelShare">
<svg class="m-style-svg m-svg-def">
<use xlink:href="#icon-share" />
</svg>
<span>分享</span>
</a>
<a
class="m-box-model m-aln-center"
@click.prevent="handelMore"
>
<a class="m-box-model m-aln-center" @click.prevent="handelMore">
<svg class="m-style-svg m-svg-def">
<use xlink:href="#icon-more" />
</svg>
Expand All @@ -78,18 +57,9 @@ import HeadRoom from 'headroom.js'
export default {
name: 'ArticleCard',
props: {
loading: {
type: Boolean,
default: true,
},
liked: {
type: Boolean,
default: false,
},
canOprate: {
type: Boolean,
default: true,
},
loading: { type: Boolean, default: true },
liked: { type: Boolean, default: false },
canOprate: { type: Boolean, default: true },
},
data () {
return {
Expand Down Expand Up @@ -161,9 +131,6 @@ export default {
handelMore () {
this.$emit('on-more')
},
goback () {
this.$router.go(-1)
},
},
}
</script>
Expand Down
2 changes: 1 addition & 1 deletion resources/spa/src/page/article/ArticleLikes.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default {
},
data () {
return {
likes: [],
likes: this.$store.state.article.likers || [],
maxId: 0,
}
},
Expand Down
2 changes: 1 addition & 1 deletion resources/spa/src/page/article/ArticleRewards.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default {
name: 'ArticleRewards',
data () {
return {
rewards: [],
rewards: this.$store.state.article.rewarders || [],
typeMap: {
feed: '动态',
news: '资讯',
Expand Down
76 changes: 26 additions & 50 deletions resources/spa/src/page/feed/FeedDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,28 +52,14 @@
</AsyncFile>
<p class="m-text-box" v-html="formatBody(feedContent)" />
</div>

<div class="m-box m-aln-center m-justify-bet m-art-foot">
<div class="m-flex-grow1 m-flex-shrink1 m-art-like-list">
<RouterLink
<ArticleLikeBadge
v-if="likeCount > 0"
tag="div"
class="m-box m-aln-center"
to="likers"
append
>
<ul class="m-box m-flex-grow0 m-flex-shrink0">
<li
v-for="({userItem = {}, id}, index) in likes.slice(0, 5)"
:key="id"
:style="{ zIndex: 5-index }"
:class="`m-avatar-box-${userItem.sex}`"
class="m-avatar-box tiny"
>
<img :src="getAvatar(userItem.avatar)">
</li>
</ul>
<span>{{ likeCount | formatNum }}人点赞</span>
</RouterLink>
:likers="likes"
:total="likeCount"
/>
</div>
<div class="m-box-model m-aln-end m-art-info">
<span v-if="time">发布于{{ time | time2tips }}</span>
Expand All @@ -82,27 +68,11 @@
</div>
<div v-if="allowReward" class="m-box-model m-box-center m-box-center-a m-art-reward">
<button class="m-art-rew-btn" @click="rewardFeed">打 赏</button>
<p class="m-art-rew-label"><a href="javascript:;">{{ reward.count | formatNum }}</a>人打赏,共<a href="javascript:;">{{ ~~reward.amount }}</a>{{ currencyUnit }}</p>
<RouterLink
tag="ul"
to="rewarders"
append
class="m-box m-aln-center m-art-rew-list"
>
<li
v-for="rew in rewardList"
:key="rew.id"
:class="`m-avatar-box-${rew.user.sex}`"
class="m-flex-grow0 m-flex-shrink0 m-art-rew m-avatar-box tiny"
>
<img :src="getAvatar(rew.user.avatar)">
</li>
<li v-if="rewardList.length > 0" class="m-box m-aln-center">
<svg class="m-style-svg m-svg-def" style="fill: #bfbfbf">
<use xlink:href="#icon-arrow-right" />
</svg>
</li>
</RouterLink>
<ArticleRewardBadge
:total="reward.count"
:amount="reward.amount"
:rewarders="rewardList"
/>
</div>
</main>

Expand Down Expand Up @@ -142,18 +112,22 @@

<script>
import { mapState } from 'vuex'
import ArticleCard from '@/page/article/ArticleCard.vue'
import CommentItem from '@/page/article/ArticleComment.vue'
import wechatShare from '@/util/wechatShare.js'
import { limit } from '@/api'
import { followUserByStatus, getUserInfoById } from '@/api/user.js'
import * as api from '@/api/feeds.js'
import ArticleCard from '@/page/article/ArticleCard.vue'
import CommentItem from '@/page/article/ArticleComment.vue'
import ArticleLikeBadge from '@/components/common/ArticleLikeBadge.vue'
import ArticleRewardBadge from '@/components/common/ArticleRewardBadge.vue'
export default {
name: 'FeedDetail',
components: {
ArticleCard,
CommentItem,
ArticleLikeBadge,
ArticleRewardBadge,
},
data () {
return {
Expand Down Expand Up @@ -347,7 +321,8 @@ export default {
this.fetching = false
this.fetchUserInfo()
this.fetchFeedComments()
this.fetchRewards()
this.fetchFeedRewards()
this.fetchFeedLikers()
this.isWechat &&
wechatShare(signUrl, {
title: `${data.user.name}的动态`,
Expand Down Expand Up @@ -407,14 +382,15 @@ export default {
this.fetchComing = false
})
},
fetchRewards () {
api.getRewards(this.feedID, { limit: 10 }).then(({ data = [] }) => {
this.rewardList = data
})
async fetchFeedRewards () {
const { data: list } = await api.getRewards(this.feedID, { limit: 10 })
this.rewardList = list
this.$store.commit('SAVE_ARTICLE', { type: 'likers', list })
},
getAvatar (avatar) {
if (!avatar) return null
return avatar.url || null
async fetchFeedLikers () {
const { data: list } = await api.getFeedLikers(this.feedID, { limit: 5 })
this.feed.likes = list
this.$store.commit('SAVE_ARTICLE', { type: 'likers', list })
},
rewardFeed () {
this.popupBuyTS()
Expand Down
Loading

0 comments on commit 54bbb40

Please sign in to comment.