refactor(views): 重构多个视图组件代码结构,优化类型定义和逻辑组织

feat(services): 新增文章分页查询方法,支持按状态筛选文章

style(styles): 调整主布局样式,优化分页组件显示效果

docs(README): 更新API文档,完善服务模块说明和类型定义

fix(components): 修复左侧模块点击属性时使用错误字段名的问题

chore(package): 移除未使用的依赖项,清理项目依赖

perf(layouts): 优化主布局组件性能,拆分功能模块,减少重复计算

test(views): 为分页组件添加基础测试用例

build: 更新构建配置,优化生产环境打包

ci: 调整CI配置,添加类型检查步骤
This commit is contained in:
qingfeng1121
2025-11-14 15:30:29 +08:00
parent 4ae0ff7c2a
commit 1dc5bdd93f
16 changed files with 1883 additions and 2456 deletions

View File

@@ -9,7 +9,7 @@
<!-- 错误状态 -->
<div v-else-if="error" class="error-state-container">
<el-alert :title="error" type="error" show-icon />
<el-button type="primary" @click="fetchArticleDetail">重新加载</el-button>
<el-button type="primary" @click="initializeArticleDetail">重新加载</el-button>
</div>
<!-- 文章详情 -->
@@ -40,14 +40,11 @@
<!-- 文章底部信息 -->
<div class="article-footer-section">
<div class="article-tag-list">
<!-- <span v-for="tag in article.tags || []" :key="tag" class="el-tag el-tag--primary">
{{ tag }}
</span> -->
</div>
<!-- 文章操作按钮 -->
<div class="article-actions-group">
<el-button type="primary" @click="goBack" plain>
<el-button type="primary" @click="navigateBack" plain>
返回
</el-button>
</div>
@@ -57,11 +54,11 @@
<div class="related-articles-section" v-if="relatedArticles.length > 0">
<h3>相关文章</h3>
<div class="related-articles-list">
<div v-for="item in relatedArticles" :key="item.articleid" class="related-article-card"
<!-- <div v-for="item in relatedArticles" :key="item.articleid" class="related-article-card"
@click="handleRelatedArticleClick(item.articleid)">
<i class="el-icon-document"></i>
<span>{{ item.title }}</span>
</div>
</div> -->
</div>
</div>
</div>
@@ -80,92 +77,185 @@
</template>
<script setup lang="ts">
// 导入必要的依赖
import { useRoute, useRouter } from 'vue-router'
// =========================================================================
// 组件导入和初始化
// =========================================================================
/**
* 导入Vue核心功能
*/
import { ref, onMounted } from 'vue'
/**
* 导入路由相关功能
*/
import { useRouter } from 'vue-router'
/**
* 导入状态管理和UI组件
*/
import { useGlobalStore } from '@/store/globalStore'
import { ElMessage } from 'element-plus'
/**
* 导入类型和工具函数
*/
import type { Article } from '@/types'
import { formatRelativeTime } from '@/utils/dateUtils'
/**
* 导入子组件
*/
import messageboard from './messageboard.vue'
import markdownViewer from './markdown.vue'
// 路由相关
// =========================================================================
// 路由和状态初始化
// =========================================================================
/**
* 初始化路由
*/
const router = useRouter()
// 响应式状态管理
/**
* 初始化全局状态管理
*/
const globalStore = useGlobalStore()
const article = ref<Article | null>(null) // 使用 null 作为初始值,避免类型不匹配问题
const loading = ref(false)
const error = ref('')
const relatedArticles = ref<Article[]>([])
/**
* 响应式状态定义
*/
const article = ref<Article | null>(null) // 文章详情数据初始为null避免类型不匹配
const loading = ref(false) // 加载状态
const error = ref('') // 错误信息
const relatedArticles = ref<Article[]>([]) // 相关文章列表
// =========================================================================
// 文章数据处理模块
// =========================================================================
/**
* 获取文章ID
* @returns {number | null} 文章ID或null
*/
const getArticleId = (): number | null => {
return globalStore.getValue('articleInfo')?.articleid || null
}
/**
* 获取文章详情数据
* @returns {Promise<Article | null>} 文章数据或null
*/
const fetchArticleDetail = async () => {
const fetchArticleData = async (): Promise<Article | null> => {
try {
// 从全局状态获取文章信息
const response = await globalStore.getValue('articleInfo')
return response || null
} catch (err) {
console.error('获取文章数据失败:', err)
throw new Error('获取文章数据失败')
}
}
/**
* 增加文章浏览量
* @param {Article} articleData 文章数据
*/
const incrementViewCount = (articleData: Article): void => {
if (articleData.viewCount) {
articleData.viewCount++
} else {
articleData.viewCount = 1
}
}
/**
* 处理文章不存在的情况
*/
const handleArticleNotFound = (): void => {
error.value = '文章不存在或已被删除'
ElMessage.error(error.value)
}
/**
* 处理获取文章数据过程中的错误
* @param {unknown} err 错误对象
*/
const handleArticleFetchError = (err: unknown): void => {
error.value = err instanceof Error ? err.message : '获取文章详情失败,请稍后重试'
console.error('获取文章详情失败:', err)
ElMessage.error(error.value)
}
/**
* 初始化文章详情数据
*/
const initializeArticleDetail = async (): Promise<void> => {
try {
loading.value = true
error.value = ''
// 获取路由参数
const articleId = globalStore.getValue('articleInfo')?.articleid || null
// 获取文章ID
const articleId = getArticleId()
if (!articleId) {
throw new Error('文章不存在')
handleArticleNotFound()
return
}
// 获取文章详情
const response = await globalStore.getValue('articleInfo')
// const markdowndata = await
if (response) {
article.value = response
// 获取并设置分类名称
// const categoryResponse = await categoryAttributeService.getAttributeById(Number(article.value.attributeid))
// article.value.categoryName = categoryResponse.data.attributename || '未分类'
// 获取并设置评论量
// const commentResponse = await messageService.getMessagesByArticleId(articleId)
// article.value.commentCount = commentResponse.data.length || 0
// 更新浏览量
// 更新前端显示的浏览量
if (article.value.viewCount) {
article.value.viewCount++
} else {
article.value.viewCount = 1
}
// 获取文章数据
const articleData = await fetchArticleData()
if (articleData) {
article.value = articleData
// 增加浏览量
incrementViewCount(articleData)
} else {
throw new Error('文章不存在或已被删除')
handleArticleNotFound()
}
} catch (err) {
error.value = err instanceof Error ? err.message : '获取文章详情失败,请稍后重试'
console.error('获取文章详情失败:', err)
ElMessage.error(error.value)
handleArticleFetchError(err)
} finally {
loading.value = false
}
}
// =========================================================================
// 导航和用户交互模块
// =========================================================================
/**
* 返回上一页
*/
const goBack = () => {
const navigateBack = (): void => {
router.back()
}
/**
* 处理相关文章点击事件
* 导航到相关文章
* @param {number} id - 相关文章ID
*/
const handleRelatedArticleClick = (id: number) => {
const navigateToRelatedArticle = (id: number): void => {
router.push({
path: '/article/:url',
query: { url: id }
})
}
// =========================================================================
// 组件生命周期和初始化
// =========================================================================
/**
* 组件挂载时获取文章详情
* 组件挂载时的初始化操作
*/
const setupComponent = (): void => {
initializeArticleDetail()
}
/**
* 组件挂载生命周期钩子
*/
onMounted(() => {
fetchArticleDetail()
setupComponent()
})
</script>