# 热门推荐模块前端设计 ## 一、页面结构 ### 完整页面布局(4个分类区块纵向堆叠) ``` ┌──────────────────────────────────────┐ │ BannerCarousel │ ├──────────────────────────────────────┤ │ 热门推荐 │ │ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │ │ │ │ │ │ │ │ │ │ ← 行1 │ │ └────┘ └────┘ └────┘ └────┘ │ │ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │ │ │ │ │ │ │ │ │ │ ← 行2 │ │ └────┘ └────┘ └────┘ └────┘ │ │ 🔄 刷新 查看更多 ›│ ├──────────────────────────────────────┤ │ 热门星卡 │ │ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │ │ │ │ │ │ │ │ │ │ ← 行1 │ │ └────┘ └────┘ └────┘ └────┘ │ │ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │ │ │ │ │ │ │ │ │ │ ← 行2 │ │ └────┘ └────┘ └────┘ └────┘ │ │ 🔄 刷新 查看更多 ›│ ├──────────────────────────────────────┤ │ 热门吧唧 │ │ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │ │ │ │ │ │ │ │ │ │ ← 行1 │ │ └────┘ └────┘ └────┘ └────┘ │ │ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │ │ │ │ │ │ │ │ │ │ ← 行2 │ │ └────┘ └────┘ └────┘ └────┘ │ │ 🔄 刷新 查看更多 ›│ ├──────────────────────────────────────┤ │ 热门海报 │ │ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │ │ │ │ │ │ │ │ │ │ ← 行1 │ │ └────┘ └────┘ └────┘ └────┘ │ │ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │ │ │ │ │ │ │ │ │ │ ← 行2 │ │ └────┘ └────┘ └────┘ └────┘ │ │ 🔄 刷新 查看更多 ›│ ├──────────────────────────────────────┤ │ CreationGrid(原有组件,不变) │ │ [热门作品] [最新作品] [星卡] [吧唧]... │ └──────────────────────────────────────┘ ``` ### 单个 HotCategoryBlock 内部结构 ``` ┌──────────────────────────────────────┐ │ 热门推荐 │ ← block-title ├──────────────────────────────────────┤ │ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │ │ │ │ │ │ │ │ │ │ │ │ └────┘ └────┘ └────┘ └────┘ │ ← block-grid (4×2) │ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │ │ │ │ │ │ │ │ │ │ │ │ └────┘ └────┘ └────┘ └────┘ │ │ 🔄 刷新 查看更多 ›│ ← block-actions └──────────────────────────────────────┘ ``` --- ## 二、组件结构 ### HotCategoryBlock.vue **Props**: ```javascript { categoryType: String, // 后端返回的 type: "hot_recommend" / "hot_star_card" / "hot_badge" / "hot_poster" title: String // 后端返回的标题: "热门推荐" } ``` **状态**: - `items: Array` — 作品列表 - `loading: Boolean` — 首次加载中(显示骨架屏) - `refreshing: Boolean` — 刷新中(按钮旋转动画) - `hasMore: Boolean` — 是否有更多可加载 **事件**: - `cardClick(item)` — 点击卡片,跳转详情 --- ## 三、样式规范 ### 3.1 布局 | 属性 | 值 | |------|-----| | 区块间距 | 上下 `32rpx`,左右 `24rpx` | | 网格 | 4列 × 2行,间距 `16rpx` | | 卡片宽 | `=(屏宽 - 48rpx - 48rpx) / 4` | | 卡片高 | `卡片宽 × 1.3` | | 圆角 | `16rpx` | ### 3.2 卡片样式 ```css .hot-card { border-radius: 16rpx; overflow: hidden; position: relative; background: rgba(255, 255, 255, 0.15); backdrop-filter: blur(10rpx); box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15); } .hot-card-image { width: 100%; height: 100%; display: block; } /* 底部渐变遮罩 */ .hot-card-overlay { position: absolute; bottom: 0; left: 0; right: 0; height: 64rpx; background: linear-gradient(to top, rgba(0,0,0,0.6), transparent); display: flex; align-items: flex-end; justify-content: space-between; padding: 0 12rpx 12rpx; } .hot-card-user { display: flex; align-items: center; } .user-avatar { width: 32rpx; height: 32rpx; border-radius: 50%; margin-right: 6rpx; } .user-name { font-size: 20rpx; color: #fff; max-width: 120rpx; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .hot-card-likes { display: flex; align-items: center; } .like-icon { width: 20rpx; height: 20rpx; margin-right: 4rpx; } .like-count { font-size: 20rpx; color: #fff; } ``` ### 3.3 标题栏样式 ```css .block-title { font-size: 30rpx; font-weight: 600; color: #fff; padding: 0 24rpx 16rpx; } ``` ### 3.4 操作按钮样式 ```css .block-actions { display: flex; align-items: center; justify-content: flex-end; padding: 16rpx 24rpx 0; gap: 24rpx; } .refresh-btn { display: flex; align-items: center; } .refresh-btn .action-icon { font-size: 28rpx; color: rgba(255, 255, 255, 0.7); } .refresh-btn.spinning .action-icon { animation: spin 0.8s linear; } @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } .more-btn { display: flex; align-items: center; } .more-text { font-size: 24rpx; color: rgba(255, 255, 255, 0.7); } .more-arrow { font-size: 24rpx; color: rgba(255, 255, 255, 0.7); margin-left: 4rpx; } ``` --- ## 四、状态处理 | 状态 | 表现 | |------|------| | `loading=true` | 显示 8 个骨架屏卡片,操作按钮禁用 | | `loading=false && items.length=0` | 空状态提示:「暂无{{title}}作品」 | | `loading=false && items.length>0` | 正常显示 8 张卡片 | | `refreshing=true` | 刷新按钮旋转动画,卡片 fade-out | | `refreshing=false` | 刷新完成,卡片 fade-in | --- ## 五、骨架屏样式 ```css .skeleton-card { border-radius: 16rpx; background: #3a3a4a; overflow: hidden; position: relative; } .skeleton-shimmer { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient( 90deg, transparent 0%, rgba(255, 255, 255, 0.1) 50%, transparent 100% ); animation: shimmer 1.5s infinite; } @keyframes shimmer { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } } ``` --- ## 六、完整组件模板 ```vue ``` --- ## 七、API 调用 ```javascript // 单个分类刷新 export function getHotInspirationFlowApi(type) { return request({ url: '/api/v1/inspiration-flow/hot', method: 'GET', data: { type } }) } // 查看更多分页 export function getHotInspirationFlowMoreApi(type, cursor = '', limit = 20) { return request({ url: '/api/v1/inspiration-flow/hot/more', method: 'GET', data: { type, cursor, limit } }) } ``` --- ## 八、hot-category-more.vue 页面 **路由参数**: - `type` — 分类类型 - `title` — 标题(URL 编码) **页面结构**: ``` ┌──────────────────────────────────────┐ │ ← 返回 热门星卡 │ ├──────────────────────────────────────┤ │ [全部] [光栅卡] [镭射卡] [撕拉卡] [拍立得] │ ← 仅星卡显示 ├──────────────────────────────────────┤ │ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │ │ │ │ │ │ │ │ │ │ │ │ └────┘ └────┘ └────┘ └────┘ │ │ ... │ └──────────────────────────────────────┘ ``` **星卡子标签**(仅 `hot_star_card` 显示): | 子标签 | value | 说明 | |-------|-------|------| | 全部 | `all` | 全部星卡 | | 光栅卡 | `raster` | 光栅卡类型 | | 镭射卡 | `holographic` | 镭射卡类型 | | 撕拉卡 | `tear_off` | 撕拉卡类型 | | 拍立得 | `polaroid` | 拍立得类型 |