mirror of
https://gitee.com/koogua/course-tencent-cloud.git
synced 2025-06-24 20:06:09 +08:00
优化IM,修改后台登录页
This commit is contained in:
parent
1de760ba56
commit
33b24e65e7
@ -60,10 +60,10 @@ class IndexLiveList extends Cache
|
||||
|
||||
$chapters = $chapterRepo->findByIds($chapterIds);
|
||||
|
||||
$chapterMappings = [];
|
||||
$chapterMapping = [];
|
||||
|
||||
foreach ($chapters as $chapter) {
|
||||
$chapterMappings[$chapter->id] = $chapter;
|
||||
$chapterMapping[$chapter->id] = $chapter;
|
||||
}
|
||||
|
||||
$courseIds = kg_array_column($lives->toArray(), 'course_id');
|
||||
@ -72,10 +72,10 @@ class IndexLiveList extends Cache
|
||||
|
||||
$courses = $courseRepo->findByIds($courseIds);
|
||||
|
||||
$courseMappings = [];
|
||||
$courseMapping = [];
|
||||
|
||||
foreach ($courses as $course) {
|
||||
$courseMappings[$course->id] = $course;
|
||||
$courseMapping[$course->id] = $course;
|
||||
}
|
||||
|
||||
foreach ($lives as $live) {
|
||||
@ -90,8 +90,8 @@ class IndexLiveList extends Cache
|
||||
continue;
|
||||
}
|
||||
|
||||
$chapter = $chapterMappings[$live->chapter_id];
|
||||
$course = $courseMappings[$chapter->course_id];
|
||||
$chapter = $chapterMapping[$live->chapter_id];
|
||||
$course = $courseMapping[$chapter->course_id];
|
||||
|
||||
$chapterInfo = [
|
||||
'id' => $chapter->id,
|
||||
|
@ -4,6 +4,7 @@ namespace App\Http\Admin\Controllers;
|
||||
|
||||
use App\Http\Admin\Services\Session as SessionService;
|
||||
use App\Http\Admin\Services\Setting as SettingService;
|
||||
use App\Library\AppInfo as AppInfo;
|
||||
use App\Traits\Auth as AuthTrait;
|
||||
use App\Traits\Response as ResponseTrait;
|
||||
use App\Traits\Security as SecurityTrait;
|
||||
@ -23,9 +24,9 @@ class SessionController extends \Phalcon\Mvc\Controller
|
||||
*/
|
||||
public function loginAction()
|
||||
{
|
||||
$currentUser = $this->getCurrentUser();
|
||||
$user = $this->getCurrentUser();
|
||||
|
||||
if ($currentUser->id > 0) {
|
||||
if ($user->id > 0) {
|
||||
$this->response->redirect(['for' => 'admin.index']);
|
||||
}
|
||||
|
||||
@ -43,11 +44,14 @@ class SessionController extends \Phalcon\Mvc\Controller
|
||||
return $this->jsonSuccess(['location' => $location]);
|
||||
}
|
||||
|
||||
$appInfo = new AppInfo();
|
||||
|
||||
$settingService = new SettingService();
|
||||
|
||||
$captcha = $settingService->getSectionSettings('captcha');
|
||||
|
||||
$this->view->pick('public/login');
|
||||
$this->view->setVar('app_info', $appInfo);
|
||||
$this->view->setVar('captcha', $captcha);
|
||||
}
|
||||
|
||||
@ -56,9 +60,9 @@ class SessionController extends \Phalcon\Mvc\Controller
|
||||
*/
|
||||
public function logoutAction()
|
||||
{
|
||||
$service = new SessionService();
|
||||
$sessionService = new SessionService();
|
||||
|
||||
$service->logout();
|
||||
$sessionService->logout();
|
||||
|
||||
$this->response->redirect(['for' => 'admin.login']);
|
||||
}
|
||||
|
@ -2,33 +2,54 @@
|
||||
|
||||
{% block content %}
|
||||
|
||||
<form class="kg-login-form layui-form" method="POST" action="{{ url({'for':'admin.login'}) }}">
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<input class="layui-input" type="text" name="account" autocomplete="off" placeholder="手机 / 邮箱" lay-verify="required">
|
||||
<div class="kg-login-wrap">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">管理登录</div>
|
||||
<div class="layui-card-body">
|
||||
<form class="layui-form kg-login-form" method="POST" action="{{ url({'for':'admin.login'}) }}">
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<input class="layui-input" type="text" name="account" autocomplete="off" placeholder="手机 / 邮箱" lay-verify="required">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<input class="layui-input" type="password" name="password" autocomplete="off" placeholder="密码" lay-verify="required">
|
||||
</div>
|
||||
</div>
|
||||
{% if captcha.enabled == 1 %}
|
||||
<div id="captcha-block" class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button id="captcha-btn" class="layui-btn layui-btn-fluid" type="button" data-app-id="{{ captcha.app_id }}">点击完成验证</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
{% set disabled = captcha.enabled ? 'disabled' : '' %}
|
||||
<button id="submit-btn" class="layui-btn layui-btn-fluid layui-btn-disabled" {{ disabled }} lay-submit="true" lay-filter="go">立即登录</button>
|
||||
<input type="hidden" name="ticket">
|
||||
<input type="hidden" name="rand">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<input class="layui-input" type="password" name="password" autocomplete="off" placeholder="密码" lay-verify="required">
|
||||
</div>
|
||||
</div>
|
||||
{% if captcha.enabled == 1 %}
|
||||
<div id="captcha-block" class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button id="captcha-btn" class="layui-btn layui-btn-fluid" type="button" data-app-id="{{ captcha.app_id }}">点击完成验证</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
{% set disabled = captcha.enabled ? 'disabled' : '' %}
|
||||
<button id="submit-btn" class="layui-btn layui-btn-fluid layui-btn-disabled" {{ disabled }} lay-submit="true" lay-filter="go">立即登录</button>
|
||||
<input type="hidden" name="ticket">
|
||||
<input type="hidden" name="rand">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="kg-login-copyright">
|
||||
Powered by <a href="{{ app_info.link }}" title="{{ app_info.name }}">{{ app_info.alias }} {{ app_info.version }}</a>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block inline_css %}
|
||||
|
||||
<style>
|
||||
body {
|
||||
background: #f2f2f2;
|
||||
}
|
||||
</style>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% set expiry_editable = relation.source_type in [1,3] %}
|
||||
|
||||
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.student.update'}) }}">
|
||||
<fieldset class="layui-elem-field layui-field-title">
|
||||
<legend>编辑学员</legend>
|
||||
@ -18,12 +20,21 @@
|
||||
<div class="layui-form-mid layui-word-aux">{{ student.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">过期时间</label>
|
||||
<div class="layui-input-block">
|
||||
<input class="layui-input" type="text" name="expiry_time" autocomplete="off" value="{{ date('Y-m-d H:i:s',relation.expiry_time) }}" lay-verify="required">
|
||||
{% if expiry_editable %}
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">过期时间</label>
|
||||
<div class="layui-input-block">
|
||||
<input class="layui-input" type="text" name="expiry_time" autocomplete="off" value="{{ date('Y-m-d H:i:s',relation.expiry_time) }}" lay-verify="required">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">过期时间</label>
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-form-mid layui-word-aux">{{ date('Y-m-d H:i:s',relation.expiry_time) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"></label>
|
||||
<div class="layui-input-block">
|
||||
|
@ -42,23 +42,6 @@
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">会员服务</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="vip" value="1" title="是" lay-filter="vip" {% if user.vip == 1 %}checked="checked"{% endif %}>
|
||||
<input type="radio" name="vip" value="0" title="否" lay-filter="vip" {% if user.vip == 0 %}checked="checked"{% endif %}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item" id="vip-expiry-block" {% if user.vip == 0 %}style="display:none;"{% endif %}>
|
||||
<label class="layui-form-label">会员期限</label>
|
||||
<div class="layui-input-block">
|
||||
{% if user.vip_expiry_time > 0 %}
|
||||
<input class="layui-input" type="text" name="vip_expiry_time" autocomplete="off" value="{{ date('Y-m-d H:i:s',user.vip_expiry_time) }}">
|
||||
{% else %}
|
||||
<input class="layui-input" type="text" name="vip_expiry_time" autocomplete="off">
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">锁定帐号</label>
|
||||
<div class="layui-input-block">
|
||||
@ -132,25 +115,11 @@
|
||||
var form = layui.form;
|
||||
var laydate = layui.laydate;
|
||||
|
||||
laydate.render({
|
||||
elem: 'input[name=vip_expiry_time]',
|
||||
type: 'datetime'
|
||||
});
|
||||
|
||||
laydate.render({
|
||||
elem: 'input[name=lock_expiry_time]',
|
||||
type: 'datetime'
|
||||
});
|
||||
|
||||
form.on('radio(vip)', function (data) {
|
||||
var block = $('#vip-expiry-block');
|
||||
if (data.value === '1') {
|
||||
block.show();
|
||||
} else {
|
||||
block.hide();
|
||||
}
|
||||
});
|
||||
|
||||
form.on('radio(locked)', function (data) {
|
||||
var block = $('#lock-expiry-block');
|
||||
if (data.value === '1') {
|
||||
|
@ -4,9 +4,9 @@
|
||||
|
||||
{%- macro gender_info(value) %}
|
||||
{% if value == 1 %}
|
||||
<span class="layui-badge layui-bg-red">男</span>
|
||||
<span class="layui-badge layui-bg-gray">男</span>
|
||||
{% elseif value == 2 %}
|
||||
<span class="layui-badge layui-bg-green">女</span>
|
||||
<span class="layui-badge layui-bg-gray">女</span>
|
||||
{% elseif value == 3 %}
|
||||
<span class="layui-badge layui-bg-gray">密</span>
|
||||
{% endif %}
|
||||
|
@ -29,6 +29,18 @@ class ImController extends Controller
|
||||
public function indexAction()
|
||||
{
|
||||
$this->seo->prependTitle('微聊');
|
||||
|
||||
$service = new ImService();
|
||||
|
||||
$activeGroups = $service->getActiveGroups();
|
||||
$activeUsers = $service->getActiveUsers();
|
||||
$newGroups = $service->getNewGroups();
|
||||
$newUsers = $service->getNewUsers();
|
||||
|
||||
$this->view->setVar('active_users', $activeUsers);
|
||||
$this->view->setVar('active_groups', $activeGroups);
|
||||
$this->view->setVar('new_groups', $newGroups);
|
||||
$this->view->setVar('new_users', $newUsers);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -74,7 +86,7 @@ class ImController extends Controller
|
||||
{
|
||||
$service = new ImService();
|
||||
|
||||
$pager = $service->getSystemMessages();
|
||||
$pager = $service->getNotices();
|
||||
|
||||
$this->view->pick('im/msgbox');
|
||||
$this->view->setVar('pager', $pager);
|
||||
|
@ -46,6 +46,8 @@ class ImGroupController extends Controller
|
||||
|
||||
$group = $service->getGroup($id);
|
||||
|
||||
$this->seo->prependTitle([$group['name'], '群组']);
|
||||
|
||||
$this->view->pick('im/group/show');
|
||||
$this->view->setVar('group', $group);
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Http\Web\Services;
|
||||
|
||||
use App\Caches\Setting as SettingCache;
|
||||
use App\Models\ImUser as ImUserModel;
|
||||
use App\Repos\ImGroup as ImGroupRepo;
|
||||
use App\Repos\ImUser as ImUserRepo;
|
||||
@ -13,55 +12,13 @@ use GatewayClient\Gateway;
|
||||
class Im extends Service
|
||||
{
|
||||
|
||||
use ImCsTrait;
|
||||
use ImFriendTrait;
|
||||
use ImGroupTrait;
|
||||
use ImMessageTrait;
|
||||
use ImNoticeTrait;
|
||||
use ImStatTrait;
|
||||
|
||||
public function getCsUser()
|
||||
{
|
||||
$csUserIds = [];
|
||||
$onlineUserIds = [];
|
||||
|
||||
$cache = new SettingCache();
|
||||
|
||||
$imInfo = $cache->get('im');
|
||||
|
||||
Gateway::$registerAddress = $this->getRegisterAddress();
|
||||
|
||||
if (!empty($imInfo['cs_user1_id'])) {
|
||||
$csUserIds[] = $imInfo['cs_user1_id'];
|
||||
if (Gateway::isUidOnline($imInfo['cs_user1_id'])) {
|
||||
$onlineUserIds[] = $imInfo['cs_user1_id'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($imInfo['cs_user2_id'])) {
|
||||
$csUserIds[] = $imInfo['cs_user2_id'];
|
||||
if (Gateway::isUidOnline($imInfo['cs_user2_id'])) {
|
||||
$onlineUserIds[] = $imInfo['cs_user2_id'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($imInfo['cs_user3_id'])) {
|
||||
$csUserIds[] = $imInfo['cs_user3_id'];
|
||||
if (Gateway::isUidOnline($imInfo['cs_user3_id'])) {
|
||||
$onlineUserIds[] = $imInfo['cs_user3_id'];
|
||||
}
|
||||
}
|
||||
|
||||
if (count($onlineUserIds) > 0) {
|
||||
$key = array_rand($onlineUserIds);
|
||||
$userId = $onlineUserIds[$key];
|
||||
} else {
|
||||
$key = array_rand($csUserIds);
|
||||
$userId = $csUserIds[$key];
|
||||
}
|
||||
|
||||
return $this->getImUser($userId);
|
||||
}
|
||||
|
||||
public function getInitInfo()
|
||||
{
|
||||
$loginUser = $this->getLoginUser();
|
||||
@ -295,26 +252,29 @@ class Im extends Service
|
||||
|
||||
$users = $userRepo->findByIds($ids);
|
||||
|
||||
$mappings = [];
|
||||
$baseUrl = kg_ci_base_url();
|
||||
|
||||
$mapping = [];
|
||||
|
||||
/**
|
||||
* 用户可以设置状态为 ['online', 'hide']
|
||||
* 列表在线状态识别为 ['online', 'offline']
|
||||
*/
|
||||
foreach ($users as $user) {
|
||||
$status = in_array($user->status, ['online', 'offline']) ? $user->status : 'offline';
|
||||
$mappings[$user->id] = [
|
||||
'id' => $user->id,
|
||||
'username' => $user->name,
|
||||
'avatar' => $user->avatar,
|
||||
'sign' => $user->sign,
|
||||
foreach ($users->toArray() as $user) {
|
||||
$status = in_array($user['status'], ['online', 'offline']) ? $user['status'] : 'offline';
|
||||
$user['avatar'] = $baseUrl . $user['avatar'];
|
||||
$mapping[$user['id']] = [
|
||||
'id' => $user['id'],
|
||||
'username' => $user['name'],
|
||||
'avatar' => $user['avatar'],
|
||||
'sign' => $user['sign'],
|
||||
'status' => $status,
|
||||
];
|
||||
}
|
||||
|
||||
foreach ($items as $key => $item) {
|
||||
foreach ($friendUsers as $friendUser) {
|
||||
$friend = $mappings[$friendUser->friend_id];
|
||||
$friend = $mapping[$friendUser->friend_id];
|
||||
if ($item['id'] == $friendUser->group_id) {
|
||||
$friend['msg_count'] = $friendUser->msg_count;
|
||||
$items[$key]['list'][] = $friend;
|
||||
@ -331,23 +291,34 @@ class Im extends Service
|
||||
{
|
||||
$userRepo = new ImUserRepo();
|
||||
|
||||
$groups = $userRepo->findGroups($user->id);
|
||||
$groupUsers = $userRepo->findGroupUsers($user->id);
|
||||
|
||||
if ($groups->count() == 0) {
|
||||
if ($groupUsers->count() == 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$groupRepo = new ImGroupRepo();
|
||||
|
||||
$ids = kg_array_column($groupUsers->toArray(), 'group_id');
|
||||
|
||||
$groups = $groupRepo->findByIds($ids);
|
||||
|
||||
$baseUrl = kg_ci_base_url();
|
||||
|
||||
$mapping = [];
|
||||
|
||||
foreach ($groups->toArray() as $group) {
|
||||
$mapping[$group['id']] = [
|
||||
'id' => $group['id'],
|
||||
'groupname' => $group['name'],
|
||||
'avatar' => $baseUrl . $group['avatar'],
|
||||
];
|
||||
}
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($groups->toArray() as $group) {
|
||||
$group['avatar'] = $baseUrl . $group['avatar'];
|
||||
$result[] = [
|
||||
'id' => $group['id'],
|
||||
'groupname' => $group['name'],
|
||||
'avatar' => $group['avatar'],
|
||||
];
|
||||
foreach ($groupUsers as $groupUser) {
|
||||
$result[] = $mapping[$groupUser->group_id];
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
54
app/Http/Web/Services/ImCsTrait.php
Normal file
54
app/Http/Web/Services/ImCsTrait.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Web\Services;
|
||||
|
||||
use App\Caches\Setting as SettingCache;
|
||||
use GatewayClient\Gateway;
|
||||
|
||||
trait ImCsTrait
|
||||
{
|
||||
|
||||
public function getCsUser()
|
||||
{
|
||||
$csUserIds = [];
|
||||
$onlineUserIds = [];
|
||||
|
||||
$cache = new SettingCache();
|
||||
|
||||
$imInfo = $cache->get('im');
|
||||
|
||||
Gateway::$registerAddress = $this->getRegisterAddress();
|
||||
|
||||
if (!empty($imInfo['cs_user1_id'])) {
|
||||
$csUserIds[] = $imInfo['cs_user1_id'];
|
||||
if (Gateway::isUidOnline($imInfo['cs_user1_id'])) {
|
||||
$onlineUserIds[] = $imInfo['cs_user1_id'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($imInfo['cs_user2_id'])) {
|
||||
$csUserIds[] = $imInfo['cs_user2_id'];
|
||||
if (Gateway::isUidOnline($imInfo['cs_user2_id'])) {
|
||||
$onlineUserIds[] = $imInfo['cs_user2_id'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($imInfo['cs_user3_id'])) {
|
||||
$csUserIds[] = $imInfo['cs_user3_id'];
|
||||
if (Gateway::isUidOnline($imInfo['cs_user3_id'])) {
|
||||
$onlineUserIds[] = $imInfo['cs_user3_id'];
|
||||
}
|
||||
}
|
||||
|
||||
if (count($onlineUserIds) > 0) {
|
||||
$key = array_rand($onlineUserIds);
|
||||
$userId = $onlineUserIds[$key];
|
||||
} else {
|
||||
$key = array_rand($csUserIds);
|
||||
$userId = $csUserIds[$key];
|
||||
}
|
||||
|
||||
return $this->getImUser($userId);
|
||||
}
|
||||
|
||||
}
|
@ -6,6 +6,7 @@ use App\Builders\ImMessageList as ImMessageListBuilder;
|
||||
use App\Library\Paginator\Query as PagerQuery;
|
||||
use App\Models\ImFriendUser as ImFriendUserModel;
|
||||
use App\Models\ImGroup as ImGroupModel;
|
||||
use App\Models\ImGroupUser as ImGroupUserModel;
|
||||
use App\Models\ImMessage as ImMessageModel;
|
||||
use App\Repos\ImFriendUser as ImFriendUserRepo;
|
||||
use App\Repos\ImMessage as ImMessageRepo;
|
||||
@ -24,52 +25,6 @@ use GatewayClient\Gateway;
|
||||
Trait ImMessageTrait
|
||||
{
|
||||
|
||||
public function pullUnreadFriendMessages($id)
|
||||
{
|
||||
$user = $this->getLoginUser();
|
||||
|
||||
$validator = new ImUserValidator();
|
||||
|
||||
$friend = $validator->checkUser($id);
|
||||
|
||||
$userRepo = new ImUserRepo();
|
||||
|
||||
$messages = $userRepo->findUnreadFriendMessages($friend->id, $user->id);
|
||||
|
||||
if ($messages->count() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Gateway::$registerAddress = $this->getRegisterAddress();
|
||||
|
||||
foreach ($messages as $message) {
|
||||
|
||||
$message->update(['viewed' => 1]);
|
||||
|
||||
$content = kg_json_encode([
|
||||
'type' => 'show_chat_msg',
|
||||
'message' => [
|
||||
'username' => $friend->name,
|
||||
'avatar' => $friend->avatar,
|
||||
'id' => $friend->id,
|
||||
'fromid' => $friend->id,
|
||||
'content' => $message->content,
|
||||
'timestamp' => 1000 * $message->create_time,
|
||||
'type' => 'friend',
|
||||
'mine' => false,
|
||||
],
|
||||
]);
|
||||
|
||||
Gateway::sendToUid($user->id, $content);
|
||||
}
|
||||
|
||||
$repo = new ImFriendUserRepo();
|
||||
|
||||
$friendUser = $repo->findFriendUser($user->id, $friend->id);
|
||||
|
||||
$friendUser->update(['msg_count' => 0]);
|
||||
}
|
||||
|
||||
public function getChatMessages()
|
||||
{
|
||||
$user = $this->getLoginUser();
|
||||
@ -86,7 +41,7 @@ Trait ImMessageTrait
|
||||
$page = $pagerQuery->getPage();
|
||||
$limit = $pagerQuery->getLimit();
|
||||
|
||||
if ($params['type'] == ImMessageModel::TYPE_FRIEND) {
|
||||
if ($params['type'] == 'friend') {
|
||||
|
||||
$chatId = ImMessageModel::getChatId($user->id, $params['id']);
|
||||
|
||||
@ -98,7 +53,7 @@ Trait ImMessageTrait
|
||||
|
||||
return $this->handleChatMessagePager($pager);
|
||||
|
||||
} elseif ($params['type'] == ImMessageModel::TYPE_GROUP) {
|
||||
} elseif ($params['type'] == 'group') {
|
||||
|
||||
$where = [
|
||||
'receiver_type' => $params['type'],
|
||||
@ -161,6 +116,8 @@ Trait ImMessageTrait
|
||||
'viewed' => $online ? 1 : 0,
|
||||
]);
|
||||
|
||||
$this->updateFriendUserChatTime($relation);
|
||||
|
||||
if ($online) {
|
||||
Gateway::sendToUid($to['id'], $content);
|
||||
} else {
|
||||
@ -177,7 +134,7 @@ Trait ImMessageTrait
|
||||
|
||||
$validator = new ImGroupUserValidator();
|
||||
|
||||
$validator->checkGroupUser($group->id, $user->id);
|
||||
$relation = $validator->checkGroupUser($group->id, $user->id);
|
||||
|
||||
$messageModel = new ImMessageModel();
|
||||
|
||||
@ -188,6 +145,8 @@ Trait ImMessageTrait
|
||||
'content' => $from['content'],
|
||||
]);
|
||||
|
||||
$this->updateGroupUserChatTime($relation);
|
||||
|
||||
$this->incrGroupMsgCount($group);
|
||||
|
||||
$excludeClientId = null;
|
||||
@ -254,6 +213,52 @@ Trait ImMessageTrait
|
||||
$this->sendChatMessage($from, $to);
|
||||
}
|
||||
|
||||
public function pullUnreadFriendMessages($id)
|
||||
{
|
||||
$user = $this->getLoginUser();
|
||||
|
||||
$validator = new ImUserValidator();
|
||||
|
||||
$friend = $validator->checkUser($id);
|
||||
|
||||
$userRepo = new ImUserRepo();
|
||||
|
||||
$messages = $userRepo->findUnreadFriendMessages($friend->id, $user->id);
|
||||
|
||||
if ($messages->count() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Gateway::$registerAddress = $this->getRegisterAddress();
|
||||
|
||||
foreach ($messages as $message) {
|
||||
|
||||
$message->update(['viewed' => 1]);
|
||||
|
||||
$content = kg_json_encode([
|
||||
'type' => 'show_chat_msg',
|
||||
'message' => [
|
||||
'username' => $friend->name,
|
||||
'avatar' => $friend->avatar,
|
||||
'id' => $friend->id,
|
||||
'fromid' => $friend->id,
|
||||
'content' => $message->content,
|
||||
'timestamp' => 1000 * $message->create_time,
|
||||
'type' => 'friend',
|
||||
'mine' => false,
|
||||
],
|
||||
]);
|
||||
|
||||
Gateway::sendToUid($user->id, $content);
|
||||
}
|
||||
|
||||
$repo = new ImFriendUserRepo();
|
||||
|
||||
$friendUser = $repo->findFriendUser($user->id, $friend->id);
|
||||
|
||||
$friendUser->update(['msg_count' => 0]);
|
||||
}
|
||||
|
||||
protected function handleChatMessagePager($pager)
|
||||
{
|
||||
if ($pager->total_items == 0) {
|
||||
@ -283,6 +288,34 @@ Trait ImMessageTrait
|
||||
return $pager;
|
||||
}
|
||||
|
||||
protected function updateFriendUserChatTime(ImFriendUserModel $hisFriendUser)
|
||||
{
|
||||
/**
|
||||
* 用于联系人排序,近期有联系的排上面
|
||||
*/
|
||||
if (time() - $hisFriendUser->update_time > 15 * 60) {
|
||||
|
||||
$hisFriendUser->update(['update_time' => time()]);
|
||||
|
||||
$repo = new ImFriendUserRepo();
|
||||
|
||||
$myFriendUser = $repo->findFriendUser($hisFriendUser->friend_id, $hisFriendUser->user_id);
|
||||
|
||||
$myFriendUser->update(['update_time' => time()]);
|
||||
}
|
||||
}
|
||||
|
||||
protected function updateGroupUserChatTime(ImGroupUserModel $groupUser)
|
||||
{
|
||||
/**
|
||||
* 用于联系人排序,近期有联系的排上面
|
||||
*/
|
||||
if (time() - $groupUser->update_time > 15 * 60) {
|
||||
$groupUser->update_time = time();
|
||||
$groupUser->update();
|
||||
}
|
||||
}
|
||||
|
||||
protected function incrFriendUserMsgCount(ImFriendUserModel $friendUser)
|
||||
{
|
||||
$friendUser->msg_count += 1;
|
||||
|
@ -2,27 +2,40 @@
|
||||
|
||||
namespace App\Http\Web\Services;
|
||||
|
||||
use App\Caches\ImActiveGroupList;
|
||||
use App\Caches\ImActiveUserList;
|
||||
use App\Caches\ImNewGroupList;
|
||||
use App\Caches\ImNewUserList;
|
||||
|
||||
trait ImStatTrait
|
||||
{
|
||||
|
||||
public function getActiveGroups()
|
||||
{
|
||||
$cache = new ImActiveGroupList();
|
||||
|
||||
return $cache->get();
|
||||
}
|
||||
|
||||
public function getActiveUsers()
|
||||
{
|
||||
$cache = new ImActiveUserList();
|
||||
|
||||
return $cache->get();
|
||||
}
|
||||
|
||||
public function getNewGroups()
|
||||
{
|
||||
$cache = new ImNewGroupList();
|
||||
|
||||
return $cache->get();
|
||||
}
|
||||
|
||||
public function getNewUsers()
|
||||
{
|
||||
$cache = new ImNewUserList();
|
||||
|
||||
return $cache->get();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -37,4 +37,14 @@
|
||||
{{ js_include('web/js/captcha.login.js') }}
|
||||
{{ js_include('web/js/captcha.verify.js') }}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block inline_js %}
|
||||
|
||||
<script>
|
||||
if (window !== top) {
|
||||
top.location.href = window.location.href;
|
||||
}
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
@ -16,5 +16,6 @@
|
||||
{% block include_js %}
|
||||
|
||||
{{ js_include('web/js/im.group.list.js') }}
|
||||
{{ js_include('web/js/im.apply.js') }}
|
||||
|
||||
{% endblock %}
|
@ -1,40 +1,33 @@
|
||||
{%- macro type_info(value) %}
|
||||
{% if value == 'course' %}
|
||||
<span class="layui-badge layui-bg-green type">课</span>
|
||||
{% elseif value == 'chat' %}
|
||||
<span class="layui-badge layui-bg-blue type">聊</span>
|
||||
{% elseif value == 'staff' %}
|
||||
<span class="layui-badge layui-bg-red type">工</span>
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
{{ partial('macros/group') }}
|
||||
|
||||
<div class="group-list clearfix">
|
||||
<div class="layui-row layui-col-space20">
|
||||
{% for item in pager.items %}
|
||||
{% set group_url = url({'for':'web.group.show','id':item.id}) %}
|
||||
{% set owner_url = url({'for':'web.user.show','id':item.owner.id}) %}
|
||||
{% set item.about = item.about ? item.about : '这家伙真懒,什么都没留下!' %}
|
||||
<div class="layui-col-md3">
|
||||
<div class="user-card">
|
||||
{{ type_info(item.type) }}
|
||||
<div class="avatar">
|
||||
<a href="{{ group_url }}" title="{{ item.about }}">
|
||||
<img src="{{ item.avatar }}" alt="{{ item.name }}">
|
||||
</a>
|
||||
</div>
|
||||
<div class="name layui-elip">
|
||||
<a href="{{ group_url }}" title="{{ item.name }}">{{ item.name }}</a>
|
||||
</div>
|
||||
<div class="owner">
|
||||
<span>组长:<a href="{{ owner_url }}">{{ item.owner.name }}</a></span>
|
||||
</div>
|
||||
<div class="meta layui-elip">
|
||||
<span>成员:{{ item.user_count }}</span>
|
||||
<span>讨论:{{ item.msg_count }}</span>
|
||||
{% if pager.total_pages > 0 %}
|
||||
<div class="group-list clearfix">
|
||||
<div class="layui-row layui-col-space20">
|
||||
{% for item in pager.items %}
|
||||
{% set group_url = url({'for':'web.group.show','id':item.id}) %}
|
||||
{% set item.about = item.about ? item.about : '这家伙真懒,什么都没留下!' %}
|
||||
<div class="layui-col-md3">
|
||||
<div class="user-card">
|
||||
{{ type_info(item.type) }}
|
||||
<div class="avatar">
|
||||
<a href="{{ group_url }}" title="{{ item.about }}">
|
||||
<img src="{{ item.avatar }}" alt="{{ item.name }}">
|
||||
</a>
|
||||
</div>
|
||||
<div class="name layui-elip">
|
||||
<a href="{{ group_url }}" title="{{ item.name }}">{{ item.name }}</a>
|
||||
</div>
|
||||
<div class="meta layui-elip">
|
||||
<span>成员:{{ item.user_count }}</span>
|
||||
<span>讨论:{{ item.msg_count }}</span>
|
||||
</div>
|
||||
<div class="action">
|
||||
<span class="layui-btn apply-group" data-id="{{ item.id }}" data-name="{{ item.name }}" data-avatar="{{ item.avatar }}">加入群组</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ partial('partials/pager_ajax') }}
|
||||
{{ partial('partials/pager_ajax') }}
|
||||
{% endif %}
|
@ -2,19 +2,30 @@
|
||||
|
||||
{% block content %}
|
||||
|
||||
{{ partial('macros/group') }}
|
||||
{{ partial('macros/user') }}
|
||||
|
||||
<div class="tab-wrap">
|
||||
<div class="layui-tab layui-tab-brief user-tab">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this">活跃群组</li>
|
||||
<li>活跃用户</li>
|
||||
<li>新进群组</li>
|
||||
<li class="layui-this">新进群组</li>
|
||||
<li>新进用户</li>
|
||||
<li>活跃群组</li>
|
||||
<li>活跃用户</li>
|
||||
</ul>
|
||||
<div class="layui-tab-content">
|
||||
<div class="layui-tab-item layui-show"></div>
|
||||
<div class="layui-tab-item"></div>
|
||||
<div class="layui-tab-item"></div>
|
||||
<div class="layui-tab-item"></div>
|
||||
<div class="layui-tab-item layui-show">
|
||||
{{ partial('im/index_groups',{'groups':new_groups}) }}
|
||||
</div>
|
||||
<div class="layui-tab-item">
|
||||
{{ partial('im/index_users',{'users':new_users}) }}
|
||||
</div>
|
||||
<div class="layui-tab-item">
|
||||
{{ partial('im/index_groups',{'groups':active_groups}) }}
|
||||
</div>
|
||||
<div class="layui-tab-item">
|
||||
{{ partial('im/index_users',{'users':active_users}) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -24,5 +35,6 @@
|
||||
{% block include_js %}
|
||||
|
||||
{{ js_include('web/js/im.js') }}
|
||||
{{ js_include('web/js/im.apply.js') }}
|
||||
|
||||
{% endblock %}
|
28
app/Http/Web/Views/im/index_groups.volt
Normal file
28
app/Http/Web/Views/im/index_groups.volt
Normal file
@ -0,0 +1,28 @@
|
||||
<div class="user-list clearfix">
|
||||
<div class="layui-row layui-col-space20">
|
||||
{% for group in groups %}
|
||||
{% set group_url = url({'for':'web.group.show','id':group.id}) %}
|
||||
{% set group.about = group.about ? group.about : '这家伙真懒,什么都没留下!' %}
|
||||
<div class="layui-col-md3">
|
||||
<div class="user-card">
|
||||
{{ type_info(group.type) }}
|
||||
<div class="avatar">
|
||||
<a href="{{ group_url }}" title="{{ group.about }}" target="group">
|
||||
<img src="{{ group.avatar }}" alt="{{ group.name }}">
|
||||
</a>
|
||||
</div>
|
||||
<div class="name layui-elip">
|
||||
<a href="{{ group_url }}" title="{{ group.name }}" target="group">{{ group.name }}</a>
|
||||
</div>
|
||||
<div class="meta layui-elip">
|
||||
<span>成员:{{ group.user_count }}</span>
|
||||
<span>讨论:{{ group.msg_count }}</span>
|
||||
</div>
|
||||
<div class="action">
|
||||
<span class="layui-btn apply-group" data-id="{{ group.id }}" data-name="{{ group.name }}" data-avatar="{{ group.avatar }}">加入群组</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
26
app/Http/Web/Views/im/index_users.volt
Normal file
26
app/Http/Web/Views/im/index_users.volt
Normal file
@ -0,0 +1,26 @@
|
||||
<div class="user-list clearfix">
|
||||
<div class="layui-row layui-col-space20">
|
||||
{% for user in users %}
|
||||
{% set user.title = user.title ? user.title : '暂露头角' %}
|
||||
{% set user.about = user.about ? user.about : '这个人很懒,什么都没留下' %}
|
||||
{% set user_url = url({'for':'web.user.show','id':user.id}) %}
|
||||
<div class="layui-col-md2">
|
||||
<div class="user-card">
|
||||
{{ vip_info(user.vip) }}
|
||||
<div class="avatar">
|
||||
<a href="{{ user_url }}" title="{{ user.about }}" target="user">
|
||||
<img src="{{ user.avatar }}" alt="{{ user.name }}">
|
||||
</a>
|
||||
</div>
|
||||
<div class="name layui-elip">
|
||||
<a href="{{ user_url }}" title="{{ user.about }}" target="user">{{ user.name }}</a>
|
||||
</div>
|
||||
<div class="title layui-elip">{{ user.title }}</div>
|
||||
<div class="action">
|
||||
<span class="layui-btn apply-friend" data-id="{{ user.id }}" data-name="{{ user.name }}" data-avatar="{{ user.avatar }}">添加好友</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
9
app/Http/Web/Views/macros/group.volt
Normal file
9
app/Http/Web/Views/macros/group.volt
Normal file
@ -0,0 +1,9 @@
|
||||
{%- macro type_info(value) %}
|
||||
{% if value == 'course' %}
|
||||
<span class="layui-badge layui-bg-green type" title="课程交流">课</span>
|
||||
{% elseif value == 'chat' %}
|
||||
<span class="layui-badge layui-bg-blue type" title="课外畅聊">聊</span>
|
||||
{% elseif value == 'staff' %}
|
||||
<span class="layui-badge layui-bg-cyan type" title="职工交流">职</span>
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
5
app/Http/Web/Views/macros/user.volt
Normal file
5
app/Http/Web/Views/macros/user.volt
Normal file
@ -0,0 +1,5 @@
|
||||
{%- macro vip_info(value) %}
|
||||
{% if value == 1 %}
|
||||
<span class="layui-badge layui-bg-orange vip">宾</span>
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
@ -1,3 +1,5 @@
|
||||
{{ partial('macros/user') }}
|
||||
|
||||
{% if pager.total_pages > 0 %}
|
||||
<div class="user-list clearfix">
|
||||
<div class="layui-row layui-col-space20">
|
||||
@ -7,9 +9,7 @@
|
||||
{% set user_url = url({'for':'web.user.show','id':item.id}) %}
|
||||
<div class="layui-col-md2">
|
||||
<div class="user-card">
|
||||
{% if item.vip == 1 %}
|
||||
<span class="vip">VIP</span>
|
||||
{% endif %}
|
||||
{{ vip_info(item.vip) }}
|
||||
<div class="avatar">
|
||||
<a href="{{ user_url }}" title="{{ item.about }}">
|
||||
<img src="{{ item.avatar }}" alt="{{ item.name }}">
|
||||
|
@ -1,3 +1,5 @@
|
||||
{{ partial('macros/group') }}
|
||||
|
||||
{% if pager.total_pages > 0 %}
|
||||
<div class="user-list clearfix">
|
||||
<div class="layui-row layui-col-space20">
|
||||
@ -6,11 +8,7 @@
|
||||
{% set item.about = item.about ? item.about : '这家伙真懒,什么都没留下!' %}
|
||||
<div class="layui-col-md3">
|
||||
<div class="user-card">
|
||||
{% if item.type == 'course' %}
|
||||
<span class="layui-badge layui-bg-green type">课</span>
|
||||
{% elseif item.type == 'chat' %}
|
||||
<span class="layui-badge layui-bg-blue type">聊</span>
|
||||
{% endif %}
|
||||
{{ type_info(item.type) }}
|
||||
<div class="avatar">
|
||||
<a href="{{ group_url }}" title="{{ item.about }}">
|
||||
<img src="{{ item.avatar }}" alt="{{ item.name }}">
|
||||
|
@ -1,3 +1,5 @@
|
||||
{{ partial('macros/user') }}
|
||||
|
||||
{% if pager.total_pages > 0 %}
|
||||
<div class="user-list vip-user-list clearfix">
|
||||
<div class="layui-row layui-col-space20">
|
||||
@ -7,9 +9,7 @@
|
||||
{% set item.about = item.about ? item.about : '这个人很懒,什么都没留下' %}
|
||||
<div class="layui-col-md2">
|
||||
<div class="user-card">
|
||||
{% if item.vip == 1 %}
|
||||
<span class="layui-badge layui-bg-orange vip">VIP</span>
|
||||
{% endif %}
|
||||
{{ vip_info(item.vip) }}
|
||||
<div class="avatar">
|
||||
<a href="{{ user_url }}" title="{{ item.about }}">
|
||||
<img src="{{ item.avatar }}" alt="{{ item.name }}">
|
||||
|
@ -76,6 +76,18 @@ class ImUser extends Repository
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
* @return ResultsetInterface|Resultset|ImGroupUserModel[]
|
||||
*/
|
||||
public function findGroupUsers($userId)
|
||||
{
|
||||
return ImGroupUserModel::query()
|
||||
->where('user_id = :user_id:', ['user_id' => $userId])
|
||||
->orderBy('update_time DESC')
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
* @return ResultsetInterface|Resultset|ImFriendUserModel[]
|
||||
|
@ -36,13 +36,13 @@ class ChapterList extends FrontendService
|
||||
}
|
||||
|
||||
if ($user->id > 0 && $this->courseUser) {
|
||||
$mappings = $this->getLearningMappings($course->id, $user->id, $this->courseUser->plan_id);
|
||||
$mapping = $this->getLearningMapping($course->id, $user->id, $this->courseUser->plan_id);
|
||||
foreach ($chapters as &$chapter) {
|
||||
foreach ($chapter['children'] as &$lesson) {
|
||||
$lesson['me'] = [
|
||||
'owned' => $this->ownedCourse || $lesson['free'] ? 1 : 0,
|
||||
'progress' => $mappings[$lesson['id']]['progress'] ?? 0,
|
||||
'duration' => $mappings[$lesson['id']]['duration'] ?? 0,
|
||||
'progress' => $mapping[$lesson['id']]['progress'] ?? 0,
|
||||
'duration' => $mapping[$lesson['id']]['duration'] ?? 0,
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -61,7 +61,7 @@ class ChapterList extends FrontendService
|
||||
return $chapters;
|
||||
}
|
||||
|
||||
protected function getLearningMappings($courseId, $userId, $planId)
|
||||
protected function getLearningMapping($courseId, $userId, $planId)
|
||||
{
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
@ -71,17 +71,17 @@ class ChapterList extends FrontendService
|
||||
return [];
|
||||
}
|
||||
|
||||
$mappings = [];
|
||||
$mapping = [];
|
||||
|
||||
foreach ($userLearnings as $learning) {
|
||||
$mappings[$learning->chapter_id] = [
|
||||
$mapping[$learning->chapter_id] = [
|
||||
'progress' => $learning->progress,
|
||||
'duration' => $learning->duration,
|
||||
'consumed' => $learning->consumed,
|
||||
];
|
||||
}
|
||||
|
||||
return $mappings;
|
||||
return $mapping;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,10 +25,10 @@ class LiveList extends FrontendService
|
||||
return [];
|
||||
}
|
||||
|
||||
$courseMappings = [];
|
||||
$courseMapping = [];
|
||||
|
||||
foreach ($courses as $course) {
|
||||
$courseMappings[$course->id] = [
|
||||
$courseMapping[$course->id] = [
|
||||
'id' => $course->id,
|
||||
'title' => $course->title,
|
||||
];
|
||||
@ -51,7 +51,7 @@ class LiveList extends FrontendService
|
||||
|
||||
foreach ($pager->items as $item) {
|
||||
$items[] = [
|
||||
'course' => $courseMappings[$item->course_id],
|
||||
'course' => $courseMapping[$item->course_id],
|
||||
'chapter' => [
|
||||
'id' => $item->id,
|
||||
'title' => $item->title,
|
||||
|
@ -27,15 +27,26 @@
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.kg-login-form {
|
||||
.kg-login-wrap {
|
||||
width: 400px;
|
||||
margin: 100px auto;
|
||||
}
|
||||
|
||||
.kg-login-form {
|
||||
padding: 15px 10px 5px 10px;
|
||||
}
|
||||
|
||||
.kg-login-form .layui-input-block {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.kg-login-copyright {
|
||||
margin-top: -80px;
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.kg-input-inline {
|
||||
float: left;
|
||||
width: 250px;
|
||||
|
@ -1345,6 +1345,7 @@ body {
|
||||
height: 16px;
|
||||
line-height: 16px;
|
||||
padding: 0 3px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.user-card .type {
|
||||
@ -1379,7 +1380,7 @@ body {
|
||||
}
|
||||
|
||||
.group-list .user-card {
|
||||
height: 250px;
|
||||
height: 240px;
|
||||
}
|
||||
|
||||
.group-about {
|
||||
|
Loading…
x
Reference in New Issue
Block a user