1
0
mirror of https://github.com/ialley-workshop-open/uni-halo.git synced 2026-07-27 12:30:41 +08:00

refactor: 项目整体重构与功能完善

1. 配置开发环境接口地址
2. 重构工具函数目录结构,迁移防抖节流等工具到base目录
3. 统一页面布局样式为全屏居中布局
4. 新增大量通用工具函数:深克隆、深合并、uuid、时间格式化、随机数、数组打乱、剪贴板操作等
5. 优化自定义tabbar实现,修复交互逻辑
6. 新增列表数据管理hook和请求loading封装
7. 移除无用测试文件和冗余代码
8. 完善首页内容,增加轮播图、作者卡片、金刚区等模块
This commit is contained in:
小莫唐尼
2026-06-11 23:33:54 +08:00
parent 3945ee611d
commit 862d176593
33 changed files with 1787 additions and 251 deletions
+2 -6
View File
@@ -16,7 +16,7 @@ async function doLogin() {
try {
// 调用登录接口
await tokenStore.login({
username: '菲鸽',
username: '小莫唐尼',
password: '123456',
})
uni.navigateBack()
@@ -28,7 +28,7 @@ async function doLogin() {
</script>
<template>
<view class="login">
<view class="min-h-screen w-full flex flex-col items-center justify-center gap-y-6 bg-page">
<!-- 本页面是非MP的登录页主要用于 h5 APP -->
<view class="text-center">
登录页
@@ -38,7 +38,3 @@ async function doLogin() {
</button>
</view>
</template>
<style lang="scss" scoped>
//
</style>
+1 -5
View File
@@ -19,7 +19,7 @@ function doRegister() {
</script>
<template>
<view class="login">
<view class="min-h-screen w-full flex flex-col items-center justify-center gap-y-6 bg-page">
<view class="text-center">
注册页
</view>
@@ -28,7 +28,3 @@ function doRegister() {
</button>
</view>
</template>
<style lang="scss" scoped>
//
</style>
+1 -1
View File
@@ -11,7 +11,7 @@ definePage({
</script>
<template>
<view class="mt-10 text-center text-green-500">
<view class="min-h-screen w-full flex flex-col items-center justify-center gap-y-6 bg-page">
相册页面
</view>
</template>
+260 -14
View File
@@ -1,4 +1,12 @@
<script lang="ts" setup>
import useRequest from '@/hooks/useRequest'
import { queryPostByName, queryPosts } from '@/api/halo-base/post'
import { completeUrl } from '@/utils/url'
import { timeFrom } from '@/utils/base/timeFrom'
import { useListData } from '@/hooks/useListData'
import type { ListedPostVo, ListedPostVoList, PostV1alpha1PublicApiQueryPostByNameRequest, PostV1alpha1PublicApiQueryPostsRequest, PostVo } from '@halo-dev/api-client'
defineOptions({
name: 'Home',
})
@@ -8,30 +16,268 @@ definePage({
style: {
navigationStyle: 'custom',
navigationBarTitleText: '首页',
enablePullDownRefresh: true,
},
})
function toRequestDemo() {
uni.navigateTo({
url: '/pages-demo/request-demo/request-demo',
})
}
const exampleImageUrls = reactive({
banner: 'https://fastly.picsum.photos/id/353/800/800.jpg?hmac=RaDuQ92sSXj4q5vOYna9G00J7KrBUC3eBS0slCWYZXA',
avatar: 'https://www.xiaoxiaomo.cn/logo.jpg',
postCover1: 'https://lh3.googleusercontent.com/aida-public/AB6AXuDg-QKAXOU1_Lv726MyeTiY2R1MAJWKzjiUy__RYoUw78YL5PctVg2sfMUCRMBybAzw_E0V0fEhir4IW2RHF7YRcxm89JFDKVMlfU_yQTijnr4o-praEXX_buxFWWxsSayLdA64X9pOmjYT5FDp9kfpW4tqZBWLfiyqhiYZnyHTCFeKZruH2auHZt4OlsOdzamOOkoib4CMGmUwTj112emdzlshRDLxGOSbThTWUOw61YirCl-RUrx1WFg2kZimP9Byq4pV7tv9YhtS',
postCover: 'https://www.yijunzhao.cn/upload/HermesWebUIHermesStudio%E8%83%8C%E5%90%8E%E7%9A%84%E5%93%81%E7%89%8C%E5%8D%87%E7%BA%A7%E4%B8%8E%E4%BA%A7%E5%93%81%E8%BF%9B%E5%8C%96-02.png',
})
const banner = reactive({
current: 0,
items: [
exampleImageUrls.banner,
exampleImageUrls.postCover1,
],
list: [
{
value: exampleImageUrls.banner,
type: 'image',
title: 'UNI HALO v3.0',
desc: '新全新探索简约的艺术风格',
time: timeFrom(new Date()),
},
{
value: exampleImageUrls.postCover1,
type: 'image',
title: 'UNI HALO v3.0 使用手册',
desc: 'uni-halo 使用手册,包含安装、配置、使用等信息666666666aaaa啊啊啊啊啊啊啊啊啊啊啊',
time: timeFrom(new Date()),
},
],
})
const quickList = reactive([
{
pagePath: 'pages/moments/moments',
text: '动态',
iconType: 'uiLib',
icon: 'gift',
},
{
pagePath: 'pages-blog/about/about',
text: '关于',
iconType: 'uiLib',
icon: 'image',
},
{
pagePath: 'pages/me/me',
text: '我的',
iconType: 'uiLib',
icon: 'user',
},
{
pagePath: 'pages/category/category',
text: '分类',
iconType: 'uiLib',
icon: 'image',
},
{
pagePath: 'pages/category/category',
text: '其他',
iconType: 'uiLib',
icon: 'image',
},
])
const { loading, error, data, run } = useRequest<ListedPostVoList, PostV1alpha1PublicApiQueryPostsRequest>(queryPosts, { loadingToast: true, loadingToastContent: '加载中...', loadingToastMask: true })
const { loading: loadingSingle, error: errorSingle, data: dataSingle, run: runSingle } = useRequest<PostVo, PostV1alpha1PublicApiQueryPostByNameRequest>(queryPostByName)
const { list: postList, refresh } = useListData<ListedPostVo>({
params: {
page: 1,
size: 10,
},
loading: toRef(loading),
onPullDownRefresh: async (params, updateData) => {
await run({ ...params })
updateData({
error: error.value,
hasNext: data.value?.hasNext,
items: data.value?.items ?? [],
})
},
onReachBottom: async (params, updateData) => {
await run({ ...params })
updateData({
error: error.value,
hasNext: data.value?.hasNext,
items: data.value?.items ?? [],
})
},
})
onLoad(() => {
console.log('测试 uni API 自动引入: onLoad')
console.log('home onLoad')
refresh()
runSingle({ name: '019eb1ca-e37c-7729-97af-e0b658aeef0f' })
})
</script>
<template>
<view class="min-h-screen flex flex-col items-center justify-center gap-y-6 bg-page pt-safe">
<image class="h-24 w-24 rounded-lg object-cover" src="/static/logo.png" />
<view class="text-2xl text-blue-500 font-bold">
Uni Halo v3.0.0
<view class="min-h-screen bg-page pb-safe">
<!-- 顶部banner -->
<view v-if="false" class="relative h-72 w-full">
<image class="h-72 w-full object-cover" :src="exampleImageUrls.banner" />
<view class="absolute bottom-4 left-4 flex flex-col gap-y-2">
<text class="text-xs text-white">welcome to new world</text>
<text class="text-2xl text-white font-bold">UNI HALO V3.0 </text>
<text class="text-xs text-white">新全新探索简约的艺术风格</text>
</view>
</view>
<view class="mt-4 flex flex-col items-center gap-y-2">
<button @click="toRequestDemo">
请求演示
</button>
<view>
<wd-swiper
v-model:current="banner.current" :list="banner.items" indicator-position="right" autoplay
:height="290"
>
<template #default="{ index }">
<view class="relative h-full w-full">
<image class="h-full w-full object-cover" :src="banner.list[index].value" />
<view class="absolute bottom-0 left-0 right-0 from-black/10 to-black/90 bg-gradient-to-b p-4">
<view class="w-5/6 flex flex-col gap-y-2">
<text class="text-xs text-white/90">{{ banner.list[index].time }}</text>
<text class="line-clamp-1 text-xl text-white font-bold">{{ banner.list[index].title }}</text>
<text class="line-clamp-1 text-xs text-white/95">{{ banner.list[index].desc }}</text>
</view>
</view>
</view>
</template>
<template #indicator="{ current, total }">
<view class="absolute bottom-4 right-4 text-xs text-white">
{{ current + 1 }}/{{ total }}
</view>
</template>
</wd-swiper>
</view>
<!-- 作者卡片 -->
<view class="mt-4 box-border px-4">
<view class="box-border flex flex-col items-center gap-y-2 rounded-2xl bg-white p-4 shadow-sm">
<view class="w-full flex items-center justify-between gap-x-2">
<image
class="uh-shadow-xs h-11 w-11 shrink-0 border-2 border-white rounded-full border-solid"
src="https://www.xiaoxiaomo.cn/logo.jpg" mode="scaleToFill"
/>
<view class="h-full flex flex-1 flex-col justify-between gap-y-1">
<view class="text-sm text-gray-900 font-bold">
小莫唐尼
</view>
<view class="line-clamp-1 text-xs text-gray-500">
一个爱凑热闹喜欢捣鼓前端的码农
</view>
</view>
<view class="h-full shrink-0 rounded-3xl bg-[#1A1A1A] px-4 py-2 text-xs text-white">
联系我
</view>
</view>
<view class="my-1 h-1px w-full bg-gray-100" />
<view class="grid grid-cols-4 w-full gap-x-4">
<view class="flex flex-col items-center justify-center gap-y-0.5">
<text class="text-sm text-gray-900 font-bold">128</text>
<text class="text-xs text-gray-600">文章</text>
</view>
<view class="flex flex-col items-center justify-center gap-y-0.5">
<text class="text-sm text-gray-900 font-bold">999</text>
<text class="text-xs text-gray-600">访客</text>
</view>
<view class="flex flex-col items-center justify-center gap-y-0.5">
<text class="text-sm text-gray-900 font-bold">1.2k</text>
<text class="text-xs text-gray-600">获赞</text>
</view>
<view class="flex flex-col items-center justify-center gap-y-0.5">
<text class="text-sm text-gray-900 font-bold">128k</text>
<text class="text-xs text-gray-600">收藏</text>
</view>
</view>
</view>
</view>
<!-- 金刚区 -->
<view class="mt-4 px-4">
<view class="flex items-center justify-around gap-x-4">
<view
v-for="item in quickList" :key="item.pagePath"
class="w-1/5 flex flex-col items-center justify-center gap-y-1"
>
<view class="flex items-center justify-center rounded-3xl bg-white p-3.5 shadow-sm">
<wd-icon :name="item.icon" :size="24" />
</view>
<text class="text-xs text-gray-800">{{ item.text }}</text>
</view>
</view>
</view>
<!-- 分类推荐 -->
<!-- 瞬间推荐 -->
<!-- 置顶文章 -->
<view v-if="dataSingle" class="mt-4 box-border px-4">
<view class="mb-2 box-border flex items-center justify-between">
<text class="text-lg text-gray-900 font-bold">置顶文章</text>
</view>
<view class="box-border rounded-xl bg-white p-4">
<image :src="completeUrl(dataSingle.spec.cover)" mode="aspectFill" class="h-36 w-full rounded-xl" />
<view class="box-border w-full flex flex-col gap-y-1 pt-2">
<text class="line-clamp-1 text-sm text-gray-900 font-bold">{{ dataSingle.spec.title }}</text>
<text class="line-clamp-2 text-xs text-gray-500">{{ dataSingle.status.excerpt }}</text>
</view>
</view>
</view>
<!-- 最新文章 -->
<view class="mt-4">
<view class="mb-2 box-border flex items-center justify-between px-4">
<text class="text-lg text-gray-900 font-bold">最新文章</text>
</view>
<view class="box-border w-full flex flex-col items-center justify-center gap-y-4 overflow-hidden px-4">
<view v-if="error && postList.length > 0" class="un-shadow-xs w-full rounded-2xl bg-white py-12">
<wd-empty :icon-size="60" icon="no-result" tip="暂无数据" />
</view>
<template v-else>
<view
v-for="post in postList" :key="post.metadata.name"
class="uh-shadow-xs flex justify-center overflow-hidden rounded-2xl bg-white p-4"
>
<image :src="completeUrl(post.spec.cover)" mode="aspectFill" class="h-22 w-22 shrink-0 rounded-lg" />
<view class="box-border flex-1 pl-4">
<view class="h-full flex flex-1 flex-col justify-between">
<view class="line-clamp-1 text-sm text-gray-900 font-bold">
{{ post.spec.title }}
</view>
<view class="line-clamp-2 text-xs text-gray-500">
{{ post.status.excerpt }}
</view>
<view class="w-full flex items-center gap-x-4">
<view class="text-xs text-gray-600">
{{ timeFrom(post.spec.publishTime) }}
</view>
<view class="text-xs text-gray-600">
·
</view>
<view class="text-xs text-gray-600">
{{ post.categories.map(c => c.spec.displayName).join('·') }}
</view>
</view>
</view>
</view>
</view>
</template>
</view>
</view>
<!-- 底部导航占位 -->
<view class="h-60px w-full" />
</view>
</template>
<style scoped>
.uh-shadow-xs {
box-shadow: 0 0 24rpx rgba(0, 0, 0, 0.035);
}
</style>
+1 -1
View File
@@ -57,7 +57,7 @@ function handleLogout() {
</script>
<template>
<view class="profile-container">
<view class="min-h-screen w-full flex flex-col items-center justify-center gap-y-6 bg-page">
<view class="mt-3 break-all px-3 text-center text-green-500">
{{ userInfo.username ? '已登录' : '未登录' }}
</view>
+1 -1
View File
@@ -11,7 +11,7 @@ definePage({
</script>
<template>
<view class="mt-10 text-center text-green-500">
<view class="min-h-screen w-full flex flex-col items-center justify-center gap-y-6 bg-page">
瞬间页面
</view>
</template>