- 在多个控制器中引入 SettlementPartyEnrichment 服务,以优化代理结算和账单的处理逻辑。 - 更新 AgentSettlementBillIndexController 和 AgentSettlementBillShowController,支持根据账单 ID 和关键字进行查询。 - 在 AgentSettlementPeriodCloseController 中添加对站点管理权限的验证,确保只有具备相应权限的管理员能够关闭账期。 - 在 AgentSettlementPeriodIndexController 中更新账期数据的返回格式,提升数据的完整性和可用性。 - 引入对相对占成比例的支持,增强代理资料的管理能力,确保数据一致性。
191 lines
6.0 KiB
PHP
191 lines
6.0 KiB
PHP
<?php
|
|
|
|
namespace App\Support;
|
|
|
|
use App\Models\AdminUser;
|
|
use App\Models\AgentNode;
|
|
use Illuminate\Database\Query\Builder;
|
|
|
|
/** 代理账单按管理员可访问站点 + 代理子树过滤。 */
|
|
final class AdminAgentSettlementScope
|
|
{
|
|
/**
|
|
* @return list<int>|null null = 不限制子树(超管或未绑定代理)
|
|
*/
|
|
public static function subtreeAgentNodeIds(AdminUser $admin): ?array
|
|
{
|
|
if ($admin->isSuperAdmin()) {
|
|
return null;
|
|
}
|
|
|
|
$actor = AdminAgentScope::primaryAgentNode($admin);
|
|
if ($actor === null) {
|
|
return null;
|
|
}
|
|
|
|
$ids = AgentNode::query()
|
|
->where('path', 'like', $actor->path.'%')
|
|
->pluck('id')
|
|
->map(static fn ($id): int => (int) $id)
|
|
->all();
|
|
|
|
return $ids;
|
|
}
|
|
|
|
public static function applyToPeriodsQuery(Builder $query, AdminUser $admin, string $periodsAlias = 'settlement_periods'): void
|
|
{
|
|
$siteIds = $admin->accessibleAdminSiteIds();
|
|
if ($siteIds === null) {
|
|
return;
|
|
}
|
|
|
|
if ($siteIds === []) {
|
|
$query->whereRaw('0 = 1');
|
|
|
|
return;
|
|
}
|
|
|
|
$query->whereIn($periodsAlias.'.admin_site_id', $siteIds);
|
|
}
|
|
|
|
public static function applyToBillsQuery(Builder $query, AdminUser $admin, string $billsAlias = 'settlement_bills'): void
|
|
{
|
|
$siteIds = $admin->accessibleAdminSiteIds();
|
|
if ($siteIds === null) {
|
|
self::applySubtreeToBillsQuery($query, $admin, $billsAlias);
|
|
|
|
return;
|
|
}
|
|
|
|
if ($siteIds === []) {
|
|
$query->whereRaw('0 = 1');
|
|
|
|
return;
|
|
}
|
|
|
|
$query->whereExists(function (Builder $sub) use ($siteIds, $billsAlias): void {
|
|
$sub->selectRaw('1')
|
|
->from('settlement_periods')
|
|
->whereColumn('settlement_periods.id', $billsAlias.'.settlement_period_id')
|
|
->whereIn('settlement_periods.admin_site_id', $siteIds);
|
|
});
|
|
|
|
self::applySubtreeToBillsQuery($query, $admin, $billsAlias);
|
|
}
|
|
|
|
/** 绑定代理仅见本子树玩家账单 + owner 为本子树节点的代理账单。 */
|
|
public static function applySubtreeToBillsQuery(Builder $query, AdminUser $admin, string $billsAlias = 'settlement_bills'): void
|
|
{
|
|
$subtreeIds = self::subtreeAgentNodeIds($admin);
|
|
if ($subtreeIds === null) {
|
|
return;
|
|
}
|
|
|
|
if ($subtreeIds === []) {
|
|
$query->whereRaw('0 = 1');
|
|
|
|
return;
|
|
}
|
|
|
|
$query->where(function (Builder $outer) use ($billsAlias, $subtreeIds): void {
|
|
$outer->where(function (Builder $player) use ($billsAlias, $subtreeIds): void {
|
|
$player->where($billsAlias.'.owner_type', 'player')
|
|
->whereExists(function (Builder $exists) use ($billsAlias, $subtreeIds): void {
|
|
$exists->selectRaw('1')
|
|
->from('players')
|
|
->whereColumn('players.id', $billsAlias.'.owner_id')
|
|
->whereIn('players.agent_node_id', $subtreeIds);
|
|
});
|
|
})->orWhere(function (Builder $agent) use ($billsAlias, $subtreeIds): void {
|
|
$agent->where($billsAlias.'.owner_type', 'agent')
|
|
->whereIn($billsAlias.'.owner_id', $subtreeIds);
|
|
});
|
|
});
|
|
}
|
|
|
|
public static function periodAccessible(AdminUser $admin, int $settlementPeriodId): bool
|
|
{
|
|
$siteIds = $admin->accessibleAdminSiteIds();
|
|
if ($siteIds === null) {
|
|
return true;
|
|
}
|
|
|
|
if ($siteIds === []) {
|
|
return false;
|
|
}
|
|
|
|
return \Illuminate\Support\Facades\DB::table('settlement_periods')
|
|
->where('id', $settlementPeriodId)
|
|
->whereIn('admin_site_id', $siteIds)
|
|
->exists();
|
|
}
|
|
|
|
public static function siteAccessible(AdminUser $admin, int $adminSiteId): bool
|
|
{
|
|
$siteIds = $admin->accessibleAdminSiteIds();
|
|
if ($siteIds === null) {
|
|
return true;
|
|
}
|
|
|
|
return in_array($adminSiteId, $siteIds, true);
|
|
}
|
|
|
|
/** 绑定代理账号不可开/关全站账期(仅站点财务或超管)。 */
|
|
public static function canManageSitePeriods(AdminUser $admin): bool
|
|
{
|
|
if ($admin->isSuperAdmin()) {
|
|
return true;
|
|
}
|
|
|
|
return AdminAgentScope::primaryAgentNode($admin) === null;
|
|
}
|
|
|
|
public static function assertCanManageSitePeriods(AdminUser $admin): void
|
|
{
|
|
if (! self::canManageSitePeriods($admin)) {
|
|
abort(403, 'agent_bound_cannot_manage_periods');
|
|
}
|
|
}
|
|
|
|
public static function billAccessible(AdminUser $admin, int $settlementBillId): bool
|
|
{
|
|
$siteIds = $admin->accessibleAdminSiteIds();
|
|
if ($siteIds !== null && $siteIds === []) {
|
|
return false;
|
|
}
|
|
|
|
$bill = \Illuminate\Support\Facades\DB::table('settlement_bills as sb')
|
|
->join('settlement_periods as sp', 'sp.id', '=', 'sb.settlement_period_id')
|
|
->where('sb.id', $settlementBillId)
|
|
->select(['sb.owner_type', 'sb.owner_id', 'sp.admin_site_id'])
|
|
->first();
|
|
|
|
if ($bill === null) {
|
|
return false;
|
|
}
|
|
|
|
if ($siteIds !== null && ! in_array((int) $bill->admin_site_id, $siteIds, true)) {
|
|
return false;
|
|
}
|
|
|
|
$subtreeIds = self::subtreeAgentNodeIds($admin);
|
|
if ($subtreeIds === null) {
|
|
return true;
|
|
}
|
|
|
|
if ((string) $bill->owner_type === 'player') {
|
|
$agentNodeId = (int) (\Illuminate\Support\Facades\DB::table('players')
|
|
->where('id', (int) $bill->owner_id)
|
|
->value('agent_node_id') ?? 0);
|
|
|
|
return $agentNodeId > 0 && in_array($agentNodeId, $subtreeIds, true);
|
|
}
|
|
|
|
if ((string) $bill->owner_type === 'agent') {
|
|
return in_array((int) $bill->owner_id, $subtreeIds, true);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|