改进 扣费
This commit is contained in:
parent
373ca437b9
commit
5a1356e26f
@ -22,7 +22,7 @@ protected function schedule(Schedule $schedule)
|
||||
|
||||
// dispatch HostCost job
|
||||
$schedule->job(new HostCost())->everyFiveMinutes();
|
||||
$schedule->job(new UserSave())->everyTenMinutes();
|
||||
// $schedule->job(new UserSave())->everyTenMinutes();
|
||||
$schedule->job(new Remote\FetchModule())->everyMinute()->onOneServer();
|
||||
$schedule->job(new Remote\PushHost())->everyMinute()->onOneServer();
|
||||
$schedule->job(new Remote\PushWorkOrder())->everyMinute()->onOneServer();
|
||||
|
10
app/Exceptions/User/BalanceNotEnoughException.php
Normal file
10
app/Exceptions/User/BalanceNotEnoughException.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions\User;
|
||||
|
||||
use Exception;
|
||||
|
||||
class BalanceNotEnoughException extends Exception
|
||||
{
|
||||
//
|
||||
}
|
54
app/Http/Controllers/User/BalanceController.php
Normal file
54
app/Http/Controllers/User/BalanceController.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\User;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class BalanceController extends Controller
|
||||
{
|
||||
//
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
//
|
||||
$balance = $request->user();
|
||||
return $this->success($balance);
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
|
||||
// 充值
|
||||
$request->validate([
|
||||
'amount' => 'required|numeric',
|
||||
]);
|
||||
|
||||
$balance = $request->user();
|
||||
|
||||
// 启用事物
|
||||
\DB::beginTransaction();
|
||||
try {
|
||||
$balance->increment('amount', $request->amount);
|
||||
\DB::commit();
|
||||
} catch (\Exception $e) {
|
||||
\DB::rollBack();
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
|
||||
return $this->success($balance);
|
||||
}
|
||||
|
||||
|
||||
// // 转换为 drops
|
||||
// public function transfer($amount = 1)
|
||||
// {
|
||||
// $balance = auth('sanctum')->user();
|
||||
// $balance->decrement('amount', $request->amount);
|
||||
// return $this->success($balance);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
19
app/Http/Controllers/UserController.php
Normal file
19
app/Http/Controllers/UserController.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Cache;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
$user['drops'] = (float) Cache::get('user_drops_' . $user['id'], 0);
|
||||
|
||||
return $this->success($user);
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Log;
|
||||
|
||||
class UserSave implements ShouldQueue
|
||||
{
|
||||
@ -34,7 +35,11 @@ public function __construct()
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
Host::active()->chunk(100, function ($hosts) {
|
||||
|
||||
// 弃用
|
||||
return false;
|
||||
|
||||
Host::all()->chunk(100, function ($hosts) {
|
||||
foreach ($hosts as $host) {
|
||||
$this->cache_key = 'user_' . $host->user_id;
|
||||
|
||||
@ -43,11 +48,18 @@ public function handle()
|
||||
if (Cache::has($this->cache_key)) {
|
||||
// if user is not instances of Model
|
||||
$user = Cache::get($this->cache_key);
|
||||
|
||||
Log::debug($user);
|
||||
|
||||
|
||||
if ($user instanceof User) {
|
||||
$this->await($this->cache_key, function () use ($user, $host) {
|
||||
$this->await($this->cache_key, function () use ($user) {
|
||||
$user->save();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// save cache
|
||||
$this->cache->put($this->cache_key, $host->user, now()->addDay());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -2,12 +2,14 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Log;
|
||||
use App\Models\Module\Module;
|
||||
use App\Exceptions\CommonException;
|
||||
use App\Models\WorkOrder\WorkOrder;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
// use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use App\Exceptions\User\BalanceNotEnoughException;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class Host extends Model
|
||||
@ -77,21 +79,26 @@ public function scopeThisUser($query, $module = null)
|
||||
public function cost($price = null)
|
||||
{
|
||||
|
||||
$cache_key = 'user_' . $this->user_id;
|
||||
$this->load('user');
|
||||
|
||||
// if cache has user
|
||||
|
||||
if (Cache::has($cache_key)) {
|
||||
// if user is not instances of Model
|
||||
$user = Cache::get($cache_key);
|
||||
|
||||
if (!($user instanceof User)) {
|
||||
$user = Cache::put($cache_key, $this->user, now()->addDay());
|
||||
}
|
||||
if ($this->user->balance < 10) {
|
||||
$amount = 1;
|
||||
} else if ($this->user->balance < 100) {
|
||||
$amount = 10;
|
||||
} else if ($this->user->balance < 1000) {
|
||||
$amount = 100;
|
||||
} else if ($this->user->balance < 10000) {
|
||||
$amount = 1000;
|
||||
} else {
|
||||
$user = Cache::put($cache_key, $this->user, now()->addDay());
|
||||
$amount = 10000;
|
||||
}
|
||||
|
||||
$cache_key = 'user_drops_' . $this->user_id;
|
||||
|
||||
$drops = Cache::get($cache_key);
|
||||
|
||||
|
||||
|
||||
// Log::debug($user);
|
||||
|
||||
@ -103,24 +110,25 @@ public function cost($price = null)
|
||||
$this->price = $this->managed_price;
|
||||
}
|
||||
|
||||
// if drops <= price
|
||||
if ($drops < $this->price) {
|
||||
try {
|
||||
$this->user->toDrops($amount);
|
||||
} catch (BalanceNotEnoughException) {
|
||||
$this->update([
|
||||
'status' => 'suspended',
|
||||
]);
|
||||
|
||||
$user->drops -= (int) $this->price;
|
||||
|
||||
// update cache
|
||||
Cache::put($cache_key, $user, now()->addDay());
|
||||
|
||||
|
||||
// if $user->drops <= 0
|
||||
if ($user->drops <= 0) {
|
||||
$this->update([
|
||||
'status' => 'suspended',
|
||||
]);
|
||||
return false;
|
||||
}
|
||||
} else if ($this->status == 'suspended') {
|
||||
$this->update([
|
||||
'status' => 'running',
|
||||
'status' => 'stopped',
|
||||
]);
|
||||
}
|
||||
|
||||
Cache::decrement($cache_key, $this->price);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3,10 +3,14 @@
|
||||
namespace App\Models;
|
||||
|
||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
use App\Exceptions\CommonException;
|
||||
use App\Exceptions\User\BalanceNotEnoughException;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Contracts\Cache\LockTimeoutException;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
@ -40,5 +44,38 @@ class User extends Authenticatable
|
||||
*/
|
||||
protected $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
'balance' => 'float',
|
||||
];
|
||||
|
||||
|
||||
public function toDrops($amount = 1)
|
||||
{
|
||||
$rate = Cache::get('drops_rate', 100);
|
||||
$total = $amount * $rate;
|
||||
|
||||
$cache_key = 'user_drops_' . $this->id;
|
||||
|
||||
$lock = Cache::lock("lock_" . $cache_key, 5);
|
||||
try {
|
||||
$lock->block(5);
|
||||
|
||||
// if user balance <= 0
|
||||
if ($this->balance < $amount) {
|
||||
throw new BalanceNotEnoughException('余额不足');
|
||||
}
|
||||
|
||||
$this->balance -= $amount;
|
||||
$this->save();
|
||||
|
||||
// increment user drops
|
||||
Cache::increment($cache_key, $total);
|
||||
|
||||
} catch (LockTimeoutException) {
|
||||
throw new CommonException('暂时无法处理此请求,请稍后再试。');
|
||||
} finally {
|
||||
optional($lock)->release();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,23 @@ public static function boot()
|
||||
|
||||
$rate = Cache::get('drops_rate', 100);
|
||||
$drops->total = $drops->amount * $rate;
|
||||
|
||||
$this->cache_key = 'user_' . $drops->user_id;
|
||||
|
||||
// if cache has user
|
||||
|
||||
// if (Cache::has($this->cache_key)) {
|
||||
// // if user is not instances of Model
|
||||
// $user = Cache::get($this->cache_key);
|
||||
// if ($user instanceof User) {
|
||||
// $this->await($this->cache_key, function () use ($user) {
|
||||
// $user->save();
|
||||
// });
|
||||
// }
|
||||
|
||||
// // delete cache
|
||||
// Cache::forget($this->cache_key);
|
||||
// }
|
||||
});
|
||||
|
||||
// created
|
||||
|
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
//
|
||||
$table->decimal('balance', 10, 2)->default(0)->after('password');
|
||||
|
||||
// drop column if exists
|
||||
if (Schema::hasColumn('users', 'drops')) {
|
||||
$table->dropColumn('drops');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
//
|
||||
$table->dropColumn('balance');
|
||||
});
|
||||
}
|
||||
};
|
@ -4,7 +4,7 @@
|
||||
use App\Http\Controllers\User\DropController;
|
||||
use App\Http\Controllers\User\TaskController;
|
||||
use App\Http\Controllers\Remote\ModuleController;
|
||||
use App\Http\Controllers\Admin\User\UserController;
|
||||
use App\Http\Controllers\UserController;
|
||||
use App\Http\Controllers\User\WorkOrder\ReplyController;
|
||||
use App\Http\Controllers\User\WorkOrder\WorkOrderController;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user