giftcon_dev/app/Services/Admin/Log/MemberAccountLogService.php

161 lines
5.0 KiB
PHP

<?php
namespace App\Services\Admin\Log;
use App\Repositories\Admin\Log\MemberAccountLogRepository;
final class MemberAccountLogService
{
public function __construct(
private readonly MemberAccountLogRepository $repo,
) {}
public function indexData(array $query = []): array
{
$filters = [
'date_from' => $this->safeDate($query['date_from'] ?? ''),
'date_to' => $this->safeDate($query['date_to'] ?? ''),
'mem_no' => $this->safeInt($query['mem_no'] ?? null),
'bank_code' => $this->safeStr($query['bank_code'] ?? '', 10),
'status' => $this->safeStr($query['status'] ?? '', 10), // ok/fail/200/520...
'account' => $this->safeStr($query['account'] ?? '', 40),
'name' => $this->safeStr($query['name'] ?? '', 40),
'q' => $this->safeStr($query['q'] ?? '', 120),
];
if ($filters['date_from'] && $filters['date_to']) {
if (strcmp($filters['date_from'], $filters['date_to']) > 0) {
[$filters['date_from'], $filters['date_to']] = [$filters['date_to'], $filters['date_from']];
}
}
$page = $this->repo->paginate($filters, 30);
$items = [];
foreach ($page->items() as $it) {
$r = is_array($it) ? $it : (array)$it;
$reqRaw = (string)($r['request_data'] ?? '');
$resRaw = (string)($r['result_data'] ?? '');
$req = $this->decodeJson($reqRaw);
$res = $this->decodeJson($resRaw);
$memNo = (int)($r['mem_no'] ?? 0);
$account = trim((string)($req['account'] ?? ''));
$accountMasked = $this->maskAccount($account);
$bankCode = trim((string)($req['bank_code'] ?? ''));
$proType = trim((string)($req['account_protype'] ?? ''));
$name = trim((string)($req['mam_accountname'] ?? ''));
$status = (int)($res['status'] ?? 0);
$ok = ($status === 200);
$depositor = trim((string)($res['depositor'] ?? ''));
$errCode = trim((string)($res['error_code'] ?? ''));
$errMsg = trim((string)($res['error_message'] ?? ''));
// JSON pretty (api_key는 마스킹)
$reqPretty = $this->prettyJson($this->maskApiKey($req), $reqRaw);
$resPretty = $this->prettyJson($res, $resRaw);
$items[] = array_merge($r, [
'mem_link' => $memNo > 0 ? ('/members/' . $memNo) : null,
'account' => $account,
'account_masked' => $accountMasked,
'bank_code' => $bankCode,
'account_protype' => $proType,
'mam_accountname' => $name,
'status_int' => $status,
'status_label' => $ok ? 'SUCCESS' : 'FAIL',
'status_badge' => $ok ? 'badge--ok' : 'badge--bad',
'depositor' => $depositor,
'error_code' => $errCode,
'error_message' => $errMsg,
'request_pretty' => $reqPretty,
'result_pretty' => $resPretty,
]);
}
return [
'filters' => $filters,
'page' => $page,
'items' => $items,
];
}
private function decodeJson(string $raw): array
{
$raw = trim($raw);
if ($raw === '') return [];
$arr = json_decode($raw, true);
return is_array($arr) ? $arr : [];
}
private function prettyJson(array $arr, string $fallbackRaw): string
{
if (!empty($arr)) {
return (string)json_encode($arr, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}
return $fallbackRaw;
}
private function maskApiKey(array $req): array
{
if (!isset($req['api_key'])) return $req;
$v = (string)$req['api_key'];
$v = trim($v);
if ($v === '') return $req;
// 앞 4 + ... + 뒤 4
$head = mb_substr($v, 0, 4);
$tail = mb_substr($v, -4);
$req['api_key'] = $head . '…' . $tail;
return $req;
}
private function maskAccount(string $account): string
{
$s = trim($account);
if ($s === '') return '';
$len = mb_strlen($s);
if ($len <= 4) return $s;
return str_repeat('*', max(0, $len - 4)) . mb_substr($s, -4);
}
private function safeStr(mixed $v, int $max): string
{
$s = trim((string)$v);
if ($s === '') return '';
if (mb_strlen($s) > $max) $s = mb_substr($s, 0, $max);
return $s;
}
private function safeInt(mixed $v): ?int
{
if ($v === null || $v === '') return null;
if (!is_numeric($v)) return null;
$n = (int)$v;
return $n >= 0 ? $n : null;
}
private function safeDate(mixed $v): ?string
{
$s = trim((string)$v);
if ($s === '') return null;
return preg_match('/^\d{4}-\d{2}-\d{2}$/', $s) ? $s : null;
}
}