提交
This commit is contained in:
@ -66,7 +66,7 @@ stopBatPath = process.platform === 'win32' ? stopBatPath.replace(/^(\w:)/, '/$1'
|
|||||||
// process.env.NODE_ENV === 'development'
|
// process.env.NODE_ENV === 'development'
|
||||||
// ? `${join(app.getAppPath(), 'src/renderer/public/startUp/startUp.html')}`
|
// ? `${join(app.getAppPath(), 'src/renderer/public/startUp/startUp.html')}`
|
||||||
// : `file://${join(app.getAppPath(), 'resources/app.asar/out/renderer/startUp/startUp.html')}`
|
// : `file://${join(app.getAppPath(), 'resources/app.asar/out/renderer/startUp/startUp.html')}`
|
||||||
|
let isRestart = false
|
||||||
function createWindow(): void {
|
function createWindow(): void {
|
||||||
// Create the browser window.
|
// Create the browser window.
|
||||||
|
|
||||||
@ -114,8 +114,12 @@ function createWindow(): void {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
ipcMain.on("restart", () => {
|
ipcMain.on("restart", () => {
|
||||||
app.relaunch();
|
// app.relaunch();
|
||||||
forceQuit();
|
// app.quit();
|
||||||
|
// cleanupProcess.kill();
|
||||||
|
// app.relaunch();
|
||||||
|
isRestart = true
|
||||||
|
windowAllClosed()
|
||||||
});
|
});
|
||||||
// 监听启动页完成的消息
|
// 监听启动页完成的消息
|
||||||
ipcMain.on('splash-completed', () => {
|
ipcMain.on('splash-completed', () => {
|
||||||
@ -173,6 +177,20 @@ function createWindow(): void {
|
|||||||
event.sender.send("selectedFileItem", path);
|
event.sender.send("selectedFileItem", path);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
ipcMain.handle('getIsFullScreen', () => {
|
||||||
|
return mainWindow.isFullScreen()
|
||||||
|
});
|
||||||
|
ipcMain.on('toggle-fullscreen', (event) => {
|
||||||
|
const win = BrowserWindow.fromWebContents(event.sender);
|
||||||
|
win!.setFullScreen(!win!.isFullScreen());
|
||||||
|
});
|
||||||
|
mainWindow.on('enter-full-screen', () => {
|
||||||
|
mainWindow.webContents.send('fullscreen-status-changed', true)
|
||||||
|
});
|
||||||
|
|
||||||
|
mainWindow.on('leave-full-screen', () => {
|
||||||
|
mainWindow.webContents.send('fullscreen-status-changed', false)
|
||||||
|
});
|
||||||
|
|
||||||
let recorder;
|
let recorder;
|
||||||
ipcMain.on("startRecoder", () => {
|
ipcMain.on("startRecoder", () => {
|
||||||
@ -212,9 +230,9 @@ function createWindow(): void {
|
|||||||
|
|
||||||
// console.log('GetHomeDir()', GetHomeDir())
|
// console.log('GetHomeDir()', GetHomeDir())
|
||||||
let prefix =
|
let prefix =
|
||||||
process.env.NODE_ENV === "development"
|
process.env.NODE_ENV === "development"
|
||||||
? "src/renderer/public"
|
? "src/renderer/public"
|
||||||
: "resources/app.asar/out/renderer";
|
: "resources/app.asar/out/renderer";
|
||||||
let data = {};
|
let data = {};
|
||||||
for (const objKey in obj) {
|
for (const objKey in obj) {
|
||||||
let files = fs.readdirSync(
|
let files = fs.readdirSync(
|
||||||
@ -415,9 +433,17 @@ function forceQuit() {
|
|||||||
// 终止所有剩余的子进程
|
// 终止所有剩余的子进程
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
// Windows系统特殊处理
|
// Windows系统特殊处理
|
||||||
exec('taskkill /F /T /PID ' + process.pid, (error) => {
|
// if (isRestart) {
|
||||||
|
// isRestart = false
|
||||||
|
// app.relaunch();
|
||||||
|
// }
|
||||||
|
let child = exec('taskkill /F /T /PID ' + process.pid, (error) => {
|
||||||
if (error) console.error('强制终止失败:', error);
|
if (error) console.error('强制终止失败:', error);
|
||||||
|
child.kill();
|
||||||
});
|
});
|
||||||
|
if (isRestart) {
|
||||||
|
app.relaunch();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// 其他系统
|
// 其他系统
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
|
|||||||
@ -76,7 +76,7 @@ export default {
|
|||||||
polyhedronObject: "多边体",
|
polyhedronObject: "多边体",
|
||||||
water: "水面",
|
water: "水面",
|
||||||
fountain: '喷泉',
|
fountain: '喷泉',
|
||||||
waterL: '水柱',
|
waterL: '喷射水柱',
|
||||||
fire: "火焰",
|
fire: "火焰",
|
||||||
explosion: "爆炸",
|
explosion: "爆炸",
|
||||||
smoke: "烟雾",
|
smoke: "烟雾",
|
||||||
|
|||||||
@ -72,7 +72,7 @@ export const TreeApi = {
|
|||||||
//树的隐藏显示
|
//树的隐藏显示
|
||||||
updateTreeShow: async (data: any) => {
|
updateTreeShow: async (data: any) => {
|
||||||
return await request.post({
|
return await request.post({
|
||||||
url: `/yjearth4/api/v1/source/show`,
|
url: `/source/updateShowHide`,
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
1
src/renderer/src/global.d.ts
vendored
1
src/renderer/src/global.d.ts
vendored
@ -12,6 +12,7 @@ interface Window {
|
|||||||
}
|
}
|
||||||
interface JQuery {
|
interface JQuery {
|
||||||
zTree: {
|
zTree: {
|
||||||
|
getZTreeObj(arg0: string): unknown
|
||||||
init: (selector: JQuery<HTMLElement>, setting: object, nodes: any[]) => any
|
init: (selector: JQuery<HTMLElement>, setting: object, nodes: any[]) => any
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
src/renderer/src/icons/svg/full_screen_exit.svg
Normal file
1
src/renderer/src/icons/svg/full_screen_exit.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20" fill="none"><g clip-path="url(#clip-path-5fVpVd-XvU6hmXyZKV6wo)"><g filter="url(#filter_am52Yzplm_UJGYFQE3_UG)"><path d="M17.5861 1.25964e-15L2.41383 1.25964e-15C1.08064 1.25964e-15 0 -1.22296e-05 0 2.41L0 17.5862C0 18.9194 1.08064 20 2.41383 20L17.5861 20C18.9193 20 19.9999 18.9194 19.9999 17.5862L19.9999 2.41C19.9999 -1.22296e-05 18.9193 1.25964e-15 17.5861 1.25964e-15ZM18.6365 17.5862C18.6365 18.1655 18.1654 18.6366 17.5861 18.6366L2.41383 18.6366C1.83451 18.6366 1.36337 18.1655 1.36337 17.5862L1.36337 2.41C1.36337 1.83068 1.83451 1.36 2.41383 1.36L17.5861 1.36C18.1654 1.36 18.6365 1.83068 18.6365 2.41L18.6365 17.5862Z" fill="#FFFFFF" ></path></g><g filter="url(#filter_e9NGsQMvMos_qxLyyDo-C)"><path d="M7.10848 3.59058L7.10669 3.59058C6.73031 3.59148 6.4259 3.89745 6.42679 4.27406L6.43238 6.44785L4.21658 6.44785C3.8402 6.44785 3.53489 6.75316 3.53489 7.12954C3.53489 7.50592 3.8402 7.81123 4.21658 7.81123L7.11585 7.81123C7.29689 7.81123 7.47055 7.73926 7.59839 7.61097C7.60628 7.60306 7.614 7.59496 7.62148 7.58667C7.62897 7.57838 7.63626 7.56991 7.64334 7.56126C7.65043 7.55261 7.65729 7.54378 7.66393 7.5348C7.67056 7.52581 7.67698 7.51667 7.68317 7.50737C7.68936 7.49805 7.69533 7.4886 7.70107 7.47901C7.70679 7.46942 7.71229 7.45968 7.71754 7.44982C7.7228 7.43996 7.7278 7.42997 7.73256 7.41987C7.73732 7.40975 7.74182 7.39953 7.74609 7.38918C7.75035 7.37886 7.75435 7.36842 7.75809 7.35789C7.76184 7.34737 7.76533 7.33675 7.76855 7.32605C7.77177 7.31534 7.77472 7.30457 7.77742 7.29373C7.78012 7.28289 7.78254 7.27198 7.78471 7.26101C7.78687 7.25003 7.78875 7.23903 7.79036 7.22797C7.79199 7.21691 7.79333 7.20582 7.79441 7.19469C7.79546 7.18358 7.79626 7.17243 7.7968 7.16126C7.79731 7.1501 7.79756 7.13893 7.79754 7.12775L7.79016 4.27048C7.78904 3.89455 7.48418 3.59058 7.10848 3.59058ZM7.07182 12.1523L4.21457 12.1597C3.83819 12.1606 3.53378 12.4666 3.53467 12.8432C3.53556 13.2191 3.84065 13.5231 4.21635 13.5231L4.21814 13.5231L6.39193 13.5175L6.39193 15.7333C6.39193 16.1097 6.69723 16.415 7.07361 16.415C7.44999 16.415 7.75529 16.1097 7.75529 15.7333L7.75529 12.834C7.75529 12.653 7.68333 12.4793 7.55503 12.3515C7.42674 12.2236 7.25241 12.1519 7.07182 12.1523ZM15.6561 6.45679L13.4823 6.46238L13.4823 4.24657C13.4823 3.87019 13.177 3.56488 12.8006 3.56488C12.4243 3.56488 12.119 3.87019 12.119 4.24657L12.119 7.14586C12.119 7.32689 12.1909 7.50056 12.3192 7.6284C12.4471 7.7558 12.6201 7.82754 12.8006 7.82754L12.8024 7.82754L15.6597 7.82017C16.0361 7.81927 16.3407 7.5133 16.3396 7.13669C16.3385 6.76009 16.0318 6.45545 15.6561 6.45679ZM15.6579 12.1687L12.7584 12.1687C12.5774 12.1687 12.4037 12.2406 12.2759 12.3689C12.268 12.3768 12.2603 12.3849 12.2528 12.3932C12.2453 12.4015 12.238 12.41 12.2309 12.4186C12.2238 12.4273 12.217 12.4361 12.2103 12.4451C12.2037 12.4541 12.1973 12.4632 12.1911 12.4725C12.1849 12.4818 12.1789 12.4913 12.1732 12.5009C12.1675 12.5105 12.162 12.5202 12.1567 12.5301C12.1515 12.5399 12.1465 12.5499 12.1417 12.56C12.1369 12.5701 12.1324 12.5803 12.1282 12.5907C12.1239 12.601 12.1199 12.6115 12.1162 12.622C12.1124 12.6325 12.1089 12.6431 12.1057 12.6538C12.1025 12.6645 12.0995 12.6753 12.0968 12.6862C12.0941 12.697 12.0917 12.7079 12.0895 12.7189C12.0874 12.7298 12.0855 12.7408 12.0839 12.7519C12.0823 12.763 12.0809 12.7741 12.0798 12.7852C12.0788 12.7963 12.078 12.8075 12.0775 12.8186C12.0769 12.8298 12.0767 12.841 12.0767 12.8521L12.0841 15.7094C12.085 16.0853 12.3901 16.3893 12.7658 16.3893L12.7676 16.3893C13.1439 16.3884 13.4484 16.0824 13.4475 15.7058L13.4419 13.532L15.6577 13.532C16.0341 13.532 16.3394 13.2267 16.3394 12.8503C16.3394 12.474 16.0343 12.1687 15.6579 12.1687Z" fill="#FFFFFF" ></path></g></g></svg>
|
||||||
|
After Width: | Height: | Size: 3.7 KiB |
@ -1,6 +1,6 @@
|
|||||||
export const uesSetTool = (setPupRef?: any) => {
|
export const uesSetTool = (setPupRef?: any) => {
|
||||||
//打开弹窗
|
//打开弹窗
|
||||||
const setShow = () => {
|
const setShow = (e) => {
|
||||||
console.log(setPupRef, 'setPupRef')
|
console.log(setPupRef, 'setPupRef')
|
||||||
setPupRef.value.open()
|
setPupRef.value.open()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,14 +13,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div> -->
|
</div> -->
|
||||||
<div
|
<div class="set_item" :title="t('iconTitle.' + item.name)" v-for="(item, i) of setList" :key="item.id"
|
||||||
class="set_item"
|
:class="{ 'last-item': i === setList.length - 1 }" @click="item.callback">
|
||||||
:title="t('iconTitle.' + item.name)"
|
|
||||||
v-for="(item, i) of setList"
|
|
||||||
:key="item.id"
|
|
||||||
:class="{ 'last-item': i === setList.length - 1 }"
|
|
||||||
@click="item.callback"
|
|
||||||
>
|
|
||||||
<svg-icon :name="item.icon" :size="20"></svg-icon>
|
<svg-icon :name="item.icon" :size="20"></svg-icon>
|
||||||
</div>
|
</div>
|
||||||
<setPup ref="setPupRef"></setPup>
|
<setPup ref="setPupRef"></setPup>
|
||||||
@ -32,6 +26,7 @@ import { useRouter } from 'vue-router'
|
|||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import setPup from '../setPup/setPup.vue'
|
import setPup from '../setPup/setPup.vue'
|
||||||
import { inject } from 'vue'
|
import { inject } from 'vue'
|
||||||
|
const { ipcRenderer } = require('electron');
|
||||||
const router = useRouter() // 路由实例
|
const router = useRouter() // 路由实例
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
import { uesSetTool } from './hooks'
|
import { uesSetTool } from './hooks'
|
||||||
@ -42,17 +37,26 @@ const { setShow } = uesSetTool(setPupRef)
|
|||||||
//控制显隐
|
//控制显隐
|
||||||
const eventBus: any = inject('bus')
|
const eventBus: any = inject('bus')
|
||||||
eventBus.on('settingPop', (data) => {
|
eventBus.on('settingPop', (data) => {
|
||||||
console.log(setPupRef.value, 'data')
|
|
||||||
data ? setPupRef.value.open() : setPupRef.value.close()
|
data ? setPupRef.value.open() : setPupRef.value.close()
|
||||||
})
|
})
|
||||||
const logout = async () => {
|
const logout = async (e) => {
|
||||||
let res = await LoginApi.logout()
|
let res = await LoginApi.logout()
|
||||||
console.log(res)
|
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
router.push({ path: '/' })
|
router.push({ path: '/' })
|
||||||
// localStorage.clear()
|
// localStorage.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const fullScreen = (item) => {
|
||||||
|
ipcRenderer.send('toggle-fullscreen');
|
||||||
|
}
|
||||||
|
const resetShow = (item) => {
|
||||||
|
//重置
|
||||||
|
new YJ.Tools(window.earth).flyHome();
|
||||||
|
}
|
||||||
|
|
||||||
const setList = ref([
|
const setList = ref([
|
||||||
// 标准版本
|
// 标准版本
|
||||||
{
|
{
|
||||||
@ -60,7 +64,9 @@ const setList = ref([
|
|||||||
index: 0,
|
index: 0,
|
||||||
icon: 'beidou',
|
icon: 'beidou',
|
||||||
name: 'locate',
|
name: 'locate',
|
||||||
className: 'header_public'
|
className: 'header_public',
|
||||||
|
dbcallback: (e)=>{},
|
||||||
|
callback: (e)=>{}
|
||||||
// dbcallback: this.flyTo,
|
// dbcallback: this.flyTo,
|
||||||
// callback: this.locate,
|
// callback: this.locate,
|
||||||
},
|
},
|
||||||
@ -70,8 +76,8 @@ const setList = ref([
|
|||||||
icon: 'sys_reset',
|
icon: 'sys_reset',
|
||||||
className: 'header_public',
|
className: 'header_public',
|
||||||
name: 'reset',
|
name: 'reset',
|
||||||
dbcallback: null
|
dbcallback: null,
|
||||||
// callback: this.resetShow,
|
callback: resetShow,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
@ -79,8 +85,8 @@ const setList = ref([
|
|||||||
icon: 'full_screen',
|
icon: 'full_screen',
|
||||||
className: 'header_public',
|
className: 'header_public',
|
||||||
name: 'fullScreen',
|
name: 'fullScreen',
|
||||||
dbcallback: null
|
dbcallback: null,
|
||||||
// callback: this.fullScreen,
|
callback: fullScreen,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 3,
|
id: 3,
|
||||||
@ -102,6 +108,13 @@ const setList = ref([
|
|||||||
callback: logout
|
callback: logout
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
|
ipcRenderer.invoke('getIsFullScreen').then((res) => {
|
||||||
|
setList.value[2].icon = res ? 'full_screen_exit' : 'full_screen'
|
||||||
|
})
|
||||||
|
ipcRenderer.on('fullscreen-status-changed', (event, isFullscreen) => {
|
||||||
|
setList.value[2].icon = isFullscreen ? 'full_screen_exit' : 'full_screen'
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@ -135,12 +148,10 @@ const setList = ref([
|
|||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 1px;
|
width: 1px;
|
||||||
background: linear-gradient(
|
background: linear-gradient(180deg,
|
||||||
180deg,
|
rgba(0, 255, 255, 0),
|
||||||
rgba(0, 255, 255, 0),
|
rgba(0, 255, 255, 1),
|
||||||
rgba(0, 255, 255, 1),
|
rgba(204, 204, 204, 0));
|
||||||
rgba(204, 204, 204, 0)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.set_item.last-item::after {
|
.set_item.last-item::after {
|
||||||
|
|||||||
@ -189,6 +189,7 @@ export const useTree = () => {
|
|||||||
* 成为同级前一个节点,"next":成为同级后一个节点》
|
* 成为同级前一个节点,"next":成为同级后一个节点》
|
||||||
* @returns {boolean} 返回 false,zTree 将恢复被拖拽的节点,也无法触发 onDrop 事件回调函数
|
* @returns {boolean} 返回 false,zTree 将恢复被拖拽的节点,也无法触发 onDrop 事件回调函数
|
||||||
*/
|
*/
|
||||||
|
// @ts-ignore
|
||||||
const beforeDrop = (
|
const beforeDrop = (
|
||||||
treeId: any,
|
treeId: any,
|
||||||
treeNodes: any,
|
treeNodes: any,
|
||||||
@ -221,6 +222,8 @@ export const useTree = () => {
|
|||||||
console.log(treeNode, 'treeNode')
|
console.log(treeNode, 'treeNode')
|
||||||
let parentNode = treeNode.getParentNode();
|
let parentNode = treeNode.getParentNode();
|
||||||
|
|
||||||
|
// if(treeNode.sourceType == 'directory') {}
|
||||||
|
|
||||||
let params = JSON.parse(treeNode.params)
|
let params = JSON.parse(treeNode.params)
|
||||||
let entityObject
|
let entityObject
|
||||||
if (treeNode.sourceType == 'pressModel') {
|
if (treeNode.sourceType == 'pressModel') {
|
||||||
@ -240,17 +243,20 @@ export const useTree = () => {
|
|||||||
(window as any).pressModelEntities.set(treeNode.id, entityObject)
|
(window as any).pressModelEntities.set(treeNode.id, entityObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else if (treeNode.sourceType != 'directory') {
|
||||||
entityObject = window.earth.entityMap.get(params.id)
|
entityObject = window.earth.entityMap.get(params.id)
|
||||||
}
|
}
|
||||||
entityObject.show = treeNode.isShow;
|
if (entityObject) {
|
||||||
(treeNode.sourceType != 'pressModel') && (params.show = treeNode.isShow)
|
entityObject.show = treeNode.isShow;
|
||||||
let params2 = {
|
(treeNode.sourceType != 'pressModel') && (params.show = treeNode.isShow)
|
||||||
"id": treeNode.id,
|
let params2 = {
|
||||||
"params": params,
|
"id": treeNode.id,
|
||||||
"isShow": treeNode.isShow ? 1 : 0,
|
"params": params,
|
||||||
|
"isShow": treeNode.isShow ? 1 : 0,
|
||||||
|
}
|
||||||
|
TreeApi.updateDirectoryInfo(params2)
|
||||||
}
|
}
|
||||||
TreeApi.updateDirectoryInfo(params2)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -287,6 +293,34 @@ export const useTree = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let ids = [
|
||||||
|
{
|
||||||
|
id: treeNode.id,
|
||||||
|
isShow: treeNode.isShow ? 1 : 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
if (treeNode.sourceType === 'directory') {
|
||||||
|
if (treeNode.children && treeNode.children.length > 0) {
|
||||||
|
treeNode.children.forEach((item) => {
|
||||||
|
ids.push({ id: item.id, isShow: item.isShow ? 1 : 0 })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const res = await TreeApi.updateTreeShow(ids)
|
||||||
|
if (res.code == 0 || res.code == 200) {
|
||||||
|
ElMessage({
|
||||||
|
message: '操作成功',
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
ElMessage({
|
||||||
|
message: '操作失败',
|
||||||
|
type: 'error'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// let source_ids = [];
|
// let source_ids = [];
|
||||||
// nodes.forEach((item) => {
|
// nodes.forEach((item) => {
|
||||||
// if (item.isHidden == false) {
|
// if (item.isHidden == false) {
|
||||||
@ -551,6 +585,12 @@ export const useTree = () => {
|
|||||||
let params = JSON.parse(zNodes.value[i].params || '{}')
|
let params = JSON.parse(zNodes.value[i].params || '{}')
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
let detail = JSON.parse(zNodes.value[i].detail || '{}')
|
let detail = JSON.parse(zNodes.value[i].detail || '{}')
|
||||||
|
if (zNodes.value[i].isShow) {
|
||||||
|
zNodes.value[i]
|
||||||
|
}
|
||||||
|
if ('show' in params) {
|
||||||
|
params.show = zNodes.value[i].isShow ? true : false
|
||||||
|
}
|
||||||
if (!params.id) {
|
if (!params.id) {
|
||||||
params.id = zNodes.value[i].id
|
params.id = zNodes.value[i].id
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user