1.优化分红方式

This commit is contained in:
2026-05-29 12:01:00 +08:00
parent f286fcc56f
commit d8673fb2c5
13 changed files with 457 additions and 60 deletions

View File

@@ -169,13 +169,14 @@
| 渠道归属 | `channel_id` 表示该子代理属于哪个顶级渠道 |
| 邀请管理 | `invite_code` 自动生成且全局唯一,用于发展玩家并做归属绑定 |
| 角色标识 | `agent_role`(如 `agent_admin` / `sub_agent` / `staff` |
| 分红设置 | 在 **管理员管理** 维护:`parent_admin_id`上级代理)、`commission_share_rate`从上级分红抽取比例 %);顶级代理留空上级与比例 |
| 分红设置 | 在 **管理员管理** 维护:`parent_admin_id`非顶级角色组必填)、`commission_share_rate`顶级角色组=从渠道总佣金分得 %;子代理=从上级实得抽取 % |
| 开奖权限 | 不在数据层开放给渠道/子代理;开奖权限仅由超管 RBAC 控制 |
### 5.1 分红计算口径现行2026-05-29
- **渠道分红**:先按 `channel.agent_mode` 与已结算注单(`bet_order.status=2`)计算 **渠道总佣金**(非充值口径)
- **管理员分红**:总佣金进入渠道 **顶级代理** 后,`admin.parent_admin_id` 树递归拆分:
- **管理员分红**渠道总佣金先按顶级代理 `commission_share_rate` 划入,再`admin.parent_admin_id` 树递归拆分:
- 顶级实得 = 渠道本期总佣金 × 顶级 `commission_share_rate`%
- 子代理实得 = 上级本期实得 × `commission_share_rate`%
- 上级保留 = 上级实得 所有直属子代理实得之和
- 同一上级下子代理比例合计 **≤ 100%**
@@ -405,6 +406,7 @@
| V1.15 | 2026-04-20 | 热点写路径收口:`GameHotDataCoordinator` + `GameHotDataLock` + `GameHotDataWriteQueue` / `GameHotDataQueueConsumer`;文档与实现对齐(替代仅 `*Forget` 描述);移动端 `betPlace` 与后台钱包共用用户互斥锁及 `coin` 乐观更新 |
| V1.16 | 2026-04-23 | 渠道结算改为单阶段口径(仅超管结算,结算即按比例发放管理员钱包并记录操作人)与管理员钱包提现流程(`admin_wallet` / `admin_wallet_record` / `admin_withdraw_order`,渠道顶级组审核) |
| V1.17 | 2026-05-29 | 代理分红改为树形拆分:`admin.commission_share_rate` + `parent_admin_id`;配置迁移至管理员管理;渠道页移除 `channel_admin_share` 入口;管理员列表树形展示与下级可见范围 |
| V1.18 | 2026-05-29 | 顶级角色组(`admin_group.pid=0`)可配置渠道分红比例;表单禁用上级代理并增加说明 |
---
@@ -447,7 +449,7 @@
|---------|------|
| `admin.parent_admin_id` | 子代理上下级 |
| `admin.channel_id` | 所属渠道 |
| `admin.commission_share_rate` | 从上级本期分红抽取比例(%);顶级代理为空 |
| `admin.commission_share_rate` | 顶级角色组:从渠道本期总佣金分得比例(%);子代理:从上级实得抽取比例(% |
| `admin.invite_code` | 子代理邀请码,注册归属 |
| `admin.agent_role` | 角色类型(均无开奖权) |
| `admin_group.channel_id` | 角色组归属渠道;`NULL` 可为系统级(仅超管) |

View File

@@ -978,19 +978,29 @@ flowchart TD
| 字段 | 说明 |
|------|------|
| `channel_id` | 所属渠道(超管可选;非超管随角色组/当前账号) |
| `parent_admin_id` | 上级代理;留空表示渠道 **顶级代理** |
| `commission_share_rate` | 从上级本期分红抽取的比例0100有上级时必填 |
| `group_arr` | 角色组(单选,仅权限) |
| `parent_admin_id` | 上级代理;**顶级角色组**`admin_group.pid=0`)时留空且不可选 |
| `commission_share_rate` | **顶级角色组**从渠道本期总佣金分得的比例0100必填**子代理**:从上级本期实得抽取的比例,有上级时必填 |
| `group_arr` | 角色组(单选,仅权限;是否顶级由 `pid=0` 判定 |
### 10.3 校验与提示
**顶级角色组**
- 上级代理字段禁用,并提示「无需绑定上级代理」
- 须填写分红比例;实得 = **渠道本期总佣金 × 本项比例**
- 同一 `channel_id` 下顶级代理比例 **合计 ≤ 100%**
- 表单调用 **GET** `/admin/auth.Admin/commissionShareRemainder?is_top_level=1&channel_id=&exclude_id=`
- 角色组联动:**GET** `/admin/auth.Admin/groupMeta?group_id=`
**子代理**
- 同一 `parent_admin_id` 下,启用子代理的 `commission_share_rate` **合计 ≤ 100%**
- 表单调用 **GET** `/admin/auth.Admin/commissionShareRemainder?parent_admin_id=&exclude_id=` 展示剩余可分配比例
- 合计 100% 时提示:上级在本层将无分红留存
### 10.4 结算拆分(与渠道结算联动)
- 渠道结算得到总佣金后,由 `AdminCommissionDistributionService` 顶级代理递归拆分
- 渠道结算得到总佣金后,由 `AdminCommissionDistributionService` 先按顶级代理 `commission_share_rate` 划入,再向下递归拆分
- 每个管理员实得写入 `agent_commission_record`**即时入账** `admin_wallet`
- 须存在至少一名渠道顶级代理,否则结算失败

View File

@@ -871,19 +871,29 @@ flowchart TD
| Field | Description |
|-------|-------------|
| `channel_id` | Channel (super-admin selectable; others follow role/account) |
| `parent_admin_id` | Parent agent; empty = channel **root agent** |
| `commission_share_rate` | Share taken from parents period commission (0100); required when parent set |
| `group_arr` | Role group (single select, permissions only) |
| `parent_admin_id` | Parent agent; **top-level role group** (`admin_group.pid=0`): empty and disabled |
| `commission_share_rate` | **Top-level role group**: share of channel period total (0100), required; **sub-agent**: share from parents net amount, required when parent set |
| `group_arr` | Role group (single select, permissions; top-level when `pid=0`) |
### 10.3 Validation & Hints
**Top-level role group:**
- Parent agent field disabled with hint “no parent required”
- Share rate required; amount = **channel period total × this rate**
- Under same `channel_id`, top-level agents rates **≤ 100% total**
- **GET** `/admin/auth.Admin/commissionShareRemainder?is_top_level=1&channel_id=&exclude_id=`
- Role group linkage: **GET** `/admin/auth.Admin/groupMeta?group_id=`
**Sub-agent:**
- Under same `parent_admin_id`, sum of enabled childrens `commission_share_rate` **≤ 100%**
- Form calls **GET** `/admin/auth.Admin/commissionShareRemainder?parent_admin_id=&exclude_id=` for remaining allocatable %
- **GET** `/admin/auth.Admin/commissionShareRemainder?parent_admin_id=&exclude_id=` for remaining allocatable %
- At 100% total: hint that parent retains no share at this level
### 10.4 Settlement Split (Channel Settlement Integration)
- After channel settlement total commission, **`AdminCommissionDistributionService`** splits recursively from root agent
- After channel settlement total commission, **`AdminCommissionDistributionService`** allocates to top-level agents by `commission_share_rate`, then splits recursively downline
- Each admins net amount → `agent_commission_record` and **immediate credit** to `admin_wallet`
- At least one channel root agent required; else settlement fails

View File

@@ -22,10 +22,12 @@ Commission is calculated in two steps:
- **Do not** configure flat channel-wide shares on the channel page (`channel_admin_share` is deprecated in UI; table may remain for history)
- Maintain the agent tree in **Administrator Management** (`/admin/auth/admin`):
- `parent_admin_id`: parent agent (empty for top-level)
- `commission_share_rate`: percentage taken from **parents commission for this period** (sub-agents only)
- `parent_admin_id`: parent agent (**required for nontop-level role groups**; **disabled and empty when role group `admin_group.pid = 0`**)
- `commission_share_rate`:
- **Top-level role group**: share (%) of **channel period total commission**; amount = channel period total × this rate
- **Sub-agent**: share (%) taken from **parents commission for this period**
- At settlement, `AdminCommissionDistributionService` splits recursively:
1. Channel total commission goes to **top-level agent(s)** (`parent_admin_id` is null)
1. Channel total commission is allocated to **top-level agents** by their `commission_share_rate` (sum per channel ≤ 100%; legacy equal split if rates missing)
2. Each agent allocates to direct children by `commission_share_rate` from **their own received amount**
3. **Parent keeps** = received amount sum allocated to children
@@ -51,12 +53,23 @@ If a sub-agent has further downline, the same rules apply on **their received am
| Visibility | Admin list | Nonsuper admin sees **self + all downline** only |
| Settlement | `/admin/channel` manual / cron | **Super admin only**; credits `admin_wallet` on settle |
### 3.1 Sub-agent share validation
### 3.1 Share rate validation
- Under the same `parent_admin_id`, enabled sub-agents `commission_share_rate` **must not exceed 100% in total**
- Form shows **remaining allocatable rate** when creating/editing sub-agents
- If total is 100%, parent keeps **no commission** at this level
- Top-level agents (no parent) **do not** set `commission_share_rate`
**Top-level role group** (`admin_group.pid = 0`):
- No parent agent required or allowed
- `commission_share_rate` is required: share of **channel period total commission**
- Under the same `channel_id`, top-level agents rates **must not exceed 100% in total**
- Form shows remaining allocatable share on the channel
**Sub-agent** (nontop-level role group):
- `parent_admin_id` required
- `commission_share_rate` is share from **parents net amount this period**
- Under the same `parent_admin_id`, enabled sub-agents rates **must not exceed 100% in total**
- Form shows remaining allocatable share under the parent
If a level totals 100%, the parent at that level keeps **no commission**.
### 3.2 Role groups
@@ -96,7 +109,7 @@ If a sub-agent has further downline, the same rules apply on **their received am
| `channel.agent_mode` / `turnover_share_rate` / `affiliate_*` | Channel commission calculation |
| `admin.parent_admin_id` | Parent agent |
| `admin.channel_id` | Channel |
| `admin.commission_share_rate` | Share from parent (%); null for top-level |
| `admin.commission_share_rate` | Top-level role group: share of channel period total (%); sub-agent: share from parent (%) |
| `agent_settlement_period` | Settlement period snapshot |
| `agent_commission_record` | Paid commission per admin |
| `admin_wallet` / `admin_wallet_record` | Admin wallet & ledger |
@@ -124,3 +137,4 @@ If a sub-agent has further downline, the same rules apply on **their received am
| 2026-04-18 | `channel_admin_share` flat split; removed `admin`/`admin_group.commission_rate` |
| 2026-04-23 | Settle-and-pay to admin wallet; `admin_wallet` system |
| 2026-05-29 | **Agent tree commission** in Administrator Management; removed channel share UI; tree list & downline visibility |
| 2026-05-29 | Top-level role groups (`pid=0`) require channel share rate; parent agent disabled in form |

View File

@@ -22,10 +22,12 @@
- **不再**在渠道管理页维护「渠道内管理员分配比例」(`channel_admin_share` 已废弃于 UI历史表可保留
-**管理员管理**`/admin/auth/admin`)维护代理树:
- `parent_admin_id`:上级代理(顶级留空
- `commission_share_rate`**上级本期分红** 中抽取的比例(%),仅子代理需要填写
- `parent_admin_id`:上级代理(**非顶级角色组**必填;**顶级角色组** `admin_group.pid=0` 时留空且不可选
- `commission_share_rate`
- **顶级角色组**:从 **渠道本期总佣金** 中分得的比例(%);实得 = 渠道本期总佣金 × 本项比例
- **子代理**:从 **上级本期分红** 中抽取的比例(%
- 结算时由 `AdminCommissionDistributionService` 递归拆分:
1. 渠道总佣金先进入该渠道 **顶级代理**`parent_admin_id` 为空
1. 渠道总佣金按各 **顶级代理**`commission_share_rate` 划入(同渠道合计 ≤ 100%;未配置比例时历史数据均分兜底
2. 每个代理按直属子代理的 `commission_share_rate`,从 **自己拿到的金额** 中划出子代理份额
3. **上级保留** = 自己拿到的金额 已分给所有子代理的金额
@@ -51,12 +53,23 @@
| 数据可见范围 | 管理员列表 | 非超管仅见 **本人 + 全部下级**,不见其他代理线 |
| 结算执行 | `/admin/channel` 手动结算 / 定时任务 | **仅超管**可结算;结算即发放至 `admin_wallet` |
### 3.1 子代理分红比例校验
### 3.1 分红比例校验
- 同一 `parent_admin_id` 下,所有启用子代理的 `commission_share_rate` **合计不得超过 100%**
- 创建/编辑子代理时,表单会提示 **当前剩余可分配比例**
- 若合计为 100%,上级在本层 **不再保留分红**
- 顶级代理(无上级)**不需要**填写 `commission_share_rate`
**顶级角色组**`admin_group.pid = 0`
- 无需、不可绑定上级代理
- 填写 `commission_share_rate`,表示从 **渠道本期总佣金** 中分得的比例
- 同一 `channel_id` 下,所有无上级顶级代理的比例 **合计 ≤ 100%**
- 表单提示同渠道剩余可分配比例
**子代理**(非顶级角色组):
- 须绑定 `parent_admin_id`
- `commission_share_rate` 表示从 **上级本期实得** 中抽取的比例
- 同一 `parent_admin_id` 下,启用子代理比例 **合计 ≤ 100%**
- 表单提示同上级剩余可分配比例
若某层合计为 100%,该层上级 **不再保留分红**
### 3.2 角色组的作用
@@ -96,7 +109,7 @@
| `channel.agent_mode` / `turnover_share_rate` / `affiliate_*` | 渠道总佣金计算参数 |
| `admin.parent_admin_id` | 上级代理 |
| `admin.channel_id` | 所属渠道 |
| `admin.commission_share_rate` | 从上级分红抽取比例(%,顶级为空 |
| `admin.commission_share_rate` | 顶级角色组:从渠道本期总佣金分得比例(%);子代理:从上级分红抽取比例(% |
| `agent_settlement_period` | 结算周期与大盘快照 |
| `agent_commission_record` | 各管理员本期实发佣金 |
| `admin_wallet` / `admin_wallet_record` | 管理员钱包与入账流水 |
@@ -125,3 +138,4 @@
| 2026-04-23 | 超管结算即发放至管理员钱包;新增 `admin_wallet` 体系 |
| 2026-05-29 | **改为代理树形分红**:配置迁移至管理员管理 `commission_share_rate` + `parent_admin_id`;移除渠道页分配比例入口;管理员列表树形展示与下级可见范围 |
| 2026-05-29 | 新增英文文档 `docs/en/commission-share-guide.md`;后台切换 `lang=en` 时文档页自动加载英文版 |
| 2026-05-29 | **顶级角色组可配置渠道分红比例**`pid=0` 时禁用上级代理并必填 `commission_share_rate`;结算按顶级比例划入后再向下拆分 |

View File

@@ -76,7 +76,7 @@
* **提现手续费收益报表**:单独统计系统抽取的 0.5% 手续费总收入。
### 3.5 🏢 代理中枢与佣金结算系统 (Agent System)
* **创建总代/子代账号**:在 **管理员管理**`/admin/auth/admin`)维护代理树:`parent_admin_id``commission_share_rate`(从上级分红抽取 %)、`channel_id`、邀请码。
* **创建总代/子代账号**:在 **管理员管理**`/admin/auth/admin`)维护代理树:`parent_admin_id``commission_share_rate`顶级角色组从渠道总佣金分得 %,子代理从上级实得抽取 %)、`channel_id`、邀请码。
* **代理树状图 (Tree View)**:管理员列表以树形展示;非超管仅见本人及全部下级。
* **渠道佣金结算**(仅超管):
* 按渠道 `agent_mode` 与已结算注单计算渠道总佣金(非充值口径)。