From 298283b3fe2600785f6a56abb8d46675e66707ba Mon Sep 17 00:00:00 2001 From: wucongxing <815046773@qq.com> Date: Fri, 21 Apr 2023 13:39:17 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=87=AA=E5=8A=A8=E5=BC=80?= =?UTF-8?q?=E5=85=B7=E5=A4=84=E6=96=B9=E3=80=82=E4=BF=AE=E6=94=B9ca?= =?UTF-8?q?=E5=AF=B9=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Consumer/AssignPharmacistConsumer.php | 122 ++++-- .../AutoPharmacistCaVerifyConsumer.php | 364 +++++++++++++++++- .../Producer/AssignPharmacistProducer.php | 2 +- app/Controller/TestController.php | 7 +- app/Model/OrderPrescriptionFile.php | 14 +- app/Services/CaService.php | 99 +++-- app/Services/ImService.php | 4 +- app/Services/MessagePush.php | 42 ++ app/Services/OrderPrescriptionService.php | 66 +++- app/Services/PatientOrderService.php | 12 +- app/Services/UserDoctorService.php | 40 +- app/Services/UserPharmacistService.php | 17 +- extend/Alibaba/Oss.php | 14 + 13 files changed, 682 insertions(+), 121 deletions(-) diff --git a/app/Amqp/Consumer/AssignPharmacistConsumer.php b/app/Amqp/Consumer/AssignPharmacistConsumer.php index 780c0d3..a13c092 100644 --- a/app/Amqp/Consumer/AssignPharmacistConsumer.php +++ b/app/Amqp/Consumer/AssignPharmacistConsumer.php @@ -4,17 +4,23 @@ declare(strict_types=1); namespace App\Amqp\Consumer; +use App\Model\OrderInquiry; use App\Model\OrderPrescription; +use App\Model\UserDoctor; +use App\Model\UserPatient; use App\Model\UserPharmacist; +use App\Services\MessagePush; use App\Utils\Log; use Hyperf\Amqp\Result; use Hyperf\Amqp\Annotation\Consumer; use Hyperf\Amqp\Message\ConsumerMessage; use Hyperf\DbConnection\Db; use PhpAmqpLib\Message\AMQPMessage; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; /** - * 分配药师 + * 分配药师-暂时废弃,现修改为创建处方时分配 */ #[Consumer(exchange: 'amqp.direct', routingKey: 'AssignPharmacist', queue: 'assign.pharmacist.queue', nums: 1)] class AssignPharmacistConsumer extends ConsumerMessage @@ -23,40 +29,63 @@ class AssignPharmacistConsumer extends ConsumerMessage { Log::getInstance()->error("开始执行 分配药师 队列:" . json_encode($data, JSON_UNESCAPED_UNICODE)); + // 获取订单-处方表数据 + $params = array(); + $params['order_prescription_id'] = $data['order_prescription_id']; + $order_prescription = OrderPrescription::getOne($params); + if (empty($order_prescription)) { + Db::rollBack(); + Log::getInstance()->info("分配药师队列执行结束:未查询到对应处方订单数据"); + return Result::DROP;// 销毁 + } + + // 检测处方状态(1:待审核 3:待使用 4:已失效 5:已使用) + if ($order_prescription['prescription_status'] != 1) { + Db::rollBack(); + Log::getInstance()->info("分配药师队列执行结束:处方状态非待审核,当前为" . $order_prescription['prescription_status']); + return Result::ACK;// 销毁 + } + + // 检测药师审核状态 + if ($order_prescription['pharmacist_audit_status'] == 1) { + Db::rollBack(); + Log::getInstance()->error("分配药师队列执行结束:药师审核状态为已通过"); + return Result::ACK;// 销毁 + } + + // 获取医生数据 + $params = array(); + $params['doctor_id'] = $order_prescription['doctor_id']; + $user_doctor = UserDoctor::getOne($params); + if (empty($user_doctor)) { + Db::rollBack(); + Log::getInstance()->error("分配药师队列执行结束:缺少医生数据"); + return Result::ACK;// 销毁 + } + + // 获取用户数据 + $params = array(); + $params['patient_id'] = $order_prescription['patient_id']; + $user_patient = UserPatient::getOne($params); + if (empty($user_patient)) { + Db::rollBack(); + Log::getInstance()->error("分配药师队列执行结束:缺少患者数据"); + return Result::ACK;// 销毁 + } + Db::beginTransaction(); - try { - // 获取订单-处方表数据 - $params = array(); - $params['order_prescription_id'] = $data['order_prescription_id']; - $order_prescription = OrderPrescription::getOne($params); - if (empty($order_prescription)){ - Db::rollBack(); - Log::getInstance()->error("分配药师队列执行失败:未查询到对应处方订单数据"); - return Result::DROP;// 销毁 - } - - // 检测处方状态(1:待审核 3:待使用 4:已失效 5:已使用) - if ($order_prescription['prescription_status'] != 1){ - Db::rollBack(); - Log::getInstance()->error("分配药师队列执行失败:处方状态错误,当前为" .$order_prescription['prescription_status']); - return Result::ACK;// 销毁 - } - - // 检测药师审核状态 - if ($order_prescription['pharmacist_audit_status'] == 1){ - Db::rollBack(); - Log::getInstance()->error("分配药师队列执行失败:药师审核状态为已通过"); - return Result::ACK;// 销毁 - } - // 分配药师 $params = array(); $params['pharmacist_id'] = "534534546"; $user_pharmacist = UserPharmacist::getOne($params); - if (empty($user_pharmacist)){ + if (empty($user_pharmacist)) { Db::rollBack(); Log::getInstance()->error("分配药师队列执行失败:药师数据错误"); + + // 分配失败,按照驳回处理 + $this->reject($data['order_prescription_id'], $user_doctor['user_id'], $user_patient['user_id'], $order_prescription['order_inquiry_id']); + return Result::DROP;// 销毁 } @@ -66,12 +95,16 @@ class AssignPharmacistConsumer extends ConsumerMessage $params = array(); $params['order_prescription_id'] = $data['order_prescription_id']; - OrderPrescription::edit($params,$save_data); + OrderPrescription::edit($params, $save_data); Db::commit(); } catch (\Exception $e) { Db::rollBack(); Log::getInstance()->error("分配药师队列执行失败原因:" . $e->getMessage()); + + // 分配失败,按照驳回处理 + $this->reject($data['order_prescription_id'], $user_doctor['user_id'], $order_prescription['order_inquiry_id']); + return Result::DROP; // 重回队列 } @@ -79,4 +112,37 @@ class AssignPharmacistConsumer extends ConsumerMessage return Result::ACK; } + + /** + * 分配失败 + * @param string $order_prescription_id + * @param string $doctor_user_id + * @param string $order_inquiry_id + * @return void + */ + public function reject(string $order_prescription_id, string $doctor_user_id, string $patient_user_id, string $order_inquiry_id): void + { + try { + $params = array(); + $params['order_prescription_id'] = $order_prescription_id; + + $data = array(); + $data['pharmacist_audit_status'] = 2; + $data['pharmacist_verify_time'] = date('Y-m-d H:i:s', time()); + $data['pharmacist_fail_reason'] = "请联系平台客服,请勿重开处方"; + + OrderPrescription::edit($params, $data); + + // 医生-开具的处方审核未通过 + $MessagePush = new MessagePush($doctor_user_id, $order_inquiry_id); + $MessagePush->prescriptionVerifyFail($order_prescription_id); + + // 患者-处方审核未通过 + $MessagePush = new MessagePush($patient_user_id, $order_inquiry_id); + $MessagePush->patientPrescriptionVerifyFail(); + + } catch (\Exception $e) { + Log::getInstance()->error("分配药师队列执行失败原因:" . $e->getMessage()); + } + } } diff --git a/app/Amqp/Consumer/AutoPharmacistCaVerifyConsumer.php b/app/Amqp/Consumer/AutoPharmacistCaVerifyConsumer.php index e630b2f..750b73e 100644 --- a/app/Amqp/Consumer/AutoPharmacistCaVerifyConsumer.php +++ b/app/Amqp/Consumer/AutoPharmacistCaVerifyConsumer.php @@ -4,12 +4,30 @@ declare(strict_types=1); namespace App\Amqp\Consumer; +use App\Amqp\Producer\PrescriptionExpiredDelayDirectProducer; +use App\Constants\HttpEnumCode; +use App\Exception\BusinessException; +use App\Model\OrderInquiry; +use App\Model\OrderPrescription; +use App\Model\OrderPrescriptionFile; +use App\Model\OrderPrescriptionProduct; +use App\Model\UserDoctor; +use App\Model\UserPatient; +use App\Model\UserPharmacist; +use App\Services\CaService; +use App\Services\ImService; +use App\Services\MessagePush; +use App\Services\OrderPrescriptionService; use App\Utils\Log; +use Hyperf\Amqp\Producer; use Hyperf\Amqp\Result; use Hyperf\Amqp\Annotation\Consumer; use Hyperf\Amqp\Message\ConsumerMessage; use Hyperf\DbConnection\Db; +use Hyperf\Redis\Redis; use PhpAmqpLib\Message\AMQPMessage; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; /** * 药师自动签章审核 @@ -20,22 +38,199 @@ class AutoPharmacistCaVerifyConsumer extends ConsumerMessage { public function consumeMessage($data, AMQPMessage $message): string { - Log::getInstance()->error("开始执行 药师自动签章审核 队列:" . json_encode($data, JSON_UNESCAPED_UNICODE)); + Log::getInstance("queue-AutoPharmacistCaVerify")->error("开始:" . json_encode($data, JSON_UNESCAPED_UNICODE)); + // 检测入参参数 + $res = $this->checkParams($data); + if (!$res) { + Log::getInstance("queue-AutoPharmacistCaVerify")->error("错误:执行参数错误"); + return Result::ACK; + } + + // 获取处方数据 + $params = array(); + $params['order_prescription_id'] = $data['order_prescription_id']; + $order_prescription = OrderPrescription::getOne($params); + if (empty($order_prescription)) { + Log::getInstance("queue-AutoPharmacistCaVerify")->error("错误:处方数据错误"); + return Result::ACK; + } + + // 检测处方数据 + $res = $this->checkPrescriptionData($order_prescription); + if (!empty($res)) { + Log::getInstance("queue-AutoPharmacistCaVerify")->error("错误:" . $res); + return Result::ACK; + } + + // 获取问诊订单数据 + $params = array(); + $params['order_inquiry_id'] = $order_prescription['order_inquiry_id']; + $order_inquiry = OrderInquiry::getOne($params); + if (empty($order_inquiry)) { + Log::getInstance("queue-AutoPharmacistCaVerify")->error("错误:问诊订单数据错误"); + return Result::ACK; + } + + // 检测问诊订单数据 + $res = $this->checkOrderInquiryData($order_inquiry); + if (!empty($res)) { + Log::getInstance("queue-AutoPharmacistCaVerify")->error("错误:" . $res); + return Result::ACK; + } + + // 获取医生数据 + $params = array(); + $params['doctor_id'] = $order_prescription['doctor_id']; + $user_doctor = UserDoctor::getOne($params); + if (empty($user_doctor)) { + Log::getInstance("queue-AutoPharmacistCaVerify")->error("错误:医生数据错误"); + return Result::ACK; + } + + // 获取用户数据 + $params = array(); + $params['patient_id'] = $order_prescription['patient_id']; + $user_patient = UserPatient::getOne($params); + if (empty($user_patient)) { + Log::getInstance("queue-AutoPharmacistCaVerify")->error("错误:患者数据错误"); + return Result::ACK; + } + + // 获取药师数据 + $params = array(); + $params['pharmacist_id'] = $order_prescription['pharmacist_id']; + $user_pharmacist = UserPharmacist::getOne($params); + if (empty($user_pharmacist)) { + Log::getInstance("queue-AutoPharmacistCaVerify")->error("错误:药师数据错误"); + return Result::ACK; + } + + // 获取处方商品数据 + $product_name = ""; + $params = array(); + $params['order_prescription_id'] = $order_prescription['order_prescription_id']; + $order_prescription_product = OrderPrescriptionProduct::getList($params); + if (!empty($order_prescription_product)){ + $product_name = array_column($order_prescription_product->toArray(),'product_name'); + if (count($product_name) > 1){ + $product_name = implode('、',$product_name); + }else{ + $product_name = $product_name[0]; + } + } + + // 订单-处方 + $OrderPrescriptionService = new OrderPrescriptionService(); + + // 下载医生签章文件 Db::beginTransaction(); - try { - // 检测入参参数 - $res = $this->checkParams($data); + // 检测执行次数 + $res = $this->checkHandleNumber($data['prescription_file_id']); + if (!$res) { + // 超出最大执行次数或检测错误 + // 自动驳回 + $OrderPrescriptionService->rejectPrescription( + $data['order_prescription_id'], + $user_doctor['user_id'], + $user_patient['user_id'], + $order_prescription['order_inquiry_id'], + "请联系平台客服,请勿重开处方" + ); + + return Result::ACK; + } + + // 获取处方文件数据 + $params = array(); + $params['prescription_file_id'] = $data['prescription_file_id']; + $params['order_prescription_id'] = $data['order_prescription_id']; + $order_prescription_file = OrderPrescriptionFile::getOne($params); + if (empty($order_prescription_file)) { + Db::rollBack(); + Log::getInstance("queue-AutoPharmacistCaVerify")->error("错误:处方文件数据错误"); + return Result::REQUEUE; + } + + // 检测处方文件数据 + $res = $this->checkPrescriptionFileData($order_prescription_file); + if (!empty($res)) { + Db::rollBack(); + Log::getInstance("queue-AutoPharmacistCaVerify")->error("错误:" . $res); + return Result::REQUEUE; + } + + // 下载医生的签章pdf并上传至oss + $prescription_pdf_oss_path = $this->downCaPdfToOss($order_prescription, $user_doctor['user_id'],2,$order_prescription_file['doctor_ca_file_id']); + if (!$prescription_pdf_oss_path) { + Db::rollBack(); + Log::getInstance("queue-AutoPharmacistCaVerify")->error("错误:" . $prescription_pdf_oss_path); + return Result::REQUEUE; + } + + // 药师/医院签章 + $OrderPrescriptionService = new OrderPrescriptionService(); + $prescription_open_result = $OrderPrescriptionService->openPrescription($data['order_prescription_id'],$user_pharmacist['user_id'],); + if (empty($prescription_open_result['file_id'])){ + Db::rollBack(); + Log::getInstance("queue-AutoPharmacistCaVerify")->error("错误:处方开具失败"); + return Result::REQUEUE; + } + + // 下载医院的签章pdf并上传至oss + $prescription_pdf_oss_path = $this->downCaPdfToOss($order_prescription, $user_doctor['user_id'],3,$prescription_open_result['file_id']); + if (!$prescription_pdf_oss_path) { + Db::rollBack(); + Log::getInstance("queue-AutoPharmacistCaVerify")->error("错误:" . $prescription_pdf_oss_path); + return Result::REQUEUE; + } + + // 修改处方文件表,添加prescription_pdf_oss_path字段 + $this->modifyOrderPrescriptionFile($data['prescription_file_id'],$prescription_pdf_oss_path,$prescription_open_result['file_id']); Db::commit(); - Log::getInstance()->error("药师自动签章审核 队列执行成功"); + Log::getInstance("queue-AutoPharmacistCaVerify")->info("成功"); } catch (\Exception $e) { Db::rollBack(); - Log::getInstance()->error("药师自动签章审核 队列执行失败原因:" . $e->getMessage()); + Log::getInstance("queue-AutoPharmacistCaVerify")->error("异常错误:" . $e->getMessage()); + return Result::REQUEUE; // 重回队列 } + // 发送消息 + try { + // 药师审核成功 + // 发送IM消息-处方已开具 + $imService = new ImService(); + $imService->prescriptionIssued($order_inquiry,$user_doctor['user_id'],$order_inquiry['user_id'],$product_name,(string)$data['order_prescription_id'],7); + + // 发送站内、短信消息-患者的处方被药师审核通过 + $MessagePush = new MessagePush($order_inquiry['user_id'],$order_inquiry['order_inquiry_id']); + $MessagePush->patientPrescriptionVerifyPass(); + + // 站内、订阅失败发送短信-医生开具的处方审核通过 + // 发送目标不同,重新实例化 + $MessagePush = new MessagePush($user_doctor['user_id'],$order_inquiry['order_inquiry_id']); + $MessagePush->prescriptionVerifySuccess(); + + // 添加处方过期队列 + $data = array(); + $data['order_prescription_id'] = (string)$order_prescription['order_prescription_id']; + + $message = new PrescriptionExpiredDelayDirectProducer($data); + $message->setDelayMs(1000 * 60 * 10); + $producer = $this->container->get(Producer::class); + $res = $producer->produce($message); + if (!$res) { + Log::getInstance("queue-AutoPharmacistCaVerify")->error("添加处方过期队列失败!"); + return Result::ACK; + } + }catch(\Exception $e){ + Log::getInstance("queue-AutoPharmacistCaVerify")->error("发送消息异常错误:" . $e->getMessage()); + return Result::ACK; + } + return Result::ACK; } @@ -46,13 +241,166 @@ class AutoPharmacistCaVerifyConsumer extends ConsumerMessage */ protected function checkParams(array $data): bool { - if (!isset($data['prescription_file_id'])){ + if (!isset($data['prescription_file_id'])) { return false; } - if (!isset($data['order_prescription_id'])){ + if (!isset($data['order_prescription_id'])) { return false; } return true; } + + /** + * 检测处方数据 + * @param array|object $order_prescription + * @return string + */ + protected function checkPrescriptionData(array|object $order_prescription): string + { + // 验证处方状态 + if ($order_prescription['prescription_status'] == 2) { + // 处方状态(1:待审核 2:待使用 3:已失效 4:已使用) + return "处方已审核"; + } + + if ($order_prescription['prescription_status'] == 3) { + // 处方状态(1:待审核 2:待使用 3:已失效 4:已使用) + return "处方已审核并失效"; + } + + if ($order_prescription['prescription_status'] == 4) { + // 处方状态(1:待审核 2:待使用 3:已失效 4:已使用) + return "处方已审核并使用"; + } + + // 验证处方审核状态 + if ($order_prescription['pharmacist_audit_status'] != 0) { + // 药师审核状态(0:审核中 1:审核成功 2:审核驳回) + return "处方已审核"; + } + + // 处方平台审核状态 + if ($order_prescription['platform_audit_status'] != 0) { + // 处方平台审核状态(0:审核中 1:审核成功 2:审核驳回) + return "处方已审核"; + } + + return ""; + } + + /** + * 检测问诊订单数据 + * @param array|object $order_inquiry + * @return string + */ + protected function checkOrderInquiryData(array|object $order_inquiry): string + { + if (in_array($order_inquiry['inquiry_status'], [1, 2, 3, 7])) { + // 问诊订单状态(1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消) + return "问诊订单状态错误,无法继续审核"; + } + + return ""; + } + + /** + * 检测处方文件数据 + * @param array|object $order_prescription_file + * @return string + */ + protected function checkPrescriptionFileData(array|object $order_prescription_file): string + { + if (empty($order_prescription_file['doctor_ca_file_id'])) { + return "缺少医生签章pdf文件id"; + } + + return ""; + } + + /** + * 检测执行次数 + * @param string $prescription_file_id + * @return bool + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + protected function checkHandleNumber(string $prescription_file_id): bool + { + try { + $redis = $this->container->get(Redis::class); + + $redis_key = "AutoPharmacistCaVerify" . $prescription_file_id; + $redis_value = $redis->get($redis_key); + if (empty($redis_value)) { + $redis->set($redis_key, 1, 60 * 60 * 24 * 5); + return true; + } + + // 问诊订单执行退款次数过多 + if ($redis_value > 3) { + // 加入短信队列,通知管理员 + + return false; + } + + $redis->incr($redis_key); + } catch (\Exception $e) { + return false; + } + + return true; + } + + /** + * 下载签章pdf并上传至oss + * @param array|object $order_prescription + * @param string $user_id 用户id + * @param string|int $user_type 用户类型 1:患者 2:医生 3:药师 + * @param string $file_id + * @return string|bool oss地址|false(存在异常时) + */ + protected function downCaPdfToOss(array|object $order_prescription, string $user_id, string|int $user_type, string $file_id): string|bool + { + try { + $user = array(); + $user['user_id'] = $user_id; + $user['user_type'] = $user_type; + $CaService = new CaService($order_prescription, $user); + + // 下载签章pdf并上传至oss + if ($user_type == 2){ + return $CaService->downCaPdfToOss($file_id,1); + }else{ + return $CaService->downCaPdfToOss($file_id,2); + } + + } catch (\Exception $e) { + return false; + } + } + + /** + * 修改处方文件表 + * @param string $prescription_file_id 主键id + * @param string $prescription_pdf_oss_path pdf的oss地址 + * @param string $hospital_ca_file_id 医院签章文件id + * @return void + */ + protected function modifyOrderPrescriptionFile(string $prescription_file_id,string $prescription_pdf_oss_path,string $hospital_ca_file_id): void + { + try { + $params = array(); + $params['prescription_file_id'] = $prescription_file_id; + + $data = array(); + $data['hospital_ca_file_id'] = $hospital_ca_file_id; + $data['prescription_pdf_oss_path'] = $prescription_pdf_oss_path; + + OrderPrescriptionFile::edit($params,$data); + }catch(\Exception $e){ + // 失败不做处理 + Log::getInstance("queue-AutoPharmacistCaVerify")->error("错误:修改处方文件表失败" . $e->getMessage()); + } + } } diff --git a/app/Amqp/Producer/AssignPharmacistProducer.php b/app/Amqp/Producer/AssignPharmacistProducer.php index c479422..09f6d0f 100644 --- a/app/Amqp/Producer/AssignPharmacistProducer.php +++ b/app/Amqp/Producer/AssignPharmacistProducer.php @@ -8,7 +8,7 @@ use Hyperf\Amqp\Annotation\Producer; use Hyperf\Amqp\Message\ProducerMessage; /** - * 分配药师 + * 分配药师-暂时废弃,现修改为创建处方时分配 */ #[Producer(exchange: 'amqp.direct', routingKey: 'AssignPharmacist')] class AssignPharmacistProducer extends ProducerMessage diff --git a/app/Controller/TestController.php b/app/Controller/TestController.php index dd1496a..c3fe11b 100644 --- a/app/Controller/TestController.php +++ b/app/Controller/TestController.php @@ -59,13 +59,13 @@ class TestController extends AbstractController // $this->test_9(); // $this->test_10(); // $this->test_11(); - $this->test_5(); +// $this->test_5(); // $this->test_1(); // $this->test_11(); // $this->test_12(); // $this->test_13(); // $this->test_14(); -// $this->test_15(); + $this->test_15(); } // 获取云证书-首次 @@ -800,6 +800,9 @@ class TestController extends AbstractController } public function test_15(){ + Log::getInstance("auto-pharmacist-ca-verify-queue")->info("ninhao"); + + dump(111);die; $wg = new \Hyperf\Utils\WaitGroup(); $channel = new Channel(); $wg->add(2); diff --git a/app/Model/OrderPrescriptionFile.php b/app/Model/OrderPrescriptionFile.php index 62acaab..3abbd56 100644 --- a/app/Model/OrderPrescriptionFile.php +++ b/app/Model/OrderPrescriptionFile.php @@ -14,14 +14,12 @@ use Hyperf\Snowflake\Concern\Snowflake; * @property int $prescription_file_id 主键id * @property int $order_prescription_id 订单-处方id * @property string $doctor_ca_file_id 医生签章pdf文件id(可请求ca下载) - * @property string $doctor_pdf_oss_path 医生签章pdf文件oss路径(null表示未下载) - * @property int $doctor_pdf_down_status 签章文件下载状态(0:未下载 1:已下载 2:下载失败) - * @property string $doctor_pdf_down_fail_reason 下载失败原因 - * @property string $doctor_img_oss_path 医生签章img文件oss路径 * @property string $hospital_ca_file_id 医院签章pdf文件id(可请求ca下载) - * @property string $hospital_pdf_oss_path 医院签章pdf文件oss路径(null表示未下载) - * @property int $hospital_pdf_down_status 签章文件下载状态(0:未下载 1:已下载 2:下载失败) - * @property string $hospital_pdf_down_fail_reason 下载失败原因 + * @property string $prescription_img_oss_path 签章img文件oss路径 + * @property string $prescription_pdf_oss_path 签章pdf文件oss路径 + * @property string $doctor_sign_image_path 医生签名图片oss地址 + * @property string $pharmacist_sign_image_path 药师签名图片oss地址 + * @property string $hospital_sign_image_path 医院签名图片oss地址 * @property \Carbon\Carbon $created_at 创建时间 * @property \Carbon\Carbon $updated_at 修改时间 */ @@ -37,7 +35,7 @@ class OrderPrescriptionFile extends Model /** * The attributes that are mass assignable. */ - protected array $fillable = ['prescription_file_id', 'order_prescription_id', 'doctor_ca_file_id', 'doctor_pdf_oss_path', 'doctor_pdf_down_status', 'doctor_pdf_down_fail_reason', 'doctor_img_oss_path', 'hospital_ca_file_id', 'hospital_pdf_oss_path', 'hospital_pdf_down_status', 'hospital_pdf_down_fail_reason', 'created_at', 'updated_at']; + protected array $fillable = ['prescription_file_id', 'order_prescription_id', 'doctor_ca_file_id', 'hospital_ca_file_id', 'prescription_img_oss_path', 'prescription_pdf_oss_path', 'doctor_sign_image_path', 'pharmacist_sign_image_path', 'hospital_sign_image_path', 'created_at', 'updated_at']; protected string $primaryKey = "prescription_file_id"; diff --git a/app/Services/CaService.php b/app/Services/CaService.php index f14f1dc..af2d39e 100644 --- a/app/Services/CaService.php +++ b/app/Services/CaService.php @@ -59,6 +59,13 @@ class CaService extends BaseService // 信用代码 protected string $org_num; + // 处方pdf本地地址 + protected string $prescription_pdf_local_path; + + // 处方pdf oss地址 + protected string $prescription_pdf_oss_path; + + /** * 初始化类,此处会获取基础数据 * @param array|object $order_prescription 处方表数据 @@ -215,6 +222,12 @@ class CaService extends BaseService // 关闭channel通道 $channel->close(); } + + // 处方pdf本地地址 + $this->prescription_pdf_local_path = "./runtime/file/prescription/" . $order_prescription_id . '.pdf'; + + // 处方pdf oss地址 + $this->prescription_pdf_oss_path = "applet/prescription/" . $order_prescription_id. '.pdf'; } /** @@ -382,8 +395,8 @@ class CaService extends BaseService // 上传处方图片至oss $oss = new Oss(); $prescription_img_oss_filename = "applet/prescription/" . $order_prescription['order_prescription_id'] . '.' . 'jpg'; - $prescription_img_url = $oss->putObject($prescription_img_oss_filename, $img_result); - $prescription_img_url = '/' . $prescription_img_url; + $prescription_img_oss_path = $oss->putObject($prescription_img_oss_filename, $img_result); + $prescription_img_oss_path = '/' . $prescription_img_oss_path; // 图片生成pdf $pdf = new TCPDF('P', 'mm', 'A4', true, 'UTF-8', false); @@ -402,37 +415,78 @@ class CaService extends BaseService // 图片生成的处方pdf存储为本地文件 runtime目录下 $pdf->Output($prescription_pdf_local_path . $prescription_pdf_local_filename, "F"); - return $prescription_img_url; + return $prescription_img_oss_path; } /** - * 下载医生开具的处方pdf + * 下载Oss中处方pdf * 存在:当次发版内医生开具后,药师再去开具 * 不存在:医生开具后,进行发版过,此时需重新下载 - * @param string $order_prescription_id - * @param string $doctor_pdf_oss_path * @return void */ - public function downDoctorPrescriptionPdf(string $order_prescription_id,string $doctor_pdf_oss_path): void + public function downOssPdfToLocal(): void { - $local_path = "./runtime/file/prescription/" . $order_prescription_id . '.' . 'pdf'; - $res = file_exists($local_path); + $res = file_exists($this->prescription_pdf_local_path); if (!$res){ // 去除第一个/ oss不识别 - $prescription_pdf_path = substr($doctor_pdf_oss_path, 1, strlen($doctor_pdf_oss_path) - 1); +// $prescription_pdf_path = substr($doctor_pdf_oss_path, 1, strlen($doctor_pdf_oss_path) - 1); $oss = new Oss(); - $oss->getObjectToLocal($prescription_pdf_path, $local_path); + $oss->getObjectToLocal($this->prescription_pdf_oss_path, $this->prescription_pdf_local_path); } } + /** + * 下载CA中pdf至本地文件 + * @param string $file_id + * @param int $type 类型 1:用户 2:医院 + * @return void + */ + public function downCaPdfToLocal(string $file_id,int $type): void + { + $CaOnline = new CaOnline(); + if ($type == 1){ + // 用户 + $prescription_pdf_result = $CaOnline->getSignedFile($this->user_entity_id, $file_id); + }else{ + // 医院 + $prescription_pdf_result = $CaOnline->getSignedFile($this->hospital_entity_id, $file_id); + } + + $file = fopen($this->prescription_pdf_local_path, "w"); + fwrite($file, $prescription_pdf_result); + fclose($file); + } + + /** + * 下载CA中的pdf并上传至oss + * @param string $file_id + * @param int $type 类型 1:用户 2:医院 + * @return string oss地址 + */ + public function downCaPdfToOss(string $file_id,int $type): string + { + $CaOnline = new CaOnline(); + + if ($type == 1){ + // 用户 + $prescription_pdf_result = $CaOnline->getSignedFile($this->user_entity_id, $file_id); + }else{ + // 医院 + $prescription_pdf_result = $CaOnline->getSignedFile($this->hospital_entity_id, $file_id); + } + + // 上传oss + $oss = new Oss(); + return $oss->putObject($this->prescription_pdf_oss_path, $prescription_pdf_result); + } + /** * 进行处方pdf签章 - * @param array|object $order_prescription * @param string $type 类型 1:医院 2:医生 3:药师 * @return string 文件id */ - public function addSignPdf(array|object $order_prescription,string $type): string + public function addSignPdf(string $type): string { // 下载签名图片 if ($type == 1){ @@ -529,9 +583,9 @@ class CaService extends BaseService } // 打开处方pdf文件 - $pdf_file = fopen("./runtime/file/prescription/" . $order_prescription['order_prescription_id'] . ".pdf", 'r'); + $pdf_file = fopen($this->prescription_pdf_local_path, 'r'); if (!$pdf_file) { - throw new BusinessException("处方图片打开失败"); + throw new BusinessException("处方pdf打开失败"); } // 处方pdf进行签章 @@ -543,22 +597,9 @@ class CaService extends BaseService throw new BusinessException("处方签章失败"); } + fclose($pdf_file); return $sign_pdf_result[0]['fileId']; } - /** - * 下载签章pdf图片 - * @param string $file_id - * @param string $order_prescription_id - * @return void - */ - public function downCaPdf(string $file_id,string $order_prescription_id): void - { - $CaOnline = new CaOnline(); - $prescription_pdf_result = $CaOnline->getSignedFile($this->user_entity_id, $file_id); - $file = fopen("./runtime/file/prescription/" . $order_prescription_id . '.pdf', "w"); - fwrite($file, $prescription_pdf_result); - fclose($file); - } } \ No newline at end of file diff --git a/app/Services/ImService.php b/app/Services/ImService.php index 7509714..6aa4988 100644 --- a/app/Services/ImService.php +++ b/app/Services/ImService.php @@ -437,10 +437,10 @@ class ImService extends BaseService * @param string $patient_user_id * @param string $product_name * @param string $order_prescription_id - * @param string $message_type 6/7 + * @param string|int $message_type 6/7 * @return void */ - public function prescriptionIssued(array|object $order_inquiry, string $doctor_user_id, string $patient_user_id, string $product_name, string $order_prescription_id, string $message_type): void + public function prescriptionIssued(array|object $order_inquiry, string $doctor_user_id, string $patient_user_id, string $product_name, string $order_prescription_id, string|int $message_type): void { try { // 发送消息 diff --git a/app/Services/MessagePush.php b/app/Services/MessagePush.php index f79b7f6..4cda40e 100644 --- a/app/Services/MessagePush.php +++ b/app/Services/MessagePush.php @@ -450,6 +450,48 @@ class MessagePush extends BaseService return true; } + /** + * 患者-处方审核未通过 + * 站内 + * @return bool + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function patientPrescriptionVerifyFail(): bool + { + try { + // 获取医生数据 + $params = array(); + $params['doctor_id'] = $this->order_inquiry['doctor_id']; + $user_doctor = UserDoctor::getOne($params); + if (empty($user_doctor)){ + throw new BusinessException("加入推送队列失败:医生数据为空"); + } + + // 站内 + // 服务消息 + $data = array(); + $data['user_id'] = $this->user['user_id']; + $data['notice_type'] = 3; + $data['notice_system_type'] = 1; + $data['from_name'] = "肝胆小秘书"; + $data['notice_brief_title'] = "{$user_doctor['user_name']}医生为您开具的电子处方未通过审核,点击查看详情。"; + $data['notice_title'] = "{$user_doctor['user_name']}医生为您开具的电子处方未通过审核,点击查看详情。"; + $data['notice_content'] = "{$user_doctor['user_name']}医生为您开具的电子处方未通过审核,您可以稍后重新发起问诊申请开具处方。"; + + $message = new SendStationMessageProducer($data); + $producer = ApplicationContext::getContainer()->get(Producer::class); + $result = $producer->produce($message); + if (!$result) { + throw new BusinessException("加入推送队列失败" . json_encode($data,JSON_UNESCAPED_UNICODE)); + } + } catch (\Exception $e) { + throw new BusinessException("加入推送队列失败" . $e->getMessage()); + } + + return true; + } + /** * 优惠劵发放 * 站内 diff --git a/app/Services/OrderPrescriptionService.php b/app/Services/OrderPrescriptionService.php index 43529ac..2b7e0af 100644 --- a/app/Services/OrderPrescriptionService.php +++ b/app/Services/OrderPrescriptionService.php @@ -30,6 +30,8 @@ use Extend\Prescription\Prescription; use Hyperf\Contract\LengthAwarePaginatorInterface; use Hyperf\Utils\WaitGroup; use Intervention\Image\ImageManager; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; use Swoole\Coroutine\Channel; use TCPDF; @@ -127,11 +129,11 @@ class OrderPrescriptionService extends BaseService * 开具处方 * 医生-正常开具 * 药师-先开具药师处方,再开具医院签章 - * @param string $order_prescription_id - * @param string $user_id + * @param string $order_prescription_id 处方id + * @param string $user_id 用户id * @return array */ - public function openPrescription(string $order_prescription_id, string $user_id,string $doctor_pdf_oss_path = ""): array + public function openPrescription(string $order_prescription_id, string $user_id): array { try { // 获取用户数据 @@ -166,38 +168,34 @@ class OrderPrescriptionService extends BaseService // 医生 if ($user['user_type'] == 2) { // 生成处方图片+处方图片生成pdf - $prescription_img_url = $CaService->createPrescriptionImgPdf($order_prescription); + $prescription_img_oss_path = $CaService->createPrescriptionImgPdf($order_prescription); } - // 药师 + // 药师-医院签章 if ($user['user_type'] == 3) { - // 检测处方图片 - if (empty($doctor_pdf_oss_path)){ - throw new BusinessException("处方文件错误"); - } - // 获取医院云证书签名+验证云证书签名 $CaService->getVerifyCertSign($order_prescription,2); - // 下载医生开具的处方pdf - $CaService->downDoctorPrescriptionPdf($order_prescription['order_prescription_id'],$doctor_pdf_oss_path); + // 下载医生开具的处方pdf至本地,文件存在时不进行下载 + $CaService->downOssPdfToLocal(); } // 进行处方pdf签章 - $file_id = $CaService->addSignPdf($order_prescription,$user['user_type']); + $file_id = $CaService->addSignPdf($user['user_type']); + // 药师-医院签章 if ($user['user_type'] == 3) { // 药师端时,需要进行系统签章 // 把药师签章的pdf存储至本地文件 // 下载药师签章pdf图片 - $CaService->downCaPdf($file_id,$order_prescription['order_prescription_id']); + $CaService->downCaPdfToLocal($file_id,1); // 进行处方pdf签章 - $file_id = $CaService->addSignPdf($order_prescription,$user['user_type']); + $file_id = $CaService->addSignPdf($user['user_type']); } $result = array(); - $result['prescription_img_url'] = $prescription_img_url ?? ""; + $result['prescription_img_oss_path'] = $prescription_img_oss_path ?? ""; $result['file_id'] = $file_id; return $result; @@ -481,4 +479,40 @@ class OrderPrescriptionService extends BaseService return true; } + /** + * 药师驳回处方 + * @param string $order_prescription_id 处方id + * @param string $doctor_user_id 医生user_id + * @param string $patient_user_id 患者user_id + * @param string $order_inquiry_id 问诊订单id + * @param string $pharmacist_fail_reason 驳回原因 + * @return void + */ + public function rejectPrescription(string $order_prescription_id, string $doctor_user_id, string $patient_user_id, string $order_inquiry_id,string $pharmacist_fail_reason = ""): void + { + try { + $params = array(); + $params['order_prescription_id'] = $order_prescription_id; + + $data = array(); + $data['pharmacist_audit_status'] = 2; + $data['pharmacist_verify_time'] = date('Y-m-d H:i:s', time()); + $data['pharmacist_fail_reason'] = $pharmacist_fail_reason; + + OrderPrescription::edit($params, $data); + + // 医生-开具的处方审核未通过 + $MessagePush = new MessagePush($doctor_user_id, $order_inquiry_id); + $MessagePush->prescriptionVerifyFail($order_prescription_id); + + // 患者-处方审核未通过 + $MessagePush = new MessagePush($patient_user_id, $order_inquiry_id); + $MessagePush->patientPrescriptionVerifyFail(); + + } catch (\Exception $e) { + throw new BusinessException($e->getMessage()); + } catch (NotFoundExceptionInterface|ContainerExceptionInterface $e) { + throw new BusinessException($e->getMessage()); + } + } } \ No newline at end of file diff --git a/app/Services/PatientOrderService.php b/app/Services/PatientOrderService.php index 5caf160..64d918f 100644 --- a/app/Services/PatientOrderService.php +++ b/app/Services/PatientOrderService.php @@ -10,6 +10,7 @@ use App\Model\Hospital; use App\Model\OrderInquiry; use App\Model\OrderInquiryCase; use App\Model\OrderPrescription; +use App\Model\OrderPrescriptionFile; use App\Model\OrderPrescriptionProduct; use App\Model\OrderProduct; use App\Model\OrderProductItem; @@ -1199,7 +1200,6 @@ class PatientOrderService extends BaseService $fields = [ 'order_prescription_id', 'prescription_status', - 'prescription_img', 'pharmacist_id', 'doctor_id', ]; @@ -1214,7 +1214,15 @@ class PatientOrderService extends BaseService return fail(); } - $order_prescription['prescription_img'] = addAliyunOssWebsite($order_prescription['prescription_img']); + // 获取处方文件数据 + $params = array(); + $params['order_prescription_id'] = $order_prescription_id; + $order_prescription_file = OrderPrescriptionFile::getOne($params); + if (empty($order_prescription_file)){ + return fail(); + } + + $order_prescription['prescription_img_oss_path'] = addAliyunOssWebsite($order_prescription_file['prescription_img_oss_path']); // 获取处方中医生签名 $params = array(); diff --git a/app/Services/UserDoctorService.php b/app/Services/UserDoctorService.php index 271d333..082248a 100644 --- a/app/Services/UserDoctorService.php +++ b/app/Services/UserDoctorService.php @@ -1378,7 +1378,7 @@ class UserDoctorService extends BaseService // 开具处方 $OrderPrescriptionService = new OrderPrescriptionService(); $prescription_open_result = $OrderPrescriptionService->openPrescription($order_prescription->order_prescription_id,$user_info['user_id']); - if (empty($prescription_open_result['prescription_img_url']) || empty($prescription_open_result['file_id'])){ + if (empty($prescription_open_result['prescription_img_oss_path']) || empty($prescription_open_result['file_id'])){ Db::rollBack(); return fail(HttpEnumCode::SERVER_ERROR, "处方开具失败"); } @@ -1394,6 +1394,7 @@ class UserDoctorService extends BaseService // 修改处方表 $data = array(); + $data['pharmacist_id'] = "534534546"; // 药师id 现固定为此用户,后续可以考虑开启队列 $data['is_auto_phar_verify'] = $system_config['is_auto_phar_verify_prescription'];// 是否药师自动审核(0:否 1:是) $data['doctor_created_time'] = date('Y-m-d H:i:s',time()); @@ -1405,13 +1406,14 @@ class UserDoctorService extends BaseService $data = array(); $data['order_prescription_id'] = $order_prescription->order_prescription_id; $data['doctor_ca_file_id'] = $prescription_open_result['file_id']; - $data['doctor_img_oss_path'] = $prescription_open_result['prescription_img_url']; + $data['prescription_img_oss_path'] = $prescription_open_result['prescription_img_oss_path']; $order_prescription_file = OrderPrescriptionFile::addOrderPrescriptionFile($data); if (empty($order_prescription_file)){ Db::rollBack(); return fail(HttpEnumCode::SERVER_ERROR, "处方开具失败"); } + // 检测药师自动审核配置开启状态 if ($system_config['is_auto_phar_verify_prescription'] == 1){ // 添加药师自动签章审核队列 $data = array(); @@ -1432,18 +1434,6 @@ class UserDoctorService extends BaseService $ImService = new ImService(); $ImService->pharmacistVerify($order_inquiry,(string)$order_prescription->order_prescription_id,$product_name,$user_doctor['user_id'],$order_inquiry['user_id']); - // 加入分配药师队列 - $data = array(); - $data['order_prescription_id'] = $order_prescription['order_prescription_id']; - - $message = new AssignPharmacistProducer($data); - $producer = ApplicationContext::getContainer()->get(Producer::class); - $result = $producer->produce($message); - if (!$result) { - Db::rollBack(); - return fail(HttpEnumCode::SERVER_ERROR); - } - Db::commit(); } catch (\Exception $e) { Db::rollBack(); @@ -1671,14 +1661,7 @@ class UserDoctorService extends BaseService $params['order_inquiry_id'] = $order_inquiry_id; OrderInquiry::edit($params,$data); - // 发送IM消息-医生接诊 - $imService = new ImService(); - $imService->doctorInquiry($order_inquiry,$user_info['user_id'],$order_inquiry['user_id']); - - // 发送站内、订阅、短信消息-医生已接诊 - $MessagePush = new MessagePush($order_inquiry['user_id'],$order_inquiry['order_inquiry_id']); - $MessagePush->patientAcceptedInquiry(); - + // 添加自动完成队列 if ($order_inquiry['inquiry_type'] == 1 || $order_inquiry['inquiry_type'] == 3){ // 专家问诊-公益问诊 $time = 1000 * 60 * 60; @@ -1690,7 +1673,6 @@ class UserDoctorService extends BaseService $time = 1000 * 60 * 30; } - // 添加自动完成队列 $data = array(); $data['order_inquiry_id'] = $order_inquiry['order_inquiry_id']; @@ -1708,6 +1690,18 @@ class UserDoctorService extends BaseService return fail(HttpEnumCode::SERVER_ERROR, $e->getMessage()); } + try { + // 发送IM消息-医生接诊 + $imService = new ImService(); + $imService->doctorInquiry($order_inquiry,$user_info['user_id'],$order_inquiry['user_id']); + + // 发送站内、订阅、短信消息-医生已接诊 + $MessagePush = new MessagePush($order_inquiry['user_id'],$order_inquiry['order_inquiry_id']); + $MessagePush->patientAcceptedInquiry(); + }catch(\Exception $e){ + return success([],HttpEnumCode::HTTP_SUCCESS,$e->getMessage()); + } + return success(); } diff --git a/app/Services/UserPharmacistService.php b/app/Services/UserPharmacistService.php index 73088eb..1da787a 100644 --- a/app/Services/UserPharmacistService.php +++ b/app/Services/UserPharmacistService.php @@ -8,6 +8,7 @@ use App\Amqp\Producer\PrescriptionExpiredDelayDirectProducer; use App\Constants\HttpEnumCode; use App\Model\OrderInquiry; use App\Model\OrderPrescription; +use App\Model\OrderPrescriptionFile; use App\Model\OrderPrescriptionProduct; use App\Model\User; use App\Model\UserDoctor; @@ -100,7 +101,6 @@ class UserPharmacistService extends BaseService "prescription_status", "pharmacist_audit_status", "platform_audit_status", - "prescription_img", "doctor_id", ]; @@ -112,6 +112,16 @@ class UserPharmacistService extends BaseService return fail(); } + // 获取处方文件数据 + $params = array(); + $params['order_prescription_id'] = $order_prescription_id; + $order_prescription_file = OrderPrescriptionFile::getOne($params); + if (empty($order_prescription_file)){ + return fail(); + } + + $order_prescription['prescription_img_oss_path'] = addAliyunOssWebsite($order_prescription_file['prescription_img_oss_path']); + $order_prescription['prescription_img'] = addAliyunOssWebsite($order_prescription['prescription_img']); // 获取处方中医生签名 @@ -134,6 +144,7 @@ class UserPharmacistService extends BaseService */ public function putPrescriptionVerify(): array { + return fail(HttpEnumCode::SERVER_ERROR,"暂时无法人工审核"); $user_info = $this->request->getAttribute("userInfo") ?? []; $order_prescription_id = $this->request->route('order_prescription_id'); @@ -164,7 +175,7 @@ class UserPharmacistService extends BaseService // 验证处方状态 if ($order_prescription['prescription_status'] != 1){ - // 处方状态(1:待审核 3:待使用 4:已失效 5:已使用) + // 处方状态(1:待审核 2:待使用 3:已失效 4:已使用) return fail(HttpEnumCode::HTTP_ERROR,"处方审核失败"); } @@ -332,4 +343,6 @@ class UserPharmacistService extends BaseService return success($result); } + + } \ No newline at end of file diff --git a/extend/Alibaba/Oss.php b/extend/Alibaba/Oss.php index 0e1ebb4..092c3d2 100644 --- a/extend/Alibaba/Oss.php +++ b/extend/Alibaba/Oss.php @@ -161,4 +161,18 @@ class Oss } } + /** + * 判断指定的文件是否存在 + * @param string $filename + * @return bool + */ + public function doesObjectExist(string $filename): bool + { + try { + $ossClient = $this->createClient(); + return $ossClient->doesObjectExist($this->config['bucket'], $filename); + }catch(\Exception $e) { + throw new BusinessException($e->getMessage()); + } + } } \ No newline at end of file