docs: 添加热门推荐模块前端设计
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
9a9f4d1b96
commit
d1b52e324f
339
docs/superpowers/specs/2026-05-28-热门推荐模块前端设计.md
Normal file
339
docs/superpowers/specs/2026-05-28-热门推荐模块前端设计.md
Normal file
@ -0,0 +1,339 @@
|
||||
# 热门推荐模块前端设计
|
||||
|
||||
## 一、页面结构
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────┐
|
||||
│ 热门推荐 │
|
||||
├──────────────────────────────────────┤
|
||||
│ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │
|
||||
│ │ │ │ │ │ │ │ │ ← 行1 │
|
||||
│ └────┘ └────┘ └────┘ └────┘ │
|
||||
│ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │
|
||||
│ │ │ │ │ │ │ │ │ ← 行2 │
|
||||
│ └────┘ └────┘ └────┘ └────┘ │
|
||||
│ 🔄 刷新 查看更多 ›│
|
||||
└──────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、组件结构
|
||||
|
||||
### 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
|
||||
<template>
|
||||
<view class="hot-category-block">
|
||||
<!-- 标题 -->
|
||||
<text class="block-title">{{ title }}</text>
|
||||
|
||||
<!-- 网格区域 -->
|
||||
<view v-if="loading" class="block-grid">
|
||||
<view v-for="i in 8" :key="i" class="skeleton-card">
|
||||
<view class="skeleton-shimmer"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-else-if="items.length === 0" class="empty-state">
|
||||
<text class="empty-text">暂无{{ title }}作品</text>
|
||||
</view>
|
||||
|
||||
<view v-else class="block-grid">
|
||||
<view
|
||||
v-for="(item, index) in items"
|
||||
:key="item.asset_id || index"
|
||||
class="hot-card"
|
||||
@click="handleCardClick(item)"
|
||||
>
|
||||
<image class="hot-card-image" :src="item.cover_url" mode="aspectFill" />
|
||||
<view class="hot-card-overlay">
|
||||
<view class="hot-card-user">
|
||||
<image class="user-avatar" :src="item.owner_avatar" mode="aspectFill" />
|
||||
<text class="user-name">{{ item.owner_nickname }}</text>
|
||||
</view>
|
||||
<view class="hot-card-likes">
|
||||
<image class="like-icon" src="/static/icon/heart-icon.png" mode="aspectFit" />
|
||||
<text class="like-count">{{ formatCount(item.likes) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<view class="block-actions">
|
||||
<view class="refresh-btn" :class="{ spinning: refreshing }" @click="handleRefresh">
|
||||
<text class="action-icon">↻</text>
|
||||
</view>
|
||||
<view class="more-btn" @click="handleViewMore">
|
||||
<text class="more-text">查看更多</text>
|
||||
<text class="more-arrow">›</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 七、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` | 拍立得类型 |
|
||||
Loading…
Reference in New Issue
Block a user