更新
This commit is contained in:
@@ -144,7 +144,7 @@ class FirstVisitConversionLogic
|
||||
}
|
||||
unset($row);
|
||||
}
|
||||
return [
|
||||
return self::withDeletedFansVisibility([
|
||||
'meta' => [
|
||||
'time_type' => $timeType,
|
||||
'time_label' => $timeLabel,
|
||||
@@ -178,7 +178,7 @@ class FirstVisitConversionLogic
|
||||
],
|
||||
'rows' => $rows,
|
||||
'target' => $target,
|
||||
];
|
||||
], $adminInfo);
|
||||
}
|
||||
|
||||
/** @return array<string,mixed> */
|
||||
@@ -190,14 +190,14 @@ class FirstVisitConversionLogic
|
||||
);
|
||||
$pageNo = max(1, (int) ($params['page_no'] ?? 1));
|
||||
$pageSize = max(1, min(100, (int) ($params['page_size'] ?? 20)));
|
||||
$empty = [
|
||||
$empty = self::withDeletedFansVisibility([
|
||||
'lists' => [],
|
||||
'count' => 0,
|
||||
'page_no' => $pageNo,
|
||||
'page_size' => $pageSize,
|
||||
'date_range' => [$context['start_date'], $context['end_date']],
|
||||
'entity' => null,
|
||||
];
|
||||
], $adminInfo, true);
|
||||
|
||||
$entityType = strtolower(trim((string) ($params['entity_type'] ?? '')));
|
||||
if (!in_array($entityType, ['dept', 'member'], true)) {
|
||||
@@ -253,9 +253,54 @@ class FirstVisitConversionLogic
|
||||
];
|
||||
unset($result['deleted_count']);
|
||||
|
||||
return self::withDeletedFansVisibility($result, $adminInfo, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除客户统计是账号专属能力,与root、角色、财务权限和DataScope无关。
|
||||
* adminInfo由认证token缓存提供;缺失账号时拒绝,不能从HTTP参数补齐或标准化账号。
|
||||
*/
|
||||
private static function canViewDeletedFans(array $adminInfo): bool
|
||||
{
|
||||
return ($adminInfo['account'] ?? null) === 'admin';
|
||||
}
|
||||
|
||||
/**
|
||||
* 只裁剪本页响应,不改变通用统计口径、加粉客户集合、排序或分页。
|
||||
* 对整个响应递归处理,避免嵌套成员、排名或未来新增位置泄露同一敏感指标。
|
||||
*/
|
||||
private static function withDeletedFansVisibility(array $result, array $adminInfo, bool $detail = false): array
|
||||
{
|
||||
$canView = self::canViewDeletedFans($adminInfo);
|
||||
if (!$canView) {
|
||||
$fields = $detail
|
||||
? ['deleted_fans_count', 'deleted_count', 'is_deleted', 'delete_time']
|
||||
: ['deleted_fans_count', 'deleted_count'];
|
||||
$result = self::removeDeletedFansFields($result, $fields);
|
||||
}
|
||||
if ($detail) {
|
||||
$result['can_view_deleted_fans'] = $canView;
|
||||
} else {
|
||||
$result['meta']['can_view_deleted_fans'] = $canView;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/** @param string[] $fields */
|
||||
private static function removeDeletedFansFields(array $value, array $fields): array
|
||||
{
|
||||
foreach ($fields as $field) {
|
||||
unset($value[$field]);
|
||||
}
|
||||
foreach ($value as &$item) {
|
||||
if (is_array($item)) {
|
||||
$item = self::removeDeletedFansFields($item, $fields);
|
||||
}
|
||||
}
|
||||
unset($item);
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve only the clicked entity and its authorized target range. This is
|
||||
* deliberately structural: it avoids recomputing all overview metrics,
|
||||
|
||||
Reference in New Issue
Block a user