Files
number/促销展示方案.md

202 lines
6.9 KiB
Markdown
Raw Permalink Normal View History

# 促销活动用户端展示方案
## 现状分析
- 后端已有用户端促销查询 API
- `GET /api/v1/promotions/skill/{skillId}` — 查询单个 Skill 的促销信息
- `POST /api/v1/promotions/skills/batch` — 批量查询促销信息
- 前端 `SkillCard.vue``detail.vue` **尚未调用这些 API**,也没有展示促销标签、促销价等信息
- 当前用户看到的只有:原价、划线价、"新品/免费/热门"标签
---
## 展示触点与优先级
促销信息应出现在 **4 个触点**,形成从"发现 → 浏览 → 决策"的完整转化路径:
| 优先级 | 触点 | 工作量 | 转化价值 |
|--------|------|--------|----------|
| **P0** | SkillCard 组件(促销标签 + 价格替换) | 小 | 高(覆盖所有列表场景) |
| **P0** | Skill 详情页(促销信息条 + 价格替换) | 中 | 最高(直接影响购买决策) |
| **P1** | 首页新增"限时特惠"专区 | 中 | 高(流量入口曝光) |
| **P2** | 商城列表页新增"促销中"筛选项 | 小 | 中(锦上添花) |
---
## P0-1SkillCard 组件 — 促销角标 + 价格替换
### 位置
`frontend/src/components/SkillCard.vue`
### 改动点
#### 1. 封面左上角标签区
- 有促销时,在已有标签(新品/免费/热门)旁新增一个**红色促销标签**
- 标签文字使用后端返回的 `tagText`(如"限时特惠"、"618折扣"
-`tagText` 为空则显示默认文案"促销中"
```html
<!-- 新增促销标签 -->
<a-tag v-if="promotion" color="red">{{ promotion.tagText || '促销中' }}</a-tag>
```
#### 2. 底部价格区域
- 有促销时:促销价作为主价格显示,原价显示为划线样式
- 无促销时:保持现有逻辑不变
```html
<!-- 有促销时的价格展示 -->
<span v-if="promotion" class="price promotion">
<span class="promo-price">¥{{ promotion.promotionPrice || calcDiscountPrice }}</span>
<span class="original">¥{{ skill.price }}</span>
</span>
```
#### 3. 数据获取方式
- **方案 A推荐**:在列表页加载 Skill 列表后,批量调用 `POST /promotions/skills/batch` 获取促销信息,合并到 skill 数据中传给 SkillCard
- **方案 B**SkillCard 内部自己请求不推荐N+1 问题)
### 涉及文件
- `frontend/src/components/SkillCard.vue` — 添加促销标签和价格展示
- `frontend/src/views/skill/list.vue` — 批量获取促销数据
- `frontend/src/views/home/index.vue` — 首页推荐区也需批量获取
- `frontend/src/service/apiService.js` — 新增用户端促销 API 调用
---
## P0-2Skill 详情页 — 促销信息条 + 价格替换
### 位置
`frontend/src/views/skill/detail.vue`
### 改动点
#### 1. 价格区域上方新增促销横条
- 醒目的渐变背景横条,包含:
- 促销标签tagText
- 倒计时:`距结束 XX:XX:XX`
- 节省金额:`省 ¥XX`
```html
<div v-if="promotion" class="promotion-banner">
<div class="promo-tag">{{ promotion.tagText || '限时折扣' }}</div>
<div class="promo-countdown">
<ClockCircleOutlined />
距结束 {{ countdown }}
</div>
<div class="promo-save">省 ¥{{ savingAmount }}</div>
</div>
```
#### 2. 价格区域替换
- 促销价作为主价格(大字、红色/品牌色)
- 原价小字划线
- 折扣率角标(如 "8折"
```html
<div class="skill-price" v-if="promotion">
<span class="promo-label">促销价</span>
<span class="promo-current">¥{{ promotionFinalPrice }}</span>
<span class="original-price">¥{{ skill.price }}</span>
<a-tag color="red" v-if="promotion.discountRate">
{{ Math.round(promotion.discountRate * 10) }}折
</a-tag>
</div>
```
#### 3. 购买按钮文案变化
- 有促销时:按钮文案从"现金购买"变为"立即抢购"
- 可选:按钮旁显示库存紧张提示(如 `promotion.stockLimit - promotion.soldCount` 较小时)
#### 4. 数据获取
- 在详情页 `onMounted` 时调用 `GET /promotions/skill/{skillId}` 获取促销信息
### 涉及文件
- `frontend/src/views/skill/detail.vue` — 促销横条、价格替换、按钮文案
- `frontend/src/service/apiService.js` — 用户端促销 API
---
## P1首页 — 限时特惠专区
### 位置
`frontend/src/views/home/index.vue`,在"热门分类"category-section和"精选推荐"content-section之间
### 展示形式
- 区块标题:`限时特惠` + 全局倒计时(取最近结束的促销活动时间)
- 横向滚动卡片列表,每张卡片展示:
- Skill 封面缩略图
- Skill 名称
- 促销价 + 原价划线
- 促销标签tagText
- 折扣率角标
- 右侧"查看更多"按钮跳转到商城列表页(带促销筛选)
### 数据获取
- 需要后端新增接口:`GET /promotions/active-skills` — 返回当前所有进行中促销关联的 Skill 列表(含促销信息)
- 或前端先获取活动列表再批量查询(多一次请求但不需改后端)
### 涉及文件
- `frontend/src/views/home/index.vue` — 新增促销专区
- 可能需要后端新增接口
---
## P2商城列表页 — 促销筛选
### 位置
`frontend/src/views/skill/list.vue` 筛选栏
### 改动点
- 筛选栏新增一个"促销中"筛选项(标签按钮或下拉选项)
- 选中后只显示有促销的 Skill
### 实现方式
- **方案 A**:后端支持 `hasPromotion=true` 查询参数
- **方案 B**:前端获取所有促销 Skill ID 后前端过滤(数据量小时可行)
### 涉及文件
- `frontend/src/views/skill/list.vue` — 新增筛选项
- 可能需要后端 Skill 列表接口支持促销筛选参数
---
## 前端新增 API 汇总
`frontend/src/service/apiService.js` 中新增用户端促销 API
```javascript
// ===================== 促销模块(用户端) =====================
export const promotionApi = {
// 查询单个 Skill 的促销信息
getSkillPromotion: (skillId) => api.get(`/promotions/skill/${skillId}`),
// 批量查询多个 Skill 的促销信息
batchGetSkillPromotions: (skillIds) => api.post('/promotions/skills/batch', skillIds),
}
```
---
## 样式规范
| 元素 | 颜色 | 字号 | 说明 |
|------|------|------|------|
| 促销标签 | `#ff4d4f`(红色) | 12px | 与"热门"标签同层 |
| 促销价 | `#ff4d4f` 或品牌主色 | 20px bold | 替代原价作为主价格 |
| 原价划线 | `var(--text-muted)` | 12px | 划线样式 |
| 促销横条背景 | 渐变 `#fff1f0 → #fff7e6` | — | 温暖的促销氛围 |
| 倒计时 | `#ff4d4f` | 14px | 紧迫感 |
| 折扣角标 | `#ff4d4f` 背景白字 | 11px bold | 如 "8折" |
---
## 实施顺序
1. **apiService.js** — 新增用户端促销 API 方法
2. **SkillCard.vue** — 接收 promotion prop展示标签和促销价
3. **list.vue** — 加载列表后批量获取促销,传给 SkillCard
4. **home/index.vue** — 首页推荐区也做相同处理
5. **detail.vue** — 详情页促销横条、价格替换、按钮文案
6. P1首页限时特惠专区
7. P2列表页促销筛选