Files
lotteryLaravel/app/Support/AdminSiteScope.php
kang e3ffffad9c feat: 增强代理和玩家管理功能
- 在 SyncAdminAuthorizationCommand 中新增对代理线路和结算菜单操作的同步功能,确保缺失的菜单操作行能够被创建。
- 更新多个控制器中的权限检查逻辑,使用 hasPermissionCode 替代原有的权限验证方式,提升权限管理的灵活性。
- 在 AdminPlayerStoreController 中引入对玩家创建能力的验证,确保只有具备相应权限的管理员能够创建玩家。
- 更新请求验证逻辑,新增 credit_limit、rebate_rate 和 extra_rebate_rate 字段,以支持更细粒度的玩家管理。
- 在 AdminUser 和 AgentNode 模型中增强角色与用户的权限管理功能,支持更细粒度的权限控制。
2026-06-04 09:17:47 +08:00

188 lines
5.4 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\AdminSite;
use App\Models\AdminUser;
use App\Models\Player;
use App\Lottery\ErrorCode;
use App\Support\ApiMessage;
use App\Support\ApiResponse;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
/**
* 后台站点数据范围:非超管仅可访问 {@see AdminUser::accessibleAdminSiteIds()} 绑定站点。
*
* 对应产品「site_only / site_all_data」运行时以 admin_user_site_roles 为准(非已废弃的 admin_data_scopes 表)。
*/
final class AdminSiteScope
{
/**
* @return list<string>|null `null` 表示不限制(超管)
*/
public static function accessibleSiteCodes(AdminUser $admin): ?array
{
$siteIds = $admin->accessibleAdminSiteIds();
if ($siteIds === null) {
return null;
}
if ($siteIds === []) {
return [];
}
return AdminSite::query()
->whereIn('id', $siteIds)
->orderBy('code')
->pluck('code')
->map(static fn ($code): string => (string) $code)
->values()
->all();
}
public static function siteCodeAllowed(AdminUser $admin, string $siteCode): bool
{
$allowed = self::accessibleSiteCodes($admin);
if ($allowed === null) {
return true;
}
return in_array($siteCode, $allowed, true);
}
public static function siteIdAllowed(AdminUser $admin, int $siteId): bool
{
$siteIds = $admin->accessibleAdminSiteIds();
if ($siteIds === null) {
return true;
}
return in_array($siteId, $siteIds, true);
}
public static function playerAccessible(AdminUser $admin, Player $player): bool
{
if (! self::siteCodeAllowed($admin, (string) $player->site_code)) {
return false;
}
return AdminAgentScope::playerAccessible($admin, $player);
}
/**
* @param Builder<Player> $query
*/
public static function applyToPlayerQuery(Builder $query, AdminUser $admin): void
{
$codes = self::accessibleSiteCodes($admin);
if ($codes === null) {
AdminAgentScope::applyToPlayerQuery($query, $admin);
return;
}
if ($codes === []) {
$query->whereRaw('0 = 1');
return;
}
$query->whereIn('site_code', $codes);
if (AdminAgentScope::primaryAgentNode($admin) !== null) {
AdminAgentScope::applyToPlayerQuery($query, $admin);
}
}
/**
* 在站点范围基础上,可选按请求的 site_code 再收窄。
*
* @param Builder<Player> $query
*/
public static function applyPlayerFilters(
Builder $query,
AdminUser $admin,
?string $requestedSiteCode,
?int $requestedAgentNodeId = null,
): void {
self::applyToPlayerQuery($query, $admin);
$siteCode = is_string($requestedSiteCode) ? trim($requestedSiteCode) : '';
if ($siteCode !== '') {
if (! self::siteCodeAllowed($admin, $siteCode)) {
$query->whereRaw('0 = 1');
return;
}
$query->where('site_code', $siteCode);
}
if ($requestedAgentNodeId !== null && $requestedAgentNodeId > 0) {
AdminAgentScope::applyRequestedAgentNodeFilter($query, $admin, $requestedAgentNodeId);
}
}
/**
* @param Builder<mixed> $query
*/
public static function applyViaPlayerRelation(Builder $query, AdminUser $admin, string $relation = 'player'): void
{
if ($admin->isSuperAdmin()) {
return;
}
$query->whereHas($relation, static function (Builder $playerQuery) use ($admin): void {
self::applyToPlayerQuery($playerQuery, $admin);
});
}
/**
* @param Builder<mixed> $query
*/
public static function applyViaPlayerRelationWithSiteCode(
Builder $query,
AdminUser $admin,
?string $requestedSiteCode,
string $relation = 'player',
?int $requestedAgentNodeId = null,
): void {
if ($admin->isSuperAdmin()) {
$siteCode = is_string($requestedSiteCode) ? trim($requestedSiteCode) : '';
$agentNodeId = $requestedAgentNodeId !== null && $requestedAgentNodeId > 0
? $requestedAgentNodeId
: null;
if ($siteCode === '' && $agentNodeId === null) {
return;
}
$query->whereHas($relation, static function (Builder $playerQuery) use ($admin, $siteCode, $agentNodeId): void {
self::applyPlayerFilters($playerQuery, $admin, $siteCode !== '' ? $siteCode : null, $agentNodeId);
});
return;
}
$query->whereHas($relation, static function (Builder $playerQuery) use ($admin, $requestedSiteCode, $requestedAgentNodeId): void {
self::applyPlayerFilters($playerQuery, $admin, $requestedSiteCode, $requestedAgentNodeId);
});
}
public static function denyUnlessPlayerAccessible(AdminUser $admin, Player $player): ?JsonResponse
{
if (! self::playerAccessible($admin, $player)) {
return ApiMessage::errorResponse(
request(),
'admin.site_player_access_denied',
ErrorCode::AdminForbidden->value,
null,
403,
);
}
return null;
}
}