u
This commit is contained in:
1 parent
5221d1cc91
commit
a8a2657753
30 files changed
+552
-255
No files matched your search
@@ -1,30 +1,96 @@
|
||||
<script lang="ts" setup>
|
||||
import type { CollapseModelValue } from 'element-plus'
|
||||
import type { PostTag } from '@/types/base'
|
||||
import { Search } from '@element-plus/icons-vue'
|
||||
import { ref } from 'vue'
|
||||
|
||||
import CustomEmpty from '@/components/CustomEmpty.vue'
|
||||
import SvgIcon from '@/components/SvgIcon.vue'
|
||||
import { useCommonStore } from '@/store/common'
|
||||
|
||||
const { postTagOptions } = useCommonStore()
|
||||
|
||||
const activeNames = ref(['1'])
|
||||
const selectedTag = ref<PostTag>(postTagOptions[0])
|
||||
|
||||
function handleChange(val: CollapseModelValue) {
|
||||
console.log(val)
|
||||
function handleChangeSelectedTag(tag: PostTag) {
|
||||
selectedTag.value = tag
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="post-wrapper">
|
||||
<div class="sidebar">
|
||||
<div class="post-sidebar">
|
||||
<el-collapse v-model="activeNames" expand-icon-position="left">
|
||||
<el-collapse-item title="标签" name="1">
|
||||
<ul class="sidebar-tags">
|
||||
<li class="sidebar-tag">
|
||||
<SvgIcon icon="streamline-color:earth-airplane" :size="18" />
|
||||
<span class="sidebar-tag-text">空运</span>
|
||||
<ul class="tag-list">
|
||||
<li
|
||||
v-for="item in postTagOptions"
|
||||
:key="item.id"
|
||||
class="tag-item"
|
||||
:class="{ active: selectedTag.id === item.id }"
|
||||
@click="handleChangeSelectedTag(item)"
|
||||
>
|
||||
<SvgIcon v-if="item.icon" :icon="item.icon" />
|
||||
<span class="tag-item-text">{{ item.name }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</div>
|
||||
|
||||
<div class="post-main">
|
||||
<div class="post-main-header">
|
||||
<el-input
|
||||
:prefix-icon="Search"
|
||||
placeholder="搜索" size="large"
|
||||
/>
|
||||
<div class="post-pagination">
|
||||
<el-pagination layout="prev, pager, next,jumper" background :total="1000" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="post-content">
|
||||
<!-- <CustomEmpty :in-container="true" /> -->
|
||||
|
||||
<div class="post-list">
|
||||
<div v-for="i in 20" :key="i" class="post-item">
|
||||
<div class="post-title-row">
|
||||
<div class="post-title">
|
||||
新项目为什么推荐WebFlux,而非SpringMVC?
|
||||
</div>
|
||||
</div>
|
||||
<div class="post-meta">
|
||||
<div class="post-meta-actions">
|
||||
<div class="post-meta-item">
|
||||
<div>刘大华</div>
|
||||
</div>
|
||||
|
||||
<div class="post-meta-divider" />
|
||||
|
||||
<div class="post-meta-item">
|
||||
<SvgIcon icon="mdi:eye-outline" />
|
||||
<span>1.7k</span>
|
||||
</div>
|
||||
<div class="post-meta-item">
|
||||
<SvgIcon icon="iconamoon:comment" />
|
||||
<span>1.7k</span>
|
||||
</div>
|
||||
|
||||
<div class="post-meta-divider" />
|
||||
|
||||
<div class="post-meta-item">
|
||||
<div>20分钟前</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="post-meta-tags">
|
||||
<div class="post-tag">
|
||||
后端
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -33,7 +99,8 @@ function handleChange(val: CollapseModelValue) {
|
||||
display: flex;
|
||||
padding: 0px 240px;
|
||||
background-color: #fff;
|
||||
.sidebar {
|
||||
|
||||
.post-sidebar {
|
||||
background-color: #fff;
|
||||
height: calc(100vh - var(--header-height));
|
||||
font-size: 16px;
|
||||
@@ -45,12 +112,12 @@ function handleChange(val: CollapseModelValue) {
|
||||
width: 240px;
|
||||
padding: 0px 16px;
|
||||
|
||||
.sidebar-tags {
|
||||
.tag-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
|
||||
.sidebar-tag {
|
||||
.tag-item {
|
||||
height: 32px;
|
||||
display: inline-flex;
|
||||
width: 100%;
|
||||
@@ -59,24 +126,130 @@ function handleChange(val: CollapseModelValue) {
|
||||
cursor: pointer;
|
||||
padding: 0px 16px;
|
||||
font-size: 16px;
|
||||
transition:
|
||||
background-color 0.2s ease,
|
||||
color 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
.sidebar-tag-text {
|
||||
.tag-item-text {
|
||||
margin-left: 12px;
|
||||
color: #646464;
|
||||
transition:
|
||||
color 0.2s ease,
|
||||
transform 0.2s ease;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #f2f2f2;
|
||||
.tag-item-text {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.post-main {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
.post-main-header {
|
||||
position: sticky;
|
||||
top: calc(var(--header-height));
|
||||
background-color: #fff;
|
||||
padding: 8px 16px 0px 16px;
|
||||
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.06);
|
||||
|
||||
.post-pagination {
|
||||
padding: 12px 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.post-content {
|
||||
padding-bottom: 36px;
|
||||
}
|
||||
|
||||
.post-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.post-item {
|
||||
padding: 12px 16px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
|
||||
.post-title-row {
|
||||
display: flex;
|
||||
margin-bottom: 8px;
|
||||
.post-title {
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
color: #252933;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.post-meta {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
flex-wrap: wrap;
|
||||
.post-meta-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.post-meta-item {
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
color: #8a919f;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
& + .post-meta-item {
|
||||
margin-left: 12px;
|
||||
}
|
||||
span {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.post-meta-divider {
|
||||
width: 1px;
|
||||
height: 12px;
|
||||
background-color: #e4e6eb;
|
||||
margin: 0 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.post-meta-tags {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
.post-tag {
|
||||
background-color: #f2f3f5;
|
||||
padding: 0 6px;
|
||||
border-radius: 2px;
|
||||
max-width: 65px;
|
||||
box-sizing: border-box;
|
||||
margin-left: 6px;
|
||||
color: #8a919f;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
min-height: 18px;
|
||||
line-height: 18px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
.post-list {
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
@@ -8,10 +8,12 @@ import { computed, nextTick, onMounted, reactive, ref } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import CustomLoading from '@/components/CustomLoading.vue'
|
||||
import WangEditor from '@/components/wang-editor/index.vue'
|
||||
import { addPostApi, getPostApi, getPostCategoryApi, getPostTagApi, updatePostApi } from '@/request/api/post'
|
||||
import { createPostApi, getEditorPostApi, updatePostApi } from '@/request/api/post/editor'
|
||||
import { useCommonStore } from '@/store/common'
|
||||
import { PostStatusEnum } from '@/types/post/editor'
|
||||
|
||||
const route = useRoute()
|
||||
const { postTagOptions } = useCommonStore()
|
||||
|
||||
const titleInputRef = ref<HTMLInputElement | null>(null)
|
||||
const wangEditorRef = ref<any>(null)
|
||||
@@ -25,9 +27,6 @@ const loading = reactive({
|
||||
const showPushDrawer = ref<boolean>(false)
|
||||
const imageUpload = ref<UploadImageResponse | null>(null)
|
||||
|
||||
const tagOptions = ref<PostTag[]>([])
|
||||
const categoryOptions = ref<PostCategory[]>([])
|
||||
|
||||
const statusOptions = [
|
||||
{
|
||||
label: '草稿',
|
||||
@@ -78,7 +77,7 @@ onMounted(() => {
|
||||
if (id) {
|
||||
loading.init = true
|
||||
|
||||
getPostApi(id).then((res) => {
|
||||
getEditorPostApi(id).then((res) => {
|
||||
if (res.isSuccess) {
|
||||
form.value = res.data
|
||||
oldForm.value = JSON.parse(JSON.stringify(res.data))
|
||||
@@ -102,19 +101,6 @@ onMounted(() => {
|
||||
async function handleShowPushDrawer() {
|
||||
loading.init = true
|
||||
showPushDrawer.value = true
|
||||
|
||||
await getPostTagApi().then((res) => {
|
||||
if (res.isSuccess) {
|
||||
tagOptions.value = res.data
|
||||
}
|
||||
else {
|
||||
ElMessage.error(res.message || '获取帖子标签失败,请稍后再试')
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log(err)
|
||||
ElMessage.error('获取帖子标签失败,请稍后再试')
|
||||
})
|
||||
|
||||
loading.init = false
|
||||
}
|
||||
|
||||
@@ -146,7 +132,7 @@ async function handleSave(formEl?: FormInstance) {
|
||||
|
||||
const res = isUpdate.value
|
||||
? await updatePostApi({ id: form.value.id, ...payload })
|
||||
: await addPostApi(payload)
|
||||
: await createPostApi(payload)
|
||||
|
||||
if (!res.isSuccess) {
|
||||
ElMessage.error(
|
||||
@@ -215,7 +201,7 @@ async function handleSave(formEl?: FormInstance) {
|
||||
<el-form-item label="标签" prop="tags">
|
||||
<el-select v-model="form.tags" multiple placeholder="请选择标签">
|
||||
<el-option
|
||||
v-for="item in tagOptions"
|
||||
v-for="item in postTagOptions"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.name"
|
||||
|
||||
@@ -6,7 +6,7 @@ import { onMounted, reactive, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import CustomLoading from '@/components/CustomLoading.vue'
|
||||
import SvgIcon from '@/components/SvgIcon.vue'
|
||||
import { deletePostApi, queryPostApi, updatePostStatusApi } from '@/request/api/post'
|
||||
import { deletePostApi, queryEditorPostsApi, updatePostStatusApi } from '@/request/api/post/editor'
|
||||
import { PostStatusEnum } from '@/types/post/editor'
|
||||
|
||||
const router = useRouter()
|
||||
@@ -89,7 +89,7 @@ onMounted(() => {
|
||||
|
||||
function queryPost() {
|
||||
loading.value = true
|
||||
queryPostApi({
|
||||
queryEditorPostsApi({
|
||||
...queryForm,
|
||||
currentPage: page.current,
|
||||
pageSize: page.pageSize,
|
||||
|
||||
@@ -295,11 +295,9 @@ const activeCollapseNames = ref(['1', '2', '3'])
|
||||
background-color: #fff;
|
||||
|
||||
:deep(.el-button) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: none;
|
||||
width: 360px;
|
||||
height: 40px;
|
||||
border-radius: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user