|
@@ -13,7 +13,7 @@ class ThirdGameBalanceService
|
|
|
private const CODE_SUCCESS = 10000;
|
|
private const CODE_SUCCESS = 10000;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 批量查询用户的三方游戏总余额,返回值已按 GAME_RATE 换算为主钱包货币。
|
|
|
|
|
|
|
+ * 批量查询用户的三方游戏总余额,三方与主钱包金额按 1:1 处理。
|
|
|
*
|
|
*
|
|
|
* @param array<int, string|int> $memberIds
|
|
* @param array<int, string|int> $memberIds
|
|
|
* @return array<string, float|null>
|
|
* @return array<string, float|null>
|
|
@@ -132,6 +132,9 @@ class ThirdGameBalanceService
|
|
|
*/
|
|
*/
|
|
|
public function recycle(string $memberId): array
|
|
public function recycle(string $memberId): array
|
|
|
{
|
|
{
|
|
|
|
|
+ // 必须在调用 transferAll 前校验,避免三方已转出后才因本地配置错误中断。
|
|
|
|
|
+ $this->recycleRate();
|
|
|
|
|
+
|
|
|
$response = $this->request('/api/server/transferAll', [
|
|
$response = $this->request('/api/server/transferAll', [
|
|
|
'playerId' => $this->playerId($memberId),
|
|
'playerId' => $this->playerId($memberId),
|
|
|
'currency' => config('third_game.currency', 'CNY'),
|
|
'currency' => config('third_game.currency', 'CNY'),
|
|
@@ -160,7 +163,14 @@ class ThirdGameBalanceService
|
|
|
'msg' => '三方游戏回收成功响应缺少有效 balanceAll,回收结果待核对',
|
|
'msg' => '三方游戏回收成功响应缺少有效 balanceAll,回收结果待核对',
|
|
|
];
|
|
];
|
|
|
}
|
|
}
|
|
|
- $gameBalance = (float) $data['balanceAll'];
|
|
|
|
|
|
|
+ $gameBalance = $this->decimalAmount($data['balanceAll']);
|
|
|
|
|
+ if ($gameBalance === null) {
|
|
|
|
|
+ return [
|
|
|
|
|
+ 'ok' => false,
|
|
|
|
|
+ 'uncertain' => true,
|
|
|
|
|
+ 'msg' => '三方游戏回收金额格式异常,回收结果待核对',
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
$this->clearCache($memberId);
|
|
$this->clearCache($memberId);
|
|
|
return [
|
|
return [
|
|
|
'ok' => true,
|
|
'ok' => true,
|
|
@@ -171,7 +181,7 @@ class ThirdGameBalanceService
|
|
|
|
|
|
|
|
if ($this->isPlayerNotFound((string) ($body['msg'] ?? ''))) {
|
|
if ($this->isPlayerNotFound((string) ($body['msg'] ?? ''))) {
|
|
|
$this->clearCache($memberId);
|
|
$this->clearCache($memberId);
|
|
|
- return ['ok' => true, 'game_balance' => 0.0, 'wallet_balance' => 0.0];
|
|
|
|
|
|
|
+ return ['ok' => true, 'game_balance' => '0.0000000000', 'wallet_balance' => '0.0000000000'];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return [
|
|
return [
|
|
@@ -181,9 +191,24 @@ class ThirdGameBalanceService
|
|
|
];
|
|
];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public function toWalletBalance($gameBalance): float
|
|
|
|
|
|
|
+ public function toWalletBalance($gameBalance): string
|
|
|
{
|
|
{
|
|
|
- return round((float) $gameBalance / $this->rate(), 2);
|
|
|
|
|
|
|
+ $balance = $this->decimalAmount($gameBalance);
|
|
|
|
|
+ if ($balance === null) {
|
|
|
|
|
+ throw new \InvalidArgumentException('三方游戏余额格式异常');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return bcdiv($balance, $this->recycleRate(), 10);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function recycleRate(): string
|
|
|
|
|
+ {
|
|
|
|
|
+ $rate = trim((string) config('third_game.recycle_rate', '1'));
|
|
|
|
|
+ if (!preg_match('/^\d+(?:\.\d+)?$/D', $rate) || bccomp($rate, '0', 10) <= 0) {
|
|
|
|
|
+ throw new \RuntimeException('GAME_RECYCLE_RATE 必须是大于 0 的数字');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $rate;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private function balancesFromResponse($response): ?array
|
|
private function balancesFromResponse($response): ?array
|
|
@@ -214,18 +239,18 @@ class ThirdGameBalanceService
|
|
|
|
|
|
|
|
private function detailResult(string $memberId, array $balances): array
|
|
private function detailResult(string $memberId, array $balances): array
|
|
|
{
|
|
{
|
|
|
- $gameBalance = array_sum(array_filter($balances, 'is_numeric'));
|
|
|
|
|
|
|
+ $gameBalance = $this->sumBalances($balances);
|
|
|
$walletBalances = [];
|
|
$walletBalances = [];
|
|
|
$gameBalances = [];
|
|
$gameBalances = [];
|
|
|
foreach ($balances as $platform => $balance) {
|
|
foreach ($balances as $platform => $balance) {
|
|
|
if (is_numeric($balance)) {
|
|
if (is_numeric($balance)) {
|
|
|
$walletBalances[] = [
|
|
$walletBalances[] = [
|
|
|
'platform' => (string) $platform,
|
|
'platform' => (string) $platform,
|
|
|
- 'balance' => round((float) $balance / $this->rate(), 2),
|
|
|
|
|
|
|
+ 'balance' => (float) $balance,
|
|
|
];
|
|
];
|
|
|
$gameBalances[] = [
|
|
$gameBalances[] = [
|
|
|
'platform' => (string) $platform,
|
|
'platform' => (string) $platform,
|
|
|
- 'balance' => round((float) $balance, 2),
|
|
|
|
|
|
|
+ 'balance' => (float) $balance,
|
|
|
];
|
|
];
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -234,24 +259,42 @@ class ThirdGameBalanceService
|
|
|
'member_id' => $memberId,
|
|
'member_id' => $memberId,
|
|
|
'player_id' => $this->playerId($memberId),
|
|
'player_id' => $this->playerId($memberId),
|
|
|
'currency' => (string) config('third_game.currency', 'CNY'),
|
|
'currency' => (string) config('third_game.currency', 'CNY'),
|
|
|
- 'rate' => $this->rate(),
|
|
|
|
|
|
|
+ 'rate' => 1,
|
|
|
'list' => $walletBalances,
|
|
'list' => $walletBalances,
|
|
|
'game_list' => $gameBalances,
|
|
'game_list' => $gameBalances,
|
|
|
- 'total_game_balance' => round($gameBalance, 2),
|
|
|
|
|
|
|
+ 'total_game_balance' => (float) $gameBalance,
|
|
|
'total_balance' => $this->totalFromBalances($balances),
|
|
'total_balance' => $this->totalFromBalances($balances),
|
|
|
];
|
|
];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private function totalFromBalances(array $balances): float
|
|
private function totalFromBalances(array $balances): float
|
|
|
{
|
|
{
|
|
|
- $gameBalance = array_sum(array_filter($balances, 'is_numeric'));
|
|
|
|
|
- return round($gameBalance / $this->rate(), 2);
|
|
|
|
|
|
|
+ return (float) $this->sumBalances($balances);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function sumBalances(array $balances): string
|
|
|
|
|
+ {
|
|
|
|
|
+ $total = '0.0000000000';
|
|
|
|
|
+ foreach ($balances as $balance) {
|
|
|
|
|
+ $amount = $this->decimalAmount($balance);
|
|
|
|
|
+ if ($amount !== null) {
|
|
|
|
|
+ $total = bcadd($total, $amount, 10);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return $total;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private function rate(): float
|
|
|
|
|
|
|
+ private function decimalAmount($value): ?string
|
|
|
{
|
|
{
|
|
|
- $rate = (float) config('third_game.rate', 10);
|
|
|
|
|
- return $rate > 0 ? $rate : 1;
|
|
|
|
|
|
|
+ if (!is_int($value) && !is_float($value) && !is_string($value)) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $value = trim((string) $value);
|
|
|
|
|
+ if (!preg_match('/^\d+(?:\.\d+)?$/D', $value)) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ return bcadd($value, '0', 10);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private function request(string $path, array $data, bool $transfer = false)
|
|
private function request(string $path, array $data, bool $transfer = false)
|