分离扣费部分,增加扣费请求

This commit is contained in:
iVampireSP.com 2022-08-23 17:36:10 +08:00
parent 9e6e5151af
commit c333e3bc38
No known key found for this signature in database
GPG Key ID: 2F7B001CA27A8132
6 changed files with 193 additions and 40 deletions

View File

@ -4,6 +4,7 @@
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\Host; use App\Models\Host;
use Cache;
use Illuminate\Http\Request; use Illuminate\Http\Request;
class HostController extends Controller class HostController extends Controller
@ -33,34 +34,59 @@ public function store(Request $request)
/** /**
* Display the specified resource. * Display the specified resource.
* *
* @param int $id * @param Host $host
* @return \Illuminate\Http\Response * @return \Illuminate\Http\Response
*/ */
public function show($id) public function show(Host $host)
{ {
return $this->success($host);
// //
// dd($host->cost());
} }
/** /**
* Update the specified resource in storage. * Update the specified resource in storage.
* *
* @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Request $request
* @param int $id * @param Host $host
* @return \Illuminate\Http\Response * @return \Illuminate\Http\Response
*/ */
public function update(Request $request, $id) public function update(Request $request, Host $host)
{ {
// //
$request->validate([
'status' => 'sometimes|in:stopped,running,suspended,error',
'managed_price' => 'sometimes|numeric|nullable',
// 如果是立即扣费
'cost_once' => 'sometimes|boolean|nullable',
]);
// if has cost_once
if ($request->has('cost_once')) {
$host->cost($request->cost_once);
return $this->updated($request->cost_once);
}
$host->update($request->all());
return $this->updated($host);
} }
/** /**
* Remove the specified resource from storage. * Remove the specified resource from storage.
* *
* @param int $id * @param Host $host
* @return \Illuminate\Http\Response * @return \Illuminate\Http\Response
*/ */
public function destroy($id) public function destroy(Host $host)
{ {
// //
$host->delete();
return $this->deleted($host);
} }
} }

View File

@ -35,40 +35,42 @@ public function __construct()
*/ */
public function handle() public function handle()
{ {
$this->cache = Cache::tags(['users']); // $this->cache = new Cache();
// chunk hosts and load user // chunk hosts and load user
Host::active()->with('user')->chunk(100, function ($hosts) { Host::active()->with('user')->chunk(100, function ($hosts) {
foreach ($hosts as $host) { foreach ($hosts as $host) {
$this->cache_key = 'user_' . $host->user_id; $host->cost();
// if cache has user // $this->cache_key = 'user_' . $host->user_id;
if ($this->cache->has($this->cache_key)) { // // if cache has user
// if user is not instances of Model
$user = $this->cache->get($this->cache_key);
if ($user instanceof User) { // if ($this->cache->has($this->cache_key)) {
$this->user = $user; // // if user is not instances of Model
} else { // $user = $this->cache->get($this->cache_key);
$this->user = $this->cache->put($this->cache_key, $host->user, now()->addDay());
}
} else {
$this->user = $this->cache->put($this->cache_key, $host->user, now()->addDay());
}
// Log::debug($user); // if ($user instanceof User) {
// $this->user = $user;
// } else {
// $this->user = $this->cache->put($this->cache_key, $host->user, now()->addDay());
// }
// } else {
// $this->user = $this->cache->put($this->cache_key, $host->user, now()->addDay());
// }
if ($host->managed_price) { // // Log::debug($user);
$host->price = $host->managed_price;
} // if ($host->managed_price) {
// $host->price = $host->managed_price;
// }
$this->user->drops -= $host->price; // $this->user->drops -= $host->price;
// update cache // // update cache
$this->cache->put($this->cache_key, $this->user, now()->addDay()); // $this->cache->put($this->cache_key, $this->user, now()->addDay());
} }
}); });
} }

70
app/Jobs/Remote/Host.php Normal file
View File

@ -0,0 +1,70 @@
<?php
namespace App\Jobs\Remote;
use Illuminate\Bus\Queueable;
use Illuminate\Support\Facades\Http;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use App\Models\Host as HostModel;
class Host implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public HostModel $host;
public string $type;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct(HostModel $host, $type = 'post')
{
//
$this->host = $host;
$this->host->load(['module']);
$this->type = $type;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
//
$http = Http::remote($this->host->module->api_token, $this->host->module->url);
switch ($this->type) {
case 'put':
$response = $http->put('hosts/' . $this->host->id, $this->host->toArray());
break;
case 'post':
$response = $http->post('hosts', $this->host->toArray());
break;
case 'delete':
$response = $http->delete('hosts/' . $this->host->id);
// if success
if ($response->successful()) {
$this->host->delete();
}
break;
}
if (!$response->successful()) {
$this->host->status = 'error';
}
$this->host->save();
}
}

View File

@ -34,18 +34,15 @@ public function __construct()
*/ */
public function handle() public function handle()
{ {
//
$this->cache = Cache::tags(['users']);
Host::active()->chunk(100, function ($hosts) { Host::active()->chunk(100, function ($hosts) {
foreach ($hosts as $host) { foreach ($hosts as $host) {
$this->cache_key = 'user_' . $host->user_id; $this->cache_key = 'user_' . $host->user_id;
// if cache has user // if cache has user
if ($this->cache->has($this->cache_key)) { if (Cache::has($this->cache_key)) {
// if user is not instances of Model // if user is not instances of Model
$user = $this->cache->get($this->cache_key); $user = Cache::get($this->cache_key);
if ($user instanceof User) { if ($user instanceof User) {
$this->await($this->cache_key, function () use ($user, $host) { $this->await($this->cache_key, function () use ($user, $host) {
$user->save(); $user->save();

View File

@ -2,12 +2,13 @@
namespace App\Models; namespace App\Models;
use App\Exceptions\CommonException;
use App\Models\Module\Module; use App\Models\Module\Module;
use App\Exceptions\CommonException;
use App\Models\WorkOrder\WorkOrder; use App\Models\WorkOrder\WorkOrder;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Support\Facades\Cache;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Host extends Model class Host extends Model
{ {
@ -31,17 +32,20 @@ class Host extends Model
// user // user
public function user() { public function user()
{
return $this->belongsTo(User::class); return $this->belongsTo(User::class);
} }
// module // module
public function module() { public function module()
{
return $this->belongsTo(Module::class); return $this->belongsTo(Module::class);
} }
// workOrders // workOrders
public function workOrders() { public function workOrders()
{
return $this->hasMany(WorkOrder::class); return $this->hasMany(WorkOrder::class);
} }
@ -52,11 +56,13 @@ public function workOrders() {
// scope // scope
public function scopeActive($query) { public function scopeActive($query)
{
return $query->where('status', 'running')->where('price', '!=', 0); return $query->where('status', 'running')->where('price', '!=', 0);
} }
public function scopeThisUser($query, $module = null) { public function scopeThisUser($query, $module = null)
{
if ($module) { if ($module) {
return $query->where('user_id', auth()->id())->where('module_id', $module); return $query->where('user_id', auth()->id())->where('module_id', $module);
} else { } else {
@ -64,6 +70,46 @@ public function scopeThisUser($query, $module = null) {
} }
} }
// cost
public function cost($price = null)
{
$cache_key = 'user_' . $this->user_id;
// 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());
}
} else {
$user = Cache::put($cache_key, $this->user, now()->addDay());
}
// Log::debug($user);
if ($price !== null) {
$this->managed_price = $price;
}
if ($this->managed_price) {
$this->price = $this->managed_price;
}
$user->drops -= $this->price;
// update cache
Cache::put($cache_key, $user, now()->addDay());
return true;
}
// on create // on create
protected static function boot() protected static function boot()
{ {
@ -85,5 +131,17 @@ protected static function boot()
// add to queue // add to queue
}); });
// when Updated
static::updated(function ($model) {
dispatch(new \App\Jobs\Remote\Host($model, 'put'));
});
// when delete
static::deleting(function ($model) {
return false;
dispatch(new \App\Jobs\Remote\Host($model, 'delete'));
});
} }
} }

View File

@ -7,7 +7,7 @@
Route::apiResource('modules', Remote\ModuleController::class)->only(['index']); Route::apiResource('modules', Remote\ModuleController::class)->only(['index']);
Route::apiResource('servers', Remote\ServerController::class); Route::apiResource('servers', Remote\ServerController::class);
Route::apiResource('hosts', Remote\Host\HostController::class); Route::apiResource('hosts', Remote\Host\HostController::class);
Route::patch('hosts/{host}/drops', [Remote\Host\DropController::class, 'update']); // Route::patch('hosts/{host}', [Remote\Host\DropController::class, 'update']);
Route::apiResource('hosts.tasks', Remote\Host\TaskController::class); Route::apiResource('hosts.tasks', Remote\Host\TaskController::class);
Route::apiResource('work-orders', Remote\WorkOrder\WorkOrderController::class); Route::apiResource('work-orders', Remote\WorkOrder\WorkOrderController::class);