Files
lotteryLaravel/app/Support/AgentNodePresenter.php

151 lines
4.9 KiB
PHP

<?php
namespace App\Support;
use App\Models\AdminSite;
use App\Models\AgentNode;
use App\Models\AgentProfile;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
final class AgentNodePresenter
{
/**
* @return array{
* id: int,
* admin_site_id: int,
* parent_id: ?int,
* path: string,
* depth: int,
* code: string,
* name: string,
* status: int,
* is_root: bool,
* username: ?string,
* email: ?string
* }
*/
/**
* @return array<string, mixed>
*/
public static function profileSummary(AgentProfile $profile): array
{
return [
'total_share_rate' => (float) $profile->total_share_rate,
'credit_limit' => (int) $profile->credit_limit,
'allocated_credit' => (int) $profile->allocated_credit,
'used_credit' => (int) $profile->used_credit,
'available_credit' => max(0, (int) $profile->credit_limit - (int) $profile->allocated_credit),
'rebate_limit' => round((float) $profile->rebate_limit * 100, 4),
'default_player_rebate' => round((float) $profile->default_player_rebate * 100, 4),
];
}
public static function item(AgentNode $node, ?AgentProfile $profile = null): array
{
$account = DB::table('admin_user_agents as aua')
->join('admin_users as au', 'au.id', '=', 'aua.admin_user_id')
->where('aua.agent_node_id', $node->id)
->orderByDesc('aua.is_primary')
->orderBy('aua.admin_user_id')
->select('au.username', 'au.email')
->first();
$siteCode = AdminSite::query()->where('id', $node->admin_site_id)->value('code');
$payload = [
'id' => (int) $node->id,
'admin_site_id' => (int) $node->admin_site_id,
'site_code' => $siteCode !== null ? (string) $siteCode : null,
'parent_id' => $node->parent_id !== null ? (int) $node->parent_id : null,
'path' => (string) $node->path,
'depth' => (int) $node->depth,
'code' => (string) $node->code,
'name' => (string) $node->name,
'status' => (int) $node->status,
'is_root' => $node->isRoot(),
'is_line_root' => $node->isRoot(),
'username' => $account?->username !== null ? (string) $account->username : null,
'email' => $account?->email !== null ? (string) $account->email : null,
];
if ($profile !== null) {
$payload['profile_summary'] = self::profileSummary($profile);
}
return $payload;
}
/**
* @param iterable<AgentNode> $nodes
* @return list<array<string, mixed>>
*/
public static function tree(iterable $nodes): array
{
$nodeList = $nodes instanceof Collection ? $nodes : collect($nodes);
$profiles = AgentProfile::query()
->whereIn('agent_node_id', $nodeList->pluck('id'))
->get()
->keyBy('agent_node_id');
$items = [];
$byParent = [];
foreach ($nodeList as $node) {
$profile = $profiles->get($node->id);
$row = self::item($node, $profile instanceof AgentProfile ? $profile : null);
$row['children'] = [];
$items[(int) $node->id] = $row;
$parentKey = $node->parent_id !== null ? (int) $node->parent_id : 0;
$byParent[$parentKey][] = (int) $node->id;
}
$attach = static function (int $id) use (&$attach, &$items, $byParent): array {
$node = $items[$id];
foreach ($byParent[$id] ?? [] as $childId) {
$node['children'][] = $attach($childId);
}
return $node;
};
$ids = array_keys($items);
$rootIds = [];
foreach ($items as $id => $row) {
$parentId = $row['parent_id'];
if ($parentId === null || ! in_array((int) $parentId, $ids, true)) {
$rootIds[] = (int) $id;
}
}
$roots = [];
foreach ($rootIds as $rootId) {
$roots[] = $attach($rootId);
}
return $roots;
}
/**
* @param iterable<AgentNode> $nodes
* @return list<array<string, mixed>>
*/
public static function list(iterable $nodes): array
{
$nodeList = $nodes instanceof Collection ? $nodes : collect($nodes);
$profiles = AgentProfile::query()
->whereIn('agent_node_id', $nodeList->pluck('id'))
->get()
->keyBy('agent_node_id');
return $nodeList
->map(function (AgentNode $node) use ($profiles): array {
$profile = $profiles->get($node->id);
return self::item($node, $profile instanceof AgentProfile ? $profile : null);
})
->values()
->all();
}
}