diff --git a/app/Http/Controllers/Api/UsersController.php b/app/Http/Controllers/Api/UsersController.php index a43c391a7..b83b2a0f4 100755 --- a/app/Http/Controllers/Api/UsersController.php +++ b/app/Http/Controllers/Api/UsersController.php @@ -1143,7 +1143,7 @@ public function umeng__alias() public function meeting__open() { $type = trim(Request::input('type')); - $meetingid = trim(Request::input('meetingid')); + $meetingid = str_replace(' ', '', trim(Request::input('meetingid'))); $name = trim(Request::input('name')); $userids = Request::input('userids'); $sharekey = trim(Request::input('sharekey')); @@ -1163,6 +1163,11 @@ public function meeting__open() if (empty($meeting)) { return Base::retError('频道ID不存在'); } + if ($meeting->end_at) { + return Base::retError('会议已结束'); + } + $meeting->updated_at = Carbon::now(); + $meeting->save(); } elseif ($type === 'create') { $meetingid = strtoupper(Base::generatePassword(11, 1)); $name = $name ?: "{$user?->nickname} 发起的会议"; diff --git a/app/Http/Controllers/IndexController.php b/app/Http/Controllers/IndexController.php index 434cdeae9..0bc327100 100755 --- a/app/Http/Controllers/IndexController.php +++ b/app/Http/Controllers/IndexController.php @@ -10,18 +10,19 @@ use App\Module\Doo; use App\Models\File; use App\Module\Base; -use App\Tasks\LoopTask; use App\Module\Extranet; -use App\Tasks\AppPushTask; use App\Module\RandomColor; +use App\Tasks\LoopTask; +use App\Tasks\AppPushTask; use App\Tasks\JokeSoupTask; use App\Tasks\DeleteTmpTask; use App\Tasks\EmailNoticeTask; use App\Tasks\AutoArchivedTask; use App\Tasks\DeleteBotMsgTask; use App\Tasks\CheckinRemindTask; -use Hhxsv5\LaravelS\Swoole\Task\Task; +use App\Tasks\CloseMeetingRoomTask; use App\Tasks\UnclaimedTaskRemindTask; +use Hhxsv5\LaravelS\Swoole\Task\Task; use LasseRafn\InitialAvatarGenerator\InitialAvatar; @@ -165,6 +166,8 @@ public function crontab() Task::deliver(new JokeSoupTask()); // 未领取任务通知 Task::deliver(new UnclaimedTaskRemindTask()); + // 关闭会议室 + Task::deliver(new CloseMeetingRoomTask()); return "success"; } diff --git a/app/Models/MeetingMsg.php b/app/Models/MeetingMsg.php new file mode 100644 index 000000000..3d886d697 --- /dev/null +++ b/app/Models/MeetingMsg.php @@ -0,0 +1,34 @@ +timestamps = false; + } +} diff --git a/app/Tasks/CloseMeetingRoomTask.php b/app/Tasks/CloseMeetingRoomTask.php new file mode 100644 index 000000000..ea90b6543 --- /dev/null +++ b/app/Tasks/CloseMeetingRoomTask.php @@ -0,0 +1,131 @@ +addMinutes(10)); + // 判断参数 + $setting = Base::setting('meetingSetting'); + if ($setting['open'] !== 'open') { + return; + } + if (empty($setting['appid']) ||empty($setting['api_key']) || empty($setting['api_secret'])) { + return; + } + $credentials = $setting['api_key'] . ":" . $setting['api_secret']; + $base64Credentials = base64_encode($credentials); + $arrHeader = [ + "Accept: application/json", + "Authorization: Basic " . $base64Credentials + ]; + // 获取10分钟未更新的会议 + $meetings = Meeting::whereNull('end_at') + ->where('updated_at', '<', Carbon::now()->subMinutes(10)) + ->take(100) + ->get(); + $dialogIds = []; + /** @var Meeting $meeting */ + foreach ($meetings as $meeting) { + if (!$this->isEmptyChannel($setting['appid'], $meeting->channel, $arrHeader)) { + $meeting->updated_at = Carbon::now(); + $meeting->save(); + continue; + } + $meeting->end_at = Carbon::now(); + $meeting->save(); + // 更新消息 + $newMsg = $meeting->toArray(); + $newMsg['end_at'] = $meeting->end_at->toDateTimeString(); + WebSocketDialogMsg::select(['web_socket_dialog_msgs.*', 'm.meetingid']) + ->join("meeting_msgs as m", "m.msg_id", "=", "web_socket_dialog_msgs.id") + ->where('m.meetingid', $meeting->meetingid) + ->chunk(100, function ($msgs) use ($newMsg, &$dialogIds) { + /** @var WebSocketDialogMsg $msg */ + foreach ($msgs as $msg) { + $msg->msg = Base::array2json($newMsg); + $msg->save(); + // + if (!isset($dialogIds[$msg->dialog_id])) { + $dialogIds[$msg->dialog_id] = []; + } + $dialogIds[$msg->dialog_id][] = [ + 'id' => $msg->id, + 'msg' => $msg->msg, + ]; + } + }); + } + // 推送更新 + foreach ($dialogIds as $dialogId => $datas) { + $dialog = WebSocketDialog::find($dialogId); + if (empty($dialog)) { + continue; + } + foreach ($datas as $data) { + $dialog->pushMsg('update', $data); + } + } + } + + public function end() + { + } + + /** + * 是否空频道 + * @param $appid + * @param $channel + * @param $arrHeader + * @return bool + */ + private function isEmptyChannel($appid, $channel, $arrHeader) + { + $curl = curl_init(); + curl_setopt_array($curl, [ + CURLOPT_URL => "https://api.sd-rtn.com/dev/v1/channel/user/{$appid}/{$channel}", + CURLOPT_RETURNTRANSFER => true, + CURLOPT_ENCODING => "", + CURLOPT_MAXREDIRS => 10, + CURLOPT_TIMEOUT => 30, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, + CURLOPT_CUSTOMREQUEST => "GET", + CURLOPT_HTTPHEADER => $arrHeader, + ]); + $response = curl_exec($curl); + $err = curl_error($curl); + curl_close($curl); + if ($err) { + return false; // 错误 + } + $data = Base::json2array($response); + if (!$data['success']) { + return false; // 失败 + } + if ($data['data']['channel_exist']) { + return false; // 有人 + } + return true; + } +} diff --git a/database/migrations/2024_04_04_082823_create_meeting_msgs_table.php b/database/migrations/2024_04_04_082823_create_meeting_msgs_table.php new file mode 100644 index 000000000..57903dc57 --- /dev/null +++ b/database/migrations/2024_04_04_082823_create_meeting_msgs_table.php @@ -0,0 +1,43 @@ +bigIncrements('id'); + $table->string('meetingid')->nullable()->default('')->unique()->comment('会议ID'); + $table->bigInteger('dialog_id')->nullable()->default(0)->comment('对话ID'); + $table->bigInteger('msg_id')->nullable()->default(0)->comment('消息ID'); + }); + WebSocketDialogMsg::whereType('meeting')->chunk(100, function ($msgs) { + /** @var WebSocketDialogMsg $msg */ + foreach ($msgs as $msg) { + $meetingid = $msg->msg['meetingid']; + $dialog_id = $msg->dialog_id; + $msg_id = $msg->id; + \DB::table('meeting_msgs')->insert(compact('meetingid', 'dialog_id', 'msg_id')); + } + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('meeting_msgs'); + } +} diff --git a/resources/assets/js/pages/manage/components/DialogView.vue b/resources/assets/js/pages/manage/components/DialogView.vue index 26d3266be..712c83b85 100644 --- a/resources/assets/js/pages/manage/components/DialogView.vue +++ b/resources/assets/js/pages/manage/components/DialogView.vue @@ -54,7 +54,7 @@