You've already forked think-plugs-notice
Compare commits
5 Commits
a19e13280a
...
master
Author | SHA1 | Date | |
---|---|---|---|
49c8de54c2 | |||
f87916a61b | |||
9b4c44ff28 | |||
16dc063a39 | |||
879982f3f3 |
@ -13,8 +13,9 @@ class Service extends Plugin
|
||||
{
|
||||
return [
|
||||
[
|
||||
'name' => '通知提醒',
|
||||
'name' => '通知',
|
||||
'subs' => [
|
||||
['name' => '通知通告', 'icon' => 'layui-icon layui-icon-cols', 'url' => 'notice/broadcast/index'],
|
||||
['name' => '通知提醒', 'icon' => 'layui-icon layui-icon-cols', 'url' => 'notice/notice/index'],
|
||||
]
|
||||
]
|
||||
|
118
src/controller/Broadcast.php
Normal file
118
src/controller/Broadcast.php
Normal file
@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace jerryyan\notice\controller;
|
||||
|
||||
use jerryyan\notice\model\NoticeBroadcast;
|
||||
use jerryyan\notice\service\NoticeService;
|
||||
use jerryyan\staff\model\StaffDept;
|
||||
use jerryyan\staff\model\StaffUser;
|
||||
use think\admin\Controller;
|
||||
use think\admin\helper\QueryHelper;
|
||||
|
||||
/**
|
||||
* 通知公告
|
||||
*/
|
||||
class Broadcast extends Controller
|
||||
{
|
||||
/**
|
||||
* 通知公告
|
||||
* @auth true
|
||||
* @menu true
|
||||
* @return void
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->title = '通知公告';
|
||||
NoticeBroadcast::mQuery()->layTable(function () {
|
||||
$this->types = NoticeBroadcast::types();
|
||||
}, static function (QueryHelper $query) {
|
||||
$query->equal('type,status')->like('title,content');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加通知公告
|
||||
* @auth true
|
||||
* @return void
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
NoticeBroadcast::mForm('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑通知公告
|
||||
* @auth true
|
||||
* @return void
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
NoticeBroadcast::mForm('form');
|
||||
}
|
||||
|
||||
protected function _form_filter(array &$vo)
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
if (empty($vo['to_depts'])) {
|
||||
if (empty($vo['id'])) {
|
||||
$this->error('请选择通知对象!');
|
||||
}
|
||||
unset($vo['to_depts']);
|
||||
} else {
|
||||
$vo['to_depts'] = arr2str($vo['to_depts']);
|
||||
}
|
||||
if (empty($vo['to'])) {
|
||||
if (empty($vo['id'])) {
|
||||
$this->error('请选择通知对象!');
|
||||
}
|
||||
unset($vo['to']);
|
||||
}
|
||||
$vo['create_by'] = session('user.id');
|
||||
} else {
|
||||
$this->depts = StaffDept::items();
|
||||
$this->types = NoticeBroadcast::types();
|
||||
}
|
||||
}
|
||||
|
||||
protected function _form_result(bool $status, $vo)
|
||||
{
|
||||
if ($status) {
|
||||
if (empty($vo['id']) || !empty($vo['rebroadcast'])) {
|
||||
if (!empty($vo['to_all'])) {
|
||||
$staffs = StaffUser::mk()->select();
|
||||
} else {
|
||||
$depts = str2arr($vo['to_depts']);
|
||||
$staffs = StaffUser::mk()->whereIn('dept_id', $depts)->select();
|
||||
}
|
||||
NoticeService::send_notice_to($vo['type'], $vo['content'], url('broadcast/view', ['id' => $vo['id']])->build(), $staffs->map(function($staff) {
|
||||
return $staff['id'];
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看通知公告
|
||||
* @auth false
|
||||
* @return void
|
||||
*/
|
||||
public function view()
|
||||
{
|
||||
$this->title = '查看通知公告';
|
||||
NoticeBroadcast::mForm('view');
|
||||
}
|
||||
|
||||
protected function _view_form_filter(array &$vo) {
|
||||
$vo['creator'] = StaffUser::mk()->where(['id' => $vo['create_by']])->findOrEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除通知公告
|
||||
* @auth true
|
||||
* @return void
|
||||
*/
|
||||
public function remove()
|
||||
{
|
||||
NoticeBroadcast::mDelete();
|
||||
}
|
||||
}
|
34
src/model/NoticeBroadcast.php
Normal file
34
src/model/NoticeBroadcast.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace jerryyan\notice\model;
|
||||
|
||||
use jerryyan\staff\model\StaffUser;
|
||||
use think\admin\Model;
|
||||
use think\db\Query;
|
||||
|
||||
class NoticeBroadcast extends Model
|
||||
{
|
||||
protected $oplogType = '通知公告管理';
|
||||
protected $oplogName = '通知公告';
|
||||
protected $globalScope = ['notDeleted'];
|
||||
|
||||
public function scopeNotDeleted(Query $query): void
|
||||
{
|
||||
$query->where('is_deleted', '=', 0);
|
||||
}
|
||||
|
||||
public function scopeDeleted(Query $query): void
|
||||
{
|
||||
$query->where('is_deleted', '=', 1);
|
||||
}
|
||||
|
||||
public static function types()
|
||||
{
|
||||
return static::mk()->group('type')->field('type')->select();
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->hasOne(StaffUser::class, 'id', 'create_by')->with(['dept']);
|
||||
}
|
||||
}
|
24
src/service/NoticeService.php
Normal file
24
src/service/NoticeService.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace jerryyan\notice\service;
|
||||
|
||||
|
||||
use jerryyan\notice\model\NoticeNotice;
|
||||
use think\admin\Service;
|
||||
|
||||
class NoticeService extends Service
|
||||
{
|
||||
public static function send_notice_to($type = '', $content = '', $link = '', $users = []): int
|
||||
{
|
||||
$notices = [];
|
||||
foreach ($users as $user) {
|
||||
$notices[] = [
|
||||
'type' => $type,
|
||||
'content' => $content,
|
||||
'link' => $link,
|
||||
'staff_id' => $user,
|
||||
];
|
||||
}
|
||||
return NoticeNotice::mk()->insertAll($notices);
|
||||
}
|
||||
}
|
99
src/view/broadcast/form.html
Normal file
99
src/view/broadcast/form.html
Normal file
@ -0,0 +1,99 @@
|
||||
<form action="{:sysuri()}" method="post" data-auto="true" class="layui-form layui-card" data-table-id="DeptTable">
|
||||
<div class="layui-card-body padding-left-40">
|
||||
<fieldset class="layui-bg-gray">
|
||||
<legend><b class="layui-badge think-bg-violet">基础信息</b></legend>
|
||||
<label class="layui-form-item relative block">
|
||||
<span class="help-label"><b>标题</b></span>
|
||||
<input maxlength="100" class="layui-input" name="title" value='{$vo.title|default=""}' required vali-name="标题" placeholder="请输入标题">
|
||||
</label>
|
||||
<label class="layui-form-item relative block">
|
||||
<span class="help-label"><b>类型</b></span>
|
||||
<select name="type" lay-search="{fuzzy: true}" lay-creatable="" required vali-name="类型" class="layui-select">
|
||||
<option value="">请选择或输入类型</option>
|
||||
{foreach $types as $type}{if isset($vo.type) and $type.type eq $vo.type}
|
||||
<option selected value="{$type.type}">{$type.type}</option>
|
||||
{else}
|
||||
<option value="{$type.type}">{$type.type}</option>
|
||||
{/if}{/foreach}
|
||||
</select>
|
||||
</label>
|
||||
<label class="layui-form-item relative block">
|
||||
<span class="help-label"><b>内容</b></span>
|
||||
<textarea class="layui-textarea" name="content" style="width: 100%" placeholder="请输入内容">
|
||||
{$vo.title|default=""}
|
||||
</textarea>
|
||||
</label>
|
||||
</fieldset>
|
||||
<fieldset class="layui-bg-gray">
|
||||
<legend><b class="layui-badge think-bg-violet">通知人</b></legend>
|
||||
{notempty name='vo.id'}
|
||||
<input type="checkbox" lay-filter="rebroadcast" lay-skin="tag" lay-text="重新发送通知" name="rebroadcast" value='1'>
|
||||
<script>
|
||||
$(function () {
|
||||
$(".rebroadcast").hide()
|
||||
})
|
||||
</script>
|
||||
{/notempty}
|
||||
|
||||
<div class="layui-form-item rebroadcast">
|
||||
<input type="checkbox" lay-filter="to_all" lay-skin="tag" lay-text="通知所有人" name="to_all" value='1'>
|
||||
</div>
|
||||
<div class="layui-form-item rebroadcast" id="to_depts">
|
||||
<label class="layui-form-label"><span class="help-label"><b>通知部门</b></span></label>
|
||||
<div class="layui-input-block">
|
||||
{foreach $depts as $dept}
|
||||
<input type="checkbox" lay-filter="to_depts" lay-skin="tag" lay-text="{$dept.name}" name="to_depts[]" value='{$dept.id}'>
|
||||
{/foreach}
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div class="hr-line-dashed"></div>
|
||||
{notempty name='vo.id'}<input type='hidden' value='{$vo.id}' name='id'>{/notempty}
|
||||
<input type="hidden" name="to" value='{$vo.to|default=""}'>
|
||||
|
||||
<div class="layui-form-item text-center">
|
||||
<button class="layui-btn" type='submit'>{:lang('保存数据')}</button>
|
||||
<button class="layui-btn layui-btn-danger" type='button' data-confirm="{:lang('确定要取消编辑吗?')}" data-close>{:lang('取消编辑')}</button>
|
||||
</div>
|
||||
</form>
|
||||
<script>
|
||||
$(function () {
|
||||
layui.use(['form'], function () {
|
||||
const Form = layui.form;
|
||||
Form.on('checkbox(to_all)', function (data) {
|
||||
if (data.elem.checked) {
|
||||
$('input[name="to"]').val('所有人')
|
||||
$('#to_depts').hide()
|
||||
$('select[name="to_depts"]').attr('disabled', true)
|
||||
} else {
|
||||
$('input[name="to"]').val(
|
||||
$('input[lay-filter="to_depts"]').filter(function (index, element) {
|
||||
return element.checked;
|
||||
}).map(function (index,element) {
|
||||
return $(element).attr('title')
|
||||
}).toArray().join(',')
|
||||
)
|
||||
$('#to_depts').show()
|
||||
}
|
||||
})
|
||||
Form.on('checkbox(to_depts)', function (data) {
|
||||
$('input[name="to"]').val(
|
||||
$('input[lay-filter="to_depts"]').filter(function (index, element) {
|
||||
return element.checked;
|
||||
}).map(function (index,element) {
|
||||
return $(element).attr('title')
|
||||
}).toArray().join(',')
|
||||
)
|
||||
})
|
||||
Form.on('checkbox(rebroadcast)', function (data) {
|
||||
if (data.elem.checked) {
|
||||
$('.rebroadcast').show()
|
||||
} else {
|
||||
$('.rebroadcast').hide()
|
||||
}
|
||||
})
|
||||
});
|
||||
})
|
||||
</script>
|
50
src/view/broadcast/index.html
Normal file
50
src/view/broadcast/index.html
Normal file
@ -0,0 +1,50 @@
|
||||
{extend name='table'}
|
||||
|
||||
{block name="button"}
|
||||
<!--{if auth("add")}-->
|
||||
<a class="layui-btn layui-btn-sm" data-modal="{:url('add')}" data-title="新增通知公告" data-height="100%">{:lang('新 增')}</a>
|
||||
<!--{/if}-->
|
||||
<!--{if auth("remove")}-->
|
||||
<a data-confirm="{:lang('确定删除这些记录吗?')}" data-table-id="FileTable" data-action='{:url("remove")}' data-rule="id#{id}" class='layui-btn layui-btn-sm layui-btn-primary'>{:lang('批量删除')}</a>
|
||||
<!--{/if}-->
|
||||
{/block}
|
||||
|
||||
{block name="content"}
|
||||
<div class="think-box-shadow" style="flex: 4">
|
||||
{include file="broadcast/index_search"}
|
||||
<table class="layui-hide" id="BroadcastTable" data-url="{:request()->url()}" data-target-search="form.form-search" lay-filter="BroadcastTable"></table>
|
||||
</div>
|
||||
<script type="text/html" id="ToolbarTpl">
|
||||
<div class="layui-btn-container">
|
||||
<!--{if auth("edit")}-->
|
||||
<a class="layui-btn layui-btn-xs" data-modal="{:url('edit')}?id={{d.id}}" data-title="编辑通知公告">{:lang('编 辑')}</a>
|
||||
<!--{/if}-->
|
||||
<!--{if auth("remove")}-->
|
||||
<a class="layui-btn layui-btn-danger layui-btn-xs" data-confirm="{:lang('确定删除该记录吗?')}" data-action="{:url('remove')}" data-value="id#{{d.id}}">{:lang('删 除')}</a>
|
||||
<!--{/if}-->
|
||||
</div>
|
||||
</script>
|
||||
<script>
|
||||
$(function () {
|
||||
$('#BroadcastTable').layTable({
|
||||
height: 'full',
|
||||
sort: ['create_at', 'desc'],
|
||||
cols: [[
|
||||
{checkbox: true, fixed: true},
|
||||
{ field: 'id', title: '序号', width: 80 },
|
||||
{ field: 'title', title: '标题', width: 200 },
|
||||
{ field: 'type', title: '类型', width: 120 },
|
||||
{ field: 'content', title: '内容' },
|
||||
{ field: 'to', title: '通知用户' },
|
||||
{ field: 'create_at', title: '创建时间', width: 200, sort: true },
|
||||
{ fixed: "right", title: "操作", width: 200, align: "center", toolbar: "#ToolbarTpl"}
|
||||
]],
|
||||
page: true
|
||||
})
|
||||
layui.use(['form', 'table'], function () {
|
||||
const Table = layui.table;
|
||||
const Form = layui.form;
|
||||
});
|
||||
})
|
||||
</script>
|
||||
{/block}
|
30
src/view/broadcast/index_search.html
Normal file
30
src/view/broadcast/index_search.html
Normal file
@ -0,0 +1,30 @@
|
||||
<fieldset>
|
||||
<legend>{:lang('条件搜索')}</legend>
|
||||
<form class="layui-form layui-form-pane form-search" action="{:request()->url()}" onsubmit="return false" method="post" autocomplete="off">
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">{:lang('内容')}</label>
|
||||
<label class="layui-input-inline">
|
||||
<input name="name" value="{$get.content|default=''}" placeholder="{:lang('内容')}" class="layui-input">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">{:lang('通知类型')}</label>
|
||||
<label class="layui-input-inline">
|
||||
<select name="status">
|
||||
<option value="">{:lang('请选择通知类型')}</option>
|
||||
{foreach $types as $type}
|
||||
{if isset($get.type) and $get.type eq $type.type}
|
||||
<option selected value="{$type.type}">{$type.type}</option>
|
||||
{else}
|
||||
<option value="{$type.type}">{$type.type}</option>
|
||||
{/if}{/foreach}
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<button class="layui-btn layui-btn-primary"><i class="layui-icon"></i> {:lang('搜 索')}</button>
|
||||
</div>
|
||||
</form>
|
||||
</fieldset>
|
11
src/view/broadcast/view.html
Normal file
11
src/view/broadcast/view.html
Normal file
@ -0,0 +1,11 @@
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">通知公告</div>
|
||||
<div class="layui-card-body">
|
||||
<h1>{$vo.title}</h1>
|
||||
<hr>
|
||||
<p>{$vo.content}</p>
|
||||
<hr>
|
||||
<p style="text-align: right">通知时间:{$vo.create_at}</p>
|
||||
<p style="text-align: right">通知人:{$vo.creator.name|default='通知人员'}</p>
|
||||
</div>
|
||||
</div>
|
@ -9,6 +9,12 @@
|
||||
{include file="notice/index_search"}
|
||||
<table class="layui-hide" id="NoticeTable" data-url="{:request()->url()}" data-target-search="form.form-search" lay-filter="NoticeTable"></table>
|
||||
</div>
|
||||
<script type="text/html" id="ContentTpl">
|
||||
{{d.content}}
|
||||
{{# if (d.link) { }}
|
||||
<a class="layui-btn layui-btn-sm" data-modal="{{d.link}}" data-area="['600px', '600px']">查看详情</a>
|
||||
{{# } }}
|
||||
</script>
|
||||
<script type="text/html" id="ToolbarTpl">
|
||||
<div class="layui-btn-container">
|
||||
{{# if(d.read_at) { }}
|
||||
@ -26,7 +32,7 @@
|
||||
cols: [[
|
||||
{ field: 'id', title: '序号', width: 80 },
|
||||
{ field: 'type', title: '类型', width: 200 },
|
||||
{ field: 'content', title: '信息内容' },
|
||||
{ field: 'content', title: '信息内容', templet: '#ContentTpl' },
|
||||
{ field: 'create_at', title: '时间', width: 200, sort: true },
|
||||
{ fixed: "right", title: "操作", width: 200, align: "center", toolbar: "#ToolbarTpl"}
|
||||
]],
|
||||
|
@ -24,7 +24,6 @@
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<input type="hidden" name="dept_id" value="{$get.dept_id|default=''}">
|
||||
<button class="layui-btn layui-btn-primary"><i class="layui-icon"></i> {:lang('搜 索')}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
83
stc/database/20250623000000_install_notice_table.php
Normal file
83
stc/database/20250623000000_install_notice_table.php
Normal file
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
use think\admin\extend\PhinxExtend;
|
||||
use think\migration\Migrator;
|
||||
|
||||
@set_time_limit(0);
|
||||
@ini_set('memory_limit', -1);
|
||||
|
||||
class InstallNoticeTable extends Migrator
|
||||
{
|
||||
|
||||
/**
|
||||
* 获取脚本名称
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'NoticePlugin';
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建数据库
|
||||
*/
|
||||
public function change()
|
||||
{
|
||||
$this->_create_notice();
|
||||
$this->_create_broadcast();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建数据对象
|
||||
* @table notice_notice
|
||||
* @return void
|
||||
*/
|
||||
private function _create_notice()
|
||||
{
|
||||
// 创建数据表对象
|
||||
$table = $this->table('notice_notice', [
|
||||
'engine' => 'InnoDB', 'collation' => 'utf8mb4_general_ci', 'comment' => '消息通知',
|
||||
]);
|
||||
// 创建或更新数据表
|
||||
PhinxExtend::upgrade($table, [
|
||||
['staff_id', 'integer', ['default' => NULL, 'null' => false, 'comment' => '员工ID']],
|
||||
['type', 'string', ['limit' => 255, 'default' => NULL, 'null' => true, 'comment' => '类型']],
|
||||
['content', 'string', ['limit' => 255, 'default' => NULL, 'null' => true, 'comment' => '信息内容']],
|
||||
['link', 'string', ['limit' => 255, 'default' => NULL, 'null' => true, 'comment' => '跳转链接(如果有)']],
|
||||
['create_at', 'datetime', ['default' => 'CURRENT_TIMESTAMP', 'null' => false, 'comment' => '创建时间']],
|
||||
['read_at', 'datetime', ['default' => NULL, 'null' => true, 'comment' => '已读时间']],
|
||||
], [
|
||||
'type', 'staff_id',
|
||||
], false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建数据对象
|
||||
* @table notice_broadcast
|
||||
* @return void
|
||||
*/
|
||||
private function _create_broadcast()
|
||||
{
|
||||
// 创建数据表对象
|
||||
$table = $this->table('notice_broadcast', [
|
||||
'engine' => 'InnoDB', 'collation' => 'utf8mb4_general_ci', 'comment' => '通知公告',
|
||||
]);
|
||||
// 创建或更新数据表
|
||||
PhinxExtend::upgrade($table, [
|
||||
['to_all', 'tinyinteger', ['limit' => 4, 'default' => 0, 'null' => false, 'comment' => '是否发送给所有人']],
|
||||
['to_depts', 'string', ['limit' => 255, 'default' => NULL, 'null' => true, 'comment' => '要发送的部门']],
|
||||
['to_users', 'string', ['limit' => 255, 'default' => NULL, 'null' => true, 'comment' => '要发送的用户']],
|
||||
['to', 'text', ['default' => NULL, 'null' => false, 'comment' => '对外的发送到']],
|
||||
['title', 'string', ['limit' => 255, 'default' => NULL, 'null' => false, 'comment' => '标题']],
|
||||
['type', 'string', ['limit' => 255, 'default' => NULL, 'null' => true, 'comment' => '类型']],
|
||||
['content', 'text', ['default' => NULL, 'null' => true, 'comment' => '内容']],
|
||||
['files', 'string', ['limit' => 255, 'default' => NULL, 'null' => true, 'comment' => '附件']],
|
||||
['create_at', 'datetime', ['default' => 'CURRENT_TIMESTAMP', 'null' => false, 'comment' => '']],
|
||||
['create_by', 'integer', ['limit' => 11, 'default' => 0, 'null' => false, 'comment' => '创建人ID']],
|
||||
['is_deleted', 'tinyinteger', ['limit' => 4, 'default' => 0, 'null' => false, 'comment' => '是否已删除']],
|
||||
], [
|
||||
'type'
|
||||
], false);
|
||||
}
|
||||
|
||||
}
|
54
stc/database/20250623000001_install_notice_menu.php
Normal file
54
stc/database/20250623000001_install_notice_menu.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
|
||||
use jerryyan\notice\Service;
|
||||
use think\admin\extend\PhinxExtend;
|
||||
use think\migration\Migrator;
|
||||
|
||||
@set_time_limit(0);
|
||||
@ini_set('memory_limit', -1);
|
||||
|
||||
/**
|
||||
* 系统模块数据
|
||||
*/
|
||||
class InstallNoticeMenu extends Migrator
|
||||
{
|
||||
|
||||
/**
|
||||
* 获取脚本名称
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'NoticePlugin';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 创建数据库
|
||||
*/
|
||||
public function change()
|
||||
{
|
||||
$this->insertMenu();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化系统菜单
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function insertMenu()
|
||||
{
|
||||
|
||||
// 初始化菜单数据
|
||||
PhinxExtend::write2menu([
|
||||
[
|
||||
'name' => '消息通知',
|
||||
'sort' => '105',
|
||||
'subs' => Service::menu(),
|
||||
],
|
||||
], [
|
||||
'url|node' => 'notice/notice/index'
|
||||
]);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user