本文引用的文件
本文件面向AI有声书生成平台,系统化梳理“用户”“会员”“订阅计划”三者的关系与业务逻辑,覆盖用户等级管理、会员到期时间、每日使用量统计等用户属性;解释订阅计划的定价策略、会员权益、自动续费机制等订阅功能的数据结构;并提供用户注册登录流程、会员升级降级、订阅状态管理等业务场景的API使用示例,以及用户行为分析与会员转化率统计的实现思路。
围绕用户与订阅模型,后端采用模块化分层:
类型与配置:统一定义用户类型、会员等级、Token计费配置、音频计费配置、套餐默认配置等。
graph TB
subgraph "控制器层"
MC["member.controller.ts"]
SC["subscription.controller.ts"]
AC["auth.controller.ts"]
end
subgraph "服务层"
MS["member.service.ts"]
SS["subscription.service.ts"]
end
subgraph "数据访问层"
PRISMA["PrismaClient(schema.prisma)"]
MODELS["models/index.ts"]
end
subgraph "类型与配置"
TYPES["types/index.ts"]
DOCS1["Token计费系统设计.md"]
DOCS2["database-structure.md"]
DOCS3["API.md"]
end
MC --> MS
SC --> SS
AC --> MS
MS --> PRISMA
SS --> PRISMA
PRISMA --> MODELS
MS --> TYPES
SS --> TYPES
SS --> DOCS1
MS --> DOCS2
SC --> DOCS3
图表来源
章节来源
章节来源
用户与订阅模型在服务层通过Prisma进行统一读写,控制器层负责路由与鉴权,类型定义确保前后端一致性。下图展示了用户、会员与订阅的关键交互:
sequenceDiagram
participant Client as "客户端"
participant AuthCtrl as "auth.controller.ts"
participant MemberCtrl as "member.controller.ts"
participant SubCtrl as "subscription.controller.ts"
participant MemberSvc as "member.service.ts"
participant SubSvc as "subscription.service.ts"
participant DB as "Prisma(schema.prisma)"
Client->>AuthCtrl : POST /api/auth/login
AuthCtrl->>MemberSvc : 登录后获取会员状态
MemberSvc->>DB : 查询User
DB-->>MemberSvc : User
MemberSvc-->>AuthCtrl : 会员状态
AuthCtrl-->>Client : 返回token与用户信息
Client->>SubCtrl : GET /api/subscription/plans
SubCtrl->>SubSvc : 获取套餐列表
SubSvc->>DB : 查询SubscriptionPlan
DB-->>SubSvc : 套餐列表
SubSvc-->>SubCtrl : 套餐数据
SubCtrl-->>Client : 套餐列表
Client->>MemberCtrl : POST /api/member/order
MemberCtrl->>MemberSvc : 创建订单
MemberSvc->>DB : 创建Order
DB-->>MemberSvc : Order
MemberSvc-->>MemberCtrl : 订单号与金额
MemberCtrl-->>Client : 订单信息
图表来源
会员状态计算
根据会员等级映射配额(每日/单次/字数限制)
flowchart TD
Start(["进入会员状态查询"]) --> LoadUser["加载User"]
LoadUser --> Today["获取今日日期"]
Today --> ResetCheck{"lastUsageDate != 今天?"}
ResetCheck --> |是| ResetDaily["dailyUsage = 0"]
ResetCheck --> |否| KeepDaily["保持dailyUsage不变"]
ResetDaily --> CalcQuota["根据memberLevel计算配额"]
KeepDaily --> CalcQuota
CalcQuota --> ExpireCheck{"memberExpireAt存在且未过期?"}
ExpireCheck --> |是| Valid["isValid = true"]
ExpireCheck --> |否| Invalid["isValid = false"]
Valid --> End(["返回状态"])
Invalid --> End
图表来源
章节来源
套餐查询
按激活状态与排序返回套餐列表,解析features字符串为数组
classDiagram
class SubscriptionPlan {
+int id
+string name
+int level
+decimal priceMonthly
+decimal priceYearly
+string description
+string features
+bool isRecommended
+bool isActive
+int sortOrder
+int dailyGenerations
+int perGenerationLimit
+int monthlyTokens
+int monthlyMinutes
+int? yearlyTokens
+int voiceOptions
+string audioQuality
+bool apiAccess
+bool batchProcessing
+bool teamManagement
+bool overageEnabled
+decimal overagePrice
}
class Subscription {
+int id
+int userId
+int planId
+datetime startDate
+datetime endDate
+string status
+bool autoRenew
}
Subscription --> SubscriptionPlan : "关联"
图表来源
章节来源
音频时长计费
提供预估生成费用与可用时长
flowchart TD
Start(["生成音频请求"]) --> Estimate["估算音频时长"]
Estimate --> QuotaCheck["检查月度配额"]
QuotaCheck --> Allowed{"配额充足?"}
Allowed --> |是| PriceCalc["计算包月内价格"]
Allowed --> |否| OverageCheck{"支持超额?"}
OverageCheck --> |是| OverageCalc["计算超额价格"]
OverageCheck --> |否| Deny["拒绝生成"]
PriceCalc --> Total["合计总费用"]
OverageCalc --> Total
Total --> Consume["扣除Token/更新用户时长"]
Consume --> End(["返回结果"])
Deny --> End
图表来源
章节来源
订单列表
支持分页查询用户历史订单
sequenceDiagram
participant Client as "客户端"
participant MemberCtrl as "member.controller.ts"
participant MemberSvc as "member.service.ts"
participant DB as "Prisma(schema.prisma)"
Client->>MemberCtrl : POST /api/member/order
MemberCtrl->>MemberSvc : createOrder(userId, productType)
MemberSvc->>DB : 创建Order
DB-->>MemberSvc : Order
MemberSvc-->>MemberCtrl : {orderNo, amount}
MemberCtrl-->>Client : 订单信息
Client->>MemberCtrl : POST /api/member/pay/mock
MemberCtrl->>MemberSvc : mockPaymentSuccess(orderNo, userId)
MemberSvc->>DB : 更新Order状态
MemberSvc->>DB : 更新User会员等级与到期时间
DB-->>MemberSvc : 成功
MemberSvc-->>MemberCtrl : {success, memberLevel, memberExpireAt}
MemberCtrl-->>Client : 支付成功
图表来源
章节来源
章节来源
章节来源
配置与文档:Token计费与数据库结构文档作为设计依据,指导服务层实现。
graph LR
MC["member.controller.ts"] --> MS["member.service.ts"]
SC["subscription.controller.ts"] --> SS["subscription.service.ts"]
AC["auth.controller.ts"] --> MS
MS --> PRISMA["Prisma(schema.prisma)"]
SS --> PRISMA
MS --> TYPES["types/index.ts"]
SS --> TYPES
SS --> DOCS1["Token计费系统设计.md"]
MS --> DOCS2["database-structure.md"]
SC --> DOCS3["API.md"]
图表来源
章节来源
[本节为通用性能建议,无需特定文件引用]
章节来源
本平台通过User、Order、SubscriptionPlan、Subscription、TokenBalance与TokenUsage等模型,构建了完善的用户与订阅管理体系。会员等级与到期时间、每日使用量统计、Token与音频时长双重计费策略,既保障用户体验,又实现可持续的商业化闭环。配套的API与文档为前端与运营提供了清晰的接入与分析路径。
[本节为总结性内容,无需特定文件引用]
erDiagram
USER {
int id PK
string phone
string openid
string nickname
string avatar
int memberLevel
datetime memberExpireAt
int dailyUsage
string lastUsageDate
int usedAudioMinutes
datetime subscriptionResetDate
datetime createdAt
datetime updatedAt
}
ORDER {
int id PK
int userId FK
string orderNo UK
int? planId FK
string productType
decimal amount
string status
string? paymentMethod
datetime? paidAt
datetime createdAt
datetime updatedAt
}
SUBSCRIPTION_PLAN {
int id PK
string name
int level
decimal priceMonthly
decimal priceYearly
string description
string features
bool isRecommended
bool isActive
int sortOrder
int dailyGenerations
int perGenerationLimit
int monthlyTokens
int monthlyMinutes
int? yearlyTokens
int voiceOptions
string audioQuality
bool apiAccess
bool batchProcessing
bool teamManagement
bool overageEnabled
decimal overagePrice
}
SUBSCRIPTION {
int id PK
int userId FK
int planId FK
datetime startDate
datetime endDate
string status
bool autoRenew
datetime createdAt
datetime updatedAt
}
TOKEN_BALANCE {
int id PK
int userId UK FK
int totalTokens
int usedTokens
datetime? resetDate
datetime createdAt
datetime updatedAt
}
TOKEN_USAGE {
int id PK
int userId FK
string type
int amount
int contentLength
int? orderId FK
string? description
datetime createdAt
}
USER ||--o{ ORDER : "has"
USER ||--o{ SUBSCRIPTION : "has"
USER ||--o{ TOKEN_BALANCE : "has"
USER ||--o{ TOKEN_USAGE : "has"
SUBSCRIPTION_PLAN ||--o{ SUBSCRIPTION : "defines"
ORDER ||--o{ TOKEN_USAGE : "records"
图表来源
章节来源