增加 转账

增加 手动添加 Drops
This commit is contained in:
iVampireSP.com 2022-11-16 19:49:12 +08:00
parent a742c83080
commit 40c4894464
No known key found for this signature in database
GPG Key ID: 2F7B001CA27A8132
10 changed files with 262 additions and 14 deletions

View File

@ -0,0 +1,60 @@
<?php
namespace App\Console\Commands;
use App\Models\Transaction;
use App\Models\User;
use Illuminate\Console\Command;
use Symfony\Component\Console\Command\Command as CommandAlias;
class UserAddDrops extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'user:add-drops {user_id} {amount}';
/**
* The console command description.
*
* @var string
*/
protected $description = '给用户添加 Drops';
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$user_id = $this->argument('user_id');
$amount = $this->argument('amount');
$user = User::findOrFail($user_id);
$transaction = new Transaction();
$current_drops = $transaction->getDrops($user->id);
$this->info($user->name . ', 当前 ' . $current_drops. ' Drops');
$this->info($user->name . ', 当前余额: ' . $user->balance . ' 元');
$this->info('添加后 ' . $current_drops + $amount . ' Drops');
if (!$this->confirm('确认添加 ' . $amount . ' Drops?')) {
$this->info('已取消。');
return;
}
$transaction->increaseDrops($user->id, $amount, '管理员添加 Drops', 'console');
$this->info('添加成功。');
return CommandAlias::SUCCESS;
}
}

View File

@ -3,13 +3,65 @@
namespace App\Http\Controllers\Web;
use App\Http\Controllers\Controller;
use App\Models\Transaction;
use App\Models\User;
use Illuminate\Http\Request;
class TransferController extends Controller
{
//
public function index() {
return view('transfer.search');
public function index(Request $request)
{
$user = $request->user();
$balance = $user->balance;
$drops = (new Transaction())->getDrops($user->id);
return view('transfer.search', compact('balance', 'drops'));
}
public function transfer(Request $request)
{
$request->validate([
'amount' => 'numeric|min:1|max:100',
'description' => 'nullable|string|max:100',
'type' => 'string|in:balance,drops'
]);
$to = User::where('email', $request->to)->first();
if (!$to) {
return back()->withErrors(['to' => '找不到用户。']);
}
$user = $request->user();
if ($request->to == $user->email) {
return back()->withErrors(['to' => '不能转给自己。']);
}
$transaction = new Transaction();
if ($request->type === 'balance') {
if ($user->balance < $request->amount) {
return back()->withErrors(['amount' => '您的余额不足。']);
} else {
$transaction->transfer($user, $to, $request->amount, $request->description);
}
} else if ($request->type === 'drops') {
$transaction = new Transaction();
$drops = $transaction->getDrops($user->id);
if ($drops < $request->amount) {
return back()->withErrors(['amount' => '您的 Drops 不足。']);
} else {
if (!$transaction->transferDrops($user, $to, $request->amount, $request->description)) {
return back()->withErrors(['amount' => '转账失败。']);
}
}
}
return back()->with('success', '转账成功,已达对方账户。');
}
}

View File

@ -74,7 +74,7 @@ public function increaseCurrentUserDrops($amount = 0)
return $this->increaseDrops(auth()->id(), $amount);
}
public function increaseDrops($user_id, $amount = 0)
public function increaseDrops($user_id, $amount, $description = null, $payment = null)
{
$cache_key = 'user_drops_' . $user_id;
@ -86,6 +86,8 @@ public function increaseDrops($user_id, $amount = 0)
Cache::forever($cache_key, $current_drops);
$this->addIncomeDrops($user_id, $amount, $description, $payment);
return $current_drops['drops'];
}
@ -113,6 +115,24 @@ public function reduceDrops($user_id, $host_id, $module_id, $auto = 1, $amount =
// $this->addPayoutDrops($user_id, $amount, $description, $host_id, $module_id);
}
public function reduceDropsWithoutHost($user_id, $amount = 0, $description = null)
{
$cache_key = 'user_drops_' . $user_id;
$current_drops = Cache::get($cache_key, [
'drops' => 0,
]);
$current_drops['drops'] = $current_drops['drops'] - $amount;
$current_drops['drops'] = round($current_drops['drops'], 5);
Cache::forever($cache_key, $current_drops);
$this->addPayoutDrops($user_id, $amount, $description, null, null);
}
public function addPayoutDrops($user_id, $amount, $description, $host_id, $module_id)
{
$data = [
@ -178,11 +198,11 @@ public function getDrops($user_id = null): float
return $drops['drops'];
}
public function addIncomeDrops($user_id, $amount, $description)
public function addIncomeDrops($user_id, $amount, $description, $payment = 'balances')
{
$data = [
'type' => 'income',
'payment' => 'balances',
'payment' => $payment,
'description' => $description,
'income' => 0,
'income_drops' => (float)$amount,
@ -220,7 +240,7 @@ public function addPayoutBalance($user_id, $amount, $description, $module_id = n
{
$data = [
'type' => 'payout',
'payment' => 'balances',
'payment' => 'balance',
'description' => $description,
'income' => 0,
'income_drops' => 0,
@ -353,4 +373,59 @@ public function addIncomeBalance($user_id, $payment, $amount, $description)
return $this->addLog($user_id, $data);
}
public function transfer(User $user, User $to, float $amount, string $description): float
{
$lock = Cache::lock("user_balance_lock_" . $user->id, 10);
$lock_to = Cache::lock("user_balance_lock_" . $to->id, 10);
try {
$lock->block(5);
$lock_to->block(5);
$user->balance -= $amount;
$user->save();
$to->balance += $amount;
$to->save();
$description_new = "转账给 {$to->name}({$to->email}) {$amount} 元,{$description}";
$this->addPayoutBalance($user->id, $amount, $description_new);
$description_new = "收到来自 {$user->name}($user->email) 转来的 {$amount} 元, $description";
$this->addIncomeBalance($to->id, 'transfer', $amount, $description_new);
return $user->balance;
} finally {
optional($lock)->release();
optional($lock_to)->release();
}
}
public function transferDrops(User $user, User $to, float $amount, string|null $description = null): bool
{
$user_drops = $this->getDrops($user->id);
// if drops not enough
if ($user_drops < $amount) {
return false;
}
$description_new = "转账给 {$to->name}($to->email) {$amount} Drops $description";
$this->reduceDropsWithoutHost($user->id, $amount, $description_new);
$description_new = "收到来自 {$to->name}($to->email) 转来的 {$amount} Drops $description";
$this->increaseDrops($to->id, $amount, $description_new, 'transfer');
return true;
}
}

View File

@ -31,10 +31,11 @@ public function render()
'alipay' => '支付宝',
'wechat', 'wepay' => '微信支付',
'drops' => 'Drops',
'balance' => '余额',
'balance', 'balances' => '余额',
'unfreeze' => '解冻',
'freeze' => '冻结',
'console' => '控制台',
'transfer' => '转账',
default => $this->payment,
};

View File

@ -102,7 +102,4 @@ function calc(el) {
</script>
{{-- {{ }}--}}
@endsection

View File

@ -55,7 +55,7 @@
</td>
<td>
{{ $t->balance }}
{{ $t->balances }}
<br/>
{{ $t->drops }} Drops
</td>

View File

@ -1,6 +1,6 @@
@extends('layouts.app')
@section('title', '用户')
@section('title', '密钥管理')
@section('content')

View File

@ -40,9 +40,13 @@
<li class="nav-item">
<a class="nav-link text-auto" href="{{ route('balances.index') }}">余额</a>
</li>
<li class="nav-item">
<a class="nav-link text-auto" href="{{ route('transfer') }}">转账</a>
</li>
<li class="nav-item">
<a class="nav-link text-auto" href="{{ route('transactions') }}">交易记录</a>
</li>
</ul>
<!-- Right Side Of Navbar -->

View File

@ -0,0 +1,58 @@
@extends('layouts.app')
@section('title', '转账')
@section('content')
<h2>转账</h2>
<p>将您的余额转入到其他莱云账号,并且无需对方确认。</p>
<p>您有: {{ $balance }} 元,以及 {{ $drops }} Drops </p>
<form method="post" action="{{ route('transfer') }}" onsubmit="return beforeContinue()">
@csrf
<div class="form-group">
<label for="to">转入账号(输入对方的邮箱)</label>
<input type="text" class="form-control" id="to" name="to" placeholder="请输入对方的邮箱">
</div>
<div class="form-group">
<label for="type">类型</label>
<select class="form-control" id="type" name="type">
<option value="balance">余额</option>
<option value="drops">Drops</option>
</select>
<div class="form-group">
<label for="amount">金额</label>
<input type="number" class="form-control" id="amount" name="amount" placeholder="请输入转账金额" min="1"
max="100" value="1">
</div>
<div class="form-group">
<label for="description">备注</label>
<input type="text" class="form-control" id="description" name="description" placeholder="请输入备注"
maxlength="100">
</div>
<button type="submit" class="btn btn-primary mt-3">转账</button>
</form>
<script>
function beforeContinue() {
return true;
if (confirm('您确定要转账吗?')) {
if (confirm('当您确定后,您将无法取消。')) {
if (confirm('钱款会直接汇入到对方账户,您将无法退回。')) {
if (confirm('您再次确认转账给这个账号吗?')) {
return true;
}
}
}
}
return false;
}
</script>
@endsection

View File

@ -18,6 +18,7 @@
Route::resource('balances', BalanceController::class);
Route::get('transfer', [TransferController::class, 'index'])->name('transfer');
Route::post('transfer', [TransferController::class, 'transfer']);
});