mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-11 10:33:54 +00:00
perf: 优化会议室
This commit is contained in:
parent
540bff89cf
commit
93c8d86caf
@ -1143,7 +1143,7 @@ class UsersController extends AbstractController
|
||||
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 @@ class UsersController extends AbstractController
|
||||
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} 发起的会议";
|
||||
|
||||
@ -10,18 +10,19 @@ use Response;
|
||||
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 @@ class IndexController extends InvokeController
|
||||
Task::deliver(new JokeSoupTask());
|
||||
// 未领取任务通知
|
||||
Task::deliver(new UnclaimedTaskRemindTask());
|
||||
// 关闭会议室
|
||||
Task::deliver(new CloseMeetingRoomTask());
|
||||
|
||||
return "success";
|
||||
}
|
||||
|
||||
34
app/Models/MeetingMsg.php
Normal file
34
app/Models/MeetingMsg.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
/**
|
||||
* App\Models\MeetingMsg
|
||||
*
|
||||
* @property int $id
|
||||
* @property string|null $meetingid 会议ID
|
||||
* @property int|null $dialog_id 对话ID
|
||||
* @property int|null $msg_id 消息ID
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel cancelAppend()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel cancelHidden()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel change($array)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel getKeyValue()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|MeetingMsg newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|MeetingMsg newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|MeetingMsg query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel remove()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel saveOrIgnore()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|MeetingMsg whereDialogId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|MeetingMsg whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|MeetingMsg whereMeetingid($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|MeetingMsg whereMsgId($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class MeetingMsg extends AbstractModel
|
||||
{
|
||||
function __construct(array $attributes = [])
|
||||
{
|
||||
parent::__construct($attributes);
|
||||
$this->timestamps = false;
|
||||
}
|
||||
}
|
||||
131
app/Tasks/CloseMeetingRoomTask.php
Normal file
131
app/Tasks/CloseMeetingRoomTask.php
Normal file
@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tasks;
|
||||
|
||||
use App\Models\Meeting;
|
||||
use App\Models\WebSocketDialog;
|
||||
use App\Module\Base;
|
||||
use Carbon\Carbon;
|
||||
use App\Models\WebSocketDialogMsg;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
@error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
|
||||
|
||||
class CloseMeetingRoomTask extends AbstractTask
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function start()
|
||||
{
|
||||
// 10分钟执行一次
|
||||
$time = intval(Cache::get("CloseMeetingRoomTask:Time"));
|
||||
if (time() - $time < 600) {
|
||||
return;
|
||||
}
|
||||
Cache::put("CloseMeetingRoomTask:Time", time(), Carbon::now()->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;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
use App\Models\WebSocketDialogMsg;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateMeetingMsgsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('meeting_msgs', function (Blueprint $table) {
|
||||
$table->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');
|
||||
}
|
||||
}
|
||||
@ -54,7 +54,7 @@
|
||||
</div>
|
||||
<!--会议-->
|
||||
<div v-else-if="msgData.type === 'meeting'" class="content-meeting no-dark-content">
|
||||
<ul class="dialog-meeting">
|
||||
<ul class="dialog-meeting" :class="{'meeting-end':!!msgData.msg.end_at}">
|
||||
<li>
|
||||
<em>{{$L('会议主题')}}</em>
|
||||
{{msgData.msg.name}}
|
||||
@ -67,7 +67,10 @@
|
||||
<em>{{$L('频道ID')}}</em>
|
||||
{{msgData.msg.meetingid.replace(/^(.{3})(.{3})(.*)$/, '$1 $2 $3')}}
|
||||
</li>
|
||||
<li class="meeting-operation" @click="openMeeting">
|
||||
<li v-if="msgData.msg.end_at" class="meeting-operation">
|
||||
{{$L('会议已结束')}}
|
||||
</li>
|
||||
<li v-else class="meeting-operation" @click="openMeeting">
|
||||
{{$L('点击加入会议')}}
|
||||
<i class="taskfont"></i>
|
||||
</li>
|
||||
|
||||
@ -1071,6 +1071,15 @@
|
||||
color: $primary-title-color;
|
||||
.dialog-meeting {
|
||||
min-width: 220px;
|
||||
&.meeting-end {
|
||||
opacity: .7;
|
||||
> li {
|
||||
&.meeting-operation {
|
||||
justify-content: center;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
}
|
||||
> li {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user