Files
number/促销展示方案.md

202 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 促销活动用户端展示方案
## 现状分析
- 后端已有用户端促销查询 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列表页促销筛选