hospital-applets-api/app/Services/OrderPrescriptionService.php

571 lines
26 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Services;
use App\Constants\HttpEnumCode;
use App\Exception\BusinessException;
use App\Model\Coupon;
use App\Model\OrderInquiry;
use App\Model\OrderPrescriptionFile;
use App\Model\OrderProduct;
use App\Model\OrderProductCoupon;
use App\Model\PatientFamily;
use App\Model\Product;
use App\Model\UserCaCert;
use App\Model\HospitalDepartmentCustom;
use App\Model\OrderInquiryCase;
use App\Model\OrderPrescription;
use App\Model\OrderPrescriptionIcd;
use App\Model\OrderPrescriptionProduct;
use App\Model\OrderProductItem;
use App\Model\User;
use App\Model\UserCoupon;
use App\Model\UserDoctor;
use App\Model\UserDoctorInfo;
use App\Model\UserPharmacist;
use App\Model\UserPharmacistInfo;
use App\Utils\Log;
use Extend\Alibaba\Oss;
use Extend\Ca\Ca;
use Extend\Ca\CaOffline;
use Extend\Ca\CaOnline;
use Extend\Prescription\Prescription;
use Hyperf\Contract\LengthAwarePaginatorInterface;
use \Hyperf\Coroutine\WaitGroup;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Swoole\Coroutine\Channel;
use TCPDF;
use Hyperf\Coroutine;
class OrderPrescriptionService extends BaseService
{
/**
* 获取医生是否存在被驳回处方
* @param string $doctor_id 医生id
* @return bool
*/
public function getDoctorExistsAuditFail(string $doctor_id): bool
{
$params = array();
$params['doctor_id'] = $doctor_id;
$params['pharmacist_audit_status'] = 2;// 处方审核状态0:审核中 1:审核成功 2:审核驳回)
$params['platform_audit_status'] = 1;// 处方平台审核状态0:审核中 1:审核成功 2:审核驳回)
$params['is_delete'] = 0;// 是否删除0:否 1:是)
return OrderPrescription::getExists($params);
}
/**
* 获取药师待审核处方-分页
* @param string $pharmacist_id 药师id
* @param int $pharmacist_audit_status 药师审核状态0:审核中 1:审核成功 2:审核驳回)
* @param int $platform_audit_status
* @param string|int $page
* @param string|int $per_page
* @return array
*/
public function getPharmacistWaitAuditPage(string $pharmacist_id, int $pharmacist_audit_status, int $platform_audit_status, string|int $page = 1, string|int $per_page = 10): array
{
$params = array();
$params['pharmacist_id'] = $pharmacist_id;
if ($pharmacist_audit_status == 0 && $platform_audit_status == 0){
$params['prescription_status'] = 1; // 处方状态1:待审核 2:待使用 3:已失效 4:已使用)
}
$params['pharmacist_audit_status'] = $pharmacist_audit_status; // 药师审核状态0:审核中 1:审核成功 2:审核驳回)
$params['platform_audit_status'] = $platform_audit_status; // 处方平台审核状态0:审核中 1:审核成功 2:审核驳回)
return OrderPrescription::getPage($params, ['*'], $page, $per_page);
}
/**
* 获取处方中开方药品
* @param string|int $order_prescription_id
* @return array
*/
public function getproductList(string|int $order_prescription_id): array
{
$params = array();
$params['order_prescription_id'] = $order_prescription_id;
$order_prescription_products = OrderPrescriptionProduct::getLimit($params);
if (empty($order_prescription_products)) {
return [];
}
$result = [];
foreach ($order_prescription_products as $order_prescription_product) {
$data = array();
$data['product_id'] = $order_prescription_product['product_id'];
$data['prescription_product_num'] = $order_prescription_product['prescription_product_num'];
$data['product_name'] = $order_prescription_product['product_name'] ?? "";
$data['product_spec'] = $order_prescription_product['product_spec'] ?? "";
$data['single_unit'] = $order_prescription_product['single_unit'] ?? "";
$data['single_use'] = $order_prescription_product['single_use'] ?? "";
$data['packaging_unit'] = $order_prescription_product['packaging_unit'] ?? "";
$data['frequency_use'] = $order_prescription_product['frequency_use'] ?? "";
$data['available_days'] = $order_prescription_product['available_days'] ?? 0;
$result[] = $data;
}
unset($order_product_items);
return $result;
}
/**
* 获取患者某一状态下的处方数量
* @param string $patient_id 患者id
* @param int $prescription_status 处方状态1:待审核 2:待使用 3:已失效 4:已使用)
* @return int
*/
public function getPatientPrescriptionWithStatus(string $patient_id, int $prescription_status): int
{
$params = array();
$params['patient_id'] = $patient_id;
$params['prescription_status'] = $prescription_status;
$params['pharmacist_audit_status'] = 1;
return OrderPrescription::getCount($params);
}
/**
* 开具处方
* 医生-正常开具
* 药师-先开具药师处方,再开具医院签章
* @param string $order_prescription_id 处方id
* @param string $user_id 用户id
* @param int $type 类型 1医院 2医生 3药师
* @return array
*/
public function openPrescription(string $order_prescription_id,int $type,string $user_id = ""): array
{
try {
// 获取处方数据
$params = array();
$params['order_prescription_id'] = $order_prescription_id;
$order_prescription = OrderPrescription::getOne($params);
if (empty($order_prescription)) {
throw new BusinessException("处方数据错误");
}
if (empty($order_prescription['doctor_created_time'])) {
throw new BusinessException("医生开方日期错误");
}
$CaService = new CaService($order_prescription,$type,$user_id);
// 获取云证书签名+验证云证书签名
$CaService->getVerifyCertSign($order_prescription);
if ($type == 2) {
// 生成处方图片+处方图片生成pdf
$prescription_img_oss_path = $CaService->createPrescriptionImgPdf($order_prescription);
}else{
// 下载已经开具的处方pdf至本地
$CaService->downOssPdfToLocal();
}
// 进行处方pdf签章
$file_id = $CaService->addSignPdf($type);
$result = array();
$result['prescription_img_oss_path'] = $prescription_img_oss_path ?? "";
$result['file_id'] = $file_id;
return $result;
} catch (\Throwable $e) {
throw new BusinessException($e->getMessage());
}
}
/**
* 上报处方平台
* @param string $order_product_id 商品订单id
* @return bool
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function reportPrescription(string $order_product_id): bool
{
// 获取商品订单数据
$params = array();
$params['order_product_id'] = $order_product_id;
$order_product = OrderProduct::getOne($params);
if (empty($order_product)) {
throw new BusinessException("上报处方平台失败:商品订单数据错误");
}
// 获取处方数据
$params = array();
$params['order_prescription_id'] = $order_product['order_prescription_id'];
$order_prescription = OrderPrescription::getOne($params);
if (empty($order_prescription)) {
throw new BusinessException("上报处方平台失败:处方数据错误");
}
// 获取问诊订单数据
$params = array();
$params['order_inquiry_id'] = $order_prescription['order_inquiry_id'];
$order_inquiry = OrderInquiry::getOne($params);
if (empty($order_inquiry)) {
throw new BusinessException("上报处方平台失败:问诊订单数据错误");
}
// 获取商品订单列表数据
$params = array();
$params['order_product_id'] = $order_product['order_product_id'];
$order_product_item = OrderProductItem::getList($params);
if (empty($order_product_item)) {
throw new BusinessException("上报处方平台失败:商品订单列表数据错误");
}
$wg = new WaitGroup();
$wg->add(9);
$user = []; // 就诊患者用户数据
$patient_family = []; // 家庭成员-基本信息
$order_prescription_icd = []; // 处方关联疾病数据
$user_doctor = []; // 医生数据
$user_doctor_info = []; // 医生详情数据
$user_pharmacist = []; // 药师数据
$user_pharmacist_info = []; // 药师详数据
$order_inquiry_case = []; // 病例数据
$product_coupons = []; // 药品优惠券数据
$user_id = $order_inquiry['user_id'];
$doctor_id = $order_prescription['doctor_id'];
$family_id = $order_inquiry['family_id'];
$pharmacist_id = $order_prescription['pharmacist_id'];
$order_inquiry_id = $order_inquiry['order_inquiry_id'];
$order_product_id = $order_product['order_product_id'];
// 获取就诊患者用户数据
Coroutine\co(function () use ($wg, &$user, $user_id) {
$params = array();
$params['user_id'] = $user_id;
$user = User::getOne($params)->toArray();
// 计数器减一
$wg->done();
});
// 获取家庭成员-基本信息
Coroutine\co(function () use ($wg, &$patient_family, $family_id) {
$params = array();
$params['family_id'] = $family_id;
$patient_family = PatientFamily::getOne($params);
// 计数器减一
$wg->done();
});
// 获取处方关联疾病数据
$order_prescription_id = $order_prescription['order_prescription_id'];
Coroutine\co(function () use ($wg, &$order_prescription_icd, $order_prescription_id) {
$params = array();
$params['order_prescription_id'] = $order_prescription_id;
$order_prescription_icd = OrderPrescriptionIcd::getList($params);
// 计数器减一
$wg->done();
});
// 获取医生数据
Coroutine\co(function () use ($wg, &$user_doctor, $doctor_id) {
$params = array();
$params['doctor_id'] = $doctor_id;
$user_doctor = UserDoctor::getOne($params);
// 计数器减一
$wg->done();
});
// 获取医生详情数据
Coroutine\co(function () use ($wg, &$user_doctor_info, $doctor_id) {
$params = array();
$params['doctor_id'] = $doctor_id;
$user_doctor_info = UserDoctorInfo::getOne($params);
// 计数器减一
$wg->done();
});
// 获取药师数据
Coroutine\co(function () use ($wg, &$user_pharmacist, $pharmacist_id) {
$params = array();
$params['pharmacist_id'] = $pharmacist_id;
$user_pharmacist = UserPharmacist::getOne($params);
// 计数器减一
$wg->done();
});
// 获取药师详情数据
Coroutine\co(function () use ($wg, &$user_pharmacist_info, $pharmacist_id) {
$params = array();
$params['pharmacist_id'] = $pharmacist_id;
$user_pharmacist_info = UserPharmacistInfo::getOne($params);
// 计数器减一
$wg->done();
});
// 获取病例数据
Coroutine\co(function () use ($wg, &$order_inquiry_case, $order_inquiry_id) {
$params = array();
$params['order_inquiry_id'] = $order_inquiry_id;
$params['status'] = 1;
$order_inquiry_case = OrderInquiryCase::getOne($params);
// 计数器减一
$wg->done();
});
// 获取药品订单优惠券数据
Coroutine\co(function () use ($wg, &$product_coupons, $order_product_id) {
$params = array();
$params['order_product_id'] = $order_product_id;
$order_product_coupons = OrderProductCoupon::getList($params);
foreach ($order_product_coupons as $order_product_coupon){
$params = array();
$params['user_coupon_id'] = $order_product_coupon['user_coupon_id'];
$user_coupon = UserCoupon::getOne($params);
if (!empty($user_coupon)){
$params = array();
$params['coupon_id'] = $user_coupon['coupon_id'];
$coupon = Coupon::getOne($params);
if (!empty($coupon)){
$product_coupons[] = $coupon->toArray();
}
}
}
// 计数器减一
$wg->done();
});
$wg->wait();
if (empty($user)) {
throw new BusinessException("用户数据错误");
}
if (empty($patient_family)) {
throw new BusinessException("用户家庭成员错误");
}
if (empty($order_prescription_icd)) {
throw new BusinessException("处方疾病数据错误");
}
if (empty($user_doctor)) {
throw new BusinessException("医生数据错误");
}
if (empty($user_doctor_info)) {
throw new BusinessException("医生详情数据错误");
}
if (empty($user_pharmacist)) {
throw new BusinessException("药师数据错误");
}
if (empty($user_pharmacist_info)) {
throw new BusinessException("药师详情数据错误");
}
if (empty($order_inquiry_case)) {
throw new BusinessException("病例数据错误");
}
// 处理疾病数据
$icd_name = array_column($order_prescription_icd->toArray(), 'icd_name');
if (!empty($icd_name)) {
if (count($icd_name) > 1) {
$icd_name = implode(';', $icd_name);
} else {
$icd_name = $icd_name[0];
}
} else {
$icd_name = "";
}
// 获取医生科室
$params = array();
$params['department_custom_id'] = $user_doctor['department_custom_id'];
$hospital_department_custom = HospitalDepartmentCustom::getOne($params);
if (empty($hospital_department_custom)) {
throw new BusinessException("医生科室数据错误");
}
// 处方pdf地址
$prescription_pdf_oss_path = "/applet/prescription/" . $order_prescription["order_prescription_id"] . ".pdf";
$arg = array();
$arg['terminalCode'] = "ZD-10003";
$arg['orderNo'] = $order_product['order_product_no']; // 订单编号
$arg['transactNo'] = $order_product['escrow_trade_no']; // 流水单号
$arg['payDate'] = $order_product['pay_time']; // 支付时间
$arg['money'] = $order_product['payment_amount_total']; // 订单金额
$arg['freight'] = $order_product['logistics_fee']; // 运费(单位:元)
$arg['takeTypeCode'] = 2; // 取货方式 1 自提 2 快递,目前只支持快递,传固定值 2
$arg['buyerName'] = $order_product['consignee_name'];// 收货人姓名
$arg['buyerPhone'] = $order_product['consignee_tel'];// 收货人联系方式
$arg['buyerAddress'] = $order_product['address'];// 收货人地址
$arg['provinceCode'] = $order_product['province_id']; // 收货地址(省) 编码
$arg['provinceName'] = $order_product['province']; // 收货地址(省) 名称
$arg['cityCode'] = $order_product['city_id']; // 收货地址(市) 编码
$arg['cityName'] = $order_product['city']; // 收货地址(市) 名称
$arg['districtCode'] = $order_product['county_id']; // 收货地址(区 县)编码
$arg['districtName'] = $order_product['county']; // 收货地址(区 县)名称
$arg['presList'][0]['prescriptionNo'] = $order_prescription['prescription_code']; // 处方编号
$arg['presList'][0]['prescriptionSubType'] = 1; // 处方类型 0无类型 1普 通处方 2儿科处 方
$arg['presList'][0]['patientName'] = $order_prescription['patient_name']; // 就诊人姓名
$arg['presList'][0]['patientPhone'] = $user['mobile']; // 就诊人联系方式
$arg['presList'][0]['idCard'] = $patient_family['id_number']; // 身份证号
$arg['presList'][0]['advice'] = $order_prescription['doctor_advice'] ?: ""; // 医嘱
$arg['presList'][0]['diagnosisName'] = $icd_name ?: ""; // 诊断
$arg['presList'][0]['thirdDoctorName'] = $user_doctor['user_name']; // 开方医生姓名
$arg['presList'][0]['thirdDeptName'] = $hospital_department_custom['department_name'] ?: ""; // 开方科室名称
$arg['presList'][0]['thirdDoctorNameImg'] = addAliyunOssWebsite($user_doctor_info['sign_image']); // 开方医生签名链接
$arg['presList'][0]['prescriptionTime'] = $order_prescription['doctor_created_time']; // 开方时间
$arg['presList'][0]['thirdFirstPharmacist'] = $user_pharmacist['user_name']; // 初审药师姓名
$arg['presList'][0]['thirdFirstPharmacistImg'] = addAliyunOssWebsite($user_pharmacist_info['sign_image']); // 初审药师签名链接
$arg['presList'][0]['thirdFirstTime'] = $order_prescription['pharmacist_verify_time']; // 初审时间
$arg['presList'][0]['thirdLastPharmacist'] = $user_pharmacist['user_name']; // 终审药师姓名
$arg['presList'][0]['thirdLastPharmacistImg'] = addAliyunOssWebsite($user_pharmacist_info['sign_image']); // 终审药师签名 链接
$arg['presList'][0]['thirdLastTime'] = $order_prescription['pharmacist_verify_time']; // 终审时间
$arg['presList'][0]['thirdSignImg'] = addAliyunOssWebsite("/basic/file/hospital_signature.png"); // 处方签章链接
$arg['presList'][0]['referenceCharge'] = $order_product['amount_total']; // 处方费用(不包含运费)
$arg['presList'][0]['chiefComplaint'] = $order_inquiry_case['disease_desc'] ?: ""; // 主诉
$arg['presList'][0]['historyPresent'] = $order_inquiry_case['disease_class_name'] ?: ""; // 现病史
$arg['presList'][0]['pastHistory'] = $order_inquiry_case['family_history'] ?: ""; // 既往史
$arg['presList'][0]['physicalExamination'] = ""; // 体格检查
$arg['presList'][0]['supplementaryExamination'] = ""; // 辅助检查
$arg['presList'][0]['allergicHistory'] = $order_inquiry_case['allergy_history'] ?: ""; // 过敏史
$arg['presList'][0]['prescriptionSignedUrl'] = addAliyunOssWebsite($prescription_pdf_oss_path) ?: "";
// 药品数据
foreach ($order_product_item as $key => $item) {
// 获取商品数据
$params = array();
$params['product_id'] = $item['product_id'];
$product = Product::getOne($params);
if (empty($product)) {
throw new BusinessException("药品数据错误");
}
$arg['presList'][0]['drugList'][$key]['drugCode'] = $product['product_platform_code']; // 药品编码
$arg['presList'][0]['drugList'][$key]['approvalNumber'] = $product['license_number']; // 批准文号
$arg['presList'][0]['drugList'][$key]['drugName'] = $product['product_name']; // 药品名称
// $arg['presList'][0]['drugList'][$key]['specifications'] = $product['product_spec']; // 药品规格
$arg['presList'][0]['drugList'][$key]['price'] = $product['product_price']; // 药品单价
$arg['presList'][0]['drugList'][$key]['packingCount'] = $item['amount']; // 药品数量
$arg['presList'][0]['drugList'][$key]['surplusPackingCount'] = 0; // 处方药品剩余使用数量
$arg['presList'][0]['drugList'][$key]['packingUnit'] = $product['packaging_unit']; // 药品单位
$arg['presList'][0]['drugList'][$key]['singleDosage'] = 1; // 单次用量
$arg['presList'][0]['drugList'][$key]['singleDosageUnit'] = ""; // 单次用量单位
$arg['presList'][0]['drugList'][$key]['useName'] = $product['single_use']; // 用法名称
$arg['presList'][0]['drugList'][$key]['frequencyName'] = $product['frequency_use']; // 频次名称
$arg['presList'][0]['drugList'][$key]['useDays'] = $product['available_days'] ? $product['available_days'] * $item['amount'] : 7; // 使用天数
$arg['presList'][0]['orderDrugList'][$key]['drugCode'] = $product['product_platform_code']; // 药品编码
$arg['presList'][0]['orderDrugList'][$key]['approvalNumber'] = $product['license_number']; // 批准文号
$arg['presList'][0]['orderDrugList'][$key]['drugName'] = $product['product_name']; // 药品名称
// $arg['presList'][0]['orderDrugList'][$key]['specifications'] = $product['product_spec']; // 药品规格
$arg['presList'][0]['orderDrugList'][$key]['price'] = $product['product_price']; // 药品单价
$arg['presList'][0]['orderDrugList'][$key]['drugCount'] = $item['amount']; // 药品数量
$arg['presList'][0]['orderDrugList'][$key]['packingUnit'] = $product['packaging_unit']; // 药品单位
$arg['presList'][0]['orderDrugList'][$key]['actualSellingPrice'] = $item['actual_product_price']; // 药品实际销售单价
}
// 处理上报处方平台药品优惠券相关数据
$arg['promotion'] = $this->handleReportPrescriptionProductCouponData($product_coupons,$order_product_item,$order_product['order_product_no']);
$Prescription = new Prescription();
$result = $Prescription->reportPrescription($arg);
if ($result['resultCode'] != "1000"){
if(!empty($result['resultDesc'])){
throw new BusinessException("上报处方平台失败:" .$result['resultDesc']);
}
throw new BusinessException("上报处方平台失败:操作编码:" . $result['resultCode']);
}
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());
}
}
/**
* 处理上报处方平台药品优惠券相关数据
* @param array $product_coupons 药品订单优惠券为coupon数据
* @param array|object $order_product_item 药品订单明细
* @param string $orderNo 药品订单编号
* @return array
*/
public function handleReportPrescriptionProductCouponData(array $product_coupons,array|object $order_product_item,string $orderNo): array
{
$promotion = array();
if (empty($product_coupons)){
return $promotion;
}
foreach ($product_coupons as $product_coupon){
// 适用范围1:全场通用 2:问诊 3:按品牌适用 4:按类别适用 5:单品使用 6:全品类药品)
if ($product_coupon["application_scope"] == 1 || $product_coupon["application_scope"] == 6){
$result = array();
$result["type"] = "orderCoupons";
$result["objectId"] = $orderNo;
$result["amount"] = $product_coupon["coupon_price"]; // 优惠金额
$result["count"] = 1;
$promotion[] = $result;
}
if ($product_coupon["application_scope"] == 5){
$product_ids = explode(',',$product_coupon['product_id']);
foreach ($order_product_item as $value){
if (in_array($value['product_id'],$product_ids)){
$result = array();
$result["type"] = "productCoupons";
$result["objectId"] = $value['product_platform_code'];
$result["amount"] = bcsub($value["product_price"],$value["actual_product_price"],2); // 优惠金额
$result["count"] = 1;
$promotion[] = $result;
}
}
}
}
return $promotion;
}
}