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 %}
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 %}
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',
|