6
0
Fork 0
jiqu-library-server/app/Services/Dealer/WalletService.php

82 lines
2.3 KiB
PHP

<?php
namespace App\Services\Dealer;
use App\Enums\DealerWalletAction;
use App\Exceptions\BizException;
use App\Models\DealerWallet;
use App\Models\DealerWalletLog;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
class WalletService
{
/**
* 变更钱包余额
*
* @param \App\Models\User $user
* @param float $changeBalance
* @param \App\Enums\DealerWalletAction $action
* @param string|null $remarks
* @param \Illuminate\Database\Eloquent\Model|null $loggable
* @return DealerWalletLog $log
*/
public function changeBalance(User $user, $changeBalance, DealerWalletAction $action, ?string $remarks = null, ?Model $loggable = null)
{
if (bccomp($changeBalance, '0', 2) === 0) {
return;
}
$wallet = $this->wallet($user);
// 变更前余额
$beforeBalance = $wallet->balance;
if (bccomp($changeBalance, '0', 2) < 0) {
// 支出
$absChangeBalance = abs($changeBalance);
if (bccomp($wallet->balance, $absChangeBalance, 2) === -1) {
throw new BizException('余额不足');
}
$wallet->update([
'balance' => bcsub($wallet->balance, $absChangeBalance, 2),
'total_expenses' => bcadd($wallet->total_expenses, $absChangeBalance, 2),
]);
} else {
// 收入
$wallet->update([
'balance' => bcadd($wallet->balance, $changeBalance, 2),
'total_revenue' => bcadd($wallet->total_revenue, $changeBalance, 2),
]);
}
return $user->dealerWalletLogs()->create([
'loggable_id' => $loggable?->id,
'loggable_type' => $loggable?->getMorphClass(),
'before_balance' => $beforeBalance,
'change_balance' => $changeBalance,
'action' => $action,
'remarks' => $remarks,
]);
}
/**
* @param \App\Models\User $user
* @return \App\Models\DealerWallet
*/
protected function wallet(User $user): DealerWallet
{
if ($wallet = $user->dealerWallet()->lockForUpdate()->first()) {
return $wallet;
}
$user->dealerWallet()->create();
return $this->wallet($user);
}
}