改进 使用 Observer 代理 boot
This commit is contained in:
parent
10f5d0f2ff
commit
7fa1ccf755
@ -2,8 +2,6 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Events\Users;
|
||||
use App\Notifications\User\UserCharged;
|
||||
use function auth;
|
||||
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
@ -28,33 +26,6 @@ class Balance extends Model
|
||||
'amount' => 'decimal:2',
|
||||
];
|
||||
|
||||
protected static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
static::creating(function (self $balance) {
|
||||
// $balance->remaining_amount = $balance->amount;
|
||||
$balance->remaining_amount = 0;
|
||||
|
||||
$balance->order_id = date('YmdHis').$balance->id.rand(1000, 9999);
|
||||
});
|
||||
|
||||
static::created(function (self $balance) {
|
||||
broadcast(new Users($balance->user, 'balance.created', $balance));
|
||||
});
|
||||
|
||||
static::updated(function (self $balance) {
|
||||
if ($balance->isDirty('paid_at')) {
|
||||
if ($balance->paid_at) {
|
||||
$balance->notify(new UserCharged());
|
||||
broadcast(new Users($balance->user, 'balance.updated', $balance));
|
||||
|
||||
$balance->user->charge($balance->amount, $balance->payment, $balance->order_id);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function user(): BelongsToAlias
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
|
@ -5,7 +5,6 @@
|
||||
use App\Events\Users;
|
||||
use App\Jobs\Host\HostJob;
|
||||
use App\Jobs\Host\UpdateOrDeleteHostJob;
|
||||
use App\Notifications\WebNotification;
|
||||
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
@ -36,82 +35,6 @@ class Host extends Model
|
||||
'managed_price' => 'decimal:2',
|
||||
];
|
||||
|
||||
protected static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
static::creating(function ($model) {
|
||||
$model->hour_at = now()->hour;
|
||||
$model->minute_at = now()->minute;
|
||||
|
||||
if ($model->price !== null) {
|
||||
$model->price = bcdiv($model->price, 1, 2);
|
||||
}
|
||||
|
||||
if ($model->managed_price !== null) {
|
||||
$model->managed_price = bcdiv($model->managed_price, 1, 2);
|
||||
}
|
||||
});
|
||||
|
||||
static::created(function (self $model) {
|
||||
$model->load('module');
|
||||
|
||||
// model price 使用 bcmul 保留两位小数
|
||||
$model->price = bcmul($model->price, 1, 2);
|
||||
|
||||
$model->user->notify(new WebNotification($model, 'hosts.created'));
|
||||
});
|
||||
|
||||
static::updating(function (self $model) {
|
||||
if ($model->isDirty('status')) {
|
||||
if ($model->status == 'suspended') {
|
||||
$model->suspended_at = now();
|
||||
} else {
|
||||
$model->suspended_at = null;
|
||||
}
|
||||
|
||||
if ($model->status == 'locked') {
|
||||
$model->locked_at = now();
|
||||
} else {
|
||||
$model->locked_at = null;
|
||||
}
|
||||
|
||||
if ($model->status == 'unavailable') {
|
||||
$model->unavailable_at = now();
|
||||
} else {
|
||||
$model->unavailable_at = null;
|
||||
}
|
||||
}
|
||||
|
||||
// 调度任务
|
||||
if ($model->status !== 'unavailable') {
|
||||
dispatch(new HostJob($model, 'patch'));
|
||||
}
|
||||
|
||||
broadcast(new Users($model->user_id, 'hosts.updating', $model));
|
||||
});
|
||||
|
||||
// when Updated
|
||||
static::updated(function ($model) {
|
||||
broadcast(new Users($model->user_id, 'hosts.updated', $model));
|
||||
});
|
||||
|
||||
//
|
||||
// static::deleting(function ($model) {
|
||||
// broadcast(new Users($model->user_id, 'hosts.deleting', $model));
|
||||
// });
|
||||
|
||||
static::deleting(function ($model) {
|
||||
Cache::forget('user_tasks_'.$model->user_id);
|
||||
});
|
||||
|
||||
static::deleted(function ($model) {
|
||||
broadcast(new Users($model->user_id, 'hosts.deleted', $model));
|
||||
Cache::forget('user_tasks_'.$model->user_id);
|
||||
Cache::forget('user_hosts_'.$model->user_id);
|
||||
});
|
||||
}
|
||||
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
public function getUserHosts($user_id = null): array|Collection
|
||||
{
|
||||
|
@ -14,7 +14,6 @@
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Str;
|
||||
use JetBrains\PhpStorm\ArrayShape;
|
||||
|
||||
class Module extends Authenticatable
|
||||
@ -46,33 +45,6 @@ class Module extends Authenticatable
|
||||
'balance' => 'decimal:4',
|
||||
];
|
||||
|
||||
protected static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
static::creating(function (self $model) {
|
||||
if (! app()->environment('local')) {
|
||||
$model->api_token = Str::random(60);
|
||||
}
|
||||
|
||||
// 如果设置了 url 并且结尾有 / 则去掉
|
||||
if ($model->url) {
|
||||
$model->url = rtrim($model->url, '/');
|
||||
}
|
||||
});
|
||||
static::updating(function (self $model) {
|
||||
// 如果结尾有 / 则去掉
|
||||
$model->url = rtrim($model->url, '/');
|
||||
});
|
||||
}
|
||||
|
||||
// public function moduleHostFunctions($host_id, $func, $requests): array
|
||||
// {
|
||||
// $http = Http::module($this->api_token, $this->url);
|
||||
// $response = $http->post("hosts/{$host_id}/functions/" . $func, $requests);
|
||||
//
|
||||
// return $this->getResponse($response);
|
||||
// }
|
||||
|
||||
// post, get, patch, delete 等请求
|
||||
public function remote($func, $requests): array
|
||||
{
|
||||
|
@ -2,13 +2,8 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Events\Users;
|
||||
use App\Exceptions\CommonException;
|
||||
use function auth;
|
||||
use function broadcast;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
|
||||
class Task extends Model
|
||||
{
|
||||
@ -30,64 +25,6 @@ class Task extends Model
|
||||
// key type string
|
||||
protected $keyType = 'string';
|
||||
|
||||
protected static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
static::creating(function (self $model) {
|
||||
// id 为 uuid
|
||||
$model->id = Uuid::uuid4()->toString();
|
||||
|
||||
// 如果是模块创建的任务
|
||||
if (auth('module')->check()) {
|
||||
$model->module_id = auth('module')->id();
|
||||
}
|
||||
|
||||
// host_id 和 user_id 至少存在一个
|
||||
if (! $model->host_id && ! $model->user_id) {
|
||||
throw new CommonException('host_id 和 user_id 至少存在一个');
|
||||
}
|
||||
|
||||
// if host_id
|
||||
if ($model->host_id) {
|
||||
$model->load('host');
|
||||
|
||||
if ($model->host === null) {
|
||||
throw new CommonException('host_id 不存在');
|
||||
}
|
||||
|
||||
$model->user_id = $model->host->user_id;
|
||||
}
|
||||
});
|
||||
|
||||
// created
|
||||
static::created(function (self $model) {
|
||||
$model->load('host');
|
||||
broadcast(new Users($model->user_id, 'tasks.created', $model));
|
||||
});
|
||||
|
||||
// updating
|
||||
static::updating(function (self $model) {
|
||||
if ($model->progress == 100) {
|
||||
$model->status = 'done';
|
||||
}
|
||||
});
|
||||
|
||||
// updated and delete
|
||||
static::updated(function (self $model) {
|
||||
$model->load('host');
|
||||
broadcast(new Users($model->user_id, 'tasks.updated', $model));
|
||||
});
|
||||
|
||||
static::deleted(function (self $model) {
|
||||
broadcast(new Users($model->user_id, 'tasks.deleted', $model));
|
||||
});
|
||||
}
|
||||
|
||||
// public function scopeUser($query)
|
||||
// {
|
||||
// return $query->where('user_id', auth()->id());
|
||||
// }
|
||||
|
||||
public function host(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Host::class);
|
||||
|
@ -3,7 +3,6 @@
|
||||
namespace App\Models;
|
||||
|
||||
use App\Exceptions\User\BalanceNotEnoughException;
|
||||
use Carbon\Exceptions\InvalidFormatException;
|
||||
use GeneaLabs\LaravelModelCaching\CachedBuilder;
|
||||
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
@ -21,7 +20,6 @@
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Str;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
|
||||
class User extends Authenticatable implements MustVerifyEmail
|
||||
@ -77,55 +75,6 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
'birthday_at',
|
||||
];
|
||||
|
||||
protected static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
static::creating(function (self $user) {
|
||||
$user->email_md5 = md5($user->email);
|
||||
$user->uuid = Str::uuid();
|
||||
});
|
||||
|
||||
static::updating(function (self $user) {
|
||||
if ($user->isDirty('banned_at')) {
|
||||
if ($user->banned_at) {
|
||||
$user->tokens()->delete();
|
||||
$user->hosts()->update(['status' => 'suspended', 'suspended_at' => now()]);
|
||||
} else {
|
||||
$user->hosts()->update(['status' => 'stopped']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($user->isDirty('email')) {
|
||||
$user->email_md5 = md5($user->email);
|
||||
}
|
||||
|
||||
if ($user->isDirty('id_card')) {
|
||||
$user->id_card = Crypt::encryptString($user->id_card);
|
||||
}
|
||||
|
||||
if ($user->isDirty('id_card') || $user->isDirty('real_name')) {
|
||||
if (empty($user->id_card) || empty($user->real_name)) {
|
||||
$user->real_name_verified_at = null;
|
||||
} else {
|
||||
$user->real_name_verified_at = now();
|
||||
|
||||
// 更新生日
|
||||
// try {
|
||||
// $user->birthday_at = $user->getBirthdayFromIdCard();
|
||||
// } catch (InvalidFormatException) {
|
||||
// $user->birthday_at = null;
|
||||
// }
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
static::deleting(function (self $user) {
|
||||
$user->tokens()->delete();
|
||||
$user->hosts()->update(['status' => 'suspended', 'suspended_at' => now()]);
|
||||
});
|
||||
}
|
||||
|
||||
public function hosts(): HasMany
|
||||
{
|
||||
return $this->hasMany(Host::class);
|
||||
|
34
app/Observers/BalanceObserver.php
Normal file
34
app/Observers/BalanceObserver.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Observers;
|
||||
|
||||
use App\Events\Users;
|
||||
use App\Models\Balance;
|
||||
use App\Notifications\User\UserCharged;
|
||||
|
||||
class BalanceObserver
|
||||
{
|
||||
public function creating(Balance $balance): void
|
||||
{
|
||||
$balance->remaining_amount = 0;
|
||||
|
||||
$balance->order_id = date('YmdHis').'-'.$balance->id.'-'.$balance->user_id.'-'.rand(1000, 9999);
|
||||
}
|
||||
|
||||
public function created(Balance $balance): void
|
||||
{
|
||||
broadcast(new Users($balance->user, 'balance.created', $balance));
|
||||
}
|
||||
|
||||
public function updated(Balance $balance): void
|
||||
{
|
||||
if ($balance->isDirty('paid_at')) {
|
||||
if ($balance->paid_at) {
|
||||
$balance->notify(new UserCharged());
|
||||
broadcast(new Users($balance->user, 'balance.updated', $balance));
|
||||
|
||||
$balance->user->charge($balance->amount, $balance->payment, $balance->order_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
93
app/Observers/HostObserver.php
Normal file
93
app/Observers/HostObserver.php
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace App\Observers;
|
||||
|
||||
use App\Events\Users;
|
||||
use App\Jobs\Host\HostJob;
|
||||
use App\Models\Host;
|
||||
use App\Notifications\WebNotification;
|
||||
|
||||
class HostObserver
|
||||
{
|
||||
public function creating(Host $host): void
|
||||
{
|
||||
$host->hour_at = now()->hour;
|
||||
$host->minute_at = now()->minute;
|
||||
|
||||
if ($host->price !== null) {
|
||||
$host->price = bcdiv($host->price, 1, 2);
|
||||
}
|
||||
|
||||
if ($host->managed_price !== null) {
|
||||
$host->managed_price = bcdiv($host->managed_price, 1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the Host "created" event.
|
||||
*
|
||||
* @param Host $host
|
||||
* @return void
|
||||
*/
|
||||
public function created(Host $host): void
|
||||
{
|
||||
$host->load('module');
|
||||
|
||||
// model price 使用 bcmul 保留两位小数
|
||||
$host->price = bcmul($host->price, 1, 2);
|
||||
|
||||
$host->user->notify(new WebNotification($host, 'hosts.created'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the Host "updated" event.
|
||||
*
|
||||
* @param Host $host
|
||||
* @return void
|
||||
*/
|
||||
public function updating(Host $host): void
|
||||
{
|
||||
if ($host->isDirty('status')) {
|
||||
if ($host->status == 'suspended') {
|
||||
$host->suspended_at = now();
|
||||
} else {
|
||||
$host->suspended_at = null;
|
||||
}
|
||||
|
||||
if ($host->status == 'locked') {
|
||||
$host->locked_at = now();
|
||||
} else {
|
||||
$host->locked_at = null;
|
||||
}
|
||||
|
||||
if ($host->status == 'unavailable') {
|
||||
$host->unavailable_at = now();
|
||||
} else {
|
||||
$host->unavailable_at = null;
|
||||
}
|
||||
}
|
||||
|
||||
// 调度任务
|
||||
if ($host->status !== 'unavailable') {
|
||||
dispatch(new HostJob($host, 'patch'));
|
||||
}
|
||||
|
||||
broadcast(new Users($host->user_id, 'hosts.updating', $host));
|
||||
}
|
||||
|
||||
public function updated(Host $host): void
|
||||
{
|
||||
broadcast(new Users($host->user_id, 'hosts.updated', $host));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the Host "deleted" event.
|
||||
*
|
||||
* @param Host $host
|
||||
* @return void
|
||||
*/
|
||||
public function deleted(Host $host): void
|
||||
{
|
||||
broadcast(new Users($host->user_id, 'hosts.deleted', $host));
|
||||
}
|
||||
}
|
26
app/Observers/ModuleObserver.php
Normal file
26
app/Observers/ModuleObserver.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Observers;
|
||||
|
||||
use App\Models\Module;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class ModuleObserver
|
||||
{
|
||||
public function creating(Module $module): void
|
||||
{
|
||||
if (! app()->environment('local')) {
|
||||
$module->api_token = Str::random(60);
|
||||
}
|
||||
|
||||
// 如果设置了 url 并且结尾有 / 则去掉
|
||||
if ($module->url) {
|
||||
$module->url = rtrim($module->url, '/');
|
||||
}
|
||||
}
|
||||
|
||||
public function updating(Module $module): void
|
||||
{
|
||||
$module->url = rtrim($module->url, '/');
|
||||
}
|
||||
}
|
66
app/Observers/TaskObserver.php
Normal file
66
app/Observers/TaskObserver.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace App\Observers;
|
||||
|
||||
use App\Events\Users;
|
||||
use App\Exceptions\CommonException;
|
||||
use App\Models\Task;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
|
||||
class TaskObserver
|
||||
{
|
||||
/**
|
||||
* @throws CommonException
|
||||
*/
|
||||
public function creating(Task $task): void
|
||||
{
|
||||
// id 为 uuid
|
||||
$task->id = Uuid::uuid4()->toString();
|
||||
|
||||
// 如果是模块创建的任务
|
||||
if (auth('module')->check()) {
|
||||
$task->module_id = auth('module')->id();
|
||||
}
|
||||
|
||||
// host_id 和 user_id 至少存在一个
|
||||
if (! $task->host_id && ! $task->user_id) {
|
||||
throw new CommonException('host_id 和 user_id 至少存在一个');
|
||||
}
|
||||
|
||||
// if host_id
|
||||
if ($task->host_id) {
|
||||
$task->load('host');
|
||||
|
||||
if ($task->host === null) {
|
||||
throw new CommonException('host_id 不存在');
|
||||
}
|
||||
|
||||
$task->user_id = $task->host->user_id;
|
||||
}
|
||||
}
|
||||
|
||||
public function created(Task $task): void
|
||||
{
|
||||
$task->load('host');
|
||||
broadcast(new Users($task->user_id, 'tasks.created', $task));
|
||||
}
|
||||
|
||||
// updating
|
||||
public function updating(Task $task): void
|
||||
{
|
||||
if ($task->progress == 100) {
|
||||
$task->status = 'done';
|
||||
}
|
||||
}
|
||||
|
||||
public function updated(Task $task): void
|
||||
{
|
||||
$task->load('host');
|
||||
broadcast(new Users($task->user_id, 'tasks.updated', $task));
|
||||
}
|
||||
|
||||
public function deleted(Task $task): void
|
||||
{
|
||||
broadcast(new Users($task->user_id, 'tasks.deleted', $task));
|
||||
}
|
||||
}
|
50
app/Observers/UserObserver.php
Normal file
50
app/Observers/UserObserver.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace App\Observers;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class UserObserver
|
||||
{
|
||||
public function creating(User $user): void
|
||||
{
|
||||
$user->email_md5 = md5($user->email);
|
||||
$user->uuid = Str::uuid();
|
||||
}
|
||||
|
||||
public function updating(User $user): void
|
||||
{
|
||||
if ($user->isDirty('banned_at')) {
|
||||
if ($user->banned_at) {
|
||||
$user->tokens()->delete();
|
||||
$user->hosts()->update(['status' => 'suspended', 'suspended_at' => now()]);
|
||||
} else {
|
||||
$user->hosts()->update(['status' => 'stopped']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($user->isDirty('email')) {
|
||||
$user->email_md5 = md5($user->email);
|
||||
}
|
||||
|
||||
if ($user->isDirty('id_card')) {
|
||||
$user->id_card = Crypt::encryptString($user->id_card);
|
||||
}
|
||||
|
||||
if ($user->isDirty('id_card') || $user->isDirty('real_name')) {
|
||||
if (empty($user->id_card) || empty($user->real_name)) {
|
||||
$user->real_name_verified_at = null;
|
||||
} else {
|
||||
$user->real_name_verified_at = now();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function deleting(User $user): void
|
||||
{
|
||||
$user->tokens()->delete();
|
||||
$user->hosts()->update(['status' => 'suspended', 'suspended_at' => now()]);
|
||||
}
|
||||
}
|
@ -2,7 +2,17 @@
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Models\Balance;
|
||||
use App\Models\Host;
|
||||
use App\Models\Module;
|
||||
use App\Models\PersonalAccessToken;
|
||||
use App\Models\Task;
|
||||
use App\Models\User;
|
||||
use App\Observers\BalanceObserver;
|
||||
use App\Observers\HostObserver;
|
||||
use App\Observers\ModuleObserver;
|
||||
use App\Observers\TaskObserver;
|
||||
use App\Observers\UserObserver;
|
||||
use Illuminate\Pagination\Paginator;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
@ -43,5 +53,16 @@ public function boot(): void
|
||||
});
|
||||
|
||||
// Carbon::setTestNow(now()->addDays(1));
|
||||
|
||||
$this->registerObservers();
|
||||
}
|
||||
|
||||
private function registerObservers(): void
|
||||
{
|
||||
User::observe(UserObserver::class);
|
||||
Host::observe(HostObserver::class);
|
||||
Task::observe(TaskObserver::class);
|
||||
Module::observe(ModuleObserver::class);
|
||||
Balance::observe(BalanceObserver::class);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user