mirror of
https://github.com/ialley-workshop-open/uni-halo.git
synced 2026-09-12 16:40:40 +08:00
feat: 新增公告模块、数据加载hook与多项体验优化
- 新增公告全流程功能:首页公告轮播、公告列表页、公告详情页 - 新增统一数据加载状态hook useDataLoading与配套测试 - 重构配置加载逻辑,新增统一bootstrap静态配置拉取 - 新增维护模式、恋爱模块支持与验证码防刷功能 - 优化投票卡片、联系页、关于页UI样式 - 新增测试页面与全局玻璃卡片样式 - 修复markdown容器内边距与首页生命周期逻辑
This commit is contained in:
@@ -320,10 +320,10 @@ onReachBottom(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="app-page min-h-screen w-screen flex flex-col" style="background-color: #fafafd;">
|
||||
<view class="app-page min-h-screen w-screen flex flex-col bg-page">
|
||||
<!-- 顶部 tabs -->
|
||||
<view class="tabs-wrap sticky top-0 z-10 bg-white px-6">
|
||||
<wd-tabs v-model="activeTabIndex" align="left" @change="handleOnTabChange">
|
||||
<view class="tabs-wrap uh-global-card-glass sticky top-0 z-10 px-6">
|
||||
<wd-tabs v-model="activeTabIndex" align="left" custom-style="background: transparent;" @change="handleOnTabChange">
|
||||
<wd-tab title="站点" />
|
||||
<wd-tab v-if="!appConfigStore.auditModeEnabled" title="小程序" />
|
||||
</wd-tabs>
|
||||
@@ -342,43 +342,42 @@ onReachBottom(() => {
|
||||
<wd-skeleton :row="5" :animated="true" />
|
||||
</view>
|
||||
|
||||
<view v-else class="content pt-6" :class="{ 'bg-white': dataList.length !== 0 }">
|
||||
<view v-else class="content pt-4">
|
||||
<view v-if="dataList.length === 0" class="h-[60vh] flex items-center justify-center content-empty">
|
||||
<wd-empty description="啊偶,博主还没有朋友呢~" />
|
||||
</view>
|
||||
|
||||
<!-- 友链列表 -->
|
||||
<view v-else class="link-list px-6">
|
||||
<view v-for="(link, index) in dataList" :key="index">
|
||||
<view v-else class="link-list flex flex-col gap-4 px-4 pb-4">
|
||||
<view v-for="link in dataList" :key="link.metadata?.name || link.spec.displayName">
|
||||
<!-- 色彩版 -->
|
||||
<view
|
||||
v-if="!globalAppSettings.links.useSimple"
|
||||
class="info flex bg-white p-3"
|
||||
:class="{ 'border-b-2 border-[#f5f5f5]': index !== dataList.length - 1 }"
|
||||
class="info uh-global-card-glass flex rounded-2xl p-3"
|
||||
@click="handleOnLinkEvent(link)"
|
||||
>
|
||||
<image class="link-logo h-[140rpx] w-[140rpx] shrink-0 rounded-xl" :src="link.spec.logo" mode="aspectFill" />
|
||||
<view class="info-detail flex flex-1 flex-col justify-center pl-7">
|
||||
<view class="link-card-name text-[30rpx] text-[#f44336] font-bold">
|
||||
<text class="group-tag mr-3 rounded-md px-1.5 py-0.5 text-[20rpx] text-white font-normal" style="background: linear-gradient(135deg, #64b5f6, #2196f3);">{{ link.spec.groupName || '暂未分组' }}</text>
|
||||
<view class="info-detail flex flex-1 flex-col justify-center pl-5">
|
||||
<view class="link-card-name text-[30rpx] text-gray-900 font-bold">
|
||||
<text class="group-tag mr-3 rounded-md bg-secondary px-1.5 py-0.5 text-[20rpx] text-[#4d7c0f] font-normal">{{ link.spec.groupName || '暂未分组' }}</text>
|
||||
{{ link.spec.displayName }}
|
||||
</view>
|
||||
<view class="link-card-url mt-1 overflow-hidden text-ellipsis whitespace-nowrap text-[24rpx] text-[#666]">
|
||||
<view class="link-card-url mt-1 overflow-hidden text-ellipsis whitespace-nowrap text-[24rpx] text-gray-400">
|
||||
站点地址:{{ link.spec.url }}
|
||||
</view>
|
||||
<view class="link-card-desc mt-2 overflow-hidden text-ellipsis whitespace-nowrap text-[24rpx] text-[#303133]">
|
||||
<view class="link-card-desc mt-2 overflow-hidden text-ellipsis whitespace-nowrap text-[24rpx] text-gray-600">
|
||||
博客简介:{{ link.spec.description || '这个博主很懒,没写简介~' }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 简洁版 -->
|
||||
<view v-else class="link-card mb-6 flex items-center rounded-xl bg-white p-6 shadow-sm" @click="handleOnLinkEvent(link)">
|
||||
<image class="logo h-[80rpx] w-[80rpx] shrink-0 border-6 border-white rounded-xl" :src="link.spec.logo" mode="aspectFill" />
|
||||
<view class="link-info flex-1 pl-6">
|
||||
<view class="name text-[30rpx] text-[#303133] font-bold">
|
||||
<view v-else class="link-card uh-global-card-glass flex items-center rounded-2xl p-4" @click="handleOnLinkEvent(link)">
|
||||
<image class="logo h-[80rpx] w-[80rpx] shrink-0 border-4 border-white/90 rounded-xl" :src="link.spec.logo" mode="aspectFill" />
|
||||
<view class="link-info flex-1 pl-5">
|
||||
<view class="name text-[30rpx] text-gray-900 font-bold">
|
||||
{{ link.spec.displayName }}
|
||||
</view>
|
||||
<view class="desc mt-3 overflow-hidden text-ellipsis whitespace-nowrap text-[24rpx] text-[#909399]">
|
||||
<view class="desc mt-2 overflow-hidden text-ellipsis whitespace-nowrap text-[24rpx] text-gray-400">
|
||||
{{ link.spec.description }}
|
||||
</view>
|
||||
</view>
|
||||
@@ -388,39 +387,39 @@ onReachBottom(() => {
|
||||
|
||||
<!-- 悬浮按钮 -->
|
||||
<view class="flot-buttons fixed bottom-[100rpx] right-8 z-999 flex flex-col gap-1.5">
|
||||
<view class="fab-btn h-[72rpx] w-[72rpx] flex items-center justify-center rounded-full bg-white shadow-sm" @click="handleToTopPage()">
|
||||
<wd-icon name="arrow-up" size="20px" color="#03a9f4" />
|
||||
<view class="fab-btn uh-global-card-glass h-[72rpx] w-[72rpx] flex items-center justify-center rounded-full" @click="handleToTopPage()">
|
||||
<wd-icon name="arrow-up" size="20px" color="#6b7280" />
|
||||
</view>
|
||||
<view v-if="(haloPluginConfigs?.linksSubmitPlugin as { enabled?: boolean } | undefined)?.enabled" class="fab-btn h-[72rpx] w-[72rpx] flex items-center justify-center rounded-full bg-white shadow-sm" @click="toSubmitLinkPage">
|
||||
<wd-icon name="edit" size="20px" color="#ff9800" />
|
||||
<view v-if="(haloPluginConfigs?.linksSubmitPlugin as { enabled?: boolean } | undefined)?.enabled" class="fab-btn uh-global-card-glass h-[72rpx] w-[72rpx] flex items-center justify-center rounded-full" @click="toSubmitLinkPage">
|
||||
<wd-icon name="edit" size="20px" color="#6b7280" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 详情弹窗 -->
|
||||
<wd-popup v-model="detail.show" position="center" custom-style="width:640rpx;border-radius:12rpx;">
|
||||
<view v-if="detail.data" class="poup p-9">
|
||||
<view v-if="detail.data" class="poup p-8">
|
||||
<view class="info flex">
|
||||
<image class="poup-logo h-[140rpx] w-[140rpx] shrink-0 rounded-full" :src="checkImageUrl(detail.data.spec.logo)" mode="aspectFill" />
|
||||
<view class="poup-info ml-6 flex flex-1 flex-col justify-center">
|
||||
<view class="poup-name text-[34rpx] font-bold">
|
||||
<view class="poup-name text-[34rpx] text-gray-900 font-bold">
|
||||
{{ detail.data.spec.displayName }}
|
||||
</view>
|
||||
<view class="poup-tag mt-2 text-[24rpx] text-[#999]">
|
||||
<view class="poup-tag mt-2 text-[24rpx] text-gray-400">
|
||||
{{ detail.data.spec.groupName }}
|
||||
</view>
|
||||
<view class="poup-link mt-3" @click="handleCopyLink(detail.data)">
|
||||
<text class="poup-url text-[24rpx] text-[#ff9800]">{{ detail.data.spec.url }}</text>
|
||||
<text class="poup-url rounded-lg bg-secondary px-2 py-1 text-[24rpx] text-[#4d7c0f]">{{ detail.data.spec.url }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="poup-desc mt-5 text-[28rpx] text-[#555] leading-[1.6]">
|
||||
<view class="poup-desc mt-5 text-[28rpx] text-gray-600 leading-[1.6]">
|
||||
博客简介:{{ detail.data.spec.description || '这个博主很懒,没写简介~' }}
|
||||
</view>
|
||||
<image class="poup-img mt-6 h-[320rpx] w-[568rpx] rounded-xl" :src="calcSiteThumbnail(detail.data.spec.url)" mode="aspectFill" />
|
||||
<image class="poup-img mt-6 h-[320rpx] w-full rounded-xl" :src="calcSiteThumbnail(detail.data.spec.url)" mode="aspectFill" />
|
||||
</view>
|
||||
</wd-popup>
|
||||
|
||||
<view class="load-text py-5 text-center text-[24rpx] text-[#999]">
|
||||
<view class="load-text py-5 text-center text-[24rpx] text-gray-400">
|
||||
{{ loadMoreText }}
|
||||
</view>
|
||||
</view>
|
||||
@@ -450,15 +449,15 @@ onReachBottom(() => {
|
||||
<view v-else class="mini-link-list flex-1 px-6 py-4">
|
||||
<view v-for="group in miniGroups" :key="group.groupName || 'ungrouped'" class="group-item mb-8">
|
||||
<view class="group-title mb-4 flex items-center">
|
||||
<text class="mr-2 inline-block h-[28rpx] w-[8rpx] rounded-full" style="background-color:#2196f3;" />
|
||||
<text class="text-[30rpx] text-[#303133] font-bold">{{ group.displayName || '未分组' }}</text>
|
||||
<text class="ml-3 text-[24rpx] text-[#999]">({{ group.links.length }})</text>
|
||||
<text class="mr-2 inline-block h-[28rpx] w-[8rpx] rounded-full bg-secondary" />
|
||||
<text class="text-[30rpx] text-gray-900 font-bold">{{ group.displayName || '未分组' }}</text>
|
||||
<text class="ml-3 text-[24rpx] text-gray-400">({{ group.links.length }})</text>
|
||||
</view>
|
||||
<view class="group-cards flex flex-col gap-4">
|
||||
<view
|
||||
v-for="link in group.links"
|
||||
:key="link.metadata?.name"
|
||||
class="mini-card flex items-center rounded-xl bg-white p-4 shadow-sm"
|
||||
class="mini-card uh-global-card-glass flex items-center rounded-2xl p-4"
|
||||
@click="handleOnMiniLinkEvent(link)"
|
||||
>
|
||||
<image
|
||||
@@ -467,17 +466,17 @@ onReachBottom(() => {
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<view class="mini-info flex flex-1 flex-col pl-5">
|
||||
<view class="mini-name overflow-hidden text-ellipsis whitespace-nowrap text-[30rpx] text-[#303133] font-bold">
|
||||
<view class="mini-name overflow-hidden text-ellipsis whitespace-nowrap text-[30rpx] text-gray-900 font-bold">
|
||||
{{ link.spec?.displayName }}
|
||||
</view>
|
||||
<view v-if="link.spec?.authorName" class="mini-author mt-1 overflow-hidden text-ellipsis whitespace-nowrap text-[24rpx] text-[#999]">
|
||||
<view v-if="link.spec?.authorName" class="mini-author mt-1 overflow-hidden text-ellipsis whitespace-nowrap text-[24rpx] text-gray-400">
|
||||
{{ link.spec.authorName }}
|
||||
</view>
|
||||
<view class="mini-desc mt-1 overflow-hidden text-ellipsis whitespace-nowrap text-[24rpx] text-[#666]">
|
||||
<view class="mini-desc mt-1 overflow-hidden text-ellipsis whitespace-nowrap text-[24rpx] text-gray-500">
|
||||
{{ link.spec?.description || '暂无简介~' }}
|
||||
</view>
|
||||
</view>
|
||||
<wd-icon name="arrow-right" size="16px" color="#c0c4cc" />
|
||||
<wd-icon name="arrow-right" size="16px" color="#c8c2b4" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -485,7 +484,7 @@ onReachBottom(() => {
|
||||
|
||||
<!-- 申请收录悬浮按钮 -->
|
||||
<view class="apply-btn-wrap fixed bottom-[100rpx] right-8 z-999">
|
||||
<view class="apply-btn h-[88rpx] flex items-center rounded-full bg-[#2196f3] px-6 shadow-sm" @click="handleOpenApply">
|
||||
<view class="apply-btn h-[88rpx] flex items-center rounded-full bg-gray-900 px-6" @click="handleOpenApply">
|
||||
<wd-icon name="add" size="20px" color="#fff" />
|
||||
<text class="ml-2 text-[26rpx] text-white">申请收录</text>
|
||||
</view>
|
||||
@@ -504,42 +503,42 @@ onReachBottom(() => {
|
||||
@click="handlePreviewMiniProgramCode(miniDetail.data)"
|
||||
@longpress="handleSaveMiniProgramCode(miniDetail.data)"
|
||||
/>
|
||||
<view class="code-tip mt-3 flex items-center text-[24rpx] text-[#999]">
|
||||
<wd-icon name="picture" size="14px" color="#999" />
|
||||
<view class="code-tip mt-3 flex items-center text-[24rpx] text-gray-400">
|
||||
<wd-icon name="picture" size="14px" color="#a8a294" />
|
||||
<text class="ml-1">点击预览,长按保存太阳码</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 名称与分组 -->
|
||||
<view class="mini-head mt-5 flex items-center">
|
||||
<text class="mini-name text-[34rpx] text-[#303133] font-bold">{{ miniDetail.data.spec?.displayName }}</text>
|
||||
<text v-if="miniDetail.data.spec?.groupName" class="group-tag ml-3 rounded-md px-2 py-0.5 text-[20rpx] text-white" style="background: linear-gradient(135deg, #64b5f6, #2196f3);">
|
||||
<text class="mini-name text-[34rpx] text-gray-900 font-bold">{{ miniDetail.data.spec?.displayName }}</text>
|
||||
<text v-if="miniDetail.data.spec?.groupName" class="group-tag ml-3 rounded-md bg-secondary px-2 py-0.5 text-[20rpx] text-[#4d7c0f]">
|
||||
{{ miniDetail.data.spec.groupName }}
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<!-- 描述 -->
|
||||
<view v-if="miniDetail.data.spec?.description" class="mini-desc mt-4 text-[28rpx] text-[#555] leading-[1.6]">
|
||||
<view v-if="miniDetail.data.spec?.description" class="mini-desc mt-4 text-[28rpx] text-gray-600 leading-[1.6]">
|
||||
{{ miniDetail.data.spec.description }}
|
||||
</view>
|
||||
|
||||
<!-- 作者信息 -->
|
||||
<view v-if="miniDetail.data.spec?.authorName || miniDetail.data.spec?.avatar || miniDetail.data.spec?.website" class="mini-author-info mt-5 flex items-center rounded-xl bg-[#f5f5f5] p-4">
|
||||
<view v-if="miniDetail.data.spec?.authorName || miniDetail.data.spec?.avatar || miniDetail.data.spec?.website" class="mini-author-info mt-5 flex items-center rounded-xl bg-[#f6f3ee] p-4">
|
||||
<image v-if="miniDetail.data.spec?.avatar" class="author-avatar h-[72rpx] w-[72rpx] shrink-0 rounded-full" :src="checkAvatarUrl(miniDetail.data.spec.avatar)" mode="aspectFill" />
|
||||
<view class="author-detail ml-4 flex flex-1 flex-col">
|
||||
<text v-if="miniDetail.data.spec?.authorName" class="author-name text-[28rpx] text-[#303133] font-medium">{{ miniDetail.data.spec.authorName }}</text>
|
||||
<text v-if="miniDetail.data.spec?.website" class="author-website mt-1 overflow-hidden text-ellipsis whitespace-nowrap text-[24rpx] text-[#999]" @click="handleCopyMiniProgramCode(miniDetail.data)">
|
||||
<text v-if="miniDetail.data.spec?.authorName" class="author-name text-[28rpx] text-gray-900 font-medium">{{ miniDetail.data.spec.authorName }}</text>
|
||||
<text v-if="miniDetail.data.spec?.website" class="author-website mt-1 overflow-hidden text-ellipsis whitespace-nowrap text-[24rpx] text-gray-400" @click="handleCopyMiniProgramCode(miniDetail.data)">
|
||||
网站:{{ miniDetail.data.spec.website }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 小程序地址 -->
|
||||
<view v-if="miniDetail.data.spec?.link" class="mini-link mt-5 flex items-center justify-between rounded-xl bg-[#fff8f0] p-4">
|
||||
<view class="link-text flex-1 overflow-hidden text-ellipsis whitespace-nowrap text-[26rpx] text-[#ff9800]">
|
||||
<view v-if="miniDetail.data.spec?.link" class="mini-link mt-5 flex items-center justify-between rounded-xl bg-secondary p-4">
|
||||
<view class="link-text flex-1 overflow-hidden text-ellipsis whitespace-nowrap text-[26rpx] text-[#4d7c0f]">
|
||||
{{ miniDetail.data.spec.link }}
|
||||
</view>
|
||||
<text class="ml-3 shrink-0 text-[26rpx] text-[#ff9800]" @click="handleCopyMiniProgramCode(miniDetail.data)">复制</text>
|
||||
<text class="ml-3 shrink-0 text-[26rpx] text-[#4d7c0f] font-bold" @click="handleCopyMiniProgramCode(miniDetail.data)">复制</text>
|
||||
</view>
|
||||
|
||||
<!-- 预览图轮播 -->
|
||||
@@ -559,9 +558,3 @@ onReachBottom(() => {
|
||||
</template>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.app-page {
|
||||
/* 布局全部由 UnoCSS 原子类实现 */
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user