82 lines
2.3 KiB
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);
|
|
}
|
|
}
|