1
0
mirror of https://gitee.com/koogua/course-tencent-cloud.git synced 2025-07-01 14:44:56 +08:00

完成未读消息,离线消息

This commit is contained in:
xiaochong0302 2020-07-01 19:45:28 +08:00
parent fc436d013f
commit b69bfb0471
24 changed files with 104 additions and 57 deletions

View File

@ -61,6 +61,7 @@ class Controller extends \Phalcon\Mvc\Controller
$this->view->setVar('site_navs', $this->siteNavs);
$this->view->setVar('site_settings', $this->siteSettings);
$this->view->setVar('auth_user', $this->authUser);
$this->view->setVar('socket_url', $this->getSocketUrl());
}
protected function getAuthUser()
@ -92,4 +93,11 @@ class Controller extends \Phalcon\Mvc\Controller
return new SiteSeo();
}
protected function getSocketUrl()
{
$config = $this->getDI()->get('config');
return $config->websocket->url;
}
}

View File

@ -27,9 +27,9 @@ class ImController extends LayerController
}
/**
* @Get("/group/members", name="web.im.group_members")
* @Get("/group/users", name="web.im.group_users")
*/
public function groupMembersAction()
public function groupUsersAction()
{
$service = new ImService();
@ -51,9 +51,9 @@ class ImController extends LayerController
}
/**
* @Get("/msg/sys/unread/count", name="web.im.count_unread_sys_msg")
* @Get("/msg/sys/unread/count", name="web.im.unread_sys_msg_count")
*/
public function countUnreadSystemMessagesAction()
public function unreadSystemMessagesCountAction()
{
$service = new ImService();
@ -62,18 +62,6 @@ class ImController extends LayerController
return $this->jsonSuccess(['count' => $count]);
}
/**
* @Post("/msg/sys/read", name="web.im.read_sys_msg")
*/
public function readSystemMessagesAction()
{
$service = new ImService();
$service->readSystemMessages();
return $this->jsonSuccess();
}
/**
* @Get("/msg/box", name="web.im.msg_box")
*/
@ -83,7 +71,7 @@ class ImController extends LayerController
$pager = $service->getSystemMessages();
$this->view->pick('messenger/msg_box');
$this->view->pick('im/msg_box');
$this->view->setVar('pager', $pager);
}
@ -98,10 +86,22 @@ class ImController extends LayerController
$pager->items = kg_array_object($pager->items);
$this->view->pick('messenger/sys_messages');
$this->view->pick('im/sys_messages');
$this->view->setVar('pager', $pager);
}
/**
* @Post("/msg/sys/read", name="web.im.read_sys_msg")
*/
public function readSystemMessagesAction()
{
$service = new ImService();
$service->readSystemMessages();
return $this->jsonSuccess();
}
/**
* @Get("/friend/status", name="web.im.friend_status")
*/
@ -124,7 +124,7 @@ class ImController extends LayerController
$pager = $service->getChatMessages();
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
$this->view->pick('messenger/chat_log');
$this->view->pick('im/chat_log');
$this->view->setVar('pager', $pager);
}
@ -171,11 +171,11 @@ class ImController extends LayerController
$service = new ImService();
if ($type == 'user') {
$this->view->pick('messenger/find_users');
$this->view->pick('im/find_users');
$target = $target ?: 'tab-users';
$pager = $service->searchUsers($query);
} else {
$this->view->pick('messenger/find_groups');
$this->view->pick('im/find_groups');
$target = $target ?: 'tab-groups';
$pager = $service->searchGroups($query);
}

View File

@ -10,6 +10,7 @@ use App\Models\ImFriendMessage as ImFriendMessageModel;
use App\Models\ImGroupMessage as ImGroupMessageModel;
use App\Models\User as UserModel;
use App\Repos\ImFriendMessage as ImFriendMessageRepo;
use App\Repos\ImFriendUser as ImFriendUserRepo;
use App\Repos\ImGroup as ImGroupRepo;
use App\Repos\ImGroupMessage as ImGroupMessageRepo;
use App\Repos\ImSystemMessage as ImSystemMessageRepo;
@ -168,7 +169,7 @@ class Im extends Service
$userRepo = new UserRepo();
$messages = $userRepo->findUnreadImFriendMessages($user->id, $friend->id);
$messages = $userRepo->findUnreadImFriendMessages($friend->id, $user->id);
if ($messages->count() == 0) {
return;
@ -185,9 +186,9 @@ class Im extends Service
'message' => [
'username' => $friend->name,
'avatar' => $friend->avatar,
'content' => $message->content,
'fromid' => $friend->id,
'id' => $friend->id,
'fromid' => $friend->id,
'content' => $message->content,
'timestamp' => 1000 * $message->create_time,
'type' => 'friend',
'mine' => false,
@ -196,6 +197,12 @@ class Im extends Service
Gateway::sendToUid($user->id, $content);
}
$repo = new ImFriendUserRepo();
$friendUser = $repo->findFriendUser($user->id, $friend->id);
$friendUser->update(['msg_count' => 0]);
}
public function countUnreadSystemMessages()
@ -287,9 +294,7 @@ class Im extends Service
Gateway::$registerAddress = $this->getRegisterAddress();
if (Gateway::isUidOnline($friend->id)) {
$status = 'online';
}
$status = Gateway::isUidOnline($friend->id) ? 'online' : 'offline';
return $status;
}
@ -384,7 +389,8 @@ class Im extends Service
if ($online) {
Gateway::sendToUid($to['id'], $content);
} else {
$relation->update(['msg_count' => $relation->msg_count + 1]);
$msgCount = $relation->msg_count + 1;
$relation->update(['msg_count' => $msgCount]);
}
} elseif ($to['type'] == 'group') {
@ -403,8 +409,8 @@ class Im extends Service
$messageModel = new ImGroupMessageModel();
$messageModel->create([
'sender_id' => $from['id'],
'group_id' => $to['id'],
'sender_id' => $from['id'],
'content' => $from['content'],
]);
@ -583,13 +589,19 @@ class Im extends Service
$userMappings = [];
/**
* 用户可以设置状态为 ['online', 'hide']
* 列表在线状态识别为 ['online', 'offline']
*/
foreach ($users as $user) {
$status = $user->im['online']['status'] ?? 'offline';
$status = in_array($status, ['online', 'offline']) ? $status : 'offline';
$userMappings[$user->id] = [
'id' => $user->id,
'username' => $user->name,
'avatar' => $user->avatar,
'sign' => $user->im['sign'] ?? '',
'status' => $user->im['online']['status'] ?? 'offline',
'status' => $status,
];
}

View File

@ -17,10 +17,10 @@
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show" id="tab-users">
{{ partial('messenger/find_users',{'pager':users_pager}) }}
{{ partial('im/find_users',{'pager':users_pager}) }}
</div>
<div class="layui-tab-item" id="tab-groups">
{{ partial('messenger/find_groups',{'pager':groups_pager}) }}
{{ partial('im/find_groups',{'pager':groups_pager}) }}
</div>
</div>
</div>

View File

@ -0,0 +1,14 @@
<script>
window.koogua = {
user: {
id: '{{ auth_user.id }}',
name: '{{ auth_user.name }}',
avatar: '{{ auth_user.avatar }}',
locked: '{{ auth_user.locked }}',
vip: '{{ auth_user.vip }}'
},
socketUrl: '{{ socket_url }}'
};
</script>

View File

@ -27,6 +27,7 @@
{{ partial('partials/footer') }}
</div>
{{ partial('partials/js_global_vars') }}
{{ js_include('lib/layui/layui.js') }}
{{ js_include('web/js/common.js') }}
{{ js_include('web/js/fixbar.js') }}

View File

@ -13,6 +13,7 @@
<body class="layer">
{% block content %}{% endblock %}
{{ partial('partials/js_global_vars') }}
{{ js_include('lib/layui/layui.js') }}
{{ js_include('web/js/common.js') }}

View File

@ -215,9 +215,7 @@ class Chapter extends Model
break;
}
if (!empty($attrs)) {
$this->attrs = kg_json_encode($attrs);
}
$this->attrs = kg_json_encode($attrs);
}
}
@ -266,8 +264,6 @@ class Chapter extends Model
{
if (!empty($this->attrs) && is_string($this->attrs)) {
$this->attrs = json_decode($this->attrs, true);
} else {
$this->attrs = [];
}
}

View File

@ -320,8 +320,6 @@ class Course extends Model
if (!empty($this->attrs) && is_string($this->attrs)) {
$this->attrs = json_decode($this->attrs, true);
} else {
$this->attrs = [];
}
}

View File

@ -194,8 +194,6 @@ class Order extends Model
if (!empty($this->item_info) && is_string($this->item_info)) {
$this->item_info = json_decode($this->item_info, true);
} else {
$this->item_info = [];
}
}

View File

@ -114,14 +114,14 @@ class Role extends Model
{
$this->update_time = time();
if (!empty($this->routes)) {
if (is_array($this->routes)) {
$this->routes = kg_json_encode($this->routes);
}
}
public function afterFetch()
{
if (!empty($this->routes)) {
if (!empty($this->routes) && is_string($this->routes)) {
$this->routes = json_decode($this->routes, true);
}
}

View File

@ -120,8 +120,6 @@ class Task extends Model
{
if (!empty($this->item_info) && is_string($this->item_info)) {
$this->item_info = json_decode($this->item_info, true);
} else {
$this->item_info = [];
}
}

View File

@ -220,8 +220,6 @@ class User extends Model
if (!empty($this->im) && is_string($this->im)) {
$this->im = json_decode($this->im, true);
} else {
$this->im = [];
}
}

View File

@ -156,15 +156,15 @@ class User extends Repository
}
/**
* @param int $userId
* @param int $friendId
* @param int $userId
* @return ResultsetInterface|Resultset|ImFriendMessageModel[]
*/
public function findUnreadImFriendMessages($userId, $friendId)
public function findUnreadImFriendMessages($friendId, $userId)
{
return ImFriendMessageModel::find([
'conditions' => 'sender_id = ?1 AND receiver_id = ?2 AND viewed = ?3',
'bind' => [1 => $userId, 2 => $friendId, 3 => 0],
'bind' => [1 => $friendId, 2 => $userId, 3 => 0],
]);
}

View File

@ -37,6 +37,8 @@ class ImGroupUser extends Validator
if (!$record) {
throw new BadRequestException('im_chat_group_user.not_found');
}
return $record;
}
public function checkIfJoined($userId, $groupId)

View File

@ -1414,4 +1414,12 @@
height: 12px;
border-radius: 2px;
font-size: 10px;
}
.layim-chat-status .online {
color: green;
}
.layim-chat-status .offline {
color: gray;
}

View File

@ -2,7 +2,7 @@ layui.use(['jquery', 'layim'], function () {
var $ = layui.jquery;
var layim = layui.layim;
var socket = new WebSocket('ws://127.0.0.1:8282');
var socket = new WebSocket(window.koogua.socketUrl);
socket.onopen = function () {
console.log('socket connect success');
@ -48,7 +48,7 @@ layui.use(['jquery', 'layim'], function () {
url: '/im/init'
},
members: {
url: '/im/group/members'
url: '/im/group/users'
},
uploadImage: {
url: '/im/img/upload'
@ -63,7 +63,6 @@ layui.use(['jquery', 'layim'], function () {
});
layim.on('ready', function (options) {
console.log(options.friend);
if (options.friend.length > 0) {
layui.each(options.friend, function (i, group) {
layui.each(group.list, function (j, user) {
@ -82,6 +81,9 @@ layui.use(['jquery', 'layim'], function () {
layim.on('chatChange', function (res) {
resetChatMessageCount(res);
if (res.data.type === 'friend') {
setFriendStatus(res);
}
});
layim.on('online', function (status) {
@ -145,7 +147,8 @@ layui.use(['jquery', 'layim'], function () {
function resetChatMessageCount(res) {
var $tabMsgCount = $('.layim-chatlist-' + res.data.type + res.data.id + ' > .msg-count');
var $listMsgCount = $('.layui-layim-list > .layim-friend' + res.data.id + ' > .msg-count');
if (res.data.type === 'friend' && $listMsgCount.text() !== '0') {
var unreadListMsgCount = parseInt($listMsgCount.text());
if (res.data.type === 'friend' && unreadListMsgCount > 0) {
$.ajax({
type: 'GET',
url: '/im/msg/friend/unread',
@ -157,14 +160,24 @@ layui.use(['jquery', 'layim'], function () {
}
function setFriendStatus(res) {
var date = new Date();
var lastQueryTime = parseInt($('#online-status-' + res.data.id).data('time'));
if (lastQueryTime > 0 && date.getTime() - lastQueryTime < 600000) {
return;
}
$.ajax({
type: 'GET',
url: '/im/friend/status',
data: {id: res.data.id},
success: function (data) {
if (data.status === 'online') {
layim.setChatStatus('<span style="color:green;">在线</span>');
layim.setChatStatus('<span id="online-status-' + res.data.id + '" class="online" data-time="' + date.getTime() + '">在线</span>');
layim.setFriendStatus(res.data.id, 'online');
} else if (data.status === 'offline') {
layim.setChatStatus('<span id="online-status-' + res.data.id + '" class="offline" data-time="' + date.getTime() + '">离线</span>');
layim.setFriendStatus(res.data.id, 'offline');
} else {
layim.setChatStatus('<span id="online-status-' + res.data.id + '" class="unknown" data-time="' + date.getTime() + '"></span>');
}
}
});

View File

@ -23,7 +23,7 @@ require_once dirname(__DIR__) . '/vendor/autoload.php';
$worker = new BusinessWorker();
// worker名称
$worker->name = 'CourseBusinessWorker';
$worker->name = 'ChatBusinessWorker';
// businessWorker进程数量
$worker->count = 4;

View File

@ -23,7 +23,7 @@ require_once dirname(__DIR__) . '/vendor/autoload.php';
$gateway = new Gateway("websocket://0.0.0.0:8282");
// gateway名称status方便查看
$gateway->name = 'CourseGateway';
$gateway->name = 'ChatGateway';
// gateway进程数
$gateway->count = 4;