instances 模块 服务和进程页面开发
This commit is contained in:
parent
0434cef898
commit
72e3776fa2
15
src/views/abnormalAlarm/serverMonitor/instances/cpu.vue
Normal file
15
src/views/abnormalAlarm/serverMonitor/instances/cpu.vue
Normal file
|
@ -0,0 +1,15 @@
|
|||
<template>
|
||||
<div>
|
||||
Cpu
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
|
@ -1298,15 +1298,18 @@ export default {
|
|||
li{
|
||||
float: left;
|
||||
font-size: 14px;
|
||||
margin-left: 25px;
|
||||
margin-left: 20px;
|
||||
font-family: MicrosoftYaHei;
|
||||
font-weight: normal;
|
||||
color: #ade6ee;
|
||||
.li-icon{
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
border-radius: 4px;
|
||||
background: red;
|
||||
margin-right: 10px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
<template>
|
||||
<div style="height: 100%;">
|
||||
<a-card :bordered="false" style="height:100%;margin-left: 20px;">
|
||||
<a-tabs default-active-key="detais" @change="handleTabChange">
|
||||
<a-tabs default-active-key="serviceProcess" @change="handleTabChange">
|
||||
<a-tab-pane key="detais" tab="DETAILS">
|
||||
<Details></Details>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="service-process" tab="SERVICE AND PROCESS">
|
||||
SERVICE AND PROCESS
|
||||
<a-tab-pane key="serviceProcess" tab="SERVICE AND PROCESS">
|
||||
<ServiceProcess></ServiceProcess>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="monitor" tab="MONITOR">
|
||||
MONITOR
|
||||
<Monitor></Monitor>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="cpu" tab="CPU">
|
||||
CPU
|
||||
<Cpu></Cpu>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="memory" tab="MEMORY">
|
||||
MEMORY
|
||||
|
@ -27,9 +27,15 @@
|
|||
|
||||
<script>
|
||||
import Details from './details.vue';
|
||||
import ServiceProcess from './serviceProcess.vue';
|
||||
import Monitor from './monitor.vue';
|
||||
import Cpu from './cpu.vue';
|
||||
export default {
|
||||
components: {
|
||||
Details,
|
||||
ServiceProcess,
|
||||
Monitor,
|
||||
Cpu,
|
||||
},
|
||||
methods: {
|
||||
handleTabChange(key) {
|
||||
|
|
15
src/views/abnormalAlarm/serverMonitor/instances/monitor.vue
Normal file
15
src/views/abnormalAlarm/serverMonitor/instances/monitor.vue
Normal file
|
@ -0,0 +1,15 @@
|
|||
<template>
|
||||
<div>
|
||||
monitor
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,602 @@
|
|||
<template>
|
||||
<div style="height: 100%;">
|
||||
<div class="service-search">
|
||||
<a-row type="flex" :gutter="10">
|
||||
<a-col flex="265px">
|
||||
<span class="item-label">Server</span>
|
||||
<a-select style="width:180px"
|
||||
v-model="queryParams.server"
|
||||
placeholder="select..."
|
||||
:filter-option="filterOption"
|
||||
show-arrow
|
||||
:options="serverOptions"
|
||||
@change="onServerChange"
|
||||
>
|
||||
<img slot="suffixIcon" src="@/assets/images/global/select-down.png" alt="" />
|
||||
</a-select>
|
||||
</a-col>
|
||||
<a-col flex="265px">
|
||||
<span class="item-label">Time</span>
|
||||
<a-select style="width:180px"
|
||||
v-model="queryParams.timer"
|
||||
placeholder="select..."
|
||||
show-arrow
|
||||
:options="timerOptions"
|
||||
@change="onTimeChange"
|
||||
>
|
||||
<img slot="suffixIcon" src="@/assets/images/global/select-down.png" alt="" />
|
||||
</a-select>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div class="service-search-btns">
|
||||
<a-button :class="['service-search-btns-ant', type=='cpu'?'service-search-btns-active':'']" @click="handleCpu">CPU</a-button>
|
||||
<a-button :class="['service-search-btns-ant', type=='memory'?'service-search-btns-active':'']" @click="handleMemory">Memory</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="service-content">
|
||||
<div class="service-content-ranked">
|
||||
<BoxTitle title="Top-ranked processes in the last hour">
|
||||
<template slot="right">
|
||||
<ul class="legend-list">
|
||||
<li v-for="(item,index) in ranked.legend" :key="index">
|
||||
<div :style="`background:${ranked.color[index]}`" class="li-icon"></div>
|
||||
{{ item }}
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
</BoxTitle>
|
||||
<div class="service-content-ranked-box" id="ranked"></div>
|
||||
</div>
|
||||
<div class="service-content-center">
|
||||
<a-row :gutter="20">
|
||||
<a-col :span="12">
|
||||
<BoxTitle title="Proces CPU usage(%)">
|
||||
<template slot="right">
|
||||
<ul class="legend-list">
|
||||
<li v-for="(item,index) in procesCpu.legend" :key="index">
|
||||
<div :style="`background:${procesCpu.color[index]}`" class="li-icon"></div>
|
||||
{{ item }}
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
</BoxTitle>
|
||||
<div class="service-content-center-item" id="cpu"></div>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<BoxTitle title="Proces menbry usage(%)">
|
||||
<template slot="right">
|
||||
<ul class="legend-list">
|
||||
<li v-for="(item,index) in procesMenbry.legend" :key="index">
|
||||
<div :style="`background:${procesMenbry.color[index]}`" class="li-icon"></div>
|
||||
{{ item }}
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
</BoxTitle>
|
||||
<div class="service-content-center-item" id="menbry"></div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
<div class="service-content-table">
|
||||
<BoxTitle title="Service"></BoxTitle>
|
||||
<div style="padding-top: 15px;">
|
||||
<TableList
|
||||
size="middle"
|
||||
rowKey="id"
|
||||
:columns="columns"
|
||||
:list="dataSource"
|
||||
:loading="loading"
|
||||
:pagination="false"
|
||||
:canSelect="false"
|
||||
>
|
||||
</TableList>
|
||||
<a-pagination
|
||||
size="small"
|
||||
v-model="ipagination.current"
|
||||
:pageSize="ipagination.pageSize"
|
||||
:page-size-options="ipagination.pageSizeOptions"
|
||||
show-size-changer
|
||||
show-quick-jumper
|
||||
:total="ipagination.total"
|
||||
:show-total="(total, range) => `Total ${total} items Page ${ipagination.current} / ${Math.ceil(total / ipagination.pageSize)}`"
|
||||
show-less-items
|
||||
@change="handlePageChange"
|
||||
@showSizeChange="handleSizeChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BoxTitle from '../../components/boxTitle.vue';
|
||||
import TableList from '../../components/tableList.vue';
|
||||
import { getAction, postAction, httpAction, deleteAction } from '@/api/manage'
|
||||
import * as echarts from 'echarts'
|
||||
const columns = [{
|
||||
title: 'STATUS',
|
||||
align: 'left',
|
||||
dataIndex: 'status',
|
||||
// width: 250,
|
||||
},{
|
||||
title: 'SERVICE NAME',
|
||||
align: 'left',
|
||||
dataIndex: 'name',
|
||||
// width: 250,
|
||||
},{
|
||||
title: 'ASSOCIATED PROCESS',
|
||||
align: 'left',
|
||||
dataIndex: 'process',
|
||||
// width: 250,
|
||||
},{
|
||||
title: 'CPU(%)',
|
||||
align: 'left',
|
||||
dataIndex: 'cpu',
|
||||
// width: 250,
|
||||
},{
|
||||
title: 'MENORY',
|
||||
align: 'left',
|
||||
dataIndex: 'menory',
|
||||
// width: 250,
|
||||
},{
|
||||
title: 'INSTANCE',
|
||||
align: 'left',
|
||||
dataIndex: 'instance',
|
||||
// width: 250,
|
||||
},{
|
||||
title: 'THREAD COUNT',
|
||||
align: 'left',
|
||||
dataIndex: 'threadCount',
|
||||
// width: 250,
|
||||
},{
|
||||
title: 'PROCESSING COUNT',
|
||||
align: 'left',
|
||||
dataIndex: 'processongCount',
|
||||
// width: 250,
|
||||
}
|
||||
]
|
||||
export default {
|
||||
components: {
|
||||
BoxTitle,
|
||||
TableList
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
type: "cpu",
|
||||
queryParams: {
|
||||
server: undefined,
|
||||
timer: "1h"
|
||||
},
|
||||
serverOptions: [],
|
||||
timerOptions: [
|
||||
{label: "1Hours",value: "1h"},
|
||||
{label: "2Hours",value: "2h"},
|
||||
{label: "3Hours",value: "3h"},
|
||||
],
|
||||
ranked: {
|
||||
content: null,
|
||||
legend: ["NemuHeadless.exe","System","dwm.exe","CompatTelRunner.exe","msedge.exe"],
|
||||
color: ['#2d5cd3','#60cae8','#1ab060','#ffbf44','#e86954']
|
||||
},
|
||||
procesCpu: {
|
||||
content: null,
|
||||
legend: ["mysqld.exe","svchost.exe"],
|
||||
color: ['#e5ae2d','#00a8ff']
|
||||
},
|
||||
procesMenbry: {
|
||||
content: null,
|
||||
legend: ["mysqld.exe","svchost.exe"],
|
||||
color: ['#9ed24d','#00a8ff']
|
||||
},
|
||||
columns,
|
||||
loading: false,
|
||||
dataSource: [],
|
||||
ipagination:{
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
pageSizeOptions: ['10', '20', '30'],
|
||||
showTotal: (total, range) => {
|
||||
const { current, pageSize } = this.ipagination
|
||||
return `Total ${total} items Page ${current} / ${Math.ceil(total / pageSize)}`
|
||||
},
|
||||
showQuickJumper: true,
|
||||
showSizeChanger: true,
|
||||
total: 0
|
||||
},
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.getServerList()
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
this.drawRanked()
|
||||
this.drawProcesCpu()
|
||||
this.drawProcesMenbry()
|
||||
},0)
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
filterOption(input, option) {
|
||||
return (
|
||||
option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
);
|
||||
},
|
||||
getServerList() {
|
||||
getAction("/sysServer/sourceList").then(res => {
|
||||
if (res.success) {
|
||||
this.serverOptions = res.result.map(item => {
|
||||
return {
|
||||
label: item.sourceName,
|
||||
value: item.sourceId
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$message.warning("This operation fails. Contact your system administrator")
|
||||
}
|
||||
})
|
||||
},
|
||||
onServerChange(val) {
|
||||
console.log(val);
|
||||
},
|
||||
onTimeChange(val) {
|
||||
console.log(val);
|
||||
},
|
||||
handleCpu() {
|
||||
this.type = "cpu"
|
||||
},
|
||||
handleMemory() {
|
||||
this.type = "memory"
|
||||
},
|
||||
drawRanked() {
|
||||
this.ranked.content = echarts.init(document.getElementById("ranked"))
|
||||
let option = {
|
||||
color:this.ranked.color,
|
||||
grid: {
|
||||
left: 25,
|
||||
right: 0,
|
||||
top: 15,
|
||||
bottom: 10,
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
axisTick: {
|
||||
show:false
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: "rgba(64, 105, 121, 0.5)"
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
color: "rgba(173, 230, 238, 1)"
|
||||
},
|
||||
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
name: "CPU utilization",
|
||||
nameLocation: "middle",
|
||||
nameTextStyle: {
|
||||
color: "#5b9cba",
|
||||
fontFamily: "ArialMT",
|
||||
fontSize: 14
|
||||
},
|
||||
nameGap: 35,
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: "rgba(64, 105, 121, 0.5)"
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
color: "rgba(173, 230, 238, 1)"
|
||||
},
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: 'Baidu',
|
||||
type: 'bar',
|
||||
barWidth: 20,
|
||||
stack: 'Search Engine',
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: [20, 32, 71, 34, 90, 30,92]
|
||||
},
|
||||
{
|
||||
name: 'Google',
|
||||
type: 'bar',
|
||||
stack: 'Search Engine',
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: [12, 25, 46, 34, 29, 23,64]
|
||||
},
|
||||
{
|
||||
name: 'Bing',
|
||||
type: 'bar',
|
||||
stack: 'Search Engine',
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: [60, 72, 71, 74, 90, 13,43]
|
||||
},
|
||||
{
|
||||
name: 'Others',
|
||||
type: 'bar',
|
||||
stack: 'Search Engine',
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: [62, 82, 91, 84, 19, 11, 55]
|
||||
},
|
||||
{
|
||||
name: 'adf',
|
||||
type: 'bar',
|
||||
barWidth: 20,
|
||||
stack: 'Search Engine',
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: [20, 32, 71, 34, 90, 30,92]
|
||||
},
|
||||
]
|
||||
};
|
||||
this.ranked.content.setOption(option)
|
||||
window.addEventListener("resize", function () {
|
||||
this.ranked.content.resize();
|
||||
});
|
||||
},
|
||||
drawProcesCpu() {
|
||||
this.procesCpu.content = echarts.init(document.getElementById("cpu"))
|
||||
let option = {
|
||||
grid: {
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 15,
|
||||
bottom: 10,
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
axisTick: {
|
||||
show:false
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: "rgba(64, 105, 121, 0.5)"
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
color: "rgba(173, 230, 238, 1)"
|
||||
},
|
||||
boundaryGap: false,
|
||||
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: "rgba(64, 105, 121, 0.5)"
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
color: "rgba(173, 230, 238, 1)"
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'line',
|
||||
name: 'Email',
|
||||
symbol: 'none',
|
||||
itemStyle:{ normal:{color:"#00a8ff"}},
|
||||
areaStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: "#00a8ff" },
|
||||
{ offset: 1, color: "rgba(255,255,255,0)" },
|
||||
]),
|
||||
},
|
||||
},
|
||||
data: [150, 230, 224, 218, 135, 147, 260],
|
||||
},
|
||||
{
|
||||
type: 'line',
|
||||
name: 'Eml',
|
||||
symbol: 'none',
|
||||
itemStyle:{ normal:{color:"#ffbf2e"}},
|
||||
areaStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: "#ffbf2e" },
|
||||
{ offset: 1, color: "rgba(255,255,255,0)" },
|
||||
]),
|
||||
},
|
||||
},
|
||||
data: [820, 932, 901, 934, 1290, 1330, 1320],
|
||||
}
|
||||
]
|
||||
};
|
||||
this.procesCpu.content.setOption(option)
|
||||
window.addEventListener("resize", function () {
|
||||
this.procesCpu.content.resize();
|
||||
});
|
||||
},
|
||||
drawProcesMenbry() {
|
||||
this.procesMenbry.content = echarts.init(document.getElementById("menbry"))
|
||||
let option = {
|
||||
grid: {
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 15,
|
||||
bottom: 10,
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
axisTick: {
|
||||
show:false
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: "rgba(64, 105, 121, 0.5)"
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
color: "rgba(173, 230, 238, 1)"
|
||||
},
|
||||
boundaryGap: false,
|
||||
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: "rgba(64, 105, 121, 0.5)"
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
color: "rgba(173, 230, 238, 1)"
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'line',
|
||||
name: 'Email',
|
||||
symbol: 'none',
|
||||
itemStyle:{ normal:{color:"#00a8ff"}},
|
||||
areaStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: "#00a8ff" },
|
||||
{ offset: 1, color: "rgba(255,255,255,0)" },
|
||||
]),
|
||||
},
|
||||
},
|
||||
data: [150, 230, 224, 218, 135, 147, 260],
|
||||
},
|
||||
{
|
||||
type: 'line',
|
||||
name: 'Eml',
|
||||
symbol: 'none',
|
||||
itemStyle:{ normal:{color:"#ffbf2e"}},
|
||||
areaStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: "#ffbf2e" },
|
||||
{ offset: 1, color: "rgba(255,255,255,0)" },
|
||||
]),
|
||||
},
|
||||
},
|
||||
data: [820, 932, 901, 934, 1290, 1330, 1320],
|
||||
}
|
||||
]
|
||||
};
|
||||
this.procesMenbry.content.setOption(option)
|
||||
window.addEventListener("resize", function () {
|
||||
this.procesMenbry.content.resize();
|
||||
});
|
||||
},
|
||||
handlePageChange(page, pageSize) {
|
||||
this.ipagination.current = page
|
||||
this.ipagination.pageSize = pageSize
|
||||
// this.getServerAlarmHistory(this.paramsArg)
|
||||
},
|
||||
handleSizeChange(current, size) {
|
||||
this.ipagination.current = current
|
||||
this.ipagination.pageSize = size
|
||||
// this.getServerAlarmHistory(this.paramsArg)
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.service-search{
|
||||
height: 50px;
|
||||
border-top: 1px solid rgba(13, 235, 201, 0.3);
|
||||
border-bottom: 1px solid rgba(13, 235, 201, 0.3);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 10px;
|
||||
background: rgba(12, 235, 201, 0.05);
|
||||
.ant-row-flex{
|
||||
flex-flow: nowrap;
|
||||
}
|
||||
.item-label{
|
||||
display: inline-block;
|
||||
font-size: 16px;
|
||||
font-family: ArialMT;
|
||||
color: #ade6ee;
|
||||
line-height: 32px;
|
||||
height: 32px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
&-btns{
|
||||
&-ant{
|
||||
background: #406979;
|
||||
border: none;
|
||||
margin-left: 10px;
|
||||
}
|
||||
&-active{
|
||||
background: #1397a3;
|
||||
}
|
||||
}
|
||||
}
|
||||
.service-content{
|
||||
height: calc(100% - 60px);
|
||||
margin-top: 10px;
|
||||
overflow: hidden;
|
||||
&-ranked{
|
||||
height: 210px;
|
||||
&-box{
|
||||
height: 170px;
|
||||
}
|
||||
}
|
||||
&-center{
|
||||
height: 210px;
|
||||
&-item{
|
||||
height: 170px;
|
||||
}
|
||||
}
|
||||
&-table{
|
||||
height: calc(100% - 420px);
|
||||
position: relative;
|
||||
.ant-pagination{
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: 0;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
}
|
||||
.legend-list{
|
||||
list-style:none;
|
||||
li{
|
||||
float: left;
|
||||
font-size: 14px;
|
||||
margin-left: 20px;
|
||||
font-family: MicrosoftYaHei;
|
||||
font-weight: normal;
|
||||
color: #ade6ee;
|
||||
.li-icon{
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 4px;
|
||||
background: red;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue
Block a user