This commit is contained in:
zimoyin
2026-04-06 20:48:32 +08:00
parent 76e9f24aa7
commit 13fd9c5f0a
77 changed files with 6034 additions and 42 deletions
@@ -0,0 +1,48 @@
<?php
namespace plugin\admin\app\repository;
use plugin\admin\app\model\Base;
use plugin\admin\app\repository\exception\EntityNotFoundException;
abstract class BaseRepository
{
protected Base $model;
public static abstract function new(): BaseRepository;
/**
* 返回带数据权限的查询构建器
*/
public function scopedQuery()
{
return $this->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();
});
}
}
@@ -0,0 +1,147 @@
<?php
namespace plugin\admin\app\repository;
use plugin\admin\app\model\OpmDsCycle;
use plugin\admin\app\model\OpmDsDevice;
use plugin\admin\app\model\OpmDsWarnRecord;
use plugin\admin\app\model\OpmMwHospital;
class DataOverviewRepository extends BaseRepository
{
/**
* 获取周期统计数据(今日/本周/本月/本年)
*/
public function getCycleCount(string $start, string $end): int
{
return OpmDsCycle::withDataPermission()
->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();
}
}
@@ -0,0 +1,55 @@
<?php
namespace plugin\admin\app\repository;
use plugin\admin\app\model\OpmMwDepartment;
use plugin\admin\app\repository\exception\EntityNotFoundException;
class DepartmentRepository extends BaseRepository
{
public function __construct()
{
$this->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();
}
}
@@ -0,0 +1,32 @@
<?php
namespace plugin\admin\app\repository;
use plugin\admin\app\model\OpmDsDevice;
use plugin\admin\app\repository\exception\EntityNotFoundException;
class DeviceRepository extends BaseRepository
{
public function __construct()
{
$this->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;
}
}
@@ -0,0 +1,140 @@
<?php
namespace plugin\admin\app\repository;
use plugin\admin\app\model\OpmDsCycle;
use plugin\admin\app\model\OpmDsDevice;
use plugin\admin\app\model\OpmDsWarnRecord;
use plugin\admin\app\model\OpmMwDepartment;
use plugin\admin\app\model\OpmMwHospital;
use support\Db;
/**
* 设备数据仓库(OpmDsDevice
* 职责:纯数据访问,带数据权限
* 注:DeviceRepository 已存在,该类专注于设备监控相关的数据查询
*/
class DeviceStatusRepository extends BaseRepository
{
public function __construct()
{
$this->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();
}
}
@@ -0,0 +1,106 @@
<?php
namespace plugin\admin\app\repository;
use plugin\admin\app\model\OpmDsCycle;
use plugin\admin\app\model\OpmDsDevice;
use plugin\admin\app\model\OpmDsSensor;
use plugin\admin\app\model\OpmMwDepartment;
use plugin\admin\app\model\OpmMwHospital;
/**
* 设备使用情况数据仓库(OpmDsCycle)
* 职责:纯数据访问,带数据权限
*/
class DeviceUsageRepository extends BaseRepository
{
public function __construct()
{
$this->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,
];
}
}
@@ -0,0 +1,50 @@
<?php
namespace plugin\admin\app\repository;
use plugin\admin\app\model\OpmMwHospital;
use plugin\admin\app\repository\exception\EntityNotFoundException;
class HospitalRepository extends BaseRepository
{
public function __construct()
{
$this->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;
}
}
@@ -0,0 +1,32 @@
<?php
namespace plugin\admin\app\repository;
use plugin\admin\app\model\OpmDsSensor;
use plugin\admin\app\repository\exception\EntityNotFoundException;
class SensorRepository extends BaseRepository
{
public function __construct()
{
$this->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;
}
}
@@ -0,0 +1,32 @@
<?php
namespace plugin\admin\app\repository;
use plugin\admin\app\model\OpmDsWarnRecord;
use plugin\admin\app\repository\exception\EntityNotFoundException;
class WarnRecordRepository extends BaseRepository
{
public function __construct()
{
$this->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;
}
}
@@ -0,0 +1,32 @@
<?php
namespace plugin\admin\app\repository;
use plugin\admin\app\model\OpmDsWarnRule;
use plugin\admin\app\repository\exception\EntityNotFoundException;
class WarnRuleRepository extends BaseRepository
{
public function __construct()
{
$this->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;
}
}
@@ -0,0 +1,17 @@
<?php
namespace plugin\admin\app\repository\exception;
use RuntimeException;
class EntityNotFoundException extends RuntimeException
{
public function __construct(
string $message = '记录不存在',
int $code = 404,
?\Throwable $previous = null
)
{
parent::__construct($message, $code, $previous);
}
}
@@ -0,0 +1,17 @@
<?php
namespace plugin\admin\app\repository\exception;
use RuntimeException;
class NotFoundUserException extends RuntimeException
{
public function __construct(
$message = 'Not Found User in database',
int $code = 404,
?\Throwable $previous = null
)
{
parent::__construct($message, $code, $previous);
}
}
@@ -0,0 +1,17 @@
<?php
namespace plugin\admin\app\repository\exception;
use RuntimeException;
class ResultNotAsExpectedException extends RuntimeException
{
public function __construct(
$message = 'Result not as expected',
int $code = 404,
?\Throwable $previous = null
)
{
parent::__construct($message, $code, $previous);
}
}