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
9185eb0731
commit
7c2d87c411
@ -7,20 +7,20 @@ use App\Repos\User as UserRepo;
|
|||||||
class ImMessageList extends Builder
|
class ImMessageList extends Builder
|
||||||
{
|
{
|
||||||
|
|
||||||
public function handleUsers(array $messages)
|
public function handleSenders(array $messages)
|
||||||
{
|
{
|
||||||
$users = $this->getUsers($messages);
|
$users = $this->getSenders($messages);
|
||||||
|
|
||||||
foreach ($messages as $key => $message) {
|
foreach ($messages as $key => $message) {
|
||||||
$messages[$key]['user'] = $users[$message['user_id']] ?? new \stdClass();
|
$messages[$key]['sender'] = $users[$message['sender_id']] ?? new \stdClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $messages;
|
return $messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUsers(array $messages)
|
public function getSenders(array $messages)
|
||||||
{
|
{
|
||||||
$ids = kg_array_column($messages, 'user_id');
|
$ids = kg_array_column($messages, 'sender_id');
|
||||||
|
|
||||||
$userRepo = new UserRepo();
|
$userRepo = new UserRepo();
|
||||||
|
|
||||||
|
@ -38,12 +38,56 @@ class MessengerController extends LayerController
|
|||||||
return $this->jsonSuccess(['data' => ['list' => $list]]);
|
return $this->jsonSuccess(['data' => ['list' => $list]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Get("/msg/unread/count", name="web.im.unread_msg_count")
|
||||||
|
*/
|
||||||
|
public function unreadMessagesCountAction()
|
||||||
|
{
|
||||||
|
$service = new MessengerService();
|
||||||
|
|
||||||
|
$count = $service->getUnreadSystemMessagesCount();
|
||||||
|
|
||||||
|
return $this->jsonSuccess(['count' => $count]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Post("/msg/read", name="web.im.read_msg")
|
||||||
|
*/
|
||||||
|
public function markMessagesAsReadAction()
|
||||||
|
{
|
||||||
|
$service = new MessengerService();
|
||||||
|
|
||||||
|
$service->markSystemMessagesAsRead();
|
||||||
|
|
||||||
|
return $this->jsonSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Get("/msg/box", name="web.im.msg_box")
|
* @Get("/msg/box", name="web.im.msg_box")
|
||||||
*/
|
*/
|
||||||
public function messageBoxAction()
|
public function messageBoxAction()
|
||||||
{
|
{
|
||||||
|
$service = new MessengerService();
|
||||||
|
|
||||||
|
$pager = $service->getSystemMessages();
|
||||||
|
|
||||||
|
$this->view->pick('messenger/msg_box');
|
||||||
|
$this->view->setVar('pager', $pager);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Get("/msg/sys", name="web.im.sys_msg")
|
||||||
|
*/
|
||||||
|
public function systemMessagesAction()
|
||||||
|
{
|
||||||
|
$service = new MessengerService();
|
||||||
|
|
||||||
|
$pager = $service->getSystemMessages();
|
||||||
|
|
||||||
|
$pager->items = kg_array_object($pager->items);
|
||||||
|
|
||||||
|
$this->view->pick('messenger/sys_messages');
|
||||||
|
$this->view->setVar('pager', $pager);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -53,7 +97,7 @@ class MessengerController extends LayerController
|
|||||||
{
|
{
|
||||||
$service = new MessengerService();
|
$service = new MessengerService();
|
||||||
|
|
||||||
$pager = $service->getChatLog();
|
$pager = $service->getChatMessages();
|
||||||
|
|
||||||
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
|
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
|
||||||
$this->view->pick('messenger/chat_log');
|
$this->view->pick('messenger/chat_log');
|
||||||
@ -67,7 +111,7 @@ class MessengerController extends LayerController
|
|||||||
{
|
{
|
||||||
$service = new MessengerService();
|
$service = new MessengerService();
|
||||||
|
|
||||||
$pager = $service->getChatLog();
|
$pager = $service->getChatMessages();
|
||||||
|
|
||||||
return $this->jsonPaginate($pager);
|
return $this->jsonPaginate($pager);
|
||||||
}
|
}
|
||||||
|
@ -8,12 +8,14 @@ use App\Caches\ImHotUserList as ImHotUserListCache;
|
|||||||
use App\Library\Paginator\Query as PagerQuery;
|
use App\Library\Paginator\Query as PagerQuery;
|
||||||
use App\Models\ImFriendMessage as ImFriendMessageModel;
|
use App\Models\ImFriendMessage as ImFriendMessageModel;
|
||||||
use App\Models\ImFriendUser as ImFriendUserModel;
|
use App\Models\ImFriendUser as ImFriendUserModel;
|
||||||
|
use App\Models\ImGroupMessage as ImGroupMessageModel;
|
||||||
use App\Models\ImSystemMessage as ImSystemMessageModel;
|
use App\Models\ImSystemMessage as ImSystemMessageModel;
|
||||||
use App\Models\User as UserModel;
|
use App\Models\User as UserModel;
|
||||||
use App\Repos\ImChatGroup as ImChatGroupRepo;
|
use App\Repos\ImChatGroup as ImChatGroupRepo;
|
||||||
use App\Repos\ImFriendMessage as ImFriendMessageRepo;
|
use App\Repos\ImFriendMessage as ImFriendMessageRepo;
|
||||||
use App\Repos\ImFriendUser as ImFriendUserRepo;
|
use App\Repos\ImFriendUser as ImFriendUserRepo;
|
||||||
use App\Repos\ImGroupMessage as ImGroupMessageRepo;
|
use App\Repos\ImGroupMessage as ImGroupMessageRepo;
|
||||||
|
use App\Repos\ImSystemMessage as ImSystemMessageRepo;
|
||||||
use App\Repos\User as UserRepo;
|
use App\Repos\User as UserRepo;
|
||||||
use App\Validators\ImChatGroup as ImChatGroupValidator;
|
use App\Validators\ImChatGroup as ImChatGroupValidator;
|
||||||
use App\Validators\ImFriendUser as ImFriendUserValidator;
|
use App\Validators\ImFriendUser as ImFriendUserValidator;
|
||||||
@ -148,7 +150,35 @@ class Messenger extends Service
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getChatLog()
|
public function getUnreadSystemMessagesCount()
|
||||||
|
{
|
||||||
|
$user = $this->getLoginUser();
|
||||||
|
|
||||||
|
$userRepo = new UserRepo();
|
||||||
|
|
||||||
|
return $userRepo->countUnreadImSystemMessages($user->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSystemMessages()
|
||||||
|
{
|
||||||
|
$user = $this->getLoginUser();
|
||||||
|
|
||||||
|
$pagerQuery = new PagerQuery();
|
||||||
|
|
||||||
|
$params = $pagerQuery->getParams();
|
||||||
|
|
||||||
|
$params['receiver_id'] = $user->id;
|
||||||
|
|
||||||
|
$sort = $pagerQuery->getSort();
|
||||||
|
$page = $pagerQuery->getPage();
|
||||||
|
$limit = $pagerQuery->getLimit();
|
||||||
|
|
||||||
|
$messageRepo = new ImSystemMessageRepo();
|
||||||
|
|
||||||
|
return $messageRepo->paginate($params, $sort, $page, $limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getChatMessages()
|
||||||
{
|
{
|
||||||
$user = $this->getLoginUser();
|
$user = $this->getLoginUser();
|
||||||
|
|
||||||
@ -172,7 +202,7 @@ class Messenger extends Service
|
|||||||
|
|
||||||
$pager = $messageRepo->paginate($params, $sort, $page, $limit);
|
$pager = $messageRepo->paginate($params, $sort, $page, $limit);
|
||||||
|
|
||||||
return $this->handleChatLogPager($pager);
|
return $this->handleChatMessagePager($pager);
|
||||||
|
|
||||||
} elseif ($params['type'] == 'group') {
|
} elseif ($params['type'] == 'group') {
|
||||||
|
|
||||||
@ -182,7 +212,7 @@ class Messenger extends Service
|
|||||||
|
|
||||||
$pager = $messageRepo->paginate($params, $sort, $page, $limit);
|
$pager = $messageRepo->paginate($params, $sort, $page, $limit);
|
||||||
|
|
||||||
return $this->handleChatLogPager($pager);
|
return $this->handleChatMessagePager($pager);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,7 +252,13 @@ class Messenger extends Service
|
|||||||
$from = $this->request->getPost('from');
|
$from = $this->request->getPost('from');
|
||||||
$to = $this->request->getPost('to');
|
$to = $this->request->getPost('to');
|
||||||
|
|
||||||
$content = [
|
$validator = new ImMessageValidator();
|
||||||
|
|
||||||
|
$validator->checkReceiver($to['id'], $to['type']);
|
||||||
|
|
||||||
|
$from['content'] = $validator->checkContent($from['content']);
|
||||||
|
|
||||||
|
$message = [
|
||||||
'username' => $from['username'],
|
'username' => $from['username'],
|
||||||
'avatar' => $from['avatar'],
|
'avatar' => $from['avatar'],
|
||||||
'content' => $from['content'],
|
'content' => $from['content'],
|
||||||
@ -237,9 +273,9 @@ class Messenger extends Service
|
|||||||
$content['id'] = $to['id'];
|
$content['id'] = $to['id'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$message = json_encode([
|
$content = json_encode([
|
||||||
'type' => 'show_chat_msg',
|
'type' => 'show_chat_msg',
|
||||||
'content' => $content,
|
'message' => $message,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Gateway::$registerAddress = '127.0.0.1:1238';
|
Gateway::$registerAddress = '127.0.0.1:1238';
|
||||||
@ -250,11 +286,33 @@ class Messenger extends Service
|
|||||||
* 不推送自己给自己发送的消息
|
* 不推送自己给自己发送的消息
|
||||||
*/
|
*/
|
||||||
if ($user->id != $to['id']) {
|
if ($user->id != $to['id']) {
|
||||||
Gateway::sendToUid($to['id'], $message);
|
|
||||||
|
$online = Gateway::isUidOnline($to['id']);
|
||||||
|
|
||||||
|
$messageModel = new ImFriendMessageModel();
|
||||||
|
|
||||||
|
$messageModel->sender_id = $from['id'];
|
||||||
|
$messageModel->receiver_id = $to['id'];
|
||||||
|
$messageModel->content = $from['content'];
|
||||||
|
$messageModel->viewed = $online ? 1 : 0;
|
||||||
|
|
||||||
|
$messageModel->create();
|
||||||
|
|
||||||
|
if ($online) {
|
||||||
|
Gateway::sendToUid($to['id'], $content);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} elseif ($to['type'] == 'group') {
|
} elseif ($to['type'] == 'group') {
|
||||||
|
|
||||||
|
$messageModel = new ImGroupMessageModel();
|
||||||
|
|
||||||
|
$messageModel->sender_id = $from['id'];
|
||||||
|
$messageModel->group_id = $to['id'];
|
||||||
|
$messageModel->content = $from['content'];
|
||||||
|
|
||||||
|
$messageModel->create();
|
||||||
|
|
||||||
$excludeClientId = null;
|
$excludeClientId = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -266,7 +324,23 @@ class Messenger extends Service
|
|||||||
|
|
||||||
$groupName = $this->getGroupName($to['id']);
|
$groupName = $this->getGroupName($to['id']);
|
||||||
|
|
||||||
Gateway::sendToGroup($groupName, $message, $excludeClientId);
|
Gateway::sendToGroup($groupName, $content, $excludeClientId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function markSystemMessagesAsRead()
|
||||||
|
{
|
||||||
|
$user = $this->getLoginUser();
|
||||||
|
|
||||||
|
$userRepo = new UserRepo();
|
||||||
|
|
||||||
|
$messages = $userRepo->findUnreadImSystemMessages($user->id);
|
||||||
|
|
||||||
|
if ($messages->count() > 0) {
|
||||||
|
foreach ($messages as $message) {
|
||||||
|
$message->viewed = 1;
|
||||||
|
$message->update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -458,7 +532,7 @@ class Messenger extends Service
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function handleChatLogPager($pager)
|
protected function handleChatMessagePager($pager)
|
||||||
{
|
{
|
||||||
if ($pager->total_items == 0) {
|
if ($pager->total_items == 0) {
|
||||||
return $pager;
|
return $pager;
|
||||||
@ -468,20 +542,17 @@ class Messenger extends Service
|
|||||||
|
|
||||||
$builder = new ImMessageListBuilder();
|
$builder = new ImMessageListBuilder();
|
||||||
|
|
||||||
$users = $builder->getUsers($messages);
|
$senders = $builder->getSenders($messages);
|
||||||
|
|
||||||
$items = [];
|
$items = [];
|
||||||
|
|
||||||
foreach ($messages as $message) {
|
foreach ($messages as $message) {
|
||||||
|
$sender = $senders[$message['sender_id']] ?? new \stdClass();
|
||||||
$user = $user = $users[$message['user_id']] ?? new \stdClass();
|
|
||||||
|
|
||||||
$items[] = [
|
$items[] = [
|
||||||
'id' => $message['id'],
|
'id' => $message['id'],
|
||||||
'content' => $message['content'],
|
'content' => $message['content'],
|
||||||
'create_time' => $message['create_time'],
|
|
||||||
'timestamp' => $message['create_time'] * 1000,
|
'timestamp' => $message['create_time'] * 1000,
|
||||||
'user' => $user,
|
'user' => $sender,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -550,36 +621,56 @@ class Messenger extends Service
|
|||||||
return $pager;
|
return $pager;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function handleApplyFriendNotice(UserModel $user, UserModel $friend, $remark)
|
protected function handleApplyFriendNotice(UserModel $sender, UserModel $receiver, $remark)
|
||||||
{
|
{
|
||||||
|
$userRepo = new UserRepo();
|
||||||
|
|
||||||
|
$itemType = ImSystemMessageModel::TYPE_FRIEND_REQUEST;
|
||||||
|
|
||||||
|
$message = $userRepo->findImSystemMessage($receiver->id, $itemType);
|
||||||
|
|
||||||
|
if ($message) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求未过期
|
||||||
|
*/
|
||||||
|
if (time() - $message->create_time < 3 * 86400) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($message->item_type['accepted'] == 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$senderInfo = [
|
||||||
|
'id' => $sender->id,
|
||||||
|
'name' => $sender->name,
|
||||||
|
'avatar' => $sender->avatar,
|
||||||
|
];
|
||||||
|
|
||||||
$sysMsgModel = new ImSystemMessageModel();
|
$sysMsgModel = new ImSystemMessageModel();
|
||||||
|
|
||||||
$sysMsgModel->user_id = $friend->id;
|
$sysMsgModel->sender_id = $sender->id;
|
||||||
$sysMsgModel->item_id = $user->id;
|
$sysMsgModel->receiver_id = $receiver->id;
|
||||||
$sysMsgModel->item_type = ImSystemMessageModel::TYPE_APPLY_FRIEND;
|
$sysMsgModel->item_type = ImSystemMessageModel::TYPE_FRIEND_REQUEST;
|
||||||
$sysMsgModel->item_info = [
|
$sysMsgModel->item_info = [
|
||||||
'user' => ['id' => $user->id, 'name' => $user->name, 'avatar' => $user->avatar],
|
'sender' => $senderInfo,
|
||||||
'remark' => $remark,
|
'remark' => $remark,
|
||||||
|
'accepted' => 0,
|
||||||
];
|
];
|
||||||
|
|
||||||
$sysMsgModel->create();
|
$sysMsgModel->create();
|
||||||
|
|
||||||
Gateway::$registerAddress = '127.0.0.1:1238';
|
Gateway::$registerAddress = '127.0.0.1:1238';
|
||||||
|
|
||||||
$online = Gateway::isUidOnline($friend->id);
|
$online = Gateway::isUidOnline($receiver->id);
|
||||||
|
|
||||||
if ($online) {
|
if ($online) {
|
||||||
|
|
||||||
$userRepo = new UserRepo();
|
$content = kg_json_encode(['type' => 'show_msg_box']);
|
||||||
|
|
||||||
$msgCount = $userRepo->countUnreadImSystemMessages($friend->id);
|
Gateway::sendToUid($receiver->id, $content);
|
||||||
|
|
||||||
$message = kg_json_encode([
|
|
||||||
'type' => 'show_msg_box',
|
|
||||||
'content' => ['msg_count' => $msgCount],
|
|
||||||
]);
|
|
||||||
|
|
||||||
Gateway::sendToUid($friend->id, $message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
body .layim-chat-main {
|
body .layim-chat-main {
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#LAY_page {
|
#LAY_page {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@ -22,7 +21,7 @@
|
|||||||
<ul id="LAY_view"></ul>
|
<ul id="LAY_view"></ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="LAY_page"></div>
|
<div id="LAY_page" data-count="{{ pager.total_items }}"></div>
|
||||||
|
|
||||||
<textarea title="消息模版" id="LAY_tpl" style="display:none;">
|
<textarea title="消息模版" id="LAY_tpl" style="display:none;">
|
||||||
<%# layui.each(d.data, function(index, item) {
|
<%# layui.each(d.data, function(index, item) {
|
||||||
@ -37,7 +36,7 @@
|
|||||||
<script src="/static/lib/layui/layui.js"></script>
|
<script src="/static/lib/layui/layui.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
layui.use(['layim', 'laypage'], function () {
|
layui.use(['jquery', 'layim', 'laytpl', 'laypage'], function () {
|
||||||
|
|
||||||
var $ = layui.jquery;
|
var $ = layui.jquery;
|
||||||
var layim = layui.layim;
|
var layim = layui.layim;
|
||||||
@ -49,38 +48,50 @@
|
|||||||
close: '%>'
|
close: '%>'
|
||||||
});
|
});
|
||||||
|
|
||||||
var chatHistoryUrl = '/im/chat/history';
|
var $target = $('#LAY_view');
|
||||||
|
var $page = $('#LAY_page');
|
||||||
|
var $tpl = $('#LAY_tpl');
|
||||||
|
|
||||||
var currentUrl = layui.url();
|
var count = $page.data('count');
|
||||||
|
var limit = 15;
|
||||||
|
|
||||||
var params = {
|
var params = {
|
||||||
id: currentUrl.search.id,
|
id: layui.url().search.id,
|
||||||
type: currentUrl.search.type,
|
type: layui.url().search.type,
|
||||||
page: 1,
|
limit: limit,
|
||||||
limit: 15,
|
sort: 'oldest',
|
||||||
sort: 'oldest'
|
page: 1
|
||||||
};
|
};
|
||||||
|
|
||||||
loadChatHistoryHtml(params);
|
/**
|
||||||
|
* 加载第一页数据
|
||||||
|
*/
|
||||||
|
loadPageHtml($target, params);
|
||||||
|
|
||||||
laypage.render({
|
/**
|
||||||
elem: 'LAY_page',
|
* 两页以上才显示分页
|
||||||
limit: 30,
|
*/
|
||||||
count: {{ pager.total_items }},
|
if (count > limit) {
|
||||||
jump: function (obj, first) {
|
laypage.render({
|
||||||
if (!first) {
|
elem: $page.attr('id'),
|
||||||
params.page = obj.curr;
|
limit: limit,
|
||||||
loadChatHistoryHtml(params);
|
count: count,
|
||||||
|
layout: ['page', 'count'],
|
||||||
|
jump: function (obj, first) {
|
||||||
|
if (!first) {
|
||||||
|
params.page = obj.curr;
|
||||||
|
loadPageHtml($target, params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
function loadChatHistoryHtml(params) {
|
function loadPageHtml(target, params) {
|
||||||
$.get(chatHistoryUrl, params, function (res) {
|
$.get('/im/chat/history', params, function (res) {
|
||||||
var html = laytpl(LAY_tpl.value).render({
|
var html = laytpl($tpl.val()).render({
|
||||||
data: res.items
|
data: res.items
|
||||||
});
|
});
|
||||||
$('#LAY_view').html(html);
|
target.html(html);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
15
app/Http/Web/Views/messenger/msg_box.volt
Normal file
15
app/Http/Web/Views/messenger/msg_box.volt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{% extends 'templates/layer.volt' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div id="LAY_view"></div>
|
||||||
|
|
||||||
|
<div id="LAY_page" class="pager" data-count="{{ pager.total_items }}"></div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block include_js %}
|
||||||
|
|
||||||
|
{{ js_include('web/js/im.msgbox.js') }}
|
||||||
|
|
||||||
|
{% endblock %}
|
20
app/Http/Web/Views/messenger/sys_messages.volt
Normal file
20
app/Http/Web/Views/messenger/sys_messages.volt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{% if pager.total_pages > 0 %}
|
||||||
|
<div class="im-user-list clearfix">
|
||||||
|
<div class="layui-row layui-col-space20">
|
||||||
|
{% for item in pager.items %}
|
||||||
|
<div class="layui-col-md2">
|
||||||
|
<div class="user-card" title="{{ item.about|e }}">
|
||||||
|
<div class="avatar">
|
||||||
|
<a href="javascript:"><img src="{{ item.avatar }}" alt="{{ item.name }}"></a>
|
||||||
|
</div>
|
||||||
|
<div class="name layui-elip" title="{{ item.name|e }}">{{ item.name }}</div>
|
||||||
|
<div class="action">
|
||||||
|
<a href="javascript:" class="layui-badge-rim apply-group" data-id="{{ item.id }}">加入群组</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ partial('partials/pager_ajax') }}
|
||||||
|
{% endif %}
|
@ -26,14 +26,14 @@ class ImFriendMessage extends Model
|
|||||||
*
|
*
|
||||||
* @var integer
|
* @var integer
|
||||||
*/
|
*/
|
||||||
public $user_id;
|
public $sender_id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接收方编号
|
* 接收方编号
|
||||||
*
|
*
|
||||||
* @var integer
|
* @var integer
|
||||||
*/
|
*/
|
||||||
public $target_id;
|
public $receiver_id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 内容
|
* 内容
|
||||||
@ -90,6 +90,8 @@ class ImFriendMessage extends Model
|
|||||||
public function beforeCreate()
|
public function beforeCreate()
|
||||||
{
|
{
|
||||||
$this->create_time = time();
|
$this->create_time = time();
|
||||||
|
|
||||||
|
$this->chat_id = self::getChatId($this->sender_id, $this->receiver_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function beforeUpdate()
|
public function beforeUpdate()
|
||||||
|
@ -22,11 +22,11 @@ class ImGroupMessage extends Model
|
|||||||
public $group_id;
|
public $group_id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户编号
|
* 发送方编号
|
||||||
*
|
*
|
||||||
* @var integer
|
* @var integer
|
||||||
*/
|
*/
|
||||||
public $user_id;
|
public $sender_id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 内容
|
* 内容
|
||||||
|
@ -7,8 +7,8 @@ use Phalcon\Mvc\Model\Behavior\SoftDelete;
|
|||||||
class ImSystemMessage extends Model
|
class ImSystemMessage extends Model
|
||||||
{
|
{
|
||||||
|
|
||||||
const TYPE_APPLY_FRIEND = 1;
|
const TYPE_FRIEND_REQUEST = 1;
|
||||||
const TYPE_APPLY_GROUP = 2;
|
const TYPE_GROUP_REQUEST = 2;
|
||||||
const TYPE_FRIEND_ACCEPTED = 3;
|
const TYPE_FRIEND_ACCEPTED = 3;
|
||||||
const TYPE_FRIEND_REFUSED = 4;
|
const TYPE_FRIEND_REFUSED = 4;
|
||||||
const TYPE_GROUP_ACCEPTED = 5;
|
const TYPE_GROUP_ACCEPTED = 5;
|
||||||
|
@ -23,8 +23,12 @@ class ImFriendMessage extends Repository
|
|||||||
$builder->andWhere('chat_id = :chat_id:', ['chat_id' => $where['chat_id']]);
|
$builder->andWhere('chat_id = :chat_id:', ['chat_id' => $where['chat_id']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($where['user_id'])) {
|
if (!empty($where['sender_id'])) {
|
||||||
$builder->andWhere('user_id = :user_id:', ['user_id' => $where['user_id']]);
|
$builder->andWhere('sender_id = :sender_id:', ['sender_id' => $where['sender_id']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($where['receiver_id'])) {
|
||||||
|
$builder->andWhere('receiver_id = :receiver_id:', ['receiver_id' => $where['receiver_id']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($where['deleted'])) {
|
if (isset($where['deleted'])) {
|
||||||
|
@ -23,8 +23,8 @@ class ImGroupMessage extends Repository
|
|||||||
$builder->andWhere('group_id = :group_id:', ['group_id' => $where['group_id']]);
|
$builder->andWhere('group_id = :group_id:', ['group_id' => $where['group_id']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($where['user_id'])) {
|
if (!empty($where['sender_id'])) {
|
||||||
$builder->andWhere('user_id = :user_id:', ['user_id' => $where['user_id']]);
|
$builder->andWhere('sender_id = :sender_id:', ['sender_id' => $where['sender_id']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($where['deleted'])) {
|
if (isset($where['deleted'])) {
|
||||||
|
80
app/Repos/ImSystemMessage.php
Normal file
80
app/Repos/ImSystemMessage.php
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Repos;
|
||||||
|
|
||||||
|
use App\Library\Paginator\Adapter\QueryBuilder as PagerQueryBuilder;
|
||||||
|
use App\Models\ImSystemMessage as ImSystemMessageModel;
|
||||||
|
use Phalcon\Mvc\Model;
|
||||||
|
use Phalcon\Mvc\Model\Resultset;
|
||||||
|
use Phalcon\Mvc\Model\ResultsetInterface;
|
||||||
|
|
||||||
|
class ImSystemMessage extends Repository
|
||||||
|
{
|
||||||
|
|
||||||
|
public function paginate($where = [], $sort = 'latest', $page = 1, $limit = 15)
|
||||||
|
{
|
||||||
|
$builder = $this->modelsManager->createBuilder();
|
||||||
|
|
||||||
|
$builder->from(ImSystemMessageModel::class);
|
||||||
|
|
||||||
|
$builder->where('1 = 1');
|
||||||
|
|
||||||
|
if (!empty($where['sender_id'])) {
|
||||||
|
$builder->andWhere('sender_id = :sender_id:', ['sender_id' => $where['sender_id']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($where['receiver_id'])) {
|
||||||
|
$builder->andWhere('receiver_id = :receiver_id:', ['receiver_id' => $where['receiver_id']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($where['deleted'])) {
|
||||||
|
$builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($sort) {
|
||||||
|
case 'oldest':
|
||||||
|
$orderBy = 'id ASC';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$orderBy = 'id DESC';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$builder->orderBy($orderBy);
|
||||||
|
|
||||||
|
$pager = new PagerQueryBuilder([
|
||||||
|
'builder' => $builder,
|
||||||
|
'page' => $page,
|
||||||
|
'limit' => $limit,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $pager->paginate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $id
|
||||||
|
* @return ImSystemMessageModel|Model|bool
|
||||||
|
*/
|
||||||
|
public function findById($id)
|
||||||
|
{
|
||||||
|
return ImSystemMessageModel::findFirst($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $ids
|
||||||
|
* @param string|array $columns
|
||||||
|
* @return ResultsetInterface|Resultset|ImSystemMessageModel[]
|
||||||
|
*/
|
||||||
|
public function findByIds($ids, $columns = '*')
|
||||||
|
{
|
||||||
|
return ImSystemMessageModel::query()
|
||||||
|
->columns($columns)
|
||||||
|
->inWhere('id', $ids)
|
||||||
|
->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findUserMessage($userId, $itemType)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -157,10 +157,36 @@ class User extends Repository
|
|||||||
->getQuery()->execute();
|
->getQuery()->execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $userId
|
||||||
|
* @param int $itemType
|
||||||
|
* @return Model|bool|ImSystemMessageModel
|
||||||
|
*/
|
||||||
|
public function findImSystemMessage($userId, $itemType)
|
||||||
|
{
|
||||||
|
return ImSystemMessageModel::findFirst([
|
||||||
|
'conditions' => 'receiver_id = ?1 AND item_type = ?2',
|
||||||
|
'bind' => [1 => $userId, 2 => $itemType],
|
||||||
|
'order' => 'id DESC',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $userId
|
||||||
|
* @return ResultsetInterface|Resultset|ImSystemMessageModel[]
|
||||||
|
*/
|
||||||
|
public function findUnreadImSystemMessages($userId)
|
||||||
|
{
|
||||||
|
return ImSystemMessageModel::find([
|
||||||
|
'conditions' => 'receiver_id = ?1 AND viewed = ?2',
|
||||||
|
'bind' => [1 => $userId, 2 => 0],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
public function countUnreadImSystemMessages($userId)
|
public function countUnreadImSystemMessages($userId)
|
||||||
{
|
{
|
||||||
return ImSystemMessageModel::count([
|
return ImSystemMessageModel::count([
|
||||||
'conditions' => 'user_id = ?1 AND viewed = ?2',
|
'conditions' => 'receiver_id = ?1 AND viewed = ?2',
|
||||||
'bind' => [1 => $userId, 2 => 0],
|
'bind' => [1 => $userId, 2 => 0],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace App\Validators;
|
namespace App\Validators;
|
||||||
|
|
||||||
|
use App\Caches\ImChatGroup as ImChatGroupCache;
|
||||||
|
use App\Caches\User as UserCache;
|
||||||
use App\Exceptions\BadRequest as BadRequestException;
|
use App\Exceptions\BadRequest as BadRequestException;
|
||||||
use App\Repos\ImFriendMessage as ImFriendMessageRepo;
|
use App\Repos\ImFriendMessage as ImFriendMessageRepo;
|
||||||
use App\Repos\ImGroupMessage as ImGroupMessageRepo;
|
use App\Repos\ImGroupMessage as ImGroupMessageRepo;
|
||||||
@ -9,11 +11,19 @@ use App\Repos\ImGroupMessage as ImGroupMessageRepo;
|
|||||||
class ImMessage extends Validator
|
class ImMessage extends Validator
|
||||||
{
|
{
|
||||||
|
|
||||||
public function checkFriendMessage($id)
|
public function checkMessage($id, $type)
|
||||||
{
|
{
|
||||||
$messageRepo = new ImFriendMessageRepo();
|
$this->checkType($type);
|
||||||
|
|
||||||
$message = $messageRepo->findById($id);
|
$message = null;
|
||||||
|
|
||||||
|
if ($type == 'friend') {
|
||||||
|
$repo = new ImFriendMessageRepo();
|
||||||
|
$message = $repo->findById($id);
|
||||||
|
} elseif ($type == 'group') {
|
||||||
|
$repo = new ImGroupMessageRepo();
|
||||||
|
$message = $repo->findById($id);
|
||||||
|
}
|
||||||
|
|
||||||
if (!$message) {
|
if (!$message) {
|
||||||
throw new BadRequestException('im_message.not_found');
|
throw new BadRequestException('im_message.not_found');
|
||||||
@ -22,17 +32,27 @@ class ImMessage extends Validator
|
|||||||
return $message;
|
return $message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function checkGroupMessage($id)
|
public function checkReceiver($id, $type)
|
||||||
{
|
{
|
||||||
$messageRepo = new ImGroupMessageRepo();
|
$this->checkType($type);
|
||||||
|
|
||||||
$message = $messageRepo->findById($id);
|
$receiver = null;
|
||||||
|
|
||||||
if (!$message) {
|
if ($type == 'friend') {
|
||||||
throw new BadRequestException('im_message.not_found');
|
$cache = new UserCache();
|
||||||
|
$receiver = $cache->get($id);
|
||||||
|
if (!$receiver) {
|
||||||
|
throw new BadRequestException('user.not_found');
|
||||||
|
}
|
||||||
|
} elseif ($type == 'group') {
|
||||||
|
$cache = new ImChatGroupCache();
|
||||||
|
$receiver = $cache->get($id);
|
||||||
|
if (!$receiver) {
|
||||||
|
throw new BadRequestException('im_chat_group.not_found');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $message;
|
return $receiver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function checkType($type)
|
public function checkType($type)
|
||||||
|
@ -1312,3 +1312,65 @@
|
|||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.layim-msgbox {
|
||||||
|
margin: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layim-msgbox li {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 0 130px 10px 60px;
|
||||||
|
line-height: 22px;
|
||||||
|
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 {
|
||||||
|
padding: 0 10px 10px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layim-msgbox li p span {
|
||||||
|
padding-left: 5px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layim-msgbox li p em {
|
||||||
|
font-style: normal;
|
||||||
|
color: #FF5722;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layim-msgbox-avatar {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layim-msgbox-user {
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layim-msgbox-content {
|
||||||
|
margin-top: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layim-msgbox .layui-btn-small {
|
||||||
|
padding: 0 15px;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layim-msgbox-btn {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 12px;
|
||||||
|
color: #999;
|
||||||
|
}
|
@ -23,15 +23,16 @@ layui.use(['jquery', 'layim'], function () {
|
|||||||
socket.send('pong...');
|
socket.send('pong...');
|
||||||
} else if (data.type === 'bind_user') {
|
} else if (data.type === 'bind_user') {
|
||||||
bindUser(data.client_id);
|
bindUser(data.client_id);
|
||||||
|
refreshMessageBox();
|
||||||
} else if (data.type === 'show_chat_msg') {
|
} else if (data.type === 'show_chat_msg') {
|
||||||
showChatMessage(data.content);
|
showChatMessage(data.message);
|
||||||
} else if (data.type === 'show_msg_box') {
|
} else if (data.type === 'show_msg_box') {
|
||||||
showMessageBox(data.content);
|
refreshMessageBox();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
layim.config({
|
layim.config({
|
||||||
title: '即时聊天',
|
title: '菜鸟驿站',
|
||||||
init: {
|
init: {
|
||||||
url: '/im/init'
|
url: '/im/init'
|
||||||
},
|
},
|
||||||
@ -78,12 +79,20 @@ layui.use(['jquery', 'layim'], function () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function showChatMessage(content) {
|
function showChatMessage(message) {
|
||||||
layim.getMessage(content);
|
layim.getMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
function showMessageBox(content) {
|
function refreshMessageBox() {
|
||||||
layim.msgbox(content.msg_count);
|
$.ajax({
|
||||||
|
type: 'GET',
|
||||||
|
url: '/im/msg/unread/count',
|
||||||
|
success: function (res) {
|
||||||
|
if (res.count > 0) {
|
||||||
|
layim.msgbox(res.count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
132
public/static/web/js/im.msgbox.js
Normal file
132
public/static/web/js/im.msgbox.js
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
layui.use(['jquery', 'layer', 'layim', 'laypage'], function () {
|
||||||
|
|
||||||
|
var $ = layui.jquery;
|
||||||
|
var layer = layui.layer;
|
||||||
|
var layim = layui.layim;
|
||||||
|
var laypage = layui.laypage;
|
||||||
|
|
||||||
|
var $target = $('#LAY_view');
|
||||||
|
var $page = $('#LAY_page');
|
||||||
|
var count = $page.data('count');
|
||||||
|
var limit = 15;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标记信息为已读
|
||||||
|
*/
|
||||||
|
markMessageAsRead();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载第一页数据
|
||||||
|
*/
|
||||||
|
loadPageHtml($target, 1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 两页以上才显示分页
|
||||||
|
*/
|
||||||
|
if (count > limit) {
|
||||||
|
laypage.render({
|
||||||
|
elem: $page.attr('id'),
|
||||||
|
limit: limit,
|
||||||
|
count: count,
|
||||||
|
jump: function (obj, first) {
|
||||||
|
if (!first) {
|
||||||
|
loadPageHtml($target, obj.curr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadPageHtml(target, page) {
|
||||||
|
$.get('/im/msg/sys', {page: page}, function (html) {
|
||||||
|
target.html(html);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function markMessageAsRead() {
|
||||||
|
$.post('/im/msg/read');
|
||||||
|
}
|
||||||
|
|
||||||
|
//操作
|
||||||
|
var active = {
|
||||||
|
//同意
|
||||||
|
agree: function (othis) {
|
||||||
|
var li = othis.parents('li')
|
||||||
|
, uid = li.data('uid')
|
||||||
|
, from_group = li.data('fromGroup')
|
||||||
|
, user = cache[uid];
|
||||||
|
|
||||||
|
//选择分组
|
||||||
|
parent.layui.layim.setFriendGroup({
|
||||||
|
type: 'friend'
|
||||||
|
, username: user.username
|
||||||
|
, avatar: user.avatar
|
||||||
|
, group: parent.layui.layim.cache().friend //获取好友分组数据
|
||||||
|
, submit: function (group, index) {
|
||||||
|
|
||||||
|
//将好友追加到主面板
|
||||||
|
parent.layui.layim.addList({
|
||||||
|
type: 'friend'
|
||||||
|
, avatar: user.avatar //好友头像
|
||||||
|
, username: user.username //好友昵称
|
||||||
|
, groupid: group //所在的分组id
|
||||||
|
, id: uid //好友ID
|
||||||
|
, sign: user.sign //好友签名
|
||||||
|
});
|
||||||
|
parent.layer.close(index);
|
||||||
|
othis.parent().html('已同意');
|
||||||
|
|
||||||
|
|
||||||
|
//实际部署时,请开启下述注释,并改成你的接口地址
|
||||||
|
/*
|
||||||
|
$.post('/im/agreeFriend', {
|
||||||
|
uid: uid //对方用户ID
|
||||||
|
,from_group: from_group //对方设定的好友分组
|
||||||
|
,group: group //我设定的好友分组
|
||||||
|
}, function(res){
|
||||||
|
if(res.code != 0){
|
||||||
|
return layer.msg(res.msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//将好友追加到主面板
|
||||||
|
parent.layui.layim.addList({
|
||||||
|
type: 'friend'
|
||||||
|
,avatar: user.avatar //好友头像
|
||||||
|
,username: user.username //好友昵称
|
||||||
|
,groupid: group //所在的分组id
|
||||||
|
,id: uid //好友ID
|
||||||
|
,sign: user.sign //好友签名
|
||||||
|
});
|
||||||
|
parent.layer.close(index);
|
||||||
|
othis.parent().html('已同意');
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//拒绝
|
||||||
|
, refuse: function (othis) {
|
||||||
|
var li = othis.parents('li')
|
||||||
|
, uid = li.data('uid');
|
||||||
|
|
||||||
|
layer.confirm('确定拒绝吗?', function (index) {
|
||||||
|
$.post('/im/refuseFriend', {
|
||||||
|
uid: uid //对方用户ID
|
||||||
|
}, function (res) {
|
||||||
|
if (res.code != 0) {
|
||||||
|
return layer.msg(res.msg);
|
||||||
|
}
|
||||||
|
layer.close(index);
|
||||||
|
othis.parent().html('<em>已拒绝</em>');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$('body').on('click', '.layui-btn', function () {
|
||||||
|
var othis = $(this), type = othis.data('type');
|
||||||
|
active[type] ? active[type].call(this, othis) : '';
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user