[前台] 系統監控 樓層頁面 forge 與圖檔大小修正 | 運維管理 異常代號縮短 | 電梯與感測器同步 bug 修正 | index.html 還原
This commit is contained in:
parent
55bff6fca3
commit
dc379c32fd
@ -633,6 +633,9 @@
|
|||||||
{
|
{
|
||||||
"title": "異常代號",
|
"title": "異常代號",
|
||||||
"data": "error_code",
|
"data": "error_code",
|
||||||
|
render: (data) => {
|
||||||
|
return data?.split('-')[0];
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "表單號",
|
"title": "表單號",
|
||||||
|
@ -417,6 +417,24 @@
|
|||||||
"building_tag": pageAct.buiTag,
|
"building_tag": pageAct.buiTag,
|
||||||
},
|
},
|
||||||
selector: "[name=forgeViewer]",
|
selector: "[name=forgeViewer]",
|
||||||
|
elevCb: () => {
|
||||||
|
let elevOption = {
|
||||||
|
selector: "[name=forgeViewer]",
|
||||||
|
viewer: viewer,
|
||||||
|
ordPath: {
|
||||||
|
"area_tag": pageAct.AreaTag,
|
||||||
|
"building_tag": pageAct.buiTag,
|
||||||
|
},
|
||||||
|
sensorObjs
|
||||||
|
}
|
||||||
|
|
||||||
|
// 電梯移動訂閱程序載入
|
||||||
|
let forge3DElev = new Forge3DElevFull(elevOption);
|
||||||
|
forge3DElev.bajaEndCallback = function () {
|
||||||
|
endPageLoading();
|
||||||
|
}
|
||||||
|
forge3DElev.init();
|
||||||
|
},
|
||||||
curDevice: {
|
curDevice: {
|
||||||
...device,
|
...device,
|
||||||
roomDbId: !isNaN(parseInt(device.room_dbid)) ? parseInt(device.room_dbid) : -1,
|
roomDbId: !isNaN(parseInt(device.room_dbid)) ? parseInt(device.room_dbid) : -1,
|
||||||
@ -438,6 +456,21 @@
|
|||||||
temp: 0,
|
temp: 0,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
let elevOption = {
|
||||||
|
selector: "[name=forgeViewer]",
|
||||||
|
viewer: viewer,
|
||||||
|
ordPath: {
|
||||||
|
"area_tag": pageAct.AreaTag,
|
||||||
|
"building_tag": pageAct.buiTag,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 電梯移動訂閱程序載入
|
||||||
|
let forge3DElev = new Forge3DElevFull(elevOption);
|
||||||
|
forge3DElev.bajaEndCallback = function () {
|
||||||
|
endPageLoading();
|
||||||
|
}
|
||||||
|
forge3DElev.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
let option = {
|
let option = {
|
||||||
@ -453,23 +486,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let elevOption = {
|
|
||||||
selector: "[name=forgeViewer]",
|
|
||||||
viewer: viewer,
|
|
||||||
ordPath: {
|
|
||||||
"area_tag": pageAct.AreaTag,
|
|
||||||
"building_tag": pageAct.buiTag,
|
|
||||||
},
|
|
||||||
sensorObjs
|
|
||||||
}
|
|
||||||
|
|
||||||
// 電梯移動訂閱程序載入
|
|
||||||
let forge3DElev = new Forge3DElevFull(elevOption);
|
|
||||||
forge3DElev.bajaEndCallback = function () {
|
|
||||||
endPageLoading();
|
|
||||||
}
|
|
||||||
forge3DElev.init();
|
|
||||||
|
|
||||||
if (subDeviceData.length != 0) {
|
if (subDeviceData.length != 0) {
|
||||||
let stSubArr = subDeviceData.map(x => Object.keys(x).filter(y => y == "ST").map(y => x));
|
let stSubArr = subDeviceData.map(x => Object.keys(x).filter(y => y == "ST").map(y => x));
|
||||||
|
|
||||||
@ -587,6 +603,7 @@
|
|||||||
|
|
||||||
var parentEle = "";
|
var parentEle = "";
|
||||||
onEvent("autodesk:click:sprite", "[name=forgeViewer]", function (e, obj) {
|
onEvent("autodesk:click:sprite", "[name=forgeViewer]", function (e, obj) {
|
||||||
|
console.log("aaa", obj)
|
||||||
forgeUnFocusAll();
|
forgeUnFocusAll();
|
||||||
let position = [obj.event.target.toolController.lastClickX - 100, obj.event.target.toolController.lastClickY - 100];
|
let position = [obj.event.target.toolController.lastClickX - 100, obj.event.target.toolController.lastClickY - 100];
|
||||||
let devObj = obj.myData;
|
let devObj = obj.myData;
|
||||||
|
@ -15,13 +15,17 @@
|
|||||||
</div> -->
|
</div> -->
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<div class="col-6 my-3">
|
<div class="col-6 my-3">
|
||||||
<div id="floChart" style="height:80vh!important;width:100%"></div>
|
<div id="floChart" style="height: 100%;width:100%; background-color: #fff;"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6 my-3">
|
<div class="col-6 my-3">
|
||||||
<div id="forgeHeatBarDiv" class="d-flex mb-4" style="gap:15px">
|
<!-- <div id="forgeViewer" class="position-relative" style="height:100%">
|
||||||
|
<div id="forgeHeatBarDiv" class="d-flex mb-4 position-absolute" style="gap:15px">
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
<div id="forgeViewer" class="position-relative" style="height:80vh">
|
||||||
|
<div id="forgeHeatBarDiv" class="d-flex mb-4 position-absolute" style="gap:15px">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="forgeViewer"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -453,7 +457,7 @@
|
|||||||
let cloDevPoiName = matchDevice.device_close_point_name;
|
let cloDevPoiName = matchDevice.device_close_point_name;
|
||||||
let errDevPoiName = matchDevice.device_error_point_name;
|
let errDevPoiName = matchDevice.device_error_point_name;
|
||||||
|
|
||||||
if (data.point_name == "Temp") {
|
if (data.point_name == "Temp" || data.point_name == "TEMP") {
|
||||||
heatMap?.changeTemp(data.device_number_full, !isNaN(parseInt(data.value)) ? parseInt(data.value) : 0);
|
heatMap?.changeTemp(data.device_number_full, !isNaN(parseInt(data.value)) ? parseInt(data.value) : 0);
|
||||||
let devIdx = currentData.findIndex(x => x.device_number == data.device_number_full);
|
let devIdx = currentData.findIndex(x => x.device_number == data.device_number_full);
|
||||||
currentData[devIdx]._temp = !isNaN(parseInt(data.value)) ? parseInt(data.value) : 0;
|
currentData[devIdx]._temp = !isNaN(parseInt(data.value)) ? parseInt(data.value) : 0;
|
||||||
@ -483,7 +487,7 @@
|
|||||||
|
|
||||||
floMyBaja.setSubscribeDeviceEndCallBack(function (data) {
|
floMyBaja.setSubscribeDeviceEndCallBack(function (data) {
|
||||||
endPageLoading();
|
endPageLoading();
|
||||||
if (data.findIndex(x => x.point_name == "Temp") != -1) {
|
if (pageAct.sysSubTag !== "M12" && (data.findIndex(x => x.point_name == "Temp" || x.point_name == "TEMP") != -1)) {
|
||||||
// 顯示溫度條
|
// 顯示溫度條
|
||||||
showHeat("[name=forgeHeatBar]");
|
showHeat("[name=forgeHeatBar]");
|
||||||
}
|
}
|
||||||
@ -1061,6 +1065,8 @@
|
|||||||
function show3DModel(urn) {
|
function show3DModel(urn) {
|
||||||
$(loadEle).Loading("start");
|
$(loadEle).Loading("start");
|
||||||
launchViewerForHotspot(urn, (viewer, nodeIds) => {
|
launchViewerForHotspot(urn, (viewer, nodeIds) => {
|
||||||
|
// 隱藏 toolbar
|
||||||
|
document.querySelector("#guiviewer3d-toolbar").style.display = "none";
|
||||||
let nextFloor = getNextFloor(pageAct.floGuid);
|
let nextFloor = getNextFloor(pageAct.floGuid);
|
||||||
let curFloTag = pageAct.floTag;
|
let curFloTag = pageAct.floTag;
|
||||||
|
|
||||||
@ -1099,8 +1105,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setHeatMap() {
|
function setHeatMap() {
|
||||||
if (pageAct.sysMainTag !== "LT") {
|
if (pageAct.sysMainTag !== "LT" && pageAct.sysSubTag !== "M12") {
|
||||||
let devices = currentData.map(x => {
|
devices = currentData.map(x => {
|
||||||
return {
|
return {
|
||||||
roomDbId: !isNaN(parseInt(x.room_dbid)) ? parseInt(x.room_dbid) : -1,
|
roomDbId: !isNaN(parseInt(x.room_dbid)) ? parseInt(x.room_dbid) : -1,
|
||||||
id: x.device_number,
|
id: x.device_number,
|
||||||
@ -1109,6 +1115,9 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
console.log("floor", devices)
|
||||||
|
|
||||||
let option = {
|
let option = {
|
||||||
devices: devices,
|
devices: devices,
|
||||||
}
|
}
|
||||||
|
2573
Frontend/index.html
2573
Frontend/index.html
File diff suppressed because it is too large
Load Diff
@ -220,11 +220,6 @@ class elevator3D {
|
|||||||
// 設置當前片段的位置
|
// 設置當前片段的位置
|
||||||
fragProxy.position = fragPosition;
|
fragProxy.position = fragPosition;
|
||||||
|
|
||||||
// if(nodeId === 13704) {
|
|
||||||
// // 改變感測器熱點位置
|
|
||||||
// this.sensorObjs&&this.sensorObjs[0]?.changePos(13706, fragProxy.position.z)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 更新當前片段的動畫變換矩陣
|
// 更新當前片段的動畫變換矩陣
|
||||||
fragProxy.updateAnimTransform();
|
fragProxy.updateAnimTransform();
|
||||||
})
|
})
|
||||||
@ -305,9 +300,9 @@ class elevator3D {
|
|||||||
}
|
}
|
||||||
fragProxyZ = fragProxy.position.z;
|
fragProxyZ = fragProxy.position.z;
|
||||||
|
|
||||||
if (nodeId === 13704) {
|
if (nodeId === 13777) {
|
||||||
// 改變感測器熱點位置
|
// 改變感測器熱點位置
|
||||||
this.sensorObjs && this.sensorObjs[0]?.changePos(13706, fragProxyZ)
|
this.sensorObjs && this.sensorObjs[0]?.changePos(nodeId + 2, fragProxyZ)
|
||||||
}
|
}
|
||||||
fragProxy.updateAnimTransform()
|
fragProxy.updateAnimTransform()
|
||||||
})
|
})
|
||||||
@ -748,7 +743,7 @@ async function testNewLight(dataList) {
|
|||||||
dataList.forEach((myData, index) => {
|
dataList.forEach((myData, index) => {
|
||||||
const position = JSON.parse(myData.device_coordinate_3d);
|
const position = JSON.parse(myData.device_coordinate_3d);
|
||||||
if (lightList.findIndex(x => x.device_guid == myData.device_guid) == -1) {
|
if (lightList.findIndex(x => x.device_guid == myData.device_guid) == -1) {
|
||||||
lightList.push({ dbid: myData.forge_dbid, device_guid: myData.device_guid, lightObject: new THREE.SpotLight(0xe1cf18, 200, 20, 0.6, 0.5, 10) });
|
lightList.push({ dbid: myData.forge_dbid, device_guid: myData.device_guid, lightObject: new THREE.SpotLight(0xe1cf18, 0, 20, 0.6, 0.5, 10) });
|
||||||
}
|
}
|
||||||
|
|
||||||
lightList[index].lightObject.position.set(position.x, position.y, position.z);
|
lightList[index].lightObject.position.set(position.x, position.y, position.z);
|
||||||
@ -776,7 +771,7 @@ async function addHotPoint(data) {
|
|||||||
let spriteIcon = "";
|
let spriteIcon = "";
|
||||||
const dbIdStart = 10;
|
const dbIdStart = 10;
|
||||||
const dbIdEnd = 19;
|
const dbIdEnd = 19;
|
||||||
if (pageAct.sysSubTag === "M12") {
|
if (pageAct.sysSubTag === "M12" && !pageAct.floTag) {
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
spriteColor = new THREE.Color(0xffffff);
|
spriteColor = new THREE.Color(0xffffff);
|
||||||
@ -886,8 +881,8 @@ async function addHotPoint(data) {
|
|||||||
// 熱點 更換顏色
|
// 熱點 更換顏色
|
||||||
async function changeColorForHotspot(dbId, type = null) {
|
async function changeColorForHotspot(dbId, type = null) {
|
||||||
const dataVizExtn = await viewer.loadExtension("Autodesk.DataVisualization");
|
const dataVizExtn = await viewer.loadExtension("Autodesk.DataVisualization");
|
||||||
console.log(dbId, dataVizExtn.viewableData.getViewableColor(dbId, false))
|
// console.log(dbId, dataVizExtn.viewableData.getViewableColor(dbId, false))
|
||||||
let spriteColorFocus = dataVizExtn.viewableData?.getViewableColor(dbId, false) || new THREE.Color(0xffffff);
|
let spriteColorFocus = new THREE.Color(0xffffff);
|
||||||
if (type == "focus" && pageAct.sysSubTag !== "M12") {
|
if (type == "focus" && pageAct.sysSubTag !== "M12") {
|
||||||
spriteColorFocus = new THREE.Color(0x00ffe1);
|
spriteColorFocus = new THREE.Color(0x00ffe1);
|
||||||
} else if (type == "error") {
|
} else if (type == "error") {
|
||||||
@ -1145,7 +1140,7 @@ function profile(callback = null) {
|
|||||||
//新增燈光
|
//新增燈光
|
||||||
async function newLight(lightPosition) {
|
async function newLight(lightPosition) {
|
||||||
//聚光燈
|
//聚光燈
|
||||||
var spotLight = new THREE.SpotLight(0xffffff, 200, 20, 0.6, 0.5, 10);
|
var spotLight = new THREE.SpotLight(0xe1cf18, 0, 20, 0.6, 0.5, 10);
|
||||||
spotLight.position.set(lightPosition.x, lightPosition.y, lightPosition.z);
|
spotLight.position.set(lightPosition.x, lightPosition.y, lightPosition.z);
|
||||||
// console.log(lightPosition.x, lightPosition.y, lightPosition.z)
|
// console.log(lightPosition.x, lightPosition.y, lightPosition.z)
|
||||||
spotLight.castShadow = false;
|
spotLight.castShadow = false;
|
||||||
|
@ -595,11 +595,10 @@ class Forge3DElevFull {
|
|||||||
|
|
||||||
frags.forEach((fragProxy) => {
|
frags.forEach((fragProxy) => {
|
||||||
fragProxy.frag.position.z = this.elev3DOption.floorHeight.filter(x => x.floor == subData["CP"])[0]?.height ?? 0;
|
fragProxy.frag.position.z = this.elev3DOption.floorHeight.filter(x => x.floor == subData["CP"])[0]?.height ?? 0;
|
||||||
console.log("1", fragProxy.frag.position.z)
|
|
||||||
let start = 0;
|
let start = 0;
|
||||||
if (node === 13704 && start == 0) {
|
if (node === 13777 && start == 0) {
|
||||||
// 改變感測器熱點位置
|
// 改變感測器熱點位置
|
||||||
this.sensorObjs && this.sensorObjs[0]?.changePos(13706, fragProxy.frag.position.z);
|
this.sensorObjs && this.sensorObjs[0]?.changePos(node + 2, fragProxy.frag.position.z);
|
||||||
start = 1;
|
start = 1;
|
||||||
}
|
}
|
||||||
fragProxy.frag.updateAnimTransform();
|
fragProxy.frag.updateAnimTransform();
|
||||||
@ -649,12 +648,10 @@ class Forge3DElevFull {
|
|||||||
let frags = elevObj.obj.fragProxys.filter(x => x.nodeId == node);
|
let frags = elevObj.obj.fragProxys.filter(x => x.nodeId == node);
|
||||||
frags.forEach((fragProxy) => {
|
frags.forEach((fragProxy) => {
|
||||||
fragProxy.frag.position.z = this.elev3DOption.floorHeight.filter(x => x.floor == subData["CP"])[0]?.height ?? 0;
|
fragProxy.frag.position.z = this.elev3DOption.floorHeight.filter(x => x.floor == subData["CP"])[0]?.height ?? 0;
|
||||||
console.log("2", fragProxy.frag.position.z)
|
|
||||||
// debugger
|
|
||||||
let start = 0;
|
let start = 0;
|
||||||
if (node === 13704 && start == 0) {
|
if (node === 13777 && start == 0) {
|
||||||
// 改變感測器熱點位置
|
// 改變感測器熱點位置
|
||||||
this.sensorObjs && this.sensorObjs[0]?.changePos(13706, fragProxy.frag.position.z);
|
this.sensorObjs && this.sensorObjs[0]?.changePos(node + 2, fragProxy.frag.position.z);
|
||||||
start = 1;
|
start = 1;
|
||||||
}
|
}
|
||||||
fragProxy.frag.updateAnimTransform()
|
fragProxy.frag.updateAnimTransform()
|
||||||
@ -717,6 +714,8 @@ class Forge3DSensor {
|
|||||||
this.DataVizCore = null;
|
this.DataVizCore = null;
|
||||||
this.tempVal = 20;
|
this.tempVal = 20;
|
||||||
this.curDevice = option.curDevice ?? null;
|
this.curDevice = option.curDevice ?? null;
|
||||||
|
this.selector = option.selector ?? "#forgeViewer"
|
||||||
|
this.elevCb = option.elevCb ?? null
|
||||||
this.#init();
|
this.#init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -729,6 +728,7 @@ class Forge3DSensor {
|
|||||||
await this.addHotPoint();
|
await this.addHotPoint();
|
||||||
this.changeColorForSensorHotspot(this.curDevice.forge_dbid, 35)
|
this.changeColorForSensorHotspot(this.curDevice.forge_dbid, 35)
|
||||||
this.subSensorDevice();
|
this.subSensorDevice();
|
||||||
|
this.elevCb()
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -745,7 +745,7 @@ class Forge3DSensor {
|
|||||||
async registerHotPoint(color = "") {
|
async registerHotPoint(color = "") {
|
||||||
var viewer = this.viewer;
|
var viewer = this.viewer;
|
||||||
const viewableType = this.DataVizCore.ViewableType.SPRITE;//DataVizCore.ViewableType.SPRITE;
|
const viewableType = this.DataVizCore.ViewableType.SPRITE;//DataVizCore.ViewableType.SPRITE;
|
||||||
const spriteColor = new THREE.Color(0x000000);
|
const spriteColor = new THREE.Color(0xff8c00);
|
||||||
// const highlightedColor = new THREE.Color(0xe0e0ff);
|
// const highlightedColor = new THREE.Color(0xe0e0ff);
|
||||||
let spriteIcon = "/file/img/forge/sensor_circle.svg";
|
let spriteIcon = "/file/img/forge/sensor_circle.svg";
|
||||||
if (location.href.indexOf("localhost:5966") != -1) {
|
if (location.href.indexOf("localhost:5966") != -1) {
|
||||||
@ -769,32 +769,32 @@ class Forge3DSensor {
|
|||||||
await viewableData.finish();
|
await viewableData.finish();
|
||||||
this.dataVizExtn.addViewables(viewableData);
|
this.dataVizExtn.addViewables(viewableData);
|
||||||
// console.log("1",this.dataVizExtn)
|
// console.log("1",this.dataVizExtn)
|
||||||
viewer.addEventListener(this.DataVizCore.MOUSE_CLICK, onSpriteClicked.bind(this));// SPRITE_SELECTED
|
viewer.addEventListener(this.DataVizCore.MOUSE_CLICK, this.onSpriteClicked.bind(this));// SPRITE_SELECTED
|
||||||
|
// viewer.addEventListener(this.DataVizCore.MOUSE_CLICK_OUT, onSpriteClickedOut.bind(this));
|
||||||
|
|
||||||
|
}
|
||||||
// ---------------- 熱點點擊事件 --------------------
|
// ---------------- 熱點點擊事件 --------------------
|
||||||
function onSpriteClicked(event) {
|
onSpriteClicked(event) {
|
||||||
|
console.log(event)
|
||||||
event.hasStopped = true;
|
event.hasStopped = true;
|
||||||
const dbIdStart = 10;
|
const dbIdStart = 10;
|
||||||
// debugger
|
|
||||||
if (event != undefined && event != null) {
|
if (event != undefined && event != null) {
|
||||||
if (event.dbId >= dbIdStart) {
|
if (event.dbId >= dbIdStart) {
|
||||||
changeColorForHotspot(event.dbId);
|
|
||||||
changeScaleForHotspot(event.dbId, false);
|
|
||||||
let myData = [this.curDevice].filter(x => x.forge_dbid == event.dbId)[0];
|
let myData = [this.curDevice].filter(x => x.forge_dbid == event.dbId)[0];
|
||||||
|
this.changeColorForSensorHotspot(event.dbId, this.tempVal)
|
||||||
moveViewToDevice(myData.forge_dbid);//移動視角至該設備
|
moveViewToDevice(myData.forge_dbid);//移動視角至該設備
|
||||||
|
$(this.selector).trigger("autodesk:click:sprite", { event, myData });
|
||||||
$(selector).trigger("autodesk:click:sprite", { event, myData });
|
|
||||||
} else {
|
} else {
|
||||||
$(selector).trigger("autodesk:clickOut:sprite", { event });
|
$(this.selector).trigger("autodesk:clickOut:sprite", { event });
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 改變熱點位置
|
// 改變熱點位置
|
||||||
changePos(dbId, positionZ) {
|
async changePos(dbId, positionZ) {
|
||||||
this.dataVizExtn.invalidateViewables(dbId, (viewable) => {
|
// const dataVizExtn = await viewer.loadExtension("Autodesk.DataVisualization") || this.dataVizExtn;
|
||||||
|
this.dataVizExtn?.invalidateViewables(dbId, (viewable) => {
|
||||||
// console.log(viewable._position)
|
// console.log(viewable._position)
|
||||||
const z = viewable._position.z + positionZ
|
const z = viewable._position.z + positionZ
|
||||||
const newPos = { ...viewable._position, z }
|
const newPos = { ...viewable._position, z }
|
||||||
@ -806,7 +806,8 @@ class Forge3DSensor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 熱點 更換顏色---環境感知器
|
// 熱點 更換顏色---環境感知器
|
||||||
changeColorForSensorHotspot(dbId, temp) {
|
async changeColorForSensorHotspot(dbId, temp) {
|
||||||
|
// const dataVizExtn = await viewer.loadExtension("Autodesk.DataVisualization");
|
||||||
const temps = [new THREE.Color(0x00009c), new THREE.Color(0xffff31), new THREE.Color(0xff8c00), new THREE.Color(0xff0000)]
|
const temps = [new THREE.Color(0x00009c), new THREE.Color(0xffff31), new THREE.Color(0xff8c00), new THREE.Color(0xff0000)]
|
||||||
let index = Math.floor(temp / 10) - 1 || 0;
|
let index = Math.floor(temp / 10) - 1 || 0;
|
||||||
if (index > 3) {
|
if (index > 3) {
|
||||||
|
Loading…
Reference in New Issue
Block a user