diff --git a/app/Caches/ImHotGroupList.php b/app/Caches/ImHotGroupList.php index 62b5d78d..b17c2dcc 100644 --- a/app/Caches/ImHotGroupList.php +++ b/app/Caches/ImHotGroupList.php @@ -48,7 +48,6 @@ class ImHotGroupList extends Cache 'name' => $group->name, 'avatar' => $group->avatar, 'about' => $group->about, - 'user_count' => $group->user_count, ]; } diff --git a/app/Caches/ImHotUserList.php b/app/Caches/ImHotUserList.php index 1ae7f453..682e651b 100644 --- a/app/Caches/ImHotUserList.php +++ b/app/Caches/ImHotUserList.php @@ -48,11 +48,7 @@ class ImHotUserList extends Cache 'name' => $user->name, 'avatar' => $user->avatar, 'about' => $user->about, - 'location' => $user->location, - 'gender' => $user->gender, 'vip' => $user->vip, - 'follower_count' => $user->follower_count, - 'following_count' => $user->following_count, ]; } @@ -67,7 +63,7 @@ class ImHotUserList extends Cache { return UserModel::query() ->where('deleted = 0') - ->orderBy('follower_count DESC') + ->orderBy('id DESC') ->limit($limit) ->execute(); } diff --git a/app/Http/Admin/Views/user/list.volt b/app/Http/Admin/Views/user/list.volt index ed87995e..cf4ce09d 100644 --- a/app/Http/Admin/Views/user/list.volt +++ b/app/Http/Admin/Views/user/list.volt @@ -1,12 +1,3 @@ -{%- macro last_login_info(user) %} - {% if user.last_login_ip %} - 学员 - {% endif %} - {% if user.last_login_time %} - 学员 - {% endif %} -{%- endmacro %} - {%- macro gender_info(value) %} {% if value == 1 %} @@ -72,9 +63,9 @@ 编号 昵称 性别 - 最后登录 教学角色 后台角色 + 活跃时间 注册时间 操作 @@ -85,9 +76,9 @@ {{ item.id }} {{ item.name }}{{ status_info(item) }} {{ gender_info(item.gender) }} - {{ last_login_info(item) }} {{ edu_role_info(item) }} {{ admin_role_info(item) }} + {{ date('Y-m-d H:i:s',item.active_time) }} {{ date('Y-m-d H:i:s',item.create_time) }}
diff --git a/app/Http/Web/Controllers/MessengerController.php b/app/Http/Web/Controllers/MessengerController.php index 83e3909a..54ee8c61 100644 --- a/app/Http/Web/Controllers/MessengerController.php +++ b/app/Http/Web/Controllers/MessengerController.php @@ -202,11 +202,15 @@ class MessengerController extends LayerController } /** - * @Post("/stats/update", name="web.im.update_stats") + * @Post("/online/update", name="web.im.update_online") */ - public function updateStatsAction() + public function updateOnlineAction() { + $service = new MessengerService(); + $service->updateOnline(); + + return $this->jsonSuccess(); } /** diff --git a/app/Http/Web/Services/Messenger.php b/app/Http/Web/Services/Messenger.php index 24b13bbd..7e3826b4 100644 --- a/app/Http/Web/Services/Messenger.php +++ b/app/Http/Web/Services/Messenger.php @@ -43,9 +43,9 @@ class Messenger extends Service 'status' => 'online', ]; - $friend = $this->handleFriendList($user->id); + $friend = $this->handleFriendList($user); - $group = $this->handleGroupList($user->id); + $group = $this->handleGroupList($user); return [ 'mine' => $mine, @@ -225,6 +225,11 @@ class Messenger extends Service { $user = $this->getLoginUser(); + $user->update([ + 'online' => 1, + 'active_time' => time(), + ]); + $clientId = $this->request->getPost('client_id'); Gateway::$registerAddress = $this->getRegisterAddress(); @@ -241,7 +246,12 @@ class Messenger extends Service } } - $this->pullUnreadFriendMessages($user->id); + $this->pullUnreadFriendMessages($user); + + /** + * @todo 隐身登录 + */ + $this->pushFriendOnlineTips($user, 'online'); } public function sendMessage() @@ -344,6 +354,21 @@ class Messenger extends Service } } + public function updateOnline() + { + $status = $this->request->getPost('status'); + + $user = $this->getLoginUser(); + + $online = $status == 'online' ? 1 : 0; + + $user->update(['online' => $online]); + + $this->pushFriendOnlineTips($user, $status); + + return $user; + } + public function updateSignature() { $sign = $this->request->getPost('sign'); @@ -500,17 +525,17 @@ class Messenger extends Service $userRepo = new UserRepo(); - $sender = $userRepo->findById($message->sender_id); + $applicant = $userRepo->findById($message->sender_id); $groupUserRepo = new ImChatGroupUserRepo(); - $groupUser = $groupUserRepo->findGroupUser($group->id, $sender->id); + $groupUser = $groupUserRepo->findGroupUser($group->id, $applicant->id); if (!$groupUser) { $groupUserModel = new ImChatGroupUserModel(); $groupUserModel->create([ 'group_id' => $group->id, - 'user_id' => $sender->id, + 'user_id' => $applicant->id, ]); } @@ -518,7 +543,9 @@ class Messenger extends Service $itemInfo['status'] = ImSystemMessageModel::REQUEST_ACCEPTED; $message->update(['item_info' => $itemInfo]); - $this->handleAcceptGroupNotice($user, $sender, $group); + $this->handleAcceptGroupNotice($user, $applicant, $group); + + $this->handleNewGroupUserNotice($applicant, $group); } public function refuseGroup() @@ -554,16 +581,18 @@ class Messenger extends Service $this->handleRefuseGroupNotice($user, $sender); } - protected function pullUnreadFriendMessages($userId) + protected function pullUnreadFriendMessages(UserModel $user) { $userRepo = new UserRepo(); - $messages = $userRepo->findUnreadImFriendMessages($userId); + $messages = $userRepo->findUnreadImFriendMessages($user->id); if ($messages->count() == 0) { return; } + Gateway::$registerAddress = $this->getRegisterAddress(); + $builder = new ImMessageListBuilder(); $senders = $builder->getSenders($messages->toArray()); @@ -588,16 +617,55 @@ class Messenger extends Service ], ]); - Gateway::sendToUid($userId, $content); + Gateway::sendToUid($user->id, $content); } } - protected function handleFriendList($userId) + protected function pushFriendOnlineTips(UserModel $user, $status) + { + /** + * 检查间隔,避免频繁提醒干扰 + */ + if (time() - $user->update_time < 600) { + return; + } + + $userRepo = new UserRepo(); + + $friendUsers = $userRepo->findImFriendUsers($user->id); + + if ($friendUsers->count() == 0) { + return; + } + + $friendIds = kg_array_column($friendUsers->toArray(), 'friend_id'); + + $friends = $userRepo->findByIds($friendIds); + + Gateway::$registerAddress = $this->getRegisterAddress(); + + foreach ($friends as $friend) { + if (Gateway::isUidOnline($friend->id)) { + $content = kg_json_encode([ + 'type' => 'show_online_tips', + 'friend' => [ + 'id' => $user->id, + 'name' => $user->name, + 'avatar' => $user->avatar, + ], + 'status' => $status == 'online' ? 'online' : 'offline', + ]); + Gateway::sendToUid($friend->id, $content); + } + } + } + + protected function handleFriendList(UserModel $user) { $userRepo = new UserRepo(); - $friendGroups = $userRepo->findImFriendGroups($userId); - $friendUsers = $userRepo->findImFriendUsers($userId); + $friendGroups = $userRepo->findImFriendGroups($user->id); + $friendUsers = $userRepo->findImFriendUsers($user->id); $items = []; @@ -634,7 +702,7 @@ class Messenger extends Service 'username' => $user->name, 'avatar' => $user->avatar, 'sign' => $user->sign, - 'status' => 'online', + 'status' => $user->online ? 'online' : 'offline', ]; } @@ -652,11 +720,11 @@ class Messenger extends Service return $items; } - protected function handleGroupList($userId) + protected function handleGroupList(UserModel $user) { $userRepo = new UserRepo(); - $groups = $userRepo->findImChatGroups($userId); + $groups = $userRepo->findImChatGroups($user->id); if ($groups->count() == 0) { return []; @@ -809,7 +877,7 @@ class Messenger extends Service $online = Gateway::isUidOnline($receiver->id); if ($online) { - $content = kg_json_encode(['type' => 'show_sys_msg']); + $content = kg_json_encode(['type' => 'refresh_msg_box']); Gateway::sendToUid($receiver->id, $content); } } @@ -883,7 +951,7 @@ class Messenger extends Service $online = Gateway::isUidOnline($receiver->id); if ($online) { - $content = kg_json_encode(['type' => 'show_sys_msg']); + $content = kg_json_encode(['type' => 'refresh_msg_box']); Gateway::sendToUid($receiver->id, $content); } } @@ -932,7 +1000,7 @@ class Messenger extends Service $online = Gateway::isUidOnline($receiver->id); if ($online) { - $content = kg_json_encode(['type' => 'show_sys_msg']); + $content = kg_json_encode(['type' => 'refresh_msg_box']); Gateway::sendToUid($receiver->id, $content); } } @@ -992,14 +1060,44 @@ class Messenger extends Service Gateway::$registerAddress = $this->getRegisterAddress(); - $online = Gateway::isUidOnline($receiver->id); - - if ($online) { - $content = kg_json_encode(['type' => 'show_sys_msg']); + if (Gateway::isUidOnline($receiver->id)) { + $content = kg_json_encode(['type' => 'refresh_msg_box']); Gateway::sendToUid($receiver->id, $content); } } + protected function handleNewGroupUserNotice(UserModel $newUser, ImChatGroupModel $group) + { + $groupRepo = new ImChatGroupRepo(); + + $users = $groupRepo->findGroupUsers($group->id); + + if ($users->count() == 0) { + return; + } + + Gateway::$registerAddress = $this->getRegisterAddress(); + + foreach ($users as $user) { + $content = kg_json_encode([ + 'type' => 'new_group_user', + 'user' => [ + 'id' => $newUser->id, + 'name' => $newUser->name, + 'avatar' => $newUser->avatar, + ], + 'group' => [ + 'id' => $group->id, + 'name' => $group->name, + 'avatar' => $group->avatar, + ], + ]); + if (Gateway::isUidOnline($user->id)) { + Gateway::sendToUid($user->id, $content); + } + } + } + protected function getGroupName($groupId) { return "group_{$groupId}"; diff --git a/app/Http/Web/Views/messenger/find_users.volt b/app/Http/Web/Views/messenger/find_users.volt index 5fa9e853..410a9b85 100644 --- a/app/Http/Web/Views/messenger/find_users.volt +++ b/app/Http/Web/Views/messenger/find_users.volt @@ -4,6 +4,9 @@ {% for item in pager.items %}
+ {% if item.vip == 0 %} + 会员 + {% endif %}
{{ item.name }}
diff --git a/app/Http/Web/Views/user/friends.volt b/app/Http/Web/Views/user/friends.volt index c159accb..aa35159d 100644 --- a/app/Http/Web/Views/user/friends.volt +++ b/app/Http/Web/Views/user/friends.volt @@ -4,6 +4,9 @@ {% for item in pager.items %}
+ {% if item.vip == 0 %} + 会员 + {% endif %}
{{ item.name }}
diff --git a/app/Http/Web/Views/user/show.volt b/app/Http/Web/Views/user/show.volt index 3f23b7fd..3342f3b7 100644 --- a/app/Http/Web/Views/user/show.volt +++ b/app/Http/Web/Views/user/show.volt @@ -13,7 +13,7 @@

{{ user.name }} {{ vip_flag }}

{{ user.location }}

-

{{ date('Y-m-d H:i',user.last_login_time) }}

+

{{ date('Y-m-d H:i',user.active_time) }}

{% if user.about %}
{{ user.about }}
diff --git a/app/Models/User.php b/app/Models/User.php index cc0529cb..841a7343 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -93,7 +93,14 @@ class User extends Model public $admin_role; /** - * VIP标识 + * 在线标识 + * + * @var int + */ + public $online; + + /** + * 会员标识 * * @var int */ @@ -113,20 +120,6 @@ class User extends Model */ public $deleted; - /** - * 最近登录IP - * - * @var string - */ - public $last_login_ip; - - /** - * 最近登录时间 - * - * @var int - */ - public $last_login_time; - /** * VIP期限 * @@ -142,18 +135,11 @@ class User extends Model public $lock_expiry_time; /** - * 关注数量 + * 活跃时间 * * @var int */ - public $following_count; - - /** - * 粉丝数量 - * - * @var int - */ - public $follower_count; + public $active_time; /** * 创建时间 diff --git a/app/Repos/User.php b/app/Repos/User.php index b58c96d6..29b985df 100644 --- a/app/Repos/User.php +++ b/app/Repos/User.php @@ -54,9 +54,6 @@ class User extends Repository } switch ($sort) { - case 'popular': - $orderBy = 'follower_count DESC'; - break; default: $orderBy = 'id DESC'; break; diff --git a/app/Services/Frontend/User/UserInfo.php b/app/Services/Frontend/User/UserInfo.php index f23e694b..919f93f9 100644 --- a/app/Services/Frontend/User/UserInfo.php +++ b/app/Services/Frontend/User/UserInfo.php @@ -30,7 +30,7 @@ class UserInfo extends FrontendService 'gender' => $user->gender, 'vip' => $user->vip, 'locked' => $user->locked, - 'last_login_time' => $user->last_login_time, + 'active_time' => $user->active_time, 'create_time' => $user->create_time, ]; } diff --git a/public/static/web/css/common.css b/public/static/web/css/common.css index 4a0b2e4a..38f4bf91 100644 --- a/public/static/web/css/common.css +++ b/public/static/web/css/common.css @@ -1153,6 +1153,7 @@ float: left; width: 100%; height: 220px; + position: relative; text-align: center; background-color: #fff; border-radius: 2px; @@ -1184,6 +1185,19 @@ font-size: 12px; } +.user-card .vip { + position: absolute; + top: 8px; + right: 8px; + padding: 1px 3px; + border-radius: 2px; + text-align: center; + font-size: 12px; + line-height: 1.5em; + background-color: orange; + color: white; +} + .user-card .action span { cursor: pointer; } @@ -1312,6 +1326,12 @@ padding: 0 5px; } +.im-user-list .vip { + top: 5px; + right: 5px; + font-size: 10px; +} + .layim-msgbox { margin: 15px; } @@ -1324,15 +1344,7 @@ border-bottom: 1px dotted #e2e2e2; } -.layim-msgbox .layim-msgbox-tips { - margin: 0; - padding: 10px 0; - border: none; - text-align: center; - color: #999; -} - -.layim-msgbox .layim-msgbox-system { +.layim-msgbox-system { padding: 0 10px 10px 10px; } diff --git a/public/static/web/js/im.js b/public/static/web/js/im.js index 57282bf9..d5359d6d 100644 --- a/public/static/web/js/im.js +++ b/public/static/web/js/im.js @@ -23,17 +23,21 @@ layui.use(['jquery', 'layim'], function () { socket.send('pong...'); } else if (data.type === 'bind_user') { bindUser(data); - showSystemMessage(); + refreshMessageBox(); + } else if (data.type === 'new_group_user') { + showNewGroupUserMessage(data); + } else if (data.type === 'show_online_tips') { + showOnlineTips(data); } else if (data.type === 'show_chat_msg') { showChatMessage(data); - } else if (data.type === 'show_sys_msg') { - showSystemMessage(); + } else if (data.type === 'refresh_msg_box') { + refreshMessageBox(); } else if (data.type === 'friend_accepted') { friendAccepted(data); - showSystemMessage(); + refreshMessageBox(); } else if (data.type === 'group_accepted') { groupAccepted(data); - showSystemMessage(); + refreshMessageBox(); } }; @@ -61,6 +65,14 @@ layui.use(['jquery', 'layim'], function () { sendChatMessage(res); }); + layim.on('online', function (status) { + $.ajax({ + type: 'POST', + url: '/im/online/update', + data: {status: status} + }); + }); + layim.on('sign', function (sign) { $.ajax({ type: 'POST', @@ -89,7 +101,17 @@ layui.use(['jquery', 'layim'], function () { layim.getMessage(res.message); } - function showSystemMessage() { + function showNewGroupUserMessage(res) { + var content = '[' + res.user.name + '] 加入群聊'; + layim.getMessage({ + system: true, + type: 'group', + id: res.group.id, + content: content + }); + } + + function refreshMessageBox() { $.ajax({ type: 'GET', url: '/im/msg/unread/count', @@ -101,6 +123,16 @@ layui.use(['jquery', 'layim'], function () { }); } + function showOnlineTips(res) { + var msg = res.friend.name + '上线了'; + layer.msg(msg, { + icon: 6, + offset: 'b', + anim: 6 + }); + layim.setFriendStatus(res.friend.id, res.status); + } + function friendAccepted(res) { layim.addList({ type: 'friend',