diff --git a/app/Http/Web/Controllers/Controller.php b/app/Http/Web/Controllers/Controller.php index 53398935..273ad118 100644 --- a/app/Http/Web/Controllers/Controller.php +++ b/app/Http/Web/Controllers/Controller.php @@ -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; + } + } diff --git a/app/Http/Web/Controllers/ImController.php b/app/Http/Web/Controllers/ImController.php index 84d4cb24..e96af78d 100644 --- a/app/Http/Web/Controllers/ImController.php +++ b/app/Http/Web/Controllers/ImController.php @@ -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); } diff --git a/app/Http/Web/Services/Im.php b/app/Http/Web/Services/Im.php index 6e9c593b..d84fe9cd 100644 --- a/app/Http/Web/Services/Im.php +++ b/app/Http/Web/Services/Im.php @@ -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, ]; } diff --git a/app/Http/Web/Views/messenger/chat_log.volt b/app/Http/Web/Views/im/chat_log.volt similarity index 100% rename from app/Http/Web/Views/messenger/chat_log.volt rename to app/Http/Web/Views/im/chat_log.volt diff --git a/app/Http/Web/Views/messenger/find.volt b/app/Http/Web/Views/im/find.volt similarity index 85% rename from app/Http/Web/Views/messenger/find.volt rename to app/Http/Web/Views/im/find.volt index f5d02c02..1565251f 100644 --- a/app/Http/Web/Views/messenger/find.volt +++ b/app/Http/Web/Views/im/find.volt @@ -17,10 +17,10 @@
- {{ partial('messenger/find_users',{'pager':users_pager}) }} + {{ partial('im/find_users',{'pager':users_pager}) }}
- {{ partial('messenger/find_groups',{'pager':groups_pager}) }} + {{ partial('im/find_groups',{'pager':groups_pager}) }}
diff --git a/app/Http/Web/Views/messenger/find_groups.volt b/app/Http/Web/Views/im/find_groups.volt similarity index 100% rename from app/Http/Web/Views/messenger/find_groups.volt rename to app/Http/Web/Views/im/find_groups.volt diff --git a/app/Http/Web/Views/messenger/find_users.volt b/app/Http/Web/Views/im/find_users.volt similarity index 100% rename from app/Http/Web/Views/messenger/find_users.volt rename to app/Http/Web/Views/im/find_users.volt diff --git a/app/Http/Web/Views/messenger/msg_box.volt b/app/Http/Web/Views/im/msg_box.volt similarity index 100% rename from app/Http/Web/Views/messenger/msg_box.volt rename to app/Http/Web/Views/im/msg_box.volt diff --git a/app/Http/Web/Views/messenger/sys_messages.volt b/app/Http/Web/Views/im/sys_messages.volt similarity index 100% rename from app/Http/Web/Views/messenger/sys_messages.volt rename to app/Http/Web/Views/im/sys_messages.volt diff --git a/app/Http/Web/Views/partials/js_global_vars.volt b/app/Http/Web/Views/partials/js_global_vars.volt new file mode 100644 index 00000000..5a8b21e9 --- /dev/null +++ b/app/Http/Web/Views/partials/js_global_vars.volt @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/app/Http/Web/Views/templates/full.volt b/app/Http/Web/Views/templates/full.volt index 32eb3fcf..6d717396 100644 --- a/app/Http/Web/Views/templates/full.volt +++ b/app/Http/Web/Views/templates/full.volt @@ -27,6 +27,7 @@ {{ partial('partials/footer') }} +{{ partial('partials/js_global_vars') }} {{ js_include('lib/layui/layui.js') }} {{ js_include('web/js/common.js') }} {{ js_include('web/js/fixbar.js') }} diff --git a/app/Http/Web/Views/templates/layer.volt b/app/Http/Web/Views/templates/layer.volt index b9b1c962..3bb71648 100644 --- a/app/Http/Web/Views/templates/layer.volt +++ b/app/Http/Web/Views/templates/layer.volt @@ -13,6 +13,7 @@ {% block content %}{% endblock %} +{{ partial('partials/js_global_vars') }} {{ js_include('lib/layui/layui.js') }} {{ js_include('web/js/common.js') }} diff --git a/app/Models/Chapter.php b/app/Models/Chapter.php index bdc74fcf..c147d91f 100644 --- a/app/Models/Chapter.php +++ b/app/Models/Chapter.php @@ -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 = []; } } diff --git a/app/Models/Course.php b/app/Models/Course.php index b7305ac7..194e52d0 100644 --- a/app/Models/Course.php +++ b/app/Models/Course.php @@ -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 = []; } } diff --git a/app/Models/Order.php b/app/Models/Order.php index 48100c4e..1a18daae 100644 --- a/app/Models/Order.php +++ b/app/Models/Order.php @@ -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 = []; } } diff --git a/app/Models/Role.php b/app/Models/Role.php index e85e89fa..780c579e 100644 --- a/app/Models/Role.php +++ b/app/Models/Role.php @@ -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); } } diff --git a/app/Models/Task.php b/app/Models/Task.php index ce2e72ed..f38c7306 100644 --- a/app/Models/Task.php +++ b/app/Models/Task.php @@ -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 = []; } } diff --git a/app/Models/User.php b/app/Models/User.php index b651c594..8cec91e8 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -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 = []; } } diff --git a/app/Repos/User.php b/app/Repos/User.php index 4eee2000..d1c007b7 100644 --- a/app/Repos/User.php +++ b/app/Repos/User.php @@ -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], ]); } diff --git a/app/Validators/ImGroupUser.php b/app/Validators/ImGroupUser.php index 73d09b5a..c1a55918 100644 --- a/app/Validators/ImGroupUser.php +++ b/app/Validators/ImGroupUser.php @@ -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) diff --git a/public/static/web/css/common.css b/public/static/web/css/common.css index 73088f6e..6d0b6ccc 100644 --- a/public/static/web/css/common.css +++ b/public/static/web/css/common.css @@ -1414,4 +1414,12 @@ height: 12px; border-radius: 2px; font-size: 10px; +} + +.layim-chat-status .online { + color: green; +} + +.layim-chat-status .offline { + color: gray; } \ No newline at end of file diff --git a/public/static/web/js/im.js b/public/static/web/js/im.js index 389c18d5..d55be50a 100644 --- a/public/static/web/js/im.js +++ b/public/static/web/js/im.js @@ -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('在线'); + layim.setChatStatus('在线'); layim.setFriendStatus(res.data.id, 'online'); + } else if (data.status === 'offline') { + layim.setChatStatus('离线'); + layim.setFriendStatus(res.data.id, 'offline'); + } else { + layim.setChatStatus(''); } } }); diff --git a/websocket/start_business_worker.php b/websocket/start_business_worker.php index 603c1bfd..e0132056 100644 --- a/websocket/start_business_worker.php +++ b/websocket/start_business_worker.php @@ -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; diff --git a/websocket/start_gateway.php b/websocket/start_gateway.php index adf405c5..313903b4 100644 --- a/websocket/start_gateway.php +++ b/websocket/start_gateway.php @@ -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;