ProductReadyProductReady

积分与推荐系统

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,
});

推荐计划

推荐计划允许用户邀请朋友,并在朋友注册时赚取积分。

工作原理

  1. 用户生成唯一的推荐码
  2. 用户分享推荐链接:https://yourapp.com/sign-up?ref=CODE
  3. 新用户使用该链接注册
  4. 双方都获得积分:
    • 推荐人:$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 密钥

注册流程

注册页面自动处理推荐码:

  1. 从 URL 读取 ?ref=CODE
  2. 验证码并显示推荐人名称
  3. 将码存储在 sessionStorage 中用于 OAuth 流程
  4. 注册后在仪表板中处理推荐
// 在注册页面
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

最佳实践

  1. 防欺诈:考虑添加:

    • 发放推荐奖励前进行邮箱验证
    • IP/设备追踪防止自我推荐
    • 推荐码生成的速率限制
  2. 积分过期:如需要可实现过期机制:

    • 为积分添加 expiresAt 字段
    • 运行定期清理任务
  3. 审计追踪:所有积分变动都记录在 userCreditTransactions 中,用于合规和调试。

On this page