Files
lotteryLaravel/app/Support/AdminAgentScope.php
kang 0841fbed32 feat: 增强管理员功能与数据处理
- 在多个控制器中引入 agent_node_id,以支持基于代理节点的权限和数据过滤。
- 更新 AdminRole 和 AdminUser 模型,新增角色范围和代理节点相关功能,提升角色管理的灵活性。
- 在请求验证中添加 agent_node_id 字段,确保 API 接口支持代理节点的相关操作。
- 优化 LotterySettings 服务,支持批量写入设置,提升配置管理的效率。
- 更新仪表板和报告服务,增强数据统计功能,确保管理员能够获取更全面的统计信息。
2026-06-02 14:36:58 +08:00

168 lines
4.2 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Support;
use App\Models\AdminUser;
use App\Models\AgentNode;
use App\Models\Player;
use Illuminate\Database\Eloquent\Builder;
/**
* 代理子树数据范围P1节点访问P2 起叠加玩家 agent_node_id
*/
final class AdminAgentScope
{
public static function primaryAgentNode(AdminUser $admin): ?AgentNode
{
if ($admin->isSuperAdmin()) {
return null;
}
$agentId = $admin->primaryAgentNodeId();
if ($agentId === null) {
return null;
}
return AgentNode::query()->find($agentId);
}
public static function nodeVisibleTo(AdminUser $admin, AgentNode $node): bool
{
if ($admin->isSuperAdmin()) {
return true;
}
$actor = self::primaryAgentNode($admin);
if ($actor === null) {
return false;
}
return $node->isSameOrDescendantOf($actor);
}
public static function playerAccessible(AdminUser $admin, Player $player): bool
{
if ($admin->isSuperAdmin()) {
return true;
}
$actor = self::primaryAgentNode($admin);
if ($actor === null) {
return false;
}
if ($player->agent_node_id === null) {
return false;
}
$playerAgent = AgentNode::query()->find((int) $player->agent_node_id);
if ($playerAgent === null) {
return false;
}
return $playerAgent->isSameOrDescendantOf($actor);
}
public static function nodeManageableBy(AdminUser $admin, AgentNode $node): bool
{
if ($admin->isSuperAdmin()) {
return true;
}
if (! $admin->hasAdminPermission('prd.agent.manage')) {
return false;
}
return self::nodeVisibleTo($admin, $node);
}
/**
* @return Builder<AgentNode>
*/
public static function visibleNodesQuery(AdminUser $admin, int $adminSiteId): Builder
{
$query = AgentNode::query()
->where('admin_site_id', $adminSiteId)
->orderBy('path');
if ($admin->isSuperAdmin()) {
return $query;
}
$actor = self::primaryAgentNode($admin);
if ($actor === null || (int) $actor->admin_site_id !== $adminSiteId) {
return $query->whereRaw('0 = 1');
}
return $query->where('path', 'like', $actor->path.'%');
}
/**
* 玩家必须落在当前代理子树agent_node_id 必填,由迁移回填根代理)。
*
* @param Builder<Player> $query
*/
public static function applyToPlayerQuery(Builder $query, AdminUser $admin): void
{
if ($admin->isSuperAdmin()) {
return;
}
$actor = self::primaryAgentNode($admin);
if ($actor === null) {
$query->whereRaw('0 = 1');
return;
}
if (! \Illuminate\Support\Facades\Schema::hasColumn('players', 'agent_node_id')) {
return;
}
$subtreeIds = AgentNode::query()
->where('path', 'like', $actor->path.'%')
->pluck('id')
->all();
if ($subtreeIds === []) {
$query->whereRaw('0 = 1');
return;
}
$query->whereIn('agent_node_id', $subtreeIds);
}
/**
* 在已有站点/代理范围上,再按指定节点子树收窄(超管筛选用)。
*
* @param Builder<Player> $query
*/
public static function applyRequestedAgentNodeFilter(Builder $query, AdminUser $admin, int $agentNodeId): void
{
$node = AgentNode::query()->find($agentNodeId);
if ($node === null || ! self::nodeVisibleTo($admin, $node)) {
$query->whereRaw('0 = 1');
return;
}
if (! \Illuminate\Support\Facades\Schema::hasColumn('players', 'agent_node_id')) {
return;
}
$subtreeIds = AgentNode::query()
->where('path', 'like', $node->path.'%')
->pluck('id')
->all();
if ($subtreeIds === []) {
$query->whereRaw('0 = 1');
return;
}
$query->whereIn('agent_node_id', $subtreeIds);
}
}