Files
ycc-proxy-server/新代理系统完整文档.md

1807 lines
97 KiB
Markdown
Raw Normal View History

2025-11-27 13:09:54 +08:00
# 新代理系统完整文档
## 文档说明
本文档详细记录了新代理系统的完整链路、业务逻辑、数据表结构、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`
---
**文档结束**