faet: 机器人消息自动清理

This commit is contained in:
kuaifan 2023-02-08 15:45:24 +08:00
parent 1d46231f4d
commit c9e7fc14a1
9 changed files with 164 additions and 11 deletions

View File

@ -1005,7 +1005,7 @@ class DialogController extends AbstractController
if (empty($msg)) {
return Base::retError("消息不存在或已被删除");
}
$msg->deleteMsg();
$msg->withdrawMsg();
return Base::retSuccess("success");
}

View File

@ -8,6 +8,7 @@ use App\Module\Ihttp;
use App\Module\RandomColor;
use App\Tasks\AppPushTask;
use App\Tasks\AutoArchivedTask;
use App\Tasks\DeleteBotMsgTask;
use App\Tasks\DeleteTmpTask;
use App\Tasks\EmailNoticeTask;
use App\Tasks\JokeSoupTask;
@ -189,6 +190,8 @@ class IndexController extends InvokeController
Task::deliver(new DeleteTmpTask('wg_tmp_msgs', 1));
Task::deliver(new DeleteTmpTask('task_worker', 12));
Task::deliver(new DeleteTmpTask('tmp', 24));
// 删除机器人消息
Task::deliver(new DeleteBotMsgTask());
// 周期任务
Task::deliver(new LoopTask());
// 获取笑话/心灵鸡汤

View File

@ -8,12 +8,16 @@ namespace App\Models;
* @property int $id
* @property int|null $userid 所属人ID
* @property int|null $bot_id 机器人ID
* @property int|null $clear_day 消息自动清理天数
* @property string|null $clear_at 下一次清理时间
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @method static \Illuminate\Database\Eloquent\Builder|UserBot newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|UserBot newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|UserBot query()
* @method static \Illuminate\Database\Eloquent\Builder|UserBot whereBotId($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserBot whereClearAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserBot whereClearDay($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserBot whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserBot whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserBot whereUpdatedAt($value)

View File

@ -368,6 +368,20 @@ class WebSocketDialog extends AbstractModel
Task::deliver($task);
}
/**
* 更新对话最后消息时间
* @return WebSocketDialogMsg|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|\Illuminate\Database\Query\Builder|object|null
*/
public function updateMsgLastAt()
{
$lastMsg = WebSocketDialogMsg::whereDialogId($this->id)->orderByDesc('id')->first();
if ($lastMsg) {
$this->last_at = $lastMsg->created_at;
$this->save();
}
return $lastMsg;
}
/**
* 获取对话(同时检验对话身份)
* @param $dialog_id

View File

@ -413,9 +413,33 @@ class WebSocketDialogMsg extends AbstractModel
/**
* 删除消息
* @param array|int $ids
* @return void
*/
public function deleteMsg()
public static function deleteMsgs($ids) {
$ids = Base::arrayRetainInt(is_array($ids) ? $ids : [$ids], true);
AbstractModel::transaction(function() use ($ids) {
$dialogIds = WebSocketDialogMsg::select('dialog_id')->whereIn("id", $ids)->distinct()->get()->pluck('dialog_id');
$replyIds = WebSocketDialogMsg::select('reply_id')->whereIn("id", $ids)->distinct()->get()->pluck('reply_id');
//
WebSocketDialogMsgRead::whereIn('msg_id', $ids)->whereNull('read_at')->delete(); // 未阅读记录不需要软删除,直接删除即可
WebSocketDialogMsgTodo::whereIn('msg_id', $ids)->delete();
self::whereIn('id', $ids)->delete();
//
foreach ($dialogIds as $id) {
WebSocketDialog::find($id)?->updateMsgLastAt();
}
foreach ($replyIds as $id) {
self::whereId($id)->update(['reply_num' => self::whereReplyId($id)->count()]);
}
});
}
/**
* 撤回消息
* @return void
*/
public function withdrawMsg()
{
$send_dt = Carbon::parse($this->created_at)->addDay();
if ($send_dt->lt(Carbon::now())) {
@ -429,14 +453,7 @@ class WebSocketDialogMsg extends AbstractModel
self::whereId($this->reply_id)->decrement('reply_num');
}
//
$last_msg = null;
if ($this->webSocketDialog) {
$last_msg = WebSocketDialogMsg::whereDialogId($this->dialog_id)->orderByDesc('id')->first();
$this->webSocketDialog->last_at = $last_msg->created_at;
$this->webSocketDialog->save();
}
//
$dialog = WebSocketDialog::find($this->dialog_id);
$dialog = $this->webSocketDialog;
if ($dialog) {
$userids = $dialog->dialogUser->pluck('userid')->toArray();
PushTask::push([
@ -447,7 +464,7 @@ class WebSocketDialogMsg extends AbstractModel
'data' => [
'id' => $this->id,
'dialog_id' => $this->dialog_id,
'last_msg' => $last_msg,
'last_msg' => $dialog->updateMsgLastAt(),
'update_read' => $deleteRead ? 1 : 0
],
]

View File

@ -3,9 +3,11 @@
namespace App\Tasks;
use App\Models\User;
use App\Models\UserBot;
use App\Models\WebSocketDialog;
use App\Models\WebSocketDialogMsg;
use App\Module\Base;
use Carbon\Carbon;
@error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
@ -186,6 +188,26 @@ class BotReceiveMsgTask extends AbstractTask
}
break;
/**
* 设置自动清理消息时间
*/
case '/clearday':
$data = $this->botManagerOne($array[1], $msg->userid);
if ($data) {
$userBot = UserBot::whereBotId($array[1])->whereUserid($msg->userid)->first();
if ($userBot) {
$userBot->clear_day = min(intval($array[2]) ?: 30, 999);
$userBot->clear_at = Carbon::now()->addDays($userBot->clear_day);
$userBot->save();
}
$data->clear_day = $userBot->clear_day;
$data->clear_at = $userBot->clear_at; // 这两个参数只是作为输出,所以不保存
} else {
$type = "notice";
$notice = "机器人不存在。";
}
break;
/**
* 会话搜索
*/

View File

@ -0,0 +1,44 @@
<?php
namespace App\Tasks;
@error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
use App\Models\UserBot;
use App\Models\WebSocketDialogMsg;
use Carbon\Carbon;
/**
* 删除机器人消息
*/
class DeleteBotMsgTask extends AbstractTask
{
public function __construct()
{
parent::__construct();
}
public function start()
{
$bots = UserBot::where('clear_at', '<=', Carbon::now())->take(100)->get();
foreach ($bots as $bot) {
WebSocketDialogMsg::whereUserid($bot->bot_id)
->where('created_at', '<=', Carbon::now()->subDays($bot->clear_day))
->orderBy('id')
->chunk(1000, function ($msgs) {
$ids = $msgs->pluck('id')->toArray();
if ($ids) {
WebSocketDialogMsg::deleteMsgs($ids);
}
});
$bot->clear_at = Carbon::now()->addDays($bot->clear_day);
$bot->save();
}
}
public function end()
{
}
}

View File

@ -0,0 +1,41 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddUserBotsClear extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
$isAdd = false;
Schema::table('user_bots', function (Blueprint $table) use (&$isAdd) {
if (!Schema::hasColumn('user_bots', 'clear_day')) {
$isAdd = true;
$table->smallInteger('clear_day')->nullable()->default(90)->after('bot_id')->comment('消息自动清理天数');
$table->timestamp('clear_at')->nullable()->after('clear_day')->comment('下一次清理时间');
}
});
if ($isAdd) {
\App\Models\UserBot::whereNull('clear_at')->update(['clear_at' => \Carbon\Carbon::now()->addDays(90)]);
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('user_bots', function (Blueprint $table) {
$table->dropColumn("clear_day");
$table->dropColumn("clear_at");
});
}
}

View File

@ -11,6 +11,7 @@
<b>机器人设置</b>
<span style="color:#84c56a">/token {机器人ID}</span> - 生成Token令牌
<span style="color:#84c56a">/revoke {机器人ID}</span> - 撤销机器人Token令牌
<span style="color:#84c56a">/clearday {机器人ID} {天数}</span> - 设置自动清理消息时间默认30天
<b>会话管理</b>
<span style="color:#84c56a">/dialog {机器人ID} [搜索关键词]</span> - 查看会话ID
@ -50,6 +51,13 @@
机器人ID<span style="color:#84c56a">{{$data->userid}}</span>
机器人名称:<span style="color:#84c56a">{{$data->nickname}}</span>
@elseif ($type === '/clearday')
<b>设置自动清理消息时间。</b>
机器人ID<span style="color:#84c56a">{{$data->userid}}</span>
机器人名称:<span style="color:#84c56a">{{$data->nickname}}</span>
清理周期:<span style="color:#84c56a">{{$data->clear_day}}</span>
下次清理:<span style="color:#84c56a">{{$data->clear_at}}</span>
@elseif ($type === '/dialog')
<b>机器人 <span style="color:#84c56a">{{$data->nickname}} (ID:{{$data->userid}})</span> 已加入的会话:</b>