Files
soul-yongping/开发文档/8、部署/新分销逻辑-代码修改总结.md

382 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 新分销逻辑 - 代码修改总结
## ✅ 已完成的代码修改
### 1. 数据库层Database Layer
#### 迁移脚本
-`scripts/migration-add-binding-fields.sql`SQL版本
-`scripts/migrate_binding_fields.py`Python完整版
-`scripts/migrate_db_simple.py`Python简化版- **已执行成功**
#### 新增字段
```sql
referral_bindings 表:
last_purchase_date DATETIME - 最后购买时间
purchase_count INT - 购买次数
total_commission DECIMAL(10,2) - 累计佣金
status 新增枚举值 'cancelled' - 被切换状态
```
#### 新增索引
```sql
idx_referee_status (referee_id, status)
idx_expiry_purchase (expiry_date, purchase_count, status)
```
---
### 2. 核心业务逻辑Business Logic
#### 2.1 绑定API`app/api/referral/bind/route.ts`
**修改前**
```typescript
// ❌ 有效期内不能切换
if (expiryDate < now) {
// 已过期才能抢夺
} else {
return { error: '绑定有效期内无法更换' }
}
```
**修改后**
```typescript
// ✅ 立即切换(无条件)
if (existing.referrer_id === referrer.id) {
action = 'renew' // 同一推荐人:续期
} else {
action = 'switch' // 不同推荐人:立即切换
// 旧绑定标记为 cancelled
await query("UPDATE referral_bindings SET status = 'cancelled' WHERE id = ?", [existing.id])
}
```
**核心变化**
- ✅ 删除"有效期内不能切换"限制
- ✅ 点击新链接立即切换推荐人
- ✅ 旧绑定标记为 `cancelled`(不是 `expired`
- ✅ 新绑定重新计算30天
---
#### 2.2 支付回调:`app/api/miniprogram/pay/notify/route.ts`
**修改前**
```typescript
// ❌ 购买后标记为 converted不再累加
await query(`
UPDATE referral_bindings
SET status = 'converted',
commission_amount = ?
WHERE id = ?
`, [commission, binding.id])
```
**修改后**
```typescript
// ✅ 保持 active累加购买次数和佣金
await query(`
UPDATE referral_bindings
SET last_purchase_date = CURRENT_TIMESTAMP,
purchase_count = purchase_count + 1,
total_commission = total_commission + ?
WHERE id = ?
`, [commission, binding.id])
```
**核心变化**
- ✅ 不再改变 `status`(保持 `active`
- ✅ 累加 `purchase_count`
- ✅ 累加 `total_commission`
- ✅ 记录 `last_purchase_date`
- ✅ 支持同一绑定多次购买分佣
---
#### 2.3 支付订单:`app/api/miniprogram/pay/route.ts`
**新增功能**:好友优惠折扣
```typescript
// ✅ 读取好友优惠配置
const referralConfig = await getConfig('referral_config')
const userDiscount = referralConfig?.userDiscount || 0
// ✅ 如果有推荐码,应用折扣
if (userDiscount > 0 && body.referralCode) {
const discountRate = userDiscount / 100
finalAmount = amount * (1 - discountRate)
// 原价 1.00 → 优惠 5% → 实付 0.95
}
```
**核心变化**
- ✅ 通过推荐链接购买会自动打折
- ✅ 折扣比例从后台配置读取
- ✅ 佣金基于实付金额计算
---
#### 2.4 提现API`app/api/withdraw/route.ts`
**新增功能**:读取最低提现门槛
```typescript
// ✅ 从配置读取最低提现门槛
const config = await getConfig('referral_config')
const minWithdrawAmount = config?.minWithdrawAmount || 10
// ✅ 检查最低门槛
if (amount < minWithdrawAmount) {
return { error: `最低提现金额为 ¥${minWithdrawAmount}` }
}
```
**核心变化**
- ✅ 提现门槛可通过后台配置
- ✅ 替代了硬编码的 10 元
---
### 3. 管理后台Admin Panel
#### 3.1 推广设置页面:`app/admin/referral-settings/page.tsx`
**新增功能**
- ✅ 配置好友优惠userDiscount
- ✅ 配置推广者分成distributorShare
- ✅ 配置绑定有效期bindingDays
- ✅ 配置最低提现金额minWithdrawAmount
- ✅ 配置自动提现开关enableAutoWithdraw
**数据安全**
```typescript
// ✅ 保存时强制类型转换
const safeConfig = {
distributorShare: Number(config.distributorShare) || 0,
minWithdrawAmount: Number(config.minWithdrawAmount) || 0,
bindingDays: Number(config.bindingDays) || 0,
userDiscount: Number(config.userDiscount) || 0,
enableAutoWithdraw: Boolean(config.enableAutoWithdraw),
}
```
---
#### 3.2 菜单入口:`app/admin/layout.tsx`
```typescript
// ✅ 新增菜单项
{ icon: CreditCard, label: "推广设置", href: "/admin/referral-settings" }
```
---
### 4. 小程序MiniProgram
#### 4.1 分销中心UI`miniprogram/pages/referral/referral.wxml`
**修改**
```xml
<!-- ✅ 删除"我的邀请码"卡片 -->
<!-- 保留分享按钮和收益明细 -->
```
---
### 5. 定时任务Scheduled Task
#### 自动解绑脚本
-`scripts/auto-unbind-expired.js`(标准版)
-`scripts/auto-unbind-expired-simple.js`简化版直接连MySQL
**解绑条件**
```javascript
WHERE status = 'active'
AND expiry_date < NOW()
AND purchase_count = 0
```
**执行逻辑**
1. 查询符合条件的绑定
2. 标记为 `expired`
3. 更新推荐人的 `referral_count`
4. 输出日志
---
## 📋 完整的业务流程
### 场景1新用户绑定
```
用户操作B 点击 A 的分享链接
触发API/api/referral/bind
数据变化:
- referral_bindings 新增记录
- referee_id: B
- referrer_id: A
- status: active
- expiry_date: NOW + 30天
- purchase_count: 0
- users.referred_by: A
- users.referral_count (A): +1
```
---
### 场景2切换推荐人
```
用户操作B 点击 C 的分享链接
触发API/api/referral/bind
数据变化:
- 旧绑定 (A -> B):
- status: active → cancelled
- 新绑定 (C -> B):
- 新增记录
- status: active
- expiry_date: NOW + 30天
- users.referred_by: A → C
- users.referral_count (A): -1
- users.referral_count (C): +1
```
---
### 场景3购买分佣
```
用户操作B 购买文章1元假设无优惠
触发API/api/miniprogram/pay/notify
数据变化:
- referral_bindings (C -> B):
- purchase_count: 0 → 1
- total_commission: 0 → 0.90
- last_purchase_date: NOW
- status: 保持 active
- users.pending_earnings (C): +0.90
```
---
### 场景4好友优惠购买
```
用户操作B 通过推荐链接购买原价1元优惠5%
触发API/api/miniprogram/pay
计算逻辑:
- 原价: 1.00元
- 优惠: 1.00 × 5% = 0.05元
- 实付: 0.95元
后续分佣:
- 佣金 = 0.95 × 90% = 0.855元
- C 获得 0.86元(四舍五入)
```
---
### 场景5自动解绑
```
触发定时任务每天02:00
执行脚本scripts/auto-unbind-expired-simple.js
筛选条件:
- status = 'active'
- expiry_date < NOW
- purchase_count = 0
数据变化:
- referral_bindings: status → expired
- users.referral_count: -1对应的推荐人
```
---
## 🎯 核心逻辑总结
| 功能 | 实现状态 | 说明 |
|------|---------|------|
| **立即切换绑定** | ✅ 完成 | 点击新链接立即切换推荐人 |
| **佣金归属** | ✅ 完成 | 给购买时的当前推荐人 |
| **购买累加** | ✅ 完成 | 同一绑定可多次购买分佣 |
| **好友优惠** | ✅ 完成 | 通过推荐链接自动打折 |
| **提现门槛** | ✅ 完成 | 后台可配置最低金额 |
| **自动解绑** | ✅ 完成 | 30天无购买自动解绑 |
| **推广设置页** | ✅ 完成 | 管理后台统一配置入口 |
---
## 📦 已部署文件清单
### 后端API7个文件
1.`app/api/referral/bind/route.ts` - 立即切换绑定
2.`app/api/miniprogram/pay/notify/route.ts` - 累加分佣
3.`app/api/miniprogram/pay/route.ts` - 好友优惠
4.`app/api/withdraw/route.ts` - 提现门槛
5.`app/admin/referral-settings/page.tsx` - 推广设置页
6.`app/admin/layout.tsx` - 菜单入口
### 小程序1个文件
7.`miniprogram/pages/referral/referral.wxml` - 去掉邀请码卡片
### 脚本5个文件
8.`scripts/migrate_db_simple.py` - 数据库迁移
9.`scripts/auto-unbind-expired-simple.js` - 定时任务
10.`scripts/test-referral-flow.js` - 功能测试
### 文档3个文件
11.`开发文档/8、部署/新分销逻辑设计方案.md`
12.`开发文档/8、部署/新分销逻辑-部署步骤.md`
13.`开发文档/8、部署/新分销逻辑-宝塔操作清单.md`
---
## 🔄 部署状态
- ✅ 数据库字段已添加
- ✅ 代码已构建pnpm build
- ✅ 代码已上传服务器python devlop.py
-**待操作:宝塔面板重启服务**
-**待操作:宝塔面板配置定时任务**
---
## 🚦 下一步操作
### 必须完成(服务才能生效)
1. **重启 Node.js 服务**
- 宝塔面板 → 网站 → soul.quwanzhi.com → Node项目 → 重启
- 或SSH执行`/www/server/nodejs/v16.20.2/bin/pm2 restart soul`
2. **配置定时任务**
- 宝塔面板 → 计划任务 → 添加Shell脚本
- 执行周期:每天 02:00
- 脚本内容:
```bash
cd /www/wwwroot/soul/dist && /www/server/nodejs/v16.20.2/bin/node scripts/auto-unbind-expired-simple.js >> /www/wwwroot/soul/logs/auto-unbind.log 2>&1
```
### 建议测试
3. **验证功能**
- 访问推广设置页面:`https://soul.quwanzhi.com/admin/referral-settings`
- 小程序测试绑定切换
- 测试购买分佣
---
## ✅ 代码逻辑完成度100%
**所有核心逻辑已全部实现并部署!**
剩余工作仅为:
1. 宝塔面板重启服务1分钟
2. 宝塔面板配置定时任务2分钟
3. 功能测试验证(可选)