1
0
Fork 0
develop
vine_liutk 2023-05-10 19:06:01 +08:00
parent 3968270cf3
commit f5e1a5698e
16 changed files with 300 additions and 81 deletions

View File

@ -33,24 +33,19 @@ class DeviceController extends AdminController
TextControl::make()->name('name')->label('名称')->size('md'),
amisMake()->SelectControl()->name('factory')->label('厂家')->options(Keyword::getByParentKey('device-factory')->pluck('name', 'id')->toArray())->size('md'),
amisMake()->SelectControl()->name('type')->label('类型')->options(Device::typeMap())->size('md'),
Components::make()->keywordsTagControl('group_tags', '分组', 'device-group')->size('md'),
Button::make()->label(__('admin.reset'))->actionType('clear-and-submit'),
amis('submit')->label(__('admin.search'))->level('primary'),
]))
->quickSaveItemApi(admin_url('quick-edit/devices/$id'))
->columns([
TableColumn::make()->name('id')->label('ID')->sortable(true),
TableColumn::make()->name('name')->label('名称'),
TableColumn::make()->name('factory.name')->label('厂家'),
TableColumn::make()->name('sn')->label('编号'),
TableColumn::make()->name('type')->type('mapping')->map(Device::typeMap())->label('类型'),
TableColumn::make()->name('is_enable')->type('switch')->label('显示')->quickEdit(Components::make()->enableControl('is_enable', '', 'inline')->saveImmediately(true)),
TableColumn::make()->name('is_recommend')->type('switch')->label('推荐')->quickEdit(Components::make()->enableControl('is_recommend', '', 'inline')->saveImmediately(true)),
TableColumn::make()->name('sort')->label(__('admin.order'))->align('center')->quickEdit(Components::make()->sortControl('sort', __('admin.order'))->saveImmediately(true)),
TableColumn::make()->name('created_at')->label('创建时间')->type('datetime')->sortable(true),
TableColumn::make()->name('created_at')->label('创建时间')->type('datetime')->sortable(true),
TableColumn::make()->name('updated_at')->label('更新时间')->type('datetime')->sortable(true),
$this->rowActions(true, 'lg'),
]);
])->debug(true);
return $this->baseList($crud);
}
@ -59,7 +54,7 @@ class DeviceController extends AdminController
{
return $this->baseForm()->body([
TextControl::make()->name('name')->label('名称')->required(true),
TextControl::make()->name('sn')->label('编号')->required(true),
TextControl::make()->name('sn')->label('设备编号')->required(true),
\amisMake()->SelectControl()->name('powered_by')->label('厂家')->options(Keyword::getByParentKey('device-factory')->pluck('name', 'id')->toArray())->required(true),
TextControl::make()->name('model_sn')->label('型号'),
\amisMake()->RadiosControl()->name('type')->label('类型')->options(Device::typeMap())->required(true),
@ -68,11 +63,6 @@ class DeviceController extends AdminController
TextControl::make()->name('extends.rtsp_url')->hiddenOn('data.type != '.Device::TYPE_MONITOR)->label(__('device.rtsp_url')),
// rtsp://admin:lcdx12345@172.16.40.2:554/Streaming/tracks/5201
TextControl::make()->name('extends.rtsp_history')->hiddenOn('data.type != '.Device::TYPE_MONITOR)->label(__('device.rtsp_history')),
Components::make()->keywordsTagControl('group_tags', '分组', 'device-group'),
Components::make()->sortControl('sort', __('admin.order')),
TextControl::make()->name('is_enable')->type('switch')->default(1)->label('显示'),
TextControl::make()->name('is_recommend')->type('switch')->default(0)->label('推荐'),
]);
}

View File

@ -0,0 +1,69 @@
<?php
namespace App\Admin\Controllers;
use Slowlyo\OwlAdmin\Renderers\Page;
use Slowlyo\OwlAdmin\Renderers\Form;
use Slowlyo\OwlAdmin\Renderers\TableColumn;
use Slowlyo\OwlAdmin\Renderers\TextControl;
use Slowlyo\OwlAdmin\Controllers\AdminController;
use App\Services\Admin\MonitorModeService;
use App\Admin\Components;
use App\Models\MonitorMode;
/**
* @property MonitorModeService $service
*/
class MonitorModeController extends AdminController
{
protected string $serviceName = MonitorModeService::class;
public function list(): Page
{
$crud = $this->baseCRUD()
->filterTogglable(false)
->headerToolbar([
$this->createButton(true, 'lg'),
...$this->baseHeaderToolBar(),
])
->filter($this->baseFilter()->actions([])->body([
TextControl::make()->name('name')->label('名称')->size('md'),
amisMake()->SelectControl()->name('type')->label('类型')->options(MonitorMode::typeMap())->size('md'),
Components::make()->keywordsTagControl('group_tags', '分组', 'device-group')->size('md'),
amis('button')->label(__('admin.reset'))->actionType('clear-and-submit'),
amis('submit')->label(__('admin.search'))->level('primary'),
]))
->columns([
TableColumn::make()->name('id')->label('ID')->sortable(true),
TableColumn::make()->name('name')->label('名称'),
TableColumn::make()->name('type')->type('mapping')->map(MonitorMode::typeMap())->label('类型'),
TableColumn::make()->name('created_at')->label(__('admin.created_at'))->type('datetime')->sortable(true),
amisMake()->Operation()->label(__('admin.actions'))->buttons([
$this->rowDeleteButton()
]),
]);
return $this->baseList($crud);
}
public function form(): Form
{
return $this->baseForm()->body([
TextControl::make()->name('name')->label('名称'),
\amisMake()->RadiosControl()->name('type')->label('类型')->options(MonitorMode::typeMap())->required(true),
Components::make()->keywordsTagControl('group_tags', '分组', 'device-group'),
Components::make()->sortControl('sort', __('admin.order')),
TextControl::make()->name('is_enable')->type('switch')->default(1)->label('显示'),
TextControl::make()->name('is_recommend')->type('switch')->default(0)->label('推荐'),
]);
}
public function detail(): Form
{
return $this->baseDetail()->body([
TextControl::make()->static()->name('id')->label('ID'),
TextControl::make()->static()->name('created_at')->label(__('admin.created_at')),
TextControl::make()->static()->name('updated_at')->label(__('admin.updated_at'))
]);
}
}

View File

@ -5,16 +5,12 @@ namespace App\Admin\Controllers;
use Slowlyo\OwlAdmin\Renderers\Page;
use Slowlyo\OwlAdmin\Renderers\Form;
use Slowlyo\OwlAdmin\Renderers\TableColumn;
use Slowlyo\OwlAdmin\Renderers\TextControl;
use Slowlyo\OwlAdmin\Controllers\AdminController;
use App\Services\Admin\RegionService;
use Slowlyo\OwlAdmin\Renderers\Button;
use Slowlyo\OwlAdmin\Renderers\Image;
use App\Admin\Components;
use App\Models\Device;
use App\Models\Region;
use Slowlyo\OwlAdmin\Renderers\Html;
use Illuminate\Http\Request;
use App\Models\MonitorMode;
class RegionController extends AdminController
{
@ -46,7 +42,6 @@ class RegionController extends AdminController
TableColumn::make()->name('category.name')->label('分类')->className('text-primary'),
TableColumn::make()->name('director')->label('负责人'),
TableColumn::make()->name('area')->label('面积m²'),
TableColumn::make()->name('devices_count')->label('设备数量'),
TableColumn::make()->name('is_enable')->type('switch')->label('显示')->quickEdit(Components::make()->enableControl('is_enable', '', 'inline')->saveImmediately(true)),
TableColumn::make()->name('created_at')->label('创建时间')->type('datetime')->sortable(true),
// TableColumn::make()->name('updated_at')->label('更新时间')->type('datetime')->sortable(true),
@ -55,7 +50,6 @@ class RegionController extends AdminController
$this->rowEditButton(true, 'lg'),
$this->rowDeleteButton()
]),
]);
return $this->baseList($crud);
@ -63,12 +57,12 @@ class RegionController extends AdminController
public function form(): Form
{
$deviceType = [];
$devices = Device::get()->groupBy('type');
foreach(Device::typeMap() as $key => $item) {;
$deviceType[] = [
$monitorModeType = [];
$monitorModes = MonitorMode::get()->groupBy('type');
foreach(MonitorMode::typeMap() as $key => $item) {;
$monitorModeType[] = [
'label' => $item,
'children' => $devices->get($key)?->pluck('name', 'id')->toArray(),
'children' => $monitorModes->get($key)?->pluck('name', 'id')->toArray(),
];
}
return $this->baseForm()->body([
@ -80,25 +74,10 @@ class RegionController extends AdminController
Components::make()->decimalControl('area', '面积m²'),
Components::make()->sortControl(),
\amisMake()->SwitchControl()->name('is_enable')->value(1)->label('显示'),
\amisMake()->TransferControl()->name('devices')->label('关联设备')
\amisMake()->TransferControl()->name('monitorModes')->label('关联监测')
->selectMode('chained')->searchable(true)
->joinValues(false)->extractValue(true)
->options($deviceType),
]);
}
public function detail(): Form
{
return $this->baseDetail()->body([
TextControl::make()->static(true)->name('id')->label('ID'),
TextControl::make()->static(true)->name('name')->label('名称'),
TextControl::make()->static(true)->name('category.name')->label('分类'),
TextControl::make()->static(true)->name('director')->label('负责人'),
TextControl::make()->name('cover')->label('封面')->static(true)->staticSchema(Image::make()),
TextControl::make()->static(true)->name('area')->label('面积m²'),
TextControl::make()->name('description')->label('内容介绍')->static(true)->staticSchema(Html::make()),
TextControl::make()->static(true)->name('created_at')->label('创建时间'),
TextControl::make()->static(true)->name('updated_at')->label('更新时间')
->options($monitorModeType),
]);
}

View File

@ -44,11 +44,15 @@ Route::group([
$router->resource('keywords', \App\Admin\Controllers\KeywordController::class);
//设备管理
$router->resource('devices', \App\Admin\Controllers\DeviceController::class);
$router->post('quick-edit/devices/{device}',[\App\Admin\Controllers\DeviceController::class, 'update']);
//设备预警
$router->get('warning-setting', '\App\Admin\Controllers\WarningSettingController@settingIndex');
$router->get('warning-notice', '\App\Admin\Controllers\WarningNoticeController@index');
//监测点位
$router->resource('monitor-modes', \App\Admin\Controllers\MonitorModeController::class);
$router->post('quick-edit/monitor-modes/{monitor_mode}',[\App\Admin\Controllers\MonitorModeController::class, 'update']);
//区域分类
$router->resource('region-categories', \App\Admin\Controllers\RegionCategoryController::class);
$router->post('quick-edit/region-categories/{region_category}', '\App\Admin\Controllers\RegionCategoryController@update');

View File

@ -28,9 +28,7 @@ class Device extends Model
];
protected $fillable = [
'name', 'sn', 'powered_by', 'type', 'model_sn', 'state', 'extends',
'is_enable', 'sort', 'is_recommend',
'group_tags'
'name', 'sn', 'powered_by', 'type', 'model_sn', 'state', 'extends'
];
public function scopePoweredBy(Builder $query, string $factory): void

View File

@ -0,0 +1,11 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class MonitorDevice extends Model
{
use HasFactory;
}

View File

@ -0,0 +1,40 @@
<?php
namespace App\Models;
use EloquentFilter\Filterable;
use Illuminate\Database\Eloquent\Model;
class MonitorMode extends Model
{
use Filterable;
protected $fillable = [
'name', 'type',
'is_enable', 'sort', 'is_recommend',
'group_tags'
];
public const TYPE_MONITOR = 1; //视频监控
public const TYPE_SOIL = 2; //土壤监测
public const TYPE_WATER_QUALITY = 3; //水质监测
public const TYPE_METEOROLOGICAL = 4; //气象监测
public const TYPE_AIR = 5; //通风控制
public const TYPE_ATOMIZING = 6; //喷雾控制
public static function typeMap()
{
return [
self::TYPE_MONITOR => '视频监控',
self::TYPE_SOIL => '土壤监测',
self::TYPE_WATER_QUALITY => '水质监测',
self::TYPE_METEOROLOGICAL => '气象监测',
self::TYPE_AIR => '通风控制',
self::TYPE_ATOMIZING => '喷雾控制'
];
}
protected function serializeDate(\DateTimeInterface $date){
return $date->format('Y-m-d H:i:s');
}
}

View File

@ -2,13 +2,11 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use EloquentFilter\Filterable;
class Region extends Model
{
use HasFactory;
use Filterable;
protected $fillable = [
@ -24,10 +22,11 @@ class Region extends Model
return $this->belongsTo(RegionCategory::class, 'category_id');
}
public function devices(){
return $this->belongsToMany(Device::class, RegionDevice::class, 'region_id', 'device_id')->withTimestamps();
public function monitorModes(){
return $this->belongsToMany(MonitorMode::class, RegionMonitor::class, 'region_id', 'monitor_id')->withTimestamps();
}
public static function regionTabConfig($region = null){
$tabs = [
[
@ -38,11 +37,11 @@ class Region extends Model
'sort' => 0,
],
];
if($region?->devices){
foreach($region->devices as $device){
switch($device->type)
if($region?->monitorModes){
foreach($region->monitorModes as $monitorMode){
switch($monitorMode->type)
{
case Device::TYPE_MONITOR:
case MonitorMode::TYPE_MONITOR:
$tabs[] = [//有监控设备才有
'title' => '监控视频',
'value' => 'monitor',
@ -51,34 +50,34 @@ class Region extends Model
'sort' => 1,
];
break;
case Device::TYPE_SOIL:
case MonitorMode::TYPE_SOIL:
$tabs[] = [//有土壤设备才有
'title' => '土壤数据',
'value' => 'turang',
'value' => 'soil',
'tab'=>\amisMake()->Service()->schemaApi(admin_url('custom-region-soil?id='.$region->id)),
'unmountOnExit' => true,//每次切换tab都要销毁
'sort' => 2,
];
break;
case Device::TYPE_WATER_QUALITY:
case MonitorMode::TYPE_WATER_QUALITY:
$tabs[] = [//有水质设备才有
'title' => '水质数据',
'value' => 'shuizi',
'value' => 'quality',
'tab'=>\amisMake()->Service()->schemaApi(admin_url('custom-region-water?id='.$region->id)),
'unmountOnExit' => true,//每次切换tab都要销毁
'sort' => 3,
];
break;
case Device::TYPE_METEOROLOGICAL:
case MonitorMode::TYPE_METEOROLOGICAL:
$tabs[] = [//有气象设备才有
'title' => '气象数据',
'value' => 'qixiang',
'value' => 'meteorological',
'tab'=>\amisMake()->Service()->schemaApi(admin_url('custom-region-meteorological?id='.$region->id)),
'unmountOnExit' => true,//每次切换tab都要销毁
'sort' => 4,
];
break;
case Device::TYPE_AIR:
case MonitorMode::TYPE_AIR:
$tabs[] = [//有通风设备才有
'title' => '通风设备',
'value' => 'air',
@ -87,11 +86,11 @@ class Region extends Model
'sort' => 5,
];
break;
case Device::TYPE_ATOMIZING:
case MonitorMode::TYPE_ATOMIZING:
$tabs[] = [//有喷雾设备才有
'title' => '喷雾设备',
'value' => 'wasserstrahl',
'tab'=>\amisMake()->Service()->schemaApi(admin_url('custom-region-wasserstrahl?id='.$region->id)),
'value' => 'atomizing',
'tab'=>\amisMake()->Service()->schemaApi(admin_url('custom-region-atomizing?id='.$region->id)),
'unmountOnExit' => true,//每次切换tab都要销毁
'sort' => 6,
];

View File

@ -0,0 +1,11 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class RegionMonitor extends Model
{
use HasFactory;
}

View File

@ -0,0 +1,14 @@
<?php
namespace App\Services\Admin;
use App\Models\MonitorMode;
/**
* @method MonitorMode getModel()
* @method MonitorMode|\Illuminate\Database\Query\Builder query()
*/
class MonitorModeService extends BaseService
{
protected string $modelName = MonitorMode::class;
}

View File

@ -25,7 +25,7 @@ class RegionService extends BaseService
public function getEditData($id): Model|\Illuminate\Database\Eloquent\Collection|Builder|array|null
{
$region = parent::getEditData($id);
$region->devices = $region->devices()->selectRaw('devices.id as value, devices.name as label')->get()->toArray();
$region->monitorModes = $region->monitorModes()->selectRaw('monitor_modes.id as value, monitor_modes.name as label')->get()->toArray();
return $region;
}
@ -45,8 +45,8 @@ class RegionService extends BaseService
DB::beginTransaction();
if($model->save()){
//处理关联设备
$devices = Arr::get($data, 'devices');
$model->devices()->sync($devices ?? []);
$monitorModes = Arr::get($data, 'monitorModes');
$model->monitorModes()->sync($monitorModes ?? []);
}
DB::commit();
return true;
@ -73,8 +73,8 @@ class RegionService extends BaseService
DB::beginTransaction();
if($model->save()){
//处理关联设备
$devices = Arr::get($data, 'devices');
$model->devices()->sync($devices ?? []);
$monitorModes = Arr::get($data, 'monitorModes');
$model->monitorModes()->sync($monitorModes ?? []);
}
DB::commit();
return true;

View File

@ -17,15 +17,11 @@ return new class extends Migration
$table->id();
$table->string('name')->comment('设备名称');
$table->string('sn')->comment('设备唯一编码');
$table->string('powered_by')->nullable()->comment('厂家');
$table->unsignedBigInteger('powered_by')->nullable()->comment('厂家');
$table->string('model_sn')->nullable()->comment('型号');
$table->unsignedTinyInteger('type')->comment('类型: 1 监控设备, 2 土壤设备, 3 水质设备, 4 气象设备');
$table->unsignedTinyInteger('state')->default(2)->comment('状态: 0 禁用, 1 在线, 2 离线, 3 故障');
$table->text('extends')->nullable()->comment('扩展信息');
$table->unsignedTinyInteger('is_recommend')->default(0)->comment('推荐开关');
$table->unsignedTinyInteger('is_enable')->default(1)->comment('显示开关');
$table->unsignedInteger('sort')->default(0)->comment('排序');
$table->string('group_tags')->nullable()->comment('分组标签');
$table->timestamps();
});
}

View File

@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('monitor_modes', function (Blueprint $table) {
$table->id();
$table->string('name')->comment('名称');
$table->unsignedTinyInteger('type')->comment('类型: 1 视频监控, 2 土壤监测, 3 水质监测, 4 气象监测, 5 通风控制');
$table->unsignedTinyInteger('is_recommend')->default(0)->comment('推荐开关');
$table->unsignedTinyInteger('is_enable')->default(1)->comment('显示开关');
$table->unsignedInteger('sort')->default(0)->comment('排序');
$table->string('group_tags')->nullable()->comment('分组标签');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('monitor_modes');
}
};

View File

@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('monitor_devices', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('monitor_id');
$table->unsignedBigInteger('device_id');
$table->text('fields')->nullable()->comment('监测字段');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('monitor_devices');
}
};

View File

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('region_monitors', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('region_id');
$table->unsignedBigInteger('monitor_id');
$table->text('config')->nullable()->comment('配置信息');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('region_monitors');
}
};

View File

@ -48,22 +48,26 @@ class AdminMenuSeeder extends Seeder
['title' => '稻田列表', 'icon' => 'icon-park:more-app', 'url' => '/custom-region/daotian', 'order'=>2],
]
],
['title' => '设备管理', 'icon' => 'icon-park:devices', 'url' => '/devices', 'order'=>6],
['title' => '设备数据', 'icon' => 'icon-park:data-switching', 'url' => '', 'order'=>7,
['title' => '监测管理', 'icon' => 'icon-park:monitor-one', 'url' => '', 'order'=>6,
'children' => [
['title' => '监测点位', 'icon' => 'icon-park:monitor-camera', 'url' => '/monitor-modes', 'order'=>1],
['title' => '设备管理', 'icon' => 'icon-park:devices', 'url' => '/devices', 'order'=>2],
]
],
['title' => '监测数据', 'icon' => 'icon-park:data-switching', 'url' => '', 'order'=>7,
'children' => [
['title' => '实时监控', 'icon'=>'icon-park:videocamera', 'url'=> '/custom-region-monitor', 'order'=>1],
['title' => '历史视频', 'icon'=>'icon-park:film', 'url'=> '/custom-region-monitor-video', 'order'=>2],
['title' => '气象数据', 'icon'=>'icon-park:brightness', 'url'=> '/custom-region-meteorological', 'order'=>3],
['title' => '土壤数据', 'icon'=>'icon-park:floor-tile', 'url'=> '/custom-region-water', 'order'=>4],
['title' => '气象监测', 'icon'=>'icon-park:brightness', 'url'=> '/custom-region-meteorological', 'order'=>3],
['title' => '土壤监测', 'icon'=>'icon-park:floor-tile', 'url'=> '/custom-region-water', 'order'=>4],
// ['title' => '水质数据', 'icon'=>'icon-park:diving-bottle', 'url'=> '/custom-region-soil', 'order'=>5],
]
],
['title' => '设备预警', 'icon' => 'icon-park:alarm', 'url' => '', 'order'=>8,
['title' => '监测预警', 'icon' => 'icon-park:alarm', 'url' => '', 'order'=>8,
'children' => [
['title' => '预警设置', 'icon'=>'icon-park:six-circular-connection', 'url'=> '/warning-setting', 'order'=>1],
['title' => '报警记录', 'icon'=>'icon-park:massage-chair-one', 'url'=> '/warning-notice', 'order'=>2],
]
]
],
// ['title' => '友情链接', 'icon' => 'icon-park:copy-link', 'url' => '/friend-links', 'order'=>9],
['title' => '系统管理', 'icon' => 'icon-park:setting', 'url' => '/system', 'order'=>10,