积分与推荐系统
ProductReady 的用户积分和推荐计划
积分与推荐系统
ProductReady 内置了积分系统和推荐计划,用于激励用户增长和参与度。
积分系统
积分是用户可以在平台内赚取和使用的虚拟货币。积分以分为单位存储(例如,1000 = $10.00)。
积分来源
用户可以通过各种活动赚取积分:
| 来源 | 描述 |
|---|---|
referral | 邀请朋友注册 |
onboarding | 完成引导步骤 |
early_adopter | 早期用户奖励 |
promotion | 各种促销活动 |
manual | 管理员手动发放 |
redemption | 兑换促销码 |
数据库架构
// 用户积分余额
export const userCredits = pgTable("user_credits", {
userId: text("user_id").primaryKey(),
balance: integer("balance").default(0).notNull(),
totalEarned: integer("total_earned").default(0).notNull(),
totalUsed: integer("total_used").default(0).notNull(),
createdAt: timestamp("created_at").defaultNow().notNull(),
updatedAt: timestamp("updated_at"),
});
// 交易历史
export const userCreditTransactions = pgTable("user_credit_transactions", {
id: text("id").primaryKey(),
userId: text("user_id").notNull(),
amount: integer("amount").notNull(),
balanceAfter: integer("balance_after").notNull(),
source: text("source").notNull(),
referenceId: text("reference_id"),
description: text("description"),
grantedBy: text("granted_by"),
spaceId: text("space_id"),
createdAt: timestamp("created_at").defaultNow().notNull(),
});API 端点
获取我的积分
// 获取当前用户的积分余额
const credits = await trpc.credits.getMyCredits.query();
// 返回: { userId, balance, totalEarned, totalUsed, balanceFormatted }获取我的交易记录
// 获取交易历史
const { transactions, total } = await trpc.credits.getMyTransactions.query({
limit: 20,
offset: 0,
source: "referral", // 可选过滤
});管理员端点
系统管理员可以管理用户积分:
// 为用户添加积分
await trpc.credits.addCredits.mutate({
userId: "user_123",
amount: 500, // $5.00
source: "manual",
description: "客服补偿积分",
});
// 列出所有交易
const { transactions, total } = await trpc.credits.listTransactions.query({
userId: "user_123", // 可选
limit: 50,
});
// 列出有积分的用户
const { users, total } = await trpc.credits.listUsersWithCredits.query({
limit: 20,
});推荐计划
推荐计划允许用户邀请朋友,并在朋友注册时赚取积分。
工作原理
- 用户生成唯一的推荐码
- 用户分享推荐链接:
https://yourapp.com/sign-up?ref=CODE - 新用户使用该链接注册
- 双方都获得积分:
- 推荐人:$5.00 积分
- 新用户:$2.00 积分
数据库架构
推荐字段添加到 user_profiles:
export const userProfiles = pgTable("user_profiles", {
// ... 其他字段
referralCode: text("referral_code").unique(),
referredBy: text("referred_by"),
referralRewarded: timestamp("referral_rewarded"),
});API 端点
获取推荐信息
const info = await trpc.referral.getMyReferralInfo.query();
// 返回: { referralCode, referralCount, totalEarned }生成推荐码
const { referralCode } = await trpc.referral.generateReferralCode.mutate();验证推荐码(公开)
const { valid, referrerName } = await trpc.referral.validateReferralCode.query({
code: "ABC123",
});UI 组件
积分和推荐 UI 集成在账户设置弹窗中:
import { AccountSettingsModal } from "~/components/dashboard/account-settings-modal";
// 弹窗包含以下标签页:
// - 个人资料
// - 积分(余额 + 交易记录)
// - 推荐(链接 + 统计)
// - API 密钥注册流程
注册页面自动处理推荐码:
- 从 URL 读取
?ref=CODE - 验证码并显示推荐人名称
- 将码存储在 sessionStorage 中用于 OAuth 流程
- 注册后在仪表板中处理推荐
// 在注册页面
const refCode = searchParams.get("ref");
const { data: refValidation } = trpc.referral.validateReferralCode.useQuery(
{ code: refCode || "" },
{ enabled: !!refCode }
);自定义
您可以在 src/server/routers/referral.ts 中自定义奖励金额:
const REFERRER_REWARD = 500; // 推荐人 $5.00
const REFERRED_REWARD = 200; // 新用户 $2.00最佳实践
-
防欺诈:考虑添加:
- 发放推荐奖励前进行邮箱验证
- IP/设备追踪防止自我推荐
- 推荐码生成的速率限制
-
积分过期:如需要可实现过期机制:
- 为积分添加
expiresAt字段 - 运行定期清理任务
- 为积分添加
-
审计追踪:所有积分变动都记录在
userCreditTransactions中,用于合规和调试。