From 584366b2529690136edfcf1d194b186a156fa468 Mon Sep 17 00:00:00 2001 From: wanghongjun <1445693971@qq.com> Date: Wed, 6 May 2026 15:12:12 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B4=BB=E5=8A=A8=E8=A1=8C=E4=BA=8B=E5=8E=862?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Exports/EventCalendarTemplateExport.php | 30 ++ .../Admin/EventCalendarController.php | 417 ++++++++++++++++++ app/Imports/EventCalendarImport.php | 80 ++++ app/Models/EventCalendar.php | 40 ++ app/Services/EventCalendarService.php | 261 +++++++++++ ..._23_143449_create_event_calendar_table.php | 35 ++ 6 files changed, 863 insertions(+) create mode 100644 app/Exports/EventCalendarTemplateExport.php create mode 100644 app/Http/Controllers/Admin/EventCalendarController.php create mode 100644 app/Imports/EventCalendarImport.php create mode 100644 app/Models/EventCalendar.php create mode 100644 app/Services/EventCalendarService.php create mode 100644 database/migrations/2026_04_23_143449_create_event_calendar_table.php diff --git a/app/Exports/EventCalendarTemplateExport.php b/app/Exports/EventCalendarTemplateExport.php new file mode 100644 index 0000000..96b5b45 --- /dev/null +++ b/app/Exports/EventCalendarTemplateExport.php @@ -0,0 +1,30 @@ +service = $service; + } + + public function index(Request $request): JsonResponse + { + try { + $query = EventCalendar::query(); + + if ($request->has('pattern_id')) { + $pattern_id = $request->input('pattern_id'); + if ($pattern_id) { + $query->where('pattern_id', $pattern_id); + } + } + + if ($request->has('status')) { + $status = $request->input('status'); + if ($status) { + $query->where('status', $status); + } + } + + if ($request->has('start_time')) { + $start_time = $request->input('start_time'); + if ($start_time && strtotime($start_time)) { + $query->where('start_time', '>=', $start_time); + } + } + + if ($request->has('end_time')) { + $end_time = $request->input('end_time'); + if ($end_time && strtotime($end_time)) { + $query->where('end_time', '<=', $end_time); + } + } + + // 分页 + $page = $request->input('page', 1); + $perPage = $request->input('per_page', 10); + + $total = $query->count(); + $statusArr = EventCalendarService::getStatus(); + $items = $query->latest()->forPage($page, $perPage)->select() + ->get()->each(function ($item) use ($statusArr) { + $item['pattern_name'] = ParkingPattern::getName( + $item['pattern_id'] + ); + $item['admin_username'] = AdminUsers::getUsername( + $item['admin_user_id'] + ); + $item['status'] = $statusArr[$item['status']] ?? ''; + $item['remake'] = ''; + unset($item['pattern_id'], $item['admin_user_id']); + return $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 = [ + 'pattern_list' => ParkingPattern::getData(), + 'status_list' => get_select_data( + EventCalendarService::getStatus() + ) + ]; + return $this->responseService->success($data); + } catch (Exception $e) { + $m_prefix = __('exception.exception_handler.resource'); + return $this->responseService->systemError( + $m_prefix . ':' . $e->getMessage() + ); + } + } + + public function create(): JsonResponse + { + try { + $data = [ + 'pattern_list' => ParkingPattern::getData() + ]; + return $this->responseService->success($data); + } catch (Exception $e) { + $m_prefix = __('exception.exception_handler.resource'); + return $this->responseService->systemError( + $m_prefix . ':' . $e->getMessage() + ); + } + } + + public function changeMode(Request $request): JsonResponse + { + try { + $data = $request->all(); + $this->saveValidator($data, 0, true); + $this->service->changeModel($data, $this->adminUserId); + return $this->responseService->success( + null, + __('admin.operation_successful') + ); + } catch (ValidationException|CustomException $e) { + throw $e; + } catch (Exception $e) { + return $this->responseService->systemError( + __('admin.operation_failed') . ':' + . $e->getMessage() + ); + } + } + + /** + * @param Request $request + * @return JsonResponse + * @throws CustomException + * @throws ValidationException + */ + public function store(Request $request): JsonResponse + { + try { + $this->saveValidator($request->all()); + $this->service->createModel($request->all(), $this->adminUserId); + return $this->responseService->success( + null, + __('admin.save_succeeded') + ); + } catch (ValidationException|CustomException $e) { + throw $e; + } catch (Exception $e) { + return $this->responseService->systemError( + __('exception.event_calendar.create_failed') . ':' + . $e->getMessage() + ); + } + } + + /** + * @param array $data + * @param int $id + * @return void + * @throws ValidationException + */ + protected function saveValidator(array $data, int $id = 0, $is = false): void + { + $rules = [ + 'pattern_id' => 'required', + 'start_time' => 'required', + 'end_time' => 'required' + ]; + $messages = [ + 'pattern_id.required' => __( + 'validation.event_calendar.p_empty' + ), + 'start_time.required' => __( + 'validation.event_calendar.s_empty' + ), + 'end_time.required' => __( + 'validation.event_calendar.e_empty' + ) + ]; + if ($id) { + $this->validateId($id, EventCalendar::class); + } + if ($is) { + unset($rules['start_time'], $messages['start_time.required']); + } + + $validator = Validator::make($data, $rules, $messages); + + if ($validator->fails()) { + throw new ValidationException($validator); + } + } + + + public function edit($id): JsonResponse + { + try { + $this->validateId($id, EventCalendar::class); + $item = EventCalendar::query()->findOrFail($id); + $data = [ + 'pattern_list' => ParkingPattern::getData() + ]; + $data['item'] = $item; + $statusArr = $item['status'] == 0 ? EventCalendarService::getStatus( + 2 + ) : EventCalendarService::getStatus(); + $data['status_list'] = get_select_data($statusArr); + unset($item['admin_user_id']); + return $this->responseService->success($data); + } catch (Exception $e) { + return $this->responseService->systemError( + __('exception.get_data_failed') . ':' . $e->getMessage() + ); + } + } + + /** + * @param Request $request + * @param string $id + * @return JsonResponse + * @throws CustomException + * @throws ValidationException + */ + public function update(Request $request, string $id): JsonResponse + { + try { + $data = $request->all(); + $this->saveValidator($data, $id); + $data['admin_user_id'] = $this->adminUserId; + $this->service->updateModel($data, $id); + return $this->responseService->success( + null, + __('admin.update_succeeded') + ); + } catch (ValidationException|CustomException $e) { + throw $e; + } catch (Exception $e) { + return $this->responseService->systemError( + __('exception.event_calendar.update_failed') . ':' + . $e->getMessage() + ); + } + } + + /** + * @param string $id + * @return JsonResponse + * @throws ValidationException + */ + public function destroy(string $id): JsonResponse + { + try { + $this->validateId($id, EventCalendar::class); + $this->service->deleteModel($id); + return $this->responseService->success( + null, + __('admin.delete_succeeded') + ); + } catch (ValidationException $e) { + throw $e; + } catch (Exception $e) { + return $this->responseService->systemError( + __('exception.event_calendar.destroy_failed') . ':' + . $e->getMessage() + ); + } + } + + /** + * @param string $id + * @return JsonResponse + * @throws ValidationException + */ + public function end(string $id): JsonResponse + { + try { + $this->validateId($id, EventCalendar::class); + $this->service->endModel($id); + return $this->responseService->success( + null, + __('exception.event_calendar.end_succeeded') + ); + } catch (ValidationException $e) { + throw $e; + } catch (Exception $e) { + return $this->responseService->systemError( + __('exception.event_calendar.end_failed') . ':' + . $e->getMessage() + ); + } + } + + /** + * @return BinaryFileResponse + */ + public function importTemplate(): BinaryFileResponse + { + return Excel::download( + new EventCalendarTemplateExport(), + __('exports.event_calendar.list') . time() . '.xlsx' + ); + } + + /** + * 创建导入 + * @param Request $request + * @return JsonResponse + * @throws ValidationException + */ + public function import(Request $request): JsonResponse + { + try { + // 1. 验证上传的文件 + $data = $request->all(); + $request->validate([ + 'file' => 'required|mimes:xlsx,xls,csv|max:2048' + ]); + $validator = Validator::make($data, [ + 'file' => 'required|mimes:xlsx,xls,csv|max:2048' + ], [ + 'file.required' => __('validation.admin_list_vip.file_empty'), + 'file.mimes' => __('validation.admin_list_vip.file_mimes'), + 'file.max' => __('validation.admin_list_vip.file_max') + ]); + if ($validator->fails()) { + throw new ValidationException($validator); + } + + // 2. 获取上传的文件 + $file = $request->file('file'); + + // 3. 正确的做法:先存储文件,再获取绝对路径进行导入 + $path = $file->store('imports'); + + // 4. 执行导入(使用存储后的绝对路径) + // storage_path('app') 获取 storage/app 的绝对路径 + Excel::import( + new EventCalendarImport($this->adminUserId), + storage_path('app/' . $path) + ); + + // 5. (可选)导入完成后删除临时文件 + Storage::delete($path); + + return $this->responseService->success( + __('controller.import.success') + ); + } catch (ValidationException $e) { + throw $e; + } catch (Exception $e) { + return $this->responseService->systemError( + __('exception.admin_vip_list.import_failed') . ':' + . $e->getMessage() + ); + } + } + + /** + * @return JsonResponse + * @throws InvalidArgumentException + */ + public function rule(): JsonResponse + { + try { + return $this->responseService->success( + $this->methodShow('eventCalendar', ['import']) + ); + } catch (Exception $e) { + return $this->responseService->systemError( + __('exception.get_data_failed') . ':' . $e->getMessage() + ); + } + } + + public function targetMode() + { + try { + $data = [ + 'model' => EventCalendarService::targetModel() + ]; + return $this->responseService->success($data); + } catch (Exception $e) { + return $this->responseService->systemError( + __('exception.get_data_failed') . ':' . $e->getMessage() + ); + } + } +} diff --git a/app/Imports/EventCalendarImport.php b/app/Imports/EventCalendarImport.php new file mode 100644 index 0000000..e572e1d --- /dev/null +++ b/app/Imports/EventCalendarImport.php @@ -0,0 +1,80 @@ +user_id = $user_id; + $this->logService = new OperationLogService(); + $this->logService->menuTitle = 'event_calendar'; + } + + /** + * @param array $row + * @return false|void + */ + public function model(array $row) + { + $pattern_name = $row['mode_name']; + $start_date = $row['start_date']; + $start_time = $row['start_time']; + $end_date = $row['end_date']; + $end_time = $row['end_time']; + if (empty($pattern_name)) { + return false; + } + $pattern_id = ParkingPattern::getId($pattern_name); + if (EventCalendar::query()->whereIn('status', [0, 1])->where( + 'pattern_id', + $pattern_id + ) + ->exists() + ) { + return false; + } + $start_date_times = strtotime($start_date); + $start_times = strtotime($start_time); + $end_date_times = strtotime($end_date); + $end_times = strtotime($end_time); + if (!$start_date_times) { + return false; + } + if (!$start_times) { + return false; + } + if (!$end_date_times) { + return false; + } + if (!$end_times) { + return false; + } + $start_date = date("Y-m-d", $start_date_times); + $start_time = date("H:i:s", $start_times); + $end_date_time = date("Y-m-d", $end_date_times); + $end_time = date("H:i:s", $end_times); + + $create = [ + 'pattern_id' => $pattern_id, + 'admin_user_id' => $this->user_id, + 'start_time' => $start_date . ' ' . $start_time, + 'end_time' => $end_date_time . ' ' . $end_time, + 'status' => 0, + 'created_at' => get_datetime() + ]; + + $model = EventCalendar::query()->create($create); + + $this->logService->logCreated($model, 'event_calendar.import'); + } +} diff --git a/app/Models/EventCalendar.php b/app/Models/EventCalendar.php new file mode 100644 index 0000000..51228ba --- /dev/null +++ b/app/Models/EventCalendar.php @@ -0,0 +1,40 @@ +logService->menuTitle = 'event_calendar'; + } + + /** + * @return array|string[] + */ + public static function getStatus($type = 1): array + { + $statusArr = self::$statusArr; + foreach ($statusArr as $key => $value) { + $statusArr[$key] = __('service.event_calendar.' . $value); + } + if ($type == 2) { + unset($statusArr[1], $statusArr[2]); + } + return $statusArr; + } + + /** + * @param array $data + * @param $user_id + * @return Builder|Model + * @throws Exception + */ + public function createModel(array $data, $user_id): Builder|Model + { + try { + DB::beginTransaction(); + + if (EventCalendar::query()->whereIn('status', [0, 1])->where( + 'pattern_id', + $data['pattern_id'] + ) + ->exists() + ) { + throw new Exception( + __('service.event_calendar.pattern_exists') + ); + } + + $start_time = get_datetime( + 'datetime', + strtotime($data['start_time']) + ); + $end_time = get_datetime('datetime', strtotime($data['end_time'])); + + $model = EventCalendar::query()->create([ + 'pattern_id' => $data['pattern_id'], + 'start_time' => $start_time, + 'end_time' => $end_time, + 'admin_user_id' => $user_id, + 'status' => 0, + 'created_at' => get_datetime() + ]); + + $this->logService->logCreated($model, 'event_calendar.create'); + + DB::commit(); + return $model; + } catch (Exception $e) { + DB::rollBack(); + throw $e; + } + } + + /** + * @param array $data + * @param string $id + * @throws Exception + */ + public function updateModel(array $data, string $id) + { + try { + DB::beginTransaction(); + $existsWhere = [ + ['pattern_id', '=', $data['pattern_id']], + ['status', 'in', [0, 1]], + ['id', '<>', $id] + ]; + if (EventCalendar::query()->where($existsWhere)->exists()) { + throw new Exception( + __('service.event_calendar.pattern_exists') + ); + } + $model = EventCalendar::query()->findOrFail($id); + $oldValues = $model->toArray(); + + $end_time = get_datetime('datetime', strtotime($data['end_time'])); + $update = [ + 'pattern_id' => $data['pattern_id'], + 'end_time' => $end_time, + 'admin_user_id' => $data['admin_user_id'], + 'updated_at' => get_datetime() + ]; + if ($oldValues['status'] == 0) { + if (isset($data['start_time']) + && strtotime( + $data['start_time'] + ) + ) { + $update['start_time'] = get_datetime( + 'datetime', + strtotime($data['start_time']) + ); + } + if (isset($data['status']) + && in_array($data['status'], [0, 3]) + ) { + $update['status'] = $data['status']; + } + } + + $model->update($update); + $this->logService->logUpdated( + $model, + $oldValues, + 'event_calendar.update' + ); + + DB::commit(); + return $model; + } catch (Exception $e) { + DB::rollBack(); + throw $e; + } + } + + public function deleteModel(int $id): bool + { + try { + DB::beginTransaction(); + + $model = EventCalendar::query()->findOrFail($id); + if ($model['status'] > 0) { + throw new Exception(__('service.event_calendar.error_status')); + } + + $this->logService->logDeleted($model, 'event_calendar.delete'); + + $model->delete(); + + DB::commit(); + return true; + } catch (Exception $e) { + DB::rollBack(); + throw $e; + } + } + + public function endModel(int $id): bool + { + try { + DB::beginTransaction(); + $model = EventCalendar::query()->findOrFail($id); + $oldValues = $model->toArray(); + if ($model['status'] != 1) { + throw new Exception(__('service.event_calendar.error_end')); + } + $update = [ + 'status' => 2, + 'updated_at' => get_datetime() + ]; + $model->update($update); + $this->logService->logUpdated( + $model, + $oldValues, + 'event_calendar.update' + ); + + DB::commit(); + return true; + } catch (Exception $e) { + DB::rollBack(); + throw $e; + } + } + + public function changeModel($data, $user_id) + { + try { + DB::beginTransaction(); + $pattern_id = $data['pattern_id']; + $end_time = $data['end_time']; + + $where = [ + 'pattern_id' => $pattern_id, + 'status' => 1 + ]; + $query = EventCalendar::query()->where($where)->first(); + + $save = [ + 'pattern_id' => $pattern_id, + 'start_time' => get_datetime(), + 'end_time' => get_datetime('datetime', strtotime($end_time)), + 'status' => 1, + 'admin_user_id' => $user_id + ]; + + if ($query) { + $save['updated_at'] = get_datetime(); + $model = EventCalendar::query()->findOrFail($query['id']); + $oldValues = $model->toArray(); + $model->update($save); + $this->logService->logUpdated( + $model, + $oldValues, + 'event_calendar.update' + ); + } else { + $save['created_at'] = get_datetime(); + $model = EventCalendar::query()->create($save); + $this->logService->logCreated($model, 'event_calendar.create'); + } + + DB::commit(); + return $model; + } catch (Exception $e) { + DB::rollBack(); + throw $e; + } + } + + public static function targetModel() + { + $pattern_id = EventCalendar::query()->where('status', 1)->first(['pattern_id']); + $columns = ['id as pattern_id', 'name as model_name']; + if ($pattern_id) { + $data = ParkingPattern::query()->findOrFail($pattern_id, $columns)->toArray(); + } else { + $data = ParkingPattern::query()->where('is_default', 1)->first($columns); + } + return $data; + } +} diff --git a/database/migrations/2026_04_23_143449_create_event_calendar_table.php b/database/migrations/2026_04_23_143449_create_event_calendar_table.php new file mode 100644 index 0000000..a95c330 --- /dev/null +++ b/database/migrations/2026_04_23_143449_create_event_calendar_table.php @@ -0,0 +1,35 @@ +id(); + $table->integer('pattern_id')->comment('模式id'); + $table->timestamp('start_time')->comment('开始时间'); + $table->timestamp('end_time')->comment('结束时间'); + $table->integer('admin_user_id')->comment('操作员'); + $table->tinyInteger('status')->default(0)->comment('状态 0计划中 1运行中 2已结束 3已停用'); + $table->timestamps(); + $table->softDeletes(); + $table->innoDb(); + $table->comment('模式管理车位'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('event_calendar'); + } +};