From 7bae1d95379a5e7e79f0557d28b8378b446f8ad3 Mon Sep 17 00:00:00 2001 From: kuaifan Date: Sun, 20 Apr 2025 00:22:43 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E5=88=86=E4=BA=AB=E6=90=9C=E7=B4=A2=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Controllers/Api/DialogController.php | 35 +++------------- app/Http/Controllers/Api/UsersController.php | 40 +++++++++++++++++-- app/Models/User.php | 22 ++++++++++ app/Models/WebSocketDialog.php | 26 ++++++++++++ resources/mobile | 2 +- 5 files changed, 92 insertions(+), 33 deletions(-) diff --git a/app/Http/Controllers/Api/DialogController.php b/app/Http/Controllers/Api/DialogController.php index 71f65dabb..73f2891d1 100755 --- a/app/Http/Controllers/Api/DialogController.php +++ b/app/Http/Controllers/Api/DialogController.php @@ -120,34 +120,11 @@ class DialogController extends AbstractController return Base::retError('请输入搜索关键词'); } // 搜索会话 - $list = DB::table('web_socket_dialog_users as u') - ->select(['d.*', 'u.top_at', 'u.last_at', 'u.mark_unread', 'u.silence', 'u.hide', 'u.color', 'u.updated_at as user_at']) - ->join('web_socket_dialogs as d', 'u.dialog_id', '=', 'd.id') - ->where('u.userid', $user->userid) - ->where('d.name', 'LIKE', "%{$key}%") - ->whereNull('d.deleted_at') - ->orderByDesc('u.top_at') - ->orderByDesc('u.last_at') - ->take(20) - ->get() - ->map(function($item) use ($user) { - return WebSocketDialog::synthesizeData($item, $user->userid); - }) - ->all(); + $take = 20; + $list = WebSocketDialog::searchDialog($user->userid, $key, $take); // 搜索联系人 - if (count($list) < 20 && Base::judgeClientVersion("0.21.60")) { - $users = User::select(User::$basicField) - ->where(function ($query) use ($key) { - if (str_contains($key, "@")) { - $query->where("email", "like", "%{$key}%"); - } else { - $query->where("nickname", "like", "%{$key}%") - ->orWhere("pinyin", "like", "%{$key}%") - ->orWhere("profession", "like", "%{$key}%"); - } - })->orderBy('userid') - ->take(20 - count($list)) - ->get(); + if (count($list) < $take && Base::judgeClientVersion("0.21.60")) { + $users = User::searchUser($key, $take - count($list)); $users->transform(function (User $item) use ($user) { $id = 'u:' . $item->userid; $lastAt = null; @@ -173,8 +150,8 @@ class DialogController extends AbstractController $list = array_merge($list, $users->toArray()); } // 搜索消息会话 - if (count($list) < 20) { - $searchResults = ZincSearchDialogMsg::search($user->userid, $key, 0, 20 - count($list)); + if (count($list) < $take) { + $searchResults = ZincSearchDialogMsg::search($user->userid, $key, 0, $take - count($list)); if ($searchResults) { foreach ($searchResults as $item) { if ($dialog = WebSocketDialog::find($item['id'])) { diff --git a/app/Http/Controllers/Api/UsersController.php b/app/Http/Controllers/Api/UsersController.php index e995269ca..3863bf633 100755 --- a/app/Http/Controllers/Api/UsersController.php +++ b/app/Http/Controllers/Api/UsersController.php @@ -2197,6 +2197,7 @@ class UsersController extends AbstractController * @apiName share__list * * @apiParam {String} [type] 分享类型:file-文件,text-列表 默认file + * @apiParam {String} [key] 搜索关键词(用于搜索会话) * @apiParam {Number} [pid] 父级文件id,用于获取子目录和上传到指定目录的id * @apiParam {Number} [upload_file_id] 上传文件id * @@ -2208,6 +2209,7 @@ class UsersController extends AbstractController { $user = User::auth(); $type = Request::input('type', 'file'); + $key = Request::input('key'); $pid = intval(Request::input('pid', -1)); $uploadFileId = intval(Request::input('upload_file_id', -1)); // 上传文件 @@ -2240,10 +2242,14 @@ class UsersController extends AbstractController 'icon' => url("images/file/light/folder.png"), 'extend' => ['upload_file_id' => 0], 'name' => Doo::translate('文件'), + 'sort' => Carbon::parse("9999")->timestamp, ]; } - $dialogList = WebSocketDialog::getDialogList($user->userid); - foreach ($dialogList['data'] as $dialog) { + $dialogTake = 50; + $dialogList = WebSocketDialog::searchDialog($user->userid, $key, $dialogTake); + $dialogIds = []; + $itemUrl = $type == "file" ? Base::fillUrl("api/dialog/msg/sendfiles") : Base::fillUrl("api/dialog/msg/sendtext"); + foreach ($dialogList as $dialog) { if ($dialog['avatar']) { $avatar = url($dialog['avatar']); } else if ($dialog['type'] == 'user') { @@ -2260,7 +2266,8 @@ class UsersController extends AbstractController 'type' => 'item', 'name' => $dialog['name'], 'icon' => $avatar, - 'url' => $type == "file" ? Base::fillUrl("api/dialog/msg/sendfiles") : Base::fillUrl("api/dialog/msg/sendtext"), + 'url' => $itemUrl, + 'sort' => Carbon::parse($dialog['last_at'])->timestamp, 'extend' => [ 'dialog_ids' => $dialog['id'], 'text_type' => 'text', @@ -2268,6 +2275,33 @@ class UsersController extends AbstractController 'silence' => 'no' ] ]; + $dialogIds[] = $dialog['id']; + } + if ($key && count($dialogList) < $dialogTake) { + $dialogUsers = User::searchUser($key, $dialogTake - count($dialogList)); + foreach ($dialogUsers as $item) { + $dialog = WebSocketDialog::getUserDialog($user->userid, $item->userid, now()->addDay()); + if ($dialog && !in_array($dialog->id, $dialogIds)) { + $lists[] = [ + 'type' => 'item', + 'name' => $item->nickname, + 'icon' => $item->userimg, + 'url' => $itemUrl, + 'sort' => Carbon::parse($item->line_at)->timestamp, + 'extend' => [ + 'dialog_ids' => $dialog->id, + 'text_type' => 'text', + 'reply_id' => 0, + 'silence' => 'no' + ] + ]; + $dialogIds[] = $dialog->id; + } + } + // 根据 $lists sort 从大到小排序 + usort($lists, function ($a, $b) { + return $b['sort'] <=> $a['sort']; + }); } } // 返回 diff --git a/app/Models/User.php b/app/Models/User.php index 74adcc123..d873a6e3d 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -749,4 +749,26 @@ class User extends AbstractModel } return (bool)User::find($userid)?->bot; } + + /** + * 搜索用户 + * @param $key + * @param $take + * @return User[]|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Query\Builder[]|\Illuminate\Support\Collection + */ + public static function searchUser($key, $take = 20) + { + return User::select(User::$basicField) + ->where(function ($query) use ($key) { + if (str_contains($key, "@")) { + $query->where("email", "like", "%{$key}%"); + } else { + $query->where("nickname", "like", "%{$key}%") + ->orWhere("pinyin", "like", "%{$key}%") + ->orWhere("profession", "like", "%{$key}%"); + } + })->orderBy('userid') + ->take($take) + ->get(); + } } diff --git a/app/Models/WebSocketDialog.php b/app/Models/WebSocketDialog.php index 4348f9b9b..1b14b204a 100644 --- a/app/Models/WebSocketDialog.php +++ b/app/Models/WebSocketDialog.php @@ -97,6 +97,32 @@ class WebSocketDialog extends AbstractModel ->whereNull('users.disable_at'); } + /** + * 搜索对话 + * @param $userid + * @param $key + * @param $take + * @return array + */ + public static function searchDialog($userid, $key, $take = 20) + { + return DB::table('web_socket_dialog_users as u') + ->select(['d.*', 'u.top_at', 'u.last_at', 'u.mark_unread', 'u.silence', 'u.hide', 'u.color', 'u.updated_at as user_at']) + ->join('web_socket_dialogs as d', 'u.dialog_id', '=', 'd.id') + ->where('u.userid', $userid) + ->where(function ($query) use ($key) { + $query->where('d.name', 'like', '%' . $key . '%'); + }) + ->whereNull('d.deleted_at') + ->orderByDesc('u.top_at') + ->orderByDesc('u.last_at') + ->take($take) + ->get() + ->map(function($item) use ($userid) { + return WebSocketDialog::synthesizeData($item, $userid); + }) + ->all(); + } /** * 获取对话列表 diff --git a/resources/mobile b/resources/mobile index c9d0d543f..5ae3e352d 160000 --- a/resources/mobile +++ b/resources/mobile @@ -1 +1 @@ -Subproject commit c9d0d543f5102a97db2d54948411f9e2d5c626f5 +Subproject commit 5ae3e352d9bca0339b2d6359398eb825dc605f9a