Files
hospital-applets-api/app/Amqp/Consumer/AutoFinishInquiryDelayDirectConsumer.php
T
2023-05-10 09:34:00 +08:00

526 lines
21 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Amqp\Consumer;
use App\Model\DoctorAccount;
use App\Model\DoctorAccountDay;
use App\Model\OrderEvaluation;
use App\Model\OrderInquiry;
use App\Model\OrderInquiryCase;
use App\Model\OrderPrescription;
use App\Model\PatientFamilyHealth;
use App\Model\PatientFamilyPersonal;
use App\Model\UserDoctor;
use App\Model\UserPatient;
use App\Services\ImService;
use App\Services\MessagePush;
use App\Utils\Log;
use App\Utils\Mask;
use Hyperf\Amqp\Message\ConsumerDelayedMessageTrait;
use Hyperf\Amqp\Message\ProducerDelayedMessageTrait;
use Hyperf\Amqp\Message\Type;
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(nums: 1)]
class AutoFinishInquiryDelayDirectConsumer extends ConsumerMessage
{
use ProducerDelayedMessageTrait;
use ConsumerDelayedMessageTrait;
protected string $exchange = 'amqp.delay.direct';
protected ?string $queue = 'auto.finish.inquiry.delay.queue';
protected string $type = Type::DIRECT; //Type::FANOUT;
protected string|array $routingKey = 'AutoFinishInquiry';
public function consumeMessage($data, AMQPMessage $message): string
{
Log::getInstance("queue-AutoFinishInquiry")->info("开始:" . json_encode($data, JSON_UNESCAPED_UNICODE));
Db::beginTransaction();
try {
// 检测入参参数
if (empty($data['order_inquiry_id'])) {
Db::rollBack();
Log::getInstance("queue-AutoFinishInquiry")->error("错误:入参错误");
return Result::DROP;
}
// 获取问诊订单数据
$params = array();
$params['order_inquiry_id'] = $data['order_inquiry_id'];
$order_inquiry = OrderInquiry::getOne($params);
if (empty($order_inquiry)) {
Db::rollBack();
Log::getInstance("queue-AutoFinishInquiry")->error("错误:问诊订单数据为空");
return Result::DROP;
}
$order_inquiry = $order_inquiry->toArray();
// 问诊订单状态(1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消)
if ($order_inquiry['inquiry_status'] != 5) {
Db::rollBack();
Log::getInstance("queue-AutoFinishInquiry")->error("错误:问诊订单未完成,无法结束");
return Result::DROP;
}
// 问诊订单退款状态(0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭 6:退款异常)
if (!in_array($order_inquiry['inquiry_refund_status'], [0, 4, 5])) {
Db::rollBack();
Log::getInstance("queue-AutoFinishInquiry")->error("错误:问诊订单正在申请退款");
return Result::DROP;
}
if (empty($order_inquiry['doctor_id'])) {
Db::rollBack();
Log::getInstance("queue-AutoFinishInquiry")->error("错误:医生id为空");
return Result::DROP;
}
// 处理统计问题
if ($order_inquiry['amount_total'] > 0) {
// 处理医生账户总表
$res = $this->handleDoctorAccount($order_inquiry);
if (!$res) {
Db::rollBack();
Log::getInstance("queue-AutoFinishInquiry")->error("错误:处理医生账户总表失败");
return Result::DROP;
}
// 处理医生账户表-日
$res = $this->handleDoctorAccountDay($order_inquiry);
if (!$res) {
Db::rollBack();
Log::getInstance("queue-AutoFinishInquiry")->error("错误:处理医生账户表-日失败");
return Result::DROP;
}
}
// 处理问诊订单表
$this->handleOrderInquiry($order_inquiry);
// 处理订单评价
$this->handleOrderEvaluation($order_inquiry);
// 处理回写患者病例-回写失败不做处理
$this->handleOrderInquiryCase($order_inquiry);
// 处理医生服务患者数量
$this->handleDoctorServedPatientsNum($order_inquiry['doctor_id']);
// 计算医生好评率
$this->computeDoctorPraiseRate($order_inquiry['doctor_id']);
// 计算医生平均响应时间
$this->computeDoctorAvgPesponseTime($order_inquiry['doctor_id']);
Db::commit();
Log::getInstance("queue-AutoFinishInquiry")->info("成功");
} catch (\Exception $e) {
Db::rollBack();
Log::getInstance("queue-AutoFinishInquiry")->error("错误:" . $e->getMessage());
return Result::ACK; // 重回队列
}
// 推送消息
try {
// 推送问诊结束im消息
$this->pushImInquiryFinish($order_inquiry);
}catch (\Exception $e){
Log::getInstance("queue-AutoFinishInquiry")->error("发送消息异常错误:" . $e->getMessage());
}
return Result::ACK;
}
/**
* 处理医生账户总表
* 创建/修改医生账户总表中总金额、账户余额数据
* @param array|object $order_inquiry
* @return bool
*/
protected function handleDoctorAccount(array|object $order_inquiry): bool
{
$params = array();
$params['doctor_id'] = $order_inquiry['doctor_id'];
$doctor_account = DoctorAccount::getOne($params);
if (empty($doctor_account)) {
// 首次
$data = array();
$data['doctor_id'] = $order_inquiry['doctor_id'];
$data['total_amount'] = $order_inquiry['amount_total'] * 0.75;
$data['balance_account'] = $order_inquiry['amount_total'] * 0.75;
$data['applied_withdrawal_amount'] = 0;
$data['actual_withdrawal_amount'] = 0;
$data['income_tax'] = 0;
$doctor_account = DoctorAccount::addDoctorAccount($data);
if (empty($doctor_account)) {
return false;
}
} else {
// 非首次
// 总金额(已结束订单的总金额)
$params = array();
$params['account_id'] = $doctor_account['account_id'];
DoctorAccount::inc($params, 'total_amount', $order_inquiry['amount_total'] * 0.75);
// 账户余额
DoctorAccount::inc($params, 'balance_account', $order_inquiry['amount_total'] * 0.75);
}
return true;
}
/**
* 处理医生账户表-日
* @param array|object $order_inquiry
* @return bool
*/
protected function handleDoctorAccountDay(array|object $order_inquiry): bool
{
$params = array();
$params['doctor_id'] = $order_inquiry['doctor_id'];
$params['date'] = date('Y-m-d', strtotime($order_inquiry['created_at']));
$doctor_account_day = DoctorAccountDay::getOne($params);
if (empty($doctor_account_day)) {
// 当日首次
$data = array();
$data['doctor_id'] = $order_inquiry['doctor_id'];
$data['year'] = date('Y', strtotime($order_inquiry['created_at']));
$data['month'] = date('m', strtotime($order_inquiry['created_at']));
$data['day'] = date('d', strtotime($order_inquiry['created_at']));
$data['date'] = date('Y-m-d', strtotime($order_inquiry['created_at']));
$data['total_amount'] = $order_inquiry['amount_total'] * 0.75;
$doctor_account_day = DoctorAccountDay::addDoctorAccountDay($data);
if (empty($doctor_account_day)) {
return false;
}
} else {
// 非当日首次
$params = array();
$params['account_detail_id'] = $doctor_account_day['account_detail_id'];
DoctorAccountDay::inc($params, 'total_amount', $order_inquiry['amount_total'] * 0.75);
}
return true;
}
/**
* 处理问诊订单表
* @param array|object $order_inquiry
* @return void
*/
protected function handleOrderInquiry(array|object $order_inquiry): void
{
$params = array();
$params['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
$data = array();
$data['inquiry_status'] = 6; // 问诊订单状态(1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消)
$data['finish_time'] = date('Y-m-d H:i:s', time()); // 订单结束时间
$data['statistics_status'] = 1; // 订单统计状态(0:未统计 1:已统计 2:统计失败)
$data['statistics_time'] = date('Y-m-d H:i:s', time()); // 订单统计时间
$data['updated_at'] = date('Y-m-d H:i:s', time()); // 修改时间
OrderInquiry::edit($params, $data);
}
/**
* 处理订单评价
* @param array|object $order_inquiry
* @return bool
*/
protected function handleOrderEvaluation(array|object $order_inquiry): bool
{
$params = array();
$params['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
$order_evaluation = OrderEvaluation::getOne($params);
if (!empty($order_evaluation)) {
// 已评价
return true;
}
// 获取用户数据
$params = array();
$params['patient_id'] = $order_inquiry['patient_id'];
$user_patient = UserPatient::getOne($params);
// 未评价
$data = array();
$data['doctor_id'] = $order_inquiry['doctor_id'];
$data['patient_id'] = $order_inquiry['patient_id'];
$data['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
$data['name_mask'] = Mask::maskNameStr($user_patient['user_name'],2);
$data['reply_quality'] = 100;//回复质量(百分制)
$data['service_attitude'] = 100; // 服务态度(百分制)
$data['reply_progress'] = 100; // 回复速度(百分制)
$data['avg_score'] = 100; // 平均得分(百分制,回复质量占4、服务态度占3、回复速度占3,计算公式:每个得分 * 占比 相加)
$data['type'] = 1; // 类型(1:默认评价 2:主动评价)
$data['content'] = "感谢您的服务";
$order_evaluation = OrderEvaluation::addOrderEvaluation($data);
if (empty($order_evaluation)) {
return false;
}
return true;
}
/**
* 处理回写患者病例
* 回写失败不做处理
* @param array|object $order_inquiry
* @return void
*/
protected function handleOrderInquiryCase(array|object $order_inquiry): void
{
// 获取订单-问诊病例表
$params = array();
$params['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
$order_inquiry_case = OrderInquiryCase::getOne($params);
if (!empty($order_inquiry_case)) {
// 获取患者家庭成员信息表-健康情况
$params = array();
$params['family_id'] = $order_inquiry['family_id'];
$params['patient_id'] = $order_inquiry['patient_id'];
$patient_family_health = PatientFamilyHealth::getOne($params);
if (empty($patient_family_health)) {
// 表数据为空
$data = array();
$data['family_id'] = $order_inquiry['family_id'];
$data['patient_id'] = $order_inquiry['patient_id'];
$data['disease_class_id'] = $order_inquiry_case['disease_class_id']; // 疾病分类id-系统
$data['disease_class_name'] = $order_inquiry_case['disease_class_name']; // 疾病名称-系统
$data['diagnosis_date'] = $order_inquiry_case['diagnosis_date']; // 确诊日期
$patient_family_health = PatientFamilyHealth::addPatientFamilyHealth($data);
if (empty($patient_family_health)) {
Log::getInstance("queue-AutoFinishInquiry")->error("错误:回写患者家庭成员信息表-健康情况表失败");
}
} else {
$data = array();
if ($order_inquiry_case['disease_class_id'] != $patient_family_health['disease_class_id']) {
$data['disease_class_id'] = $order_inquiry_case['disease_class_id']; // 疾病分类id-系统
}
if ($order_inquiry_case['disease_class_name'] != $patient_family_health['disease_class_name']) {
$data['disease_class_name'] = $order_inquiry_case['disease_class_name']; // 疾病名称-系统
}
if ($order_inquiry_case['diagnosis_date'] != $patient_family_health['diagnosis_date']) {
$data['diagnosis_date'] = $order_inquiry_case['diagnosis_date']; // 确诊日期
}
if (!empty($data)) {
$params = array();
$params['family_health_id'] = $patient_family_health['family_health_id'];
PatientFamilyHealth::edit($params, $data);
}
}
// 获取患者家庭成员信息表-个人情况
$params = array();
$params['family_id'] = $order_inquiry['family_id'];
$params['patient_id'] = $order_inquiry['patient_id'];
$patient_family_personal = PatientFamilyPersonal::getOne($params);
if (empty($patient_family_personal)) {
$data = array();
$data['family_id'] = $order_inquiry['family_id'];
$data['patient_id'] = $order_inquiry['patient_id'];
if ($order_inquiry_case['is_allergy_history'] !== null) {
$data['is_allergy_history'] = $order_inquiry_case['is_allergy_history']; // 是否存在过敏史(0:否 1:是)
}
if ($order_inquiry_case['allergy_history'] != null) {
$data['allergy_history'] = $order_inquiry_case['allergy_history']; // 过敏史描述
}
if ($order_inquiry_case['is_family_history'] !== null) {
$data['is_family_history'] = $order_inquiry_case['is_family_history']; // 是否存在家族病史(0:否 1:是)
}
if ($order_inquiry_case['family_history'] != null) {
$data['family_history'] = $order_inquiry_case['family_history']; // 家族病史描述
}
if ($order_inquiry_case['is_pregnant'] !== null) {
$data['is_pregnant'] = $order_inquiry_case['is_pregnant']; // 是否备孕、妊娠、哺乳期(0:否 1:是)
}
if ($order_inquiry_case['pregnant'] != null) {
$data['pregnant'] = $order_inquiry_case['pregnant']; // 是否备孕、妊娠、哺乳期(0:否 1:是)
}
$patient_family_personal = PatientFamilyPersonal::addPatientFamilyPersonal($data);
if (empty($patient_family_personal)) {
Log::getInstance("queue-AutoFinishInquiry")->error("错误:回写患者家庭成员信息表-个人情况表失败");
}
} else {
$data = array();
if ($order_inquiry_case['is_allergy_history'] !== $patient_family_personal['is_allergy_history']) {
$data['is_allergy_history'] = $order_inquiry_case['is_allergy_history']; // 是否存在过敏史(0:否 1:是)
}
if ($order_inquiry_case['allergy_history'] != $patient_family_personal['allergy_history']) {
$data['allergy_history'] = $order_inquiry_case['allergy_history']; // 过敏史描述
}
if ($order_inquiry_case['is_family_history'] !== $patient_family_personal['is_family_history']) {
$data['is_family_history'] = $order_inquiry_case['is_family_history']; // 是否存在家族病史(0:否 1:是)
}
if ($order_inquiry_case['family_history'] != $patient_family_personal['family_history']) {
$data['family_history'] = $order_inquiry_case['family_history']; // 家族病史描述
}
if ($order_inquiry_case['is_pregnant'] !== $patient_family_personal['is_pregnant']) {
$data['is_pregnant'] = $order_inquiry_case['is_pregnant']; // 是否备孕、妊娠、哺乳期(0:否 1:是)
}
if ($order_inquiry_case['pregnant'] != $patient_family_personal['pregnant']) {
$data['pregnant'] = $order_inquiry_case['pregnant']; // 是否备孕、妊娠、哺乳期(0:否 1:是)
}
if (!empty($data)) {
$params = array();
$params['family_personal_id'] = $patient_family_personal['family_personal_id'];
PatientFamilyPersonal::edit($params, $data);
}
}
}
}
/**
* 处理医生服务患者数量
* @param string $doctor_id
* @return void
*/
protected function handleDoctorServedPatientsNum(string $doctor_id): void
{
$params = array();
$params['doctor_id'] = $doctor_id;
UserDoctor::inc($params,'served_patients_num');
}
/**
* 处理医生好评率
* @param string $doctor_id
* @return int|void
*/
protected function computeDoctorPraiseRate(string $doctor_id)
{
// 获取该医生全部问诊评价总数
$params = array();
$params['doctor_id'] = $doctor_id;
$order_evaluation_count = OrderEvaluation::getCount($params);
if ($order_evaluation_count == 0){
return 0;
}
// 获取该医生好评的评价总数
$avg_score_params = [80, 100];
$good_quantity = OrderEvaluation::getScoreCount($params, $avg_score_params);
$praise_rate = floor(($good_quantity / $order_evaluation_count) * 100);
$params = array();
$params['doctor_id'] = $doctor_id;
$data = array();
$data['praise_rate'] = $praise_rate;
UserDoctor::editUserDoctor($params,$data);
}
/**
* 处理医生平均响应时间
* @param string $doctor_id
* @return void
*/
protected function computeDoctorAvgPesponseTime(string $doctor_id): void
{
// 统计数组
$avg_response_time = [];
// 获取该医生全部已结束问诊订单
$params = array();
$params['doctor_id'] = $doctor_id;
$params['inquiry_status'] = 6;
$order_inquiry = OrderInquiry::getList($params);
if (!empty($order_inquiry)){
$order_inquiry = $order_inquiry->toArray();
foreach ($order_inquiry as $item){
if (empty($item['reception_time'])){
continue;
}
$response_time = strtotime($item['reception_time']) - strtotime($item['created_at']);
if ($response_time < 0){
// 小于0的数据不统计
continue;
}
$avg_response_time[] = $response_time;
}
if (!empty($avg_response_time)){
$result = floor((array_sum($avg_response_time) / count($avg_response_time)) / 60 * 100) / 100;
$params = array();
$params['doctor_id'] = $doctor_id;
$data = array();
$data['avg_response_time'] = $result;
UserDoctor::editUserDoctor($params,$data);
}
}
}
/**
* 推送问诊结束im消息
* @param array|object $order_inquiry
* @return void
*/
protected function pushImInquiryFinish(array|object $order_inquiry): void
{
// 当前用户是否在这三天内再次咨询了该医生
$is_inquiry = false;
$params = array();
$params[] = ['user_id','=',$order_inquiry['user_id']];
$params[] = ['doctor_id','=',$order_inquiry['doctor_id']];
$params[] = ['created_at','>',$order_inquiry['created_at']];
$order_inquirys = OrderInquiry::getList($params);
if (!empty($order_inquirys)){
foreach ($order_inquirys as $item){
if ($item['order_inquiry_id'] == $order_inquiry['order_inquiry_id']){
continue;
}
$is_inquiry = true;
break;
}
}
if (!$is_inquiry){
// 获取医生数据
$params = array();
$params['doctor_id'] = $order_inquiry['doctor_id'];
$user_doctor = UserDoctor::getOne($params);
if (!empty($user_doctor)){
// 发送IM消息-问诊已结束
$imService = new ImService();
$imService->inquiryFinish($order_inquiry,$user_doctor['user_id'],$order_inquiry['user_id']);
}
}
}
}