473 lines
19 KiB
PHP
473 lines
19 KiB
PHP
<?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 ['会话已结束'];
|
||
}
|
||
|
||
|
||
}
|