where([ 'su_id' => \Yii::$app->user->identity->id, 'type' => 1, 'is_pay' => 1, 'accept_status' => OrderAcceptEnum::WAIT_ACCEPT, ])->count(); $wait_accepting_count = (int)Order::find()->where([ 'su_id' => \Yii::$app->user->identity->id, 'type' => 1, 'is_pay' => 1, 'accept_status' => OrderAcceptEnum::ACCEPTING, ])->count(); $wait_over_count = (int)Order::find()->where([ 'su_id' => \Yii::$app->user->identity->id, 'type' => 1, 'is_pay' => 1, 'accept_status' => [OrderAcceptEnum::REFUSED, OrderAcceptEnum::OVER, OrderAcceptEnum::TIMEOUT_ACCEPT, OrderAcceptEnum::CANCEL] ])->count(); return [ 'wait_accept_count' => $wait_accept_count, 'wait_accepting_count' => $wait_accepting_count, 'wait_over_count' => $wait_over_count, ]; } /** * @doc-name 咨询列表 * @doc-param int status 0全部1待接诊2咨询中3已结束 0 optional * @doc-param int type 1图文2视频 * @doc-param int page 页码 1 optional * @doc-param int page_size 每页条数 20 optional * @doc-return mixed @List{Order{id,user_id-int-用户,type-int-订单类型1图文2视频,avatarurl-string-用户头像,@Accept_info{status-int-状态,text-string-列表文字描述,text_detail-string-详情描述},@Message{no_read-int-未读条数,message-string-最新消息,message_time-int-发送时间,message_time_format-string-格式化时间},@Patient{id-int-患者问诊id,name-string-姓名,sex-int-1男2女,age-int-年龄}}} 咨询列表 * @doc-return mixed @Pagination{total_count-int-总数量,page_count-int-总页数,current_page-int-当前页,per_page-int-每页条数} 分页数据 */ public function actionList() { $post = \Yii::$app->request->post(); $query = Order::find()->where([ 'su_id' => \Yii::$app->user->identity->id, 'type' => $post['type'] ?? 1, 'is_pay' => 1 ])->with('inquiry','session','user')->orderBy(['id'=>SORT_DESC]); $status = ArrayHelper::getValue($post,'status',0); switch($status){ case 1: $query->andWhere([ 'accept_status' => OrderAcceptEnum::WAIT_ACCEPT ]); break; case 2: $query->andWhere([ 'accept_status' => OrderAcceptEnum::ACCEPTING ]); break; case 3: $query->andWhere([ 'accept_status' => [OrderAcceptEnum::REFUSED,OrderAcceptEnum::OVER,OrderAcceptEnum::TIMEOUT_ACCEPT,OrderAcceptEnum::CANCEL] ]); break; default: $query->andWhere([ '<>','accept_status',[OrderAcceptEnum::NO,OrderAcceptEnum::CANCEL] ]); break; } $this->field = [ Order::class => [ 'id', 'user_id', 'up_id', 'type', 'avatarurl' => 'user.avatarurl', 'accept_info' => function($model){ return Order::accept_info($model); }, 'ims_id' => 'session.ims_id', 'message' => function($model){ $ims_id = $model->session->ims_id; $count = ImMessage::find()->where([ 'ims_id' => $ims_id, 'user_id' => $model->user_id, 'service_id' => \Yii::$app->user->identity->id, // 'content_type' => ImMessageTypeEnum::COMMON, 'read_status' => 0, 'type' => ImMessageSendTypeEnum::USER_SEND, 'is_delete' => 0 ])->count(); //未接诊获取第一条病情描述,接诊了获取最新的一条消息 if($model->accept_status == OrderAcceptEnum::WAIT_ACCEPT){ $new = ImMessage::find()->where([ 'ims_id' => $ims_id, 'user_id' => $model->user_id, 'service_id' => \Yii::$app->user->identity->id, 'is_delete' => 0 ])->orderBy('id asc')->one(); }else{ $new = ImMessage::find()->where([ 'ims_id' => $ims_id, 'user_id' => $model->user_id, 'service_id' => \Yii::$app->user->identity->id, 'is_delete' => 0 ])->orderBy('id desc')->one(); } return [ 'no_read' => $count, 'message' => $new->content, 'message_time' => $new->created_at, 'message_time_format' => FuncHelper::time_tran($new->created_at) ]; }, 'patient' => function($model){ $patient_data = json_decode($model->inquiry->patient_data,true); return [ 'id' => $model->inquiry->id, 'name' => $patient_data['name'], 'sex' => $patient_data['sex'], 'age' => FuncHelper::getAgeFromIdNo($patient_data['id_card']), ]; }, ], ]; return $this->create($query, $post); } /** * @doc-name 最新消息 * @doc-param int page 页码 1 optional * @doc-param int page_size 每页条数 20 optional * @doc-return mixed @List{Order{id,user_id-int-用户,type-int-订单类型1图文2视频,avatarurl-string-用户头像,@Accept_info{status-int-状态,text-string-列表文字描述,text_detail-string-详情描述},@Message{no_read-int-未读条数,message-string-最新消息,message_time-int-发送时间,message_time_format-string-格式化时间},@Patient{id-int-患者问诊id,name-string-姓名,sex-int-1男2女,age-int-年龄}}} 咨询列表 * @doc-return mixed @Pagination{total_count-int-总数量,page_count-int-总页数,current_page-int-当前页,per_page-int-每页条数} 分页数据 */ public function actionNewList() { $post = \Yii::$app->request->post(); $query = Order::find()->where([ 'su_id' => \Yii::$app->user->identity->id, 'is_pay' => 1 ])->with('inquiry', 'session', 'user')->orderBy('id desc'); $query->where(['in', 'accept_status', [OrderAcceptEnum::WAIT_ACCEPT, OrderAcceptEnum::ACCEPTING]]); $this->field = [ Order::class => [ 'id', 'user_id', 'up_id', 'type', 'avatarurl' => 'user.avatarurl', 'accept_info' => function ($model) { return Order::accept_info($model); }, 'ims_id' => 'session.ims_id', 'message' => function ($model) { $ims_id = $model->session->ims_id; $count = ImMessage::find()->where([ 'ims_id' => $ims_id, 'user_id' => $model->user_id, 'service_id' => \Yii::$app->user->identity->id, // 'content_type' => ImMessageTypeEnum::COMMON, 'read_status' => 0, 'type' => ImMessageSendTypeEnum::USER_SEND, 'is_delete' => 0 ])->count(); //未接诊获取第一条病情描述,接诊了获取最新的一条消息 if ($model->accept_status == OrderAcceptEnum::WAIT_ACCEPT) { $new = ImMessage::find()->where([ 'ims_id' => $ims_id, 'user_id' => $model->user_id, 'service_id' => \Yii::$app->user->identity->id, 'is_delete' => 0 ])->orderBy('id asc')->one(); } else { $new = ImMessage::find()->where([ 'ims_id' => $ims_id, 'user_id' => $model->user_id, 'service_id' => \Yii::$app->user->identity->id, 'is_delete' => 0 ])->orderBy('id desc')->one(); } return [ 'no_read' => $count, 'message' => $new->content ?? '', 'message_time' => $new->created_at ?? '', 'message_time_format' => $new ? FuncHelper::time_tran($new->created_at) : '', ]; }, 'patient' => function ($model) { $patient_data = json_decode($model->inquiry->patient_data, true); return [ 'id' => $model->inquiry->id, 'name' => $patient_data['name'], 'sex' => $patient_data['sex'], 'age' => FuncHelper::getAgeFromIdNo($patient_data['id_card']), ]; }, ], ]; return $this->create($query, $post); } /** * @doc-name 读取消息 * @doc-param int ims_id 会话id * @doc-param int up_id 就诊人id * @doc-return string up_id 就诊人id */ public function actionReadMsg() { $post = \Yii::$app->request->post(); $this->requestValidate($post, [ ['ims_id', 'required'], ['up_id', 'required'] ]); \Yii::$app->db->createCommand() ->update('yii_im_message', ['read_status' => 1], ['ims_id' => $post['ims_id'], 'service_id' => \Yii::$app->user->identity->id]) ->execute(); return ['up_id' => $post['up_id']]; } /** * @doc-name 咨询详情 * @doc-param int order_id 订单id * @doc-return mixed Order{id,auto_over_time,@Accept_info{status-int-状态,text-string-列表文字描述,text_detail-string-详情描述},@Patient{id-int-患者问诊id,name-string-姓名,sex-int-1男2女,age-int-年龄}} 咨询详情 */ public function actionInfo() { $post = \Yii::$app->request->post(); $this->requestValidate($post,[ ['order_id','required'] ]); $info = Order::find()->where([ 'id' => $post['order_id'], 'su_id' => \Yii::$app->user->identity->id, ])->with('inquiry','session')->one(); if(!$info){ throw new Exception('订单不存在'); } return ArrayHelper::toArray($info,[ Order::class => [ 'id','auto_over_time', 'accept_info' => function($model){ return Order::accept_info($model); }, 'ims_id' => 'session.ims_id', 'patient' => function($model){ $patient_data = json_decode($model->inquiry->patient_data,true); return [ 'id' => $model->inquiry->id, 'name' => $patient_data['name'], 'sex' => $patient_data['sex'], 'age' => FuncHelper::getAgeFromIdNo($patient_data['id_card']), ]; }, ] ]); } /** * @doc-name 获取患者详情 * @doc-param int order_id 订单id * @doc-return mixed UserInquiry{liver_function,renal_function,allergic_status,allergic_history,person_status,person_history,family_status,family_history,@Patient_data{age-int-年龄,UserPatient{*}}} 患者信息 */ public function actionPatientInfo() { $post = \Yii::$app->request->post(); $this->requestValidate($post,[ ['order_id','required'] ]); $info = Order::find()->where([ 'id' => $post['order_id'], 'su_id' => \Yii::$app->user->identity->id, ])->with('inquiry')->one(); if(!$info){ throw new Exception('订单不存在'); } return $info->inquiry ? ArrayHelper::toArray($info->inquiry,[ UserInquiry::class => [ 'liver_function','renal_function','allergic_status','allergic_history','person_status','person_history','family_status','family_history', 'patient_data' => function($model){ $patient_data = json_decode($model->patient_data,true); $patient_data['age'] = FuncHelper::getAgeFromIdNo($patient_data['id_card']); return $patient_data; } ] ]) : []; } /** * @doc-name 退诊原因 * @doc-return mixed InquiryRefuseReason{*} 退诊原因列表 */ public function actionRefuseReason() { $all = InquiryRefuseReason::find()->orderBy('id asc')->all(); return $all; } /** * @doc-name 退诊 * @doc-param int order_id 订单id * @doc-param int reason_id 退针原因id */ public function actionRefuse() { $post = \Yii::$app->request->post(); $this->requestValidate($post,[ ['order_id','required'], ['reason_id','required','message'=>'请选择退诊原因'] ]); $info = Order::find()->where([ 'id' => $post['order_id'], 'su_id' => \Yii::$app->user->identity->id, ])->with('inquiry','session','serviceUser')->one(); if(!$info){ throw new Exception('订单不存在'); } $order = $info; $reason = InquiryRefuseReason::findOne($post['reason_id']); if(!$reason){ throw new Exception('退诊原因不存在'); } if(!$order->session->ims_id){ throw new Exception('缺少会话,请联系开发者'); } $imMessageSession = ImMessageSession::findOne($order->session->ims_id); if(!$imMessageSession){ throw new Exception('缺少会话,请联系开发者'); } $t = \Yii::$app->db->beginTransaction(); try { //订单状态变更 - 退诊-取消-退款 //生成记录 $orderRefund = new OrderRefund(); $orderRefund->user_id = $order->user_id; $orderRefund->order_id = $order->id; $orderRefund->refund_no = FuncHelper::generate_order_no('RF'); $orderRefund->refund_price = $order->total_pay_price; $orderRefund->remark = '医生拒诊取消'; $orderRefund->saveOrFail(); //取消状态 $order->cancel_status = 1; $order->cancel_time = time(); $order->cancel_remark = '医生拒诊取消'; //接诊状态 $order->accept_status = OrderAcceptEnum::REFUSED; $order->refuse_time = time(); //退款状态 $order->refund_status = 1; $order->refund_time = time(); $order->saveOrFail(); //退款操作 $refundForm = new \common\forms\OrderRefundForm(); $refundForm->refundMoney($orderRefund); //------------------------------发消息------------------------------- //以医生身份给用户发一条退诊消息 $message = [ 'type' => 'text', 'from_User' => [ 'id' => $order->su_id, 'name' => $order->serviceUser->docInfo->name, 'avatar' => $order->serviceUser->docIdentity->work_avator ], 'data' => [ 'text' => $reason['reason_message'] ], ]; $form = new ImMessageForm(); $form->ims_id = $order->session->ims_id; $form->from_id = $order->su_id; $form->to_id = $order->user_id; $form->type = ImMessageSendTypeEnum::SERVICE_SEND;//!! $form->content = json_encode($message); $form->sendMessage(); //以用户身份给医生发送一条event类型的消息 $message = [ 'type' => 'end', 'from_User' => [ 'id' => $order->user->id, 'name' => $order->user->nickname, 'avatar' => $order->user->avatarurl ], 'data' => [ 'text' => '退诊成功,问诊费用已退回患者账户' ], ]; $form = new ImMessageForm(); $form->ims_id = $order->session->ims_id; $form->from_id = $order->user_id; $form->to_id = $order->su_id; $form->type = ImMessageSendTypeEnum::USER_SEND; $form->content = json_encode($message); $form->sendMessage(); //以医生身份给用户发送一条event类型的消息 $message = [ 'type' => 'end', 'from_User' => [ 'id' => $order->su_id, 'name' => $order->serviceUser->docInfo->name, 'avatar' => $order->serviceUser->docIdentity->work_avator ], 'data' => [ 'text' => '问诊结束,问诊费用已退回账户' ], ]; $form = new ImMessageForm(); $form->ims_id = $order->session->ims_id; $form->from_id = $order->su_id; $form->to_id = $order->user_id; $form->type = ImMessageSendTypeEnum::SERVICE_SEND;//!! $form->content = json_encode($message); $form->sendMessage(); //----------------------------发消息----------------------------------- //结束消息会话 $imMessageSession->status = ImSessionStatusEnum::END; $imMessageSession->saveOrFail(); $t->commit(); }catch (Exception $exception) { $t->rollBack(); throw new Exception('退诊失败:'.$exception->getMessage()); } return []; } /** * @doc-name 接诊 * @doc-param int order_id 订单id */ public function actionAccess() { $post = \Yii::$app->request->post(); $this->requestValidate($post,[ ['order_id','required'] ]); $info = Order::find()->where([ 'id' => $post['order_id'], 'su_id' => \Yii::$app->user->identity->id, ])->with('inquiry','session','serviceUser')->one(); if(!$info){ throw new Exception('订单不存在'); } $order = $info; $t = \Yii::$app->db->beginTransaction(); try { //修改订单状态 $order->accept_status = OrderAcceptEnum::ACCEPTING; $order->accept_time = time(); //接诊自动结束 $config = \Yii::$app->params; $auto_accept_over_time = isset($config['order']['accept_over_time']) ? $config['order']['accept_over_time'] : 24*60*60; $auto_over_time = time() + $auto_accept_over_time; $order->auto_over_time = $auto_over_time; $order->saveOrFail(); //--------------------------------------------发消息-------------------------------------------------------- //先以用户身份给医生发送一条事件消息 $message = [ 'type' => 'end', 'from_User' => [ 'id' => $order->user->id, 'name' => $order->user->nickname, 'avatar' => $order->user->avatarurl ], 'data' => [ 'text' => '问诊已开始,请及时回复' ], ]; $form = new ImMessageForm(); $form->ims_id = $order->session->ims_id; $form->from_id = $order->user_id; $form->to_id = $order->su_id; $form->type = ImMessageSendTypeEnum::USER_SEND; $form->content = json_encode($message); $form->sendMessage(); //以医生身份给用户发送一条event的消息 $message = [ 'type' => 'end', 'from_User' => [ 'id' => $order->su_id, 'name' => $order->serviceUser->docInfo->name, 'avatar' => $order->serviceUser->docIdentity->work_avator ], 'data' => [ 'text' => '问诊已开始,本次问诊可持续'.FuncHelper::time_left($auto_accept_over_time), ], ]; $form = new ImMessageForm(); $form->ims_id = $order->session->ims_id; $form->from_id = $order->su_id; $form->to_id = $order->user_id; $form->type = ImMessageSendTypeEnum::SERVICE_SEND;//!! $form->content = json_encode($message); $form->sendMessage(); //以医生身份给用户发送一条notice的消息 $message = [ 'type' => 'system', 'from_User' => [ 'id' => $order->su_id, 'name' => $order->serviceUser->docInfo->name, 'avatar' => $order->serviceUser->docIdentity->work_avator ], 'data' => [ 'text' => '医生已接诊,稍后将与您联系,您可继续补充问诊内容,如目前症状、患病时长、检查及用药情况、需要的帮助等,医生看到后将及时回复您,线上咨询不能代替面诊,医生的回复仅为建议', ], ]; $form = new ImMessageForm(); $form->ims_id = $order->session->ims_id; $form->from_id = $order->su_id; $form->to_id = $order->user_id; $form->type = ImMessageSendTypeEnum::SERVICE_SEND;//!! $form->content = json_encode($message); $form->sendMessage(); //-----------------------------------------------发消息---------------------------------------------------- //发送问诊结束队列 \Yii::$app->queue->delay($auto_accept_over_time)->push(new OrderOverJob([ 'orderId' => $order->id, ])); $t->commit(); }catch (Exception $exception){ $t->rollBack(); throw new Exception('接诊失败:'.$exception->getMessage()); } return []; } /** * @doc-name 医生赠送条数 * @doc-param int ims_id 会话id * @doc-param int number 赠送条数 */ public function giveNumber() { $post = \Yii::$app->request->post(); $this->requestValidate($post,[ ['ims_id','required'], ['number','required','message'=>'赠送条数不能为空'], ['number','integer','赠送数量只能是正整数'] ]); $number = ArrayHelper::getValue($post,'number',0); if($number <= 0){ throw new Exception('赠送数量只能是正整数'); } //查询会话 $ims = ImMessageSession::find()->where([ 'id' => $post['ims_id'], ])->with('order')->one(); if(!$ims || $ims->status == ImSessionStatusEnum::END){ throw new Exception('会话不存在或已结束'); } if(!$ims->order || $ims->order->accept_status != OrderAcceptEnum::ACCEPTING){ throw new Exception('会话订单不存在或未接诊状态'); } $model = new OrderNumberChange(); $model->order_id = $ims->order->id; $model->number = $number; $model->type = NumberChangeTypeEnum::GIVE; $model->saveOrFail(); return []; } /** * 设为精选 */ public function setBest() { } /** * @doc-name 结束问诊 * @doc-param int order_id 订单id */ public function actionOrderOver() { $post = \Yii::$app->request->post(); $this->requestValidate($post, [ ['order_id', 'required'] ]); $info = Order::find()->where([ 'id' => $post['order_id'], 'su_id' => \Yii::$app->user->identity->id, ])->with('inquiry', 'session')->one(); if (!$info) { throw new Exception('订单不存在'); } if ($info->accept_status != OrderAcceptEnum::ACCEPTING) { throw new Exception('订单当前非接诊中,无法结束'); } $info->accept_status = OrderAcceptEnum::OVER; $info->saveOrFail(); return ['结束成功']; } }