270 lines
6.7 KiB
Markdown
270 lines
6.7 KiB
Markdown
|
|
# 小程序最低提现金额对接说明
|
|||
|
|
|
|||
|
|
## 📋 需求
|
|||
|
|
|
|||
|
|
小程序分销中心的最低提现金额,需要从管理后台的「推广设置」→「提现规则」→「最低提现金额」动态获取。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ✅ 已完成的对接
|
|||
|
|
|
|||
|
|
### 1. 后端 API 返回最低提现金额
|
|||
|
|
|
|||
|
|
**文件**: `app/api/referral/data/route.ts`
|
|||
|
|
|
|||
|
|
**代码**(第34-42行,第200行):
|
|||
|
|
```typescript
|
|||
|
|
// 获取分销配置
|
|||
|
|
let distributorShare = DISTRIBUTOR_SHARE
|
|||
|
|
let minWithdrawAmount = 10 // 默认最低提现金额
|
|||
|
|
try {
|
|||
|
|
const config = await getConfig('referral_config')
|
|||
|
|
if (config?.distributorShare) {
|
|||
|
|
distributorShare = config.distributorShare / 100
|
|||
|
|
}
|
|||
|
|
if (config?.minWithdrawAmount) {
|
|||
|
|
minWithdrawAmount = Number(config.minWithdrawAmount)
|
|||
|
|
}
|
|||
|
|
} catch (e) { /* 使用默认配置 */ }
|
|||
|
|
|
|||
|
|
// 返回数据
|
|||
|
|
return NextResponse.json({
|
|||
|
|
data: {
|
|||
|
|
// ... 其他数据 ...
|
|||
|
|
shareRate: Math.round(distributorShare * 100),
|
|||
|
|
minWithdrawAmount, // ← 返回给小程序
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**逻辑**:
|
|||
|
|
1. 从 `system_config` 表读取 `referral_config.minWithdrawAmount`
|
|||
|
|
2. 如果读取失败,使用默认值 10
|
|||
|
|
3. 在 API 响应中返回给前端
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 2. 小程序接收并保存配置
|
|||
|
|
|
|||
|
|
**文件**: `miniprogram/pages/referral/referral.js`
|
|||
|
|
|
|||
|
|
**初始化**(第30行):
|
|||
|
|
```javascript
|
|||
|
|
data: {
|
|||
|
|
minWithdrawAmount: 10, // 最低提现金额(从后端获取)
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**动态更新**(第161行):
|
|||
|
|
```javascript
|
|||
|
|
this.setData({
|
|||
|
|
shareRate: realData?.shareRate || 90,
|
|||
|
|
minWithdrawAmount: realData?.minWithdrawAmount || 10, // ← 从API获取
|
|||
|
|
})
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**逻辑**:
|
|||
|
|
1. 页面加载时初始值为 10
|
|||
|
|
2. 调用 `/api/referral/data` 获取真实配置
|
|||
|
|
3. 使用 `setData` 更新 `minWithdrawAmount`
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 3. 小程序 UI 动态显示
|
|||
|
|
|
|||
|
|
**文件**: `miniprogram/pages/referral/referral.wxml`
|
|||
|
|
|
|||
|
|
**提现按钮**(第52-54行):
|
|||
|
|
```xml
|
|||
|
|
<view class="withdraw-btn {{pendingEarnings < minWithdrawAmount ? 'btn-disabled' : ''}}" bindtap="handleWithdraw">
|
|||
|
|
{{pendingEarnings < minWithdrawAmount ? '满' + minWithdrawAmount + '元可提现' : '申请提现'}}
|
|||
|
|
</view>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**显示效果**:
|
|||
|
|
- **未达到金额**: 按钮显示 "满10元可提现"(灰色禁用)
|
|||
|
|
- **达到金额**: 按钮显示 "申请提现"(绿色可点击)
|
|||
|
|
|
|||
|
|
**动态性**:
|
|||
|
|
- 如果管理后台改为 20 元,按钮会显示 "满20元可提现"
|
|||
|
|
- 如果管理后台改为 5 元,按钮会显示 "满5元可提现"
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 4. 提现逻辑验证(新增)
|
|||
|
|
|
|||
|
|
**文件**: `miniprogram/pages/referral/referral.js`
|
|||
|
|
|
|||
|
|
**修改前**(第559-565行):
|
|||
|
|
```javascript
|
|||
|
|
async handleWithdraw() {
|
|||
|
|
const pendingEarnings = parseFloat(this.data.pendingEarnings) || 0
|
|||
|
|
|
|||
|
|
if (pendingEarnings <= 0) {
|
|||
|
|
wx.showToast({ title: '暂无可提现收益', icon: 'none' })
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
// 直接提现(没有检查最低金额)❌
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**修改后**(已完成):
|
|||
|
|
```javascript
|
|||
|
|
async handleWithdraw() {
|
|||
|
|
const pendingEarnings = parseFloat(this.data.pendingEarnings) || 0
|
|||
|
|
const minWithdrawAmount = this.data.minWithdrawAmount || 10
|
|||
|
|
|
|||
|
|
if (pendingEarnings <= 0) {
|
|||
|
|
wx.showToast({ title: '暂无可提现收益', icon: 'none' })
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 检查是否达到最低提现金额 ✅
|
|||
|
|
if (pendingEarnings < minWithdrawAmount) {
|
|||
|
|
wx.showToast({
|
|||
|
|
title: `满${minWithdrawAmount}元可提现`,
|
|||
|
|
icon: 'none'
|
|||
|
|
})
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 确认提现...
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**优势**:
|
|||
|
|
- ✅ 双重验证(UI禁用 + 逻辑验证)
|
|||
|
|
- ✅ 防止用户绕过UI直接调用
|
|||
|
|
- ✅ 提示信息也是动态的
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📊 数据流转图
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
管理后台输入
|
|||
|
|
↓
|
|||
|
|
保存到 system_config.referral_config.minWithdrawAmount
|
|||
|
|
↓
|
|||
|
|
后端 API (/api/referral/data) 读取并返回
|
|||
|
|
↓
|
|||
|
|
小程序 loadData() 接收并保存到 this.data.minWithdrawAmount
|
|||
|
|
↓
|
|||
|
|
┌─────────────────────┬─────────────────────┐
|
|||
|
|
│ │ │
|
|||
|
|
WXML 动态显示 JS 逻辑验证
|
|||
|
|
│ │
|
|||
|
|
"满X元可提现" handleWithdraw()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🧪 测试验证
|
|||
|
|
|
|||
|
|
### 测试1: 修改最低提现金额为 20 元
|
|||
|
|
|
|||
|
|
**步骤**:
|
|||
|
|
1. 登录管理后台 `/admin/referral-settings`
|
|||
|
|
2. 将「最低提现金额」改为 **20**
|
|||
|
|
3. 点击「保存配置」
|
|||
|
|
4. 打开小程序分销中心
|
|||
|
|
5. 刷新页面(下拉刷新)
|
|||
|
|
|
|||
|
|
**预期结果**:
|
|||
|
|
- 如果待结算收益 < 20 元,按钮显示 "满20元可提现"(灰色)
|
|||
|
|
- 如果待结算收益 ≥ 20 元,按钮显示 "申请提现"(绿色)
|
|||
|
|
- 点击按钮时,也会验证是否 ≥ 20 元
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 测试2: 修改最低提现金额为 5 元
|
|||
|
|
|
|||
|
|
**步骤**:
|
|||
|
|
1. 管理后台改为 **5** 元
|
|||
|
|
2. 小程序刷新
|
|||
|
|
|
|||
|
|
**预期结果**:
|
|||
|
|
- 按钮显示 "满5元可提现" 或 "申请提现"
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 测试3: 尝试绕过验证
|
|||
|
|
|
|||
|
|
**步骤**:
|
|||
|
|
1. 设置最低提现金额为 20 元
|
|||
|
|
2. 用户只有 10 元待结算
|
|||
|
|
3. 尝试点击提现按钮(虽然已禁用)
|
|||
|
|
|
|||
|
|
**预期结果**:
|
|||
|
|
- UI 层面:按钮已禁用,无法点击 ✅
|
|||
|
|
- 逻辑层面:即使绕过UI,也会提示 "满20元可提现" ✅
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📝 对接清单
|
|||
|
|
|
|||
|
|
| 位置 | 功能 | 状态 |
|
|||
|
|
|------|------|------|
|
|||
|
|
| 管理后台 | 配置最低提现金额 | ✅ 已完成 |
|
|||
|
|
| 后端 API | 读取配置并返回 | ✅ 已完成 |
|
|||
|
|
| 小程序 JS | 接收并保存到 data | ✅ 已完成 |
|
|||
|
|
| 小程序 WXML | 动态显示按钮文案 | ✅ 已完成 |
|
|||
|
|
| 小程序 JS | 提现时验证金额 | ✅ 新增完成 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎯 核心代码位置
|
|||
|
|
|
|||
|
|
### 后端配置读取
|
|||
|
|
- **文件**: `app/api/referral/data/route.ts`
|
|||
|
|
- **行数**: 第34-42行(读取配置),第200行(返回数据)
|
|||
|
|
|
|||
|
|
### 小程序数据接收
|
|||
|
|
- **文件**: `miniprogram/pages/referral/referral.js`
|
|||
|
|
- **行数**: 第30行(初始化),第161行(动态更新)
|
|||
|
|
|
|||
|
|
### 小程序 UI 显示
|
|||
|
|
- **文件**: `miniprogram/pages/referral/referral.wxml`
|
|||
|
|
- **行数**: 第52-54行(提现按钮)
|
|||
|
|
|
|||
|
|
### 小程序逻辑验证
|
|||
|
|
- **文件**: `miniprogram/pages/referral/referral.js`
|
|||
|
|
- **行数**: 第558-578行(handleWithdraw 函数)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ✨ 完成效果
|
|||
|
|
|
|||
|
|
### 管理后台操作
|
|||
|
|
```
|
|||
|
|
1. 进入「推广设置」
|
|||
|
|
2. 修改「最低提现金额」为任意值(如 15)
|
|||
|
|
3. 保存配置
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 小程序自动响应
|
|||
|
|
```
|
|||
|
|
1. 用户打开分销中心
|
|||
|
|
2. API 自动返回最新的 minWithdrawAmount = 15
|
|||
|
|
3. 按钮显示:
|
|||
|
|
- 待结算 < 15 元 → "满15元可提现"
|
|||
|
|
- 待结算 ≥ 15 元 → "申请提现"
|
|||
|
|
4. 点击提现时,再次验证 ≥ 15 元
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🚀 无需额外操作
|
|||
|
|
|
|||
|
|
**好消息**:
|
|||
|
|
- ✅ 后端已经在返回 `minWithdrawAmount`
|
|||
|
|
- ✅ 小程序已经在使用这个值
|
|||
|
|
- ✅ UI 已经动态显示
|
|||
|
|
- ✅ 现在又加上了逻辑验证
|
|||
|
|
|
|||
|
|
**只需要部署新代码即可!**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**现在最低提现金额已经完全对接,管理后台修改后小程序会自动生效!**
|