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

feat: 完成uni-halo小程序基础功能迭代

本次提交完成多项核心功能升级与优化:
1. 新增页面背景色变量page3并替换部分页面背景样式
2. 新增通用列表分页请求基础接口类型
3. 调整首页默认跳转路径为首页
4. 重构配置结构,新增插件配置模块
5. 新增瞬间、友链、相册相关API接口与类型定义
6. 重构useRequest导出方式,修复hook导出问题
7. 移除部分调试日志代码
8. 新增padStart兼容polyfill工具函数
9. 新增文章卡片多种布局样式支持
10. 优化友链页面UI展示与交互逻辑
11. 新增瞬间页面时间轴展示模式与时间解析工具
12. 新增相册页面多种浏览模式切换功能
This commit is contained in:
小莫唐尼
2026-06-14 22:00:54 +08:00
parent a60def91a0
commit 21eeb912fd
17 changed files with 717 additions and 150 deletions
+97 -26
View File
@@ -1,13 +1,18 @@
<script lang="ts" setup>
import { getCurrentInstance } from 'vue'
import useRequest from '@/hooks/useRequest'
import { storeToRefs } from 'pinia'
import { useRequest } from '@/hooks/useRequest'
import { random } from '@/utils/base/random'
import { queryLinkGroups, queryLinks } from '@/api/halo-plugin/link'
import { cover } from '@/utils/imageHelper'
import { copy } from '@/utils/base/clipboard'
import { getRect } from '@/utils/base/getRect'
import { useListData } from '@/hooks/useListData'
import type { IPaginationParams } from '@/hooks/useListData'
import { debounce } from '@/utils/base/debounce'
import { useUniHaloConfigStore } from '@/store/config'
import type { IPaginationParams } from '@/hooks/useListData'
import type { ILink, ILinkGroup, LinkTypes } from '@/api/halo-plugin/link'
import type { IHaloListResponseBase } from '@/api/types/halo'
defineOptions({
name: 'Links',
@@ -21,10 +26,13 @@ definePage({
},
})
const { loading: loadingGroups, error: errorGroups, data: dataGroups, run: runGroups } = useRequest<any>(queryLinkGroups, { loadingToast: false, loadingToastContent: '加载中...', loadingToastMask: true })
const { loading, error, data, run } = useRequest<any, IPaginationParams>(queryLinks, { loadingToast: false, loadingToastContent: '加载中...', loadingToastMask: true })
const { config } = storeToRefs(useUniHaloConfigStore())
const { reset } = useUniHaloConfigStore()
const { list: links, refresh } = useListData<any>({
const { loading: loadingGroups, error: errorGroups, data: dataGroups, run: runGroups } = useRequest<ILinkGroup[]>(queryLinkGroups, { loadingToast: false, loadingToastContent: '加载中...', loadingToastMask: true })
const { loading, error, data, run } = useRequest<IHaloListResponseBase<ILink>, IPaginationParams>(queryLinks, { loadingToast: false, loadingToastContent: '加载中...', loadingToastMask: true })
const { list: links, refresh } = useListData<ILink>({
params: {
page: 1,
size: 0,
@@ -53,12 +61,20 @@ interface ILinkGroupData {
name: string
index: string
priority: number
links: any[]
links: ILink[]
}
const linkTypes: LinkTypes[] = ['mpweixin', 'website', 'android', 'ios']
const linkGroups = computed(() => {
const groupedLinks = links.value.reduce((acc, link) => {
const groupName = link.spec.groupName
// 处理站点类型
link.uh = {
type: linkTypes[random(0, linkTypes.length - 1)],
}
const group = dataGroups.value?.find(item => item.metadata.name === groupName)
let _groupName = '未分组'
if (group) {
@@ -74,7 +90,7 @@ const linkGroups = computed(() => {
}
acc[_groupName].links.push(toRaw(link))
return acc
}, {} as Record<string, any[]>)
}, {} as Record<string, ILinkGroupData>)
// // 分组还需要根据 分组中的 spec.priority 字段进行排序
return Object.values(groupedLinks)
.map((item) => {
@@ -149,39 +165,54 @@ onLoad(async () => {
</script>
<template>
<view class="min-h-screen w-full flex flex-col bg-page2">
<!-- <view>
<view>分组数据</view>
<view>{{ dataGroups }}</view>
</view> -->
<view class="bg-page3 min-h-screen w-full flex flex-col">
<!-- 分组列表 -->
<view v-if="linkGroups.length !== 0" class="box-border w-full flex flex-col gap-y-4 overflow-hidden p-4 pb-0">
<template v-for="(item, index) in linkGroups" :key="item.name">
<view v-if="linkGroups.length !== 0" class="box-border w-full flex flex-col gap-y-6 overflow-hidden p-4 pb-0">
<view v-for="(item, index) in linkGroups" :key="item.name" class="flex flex-col gap-y-4">
<view
v-if="linkGroups.length !== 1" class="flex items-center justify-between text-sm"
:class="[`group-start-${index}`]"
>
<text class="font-bold">{{ item.name }}</text>
<view class="flex items-center gap-x-1 font-bold">
<wd-icon name="folder" :size="16" />
<text class="font-bold">{{ item.name }}</text>
</view>
<text class="text-xs text-gray-600"> {{ item.links.length }} 条记录 </text>
</view>
<!-- 分组卡片 -->
<view
v-for="(link, linkIndex) in item.links" :key="link.metadata.name"
class="uh-shadow-card box-border w-full flex flex-col items-center justify-center gap-y-2 overflow-hidden border-2 border-white rounded-xl border-solid bg-white p-4"
class="uh-shadow-card relative box-border w-full flex flex-col items-center justify-center gap-y-2 overflow-hidden rounded-xl bg-white p-4"
:class="[
linkIndex === item.links.length - 1 ? `group-end-${index}` : '',
]"
]" :style="{
boxShadow: '0 16rpx 60rpx rgba(0, 0, 0, 0.06)',
}"
>
<!-- 右上角装饰 -->
<view
class="uh-blur-3xl absolute right-0 top-0 h-12 w-12 rounded-full" :class="[
{
'bg-[#10B981]/30': link.uh.type === 'mpweixin',
'bg-[#007AFF]/30': link.uh.type === 'website',
'bg-[#FF9800]/30': link.uh.type === 'android',
'bg-[#FF5722]/30': link.uh.type === 'ios',
},
]"
/>
<!-- 顶部信息 -->
<view class="box-border w-full flex items-center justify-between gap-x-3">
<view
class="uh-shadow-md box-border h-10 w-10 shrink-0 overflow-hidden border-2 border-white rounded-xl border-solid bg-white"
class="uh-shadow-md box-border h-11 w-11 shrink-0 overflow-hidden border-2 border-white rounded-lg border-solid bg-white"
:style="{
boxShadow: '0 16rpx 40rpx rgba(0, 0, 0, 0.055)',
}"
>
<image :src="cover(link.spec.logo)" mode="aspectFill" class="h-full w-full" />
</view>
<view class="flex flex-1 flex-col gap-y-0.5">
<view class="box-border flex flex-1 flex-col gap-y-0.5 pl-1">
<view class="line-clamp-1 text-sm text-gray-900 font-bold">
{{ link.spec.displayName }}
</view>
@@ -189,22 +220,58 @@ onLoad(async () => {
{{ link.spec.url }}
</view>
</view>
<view class="shrink-0">
<view v-if="false" class="shrink-0">
<view
class="uh-shadow-md rounded-3xl bg-[#1A1A1A] px-4 py-1.5 text-xs text-white"
class="uh-shadow-md rounded-xl bg-gray-900 px-4 py-1.5 text-xs text-white"
@click="copy(link.spec.url, true)"
>
复制
</view>
</view>
</view>
<!-- 底部信息 -->
<view class="line-clamp-2 w-full text-xs text-gray-500 leading-relaxed">
<!-- 站点描述 -->
<view v-if="link.spec.description" class="line-clamp-2 mt-1 w-full text-xs text-gray-500 leading-relaxed">
{{ link.spec.description }}
<!-- {{ '你好,我是 UNI HALO v3.0 新版本,开源免费 Halo 博客小程序支持多端编译' }} -->
</view>
<!-- 底部操作区域 -->
<view class="w-full flex items-center justify-between">
<view class="flex shrink-0 items-center gap-x-2">
<view
class="box-border flex items-center justify-center border border-gray-200 rounded-lg border-solid p-2 text-gray-600"
>
<wd-icon name="share-alt" :size="14" />
</view>
<view
class="box-border flex items-center justify-center border border-gray-200 rounded-lg border-solid p-2 text-gray-600"
>
<wd-icon name="copy" :size="14" />
</view>
<view
v-if="false"
class="box-border flex items-center justify-center border border-gray-200 rounded-lg border-solid p-2 py-1.5 text-xs text-gray-600"
>
网站
</view>
</view>
<view class="mt-2 flex shrink-0 items-center justify-end gap-x-2">
<button
v-if="config.base.isIndividual"
class="uh-shadow-md rounded-lg bg-gray-900 px-4 py-2 text-xs text-white outline-0 border-none!"
@click="copy(link.spec.url, true)"
>
<wd-icon name="copy" :size="14" /> 复制
</button>
<button
v-if="!config.base.isIndividual"
class="uh-shadow-md rounded-lg bg-gray-900 px-4 py-2 text-xs text-white outline-0 border-none!"
>
<wd-icon name="Launch" :size="14" /> 访问
</button>
</view>
</view>
</view>
</template>
</view>
</view>
<view v-else class="w-full flex flex-1 items-center justify-center">
<wd-empty icon="no-content" tip="暂无友链">
@@ -216,7 +283,7 @@ onLoad(async () => {
<!-- 导航 -->
<view
v-if="!useBottomGroupNav && allGroupRects.length !== 0" class="fixed right-2 top-1/2 z-50" :style="{
v-if="!useBottomGroupNav && allGroupRects.length !== 0" class="fixed right-2 top-1/2 z-50 hidden!" :style="{
transform: 'translateY(-50%)',
}"
>
@@ -278,4 +345,8 @@ onLoad(async () => {
.uh-shadow-card {
box-shadow: 0 16rpx 60rpx rgba(0, 0, 0, 0.04);
}
.uh-blur-3xl {
filter: blur(64px);
}
</style>