You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

399 lines
20 KiB
PHP

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace App\Services\Admin\YeWu;
use App\Services\SendMessgeService;
use DateInterval;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use DateTime;
use Tools;
class PlanListService
{
public function GetEnablePlan($regnum, $entrustids, $episodeid, $appointment_type, $appointment_date)
{
date_default_timezone_set('PRC');
// $regnum = request('regnum');
// $entrustid = request('entrustid');
// $episodeid = request('episodeid');
// $appointment_type = request('appointment_type'); //预约类型
// $appointment_date = request('date'); //预约日期
$allDevice = [];//所有医嘱检查项目绑定的设备id
$commPatientType = [];//所有医嘱共同的病人类型
foreach ($entrustids as $key => $entrustid) {
$info = DB::table('s_list')->where(['reg_num' => $regnum, 'entrust_id' => $entrustid, 'episodeid' => $episodeid, 'is_nullify' => 0])->first();
if (!$info) return \Yz::echoError1('没有找到对应医嘱信息');
$itemInfo = DB::table('s_check_item')->where(['item_name' => $info->entrust, 'status' => 1, "is_del" => 0])->get();
if (count($itemInfo) == 0) return \Yz::echoError1('没有找到可用的检查项目信息');
$itemInfo = $itemInfo[0];
$qudaos = explode(',', $itemInfo->reservation_method);
if (!in_array($appointment_type, $qudaos)) return \Yz::echoError1('此检查项目不支持在当前渠道预约');
// $entrust_time = $info->entrust_date . ' ' . $info->entrust_time; //医嘱时间
// $date = new DateTime($entrust_time);
// $date->modify("+" . $itemInfo->check_begin_time . " minutes");
// $enableCheckTime = $date;//到此时间后可进行预约
// $current_time = new DateTime();
// if ($current_time < $enableCheckTime) return \Yz::echoError1("请于" . $enableCheckTime->format("Y-m-d H:i:s") . "后进行预约");
//获取检查项目绑定的服务组(设备),判断状态正常的
$devices = DB::table('s_check_item_device')
->leftJoin("s_devices", "s_check_item_device.device_id", "=", "s_devices.id")
->where(['s_check_item_device.item_id' => $itemInfo->id])
->where(['s_devices.status' => 1, 'is_del' => 0])->pluck('s_devices.id')->toArray();
$allDevice[] = $devices;
if (!in_array($info->patient_type, $commPatientType)) {
// 如果不在数组中,则添加它
array_push($commPatientType, $info->patient_type);
}
}
$commonDevice = []; //多个检查项目共同的设备id
foreach ($allDevice as $set) {
if (count($commonDevice) == 0) {
// 如果$intersection为空直接将第一个子数组的元素放入
$commonDevice = $set;
} else {
// 使用array_intersect()函数求当前子数组与已有交集的交集
$commonDevice = array_intersect($commonDevice, $set);
}
}
// dd($commonDevice);
//获取主表检查项目绑定的科室id
$department_id = DB::table('s_department')->where(['department_number' => $info->RISRAcceptDeptCode])->first();
if (!$department_id) return \Yz::echoError1('获取医嘱检查项目科室信息失败');
// // 获取当前日期
// $startDate = date('Y-m-d');
// // 创建一个空数组来存储日期
// $datesArray = [];
// // 循环获取今天及之后7天的日期
// for ($i = 0; $i <7; $i++) {
// // 使用DateTime对象方便地进行日期操作
// $dateObject = new DateTime($startDate);
// $dateObject->add(new DateInterval('P'.$i.'D')); // P1D表示增加一天
// // 将日期格式化后存入数组
// $datesArray[] = $dateObject->format('Y-m-d');
// }
//获取对应日期的计划明细
// $plan = DB::table('s_source_roster_detail as a')
// ->select('a.*', 'b.department_resources_name', 'c.roster_detail_id', 'c.count', 'c.used_count','e.device_name as devices')
// ->leftJoin('s_department_resources as b', 'a.resources_id', '=', 'b.id')
// ->leftJoin('s_source_roster_detail_count as c', 'a.id', '=', 'c.roster_detail_id')
// ->leftJoin('s_source_roster_detail_device as d','a.id','=','d.roster_detail_id')
// ->leftJoin('s_devices as e','d.device_id','=','e.id')
// ->where(['a.department_id' => $department_id->id])
// ->where('a.date',$appointment_date)
// ->where(['a.status' => 1, 'a.is_del' => 0, 'b.is_del' => 0, 'c.appointment_type_id' => $appointment_type])
// ->whereIn('d.device_id',$commonDevice)
// ->orderBy('a.date')
// ->get();
$placeholders = implode(',', array_fill(0, count($commonDevice), '?'));
$canshu = array_merge($commonDevice, [$department_id->id, $appointment_date, $appointment_type]);
$plan = DB::select("SELECT
a.*,
dd.devices,
b.department_resources_name,
c.roster_detail_id,
c.count,
c.used_count
FROM
s_source_roster_detail AS a
LEFT JOIN s_department_resources AS b ON a.resources_id = b.id
LEFT JOIN s_source_roster_detail_count AS c ON a.id = c.roster_detail_id
JOIN (
SELECT
roster_detail_id,
GROUP_CONCAT( e.device_name SEPARATOR ', ' ) AS devices
FROM
s_source_roster_detail_device AS d
LEFT JOIN s_devices AS e ON d.device_id = e.id
WHERE
d.device_id IN ($placeholders)
GROUP BY
d.roster_detail_id
) AS dd ON a.id = dd.roster_detail_id
WHERE
a.department_id = ?
AND a.date = ?
AND a.STATUS = 1
AND a.is_del = 0
AND b.is_del = 0
AND c.appointment_type_id =?", $canshu);
//遍历列表 把超过当前时间的放在后面
$pl1 = [];
$pl2 = [];
$pp = [];
$nowtime = date('Y-m-d H:i:s');
foreach ($plan as $key => $p) {
// //病人类型不符合的过滤掉
$planPatientType = explode(",", $p->patient_type);
if (!empty(array_diff($commPatientType, $planPatientType))) {
continue;
}
//过期的排在后面
$time = $p->date . ' ' . $p->end_time;
if ($time > $nowtime) {
$pl1[] = $p;
} else {
$pl2[] = $p;
}
}
$pp = array_merge($pl1, $pl2);
return \Yz::Return(true, '查询完成', ['today_date' => date("Y-m-d"), 'appointment_date' => $appointment_date, 'weekname' => Tools::GetWeekName($appointment_date), 'mainInfo' => $info, 'plan_list' => $pp]);
}
//开始预约占用名额
public function YuYue($planid, $appointment_type, $mainlistids, $do_type)
{
date_default_timezone_set('PRC');
$nowdatetime = date("Y-m-d H:i:s");
// $planid = request('planid');
// $appointment_type = request('appointment_type');//渠道id
// $mainlistid = request('mainlistid');//主表id
// $do_type = request('dotype');//操作类型,1预约2改约
// if (!isset($do_type)) return \Yz::echoError1('参数:操作类型 不能为空');
$planInfo = DB::table('s_source_roster_detail')->where(['id' => $planid, 'status' => 1, 'is_del' => 0])->first();
if (!$planInfo) return \Yz::echoError1('当前时段不可用');
if ($nowdatetime > $planInfo->date . ' ' . $planInfo->end_reservation_time) return \Yz::echoError1('已经超过预约截止时间');
$planCount = DB::table('s_source_roster_detail_count')->where(['roster_detail_id' => $planid,
'appointment_type_id' => $appointment_type])->first();
if ($planCount->count < ($planCount->used_count + count($mainlistids))) return \Yz::echoError1('当前预约时间名额不足');
$oldMainInfos = [];//临时存储原来的主表信息,用于改约
//遍历多个s_list表id,前端多选,一次预约多个检查项目
foreach ($mainlistids as $key_m => $mainlistid) {
$mainInfo = DB::table('s_list as a')
->select('a.*', 'b.period_begin_time', 'b.period_end_time')
->leftJoin('s_period as b', 'a.reservation_time', '=', 'b.id')
->where(['a.id' => $mainlistid])->first();
$oldMainInfos[] = $mainInfo;
if (!$mainInfo) return \Yz::echoError1('医嘱不存在');
//判断状态
$msg_t = "";
if ($mainInfo->list_status == 0) {
$msg_t = "当前状态为待预约";
}
if ($mainInfo->list_status == 1) {
$msg_t = "已经在" . $mainInfo->reservation_date . '的' . $mainInfo->period_begin_time . '-' . $mainInfo->period_end_time . '预约成功,不能再次预约';
}
if ($mainInfo->list_status == 2) {
$msg_t = "当前状态为已登记";
}
if ($mainInfo->list_status == 3) {
$msg_t = "当前状态为已完成";
}
if ($do_type == 1 && $mainInfo->list_status <> 0) return \Yz::echoError1($mainInfo->entrust . ' ' . $msg_t . ',禁止预约');
if ($do_type == 2 && $mainInfo->list_status <> 1) return \Yz::echoError1($mainInfo->entrust . ' ' . $msg_t . ',不允许改约操作');
//判断病人类型
$plan_patient_type=explode(",", $planInfo->patient_type);
if(!in_array($mainInfo->patient_type, $plan_patient_type)) return \Yz::echoError1('当前计划不支持此病人类型');
//判断互斥暂时根据reg_num判断身份
//查询想要预约的项目 其自身code
$item = DB::table('s_check_item')->where(['item_name' => $mainInfo->entrust, 'status' => 1, 'is_del' => 0])->first();
if (!$item) return \Yz::echoError1('此检查项目不可用');
//医嘱开具后,预约时间需在设定的等待期之后,单位分钟
$entrust_time = $mainInfo->entrust_date . ' ' . $mainInfo->entrust_time; //医嘱时间
$date = new DateTime($entrust_time);
$date->modify("+" . $item->check_begin_time . " minutes");
$enableCheckTime = $date;//到此时间后可进行预约
$plan_dateTime = $planInfo->date . ' ' . $planInfo->end_time;
$plan_dateTime = new DateTime($plan_dateTime);
if ($plan_dateTime < $enableCheckTime) return \Yz::echoError1($item->item_name . " 已设置只能预约医嘱开具后" . $item->check_begin_time . "分钟后的时间,请预约" . $enableCheckTime->format("Y-m-d H:i:s") . "之后的时间");
//检测是否空腹
$configs = DB::table('configs')->where('label', '开启空腹')->first();
if ($item->limosis == 1 and $planInfo->end_reservation_time > '12:00:00' and $configs->value == 1) return \Yz::echoError1($item->item_name . ' 项目必须空腹,只能预约上午,请重新选择时间');
//查询当前检查项目是否存在互斥
$cha_hc = DB::table('s_huchi')->where('is_del', 0)
->where(function ($q) use ($item) {
$q->where(['code1' => $item->item_code])->orWhere('code2', $item->item_code);
})->get();
if (count($cha_hc) > 0) {
//查询用户预约中的医嘱
$status_1 = DB::table('s_list')
->select('s_check_item.item_code', 's_list.entrust', 's_list.reservation_date', 's_list.reservation_time')
->leftJoin('s_check_item', 's_list.entrust', '=', 's_check_item.item_name')
->where(['s_list.reg_num' => $mainInfo->reg_num, 's_list.list_status' => 1, 's_list.is_del' => 0, 's_list.is_nullify' => 0])
//排除自身,自己不能互斥自己
->whereNotIn('item_name', [$mainInfo->entrust])
->get();
if (count($status_1) > 0) {
foreach ($status_1 as $key => $value) {
foreach ($cha_hc as $k => $v) {
if ($v->code1 == $value->item_code or $v->code2 == $value->item_code) {
if ($v->time == 0) {
//如果是永久互斥,直接拒绝
return \Yz::Return(false, '当前预约项目与' . $value->entrust . '互斥,暂不可预约', ['name' => $value->entrust]);
}
if ($v->time > 0) {
//如果设置互斥时间,则判断预约时间是否超过 正在预约的最后时间段+互斥时间
$period = DB::table('s_period')->where(['id' => $value->reservation_time])->first();
$endTime = $period->period_end_time;
$periodEndDateTime = $value->reservation_date . ' ' . $endTime;
$date = new DateTime($periodEndDateTime);
// 添加互斥时间/小时
$date->add(new \DateInterval('PT' . $v->time . 'H')); // PTXH 表示X小时的时间间隔
$HuChi_EndDateTime = $date->format('Y-m-d H:i:s');//已经预约的项目结束互斥时间
$YuYueDateTime = substr($planInfo->date, 0, 10) . ' ' . $planInfo->begin_time;
if ($HuChi_EndDateTime > $YuYueDateTime) {
return \Yz::Return(false, '当前预约项目与' . $value->entrust . '互斥,暂不可预约,请预约' . $HuChi_EndDateTime . '后的日期', ['name' => $value->entrust]);
}
}
}
}
}
}
}
}
DB::beginTransaction();
try {
//更新计划明细表使用数量
$u = DB::table('s_source_roster_detail_count')->where(['id' => $planCount->id])->whereRaw('count >= (used_count + ?)', [count($mainlistids)])
->increment('used_count', count($mainlistids));
if ($u) {
$cha = DB::table('s_source_roster_detail_count')->where(['id' => $planCount->id])->first();
if ($cha->count >= $cha->used_count) {
//更新主表信息
$u_data = [
'list_status' => 1,
'reservation_date' => $planInfo->date,
'reservation_time' => $planInfo->period_id,
'reservation_sources' => $planInfo->resources_id,
'services_group' => $planInfo->device_id,
'roster_id' => $planInfo->id,
'department_id' => $planInfo->department_id,
'xuhao' => 0,
'appointment_type_id' => $appointment_type,
];
$u_mainList = DB::table('s_list')->whereIn('id', $mainlistids)->update($u_data);
$note = "预约";
foreach ($oldMainInfos as $key => $oldMainInfo) {
if ($do_type == 2) {
// if(count($mainlistids)>1) return \Yz::echoError1('请选择1条医嘱改约暂不支持批量');
$note = "改约";
//如果是改约,则恢复原来的数量
$u_old = DB::table('s_source_roster_detail_count')->where(['roster_detail_id' => $oldMainInfo->roster_id, 'appointment_type_id' => $oldMainInfo->appointment_type_id, ['used_count', '>', 0]])->decrement('used_count');
}
$i_log = DB::table('s_list_log')->insert([
'list_id' => $oldMainInfo->id,
'reg_num' => $oldMainInfo->reg_num,
'old_status' => $oldMainInfo->list_status,
'new_status' => 1,
'create_user' => null,
'note' => $note,
'data' => json_encode($u_data)
]);
}
if ($u_mainList) {
DB::commit();
if(config('app.globals.预约完成短信通知')==1){
$this->SendMsg($oldMainInfos,$do_type);
}
return \Yz::Return(true, '预约成功', ['planid' => $planid, 'mainlistids' => $mainlistids]);
} else {
DB::rollBack();
return \Yz::echoError1('预约失败');
}
} else {
DB::rollBack();
return \Yz::echoError1('当前预约时间名额不足');
}
} else {
return \Yz::echoError1('操作失败');
}
} catch (\Exception $e) {
DB::rollBack();
return \Yz::echoError1('预约异常' . $e->getMessage());
}
}
public function CancelYuYue($MainListId, $reg_num)
{
date_default_timezone_set('PRC');
$nowdatetime = date("Y-m-d H:i:s");
$mainInfo = DB::table('s_list')->where(['id' => $MainListId, 'reg_num' => $reg_num])->first();
if (!$mainInfo) return \Yz::echoError1('医嘱不存在');
//判断状态
if ($mainInfo->list_status <> 1) return \Yz::echoError1('该记录无法取消,当前状态:' . $mainInfo->list_status);
DB::beginTransaction();
try {
$u_data = [
'list_status' => 0,
'reservation_date' => null,
'reservation_time' => null,
'reservation_sources' => null,
'services_group' => null,
'roster_id' => null,
'xuhao' => null,
'department_id' => null,
'appointment_type_id' => null,
'canel_time' => $nowdatetime,
];
$u_mainList = DB::table('s_list')->where(['id' => $MainListId])->update($u_data);
$i_log = DB::table('s_list_log')->insert([
'list_id' => $mainInfo->id,
'reg_num' => $mainInfo->reg_num,
'old_status' => $mainInfo->list_status,
'new_status' => 0,
'create_user' => null,
'note' => '取消预约',
'data' => json_encode($u_data)
]);
$u_count = DB::table('s_source_roster_detail_count')->where(['roster_detail_id' => $mainInfo->roster_id, 'appointment_type_id' => $mainInfo->appointment_type_id])->decrement('used_count');
if ($u_mainList && $u_count) {
DB::commit();
return \Yz::Return(true, '取消成功', []);
} else {
DB::rollBack();
return \Yz::echoError1('取消失败');
}
} catch (\Exception $e) {
DB::rollBack();
return \Yz::echoError1('取消异常');
}
}
//短信提醒
public function SendMsg($infos,$dotype=1)
{
$s=new SendMessgeService();
foreach ($infos as $key => $info) {
$mainInfo = DB::table('s_list as a')
->select('a.*', 'b.period_begin_time', 'b.period_end_time')
->leftJoin('s_period as b', 'a.reservation_time', '=', 'b.id')
->where(['a.id' => $info->id])->first();
$s->sendMessage($info->user_phone,'测试短信,项目:'.$mainInfo->entrust.',时间:'.$mainInfo->reservation_date.' '.substr($mainInfo->period_begin_time,0,5).'-'.substr($mainInfo->period_end_time,0,5));
}
}
}