From 13fd9c5f0a1a3b7146f9ab0e4be2fed6a1c67f4a Mon Sep 17 00:00:00 2001 From: zimoyin <2556608754@qq.com> Date: Mon, 6 Apr 2026 20:48:32 +0800 Subject: [PATCH] init --- app/controller/IndexController.php | 2 +- .../exception/NotFoundUserException.php | 2 +- .../ResultNotAsExpectedException.php | 2 +- .../admin/app/controller/AppealController.php | 19 + .../app/controller/DataOverviewController.php | 90 ++++ .../app/controller/DepartmentController.php | 75 ++++ .../admin/app/controller/DeviceController.php | 68 +++ .../controller/DeviceMonitorController.php | 19 + .../app/controller/DeviceStatusController.php | 86 ++++ .../app/controller/DeviceUsageController.php | 48 +++ .../app/controller/EnforcementController.php | 19 + .../app/controller/HospitalController.php | 74 ++++ .../admin/app/controller/SensorController.php | 63 +++ .../admin/app/controller/VideoController.php | 19 + .../app/controller/WarnRecordController.php | 75 ++++ .../app/controller/WarnRuleController.php | 72 ++++ .../app/controller/WithDataPermission.php | 66 +++ plugin/admin/app/model/Base.php | 39 -- plugin/admin/app/model/OpmDsAuth.php | 41 ++ plugin/admin/app/model/OpmDsCamera.php | 43 ++ plugin/admin/app/model/OpmDsCycle.php | 52 +++ plugin/admin/app/model/OpmDsData.php | 56 +++ plugin/admin/app/model/OpmDsDepartment.php | 42 ++ plugin/admin/app/model/OpmDsDevice.php | 68 +++ plugin/admin/app/model/OpmDsLog.php | 42 ++ plugin/admin/app/model/OpmDsMenu.php | 46 ++ plugin/admin/app/model/OpmDsRawData.php | 54 +++ plugin/admin/app/model/OpmDsRegion.php | 42 ++ plugin/admin/app/model/OpmDsReportData.php | 47 +++ plugin/admin/app/model/OpmDsReportLog.php | 48 +++ plugin/admin/app/model/OpmDsRole.php | 40 ++ plugin/admin/app/model/OpmDsSensor.php | 56 +++ plugin/admin/app/model/OpmDsTestreport.php | 51 +++ plugin/admin/app/model/OpmDsVerifyData.php | 45 ++ plugin/admin/app/model/OpmDsWarnRecord.php | 53 +++ plugin/admin/app/model/OpmDsWarnRule.php | 49 +++ .../admin/app/repository/BaseRepository.php | 48 +++ .../app/repository/DataOverviewRepository.php | 147 +++++++ .../app/repository/DepartmentRepository.php | 55 +++ .../admin/app/repository/DeviceRepository.php | 32 ++ .../app/repository/DeviceStatusRepository.php | 140 +++++++ .../app/repository/DeviceUsageRepository.php | 106 +++++ .../app/repository/HospitalRepository.php | 50 +++ .../admin/app/repository/SensorRepository.php | 32 ++ .../app/repository/WarnRecordRepository.php | 32 ++ .../app/repository/WarnRuleRepository.php | 32 ++ .../exception/EntityNotFoundException.php | 17 + .../exception/NotFoundUserException.php | 17 + .../ResultNotAsExpectedException.php | 17 + plugin/admin/app/service/BaseService.php | 7 + .../admin/app/service/DataOverviewService.php | 176 ++++++++ .../admin/app/service/DepartmentService.php | 23 + .../admin/app/service/DeviceStatusService.php | 146 +++++++ .../admin/app/service/DeviceUsageService.php | 69 +++ plugin/admin/app/service/HospitalService.php | 28 ++ plugin/admin/app/view/appeal/index.html | 20 + .../admin/app/view/data-overview/index.html | 394 ++++++++++++++++++ plugin/admin/app/view/department/index.html | 189 +++++++++ plugin/admin/app/view/department/insert.html | 97 +++++ plugin/admin/app/view/department/update.html | 126 ++++++ .../admin/app/view/device-monitor/index.html | 77 ++++ .../admin/app/view/device-status/index.html | 332 +++++++++++++++ plugin/admin/app/view/device-usage/index.html | 183 ++++++++ plugin/admin/app/view/device/index.html | 193 +++++++++ plugin/admin/app/view/device/insert.html | 129 ++++++ plugin/admin/app/view/device/update.html | 169 ++++++++ plugin/admin/app/view/enforcement/index.html | 20 + plugin/admin/app/view/hospital/index.html | 198 +++++++++ plugin/admin/app/view/hospital/insert.html | 104 +++++ plugin/admin/app/view/hospital/update.html | 129 ++++++ plugin/admin/app/view/sensor/index.html | 135 ++++++ plugin/admin/app/view/sensor/insert.html | 78 ++++ plugin/admin/app/view/sensor/update.html | 78 ++++ plugin/admin/app/view/video/index.html | 20 + plugin/admin/app/view/warn-record/deal.html | 99 +++++ plugin/admin/app/view/warn-record/index.html | 201 +++++++++ plugin/admin/app/view/warn-rule/index.html | 218 ++++++++++ 77 files changed, 6034 insertions(+), 42 deletions(-) create mode 100644 plugin/admin/app/controller/AppealController.php create mode 100644 plugin/admin/app/controller/DataOverviewController.php create mode 100644 plugin/admin/app/controller/DepartmentController.php create mode 100644 plugin/admin/app/controller/DeviceController.php create mode 100644 plugin/admin/app/controller/DeviceMonitorController.php create mode 100644 plugin/admin/app/controller/DeviceStatusController.php create mode 100644 plugin/admin/app/controller/DeviceUsageController.php create mode 100644 plugin/admin/app/controller/EnforcementController.php create mode 100644 plugin/admin/app/controller/HospitalController.php create mode 100644 plugin/admin/app/controller/SensorController.php create mode 100644 plugin/admin/app/controller/VideoController.php create mode 100644 plugin/admin/app/controller/WarnRecordController.php create mode 100644 plugin/admin/app/controller/WarnRuleController.php create mode 100644 plugin/admin/app/controller/WithDataPermission.php create mode 100644 plugin/admin/app/model/OpmDsAuth.php create mode 100644 plugin/admin/app/model/OpmDsCamera.php create mode 100644 plugin/admin/app/model/OpmDsCycle.php create mode 100644 plugin/admin/app/model/OpmDsData.php create mode 100644 plugin/admin/app/model/OpmDsDepartment.php create mode 100644 plugin/admin/app/model/OpmDsDevice.php create mode 100644 plugin/admin/app/model/OpmDsLog.php create mode 100644 plugin/admin/app/model/OpmDsMenu.php create mode 100644 plugin/admin/app/model/OpmDsRawData.php create mode 100644 plugin/admin/app/model/OpmDsRegion.php create mode 100644 plugin/admin/app/model/OpmDsReportData.php create mode 100644 plugin/admin/app/model/OpmDsReportLog.php create mode 100644 plugin/admin/app/model/OpmDsRole.php create mode 100644 plugin/admin/app/model/OpmDsSensor.php create mode 100644 plugin/admin/app/model/OpmDsTestreport.php create mode 100644 plugin/admin/app/model/OpmDsVerifyData.php create mode 100644 plugin/admin/app/model/OpmDsWarnRecord.php create mode 100644 plugin/admin/app/model/OpmDsWarnRule.php create mode 100644 plugin/admin/app/repository/BaseRepository.php create mode 100644 plugin/admin/app/repository/DataOverviewRepository.php create mode 100644 plugin/admin/app/repository/DepartmentRepository.php create mode 100644 plugin/admin/app/repository/DeviceRepository.php create mode 100644 plugin/admin/app/repository/DeviceStatusRepository.php create mode 100644 plugin/admin/app/repository/DeviceUsageRepository.php create mode 100644 plugin/admin/app/repository/HospitalRepository.php create mode 100644 plugin/admin/app/repository/SensorRepository.php create mode 100644 plugin/admin/app/repository/WarnRecordRepository.php create mode 100644 plugin/admin/app/repository/WarnRuleRepository.php create mode 100644 plugin/admin/app/repository/exception/EntityNotFoundException.php create mode 100644 plugin/admin/app/repository/exception/NotFoundUserException.php create mode 100644 plugin/admin/app/repository/exception/ResultNotAsExpectedException.php create mode 100644 plugin/admin/app/service/BaseService.php create mode 100644 plugin/admin/app/service/DataOverviewService.php create mode 100644 plugin/admin/app/service/DepartmentService.php create mode 100644 plugin/admin/app/service/DeviceStatusService.php create mode 100644 plugin/admin/app/service/DeviceUsageService.php create mode 100644 plugin/admin/app/service/HospitalService.php create mode 100644 plugin/admin/app/view/appeal/index.html create mode 100644 plugin/admin/app/view/data-overview/index.html create mode 100644 plugin/admin/app/view/department/index.html create mode 100644 plugin/admin/app/view/department/insert.html create mode 100644 plugin/admin/app/view/department/update.html create mode 100644 plugin/admin/app/view/device-monitor/index.html create mode 100644 plugin/admin/app/view/device-status/index.html create mode 100644 plugin/admin/app/view/device-usage/index.html create mode 100644 plugin/admin/app/view/device/index.html create mode 100644 plugin/admin/app/view/device/insert.html create mode 100644 plugin/admin/app/view/device/update.html create mode 100644 plugin/admin/app/view/enforcement/index.html create mode 100644 plugin/admin/app/view/hospital/index.html create mode 100644 plugin/admin/app/view/hospital/insert.html create mode 100644 plugin/admin/app/view/hospital/update.html create mode 100644 plugin/admin/app/view/sensor/index.html create mode 100644 plugin/admin/app/view/sensor/insert.html create mode 100644 plugin/admin/app/view/sensor/update.html create mode 100644 plugin/admin/app/view/video/index.html create mode 100644 plugin/admin/app/view/warn-record/deal.html create mode 100644 plugin/admin/app/view/warn-record/index.html create mode 100644 plugin/admin/app/view/warn-rule/index.html diff --git a/app/controller/IndexController.php b/app/controller/IndexController.php index 3f6ee5f..bc4cc11 100644 --- a/app/controller/IndexController.php +++ b/app/controller/IndexController.php @@ -3,7 +3,7 @@ namespace app\controller; use app\config\Config; -use plugin\admin\app\common\ModelAutoGenerator; +use app\utils\ModelAutoGenerator; use app\zlm\ZLMClient; use support\Request; use support\Response; diff --git a/app/repository/exception/NotFoundUserException.php b/app/repository/exception/NotFoundUserException.php index 85b7425..b0c3208 100644 --- a/app/repository/exception/NotFoundUserException.php +++ b/app/repository/exception/NotFoundUserException.php @@ -1,6 +1,6 @@ service = new DataOverviewService(); + } + + public function index(): Response + { + return raw_view('data-overview/index'); + } + + /** + * 消毒灭菌次数概况(今日/本周/本月/本年) + */ + public function getIndexCount(): Response + { + return json(['code' => 0, 'data' => $this->service->getIndexCount()]); + } + + /** + * 消毒灭菌锅(设备)运行状态 + */ + public function getIndexRunStatus(): Response + { + return json(['code' => 0, 'data' => $this->service->getDeviceRunStatus()]); + } + + /** + * 消毒灭菌统计折线图(7日/30日/本年) + */ + public function getIndexLine(Request $request): Response + { + $parameterTime = $request->get('parameter_time', 'week'); + return json(['code' => 0, 'data' => $this->service->getLineData($parameterTime)]); + } + + /** + * 预警概览(预警次数/处理次数) + */ + public function getIndexWarnCount(): Response + { + return json(['code' => 0, 'data' => $this->service->getWarnCount()]); + } + + /** + * 预警分布饼图数据 + */ + public function getIndexWarnTypePie(): Response + { + return json(['code' => 0, 'data' => $this->service->getWarnTypePie()]); + } + + /** + * 预警分布百分比信息 + */ + public function getIndexWarnTypePieInfo(): Response + { + return json(['code' => 0, 'data' => $this->service->getWarnTypePieInfo()]); + } + + /** + * 预警设备列表 + */ + public function getIndexWarnDeviceList(): Response + { + $data = $this->service->getWarnDeviceList(); + return json(['code' => 0, 'data' => $data ?? false]); + } + + /** + * 事件数据 + */ + public function getIndexEvent(): Response + { + return json(['code' => 0, 'data' => $this->service->getEventData()]); + } +} diff --git a/plugin/admin/app/controller/DepartmentController.php b/plugin/admin/app/controller/DepartmentController.php new file mode 100644 index 0000000..09bd3cd --- /dev/null +++ b/plugin/admin/app/controller/DepartmentController.php @@ -0,0 +1,75 @@ +model = new OpmMwDepartment; + $this->service = new DepartmentService(); + $this->repository = DepartmentRepository::new(); + } + + public function index(): Response + { + return raw_view('department/index'); + } + + public function insert(Request $request): Response + { + if ($request->method() === 'POST') { + return parent::insert($request); + } + return raw_view('department/insert'); + } + + public function update(Request $request): Response + { + if ($request->method() === 'POST') { + return parent::update($request); + } + return raw_view('department/update'); + } + + protected function afterQuery($items) + { + foreach ($items as &$item) { + $hospital = OpmMwHospital::find($item->organ_id); + $item->hospital_name = $hospital->organ_name ?? '未知'; + } + return $items; + } + + /** + * 获取指定医院下科室选项 + */ + public function options(Request $request): Response + { + $hospitalId = (int)$request->get('hospital_id', 0); + if ($hospitalId <= 0) { + return $this->json(1, '缺少医院ID参数'); + } + return $this->json(0, 'ok', $this->service->getDepartmentOptions($hospitalId)); + } +} diff --git a/plugin/admin/app/controller/DeviceController.php b/plugin/admin/app/controller/DeviceController.php new file mode 100644 index 0000000..f046f55 --- /dev/null +++ b/plugin/admin/app/controller/DeviceController.php @@ -0,0 +1,68 @@ +model = new OpmDsDevice; + $this->repository = DeviceRepository::new(); + } + + public function index(): Response + { + return raw_view('device/index'); + } + + public function insert(Request $request): Response + { + if ($request->method() === 'POST') { + return parent::insert($request); + } + return raw_view('device/insert'); + } + + public function update(Request $request): Response + { + if ($request->method() === 'POST') { + return parent::update($request); + } + return raw_view('device/update'); + } + + protected function afterQuery($items) + { + $statusMap = [1 => '正常', 2 => '离线', 3 => '报警']; + $typeMap = [1 => '网关', 2 => '消毒灭菌器']; + + foreach ($items as &$item) { + $hospital = OpmMwHospital::find($item->hospital_id); + $department = OpmMwDepartment::find($item->department_id); + $item->hospital_name = $hospital->organ_name ?? '未知'; + $item->department_name = $department->dept_name ?? '未知'; + $item->status_text = $statusMap[$item->status] ?? '未知'; + $item->type_text = $typeMap[$item->type] ?? '未知'; + } + return $items; + } +} diff --git a/plugin/admin/app/controller/DeviceMonitorController.php b/plugin/admin/app/controller/DeviceMonitorController.php new file mode 100644 index 0000000..37ad78e --- /dev/null +++ b/plugin/admin/app/controller/DeviceMonitorController.php @@ -0,0 +1,19 @@ +service = new DeviceStatusService(); + } + + public function index(): Response + { + return raw_view('device-status/index'); + } + + /** + * 获取设备按钮列表(带数据权限) + */ + public function getDeviceNameList(): Response + { + return json(['code' => 0, 'data' => $this->service->getDeviceNameList()]); + } + + /** + * 获取设备基本信息 + */ + public function getDeviceBasicInfo(): Response + { + $deviceId = request()->get('id') ? (int)request()->get('id') : null; + return json(['code' => 0, 'data' => $this->service->getDeviceBasicInfo($deviceId)]); + } + + /** + * 获取设备灭菌次数及合规次数 + */ + public function getDeviceRunInfo(): Response + { + $deviceId = request()->get('id') ? (int)request()->get('id') : null; + return json(['code' => 0, 'data' => $this->service->getDeviceRunInfo($deviceId)]); + } + + /** + * 获取设备预警次数(按类型分) + */ + public function getDeviceWarnInfo(): Response + { + $deviceId = request()->get('id') ? (int)request()->get('id') : null; + return json(['code' => 0, 'data' => $this->service->getDeviceWarnInfo($deviceId)]); + } + + /** + * 获取设备最近周期运行折线图数据 + */ + public function getDeviceCycleRunLine(): Response + { + $deviceId = request()->get('id') ? (int)request()->get('id') : null; + return json(['code' => 0, 'data' => $this->service->getDeviceCycleRunLine($deviceId)]); + } + + /** + * 获取设备最近周期运行列表(右侧小表格) + */ + public function getDeviceCycleRunList(): Response + { + $deviceId = request()->get('id') ? (int)request()->get('id') : null; + return json(['code' => 0, 'data' => $this->service->getDeviceCycleRunList($deviceId)]); + } + + /** + * 获取该设备下所有周期运行信息(操作记录) + */ + public function getDeviceAllCycleInfo(): Response + { + $deviceId = request()->get('id') ? (int)request()->get('id') : null; + return json(['code' => 0, 'data' => $this->service->getDeviceAllCycleInfo($deviceId)]); + } +} diff --git a/plugin/admin/app/controller/DeviceUsageController.php b/plugin/admin/app/controller/DeviceUsageController.php new file mode 100644 index 0000000..2afe638 --- /dev/null +++ b/plugin/admin/app/controller/DeviceUsageController.php @@ -0,0 +1,48 @@ +service = new DeviceUsageService(); + } + + public function index(): Response + { + return raw_view('device-usage/index'); + } + + /** + * 获取设备使用情况列表(Layui table 格式,带数据权限) + */ + public function select(): Response + { + $params = request()->get(); + $result = $this->service->getUsageList($params); + + return json([ + 'code' => 0, + 'msg' => '', + 'count' => $result['total'], + 'data' => $result['data'], + ]); + } + + /** + * 获取设备下拉选项(带数据权限,复用 DeviceStatusService) + */ + public function deviceOptions(): Response + { + return json(['code' => 0, 'msg' => 'ok', 'data' => $this->service->getDeviceOptions()]); + } +} diff --git a/plugin/admin/app/controller/EnforcementController.php b/plugin/admin/app/controller/EnforcementController.php new file mode 100644 index 0000000..6e55aa7 --- /dev/null +++ b/plugin/admin/app/controller/EnforcementController.php @@ -0,0 +1,19 @@ +model = new OpmMwHospital; + $this->service = new HospitalService(); + $this->repository = HospitalRepository::new(); + } + + public function index(): Response + { + return raw_view('hospital/index'); + } + + public function insert(Request $request): Response + { + if ($request->method() === 'POST') { + return parent::insert($request); + } + return raw_view('hospital/insert'); + } + + public function update(Request $request): Response + { + if ($request->method() === 'POST') { + return parent::update($request); + } + return raw_view('hospital/update'); + } + + protected function afterQuery($items) + { + $levelMap = [0 => '未定级', 1 => '一级', 2 => '二级', 3 => '三级']; + $gradeMap = [0 => '未定级', 1 => '甲等', 2 => '乙等']; + + foreach ($items as &$item) { + $level = $levelMap[$item->organ_level] ?? '未知'; + $grade = $gradeMap[$item->grade] ?? '未知'; + $item->level_grade_text = $level . $grade; + } + return $items; + } + + /** + * 医院下拉选项(供其他页面使用) + */ + public function options(): Response + { + return $this->json(0, 'ok', $this->service->getHospitalOptions()); + } +} diff --git a/plugin/admin/app/controller/SensorController.php b/plugin/admin/app/controller/SensorController.php new file mode 100644 index 0000000..b361cf5 --- /dev/null +++ b/plugin/admin/app/controller/SensorController.php @@ -0,0 +1,63 @@ +model = new OpmDsSensor; + $this->repository = SensorRepository::new(); + } + + public function index(): Response + { + return raw_view('sensor/index'); + } + + public function insert(Request $request): Response + { + if ($request->method() === 'POST') { + return parent::insert($request); + } + return raw_view('sensor/insert'); + } + + public function update(Request $request): Response + { + if ($request->method() === 'POST') { + return parent::update($request); + } + return raw_view('sensor/update'); + } + + protected function afterQuery($items) + { + foreach ($items as &$item) { + $hospital = OpmMwHospital::find($item->hospital_id); + $department = OpmMwDepartment::find($item->department_id); + $item->hospital_name = $hospital->organ_name ?? '未知'; + $item->department_name = $department->dept_name ?? '未知'; + } + return $items; + } +} diff --git a/plugin/admin/app/controller/VideoController.php b/plugin/admin/app/controller/VideoController.php new file mode 100644 index 0000000..4bc8b5b --- /dev/null +++ b/plugin/admin/app/controller/VideoController.php @@ -0,0 +1,19 @@ +model = new OpmDsWarnRecord; + $this->repository = WarnRecordRepository::new(); + } + + public function index(): Response + { + return raw_view('warn-record/index'); + } + + /** + * 处置页面 / 处置提交 + */ + public function deal(Request $request): Response + { + if ($request->method() === 'POST') { + $id = (int)$request->post('id'); + $record = $this->repository->findWithPermission($id); + $record->action = $request->post('action', ''); + $record->action_name = $request->post('action_name', ''); + $record->action_time = $request->post('action_time', date('Y-m-d H:i:s')); + $record->status = 2; // 已处理 + $record->save(); + return $this->json(0, 'ok'); + } + return raw_view('warn-record/deal'); + } + + protected function afterQuery($items) + { + $typeMap = [1 => '温度预警', 2 => '压力预警', 3 => '时间预警']; + $levelMap = [1 => '初级', 2 => '中级', 3 => '高级']; + $statusMap = [1 => '未处理', 2 => '已处理']; + $notifierTypeMap = [1 => '短信', 2 => '电话', 3 => '微信']; + + foreach ($items as &$item) { + $hospital = OpmMwHospital::find($item->hospital_id); + $device = OpmDsDevice::find($item->device_id); + $item->hospital_name = $hospital->organ_name ?? '未知'; + $item->device_name = $device->name ?? '未知'; + $item->type_text = $typeMap[$item->type] ?? '未知'; + $item->level_text = $levelMap[$item->level] ?? '未知'; + $item->status_text = $statusMap[$item->status] ?? '未知'; + $item->notifier_type_text = $notifierTypeMap[$item->notifier_type] ?? '未知'; + } + return $items; + } +} diff --git a/plugin/admin/app/controller/WarnRuleController.php b/plugin/admin/app/controller/WarnRuleController.php new file mode 100644 index 0000000..b0b2fb4 --- /dev/null +++ b/plugin/admin/app/controller/WarnRuleController.php @@ -0,0 +1,72 @@ +model = new OpmDsWarnRule; + $this->repository = WarnRuleRepository::new(); + } + + public function index(): Response + { + return raw_view('warn-rule/index'); + } + + public function insert(Request $request): Response + { + if ($request->method() === 'POST') { + return parent::insert($request); + } + return raw_view('warn-rule/insert'); + } + + public function update(Request $request): Response + { + if ($request->method() === 'POST') { + return parent::update($request); + } + return raw_view('warn-rule/update'); + } + + protected function afterQuery($items) + { + $typeMap = [1 => '温度', 2 => '压力', 3 => '时间']; + $levelMap = [1 => '初级', 2 => '中级', 3 => '高级']; + $noticeTypeMap = [1 => '短信', 2 => '电话', 3 => '微信']; + $isOpenMap = [1 => '开启', 2 => '关闭']; + + foreach ($items as &$item) { + $hospital = OpmMwHospital::find($item->hospital_id); + $device = OpmDsDevice::find($item->device_id); + $item->hospital_name = $hospital->organ_name ?? '未知'; + $item->device_name = $device->name ?? '未知'; + $item->type_text = $typeMap[$item->type] ?? '未知'; + $item->level_text = $levelMap[$item->level] ?? '未知'; + $item->notice_type_text = $noticeTypeMap[$item->notice_type] ?? '未知'; + $item->is_open_text = $isOpenMap[$item->is_open] ?? '未知'; + } + return $items; + } +} diff --git a/plugin/admin/app/controller/WithDataPermission.php b/plugin/admin/app/controller/WithDataPermission.php new file mode 100644 index 0000000..f130db8 --- /dev/null +++ b/plugin/admin/app/controller/WithDataPermission.php @@ -0,0 +1,66 @@ +repository 属性(BaseRepository 子类) + * 重写 doSelect / doUpdate / doDelete,走 Repository 的 scopedQuery + */ +trait WithDataPermission +{ + /** + * 查询 - 以 repository->scopedQuery() 为基础,注入 withDataPermission + */ + protected function doSelect(array $where, ?string $field = null, string $order = 'desc') + { + $model = $this->repository->scopedQuery(); + foreach ($where as $column => $value) { + if (is_array($value)) { + if ($value[0] === 'like' || $value[0] === 'not like') { + $model = $model->where($column, $value[0], "%$value[1]%"); + } elseif (in_array($value[0], ['>', '=', '<', '<>'])) { + $model = $model->where($column, $value[0], $value[1]); + } elseif ($value[0] == 'in' && !empty($value[1])) { + $valArr = is_string($value[1]) ? explode(",", trim($value[1])) : $value[1]; + $model = $model->whereIn($column, $valArr); + } elseif ($value[0] == 'not in' && !empty($value[1])) { + $valArr = is_string($value[1]) ? explode(",", trim($value[1])) : $value[1]; + $model = $model->whereNotIn($column, $valArr); + } elseif ($value[0] == 'null') { + $model = $model->whereNull($column); + } elseif ($value[0] == 'not null') { + $model = $model->whereNotNull($column); + } elseif ($value[0] !== '' || $value[1] !== '') { + $model = $model->whereBetween($column, $value); + } + } else { + $model = $model->where($column, $value); + } + } + if ($field) { + $model = $model->orderBy($field, $order); + } + return $model; + } + + /** + * 更新 - 带数据权限查找记录 + */ + protected function doUpdate($id, $data) + { + $model = $this->repository->findWithPermission($id); + foreach ($data as $key => $val) { + $model->{$key} = $val; + } + $model->save(); + } + + /** + * 删除 - 带数据权限 + */ + protected function doDelete(array $ids) + { + $this->repository->deleteWithPermission($ids); + } +} diff --git a/plugin/admin/app/model/Base.php b/plugin/admin/app/model/Base.php index 0152840..7d1c9dc 100644 --- a/plugin/admin/app/model/Base.php +++ b/plugin/admin/app/model/Base.php @@ -19,45 +19,6 @@ class Base extends Model */ protected $connection = 'plugin.admin.mysql'; - /** - * -------------------------- - * 【核心配置】权限规则配置 - * 新增规则只需在这里加一项,无需改下面的逻辑 - * -------------------------- - */ - protected function getPermissionRules(): array - { - return [ - // 规则1:医院权限 - 'hospital' => [ - 'table' => 'opm_mw_hospital', // 表名 - 'admin_attr' => 'hospitals', // 用户属性里的键($admin['hospitals']) - 'permission_field'=> 'id', // 表中用于权限过滤的字段 - 'related_field' => null, // 关联上级权限的字段(如科室关联医院的organ_id) - 'related_rule' => null, // 关联的上级规则key(对应上面的'hospital') - ], - // 规则2:科室权限 - 'department' => [ - 'table' => 'opm_mw_department', - 'admin_attr' => 'departments', - 'permission_field'=> 'id', - 'related_field' => 'organ_id', // 科室通过organ_id关联医院 - 'related_rule' => 'hospital', // 关联上级规则:医院 - ], - // 规则3:数据权限 - // 这个需要绑定 医院的.id - // 这个需要绑定 科室的.id - 'data' => [ - 'table' => 'opm_mw_info_data', - 'admin_attr' => 'data', - 'permission_field'=> 'id', - 'related_field' => null, - 'related_rule' => null, - ], - - ]; - } - /** * 格式化日期 */ diff --git a/plugin/admin/app/model/OpmDsAuth.php b/plugin/admin/app/model/OpmDsAuth.php new file mode 100644 index 0000000..242613b --- /dev/null +++ b/plugin/admin/app/model/OpmDsAuth.php @@ -0,0 +1,41 @@ +model->newQuery()->withDataPermission(); + } + + /** + * 通过ID查找记录(带数据权限),找不到则抛异常 + * @throws EntityNotFoundException + */ + public function findWithPermission(int $id) + { + $record = $this->scopedQuery()->find($id); + if (!$record) { + throw new EntityNotFoundException('记录不存在'); + } + return $record; + } + + /** + * 通过ID批量删除(带数据权限) + */ + public function deleteWithPermission(array $ids): void + { + if (empty($ids)) { + return; + } + $primaryKey = $this->model->getKeyName(); + $this->scopedQuery()->whereIn($primaryKey, $ids)->each(function ($model) { + $model->delete(); + }); + } +} diff --git a/plugin/admin/app/repository/DataOverviewRepository.php b/plugin/admin/app/repository/DataOverviewRepository.php new file mode 100644 index 0000000..0ad07dc --- /dev/null +++ b/plugin/admin/app/repository/DataOverviewRepository.php @@ -0,0 +1,147 @@ +where('created_at', '>=', $start) + ->where('created_at', '<=', $end) + ->count(); + } + + /** + * 获取设备运行状态列表 + */ + public function getDeviceRunStatus(): array + { + return OpmDsDevice::withDataPermission() + ->orderBy('status', 'desc') + ->get() + ->map(function ($item) { + return [ + 'name' => $item->name, + 'description' => $item->description, + 'status' => $item->status == 1 ? '正常' : '报警', + ]; + }) + ->toArray(); + } + + /** + * 获取指定日期的周期数量 + */ + public function getCycleCountByDate(string $date): int + { + return OpmDsCycle::withDataPermission() + ->where('created_at', $date) + ->count(); + } + + /** + * 获取指定日期的合格周期数量 + */ + public function getQualifiedCycleCountByDate(string $date): int + { + return OpmDsCycle::withDataPermission() + ->where('created_at', $date) + ->where('is_warn', 1) + ->count(); + } + + /** + * 获取指定月份的周期数量 + */ + public function getCycleCountByMonth(string $monthStart, string $monthEnd): int + { + return OpmDsCycle::withDataPermission() + ->where('start_time', '>=', $monthStart) + ->where('start_time', '<=', $monthEnd) + ->count(); + } + + /** + * 获取指定月份的合格周期数量 + */ + public function getQualifiedCycleCountByMonth(string $monthStart, string $monthEnd): int + { + return OpmDsCycle::withDataPermission() + ->where('start_time', '>=', $monthStart) + ->where('start_time', '<=', $monthEnd) + ->where('is_warn', 1) + ->count(); + } + + /** + * 获取预警总数 + */ + public function getWarnCount(): int + { + return OpmDsWarnRecord::withDataPermission()->count(); + } + + /** + * 获取已处理预警数量 + */ + public function getWarnDealCount(): int + { + return OpmDsWarnRecord::withDataPermission() + ->where('status', 2) + ->count(); + } + + /** + * 获取指定类型的预警数量 + */ + public function getWarnCountByType(int $type): int + { + return OpmDsWarnRecord::withDataPermission() + ->where('type', $type) + ->count(); + } + + /** + * 获取预警记录列表(带关联信息) + */ + public function getWarnRecordList(): array + { + $records = OpmDsWarnRecord::withDataPermission()->get(); + + if ($records->isEmpty()) { + return []; + } + + $typeMap = [1 => '温度预警', 2 => '压力预警', 3 => '时间预警']; + $levelMap = [1 => '初级', 2 => '中级', 3 => '高级']; + + return $records->map(function ($item) use ($typeMap, $levelMap) { + $hospital = OpmMwHospital::find($item->hospital_id); + $device = OpmDsDevice::find($item->device_id); + + return [ + 'hospital' => $hospital->hospital ?? '', + 'name' => $device->name ?? '', + 'type' => $typeMap[$item->type] ?? '未知', + 'level' => $levelMap[$item->level] ?? '未知', + 'notifier' => $item->notifier, + 'notification_time' => $item->notification_time, + 'status' => $item->status == 1 ? '未处理' : '已处理', + ]; + })->toArray(); + } + + public static function new(): BaseRepository + { + return new self(); + } +} diff --git a/plugin/admin/app/repository/DepartmentRepository.php b/plugin/admin/app/repository/DepartmentRepository.php new file mode 100644 index 0000000..61e80ca --- /dev/null +++ b/plugin/admin/app/repository/DepartmentRepository.php @@ -0,0 +1,55 @@ +model = new OpmMwDepartment; + } + + public static function new(): DepartmentRepository + { + return new self(); + } + + /** + * 只查询消毒灭菌科室 (type=1) + */ + public function scopedQuery() + { + return parent::scopedQuery()->where('type', 1); + } + + /** + * 根据ID查找科室 + * @throws EntityNotFoundException + */ + public function findOrFail(int $id): OpmMwDepartment + { + $dept = $this->scopedQuery()->find($id); + if (!$dept) { + throw new EntityNotFoundException('科室不存在'); + } + return $dept; + } + + /** + * 获取指定医院下的科室选项 + */ + public function getDepartmentsByHospital(int $hospitalId): array + { + return $this->scopedQuery() + ->where('organ_id', $hospitalId) + ->get() + ->map(fn($item) => [ + 'id' => $item->id, + 'name' => $item->dept_name, + ]) + ->toArray(); + } +} diff --git a/plugin/admin/app/repository/DeviceRepository.php b/plugin/admin/app/repository/DeviceRepository.php new file mode 100644 index 0000000..ef2c9ac --- /dev/null +++ b/plugin/admin/app/repository/DeviceRepository.php @@ -0,0 +1,32 @@ +model = new OpmDsDevice; + } + + public static function new(): DeviceRepository + { + return new self(); + } + + /** + * 根据ID查找设备 + * @throws EntityNotFoundException + */ + public function findOrFail(int $id): OpmDsDevice + { + $device = $this->scopedQuery()->find($id); + if (!$device) { + throw new EntityNotFoundException('设备不存在'); + } + return $device; + } +} diff --git a/plugin/admin/app/repository/DeviceStatusRepository.php b/plugin/admin/app/repository/DeviceStatusRepository.php new file mode 100644 index 0000000..f8e158e --- /dev/null +++ b/plugin/admin/app/repository/DeviceStatusRepository.php @@ -0,0 +1,140 @@ +model = new OpmDsDevice; + } + + public static function new(): DeviceStatusRepository + { + return new self(); + } + + /** + * 获取消毒灭菌器列表(带数据权限,仅 type=2) + */ + public function getDeviceNameList(): array + { + return $this->scopedQuery() + ->where('type', 2) + ->select(['id', 'name']) + ->get() + ->toArray(); + } + + /** + * 获取消毒灭菌器下拉选项(带数据权限) + */ + public function getDeviceOptions(): array + { + return $this->scopedQuery() + ->where('type', 2) + ->select(['id', 'name']) + ->get() + ->map(fn($item) => ['name' => $item->name, 'value' => $item->id]) + ->toArray(); + } + + /** + * 获取第一个消毒灭菌器ID(带数据权限) + */ + public function getFirstDeviceId(): ?int + { + $device = $this->scopedQuery()->where('type', 2)->first(); + return $device?->id; + } + + /** + * 获取设备基本信息 + */ + public function getDeviceDetail(int $deviceId): array + { + $device = OpmDsDevice::find($deviceId); + if (!$device) return []; + + $hospital = OpmMwHospital::find($device->hospital_id); + $department = OpmMwDepartment::find($device->department_id); + + return [ + 'id' => $device->id, + 'name' => $device->name, + 'manufacturer' => $device->manufacturer, + 'description' => $device->description, + 'hospital' => $hospital->organ_name ?? '', + 'department' => $department->dept_name ?? '', + 'created_at' => $device->created_at, + ]; + } + + /** + * 获取设备消毒次数及合规次数 + */ + public function getCycleStats(int $deviceId): array + { + return [ + 'totalCount' => OpmDsCycle::where('device_id', $deviceId)->count(), + 'ComplianceCount' => OpmDsCycle::where('device_id', $deviceId)->where('is_warn', 1)->count(), + ]; + } + + /** + * 获取设备预警次数(按类型) + */ + public function getWarnStats(int $deviceId): array + { + return [ + 'totalWarnCount' => OpmDsWarnRecord::where('device_id', $deviceId)->count(), + 'totalTemperatureWarnCount' => OpmDsWarnRecord::where('device_id', $deviceId)->where('type', 1)->count(), + 'totalPressureWarnCount' => OpmDsWarnRecord::where('device_id', $deviceId)->where('type', 2)->count(), + 'totalTimeWarnCount' => OpmDsWarnRecord::where('device_id', $deviceId)->where('type', 3)->count(), + ]; + } + + /** + * 获取设备最近一个周期ID + */ + public function getLatestCycleId(int $deviceId): ?int + { + $cycle = OpmDsCycle::where('device_id', $deviceId)->orderBy('id', 'desc')->first(); + return $cycle?->id; + } + + /** + * 获取指定周期的运行数据(温度、压力、时间) + */ + public function getCycleRunData(int $cycleId, int $limit = 1000): \Illuminate\Support\Collection + { + return Db::connection('plugin.admin.mysql') + ->table('opm_ds_data_big') + ->where('cycle_id', $cycleId) + ->orderBy('sensor_time', 'asc') + ->limit($limit) + ->get(['temperature', 'pressure', 'sensor_time']); + } + + /** + * 获取设备所有周期列表(操作记录) + */ + public function getAllCyclesByDevice(int $deviceId): \Illuminate\Database\Eloquent\Collection + { + return OpmDsCycle::where('device_id', $deviceId) + ->orderBy('id', 'desc') + ->get(); + } +} diff --git a/plugin/admin/app/repository/DeviceUsageRepository.php b/plugin/admin/app/repository/DeviceUsageRepository.php new file mode 100644 index 0000000..44941e4 --- /dev/null +++ b/plugin/admin/app/repository/DeviceUsageRepository.php @@ -0,0 +1,106 @@ +model = new OpmDsCycle; + } + + public static function new(): DeviceUsageRepository + { + return new self(); + } + + /** + * 分页查询周期列表(纯数据访问,带数据权限) + * + * @param array $filters ['hospital_ids' => [], 'device_id' => int, 'start_time' => string, 'end_time' => string] + * @param int $page + * @param int $limit + * @return array ['total' => int, 'items' => Collection] + */ + public function paginateCycles(array $filters, int $page, int $limit): array + { + $query = $this->scopedQuery(); + + if (!empty($filters['hospital_ids'])) { + $query->whereIn('hospital_id', $filters['hospital_ids']); + } + + if (!empty($filters['device_id'])) { + $query->where('device_id', $filters['device_id']); + } + + if (!empty($filters['start_time'])) { + $query->where('start_time', '>=', $filters['start_time']); + } + + if (!empty($filters['end_time'])) { + $query->where('end_time', '<=', $filters['end_time'] . ' 23:59:59'); + } + + $total = $query->count(); + + $items = (clone $query) + ->orderBy('id', 'desc') + ->skip(($page - 1) * $limit) + ->take($limit) + ->get(); + + return ['total' => $total, 'items' => $items]; + } + + /** + * 格式化单条周期记录(关联查询医院/科室/设备/传感器) + */ + public function formatCycleItem($item): array + { + $hospital = OpmMwHospital::find($item->hospital_id); + $department = OpmMwDepartment::find($item->department_id); + $device = OpmDsDevice::find($item->device_id); + $sensor = OpmDsSensor::find($item->sensor_id); + + // 计算时长 + $duration = ''; + if ($item->start_time && $item->end_time) { + $start = strtotime($item->start_time); + $end = strtotime($item->end_time); + if ($start && $end && $end > $start) { + $diff = $end - $start; + $hours = floor($diff / 3600); + $minutes = floor(($diff % 3600) / 60); + $duration = $hours . '小时' . $minutes . '分钟'; + } + } + + return [ + 'id' => $item->id, + 'hospital_name' => $hospital->organ_name ?? '', + 'department' => $department->dept_name ?? '', + 'device_name' => $device->name ?? '', + 'sensor_sn' => $sensor->sn ?? '', + 'sensor_coding' => $sensor->coding ?? '', + 'pack' => $item->pack, + 'operation' => $item->operation, + 'start_time' => $item->start_time, + 'end_time' => $item->end_time, + 'duration' => $duration, + 'is_warn' => $item->is_warn, + 'is_warn_text' => $item->is_warn == 1 ? '正常' : '预警', + 'created_at' => $item->created_at, + ]; + } +} diff --git a/plugin/admin/app/repository/HospitalRepository.php b/plugin/admin/app/repository/HospitalRepository.php new file mode 100644 index 0000000..b249ab3 --- /dev/null +++ b/plugin/admin/app/repository/HospitalRepository.php @@ -0,0 +1,50 @@ +model = new OpmMwHospital; + } + + public static function new(): HospitalRepository + { + return new self(); + } + + /** + * 只查询消毒灭菌医院 (ds_region_id != 0) + */ + public function scopedQuery() + { + return parent::scopedQuery()->where('ds_region_id', '!=', 0); + } + + /** + * 获取医院列表(带数据权限) + */ + public function getListWithPermission(): \Illuminate\Database\Eloquent\Collection + { + return $this->scopedQuery() + ->orderBy('id', 'desc') + ->get(); + } + + /** + * 根据ID查找医院 + * @throws EntityNotFoundException + */ + public function findOrFail(int $id): OpmMwHospital + { + $hospital = $this->scopedQuery()->find($id); + if (!$hospital) { + throw new EntityNotFoundException('医院不存在'); + } + return $hospital; + } +} diff --git a/plugin/admin/app/repository/SensorRepository.php b/plugin/admin/app/repository/SensorRepository.php new file mode 100644 index 0000000..f1245e6 --- /dev/null +++ b/plugin/admin/app/repository/SensorRepository.php @@ -0,0 +1,32 @@ +model = new OpmDsSensor; + } + + public static function new(): SensorRepository + { + return new self(); + } + + /** + * 根据ID查找传感器 + * @throws EntityNotFoundException + */ + public function findOrFail(int $id): OpmDsSensor + { + $sensor = $this->scopedQuery()->find($id); + if (!$sensor) { + throw new EntityNotFoundException('传感器不存在'); + } + return $sensor; + } +} diff --git a/plugin/admin/app/repository/WarnRecordRepository.php b/plugin/admin/app/repository/WarnRecordRepository.php new file mode 100644 index 0000000..3d049d6 --- /dev/null +++ b/plugin/admin/app/repository/WarnRecordRepository.php @@ -0,0 +1,32 @@ +model = new OpmDsWarnRecord; + } + + public static function new(): WarnRecordRepository + { + return new self(); + } + + /** + * 根据ID查找预警记录 + * @throws EntityNotFoundException + */ + public function findOrFail(int $id): OpmDsWarnRecord + { + $record = $this->scopedQuery()->find($id); + if (!$record) { + throw new EntityNotFoundException('预警记录不存在'); + } + return $record; + } +} diff --git a/plugin/admin/app/repository/WarnRuleRepository.php b/plugin/admin/app/repository/WarnRuleRepository.php new file mode 100644 index 0000000..222272f --- /dev/null +++ b/plugin/admin/app/repository/WarnRuleRepository.php @@ -0,0 +1,32 @@ +model = new OpmDsWarnRule; + } + + public static function new(): WarnRuleRepository + { + return new self(); + } + + /** + * 根据ID查找报警规则 + * @throws EntityNotFoundException + */ + public function findOrFail(int $id): OpmDsWarnRule + { + $rule = $this->scopedQuery()->find($id); + if (!$rule) { + throw new EntityNotFoundException('报警规则不存在'); + } + return $rule; + } +} diff --git a/plugin/admin/app/repository/exception/EntityNotFoundException.php b/plugin/admin/app/repository/exception/EntityNotFoundException.php new file mode 100644 index 0000000..ceed067 --- /dev/null +++ b/plugin/admin/app/repository/exception/EntityNotFoundException.php @@ -0,0 +1,17 @@ +repository = DataOverviewRepository::new(); + } + + /** + * 获取首页统计计数(今日/本周/本月/本年) + */ + public function getIndexCount(): array + { + $today = date('Y-m-d'); + $weekStart = date('Y-m-d', time() - ((date('w') == 0 ? 7 : date('w')) - 1) * 86400); + $monthStart = date('Y-m') . '-01'; + $yearStart = date('Y') . '-01-01'; + + return [ + 'todayCount' => $this->repository->getCycleCount($today, $today), + 'weekCount' => $this->repository->getCycleCount($weekStart, $today), + 'monthCount' => $this->repository->getCycleCount($monthStart, $today), + 'yearCount' => $this->repository->getCycleCount($yearStart, $today), + ]; + } + + /** + * 获取设备运行状态 + */ + public function getDeviceRunStatus(): array + { + return $this->repository->getDeviceRunStatus(); + } + + /** + * 获取折线图数据(7日/30日/本年) + */ + public function getLineData(string $parameterTime): array + { + $result = ['time' => [], 'count' => [], 'qualifiedCount' => []]; + + if ($parameterTime !== 'year') { + $days = $parameterTime === 'week' ? 6 : 29; + $startDate = date('Y-m-d', time() - $days * 86400); + $endDate = date('Y-m-d'); + $dates = $this->getDateRange($startDate, $endDate); + + foreach ($dates as $date) { + $result['time'][] = date('m-d', strtotime($date)); + $result['count'][] = $this->repository->getCycleCountByDate($date); + $result['qualifiedCount'][] = $this->repository->getQualifiedCycleCountByDate($date); + } + } else { + $months = $this->getYearMonths(); + foreach ($months as $month) { + $monthStart = $month . '-01 00:00:00'; + $monthEnd = $month . '-31 00:00:00'; + + $result['time'][] = date('m-d', strtotime($monthStart)); + $result['count'][] = $this->repository->getCycleCountByMonth($monthStart, $monthEnd); + $result['qualifiedCount'][] = $this->repository->getQualifiedCycleCountByMonth($monthStart, $monthEnd); + } + } + + return $result; + } + + /** + * 获取预警统计 + */ + public function getWarnCount(): array + { + return [ + 'warnCount' => $this->repository->getWarnCount(), + 'warnDealCount' => $this->repository->getWarnDealCount(), + ]; + } + + /** + * 获取预警类型饼图数据 + */ + public function getWarnTypePie(): array + { + $total = $this->repository->getWarnCount(); + + if ($total != 0) { + $result = []; + for ($type = 1; $type <= 3; $type++) { + $count = $this->repository->getWarnCountByType($type); + $result[] = round($count / $total, 2) * 100; + } + } else { + $result = [0.000001, 0.000001, 0.000001]; + } + + return $result; + } + + /** + * 获取预警类型百分比信息 + */ + public function getWarnTypePieInfo(): array + { + $total = $this->repository->getWarnCount(); + + if ($total != 0) { + $result = []; + foreach (['temperature' => 1, 'pressure' => 2, 'time' => 3] as $key => $type) { + $count = $this->repository->getWarnCountByType($type); + $result[$key] = round($count / $total, 2) * 100; + } + } else { + $result = ['temperature' => 0, 'pressure' => 0, 'time' => 0]; + } + + return $result; + } + + /** + * 获取预警设备列表 + */ + public function getWarnDeviceList(): ?array + { + $data = $this->repository->getWarnRecordList(); + return empty($data) ? null : $data; + } + + /** + * 获取事件数据 + */ + public function getEventData(): array + { + return [ + 'noStandard' => 0, + 'LowFrequency' => 0, + 'AbnormalOperation' => 0, + 'AbnormalMonitoring' => 0, + 'AbnormalData' => 0, + ]; + } + + /** + * 获取日期范围内每一天 + */ + private function getDateRange(string $start, string $end): array + { + $dates = []; + $current = strtotime($start); + $endTime = strtotime($end); + while ($current <= $endTime) { + $dates[] = date('Y-m-d', $current); + $current = strtotime('+1 day', $current); + } + return $dates; + } + + /** + * 获取本年每个月 + */ + private function getYearMonths(): array + { + $months = []; + $year = date('Y'); + for ($i = 1; $i <= 12; $i++) { + $months[] = date('Y-m', strtotime("{$year}-{$i}")); + } + return $months; + } +} diff --git a/plugin/admin/app/service/DepartmentService.php b/plugin/admin/app/service/DepartmentService.php new file mode 100644 index 0000000..6ba11b1 --- /dev/null +++ b/plugin/admin/app/service/DepartmentService.php @@ -0,0 +1,23 @@ +repository = DepartmentRepository::new(); + } + + /** + * 获取指定医院下的科室选项 + */ + public function getDepartmentOptions(int $hospitalId): array + { + return $this->repository->getDepartmentsByHospital($hospitalId); + } +} diff --git a/plugin/admin/app/service/DeviceStatusService.php b/plugin/admin/app/service/DeviceStatusService.php new file mode 100644 index 0000000..b58e577 --- /dev/null +++ b/plugin/admin/app/service/DeviceStatusService.php @@ -0,0 +1,146 @@ +repository = DeviceStatusRepository::new(); + } + + /** + * 获取消毒灭菌器按钮列表 + */ + public function getDeviceNameList(): array + { + return $this->repository->getDeviceNameList(); + } + + /** + * 获取消毒灭菌器下拉选项(供其他模块复用) + */ + public function getDeviceOptions(): array + { + return $this->repository->getDeviceOptions(); + } + + /** + * 解析设备ID,未传则取第一个设备 + */ + private function resolveDeviceId(?int $deviceId): ?int + { + return $deviceId ?: $this->repository->getFirstDeviceId(); + } + + /** + * 获取设备基本信息 + */ + public function getDeviceBasicInfo(?int $deviceId): array + { + $deviceId = $this->resolveDeviceId($deviceId); + if (!$deviceId) return []; + + return $this->repository->getDeviceDetail($deviceId); + } + + /** + * 获取设备消毒次数及合规次数 + */ + public function getDeviceRunInfo(?int $deviceId): array + { + $deviceId = $this->resolveDeviceId($deviceId); + if (!$deviceId) return ['totalCount' => 0, 'ComplianceCount' => 0]; + + return $this->repository->getCycleStats($deviceId); + } + + /** + * 获取设备预警次数(按类型分) + */ + public function getDeviceWarnInfo(?int $deviceId): array + { + $deviceId = $this->resolveDeviceId($deviceId); + if (!$deviceId) return [ + 'totalWarnCount' => 0, 'totalTemperatureWarnCount' => 0, + 'totalPressureWarnCount' => 0, 'totalTimeWarnCount' => 0, + ]; + + return $this->repository->getWarnStats($deviceId); + } + + /** + * 获取设备最近周期运行折线数据 + */ + public function getDeviceCycleRunLine(?int $deviceId): array + { + $deviceId = $this->resolveDeviceId($deviceId); + if (!$deviceId) return []; + + $cycleId = $this->repository->getLatestCycleId($deviceId); + if (!$cycleId) return []; + + $data = $this->repository->getCycleRunData($cycleId, 1000); + + $temperature = []; + $pressure = []; + $time = []; + foreach ($data as $row) { + $temperature[] = $row->temperature; + $pressure[] = $row->pressure; + $time[] = date('m-d H:i', strtotime($row->sensor_time)); + } + + return compact('temperature', 'pressure', 'time'); + } + + /** + * 获取设备最近周期运行列表(右侧小表格) + */ + public function getDeviceCycleRunList(?int $deviceId): array + { + $deviceId = $this->resolveDeviceId($deviceId); + if (!$deviceId) return []; + + $cycleId = $this->repository->getLatestCycleId($deviceId); + if (!$cycleId) return []; + + return $this->repository->getCycleRunData($cycleId, 10) + ->map(fn($row) => (array)$row) + ->toArray(); + } + + /** + * 获取设备所有周期运行信息(操作记录) + */ + public function getDeviceAllCycleInfo(?int $deviceId): array + { + $deviceId = $this->resolveDeviceId($deviceId); + if (!$deviceId) return []; + + $cycles = $this->repository->getAllCyclesByDevice($deviceId); + + return $cycles->map(function ($item) { + $device = OpmDsDevice::find($item->device_id); + + return [ + 'id' => $item->id, + 'operation' => $item->operation, + 'name' => $device->name ?? '', + 'created_at' => $item->created_at, + 'start_time' => $item->start_time, + 'pack' => $item->pack, + 'is_warn' => $item->is_warn == 1 ? '正常' : '预警', + ]; + })->toArray(); + } +} diff --git a/plugin/admin/app/service/DeviceUsageService.php b/plugin/admin/app/service/DeviceUsageService.php new file mode 100644 index 0000000..44970ac --- /dev/null +++ b/plugin/admin/app/service/DeviceUsageService.php @@ -0,0 +1,69 @@ +repository = DeviceUsageRepository::new(); + $this->deviceStatusService = new DeviceStatusService(); + } + + /** + * 获取设备使用情况列表(带分页、筛选) + */ + public function getUsageList(array $params): array + { + $page = max(1, (int)($params['page'] ?? 1)); + $limit = max(1, (int)($params['limit'] ?? 20)); + + // 解析医院多选参数 + $filters = []; + $hospitalId = $params['hospital_id'] ?? null; + if ($hospitalId) { + if (is_array($hospitalId) && ($hospitalId[0] ?? '') === 'in') { + $filters['hospital_ids'] = explode(',', trim($hospitalId[1] ?? '')); + } else { + $filters['hospital_ids'] = (array)$hospitalId; + } + } + + if (!empty($params['device_id'])) { + $filters['device_id'] = $params['device_id']; + } + if (!empty($params['start_time'])) { + $filters['start_time'] = $params['start_time']; + } + if (!empty($params['end_time'])) { + $filters['end_time'] = $params['end_time']; + } + + $result = $this->repository->paginateCycles($filters, $page, $limit); + + $data = []; + foreach ($result['items'] as $item) { + $data[] = $this->repository->formatCycleItem($item); + } + + return ['total' => $result['total'], 'data' => $data]; + } + + /** + * 获取设备下拉选项(复用 DeviceStatusService) + */ + public function getDeviceOptions(): array + { + return $this->deviceStatusService->getDeviceOptions(); + } +} diff --git a/plugin/admin/app/service/HospitalService.php b/plugin/admin/app/service/HospitalService.php new file mode 100644 index 0000000..7fa0283 --- /dev/null +++ b/plugin/admin/app/service/HospitalService.php @@ -0,0 +1,28 @@ +repository = HospitalRepository::new(); + } + + /** + * 获取医院下拉选项(用于其他模块选择医院) + */ + public function getHospitalOptions(): array + { + return $this->repository->getListWithPermission() + ->map(fn($item) => [ + 'value' => $item->id, + 'name' => $item->organ_name, + ]) + ->toArray(); + } +} diff --git a/plugin/admin/app/view/appeal/index.html b/plugin/admin/app/view/appeal/index.html new file mode 100644 index 0000000..4098504 --- /dev/null +++ b/plugin/admin/app/view/appeal/index.html @@ -0,0 +1,20 @@ + + +
+ +申诉列表
+该功能正在开发中,敬请期待...
+| 时间 | 温度 | 压力 |
|---|---|---|
| 暂无数据 | ||
执法事件列表
+该功能正在开发中,敬请期待...
+视频监控
+该功能正在开发中,敬请期待...
+