删掉无用信息
This commit is contained in:
@@ -1,40 +0,0 @@
|
||||
package com.org.flashsalesystem.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 测试控制器
|
||||
* 用于验证应用程序是否正常启动
|
||||
*/
|
||||
@Tag(name = "系统测试", description = "系统健康检查和测试接口")
|
||||
@RestController
|
||||
@RequestMapping("/test")
|
||||
public class TestController {
|
||||
|
||||
@Operation(summary = "系统问候", description = "测试系统是否正常运行")
|
||||
@GetMapping("/hello")
|
||||
public Map<String, Object> hello() {
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("message", "Hello! 秒杀系统运行正常");
|
||||
response.put("status", "success");
|
||||
response.put("timestamp", System.currentTimeMillis());
|
||||
return response;
|
||||
}
|
||||
|
||||
@Operation(summary = "健康检查", description = "检查系统健康状态")
|
||||
@GetMapping("/health")
|
||||
public Map<String, Object> health() {
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("status", "UP");
|
||||
response.put("application", "FlashSaleSystem");
|
||||
response.put("version", "1.0.0");
|
||||
return response;
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ spring:
|
||||
|
||||
# 数据源配置
|
||||
datasource:
|
||||
url: jdbc:mysql://localhost:3306/flash_sale_db?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
|
||||
url: jdbc:mysql://localhost:3306/flash_sale_db?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useSSL=false
|
||||
username: root
|
||||
password: root
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
|
||||
@@ -1,533 +0,0 @@
|
||||
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="fn" uri="http://flashsale.org/functions" %>
|
||||
|
||||
<c:set var="pageTitle" value="系统监控"/>
|
||||
<%@ include file="../common/header.jsp" %>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<!-- 侧边栏 -->
|
||||
<nav class="col-md-3 col-lg-2 d-md-block bg-light sidebar">
|
||||
<div class="position-sticky pt-3">
|
||||
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
|
||||
<span>管理功能</span>
|
||||
</h6>
|
||||
<ul class="nav flex-column">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="${pageContext.request.contextPath}/admin">
|
||||
<i class="fas fa-tachometer-alt"></i> 仪表盘
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="${pageContext.request.contextPath}/admin/products">
|
||||
<i class="fas fa-box"></i> 商品管理
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="${pageContext.request.contextPath}/admin/flashsales">
|
||||
<i class="fas fa-bolt"></i> 秒杀管理
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="${pageContext.request.contextPath}/admin/orders">
|
||||
<i class="fas fa-shopping-cart"></i> 订单管理
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="${pageContext.request.contextPath}/admin/users">
|
||||
<i class="fas fa-users"></i> 用户管理
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="${pageContext.request.contextPath}/admin/monitor">
|
||||
<i class="fas fa-chart-line"></i> 系统监控
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- 主内容区域 -->
|
||||
<main class="col-md-9 ms-sm-auto col-lg-10 px-md-4">
|
||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||
<h1 class="h2">系统监控</h1>
|
||||
<div class="btn-toolbar mb-2 mb-md-0">
|
||||
<div class="btn-group me-2">
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="refreshMonitorData()">
|
||||
<i class="fas fa-sync-alt"></i> 刷新数据
|
||||
</button>
|
||||
<button type="button" class="btn btn-sm btn-success" onclick="exportReport()">
|
||||
<i class="fas fa-download"></i> 导出报告
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 系统状态概览 -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-3">
|
||||
<div class="card text-center">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-success" id="systemStatus">正常</h5>
|
||||
<p class="card-text">系统状态</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card text-center">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-info" id="cpuUsage">0%</h5>
|
||||
<p class="card-text">CPU使用率</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card text-center">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-warning" id="memoryUsage">0%</h5>
|
||||
<p class="card-text">内存使用率</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card text-center">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-primary" id="diskUsage">0%</h5>
|
||||
<p class="card-text">磁盘使用率</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Redis监控 -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-database"></i> Redis集群状态</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>节点</th>
|
||||
<th>状态</th>
|
||||
<th>内存使用</th>
|
||||
<th>连接数</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="redisNodesTable">
|
||||
<tr>
|
||||
<td colspan="4" class="text-center">
|
||||
<i class="fas fa-spinner fa-spin"></i> 加载中...
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-chart-bar"></i> 数据库连接池</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<div class="text-center">
|
||||
<h4 class="text-success" id="activeConnections">0</h4>
|
||||
<small>活跃连接</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="text-center">
|
||||
<h4 class="text-info" id="idleConnections">0</h4>
|
||||
<small>空闲连接</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<div class="text-center">
|
||||
<h4 class="text-warning" id="maxConnections">0</h4>
|
||||
<small>最大连接</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="text-center">
|
||||
<h4 class="text-primary" id="totalConnections">0</h4>
|
||||
<small>总连接数</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 接口性能监控 -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-tachometer-alt"></i> 接口性能监控</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>接口路径</th>
|
||||
<th>请求次数</th>
|
||||
<th>平均响应时间</th>
|
||||
<th>成功率</th>
|
||||
<th>最后调用</th>
|
||||
<th>状态</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="apiPerformanceTable">
|
||||
<tr>
|
||||
<td colspan="6" class="text-center">
|
||||
<i class="fas fa-spinner fa-spin"></i> 加载中...
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 错误日志 -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-exclamation-triangle"></i> 最近错误日志</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>时间</th>
|
||||
<th>级别</th>
|
||||
<th>模块</th>
|
||||
<th>错误信息</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="errorLogsTable">
|
||||
<tr>
|
||||
<td colspan="5" class="text-center">
|
||||
<i class="fas fa-spinner fa-spin"></i> 加载中...
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 实时监控图表 -->
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-chart-line"></i> CPU & 内存使用趋势</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<canvas id="systemChart" width="400" height="200"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-chart-area"></i> 请求量统计</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<canvas id="requestChart" width="400" height="200"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
top: 56px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 100;
|
||||
padding: 48px 0 0;
|
||||
box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1);
|
||||
}
|
||||
|
||||
.sidebar .nav-link {
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.sidebar .nav-link.active {
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
main {
|
||||
margin-left: 240px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
main {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
position: relative;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
loadMonitorData();
|
||||
|
||||
// 每2分钟自动刷新数据(降低频率)
|
||||
setInterval(function () {
|
||||
loadMonitorData();
|
||||
}, 120000);
|
||||
});
|
||||
|
||||
function loadMonitorData() {
|
||||
loadSystemStatus();
|
||||
loadRedisStatus();
|
||||
loadDatabaseStatus();
|
||||
loadApiPerformance();
|
||||
loadErrorLogs();
|
||||
updateCharts();
|
||||
}
|
||||
|
||||
function loadSystemStatus() {
|
||||
// 调用真实API获取系统状态
|
||||
$.get('${pageContext.request.contextPath}/api/admin/monitor/system')
|
||||
.done(function (response) {
|
||||
if (response.success) {
|
||||
updateSystemStatus(response.data);
|
||||
} else {
|
||||
console.error('获取系统状态失败:', response.message);
|
||||
// 显示默认状态
|
||||
updateSystemStatus({
|
||||
status: '未知',
|
||||
cpuUsage: 0,
|
||||
memoryUsage: 0,
|
||||
diskUsage: 0
|
||||
});
|
||||
}
|
||||
})
|
||||
.fail(function () {
|
||||
console.error('获取系统状态请求失败');
|
||||
// 显示默认状态
|
||||
updateSystemStatus({
|
||||
status: '连接失败',
|
||||
cpuUsage: 0,
|
||||
memoryUsage: 0,
|
||||
diskUsage: 0
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 更新系统状态显示
|
||||
function updateSystemStatus(data) {
|
||||
const statusClass = data.status === '正常' ? 'text-success' : 'text-danger';
|
||||
$('#systemStatus').text(data.status || '未知').removeClass().addClass('card-title ' + statusClass);
|
||||
$('#cpuUsage').text((data.cpuUsage || 0) + '%');
|
||||
$('#memoryUsage').text((data.memoryUsage || 0) + '%');
|
||||
$('#diskUsage').text((data.diskUsage || 0) + '%');
|
||||
}
|
||||
|
||||
function loadRedisStatus() {
|
||||
// 调用真实API获取Redis状态
|
||||
$.get('${pageContext.request.contextPath}/api/admin/monitor/redis')
|
||||
.done(function (response) {
|
||||
if (response.success) {
|
||||
updateRedisStatus(response.data);
|
||||
} else {
|
||||
console.error('获取Redis状态失败:', response.message);
|
||||
// 显示默认状态
|
||||
updateRedisStatus([]);
|
||||
}
|
||||
})
|
||||
.fail(function () {
|
||||
console.error('获取Redis状态请求失败');
|
||||
// 显示默认状态
|
||||
updateRedisStatus([]);
|
||||
});
|
||||
}
|
||||
|
||||
// 更新Redis状态显示
|
||||
function updateRedisStatus(nodes) {
|
||||
let html = '';
|
||||
if (nodes && nodes.length > 0) {
|
||||
nodes.forEach(node => {
|
||||
const statusClass = node.status === '正常' ? 'bg-success' : 'bg-danger';
|
||||
html += `
|
||||
<tr>
|
||||
<td>${node.node}</td>
|
||||
<td><span class="badge ${statusClass}">${node.status}</span></td>
|
||||
<td>${node.memory}</td>
|
||||
<td>${node.connections}</td>
|
||||
</tr>
|
||||
`;
|
||||
});
|
||||
} else {
|
||||
html = '<tr><td colspan="4" class="text-center">无法获取Redis状态</td></tr>';
|
||||
}
|
||||
$('#redisNodesTable').html(html);
|
||||
}
|
||||
|
||||
function loadDatabaseStatus() {
|
||||
// 模拟数据库连接池状态
|
||||
setTimeout(function () {
|
||||
$('#activeConnections').text('12');
|
||||
$('#idleConnections').text('8');
|
||||
$('#maxConnections').text('20');
|
||||
$('#totalConnections').text('20');
|
||||
}, 600);
|
||||
}
|
||||
|
||||
function loadApiPerformance() {
|
||||
// 模拟接口性能数据
|
||||
setTimeout(function () {
|
||||
const apis = [
|
||||
{
|
||||
path: '/api/flashsale/participate',
|
||||
requests: 1234,
|
||||
avgTime: '45ms',
|
||||
successRate: '99.8%',
|
||||
lastCall: '10:30:15',
|
||||
status: '正常'
|
||||
},
|
||||
{
|
||||
path: '/api/product/hot',
|
||||
requests: 567,
|
||||
avgTime: '23ms',
|
||||
successRate: '100%',
|
||||
lastCall: '10:29:45',
|
||||
status: '正常'
|
||||
},
|
||||
{
|
||||
path: '/api/user/login',
|
||||
requests: 89,
|
||||
avgTime: '156ms',
|
||||
successRate: '98.9%',
|
||||
lastCall: '10:28:30',
|
||||
status: '正常'
|
||||
},
|
||||
{
|
||||
path: '/api/order/create',
|
||||
requests: 234,
|
||||
avgTime: '89ms',
|
||||
successRate: '99.5%',
|
||||
lastCall: '10:27:20',
|
||||
status: '正常'
|
||||
}
|
||||
];
|
||||
|
||||
let html = '';
|
||||
apis.forEach(api => {
|
||||
html += `
|
||||
<tr>
|
||||
<td><code>${api.path}</code></td>
|
||||
<td>${api.requests}</td>
|
||||
<td>${api.avgTime}</td>
|
||||
<td>${api.successRate}</td>
|
||||
<td>${api.lastCall}</td>
|
||||
<td><span class="badge bg-success">${api.status}</span></td>
|
||||
</tr>
|
||||
`;
|
||||
});
|
||||
|
||||
$('#apiPerformanceTable').html(html);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function loadErrorLogs() {
|
||||
// 模拟错误日志数据
|
||||
setTimeout(function () {
|
||||
const logs = [
|
||||
{
|
||||
time: '10:25:30',
|
||||
level: 'WARN',
|
||||
module: 'RedisService',
|
||||
message: 'Redis连接池使用率较高',
|
||||
action: '查看详情'
|
||||
},
|
||||
{
|
||||
time: '10:20:15',
|
||||
level: 'ERROR',
|
||||
module: 'FlashSaleService',
|
||||
message: '秒杀库存扣减失败',
|
||||
action: '查看详情'
|
||||
},
|
||||
{time: '10:15:45', level: 'INFO', module: 'UserService', message: '用户登录成功', action: '查看详情'}
|
||||
];
|
||||
|
||||
let html = '';
|
||||
if (logs.length === 0) {
|
||||
html = '<tr><td colspan="5" class="text-center text-success">暂无错误日志</td></tr>';
|
||||
} else {
|
||||
logs.forEach(log => {
|
||||
const levelClass = log.level === 'ERROR' ? 'bg-danger' :
|
||||
log.level === 'WARN' ? 'bg-warning' : 'bg-info';
|
||||
|
||||
html += `
|
||||
<tr>
|
||||
<td>${log.time}</td>
|
||||
<td><span class="badge ${levelClass}">${log.level}</span></td>
|
||||
<td>${log.module}</td>
|
||||
<td>${log.message}</td>
|
||||
<td><button class="btn btn-sm btn-outline-primary">${log.action}</button></td>
|
||||
</tr>
|
||||
`;
|
||||
});
|
||||
}
|
||||
|
||||
$('#errorLogsTable').html(html);
|
||||
}, 1200);
|
||||
}
|
||||
|
||||
function updateCharts() {
|
||||
// 这里应该使用Chart.js或其他图表库来绘制实时图表
|
||||
// 由于简化,这里只是模拟
|
||||
console.log('更新监控图表...');
|
||||
}
|
||||
|
||||
function refreshMonitorData() {
|
||||
// 显示加载状态
|
||||
$('#redisNodesTable').html('<tr><td colspan="4" class="text-center"><i class="fas fa-spinner fa-spin"></i> 加载中...</td></tr>');
|
||||
$('#apiPerformanceTable').html('<tr><td colspan="6" class="text-center"><i class="fas fa-spinner fa-spin"></i> 加载中...</td></tr>');
|
||||
$('#errorLogsTable').html('<tr><td colspan="5" class="text-center"><i class="fas fa-spinner fa-spin"></i> 加载中...</td></tr>');
|
||||
|
||||
// 重新加载数据
|
||||
loadMonitorData();
|
||||
}
|
||||
|
||||
function exportReport() {
|
||||
console.log('导出监控报告');
|
||||
alert('监控报告导出功能开发中...');
|
||||
}
|
||||
</script>
|
||||
|
||||
<%@ include file="../common/footer.jsp" %>
|
||||
@@ -39,11 +39,6 @@
|
||||
<i class="fas fa-users"></i> 用户管理
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="${pageContext.request.contextPath}/admin/monitor">
|
||||
<i class="fas fa-chart-line"></i> 系统监控
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
@@ -173,48 +173,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 性能指标 -->
|
||||
<section id="performance" class="mb-5">
|
||||
<h2 class="text-center fw-bold mb-5">
|
||||
<i class="fas fa-chart-line"></i> 性能指标
|
||||
</h2>
|
||||
|
||||
<div class="row g-4">
|
||||
<div class="col-md-3 col-sm-6">
|
||||
<div class="card border-primary">
|
||||
<div class="card-body text-center">
|
||||
<h3 class="text-primary fw-bold" id="qpsCounter">10000+</h3>
|
||||
<p class="card-text">QPS并发处理</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 col-sm-6">
|
||||
<div class="card border-success">
|
||||
<div class="card-body text-center">
|
||||
<h3 class="text-success fw-bold" id="responseTime"><100ms</h3>
|
||||
<p class="card-text">平均响应时间</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 col-sm-6">
|
||||
<div class="card border-warning">
|
||||
<div class="card-body text-center">
|
||||
<h3 class="text-warning fw-bold" id="successRate">99.9%</h3>
|
||||
<p class="card-text">系统可用性</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 col-sm-6">
|
||||
<div class="card border-info">
|
||||
<div class="card-body text-center">
|
||||
<h3 class="text-info fw-bold" id="concurrentUsers">50000+</h3>
|
||||
<p class="card-text">并发用户支持</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
Reference in New Issue
Block a user