feat: enhance agent management and validation logic
- Updated AGENTS.md to clarify agent account restrictions and permissions. - Implemented checks in AgentNodeAdminUserStoreController and AgentNodeRoleStoreController to restrict admin user and role creation to the agent's own node. - Enhanced validation in AdminPlayerStoreController and AdminPlayerUpdateController to enforce credit limit and rebate rate rules based on player funding mode. - Refactored various request classes to utilize shared admin account field rules for consistency. - Improved error handling in services related to credit allocation and rebate limits to ensure proper validation and messaging.
This commit is contained in:
@@ -7,7 +7,6 @@ namespace App\Support;
|
||||
use App\Lottery\ErrorCode;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Lang;
|
||||
|
||||
/**
|
||||
* API 响应文案(zh / en / ne),供 msg 字段与 RuntimeException reason 翻译。
|
||||
@@ -15,7 +14,7 @@ use Illuminate\Support\Facades\Lang;
|
||||
final class ApiMessage
|
||||
{
|
||||
/** @var list<string> */
|
||||
private const LOOKUP_PREFIXES = ['api.reasons.', 'api.', 'admin.', 'jackpot.', 'wallet.'];
|
||||
private const LOOKUP_PREFIXES = ['api.reasons.', 'api.', 'admin.', 'sso.', 'jackpot.', 'wallet.'];
|
||||
|
||||
public static function locale(?Request $request = null): string
|
||||
{
|
||||
@@ -33,16 +32,18 @@ final class ApiMessage
|
||||
*/
|
||||
public static function get(?Request $request, string $key, array $replace = []): string
|
||||
{
|
||||
$locale = self::locale($request);
|
||||
$fallback = (string) config('lottery.locales.fallback', 'en');
|
||||
$key = trim($key);
|
||||
if ($key === '') {
|
||||
return self::translateKey($request, 'api.client_error', $replace);
|
||||
}
|
||||
|
||||
foreach ([$locale, $fallback] as $tryLocale) {
|
||||
foreach (self::candidateKeys($key) as $fullKey) {
|
||||
$msg = trans($fullKey, $replace, $tryLocale);
|
||||
if ($msg !== $fullKey && $msg !== '') {
|
||||
return $msg;
|
||||
}
|
||||
}
|
||||
if (preg_match('/\p{Han}/u', $key) === 1) {
|
||||
return $key;
|
||||
}
|
||||
|
||||
$resolved = self::translateKey($request, $key, $replace);
|
||||
if ($resolved !== null) {
|
||||
return $resolved;
|
||||
}
|
||||
|
||||
return $key;
|
||||
@@ -57,15 +58,69 @@ final class ApiMessage
|
||||
{
|
||||
$reasonKey = trim($reasonKey);
|
||||
if ($reasonKey === '') {
|
||||
return self::get($request, 'client_error', $replace);
|
||||
return self::translateKey($request, 'api.client_error', $replace)
|
||||
?? trans('api.client_error', [], self::locale($request));
|
||||
}
|
||||
|
||||
$translated = self::get($request, $reasonKey, $replace);
|
||||
if ($translated !== $reasonKey) {
|
||||
return $translated;
|
||||
if (preg_match('/\p{Han}/u', $reasonKey) === 1) {
|
||||
return $reasonKey;
|
||||
}
|
||||
|
||||
return self::get($request, 'client_error', $replace);
|
||||
$resolved = self::translateKey($request, $reasonKey, $replace);
|
||||
if ($resolved !== null) {
|
||||
return $resolved;
|
||||
}
|
||||
|
||||
$resolved = self::translateBusinessKey($request, $reasonKey, $replace);
|
||||
if ($resolved !== null) {
|
||||
return $resolved;
|
||||
}
|
||||
|
||||
return $reasonKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* abort() / HttpException 的 message 转为用户可见文案。
|
||||
*/
|
||||
public static function httpExceptionMessage(?Request $request, int $status, string $rawMessage): string
|
||||
{
|
||||
$trimmed = trim($rawMessage);
|
||||
if ($trimmed !== '') {
|
||||
if (preg_match('/\p{Han}/u', $trimmed) === 1) {
|
||||
return $trimmed;
|
||||
}
|
||||
|
||||
if (str_starts_with($trimmed, 'admin.')) {
|
||||
return self::get($request, $trimmed);
|
||||
}
|
||||
|
||||
$resolved = self::translateKey($request, $trimmed);
|
||||
if ($resolved !== null) {
|
||||
return $resolved;
|
||||
}
|
||||
|
||||
$resolved = self::translateBusinessKey($request, $trimmed);
|
||||
if ($resolved !== null) {
|
||||
return $resolved;
|
||||
}
|
||||
|
||||
if (str_contains($trimmed, ' ')) {
|
||||
return $trimmed;
|
||||
}
|
||||
|
||||
return $trimmed;
|
||||
}
|
||||
|
||||
return match ($status) {
|
||||
401 => self::get($request, 'admin.unauthenticated'),
|
||||
403 => self::get($request, 'admin.permission_denied'),
|
||||
404 => self::get($request, 'api.not_found'),
|
||||
422 => self::get($request, 'api.validation_failed'),
|
||||
429 => self::get($request, 'api.too_many_requests'),
|
||||
default => $status >= 500
|
||||
? self::get($request, 'api.server_error')
|
||||
: self::get($request, 'api.client_error'),
|
||||
};
|
||||
}
|
||||
|
||||
public static function successMessage(?Request $request = null): string
|
||||
@@ -109,6 +164,54 @@ final class ApiMessage
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, string|int|float> $replace
|
||||
*/
|
||||
private static function translateKey(?Request $request, string $key, array $replace = []): ?string
|
||||
{
|
||||
$locale = self::locale($request);
|
||||
$fallback = (string) config('lottery.locales.fallback', 'en');
|
||||
|
||||
foreach ([$locale, $fallback] as $tryLocale) {
|
||||
foreach (self::candidateKeys($key) as $fullKey) {
|
||||
$msg = trans($fullKey, $replace, $tryLocale);
|
||||
if ($msg !== $fullKey && $msg !== '') {
|
||||
return $msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, string|int|float> $replace
|
||||
*/
|
||||
private static function translateBusinessKey(?Request $request, string $key, array $replace = []): ?string
|
||||
{
|
||||
$locale = self::locale($request);
|
||||
$fallback = (string) config('lottery.locales.fallback', 'en');
|
||||
$candidates = array_values(array_unique([
|
||||
$key,
|
||||
str_contains($key, '.') ? substr($key, strrpos($key, '.') + 1) : $key,
|
||||
]));
|
||||
|
||||
foreach ([$locale, $fallback] as $tryLocale) {
|
||||
foreach ($candidates as $candidate) {
|
||||
if ($candidate === '') {
|
||||
continue;
|
||||
}
|
||||
$businessKey = 'validation.business.'.$candidate;
|
||||
$msg = trans($businessKey, $replace, $tryLocale);
|
||||
if ($msg !== $businessKey) {
|
||||
return $msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<string>
|
||||
*/
|
||||
@@ -124,6 +227,7 @@ final class ApiMessage
|
||||
$key,
|
||||
'api.'.$key,
|
||||
'admin.'.$key,
|
||||
'sso.'.$key,
|
||||
'jackpot.'.$key,
|
||||
'wallet.'.$key,
|
||||
'api.reasons.'.$key,
|
||||
|
||||
Reference in New Issue
Block a user