1
0
Fork 0

patient.type_id

master
panliang 2023-10-09 15:35:41 +08:00
parent ea79dd81f1
commit b05fd0aa27
57 changed files with 695 additions and 164 deletions

View File

@ -5,7 +5,9 @@ namespace App\Admin\Controllers;
use App\Admin\Components;
use App\Admin\Services\KeywordService;
use App\Models\Keyword;
use App\Models\Patient;
use Illuminate\Http\Request;
use Slowlyo\OwlAdmin\Admin;
use Slowlyo\OwlAdmin\Controllers\AdminController;
use Slowlyo\OwlAdmin\Renderers\Form;
use Slowlyo\OwlAdmin\Renderers\Page;
@ -110,13 +112,23 @@ class CategoryController extends AdminController
public function getContent(Request $request)
{
$id = $request->input('id');
$info = Keyword::find($id);
$patient = Patient::findOrFail($id);
$info = $patient->type;
$content = data_get($info, 'content');
return $this->response()->success([
'content' => $content
]);
}
public function getPermissionList(Request $request)
{
$user = Admin::user();
$list = Keyword::where('parent_id', $this->getParentId())->filter(request()->all(), $this->service->getModelFilter())->sort()->get();
$list = $list->filter(fn($item) => $user->can($item->key));
return $this->response()->success(['items' => $list]);
}
protected function rowDeleteButton(): AjaxAction
{
return AjaxAction::make()

View File

@ -11,6 +11,7 @@ use Slowlyo\OwlAdmin\Renderers\Page;
use App\Models\{Keyword, Patient};
use Illuminate\Http\Request;
use Slowlyo\OwlAdmin\Services\AdminUserService;
use Slowlyo\OwlAdmin\Support\Excel\AdminExport;
/**
* 病人管理
@ -31,15 +32,20 @@ class PatientController extends AdminController
->headerToolbar([
$this->createButton(true, 'lg'),
amis('reload')->align('right'),
$this->exportAction(),
])
->filter($this->baseFilter()->actions()->body([
amisMake()->SelectControl()->options($this->getTypeOptions())->name('type_id')->label(__('patient.type_id'))->size('md')->clearable(),
amisMake()->TextControl()->name('keyword')->label(__('patient.keyword'))->placeholder(__('patient.name') . '/' . __('patient.phone'))->size('md')->clearable(),
amisMake()->SelectControl()->options($this->getAdminUserOptions())->searchable()->name('admin_user_id')->label(__('patient.admin_user_id'))->size('md')->clearable(),
amisMake()->SelectControl()->options($this->getAdminUserOptions())->searchable()->name('doctor_id')->label(__('patient.doctor_id'))->size('md')->clearable(),
amisMake()->SelectControl()->options($this->getAdminUserOptions())->searchable()->name('inviter_id')->label(__('patient.inviter_id'))->size('md')->clearable(),
amisMake()->SelectControl()->options($this->getAdminUserOptions())->searchable()->name('saler_id')->label(__('patient.saler_id'))->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('type.name')->label(__('patient.type_id')),
amisMake()->TableColumn()->name('name')->label(__('patient.name')),
amisMake()->TableColumn()->name('sex_text')->label(__('patient.sex')),
amisMake()->TableColumn()->name('phone')->label(__('patient.phone')),
@ -58,6 +64,7 @@ class PatientController extends AdminController
public function form(): Form
{
return $this->baseForm()->body([
amisMake()->SelectControl()->options($this->getTypeOptions())->name('type_id')->label(__('patient.type_id'))->required(),
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')),
@ -103,7 +110,7 @@ class PatientController extends AdminController
->level('warning')
->className('mr-1')
->actionType('dialog')
->dialog(amisMake()->Dialog()->size('lg')->title('修改基础信息')->body(
->dialog(amisMake()->Dialog()->size('lg')->title('添加病历记录')->body(
$record->form(false, $id)->api('post:' . admin_url('/record'))->onEvent([
'submitSucc' => [
'actions' => [
@ -179,4 +186,101 @@ class PatientController extends AdminController
return $this->adminUserOptions;
}
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;
$buttons = [
amisMake()->VanillaAction()->label(__('admin.export.all'))->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
)
),
];
return amisMake()
->DropdownButton()
->label(__('admin.export.title'))
->set('icon', 'fa-solid fa-download')
->buttons($buttons)
->align('right')
->closeOnClick();
}
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.id'),
__('patient.type_id'),
__('patient.name'),
__('patient.sex'),
__('patient.phone'),
__('patient.address'),
__('patient.birthday'),
__('patient.age'),
__('patient.treat_at'),
__('patient.doctor_id'),
__('patient.inviter_id'),
__('patient.saler_id'),
__('patient.created_at'),
];
}
protected function exportColumns($row)
{
return [
$row->id,
$row->type?->name,
$row->name,
$row->sex->text(),
$row->phone,
$row->address,
$row->birthday_format,
$row->age,
$row->treat_format,
$row->doctor?->name,
$row->inviter?->name,
$row->saler?->name,
$row->created_at,
];
}
}

View File

@ -3,7 +3,7 @@
namespace App\Admin\Controllers;
use App\Enums\OrderStatus;
use App\Models\{Keyword, Patient};
use App\Models\{Keyword, Patient, PatientRecord};
use App\Admin\Services\PatientRecordService;
use Slowlyo\OwlAdmin\Controllers\AdminController;
use Slowlyo\OwlAdmin\Renderers\Form;
@ -24,6 +24,8 @@ class PatientRecordController extends AdminController
protected $adminUserOptions;
protected $illnessOptions;
public function list(): Page
{
$crud = $this->baseCRUD()
@ -31,21 +33,25 @@ class PatientRecordController extends AdminController
->columnsTogglable(false)
->headerToolbar([
$this->createButton(true, 'lg'),
$this->exportAction(),
amis('reload')->align('right'),
$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('admin_user_id')->label(__('patient-record.admin_user_id'))->clearable()->size('md'),
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()->Mapping()->map($this->getTypeOptions()->pluck('label', 'value'))->name('type_id')->label(__('patient-record.type_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')),
@ -59,11 +65,12 @@ class PatientRecordController extends AdminController
->alwaysShowPagination()
->affixRowClassName('text-info-dk')
->affixRow([
['type' => 'text', 'text' => '总计: ${total}', 'colSpan' => 4],
['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' => ''],
]);
return $this->baseList($crud);
@ -71,19 +78,25 @@ class PatientRecordController extends AdminController
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();
$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)->static();
$patient_element->value($patient_id);
}
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()->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(),
@ -102,7 +115,7 @@ class PatientRecordController extends AdminController
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'))->value($this->user()->name)->readonly(),
amisMake()->TextControl()->label(__('patient-record.creator_id'))->name('creator_id')->value($this->user()->name)->readonly(),
]);
}
@ -173,6 +186,15 @@ class PatientRecordController extends AdminController
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]]]];
@ -238,6 +260,7 @@ class PatientRecordController extends AdminController
__('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'),
@ -259,6 +282,7 @@ class PatientRecordController extends AdminController
$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,

View File

@ -0,0 +1,53 @@
<?php
namespace App\Admin\Controllers;
use App\Admin\Services\TotalIllnessTypeService;
use App\Models\Keyword;
use App\Models\PatientRecord;
use Slowlyo\OwlAdmin\Controllers\AdminController;
/**
* 病种统计
*/
class TotalIllnessTypeController extends AdminController
{
protected string $serviceName = TotalIllnessTypeService::class;
protected $illness;
public function list()
{
$crud = $this->baseCRUD()
->filterTogglable(false)
->columnsTogglable(false)
->alwaysShowPagination()
->headerToolbar([])
->filter($this->baseFilter()->actions()->body([
amisMake()->SelectControl()->options($this->getIllness())->name('id')->label(__('total-illness-type.id'))->size('md')->clearable(),
amisMake()->DateRangeControl()->name('treat_range')->label(__('total-illness-type.treat_at'))->clearable()->size('md'),
// amisMake()->Button()->label(__('admin.reset'))->actionType('clear-and-submit'),
amisMake()->Component()->setType('submit')->label(__('admin.search'))->level('primary'),
]))
->columns([
amisMake()->Column()->name('name')->label(__('total-illness-type.id')),
amisMake()->Column()->name('count')->label(__('total-illness-type.count')),
])
->affixRowClassName('text-info-dk')
->affixRow([
['type' => 'text', 'text' => '总计: ${total}'],
['type' => 'text', 'text' => __('total-illness-type.count'). ': ${count}'],
]);
return $this->baseList($crud);
}
public function getIllness()
{
if (!$this->illness) {
$this->illness = Keyword::where('type_key', PatientRecord::ILLNESS_TYPE_KEY)->select(['id as value', 'name as label'])->get();
}
return $this->illness;
}
}

View File

@ -5,14 +5,14 @@ namespace App\Admin\Controllers;
use Slowlyo\OwlAdmin\Controllers\AdminController;
use App\Models\{Keyword, Patient, PatientRecord};
use Illuminate\Support\Facades\DB;
use App\Admin\Services\TotalRecordService;
use App\Admin\Services\TotalPatientService;
/**
* 财务统计
* 客户统计
*/
class TotalRecordController extends AdminController
class TotalPatientController extends AdminController
{
protected string $serviceName = TotalRecordService::class;
protected string $serviceName = TotalPatientService::class;
protected $patientOptions;
@ -23,29 +23,29 @@ class TotalRecordController extends AdminController
$crud = $this->baseCRUD()
->filterTogglable(false)
->columnsTogglable(false)
->alwaysShowPagination()
->headerToolbar([])
->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->getPatientOptions())->searchable()->name('id')->label(__('total-record.name'))->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(__('total-record.treat_at'))->clearable()->size('md'),
// amisMake()->Button()->label(__('admin.reset'))->actionType('clear-and-submit'),
amisMake()->Component()->setType('submit')->label(__('admin.search'))->level('primary'),
]))
->columns([
amisMake()->Column()->name('patient.name')->label(__('total-record.name')),
amisMake()->Mapping()->map($this->getTypeOptions()->pluck('label', 'value'))->name('type_id')->label(__('patient-record.type_id')),
amisMake()->Date()->name('min_treat_at')->label(__('total-record.min_treat_at'))->sortable(true),
amisMake()->Date()->name('max_treat_at')->label(__('total-record.max_treat_at'))->sortable(true),
amisMake()->Column()->name('count')->label(__('total-record.count'))->sortable(true),
amisMake()->Column()->name('sell_price')->label(__('total-record.sell_price'))->sortable(true),
amisMake()->Column()->name('name')->label(__('total-record.name')),
amisMake()->Column()->name('type.name')->label(__('total-record.type_id')),
amisMake()->Column()->name('records_count')->label(__('total-record.records_count')),
amisMake()->Column()->name('origin_price')->label(__('total-record.origin_price')),
amisMake()->Column()->name('sell_price')->label(__('total-record.sell_price')),
])
->affixRowClassName('text-info-dk')
->affixRow([
['type' => 'text', 'text' => '总计: ${total}', 'colSpan' => 4],
['type' => 'text', 'text' => '看病次数: ${count}'],
['type' => 'text', 'text' => '总计: ${total}', 'colSpan' => 2],
['type' => 'text', 'text' => __('total-record.records_count').': ${records_count}'],
['type' => 'text', 'text' => __('total-record.origin_price') . ': ${origin_price}'],
['type' => 'text', 'text' => __('total-record.sell_price') . ': ${sell_price}'],
])
->alwaysShowPagination();
]);
return $this->baseList($crud);
}

View File

@ -0,0 +1,71 @@
<?php
namespace App\Admin\Controllers;
use App\Admin\Services\TotalProfitService;
use App\Models\Keyword;
use Slowlyo\OwlAdmin\Controllers\AdminController;
use Slowlyo\OwlAdmin\Services\AdminUserService;
/**
* 提成统计
*/
class TotalProfitController extends AdminController
{
protected string $serviceName = TotalProfitService::class;
protected $adminUserOptions;
protected $typeOptions;
public function list()
{
$crud = $this->baseCRUD()
->filterTogglable(false)
->columnsTogglable(false)
->alwaysShowPagination()
->headerToolbar([])
->filter($this->baseFilter()->actions()->body([
amisMake()->SelectControl()->options($this->getAdminUserOptions())->searchable()->name('id')->label(__('total-profit.id'))->clearable()->size('md'),
amisMake()->SelectControl()->options($this->getTypeOptions())->name('type_id')->label(__('total-profit.type_id'))->size('md')->clearable(),
amisMake()->DateRangeControl()->name('treat_range')->label(__('total-record.treat_at'))->clearable()->size('md'),
// amisMake()->Button()->label(__('admin.reset'))->actionType('clear-and-submit'),
amisMake()->Component()->setType('submit')->label(__('admin.search'))->level('primary'),
]))
->columns([
amisMake()->Column()->name('name')->label(__('total-profit.id')),
amisMake()->Column()->name('records_count')->label(__('total-profit.records_count')),
amisMake()->Column()->name('doctor_money')->label(__('total-profit.doctor_money')),
amisMake()->Column()->name('inviter_money')->label(__('total-profit.inviter_money')),
amisMake()->Column()->name('saler_money')->label(__('total-profit.saler_money')),
])
->affixRowClassName('text-info-dk')
->affixRow([
['type' => 'text', 'text' => '总计: ${total}'],
['type' => 'text', 'text' => __('total-profit.records_count'). ': ${records_count}'],
['type' => 'text', 'text' => __('total-profit.doctor_money'). ': ${doctor_money}'],
['type' => 'text', 'text' => __('total-profit.inviter_money'). ': ${inviter_money}'],
['type' => 'text', 'text' => __('total-profit.saler_money'). ': ${saler_money}'],
]);
return $this->baseList($crud);
}
public function getAdminUserOptions()
{
if (!$this->adminUserOptions) {
$this->adminUserOptions = AdminUserService::make()->query()->select(['id as value', 'name as label'])->get();
}
return $this->adminUserOptions;
}
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;
}
}

View File

@ -71,7 +71,9 @@ class BaseService extends AdminService
return false;
}
$this->modelName::create($data);
$model = $this->modelName::create($data);
$this->afterCreate($model);
return true;
}
@ -134,4 +136,15 @@ class BaseService extends AdminService
{
return true;
}
/**
* 数据创建成功
*
* @param $model
* @return void
*/
public function afterCreate($model)
{
}
}

View File

@ -6,6 +6,7 @@ use App\ModelFilters\KeywordFilter;
use App\Models\Keyword;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Slowlyo\OwlAdmin\Models\AdminPermission;
/**
* @method Keyword getModel()
@ -46,6 +47,9 @@ class KeywordService extends BaseService
}
})->delete();
// 删除对应权限
AdminPermission::where('slug', Keyword::whereIn('id', $ids)->pluck('key'))->delete();
return true;
}
@ -56,9 +60,9 @@ class KeywordService extends BaseService
'name' => ['required'],
];
$updateRules = [
'key' => [Rule::unique('keywords', 'key')->ignore($id)]
'key' => [Rule::unique('keywords', 'key')->ignore(data_get($model, 'id'))]
];
$validator = Validator::make($data, $id ? $updateRules : $createRules, [
$validator = Validator::make($data, $model ? $updateRules : $createRules, [
'key.unique' => ':input 已经存在'
]);
if ($validator->fails()) {
@ -84,4 +88,16 @@ class KeywordService extends BaseService
}
return $data;
}
public function afterCreate($model)
{
// 创建对应的权限
AdminPermission::updateOrCreate([
'slug' => $model->key,
], [
'name' => $model->name,
'parent_id' => 0,
'order' => 1
]);
}
}

View File

@ -14,7 +14,7 @@ class PatientRecordService extends BaseService
{
protected string $modelName = PatientRecord::class;
protected array $withRelationships = ['doctor', 'patient', 'type', 'creator', 'notifyUser', 'inviter', 'saler'];
protected array $withRelationships = ['doctor', 'patient', 'type', 'creator', 'notifyUser', 'inviter', 'saler', 'illnessType'];
protected string $modelFilterName = PatientRecordFilter::class;
@ -41,26 +41,25 @@ class PatientRecordService extends BaseService
$list = $query->clone()->paginate(request()->input('perPage', 20));
$items = $list->items();
$total = $list->total();
$sell_price = floatval($query->clone()->sum('sell_price'));
$doctor_money = floatval($query->clone()->sum('doctor_money'));
$inviter_money = floatval($query->clone()->sum('inviter_money'));
$saler_money = floatval($query->clone()->sum('saler_money'));
$sell_price = round($query->clone()->sum('sell_price'), 2, PHP_ROUND_HALF_DOWN);
$doctor_money = round($query->clone()->sum('doctor_money'), 2, PHP_ROUND_HALF_DOWN);
$inviter_money = round($query->clone()->sum('inviter_money'), 2, PHP_ROUND_HALF_DOWN);
$saler_money = round($query->clone()->sum('saler_money'), 2, PHP_ROUND_HALF_DOWN);
return compact('items', 'total', 'sell_price', 'doctor_money', 'inviter_money', 'saler_money');
}
public function resloveData($data, $model = null)
{
$creator_id = data_get($data, 'creator_id');
if (!$creator_id) {
$data['creator_id'] = data_get(Admin::user(), 'id');
}
if ($images = data_get($data, 'images')) {
$data['images'] = is_array($images) ? $images : explode(',', $images);
}
if (!$model) {
$data['is_notified'] = data_get($data, 'is_notified', 1);
$data['creator_id'] = Admin::user()->id;
$patient = Patient::findOrFail(data_get($data, 'patient_id'));
$type = Keyword::findOrFail(data_get($data, 'type_id'));
$type = $patient->type;
$data['type_id'] = $patient->type_id;
$data['saler_id'] = $patient->saler_id;
$data['inviter_id'] = $patient->inviter_id;
if (data_get($data, 'doctor_id')) {
@ -90,15 +89,15 @@ class PatientRecordService extends BaseService
{
$createRules = [
'patient_id' => 'required',
'type_id' => 'required',
'illness_type_id' => 'required',
'treat_at' => 'required',
'doctor_id' => 'required',
'origin_price' => ['required', 'decimal:0,2'],
'sell_price' => ['required', 'decimal:0,2'],
'order_status' => 'required',
'next_treat_at' => [Rule::requiredIf(fn () => request('is_notified') == 0)],
'notify_at' => [Rule::requiredIf(fn () => request('is_notified') == 0)],
'notify_user_id' => [Rule::requiredIf(fn () => request('is_notified') == 0)],
'next_treat_at' => [Rule::requiredIf(fn () => data_get($data, 'is_notified') == 0)],
'notify_at' => [Rule::requiredIf(fn () => data_get($data, 'is_notified') == 0)],
'notify_user_id' => [Rule::requiredIf(fn () => data_get($data, 'is_notified') == 0)],
];
$updateRules = [
'origin_price' => 'decimal:0,2',
@ -106,7 +105,6 @@ class PatientRecordService extends BaseService
];
$validator = Validator::make($data, $model ? $updateRules : $createRules, [
'patient_id.required' => '请选择病人',
'type_id.required' => '请选择诊疗类型',
'treat_at.required' => '请选择诊疗时间',
'origin_price.required' => __('patient-record.origin_price') . '必填',
'origin_price.decimal' => __('patient-record.origin_price') . '保留2位小数',
@ -115,6 +113,7 @@ class PatientRecordService extends BaseService
'notify_at.required' => __('patient-record.notify_at') . '必填',
'notify_user_id.required' => __('patient-record.notify_user_id') . '必填',
'next_treat_at.required' => __('patient-record.next_treat_at') . '必填',
'illness_type_id.required' => __('patient-record.illness_type_id') . '必填',
]);
if ($validator->fails()) {
return $validator->errors()->first();

View File

@ -10,7 +10,7 @@ class PatientService extends BaseService
{
protected string $modelName = Patient::class;
protected array $withRelationships = ['doctor', 'inviter', 'saler'];
protected array $withRelationships = ['doctor', 'inviter', 'saler', 'type'];
protected string $modelFilterName = PatientFilter::class;

View File

@ -0,0 +1,50 @@
<?php
namespace App\Admin\Services;
use App\ModelFilters\KeywordFilter;
use App\Models\Keyword;
use App\Models\PatientRecord;
class TotalIllnessTypeService extends BaseService
{
protected string $modelName = Keyword::class;
protected array $withRelationships = [];
protected string $modelFilterName = KeywordFilter::class;
public function listQuery()
{
$filter = $this->getModelFilter();
$query = $this->query()->where('type_key', PatientRecord::ILLNESS_TYPE_KEY);
if ($this->withRelationships) {
$query->with($this->withRelationships);
}
if ($filter) {
$query->filter(request()->only(['id']), $filter);
}
$subQuery = fn ($q) => $q->filter(request()->except(['id']));
$query->select(['id', 'name'])->with(['illnessTypeRecords' => $subQuery]);
return $query;
}
public function list()
{
$query = $this->listQuery();
$list = (clone $query)->paginate(request()->input('perPage', 20));
$items = collect($list->items())->map(function ($item) {
$item['count'] = $item->illnessTypeRecords->count();
return $item;
});
$allList = (clone $query)->get();
$count = round($allList->sum(fn ($item) => $item->illnessTypeRecords->count()), 2, PHP_ROUND_HALF_DOWN);;
$total = $list->total();
$this->sortable($query);
return compact('items', 'total', 'count');
}
}

View File

@ -0,0 +1,60 @@
<?php
namespace App\Admin\Services;
use App\ModelFilters\PatientFilter;
use App\Models\Patient;
use App\Models\PatientRecord;
class TotalPatientService extends BaseService
{
protected string $modelName = Patient::class;
protected array $withRelationships = ['type'];
protected string $modelFilterName = PatientFilter::class;
public function getModelFilter()
{
return $this->modelFilterName;
}
public function listQuery()
{
$filter = $this->getModelFilter();
$query = $this->query();
if ($this->withRelationships) {
$query->with($this->withRelationships);
}
if ($filter) {
$query->filter(request()->only(['id', 'type_id']), $filter);
}
$subQuery = fn($q) => $q->filter(request()->only(['treat_range', 'type_id']));
$query->select(['id', 'name', 'type_id'])->with(['records' => $subQuery]);
return $query;
}
public function list()
{
$query = $this->listQuery();
$list = (clone $query)->paginate(request()->input('perPage', 20));
$items = collect($list->items())->map(function ($item) {
$item['sell_price'] = round($item->records->sum('sell_price'), 2, PHP_ROUND_HALF_DOWN);
$item['origin_price'] = round($item->records->sum('origin_price'), 2, PHP_ROUND_HALF_DOWN);
$item['records_count'] = $item->records->count();
return $item;
});
$allList = (clone $query)->get();
$records_count = round($allList->sum(fn($item) => $item->records->count()), 2, PHP_ROUND_HALF_DOWN);
$origin_price = round($allList->sum(fn($item) => $item->records->sum('origin_price')), 2, PHP_ROUND_HALF_DOWN);
$sell_price = round($allList->sum(fn($item) => $item->records->sum('sell_price')), 2, PHP_ROUND_HALF_DOWN);
$total = $list->total();
return compact('items', 'total', 'sell_price', 'origin_price', 'records_count');
}
}

View File

@ -0,0 +1,64 @@
<?php
namespace App\Admin\Services;
use App\Models\AdminUser;
class TotalProfitService extends BaseService
{
protected string $modelName = AdminUser::class;
protected array $withRelationships = [];
protected string $modelFilterName = '';
public function listQuery()
{
$filter = $this->getModelFilter();
$query = $this->query();
if ($this->withRelationships) {
$query->with($this->withRelationships);
}
if ($filter) {
$query->filter(request()->input(), $filter);
}
$request = request();
if ($request->filled('id')) {
$query->where('id', $request->input('id'));
}
$subQuery = fn ($q) => $q->filter(request()->except(['id']));
$query->select(['id', 'name'])->with([
'doctors' => $subQuery,
'inviters' => $subQuery,
'salers' => $subQuery
]);
return $query;
}
public function list()
{
$query = $this->listQuery();
$list = (clone $query)->paginate(request()->input('perPage', 20));
$items = collect($list->items())->map(function ($item) {
$item['doctor_money'] = round($item->doctors->sum('doctor_money'), 2, PHP_ROUND_HALF_DOWN);
$item['inviter_money'] = round($item->inviters->sum('inviter_money'), 2, PHP_ROUND_HALF_DOWN);
$item['saler_money'] = round($item->salers->sum('saler_money'), 2, PHP_ROUND_HALF_DOWN);
$item['records_count'] = floor($item->doctors->count() + $item->inviters->count() + $item->salers->count());
return $item;
});
$allList = (clone $query)->get();
$records_count = $allList->sum(fn ($item) => $item->doctors->count() + $item->inviters->count() + $item->salers->count());
$doctor_money = round($allList->sum(fn ($item) => $item->doctors->sum('doctor_money')), 2, PHP_ROUND_HALF_DOWN);
$inviter_money = round($allList->sum(fn ($item) => $item->inviters->sum('inviter_money')), 2, PHP_ROUND_HALF_DOWN);
$saler_money = round($allList->sum(fn ($item) => $item->salers->sum('saler_money')), 2, PHP_ROUND_HALF_DOWN);
$total = $list->total();
$this->sortable($query);
return compact('items', 'total', 'records_count', 'doctor_money', 'inviter_money', 'saler_money');
}
}

View File

@ -1,71 +0,0 @@
<?php
namespace App\Admin\Services;
use App\Models\PatientRecord;
use App\ModelFilters\PatientRecordFilter;
use Illuminate\Support\Facades\DB;
class TotalRecordService extends BaseService
{
protected string $modelName = PatientRecord::class;
protected array $withRelationships = ['patient'];
protected string $modelFilterName = PatientRecordFilter::class;
public function getModelFilter()
{
return $this->modelFilterName;
}
public function primaryKey()
{
return 'patient_id';
}
public function sortColumn()
{
return 'patient_id';
}
public function listQuery()
{
$filter = $this->getModelFilter();
$query = $this->query();
if ($this->withRelationships) {
$query->with($this->withRelationships);
}
if ($filter) {
$query->filter(request()->input(), $filter);
}
$query->select([
'patient_id',
'type_id',
DB::raw('count(1) as count'),
DB::raw('sum(`sell_price`) as `sell_price`'),
DB::raw('min(`treat_at`) as `min_treat_at`'),
DB::raw('max(`treat_at`) as `max_treat_at`'),
])->groupBy('patient_id', 'type_id');
$this->sortable($query);
return $query;
}
public function list()
{
$query = $this->listQuery();
$list = (clone $query)->paginate(request()->input('perPage', 20));
$items = $list->items();
$total = $list->total();
$count = floatval((new PatientRecordService())->listQuery()->count());
$sell_price = floatval((new PatientRecordService())->listQuery()->sum('sell_price'));
return compact('items', 'total', 'sell_price', 'count');
}
}

View File

@ -31,6 +31,7 @@ Route::group([
$router->get('keywords/list', '\App\Admin\Controllers\KeywordsController@getList')->name('api.keywords.get_list');
$router->get('category/content', '\App\Admin\Controllers\CategoryController@getContent')->name('api.category.content');
$router->get('patient/options', '\App\Admin\Controllers\PatientController@getSelectOptions')->name('api.patient.options');
$router->get('category/permission-list', '\App\Admin\Controllers\CategoryController@getPermissionList')->name('api.category.permission_list');
});
// 字典表
@ -43,5 +44,9 @@ Route::group([
$router->resource('record', \App\Admin\Controllers\PatientRecordController::class)->names('admin.patient_record');
// 财务统计
$router->get('total/record', [\App\Admin\Controllers\TotalRecordController::class, 'index']);
$router->get('total/record', [\App\Admin\Controllers\TotalPatientController::class, 'index']);
// 提成统计
$router->get('total/profit', [\App\Admin\Controllers\TotalProfitController::class, 'index']);
// 病种统计
$router->get('total/illness-type', [\App\Admin\Controllers\TotalIllnessTypeController::class, 'index']);
});

View File

@ -15,6 +15,11 @@ class KeywordFilter extends ModelFilter
*/
public $relations = [];
public function id($key)
{
$this->whereIn('id', is_array($key) ? $key : explode(',', $key));
}
public function parent($id)
{
$this->where('parent_id', $id);

View File

@ -14,6 +14,11 @@ class PatientFilter extends ModelFilter
*/
public $relations = [];
public function id($key)
{
$this->whereIn('id', is_array($key) ? $key : explode(',', $key));
}
public function keyword($key)
{
$this->where(fn ($q) => $q->where('name', 'like', '%'.$key.'%')->orWhere('phone', 'like', '%'.$key.'%'));
@ -23,4 +28,22 @@ class PatientFilter extends ModelFilter
{
$this->where(fn($q) => $q->where('doctor_id', $key)->orWhere('inviter_id', $key)->orWhere('saler_id', $key));
}
public function inviter($key)
{
$this->where('inviter_id', $key);
}
public function doctor($key)
{
$this->where('doctor_id', $key);
}
public function saler($key)
{
$this->where('saler_id', $key);
}
public function type($key)
{
$this->where('type_id', $key);
}
}

View File

@ -29,6 +29,18 @@ class PatientRecordFilter extends ModelFilter
{
$this->where('doctor_id', $key);
}
public function inviter($key)
{
$this->where('inviter_id', $key);
}
public function saler($key)
{
$this->where('saler_id', $key);
}
public function illnessType($key)
{
$this->where('illness_type_id', $key);
}
public function treatRange($key)
{

View File

@ -0,0 +1,22 @@
<?php
namespace App\Models;
use Slowlyo\OwlAdmin\Models\AdminUser as Base;
use Illuminate\Database\Eloquent\Model;
class AdminUser extends Model
{
public function doctors()
{
return $this->hasMany(PatientRecord::class, 'doctor_id');
}
public function inviters()
{
return $this->hasMany(PatientRecord::class, 'inviter_id');
}
public function salers()
{
return $this->hasMany(PatientRecord::class, 'saler_id');
}
}

View File

@ -31,6 +31,11 @@ class Keyword extends Model
return $this->hasMany(static::class, 'parent_id');
}
public function illnessTypeRecords()
{
return $this->hasMany(PatientRecord::class, 'illness_type_id');
}
public function scopeSort($q)
{
return $q->orderByDesc('sort');

View File

@ -16,7 +16,11 @@ class Patient extends Model
{
use HasDateTimeFormatter, Filterable;
protected $fillable = ['name', 'sex', 'phone', 'address', 'birthday', 'treat_at', 'illness', 'doctor_id', 'remarks', 'images', 'inviter_id', 'saler_id'];
protected $fillable = [
'name', 'sex', 'phone', 'address', 'birthday',
'treat_at', 'illness', 'remarks', 'images',
'doctor_id', 'inviter_id', 'saler_id', 'type_id',
];
protected $appends = ['age', 'sex_text', 'treat_format', 'birthday_format'];
@ -70,6 +74,16 @@ class Patient extends Model
return $this->belongsTo(AdminUser::class, 'saler_id');
}
public function type()
{
return $this->belongsTo(Keyword::class, 'type_id');
}
public function records()
{
return $this->hasMany(PatientRecord::class, 'patient_id');
}
public function scopeSort($q)
{
return $q->orderBy('id', 'desc');

View File

@ -16,8 +16,10 @@ class PatientRecord extends Model
{
use HasDateTimeFormatter, Filterable;
const ILLNESS_TYPE_KEY = 'illness_type';
protected $fillable = [
'patient_id', 'type_id',
'patient_id', 'type_id', 'illness_type_id',
'treat_at', 'content', 'images',
'doctor_id', 'doctor_ratio', 'doctor_money',
'saler_id', 'saler_ratio', 'saler_money',
@ -74,6 +76,11 @@ class PatientRecord extends Model
return $this->belongsTo(AdminUser::class, 'creator_id');
}
public function illnessType()
{
return $this->belongsTo(Keyword::class, 'illness_type_id');
}
public function scopeSort($q)
{
return $q->orderBy('treat_at', 'desc');

View File

@ -2,7 +2,6 @@
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

View File

@ -37,7 +37,8 @@ return [
'controller' => \Slowlyo\OwlAdmin\Controllers\AuthController::class,
'guard' => 'sanctum',
'except' => [
'system/admin_users'
'system/admin_users',
'api/*'
],
],

View File

@ -2,6 +2,7 @@
namespace Database\Factories;
use App\Models\Keyword;
use Illuminate\Database\Eloquent\Factories\Factory;
use App\Models\Patient;
use App\Enums\Gender;
@ -23,6 +24,7 @@ class PatientFactory extends Factory
{
$faker = $this->faker;
return [
'type_id' => Keyword::where('type_key', 'treat_type')->inRandomOrder()->value('id'),
'name' => $faker->name,
'sex' => $faker->randomElement(array_keys(Gender::map())),
'phone' => $faker->phoneNumber,

View File

@ -24,13 +24,14 @@ class PatientRecordFactory extends Factory
$faker = $this->faker;
$sell_price = $faker->numberBetween(100, 200);
$patient = Patient::inRandomOrder()->first();
$type = Keyword::where('type_key', 'treat_type')->inRandomOrder()->first();
$type = $patient->type;
$doctor_ratio = data_get($type->options, 'doctor_ratio', 0);
$inviter_ratio = data_get($type->options, 'inviter_ratio', 0);
$saler_ratio = data_get($type->options, 'saler_ratio', 0);
return [
'patient_id' => $patient->id,
'type_id' => $type->id,
'illness_type_id' => Keyword::where('type_key', PatientRecord::ILLNESS_TYPE_KEY)->inRandomOrder()->value('id'),
'treat_at' => $faker->dateTimeBetween('-7 days'),
'doctor_id' => AdminUser::inRandomOrder()->value('id'),
'doctor_ratio' => $doctor_ratio,

View File

@ -15,6 +15,7 @@ return new class extends Migration
Schema::create('patients', function (Blueprint $table) {
$table->id();
$table->string('name')->comment('姓名');
$table->unsignedBigInteger('type_id')->comment('类别, keywords.id');
$table->string('sex')->default(Gender::None->value)->comment('性别');
$table->string('phone')->nullable()->comment('联系方式');
$table->string('address')->nullable()->comment('地址');

View File

@ -15,6 +15,7 @@ return new class extends Migration
$table->id();
$table->unsignedBigInteger('patient_id')->comment('病人, patients.id');
$table->unsignedBigInteger('type_id')->comment('类别, keywords.id');
$table->unsignedBigInteger('illness_type_id')->comment('病种, keywords.id');
$table->timestamp('treat_at')->comment('就诊时间');
$table->text('content')->comment('就诊情况');
$table->json('images')->nullable()->comment('图片');

View File

@ -18,18 +18,20 @@ class AdminMenuSeeder extends Seeder
{
// 图标: https://iconpark.oceanengine.com/official
$menus = [
['title' => '主页', 'icon' => 'icon-park:home-two', 'url' => '/dashboard', 'is_home' => 1, 'order' => 1],
['title' => '分类管理', 'icon' => 'icon-park:all-application', 'url' => '/category', 'order' => 2],
['title' => '病人管理', 'icon' => 'icon-park:peoples-two', 'url' => '/patient', 'order' => 3],
['title' => '病历管理', 'icon' => 'icon-park:newspaper-folding', 'url' => '/record', 'order' => 4],
['title' => '财务统计', 'icon' => 'icon-park:data-file', 'url' => '/total/record', 'order' => 5],
['title' => '系统管理', 'icon' => 'icon-park:setting', 'url' => '/system', 'order' => 6, 'children' => [
['title' => '用户管理', 'icon' => 'icon-park:people-plus', 'url' => '/system/admin_users', 'order' => 1],
['title' => '角色管理', 'icon' => 'icon-park:people-plus-one', 'url' => '/system/admin_roles', 'order' => 2],
['title' => '权限管理', 'icon' => 'icon-park:key-one', 'url' => '/system/admin_permissions', 'order' => 3],
['title' => '菜单管理', 'icon' => 'icon-park:menu-fold-one', 'url' => '/system/admin_menus', 'order' => 4],
['title' => '字典管理', 'icon' => 'icon-park:arrow-keys', 'url' => '/keywords', 'order' => 5],
['title' => '配置管理', 'icon' => 'icon-park:setting-two', 'url' => '/system/settings', 'order' => 6],
['title' => '主页', 'icon' => 'icon-park:home-two', 'url' => '/dashboard', 'is_home' => 1],
['title' => '分类管理', 'icon' => 'icon-park:all-application', 'url' => '/category'],
['title' => '病人管理', 'icon' => 'icon-park:peoples-two', 'url' => '/patient'],
['title' => '病历管理', 'icon' => 'icon-park:newspaper-folding', 'url' => '/record'],
['title' => '客户统计', 'icon' => 'icon-park:user-positioning', 'url' => '/total/record'],
['title' => '提成统计', 'icon' => 'icon-park:workbench', 'url' => '/total/profit'],
['title' => '病种统计', 'icon' => 'icon-park:pills', 'url' => '/total/illness-type'],
['title' => '系统管理', 'icon' => 'icon-park:setting', 'url' => '/system', 'children' => [
['title' => '用户管理', 'icon' => 'icon-park:people-plus', 'url' => '/system/admin_users'],
['title' => '角色管理', 'icon' => 'icon-park:people-plus-one', 'url' => '/system/admin_roles'],
['title' => '权限管理', 'icon' => 'icon-park:key-one', 'url' => '/system/admin_permissions'],
['title' => '菜单管理', 'icon' => 'icon-park:menu-fold-one', 'url' => '/system/admin_menus'],
['title' => '字典管理', 'icon' => 'icon-park:arrow-keys', 'url' => '/keywords'],
['title' => '配置管理', 'icon' => 'icon-park:setting-two', 'url' => '/system/settings'],
]],
];
DB::table('admin_menus')->truncate();
@ -45,7 +47,7 @@ class AdminMenuSeeder extends Seeder
public function createMenus(array $menus, $pid = 0)
{
foreach ($menus as $menu) {
foreach ($menus as $index => $menu) {
$mm = AdminMenu::create([
'title' => $menu['title'],
'icon' => $menu['icon'],
@ -54,7 +56,7 @@ class AdminMenuSeeder extends Seeder
'url_type' => $menu['url_type'] ?? 1,
'visible' => $menu['visible'] ?? 1,
'is_home' => $menu['is_home'] ?? 0,
'order' => $menu['order'] ?? 0,
'order' => $index + 1,
]);
if (isset($menu['children'])) {

View File

@ -2,6 +2,7 @@
namespace Database\Seeders;
use App\Admin\Services\KeywordService;
use App\Models\Keyword;
use Illuminate\Database\Seeder;
use Illuminate\Support\Arr;
@ -18,19 +19,29 @@ class KeywordSeeder extends Seeder
Keyword::truncate();
$list = [
['key' => 'treat_type', 'name' => '诊疗类别', 'children' => [
['key' => 'treat_head', 'name' => '头疗', 'content' => '按摩意见:', 'data' => [
['key' => 'treat_head', 'name' => '头疗', 'content' => '按摩意见:', 'options' => [
'doctor_ratio' => 10,
'inviter_ratio' => 9,
'saler_ratio' => 8
]],
['key' => 'treat_normal', 'name' => '看病', 'content' => '病症:', 'options' => [
'doctor_ratio' => 10,
'inviter_ratio' => 10,
'saler_ratio' => 10
]],
['key' => 'treat_normal', 'name' => '看病', 'content' => '病症:', 'data' => [
'doctor_ratio' => 10,
'inviter_ratio' => 10,
'saler_ratio' => 10
]],
]]
]],
['key' => 'illness_type', 'name' => '病种', 'children' => [
['name' => '糖尿病'],
['name' => '高血压'],
['name' => '腰间盘突出'],
]]
];
$this->createByTree($list);
// 添加类别权限
$service = (new KeywordService());
foreach (Keyword::where('type_key', 'treat_type')->get() as $item) {
$service->afterCreate($item);
}
}
protected function createByTree($list, $parent = null)

View File

@ -27,4 +27,5 @@ return [
'creator_id' => '操作人',
'created_at' => '录入时间',
'images' => '图片资料',
'illness_type_id' => '病种',
];

View File

@ -3,6 +3,7 @@
return [
'id' => 'ID',
'keyword' => '关键字',
'type_id' => '类别',
'name' => '姓名',
'sex' => '性别',
'phone' => '联系方式',
@ -10,7 +11,7 @@ return [
'birthday' => '出生年月',
'treat_at' => '初诊时间',
'illness' => '病情描述',
'doctor_id' => '诊医生',
'doctor_id' => '诊医生',
'saler_id' => '业务员',
'inviter_id' => '推荐人',
'admin_user_id' => '相关人员',

View File

@ -0,0 +1,8 @@
<?php
return [
'id' => '病种',
'name' => '病种',
'count' => '次数',
'treat_at' => '时间段',
];

View File

@ -0,0 +1,13 @@
<?php
return [
'id' => '提成人',
'name' => '姓名',
'type_id' => '类别',
'records_count' => '次数',
'doctor_money' => '医生提成',
'inviter_money' => '推荐人提成',
'saler_money' => '业务员提成',
'total_money' => '总提成',
'treat_at' => '时间段',
];

View File

@ -2,10 +2,11 @@
return [
'name' => '姓名',
'type_id' => '类别',
'treat_at' => '时间段',
'min_treat_at' => '开始时间',
'max_treat_at' => '结束时间',
'count' => '看病次数',
'origin_price' => '划',
'records_count' => '次数',
'origin_price' => '划线',
'sell_price' => '实收',
];

View File

@ -1,2 +1,2 @@
<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>宝芝堂</title><script>var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))
document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />')</script><link rel="stylesheet" href="/h5/static/index.5841170f.css"/><script defer="defer" src="/h5/static/js/chunk-vendors.7eabb1da.js"></script><script defer="defer" src="/h5/static/js/index.97494fcd.js"></script></head><body><noscript><strong>Please enable JavaScript to continue.</strong></noscript><div id="app"></div></body></html>
document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />')</script><link rel="stylesheet" href="/h5/static/index.5841170f.css"/><script defer="defer" src="/h5/static/js/chunk-vendors.7eabb1da.js"></script><script defer="defer" src="/h5/static/js/index.2acbe9ee.js"></script></head><body><noscript><strong>Please enable JavaScript to continue.</strong></noscript><div id="app"></div></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
(self["webpackChunkuniapp"]=self["webpackChunkuniapp"]||[]).push([[225],{1230:function(t,i,e){var n=e(811);n.__esModule&&(n=n.default),"string"===typeof n&&(n=[[t.id,n,""]]),n.locals&&(t.exports=n.locals);var o=e(5472).Z;o("3ba7bdf7",n,!0,{sourceMap:!1,shadowMode:!1})},4605:function(t,i,e){"use strict";e.r(i),e.d(i,{default:function(){return r}});var n,o={uSearch:e(8035).Z,uButton:e(7344).Z,uList:e(4307).Z,uSwipeAction:e(3309).Z,uListItem:e(8556).Z,uSwipeActionItem:e(8268).Z,uCell:e(7981).Z,uActionSheet:e(7030).Z},a=function(){var t=this,i=t.$createElement,e=t._self._c||i;return e("v-uni-view",{staticClass:"page"},[e("u-search",{attrs:{bgColor:"white",showAction:!1,margin:"10px 0",placeholder:"姓名/联系方式"},on:{search:function(i){arguments[0]=i=t.$handleEvent(i),t.loadData(!0)},change:function(i){arguments[0]=i=t.$handleEvent(i),t.changeSearch.apply(void 0,arguments)}},model:{value:t.search,callback:function(i){t.search=i},expression:"search"}}),e("v-uni-view",{staticClass:"add-button"},[e("u-button",{attrs:{type:"primary",icon:"plus",shape:"circle",size:"large"},on:{click:function(i){arguments[0]=i=t.$handleEvent(i),t.add.apply(void 0,arguments)}}})],1),e("u-list",{staticClass:"list",on:{scrolltolower:function(i){arguments[0]=i=t.$handleEvent(i),t.reachBottom.apply(void 0,arguments)}}},[e("u-swipe-action",t._l(t.list,(function(i,n){return e("u-list-item",{key:i.id},[e("u-swipe-action-item",{attrs:{options:t.swipeOption,name:n},on:{click:function(i){arguments[0]=i=t.$handleEvent(i),t.swipeClick.apply(void 0,arguments)}}},[e("u-cell",{attrs:{title:i.name+(""!=i.age?"("+i.age+")":""),label:i.phone?i.phone:"暂无联系方式",clickable:!0,isLink:!1,url:"/pages/patient/detail?id="+i.id}})],1)],1)})),1)],1),e("u-action-sheet",{attrs:{actions:t.option.list,title:t.option.title,show:t.option.show,closeOnClickOverlay:!0},on:{close:function(i){arguments[0]=i=t.$handleEvent(i),t.closeOption.apply(void 0,arguments)},select:function(i){arguments[0]=i=t.$handleEvent(i),t.chooseOption.apply(void 0,arguments)}}})],1)},c=[],s=(e(423),e(101),e(6228),{data:function(){return{typeId:"",list:[],page:1,perPage:20,total:0,search:"",option:{id:"",show:!1,list:[{name:"详细",color:"#4cd964",action:"detail"},{name:"修改",color:"#007aff",action:"edit"},{name:"添加病历",color:"#f0ad4e",action:"record-add"},{name:"查看病历",color:"#4cd964",action:"record"},{name:"删除",color:"#dd524d",action:"delete"}],title:""},swipeOption:[{text:"删除",style:{backgroundColor:"#dd524d"}}]}},onLoad:function(){this.typeId=uni.getStorageSync("medical_record_treat_type_id")},onShow:function(){this.loadData(!0)},onPullDownRefresh:function(){this.loadData(!0)},methods:{loadData:function(t){var i=this;t&&(this.list=[],this.page=1),uni.showLoading();var e={_action:"getData",page:this.page,perPage:this.perPage,keyword:this.search,type_id:this.typeId};this.$ajax.get("/admin-api/patient",{params:e}).then((function(t){uni.stopPullDownRefresh(),0==t.status&&(i.list=i.list.concat(t.data.items),i.total=t.data.total)})).catch((function(t){uni.stopPullDownRefresh()}))},reachBottom:function(){this.list.length<this.total&&(this.page++,this.loadData())},changeSearch:function(t){t||this.loadData(!0)},add:function(){uni.navigateTo({url:"/pages/patient/form"})},openOption:function(t){var i=this.list[t];this.option.title=i.name,this.option.id=i.id,this.option.show=!0},closeOption:function(){this.option.show=!1},chooseOption:function(t){var i=this,e=this.option.id;return"detail"==t.action?uni.navigateTo({url:"/pages/patient/detail?id=".concat(e)}):"edit"==t.action?uni.navigateTo({url:"/pages/patient/form?id=".concat(e)}):"delete"==t.action?uni.showModal({title:"删除 "+this.option.title,content:"是否确定?",success:function(t){t.confirm&&i.delete(e)}}):"record-add"==t.action?uni.navigateTo({url:"/pages/record/form?patient=".concat(e)}):"record"==t.action?uni.navigateTo({url:"/pages/record/index?patient=".concat(e)}):void 0},swipeClick:function(t){var i=this,e=t.index,n=this.list[t.name];if(0==e)return uni.showModal({title:"删除 "+n.name,content:"是否确定?",success:function(t){t.confirm&&i.delete(n.id)}})},delete:function(t){var i=this;uni.showLoading(),this.$ajax.delete("/admin-api/patient/".concat(t)).then((function(t){0==t.status&&(uni.showToast({title:"删除成功",icon:"success"}),setTimeout((function(){i.loadData(!0)}),1e3))}))}}}),l=s,d=(e(1230),e(1503)),u=(0,d.Z)(l,a,c,!1,null,"87e4cf9e",null,!1,o,n),r=u.exports},811:function(t,i,e){"use strict";e.r(i);var n=e(2916),o=e.n(n),a=e(3282),c=e.n(a),s=c()(o());s.push([t.id,".list[data-v-87e4cf9e]{background-color:#fff;padding-bottom:20px}.add-button[data-v-87e4cf9e]{position:absolute;bottom:100px;right:50px;z-index:999}",""]),i["default"]=s}}]);

View File

@ -1 +0,0 @@
(self["webpackChunkuniapp"]=self["webpackChunkuniapp"]||[]).push([[225],{5313:function(t,i,n){var a=n(7661);a.__esModule&&(a=a.default),"string"===typeof a&&(a=[[t.id,a,""]]),a.locals&&(t.exports=a.locals);var e=n(5472).Z;e("49136db0",a,!0,{sourceMap:!1,shadowMode:!1})},4940:function(t,i,n){"use strict";n.r(i),n.d(i,{default:function(){return r}});var a,e={uSearch:n(8035).Z,uButton:n(7344).Z,uList:n(4307).Z,uSwipeAction:n(3309).Z,uListItem:n(8556).Z,uSwipeActionItem:n(8268).Z,uCell:n(7981).Z,uActionSheet:n(7030).Z},o=function(){var t=this,i=t.$createElement,n=t._self._c||i;return n("v-uni-view",{staticClass:"page"},[n("u-search",{attrs:{bgColor:"white",showAction:!1,margin:"10px 0",placeholder:"姓名/联系方式"},on:{search:function(i){arguments[0]=i=t.$handleEvent(i),t.loadData(!0)},change:function(i){arguments[0]=i=t.$handleEvent(i),t.changeSearch.apply(void 0,arguments)}},model:{value:t.search,callback:function(i){t.search=i},expression:"search"}}),n("v-uni-view",{staticClass:"add-button"},[n("u-button",{attrs:{type:"primary",icon:"plus",shape:"circle",size:"large"},on:{click:function(i){arguments[0]=i=t.$handleEvent(i),t.add.apply(void 0,arguments)}}})],1),n("u-list",{staticClass:"list",on:{scrolltolower:function(i){arguments[0]=i=t.$handleEvent(i),t.reachBottom.apply(void 0,arguments)}}},[n("u-swipe-action",t._l(t.list,(function(i,a){return n("u-list-item",{key:i.id},[n("u-swipe-action-item",{attrs:{options:t.swipeOption,name:a},on:{click:function(i){arguments[0]=i=t.$handleEvent(i),t.swipeClick.apply(void 0,arguments)}}},[n("u-cell",{attrs:{title:i.name+(""!=i.age?"("+i.age+")":""),label:i.phone?i.phone:"暂无联系方式",clickable:!0,isLink:!1,url:"/pages/patient/detail?id="+i.id}})],1)],1)})),1)],1),n("u-action-sheet",{attrs:{actions:t.option.list,title:t.option.title,show:t.option.show,closeOnClickOverlay:!0},on:{close:function(i){arguments[0]=i=t.$handleEvent(i),t.closeOption.apply(void 0,arguments)},select:function(i){arguments[0]=i=t.$handleEvent(i),t.chooseOption.apply(void 0,arguments)}}})],1)},s=[],c=(n(423),n(101),n(6228),{data:function(){return{list:[],page:1,perPage:20,total:0,search:"",option:{id:"",show:!1,list:[{name:"详细",color:"#4cd964",action:"detail"},{name:"修改",color:"#007aff",action:"edit"},{name:"添加病历",color:"#f0ad4e",action:"record-add"},{name:"查看病历",color:"#4cd964",action:"record"},{name:"删除",color:"#dd524d",action:"delete"}],title:""},swipeOption:[{text:"删除",style:{backgroundColor:"#dd524d"}}]}},onShow:function(){this.loadData(!0)},onPullDownRefresh:function(){this.loadData(!0)},methods:{loadData:function(t){var i=this;t&&(this.list=[],this.page=1),uni.showLoading();var n={_action:"getData",page:this.page,perPage:this.perPage,keyword:this.search};this.$ajax.get("/admin-api/patient?",{params:n}).then((function(t){uni.stopPullDownRefresh(),0==t.status&&(i.list=i.list.concat(t.data.items),i.total=t.data.total)})).catch((function(t){uni.stopPullDownRefresh()}))},reachBottom:function(){this.list.length<this.total&&(this.page++,this.loadData())},changeSearch:function(t){t||this.loadData(!0)},add:function(){uni.navigateTo({url:"/pages/patient/form"})},openOption:function(t){var i=this.list[t];this.option.title=i.name,this.option.id=i.id,this.option.show=!0},closeOption:function(){this.option.show=!1},chooseOption:function(t){var i=this,n=this.option.id;return"detail"==t.action?uni.navigateTo({url:"/pages/patient/detail?id=".concat(n)}):"edit"==t.action?uni.navigateTo({url:"/pages/patient/form?id=".concat(n)}):"delete"==t.action?uni.showModal({title:"删除 "+this.option.title,content:"是否确定?",success:function(t){t.confirm&&i.delete(n)}}):"record-add"==t.action?uni.navigateTo({url:"/pages/record/form?patient=".concat(n)}):"record"==t.action?uni.navigateTo({url:"/pages/record/index?patient=".concat(n)}):void 0},swipeClick:function(t){var i=this,n=t.index,a=this.list[t.name];if(0==n)return uni.showModal({title:"删除 "+a.name,content:"是否确定?",success:function(t){t.confirm&&i.delete(a.id)}})},delete:function(t){var i=this;uni.showLoading(),this.$ajax.delete("/admin-api/patient/".concat(t)).then((function(t){0==t.status&&(uni.showToast({title:"删除成功",icon:"success"}),setTimeout((function(){i.loadData(!0)}),1e3))}))}}}),l=c,u=(n(5313),n(1503)),d=(0,u.Z)(l,o,s,!1,null,"1aac93f0",null,!1,e,a),r=d.exports},7661:function(t,i,n){"use strict";n.r(i);var a=n(2916),e=n.n(a),o=n(3282),s=n.n(o),c=s()(e());c.push([t.id,".list[data-v-1aac93f0]{background-color:#fff;padding-bottom:20px}.add-button[data-v-1aac93f0]{position:absolute;bottom:100px;right:50px;z-index:999}",""]),i["default"]=c}}]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long