文章列表

dev
truthhun 1 year ago
parent 545d1a9a6d
commit 08db3fdc74

@ -136,6 +136,7 @@ func (s *ArticleAPIService) ListArticle(ctx context.Context, req *pb.ListArticle
Size: int(req.Size_),
WithCount: true,
QueryLike: make(map[string][]interface{}),
Sort: []string{req.Order},
}
_, err := s.checkPermission(ctx)

@ -0,0 +1,129 @@
<template>
<div class="com-article-list">
<ul v-if="articles.length > 0">
<li v-for="article in articles" :key="'a' + article.id">
<nuxt-link
:to="`/article/${article.identifier}`"
class="el-link el-link--default"
:title="article.title"
>
<span v-if="withHtml" v-html="article.title"></span>
<template v-else>{{ article.title }}</template>
</nuxt-link>
<div v-if="withDescription" class="description">
<span v-if="withHtml" v-html="article.description"></span>
<template v-else>{{ article.description }}</template>
</div>
<div class="help-block">
<el-tooltip
:content="'发布时间:' + formatDatetime(article.created_at)"
>
<span title="发布时间">
<i class="el-icon-time"></i>
{{ formatRelativeTime(article.created_at) }}
</span>
</el-tooltip>
<span
><i class="el-icon-view"></i>
{{ article.view_count || 0 }} 浏览</span
>
<span><i class="el-icon-user"></i> 魔豆文库</span>
<!-- <span
><i class="el-icon-chat-dot-square"></i>
{{ article.comment_count || 0 }} 评论</span
>
<span
><i class="el-icon-star-off"></i>
{{ article.favorite_count || 0 }} 收藏</span
> -->
</div>
</li>
</ul>
<div v-else>
<el-empty description="暂无数据"></el-empty>
</div>
</div>
</template>
<script>
import { formatDatetime, formatRelativeTime } from '~/utils/utils'
export default {
props: {
articles: {
type: Array,
default: () => [],
},
withDescription: {
type: Boolean,
default: false,
},
withHtml: {
type: Boolean,
default: false,
},
},
methods: {
formatRelativeTime,
formatDatetime,
},
}
</script>
<style lang="scss">
.com-article-list {
mark {
background-color: transparent;
color: red;
}
}
</style>
<style lang="scss" scoped>
.com-article-list {
ul,
li {
margin: 0;
padding: 0;
list-style: none;
}
li {
border-bottom: 1px dashed #efefef;
padding: 20px 0;
&:last-child {
border-bottom: none;
}
.help-block {
color: #999;
font-size: 13px;
margin-top: 10px;
span {
margin-right: 20px;
}
}
a {
font-size: 18px;
color: #222;
display: inline-block;
max-width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.no-articles {
text-align: center;
font-size: 15px;
color: #ccc;
padding: 40px 0;
}
.description {
margin-top: 10px;
color: #777;
font-size: 15px;
line-height: 24px;
max-height: 72px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
}
</style>

@ -0,0 +1,134 @@
<template>
<div class="page page-article-index">
<el-row :gutter="20">
<el-col :span="18">
<el-card shadow="never">
<div slot="header">文章列表</div>
<article-list :articles="articles" />
<el-pagination
v-if="total > 0"
:current-page="query.page"
:page-size="size"
:layout="
isMobile
? 'total, prev, pager, next'
: 'total, prev, pager, next, jumper'
"
:pager-count="isMobile ? 5 : 7"
:small="isMobile"
:total="total"
@current-change="pageChange"
>
</el-pagination>
</el-card>
</el-col>
<el-col :span="6">
<el-card shadow="never" class="popular">
<div slot="header">热门</div>
<div v-if="populars.length > 0">
<nuxt-link
:to="`/article/${article.identifier}`"
v-for="article in populars"
:key="'article-' + article.id"
:title="article.title"
class="el-link el-link--default"
>{{ article.title }}</nuxt-link
>
</div>
<el-empty v-else> </el-empty>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import { listArticle } from '~/api/article'
export default {
name: 'PageArticleIndex',
data() {
return {
total: 100,
size: 10,
query: {
page: 1,
},
populars: [],
articles: [],
}
},
computed: {
...mapGetters('setting', ['settings']),
...mapGetters('device', ['isMobile']),
},
watch: {
$route: {
handler() {
let page = this.$route.query.page || 1
this.query.page = parseInt(page) || 1
this.getArticles()
},
immediate: true,
},
},
async created() {
await Promise.all([this.getArticles(), this.getPopulars()])
},
methods: {
pageChange(page) {
this.query.page = page
this.$router.push({
path: this.$route.path,
query: this.query,
})
},
async getArticles() {
const res = await listArticle({ size: this.size, page: this.query.page })
if (res.status !== 200) {
this.$message.error(res.data.message || '获取文章列表失败')
return
}
this.articles = res.data.article || []
this.total = res.data.total || 0
},
async getPopulars() {
const res = await listArticle({
page: 1,
size: 5,
order: 'view_count desc',
})
if (res.status !== 200) {
this.$message.error(res.data.message || '获取热门文章失败')
return
}
this.populars = res.data.article || []
},
},
}
</script>
<style lang="scss">
.page-article-index {
.el-card__body {
padding-top: 0;
padding-bottom: 0;
.el-pagination {
padding: 20px 0;
border-top: 1px dashed #efefef;
}
}
.popular {
a {
display: block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
height: 40px;
line-height: 40px;
border-bottom: 1px dashed #efefef;
&:last-of-type {
border-bottom: 0;
}
}
}
}
</style>
Loading…
Cancel
Save