diff --git a/app/Enums/DeviceType.php b/app/Enums/DeviceType.php index 356d117..e6525d8 100644 --- a/app/Enums/DeviceType.php +++ b/app/Enums/DeviceType.php @@ -8,4 +8,25 @@ enum DeviceType: int case Soil = 2; // 土壤设备 case WaterQuality = 3; // 水质设备 case Meteorological = 4; // 气象设备 + + /** + * @return string + */ + public function typeName(): string + { + return static::types()[$this->value]; + } + + /** + * @return array + */ + public static function types(): array + { + return [ + static::Monitor->value => '监控设备', + static::Soil->value => '土壤设备', + static::WaterQuality->value => '水质设备', + static::Meteorological->value => '气象设备', + ]; + } } diff --git a/app/Http/Controllers/DeviceController.php b/app/Http/Controllers/DeviceController.php new file mode 100644 index 0000000..95fc7ad --- /dev/null +++ b/app/Http/Controllers/DeviceController.php @@ -0,0 +1,62 @@ +filter($request->input()); + $list = $query->simplePaginate(Paginator::resolvePerPage('per_page', 20, 50)); + return $this->json(DeviceResource::collection($list)); + } + + public function store(DeviceRequest $request) + { + $input = $request->input(); + //如果不是监控设备,移除extends + if($input['type'] != DeviceType::Monitor->value){ + unset($input['extends']); + } + Device::create(array_merge($input, [ + 'created_by' => auth('api')->user()?->id ?? 0, + 'updated_by' => auth('api')->user()?->id ?? 0, + ])); + return $this->success('添加成功'); + } + + public function show(Device $device) + { + return $this->json(DeviceResource::make($device)); + } + + public function update(Device $device, DeviceRequest $request) + { + $input = $request->input(); + //如果不是监控设备,移除extends + if($input['type'] != DeviceType::Monitor->value){ + $input['extends'] = null; + } + $device->update(array_merge($input, [ + 'updated_by' => auth('api')->user()?->id ?? 0, + ])); + return $this->success('修改成功'); + } + + public function destroy(Device $device) + { + $device->delete(); + return $this->success('删除成功'); + } + + public function types(){ + return $this->json(DeviceType::types()); + } +} diff --git a/app/Http/Requestes/CropFlowUpdateRequest.php b/app/Http/Requestes/CropFlowUpdateRequest.php index 262e0b6..7d90b2b 100644 --- a/app/Http/Requestes/CropFlowUpdateRequest.php +++ b/app/Http/Requestes/CropFlowUpdateRequest.php @@ -18,7 +18,7 @@ class CropFlowUpdateRequest extends FormRequest return [ 'time_year' => 'required|date_format:Y', 'crop_id' => 'required|integer|min:0', - 'sale' => 'required|integer|min:1', + 'sale' => 'required|regex:/^\d+(\.\d{1,2})?$/', 'flow_name'=> 'required|string|max:100', ]; } diff --git a/app/Http/Requestes/DeviceRequest.php b/app/Http/Requestes/DeviceRequest.php new file mode 100644 index 0000000..d1f84a8 --- /dev/null +++ b/app/Http/Requestes/DeviceRequest.php @@ -0,0 +1,59 @@ + ['required', new Enum(DeviceType::class)], + 'agricultural_base_id' => 'required|integer|min:0', + 'sn' => 'required|string|max:64', + 'monitoring_point' => 'required|string|max:100', + 'extends' => 'required_if:type,1', + 'extends.ip'=> 'required_if:type,1|string', + 'extends.port'=> 'required_if:type,1|string', + 'extends.rtsp_url'=> 'required_if:type,1|string', + 'extends.username'=> 'required_if:type,1|string', + 'extends.password'=> 'required_if:type,1|string', + 'extends.passage'=> 'required_if:type,1|string', + ]; + } + + public function messages() + { + $messages = [ + 'type' => '请选择设备类型', + 'agricultural_base_id' => '请选择基地', + 'sn' => '请填写设备编号', + 'monitoring_point' => '请填写监控点', + 'extends.required_if' =>'请填写监控设备信息', + 'extends.ip.required_if' =>'请填写监控设备IP', + 'extends.port.required_if' =>'请填写监控设备端口', + 'extends.rtsp_url.required_if' =>'请填写监控设备RTSP地址', + 'extends.username.required_if' =>'请填写监控设备登录名', + 'extends.password.required_if' =>'请填写监控设备登录密码', + 'extends.passage.required_if' =>'请填写监控设备播放通道', + ]; + + return $messages; + } + + protected function failedValidation(Validator $validator) + { + $error = $validator->errors()->all(); + throw new HttpResponseException(response()->json(['data' => [], 'code' => 400, 'message' => $error[0]])); + } +} diff --git a/app/Http/Resources/DeviceResource.php b/app/Http/Resources/DeviceResource.php new file mode 100644 index 0000000..1cd23cc --- /dev/null +++ b/app/Http/Resources/DeviceResource.php @@ -0,0 +1,34 @@ + $this->id, + 'type' => $this->type?->typeName() ?? '未知', + 'sn' => $this->sn, + 'base_name' => $this->whenLoaded('base', function (){ + return $this->base?->name ?? ''; + }, ''), + 'base_id' => $this->agricultural_base_id, + 'monitoring_point' => $this->monitoring_point ?? '', + 'status' => $this->status?->value, + 'extends' => $this->extends ?? [], + 'created_by' => $this->whenLoaded('createdBy', function (){ + return $this->createdBy?->name; + }, ''),//录入人 + 'created_at' => strtotime($this->created_at) ?? 0,//录入时间 + ]; + } +} diff --git a/app/ModelFilters/DeviceFilter.php b/app/ModelFilters/DeviceFilter.php new file mode 100644 index 0000000..08f2071 --- /dev/null +++ b/app/ModelFilters/DeviceFilter.php @@ -0,0 +1,21 @@ +where('monitoring_point', 'like', $point.'%'); + } + + public function base($base){ + return $this->where('agricultural_base_id', $base); + } + + public function type($type){ + return $this->where('type', $type); + } +} diff --git a/app/Models/Device.php b/app/Models/Device.php index a145083..c8dfa04 100644 --- a/app/Models/Device.php +++ b/app/Models/Device.php @@ -2,15 +2,16 @@ namespace App\Models; -use App\Enums\DeviceStatus; use App\Enums\DeviceType; -use Illuminate\Database\Eloquent\Factories\HasFactory; +use App\Enums\DeviceStatus; +use EloquentFilter\Filterable; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Factories\HasFactory; class Device extends Model { - use HasFactory; + use HasFactory, Filterable; protected $attributes = [ 'status' => DeviceStatus::Offline, @@ -19,6 +20,7 @@ class Device extends Model protected $casts = [ 'type' => DeviceType::class, 'status' => DeviceStatus::class, + 'extends' => 'array' ]; protected $fillable = [ @@ -34,6 +36,10 @@ class Device extends Model 'updated_by', ]; + public function base(){ + return $this->belongsTo(AgriculturalBase::class, 'agricultural_base_id'); + } + public function createdBy(): BelongsTo { return $this->belongsTo(AdminUser::class, 'created_by'); diff --git a/database/migrations/2022_10_14_095443_create_devices_table.php b/database/migrations/2022_10_14_095443_create_devices_table.php index bb775e1..950ad27 100644 --- a/database/migrations/2022_10_14_095443_create_devices_table.php +++ b/database/migrations/2022_10_14_095443_create_devices_table.php @@ -17,8 +17,8 @@ return new class extends Migration $table->id(); $table->unsignedBigInteger('agricultural_base_id')->comment('农业基地ID'); $table->string('sn')->comment('序列号'); - $table->string('name')->comment('名称'); - $table->string('model')->comment('型号'); + $table->string('name')->nullable()->comment('名称'); + $table->string('model')->nullable()->comment('型号'); $table->string('monitoring_point')->nullable()->comment('监控点'); $table->tinyInteger('type')->comment('类型: 1 监控设备, 2 土壤设备, 3 水质设备, 4 气象设备'); $table->tinyInteger('status')->default(2)->comment('状态: 0 禁用, 1 在线, 2 离线, 3 故障'); diff --git a/routes/api.php b/routes/api.php index 4fe4800..6864120 100644 --- a/routes/api.php +++ b/routes/api.php @@ -21,6 +21,7 @@ Route::group(['middleware' => 'auth:sanctum'], function () { Route::get('keywords-crops', [KeywordController::class, 'crops']); //农作物 Route::get('keywords-crops-cate', [KeywordController::class, 'cropsCate']); //农作物产业分类 Route::get('permissions', [AdminPermissionController::class, 'index']); + Route::get('device-types', [DeviceController::class, 'types']); Route::group(['as'=>'endpoint.'], function (){ @@ -34,6 +35,8 @@ Route::group(['middleware' => 'auth:sanctum'], function () { Route::apiResource('crop-yields', CropYieldController::class)->names('crops_output'); //流向 Route::apiResource('crop-flows', CropFlowController::class)->names('crops_flow'); + //设备管理 + Route::apiResource('devices', DeviceController::class)->names('device'); /** 系统管理 **/ Route::apiResource('admin-users', AdminUserController::class)->names('admin_users');