Loyalty Program · Gift Cards · Membership Tiers · Points | 更新时间: 2026-02-08
admin/loyalty/config/page.tsx (忠诚度配置),
admin/loyalty/tiers/page.tsx (等级配置),
admin/loyalty/points/page.tsx (积分管理),
admin/loyalty/gift-cards/page.tsx (礼品卡管理),
admin/gift-cards/page.tsx (礼品卡列表),
admin/gift-cards/[id]/page.tsx (礼品卡详情),
gift-cards/page.tsx (我的礼品卡),
gift-cards/purchase/page.tsx (购买礼品卡),
gift-cards/claim/[token]/page.tsx (兑换礼品卡),
account/gift-cards/page.tsx (账户礼品卡),
account/gift-cards/purchase/page.tsx (账户内购买)
GiftCardBalance.tsx,
GiftCardPurchaseForm.tsx,
GiftCardRedeemInput.tsx,
GiftCardDetailModal.tsx,
GiftCardInput.tsx (支付集成),
GiftCardPaymentOption.tsx,
LoyaltyPaymentOption.tsx,
PointsAdjustModal.tsx,
PointsBalance.tsx,
TierBadge.tsx,
TierProgress.tsx
useLoyaltyApi.ts (tiers + points + gift cards mutations),
useGiftCard.ts (claim + verify),
useLoyalty.ts (points utilities)
api/gift-cards.js (purchase),
api/admin/gift-cards.js (admin listing),
api/loyalty.js (points + membership + gift card ops),
api/reports/loyalty.js (5 report endpoints),
services/loyalty/loyaltyService.js (Facade),
services/loyalty/giftCardService.js,
services/giftCard/giftCardService.js (claim tokens)
erDiagram
guests ||--o| customer_memberships : "has membership"
customer_memberships }o--|| membership_tiers : "at tier"
guests ||--o| points_accounts : "has points"
points_accounts ||--o{ points_transactions : "earns/redeems"
guests ||--o{ gift_cards : "owns"
gift_cards ||--o{ gift_card_transactions : "transactions"
gift_cards ||--o{ gift_card_claims : "claim attempts"
membership_tiers {
uuid id PK
string name "Bronze/Silver/Gold/Platinum"
string code "tier code"
string color "Hex color"
decimal upgrade_threshold "Spend threshold"
decimal discount_percent "Member discount"
decimal points_multiplier "Points earn multiplier"
boolean priority_booking "Priority flag"
int birthday_bonus_points "Birthday bonus"
boolean is_default "Default tier for new members"
}
gift_cards {
uuid id PK
string card_number "6017 prefix + Luhn"
enum card_type "electronic | physical"
decimal initial_amount "$10-500"
decimal balance "Current balance"
enum status "pending | active | used | expired | disabled"
string claim_token "JWT 30-day"
enum delivery_method "email | sms | both"
}
points_accounts {
string customer_id FK
int total_points "Lifetime"
int available_points "Spendable"
int frozen_points "Pending"
int lifetime_earned "Total earned"
int lifetime_redeemed "Total redeemed"
}
membership_tiers + customer_memberships 表,基于消费金额自动升降级,带折扣/积分倍率/专属权益。这是 017-loyalty-program 实现的完整系统。
guests.vip_status 字段 (none/bronze/silver/gold/platinum) + vip_points。来自 012-profile-management,是早期遗留系统。
| 属性 | 值 |
|---|---|
| 前缀 | 6017 (QQ Nails 标识) |
| 总长度 | 16 位 (4 前缀 + 11 随机 + 1 校验) |
| 校验算法 | Luhn (信用卡式校验) |
| 生成方式 | PostgreSQL 函数,数据库级唯一性约束 |
| 操作 | 所需权限 |
|---|---|
| 查看礼品卡列表 | giftcards:view |
| 管理礼品卡 | giftcards:manage |
| 管理忠诚度设置 | loyalty:manage |
| 查看忠诚度报告 | reports:view_loyalty |
| CUJ | 优先级 | 描述 | 触发点 | 业务价值 | E2E 状态 |
|---|---|---|---|---|---|
| M1 | P1 | 忠诚度系统配置 | Admin → Loyalty → Config | 积分规则、礼品卡规则、折扣策略统一配置 | 缺失 |
| M2 | P1 | 会员等级管理 | Admin → Loyalty → Tiers | 分层会员体系,差异化权益 | 缺失 |
| M3 | P1 | 积分管理与手动调整 | Admin → Loyalty → Points | 积分运营灵活性 | 缺失 |
| M4 | P0 | 礼品卡购买(客户端) | /gift-cards/purchase | 收入增长 — 预付费模式 | 部分覆盖 |
| M5 | P0 | 礼品卡兑换与使用 | /gift-cards/claim/[token] | 客户体验 — 收礼→激活→支付 | 部分覆盖 |
| M6 | P1 | 礼品卡后台管理 | Admin → Gift Cards | 运营管理 — 查询/充值/取消 | 缺失 |
| M7 | P2 | 忠诚度报告分析 | Reports → Loyalty | 留存/流失/积分负债分析 | 缺失 |
P1 全局配置 — 积分规则、礼品卡规则、折扣策略
admin/loyalty/config/page.tsx,
loyalty:manage 权限
| 分组 | 配置项 | 默认值 |
|---|---|---|
| 积分系统 | points_enabled | true |
| points_earn_rate (每$1赚几分) | 1 | |
| points_redeem_rate (兑换$1需几分) | 100 | |
| points_min_redeem (最低兑换) | 100 | |
| points_expire_days (0=永不过期) | 365 | |
| 礼品卡 | gift_cards_enabled | true |
| gift_card_min_amount | $10 | |
| gift_card_max_amount | $500 | |
| gift_card_expire_months (0=永不) | 0 | |
| 会员 | tier_period_months (评估周期) | 12 |
| downgrade_protection_days (降级保护) | 30 | |
| discount_stacking | "best" (best/stack/member_first) | |
| 跨店 | cross_store_points | true |
| cross_store_gift_cards | true |
/admin/loyalty/configP1 分层会员体系 — 等级创建、阈值、权益配置
admin/loyalty/tiers/page.tsx,
TierBadge.tsx,
TierProgress.tsx,
membership_tiers 表,
customer_memberships 表
flowchart LR
A["新客户"] --> B["默认等级 (is_default)"]
B --> C{"评估周期内消费 >= threshold?"}
C -->|"是"| D["自动升级"]
D --> E["享受折扣 + 积分倍率 + 专属权益"]
C -->|"否"| F{"降级保护期内?"}
F -->|"是"| G["保持当前等级"]
F -->|"否"| H["自动降级到匹配等级"]
/admin/loyalty/tiersis_active=false(软删除)
P1 积分运营 — 查看余额、手动增减、过期管理
admin/loyalty/points/page.tsx,
PointsAdjustModal.tsx,
PointsBalance.tsx,
GET /api/loyalty/points/account/:customer_id
P0 收入增长 — 客户在线购买电子礼品卡
gift-cards/purchase/page.tsx,
account/gift-cards/purchase/page.tsx,
GiftCardPurchaseForm.tsx,
POST /api/gift-cards/purchase,
services/loyalty/giftCardService.js
flowchart TD
A["选择金额"] --> B["选择配送方式"]
B --> C["填写收件人信息"]
C --> D["个性化 (From/To/Message)"]
D --> E["确认购买"]
E --> F["生成卡号 6017-xxxx-xxxx-x"]
F --> G{"配送方式"}
G -->|"Email"| H["发送邮件 + 兑换链接"]
G -->|"SMS"| I["发送短信 + 兑换链接"]
G -->|"Both"| J["邮件 + 短信"]
H --> K["成功页面 (遮蔽卡号)"]
I --> K
J --> K
style E fill:#4caf50,stroke:#388e3c,color:#fff
/gift-cards/purchase/^\d*\.?\d*$/
P0 客户体验 — 收到礼品卡 → 激活 → 在结账时使用
gift-cards/claim/[token]/page.tsx,
gift-cards/page.tsx,
account/gift-cards/page.tsx,
GiftCardPaymentOption.tsx,
GiftCardInput.tsx,
services/giftCard/giftCardService.js
flowchart TD
A["收到兑换链接"] --> B["打开 /gift-cards/claim/token"]
B --> V{"验证 JWT Token"}
V -->|"无效"| E1["错误: 链接无效"]
V -->|"过期"| E2["错误: 链接已过期"]
V -->|"已兑换"| E3["提示: 已兑换"]
V -->|"有效"| C["显示卡面: 金额、发送者、消息"]
C --> D{"需要登录?"}
D -->|"已登录"| F["点击 Claim"]
D -->|"未登录"| G["提示登录/注册"]
G --> F
F --> H["卡绑定到账户, status → active"]
H --> I["成功: 卡已添加"]
style E1 fill:#c62828,stroke:#b71c1c,color:#fff
style E2 fill:#c62828,stroke:#b71c1c,color:#fff
style H fill:#4caf50,stroke:#388e3c,color:#fff
/gift-cards/claim/{token}/gift-cards 或 /account/gift-cardsP1 运营管理 — 搜索、查看详情、充值、取消
admin/gift-cards/page.tsx,
admin/gift-cards/[id]/page.tsx,
admin/loyalty/gift-cards/page.tsx,
GiftCardDetailModal.tsx,
GET /api/gift-cards (admin)
giftcards:view 权限,且具备对应范围(scope)/admin/gift-cards 搜索卡号/邮箱/手机号P2 数据驱动 — 留存/流失/积分负债/礼品卡分析
reports/loyalty/page.tsx,
GET /api/reports/loyalty/* (5 endpoints)
| Tab | API | 内容 |
|---|---|---|
| Retention | /retention | 留存率、留存趋势图、到访频率分布 |
| Churn | /churn | 流失风险汇总、预警列表(可直接联系) |
| Membership | /membership | 等级分布饼图、趋势、Top 会员 |
| Points | /points | 积分趋势、余额分布、负债卡(outstanding risk)、Top 赚取 |
| Gift Cards | /giftcards | 销售/兑换趋势、分布、即将过期提醒、负债卡 |
reports:view_loyalty 权限,且具备对应范围(scope)/reports/loyalty| 关联模块 | 关联点 | 说明 |
|---|---|---|
| CUJ-F (Payments) | 礼品卡支付 + 积分抵扣 | 结账页面的 GiftCardPaymentOption 和 LoyaltyPaymentOption 组件 |
| CUJ-E (Guests) | VIP 状态 + 会员等级 | 客户详情页的 VipBadge/VipProgress 与 TierBadge/TierProgress 两套系统 |
| CUJ-H (Reports) | 忠诚度报告 | reports/loyalty 5 个 Tab 整合在报告模块中 |
| CUJ-K (Account) | 客户端礼品卡管理 | account/gift-cards 页面供客户查看和购买礼品卡 |
| # | 规则 | 实现位置 |
|---|---|---|
| 1 | 礼品卡金额范围: $10 – $500,批量 1-100 张,消息 ≤500 字符 | POST /api/gift-cards/purchase 验证 |
| 2 | Claim Token: JWT 30 天有效,密钥 GIFT_CARD_SECRET (fallback JWT_SECRET) |
giftCardService.generateClaimToken() |
| 3 | 等级自动评估: 评估周期内消费 ≥ threshold → 升级;保护期外消费不足 → 降级 | loyaltyService.membership.evaluateTier() |
| 4 | 折扣叠加: 3 种策略 — best (取最优)、stack (叠加)、member_first (会员优先) | admin/loyalty/config |
| 5 | 积分 ACID: 使用 tenantDb.transactionWithTenant 保证积分操作原子性 |
giftCardService.purchaseGiftCard() |
| 6 | 跨店使用: 积分和礼品卡可配置是否允许跨门店使用,默认允许 | loyalty config |
| 7 | 两套等级系统共存: guests.vip_status (遗留) 与 membership_tiers (正式) 独立运行,未同步 | guests 表 vs customer_memberships 表 |