feat: 支持角色身份自定义名称全链路配置与动态展示

这个提交包含在:
chen
2026-09-17 15:40:47 +08:00
父节点 06e98c57e0
当前提交 f8179706b3
共有 24 个文件被更改,包括 508 次插入 和 110 次删除

查看文件

@@ -169,7 +169,7 @@ class Dashboard extends Common
'available_voucher' => number_format($availableVoucher, 2, '.', ''),
];
// 7. 合伙股东网络与全角色身份矩阵 (收益按角色专属类型归集,杜绝重复统计)
// 7. 收益中心网络与全角色身份矩阵 (收益按角色专属类型归集,杜绝重复统计)
$totalRegisteredUsers = (int) User::count();
$totalAgents = (int) Agent::count();
$normalUserCount = max(0, $totalRegisteredUsers - $totalAgents);
@@ -194,7 +194,7 @@ class Dashboard extends Common
$activeUserIds = $activeService->activeUserIds($activeWindowStart, $now);
$activeUserMap = array_flip($activeUserIds);
// 全量合伙股东基础信息
// 全量成员档案基础信息
$allAgents = Agent::field('user_id, level, is_venue, is_county, madow, last_self_order_time')->select();
// 收益明细按 (user_id + reward_type) 聚合,精确归集各角色产出收益
@@ -284,18 +284,25 @@ class Dashboard extends Common
];
};
$roleNames = PartnerConfig::roleNames();
$tasterTitle = $roleNames['taster'];
$makerTitle = $roleNames['maker'];
$venueTitle = $roleNames['venue'];
$countyTitle = $roleNames['county'];
$partnerTitle = $roleNames['partner'];
// 统计各角色身份详细指标
$roleList = [
$calcRoleStats(function($a) { return (int)$a->level == 1; }, 'taster', '品酒师', '基础身份', '人', '品', '#806af6', 1, '', $roleRewardTypeFilter['taster']),
$calcRoleStats(function($a) { return (int)$a->level == 2; }, 'maker_v1', '创客V1', '创客梯队', '人', 'V1', '#13c2c2', 2, '', $roleRewardTypeFilter['maker']),
$calcRoleStats(function($a) { return (int)$a->level == 3; }, 'maker_v2', '创客V2', '创客梯队', '人', 'V2', '#13c2c2', 3, '', $roleRewardTypeFilter['maker']),
$calcRoleStats(function($a) { return (int)$a->level == 4; }, 'maker_v3', '创客V3', '创客梯队', '人', 'V3', '#13c2c2', 4, '', $roleRewardTypeFilter['maker']),
$calcRoleStats(function($a) { return (int)$a->level == 5; }, 'maker_v4', '创客V4', '创客梯队', '人', 'V4', '#13c2c2', 5, '', $roleRewardTypeFilter['maker']),
$calcRoleStats(function($a) { return (int)$a->level == 6; }, 'maker_v5', '创客V5', '创客梯队', '人', 'V5', '#13c2c2', 6, '', $roleRewardTypeFilter['maker']),
$calcRoleStats(function($a) { return (int)$a->level == 7; }, 'maker_v6', '创客V6', '创客梯队', '人', 'V6', '#13c2c2', 7, '', $roleRewardTypeFilter['maker']),
$calcRoleStats(function($a) { return (int)$a->level >= 2; }, 'maker_total', '创客队伍小计', '创客梯队', '人', '创', '#13c2c2', 'maker', '', $roleRewardTypeFilter['maker']),
$calcRoleStats(function($a) { return (int)$a->is_venue == 1; }, 'venue', '实体酒道馆', '渠道授权', '家', '馆', '#fa8c16', '', 'venue', $roleRewardTypeFilter['venue']),
$calcRoleStats(function($a) { return (int)$a->is_county == 1; }, 'county', '区县代理', '渠道授权', '个', '县', '#722ed1', '', 'county', $roleRewardTypeFilter['county']),
$calcRoleStats(function($a) { return (int)$a->level == 1; }, 'taster', $tasterTitle, '基础身份', '人', mb_substr($tasterTitle, 0, 1), '#806af6', 1, '', $roleRewardTypeFilter['taster']),
$calcRoleStats(function($a) { return (int)$a->level == 2; }, 'maker_v1', $makerTitle . 'V1', $makerTitle . '梯队', '人', 'V1', '#13c2c2', 2, '', $roleRewardTypeFilter['maker']),
$calcRoleStats(function($a) { return (int)$a->level == 3; }, 'maker_v2', $makerTitle . 'V2', $makerTitle . '梯队', '人', 'V2', '#13c2c2', 3, '', $roleRewardTypeFilter['maker']),
$calcRoleStats(function($a) { return (int)$a->level == 4; }, 'maker_v3', $makerTitle . 'V3', $makerTitle . '梯队', '人', 'V3', '#13c2c2', 4, '', $roleRewardTypeFilter['maker']),
$calcRoleStats(function($a) { return (int)$a->level == 5; }, 'maker_v4', $makerTitle . 'V4', $makerTitle . '梯队', '人', 'V4', '#13c2c2', 5, '', $roleRewardTypeFilter['maker']),
$calcRoleStats(function($a) { return (int)$a->level == 6; }, 'maker_v5', $makerTitle . 'V5', $makerTitle . '梯队', '人', 'V5', '#13c2c2', 6, '', $roleRewardTypeFilter['maker']),
$calcRoleStats(function($a) { return (int)$a->level == 7; }, 'maker_v6', $makerTitle . 'V6', $makerTitle . '梯队', '人', 'V6', '#13c2c2', 7, '', $roleRewardTypeFilter['maker']),
$calcRoleStats(function($a) { return (int)$a->level >= 2; }, 'maker_total', $makerTitle . '队伍小计', $makerTitle . '梯队', '人', mb_substr($makerTitle, 0, 1), '#13c2c2', 'maker', '', $roleRewardTypeFilter['maker']),
$calcRoleStats(function($a) { return (int)$a->is_venue == 1; }, 'venue', $venueTitle, '渠道授权', '家', mb_substr($venueTitle, 0, 1), '#fa8c16', '', 'venue', $roleRewardTypeFilter['venue']),
$calcRoleStats(function($a) { return (int)$a->is_county == 1; }, 'county', $countyTitle, '渠道授权', '个', mb_substr($countyTitle, 0, 1), '#722ed1', '', 'county', $roleRewardTypeFilter['county']),
];
// 增加普通注册会员行 (明确标明无需自购考核)
@@ -365,6 +372,8 @@ class Dashboard extends Common
'active_rate' => $activeRate,
'role_list' => $roleList,
'role_stats' => $roleStats,
'role_names' => $roleNames,
'custom_role_names' => $roleNames,
];
// 8. CFO 视角:平台资金池结余、刚性法币流动负债与提现风控
@@ -408,7 +417,7 @@ class Dashboard extends Common
'pending_voucher_quota' => number_format($pendingVoucher, 2, '.', ''),
];
// 9. COO 视角:转化复购漏斗、合伙股东自购续期雷达、供应链库存与实时待办看板
// 9. COO 视角:转化复购漏斗、进阶成员自购续期雷达、供应链库存与实时待办看板
$paidOrderUsers = Order::whereIn('status', [Order::STATUS_PAID, Order::STATUS_COMPLETED])
->group('user_id')
->field('user_id, count(*) as buy_count')
@@ -428,7 +437,7 @@ class Dashboard extends Common
$repeatPurchaseRate = $paidUsersCount > 0 ? round(($repeatBuyCount / $paidUsersCount) * 100, 1) : 0.0;
$arpu = $paidUsersCount > 0 ? round($netGmv / $paidUsersCount, 2) : 0.0;
// 9.2 合伙股东 30 天自购续期雷达 (仅统计具备合伙股东身份的会员,避免恐慌误判)
// 9.2 进阶成员 30 天自购续期雷达 (仅统计具备进阶角色的会员,避免恐慌误判)
$activePartnersCount = 0;
$warningPartnersCount = 0;
$pendingRenewCount = 0;
@@ -506,7 +515,7 @@ class Dashboard extends Common
}
}
// 股东专属自购达标率(分子为在保合格股东,分母为合伙股东总人数)
// 进阶成员自购达标率(分子为在保合格进阶成员,分母为进阶角色总人数)
$partnerActiveRate = $partnerShareholderCount > 0
? round((($activePartnersCount + $warningPartnersCount) / $partnerShareholderCount) * 100, 1)
: 0.0;
@@ -634,6 +643,8 @@ class Dashboard extends Common
'partner_network' => $partnerNetwork,
'finance_overview' => $financeOverview,
'operation_overview' => $operationOverview,
'custom_role_names' => $roleNames,
'role_names' => $roleNames,
]);
}
@@ -887,7 +898,7 @@ class Dashboard extends Common
$searchHistory = new SearchHistory();
$hotSearch = $searchHistory->hotSearch();
// 3. 合伙股东收益排行 TOP 5
// 3. 收益中心收益排行 TOP 5
$partnerRanking = [];
$rankingRows = Reward::field('user_id, sum(amount) as total_income, count(*) as reward_count')
->where('status', 1)