doge 9 godzin temu
rodzic
commit
65e313eccc

+ 21 - 6
app/Http/Controllers/admin/Agent.php

@@ -21,6 +21,7 @@ use Illuminate\Validation\Rule;
 use Illuminate\Support\Facades\DB;
 use App\Rules\DecimalNumber;
 use App\Constants\Util;
+use App\Services\ThirdGameBalanceService;
 
 class Agent extends AgentApiController
 {
@@ -114,22 +115,36 @@ class Agent extends AgentApiController
         });
     }
 
-    public function quota(Request $request)
+    public function quota(Request $request, ThirdGameBalanceService $thirdGame)
     {
-        return $this->execute(function () use ($request) {
-            $data = $request->validate(['agent_id' => ['required', 'integer', 'exists:agents,id']]);
+        return $this->execute(function () use ($request, $thirdGame) {
+            $data = $request->validate([
+                'agent_id' => ['required', 'integer', 'exists:agents,id'],
+                'refresh' => ['nullable', 'boolean'],
+            ]);
             $agent = AgentModel::query()->findOrFail($data['agent_id']);
+            $provider = $thirdGame->agentBalances((int) $agent->id, $request->boolean('refresh'));
+            if (empty($provider['ok'])) {
+                throw new \RuntimeException((string) ($provider['msg'] ?? '三方平台余额查询失败'));
+            }
+            $balances = is_array($provider['balances'] ?? null) ? $provider['balances'] : [];
             $platforms = EgameItem::query()->where('item_type', EgameItem::TYPE_PLATFORM)->where('game_type', 0)
                 ->where('status', EgameItem::STATUS_ENABLED)->orderByDesc('sort')->get(['plat_type', 'name', 'logo'])
-                ->map(function (EgameItem $platform) {
+                ->map(function (EgameItem $platform) use ($balances) {
+                    $key = strtolower((string) $platform->plat_type);
                     $platform->logo = Util::ensureUrl($platform->logo);
+                    $platform->setAttribute('balance', $balances[$key] ?? '0.0000000000');
+                    $platform->setAttribute('account_opened', array_key_exists($key, $balances) ? 1 : 0);
                     return $platform;
                 });
             return [
+                'agent_id' => (int) $agent->id,
+                'player_id' => (string) $provider['player_id'],
+                'currency' => (string) $provider['currency'],
                 'balance' => (string) $agent->balance,
                 'frozen_balance' => (string) $agent->frozen_balance,
-                'quota_mode' => 'internal',
-                'provider_wallet_supported' => false,
+                'quota_mode' => 'provider',
+                'provider_wallet_supported' => true,
                 'platforms' => $platforms,
             ];
         });

+ 56 - 0
app/Services/ThirdGameBalanceService.php

@@ -155,6 +155,44 @@ class ThirdGameBalanceService
         return 'u' . $userId;
     }
 
+    public function agentPlayerId(int $agentId): string
+    {
+        if ($agentId <= 0) {
+            throw new \InvalidArgumentException('agents.id 必须是正整数');
+        }
+        return 'a' . $agentId;
+    }
+
+    /**
+     * 查询代理自己在各三方游戏平台的余额。玩家不存在时返回空 balances,调用方按平台补 0。
+     */
+    public function agentBalances(int $agentId, bool $forceRefresh = false): array
+    {
+        $identity = 'agent:' . $agentId;
+        $playerId = $this->agentPlayerId($agentId);
+        if (!$forceRefresh) {
+            $cached = Cache::get($this->detailCacheKey($identity));
+            if (is_array($cached)) {
+                return $this->agentBalanceResult($agentId, $playerId, $cached);
+            }
+        }
+
+        $response = $this->request('/api/server/balanceAll', [
+            'playerId' => $playerId,
+            'currency' => config('third_game.currency', 'CNY'),
+        ]);
+        $balances = $this->balancesFromResponse($response);
+        if ($balances === null) {
+            return ['ok' => false, 'msg' => $this->responseMessage($response)];
+        }
+        Cache::put(
+            $this->detailCacheKey($identity),
+            $balances,
+            max(1, (int) config('third_game.cache_seconds', 30))
+        );
+        return $this->agentBalanceResult($agentId, $playerId, $balances);
+    }
+
     /**
      * 查询单个用户在 ag、pg 等各游戏平台的余额。
      */
@@ -434,6 +472,24 @@ class ThirdGameBalanceService
         ];
     }
 
+    private function agentBalanceResult(int $agentId, string $playerId, array $balances): array
+    {
+        $normalized = [];
+        foreach ($balances as $platform => $balance) {
+            $amount = $this->decimalAmount($balance);
+            if ($amount !== null) {
+                $normalized[strtolower((string) $platform)] = $amount;
+            }
+        }
+        return [
+            'ok' => true,
+            'agent_id' => $agentId,
+            'player_id' => $playerId,
+            'currency' => (string) config('third_game.currency', 'CNY'),
+            'balances' => $normalized,
+        ];
+    }
+
     private function totalFromBalances(array $balances): float
     {
         return (float) $this->sumBalances($balances);

+ 21 - 4
docs/总后台/代理列表.md

@@ -307,6 +307,7 @@ GET /admin/agent/show?id=12
 | 参数 | 类型 | 必填 | 说明 |
 |---|---|---:|---|
 | `agent_id` | integer | 是 | 代理 ID |
+| `refresh` | boolean | 否 | `1/true` 强制请求三方;不传时使用最多 30 秒缓存 |
 
 ```http
 GET /admin/agent/quota?agent_id=12
@@ -318,18 +319,34 @@ GET /admin/agent/quota?agent_id=12
   "timestamp": 1787568000,
   "msg": "OK",
   "data": {
+    "agent_id": 12,
+    "player_id": "a12",
+    "currency": "CNY",
     "balance": "5500.0000",
     "frozen_balance": "200.0000",
-    "quota_mode": "internal",
-    "provider_wallet_supported": false,
+    "quota_mode": "provider",
+    "provider_wallet_supported": true,
     "platforms": [
-      {"plat_type":"ag","name":"AG钱包","logo":"https://api.example.com/static/ag.png"}
+      {
+        "plat_type":"ag",
+        "name":"AG钱包",
+        "logo":"https://api.example.com/static/ag.png",
+        "balance":"125.5000000000",
+        "account_opened":1
+      },
+      {
+        "plat_type":"pg",
+        "name":"PG钱包",
+        "logo":"https://api.example.com/static/pg.png",
+        "balance":"0.0000000000",
+        "account_opened":0
+      }
     ]
   }
 }
 ```
 
-当前额度是站内代理额度。api-bet 当前接入没有“每个代理一个三方子钱包”,因此 `provider_wallet_supported` 固定为 `false`,平台项不能显示成代理真实三方余额。
+代理自己的三方玩家号使用 `a + agents.id`。`balance` 是代理站内额度;`platforms[].balance` 是该代理在对应三方平台的真实余额。未创建三方玩家或未开通该平台时返回 `0.0000000000` 且 `account_opened=0`;已开通但余额为 0 时返回相同余额、`account_opened=1`。如果 api-bet 请求失败,接口返回错误,不会把故障当作 0
 
 ## 8. 绑定/解绑会员
 

+ 24 - 0
tests/Unit/ThirdGameAgentPlayerIdTest.php

@@ -0,0 +1,24 @@
+<?php
+
+namespace Tests\Unit;
+
+use App\Services\ThirdGameBalanceService;
+use InvalidArgumentException;
+use PHPUnit\Framework\TestCase;
+
+class ThirdGameAgentPlayerIdTest extends TestCase
+{
+    public function test_agent_player_id_uses_agent_primary_key(): void
+    {
+        $service = new ThirdGameBalanceService();
+
+        $this->assertSame('a1', $service->agentPlayerId(1));
+        $this->assertSame('a483', $service->agentPlayerId(483));
+    }
+
+    public function test_agent_player_id_rejects_non_positive_id(): void
+    {
+        $this->expectException(InvalidArgumentException::class);
+        (new ThirdGameBalanceService())->agentPlayerId(0);
+    }
+}