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