From 1a2b30c0a4e0518dc8bbc382b0374847c25c86c8 Mon Sep 17 00:00:00 2001 From: panliang <1163816051@qq.com> Date: Wed, 30 Aug 2023 13:46:32 +0800 Subject: [PATCH] patient --- app/Admin/Controllers/CategoryController.php | 103 ++++++++++++ app/Admin/Controllers/PatientController.php | 148 ++++++++++++++++++ .../Controllers/PatientRecordController.php | 136 ++++++++++++++++ app/Admin/Services/PatientRecordService.php | 43 +++++ app/Admin/Services/PatientService.php | 58 +++++++ app/Console/Commands/ModelFillable.php | 54 +++++++ app/Enums/Gender.php | 33 ++++ app/Enums/OrderStatus.php | 31 ++++ app/ModelFilters/PatienRecordFilter.php | 35 +++++ app/ModelFilters/PatientFilter.php | 21 +++ app/Models/Patient.php | 61 ++++++++ app/Models/PatientRecord.php | 57 +++++++ database/factories/PatientFactory.php | 35 +++++ database/factories/PatientRecordFactory.php | 42 +++++ ...023_08_30_075602_create_patients_table.php | 37 +++++ ...30_090313_create_patient_records_table.php | 43 +++++ database/seeders/PatientSeeder.php | 22 +++ lang/zh_CN/category.php | 17 ++ lang/zh_CN/patient.php | 17 ++ lang/zh_CN/patient_record.php | 20 +++ 20 files changed, 1013 insertions(+) create mode 100644 app/Admin/Controllers/CategoryController.php create mode 100644 app/Admin/Controllers/PatientController.php create mode 100644 app/Admin/Controllers/PatientRecordController.php create mode 100644 app/Admin/Services/PatientRecordService.php create mode 100644 app/Admin/Services/PatientService.php create mode 100644 app/Console/Commands/ModelFillable.php create mode 100644 app/Enums/Gender.php create mode 100644 app/Enums/OrderStatus.php create mode 100644 app/ModelFilters/PatienRecordFilter.php create mode 100644 app/ModelFilters/PatientFilter.php create mode 100644 app/Models/Patient.php create mode 100644 app/Models/PatientRecord.php create mode 100644 database/factories/PatientFactory.php create mode 100644 database/factories/PatientRecordFactory.php create mode 100644 database/migrations/2023_08_30_075602_create_patients_table.php create mode 100644 database/migrations/2023_08_30_090313_create_patient_records_table.php create mode 100644 database/seeders/PatientSeeder.php create mode 100644 lang/zh_CN/category.php create mode 100644 lang/zh_CN/patient.php create mode 100644 lang/zh_CN/patient_record.php diff --git a/app/Admin/Controllers/CategoryController.php b/app/Admin/Controllers/CategoryController.php new file mode 100644 index 0000000..e0c702d --- /dev/null +++ b/app/Admin/Controllers/CategoryController.php @@ -0,0 +1,103 @@ +actionOfGetData()) { + $list = Keyword::where('parent_id', $this->getParentId())->filter(request()->all(), $this->service->getModelFilter())->sort()->get(); + return $this->response()->success(['items' => $list]); + } + + if ($this->actionOfExport()) { + return $this->export(); + } + + return $this->response()->success($this->list()); + } + + public function list(): Page + { + $crud = $this->baseCRUD() + ->filterTogglable(false) + ->columnsTogglable(false) + ->loadDataOnce(true) + ->autoFillHeight(true) + ->footerToolbar([]) + ->headerToolbar([ + $this->createButton(true), + amis('reload')->align('right'), + ]) + ->filter($this->baseFilter()->actions()->body([ + amisMake()->TextControl()->name('name')->label(__('category.name'))->size('md')->clearable(), + // amisMake()->Button()->label(__('admin.reset'))->actionType('clear-and-submit'), + amisMake()->Component()->setType('submit')->label(__('admin.search'))->level('primary'), + ])) + ->columns([ + amisMake()->TableColumn()->name('id')->label(__('category.id')), + amisMake()->TableColumn()->name('key')->label(__('category.key')), + amisMake()->TableColumn()->name('name')->label(__('category.name')), + // amisMake()->TableColumn()->name('content')->label(__('category.content')), + amisMake()->TextareaControl()->static()->name('content')->label(__('category.content')), + $this->rowActions(true), + ]); + + return $this->baseList($crud); + } + + public function form(): Form + { + return $this->baseForm()->body([ + amisMake()->HiddenControl()->name('parent_id')->value($this->getParentId()), + amisMake()->TextControl()->name('key')->label(__('category.key'))->required(true), + amisMake()->TextControl()->name('name')->label(__('category.name'))->required(true), + amisMake()->TextareaControl()->name('content')->label(__('category.content')), + ]); + } + + public function detail() + { + return $this->baseDetail()->body([ + amisMake()->TextControl()->name('key')->label(__('category.key'))->static(true), + amisMake()->TextControl()->name('name')->label(__('category.name'))->static(true), + amisMake()->TextareaControl()->name('content')->label(__('category.content'))->static(), + ]); + } + + public function getParentId() + { + if (!$this->parentId) { + $this->parentId = Keyword::where('key', $this->typeKey)->value('id'); + } + return $this->parentId; + } + + public function getContent(Request $request) + { + $id = $request->input('id'); + $info = Keyword::find($id); + $content = data_get($info, 'content'); + return $this->response()->success([ + 'content' => $content + ]); + } +} diff --git a/app/Admin/Controllers/PatientController.php b/app/Admin/Controllers/PatientController.php new file mode 100644 index 0000000..344ae9c --- /dev/null +++ b/app/Admin/Controllers/PatientController.php @@ -0,0 +1,148 @@ +baseCRUD() + ->filterTogglable(false) + ->columnsTogglable(false) + ->headerToolbar([ + $this->createButton(true, 'lg'), + amis('reload')->align('right'), + ]) + ->filter($this->baseFilter()->actions()->body([ + amisMake()->TextControl()->name('keyword')->label(__('patient.keyword'))->placeholder(__('patient.name') . '/' . __('patient.phone'))->size('md')->clearable(), + // 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.id')), + amisMake()->TableColumn()->name('name')->label(__('patient.name')), + amisMake()->TableColumn()->name('sex_text')->label(__('patient.sex')), + amisMake()->TableColumn()->name('phone')->label(__('patient.phone')), + amisMake()->TableColumn()->name('age')->label(__('patient.age')), + amisMake()->TableColumn()->name('treat_format')->label(__('patient.treat_at')), + $this->rowActions(), + ]); + + return $this->baseList($crud); + } + + public function form(): Form + { + return $this->baseForm()->body([ + amisMake()->TextControl()->name('name')->label(__('patient.name'))->required(true), + amisMake()->SelectControl()->options(Gender::options())->name('sex')->label(__('patient.sex')), + amisMake()->TextControl()->name('phone')->label(__('patient.phone')), + amisMake()->TextControl()->name('address')->label(__('patient.address')), + amisMake()->DateControl()->name('birthday')->label(__('patient.birthday')), + amisMake()->DateControl()->name('treat_at')->label(__('patient.treat_at')), + Components::make()->adminUserSelectControl()->name('doctor_id')->label(__('patient.doctor_id')), + amisMake()->TextareaControl()->name('illness')->label(__('patient.illness')), + ]); + } + + public function show($id) + { + if ($this->actionOfGetData()) { + return $this->response()->success($this->service->getDetail($id)); + } + + $record = new PatientRecordController(); + $detail = amisMake() + ->Card() + ->className('base-form') + ->header(['title' => __('admin.detail')]) + ->body($this->detail($id)) + ->toolbar([ + amisMake()->Button()->label('修改基础信息') + ->level('primary') + ->className('mr-1') + ->actionType('dialog') + ->dialog(amisMake()->Dialog()->size('lg')->title('修改基础信息')->body( + $this->form(true)->api($this->getUpdatePath())->initApi($this->getEditGetDataPath())->onEvent([ + 'submitSucc' => [ + 'actions' => [ + ['actionType' => 'custom', 'script' => 'window.$owl.refreshAmisPage()',] + ] + ] + ]) + )), + amisMake()->Button()->label('添加病历记录') + ->level('warning') + ->className('mr-1') + ->actionType('dialog') + ->dialog(amisMake()->Dialog()->size('lg')->title('修改基础信息')->body( + $record->form(false, $id)->api('post:' . admin_url('/record'))->onEvent([ + 'submitSucc' => [ + 'actions' => [ + ['actionType' => 'custom', 'script' => 'window.$owl.refreshAmisPage()',] + ] + ] + ]) + )), + $this->backButton() + ]); + + $page = $this->basePage()->body($detail); + + return $this->response()->success($page); + } + + public function detail($id) + { + return $this->baseDetail()->body(amisMake()->Tabs()->tabs([ + amisMake()->Tab()->title('基础信息')->body([ + amisMake()->TextControl()->name('name')->label(__('patient.name'))->static(), + amisMake()->SelectControl()->options(Gender::options())->name('sex')->label(__('patient.sex'))->static(), + amisMake()->TextControl()->name('phone')->label(__('patient.phone'))->static(), + amisMake()->TextControl()->name('address')->label(__('patient.address'))->static(), + amisMake()->DateControl()->name('birthday')->label(__('patient.birthday'))->static(), + amisMake()->DateControl()->name('treat_format')->label(__('patient.treat_at'))->static(), + amisMake()->TextControl()->name('doctor.name')->label(__('patient.doctor_id'))->static(), + amisMake()->TextareaControl()->name('illness')->label(__('patient.illness'))->static(), + amisMake()->TextControl()->name('created_at')->label(__('patient.created_at'))->static(), + ]), + amisMake()->Tab()->title('病历记录')->body(amisMake()->Service() + ->api(admin_url('/record?_action=getData&page=1&patient_id='.$id.'&perPage=20')) + ->body(amisMake()->Table()->columns([ + amisMake()->TableColumn()->name('id')->label(__('patient_record.id')), + amisMake()->Mapping()->map($this->getTypeOptions()->pluck('label', 'value'))->name('type_id')->label(__('patient_record.type_id')), + amisMake()->TableColumn()->name('treat_at')->label(__('patient_record.treat_at')), + amisMake()->TableColumn()->name('next_treat_at')->label(__('patient_record.next_treat_at')), + amisMake()->TableColumn()->name('doctor.name')->label(__('patient_record.doctor_id')), + ])->affixRow([ + amisMake()->Button()->level('link')->label('查看更多')->colSpan(5)->actionType('link')->link(admin_url('/record?patient_id=' . $id)), + ]) + ) + ) + ])); + } + + 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; + } +} diff --git a/app/Admin/Controllers/PatientRecordController.php b/app/Admin/Controllers/PatientRecordController.php new file mode 100644 index 0000000..09b2825 --- /dev/null +++ b/app/Admin/Controllers/PatientRecordController.php @@ -0,0 +1,136 @@ +baseCRUD() + ->filterTogglable(false) + ->columnsTogglable(false) + ->headerToolbar([ + $this->createButton(true, 'lg'), + amis('reload')->align('right'), + ]) + ->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()->DateRangeControl()->name('treat_range')->label(__('patient_record.treat_at'))->size('md')->clearable(), + // 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()->Mapping()->map($this->getTypeOptions()->pluck('label', 'value'))->name('type_id')->label(__('patient_record.type_id')), + amisMake()->TableColumn()->name('treat_at')->label(__('patient_record.treat_at')), + amisMake()->TableColumn()->name('next_treat_at')->label(__('patient_record.next_treat_at')), + amisMake()->TableColumn()->name('doctor.name')->label(__('patient_record.doctor_id')), + $this->rowActions(), + ]); + + 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'))->required(); + if ($patient_id) { + $patient_element->value($patient_id)->static(); + } + return $this->baseForm()->body([ + $patient_element, + amisMake()->SelectControl()->options($this->getTypeOptions())->name('type_id')->label(__('patient_record.type_id'))->required()->onEvent([ + 'change' => [ + 'actions' => [ + ['actionType' => 'reload', 'componentId' => 'patient_record_form_content_service', 'args' => ['select_type_id' => '${type_id}']] + ] + ] + ]), + amisMake()->DateTimeControl()->name('treat_at')->label(__('patient_record.treat_at'))->value(now())->required(), + amisMake()->SelectControl()->options($this->getAdminUserOptions())->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(amisMake()->TextareaControl()->name('content')->label(__('patient_record.content'))), + amisMake()->DateTimeControl()->name('next_treat_at')->label(__('patient_record.next_treat_at')), + amisMake()->SelectControl()->options($this->getAdminUserOptions())->name('notify_user_id')->label(__('patient_record.notify_user_id')), + amisMake()->DateTimeControl()->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'))->value($this->user()->name)->staitc(), + ]); + } + + public function detail() + { + return $this->baseDetail()->body([ + amisMake()->TextControl()->name('patient_id')->label(__('patient_record.patient_id'))->static(), + amisMake()->TextControl()->name('type_id')->label(__('patient_record.type_id'))->static(), + amisMake()->DateTimeControl()->name('treat_at')->label(__('patient_record.treat_at'))->static(), + amisMake()->SelectControl()->options($this->getAdminUserOptions())->name('doctor_id')->label(__('patient_record.doctor_id'))->static(), + amisMake()->TextControl()->name('origin_price')->label(__('patient_record.origin_price'))->static(), + amisMake()->TextControl()->name('sell_price')->label(__('patient_record.sell_price'))->static(), + amisMake()->SelectControl()->options(OrderStatus::options())->name('order_status')->label(__('patient_record.order_status'))->static(), + amisMake()->TextareaControl()->name('content')->label(__('patient_record.content'))->static(), + amisMake()->DateTimeControl()->name('next_treat_at')->label(__('patient_record.next_treat_at'))->static(), + amisMake()->SelectControl()->options($this->getAdminUserOptions())->name('notify_user_id')->label(__('patient_record.notify_user_id'))->placeholder('')->static(), + amisMake()->DateTimeControl()->name('notify_at')->label(__('patient_record.notify_at'))->static(), + amisMake()->TextControl()->name('notify_remarks')->label(__('patient_record.notify_remarks'))->static(), + amisMake()->SelectControl()->options($this->getAdminUserOptions())->name('creator_id')->label(__('patient_record.creator_id'))->static(), + amisMake()->DateTimeControl()->name('created_at')->label(__('patient.created_at'))->static(), + ]); + } + + 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'])->get(); + } + + return $this->patientOptions; + } + + public function getAdminUserOptions() + { + if (!$this->adminUserOptions) { + $this->adminUserOptions = AdminUser::select(['id as value', 'name as label'])->get(); + } + + return $this->adminUserOptions; + } +} diff --git a/app/Admin/Services/PatientRecordService.php b/app/Admin/Services/PatientRecordService.php new file mode 100644 index 0000000..53b0f69 --- /dev/null +++ b/app/Admin/Services/PatientRecordService.php @@ -0,0 +1,43 @@ +getModel(); + $filter = $this->getModelFilter(); + + $query = $this->query(); + if ($this->withRelationships) { + $query->with($this->withRelationships); + } + + if ($filter) { + $query->filter(request()->input(), $filter); + } + + return $query->sort(); + } + + public function resloveData($data) + { + $creator_id = data_get($data, 'creator_id'); + if (!$creator_id) { + $data['creator_id'] = data_get(Admin::user(), 'id'); + } + return $data; + } +} diff --git a/app/Admin/Services/PatientService.php b/app/Admin/Services/PatientService.php new file mode 100644 index 0000000..7eaf43b --- /dev/null +++ b/app/Admin/Services/PatientService.php @@ -0,0 +1,58 @@ + ['required'], + ]); + if ($validator->fails()) { + return $validator->errors()->first(); + } + } + return true; + } + + /** + * 删除的前置方法 + * + * @param array $ids 主键id + * @return mixed true: 继续后续操作, string: 中断操作, 返回错误提示 + */ + public function preDelete(array $ids) + { + return true; + } +} diff --git a/app/Console/Commands/ModelFillable.php b/app/Console/Commands/ModelFillable.php new file mode 100644 index 0000000..c193e33 --- /dev/null +++ b/app/Console/Commands/ModelFillable.php @@ -0,0 +1,54 @@ +argument('table'); + $ignore = ['id', 'created_at', 'updated_at', 'deleted_at']; + $connection = $this->option('connection'); + if (! $connection) { + $connection = config('database.default'); + } + + if (Schema::connection($connection)->hasTable($table)) { + $list = Schema::connection($connection)->getColumnListing($table); + $list = array_filter($list, function ($value) use ($ignore) { + return ! in_array($value, $ignore); + }); + $this->info("protected \$fillable = ['".implode('\', \'', $list)."'];"); + } + } +} diff --git a/app/Enums/Gender.php b/app/Enums/Gender.php new file mode 100644 index 0000000..9362d15 --- /dev/null +++ b/app/Enums/Gender.php @@ -0,0 +1,33 @@ +value => '未知', + self::Male->value => '男', + self::Female->value => '女', + ]; + } + + public static function options() + { + $list = []; + foreach (static::map() as $key => $value) { + array_push($list, ['label' => $value, 'value' => $key]); + } + return $list; + } + + public function text() + { + return data_get(self::map(), $this->value); + } +} diff --git a/app/Enums/OrderStatus.php b/app/Enums/OrderStatus.php new file mode 100644 index 0000000..1ff6d15 --- /dev/null +++ b/app/Enums/OrderStatus.php @@ -0,0 +1,31 @@ +value => '未收', + self::Success->value => '已收', + ]; + } + + public static function options() + { + $list = []; + foreach (static::map() as $key => $value) { + array_push($list, ['label' => $value, 'value' => $key]); + } + return $list; + } + + public function text() + { + return data_get(self::map(), $this->value); + } +} diff --git a/app/ModelFilters/PatienRecordFilter.php b/app/ModelFilters/PatienRecordFilter.php new file mode 100644 index 0000000..ebdfd8f --- /dev/null +++ b/app/ModelFilters/PatienRecordFilter.php @@ -0,0 +1,35 @@ + [input_key1, input_key2]]. + * + * @var array + */ + public $relations = []; + + public function patient($key) + { + $this->where('patient_id', $key); + } + + public function type($key) + { + $this->where('type_id', $key); + } + + public function treatRange($key) + { + $arr = explode(',', $key); + $start = Carbon::createFromTimestamp(data_get($arr, 0, time()))->startOfDay(); + $end = Carbon::createFromTimestamp(data_get($arr, 1, time()))->endOfDay(); + $this->whereBetween('treat_at', [$start, $end]); + } +} diff --git a/app/ModelFilters/PatientFilter.php b/app/ModelFilters/PatientFilter.php new file mode 100644 index 0000000..26b7b9b --- /dev/null +++ b/app/ModelFilters/PatientFilter.php @@ -0,0 +1,21 @@ + [input_key1, input_key2]]. + * + * @var array + */ + public $relations = []; + + public function keyword($key) + { + $this->where(fn ($q) => $q->where('name', 'like', '%'.$key.'%')->orWhere('phone', 'like', '%'.$key.'%')); + } +} diff --git a/app/Models/Patient.php b/app/Models/Patient.php new file mode 100644 index 0000000..825ca51 --- /dev/null +++ b/app/Models/Patient.php @@ -0,0 +1,61 @@ + Gender::class, + 'treat_at' => 'date', + 'birthday' => 'date', + ]; + + protected function age(): Attribute + { + return new Attribute( + get: fn () => $this->birthday ? $this->birthday->diffInYears() : '', + ); + } + + protected function sexText(): Attribute + { + return new Attribute( + get: fn () => $this->sex ? $this->sex->text() : '', + ); + } + + protected function treatFormat(): Attribute + { + return new Attribute( + get: fn () => $this->treat_at ? $this->treat_at->format('Y-m-d') : '', + ); + } + + protected function birthdayFormat(): Attribute + { + return new Attribute( + get: fn () => $this->birthday ? $this->birthday->format('Y-m-d') : '', + ); + } + + public function doctor() + { + return $this->belongsTo(AdminUser::class, 'doctor_id'); + } +} diff --git a/app/Models/PatientRecord.php b/app/Models/PatientRecord.php new file mode 100644 index 0000000..be7c965 --- /dev/null +++ b/app/Models/PatientRecord.php @@ -0,0 +1,57 @@ + OrderStatus::class, + 'notify_at' => 'datetime', + 'treat_at' => 'datetime', + 'next_treat_at' => 'datetime', + ]; + + public function patient() + { + return $this->belongsTo(Patient::class, 'patient_id'); + } + + public function type() + { + return $this->belongsTo(Keyword::class, 'type_id'); + } + + public function doctor() + { + return $this->belongsTo(AdminUser::class, 'doctor_id'); + } + + public function notifyUser() + { + return $this->belongsTo(AdminUser::class, 'notify_user_id'); + } + + public function creator() + { + return $this->belongsTo(AdminUser::class, 'creator_id'); + } + + public function scopeSort($q) + { + return $q->orderBy('treat_at', 'desc'); + } +} diff --git a/database/factories/PatientFactory.php b/database/factories/PatientFactory.php new file mode 100644 index 0000000..6ff3574 --- /dev/null +++ b/database/factories/PatientFactory.php @@ -0,0 +1,35 @@ + + */ +class PatientFactory extends Factory +{ + protected $model = Patient::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + $faker = $this->faker; + return [ + 'name' => $faker->name, + 'sex' => $faker->randomElement(array_keys(Gender::map())), + 'phone' => $faker->phoneNumber, + 'address' => $faker->address, + 'birthday' => $faker->dateTimeBetween('-30 years', '-10 years'), + 'treat_at' => $faker->dateTimeBetween('-7 days'), + 'illness' => '基本稳定', + 'doctor_id' => 1, + ]; + } +} diff --git a/database/factories/PatientRecordFactory.php b/database/factories/PatientRecordFactory.php new file mode 100644 index 0000000..6356618 --- /dev/null +++ b/database/factories/PatientRecordFactory.php @@ -0,0 +1,42 @@ + + */ +class PatientRecordFactory extends Factory +{ + protected $model = PatientRecord::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + $faker = $this->faker; + return [ + 'patient_id' => Patient::inRandomOrder()->value('id'), + 'type_id' => Keyword::where('type_key', 'treat_type')->inRandomOrder()->value('id'), + 'treat_at' => $faker->dateTimeBetween('-7 days'), + 'doctor_id' => 1, + 'content' => '逐渐恢复', + 'origin_price' => $faker->numberBetween(200, 300), + 'sell_price' => $faker->numberBetween(100, 200), + 'order_status' => OrderStatus::Success->value, + 'notify_at' => $faker->dateTimeBetween('now', '+7 days'), + 'notify_user_id' => 1, + 'notify_remarks' => '带上医保卡', + 'is_notified' => 0, + 'next_treat_at' => $faker->dateTimeBetween('now', '+7 days'), + 'creator_id' => 1 + ]; + } +} diff --git a/database/migrations/2023_08_30_075602_create_patients_table.php b/database/migrations/2023_08_30_075602_create_patients_table.php new file mode 100644 index 0000000..a761406 --- /dev/null +++ b/database/migrations/2023_08_30_075602_create_patients_table.php @@ -0,0 +1,37 @@ +id(); + $table->string('name')->comment('姓名'); + $table->string('sex')->default(Gender::None->value)->comment('性别'); + $table->string('phone')->nullable()->comment('联系方式'); + $table->string('address')->nullable()->comment('地址'); + $table->date('birthday')->nullable()->comment('出生年月'); + $table->dateTime('treat_at')->nullable()->comment('初诊时间'); + $table->text('illness')->nullable()->comment('病情描述'); + $table->unsignedBigInteger('doctor_id')->nullable()->comment('坐诊医生, admin_users.id'); + $table->string('remarks')->nullable()->comment('备注'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('patients'); + } +}; diff --git a/database/migrations/2023_08_30_090313_create_patient_records_table.php b/database/migrations/2023_08_30_090313_create_patient_records_table.php new file mode 100644 index 0000000..ab18ed4 --- /dev/null +++ b/database/migrations/2023_08_30_090313_create_patient_records_table.php @@ -0,0 +1,43 @@ +id(); + $table->unsignedBigInteger('patient_id')->comment('病人, patients.id'); + $table->unsignedBigInteger('type_id')->comment('类别, keywords.id'); + $table->timestamp('treat_at')->comment('就诊时间'); + $table->unsignedBigInteger('doctor_id')->comment('医生, admin_users.id'); + $table->text('content')->comment('就诊情况'); + $table->decimal('origin_price')->default(0)->comment('划线价'); + $table->decimal('sell_price')->default(0)->comment('实收价'); + $table->unsignedTinyInteger('order_status')->default(0)->comment('状态(0: 未收, 1: 已收)'); + + $table->timestamp('notify_at')->nullable()->comment('提醒时间'); + $table->unsignedBigInteger('notify_user_id')->nullable()->comment('提醒人, admin_users.id'); + $table->string('notify_remarks')->nullable()->comment('提醒备注'); + $table->unsignedTinyInteger('is_notified')->default(0)->comment('是否已经提醒'); + $table->timestamp('next_treat_at')->nullable()->comment('下次就诊时间'); + + $table->unsignedBigInteger('creator_id')->comment('操作人, admin_users.id'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('patient_records'); + } +}; diff --git a/database/seeders/PatientSeeder.php b/database/seeders/PatientSeeder.php new file mode 100644 index 0000000..b741685 --- /dev/null +++ b/database/seeders/PatientSeeder.php @@ -0,0 +1,22 @@ +count(10)->create(); + (new PatientRecordFactory())->count(100)->create(); + } +} diff --git a/lang/zh_CN/category.php b/lang/zh_CN/category.php new file mode 100644 index 0000000..f29fc48 --- /dev/null +++ b/lang/zh_CN/category.php @@ -0,0 +1,17 @@ + 'ID', + 'name' => '名称', + 'key' => 'KEY', + 'value' => '值', + 'parent_id' => '上级', + 'type_key' => '上级', + 'path' => '上级', + 'sort' => '排序(倒序)', + 'level' => '层级', + 'data' => '扩展', + 'image' => '图片', + 'description' => '描述', + 'content' => '内容', +]; diff --git a/lang/zh_CN/patient.php b/lang/zh_CN/patient.php new file mode 100644 index 0000000..612eb18 --- /dev/null +++ b/lang/zh_CN/patient.php @@ -0,0 +1,17 @@ + 'ID', + 'keyword' => '关键字', + 'name' => '姓名', + 'sex' => '性别', + 'phone' => '联系方式', + 'address' => '地址', + 'birthday' => '出生年月', + 'treat_at' => '初诊时间', + 'illness' => '病情描述', + 'doctor_id' => '坐诊医生', + 'age' => '年龄', + 'remarks' => '备注', + 'created_at' => '录入时间', +]; diff --git a/lang/zh_CN/patient_record.php b/lang/zh_CN/patient_record.php new file mode 100644 index 0000000..5b8f875 --- /dev/null +++ b/lang/zh_CN/patient_record.php @@ -0,0 +1,20 @@ + 'ID', + 'patient_id' => '姓名', + 'type_id' => '类别', + 'treat_at' => '诊疗时间', + 'doctor_id' => '就诊医生', + 'content' => '诊疗情况', + 'origin_price' => '划线价', + 'sell_price' => '实收价', + 'order_status' => '收费情况', + 'notify_at' => '通知时间', + 'notify_user_id' => '通知人', + 'notify_remarks' => '通知备注', + 'is_notified' => '是否已经通知', + 'next_treat_at' => '下次就诊时间', + 'creator_id' => '操作人', + 'created_at' => '录入时间', +];