支持 余额扣费
This commit is contained in:
parent
3555d0ba2d
commit
7b874970c6
@ -7,6 +7,7 @@
|
||||
use App\Models\User\Balance;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Exceptions\ChargeException;
|
||||
|
||||
class UserAddBalance extends Command
|
||||
{
|
||||
@ -53,8 +54,9 @@ public function handle()
|
||||
|
||||
$balance = new Balance();
|
||||
|
||||
$this->info($user->name . ', 当前余额: ' . $user->balance);
|
||||
$this->info($user->name . ', 当前余额: ' . $user->balance . ' 元');
|
||||
|
||||
$this->info('充值后余额: ' . ($user->balance + $amount) . ' 元');
|
||||
if (!$this->confirm('确认充值 ' . $amount . ' 元?')) {
|
||||
$this->info('已取消。');
|
||||
return;
|
||||
@ -70,30 +72,18 @@ public function handle()
|
||||
|
||||
$transaction = new Transaction();
|
||||
|
||||
DB::beginTransaction();
|
||||
$description = '控制台充值 ' . $amount . ' 元';
|
||||
|
||||
try {
|
||||
$balance->user->increment('balance', $amount);
|
||||
|
||||
$description = '控制台充值 ' . $amount . ' 元';
|
||||
$transaction->addIncomeBalance($balance->user_id, 'console', $amount, $description);
|
||||
|
||||
$balance->update([
|
||||
'paid_at' => now(),
|
||||
]);
|
||||
|
||||
DB::commit();
|
||||
$transaction->addAmount($user->id, 'console', $amount, $description);
|
||||
|
||||
$this->info('充值成功。');
|
||||
|
||||
$user->refresh();
|
||||
$this->info($user->name . ', 当前余额: ' . $user->balance);
|
||||
} catch (ChargeException $e) {
|
||||
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
|
||||
$this->error('充值失败。' . $e->getMessage());
|
||||
|
||||
return;
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
10
app/Exceptions/ChargeException.php
Normal file
10
app/Exceptions/ChargeException.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class ChargeException extends Exception
|
||||
{
|
||||
//
|
||||
}
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Http\Controllers\Remote\Host;
|
||||
|
||||
use Cache;
|
||||
use App\Models\Host;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Http\Request;
|
||||
@ -52,7 +51,6 @@ public function store(Request $request)
|
||||
$host['host_id'] = $host->id;
|
||||
|
||||
return $this->created($host);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -86,15 +84,24 @@ public function update(Request $request, Host $host)
|
||||
|
||||
// 如果是立即扣费
|
||||
'cost_once' => 'sometimes|numeric|nullable',
|
||||
|
||||
'cost_balance' => 'sometimes|numeric|nullable',
|
||||
]);
|
||||
|
||||
// if has cost_once
|
||||
if ($request->has('cost_once')) {
|
||||
$host->cost($request->cost_once, false);
|
||||
$host->cost($request->cost_once ?? 0, false);
|
||||
|
||||
return $this->updated($request->cost_once);
|
||||
return $this->updated();
|
||||
}
|
||||
|
||||
if ($request->has('cost_balance')) {
|
||||
$host->costBalance($request->cost_balance ?? 0);
|
||||
|
||||
return $this->updated();
|
||||
}
|
||||
|
||||
|
||||
$update = $request->all();
|
||||
// module_id 不能被更新
|
||||
unset($update['module_id']);
|
||||
|
@ -3,15 +3,16 @@
|
||||
namespace App\Http\Controllers\User;
|
||||
|
||||
use Exception;
|
||||
use App\Models\Transaction;
|
||||
use App\Models\User\Balance;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Exceptions\ChargeException;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Alipay\EasySDK\Kernel\Util\ResponseChecker;
|
||||
use Alipay\EasySDK\Kernel\Factory as AlipayFactory;
|
||||
use App\Models\Transaction;
|
||||
|
||||
class BalanceController extends Controller
|
||||
{
|
||||
@ -161,16 +162,9 @@ public function checkAndCharge(Balance $balance)
|
||||
|
||||
$transaction = new Transaction();
|
||||
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
$balance->user->increment('balance', $trade->totalAmount);
|
||||
|
||||
$description = '充值 ' . $trade->totalAmount . ' 元';
|
||||
$transaction->addIncomeBalance($balance->user_id, 'alipay', $trade->totalAmount, $description);
|
||||
|
||||
DB::commit();
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
$transaction->addAmount($balance->user_id, 'alipay', $trade->totalAmount);
|
||||
} catch (ChargeException $e) {
|
||||
AlipayFactory::payment()->common()->refund($balance->order_id, $trade->totalAmount);
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
|
@ -152,6 +152,24 @@ public function cost($price = null, $auto = true)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public function costBalance($amount = 1)
|
||||
{
|
||||
$transaction = new Transaction();
|
||||
|
||||
$left = $transaction->reduceAmount($this->user_id, $amount);
|
||||
|
||||
broadcast(new UserEvent($this->user_id, 'balances.amount.reduced', $this->user));
|
||||
|
||||
if ($left < 0) {
|
||||
$this->update([
|
||||
'status' => 'suspended',
|
||||
]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
@ -2,9 +2,11 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Jenssegers\Mongodb\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use App\Exceptions\ChargeException;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Jenssegers\Mongodb\Eloquent\Model;
|
||||
use Illuminate\Contracts\Cache\LockTimeoutException;
|
||||
|
||||
class Transaction extends Model
|
||||
{
|
||||
@ -203,27 +205,61 @@ public function addPayoutBalance($user_id, $amount, $description)
|
||||
return $this->addLog($user_id, $data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function reduceAmount($user_id, $amount = 0, $description = '扣除费用请求。')
|
||||
{
|
||||
$user = User::findOrFail($user_id);
|
||||
|
||||
if ($user) {
|
||||
$lock = Cache::lock("user_balance_lock_" . $user_id, 10);
|
||||
try {
|
||||
|
||||
$lock->block(5);
|
||||
|
||||
$user = User::findOrFail($user_id);
|
||||
|
||||
$user->balance -= $amount;
|
||||
|
||||
$user->save();
|
||||
|
||||
$this->addPayoutBalance($user_id, $amount, $description);
|
||||
|
||||
return $user->balance;
|
||||
} finally {
|
||||
optional($lock)->release();
|
||||
}
|
||||
|
||||
$data = [
|
||||
'type' => 'payout',
|
||||
'payment' => 'balance',
|
||||
'description' => $description,
|
||||
'income' => 0,
|
||||
'income_drops' => 0,
|
||||
'outcome' => $amount,
|
||||
'outcome_drops' => 0
|
||||
];
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->addLog($user_id, $data);
|
||||
public function addAmount($user_id, $payment = 'console', $amount = 0, $description = null)
|
||||
{
|
||||
$lock = Cache::lock("user_balance_lock_" . $user_id, 10);
|
||||
try {
|
||||
|
||||
$lock->block(5);
|
||||
|
||||
$user = User::findOrFail($user_id);
|
||||
|
||||
$left_balance = $user->balance + $amount;
|
||||
|
||||
$user->increment('balance', $amount);
|
||||
|
||||
if (!$description) {
|
||||
$description = '充值金额。';
|
||||
} else {
|
||||
$description = '充值 ' . $amount . ' 元';
|
||||
}
|
||||
|
||||
$this->addIncomeBalance($user_id, $payment, $amount, $description);
|
||||
|
||||
return $left_balance;
|
||||
} catch (LockTimeoutException $e) {
|
||||
Log::error($e);
|
||||
throw new ChargeException('充值失败,请稍后再试。');
|
||||
} finally {
|
||||
optional($lock)->release();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -96,14 +96,14 @@ public function toDrops($amount = 1)
|
||||
return $this;
|
||||
}
|
||||
|
||||
// when update
|
||||
// protected static function boot()
|
||||
// {
|
||||
// parent::boot();
|
||||
protected static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
// // when update
|
||||
// static::updating(function ($model) {
|
||||
static::updating(function ($model) {
|
||||
|
||||
// });
|
||||
// }
|
||||
// balance 四舍五入
|
||||
$model->balance = round($model->balance, 2);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user