Files
xk-api-yii/service/modules/v1/controllers/ImageOrderController.php
2024-09-19 11:32:39 +08:00

651 lines
26 KiB
PHP

<?php
namespace service\modules\v1\controllers;
use common\core\BaseServiceController;
use common\enums\ImMessageSendTypeEnum;
use common\enums\ImSessionStatusEnum;
use common\enums\NumberChangeTypeEnum;
use common\enums\OrderAcceptEnum;
use common\forms\ImMessageForm;
use common\helpers\ArrayHelper;
use common\helpers\FuncHelper;
use common\jobs\OrderOverJob;
use common\models\ImMessage;
use common\models\ImMessageSession;
use common\models\InquiryRefuseReason;
use common\models\Order;
use common\models\OrderNumberChange;
use common\models\OrderRefund;
use common\models\UserInquiry;
use yii\base\Exception;
/**
* @doc-module 图文咨询
*/
class ImageOrderController extends BaseServiceController
{
/**
* @doc-name 咨询列表角标
* @doc-return int wait_accept_count 待接诊
* @doc-return int wait_accepting_count 接诊中
* @doc-return int wait_over_count 已结束
*/
public function actionListMain()
{
$wait_accept_count = (int)Order::find()->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 ['结束成功'];
}
}