topfans/docs/PRD-activity.md
2026-04-07 22:28:50 +08:00

6.8 KiB
Raw Permalink Blame History

运营活动功能实现计划

背景

用户希望添加一个运营活动功能:

  • 用户可以进入运营活动界面
  • 通过水晶购买道具推进活动进程
  • 购买道具可获得贡献点
  • 后台统计贡献点排名
  • 运营活动有时间限制
  • 不同阶段展示不同界面效果

现有代码基础

  • 前端已有应援活动页面 (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

-- 运营活动表
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

// 活动相关消息定义
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. 整体流程: 完整流程测试 - 购买道具 -> 贡献点增加 -> 排名更新