diff --git a/app/Http/Controllers/Notify/NotifyController.php b/app/Http/Controllers/Notify/NotifyController.php index ea959d7..059cc62 100644 --- a/app/Http/Controllers/Notify/NotifyController.php +++ b/app/Http/Controllers/Notify/NotifyController.php @@ -49,33 +49,9 @@ class NotifyController extends Controller // 建议是拿订单号调用微信支付查询接口, $this->info('接收回调消息', $message->toArray()); try{ - // 验证通过,业务处理 + // 验证签名通过,业务处理 $app->getValidator()->validate($app->getRequest()); - // 查询订单 - $response = $app->getClient()->postXml(V2Api::QUERY_ORDER->value, [ - 'body' => [ - 'appid' => config('wechat.payment.app_id'), - 'mch_id' => config('wechat.payment.mch_id'), - 'out_trade_no' => $message->out_trade_no - ] - ]); - if ($response->isFailed()) { - // 查询失败 - $this->warning('订单查询失败', [$message->out_trade_no]); - return $next($message); - } - - // 不成功 - if ( - !isset($response['return_code'], $response['result_code']) || - $response["return_code"] !== "SUCCESS" || - $response["result_code"] !== "SUCCESS" - ) { - $this->warning('订单查询支付失败', [$message->out_trade_no, $response]); - return $next($message); - } - // 业务处理 $result = $this->notify_logic->notifyHandle($message); diff --git a/app/Http/Controllers/Patient/PatientController.php b/app/Http/Controllers/Patient/PatientController.php index ae63596..22488c5 100644 --- a/app/Http/Controllers/Patient/PatientController.php +++ b/app/Http/Controllers/Patient/PatientController.php @@ -79,7 +79,7 @@ class PatientController /** * 设置默认状态 * @param Request $request - * @param string $patient_id + * @param string $patient_id 此处为 patient_number * @return JsonResponse * @throws GeneralException */ @@ -93,7 +93,7 @@ class PatientController /** * 删除 * @param Request $request - * @param string $patient_id + * @param string $patient_id 此处为 patient_number * @return JsonResponse * @throws GeneralException */ diff --git a/app/Http/Controllers/Registration/RecordController.php b/app/Http/Controllers/Registration/RecordController.php index bcec954..7b07a48 100644 --- a/app/Http/Controllers/Registration/RecordController.php +++ b/app/Http/Controllers/Registration/RecordController.php @@ -28,7 +28,7 @@ class RecordController /** * 获取挂号记录列表 * @param Request $request - * @param string $patient_id + * @param string $patient_id 此处为 patient_number * @return JsonResponse * @throws GeneralException */ @@ -51,7 +51,7 @@ class RecordController /** * 退号 * @param Request $request - * @param string $patient_id + * @param string $patient_id 此处为 patient_number * @param string $serial_no * @return JsonResponse * @throws GeneralException diff --git a/app/Http/Controllers/Registration/RegisterController.php b/app/Http/Controllers/Registration/RegisterController.php index 1e480c5..35547b8 100644 --- a/app/Http/Controllers/Registration/RegisterController.php +++ b/app/Http/Controllers/Registration/RegisterController.php @@ -26,7 +26,7 @@ class RegisterController /** * 获取挂号记录列表 * @param RegisterRequest $request - * @param string $patient_id + * @param string $patient_id 此处为 patient_number * @return JsonResponse * @throws GeneralException */ diff --git a/app/Http/Controllers/Registration/ScheduleController.php b/app/Http/Controllers/Registration/ScheduleController.php index f9ed962..2453a0d 100644 --- a/app/Http/Controllers/Registration/ScheduleController.php +++ b/app/Http/Controllers/Registration/ScheduleController.php @@ -32,10 +32,11 @@ class ScheduleController public function dept(Request $request): JsonResponse { $validated = $request->validate([ - 'date' => 'required|date_format:Y-m-d', + 'date' => 'required|date_format:Y-m-d|after_or_equal:today', ],[ 'date.required' => '请传入日期', 'date.date_format' => '日期格式错误', + 'date.after_or_equal' => '日期不能小于今天' ]); $response = $this->schedule_logic->getDeptLists($validated['date']); @@ -52,11 +53,12 @@ class ScheduleController public function doctor(Request $request): JsonResponse { $validated = $request->validate([ - 'date' => 'required|date_format:Y-m-d', + 'date' => 'required|date_format:Y-m-d||after_or_equal:today', 'dept_id' => 'required|numeric' ], [ 'date.required' => '请传入日期', 'date.date_format' => '日期格式错误', + 'date.after_or_equal' => '日期不能小于今天', 'dept_id.required' => '请传入科室ID', 'dept_id.numeric' => '科室ID格式错误', ]); diff --git a/app/Http/Logics/Notify/NotifyLogic.php b/app/Http/Logics/Notify/NotifyLogic.php index 72de1cc..bfc3242 100644 --- a/app/Http/Logics/Notify/NotifyLogic.php +++ b/app/Http/Logics/Notify/NotifyLogic.php @@ -24,8 +24,10 @@ use RedisException; use Exception; use ReflectionException; use UnifyPayment\Cores\Struct\ConfirmOrderForEx; +use UnifyPayment\Cores\Struct\QueryOrder; use UnifyPayment\Cores\Struct\RefundOrder; use UnifyPayment\Mock\ConfirmOrderForExHandler; +use UnifyPayment\Mock\QueryOrderHandler; use UnifyPayment\Mock\RefundOrderHandler; use UnifyPayment\Unify; @@ -64,6 +66,13 @@ class NotifyLogic */ public function notifyHandle(Message $notify): bool { + // 查询支付平台,订单是否正常 + $result = $this->unifyQuery($notify->out_trade_no); + if (!$result) { + return false; + } + + // 订单加锁,防止并发 $lock_id = $this->addLockOrder($notify->out_trade_no); if (!$lock_id) { return false; @@ -120,7 +129,6 @@ class NotifyLogic protected function registrationOrderHandle(OrderModel $order_info, Message $notify): void { // 挂号确认 - $patient = $order_info->patient; $record = $order_info->registrationRecord; $extra = json_decode($record->extra_info, true); $pay_time = strtotime($notify->time_end); @@ -132,7 +140,7 @@ class NotifyLogic $record->docttor_id, $record->reg_id, $extra['SHIFT']['RANKID'], - $record->date, + $record->visit_date, PayType::WECHAT_PAY->hisCode(), $order_info->order_id, '', @@ -145,18 +153,18 @@ class NotifyLogic $response = $this->his_client->registerConfirm(... $data); $this->info('挂号订单出入参:'.$order_info->order_id, [$data, $response]); - if (isset($response['RESULTCODE']) && $response['RESULTCODE'] === '0') { + if (isset($response['success']) && $response['success'] === true) { // 成功流程 - $order_info->orderConfirm($order_info->order_id, $response['VISITNO'], $response); + $order_info->orderConfirm($order_info->order_id, $response['visitNo'], $response); // 支付平台业务确认 $this->unifyConfirm($notify['out_trade_no'], $response['VISITNO'], $notify['openid'], $notify['transaction_id']); // 推送成功 $this->sendRegistrationSuccessMessage($order_info); - } else if (isset($response['RESULTCODE'])) { + } else if (isset($response['success'])) { // 失败流程 - $this->handleOrderReverse($order_info, $response['ERRORMSG'] ?? ''); + $this->handleOrderReverse($order_info, $response['msg'] ?? ''); // 推送失败 $this->sendRegistrationFailureMessage($order_info); @@ -175,7 +183,7 @@ class NotifyLogic * @param Message $notify * @throws GeneralException */ - protected function outpatientOrderHandle(OrderModel $order_info, Message $notify): void + public function outpatientOrderHandle(OrderModel $order_info, Message $notify): void { // 挂号确认 $patient = $order_info->patient; @@ -316,6 +324,31 @@ class NotifyLogic return $result; } + /** + * 支付平台业务查询 + * @param string $order_id + * @return bool + */ + protected function unifyQuery(string $order_id): bool + { + try { + $query_order = new QueryOrder($order_id); + $response = Unify::common(config('unify'))->order->setMockHandler([new QueryOrderHandler(true)])->query($query_order); + $this->info('支付平台查询结果', $response); + + if ($response['status'] === 200 && $response['success'] === true) { + return true; + } + + return false; + } catch (ReflectionException|Exception $e) { + $err_msg = "订单号:{$order_id}, 支付平台查询结果异常,错误消息:{$e->getMessage()} ON {$e->getFile()}:{$e->getLine()}"; + $this->error($err_msg); + + return false; + } + } + /** * 支付平台业务确认 * @param string $order_id @@ -331,7 +364,7 @@ class NotifyLogic $response = Unify::common(config('unify'))->order->setMockHandler([new ConfirmOrderForExHandler(true)])->confirmForEx($confirm_order); $this->info('支付平台确认结果', $response); - if ($response['status'] === 200 || $response['success'] === true) { + if ($response['status'] === 200 && $response['success'] === true) { return true; } diff --git a/app/Http/Logics/Outpatient/PaymentLogic.php b/app/Http/Logics/Outpatient/PaymentLogic.php index f1027d5..6fb19a5 100644 --- a/app/Http/Logics/Outpatient/PaymentLogic.php +++ b/app/Http/Logics/Outpatient/PaymentLogic.php @@ -181,8 +181,8 @@ class PaymentLogic $total_fee * 100, 0, $this->open_id, - $patient_info['PATIENTID'], - $patient_info['NAME'], + $patient_info['patientNumber'], + $patient_info['name'], $order_type, SourceId::MINI_PROGRAM, $pay_record_data diff --git a/app/Http/Logics/Patient/PatientLogic.php b/app/Http/Logics/Patient/PatientLogic.php index d39151b..cced0d8 100644 --- a/app/Http/Logics/Patient/PatientLogic.php +++ b/app/Http/Logics/Patient/PatientLogic.php @@ -51,19 +51,19 @@ class PatientLogic /** * 卡详情 - * @param string $patient_id + * @param string $patient_number * @return Patient * @throws GeneralException */ - public function getPatientDetails(string $patient_id): Patient + public function getPatientDetails(string $patient_number): Patient { - $info = $this->patient_model->getBindPatientInfoByPatientId($this->open_id, $patient_id); + $info = $this->patient_model->getBindPatientInfoByPatientNumber($this->open_id, $patient_number); if(empty($info)) { throw new GeneralException('找不到该就诊卡!'); } // 获取患者信息 - $response = $this->his_client->getPatientInfo($info['patient_id'], CardType::OUTPATIENT_NO, $info['name']); + $response = $this->his_client->getPatientInfo($info['patient_number'], CardType::OUTPATIENT_NO, $info['name']); if (!isset($response['success']) || !$response['success']) { throw new GeneralException($response['msg'] ?? '找不到该就诊卡!', Response::HTTP_SERVICE_UNAVAILABLE); } @@ -157,16 +157,17 @@ class PatientLogic throw new GeneralException('建档失败,失败原因:'. $response['msg'] ?? '未知错误', Response::HTTP_SERVICE_UNAVAILABLE); } - $patient_id = $response['response']['patientNumber']; + $patient_id = $response['response']['patientId']; + $patient_number = $response['response']['patientNumber']; // 写入数据库 - $result = $this->patient_model->createPatient($this->union_id, $this->open_id, $patient_id, $data['name'], $sex); + $result = $this->patient_model->createPatient($this->union_id, $this->open_id, $patient_id, $patient_number, $data['name'], $sex); if (!$result) { throw new GeneralException('数据保存失败,请重试!', Response::HTTP_INTERNAL_SERVER_ERROR); } - $this->sendBindPatientSubscribeMessage($result->id, $data['name']); + $this->sendBindPatientSubscribeMessage($result->id, $result->id, $data['name']); return $patient_id; } @@ -197,9 +198,11 @@ class PatientLogic } $patient_info = &$response['response']; + $patient_id = &$patient_info['response']['patientId']; + $patient_number = &$patient_info['response']['patientNumber']; $sex = Sex::from((int) $patient_info['SEX']); - if ($patient_info['patientNumber'] != $data['patient_id']) { + if ($patient_info['patientNumber'] != $data['patient_number']) { throw new GeneralException('该证件号已建档,但就诊卡号不匹配!'); } @@ -222,30 +225,30 @@ class PatientLogic } // 写入数据库 - $result = $this->patient_model->createPatient($this->union_id, $this->open_id, $patient_info['patientNumber'], $data['name'], $sex); + $result = $this->patient_model->createPatient($this->union_id, $this->open_id, $patient_id, $patient_number, $data['name'], $sex); if (!$result) { throw new GeneralException('数据保存失败,请重试!', Response::HTTP_INTERNAL_SERVER_ERROR); } $this->sendBindPatientSubscribeMessage($this->open_id, $result->id, $data['name']); - return $patient_info['patientNumber']; + return $patient_number; } /** * 设置默认就诊卡 - * @param string $patient_id + * @param string $patient_number * @return bool * @throws GeneralException */ - public function setDefaultPatient(string $patient_id): bool + public function setDefaultPatient(string $patient_number): bool { - $info = $this->patient_model->getBindPatientInfoByPatientId($this->open_id, $patient_id); + $info = $this->patient_model->getBindPatientInfoByPatientNumber($this->open_id, $patient_number); if (empty($info)) { throw new GeneralException('该就诊卡不存在!'); } - $result = $this->patient_model->setDefaultPatient($this->open_id, $patient_id); + $result = $this->patient_model->setDefaultPatient($this->open_id, $info->patient_id); if (!$result) { throw new GeneralException('设置失败,请稍后再试!', Response::HTTP_INTERNAL_SERVER_ERROR); } @@ -255,23 +258,23 @@ class PatientLogic /** * 解绑 - * @param string $patient_id + * @param string $patient_number * @return bool * @throws GeneralException */ - public function cancelBindPatient(string $patient_id): bool + public function cancelBindPatient(string $patient_number): bool { - $info = $this->patient_model->getBindPatientInfoByPatientId($this->open_id, $patient_id); + $info = $this->patient_model->getBindPatientInfoByPatientNumber($this->open_id, $patient_number); if (empty($info)) { throw new GeneralException('该就诊卡不存在!'); } - $result = $this->patient_model->deletePatient($this->open_id, $patient_id); + $result = $this->patient_model->deletePatient($this->open_id, $info->patient_id); if (!$result) { throw new GeneralException('解绑失败,请稍后再试!', Response::HTTP_INTERNAL_SERVER_ERROR); } - $this->sendUnbindPatientSubscribeMessage($this->open_id, $info->id, $info['name'], '', $info['patient_id']); + $this->sendUnbindPatientSubscribeMessage($this->open_id, $info->id, $info['name'], '', $patient_number); return true; } } diff --git a/app/Http/Logics/Registration/RecordLogic.php b/app/Http/Logics/Registration/RecordLogic.php index 907142f..bc0e1e6 100644 --- a/app/Http/Logics/Registration/RecordLogic.php +++ b/app/Http/Logics/Registration/RecordLogic.php @@ -8,6 +8,7 @@ use App\Dictionary\Order\SourceId; use App\Dictionary\Order\Type; use App\Exceptions\GeneralException; use App\Models\Order; +use App\Models\Patient; use App\Models\RegistrationRecord; use App\Services\HisHttp\Client; use App\Utils\Traits\Logger; @@ -28,6 +29,8 @@ class RecordLogic private RegistrationRecord $reg_record_model; + private Patient $patient_model; + private Order $order_model; /** @@ -40,19 +43,23 @@ class RecordLogic $this->setChannel('refund'); $this->his_client = app('HisHttpService'); $this->reg_record_model = new RegistrationRecord(); + $this->patient_model = new Patient(); $this->order_model = new Order(); } /** * 获取挂号记录列表 - * @param string $patient_id + * @param string $patient_number * @param string $start_date * @param string $end_date * @return array * @throws GeneralException */ - public function getRecordLists(string $patient_id, string $start_date, string $end_date): array + public function getRecordLists(string $patient_number, string $start_date, string $end_date): array { + $patient_info = $this->getPatientInfo($this->open_id, $patient_number); + $patient_id = $patient_info->patient_id; + $response = $this->his_client->getRegisterRecordLists($patient_id, $start_date, $end_date); if (!isset($response['RESULTCODE']) || $response['RESULTCODE'] !== '0') { @@ -66,13 +73,16 @@ class RecordLogic /** * 退号 - * @param string $patient_id + * @param string $patient_number * @param string $reg_serial_no * @return true * @throws GeneralException */ - public function refundRegisterRecord(string $patient_id, string $reg_serial_no): true + public function refundRegisterRecord(string $patient_number, string $reg_serial_no): true { + $patient_info = $this->getPatientInfo($this->open_id, $patient_number); + $patient_id = $patient_info->patient_id; + $cache_key = 'Registration.Record.'. $this->open_id.'.'. $patient_id; $record_info = Cache::get($cache_key); @@ -164,4 +174,21 @@ class RecordLogic $this->order_model->reverseOrderOpera($refund_order_id, $fee, true); return true; } + + /** + * 获取患者信息 + * @param string $open_id + * @param string $patient_number + * @return mixed + * @throws GeneralException + */ + protected function getPatientInfo(string $open_id, string $patient_number): mixed + { + $info = $this->patient_model->getBindPatientInfoByPatientNumber($open_id, $patient_number); + if (empty($info)) { + throw new GeneralException('找不到患者信息,请重新再试!', Response::HTTP_BAD_REQUEST); + } + + return $info; + } } diff --git a/app/Http/Logics/Registration/RegisterLogic.php b/app/Http/Logics/Registration/RegisterLogic.php index e505afd..f5cf043 100644 --- a/app/Http/Logics/Registration/RegisterLogic.php +++ b/app/Http/Logics/Registration/RegisterLogic.php @@ -13,7 +13,9 @@ use App\Models\Patient; use App\Services\HisHttp\Client; use App\Utils\Traits\Logger; use App\Utils\Traits\MiniProgramAuth; +use App\Utils\Traits\SendSubscribeMessage; use Illuminate\Auth\AuthenticationException; +use Illuminate\Support\Facades\Redis; use ReflectionException; use Symfony\Component\HttpFoundation\Response; use UnifyPayment\Cores\Exceptions\InvalidConfigException; @@ -26,6 +28,7 @@ class RegisterLogic { use Logger; use MiniProgramAuth; + use SendSubscribeMessage; private Client $his_client; @@ -47,7 +50,8 @@ class RegisterLogic } /** - * @param string $patient_id + * 挂号 + * @param string $patient_number * @param string $date * @param string $dept_id * @param string $doctor_id @@ -55,22 +59,25 @@ class RegisterLogic * @return array * @throws GeneralException */ - public function register(string $patient_id, string $date, string $dept_id, string $doctor_id, string $reg_id): array + public function register(string $patient_number, string $date, string $dept_id, string $doctor_id, string $reg_id): array { // 基础信息 - $patient_info = $this->getPatientInfo($patient_id, $this->open_id); + $patient_info = $this->getPatientInfo($this->open_id, $patient_number); $schedule_info = $this->getRegisterScheduleDetails($date, $dept_id, $doctor_id, $reg_id); - // 锁号? - // 创建订单 $order_type = $date === date('Y-m-d') ? Type::TODAY_REGISTRATION : Type::APPOINTMENT_REGISTRATION; $pay_type = PayType::WECHAT_PAY; $order_id = $this->order_model->getOrderId($pay_type, 'M'); - $reg_fee = (float)(string) $schedule_info['SHIFT']['FEE']; + $reg_fee = (float)(string) $schedule_info['scheduleInfo']['fee']; $order = $this->createOrder($order_id, $pay_type, $reg_fee, $order_type, $patient_info, $schedule_info); + // 挂号金额为 0 元 + if ($reg_fee === 0.0) { + return $this->freeRegistrationConfirm($order); + } + // 申请支付 $pay_data = $this->applyPayment($order_type, $order_id, $reg_fee, $patient_info['patientNumber'], $patient_info['name']); @@ -82,14 +89,14 @@ class RegisterLogic /** * 获取患者信息 - * @param string $patient_id * @param string $open_id + * @param string $patient_number * @return mixed * @throws GeneralException */ - protected function getPatientInfo(string $patient_id, string $open_id): mixed + protected function getPatientInfo(string $open_id, string $patient_number): mixed { - $info = $this->patient_model->getBindPatientInfo($open_id, $patient_id); + $info = $this->patient_model->getBindPatientInfoByPatientNumber($open_id, $patient_number); if (empty($info)) { throw new GeneralException('找不到患者信息,请重新再试!', Response::HTTP_BAD_REQUEST); } @@ -121,18 +128,17 @@ class RegisterLogic // 获取排班医生信息 $is_today = $dept_id === date('Y-m-d') ? '3' : '1'; $schedule_info = $this->his_client->getDoctorLists($dept_id, $is_today, '', $date); - if (!isset($schedule_info['RESULTCODE']) || $schedule_info['RESULTCODE'] !== '0') { - throw new GeneralException($schedule_info['ERRORMSG'] ?? '找不到该号源,请重新再试!', Response::HTTP_SERVICE_UNAVAILABLE); + if (!isset($schedule_info['success']) || !$schedule_info['success']) { + throw new GeneralException($schedule_info['msg'] ?? '找不到该号源,请重新再试!', Response::HTTP_SERVICE_UNAVAILABLE); } // 获取号源信息 - $schedule_info = xmlArrayToListByKey($schedule_info, 'ITEM'); - foreach ($schedule_info['ITEM'] as $v) { - if ($v['DOCTID'] === $doctor_id) { - $v = xmlArrayToListByKey($v, 'SHIFT'); - foreach ($v['SHIFT'] as $v2) { - if ($v2['REGID'] === $reg_id && $v2['FDATE'] === $date) { - $v['SHIFT'] = $v2; + foreach ($schedule_info['response'] as $v) { + if ($v['doctId'] === $doctor_id) { + foreach ($v['doctotVisitInfoList'] as $v2) { + if ($v2['regId'] === $reg_id && $v2['visitDate'] === $date) { + $v['scheduleInfo'] = $v2; + unset($v['doctotVisitInfoList']); $info = $v; } } @@ -143,21 +149,26 @@ class RegisterLogic throw new GeneralException('找不到该号源,请重新再试!', Response::HTTP_BAD_REQUEST); } - if (!isset($info['SHIFT']['REGCOUNT']) || $info['SHIFT']['REGCOUNT'] <= 0) { + if (!isset($info['scheduleInfo']['regCount']) || $info['scheduleInfo']['regCount'] <= 0) { throw new GeneralException('该号源已挂完,请重新选择号源!', Response::HTTP_BAD_REQUEST); } // 获取科室名称 - $dept_lists = $this->his_client->getDepType('', '','01', $date); - if (!isset($schedule_info['RESULTCODE']) || $schedule_info['RESULTCODE'] !== '0') { - throw new GeneralException($schedule_info['ERRORMSG'] ?? '找不到该号源,请重新再试!', Response::HTTP_SERVICE_UNAVAILABLE); + if (Redis::exists('departments.'. $date)) { + $dept_lists = Redis::get('departments.'. $date); + $dept_lists = json_decode($dept_lists, true); + } else { + $dept_lists = $this->his_client->getDepType('', '','01', $date); + + if (!isset($dept_lists['success']) || !$dept_lists['success']) { + throw new GeneralException($schedule_info['msg'] ?? '找不到该号源,请重新再试!', Response::HTTP_SERVICE_UNAVAILABLE); + } } - $dept_lists = xmlArrayToListByKey($dept_lists, 'ITEM'); - foreach ($dept_lists['ITEM'] as $v) { - if ($v['DEPID'] === $dept_id) { - $info['dept_id'] = $v['DEPID']; - $info['dept_name'] = $v['DEPNAME']; + foreach ($dept_lists['response'] as $v) { + if ($v['typeId'] === $dept_id) { + $info['dept_id'] = $v['typeId']; + $info['dept_name'] = $v['typeName']; } } @@ -181,15 +192,15 @@ class RegisterLogic // 挂号记录表 $reg_record_data = [ 'relate_patient_id' => $patient_info['id'], - 'reg_id' => $schedule_info['SHIFT']['REGID'], + 'reg_id' => $schedule_info['scheduleInfo']['regId'], 'dept_id' => $schedule_info['dept_id'], 'dept_name' => $schedule_info['dept_name'], - 'dept_location' => $schedule_info['DEPLOCATION'], - 'doctor_id' => $schedule_info['DOCTID'], - 'doctor_name' => $schedule_info['DOCTNAME'], - 'visit_date' => date('Y-m-d', strtotime($schedule_info['SHIFT']['FDATE'])), - 'begin_time' => $schedule_info['SHIFT']['STARTTIME'], - 'end_time' => $schedule_info['SHIFT']['ENDTIME'], + 'dept_location' => '', + 'doctor_id' => $schedule_info['doctId'], + 'doctor_name' => $schedule_info['doctName'], + 'visit_date' => date('Y-m-d', strtotime($schedule_info['scheduleInfo']['visitDate'])), + 'begin_time' => $schedule_info['scheduleInfo']['startTime'], + 'end_time' => $schedule_info['scheduleInfo']['endTime'], 'lock_status' => 0, 'extra_info' => json_encode($schedule_info, JSON_UNESCAPED_UNICODE), ]; @@ -201,8 +212,8 @@ class RegisterLogic $reg_fee * 100, 0, $this->open_id, - $patient_info['PATIENTID'], - $patient_info['NAME'], + $patient_info['patientId'], + $patient_info['name'], $order_type, SourceId::MINI_PROGRAM, $reg_record_data @@ -215,6 +226,58 @@ class RegisterLogic return $order; } + /** + * 免费挂号确认 + * @param Order $order + * @return array + * @throws GeneralException + */ + protected function freeRegistrationConfirm(Order $order): array + { + // 挂号确认 + $record = &$order->registrationRecord; + $extra = json_decode($record->extra_info, true); + + $data = [ + $order->patient_id, + $order->patient_name, + $record->dept_id, + $record->doctor_id, + $record->reg_id, + $extra['scheduleInfo']['rankId'], + $record->visit_date, + PayType::WECHAT_PAY->hisCode(), + $order->order_id, + '', + '', + '', + '', + '0', + '' + ]; + $response = $this->his_client->registerConfirm(... $data); + $this->info('挂号订单出入参:'.$order->order_id, [$data, $response]); + + if (isset($response['success']) && $response['success'] === true) { + // 成功流程 + $order->orderConfirm($order->order_id, $response['response']['visitNo'], $response['response']); + + // 推送成功 + $this->sendRegistrationSuccessMessage($order); + + // 返回数据 + return [ + 'order_id' => $order->order_id, + 'reg_serial_no' => $response['response']['visitNo'] + ]; + } else { + // 推送失败 + $this->sendRegistrationFailureMessage($order); + + throw new GeneralException('挂号失败,失败原因:'. ($response['msg'] ?? '数据异常'). ',请重新再试!'); + } + } + /** * 申请支付 * @param Type $order_type @@ -242,7 +305,7 @@ class RegisterLogic $response = Unify::pay(config('unify'))->mini->setMockHandler([new CreateOrderHandler(true)])->jsapi($order_obj); $this->info('jsapi 支付参数', $response); - if (!$response['success'] || empty($response['response'])) { + if (!$response['success'] && empty($response['response'])) { throw new GeneralException('申请支付失败,请重新再试!', Response::HTTP_SERVICE_UNAVAILABLE); } diff --git a/app/Http/Logics/Registration/ScheduleLogic.php b/app/Http/Logics/Registration/ScheduleLogic.php index b4a0ced..4f9cd70 100644 --- a/app/Http/Logics/Registration/ScheduleLogic.php +++ b/app/Http/Logics/Registration/ScheduleLogic.php @@ -6,6 +6,7 @@ namespace App\Http\Logics\Registration; use App\Exceptions\GeneralException; use App\Services\HisHttp\Client; use App\Utils\Traits\Logger; +use Illuminate\Support\Facades\Redis; use Symfony\Component\HttpFoundation\Response; class ScheduleLogic @@ -36,6 +37,8 @@ class ScheduleLogic throw new GeneralException($response['msg'] ?? '暂无科室排班!', Response::HTTP_SERVICE_UNAVAILABLE); } + Redis::setex('departments.'. $date, 2 * 3600, json_encode($response, JSON_UNESCAPED_UNICODE)); + return $response; } diff --git a/app/Http/Requests/Registration/RegisterRequest.php b/app/Http/Requests/Registration/RegisterRequest.php index 72122ce..9dc4d59 100644 --- a/app/Http/Requests/Registration/RegisterRequest.php +++ b/app/Http/Requests/Registration/RegisterRequest.php @@ -28,7 +28,7 @@ class RegisterRequest extends FormRequest public function rules(): array { return [ - 'date' => 'required|date_format:Y-m-d', + 'date' => 'required|date_format:Y-m-d||after_or_equal:today', 'dept_id' => 'required', 'doctor_id' => 'required', 'reg_id' => 'required' @@ -44,6 +44,7 @@ class RegisterRequest extends FormRequest return [ 'date.required' => '必须选择挂号日期', 'date.date_format' => '必须选择挂号日期', + 'date.after_or_equal' => '挂号日期不得小于今天', 'dept_id.required' => '必须选择挂号科室', 'doctor_id.required' => '必须选择挂号医生', 'reg_id.required' => '必须选择挂号时间段', diff --git a/app/Http/Resources/Patient/PatientDetailsResource.php b/app/Http/Resources/Patient/PatientDetailsResource.php index 555f716..fde6190 100644 --- a/app/Http/Resources/Patient/PatientDetailsResource.php +++ b/app/Http/Resources/Patient/PatientDetailsResource.php @@ -15,7 +15,7 @@ class PatientDetailsResource extends JsonResource public function toArray(Request $request = null): array { return [ - 'patient_id' => $this->resource['patient_id'], + 'patient_id' => $this->resource['patient_number'], 'patient_name' => $this->resource['name'], // 'card_no' => $this->resource['card_no'], 'sex' => $this->resource['sex'], diff --git a/app/Http/Resources/Patient/PatientListsResource.php b/app/Http/Resources/Patient/PatientListsResource.php index 0829fa6..7f77c1a 100644 --- a/app/Http/Resources/Patient/PatientListsResource.php +++ b/app/Http/Resources/Patient/PatientListsResource.php @@ -17,7 +17,7 @@ class PatientListsResource extends JsonResource $lists = []; foreach ($this->resource as $v) { $lists[] = [ - 'patient_id' => $v['patient_id'], + 'patient_id' => $v['patient_number'], 'patient_name' => $v['name'], 'is_default' => $v['def_status'] ]; diff --git a/app/Http/Resources/Registration/Schedule/DeptListsResource.php b/app/Http/Resources/Registration/Schedule/DeptListsResource.php index 489789b..23c5280 100644 --- a/app/Http/Resources/Registration/Schedule/DeptListsResource.php +++ b/app/Http/Resources/Registration/Schedule/DeptListsResource.php @@ -4,6 +4,8 @@ namespace App\Http\Resources\Registration\Schedule; use Illuminate\Http\Request; use Illuminate\Http\Resources\Json\JsonResource; +use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Redis; class DeptListsResource extends JsonResource { @@ -14,10 +16,12 @@ class DeptListsResource extends JsonResource */ public function toArray(Request $request = null): array { - $this->resource = xmlArrayToListByKey($this->resource, 'ITEM'); + $department_lists = $this->getDepartmentLists(); + $sort = collect($department_lists)->pluck('sort', 'dept_id'); + $lists = []; - foreach ($this->resource['ITEM'] as $v) { + foreach ($this->resource['response'] as $v) { $lists[] = [ 'dept_id' => $v['typeId'], 'dept_name' => $v['typeName'], @@ -25,6 +29,36 @@ class DeptListsResource extends JsonResource ]; } + // 根据科室的 sort 字段对 $lists 进行排序 + usort($lists, function ($a, $b) use ($sort) { + $sort_a = $sort[$a['dept_id']] ?? 0; + $sort_b = $sort[$b['dept_id']] ?? 0; + return $sort_b <=> $sort_a; // 倒序排序 + }); + return $lists; } + + /** + * 获取医生列表 + * @return array + */ + public function getDepartmentLists(): array + { + if (Redis::exists('department.lists')) { + $department_lists = Redis::get('doctor.lists'); + $department_lists = json_decode($department_lists, true); + } else { + $db = DB::connection('mysql_admin')->table('departments'); + $department_lists = $db + ->where('is_enable', 1) + ->orderBy('sort', 'DESC') + ->orderBy('id', 'ASC') + ->get(); + + Redis::setex('department.lists', 4 * 3600, json_encode($department_lists, JSON_UNESCAPED_UNICODE)); + } + + return $department_lists; + } } diff --git a/app/Http/Resources/Registration/Schedule/DoctorListsResource.php b/app/Http/Resources/Registration/Schedule/DoctorListsResource.php index 50ae98c..3796a09 100644 --- a/app/Http/Resources/Registration/Schedule/DoctorListsResource.php +++ b/app/Http/Resources/Registration/Schedule/DoctorListsResource.php @@ -4,6 +4,8 @@ namespace App\Http\Resources\Registration\Schedule; use Illuminate\Http\Request; use Illuminate\Http\Resources\Json\JsonResource; +use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Redis; class DoctorListsResource extends JsonResource { @@ -14,35 +16,66 @@ class DoctorListsResource extends JsonResource */ public function toArray(Request $request = null): array { - $this->resource = xmlArrayToListByKey($this->resource, 'ITEM'); + $doctor_lists = $this->getDoctorLists(); + $specialty = collect($doctor_lists)->pluck('specialty', 'doctor_id'); + $sort = collect($doctor_lists)->pluck('sort', 'doctor_id'); $lists = []; - foreach ($this->resource['ITEM'] as $k=>$v) { + foreach ($this->resource['response'] as $k=>$v) { $lists[$k] = [ - 'doctor_id' => $v['DOCTID'], - 'doctor_name' => $v['DOCTNAME'], - 'doctor_title' => $v['TYPENAME'], - 'doctor_intro' => $v['DEPLOCATION'], - 'is_doctor' => (int) $v['ISKSDOC'], + 'doctor_id' => $v['doctId'], + 'doctor_name' => $v['doctName'], + 'doctor_title' => $v['docTitle'], + 'doctor_intro' => $specialty[$v['doctId']] ?? ($v['depLocation'] ?: '暂无介绍'), + 'is_doctor' => (int) $v['isksDoc'], ]; - $v = xmlArrayToListByKey($v, 'SHIFT'); - foreach ($v['SHIFT'] as $k2=>$v2) { + foreach ($v['doctotVisitInfoList'] as $k2 => $v2) { $lists[$k]['schedule_lists'][$k2] = [ - 'reg_id' => $v2['REGID'], - 'date' => $v2['FDATE'], - 'rank_id' => $v2['RANKID'], - 'rank_name' => $v2['RANKNAME'], - 'start_time' => $v2['STARTTIME'], - 'end_time' => $v2['ENDTIME'], - 'fee' => $v2['FEE'], - 'fee_code' => $v2['FEECODE'], - 'reg_count' => $v2['REGCOUNT'], - 'no_visit_count' => $v2['JZCOUNT'], + 'reg_id' => $v2['regId'], + 'date' => $v2['visitDate'], + 'rank_id' => $v2['rankId'], + 'rank_name' => $v2['rankName'], + 'start_time' => $v2['startTime'], + 'end_time' => $v2['endTime'], + 'fee' => (float) $v2['fee'], + 'fee_code' => $v2['feeCode'], + 'reg_count' => (int) $v2['regCount'], + 'no_visit_count' => (int) $v2['noVisits'], ]; } } + // 根据医生的 sort 字段对 $lists 进行排序 + usort($lists, function ($a, $b) use ($sort) { + $sort_a = $sort[$a['doctor_id']] ?? 0; + $sort_b = $sort[$b['doctor_id']] ?? 0; + return $sort_b <=> $sort_a; // 倒序排序 + }); + return $lists; } + + /** + * 获取医生列表 + * @return array + */ + public function getDoctorLists(): array + { + if (Redis::exists('doctor.lists')) { + $doctor_lists = Redis::get('doctor.lists'); + $doctor_lists = json_decode($doctor_lists, true); + } else { + $db = DB::connection('mysql_admin')->table('doctors'); + $doctor_lists = $db + ->where('is_enable', 1) + ->orderBy('sort', 'DESC') + ->orderBy('id', 'ASC') + ->get(); + + Redis::setex('doctor.lists', 4 * 3600, json_encode($doctor_lists, JSON_UNESCAPED_UNICODE)); + } + + return $doctor_lists; + } } diff --git a/app/Models/Order.php b/app/Models/Order.php index 6c86342..bca7985 100644 --- a/app/Models/Order.php +++ b/app/Models/Order.php @@ -33,6 +33,7 @@ class Order extends Model */ protected $fillable = [ 'relate_id', + 'relate_patient_id', 'order_id', 'his_order_id', 'transaction_id', @@ -289,7 +290,7 @@ class Order extends Model $extra_info = json_decode($record->extra_info, true); $extra_info['confirm_response'] = $response; - $record->update(['extra_info' => json_encode($extra_info, JSON_UNESCAPED_UNICODE)]); + $record->update(['dept_location' => $response['depLocation'], 'extra_info' => json_encode($extra_info, JSON_UNESCAPED_UNICODE)]); break; case Type::OUTPATIENT_PAYMENT->value: $record = $order->outpatientPaymentRecord; diff --git a/app/Models/Patient.php b/app/Models/Patient.php index 59c918e..55cf418 100644 --- a/app/Models/Patient.php +++ b/app/Models/Patient.php @@ -28,6 +28,7 @@ class Patient extends Model 'union_id', 'open_id', 'patient_id', + 'patient_number', 'card_type', 'card_no', 'name', @@ -128,6 +129,17 @@ class Patient extends Model return $this->where('open_id', $open_id)->where('patient_id', $patient_id)->first(); } + /** + * 获取绑定患者信息By number + * @param string $open_id + * @param string $patient_number + * @return mixed + */ + public function getBindPatientInfoByPatientNumber(string $open_id, string $patient_number): mixed + { + return $this->where('open_id', $open_id)->where('patient_number', $patient_number)->first(); + } + /** * 获取绑定患者信息By Patient Id * @param string $patient_id @@ -144,16 +156,18 @@ class Patient extends Model * @param string $union_id * @param string $open_id * @param string $patient_id + * @param string $patient_number * @param string $name * @param Sex $gender * @return mixed */ - public function createPatient(string $union_id, string $open_id, string $patient_id, string $name, Sex $gender): mixed + public function createPatient(string $union_id, string $open_id, string $patient_id, string $patient_number, string $name, Sex $gender): mixed { $data = [ 'union_id' => $union_id, 'open_id' => $open_id, 'patient_id' => $patient_id, + 'patient_number' => $patient_number, 'card_type' => 0, 'card_no' => '', 'name' => $name, diff --git a/app/Services/HisHttp/Client.php b/app/Services/HisHttp/Client.php index 5bbfe00..9347ff2 100644 --- a/app/Services/HisHttp/Client.php +++ b/app/Services/HisHttp/Client.php @@ -58,6 +58,10 @@ class Client */ protected function requestHandle(string $method_name, string $request_name, array $params): mixed { + //if ($request_name === 'PayRegTrade') { + dd(json_encode($params['json'], JSON_UNESCAPED_UNICODE)); + //} + try { return $this->service ->transferMethod($method_name, $request_name, $params) diff --git a/app/Utils/Traits/RedisLockUtil.php b/app/Utils/Traits/RedisLockUtil.php index 1d2f9bf..cc50617 100644 --- a/app/Utils/Traits/RedisLockUtil.php +++ b/app/Utils/Traits/RedisLockUtil.php @@ -3,7 +3,9 @@ declare(strict_types = 1); namespace App\Utils\Traits; -use RedisException; +use Illuminate\Support\Facades\Log; +use Illuminate\Support\Facades\Redis; +use Illuminate\Support\Str; trait RedisLockUtil { @@ -12,36 +14,41 @@ trait RedisLockUtil * 加锁 * @param string $lock_str 锁字符串 * @param int $expire_time 超时时间,默认300秒 - * @return false|string - * @throws RedisException + * @return bool|string */ public function addLock(string $lock_str, int $expire_time = 300): bool|string { - $redis = app('redis'); - - $unique_id = $this->getUniqueLockId(); - $result = $redis->set($lock_str, $unique_id, 'ex', $expire_time, 'nx'); - - return $result ? $unique_id : false; + try { + $unique_id = $this->getUniqueLockId(); + $result = Redis::set($lock_str, $unique_id, 'ex', $expire_time, 'nx'); + + return $result ? $unique_id : false; + } catch (\Exception $e) { + Log::channel('genera_error')->error("Error while acquiring lock for {$lock_str}: " . $e->getMessage()); + return false; + } } + /** * 解锁 * @param string $lock_str 锁字符串 * @param string $unique_id 唯一锁ID * @return bool - * @throws RedisException */ public function unlock(string $lock_str, string $unique_id): bool { - $redis = app('redis'); - - $redis->watch($lock_str); - if ($unique_id == $redis->get($lock_str)) { - $redis->multi()->del($lock_str)->exec(); - return true; + try { + Redis::watch($lock_str); + if (Redis::exists($lock_str) && $unique_id == Redis::get($lock_str)) { + Redis::multi()->del($lock_str)->exec(); + return true; + } + Redis::unwatch(); + return false; + } catch (\Exception $e) { + Log::channel('genera_error')->error("Error while releasing lock for {$lock_str}: " . $e->getMessage()); + return false; } - $redis->unwatch(); - return false; } /** @@ -50,6 +57,6 @@ trait RedisLockUtil */ protected function getUniqueLockId(): string { - return md5(uniqid((string)mt_rand(), true)); + return Str::uuid()->toString(); } } diff --git a/app/Utils/Traits/SendSubscribeMessage.php b/app/Utils/Traits/SendSubscribeMessage.php index ec944d2..e50a16d 100644 --- a/app/Utils/Traits/SendSubscribeMessage.php +++ b/app/Utils/Traits/SendSubscribeMessage.php @@ -13,7 +13,7 @@ use App\Models\SendMessageJob; trait SendSubscribeMessage { - protected static SendMessageJob $message_model; + protected static ?SendMessageJob $message_model = null; /** * 单例获取 SendMessageJob @@ -46,7 +46,7 @@ trait SendSubscribeMessage 'time2' => ['value' => date('Y-m-d H:i')], 'thing3' => ['value' => '您已绑定成功,可以进行线上线下就医服务。'], ], - 'miniprogram_state' => env('custom.mini_program_message_state') + 'miniprogram_state' => config('custom.mini_program_message_state') ]; $message = self::getSendMessageJob()->insertMessageJobs(0, $relate_patient_id, Type::SINGLE_SUBSCRIBE, $subscribe_id, $data, ''); @@ -77,7 +77,7 @@ trait SendSubscribeMessage 'character_string5' => ['value' => $inpatient_id], 'character_string6' => ['value' => $patient_id], ], - 'miniprogram_state' => env('custom.mini_program_message_state') + 'miniprogram_state' => config('custom.mini_program_message_state') ]; $message = self::getSendMessageJob()->insertMessageJobs(0, $relate_patient_id, Type::SINGLE_SUBSCRIBE, $subscribe_id, $data); @@ -106,10 +106,10 @@ trait SendSubscribeMessage 'thing6' => ['value' => $record->dept_location], 'thing5' => ['value' => '请准时前往医院就诊。'], ], - 'miniprogram_state' => env('custom.mini_program_message_state') + 'miniprogram_state' => config('custom.mini_program_message_state') ]; - $message = self::getSendMessageJob()->insertMessageJobs(0, $order->relate_patient_id, Type::SINGLE_SUBSCRIBE, $subscribe_id, $data, ''); + $message = self::getSendMessageJob()->insertMessageJobs($order->id, $order->relate_patient_id, Type::SINGLE_SUBSCRIBE, $subscribe_id, $data, ''); SendWeChatMessageJob::dispatch($message); } @@ -121,6 +121,8 @@ trait SendSubscribeMessage */ public function sendRegistrationSuccessMessage(OrderModel $order): void { + // 重新强关联,避免缓存 + $order->load('registrationRecord'); $record = &$order->registrationRecord; $subscribe_id = SubscribeId::REGISTRATION_SUCCESS; $visit_time = $record->visit_date . ' '. $record->begin_time . '~'. $record->end_time; @@ -135,10 +137,10 @@ trait SendSubscribeMessage 'thing19' => ['value' => $record->doctor_name], 'amount13' => ['value' => $order->fee / 100], ], - 'miniprogram_state' => env('custom.mini_program_message_state') + 'miniprogram_state' => config('custom.mini_program_message_state') ]; - $message = self::getSendMessageJob()->insertMessageJobs(0, $order->relate_patient_id, Type::SINGLE_SUBSCRIBE, $subscribe_id, $data, ''); + $message = self::getSendMessageJob()->insertMessageJobs($order->id, $order->relate_patient_id, Type::SINGLE_SUBSCRIBE, $subscribe_id, $data, ''); SendWeChatMessageJob::dispatch($message); } @@ -150,6 +152,8 @@ trait SendSubscribeMessage */ public function sendRegistrationFailureMessage(OrderModel $order): void { + // 重新强关联,避免缓存 + $order->load('registrationRecord'); $record = &$order->registrationRecord; $subscribe_id = SubscribeId::REGISTRATION_FAILURE; $visit_time = $record->visit_date . ' '. $record->begin_time . '~'. $record->end_time; @@ -164,10 +168,10 @@ trait SendSubscribeMessage 'time4' => ['value' => $visit_time], 'amount13' => ['value' => $order->fee / 100], ], - 'miniprogram_state' => env('custom.mini_program_message_state') + 'miniprogram_state' => config('custom.mini_program_message_state') ]; - $message = self::getSendMessageJob()->insertMessageJobs(0, $order->relate_patient_id, Type::SINGLE_SUBSCRIBE, $subscribe_id, $data, ''); + $message = self::getSendMessageJob()->insertMessageJobs($order->id, $order->relate_patient_id, Type::SINGLE_SUBSCRIBE, $subscribe_id, $data, ''); SendWeChatMessageJob::dispatch($message); } @@ -179,6 +183,8 @@ trait SendSubscribeMessage */ public function sendRegistrationCancelMessage(OrderModel $order): void { + // 重新强关联,避免缓存 + $order->load('registrationRecord'); $record = &$order->registrationRecord; $subscribe_id = SubscribeId::REGISTRATION_CANCEL; $visit_time = $record->visit_date . ' '. $record->begin_time . '~'. $record->end_time; @@ -193,7 +199,7 @@ trait SendSubscribeMessage 'time4' => ['value' => $visit_time], 'thing5' => ['value' => '已成功取消预约,如有需要请重新预约。'], ], - 'miniprogram_state' => env('custom.mini_program_message_state') + 'miniprogram_state' => config('custom.mini_program_message_state') ]; $message = self::getSendMessageJob()->insertMessageJobs(0, $order->relate_patient_id, Type::SINGLE_SUBSCRIBE, $subscribe_id, $data, ''); @@ -208,7 +214,9 @@ trait SendSubscribeMessage */ public function sendOutpatientPaymentSuccessMessage(OrderModel $order): void { - $record = &$order->outpatientPaymentRecord; + // 重新强关联,避免缓存 +// $order->load('outpatientPaymentRecord'); +// $record = &$order->outpatientPaymentRecord; $subscribe_id = SubscribeId::OUTPATIENT_PAYMENT_SUCCESS; $data = [ 'touser' => $order->open_id, @@ -221,10 +229,10 @@ trait SendSubscribeMessage 'character_string14' => ['value' => $order->patient_id], 'thing9' => ['value' => '门诊缴费'], ], - 'miniprogram_state' => env('custom.mini_program_message_state') + 'miniprogram_state' => config('custom.mini_program_message_state') ]; - $message = self::getSendMessageJob()->insertMessageJobs(0, $order->relate_patient_id, Type::SINGLE_SUBSCRIBE, $subscribe_id, $data, ''); + $message = self::getSendMessageJob()->insertMessageJobs($order->id, $order->relate_patient_id, Type::SINGLE_SUBSCRIBE, $subscribe_id, $data, ''); SendWeChatMessageJob::dispatch($message); } @@ -236,7 +244,8 @@ trait SendSubscribeMessage */ public function sendOutpatientPaymentFailureMessage(OrderModel $order): void { - $record = &$order->outpatientPaymentRecord; +// $order->load('outpatientPaymentRecord'); +// $record = &$order->outpatientPaymentRecord; $subscribe_id = SubscribeId::OUTPATIENT_PAYMENT_FAILURE; $data = [ 'touser' => $order->open_id, @@ -250,10 +259,10 @@ trait SendSubscribeMessage 'amount4' => ['value' => $order->fee / 100], 'date6' => ['value' => date('Y-m-d')], ], - 'miniprogram_state' => env('custom.mini_program_message_state') + 'miniprogram_state' => config('custom.mini_program_message_state') ]; - $message = self::getSendMessageJob()->insertMessageJobs(0, $order->relate_patient_id, Type::SINGLE_SUBSCRIBE, $subscribe_id, $data, ''); + $message = self::getSendMessageJob()->insertMessageJobs($order->id, $order->relate_patient_id, Type::SINGLE_SUBSCRIBE, $subscribe_id, $data, ''); SendWeChatMessageJob::dispatch($message); } diff --git a/app/Utils/Transfer/HisHttpClient/ClientMockHttpTransfer.php b/app/Utils/Transfer/HisHttpClient/ClientMockHttpTransfer.php index d98b068..640cd8b 100644 --- a/app/Utils/Transfer/HisHttpClient/ClientMockHttpTransfer.php +++ b/app/Utils/Transfer/HisHttpClient/ClientMockHttpTransfer.php @@ -48,6 +48,7 @@ class ClientMockHttpTransfer extends HttpTransferAbstract 'GetCardInfo' => $this->mockGetPatientInfo($request_data), 'GetDepType' => $this->mockGetDepLists($request_data), 'GetDoctList' => $this->mockGetDoctorLists($request_data), + 'PayRegTrade' => $this->mockConfirmRegister($request_data), 'GetGHMXList' => $this->mockGetRegisterRecordLists($request_data), 'GHCancelCheck' => $this->mockCheckRefundRegisterStatus($request_data), 'GHCancelConfirm' => $this->mockRefundRegister($request_data), @@ -134,7 +135,15 @@ class ClientMockHttpTransfer extends HttpTransferAbstract private function mockGetDoctorLists(array $params): self { $date = &$params['json']['date']; - $this->transfer_response = '0Success1000120001张三内科一诊室主任医师11000130001'.$date.'1上午班08:0012:0050.0000120151000130002'.$date.'2下午班14:0018:0055.0000218121000130003'.$date.'3夜班20:0000:0060.00003108XM0011234567890挂号诊查费50105001000220002李四外科二诊室副主任医师01000230004'.$date.'1上午班08:0012:0060.0000425201000230005'.$date.'2下午班14:0018:0065.000052018XM0020987654321挂号诊查费100151500'; + $this->transfer_response = '{"status":200,"success":true,"msg":"成功","msgDev":null,"response":[{"doctId":"10488","doctName":"梁燕华","docTitle":"副主任医师","depLocation":"","isksDoc":"1","doctotVisitInfoList":[{"doctId":"10488","regId":"916601","rankId":"1","rankName":"上午","startTime":"08:00","endTime":"08:30","fee":"0","feeCode":"","regCount":"4","noVisits":"0","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10488","regId":"916602","rankId":"1","rankName":"上午","startTime":"08:30","endTime":"09:00","fee":"0","feeCode":"","regCount":"3","noVisits":"0","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10488","regId":"916603","rankId":"1","rankName":"上午","startTime":"09:00","endTime":"09:30","fee":"0","feeCode":"","regCount":"3","noVisits":"0","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10488","regId":"916604","rankId":"1","rankName":"上午","startTime":"09:30","endTime":"10:00","fee":"0","feeCode":"","regCount":"3","noVisits":"0","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10488","regId":"916605","rankId":"1","rankName":"上午","startTime":"10:00","endTime":"10:30","fee":"0","feeCode":"","regCount":"1","noVisits":"0","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10488","regId":"916606","rankId":"1","rankName":"上午","startTime":"10:30","endTime":"11:00","fee":"0","feeCode":"","regCount":"3","noVisits":"0","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10488","regId":"916607","rankId":"1","rankName":"上午","startTime":"11:00","endTime":"11:30","fee":"0","feeCode":"","regCount":"4","noVisits":"0","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10488","regId":"916608","rankId":"1","rankName":"上午","startTime":"11:30","endTime":"12:00","fee":"0","feeCode":"","regCount":"5","noVisits":"0","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10488","regId":"916609","rankId":"2","rankName":"下午","startTime":"14:00","endTime":"14:30","fee":"0","feeCode":"","regCount":"4","noVisits":"0","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10488","regId":"916610","rankId":"2","rankName":"下午","startTime":"14:30","endTime":"15:00","fee":"0","feeCode":"","regCount":"4","noVisits":"0","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10488","regId":"916611","rankId":"2","rankName":"下午","startTime":"15:00","endTime":"15:30","fee":"0","feeCode":"","regCount":"4","noVisits":"0","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10488","regId":"916612","rankId":"2","rankName":"下午","startTime":"15:30","endTime":"16:00","fee":"0","feeCode":"","regCount":"4","noVisits":"0","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10488","regId":"916613","rankId":"2","rankName":"下午","startTime":"16:00","endTime":"16:30","fee":"0","feeCode":"","regCount":"4","noVisits":"0","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10488","regId":"916017","rankId":"2","rankName":"下午","startTime":"16:30","endTime":"17:00","fee":"0","feeCode":"","regCount":"5","noVisits":"0","visitDate":"'. $date.'","timeSlot":null}]},{"doctId":"10446","doctName":"陈秀纯","docTitle":"主治医师","depLocation":"","isksDoc":"1","doctotVisitInfoList":[{"doctId":"10446","regId":"916156","rankId":"1","rankName":"上午","startTime":"08:00","endTime":"08:30","fee":"0","feeCode":"","regCount":"2","noVisits":"1","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10446","regId":"916157","rankId":"1","rankName":"上午","startTime":"08:30","endTime":"09:00","fee":"0","feeCode":"","regCount":"2","noVisits":"1","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10446","regId":"916158","rankId":"1","rankName":"上午","startTime":"09:00","endTime":"09:30","fee":"0","feeCode":"","regCount":"3","noVisits":"2","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10446","regId":"916160","rankId":"1","rankName":"上午","startTime":"10:00","endTime":"10:30","fee":"0","feeCode":"","regCount":"2","noVisits":"3","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10446","regId":"916161","rankId":"1","rankName":"上午","startTime":"10:30","endTime":"11:00","fee":"0","feeCode":"","regCount":"2","noVisits":"3","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10446","regId":"916162","rankId":"1","rankName":"上午","startTime":"11:00","endTime":"11:30","fee":"0","feeCode":"","regCount":"4","noVisits":"3","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10446","regId":"916163","rankId":"1","rankName":"上午","startTime":"11:30","endTime":"12:00","fee":"0","feeCode":"","regCount":"3","noVisits":"3","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10446","regId":"916164","rankId":"2","rankName":"下午","startTime":"14:00","endTime":"14:30","fee":"0","feeCode":"","regCount":"3","noVisits":"1","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10446","regId":"916165","rankId":"2","rankName":"下午","startTime":"14:30","endTime":"15:00","fee":"0","feeCode":"","regCount":"4","noVisits":"1","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10446","regId":"916166","rankId":"2","rankName":"下午","startTime":"15:00","endTime":"15:30","fee":"0","feeCode":"","regCount":"3","noVisits":"1","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10446","regId":"916167","rankId":"2","rankName":"下午","startTime":"15:30","endTime":"16:00","fee":"0","feeCode":"","regCount":"4","noVisits":"1","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10446","regId":"916168","rankId":"2","rankName":"下午","startTime":"16:00","endTime":"16:30","fee":"0","feeCode":"","regCount":"4","noVisits":"1","visitDate":"'. $date.'","timeSlot":null},{"doctId":"10446","regId":"916169","rankId":"2","rankName":"下午","startTime":"16:30","endTime":"17:00","fee":"0","feeCode":"","regCount":"5","noVisits":"1","visitDate":"'. $date.'","timeSlot":null}]}]}'; + + return $this; + } + + private function mockConfirmRegister(array $params): self + { + $date = &$params['json']['date']; + $this->transfer_response = '{"status":200,"success":true,"msg":"成功","msgDev":null,"response":{"visitNo":"5358197","waitNum":"","treaID":"1-4","date":"2025-01-22","startTime":"16:30","endTime":"17:00","oppatNo":"288712335574","depLocation":"请到一楼儿童保健门诊","transNo":"","hzrs":"1"}}'; return $this; } @@ -158,7 +167,7 @@ class ClientMockHttpTransfer extends HttpTransferAbstract */ private function mockCheckRefundRegisterStatus(array $params): self { - $this->transfer_response = '0可退号'; + $this->transfer_response = '{"status":200,"success":false,"msg":"退号取消检查不通过:当前挂号已过了挂号效期,不能重复退号","msgDev":null,"response":null}'; return $this; } @@ -170,7 +179,7 @@ class ClientMockHttpTransfer extends HttpTransferAbstract */ private function mockRefundRegister(array $params): self { - $this->transfer_response = '0退号成功'; + $this->transfer_response = '{"status":200,"success":true,"msg":"退号成功","msgDev":null,"response":null}'; return $this; } diff --git a/config/database.php b/config/database.php index edaa45f..dbf142c 100644 --- a/config/database.php +++ b/config/database.php @@ -62,6 +62,27 @@ return [ ]) : [], ], + // 管理后台数据库 + 'mysql_admin' => [ + 'driver' => 'mysql', + 'url' => env('DB_ADMIN_URL'), + 'host' => env('DB_ADMIN_HOST', '127.0.0.1'), + 'port' => env('DB_ADMIN_PORT', '3306'), + 'database' => env('DB_ADMIN_DATABASE', 'laravel'), + 'username' => env('DB_ADMIN_USERNAME', 'root'), + 'password' => env('DB_ADMIN_PASSWORD', ''), + 'unix_socket' => env('DB_ADMIN_SOCKET', ''), + 'charset' => env('DB_ADMIN_CHARSET', 'utf8mb4'), + 'collation' => env('DB_ADMIN_COLLATION', 'utf8mb4_unicode_ci'), + 'prefix' => env('DB_ADMIN_PREFIX', ''), + 'prefix_indexes' => true, + 'strict' => true, + 'engine' => null, + 'options' => extension_loaded('pdo_mysql') ? array_filter([ + PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), + ]) : [], + ], + 'mariadb' => [ 'driver' => 'mariadb', 'url' => env('DB_URL'), diff --git a/config/logging.php b/config/logging.php index f4784ca..b2fdd62 100644 --- a/config/logging.php +++ b/config/logging.php @@ -147,6 +147,15 @@ return [ 'max_files' => 30, ], + // 通用错误日志 + 'genera_error' => [ + 'driver' => 'custom', + 'via' => GeneralDailyLogger::class, + 'service_type' => 'GeneraErrorLog', + 'level' => Level::Info, + 'max_files' => 30, + ], + // HisSoap 'his_soap' => [ 'driver' => 'custom', @@ -174,7 +183,7 @@ return [ 'max_files' => 30, ], - // 挂号日志 + // 缴费日志 'outpatient' => [ 'driver' => 'custom', 'via' => GeneralDailyLogger::class, diff --git a/database/migrations/2023_03_03_075720_create_patients_table.php b/database/migrations/2023_03_03_075720_create_patients_table.php index 90466ab..fa70485 100644 --- a/database/migrations/2023_03_03_075720_create_patients_table.php +++ b/database/migrations/2023_03_03_075720_create_patients_table.php @@ -15,7 +15,8 @@ return new class () extends Migration { $table->id(); $table->string('union_id', 32)->default('')->comment(' union_id'); $table->string('open_id', 32)->index()->comment('openid'); - $table->string('patient_id', 20)->index()->comment('患者门诊号'); + $table->string('patient_id', 20)->index()->comment('患者ID'); + $table->string('patient_number', 20)->index()->comment('患者门诊号'); $table->unsignedTinyInteger('card_type')->index()->comment('患者证件类型'); $table->string('card_no', 64)->index()->comment('患者证件号'); $table->string('name', 50)->comment('患者名称');