Files

180 lines
5.3 KiB
Markdown
Raw Permalink 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.
# 积分体系模块
## 概述
积分体系是追光AI的用户激励核心,包含20级成长系统、积分奖励引擎、积分商店、签到连击和Streak冻结保护,通过游戏化机制提升用户活跃度和留存率。
## 积分规则
| 行为 | 积分 | 每日上限 |
|------|------|----------|
| 发表评论 | +5 | 50 |
| 评论被点赞 | +2 | 20 |
| 发布论坛话题 | +10 | 无限制 |
| 论坛回复 | +5 | 30 |
| 发表评价 | +8 | 20 |
| 每日签到 | +1 (递增) | 1 |
| 签到连击 bonus | 连续7天+3, 连续30天+10 | - |
---
## 等级系统 - 20级成长体系
### 等级配置
- **配置文件**: `src/lib/level-config.ts` — 客户端安全(无Prisma依赖)
- 等级范围: LV01(0分) → LV20(50000分)
- 等级图标: ⭐(初级) → ⭐⭐⭐(中级) → 🌟(高级) → 🌟🌟(精英) → 🌟🌟🌟(大师)
### 等级表
| 等级 | 最低积分 | 徽章 | 每日限额 |
|------|----------|------|----------|
| LV01 | 0 | ⭐ | 50 |
| LV02 | 10 | ⭐ | 80 |
| LV03 | 30 | ⭐⭐ | 100 |
| LV04 | 60 | ⭐⭐ | 120 |
| LV05 | 100 | ⭐⭐ | 150 |
| LV06 | 200 | ⭐⭐⭐ | 180 |
| LV07 | 400 | ⭐⭐⭐ | 200 |
| LV08 | 700 | ⭐⭐⭐ | 250 |
| LV09 | 1000 | ⭐⭐⭐ | 300 |
| LV10 | 1500 | 🌟 | 400 |
| LV11 | 2000 | 🌟 | 500 |
| LV12 | 3000 | 🌟 | 600 |
| LV13 | 4500 | 🌟 | 700 |
| LV14 | 6000 | 🌟🌟 | 800 |
| LV15 | 8000 | 🌟🌟 | 1000 |
| LV16 | 11000 | 🌟🌟 | 1200 |
| LV17 | 15000 | 🌟🌟 | 1500 |
| LV18 | 20000 | 🌟🌟🌟 | 1800 |
| LV19 | 30000 | 🌟🌟🌟 | 2000 |
| LV20 | 50000 | 🌟🌟🌟 | 3000 |
### 旧等级迁移映射
BRONZE→LV01, SILVER→LV03, GOLD→LV06, PLATINUM→LV10
### 积分奖励引擎
- **文件**: `src/lib/points-reward.ts`
- `rewardPoints()` — 自动发放积分 + 日限额检查 + 事务写入
- `getUserStats()` — 获取用户综合统计(积分/评论数/话题数等)
- `getUserPointsHistory()` — 积分历史分页查询
---
## 签到系统
### 每日签到
- 基础+1分,连续签到递增奖励
- 连续7天: +3 bonus
- 连续30天: +10 bonus
- 中断重置
### CheckInCard 组件
- 位置: 用户中心顶部
- 功能: 签到按钮、连击天数显示、季度签到日历
---
## Streak 冻结保护
### 功能说明
- 用户可通过积分商店购买 Streak Freeze 卡片
- 当用户某天未签到时,自动消耗一张 Freeze 卡保护连击不断
- 最多持有 3 张 Freeze 卡
### 核心库
- **文件**: `src/lib/streak-freeze.ts`
- `checkAndApplyFreeze(userId)` — 检查是否需要冻结并自动应用
- `getFreezeCardCount(userId)` — 获取当前持有数量
- `useFreezeCard(userId)` — 消耗一张冻结卡
### 定时任务
- **脚本**: `scripts/grant-freeze-cards.mjs`
- 定期为活跃用户发放 Freeze 卡(每日01:00)
---
## 积分商店
### 功能概述
用户可使用积分兑换虚拟物品和社区权益。
### 商品定义
- **文件**: `src/lib/shop-items.ts`
- 商品类型: 头像框、昵称颜色、特效道具、Streak Freeze 卡
### API 接口
| 路由 | 方法 | 功能 |
|------|------|------|
| /api/user/shop/items | GET | 获取可购买商品列表 |
| /api/user/shop/purchase | POST | 购买商品(扣积分) |
| /api/user/shop/my-items | GET | 获取用户已购物品 |
### 前端组件
- 积分商店页面(用户中心入口)
- 商品卡片(名称/图标/价格/库存/购买按钮)
- 已购物品展示(个人中心装饰效果)
---
## 数据模型
### PointsHistory (积分历史)
| 字段 | 类型 | 说明 |
|------|------|------|
| id | Int @id | 主键 |
| userId | Int | 用户ID |
| points | Int | 积分变动(正数获得/负数消耗) |
| reason | String | 积分原因 |
| detail | String? | 详细信息 |
| refType | String? | 关联类型 |
| refId | Int? | 关联ID |
| createdAt | DateTime | 创建时间 |
### StreakFreeze (冻结卡) 🆕
| 字段 | 类型 | 说明 |
|------|------|------|
| id | Int @id | 主键 |
| userId | Int | 用户ID |
| cardCount | Int | 持有数量 |
| lastUsedAt | DateTime? | 最近使用时间 |
| createdAt | DateTime | 创建时间 |
### UserShopItem (已购物品) 🆕
| 字段 | 类型 | 说明 |
|------|------|------|
| id | Int @id | 主键 |
| userId | Int | 用户ID |
| itemId | String | 商品ID |
| purchasedAt | DateTime | 购买时间 |
| isActive | Boolean | 是否启用/佩戴 |
---
## 前端组件
| 组件 | 文件 | 说明 |
|------|------|------|
| MemberBadge | `src/components/common/MemberBadge.tsx` | 会员等级徽章(⭐🌟 + 积分显示,3种尺寸) |
| LevelProgress | `src/components/common/LevelProgress.tsx` | 等级进度条(当前/下一级/进度百分比,动态变色) |
| CheckInCard | `src/components/common/CheckInCard.tsx` | 签到卡片(签到按钮/连击天数/季度日历) |
---
## 技术实现要点
### 积分自动奖励机制
所有评论/发帖/点赞操作自动通过 `rewardPoints()` 发放积分:
- 每日上限检查(防刷分)
- 事务写入(积分变更 + 历史记录同时写入)
- 等级自动随积分变化更新
### 日志分类
积分变动通过 `reason` 字段区分:
- `comment` — 评论
- `comment_liked` — 评论被点赞
- `topic_create` — 发帖
- `reply` — 回复
- `review` — 评价
- `check_in` — 签到
- `shop_purchase` — 商店消费(负数)