mirror of
https://gitee.com/koogua/course-tencent-cloud.git
synced 2025-06-21 11:18:10 +08:00
设计群组管理
This commit is contained in:
parent
29cc05a4f9
commit
c88284e5b7
@ -19,6 +19,39 @@ class ImGroupUserList extends Builder
|
|||||||
return $relations;
|
return $relations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function handleUsers(array $relations)
|
||||||
|
{
|
||||||
|
$users = $this->getUsers($relations);
|
||||||
|
|
||||||
|
foreach ($relations as $key => $value) {
|
||||||
|
$relations[$key]['user'] = $users[$value['user_id']] ?? new \stdClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $relations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUsers(array $relations)
|
||||||
|
{
|
||||||
|
$ids = kg_array_column($relations, 'user_id');
|
||||||
|
|
||||||
|
$userRepo = new UserRepo();
|
||||||
|
|
||||||
|
$columns = ['id', 'name', 'avatar', 'about', 'vip'];
|
||||||
|
|
||||||
|
$users = $userRepo->findByIds($ids, $columns);
|
||||||
|
|
||||||
|
$baseUrl = kg_ci_base_url();
|
||||||
|
|
||||||
|
$result = [];
|
||||||
|
|
||||||
|
foreach ($users->toArray() as $user) {
|
||||||
|
$user['avatar'] = $baseUrl . $user['avatar'];
|
||||||
|
$result[$user['id']] = $user;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
public function getGroups(array $relations)
|
public function getGroups(array $relations)
|
||||||
{
|
{
|
||||||
$ids = kg_array_column($relations, 'group_id');
|
$ids = kg_array_column($relations, 'group_id');
|
||||||
|
@ -51,15 +51,16 @@ class OrderController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Get("/{id:[0-9]+}/statuses", name="admin.order.statuses")
|
* @Get("/{id:[0-9]+}/status/history", name="admin.order.status_history")
|
||||||
*/
|
*/
|
||||||
public function statusesAction($id)
|
public function statusHistoryAction($id)
|
||||||
{
|
{
|
||||||
$orderService = new OrderService();
|
$orderService = new OrderService();
|
||||||
|
|
||||||
$statuses = $orderService->getStatusHistory($id);
|
$statusHistory = $orderService->getStatusHistory($id);
|
||||||
|
|
||||||
$this->view->setVar('statuses', $statuses);
|
$this->view->pick('order/status_history');
|
||||||
|
$this->view->setVar('status_history', $statusHistory);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -51,15 +51,16 @@ class RefundController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Get("/{id:[0-9]+}/statuses", name="admin.refund.statuses")
|
* @Get("/{id:[0-9]+}/status/history", name="admin.refund.status_history")
|
||||||
*/
|
*/
|
||||||
public function statusesAction($id)
|
public function statusHistoryAction($id)
|
||||||
{
|
{
|
||||||
$refundService = new RefundService();
|
$refundService = new RefundService();
|
||||||
|
|
||||||
$statuses = $refundService->getStatusHistory($id);
|
$statusHistory = $refundService->getStatusHistory($id);
|
||||||
|
|
||||||
$this->view->setVar('statuses', $statuses);
|
$this->view->pick('refund/status_history');
|
||||||
|
$this->view->setVar('status_history', $statusHistory);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,15 +51,16 @@ class TradeController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Get("/{id:[0-9]+}/statuses", name="admin.trade.statuses")
|
* @Get("/{id:[0-9]+}/status/history", name="admin.trade.status_history")
|
||||||
*/
|
*/
|
||||||
public function statusesAction($id)
|
public function statusHistoryAction($id)
|
||||||
{
|
{
|
||||||
$tradeService = new TradeService();
|
$tradeService = new TradeService();
|
||||||
|
|
||||||
$statuses = $tradeService->getStatusHistory($id);
|
$statusHistory = $tradeService->getStatusHistory($id);
|
||||||
|
|
||||||
$this->view->setVar('statuses', $statuses);
|
$this->view->pick('trade/status_history');
|
||||||
|
$this->view->setVar('status_history', $statusHistory);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% set order_status_url = url({'for':'admin.order.statuses','id':order.id}) %}
|
{% set order_sh_url = url({'for':'admin.order.status_history','id':order.id}) %}
|
||||||
|
|
||||||
<fieldset class="layui-elem-field layui-field-title">
|
<fieldset class="layui-elem-field layui-field-title">
|
||||||
<legend>订单信息</legend>
|
<legend>订单信息</legend>
|
||||||
@ -13,32 +13,13 @@
|
|||||||
<td>订单金额</td>
|
<td>订单金额</td>
|
||||||
<td>订单类型</td>
|
<td>订单类型</td>
|
||||||
<td>订单状态</td>
|
<td>订单状态</td>
|
||||||
<td>历史状态</td>
|
|
||||||
<td>创建时间</td>
|
<td>创建时间</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ item_info(order) }}</td>
|
<td>{{ item_info(order) }}</td>
|
||||||
<td>{{ '¥%0.2f'|format(order.amount) }}</td>
|
<td>{{ '¥%0.2f'|format(order.amount) }}</td>
|
||||||
<td>{{ item_type(order.item_type) }}</td>
|
<td>{{ item_type(order.item_type) }}</td>
|
||||||
<td>{{ order_status(order.status) }}</td>
|
<td><a class="kg-status-history" href="javascript:" title="查看历史状态" data-url="{{ order_sh_url }}">{{ order_status(order.status) }}</a></td>
|
||||||
<td>
|
|
||||||
<button class="layui-btn layui-btn-xs layui-bg-green order-status" data-url="{{ order_status_url }}">详情</button>
|
|
||||||
</td>
|
|
||||||
<td>{{ date('Y-m-d H:i:s',order.create_time) }}</td>
|
<td>{{ date('Y-m-d H:i:s',order.create_time) }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<script>
|
|
||||||
layui.use(['jquery', 'layer'], function () {
|
|
||||||
var $ = layui.jquery;
|
|
||||||
var layer = layui.layer;
|
|
||||||
$('.order-status').on('click', function () {
|
|
||||||
layer.open({
|
|
||||||
type: 2,
|
|
||||||
title: '历史状态',
|
|
||||||
content: $(this).data('url'),
|
|
||||||
area: ['640px', '320px']
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
@ -24,13 +24,15 @@
|
|||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
{% for item in refunds %}
|
{% for item in refunds %}
|
||||||
|
{% set refund_sh_url = url({'for':'admin.refund.status_history','id':item.id}) %}
|
||||||
|
{% set refund_show_url = url({'for':'admin.refund.show','id':item.id}) %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ item.sn }}</td>
|
<td>{{ item.sn }}</td>
|
||||||
<td>{{ '¥%0.2f'|format(item.amount) }}</td>
|
<td>{{ '¥%0.2f'|format(item.amount) }}</td>
|
||||||
<td><a href="javascript:" title="{{ item.apply_note }}">{{ substr(item.apply_note,0,15) }}</td>
|
<td><a href="javascript:" title="{{ item.apply_note }}">{{ substr(item.apply_note,0,15) }}</td>
|
||||||
<td>{{ refund_status(item.status) }}</td>
|
<td><a class="kg-status-history" href="javascript:" title="查看历史状态" data-url="{{ refund_sh_url }}">{{ refund_status(item.status) }}</a></td>
|
||||||
<td>{{ date('Y-m-d H:i:s',item.create_time) }}</td>
|
<td>{{ date('Y-m-d H:i:s',item.create_time) }}</td>
|
||||||
<td><a class="layui-btn layui-btn-sm" href="{{ url({'for':'admin.refund.show','id':item.id}) }}">详情</a></td>
|
<td><a class="layui-btn layui-btn-sm" href="{{ refund_show_url }}">详情</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
@ -51,13 +53,15 @@
|
|||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
{% for item in trades %}
|
{% for item in trades %}
|
||||||
|
{% set trade_sh_url = url({'for':'admin.trade.status_history','id':item.id}) %}
|
||||||
|
{% set trade_show_url = url({'for':'admin.trade.show','id':item.id}) %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ item.sn }}</td>
|
<td>{{ item.sn }}</td>
|
||||||
<td>{{ '¥%0.2f'|format(item.amount) }}</td>
|
<td>{{ '¥%0.2f'|format(item.amount) }}</td>
|
||||||
<td>{{ channel_type(item.channel) }}</td>
|
<td>{{ channel_type(item.channel) }}</td>
|
||||||
<td>{{ trade_status(item.status) }}</td>
|
<td><a class="kg-status-history" href="javascript:" title="查看历史状态" data-url="{{ trade_sh_url }}">{{ trade_status(item.status) }}</a></td>
|
||||||
<td>{{ date('Y-m-d H:i:s',item.create_time) }}</td>
|
<td>{{ date('Y-m-d H:i:s',item.create_time) }}</td>
|
||||||
<td><a class="layui-btn layui-btn-sm" href="{{ url({'for':'admin.trade.show','id':item.id}) }}">详情</a></td>
|
<td><a class="layui-btn layui-btn-sm" href="{{ trade_show_url }}">详情</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
@ -65,3 +69,5 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{{ partial('order/user_info') }}
|
{{ partial('order/user_info') }}
|
||||||
|
|
||||||
|
{{ js_include('admin/js/status-history.js') }}
|
@ -5,7 +5,7 @@
|
|||||||
<td>状态</td>
|
<td>状态</td>
|
||||||
<td>时间</td>
|
<td>时间</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% for item in statuses %}
|
{% for item in status_history %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ order_status(item.status) }}</td>
|
<td>{{ order_status(item.status) }}</td>
|
||||||
<td>{{ date('Y-m-d H:i:s',item.create_time) }}</td>
|
<td>{{ date('Y-m-d H:i:s',item.create_time) }}</td>
|
@ -2,7 +2,8 @@
|
|||||||
{{ partial('trade/macro') }}
|
{{ partial('trade/macro') }}
|
||||||
{{ partial('refund/macro') }}
|
{{ partial('refund/macro') }}
|
||||||
|
|
||||||
{% set refund_status_url = url({'for':'admin.refund.statuses','id':refund.id}) %}
|
{% set refund_sh_url = url({'for':'admin.refund.status_history','id':refund.id}) %}
|
||||||
|
{% set refund_review_url = url({'for':'admin.refund.review','id':refund.id}) %}
|
||||||
|
|
||||||
<fieldset class="layui-elem-field layui-field-title">
|
<fieldset class="layui-elem-field layui-field-title">
|
||||||
<legend>退款信息</legend>
|
<legend>退款信息</legend>
|
||||||
@ -14,7 +15,6 @@
|
|||||||
<th>退款金额</th>
|
<th>退款金额</th>
|
||||||
<th>退款备注</th>
|
<th>退款备注</th>
|
||||||
<th>退款状态</th>
|
<th>退款状态</th>
|
||||||
<th>历史状态</th>
|
|
||||||
<th>创建时间</th>
|
<th>创建时间</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@ -28,10 +28,7 @@
|
|||||||
<p class="layui-elip" title="{{ refund.review_note }}">审核意见:{{ refund.review_note }}</p>
|
<p class="layui-elip" title="{{ refund.review_note }}">审核意见:{{ refund.review_note }}</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td>{{ refund_status(refund.status) }}</td>
|
<td><a class="kg-status-history" href="javascript:" title="查看历史状态" data-url="{{ refund_sh_url }}">{{ refund_status(refund.status) }}</a></td>
|
||||||
<td>
|
|
||||||
<button class="layui-btn layui-btn-xs layui-bg-green refund-status" data-url="{{ refund_status_url }}">详情</button>
|
|
||||||
</td>
|
|
||||||
<td>{{ date('Y-m-d H:i:s',refund.create_time) }}</td>
|
<td>{{ date('Y-m-d H:i:s',refund.create_time) }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@ -39,7 +36,7 @@
|
|||||||
<br>
|
<br>
|
||||||
|
|
||||||
{% if refund.status == 'pending' %}
|
{% if refund.status == 'pending' %}
|
||||||
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.refund.review','id':refund.id}) }}">
|
<form class="layui-form kg-form" method="POST" action="{{ refund_review_url }}">
|
||||||
<fieldset class="layui-elem-field layui-field-title">
|
<fieldset class="layui-elem-field layui-field-title">
|
||||||
<legend>审核退款</legend>
|
<legend>审核退款</legend>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
@ -82,17 +79,4 @@
|
|||||||
|
|
||||||
{{ partial('order/user_info') }}
|
{{ partial('order/user_info') }}
|
||||||
|
|
||||||
<script>
|
{{ js_include('admin/js/status-history.js') }}
|
||||||
layui.use(['jquery', 'layer'], function () {
|
|
||||||
var $ = layui.jquery;
|
|
||||||
var layer = layui.layer;
|
|
||||||
$('.refund-status').on('click', function () {
|
|
||||||
layer.open({
|
|
||||||
type: 2,
|
|
||||||
title: '历史状态',
|
|
||||||
content: $(this).data('url'),
|
|
||||||
area: ['640px', '320px']
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
@ -5,7 +5,7 @@
|
|||||||
<td>状态</td>
|
<td>状态</td>
|
||||||
<td>时间</td>
|
<td>时间</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% for item in statuses %}
|
{% for item in status_history %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ refund_status(item.status) }}</td>
|
<td>{{ refund_status(item.status) }}</td>
|
||||||
<td>{{ date('Y-m-d H:i:s',item.create_time) }}</td>
|
<td>{{ date('Y-m-d H:i:s',item.create_time) }}</td>
|
@ -6,9 +6,11 @@
|
|||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
{% set trade_refund_url = url({'for':'admin.trade.refund','id':trade.id}) %}
|
||||||
|
|
||||||
<div class="kg-text-center">
|
<div class="kg-text-center">
|
||||||
{% if trade.status == 'finished' %}
|
{% if trade.status == 'finished' %}
|
||||||
<button class="kg-refund layui-btn layui-bg-green" data-url="{{ url({'for':'admin.trade.refund','id':trade.id}) }}">申请退款</button>
|
<button class="kg-refund layui-btn layui-bg-green" data-url="{{ trade_refund_url }}">申请退款</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<button class="kg-back layui-btn layui-bg-gray">返回上页</button>
|
<button class="kg-back layui-btn layui-bg-gray">返回上页</button>
|
||||||
</div>
|
</div>
|
||||||
@ -27,13 +29,15 @@
|
|||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
{% for item in refunds %}
|
{% for item in refunds %}
|
||||||
|
{% set refund_sh_url = url({'for':'admin.refund.status_history','id':item.id}) %}
|
||||||
|
{% set refund_show_url = url({'for':'admin.refund.show','id':item.id}) %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ item.sn }}</td>
|
<td>{{ item.sn }}</td>
|
||||||
<td>{{ '¥%0.2f'|format(item.amount) }}</td>
|
<td>{{ '¥%0.2f'|format(item.amount) }}</td>
|
||||||
<td><a href="javascript:" title="{{ item.apply_note }}">{{ substr(item.apply_note,0,15) }}</td>
|
<td><a href="javascript:" title="{{ item.apply_note }}">{{ substr(item.apply_note,0,15) }}</td>
|
||||||
<td>{{ refund_status(item) }}</td>
|
<td><a class="kg-status-history" href="javascript:" title="查看历史状态" data-url="{{ refund_sh_url }}">{{ refund_status(item) }}</a></td>
|
||||||
<td>{{ date('Y-m-d H:i:s',item.create_time) }}</td>
|
<td>{{ date('Y-m-d H:i:s',item.create_time) }}</td>
|
||||||
<td><a class="layui-btn layui-btn-sm" href="{{ url({'for':'admin.refund.show','id':item.id}) }}">详情</a></td>
|
<td><a class="layui-btn layui-btn-sm" href="{{ refund_show_url }}">详情</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
@ -47,6 +51,8 @@
|
|||||||
|
|
||||||
{{ partial('order/user_info') }}
|
{{ partial('order/user_info') }}
|
||||||
|
|
||||||
|
{{ js_include('admin/js/status-history.js') }}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
layui.use(['jquery', 'layer'], function () {
|
layui.use(['jquery', 'layer'], function () {
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<td>状态</td>
|
<td>状态</td>
|
||||||
<td>时间</td>
|
<td>时间</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% for item in statuses %}
|
{% for item in status_history %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ trade_status(item.status) }}</td>
|
<td>{{ trade_status(item.status) }}</td>
|
||||||
<td>{{ date('Y-m-d H:i:s',item.create_time) }}</td>
|
<td>{{ date('Y-m-d H:i:s',item.create_time) }}</td>
|
@ -1,4 +1,4 @@
|
|||||||
{% set trade_status_url = url({'for':'admin.trade.statuses','id':trade.id}) %}
|
{% set trade_sh_url = url({'for':'admin.trade.status_history','id':trade.id}) %}
|
||||||
|
|
||||||
<fieldset class="layui-elem-field layui-field-title">
|
<fieldset class="layui-elem-field layui-field-title">
|
||||||
<legend>交易信息</legend>
|
<legend>交易信息</legend>
|
||||||
@ -10,32 +10,13 @@
|
|||||||
<th>交易金额</th>
|
<th>交易金额</th>
|
||||||
<th>交易平台</th>
|
<th>交易平台</th>
|
||||||
<th>交易状态</th>
|
<th>交易状态</th>
|
||||||
<th>历史状态</th>
|
|
||||||
<th>创建时间</th>
|
<th>创建时间</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ trade.sn }}</td>
|
<td>{{ trade.sn }}</td>
|
||||||
<td>{{ '¥%0.2f'|format(trade.amount) }}</td>
|
<td>{{ '¥%0.2f'|format(trade.amount) }}</td>
|
||||||
<td>{{ channel_type(trade.channel) }}</td>
|
<td>{{ channel_type(trade.channel) }}</td>
|
||||||
<td>{{ trade_status(trade.status) }}</td>
|
<td><a class="kg-status-history" href="javascript:" title="查看历史状态" data-url="{{ trade_sh_url }}">{{ trade_status(trade.status) }}</a></td>
|
||||||
<td>
|
|
||||||
<button class="layui-btn layui-btn-xs layui-bg-green trade-status" data-url="{{ trade_status_url }}">详情</button>
|
|
||||||
</td>
|
|
||||||
<td>{{ date('Y-m-d H:i:s',trade.create_time) }}</td>
|
<td>{{ date('Y-m-d H:i:s',trade.create_time) }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<script>
|
|
||||||
layui.use(['jquery', 'layer'], function () {
|
|
||||||
var $ = layui.jquery;
|
|
||||||
var layer = layui.layer;
|
|
||||||
$('.trade-status').on('click', function () {
|
|
||||||
layer.open({
|
|
||||||
type: 2,
|
|
||||||
title: '历史状态',
|
|
||||||
content: $(this).data('url'),
|
|
||||||
area: ['640px', '320px']
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
@ -147,14 +147,14 @@ class ImController extends LayerController
|
|||||||
{
|
{
|
||||||
$service = new ImService();
|
$service = new ImService();
|
||||||
|
|
||||||
$usersPager = $service->getNewUsers();
|
$userPager = $service->getNewUsers();
|
||||||
$groupsPager = $service->getNewGroups();
|
$groupPager = $service->getNewGroups();
|
||||||
|
|
||||||
$usersPager->items = kg_array_object($usersPager->items);
|
$userPager->items = kg_array_object($userPager->items);
|
||||||
$groupsPager->items = kg_array_object($groupsPager->items);
|
$groupPager->items = kg_array_object($groupPager->items);
|
||||||
|
|
||||||
$this->view->setVar('users_pager', $usersPager);
|
$this->view->setVar('user_pager', $userPager);
|
||||||
$this->view->setVar('groups_pager', $groupsPager);
|
$this->view->setVar('group_pager', $groupPager);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace App\Http\Web\Controllers;
|
namespace App\Http\Web\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Web\Services\ImGroup as ImGroupService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @RoutePrefix("/im/group")
|
* @RoutePrefix("/im/group")
|
||||||
*/
|
*/
|
||||||
@ -16,44 +18,52 @@ class ImGroupController extends Controller
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @Get("/{id:[0-9]+}/manage", name="web.im_group.manage")
|
|
||||||
*/
|
|
||||||
public function manageAction()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Get("/{id:[0-9]+}/users", name="web.im_group.users")
|
* @Get("/{id:[0-9]+}/users", name="web.im_group.users")
|
||||||
*/
|
*/
|
||||||
public function usersAction()
|
public function usersAction($id)
|
||||||
{
|
{
|
||||||
|
$service = new ImGroupService();
|
||||||
|
|
||||||
|
$group = $service->getGroup($id);
|
||||||
|
|
||||||
|
$pager = $service->getGroupUsers($id);
|
||||||
|
|
||||||
|
$pager->items = kg_array_object($pager->items);
|
||||||
|
|
||||||
|
$this->view->setVar('group', $group);
|
||||||
|
$this->view->setVar('pager', $pager);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Post("/user/delete", name="web.im_group.delete_user")
|
* @Post("/{id:[0-9]+}/update", name="web.im_group.update")
|
||||||
*/
|
*/
|
||||||
public function deleteUserAction()
|
public function updateAction()
|
||||||
{
|
{
|
||||||
|
$service = new ImGroupService();
|
||||||
|
|
||||||
|
$service->updateGroup($id);
|
||||||
|
|
||||||
|
$content = ['msg' => '更新群组成功'];
|
||||||
|
|
||||||
|
return $this->jsonSuccess($content);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Post("/user/block", name="web.im_group.block_user")
|
* @Post("/{gid:[0-9]+}/user/{uid:[0-9]+}/delete", name="web.im_group.delete_user")
|
||||||
*/
|
*/
|
||||||
public function blockUserAction()
|
public function deleteGroupUserAction($gid, $uid)
|
||||||
{
|
{
|
||||||
|
$service = new ImGroupService();
|
||||||
|
|
||||||
}
|
$service->deleteGroupUser($gid, $uid);
|
||||||
|
|
||||||
/**
|
$content = [
|
||||||
* @Post("/user/unblock", name="web.im_group.unblock_user")
|
'location' => $this->request->getHTTPReferer(),
|
||||||
*/
|
'msg' => '移除用户成功',
|
||||||
public function unblockUserAction()
|
];
|
||||||
{
|
|
||||||
|
|
||||||
|
return $this->jsonSuccess($content);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ class Im extends Service
|
|||||||
|
|
||||||
$validator = new ImGroupValidator();
|
$validator = new ImGroupValidator();
|
||||||
|
|
||||||
$group = $validator->checkGroupCache($id);
|
$group = $validator->checkGroup($id);
|
||||||
|
|
||||||
$groupRepo = new ImGroupRepo();
|
$groupRepo = new ImGroupRepo();
|
||||||
|
|
||||||
|
@ -2,27 +2,109 @@
|
|||||||
|
|
||||||
namespace App\Http\Web\Services;
|
namespace App\Http\Web\Services;
|
||||||
|
|
||||||
|
use App\Builders\ImGroupUserList as ImGroupUserListBuilder;
|
||||||
|
use App\Library\Paginator\Query as PagerQuery;
|
||||||
|
use App\Repos\ImGroupUser as ImGroupUserRepo;
|
||||||
|
use App\Validators\ImGroup as ImGroupValidator;
|
||||||
|
use App\Validators\ImGroupUser as ImGroupUserValidator;
|
||||||
|
|
||||||
class ImGroup extends Service
|
class ImGroup extends Service
|
||||||
{
|
{
|
||||||
|
|
||||||
public function getGroups()
|
public function getGroups()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateGroup($id)
|
||||||
|
{
|
||||||
|
$post = $this->request->getPost();
|
||||||
|
|
||||||
|
$user = $this->getLoginUser();
|
||||||
|
|
||||||
|
$validator = new ImGroupValidator();
|
||||||
|
|
||||||
|
$group = $validator->checkGroup($id);
|
||||||
|
|
||||||
|
$validator->checkOwner($user->id, $group->owner_id);
|
||||||
|
|
||||||
|
$data = [];
|
||||||
|
|
||||||
|
$data['name'] = $validator->checkName($post['name']);
|
||||||
|
$data['about'] = $validator->checkAbout($post['about']);
|
||||||
|
|
||||||
|
$group->update($data);
|
||||||
|
|
||||||
|
return $group;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getGroup($id)
|
||||||
|
{
|
||||||
|
$validator = new ImGroupValidator();
|
||||||
|
|
||||||
|
return $validator->checkGroup($id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getGroupUsers($id)
|
public function getGroupUsers($id)
|
||||||
{
|
{
|
||||||
|
$validator = new ImGroupValidator();
|
||||||
|
|
||||||
|
$group = $validator->checkGroup($id);
|
||||||
|
|
||||||
|
$pagerQuery = new PagerQuery();
|
||||||
|
|
||||||
|
$params = $pagerQuery->getParams();
|
||||||
|
|
||||||
|
$params['group_id'] = $group->id;
|
||||||
|
|
||||||
|
$sort = $pagerQuery->getSort();
|
||||||
|
$page = $pagerQuery->getPage();
|
||||||
|
$limit = $pagerQuery->getLimit();
|
||||||
|
|
||||||
|
$repo = new ImGroupUserRepo();
|
||||||
|
|
||||||
|
$pager = $repo->paginate($params, $sort, $page, $limit);
|
||||||
|
|
||||||
|
return $this->handleGroupUsers($pager);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function deleteUser()
|
public function deleteGroupUser($groupId, $userId)
|
||||||
{
|
{
|
||||||
|
$loginUser = $this->getLoginUser();
|
||||||
|
|
||||||
|
$validator = new ImGroupUserValidator();
|
||||||
|
|
||||||
|
$group = $validator->checkGroup($groupId);
|
||||||
|
|
||||||
|
$validator->checkOwner($loginUser->id, $group->owner_id);
|
||||||
|
|
||||||
|
$groupUser = $validator->checkGroupUser($groupId, $userId);
|
||||||
|
|
||||||
|
$groupUser->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function blockUser()
|
protected function handleGroupUsers($pager)
|
||||||
{
|
{
|
||||||
|
if ($pager->total_items == 0) {
|
||||||
|
return $pager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function unblockUser()
|
$builder = new ImGroupUserListBuilder();
|
||||||
{
|
|
||||||
|
$relations = $pager->items->toArray();
|
||||||
|
|
||||||
|
$users = $builder->getUsers($relations);
|
||||||
|
|
||||||
|
$items = [];
|
||||||
|
|
||||||
|
foreach ($relations as $relation) {
|
||||||
|
$user = $users[$relation['user_id']] ?? new \stdClass();
|
||||||
|
$items[] = $user;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pager->items = $items;
|
||||||
|
|
||||||
|
return $pager;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -15,10 +15,10 @@
|
|||||||
</ul>
|
</ul>
|
||||||
<div class="layui-tab-content">
|
<div class="layui-tab-content">
|
||||||
<div class="layui-tab-item layui-show" id="tab-users">
|
<div class="layui-tab-item layui-show" id="tab-users">
|
||||||
{{ partial('im/find_users',{'pager':users_pager}) }}
|
{{ partial('im/find_users',{'pager':user_pager}) }}
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-tab-item" id="tab-groups">
|
<div class="layui-tab-item" id="tab-groups">
|
||||||
{{ partial('im/find_groups',{'pager':groups_pager}) }}
|
{{ partial('im/find_groups',{'pager':group_pager}) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="name layui-elip" title="{{ item.name|e }}">{{ item.name }}</div>
|
<div class="name layui-elip" title="{{ item.name|e }}">{{ item.name }}</div>
|
||||||
<div class="action">
|
<div class="action">
|
||||||
<a href="javascript:" class="layui-badge-rim apply-friend" data-id="{{ item.id }}" data-name="{{ item.name }}" data-avatar="{{ item.avatar }}">加为好友</a>
|
<button class="layui-btn apply-friend" data-id="{{ item.id }}" data-name="{{ item.name }}" data-avatar="{{ item.avatar }}">加为好友</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
23
app/Http/Web/Views/im_group/edit.volt
Normal file
23
app/Http/Web/Views/im_group/edit.volt
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{% set update_group_url = url({'for':'web.im_group.update','id':group.id}) %}
|
||||||
|
|
||||||
|
<form class="layui-form" method="post" action="{{ update_group_url }}">
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">名称</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input class="layui-input" type="text" name="name" value="{{ group.name }}" lay-verify="required">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">简介</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<textarea class="layui-textarea" name="about" lay-verify="required">{{ group.about }}</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label"></label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<button class="layui-btn" lay-submit="true" lay-filter="go">提交</button>
|
||||||
|
<button class="layui-btn layui-btn-primary" type="reset">重置</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
34
app/Http/Web/Views/im_group/manage.volt
Normal file
34
app/Http/Web/Views/im_group/manage.volt
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{% extends 'templates/layer.volt' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<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">
|
||||||
|
{% if item.vip == 1 %}
|
||||||
|
<span class="vip">会员</span>
|
||||||
|
{% endif %}
|
||||||
|
<div class="avatar">
|
||||||
|
<a href="javascript:" title="{{ item.about }}"><img src="{{ item.avatar }}" alt="{{ item.name }}"></a>
|
||||||
|
</div>
|
||||||
|
<div class="name layui-elip" title="{{ item.name }}">{{ item.name }}</div>
|
||||||
|
<div class="action">
|
||||||
|
<a href="javascript:" class="layui-badge-rim apply-friend" data-id="{{ item.id }}" data-name="{{ item.name }}" data-avatar="{{ item.avatar }}">加为好友</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ partial('partials/pager') }}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block include_js %}
|
||||||
|
|
||||||
|
{{ js_include('web/js/my.im.js') }}
|
||||||
|
|
||||||
|
{% endblock %}
|
31
app/Http/Web/Views/im_group/users.volt
Normal file
31
app/Http/Web/Views/im_group/users.volt
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
{% extends 'templates/layer.volt' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="bg-wrap">
|
||||||
|
<div class="im-user-list clearfix">
|
||||||
|
<div class="layui-row layui-col-space20">
|
||||||
|
{% for item in pager.items %}
|
||||||
|
{% set delete_url = url({'for':'web.im_group.delete_user','gid':group.id,'uid':item.id}) %}
|
||||||
|
<div class="layui-col-md2">
|
||||||
|
<div class="user-card">
|
||||||
|
{% if item.vip == 1 %}
|
||||||
|
<span class="vip">会员</span>
|
||||||
|
{% endif %}
|
||||||
|
<div class="avatar">
|
||||||
|
<a href="javascript:" title="{{ item.about }}"><img src="{{ item.avatar }}" alt="{{ item.name }}"></a>
|
||||||
|
</div>
|
||||||
|
<div class="name layui-elip" title="{{ item.name }}">{{ item.name }}</div>
|
||||||
|
<div class="action">
|
||||||
|
<button class="layui-btn kg-delete" data-tips="你确定要移除该用户吗?" data-url="{{ delete_url }}">移除</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ partial('partials/pager') }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
@ -34,7 +34,7 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{% for item in pager.items %}
|
{% for item in pager.items %}
|
||||||
{% set owner_url = url({'for':'web.user.show','id':item.owner.id}) %}
|
{% set owner_url = url({'for':'web.user.show','id':item.owner.id}) %}
|
||||||
{% set manage_url = url({'for':'web.im_group.manage','id':item.id}) %}
|
{% set manage_url = url({'for':'web.im_group.users','id':item.id}) %}
|
||||||
{% set delete_url = url({'for':'web.im.quit_group','id':item.id}) %}
|
{% set delete_url = url({'for':'web.im.quit_group','id':item.id}) %}
|
||||||
<tr>
|
<tr>
|
||||||
<td><span title="{{ item.about }}">{{ item.name }}</span> {{ type_info(item.type) }}</td>
|
<td><span title="{{ item.about }}">{{ item.name }}</span> {{ type_info(item.type) }}</td>
|
||||||
@ -42,7 +42,7 @@
|
|||||||
<td><span class="layui-badge-rim">{{ item.user_count }}</span></td>
|
<td><span class="layui-badge-rim">{{ item.user_count }}</span></td>
|
||||||
<td>
|
<td>
|
||||||
{% if auth_user.id == item.owner.id %}
|
{% if auth_user.id == item.owner.id %}
|
||||||
<button class="layui-btn layui-btn-sm layui-bg-blue" data-url="{{ manage_url }}">管理</button>
|
<button class="layui-btn layui-btn-sm layui-bg-blue btn-manage-group" data-url="{{ manage_url }}">管理</button>
|
||||||
{% else %}
|
{% else %}
|
||||||
<button class="layui-btn layui-btn-sm kg-delete" data-tips="确定要退出吗?" data-url="{{ delete_url }}">退出</button>
|
<button class="layui-btn layui-btn-sm kg-delete" data-tips="确定要退出吗?" data-url="{{ delete_url }}">退出</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -61,6 +61,6 @@
|
|||||||
|
|
||||||
{% block include_js %}
|
{% block include_js %}
|
||||||
|
|
||||||
{{ js_include('web/js/my.im.js') }}
|
{{ js_include('web/js/my.js') }}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -14,16 +14,13 @@
|
|||||||
{% block link_css %}{% endblock %}
|
{% block link_css %}{% endblock %}
|
||||||
{% block inline_css %}{% endblock %}
|
{% block inline_css %}{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
<body class="full">
|
<body class="main">
|
||||||
|
|
||||||
<div id="header">
|
<div id="header">
|
||||||
{{ partial('partials/header') }}
|
{{ partial('partials/header') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="main" class="layui-main">
|
<div id="main" class="layui-main">
|
||||||
{% block content %}{% endblock %}
|
{% block content %}{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="footer">
|
<div id="footer">
|
||||||
{{ partial('partials/footer') }}
|
{{ partial('partials/footer') }}
|
||||||
</div>
|
</div>
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -8,9 +8,9 @@
|
|||||||
<span class="vip">会员</span>
|
<span class="vip">会员</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="avatar">
|
<div class="avatar">
|
||||||
<a href="javascript:" title="{{ item.about|e }}"><img src="{{ item.avatar }}" alt="{{ item.name }}"></a>
|
<a href="javascript:" title="{{ item.about }}"><img src="{{ item.avatar }}" alt="{{ item.name }}"></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="name layui-elip" title="{{ item.name|e }}">{{ item.name }}</div>
|
<div class="name layui-elip" title="{{ item.name }}">{{ item.name }}</div>
|
||||||
<div class="action">
|
<div class="action">
|
||||||
<a href="javascript:" class="layui-badge-rim apply-friend" data-id="{{ item.id }}" data-name="{{ item.name }}" data-avatar="{{ item.avatar }}">加为好友</a>
|
<a href="javascript:" class="layui-badge-rim apply-friend" data-id="{{ item.id }}" data-name="{{ item.name }}" data-avatar="{{ item.avatar }}">加为好友</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'templates/full.volt' %}
|
{% extends 'templates/main.volt' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
514
app/Library/Collection.php
Normal file
514
app/Library/Collection.php
Normal file
@ -0,0 +1,514 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Library;
|
||||||
|
|
||||||
|
use ArrayAccess;
|
||||||
|
use ArrayIterator;
|
||||||
|
use Countable;
|
||||||
|
use IteratorAggregate;
|
||||||
|
use JsonSerializable;
|
||||||
|
|
||||||
|
class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
|
||||||
|
{
|
||||||
|
|
||||||
|
protected $items = [];
|
||||||
|
|
||||||
|
public function __construct($items = [])
|
||||||
|
{
|
||||||
|
$this->items = $this->convertToArray($items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function make($items = [])
|
||||||
|
{
|
||||||
|
return new static($items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isEmpty()
|
||||||
|
{
|
||||||
|
return empty($this->items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toArray()
|
||||||
|
{
|
||||||
|
return array_map(function ($value) {
|
||||||
|
return ($value instanceof self) ? $value->toArray() : $value;
|
||||||
|
}, $this->items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function all()
|
||||||
|
{
|
||||||
|
return $this->items;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合并数组
|
||||||
|
*
|
||||||
|
* @param mixed $items
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public function merge($items)
|
||||||
|
{
|
||||||
|
return new static(array_merge($this->items, $this->convertToArray($items)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 交换数组中的键和值
|
||||||
|
*
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public function flip()
|
||||||
|
{
|
||||||
|
return new static(array_flip($this->items));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按指定键整理数据
|
||||||
|
*
|
||||||
|
* @param mixed $items 数据
|
||||||
|
* @param string $indexKey 键名
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function dictionary($items = null, &$indexKey = null)
|
||||||
|
{
|
||||||
|
if ($items instanceof self) {
|
||||||
|
$items = $items->all();
|
||||||
|
}
|
||||||
|
|
||||||
|
$items = is_null($items) ? $this->items : $items;
|
||||||
|
|
||||||
|
if (isset($indexKey) && is_string($indexKey)) {
|
||||||
|
return array_column($items, null, $indexKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $items;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 比较数组,返回差集
|
||||||
|
*
|
||||||
|
* @param mixed $items 数据
|
||||||
|
* @param string $indexKey 指定比较的键名
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public function diff($items, $indexKey = null)
|
||||||
|
{
|
||||||
|
if ($this->isEmpty() || is_scalar($this->items[0])) {
|
||||||
|
return new static(array_diff($this->items, $this->convertToArray($items)));
|
||||||
|
}
|
||||||
|
|
||||||
|
$diff = [];
|
||||||
|
|
||||||
|
$dictionary = $this->dictionary($items, $indexKey);
|
||||||
|
|
||||||
|
if (is_string($indexKey)) {
|
||||||
|
foreach ($this->items as $item) {
|
||||||
|
if (!isset($dictionary[$item[$indexKey]])) {
|
||||||
|
$diff[] = $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new static($diff);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 比较数组,返回交集
|
||||||
|
*
|
||||||
|
* @param mixed $items 数据
|
||||||
|
* @param string $indexKey 指定比较的键名
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public function intersect($items, $indexKey = null)
|
||||||
|
{
|
||||||
|
if ($this->isEmpty() || is_scalar($this->items[0])) {
|
||||||
|
return new static(array_diff($this->items, $this->convertToArray($items)));
|
||||||
|
}
|
||||||
|
|
||||||
|
$intersect = [];
|
||||||
|
|
||||||
|
$dictionary = $this->dictionary($items, $indexKey);
|
||||||
|
|
||||||
|
if (is_string($indexKey)) {
|
||||||
|
foreach ($this->items as $item) {
|
||||||
|
if (isset($dictionary[$item[$indexKey]])) {
|
||||||
|
$intersect[] = $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new static($intersect);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回数组中所有的键名
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function keys()
|
||||||
|
{
|
||||||
|
$current = current($this->items);
|
||||||
|
|
||||||
|
if (is_scalar($current)) {
|
||||||
|
$array = $this->items;
|
||||||
|
} elseif (is_array($current)) {
|
||||||
|
$array = $current;
|
||||||
|
} else {
|
||||||
|
$array = $current->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_keys($array);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除数组的最后一个元素(出栈)
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function pop()
|
||||||
|
{
|
||||||
|
return array_pop($this->items);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过使用用户自定义函数,以字符串返回数组
|
||||||
|
*
|
||||||
|
* @param callable $callback
|
||||||
|
* @param mixed $initial
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function reduce(callable $callback, $initial = null)
|
||||||
|
{
|
||||||
|
return array_reduce($this->items, $callback, $initial);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 以相反的顺序返回数组。
|
||||||
|
*
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public function reverse()
|
||||||
|
{
|
||||||
|
return new static(array_reverse($this->items));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除数组中首个元素,并返回被删除元素的值
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function shift()
|
||||||
|
{
|
||||||
|
return array_shift($this->items);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在数组结尾插入一个元素
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
* @param mixed $key
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function push($value, $key = null)
|
||||||
|
{
|
||||||
|
if (is_null($key)) {
|
||||||
|
$this->items[] = $value;
|
||||||
|
} else {
|
||||||
|
$this->items[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 把一个数组分割为新的数组块.
|
||||||
|
*
|
||||||
|
* @param int $size
|
||||||
|
* @param bool $preserveKeys
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public function chunk($size, $preserveKeys = false)
|
||||||
|
{
|
||||||
|
$chunks = [];
|
||||||
|
|
||||||
|
foreach (array_chunk($this->items, $size, $preserveKeys) as $chunk) {
|
||||||
|
$chunks[] = new static($chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new static($chunks);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在数组开头插入一个元素
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
* @param mixed $key
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function unshift($value, $key = null)
|
||||||
|
{
|
||||||
|
if (is_null($key)) {
|
||||||
|
array_unshift($this->items, $value);
|
||||||
|
} else {
|
||||||
|
$this->items = [$key => $value] + $this->items;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 给每个元素执行个回调
|
||||||
|
*
|
||||||
|
* @param callable $callback
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function each(callable $callback)
|
||||||
|
{
|
||||||
|
foreach ($this->items as $key => $item) {
|
||||||
|
$result = $callback($item, $key);
|
||||||
|
if (false === $result) {
|
||||||
|
break;
|
||||||
|
} elseif (!is_object($item)) {
|
||||||
|
$this->items[$key] = $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用回调函数处理数组中的元素
|
||||||
|
*
|
||||||
|
* @param callable|null $callback
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public function map(callable $callback)
|
||||||
|
{
|
||||||
|
return new static(array_map($callback, $this->items));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用回调函数过滤数组中的元素
|
||||||
|
*
|
||||||
|
* @param callable|null $callback
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public function filter(callable $callback = null)
|
||||||
|
{
|
||||||
|
if ($callback) {
|
||||||
|
return new static(array_filter($this->items, $callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new static(array_filter($this->items));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据字段条件过滤数组中的元素
|
||||||
|
*
|
||||||
|
* @param string $field 字段名
|
||||||
|
* @param mixed $operator 操作符
|
||||||
|
* @param mixed $value 数据
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public function where($field, $operator, $value = null)
|
||||||
|
{
|
||||||
|
if (is_null($value)) {
|
||||||
|
$value = $operator;
|
||||||
|
$operator = '=';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->filter(function ($data) use ($field, $operator, $value) {
|
||||||
|
|
||||||
|
if (strpos($field, '.')) {
|
||||||
|
list($field, $relation) = explode('.', $field);
|
||||||
|
$result = isset($data[$field][$relation]) ? $data[$field][$relation] : null;
|
||||||
|
} else {
|
||||||
|
$result = isset($data[$field]) ? $data[$field] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($operator) {
|
||||||
|
case '===':
|
||||||
|
return $result === $value;
|
||||||
|
case '!==':
|
||||||
|
return $result !== $value;
|
||||||
|
case '!=':
|
||||||
|
case '<>':
|
||||||
|
return $result != $value;
|
||||||
|
case '>':
|
||||||
|
return $result > $value;
|
||||||
|
case '>=':
|
||||||
|
return $result >= $value;
|
||||||
|
case '<':
|
||||||
|
return $result < $value;
|
||||||
|
case '<=':
|
||||||
|
return $result <= $value;
|
||||||
|
case 'like':
|
||||||
|
return is_string($result) && false !== strpos($result, $value);
|
||||||
|
case 'not_like':
|
||||||
|
return is_string($result) && false === strpos($result, $value);
|
||||||
|
case 'in':
|
||||||
|
return is_scalar($result) && in_array($result, $value, true);
|
||||||
|
case 'not_in':
|
||||||
|
return is_scalar($result) && !in_array($result, $value, true);
|
||||||
|
case 'between':
|
||||||
|
list($min, $max) = is_string($value) ? explode(',', $value) : $value;
|
||||||
|
return is_scalar($result) && $result >= $min && $result <= $max;
|
||||||
|
case 'not_between':
|
||||||
|
list($min, $max) = is_string($value) ? explode(',', $value) : $value;
|
||||||
|
return is_scalar($result) && $result > $max || $result < $min;
|
||||||
|
case '==':
|
||||||
|
case '=':
|
||||||
|
default:
|
||||||
|
return $result == $value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回数据中指定的一列
|
||||||
|
*
|
||||||
|
* @param mixed $columnKey 键名
|
||||||
|
* @param mixed $indexKey 作为索引值的列
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function column($columnKey, $indexKey = null)
|
||||||
|
{
|
||||||
|
return array_column($this->items, $columnKey, $indexKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对数组排序
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param callable|null $callback
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public function sort(callable $callback = null)
|
||||||
|
{
|
||||||
|
$items = $this->items;
|
||||||
|
|
||||||
|
$callback = $callback ?: function ($a, $b) {
|
||||||
|
return $a == $b ? 0 : (($a < $b) ? -1 : 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
uasort($items, $callback);
|
||||||
|
|
||||||
|
return new static($items);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定字段排序
|
||||||
|
*
|
||||||
|
* @param string $field 排序字段
|
||||||
|
* @param string $order 排序
|
||||||
|
* @param bool $intSort 是否为数字排序
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function order($field, $order = null, $intSort = true)
|
||||||
|
{
|
||||||
|
return $this->sort(function ($a, $b) use ($field, $order, $intSort) {
|
||||||
|
|
||||||
|
$fieldA = isset($a[$field]) ? $a[$field] : null;
|
||||||
|
$fieldB = isset($b[$field]) ? $b[$field] : null;
|
||||||
|
|
||||||
|
if ($intSort) {
|
||||||
|
return 'desc' == strtolower($order) ? $fieldB >= $fieldA : $fieldA >= $fieldB;
|
||||||
|
} else {
|
||||||
|
return 'desc' == strtolower($order) ? strcmp($fieldB, $fieldA) : strcmp($fieldA, $fieldB);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将数组打乱
|
||||||
|
*
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public function shuffle()
|
||||||
|
{
|
||||||
|
$items = $this->items;
|
||||||
|
|
||||||
|
shuffle($items);
|
||||||
|
|
||||||
|
return new static($items);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 截取数组
|
||||||
|
*
|
||||||
|
* @param int $offset
|
||||||
|
* @param int $length
|
||||||
|
* @param bool $preserveKeys
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public function slice($offset, $length = null, $preserveKeys = false)
|
||||||
|
{
|
||||||
|
return new static(array_slice($this->items, $offset, $length, $preserveKeys));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetExists($offset)
|
||||||
|
{
|
||||||
|
return array_key_exists($offset, $this->items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetGet($offset)
|
||||||
|
{
|
||||||
|
return $this->items[$offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetSet($offset, $value)
|
||||||
|
{
|
||||||
|
if (is_null($offset)) {
|
||||||
|
$this->items[] = $value;
|
||||||
|
} else {
|
||||||
|
$this->items[$offset] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetUnset($offset)
|
||||||
|
{
|
||||||
|
unset($this->items[$offset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function count()
|
||||||
|
{
|
||||||
|
return count($this->items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIterator()
|
||||||
|
{
|
||||||
|
return new ArrayIterator($this->items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function jsonSerialize()
|
||||||
|
{
|
||||||
|
return $this->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换当前数据集为JSON字符串
|
||||||
|
*
|
||||||
|
* @param integer $options json参数
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function toJson($options = JSON_UNESCAPED_UNICODE)
|
||||||
|
{
|
||||||
|
return json_encode($this->toArray(), $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return $this->toJson();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换成数组
|
||||||
|
*
|
||||||
|
* @param mixed $items
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function convertToArray($items)
|
||||||
|
{
|
||||||
|
if ($items instanceof self) {
|
||||||
|
return $items->all();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (array)$items;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -179,12 +179,3 @@ img.kg-qrcode {
|
|||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
border-top: none;
|
border-top: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.kg-status-history {
|
|
||||||
line-height: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.kg-status-history .time {
|
|
||||||
margin-left: 10px;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
15
public/static/admin/js/status-history.js
Normal file
15
public/static/admin/js/status-history.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
layui.use(['jquery', 'layer'], function () {
|
||||||
|
|
||||||
|
var $ = layui.jquery;
|
||||||
|
var layer = layui.layer;
|
||||||
|
|
||||||
|
$('.kg-status-history').on('click', function () {
|
||||||
|
layer.open({
|
||||||
|
type: 2,
|
||||||
|
title: '历史状态',
|
||||||
|
content: $(this).data('url'),
|
||||||
|
area: ['640px', '320px']
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@ -1,4 +1,4 @@
|
|||||||
.full {
|
.main {
|
||||||
background-color: #f2f2f2;
|
background-color: #f2f2f2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,9 +61,9 @@
|
|||||||
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.layer-wrap {
|
.bg-wrap {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
margin-bottom: 20px;
|
background-color: #f2f2f2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pager {
|
.pager {
|
||||||
@ -1501,6 +1501,11 @@ body {
|
|||||||
width: 10%;
|
width: 10%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.im-manage-wrap {
|
||||||
|
padding: 20px 20px 10px 20px;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
}
|
||||||
|
|
||||||
.im-search-wrap {
|
.im-search-wrap {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
background-color: #f2f2f2;
|
background-color: #f2f2f2;
|
||||||
@ -1542,6 +1547,17 @@ body {
|
|||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.im-user-list .action button {
|
||||||
|
padding: 0 5px;
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.im-user-list .layui-btn + .layui-btn {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.layim-msgbox {
|
.layim-msgbox {
|
||||||
margin: 15px;
|
margin: 15px;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
layui.use(['jquery', 'layer'], function () {
|
|
||||||
|
|
||||||
var $ = layui.jquery;
|
|
||||||
var layer = layui.layer;
|
|
||||||
|
|
||||||
});
|
|
@ -93,6 +93,20 @@ layui.use(['jquery', 'layer', 'helper'], function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 群组管理
|
||||||
|
*/
|
||||||
|
$('.btn-manage-group').on('click', function () {
|
||||||
|
var url = $(this).data('url');
|
||||||
|
layer.open({
|
||||||
|
type: 2,
|
||||||
|
title: '群组管理',
|
||||||
|
maxmin: true,
|
||||||
|
resize: false,
|
||||||
|
content: [url, 'no'],
|
||||||
|
area: ['1000px', '510px']
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
if ($('#tab-courses').length > 0) {
|
if ($('#tab-courses').length > 0) {
|
||||||
var $tabCourses = $('#tab-courses');
|
var $tabCourses = $('#tab-courses');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user