17 changed files with 557 additions and 0 deletions
@ -0,0 +1,62 @@ |
|||
<?php |
|||
|
|||
namespace App\Exports; |
|||
|
|||
use App\Models\AdminNotice; |
|||
use App\Services\AdminNoticeService; |
|||
use App\Services\OperationLogService; |
|||
use Maatwebsite\Excel\Concerns\FromArray; |
|||
use Maatwebsite\Excel\Concerns\WithHeadings; |
|||
|
|||
class AdminNoticeExport implements FromArray, WithHeadings |
|||
{ |
|||
public function array(): array |
|||
{ |
|||
$data = []; |
|||
$index = 1; |
|||
$columns = [ |
|||
'alarm_time', |
|||
'alarm_type', |
|||
'camera_ip', |
|||
'msg_type', |
|||
'space_id', |
|||
'msg_content' |
|||
]; |
|||
AdminNotice::all($columns)->each( |
|||
function ($item) use (&$data, &$index) { |
|||
$oldItem = (new AdminNoticeService( |
|||
new OperationLogService() |
|||
))->getItem($item); |
|||
$data[] = [ |
|||
'id' => $index, |
|||
'alarm_time' => $oldItem['alarm_time'], |
|||
'alarm_type' => $oldItem['alarm_type'], |
|||
'msg_type' => $oldItem['msg_type'], |
|||
'space_number' => $oldItem['parking_space_number'], |
|||
'license_plate' => $oldItem['license_plate'], |
|||
'camera_ip' => $oldItem['camera_ip'], |
|||
'msg_content' => $oldItem['msg_content'] |
|||
]; |
|||
$index += 1; |
|||
} |
|||
); |
|||
return $data; |
|||
} |
|||
|
|||
/** |
|||
* @return array |
|||
*/ |
|||
public function headings(): array |
|||
{ |
|||
return [ |
|||
__('exports.global.index'), |
|||
__('exports.notice.alarm_time'), |
|||
__('exports.notice.alarm_type'), |
|||
__('exports.notice.msg_type'), |
|||
__('exports.notice.space_number'), |
|||
__('exports.notice.license_plate'), |
|||
__('exports.notice.camera_ip'), |
|||
__('exports.notice.msg_content') |
|||
]; |
|||
} |
|||
} |
|||
@ -0,0 +1,188 @@ |
|||
<?php |
|||
|
|||
namespace App\Http\Controllers\Admin; |
|||
|
|||
use App\Exports\AdminNoticeExport; |
|||
use App\Models\AdminNotice; |
|||
use App\Services\AdminNoticeService; |
|||
use App\Services\ApiResponseService; |
|||
use Exception; |
|||
use Illuminate\Http\JsonResponse; |
|||
use Illuminate\Http\Request; |
|||
use Illuminate\Support\Facades\Validator; |
|||
use Illuminate\Validation\ValidationException; |
|||
use Maatwebsite\Excel\Facades\Excel; |
|||
use Symfony\Component\HttpFoundation\BinaryFileResponse; |
|||
|
|||
class NoticeController extends BaseController |
|||
{ |
|||
|
|||
protected AdminNoticeService $service; |
|||
|
|||
/** |
|||
* 构造函数 |
|||
* @param ApiResponseService $responseService |
|||
* @param AdminNoticeService $service |
|||
*/ |
|||
public function __construct( |
|||
ApiResponseService $responseService, |
|||
AdminNoticeService $service |
|||
) { |
|||
parent::__construct($responseService); |
|||
$this->service = $service; |
|||
} |
|||
|
|||
public function index(Request $request): JsonResponse |
|||
{ |
|||
try { |
|||
$query = AdminNotice::query(); |
|||
|
|||
if ($request->has('alarm_type')) { |
|||
$alarm_type = $request->input('alarm_type'); |
|||
if ($alarm_type) { |
|||
$query->where('alarm_type', $alarm_type); |
|||
} |
|||
} |
|||
|
|||
if ($request->has('msg_type')) { |
|||
$msg_type = $request->input('msg_type'); |
|||
if ($msg_type) { |
|||
$query->where('msg_type', $msg_type); |
|||
} |
|||
} |
|||
|
|||
if ($request->has('start_time') && $request->has('end_time')) { |
|||
$start_time = $request->input('start_time'); |
|||
$end_time = $request->input('end_time'); |
|||
if ($start_time && $end_time) { |
|||
$query->whereBetween('alarm_time', [$start_time, $end_time] |
|||
); |
|||
} |
|||
} |
|||
|
|||
// 分页 |
|||
$page = $request->input('page', 1); |
|||
$perPage = $request->input('per_page', 10); |
|||
|
|||
$columns = [ |
|||
'id', |
|||
'alarm_time', |
|||
'alarm_type', |
|||
'camera_ip', |
|||
'msg_type', |
|||
'space_id' |
|||
]; |
|||
$total = $query->count(); |
|||
$items = $query->latest()->forPage($page, $perPage)->select( |
|||
$columns |
|||
)->get()->each(function ($item) { |
|||
return $this->service->getItem($item); |
|||
}); |
|||
|
|||
return $this->responseService->success([ |
|||
'items' => $items, |
|||
'total' => $total, |
|||
'page' => $page, |
|||
'per_page' => $perPage, |
|||
'last_page' => ceil($total / $perPage), |
|||
]); |
|||
} catch (Exception $e) { |
|||
$m_prefix = __('exception.exception_handler.resource'); |
|||
return $this->responseService->systemError( |
|||
$m_prefix . ':' . $e->getMessage() |
|||
); |
|||
} |
|||
} |
|||
|
|||
public function search(): JsonResponse |
|||
{ |
|||
try { |
|||
$data = [ |
|||
'alarm_type_list' => get_select_data( |
|||
AdminNoticeService::getAlarmType() |
|||
), |
|||
'msg_type_list' => get_select_data( |
|||
AdminNoticeService::getMsgType() |
|||
) |
|||
]; |
|||
return $this->responseService->success($data); |
|||
} catch (Exception $e) { |
|||
$m_prefix = __('exception.exception_handler.resource'); |
|||
return $this->responseService->systemError( |
|||
$m_prefix . ':' . $e->getMessage() |
|||
); |
|||
} |
|||
} |
|||
|
|||
public function setting(Request $request): JsonResponse |
|||
{ |
|||
try { |
|||
$data = $request->all(); |
|||
$rules = [ |
|||
'close_alert' => 'required|in:0,1', |
|||
'close_all_alert' => 'required|in:0,1', |
|||
]; |
|||
$messages = [ |
|||
'close_alert.required' => __( |
|||
'validation.notice.c_empty' |
|||
), |
|||
'close_alert.numeric' => __( |
|||
'validation.notice.c_in' |
|||
), |
|||
'close_all_alert.required' => __( |
|||
'validation.notice.c_empty' |
|||
), |
|||
'close_all_alert.numeric' => __( |
|||
'validation.notice.c_in' |
|||
), |
|||
]; |
|||
$validator = Validator::make($data, $rules, $messages); |
|||
|
|||
if ($validator->fails()) { |
|||
throw new ValidationException($validator); |
|||
} |
|||
$this->service->updateConfig($data); |
|||
return $this->responseService->success([], |
|||
__('admin.operation_successful')); |
|||
} catch (Exception $e) { |
|||
$m_prefix = __('exception.exception_handler.resource'); |
|||
return $this->responseService->systemError( |
|||
$m_prefix . ':' . $e->getMessage() |
|||
); |
|||
} |
|||
} |
|||
|
|||
public function show(string $id): JsonResponse |
|||
{ |
|||
try { |
|||
$columns = [ |
|||
'id', |
|||
'alarm_time', |
|||
'alarm_type', |
|||
'camera_ip', |
|||
'msg_type', |
|||
'space_id', |
|||
'floor_id', |
|||
'camera_id' |
|||
]; |
|||
$data = AdminNotice::query()->find($id, $columns)->toArray(); |
|||
$data = $this->service->getItem($data); |
|||
return $this->responseService->success($data); |
|||
} catch (Exception $e) { |
|||
return $this->responseService->systemError( |
|||
__('exception.get_data_failed') . ':' . $e->getMessage() |
|||
); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @return BinaryFileResponse |
|||
*/ |
|||
public function export(): BinaryFileResponse |
|||
{ |
|||
return Excel::download( |
|||
new AdminNoticeExport(), |
|||
__('exports.notice.list') . time() . '.xlsx' |
|||
); |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
<?php |
|||
|
|||
namespace App\Models; |
|||
|
|||
use Illuminate\Database\Eloquent\Factories\HasFactory; |
|||
use Illuminate\Database\Eloquent\Model; |
|||
use Illuminate\Notifications\Notifiable; |
|||
|
|||
class AdminNotice extends Model |
|||
{ |
|||
use HasFactory, Notifiable; |
|||
|
|||
protected $table = 'admin_notice'; |
|||
|
|||
/** |
|||
* The attributes that should be hidden for serialization. |
|||
* @var array<int, string> |
|||
*/ |
|||
protected $hidden |
|||
= [ |
|||
'updated_at', |
|||
'deleted_at' |
|||
]; |
|||
|
|||
public function getAlarmTimeAttribute($value): string |
|||
{ |
|||
return get_datetime('datetime', strtotime($value)); |
|||
} |
|||
} |
|||
@ -0,0 +1,147 @@ |
|||
<?php |
|||
|
|||
namespace App\Services; |
|||
|
|||
use App\Models\AdminConfigs; |
|||
use App\Models\AdminFloor; |
|||
use App\Models\AdminNotice; |
|||
use App\Models\ParkingCamera; |
|||
use App\Models\ParkingLicensePlate; |
|||
use App\Models\ParkingSpace; |
|||
use Exception; |
|||
use Illuminate\Support\Facades\DB; |
|||
|
|||
class AdminNoticeService extends BaseService |
|||
{ |
|||
|
|||
private static array $alarmTypeArr |
|||
= [ |
|||
1 => 'hint', |
|||
2 => 'support' |
|||
]; |
|||
|
|||
private static array $msgTypeArr |
|||
= [ |
|||
1 => 'touch', |
|||
2 => 'illegal', |
|||
3 => 'offline', |
|||
4 => 'vip', |
|||
5 => 'task' |
|||
]; |
|||
|
|||
public function __construct(OperationLogService $logService) |
|||
{ |
|||
parent::__construct($logService); |
|||
$this->logService->menuTitle = 'alarm_notice'; |
|||
} |
|||
|
|||
/** |
|||
* @return array|string[] |
|||
*/ |
|||
public static function getAlarmType(): array |
|||
{ |
|||
$alarmTypeArr = self::$alarmTypeArr; |
|||
foreach ($alarmTypeArr as $key => $value) { |
|||
$alarmTypeArr[$key] = __('service.notice.' . $value); |
|||
} |
|||
return $alarmTypeArr; |
|||
} |
|||
|
|||
/** |
|||
* @return array|string[] |
|||
*/ |
|||
public static function getMsgType(): array |
|||
{ |
|||
$msgTypeArr = self::$msgTypeArr; |
|||
foreach ($msgTypeArr as $key => $value) { |
|||
$msgTypeArr[$key] = __('service.notice.' . $value); |
|||
} |
|||
return $msgTypeArr; |
|||
} |
|||
|
|||
public function getItem($item) |
|||
{ |
|||
$alarmTypeArr = self::getAlarmType(); |
|||
$msgTypeArr = self::getMsgType(); |
|||
$item['alarm_type'] = $alarmTypeArr[$item['alarm_type']]; |
|||
$item['msg_type'] = $msgTypeArr[$item['msg_type']]; |
|||
$item['parking_space_number'] = ''; |
|||
$item['license_plate'] = ''; |
|||
$ParkingSpace = ParkingSpace::query()->findOrFail( |
|||
$item['space_id'], |
|||
['number', 'license_plate_id'] |
|||
); |
|||
if ($ParkingSpace) { |
|||
$item['parking_space_number'] = $ParkingSpace['number']; |
|||
$item['license_plate'] = ParkingLicensePlate::getNumber( |
|||
$ParkingSpace['license_plate_id'] |
|||
); |
|||
} |
|||
if (isset($item['floor_id'])) { |
|||
$item['floor'] = AdminFloor::getName($item['floor_id']); |
|||
unset($item['floor_id']); |
|||
} |
|||
if (isset($item['camera_id'])) { |
|||
$item['camera_number'] = ParkingCamera::getNumber($item['camera_id']); |
|||
unset($item['camera_id']); |
|||
} |
|||
unset($item['space_id']); |
|||
return $item; |
|||
} |
|||
|
|||
public function updateConfig($data) |
|||
{ |
|||
try { |
|||
DB::beginTransaction(); |
|||
$content = [ |
|||
'close_alert' => $data['close_alert'], |
|||
'close_all_alert' => $data['close_all_alert'] |
|||
]; |
|||
$model = AdminConfigs::query()->where('name', 'information_setting') |
|||
->first(); |
|||
$oldValues = $model->toArray(); |
|||
|
|||
$model->update([ |
|||
'content' => $content, |
|||
'updated_at' => get_datetime() |
|||
]); |
|||
|
|||
$this->logService->logUpdated($model, $oldValues, 'config.update'); |
|||
|
|||
DB::commit(); |
|||
return $model; |
|||
} catch (Exception $e) { |
|||
DB::rollBack(); |
|||
throw $e; |
|||
} |
|||
} |
|||
|
|||
public static function createData($data, $user_id) |
|||
{ |
|||
$alarm_type = $data['alarm_type']; |
|||
$camera_ip = $data['camera_ip']; |
|||
$msg_type = $data['msg_type']; |
|||
$create = [ |
|||
'alarm_time' => get_datetime(), |
|||
'alarm_type' => $alarm_type, |
|||
'camera_ip' => $camera_ip, |
|||
'msg_type' => $msg_type, |
|||
'is_read' => 0, |
|||
'admin_user_id' => $user_id, |
|||
'created_at' => get_datetime() |
|||
]; |
|||
if (isset($data['space_id']) && $data['space_id']) { |
|||
$create['space_id'] = $data['space_id']; |
|||
} |
|||
if (isset($data['floor_id']) && $data['floor_id']) { |
|||
$create['floor_id'] = $data['floor_id']; |
|||
} |
|||
if (isset($data['camera_id']) && $data['camera_id']) { |
|||
$create['camera_id'] = $data['camera_id']; |
|||
} |
|||
if (isset($data['msg_content']) && $data['msg_content']) { |
|||
$create['msg_content'] = $data['msg_content']; |
|||
} |
|||
AdminNotice::query()->create($create); |
|||
} |
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
<?php |
|||
|
|||
use Illuminate\Database\Migrations\Migration; |
|||
use Illuminate\Database\Schema\Blueprint; |
|||
use Illuminate\Support\Facades\Schema; |
|||
|
|||
return new class extends Migration |
|||
{ |
|||
/** |
|||
* Run the migrations. |
|||
*/ |
|||
public function up(): void |
|||
{ |
|||
Schema::create('admin_notice', function (Blueprint $table) { |
|||
$table->id(); |
|||
$table->timestamp('alarm_time')->comment('信息时间'); |
|||
$table->tinyInteger('alarm_type')->default(0)->comment('信息类型'); |
|||
$table->string('camera_ip', 15)->comment('ip'); |
|||
$table->tinyInteger('msg_type')->default(0)->comment('信息内容'); |
|||
$table->string('msg_content', 255)->default('')->comment('信息内容详情'); |
|||
$table->integer('space_id')->nullable()->comment('车位id'); |
|||
$table->integer('floor_id')->nullable()->comment('楼层id'); |
|||
$table->integer('camera_id')->nullable()->comment('相机设备id'); |
|||
$table->tinyInteger('is_read')->default(0)->comment('是否已读'); |
|||
$table->integer('admin_user_id')->default(0)->comment('操作员'); |
|||
$table->timestamps(); |
|||
$table->innoDb(); |
|||
$table->index('alarm_type', 'alarm_type'); |
|||
$table->index('msg_type', 'msg_type'); |
|||
$table->comment('警报 & 消息'); |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* Reverse the migrations. |
|||
*/ |
|||
public function down(): void |
|||
{ |
|||
Schema::dropIfExists('admin_notice'); |
|||
} |
|||
}; |
|||
Loading…
Reference in new issue