style: 优化合伙股东文案为进阶身份与档案管理

这个提交包含在:
chen
2026-09-17 15:23:30 +08:00
父节点 4ae2b1688c
当前提交 06e98c57e0
共有 19 个文件被更改,包括 177 次插入 和 157 次删除

查看文件

@@ -78,7 +78,7 @@ class PartnerRewardService
Wallet::change($reward->user_id, 'commission', -$reward->amount, 'reward_back', [
'partner_reward_id' => $reward->id,
'order_id' => $orderId,
], '合伙股东收益退回');
], '收益中心奖励退回');
AgentModel::where('user_id', $reward->user_id)->setDec('total_income', $reward->amount);
}
if ($reward->reward_type === 'push3' && $reward->user_id > 0) {

查看文件

@@ -52,7 +52,7 @@ class Config extends Common
'status' => $this->auth->check('shopro/config/commission')
],
[
'label' => '合伙股东规则',
'label' => '收益中心规则',
'name' => 'shopro/config/partner',
'status' => $this->auth->check('shopro/config/commission')
],
@@ -187,7 +187,7 @@ class Config extends Common
}
/**
* 合伙股东规则
* 收益中心规则
*/
public function partner()
{

查看文件

@@ -257,10 +257,15 @@
<el-button class="ml-2" type="primary" link @click="onChangeParentUser">更换
</el-button>
</el-form-item>
<<<<<<< Updated upstream
<el-form-item v-if="state.data.partner_mode" label="佣金规则:">
<div class="tip" style="color: var(--sa-subfont); line-height: 1.4;">
已切换为收益中心固定金额规则,旧百分比不再生效。
</div>
=======
<el-form-item v-if="state.data.partner_mode" label="佣金比例:">
<div class="tip">已切换为收益中心固定金额,旧百分比不再生效。</div>
>>>>>>> Stashed changes
</el-form-item>
<el-form-item v-else label="佣金比例:">
<div class="commission-item">

查看文件

@@ -71,7 +71,7 @@
<el-scrollbar height="100%">
<el-alert class="mb-4" type="warning">
<template #title>
等级 1 固定为品酒师,2–7 对应创客 V1–V6。合伙股东模式下百分比佣金不再生效,级差金额请到「分销设置 → 合伙股东」修改。
等级 1 固定为品酒师,2–7 对应创客 V1–V6。收益中心模式下百分比佣金不再生效,级差金额请到「分销设置 → 收益中心规则」修改。
</template>
</el-alert>
<el-form :model="form.model" :rules="form.rules" ref="formRef" label-width="150px">

查看文件

@@ -7,7 +7,7 @@
<div class="sa-title-left">
<div class="left-name">身份等级</div>
<div style="font-size:12px;color:#999;margin-top:4px">
等级 1 固定为品酒师;2–7 对应创客 V1–V6。百分比佣金在合伙股东模式下不使用。
等级 1 固定为品酒师;2–7 对应创客 V1–V6。百分比佣金在收益中心模式下不使用。
</div>
</div>
<div class="sa-title-right">

查看文件

@@ -864,13 +864,13 @@
</el-form-item>
</template>
<!-- 合伙股东 -->
<!-- 收益中心规则 -->
<template v-if="state.tabActive == 'shopro/config/partner'">
<el-alert class="mb-4" type="warning" :closable="false"
title="规则已保存后仅对之后的新订单生效,已入账流水不追溯。不要把「分销层级」改成 0,否则用户端收益中心打不开。">
</el-alert>
<div class="sa-title is-line">总控</div>
<el-form-item label="启用合伙股东结算">
<el-form-item label="启用收益中心结算">
<el-radio-group v-model="form.model.partner_enable">
<el-radio :label="1">开启</el-radio>
<el-radio :label="0">关闭</el-radio>

查看文件

@@ -90,7 +90,7 @@
.dashboard-index .font-bold { font-weight: 600; }
.dashboard-index .cursor-pointer { cursor: pointer; }
/* 合伙股东与角色身份网络卡片 */
/* 收益中心网络与角色身份矩阵卡片 */
.dashboard-index .network-card {
padding: 14px 16px;
min-height: 98px;
@@ -547,13 +547,13 @@
</div>
</el-col>
<!-- 创客骨干梯队 (合伙股东) -->
<!-- 创客骨干梯队 -->
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
<div class="network-card card">
<div class="sa-flex sa-row-between mb-2">
<div class="sa-flex">
<span class="network-badge bg-cyan mr-2">创</span>
<span class="font-bold text-dark" style="font-size: 14px;">创客骨干 (V1~V6 · 合伙股东)</span>
<span class="font-bold text-dark" style="font-size: 14px;">创客骨干梯队 (V1~V6)</span>
</div>
<span class="text-cyan font-bold cursor-pointer" style="font-size: 18px;" @click="onOpenAgent('')">
{{ state.partner.maker_count }} <span style="font-size: 12px; color: var(--sa-subfont);">人</span>
@@ -614,7 +614,7 @@
</span>
</div>
<div class="sa-flex" style="margin-top: 4px;">
<el-button size="small" type="primary" plain @click="onOpenAgent('')">合伙股东档案 →</el-button>
<el-button size="small" type="primary" plain @click="onOpenAgent('')">成员档案 →</el-button>
<el-button size="small" type="success" plain @click="onOpenReward('')">全部收益流水 →</el-button>
</div>
</div>
@@ -681,7 +681,7 @@
<el-table-column label="30天自购活跃考核" min-width="170">
<template #header>
<span style="font-size: 13px;">30天自购活跃考核</span>
<el-tooltip content="仅具备合伙股东身份(创客V1~V6、酒道馆、区县代理)需按月履行自购以维持分润资格;普通会员及品酒师属于基础会员,免自购考核" placement="top">
<el-tooltip content="进阶角色(创客V1~V6、酒道馆、区县代理、合伙股东)需按月履行自购以维持分润资格;普通会员及品酒师属于基础会员,免自购考核" placement="top">
<i class="el-icon-info text-muted" style="margin-left: 2px; cursor: pointer;"></i>
</el-tooltip>
</template>
@@ -710,7 +710,7 @@
</el-col>
</el-row>
<!-- ================= 2.3 商城运营全貌 · 购买转化、合伙股东活跃与库存安全 ================= -->
<!-- ================= 2.3 商城运营全貌 · 购买转化、进阶成员活跃与库存安全 ================= -->
<el-row :gutter="16">
<!-- 左侧:会员购买转化与复购分析 -->
<el-col :xs="24" :sm="24" :md="24" :lg="8" :xl="8">
@@ -758,17 +758,17 @@
</div>
</el-col>
<!-- 中间:合伙股东 30 天自购活跃与续期监控 -->
<!-- 中间:进阶角色 30 天自购活跃与续期监控 -->
<el-col :xs="24" :sm="24" :md="24" :lg="8" :xl="8">
<div class="coo-panel-card card">
<div class="sa-flex sa-row-between mb-3">
<div class="sa-flex">
<span class="font-bold text-dark" style="font-size: 14px;">合伙股东 30天自购活跃与续期监控</span>
<el-tooltip content="合伙股东(创客/酒道馆/区县)是会员专属进阶身份,享有团队分润,需保持 30 天自购活跃;普通会员与品酒师属于基础会员,免于考核" placement="top">
<span class="font-bold text-dark" style="font-size: 14px;">进阶角色 30天自购活跃与续期监控</span>
<el-tooltip content="进阶角色(创客/酒道馆/区县/合伙股东)享有团队分润,需保持 30 天自购活跃;普通会员与品酒师属于基础会员,免于考核" placement="top">
<i class="el-icon-info text-muted" style="margin-left: 4px; cursor: pointer;"></i>
</el-tooltip>
</div>
<span class="cursor-pointer text-primary" style="font-size: 12px;" @click="onOpenAgent('')">合伙股东档案 →</span>
<span class="cursor-pointer text-primary" style="font-size: 12px;" @click="onOpenAgent('')">成员档案 →</span>
</div>
<!-- 4状态指标标签 -->
@@ -806,7 +806,7 @@
<!-- 7天临界断档名单列表(若有则提醒续期,若无则展示待续期列表) -->
<div v-if="state.operation.warning_partners > 0">
<div class="warning-alert-row mb-2 sa-flex sa-row-between">
<span>⚠️ <strong>到期提醒:</strong>以下合伙股东自购即将到期(7天内)</span>
<span>⚠️ <strong>到期提醒:</strong>以下进阶成员自购即将到期(7天内)</span>
<span style="font-weight: bold;">{{ state.operation.warning_partners }} 人临期</span>
</div>
<div style="max-height: 120px; overflow-y: auto;">
@@ -828,10 +828,10 @@
<div v-else>
<div class="sa-flex sa-row-between" style="background: #f6ffed; border: 1px solid #b7eb8f; padding: 8px 12px; border-radius: 6px; font-size: 12px; color: #389e0d; margin-bottom: 8px;">
<span>🛡️ 合伙股东状态良好,暂无 7 天内即将到期人员</span>
<span>🛡️ 各进阶成员状态良好,暂无 7 天内即将到期人员</span>
<span>全部合格</span>
</div>
<div style="font-size: 11px; color: var(--sa-subfont); margin-bottom: 4px;">已超期合伙股东 (自购 1 单即可恢复分润资格):</div>
<div style="font-size: 11px; color: var(--sa-subfont); margin-bottom: 4px;">已超期成员 (自购 1 单即可恢复分润资格):</div>
<div style="max-height: 100px; overflow-y: auto;">
<div class="sa-flex sa-row-between mb-1 pb-1" v-for="pUser in state.operation.pending_renew_list.slice(0, 3)" :key="pUser.user_id" style="border-bottom: 1px dashed #f0f2f5; font-size: 12px;">
<div class="sa-flex">
@@ -842,7 +842,7 @@
<el-tag size="mini" type="info" effect="plain">{{ pUser.overdue_text }}</el-tag>
</div>
<div v-if="!state.operation.pending_renew_list || state.operation.pending_renew_list.length === 0" class="text-muted" style="font-size: 11px; text-align: center; padding: 8px 0;">
暂无已超期合伙股东
暂无已超期成员
</div>
</div>
</div>
@@ -872,7 +872,7 @@
</div>
</el-col>
<el-col :span="12" class="mb-2">
<div style="font-size: 11px; color: var(--sa-subfont);">合伙股东自购合格率</div>
<div style="font-size: 11px; color: var(--sa-subfont);">自购合格达标率</div>
<div class="sa-flex sa-row-between mt-1">
<strong class="text-dark" style="font-size: 14px;">{{ state.partner?.active_rate || 0 }}%</strong>
<el-tag size="mini" :type="state.operation?.risk_indicators?.partner_active_rate?.status || 'success'">
@@ -999,14 +999,14 @@
{/if}
{if $auth->check('shopro/dashboard/ranking')}
<!-- ================= 4. 合伙股东收益排行 & 电商运营与风控监控 ================= -->
<!-- ================= 4. 收益中心收益排行 & 电商运营与风控监控 ================= -->
<el-row :gutter="16">
<!-- 左侧:合伙股东收益排行 TOP 5 -->
<!-- 左侧:收益排行 TOP 5 -->
<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
<div class="partner-ranking-card card">
<div class="sa-flex sa-row-between mb-2">
<div class="card-header-title" style="margin-bottom: 0;">
<span>合伙股东收益排行榜 (TOP 5)</span>
<span>收益排行榜 (TOP 5)</span>
</div>
<span class="cursor-pointer text-primary" style="font-size: 12px;" @click="onOpenReward('')">查看全部 →</span>
</div>

查看文件

@@ -880,7 +880,7 @@
<div class="partner-split-content order-content">
<div class="title sa-flex sa-row-between">
<div class="sa-flex">
<span>合伙股东分成明细</span>
<span>收益中心分成明细</span>
<el-tag v-if="state.detail.partner_split && state.detail.partner_split.has_data" size="small" type="success" style="margin-left: 10px;">有分成记录</el-tag>
<el-tag v-else size="small" type="info" style="margin-left: 10px;">暂无分成记录</el-tag>
</div>
@@ -975,7 +975,7 @@
</el-table-column>
</el-table>
<div v-else style="padding:16px 0;color:var(--sa-subfont);font-size:13px;text-align:center;">
暂无合伙股东分成记录(未产生分成、未支付或尚未日结)
暂无收益分成记录(未产生分成、未支付或尚未日结)
</div>
</div>
<div class="goods-content">

查看文件

@@ -1,6 +1,6 @@
# 收益中心前后端接口约定(身份标签与收益资产)
> 注:本模块为「收益中心」,「合伙股东」为进阶会员的身份标签(创客/酒道馆/区县)。
> 注:本模块为「收益中心」。「合伙股东」为独立角色身份之一,创客、酒道馆、区县代理各属于独立角色身份,绝不隶属于合伙股东。
## profile `GET user.user/profile` 增补字段
@@ -18,9 +18,14 @@
}
```
identities 取值:`taster` | `maker` | `venue` | `county`
is_partner = 含 maker 或 venue 或 county
identity_text 例:`品酒师` / `合伙股东 · 创客V5 · 酒道馆`
identities 取值:`taster` | `maker` | `venue` | `county` | `partner`
各身份平行独立:
- 品酒师:`taster`
- 创客:`maker`(对应等级如创客V1~V6)
- 酒道馆:`venue`
- 区县代理:`county`
- 合伙股东:`partner`(独立角色身份)
identity_text 拼接示例:`品酒师` / `创客V5 · 酒道馆` / `合伙股东 · 区县代理`
## agent `GET commission.agent` 在原 agent 上增补

查看文件

@@ -6,19 +6,20 @@
### 1. 角色定义与身份演进体系
系统包含 **4 个业务层级角色** 与 **1 个核心荣誉身份标识**。
系统包含 **5 个独立平行的业务角色身份**,各个角色身份权责清晰,**严禁将「合伙股东」作为上位统称**(创客、酒道馆、区县代理均为独立角色身份,绝不隶属于合伙股东):
| 角色/标识 | 角色性质 | 准入/获得条件 | 互斥与共存规则 | 核心定位 |
| 角色身份名称 | 身份性质 | 准入/获得条件 | 互斥与共存规则 | 核心定位与业务权益 |
| :--- | :--- | :--- | :--- | :--- |
| **品酒师** | 基础会员角色 | 所有用户注册默认即为品酒师(系统分销等级 `level = 1`)。<br>*(注:若启用考核门槛,为直推 3 单或伞下 1 人升级)* | 与创客**互斥**(升级创客后自动脱离品酒师身份) | 基础消费与推广会员 |
| **创客** | 进阶层级角色 | 由品酒师升级而来,细分为 **V1 ~ V6** 六个等级(对应系统 `level = 2 ~ 7`),后台可灵活设置升级条件与权益 | 与品酒师**互斥**;可与酒道馆、区县代理**叠加共存** | 团队核心骨干 |
| **酒道馆** | 特殊业务角色 | 后台独立开通/授权(系统标识 `is_venue = 1`) | 独立身份标识,可与创客、区县代理**叠加共存** | 实体/线下业务枢纽 |
| **区县代理** | 区域代理角色 | 后台独立开通/绑定特定行政区划(系统标识 `is_county = 1`) | 独立身份标识,可与创客、酒道馆**叠加共存** | 区域渠道领头人 |
| **合伙股东** | **专属身份标识** | 会员只要满足:**创客 (V1~V6)**、**酒道馆**、**区县代理** 中的任意一个或多个,系统自动点亮「合伙股东」复合身份标识 | 纯荣誉与身份标识,非单一职级;品酒师不可获得此标识 | 高阶合伙人象征 |
| **品酒师** | 基础会员身份 | 所有用户注册默认即为品酒师(系统分销等级 `level = 1`)。<br>*(注:若启用考核门槛,为直推 3 单或伞下 1 人升级)* | 与创客**互斥**(升级创客后自动覆盖品酒师身份) | **基础消费与推广**:推三返一(398/400/600 循环返现)、每日 GMV 1:1 马豆分红、1.5 倍兑换券释放 |
| **创客** | 进阶层级身份 | 由品酒师升级而来,细分为 **V1 ~ V6** 六个等级(对应系统 `level = 2 ~ 7`),后台可灵活设置升级门槛 | 与品酒师**互斥**;可与酒道馆、区县代理、合伙股东**独立叠加** | **团队核心骨干**:继承品酒师权益,享创客极差奖(20~120元阶梯)、同级平级奖(10%)、被超越奖(5%) |
| **酒道馆** | 实体枢纽身份 | 后台独立审核开通/授权(系统标识 `is_venue = 1`) | 独立身份,可与创客、区县代理、合伙股东**独立叠加** | **实体/线下业务枢纽**:享团队订单收益(50元/单)、酒道馆平级奖(10%)、全网每单 100 元平台均分奖池 |
| **区县代理** | 区域代理身份 | 后台独立开通/绑定特定行政区划(系统标识 `is_county = 1`) | 独立身份,可与创客、酒道馆、合伙股东**独立叠加** | **区域渠道领头人**:享团队拆分奖(独享100元或与馆各50元)、区县平级奖(10%)、全网每单 50 元平台均分奖池 |
| **合伙股东** | **独立高阶角色身份** | 独立身份,按股东准入标准/后台独立开通授信 | **独立角色身份**,不是创客/馆/县的统称;可与其他身份独立并存 | **资本与顶层合伙身份**:享有股东专属权益与平台顶层红利 |
> **身份互斥与共存规则总结**:
> 1. **品酒师 ↔ 创客 严格互斥**:用户等级由低到高演进,升级创客即覆盖品酒师等级,但创客**全额继承品酒师所有权益**。
> 2. **多重身份可叠加**:同一个会员可以同时兼具「创客 V5 + 酒道馆 + 区县代理」,且系统合并展示为:「合伙股东 · 创客V5 · 酒道馆 · 区县代理」。
> **身份关系与规范说明**:
> 1. **严禁概念误导**:**「合伙股东」只是一个独立的角色身份**,创客、酒道馆、区县代理各有其独立的业务逻辑与结算规则,**绝不是所有角色都在合伙股东下**!
> 2. **品酒师 ↔ 创客 严格互斥**:用户等级由低到高演进,升级创客即覆盖品酒师等级,创客全额继承品酒师基础权益。
> 3. **多重身份独立叠加**:同一个会员若同时具备多种资格,系统直接按实际身份平行展示(例如:`创客V5 · 酒道馆` 或 `合伙股东 · 区县代理`),严禁无故给所有创客、馆、县强制前缀“合伙股东”。
---
@@ -173,8 +174,8 @@
- **实现机制**:
- 复用了 `fa_shopro_commission_level`,`level = 1` 为品酒师,`level = 2~7` 分别映射为创客 V1~V6。因为同一个用户在表中只有一行 `level` 字段,天然保证了**品酒师与创客绝不可能同时存在**。
- 酒道馆(`is_venue`)与区县代理(`is_county`)作为布尔标记加在 `fa_shopro_commission_agent` 表中,支持多选叠加。
- `IdentityService::build()` 动态判断:若 `level >= 2` 或 `is_venue=1` 或 `is_county=1`,则自动赋予 `is_partner = true`,并输出拼接文本(如 `合伙股东 · 创客V5 · 酒道馆`)。
- **完善度**:与业务需求完全吻合。
- **重要纠偏与规范**:**「合伙股东」是独立角色身份**,不是创客/馆/县的统称上级。历史代码中若将创客、酒道馆、区县强行赋予 `is_partner=true` 并前缀“合伙股东”属于概念误导,业务规范已澄清:创客即创客、酒道馆即酒道馆、区县即区县、合伙股东即合伙股东,各身份平行独立。
- **完善度**:已纠正概念定义,业务权责边界已明确。
#### ② 品酒师「推三返一」
- **代码位置**:[`Push3Reward.php`](file:///Users/chen/Desktop/xbiuld/henglianshutong/addons/shopro/service/partner/Push3Reward.php)

查看文件

@@ -8,9 +8,10 @@
> [!IMPORTANT]
> ### 核心概念澄清(避免误导)
> 1. **系统定位**:本模块在管理后台与用户端统一命名为**「收益中心」**(原「分销中心」)。
> 2. **「合伙股东」只是会员的身份标签,不是系统/模块名称**:
> - **「品酒师」**:注册即是的基础分销会员身份标签(对应分销商 `level = 1`)。
> - **「合伙股东」**:进阶会员身份标签。当会员升级为创客(`level >= 2`,创客 V1–V6)、被后台开通酒道馆(`is_venue = 1`)或开通区县代理(`is_county = 1`)时,获得「合伙股东」身份标签(例如:“合伙股东 · 创客V5 · 酒道馆”)。
> 2. **「合伙股东」只是一个独立的角色身份,不是所有角色都在合伙股东下(切勿误导)**:
> - 系统包含 **品酒师**、**创客 (V1–V6)**、**酒道馆**、**区县代理**、**合伙股东** 等独立平行的角色身份。
> - **「合伙股东」本身仅是一个独立的高阶角色身份**,创客、酒道馆、区县代理各司其职,**绝不隶属于合伙股东**。
> - 各角色身份平行独立,严禁将所有进阶角色归属于合伙股东名下,更不可强行加挂“合伙股东·创客”等混淆关系的命名。
> 3. 后台所有菜单、页面表头及用户端导航,均统一按功能命名(如「收益中心」、「成员档案」、「收益流水」),切勿将整套系统误叫为“合伙股东”。
---
@@ -21,7 +22,7 @@
| 角色 | 他要完成的事 |
|---|---|
| 运营 | 开通酒道馆/区县、改创客等级、查一笔订单钱分给了谁 |
| 运营 | 开通酒道馆/区县/合伙股东、改创客等级、查一笔订单钱分给了谁 |
| 财务 | 按日对账:GMV、发放合计、均分、马豆、兑换券;导出 |
| 客服 | 用户说「我没收到钱」时,3 分钟内看到原因(不活跃 / 无上级 / 已退款) |
| 超管 | 改规则数字(级差 20、均分 100),改完只影响新单 |
@@ -31,8 +32,9 @@
| 身份 | 他打开 App 要立刻看到 |
|---|---|
| 品酒师 | 我是品酒师;直推满 3 单返一圈钱;我的兑换券还剩多少天 |
| 创客 V1–V6 | 合伙股东徽章 + 等级;极差/平级进佣金 |
| 酒道馆 / 区县 | 多一枚身份标;团队奖和平台均分能分开看 |
| 创客 V1–V6 | 创客专属徽章 + 等级;极差/平级进佣金 |
| 酒道馆 / 区县 | 独立身份标;团队奖和平台均分能分开看 |
| 合伙股东 | 专属合伙股东身份徽章与对应权益 |
| 所有人 | 30 天没下单时,收益页明确写「本月无自购,暂停发放」 |
### 1.3 本期不做(避免范围膨胀)
@@ -51,7 +53,7 @@
```
商城
└─ 收益中心(原「分销中心」)
├─ 成员档案 原分销商:查人、改上级、开通酒道馆/区县(显示品酒师/合伙股东身份)
├─ 成员档案 原分销商:查人、改上级、开通酒道馆/区县/合伙股东(显示品酒师/创客/酒道馆/区县/合伙股东身份)
├─ 身份等级 原分销商等级:品酒师 / 创客 V1–V6
├─ 计奖商品 原分销商品:是否参与计奖
├─ 收益流水 即时奖 / 均分 / 马豆等入账与补发退回
@@ -62,7 +64,7 @@
└─ 动态日志 原分销动态
商城 → 商城配置
├─ 分销基础 层级/成为条件等底座(勿把层级改成 0)
└─ 合伙股东规则 Tab:固定金额、均分、马豆、兑换券规则
└─ 收益中心规则 Tab:固定金额、均分、马豆、兑换券规则
```
权限节点(写入 `addons/shopro/config/menu.php`,升级菜单):
@@ -79,14 +81,14 @@
## 3. 后台:改现有页
### 3.1 分销设置 · 新增 Tab「合伙股东」
### 3.1 分销设置 · 新增 Tab「收益中心规则」
**现有:** `application/admin/view/shopro/config/index.html` + `public/assets/js/backend/shopro/config.js` 已有分销 Tab。
**处理:** 同一页加第三个分组,保存进 `shop.commission.partner.*`,不要新菜单。
| 区块 | 字段 | 控件 | 默认 | 校验 / 说明文案 |
|---|---|---|---|---|
| 总控 | 启用合伙股东结算 | 开关 | 开 | 关闭后新单不再记即时奖,旧流水不动 |
| 总控 | 启用收益中心新结算 | 开关 | 开 | 关闭后新单不再记即时奖,旧流水不动 |
| 总控 | 关闭旧百分比分佣 | 开关 `partner_mode` | 开 | 旁注:不要把「分销层级」改成 0,否则用户端收益中心打不开 |
| 计单 | 合格订单口径 | 单选 | 订单头 | 选项:订单头 / 商品件数 |
| 活跃 | 领取窗口天数 | 数字 | 30 | ≥1 |
@@ -144,8 +146,8 @@
**改:**
1. 「等级佣金比例」三块(commission_1/2/3)在 `partner_mode` 下改成展示文案:「已切换为合伙股东固定金额,旧百分比不再生效。」仍可折叠看历史配置。
2. 新增卡片「合伙股东资产」:
1. 「等级佣金比例」三块(commission_1/2/3)在 `partner_mode` 下改成展示文案:「已切换为收益中心固定金额新模式,旧百分比不再生效。」仍可折叠看历史配置。
2. 新增卡片「收益中心资产」:
| 字段 | 只读 |
|---|---|
@@ -155,7 +157,7 @@
| 直推计奖序号 | 第 14 单,下一单将返 400 |
| 马豆 / 约合 | |
| 兑换券 总额 / 已释放 / 已使用 / 可用 | |
| 累计合伙股东现金收益 | 从 `partner_reward` 已入账求和 |
| 累计现金收益 | 从 `partner_reward` 已入账求和 |
3. 新增 Tab 或按钮「TA 的收益流水」:跳到收益流水页并带 `user_id`。
4. 新增按钮「手工补发 / 扣回」(权限 `reissue`),打开 4.1 的弹窗并预填用户。
@@ -189,7 +191,7 @@
**现有:** 权重、名称、徽章、百分比、升级条件。
**改:**
- 页面顶警告改为:「等级 1 固定为品酒师;2–7 对应创客 V1–V6。百分比佣金在合伙股东模式下不使用。」
- 页面顶警告改为:「等级 1 固定为品酒师;2–7 对应创客 V1–V6。百分比佣金在收益中心新模式下不使用。」
- 增加只读映射表:level → 单笔极差基数(读配置 `maker_bonus`,点「去规则里改」跳设置 Tab)。
- 升级条件原样保留:运营可配「直推满 N 人升 V2」等,走现成 `agentUpgrade` 队列。
- 初始化数据:上线脚本插入 7 条等级(若库里已有旧等级,提供「迁移说明」:把旧 level=1 改名为品酒师,新增 2–7)。
@@ -197,7 +199,7 @@
### 3.6 分销商品
**现有:** 是否参与分销。
**改文案:** 「参与分销 / 合伙股东计奖」。
**改文案:** 「参与分销 / 收益中心计奖」。
关闭的商品:不计入推三返一、极差、拆分、均分、马豆 N、兑换券。
不改表结构。
@@ -309,7 +311,7 @@ ID、入账时间、受益人、买家、订单、奖项、角色、金额、马
### 5.1 上线当天
1. 跑 SQL,插入 7 条等级。
2. 分销设置:成为分销商 = 注册即是;关掉申请表单;打开合伙股东结算。
2. 分销设置:成为分销商 = 注册即是;关掉申请表单;打开收益中心结算。
3. 用测试号 A 推荐 B,B 下一单,A 应到账 398。
4. 后台把 A 调成创客 V5 + 酒道馆,再让 C 在 B 下面下单,核对拆账。
@@ -364,17 +366,18 @@ ID、入账时间、受益人、买家、订单、奖项、角色、金额、马
[品酒师]
```
或
或多重身份:
```
张三
[合伙股东] [创客V5] [酒道馆]
[创客V5] [酒道馆]
```
(若被授予合伙股东身份,则独立并列显示 `[合伙股东]`)
规则:
- 仅品酒师:一枚灰/棕标签「品酒师」。
- `is_partner`:先一枚主标「合伙股东」,再跟创客等级、酒道馆、区县。
- 独立展示:各身份(创客等级、酒道馆、区县、合伙股东)平行独立,按实际资格呈现,**严禁将合伙股东作为其他角色的统称或强制前缀**。
- 最多一行,超出换行不撑破头像区。
- 点击徽章 → `/pages/commission/index`(未登录走登录)。
@@ -477,7 +480,7 @@ ID、入账时间、受益人、买家、订单、奖项、角色、金额、马
```
`filterUserNum` 文案「直推 x 人」可保留。
顶上「团队分销商人数」改文案为「团队合伙股东人数」可选,避免一次改太多;若改,一级/二级同步改「一级成员」。
顶上「团队分销商人数」改文案为「团队成员人数」,一级/二级同步改「一级成员」。
数据:`GET commission.agent/team` 已 with agent,后端 agent 加 `is_venue` `is_county` 即可,前端加两个 `v-if`。
@@ -614,9 +617,9 @@ ID、入账时间、受益人、买家、订单、奖项、角色、金额、马
```json
{
"identity_text": "合伙股东 · 创客V5 · 酒道馆",
"identity_text": "创客V5 · 酒道馆",
"identities": ["maker", "venue"],
"is_partner": true,
"is_partner": false,
"maker_level_name": "创客V5",
"madow": "12.50000000",
"madow_rate": "0.00000750",
@@ -681,7 +684,7 @@ export default {
| ID | 任务 | 文件 | 验收 |
|---|---|---|---|
| U1 | store + api | `user.js` `api/partner.js` `api/index.js` | profile 有徽章字段不报错 |
| U2 | 用户卡片徽章 | `s-user-card.vue` | 我的页能看到品酒师/合伙股东 |
| U2 | 用户卡片徽章 | `s-user-card.vue` | 我的页能正确显示各独立身份徽章(品酒师/创客/酒道馆/区县/合伙股东) |
| U3 | 钱包五项 | `s-wallet-card.vue` | 能进收益/马豆/券 |
| U4 | 收益中心改名与警示 | `commission/index.vue` `pages.json` | 30 日无单有黄条 |
| U5 | 身份条/账户卡/菜单 | 三个 components | 馆/县标、四指标、新菜单 |
@@ -706,7 +709,7 @@ export default {
|---|---|---|
| 1 注册 X,A 分享 | X 为品酒师,上级 A | X「我的」徽章品酒师 |
| 2 X 下首单 1398 | A 流水 push3=398;X 有券计划 2097 | A 收益 +398;X 兑换券总额 2097、已释放 0 |
| 3 把 B 调成 V5 | 身份列变化 | B 徽章变合伙股东·创客V5 |
| 3 把 B 调成 V5 | 身份列变化 | B 徽章变创客V5 |
| 4 再下一单(链上有两个 V5) | B 极差 100,C 平级 10 | 两人收益明细对应文案 |
| 5 开通 D 酒道馆、E 区县 | 拆分 50+50 | D/E 多标,明细有团队奖 |
| 6 把 A 的自购时间改到 31 天前(测) | A 灰点;新单 A 一条 skip | A 顶栏黄条;明细「未发放」 |
@@ -721,7 +724,7 @@ export default {
给运营的一页纸:
1. 用户默认都是品酒师,不用申请。
2. 创客/酒道馆/区县你在后台开通,用户端只展示。
2. 创客/酒道馆/区县/合伙股东在后台独立开通管理,用户端平行展示。
3. 钱进「收益」可提现;马豆只能看值;兑换券只能兑货,365 天慢慢出来。
4. 30 天自己不买,推广费停发,不是封号。
5. 改规则只影响以后的单。
@@ -731,6 +734,6 @@ export default {
## 16. 和主技术方案的关系
- 表结构、钩子、算法:只看 `合伙股东收益体系二次开发文档.md`。
- 表结构、钩子、算法:只看 `收益中心二次开发文档.md`。
- 页面、字段、文案、验收剧本:只看本文。
- 两边冲突时,以算法文档的「建议默认」为准,本文跟默认走。

查看文件

@@ -10,9 +10,10 @@
> [!IMPORTANT]
> ### 核心概念澄清(避免误导)
> 1. **系统定位**:本模块为**会员收益体系**,后台一级菜单与用户端统一命名为**「收益中心」**(原「分销中心」)。
> 2. **「合伙股东」只是会员的身份标签,不是系统/模块名称**:
> - **「品酒师」**:注册即是的基础分销会员身份标签(对应分销商 `level = 1`)。
> - **「合伙股东」**:进阶会员身份标签。当会员满足创客(`level >= 2`,对应创客 V1–V6)、酒道馆(`is_venue = 1`)或区县代理(`is_county = 1`)时,系统为该会员附加「合伙股东」身份标签(展示为:“合伙股东 · 创客V5 · 酒道馆”)。
> 2. **「合伙股东」只是一个独立的角色身份,不是所有角色都在合伙股东下(切勿误导)**:
> - 系统中包含 **品酒师**、**创客 (V1–V6)**、**酒道馆**、**区县代理**、**合伙股东** 等独立平行的角色身份。
> - **「合伙股东」本身仅是一个独立的高阶角色身份**,创客、酒道馆、区县代理各司其职,**绝不隶属于合伙股东**。
> - 各角色身份平行独立,严禁将所有进阶角色归属于合伙股东名下,更不可强行加挂“合伙股东·创客”等混淆关系的命名。
> 3. 后台所有菜单、页面表头及用户端导航,均统一按功能命名(如「收益中心」、「成员档案」、「收益流水」),切勿将整套系统误叫为“合伙股东”。
---
@@ -24,7 +25,7 @@
| 商城后端 | `addons/shopro`、`application/admin` | 完整,Shopro Plus 3.2.0 |
| 管理后台前端 | `application/admin/view/shopro` + `public/assets/js/backend/shopro` | 完整,Element Plus + RequireJS |
| 用户端 | **`uniapp/`** | Shopro sheep 3.1.0,接口前缀 `/addons/shopro/`,与后端完全对齐 |
| 现有分销 UI | `uniapp/pages/commission/*` | 只有等级名徽章 + 百分比分销中心,没有品酒师/合伙股东/马豆/释放券 |
| 现有分销 UI | `uniapp/pages/commission/*` | 只有等级名徽章 + 百分比分销中心,没有品酒师/创客/酒道馆/区县/合伙股东等新身份/马豆/释放券 |
用户端请求:
@@ -197,20 +198,22 @@ PayOper 支付成功
| level | 名称 | 业务身份 | 单笔极差基数(建议) |
|---|---|---|---|
| 1 | 品酒师 | 普通会员 | 0(不参与极差) |
| 2 | 创客V1 | 合伙股东·创客 | 20 |
| 3 | 创客V2 | 合伙股东·创客 | 40 |
| 4 | 创客V3 | 合伙股东·创客 | 60 |
| 5 | 创客V4 | 合伙股东·创客 | 80 |
| 6 | 创客V5 | 合伙股东·创客 | 100 |
| 7 | 创客V6 | 合伙股东·创客 | 120 |
| 1 | 品酒师 | 基础会员 | 0(不参与极差) |
| 2 | 创客V1 | 进阶骨干·创客 | 20 |
| 3 | 创客V2 | 进阶骨干·创客 | 40 |
| 4 | 创客V3 | 进阶骨干·创客 | 60 |
| 5 | 创客V4 | 进阶骨干·创客 | 80 |
| 6 | 创客V5 | 进阶骨干·创客 | 100 |
| 7 | 创客V6 | 进阶骨干·创客 | 120 |
判定:
判定说明:
```
是品酒师 = agent 存在且 level == 1
是创客 = agent 存在且 level >= 2
合伙股东 = 创客 或 酒道馆 或 区县代理
是品酒师 = agent 存在且 level == 1
是创客 = agent 存在且 level >= 2(细分为创客V1~V6)
是酒道馆 = is_venue == 1
是区县代理 = is_county == 1
是合伙股东 = 独立高阶角色身份(后台独立开通/授予,各角色身份独立平行,绝不把创客/馆/县归为合伙股东)
```
一个人只有一个 `level`,所以**不可能同时是品酒师和创客**,与需求一致。
@@ -653,7 +656,7 @@ CREATE TABLE `fa_shopro_partner_voucher_plan` (
}
```
`identities` 例:`["maker","venue"]`,`identity_text`:`合伙股东 · 创客V5 · 酒道馆`。
`identities` 例:`["maker","venue"]`,`identity_text`:`创客V5 · 酒道馆`(各身份独立平行展示)。
徽章继续用 `level_info.name` + `level_info.image`,前端可再画酒道馆/区县小标。
### 9.2 扩展 `GET /addons/shopro/user.user/profile`
@@ -682,7 +685,7 @@ CREATE TABLE `fa_shopro_partner_voucher_plan` (
| 页 | 文件 | 改动 |
|---|---|---|
| 分销设置 | `view/shopro/config/index.html` + `js/backend/shopro/config.js` | 增加「合伙股东」Tab |
| 分销设置 | `view/shopro/config/index.html` + `js/backend/shopro/config.js` | 增加「收益中心规则」Tab |
| 分销商编辑 | `commission/agent` 的 edit | `is_venue` `is_county` `county_code` |
| 分销商列表 | `agent.js` / `agent/index.html` | 筛酒道馆/区县,列身份 |
| 等级 | `commission/level/add.html` | 文案改为级差基数;`commission_rules` 可空;展示 `maker_bonus[level]` |
@@ -691,9 +694,9 @@ CREATE TABLE `fa_shopro_partner_voucher_plan` (
| 菜单 | 控制器 | 能力 |
|---|---|---|
| 合伙股东 / 收益流水 | `shopro/partner/reward` | 筛选、导出、手工补发/扣回 |
| 合伙股东 / 日结对账 | `shopro/partner/daily` | 按日看池子、重跑昨天 |
| 合伙股东 / 兑换券 | `shopro/partner/voucher` | 计划、已释放、已使用 |
| 收益中心 / 收益流水 | `shopro/partner/reward` | 筛选、导出、手工补发/扣回 |
| 收益中心 / 日结对账 | `shopro/partner/daily` | 按日看池子、重跑昨天 |
| 收益中心 / 兑换券 | `shopro/partner/voucher` | 计划、已释放、已使用 |
样式、筛选器、导出照抄 `commission/reward`。
@@ -737,7 +740,7 @@ CREATE TABLE `fa_shopro_partner_voucher_plan` (
|---|---|
| `uniapp/sheep/store/user.js` | `defaultUserInfo` 增加 `identities` `identity_text` `madow` `madow_value` `voucher_available`;`getInfo()` 后即可画徽章,不必等 agent |
| `uniapp/sheep/api/partner.js` | **新建**,见 9.3;在 `sheep/api/index.js` 注册 `partner` |
| `uniapp/sheep/components/s-user-card/s-user-card.vue` | 昵称下方:`品酒师` 或 `合伙股东 · 创客Vx`,可叠加酒道馆/区县 |
| `uniapp/sheep/components/s-user-card/s-user-card.vue` | 昵称下方:`品酒师` 或 `创客Vx`,可独立叠加酒道馆/区县/合伙股东等身份徽章 |
| `uniapp/sheep/components/s-wallet-card/s-wallet-card.vue` | 恢复佣金入口;加「马豆」「兑换券」两项(点进新页) |
| `uniapp/pages/commission/index.vue` | `title` 改为「收益中心」 |
| `uniapp/pages/commission/components/commission-info.vue` | `level_info` 一枚 + `is_venue`/`is_county` 两枚 |

查看文件

@@ -1,6 +1,6 @@
# 收益中心 · 多维关系场景收益模拟与财务测算报告
> 本文档依据恒联数通「收益中心」(合伙股东)二次开发核心代码及业务规则编制,用于模拟分析各种会员层级关系、拓扑链路下的即时收益、日结分红、兑换券释放及平台综合现金拨比。
> 本文档依据恒联数通「收益中心」二次开发核心代码及业务规则编制,用于模拟分析各种会员层级关系、拓扑链路下的即时收益、日结分红、兑换券释放及平台综合现金拨比。
---
@@ -119,7 +119,7 @@
---
## 场景五:合伙股东完整大链条(创客 + 酒道馆 + 区县代理 + 双平级)
## 场景五:多重身份完整大链条(创客 + 酒道馆 + 区县代理 + 双平级)
### 1. 业务关系拓扑
```
@@ -138,11 +138,11 @@
| :--- | :--- | :--- | :--- | :--- |
| **买家 A** | 品酒师 | 兑换券发放 | ¥ 0.00 | 获 2097 元兑换券,按 365 天释放 |
| **推荐人 B**| 品酒师 | 推三返一 | **¥ 398.00** | 直推第 1 单,返现 398 元 |
| **创客 C** | 合伙股东·创客 V4 | 创客极差奖 | **¥ 80.00** | 链上首位创客,独享 V4 极差 80 元 |
| **酒道馆 1**| 合伙股东·酒道馆 A| **酒道馆团队奖** | **¥ 50.00** | 链上有馆有县,团队奖拆分获得 50 元 |
| **酒道馆 2**| 合伙股东·酒道馆 B| **酒道馆平级奖** | **¥ 5.00** | 第二个酒道馆,获下级馆团队奖的 10%:$50 \times 10\% = 5$ 元 |
| **区县代理1**| 合伙股东·区县甲 | **区县团队奖** | **¥ 50.00** | 链上有馆有县,团队奖拆分获得 50 元 |
| **区县代理2**| 合伙股东·区县乙 | **区县平级奖** | **¥ 5.00** | 第二个区县代理,获下级县团队奖的 10%:$50 \times 10\% = 5$ 元 |
| **创客 C** | 创客 V4 | 创客极差奖 | **¥ 80.00** | 链上首位创客,独享 V4 极差 80 元 |
| **酒道馆 1**| 酒道馆 A | **酒道馆团队奖** | **¥ 50.00** | 链上有馆有县,团队奖拆分获得 50 元 |
| **酒道馆 2**| 酒道馆 B | **酒道馆平级奖** | **¥ 5.00** | 第二个酒道馆,获下级馆团队奖的 10%:$50 \times 10\% = 5$ 元 |
| **区县代理1**| 区县代理 甲 | **区县团队奖** | **¥ 50.00** | 链上有馆有县,团队奖拆分获得 50 元 |
| **区县代理2**| 区县代理 乙 | **区县平级奖** | **¥ 5.00** | 第二个区县代理,获下级县团队奖的 10%:$50 \times 10\% = 5$ 元 |
### 3. 财务穿透与拨比测算
- **本单即时现金总支出**:$398 + 80 + 50 + 5 + 50 + 5 = 588.00$ 元。
@@ -165,7 +165,7 @@
| 收益人 | 会员身份 / 标签 | 获得奖项 | 现金收益 | 计算规则与说明 |
| :--- | :--- | :--- | :--- | :--- |
| **推荐人 B** | 品酒师 | 推三返一 | **¥ 400.00** | 第 2 单享受 400 元 |
| **区县代理甲** | 合伙股东·区县 | **区县团队奖** | **¥ 100.00** | **链上无酒道馆,区县代理独享全额 100 元团队奖** |
| **区县代理甲** | 区县代理 | **区县团队奖** | **¥ 100.00** | **链上无酒道馆,区县代理独享全额 100 元团队奖** |
- **本单现金分润总额**:$400 + 100 = 500$ 元。
- **本单现金拨比率**:$500 / 1398 \approx 35.77\%$。
@@ -184,12 +184,12 @@
| 收益人 | 身份 | 获得奖项 | 现金收益 | 计算规则与说明 |
| :--- | :--- | :--- | :--- | :--- |
| **馆主 A (买家)** | 合伙股东·酒道馆 | 推三返一 | ¥ 0.00 | 自购不产生推三返一(记录 skip) |
| **馆主 A (买家)** | 合伙股东·酒道馆 | **酒道馆团队奖** | **¥ 50.00** | **自购计入团队链头,自购自得馆团队奖 50 元** |
| **馆主 A (买家)** | 合伙股东·酒道馆 | 兑换券计划 | ¥ 0.00 (券 2097) | 自身获得 2097 元产品兑换券,分 365 天释放 |
| **上级馆 B** | 合伙股东·酒道馆 | **酒道馆平级奖** | **¥ 5.00** | 获得馆主 A 自购团队奖的 10%:$50 \times 10\% = 5$ 元 |
| **馆主 A (买家)** | 酒道馆 | 推三返一 | ¥ 0.00 | 自购不产生推三返一(记录 skip) |
| **馆主 A (买家)** | 酒道馆 | **酒道馆团队奖** | **¥ 50.00** | **自购计入团队链头,自购自得馆团队奖 50 元** |
| **馆主 A (买家)** | 酒道馆 | 兑换券计划 | ¥ 0.00 (券 2097) | 自身获得 2097 元产品兑换券,分 365 天释放 |
| **上级馆 B** | 酒道馆 | **酒道馆平级奖** | **¥ 5.00** | 获得馆主 A 自购团队奖的 10%:$50 \times 10\% = 5$ 元 |
- **财务特征**:合伙股东自购能享受到对应身份的团队奖返点,增强会员自购粘性。
- **财务特征**:酒道馆主自购能享受到对应身份的团队奖返点,增强会员自购粘性。
---

查看文件

@@ -309,6 +309,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
level: Number(row.level || 1),
is_venue: Number(row.is_venue || 0),
is_county: Number(row.is_county || 0),
is_partner: Number(row.is_partner || 0),
county_code: row.county_code || '',
area_arr: row.county_code ? findAreaPath(identity.areaSelect, row.county_code) || [] : [],
upgrade_lock: Number(row.upgrade_lock || 0),
@@ -331,18 +332,14 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
}
}
function identityLabel(level, isVenue, isCounty) {
function identityLabel(level, isVenue, isCounty, isPartner) {
const lv = identity.levels.find(i => Number(i.level) === Number(level))
let name = lv?.name || (Number(level) === 1 ? '品酒师' : `创客V${Number(level) - 1}`)
const tags = []
if (Number(level) >= 2) tags.push(name)
else tags.push(name)
const tags = [name]
if (Number(isVenue)) tags.push('酒道馆')
if (Number(isCounty)) tags.push('区县代理')
if (Number(level) >= 2 || Number(isVenue) || Number(isCounty)) {
return '合伙股东 · ' + tags.filter((v, i, a) => a.indexOf(v) === i).join(' · ')
}
return tags[0]
if (Number(isPartner)) tags.push('合伙股东')
return tags.filter((v, i, a) => a.indexOf(v) === i).join(' · ')
}
function onSubmitIdentity() {
@@ -351,7 +348,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
return
}
const { ElMessageBox } = ElementPlus
const afterText = identityLabel(identity.form.level, identity.form.is_venue, identity.form.is_county)
const afterText = identityLabel(identity.form.level, identity.form.is_venue, identity.form.is_county, identity.form.is_partner)
const name = identity.form.nickname || identity.form.user_id
ElMessageBox.confirm(
`将「${name}」从 ${identity.form.before_text || '当前身份'} 调整为 ${afterText}。已入账收益不追溯。确定?`,
@@ -544,6 +541,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
level: Number(state.data.level || 1),
is_venue: Number(state.data.is_venue || 0),
is_county: Number(state.data.is_county || 0),
is_partner: Number(state.data.is_partner || 0),
county_code: state.data.county_code || '',
area_arr: [],
upgrade_lock: Number(state.data.upgrade_lock || 0),
@@ -563,14 +561,13 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
}
const { ElMessageBox } = ElementPlus
const lv = identity.levels.find(i => Number(i.level) === Number(identity.form.level))
let after = lv?.name || '品酒师'
if (Number(identity.form.is_venue) || Number(identity.form.is_county) || Number(identity.form.level) >= 2) {
const parts = ['合伙股东']
if (Number(identity.form.level) >= 2) parts.push(lv?.name || `创客V${identity.form.level - 1}`)
if (Number(identity.form.is_venue)) parts.push('酒道馆')
if (Number(identity.form.is_county)) parts.push('区县代理')
after = parts.join(' · ')
}
const tags = []
if (Number(identity.form.level) >= 2) tags.push(lv?.name || `创客V${identity.form.level - 1}`)
else tags.push(lv?.name || '品酒师')
if (Number(identity.form.is_venue)) tags.push('酒道馆')
if (Number(identity.form.is_county)) tags.push('区县代理')
if (Number(identity.form.is_partner)) tags.push('合伙股东')
const after = tags.filter((v, i, a) => a.indexOf(v) === i).join(' · ')
ElMessageBox.confirm(
`将「${identity.form.nickname}」从 ${identity.form.before_text || '当前身份'} 调整为 ${after}。已入账收益不追溯。确定?`,
'确认调整身份',

查看文件

@@ -33,7 +33,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
}
function onGotoPartnerConfig() {
Fast.api.open('shopro/config?tab=shopro/config/partner', '合伙股东规则')
Fast.api.open('shopro/config?tab=shopro/config/partner', '收益中心规则')
}
function onAdd() {

查看文件

@@ -133,7 +133,7 @@ class AgentDetailTest
$data = $response->getData();
$this->assert($data['code'] === 1 || $data['code'] === 0, '详情响应格式符合规范 (code/msg/data)');
$this->assert(isset($data['data']['user_id']), '详情数据包含 user_id');
$this->assert(isset($data['data']['active_status_text']), '详情数据包含合伙股东活跃状态扩展字段');
$this->assert(isset($data['data']['active_status_text']), '详情数据包含成员自购活跃状态扩展字段');
}
} catch (\Throwable $e) {
$this->assert(false, '详情接口测试执行异常: ' . $e->getMessage());

查看文件

@@ -110,7 +110,7 @@ class DashboardWealthTest
'total() 返回完整的 voucher_data 消费兑换券杠杆资金池指标');
$this->assert(!empty($network) && isset($network['maker_count'], $network['taster_count'], $network['active_rate']),
'total() 返回完整的 partner_network 合伙股东活力分布');
'total() 返回完整的 partner_network 团队成员活力分布');
$this->assert(!empty($network['role_list']) && is_array($network['role_list']),
'total() 返回 role_list 全角色身份矩阵列表');
@@ -182,7 +182,7 @@ class DashboardWealthTest
}
/**
* 测试 4:排行与对账 ranking() 合伙股东收益排行与最新日结
* 测试 4:排行与对账 ranking() 收益排行榜与最新日结
*/
public function testRankingPartnerAndDailyData()
{
@@ -193,7 +193,7 @@ class DashboardWealthTest
$partnerRanking = $data['partner_ranking'] ?? null;
$recentReport = $data['daily_report_recent'] ?? null;
$this->assert(is_array($partnerRanking), 'ranking() 返回 partner_ranking 合伙股东收益榜');
$this->assert(is_array($partnerRanking), 'ranking() 返回 partner_ranking 收益排行榜');
if (!empty($partnerRanking)) {
$top1 = $partnerRanking[0];
$this->assert(isset($top1['user_id'], $top1['nickname'], $top1['total_income'], $top1['identity_text']),
@@ -292,7 +292,7 @@ class DashboardWealthTest
}
/**
* 测试 8:自购雷达纯净性检验(仅合伙股东身份纳入考核,杜绝品酒师与普通会员混入)
* 测试 8:自购雷达纯净性检验(进阶角色创客/馆/县/股东纳入考核,杜绝品酒师与普通会员混入)
*/
public function testPartnerShareholderRadarPurity()
{
@@ -304,30 +304,30 @@ class DashboardWealthTest
$warningList = $operation['warning_list'] ?? [];
$pendingList = $operation['pending_renew_list'] ?? [];
// 验证预警名单中所有人均为合伙股东(创客V1~V6/酒道馆/区县)
// 验证预警名单中所有人均为进阶角色(创客V1~V6/酒道馆/区县/合伙股东)
$hasNonPartnerInWarning = false;
foreach ($warningList as $wUser) {
$levelText = $wUser['level_text'] ?? '';
if (strpos($levelText, '品酒师') !== false && strpos($levelText, '合伙股东') === false) {
if (strpos($levelText, '品酒师') !== false && strpos($levelText, '创客') === false && strpos($levelText, '酒道馆') === false && strpos($levelText, '区县') === false && strpos($levelText, '合伙股东') === false) {
$hasNonPartnerInWarning = true;
}
}
$this->assert(!$hasNonPartnerInWarning, "自购临期预警名单严禁混入普通会员或品酒师,100%为合伙股东身份");
$this->assert(!$hasNonPartnerInWarning, "自购临期预警名单严禁混入普通会员或基础品酒师,100%为进阶角色身份");
// 验证待续期名单中所有人均为合伙股东
// 验证待续期名单中所有人均为进阶角色
$hasNonPartnerInPending = false;
foreach ($pendingList as $pUser) {
$levelText = $pUser['level_text'] ?? '';
if (strpos($levelText, '品酒师') !== false && strpos($levelText, '合伙股东') === false) {
if (strpos($levelText, '品酒师') !== false && strpos($levelText, '创客') === false && strpos($levelText, '酒道馆') === false && strpos($levelText, '区县') === false && strpos($levelText, '合伙股东') === false) {
$hasNonPartnerInPending = true;
}
}
$this->assert(!$hasNonPartnerInPending, "自购买超期待续期名单严禁混入普通会员或品酒师,100%为合伙股东身份");
$this->assert(!$hasNonPartnerInPending, "自购买超期待续期名单严禁混入普通会员或基础品酒师,100%为进阶角色身份");
// 验证 partner_network 中 active_rate 正确性
$partnerNetwork = $data['partner_network'] ?? [];
$activeRate = $partnerNetwork['active_rate'] ?? null;
$this->assert($activeRate !== null && $activeRate >= 0 && $activeRate <= 100, "合伙股东自购达标率 partner_network.active_rate({$activeRate}%) 合法且在区间内");
$this->assert($activeRate !== null && $activeRate >= 0 && $activeRate <= 100, "进阶成员自购达标率 partner_network.active_rate({$activeRate}%) 合法且在区间内");
}
}

查看文件

@@ -54,14 +54,14 @@
</view>
</view>
<!-- 团队合伙股东人数卡片 -->
<!-- 团队成员人数卡片 -->
<view
class="data-card"
:class="{ 'card-active': state.currentFilter === 'partner' }"
@tap="onSelectHeaderTab('all', 'partner')"
>
<view class="total-item">
<view class="item-title">合伙股东总数(人)</view>
<view class="item-title">分销成员总数(人)</view>
<view class="total-num text-gold">{{ headerNum('child_agent_count_all') }}</view>
</view>
<view class="category-item ss-flex">
@@ -70,7 +70,7 @@
:class="{ 'sub-active': state.currentFilter === 'partner' && state.currentLevelTab === '1' }"
@tap.stop="onSelectHeaderTab('1', 'partner')"
>
<view class="item-title">一级合伙</view>
<view class="item-title">一级成员</view>
<view class="category-num text-gold">{{ headerNum('child_agent_count_1') }}</view>
</view>
<view
@@ -78,7 +78,7 @@
:class="{ 'sub-active': state.currentFilter === 'partner' && state.currentLevelTab === '2' }"
@tap.stop="onSelectHeaderTab('2', 'partner')"
>
<view class="item-title">二级合伙</view>
<view class="item-title">二级成员</view>
<view class="category-num text-gold">{{ headerNum('child_agent_count_2') }}</view>
</view>
</view>

查看文件

@@ -24,13 +24,11 @@
class="identity-row ss-flex ss-col-center ss-flex-wrap"
@tap="onBadgeTap"
>
<view v-if="isTasterOnly" class="identity-tag taster-tag">品酒师</view>
<template v-else-if="isPartner">
<view class="identity-tag partner-tag">合伙股东</view>
<view v-if="makerLevelName" class="identity-tag maker-tag">{{ makerLevelName }}</view>
<view v-if="hasVenue" class="identity-tag venue-tag">酒道馆</view>
<view v-if="hasCounty" class="identity-tag county-tag">区县</view>
</template>
<view v-if="hasTaster" class="identity-tag taster-tag">品酒师</view>
<view v-if="makerLevelName" class="identity-tag maker-tag">{{ makerLevelName }}</view>
<view v-if="hasVenue" class="identity-tag venue-tag">酒道馆</view>
<view v-if="hasCounty" class="identity-tag county-tag">区县</view>
<view v-if="hasPartner" class="identity-tag partner-tag">合伙股东</view>
</view>
</view>
</view>
@@ -113,18 +111,6 @@
const identityText = computed(() => userInfo.value?.identity_text || '');
const isPartner = computed(() => {
if (userInfo.value?.is_partner) return true;
if (identities.value.some((item) => ['maker', 'venue', 'county'].includes(item))) return true;
return ['合伙股东', '创客', '酒道馆', '区县'].some((key) => identityText.value.includes(key));
});
const isTasterOnly = computed(() => {
if (isPartner.value) return false;
if (identities.value.includes('taster')) return true;
return identityText.value === '品酒师';
});
const makerLevelName = computed(() => userInfo.value?.maker_level_name || '');
const hasVenue = computed(
@@ -135,7 +121,27 @@
() => identities.value.includes('county') || identityText.value.includes('区县'),
);
const showIdentityBadges = computed(() => isTasterOnly.value || isPartner.value);
const hasPartner = computed(() => {
return (
Boolean(userInfo.value?.is_partner) ||
identities.value.includes('partner') ||
identityText.value.includes('合伙股东')
);
});
const hasTaster = computed(() => {
if (makerLevelName.value) return false;
return identities.value.includes('taster') || identityText.value.includes('品酒师');
});
const showIdentityBadges = computed(
() =>
hasTaster.value ||
!!makerLevelName.value ||
hasVenue.value ||
hasCounty.value ||
hasPartner.value,
);
function onBind() {
showAuthModal('changeMobile');