From 2b0221ed36b1147df82881a1c5cde9543807ca00 Mon Sep 17 00:00:00 2001 From: brusnitsyn Date: Mon, 6 Jul 2026 15:27:43 +0900 Subject: [PATCH] =?UTF-8?q?=D0=A8=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD=20=D0=BE?= =?UTF-8?q?=D1=82=D1=87=D0=B5=D1=82=D0=B0=20=D0=B4=D0=B5=D0=B6=D1=83=D1=80?= =?UTF-8?q?=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=B2=D1=80=D0=B0=D1=87=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Exports/DutyReportExport.php | 41 +++++++++++++++++++ .../Controllers/Web/DutyReportController.php | 26 +++++++++++- resources/js/Pages/Report/Index.vue | 30 ++++++++++++++ resources/js/Pages/Statistic/Index.vue | 2 +- routes/web.php | 1 + 5 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 app/Exports/DutyReportExport.php diff --git a/app/Exports/DutyReportExport.php b/app/Exports/DutyReportExport.php new file mode 100644 index 0000000..35ea494 --- /dev/null +++ b/app/Exports/DutyReportExport.php @@ -0,0 +1,41 @@ +data = $data; + $this->dateRange = $dateRange; + $this->user = $user; + $this->department = $department; + $this->reportName = $reportName; + } + + public function array(): array + { + // TODO: Implement array() method. + } + + public function title(): string + { + return $this->sheetTitle; + } +} diff --git a/app/Http/Controllers/Web/DutyReportController.php b/app/Http/Controllers/Web/DutyReportController.php index 16316c8..8963268 100644 --- a/app/Http/Controllers/Web/DutyReportController.php +++ b/app/Http/Controllers/Web/DutyReportController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers\Web; +use App\Exports\DutyReportExport; use App\Http\Controllers\Controller; use App\Http\Resources\MedicalHistoryResource; use App\Models\Department; @@ -15,11 +16,13 @@ use App\Services\DutyReportService; use App\Services\MedicalHistoryService; use App\Services\NurseMedicalHistoryService; use App\Services\NurseReportService; +use App\Services\StatisticsService; use App\Services\UnifiedMedicalHistoryService; use Illuminate\Http\Request; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Auth; use Inertia\Inertia; +use Maatwebsite\Excel\Facades\Excel; class DutyReportController extends Controller { @@ -28,7 +31,8 @@ class DutyReportController extends Controller protected MedicalHistoryService $medicalHistoryService, protected DutyMedicalHistoryService $dutyMedicalHistoryService, protected DutyReportService $dutyReportService, - protected NurseMedicalHistoryService $nurseMedicalHistoryService + protected NurseMedicalHistoryService $nurseMedicalHistoryService, + protected StatisticsService $statisticsService ) {} @@ -356,4 +360,24 @@ class DutyReportController extends Controller 'out_reason' => 'Закрыто пользователем' ]); } + + /** + * Формирование отчета дежурного в Excel + */ + public function generateReport(Request $request) + { + $user = $request->user(); + + $queryStartDate = $request->query('startAt'); + $queryEndDate = $request->query('endAt'); + $queryDepartmentId = $request->query('departmentId', $user->department->department_id); + + [$startDate, $endDate] = $this->dateRangeService->getStatisticsDateRange($user, $queryStartDate, $queryEndDate); + $isRangeOneDay = $this->dateRangeService->isRangeOneDay($startDate, $endDate); + $department = Department::find($queryDepartmentId); + + $finalData = $this->statisticsService->getStatisticsData($user, $startDate, $endDate, $isRangeOneDay, $department->department_id); + + return Excel::download(new DutyReportExport($finalData['data'], [$startDate, $endDate], $user, $department), 'statistics.xlsx'); + } } diff --git a/resources/js/Pages/Report/Index.vue b/resources/js/Pages/Report/Index.vue index 6e9b664..45c2101 100644 --- a/resources/js/Pages/Report/Index.vue +++ b/resources/js/Pages/Report/Index.vue @@ -216,6 +216,33 @@ const reportCreatorType = computed(() => { else return 'warning' }) +const downloadReport = async () => { + try { + const response = await fetch(`/duty/report/generate?startAt=${props.dates[0]}&endAt=${props.dates[1]}&departmentId=${props.department.department_id}`, { + method: 'GET', + headers: { + 'Accept': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + }, + }) + + if (!response.ok) { + throw new Error('Ошибка загрузки файла') + } + + const blob = await response.blob() + const url = window.URL.createObjectURL(blob) + const a = document.createElement('a') + a.href = url + a.download = 'Отчёт дежурного.xlsx' + document.body.appendChild(a) + a.click() + window.URL.revokeObjectURL(url) + document.body.removeChild(a) + } catch { + // silent + } +} + watch(() => props, (newProps) => { syncPageProps(newProps) }, { @@ -321,6 +348,9 @@ watch(() => props, (newProps) => { secondary type="error" :loading="loading" @click="onShowUnwantedEventModal"> Нежелательные события ({{ latestReportObj.unwanted_events?.length ?? 0 }}) + + Сформировать отчет дежурного + Сохранить введенные данные diff --git a/resources/js/Pages/Statistic/Index.vue b/resources/js/Pages/Statistic/Index.vue index 854108d..a095fcd 100644 --- a/resources/js/Pages/Statistic/Index.vue +++ b/resources/js/Pages/Statistic/Index.vue @@ -50,7 +50,7 @@ const columns = ref([ { title: 'Отделение', key: 'department', - width: 200, + width: 240, titleAlign: 'center', cellProps: (row) => ({ style: '--n-merged-td-color: var(--n-merged-th-color); --n-merged-td-color-striped: var(--n-merged-th-color); --n-td-text-color: var(--color-zinc-400); --n-th-text-color: var(--color-zinc-400);' diff --git a/routes/web.php b/routes/web.php index d2a2e0b..1a69340 100644 --- a/routes/web.php +++ b/routes/web.php @@ -126,5 +126,6 @@ Route::prefix('duty')->middleware(['auth'])->group(function () { Route::prefix('report')->group(function () { Route::get('/', [\App\Http\Controllers\Web\DutyReportController::class, 'index']); Route::post('/save', [\App\Http\Controllers\Web\DutyReportController::class, 'store']); + Route::get('/generate', [\App\Http\Controllers\Web\DutyReportController::class, 'generateReport']); }); });