1
0
Fork 0
medical-record-server/app/Admin/Controllers/PatientRecordController.php

295 lines
15 KiB
PHP

<?php
namespace App\Admin\Controllers;
use App\Enums\OrderStatus;
use App\Models\{Keyword, Patient, PatientRecord};
use App\Admin\Services\PatientRecordService;
use Slowlyo\OwlAdmin\Controllers\AdminController;
use Slowlyo\OwlAdmin\Renderers\Form;
use Slowlyo\OwlAdmin\Renderers\Page;
use Slowlyo\OwlAdmin\Services\AdminUserService;
use Slowlyo\OwlAdmin\Support\Excel\AdminExport;
/**
* 病历管理
*/
class PatientRecordController extends AdminController
{
protected string $serviceName = PatientRecordService::class;
protected $typeOptions;
protected $patientOptions;
protected $adminUserOptions;
protected $illnessOptions;
public function list(): Page
{
$crud = $this->baseCRUD()
->filterTogglable(false)
->columnsTogglable(false)
->headerToolbar([
$this->createButton(true, 'lg'),
$this->exportAction(),
])
->filter($this->baseFilter()->actions()->body([
amisMake()->SelectControl()->options($this->getPatientOptions())->searchable()->name('patient_id')->label(__('patient-record.patient_id'))->size('md')->clearable(),
amisMake()->SelectControl()->options($this->getTypeOptions())->name('type_id')->label(__('patient-record.type_id'))->size('md')->clearable(),
amisMake()->SelectControl()->options($this->getIllnessOption())->name('illness_type_id')->label(__('patient-record.illness_type_id'))->size('md')->clearable(),
amisMake()->DateRangeControl()->name('treat_range')->label(__('patient-record.treat_at'))->size('md')->clearable(),
amisMake()->SelectControl()->options($this->getAdminUserOptions())->searchable()->name('doctor_id')->label(__('patient-record.doctor_id'))->clearable()->size('md'),
amisMake()->SelectControl()->options($this->getAdminUserOptions())->searchable()->name('inviter_id')->label(__('patient-record.inviter_id'))->clearable()->size('md'),
amisMake()->SelectControl()->options($this->getAdminUserOptions())->searchable()->name('saler_id')->label(__('patient-record.saler_id'))->clearable()->size('md'),
// amisMake()->Button()->label(__('admin.reset'))->actionType('clear-and-submit'),
amisMake()->Component()->setType('submit')->label(__('admin.search'))->level('primary'),
]))
->columns([
amisMake()->TableColumn()->name('id')->label(__('patient-record.id')),
amisMake()->TableColumn()->name('patient.name')->label(__('patient-record.patient_id')),
amisMake()->TableColumn()->name('type.name')->label(__('patient-record.type_id')),
amisMake()->TableColumn()->name('illness_type.name')->label(__('patient-record.illness_type_id')),
amisMake()->TableColumn()->name('treat_at')->label(__('patient-record.treat_at')),
amisMake()->TableColumn()->name('sell_price')->label(__('patient-record.sell_price')),
amisMake()->TableColumn()->name('doctor.name')->label(__('patient-record.doctor_id')),
amisMake()->TableColumn()->name('doctor_money')->label(__('patient-record.doctor_money')),
amisMake()->TableColumn()->name('inviter.name')->label(__('patient-record.inviter_id')),
amisMake()->TableColumn()->name('inviter_money')->label(__('patient-record.inviter_money')),
amisMake()->TableColumn()->name('saler.name')->label(__('patient-record.saler_id')),
amisMake()->TableColumn()->name('saler_money')->label(__('patient-record.saler_money')),
$this->rowActions(),
])
->alwaysShowPagination()
->affixRowClassName('text-info-dk')
->affixRow([
['type' => 'text', 'text' => '总计: ${total}', 'colSpan' => 5],
['type' => 'text', 'text' => __('total-record.sell_price') . ': ${sell_price}'],
['type' => 'text', 'text' => __('patient-record.doctor_money').': ${doctor_money}', 'colSpan' => 2],
['type' => 'text', 'text' => __('patient-record.inviter_money').': ${inviter_money}', 'colSpan' => 2],
['type' => 'text', 'text' => __('patient-record.saler_money').': ${saler_money}', 'colSpan' => 2],
['type' => 'text', 'text' => __('patient-record.total_money').': ${total_money}'],
]);
return $this->baseList($crud);
}
public function form($isEdit, $patient_id = null): Form
{
$patient_element = amisMake()->SelectControl()
->options($this->getPatientOptions())
->searchable()
->name('patient_id')
->label(__('patient-record.patient_id'))
->onEvent([
'change' => [
'actions' => [
['actionType' => 'reload', 'componentId' => 'patient_record_form_content_service', 'args' => ['select_type_id' => '${patient_id}']]
]
]
])
->required();
if ($patient_id) {
$patient_element->value($patient_id);
}
return $this->baseForm()->body([
$patient_element,
amisMake()->SelectControl()->options($this->getIllnessOption())->name('illness_type_id')->label(__('patient-record.illness_type_id'))->required(),
amisMake()->DateTimeControl()->name('treat_at')->label(__('patient-record.treat_at'))->value(now())->required(),
amisMake()->SelectControl()->options($this->getAdminUserOptions())->searchable()->name('doctor_id')->label(__('patient-record.doctor_id'))->required(),
amisMake()->NumberControl()->name('origin_price')->label(__('patient-record.origin_price'))->required(),
amisMake()->NumberControl()->name('sell_price')->label(__('patient-record.sell_price'))->required(),
amisMake()->SelectControl()->options(OrderStatus::options())->name('order_status')->label(__('patient-record.order_status'))->default(OrderStatus::Success->value)->required(),
amisMake()->Service()
->className('cxd-Form-item')
->id('patient_record_form_content_service')
->api(amisMake()->BaseApi()->method('get')->url(admin_url('api/category/content?id=${select_type_id}')))
->initFetch(false)
// ->body(Components::make()->fuEditorControl()->name('content')->label(__('patient-record.content'))),
->body(amisMake()->TextareaControl()->name('content')->label(__('patient-record.content'))),
amisMake()->ImageControl()->multiple()->receiver(admin_url('upload_image') . '?full-url=1')->name('images')->label(__('patient-record.images')),
amisMake()->DateTimeControl()->name('next_treat_at')->label(__('patient-record.next_treat_at')),
amisMake()->SwitchControl()->name('is_notified')->label(__('patient-record.is_notified'))->trueValue(0)->falseValue(1),
amisMake()->SelectControl()->options($this->getAdminUserOptions())->searchable()->name('notify_user_id')->label(__('patient-record.notify_user_id')),
amisMake()->DateControl()->name('notify_at')->label(__('patient-record.notify_at')),
// amisMake()->TextControl()->name('notify_remarks')->label(__('patient-record.notify_remarks')),
// amisMake()->TextControl()->label(__('patient-record.creator_id'))->name('creator_id')->value($this->user()->name)->readonly(),
]);
}
public function detail()
{
return $this->baseDetail()->panelClassName('m:px-0')->body([
amisMake()->Property()->items([
['label' => __('patient-record.patient_id'), 'content' => '${patient.name}'],
['label' => __('patient-record.type_id'), 'content' => '${type.name}'],
['label' => __('patient-record.treat_at'), 'content' => '${treat_at}'],
['label' => __('patient-record.origin_price'), 'content' => '${origin_price}'],
['label' => __('patient-record.sell_price'), 'content' => '${sell_price}'],
['label' => __('patient-record.order_status'), 'content' => '${order_status_text}'],
['label' => __('patient-record.doctor_id'), 'content' => '${doctor.name}'],
['label' => __('patient-record.doctor_ratio'), 'content' => '${doctor_ratio}'],
['label' => __('patient-record.doctor_money'), 'content' => '${doctor_money}'],
['label' => __('patient-record.inviter_id'), 'content' => '${inviter.name}'],
['label' => __('patient-record.inviter_ratio'), 'content' => '${inviter_ratio}'],
['label' => __('patient-record.inviter_money'), 'content' => '${inviter_money}'],
['label' => __('patient-record.saler_id'), 'content' => '${saler.name}'],
['label' => __('patient-record.saler_ratio'), 'content' => '${saler_ratio}'],
['label' => __('patient-record.saler_money'), 'content' => '${saler_money}'],
['label' => __('patient-record.illness_type_id'), 'content' => '${illness_type.name}', 'span' => 3],
['label' => __('patient-record.content'), 'content' => amisMake()->Tpl()->tpl('${content | raw}'), 'span' => 3],
['label' => __('patient-record.images'), 'content' => amisMake()->Images()->source('${images}')->defaultImage(null), 'span' => 3],
['label' => __('patient-record.next_treat_at'), 'content' => '${next_treat_at}'],
['label' => __('patient-record.is_notified'), 'content' => amisMake()->Status()->value('${is_notified}')->source([
['icon' => 'fa fa-check', 'color' => '#30bf13'],
['icon' => 'fa fa-close', 'color' => '#cc292e']
])],
['label' => __('patient-record.notify_user_id'), 'content' => '${notify_user.name}'],
['label' => __('patient-record.notify_at'), 'content' => '${notify_at}'],
['label' => __('patient-record.creator_id'), 'content' => '${creator.name}'],
['label' => __('patient-record.created_at'), 'content' => '${created_at}'],
]),
]);
}
public function getTypeOptions()
{
if (!$this->typeOptions) {
$this->typeOptions = Keyword::where('type_key', 'treat_type')->select(['id as value', 'name as label'])->get();
}
return $this->typeOptions;
}
public function getPatientOptions()
{
if (!$this->patientOptions) {
$this->patientOptions = Patient::select(['id as value', 'name as label'])->sort()->get();
}
return $this->patientOptions;
}
public function getAdminUserOptions()
{
if (!$this->adminUserOptions) {
$this->adminUserOptions = AdminUserService::make()->query()->select(['id as value', 'name as label'])->get();
}
return $this->adminUserOptions;
}
public function getIllnessOption()
{
if (!$this->illnessOptions) {
$this->illnessOptions = Keyword::where('type_key', PatientRecord::ILLNESS_TYPE_KEY)->select(['id as value', 'name as label'])->get();
}
return $this->illnessOptions;
}
protected function exportAction($disableSelectedItem = false)
{
$event = fn($script) => ['click' => ['actions' => [['actionType' => 'custom', 'script' => $script]]]];
$downloadPath = '/' . admin_url('_download_export', true);
$exportPath = $this->getExportPath();
$doAction = <<<JS
doAction([
{ actionType: "ajax", args: { api: { url: url.toString(), method: "get" } } },
{
actionType: "custom",
expression: "\${event.data.responseResult.responseStatus === 0}",
script: "window.open('{$downloadPath}?path='+event.data.responseResult.responseData.path)"
}
])
JS;
return amisMake()->VanillaAction()
->label(__('admin.export.title'))
->set('icon', 'fa-solid fa-download')
->align('right')
->onEvent($event(
<<<JS
let url = new URL("{$exportPath}", window.location.origin)
let param = window.location.href.split('?')[1]
if (param) {
url = url + '&' + param
}
{$doAction}
JS
));
}
protected function export()
{
// 默认在 storage/app/ 下
$path = sprintf('%s-%s.xlsx', $this->exportFileName(), date('YmdHis'));
// 导出本页和导出选中项都是通过 _ids 查询
$ids = request()->input('_ids');
// listQuery() 为列表查询条件,与获取列表数据一致
$query = $this->service->listQuery()
->when($ids, fn($query) => $query->whereIn($this->service->primaryKey(), explode(',', $ids)));
// 此处使用 laravel-excel 导出,可自行修改
AdminExport::make($query)
->setHeadings($this->exportHeadings())
->setMap(fn($row) => $this->exportColumns($row))
->store($path);
return $this->response()->success(compact('path'));
}
protected function exportHeadings()
{
return [
__('patient-record.id'),
__('patient-record.patient_id'),
__('patient-record.type_id'),
__('patient-record.illness_type_id'),
__('patient-record.treat_at'),
__('patient-record.origin_price'),
__('patient-record.sell_price'),
__('patient-record.order_status'),
__('patient-record.doctor_id'),
__('patient-record.doctor_money'),
__('patient-record.inviter_id'),
__('patient-record.inviter_money'),
__('patient-record.saler_id'),
__('patient-record.saler_money'),
__('patient-record.creator_id'),
__('patient-record.created_at'),
];
}
protected function exportColumns($row)
{
return [
$row->id,
data_get($row->patient, 'name'),
data_get($row->type, 'name'),
data_get($row->illnessType, 'name'),
$row->treat_at,
$row->origin_price,
$row->sell_price,
$row->order_status->text(),
data_get($row->doctor, 'name'),
$row->doctor_money,
data_get($row->inviter, 'name'),
$row->inviter_money,
data_get($row->saler, 'name'),
$row->saler_money,
data_get($row->creator, 'name'),
$row->created_at,
];
}
}