Files
schoolNews/schoolNewsWeb/src/views/admin/manage/resource/ArticleManagementView.vue

277 lines
7.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<AdminLayout
title="资源管理"
subtitle="管理文章、资源、数据等内容"
>
<div class="article-management">
<div class="action-bar">
<el-button type="primary" @click="showCreateDialog">+ 新增文章</el-button>
<el-input
v-model="searchKeyword"
placeholder="搜索文章..."
style="width: 300px"
onkeydown=""
clearable
/>
</div>
<el-table :data="articles" style="width: 100%">
<el-table-column prop="title" label="文章标题" min-width="200" />
<el-table-column prop="category" label="分类" width="120" />
<el-table-column prop="author" label="作者" width="120" />
<el-table-column prop="publishTime" label="发布日期" width="120" />
<el-table-column prop="views" label="阅读量" width="100" />
<el-table-column prop="status" label="状态" width="100">
<template #default="{ row }">
<el-tag :type="getStatusType(row.status)">
{{ getStatusText(row.status) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="250" fixed="right">
<template #default="{ row }">
<el-button size="small" @click="viewArticle(row)">查看</el-button>
<el-button
size="small"
:type="getActionButtonType(row.status)"
@click="changeArticleStatus(row)"
>
{{ getActionButtonText(row.status) }}
</el-button>
<el-button size="small" @click="editArticle(row)">编辑</el-button>
<el-button size="small" type="danger" @click="deleteArticle()">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
v-model:current-page="pageParam.pageNumber"
v-model:page-size="pageParam.pageSize"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
<!-- 文章查看弹窗 -->
<ArticleShowView
v-model="showViewDialog"
:as-dialog="true"
title="文章详情"
width="900px"
:article-data="currentArticle"
:category-list="categoryList"
:show-edit-button="true"
@edit="handleEditFromView"
@close="showViewDialog = false"
/>
</div>
</AdminLayout>
</template>
<script setup lang="ts">
import { AdminLayout } from '@/views/admin';
defineOptions({
name: 'ArticleManagementView'
});
import { ref, onMounted } from 'vue';
import { ElButton, ElInput, ElTable, ElTableColumn, ElTag, ElPagination, ElMessage } from 'element-plus';
import { useRouter } from 'vue-router';
import { resourceApi, resourceTagApi } from '@/apis/resource'
import type { PageParam, ResourceSearchParams, Resource, Tag } from '@/types';
import { ArticleShowView } from '@/views/public/article';
import { ArticleStatus } from '@/types/enums';
const router = useRouter();
const searchKeyword = ref('');
const pageParam = ref<PageParam>({
pageNumber: 1,
pageSize: 10
});
const filter = ref<ResourceSearchParams>({
keyword: searchKeyword.value
});
const total = ref<number>(0);
const articles = ref<Resource[]>([]);
const showViewDialog = ref(false);
const currentArticle = ref<any>(null);
const categoryList = ref<Tag[]>([]); // 改为使用Tag类型tagType=1表示文章分类
onMounted(() => {
loadArticles();
loadCategories();
});
async function loadCategories() {
try {
// 使用新的标签API获取文章分类标签tagType=1
const res = await resourceTagApi.getTagsByType(1); // 1 = 文章分类标签
if (res.success && res.dataList) {
categoryList.value = res.dataList;
}
} catch (error) {
console.error('加载分类列表失败:', error);
}
}
async function loadArticles() {
const res = await resourceApi.getResourcePage(pageParam.value, filter.value);
if (res.success) {
articles.value = res.pageDomain?.dataList || [];
total.value = res.pageDomain?.pageParam.totalElements || 0;
}
}
function showCreateDialog() {
// 尝试跳转
router.push('/article/add')
.then(() => {
console.log('路由跳转成功!');
console.log('跳转后路由:', router.currentRoute.value.fullPath);
})
.catch(err => {
console.error('路由跳转失败:', err);
});
}
function handleDataCollection() {
// TODO: 数据采集功能
ElMessage.info('数据采集功能开发中');
}
async function viewArticle(row: any) {
try {
const res = await resourceApi.getResourceById(row.resourceID);
if (res.success && res.data) {
// 将 ResourceVO 转换为 ArticleShowView 期望的格式
const resourceVO = res.data;
currentArticle.value = {
...resourceVO.resource,
tags: resourceVO.tags || []
};
showViewDialog.value = true;
} else {
ElMessage.error('获取文章详情失败');
}
} catch (error) {
ElMessage.error('获取文章详情失败');
console.error(error);
}
}
function editArticle(row: any) {
router.push('/article/add?id=' + row.resourceID);
}
async function changeArticleStatus(row: Resource) {
try {
// status: 0-草稿, 1-已发布, 2-已下架
if (row.status === ArticleStatus.DRAFT || row.status === ArticleStatus.OFFLINE) {
// 草稿或下架状态 -> 发布
const res = await resourceApi.publishResource(row.resourceID!);
if (res.success) {
ElMessage.success('发布成功');
loadArticles();
} else {
ElMessage.error('发布失败');
}
} else if (row.status === ArticleStatus.PUBLISHED) {
// 已发布状态 -> 下架
const res = await resourceApi.unpublishResource(row.resourceID!);
if (res.success) {
ElMessage.success('下架成功');
loadArticles();
} else {
ElMessage.error('下架失败');
}
}
} catch (error) {
console.error('操作失败:', error);
ElMessage.error('操作失败');
}
}
function handleEditFromView() {
if (currentArticle.value?.resourceID) {
showViewDialog.value = false;
router.push('/article/add?id=' + currentArticle.value.resourceID);
}
}
function deleteArticle() {
// TODO: 删除文章
ElMessage.info('删除功能开发中');
}
function getStatusType(status: number) {
const typeMap: Record<number, any> = {
[ArticleStatus.DRAFT]: 'info',
[ArticleStatus.PUBLISHED]: 'success',
[ArticleStatus.OFFLINE]: 'warning',
[ArticleStatus.FAILED]: 'danger'
};
return typeMap[status] || 'info';
}
function getStatusText(status: number) {
const textMap: Record<number, string> = {
[ArticleStatus.DRAFT]: '草稿',
[ArticleStatus.PUBLISHED]: '已发布',
[ArticleStatus.OFFLINE]: '已下架',
[ArticleStatus.FAILED]: '审核失败'
};
return textMap[status] || '未知';
}
function getActionButtonType(status: number) {
// 草稿或下架状态显示主要按钮(发布), 已发布状态显示警告按钮(下架)
if (status === ArticleStatus.DRAFT || status === ArticleStatus.OFFLINE || status === ArticleStatus.FAILED) {
return 'primary';
} else if (status === ArticleStatus.PUBLISHED) {
return 'warning';
}
return '';
}
function getActionButtonText(status: number) {
// 草稿或下架状态显示"发布", 已发布状态显示"下架"
if (status === ArticleStatus.DRAFT || status === ArticleStatus.OFFLINE || status === ArticleStatus.FAILED) {
return '发布';
} else if (status === ArticleStatus.PUBLISHED) {
return '下架';
}
return '操作';
}
function handleSizeChange(val: number) {
pageParam.value.pageSize = val;
loadArticles();
}
function handleCurrentChange(val: number) {
pageParam.value.pageNumber = val;
loadArticles();
}
</script>
<style lang="scss" scoped>
.article-management {
background: #FFFFFF;
padding: 24px;
border-radius: 14px;
}
.action-bar {
display: flex;
gap: 16px;
margin-bottom: 20px;
align-items: center;
}
.el-table {
margin-bottom: 20px;
}
</style>