更新bug
This commit is contained in:
@@ -64,10 +64,11 @@ class FirstVisitConversionLogic
|
||||
$effectiveAdminIds = self::intersectVisibleIds($effectiveAdminIds, $deptAdminIds);
|
||||
}
|
||||
|
||||
if ($selectedAssistantId > 0) {
|
||||
$assistantValid = self::isActiveAssistant($selectedAssistantId)
|
||||
&& ($effectiveAdminIds === null || in_array($selectedAssistantId, $effectiveAdminIds, true));
|
||||
$effectiveAdminIds = $assistantValid ? [$selectedAssistantId] : [];
|
||||
$selectedAssistantValid = $selectedAssistantId <= 0;
|
||||
if ($selectedAssistantId > 0) {
|
||||
$selectedAssistantValid = self::isActiveAssistant($selectedAssistantId)
|
||||
&& ($effectiveAdminIds === null || in_array($selectedAssistantId, $effectiveAdminIds, true));
|
||||
$effectiveAdminIds = $selectedAssistantValid ? [$selectedAssistantId] : [];
|
||||
}
|
||||
$costAllocationAdminIds = self::costAllocationAdminIds(
|
||||
$effectiveAdminIds,
|
||||
@@ -136,19 +137,20 @@ class FirstVisitConversionLogic
|
||||
(int) $summary['total_open_count']
|
||||
);
|
||||
|
||||
$rankingRows = self::rankingRows($rows);
|
||||
$rankingKind = self::rankingKind($scopeValue, $selectedAssistantId);
|
||||
$rankingRows = self::rankingRows($rows, $rankingKind);
|
||||
// 目前只维护了部门月度目标;本人范围或筛选单个员工时不能拿整个部门目标冒充个人目标。
|
||||
$targetDeptIds = ($scopeValue === DataScopeService::SCOPE_SELF || $selectedAssistantId > 0)
|
||||
? []
|
||||
: self::resolveTargetDeptIds($allowedDeptSet, $selectedDeptIds, $selectedDeptId);
|
||||
$target = self::buildTargetProgress((int) date('Y'), $effectiveAdminIds, $targetDeptIds);
|
||||
|
||||
$selectedDeptName = $selectedDeptId > 0
|
||||
? (string) (Db::name('dept')->where('id', $selectedDeptId)->whereNull('delete_time')->value('name') ?? '')
|
||||
: '';
|
||||
$selectedAssistantName = $selectedAssistantId > 0
|
||||
? (string) (Admin::where('id', $selectedAssistantId)->whereNull('delete_time')->value('name') ?? '')
|
||||
: '';
|
||||
$selectedDeptName = $selectedDeptId > 0 && $deptSelectionValid
|
||||
? (string) (Db::name('dept')->where('id', $selectedDeptId)->whereNull('delete_time')->value('name') ?? '')
|
||||
: '';
|
||||
$selectedAssistantName = $selectedAssistantId > 0 && $selectedAssistantValid
|
||||
? (string) (Admin::where('id', $selectedAssistantId)->whereNull('delete_time')->value('name') ?? '')
|
||||
: '';
|
||||
$selectedMediaChannelName = $selectedMediaChannelCode !== ''
|
||||
? (string) ($selectedMediaChannel['channel_name'] ?? $selectedMediaChannelCode)
|
||||
: '';
|
||||
@@ -159,8 +161,9 @@ class FirstVisitConversionLogic
|
||||
'start_date' => $startDate,
|
||||
'end_date' => $endDate,
|
||||
'generated_at' => date('Y-m-d H:i:s'),
|
||||
'scope_value' => $scopeValue,
|
||||
'scope_label' => DataScopeService::scopeLabel($scopeValue),
|
||||
'scope_value' => $scopeValue,
|
||||
'scope_label' => DataScopeService::scopeLabel($scopeValue),
|
||||
'ranking_kind' => $rankingKind,
|
||||
'selected_dept_name' => $selectedDeptName,
|
||||
'selected_assistant_name' => $selectedAssistantName,
|
||||
'selected_media_channel_code' => $selectedMediaChannelCode,
|
||||
@@ -529,10 +532,33 @@ class FirstVisitConversionLogic
|
||||
), static fn (string $value): bool => $value !== '')));
|
||||
}
|
||||
|
||||
/** @param array<int,array<string,mixed>> $rows @return array<int,array<string,mixed>> */
|
||||
private static function rankingRows(array $rows): array
|
||||
{
|
||||
// lists 里可能同时存在“未绑定/未分配部门”等虚拟根节点。它们会让顶层节点数量
|
||||
/** 根据生效数据范围返回排行榜展示维度,不能把 scope_value 当作角色枚举。 */
|
||||
private static function rankingKind(int $scopeValue, int $selectedAssistantId = 0): string
|
||||
{
|
||||
if ($scopeValue === DataScopeService::SCOPE_SELF || $selectedAssistantId > 0) {
|
||||
return 'hidden';
|
||||
}
|
||||
|
||||
return $scopeValue === DataScopeService::SCOPE_DEPT ? 'member' : 'group';
|
||||
}
|
||||
|
||||
/** @param array<int,array<string,mixed>> $rows @return array<int,array<string,mixed>> */
|
||||
private static function rankingRows(array $rows, string $rankingKind): array
|
||||
{
|
||||
if ($rankingKind === 'hidden') {
|
||||
return [];
|
||||
}
|
||||
|
||||
// “仅本部门”范围使用可见成员维度;更大范围使用当前可见组织根节点的
|
||||
// 直属下级,避免父子汇总同时参与占比。
|
||||
if ($rankingKind === 'member') {
|
||||
$members = [];
|
||||
self::collectRankingMembers($rows, $members);
|
||||
|
||||
return array_values($members);
|
||||
}
|
||||
|
||||
// lists 里可能同时存在“未绑定/未分配部门”等虚拟根节点。它们会让顶层节点数量
|
||||
// 大于 1,导致原逻辑无法展开唯一的真实组织根节点,图表最终只显示医院汇总行。
|
||||
$visibleRows = array_values(array_filter($rows, static function (array $row): bool {
|
||||
return (int) ($row['id'] ?? 0) > 0 && !((bool) ($row['_virtual_bucket'] ?? false));
|
||||
@@ -557,23 +583,59 @@ class FirstVisitConversionLogic
|
||||
$chartRows[] = $row;
|
||||
}
|
||||
|
||||
return $chartRows;
|
||||
}
|
||||
return $chartRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int,array<string,mixed>> $rows
|
||||
* @param array<int,array<string,mixed>> $members
|
||||
*/
|
||||
private static function collectRankingMembers(array $rows, array &$members): void
|
||||
{
|
||||
foreach ($rows as $row) {
|
||||
if ((string) ($row['type'] ?? '') === 'member') {
|
||||
$adminId = (int) ($row['admin_id'] ?? 0);
|
||||
if ($adminId > 0) {
|
||||
$members[$adminId] = $row;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
self::collectRankingMembers(
|
||||
is_array($row['children'] ?? null) ? $row['children'] : [],
|
||||
$members
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/** @param array<int,array<string,mixed>> $rows @return array<int,array<string,mixed>> */
|
||||
private static function topRows(array $rows, string $metric): array
|
||||
{
|
||||
$rows = array_values(array_filter($rows, static fn (array $row): bool => (int) ($row['id'] ?? 0) > 0));
|
||||
usort($rows, static function (array $left, array $right) use ($metric): int {
|
||||
return (float) ($right[$metric] ?? 0) <=> (float) ($left[$metric] ?? 0);
|
||||
});
|
||||
|
||||
return array_map(static fn (array $row): array => [
|
||||
'id' => (int) ($row['id'] ?? 0),
|
||||
'name' => (string) ($row['name'] ?? ''),
|
||||
'value' => round((float) ($row[$metric] ?? 0), 2),
|
||||
], array_slice($rows, 0, 6));
|
||||
}
|
||||
private static function topRows(array $rows, string $metric): array
|
||||
{
|
||||
$rows = array_values(array_filter($rows, static function (array $row): bool {
|
||||
if ((string) ($row['type'] ?? '') === 'member') {
|
||||
return (int) ($row['admin_id'] ?? 0) > 0;
|
||||
}
|
||||
|
||||
return (int) ($row['id'] ?? 0) > 0;
|
||||
}));
|
||||
usort($rows, static function (array $left, array $right) use ($metric): int {
|
||||
$valueCompare = (float) ($right[$metric] ?? 0) <=> (float) ($left[$metric] ?? 0);
|
||||
if ($valueCompare !== 0) {
|
||||
return $valueCompare;
|
||||
}
|
||||
$nameCompare = strnatcasecmp((string) ($left['name'] ?? ''), (string) ($right['name'] ?? ''));
|
||||
if ($nameCompare !== 0) {
|
||||
return $nameCompare;
|
||||
}
|
||||
|
||||
return strcmp((string) ($left['id'] ?? ''), (string) ($right['id'] ?? ''));
|
||||
});
|
||||
|
||||
return array_map(static fn (array $row): array => [
|
||||
'id' => $row['id'] ?? 0,
|
||||
'name' => (string) ($row['name'] ?? ''),
|
||||
'value' => round((float) ($row[$metric] ?? 0), 2),
|
||||
], $rows);
|
||||
}
|
||||
|
||||
/** @param int[]|null $baseVisibleAdminIds @param int[] $selectedDeptIds @return array<int,array{id:int,name:string}> */
|
||||
private static function assistantOptions(?array $baseVisibleAdminIds, array $selectedDeptIds, int $selectedDeptId): array
|
||||
|
||||
Reference in New Issue
Block a user