数据结构优化
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
<th class="w-20">ID</th>
|
||||
<th>标题</th>
|
||||
<th>分类</th>
|
||||
<th>专栏</th>
|
||||
<th>标签</th>
|
||||
<th>发布日期</th>
|
||||
<th>状态</th>
|
||||
<th class="text-right">操作</th>
|
||||
@@ -26,6 +28,25 @@
|
||||
<td class="font-mono text-xs text-white/40">#{{ post.id }}</td>
|
||||
<td class="font-medium text-white group-hover:text-art-accent transition-colors">{{ post.title }}</td>
|
||||
<td><span class="px-2 py-1 rounded bg-white/5 border border-white/5 text-xs text-art-muted">{{ post.categoryName || post.category?.name || '未分类' }}</span></td>
|
||||
<td>
|
||||
<span v-if="post.columnName || post.column?.name" class="px-2 py-1 rounded bg-art-accent/10 border border-art-accent/20 text-xs text-art-accent">
|
||||
{{ post.columnName || post.column?.name }}
|
||||
</span>
|
||||
<span v-else class="text-art-muted text-xs">-</span>
|
||||
</td>
|
||||
<td>
|
||||
<div v-if="post.tags && post.tags.length > 0" class="flex flex-wrap gap-1">
|
||||
<span
|
||||
v-for="tag in post.tags.slice(0, 3)"
|
||||
:key="tag.id"
|
||||
class="px-2 py-0.5 rounded bg-white/5 border border-white/5 text-xs text-art-muted"
|
||||
>
|
||||
#{{ tag.name }}
|
||||
</span>
|
||||
<span v-if="post.tags.length > 3" class="text-art-muted text-xs">+{{ post.tags.length - 3 }}</span>
|
||||
</div>
|
||||
<span v-else class="text-art-muted text-xs">-</span>
|
||||
</td>
|
||||
<td class="text-art-muted text-xs">{{ post.date }}</td>
|
||||
<td>
|
||||
<button
|
||||
@@ -38,6 +59,9 @@
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<div class="flex items-center justify-end gap-2 opacity-0 group-hover:opacity-100 transition-opacity duration-200">
|
||||
<button @click="openRelationModal(post)" class="admin-btn-secondary py-1 px-3 text-xs">
|
||||
管理
|
||||
</button>
|
||||
<router-link :to="`/admin/posts/${post.id}/edit`" class="admin-btn-secondary py-1 px-3 text-xs">
|
||||
编辑
|
||||
</router-link>
|
||||
@@ -61,33 +85,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Category Modal -->
|
||||
<div v-if="isCategoryModalOpen" class="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm" @click.self="closeCategoryModal">
|
||||
<div class="bg-[#1a1a1a] border border-white/10 rounded-lg shadow-xl w-full max-w-md overflow-hidden animate-reveal">
|
||||
<div class="p-4 border-b border-white/10 flex justify-between items-center">
|
||||
<h3 class="text-lg font-serif italic text-white">修改文章分类</h3>
|
||||
<button @click="closeCategoryModal" class="text-white/50 hover:text-white">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="p-6 space-y-4">
|
||||
<p class="text-sm text-art-muted">正在修改文章: <span class="text-white">{{ editingPost?.title }}</span></p>
|
||||
|
||||
<div class="space-y-2">
|
||||
<label class="block text-xs font-medium text-art-muted uppercase tracking-wider">选择分类</label>
|
||||
<CustomSelect
|
||||
v-model="selectedCategoryId"
|
||||
:options="categories"
|
||||
placeholder="请选择分类"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-4 border-t border-white/10 flex justify-end gap-3 bg-white/5">
|
||||
<button @click="closeCategoryModal" class="px-4 py-2 text-sm text-white/70 hover:text-white transition-colors">取消</button>
|
||||
<button @click="saveCategory" class="admin-btn-primary py-1.5 px-4 text-sm">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Post Relation Modal -->
|
||||
<PostRelationModal
|
||||
v-model:isOpen="isRelationModalOpen"
|
||||
:post="editingPost"
|
||||
@saved="fetchPosts"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -96,10 +99,18 @@ import { ref, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { getAdminPosts, deletePost as deletePostApi, Post, togglePostStatus } from '../../services/api'
|
||||
import { useToast } from '../../composables/useToast'
|
||||
import PostRelationModal from '../../components/admin/PostRelationModal.vue'
|
||||
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
const posts = ref<Post[]>([])
|
||||
const isRelationModalOpen = ref(false)
|
||||
const editingPost = ref<Post | null>(null)
|
||||
|
||||
const openRelationModal = (post: Post) => {
|
||||
editingPost.value = post
|
||||
isRelationModalOpen.value = true
|
||||
}
|
||||
|
||||
const fetchPosts = async () => {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user