mirror of
https://gitee.com/koogua/course-tencent-cloud.git
synced 2025-07-01 14:44:56 +08:00
完成未读消息,离线消息
This commit is contained in:
parent
fc436d013f
commit
b69bfb0471
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -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>
|
14
app/Http/Web/Views/partials/js_global_vars.volt
Normal file
14
app/Http/Web/Views/partials/js_global_vars.volt
Normal 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>
|
@ -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') }}
|
||||
|
@ -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') }}
|
||||
|
||||
|
@ -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 = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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],
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -1414,4 +1414,12 @@
|
||||
height: 12px;
|
||||
border-radius: 2px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.layim-chat-status .online {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.layim-chat-status .offline {
|
||||
color: gray;
|
||||
}
|
@ -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>');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user