feat: 添加分类树接口和分页组件,优化留言板功能
refactor: 重构文章服务和留言服务API调用方式 fix: 修复token验证逻辑和全局状态管理问题 style: 更新页脚样式和关于页面内容 docs: 添加类型定义和接口注释
This commit is contained in:
@@ -15,11 +15,11 @@
|
||||
<div v-if="article.marked" class="article-special-tag">标记文章</div>
|
||||
<p class="article-content-preview">{{ formatContentPreview(article.content, 150) }}</p>
|
||||
<div class="article-meta-info">
|
||||
<span class="article-publish-date">{{ formatRelativeTime(article.createdAt || article.createTime) }}</span>
|
||||
<span v-if="article.categoryName" class="article-category-badge">{{ article.categoryName }} </span>
|
||||
<span v-if="article.viewCount" class="article-views-count">{{ article.viewCount }} 阅读</span>
|
||||
<span class="article-publish-date">{{ formatRelativeTime(article.createtime || article.createtime) }}</span>
|
||||
<span v-if="article.attributename" class="article-category-badge">{{ article.attributename }} </span>
|
||||
<span v-if="article.viewcount" class="article-views-count">{{ article.viewcount }} 阅读</span>
|
||||
<span v-if="article.likes > 0" class="article-likes-count">{{ article.likes }} 点赞</span>
|
||||
<span v-if="article.commentCount > 0" class="article-comments-count">{{ article.commentCount }} 评论</span>
|
||||
<span v-if="article.commentcount > 0" class="article-comments-count">{{ article.commentcount }} 评论</span>
|
||||
<div class="article-status-badge-container" v-if="globalStore.Login">
|
||||
<span v-if="article.status === 0" class="article-status-badge badge badge-warning">草稿</span>
|
||||
<span v-if="article.status === 1" class="article-status-badge badge badge-success">已发表</span>
|
||||
@@ -28,7 +28,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 分页区域 -->
|
||||
<el-pagination size="medium" background :layout="pageLayout" v-model:current-page="pageNum" hide-on-single-page="true" @current-change="changePage" :page-size="pageSize" :page-count="totalPages" class="mt-4" />
|
||||
<CustomPagination
|
||||
v-model:pageNum="pageNum"
|
||||
:pageSize="pageSize"
|
||||
:totalPages="totalPages"
|
||||
@pageChange="changePage"
|
||||
/>
|
||||
</transition-group>
|
||||
<!-- 空状态 -->
|
||||
<div v-if="!loading && articleList.length === 0" class="empty-state-container">
|
||||
@@ -44,8 +49,8 @@ import { formatRelativeTime } from '@/utils/dateUtils'
|
||||
import { formatContentPreview } from '@/utils/stringUtils'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { articleService, messageService, categoryAttributeService } from '@/services'
|
||||
import PaginationComponent from '@/views/page.vue'
|
||||
import { useGlobalStore } from '@/store/globalStore'
|
||||
import CustomPagination from '@/components/CustomPagination.vue'
|
||||
|
||||
// ========== 组件初始化 ==========
|
||||
|
||||
@@ -59,7 +64,6 @@ const route = useRoute()
|
||||
const pageNum = ref(1) // 当前页码
|
||||
const pageSize = ref(10) // 每页数量
|
||||
const totalPages = ref(0) // 总页数
|
||||
const pageLayout = ref('pager, next')// 分页布局
|
||||
|
||||
// 响应式状态
|
||||
const articleList = ref([])
|
||||
@@ -84,7 +88,6 @@ const getArticlesByRoute = async () => {
|
||||
// 检查URL参数,确定获取文章的方式
|
||||
const pathSegment = route.path.split('/')[2]
|
||||
// console.log('当前路由分段:', pathSegment)
|
||||
|
||||
switch (pathSegment) {
|
||||
case 'aericleattribute':
|
||||
// 按属性类型获取文章
|
||||
@@ -97,12 +100,13 @@ const getArticlesByRoute = async () => {
|
||||
case 'aericletitle':
|
||||
// 按标题搜索文章
|
||||
const titleData = globalStore.getValue('articleserarch')
|
||||
console.log('按标题搜索文章:', titleData.name)
|
||||
// console.log('按标题搜索文章:', titleData.name)
|
||||
return await articleService.getPagedArticles({title: titleData?.name}, pageNum.value, pageSize.value)
|
||||
case 'aericlestatus':
|
||||
// 按状态获取文章
|
||||
const statusData = globalStore.getValue('articlestatus')
|
||||
return await articleService.getPagedArticles({status: statusData?.status}, pageNum.value, pageSize.value)
|
||||
// console.log('按状态获取文章:', statusData.status)
|
||||
return await articleService.getPagedArticles({status: statusData.status}, pageNum.value, pageSize.value)
|
||||
default:
|
||||
// 默认获取所有文章
|
||||
// console.log('获取所有文章列表')
|
||||
@@ -110,50 +114,6 @@ const getArticlesByRoute = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 为单篇文章补充额外信息(留言数量、分类名称等)
|
||||
* @param {Object} article - 文章对象
|
||||
* @returns {Promise<Object>} 补充信息后的文章对象
|
||||
*/
|
||||
const enrichArticleWithExtraInfo = async (article) => {
|
||||
try {
|
||||
// 获取留言数量
|
||||
const messageResponse = await messageService.getMessagesByArticleId(article.articleid)
|
||||
// 获取分类名称
|
||||
const categoryResponse = await categoryAttributeService.getAttributeById(article.attributeid)
|
||||
|
||||
// 设置分类名称
|
||||
article.categoryName = categoryResponse?.data?.attributename || '未分类'
|
||||
// 设置评论数量
|
||||
article.commentCount = messageResponse?.data?.length || 0
|
||||
// 标准化标记字段名
|
||||
article.marked = article.mg
|
||||
|
||||
return article
|
||||
} catch (err) {
|
||||
console.error(`获取文章${article.articleid}额外信息失败:`, err)
|
||||
// 错误情况下设置默认值
|
||||
article.commentCount = 0
|
||||
article.categoryName = '未分类'
|
||||
return article
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量为文章列表补充额外信息
|
||||
* @param {Array} articles - 原始文章列表
|
||||
* @returns {Promise<Array>} 补充信息后的文章列表
|
||||
*/
|
||||
const enrichArticlesWithExtraInfo = async (articles) => {
|
||||
const enrichedArticles = []
|
||||
|
||||
for (const article of articles) {
|
||||
const enrichedArticle = await enrichArticleWithExtraInfo(article)
|
||||
enrichedArticles.push(enrichedArticle)
|
||||
}
|
||||
|
||||
return enrichedArticles
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -161,7 +121,6 @@ const enrichArticlesWithExtraInfo = async (articles) => {
|
||||
*/
|
||||
const fetchArticles = async () => {
|
||||
let response = {}
|
||||
|
||||
try {
|
||||
loading.value = true
|
||||
|
||||
@@ -170,16 +129,17 @@ const fetchArticles = async () => {
|
||||
// console.log('更新后的文章列表:', response)
|
||||
|
||||
// 2. 确保数据存在
|
||||
if (!response.data.content || !Array.isArray(response.data.content)) {
|
||||
if (!response.data || !Array.isArray(response.data)) {
|
||||
articleList.value = []
|
||||
totalPages.value = 0
|
||||
return
|
||||
}
|
||||
|
||||
// 3. 为文章列表补充额外信息
|
||||
const enrichedArticles = await enrichArticlesWithExtraInfo(response.data.content)
|
||||
|
||||
console.log('补充额外信息后的文章列表:', response.data)
|
||||
// 4. 更新文章列表
|
||||
articleList.value = enrichedArticles
|
||||
articleList.value = response.data
|
||||
// 5. 更新总页数
|
||||
totalPages.value = response.totalPages
|
||||
} catch (error) {
|
||||
console.error('获取文章列表失败:', error)
|
||||
ElMessage.error('获取文章列表失败,请稍后重试')
|
||||
@@ -197,13 +157,10 @@ const fetchArticles = async () => {
|
||||
const handleArticleClick = (article) => {
|
||||
try {
|
||||
// 增加文章浏览量(异步操作,不阻塞后续流程)
|
||||
articleService.incrementArticleViews(article.articleId).catch(err => {
|
||||
articleService.incrementArticleViews(article.articleid).catch(err => {
|
||||
console.error('增加文章浏览量失败:', err)
|
||||
})
|
||||
|
||||
// 清除之前的文章信息
|
||||
globalStore.removeValue('articleInfo')
|
||||
|
||||
// 存储文章信息到全局状态
|
||||
globalStore.setValue('articleInfo', article)
|
||||
|
||||
@@ -221,18 +178,8 @@ const handleArticleClick = (article) => {
|
||||
* @param {number} newPage - 新的页码
|
||||
*/
|
||||
const changePage = (newPage) => {
|
||||
pageNum.value = newPage
|
||||
fetchArticles()
|
||||
// 根据当前页码优化分页布局
|
||||
if (page === 1) {
|
||||
// 第一页只显示页码和下一页按钮
|
||||
pageLayout.value = 'pager, next'
|
||||
} else if (page === totalPages.value) {
|
||||
// 最后一页只显示上一页按钮和页码
|
||||
pageLayout.value = 'prev, pager'
|
||||
} else {
|
||||
// 中间页显示完整的上一页、页码、下一页
|
||||
pageLayout.value = 'prev, pager, next'
|
||||
}
|
||||
}
|
||||
// ========== 生命周期和监听器 ==========
|
||||
|
||||
|
||||
Reference in New Issue
Block a user