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.

628 lines
24 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\Http\Controllers\API\H5;
use App\Http\Controllers\API\AspNetZhuanController;
use App\Http\Controllers\Controller;
use App\Http\Controllers\API\PEISApiController;
use App\Lib\Tools;
use App\Services\ConfigService;
use DateTime;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class OrderController extends Controller
{
public function list(Request $request)
{
// status 1-待支付 2-已预约 3-交易关闭 4-已完成 5-已退款
$openid = $request->post('openid');
$user = DB::table('web_users')->where(['openid' => $openid, 'is_del' => 0])->first();
if (!$user) return \Yz::echoError1("openid对应用户不存在");
$persons_sfz=DB::table('web_user_person')->where(['user_id' => $user->id,'is_del'=>0])->pluck('id_number')->toArray();
$OrderList = DB::table('orders')
->select('id', 'title', 'status', 'name', 'appointment_time as time', 'order_number as order',
DB::raw("CASE WHEN type = 1 THEN '个检' WHEN type = 2 THEN '团检' ELSE 'unknown' END as type"),
'price', 'true_price', 'pay_time', 'refund_time', 'created_at')
->where(['web_user_id' => $user->id])
->orWhere(function($query) use ($persons_sfz) {
$query->WhereIn('id_number', $persons_sfz)
->where('person_id', 0);
})->orderBy('id','desc')->get();
$WaitingPaymentTime = config('app.globals.WaitingPaymentTime');//支付等待時間
foreach ($OrderList as $key => $list) {
if ($list->status == 1) {
$datetime = new DateTime($list->created_at);
$timestamp = $datetime->getTimestamp();
$list->end_time = $timestamp + (60 * $WaitingPaymentTime);
if (time() > $list->end_time) {
$list->status = 3;
}
}
}
return \Yz::Return(true, '获取成功', [
'list' => $OrderList
]);
}
public function GetDetail()
{
$id = request('id');
$order_info = DB::table('orders')->where(['id' => $id])->first();
if(!!$order_info){
$order_info->buy_info=json_decode($order_info->buy_info,true);
}else{
return \Yz::echoError1('未找到有效订单');
}
return \Yz::Return(true, '获取成功', [
'info' => $order_info
]);
}
//创建订单
public function Create()
{
$hospital_id = request('hospital');
$openid = request('openid');
$person_id = request('person_id');
$combo_id = request('combo_id');
$type = request('type');//1个检2团检
$group_id = request('group_id');//团检id
$item_ids = request('item_ids');//自选item的ids
if (count($item_ids) != 0 and $item_ids[0]=="") {
$item_ids=[];
}
$duo_xuan_yi = request('duo_xuan_yi'); //多选1
$plan_id = request('plan_id');//号源id
$plan_nmr_id = request('plan_nmr_id');//核磁号源id
$doctor = request('doctor');//预约的医生名字
$jifen = request('jifen',0); //使用的积分数量
$yucunkuan = request('yucunkuan',0);//使用的预存款数量
$wj_flag= request('wj'); //问卷标记
if(isset($wj_flag) and $wj_flag==1){
$wj_zhekou=config('app.globals.Wj_ZheKou');//问卷过来的折扣率
}
if (!isset($hospital_id)) return \Yz::echoError1('医院id不能为空');
if (!isset($openid)) return \Yz::echoError1('openid不能为空');
if (!isset($person_id)) return \Yz::echoError1('person_id不能为空');
if (!isset($type)) return \Yz::echoError1('type体检类型不能为空');
if ($type != 1 && $type != 2) {
return \Yz::echoError1('type参数体检类型错误');
}
if (!isset($plan_id)) return \Yz::echoError1('号源id不能为空');
if ($type == 2 and !isset($group_id)) return \Yz::echoError1('团检group_id不能为空');
if ($type == 1 and isset($group_id)) return \Yz::echoError1('体检类型:个检 与group_id冲突');
$user = DB::table('web_users')->where(['openid' => $openid, 'status' => 1, 'is_del' => 0])->first();
if (!$user) return \Yz::echoError1('用户不存在');
$person = DB::table('web_user_person')->where(['id' => $person_id, 'is_del' => 0])->first();
if (!$person) return \Yz::echoError1('体检人不存在');
$title = "自选项目";
$price = 0;
$true_price = 0;//订单真实支付金额
$buy_info = [
'combo' => [
'id' => 0,
'name' => $title,
'price' => 0,
],
'items' => [],
'group' => [
'id' => '',
],
'nmr_list'=>[]
];
//如果是套餐
$Nx1_arrInfo=[];
$TJ_Leixing_id=1;//存储用体检类型
$checkup_type_id = false; //体检类型id
if (isset($combo_id) and $combo_id <> 0) {
$combo_info = DB::table('combos')->where(['combo_id' => $combo_id, 'status' => 1])->first();
if (!$combo_info) return \Yz::echoError1("套餐不存在");
if (!isset($combo_info->checkup_type_id)) return \Yz::echoError1("套餐未关联体检类型");
$checkup_type_id = $combo_info->checkup_type_id;
//构建多选一数据
if(isset($duo_xuan_yi) and !empty($duo_xuan_yi)){
$combo_Nx1=json_decode($combo_info->duo_xuan_yi,true);
foreach ($duo_xuan_yi as $r_k=>$r_v){
foreach ($combo_Nx1 as $k=> $n1v){
if($r_v['zu_name'] == $n1v['组名称']){
foreach ($n1v['包含项目'] as $k2 => $v2){
if($v2['Id'] == $r_v['item_id']){
if($v2['科室名称']=='影像科'){
$buy_info['nmr_list'][]=[
'item_id' => $v2['Id'],
'name' => $v2['名称'],
];
}
$Nx1_arrInfo[] = [
'id' => $v2['Id'],
'name' => $v2['名称'],
'price' =>0
];
}
}
}
}
}
}
$TJ_Leixing_id=$checkup_type_id;
$price += $combo_info->price;
$title = $combo_info->name;
$buy_info['combo'] = [
'id' => $combo_info->combo_id,
'name' => $combo_info->name,
'price' => $combo_info->price,
];
//如果有影像科则存储在nmr_list字段
$comboItem=DB::table('combo_items')->where(['combo_id' => $combo_id, 'status' => 1,'keshi_name'=>'影像科'])->get();
if(count($comboItem)>0){
foreach ($comboItem as $item){
$buy_info['nmr_list'][]=[
'item_id' => $item->item_id,
'name' => $item->name,
];
}
}
}
//如果有自选项目
$items_list = [];
if (count($item_ids) != 0 ) {
$items_list = DB::table('items')->whereIn('item_id', $item_ids)->where(['status' => 1])->get();
$existingIds = [];
$item_price=0;
foreach ($items_list as $item) {
$item_price+=$item->price;
$existingIds[] = $item->item_id;
$buy_info['items'][] = [
'id' => $item->item_id,
'name' => $item->name,
'price' => $item->price
];
//如果有影像科则存储在nmr_list字段
if($item->keshi_name=='影像科'){
$buy_info['nmr_list'][]=[
'item_id' => $item->item_id,
'name' => $item->name,
];
}
}
if(isset($wj_flag) and $wj_flag==1){
$item_price=$item_price*$wj_zhekou;
}
$price += $item_price;
$missingIds = array_diff($item_ids, $existingIds);
if (count($missingIds) > 0) return \Yz::echoError1("部分自选项目不可用Id:" . implode(', ', $missingIds));
}
//如果有 多选一项目
if(!empty($Nx1_arrInfo)){
$buy_info['items']=array_merge($buy_info['items'],$Nx1_arrInfo);
}
$true_price = $price;
//如果是团检
$group_info = false;
if ($type == 2) {
$P = new PersonController();
$data = [
'电话号码' => null,
'证件号码' => null,
'预约Id' => $group_id
];
$group_info = $P->group_info($hospital_id, $data);
$group_info = $group_info[0];
$buy_info['group'] = [
'id' => $group_id,
'combo_name' => $group_info['combo_name'],
'combo_id' => $group_info['combo_id'],
'group_name' => $group_info['group_name'],
'items' => $group_info['items'],
'group_id' => $group_info['group_id'],
];
$TJ_Leixing_id=$group_info['checkup_type_id'];
$title = "单位团检" . $group_info['combo_name'];
$price = $price + $group_info['sixi_zong_ji_jin_e'];
$need_pay = ($price - $group_info['tongshou_xiane']) > 0 ? $price - $group_info['tongshou_xiane'] : 0;
//团检订单金额为减去统收后的金的
$price = $need_pay;
$true_price = $need_pay;
//如果有影像科则存储在nmr_list字段
$all_items = DB::table('items')->where(['status' => 1,'keshi_name'=>'影像科'])->get();
foreach ($group_info['items'] as $item) {
foreach ($all_items as $it) {
if ($it->item_id == $item['id']) {
$buy_info['nmr_list'][]=[
'item_id' => $item->item_id,
'name' => $item->name,
];
}
}
}
}
//调用思信接口判断各个项目是否可用
$check_items = [];
foreach ($item_ids as $item_id) {
$check_items[] = ['Id' => $item_id];
}
if ((isset($combo_id) and $combo_id <> 0) || count($check_items) != 0) {
$item_check = self::item_check($hospital_id, [
'人员信息列表' => [[
"序号" => 0,
"性别" => $person->sex == 1 ? '男' : '女',
"年龄" => floor((time() - strtotime($person->birthday)) / 86400 / 360),
"婚姻状态" => $person->married == 1 ? '已婚' : '未婚',
]],
'套餐Id' => $combo_id == 0 ? null : $combo_id,
'可选项目信息' => $check_items,
]);
if (count($item_check['data']) != 1) {
return \Yz::echoError1("体检系统提示:" . $item_check['message']);
}
}
//检查号源是否可用
$plan = new PlanController();
$plan_check = $plan->CheckPlan($plan_id, $hospital_id, $type, $person->sex, $price, $checkup_type_id);
if ($plan_check['status'] === false) return \Yz::echoError1($plan_check['msg']);
$plan = $plan_check['plan'];
//判断号源是否可用vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// $plan = DB::table('plans')->where(['id' => $plan_id, 'hospital_id' => $hospital_id, 'status' => 1, 'is_del' => 0])->first();
// if (!$plan) return \Yz::echoError1("号源不可用");
// //判断个检/团检类型
// if ($plan->use_type <> 0 and $plan->use_type <> $type) {
// $type_temp = '';
// if ($plan->use_type == 1) $type_temp = '个检';
// if ($plan->use_type == 2) $type_temp = '团检';
// return \Yz::echoError1("此号源为" . $type_temp . "号源,不可用");
// }
// //判断是否是预留号源
// if ($plan->type <> 1) return \Yz::echoError1("此号源为预留号源,不可用");
// //判断是否是vip
// //判断性别
// if ($plan->sex <> 0 and $plan->sex <> $person->sex) return \Yz::echoError1("此号源性别与体检人性别不符,不可用");
// //判断体检类型checkup_type
// //判断金额
// if ($plan->use_type == 1 and $plan->amount_limit1 <> 0) {
// if ($price < $plan->amount_limit1) return \Yz::echoError1("未达到此号源限制的金额,不可用");
// }
// if ($plan->use_type == 2 and $plan->amount_limit2 <> 0) {
// if ($price < $plan->amount_limit2) return \Yz::echoError1("未达到此号源限制的金额,不可用");
// }
// //判断时间是否过期
// $plan_datetime = $plan->date . ' ' . $plan->time;
// if ($plan_datetime < date('Y-m-d H:i:s')) return \Yz::echoError1("号源已过期,不可用");
//判断号源是否可用^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//如果是团检 判断号源在 团检登记人的有效时间范围内
$plan_datetime = $plan->date . ' ' . $plan->time;
if (!!$group_info) {
if (!($plan_datetime > $group_info['start_time'] . ' 00:00:00' and $plan_datetime < $group_info['end_time'] . ' 23:59:59')) {
return \Yz::echoError1("预约日期不在单位有效时间范围内,请重新选择");
}
}
//校验积分和预存款
$env=config('app.globals.Env');
$AspNet=new AspNetZhuanController();
if($env=='pro') { //如果是正式环境, 测试环境不抵扣
if($jifen>0) {
$all_jifen= $AspNet::GetJiFen_YuCunKuan(1,$person->ghzid);
if($jifen>$all_jifen) return \Yz::echoError1("用户剩余积分不足");
}
if($yucunkuan>0) {
// return \Yz::echoError1("暂不支持预存款");
$all_yucunkuan= $AspNet::GetJiFen_YuCunKuan(2,$person->ghzid);
if($yucunkuan>$all_yucunkuan) return \Yz::echoError1("用户剩余预存款不足");
}
$true_price=$true_price-($jifen+$yucunkuan);
if($true_price<-1) return \Yz::echoError1("预抵扣金额超过订单金额,操作失败");
if($true_price<0) $true_price=0;
}
$now_datetime=date('Y-m-d H:i:s');
//构建订单号
$order_num = $this->generateOrderNumber();
$data = [
'title' => $title,
'type' => $type,
'web_user_id' => $user->id,
'checkup_type_id'=>$TJ_Leixing_id,
'person_id' => $person->id,
'name' => $person->name,
'id_number' => $person->id_number,
'buy_info' => json_encode($buy_info, JSON_UNESCAPED_UNICODE),
'price' => $price,
'true_price' =>number_format($true_price, 2, '.', ''),
'jifen'=>$jifen,
'yucunkuan'=>$yucunkuan,
'order_number' => $order_num,
'status' => 1,
'appointment_date' => $plan->date,
'appointment_time' => $plan->time,
'plan_id' => $plan->id,
'plan_number' => $plan->plan_number,
'combo_id' => $combo_id,
'hospital_id' => $hospital_id,
'doctor' => $doctor,
'phone' => $person->phone,
'sex' => $person->sex,
'birthday' => $person->birthday,
'married' => $person->married,
'wj_flag'=>$wj_flag,
'created_at' =>$now_datetime,
];
DB::beginTransaction();
$insert = DB::table('orders')->insertGetId($data);
$up_plan = DB::table('plans')->where(['id' => $plan->id, 'status' => 1])->update([
'status' => 2
]);
//更新问卷log表
DB::table('questionnaires_logs')->where(['person_id'=>$person->id,'order_id'=>0])->update([
'order_id' => $insert,
]);
//调用接口扣除积分和预存款
$jifen_dikou_status=true;
$yucunkuan_dikou_status=true;
$yyid=$hospital_id;
if($yyid==1) $yyid=6;
if($env=='pro') { //如果是正式环境
if($jifen>0) {
$jifen_dikou_status=false;
$jifen_dikou_status= $AspNet::UseJiFen($person->ghzid,-$jifen,$yyid,$insert,'tj_h5','抵扣体检H5订单',$now_datetime);
}
if($yucunkuan>0) {
$yucunkuan_dikou_status=false;
$yucunkuan_dikou_status= $AspNet::UseYuCunKuan($person->ghzid,-$yucunkuan,$yyid,0,$insert,'tj_h5','抵扣体检H5订单',$now_datetime);
}
}
if ($insert and $up_plan and $jifen_dikou_status and $yucunkuan_dikou_status) {
DB::commit();
$action = false;
if ($true_price == 0) {
//如果是免费的,直接去预约
$yuyue = self::Finish($order_num);
if ($yuyue['status'] === true) {
return \Yz::return(true, "操作成功", ['action' => $action, 'orderid' => $insert]);
} else {
return \Yz::echoError1($yuyue['msg']);
}
}
if ($true_price > 0) {
//如果大于0则提示前端去支付
$action = "pay";
}
return \Yz::return(true, "操作成功", ['action' => $action, 'orderid' => $insert]);
} else {
DB::rollBack();
return \Yz::echoError1('操作失败');
}
}
//订单改约
public function ChangeAppointment()
{
$orderid = request('orderid');
$plan_id = request('planid');
$nmr_plan_id = request('nmrPlanid');
$doctor = request('doctor');
$orderInfo=DB::table('orders')->where(['id' => $orderid,'status'=>2])->first();
if(!$orderInfo) return \Yz::echoError1("未找到有效订单");
$planInfo = DB::table('plans')->where(['id' => $plan_id,'status'=>1])->first();
if(!$planInfo) return \Yz::echoError1("所选体检日期号源无效");
//判断核磁号源有效性能,日期范围是否正常,判断核磁新日期时间是否和旧的日期时间一样
//判断体检日期是否在核磁3天左右
//判断体检日期时间是否和旧的日期时间一样。一样则跳过,不一样则更新
if(isset($plan_id) && $plan_id<>$orderInfo->plan_id){
$peis = new PEISApiController();
$data="appointmentId=".$orderInfo->appointment_number."&appGroupId=66&appPlanId=".$plan_id."&appPlanNumber=".$planInfo->plan_number."&date=".urlencode($planInfo->date.' '.$planInfo->time);
$ch = $peis::Post2('修改用户预约时间', $peis::Api('修改用户预约时间',$data),$orderInfo->hospital_id,[]);
if($ch=='修改预约时刻保存成功'){
//恢复旧的plans
DB::table('plans')->where(['id' => $orderInfo->plan_id])->update(
['status'=>1]
);
//使用新的plans
DB::table('plans')->where(['id' => $plan_id])->update(
['status'=>2]
);
//更新订单
DB::table('orders')->where(['id' => $orderInfo->id])->update([
'plan_id'=>$plan_id,
'plan_number'=>$planInfo->plan_number,
'appointment_date'=>$planInfo->date,
'appointment_time'=>$planInfo->time,
'doctor'=>isset($doctor)?$doctor:null,
]);
}
return \Yz::Return(true,"操作完成",[]);
}
return \Yz::echoError1("未更改内容,无需进行此操作");
}
public function generateOrderNumber()
{
// 获取当前时间的时间戳(精确到毫秒)
$timestamp = round(microtime(true) * 1000);
// 生成一个随机数(可以根据需要调整长度)
$randomPart = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 6);
// 拼接时间戳和随机部分
$orderNumber = date("YmdHis", $timestamp / 1000) . substr($timestamp % 1000, -3) . $randomPart;
return $orderNumber;
}
public function item_check($hospital, $data)
{
$peis = new PEISApiController();
$check = $peis::Post('套餐项目检查', $hospital, $data);
return $check;
}
public function Finish_test() //删除!!!
{
$f = self::Finish('20240916154519911MbHwIE');
dd($f);
}
//最后步骤,开始通知思信预约
public function Finish($order_number)
{
$order_info = DB::table('orders')->where(['order_number' => $order_number])->first();
if (!$order_info) return ['status' => false, 'msg' => "未找到有效订单。"];
$buy_info = json_decode($order_info->buy_info, true);
$combo_id = $buy_info['combo']['id'];
$item_arr = [];
foreach ($buy_info['items'] as $item) {
$item_arr[] = ['Id' => $item['id'], '已收费' => true];
}
//调用思信 套餐项目检查
if ((isset($combo_id) and $combo_id <> 0) || count($item_arr) != 0) {
$item_check = self::item_check($order_info->hospital_id, [
'人员信息列表' => [[
"序号" => 0,
"性别" => $order_info->sex == 1 ? '男' : '女',
"年龄" => floor((time() - strtotime($order_info->birthday)) / 86400 / 360),
"婚姻状态" => $order_info->married == 1 ? '已婚' : '未婚',
]],
'套餐Id' => $combo_id == 0 ? null : $combo_id,
'可选项目信息' => $item_arr,
]);
if (count($item_check['data']) != 1) {
return ['status' => false, 'msg' => "体检系统提示:" . $item_check['message']];
}
}
//如果是个检
if ($order_info->type == 1) {
$cad = [
'type' => 1,
"姓名" => $order_info->name,
"性别" => $order_info->sex == 1 ? '男' : '女',
"年龄" => floor((time() - strtotime($order_info->birthday)) / 86400 / 360),
"婚姻状态" => $order_info->married == 1 ? '已婚' : '未婚',
"证件号码" => $order_info->id_number,
"电话号码" => $order_info->phone,
"预约时间" => $order_info->appointment_date . ' ' . $order_info->appointment_time,
"介绍人" => $order_info->referral,
'套餐Id' => $order_info->combo_id == 0 ? null : $order_info->combo_id,
"已收费" => true,
];
$cad2=[
"可选项目信息" => $item_arr,
"总计金额" => $order_info->price,
];
if($order_info->wj_flag == 1){
$temp=[];
foreach ($item_arr as $k => $item) {
$temp[]=[
"Id"=> $item['Id'],
"已收费"=>$item['已收费'],
"优惠方式"=>"打折",
"优惠值"=> config('app.globals.Wj_ZheKou')
];
}
$cad2=[
"可选项目信息" => $temp,
];
}
$cad=array_merge($cad,$cad2);
} else {
$cad = [
'type' => 2,
"预约Id" => $buy_info['group']['group_id'],
"预约时间" => $order_info->appointment_date . ' ' . $order_info->appointment_time,
'套餐Id' => null,
"可选项目信息" => $item_arr
];
}
//如果是 如果订单未支付 在这里更新订单状态为已支付。
DB::table('orders')->where(['order_number' => $order_number, 'status' => 1])->update([
'status' => 2,
'pay_time' => date('Y-m-d H:i:s'),
]);
//查询确认订单已经是支付状态
$cha = DB::table('orders')->where(['order_number' => $order_number, 'status' => 2])->first();
if (!$cha) return ['status' => false, 'msg' => "订单未支付,禁止预约"];
//把状态更新为支付后,然后再开始预约思信
$create_appointment = self::create_appointment($order_info->hospital_id, $cad);
if (!isset($create_appointment['data'][0][0])) return ['status' => false, 'msg' => "体检预约,返回非预期结果"];
//预约完成后查询预约结果
$appointment_info = self::appointment_info($order_info->hospital_id, [
'type' => $order_info->type,
"证件号码" => null,
"电话号码" => null,
"预约Id" => $create_appointment['data'][0][0],
]);
//如果是医生web端预约则调用预约时段修改接口传入医生名称
if ($order_info->source == 'web') {
$peis = new PEISApiController();
$dat = [
"预约Id" => $create_appointment['data'][0][0],
"预约开始时间" => $order_info->appointment_date . ' ' . $order_info->appointment_time,
"预约截止时间" => $order_info->appointment_date . ' ' . $order_info->appointment_time,
"AppDoctor" => $order_info->appdoctor
];
$info = $peis::Post('预约时段修改', $order_info->hospital_id,$dat);
}
$u=DB::table('orders')->where(['order_number' => $order_number])->update([
'appointment_number' => $create_appointment['data'][0][0],
'appointment_back_info' => json_encode($appointment_info['data'][0], JSON_UNESCAPED_UNICODE)
]);
$is_sendMsg=DB::table('configs')->where(['label' => '预约完成短信通知'])->first();
if(!!$is_sendMsg and $is_sendMsg->value==1){
Tools::SendMsg($cha->hospital_id,$cha->phone,$cha->name,$cha->appointment_date.' '.substr($cha->appointment_time, 0, 5));
}
return ['status' => true, 'msg' => "完成"];
}
public function create_appointment($hospital, $data)
{
$peis = new PEISApiController();
$url_code = $data['type'] == 1 ? '个检预约' : '团检预约';
unset($data['type']);
$info = $peis::Post($url_code, $hospital, $data);
return $info;
}
public function appointment_info($hospital, $data)
{
$peis = new PEISApiController();
$url_code = $data['type'] == 1 ? '个检预约查询' : '团检预约查询';
unset($data['type']);
$info = $peis::Post($url_code, $hospital, $data);
return $info;
}
public function cancel_appointment($hospital, $data)
{
$peis = new PEISApiController();
$url_code = $data['type'] == 1 ? '个检预约取消' : '团检预约取消';
unset($data['type']);
$info = $peis::Post($url_code, $hospital, $data);
return $info;
}
}