From 041a588023703d599be8a4fe175efd5f997fdad4 Mon Sep 17 00:00:00 2001 From: panliang <1163816051@qq.com> Date: Tue, 9 May 2023 19:07:47 +0800 Subject: [PATCH 1/4] api region --- app/Admin/Components.php | 9 ++-- app/Casts/Storage.php | 51 +++++++++++++++++++ app/Http/Controllers/Api/RegionController.php | 27 ++++++++++ app/Http/Resources/RegionCategoryResource.php | 24 +++++++++ app/Http/Resources/RegionResource.php | 28 ++++++++++ app/Models/Article.php | 14 ++--- app/Models/Banner.php | 12 +---- app/Models/Region.php | 42 +++++++++++++-- app/Models/RegionCategory.php | 18 +++++++ app/Models/RegionPlantLog.php | 4 +- app/Services/Admin/CropHarvestService.php | 7 ++- ...111915_create_plant_harvest_logs_table.php | 1 + database/seeders/DatabaseSeeder.php | 1 + routes/api.php | 18 ++++--- 14 files changed, 216 insertions(+), 40 deletions(-) create mode 100644 app/Casts/Storage.php create mode 100644 app/Http/Controllers/Api/RegionController.php create mode 100644 app/Http/Resources/RegionCategoryResource.php create mode 100644 app/Http/Resources/RegionResource.php diff --git a/app/Admin/Components.php b/app/Admin/Components.php index 53aab56..28b3b87 100644 --- a/app/Admin/Components.php +++ b/app/Admin/Components.php @@ -51,12 +51,13 @@ class Components extends BaseRenderer { ->options([ "menubar" => false, "min_height" => 500, - "toolbar" => "undo redo | bold italic underline strikethrough | fontfamily fontsize blocks | alignleft aligncenter alignright alignjustify | image link | outdent indent | numlist bullist | forecolor backcolor removeformat | charmap emoticons", + "plugins" => 'image link table lists charmap emoticons code table fullscreen', + "toolbar" => "undo redo | bold italic underline strikethrough | fontfamily fontsize blocks | alignleft aligncenter alignright alignjustify | image link | outdent indent | numlist bullist table | forecolor backcolor removeformat | charmap emoticons | code fullscreen", + "toolbar_mode" => "wrap", "help_tabs" => [], "convert_urls" => false, - "quickbars_selection_toolbar" => "fontsize forecolor backcolor", - "toolbar_mode" => "wrap", - "quickbars_insert_toolbar" => false, + // "quickbars_selection_toolbar" => "fontsize forecolor backcolor", + // "quickbars_insert_toolbar" => false, ]) ->receiver(admin_url('upload_rich')) ->name($name) diff --git a/app/Casts/Storage.php b/app/Casts/Storage.php new file mode 100644 index 0000000..8705ee0 --- /dev/null +++ b/app/Casts/Storage.php @@ -0,0 +1,51 @@ +disk = $disk; + } + + /** + * Cast the given value. + * + * @param \Illuminate\Database\Eloquent\Model $model + * @param string $key + * @param mixed $value + * @param array $attributes + * @return array + */ + public function get($model, $key, $value, $attributes) + { + return $value ? (Str::startsWith($value, ['http://', 'https://']) ? $value : StorageFacades::disk($this->disk)->url($value)) : ''; + } + + /** + * Prepare the given value for storage. + * + * @param \Illuminate\Database\Eloquent\Model $model + * @param string $key + * @param array $value + * @param array $attributes + * @return string + */ + public function set($model, $key, $value, $attributes) + { + return $value; + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Api/RegionController.php b/app/Http/Controllers/Api/RegionController.php new file mode 100644 index 0000000..aa27475 --- /dev/null +++ b/app/Http/Controllers/Api/RegionController.php @@ -0,0 +1,27 @@ +show()->sort()->get(); + + return $this->json(RegionCategoryResource::collection($list)); + } + + public function index(Request $request) + { + $query = Region::query()->sort()->show(); + + $list = $query->paginate($request->input('per_page')); + + return $this->json(RegionResource::collection($list)); + } +} diff --git a/app/Http/Resources/RegionCategoryResource.php b/app/Http/Resources/RegionCategoryResource.php new file mode 100644 index 0000000..07dd3fd --- /dev/null +++ b/app/Http/Resources/RegionCategoryResource.php @@ -0,0 +1,24 @@ + $this->id, + 'name' => $this->name, + 'icon' => $this->icon, + 'description' => $this->description, + ]; + } +} diff --git a/app/Http/Resources/RegionResource.php b/app/Http/Resources/RegionResource.php new file mode 100644 index 0000000..0fbd93a --- /dev/null +++ b/app/Http/Resources/RegionResource.php @@ -0,0 +1,28 @@ + $this->id, + 'name' => $this->name, + 'cover' => $this->cover, + 'director' => $this->director, + 'area' => $this->area, + 'description' => $this->description, + 'category_id' => $this->category_id, + 'category' => RegionCategoryResource::make($this->whenLoaded('category')), + ]; + } +} diff --git a/app/Models/Article.php b/app/Models/Article.php index c45a8d1..fd61ca6 100644 --- a/app/Models/Article.php +++ b/app/Models/Article.php @@ -2,12 +2,10 @@ namespace App\Models; -use Illuminate\Support\Str; +use App\Casts\Storage; use EloquentFilter\Filterable; use Illuminate\Database\Eloquent\Model; -use Illuminate\Support\Facades\Storage; -use Illuminate\Database\Eloquent\Casts\Attribute; -use Illuminate\Database\Eloquent\Factories\HasFactory; + /** * 文章 */ @@ -23,15 +21,9 @@ class Article extends Model 'published_at' => 'datetime:Y-m-d H:i:s', 'is_enable' => 'boolean', 'is_recommend' => 'boolean', + 'cover' => Storage::class, ]; - protected function cover(): Attribute - { - return Attribute::make( - get: fn($value) => $value ? (Str::startsWith($value, ['http://', 'https://']) ? $value : Storage::url($value)) : '', - ); - } - public function category() { return $this->belongsTo(ArticleCategory::class, 'category_id'); diff --git a/app/Models/Banner.php b/app/Models/Banner.php index 467a09f..b6d6258 100644 --- a/app/Models/Banner.php +++ b/app/Models/Banner.php @@ -2,13 +2,11 @@ namespace App\Models; +use App\Casts\Storage; use Illuminate\Support\Str; use App\Filters\BannerFilter; use EloquentFilter\Filterable; use Illuminate\Database\Eloquent\Model; -use Illuminate\Support\Facades\Storage; -use Illuminate\Database\Eloquent\Casts\Attribute; -use Illuminate\Database\Eloquent\Factories\HasFactory; /** * 广告图 @@ -25,15 +23,9 @@ class Banner extends Model 'published_at' => 'datetime:Y-m-d H:i:s', 'is_enable' => 'boolean', 'link_config' => 'json', + 'picture' => Storage::class, ]; - protected function picture(): Attribute - { - return Attribute::make( - get: fn($value) => $value ? (Str::startsWith($value, ['http://', 'https://']) ? $value : Storage::url($value)) : '', - ); - } - public function place() { return $this->belongsTo(BannerPlace::class, 'place_id'); diff --git a/app/Models/Region.php b/app/Models/Region.php index b138c29..14b23a7 100644 --- a/app/Models/Region.php +++ b/app/Models/Region.php @@ -2,10 +2,14 @@ namespace App\Models; -use Illuminate\Database\Eloquent\Factories\HasFactory; -use Illuminate\Database\Eloquent\Model; +use App\Casts\Storage; use EloquentFilter\Filterable; +use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Factories\HasFactory; +/** + * 实验田 + */ class Region extends Model { use HasFactory; @@ -16,15 +20,45 @@ class Region extends Model 'sort', 'is_recommend','is_enable' ]; + protected $casts = [ + 'cover' => Storage::class, + ]; + protected function serializeDate(\DateTimeInterface $date){ return $date->format('Y-m-d H:i:s'); } - public function category(){ + public function scopeShow($q) + { + return $q->where('is_enable', 1); + } + + public function scopeSort($q) + { + return $q->orderBy('sort', 'desc')->latest('id'); + } + + // 试验田分类 + public function category() + { return $this->belongsTo(RegionCategory::class, 'category_id'); } - public function devices(){ + // 关联设备 + public function devices() + { return $this->belongsToMany(Device::class, RegionDevice::class, 'region_id', 'device_id')->withTimestamps(); } + + // 种植记录 + public function plants() + { + return $this->hasMany(RegionPlantLog::class, 'region_id'); + } + + // 收货记录 + public function harvest() + { + return $this->hasMany(PlantHarvestLog::class, 'region_id'); + } } diff --git a/app/Models/RegionCategory.php b/app/Models/RegionCategory.php index 58fe2cb..1ac3b3a 100644 --- a/app/Models/RegionCategory.php +++ b/app/Models/RegionCategory.php @@ -5,13 +5,21 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use EloquentFilter\Filterable; +use App\Casts\Storage; +/** + * 区域分类 + */ class RegionCategory extends Model { use HasFactory; use Filterable; protected $fillable = ['name', 'icon', 'description', 'parent_id', 'level', 'sort', 'path', 'is_enable']; + + protected $casts = [ + 'icon' => Storage::class, + ]; protected function serializeDate(\DateTimeInterface $date){ return $date->format('Y-m-d H:i:s'); @@ -41,4 +49,14 @@ class RegionCategory extends Model { return $this->belongsTo(self::class, 'parent_id'); } + + public function scopeShow($q) + { + return $q->where('is_enable', 1); + } + + public function scopeSort($q) + { + return $q->orderBy('sort', 'desc')->latest('id'); + } } diff --git a/app/Models/RegionPlantLog.php b/app/Models/RegionPlantLog.php index 2a78026..0e5036b 100644 --- a/app/Models/RegionPlantLog.php +++ b/app/Models/RegionPlantLog.php @@ -19,9 +19,9 @@ class RegionPlantLog extends Model //1进行中,2已结束 protected function plantState():Attribute - { + { return Attribute::make( - get:fn($value, $attributes) => $attributes['end_at'] ? 2:1, + get: fn($value) => $this->end_at ? 2 : 1, ); } diff --git a/app/Services/Admin/CropHarvestService.php b/app/Services/Admin/CropHarvestService.php index cd0d463..e3747d7 100644 --- a/app/Services/Admin/CropHarvestService.php +++ b/app/Services/Admin/CropHarvestService.php @@ -2,7 +2,7 @@ namespace App\Services\Admin; -use App\Models\PlantHarvestLog; +use App\Models\{PlantHarvestLog, RegionPlantLog}; use App\Filters\Admin\PlantHarvestLogFilter; use Illuminate\Support\Arr; use Throwable; @@ -21,7 +21,7 @@ class CropHarvestService extends BaseService public function store($data): bool { $columns = $this->getTableColumns(); - $model = $this->getModel(); + $model = $this->getModel(); foreach ($data as $k => $v) { if (!in_array($k, $columns)) { @@ -29,6 +29,9 @@ class CropHarvestService extends BaseService } $model->setAttribute($k, $v); } + if ($model->plant_id) { + $model->region_id = RegionPlantLog::where('id', $model->plant_id)->value('region_id'); + } try{ DB::beginTransaction(); diff --git a/database/migrations/2023_03_21_111915_create_plant_harvest_logs_table.php b/database/migrations/2023_03_21_111915_create_plant_harvest_logs_table.php index 74170f4..c15fdbf 100644 --- a/database/migrations/2023_03_21_111915_create_plant_harvest_logs_table.php +++ b/database/migrations/2023_03_21_111915_create_plant_harvest_logs_table.php @@ -15,6 +15,7 @@ return new class extends Migration { Schema::create('plant_harvest_logs', function (Blueprint $table) { $table->id(); + $table->unsignedBigInteger('region_id'); $table->unsignedBigInteger('plant_id'); $table->string('director')->nullable()->comment('负责人'); $table->decimal('area')->default(0.00)->comment('面积/平米'); diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index d198219..0b55628 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -20,5 +20,6 @@ class DatabaseSeeder extends Seeder $this->call(KeywordSeeder::class); $this->call(BannerSeeder::class); $this->call(SettingSeeder::class); + $this->call(RegionCategorySeeder::class); } } diff --git a/routes/api.php b/routes/api.php index 09872b0..45a342f 100644 --- a/routes/api.php +++ b/routes/api.php @@ -2,6 +2,7 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; +use App\Http\Controllers\Api\{BannerController, AdminNoticeController, ArticleController, RegionController}; /* |-------------------------------------------------------------------------- @@ -14,12 +15,15 @@ use Illuminate\Support\Facades\Route; | */ -Route::get('banner', [\App\Http\Controllers\Api\BannerController::class, 'index']); +Route::get('banner', [BannerController::class, 'index']); -Route::get('notice', [\App\Http\Controllers\Api\AdminNoticeController::class, 'index']); -Route::get('notice/{id}', [\App\Http\Controllers\Api\AdminNoticeController::class, 'show']); +Route::get('notice', [AdminNoticeController::class, 'index']); +Route::get('notice/{id}', [AdminNoticeController::class, 'show']); -Route::get('article/category', [\App\Http\Controllers\Api\ArticleController::class, 'category']); -Route::get('article/tree', [\App\Http\Controllers\Api\ArticleController::class, 'tree']); -Route::get('article', [\App\Http\Controllers\Api\ArticleController::class, 'index']); -Route::get('article/{id}', [\App\Http\Controllers\Api\ArticleController::class, 'show']); +Route::get('article/category', [ArticleController::class, 'category']); +Route::get('article/tree', [ArticleController::class, 'tree']); +Route::get('article', [ArticleController::class, 'index']); +Route::get('article/{id}', [ArticleController::class, 'show']); + +Route::get('region/category', [RegionController::class, 'category']); +Route::get('region', [RegionController::class, 'index']); From cbf27302e47c66657acf1a4e689c6c9c73a87430 Mon Sep 17 00:00:00 2001 From: panliang <1163816051@qq.com> Date: Tue, 9 May 2023 19:38:52 +0800 Subject: [PATCH 2/4] api region harvest --- app/Http/Controllers/Api/RegionController.php | 28 +++++++++++++++++-- app/Http/Resources/PlantHarvestResource.php | 27 ++++++++++++++++++ app/Http/Resources/RegionPlantResource.php | 27 ++++++++++++++++++ app/Http/Resources/RegionResource.php | 1 + app/Models/Region.php | 14 +++++++--- app/Models/RegionPlantLog.php | 7 ++++- routes/api.php | 3 ++ 7 files changed, 100 insertions(+), 7 deletions(-) create mode 100644 app/Http/Resources/PlantHarvestResource.php create mode 100644 app/Http/Resources/RegionPlantResource.php diff --git a/app/Http/Controllers/Api/RegionController.php b/app/Http/Controllers/Api/RegionController.php index aa27475..61c882c 100644 --- a/app/Http/Controllers/Api/RegionController.php +++ b/app/Http/Controllers/Api/RegionController.php @@ -5,7 +5,8 @@ namespace App\Http\Controllers\Api; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use App\Models\{Region, RegionCategory}; -use App\Http\Resources\{RegionResource, RegionCategoryResource}; +use App\Http\Resources\{RegionResource, RegionCategoryResource, RegionPlantResource, PlantHarvestResource}; +use App\Filters\Admin\RegionFilter; class RegionController extends Controller { @@ -18,10 +19,33 @@ class RegionController extends Controller public function index(Request $request) { - $query = Region::query()->sort()->show(); + $query = Region::with(['currentPlant'])->filter($request->all(), RegionFilter::class)->sort()->show(); $list = $query->paginate($request->input('per_page')); return $this->json(RegionResource::collection($list)); } + + public function show($id) + { + $info = Region::with(['currentPlant'])->show()->findOrFail($id); + + return $this->json(RegionResource::make($info)); + } + + public function plants($id) + { + $info = Region::show()->findOrFail($id); + $list = $info->plants()->get(); + + return $this->json(RegionPlantResource::collection($list)); + } + + public function harvests($id) + { + $info = Region::show()->findOrFail($id); + $list = $info->harvests()->get(); + + return $this->json(PlantHarvestResource::collection($list)); + } } diff --git a/app/Http/Resources/PlantHarvestResource.php b/app/Http/Resources/PlantHarvestResource.php new file mode 100644 index 0000000..88cbaa2 --- /dev/null +++ b/app/Http/Resources/PlantHarvestResource.php @@ -0,0 +1,27 @@ + $this->id, + 'plant_id' => $this->plant_id, + 'region_id' => $this->region_id, + 'director' => $this->director, + 'area' => $this->area, + 'output' => $this->output, + 'harvest_at' => $this->harvest_at ? $this->harvest_at->timestamp : '', + ]; + } +} diff --git a/app/Http/Resources/RegionPlantResource.php b/app/Http/Resources/RegionPlantResource.php new file mode 100644 index 0000000..9ec2393 --- /dev/null +++ b/app/Http/Resources/RegionPlantResource.php @@ -0,0 +1,27 @@ + $this->id, + 'plant_name' => $this->plant_name, + 'director' => $this->director, + 'area' => $this->area, + 'start_at' => $this->start_at ? $this->start_at->timestamp : '', + 'end_at' => $this->end_at ? $this->end_at->timestamp : '', + 'plant_state' => $this->plant_state, + ]; + } +} diff --git a/app/Http/Resources/RegionResource.php b/app/Http/Resources/RegionResource.php index 0fbd93a..4f79e8f 100644 --- a/app/Http/Resources/RegionResource.php +++ b/app/Http/Resources/RegionResource.php @@ -23,6 +23,7 @@ class RegionResource extends JsonResource 'description' => $this->description, 'category_id' => $this->category_id, 'category' => RegionCategoryResource::make($this->whenLoaded('category')), + 'current_plant' => RegionPlantResource::make($this->whenLoaded('currentPlant')), ]; } } diff --git a/app/Models/Region.php b/app/Models/Region.php index 668207c..7101f1b 100644 --- a/app/Models/Region.php +++ b/app/Models/Region.php @@ -53,15 +53,21 @@ class Region extends Model // 种植记录 public function plants() { - return $this->hasMany(RegionPlantLog::class, 'region_id'); + return $this->hasMany(RegionPlantLog::class, 'region_id')->orderBy('start_at', 'desc'); + } + + // 当前种植 + public function currentPlant() + { + return $this->hasOne(RegionPlantLog::class, 'region_id')->orderBy('start_at', 'desc'); } // 收货记录 - public function harvest() + public function harvests() { - return $this->hasMany(PlantHarvestLog::class, 'region_id'); + return $this->hasMany(PlantHarvestLog::class, 'region_id')->orderBy('harvest_at', 'desc'); } - + public static function regionTabConfig($region = null){ $tabs = [ [ diff --git a/app/Models/RegionPlantLog.php b/app/Models/RegionPlantLog.php index 0e5036b..089b6e9 100644 --- a/app/Models/RegionPlantLog.php +++ b/app/Models/RegionPlantLog.php @@ -6,6 +6,9 @@ use EloquentFilter\Filterable; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Model; +/** + * 种植记录 + */ class RegionPlantLog extends Model { use Filterable; @@ -25,7 +28,9 @@ class RegionPlantLog extends Model ); } - public function harvestes(){ + // 收获记录 + public function harvestes() + { return $this->hasMany(PlantHarvestLog::class, 'plant_id'); } } diff --git a/routes/api.php b/routes/api.php index 45a342f..c58e131 100644 --- a/routes/api.php +++ b/routes/api.php @@ -27,3 +27,6 @@ Route::get('article/{id}', [ArticleController::class, 'show']); Route::get('region/category', [RegionController::class, 'category']); Route::get('region', [RegionController::class, 'index']); +Route::get('region/{id}', [RegionController::class, 'show']); +Route::get('region/{id}/plants', [RegionController::class, 'plants']); +Route::get('region/{id}/harvests', [RegionController::class, 'harvests']); From 4745c1dff4556a2430fe1ffb70a27f802f46f953 Mon Sep 17 00:00:00 2001 From: panliang <1163816051@qq.com> Date: Tue, 9 May 2023 20:16:14 +0800 Subject: [PATCH 3/4] region pagination --- app/Exceptions/Handler.php | 1 + .../Controllers/Api/ArticleController.php | 2 ++ app/Http/Controllers/Api/RegionController.php | 21 +++++++++++++++---- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 5552f78..91208d0 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -44,6 +44,7 @@ class Handler extends ExceptionHandler */ public function register() { + // Laravel9.x 无法捕获 ModelNotFoundException, 在父类 prepareException 方法中被转换为 Symfony\Component\HttpKernel\Exception\NotFoundHttpException $this->renderable(function (\Illuminate\Database\Eloquent\ModelNotFoundException $e, Request $request) { if ($request->acceptsJson()) { return response()->json(['status' => 404, 'msg' => '资源不存在', 'data' => null], 200); diff --git a/app/Http/Controllers/Api/ArticleController.php b/app/Http/Controllers/Api/ArticleController.php index e8cae18..e917ba0 100644 --- a/app/Http/Controllers/Api/ArticleController.php +++ b/app/Http/Controllers/Api/ArticleController.php @@ -32,6 +32,8 @@ class ArticleController extends Controller $list = $query->paginate($request->input('per_page')); + + return $this->json(ArticleResource::collection($list)); } diff --git a/app/Http/Controllers/Api/RegionController.php b/app/Http/Controllers/Api/RegionController.php index 61c882c..b501f93 100644 --- a/app/Http/Controllers/Api/RegionController.php +++ b/app/Http/Controllers/Api/RegionController.php @@ -33,18 +33,31 @@ class RegionController extends Controller return $this->json(RegionResource::make($info)); } - public function plants($id) + public function plants($id, Request $request) { $info = Region::show()->findOrFail($id); - $list = $info->plants()->get(); + + $query = $info->plants(); + $per = $request->input('per_page'); + if ($per == -1) { + $list = $query->get(); + } else { + $list = $query->paginate($per); + } return $this->json(RegionPlantResource::collection($list)); } - public function harvests($id) + public function harvests($id, Request $request) { $info = Region::show()->findOrFail($id); - $list = $info->harvests()->get(); + $query = $info->harvests(); + $per = $request->input('per_page'); + if ($per == -1) { + $list = $query->get(); + } else { + $list = $query->paginate($per); + } return $this->json(PlantHarvestResource::collection($list)); } From 7281a51b22ec60037fd63521bb97baa69f3d871e Mon Sep 17 00:00:00 2001 From: panliang <1163816051@qq.com> Date: Tue, 9 May 2023 20:24:22 +0800 Subject: [PATCH 4/4] timestamp null --- app/Http/Resources/PlantHarvestResource.php | 2 +- app/Http/Resources/RegionPlantResource.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Http/Resources/PlantHarvestResource.php b/app/Http/Resources/PlantHarvestResource.php index 88cbaa2..69d0b3b 100644 --- a/app/Http/Resources/PlantHarvestResource.php +++ b/app/Http/Resources/PlantHarvestResource.php @@ -21,7 +21,7 @@ class PlantHarvestResource extends JsonResource 'director' => $this->director, 'area' => $this->area, 'output' => $this->output, - 'harvest_at' => $this->harvest_at ? $this->harvest_at->timestamp : '', + 'harvest_at' => $this->harvest_at ? $this->harvest_at->timestamp : null, ]; } } diff --git a/app/Http/Resources/RegionPlantResource.php b/app/Http/Resources/RegionPlantResource.php index 9ec2393..ad6b1d5 100644 --- a/app/Http/Resources/RegionPlantResource.php +++ b/app/Http/Resources/RegionPlantResource.php @@ -19,8 +19,8 @@ class RegionPlantResource extends JsonResource 'plant_name' => $this->plant_name, 'director' => $this->director, 'area' => $this->area, - 'start_at' => $this->start_at ? $this->start_at->timestamp : '', - 'end_at' => $this->end_at ? $this->end_at->timestamp : '', + 'start_at' => $this->start_at ? $this->start_at->timestamp : null, + 'end_at' => $this->end_at ? $this->end_at->timestamp : null, 'plant_state' => $this->plant_state, ]; }