diff --git a/app/Http/Controllers/Api/DialogController.php b/app/Http/Controllers/Api/DialogController.php
index 0bf26f070..a6ca86422 100755
--- a/app/Http/Controllers/Api/DialogController.php
+++ b/app/Http/Controllers/Api/DialogController.php
@@ -1005,7 +1005,7 @@ class DialogController extends AbstractController
if (empty($msg)) {
return Base::retError("消息不存在或已被删除");
}
- $msg->deleteMsg();
+ $msg->withdrawMsg();
return Base::retSuccess("success");
}
diff --git a/app/Http/Controllers/IndexController.php b/app/Http/Controllers/IndexController.php
index 472171561..80fc70738 100755
--- a/app/Http/Controllers/IndexController.php
+++ b/app/Http/Controllers/IndexController.php
@@ -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());
// 获取笑话/心灵鸡汤
diff --git a/app/Models/UserBot.php b/app/Models/UserBot.php
index 4c03d3628..768e1e773 100644
--- a/app/Models/UserBot.php
+++ b/app/Models/UserBot.php
@@ -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)
diff --git a/app/Models/WebSocketDialog.php b/app/Models/WebSocketDialog.php
index 6d87ea97f..6c30ab3b4 100644
--- a/app/Models/WebSocketDialog.php
+++ b/app/Models/WebSocketDialog.php
@@ -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
diff --git a/app/Models/WebSocketDialogMsg.php b/app/Models/WebSocketDialogMsg.php
index a4d40269d..4a92cc3fb 100644
--- a/app/Models/WebSocketDialogMsg.php
+++ b/app/Models/WebSocketDialogMsg.php
@@ -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
],
]
diff --git a/app/Tasks/BotReceiveMsgTask.php b/app/Tasks/BotReceiveMsgTask.php
index 12bb9b37f..e4c56e421 100644
--- a/app/Tasks/BotReceiveMsgTask.php
+++ b/app/Tasks/BotReceiveMsgTask.php
@@ -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;
+
/**
* 会话搜索
*/
diff --git a/app/Tasks/DeleteBotMsgTask.php b/app/Tasks/DeleteBotMsgTask.php
new file mode 100644
index 000000000..d29e9ca89
--- /dev/null
+++ b/app/Tasks/DeleteBotMsgTask.php
@@ -0,0 +1,44 @@
+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()
+ {
+
+ }
+}
diff --git a/database/migrations/2023_02_08_152033_add_user_bots_clear.php b/database/migrations/2023_02_08_152033_add_user_bots_clear.php
new file mode 100644
index 000000000..bfc6c19c2
--- /dev/null
+++ b/database/migrations/2023_02_08_152033_add_user_bots_clear.php
@@ -0,0 +1,41 @@
+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");
+ });
+ }
+}
diff --git a/resources/views/push/bot.blade.php b/resources/views/push/bot.blade.php
index fff213f9d..0618d694f 100755
--- a/resources/views/push/bot.blade.php
+++ b/resources/views/push/bot.blade.php
@@ -11,6 +11,7 @@
机器人设置
/token {机器人ID} - 生成Token令牌
/revoke {机器人ID} - 撤销机器人Token令牌
+ /clearday {机器人ID} {天数} - 设置自动清理消息时间(默认30天)
会话管理
/dialog {机器人ID} [搜索关键词] - 查看会话ID
@@ -50,6 +51,13 @@
机器人ID:{{$data->userid}}
机器人名称:{{$data->nickname}}
+@elseif ($type === '/clearday')
+ 设置自动清理消息时间。
+
+ 机器人ID:{{$data->userid}}
+ 机器人名称:{{$data->nickname}}
+ 清理周期:{{$data->clear_day}}天
+ 下次清理:{{$data->clear_at}}
@elseif ($type === '/dialog')
机器人 {{$data->nickname}} (ID:{{$data->userid}}) 已加入的会话: