1
0
mirror of https://gitee.com/koogua/course-tencent-cloud.git synced 2025-07-19 22:52:59 +08:00

好友申请

This commit is contained in:
xiaochong0302 2020-06-22 20:02:55 +08:00
parent fceffa655f
commit 148d2fdc4d
31 changed files with 761 additions and 158 deletions

View File

@ -0,0 +1,70 @@
<?php
namespace App\Caches;
use App\Models\ImChatGroup as ImChatGroupModel;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
class ImHotGroupList extends Cache
{
protected $lifetime = 1 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'im_hot_group_list';
}
public function getContent($id = null)
{
$limit = 12;
$groups = $this->findHotGroups($limit);
if ($groups->count() == 0) {
return [];
}
return $this->handleContent($groups);
}
/**
* @param ImChatGroupModel[] $groups
* @return array
*/
protected function handleContent($groups)
{
$result = [];
foreach ($groups as $group) {
$result[] = [
'id' => $group->id,
'name' => $group->name,
'avatar' => $group->avatar,
'about' => $group->about,
];
}
return $result;
}
/**
* @param int $limit
* @return ResultsetInterface|Resultset|ImChatGroupModel[]
*/
public function findHotGroups($limit = 12)
{
return ImChatGroupModel::query()
->where('deleted = 0')
->orderBy('user_count DESC')
->limit($limit)
->execute();
}
}

View File

@ -0,0 +1,73 @@
<?php
namespace App\Caches;
use App\Models\User as UserModel;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
class ImHotUserList extends Cache
{
protected $lifetime = 1 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'im_hot_user_list';
}
public function getContent($id = null)
{
$limit = 12;
$users = $this->findHotUsers($limit);
if ($users->count() == 0) {
return [];
}
return $this->handleContent($users);
}
/**
* @param UserModel[] $users
* @return array
*/
protected function handleContent($users)
{
$result = [];
foreach ($users as $user) {
$result[] = [
'id' => $user->id,
'name' => $user->name,
'avatar' => $user->avatar,
'about' => $user->about,
'sign' => $user->sign,
'location' => $user->location,
'vip' => $user->vip,
];
}
return $result;
}
/**
* @param int $limit
* @return ResultsetInterface|Resultset|UserModel[]
*/
public function findHotUsers($limit = 12)
{
return UserModel::query()
->where('deleted = 0')
->orderBy('follower_count DESC')
->limit($limit)
->execute();
}
}

View File

@ -15,7 +15,7 @@ class MessengerController extends LayerController
use ResponseTrait;
/**
* @Get("/init", name="im.init")
* @Get("/init", name="web.im.init")
*/
public function initAction()
{
@ -27,7 +27,7 @@ class MessengerController extends LayerController
}
/**
* @Get("/group/members", name="im.group_members")
* @Get("/group/members", name="web.im.group_members")
*/
public function groupMembersAction()
{
@ -39,7 +39,7 @@ class MessengerController extends LayerController
}
/**
* @Get("/msg/box", name="im.msg_box")
* @Get("/msg/box", name="web.im.msg_box")
*/
public function messageBoxAction()
{
@ -47,7 +47,7 @@ class MessengerController extends LayerController
}
/**
* @Get("/chat/log", name="im.chat_log")
* @Get("/chat/log", name="web.im.chat_log")
*/
public function chatLogAction()
{
@ -61,7 +61,7 @@ class MessengerController extends LayerController
}
/**
* @Get("/chat/history", name="im.chat_history")
* @Get("/chat/history", name="web.im.chat_history")
*/
public function chatHistoryAction()
{
@ -73,15 +73,47 @@ class MessengerController extends LayerController
}
/**
* @Get("/find", name="im.find")
* @Get("/find", name="web.im.find")
*/
public function findAction()
{
$service = new MessengerService();
$usersPager = $service->getHotUsers();
$groupsPager = $service->getHotGroups();
$usersPager->items = kg_array_object($usersPager->items);
$groupsPager->items = kg_array_object($groupsPager->items);
$this->view->setVar('users_pager', $usersPager);
$this->view->setVar('groups_pager', $groupsPager);
}
/**
* @Post("/user/bind", name="im.bind_user")
* @Get("/search", name="web.im.search")
*/
public function searchAction()
{
$query = $this->request->getQuery('query', ['trim', 'string']);
$type = $this->request->getQuery('type', ['trim', 'string']);
$service = new MessengerService();
if ($type == 'user') {
$pager = $service->searchUsers($query);
$this->view->pick('messenger/find_users');
} else {
$pager = $service->searchGroups($query);
$this->view->pick('messenger/find_groups');
}
$pager->items = kg_array_object($pager->items);
$this->view->setVar('pager', $pager);
}
/**
* @Post("/user/bind", name="web.im.bind_user")
*/
public function bindUserAction()
{
@ -93,7 +125,7 @@ class MessengerController extends LayerController
}
/**
* @Post("/msg/send", name="im.send_msg")
* @Post("/msg/send", name="web.im.send_msg")
*/
public function sendMessageAction()
{
@ -105,14 +137,14 @@ class MessengerController extends LayerController
}
/**
* @Post("/img/upload", name="im.upload_img")
* @Post("/img/upload", name="web.im.upload_img")
*/
public function uploadImageAction()
{
}
/**
* @Post("/file/upload", name="im.upload_file")
* @Post("/file/upload", name="web.im.upload_file")
*/
public function uploadFileAction()
{
@ -120,7 +152,7 @@ class MessengerController extends LayerController
}
/**
* @Post("/stats/update", name="im.update_stats")
* @Post("/stats/update", name="web.im.update_stats")
*/
public function updateStatsAction()
{
@ -128,30 +160,47 @@ class MessengerController extends LayerController
}
/**
* @Post("/sign/update", name="im.update_sign")
* @Post("/sign/update", name="web.web.im.update_sign")
*/
public function updateSignAction()
public function updateSignatureAction()
{
$service = new MessengerService();
$service->updateSignature();
return $this->jsonSuccess();
}
/**
* @Post("/friend/apply", name="im.apply_friend")
* @Post("/friend/apply", name="web.im.apply_friend")
*/
public function applyFriendAction()
{
$service = new MessengerService();
$service->applyFriend();
$content = ['msg' => '发送申请成功,请等待对方通过'];
return $this->jsonSuccess($content);
}
/**
* @Post("/group/apply", name="im.apply_group")
* @Post("/group/apply", name="web.im.apply_group")
*/
public function applyGroupAction()
{
$service = new MessengerService();
$service->applyGroup();
$content = ['msg' => '发送申请成功,请等待管理员通过'];
return $this->jsonSuccess($content);
}
/**
* @Post("/friend/approve", name="im.approve_friend")
* @Post("/friend/approve", name="web.im.approve_friend")
*/
public function approveFriendAction()
{
@ -159,7 +208,7 @@ class MessengerController extends LayerController
}
/**
* @Post("/group/approve", name="im.approve_group")
* @Post("/group/approve", name="web.web.im.approve_group")
*/
public function approveGroupAction()
{

View File

@ -2,6 +2,7 @@
namespace App\Http\Web\Controllers;
use App\Library\Security;
use App\Models\ContentImage as ContentImageModel;
use App\Services\Frontend\Chapter\Learning as LearningService;
use App\Services\Storage as StorageService;
@ -52,6 +53,16 @@ class PublicController extends \Phalcon\Mvc\Controller
exit;
}
/**
* @Post("/token/refresh", name="web.refresh_token")
*/
public function refreshTokenAction()
{
$security = new Security();
return $this->jsonSuccess();
}
/**
* @Post("/{id:[0-9]+}/learning", name="web.learning")
*/

View File

@ -3,14 +3,19 @@
namespace App\Http\Web\Services;
use App\Builders\ImMessageList as ImMessageListBuilder;
use App\Caches\ImHotGroupList as ImHotGroupListCache;
use App\Caches\ImHotUserList as ImHotUserListCache;
use App\Library\Paginator\Query as PagerQuery;
use App\Models\ImFriendMessage as ImFriendMessageModel;
use App\Models\ImFriendUser as ImFriendUserModel;
use App\Repos\ImChatGroup as ImChatGroupRepo;
use App\Repos\ImFriendMessage as ImFriendMessageRepo;
use App\Repos\ImFriendUser as ImFriendUserRepo;
use App\Repos\ImGroupMessage as ImGroupMessageRepo;
use App\Repos\User as UserRepo;
use App\Validators\ImChatGroup as ImChatGroupValidator;
use App\Validators\ImMessage as ImMessageValidator;
use App\Validators\User as UserValidator;
use GatewayClient\Gateway;
class Messenger extends Service
@ -39,6 +44,46 @@ class Messenger extends Service
];
}
public function searchUsers($query)
{
}
public function searchGroups($query)
{
}
public function getHotUsers()
{
$cache = new ImHotUserListCache();
$items = $cache->get();
$pager = new \stdClass();
$pager->total_items = count($items);
$pager->total_pages = 1;
$pager->items = $items;
return $pager;
}
public function getHotGroups()
{
$cache = new ImHotGroupListCache();
$items = $cache->get();
$pager = new \stdClass();
$pager->total_items = count($items);
$pager->total_pages = 1;
$pager->items = $items;
return $pager;
}
public function getGroupUsers()
{
$id = $this->request->getQuery('id');
@ -194,12 +239,106 @@ class Messenger extends Service
}
}
public function updateSignature()
{
$sign = $this->request->getPost('sign');
$user = $this->getLoginUser();
$validator = new UserValidator();
$validator->checkSign($sign);
$user->update(['sign' => $sign]);
return $user;
}
public function applyFriend()
{
$friendId = $this->request->getPost('friend_id');
$user = $this->getLoginUser();
$userValidator = new UserValidator();
$friend = $userValidator->checkUser($friendId);
$friendUserRepo = new ImFriendUserRepo();
$friendUser = $friendUserRepo->findFriendUser($user->id, $friend->id);
if (!$friendUser) {
$model = new ImFriendUserModel();
$model->user_id = $user->id;
$model->friend_id = $friend->id;
$model->create();
}
/**
* @todo 向对方发好友申请的系统消息
*/
}
public function approveFriend()
{
$friendId = $this->request->getPost('friend_id');
$user = $this->getLoginUser();
$userValidator = new UserValidator();
$friend = $userValidator->checkUser($friendId);
$friendUserRepo = new ImFriendUserRepo();
$friendUser = $friendUserRepo->findFriendUser($user->id, $friend->id);
if (!$friendUser) {
$model = new ImFriendUserModel();
$model->user_id = $user->id;
$model->friend_id = $friend->id;
$model->create();
}
/**
* @todo 向对方发通过好友申请的系统消息
*/
}
public function refuseFriend()
{
$friendId = $this->request->getPost('friend_id');
$user = $this->getLoginUser();
$userValidator = new UserValidator();
$friend = $userValidator->checkUser($friendId);
/**
* @todo 向对方发拒绝添加好友的系统消息
*/
}
public function applyGroup()
{
}
public function approveGroup()
{
}
public function refuseGroup()
{
}
protected function handleFriendList($userId)
{
$userRepo = new UserRepo();
$friendGroups = $userRepo->findImFriendGroups($userId);
$friends = $userRepo->findImFriends($userId);
$friendUsers = $userRepo->findImFriendUsers($userId);
$items = [];
@ -211,11 +350,11 @@ class Messenger extends Service
}
}
if ($friends->count() == 0) {
if ($friendUsers->count() == 0) {
return $items;
}
$userIds = kg_array_column($friends->toArray(), 'friend_id');
$userIds = kg_array_column($friendUsers->toArray(), 'friend_id');
$users = $userRepo->findByIds($userIds);
@ -232,9 +371,9 @@ class Messenger extends Service
}
foreach ($items as $key => $item) {
foreach ($friends as $friend) {
$userId = $friend->friend_id;
if ($item['id'] == $friend->group_id) {
foreach ($friendUsers as $friendUser) {
$userId = $friendUser->friend_id;
if ($item['id'] == $friendUser->group_id) {
$items[$key]['list'][] = $userMappings[$userId];
} else {
$items[0]['list'][] = $userMappings[$userId];

View File

@ -0,0 +1,34 @@
{% extends 'templates/layer.volt' %}
{% block content %}
<div class="im-search">
<form class="layui-form" action="{{ url({'for':'web.im.search'}) }}">
<input class="layui-input" type="text" name="query" value="{{ request.get('query')|striptags }}" placeholder="请输入关键字...">
</form>
</div>
<div class="tab-container">
<div class="layui-tab layui-tab-brief user-tab">
<ul class="layui-tab-title">
<li class="layui-this">成员</li>
<li>群组</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show" id="tab-users">
{{ partial('messenger/find_users',{'pager':users_pager}) }}
</div>
<div class="layui-tab-item" id="tab-groups">
{{ partial('messenger/find_groups',{'pager':groups_pager}) }}
</div>
</div>
</div>
</div>
{% endblock %}
{% block include_js %}
{{ js_include('web/js/im.find.js') }}
{% endblock %}

View 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 %}

View 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-friend" data-id="{{ item.id }}">加为好友</a>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{{ partial('partials/pager_ajax') }}
{% endif %}

View File

@ -1,82 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN-Hans">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="keywords" content="{{ site_seo.getKeywords() }}">
<meta name="description" content="{{ site_seo.getDescription() }}">
<meta name="csrf-token" content="{{ csrfToken.getToken() }}">
<title>{{ site_seo.getTitle() }}</title>
{{ icon_link('favicon.ico') }}
{{ css_link('lib/layui/css/layui.css') }}
{{ css_link('web/css/common.css') }}
{% block link_css %}{% endblock %}
{% block inline_css %}{% endblock %}
</head>
{% set course_url = url({'for':'web.course.show','id':chapter.course.id}) %}
<body class="chapter-bg">
<div class="chapter-main">
<div class="header clearfix">
<div class="back fl">
<span><i class="layui-icon layui-icon-return"></i> <a href="{{ course_url }}">返回课程主页</a></span>
</div>
<div class="stats fr">
<span class="user">203</span>
<span class="agree">300</span>
<span class="oppose">50</span>
</div>
<div class="action fr">
<span class="user">203</span>
<span class="agree">300</span>
<span class="oppose">50</span>
</div>
</div>
<div class="content">
{% block content %}{% endblock %}
</div>
<div class="chapter-sidebar-btn">
<i class="switch-icon layui-icon layui-icon-shrink-right"></i>
</div>
</div>
<div class="chapter-sidebar">
<div class="layui-tab layui-tab-brief">
<ul class="layui-tab-title">
<li class="layui-this">目录</li>
<li>讨论</li>
<li>资料</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show" id="tab-courses" data-url="#"></div>
<div class="layui-tab-item" id="tab-favorites" data-url="#"></div>
<div class="layui-tab-item" id="tab-friends" data-url="#"></div>
</div>
</div>
</div>
{{ js_include('lib/layui/layui.all.js') }}
{{ js_include('web/js/common.js') }}
<script>
var $ = layui.jquery;
$('.chapter-sidebar-btn').on('click', function () {
var switchIcon = $(this).children('.switch-icon');
var mainBlock = $('.chapter-main');
var sidebarBlock = $('.chapter-sidebar');
var spreadLeft = 'layui-icon-spread-left';
var shrinkRight = 'layui-icon-shrink-right';
if (switchIcon.hasClass(spreadLeft)) {
switchIcon.removeClass(spreadLeft).addClass(shrinkRight);
mainBlock.css('right', 0);
sidebarBlock.css('width', 0);
} else {
switchIcon.removeClass(shrinkRight).addClass(spreadLeft);
mainBlock.css('right', 320);
sidebarBlock.css('width', 320);
}
});
</script>
{% block include_js %}{% endblock %}
{% block inline_js %}{% endblock %}
</body>
</html>

View File

@ -13,7 +13,7 @@
{% block link_css %}{% endblock %}
{% block inline_css %}{% endblock %}
</head>
<body class="body">
<body class="full">
<div id="header">
{{ partial('partials/header') }}

View File

@ -12,8 +12,10 @@
</head>
<body class="layer">
{% block content %}{% endblock %}
{{ js_include('lib/layui/layui.js') }}
{{ js_include('web/js/common.js') }}
{% block include_js %}{% endblock %}
{% block inline_js %}{% endblock %}
</body>

View File

@ -41,17 +41,8 @@
{% endblock %}
{% block inline_js %}
{% block include_js %}
<script>
if ($('#tab-courses').length > 0) {
var $tabCourses = $('#tab-courses');
helper.ajaxLoadHtml($tabCourses.attr('data-url'), $tabCourses.attr('id'));
}
if ($('#tab-favorites').length > 0) {
var $tabFavorites = $('#tab-favorites');
helper.ajaxLoadHtml($tabFavorites.attr('data-url'), $tabFavorites.attr('id'));
}
</script>
{{ js_include('web/js/user.show.js') }}
{% endblock %}

View File

@ -31,7 +31,6 @@ class Security
$this->options['lifetime'] = $options['lifetime'] ?? 3600;
$this->cache = Di::getDefault()->get('cache');
$this->session = Di::getDefault()->get('session');
$this->generateToken();

View File

@ -14,13 +14,6 @@ class ImFriendMessage extends Model
*/
public $id;
/**
* 用户编号
*
* @var integer
*/
public $user_id;
/**
* 对话编号
*
@ -28,6 +21,20 @@ class ImFriendMessage extends Model
*/
public $chat_id;
/**
* 发送方编号
*
* @var integer
*/
public $user_id;
/**
* 接收方编号
*
* @var integer
*/
public $target_id;
/**
* 内容
*
@ -35,6 +42,13 @@ class ImFriendMessage extends Model
*/
public $content;
/**
* 阅读标识
*
* @var integer
*/
public $viewed;
/**
* 删除标识
*

View File

@ -2,7 +2,7 @@
namespace App\Models;
class ImFriend extends Model
class ImFriendUser extends Model
{
/**
@ -56,7 +56,7 @@ class ImFriend extends Model
public function getSource()
{
return 'kg_im_friend';
return 'kg_im_friend_user';
}
public function beforeCreate()

View File

@ -134,7 +134,6 @@ class User extends Model
*/
public $vip_expiry_time;
/**
* 锁定期限
*
@ -143,18 +142,18 @@ class User extends Model
public $lock_expiry_time;
/**
* 通知数量
* 关注数量
*
* @var int
*/
public $notice_count;
public $following_count;
/**
* 私信数量
* 粉丝数量
*
* @var int
*/
public $msg_count;
public $follower_count;
/**
* 创建时间

View File

@ -0,0 +1,25 @@
<?php
namespace App\Repos;
use App\Models\ImChatGroupUser as ImChatGroupUserModel;
use Phalcon\Mvc\Model;
class ImChatGroupUser extends Repository
{
/**
* @param int $userId
* @param int $groupId
* @return ImChatGroupUserModel|Model|bool
*/
public function findGroupUser($userId, $groupId)
{
return ImChatGroupUserModel::findFirst([
'conditions' => 'user_id = ?1 AND group_id = ?2',
'bind' => [1 => $userId, 2 => $groupId],
'order' => 'id DESC',
]);
}
}

View File

@ -3,8 +3,8 @@
namespace App\Repos;
use App\Library\Paginator\Adapter\QueryBuilder as PagerQueryBuilder;
use App\Models\ImFriend as ImFriendModel;
use App\Models\ImFriendGroup as ImFriendGroupModel;
use App\Models\ImFriendUser as ImFriendUserModel;
use App\Models\User as UserModel;
use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Resultset;
@ -81,7 +81,7 @@ class ImFriendGroup extends Repository
return $this->modelsManager->createBuilder()
->columns('u.*')
->addFrom(UserModel::class, 'u')
->join(ImFriendModel::class, 'u.id = f.user_id', 'f')
->join(ImFriendUserModel::class, 'u.id = f.user_id', 'f')
->where('f.group_id = :group_id:', ['group_id' => $groupId])
->andWhere('u.deleted = 0')
->getQuery()->execute();

View File

@ -0,0 +1,25 @@
<?php
namespace App\Repos;
use App\Models\ImFriendUser as ImFriendUserModel;
use Phalcon\Mvc\Model;
class ImFriendUser extends Repository
{
/**
* @param int $userId
* @param int $friendId
* @return ImFriendUserModel|Model|bool
*/
public function findFriendUser($userId, $friendId)
{
return ImFriendUserModel::findFirst([
'conditions' => 'user_id = ?1 AND friend_id = ?2',
'bind' => [1 => $userId, 2 => $friendId],
'order' => 'id DESC',
]);
}
}

View File

@ -5,8 +5,8 @@ namespace App\Repos;
use App\Library\Paginator\Adapter\QueryBuilder as PagerQueryBuilder;
use App\Models\ImChatGroup as ImChatGroupModel;
use App\Models\ImChatGroupUser as ImChatGroupUserModel;
use App\Models\ImFriend as ImFriendModel;
use App\Models\ImFriendGroup as ImFriendGroupModel;
use App\Models\ImFriendUser as ImFriendUserModel;
use App\Models\User as UserModel;
use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Resultset;
@ -117,11 +117,11 @@ class User extends Repository
/**
* @param int $userId
* @return ResultsetInterface|Resultset|ImFriendModel[]
* @return ResultsetInterface|Resultset|ImFriendUserModel[]
*/
public function findImFriends($userId)
public function findImFriendUsers($userId)
{
return ImFriendModel::query()
return ImFriendUserModel::query()
->where('user_id = :user_id:', ['user_id' => $userId])
->execute();
}

View File

@ -2,8 +2,8 @@
namespace App\Traits;
use App\Caches\User as UserCache;
use App\Models\User as UserModel;
use App\Repos\User as UserRepo;
use App\Services\Auth as AuthService;
use App\Validators\Validator as AppValidator;
use Phalcon\Di;
@ -22,9 +22,9 @@ trait Auth
return $this->getGuestUser();
}
$userCache = new UserCache();
$userRepo = new UserRepo();
return $userCache->get($authUser['id']);
return $userRepo->findById($authUser['id']);
}
/**
@ -38,9 +38,9 @@ trait Auth
$validator->checkAuthUser($authUser);
$userCache = new UserCache();
$userRepo = new UserRepo();
return $userCache->get($authUser['id']);
return $userRepo->findById($authUser['id']);
}
/**

View File

@ -65,7 +65,7 @@ class ImChatGroup extends Validator
throw new BadRequestException('im_chat_group.name_too_short');
}
if ($length > 50) {
if ($length > 30) {
throw new BadRequestException('im_chat_group.name_too_long');
}

View File

@ -0,0 +1,33 @@
<?php
namespace App\Validators;
use App\Exceptions\BadRequest as BadRequestException;
use App\Repos\ImChatGroupUser as ImChatGroupUserRepo;
class ImChatGroupUser extends Validator
{
public function checkIfJoined($userId, $groupId)
{
$repo = new ImChatGroupUserRepo();
$record = $repo->findGroupUser($userId, $groupId);
if ($record && $record->blocked == 0) {
throw new BadRequestException('im_chat_group_user.has_joined');
}
}
public function checkIfBlocked($userId, $groupId)
{
$repo = new ImChatGroupUserRepo();
$record = $repo->findGroupUser($userId, $groupId);
if ($record && $record->blocked == 1) {
throw new BadRequestException('im_chat_group_user.blocked');
}
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace App\Validators;
use App\Exceptions\BadRequest as BadRequestException;
use App\Repos\ImFriendUser as ImFriendUserRepo;
class ImFriendUser extends Validator
{
public function checkIfSelfApply($userId, $friendId)
{
if ($userId == $friendId) {
throw new BadRequestException('im_friend_user.self_apply');
}
}
public function checkIfJoined($userId, $friendId)
{
$repo = new ImFriendUserRepo();
$record = $repo->findFriendUser($userId, $friendId);
if ($record && $record->blocked == 0) {
throw new BadRequestException('im_friend_user.has_joined');
}
}
public function checkIfBlocked($userId, $friendId)
{
$repo = new ImFriendUserRepo();
$record = $repo->findFriendUser($userId, $friendId);
if ($record && $record->blocked == 1) {
throw new BadRequestException('im_friend_user.blocked');
}
}
}

View File

@ -82,7 +82,7 @@ class User extends Validator
$length = kg_strlen($value);
if ($length > 30) {
throw new BadRequestException('role.title_too_long');
throw new BadRequestException('user.title_too_long');
}
return $value;
@ -101,6 +101,19 @@ class User extends Validator
return $value;
}
public function checkSign($sign)
{
$value = $this->filter->sanitize($sign, ['trim', 'string']);
$length = kg_strlen($value);
if ($length > 50) {
throw new BadRequestException('user.sign_too_long');
}
return $value;
}
public function checkGender($value)
{
$list = UserModel::genderTypes();

View File

@ -57,6 +57,7 @@ $error['account.login_password_incorrect'] = '登录密码不正确';
$error['user.not_found'] = '用户不存在';
$error['user.name_taken'] = '用户名被占用';
$error['user.title_too_long'] = '头衔过长超过30个字符';
$error['user.sign_too_long'] = '签名过长超过50个字符';
$error['user.about_too_long'] = '简介过长超过255个字符';
$error['user.invalid_gender'] = '无效的性别类型';
$error['user.invalid_edu_role'] = '无效的教学角色';
@ -325,4 +326,29 @@ $error['learning.invalid_request_id'] = '无效的请求编号';
$error['learning.invalid_position'] = '无效的播放位置';
$error['learning.invalid_interval'] = '无效的间隔时间';
/**
* 即时通讯
*/
$error['im_friend_group.not_found'] = '分组不存在';
$error['im_friend_group.name_too_short'] = '分组名太短少于2字符';
$error['im_friend_group.name_too_long'] = '分组名太长超过15字符';
$error['im_chat_group.not_found'] = '群组不存在';
$error['im_chat_group.name_too_short'] = '群组名太短少于2字符';
$error['im_chat_group.name_too_long'] = '群组名太长超过30字符';
$error['im_chat_group.about_too_long'] = '群组简介太长超过255字符';
$error['im_chat_group_user.has_joined'] = '已经加入过群组';
$error['im_chat_group_user.blocked'] = '被群组屏蔽';
$error['im_friend_user.self_apply'] = '不能添加自己为好友';
$error['im_friend_user.has_joined'] = '已经是好友啦';
$error['im_friend_user.blocked'] = '被对方屏蔽';
$error['im_message.not_found'] = '消息不存在';
$error['im_message.invalid_type'] = '无效的消息类型';
$error['im_message.content_too_short'] = '消息内容太短少于1字符';
$error['im_message.content_too_long'] = '消息内容太长超过1000字符';
return $error;

View File

@ -20,7 +20,12 @@
background-color: #fff;
}
.body {
.full {
background-color: #f2f2f2;
}
.layer {
padding: 20px;
background-color: #f2f2f2;
}
@ -60,10 +65,6 @@
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
}
.layer-container {
padding: 20px;
}
.pager {
margin-top: 25px;
text-align: center;
@ -1190,6 +1191,10 @@
font-size: 12px;
}
.user-card .action span {
cursor: pointer;
}
.my-profile-card {
text-align: center;
}
@ -1283,12 +1288,28 @@
margin-right: 8px;
}
.layer .layim-chat-main {
height: auto;
.im-search {
margin-bottom: 10px;
}
.layim-chat-user img {
width: 40px;
height: 40px;
.im-user-list .user-card {
height: 150px;
font-size: 12px;
color: #666;
}
.im-user-list .avatar {
margin-top: 15px;
margin-bottom: 10px;
}
.im-user-list .avatar img {
width: 64px;
height: 64px;
border-radius: 100%;
}
.im-user-list .name {
margin-bottom: 10px;
padding: 0 5px;
}

View File

@ -25,6 +25,23 @@ layui.use(['jquery', 'form', 'element', 'layer'], function () {
}
});
/**
* @todo 定时刷新token
*/
/**
setInterval(function () {
var $token = $('meta[name="csrf-token"]');
$.ajax({
type: 'POST',
url: '/token/refresh',
data: {token: $token.val()},
success: function (res) {
$token.attr('content', res.token);
}
});
}, 300000);
*/
form.on('submit(go)', function (data) {
var submit = $(this);
submit.attr('disabled', 'disabled').addClass('layui-btn-disabled');
@ -46,8 +63,8 @@ layui.use(['jquery', 'form', 'element', 'layer'], function () {
}
},
error: function (xhr) {
var json = JSON.parse(xhr.responseText);
layer.msg(json.msg, {icon: 2});
var res = JSON.parse(xhr.responseText);
layer.msg(res.msg, {icon: 2});
submit.removeAttr('disabled').removeClass('layui-btn-disabled');
}
});

View File

@ -0,0 +1,38 @@
layui.use(['jquery', 'layer'], function () {
var $ = layui.jquery;
var layer = layui.layer;
$('.apply-friend').on('click', function () {
var friendId = $(this).attr('data-id');
$.ajax({
type: 'POST',
url: '/im/friend/apply',
data: {friend_id: friendId},
success: function (res) {
layer.msg(res.msg, {icon: 1});
},
error: function (xhr) {
var res = JSON.parse(xhr.responseText);
layer.msg(res.msg, {icon: 2});
}
});
});
$('.apply-group').on('click', function () {
var groupId = $(this).attr('data-id');
$.ajax({
type: 'POST',
url: '/im/group/apply',
data: {group_id: groupId},
success: function (res) {
layer.msg(res.msg, {icon: 1});
},
error: function (xhr) {
var res = JSON.parse(xhr.responseText);
layer.msg(res.msg, {icon: 2});
}
});
});
});

View File

@ -42,7 +42,7 @@ layui.use(['jquery', 'layim'], function () {
uploadFile: {
url: '/im/file/upload'
},
maxLength: 1500,
maxLength: 1000,
find: '/im/find',
msgbox: '/im/msg/box',
chatLog: '/im/chat/log'
@ -52,6 +52,14 @@ layui.use(['jquery', 'layim'], function () {
sendMessage(res.mine, res.to);
});
layim.on('sign', function (sign) {
$.ajax({
type: 'POST',
url: '/im/sign/update',
data: {sign: sign}
});
});
function bindUser(clientId) {
$.ajax({
type: 'POST',

View File

@ -0,0 +1,18 @@
layui.use(['jquery', 'element'], function () {
var $ = layui.jquery;
if ($('#tab-courses').length > 0) {
var $tabCourses = $('#tab-courses');
layui.ajaxLoadHtml($tabCourses.attr('data-url'), $tabCourses.attr('id'));
}
if ($('#tab-favorites').length > 0) {
var $tabFavorites = $('#tab-favorites');
layui.ajaxLoadHtml($tabFavorites.attr('data-url'), $tabFavorites.attr('id'));
}
if ($('#tab-friends').length > 0) {
var $tabFriends = $('#tab-friends');
layui.ajaxLoadHtml($tabFriends.attr('data-url'), $tabFriends.attr('id'));
}
});