mirror of
https://github.com/ialley-workshop-open/uni-halo.git
synced 2026-09-12 16:40:40 +08:00
refactor: 移除启动页逻辑,新增全局组件与偏好设置系统
1. 移除旧版启动页分流逻辑,直接跳转首页 2. 新增返回顶部、章节标题、导航栏等全局组件 3. 重构偏好设置系统,实现站点默认与本地差异分层管理 4. 删除冗余的测试mock、插件模块与样式文件 5. 优化文章卡片与评论组件样式,更新全局主题色 6. 清理废弃的请求参数与配置项
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, ref, watch } from 'vue'
|
||||
import { getBanners } from '@/api/uni-halo'
|
||||
import { useAppConfigStore } from '@/store/appConfig'
|
||||
import { checkAvatarUrl, checkThumbnailUrl } from '@/utils/url'
|
||||
import { formatTime } from '@/utils/formatTime'
|
||||
import type { IBannerPublicItem } from '@/api/types/uni-halo'
|
||||
|
||||
export interface IBannerItem {
|
||||
/** 条目标识(Banner 为 metadata.name;兼容旧数据) */
|
||||
id ?: string | number
|
||||
/** Banner 条目 metadata.name(custom 详情页跳转用) */
|
||||
name ?: string
|
||||
title ?: string
|
||||
image ?: string
|
||||
src ?: string
|
||||
/** 来源:post=文章快照 / custom=自定义 */
|
||||
type ?: string
|
||||
/** 文章 id(source=post 时跳转文章详情) */
|
||||
postId ?: string
|
||||
content ?: string
|
||||
url ?: string
|
||||
/** 展示日期(ISO 快照) */
|
||||
date ?: string
|
||||
authorName ?: string
|
||||
authorAvatar ?: string
|
||||
[key : string] : unknown
|
||||
}
|
||||
|
||||
const appConfigStore = useAppConfigStore()
|
||||
|
||||
const haloConfigs = computed(() => appConfigStore.configs)
|
||||
const bannerConfig = computed(() => haloConfigs.value.pageConfig?.homeConfig?.bannerConfig)
|
||||
|
||||
/* ---------------- 数据(高内聚:内部请求公开接口) ---------------- */
|
||||
const bannerList = ref<IBannerItem[]>([])
|
||||
const currentIndex = ref(0)
|
||||
const currentBanner = ref<IBannerItem | null>(null)
|
||||
|
||||
/** 公开 Banner 条目 → 轮播展示项 */
|
||||
function mapBanners(items : IBannerPublicItem[]) : IBannerItem[] {
|
||||
return items.map(item => ({
|
||||
id: item.name,
|
||||
name: item.name,
|
||||
title: item.title || '',
|
||||
image: checkThumbnailUrl(item.cover),
|
||||
src: checkThumbnailUrl(item.cover),
|
||||
type: item.source,
|
||||
postId: item.postId,
|
||||
url: item.link,
|
||||
date: formatTime({
|
||||
d: item.date,
|
||||
f: 'yyyy年MM月dd日 星期w'
|
||||
}),
|
||||
authorName: item.authorName,
|
||||
authorAvatar: item.authorAvatar ? checkAvatarUrl(item.authorAvatar) : '',
|
||||
}))
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const res = await getBanners()
|
||||
bannerList.value = mapBanners(res.data || [])
|
||||
handleBannerChange({
|
||||
detail: { current: 0 }
|
||||
})
|
||||
}
|
||||
catch (err) {
|
||||
console.error('获取轮播图失败', err)
|
||||
}
|
||||
})
|
||||
|
||||
function handleBannerChange(e : any) {
|
||||
currentIndex.value = e?.detail?.current ?? 0
|
||||
currentBanner.value = bannerList.value[currentIndex.value]
|
||||
}
|
||||
|
||||
function handleOnClick(item : IBannerItem) {
|
||||
// 审核模式下照常展示 Banner,点击分发不拦截(详情页自行处理审核限制)
|
||||
if (item.type === 'custom') {
|
||||
// 自定义条目:跳转 Banner 详情页,页面内调公开详情接口展示 content/外链
|
||||
if (item.name) {
|
||||
uni.navigateTo({
|
||||
url: `/pages-blog/banner-detail/banner-detail?name=${item.name}`,
|
||||
animationType: 'slide-in-right',
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
// 文章来源
|
||||
uni.navigateTo({
|
||||
url: `/pages-blog/article-detail/article-detail?name=${item.postId}`,
|
||||
animationType: 'slide-in-right',
|
||||
})
|
||||
}
|
||||
|
||||
function handleToSearch() {
|
||||
uni.navigateTo({ url: '/pages-blog/search/search' })
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view v-if="bannerList.length > 0" class="relative w-full mb-6 box-border ">
|
||||
<view class="box-border relative w-full h-52 overflow-hidden">
|
||||
<swiper class="w-full h-52" :circular="true" :indicator-dots="false" :autoplay="true" :interval="3000"
|
||||
:duration="1000" @change="handleBannerChange">
|
||||
<swiper-item v-for="(item, index) in bannerList" :key="index" class="relative">
|
||||
<image :src="item.image || item.src" class="h-full w-full" mode="aspectFill"
|
||||
@click.stop="handleOnClick(item)" />
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<view v-if="currentBanner"
|
||||
class="pointer-events-none absolute inset-0 z-10 flex flex-col items-center justify-center gap-y-2 bg-white/5 backdrop-blur-[2rpx]">
|
||||
<text class="text-sm text-gray-900 font-bold bg-secondary px-3 py-0.5 rounded-xl">
|
||||
{{ currentBanner.title }}
|
||||
</text>
|
||||
<text
|
||||
class="text-xs text-white text-shadow-[0_2rpx_8rpx_rgba(0,0,0,0.4)]">{{ currentBanner.date }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="absolute bottom-0 left-0 right-0 h-12 w-full bg-gradient-to-b from-white/0 to-page" />
|
||||
<view class="absolute left-0 right-0 z-10 flex items-center justify-center -translate-y-6">
|
||||
<view
|
||||
class="uh-global-card-glass border w-4/5 rounded-full px-4 py-2 text-sm text-gray-600 flex items-center justify-center gap-x-2"
|
||||
@click="handleToSearch()">
|
||||
<wd-icon name="search-line" size="32rpx"></wd-icon>
|
||||
<text>哈喽,想看些什么 <text class="bg-secondary rounded-xl px-1">{ 内容 }</text> 呢~</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
Reference in New Issue
Block a user