mirror of https://github.com/halo-dev/halo
refactor: post list component code optimization (halo-dev/console#445)
Signed-off-by: Ryan Wang <i@ryanc.cc>pull/3445/head
parent
f33dfed835
commit
2f775241b7
|
@ -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: '私密'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue