Files
ycc-proxy-server/新代理系统完整文档.md
2025-11-27 13:09:54 +08:00

1807 lines
97 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.

# 新代理系统完整文档
## 文档说明
本文档详细记录了新代理系统的完整链路、业务逻辑、数据表结构、API接口和配置说明用于后续系统调整和维护。
**文档版本**: v1.0
**最后更新**: 2024年
**维护人员**: 开发团队
---
## 目录
1. [系统概述](#一系统概述)
2. [数据表结构](#二数据表结构)
3. [核心业务规则](#三核心业务规则)
4. [完整链路流程](#四完整链路流程)
5. [关键代码逻辑](#五关键代码逻辑)
6. [API接口列表](#六api接口列表)
7. [系统配置说明](#七系统配置说明)
8. [数据流转图](#八数据流转图)
---
## 一、系统概述
### 1.1 系统定位
新代理系统是一个三级代理分销系统,**用户只能通过邀请码成为代理**,支持邀请码管理、推广、收益分配、升级和提现等完整业务流程。
### 1.2 核心特性
- **三级代理体系**:普通(Level 1) → 黄金(Level 2) → 钻石(Level 3)
- **团队结构管理**:钻石代理作为团队首领,管理整个团队
- **邀请码机制****用户不能自主成为代理,只能通过邀请码成为代理**
- 平台发放钻石邀请码:管理员生成,用户使用后成为钻石代理(**只能使用一次,使用后立即失效**
- 代理发放邀请码:代理生成,用户使用后成为该代理的下级(**普通邀请码可以无限使用**
- 邀请链接/二维码:代理生成,用户通过链接注册成为该代理的下级
- **灵活的价格体系**:代理可自定义推广价格,系统自动计算收益
- **智能收益分配**:自动计算代理收益和上级返佣
- **升级机制**:支持自主付费升级和钻石代理升级下级
- **税费管理**:月度累计提现,自动计算税费
- **实名认证**:提现前必须完成实名认证(三要素核验,无需审核)
### 1.3 技术架构
- **框架**: Go-Zero
- **数据库**: MySQL
- **缓存**: Redis
- **支付**: 支付宝、微信支付
- **加密**: AES加密手机号、身份证号
---
## 二、数据表结构
### 2.1 核心数据表
#### 2.1.1 agent代理基本信息表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | bigint | 主键ID |
| user_id | bigint | 用户ID唯一 |
| level | tinyint | 代理等级1=普通2=黄金3=钻石 |
| region | varchar(50) | 区域(可选) |
| mobile | varchar(50) | 手机号(加密) |
| wechat_id | varchar(100) | 微信号(可选) |
| team_leader_id | bigint | 团队首领ID钻石代理的ID |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
| delete_time | datetime | 删除时间 |
| del_state | tinyint | 删除状态0=未删除1=已删除 |
| version | bigint | 版本号(乐观锁) |
**索引**:
- PRIMARY KEY (`id`)
- UNIQUE KEY `uk_user_id` (`user_id`)
- KEY `idx_mobile` (`mobile`)
- KEY `idx_level` (`level`)
- KEY `idx_team_leader_id` (`team_leader_id`)
#### 2.1.2 agent_wallet代理钱包表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | bigint | 主键ID |
| agent_id | bigint | 代理ID唯一 |
| balance | decimal(10,2) | 可用余额 |
| frozen_balance | decimal(10,2) | 冻结余额 |
| total_earnings | decimal(10,2) | 累计收益 |
| withdrawn_amount | decimal(10,2) | 已提现金额 |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
| delete_time | datetime | 删除时间 |
| del_state | tinyint | 删除状态 |
| version | bigint | 版本号 |
#### 2.1.4 agent_relation代理关系表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | bigint | 主键ID |
| parent_id | bigint | 上级代理ID |
| child_id | bigint | 下级代理ID |
| relation_type | tinyint | 关系类型1=直接关系2=已脱离 |
| detach_reason | varchar(200) | 脱离原因 |
| detach_time | datetime | 脱离时间 |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
| delete_time | datetime | 删除时间 |
| del_state | tinyint | 删除状态 |
| version | bigint | 版本号 |
**关系类型说明**:
- `relation_type = 1`: 直接关系(正常上下级)
- `relation_type = 2`: 已脱离(升级后脱离直接关系)
**唯一约束**:
- UNIQUE KEY `uk_parent_child_type` (`parent_id`, `child_id`, `relation_type`)
#### 2.1.5 agent_link推广链接表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | bigint | 主键ID |
| agent_id | bigint | 代理ID |
| user_id | bigint | 用户ID |
| product_id | bigint | 产品ID |
| link_identifier | varchar(200) | 链接标识(加密) |
| set_price | decimal(10,2) | 设定价格 |
| actual_base_price | decimal(10,2) | 实际底价(基础底价+等级加成) |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
| delete_time | datetime | 删除时间 |
| del_state | tinyint | 删除状态 |
| version | bigint | 版本号 |
**唯一约束**:
- UNIQUE KEY `uk_agent_product_price` (`agent_id`, `product_id`, `set_price`, `del_state`)
#### 2.1.6 agent_order代理订单表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | bigint | 主键ID |
| agent_id | bigint | 代理ID |
| order_id | bigint | 订单ID |
| product_id | bigint | 产品ID |
| order_amount | decimal(10,2) | 订单金额SetPrice |
| set_price | decimal(10,2) | 设定价格 |
| actual_base_price | decimal(10,2) | 实际底价 |
| price_cost | decimal(10,2) | 提价成本 |
| agent_profit | decimal(10,2) | 代理收益 |
| process_status | tinyint | 处理状态0=待处理1=处理成功2=处理失败 |
| process_time | datetime | 处理时间 |
| process_remark | varchar(500) | 处理备注 |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
| delete_time | datetime | 删除时间 |
| del_state | tinyint | 删除状态 |
| version | bigint | 版本号 |
**处理状态说明**:
- `process_status = 0`: 待处理(订单创建后)
- `process_status = 1`: 处理成功(收益已分配)
- `process_status = 2`: 处理失败
#### 2.1.7 agent_commission代理佣金表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | bigint | 主键ID |
| agent_id | bigint | 代理ID |
| order_id | bigint | 订单ID |
| product_id | bigint | 产品ID |
| amount | decimal(10,2) | 佣金金额(代理收益) |
| status | tinyint | 状态1=已发放 |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
| delete_time | datetime | 删除时间 |
| del_state | tinyint | 删除状态 |
| version | bigint | 版本号 |
#### 2.1.8 agent_rebate代理返佣表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | bigint | 主键ID |
| agent_id | bigint | 获得返佣的代理ID |
| source_agent_id | bigint | 来源代理ID产生订单的代理 |
| order_id | bigint | 订单ID |
| product_id | bigint | 产品ID |
| rebate_type | tinyint | 返佣类型1=直接上级返佣2=钻石上级返佣3=黄金上级返佣 |
| level_bonus | decimal(10,2) | 等级加成金额 |
| rebate_amount | decimal(10,2) | 返佣金额 |
| status | tinyint | 状态1=已发放 |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
| delete_time | datetime | 删除时间 |
| del_state | tinyint | 删除状态 |
| version | bigint | 版本号 |
**返佣类型说明**:
- `rebate_type = 1`: 直接上级返佣(普通代理的等级加成给直接上级)
- `rebate_type = 2`: 钻石上级返佣(给钻石上级的返佣)
- `rebate_type = 3`: 黄金上级返佣(给黄金上级的返佣)
#### 2.1.9 agent_upgrade代理升级表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | bigint | 主键ID |
| agent_id | bigint | 代理ID |
| from_level | tinyint | 原等级 |
| to_level | tinyint | 目标等级 |
| upgrade_type | tinyint | 升级类型1=自主付费2=钻石升级下级 |
| upgrade_fee | decimal(10,2) | 升级费用 |
| rebate_amount | decimal(10,2) | 返佣金额(给原直接上级) |
| rebate_agent_id | bigint | 返佣代理ID原直接上级 |
| operator_agent_id | bigint | 操作代理ID钻石升级下级时使用 |
| order_no | varchar(100) | 支付订单号 |
| status | tinyint | 状态1=待处理2=已完成3=已失败 |
| remark | varchar(500) | 备注 |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
| delete_time | datetime | 删除时间 |
| del_state | tinyint | 删除状态 |
| version | bigint | 版本号 |
**升级类型说明**:
- `upgrade_type = 1`: 自主付费升级(代理自己付费)
- `upgrade_type = 2`: 钻石升级下级(钻石代理操作,免费)
#### 2.1.10 agent_withdrawal代理提现表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | bigint | 主键ID |
| agent_id | bigint | 代理ID |
| withdraw_no | varchar(100) | 提现单号(唯一) |
| payee_account | varchar(100) | 收款账户(支付宝账号) |
| payee_name | varchar(100) | 收款人姓名 |
| amount | decimal(10,2) | 提现金额 |
| tax_amount | decimal(10,2) | 税费金额 |
| actual_amount | decimal(10,2) | 实际到账金额 |
| status | tinyint | 状态1=待审核2=审核通过3=审核拒绝4=提现中5=提现成功6=提现失败 |
| remark | varchar(500) | 备注 |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
| delete_time | datetime | 删除时间 |
| del_state | tinyint | 删除状态 |
| version | bigint | 版本号 |
**状态说明**:
- `status = 1`: 待审核(代理申请后)
- `status = 2`: 审核通过(管理员审核通过,准备转账)
- `status = 3`: 审核拒绝(管理员拒绝)
- `status = 4`: 提现中(已调用支付宝转账接口,处理中)
- `status = 5`: 提现成功(转账成功)
- `status = 6`: 提现失败(转账失败)
#### 2.1.11 agent_withdrawal_tax代理提现扣税表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | bigint | 主键ID |
| agent_id | bigint | 代理ID |
| withdrawal_id | bigint | 提现记录ID |
| year_month | bigint | 年月格式YYYYMM如202401 |
| withdrawal_amount | decimal(10,2) | 提现金额 |
| taxable_amount | decimal(10,2) | 应税金额 |
| tax_rate | decimal(5,4) | 税率 |
| tax_amount | decimal(10,2) | 税费金额 |
| actual_amount | decimal(10,2) | 实际到账金额 |
| tax_status | tinyint | 扣税状态1=待扣税2=已扣税 |
| tax_time | datetime | 扣税时间 |
| remark | varchar(500) | 备注 |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
| delete_time | datetime | 删除时间 |
| del_state | tinyint | 删除状态 |
| version | bigint | 版本号 |
**扣税状态说明**:
- `tax_status = 1`: 待扣税(提现申请后)
- `tax_status = 2`: 已扣税(提现成功后)
#### 2.1.12 agent_config代理系统配置表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | bigint | 主键ID |
| config_key | varchar(100) | 配置键(唯一) |
| config_value | varchar(500) | 配置值 |
| config_type | varchar(50) | 配置类型price=价格bonus=等级加成upgrade=升级费用rebate=返佣tax=税费 |
| description | varchar(500) | 配置描述 |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
| delete_time | datetime | 删除时间 |
| del_state | tinyint | 删除状态 |
| version | bigint | 版本号 |
**配置键列表**:
- `base_price`: 基础底价
- `system_max_price`: 系统价格上限
- `price_threshold`: 提价标准阈值
- `price_fee_rate`: 提价手续费比例
- `level_1_bonus`: 普通代理等级加成6元
- `level_2_bonus`: 黄金代理等级加成3元
- `level_3_bonus`: 钻石代理等级加成0元
- `upgrade_to_gold_fee`: 升级为黄金费用199元
- `upgrade_to_diamond_fee`: 升级为钻石费用980元
- `upgrade_to_gold_rebate`: 升级为黄金返佣139元
- `upgrade_to_diamond_rebate`: 升级为钻石返佣680元
- `tax_rate`: 税率默认0.06即6%
- `tax_exemption_amount`: 免税额度默认0
#### 2.1.13 agent_product_config代理产品配置表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | bigint | 主键ID |
| product_id | bigint | 产品ID唯一 |
| product_name | varchar(100) | 产品名称 |
| base_price | decimal(10,2) | 基础底价(可覆盖系统配置) |
| system_max_price | decimal(10,2) | 系统价格上限(可覆盖系统配置) |
| price_threshold | decimal(10,2) | 提价标准阈值(可选,覆盖系统配置) |
| price_fee_rate | decimal(5,4) | 提价手续费比例(可选,覆盖系统配置) |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
| delete_time | datetime | 删除时间 |
| del_state | tinyint | 删除状态 |
| version | bigint | 版本号 |
#### 2.1.14 agent_real_name代理实名认证表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | bigint | 主键ID |
| agent_id | bigint | 代理ID唯一 |
| name | varchar(50) | 真实姓名 |
| id_card | varchar(50) | 身份证号(加密) |
| mobile | varchar(50) | 手机号(加密) |
| verify_time | datetime | 验证时间三要素验证通过时间NULL表示未验证 |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
| delete_time | datetime | 删除时间 |
| del_state | tinyint | 删除状态 |
| version | bigint | 版本号 |
**验证说明**:
- `verify_time IS NULL`: 未验证(未通过三要素核验或未提交)
- `verify_time IS NOT NULL`: 已通过(三要素核验通过,可以提现)
**重要**:实名认证改为三要素核验,无需人工审核。提交实名认证信息后,系统自动进行三要素核验(姓名、身份证号、手机号),核验通过后自动设置 `verify_time`,无需管理员审核。
### 2.2 数据表关系图
```
agent (代理表)
├── agent_wallet (钱包表) 1:1
├── agent_link (推广链接表) 1:N
├── agent_order (代理订单表) 1:N
├── agent_relation (关系表) 1:N (作为parent_id)
│ └── agent_relation (关系表) 1:N (作为child_id)
├── agent_commission (佣金表) 1:N
├── agent_rebate (返佣表) 1:N (作为agent_id)
│ └── agent_rebate (返佣表) 1:N (作为source_agent_id)
├── agent_upgrade (升级表) 1:N
├── agent_withdrawal (提现表) 1:N
│ └── agent_withdrawal_tax (扣税表) 1:N
└── agent_real_name (实名认证表) 1:1
```
---
## 三、核心业务规则
### 3.1 代理等级体系
#### 3.1.1 等级定义
| 等级 | 数值 | 名称 | 说明 |
|------|------|------|------|
| Level 1 | 1 | 普通代理 | 初始等级,所有新代理默认等级 |
| Level 2 | 2 | 黄金代理 | 中级等级,可通过付费或钻石升级获得 |
| Level 3 | 3 | 钻石代理 | 最高等级,团队首领,可通过付费获得 |
#### 3.1.2 等级加成规则
| 等级 | 等级加成 | 说明 |
|------|---------|------|
| 普通代理 | +6元 | 实际底价 = 基础底价 + 6元 |
| 黄金代理 | +3元 | 实际底价 = 基础底价 + 3元 |
| 钻石代理 | +0元 | 实际底价 = 基础底价 |
**计算公式**:
```
实际底价 = 基础底价 + 等级加成
```
### 3.2 团队结构规则
#### 3.2.1 团队定义
- **团队**: 由一个钻石代理作为首领,及其所有下级代理组成的层级关系链
- **团队首领**: 必须是钻石代理,每个团队有且仅有一个首领
- **团队关系**: 通过 `team_leader_id` 字段关联,所有团队成员指向同一个钻石代理
#### 3.2.2 上下级关系约束
**核心原则**:
1. **下级不能比上级等级高**: 下级等级必须 ≤ 上级等级
2. **同级不能作为上下级**(除了普通代理): 黄金和钻石不能作为同级上下级
3. **钻石 → 黄金禁止**: 钻石代理不能直接管理黄金代理(特殊规则)
**允许的关系**:
- 普通 → 普通 ✓(同级普通允许)
- 黄金 → 普通 ✓(上级等级高于下级)
- 钻石 → 普通 ✓(上级等级高于下级)
- 钻石 → 黄金 ✓上级等级高于下级但实际禁止见规则3
**禁止的关系**:
- 普通 → 黄金 ✗(下级等级高于上级)
- 普通 → 钻石 ✗(下级等级高于上级)
- 黄金 → 黄金 ✗(同级不能作为上下级)
- 钻石 → 钻石 ✗(同级不能作为上下级)
- 黄金 → 钻石 ✗(下级等级高于上级)
- 钻石 → 黄金 ✗(特殊规则禁止)
#### 3.2.3 升级规则
**核心规则**: 代理升级后,其所有下级(直接+间接)会跟随该代理。
**升级场景**:
1. **普通 → 黄金**:
- 升级后必须脱离直接上级关系(因为黄金等级高于普通,或与黄金同级)
- 保留团队关系(通过团队首领钻石代理)
- 仍属于原团队
- 所有下级(直接+间接)继续跟随该代理
2. **黄金 → 钻石**:
- 独立成为新团队
- 成为新团队的首领(`team_leader_id = 自己`
- 所有下级(直接+间接)跟随该代理到新团队
3. **普通 → 钻石**:
- 独立成为新团队
- 成为新团队的首领
- 所有下级(直接+间接)跟随该代理到新团队
#### 3.2.4 升级方法和费用规则
**升级方式**:
1. **钻石代理升级下级**:
- 钻石代理可以将下级的普通代理升级为黄金代理
- 升级方式: 钻石代理操作,无需被升级代理付费
- 限制: 只能升级普通代理为黄金代理
2. **代理自主付费升级**:
- 普通代理可以付费升级为黄金代理199元
- 普通代理可以付费升级为钻石代理980元
- 黄金代理可以付费升级为钻石代理980元
**升级费用和返佣规则**:
| 升级类型 | 升级费用 | 直接上级返佣 | 说明 |
|---------|---------|-------------|------|
| 普通→黄金 | 199元 | 139元 | 付费后立即返佣给直接上级 |
| 普通→钻石 | 980元 | 680元 | 付费后立即返佣给直接上级 |
| 黄金→钻石 | 980元 | 680元 | 付费后立即返佣给直接上级 |
| 钻石升级下级(普通→黄金) | 免费 | 无 | 钻石代理操作,被升级代理无需付费 |
**重要规则**:
-**返佣给原直接上级**: 即使升级后脱离直接上下级关系,返佣仍然给原直接上级
-**返佣时机**: 付费成功后立即返佣,然后执行升级操作
-**升级流程**: 付费 → 返佣给直接上级 → 升级 → 根据情况脱离关系
### 3.3 价格体系规则
#### 3.3.1 价格计算公式
```
实际底价 = 基础底价 + 等级加成
代理收益 = 设定价格 - 实际底价 - 提价成本
提价成本 = (设定价格 - 提价阈值) × 提价手续费比例(当设定价格 > 提价阈值时)
```
#### 3.3.2 价格约束
- **最低价格**: 实际底价(基础底价 + 等级加成)
- **最高价格**: 系统价格上限(或产品配置的价格上限)
- **价格范围**: `实际底价 ≤ 设定价格 ≤ 系统价格上限`
#### 3.3.3 提价成本计算
- **当设定价格 ≤ 提价阈值**: 提价成本 = 0
- **当设定价格 > 提价阈值**: 提价成本 = (设定价格 - 提价阈值) × 提价手续费比例
### 3.4 收益分配规则
#### 3.4.1 代理收益
代理收益 = 设定价格 - 实际底价 - 提价成本
**分配流程**:
1. 订单支付成功后,触发 `AgentService.AgentProcess`
2. 计算代理收益并发放到代理钱包
3. 创建 `agent_commission` 记录
4. 更新 `agent_wallet` 余额和累计收益
#### 3.4.2 等级加成返佣分配
**普通代理等级加成6元**:
1. **优先级1**: 给直接上级最多3元
- 如果直接上级存在分配3元给直接上级
- 剩余金额 = 6 - 3 = 3元
2. **优先级2**: 给钻石上级(剩余金额全部)
- 查找上级链中的钻石代理
- 如果找到,剩余金额全部给钻石上级
3. **优先级3**: 给黄金上级最多3元如果钻石上级不存在
- 如果钻石上级不存在,查找黄金上级
- 如果找到最多分配3元给黄金上级
- 如果剩余金额 > 3元超出部分归平台
4. **优先级4**: 都没有,剩余金额归平台
**黄金代理等级加成3元**:
1. 全部给钻石上级(如有)
2. 如果找不到钻石上级,归平台
**钻石代理等级加成0元**:
- 无返佣分配
#### 3.4.3 返佣记录
所有返佣都会记录到 `agent_rebate` 表,包含:
- 获得返佣的代理ID
- 来源代理ID产生订单的代理
- 返佣类型1=直接上级2=钻石上级3=黄金上级)
- 返佣金额
- 等级加成金额
### 3.5 提现规则
#### 3.5.1 提现条件
1. **实名认证**: 必须完成实名认证且三要素核验已通过(`verify_time` 不为空)
2. **余额充足**: 钱包余额 >= 提现金额
3. **账户信息**: 必须提供支付宝账号和收款人姓名
#### 3.5.2 税费计算规则
**计算公式**:
```
本月累计提现金额 = 查询本月所有已提现金额之和
剩余免税额度 = 免税额度 - 本月累计提现金额
如果 本次提现金额 <= 剩余免税额度:
应税金额 = 0
税费 = 0
否则:
应税金额 = 本次提现金额 - 剩余免税额度
税费 = 应税金额 × 税率
实际到账金额 = 提现金额 - 税费
```
**示例**:
- 免税额度: 1000元
- 税率: 6%
- 本月已提现: 800元
- 本次提现: 500元
计算:
- 剩余免税额度 = 1000 - 800 = 200元
- 本次提现500元 > 剩余免税额度200元
- 应税金额 = 500 - 200 = 300元
- 税费 = 300 × 6% = 18元
- 实际到账 = 500 - 18 = 482元
#### 3.5.3 提现流程
1. **代理申请提现**:
- 验证实名认证状态
- 验证余额
- 计算税费
- 冻结余额
- 创建提现记录和扣税记录
2. **管理员审核**:
- 审核通过: 调用支付宝转账接口
- 审核拒绝: 解冻余额,返回余额
3. **转账处理**:
- 转账成功: 解冻并扣除余额,更新扣税状态
- 转账失败: 解冻余额,返回余额
- 处理中: 保持提现中状态,后续轮询更新
---
## 四、完整链路流程
### 4.1 通过邀请码成为代理链路
**重要规则**:用户不能自主成为代理,只能通过邀请码成为代理。成为代理的唯一途径包括:
1. 平台发放钻石邀请码
2. 代理发放邀请码
3. 代理邀请链接/二维码
```
┌─────────────────────────────────────────────────────────────┐
│ 1. 用户通过邀请码申请成为代理 │
│ API: POST /api/v1/agent/apply │
│ Logic: ApplyForAgentLogic │
│ - 必须提供邀请码(必填) │
│ - 如果没有邀请码,直接拒绝 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 2. 验证手机验证码 │
│ - 从Redis读取验证码 │
│ - 验证码校验 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 3. 用户注册/绑定(如需要) │
│ - 检查用户是否存在 │
│ - 不存在则注册新用户 │
│ - 临时用户则绑定为正式用户 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 4. 检查是否已是代理 │
│ - 检查是否已是代理agent表
│ - 如果已是代理,直接拒绝 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 5. 验证邀请码 │
│ - 查询邀请码是否存在 │
│ - 验证邀请码状态(未使用、未过期) │
│ - 获取邀请码信息目标等级、发放代理ID
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 6. 创建代理记录 │
│ - 根据邀请码的target_level设置代理等级 │
│ - 如果是代理发放的邀请码,建立上下级关系 │
│ - 如果是平台发放的钻石邀请码,独立成团队 │
│ - 初始化钱包 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 7. 更新邀请码状态 │
│ - **钻石邀请码**:状态更新为"已使用"status=1使用后立即失效│
│ - **普通邀请码**不更新状态保持未使用status=0可继续使用│
│ - 记录使用用户ID和代理ID用于统计
│ - 记录使用时间 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 8. 生成并返回Token │
│ - 生成JWT Token │
│ - 返回给前端 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 8. 完成(无需审核,直接成为代理) │
│ - 代理记录已创建 │
│ - 钱包已初始化 │
│ - 关系已建立(如有上级) │
│ - 团队首领已设置 │
│ - 微信号和区域为可选字段 │
└─────────────────────────────────────────────────────────────┘
```
### 4.2 推广链接生成链路
```
┌─────────────────────────────────────────────────────────────┐
│ 1. 代理生成推广链接 │
│ API: POST /api/v1/agent/link/generate │
│ Logic: GeneratingLinkLogic │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 2. 获取代理信息 │
│ - 从Token获取用户ID │
│ - 查询 agent 表 │
│ - 验证代理身份 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 3. 获取系统配置 │
│ - base_price基础底价
│ - system_max_price系统价格上限
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 4. 计算实际底价 │
│ 实际底价 = 基础底价 + 等级加成 │
│ - 普通代理: +6元 │
│ - 黄金代理: +3元 │
│ - 钻石代理: +0元 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 5. 验证设定价格范围 │
│ - 实际底价 ≤ 设定价格 ≤ 系统价格上限 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 6. 检查是否已存在相同链接 │
│ - 查询 agent_link 表 │
│ - 条件: agent_id + product_id + set_price + del_state=0 │
│ - 如果存在,直接返回已有链接 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 7. 生成推广链接标识 │
│ - 构建 AgentIdentifier 结构 │
│ { AgentID, ProductID, SetPrice } │
│ - JSON序列化 │
│ - AES加密生成 LinkIdentifier │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 8. 保存推广链接 │
│ - 插入 agent_link 表 │
│ - 记录 agent_id, product_id, link_identifier │
│ - 记录 set_price, actual_base_price │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 9. 返回加密后的 LinkIdentifier │
│ - 前端使用此标识生成推广链接 │
└─────────────────────────────────────────────────────────────┘
```
### 4.3 订单处理与收益分配链路
```
┌─────────────────────────────────────────────────────────────┐
│ 1. 用户通过推广链接下单 │
│ API: POST /api/v1/pay/payment │
│ Logic: PaymentLogic │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 2. 解析推广链接标识 │
│ - 解密 LinkIdentifier │
│ - 解析 AgentIdentifier │
│ - 获取 AgentID, ProductID, SetPrice │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 3. 查询推广链接信息 │
│ - 查询 agent_link 表 │
│ - 验证链接有效性 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 4. 创建订单记录 │
│ - 插入 order 表 │
│ - 记录订单金额SetPrice
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 5. 创建代理订单记录 │
│ - 插入 agent_order 表 │
│ - OrderAmount = SetPrice │
│ - SetPrice = 设定价格 │
│ - ActualBasePrice = 实际底价(基础底价+等级加成) │
│ - PriceCost = 提价成本 │
│ - AgentProfit = 代理收益SetPrice - ActualBasePrice - PriceCost
│ - ProcessStatus = 0待处理
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 6. 用户支付订单 │
│ - 调用支付宝/微信支付接口 │
│ - 生成支付订单 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 7. 支付成功回调 │
│ - 支付宝/微信支付回调 │
│ - 验证签名 │
│ - 更新订单状态 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 8. 触发代理订单处理 │
│ Service: AgentService.AgentProcess │
│ - 检查是否是代理订单 │
│ - 检查订单是否已处理(防重复) │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 9. 获取代理信息和系统配置 │
│ - 查询 agent 表 │
│ - 获取代理等级 │
│ - 获取系统配置base_price等
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 10. 使用事务处理订单(开始事务) │
│ - 计算实际底价和代理收益 │
│ - 计算提价成本 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 11. 更新代理订单状态 │
│ - ProcessStatus = 1处理成功
│ - ProcessTime = 当前时间 │
│ - ProcessRemark = "处理成功" │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 12. 发放代理佣金 │
│ - 创建 agent_commission 记录 │
│ - 更新 agent_wallet │
│ Balance += AgentProfit │
│ TotalEarnings += AgentProfit │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 13. 分配等级加成返佣 │
│ - 根据代理等级分配返佣 │
│ - 普通代理6元: 给直接上级3元剩余给钻石/黄金上级 │
│ - 黄金代理3元: 全部给钻石上级 │
│ - 钻石代理0元: 无返佣 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 14. 记录返佣 │
│ - 创建 agent_rebate 记录 │
│ - 更新上级钱包余额 │
│ - 记录返佣类型和金额 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 15. 提交事务(完成) │
└─────────────────────────────────────────────────────────────┘
```
### 4.4 代理升级链路
#### 4.4.1 自主付费升级链路
```
┌─────────────────────────────────────────────────────────────┐
│ 1. 代理申请升级 │
│ API: POST /api/v1/agent/upgrade/apply │
│ Logic: ApplyUpgradeLogic │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 2. 验证升级条件 │
│ - 验证当前等级和目标等级 │
│ - 普通→黄金: ✓ │
│ - 普通→钻石: ✓ │
│ - 黄金→钻石: ✓ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 3. 计算升级费用和返佣 │
│ - 普通→黄金: 199元返佣139元 │
│ - 普通→钻石: 980元返佣680元 │
│ - 黄金→钻石: 980元返佣680元 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 4. 查找原直接上级 │
│ - 查询 agent_relation 表 │
│ - RelationType = 1直接关系
│ - 用于返佣 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 5. 创建升级记录 │
│ - 插入 agent_upgrade 表 │
│ - UpgradeType = 1自主付费
│ - Status = 1待处理
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 6. 返回升级ID和订单号 │
│ - 用于支付 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 7. 用户支付升级费用 │
│ - 调用支付接口 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 8. 支付成功回调 │
│ - 触发升级处理 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 9. 执行升级操作 │
│ Service: AgentService.ProcessUpgrade │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 10. 返佣给原直接上级(开始事务) │
│ - 更新上级钱包余额 │
│ - Balance += RebateAmount │
│ - TotalEarnings += RebateAmount │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 11. 更新代理等级 │
│ - agent.Level = toLevel │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 12. 检查是否需要脱离直接上级关系 │
│ - 检查升级后等级是否高于上级 │
│ - 检查是否同级(黄金/钻石) │
│ - 检查是否钻石→黄金(禁止) │
└─────────────────────────────────────────────────────────────┘
┌───────────────────────────────┐
│ 需要脱离关系 │
└───────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 13. 脱离直接上级关系 │
│ - 更新 agent_relation 表 │
│ - RelationType = 2已脱离
│ - DetachReason = "upgrade" │
│ - DetachTime = 当前时间 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 14. 更新团队首领 │
│ - 如果升级为钻石: team_leader_id = 自己 │
│ - 如果升级为黄金: 查找上级链中的钻石代理 │
│ - 更新所有下级的 team_leader_id │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 15. 更新升级记录状态 │
│ - Status = 2已完成
│ - Remark = "升级成功" │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 16. 提交事务(完成) │
└─────────────────────────────────────────────────────────────┘
```
#### 4.4.2 钻石升级下级链路
```
┌─────────────────────────────────────────────────────────────┐
│ 1. 钻石代理升级下级 │
│ API: POST /api/v1/agent/upgrade/subordinate │
│ Logic: UpgradeSubordinateLogic │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 2. 验证权限 │
│ - 必须是钻石代理Level = 3
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 3. 验证下级等级 │
│ - 只能是普通代理Level = 1
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 4. 验证关系 │
│ - 必须是直接下级 │
│ - 查询 agent_relation 表 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 5. 验证目标等级 │
│ - 只能升级为黄金toLevel = 2
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 6. 创建升级记录 │
│ - 插入 agent_upgrade 表 │
│ - UpgradeType = 2钻石升级下级
│ - UpgradeFee = 0免费
│ - RebateAmount = 0无返佣
│ - OperatorAgentId = 操作者代理ID │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 7. 执行升级操作 │
│ Service: AgentService.ProcessUpgrade │
│ - 更新下级等级为黄金 │
│ - 脱离直接上级关系(如需要) │
│ - 更新团队首领(保持原团队首领) │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 8. 更新升级记录状态 │
│ - Status = 2已完成
│ - Remark = "钻石代理升级下级成功" │
└─────────────────────────────────────────────────────────────┘
```
### 4.5 提现链路
```
┌─────────────────────────────────────────────────────────────┐
│ 1. 代理申请提现 │
│ API: POST /api/v1/agent/withdrawal/apply │
│ Logic: ApplyWithdrawalLogic │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 2. 验证实名认证 │
│ - 查询 agent_real_name 表 │
│ - verify_time 必须不为空(三要素核验已通过) │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 3. 验证提现金额 │
│ - Amount > 0 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 4. 验证钱包余额 │
│ - Balance >= Amount │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 5. 计算税费 │
│ - 查询本月累计提现金额 │
│ - 计算剩余免税额度 │
│ - 计算应税金额 │
│ - 计算税费 = 应税金额 × 税率 │
│ - 计算实际到账金额 = 提现金额 - 税费 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 6. 生成提现单号 │
│ - 格式: WD + timestamp + agentId │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 7. 使用事务处理提现申请(开始事务) │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 8. 冻结余额 │
│ - FrozenBalance += Amount │
│ - Balance -= Amount │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 9. 创建提现记录 │
│ - 插入 agent_withdrawal 表 │
│ - Status = 1待审核
│ - 记录 PayeeAccount, PayeeName │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 10. 创建扣税记录 │
│ - 插入 agent_withdrawal_tax 表 │
│ - TaxStatus = 1待扣税
│ - 记录 YearMonth, TaxableAmount, TaxAmount │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 11. 提交事务(完成) │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 12. 管理员审核提现 │
│ API: POST /api/v1/admin/agent/withdrawal/audit │
│ Logic: AdminAuditWithdrawalLogic │
└─────────────────────────────────────────────────────────────┘
┌───────────────────────────────┐
│ 审核通过Status=2
└───────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 13. 更新提现状态为提现中 │
│ - Status = 4提现中
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 14. 调用支付宝转账接口 │
│ - AliTransfer(account, name, amount, remark, outBizNo) │
└─────────────────────────────────────────────────────────────┘
┌───────────────┬───────────────┬───────────────┐
│ 转账成功 │ 转账失败 │ 处理中 │
│ (SUCCESS) │ (FAIL) │ (DEALING) │
└───────────────┴───────────────┴───────────────┘
↓ ↓ ↓
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ 15. 更新状态 │ │ 15. 更新状态 │ │ 15. 保持状态 │
│ Status = 5 │ │ Status = 6 │ │ Status = 4 │
│ (提现成功) │ │ (提现失败) │ │ (提现中) │
└───────────────┘ └───────────────┘ └───────────────┘
↓ ↓
┌───────────────┐ ┌───────────────┐
│ 16. 解冻并扣 │ │ 16. 解冻余额 │
│ 除余额 │ │ 返回余额 │
│ - FrozenBalance│ │ - FrozenBalance│
│ -= Amount │ │ -= Amount │
│ - WithdrawnAmount│ │ - Balance │
│ += Amount │ │ += Amount │
└───────────────┘ └───────────────┘
┌───────────────┐
│ 17. 更新扣税 │
│ 状态 │
│ TaxStatus = 2 │
│ (已扣税) │
└───────────────┘
```
### 4.6 实名认证链路
```
┌─────────────────────────────────────────────────────────────┐
│ 1. 代理提交实名认证信息 │
│ API: POST /api/v1/agent/real_name │
│ Logic: RealNameAuthLogic │
│ - 姓名、身份证号、手机号 │
│ - 验证码(手机号验证码) │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 2. 验证代理身份 │
│ - 从Token获取用户ID │
│ - 查询 agent 表 │
│ - 验证手机号是否匹配 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 3. 验证手机验证码 │
│ - 从Redis读取验证码 │
│ - 验证码校验 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 4. 三要素核验(自动) │
│ - 调用 VerificationService.ThreeFactorVerification │
│ - 核验姓名、身份证号、手机号是否一致 │
│ - 核验通过:继续流程 │
│ - 核验失败:返回错误 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 5. 加密敏感信息 │
│ - 加密身份证号 │
│ - 加密手机号 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 6. 保存实名认证记录(开始事务) │
│ - 检查是否已有记录 │
│ - 如有记录更新姓名、身份证号、手机号、verify_time │
│ - 如无记录:创建新记录,设置 verify_time = 当前时间 │
│ - verify_time 不为空表示已通过三要素核验 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 7. 提交事务(完成) │
│ - 返回成功,实名认证完成 │
│ - 可以申请提现 │
└─────────────────────────────────────────────────────────────┘
```
**重要说明**
- 实名认证改为三要素核验,无需人工审核
- 核验通过后自动设置 `verify_time`,无需管理员操作
- `verify_time` 不为空即表示已通过认证,可以提现
---
## 五、关键代码逻辑
### 5.1 AgentService 核心方法
#### 5.1.1 AgentProcess订单处理
**文件**: `app/main/api/internal/service/agentService.go`
**功能**: 处理代理订单,分配收益和返佣
**核心逻辑**:
```go
func (s *AgentService) AgentProcess(ctx context.Context, order *model.Order) error {
// 1. 检查是否是代理订单
agentOrder, err := s.AgentOrderModel.FindOneByOrderId(ctx, order.Id)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return nil // 不是代理订单
}
return err
}
// 2. 检查订单是否已处理(防重复)
if agentOrder.ProcessStatus == 1 {
return nil
}
// 3. 获取代理信息和系统配置
agent, err := s.AgentModel.FindOne(ctx, agentOrder.AgentId)
basePrice, err := s.getConfigFloat(ctx, "base_price")
// 4. 使用事务处理
return s.AgentWalletModel.Trans(ctx, func(transCtx context.Context, session sqlx.Session) error {
// 4.1 计算实际底价和代理收益
levelBonus := s.getLevelBonus(agent.Level)
actualBasePrice := basePrice + float64(levelBonus)
priceCost := s.calculatePriceCost(agentOrder.SetPrice, priceThreshold, priceFeeRate)
agentProfit := agentOrder.SetPrice - actualBasePrice - priceCost
// 4.2 更新代理订单状态
agentOrder.ProcessStatus = 1
s.AgentOrderModel.UpdateWithVersion(transCtx, session, agentOrder)
// 4.3 发放代理佣金
s.giveAgentCommission(transCtx, session, agentOrder.AgentId, order.Id, order.ProductId, agentProfit)
// 4.4 分配等级加成返佣
if levelBonus > 0 {
s.distributeLevelBonus(transCtx, session, agent, order.Id, order.ProductId, float64(levelBonus), levelBonus)
}
return nil
})
}
```
#### 5.1.2 distributeLevelBonus等级加成返佣分配
**功能**: 根据代理等级分配等级加成返佣给上级链
**核心逻辑**:
```go
func (s *AgentService) distributeLevelBonus(ctx context.Context, session sqlx.Session, agent *model.Agent, orderId, productId int64, levelBonus float64, levelBonusInt int64) error {
// 钻石代理等级加成为0无返佣分配
if agent.Level == 3 {
return nil
}
// 黄金代理等级加成3元全部给钻石上级
if agent.Level == 2 {
diamondParent, err := s.findDiamondParent(ctx, agent.Id)
if diamondParent != nil {
100002 return s.giveRebate(ctx, session, diamondParent.Id, agent.Id, orderId, productId, levelBonus, levelBonusInt, 2)
}
return nil
}
// 普通代理等级加成6元按规则分配给上级链
if agent.Level == 1 {
return s.distributeNormalAgentBonus(ctx, session, agent, orderId, productId, levelBonus, levelBonusInt)
}
return nil
}
```
#### 5.1.3 ProcessUpgrade代理升级处理
**功能**: 处理代理升级,包括返佣、关系脱离、团队首领更新
**核心逻辑**:
```go
func (s *AgentService) ProcessUpgrade(ctx context.Context, agentId, toLevel int64, upgradeType int64, upgradeFee, rebateAmount float64, orderNo string, operatorAgentId int64) error {
return s.AgentWalletModel.Trans(ctx, func(transCtx context.Context, session sqlx.Session) error {
// 1. 获取代理信息
agent, err := s.AgentModel.FindOne(transCtx, agentId)
// 2. 如果是自主付费升级,处理返佣
if upgradeType == 1 {
parent, err := s.findDirectParent(transCtx, agentId)
if parent != nil && rebateAmount > 0 {
s.giveRebateForUpgrade(transCtx, session, parent.Id, agentId, rebateAmount)
}
}
// 3. 更新代理等级
agent.Level = toLevel
// 4. 检查是否需要脱离直接上级关系
needDetach, err := s.needDetachFromParent(transCtx, agent, toLevel)
if needDetach {
s.detachFromParent(transCtx, session, agentId)
}
// 5. 如果升级为钻石,独立成新团队
if toLevel == 3 {
agent.TeamLeaderId = sql.NullInt64{Int64: agentId, Valid: true}
s.updateChildrenTeamLeader(transCtx, session, agentId, agentId)
} else {
// 更新团队首领(查找上级链中的钻石代理)
teamLeaderId, _ := s.findTeamLeaderId(transCtx, agentId)
if teamLeaderId > 0 {
agent.TeamLeaderId = sql.NullInt64{Int64: teamLeaderId, Valid: true}
}
}
// 6. 更新代理记录
s.AgentModel.UpdateWithVersion(transCtx, session, agent)
return nil
})
}
```
#### 5.1.4 calculateTax税费计算
**功能**: 计算提现税费,基于月度累计和免税额度
**核心逻辑**:
```go
func calculateTax(ctx context.Context, agentId int64, amount float64, yearMonth int64) (*TaxInfo, error) {
// 1. 获取税率配置默认6%
taxRate := 0.06
config, _ := AgentConfigModel.FindOneByConfigKey(ctx, "tax_rate")
if config != nil {
taxRate = parseFloat(config.ConfigValue)
}
// 2. 查询本月已提现金额
taxRecords, _ := AgentWithdrawalTaxModel.FindAll(...)
monthlyTotal := sum(taxRecords.WithdrawalAmount)
// 3. 获取免税额度配置默认0
exemptionAmount := 0.0
exemptionConfig, _ := AgentConfigModel.FindOneByConfigKey(ctx, "tax_exemption_amount")
if exemptionConfig != nil {
exemptionAmount = parseFloat(exemptionConfig.ConfigValue)
}
// 4. 计算应税金额
remainingExemption := exemptionAmount - monthlyTotal
taxableAmount := amount
if remainingExemption > 0 {
if amount <= remainingExemption {
taxableAmount = 0 // 完全免税
} else {
taxableAmount = amount - remainingExemption // 部分免税
}
}
// 5. 计算税费和实际到账金额
taxAmount := taxableAmount * taxRate
actualAmount := amount - taxAmount
return &TaxInfo{
TaxableAmount: taxableAmount,
TaxRate: taxRate,
TaxAmount: taxAmount,
ActualAmount: actualAmount,
}, nil
}
```
---
## 六、API接口列表
### 6.1 前端接口agent.api
#### 6.1.1 公开接口(无需登录)
| 接口 | 方法 | 路径 | 说明 |
|------|------|------|------|
| 获取推广链接数据 | GET | `/api/v1/agent/link` | 根据LinkIdentifier获取推广链接信息 |
| 通过邀请码申请成为代理 | POST | `/api/v1/agent/apply` | 用户通过邀请码申请成为代理(必须提供邀请码) |
#### 6.1.2 需要登录的接口
| 接口 | 方法 | 路径 | 说明 |
|------|------|------|------|
| ~~查询代理申请状态~~ | ~~GET~~ | ~~`/api/v1/agent/audit/status`~~ | ~~查询当前用户的代理申请审核状态(已废弃:无需审核)~~ |
| 查看代理信息 | GET | `/api/v1/agent/info` | 获取当前代理的详细信息 |
| 生成推广链接 | POST | `/api/v1/agent/generating_link` | 生成产品推广链接 |
| 获取产品配置 | GET | `/api/v1/agent/product_config` | 获取代理可配置的产品价格信息 |
| 获取团队统计 | GET | `/api/v1/agent/team/statistics` | 获取团队统计数据 |
| 获取下级列表 | GET | `/api/v1/agent/subordinate/list` | 分页查询直接下级列表 |
| 获取收益信息 | GET | `/api/v1/agent/revenue` | 获取钱包余额和收益信息 |
| 获取佣金记录 | GET | `/api/v1/agent/commission/list` | 分页查询佣金记录 |
| 获取返佣记录 | GET | `/api/v1/agent/rebate/list` | 分页查询返佣记录 |
| 获取升级记录 | GET | `/api/v1/agent/upgrade/list` | 分页查询升级记录 |
| 申请升级 | POST | `/api/v1/agent/upgrade/apply` | 自主付费升级 |
| 钻石升级下级 | POST | `/api/v1/agent/upgrade/subordinate` | 钻石代理升级下级 |
| 获取提现列表 | GET | `/api/v1/agent/withdrawal/list` | 分页查询提现记录 |
| 申请提现 | POST | `/api/v1/agent/withdrawal/apply` | 申请提现 |
| 实名认证 | POST | `/api/v1/agent/real_name` | 提交实名认证信息(三要素核验,自动通过) |
### 6.2 后台管理接口admin_agent.api
| 接口 | 方法 | 路径 | 说明 |
|------|------|------|------|
| 代理分页查询 | GET | `/api/v1/admin/agent/list` | 分页查询代理列表 |
| ~~代理审核~~ | ~~POST~~ | ~~`/api/v1/admin/agent/audit`~~ | ~~审核代理申请(已废弃:通过邀请码直接成为代理,无需审核)~~ |
| 推广链接分页查询 | GET | `/api/v1/admin/agent/link/list` | 分页查询推广链接 |
| 代理订单分页查询 | GET | `/api/v1/admin/agent/order/list` | 分页查询代理订单 |
| 代理佣金分页查询 | GET | `/api/v1/admin/agent/commission/list` | 分页查询佣金记录 |
| 代理返佣分页查询 | GET | `/api/v1/admin/agent/rebate/list` | 分页查询返佣记录 |
| 代理升级记录分页查询 | GET | `/api/v1/admin/agent/upgrade/list` | 分页查询升级记录 |
| 代理提现分页查询 | GET | `/api/v1/admin/agent/withdrawal/list` | 分页查询提现记录 |
| 代理提现审核 | POST | `/api/v1/admin/agent/withdrawal/audit` | 审核提现申请 |
| 代理实名认证分页查询 | GET | `/api/v1/admin/agent/real_name/list` | 分页查询实名认证记录 |
| ~~代理实名认证审核~~ | ~~POST~~ | ~~`/api/v1/admin/agent/real_name/audit`~~ | ~~审核实名认证(已废弃:改为三要素核验,无需审核)~~ |
| 系统配置查询 | GET | `/api/v1/admin/agent/config` | 查询系统配置 |
| 系统配置更新 | POST | `/api/v1/admin/agent/config/update` | 更新系统配置 |
| 产品配置分页查询 | GET | `/api/v1/admin/agent/product_config/list` | 分页查询产品配置 |
| 产品配置更新 | POST | `/api/v1/admin/agent/product_config/update` | 更新产品配置 |
---
## 七、系统配置说明
### 7.1 系统配置项agent_config表
| 配置键 | 配置类型 | 默认值 | 说明 |
|--------|---------|--------|------|
| `base_price` | price | - | 基础底价(系统默认) |
| `system_max_price` | price | - | 系统价格上限 |
| `price_threshold` | price | - | 提价标准阈值 |
| `price_fee_rate` | price | - | 提价手续费比例0-1之间的小数 |
| `level_1_bonus` | bonus | 6 | 普通代理等级加成(元) |
| `level_2_bonus` | bonus | 3 | 黄金代理等级加成(元) |
| `level_3_bonus` | bonus | 0 | 钻石代理等级加成(元) |
| `upgrade_to_gold_fee` | upgrade | 199 | 升级为黄金费用(元) |
| `upgrade_to_diamond_fee` | upgrade | 980 | 升级为钻石费用(元) |
| `upgrade_to_gold_rebate` | rebate | 139 | 升级为黄金返佣(元) |
| `upgrade_to_diamond_rebate` | rebate | 680 | 升级为钻石返佣(元) |
| `tax_rate` | tax | 0.06 | 税率默认6%即0.06 |
| `tax_exemption_amount` | tax | 0 | 免税额度默认0 |
### 7.2 产品配置项agent_product_config表
每个产品可以单独配置以下参数,覆盖系统默认配置:
| 字段 | 说明 |
|------|------|
| `base_price` | 产品基础底价(覆盖系统配置) |
| `system_max_price` | 产品价格上限(覆盖系统配置) |
| `price_threshold` | 产品提价标准阈值(可选,覆盖系统配置) |
| `price_fee_rate` | 产品提价手续费比例(可选,覆盖系统配置) |
### 7.3 配置优先级
1. **产品配置** > **系统配置**
- 如果产品配置了 `base_price`,使用产品配置
- 如果产品未配置,使用系统配置
2. **系统配置** > **代码默认值**
- 如果系统配置存在,使用系统配置
- 如果系统配置不存在,使用代码中的默认值
---
## 八、数据流转图
### 8.1 订单处理数据流
```
用户下单
创建 order 记录
创建 agent_order 记录ProcessStatus=0
用户支付
支付成功回调
调用 AgentService.AgentProcess
┌─────────────────────────────────────┐
│ 事务开始 │
│ 1. 计算实际底价 = 基础底价 + 等级加成 │
│ 2. 计算提价成本 │
│ 3. 计算代理收益 │
│ 4. 更新 agent_order (ProcessStatus=1) │
│ 5. 创建 agent_commission 记录 │
│ 6. 更新 agent_wallet (Balance, TotalEarnings) │
│ 7. 分配等级加成返佣 │
│ - 创建 agent_rebate 记录 │
│ - 更新上级 agent_wallet │
│ 事务提交 │
└─────────────────────────────────────┘
```
### 8.2 升级处理数据流
```
代理申请升级
创建 agent_upgrade 记录Status=1
用户支付升级费用
支付成功回调
调用 AgentService.ProcessUpgrade
┌─────────────────────────────────────┐
│ 事务开始 │
│ 1. 返佣给原直接上级(如需要) │
│ - 更新上级 agent_wallet │
│ 2. 更新 agent.Level │
│ 3. 检查是否需要脱离关系 │
│ - 更新 agent_relation (RelationType=2) │
│ 4. 更新团队首领 │
│ - 更新 agent.TeamLeaderId │
│ - 更新所有下级的 TeamLeaderId │
│ 5. 更新 agent_upgrade (Status=2) │
│ 事务提交 │
└─────────────────────────────────────┘
```
### 8.3 提现处理数据流
```
代理申请提现
验证实名认证和余额
计算税费
┌─────────────────────────────────────┐
│ 事务开始 │
│ 1. 冻结余额 │
│ - agent_wallet.FrozenBalance += Amount │
│ - agent_wallet.Balance -= Amount │
│ 2. 创建 agent_withdrawal 记录 │
│ (Status=1, 待审核) │
│ 3. 创建 agent_withdrawal_tax 记录 │
│ (TaxStatus=1, 待扣税) │
│ 事务提交 │
└─────────────────────────────────────┘
管理员审核
审核通过Status=2
调用支付宝转账接口
转账成功/失败/处理中
┌─────────────────────────────────────┐
│ 事务开始 │
│ 1. 更新 agent_withdrawal.Status │
│ 2. 解冻并扣除余额(成功) │
│ - agent_wallet.FrozenBalance -= Amount │
│ - agent_wallet.WithdrawnAmount += Amount │
│ 3. 更新 agent_withdrawal_tax.TaxStatus │
│ 事务提交 │
└─────────────────────────────────────┘
```
---
## 九、关键算法说明
### 9.1 团队统计递归算法
```go
func getTeamMembers(agentId int64) []int64 {
teamMembers := []int64{agentId} // 包括自己
var collectChildren func(int64)
collectChildren = func(parentId int64) {
// 查找直接下级relation_type=1
relations := findDirectChildren(parentId)
for _, relation := range relations {
teamMembers = append(teamMembers, relation.ChildId)
collectChildren(relation.ChildId) // 递归
}
}
collectChildren(agentId)
return teamMembers
}
```
### 9.2 查找上级链算法
```go
// 查找直接上级
func findDirectParent(agentId int64) *Agent {
relation := findRelation(childId=agentId, relationType=1)
return findAgent(relation.ParentId)
}
// 查找钻石上级(向上递归)
func findDiamondParent(agentId int64) *Agent {
currentId := agentId
maxDepth := 100
depth := 0
for depth < maxDepth {
parent := findDirectParent(currentId)
if parent == nil {
return nil
}
if parent.Level == 3 { // 钻石
return parent
}
currentId = parent.Id
depth++
}
return nil
}
```
### 9.3 价格计算算法
```go
// 计算实际底价
func calculateActualBasePrice(agentLevel int64, basePrice float64) float64 {
levelBonus := getLevelBonus(agentLevel) // 6, 3, 0
return basePrice + float64(levelBonus)
}
// 计算提价成本
func calculatePriceCost(setPrice, priceThreshold, priceFeeRate float64) float64 {
if setPrice <= priceThreshold {
return 0
}
return (setPrice - priceThreshold) * priceFeeRate
}
// 计算代理收益
func calculateAgentProfit(setPrice, actualBasePrice, priceCost float64) float64 {
return setPrice - actualBasePrice - priceCost
}
```
---
## 十、注意事项和最佳实践
### 10.1 数据一致性
1. **事务使用**: 所有涉及多表更新的操作必须使用事务
- 订单处理agent_order, agent_commission, agent_wallet, agent_rebate
- 升级处理agent, agent_relation, agent_wallet, agent_upgrade
- 提现处理agent_withdrawal, agent_withdrawal_tax, agent_wallet
2. **乐观锁**: 所有更新操作使用 `version` 字段进行乐观锁控制
- 使用 `UpdateWithVersion` 方法
- 更新失败时重试或提示用户
3. **防重复处理**:
- 订单处理前检查 `agent_order.ProcessStatus`
- 升级处理前检查 `agent_upgrade.Status`
### 10.2 性能优化
1. **批量查询**: 避免N+1查询问题
- 列表查询时批量获取产品名称、代理信息等
2. **索引使用**:
- `agent_relation`: `idx_parent_relation`, `idx_child_relation`
- `agent_rebate`: `idx_order_rebate_type`
- `agent_order`: `idx_process_status`
3. **递归深度限制**:
- 查找上级链时设置最大深度如100层
- 防止无限循环
### 10.3 错误处理
1. **配置缺失**: 配置项不存在时使用默认值
- 税率默认6%
- 等级加成使用代码中的固定值
2. **关系异常**:
- 找不到上级时,返佣归平台
- 升级时找不到直接上级,跳过返佣
3. **余额不足**:
- 提现前验证余额
- 使用事务确保余额扣减的原子性
### 10.4 安全考虑
1. **数据加密**:
- 手机号、身份证号使用AES加密存储
- 推广链接标识加密传输
2. **权限控制**:
- 代理只能查看自己的数据
- 管理员需要认证和授权
3. **金额精度**:
- 使用 `decimal(10,2)` 类型存储金额
- 计算时注意浮点数精度问题
---
## 十一、常见问题解答
### 11.1 升级后关系脱离规则
**Q**: 为什么普通代理升级为黄金后要脱离直接上级关系?
**A**: 根据关系约束规则:
- 下级不能比上级等级高
- 同级不能作为上下级(除了普通代理)
- 如果直接上级是普通代理,升级后黄金等级高于普通,必须脱离
- 如果直接上级是黄金/钻石,升级后同级,也必须脱离
### 11.2 返佣分配规则
**Q**: 普通代理的6元等级加成如何分配
**A**: 按优先级分配:
1. 给直接上级根据上级等级钻石6元黄金3元普通2元
2. 剩余金额给钻石上级(如有)
3. 如果无钻石上级给黄金上级最多3元
4. 都没有,剩余归平台
### 11.3 团队归属
**Q**: 升级后团队归属如何变化?
**A**:
- 普通→黄金仍属于原团队通过team_leader_id指向原钻石代理
- 黄金→钻石独立成新团队team_leader_id指向自己
- 普通→钻石独立成新团队team_leader_id指向自己
### 11.4 税费计算
**Q**: 税费如何计算?
**A**:
1. 查询本月累计提现金额
2. 计算剩余免税额度 = 免税额度 - 本月累计
3. 如果本次提现 <= 剩余免税额度,免税
4. 否则,应税金额 = 本次提现 - 剩余免税额度
5. 税费 = 应税金额 × 税率
---
## 十二、后续优化建议
### 12.1 功能扩展
1. **多级返佣**: 支持更多层级的返佣分配
2. **业绩统计**: 增加团队业绩统计和排行榜
3. **消息通知**: 收益到账、升级成功等消息推送
### 12.2 性能优化
1. **缓存策略**:
- 系统配置缓存
- 团队统计数据缓存
- 代理信息缓存
2. **异步处理**:
- 订单处理异步化
- 团队统计异步计算
### 12.3 监控和日志
1. **关键操作日志**:
- 订单处理日志
- 升级操作日志
- 提现操作日志
2. **性能监控**:
- 订单处理耗时
- 数据库查询耗时
- 接口响应时间
---
## 附录
### A. 数据表索引说明
详见 `deploy/sql/agent_system_migration.sql` 文件中的索引定义。
### B. API接口详细定义
详见 `app/main/api/desc/front/agent.api``app/main/api/desc/admin/admin_agent.api` 文件。
### C. 代码文件清单
- **Service层**: `app/main/api/internal/service/agentService.go`
- **Logic层**: `app/main/api/internal/logic/agent/*.go`
- **Model层**: `app/main/model/agent*.go`
- **API定义**: `app/main/api/desc/front/agent.api`, `app/main/api/desc/admin/admin_agent.api`
---
**文档结束**