Шаблон отчета дежурного врача

This commit is contained in:
brusnitsyn
2026-07-06 15:27:43 +09:00
parent d322317d06
commit 2b0221ed36
5 changed files with 98 additions and 2 deletions

View File

@@ -0,0 +1,41 @@
<?php
namespace App\Exports;
use App\Models\Department;
use App\Models\User;
use Maatwebsite\Excel\Concerns\FromArray;
use Maatwebsite\Excel\Concerns\WithTitle;
class DutyReportExport implements FromArray, WithTitle
{
protected array $data;
protected array $dateRange;
protected User $user;
protected Department $department;
protected string $reportName;
public function __construct(
array $data,
array $dateRange,
User $user,
Department $department,
string $reportName = 'Статистика по отделениям',
) {
$this->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;
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Http\Controllers\Web; namespace App\Http\Controllers\Web;
use App\Exports\DutyReportExport;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Http\Resources\MedicalHistoryResource; use App\Http\Resources\MedicalHistoryResource;
use App\Models\Department; use App\Models\Department;
@@ -15,11 +16,13 @@ use App\Services\DutyReportService;
use App\Services\MedicalHistoryService; use App\Services\MedicalHistoryService;
use App\Services\NurseMedicalHistoryService; use App\Services\NurseMedicalHistoryService;
use App\Services\NurseReportService; use App\Services\NurseReportService;
use App\Services\StatisticsService;
use App\Services\UnifiedMedicalHistoryService; use App\Services\UnifiedMedicalHistoryService;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Carbon; use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Inertia\Inertia; use Inertia\Inertia;
use Maatwebsite\Excel\Facades\Excel;
class DutyReportController extends Controller class DutyReportController extends Controller
{ {
@@ -28,7 +31,8 @@ class DutyReportController extends Controller
protected MedicalHistoryService $medicalHistoryService, protected MedicalHistoryService $medicalHistoryService,
protected DutyMedicalHistoryService $dutyMedicalHistoryService, protected DutyMedicalHistoryService $dutyMedicalHistoryService,
protected DutyReportService $dutyReportService, protected DutyReportService $dutyReportService,
protected NurseMedicalHistoryService $nurseMedicalHistoryService protected NurseMedicalHistoryService $nurseMedicalHistoryService,
protected StatisticsService $statisticsService
) )
{} {}
@@ -356,4 +360,24 @@ class DutyReportController extends Controller
'out_reason' => 'Закрыто пользователем' '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');
}
} }

View File

@@ -216,6 +216,33 @@ const reportCreatorType = computed(() => {
else return 'warning' 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) => { watch(() => props, (newProps) => {
syncPageProps(newProps) syncPageProps(newProps)
}, { }, {
@@ -321,6 +348,9 @@ watch(() => props, (newProps) => {
secondary type="error" :loading="loading" @click="onShowUnwantedEventModal"> secondary type="error" :loading="loading" @click="onShowUnwantedEventModal">
Нежелательные события ({{ latestReportObj.unwanted_events?.length ?? 0 }}) Нежелательные события ({{ latestReportObj.unwanted_events?.length ?? 0 }})
</NButton> </NButton>
<NButton secondary @click="downloadReport" :loading="loading">
Сформировать отчет дежурного
</NButton>
<NButton v-if="props.canSaveReport" secondary @click="submit" :loading="loading"> <NButton v-if="props.canSaveReport" secondary @click="submit" :loading="loading">
Сохранить введенные данные Сохранить введенные данные
</NButton> </NButton>

View File

@@ -50,7 +50,7 @@ const columns = ref([
{ {
title: 'Отделение', title: 'Отделение',
key: 'department', key: 'department',
width: 200, width: 240,
titleAlign: 'center', titleAlign: 'center',
cellProps: (row) => ({ 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);' 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);'

View File

@@ -126,5 +126,6 @@ Route::prefix('duty')->middleware(['auth'])->group(function () {
Route::prefix('report')->group(function () { Route::prefix('report')->group(function () {
Route::get('/', [\App\Http\Controllers\Web\DutyReportController::class, 'index']); Route::get('/', [\App\Http\Controllers\Web\DutyReportController::class, 'index']);
Route::post('/save', [\App\Http\Controllers\Web\DutyReportController::class, 'store']); Route::post('/save', [\App\Http\Controllers\Web\DutyReportController::class, 'store']);
Route::get('/generate', [\App\Http\Controllers\Web\DutyReportController::class, 'generateReport']);
}); });
}); });