diff --git a/src/components/uh-article-card/uh-article-card.vue b/src/components/uh-article-card/uh-article-card.vue
index 1cfcf1a..e8471d0 100644
--- a/src/components/uh-article-card/uh-article-card.vue
+++ b/src/components/uh-article-card/uh-article-card.vue
@@ -1,125 +1,181 @@
-
-
- 置顶
-
-
-
-
- {{ article.spec.title }}
-
-
- {{ article.status?.excerpt }}
-
-
-
-
- {{ cate.spec.displayName }}
-
-
-
-
- # {{ tag.spec.displayName }}
-
-
-
-
-
-
- {{ article.owner.displayName }}
-
-
- {{ publishTimeText }}
-
-
- 浏览
- {{ visitCount }}
- 次
-
-
-
-
+
+
+ 置顶
+
+
+
+
+ {{ article.spec.title }}
+
+
+ {{ article.status?.excerpt }}
+
+
+
+
+ {{ cate.spec.displayName }}
+
+
+
+
+ # {{ tag.spec.displayName }}
+
+
+
+
+
+
+ {{ article.owner.displayName }}
+
+ {{ publishTimeText }}
+
+ 浏览
+ {{ visitCount }}
+ 次
+
+
+
+
diff --git a/src/pages-blog/archives/archives.vue b/src/pages-blog/archives/archives.vue
index 79c1ce0..2253da8 100644
--- a/src/pages-blog/archives/archives.vue
+++ b/src/pages-blog/archives/archives.vue
@@ -3,11 +3,8 @@ import { computed, ref } from 'vue'
import { onPullDownRefresh, onReachBottom } from '@dcloudio/uni-app'
import { getPostList } from '@/api/halo'
import { useAppConfigStore } from '@/store/appConfig'
-import { useSettingStore } from '@/store/setting'
import { DataLoadingStatusEnum, useDataLoadingStatus } from '@/hooks/useDataLoadingStatus'
-import { checkThumbnailUrl } from '@/utils/url'
import { sleep } from '@/utils/common'
-import { formatTime as formatTimeUtil } from '@/utils/formatTime'
import type { IPost } from '@/api/types/halo'
definePage({
@@ -19,10 +16,8 @@ definePage({
})
const appConfigStore = useAppConfigStore()
-const settingStore = useSettingStore()
const calcAuditModeEnabled = computed(() => appConfigStore.auditModeEnabled)
-const globalAppSettings = computed(() => settingStore.settings)
/* ---------------- 状态 ---------------- */
const { loadingStatus, updateLoadingStatus } = useDataLoadingStatus()
@@ -43,17 +38,6 @@ const loadMoreText = ref('加载中...')
const postLabelYearKey = 'content.halo.run/archive-year'
const postLabelMonthKey = 'content.halo.run/archive-month'
-/** 卡片布局偏好 → 原子类(对应旧版 cardType 样式变体) */
-const CARD_LAYOUTS: Record = {
- lr_image_text: { card: '', thumb: 'h-[170rpx] w-[200rpx]', info: 'w-0 flex-1 pl-5' },
- lr_text_image: { card: '', thumb: 'order-2 h-[170rpx] w-[200rpx]', info: 'order-1 w-0 flex-1 pr-5' },
- tb_image_text: { card: 'flex-col', thumb: 'h-[220rpx] w-full', info: 'w-full pt-3' },
- tb_text_image: { card: 'flex-col', thumb: 'order-2 h-[220rpx] w-full', info: 'order-1 w-full pb-3' },
- only_text: { card: '', thumb: 'hidden', info: 'py-1' },
-}
-
-const calcCardLayout = computed(() => CARD_LAYOUTS[globalAppSettings.value.layout.cardType] || CARD_LAYOUTS.lr_image_text)
-
/* ---------------- 数据处理 ---------------- */
/** 按 tab 分组文章 */
function handleGetPosts(list: IPost[]): Record {
@@ -124,7 +108,6 @@ async function handleGetData() {
const posts = handleGetPosts(filtered)
dataList.value = handleGetShowDataList(posts)
cacheDataList.value = filtered
- c
updateLoadingStatus(
dataList.value.length === 0 ? DataLoadingStatusEnum.Empty : DataLoadingStatusEnum.Success,
)
@@ -207,15 +190,6 @@ function handleOnTabChange(e: { index: number }) {
uni.pageScrollTo({ scrollTop: 0, duration: 500 })
}
-function handleToArticleDetail(article: IPost) {
- if (calcAuditModeEnabled.value)
- return
- uni.navigateTo({
- url: `/pages-blog/article-detail/article-detail?name=${article.metadata.name}`,
- animationType: 'slide-in-right',
- })
-}
-
function handleToTopPage(duration = 500) {
uni.pageScrollTo({
scrollTop: 0,
@@ -226,11 +200,6 @@ function handleToTopPage(duration = 500) {
})
}
-function formatTime(time?: string): string {
- // 与旧项目一致:yyyy年MM月dd日 星期w
- return time ? formatTimeUtil({ d: time, f: 'yyyy年MM月dd日 星期w' }) : ''
-}
-
/* ---------------- 生命周期 ---------------- */
handleGetData()
@@ -301,27 +270,14 @@ onReachBottom(() => {
共 {{ item.posts.length }} 篇{{ calcAuditModeEnabled ? '内容' : '文章' }}
-
-
+
-
-
-
- {{ post.spec.title }}
-
-
- {{ post.status?.excerpt }}
-
-
- 日期:{{ formatTime(post.spec.publishTime) }}
-
-
-
+ from="archives"
+ :article="post"
+ :audit-mode="calcAuditModeEnabled"
+ />
该日期下暂无归档文章!
diff --git a/src/pages-blog/articles/articles.vue b/src/pages-blog/articles/articles.vue
index 417a6d1..6cbba70 100644
--- a/src/pages-blog/articles/articles.vue
+++ b/src/pages-blog/articles/articles.vue
@@ -1,9 +1,4 @@
-
-
+
-
-
+
{
-
-
+
{
-
-
-import { computed, ref } from 'vue'
-import { onPullDownRefresh, onReachBottom, onShow } from '@dcloudio/uni-app'
-import { getPostList } from '@/api/halo'
-import { useAppConfigStore } from '@/store/appConfig'
-import { useSettingStore } from '@/store/setting'
-import { checkAvatarUrl, checkImageUrl } from '@/utils/url'
-import { t } from '@/locale'
-import { useMaintenanceIntercept } from '@/hooks/useMaintenanceIntercept'
-import { DataLoadingStatusEnum, useDataLoadingStatus } from '@/hooks/useDataLoadingStatus'
-import type { IPost } from '@/api/types/halo'
+ import { computed, ref } from 'vue'
+ import { onPullDownRefresh, onReachBottom, onShow } from '@dcloudio/uni-app'
+ import { getPostList } from '@/api/halo'
+ import { useAppConfigStore } from '@/store/appConfig'
+ import { useSettingStore } from '@/store/setting'
+ import { checkAvatarUrl, checkImageUrl } from '@/utils/url'
+ import { t } from '@/locale'
+ import { useMaintenanceIntercept } from '@/hooks/useMaintenanceIntercept'
+ import { DataLoadingStatusEnum, useDataLoadingStatus } from '@/hooks/useDataLoadingStatus'
+ import type { IPost } from '@/api/types/halo'
-definePage({
- style: {
- navigationBarTitleText: '首页',
- enablePullDownRefresh: true,
- navigationStyle: 'custom',
- },
-})
+ definePage({
+ style: {
+ navigationBarTitleText: '首页',
+ enablePullDownRefresh: true,
+ navigationStyle: 'custom',
+ },
+ })
-const appConfigStore = useAppConfigStore()
-const settingStore = useSettingStore()
+ const appConfigStore = useAppConfigStore()
+ const settingStore = useSettingStore()
-/** 维护拦截(插件可用性 + 维护模式,任一命中跳维护页;与入口页共用 hooks) */
-const { interceptOrContinue } = useMaintenanceIntercept()
-/** 是否已被拦截(配置已带维护键时同步置位,避免首载闪跳) */
-const intercepted = ref(!!appConfigStore.configs.maintenance)
+ /** 维护拦截(插件可用性 + 维护模式,任一命中跳维护页;与入口页共用 hooks) */
+ const { interceptOrContinue } = useMaintenanceIntercept()
+ /** 是否已被拦截(配置已带维护键时同步置位,避免首载闪跳) */
+ const intercepted = ref(!!appConfigStore.configs.maintenance)
-const haloConfigs = computed(() => appConfigStore.configs)
+ const haloConfigs = computed(() => appConfigStore.configs)
-/* ---------------- 状态 ---------------- */
-const { loadingStatus, updateLoadingStatus } = useDataLoadingStatus()
-const isLoadMore = ref(false)
-const loadMoreText = ref(t('common.loading'))
-const articleList = ref([])
+ /* ---------------- 状态 ---------------- */
+ const { loadingStatus, updateLoadingStatus } = useDataLoadingStatus()
+ const isLoadMore = ref(false)
+ const loadMoreText = ref(t('common.loading'))
+ const articleList = ref([])
-const result = ref<{ hasNext: boolean }>({ hasNext: false })
+ const result = ref<{ hasNext : boolean }>({ hasNext: false })
-const queryParams = ref({
- size: 10,
- page: 1,
- sort: ['spec.pinned,desc', 'spec.publishTime,desc'],
-})
+ const queryParams = ref({
+ size: 10,
+ page: 1,
+ sort: ['spec.pinned,desc', 'spec.publishTime,desc'],
+ })
-/* ---------------- 最新推荐模式(默认/置顶/最新/最旧) ---------------- */
-const recommendTabs = [
- { label: '默认', value: 'default' },
- { label: '置顶', value: 'pinned' },
- { label: '最新', value: 'latest' },
- { label: '最旧', value: 'oldest' },
-]
+ /* ---------------- 最新推荐模式(默认/置顶/最新/最旧) ---------------- */
+ const recommendTabs = [
+ { label: '默认', value: 'default' },
+ { label: '置顶', value: 'pinned' },
+ { label: '最新', value: 'latest' },
+ { label: '最旧', value: 'oldest' },
+ ]
-const recommendMode = ref<'default' | 'pinned' | 'latest' | 'oldest'>('default')
+ const recommendMode = ref<'default' | 'pinned' | 'latest' | 'oldest'>('default')
-/** 各模式对应排序参数(默认 = 置顶优先 + 发布时间倒序) */
-const recommendSortMap: Record = {
- default: ['spec.pinned,desc', 'spec.publishTime,desc'],
- pinned: ['spec.pinned,desc'],
- latest: ['spec.publishTime,desc'],
- oldest: ['spec.publishTime,asc'],
-}
+ /** 各模式对应排序参数(默认 = 置顶优先 + 发布时间倒序) */
+ const recommendSortMap : Record = {
+ default: ['spec.pinned,desc', 'spec.publishTime,desc'],
+ pinned: ['spec.pinned,desc'],
+ latest: ['spec.publishTime,desc'],
+ oldest: ['spec.publishTime,asc'],
+ }
-/** 切换推荐模式:重置分页并重新查询 */
-function handleRecommendModeChange(mode: 'default' | 'pinned' | 'latest' | 'oldest') {
- if (recommendMode.value === mode)
- return
- recommendMode.value = mode
- isLoadMore.value = false
- articleList.value = []
- queryParams.value.page = 1
- queryParams.value.sort = recommendSortMap[mode]
- handleGetArticleList()
-}
+ /** 切换推荐模式:重置分页并重新查询 */
+ function handleRecommendModeChange(mode : 'default' | 'pinned' | 'latest' | 'oldest') {
+ if (recommendMode.value === mode)
+ return
+ recommendMode.value = mode
+ isLoadMore.value = false
+ articleList.value = []
+ queryParams.value.page = 1
+ queryParams.value.sort = recommendSortMap[mode]
+ handleGetArticleList()
+ }
-/* ---------------- 计算属性 ---------------- */
-const appInfo = computed(() => {
- const appInfoData = haloConfigs.value.appConfig?.appInfo as { name?: string, logo?: string } | undefined
- return {
- name: appInfoData?.name || 'uni-halo',
- logo: checkImageUrl(appInfoData?.logo),
- }
-})
+ /* ---------------- 计算属性 ---------------- */
+ const appInfo = computed(() => {
+ const appInfoData = haloConfigs.value.appConfig?.appInfo as { name ?: string, logo ?: string } | undefined
+ return {
+ name: appInfoData?.name || 'uni-halo',
+ logo: checkImageUrl(appInfoData?.logo),
+ }
+ })
-const bloggerInfo = computed(() => {
- const blogger = haloConfigs.value.authorConfig?.blogger as { nickname?: string, avatar?: string } | undefined
- return {
- nickname: blogger?.nickname || '',
- avatar: checkAvatarUrl(blogger?.avatar),
- }
-})
+ const bloggerInfo = computed(() => {
+ const blogger = haloConfigs.value.authorConfig?.blogger as { nickname ?: string, avatar ?: string } | undefined
+ return {
+ nickname: blogger?.nickname || '',
+ avatar: checkAvatarUrl(blogger?.avatar),
+ }
+ })
-const calcAuditModeEnabled = computed(() => appConfigStore.auditModeEnabled)
+ const calcAuditModeEnabled = computed(() => appConfigStore.auditModeEnabled)
-const globalAppSettings = computed(() => settingStore.settings)
+ const globalAppSettings = computed(() => settingStore.settings)
-/* ---------------- 数据加载 ---------------- */
-async function handleQuery() {
- handleGetArticleList()
-}
+ /* ---------------- 数据加载 ---------------- */
+ async function handleQuery() {
+ handleGetArticleList()
+ }
-/** 文章列表 */
-async function handleGetArticleList() {
- if (calcAuditModeEnabled.value) {
- // 审核模式:真实文章按 audit-data posts 过滤(数组顺序即展示顺序)
- const auditPostNames = appConfigStore.auditData.spec?.posts || []
- try {
- const res = await getPostList({ page: 1, size: 0, sort: ['spec.publishTime,desc'] })
- const filtered = res.data.items.filter(item => auditPostNames.includes(item.metadata.name))
- articleList.value = filtered.map((item) => {
- item.owner.avatar = checkAvatarUrl(item.owner.avatar)
- return item
- })
- updateLoadingStatus(articleList.value.length === 0 ? DataLoadingStatusEnum.Empty : DataLoadingStatusEnum.Success)
- loadMoreText.value = t('common.noMore')
- }
- catch (err) {
- console.error('获取审核文章失败', err)
- updateLoadingStatus(DataLoadingStatusEnum.Error)
- loadMoreText.value = t('common.loadFailed')
- }
- finally {
- uni.hideLoading()
- uni.stopPullDownRefresh()
- }
- return
- }
+ /** 文章列表 */
+ async function handleGetArticleList() {
+ if (calcAuditModeEnabled.value) {
+ // 审核模式:真实文章按 audit-data posts 过滤(数组顺序即展示顺序)
+ const auditPostNames = appConfigStore.auditData.spec?.posts || []
+ try {
+ const res = await getPostList({ page: 1, size: 0, sort: ['spec.publishTime,desc'] })
+ const filtered = res.data.items.filter(item => auditPostNames.includes(item.metadata.name))
+ articleList.value = filtered.map((item) => {
+ item.owner.avatar = checkAvatarUrl(item.owner.avatar)
+ return item
+ })
+ updateLoadingStatus(articleList.value.length === 0 ? DataLoadingStatusEnum.Empty : DataLoadingStatusEnum.Success)
+ loadMoreText.value = t('common.noMore')
+ }
+ catch (err) {
+ console.error('获取审核文章失败', err)
+ updateLoadingStatus(DataLoadingStatusEnum.Error)
+ loadMoreText.value = t('common.loadFailed')
+ }
+ finally {
+ uni.hideLoading()
+ uni.stopPullDownRefresh()
+ }
+ return
+ }
- if (!isLoadMore.value) {
- updateLoadingStatus(DataLoadingStatusEnum.Loading)
- }
- loadMoreText.value = t('common.loading')
+ if (!isLoadMore.value) {
+ updateLoadingStatus(DataLoadingStatusEnum.Loading)
+ }
+ loadMoreText.value = t('common.loading')
- try {
- const res = await getPostList({ ...toRaw(queryParams.value) })
- result.value.hasNext = res.data.hasNext
- articleList.value = (isLoadMore.value
- ? articleList.value.concat(res.data.items)
- : res.data.items).map((item) => {
- item.owner.avatar = checkAvatarUrl(item.owner.avatar)
- return item
- })
- updateLoadingStatus(articleList.value.length === 0 ? DataLoadingStatusEnum.Empty : DataLoadingStatusEnum.Success)
- loadMoreText.value = res.data.hasNext ? t('common.loadMore') : t('common.noMore')
- }
- catch (err) {
- updateLoadingStatus(DataLoadingStatusEnum.Error)
- loadMoreText.value = t('common.loadFailed')
- console.error('获取文章失败', err)
- }
- finally {
- uni.hideLoading()
- uni.stopPullDownRefresh()
- }
-}
+ try {
+ const res = await getPostList({ ...toRaw(queryParams.value) })
+ result.value.hasNext = res.data.hasNext
+ articleList.value = (isLoadMore.value
+ ? articleList.value.concat(res.data.items)
+ : res.data.items).map((item) => {
+ item.owner.avatar = checkAvatarUrl(item.owner.avatar)
+ return item
+ })
+ updateLoadingStatus(articleList.value.length === 0 ? DataLoadingStatusEnum.Empty : DataLoadingStatusEnum.Success)
+ loadMoreText.value = res.data.hasNext ? t('common.loadMore') : t('common.noMore')
+ }
+ catch (err) {
+ updateLoadingStatus(DataLoadingStatusEnum.Error)
+ loadMoreText.value = t('common.loadFailed')
+ console.error('获取文章失败', err)
+ }
+ finally {
+ uni.hideLoading()
+ uni.stopPullDownRefresh()
+ }
+ }
-/* ---------------- 跳转 ---------------- */
+ /* ---------------- 跳转 ---------------- */
-/** 更多文章:跳转文章列表页 */
-function handleToArticles() {
- uni.navigateTo({ url: '/pages-blog/articles/articles' })
-}
+ function handleToArticles() {
+ uni.navigateTo({ url: '/pages-blog/articles/articles' })
+ }
-function handleOnLogoToPage() {
- uni.switchTab({ url: '/pages/tabbar/about/about' })
-}
+ function handleOnLogoToPage() {
+ uni.switchTab({ url: '/pages/tabbar/about/about' })
+ }
-function handleToTopPage(duration = 500) {
- uni.pageScrollTo({
- scrollTop: 0,
- duration,
- fail: (err) => {
- console.error('回顶失败', err)
- },
- })
-}
+ function init() {
+ if (!intercepted.value) {
+ handleQuery()
+ }
+ }
+ init()
-function init() {
- if (!intercepted.value) {
- handleQuery()
- }
-}
-init()
+ /* ---------------- 生命周期 ---------------- */
-/* ---------------- 生命周期 ---------------- */
+ // 维护检查
+ onShow(async () => {
+ intercepted.value = await interceptOrContinue()
+ console.log('拦截状态', intercepted.value)
+ })
-// 维护检查
-onShow(async () => {
- intercepted.value = await interceptOrContinue()
- console.log('拦截状态', intercepted.value)
-})
+ onPullDownRefresh(() => {
+ isLoadMore.value = false
+ queryParams.value.page = 1
+ handleQuery()
+ })
-onPullDownRefresh(() => {
- isLoadMore.value = false
- queryParams.value.page = 1
- handleQuery()
-})
-
-onReachBottom(() => {
- if (calcAuditModeEnabled.value) {
- uni.showToast({ icon: 'none', title: t('common.noMoreData') })
- return
- }
- if (result.value.hasNext) {
- queryParams.value.page += 1
- isLoadMore.value = true
- handleGetArticleList()
- }
- else {
- uni.showToast({ icon: 'none', title: t('common.noMoreData') })
- }
-})
+ onReachBottom(() => {
+ if (calcAuditModeEnabled.value) {
+ uni.showToast({ icon: 'none', title: t('common.noMoreData') })
+ return
+ }
+ if (result.value.hasNext) {
+ queryParams.value.page += 1
+ isLoadMore.value = true
+ handleGetArticleList()
+ }
+ else {
+ uni.showToast({ icon: 'none', title: t('common.noMoreData') })
+ }
+ })
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
- 最新推荐
-
-
-
-
-
- {{ tab.label }}
-
-
-
-
-
-
-
-
-
+
+
+ 最新推荐
+
+
+
+
+
+ {{ tab.label }}
+
+
+ 更多
+
+
+
+
+
+
+
+
-
-
+
-
-
-
-
-
- {{ loadMoreText }}
-
-
-
-
-
+
+
+
+
+
+ {{ loadMoreText }}
+
+
+
+
+
\ No newline at end of file