初步基本功能实现

This commit is contained in:
miao 2022-12-16 14:59:19 +08:00
parent 2b1ab68d29
commit e6fed227dc
5 changed files with 492 additions and 324 deletions

View File

@ -7,6 +7,7 @@
}
">
<q-card class="overflow-hidden" style="overflow-y: scroll; max-width: 60vw">
<q-form @submit="onSubmit">
<q-card-section class="q-ma-none q-pa-sm">
<div class="row">
<div class="col-auto text-h6">
@ -64,8 +65,11 @@
<span class="q-mb-md">X:</span>
</q-item-section>
<q-item-section>
<q-input v-if="(current_index > -1)" type="number" min="0"
v-model="test_monitor_wall[current_index].currentx" :rules="[
<q-input v-if="(current_index > -1)" type="number" :min="min_x()"
v-model="test_monitor_wall[current_index].centerx"
@update:model-value="center_x()"
:max="max_x()"
:rules="[
(val) =>
(val != null &&
val != undefined &&
@ -95,15 +99,17 @@
<span class="q-mb-md">Y:</span>
</q-item-section>
<q-item-section>
<q-input v-if="(current_index > -1)" :hint="''" type="number" min="0"
v-model="test_monitor_wall[current_index].currenty" :rules="[
<q-input v-if="(current_index > -1)" :hint="''" type="number" :min="min_y()" :max="max_y()"
v-model="test_monitor_wall[current_index].centery"
@update:model-value="center_y()"
:rules="[
(val) =>
(val != null &&
val != undefined &&
val.toString().length > 0) ||
$t('Please type something'),
(val) =>
parseInt(val) >= 0 ||
parseInt(val) > 0 ||
$t('the number must be greater than 0'),
]" lazy-rules>
<template v-slot:append>
@ -133,20 +139,20 @@
</div>
</div>
</div>
<div id="monitors" ref="wall" v-if="$store.state.power_state"
style="position: absolute; height: 85%; width: 95%; overflow: hidden;">
<div v-for=" (item, index) of test_monitor_wall">
<vue3-resize-drag v-if="((item.id < 4) && item.uuid != '')" :w="($refs.wall?.offsetWidth * 0.5)"
:h="($refs.wall?.offsetHeight * 0.5)"
:x="((item.currentx) > $refs.wall?.offsetWidth - item.w ? item.currenty - item.w : item.currentx)"
:y="((item.currenty) > $refs.wall?.offsetHeight - item.h ? item.currenty - item.h : item.currenty)"
:resizeIconSize="8" :isActive="item.active" :isGuide="(true && item.angle == 0)" :rotate="item.angle"
style="background-color: grey; opacity: 0.8; text-align: center;position: absolute; "
@moveHandler="moveingMonitor(item, $event)" @moveEndHandler="moveMonitor(item, $event)"
<div ref="wall" v-if="$store.state.power_state"
style="position: absolute; height: 85%; width: 95%; overflow: hidden;" @click="canel_active()">
<div v-for=" (item, index) of test_monitor_wall" @click.stop="Unchecked==false">
<vue3-resize-drag v-if="item.isShow" :w="item.w" :h="item.h" :x="parseInt(item.currentx.toString())"
:y="parseInt(item.currenty.toString())"
:isActive="item.active" :isGuide="(true && item.angle == 0)" :rotate="parseInt(item.angle.toString())"
:is-resizable="false" :resizeIconSize="10"
style="background-color: grey; text-align: center;position: absolute; "
@moveHandler="moveingMonitor(item, $event, index)" @moveEndHandler="moveMonitor(item, $event)"
@mousedown="activeMouseDown(item, index)" @rotateHandler="rotateMonitor(item, $event)"
:z-index="item.active ? 99 : 0">
<div class="full-height full-width" :class="item.active ? 'monitor_selected' : ''"
style="text-align:center;" :style="{ lineHeight: show_box_line_height($refs.wall?.offsetHeight) }">
style="text-align:center;"
:style="{ lineHeight: show_box_line_height(item.h) }">
<q-popup-proxy context-menu>
<q-list>
<q-item clickable v-close-popup>
@ -159,38 +165,9 @@
</q-item-section>
</q-item>
<q-item clickable v-close-popup>
<q-item-section @click="closeAllWindows()"> {{ $t("close all windows") }} </q-item-section>
</q-item>
</q-list>
</q-popup-proxy>
{{ item.uuid }}
</div>
</vue3-resize-drag>
<vue3-resize-drag v-else-if="(item.id < 8 && item.uuid != '')" :w="($refs.wall?.offsetWidth * 0.6)"
:h="($refs.wall?.offsetHeight * 0.6)"
:x="((item.currentx) > $refs.wall?.offsetWidth - item.w ? item.currenty - item.w : item.currentx)"
:y="((item.currenty) > $refs.wall?.offsetHeight - item.h ? item.currenty - item.h : item.currenty)"
:resizeIconSize="8" :isActive="item.active" :isGuide="(true && item.angle == 0)" :rotate="item.angle"
style="background-color: grey; opacity: 0.8; text-align: center;position: absolute;"
@moveHandler="moveingMonitor(item, $event)" @moveEndHandler="moveMonitor(item, $event)"
@mousedown="activeMouseDown(item, index)" @rotateHandler="rotateMonitor(item, $event)"
:z-index="item.active ? 99 : 0">
<div class="full-height full-width" :class="item.active ? 'monitor_selected' : ''"
style="text-align:center;" :style="{ lineHeight: show_box_line_height($refs.wall?.offsetHeight) }">
<q-popup-proxy context-menu>
<q-list>
<q-item clickable v-close-popup>
<q-item-section @click="closeWindow(item, index)"> {{ $t("close this window") }}
<q-item-section @click="closeAllWindows()"> {{ $t("close all windows") }}
</q-item-section>
</q-item>
<q-item clickable v-close-popup>
<q-item-section @click="closeOtherWindows(item, index)">
{{ $t("close other windows") }}
</q-item-section>
</q-item>
<q-item clickable v-close-popup>
<q-item-section @click="closeAllWindows()"> {{ $t("close all windows") }} </q-item-section>
</q-item>
</q-list>
</q-popup-proxy>
{{ item.uuid }}
@ -215,23 +192,25 @@
<div v-for="(j) in 4" style="display:inline-block"
v-if="(item < test_monitor_list.length / 4 || (test_monitor_list.length % 4 == 0))"
:style="{ lineHeight: box_height(item, j) }">
<div v-if="test_monitor_list[(item - 1) * 4 + (j - 1)] == ''">
<div v-if="test_monitor_list[(item - 1) * 4 + (j - 1)].isHide">
</div>
<div v-else style="background-color: grey; opacity: 0.5; border: 1px solid black;text-align: center;"
:style="{ width: box_width(item, j), height: box_height(item, j) }" :draggable="$store.state.power_state"
<div v-else style="background-color: grey; border: 1px solid black;text-align: center;"
:style="{ width: box_width(item, j), height: box_height(item, j) }"
:draggable="$store.state.power_state"
@dragstart="(evt) => onDragStart(evt, (test_monitor_list[(item - 1) * 4 + (j - 1)]))"
@dragend="(evt) => onDragend(evt, item, j)">
{{ (test_monitor_list[(item - 1) * 4 + (j - 1)].uuid) }}
</div>
</div>
<div v-else v-for="j in (test_monitor_list.length) % 4" style="display:inline-block;text-align: center;"
:style="{ lineHeight: box_height(item, j) }">
<div v-if="test_monitor_list[(item - 1) * 4 + (j - 1)] == ''">
<div v-else v-for="j in (test_monitor_list.length) % 4"
style="display:inline-block;text-align: center;" :style="{ lineHeight: box_height(item, j) }">
<div v-if="test_monitor_list[(item - 1) * 4 + (j - 1)].isHide">
</div>
<div v-else style="background-color: grey; opacity: 0.5; border: 1px solid black;"
:style="{ width: box_width(item, j), height: box_height(item, j) }" :draggable="$store.state.power_state"
<div v-else style="background-color: grey; border: 1px solid black;"
:style="{ width: box_width(item, j), height: box_height(item, j) }"
:draggable="$store.state.power_state"
@dragstart="(evt) => onDragStart(evt, (test_monitor_list[(item - 1) * 4 + (j - 1)]))"
@dragend="(evt) => onDragend(evt, item, j)">
{{ (test_monitor_list[(item - 1) * 4 + (j - 1)].uuid) }}
@ -251,6 +230,7 @@
<q-btn :loading="loading" flat :label="$t('Cancel')" no-caps color="primary" v-close-popup />
<q-btn ref="accept" flat :label="$t('Accept')" no-caps :loading="loading" type="submit" color="primary" />
</q-card-actions>
</q-form>
</q-card>
</q-dialog>
</template>
@ -278,13 +258,16 @@
<script lang="ts">
import { defineComponent, ref, watch, computed, Ref, reactive } from "vue";
import { useStore } from "src/store";
import { useQuasar, extend } from "quasar";
import { useQuasar, extend, QBtn, QCard, QCardActions, QCardSection, QDialog, QInput, QItem, QItemLabel, QItemSection, QList, QPopupProxy, QSeparator, QSpace, QTooltip } from "quasar";
import { useI18n } from "vue-i18n";
import GlobalData from "src/common/GlobalData";
import { HttpProtocol } from "src/entities/HttpProtocol";
import vue3ResizeDrag from "../third_lib/vue3-resize-drag/components/vue3-resize-drag/index.vue";
import itemDrag from "src/third_lib/vue3-resize-drag/components/vue3-resize-drag/func/drag";
import MagicWallConfig from "src/entities/MagicWallConfig";
import { PointF } from "src/entities/RectF";
import { number } from "@intlify/core-base";
import EventBus, { EventNamesDefine } from "src/common/EventBus";
class test_monitor {
uuid = "";
active = false;
@ -294,8 +277,13 @@ class test_monitor {
h = 0;
currentx = 0;
currenty = 0;
centerx=0;
centery=0;
angle = 0;
id = 0;
resize = 0;
isHide = false;
isShow = false;
reset() {
this.uuid = "";
this.active = false;
@ -305,8 +293,21 @@ class test_monitor {
this.h = 0;
this.currentx = 0;
this.currenty = 0;
this.centerx=0;
this.centery=0;
this.angle = 0;
this.id = 0;
this.isHide = false;//
this.isShow = false;//
this.resize = 0;
}
constructor(id: number, uuid: string, w: number, h: number, resize: number) {
this.reset();
this.id = id;
this.uuid = uuid;
this.w = w;
this.h = h;
this.resize = resize;
}
}
@ -320,8 +321,6 @@ export default defineComponent({
let show_dialog = ref(false);
let loading = ref(false);
let upload_url = ref("");
let file_count = ref(0);
let show_windows_flag = ref(true); // window
let wall: Ref<HTMLElement | null> = ref(null);
let current_index = ref(-1);
@ -335,17 +334,19 @@ export default defineComponent({
const aw = 128; const ah = 72;
const bw = 160; const bh = 90;
let test_monitor_list: Ref<Object[]> = ref([
{ id: 0, uuid: "01", active: false, start_x: 0, start_y: 0, w: aw, h: ah },
{ id: 1, uuid: "02", active: false, start_x: 0, start_y: 0, w: aw, h: ah },
{ id: 2, uuid: "03", active: false, start_x: 0, start_y: 0, w: aw, h: ah },
{ id: 3, uuid: "04", active: false, start_x: 0, start_y: 0, w: aw, h: ah },
{ id: 4, uuid: "05", active: false, start_x: 0, start_y: 0, w: bw, h: bh },
{ id: 5, uuid: "06", active: false, start_x: 0, start_y: 0, w: bw, h: bh },
{ id: 6, uuid: "07", active: false, start_x: 0, start_y: 0, w: bw, h: bh },
{ id: 7, uuid: "08", active: false, start_x: 0, start_y: 0, w: bw, h: bh },
const ar = 0.2; const br = 0.6;
let test_monitor_list: Ref<test_monitor[]> = ref([
new test_monitor(0, "01", aw, ah, ar),
new test_monitor(1, "02", aw, ah, ar),
new test_monitor(2, "03", aw, ah, ar),
new test_monitor(3, "04", aw, ah, ar),
new test_monitor(4, "05", bw, bh, br),
new test_monitor(5, "06", bw, bh, br),
new test_monitor(6, "07", bw, bh, br),
new test_monitor(7, "08", bw, bh, br),
// new test_monitor(8, "09", bw, bh, br),
]);
const delete_monitor_list: Ref<test_monitor[]> = ref([]);
const copy_monitor_list = test_monitor_list.value;
interface show__Rect {
width: number;
height: number;
@ -362,100 +363,226 @@ export default defineComponent({
width: 0,
height: 0,
active: false
})
});
let test_monitor_wall: Ref<test_monitor[]> = ref([]);
const moveingMonitor = (item: test_monitor, rect: show__Rect) => {
const set_x=()=>{
const wall_dom = wall.value
const item = test_monitor_wall.value[current_index.value]
const rx: number = item.currentx + item.w;
if (wall_dom) {
if (rx > wall_dom.offsetWidth) {
item.currentx = Math.round(wall_dom.offsetWidth - item.w)
return parseInt(item.currentx.toString());
}else{
return item.currentx
}
}
};
const min_x=()=>{
const wall_dom = wall.value
const item = test_monitor_wall.value[current_index.value]
if (wall_dom) {
return Math.floor(item.w/2)
}
};
const max_x=()=>{
const wall_dom = wall.value
const item = test_monitor_wall.value[current_index.value]
if (wall_dom) {
return Math.round(wall_dom.offsetWidth -item.w/2)
}
};
const set_y=()=>{
//
const wall_dom = wall.value
const item = test_monitor_wall.value[current_index.value]
const ry: number = item.currenty + item.h;
if (wall_dom) {
if (ry > wall_dom.offsetHeight) {
item.currenty = Math.round(wall_dom.offsetHeight - item.h)
return parseInt(item.currenty.toString());
}else{
return parseInt(item.currenty.toString());
}
}
};
const min_y=()=>{
const wall_dom = wall.value
const item = test_monitor_wall.value[current_index.value]
if (wall_dom) {
return Math.floor(item.h/2)
}
};
const max_y=()=>{
const wall_dom = wall.value
const item = test_monitor_wall.value[current_index.value]
if (wall_dom) {
return Math.round(wall_dom.offsetHeight - item.h/2)
}
};
let Unchecked=ref(false);
const moveingMonitor = (item: test_monitor, rect: show__Rect, index: number) => {
if (item.active) {
test_monitor_wall.value.forEach(element => {
element.active = false
});
}
item.active = true;
if (rect.left > 0) {
item.currentx = rect.left;
const wall_dom = wall.value
if (wall_dom) {
item.h = wall_dom.offsetHeight * item.resize;
item.w = wall_dom.offsetWidth * item.resize;
}
if (rect.top > 0) {
item.currenty = rect.top;
item.active = true;
item.currentx = parseInt(rect.left.toString())
item.currenty = parseInt(rect.top.toString())
item.centerx=Math.round(item.currentx+item.w/2)
item.centery=Math.round(item.currenty+item.h/2)
if (Number.isNaN(rect.left || rect.left < 0)) {
item.currentx = 0
}
};
const rotateMonitor = (item: test_monitor, rect: show__Rect) => {
item.angle = rect.angle;
};
const moveMonitor = (item: test_monitor, rect: show__Rect) => {
let test = JSON.stringify(rect)
//
//
const wall_dom = wall.value
if (rect.left < 0) {
if (item.currentx == 0) {
item.currentx = 0.1
} else {
item.currentx = 0
}
} else if(wall_dom&&rect.left>wall_dom.offsetWidth-item.w) {
item.currentx =set_x()??0;
}else{
item.currentx = rect.left
item.currentx = parseInt(rect.left.toString())
}
if (rect.top < 0) {
if (item.currenty == 0) {
item.currenty = 0.1
} else {
item.currenty = 0
}
} else if(wall.value&&rect.top>wall.value.offsetHeight-item.h){
item.currenty =set_y()??0;
}else{
item.currenty = rect.top
item.currenty = parseInt(rect.top.toString())
}
item.centerx=Math.floor(item.currentx+item.w/2)
item.centery=Math.floor(item.currenty+item.h/2)
};
let test_delete_flag = false;
EventBus.getInstance().on(EventNamesDefine.WindowResize, () => {
const wall_dom = wall.value
if (wall_dom) {
test_monitor_wall.value.forEach((element) => {
element.h = wall_dom.offsetHeight * element.resize;
element.w = wall_dom.offsetWidth * element.resize;
})
}
});
return {
show_dialog,
loading,
upload_url,
delete_monitor_list,
file_count,
window_rect,
Unchecked,
current_index,
test_monitor_list,
test_monitor_wall,
wall,
set_x,
min_x,
max_x,
set_y,
min_y,
max_y,
moveMonitor,
moveingMonitor,
rotateMonitor,
loga(a: any) {
console.log(a);
},
aaa(x: any) {
console.log(x)
},
showDialog() {
async showDialog() {
show_dialog.value = true;
let client = GlobalData.getInstance().getCurrentClient();
if (client) {
let url = new URL(client.url);
url.port =
GlobalData.getInstance().applicationConfig?.httpserver_port ??
HttpProtocol.DefaultHttpPort.toString();
url.pathname = HttpProtocol.RequestUploadFile;
url.protocol = "http:";
url.searchParams.append(
"type",
HttpProtocol.UploadTypeBackgroundImage
);
upload_url.value = url.toString();
const response = await client.getMagicWallConfig()
const a = response?.config.windows;
const wall_dom = wall.value
if (a && wall_dom) {
a.forEach((element) => {
let item: test_monitor = new test_monitor(0, '0', 0, 0, 0)
extend(true, item, test_monitor_list.value[element.index])
item.currentx = Math.round(element.lt.x * wall_dom.offsetWidth);
item.currenty = Math.round(element.lt.y * wall_dom.offsetHeight);
item.h = wall_dom.offsetHeight * element.h;
item.w = wall_dom.offsetWidth * element.w;
item.centerx=Math.floor(item.currentx+item.w/2);
item.centery=Math.floor(item.currenty+item.h/2);
item.angle = element.angle
item.isShow = true;
test_monitor_wall.value.push(item);
test_monitor_list.value.forEach((ele) => {
if (element.index == ele.id) {
ele.isHide = true;
}
})
})
if (a.length == 1) {
current_index.value = 0
} else {
current_index.value = -1
}
}
}
},
resetData() {
test_monitor_wall.value = [];
current_index.value = -1;
test_monitor_list.value.forEach(element => {
element.isHide = false;
})
loading.value = false;
upload_url.value = "";
file_count.value = 0;
},
async onSubmit() {
loading.value = true;
let client = GlobalData.getInstance().getCurrentClient();
const wall_dom = wall.value
if (client && wall_dom) {
const response = await client.getMagicWallConfig();
const cloud_monitor_list = new MagicWallConfig();
cloud_monitor_list.magic_wall_enable = response?.config.magic_wall_enable ?? true;
cloud_monitor_list.col = response?.config.col ?? 2;
cloud_monitor_list.row = response?.config.row ?? 2;
let tep_width = 0;
test_monitor_wall.value.forEach((element, index) => {
if (element.isShow) {
cloud_monitor_list.windows.push({
index: element.id, lt: new PointF(element.currentx / wall_dom.offsetWidth, element.currenty / wall_dom.offsetHeight), h: element.h / wall_dom.offsetHeight, w: element.w / wall_dom.offsetWidth, angle: parseInt(element.angle.toString())
})
}
});
const setMagic = await client.setMagicWallConfig(cloud_monitor_list);
$q.notify({
color: setMagic?.success ? "positive" : "negative",
icon: setMagic?.success ? "done" : "warning",
message:
$t.t("set magic wall") +
(setMagic?.success ? $t.t("success") : $t.t("fail")) +
"!",
position: "top",
timeout: 2500,
});
show_dialog.value = false;
}
loading.value = false;
},
activeMouseDown(item: test_monitor, index: number) {
current_index.value = index;
item.active = true;
Unchecked.value=false;
if (item.active) {
test_monitor_wall.value.forEach(element => {
element.active = false
});
}
item.active = true;
current_index.value = index;
},
onDragStart(e: DragEvent, item: test_monitor) {
item.start_x = e.offsetX;
@ -481,22 +608,38 @@ export default defineComponent({
});
}
if (item.currentx < 0) {
item.currentx = 0.1
item.currentx = 0
window_rect.x = 0
} else {
window_rect.x = item.currentx
}
if (item.currenty < 0) {
item.currenty = 0.1
item.currenty = 0
window_rect.y = 0
} else {
window_rect.y = item.currenty
}
test_delete_flag = false;
const wall_dom = wall.value
item.isShow = true;
if (wall_dom) {
item.h = wall_dom?.offsetHeight * item.resize;
item.w = wall_dom?.offsetWidth * item.resize;
if(item.currentx> wall_dom?.offsetWidth-item.w){
item.currentx=Math.round(wall_dom?.offsetWidth-item.w)
}
if(item.currenty> wall_dom?.offsetHeight-item.h){
item.currenty=Math.round(wall_dom?.offsetHeight-item.h)
}
item.centerx=Math.round(item.currentx+item.w/2);
item.centery=Math.round(item.currenty+item.h/2);
}
if (test_monitor_wall.value.indexOf(item) == -1) {
test_monitor_wall.value.push(item);
test_delete_flag = true;
}
current_index.value = test_monitor_wall.value.length - 1
}
},
@ -517,7 +660,7 @@ export default defineComponent({
onDragend(e: DragEvent, row: number, col: number) {
let num = (row - 1) * 4 + (col - 1);
if (test_delete_flag) {
test_monitor_list.value[num] = ""
test_monitor_list.value[num].isHide = true
}
},
onDragLeave(e: DragEvent) {
@ -526,27 +669,29 @@ export default defineComponent({
},
closeWindow(item: test_monitor, index: number) {
current_index.value = -1;
test_monitor_list.value[item.id] = item;
test_monitor_wall.value[index] = new test_monitor;
test_monitor_list.value[item.id].isHide = false;
test_monitor_wall.value[index].isShow = false;
},
closeOtherWindows(item: test_monitor, index: number) {
current_index.value = 0;
current_index.value = index;
let tep = JSON.parse(JSON.stringify(item));
delete_monitor_list.value = test_monitor_wall.value;
delete_monitor_list.value.forEach(element => {
test_monitor_list.value[element.id] = element
test_monitor_list.value.forEach(element => {
element.isHide = false;
})
test_monitor_list.value[item.id] = []
test_monitor_wall.value = [tep,];
test_monitor_wall.value.forEach(element => {
element.isShow = false;
})
test_monitor_list.value[item.id].isHide = true;
test_monitor_wall.value[index].isShow = true;
},
closeAllWindows() {
current_index.value = -1;
delete_monitor_list.value = test_monitor_wall.value;
delete_monitor_list.value.forEach(element => {
test_monitor_list.value[element.id] = element
test_monitor_list.value.forEach(element => {
element.isHide = false;
})
test_monitor_wall.value.forEach(element => {
element.isShow = false;
})
test_monitor_wall.value = [];
},
box_width(row: number, col: number) {
let tep = JSON.parse(JSON.stringify(test_monitor_list.value[(row - 1) * 4 + (col - 1)]))
@ -558,7 +703,26 @@ export default defineComponent({
},
show_box_line_height(height: number) {
return height * 0.5 + "px"
},
center_x(){
const wall_dom = wall.value
const item = test_monitor_wall.value[current_index.value]
item.currentx=Math.round(item.centerx-item.w/2);
},
center_y(){
const wall_dom = wall.value
const item = test_monitor_wall.value[current_index.value]
item.currenty=Math.round(item.centery-item.h/2);
},
canel_active(){
Unchecked.value=true;
if(Unchecked){
current_index.value=-1
test_monitor_wall.value.forEach((element)=>{
element.active=false;
})
}
},
};
},
});

View File

@ -1,8 +1,8 @@
import RotatedRectF from "./RectF";
import RotatedRectF, { RotatedRectFWithIndex } from "./RectF";
export default class MagicWallConfig {
magic_wall_enable = false;
row = 0;
col = 0;
windows: RotatedRectF[] = [];
windows: RotatedRectFWithIndex[] = [];
}

View File

@ -32,3 +32,6 @@ export class RotatedRectF extends RectF {
this.angle = angle;
}
}
export class RotatedRectFWithIndex extends RotatedRectF{
index:number=0;
}

View File

@ -401,6 +401,7 @@ export default {
"Please input vaild host. example: 192.168.1.1 or 192.168.1.1:8080":
"Please Input Vaild Host. Example: 192.168.1.1 or 192.168.1.1:8080",
"equipment data": "Equipment Data",
"set magic wall":"Set Magic wall Success",
"magic wall":"Magic Wall",
"angle":"Angle",
"topology diagram":"Topology Diagram",

View File

@ -668,7 +668,7 @@ export default {
"new password": "新密码",
"edit user or password": "修改用户名和密码",
"old password error": "旧密码不匹配",
"set magic wall":"设置魔墙",
"magic wall":"魔墙",
"angle":"角度",
"topology diagram":"拓扑图",