where([ 'user_id' => \Yii::$app->user->identity->id, 'type' => ImSessionTypeEnum::USER_LEAD, 'is_delete' => 0 ])->with('serviceUser')->orderBy('id desc')->one(); $leadSessions = $leadSessions ? ArrayHelper::toArray($leadSessions,[ ImMessageSession::class => [ 'id', 'type', 'name' => function(){ return '导医消息'; }, 'avatar' => 'serviceUser.leadInfo.avatar', 'noread_count' => function($model){ $count = ImMessage::find()->where([ 'ims_id' => $model->id, 'read_status' => 0, 'type' => ImMessageSendTypeEnum::SERVICE_SEND, 'is_delete' => 0 ])->count(); return $count; }, 'last' => function($model){ $message = ImMessage::find()->where([ 'ims_id' => $model->id, 'is_delete' => 0, ])->orderBy('id desc')->one(); if($message){ return [ 'created_at' => $message['created_at'], 'created_at_format' => FuncHelper::time_tran($message['created_at']), 'content' => $message['content'], ]; }else{ return []; } } ] ]) : []; //最新的消息排在最上边,不管是谁发送的,不管已读未读 $last = ImMessage::find()->where([ 'is_delete' => 0, ])->addSelect('ims_id,MAX(id) as id,max(created_at) as created_at')->groupBy('ims_id')->orderBy('id desc'); $docSessions = ImMessageSession::find()->alias('ims')->select([ 'ims.*', ])->addSelect('l.id as last_id,l.created_at as last_time')->where([ 'ims.user_id' => \Yii::$app->user->identity->id, 'ims.type' => UserRoleEnum::DOCTOR, 'ims.is_delete' => 0 ])->joinWith(['order' => function($q){ $q->alias('o')->andWhere(['<>','o.accept_status',OrderAcceptEnum::NO]); }])->leftJoin('(' . $last->createCommand()->getRawSql() . ') l', 'ims.id = l.ims_id') ->with('serviceUser') ->orderBy('l.created_at desc,ims.id desc') ->all(); $docSessions = count($docSessions) > 0 ? ArrayHelper::toArray($docSessions,[ ImMessageSession::class => [ 'id', 'type', 'name' => 'serviceUser.docInfo.name', 'avatar' => 'serviceUser.docInfo.avatar', 'depart' => 'serviceUser.docInfo.depart.name', 'noread_count' => function($model){ $count = ImMessage::find()->where([ 'ims_id' => $model->id, 'read_status' => 0, 'type' => ImMessageSendTypeEnum::SERVICE_SEND, 'is_delete' => 0 ])->count(); return $count; }, 'last' => function($model){ $message = ImMessage::findOne($model->last_id); if($message){ return [ 'created_at' => $model->last_time, 'created_at_format' => FuncHelper::time_tran($model->last_time), 'content' => $message->content ]; }else{ return []; } } ] ]) : []; return [ 'lead' => $leadSessions, 'doc' => $docSessions ]; } /** * @doc-name 清除未读 */ public function actionClearNoRead() { $t=\Yii::$app->db->beginTransaction(); try { ImMessage::updateAll(['read_status'=>1],[ 'user_id' => \Yii::$app->user->identity->id, 'type' => ImMessageSendTypeEnum::SERVICE_SEND, 'read_status' => 0, 'is_delete' => 0 ]); SystemNotice::updateAll(['read_status'=>1],[ 'user_id' => \Yii::$app->user->identity->id, 'base_type' =>SystemNoticeTypeEnum::REMINDER, 'scene_type' => 1, 'read_status' => 0, ]); $t->commit(); return ['清除成功']; }catch (\Exception $e){ $t->rollBack(); throw $e; } } /** * @doc-name 会话消息记录 * @doc-param int ims_id 会话id * @doc-param int page 页码 1 optional * @doc-param int page_size 每页条数 20 optional * @doc-return mixed @Session{ImMessageSession{*,@User-mixed-用户信息{name-string-名称,avatar-string-头像},@ServiceUser-mixed-服务人员信息{name-string-名称,avator-string-头像}}} 会话信息 * @doc-return mixed @List{ImMessage{*,@User-mixed-用户信息{name-string-名称,avatar-string-头像},@ServiceUser-mixed-服务人员信息{name-string-名称,avator-string-头像}}} 消息记录 * @doc-return mixed @Pagination{total_count-int-总数量,page_count-int-总页数,current_page-int-当前页,per_page-int-每页条数} 分页数据 */ public function actionMessageList() { $post = \Yii::$app->request->post(); $this->requestValidate($post,[ ['ims_id','required'] ]); $imMessageSession = ImMessageSession::find()->with('user','serviceUser')->where([ 'id' => $post['ims_id'], 'user_id' => \Yii::$app->user->identity->id, 'is_delete' => 0 ])->with('order')->one(); $session = $imMessageSession ? ArrayHelper::toArray($imMessageSession,[ ImMessageSession::class => [ 'id','user_id','service_id','type','status','created_at', 'user','order', 'serviceUser' => function($model){ switch($model->type) { case ImSessionTypeEnum::USER_USER: $serviceUser = User::findOne($model->service_id); return [ 'name' => $serviceUser->nickname, 'avatar' => $serviceUser->avatarurl, ]; break; case ImSessionTypeEnum::USER_DOC: $serviceUser = ServiceUser::find()->where([ 'id' => $model->service_id ])->with('docInfo')->one(); return [ 'name' => $serviceUser->docInfo->name, 'avatar' => $serviceUser->docInfo->avatar, ]; case ImSessionTypeEnum::USER_LEAD: $serviceUser = ServiceUser::find()->where([ 'id' => $model->service_id ])->with('leadInfo')->one(); return [ 'name' => $serviceUser->leadInfo->name, 'avatar' => $serviceUser->leadInfo->avatar, ]; case ImSessionTypeEnum::DOC_SERV: case ImSessionTypeEnum::DRUG_SERV: case ImSessionTypeEnum::LEAD_SERV: //这三种情况member下暂时不会有 break; } }, ], User::class => [ 'name'=>'nickname','avatar'=>'avatarurl' ], Order::class => [ 'id', 'auto_over_time', 'image_limit_status', 'left_number', 'status' => function($model){ return Order::status_info($model); }, 'accept_status' => function($model){ return Order::accept_info($model); }, ] ]) : []; $this->extend_result['session'] = $session; $query = ImMessage::find()->where([ 'ims_id' => $post['ims_id'], 'user_id' => \Yii::$app->user->identity->id, 'is_delete' => 0 ])->with('user','imSession')->orderBy('id desc'); $this->field = [ ImMessage::class => [ 'id','user_id','service_id','content','read_status','type','created_at', 'user', 'serviceUser' => function($model){ switch($model->imSession->type) { case ImSessionTypeEnum::USER_USER: $serviceUser = User::findOne($model->service_id); return [ 'name' => $serviceUser->nickname, 'avatar' => $serviceUser->avatarurl, ]; case ImSessionTypeEnum::USER_DOC: $serviceUser = ServiceUser::find()->where([ 'id' => $model->service_id ])->with('docInfo')->one(); return [ 'name' => $serviceUser->docInfo->name, 'avatar' => $serviceUser->docInfo->avatar, ]; case ImSessionTypeEnum::USER_LEAD: $serviceUser = ServiceUser::find()->where([ 'id' => $model->service_id ])->with('leadInfo')->one(); return [ 'name' => $serviceUser->leadInfo->name, 'avatar' => $serviceUser->leadInfo->avatar, ]; case ImSessionTypeEnum::DOC_SERV: case ImSessionTypeEnum::DRUG_SERV: case ImSessionTypeEnum::LEAD_SERV: //这三种情况member下暂时不会有 break; } }, ], User::class => [ 'name'=>'nickname','avatar'=>'avatarurl' ], ]; return $this->create($query,$post); } /** * @doc-name 用户端发送消息 * @doc-desc session_type是会话的类型,直接取用会话的类型,导医第一次可能没有会话id,会话id传递0,会话类型直接传递3 * @doc-param int ims_id 会话id,跟导医第一次可能没有会话id,传递0 * @doc-param int session_type 会话类型1跟医生的会话3跟导医的会话 * @doc-param json content 消息内容 * @doc-return int image_limit_status 会话类型1会返回,是否限制回复条数1限制0不限制 * @doc-return int left_number 会话类型1会返回,剩余条数,限制状态下,为0表示回复条数不足,不限制状态下,为0表示无限制 */ public function actionMessageSend() { //用戶端发送消息 $post = \Yii::$app->request->post(); $this->requestValidate($post,[ [['ims_id','session_type'],'required'], ['session_type','in','range'=>[1,3]], ['content','required','message'=>'消息内容不能为空'] ]); $form = new ImMessageForm(); $form->attributes = $post; $form->from_id = \Yii::$app->user->identity->id; switch($post['session_type']) { case ImSessionTypeEnum::USER_LEAD: //导医用的是最新的会话,不管结束未结束,给导医发送消息也可以传递ims_id,不过后台会根据导医会话的状态重新创建会话并进行接入操作 $query = ImMessageSession::find()->where([ 'user_id' => \Yii::$app->user->identity->id,//id 32 'type' => $post['session_type'], 'is_delete' => 0, 'status'=> ImSessionStatusEnum::ING ]); if($post['ims_id']){ $query->andWhere([ 'id' => $post['ims_id'] ]); } $ims= $query->one(); $lead_id=LeadInfo::getLastLeadUserId();//空闲导医 if(!$ims){ //不要判断!$post['ims_id']否则会添加一堆的会话 $ims = new ImMessageSession(); $ims->user_id = \Yii::$app->user->identity->id; $ims->type = $post['session_type']; $ims->saveOrFail(); } $form->ims_id = $ims->id; $form->to_id = $ims->service_id; $form->sendMessage(); return []; case ImSessionTypeEnum::USER_DOC: $image_limit_status = 0; $left_number = 0; $ims = ImMessageSession::find()->where([ 'id' => $post['ims_id'], 'is_delete' => 0 ])->with('order')->one(); if(!$ims || !$ims->order){ throw new Exception('会话不存在或者会话订单不存在'); } $form->to_id = $ims->service_id; $order = $ims->order; //检查订单状态 if($order->accept_status == OrderAcceptEnum::WAIT_ACCEPT){ //待接诊状态 - 可以补充回答 $form->sendMessage(); }elseif($order->accept_status == OrderAcceptEnum::ACCEPTING ){ //已接诊状态 - 发送消息 - 扣除相应的条数 $ts = \Yii::$app->db->beginTransaction(); try { $order = Order::findOne($ims->order->id); if($order->image_limit_status && $order->left_number <=0){ throw new Exception('回复条数不足'); } $form->sendMessage(); if($order->image_limit_status){ $order->updateCounters(['left_number' => -1]); } $image_limit_status = $order->image_limit_status; $left_number = $order->left_number; $ts->commit(); }catch (\Exception $exception){ $ts->rollBack(); throw $exception; } }else{ //其他情况-拒绝 throw new Exception('发送失败:订单非待接诊和接诊状态,无法发送消息'); } return [ 'image_limit_status' => $image_limit_status, 'left_number' => $left_number, ]; } } /** * @doc-name 结束会话 * @doc-param int ims_id 会话id * @doc-param int service_id 服务端id */ public function actionOverSession() { $post= \Yii::$app->request->post(); $this->requestValidate($post,[ [ ['ims_id','service_id'],'required' ] ]); $imMessageSession= ImMessageSession::find()->where([ 'id'=>$post['ims_id'], 'user_id'=>\Yii::$app->user->identity->getId(), 'service_id'=>$post['service_id'], 'status'=>0 ])->one(); if (!$imMessageSession)throw new \yii\db\Exception('聊天消息会话不存在或已结束'); $order_id=ImMessageSessionOrder::find()->select('order_id')->where([ 'ims_id'=>$post['ims_id'], ])->column(); $order= Order::find()->where([ 'id'=>$order_id, 'user_id'=>\Yii::$app->user->identity->getId(), 'su_id'=>$post['service_id'] ])->one(); if (!$order)throw new \yii\db\Exception('订单不存在'); $t=\Yii::$app->db->beginTransaction(); try { Order::updateAll(['accept_status'=>OrderAcceptEnum::OVER],[ 'id'=>$order_id, 'user_id'=>\Yii::$app->user->identity->getId(), 'su_id'=>$post['service_id'] ]); ImMessageSession::updateAll( ['status'=>10], ['id'=>$post['ims_id'], 'user_id'=>\Yii::$app->user->identity->getId(), 'service_id'=>$post['service_id']]); $t->commit(); }catch (\Exception $e){ $t->rollBack(); throw $e; } return ['会话已结束']; } }