diff --git a/app/Models/Balance.php b/app/Models/Balance.php index 06d8298..247b052 100644 --- a/app/Models/Balance.php +++ b/app/Models/Balance.php @@ -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); diff --git a/app/Models/Host.php b/app/Models/Host.php index e34934e..caf021d 100644 --- a/app/Models/Host.php +++ b/app/Models/Host.php @@ -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 { diff --git a/app/Models/Module.php b/app/Models/Module.php index 61c494b..8cb76e3 100644 --- a/app/Models/Module.php +++ b/app/Models/Module.php @@ -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 { diff --git a/app/Models/Task.php b/app/Models/Task.php index e52fa65..32a66b2 100644 --- a/app/Models/Task.php +++ b/app/Models/Task.php @@ -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); diff --git a/app/Models/User.php b/app/Models/User.php index e6ac4ee..41e124e 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -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); diff --git a/app/Observers/BalanceObserver.php b/app/Observers/BalanceObserver.php new file mode 100644 index 0000000..a2d2534 --- /dev/null +++ b/app/Observers/BalanceObserver.php @@ -0,0 +1,34 @@ +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); + } + } + } +} diff --git a/app/Observers/HostObserver.php b/app/Observers/HostObserver.php new file mode 100644 index 0000000..4604b2c --- /dev/null +++ b/app/Observers/HostObserver.php @@ -0,0 +1,93 @@ +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)); + } +} diff --git a/app/Observers/ModuleObserver.php b/app/Observers/ModuleObserver.php new file mode 100644 index 0000000..a6d1bab --- /dev/null +++ b/app/Observers/ModuleObserver.php @@ -0,0 +1,26 @@ +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, '/'); + } +} diff --git a/app/Observers/TaskObserver.php b/app/Observers/TaskObserver.php new file mode 100644 index 0000000..653d46e --- /dev/null +++ b/app/Observers/TaskObserver.php @@ -0,0 +1,66 @@ +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)); + } +} diff --git a/app/Observers/UserObserver.php b/app/Observers/UserObserver.php new file mode 100644 index 0000000..b0d3834 --- /dev/null +++ b/app/Observers/UserObserver.php @@ -0,0 +1,50 @@ +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()]); + } +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 7521977..cea3f05 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -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); } }