fix: 修复数个bug
1.asset exporter项在编辑asset时隐藏; 2.module 新增时默认端口161/9100; 3.asset detail feature重复数据; 4.刚进入panel时新增chart时不应该有panel选项; 5.overview 流量图表 处理查询折线数据异常的情况; 6.alert-msg和alert-rule二级的msg表头保持一致; 7.alert-rule detail告警数量 靠左对齐
This commit is contained in:
@@ -75,30 +75,34 @@
|
|||||||
|
|
||||||
<div class="content-item-value item-tip" :id="`value-${index}-${i}`" :class="{'content-item-value-muti': Array.isArray(value) && value.length > 0}">
|
<div class="content-item-value item-tip" :id="`value-${index}-${i}`" :class="{'content-item-value-muti': Array.isArray(value) && value.length > 0}">
|
||||||
<template v-if="Array.isArray(value) && value.length>0">
|
<template v-if="Array.isArray(value) && value.length>0">
|
||||||
<div v-if="typeof value[0] == 'string'" class="item-value-sub" v-for="(_item, _index) in value" :key="_index">{{_item}}</div>
|
<template v-if="typeof value[0] == 'string'">
|
||||||
<el-table
|
<div class="item-value-sub" v-for="(_item, _index) in value" :key="_index">{{_item}}</div>
|
||||||
v-else
|
</template>
|
||||||
class="nz-table asset-info-table"
|
<template v-else>
|
||||||
:data="value"
|
<el-table
|
||||||
tooltip-effect="light"
|
class="nz-table asset-info-table"
|
||||||
height="100%"
|
:data="value"
|
||||||
ref="dataTable"
|
tooltip-effect="light"
|
||||||
v-scrollBar:el-table="'small'"
|
height="100%"
|
||||||
>
|
ref="dataTable"
|
||||||
<el-table-column
|
v-scrollBar:el-table="'small'"
|
||||||
:resizable="false"
|
|
||||||
v-for="(_item, _index) in setLabels(value)"
|
|
||||||
v-if="_item.show"
|
|
||||||
:key="`col-${_index}`"
|
|
||||||
:label="_item.label"
|
|
||||||
>
|
>
|
||||||
<template slot-scope="scope" :column="_item">
|
<el-table-column
|
||||||
<template >
|
:resizable="false"
|
||||||
<span v-html="scope.row[_item.prop]"></span>
|
v-for="(_item, _index) in setLabels(value)"
|
||||||
|
v-if="_item.show"
|
||||||
|
:key="`col-${_index}`"
|
||||||
|
:label="_item.label"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope" :column="_item">
|
||||||
|
<template >
|
||||||
|
<span v-html="scope.row[_item.prop]"></span>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</el-table-column>
|
||||||
</el-table-column>
|
</el-table>
|
||||||
</el-table>
|
</template>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="key">
|
<template v-else-if="key">
|
||||||
<span class="content-text">{{value ? value : " "}}</span>
|
<span class="content-text">{{value ? value : " "}}</span>
|
||||||
@@ -201,11 +205,11 @@
|
|||||||
<template v-for="(module, mProjectName, ti) in item.data._module_" v-if="mProjectName == key">
|
<template v-for="(module, mProjectName, ti) in item.data._module_" v-if="mProjectName == key">
|
||||||
<div class="content-item" @click.stop="showDeep(`deep-${index}-${i}-${ti}-${fi}`)" v-for="(moduleNum, moduleName, fi) in module" v-if="moduleName != '_endpoint_'">
|
<div class="content-item" @click.stop="showDeep(`deep-${index}-${i}-${ti}-${fi}`)" v-for="(moduleNum, moduleName, fi) in module" v-if="moduleName != '_endpoint_'">
|
||||||
<div class="content-item-key item-tip deep" :id="`key-${index}-${i}-${ti}-${fi}`">
|
<div class="content-item-key item-tip deep" :id="`key-${index}-${i}-${ti}-${fi}`">
|
||||||
<span class="content-text">
|
<span class="content-text">
|
||||||
<span><i v-if="module._endpoint_[moduleName]" :class="{'el-icon-caret-right': deepShow.indexOf(`deep-${index}-${i}-${ti}-${fi}`) == -1,'el-icon-caret-bottom': deepShow.indexOf(`deep-${index}-${i}-${ti}-${fi}`) > -1}"></i></span>
|
<span><i v-if="module._endpoint_[moduleName]" :class="{'el-icon-caret-right': deepShow.indexOf(`deep-${index}-${i}-${ti}-${fi}`) == -1,'el-icon-caret-bottom': deepShow.indexOf(`deep-${index}-${i}-${ti}-${fi}`) > -1}"></i></span>
|
||||||
<span>{{moduleName}}</span>
|
<span>{{moduleName}}</span>
|
||||||
<!--<span v-if="module._endpoint_[moduleName]">{{Object.keys(module._endpoint_[moduleName]).length-1}}个endpoint</span>-->
|
<!--<span v-if="module._endpoint_[moduleName]">{{Object.keys(module._endpoint_[moduleName]).length-1}}个endpoint</span>-->
|
||||||
</span>
|
</span>
|
||||||
<div class="item-tip-hide item-tip-key el-popover" :class="itemTip(`key-${index}-${i}-${ti}`, moduleName, fi, ready)">{{moduleName}}</div>
|
<div class="item-tip-hide item-tip-key el-popover" :class="itemTip(`key-${index}-${i}-${ti}`, moduleName, fi, ready)">{{moduleName}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content-item-value item-tip deep" :id="`value-${index}-${i}-${ti}-${fi}`">
|
<div class="content-item-value item-tip deep" :id="`value-${index}-${i}-${ti}-${fi}`">
|
||||||
@@ -377,20 +381,15 @@
|
|||||||
this.$chartResizeTool.start(vm, this.data, e);
|
this.$chartResizeTool.start(vm, this.data, e);
|
||||||
},
|
},
|
||||||
setLabels:function(source){
|
setLabels:function(source){
|
||||||
let labels=[];
|
let labels = Object.keys(source[0]);
|
||||||
source.forEach(item=>{
|
labels = labels.map(item=>{
|
||||||
labels=labels.concat(Object.keys(item))
|
|
||||||
})
|
|
||||||
labels=Array.from(new Set(labels));
|
|
||||||
|
|
||||||
labels=labels.map(item=>{
|
|
||||||
return{
|
return{
|
||||||
label:this.replaceSplit(item),
|
label:this.replaceSplit(item),
|
||||||
prop:item,
|
prop:item,
|
||||||
show:true,
|
show:true,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
console.info(labels)
|
console.info(labels);
|
||||||
return labels;
|
return labels;
|
||||||
},
|
},
|
||||||
replaceSplit(key){
|
replaceSplit(key){
|
||||||
|
|||||||
@@ -379,6 +379,16 @@
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
height: 26px;
|
height: 26px;
|
||||||
}
|
}
|
||||||
|
.item-tip.deep:nth-of-type(2) {
|
||||||
|
padding-left: 13px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 26px;
|
||||||
|
}
|
||||||
|
.item-tip.deepp:last-of-type {
|
||||||
|
padding-left: 13px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 26px;
|
||||||
|
}
|
||||||
.tag-value:hover .item-tip-show {
|
.tag-value:hover .item-tip-show {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -276,7 +276,7 @@
|
|||||||
prop: 'endAt',
|
prop: 'endAt',
|
||||||
show: true,
|
show: true,
|
||||||
}, {
|
}, {
|
||||||
label: this.$t('alert.list.current'),
|
label: this.$t('overall.value'),
|
||||||
prop: 'current',
|
prop: 'current',
|
||||||
show: true
|
show: true
|
||||||
}, {
|
}, {
|
||||||
|
|||||||
@@ -509,12 +509,12 @@
|
|||||||
//this.$router.go(-1);
|
//this.$router.go(-1);
|
||||||
},
|
},
|
||||||
getLinkData(){
|
getLinkData(){
|
||||||
console.log('aaa');
|
//console.log('aaa');
|
||||||
this.$get('link').then(response=>{
|
this.$get('link').then(response=>{
|
||||||
console.log(response);
|
//console.log(response);
|
||||||
// this.linkData=response.data;
|
// this.linkData=response.data;
|
||||||
this.$store.commit('setLinkData',response.data);
|
this.$store.commit('setLinkData',response.data);
|
||||||
console.log(this.$store)
|
//console.log(this.$store)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -692,7 +692,7 @@
|
|||||||
immediate: true,
|
immediate: true,
|
||||||
deep: true,
|
deep: true,
|
||||||
handler(n, o) {
|
handler(n, o) {
|
||||||
if (n.type && n.type.toLowerCase() == 'snmp') {
|
if (!n.id && n.type && n.type.toLowerCase() == 'snmp') {
|
||||||
n.port = 161;
|
n.port = 161;
|
||||||
this.expandedWalkData = [];
|
this.expandedWalkData = [];
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
@@ -701,6 +701,8 @@
|
|||||||
for (let i = 0; i < n.walk.length; i++) {
|
for (let i = 0; i < n.walk.length; i++) {
|
||||||
this.expandedWalkData.push(n.walk[i].substring(0, n.walk[i].lastIndexOf(".")));
|
this.expandedWalkData.push(n.walk[i].substring(0, n.walk[i].lastIndexOf(".")));
|
||||||
}
|
}
|
||||||
|
} else if (!n.id && n.type && n.type.toLowerCase() == 'http') {
|
||||||
|
n.port = 9100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -69,9 +69,10 @@
|
|||||||
>
|
>
|
||||||
<template slot-scope="scope" :column="item">
|
<template slot-scope="scope" :column="item">
|
||||||
<template v-if="item.prop == 'alertRule'">
|
<template v-if="item.prop == 'alertRule'">
|
||||||
<div class="link too-long-split"
|
<!--<div class="link too-long-split"
|
||||||
@click="viewRule(scope.row[item.prop].id)" :id="'view-rule-'+scope.row[item.prop].id"
|
@click="viewRule(scope.row[item.prop].id)" :id="'view-rule-'+scope.row[item.prop].id"
|
||||||
v-if="scope.row[item.prop].alertName">{{scope.row[item.prop].alertName}}</div>
|
v-if="scope.row[item.prop].alertName">{{scope.row[item.prop].alertName}}</div>-->
|
||||||
|
<span class="too-long-split"v-if="scope.row[item.prop].alertName">{{scope.row[item.prop].alertName}}</span>
|
||||||
<template v-else>-</template>
|
<template v-else>-</template>
|
||||||
</template>
|
</template>
|
||||||
<!--<div v-else-if="item.prop == 'type'" class="content-right-options">
|
<!--<div v-else-if="item.prop == 'type'" class="content-right-options">
|
||||||
|
|||||||
@@ -73,8 +73,8 @@
|
|||||||
>
|
>
|
||||||
<template slot-scope="scope" :column="item">
|
<template slot-scope="scope" :column="item">
|
||||||
<div v-if="item.prop == 'option'" class="content-right-options">
|
<div v-if="item.prop == 'option'" class="content-right-options">
|
||||||
<span :title="$t('overall.view')" @click="detail(scope.row)" class="content-right-option" :id="'dc-detail-'+scope.row.id"><i class="nz-icon nz-icon-view"></i></span>
|
<!--<span :title="$t('overall.view')" @click="detail(scope.row)" class="content-right-option" :id="'dc-detail-'+scope.row.id"><i class="nz-icon nz-icon-view"></i></span>
|
||||||
|
-->
|
||||||
<span :title="$t('overall.edit')" @click="edit(scope.row)" class="content-right-option" :id="'dc-edit-'+scope.row.id"><i class="nz-icon nz-icon-edit"></i></span>
|
<span :title="$t('overall.edit')" @click="edit(scope.row)" class="content-right-option" :id="'dc-edit-'+scope.row.id"><i class="nz-icon nz-icon-edit"></i></span>
|
||||||
|
|
||||||
<span :title="$t('overall.delete')" @click="del(scope.row)" class="content-right-option" :id="'dc-del-'+scope.row.id"><i class="el-icon-delete"></i></span>
|
<span :title="$t('overall.delete')" @click="del(scope.row)" class="content-right-option" :id="'dc-del-'+scope.row.id"><i class="el-icon-delete"></i></span>
|
||||||
|
|||||||
@@ -394,13 +394,13 @@
|
|||||||
'promql-input': promqlInput,
|
'promql-input': promqlInput,
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
if(this.showPanel){
|
|
||||||
this.panelName2 = this.showPanel.name;
|
|
||||||
}
|
|
||||||
this.rightBox.show = true;
|
this.rightBox.show = true;
|
||||||
this.isUrl = false;
|
this.isUrl = false;
|
||||||
this.isSingleStat = false;
|
this.isSingleStat = false;
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
|
if(this.showPanel){
|
||||||
|
this.panelName2 = this.showPanel.name;
|
||||||
|
}
|
||||||
this.initElements();
|
this.initElements();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -494,77 +494,88 @@
|
|||||||
queryAlertTrendData() {
|
queryAlertTrendData() {
|
||||||
this.$refs.chartbox.startLoading();
|
this.$refs.chartbox.startLoading();
|
||||||
this.chartSeries = [];
|
this.chartSeries = [];
|
||||||
|
let rxPromise = new Promise((resolve, reject) => {
|
||||||
this.$get('/prom/api/v1/query_range', this.trendParamHandle('rx')).then(response=>{
|
this.$get('/prom/api/v1/query_range', this.trendParamHandle('rx')).then(response=>{
|
||||||
if(response.status == 'success'){
|
if(response.status == 'success'){
|
||||||
if(response.data.result){
|
if(response.data.result){
|
||||||
let series={
|
let series={
|
||||||
name: 'RX',
|
name: 'RX',
|
||||||
symbol:'none', //去掉点
|
symbol:'none', //去掉点
|
||||||
smooth:0.2, //曲线变平滑
|
smooth:0.2, //曲线变平滑
|
||||||
data: [],
|
data: [],
|
||||||
type:'line',
|
type:'line',
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
width: 1,
|
width: 1,
|
||||||
opacity: 0.9
|
opacity: 0.9
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
if (response.data.result.length > 0) {
|
if (response.data.result.length > 0) {
|
||||||
series.data=response.data.result[0].values.map((item)=>{
|
series.data=response.data.result[0].values.map((item)=>{
|
||||||
return [item[0]*1000,item[1]];
|
return [item[0]*1000,item[1]];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.chartSeries.push(series);
|
this.chartSeries.push(series);
|
||||||
if (this.chartSeries.length == 2) {
|
if (this.chartSeries.length == 2) {
|
||||||
this.$refs.chartbox.modifyOption("tooltip", "backgroundColor", "rgba(221,228,237,1)");
|
this.$refs.chartbox.modifyOption("tooltip", "backgroundColor", "rgba(221,228,237,1)");
|
||||||
this.$refs.chartbox.modifyOption("tooltip", "textStyle", {color: "#000"});
|
this.$refs.chartbox.modifyOption("tooltip", "textStyle", {color: "#000"});
|
||||||
this.$refs.chartbox.modifyOption("grid", "top", 30);
|
this.$refs.chartbox.modifyOption("grid", "top", 30);
|
||||||
this.$refs.chartbox.modifyOption("grid", "left", 0);
|
this.$refs.chartbox.modifyOption("grid", "left", 0);
|
||||||
this.$refs.chartbox.modifyOption("grid", "right", 30);
|
this.$refs.chartbox.modifyOption("grid", "right", 30);
|
||||||
this.$refs.chartbox.modifyOption("grid", "bottom", 8);
|
this.$refs.chartbox.modifyOption("grid", "bottom", 8);
|
||||||
this.$refs.chartbox.modifyOption("grid", "containLabel", true);
|
this.$refs.chartbox.modifyOption("grid", "containLabel", true);
|
||||||
this.$refs.chartbox.setSeries(this.chartSeries);
|
this.$refs.chartbox.setSeries(this.chartSeries);
|
||||||
this.$refs.chartbox.endLoading();
|
}
|
||||||
}
|
}
|
||||||
|
resolve(true);
|
||||||
|
}else{
|
||||||
|
console.error(response);
|
||||||
|
resolve(false);
|
||||||
}
|
}
|
||||||
}else{
|
});
|
||||||
console.error(response)
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
this.$get('/prom/api/v1/query_range', this.trendParamHandle('tx')).then(response=>{
|
let txPromise = new Promise((resolve, reject) => {
|
||||||
if(response.status == 'success'){
|
this.$get('/prom/api/v1/query_range', this.trendParamHandle('tx')).then(response=>{
|
||||||
if(response.data.result){
|
if(response.status == 'success'){
|
||||||
let series={
|
if(response.data.result){
|
||||||
name: 'TX',
|
let series={
|
||||||
symbol:'none', //去掉点
|
name: 'TX',
|
||||||
smooth:0.2, //曲线变平滑
|
symbol:'none', //去掉点
|
||||||
data: [],
|
smooth:0.2, //曲线变平滑
|
||||||
type:'line',
|
data: [],
|
||||||
lineStyle: {
|
type:'line',
|
||||||
width: 1,
|
lineStyle: {
|
||||||
opacity: 0.9
|
width: 1,
|
||||||
},
|
opacity: 0.9
|
||||||
};
|
},
|
||||||
if (response.data.result.length > 0) {
|
};
|
||||||
series.data=response.data.result[0].values.map((item)=>{
|
if (response.data.result.length > 0) {
|
||||||
return [item[0]*1000,item[1]];
|
series.data=response.data.result[0].values.map((item)=>{
|
||||||
});
|
return [item[0]*1000,item[1]];
|
||||||
}
|
});
|
||||||
this.chartSeries.push(series);
|
}
|
||||||
if (this.chartSeries.length == 2) {
|
this.chartSeries.push(series);
|
||||||
this.$refs.chartbox.modifyOption("tooltip", "backgroundColor", "rgba(221,228,237,1)");
|
if (this.chartSeries.length == 2) {
|
||||||
this.$refs.chartbox.modifyOption("tooltip", "textStyle", {color: "#000"});
|
this.$refs.chartbox.modifyOption("tooltip", "backgroundColor", "rgba(221,228,237,1)");
|
||||||
this.$refs.chartbox.modifyOption("grid", "top", 30);
|
this.$refs.chartbox.modifyOption("tooltip", "textStyle", {color: "#000"});
|
||||||
this.$refs.chartbox.modifyOption("grid", "left", 0);
|
this.$refs.chartbox.modifyOption("grid", "top", 30);
|
||||||
this.$refs.chartbox.modifyOption("grid", "right", 30);
|
this.$refs.chartbox.modifyOption("grid", "left", 0);
|
||||||
this.$refs.chartbox.modifyOption("grid", "bottom", 8);
|
this.$refs.chartbox.modifyOption("grid", "right", 30);
|
||||||
this.$refs.chartbox.setSeries(this.chartSeries);
|
this.$refs.chartbox.modifyOption("grid", "bottom", 8);
|
||||||
this.$refs.chartbox.endLoading();
|
this.$refs.chartbox.setSeries(this.chartSeries);
|
||||||
|
//this.$refs.chartbox.endLoading();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
resolve(true);
|
||||||
|
}else{
|
||||||
|
console.error(response)
|
||||||
|
resolve(false);
|
||||||
}
|
}
|
||||||
}else{
|
});
|
||||||
console.error(response)
|
});
|
||||||
}
|
Promise.all([rxPromise, txPromise]).then(resolve => {
|
||||||
|
this.$refs.chartbox.endLoading();
|
||||||
|
}, reject => {
|
||||||
|
this.$refs.chartbox.endLoading();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
trendParamHandle(t) {
|
trendParamHandle(t) {
|
||||||
|
|||||||
@@ -226,7 +226,7 @@
|
|||||||
}
|
}
|
||||||
this.filter.searchName='';
|
this.filter.searchName='';
|
||||||
//this.$refs.searchInput.select();
|
//this.$refs.searchInput.select();
|
||||||
this.showPanel = val
|
this.showPanel = val;
|
||||||
this.filter.panelId = this.showPanel.id;
|
this.filter.panelId = this.showPanel.id;
|
||||||
// let curTime = this.$refs.calendarPanel.getCurrentTime();
|
// let curTime = this.$refs.calendarPanel.getCurrentTime();
|
||||||
let curTime=this.searchTime;
|
let curTime=this.searchTime;
|
||||||
@@ -429,15 +429,13 @@
|
|||||||
let isInitData = false;
|
let isInitData = false;
|
||||||
if (response.data.list.length > 0) {
|
if (response.data.list.length > 0) {
|
||||||
if (this.$store.state.showPanel.id !== 0 && this.$store.state.showPanel.name !== '') {
|
if (this.$store.state.showPanel.id !== 0 && this.$store.state.showPanel.name !== '') {
|
||||||
this.showPanel.name = this.$store.state.showPanel.name;
|
this.showPanel = this.$store.state.showPanel;
|
||||||
this.showPanel.id = this.$store.state.showPanel.id;
|
|
||||||
}
|
}
|
||||||
if (clearShowPanel) {
|
if (clearShowPanel) {
|
||||||
this.showPanel.id = '';
|
this.showPanel.id = '';
|
||||||
}
|
}
|
||||||
if (this.showPanel.id === '') {
|
if (!this.showPanel.id) {
|
||||||
this.showPanel.id = response.data.list[0].id;
|
this.showPanel = response.data.list[0];
|
||||||
this.showPanel.name = response.data.list[0].name;
|
|
||||||
this.filter.panelId = this.showPanel.id;
|
this.filter.panelId = this.showPanel.id;
|
||||||
this.getData(this.filter);
|
this.getData(this.filter);
|
||||||
isInitData = true;
|
isInitData = true;
|
||||||
@@ -453,7 +451,7 @@
|
|||||||
}
|
}
|
||||||
this.$store.state.showPanel.id = 0;
|
this.$store.state.showPanel.id = 0;
|
||||||
this.$store.state.showPanel.name = '';
|
this.$store.state.showPanel.name = '';
|
||||||
|
this.$store.state.showPanel.type = 'dashboard';
|
||||||
}else {
|
}else {
|
||||||
if(response.msg){
|
if(response.msg){
|
||||||
this.$message.error(response.msg);
|
this.$message.error(response.msg);
|
||||||
@@ -580,7 +578,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.panelDataDragTmp = [...this.panelData];
|
this.panelDataDragTmp = [...this.panelData];
|
||||||
console.log(this.panelDataDragTmp)
|
//console.log(this.panelDataDragTmp)
|
||||||
},
|
},
|
||||||
end (event) {
|
end (event) {
|
||||||
// console.info("end event:", event)
|
// console.info("end event:", event)
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ const store = new Vuex.Store({
|
|||||||
},
|
},
|
||||||
showPanel:{
|
showPanel:{
|
||||||
id:0,
|
id:0,
|
||||||
name:''
|
name:'',
|
||||||
|
type: "dashboard"
|
||||||
},
|
},
|
||||||
consoleShow:false,//是否显示console窗口
|
consoleShow:false,//是否显示console窗口
|
||||||
consoleCount:0,//当前console窗口数
|
consoleCount:0,//当前console窗口数
|
||||||
|
|||||||
Reference in New Issue
Block a user