refactor: post list component code optimization (halo-dev/console#445)

Signed-off-by: Ryan Wang <i@ryanc.cc>
pull/3445/head
Ryan Wang 2022-02-21 13:59:10 +08:00 committed by GitHub
parent f33dfed835
commit 2f775241b7
2 changed files with 216 additions and 200 deletions

View File

@ -95,3 +95,30 @@ export const attachmentTypes = {
text: 'MinIO' text: 'MinIO'
} }
} }
export const postStatuses = {
PUBLISHED: {
value: 'PUBLISHED',
color: 'green',
status: 'success',
text: '已发布'
},
DRAFT: {
value: 'DRAFT',
color: 'yellow',
status: 'warning',
text: '草稿'
},
RECYCLE: {
value: 'RECYCLE',
color: 'red',
status: 'error',
text: '回收站'
},
INTIMATE: {
value: 'INTIMATE',
color: 'blue',
status: 'success',
text: '私密'
}
}

View File

@ -12,8 +12,8 @@
<a-col :md="6" :sm="24"> <a-col :md="6" :sm="24">
<a-form-item label="文章状态:"> <a-form-item label="文章状态:">
<a-select v-model="list.params.status" allowClear placeholder="请选择文章状态" @change="handleQuery()"> <a-select v-model="list.params.status" allowClear placeholder="请选择文章状态" @change="handleQuery()">
<a-select-option v-for="status in Object.keys(postStatus)" :key="status" :value="status"> <a-select-option v-for="status in Object.keys(postStatuses)" :key="status" :value="status">
{{ postStatus[status].text }} {{ postStatuses[status].text }}
</a-select-option> </a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-item>
@ -51,25 +51,26 @@
<a-button icon="plus" type="primary">写文章</a-button> <a-button icon="plus" type="primary">写文章</a-button>
</router-link> </router-link>
<a-dropdown v-show="list.params.status != null && list.params.status !== '' && !isMobile()"> <a-dropdown v-show="list.params.status != null && list.params.status !== '' && !isMobile()">
<a-menu slot="overlay"> <template #overlay>
<a-menu>
<a-menu-item <a-menu-item
v-if="['DRAFT', 'RECYCLE'].includes(list.params.status)" v-if="['DRAFT', 'RECYCLE'].includes(list.params.status)"
key="1" key="1"
@click="handleEditStatusMore(postStatus.PUBLISHED.value)" @click="handleEditStatusMore(postStatuses.PUBLISHED.value)"
> >
发布 发布
</a-menu-item> </a-menu-item>
<a-menu-item <a-menu-item
v-if="['PUBLISHED', 'DRAFT', 'INTIMATE'].includes(list.params.status)" v-if="['PUBLISHED', 'DRAFT', 'INTIMATE'].includes(list.params.status)"
key="2" key="2"
@click="handleEditStatusMore(postStatus.RECYCLE.value)" @click="handleEditStatusMore(postStatuses.RECYCLE.value)"
> >
移到回收站 移到回收站
</a-menu-item> </a-menu-item>
<a-menu-item <a-menu-item
v-if="['RECYCLE', 'PUBLISHED', 'INTIMATE'].includes(list.params.status)" v-if="['RECYCLE', 'PUBLISHED', 'INTIMATE'].includes(list.params.status)"
key="3" key="3"
@click="handleEditStatusMore(postStatus.DRAFT.value)" @click="handleEditStatusMore(postStatuses.DRAFT.value)"
> >
草稿 草稿
</a-menu-item> </a-menu-item>
@ -77,6 +78,7 @@
永久删除 永久删除
</a-menu-item> </a-menu-item>
</a-menu> </a-menu>
</template>
<a-button class="ml-2"> <a-button class="ml-2">
批量操作 批量操作
<a-icon type="down" /> <a-icon type="down" />
@ -87,14 +89,15 @@
<!-- Mobile --> <!-- Mobile -->
<a-list <a-list
v-if="isMobile()" v-if="isMobile()"
:dataSource="formattedPosts" :dataSource="list.data"
:loading="list.loading" :loading="list.loading"
:pagination="false" :pagination="false"
itemLayout="vertical" itemLayout="vertical"
size="large" size="large"
> >
<a-list-item :key="index" slot="renderItem" slot-scope="item, index"> <template #renderItem="item, index">
<template slot="actions"> <a-list-item :key="index">
<template #actions>
<span> <span>
<a-icon type="eye" /> <a-icon type="eye" />
{{ item.visits }} {{ item.visits }}
@ -107,7 +110,9 @@
<span> <span>
<a-icon type="bars" /> <a-icon type="bars" />
</span> </span>
<a-menu slot="overlay">
<template #overlay>
<a-menu>
<a-menu-item <a-menu-item
v-if="['PUBLISHED', 'DRAFT', 'INTIMATE'].includes(item.status)" v-if="['PUBLISHED', 'DRAFT', 'INTIMATE'].includes(item.status)"
@click="handleEditClick(item)" @click="handleEditClick(item)"
@ -146,15 +151,14 @@
</a-menu-item> </a-menu-item>
<a-menu-item @click="handleShowPostSettings(item)"></a-menu-item> <a-menu-item @click="handleShowPostSettings(item)"></a-menu-item>
</a-menu> </a-menu>
</template>
</a-dropdown> </a-dropdown>
</template> </template>
<template slot="extra"> <template #extra>
<span> <a-badge :status="postStatuses[item.status].status" :text="item.status | statusText" />
<a-badge :status="item.statusProperty.status" :text="item.statusProperty.text" />
</span>
</template> </template>
<a-list-item-meta> <a-list-item-meta>
<template slot="description"> <template #description>
{{ item.createTime | moment }} {{ item.createTime | moment }}
</template> </template>
<template #title> <template #title>
@ -174,6 +178,15 @@
twoToneColor="red" twoToneColor="red"
type="pushpin" type="pushpin"
/> />
<a-tooltip v-if="item.inProgress" placement="top" title="当前有内容已保存,但还未发布。">
<a-icon
class="cursor-pointer"
style="margin-right: 3px"
theme="twoTone"
twoToneColor="#52c41a"
type="info-circle"
/>
</a-tooltip>
<a-tooltip <a-tooltip
v-if="['PUBLISHED', 'INTIMATE'].includes(item.status)" v-if="['PUBLISHED', 'INTIMATE'].includes(item.status)"
:title="'点击访问【' + item.title + '】'" :title="'点击访问【' + item.title + '】'"
@ -188,9 +201,9 @@
:title="'点击预览【' + item.title + '】'" :title="'点击预览【' + item.title + '】'"
placement="top" placement="top"
> >
<a-button class="!p-0" type="link" @click="handlePreview(item.id)"> <a class="no-underline" href="javascript:void(0);" @click="handlePreview(item.id)">
{{ item.title }} {{ item.title }}
</a-button> </a>
</a-tooltip> </a-tooltip>
<a-button v-else class="!p-0" disabled type="link"> <a-button v-else class="!p-0" disabled type="link">
{{ item.title }} {{ item.title }}
@ -198,9 +211,12 @@
</div> </div>
</template> </template>
</a-list-item-meta> </a-list-item-meta>
<div v-if="item.summary" class="mb-3 block">
<span> {{ item.summary }}... </span> <span> {{ item.summary }}... </span>
<br /> </div>
<br />
<div class="block">
<a-tag <a-tag
v-for="(category, categoryIndex) in item.categories" v-for="(category, categoryIndex) in item.categories"
:key="'category_' + categoryIndex" :key="'category_' + categoryIndex"
@ -209,16 +225,17 @@
@click="handleSelectCategory(category)" @click="handleSelectCategory(category)"
>{{ category.name }} >{{ category.name }}
</a-tag> </a-tag>
<br /> </div>
<post-tag v-for="(tag, tagIndex) in item.tags" :key="tagIndex" :tag="tag" style="margin-bottom: 8px" /> <post-tag v-for="(tag, tagIndex) in item.tags" :key="tagIndex" :tag="tag" style="margin-bottom: 8px" />
</a-list-item> </a-list-item>
</template>
</a-list> </a-list>
<!-- Desktop --> <!-- Desktop -->
<a-table <a-table
v-else v-else
:columns="columns" :columns="columns"
:dataSource="formattedPosts" :dataSource="list.data"
:loading="list.loading" :loading="list.loading"
:pagination="false" :pagination="false"
:rowKey="post => post.id" :rowKey="post => post.id"
@ -264,13 +281,14 @@
{{ text }} {{ text }}
</a-button> </a-button>
</template> </template>
<span slot="status" slot-scope="statusProperty">
<a-badge :status="statusProperty.status" :text="statusProperty.text" />
</span>
<span slot="categories" slot-scope="categoriesOfPost"> <template #status="status">
<a-badge :status="postStatuses[status].status" :text="status | statusText" />
</template>
<template #categories="categories">
<a-tag <a-tag
v-for="(category, index) in categoriesOfPost" v-for="(category, index) in categories"
:key="index" :key="index"
color="blue" color="blue"
style="margin-bottom: 8px; cursor: pointer" style="margin-bottom: 8px; cursor: pointer"
@ -278,52 +296,50 @@
> >
{{ category.name }} {{ category.name }}
</a-tag> </a-tag>
</span> </template>
<template #tags="tags"> <template #tags="tags">
<post-tag v-for="(tag, index) in tags" :key="index" :tag="tag" style="margin-bottom: 8px" /> <post-tag v-for="(tag, index) in tags" :key="index" :tag="tag" style="margin-bottom: 8px" />
</template> </template>
<span <template #commentCount="text, record">
slot="commentCount"
slot-scope="text, record"
style="cursor: pointer"
@click="handleShowPostComments(record)"
>
<a-badge <a-badge
:count="record.commentCount" :count="record.commentCount"
:numberStyle="{ backgroundColor: '#f38181' }" :numberStyle="{ backgroundColor: '#f38181' }"
:overflowCount="999" :overflowCount="999"
:showZero="true" :showZero="true"
class="cursor-pointer"
@click="handleShowPostComments(record)"
/> />
</span> </template>
<span slot="visits" slot-scope="visits"> <template #visits="visits">
<a-badge <a-badge
:count="visits" :count="visits"
:numberStyle="{ backgroundColor: '#00e0ff' }" :numberStyle="{ backgroundColor: '#00e0ff' }"
:overflowCount="9999" :overflowCount="9999"
:showZero="true" :showZero="true"
class="cursor-pointer"
/> />
</span> </template>
<span slot="createTime" slot-scope="createTime"> <template #createTime="createTime">
<a-tooltip placement="top"> <a-tooltip placement="top">
<template slot="title"> <template #title>
{{ createTime | moment }} {{ createTime | moment }}
</template> </template>
{{ createTime | timeAgo }} {{ createTime | timeAgo }}
</a-tooltip> </a-tooltip>
</span> </template>
<span slot="action" slot-scope="text, post"> <template #action="text, post">
<a-button <a-button
v-if="['PUBLISHED', 'DRAFT', 'INTIMATE'].includes(post.status)" v-if="['PUBLISHED', 'DRAFT', 'INTIMATE'].includes(post.status)"
class="!p-0" class="!p-0"
type="link" type="link"
@click="handleEditClick(post)" @click="handleEditClick(post)"
>编辑</a-button >编辑
> </a-button>
<a-popconfirm <a-popconfirm
v-else-if="post.status === 'RECYCLE'" v-else-if="post.status === 'RECYCLE'"
:title="'你确定要发布【' + post.title + '】文章?'" :title="'你确定要发布【' + post.title + '】文章?'"
@ -359,7 +375,7 @@
<a-divider type="vertical" /> <a-divider type="vertical" />
<a-button class="!p-0" type="link" @click="handleShowPostSettings(post)"></a-button> <a-button class="!p-0" type="link" @click="handleShowPostSettings(post)"></a-button>
</span> </template>
</a-table> </a-table>
<div class="page-wrapper"> <div class="page-wrapper">
<a-pagination <a-pagination
@ -407,6 +423,7 @@ import { PageView } from '@/layouts'
import PostSettingModal from './components/PostSettingModal.vue' import PostSettingModal from './components/PostSettingModal.vue'
import TargetCommentDrawer from '../comment/components/TargetCommentDrawer' import TargetCommentDrawer from '../comment/components/TargetCommentDrawer'
import apiClient from '@/utils/api-client' import apiClient from '@/utils/api-client'
import { postStatuses } from '@/core/constant'
const columns = [ const columns = [
{ {
@ -418,8 +435,7 @@ const columns = [
}, },
{ {
title: '状态', title: '状态',
className: 'status', dataIndex: 'status',
dataIndex: 'statusProperty',
width: '100px', width: '100px',
scopedSlots: { customRender: 'status' } scopedSlots: { customRender: 'status' }
}, },
@ -457,32 +473,6 @@ const columns = [
scopedSlots: { customRender: 'action' } scopedSlots: { customRender: 'action' }
} }
] ]
const postStatus = {
PUBLISHED: {
value: 'PUBLISHED',
color: 'green',
status: 'success',
text: '已发布'
},
DRAFT: {
value: 'DRAFT',
color: 'yellow',
status: 'warning',
text: '草稿'
},
RECYCLE: {
value: 'RECYCLE',
color: 'red',
status: 'error',
text: '回收站'
},
INTIMATE: {
value: 'INTIMATE',
color: 'blue',
status: 'success',
text: '私密'
}
}
export default { export default {
name: 'PostList', name: 'PostList',
components: { components: {
@ -493,8 +483,8 @@ export default {
mixins: [mixin, mixinDevice], mixins: [mixin, mixinDevice],
data() { data() {
return { return {
postStatus,
columns, columns,
postStatuses,
list: { list: {
data: [], data: [],
loading: false, loading: false,
@ -523,12 +513,6 @@ export default {
} }
}, },
computed: { computed: {
formattedPosts() {
return this.list.data.map(post => {
post.statusProperty = this.postStatus[post.status]
return post
})
},
pagination() { pagination() {
return { return {
page: this.list.params.page + 1, page: this.list.params.page + 1,
@ -799,6 +783,11 @@ export default {
this.postSettingLoading = false this.postSettingLoading = false
} }
} }
},
filters: {
statusText(type) {
return type ? postStatuses[type].text : ''
}
} }
} }
</script> </script>