230 lines
6.8 KiB
Markdown
230 lines
6.8 KiB
Markdown
# 运营活动功能实现计划
|
||
|
||
## 背景
|
||
|
||
用户希望添加一个运营活动功能:
|
||
- 用户可以进入运营活动界面
|
||
- 通过水晶购买道具推进活动进程
|
||
- 购买道具可获得贡献点
|
||
- 后台统计贡献点排名
|
||
- 运营活动有时间限制
|
||
- 不同阶段展示不同界面效果
|
||
|
||
**现有代码基础**:
|
||
- 前端已有应援活动页面 (`frontend/pages/support-activity/`)
|
||
- 已有活动配置 (`frontend/utils/activity-config.js`)
|
||
- 已有排行榜服务可作为参考 (`backend/services/assetService/service/ranking_service.go`)
|
||
- 水晶余额在 `fan_profiles.crystal_balance` 中
|
||
|
||
---
|
||
|
||
## 实现方案
|
||
|
||
### 1. 数据库设计
|
||
|
||
**✅ 已确认: 道具配置使用数据库方式**
|
||
|
||
新建表:`activities`, `activity_items`, `activity_contributions`, `activity_user_stats`
|
||
|
||
```sql
|
||
-- 运营活动表
|
||
CREATE TABLE IF NOT EXISTS activities (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
activity_type VARCHAR(50) NOT NULL, -- 活动类型: birthday/concert/bus
|
||
title VARCHAR(100) NOT NULL, -- 活动标题
|
||
description TEXT, -- 活动描述
|
||
star_id BIGINT NOT NULL, -- 所属明星
|
||
start_time BIGINT NOT NULL, -- 开始时间
|
||
end_time BIGINT NOT NULL, -- 结束时间
|
||
target_progress BIGINT NOT NULL DEFAULT 1000, -- 目标进度
|
||
current_progress BIGINT NOT NULL DEFAULT 0, -- 当前进度
|
||
status VARCHAR(20) NOT NULL DEFAULT 'pending', -- pending/active/completed/expired
|
||
stage_configs JSONB, -- 阶段配置 (不同进度的背景图等)
|
||
created_at BIGINT NOT NULL,
|
||
updated_at BIGINT NOT NULL
|
||
);
|
||
|
||
-- 活动道具表 (数据库配置,支持运营平台动态调整)
|
||
CREATE TABLE IF NOT EXISTS activity_items (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
activity_id BIGINT NOT NULL,
|
||
item_type VARCHAR(50) NOT NULL, -- 道具类型: firework/megaphone/love
|
||
item_name VARCHAR(50) NOT NULL, -- 道具名称
|
||
icon_url VARCHAR(500), -- 道具图标
|
||
crystal_cost INTEGER NOT NULL, -- 水晶消耗
|
||
contribution_points INTEGER NOT NULL, -- 贡献点奖励
|
||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||
is_active BOOLEAN NOT NULL DEFAULT true,
|
||
created_at BIGINT NOT NULL,
|
||
updated_at BIGINT NOT NULL
|
||
);
|
||
|
||
-- 用户活动贡献记录表
|
||
CREATE TABLE IF NOT EXISTS activity_contributions (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
activity_id BIGINT NOT NULL,
|
||
user_id BIGINT NOT NULL,
|
||
star_id BIGINT NOT NULL,
|
||
item_id BIGINT NOT NULL,
|
||
item_type VARCHAR(50) NOT NULL,
|
||
quantity INTEGER NOT NULL DEFAULT 1,
|
||
crystal_spent BIGINT NOT NULL,
|
||
contribution_points BIGINT NOT NULL,
|
||
created_at BIGINT NOT NULL
|
||
);
|
||
|
||
-- 用户活动贡献汇总表 (用于排行榜)
|
||
CREATE TABLE IF NOT EXISTS activity_user_stats (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
activity_id BIGINT NOT NULL,
|
||
user_id BIGINT NOT NULL,
|
||
star_id BIGINT NOT NULL,
|
||
total_contribution BIGINT NOT NULL DEFAULT 0,
|
||
total_crystal_spent BIGINT NOT NULL DEFAULT 0,
|
||
total_items INTEGER NOT NULL DEFAULT 0,
|
||
last_contribute_at BIGINT NOT NULL,
|
||
created_at BIGINT NOT NULL,
|
||
updated_at BIGINT NOT NULL,
|
||
|
||
CONSTRAINT uk_activity_user_star UNIQUE (activity_id, user_id, star_id)
|
||
);
|
||
```
|
||
|
||
### 2. Proto 定义
|
||
|
||
新建 `backend/proto/activity.proto`:
|
||
|
||
```protobuf
|
||
// 活动相关消息定义
|
||
message Activity {
|
||
int64 id = 1;
|
||
string activity_type = 2;
|
||
string title = 3;
|
||
string description = 4;
|
||
int64 star_id = 5;
|
||
int64 start_time = 6;
|
||
int64 end_time = 7;
|
||
int64 target_progress = 8;
|
||
int64 current_progress = 9;
|
||
string status = 10;
|
||
string current_stage = 11; // 当前阶段: early/mid/late/completed
|
||
repeated ActivityItem items = 12;
|
||
}
|
||
|
||
message ActivityItem {
|
||
int64 id = 1;
|
||
string item_type = 2;
|
||
string item_name = 3;
|
||
string icon_url = 4;
|
||
int32 crystal_cost = 5;
|
||
int32 contribution_points = 6;
|
||
}
|
||
|
||
// 贡献购买请求
|
||
message PurchaseItemRequest {
|
||
int64 activity_id = 1;
|
||
string item_type = 2;
|
||
int32 quantity = 3;
|
||
int64 star_id = 4;
|
||
}
|
||
|
||
// 贡献点排名
|
||
message ContributionRankingRequest {
|
||
int64 activity_id = 1;
|
||
int64 star_id = 2;
|
||
int32 page = 3;
|
||
int32 page_size = 4;
|
||
}
|
||
|
||
message ContributionRankingItem {
|
||
int32 rank = 1;
|
||
int64 user_id = 2;
|
||
string nickname = 3;
|
||
string avatar_url = 4;
|
||
int64 total_contribution = 5;
|
||
int64 total_crystal_spent = 6;
|
||
}
|
||
|
||
message MyContribution {
|
||
int32 rank = 1;
|
||
int64 total_contribution = 2;
|
||
int64 total_crystal_spent = 3;
|
||
string status = 4; // ranked/unranked
|
||
}
|
||
```
|
||
|
||
### 3. 后端服务实现
|
||
|
||
**新建服务**: `backend/services/activityService/`
|
||
|
||
- `main.go` - 服务入口
|
||
- `service/activity_service.go` - 业务逻辑
|
||
- `repository/activity_repository.go` - 数据库操作
|
||
- `provider/activity_provider.go` - Dubbo provider
|
||
|
||
**API 端点** (通过 gateway):
|
||
- `GET /api/v1/activities/:id` - 获取活动详情
|
||
- `GET /api/v1/activities/:id/items` - 获取活动道具列表
|
||
- `POST /api/v1/activities/:id/purchase` - 购买道具
|
||
- `GET /api/v1/activities/:id/ranking` - 贡献点排名
|
||
- `GET /api/v1/activities?star_id=:star_id` - 获取活动列表
|
||
|
||
**水晶扣减逻辑**:
|
||
1. 检查用户水晶余额是否足够
|
||
2. 扣减水晶 (`fan_profiles.crystal_balance`)
|
||
3. 增加活动进度
|
||
4. 记录贡献明细
|
||
5. 更新用户贡献汇总
|
||
6. 返回结果
|
||
|
||
### 4. 前端实现
|
||
|
||
**修改文件**:
|
||
- `frontend/utils/activity-config.js` - 添加动态阶段配置
|
||
- `frontend/pages/support-activity/index.vue` - 接入后端 API
|
||
- `frontend/pages/support-activity/components/ActionBar.vue` - 购买道具交互
|
||
- `frontend/utils/api.js` - 添加活动 API
|
||
|
||
**阶段展示逻辑**:
|
||
```
|
||
- 0-25%: 初期 (early) - 初始背景
|
||
- 26-50%: 中期 (mid) - 中期背景
|
||
- 51-75%: 后期 (late) - 后期背景
|
||
- 76-100%: 完成 (completed) - 完成背景 + 特效动画
|
||
```
|
||
|
||
**时间限制显示**:
|
||
- 活动未开始: 显示"距开始还有 X 天"
|
||
- 活动进行中: 显示"还剩 X 天 X 小时"
|
||
- 活动已结束: 显示"活动已结束"
|
||
|
||
---
|
||
|
||
## 关键文件路径
|
||
|
||
| 组件 | 文件路径 |
|
||
|------|----------|
|
||
| 数据库初始化 | `backend/scripts/init_database.sql` |
|
||
| Proto 定义 | `backend/proto/activity.proto` (新建) |
|
||
| 活动服务 | `backend/services/activityService/` (新建) |
|
||
| Gateway 路由 | `backend/gateway/controller/` (新增) |
|
||
| 前端活动配置 | `frontend/utils/activity-config.js` |
|
||
| 前端活动页面 | `frontend/pages/support-activity/index.vue` |
|
||
| 前端 API | `frontend/utils/api.js` |
|
||
|
||
---
|
||
|
||
## 验证方案
|
||
|
||
1. **数据库**: 确认表创建成功,索引正确
|
||
2. **后端 API**:
|
||
- 创建活动,验证返回
|
||
- 购买道具,验证水晶扣减和贡献点增加
|
||
- 获取排名,验证排序正确
|
||
3. **前端**:
|
||
- 活动页面加载正常
|
||
- 购买道具交互正常
|
||
- 不同阶段背景切换正常
|
||
- 倒计时显示正常
|
||
4. **整体流程**: 完整流程测试 - 购买道具 -> 贡献点增加 -> 排名更新
|