# 分销与邀请模块业务说明

> 本文档描述分销体系（合作商管理、佣金、提现）和邀请有礼活动的完整链路。
> 帮助开发人员快速理解"为什么这样设计"以及各环节的特殊处理方式。

---

## 一、分销体系概览

```
合作商 (Distributor)
    ├── 推荐用户 (DistributorReferral)
    │     └── 用户下单 → 产生佣金 (DistributorCommission)
    ├── 佣金余额管理
    │     ├── commissionBalance（可用余额）
    │     ├── frozenAmount（冻结金额）
    │     ├── totalCommission（累计佣金）
    │     └── totalWithdrawn（已提现总额）
    ├── 提现管理 (DistributorWithdrawal)
    └── 月度报表 (DistributorMonthlyReport)
```

---

## 二、合作商管理

### 2.1 Distributor 实体

| 字段 | 类型 | 说明 |
|------|------|------|
| id | Long | 雪花算法主键（`@JsonSerialize(using = ToStringSerializer.class)`） |
| code | String | 合作商编码（唯一标识） |
| name | String | 合作商名称 |
| phone | String | 联系电话 |
| status | Integer | 状态 |
| qrcodeContent | String | 推广二维码内容 |
| totalReferrals | Integer | 总推荐人数 |
| validReferrals | Integer | 有效推荐人数 |
| commissionBalance | BigDecimal | 可用佣金余额 |
| frozenAmount | BigDecimal | 冻结金额 |
| totalCommission | BigDecimal | 累计佣金总额 |
| totalWithdrawn | BigDecimal | 已提现总额 |
| remark | String | 备注 |
| creatorId | Long | 创建人ID |
| creatorName | String | 创建人姓名 |
| deleted | Integer | 逻辑删除 |

### 2.2 DistributorConfig（合作商配置）

| 字段 | 说明 |
|------|------|
| commissionRate | 佣金比例 |
| minWithdrawAmount | 最低提现金额 |
| commissionFreezeDays | 佣金冻结天数 |

---

## 三、推荐与佣金

### 3.1 DistributorReferral（推荐记录）

| 关键字段 | 说明 |
|---------|------|
| distributorId | 合作商ID |
| userId | 被推荐用户ID |
| status | 推荐状态 |
| sourceChannel | 来源渠道 |
| firstOrderAmount | 首单金额 |
| firstOrderTime | 首单时间 |

### 3.2 DistributorCommission（佣金记录）

| 关键字段 | 说明 |
|---------|------|
| distributorId | 合作商ID |
| orderId | 订单ID |
| referralId | 推荐记录ID |
| orderAmount | 订单金额 |
| commissionRate | 佣金比例 |
| commissionAmount | 佣金金额 |
| status | 状态：0-待结算 1-已结算 2-已冻结 3-已取消 |

### 3.3 佣金产生流程

```
被推荐用户下单 → 订单完成（payStatus=PAID）
    ↓
检查该用户是否有推荐记录（DistributorReferral）
    ↓
计算佣金 = 订单金额 × 佣金比例
    ↓
创建佣金记录（DistributorCommission，status=待结算）
    ↓
佣金冻结期过后 → 状态变为已结算
    ↓
更新合作商 commissionBalance
```

#### 为什么佣金有冻结期？

订单可能发生退款，如果在退款前佣金已结算并提现，会造成资金损失。冻结期（`commissionFreezeDays`）确保订单度过退款风险期后佣金才变为可用，这是分销业务的标准风控手段。

冻结期由 `DistributorConfig.commissionFreezeDays` 配置，不同合作商可设置不同天数。

---

## 四、提现管理

### 4.1 DistributorWithdrawal（提现记录）

| 关键字段 | 说明 |
|---------|------|
| distributorId | 合作商ID |
| amount | 提现金额 |
| status | 状态：0-待审核 1-已通过 2-已拒绝 3-已打款 |
| bankName | 收款银行 |
| bankAccount | 收款账号 |
| accountName | 收款人姓名 |
| reviewRemark | 审核备注 |
| reviewerId | 审核人ID |
| reviewTime | 审核时间 |

### 4.2 提现流程

```
合作商申请提现
    ↓
检查：余额 >= 提现金额 >= 最低提现额度
    ↓
冻结金额（frozenAmount += amount）
    ↓
创建提现记录（status=待审核）
    ↓
运营平台审核
    ├── 通过 → 打款 → 状态变为已打款
    │         → 扣减 commissionBalance 和 frozenAmount
    │         → 累加 totalWithdrawn
    └── 拒绝 → 解冻（frozenAmount -= amount）→ 状态变为已拒绝
```

#### 提现审核的合规原因

分销业务涉及资金流出，需要人工审核确认：
- 防止恶意刷单后提现
- 确认银行账户信息正确
- 满足财务合规要求

提现冻结机制确保审核期间这部分金额不会被二次提现。

---

## 五、月度报表

### 5.1 DistributorMonthlyReport

| 关键字段 | 说明 |
|---------|------|
| distributorId | 合作商ID |
| year / month | 年月 |
| totalOrders | 月度总订单数 |
| totalOrderAmount | 月度总订单金额 |
| totalCommission | 月度总佣金 |
| newReferrals | 月度新增推荐人数 |
| validReferrals | 月度有效推荐人数 |

---

## 六、小程序端分销接口

| 接口 | 控制器 | 说明 |
|------|--------|------|
| 获取合作商信息 | DistributorMpController | 合作商个人中心 |
| 获取推荐列表 | DistributorMpController | 推荐用户列表 |
| 获取佣金记录 | DistributorMpController | 佣金明细 |
| 申请提现 | DistributorMpController | 发起提现 |
| 获取提现记录 | DistributorMpController | 提现历史 |
| 生成推广码 | DistributorMpController | 推广二维码 |

---

## 七、邀请有礼体系

### 7.1 与分销的区别

| 维度 | 分销（Distributor） | 邀请有礼（InviteActivity） |
|------|---------------------|---------------------------|
| 角色 | 合作商（B端） | 普通用户（C端） |
| 奖励 | 佣金（金额） | 优惠券 |
| 管理 | 运营平台分配 | 用户自主参与 |
| 触发 | 被推荐人下单 | 被邀请人首单/绑定 |

#### 为什么邀请有礼发优惠券而非佣金？

分销面向B端合作商，发佣金合理且合规。邀请有礼面向C端普通用户，发佣金涉及个人税务和支付通道问题，而发优惠券：
- 无合规风险
- 促进复购（优惠券只能在平台消费）
- 实现成本低（无需对接提现通道）
- 双向奖励（邀请人和被邀请人各得一张券）更容易实施

### 7.2 邀请流程

```
邀请人分享邀请码/链接
    ↓
被邀请人扫码 → 绑定邀请关系（InviteRecord，status=待激活）
    ↓
被邀请人完成首单（满足 minOrderAmount 条件）
    ↓
InviteActivityServiceImpl 处理邀请激活
    ↓
更新 InviteRecord.status = 已激活/已奖励
    ↓
发放奖励：
    ├── 邀请人 → 发放 couponTemplateId 对应的优惠券
    └── 被邀请人 → 发放 inviteeCouponTemplateId 对应的优惠券（双向奖励时）
```

### 7.3 邀请限制

- 每日邀请上限：dailyLimit
- 活动期间总上限：totalLimit
- 首单金额门槛：requireFirstOrder + minOrderAmount
- 防重复：同一被邀请人只能被同一邀请人邀请一次

---

## 八、核心代码文件索引

| 文件 | 职责 |
|------|------|
| `haha-entity/.../Distributor.java` | 合作商实体 |
| `haha-entity/.../DistributorCommission.java` | 佣金记录实体 |
| `haha-entity/.../DistributorConfig.java` | 合作商配置实体 |
| `haha-entity/.../DistributorReferral.java` | 推荐记录实体 |
| `haha-entity/.../DistributorWithdrawal.java` | 提现记录实体 |
| `haha-entity/.../DistributorMonthlyReport.java` | 月度报表实体 |
| `haha-entity/.../InviteActivity.java` | 邀请活动实体 |
| `haha-entity/.../InviteRecord.java` | 邀请记录实体 |
| `haha-entity/.../InviteReward.java` | 邀请奖励实体 |
| `haha-service/.../DistributorServiceImpl.java` | 合作商服务 |
| `haha-service/.../DistributorCommissionServiceImpl.java` | 佣金服务 |
| `haha-service/.../DistributorWithdrawalServiceImpl.java` | 提现服务 |
| `haha-service/.../DistributorReportServiceImpl.java` | 报表服务 |
| `haha-service/.../InviteActivityServiceImpl.java` | 邀请活动服务（含激活逻辑） |
| `haha-admin/.../DistributorAdminController.java` | 运营平台-合作商API |
| `haha-miniapp/.../InviteController.java` | 小程序-邀请API |
