|
|
@@ -0,0 +1,466 @@
|
|
|
+# AI语音应用 - 订阅支付系统
|
|
|
+
|
|
|
+## 📌 快速开始
|
|
|
+
|
|
|
+### 1. 启动后端服务
|
|
|
+
|
|
|
+```bash
|
|
|
+cd server
|
|
|
+npm install
|
|
|
+npx prisma db push # 初始化数据库
|
|
|
+npx tsc # 编译TypeScript
|
|
|
+node dist/app.js # 启动服务
|
|
|
+```
|
|
|
+
|
|
|
+### 2. 启动前端服务
|
|
|
+
|
|
|
+```bash
|
|
|
+cd my-uniapp-vue3
|
|
|
+npm install
|
|
|
+npm run dev:h5 # H5开发模式
|
|
|
+```
|
|
|
+
|
|
|
+### 3. 访问订阅页面
|
|
|
+
|
|
|
+1. 打开浏览器访问 `http://localhost:8080`
|
|
|
+2. 登录账号
|
|
|
+3. 点击底部导航「我的」
|
|
|
+4. 点击「会员中心」或「订阅套餐」
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 💳 功能列表
|
|
|
+
|
|
|
+### ✅ 已完成功能
|
|
|
+
|
|
|
+#### 1. 套餐系统
|
|
|
+- 4个套餐等级:免费版、基础版、专业版、旗舰版
|
|
|
+- 月付和年付价格
|
|
|
+- Token配额限制
|
|
|
+- 功能权限控制
|
|
|
+
|
|
|
+#### 2. 订阅管理
|
|
|
+- 创建订阅订单
|
|
|
+- 订阅状态管理
|
|
|
+- 订阅有效期计算
|
|
|
+- 自动续费开关
|
|
|
+
|
|
|
+#### 3. 支付系统
|
|
|
+- 支付宝支付(集成接口)
|
|
|
+- 微信支付(集成接口)
|
|
|
+- 模拟支付(开发环境)
|
|
|
+- 支付回调处理
|
|
|
+
|
|
|
+#### 4. Token配额系统
|
|
|
+- Token余额管理
|
|
|
+- Token使用记录
|
|
|
+- 配额检查和扣费
|
|
|
+- 月度/年度重置
|
|
|
+
|
|
|
+#### 5. 前端页面
|
|
|
+- 订阅套餐页面(pages/member/index.vue)
|
|
|
+- 订单历史页面(pages/orders/index.vue)
|
|
|
+- Token余额显示
|
|
|
+- 支付方式选择
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 🏷️ 套餐详情
|
|
|
+
|
|
|
+### 免费版(¥0/月)
|
|
|
+```
|
|
|
+✅ 每天3次生成
|
|
|
+✅ 每次最多2000字
|
|
|
+✅ 基础音色5种
|
|
|
+✅ 标准音质
|
|
|
+❌ 每月10000 Token
|
|
|
+❌ 无高清音质
|
|
|
+❌ 无优先队列
|
|
|
+```
|
|
|
+
|
|
|
+### 基础版(¥9.9/月)
|
|
|
+```
|
|
|
+✅ 无限制生成次数
|
|
|
+✅ 每次最多10000字
|
|
|
+✅ 全部音色
|
|
|
+✅ 高清音质
|
|
|
+✅ 优先队列
|
|
|
+✅ 每月50000 Token
|
|
|
+❌ 无API访问
|
|
|
+❌ 无批量处理
|
|
|
+```
|
|
|
+
|
|
|
+### 专业版(¥29.9/月)⭐ 推荐
|
|
|
+```
|
|
|
+✅ 无限制生成次数
|
|
|
+✅ 每次最多50000字
|
|
|
+✅ 全部音色+定制音色
|
|
|
+✅ 无损音质
|
|
|
+✅ VIP优先队列
|
|
|
+✅ API访问
|
|
|
+✅ 每月200000 Token
|
|
|
+❌ 无批量处理
|
|
|
+❌ 无团队管理
|
|
|
+```
|
|
|
+
|
|
|
+### 旗舰版(¥99/月)
|
|
|
+```
|
|
|
+✅ 无限制生成次数
|
|
|
+✅ 每次最多200000字
|
|
|
+✅ 全部功能
|
|
|
+✅ 无损音质
|
|
|
+✅ 专属技术支持
|
|
|
+✅ 批量处理
|
|
|
+✅ 团队管理
|
|
|
+✅ 每年1000000 Token
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 🔌 API 接口
|
|
|
+
|
|
|
+### 订阅相关
|
|
|
+
|
|
|
+#### 获取套餐列表
|
|
|
+```bash
|
|
|
+GET /api/subscription/plans
|
|
|
+```
|
|
|
+
|
|
|
+响应:
|
|
|
+```json
|
|
|
+{
|
|
|
+ "code": 0,
|
|
|
+ "data": {
|
|
|
+ "plans": [
|
|
|
+ {
|
|
|
+ "id": 1,
|
|
|
+ "name": "免费版",
|
|
|
+ "level": 0,
|
|
|
+ "priceMonthly": 0,
|
|
|
+ "priceYearly": 0,
|
|
|
+ "features": ["每天3次生成", "每次最多2000字"],
|
|
|
+ "monthlyTokens": 10000
|
|
|
+ },
|
|
|
+ // ...
|
|
|
+ ]
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+#### 获取Token余额
|
|
|
+```bash
|
|
|
+GET /api/subscription/balance
|
|
|
+Authorization: Bearer <token>
|
|
|
+```
|
|
|
+
|
|
|
+响应:
|
|
|
+```json
|
|
|
+{
|
|
|
+ "code": 0,
|
|
|
+ "data": {
|
|
|
+ "totalTokens": 50000,
|
|
|
+ "usedTokens": 1200,
|
|
|
+ "remainingTokens": 48800,
|
|
|
+ "isUnlimited": false,
|
|
|
+ "resetDate": "2026-05-01T00:00:00.000Z"
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+#### 获取Token使用记录
|
|
|
+```bash
|
|
|
+GET /api/subscription/usage?page=1&pageSize=20
|
|
|
+Authorization: Bearer <token>
|
|
|
+```
|
|
|
+
|
|
|
+响应:
|
|
|
+```json
|
|
|
+{
|
|
|
+ "code": 0,
|
|
|
+ "data": {
|
|
|
+ "list": [
|
|
|
+ {
|
|
|
+ "id": 1,
|
|
|
+ "type": "text_to_speech",
|
|
|
+ "amount": 1500,
|
|
|
+ "contentLength": 1500,
|
|
|
+ "createdAt": "2026-04-12T10:00:00.000Z"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "total": 50,
|
|
|
+ "page": 1,
|
|
|
+ "pageSize": 20,
|
|
|
+ "totalPages": 3
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+#### 检查配额
|
|
|
+```bash
|
|
|
+POST /api/subscription/check-quota
|
|
|
+Authorization: Bearer <token>
|
|
|
+Content-Type: application/json
|
|
|
+
|
|
|
+{
|
|
|
+ "tokens": 5000
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+响应:
|
|
|
+```json
|
|
|
+{
|
|
|
+ "code": 0,
|
|
|
+ "data": {
|
|
|
+ "allowed": true,
|
|
|
+ "reason": null
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 支付相关
|
|
|
+
|
|
|
+#### 创建支付订单
|
|
|
+```bash
|
|
|
+POST /api/payment/create
|
|
|
+Authorization: Bearer <token>
|
|
|
+Content-Type: application/json
|
|
|
+
|
|
|
+{
|
|
|
+ "planId": 2,
|
|
|
+ "paymentMethod": "alipay"
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+响应:
|
|
|
+```json
|
|
|
+{
|
|
|
+ "code": 0,
|
|
|
+ "message": "订单创建成功",
|
|
|
+ "data": {
|
|
|
+ "orderNo": "PAY20260412123456",
|
|
|
+ "amount": 9.9,
|
|
|
+ "planName": "基础版",
|
|
|
+ "paymentUrl": "https://..."
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+#### 模拟支付(开发环境)
|
|
|
+```bash
|
|
|
+POST /api/payment/mock
|
|
|
+Authorization: Bearer <token>
|
|
|
+Content-Type: application/json
|
|
|
+
|
|
|
+{
|
|
|
+ "orderNo": "PAY20260412123456"
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+#### 获取订单列表
|
|
|
+```bash
|
|
|
+GET /api/payment/orders?page=1&pageSize=10
|
|
|
+Authorization: Bearer <token>
|
|
|
+```
|
|
|
+
|
|
|
+响应:
|
|
|
+```json
|
|
|
+{
|
|
|
+ "code": 0,
|
|
|
+ "data": {
|
|
|
+ "list": [
|
|
|
+ {
|
|
|
+ "id": 1,
|
|
|
+ "orderNo": "PAY20260412123456",
|
|
|
+ "planName": "基础版",
|
|
|
+ "amount": 9.9,
|
|
|
+ "status": "paid",
|
|
|
+ "paymentMethod": "alipay",
|
|
|
+ "createdAt": "2026-04-12T10:00:00.000Z",
|
|
|
+ "paidAt": "2026-04-12T10:05:00.000Z"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "total": 5,
|
|
|
+ "page": 1,
|
|
|
+ "pageSize": 10,
|
|
|
+ "totalPages": 1
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 🗄️ 数据库表
|
|
|
+
|
|
|
+### SubscriptionPlan(套餐表)
|
|
|
+```sql
|
|
|
+SELECT * FROM SubscriptionPlan;
|
|
|
+```
|
|
|
+
|
|
|
+### Subscription(订阅表)
|
|
|
+```sql
|
|
|
+SELECT * FROM Subscription WHERE userId = <user_id>;
|
|
|
+```
|
|
|
+
|
|
|
+### TokenUsage(Token使用记录)
|
|
|
+```sql
|
|
|
+SELECT * FROM TokenUsage WHERE userId = <user_id> ORDER BY createdAt DESC LIMIT 20;
|
|
|
+```
|
|
|
+
|
|
|
+### TokenBalance(Token余额)
|
|
|
+```sql
|
|
|
+SELECT * FROM TokenBalance WHERE userId = <user_id>;
|
|
|
+```
|
|
|
+
|
|
|
+### Order(订单表)
|
|
|
+```sql
|
|
|
+SELECT * FROM Order WHERE userId = <user_id> ORDER BY createdAt DESC LIMIT 20;
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 🧪 测试支付
|
|
|
+
|
|
|
+### 1. 创建订单
|
|
|
+```bash
|
|
|
+curl -X POST http://localhost:3000/api/payment/create \
|
|
|
+ -H "Authorization: Bearer <your_token>" \
|
|
|
+ -H "Content-Type: application/json" \
|
|
|
+ -d '{"planId": 2, "paymentMethod": "mock"}'
|
|
|
+```
|
|
|
+
|
|
|
+### 2. 模拟支付
|
|
|
+```bash
|
|
|
+curl -X POST http://localhost:3000/api/payment/mock \
|
|
|
+ -H "Authorization: Bearer <your_token>" \
|
|
|
+ -H "Content-Type: application/json" \
|
|
|
+ -d '{"orderNo": "PAY20260412XXXXXX"}'
|
|
|
+```
|
|
|
+
|
|
|
+### 3. 查看Token余额
|
|
|
+```bash
|
|
|
+curl http://localhost:3000/api/subscription/balance \
|
|
|
+ -H "Authorization: Bearer <your_token>"
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 📱 前端页面路径
|
|
|
+
|
|
|
+### 订阅套餐页面
|
|
|
+```
|
|
|
+pages/member/index.vue
|
|
|
+```
|
|
|
+访问方式:用户中心 → 会员中心
|
|
|
+
|
|
|
+### 订单历史页面
|
|
|
+```
|
|
|
+pages/orders/index.vue
|
|
|
+```
|
|
|
+访问方式:用户中心 → 订单历史
|
|
|
+
|
|
|
+### Token使用记录
|
|
|
+在订单历史页面底部显示
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## ⚙️ 配置说明
|
|
|
+
|
|
|
+### 环境变量
|
|
|
+
|
|
|
+在 `server/.env` 中配置:
|
|
|
+
|
|
|
+```env
|
|
|
+# 支付宝配置(可选)
|
|
|
+ALIPAY_APP_ID=your_app_id
|
|
|
+ALIPAY_PRIVATE_KEY=your_private_key
|
|
|
+ALIPAY_PUBLIC_KEY=alipay_public_key
|
|
|
+
|
|
|
+# 微信支付配置(可选)
|
|
|
+WECHAT_APP_ID=your_app_id
|
|
|
+WECHAT_MCH_ID=your_mch_id
|
|
|
+WECHAT_API_KEY=your_api_key
|
|
|
+
|
|
|
+# 数据库配置
|
|
|
+DATABASE_URL=mysql://user:password@localhost:3306/audio_book
|
|
|
+```
|
|
|
+
|
|
|
+### 套餐配置
|
|
|
+
|
|
|
+编辑 `server/src/modules/subscription/subscription.service.ts` 中的 `DEFAULT_PLANS` 数组。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 🔒 Token消耗逻辑
|
|
|
+
|
|
|
+### 扣费时机
|
|
|
+1. 用户提交生成请求
|
|
|
+2. 后端检查Token余额
|
|
|
+3. 余额充足 → 扣除Token → 开始生成
|
|
|
+4. 余额不足 → 返回错误
|
|
|
+
|
|
|
+### 扣费示例
|
|
|
+```
|
|
|
+用户请求生成:1500字
|
|
|
+扣费:1500 Token
|
|
|
+剩余Token:48800 - 1500 = 47300
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 🎯 使用流程
|
|
|
+
|
|
|
+### 用户订阅流程
|
|
|
+1. 用户进入订阅页面
|
|
|
+2. 查看套餐列表和价格
|
|
|
+3. 选择套餐
|
|
|
+4. 选择支付方式(支付宝/微信)
|
|
|
+5. 点击「立即订阅」
|
|
|
+6. 完成支付
|
|
|
+7. 订阅成功,自动激活
|
|
|
+8. Token配额到账
|
|
|
+
|
|
|
+### Token使用流程
|
|
|
+1. 用户进入生成页面
|
|
|
+2. 输入文本内容
|
|
|
+3. 系统计算Token消耗
|
|
|
+4. 检查Token余额
|
|
|
+5. 余额充足 → 扣除Token → 生成音频
|
|
|
+6. 余额不足 → 提示充值
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## ❓ 常见问题
|
|
|
+
|
|
|
+### Q: 如何配置真实支付?
|
|
|
+A: 请参考 `docs/支付集成指南.md`
|
|
|
+
|
|
|
+### Q: Token可以退款吗?
|
|
|
+A: 可以联系客服处理
|
|
|
+
|
|
|
+### Q: 订阅可以升级吗?
|
|
|
+A: 可以,补差价升级
|
|
|
+
|
|
|
+### Q: 自动续费如何关闭?
|
|
|
+A: 在订阅管理页面关闭
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 📞 技术支持
|
|
|
+
|
|
|
+如有问题,请查看:
|
|
|
+- 详细支付集成文档:`docs/支付集成指南.md`
|
|
|
+- 数据库表结构:`server/prisma/schema.prisma`
|
|
|
+- 后端日志输出
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 🚀 未来计划
|
|
|
+
|
|
|
+- [ ] 真实支付宝支付集成
|
|
|
+- [ ] 真实微信支付集成
|
|
|
+- [ ] 批量Token购买
|
|
|
+- [ ] 团队管理功能
|
|
|
+- [ ] API访问控制
|
|
|
+- [ ] 自动续费功能
|
|
|
+- [ ] 退款管理功能
|
|
|
+- [ ] 数据分析报表
|