fix(commission): 优化拓扑BFS防环遍历与升级考核直推有效品酒师指标

这个提交包含在:
chen
2026-09-29 15:25:31 +08:00
父节点 dbb9951857
当前提交 a7a8e3e494
共有 2 个文件被更改,包括 68 次插入 和 18 次删除

查看文件

@@ -121,24 +121,30 @@ class Agent extends Common
*/
private function getOperationalStats($detail, $id)
{
// 建立邻接表,使用广度优先遍历(BFS)安全获取全部后代节点,杜绝潜在脏数据循环引用死循环
$allUsers = \think\Db::name('user')->column('parent_user_id', 'id');
$getDesc = function ($uid) use (&$getDesc, $allUsers) {
$res = [];
foreach ($allUsers as $cid => $pid) {
if ((int)$pid === (int)$uid) {
$res[] = $cid;
$res = array_merge($res, $getDesc($cid));
}
}
return $res;
};
$descIds = $getDesc($id);
$directIds = [];
$children = [];
foreach ($allUsers as $cid => $pid) {
if ((int)$pid === (int)$id) {
$directIds[] = $cid;
if ($pid) {
$children[$pid][] = (int)$cid;
}
}
$descIds = [];
$queue = [(int)$id];
$visited = [(int)$id => true];
while (!empty($queue)) {
$curr = array_shift($queue);
if (!empty($children[$curr])) {
foreach ($children[$curr] as $cid) {
if (!isset($visited[$cid])) {
$visited[$cid] = true;
$descIds[] = $cid;
$queue[] = $cid;
}
}
}
}
$directIds = $children[(int)$id] ?? [];
// 1. 团队角色拓扑
$directCount = count($directIds);
@@ -200,15 +206,28 @@ class Agent extends Common
$targetDirectUsers = intval($nextRules['child_user_count_1'] ?? 0);
$targetTeamOrders = intval($nextRules['child_order_count_all'] ?? 0);
// 解析直推有效品酒师/创客指标要求
$targetDirectAgents = 0;
if (!empty($nextRules['child_agent_level_1']) && is_array($nextRules['child_agent_level_1'])) {
foreach ($nextRules['child_agent_level_1'] as $al) {
$targetDirectAgents += intval($al['count'] ?? 0);
}
} elseif (!empty($nextRules['child_agent_count_1'])) {
$targetDirectAgents = intval($nextRules['child_agent_count_1']);
}
$currentDirectUsers = intval($detail->child_user_count_1 ?? $directCount);
$currentDirectAgents = intval($detail->child_agent_count_1 ?? $directPaidCount);
$currentTeamOrders = intval($detail->child_order_count_all ?? 0);
$currentSelfMoney = (float)($detail->child_order_money_0 ?? 0);
$directUserGap = max(0, $targetDirectUsers - $currentDirectUsers);
$directAgentGap = max(0, $targetDirectAgents - $currentDirectAgents);
$teamOrderGap = max(0, $targetTeamOrders - $currentTeamOrders);
$isSelfPaid = ($selfOrderCount > 0 || $currentSelfMoney >= 1398);
$directUserPercent = $targetDirectUsers > 0 ? min(100, (int)round(($currentDirectUsers / $targetDirectUsers) * 100)) : 100;
$directAgentPercent = $targetDirectAgents > 0 ? min(100, (int)round(($currentDirectAgents / $targetDirectAgents) * 100)) : 100;
$teamOrderPercent = $targetTeamOrders > 0 ? min(100, (int)round(($currentTeamOrders / $targetTeamOrders) * 100)) : 100;
$upgradeRadar = [
@@ -221,13 +240,18 @@ class Agent extends Common
'direct_user_gap' => $directUserGap,
'direct_user_reached' => ($directUserGap === 0),
'direct_user_percent' => $directUserPercent,
'target_direct_agents' => $targetDirectAgents,
'current_direct_agents' => $currentDirectAgents,
'direct_agent_gap' => $directAgentGap,
'direct_agent_reached' => ($directAgentGap === 0),
'direct_agent_percent' => $directAgentPercent,
'target_team_orders' => $targetTeamOrders,
'current_team_orders' => $currentTeamOrders,
'team_order_gap' => $teamOrderGap,
'team_order_reached' => ($teamOrderGap === 0),
'team_order_percent' => $teamOrderPercent,
'self_paid_reached' => $isSelfPaid,
'all_reached' => ($directUserGap === 0 && $teamOrderGap === 0 && $isSelfPaid),
'all_reached' => ($directUserGap === 0 && $directAgentGap === 0 && $teamOrderGap === 0 && $isSelfPaid),
'upgrade_lock' => intval($detail->upgrade_lock ?? 0)
];
} else {
@@ -241,6 +265,11 @@ class Agent extends Common
'direct_user_gap' => 0,
'direct_user_reached' => true,
'direct_user_percent' => 100,
'target_direct_agents' => 0,
'current_direct_agents' => intval($detail->child_agent_count_1 ?? $directPaidCount),
'direct_agent_gap' => 0,
'direct_agent_reached' => true,
'direct_agent_percent' => 100,
'target_team_orders' => 0,
'current_team_orders' => intval($detail->child_order_count_all ?? 0),
'team_order_gap' => 0,
@@ -248,7 +277,6 @@ class Agent extends Common
'team_order_percent' => 100,
'self_paid_reached' => true,
'all_reached' => true,
'upgrade_lock' => intval($detail->upgrade_lock ?? 0)
];
}

查看文件

@@ -590,8 +590,30 @@
</div>
<div class="op-radar-body" v-if="state.data.operational_stats.upgrade_radar.next_level > 0">
<!-- 直推实名/购买用户考核 -->
<div class="op-radar-metric">
<!-- 直推实名/有效品酒师考核 -->
<div class="op-radar-metric" v-if="state.data.operational_stats.upgrade_radar.target_direct_agents > 0">
<div class="m-label">
<span>
直推有效品酒师
<el-popover placement="top" trigger="hover" content="需直推用户完成首单自购(child_order_count_0 ≥ 1)激活为有效品酒师">
<template #reference>
<span style="cursor: pointer; color: #94a3b8; font-size: 11px;">ℹ️ 说明</span>
</template>
</el-popover>
</span>
<el-tag size="small" :type="state.data.operational_stats.upgrade_radar.direct_agent_reached ? 'success' : 'danger'">
{{ state.data.operational_stats.upgrade_radar.direct_agent_reached ? '已达标' : '缺 ' + state.data.operational_stats.upgrade_radar.direct_agent_gap + ' 人' }}
</el-tag>
</div>
<div class="m-val">
{{ state.data.operational_stats.upgrade_radar.current_direct_agents }}
<span style="font-size: 12px; color: #94a3b8; font-weight: normal;"> / {{ state.data.operational_stats.upgrade_radar.target_direct_agents }} 人</span>
</div>
<el-progress :percentage="state.data.operational_stats.upgrade_radar.direct_agent_percent"
:status="state.data.operational_stats.upgrade_radar.direct_agent_reached ? 'success' : 'warning'"
:stroke-width="6" style="margin-top: 6px;"></el-progress>
</div>
<div class="op-radar-metric" v-else>
<div class="m-label">
<span>有效直推人数指标</span>
<el-tag size="small" :type="state.data.operational_stats.upgrade_radar.direct_user_reached ? 'success' : 'danger'">