|
|
<?php
|
|
|
|
|
|
namespace App\Http\Controllers\API\Admin;
|
|
|
|
|
|
use App\Http\Controllers\Controller;
|
|
|
use Illuminate\Http\Request;
|
|
|
use App\Lib\Rs;
|
|
|
use Illuminate\Support\Facades\DB;
|
|
|
use App\Services\UserService;
|
|
|
|
|
|
class WorkbenchController extends Controller
|
|
|
{
|
|
|
protected $userService;
|
|
|
|
|
|
public function __construct(UserService $userService)
|
|
|
{
|
|
|
$this->userService = $userService;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取医嘱列表
|
|
|
*/
|
|
|
public function getApplicationList(Request $request)
|
|
|
{
|
|
|
$hisRequestNo = $request->input('his_request_no', '');
|
|
|
$patientName = $request->input('patient_name', '');
|
|
|
$patientPhone = $request->input('patient_phone', '');
|
|
|
$applyDoctorName = $request->input('apply_doctor_name', '');
|
|
|
$status = $request->input('status', null);
|
|
|
$applyTimeStart = $request->input('apply_time_start', '');
|
|
|
$applyTimeEnd = $request->input('apply_time_end', '');
|
|
|
$page = $request->input('page', 1);
|
|
|
$pageSize = $request->input('page_size', 10);
|
|
|
|
|
|
// 获取当前用户信息,非管理员按执行科室或开单医生过滤
|
|
|
$sysUser = $this->userService->getUserInfoFromRequest($request);
|
|
|
$isAdmin = $this->userService->isAdminFromRequest($request);
|
|
|
$deptCode = null;
|
|
|
$hisCode = null;
|
|
|
if (!$isAdmin) {
|
|
|
if (!empty($sysUser->dept_id)) {
|
|
|
$dept = DB::table('department')->where('id', $sysUser->dept_id)->where('deleted', 0)->first();
|
|
|
if ($dept && !empty($dept->code)) {
|
|
|
$deptCode = $dept->code;
|
|
|
}
|
|
|
}
|
|
|
if (!empty($sysUser->his_code)) {
|
|
|
$hisCode = $sysUser->his_code;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
$query = DB::table('exam_application as ea')
|
|
|
->leftJoin('patient_type as pt', 'ea.patient_type', '=', 'pt.mask')
|
|
|
->select([
|
|
|
'ea.id',
|
|
|
'ea.his_order_id',
|
|
|
'ea.his_request_no',
|
|
|
'ea.patient_id',
|
|
|
'ea.patient_type',
|
|
|
'ea.patient_name',
|
|
|
'ea.patient_id_card_no',
|
|
|
'ea.patient_phone',
|
|
|
'ea.patient_gender',
|
|
|
'ea.patient_age',
|
|
|
'ea.patient_birthday',
|
|
|
'ea.apply_department_code',
|
|
|
'ea.apply_department_name',
|
|
|
'ea.apply_doctor_code',
|
|
|
'ea.apply_doctor_name',
|
|
|
'ea.examination_item_name',
|
|
|
'ea.examination_item_code',
|
|
|
'ea.examination_department_code',
|
|
|
'ea.examination_department_name',
|
|
|
'ea.apply_time',
|
|
|
'ea.payment_status',
|
|
|
'ea.clinical_diagnosis',
|
|
|
'ea.notes',
|
|
|
'ea.status',
|
|
|
'ea.created_at',
|
|
|
'ea.updated_at',
|
|
|
'ea.his_cancel_time',
|
|
|
'ea.his_cancel_reason',
|
|
|
'pt.name as patient_type_name'
|
|
|
]);
|
|
|
|
|
|
if (!empty($hisRequestNo)) {
|
|
|
$query->where('ea.his_request_no', 'like', '%' . $hisRequestNo . '%');
|
|
|
}
|
|
|
|
|
|
if (!empty($patientName)) {
|
|
|
$query->where('ea.patient_name', 'like', '%' . $patientName . '%');
|
|
|
}
|
|
|
|
|
|
if (!empty($patientPhone)) {
|
|
|
$query->where('ea.patient_phone', 'like', '%' . $patientPhone . '%');
|
|
|
}
|
|
|
|
|
|
if (!empty($applyDoctorName)) {
|
|
|
$query->where('ea.apply_doctor_name', 'like', '%' . $applyDoctorName . '%');
|
|
|
}
|
|
|
|
|
|
if ($status !== null) {
|
|
|
$query->where('ea.status', $status);
|
|
|
}
|
|
|
|
|
|
if (!empty($applyTimeStart)) {
|
|
|
$query->where('ea.apply_time', '>=', $applyTimeStart);
|
|
|
}
|
|
|
|
|
|
if (!empty($applyTimeEnd)) {
|
|
|
$query->where('ea.apply_time', '<=', $applyTimeEnd . ' 23:59:59');
|
|
|
}
|
|
|
|
|
|
// 非管理员:执行科室是自己科室 OR 开单医生是自己
|
|
|
if (!$isAdmin) {
|
|
|
if ($deptCode !== null || $hisCode !== null) {
|
|
|
$query->where(function ($q) use ($deptCode, $hisCode) {
|
|
|
if ($deptCode !== null) {
|
|
|
$q->where('ea.examination_department_code', $deptCode);
|
|
|
}
|
|
|
if ($hisCode !== null) {
|
|
|
$q->orWhere('ea.apply_doctor_code', $hisCode);
|
|
|
}
|
|
|
});
|
|
|
} else {
|
|
|
$query->whereRaw('1 = 0');
|
|
|
}
|
|
|
}
|
|
|
|
|
|
$total = $query->count();
|
|
|
$list = $query->orderBy('ea.apply_time', 'desc')
|
|
|
->orderBy('ea.id', 'desc')
|
|
|
->skip(($page - 1) * $pageSize)
|
|
|
->take($pageSize)
|
|
|
->get();
|
|
|
|
|
|
// 查询已预约的医嘱的预约信息
|
|
|
$appointmentIds = $list->where('status', 1)->pluck('id')->toArray();
|
|
|
$appointments = [];
|
|
|
if (!empty($appointmentIds)) {
|
|
|
$appointments = DB::table('exam_appointment as ea')
|
|
|
->leftJoin('department_resource as dr', 'ea.department_resource_id', '=', 'dr.id')
|
|
|
->whereIn('ea.exam_application_id', $appointmentIds)
|
|
|
->where('ea.status', 1) // 只获取预约成功的记录
|
|
|
->select([
|
|
|
'ea.id',
|
|
|
'ea.exam_application_id',
|
|
|
'ea.time_slot_id',
|
|
|
'ea.channel_id',
|
|
|
'ea.appointment_time',
|
|
|
'ea.department_resource_id',
|
|
|
'dr.cancel_reason_required'
|
|
|
])
|
|
|
->get()
|
|
|
->keyBy('exam_application_id');
|
|
|
}
|
|
|
|
|
|
// 为每个医嘱添加预约信息
|
|
|
foreach ($list as $item) {
|
|
|
// 如果医嘱已预约,添加预约信息
|
|
|
if ($item->status === 1 && isset($appointments[$item->id])) {
|
|
|
$item->appointment_info = $appointments[$item->id];
|
|
|
} else {
|
|
|
$item->appointment_info = null;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return Rs::success([
|
|
|
'list' => $list,
|
|
|
'total' => $total,
|
|
|
'page' => $page,
|
|
|
'page_size' => $pageSize,
|
|
|
'total_pages' => ceil($total / $pageSize)
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取患者预约列表(历史预约记录)
|
|
|
*/
|
|
|
public function getPatientAppointments(Request $request)
|
|
|
{
|
|
|
$patientId = $request->input('patient_id', 0);
|
|
|
$statusArr = $request->input('status_arr');
|
|
|
|
|
|
if (empty($patientId)) {
|
|
|
return Rs::error('患者ID不能为空');
|
|
|
}
|
|
|
|
|
|
$list = collect();
|
|
|
|
|
|
// 状态处理逻辑简化
|
|
|
$hasPending = $statusArr === null || (is_array($statusArr) && in_array(0, $statusArr));
|
|
|
$hasScheduled = $statusArr === null || (is_array($statusArr) && array_intersect([1, 2, 3], $statusArr));
|
|
|
|
|
|
// 查询未预约记录
|
|
|
if ($hasPending) {
|
|
|
$pending = DB::table('exam_application')
|
|
|
->where('patient_id', $patientId)
|
|
|
->where('status', 0)
|
|
|
->select(['id', 'his_order_id', 'patient_id', 'patient_name', 'patient_id_card_no', 'patient_gender', 'patient_age',
|
|
|
'examination_item_name', 'examination_item_code', 'examination_department_name',
|
|
|
'examination_department_code', 'apply_doctor_name', 'apply_doctor_code',
|
|
|
'apply_department_name', 'apply_time', 'payment_status', 'clinical_diagnosis',
|
|
|
'notes', 'status', 'created_at', 'updated_at'])
|
|
|
->orderBy('apply_time', 'desc')
|
|
|
->orderBy('id', 'desc')
|
|
|
->get()
|
|
|
->map(function ($item) {
|
|
|
// 补充预约表字段
|
|
|
return (object) array_merge((array)$item, [
|
|
|
'time_slot_id' => null, 'channel_id' => null, 'exam_application_id' => $item->id,
|
|
|
'appointment_time' => null, 'check_in_time' => null, 'finish_time' => null,
|
|
|
'cancel_time' => null, 'channel_name' => null, 'channel_short_name' => null
|
|
|
]);
|
|
|
});
|
|
|
|
|
|
$list = $list->concat($pending);
|
|
|
}
|
|
|
|
|
|
// 查询已预约记录
|
|
|
if ($hasScheduled) {
|
|
|
$scheduledStatuses = $statusArr === null ? [1, 2, 3] : array_intersect([1, 2, 3], $statusArr);
|
|
|
|
|
|
if (!empty($scheduledStatuses)) {
|
|
|
$appointments = DB::table('exam_appointment as ea')
|
|
|
->leftJoin('channel as c', 'ea.channel_id', '=', 'c.id')
|
|
|
->leftJoin('exam_application as eapp', 'ea.exam_application_id', '=', 'eapp.id')
|
|
|
->leftJoin('plan as p', 'ea.time_slot_id', '=', 'p.id')
|
|
|
->leftJoin('department_resource as dr', 'ea.department_resource_id', '=', 'dr.id')
|
|
|
->select(['ea.id', 'ea.time_slot_id', 'ea.channel_id', 'ea.exam_application_id', 'ea.patient_id',
|
|
|
'ea.patient_name', 'ea.status', 'ea.appointment_time', 'ea.check_in_time',
|
|
|
'ea.finish_time', 'ea.cancel_time', 'ea.created_at', 'ea.updated_at',
|
|
|
'c.name as channel_name', 'c.short_name as channel_short_name',
|
|
|
'eapp.examination_item_name', 'eapp.examination_item_code',
|
|
|
'eapp.examination_department_name', 'eapp.examination_department_code',
|
|
|
'eapp.apply_doctor_name', 'eapp.apply_doctor_code', 'eapp.apply_department_name',
|
|
|
'eapp.apply_time', 'eapp.payment_status', 'eapp.clinical_diagnosis', 'eapp.notes',
|
|
|
'eapp.patient_id_card_no',
|
|
|
'p.start_time as slot_start_time', 'p.end_time as slot_end_time',
|
|
|
'dr.name as room_name', 'dr.cancel_reason_required'])
|
|
|
->where('ea.patient_id', $patientId)
|
|
|
->whereIn('ea.status', $scheduledStatuses)
|
|
|
->orderBy('ea.id', 'desc')
|
|
|
->get();
|
|
|
|
|
|
$list = $list->concat($appointments);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 简化排序逻辑
|
|
|
if (!$list->isEmpty()) {
|
|
|
$list = $list->sortByDesc(function ($item) {
|
|
|
return $item->updated_at ?? $item->apply_time ?? $item->created_at;
|
|
|
})->values();
|
|
|
}
|
|
|
|
|
|
return Rs::success($list);
|
|
|
}
|
|
|
/**
|
|
|
* 获取患者详情
|
|
|
*/
|
|
|
public function getPatientDetail(Request $request)
|
|
|
{
|
|
|
$patientId = $request->input('patient_id', 0);
|
|
|
|
|
|
if (empty($patientId)) {
|
|
|
return Rs::error('患者ID不能为空');
|
|
|
}
|
|
|
|
|
|
// 从exam_application表获取患者信息
|
|
|
$patientInfo = DB::table('exam_application')
|
|
|
->where('patient_id', $patientId)
|
|
|
->select([
|
|
|
'patient_id',
|
|
|
'patient_name',
|
|
|
'patient_gender',
|
|
|
'patient_age',
|
|
|
'patient_phone',
|
|
|
'patient_type',
|
|
|
'patient_birthday'
|
|
|
])
|
|
|
->first();
|
|
|
|
|
|
if (!$patientInfo) {
|
|
|
return Rs::error('未找到患者信息');
|
|
|
}
|
|
|
|
|
|
// 获取患者类型名称
|
|
|
$patientTypeName = '';
|
|
|
if ($patientInfo->patient_type == 1) {
|
|
|
$patientTypeName = '门诊患者';
|
|
|
} elseif ($patientInfo->patient_type == 2) {
|
|
|
$patientTypeName = '住院患者';
|
|
|
} elseif ($patientInfo->patient_type == 3) {
|
|
|
$patientTypeName = '急诊患者';
|
|
|
} elseif ($patientInfo->patient_type == 4) {
|
|
|
$patientTypeName = '体检患者';
|
|
|
}
|
|
|
|
|
|
$patientInfo->patient_type_name = $patientTypeName;
|
|
|
|
|
|
return Rs::success($patientInfo);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 根据HIS医嘱ID数组获取医嘱信息
|
|
|
*/
|
|
|
public function getApplicationsByHisOrderIds(Request $request)
|
|
|
{
|
|
|
$hisOrderIds = $request->input('his_order_ids', []);
|
|
|
$channelId = $request->input('channel_id', 2); // 默认护士站
|
|
|
|
|
|
if (empty($hisOrderIds) || !is_array($hisOrderIds)) {
|
|
|
return Rs::error('医嘱ID列表不能为空');
|
|
|
}
|
|
|
|
|
|
$list = DB::table('exam_application as ea')
|
|
|
->leftJoin('patient_type as pt', 'ea.patient_type', '=', 'pt.mask')
|
|
|
->whereIn('ea.his_order_id', $hisOrderIds)
|
|
|
->whereIn('ea.status', [0, 1]) // 只获取申请中和已预约的医嘱
|
|
|
->select([
|
|
|
'ea.id',
|
|
|
'ea.his_request_no',
|
|
|
'ea.his_order_id',
|
|
|
'ea.patient_id',
|
|
|
'ea.patient_type',
|
|
|
'ea.patient_name',
|
|
|
'ea.patient_phone',
|
|
|
'ea.patient_gender',
|
|
|
'ea.patient_age',
|
|
|
'ea.apply_department_code',
|
|
|
'ea.apply_department_name',
|
|
|
'ea.apply_doctor_code',
|
|
|
'ea.apply_doctor_name',
|
|
|
'ea.examination_item_name',
|
|
|
'ea.examination_item_code',
|
|
|
'ea.examination_department_code',
|
|
|
'ea.examination_department_name',
|
|
|
'ea.apply_time',
|
|
|
'ea.payment_status',
|
|
|
'ea.status',
|
|
|
'ea.clinical_diagnosis',
|
|
|
'ea.notes',
|
|
|
'ea.created_at',
|
|
|
'ea.updated_at',
|
|
|
'ea.his_cancel_time',
|
|
|
'ea.his_cancel_reason',
|
|
|
'pt.name as patient_type_name'
|
|
|
])
|
|
|
->orderBy('ea.apply_time', 'desc')
|
|
|
->orderBy('ea.id', 'desc')
|
|
|
->get();
|
|
|
|
|
|
// 获取渠道掩码
|
|
|
$channel = DB::table('channel')->where('id', $channelId)->value('mask');
|
|
|
$channelMask = $channel ?? 2; // 默认护士站掩码
|
|
|
|
|
|
// 查询已预约的医嘱的预约信息
|
|
|
$appointmentIds = $list->where('status', 1)->pluck('id')->toArray();
|
|
|
$appointments = [];
|
|
|
if (!empty($appointmentIds)) {
|
|
|
$appointments = DB::table('exam_appointment as ea')
|
|
|
->leftJoin('department_resource as dr', 'ea.department_resource_id', '=', 'dr.id')
|
|
|
->whereIn('ea.exam_application_id', $appointmentIds)
|
|
|
->where('ea.status', 1) // 只获取预约成功的记录
|
|
|
->select([
|
|
|
'ea.id',
|
|
|
'ea.exam_application_id',
|
|
|
'ea.time_slot_id',
|
|
|
'ea.channel_id',
|
|
|
'ea.appointment_time',
|
|
|
'ea.department_resource_id',
|
|
|
'dr.cancel_reason_required'
|
|
|
])
|
|
|
->get()
|
|
|
->keyBy('exam_application_id');
|
|
|
}
|
|
|
|
|
|
// 为每个医嘱添加项目状态检查和预约信息
|
|
|
foreach ($list as $item) {
|
|
|
$item->status_messages = $this->checkItemStatus($item->examination_item_code, $channelMask);
|
|
|
|
|
|
// 如果医嘱已预约,添加预约信息
|
|
|
if ($item->status === 1 && isset($appointments[$item->id])) {
|
|
|
$item->appointment_info = $appointments[$item->id];
|
|
|
} else {
|
|
|
$item->appointment_info = null;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return Rs::success($list);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 检查项目状态
|
|
|
* @param string $itemCode 项目编码
|
|
|
* @param int $channelMask 渠道掩码
|
|
|
* @return array 状态消息数组
|
|
|
*/
|
|
|
private function checkItemStatus($itemCode, $channelMask)
|
|
|
{
|
|
|
$messages = [];
|
|
|
|
|
|
// 1. 检查项目是否存在于数据库
|
|
|
$examItem = DB::table('exam_item')
|
|
|
->where('code', $itemCode)
|
|
|
->where('deleted', 0)
|
|
|
->first();
|
|
|
|
|
|
if (!$examItem) {
|
|
|
$messages[] = '项目不存在';
|
|
|
return $messages;
|
|
|
}
|
|
|
|
|
|
// 2. 检查项目状态是否正常
|
|
|
if ($examItem->status !== 1) {
|
|
|
$messages[] = '项目已停用';
|
|
|
}
|
|
|
|
|
|
// 3. 检查项目是否需要预约
|
|
|
if ($examItem->need_appointment === 0) {
|
|
|
$messages[] = '无需预约';
|
|
|
return $messages;
|
|
|
}
|
|
|
|
|
|
// 4. 检查项目是否支持当前渠道预约
|
|
|
if ($examItem->enable_channel_mask !== null) {
|
|
|
if (($examItem->enable_channel_mask & $channelMask) === 0) {
|
|
|
$messages[] = '不支持此渠道预约';
|
|
|
return $messages;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 5. 检查项目是否关联了资源
|
|
|
$resourceCount = DB::table('exam_item_resource')
|
|
|
->where('item_id', $examItem->id)
|
|
|
->where('deleted', 0)
|
|
|
->count();
|
|
|
|
|
|
if ($resourceCount === 0) {
|
|
|
$messages[] = '未关联资源';
|
|
|
}
|
|
|
|
|
|
return $messages;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取操作日志
|
|
|
*/
|
|
|
public function getOperationLogs(Request $request)
|
|
|
{
|
|
|
$applicationId = $request->input('application_id', 0);
|
|
|
|
|
|
if (empty($applicationId)) {
|
|
|
return Rs::error('医嘱ID不能为空');
|
|
|
}
|
|
|
|
|
|
$list = DB::table('operation_log')
|
|
|
->where('application_id', $applicationId)
|
|
|
->orderBy('operation_time', 'desc')
|
|
|
->orderBy('id', 'desc')
|
|
|
->get()
|
|
|
->map(function ($item) {
|
|
|
// 解析JSON字段
|
|
|
$item->old_values = $item->old_values ? json_decode($item->old_values, true) : null;
|
|
|
$item->new_values = $item->new_values ? json_decode($item->new_values, true) : null;
|
|
|
|
|
|
// 添加中文描述
|
|
|
$item->operator_type_name = $this->getOperatorTypeName($item->operator_type);
|
|
|
$item->operation_type_name = $this->getOperationTypeName($item->operation_type);
|
|
|
$item->entity_type_name = $this->getEntityTypeName($item->entity_type);
|
|
|
|
|
|
return $item;
|
|
|
});
|
|
|
|
|
|
return Rs::success($list);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取操作来源名称
|
|
|
*/
|
|
|
private function getOperatorTypeName($type)
|
|
|
{
|
|
|
$typeMap = [
|
|
|
1 => 'HIS系统',
|
|
|
2 => '预约系统',
|
|
|
3 => '管理员'
|
|
|
];
|
|
|
return $typeMap[$type] ?? '未知';
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取操作类型名称
|
|
|
*/
|
|
|
private function getOperationTypeName($type)
|
|
|
{
|
|
|
$typeMap = [
|
|
|
1 => '创建',
|
|
|
2 => '更新',
|
|
|
3 => '作废',
|
|
|
4 => '取消'
|
|
|
];
|
|
|
return $typeMap[$type] ?? '未知';
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取操作实体名称
|
|
|
*/
|
|
|
private function getEntityTypeName($type)
|
|
|
{
|
|
|
$typeMap = [
|
|
|
1 => '检查申请单',
|
|
|
2 => '预约记录'
|
|
|
];
|
|
|
return $typeMap[$type] ?? '未知';
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取病区患者列表
|
|
|
*/
|
|
|
public function getWardPatientList(Request $request)
|
|
|
{
|
|
|
// 获取查询参数
|
|
|
$appointmentStatus = $request->input('appointment_status', null);
|
|
|
$bedNumber = $request->input('bed_number', '');
|
|
|
$patientName = $request->input('patient_name', '');
|
|
|
$page = $request->input('page', 1);
|
|
|
$pageSize = $request->input('page_size', 20);
|
|
|
|
|
|
// 获取当前用户信息
|
|
|
$sysUser = $this->userService->getUserInfoFromRequest($request);
|
|
|
if (!$sysUser) {
|
|
|
return Rs::error('用户不存在');
|
|
|
}
|
|
|
|
|
|
// 判断是否为管理员(从 JWT payload 中直接判断,无需额外查询)
|
|
|
$isAdmin = $this->userService->isAdminFromRequest($request);
|
|
|
|
|
|
// 构建查询:获取每个患者的最新检查申请记录
|
|
|
$subQuery = DB::table('exam_application as ea')
|
|
|
->select([
|
|
|
'ea.patient_id',
|
|
|
'ea.id',
|
|
|
'ea.bed_code',
|
|
|
'ea.inpatient_id',
|
|
|
'ea.patient_name',
|
|
|
'ea.patient_gender',
|
|
|
'ea.patient_age',
|
|
|
'ea.ward_code',
|
|
|
'ea.ward_name',
|
|
|
'ea.apply_department_name',
|
|
|
'ea.apply_doctor_name',
|
|
|
'ea.clinical_diagnosis',
|
|
|
'ea.status as appointment_status',
|
|
|
'ea.apply_time'
|
|
|
])
|
|
|
->whereIn('ea.id', function($query) {
|
|
|
$query->selectRaw('MAX(id)')
|
|
|
->from('exam_application')
|
|
|
->groupBy('patient_id');
|
|
|
});
|
|
|
|
|
|
// 非管理员只显示对应病区的患者,未绑定病区则拒绝
|
|
|
if (!$isAdmin) {
|
|
|
if (empty($sysUser->ward_code)) {
|
|
|
return Rs::error('用户未绑定病区,无法获取病区患者');
|
|
|
}
|
|
|
$subQuery->where('ea.ward_code', $sysUser->ward_code);
|
|
|
}
|
|
|
|
|
|
// 默认只查询住院患者(patient_type = 2)
|
|
|
$subQuery->where('ea.patient_type', 2);
|
|
|
|
|
|
// 添加筛选条件
|
|
|
if (!empty($bedNumber)) {
|
|
|
$subQuery->where('ea.bed_code', $bedNumber);
|
|
|
}
|
|
|
|
|
|
if (!empty($patientName)) {
|
|
|
$subQuery->where('ea.patient_name', 'like', '%' . $patientName . '%');
|
|
|
}
|
|
|
|
|
|
if ($appointmentStatus !== null) {
|
|
|
$subQuery->where('ea.status', $appointmentStatus);
|
|
|
}
|
|
|
|
|
|
// 计算总数
|
|
|
$total = $subQuery->count();
|
|
|
|
|
|
// 获取患者列表
|
|
|
$patients = $subQuery
|
|
|
->orderBy('ea.apply_time', 'desc')
|
|
|
->orderBy('ea.id', 'desc')
|
|
|
->skip(($page - 1) * $pageSize)
|
|
|
->take($pageSize)
|
|
|
->get();
|
|
|
|
|
|
// 获取所有患者ID
|
|
|
$patientIds = $patients->pluck('patient_id')->toArray();
|
|
|
|
|
|
// 查询每个患者的待预约数量 (status = 0)
|
|
|
$pendingCounts = [];
|
|
|
if (!empty($patientIds)) {
|
|
|
$pendingCounts = DB::table('exam_application')
|
|
|
->whereIn('patient_id', $patientIds)
|
|
|
->where('status', 0)
|
|
|
->selectRaw('patient_id, COUNT(*) as count')
|
|
|
->groupBy('patient_id')
|
|
|
->pluck('count', 'patient_id')
|
|
|
->toArray();
|
|
|
}
|
|
|
|
|
|
// 查询每个患者的今日检查数量
|
|
|
$today = date('Y-m-d');
|
|
|
$todayCheckCounts = [];
|
|
|
if (!empty($patientIds)) {
|
|
|
$todayCheckCounts = DB::table('exam_appointment')
|
|
|
->join('exam_application', 'exam_appointment.exam_application_id', '=', 'exam_application.id')
|
|
|
->whereIn('exam_application.patient_id', $patientIds)
|
|
|
->where('exam_appointment.status', 1) // 预约成功
|
|
|
->whereDate('exam_appointment.appointment_time', $today)
|
|
|
->selectRaw('exam_application.patient_id, COUNT(*) as count')
|
|
|
->groupBy('exam_application.patient_id')
|
|
|
->pluck('count', 'patient_id')
|
|
|
->toArray();
|
|
|
}
|
|
|
|
|
|
// 组装返回数据
|
|
|
$list = $patients->map(function ($patient) use ($pendingCounts, $todayCheckCounts) {
|
|
|
return [
|
|
|
'id' => $patient->patient_id,
|
|
|
'bed_number' => $patient->bed_code ?? '',
|
|
|
'inpatient_no' => $patient->inpatient_id ?? '',
|
|
|
'patient_name' => $patient->patient_name,
|
|
|
'gender' => $patient->patient_gender,
|
|
|
'age' => $patient->patient_age,
|
|
|
'ward_code' => $patient->ward_code,
|
|
|
'ward_name' => $patient->ward_name ?? '',
|
|
|
'department_name' => $patient->apply_department_name ?? '',
|
|
|
'attending_doctor' => $patient->apply_doctor_name ?? '',
|
|
|
'diagnosis' => $patient->clinical_diagnosis ?? '',
|
|
|
'pending_count' => $pendingCounts[$patient->patient_id] ?? 0,
|
|
|
'today_check_count' => $todayCheckCounts[$patient->patient_id] ?? 0,
|
|
|
'appointment_status' => $patient->appointment_status
|
|
|
];
|
|
|
});
|
|
|
|
|
|
return Rs::success([
|
|
|
'list' => $list,
|
|
|
'total' => $total,
|
|
|
'page' => $page,
|
|
|
'page_size' => $pageSize,
|
|
|
'total_pages' => ceil($total / $pageSize)
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 批量获取多个患者的待预约项目
|
|
|
*/
|
|
|
public function getBatchPatientExaminations(Request $request)
|
|
|
{
|
|
|
$patientIds = $request->input('patient_ids', []);
|
|
|
|
|
|
if (empty($patientIds) || !is_array($patientIds)) {
|
|
|
return Rs::error('患者ID列表不能为空');
|
|
|
}
|
|
|
|
|
|
// 限制一次最多查询100个患者
|
|
|
if (count($patientIds) > 100) {
|
|
|
return Rs::error('一次最多查询100个患者');
|
|
|
}
|
|
|
|
|
|
// 查询所有患者的待预约项目(status = 0)
|
|
|
$examinations = DB::table('exam_application')
|
|
|
->whereIn('patient_id', $patientIds)
|
|
|
->where('status', 0)
|
|
|
->select([
|
|
|
'patient_id',
|
|
|
'patient_name',
|
|
|
'patient_gender',
|
|
|
'patient_age',
|
|
|
'id',
|
|
|
'his_order_id',
|
|
|
'examination_item_name',
|
|
|
'examination_item_code',
|
|
|
'examination_department_name',
|
|
|
'examination_department_code',
|
|
|
'apply_doctor_name',
|
|
|
'apply_doctor_code',
|
|
|
'apply_department_name',
|
|
|
'apply_time',
|
|
|
'payment_status',
|
|
|
'clinical_diagnosis',
|
|
|
'notes'
|
|
|
])
|
|
|
->orderBy('patient_id')
|
|
|
->orderBy('apply_time', 'desc')
|
|
|
->get();
|
|
|
|
|
|
// 按患者ID分组
|
|
|
$groupedExaminations = [];
|
|
|
foreach ($examinations as $exam) {
|
|
|
if (!isset($groupedExaminations[$exam->patient_id])) {
|
|
|
$groupedExaminations[$exam->patient_id] = [];
|
|
|
}
|
|
|
$groupedExaminations[$exam->patient_id][] = (array)$exam;
|
|
|
}
|
|
|
|
|
|
return Rs::success($groupedExaminations);
|
|
|
}
|
|
|
|
|
|
public function getPatientPendingItems(Request $request)
|
|
|
{
|
|
|
$patientId = $request->input('patient_id', 0);
|
|
|
$channelId = $request->input('channel_id', 2);
|
|
|
|
|
|
if (empty($patientId)) {
|
|
|
return Rs::error('患者ID不能为空');
|
|
|
}
|
|
|
|
|
|
$applications = DB::table('exam_application')
|
|
|
->where('patient_id', $patientId)
|
|
|
->where('status', 0)
|
|
|
->select([
|
|
|
'id', 'his_order_id', 'patient_id', 'patient_name',
|
|
|
'examination_item_name', 'examination_item_code',
|
|
|
'examination_department_name', 'examination_department_code',
|
|
|
'apply_doctor_name', 'apply_department_name',
|
|
|
'apply_time', 'payment_status', 'status'
|
|
|
])
|
|
|
->orderBy('apply_time', 'desc')
|
|
|
->get();
|
|
|
|
|
|
if ($applications->isEmpty()) {
|
|
|
return Rs::success([
|
|
|
'items' => [],
|
|
|
'groups' => [],
|
|
|
'extra_his_order_ids' => []
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
$itemCodes = $applications->pluck('examination_item_code')->unique()->toArray();
|
|
|
|
|
|
$examItems = DB::table('exam_item')
|
|
|
->whereIn('code', $itemCodes)
|
|
|
->where('deleted', 0)
|
|
|
->select('id', 'code', 'name', 'use_seats')
|
|
|
->get()
|
|
|
->keyBy('code');
|
|
|
|
|
|
$examItemIds = $examItems->pluck('id')->toArray();
|
|
|
|
|
|
$itemResources = DB::table('exam_item_resource')
|
|
|
->whereIn('item_id', $examItemIds)
|
|
|
->where('deleted', 0)
|
|
|
->select('item_id', 'resource_id')
|
|
|
->get();
|
|
|
|
|
|
$resourcesByItem = [];
|
|
|
foreach ($itemResources as $ir) {
|
|
|
$resourcesByItem[$ir->item_id][] = $ir->resource_id;
|
|
|
}
|
|
|
|
|
|
$resourcesInfo = [];
|
|
|
if (!empty($itemResources)) {
|
|
|
$resourceIds = $itemResources->pluck('resource_id')->unique()->toArray();
|
|
|
$resourcesInfo = DB::table('department_resource')
|
|
|
->whereIn('id', $resourceIds)
|
|
|
->pluck('name', 'id')
|
|
|
->toArray();
|
|
|
}
|
|
|
|
|
|
$groupMap = [];
|
|
|
foreach ($applications as $app) {
|
|
|
$examItem = $examItems->get($app->examination_item_code);
|
|
|
if (!$examItem) {
|
|
|
continue;
|
|
|
}
|
|
|
$itemId = $examItem->id;
|
|
|
$resourceIds = $resourcesByItem[$itemId] ?? [];
|
|
|
$groupMap[$app->id] = [
|
|
|
'application_id' => $app->id,
|
|
|
'his_order_id' => $app->his_order_id,
|
|
|
'item_name' => $app->examination_item_name,
|
|
|
'resource_ids' => $resourceIds,
|
|
|
];
|
|
|
}
|
|
|
|
|
|
$assignedGroups = [];
|
|
|
$appGroupIndex = [];
|
|
|
$groupIndex = 0;
|
|
|
|
|
|
foreach ($groupMap as $appId => $info) {
|
|
|
if (isset($appGroupIndex[$appId])) {
|
|
|
continue;
|
|
|
}
|
|
|
$groupApps = [$appId];
|
|
|
$groupResources = $info['resource_ids'];
|
|
|
|
|
|
foreach ($groupMap as $otherAppId => $otherInfo) {
|
|
|
if ($otherAppId === $appId || isset($appGroupIndex[$otherAppId])) {
|
|
|
continue;
|
|
|
}
|
|
|
$intersection = array_intersect($groupResources, $otherInfo['resource_ids']);
|
|
|
if (!empty($intersection)) {
|
|
|
$groupApps[] = $otherAppId;
|
|
|
$groupResources = $intersection;
|
|
|
$appGroupIndex[$otherAppId] = $groupIndex;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
$appGroupIndex[$appId] = $groupIndex;
|
|
|
|
|
|
$primaryResourceId = !empty($groupResources) ? array_values($groupResources)[0] : null;
|
|
|
$assignedGroups[$groupIndex] = [
|
|
|
'resource_id' => $primaryResourceId,
|
|
|
'resource_name' => $primaryResourceId ? ($resourcesInfo[$primaryResourceId] ?? '未知') : '未知',
|
|
|
'application_ids' => [],
|
|
|
'his_order_ids' => [],
|
|
|
'items' => []
|
|
|
];
|
|
|
|
|
|
foreach ($groupApps as $gAppId) {
|
|
|
$gInfo = $groupMap[$gAppId];
|
|
|
$assignedGroups[$groupIndex]['application_ids'][] = $gAppId;
|
|
|
$assignedGroups[$groupIndex]['his_order_ids'][] = $gInfo['his_order_id'];
|
|
|
$assignedGroups[$groupIndex]['items'][] = [
|
|
|
'application_id' => $gAppId,
|
|
|
'his_order_id' => $gInfo['his_order_id'],
|
|
|
'item_name' => $gInfo['item_name']
|
|
|
];
|
|
|
}
|
|
|
|
|
|
$groupIndex++;
|
|
|
}
|
|
|
|
|
|
$groups = array_values($assignedGroups);
|
|
|
|
|
|
$currentHisOrderIds = $request->input('current_his_order_ids', []);
|
|
|
$allHisOrderIds = $applications->pluck('his_order_id')->toArray();
|
|
|
$extraHisOrderIds = array_values(array_diff($allHisOrderIds, $currentHisOrderIds));
|
|
|
|
|
|
return Rs::success([
|
|
|
'items' => $applications,
|
|
|
'groups' => $groups,
|
|
|
'extra_his_order_ids' => $extraHisOrderIds
|
|
|
]);
|
|
|
}
|
|
|
}
|