Files
xk-api-yii/member/modules/v1/controllers/ImController.php

473 lines
19 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 member\modules\v1\controllers;
use common\core\BaseAppController;
use common\enums\ImMessageSendTypeEnum;
use common\enums\ImSessionStatusEnum;
use common\enums\ImSessionTypeEnum;
use common\enums\OrderAcceptEnum;
use common\enums\SystemNoticeTypeEnum;
use common\enums\UserRoleEnum;
use common\forms\ImMessageForm;
use common\helpers\ArrayHelper;
use common\helpers\FuncHelper;
use common\models\oldDb\ImMessage;
use common\models\oldDb\ImMessageSession;
use common\models\oldDb\ImMessageSessionOrder;
use common\models\oldDb\LeadInfo;
use common\models\oldDb\Order;
use common\models\oldDb\ServiceUser;
use common\models\oldDb\SystemNotice;
use common\models\oldDb\User;
use yii\base\Exception;
/**
* @doc-module Im
*/
class ImController extends BaseAppController
{
public function beforeAction($action)
{
$parent = parent::beforeAction($action); // TODO: Change the autogenerated stub
return $parent;
}
/**
* @doc-name 会话列表
* @doc-return mixed @Lead{id-int-会话id,ImMessageSession{type},name-string-名称,avatar-string-头像,noread_count-int-未读数量,@Last{created_at-int-上次消息时间,created_at_format-string-格式化后的时间,content-string-上次消息}} 导医会话
* @doc-return mixed @Doc{id-int-会话id,ImMessageSession{type},name-string-名称,avatar-string-头像,depart-string-科室,noread_count-int-未读数量,@Last{created_at-int-上次消息时间,created_at_format-string-格式化后的时间,content-string-上次消息}} 医生会话
*/
public function actionSessionList()
{
//导医始终排在最上边 -
//导医用的是最新的会话不管结束未结束给导医发送消息也可以传递to_id和ims_id,不过后台会根据导医会话的状态重新创建会话并进行接入
$leadSessions = ImMessageSession::find()->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 ['会话已结束'];
}
}